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)  

ecma119_tree.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007 Vreixo Formoso
3  * Copyright (c) 2009 - 2016 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 #ifdef HAVE_CONFIG_H
12 #include "../config.h"
13 #endif
14 
15 /* Must be before ecma119.h because of eventual Libisofs_with_rrip_rR */
16 #include "libisofs.h"
17 
18 #include "ecma119_tree.h"
19 #include "ecma119.h"
20 #include "node.h"
21 #include "util.h"
22 #include "filesrc.h"
23 #include "messages.h"
24 #include "image.h"
25 #include "stream.h"
26 #include "eltorito.h"
27 
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdio.h>
31 
32 /* @param flag bit0= Do not issue error messages
33 */
34 int iso_get_ecma119_name(IsoWriteOpts *opts, char *input_charset, int imgid,
35  char *node_name, enum IsoNodeType node_type,
36  char **name, int flag)
37 {
38  int ret, relaxed, free_ascii_name = 0, force_dots = 0;
39  char *ascii_name;
40  char *isoname = NULL;
41 
42  if (node_name == NULL) {
43  /* it is not necessarily an error, it can be the root */
44  return ISO_SUCCESS;
45  }
46 
47  if (opts->untranslated_name_len > 0) {
48  ascii_name = node_name;
49  ret = 1;
50  } else {
51  ret = str2ascii(input_charset, node_name, &ascii_name);
52  free_ascii_name = 1;
53  }
54  if (ret < 0) {
55  if (!(flag & 512))
56  iso_msg_submit(imgid, ret, 0,
57  "Cannot convert name '%s' to ASCII", node_name);
58  return ret;
59  }
60 
61  if (opts->allow_full_ascii) {
62  relaxed = 2;
63  } else {
64  relaxed = (int)opts->allow_lowercase;
65  }
66  if (opts->allow_7bit_ascii)
67  relaxed |= 4;
68  if (node_type == LIBISO_DIR && !(opts->allow_dir_id_ext)) {
69  if (opts->untranslated_name_len > 0) {
70  if (strlen(ascii_name) > opts->untranslated_name_len) {
71 needs_transl:;
72  if (!(flag & 512))
74  "File name too long (%d > %d) for untranslated recording: '%s'",
75  strlen(ascii_name), opts->untranslated_name_len,
76  ascii_name);
77  return ISO_NAME_NEEDS_TRANSL;
78  }
79  isoname = strdup(ascii_name);
80  } else if (opts->max_37_char_filenames) {
81  isoname = iso_r_dirid(ascii_name, 37, relaxed);
82  } else if (opts->iso_level == 1) {
83 
84 #ifdef Libisofs_old_ecma119_nameS
85 
86  if (relaxed) {
87  isoname = iso_r_dirid(ascii_name, 8, relaxed);
88  } else {
89  isoname = iso_1_dirid(ascii_name, 0);
90  }
91 
92 #else /* Libisofs_old_ecma119_nameS */
93 
94  isoname = iso_1_dirid(ascii_name, relaxed);
95 
96 #endif /* ! Libisofs_old_ecma119_nameS */
97 
98 
99  } else {
100  if (relaxed) {
101  isoname = iso_r_dirid(ascii_name, 31, relaxed);
102  } else {
103  isoname = iso_2_dirid(ascii_name);
104  }
105  }
106  } else {
107  force_dots = !((opts->no_force_dots & 1) ||
108  node_type == LIBISO_DIR);
109  if (opts->untranslated_name_len > 0) {
110  if (strlen(ascii_name) > opts->untranslated_name_len)
111  goto needs_transl;
112  isoname = strdup(ascii_name);
113  } else if (opts->max_37_char_filenames) {
114  isoname = iso_r_fileid(ascii_name, 36, relaxed, force_dots);
115  } else if (opts->iso_level == 1) {
116 
117 #ifdef Libisofs_old_ecma119_nameS
118 
119  int max_len;
120 
121  if (relaxed) {
122  if (strchr(ascii_name, '.') == NULL)
123  max_len = 8;
124  else
125  max_len = 11;
126  isoname = iso_r_fileid(ascii_name, max_len, relaxed,
127  force_dots);
128  } else {
129  isoname = iso_1_fileid(ascii_name, 0, force_dots);
130  }
131 
132 #else /* Libisofs_old_ecma119_nameS */
133 
134  isoname = iso_1_fileid(ascii_name, relaxed, force_dots);
135 
136 #endif /* ! Libisofs_old_ecma119_nameS */
137 
138  } else {
139  if (relaxed || !force_dots) {
140  isoname = iso_r_fileid(ascii_name, 30, relaxed, force_dots);
141  } else {
142  isoname = iso_2_fileid(ascii_name);
143  }
144  }
145  }
146  if (free_ascii_name)
147  free(ascii_name);
148  if (isoname != NULL) {
149  *name = isoname;
150  return ISO_SUCCESS;
151  } else {
152  /*
153  * only possible if mem error, as check for empty names is done
154  * in public tree
155  */
156  return ISO_OUT_OF_MEM;
157  }
158 }
159 
160 static
161 int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
162 {
163  int ret;
164 
165  ret = iso_get_ecma119_name(img->opts, img->input_charset, img->image->id,
166  iso->name, iso->type, name, 0);
167  return ret;
168 }
169 
171 {
172  if (img->rr_reloc_node == node &&
173  node != img->root && node != img->partition_root &&
174  (img->opts->rr_reloc_flags & 2))
175  return 1;
176  return 0;
177 }
178 
179 static
181 {
182  Ecma119Node *ecma;
183 
184  ecma = calloc(1, sizeof(Ecma119Node));
185  if (ecma == NULL) {
186  return ISO_OUT_OF_MEM;
187  }
188 
189  ecma->node = iso;
190  iso_node_ref(iso);
191  ecma->nlink = 1;
192  *node = ecma;
193  return ISO_SUCCESS;
194 }
195 
196 /**
197  * Create a new ECMA-119 node representing a directory from a iso directory
198  * node.
199  */
200 static
201 int create_dir(Ecma119Image *img, IsoDir *iso, Ecma119Node **node)
202 {
203  int ret;
204  Ecma119Node **children = NULL;
205  struct ecma119_dir_info *dir_info;
206 
207  if (iso->nchildren > 0) {
208  children = calloc(1, sizeof(void*) * iso->nchildren);
209  if (children == NULL)
210  return ISO_OUT_OF_MEM;
211  }
212 
213  dir_info = calloc(1, sizeof(struct ecma119_dir_info));
214  if (dir_info == NULL) {
215  if (children != NULL)
216  free(children);
217  return ISO_OUT_OF_MEM;
218  }
219 
220  ret = create_ecma119_node(img, (IsoNode*)iso, node);
221  if (ret < 0) {
222  if (children != NULL)
223  free(children);
224  free(dir_info);
225  return ret;
226  }
227  (*node)->type = ECMA119_DIR;
228  (*node)->info.dir = dir_info;
229  (*node)->info.dir->nchildren = 0;
230  (*node)->info.dir->children = children;
231  return ISO_SUCCESS;
232 }
233 
234 
235 static
237 {
238  int ret;
239  off_t size;
240 
241  size = iso_stream_get_size(iso->stream);
242  if (size > (off_t)MAX_ISO_FILE_SECTION_SIZE && img->opts->iso_level != 3) {
243  char *ipath = iso_tree_get_node_path(ISO_NODE(iso));
245  "File \"%s\" cannot be added to image because "
246  "its size is 4 GiB or larger", ipath);
247  free(ipath);
248  return ISO_FILE_TOO_BIG;
249  }
250  ret = iso_file_src_create(img, iso, src);
251  if (ret < 0) {
252  return ret;
253  }
254  return 0;
255 }
256 
257 
258 /**
259  * Create a new ECMA-119 node representing a regular file from a iso file
260  * node.
261  */
262 static
264 {
265  int ret;
266  IsoFileSrc *src;
267 
268  ret = create_file_src(img, iso, &src);
269  if (ret < 0) {
270  return ret;
271  }
272 
273  ret = create_ecma119_node(img, (IsoNode*)iso, node);
274  if (ret < 0) {
275  /*
276  * the src doesn't need to be freed, it is free together with
277  * the Ecma119Image
278  */
279  return ret;
280  }
281  (*node)->type = ECMA119_FILE;
282  (*node)->info.file = src;
283 
284  return ret;
285 }
286 
287 /**
288  * Create a new ECMA-119 node representing a regular file from an El-Torito
289  * boot catalog
290  */
291 static
293 {
294  int ret;
295  IsoFileSrc *src;
296 
297  ret = el_torito_catalog_file_src_create(img, &src);
298  if (ret < 0) {
299  return ret;
300  }
301 
302  ret = create_ecma119_node(img, (IsoNode*)iso, node);
303  if (ret < 0) {
304  /*
305  * the src doesn't need to be freed, it is free together with
306  * the Ecma119Image
307  */
308  return ret;
309  }
310  (*node)->type = ECMA119_FILE;
311  (*node)->info.file = src;
312 
313  return ret;
314 }
315 
316 /**
317  * Create a new ECMA-119 node representing a symbolic link from a iso symlink
318  * node.
319  */
320 static
322 {
323  int ret;
324 
325  ret = create_ecma119_node(img, (IsoNode*)iso, node);
326  if (ret < 0) {
327  return ret;
328  }
329  (*node)->type = ECMA119_SYMLINK;
330  return ISO_SUCCESS;
331 }
332 
333 /**
334  * Create a new ECMA-119 node representing a special file.
335  */
336 static
338 {
339  int ret;
340 
341  ret = create_ecma119_node(img, (IsoNode*)iso, node);
342  if (ret < 0) {
343  return ret;
344  }
345  (*node)->type = ECMA119_SPECIAL;
346  return ISO_SUCCESS;
347 }
348 
350 {
351  if (node == NULL) {
352  return;
353  }
354  if (node->type == ECMA119_DIR) {
355  size_t i;
356  for (i = 0; i < node->info.dir->nchildren; i++) {
357  ecma119_node_free(node->info.dir->children[i]);
358  }
359  if (node->info.dir->children != NULL)
360  free(node->info.dir->children);
361  free(node->info.dir);
362  }
363  free(node->iso_name);
364  iso_node_unref(node->node);
365  free(node);
366 }
367 
368 
369 static
371 {
372  int ret;
373  struct iso_filesrc_list_item *item;
374 
375  LIBISO_ALLOC_MEM(item, struct iso_filesrc_list_item, 1);
376  item->src = src;
377  item->next = image->ecma119_hidden_list;
378  image->ecma119_hidden_list = item;
379  ret = ISO_SUCCESS;
380 ex:
381  return ret;
382 }
383 
384 
386 {
387  struct iso_filesrc_list_item *item, *next;
388 
389  for (item = *start_item; item != NULL; item = next) {
390  next = item->next;
391  LIBISO_FREE_MEM(item);
392  }
393  return ISO_SUCCESS;
394 }
395 
396 
397 /**
398  * @param flag
399  * bit0= iso is in a hidden directory. Thus hide it.
400  * @return
401  * 1 success, 0 node ignored, < 0 error
402  *
403  */
404 static
405 int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree,
406  int depth, int pathlen, int flag)
407 {
408  int ret, hidden;
409  Ecma119Node *node = NULL;
410  int max_path;
411  char *iso_name= NULL, *ipath = NULL;
412  IsoFileSrc *src = NULL;
413  IsoWriteOpts *opts;
414 
415  if (image == NULL || iso == NULL || tree == NULL) {
416  return ISO_NULL_POINTER;
417  }
418  opts = image->opts;
419  *tree = NULL;
420 
421  hidden = flag & 1;
422  if (iso->hidden & LIBISO_HIDE_ON_RR) {
423  hidden = 1;
424  if (!((iso->hidden & LIBISO_HIDE_BUT_WRITE) ||
425  iso->type == LIBISO_BOOT)) {
426  return 0; /* file will be ignored */
427  }
428  }
429 
430  if (hidden) {
431  max_path= pathlen;
432  } else {
433  ret = get_iso_name(image, iso, &iso_name);
434  if (ret < 0) {
435  iso_name = NULL; /* invalid, do not free */
436  goto ex;
437  }
438  max_path = pathlen + 1 + (iso_name ? strlen(iso_name) : 0);
439  if (!opts->rockridge) {
440  if ((iso->type == LIBISO_DIR && depth > 8) &&
441  !opts->allow_deep_paths) {
442  ipath = iso_tree_get_node_path(iso);
444  0, "File \"%s\" can't be added, "
445  "because directory depth "
446  "is greater than 8.", ipath);
447  goto ex;
448  } else if (max_path > 255 && !opts->allow_longer_paths) {
449  ipath = iso_tree_get_node_path(iso);
451  0, "File \"%s\" can't be added, "
452  "because path length "
453  "is greater than 255 characters", ipath);
454  goto ex;
455  }
456  }
457  }
458 
459  switch (iso->type) {
460  case LIBISO_FILE:
461  if (hidden) {
462  ret = create_file_src(image, (IsoFile *) iso, &src);
463  if (ret <= 0)
464  goto ex;
465  ret = add_to_hidden_list(image, src);
466  } else {
467  ret = create_file(image, (IsoFile*)iso, &node);
468  }
469  break;
470  case LIBISO_SYMLINK:
471  if (hidden) {
472  ret = 0; /* Hidden means non-existing */
473  goto ex;
474  }
475  if (opts->rockridge) {
476  ret = create_symlink(image, (IsoSymlink*)iso, &node);
477  } else {
478  /* symlinks are only supported when RR is enabled */
479  char *ipath = iso_tree_get_node_path(iso);
480  ret = iso_msg_submit(image->image->id, ISO_FILE_IGNORED, 0,
481  "File \"%s\" ignored. Symlinks need RockRidge extensions.",
482  ipath);
483  free(ipath);
484  }
485  break;
486  case LIBISO_SPECIAL:
487  if (hidden) {
488  ret = 0; /* Hidden means non-existing */
489  goto ex;
490  }
491  if (opts->rockridge) {
492  ret = create_special(image, (IsoSpecial*)iso, &node);
493  } else {
494  /* special files are only supported when RR is enabled */
495  char *ipath = iso_tree_get_node_path(iso);
496  ret = iso_msg_submit(image->image->id, ISO_FILE_IGNORED, 0,
497  "File \"%s\" ignored. Special files need RockRidge extensions.",
498  ipath);
499  free(ipath);
500  }
501  break;
502  case LIBISO_BOOT:
503  if (image->eltorito) {
504  if (hidden) {
505  ret = el_torito_catalog_file_src_create(image, &src);
506  if (ret <= 0)
507  goto ex;
508  ret = add_to_hidden_list(image, src);
509  } else {
510  ret = create_boot_cat(image, (IsoBoot*)iso, &node);
511  }
512  } else {
513  /* log and ignore */
514  ret = iso_msg_submit(image->image->id, ISO_FILE_IGNORED, 0,
515  "El-Torito catalog found on a image without El-Torito.");
516  }
517  break;
518  case LIBISO_DIR:
519  {
520  IsoNode *pos;
521  IsoDir *dir = (IsoDir*)iso;
522 
523  if (!hidden) {
524  ret = create_dir(image, dir, &node);
525  if (ret < 0) {
526  goto ex;
527  }
528  if (depth == 1) { /* root is default */
529  image->rr_reloc_node = node;
530  } else if (depth == 2) {
531  /* Directories in root may be used as relocation dir */
532  if (opts->rr_reloc_dir != NULL)
533  if (opts->rr_reloc_dir[0] != 0 &&
534  strcmp(iso->name, opts->rr_reloc_dir) == 0)
535  image->rr_reloc_node = node;
536  }
537  }
538  ret = ISO_SUCCESS;
539  pos = dir->children;
540  while (pos) {
541  int cret;
542  Ecma119Node *child;
543  cret = create_tree(image, pos, &child, depth + 1, max_path,
544  !!hidden);
545  if (cret < 0) {
546  /* error */
547  ret = cret;
548  break;
549  } else if (cret == ISO_SUCCESS && !hidden) {
550  /* add child to this node */
551  int nchildren = node->info.dir->nchildren++;
552  node->info.dir->children[nchildren] = child;
553  child->parent = node;
554  }
555  pos = pos->next;
556  }
557  }
558  break;
559  default:
560  /* should never happen */
561  ret = ISO_ASSERT_FAILURE;
562  goto ex;
563  }
564  if (ret <= 0) {
565  goto ex;
566  }
567  if (!hidden) {
568  node->iso_name = iso_name;
569  iso_name = NULL; /* now owned by node, do not free */
570  *tree = node;
571  node = NULL; /* now owned by caller, do not free */
572  }
573  ret = ISO_SUCCESS;
574 ex:
575  if (iso_name != NULL)
576  free(iso_name);
577  if (ipath != NULL)
578  free(ipath);
579  if (node != NULL)
580  ecma119_node_free(node);
581  if (hidden && ret == ISO_SUCCESS)
582  ret = 0;
583  /* The sources of hidden files are now owned by the rb-tree */
584  return ret;
585 }
586 
587 /**
588  * Compare the iso name of two ECMA-119 nodes
589  */
590 static
591 int cmp_node_name(const void *f1, const void *f2)
592 {
593  Ecma119Node *f = *((Ecma119Node**)f1);
594  Ecma119Node *g = *((Ecma119Node**)f2);
595  return strcmp(f->iso_name, g->iso_name);
596 }
597 
598 /**
599  * Sorts a the children of each directory in the ECMA-119 tree represented
600  * by \p root, according to the order specified in ECMA-119, section 9.3.
601  */
602 static
604 {
605  size_t i;
606 
607  if (root->info.dir->children == NULL)
608  return;
609  qsort(root->info.dir->children, root->info.dir->nchildren, sizeof(void*),
610  cmp_node_name);
611  for (i = 0; i < root->info.dir->nchildren; i++) {
612  if (root->info.dir->children[i]->type == ECMA119_DIR)
613  sort_tree(root->info.dir->children[i]);
614  }
615 }
616 
617 /**
618  * Ensures that the ISO name of each children of the given dir is unique,
619  * changing some of them if needed.
620  * It also ensures that resulting filename is always <= than given
621  * max_name_len, including extension. If needed, the extension will be reduced,
622  * but never under 3 characters.
623  */
624 static
625 int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
626  int max_dir_len)
627 {
628  int ret;
629  int i, nchildren;
630  Ecma119Node **children;
631  IsoHTable *table;
632  int need_sort = 0;
633 
634  nchildren = dir->info.dir->nchildren;
635  children = dir->info.dir->children;
636 
637  if (nchildren <= 0)
638  return ISO_SUCCESS; /* nothing to do */
639 
640  /* a hash table will temporary hold the names, for fast searching */
641  ret = iso_htable_create((nchildren * 100) / 80, iso_str_hash,
642  (compare_function_t)strcmp, &table);
643  if (ret < 0) {
644  return ret;
645  }
646  for (i = 0; i < nchildren; ++i) {
647  char *name = children[i]->iso_name;
648  ret = iso_htable_add(table, name, name);
649  if (ret < 0) {
650  goto mangle_cleanup;
651  }
652  }
653 
654  for (i = 0; i < nchildren; ++i) {
655  char *name, *ext;
656  char full_name[40];
657  const int full_max_len = 40 - 1;
658  int max; /* computed max len for name, without extension */
659  int j = i;
660  int digits = 1; /* characters to change per name */
661 
662  /* first, find all child with same name */
663  while (j + 1 < nchildren && !cmp_node_name(children + i, children + j
664  + 1)) {
665  ++j;
666  }
667  if (j == i) {
668  /* name is unique */
669  continue;
670  }
671 
672  if (img->opts->untranslated_name_len) {
673  /* This should not happen because no two IsoNode names should be
674  identical and only unaltered IsoNode names should be seen here.
675  Thus the Ema119Node names should be unique.
676  */
678  "ECMA-119 file name collision: '%s'",
679  children[i]->iso_name);
680  ret = ISO_NAME_NEEDS_TRANSL;
681  goto mangle_cleanup;
682  }
683 
684  /*
685  * A max of 7 characters is good enough, it allows handling up to
686  * 9,999,999 files with same name. We can increment this to
687  * max_name_len, but the int_pow() function must then be modified
688  * to return a bigger integer.
689  */
690  while (digits < 8) {
691  int ok, k;
692  char *dot;
693  int change = 0; /* number to be written */
694 
695  /* copy name to buffer */
696  strncpy(full_name, children[i]->iso_name, full_max_len);
697  full_name[full_max_len] = 0;
698 
699  /* compute name and extension */
700  dot = strrchr(full_name, '.');
701  if (dot != NULL &&
702  (children[i]->type != ECMA119_DIR ||
703  img->opts->allow_dir_id_ext)) {
704 
705  /*
706  * File (normally not dir) with extension
707  * Note that we don't need to check for placeholders, as
708  * tree reparent happens later, so no placeholders can be
709  * here at this time.
710  */
711  int extlen;
712  full_name[dot - full_name] = '\0';
713  name = full_name;
714  ext = dot + 1;
715 
716  /*
717  * For iso level 1 we force ext len to be 3, as name
718  * can't grow on the extension space
719  */
720  extlen = (max_file_len == 12) ? 3 : strlen(ext);
721  max = max_file_len - extlen - 1 - digits;
722  if (max <= 0) {
723  /* this can happen if extension is too long */
724  if (extlen + max > 3) {
725  /*
726  * reduce extension len, to give name an extra char
727  * note that max is negative or 0
728  */
729  extlen = extlen + max - 1;
730  ext[extlen] = '\0';
731  max = max_file_len - extlen - 1 - digits;
732  } else {
733  /*
734  * error, we don't support extensions < 3
735  * This can't happen with current limit of digits.
736  */
737  ret = ISO_ERROR;
738  goto mangle_cleanup;
739  }
740  }
741  /* ok, reduce name by digits */
742  if (name + max < dot) {
743  name[max] = '\0';
744  }
745  } else {
746  /* Directory (normally), or file without extension */
747  if (children[i]->type == ECMA119_DIR) {
748  max = max_dir_len - digits;
749  dot = NULL; /* dots (normally) have no meaning in dirs */
750  } else {
751  max = max_file_len - digits;
752  }
753  name = full_name;
754  if ((size_t) max < strlen(name)) {
755  name[max] = '\0';
756  }
757  /* let ext be an empty string */
758  ext = name + strlen(name);
759  }
760 
761  ok = 1;
762  /* change name of each file */
763  for (k = i; k <= j; ++k) {
764  char tmp[40];
765  char fmt[16];
766  if (dot != NULL) {
767  sprintf(fmt, "%%s%%0%dd.%%s", digits);
768  } else {
769  sprintf(fmt, "%%s%%0%dd%%s", digits);
770  }
771  while (1) {
772  sprintf(tmp, fmt, name, change, ext);
773  ++change;
774  if (change > int_pow(10, digits)) {
775  ok = 0;
776  break;
777  }
778  if (!iso_htable_get(table, tmp, NULL)) {
779  /* the name is unique, so it can be used */
780  break;
781  }
782  }
783  if (ok) {
784  char *new = strdup(tmp);
785  if (new == NULL) {
786  ret = ISO_OUT_OF_MEM;
787  goto mangle_cleanup;
788  }
789 
790 #ifdef Libisofs_extra_verbose_debuG
791  iso_msg_debug(img->image->id, "\"%s\" renamed to \"%s\"",
792  children[k]->iso_name, new);
793 #endif
794 
795  iso_htable_remove_ptr(table, children[k]->iso_name, NULL);
796  free(children[k]->iso_name);
797  children[k]->iso_name = new;
798  iso_htable_add(table, new, new);
799 
800  /*
801  * if we change a name we need to sort again children
802  * at the end
803  */
804  need_sort = 1;
805  } else {
806  /* we need to increment digits */
807  break;
808  }
809  }
810  if (ok) {
811  break;
812  } else {
813  ++digits;
814  }
815  }
816  if (digits == 8) {
818  goto mangle_cleanup;
819  }
820  i = j;
821  }
822 
823  /*
824  * If needed, sort again the files inside dir
825  */
826  if (need_sort) {
827  qsort(children, nchildren, sizeof(void*), cmp_node_name);
828  }
829 
830  ret = ISO_SUCCESS;
831 
832 mangle_cleanup : ;
833  iso_htable_destroy(table, NULL);
834  return ret;
835 }
836 
837 static
838 int mangle_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len,
839  int max_dir_len)
840 {
841  int ret;
842  size_t i;
843 
844  ret = mangle_single_dir(img, dir, max_file_len, max_dir_len);
845  if (ret < 0) {
846  return ret;
847  }
848 
849  /* recurse */
850  for (i = 0; i < dir->info.dir->nchildren; ++i) {
851  if (dir->info.dir->children[i]->type == ECMA119_DIR) {
852  ret = mangle_dir(img, dir->info.dir->children[i], max_file_len,
853  max_dir_len);
854  if (ret < 0) {
855  /* error */
856  return ret;
857  }
858  }
859  }
860  return ISO_SUCCESS;
861 }
862 
863 static
864 int mangle_tree(Ecma119Image *img, Ecma119Node *dir, int recurse)
865 {
866  int max_file, max_dir;
867  Ecma119Node *root;
868 
869  if (img->opts->untranslated_name_len > 0) {
870  max_file = max_dir = img->opts->untranslated_name_len;
871  } else if (img->opts->max_37_char_filenames) {
872  max_file = max_dir = 37;
873  } else if (img->opts->iso_level == 1) {
874  max_file = 12; /* 8 + 3 + 1 */
875  max_dir = 8;
876  } else {
877  max_file = max_dir = 31;
878  }
879  if (dir != NULL) {
880  root = dir;
881  } else if (img->eff_partition_offset > 0) {
882  root = img->partition_root;
883  } else {
884  root = img->root;
885  }
886  if (recurse) {
887  return mangle_dir(img, root, max_file, max_dir);
888  } else {
889  return mangle_single_dir(img, root, max_file, max_dir);
890  }
891 }
892 
893 /**
894  * Create a new ECMA-119 node representing a placeholder for a relocated
895  * dir.
896  *
897  * See IEEE P1282, section 4.1.5 for details
898  */
899 static
901  Ecma119Node **node)
902 {
903  Ecma119Node *ret;
904 
905  ret = calloc(1, sizeof(Ecma119Node));
906  if (ret == NULL) {
907  return ISO_OUT_OF_MEM;
908  }
909 
910  /*
911  * TODO
912  * If real is a dir, while placeholder is a file, ISO name restricctions
913  * are different, what to do?
914  */
915  ret->iso_name = strdup(real->iso_name);
916  if (ret->iso_name == NULL) {
917  free(ret);
918  return ISO_OUT_OF_MEM;
919  }
920 
921  /* take a ref to the IsoNode */
922  ret->node = real->node;
923  iso_node_ref(real->node);
924  ret->parent = parent;
925  ret->type = ECMA119_PLACEHOLDER;
926  ret->info.real_me = real;
927  ret->ino = real->ino;
928  ret->nlink = real->nlink;
929 
930  *node = ret;
931  return ISO_SUCCESS;
932 }
933 
934 static
936 {
937  size_t ret = 0, i;
938  for (i = 0; i < dir->info.dir->nchildren; i++) {
939  size_t len = strlen(dir->info.dir->children[i]->iso_name);
940  ret = MAX(ret, len);
941  }
942  return ret;
943 }
944 
945 /**
946  * Relocates a directory, as specified in Rock Ridge Specification
947  * (see IEEE P1282, section 4.1.5). This is needed when the number of levels
948  * on a directory hierarchy exceeds 8, or the length of a path is higher
949  * than 255 characters, as specified in ECMA-119, section 6.8.2.1
950  */
951 static
952 int reparent(Ecma119Node *child, Ecma119Node *parent)
953 {
954  int ret;
955  size_t i;
956  Ecma119Node *placeholder;
957 
958  /* replace the child in the original parent with a placeholder */
959  for (i = 0; i < child->parent->info.dir->nchildren; i++) {
960  if (child->parent->info.dir->children[i] == child) {
961  ret = create_placeholder(child->parent, child, &placeholder);
962  if (ret < 0) {
963  return ret;
964  }
965  child->parent->info.dir->children[i] = placeholder;
966  break;
967  }
968  }
969 
970  /* just for debug, this should never happen... */
971  if (i == child->parent->info.dir->nchildren) {
972  return ISO_ASSERT_FAILURE;
973  }
974 
975  /* keep track of the real parent */
976  child->info.dir->real_parent = child->parent;
977 
978  /* add the child to its new parent */
979  child->parent = parent;
980  parent->info.dir->nchildren++;
981  parent->info.dir->children = realloc(parent->info.dir->children,
982  sizeof(void*) * parent->info.dir->nchildren);
983  parent->info.dir->children[parent->info.dir->nchildren - 1] = child;
984  return ISO_SUCCESS;
985 }
986 
987 /**
988  * Reorder the tree, if necessary, to ensure that
989  * - the depth is at most 8
990  * - each path length is at most 255 characters
991  * This restriction is imposed by ECMA-119 specification (ECMA-119, 6.8.2.1).
992  *
993  * @param dir
994  * Dir we are currently processing
995  * @param level
996  * Level of the directory in the hierarchy
997  * @param pathlen
998  * Length of the path until dir, including it
999  * @return
1000  * 1 success, < 0 error
1001  */
1002 static
1004  int dir_level, int dir_pathlen)
1005 {
1006  int ret, level, pathlen, newpathlen;
1007  size_t max_path, i;
1008  Ecma119Node *reloc, *child;
1009 
1010  /* might change by relocation */
1011  level = dir_level;
1012  pathlen = dir_pathlen;
1013 
1014  max_path = pathlen + 1 + max_child_name_len(dir);
1015 
1016  if (level > 8 || max_path > 255) {
1017  reloc = img->rr_reloc_node;
1018  if (reloc == NULL) {
1019  if (img->eff_partition_offset > 0) {
1020  reloc = img->partition_root;
1021  } else {
1022  reloc = img->root;
1023  }
1024  }
1025  ret = reparent(dir, reloc);
1026  if (ret < 0) {
1027  return ret;
1028  }
1029 
1030  if (reloc == img->root || reloc == img->partition_root) {
1031  /*
1032  * we are appended to the root's children now, so there is no
1033  * need to recurse (the root will hit us again)
1034  */
1035  return ISO_SUCCESS;
1036  }
1037 
1038  /* dir is now the relocated Ecma119Node */
1039  pathlen = 37 + 1; /* The dir name might get longer by mangling */
1040  level = 2;
1041  if (img->opts->rr_reloc_dir != NULL) {
1042  pathlen += strlen(img->rr_reloc_node->iso_name) + 1;
1043  if(img->opts->rr_reloc_dir[0] != 0)
1044  level = 3;
1045  }
1046  }
1047 
1048  if (ecma119_is_dedicated_reloc_dir(img, (Ecma119Node *) dir))
1049  return ISO_SUCCESS;
1050 
1051  for (i = 0; i < dir->info.dir->nchildren; i++) {
1052  child = dir->info.dir->children[i];
1053  if (child->type == ECMA119_DIR) {
1054  newpathlen = pathlen + 1 + strlen(child->iso_name);
1055  ret = reorder_tree(img, child, level + 1, newpathlen);
1056  if (ret < 0)
1057  return ret;
1058  }
1059  }
1060  return ISO_SUCCESS;
1061 }
1062 
1063 /*
1064  * @param flag
1065  * bit0= recursion
1066  * bit1= count nodes rather than fill them into *nodes
1067  * @return
1068  * <0 error
1069  * bit0= saw ino == 0
1070  * bit1= saw ino != 0
1071  */
1072 static
1074  Ecma119Node **nodes, size_t nodes_size, size_t *node_count,
1075  int flag)
1076 {
1077  int ret, result = 0;
1078  size_t i;
1079  Ecma119Node *child;
1080 
1081  if (!(flag & 1)) {
1082  *node_count = 0;
1083  if (!(flag & 2)) {
1084  /* Register the tree root node */
1085  if (*node_count >= nodes_size) {
1087  "Programming error: Overflow of hardlink sort array");
1088  return ISO_ASSERT_FAILURE;
1089  }
1090  nodes[*node_count] = dir;
1091  }
1092  result|= (dir->ino == 0 ? 1 : 2);
1093  (*node_count)++;
1094  }
1095 
1096  for (i = 0; i < dir->info.dir->nchildren; i++) {
1097  child = dir->info.dir->children[i];
1098  if (!(flag & 2)) {
1099  if (*node_count >= nodes_size) {
1101  "Programming error: Overflow of hardlink sort array");
1102  return ISO_ASSERT_FAILURE;
1103  }
1104  nodes[*node_count] = child;
1105  }
1106  result|= (child->ino == 0 ? 1 : 2);
1107  (*node_count)++;
1108 
1109  if (child->type == ECMA119_DIR) {
1110  ret = make_node_array(img, child,
1111  nodes, nodes_size, node_count, flag | 1);
1112  if (ret < 0)
1113  return ret;
1114  }
1115  }
1116  return result;
1117 }
1118 
1119 /*
1120  * @param flag
1121  * bit0= compare stat properties and attributes
1122  * bit1= treat all nodes with image ino == 0 as unique
1123  */
1124 static
1125 int ecma119_node_cmp_flag(const void *v1, const void *v2, int flag)
1126 {
1127  int ret;
1128  Ecma119Node *n1, *n2;
1129 
1130  n1 = *((Ecma119Node **) v1);
1131  n2 = *((Ecma119Node **) v2);
1132  if (n1 == n2)
1133  return 0;
1134 
1135  ret = iso_node_cmp_flag(n1->node, n2->node, flag & (1 | 2));
1136  return ret;
1137 }
1138 
1139 static
1140 int ecma119_node_cmp_hard(const void *v1, const void *v2)
1141 {
1142  return ecma119_node_cmp_flag(v1, v2, 1);
1143 }
1144 
1145 static
1146 int ecma119_node_cmp_nohard(const void *v1, const void *v2)
1147 {
1148  return ecma119_node_cmp_flag(v1, v2, 1 | 2);
1149 }
1150 
1151 static
1152 int family_set_ino(Ecma119Image *img, Ecma119Node **nodes, size_t family_start,
1153  size_t next_family, ino_t img_ino, ino_t prev_ino, int flag)
1154 {
1155  size_t i;
1156 
1157  if (img_ino != 0) {
1158  /* Check whether this is the same img_ino as in the previous
1159  family (e.g. by property divergence of imported hardlink).
1160  */
1161  if (img_ino == prev_ino)
1162  img_ino = 0;
1163 
1164  /* Accept only if it is within the 32 bit range. */
1165  if (((uint64_t) img_ino) > 0xffffffff)
1166  img_ino = 0;
1167 
1168  }
1169  if (img_ino == 0) {
1170  img_ino = img_give_ino_number(img->image, 0);
1171  }
1172  for (i = family_start; i < next_family; i++) {
1173  nodes[i]->ino = img_ino;
1174  nodes[i]->nlink = next_family - family_start;
1175  }
1176  return 1;
1177 }
1178 
1179 static
1180 int match_hardlinks(Ecma119Image *img, Ecma119Node *dir, int flag)
1181 {
1182  int ret;
1183  size_t nodes_size = 0, node_count = 0, i, family_start;
1184  Ecma119Node **nodes = NULL;
1185  unsigned int fs_id;
1186  dev_t dev_id;
1187  ino_t img_ino = 0, prev_ino = 0;
1188 
1189  ret = make_node_array(img, dir, nodes, nodes_size, &node_count, 2);
1190  if (ret < 0)
1191  return ret;
1192  nodes_size = node_count;
1193  nodes = (Ecma119Node **) calloc(sizeof(Ecma119Node *), nodes_size);
1194  if (nodes == NULL)
1195  return ISO_OUT_OF_MEM;
1196  ret = make_node_array(img, dir, nodes, nodes_size, &node_count, 0);
1197  if (ret < 0)
1198  goto ex;
1199 
1200  /* Sort according to id tuples, IsoFileSrc identity, properties, xattr. */
1201  if (img->opts->hardlinks)
1202  qsort(nodes, node_count, sizeof(Ecma119Node *), ecma119_node_cmp_hard);
1203  else
1204  qsort(nodes, node_count, sizeof(Ecma119Node *),
1206 
1207  /* Hand out image inode numbers to all Ecma119Node.ino == 0 .
1208  Same sorting rank gets same inode number.
1209  Split those image inode number families where the sort criterion
1210  differs.
1211  */
1212  iso_node_get_id(nodes[0]->node, &fs_id, &dev_id, &img_ino, 1);
1213  family_start = 0;
1214  for (i = 1; i < node_count; i++) {
1215  if (nodes[i]->type != ECMA119_DIR &&
1216  ecma119_node_cmp_hard(nodes + (i - 1), nodes + i) == 0) {
1217  /* Still in same ino family */
1218  if (img_ino == 0) { /* Just in case any member knows its img_ino */
1219  iso_node_get_id(nodes[0]->node, &fs_id, &dev_id, &img_ino, 1);
1220  }
1221  continue;
1222  }
1223  family_set_ino(img, nodes, family_start, i, img_ino, prev_ino, 0);
1224  prev_ino = img_ino;
1225  iso_node_get_id(nodes[i]->node, &fs_id, &dev_id, &img_ino, 1);
1226  family_start = i;
1227  }
1228  family_set_ino(img, nodes, family_start, i, img_ino, prev_ino, 0);
1229 
1230  ret = ISO_SUCCESS;
1231 ex:;
1232  if (nodes != NULL)
1233  free((char *) nodes);
1234  return ret;
1235 }
1236 
1238 {
1239  int ret;
1240  Ecma119Node *root;
1241 
1242  ret = create_tree(img, (IsoNode*)img->image->root, &root, 1, 0, 0);
1243  if (ret <= 0) {
1244  if (ret == 0) {
1245  /* unexpected error, root ignored!! This can't happen */
1246  ret = ISO_ASSERT_FAILURE;
1247  }
1248  return ret;
1249  }
1250  if (img->eff_partition_offset > 0) {
1251  img->partition_root = root;
1252  } else {
1253  img->root = root;
1254  }
1255 
1256  iso_msg_debug(img->image->id, "Matching hardlinks...");
1257  ret = match_hardlinks(img, root, 0);
1258  if (ret < 0) {
1259  return ret;
1260  }
1261 
1262  iso_msg_debug(img->image->id, "Sorting the low level tree...");
1263  sort_tree(root);
1264 
1265  iso_msg_debug(img->image->id, "Mangling names...");
1266  ret = mangle_tree(img, NULL, 1);
1267  if (ret < 0) {
1268  return ret;
1269  }
1270 
1271  if (img->opts->rockridge && !img->opts->allow_deep_paths) {
1272 
1273  /* Relocate deep directories, according to RRIP, 4.1.5 */
1274  ret = reorder_tree(img, root, 1, 0);
1275  if (ret < 0) {
1276  return ret;
1277  }
1278 
1279  /*
1280  * and we need to remangle the root directory, as the function
1281  * above could insert new directories into the relocation directory.
1282  * Note that recurse = 0, as we don't need to recurse.
1283  */
1284  ret = mangle_tree(img, img->rr_reloc_node, 0);
1285  if (ret < 0) {
1286  return ret;
1287  }
1288  }
1289 
1290  return ISO_SUCCESS;
1291 }
1292 
1293 /**
1294  * Search the tree for a certain IsoNode and return its owning Ecma119Node
1295  * or NULL.
1296  */
1297 static
1299 {
1300  size_t i;
1301  Ecma119Node *res = NULL;
1302 
1303  if (root->node == node)
1304  return root;
1305  for (i = 0; i < root->info.dir->nchildren && res == NULL; i++) {
1306  if (root->info.dir->children[i]->type == ECMA119_DIR)
1307  res = search_iso_node(root->info.dir->children[i], node);
1308  else if (root->info.dir->children[i]->node == node)
1309  res = root->info.dir->children[i];
1310  }
1311  return res;
1312 }
1313 
1314 
1316 {
1317  Ecma119Node *res = NULL;
1318 
1319  if (img->root != NULL)
1320  res = search_iso_node(img->root, node);
1321  return res;
1322 }
1323 
#define MAX_ISO_FILE_SECTION_SIZE
Definition: ecma119.h:33
static int ecma119_node_cmp_nohard(const void *v1, const void *v2)
static int create_placeholder(Ecma119Node *parent, Ecma119Node *real, Ecma119Node **node)
Definition: ecma119_tree.c:900
int ecma119_is_dedicated_reloc_dir(Ecma119Image *img, Ecma119Node *node)
Definition: ecma119_tree.c:170
static int reparent(Ecma119Node *child, Ecma119Node *parent)
Definition: ecma119_tree.c:952
static Ecma119Node * search_iso_node(Ecma119Node *root, IsoNode *node)
static int reorder_tree(Ecma119Image *img, Ecma119Node *dir, int dir_level, int dir_pathlen)
static int make_node_array(Ecma119Image *img, Ecma119Node *dir, Ecma119Node **nodes, size_t nodes_size, size_t *node_count, int flag)
void ecma119_node_free(Ecma119Node *node)
Definition: ecma119_tree.c:349
static void sort_tree(Ecma119Node *root)
Definition: ecma119_tree.c:603
static int ecma119_node_cmp_hard(const void *v1, const void *v2)
static int create_ecma119_node(Ecma119Image *img, IsoNode *iso, Ecma119Node **node)
Definition: ecma119_tree.c:180
static int ecma119_node_cmp_flag(const void *v1, const void *v2, int flag)
static int create_file_src(Ecma119Image *img, IsoFile *iso, IsoFileSrc **src)
Definition: ecma119_tree.c:236
static size_t max_child_name_len(Ecma119Node *dir)
Definition: ecma119_tree.c:935
static int mangle_single_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len, int max_dir_len)
Definition: ecma119_tree.c:625
static int create_symlink(Ecma119Image *img, IsoSymlink *iso, Ecma119Node **node)
Definition: ecma119_tree.c:321
static int create_file(Ecma119Image *img, IsoFile *iso, Ecma119Node **node)
Definition: ecma119_tree.c:263
static int mangle_dir(Ecma119Image *img, Ecma119Node *dir, int max_file_len, int max_dir_len)
Definition: ecma119_tree.c:838
int iso_filesrc_list_destroy(struct iso_filesrc_list_item **start_item)
Definition: ecma119_tree.c:385
static int match_hardlinks(Ecma119Image *img, Ecma119Node *dir, int flag)
static int mangle_tree(Ecma119Image *img, Ecma119Node *dir, int recurse)
Definition: ecma119_tree.c:864
int iso_get_ecma119_name(IsoWriteOpts *opts, char *input_charset, int imgid, char *node_name, enum IsoNodeType node_type, char **name, int flag)
Definition: ecma119_tree.c:34
static int create_tree(Ecma119Image *image, IsoNode *iso, Ecma119Node **tree, int depth, int pathlen, int flag)
Definition: ecma119_tree.c:405
static int add_to_hidden_list(Ecma119Image *image, IsoFileSrc *src)
Definition: ecma119_tree.c:370
int ecma119_tree_create(Ecma119Image *img)
static int cmp_node_name(const void *f1, const void *f2)
Definition: ecma119_tree.c:591
Ecma119Node * ecma119_search_iso_node(Ecma119Image *img, IsoNode *node)
static int family_set_ino(Ecma119Image *img, Ecma119Node **nodes, size_t family_start, size_t next_family, ino_t img_ino, ino_t prev_ino, int flag)
static int create_special(Ecma119Image *img, IsoSpecial *iso, Ecma119Node **node)
Definition: ecma119_tree.c:337
static int get_iso_name(Ecma119Image *img, IsoNode *iso, char **name)
Definition: ecma119_tree.c:161
static int create_dir(Ecma119Image *img, IsoDir *iso, Ecma119Node **node)
Definition: ecma119_tree.c:201
static int create_boot_cat(Ecma119Image *img, IsoBoot *iso, Ecma119Node **node)
Definition: ecma119_tree.c:292
@ ECMA119_PLACEHOLDER
Definition: ecma119_tree.h:22
@ ECMA119_DIR
Definition: ecma119_tree.h:19
@ ECMA119_SPECIAL
Definition: ecma119_tree.h:21
@ ECMA119_SYMLINK
Definition: ecma119_tree.h:20
@ ECMA119_FILE
Definition: ecma119_tree.h:18
int el_torito_catalog_file_src_create(Ecma119Image *target, IsoFileSrc **src)
Definition: eltorito.c:1199
int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
Definition: filesrc.c:69
uint32_t img_give_ino_number(IsoImage *image, int flag)
Definition: image.c:713
char * iso_r_dirid(const char *src, int size, int relaxed)
Definition: util.c:1026
char * iso_1_dirid(const char *src, int relaxed)
Definition: util.c:882
char * iso_2_fileid(const char *src)
Definition: util.c:960
char * iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot)
Definition: util.c:1090
char * iso_1_fileid(const char *src, int relaxed, int force_dots)
Definition: util.c:892
char * iso_2_dirid(const char *src)
Definition: util.c:887
int str2ascii(const char *icharset, const char *input, char **output)
Definition: util.c:392
int int_pow(int base, int power)
Definition: util.c:159
int iso_htable_remove_ptr(IsoHTable *table, void *key, hfree_data_t free_data)
Definition: util_htable.c:236
int iso_htable_add(IsoHTable *table, void *key, void *data)
Definition: util_htable.c:70
int(* compare_function_t)(const void *a, const void *b)
Definition: util.h:343
int iso_htable_create(size_t size, hash_funtion_t hash, compare_function_t compare, IsoHTable **table)
Definition: util_htable.c:321
#define LIBISO_FREE_MEM(pt)
Definition: util.h:627
void iso_htable_destroy(IsoHTable *table, hfree_data_t free_data)
Definition: util_htable.c:290
unsigned int iso_str_hash(const void *key)
Definition: util_htable.c:270
#define LIBISO_ALLOC_MEM(pt, typ, count)
Definition: util.h:615
int iso_htable_get(IsoHTable *table, void *key, void **data)
Definition: util_htable.c:144
#define MAX(a, b)
Definition: util.h:31
void iso_node_unref(IsoNode *node)
Definition: node.c:56
#define ISO_SUCCESS
Definition: libisofs.h:8719
IsoNodeType
Definition: libisofs.h:228
@ LIBISO_BOOT
Definition: libisofs.h:233
@ LIBISO_DIR
Definition: libisofs.h:229
@ LIBISO_FILE
Definition: libisofs.h:230
@ LIBISO_SYMLINK
Definition: libisofs.h:231
@ LIBISO_SPECIAL
Definition: libisofs.h:232
#define ISO_OUT_OF_MEM
Definition: libisofs.h:8745
#define ISO_NODE(n)
Definition: libisofs.h:249
char * iso_tree_get_node_path(IsoNode *node)
Definition: tree.c:1247
off_t iso_stream_get_size(IsoStream *stream)
Definition: stream.c:810
#define ISO_FILE_IMGPATH_WRONG
Definition: libisofs.h:8852
#define ISO_FILE_TOO_BIG
Definition: libisofs.h:8835
#define ISO_FILE_IGNORED
Definition: libisofs.h:8832
void iso_node_ref(IsoNode *node)
Definition: node.c:46
#define ISO_NULL_POINTER
Definition: libisofs.h:8742
@ LIBISO_HIDE_BUT_WRITE
Definition: libisofs.h:326
@ LIBISO_HIDE_ON_RR
Definition: libisofs.h:302
#define ISO_ERROR
Definition: libisofs.h:8734
#define ISO_NAME_NEEDS_TRANSL
Definition: libisofs.h:9085
#define ISO_MANGLE_TOO_MUCH_FILES
Definition: libisofs.h:8868
#define ISO_ASSERT_FAILURE
Definition: libisofs.h:8737
int iso_msg_submit(int imgid, int errcode, int causedby, const char *fmt,...)
Definition: messages.c:579
void iso_msg_debug(int imgid, const char *fmt,...)
Definition: messages.c:253
int iso_node_get_id(IsoNode *node, unsigned int *fs_id, dev_t *dev_id, ino_t *ino_id, int flag)
Definition: node.c:2592
int iso_node_cmp_flag(IsoNode *n1, IsoNode *n2, int flag)
Definition: node.c:2743
Definition: node.h:140
IsoNode * children
Definition: node.h:144
size_t nchildren
Definition: node.h:143
Definition: node.h:149
IsoStream * stream
Definition: node.h:166
int id
Definition: image.h:97
IsoDir * root
Definition: image.h:43
Definition: node.h:100
char * name
Definition: node.h:113
enum IsoNodeType type
Definition: node.h:111
int hidden
Definition: node.h:124
IsoNode * next
Definition: node.h:131
Ecma119Node * real_parent
Definition: ecma119_tree.h:48
Ecma119Node ** children
Definition: ecma119_tree.h:34
struct iso_filesrc_list_item * ecma119_hidden_list
Definition: ecma119.h:758
IsoImage * image
Definition: ecma119.h:560
unsigned int eltorito
Definition: ecma119.h:566
IsoWriteOpts * opts
Definition: ecma119.h:563
Ecma119Node * rr_reloc_node
Definition: ecma119.h:571
char * input_charset
Definition: ecma119.h:591
Ecma119Node * partition_root
Definition: ecma119.h:797
Ecma119Node * root
Definition: ecma119.h:561
uint32_t eff_partition_offset
Definition: ecma119.h:794
union ecma119_node::@0 info
uint32_t ino
Definition: ecma119_tree.h:67
nlink_t nlink
Definition: ecma119_tree.h:69
char * iso_name
Definition: ecma119_tree.h:61
IsoNode * node
Definition: ecma119_tree.h:65
Ecma119Node * real_me
Definition: ecma119_tree.h:78
Ecma119Node * parent
Definition: ecma119_tree.h:63
struct ecma119_dir_info * dir
Definition: ecma119_tree.h:76
enum ecma119_node_type type
Definition: ecma119_tree.h:72
struct iso_filesrc_list_item * next
Definition: ecma119_tree.h:87
unsigned int allow_full_ascii
Definition: ecma119.h:175
unsigned int allow_7bit_ascii
Definition: ecma119.h:182
unsigned int untranslated_name_len
Definition: ecma119.h:326
unsigned int hardlinks
Definition: ecma119.h:221
unsigned int allow_dir_id_ext
Definition: ecma119.h:128
unsigned int max_37_char_filenames
Definition: ecma119.h:154
unsigned int rockridge
Definition: ecma119.h:106
unsigned int allow_deep_paths
Definition: ecma119.h:141
unsigned int allow_longer_paths
Definition: ecma119.h:146
unsigned int allow_lowercase
Definition: ecma119.h:169
int rr_reloc_flags
Definition: ecma119.h:259
unsigned int no_force_dots
Definition: ecma119.h:163
char * rr_reloc_dir
Definition: ecma119.h:258