xorriso  1.5.4.pl02
About: GNU xorriso creates, loads, manipulates and writes ISO 9660 filesystem images with Rock Ridge extensions. It is suitable for incremental data backup and for production of bootable ISO 9660 images. GNU xorriso is a statical compilation of the libraries libburn, libisofs, libisoburn, and libjte.
  Fossies Dox: xorriso-1.5.4.pl02.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

rockridge_read.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007 Vreixo Formoso
3  * Copyright (c) 2009 Thomas Schmitt
4  *
5  * This file is part of the libisofs project; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License version 2
7  * or later as published by the Free Software Foundation.
8  * See COPYING file for details.
9  */
10 
11 /*
12  * This file contains functions related to the reading of SUSP,
13  * Rock Ridge and AAIP extensions on an ECMA-119 image.
14  */
15 
16 #ifdef HAVE_CONFIG_H
17 #include "../config.h"
18 #endif
19 
20 #include "libisofs.h"
21 #include "ecma119.h"
22 #include "util.h"
23 #include "rockridge.h"
24 #include "messages.h"
25 
26 #include <sys/stat.h>
27 #include <stdlib.h>
28 #include <string.h>
29 
31 {
32  uint8_t* base;
33  int pos;
34  int size;
36  int msgid;
37 
38  /* Number of blocks in the ISO 9660 filesystem */
39  uint32_t fs_blocks;
40 
41  /* block and offset for next continuation area */
42  uint32_t ce_block;
43  uint32_t ce_off;
44 
45  /** Length of the next continuation area, 0 if no more CA are specified */
46  uint32_t ce_len;
47 
48  uint8_t *buffer; /*< If there are continuation areas */
49 };
50 
53  uint32_t fs_blocks, uint8_t len_skp, int msgid)
54 {
55  int pad = (record->len_fi[0] + 1) % 2;
56  struct susp_iterator *iter = malloc(sizeof(struct susp_iterator));
57  if (iter == NULL) {
58  return NULL;
59  }
60 
61  iter->base = record->file_id + record->len_fi[0] + pad;
62  iter->pos = len_skp; /* 0 in most cases */
63  iter->size = record->len_dr[0] - record->len_fi[0] - 33 - pad;
64  iter->src = src;
65  iter->msgid = msgid;
66  iter->fs_blocks = fs_blocks;
67 
68  iter->ce_len = 0;
69  iter->buffer = NULL;
70 
71  return iter;
72 }
73 
74 /* More than 1 MiB in a single file's CE area is suspicious */
75 #define ISO_SUSP_MAX_CE_BYTES (1024 * 1024)
76 
77 
78 /* @param flag bit0 = First call on root:
79  Not yet clear whether this is SUSP at all
80 */
82  int flag)
83 {
84  struct susp_sys_user_entry *entry;
85 
86  entry = (struct susp_sys_user_entry*)(iter->base + iter->pos);
87 
88  if (flag & 1) {
89  /* Yet unclear whether it is SUSP at all */
90  if (iter->size < 7)
91  return 0;
92  if (!SUSP_SIG(entry, 'S', 'P'))
93  return 0;
94  if (entry->len_sue[0] < 7)
95  return 0;
96  /* Looks like SUSP enough to pass the further processing here. */
97  }
98  if ( (iter->pos + 4 > iter->size) || (SUSP_SIG(entry, 'S', 'T'))) {
99 
100  /*
101  * End of the System Use Area or Continuation Area.
102  * Note that ST is not needed when the space left is less than 4.
103  * (IEEE 1281, SUSP. section 4)
104  */
105  if (iter->ce_len) {
106  uint32_t block, nblocks, skipped_blocks, skipped_bytes;
107 
108  /* A CE was found, there is another continuation area */
109  skipped_blocks = iter->ce_off / BLOCK_SIZE;
110  skipped_bytes = skipped_blocks * BLOCK_SIZE;
111  nblocks = DIV_UP(iter->ce_off - skipped_bytes + iter->ce_len,
112  BLOCK_SIZE);
113  if (nblocks <= 0 || iter->ce_len > ISO_SUSP_MAX_CE_BYTES)
114  return ISO_SUSP_WRONG_CE_SIZE;
115  if (((uint64_t) iter->ce_block) + skipped_blocks + nblocks >
116  (uint64_t) iter->fs_blocks)
117  return ISO_SUSP_WRONG_CE_SIZE;
118  iter->buffer = realloc(iter->buffer, nblocks * BLOCK_SIZE);
119 
120  /* Read blocks needed to cache the given CE area range */
121  for (block = 0; block < nblocks; ++block) {
122  int ret;
123  ret = iter->src->read_block(iter->src,
124  iter->ce_block + skipped_blocks + block,
125  iter->buffer + block * BLOCK_SIZE);
126  if (ret < 0) {
127  return ret;
128  }
129  }
130  iter->base = iter->buffer + (iter->ce_off - skipped_bytes);
131  iter->pos = 0;
132  iter->size = iter->ce_len;
133  iter->ce_len = 0;
134  entry = (struct susp_sys_user_entry*)iter->base;
135  } else {
136  return 0;
137  }
138  }
139 
140  if (entry->len_sue[0] == 0) {
141  /* a wrong image with this lead us to a infinity loop */
143  "Damaged RR/SUSP information.");
144  return ISO_WRONG_RR;
145  }
146 
147  iter->pos += entry->len_sue[0];
148 
149  if (SUSP_SIG(entry, 'C', 'E')) {
150  /* Continuation entry */
151  if (iter->ce_len) {
152  int ret;
153  ret = iso_msg_submit(iter->msgid, ISO_UNSUPPORTED_SUSP, 0,
154  "More than one CE System user entry has found in a single "
155  "System Use field or continuation area. This breaks SUSP "
156  "standard and it's not supported. Ignoring last CE. Maybe "
157  "the image is damaged.");
158  if (ret < 0) {
159  return ret;
160  }
161  } else {
162  iter->ce_block = iso_read_bb(entry->data.CE.block, 4, NULL);
163  iter->ce_off = iso_read_bb(entry->data.CE.offset, 4, NULL);
164  iter->ce_len = iso_read_bb(entry->data.CE.len, 4, NULL);
165  }
166 
167  /* we don't want to return CE entry to the user */
168  return susp_iter_next(iter, sue, 0);
169  } else if (SUSP_SIG(entry, 'P', 'D')) {
170  /* skip padding */
171  return susp_iter_next(iter, sue, 0);
172  }
173 
174  *sue = entry;
175  return ISO_SUCCESS;
176 }
177 
179 {
180  free(iter->buffer);
181  free(iter);
182 }
183 
184 /**
185  * Fills a struct stat with the values of a Rock Ridge PX entry (RRIP, 4.1.1).
186  *
187  * @return
188  * 1 on success, < 0 on error
189  */
190 int read_rr_PX(struct susp_sys_user_entry *px, struct stat *st)
191 {
192  if (px == NULL || st == NULL) {
193  return ISO_NULL_POINTER;
194  }
195  if (px->sig[0] != 'P' || px->sig[1] != 'X') {
196  return ISO_WRONG_ARG_VALUE;
197  }
198 
199  if (px->len_sue[0] != 44 && px->len_sue[0] != 36) {
200  return ISO_WRONG_RR;
201  }
202 
203  st->st_mode = iso_read_bb(px->data.PX.mode, 4, NULL);
204  st->st_nlink = iso_read_bb(px->data.PX.links, 4, NULL);
205  st->st_uid = iso_read_bb(px->data.PX.uid, 4, NULL);
206  st->st_gid = iso_read_bb(px->data.PX.gid, 4, NULL);
207  st->st_ino = 0;
208  if (px->len_sue[0] == 44) {
209  /* this corresponds to RRIP 1.12, so we have inode serial number */
210  st->st_ino = iso_read_bb(px->data.PX.serial, 4, NULL);
211  /* Indicate that st_ino is valid */
212  return 2;
213  }
214  return 1;
215 }
216 
217 /**
218  * Fills a struct stat with the values of a Rock Ridge TF entry (RRIP, 4.1.6)
219  *
220  * @return
221  * 1 on success, < 0 on error
222  */
223 int read_rr_TF(struct susp_sys_user_entry *tf, struct stat *st)
224 {
225  time_t time;
226  int s;
227  int nts = 0;
228 
229  if (tf == NULL || st == NULL) {
230  return ISO_NULL_POINTER;
231  }
232  if (tf->sig[0] != 'T' || tf->sig[1] != 'F') {
233  return ISO_WRONG_ARG_VALUE;
234  }
235 
236  if (tf->data.TF.flags[0] & (1 << 7)) {
237  /* long form */
238  s = 17;
239  } else {
240  s = 7;
241  }
242 
243  /* 1. Creation time */
244  if (tf->data.TF.flags[0] & (1 << 0)) {
245  /* Linux accepts ctime by Creation time and by Attributes time.
246  * If both are given, then Attribute time will win.
247  */
248  if (tf->len_sue[0] < 5 + (nts+1) * s) {
249  /* RR TF entry too short. */
250  return ISO_WRONG_RR;
251  }
252  if (s == 7) {
253  time = iso_datetime_read_7(&tf->data.TF.t_stamps[nts*7]);
254  } else {
255  time = iso_datetime_read_17(&tf->data.TF.t_stamps[nts*17]);
256  }
257  st->st_ctime = time;
258  ++nts;
259  }
260 
261  /* 2. modify time */
262  if (tf->data.TF.flags[0] & (1 << 1)) {
263  if (tf->len_sue[0] < 5 + (nts+1) * s) {
264  /* RR TF entry too short. */
265  return ISO_WRONG_RR;
266  }
267  if (s == 7) {
268  time = iso_datetime_read_7(&tf->data.TF.t_stamps[nts*7]);
269  } else {
270  time = iso_datetime_read_17(&tf->data.TF.t_stamps[nts*17]);
271  }
272  st->st_mtime = time;
273  ++nts;
274  }
275 
276  /* 3. access time */
277  if (tf->data.TF.flags[0] & (1 << 2)) {
278  if (tf->len_sue[0] < 5 + (nts+1) * s) {
279  /* RR TF entry too short. */
280  return ISO_WRONG_RR;
281  }
282  if (s == 7) {
283  time = iso_datetime_read_7(&tf->data.TF.t_stamps[nts*7]);
284  } else {
285  time = iso_datetime_read_17(&tf->data.TF.t_stamps[nts*17]);
286  }
287  st->st_atime = time;
288  ++nts;
289  }
290 
291  /* 4. attributes time */
292  if (tf->data.TF.flags[0] & (1 << 3)) {
293  if (tf->len_sue[0] < 5 + (nts+1) * s) {
294  /* RR TF entry too short. */
295  return ISO_WRONG_RR;
296  }
297  if (s == 7) {
298  time = iso_datetime_read_7(&tf->data.TF.t_stamps[nts*7]);
299  } else {
300  time = iso_datetime_read_17(&tf->data.TF.t_stamps[nts*17]);
301  }
302  st->st_ctime = time;
303  ++nts;
304  }
305 
306  /* we ignore backup, expire and effect times */
307 
308  return ISO_SUCCESS;
309 }
310 
311 /**
312  * Read a RR NM entry (RRIP, 4.1.4), and appends the name stored there to
313  * the given name. You can pass a pointer to NULL as name.
314  *
315  * @return
316  * 1 on success, < 0 on error
317  */
318 int read_rr_NM(struct susp_sys_user_entry *nm, char **name, int *cont)
319 {
320  if (nm == NULL || name == NULL) {
321  return ISO_NULL_POINTER;
322  }
323  if (nm->sig[0] != 'N' || nm->sig[1] != 'M') {
324  return ISO_WRONG_ARG_VALUE;
325  }
326 
327  if (nm->len_sue[0] == 5) {
328  if (nm->data.NM.flags[0] & 0x2) {
329  /* it is a "." entry */
330  if (*name == NULL) {
331  return ISO_SUCCESS;
332  } else {
333  /* we can't have a previous not-NULL name */
334  return ISO_WRONG_RR;
335  }
336  }
337  }
338 
339  if (nm->len_sue[0] <= 5) {
340  /* ".." entry is an error, as we will never call it */
341  return ISO_WRONG_RR;
342  }
343 
344  /* concatenate the results */
345  if (*cont) {
346  *name = realloc(*name, strlen(*name) + nm->len_sue[0] - 5 + 1);
347  strncat(*name, (char*)nm->data.NM.name, nm->len_sue[0] - 5);
348  } else {
349  *name = iso_util_strcopy((char*)nm->data.NM.name, nm->len_sue[0] - 5);
350  }
351  if (*name == NULL) {
352  return ISO_OUT_OF_MEM;
353  }
354 
355  /* and set cond according to the value of CONTINUE flag */
356  *cont = nm->data.NM.flags[0] & 0x01;
357  return ISO_SUCCESS;
358 }
359 
360 /**
361  * Read a SL RR entry (RRIP, 4.1.3), checking if the destination continues.
362  *
363  * @param cont
364  * 0 not continue, 1 continue, 2 continue component
365  * @return
366  * 1 on success, < 0 on error
367  */
368 int read_rr_SL(struct susp_sys_user_entry *sl, char **dest, int *cont)
369 {
370  int pos;
371 
372  if (sl == NULL || dest == NULL) {
373  return ISO_NULL_POINTER;
374  }
375  if (sl->sig[0] != 'S' || sl->sig[1] != 'L') {
376  return ISO_WRONG_ARG_VALUE;
377  }
378 
379  for (pos = 0; pos + 5 < sl->len_sue[0];
380  pos += 2 + sl->data.SL.comps[pos + 1]) {
381  char *comp;
382  uint8_t len;
383  uint8_t flags = sl->data.SL.comps[pos];
384 
385  if (flags & 0x2) {
386  /* current directory */
387  len = 1;
388  comp = ".";
389  } else if (flags & 0x4) {
390  /* parent directory */
391  len = 2;
392  comp = "..";
393  } else if (flags & 0x8) {
394  /* root directory */
395  len = 1;
396  comp = "/";
397  } else if (flags & ~0x01) {
398  /* unsupported flag component */
399  return ISO_UNSUPPORTED_RR;
400  } else {
401  len = sl->data.SL.comps[pos + 1];
402  comp = (char*)&sl->data.SL.comps[pos + 2];
403  }
404 
405  if (*cont == 1) {
406  /* new component */
407  size_t size = strlen(*dest);
408  int has_slash;
409 
410  *dest = realloc(*dest, strlen(*dest) + len + 2);
411  if (*dest == NULL) {
412  return ISO_OUT_OF_MEM;
413  }
414  /* it is a new compoenent, add the '/' */
415  has_slash = 0;
416  if (size > 0)
417  if ((*dest)[size - 1] == '/')
418  has_slash = 1;
419  if (!has_slash) {
420  (*dest)[size] = '/';
421  (*dest)[size+1] = '\0';
422  }
423  strncat(*dest, comp, len);
424  } else if (*cont == 2) {
425  /* the component continues */
426  *dest = realloc(*dest, strlen(*dest) + len + 1);
427  if (*dest == NULL) {
428  return ISO_OUT_OF_MEM;
429  }
430  /* we don't have to add the '/' */
431  strncat(*dest, comp, len);
432  } else {
433  *dest = iso_util_strcopy(comp, len);
434  }
435  if (*dest == NULL) {
436  return ISO_OUT_OF_MEM;
437  }
438  /* do the component continue or not? */
439  *cont = (flags & 0x01) ? 2 : 1;
440  }
441 
442  if (*cont == 2) {
443  /* TODO check that SL flag is set to continute too ?*/
444  } else {
445  *cont = sl->data.SL.flags[0] & 0x1 ? 1 : 0;
446  }
447 
448  return ISO_SUCCESS;
449 }
450 
451 /**
452  * Fills a struct stat with the values of a Rock Ridge PN entry (RRIP, 4.1.2).
453  *
454  * @return
455  * 1 on success, < 0 on error
456  */
457 int read_rr_PN(struct susp_sys_user_entry *pn, struct stat *st)
458 {
459  int high_shift= 0;
460 
461  if (pn == NULL || st == NULL) {
462  return ISO_NULL_POINTER;
463  }
464  if (pn->sig[0] != 'P' || pn->sig[1] != 'N') {
465  return ISO_WRONG_ARG_VALUE;
466  }
467 
468  if (pn->len_sue[0] != 20) {
469  return ISO_WRONG_RR;
470  }
471 
472  /* (dev_t << 32) causes compiler warnings on FreeBSD
473  because sizeof(dev_t) is 4.
474  */
475  st->st_rdev = (dev_t)iso_read_bb(pn->data.PN.low, 4, NULL);
476  if (sizeof(st->st_rdev) > 4) {
477  high_shift = 32;
478  st->st_rdev |= (dev_t)((dev_t)iso_read_bb(pn->data.PN.high, 4, NULL) <<
479  high_shift);
480  }
481 
482 /* was originally:
483  st->st_rdev = (dev_t)((dev_t)iso_read_bb(pn->data.PN.high, 4, NULL) << 32)
484  | (dev_t)iso_read_bb(pn->data.PN.low, 4, NULL);
485 */
486 
487  return ISO_SUCCESS;
488 }
489 
490 
491 /* AA is the obsolete field signature of AAIP versions < 2.0
492 */
494  unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
495  size_t *prev_field, int *is_done, int flag)
496 {
497  unsigned char *aapt;
498 
499  if (*is_done) {
500 
501  /* To coexist with Apple ISO :
502  Gracefully react on possibly trailing Apple AA
503  */
504  if (sue->version[0] != 1 || sue->len_sue[0] == 7)
505  return ISO_SUCCESS;
506 
507  return ISO_WRONG_RR;
508  }
509  if (*aa_size == 0 || *aa_string == NULL) {
510  /* Gracefully react on possibly leading Apple AA
511  */
512  if (sue->version[0] != 1 || sue->len_sue[0] < 9)
513  return ISO_SUCCESS;
514  }
515 
516  /* A valid AAIP AA entry has 5 header bytes and at least 1 component byte
517  */
518  if (sue->len_sue[0] < 6)
519  return ISO_WRONG_RR;
520 
521  /* Possibly create or grow storage */
522  if (*aa_size == 0 || *aa_string == NULL) {
523  *aa_size = *aa_len + sue->len_sue[0];
524  *aa_string = calloc(*aa_size, 1);
525  *aa_len = 0;
526  } else if (*aa_len + sue->len_sue[0] > *aa_size) {
527 
528  if (sue->version[0] != 1) {
529  /* Apple ISO within the AAIP field group is not AAIP compliant
530  */
531  return ISO_WRONG_RR;
532  }
533 
534  *aa_size += *aa_len + sue->len_sue[0];
535  *aa_string = realloc(*aa_string, *aa_size);
536  }
537  if (*aa_string == NULL)
538  return ISO_OUT_OF_MEM;
539 
540  if (*aa_len > 0) {
541  /* Mark prev_field as being continued */
542  (*aa_string)[*prev_field + 4] = 1;
543  }
544 
545  *prev_field = *aa_len;
546 
547  /* Compose new SUSP header with signature aa[], cont == 0 */
548  aapt = *aa_string + *aa_len;
549 
550  aapt[0] = 'A';
551  aapt[1] = 'L';
552  aapt[2] = sue->len_sue[0];
553  aapt[3] = 1;
554  aapt[4] = 0;
555 
556  /* Append sue payload */
557  memcpy(aapt + 5, sue->data.AL.comps, sue->len_sue[0] - 5);
558  *is_done = !(sue->data.AL.flags[0] & 1);
559  *aa_len += sue->len_sue[0];
560 
561  return ISO_SUCCESS;
562 }
563 
564 
565 /* AL is the field signature of AAIP versions >= 2.0
566 */
568  unsigned char **aa_string, size_t *aa_size, size_t *aa_len,
569  size_t *prev_field, int *is_done, int flag)
570 {
571  unsigned char *aapt;
572 
573  if (*is_done)
574  return ISO_WRONG_RR;
575  if (sue->version[0] != 1)
576  return ISO_WRONG_RR;
577 
578  /* A valid AL entry has 5 header bytes and at least 1 component byte
579  */
580  if (sue->len_sue[0] < 6)
581  return ISO_WRONG_RR;
582 
583  /* Possibly create or grow storage */
584  if (*aa_size == 0 || *aa_string == NULL) {
585  *aa_size = *aa_len + sue->len_sue[0];
586  *aa_string = calloc(*aa_size, 1);
587  *aa_len = 0;
588  } else if (*aa_len + sue->len_sue[0] > *aa_size) {
589  *aa_size += *aa_len + sue->len_sue[0];
590  *aa_string = realloc(*aa_string, *aa_size);
591  }
592  if (*aa_string == NULL)
593  return ISO_OUT_OF_MEM;
594 
595  if (*aa_len > 0) {
596  /* Mark prev_field as being continued */
597  (*aa_string)[*prev_field + 4] = 1;
598  }
599 
600  *prev_field = *aa_len;
601 
602  /* Compose new SUSP header with signature aa[], cont == 0 */
603  aapt = *aa_string + *aa_len;
604 
605  aapt[0] = 'A';
606  aapt[1] = 'L';
607  aapt[2] = sue->len_sue[0];
608  aapt[3] = 1;
609  aapt[4] = 0;
610 
611  /* Append sue payload */
612  memcpy(aapt + 5, sue->data.AL.comps, sue->len_sue[0] - 5);
613  *is_done = !(sue->data.AL.flags[0] & 1);
614  *aa_len += sue->len_sue[0];
615 
616  return ISO_SUCCESS;
617 }
618 
619 /**
620  * Reads the zisofs parameters from a ZF field (see doc/zisofs_format.txt
621  * and doc/zisofs2_format.txt).
622  *
623  * @return
624  * 1 on success, < 0 on error
625  */
626 int read_zisofs_ZF(struct susp_sys_user_entry *zf, uint8_t algorithm[2],
627  uint8_t *header_size_div4, uint8_t *block_size_log2,
628  uint64_t *uncompressed_size, int flag)
629 {
630  if (zf == NULL) {
631  return ISO_NULL_POINTER;
632  }
633  if ((zf->sig[0] != 'Z' || zf->sig[1] != 'F') &&
634  (zf->sig[0] != 'Z' || zf->sig[1] != '2'))
635  return ISO_WRONG_ARG_VALUE;
636  if (zf->len_sue[0] != 16) {
637  return ISO_WRONG_RR;
638  }
639  if (zf->version[0] > 2)
640  return ISO_WRONG_RR;
641  algorithm[0] = zf->data.ZF.parameters[0];
642  algorithm[1] = zf->data.ZF.parameters[1];
643  *header_size_div4 = zf->data.ZF.parameters[2];
644  *block_size_log2 = zf->data.ZF.parameters[3];
645  if (zf->version[0] == 1)
646  *uncompressed_size = iso_read_bb(&(zf->data.ZF.parameters[4]), 4,
647  NULL);
648  else
649  *uncompressed_size = iso_read_lsb64(&(zf->data.ZF.parameters[4]));
650  return ISO_SUCCESS;
651 }
652 
653 
#define BLOCK_SIZE
Definition: buffer.h:23
char * iso_util_strcopy(const char *buf, size_t len)
Definition: util.c:1912
uint64_t iso_read_lsb64(const uint8_t *buf)
Definition: util.c:1554
time_t iso_datetime_read_17(const uint8_t *buf)
Definition: util.c:1841
time_t iso_datetime_read_7(const uint8_t *buf)
Definition: util.c:1826
uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error)
Definition: util.c:1542
#define DIV_UP(n, div)
Definition: util.h:38
#define ISO_SUCCESS
Definition: libisofs.h:8719
#define ISO_UNSUPPORTED_RR
Definition: libisofs.h:8882
#define ISO_WRONG_RR
Definition: libisofs.h:8879
#define ISO_OUT_OF_MEM
Definition: libisofs.h:8745
#define ISO_UNSUPPORTED_SUSP
Definition: libisofs.h:8900
#define ISO_SUSP_WRONG_CE_SIZE
Definition: libisofs.h:9236
#define ISO_WRONG_ARG_VALUE
Definition: libisofs.h:8751
#define ISO_NULL_POINTER
Definition: libisofs.h:8742
int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt,...)
Definition: messages.c:579
#define SUSP_SIG(entry, a, b)
Definition: rockridge.h:45
int read_rr_TF(struct susp_sys_user_entry *tf, struct stat *st)
SuspIterator * susp_iter_new(IsoDataSource *src, struct ecma119_dir_record *record, uint32_t fs_blocks, uint8_t len_skp, int msgid)
int read_zisofs_ZF(struct susp_sys_user_entry *zf, uint8_t algorithm[2], uint8_t *header_size_div4, uint8_t *block_size_log2, uint64_t *uncompressed_size, int flag)
void susp_iter_free(SuspIterator *iter)
int read_rr_SL(struct susp_sys_user_entry *sl, char **dest, int *cont)
int read_aaip_AL(struct susp_sys_user_entry *sue, unsigned char **aa_string, size_t *aa_size, size_t *aa_len, size_t *prev_field, int *is_done, int flag)
#define ISO_SUSP_MAX_CE_BYTES
int read_rr_PX(struct susp_sys_user_entry *px, struct stat *st)
int susp_iter_next(SuspIterator *iter, struct susp_sys_user_entry **sue, int flag)
int read_aaip_AA(struct susp_sys_user_entry *sue, unsigned char **aa_string, size_t *aa_size, size_t *aa_len, size_t *prev_field, int *is_done, int flag)
int read_rr_PN(struct susp_sys_user_entry *pn, struct stat *st)
int read_rr_NM(struct susp_sys_user_entry *nm, char **name, int *cont)
uint8_t comps[1]
Definition: rockridge.h:156
uint8_t flags[1]
Definition: rockridge.h:155
uint8_t len_dr[(1) -(1)+1]
Definition: ecma119.h:1011
uint8_t file_id[(34) -(34)+1]
Definition: ecma119.h:1021
uint8_t len_fi[(33) -(33)+1]
Definition: ecma119.h:1020
int(* read_block)(IsoDataSource *src, uint32_t lba, uint8_t *buffer)
Definition: libisofs.h:459
uint8_t name[1]
Definition: rockridge.h:130
uint8_t flags[1]
Definition: rockridge.h:129
uint8_t low[8]
Definition: rockridge.h:124
uint8_t high[8]
Definition: rockridge.h:123
uint8_t mode[8]
Definition: rockridge.h:108
uint8_t links[8]
Definition: rockridge.h:109
uint8_t uid[8]
Definition: rockridge.h:110
uint8_t serial[8]
Definition: rockridge.h:112
uint8_t gid[8]
Definition: rockridge.h:111
uint8_t comps[1]
Definition: rockridge.h:141
uint8_t flags[1]
Definition: rockridge.h:140
uint8_t t_stamps[1]
Definition: rockridge.h:118
uint8_t flags[1]
Definition: rockridge.h:117
uint8_t block[8]
Definition: rockridge.h:84
uint8_t offset[8]
Definition: rockridge.h:85
uint8_t len[8]
Definition: rockridge.h:86
uint32_t ce_len
IsoDataSource * src
uint32_t fs_blocks
uint32_t ce_block
uint8_t * buffer
uint32_t ce_off
uint8_t * base
Definition: rockridge.h:170
uint8_t len_sue[1]
Definition: rockridge.h:172
struct rr_SL SL
Definition: rockridge.h:183
uint8_t sig[2]
Definition: rockridge.h:171
struct rr_PX PX
Definition: rockridge.h:178
struct zisofs_ZF ZF
Definition: rockridge.h:186
struct aaip_AL AL
Definition: rockridge.h:185
union susp_sys_user_entry::@6 data
uint8_t version[1]
Definition: rockridge.h:173
struct rr_TF TF
Definition: rockridge.h:179
struct rr_PN PN
Definition: rockridge.h:180
struct rr_NM NM
Definition: rockridge.h:181
struct susp_CE CE
Definition: rockridge.h:175
uint8_t parameters[1]
Definition: rockridge.h:162