libisoburn  1.5.4
About: libisoburn is a frontend for the libraries libburn and libisofs which enables creation and expansion of ISO-9660 filesystems on all media and file types supported by libburn. It implements the API and command interpreter of program xorriso, and installs this program as small dynamically linked binary. xorriso is suitable for incremental data backup and for production of bootable ISO 9660 images. A statically linked version is available as GNU xorriso.
  Fossies Dox: libisoburn-1.5.4.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

iso_tree.c
Go to the documentation of this file.
1 
2 /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
3 
4  Copyright 2007-2019 Thomas Schmitt, <scdbackup@gmx.net>
5 
6  Provided under GPL version 2 or later.
7 
8  This file contains functions which access nodes of the
9  libisofs tree model.
10 */
11 
12 #ifdef HAVE_CONFIG_H
13 #include "../config.h"
14 #endif
15 
16 #include <ctype.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <sys/stat.h>
23 #include <sys/time.h>
24 #include <time.h>
25 #include <errno.h>
26 
27 #include <pwd.h>
28 #include <grp.h>
29 
30 
31 #include "xorriso.h"
32 #include "xorriso_private.h"
33 #include "xorrisoburn.h"
34 
35 #include "lib_mgt.h"
36 #include "iso_img.h"
37 #include "iso_tree.h"
38 #include "iso_manip.h"
39 #include "sort_cmp.h"
40 
41 
42 /* @param eff_path returns resulting effective path.
43  Must provide at least SfileadrL bytes of storage.
44  @param flag bit0= do not produce problem events (unless faulty path format)
45  bit1= do not use libisofs (work literally or in disk world)
46  bit2= (implies bit1) this is an address in the disk world
47  bit3= return root directory as "/" and not as ""
48  bit4= (with bit2) determine type of disk file eff_path
49  and return 0 if not existing
50  bit5= (with bit3) this is not a parameter
51  bit6= insist in having an ISO image, even with bits1+2
52  @return -1 = faulty path format, 0 = not found ,
53  1 = found simple node , 2 = found directory
54 */
55 int Xorriso_normalize_img_path(struct XorrisO *xorriso, char *wd,
56  char *img_path, char eff_path[], int flag)
57 {
58  int ret, is_dir= 0, done= 0;
59  IsoImage *volume;
60  IsoDir *dir= NULL;
61  IsoNode *node= NULL;
62  char *path= NULL, *apt, *npt, *cpt, *link_target= NULL;
63 
64  Xorriso_alloc_meM(path, char, SfileadrL);
65  Xorriso_alloc_meM(link_target, char, SfileadrL);
66 
67  if(flag & 4)
68  flag|= 2;
69  if((flag&64) || !(flag&2)) {
70  ret= Xorriso_get_volume(xorriso, &volume, 0);
71  if(ret<=0)
72  goto ex;
73  }
74 
75  eff_path[0]= 0;
76  if(img_path[0]==0) {
77  if(flag&8)
78  strcpy(eff_path, "/");
79  {ret= 2; goto ex;} /* root directory */
80  }
81 
82  apt= npt= path;
83  if(img_path[0]!='/') {
84  strcpy(path, wd);
85  ret= Sfile_add_to_path(path, img_path, 0);
86  if(ret<=0)
87  goto much_too_long;
88  } else
89  if(Sfile_str(path, img_path, 0)<=0)
90  {ret= -1; goto ex;}
91 
92  if(path[0]!='/') {
93  sprintf(xorriso->info_text,
94  "Internal error: Unresolvable relative addressing in iso_rr_path '%s'",
95  img_path);
96  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FATAL", 0);
97  {ret= -1; goto ex;}
98  } else if(path[1]==0) {
99  if(flag&8)
100  strcpy(eff_path, "/");
101  {ret= 2; goto ex;} /* root directory */
102  }
103 
104  if(apt[0] == '.')
105  if(apt[1] == 0 || apt[1] == '/')
106  is_dir= 1;
107  for(npt= apt; !done; apt= npt+1) {
108  npt= strchr(apt, '/');
109  if(npt==NULL) {
110  npt= apt+strlen(apt);
111  done= 1;
112  } else
113  *npt= 0;
114  if(*apt==0) {
115  *apt= '/';
116  apt++;
117  if(done)
118  break;
119  continue;
120  }
121  if(strcmp(apt,".")==0)
122  continue;
123  if(strcmp(apt,"..")==0) {
124  if(!(flag&2)) {
125  node= (IsoNode *) dir;
126  if(node==NULL) {
127 bonked_root:;
128  sprintf(xorriso->info_text,
129  "Relative addressing in path exceeds root directory: ");
130  Text_shellsafe(img_path, xorriso->info_text, 1);
131  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
132  {ret= -1; goto ex;}
133  }
134  dir= iso_node_get_parent(node);
135 
136  /* >>> Get absolute path of node as eff_path, to avoid link problems */;
137 
138  }
139  if(flag & 4) {
140  /* Linux-ish local filesystem semantics:
141  If the parent is a symbolic link, do not ascend to its parent,
142  but to the parent of the link target.
143  >>> ??? Are there systems which do it differently ?
144  */
145  if(Sfile_type(eff_path, 0) == 3) {
146  ret= Xorriso_resolve_link(xorriso, eff_path, link_target, 2);
147  if(ret <= 0)
148  {ret= -1; goto ex;}
149  strcpy(eff_path, link_target);
150  }
151  }
152 
153  /* truncate eff_path */;
154  cpt= strrchr(eff_path, '/');
155  if(cpt==NULL) /* ??? if not flag&2 then this is a bug */
156  goto bonked_root;
157  *cpt= 0;
158  is_dir= 1;
159  continue;
160  }
161  is_dir= 0;
162  ret= Sfile_add_to_path(eff_path, apt, 0);
163  if(ret<=0) {
164 much_too_long:;
165  sprintf(xorriso->info_text, "Effective path gets much too long (%d)",
166  (int) (strlen(eff_path)+strlen(apt)+1));
167  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
168  {ret= -1; goto ex;}
169  }
170  if(!(flag&2)) {
171  dir= (IsoDir *) node;
172  ret= Xorriso_node_from_path(xorriso, volume, eff_path, &node, flag&1);
173  if(ret<=0)
174  {ret= 0; goto ex;}
175  if(dir==NULL) /* could be false with "/dir/.." */
176  dir= iso_node_get_parent(node);
177  is_dir= LIBISO_ISDIR(node);
178  }
179  }
180  if(flag&16) {
181  ret= Sfile_type(eff_path,
182  1|(4*(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&32)))
183  ));
184  if(ret<0)
185  {ret= 0; goto ex;}
186  if(ret==2)
187  is_dir= 1;
188  else
189  is_dir= 0;
190  }
191  ret= 1+!!is_dir;
192 ex:;
193  Xorriso_free_meM(path);
194  Xorriso_free_meM(link_target);
195  return(ret);
196 }
197 
198 
199 int Xorriso_get_node_by_path(struct XorrisO *xorriso,
200  char *in_path, char *eff_path,
201  IsoNode **node, int flag)
202 {
203  int ret;
204  char *path= NULL;
205  IsoImage *volume;
206 
207  Xorriso_alloc_meM(path, char, SfileadrL);
208 
209  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, in_path, path, 0);
210  if(ret<=0)
211  goto ex;
212  if(eff_path!=NULL)
213  strcpy(eff_path, path);
214  ret= Xorriso_get_volume(xorriso, &volume, 0);
215  if(ret<=0)
216  goto ex;
217  ret= Xorriso_node_from_path(xorriso, volume, path, node, 0);
218  if(ret<=0)
219  {ret= 0; goto ex;}
220  ret= 1;
221 ex:;
222  Xorriso_free_meM(path);
223  return(ret);
224 }
225 
226 
227 /* @param flag
228 */
229 int Xorriso_node_get_dev(struct XorrisO *xorriso, IsoNode *node,
230  char *path, dev_t *dev, int flag)
231 {
232  *dev= iso_special_get_dev((IsoSpecial *) node);
233  return(1);
234 }
235 
236 
237 /* @param flag bit0= *node is already valid
238  bit1= add extra block for size estimation
239  bit2= complain loudely if path is missing in image
240  bit3= stbuf is to be used without eventual ACL
241  bit4= try to obtain a better st_nlink count if hardlinks
242  are enabled
243  bit5= do not look for truncated versions of path component
244 */
245 int Xorriso_fake_stbuf(struct XorrisO *xorriso, char *path, struct stat *stbuf,
246  IsoNode **node, int flag)
247 {
248  int ret, min_hl, max_hl, node_idx, i;
249  IsoImage *volume;
250  IsoBoot *bootcat;
251  uint32_t lba;
252  char *catcontent = NULL;
253  off_t catsize;
254  dev_t dev_number;
255 
256  memset((char *) stbuf, 0, sizeof(struct stat));
257  if(!(flag&1)) {
258  ret= Xorriso_get_volume(xorriso, &volume, 0);
259  if(ret<=0)
260  return(-1);
261  ret= Xorriso_node_from_path(xorriso, volume, path, node,
262  ((flag >> 4) & 2) | !(flag&4));
263  if(ret<=0)
264  *node= NULL;
265  }
266  if(*node==NULL)
267  return(0);
268 
269  /* >>> stbuf->st_dev */
270  /* >>> stbuf->st_ino */
271 
272  if(flag & 8)
273  stbuf->st_mode= iso_node_get_perms_wo_acl(*node) & 07777;
274  else
275  stbuf->st_mode= iso_node_get_permissions(*node) & 07777;
276  if(LIBISO_ISDIR(*node))
277  stbuf->st_mode|= S_IFDIR;
278  else if(LIBISO_ISREG(*node))
279  stbuf->st_mode|= S_IFREG;
280  else if(LIBISO_ISLNK(*node))
281  stbuf->st_mode|= S_IFLNK;
282  else if(LIBISO_ISCHR(*node)) {
283  stbuf->st_mode|= S_IFCHR;
284  Xorriso_node_get_dev(xorriso, *node, path, &dev_number, 0);
285  stbuf->st_rdev= dev_number;
286  } else if(LIBISO_ISBLK(*node)) {
287  stbuf->st_mode|= S_IFBLK;
288  /* ts B11124:
289  Debian mips and mipsel have sizeof(stbuf.st_rdev) == 4
290  whereas sizeof(dev_t) is 8.
291  This workaround assumes that the returned numbers fit into 4 bytes.
292  The may stem from the local filesystem or from the ISO image.
293  At least there will be no memory corruption but only an integer rollover.
294  */
295  Xorriso_node_get_dev(xorriso, *node, path, &dev_number, 0);
296  stbuf->st_rdev= dev_number;
297  } else if(LIBISO_ISFIFO(*node))
298  stbuf->st_mode|= S_IFIFO;
299  else if(LIBISO_ISSOCK(*node))
300  stbuf->st_mode|= S_IFSOCK;
301  else if(LIBISO_ISBOOT(*node))
302  stbuf->st_mode|= Xorriso_IFBOOT;
303 
304  /* >>> With directories this should be : number of subdirs + 2 */
305  /* >>> ??? How to obtain RR hardlink number for other types ? */
306  /* This may get overridden farther down */
307  stbuf->st_nlink= 1;
308 
309  stbuf->st_uid= iso_node_get_uid(*node);
310  stbuf->st_gid= iso_node_get_gid(*node);
311 
312  if(LIBISO_ISREG(*node))
313  stbuf->st_size= iso_file_get_size((IsoFile *) *node)+ (2048 * !!(flag&2));
314  else if(LIBISO_ISBOOT(*node)) {
315  ret= Xorriso_get_volume(xorriso, &volume, 0);
316  if(ret <= 0)
317  return(-1);
318  ret= iso_image_get_bootcat(volume, &bootcat, &lba, &catcontent, &catsize);
319  if(catcontent != NULL)
320  free(catcontent);
321  if(ret < 0) {
322  Xorriso_process_msg_queues(xorriso,0);
323  return(-1);
324  }
325  stbuf->st_size= catsize;
326  } else
327  stbuf->st_size= 0;
328 
329  stbuf->st_blksize= 2048;
330  stbuf->st_blocks= stbuf->st_size / (off_t) 2048;
331  if(stbuf->st_blocks * (off_t) 2048 != stbuf->st_size)
332  stbuf->st_blocks++;
333 
334  stbuf->st_atime= iso_node_get_atime(*node);
335  stbuf->st_mtime= iso_node_get_mtime(*node);
336  stbuf->st_ctime= iso_node_get_ctime(*node);
337 
338  if(LIBISO_ISDIR(*node) || (xorriso->ino_behavior & 1) || (!(flag & 16)) ||
339  xorriso->hln_array == NULL)
340  return(1);
341 
342  /* Try to obtain a better link count */
343  ret= Xorriso_search_hardlinks(xorriso, *node, &node_idx, &min_hl, &max_hl, 0);
344  if(ret < 0)
345  return(ret);
346  if(ret > 0 && node_idx >= 0) {
347  for(i= min_hl; i <= max_hl; i++) {
348  if(i == node_idx)
349  continue;
350  /* Check whether node is still valid */
351  if(iso_node_get_parent(xorriso->hln_array[i]) != NULL)
352  stbuf->st_nlink++;
353  }
354  }
355  return(1);
356 }
357 
358 
359 /* @param flag >>> bit0= follow links (i.e. stat() rather than lstat()
360  bit1= do not return -2 on severe errors
361  bit2= complain loudely if path is missing in image
362 */
363 int Xorriso_iso_lstat(struct XorrisO *xorriso, char *path, struct stat *stbuf,
364  int flag)
365 {
366  int ret;
367  IsoNode *node;
368 
369  if(flag&1) {
370 
371  /* >>> follow link in ISO image */;
372 
373  }
374 
375  ret= Xorriso_fake_stbuf(xorriso, path, stbuf, &node, flag&4);
376  if(ret>0)
377  return(0);
378  if(ret<0 && !(flag&2))
379  return(-2);
380  return(-1);
381 }
382 
383 
384 int Xorriso_node_is_valid(struct XorrisO *xorriso, IsoNode *in_node, int flag)
385 {
386  IsoNode *node, *parent;
387 
388  for(node= in_node; 1; node= parent) {
389  parent= (IsoNode *) iso_node_get_parent(node);
390  if(parent == node)
391  break;
392  if(parent == NULL)
393  return(0); /* Node is not in the tree (any more) */
394  }
395  return(1);
396 }
397 
398 
399 int Xorriso_path_from_node(struct XorrisO *xorriso, IsoNode *in_node,
400  char path[SfileadrL], int flag)
401 {
402  int ret, i, comp_count= 0;
403  IsoNode *node, *parent, **components= NULL;
404  char *wpt, *npt;
405 
406  for(node= in_node; 1; node= parent) {
407  parent= (IsoNode *) iso_node_get_parent(node);
408  if(parent == node)
409  break;
410  if(parent == NULL)
411  return(0); /* Node is not in the tree (any more) */
412  comp_count++;
413  }
414  if(comp_count == 0) {
415  strcpy(path, "/");
416  return(1);
417  }
418  components= calloc(comp_count, sizeof(IsoNode *));
419  if(components == NULL) {
420  Xorriso_no_malloc_memory(xorriso, NULL, 0);
421  ret= -1; goto ex;
422  }
423  i= comp_count;
424  for(node= in_node; 1; node= parent) {
425  parent= (IsoNode *) iso_node_get_parent(node);
426  if(parent == node)
427  break;
428  components[--i]= node;
429  }
430 
431  wpt= path;
432  for(i= 0; i < comp_count; i++) {
433  npt= (char *) iso_node_get_name(components[i]);
434  if((wpt - path) + strlen(npt) + 1 >= SfileadrL) {
435 
436  /* >>> path is getting much too long */;
437 
438  ret= -1; goto ex;
439  }
440  *(wpt++)= '/';
441  strcpy(wpt, npt);
442  wpt+= strlen(npt);
443  *wpt= 0;
444  }
445  ret= 1;
446 ex:;
447  if(components != NULL)
448  free(components);
449  return(ret);
450 }
451 
452 
453 /* <<< The lookup from node pointer will be done by Xorriso_path_from_node()
454  (Currently it runs a full tree traversal)
455  Parameter node and flag bit0 will vanish then
456 */
457 /* @param flag bit0= use lba rather than node pointer
458 */
459 int Xorriso_path_from_lba(struct XorrisO *xorriso, IsoNode *node, int lba,
460  char path[SfileadrL], int flag)
461 {
462  int ret;
463  struct FindjoB *job= NULL;
464  struct stat dir_stbuf;
465  char *found_path;
466 
467  path[0]= 0;
468  if((flag & 1) && lba <= 0)
469  return(0);
470 
471  ret= Findjob_new(&job, "/", 0);
472  if(ret <= 0) {
473  Xorriso_no_findjob(xorriso, "path_from_node", 0);
474  return(ret);
475  }
476  if(flag & 1)
477  Findjob_set_lba_range(job, lba, 1, 0);
478  else
479  Findjob_set_wanted_node(job, (void *) node, 0);
481  ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0,
482  NULL, "/", &dir_stbuf, 0, 0);
483  if(ret > 0) {
484  ret= 1;
485  Findjob_get_found_path(job, &found_path, 0);
486  if(found_path == NULL)
487  ret= 0;
488  else if(Sfile_str(path, found_path, 0) <= 0)
489  ret= -1;
490  }
491  Findjob_destroy(&job, 0);
492  return(ret);
493 }
494 
495 
496 /* @param flag bit0= in_node is valid, do not resolve iso_adr
497  bit2= recognize and parse split parts despite
498  xorriso->split_size <= 0
499 */
500 int Xorriso_identify_split(struct XorrisO *xorriso, char *iso_adr,
501  void *in_node,
502  struct SplitparT **parts, int *count,
503  struct stat *total_stbuf, int flag)
504 {
505  int ret, i, incomplete= 0, overlapping= 0;
506  int partno, total_parts, first_total_parts= -1;
507  off_t offset, bytes, total_bytes, first_total_bytes= -1, first_bytes= -1;
508  off_t size, covered;
509 
510  IsoImage *volume;
511  IsoDir *dir_node;
512  IsoDirIter *iter= NULL;
513  IsoNode *node;
514  char *name;
515  struct stat stbuf, first_stbuf;
516 
517  *count= 0;
518  *parts= NULL;
519 
520  if(xorriso->split_size <= 0 && !(flag & 4))
521  return(0);
522 
523  if(flag&1) {
524  node= (IsoNode *) in_node;
525  } else {
526  ret= Xorriso_get_volume(xorriso, &volume, 0);
527  if(ret<=0)
528  return(-1);
529  ret= Xorriso_node_from_path(xorriso, volume, iso_adr, &node, 1);
530  if(ret<=0)
531  return(-1);
532  }
533  if(!LIBISO_ISDIR(node))
534  return(0);
535  dir_node= (IsoDir *) node;
536 
537  ret= iso_dir_get_children(dir_node, &iter);
538  if(ret<0) {
539 cannot_iter:;
540  Xorriso_cannot_create_iter(xorriso, ret, 0);
541  return(-1);
542  }
543 
544  for(i= 0; iso_dir_iter_next(iter, &node) == 1; i++) {
545  name= (char *) iso_node_get_name(node);
546  ret= Splitpart__parse(name, &partno, &total_parts,
547  &offset, &bytes, &total_bytes, 0);
548  if(ret<=0)
549  {ret= 0; goto ex;}
550  if(i==0) {
551  first_total_parts= total_parts;
552  first_bytes= bytes;
553  first_total_bytes= total_bytes;
554  Xorriso_fake_stbuf(xorriso, "", &first_stbuf, &node, 1);
555  size= first_stbuf.st_size;
556  } else {
557  if(first_total_parts!=total_parts || first_total_bytes!=total_bytes ||
558  (first_bytes!=bytes && partno!=total_parts))
559  {ret= 0; goto ex;}
560  Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1);
561  if(first_stbuf.st_mode != stbuf.st_mode ||
562  first_stbuf.st_uid != stbuf.st_uid ||
563  first_stbuf.st_gid != stbuf.st_gid ||
564  first_stbuf.st_mtime != stbuf.st_mtime ||
565  first_stbuf.st_ctime != stbuf.st_ctime)
566  {ret= 0; goto ex;}
567  size= stbuf.st_size;
568  }
569  /* check for plausible size */
570  if(!((partno != total_parts && size == bytes) ||
571  (partno == total_parts && size <= bytes)))
572  {ret= 0; goto ex;}
573  if(offset != first_bytes * (off_t) (partno - 1))
574  {ret= 0; goto ex;}
575  (*count)++;
576  }
577  if(*count <= 0 || *count != first_total_parts)
578  {ret= 0; goto ex;}
579 
580  ret= Splitparts_new(parts, (*count)+1, 0); /* (have one end marker item) */
581  if(ret<=0)
582  return(ret);
583 
584  iso_dir_iter_free(iter);
585  ret= iso_dir_get_children(dir_node, &iter);
586  if(ret<0)
587  goto cannot_iter;
588  for(i= 0; i<*count; i++) {
589  ret= iso_dir_iter_next(iter, &node);
590  if(ret!=1)
591  break;
592  name= (char *) iso_node_get_name(node);
593  ret= Splitpart__parse(name, &partno, &total_parts,
594  &offset, &bytes, &total_bytes, 0);
595  if(ret<=0)
596  {ret= 0; goto ex;}
597  ret= Splitparts_set(*parts, i, name, partno, total_parts, offset, bytes,
598  total_bytes, 0);
599  if(ret<=0)
600  goto ex;
601  }
602 
603  Splitparts_sort(*parts, *count, 0);
604 
605  covered= 0;
606  for(i= 0; i<*count; i++) {
607  Splitparts_get(*parts, i, &name, &partno, &total_parts, &offset, &bytes,
608  &total_bytes, 0);
609  if(offset>covered)
610  incomplete= 1;
611  else if(offset<covered)
612  overlapping= 1;
613  if(offset+bytes > covered)
614  covered= offset+bytes;
615  }
616  if(total_bytes>covered)
617  incomplete= 1;
618  memcpy(total_stbuf, &first_stbuf, sizeof(struct stat));
619  total_stbuf->st_size= total_bytes;
620  ret= !(overlapping || incomplete);
621 ex:;
622  if(iter!=NULL)
623  iso_dir_iter_free(iter);
624  return(ret);
625 }
626 
627 
628 /* @param flag bit0= node is valid, do not resolve path
629  bit1= insist in complete collection of part files
630  bit2= recognize and parse split parts despite
631  xorriso->split_size <= 0
632 */
633 int Xorriso_is_split(struct XorrisO *xorriso, char *path, void *node,
634  int flag)
635 {
636  struct SplitparT *split_parts= NULL;
637  int split_count= 0, ret;
638  struct stat stbuf;
639 
640  ret= Xorriso_identify_split(xorriso, path, node, &split_parts,
641  &split_count, &stbuf, flag & 7);
642  if(split_parts!=NULL)
643  Splitparts_destroy(&split_parts, split_count, 0);
644  return(ret>0);
645 }
646 
647 
648 /* @param node Opaque handle to IsoNode which is to be inquired instead of path if it is not NULL.
649  @param path is used as address if node is NULL.
650  @param acl_text if acl_text is not NULL, then *acl_text will be set to the
651  ACL text (without comments) of the file object. In this
652  case it finally has to be freed by the caller.
653  @param flag bit0= do not report to result but only retrieve ACL text
654  bit1= check for existence of true ACL (not fabricated),
655  do not allocate and set acl_text but return 1 or 2
656  bit2-3: what ALC to retrieve:
657  0= "access" and "default", mark "default:"
658  1= "access" only
659  2= "default" only, do not mark "default:"
660  bit4= get "access" ACL only if not trivial
661  @return 2 ok, no ACL available, eventual *acl_text will be NULL
662  1 ok, ACL available, eventual *acl_text stems from malloc()
663  <=0 error
664 */
665 int Xorriso_getfacl(struct XorrisO *xorriso, void *in_node, char *path,
666  char **acl_text, int flag)
667 {
668  int ret, d_ret, result_len= 0, pass, what;
669  IsoNode *node;
670  char *text= NULL, *d_text= NULL, *cpt, *npt;
671  uid_t uid;
672  gid_t gid;
673  struct passwd *pwd;
674  struct group *grp;
675 
676  what= (flag >> 2) & 3;
677  if(acl_text != NULL)
678  *acl_text= NULL;
679 
680  node= (IsoNode *) in_node;
681  if(node == NULL) {
682  ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
683  if(ret<=0)
684  goto ex;
685  }
686  ret= iso_node_get_acl_text(node, &text, &d_text, flag & 16);
687  d_ret= (d_text != NULL);
688  if(ret < 0 || d_ret < 0) {
689  if(path != NULL && path[0] != 0) {
690  strcpy(xorriso->info_text, "Error with obtaining ACL of ");
691  Text_shellsafe(path, xorriso->info_text, 1);
692  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
693  }
694  ret= 0; goto ex;
695  }
696  if(flag & 2) {
697  ret= 1 + (ret != 1 && d_ret == 0);
698  goto ex;
699  }
700  if((ret == 0 || ret == 2) && d_ret == 0) {
701  if(flag & 1) {
702  ret= 1 + (ret == 0);
703  goto ex;
704  }
705  strcpy(xorriso->info_text, "No ACL associated with ");
706  Text_shellsafe(path, xorriso->info_text, 1);
707  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
708  if(ret == 0)
709  {ret= 2; goto ex;}
710  }
711 
712  if(!(flag & 1)) {
713  ret= Xorriso_getfname(xorriso, path, 0);
714  if(ret <= 0)
715  goto ex;
716  uid= iso_node_get_uid(node);
717  pwd= getpwuid(uid);
718  if(pwd == NULL)
719  sprintf(xorriso->result_line, "# owner: %.f\n", (double) uid);
720  else
721  sprintf(xorriso->result_line, "# owner: %s\n", pwd->pw_name);
722  Xorriso_result(xorriso, 0);
723  gid= iso_node_get_gid(node);
724  grp= getgrgid(gid);
725  if(grp == NULL)
726  sprintf(xorriso->result_line, "# group: %.f\n", (double) gid);
727  else
728  sprintf(xorriso->result_line, "# group: %s\n", grp->gr_name);
729  Xorriso_result(xorriso, 0);
730  }
731 
732  for(pass= 0; pass < 1 + (acl_text != NULL && !(flag & 2)); pass++) {
733  if(pass) {
734  if(result_len == 0)
735  break;
736  *acl_text= calloc(result_len + 1, 1);
737  if(*acl_text == NULL) {
738  Xorriso_no_malloc_memory(xorriso, NULL, 0);
739  ret= -1; goto ex;
740  }
741  }
742  if(text != NULL && what <= 1) {
743  for(npt= cpt= text; npt != NULL; cpt= npt + 1) {
744  npt= strchr(cpt, '\n');
745  if(npt != NULL)
746  *npt= 0;
747  if(*cpt == 0) {
748  if(d_text != NULL || pass) {
749  if(npt != NULL)
750  *npt= '\n';
751  continue;
752  }
753  } else
754  result_len+= strlen(cpt) + 1;
755  if(pass) {
756  sprintf(*acl_text + strlen(*acl_text), "%s\n", cpt);
757  } else if(!(flag & 1)) {
758  if(Sfile_str(xorriso->result_line, cpt, 0) <= 0)
759  goto too_long;
760  strcat(xorriso->result_line, "\n");
761  Xorriso_result(xorriso, 0);
762  }
763  if(npt != NULL)
764  *npt= '\n';
765  }
766  }
767  if(d_text != NULL && (what == 0 || what == 2)) {
768  for(npt= cpt= d_text; npt != NULL; cpt= npt + 1) {
769  npt= strchr(cpt, '\n');
770  if(npt != NULL)
771  *npt= 0;
772  if(*cpt != 0) {
773  if(pass) {
774  if(what == 0)
775  sprintf(*acl_text + strlen(*acl_text), "default:%s\n", cpt);
776  else
777  sprintf(*acl_text + strlen(*acl_text), "%s\n", cpt);
778  } else {
779  xorriso->result_line[0]= 0;
780  if(what == 0)
781  if(Sfile_str(xorriso->result_line, "default:", 0) <= 0)
782  goto too_long;
783  if(Sfile_str(xorriso->result_line, cpt, 1) <= 0)
784  goto too_long;
785  result_len+= strlen(cpt) + 9;
786  }
787  } else
788  xorriso->result_line[0]= 0;
789  if(pass== 0 && !(flag & 1)) {
790  strcat(xorriso->result_line, "\n");
791  Xorriso_result(xorriso, 0);
792  }
793  if(npt != NULL)
794  *npt= '\n';
795  }
796  }
797  }
798  if(result_len == 0) {
799  if(acl_text != NULL)
800  *acl_text= NULL;
801  ret= 2;
802  } else {
803  ret= 1;
804  }
805 ex:;
806  iso_node_get_acl_text(node, &text, &d_text, 1 << 15);
807  return(ret);
808 too_long:
809  Xorriso_msgs_submit(xorriso, 0, "Oversized ACL", 0, "FAILURE", 0);
810  ret= 0;
811  goto ex;
812 }
813 
814 
815 /*
816  @param flag bit0= do not report to result but only retrieve attr text
817  bit1= path is disk_path
818  bit3= do not ignore non-user attributes
819  bit4= ignore isofs. attributes despite bit3
820  bit5= in case of symbolic link on disk: inquire link target
821  bit6= check for existence of xattr, return 0 or 1
822  (depends also on bit3)
823 */
824 int Xorriso_getfattr(struct XorrisO *xorriso, void *in_node, char *path,
825  char **attr_text, int flag)
826 {
827  int ret= 1, i, bsl_mem, result_len= 0, pass;
828  size_t num_attrs= 0, *value_lengths= NULL;
829  char **names= NULL, **values= NULL, *bsl;
830 
831  if(attr_text != NULL)
832  *attr_text= NULL;
833  if((xorriso->do_aaip & 1024) && !(flag & 8))
834  flag|= 8 | 16;
835  ret= Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names,
836  &value_lengths, &values, flag & (2 | 8 | 32));
837  if(ret <= 0)
838  goto ex;
839  if(flag & 64) {
840  ret= (num_attrs > 0);
841  goto ex;
842  }
843  if(num_attrs == 0)
844  {ret= 2; goto ex;}
845 
846  if(!(flag & 1)) {
847  ret= Xorriso_getfname(xorriso, path, 0);
848  if(ret <= 0)
849  goto ex;
850  }
851  for(pass= 0; pass < 1 + (attr_text != NULL); pass++) {
852  if(pass) {
853  *attr_text= calloc(result_len + 1, 1);
854  if(*attr_text == NULL) {
855  Xorriso_no_malloc_memory(xorriso, NULL, 0);
856  ret= -1; goto ex;
857  }
858  }
859  for(i= 0; i < (int) num_attrs; i++) {
860  if(flag & 16)
861  if(strncmp(names[i], "isofs.", 6) == 0)
862  continue;
863  if(strlen(names[i]) + value_lengths[i] >= SfileadrL) {
864  sprintf(xorriso->result_line, "# oversized: name %d , value %d bytes\n",
865  (int) strlen(names[i]), (int) value_lengths[i]);
866  } else {
867  ret= Sfile_bsl_encoder(&bsl, names[i], strlen(names[i]), 8);
868  if(ret <= 0)
869  {ret= -1; goto ex;}
870  strcpy(xorriso->result_line, bsl);
871  free(bsl);
872  ret= Sfile_bsl_encoder(&bsl, values[i], value_lengths[i], 8);
873  if(ret <= 0)
874  {ret= -1; goto ex;}
875  sprintf(xorriso->result_line + strlen(xorriso->result_line),
876  "=\"%s\"\n", bsl);
877  free(bsl);
878  }
879  /* temporarily disable -backslash_codes with result output */
880  result_len+= strlen(xorriso->result_line);
881  if(pass) {
882  strcat(*attr_text, xorriso->result_line);
883  } else if(!(flag & 1)) {
884  bsl_mem= xorriso->bsl_interpretation;
885  xorriso->bsl_interpretation= 0;
886  Xorriso_result(xorriso, 0);
887  xorriso->bsl_interpretation= bsl_mem;
888  }
889  }
890  }
891  if((flag & 16) && attr_text != NULL)
892  if(*attr_text != NULL)
893  if((*attr_text)[0] == 0) {
894  free(*attr_text);
895  *attr_text= NULL;
896  ret= 2;
897  goto ex;
898  }
899  if(!(flag & 1)) {
900  strcpy(xorriso->result_line, "\n");
901  Xorriso_result(xorriso, 0);
902  }
903  ret= 1;
904 ex:;
905  Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names,
906  &value_lengths, &values, 1 << 15);
907  return(ret);
908 }
909 
910 
911 /*
912  @param flag bit0= with mode "e" : Use echo -e encoding but
913  do not put out commands and quotation marks.
914  Rather apply double backslash.
915 */
917  char *comp, size_t comp_len,
918  char *mode, int flag)
919 {
920  int ret;
921  size_t line_limit;
922  char *line, *wpt, *bsl = NULL;
923  unsigned char *upt, *uval;
924 
925  line= xorriso->result_line;
926  line_limit= sizeof(xorriso->result_line);
927  uval= (unsigned char *) comp;
928 
929  if(*mode == 'q') {
930  Text_shellsafe(comp, line, 1);
931  } else if(*mode == 'e' || mode[0] == 0) {
932  for(upt= uval; (size_t) (upt - uval) < comp_len; upt++)
933  if(*upt <= 037 || *upt >= 0177)
934  break;
935  if((size_t) (upt - uval) < comp_len || (flag & 1)) {
936  /* Use "$(echo -e '\0xyz')" */;
937  if(!(flag & 1))
938  strcat(line, "\"$(echo -e '");
939  wpt= line + strlen(line);
940  for(upt= uval; (size_t) (upt - uval) < comp_len; upt++) {
941  if(wpt - line + 5 + 3 + 1 > (ssize_t) line_limit)
942  /* "\\0xyz" + "')\"" + 0 */
943  goto too_much;
944  if(*upt <= 037 || *upt >= 0177 || *upt == '\\' || *upt == '\'') {
945  if(flag & 1)
946  *(wpt++)= '\\';
947  sprintf((char *) wpt, "\\0%-3.3o", *upt);
948  wpt+= strlen(wpt);
949  } else {
950  *(wpt++)= *upt;
951  }
952  }
953  *wpt= 0;
954  if(!(flag & 1))
955  strcpy(wpt, "')\"");
956  } else {
957  Text_shellsafe(comp, line, 1);
958  }
959  } else if(*mode == 'b') {
960  ret= Sfile_bsl_encoder(&bsl, comp, comp_len, 8);
961  if(ret <= 0)
962  {ret= -1; goto ex;}
963  if(strlen(line) + strlen(bsl) + 1 > line_limit)
964  goto too_much;
965  strcat(line, bsl);
966  free(bsl);
967  bsl= NULL;
968  } else if(*mode == 'r') {
969  if(strlen(line) + strlen(comp) + 1 > line_limit)
970  goto too_much;
971  strcat(line, comp);
972  }
973  ret= 1;
974 ex:;
975  if(bsl != NULL)
976  free(bsl);
977  return(ret);
978 too_much:;
979  Xorriso_msgs_submit(xorriso, 0, "Oversized BSD-style file attribute",
980  0, "FAILURE", 0);
981  ret= -1;
982  goto ex;
983 }
984 
985 
986 /*
987  @param flag bit1= path is disk_path
988  bit3= do not ignore eventual non-user attributes.
989  bit5= in case of symbolic link on disk: inquire link target
990 */
991 int Xorriso_list_extattr(struct XorrisO *xorriso, void *in_node, char *path,
992  char *show_path, char *mode, int flag)
993 {
994  int ret= 1, i, bsl_mem;
995  size_t num_attrs= 0, *value_lengths= NULL;
996  char **names= NULL, **values= NULL, *cpt, *space_pt, *name_pt, *path_pt;
997  char *line;
998  unsigned char *upt, *uval;
999 
1000  line= xorriso->result_line;
1001  ret= Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names,
1002  &value_lengths, &values, flag & (2 | 8 | 32));
1003  if(ret <= 0)
1004  goto ex;
1005  if(flag & 64) {
1006  ret= (num_attrs > 0);
1007  goto ex;
1008  }
1009  if(num_attrs == 0)
1010  {ret= 2; goto ex;}
1011 
1012  strcpy(line, "n=");
1013  path_pt= show_path + (show_path[0] == '/');
1014  if(path_pt[0] == 0)
1015  path_pt= ".";
1016  ret= Xorriso_append_extattr_comp(xorriso, path_pt, strlen(path_pt), mode, 0);
1017  if(ret <= 0)
1018  goto ex;
1019  strcat(line, "\n");
1020  Xorriso_result(xorriso, 0);
1021  for(i= 0; i < (int) num_attrs; i++) {
1022  line[0]= 0;
1023  uval= (unsigned char *) values[i];
1024 
1025  if(strlen(names[i]) + value_lengths[i] >= SfileadrL) {
1026  sprintf(line,
1027  "echo 'OMITTED: Oversized: name %d bytes, value %d bytes in file '\"$n\" >&2\n",
1028  (int) strlen(names[i]), (int) value_lengths[i]);
1029  Xorriso_result(xorriso, 0);
1030  continue;
1031  }
1032 
1033  /* Form: $c space name value $n */
1034 
1035  /* Split namespace from name */
1036  cpt= strchr(names[i], '.');
1037  if(cpt == NULL) {
1038  space_pt= "user";
1039  name_pt= names[i];
1040  } else {
1041  *cpt= 0;
1042  space_pt= names[i];
1043  name_pt= cpt + 1;
1044  }
1045 
1046  /* FreeBSD setextattr cannot set 0-bytes */
1047  for(upt= uval; (size_t) (upt - uval) < value_lengths[i]; upt++)
1048  if(*upt == 0
1049  )
1050  break;
1051  if((size_t) (upt - uval) < value_lengths[i]) {
1052  strcpy(line, "echo 'OMITTED: Value contains 0-bytes : space \"'\"");
1053  ret= Xorriso_append_extattr_comp(xorriso, space_pt, strlen(space_pt),
1054  "e", 1);
1055  if(ret <= 0)
1056  goto ex;
1057  strcat(line, "\"'\" , name \"'\"");
1058  ret= Xorriso_append_extattr_comp(xorriso, name_pt, strlen(name_pt),
1059  "e", 1);
1060  if(ret <= 0)
1061  goto ex;
1062  strcat(line, "\"'\" in file '\"");
1063  ret= Xorriso_append_extattr_comp(xorriso, path_pt, strlen(path_pt),
1064  "e", 1);
1065  if(ret <= 0)
1066  goto ex;
1067  strcat(line, "\" >&2\n");
1068 
1069  /* temporarily disable -backslash_codes with result output */
1070  bsl_mem= xorriso->bsl_interpretation;
1071  xorriso->bsl_interpretation= 0;
1072  Xorriso_result(xorriso, 0);
1073  xorriso->bsl_interpretation= bsl_mem;
1074  strcpy(line, "# ");
1075  }
1076 
1077  strcat(line, "$c ");
1078  ret= Xorriso_append_extattr_comp(xorriso, space_pt, strlen(space_pt),
1079  mode, 0);
1080  if(ret <= 0)
1081  goto ex;
1082  strcat(line, " ");
1083  ret= Xorriso_append_extattr_comp(xorriso,name_pt, strlen(name_pt), mode, 0);
1084  if(ret <= 0)
1085  goto ex;
1086  strcat(line, " ");
1087  ret= Xorriso_append_extattr_comp(xorriso, values[i], value_lengths[i],
1088  mode, 0);
1089  if(ret <= 0)
1090  goto ex;
1091  strcat(line, " \"$n\"\n");
1092 
1093  /* temporarily disable -backslash_codes with result output */
1094  bsl_mem= xorriso->bsl_interpretation;
1095  xorriso->bsl_interpretation= 0;
1096  Xorriso_result(xorriso, 0);
1097  xorriso->bsl_interpretation= bsl_mem;
1098  }
1099  strcpy(line, "\n");
1100  Xorriso_result(xorriso, 0);
1101  ret= 1;
1102 ex:;
1103  Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names,
1104  &value_lengths, &values, 1 << 15);
1105  return(ret);
1106 }
1107 
1108 
1109 /*
1110  @param flag
1111  Bitfield for control purposes
1112  bit0= get default ACL rather than access ACL
1113  bit4= set *text = NULL and return 2
1114  if the ACL matches st_mode permissions.
1115  bit5= in case of symbolic link: inquire link target
1116  bit15= free text and return 1
1117  @return
1118  1 ok
1119  2 ok, trivial ACL found while bit4 is set, *text is NULL
1120  0 no ACL manipulation adapter available / ACL not supported by fs
1121  -1 failure of system ACL service (see errno)
1122  -2 attempt to inquire ACL of a symbolic link without bit4 or bit5
1123  resp. with no suitable link target
1124 */
1125 int Xorriso_local_getfacl(struct XorrisO *xorriso, char *disk_path,
1126  char **text, int flag)
1127 {
1128  int ret, skip= 0, colons= 0, countdown= 0;
1129  char *acl= NULL, *cpt, *wpt;
1130 
1131  if(flag & (1 << 15)) {
1132  if(*text != NULL)
1133  free(*text);
1134  *text= NULL;
1135  return(1);
1136  }
1137  *text= NULL;
1138  ret= iso_local_get_acl_text(disk_path, &acl, flag & (1 | 16 | 32));
1139  Xorriso_process_msg_queues(xorriso,0);
1140  if(ret < 0 || ret == 2)
1141  return(ret);
1142  if(acl == NULL)
1143  return(0);
1144  *text= strdup(acl);
1145  iso_local_get_acl_text(disk_path, &acl, 1 << 15);
1146  if(*text == NULL) {
1147  Xorriso_no_malloc_memory(xorriso, NULL, 0);
1148  return(-1);
1149  }
1150 
1151  /* Garbage collection about trailing remarks after 3 permission chars */
1152  wpt= *text;
1153  for(cpt= *text; *cpt; cpt++) {
1154  if(skip) {
1155  if(*cpt == '\n')
1156  skip= 0;
1157  else
1158  continue;
1159  }
1160  if(*cpt == ':' && !countdown) {
1161  colons++;
1162  if(colons == 2) {
1163  countdown= 4;
1164  colons= 0;
1165  }
1166  }
1167  if(countdown > 0) {
1168  countdown--;
1169  if(countdown == 0)
1170  skip= 1;
1171  }
1172  *wpt= *cpt;
1173  wpt++;
1174  }
1175  *wpt= 0;
1176 
1177  return(1);
1178 }
1179 
1180 
1181 /*
1182  @param flag
1183  bit1= path is disk_path
1184  bit3= do not ignore eventual non-user attributes.
1185  bit5= in case of symbolic link on disk: inquire link target
1186  bit15= free memory
1187 */
1188 int Xorriso_get_attrs(struct XorrisO *xorriso, void *in_node, char *path,
1189  size_t *num_attrs, char ***names,
1190  size_t **value_lengths, char ***values, int flag)
1191 {
1192  int ret, i, widx;
1193  IsoNode *node;
1194 
1195  if(flag & (1 << 15)) {
1196  if(flag & 2) {
1197  iso_local_get_attrs(NULL, num_attrs, names, value_lengths, values,
1198  1 << 15);
1199  } else {
1200  iso_node_get_attrs(NULL, num_attrs, names, value_lengths, values,
1201  1 << 15);
1202  }
1203  return(1);
1204  }
1205 
1206  *num_attrs= 0;
1207  if(flag & 2) {
1208  ret= iso_local_get_attrs(path, num_attrs, names, value_lengths, values,
1209  flag & (8 | 32));
1210  if(ret < 0) {
1211  strcpy(xorriso->info_text, "Error with reading xattr of disk file ");
1212  Text_shellsafe(path, xorriso->info_text, 1);
1213  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
1214  }
1215  } else {
1216  node= (IsoNode *) in_node;
1217  if(node == NULL) {
1218  ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
1219  if(ret<=0)
1220  goto ex;
1221  }
1222  ret= iso_node_get_attrs(node, num_attrs, names, value_lengths, values,
1223  0);
1224  if(ret < 0) {
1225  Xorriso_report_iso_error(xorriso, "", ret,
1226  "Error when obtaining xattr of ISO node", 0, "FAILURE", 1);
1227  goto ex;
1228  }
1229 
1230  if(!(flag & 8)) {
1231  /* Filter away any non-userspace xattr */;
1232  widx= 0;
1233  for(i= 0; i < (int) *num_attrs; i++) {
1234  if(strncmp((*names)[i], "user.", 5) != 0) {
1235  free((*names)[i]);
1236  (*names)[i]= NULL;
1237  if((*values)[i] != NULL) {
1238  free((*values)[i]);
1239  (*values)[i]= NULL;
1240  }
1241  } else {
1242  if(widx != i) {
1243  (*names)[widx]= (*names)[i];
1244  (*value_lengths)[widx]= (*value_lengths)[i];
1245  (*values)[widx]= (*values)[i];
1246  (*names)[i]= NULL;
1247  (*value_lengths)[i]= 0;
1248  (*values)[i]= NULL;
1249  }
1250  widx++;
1251  }
1252  }
1253  *num_attrs= widx;
1254  }
1255  }
1256  ret= 1;
1257 ex:;
1258  Xorriso_process_msg_queues(xorriso,0);
1259  return(ret);
1260 }
1261 
1262 
1263 int Xorriso_get_attr_value(struct XorrisO *xorriso, void *in_node, char *path,
1264  char *name, size_t *value_length, char **value, int flag)
1265 {
1266  int ret;
1267  size_t num_attrs= 0, *value_lengths= NULL, i;
1268  char **names = NULL, **values= NULL;
1269 
1270  *value= NULL;
1271  *value_length= 0;
1272  ret= Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names,
1273  &value_lengths, &values, 8);
1274  if(ret <= 0)
1275  goto ex;
1276 
1277  for(i= 0; i < num_attrs; i++) {
1278  if(strcmp(name, names[i]) != 0)
1279  continue;
1280  *value= calloc(value_lengths[i] + 1, 1);
1281  if(*value == NULL)
1282  {ret= -1; goto ex;}
1283  memcpy(*value, values[i], value_lengths[i]);
1284  (*value)[value_lengths[i]]= 0;
1285  *value_length= value_lengths[i];
1286  ret= 1; goto ex;
1287  }
1288  ret= 0;
1289 ex:
1290  Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names,
1291  &value_lengths, &values, 1 << 15);
1292  return(ret);
1293 }
1294 
1295 
1296 int Xorriso_stream_type(struct XorrisO *xorriso, IsoNode *node,
1297  IsoStream *stream, char type_text[], int flag)
1298 {
1299  int ret, lba, stream_type, block_size_log2;
1300  uint8_t zisofs_algo[2], algo_num;
1301  char text[5];
1302 
1303  strncpy(text, stream->class->type, 4);
1304  text[4]= 0;
1305  if(strcmp(text, "fsrc") == 0) {
1306  ret= Xorriso__file_start_lba(node, &lba, 0);
1307  if(ret > 0 && lba > 0)
1308  strcpy(type_text, "image");
1309  else
1310  strcpy(type_text, "disk");
1311  } else if(strcmp(text, "ziso") == 0 || strcmp(text, "osiz") == 0) {
1312  if(strcmp(text, "ziso") == 0)
1313  strcpy(type_text, "--zisofs");
1314  else
1315  strcpy(type_text, "--zisofs-decode");
1316  ret= iso_stream_get_zisofs_par(stream, &stream_type, zisofs_algo, &algo_num,
1317  &block_size_log2, 0);
1318  if(ret == 1)
1319  sprintf(type_text + strlen(type_text), ":%c%c:%dk",
1320  zisofs_algo[0], zisofs_algo[1], 1 << (block_size_log2 - 10));
1321  } else if(strcmp(text, "gzip") == 0) {
1322  strcpy(type_text, "--gzip");
1323  } else if(strcmp(text, "pizg") == 0) {
1324  strcpy(type_text, "--gunzip");
1325  } else if(strcmp(text, "cout") == 0 || strcmp(text, "boot") == 0 ||
1326  strcmp(text, "user") == 0 || strcmp(text, "extf") == 0) {
1327  strcpy(type_text, text);
1328  } else {
1329  Text_shellsafe(text, type_text, 0);
1330  }
1331  return(1);
1332 }
1333 
1334 
1335 /*
1336  @param flag bit0= do not report to result but only retrieve md5 text
1337  @return 1= ok, 0= no md5 available, <0= other error
1338 */
1339 int Xorriso_get_md5(struct XorrisO *xorriso, void *in_node, char *path,
1340  char md5[16], int flag)
1341 {
1342  int ret= 1, i;
1343  char *wpt;
1344  IsoImage *image;
1345  IsoNode *node;
1346 
1347  ret= Xorriso_get_volume(xorriso, &image, 0);
1348  if(ret <= 0)
1349  goto ex;
1350  node= (IsoNode *) in_node;
1351  if(node == NULL) {
1352  ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
1353  if(ret<=0)
1354  goto ex;
1355  }
1356  if(!LIBISO_ISREG(node))
1357  return(0);
1358  ret= iso_file_get_md5(image, (IsoFile *) node, md5, 0);
1359  Xorriso_process_msg_queues(xorriso,0);
1360  if(ret <= 0)
1361  goto ex;
1362  if(flag & 1)
1363  {ret= 1; goto ex;}
1364 
1365  wpt= xorriso->result_line;
1366  for(i= 0; i < 16; i++) {
1367  sprintf(wpt, "%2.2x", ((unsigned char *) md5)[i]);
1368  wpt+= 2;
1369  }
1370  strcpy(wpt, " ");
1371  wpt+= 2;
1372  Xorriso_getfname(xorriso, path, 1 | 2);
1373  ret= 1;
1374 ex:;
1375  return(ret);
1376 }
1377 
1378 
1379 int Xorriso_make_md5(struct XorrisO *xorriso, void *in_node, char *path,
1380  int flag)
1381 {
1382  int ret;
1383  off_t size;
1384  IsoNode *node;
1385 
1386  node= (IsoNode *) in_node;
1387  if(node == NULL) {
1388  ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
1389  if(ret <= 0)
1390  return(ret);
1391  }
1392  if(!LIBISO_ISREG(node))
1393  return(0);
1394  ret= iso_file_make_md5((IsoFile *) node, 0);
1395  size= iso_file_get_size((IsoFile *) node);
1396  xorriso->pacifier_count+= size;
1397  xorriso->pacifier_byte_count+= size;
1398  Xorriso_pacifier_callback(xorriso, "content bytes read",
1399  xorriso->pacifier_count, 0, "", 8);
1400  Xorriso_process_msg_queues(xorriso, 0);
1401  if(ret < 0) {
1402  Xorriso_report_iso_error(xorriso, "", ret,
1403  "Error when computing MD5", 0, "FAILURE", 1);
1404  return(0);
1405  }
1406  Xorriso_set_change_pending(xorriso, 1);
1407  return(1);
1408 }
1409 
1410 
1411 /* @param flag bit0= do not only sum up sizes but also print subdirs
1412 
1413  bit2= do not report result by Xorriso_result()
1414 */
1415 int Xorriso_show_du_subs(struct XorrisO *xorriso, IsoDir *dir_node,
1416  char *abs_path, char *rel_path, off_t *size,
1417  off_t boss_mem, int flag)
1418 {
1419  int i, ret, no_sort= 0, filec= 0, l;
1420  IsoDirIter *iter= NULL;
1421  IsoNode *node, **node_array= NULL;
1422  char *name;
1423  off_t sub_size, report_size, mem= 0;
1424  char *path= NULL, *show_path= NULL, *sfe= NULL;
1425 
1426  Xorriso_alloc_meM(sfe, char, 5 * SfileadrL);
1427  Xorriso_alloc_meM(path, char, SfileadrL);
1428  Xorriso_alloc_meM(show_path, char, SfileadrL);
1429 
1430  *size= 0;
1431  ret= iso_dir_get_children(dir_node, &iter);
1432  if(ret<0) {
1433 cannot_create_iter:;
1434  Xorriso_cannot_create_iter(xorriso, ret, 0);
1435  {ret= -1; goto ex;}
1436  }
1437  for(i= 0; iso_dir_iter_next(iter, &node) == 1; ) {
1438  sub_size= 0;
1439  name= (char *) iso_node_get_name(node);
1440  strcpy(show_path, rel_path);
1441  if(Sfile_add_to_path(show_path, name, 0)<=0)
1442  goto much_too_long;
1443  if(LIBISO_ISDIR(node)) {
1444  strcpy(path, abs_path);
1445  if(Sfile_add_to_path(path, name, 0)<=0) {
1446 much_too_long:;
1447  Xorriso_much_too_long(xorriso, strlen(path)+strlen(name)+1, 2);
1448  {ret= -1; goto ex;}
1449  }
1450  filec++;
1451  l= strlen(rel_path)+1;
1452  mem+= l;
1453  if(l % sizeof(char *))
1454  mem+= sizeof(char *)-(l % sizeof(char *));
1455  if(flag&1) /* diving and counting is done further below */
1456  continue;
1457  ret= Xorriso_show_du_subs(xorriso, (IsoDir *) node,
1458  path, show_path, &sub_size, boss_mem, 0);
1459  if(ret<0)
1460  goto ex;
1461  if(ret==0)
1462  continue;
1463  }
1464 
1465  if(LIBISO_ISREG(node)) {
1466  sub_size+= iso_file_get_size((IsoFile *) node)+2048;
1467 /*
1468  sub_size+= iso_file_get_size((IsoFile *) node)+strlen(name)+1;
1469 */
1470  }
1471 
1472  if(sub_size>0)
1473  (*size)+= sub_size;
1474  Xorriso_process_msg_queues(xorriso,0);
1475  }
1476 
1477  if(filec<=0 || !(flag&1))
1478  {ret= 1; goto ex;}
1479 
1480  /* Reset iteration */
1481  iso_dir_iter_free(iter);
1482  iter= NULL;
1483  Xorriso_process_msg_queues(xorriso,0);
1484 
1485  ret= Xorriso_sorted_node_array(xorriso, dir_node, &filec, &node_array,
1486  boss_mem, 1|2|4);
1487  if(ret<0)
1488  goto ex;
1489  if(ret==0) {
1490  no_sort= 1;
1491  ret= iso_dir_get_children(dir_node, &iter);
1492  if(ret<0)
1493  goto cannot_create_iter;
1494  }
1495 
1496  for(i= 0; (no_sort || i<filec) && !(xorriso->request_to_abort); i++) {
1497  if(no_sort) {
1498  ret= iso_dir_iter_next(iter, &node);
1499  if(ret!=1)
1500  break;
1501  if(!LIBISO_ISDIR(node))
1502  continue;
1503  } else
1504  node= node_array[i];
1505 
1506  sub_size= 0;
1507  name= (char *) iso_node_get_name(node);
1508  strcpy(show_path, rel_path);
1509  if(Sfile_add_to_path(show_path, name, 0)<=0)
1510  goto much_too_long;
1511  strcpy(path, abs_path);
1512  if(Sfile_add_to_path(path, name, 0)<=0)
1513  goto much_too_long;
1514  ret= Xorriso_show_du_subs(xorriso, (IsoDir *) node,
1515  path, show_path, &sub_size, boss_mem+mem, flag&1);
1516  if(ret<0)
1517  goto ex;
1518 
1519  if(LIBISO_ISREG(node)) {
1520  sub_size+= iso_file_get_size((IsoFile *) node)+2048;
1521 /*
1522  sub_size+= iso_tree_node_get_size((IsoFile *) node)+strlen(name)+1;
1523 */
1524  }
1525  if(sub_size>0)
1526  (*size)+= sub_size;
1527  report_size= sub_size/1024;
1528  if(report_size*1024<sub_size)
1529  report_size++;
1530  if(!(flag & 4)) {
1531  if(xorriso->sh_style_result)
1532  sprintf(xorriso->result_line, "%-7.f ",(double) (report_size));
1533  else
1534  sprintf(xorriso->result_line, "%7.f ",(double) (report_size));
1535  sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n",
1536  Xorriso_esc_filepath(xorriso, show_path, sfe, 0));
1537  Xorriso_result(xorriso, 0);
1538  }
1539  }
1540  ret= 1;
1541 ex:;
1542  Xorriso_free_meM(sfe);
1543  Xorriso_free_meM(path);
1544  Xorriso_free_meM(show_path);
1545  if(iter!=NULL)
1546  iso_dir_iter_free(iter);
1547  if(node_array!=NULL)
1548  free((char *) node_array);
1549  Xorriso_process_msg_queues(xorriso,0);
1550  return(ret);
1551 }
1552 
1553 
1554 int Xorriso_sorted_dir_i(struct XorrisO *xorriso, IsoDir *dir_node,
1555  int *filec, char ***filev, off_t boss_mem, int flag)
1556 {
1557  int i,j,ret;
1558  IsoDirIter *iter= NULL;
1559  IsoNode *node;
1560  char *name;
1561  off_t mem;
1562 
1563  (*filec)= 0;
1564  (*filev)= NULL;
1565 
1566  ret= iso_dir_get_children(dir_node, &iter);
1567  if(ret<0) {
1568 cannot_iter:;
1569  Xorriso_cannot_create_iter(xorriso, ret, 0);
1570  {ret= -1; goto ex;}
1571  }
1572  mem= 0;
1573  for(i= 0; iso_dir_iter_next(iter, &node) == 1; ) {
1574  name= (char *) iso_node_get_name(node);
1575  mem+= sizeof(char *)+strlen(name)+8;
1576  (*filec)++;
1577  }
1578  iso_dir_iter_free(iter);
1579  iter= NULL;
1580  if(*filec==0)
1581  {ret= 1; goto ex;}
1582 
1583  ret= Xorriso_check_temp_mem_limit(xorriso, mem+boss_mem, 2);
1584  if(ret<=0)
1585  goto ex;
1586  (*filev)= (char **) calloc(*filec, sizeof(char *));
1587  if(*filev==NULL)
1588  {ret= -1; goto ex; }
1589  ret= iso_dir_get_children(dir_node, &iter);
1590  if(ret<0)
1591  goto cannot_iter;
1592  for(i= 0; i<*filec; i++) {
1593  ret= iso_dir_iter_next(iter, &node);
1594  if(ret!=1)
1595  break;
1596  name= (char *) iso_node_get_name(node);
1597  (*filev)[i]= strdup(name);
1598  if((*filev)[i]==NULL) {
1599  for(j= 0; j<i; j++)
1600  if((*filev)[j]!=NULL)
1601  free((*filev)[j]);
1602  free((char *) (*filev));
1603  ret= -1; goto ex;
1604  }
1605  }
1606  Sort_argv(*filec, *filev, 0);
1607  ret= 1;
1608 ex:;
1609  if(iter!=NULL)
1610  iso_dir_iter_free(iter);
1611  return(ret);
1612 }
1613 
1614 
1615 int Xorriso_node_eff_hidden(struct XorrisO *xorriso, IsoNode *node, int flag)
1616 {
1617  int hidden_state= 0, ret;
1618  IsoNode *current, *parent;
1619 
1620  current= node;
1621  for(current= node; hidden_state != 7;) {
1622  ret= iso_node_get_hidden(current);
1623  if(ret & LIBISO_HIDE_ON_RR)
1624  hidden_state|= 1;
1625  if(ret & LIBISO_HIDE_ON_JOLIET)
1626  hidden_state|= 2;
1627  if(ret & LIBISO_HIDE_ON_HFSPLUS)
1628  hidden_state|= 4;
1629  parent= (IsoNode *) iso_node_get_parent(current);
1630  if(parent == current)
1631  break;
1632  current= parent;
1633  }
1634  return(hidden_state);
1635 }
1636 
1637 
1638 /* @param flag bit0= do not truncate components which contain any of "*?["
1639 */
1640 int Xorriso_truncate_path_comps(struct XorrisO *xorriso, char *path,
1641  char *buffer, char **resultpt, int flag)
1642 {
1643  char *rpt, *basrpt, *wpt, *baswpt, *cpt;
1644  int ended, ret, skip;
1645 
1646  *resultpt= path;
1647 
1648  /* Check component lengths */
1649  rpt= path;
1650  if(*rpt == '/')
1651  rpt++;
1652  for(ended= 0; !ended;) {
1653  basrpt= rpt;
1654  rpt= strchr(basrpt, '/');
1655  if(rpt == NULL) {
1656  rpt= basrpt + strlen(basrpt);
1657  ended= 1;
1658  }
1659  skip= 0;
1660  if(flag & 1) {
1661  for(cpt= basrpt; cpt < rpt; cpt++) {
1662  if(strchr("*?[", *cpt) != NULL) {
1663  skip= 1;
1664  break;
1665  }
1666  }
1667  }
1668  if((!skip) && rpt - basrpt > xorriso->file_name_limit) {
1669  ended= 0;
1670  break;
1671  }
1672  if(*rpt == '/')
1673  rpt++;
1674  }
1675  if(ended)
1676  return(1); /* All short enough */
1677 
1678  /* Some truncation is needed */
1679  buffer[0]= 0;
1680  wpt= buffer;
1681  if(path[0] == '/')
1682  *(wpt++)= '/';
1683  rpt= path;
1684  if(*rpt == '/')
1685  rpt++;
1686  for(ended= 0; !ended;) {
1687  basrpt= rpt;
1688  baswpt= wpt;
1689  rpt= strchr(basrpt, '/');
1690  if(rpt == NULL) {
1691  rpt= basrpt + strlen(basrpt);
1692  ended= 1;
1693  }
1694  skip= 0;
1695  for(cpt= basrpt; cpt < rpt; cpt++) {
1696  *(wpt++)= *cpt;
1697  if((flag & 1) && strchr("*?[", *cpt) != NULL)
1698  skip= 1;
1699  }
1700  *wpt= 0;
1701  if((!skip) && rpt - basrpt > xorriso->file_name_limit) {
1702  ret= iso_truncate_leaf_name(1, xorriso->file_name_limit, baswpt, 0);
1703  Xorriso_process_msg_queues(xorriso, 0);
1704  if(ret < 0)
1705  return(0);
1706  wpt= baswpt + strlen(baswpt);
1707  }
1708  if(!ended) {
1709  *(wpt++)= '/';
1710  rpt++;
1711  }
1712  }
1713  *resultpt= buffer;
1714  return(1);
1715 }
1716 
1717 
1718 /* @param flag bit0= long format
1719  bit1= do not print count of nodes
1720  bit2= du format
1721  bit3= print directories as themselves (ls -d)
1722  bit5= do not look for truncated versions of path component
1723 */
1724 int Xorriso_ls_filev(struct XorrisO *xorriso, char *wd,
1725  int filec, char **filev, off_t boss_mem, int flag)
1726 {
1727  int i, ret, was_error= 0, dfilec= 0, pass, passes, hidden_state= 0;
1728  IsoNode *node;
1729  IsoImage *volume;
1730  char *path= NULL, *link_target= NULL, *rpt, **dfilev= NULL;
1731  char *a_text= NULL, *d_text= NULL, *namept;
1732  off_t size;
1733  struct stat stbuf;
1734 
1735  Xorriso_alloc_meM(path, char, SfileadrL);
1736  Xorriso_alloc_meM(link_target, char, SfileadrL);
1737 
1738  rpt= xorriso->result_line;
1739 
1740  ret= Xorriso_get_volume(xorriso, &volume, 0);
1741  if(ret<=0)
1742  goto ex;
1743 
1744  Sort_argv(filec, filev, 0);
1745 
1746  /* Count valid nodes, warn of invalid ones */
1747  for(i= 0; i<filec; i++) {
1748  ret= Xorriso_make_abs_adr(xorriso, wd, filev[i], path, 1|2|4);
1749  if(ret<=0) {
1750  was_error++;
1751  continue;
1752  }
1753  ret= Xorriso_node_from_path(xorriso, volume, path, &node,
1754  1 | ((flag >> 4) & 2));
1755  if(ret<=0) {
1756  sprintf(xorriso->info_text, "Not found in ISO image: ");
1757  Text_shellsafe(path, xorriso->info_text, 1);
1758  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
1759  was_error++;
1760  continue;
1761  }
1762  }
1763 
1764  if((flag&8) && !(flag&(2|4))) {
1765  sprintf(xorriso->info_text, "Valid ISO nodes found: %d\n", filec-was_error);
1766  Xorriso_info(xorriso,1);
1767  if(filec-was_error<=0)
1768  {ret= !was_error; goto ex;}
1769  }
1770 
1771  passes= 1+!(flag&(4|8));
1772  for(pass= 0; pass<passes; pass++)
1773  for(i= 0; i<filec && !(xorriso->request_to_abort); i++) {
1774  rpt[0]= 0;
1775  ret= Xorriso_make_abs_adr(xorriso, wd, filev[i], path, 1|2|4);
1776  if(ret<=0)
1777  continue;
1778  ret= Xorriso_fake_stbuf(xorriso, path, &stbuf, &node, ((flag&4) >> 1) | 16);
1779  if(ret<=0)
1780  continue;
1781  if(LIBISO_ISDIR(node) && !(flag&(4|8))) {
1782  if(pass==0)
1783  continue;
1784  if(filec>1) {
1785  strcpy(xorriso->result_line, "\n");
1786  Xorriso_result(xorriso,0);
1787  Xorriso_esc_filepath(xorriso, filev[i], xorriso->result_line, 0);
1788  strcat(xorriso->result_line, ":\n");
1789  Xorriso_result(xorriso,0);
1790  }
1791  ret= Xorriso_sorted_dir_i(xorriso,
1792  (IsoDir *) node, &dfilec, &dfilev, boss_mem, 0);
1793  if(ret<=0) {
1794 
1795  /* >>> libisofs iterator loop and single item Xorriso_lsx_filev() */;
1796 
1797  } else {
1798  if(flag&1) {
1799  sprintf(xorriso->result_line, "total %d\n", dfilec);
1800  Xorriso_result(xorriso,0);
1801  }
1802  Xorriso_ls_filev(xorriso, path,
1803  dfilec, dfilev, boss_mem, (flag & 1) | 2 | 8);
1804  }
1805  if(dfilec>0)
1806  Sfile_destroy_argv(&dfilec, &dfilev, 0);
1807  continue;
1808  } else
1809  if(pass>0)
1810  continue;
1811  link_target[0]= 0;
1812  if((flag&5)==1) { /* -ls_l */
1813  iso_node_get_acl_text(node, &a_text, &d_text, 16);
1814  hidden_state= Xorriso_node_eff_hidden(xorriso, node, 0);
1815  ret= Xorriso_format_ls_l(xorriso, &stbuf,
1816  1 | ((a_text != NULL || d_text != NULL) << 1) |
1817  (hidden_state << 2));
1818  iso_node_get_acl_text(node, &a_text, &d_text, 1 << 15);
1819  if(ret<=0)
1820  continue;
1821  if(LIBISO_ISLNK(node)) {
1822  if(Sfile_str(link_target, (char *) iso_symlink_get_dest(
1823  (IsoSymlink *) node), 0)<=0)
1824  link_target[0]= 0;
1825  }
1826  } else if(flag&4) { /* -du or -dus */
1827  size= stbuf.st_size;
1828  if(S_ISDIR(stbuf.st_mode)) {
1829  ret= Xorriso_show_du_subs(xorriso, (IsoDir *) node,
1830  path, filev[i], &size, boss_mem, flag&1);
1831  if(ret<0)
1832  {ret= -1; goto ex;}
1833  if(ret==0)
1834  continue;
1835  }
1836  if(xorriso->sh_style_result)
1837  sprintf(rpt, "%-7.f ",(double) (size/1024));
1838  else
1839  sprintf(rpt, "%7.f ",(double) (size/1024));
1840  }
1841  Xorriso_truncate_path_comps(xorriso, filev[i], path, &namept, 0);
1842  if(link_target[0] && (flag&5)==1) {
1843  Xorriso_esc_filepath(xorriso, namept, xorriso->result_line, 1);
1844  strcat(xorriso->result_line, " -> ");
1845  Xorriso_esc_filepath(xorriso, link_target, xorriso->result_line, 1 | 2);
1846  } else {
1847  Xorriso_esc_filepath(xorriso, namept, xorriso->result_line, 1);
1848  }
1849  strcat(xorriso->result_line, "\n");
1850  Xorriso_result(xorriso, 0);
1851  }
1852  ret= !was_error;
1853 ex:;
1854  Xorriso_free_meM(path);
1855  Xorriso_free_meM(link_target);
1856  return(ret);
1857 }
1858 
1859 
1860 /*
1861  @return: <=0 = error, 1= directory tree, 2= path leads to non-directory
1862 */
1863 int Xorriso_get_dus(struct XorrisO *xorriso, char *iso_rr_path, off_t *size,
1864  off_t boss_mem, int flag)
1865 {
1866  int ret;
1867  IsoNode *node;
1868  char *path= NULL;
1869  struct stat stbuf;
1870 
1871  Xorriso_alloc_meM(path, char, SfileadrL);
1872 
1873  ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, iso_rr_path, path,
1874  1 | 2 | 4);
1875  if(ret <= 0)
1876  goto ex;
1877  ret= Xorriso_fake_stbuf(xorriso, path, &stbuf, &node, 0);
1878  if(ret <= 0)
1879  goto ex;
1880  if(!S_ISDIR(stbuf.st_mode)) {
1881  *size= stbuf.st_size;
1882  ret= 2; goto ex;
1883  }
1884  ret= Xorriso_show_du_subs(xorriso, (IsoDir *) node, path, iso_rr_path, size,
1885  boss_mem, 4);
1886  if(ret <= 0)
1887  goto ex;
1888  ret= 1;
1889 ex:
1890  Xorriso_free_meM(path);
1891  return(ret);
1892 }
1893 
1894 
1895 /* This function needs less buffer memory than Xorriso_ls_filev() but cannot
1896  perform structured pattern matching as done by Xorriso_expand_pattern()
1897  for subsequent Xorriso_ls_filev().
1898  @param flag bit0= long format
1899  bit1= only check for directory existence
1900  bit2= do not apply search pattern but accept any file
1901  bit3= just count nodes and return number
1902 */
1903 int Xorriso_ls(struct XorrisO *xorriso, int flag)
1904 {
1905  int ret, i, filec= 0, failed_at, no_sort= 0;
1906  IsoNode *node, **node_array= NULL;
1907  IsoDir *dir_node;
1908  IsoDirIter *iter= NULL;
1909  char *link_target= NULL, *npt, *rpt;
1910  struct stat stbuf;
1911 
1912  Xorriso_alloc_meM(link_target, char, SfileadrL);
1913 
1914  rpt= xorriso->result_line;
1915 
1916  ret= Xorriso_dir_from_path(xorriso, "Working directory", xorriso->wdi,
1917  &dir_node, 0);
1918  if(ret <= 0)
1919  goto ex;
1920  ret= iso_dir_get_children(dir_node, &iter);
1921  if(ret<0) {
1922 cannot_create_iter:;
1923  Xorriso_cannot_create_iter(xorriso, ret, 0);
1924  {ret= -1; goto ex;}
1925  }
1926  Xorriso_process_msg_queues(xorriso,0);
1927 
1928  for(i= 0; iso_dir_iter_next(iter, &node) == 1; ) {
1929  npt= (char *) iso_node_get_name(node);
1930  if(!(flag&4)) {
1931  ret= Xorriso_regexec(xorriso, npt, &failed_at, 0);
1932  if(ret)
1933  continue; /* no match */
1934  }
1935  filec++;
1936  }
1937  /* Reset iteration */
1938  iso_dir_iter_free(iter);
1939  iter= NULL;
1940  Xorriso_process_msg_queues(xorriso,0);
1941  if(flag&8)
1942  {ret= filec; goto ex;}
1943  sprintf(xorriso->info_text, "Valid ISO nodes found: %d\n", filec);
1944  Xorriso_info(xorriso,1);
1945 
1946  ret= Xorriso_sorted_node_array(xorriso, dir_node, &filec, &node_array, 0,
1947  flag&4);
1948  if(ret<0)
1949  goto ex;
1950  if(ret==0) {
1951  no_sort= 1;
1952  ret= iso_dir_get_children(dir_node, &iter);
1953  if(ret<0)
1954  goto cannot_create_iter;
1955  }
1956 
1957  for(i= 0; i<filec && !(xorriso->request_to_abort); i++) {
1958  if(no_sort) {
1959  ret= iso_dir_iter_next(iter, &node);
1960  if(ret!=1)
1961  break;
1962  npt= (char *) iso_node_get_name(node);
1963  if(!(flag&4)) {
1964  ret= Xorriso_regexec(xorriso, npt, &failed_at, 0);
1965  if(ret)
1966  continue; /* no match */
1967  }
1968  } else
1969  node= node_array[i];
1970 
1971  npt= (char *) iso_node_get_name(node);
1972  link_target[0]= 0;
1973  if(LIBISO_ISLNK(node)) {
1974  if(Sfile_str(link_target, (char *) iso_symlink_get_dest(
1975  (IsoSymlink *) node), 0)<=0)
1976  link_target[0]= 0;
1977  }
1978  rpt[0]= 0;
1979  if(flag&1) {
1980  ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1);
1981  if(ret<=0)
1982  continue;
1983  ret= Xorriso_format_ls_l(xorriso, &stbuf, 1);
1984  if(ret<=0)
1985  continue;
1986  }
1987  if(link_target[0] && (flag&1)) {
1988  Xorriso_esc_filepath(xorriso, npt, xorriso->result_line, 1);
1989  strcat(xorriso->result_line, " -> ");
1990  Xorriso_esc_filepath(xorriso, link_target, xorriso->result_line, 1 | 2);
1991  } else {
1992  Xorriso_esc_filepath(xorriso, npt, xorriso->result_line, 1);
1993  }
1994  strcat(xorriso->result_line, "\n");
1995  Xorriso_result(xorriso, 0);
1996  }
1997 
1998  ret= 1;
1999 ex:;
2000  if(iter!=NULL)
2001  iso_dir_iter_free(iter);
2002  Xorriso_process_msg_queues(xorriso,0);
2003  if(node_array!=NULL)
2004  free((char *) node_array);
2005  Xorriso_free_meM(link_target);
2006  return(ret);
2007 }
2008 
2009 
2010 /* @param flag bit0= count results rather than storing them
2011  bit1= this is a recursion
2012  bit2= prepend wd (automatically done if wd[0]!=0)
2013 */
2015  struct XorrisO *xorriso, char *wd, IsoDir *dir,
2016  int *filec, char **filev, int count_limit, off_t *mem,
2017  int *dive_count, int flag)
2018 {
2019  int ret, failed_at;
2020  IsoDirIter *iter= NULL;
2021  IsoNode *node;
2022  char *name;
2023  char *adr= NULL;
2024 
2025  adr= malloc(SfileadrL);
2026  if(adr==NULL) {
2027  Xorriso_no_malloc_memory(xorriso, &adr, 0);
2028  {ret= -1; goto ex;}
2029  }
2030 
2031  if(!(flag&2))
2032  *dive_count= 0;
2033  else
2034  (*dive_count)++;
2035  ret= Xorriso_check_for_root_pattern(xorriso, filec, filev, count_limit,
2036  mem, (flag&1)|2);
2037  if(ret!=2)
2038  goto ex;
2039 
2040  ret= iso_dir_get_children(dir, &iter);
2041  if(ret<0) {
2042  Xorriso_cannot_create_iter(xorriso, ret, 0);
2043  {ret= -1; goto ex;}
2044  }
2045  while(iso_dir_iter_next(iter, &node) == 1) {
2046  name= (char *) iso_node_get_name(node);
2047  ret= Xorriso_make_abs_adr(xorriso, wd, name, adr, flag&4);
2048  if(ret<=0)
2049  goto ex;
2050  ret= Xorriso_regexec(xorriso, adr, &failed_at, 1);
2051  if(ret) { /* no match */
2052  if(failed_at <= *dive_count) /* no hope for a match */
2053  continue;
2054 
2055  if(!LIBISO_ISDIR(node)) {
2056 
2057  /* >>> How to deal with softlinks ? */
2058 
2059  continue;
2060  }
2061  /* dive deeper */
2063  xorriso, adr, (IsoDir *) node,
2064  filec, filev, count_limit, mem, dive_count, flag|2);
2065  if(ret<=0)
2066  goto ex;
2067  } else {
2068  ret= Xorriso_register_matched_adr(xorriso, adr, count_limit,
2069  filec, filev, mem, (flag&1)|2);
2070  if(ret<=0)
2071  goto ex;
2072  }
2073  }
2074  ret= 1;
2075 ex:;
2076  if(adr!=NULL)
2077  free(adr);
2078  if(flag&2)
2079  (*dive_count)--;
2080  if(iter != NULL)
2081  iso_dir_iter_free(iter);
2082  return(ret);
2083 }
2084 
2085 
2086 /* @param flag bit0= a match count !=1 is a FAILURE event
2087  bit1= with bit0 tolerate 0 matches if pattern is a constant
2088  bit2= do not issue debug messages about temporary memory needs
2089  bit3= do not add unresolved pattern to filev
2090 */
2091 int Xorriso_expand_pattern(struct XorrisO *xorriso,
2092  int num_patterns, char **patterns, int extra_filec,
2093  int *filec, char ***filev, off_t *mem, int flag)
2094 {
2095  int ret, count= 0, abs_adr= 0, i, was_count, was_filec;
2096  int nonconst_mismatches= 0, dive_count= 0;
2097  IsoImage *volume;
2098  IsoDir *dir= NULL, *root_dir;
2099  IsoNode *iso_node;
2100 
2101  *filec= 0;
2102  *filev= NULL;
2103 
2104  xorriso->search_mode= 3;
2105  xorriso->structured_search= 1;
2106 
2107  ret= Xorriso_get_volume(xorriso, &volume, 0);
2108  if(ret<=0)
2109  return(ret);
2110  root_dir= iso_image_get_root(volume);
2111  if(root_dir==NULL) {
2112  Xorriso_process_msg_queues(xorriso,0);
2113  sprintf(xorriso->info_text,
2114  "While expanding pattern : Cannot obtain root node of ISO image");
2115  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
2116  ret= -1; goto ex;
2117  }
2118 
2119  for(i= 0; i<num_patterns; i++) {
2120  ret= Xorriso_prepare_expansion_pattern(xorriso, patterns[i], 0);
2121  if(ret<=0)
2122  return(ret);
2123  if(ret==2)
2124  abs_adr= 4;
2125  if(patterns[i][0]=='/' || abs_adr) {
2126  dir= root_dir;
2127  abs_adr= 4;
2128  } else {
2129  /* This is done so late to allow the following:
2130  It is not an error if xorriso->wdi does not exist yet, but one may
2131  not use it as base for relative address searches.
2132  */
2133  ret= Xorriso_node_from_path(xorriso, volume, xorriso->wdi, &iso_node, 1);
2134  dir= (IsoDir *) iso_node;
2135  if(ret<=0) {
2136  Xorriso_process_msg_queues(xorriso,0);
2137  sprintf(xorriso->info_text, "While expanding pattern ");
2138  Text_shellsafe(patterns[i], xorriso->info_text, 1);
2139  strcat(xorriso->info_text,
2140  " : Working directory does not exist in ISO image");
2141  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2142  ret= 0; goto ex;
2143  }
2144  if(!LIBISO_ISDIR((IsoNode *) dir)) {
2145  sprintf(xorriso->info_text,
2146  "Working directory path does not lead to a directory in ISO image");
2147  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2148  ret= 0; goto ex;
2149  }
2150  }
2151 
2152  /* count the matches */
2153  was_count= count;
2154  ret= Xorriso_obtain_pattern_files_i(xorriso, "", dir, &count, NULL, 0,
2155  mem, &dive_count, 1 | abs_adr);
2156  if(ret<=0)
2157  goto ex;
2158  if(was_count==count && strcmp(patterns[i],"*")!=0 && (flag&3)!=1 &&
2159  !(flag & 8)) {
2160  count++;
2161  Xorriso_eval_nonmatch(xorriso, patterns[i], &nonconst_mismatches, mem, 0);
2162  }
2163  }
2164 
2165  ret= Xorriso_check_matchcount(xorriso, count, nonconst_mismatches,
2166  num_patterns, patterns, (flag&1)|2);
2167  if(ret<=0)
2168  goto ex;
2169  count+= extra_filec;
2170  (*mem)+= extra_filec * sizeof(char *);
2171  if(count<=0)
2172  {ret= !!(flag & 8); goto ex;}
2173  ret= Xorriso_alloc_pattern_mem(xorriso, *mem, count, filev, !!(flag & 4));
2174  if(ret<=0)
2175  goto ex;
2176  /* now store addresses */
2177  for(i= 0; i<num_patterns; i++) {
2178  ret= Xorriso_prepare_expansion_pattern(xorriso, patterns[i], 0);
2179  if(ret<=0)
2180  return(ret);
2181  if(ret==2)
2182  abs_adr= 4;
2183 
2184  was_filec= *filec;
2185  ret= Xorriso_obtain_pattern_files_i(xorriso, "", dir, filec, *filev, count,
2186  mem, &dive_count, abs_adr);
2187  if(ret<=0)
2188  goto ex;
2189  if(was_filec == *filec && strcmp(patterns[i],"*")!=0 && (flag&3) != 1 &&
2190  !(flag & 8)) {
2191  (*filev)[*filec]= strdup(patterns[i]);
2192  if((*filev)[*filec]==NULL) {
2193  (*mem)= strlen(patterns[i])+1;
2194  Xorriso_no_pattern_memory(xorriso, *mem, 0);
2195  ret= -1; goto ex;
2196  }
2197  (*filec)++;
2198  }
2199  }
2200  ret= 1;
2201 ex:;
2202  if(ret<=0) {
2203  Sfile_destroy_argv(&count, filev, 0);
2204  *filec= 0;
2205  }
2206  return(ret);
2207 }
2208 
2209 
2210 int Xorriso__start_end_lbas(IsoNode *node,
2211  int *lba_count, int **start_lbas, int **end_lbas,
2212  off_t **section_sizes, off_t *size, int flag)
2213 {
2214  int section_count= 0, ret, i;
2215  struct iso_file_section *sections= NULL;
2216 
2217  *lba_count= 0;
2218  *start_lbas= *end_lbas= NULL;
2219  *section_sizes= NULL;
2220  *size= 0;
2221  if(!LIBISO_ISREG(node))
2222  return(0);
2223  *size= iso_file_get_size((IsoFile *) node);
2224  ret= iso_file_get_old_image_sections((IsoFile *) node, &section_count,
2225  &sections, 0);
2226  if(ret < 0)
2227  {ret= -1; goto ex;}
2228  if(ret != 1 || section_count <= 0)
2229  {ret= 0; goto ex;}
2230  *start_lbas= calloc(section_count, sizeof(int));
2231  *end_lbas= calloc(section_count, sizeof(int));
2232  *section_sizes= calloc(section_count, sizeof(off_t));
2233  if(*start_lbas == NULL || *end_lbas == NULL || *section_sizes == NULL)
2234  {ret= -1; goto ex;}
2235  for(i= 0; i < section_count; i++) {
2236  (*start_lbas)[i]= sections[i].block;
2237  (*end_lbas)[i]= sections[i].block + sections[i].size / 2048 - 1;
2238  if(sections[i].size % 2048)
2239  (*end_lbas)[i]++;
2240  (*section_sizes)[i]= sections[i].size;
2241  }
2242  *lba_count= section_count;
2243  ret= 1;
2244 ex:;
2245  if(sections != NULL)
2246  free((char *) sections);
2247  if(ret <= 0) {
2248  if((*start_lbas) != NULL)
2249  free((char *) *start_lbas);
2250  if((*end_lbas) != NULL)
2251  free((char *) *end_lbas);
2252  *start_lbas= *end_lbas= NULL;
2253  *lba_count= 0;
2254  }
2255  return(ret);
2256 }
2257 
2258 
2259 int Xorriso__file_start_lba(IsoNode *node,
2260  int *lba, int flag)
2261 {
2262  int *start_lbas= NULL, *end_lbas= NULL, lba_count= 0, i, ret;
2263  off_t size, *section_sizes= NULL;
2264 
2265  *lba= -1;
2266  ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas,
2267  &section_sizes, &size, 0);
2268  if(ret <= 0)
2269  return(ret);
2270  for(i= 0; i < lba_count; i++) {
2271  if(*lba < 0 || start_lbas[i] < *lba)
2272  *lba= start_lbas[i];
2273  }
2274  if(start_lbas != NULL)
2275  free((char *) start_lbas);
2276  if(end_lbas != NULL)
2277  free((char *) end_lbas);
2278  if(section_sizes != NULL)
2279  free((char *) section_sizes);
2280  if(*lba < 0)
2281  return(0);
2282  return(1);
2283 }
2284 
2285 
2286 /* flag bit0= examine sub directories rather than data files
2287 */
2288 int Xorriso_dir_disk_path(struct XorrisO *xorriso, IsoNode *dir_node,
2289  char disk_path[SfileadrL], int flag)
2290 {
2291  int ret;
2292  char *npt;
2293  IsoNode *node;
2294  IsoDir *dir;
2295  IsoDirIter *iter= NULL;
2296 
2297  dir= (IsoDir *) dir_node;
2298  ret= iso_dir_get_children(dir, &iter);
2299  if(ret<0) {
2300  Xorriso_cannot_create_iter(xorriso, ret, 0);
2301  {ret= -1; goto ex;}
2302  }
2303  while(1) {
2304  ret= iso_dir_iter_next(iter, &node);
2305  if(ret < 0) {
2306  Xorriso_report_iso_error(xorriso, "", ret,
2307  "Error when iterating over directory", 0, "FAILURE", 1);
2308  ret= -1; goto ex;
2309  }
2310  if(ret == 0)
2311  break;
2312 
2313  if(LIBISO_ISDIR(node) && (flag & 1)) {
2314  ret= Xorriso_dir_disk_path(xorriso, node, disk_path, flag);
2315  if(ret < 0)
2316  goto ex;
2317  if(ret == 0)
2318  continue;
2319  } else if(LIBISO_ISREG(node) && !(flag & 1)) {
2320  ret= Xorriso_retrieve_disk_path(xorriso, node, disk_path, 0);
2321  if(ret < 0)
2322  goto ex;
2323  if(ret == 0)
2324  continue;
2325  } else
2326  continue;
2327  /* Use its parent dir as answer */
2328  npt= strrchr(disk_path, '/');
2329  if(npt == NULL || npt == disk_path)
2330  strcpy(disk_path, "/");
2331  else
2332  *npt= 0;
2333  ret= 1; goto ex;
2334  }
2335  if(!(flag & 1))
2336  ret= Xorriso_dir_disk_path(xorriso, dir_node, disk_path, 1);
2337  else
2338  ret= 0;
2339 ex:
2340  if(iter != NULL)
2341  iso_dir_iter_free(iter);
2342  return(ret);
2343 }
2344 
2345 
2346 int Xorriso_retrieve_disk_path(struct XorrisO *xorriso, IsoNode *node,
2347  char disk_path[SfileadrL], int flag)
2348 {
2349  IsoFile *file;
2350  IsoStream *stream= NULL, *input_stream;
2351  char type_text[80], *source_path = NULL;
2352  int ret;
2353 
2354  if(LIBISO_ISDIR(node)) {
2355  ret= Xorriso_dir_disk_path(xorriso, node, disk_path, 0);
2356  return(ret);
2357  }
2358 
2359  if(!LIBISO_ISREG(node))
2360  return(0);
2361 
2362  /* Obtain most fundamental input stream */
2363  file= (IsoFile *) node;
2364  input_stream= iso_file_get_stream(file);
2365  if(input_stream == NULL)
2366  return(0);
2367  while(1) {
2368  stream= input_stream;
2369  input_stream= iso_stream_get_input_stream(stream, 0);
2370  if(input_stream == NULL)
2371  break;
2372  }
2373 
2374  /* Obtain disk path if applicable */
2375  type_text[0]= 0;
2376  Xorriso_stream_type(xorriso, node, stream, type_text, 0);
2377  if(strcmp(type_text, "disk") != 0 && strcmp(type_text, "cout") != 0)
2378  return(0); /* among othersi rejected: "image" */
2379  source_path= iso_stream_get_source_path(stream, 0);
2380  if(source_path == NULL)
2381  return(0);
2382  if(strlen(source_path) >= SfileadrL) {
2383  free(source_path);
2384  return(0);
2385  }
2386  strcpy(disk_path, source_path);
2387  free(source_path);
2388  return(1);
2389 }
2390 
2391 
2392 /* @param flag bit0= show numbers from iso_stream_get_id
2393  */
2394 int Xorriso_show_stream(struct XorrisO *xorriso, void *in_node,
2395  char *path, int flag)
2396 {
2397  int ret;
2398  IsoNode *node;
2399  IsoFile *file;
2400  IsoStream *stream= NULL, *input_stream;
2401  IsoExternalFilterCommand *cmd;
2402  char type_text[80], *source_path= NULL;
2403  unsigned int fs_id;
2404  dev_t dev_id;
2405  ino_t ino_id;
2406 
2407  node= (IsoNode *) in_node;
2408  if(node == NULL) {
2409  ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
2410  if(ret <= 0)
2411  goto ex;
2412  }
2413  if(!LIBISO_ISREG(node))
2414  {ret= 2; goto ex;}
2415  file= (IsoFile *) node;
2416  input_stream= iso_file_get_stream(file);
2417  Text_shellsafe(path, xorriso->result_line, 0);
2418  while(1) {
2419  stream= input_stream;
2420  input_stream= iso_stream_get_input_stream(stream, 0);
2421  if(input_stream == NULL)
2422  break;
2423  strcat(xorriso->result_line, " < ");
2424  Xorriso_stream_type(xorriso, node, stream, type_text, 0);
2425  strcat(xorriso->result_line, type_text);
2426  if(flag & 1) {
2427  iso_stream_get_id(stream, &fs_id, &dev_id, &ino_id);
2428  sprintf(xorriso->result_line + strlen(xorriso->result_line),
2429  "[%u,%lu,%lu]", fs_id, (unsigned long) dev_id,
2430  (unsigned long) ino_id);
2431  }
2432  ret= iso_stream_get_external_filter(stream, &cmd, 0);
2433  if(ret < 0) {
2434  Xorriso_process_msg_queues(xorriso,0);
2435  Xorriso_report_iso_error(xorriso, "", ret,
2436  "Error when inquiring filter command of node", 0, "FAILURE", 1);
2437  ret= 0; goto ex;
2438  }
2439  if(ret > 0) {
2440  strcat(xorriso->result_line, ":");
2441  Text_shellsafe(cmd->name, xorriso->result_line, 1);
2442  }
2443  if(strlen(xorriso->result_line) > SfileadrL) {
2444  Xorriso_result(xorriso, 0);
2445  xorriso->result_line[0]= 0;
2446  }
2447  }
2448  strcat(xorriso->result_line, " < ");
2449  Xorriso_stream_type(xorriso, node, stream, type_text, 0);
2450  strcat(xorriso->result_line, type_text);
2451  if(flag & 1) {
2452  iso_stream_get_id(stream, &fs_id, &dev_id, &ino_id);
2453  sprintf(xorriso->result_line + strlen(xorriso->result_line), "[%u,%lu,%lu]",
2454  fs_id, (unsigned long) dev_id, (unsigned long) ino_id);
2455  }
2456 
2457  source_path= iso_stream_get_source_path(stream, 0);
2458  if(source_path != NULL) {
2459  strcat(xorriso->result_line, ":");
2460  Text_shellsafe(source_path, xorriso->result_line, 1);
2461  }
2462 
2463  strcat(xorriso->result_line, "\n");
2464  Xorriso_result(xorriso, 0);
2465  ret= 1;
2466 ex:;
2467  if(source_path != NULL)
2468  free(source_path);
2469  return(ret);
2470 }
2471 
2472 
2473 /* @param damage_start Returns first damaged byte address
2474  @param damage_end Returns first byte address after last damaged byte
2475  @return <0 error, 0=undamaged , 1=damaged
2476 */
2477 int Xorriso_file_eval_damage(struct XorrisO *xorriso, IsoNode *node,
2478  off_t *damage_start, off_t *damage_end,
2479  int flag)
2480 {
2481  int *start_lbas= NULL, *end_lbas= NULL, lba_count= 0, sect;
2482  int i, sectors, sector_size, ret;
2483  off_t sect_base= 0, size= 0, byte, *section_sizes= NULL;
2484  struct SectorbitmaP *map;
2485 
2486  *damage_start= *damage_end= -1;
2487  map= xorriso->in_sector_map;
2488  if(map == NULL)
2489  return(0);
2491  sector_size/= 2048;
2492 
2493  ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas,
2494  &section_sizes, &size, 0);
2495  if(ret <= 0) {
2496  Xorriso_process_msg_queues(xorriso, 0);
2497  return(ret);
2498  }
2499  for(sect= 0; sect < lba_count; sect++) {
2500  for(i= start_lbas[sect]; i <= end_lbas[sect]; i+= sector_size) {
2501  if(Sectorbitmap_is_set(map, i / sector_size, 0) == 0) {
2502  byte= ((off_t) 2048) * ((off_t) (i - start_lbas[sect])) + sect_base;
2503  if(*damage_start < 0 || byte < *damage_start)
2504  *damage_start= byte;
2505  if(byte + (off_t) 2048 > *damage_end)
2506  *damage_end= byte + (off_t) 2048;
2507  }
2508  }
2509  sect_base+= ((off_t) 2048) *
2510  ((off_t) (end_lbas[sect] - start_lbas[sect] + 1));
2511  }
2512  if(*damage_end > size)
2513  *damage_end= size;
2514  if(start_lbas != NULL)
2515  free((char *) start_lbas);
2516  if(end_lbas != NULL)
2517  free((char *) end_lbas);
2518  if(section_sizes != NULL)
2519  free((char *) section_sizes);
2520  if(*damage_start < 0)
2521  return(0);
2522  return(1);
2523 }
2524 
2525 
2526 /* @param flag bit0= report_sections : section size rather than total size
2527  bit1= last_data_file_block : looking for highest data file block
2528 */
2529 int Xorriso_report_lba(struct XorrisO *xorriso, char *show_path,
2530  IsoNode *node, uint32_t *last_block, int flag)
2531 {
2532  int ret, *start_lbas= NULL, *end_lbas= NULL, lba_count, i;
2533  off_t size, *section_sizes= NULL;
2534 
2535  ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas,
2536  &section_sizes, &size, 0);
2537  if(ret < 0) {
2538  Xorriso_process_msg_queues(xorriso, 0);
2539  {ret= -1; goto ex;}
2540  }
2541  if(ret == 0)
2542  {ret= 1; goto ex;} /* it is ok to ignore other types */
2543  for(i= 0; i < lba_count; i++) {
2544  if(flag & 1)
2545  size= section_sizes[i];
2546  if(flag & 2) {
2547  if(end_lbas[i] > 0 && (uint32_t) end_lbas[i] > *last_block)
2548  *last_block= end_lbas[i];
2549  } else {
2550  sprintf(xorriso->result_line,
2551  "File data lba: %2d , %8d , %8d , %8.f , ",
2552  i, start_lbas[i], end_lbas[i] + 1 - start_lbas[i], (double) size);
2553  Text_shellsafe(show_path, xorriso->result_line, 1);
2554  strcat(xorriso->result_line, "\n");
2555  Xorriso_result(xorriso, 0);
2556  }
2557  }
2558  ret= 1;
2559 ex:;
2560  if(start_lbas != NULL)
2561  free((char *) start_lbas);
2562  if(end_lbas != NULL)
2563  free((char *) end_lbas);
2564  if(section_sizes != NULL)
2565  free((char *) section_sizes);
2566  return(ret);
2567 }
2568 
2569 
2570 int Xorriso_report_damage(struct XorrisO *xorriso, char *show_path,
2571  IsoNode *node, int flag)
2572 {
2573  int ret;
2574  off_t size= 0, damage_start, damage_end;
2575 
2576  ret= Xorriso_file_eval_damage(xorriso, node, &damage_start, &damage_end, 0);
2577  if(ret < 0)
2578  return(0);
2579 
2580  if(LIBISO_ISREG(node))
2581  size= iso_file_get_size((IsoFile *) node);
2582  if(ret > 0) {
2583  sprintf(xorriso->result_line, "File damaged : %8.f , %8.f , %8.f , ",
2584  (double) damage_start, (double) (damage_end - damage_start) ,
2585  (double) size);
2586  } else {
2587  sprintf(xorriso->result_line, "File seems ok: %8.f , %8.f , %8.f , ",
2588  -1.0, -1.0, (double) size);
2589  }
2590  Text_shellsafe(show_path, xorriso->result_line, 1);
2591  strcat(xorriso->result_line, "\n");
2592  Xorriso_result(xorriso, 0);
2593  return(1);
2594 }
2595 
2596 
2597 /* @param flag bit0= do not accept hln_targets[i] != NULL as *node_idx
2598  bit1= use *node_idx as found index rather than searching it
2599  bit2= with bit1: use xorriso->node_array rather than hln_array
2600 */
2601 int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node,
2602  int *node_idx, int *min_hl, int *max_hl, int flag)
2603 {
2604  int idx, ret, i, node_count;
2605  void *np, **node_array;
2606 
2607  node_array= xorriso->hln_array;
2608  node_count= xorriso->hln_count;
2609  *min_hl= *max_hl= -1;
2610  np= node;
2611  if(flag & 2) {
2612  idx= *node_idx;
2613  if(flag & 4) {
2614  node_array= xorriso->node_array;
2615  node_count= xorriso->node_counter;
2616  }
2617  } else {
2618  *node_idx= -1;
2619  ret= Xorriso_search_in_hln_array(xorriso, np, &idx, 0);
2620  if(ret <= 0)
2621  return(ret);
2622  }
2623  for(i= idx - 1; i >= 0 ; i--)
2624  if(Xorriso__findi_sorted_ino_cmp(&(node_array[i]), &np) != 0)
2625  break;
2626  *min_hl= i + 1;
2627  for(i= idx + 1; i < node_count; i++)
2628  if(Xorriso__findi_sorted_ino_cmp(&(node_array[i]), &np) != 0)
2629  break;
2630  *max_hl= i - 1;
2631 
2632  /* Search for *node_idx */
2633  if(flag & 2)
2634  return(1);
2635  for(i= *min_hl; i <= *max_hl; i++)
2636  if(node_array[i] == np) {
2637  if((flag & 1) && xorriso->hln_targets != NULL && !(flag & 4))
2638  if(xorriso->hln_targets[i] != NULL)
2639  continue;
2640  *node_idx= i;
2641  break;
2642  }
2643  return(1);
2644 }
2645 
2646 
2647 /* @param flag bit0=do not complain about non existent node
2648  bit1= do not try to find truncated name first
2649  */
2650 int Xorriso_node_from_path(struct XorrisO *xorriso, IsoImage *volume,
2651  char *path, IsoNode **node, int flag)
2652 {
2653  int ret;
2654  char *path_pt;
2655 
2656  path_pt= path;
2657  if(path[0]==0)
2658  path_pt= "/";
2659  if(volume == NULL) {
2660  ret= Xorriso_get_volume(xorriso, &volume, 0);
2661  if(ret <= 0)
2662  return(ret);
2663  }
2664  *node= NULL;
2665  ret= 2;
2666  if(!(flag & 2))
2667  ret= iso_image_path_to_node(volume, path_pt, node);
2668  if(ret == 2)
2669  ret= iso_tree_path_to_node(volume, path_pt, node);
2670  Xorriso_process_msg_queues(xorriso,0);
2671  if(ret<=0 || (*node)==NULL) {
2672  if(!(flag&1)) {
2673  sprintf(xorriso->info_text, "Cannot find path ");
2674  Text_shellsafe(path_pt, xorriso->info_text, 1);
2675  strcat(xorriso->info_text, " in loaded ISO image");
2676  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2677  }
2678  return(0);
2679  }
2680  return(1);
2681 }
2682 
2683 
2684 /* @param flag bit0=do not complain about non existent node
2685  bit1= do not try to find truncated name first
2686  */
2687 int Xorriso_dir_from_path(struct XorrisO *xorriso, char *purpose,
2688  char *path, IsoDir **dir_node, int flag)
2689 {
2690  IsoImage *volume;
2691  IsoNode *node;
2692  int ret, is_dir= 0;
2693 
2694  ret= Xorriso_get_volume(xorriso, &volume, 0);
2695  if(ret<=0)
2696  return(ret);
2697 
2698  ret= Xorriso_node_from_path(xorriso, volume, path, &node, flag & 3);
2699  if(ret<=0)
2700  goto wdi_is_not_a_dir;
2701  if(LIBISO_ISDIR(node))
2702  is_dir= 1;
2703  if(!is_dir) {
2704 wdi_is_not_a_dir:;
2705  sprintf(xorriso->info_text,
2706  "%s path does not lead to a directory in ISO image", purpose);
2707  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2708  return(0);
2709  }
2710  *dir_node= (IsoDir *) node;
2711  return(1);
2712 }
2713 
2714 
2715 /*
2716  @param flag bit0= do not remove leading slash
2717  bit1= append flatly to result_line and put out
2718 */
2719 int Xorriso_getfname(struct XorrisO *xorriso, char *path, int flag)
2720 {
2721  int ret, path_offset= 0, bsl_mem;
2722  char *bsl_path= NULL;
2723 
2724  if(path[0] == '/' && !(flag & 1))
2725  path_offset= 1;
2726 
2727  /* backslash escaped path rather than shellsafe path */
2728  ret= Sfile_bsl_encoder(&bsl_path, path + path_offset,
2729  strlen(path + path_offset), 8);
2730  if(ret <= 0)
2731  return(-1);
2732  if(flag & 2) {
2733  sprintf(xorriso->result_line + strlen(xorriso->result_line),
2734  "%s\n", bsl_path[0] ? bsl_path : ".");
2735  } else {
2736  sprintf(xorriso->result_line, "# file: %s\n", bsl_path[0] ? bsl_path : ".");
2737  }
2738  free(bsl_path);
2739  bsl_path= NULL;
2740  /* temporarily disable -backslash_codes with result output */
2741  bsl_mem= xorriso->bsl_interpretation;
2742  xorriso->bsl_interpretation= 0;
2743  Xorriso_result(xorriso, 0);
2744  xorriso->bsl_interpretation= bsl_mem;
2745  return(1);
2746 }
2747 
2748 
2749 int Xorriso_is_plain_image_file(struct XorrisO *xorriso, void *in_node,
2750  char *path, int flag)
2751 {
2752  int ret, lba;
2753  IsoStream *stream;
2754  IsoNode *node;
2755 
2756  node= (IsoNode *) in_node;
2757  if(node == NULL) {
2758  ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
2759  if(ret<=0)
2760  return(ret);
2761  }
2762 
2763  ret= Xorriso__file_start_lba(node, &lba, 0);
2764  if(ret > 0) { /* Stream source is from loaded image */
2765  stream= iso_file_get_stream((IsoFile *) node);
2766  if(stream != NULL)
2767  if(iso_stream_get_input_stream(stream, 0) == NULL)
2768  return(1);
2769  }
2770  return(0);
2771 }
2772 
int Splitpart__parse(char *name, int *partno, int *total_parts, off_t *offset, off_t *bytes, off_t *total_bytes, int flag)
Definition: aux_objects.c:153
int Splitparts_new(struct SplitparT **o, int count, int flag)
Definition: aux_objects.c:62
int Splitparts_sort(struct SplitparT *o, int count, int flag)
Definition: aux_objects.c:259
int Splitparts_get(struct SplitparT *o, int idx, char **name, int *partno, int *total_parts, off_t *offset, off_t *bytes, off_t *total_bytes, int flag)
Definition: aux_objects.c:115
int Splitparts_destroy(struct SplitparT **o, int count, int flag)
Definition: aux_objects.c:81
int Splitparts_set(struct SplitparT *o, int idx, char *name, int partno, int total_parts, off_t offset, off_t bytes, off_t total_bytes, int flag)
Definition: aux_objects.c:97
int Sectorbitmap_is_set(struct SectorbitmaP *o, int sector, int flag)
Definition: check_media.c:477
int Sectorbitmap_get_layout(struct SectorbitmaP *o, int *sectors, int *sector_size, int flag)
Definition: check_media.c:498
int Xorriso_format_ls_l(struct XorrisO *xorriso, struct stat *stbuf, int flag)
Definition: disk_ops.c:661
int Xorriso_resolve_link(struct XorrisO *xorriso, char *link_path, char result_path[4096], int flag)
Definition: disk_ops.c:45
int Findjob_set_action_found_path(struct FindjoB *o, int flag)
Definition: findjob.c:1292
int Findjob_set_lba_range(struct FindjoB *o, int start_lba, int count, int flag)
Definition: findjob.c:898
int Findjob_set_wanted_node(struct FindjoB *o, void *wanted_node, int flag)
Definition: findjob.c:1021
int Findjob_destroy(struct FindjoB **o, int flag)
Definition: findjob.c:401
int Findjob_new(struct FindjoB **o, char *start_path, int flag)
Definition: findjob.c:355
int Findjob_get_found_path(struct FindjoB *o, char **path, int flag)
Definition: findjob.c:1105
static int Sfile_destroy_argv(int *argc, char ***argv, int flag)
#define SfileadrL
int Xorriso_set_change_pending(struct XorrisO *xorriso, int flag)
Definition: iso_img.c:1004
int Xorriso_get_volume(struct XorrisO *xorriso, IsoImage **volume, int flag)
Definition: iso_img.c:966
int Xorriso_cannot_create_iter(struct XorrisO *xorriso, int iso_error, int flag)
Definition: iso_manip.c:2509
int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, void *boss_iter, off_t boss_mem, void *dir_node_generic, char *dir_path, struct stat *dir_stbuf, int depth, int flag)
Definition: iso_manip.c:3355
int Xorriso_sorted_dir_i(struct XorrisO *xorriso, IsoDir *dir_node, int *filec, char ***filev, off_t boss_mem, int flag)
Definition: iso_tree.c:1554
int Xorriso_show_du_subs(struct XorrisO *xorriso, IsoDir *dir_node, char *abs_path, char *rel_path, off_t *size, off_t boss_mem, int flag)
Definition: iso_tree.c:1415
int Xorriso_get_md5(struct XorrisO *xorriso, void *in_node, char *path, char md5[16], int flag)
Definition: iso_tree.c:1339
int Xorriso_append_extattr_comp(struct XorrisO *xorriso, char *comp, size_t comp_len, char *mode, int flag)
Definition: iso_tree.c:916
int Xorriso_dir_disk_path(struct XorrisO *xorriso, IsoNode *dir_node, char disk_path[4096], int flag)
Definition: iso_tree.c:2288
int Xorriso_retrieve_disk_path(struct XorrisO *xorriso, IsoNode *node, char disk_path[4096], int flag)
Definition: iso_tree.c:2346
int Xorriso_fake_stbuf(struct XorrisO *xorriso, char *path, struct stat *stbuf, IsoNode **node, int flag)
Definition: iso_tree.c:245
int Xorriso_report_lba(struct XorrisO *xorriso, char *show_path, IsoNode *node, uint32_t *last_block, int flag)
Definition: iso_tree.c:2529
int Xorriso_dir_from_path(struct XorrisO *xorriso, char *purpose, char *path, IsoDir **dir_node, int flag)
Definition: iso_tree.c:2687
int Xorriso_iso_lstat(struct XorrisO *xorriso, char *path, struct stat *stbuf, int flag)
Definition: iso_tree.c:363
int Xorriso_get_dus(struct XorrisO *xorriso, char *iso_rr_path, off_t *size, off_t boss_mem, int flag)
Definition: iso_tree.c:1863
int Xorriso__file_start_lba(IsoNode *node, int *lba, int flag)
Definition: iso_tree.c:2259
int Xorriso_getfname(struct XorrisO *xorriso, char *path, int flag)
Definition: iso_tree.c:2719
int Xorriso_node_eff_hidden(struct XorrisO *xorriso, IsoNode *node, int flag)
Definition: iso_tree.c:1615
int Xorriso_get_attr_value(struct XorrisO *xorriso, void *in_node, char *path, char *name, size_t *value_length, char **value, int flag)
Definition: iso_tree.c:1263
int Xorriso_path_from_node(struct XorrisO *xorriso, IsoNode *in_node, char path[4096], int flag)
Definition: iso_tree.c:399
int Xorriso_identify_split(struct XorrisO *xorriso, char *iso_adr, void *in_node, struct SplitparT **parts, int *count, struct stat *total_stbuf, int flag)
Definition: iso_tree.c:500
int Xorriso_list_extattr(struct XorrisO *xorriso, void *in_node, char *path, char *show_path, char *mode, int flag)
Definition: iso_tree.c:991
int Xorriso_node_from_path(struct XorrisO *xorriso, IsoImage *volume, char *path, IsoNode **node, int flag)
Definition: iso_tree.c:2650
int Xorriso_make_md5(struct XorrisO *xorriso, void *in_node, char *path, int flag)
Definition: iso_tree.c:1379
int Xorriso_obtain_pattern_files_i(struct XorrisO *xorriso, char *wd, IsoDir *dir, int *filec, char **filev, int count_limit, off_t *mem, int *dive_count, int flag)
Definition: iso_tree.c:2014
int Xorriso_truncate_path_comps(struct XorrisO *xorriso, char *path, char *buffer, char **resultpt, int flag)
Definition: iso_tree.c:1640
int Xorriso_report_damage(struct XorrisO *xorriso, char *show_path, IsoNode *node, int flag)
Definition: iso_tree.c:2570
int Xorriso_is_plain_image_file(struct XorrisO *xorriso, void *in_node, char *path, int flag)
Definition: iso_tree.c:2749
int Xorriso_ls_filev(struct XorrisO *xorriso, char *wd, int filec, char **filev, off_t boss_mem, int flag)
Definition: iso_tree.c:1724
int Xorriso_getfacl(struct XorrisO *xorriso, void *in_node, char *path, char **acl_text, int flag)
Definition: iso_tree.c:665
int Xorriso_show_stream(struct XorrisO *xorriso, void *in_node, char *path, int flag)
Definition: iso_tree.c:2394
int Xorriso_ls(struct XorrisO *xorriso, int flag)
Definition: iso_tree.c:1903
int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node, int *node_idx, int *min_hl, int *max_hl, int flag)
Definition: iso_tree.c:2601
int Xorriso_getfattr(struct XorrisO *xorriso, void *in_node, char *path, char **attr_text, int flag)
Definition: iso_tree.c:824
int Xorriso_file_eval_damage(struct XorrisO *xorriso, IsoNode *node, off_t *damage_start, off_t *damage_end, int flag)
Definition: iso_tree.c:2477
int Xorriso_node_get_dev(struct XorrisO *xorriso, IsoNode *node, char *path, dev_t *dev, int flag)
Definition: iso_tree.c:229
int Xorriso__start_end_lbas(IsoNode *node, int *lba_count, int **start_lbas, int **end_lbas, off_t **section_sizes, off_t *size, int flag)
Definition: iso_tree.c:2210
int Xorriso_node_is_valid(struct XorrisO *xorriso, IsoNode *in_node, int flag)
Definition: iso_tree.c:384
int Xorriso_is_split(struct XorrisO *xorriso, char *path, void *node, int flag)
Definition: iso_tree.c:633
int Xorriso_get_attrs(struct XorrisO *xorriso, void *in_node, char *path, size_t *num_attrs, char ***names, size_t **value_lengths, char ***values, int flag)
Definition: iso_tree.c:1188
int Xorriso_get_node_by_path(struct XorrisO *xorriso, char *in_path, char *eff_path, IsoNode **node, int flag)
Definition: iso_tree.c:199
int Xorriso_local_getfacl(struct XorrisO *xorriso, char *disk_path, char **text, int flag)
Definition: iso_tree.c:1125
int Xorriso_normalize_img_path(struct XorrisO *xorriso, char *wd, char *img_path, char eff_path[], int flag)
Definition: iso_tree.c:55
int Xorriso_path_from_lba(struct XorrisO *xorriso, IsoNode *node, int lba, char path[4096], int flag)
Definition: iso_tree.c:459
int Xorriso_stream_type(struct XorrisO *xorriso, IsoNode *node, IsoStream *stream, char type_text[], int flag)
Definition: iso_tree.c:1296
int Xorriso_expand_pattern(struct XorrisO *xorriso, int num_patterns, char **patterns, int extra_filec, int *filec, char ***filev, off_t *mem, int flag)
Definition: iso_tree.c:2091
#define LIBISO_ISREG(node)
Definition: iso_tree.h:18
#define LIBISO_ISDIR(node)
Definition: iso_tree.h:17
#define LIBISO_ISBOOT(node)
Definition: iso_tree.h:28
#define LIBISO_ISBLK(node)
Definition: iso_tree.h:22
#define LIBISO_ISCHR(node)
Definition: iso_tree.h:20
#define LIBISO_ISSOCK(node)
Definition: iso_tree.h:26
#define LIBISO_ISFIFO(node)
Definition: iso_tree.h:24
#define LIBISO_ISLNK(node)
Definition: iso_tree.h:19
int Xorriso_report_iso_error(struct XorrisO *xorriso, char *victim, int iso_error_code, char msg_text[], int os_errno, char min_severity[], int flag)
Definition: lib_mgt.c:430
int Xorriso_process_msg_queues(struct XorrisO *xorriso, int flag)
Forward any pending messages from the library message queues to the xorriso message system which puts...
Definition: lib_mgt.c:519
int Xorriso_register_matched_adr(struct XorrisO *xorriso, char *adr, int count_limit, int *filec, char **filev, off_t *mem, int flag)
Definition: match.c:396
int Xorriso_no_pattern_memory(struct XorrisO *xorriso, off_t mem, int flag)
Definition: match.c:596
int Xorriso_check_matchcount(struct XorrisO *xorriso, int count, int nonconst_mismatches, int num_patterns, char **patterns, int flag)
Definition: match.c:574
int Xorriso_check_for_root_pattern(struct XorrisO *xorriso, int *filec, char **filev, int count_limit, off_t *mem, int flag)
Definition: match.c:364
int Xorriso_regexec(struct XorrisO *xorriso, char *to_match, int *failed_at, int flag)
Definition: match.c:225
int Xorriso_alloc_pattern_mem(struct XorrisO *xorriso, off_t mem, int count, char ***filev, int flag)
Definition: match.c:609
int Xorriso_prepare_expansion_pattern(struct XorrisO *xorriso, char *pattern, int flag)
Definition: match.c:339
int Xorriso_eval_nonmatch(struct XorrisO *xorriso, char *pattern, int *nonconst_mismatches, off_t *mem, int flag)
Definition: match.c:548
int Sort_argv(int argc, char **argv, int flag)
Definition: misc_funct.c:40
char * Text_shellsafe(char *in_text, char *out_text, int flag)
Definition: misc_funct.c:1044
int Xorriso_make_abs_adr(struct XorrisO *xorriso, char *wd, char *name, char adr[], int flag)
Definition: parse_exec.c:2812
int Xorriso_check_temp_mem_limit(struct XorrisO *xorriso, off_t mem, int flag)
Definition: parse_exec.c:2896
int Sfile_bsl_encoder(char **result, char *text, size_t text_len, int flag)
Definition: sfile.c:562
int Sfile_type(char *filename, int flag)
Definition: sfile.c:225
int Sfile_add_to_path(char path[4096], char *addon, int flag)
Definition: sfile.c:137
int Sfile_str(char target[4096], char *source, int flag)
Definition: sfile.c:836
#define Xorriso_free_meM(pt)
Definition: sfile.h:27
#define Xorriso_alloc_meM(pt, typ, count)
Definition: sfile.h:19
int Xorriso_sorted_node_array(struct XorrisO *xorriso, IsoDir *dir_node, int *nodec, IsoNode ***node_array, off_t boss_mem, int flag)
Definition: sort_cmp.c:337
int Xorriso__findi_sorted_ino_cmp(const void *p1, const void *p2)
Definition: sort_cmp.c:34
int Xorriso_search_in_hln_array(struct XorrisO *xorriso, void *node, int *idx, int flag)
Definition: sort_cmp.c:132
unsigned char * map
Definition: check_media.h:58
off_t pacifier_count
void ** hln_array
int bsl_interpretation
int structured_search
off_t split_size
off_t pacifier_byte_count
int do_follow_links
int ino_behavior
char result_line[10 *4096]
int sh_style_result
struct SectorbitmaP * in_sector_map
char info_text[10 *4096]
void ** hln_targets
int file_name_limit
int request_to_abort
void ** node_array
int node_counter
int do_follow_param
char wdi[4096]
int Xorriso_msgs_submit(struct XorrisO *xorriso, int error_code, char msg_text[], int os_errno, char severity[], int flag)
Submit a problem message to the xorriso problem reporting and handling system.
Definition: text_io.c:2504
int Xorriso_no_findjob(struct XorrisO *xorriso, char *cmd, int flag)
Definition: text_io.c:4110
int Xorriso_pacifier_callback(struct XorrisO *xorriso, char *what_done, off_t count, off_t todo, char *current_object, int flag)
Definition: text_io.c:3969
int Xorriso_no_malloc_memory(struct XorrisO *xorriso, char **to_free, int flag)
Definition: text_io.c:4077
int Xorriso_info(struct XorrisO *xorriso, int flag)
Definition: text_io.c:2367
char * Xorriso_esc_filepath(struct XorrisO *xorriso, char *in_text, char *out_text, int flag)
Definition: text_io.c:4742
int Xorriso_much_too_long(struct XorrisO *xorriso, int len, int flag)
Definition: text_io.c:4097
int Xorriso_result(struct XorrisO *xorriso, int flag)
Definition: text_io.c:2337
#define Xorriso_IFBOOT
Definition: xorrisoburn.h:573