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

iso_manip.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 manipulate the libisofs tree model.
9 */
10 
11 #ifdef HAVE_CONFIG_H
12 #include "../config.h"
13 #endif
14 
15 #include <ctype.h>
16 #include <sys/types.h>
17 #include <unistd.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <sys/stat.h>
22 #include <sys/time.h>
23 #include <time.h>
24 #include <errno.h>
25 
26 
27 #include "xorriso.h"
28 #include "xorriso_private.h"
29 #include "xorrisoburn.h"
30 
31 #include "lib_mgt.h"
32 #include "iso_img.h"
33 #include "iso_tree.h"
34 #include "iso_img.h"
35 #include "iso_manip.h"
36 #include "sort_cmp.h"
37 #include "parse_exec.h"
38 #include "write_run.h"
39 
40 
41 
42 /* @param flag bit0= give directory x-permission where is r-permission
43  bit1= do not transfer ACL or xattr
44  bit2= record dev,inode (only if enabled by xorriso)
45  bit3= with bit0: pretend to have indeed a directory
46  bit5= transfer ACL or xattr from eventual link target
47 */
48 int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf,
49  char *disk_path, IsoNode *node, int flag)
50 {
51  mode_t mode;
52  int ret= 1;
53  size_t num_attrs= 0, *value_lengths= NULL;
54  char **names= NULL, **values= NULL;
55 
56  mode= stbuf->st_mode;
57 
58  if((!(flag & 2)) && !(xorriso->do_aaip & 1))
59  /* Will drop ACL. Update mode S_IRWXG by eventual group:: ACL entry */
60  iso_local_get_perms_wo_acl(disk_path, &mode, flag & 32);
61 
62  if((flag & 1) && ((flag & 8) || S_ISDIR(mode))) {
63  if(mode&S_IRUSR)
64  mode|= S_IXUSR;
65  if(mode&S_IRGRP)
66  mode|= S_IXGRP;
67  if(mode&S_IROTH)
68  mode|= S_IXOTH;
69  }
70  iso_node_set_permissions(node, mode & 07777);
71  iso_node_set_uid(node, stbuf->st_uid);
72  iso_node_set_gid(node, stbuf->st_gid);
73  iso_node_set_atime(node, stbuf->st_atime);
74  iso_node_set_mtime(node, stbuf->st_mtime);
75  iso_node_set_ctime(node, stbuf->st_ctime);
76 
77  if((xorriso->do_aaip & 5) && !(flag & 2)) {
78  ret= iso_local_get_attrs(disk_path, &num_attrs, &names, &value_lengths,
79  &values, ((xorriso->do_aaip & 1) && !(flag & 2))
80  | ((!(xorriso->do_aaip & 4)) << 2)
81  | (flag & 32));
82  if(ret < 0) {
83  Xorriso_process_msg_queues(xorriso,0);
84  Xorriso_report_iso_error(xorriso, disk_path, ret,
85  "Error when obtaining local ACL and xattr", 0,
86  "FAILURE", 1 | 2);
87  ret= 0; goto ex;
88  }
89 
90  /* Preserve namespace isofs, but not ACL or system xattr */
91  ret= iso_node_set_attrs(node, num_attrs, names, value_lengths, values,
92  1 | 8 | 16);
93  if(ret < 0) {
94  Xorriso_process_msg_queues(xorriso,0);
95  Xorriso_report_iso_error(xorriso, "", ret,
96  "Error when setting ACL and xattr to image node",
97  0, "FAILURE", 1);
98  ret= 0; goto ex;
99  }
100  }
101 
102  if((flag & 4) && ((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2))) {
103  ret= Xorriso_record_dev_inode(xorriso, disk_path, (dev_t) 0, (ino_t) 0,
104  (void *) node, "", flag & 32);
105  if(ret <= 0)
106  goto ex;
107  }
108 
109  ret= 1;
110 ex:;
111  Xorriso_process_msg_queues(xorriso,0);
112  iso_local_get_attrs(disk_path, &num_attrs, &names, &value_lengths,
113  &values, 1 << 15); /* free memory */
114  return(ret);
115 }
116 
117 
118 int Xorriso_graft_split(struct XorrisO *xorriso, IsoImage *volume,
119  IsoDir *dir, char *disk_path, char *img_name,
120  char *nominal_source, char *nominal_target,
121  off_t size, IsoNode **node, int flag)
122 {
123  int ret;
124  IsoDir *new_dir= NULL;
125  IsoNode *part_node;
126  int partno, total_parts;
127  off_t offset;
128  char *part_name= NULL;
129 
130  Xorriso_alloc_meM(part_name, char, SfileadrL);
131 
132  ret= iso_image_add_new_dir(volume, dir, img_name, &new_dir);
133  if(ret < 0)
134  goto ex;
135  *node= (IsoNode *) new_dir;
136  if(xorriso->update_flags & 1) {
137  ret= Xorriso_mark_update_merge(xorriso, img_name, node, 1);
138  if(ret <= 0)
139  {ret= 0; goto ex;}
140  }
141  total_parts= size / xorriso->split_size;
142  if(size % xorriso->split_size)
143  total_parts++;
144  for(partno= 1; partno<=total_parts; partno++) {
145  offset = xorriso->split_size * (off_t) (partno-1);
146  Splitpart__compose(part_name, partno, total_parts, offset,
147  xorriso->split_size, size, 0);
148  ret= Xorriso_tree_graft_node(xorriso, volume,
149  new_dir, disk_path, part_name,
150  nominal_source, nominal_target,
151  offset, xorriso->split_size,
152  &part_node, 8);
153  if(ret<=0)
154  goto ex;
155  }
156  sprintf(xorriso->info_text, "Split into %d parts: ", total_parts);
157  Text_shellsafe(nominal_target, xorriso->info_text, 1);
158  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
159  ret= 1;
160 ex:;
161  Xorriso_free_meM(part_name);
162  return(ret);
163 }
164 
165 
166 /*
167  @param flag bit0= ISO_NODE_NAME_NOT_UNIQUE exception mode:
168  Do not issue message. Return existing node into *node.
169  bit1= if name truncation happens: copy truncated into img_name
170  bit3= cut_out_node: offset and size are valid
171  bit8= hide in iso_rr
172  bit9= hide in joliet
173  bit10= hide in hfsplus
174 */
175 int Xorriso_tree_graft_node(struct XorrisO *xorriso, IsoImage *volume,
176  IsoDir *dir, char *disk_path, char *img_name,
177  char *nominal_source, char *nominal_target,
178  off_t offset, off_t cut_size,
179  IsoNode **node, int flag)
180 {
181  int ret, stbuf_valid= 0;
182  struct stat stbuf;
183  char *namept, *eff_name, *trunc_name= NULL;
184  off_t size= 0;
185 
186  eff_name= img_name;
187  if(lstat(disk_path, &stbuf) != -1) {
188  stbuf_valid= 1;
189  if(S_ISREG(stbuf.st_mode))
190  size= stbuf.st_size;
191  }
192  if((int) strlen(eff_name) > xorriso->file_name_limit) {
193  Xorriso_alloc_meM(trunc_name, char, SfileadrL);
194  strncpy(trunc_name, eff_name, SfileadrL - 1);
195  trunc_name[SfileadrL - 1]= 0;
196  ret= iso_truncate_leaf_name(1, xorriso->file_name_limit, trunc_name, 0);
197  if(ret < 0)
198  goto ex;
199  strcpy(xorriso->info_text, "File name had to be truncated and MD5 marked: ");
200  Text_shellsafe(eff_name, xorriso->info_text, 1);
201  strcat(xorriso->info_text, " -> ");
202  Text_shellsafe(trunc_name, xorriso->info_text, 1);
203  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
204  eff_name= trunc_name;
205  if(flag & 2)
206  strcpy(img_name, trunc_name);
207  }
208  if(flag&8) {
209  if(cut_size > xorriso->file_size_limit && xorriso->file_size_limit > 0) {
210  sprintf(xorriso->info_text,
211  "File piece exceeds size limit of %.f bytes: %.f from ",
212  (double) xorriso->file_size_limit, (double) cut_size);
213  Text_shellsafe(disk_path, xorriso->info_text, 1);
214  strcat(xorriso->info_text, "\n");
215  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
216  return(0);
217  }
218  ret= iso_tree_add_new_cut_out_node(volume, dir, eff_name, disk_path,
219  offset, cut_size, node);
220  if(ret<0)
221  goto ex;
222  } else {
223  if(xorriso->split_size > 0 && size > xorriso->split_size) {
224  ret= Xorriso_graft_split(xorriso, volume, dir, disk_path, eff_name,
225  nominal_source, nominal_target, size,
226  node, 0);
227  if(ret<=0)
228  goto ex;
229  } else if(size > xorriso->file_size_limit && xorriso->file_size_limit > 0) {
230  sprintf(xorriso->info_text,
231  "File exceeds size limit of %.f bytes: ",
232  (double) xorriso->file_size_limit);
233  Text_shellsafe(disk_path, xorriso->info_text, 1);
234  strcat(xorriso->info_text, "\n");
235  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
236  return(0);
237  } else {
238  ret= iso_tree_add_new_node(volume, dir, eff_name, disk_path, node);
239  if(ret<0)
240  goto ex;
241  }
242  }
243  if(flag & (256 | 512 | 1024)) {
244  ret= Xorriso_set_hidden(xorriso, (void *) *node, "", (flag >> 8) & 7, 0);
245  if(ret <= 0)
246  goto ex;
247  }
248  if(stbuf_valid && ((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2))) {
249  ret= Xorriso_record_dev_inode(xorriso, disk_path,
250  stbuf.st_dev, stbuf.st_ino, (void *) *node, "", 1);
251  if(ret <= 0)
252  goto ex;
253  }
254  if(xorriso->update_flags & 1) {
255  ret= Xorriso_mark_update_merge(xorriso, eff_name, *node, 1);
256  if(ret <= 0)
257  goto ex;
258  }
259 
260 ex:;
261  if(ret<0) {
262  if(ret == (int) ISO_NODE_NAME_NOT_UNIQUE && (flag & 1)) {
263  iso_image_dir_get_node(volume, dir, eff_name, node, 0);
264  } else {
265  Xorriso_process_msg_queues(xorriso,0);
266  if(ret == (int) ISO_RR_NAME_TOO_LONG ||
267  ret == (int) ISO_RR_NAME_RESERVED ||
268  ret == (int) ISO_RR_PATH_TOO_LONG)
269  namept= nominal_target;
270  else
271  namept= nominal_source;
272  Xorriso_report_iso_error(xorriso, namept, ret,
273  "Cannot add node to tree", 0, "FAILURE", 1|2);
274  }
275  } else {
276  if(LIBISO_ISREG(*node))
277  xorriso->pacifier_byte_count+= iso_file_get_size((IsoFile *) *node);
278  ret= 1;
279  }
280  Xorriso_free_meM(trunc_name);
281  return(ret);
282 }
283 
284 
285 /*
286  @param boss_iter Opaque handle to be forwarded to actions in ISO image
287  Set to NULL if calling this function without having
288  a boss iterator object.
289  @param node Pointer to pointer to existing node,
290  *node is set to NULL, if the node gets removed.
291  @param flag bit0= source is directory
292  bit4= return 3 on rejection by exclusion or user
293  bit6= do not delete eventually existing node from di_array
294  bit7= no special handling of split file directories
295  @return 1= no action was needed, 2= target removed,
296  3= rejected with bit4, <=0 means error
297 */
298 int Xoriso_handle_collision(struct XorrisO *xorriso, void *boss_iter,
299  IsoNode **node, char *img_path,
300  char *full_img_path, char *disk_path,
301  char *show_path, int flag)
302 {
303  int ret, target_is_dir, target_is_split, source_is_dir;
304 
305  source_is_dir= flag & 1;
306  target_is_dir= LIBISO_ISDIR(*node);
307 
308  target_is_split= 0;
309  if(target_is_dir && !(flag & 128))
310  target_is_split= Xorriso_is_split(xorriso, "", (void *) *node, 1 | 2);
311 
312  if(!((target_is_dir && !target_is_split) && source_is_dir)) {
313  Xorriso_process_msg_queues(xorriso, 0);
314 
315  /* handle overwrite situation */;
316  if(xorriso->do_overwrite == 1 ||
317  (xorriso->do_overwrite == 2 && !(target_is_dir && !target_is_split))) {
318  ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, img_path,
319  1 | 8 | (flag & 64));
320  if(ret <= 0)
321  return(ret);
322  if(ret == 3) {
323  sprintf(xorriso->info_text, "User revoked adding of: ");
324  Text_shellsafe(show_path, xorriso->info_text, 1);
325  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
326  return(3 * !!(flag & 16));
327  }
328  *node= NULL;
329  return(2);
330  }
331 
332  if (disk_path[0])
333  Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
334  if(strcmp(full_img_path, img_path) == 0)
335  sprintf(xorriso->info_text,
336  "While grafting '%s' : file object exists and may not be overwritten",
337  img_path);
338  else
339  sprintf(xorriso->info_text,
340  "While grafting '%s' : '%s' exists and may not be overwritten",
341  full_img_path, img_path);
342  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
343  return(0);
344  }
345  return(1);
346 }
347 
348 
349 /* @param flag bit0= recursion is active
350  bit1= do not report added files
351  bit6= do not delete eventually existing node from di_array
352  bit7= no special handling of split file directories
353  bit8= hide in iso_rr
354  bit9= hide in joliet
355 */
356 int Xorriso_add_tree(struct XorrisO *xorriso, IsoDir *dir,
357  char *img_dir_path, char *disk_dir_path,
358  struct LinkiteM *link_stack, int flag)
359 {
360  IsoImage *volume;
361  IsoNode *node;
362  int ret, source_is_dir, source_is_link, fret, was_failure= 0;
363  int do_not_dive, hide_attrs;
364  struct DirseQ *dirseq= NULL;
365  char *name, *img_name, *srcpt, *stbuf_src= "";
366  struct stat stbuf, hstbuf;
367  dev_t dir_dev;
368  struct LinkiteM *own_link_stack = NULL;
369  char *sfe= NULL, *sfe2= NULL;
370  char *disk_path= NULL, *img_path= NULL, *link_target= NULL;
371 
372 #define Xorriso_add_handle_collisioN 1
373 #define Xorriso_optimistic_add_treE 1
374 
375 #ifndef Xorriso_optimistic_add_treE
376 #ifndef Xorriso_add_handle_collisioN
377  int target_is_split= 0, target_is_dir;
378 #endif
379 #endif
380 
381  /* Avoiding large local memory objects in order to save stack space */
382  sfe= malloc(5*SfileadrL);
383  sfe2= malloc(5*SfileadrL);
384  disk_path= malloc(2*SfileadrL);
385  img_path= malloc(2*SfileadrL);
386  link_target= calloc(SfileadrL, 1);
387  if(sfe==NULL || sfe2==NULL || disk_path==NULL || img_path==NULL ||
388  link_target==NULL) {
389  Xorriso_no_malloc_memory(xorriso, &sfe, 0);
390  {ret= -1; goto ex;}
391  }
392 
393  own_link_stack= link_stack;
394 
395  ret= Xorriso_get_volume(xorriso, &volume, 0);
396  if(ret<=0)
397  goto ex;
398 
399  stbuf_src= disk_dir_path;
400  if(lstat(disk_dir_path, &stbuf)==-1)
401  goto cannot_open_dir;
402  dir_dev= stbuf.st_dev;
403  if(S_ISLNK(stbuf.st_mode)) {
404  if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1))))
405  {ret= 2; goto ex;}
406  stbuf_src= disk_dir_path;
407  if(stat(disk_dir_path, &stbuf)==-1)
408  goto cannot_open_dir;
409  if(dir_dev != stbuf.st_dev &&
410  !(xorriso->do_follow_mount || (xorriso->do_follow_param && !(flag&1))))
411  {ret= 2; goto ex;}
412  }
413  ret= Dirseq_new(&dirseq, disk_dir_path, 1);
414  if(ret<0) {
415  sprintf(xorriso->info_text,"Failed to create source filesystem iterator");
416  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
417  {ret= -1; goto ex;}
418  }
419  if(ret==0) {
420 cannot_open_dir:;
421  Xorriso_msgs_submit(xorriso, 0, disk_dir_path, 0, "ERRFILE", 0);
422  sprintf(xorriso->info_text,"Cannot open as source directory: %s",
423  Text_shellsafe(disk_dir_path, sfe, 0));
424  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
425  {ret= 0; goto ex;}
426  }
427 
428  if(Sfile_str(disk_path, disk_dir_path,0)<=0)
429  {ret= -1; goto ex;}
430  if(disk_path[0]==0 || disk_path[strlen(disk_path)-1]!='/')
431  strcat(disk_path,"/");
432  name= disk_path+strlen(disk_path);
433  if(Sfile_str(img_path, img_dir_path, 0)<=0)
434  {ret= -1; goto ex;}
435  if(img_path[0] == 0)
436  strcat(img_path, "/");
437  else if(img_path[strlen(img_path) - 1] != '/')
438  strcat(img_path, "/");
439  img_name= img_path+strlen(img_path);
440 
441  while(1) { /* loop over directory content */
442  stbuf_src= "";
443  Linkitem_reset_stack(&own_link_stack, link_stack, 0);
444  srcpt= disk_path;
445  Xorriso_process_msg_queues(xorriso,0);
446  ret= Dirseq_next_adr(dirseq,name,0); /* name is a pointer into disk_path */
447  if(ret==0)
448  break;
449  if(ret<0) {
450  sprintf(xorriso->info_text,"Failed to obtain next directory entry");
451  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
452  {ret= -1; goto ex;}
453  }
454 
455  /* Compare exclusions against disk_path resp. name */
456  ret= Xorriso_path_is_excluded(xorriso, disk_path, 0); /* (is never param) */
457  if(ret<0)
458  {ret= -1; goto ex;}
459  if(ret>0)
460  continue;
461  /* Check for mkisofs-style hidings */
462  hide_attrs= (flag >> 8) & 3;
463  if(hide_attrs != 3) {
464  ret= Xorriso_path_is_hidden(xorriso, disk_path, 0);
465  if(ret<0)
466  goto ex;
467  if(ret>=0)
468  hide_attrs|= ret;
469  }
470 
471  strcpy(img_name, name);
472  if(Xorriso_much_too_long(xorriso, strlen(img_path), 0)<=0)
473  {ret= 0; goto was_problem;}
474  if(Xorriso_much_too_long(xorriso, strlen(srcpt), 0)<=0)
475  {ret= 0; goto was_problem;}
476  stbuf_src= srcpt;
477  if(lstat(srcpt, &stbuf)==-1) {
478 cannot_lstat:;
479  Xorriso_msgs_submit(xorriso, 0, srcpt, 0, "ERRFILE", 0);
480  sprintf(xorriso->info_text,
481  "Cannot determine attributes of source file %s",
482  Text_shellsafe(srcpt, sfe, 0));
483  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
484  ret= 0; goto was_problem;
485  }
486  source_is_dir= 0;
487  source_is_link= S_ISLNK(stbuf.st_mode);
488  if(xorriso->do_follow_links && source_is_link) {
489  /* Xorriso_hop_link checks for wide link loops */
490  ret= Xorriso_hop_link(xorriso, srcpt, &own_link_stack, &hstbuf, 0);
491  if(ret<0)
492  goto was_problem;
493  if(ret==1) {
494  ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 0);
495  if(ret<=0)
496  goto was_problem;
497  srcpt= link_target;
498  stbuf_src= srcpt;
499  if(lstat(srcpt, &stbuf)==-1)
500  goto cannot_lstat;
501  } else {
502  if(Xorriso_eval_problem_status(xorriso, 0, 1|2)<0)
503  {ret= 0; goto was_problem;}
504  ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1);
505  if(ret<=0)
506  goto was_problem;
507  }
508  } else if (S_ISLNK(stbuf.st_mode)) {
509  ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1);
510  if(ret<=0)
511  goto was_problem;
512  }
513  do_not_dive= 0;
514  if(S_ISDIR(stbuf.st_mode)) {
515  source_is_dir= 1;
516  if(dir_dev != stbuf.st_dev && !xorriso->do_follow_mount)
517  do_not_dive= 1;
518  }
519 
520 #ifdef Xorriso_optimistic_add_treE
521 
522  ret= Xorriso_tree_graft_node(xorriso, volume, dir, srcpt, img_name,
523  "", img_path, (off_t) 0, (off_t) 0,
524  &node, 1 | (hide_attrs << 8));
525  if(ret == (int) ISO_NODE_NAME_NOT_UNIQUE) {
526  ret= Xoriso_handle_collision(xorriso, NULL, &node, img_path, img_path,
527  srcpt, img_path,
528  (!!source_is_dir) | (flag & (64 | 128)));
529  if(ret <= 0)
530  goto was_problem;
531  if(node == NULL) {
532  ret= Xorriso_tree_graft_node(xorriso, volume, dir, srcpt, img_name,
533  "", img_path, (off_t) 0, (off_t) 0,
534  &node, (hide_attrs << 8));
535  if(ret <= 0)
536  node= NULL;
537  }
538  }
539 
540 #else /* Xorriso_optimistic_add_treE */
541 
542  /* does a node exist with this name ? */
543  node= NULL;
544  if(dir != NULL) {
545  ret= iso_image_get_dir_node(volume, dir, img_name, &node);
546  } else {
547  ret= Xorriso_node_from_path(xorriso, volume, img_path, &node, 1);
548  }
549  if(ret>0) {
550  target_is_dir= LIBISO_ISDIR(node);
551  target_is_split= 0;
552  if(target_is_dir && !(flag & 128))
553  target_is_split= Xorriso_is_split(xorriso, "", (void *) node, 1 | 2);
554 
555  if(!((target_is_dir && !target_is_split) && source_is_dir)) {
556  Xorriso_process_msg_queues(xorriso,0);
557 
558  /* handle overwrite situation */;
559  if(xorriso->do_overwrite==1 ||
560  (xorriso->do_overwrite==2 && !(target_is_dir && !target_is_split))) {
561  ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, img_path,
562  1 | 8 | (flag & 64));
563  if(ret<=0)
564  goto was_problem;
565  if(ret==3) {
566  sprintf(xorriso->info_text, "User revoked adding of: %s",
567  Text_shellsafe(img_path, sfe, 0));
568  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
569  ret= 0; goto was_problem;
570  }
571  node= NULL;
572  } else {
573  Xorriso_msgs_submit(xorriso, 0, srcpt, 0, "ERRFILE", 0);
574  sprintf(xorriso->info_text,
575  "While grafting %s : file object exists and may not be overwritten by %s",
576  Text_shellsafe(img_path,sfe,0), Text_shellsafe(stbuf_src,sfe2,0));
577  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
578  ret= 0; goto was_problem;
579  }
580  }
581  }
582 
583  if(node==NULL) {
584  ret= Xorriso_tree_graft_node(xorriso, volume, dir, srcpt, img_name,
585  "", img_path, (off_t) 0, (off_t) 0,
586  &node, (hide_attrs << 8));
587  }
588 
589 #endif /* Xorriso_optimistic_add_treE */
590 
591  if(node==NULL) {
592  Xorriso_process_msg_queues(xorriso,0);
593  Xorriso_msgs_submit(xorriso, 0, stbuf_src, 0, "ERRFILE", 0);
594  sprintf(xorriso->info_text, "Grafting failed: %s = %s",
595  Text_shellsafe(img_path,sfe,0), Text_shellsafe(stbuf_src,sfe2,0));
596  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
597  ret= 0; goto was_problem;
598  }
599 
600  xorriso->pacifier_count++;
601  if((xorriso->pacifier_count%100)==0)
602  Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count,
603  xorriso->pacifier_total, "", 0);
604 
605  Xorriso_set_change_pending(xorriso, 0);
606  if(source_is_dir) {
607  if(do_not_dive) {
608  sprintf(xorriso->info_text, "Did not follow mount point : %s",
609  Text_shellsafe(disk_path, sfe, 0));
610  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
611  } else {
612  ret= Xorriso_add_tree(xorriso, (IsoDir *) node,
613  img_path, disk_path, own_link_stack,
614  1 | (flag & (2 | 64 | 128)));
615  }
616  if(ret<=0)
617  goto was_problem;
618  }
619 
620  continue; /* regular bottom of loop */
621 was_problem:;
622  was_failure= 1;
623  fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
624  if(fret<0)
625  goto ex;
626  }
627 
628  ret= 1;
629 ex:
630  if(sfe!=NULL)
631  free(sfe);
632  if(sfe2!=NULL)
633  free(sfe2);
634  if(disk_path!=NULL)
635  free(disk_path);
636  if(img_path!=NULL)
637  free(img_path);
638  if(link_target!=NULL)
639  free(link_target);
640  Xorriso_process_msg_queues(xorriso,0);
641  Linkitem_reset_stack(&own_link_stack, link_stack, 0);
642  Dirseq_destroy(&dirseq, 0);
643  if(ret<=0)
644  return(ret);
645  return(!was_failure);
646 }
647 
648 
649 /* @param flag bit0= cut_out mode : base on leaf parent directory
650  bit1= do not check and perform hidings
651 */
653  char *full_img_path, char *img_path, char *full_disk_path, int flag)
654 {
655  int ret, nfic, nic, nfdc, d, i;
656  char *nfi= NULL, *ni= NULL, *nfd= NULL, *cpt;
657  struct stat stbuf;
658 
659  Xorriso_alloc_meM(nfi, char, SfileadrL);
660  Xorriso_alloc_meM(ni, char, SfileadrL);
661  Xorriso_alloc_meM(nfd, char, SfileadrL);
662 
663  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, full_img_path, nfi,
664  1|2);
665  if(ret<=0)
666  goto ex;
667  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, img_path, ni, 1|2);
668  if(ret<=0)
669  goto ex;
670  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, full_disk_path, nfd,
671  1|2|4);
672  if(ret<=0)
673  goto ex;
674  nfic= Sfile_count_components(nfi, 0);
675  nic= Sfile_count_components(ni, 0);
676  nfdc= Sfile_count_components(nfd, 0);
677  d= nfic-(flag&1)-nic;
678  if(d<0)
679  {ret= -1; goto ex;}
680  if(d>nfdc)
681  {ret= 0; goto ex;}
682  for(i= 0; i<d; i++) {
683  cpt= strrchr(nfd, '/');
684  if(cpt==NULL)
685  {ret= -1; goto ex;} /* should not happen */
686  *cpt= 0;
687  }
688  if(nfd[0]==0)
689  strcpy(nfd, "/");
690  if(stat(nfd, &stbuf)==-1)
691  {ret= 0; goto ex;}
692  Xorriso_transfer_properties(xorriso, &stbuf, nfd, (IsoNode *) dir,
693  ((8 | 1) * ((flag&1) && d==0)) | 4 | 32);
694  sprintf(xorriso->info_text, "Copied properties for ");
695  Text_shellsafe(ni, xorriso->info_text, 1);
696  sprintf(xorriso->info_text+strlen(xorriso->info_text), " from ");
697  Text_shellsafe(nfd, xorriso->info_text, 1);
698  if(!((flag&1) && d==0))
699  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
700 
701  if(!(flag & 2)) {
702  /* Check for mkisofs-style hidings */
703  ret= Xorriso_path_is_hidden(xorriso, nfd, 0);
704  if(ret<0)
705  goto ex;
706  if(ret>=0) {
707  /* Hide dir */
708  ret= Xorriso_set_hidden(xorriso, (void *) dir, "", ret, 0);
709  if(ret <= 0)
710  goto ex;
711  }
712  }
713  ret= 1;
714 ex:
715  Xorriso_free_meM(nfi);
716  Xorriso_free_meM(ni);
717  Xorriso_free_meM(nfd);
718  return(ret);
719 }
720 
721 
722 /* @param bit0= copy link target properties rather than link properties
723  bit1= give directory x-permission where is r-permission
724  bit2= record dev,inode (only if enabled by xorriso)
725 */
726 int Xorriso_copy_properties(struct XorrisO *xorriso,
727  char *disk_path, char *img_path, int flag)
728 {
729  int ret;
730  IsoNode *node;
731  struct stat stbuf;
732 
733  ret= Xorriso_get_node_by_path(xorriso, img_path, NULL, &node, 0);
734  if(ret<=0)
735  return(ret);
736  if(flag & 1) {
737  if(stat(disk_path, &stbuf)==-1)
738  return(0);
739  } else {
740  if(lstat(disk_path, &stbuf)==-1)
741  return(0);
742  }
743  Xorriso_transfer_properties(xorriso, &stbuf, disk_path, node,
744  ((flag & 2) >> 1) | ((flag & 1) << 5) | (flag & 4));
745  Xorriso_set_change_pending(xorriso, 0);
746  return(1);
747 }
748 
749 
750 int Xorriso_add_symlink(struct XorrisO *xorriso, IsoDir *parent,
751  char *link_target, char *leaf_name,
752  char *nominal_path, int flag)
753 {
754  int ret= 0;
755  IsoSymlink *link= NULL;
756  IsoImage *volume;
757 
758  ret= Xorriso_get_volume(xorriso, &volume, 0);
759  if(ret <= 0)
760  return(ret);
761  ret= iso_image_add_new_symlink(volume, parent, leaf_name, link_target, &link);
762  Xorriso_process_msg_queues(xorriso,0);
763  if(ret < 0) {
764  Xorriso_report_iso_error(xorriso, nominal_path, ret,
765  "Cannot create symbolic link", 0, "FATAL", 1);
766  ret= 0;
767  }
768  return(ret);
769 }
770 
771 
772 /* @param boss_iter Opaque handle to be forwarded to actions in ISO image
773  Set to NULL if calling this function from outside ISO world
774  @param flag bit0= mkdir: graft in as empty directory, not as copy from disk
775  bit1= do not report added files
776  bit2= -follow, -not_*: this is not a command parameter
777  bit3= use offset and cut_size for cut_out_node
778  bit4= return 3 on rejection by exclusion or user
779  bit5= if directory then do not add sub tree
780  bit6= do not delete eventually existing node from di_array
781  bit7= no special handling of split file directories
782  bit8= hide in iso_rr
783  bit9= hide in joliet
784  bit10= ln -s: graft in as symbolic link.
785  Link target is handed over in parameter disk_path.
786  @return <=0 = error , 1 = added simple node , 2 = added directory ,
787  3 = rejected
788 */
789 int Xorriso_graft_in(struct XorrisO *xorriso, void *boss_iter,
790  char *disk_path, char *img_path,
791  off_t offset, off_t cut_size, int flag)
792 {
793  IsoImage *volume;
794  char *path= NULL, *apt, *npt, *cpt;
795  char *disk_path_pt, *resolved_disk_path= NULL;
796  IsoDir *dir= NULL, *hdir;
797  IsoNode *node;
798  int done= 0, is_dir= 0, l, ret, source_is_dir, resolve_link= 0;
799  int hide_attrs;
800  struct stat stbuf;
801 
802 #define Xorriso_graft_handle_collisioN 1
803 #define Xorriso_optimistic_graft_iN 1
804 
805 #ifndef Xorriso_optimistic_graft_iN
806 #ifndef Xorriso_graft_handle_collisioN
807  int target_is_split, target_is_dir;
808 #endif
809 #endif
810 
811  Xorriso_alloc_meM(path, char, SfileadrL);
812  Xorriso_alloc_meM(resolved_disk_path, char, SfileadrL);
813 
814  hide_attrs= (flag >> 8) & 3;
815  if (disk_path == NULL && !(flag & 1)) {
816  Xorriso_msgs_submit(xorriso, 0,
817  "Program error: Xorriso_graft_in(): disk_path == NULL && !(flag & 1)",
818  0, "ABORT", 0);
819  {ret= -1; goto ex;}
820  }
821  if (disk_path == NULL) {
822  disk_path= "";
823  } else {
824  ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&4));
825  if(ret<0)
826  goto ex;
827  if(ret>0)
828  {ret= 3*!!(flag&16); goto ex;}
829 
830  /* Check for mkisofs-style hidings */
831  if(hide_attrs != 3) {
832  ret= Xorriso_path_is_hidden(xorriso, disk_path, 0);
833  if(ret<0)
834  goto ex;
835  if(ret>=0)
836  hide_attrs|= ret;
837  }
838  }
839 
840  for(cpt= img_path; 1; cpt++) {
841  cpt= strstr(cpt,"/.");
842  if(cpt==NULL)
843  break;
844  if(cpt[2]=='.') {
845  if(cpt[3]=='/' || cpt[3]==0)
846  break;
847  } else if(cpt[2]=='/' || cpt[2]==0)
848  break;
849  }
850  if(cpt!=NULL) {
851  if(disk_path[0])
852  Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
853  sprintf(xorriso->info_text,
854  "Unsupported relative addressing in iso_rr_path ");
855  Text_shellsafe(img_path, xorriso->info_text, 1);
856  if(disk_path[0]) {
857  strcat(xorriso->info_text, " (disk: ");
858  Text_shellsafe(disk_path, xorriso->info_text, 1);
859  strcat(xorriso->info_text, ")");
860  }
861  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
862  {ret= 0; goto ex;}
863  }
864 
865  ret= Xorriso_get_volume(xorriso, &volume, 0);
866  if(ret<=0)
867  goto ex;
868 
869  strncpy(path, img_path, SfileadrL - 1);
870  path[SfileadrL - 1]= 0;
871  apt= npt= path;
872 
873  if(!(flag & (1 | 1024))) {
874  if(disk_path[0] == 0) {
875  Xorriso_msgs_submit(xorriso, 0, "/", 0, "ERRFILE", 0);
876  sprintf(xorriso->info_text,
877  "Will not graft-in the whole local filesystem by path '/'");
878  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
879  {ret= 0; goto ex;}
880  }
881  ret= lstat(disk_path, &stbuf);
882  if(ret!=-1) {
883  if(S_ISDIR(stbuf.st_mode))
884  is_dir= 1;
885  else if((stbuf.st_mode&S_IFMT)==S_IFLNK &&
886  (xorriso->do_follow_links ||
887  (xorriso->do_follow_param && !(flag&4)))) {
888  resolve_link= 1;
889  ret= stat(disk_path, &stbuf);
890  if(ret!=-1) {
891  if(S_ISDIR(stbuf.st_mode))
892  is_dir= 1;
893  }
894  }
895  }
896  if(ret == -1) {
897  Xorriso_process_msg_queues(xorriso,0);
898  Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
899  sprintf(xorriso->info_text,
900  "Cannot determine attributes of source file ");
901  Text_shellsafe(disk_path, xorriso->info_text, 1);
902  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
903  {ret= 0; goto ex;}
904  }
905  if(S_ISDIR(stbuf.st_mode)) {
906  is_dir= 1;
907  } else {
908  l= strlen(img_path);
909  if(l>0)
910  if(img_path[l-1]=='/')
911  l= 0;
912  if(l==0) {
913  Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
914  sprintf(xorriso->info_text, "Source ");
915  Text_shellsafe(disk_path, xorriso->info_text, 1);
916  strcat(xorriso->info_text, " is not a directory. Target ");
917  Text_shellsafe(img_path, xorriso->info_text, 1);
918  strcat(xorriso->info_text, " would be.");
919  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
920  {ret= 0; goto ex;}
921  }
922  }
923  }
924 
925  dir= iso_image_get_root(volume);
926  if(dir==NULL) {
927  Xorriso_process_msg_queues(xorriso,0);
928  sprintf(xorriso->info_text,
929  "While grafting '%s' : no root node available", img_path);
930  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
931  {ret= 0; goto ex;}
932  }
933  for(npt= apt; !done; apt= npt+1) {
934  npt= strchr(apt, '/');
935  if(npt==NULL) {
936  npt= apt+strlen(apt);
937  done= 1;
938  } else
939  *npt= 0;
940  if(*apt==0) {
941  *apt= '/';
942  apt++;
943  if(done)
944  goto attach_source;
945  continue;
946  }
947  source_is_dir= (is_dir || (flag&1) || !done);
948 
949 #ifdef Xorriso_optimistic_graft_iN
950 
951  /* Directories of the source path are likely to exist already as directory
952  in the image.
953  That will cause two lookups with optimistic, and only one with
954  pessimistic.
955  So optimism will pay off only with the leaf. I.e. if(done).
956  */
957  if(source_is_dir) { /* eventually create directory */
958  ret= iso_image_dir_get_node(volume, dir, apt, &node, 0);
959  if(ret == 1) {
960  ret= Xoriso_handle_collision(xorriso, boss_iter, &node, path,
961  img_path, disk_path,
962  disk_path[0] ? disk_path : img_path,
963  (!!source_is_dir) | (flag & (16 | 64 | 128)));
964  if(ret <= 0 || ret == 3)
965  goto ex;
966  if(ret == 1 && node != NULL)
967  dir= (IsoDir *) node;
968  } else
969  node= NULL;
970  if(node == NULL) {
971  ret= iso_image_add_new_dir(volume, dir, apt, &hdir);
972  if(ret < 0) {
973  Xorriso_process_msg_queues(xorriso,0);
974  if(disk_path[0])
975  Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
976  Xorriso_report_iso_error(xorriso, img_path, ret,
977  "Cannot create directory", 0, "FAILURE", 1);
978  sprintf(xorriso->info_text,
979  "While grafting '%s' : could not insert '%s'", img_path, path);
980  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
981  {ret= 0; goto ex;}
982  }
983  if(xorriso->update_flags & 1) {
984  ret= Xorriso_mark_update_merge(xorriso, path, (IsoNode *) hdir, 1);
985  if(ret <= 0)
986  {ret= 0; goto ex;}
987  }
988 
989  dir= hdir;
990  Xorriso_set_change_pending(xorriso, 0);
991  iso_node_set_ctime((IsoNode *) dir, time(NULL));
992  iso_node_set_uid((IsoNode *) dir, geteuid());
993  iso_node_set_gid((IsoNode *) dir, getegid());
994 
995  if(disk_path[0] && !done) {
996  /* This not only copies disk directory properties
997  but also sets eventual hide_attrs */
998  Xorriso_copy_implicit_properties(xorriso, dir, img_path, path,
999  disk_path, !!(flag&8));
1000  }
1001  }
1002  }
1003 
1004  if(done) {
1005 attach_source:;
1006  if(flag&1) {
1007  /* directory node was created above */;
1008 
1009  } else if(flag & 1024) {
1010  ret= Xorriso_add_symlink(xorriso, dir, disk_path, apt, img_path, 0);
1011  if(ret <= 0)
1012  goto ex;
1013  Xorriso_set_change_pending(xorriso, 0);
1014 
1015  } else if(is_dir) {
1016  Xorriso_transfer_properties(xorriso, &stbuf, disk_path,
1017  (IsoNode *) dir, 4 | 32);
1018  if(!(flag&32)) {
1019  ret= Xorriso_add_tree(xorriso, dir, img_path, disk_path, NULL,
1020  flag & (2 | 64 | 128));
1021  if(ret<=0)
1022  goto ex;
1023  }
1024  } else {
1025  if(resolve_link) {
1026  ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0);
1027  if(ret<=0)
1028  goto ex;
1029  disk_path_pt= resolved_disk_path;
1030  } else
1031  disk_path_pt= disk_path;
1032 
1033  ret= Xorriso_tree_graft_node(xorriso, volume, dir, disk_path_pt, apt,
1034  disk_path, img_path, offset, cut_size,
1035  &node, 1 | (flag & 8) | (hide_attrs << 8));
1036  if(ret == (int) ISO_NODE_NAME_NOT_UNIQUE) {
1037  ret= Xoriso_handle_collision(xorriso, boss_iter, &node, img_path,
1038  img_path, disk_path,
1039  disk_path[0] ? disk_path : img_path,
1040  (flag & (16 | 64 | 128)));
1041  if(ret <= 0 || ret == 3)
1042  goto ex;
1043  ret= Xorriso_tree_graft_node(xorriso, volume, dir, disk_path_pt, apt,
1044  disk_path, img_path, offset, cut_size,
1045  &node, (flag & 8) | (hide_attrs << 8));
1046  }
1047  if(ret<=0) {
1048  sprintf(xorriso->info_text, "Grafting failed: ");
1049  Text_shellsafe(img_path, xorriso->info_text, 1);
1050  strcat(xorriso->info_text, " = ");
1051  Text_shellsafe(disk_path, xorriso->info_text, 1);
1052  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1053  {ret= 0; goto ex;}
1054  }
1055  Xorriso_set_change_pending(xorriso, 0);
1056 
1057  /* <<< Why set the name once again ?
1058  iso_image_set_node_name(volume, node, apt, 1);
1059  */
1060 
1061  xorriso->pacifier_count++;
1062  if(xorriso->pacifier_count%100 && !(flag&2))
1063  Xorriso_pacifier_callback(xorriso, "files added",
1064  xorriso->pacifier_count,
1065  xorriso->pacifier_total, "", 0);
1066  }
1067  } else
1068  *npt= '/';
1069 
1070 #else /* Xorriso_optimistic_graft_iN */
1071 
1072  node= NULL;
1073  ret= iso_image_dir_get_node(volume, dir, apt, &node, 0);
1074  if(ret == 1) {
1075 
1076 #ifdef Xorriso_graft_handle_collisioN
1077 
1078  ret= Xoriso_handle_collision(xorriso, boss_iter, &node, path, img_path,
1079  disk_path,
1080  disk_path[0] ? disk_path : img_path,
1081  (!!source_is_dir) | (flag & (16 | 64 | 128)));
1082  if(ret <= 0 || ret == 3)
1083  goto ex;
1084  if(ret == 2)
1085  goto handle_path_node;
1086 
1087 #else /* Xorriso_graft_handle_collisioN */
1088 
1089  target_is_dir= LIBISO_ISDIR(node);
1090 
1091  target_is_split= 0;
1092  if(target_is_dir && !(flag & 128))
1093  target_is_split= Xorriso_is_split(xorriso, "", (void *) node, 1 | 2);
1094 
1095  if(!((target_is_dir && !target_is_split) && source_is_dir)) {
1096  Xorriso_process_msg_queues(xorriso,0);
1097 
1098  /* handle overwrite situation */;
1099  if(xorriso->do_overwrite==1 ||
1100  (xorriso->do_overwrite==2 && !(target_is_dir && !target_is_split))) {
1101  ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, path,
1102  1 | 8 | (flag & 64));
1103  if(ret<=0)
1104  goto ex;
1105  if(ret==3) {
1106  sprintf(xorriso->info_text, "User revoked adding of: ");
1107  if(disk_path[0])
1108  Text_shellsafe(disk_path, xorriso->info_text, 1);
1109  else
1110  Text_shellsafe(img_path, xorriso->info_text, 1);
1111  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1112  {ret= 3*!!(flag&16); goto ex;}
1113  }
1114  node= NULL;
1115  goto handle_path_node;
1116  }
1117 
1118  if (disk_path[0])
1119  Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
1120  sprintf(xorriso->info_text,
1121  "While grafting '%s' : '%s' exists and may not be overwritten",
1122  img_path, path);
1123  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1124  {ret= 0; goto ex;}
1125  }
1126 
1127 #endif /* ! Xorriso_graft_handle_collisioN */
1128 
1129  dir= (IsoDir *) node;
1130  }
1131 
1132 handle_path_node:;
1133  if(node==NULL && source_is_dir) { /* make a directory */
1134  ret= iso_image_add_new_dir(volume, dir, apt, &hdir);
1135  if(ret<0) {
1136  Xorriso_process_msg_queues(xorriso,0);
1137  if(disk_path[0])
1138  Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
1139  Xorriso_report_iso_error(xorriso, img_path, ret,
1140  "Cannot create directory", 0, "FAILURE", 1);
1141  sprintf(xorriso->info_text,
1142  "While grafting '%s' : could not insert '%s'", img_path, path);
1143  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1144  {ret= 0; goto ex;}
1145  }
1146  if(xorriso->update_flags & 1) {
1147  ret= Xorriso_mark_update_merge(xorriso, path, (IsoNode *) hdir, 1);
1148  if(ret <= 0)
1149  {ret= 0; goto ex;}
1150  }
1151 
1152  dir= hdir;
1153  Xorriso_set_change_pending(xorriso, 0);
1154  iso_node_set_ctime((IsoNode *) dir, time(NULL));
1155  iso_node_set_uid((IsoNode *) dir, geteuid());
1156  iso_node_set_gid((IsoNode *) dir, getegid());
1157 
1158  if(disk_path[0] && !done)
1159  /* This not only copies disk directory properties
1160  but also sets eventual hide_attrs */
1161  Xorriso_copy_implicit_properties(xorriso, dir, img_path, path, disk_path,
1162  !!(flag&8));
1163  }
1164  if(done) {
1165 attach_source:;
1166  if(flag&1) {
1167  /* directory node was created above */;
1168 
1169  } else if(flag & 1024) {
1170  ret= Xorriso_add_symlink(xorriso, dir, disk_path, apt, img_path, 0);
1171  if(ret <= 0)
1172  goto ex;
1173 
1174  } else if(is_dir) {
1175  Xorriso_transfer_properties(xorriso, &stbuf, disk_path,
1176  (IsoNode *) dir, 4 | 32);
1177  if(!(flag&32)) {
1178  ret= Xorriso_add_tree(xorriso, dir, img_path, disk_path, NULL,
1179  flag & (2 | 64 | 128));
1180  if(ret<=0)
1181  goto ex;
1182  }
1183  } else {
1184  if(resolve_link) {
1185  ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0);
1186  if(ret<=0)
1187  goto ex;
1188  disk_path_pt= resolved_disk_path;
1189  } else
1190  disk_path_pt= disk_path;
1191 
1192  ret= Xorriso_tree_graft_node(xorriso, volume, dir, disk_path_pt, apt,
1193  disk_path, img_path, offset, cut_size,
1194  &node, (flag&8) | (hide_attrs << 8));
1195  if(ret<=0) {
1196  sprintf(xorriso->info_text, "Grafting failed: ");
1197  Text_shellsafe(img_path, xorriso->info_text, 1);
1198  strcat(xorriso->info_text, " = ");
1199  Text_shellsafe(disk_path, xorriso->info_text, 1);
1200  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1201  {ret= 0; goto ex;}
1202  }
1203  Xorriso_set_change_pending(xorriso, 0);
1204  iso_image_set_node_name(volume, node, apt, 1);
1205 
1206  xorriso->pacifier_count++;
1207  if(xorriso->pacifier_count%100 && !(flag&2))
1208  Xorriso_pacifier_callback(xorriso, "files added",
1209  xorriso->pacifier_count,
1210  xorriso->pacifier_total, "", 0);
1211  }
1212  } else
1213  *npt= '/';
1214 
1215 #endif /* ! Xorriso_optimistic_graft_iN */
1216 
1217  }
1218 
1219  Xorriso_process_msg_queues(xorriso,0);
1220  ret= 1+!!is_dir;
1221 ex:;
1222  Xorriso_free_meM(path);
1223  Xorriso_free_meM(resolved_disk_path);
1224  return(ret);
1225 }
1226 
1227 
1228 /* @param flag bit0= -follow: disk_path is not a command parameter
1229 */
1230 int Xorriso_cut_out(struct XorrisO *xorriso, char *disk_path,
1231  off_t startbyte, off_t bytecount, char *iso_rr_path, int flag)
1232 {
1233  int ret;
1234  char *eff_source= NULL, *eff_dest= NULL;
1235  struct stat stbuf;
1236 
1237  Xorriso_alloc_meM(eff_source, char, SfileadrL);
1238  Xorriso_alloc_meM(eff_dest, char, SfileadrL);
1239 
1240  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_source,
1241  2|4);
1242  if(ret<=0)
1243  goto ex;
1244  ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&1));
1245  if(ret!=0)
1246  {ret= 0; goto ex;}
1247 
1248  if(lstat(eff_source, &stbuf)==-1) {
1249  Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0);
1250  sprintf(xorriso->info_text, "-cut_out: Cannot determine type of ");
1251  Text_shellsafe(eff_source, xorriso->info_text, 1);
1252  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
1253  {ret= 0; goto ex;}
1254  }
1255 
1256  if((stbuf.st_mode&S_IFMT) == S_IFLNK) {
1257  if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1))))
1258  goto unsupported_type;
1259  if(stat(eff_source, &stbuf)==-1) {
1260  Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0);
1261  sprintf(xorriso->info_text,
1262  "-cut_out: Cannot determine link target type of ");
1263  Text_shellsafe(eff_source, xorriso->info_text, 1);
1264  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
1265  {ret= 0; goto ex;}
1266  }
1267  }
1268  if(S_ISREG(stbuf.st_mode)) {
1269  if(stbuf.st_size<startbyte) {
1270  Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0);
1271  sprintf(xorriso->info_text,
1272  "-cut_out: Byte offset %.f larger than file size %.f",
1273  (double) startbyte, (double) stbuf.st_size);
1274  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "SORRY", 0);
1275  {ret= 0; goto ex;}
1276  }
1277  } else {
1278 unsupported_type:;
1279  Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0);
1280  sprintf(xorriso->info_text, "-cut_out: Unsupported file type (%s) with ",
1281  Ftypetxt(stbuf.st_mode, 0));
1282  Text_shellsafe(eff_source, xorriso->info_text, 1);
1283  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
1284  {ret= 0; goto ex;}
1285  }
1286 
1287  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, iso_rr_path, eff_dest,
1288  2);
1289  if(ret<=0)
1290  goto ex;
1291 
1292  ret= Xorriso_graft_in(xorriso, NULL, eff_source, eff_dest,
1293  startbyte, bytecount, 8);
1294 ex:;
1295  Xorriso_free_meM(eff_source);
1296  Xorriso_free_meM(eff_dest);
1297  return(ret);
1298 }
1299 
1300 
1301 /* @param flag bit0= do not produce info message on success
1302  bit1= do not raise protest if directory already exists
1303  @return 1=success,
1304  0=was already directory, -1=was other type, -2=other error
1305 */
1306 int Xorriso_mkdir(struct XorrisO *xorriso, char *path, int flag)
1307 {
1308  int ret;
1309  char *eff_path= NULL;
1310 
1311  Xorriso_alloc_meM(eff_path, char, SfileadrL);
1312 
1313  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 1);
1314  if(ret<0)
1315  {ret= -2; goto ex;}
1316  if(ret>0) {
1317  if(ret == 2 && (flag & 2))
1318  {ret= 0; goto ex;}
1319  sprintf(xorriso->info_text,"-mkdir: Address already existing ");
1320  Text_shellsafe(eff_path, xorriso->info_text, 1);
1321  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
1322  (ret==2 ? "WARNING" : "FAILURE"), 0);
1323  {ret= -1 + (ret == 2); goto ex;}
1324  }
1325  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 2);
1326  if(ret<0)
1327  {ret= -2; goto ex;}
1328  ret= Xorriso_graft_in(xorriso, NULL, NULL, eff_path, (off_t) 0, (off_t) 0, 1);
1329  if(ret<=0)
1330  {ret= -2; goto ex;}
1331  if(!(flag&1)) {
1332  sprintf(xorriso->info_text, "Created directory in ISO image: ");
1333  Text_shellsafe(eff_path, xorriso->info_text, 1);
1334  strcat(xorriso->info_text, "\n");
1335  Xorriso_info(xorriso, 0);
1336  }
1337  ret= 1;
1338 ex:;
1339  Xorriso_free_meM(eff_path);
1340  return(ret);
1341 }
1342 
1343 
1344 /* @param boss_iter If not NULL then this is an iterator suitable for
1345  iso_dir_iter_remove() which is then to be used instead
1346  of iso_node_remove().
1347  @param flag bit0= remove whole sub tree: rm -r
1348  bit1= remove empty directory: rmdir
1349  bit2= recursion: do not reassure in mode 2 "tree"
1350  bit3= this is for overwriting and not for plain removal
1351  bit4= count deleted files in xorriso->pacifier_count
1352  bit5= with bit0 only remove directory content, not the directory
1353  bit6= do not delete eventually existing node from di_array
1354  @return <=0 = error
1355  1 = removed simple node
1356  2 = removed directory or tree
1357  3 = did not remove on user revocation
1358 */
1359 int Xorriso_rmi(struct XorrisO *xorriso, void *boss_iter, off_t boss_mem,
1360  char *path, int flag)
1361 {
1362  int ret, is_dir= 0, pl, not_removed= 0, fret;
1363  IsoNode *victim_node= NULL, *node;
1364  IsoDir *boss_node, *root_dir;
1365  IsoDirIter *iter= NULL;
1366  IsoImage *volume;
1367  char *sub_name, *name;
1368  char *sfe= NULL, *sub_path= NULL;
1369  off_t mem;
1370  IsoNode **node_array= NULL;
1371  int node_count= 0, node_idx;
1372 
1373  /* Avoiding large local memory objects in order to save stack space */
1374  sfe= malloc(5*SfileadrL);
1375  sub_path= malloc(2*SfileadrL);
1376  if(sfe==NULL || sub_path==NULL) {
1377  Xorriso_no_malloc_memory(xorriso, &sfe, 0);
1378  {ret= -1; goto ex;}
1379  }
1380 
1381 #ifndef Libisofs_iso_dir_iter_sufficienT
1382  /* Ticket 127: A80301 - A80302
1383  I do not not deem IsoDirIter safe for node list manipulations.
1384  The parameter boss_iter once was intended to allow such but
1385  has now been downgraded to a mere check for eventual programming bugs.
1386  */
1387  if(boss_iter!=NULL) {
1388  sprintf(xorriso->info_text,
1389  "Program error: Xorriso_rmi() was requested to delete iterated node %s",
1390  Text_shellsafe(path, sfe, 0));
1391  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
1392  ret= -1; goto ex;
1393  }
1394 #endif /* Libisofs_iso_dir_iter_sufficienT */
1395 
1396  ret= Xorriso_get_volume(xorriso, &volume, 0);
1397  if(ret<=0)
1398  goto ex;
1399 
1400  if(Xorriso_much_too_long(xorriso, strlen(path), 0)<=0)
1401  {ret= 0; goto ex;}
1402  ret= Xorriso_node_from_path(xorriso, volume, path, &victim_node, 0);
1403  if(ret<=0)
1404  goto ex;
1405  root_dir= iso_image_get_root(volume);
1406  if(((void *) root_dir) == ((void *) victim_node) && !(flag & 1)) {
1407  sprintf(xorriso->info_text, "May not delete root directory");
1408  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1409  {ret= 0; goto ex;}
1410  }
1411 
1412  if(LIBISO_ISDIR(victim_node))
1413  is_dir= 1;
1414  if(!is_dir) {
1415  if(flag&2) { /* rmdir */
1416  sprintf(xorriso->info_text, "%s in loaded ISO image is not a directory",
1417  Text_shellsafe(path, sfe, 0));
1418  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1419  ret= 0; goto ex;
1420  }
1421  } else {
1422  if(flag&1) { /* rm -r */
1423  if((xorriso->do_reassure==1 && !xorriso->request_not_to_ask) ||
1424  (flag&32) || ((void *) root_dir) == ((void *) victim_node)) {
1425  /* Iterate over subordinates and delete them */
1426  mem= boss_mem;
1427 
1428  ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem,
1429  &iter, &node_array, &node_count, &node_idx,
1430  &node, 1|2);
1431  if(ret<=0) {
1432 cannot_create_iter:;
1433  Xorriso_cannot_create_iter(xorriso, ret, 0);
1434  ret= -1; goto ex;
1435  }
1436  pl= strlen(path);
1437  strcpy(sub_path, path);
1438  if(pl==0 || sub_path[pl-1]!='/') {
1439  sub_path[pl++]= '/';
1440  sub_path[pl]= 0;
1441  }
1442  sub_name= sub_path+pl;
1443  while(1) {
1444  ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, &iter,
1445  &node_array, &node_count, &node_idx, &node, 0);
1446  if(ret<0)
1447  goto ex;
1448  if(ret==0 || xorriso->request_to_abort)
1449  break;
1450  name= (char *) iso_node_get_name(node);
1451  if(Xorriso_much_too_long(xorriso, pl+1+strlen(name), 0)<=0)
1452  {ret= 0; goto rm_r_problem_handler;}
1453  strcpy(sub_name, name);
1454  ret= Xorriso_rmi(xorriso, iter, mem, sub_path,
1455  (flag & ( 1 | 2 | 8 | 16 | 64)) | 4);
1456  if(ret==3 || ret<=0 || xorriso->request_to_abort) {
1457 rm_r_problem_handler:;
1458  not_removed= 1;
1459  fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
1460  if(fret<0)
1461  goto dir_not_removed;
1462  }
1463  }
1464  if(flag&32)
1465  {ret= 2; goto ex;}
1466 
1467  if(not_removed) {
1468 dir_not_removed:;
1469  sprintf(xorriso->info_text, "Directory not removed: %s",
1470  Text_shellsafe(path, sfe, 0));
1471  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1472  if(ret>0)
1473  ret= 3;
1474  goto ex;
1475  }
1476  }
1477  } else {
1478  if(!(flag&2)) { /* not rmdir */
1479  sprintf(xorriso->info_text, "%s in loaded ISO image is a directory",
1480  Text_shellsafe(path, sfe, 0));
1481  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1482  ret= 0; goto ex;
1483  }
1484 
1485  ret= iso_dir_get_children((IsoDir *) victim_node, &iter);
1486  Xorriso_process_msg_queues(xorriso,0);
1487  if(ret<0)
1488  goto cannot_create_iter;
1489  if(ret>0) {
1490  if(iso_dir_iter_next(iter, &node) == 1) {
1491  sprintf(xorriso->info_text,
1492  "Directory not empty on attempt to delete: %s",
1493  Text_shellsafe(path, sfe, 0));
1494  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1495  ret= 0; goto ex;
1496  }
1497  }
1498  }
1499  }
1500 
1501  if(((void *) root_dir) == ((void *) victim_node))
1502  {ret= 2; goto ex;}
1503 
1504  if(xorriso->request_to_abort)
1505  {ret= 3; goto ex;}
1506  boss_node= iso_node_get_parent(victim_node);
1507  Xorriso_process_msg_queues(xorriso,0);
1508  if(boss_node==NULL) {
1509  sprintf(xorriso->info_text,
1510  "Cannot find parent node of %s in loaded ISO image",
1511  Text_shellsafe(path, sfe, 0));
1512  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1513  ret= 0; goto ex;
1514  }
1515 
1516  while((xorriso->do_reassure==1 || (xorriso->do_reassure==2 && !(flag&4)))
1517  && !xorriso->request_not_to_ask) {
1518  /* ls -ld */
1519  Xorriso_ls_filev(xorriso, xorriso->wdi, 1, &path, (off_t) 0, 1|2|8);
1520  if(is_dir) /* du -s */
1521  Xorriso_ls_filev(xorriso, xorriso->wdi, 1, &path, (off_t) 0, 2|4);
1522  if(flag&8)
1523  sprintf(xorriso->info_text,
1524  "File exists. Remove ? n= keep old, y= remove, x= abort, @= stop asking\n");
1525  else
1526  sprintf(xorriso->info_text,
1527  "Remove above file ? n= keep it, y= remove it, x= abort, @= stop asking\n");
1528  Xorriso_info(xorriso, 4);
1529  ret= Xorriso_request_confirmation(xorriso, 1|2|4|16);
1530  if(ret<=0)
1531  goto ex;
1532  if(xorriso->request_to_abort) {
1533  sprintf(xorriso->info_text,
1534  "Removal operation aborted by user before file: %s",
1535  Text_shellsafe(path, sfe, 0));
1536  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1537  ret= 3; goto ex;
1538  }
1539  if(ret==3)
1540  continue;
1541  if(ret==6) /* yes */
1542  break;
1543  if(ret==4) { /* yes, do not ask again */
1544  xorriso->request_not_to_ask= 1;
1545  break;
1546  }
1547  if(ret==1) { /* no */
1548  sprintf(xorriso->info_text, "Kept in existing state: %s",
1549  Text_shellsafe(path, sfe, 0));
1550  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1551  ret= 3; goto ex;
1552  }
1553  }
1554 
1555  if(!(flag & 64))
1556  Xorriso_invalidate_di_item(xorriso, victim_node, 0);
1557 
1558 #ifdef Libisofs_iso_dir_iter_sufficienT
1559 
1560  if(boss_iter!=NULL) {
1561  ret= iso_dir_iter_remove((IsoDirIter *) boss_iter);
1562  if(ret<0)
1563  ret= -1;
1564  } else
1565  ret= iso_node_remove(victim_node);
1566 
1567 #else /* ! Libisofs_iso_dir_iter_sufficienT */
1568 
1569  ret= iso_node_remove(victim_node);
1570 
1571 #endif /* Libisofs_iso_dir_iter_sufficienT */
1572 
1573  Xorriso_process_msg_queues(xorriso,0);
1574  if(ret<0) {
1575  Xorriso_report_iso_error(xorriso, path, ret, "Cannot remove node", 0,
1576  "FATAL", 1);
1577  sprintf(xorriso->info_text,
1578  "Internal failure to remove %s from loaded ISO image",
1579  Text_shellsafe(path, sfe, 0));
1580  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
1581  ret= -1; goto ex;
1582  }
1583 
1584  if(flag&16)
1585  xorriso->pacifier_count++;
1586  Xorriso_set_change_pending(xorriso, 0);
1587  ret= 1+!!is_dir;
1588 ex:;
1589  if(sfe!=NULL)
1590  free(sfe);
1591  if(sub_path!=NULL)
1592  free(sub_path);
1593  Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, &iter,
1594  &node_array, &node_count, &node_idx, &node, (1u<<31));
1595  return(ret);
1596 }
1597 
1598 
1599 int Xorriso_overwrite_dest(struct XorrisO *xorriso, void *boss_iter,
1600  char *eff_dest, int dest_ret, char *activity,
1601  int flag)
1602 {
1603  int ret;
1604 
1605  if(dest_ret==2 && xorriso->do_overwrite!=1) {
1606  sprintf(xorriso->info_text, "%s: May not overwrite directory: ", activity);
1607  Text_shellsafe(eff_dest, xorriso->info_text, 1);
1608  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1609  return(0);
1610  } else if (dest_ret==1 && !xorriso->do_overwrite) {
1611  sprintf(xorriso->info_text, "%s: May not overwrite: ", activity);
1612  Text_shellsafe(eff_dest, xorriso->info_text, 1);
1613  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1614  return(0);
1615  } else if(dest_ret>0) {
1616  ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, eff_dest, 1|8);
1617  if(ret<=0)
1618  return(0);
1619  if(ret==3) {
1620  sprintf(xorriso->info_text, "%s: User revoked removal of: ", activity);
1621  Text_shellsafe(eff_dest, xorriso->info_text, 1);
1622  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1623  return(0);
1624  }
1625  }
1626  return(1);
1627 }
1628 
1629 
1630 /* @param boss_iter Opaque handle to be forwarded to actions in ISO image
1631  Set to NULL if calling this function from outside ISO world
1632  @param flag bit0= silently ignore attempt of renaming to same path
1633  and return 2
1634 */
1635 int Xorriso_rename(struct XorrisO *xorriso, void *boss_iter,
1636  char *origin, char *dest, int flag)
1637 {
1638  int ret, ol, dest_ret;
1639  char *eff_dest= NULL, *dir_adr= NULL, *cpt;
1640  char *leafname, *eff_origin= NULL, *old_leafname;
1641  IsoImage *volume;
1642  IsoDir *origin_dir, *dest_dir;
1643  IsoNode *node, *iso_node;
1644 
1645  Xorriso_alloc_meM(eff_dest, char, SfileadrL);
1646  Xorriso_alloc_meM(dir_adr, char, SfileadrL);
1647  Xorriso_alloc_meM(eff_origin, char, SfileadrL);
1648 
1649 #ifndef Libisofs_iso_dir_iter_sufficienT
1650  /* Ticket 127: A80301 - A80302
1651  I do not not deem IsoDirIter safe for node list manipulations.
1652  The parameter boss_iter once was intended to allow such but
1653  has now been downgraded to a mere check for eventual programming bugs.
1654  */
1655  if(boss_iter!=NULL) {
1656  sprintf(xorriso->info_text,
1657  "Program error: Xorriso_rename() was requested to delete iterated node ");
1658  Text_shellsafe(origin, xorriso->info_text, 1);
1659  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
1660  {ret= -1; goto ex;}
1661  }
1662 #endif /* Libisofs_iso_dir_iter_sufficienT */
1663 
1664  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, origin, eff_origin, 0);
1665  if(ret<=0)
1666  goto ex;
1667  dest_ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, dest, eff_dest,1);
1668  if(dest_ret<0)
1669  {ret= dest_ret; goto ex;}
1670  if(dest_ret==0) { /* obtain eff_dest address despite it does not exist */
1671  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, dest, eff_dest, 2);
1672  if(ret<=0)
1673  goto ex;
1674  }
1675 
1676  /* Prevent that destination is a subordinate of origin
1677  (that would be a black hole plopping out of the universe) */
1678  ol= strlen(eff_origin);
1679  if(ol==0) {
1680  sprintf(xorriso->info_text, "May not rename root directory");
1681  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1682  {ret= 0; goto ex;}
1683  } else if(strcmp(eff_origin, eff_dest)==0) {
1684  if(flag & 1)
1685  {ret= 2; goto ex;}
1686  sprintf(xorriso->info_text, "Ignored attempt to rename ");
1687  Text_shellsafe(eff_origin, xorriso->info_text, 1);
1688  strcat(xorriso->info_text, " to itself");
1689  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
1690  {ret= 0; goto ex;}
1691  } else if(strncmp(eff_origin, eff_dest, ol)==0 &&
1692  (eff_dest[ol]==0 || eff_dest[ol]=='/')) {
1693  sprintf(xorriso->info_text, "May not rename ");
1694  Text_shellsafe(eff_origin, xorriso->info_text, 1);
1695  strcat(xorriso->info_text, " to its own sub address ");
1696  Text_shellsafe(eff_dest, xorriso->info_text, 1 | 2);
1697  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1698  {ret= 0; goto ex;}
1699  }
1700 
1701  /* Check whether destination exists and may be not overwritable */
1702  ret= Xorriso_overwrite_dest(xorriso, boss_iter,
1703  eff_dest, dest_ret, "Renaming", 0);
1704  if(ret <= 0)
1705  goto ex;
1706 
1707  /* Ensure existence of destination directory */
1708  strcpy(dir_adr, eff_dest);
1709  cpt= strrchr(dir_adr, '/');
1710  if(cpt==NULL)
1711  cpt= dir_adr+strlen(dir_adr);
1712  *cpt= 0;
1713  if(dir_adr[0]!=0) {
1714  ret= Xorriso_graft_in(xorriso, boss_iter, NULL, dir_adr,
1715  (off_t) 0, (off_t) 0, 1);
1716  if(ret<=0)
1717  goto ex;
1718  }
1719 
1720  /* Move node */
1721  ret= Xorriso_get_volume(xorriso, &volume, 0);
1722  if(ret<=0)
1723  goto ex;
1724  Xorriso_node_from_path(xorriso, volume, dir_adr, &iso_node, 0);
1725  dest_dir= (IsoDir *) iso_node;
1726  strcpy(dir_adr, eff_origin);
1727  cpt= strrchr(dir_adr, '/');
1728  if(cpt==NULL)
1729  cpt= dir_adr+strlen(dir_adr);
1730  *cpt= 0;
1731  Xorriso_node_from_path(xorriso, volume, dir_adr, &iso_node, 0);
1732  origin_dir= (IsoDir *) iso_node;
1733  Xorriso_node_from_path(xorriso, volume, eff_origin, &node, 0);
1734  if(dest_dir==NULL || origin_dir==NULL || node==NULL) {
1735  Xorriso_process_msg_queues(xorriso,0);
1736  sprintf(xorriso->info_text,
1737  "Internal error on rename: confirmed node turns out as NULL");
1738  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
1739  {ret= -1; goto ex;}
1740  }
1741  ret= iso_node_take(node);
1742  if(ret<0) {
1743  Xorriso_process_msg_queues(xorriso,0);
1744  Xorriso_report_iso_error(xorriso, eff_dest, 0, "Cannot take", 0, "FATAL",1);
1745  sprintf(xorriso->info_text,
1746  "Internal error on rename: failed to take node");
1747  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
1748  {ret= -1; goto ex;}
1749  }
1750  leafname= strrchr(eff_dest, '/');
1751  if(leafname==NULL)
1752  leafname= eff_dest;
1753  else
1754  leafname++;
1755 
1756  old_leafname= (char *) iso_node_get_name(node);
1757  if(strcmp(leafname, old_leafname)!=0)
1758  ret= iso_image_set_node_name(volume, node, leafname, 1);
1759  else
1760  ret= 1;
1761  if(ret<0) {
1762  Xorriso_process_msg_queues(xorriso,0);
1763  Xorriso_report_iso_error(xorriso, eff_dest, ret, "Cannot set name", 0,
1764  "FAILURE", 1);
1765  ret= iso_dir_add_node(origin_dir, node, 0);
1766  Xorriso_process_msg_queues(xorriso,0);
1767  if(ret < 0)
1768  Xorriso_report_iso_error(xorriso, eff_origin, ret,
1769  "Cannot re-instate node at old path",
1770  0, "FAILURE", 1);
1771  {ret= -1; goto ex;}
1772  }
1773  Xorriso_process_msg_queues(xorriso,0);
1774  ret= iso_dir_add_node(dest_dir, node, 0);
1775  if(ret<0) {
1776  Xorriso_process_msg_queues(xorriso,0);
1777  Xorriso_report_iso_error(xorriso, eff_dest, 0, "Cannot add", 0, "FATAL", 1);
1778  sprintf(xorriso->info_text,
1779  "Internal error on rename: failed to insert node");
1780  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
1781  {ret= -1; goto ex;}
1782  }
1783  Xorriso_set_change_pending(xorriso, 0);
1784  ret= 1;
1785 ex:;
1786  Xorriso_free_meM(eff_dest);
1787  Xorriso_free_meM(dir_adr);
1788  Xorriso_free_meM(eff_origin);
1789  return(ret);
1790 }
1791 
1792 
1793 int Xorriso_cannot_clone(struct XorrisO *xorriso, char *eff_origin,
1794  char *eff_dest, int iso_error, int flag)
1795 {
1796  Xorriso_report_iso_error(xorriso, eff_dest, iso_error, "Cannot clone",
1797  0, "FAILURE", 1);
1798  sprintf(xorriso->info_text, "Failed to clone ");
1799  Text_shellsafe(eff_origin, xorriso->info_text, 1);
1800  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1801  return(0);
1802 }
1803 
1804 
1805 /* @param flag bit0= for iso_tree_clone() : merge directories
1806  bit1= do not issue NOTE message
1807 */
1808 int Xorriso_clone_tree(struct XorrisO *xorriso, void *boss_iter,
1809  char *origin, char *dest, int flag)
1810 {
1811  int ret, dest_ret, l;
1812  char *eff_dest= NULL, *eff_origin= NULL, *dir_adr= NULL;
1813  char *leafname;
1814  IsoImage *volume;
1815  IsoDir *new_parent;
1816  IsoNode *origin_node, *dir_node, *new_node;
1817 
1818  Xorriso_alloc_meM(eff_dest, char, SfileadrL);
1819  Xorriso_alloc_meM(eff_origin, char, SfileadrL);
1820  Xorriso_alloc_meM(dir_adr, char, SfileadrL);
1821 
1822  ret= Xorriso_get_volume(xorriso, &volume, 0);
1823  if(ret <= 0)
1824  goto ex;
1825 
1826  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, origin, eff_origin, 0);
1827  if(ret<=0)
1828  goto ex;
1829  ret= Xorriso_node_from_path(xorriso, volume, eff_origin, &origin_node, 0);
1830  if(ret <= 0)
1831  goto ex;
1832 
1833  dest_ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, dest, eff_dest,1);
1834  if(dest_ret<0)
1835  {ret= dest_ret; goto ex;}
1836  if(dest_ret > 0) {
1837  if(eff_dest[0] == 0)
1838  strcpy(eff_dest, "/");
1839  sprintf(xorriso->info_text,
1840  "Cloning: Copy address already exists: ");
1841  Text_shellsafe(eff_dest, xorriso->info_text, 1);
1842  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1843  {ret= 0; goto ex;}
1844  } else {
1845  /* obtain eff_dest address despite it does not exist */
1846  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, dest, eff_dest, 2);
1847  if(ret<=0)
1848  goto ex;
1849  }
1850 
1851  /* Obtain parent path and leaf name */
1852  strcpy(dir_adr, eff_dest);
1853  for(l= strlen(dir_adr); l > 0; ) {
1854  if(dir_adr[l - 1] == '/')
1855  dir_adr[--l]= 0;
1856  else
1857  break;
1858  }
1859  leafname= strrchr(dir_adr, '/');
1860  if(leafname == NULL) {
1861  leafname= dir_adr;
1862  if (leafname[0] == 0) {
1863  Xorriso_msgs_submit(xorriso, 0, "Empty file name as clone destination",
1864  0, "FAILURE", 0);
1865  {ret= 0; goto ex;}
1866  }
1867  } else {
1868  *leafname= 0;
1869  leafname++;
1870  if(dir_adr[0] != 0) {
1871  /* Ensure existence of destination directory */
1872  ret= Xorriso_graft_in(xorriso, boss_iter, NULL, dir_adr,
1873  (off_t) 0, (off_t) 0, 1);
1874  if(ret <= 0)
1875  goto ex;
1876  }
1877  }
1878 
1879  ret= Xorriso_node_from_path(xorriso, volume, dir_adr, &dir_node, 0);
1880  if(ret <= 0)
1881  goto ex;
1882  new_parent= (IsoDir *) dir_node;
1883 
1884  ret = iso_image_tree_clone(volume, origin_node, new_parent, leafname,
1885  &new_node, (flag & 1) | 2);
1886  Xorriso_process_msg_queues(xorriso,0);
1887  if(ret < 0) {
1888  Xorriso_cannot_clone(xorriso, eff_origin, eff_dest, ret, 0);
1889  {ret= 0; goto ex;}
1890  }
1891  Xorriso_set_change_pending(xorriso, 0);
1892  if(!(flag & 2)) {
1893  strcpy(xorriso->info_text, "Cloned in ISO image: ");
1894  Text_shellsafe(eff_origin, xorriso->info_text, 1);
1895  strcat(xorriso->info_text, " to ");
1896  Text_shellsafe(eff_dest, xorriso->info_text, 1 | 2);
1897  strcat(xorriso->info_text, "\n");
1898  Xorriso_info(xorriso, 0);
1899  }
1900  ret= 1;
1901 ex:;
1902  Xorriso_free_meM(eff_dest);
1903  Xorriso_free_meM(eff_origin);
1904  Xorriso_free_meM(dir_adr);
1905  return(ret);
1906 }
1907 
1908 
1909 int Xorriso_clone_under(struct XorrisO *xorriso, char *origin, char *dest,
1910  int flag)
1911 {
1912  int ret, pass;
1913  char *eff_dest= NULL, *eff_origin= NULL, *namept;
1914  IsoDir *origin_dir, *dest_dir;
1915  IsoDirIter *iter= NULL;
1916  IsoNode *origin_node, *new_node;
1917  IsoImage *volume;
1918 
1919  Xorriso_alloc_meM(eff_dest, char, SfileadrL);
1920  Xorriso_alloc_meM(eff_origin, char, SfileadrL);
1921 
1922  ret= Xorriso_get_volume(xorriso, &volume, 0);
1923  if(ret <= 0)
1924  goto ex;
1925  ret= Xorriso_dir_from_path(xorriso, "Copy source", origin, &origin_dir, 0);
1926  if(ret <= 0)
1927  goto ex;
1928  ret= Xorriso_dir_from_path(xorriso, "Copy destination", dest, &dest_dir, 0);
1929  if(ret <= 0)
1930  goto ex;
1931 
1932  for(pass= 0; pass < 2; pass++) {
1933  ret= iso_dir_get_children(origin_dir, &iter);
1934  if(ret < 0) {
1935  Xorriso_cannot_create_iter(xorriso, ret, 0);
1936  {ret= -1; goto ex;}
1937  }
1938  Xorriso_process_msg_queues(xorriso,0);
1939 
1940  while(iso_dir_iter_next(iter, &origin_node) == 1) {
1941  namept= (char *) iso_node_get_name(origin_node);
1942  sprintf(eff_origin, "%s/%s", origin, namept);
1943  sprintf(eff_dest, "%s/%s", dest, namept);
1944  if(pass == 0) {
1945  ret= Xorriso_node_from_path(xorriso, volume, eff_dest, &new_node, 1);
1946  if(ret < 0)
1947  goto ex;
1948  if(ret > 0) {
1949  sprintf(xorriso->info_text, "Cloning: Copy address already exists: ");
1950  Text_shellsafe(eff_dest, xorriso->info_text, 1);
1951  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1952  ret= 0; goto ex;
1953  }
1954  } else {
1955  ret = iso_image_tree_clone(volume, origin_node, dest_dir, namept,
1956  &new_node, 1 | 2);
1957  Xorriso_process_msg_queues(xorriso,0);
1958  if(ret < 0) {
1959  Xorriso_cannot_clone(xorriso, eff_origin, eff_dest, ret, 0);
1960  ret= 0; goto ex;
1961  }
1962  }
1963  }
1964  iso_dir_iter_free(iter);
1965  iter= NULL;
1966  }
1967  Xorriso_set_change_pending(xorriso, 0);
1968  ret= 1;
1969 ex:;
1970  if(iter != NULL)
1971  iso_dir_iter_free(iter);
1972  Xorriso_free_meM(eff_dest);
1973  Xorriso_free_meM(eff_origin);
1974  Xorriso_process_msg_queues(xorriso,0);
1975  return(ret);
1976 }
1977 
1978 
1979 int Xorriso_set_st_mode(struct XorrisO *xorriso, char *in_path,
1980  mode_t mode_and, mode_t mode_or, int flag)
1981 {
1982  mode_t mode= 0;
1983  int ret;
1984  IsoNode *node;
1985  char *path= NULL;
1986 
1987  Xorriso_alloc_meM(path, char, SfileadrL);
1988  ret= Xorriso_get_node_by_path(xorriso, in_path, path, &node, 0);
1989  if(ret<=0)
1990  goto ex;
1991  mode= iso_node_get_permissions(node);
1992  mode= (mode & mode_and) | mode_or;
1993  iso_node_set_permissions(node, mode);
1994  iso_node_set_ctime(node, time(NULL));
1995  sprintf(xorriso->info_text,"Permissions now: %-5.5o ",
1996  (unsigned int) (mode & 0xffff));
1997  Text_shellsafe(path, xorriso->info_text, 1);
1998  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
1999  Xorriso_set_change_pending(xorriso, 0);
2000  Xorriso_process_msg_queues(xorriso,0);
2001  ret= 1;
2002 ex:;
2003  Xorriso_free_meM(path);
2004  return(ret);
2005 }
2006 
2007 
2008 int Xorriso_set_uid(struct XorrisO *xorriso, char *in_path, uid_t uid,
2009  int flag)
2010 {
2011  int ret;
2012  IsoNode *node;
2013 
2014  ret= Xorriso_get_node_by_path(xorriso, in_path, NULL, &node, 0);
2015  if(ret<=0)
2016  return(ret);
2017  iso_node_set_uid(node, uid);
2018  iso_node_set_ctime(node, time(NULL));
2019  Xorriso_set_change_pending(xorriso, 0);
2020  Xorriso_process_msg_queues(xorriso,0);
2021  return(1);
2022 }
2023 
2024 
2025 int Xorriso_set_gid(struct XorrisO *xorriso, char *in_path, gid_t gid,
2026  int flag)
2027 {
2028  int ret;
2029  IsoNode *node;
2030 
2031  ret= Xorriso_get_node_by_path(xorriso, in_path, NULL, &node, 0);
2032  if(ret<=0)
2033  return(ret);
2034  iso_node_set_gid(node, gid);
2035  iso_node_set_ctime(node, time(NULL));
2036  Xorriso_set_change_pending(xorriso, 0);
2037  Xorriso_process_msg_queues(xorriso,0);
2038  return(1);
2039 }
2040 
2041 
2042 /* @parm flag bit0= atime, bit1= ctime, bit2= mtime, bit8=no auto ctime */
2043 int Xorriso_set_time(struct XorrisO *xorriso, char *in_path, time_t t,
2044  int flag)
2045 {
2046  int ret;
2047  IsoNode *node;
2048 
2049  ret= Xorriso_get_node_by_path(xorriso, in_path, NULL, &node, 0);
2050  if(ret<=0)
2051  return(ret);
2052  if(flag&1)
2053  iso_node_set_atime(node, t);
2054  if(flag&2)
2055  iso_node_set_ctime(node, t);
2056  if(flag&4)
2057  iso_node_set_mtime(node, t);
2058  if(!(flag&(2|256)))
2059  iso_node_set_ctime(node, time(NULL));
2060  Xorriso_set_change_pending(xorriso, 0);
2061  Xorriso_process_msg_queues(xorriso,0);
2062  return(1);
2063 }
2064 
2065 
2066 /*
2067  Apply the effect of mkisofs -r to a single node
2068 */
2069 int Xorriso_mkisofs_lower_r(struct XorrisO *xorriso, IsoNode *node, int flag)
2070 {
2071  mode_t perms;
2072 
2073  perms= iso_node_get_permissions(node);
2074  iso_node_set_uid(node, (uid_t) 0);
2075  iso_node_set_gid(node, (gid_t) 0);
2076  perms|= S_IRUSR | S_IRGRP | S_IROTH;
2077  perms&= ~(S_IWUSR | S_IWGRP | S_IWOTH);
2078  if(perms & (S_IXUSR | S_IXGRP | S_IXOTH))
2079  perms|= (S_IXUSR | S_IXGRP | S_IXOTH);
2080  perms&= ~(S_ISUID | S_ISGID | S_ISVTX);
2081  iso_node_set_permissions(node, perms);
2082  return(1);
2083 }
2084 
2085 
2086 /* @param node Opaque handle to IsoNode which is to be manipulated
2087  instead of path if it is not NULL.
2088  @param path is used as address if node is NULL.
2089  @param access_text "access" ACL in long text form
2090  @param default_text "default" ACL in long text form
2091  @param flag bit0= do not warn of root directory if not capable of AAIP
2092  @return >0 success , <=0 failure
2093 */
2094 int Xorriso_setfacl(struct XorrisO *xorriso, void *in_node, char *path,
2095  char *access_text, char *default_text, int flag)
2096 {
2097  int ret;
2098  IsoNode *node;
2099 
2100  node= (IsoNode *) in_node;
2101  if(node == NULL) {
2102  ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
2103  if(ret<=0)
2104  goto ex;
2105  }
2106  ret= iso_node_set_acl_text(node, access_text, default_text, 4);
2107  Xorriso_process_msg_queues(xorriso,0);
2108  if(ret <= 0) {
2109  Xorriso_report_iso_error(xorriso, "", ret,
2110  "Error when setting ACL to image node",
2111  0, "FAILURE", 1);
2112  if(path != NULL && path[0] != 0) {
2113  strcpy(xorriso->info_text, "Error with setting ACL of ");
2114  Text_shellsafe(path, xorriso->info_text, 1);
2115  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2116  }
2117  ret= 0; goto ex;
2118  }
2119  Xorriso_set_change_pending(xorriso, 0);
2120  ret= 1;
2121 ex:;
2122  return(ret);
2123 }
2124 
2125 
2126 /* @param in_node Opaque handle to IsoNode which is to be manipulated
2127  instead of path if it is not NULL.
2128  @param path is used as address if node is NULL.
2129  @param num_attrs Number of attributes
2130  @param names Array of pointers to 0 terminated name strings
2131  @param value_lengths Array of byte lengths for each attribute payload
2132  @param values Array of pointers to the attribute payload bytes
2133  @param flag bit0= Do not maintain eventual existing ACL of the node
2134  bit1= Do not clear the existing attribute list
2135  bit2= Delete the attributes with the given names
2136  bit3= Allow non-user attributes.
2137  bit4= do not warn of root if incapable of AAIP
2138  @return >0 success , <=0 failure
2139 */
2140 int Xorriso_setfattr(struct XorrisO *xorriso, void *in_node, char *path,
2141  size_t in_num_attrs, char **in_names,
2142  size_t *in_value_lengths, char **in_values, int flag)
2143 {
2144  int ret, block_isofs= 0, in_original= 1;
2145  size_t i, j, num_attrs;
2146  IsoNode *node;
2147  char **names, **values;
2148  size_t *value_lengths;
2149 
2150  num_attrs= in_num_attrs;
2151  names= in_names;
2152  value_lengths= in_value_lengths;
2153  values= in_values;
2154 
2155  node= (IsoNode *) in_node;
2156  if(node == NULL) {
2157  ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
2158  if(ret<=0)
2159  goto ex;
2160  }
2161  if((xorriso->do_aaip & 1024) && !(flag & 8)) {
2162  flag|= 8;
2163  block_isofs= 1;
2164  for(i= 0; i < in_num_attrs; i++) {
2165  if(strncmp(in_names[i], "isofs.", 6) == 0) {
2166  if(in_original) {
2167  strcpy(xorriso->info_text,
2168  "Attempt to set xattr from namespace \"isofs\" to ");
2169  Text_shellsafe(path, xorriso->info_text, 1);
2170  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
2171  ret= Xorriso_eval_problem_status(xorriso, 0, 0);
2172  if(ret < 0) {
2173  ret= 0; goto ex;
2174  }
2175  /* Switch to copy mode and omit isofs names */
2176  Xorriso_alloc_meM(names, char *, num_attrs);
2177  Xorriso_alloc_meM(value_lengths, size_t, num_attrs);
2178  Xorriso_alloc_meM(values, char *, num_attrs);
2179  in_original= 0;
2180  for(j= 0; j < i; j++) {
2181  names[j]= in_names[j];
2182  value_lengths[j]= in_value_lengths[j];
2183  values[j]= in_values[j];
2184  }
2185  num_attrs= i;
2186  }
2187  } else if(!in_original) {
2188  names[num_attrs]= in_names[i];
2189  value_lengths[num_attrs]= in_value_lengths[i];
2190  values[num_attrs]= in_values[i];
2191  num_attrs++;
2192  }
2193  }
2194  }
2195  if(num_attrs <= 0) {
2196  ret= 1; goto ex;
2197  }
2198 
2199  ret= iso_node_set_attrs(node, num_attrs, names, value_lengths, values,
2200  (flag & (1 | 2 | 4 | 8)) | (block_isofs << 4));
2201  Xorriso_process_msg_queues(xorriso,0);
2202  if(ret <= 0) {
2203  Xorriso_report_iso_error(xorriso, "", ret,
2204  "Error when setting ACL and xattr to image node",
2205  0, "FAILURE", 1);
2206  if(path != NULL && path[0] != 0) {
2207  strcpy(xorriso->info_text, "Error with setting xattr of ");
2208  Text_shellsafe(path, xorriso->info_text, 1);
2209  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2210  }
2211  ret= 0; goto ex;
2212  }
2213  Xorriso_set_change_pending(xorriso, 0);
2214  ret= 1;
2215 ex:;
2216  Xorriso_process_msg_queues(xorriso, 0);
2217  if(!in_original) {
2218  Xorriso_free_meM(names);
2219  Xorriso_free_meM(value_lengths);
2220  Xorriso_free_meM(values);
2221  }
2222  return(ret);
2223 }
2224 
2225 
2226 /*
2227  @param flag bit0= use parameters dev,ino rather than disk_path
2228  bit1= compare attribute rather than setting it
2229  return: 0=dev,ino match, 1=mismatch, 2=no node attribute
2230  -1=error
2231  bit5= if not bit0:
2232  transfer dev,inode from eventual link target
2233  bit7= omit dev check mit bit1
2234 */
2235 int Xorriso_record_dev_inode(struct XorrisO *xorriso, char *disk_path,
2236  dev_t dev, ino_t ino,
2237  void *in_node, char *iso_path, int flag)
2238 {
2239  size_t l, di_l= 0;
2240  int i, ret;
2241  dev_t hdev;
2242  ino_t hino;
2243  char buf[66], *bufpt, *wpt, *di= NULL;
2244  static char *name= "isofs.di";
2245  struct stat stbuf;
2246 
2247  if(!(flag & 1)) {
2248  if(flag & 32) {
2249  if(stat(disk_path, &stbuf) == -1)
2250  return(-1);
2251  } else {
2252  if(lstat(disk_path, &stbuf) == -1)
2253  return(-1);
2254  }
2255  dev= stbuf.st_dev;
2256  ino= stbuf.st_ino;
2257  }
2258 
2259  wpt= buf;
2260  hdev= dev;
2261  for(i= 0; hdev != 0; i++)
2262  hdev= hdev >> 8;
2263  l= i;
2264  *(wpt++)= l;
2265  for(i= 0; i < (int) l; i++)
2266  *(wpt++)= dev >> (8 * (l - i - 1));
2267  hino= ino;
2268  for(i= 0; hino != 0; i++)
2269  hino= hino >> 8;
2270  l= i;
2271  *(wpt++)= l;
2272  for(i= 0; i < (int) l; i++)
2273  *(wpt++)= ino >> (8 * (l - i - 1));
2274  l= wpt - buf;
2275  bufpt= buf;
2276 
2277  if(flag & 2) {
2278  /* Compare node attribute with bufpt,l */
2279  ret= Xorriso_get_attr_value(xorriso, in_node, iso_path,
2280  "isofs.di", &di_l, &di, 0);
2281  if(ret < 0)
2282  goto ex;
2283  if(ret == 0)
2284  {ret= 2; goto ex;}
2285  if(flag & 128) {
2286  if(di_l <= 0)
2287  {ret= 1; goto ex;}
2288  hino= 0;
2289  for(i= di[0] + 2; i < (int) di_l && i - di[0] - 2 < di[(int) di[0] + 1];
2290  i++)
2291  hino= (hino << 8) | ((unsigned char *) di)[i];
2292  if(hino != ino)
2293  {ret= 1; goto ex;}
2294  } else {
2295  if(l != di_l)
2296  {ret= 1; goto ex;}
2297  for(i= 0; i < (int) l; i++)
2298  if(di[i] != buf[i])
2299  {ret= 1; goto ex;}
2300  }
2301  ret= 0;
2302  } else {
2303  ret= Xorriso_setfattr(xorriso, in_node, iso_path,
2304  (size_t) 1, &name, &l, &bufpt, 2 | 8);
2305  }
2306 ex:;
2307  if(di != NULL)
2308  free(di);
2309  return(ret);
2310 }
2311 
2312 
2313 /* @return see Xorriso_update_interpreter()
2314 */
2315 int Xorriso_widen_hardlink(struct XorrisO *xorriso, void * boss_iter,
2316  IsoNode *node,
2317  char *abs_path, char *iso_prefix, char *disk_prefix,
2318  int flag)
2319 {
2320  int ret= 0, idx, low, high, i, do_widen= 0, compare_result= 0;
2321  char *disk_path;
2322 
2323  Xorriso_alloc_meM(disk_path, char, SfileadrL);
2324 
2325  /* Lookup all di_array instances of node */
2326  if(LIBISO_ISDIR(node))
2327  {ret= 3; goto ex;}
2328  ret= Xorriso_search_di_range(xorriso, node, &idx, &low, &high, 2);
2329  if(ret <= 0)
2330  {ret= 3; goto ex;}
2331  /* Check and reset di_do_widen bits */
2332  for(i= low; i <= high; i++) {
2333  if(node != xorriso->di_array[i]) /* might be NULL */
2334  continue;
2335  if(xorriso->di_do_widen[i / 8] & (1 << (i % 8)))
2336  do_widen= 1;
2337  xorriso->di_do_widen[i / 8]&= ~(1 << (i % 8));
2338  }
2339  if(idx < 0 || !do_widen)
2340  {ret= 3; goto ex;}
2341 
2342  ret= Xorriso_pfx_disk_path(xorriso, abs_path, iso_prefix, disk_prefix,
2343  disk_path, 0);
2344  if(ret <= 0)
2345  goto ex;
2346  ret= Sfile_type(disk_path, 1);
2347  if(ret < 0)
2348  {ret= 3; goto ex;} /* does not exist on disk */
2349 
2350  /* >>> compare_result bit17 = is_split */;
2351 
2352  ret= Xorriso_update_interpreter(xorriso, boss_iter, NULL,
2353  compare_result, disk_path, abs_path, 1);
2354  if(ret <= 0)
2355  goto ex;
2356 ex:;
2357  Xorriso_free_meM(disk_path);
2358  return(ret);
2359 }
2360 
2361 
2362 int Xorriso_set_hidden(struct XorrisO *xorriso, void *in_node, char *path,
2363  int hide_state, int flag)
2364 {
2365  int ret, hide_attrs= 0;
2366  IsoNode *node;
2367 
2368  node= (IsoNode *) in_node;
2369  if(node == NULL) {
2370  ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
2371  if(ret<=0)
2372  return(ret);
2373  }
2374  if(hide_state) {
2375  hide_attrs|= LIBISO_HIDE_BUT_WRITE;
2376  if(hide_state & 1)
2377  hide_attrs|= LIBISO_HIDE_ON_RR;
2378  if(hide_state & 2)
2379  hide_attrs|= LIBISO_HIDE_ON_JOLIET;
2380  if(hide_state & 4)
2381  hide_attrs|= LIBISO_HIDE_ON_HFSPLUS;
2382  }
2383  iso_node_set_hidden(node, hide_attrs);
2384  return(1);
2385 }
2386 
2387 
2388 /* @param flag bit0= increase only upper estimation
2389 */
2390 int Xorriso_estimate_file_size(struct XorrisO *xorriso, struct FindjoB *job,
2391  char *basename, mode_t st_mode, off_t st_size, int flag)
2392 {
2393  off_t upper, lower, size;
2394 
2395  lower = 3 * strlen(basename) + 34; /* >>> + minimum RR ? */
2396  upper = 3 * strlen(basename) + 2048;
2397  if(S_ISREG(st_mode)) {
2398  size= ((st_size + (off_t) 2047) / (off_t) 2048) * (off_t) 2048;
2399  lower+= size;
2400  upper+= size;
2401  } else if(S_ISDIR(st_mode)) {
2402  upper+= 4096;
2403  }
2404  job->estim_upper_size+= upper;
2405  if(!(flag & 1))
2406  job->estim_lower_size+= lower;
2407  return(1);
2408 }
2409 
2410 
2411 /* @param flag bit0= do not compare but print input and back converted name
2412 */
2413 int Xorriso_test_outchar(struct XorrisO *xorriso, void *node_pt,
2414  int name_space, int flag)
2415 {
2416  IsoNode *node;
2417  char *result= NULL, *name, *back= NULL;
2418  int ret, relax_mem;
2419  size_t result_len, back_len, i;
2420  struct isoburn_imgen_opts *sopts= NULL;
2421 
2422  relax_mem= xorriso->relax_compliance;
2423 
2424  node= (IsoNode *) node_pt;
2425  ret= isoburn_igopt_new(&sopts, 0);
2426  if(ret<=0) {
2427  Xorriso_process_msg_queues(xorriso, 0);
2428  ret= -1; goto ex;
2429  }
2430  if(!(flag & 1))
2432  ret= Xorriso_make_iso_write_opts(xorriso, NULL, sopts, 0);
2433  if(ret <= 0) {
2434  ret= -1; goto ex;
2435  }
2436 
2437  if(iso_node_get_type(node) == LIBISO_DIR)
2438  name_space |= 256;
2439  name_space|= 512; /* no error messages */
2440 
2441  name= (char *) iso_node_get_name(node);
2442  if(name == NULL) {
2443  ret= 1; goto ex;
2444  }
2445  ret= isoburn_conv_name_chars(sopts, name, strlen(name), &result, &result_len,
2446  name_space);
2447  if(ret <= 0) {
2448  Xorriso_process_msg_queues(xorriso, 0);
2449  if(flag & 1)
2450  goto print_outname;
2451  ret= 0; goto ex;
2452  }
2453 
2454  /* Convert back and compare with original */
2455  ret= isoburn_conv_name_chars(sopts, result, result_len, &back, &back_len,
2456  name_space | (1 << 15));
2457  if(ret <= 0) {
2458  Xorriso_process_msg_queues(xorriso, 0);
2459  if(flag & 1)
2460  goto print_outname;
2461  ret= 0; goto ex;
2462  }
2463  if(flag & 1) {
2464 print_outname:;
2465  Text_shellsafe(name, xorriso->result_line, 0);
2466  strcat(xorriso->result_line, "\n");
2467  Xorriso_result(xorriso, 0);
2468  if(back == NULL)
2469  strcpy(xorriso->result_line, "(file name conversion error)");
2470  else
2471  Text_shellsafe(back, xorriso->result_line, 0);
2472  strcat(xorriso->result_line, "\n");
2473  Xorriso_result(xorriso, 0);
2474  strcpy(xorriso->result_line, "--\n");
2475  Xorriso_result(xorriso, 0);
2476  } else {
2477  for(i= 0; i < back_len; i++)
2478  if(name[i] != back[i])
2479  {ret= 0; goto ex;}
2480  if(name[i] != 0)
2481  {ret= 0; goto ex;}
2482  }
2483 
2484  ret= 1;
2485 ex:;
2486  isoburn_igopt_destroy(&sopts, 0);
2487  if(result != NULL)
2488  free(result);
2489  if(back != NULL)
2490  free(back);
2491  xorriso->relax_compliance= relax_mem;
2492  return(ret);
2493 }
2494 
2495 
2496 int Xorriso_set_to_mtime(struct XorrisO *xorriso, char *show_path,
2497  IsoNode *node, int flag)
2498 {
2499  time_t t;
2500 
2501  t= iso_node_get_mtime(node);
2502  iso_node_set_atime(node, t);
2503  iso_node_set_ctime(node, t);
2504  Xorriso_set_change_pending(xorriso, 0);
2505  return(1);
2506 }
2507 
2508 
2509 int Xorriso_cannot_create_iter(struct XorrisO *xorriso, int iso_error,int flag)
2510 {
2511  Xorriso_process_msg_queues(xorriso,0);
2512  Xorriso_report_iso_error(xorriso, "", iso_error, "Cannot create iter", 0,
2513  "FATAL", 1);
2514  sprintf(xorriso->info_text, "Cannot create IsoDirIter object");
2515  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
2516  return(1);
2517 }
2518 
2519 
2520 /* The caller shall make no assumptions about the meaning of iter, node_array,
2521  node_count, node_idx ! They are just opaque handles for which the caller
2522  provides the memory of proper type.
2523  @param flag bit0= initialize iteration
2524  bit1= action needs full freedom of object manipulation
2525  bit2= action needs LBA sorted iteration
2526  bit31= end iteration (mandatory !)
2527 */
2528 int Xorriso_findi_iter(struct XorrisO *xorriso, IsoDir *dir_node, off_t *mem,
2529  IsoDirIter **iter,
2530  IsoNode ***node_array, int *node_count, int *node_idx,
2531  IsoNode **iterated_node, int flag)
2532 {
2533  int ret, i;
2534  IsoNode *node;
2535  off_t new_mem= 0;
2536  char mem_text[80], limit_text[80];
2537 
2538  if(flag&1) {
2539  *node_array= NULL;
2540  *node_count= -1;
2541  *node_idx= 0;
2542  *iter= NULL;
2543  ret= iso_dir_get_children(dir_node, iter);
2544  if(ret<0) {
2545 cannot_iter:;
2546  Xorriso_cannot_create_iter(xorriso, ret, 0);
2547  return(-1);
2548  }
2549  if((flag&2)|(flag&4)) {
2550  /* copy list of nodes and prepare soft iterator */
2551  *node_count= 0;
2552  while(iso_dir_iter_next(*iter, &node) == 1)
2553  (*node_count)++;
2554  iso_dir_iter_free(*iter);
2555  *iter= NULL;
2556 
2557  new_mem= ((*node_count)+1) * sizeof(IsoNode *);
2558  if(new_mem > xorriso->temp_mem_limit) {
2559  Sfile_scale((double) new_mem, mem_text, 5,1e4, 0);
2560  Sfile_scale((double) xorriso->temp_mem_limit, limit_text, 5,1e4, 0);
2561  sprintf(xorriso->info_text,
2562  "Stacked directory snapshots exceed -temp_mem_limit (%s > %s)",
2563  mem_text, limit_text);
2564  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2565  *node_count= -1;
2566  return(-1);
2567  }
2568  (*node_array)= (IsoNode **) calloc((*node_count)+1, sizeof(IsoNode *));
2569  if(*node_array == NULL) {
2570  sprintf(xorriso->info_text,
2571  "Could not allocate inode list of %.f bytes",
2572  ((double) (*node_count)+1) * (double) sizeof(IsoNode *));
2573  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
2574  *node_count= -1;
2575  return(-1);
2576  }
2577  *mem= new_mem;
2578  ret= iso_dir_get_children(dir_node, iter);
2579  if(ret<0)
2580  goto cannot_iter;
2581  while(iso_dir_iter_next(*iter, &node) == 1 && *node_idx < *node_count) {
2582  (*node_array)[*node_idx]= node;
2583  iso_node_ref(node);
2584  (*node_idx)++;
2585  }
2586  iso_dir_iter_free(*iter);
2587  *iter= NULL;
2588  *node_count= *node_idx;
2589  *node_idx= 0;
2590  if((flag&4) && *node_count>1)
2591  qsort(*node_array, *node_count, sizeof(IsoNode *),
2593  }
2594  }
2595 
2596  if(flag&(1u<<31)) {
2597  if(*node_count>=0 && *node_array!=NULL) {
2598  for(i= 0; i<*node_count; i++)
2599  iso_node_unref((*node_array)[i]);
2600  free(*node_array);
2601  *node_array= NULL;
2602  *node_count= -1;
2603  *node_idx= 0;
2604  } else {
2605  if(*iter!=NULL)
2606  iso_dir_iter_free(*iter);
2607  *iter= NULL;
2608  }
2609  }
2610 
2611  if(flag&(1|(1u<<31)))
2612  return(1);
2613  if(*node_count>=0) {
2614  /* return next node_array element */
2615  if(*node_idx>=*node_count)
2616  return(0);
2617  *iterated_node= (*node_array)[*node_idx];
2618  (*node_idx)++;
2619  } else {
2620  ret= iso_dir_iter_next(*iter, iterated_node);
2621  return(ret == 1);
2622  }
2623  return(1);
2624 }
2625 
2626 
2627 /* @param flag bit0= not a command parameter (directory iteration or recursion)
2628  bit1= do not count deleted files with rm and rm_r
2629  @return <=0 error,
2630  1=ok
2631  2=ok, node has been deleted,
2632  3=ok, do not dive into directory (e.g. because it is a split file)
2633  4=ok, end findjob gracefully
2634 */
2635 int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job,
2636  IsoDirIter *boss_iter, off_t boss_mem,
2637  char *abs_path, char *show_path,
2638  IsoNode *node, int depth, int flag)
2639 {
2640  int ret= 0, type, action= 0, hflag, deleted= 0, no_dive= 0, i, bless_idx;
2641  int unbless= 0;
2642  uid_t user= 0;
2643  gid_t group= 0;
2644  time_t date= 0;
2645  mode_t mode_or= 0, mode_and= ~1;
2646  char *target, *text_2, *iso_prefix, md5[16], *basename, bless_code[17];
2647  char crtp[10];
2648  struct FindjoB *subjob;
2649  struct stat dir_stbuf, stbuf;
2650  void *xinfo;
2651  struct iso_hfsplus_xinfo_data *hfsplus_xinfo;
2652  size_t value_length;
2653  char *value;
2654 
2655  action= Findjob_get_action_parms(job, &target, &text_2, &user, &group,
2656  &mode_and, &mode_or, &type, &date, &subjob, 0);
2657  if(action<0)
2658  action= 0;
2659  job->match_count++;
2660 
2661  hflag= 16*!(flag&2);
2662  ret= 1;
2663  if(action==1) { /* rm (including rmdir) */
2664  ret= Xorriso_fake_stbuf(xorriso, abs_path, &dir_stbuf, &node, 1);
2665  if(ret>0) {
2666  if(S_ISDIR(dir_stbuf.st_mode))
2667  hflag= 2;
2668  ret= Xorriso_rmi(xorriso, boss_iter, boss_mem, abs_path, hflag);
2669  deleted= 1;
2670  }
2671  } else if(action==2) { /* rm_r */
2672  ret= Xorriso_rmi(xorriso, boss_iter, boss_mem, abs_path, 1|hflag);
2673  deleted= 1;
2674  } else if(action==3) {
2675 
2676  /* >>> mv target */;
2677 
2678  } else if(action==4) { /* chown */
2679  ret= Xorriso_set_uid(xorriso, abs_path, user, 0);
2680  } else if(action==5) { /* chgrp */
2681  ret= Xorriso_set_gid(xorriso, abs_path, group, 0);
2682  } else if(action==6) { /* chmod */
2683  ret= Xorriso_set_st_mode(xorriso, abs_path, mode_and, mode_or, 0);
2684  } else if(action==7) { /* alter_date */
2685  ret= Xorriso_set_time(xorriso, abs_path, date, type&7);
2686  } else if(action==8) { /* lsdl */
2687  ret= Xorriso_ls_filev(xorriso, "", 1, &abs_path, (off_t) 0, 1|2|8);
2688  } else if(action>=9 && action<=13) { /* actions which have own findjobs */
2689  Findjob_set_start_path(subjob, abs_path, 0);
2690  ret= Xorriso_findi(xorriso, subjob, boss_iter, boss_mem, NULL,
2691  abs_path, &dir_stbuf, depth, 1);
2692  } else if(action==14 || action==17 || action == 41) {
2693  /* compare , update , update_merge */
2694  Findjob_get_start_path(job, &iso_prefix, 0);
2695  ret= Xorriso_find_compare(xorriso, (void *) boss_iter, (void *) node,
2696  abs_path, iso_prefix, target,
2697  (action == 17 || action == 41)
2698  | ((flag&1)<<1) | ((action == 41) << 2));
2699  if(ret==2)
2700  deleted= 1;
2701  if(ret==3)
2702  no_dive= 1;
2703  if(ret>=0)
2704  ret= 1;
2705  } else if(action==16 || action==18) { /* not_in_iso , add_missing */
2706  ;
2707  } else if(action == 21) { /* report_damage */
2708  ret= Xorriso_report_damage(xorriso, show_path, node, 0);
2709  } else if(action == 22) {
2710  ret= Xorriso_report_lba(xorriso, show_path, node,
2711  &job->last_data_file_block, 0);
2712  } else if(action == 23) { /* internal: memorize path of last matching node */
2713  ret= Findjob_set_found_path(job, show_path, 0);
2714  } else if(action == 24) {
2715  ret= Xorriso_getfacl(xorriso, (void *) node, show_path, NULL, 0);
2716  } else if(action == 25) {
2717  if(target == NULL || target[0] || text_2 == NULL || text_2[0])
2718  ret= Xorriso_setfacl(xorriso, (void *) node, show_path, target, text_2,0);
2719  } else if(action == 26) {
2720  ret= Xorriso_getfattr(xorriso, (void *) node, show_path, NULL, 0);
2721  } else if(action == 27) {
2722  ret= Xorriso_path_setfattr(xorriso, (void *) node, show_path,
2723  target, strlen(text_2), text_2, 0);
2724  } else if(action == 28) { /* set_filter */
2725  ret= Xorriso_set_filter(xorriso, (void *) node, show_path, target, 1 | 2);
2726  } else if(action == 29 || action == 52) { /* show_stream , show_stream_id */
2727  ret= Xorriso_show_stream(xorriso, (void *) node, show_path, (action == 52));
2728  } else if(action == 30) { /* internal: count */
2729  xorriso->node_counter++;
2730  } else if(action == 31) { /* internal: register */
2731  if(xorriso->node_counter < xorriso->node_array_size) {
2732  xorriso->node_array[xorriso->node_counter++]= (void *) node;
2733  iso_node_ref(node); /* In case node gets deleted from tree during
2734  the lifetime of xorriso->node_array */
2735  }
2736  } else if(action == 32) { /* internal: widen_hardlinks disk_equiv */
2737  Findjob_get_start_path(job, &iso_prefix, 0);
2738  ret= Xorriso_widen_hardlink(xorriso, (void *) boss_iter, node, abs_path,
2739  iso_prefix, target, 0);
2740  if(ret==2)
2741  deleted= 1;
2742  } else if(action == 33) { /* get_any_xattr */
2743  ret= Xorriso_getfattr(xorriso, (void *) node, show_path, NULL, 8);
2744  } else if(action == 34) { /* get_md5 */
2745  ret= Xorriso_get_md5(xorriso, (void *) node, show_path, md5, 0);
2746  if(ret >= 0)
2747  ret= 1;
2748  } else if(action == 35) { /* check_md5 */
2749  ret= Xorriso_check_md5(xorriso, (void *) node, show_path, 2);
2750  if(ret == 0)
2751  xorriso->find_check_md5_result|= 1;
2752  else if(ret < 0)
2753  xorriso->find_check_md5_result|= 2;
2754  else if(ret == 1)
2755  xorriso->find_check_md5_result|= 8;
2756  else if(ret == 2)
2757  xorriso->find_check_md5_result|= 4;
2758  if(ret >= 0)
2759  ret= 1;
2760  } else if(action == 36) { /* make_md5 */
2761  ret= Xorriso_make_md5(xorriso, (void *) node, show_path, 0);
2762  if(ret >= 0)
2763  ret= 1;
2764  } else if(action == 37) { /* mkisofs_r */
2765  ret= Xorriso_mkisofs_lower_r(xorriso, node, 0);
2766  } else if(action == 38) { /* sort_weight */
2767  iso_node_set_sort_weight(node, type);
2768  Xorriso_set_change_pending(xorriso, 0);
2769  } else if(action == 39) { /* hide */
2770  Xorriso_set_hidden(xorriso, node, NULL, type, 0);
2771  } else if(action == 40) { /* estimate_size */
2772  basename= strrchr(abs_path, '/');
2773  if(basename != NULL)
2774  basename++;
2775  else
2776  basename= abs_path;
2777  ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1);
2778  if(ret > 0)
2779  ret= Xorriso_estimate_file_size(xorriso, job, basename, stbuf.st_mode,
2780  stbuf.st_size, 0);
2781  } else if(action == 42) { /* rm_merge */
2782  ret= Xorriso_mark_update_merge(xorriso, show_path, node, 2 | 4);
2783  if(ret == 2) {
2784  ret= Xorriso_rmi(xorriso, boss_iter, boss_mem, abs_path, 1|hflag);
2785  sprintf(xorriso->info_text, "Deleted ");
2786  Text_shellsafe(show_path, xorriso->info_text, 1);
2787  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
2788  deleted= 1;
2789  }
2790  } else if(action == 43) { /* clear_merge */
2791  ret= Xorriso_mark_update_merge(xorriso, show_path, node, 2 | 4);
2792  } else if(action == 44) { /* list_extattr */
2793  ret= Xorriso_list_extattr(xorriso, (void *) node, show_path, show_path,
2794  target, 0);
2795  } else if(action == 45) { /* set_hfs_crtp */
2796  ret= Xorriso_hfsplus_file_creator_type(xorriso, show_path, (void *) node,
2797  target, text_2, 0);
2798 
2799  } else if(action == 46) { /* get_hfs_crtp */
2800  ret= iso_node_get_xinfo(node, iso_hfsplus_xinfo_func, &xinfo);
2801  if(ret < 0) {
2802  Xorriso_process_msg_queues(xorriso, 0);
2803  ret= 0;
2804  } else if(ret == 1) {
2805  hfsplus_xinfo= (struct iso_hfsplus_xinfo_data *) xinfo;
2806  for(i= 0; i < 4; i++)
2807  xorriso->result_line[i]= hfsplus_xinfo->creator_code[i];
2808  xorriso->result_line[4]= ' ';
2809  for(i= 0; i < 4; i++)
2810  xorriso->result_line[5 + i]= hfsplus_xinfo->type_code[i];
2811  xorriso->result_line[9]= ' ';
2812  xorriso->result_line[10]= 0;
2813  Text_shellsafe(show_path, xorriso->result_line, 1);
2814  strcat(xorriso->result_line, "\n");
2815  Xorriso_result(xorriso, 0);
2816  }
2817  ret= 1;
2818  } else if(action == 47) { /* set_hfs_bless */
2819  if(strcmp(target, "none") == 0 ||
2820  strcmp(target, "n") == 0 || strcmp(target, "N") == 0) {
2821  ret= Xorriso_get_blessing(xorriso, node, &bless_idx, bless_code, 0);
2822  if(ret < 0)
2823  return(ret);
2824  if(ret == 0)
2825  return(1);
2826  unbless= 1;
2827  }
2828  ret= Xorriso_hfsplus_bless(xorriso, show_path, (void *) node, target, 0);
2829  /* If successful, end -find run gracefully */
2830  if(ret > 0) {
2831  if(unbless) {
2832  sprintf(xorriso->info_text, "HFS blessing '%s' revoked from ",
2833  bless_code);
2834  } else {
2835  sprintf(xorriso->info_text, "HFS blessing '%s' issued to ", target);
2836  }
2837  Text_shellsafe(show_path, xorriso->info_text, 1);
2838  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2839  }
2840  if(!unbless)
2841  return(4);
2842  } else if(action == 48) { /* get_hfs_bless */
2843  ret= Xorriso_get_blessing(xorriso, node, &bless_idx, bless_code, 0);
2844  if (ret > 0) {
2845  sprintf(xorriso->result_line, "%-16.16s ", bless_code);
2846  Text_shellsafe(show_path, xorriso->result_line, 1);
2847  strcat(xorriso->result_line, "\n");
2848  Xorriso_result(xorriso, 0);
2849  } else if(ret == 0)
2850  ret= 1;
2851  } else if(action == 49) {
2852  /* internal: update creator, type, and blessings from persistent isofs.* */
2853  ret= Xorriso_get_attr_value(xorriso, node, show_path, "isofs.hx",
2854  &value_length, &value, 0);
2855  if(ret < 0)
2856  return(ret);
2857  if(ret > 0) {
2858  if(value_length >= 10) {
2859  ret= Xorriso_hfsplus_file_creator_type(xorriso, show_path,
2860  (void *) node,
2861  value + 2, value + 6, 4);
2862  } else
2863  ret= 1;
2864  free(value);
2865  if(ret <= 0)
2866  return(ret);
2867  }
2868  ret= Xorriso_get_attr_value(xorriso, node, show_path, "isofs.hb",
2869  &value_length, &value, 0);
2870  if(ret < 0)
2871  return(ret);
2872  if(ret > 0) {
2873  if(value_length >= 1) {
2874  bless_code[0]= value[0];
2875  bless_code[1]= 0;
2876  ret= Xorriso_hfsplus_bless(xorriso, show_path, (void *) node,
2877  bless_code, 0);
2878  } else
2879  ret= 1;
2880  free(value);
2881  if(ret <= 0)
2882  return(ret);
2883  }
2884  ret= 1;
2885 
2886  } else if(action == 50) { /* print_outname */
2887  ret= Xorriso_test_outchar(xorriso, (void *) node, type, 1);
2888  if(ret <= 0)
2889  return(ret);
2890 
2891  } else if(action == 51) { /* report_sections */
2892  ret= Xorriso_report_lba(xorriso, show_path, node,
2893  &job->last_data_file_block, 1);
2894 
2895  } else if(action == 53) { /* internal: show_hfs_cmd */
2896  ret= Xorriso_get_blessing(xorriso, node, &bless_idx, bless_code, 0);
2897  if (ret > 0) {
2898  if(xorriso->show_hfs_cmd_flag & 2) {
2899  sprintf(xorriso->result_line, "-hfs-bless-by %s ", bless_code);
2900  Text_shellsafe(show_path, xorriso->result_line, 1);
2901  } else {
2902  sprintf(xorriso->result_line, "-find ");
2903  Text_shellsafe(show_path, xorriso->result_line, 1);
2904  sprintf(xorriso->result_line + strlen(xorriso->result_line),
2905  " -exec set_hfs_bless %s --", bless_code);
2906  }
2907  ret= Xorriso_record_cmd_line(xorriso, xorriso->result_line,
2908  xorriso->show_hfs_cmds,
2909  &xorriso->show_hfs_cmd_count,
2910  (xorriso->show_hfs_cmd_flag & 1));
2911  if(ret <= 0)
2912  return(ret);
2913  }
2914  ret= iso_node_get_xinfo(node, iso_hfsplus_xinfo_func, &xinfo);
2915  if(ret < 0) {
2916  Xorriso_process_msg_queues(xorriso, 0);
2917  ret= 0;
2918  } else if(ret == 1) {
2919  hfsplus_xinfo= (struct iso_hfsplus_xinfo_data *) xinfo;
2920  for(i= 0; i < 4; i++)
2921  crtp[i]= hfsplus_xinfo->creator_code[i];
2922  crtp[4]= ' ';
2923  for(i= 0; i < 4; i++)
2924  crtp[5 + i]= hfsplus_xinfo->type_code[i];
2925  crtp[9]= 0;
2926  if(xorriso->show_hfs_cmd_flag & 2) {
2927  sprintf(xorriso->result_line, "-hfsplus-file-creator-type %s ", crtp);
2928  Text_shellsafe(show_path, xorriso->result_line, 1);
2929  } else {
2930  sprintf(xorriso->result_line, "-find ");
2931  Text_shellsafe(show_path, xorriso->result_line, 1);
2932  sprintf(xorriso->result_line + strlen(xorriso->result_line),
2933  " -exec set_hfs_crtp %s --", crtp);
2934  }
2935  ret= Xorriso_record_cmd_line(xorriso, xorriso->result_line,
2936  xorriso->show_hfs_cmds,
2937  &xorriso->show_hfs_cmd_count,
2938  (xorriso->show_hfs_cmd_flag & 1));
2939  if(ret <= 0)
2940  return(ret);
2941  }
2942  ret= 1;
2943 
2944  } else if(action == 54 || action == 56) { /* internal: truncate_name */
2945  ret= Xorriso_truncate_uniquely(xorriso, xorriso->file_name_limit,
2946  node, abs_path, show_path,
2947  2 * (action == 56));
2948 
2949  } else if(action == 55 || action == 57) {
2950  /* internal: unique_trunc_test length (in type) */
2951  ret= Xorriso_truncate_uniquely(xorriso, type, node, abs_path, show_path,
2952  1 | (2 * (action == 57)));
2953 
2954  } else if(action == 58) { /* internal: last_data_file_block */
2955  ret= Xorriso_report_lba(xorriso, show_path, node,
2956  &job->last_data_file_block, 2);
2957 
2958  } else if(action == 59) { /* set_to_mtime */
2959  ret= Xorriso_set_to_mtime(xorriso, show_path, node, 0);
2960 
2961  } else { /* includes : 15 in_iso */
2962  Xorriso_esc_filepath(xorriso, show_path, xorriso->result_line, 0);
2963  strcat(xorriso->result_line, "\n");
2964  Xorriso_result(xorriso, 0);
2965  ret= 1;
2966  }
2967  if(ret<=0)
2968  return(ret);
2969  if(deleted)
2970  return(2);
2971  if(no_dive)
2972  return(3);
2973  return(1);
2974 }
2975 
2976 
2977 /* flag bit0= perform -disk_path rather than -disk_name
2978  bit0= use_pattern
2979 */
2980 int Exprtest_match_disk_name(struct XorrisO *xorriso, struct ExprtesT *ftest,
2981  IsoNode *node, int flag)
2982 
2983 {
2984  int ret;
2985  char *disk_path= NULL, *npt;
2986  regmatch_t name_match;
2987  char *arg1;
2988  void *arg2;
2989 
2990  Xorriso_alloc_meM(disk_path, char, SfileadrL);
2991 
2992  ret= Xorriso_retrieve_disk_path(xorriso, node, disk_path, 0);
2993  if(ret <= 0)
2994  {ret= 0; goto ex;}
2995  if(flag & 1) {
2996  if(strcmp(disk_path, ftest->arg1) == 0)
2997  {ret= 1; goto ex;}
2998  {ret= 0; goto ex;}
2999  }
3000  arg1= (char *) ftest->arg1;
3001  arg2= ftest->arg2;
3002  npt= strrchr(disk_path, '/');
3003  if(npt != NULL)
3004  npt++;
3005  else
3006  npt= disk_path;
3007  if(flag & 2) {
3008  ret= ! regexec(arg2, npt, 1, &name_match, 0);
3009  } else {
3010  ret= (strcmp(arg1, npt) == 0);
3011  }
3012 ex:;
3013  Xorriso_free_meM(disk_path);
3014  return(ret);
3015 }
3016 
3017 
3018 int Exprtest_match(struct XorrisO *xorriso, struct ExprtesT *ftest,
3019  void *node_pt, char *name, char *path,
3020  struct stat *boss_stbuf, struct stat *stbuf, int flag)
3021 /*
3022 return:
3023  <0 = error
3024  0 = does not match
3025  1 = does match
3026  2 = immediate decision : does not match
3027  3 = immediate decision : does match
3028 */
3029 {
3030  int value=0, ret, start_lba, end_lba, bless_idx;
3031  int lba_count, *file_end_lbas= NULL, *file_start_lbas= NULL, i, mask;
3032  void *arg1, *arg2;
3033  char ft, *decision, md5[16], bless_code[17];
3034  regmatch_t name_match;
3035  off_t damage_start, damage_end, size, *section_sizes= NULL;
3036  void *xinfo_dummy;
3037  IsoNode *node;
3038  IsoStream *stream;
3039  struct iso_hfsplus_xinfo_data *hfsplus_xinfo;
3040 
3041  if(ftest == NULL)
3042  return(1);
3043 
3044  node= (IsoNode *) node_pt;
3045  arg1= ftest->arg1;
3046  arg2= ftest->arg2;
3047 
3048  if(node == NULL) {
3049  switch(ftest->test_type) {
3050  case 0: case 1: case 2: case 4: case 11: case 12: case 13:
3051  case 22: case 23: case 25: case 26:
3052  /* Tests which need no node parameter */
3053  break;
3054  default:
3055  value= 0;
3056  goto ex;
3057  }
3058  }
3059 
3060  switch(ftest->test_type) {
3061  case 0: /* -false */
3062  value= 0;
3063 
3064  break; case 1: /* -name *arg1 (regex in *arg2) */
3065  if (ftest->boss->use_pattern) {
3066  ret= regexec(arg2, name, 1, &name_match, 0);
3067  value= !ret;
3068  } else {
3069  value= (strcmp((char *) arg1, name) == 0);
3070  }
3071 
3072  break; case 2: /* -type *arg1 */
3073  value= 1;
3074  ft= *((char *) arg1);
3075  if(ft!=0) {
3076  if(S_ISBLK(stbuf->st_mode)) {
3077  if(ft!='b')
3078  value= 0;
3079  } else if(S_ISCHR(stbuf->st_mode)) {
3080  if(ft!='c')
3081  value= 0;
3082  } else if(S_ISDIR(stbuf->st_mode)) {
3083  if(ft=='m') {
3084  if(node != NULL)
3085  value= 0;
3086  else if(boss_stbuf==NULL)
3087  value= 0;
3088  else if(boss_stbuf->st_dev == stbuf->st_dev)
3089  value= 0;
3090  } else if(ft!='d')
3091  value= 0;
3092  } else if(S_ISFIFO(stbuf->st_mode)) {
3093  if(ft!='p')
3094  value= 0;
3095  } else if(S_ISREG(stbuf->st_mode)) {
3096  if(ft!='f' && ft!='-')
3097  value= 0;
3098  } else if(((stbuf->st_mode)&S_IFMT)==S_IFLNK) {
3099  if(ft!='l')
3100  value= 0;
3101  } else if(((stbuf->st_mode)&S_IFMT)==S_IFSOCK) {
3102  if(ft!='s')
3103  value= 0;
3104  } else if((flag & 1) && ((stbuf->st_mode) & S_IFMT) == Xorriso_IFBOOT) {
3105  if(ft!='e' || node == NULL)
3106  value= 0;
3107  } else {
3108  if(ft!='X')
3109  value= 0;
3110  }
3111  }
3112 
3113  break; case 3: /* -damaged */;
3114  value= Xorriso_file_eval_damage(xorriso, node, &damage_start, &damage_end,
3115  0);
3116  if(value > 0)
3117  value= 1;
3118 
3119  break; case 4: /* -lba_range *arg1 *arg2 */
3120  value= 1;
3121  start_lba= *((int *) ftest->arg1);
3122  end_lba= *((int *) ftest->arg2);
3123  if(node == NULL) {
3124  value= !(start_lba >= 0);
3125  goto ex;
3126  }
3127  ret= Xorriso__start_end_lbas(node, &lba_count, &file_start_lbas,
3128  &file_end_lbas, &section_sizes, &size, 0);
3129  if(ret <= 0) {
3130  if(ret < 0)
3131  Xorriso_process_msg_queues(xorriso, 0);
3132  if(start_lba >= 0)
3133  value= 0;
3134  } else {
3135  for(i= 0; i < lba_count; i++) {
3136  if(start_lba >= 0) {
3137  if(file_end_lbas[i] < start_lba || file_start_lbas[i] > end_lba)
3138  value= 0;
3139  } else {
3140  if(file_end_lbas[i] >= -start_lba && file_start_lbas[i] <= -end_lba)
3141  value= 0;
3142  }
3143  }
3144  }
3145 
3146  break; case 5: /* -has_acl */
3147  ret = Xorriso_getfacl(xorriso, (void *) node, "", NULL, 2);
3148  if(ret <= 0) {
3149  value= -1;
3150  Xorriso_process_msg_queues(xorriso, 0);
3151  goto ex;
3152  }
3153  value= (ret == 1);
3154 
3155  break; case 6: /* -has_xattr */
3156  case 14: /* -has_any_xattr */
3157  ret = Xorriso_getfattr(xorriso, (void *) node, "", NULL,
3158  64 | (8 * (ftest->test_type == 14)));
3159  if(ret < 0) {
3160  value= -1;
3161  Xorriso_process_msg_queues(xorriso, 0);
3162  goto ex;
3163  }
3164  value= (ret > 0);
3165 
3166  break; case 7: /* -has_aaip */
3167  ret= iso_node_get_xinfo(node, aaip_xinfo_func, &xinfo_dummy);
3168  if(ret < 0) {
3169  value= -1;
3170  Xorriso_process_msg_queues(xorriso, 0);
3171  goto ex;
3172  }
3173  value= (ret > 0);
3174 
3175  break; case 8: /* -has_filter */
3176  value= 0;
3177  if(LIBISO_ISREG(node)) {
3178  stream= iso_file_get_stream((IsoFile *) node);
3179  if(iso_stream_get_input_stream(stream, 0) != NULL)
3180  value= 1;
3181  }
3182 
3183  break; case 9: /* -wanted_node arg1 (for internal use) */
3184  value= (((IsoNode *) arg1) == node);
3185 
3186  break; case 10: /* -pending_data */
3187  value= 1;
3188  if(!LIBISO_ISREG(node)) {
3189  value= 0;
3190  } else {
3191  ret= Xorriso__file_start_lba(node, &start_lba, 0);
3192  if(ret > 0 && start_lba >= 0)
3193  value= 0;
3194  }
3195 
3196  break; case 11: /* -decision */
3197  value= 2;
3198  decision= (char *) arg1;
3199  if(strcmp(decision, "yes") == 0 || strcmp(decision, "true") == 0)
3200  value= 3;
3201 
3202  break; case 12: /* -prune */
3203  value= 1;
3204  ftest->boss->prune= 1;
3205 
3206  break; case 13: /* -wholename *arg1 (regex in *arg2) */
3207  if (ftest->boss->use_pattern) {
3208  ret= regexec(arg2, path, 1, &name_match, 0);
3209  value= !ret;
3210  } else {
3211  value= (strcmp(arg1, path) == 0);
3212  }
3213 
3214  break; case 15: /* -has_md5 */
3215  ret= Xorriso_get_md5(xorriso, node, path, md5, 1);
3216  value= (ret > 0);
3217 
3218  break; case 16: /* -disk_name *arg1 (regex in *arg2) */
3219  value= !! Exprtest_match_disk_name(xorriso, ftest, node,
3220  2 * (ftest->boss->use_pattern));
3221 
3222  break; case 17: /* -hidden int *arg1 */
3223  value= 1;
3224  ret= iso_node_get_hidden(node);
3225  mask= *((int *) arg1) & 3;
3226  if((!!(mask & 1)) ^ (!!(ret & LIBISO_HIDE_ON_RR)))
3227  value= 0;
3228  if((!!(mask & 2)) ^ (!!(ret & LIBISO_HIDE_ON_JOLIET)))
3229  value= 0;
3230  if((!!(mask & 3)) ^ (!!(ret & LIBISO_HIDE_ON_HFSPLUS)))
3231  value= 0;
3232 
3233  break; case 18: /* -has_hfs_crtp char *creator char *type */
3234  ret= iso_node_get_xinfo(node, iso_hfsplus_xinfo_func, &xinfo_dummy);
3235  value= 0;
3236  if(ret < 0) {
3237  Xorriso_process_msg_queues(xorriso, 0);
3238  ret= 0;
3239  } else if(ret == 1) {
3240  hfsplus_xinfo= (struct iso_hfsplus_xinfo_data *) xinfo_dummy;
3241  if((strlen(arg1) == 1 ||
3242  (strncmp(arg1, (char *) hfsplus_xinfo->creator_code, 4) == 0 &&
3243  strlen(arg1) == 4)) &&
3244  (strlen(arg2) == 1 ||
3245  (strncmp(arg2, (char *) hfsplus_xinfo->type_code, 4) == 0 &&
3246  strlen(arg2) == 4)))
3247  value= 1;
3248  }
3249 
3250  break; case 19: /* -has_hfs_bless int bless_index */
3251  value= 0;
3252  ret= Xorriso_get_blessing(xorriso, node, &bless_idx, bless_code, 0);
3253  if (ret > 0) {
3254  if(*((int *) arg1) == (int) ISO_HFSPLUS_BLESS_MAX ||
3255  *((int *) arg1) == bless_idx)
3256  value= 1;
3257  }
3258 
3259  break; case 20: /* -disk_path */
3260  value= !! Exprtest_match_disk_name(xorriso, ftest, node,
3261  1 | 2 * (ftest->boss->use_pattern));
3262 
3263  break; case 21: /* -bad_outname */
3264  ret= Xorriso_test_outchar(xorriso, node, *((int *) arg1), 0);
3265  if(ret < 0) {
3266  value= -1;
3267  goto ex;
3268  }
3269  value= !ret; /* Xorriso_test_outchar() returns 1 for good and 0 for bad */
3270 
3271  break; case 22: /* -use_pattern */
3272  ftest->boss->use_pattern= (strcmp(arg1, "off") != 0);
3273  value= 1;
3274 
3275  break; case 23: /* -or_use_pattern */
3276  ftest->boss->use_pattern= (strcmp(arg1, "off") != 0);
3277  value= 0;
3278 
3279  break; case 24: /* -name_limit_blocker */
3280  ret= Xorriso_truncate_uniquely(xorriso, *((int *) arg1), node, path, path,
3281  1 | 4);
3282  value= (ret == 0);
3283 
3284  break; case 25: /* -maxdepth */
3285  value= (ftest->boss->depth <= *((int *) arg1));
3286 
3287  break; case 26: /* -mindepth */
3288  value= (ftest->boss->depth >= *((int *) arg1));
3289 
3290  break; default:
3291 
3292  /* >>> complain about unknown test type */;
3293 
3294  value= -1;
3295 
3296  }
3297 
3298 ex:;
3299  if(ftest->invert && value<=1 && value>=0)
3300  value= !value;
3301  if(file_start_lbas != NULL)
3302  free((char *) file_start_lbas);
3303  if(file_end_lbas != NULL)
3304  free((char *) file_end_lbas);
3305  if(section_sizes != NULL)
3306  free((char *) section_sizes);
3307  return(value);
3308 }
3309 
3310 
3311 /* @return <0 = error , 0 = no match , 1 = match */
3312 int Xorriso_findi_test(struct XorrisO *xorriso, struct FindjoB *job,
3313  IsoNode *node, char *name, char *path,
3314  struct stat *boss_stbuf, struct stat *stbuf,
3315  int depth, int flag)
3316 {
3317  int ret;
3318 
3319  job->prune= 0;
3320  ret= Findjob_test_2(xorriso, job, node, name, path, boss_stbuf, stbuf, 1);
3321  if(ret <= 0)
3322  return(ret);
3323  return(1);
3324 }
3325 
3326 
3327 int Xorriso_findi_headline(struct XorrisO *xorriso, struct FindjoB *job,
3328  int flag)
3329 {
3330  int action;
3331 
3332  action= Findjob_get_action(job, 0);
3333  if(action == 21) { /* report_damage */
3334  sprintf(xorriso->result_line, "Report layout: %8s , %8s , %8s , %s\n",
3335  "at byte", "Range", "Filesize", "ISO image path");
3336  Xorriso_result(xorriso, 0);
3337  } else if(action == 22 || action == 51) { /* report_lba, report_sections */
3338  sprintf(xorriso->result_line,
3339  "Report layout: %2s , %8s , %8s , %8s , %s\n",
3340  "xt", "Startlba", "Blocks", action == 22 ? "Filesize" : "Sectsize",
3341  "ISO image path");
3342  Xorriso_result(xorriso, 0);
3343  }
3344  return(1);
3345 }
3346 
3347 
3348 /* @param flag bit0= recursion
3349  bit1= do not count deleted files with rm and rm_r
3350  bit2= do not dive into split file directories
3351  (implicitly given with actions 14=compare and 17=update)
3352  @return <=0 error, 1= ok , 2= dir node and path has been deleted
3353  4= end gracefully
3354 */
3355 int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job,
3356  void *boss_iter, off_t boss_mem,
3357  void *dir_node_generic, char *dir_path,
3358  struct stat *dir_stbuf, int depth, int flag)
3359 {
3360  int ret, action= 0, hflag, deleted= 0, no_dive= 0;
3361  IsoDirIter *iter= NULL;
3362  IsoDir *dir_node= NULL;
3363  IsoNode *node, *iso_node;
3364  IsoImage *volume= NULL;
3365  struct stat stbuf;
3366  char *name;
3367  off_t mem;
3368  IsoNode **node_array= NULL;
3369  int node_count= 0, node_idx;
3370  char *path= NULL, *abs_path= NULL;
3371 
3372  job->depth= depth;
3373 
3374  if(xorriso->request_to_abort)
3375  {ret= 0; goto ex;}
3376 
3377  path= malloc(SfileadrL);
3378  abs_path= malloc(SfileadrL);
3379  if(path==NULL || abs_path==NULL) {
3380  Xorriso_no_malloc_memory(xorriso, &path, 0);
3381  {ret= -1; goto ex;}
3382  }
3383 
3384  action= Findjob_get_action(job, 0);
3385  if(action<0)
3386  action= 0;
3387  if(!(flag & 1)) {
3388  Xorriso_findi_headline(xorriso, job, 0);
3389  job->last_data_file_block= 0;
3390  }
3391 
3392  dir_node= (IsoDir *) dir_node_generic;
3393  if(dir_node==NULL) {
3394  ret= Xorriso_get_volume(xorriso, &volume, 0);
3395  if(ret<=0)
3396  {ret= -1; goto ex;}
3397  ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, dir_path, path, 1|2|4);
3398  if(ret<=0)
3399  goto ex;
3400  ret= Xorriso_node_from_path(xorriso, volume, path, &iso_node, 0);
3401  dir_node= (IsoDir *) iso_node;
3402  if(ret<=0)
3403  {ret= 0; goto ex;}
3404  ret= Xorriso_fake_stbuf(xorriso, "", dir_stbuf, &iso_node, 1);
3405  if(ret<=0)
3406  goto ex;
3407 
3408  name= strrchr(dir_path, '/');
3409  if(name==NULL)
3410  name= dir_path;
3411  else
3412  name++;
3413 
3414  ret= Xorriso_findi_test(xorriso, job, iso_node, name, path, NULL, dir_stbuf,
3415  depth, 0);
3416  if(ret<0)
3417  goto ex;
3418  if(job->prune)
3419  no_dive= 1;
3420  if(ret>0) {
3421  iso_node_ref(iso_node); /* protect from real disposal */
3422  ret= Xorriso_findi_action(xorriso, job,
3423  (IsoDirIter *) boss_iter, boss_mem,
3424  path, dir_path, iso_node, depth,
3425  flag&(1|2));
3426  deleted= (iso_node_get_parent(iso_node) == NULL); /* still in tree ? */
3427  iso_node_unref(iso_node); /* eventually do real disposal */
3428  if(xorriso->request_to_abort)
3429  {ret= 0; goto ex;}
3430  if(ret == 4)
3431  goto ex;
3432  if(ret<=0)
3433  goto ex;
3434  if(ret==2 || deleted) {
3435  /* re-determine dir_node in case it has a new persona */
3436  ret= Xorriso_node_from_path(xorriso, volume, path, &iso_node, 1);
3437  if(ret==0) {
3438  deleted= 1;
3439  {ret= 2; goto ex;}
3440  }
3441  if(ret<0)
3442  {ret= 0; goto ex;}
3443  dir_node= (IsoDir *) iso_node;
3444  ret= Xorriso_fake_stbuf(xorriso, "", dir_stbuf, &iso_node, 1);
3445  if(ret<=0)
3446  goto ex;
3447  }
3448  if(ret==3)
3449  no_dive= 1;
3450  }
3451  }
3452  if(no_dive || !LIBISO_ISDIR((IsoNode *) dir_node))
3453  {ret= 1; goto ex;}
3454  if(action == 14 || action == 17 || (flag & 4))
3455  if(Xorriso_is_split(xorriso, dir_path, (IsoNode *) dir_node, 1)>0)
3456  {ret= 1; goto ex;}
3457 
3458  mem= boss_mem;
3459  hflag= 1;
3460  if(action==1 || action==2 || action==3 || action==17 || action == 28 ||
3461  action == 32 || action == 41 || action == 42)
3462  hflag|= 2; /* need freedom to manipulate image */
3463  if(action==14 || action==17 || action == 28 || action == 35 || action == 36 ||
3464  action == 41)
3465  hflag|= 4; /* need LBA sorted iteration for good data reading performance */
3466  ret= Xorriso_findi_iter(xorriso, dir_node, &mem,
3467  &iter, &node_array, &node_count, &node_idx,
3468  &node, hflag);
3469  if(ret<=0)
3470  goto ex;
3471  job->depth++;
3472  while(1) {
3473  ret= Xorriso_findi_iter(xorriso, dir_node, &mem, &iter,
3474  &node_array, &node_count, &node_idx, &node, 0);
3475  if(ret<0)
3476  goto ex;
3477  if(ret==0)
3478  break;
3479  name= (char *) iso_node_get_name(node);
3480  ret= Xorriso_make_abs_adr(xorriso, dir_path, name, path, 4);
3481  if(ret<=0)
3482  goto ex;
3483  ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1);
3484  if(ret<0)
3485  goto ex;
3486  if(ret==0)
3487  continue;
3488 
3489 /* ??? This seems to be redundant with the single test above
3490  ??? Should i dive in unconditionally and leave out test and action here ?
3491  ??? Then do above test unconditionally ?
3492  --- Seems that the current configuration represents the special
3493  handling of the find start path with mount points. Dangerous to change.
3494 */
3495 
3496  ret= Xorriso_findi_test(xorriso, job, node, name, path, dir_stbuf, &stbuf,
3497  depth, 0);
3498  if(ret<0)
3499  goto ex;
3500  if(job->prune)
3501  no_dive= 1;
3502  if(ret>0) {
3503  ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, path, abs_path, 1|2|4);
3504  if(ret<=0)
3505  goto ex;
3506  ret= Xorriso_findi_action(xorriso, job, iter, mem,
3507  abs_path, path, node, depth, 1|(flag&2));
3508  if(xorriso->request_to_abort)
3509  {ret= 0; goto ex;}
3510  if(ret == 4)
3511  goto ex;
3512  if(ret==2) { /* node has been deleted */
3513  /* re-determine node in case it has a new persona */
3514  if(volume==NULL) {
3515  ret= Xorriso_get_volume(xorriso, &volume, 0);
3516  if(ret<=0)
3517  {ret= -1; goto ex;}
3518  }
3519  ret= Xorriso_node_from_path(xorriso, volume, abs_path, &node, 1);
3520  if(ret==0)
3521  continue;
3522  if(ret<0)
3523  {ret= 0; goto ex;}
3524  ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1);
3525  if(ret<0)
3526  goto ex;
3527  if(ret==0)
3528  continue;
3529  }
3530  no_dive= (ret==3);
3531  if(ret<=0) {
3532  if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0)
3533  goto ex;
3534  }
3535  }
3536 
3537  if(S_ISDIR(stbuf.st_mode) && !no_dive) {
3538  ret= Xorriso_findi(xorriso, job, (void *) iter, mem,
3539  (void *) node, path, &stbuf, depth+1, flag|1);
3540  if(ret<0)
3541  goto ex;
3542  if(xorriso->request_to_abort)
3543  {ret= 0; goto ex;}
3544  if(ret == 4)
3545  goto ex;
3546  }
3547  }
3548 
3549  ret= 1;
3550 ex:;
3551  job->depth= depth;
3552  if(path!=NULL)
3553  free(path);
3554  if(abs_path!=NULL)
3555  free(abs_path);
3556  Xorriso_process_msg_queues(xorriso,0);
3557 
3558  Xorriso_findi_iter(xorriso, dir_node, &mem, &iter, &node_array, &node_count,
3559  &node_idx, &node, (1u<<31));
3560  if(ret<=0)
3561  return(ret);
3562  if(deleted)
3563  return(2);
3564  return(1);
3565 }
3566 
3567 
3568 /* @param flag bit0= do not dive into trees
3569  bit1= do not perform job->action on resulting node array
3570  bit2= do not free node_array after all actions are done
3571 */
3572 int Xorriso_findi_sorted(struct XorrisO *xorriso, struct FindjoB *job,
3573  off_t boss_mem, int filec, char **filev, int flag)
3574 {
3575  int i, ret, find_flag= 0;
3576  struct FindjoB array_job, *proxy_job= NULL, *hindmost= NULL, *hmboss= NULL;
3577  struct stat dir_stbuf;
3578  IsoNode *node;
3579  char *abs_path= NULL;
3580  off_t mem_needed= 0;
3581 
3582  array_job.start_path= NULL;
3583 
3584  Xorriso_alloc_meM(abs_path, char, SfileadrL);
3585 
3586  if(job->action == 14 || job->action == 17)
3587  find_flag|= 4;
3588  if(job->action>=9 && job->action<=13) { /* actions which have own findjobs */
3589  /* array_job replaces the hindmost job in the chain */
3590  for(hindmost= job; hindmost->subjob != NULL; hindmost= hindmost->subjob)
3591  hmboss= hindmost;
3592  if(hmboss == NULL)
3593  {ret= -1; goto ex;}
3594  memcpy(&array_job, hindmost, sizeof(struct FindjoB));
3595  hmboss->subjob= &array_job;
3596  proxy_job= job;
3597  } else {
3598  memcpy(&array_job, job, sizeof(struct FindjoB));
3599  proxy_job= &array_job;
3600  hindmost= job;
3601  }
3602  array_job.start_path= NULL; /* is owned by the original, not by array_job */
3603 
3604  /* Count matching nodes */
3605  Xorriso_destroy_node_array(xorriso, 0);
3606  array_job.action= 30; /* internal: count */
3607  for(i= 0; i < filec; i++) {
3608  if(flag & 1) {
3609  xorriso->node_counter++;
3610  continue;
3611  }
3612  ret= Findjob_set_start_path(proxy_job, filev[i], 0);
3613  if(ret <= 0)
3614  goto ex;
3615  ret= Xorriso_findi(xorriso, proxy_job, NULL, boss_mem, NULL,
3616  filev[i], &dir_stbuf, 0, find_flag);
3617  if(ret <= 0)
3618  goto ex;
3619  }
3620  if(xorriso->node_counter <= 0)
3621  {ret= 1; goto ex;}
3622 
3623  mem_needed= boss_mem + xorriso->node_counter * sizeof(IsoNode *);
3624  if(!(flag &1)) {
3625  ret= Xorriso_check_temp_mem_limit(xorriso, mem_needed, 0);
3626  if(ret <= 0) {
3627  /* Memory curbed : Perform unsorted find jobs */
3628  if(hmboss != NULL)
3629  hmboss->subjob= hindmost;
3630  for(i= 0; i < filec; i++) {
3631  ret= Findjob_set_start_path(job, filev[i], 0);
3632  if(ret <= 0)
3633  goto ex;
3634  ret= Xorriso_findi(xorriso, job, NULL, boss_mem, NULL,
3635  filev[i], &dir_stbuf, 0, find_flag);
3636  if(ret <= 0)
3637  if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0)
3638  goto ex;
3639  }
3640  {ret= 1; goto ex;}
3641  }
3642  }
3643 
3644  /* Copy matching nodes into allocated array */
3645  ret= Xorriso_new_node_array(xorriso, xorriso->temp_mem_limit, 0, 0);
3646  if(ret <= 0)
3647  goto ex;
3648  array_job.action= 31; /* internal: register */
3649  xorriso->node_counter= 0;
3650  for(i= 0; i < filec; i++) {
3651  if(flag & 1) {
3652  ret= Xorriso_get_node_by_path(xorriso, filev[i], NULL, &node, 0);
3653  if(ret <= 0)
3654  goto ex;
3655  if(xorriso->node_counter < xorriso->node_array_size) {
3656  xorriso->node_array[xorriso->node_counter++]= (void *) node;
3657  iso_node_ref(node);
3658  }
3659  continue;
3660  }
3661  ret= Findjob_set_start_path(proxy_job, filev[i], 0);
3662  if(ret <= 0)
3663  goto ex;
3664  ret= Xorriso_findi(xorriso, proxy_job, NULL, mem_needed, NULL,
3665  filev[i], &dir_stbuf, 0, find_flag);
3666  if(ret <= 0)
3667  goto ex;
3668  }
3669 
3670  Xorriso_sort_node_array(xorriso, 0);
3671  if(flag & 2)
3672  {ret= 1; goto ex;}
3673 
3674  /* Perform job->action on xorriso->node_array */
3675 
3676  /* Headlines of actions report_damage , report_lba */;
3677  Xorriso_findi_headline(xorriso, job, 0);
3678 
3679  for(i= 0; i < xorriso->node_counter; i++) {
3680  node= xorriso->node_array[i];
3681  ret= Xorriso_path_from_node(xorriso, node, abs_path, 0);
3682  if(ret < 0)
3683  goto ex;
3684  if(ret == 0)
3685  continue; /* node is deleted from tree meanwhile */
3686 
3687  ret= Xorriso_findi_action(xorriso, hindmost, NULL, (off_t) 0,
3688  abs_path, abs_path, node, 0, 1);
3689  if(ret <= 0 || xorriso->request_to_abort)
3690  if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0)
3691  goto ex;
3692  if(ret == 4) /* end gracefully */
3693  break;
3694  }
3695 
3696  ret= 1;
3697 ex:;
3698  if(!(flag & (2 | 4)))
3699  Xorriso_destroy_node_array(xorriso, 0);
3700  if(hmboss != NULL)
3701  hmboss->subjob= hindmost;
3702  if(array_job.start_path != NULL)
3703  free(array_job.start_path);
3704  Xorriso_free_meM(abs_path);
3705  return(ret);
3706 }
3707 
3708 
3709 int Xorriso_all_node_array(struct XorrisO *xorriso, int addon_nodes, int flag)
3710 {
3711  int ret;
3712  struct FindjoB *job= NULL;
3713  struct stat dir_stbuf;
3714 
3715  ret= Findjob_new(&job, "/", 0);
3716  if(ret<=0) {
3717  Xorriso_no_findjob(xorriso, "xorriso", 0);
3718  {ret= -1; goto ex;}
3719  }
3720  Findjob_set_action_target(job, 30, NULL, 0);
3721  Xorriso_destroy_node_array(xorriso, 0);
3722  ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, NULL, "/",
3723  &dir_stbuf, 0, 0);
3724  if(ret <= 0)
3725  goto ex;
3726  ret= Xorriso_new_node_array(xorriso, xorriso->temp_mem_limit, addon_nodes, 0);
3727  if(ret <= 0)
3728  goto ex;
3729  Findjob_set_action_target(job, 31, NULL, 0);
3730  ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, NULL, "/",
3731  &dir_stbuf, 0, 0);
3732  if(ret <= 0)
3733  goto ex;
3734  ret= 1;
3735 ex:;
3736  Findjob_destroy(&job, 0);
3737  return(ret);
3738 }
3739 
3740 
3741 int Xorriso_perform_acl_from_list(struct XorrisO *xorriso, char *file_path,
3742  char *uid, char *gid, char *acl, int flag)
3743 {
3744  int ret, zero= 0;
3745  uid_t uid_number;
3746  gid_t gid_number;
3747 
3748  /* Set group and owner */
3749  if(gid[0]) {
3750  ret= Xorriso_convert_gidstring(xorriso, gid, &gid_number, 0);
3751  if(ret<=0)
3752  return(ret);
3753  ret= Xorriso_set_gid(xorriso, file_path, gid_number, 0);
3754  if(ret<=0)
3755  return(ret);
3756  }
3757  if(uid[0]) {
3758  ret= Xorriso_convert_uidstring(xorriso, uid, &uid_number, 0);
3759  if(ret<=0)
3760  return(ret);
3761  ret= Xorriso_set_uid(xorriso, file_path, uid_number, 0);
3762  if(ret<=0)
3763  return(ret);
3764  }
3765  ret= Xorriso_option_setfacli(xorriso, acl, 1, &file_path, &zero, 0);
3766  if(ret <= 0)
3767  return(ret);
3768  return(1);
3769 }
3770 
3771 
3772 /*
3773  @param flag bit0= do not perform setfattr but only check input
3774 */
3775 int Xorriso_path_setfattr(struct XorrisO *xorriso, void *in_node, char *path,
3776  char *name, size_t value_length, char *value, int flag)
3777 {
3778  int ret, hflag;
3779  size_t num_attrs= 1;
3780  char *name_pt;
3781 
3782  hflag= 2;
3783  name_pt= name;
3784  if(name[0] == 0) {
3785  sprintf(xorriso->info_text,
3786  "-setfattr: Empty attribute name is not allowed");
3787  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
3788  return(0);
3789  } else if(strcmp(name, "--remove-all") == 0) {
3790  if(value[0]) {
3791  sprintf(xorriso->info_text,
3792  "-setfattr: Value is not empty with pseudo name --remove-all");
3793  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
3794  return(0);
3795  }
3796  num_attrs= 0;
3797  hflag= 0;
3798  } else if(name[0] == '-') {
3799  name_pt++;
3800  hflag|= 4;
3801  } else if(name[0] == '=' || name[0] == '+') {
3802  name_pt++;
3803  }
3804  if(flag & 1)
3805  return(1);
3806  ret= Xorriso_setfattr(xorriso, in_node, path,
3807  num_attrs, &name_pt, &value_length, &value, hflag);
3808  return(ret);
3809 }
3810 
3811 
3812 /* Warning: The text content of lst gets mangled by 0s and unescaping.
3813 */
3814 int Xorriso_perform_attr_from_list(struct XorrisO *xorriso, char *path,
3815  struct Xorriso_lsT *lst_start, int flag)
3816 {
3817  int ret, eaten;
3818  char *valuept, *ept, *line, **names= NULL, **values= NULL;
3819  size_t num_attr= 0, *value_lengths= NULL, v_len;
3820  struct Xorriso_lsT *lst;
3821 
3822  for(lst= lst_start; lst != NULL; lst= Xorriso_lst_get_next(lst, 0))
3823  num_attr++;
3824  if(num_attr == 0) {
3825  ret= Xorriso_setfattr(xorriso, NULL, path, num_attr, NULL, NULL, NULL, 0);
3826  goto ex;
3827  }
3828 
3829  names= calloc(num_attr, sizeof(char *));
3830  if(names == NULL) {
3831  Xorriso_no_malloc_memory(xorriso, NULL, 0);
3832  ret= -1; goto ex;
3833  }
3834  value_lengths= calloc(num_attr, sizeof(size_t));
3835  if(value_lengths== NULL) {
3836  Xorriso_no_malloc_memory(xorriso, NULL, 0);
3837  ret= -1; goto ex;
3838  }
3839  values= calloc(num_attr, sizeof(char *));
3840  if(values== NULL) {
3841  Xorriso_no_malloc_memory(xorriso, NULL, 0);
3842  ret= -1; goto ex;
3843  }
3844 
3845  num_attr= 0;
3846  for(lst= lst_start; lst != NULL; lst= Xorriso_lst_get_next(lst, 0)) {
3847  line= Xorriso_lst_get_text(lst, 0);
3848  ept= strchr(line, '=');
3849  if(ept == NULL)
3850  continue;
3851  /* Split into name and content */;
3852  *ept= 0;
3853  valuept= ept + 1;
3854 
3855  /* Strip quotes from value */
3856  v_len= strlen(valuept);
3857  if(v_len < 2 || *valuept != '"' || *(valuept + v_len - 1) != '"')
3858  continue;
3859  *valuept= 0;
3860  *(valuept + v_len - 1)= 0;
3861  valuept++;
3862  v_len-= 2;
3863 
3864  /* Unescape backslashes , values eventually with 0-bytes */
3865  ret= Sfile_bsl_interpreter(line, strlen(line), &eaten, 0);
3866  if(ret <= 0)
3867  continue;
3868  ret= Sfile_bsl_interpreter(valuept, (int) v_len, &eaten, 2);
3869  if(ret <= 0)
3870  continue;
3871 
3872  names[num_attr]= line;
3873  values[num_attr]= valuept;
3874  value_lengths[num_attr]= v_len - eaten;
3875  num_attr++;
3876  }
3877  ret= Xorriso_setfattr(xorriso, NULL, path, num_attr, names,
3878  value_lengths, values, 0);
3879 ex:;
3880  if(names != NULL)
3881  free(names);
3882  if(value_lengths != NULL)
3883  free(value_lengths);
3884  if(values != NULL)
3885  free(values);
3886  return(ret);
3887 }
3888 
3889 
3890 int Xorriso__mark_update_xinfo(void *data, int flag)
3891 {
3892  /* data is an int disguised as pointer. It does not point to memory. */
3893  return(1);
3894 }
3895 
3896 
3897 int Xorriso__mark_update_cloner(void *old_data, void **new_data, int flag)
3898 {
3899  *new_data= NULL;
3900  if(flag)
3901  return(ISO_XINFO_NO_CLONE);
3902  if(old_data == NULL)
3903  return(0);
3904  /* data is an int disguised as pointer. It does not point to memory. */
3905  *new_data= old_data;
3906  return(0);
3907 }
3908 
3909 
3910 /* @param flag bit0= found on disk
3911  bit1= inquire visit-found status:
3912  1=not visited, 2=not found, 3=found
3913  bit2= with bit1: delete xinfo before returning status
3914 */
3915 int Xorriso_mark_update_merge(struct XorrisO *xorriso, char *path,
3916  void *in_node, int flag)
3917 {
3918  int ret;
3919  void *xipt= NULL;
3920  IsoNode *node;
3921 
3922  if(in_node == NULL) {
3923  ret= Xorriso_node_from_path(xorriso, NULL, path, &node, 0);
3924  if(ret <= 0)
3925  return(ret);
3926  } else
3927  node= (IsoNode *) in_node;
3929  if(ret < 0) {
3930  Xorriso_process_msg_queues(xorriso,0);
3931  Xorriso_report_iso_error(xorriso, "", ret,
3932  "Error when looking for update_merge xinfo",
3933  0, "FAILURE", 1);
3934  return(0);
3935  }
3936  if(flag & 2) { /* Inquire status and optionally delete xinfo */
3937  if(ret == 0)
3938  return(1);
3939  if(flag & 4) {
3941  if(ret < 0) {
3942  Xorriso_process_msg_queues(xorriso,0);
3943  Xorriso_report_iso_error(xorriso, "", ret,
3944  "Error when removing update_merge xinfo",
3945  0, "FAILURE", 1);
3946  return(0);
3947  }
3948  }
3949  if(((char *) &xipt)[0])
3950  return(3);
3951  return(2);
3952  }
3953  /* xipt is a byte value disguised as void pointer */
3954  if(ret == 1) {
3955  if(((char *) &xipt)[0])
3956  return(1);
3957  if(!(flag & 1))
3958  return(1);
3959  } else
3960  ((char *) &xipt)[0]= 0;
3961  if(flag & 1)
3962  ((char *) &xipt)[0]= 1;
3964  if(ret < 0)
3965  goto set_error;
3967  if(ret <= 0) {
3968 set_error:;
3969  Xorriso_process_msg_queues(xorriso,0);
3970  Xorriso_report_iso_error(xorriso, "", ret,
3971  "Error when trying to set update_merge xinfo",
3972  0, "FAILURE", 1);
3973  return(0);
3974  }
3975  return(1);
3976 }
3977 
3978 
3979 /* flag bit0= in case of error talk of "overwrite" rather than "remove"
3980 */
3981 static int Xorriso_remove_hfsplus_crtp(struct XorrisO *xorriso, IsoNode *node,
3982  char *path, int flag)
3983 {
3984  int ret;
3985  char *msg, buf[10], *bufpt;
3986  size_t l;
3987  static char *name= "isofs.hx";
3988 
3990  Xorriso_process_msg_queues(xorriso, 0);
3991  if(ret < 0) {
3992  if(flag & 1)
3993  msg= "Cannot overwrite HFS+ creator and type of ISO node";
3994  else
3995  msg= "Cannot remove HFS+ creator and type of ISO node";
3996  Xorriso_report_iso_error(xorriso, path, ret, msg, 0, "FAILURE", 1);
3997  return(0);
3998  }
3999  /* Delete isofs.hx attribute */
4000  bufpt= buf;
4001 
4002  /* >>> ??? check whether there is isofs.hx attached ? */;
4003 
4004  ret= Xorriso_setfattr(xorriso, node, path,
4005  (size_t) 1, &name, &l, &bufpt, 4 | 8);
4006  return(ret);
4007 }
4008 
4009 
4010 static int Xorriso_set_hfsplus_crtp(struct XorrisO *xorriso, IsoNode *node,
4011  char *path, char *creator, char *hfs_type,
4012  int flag)
4013 {
4014  struct iso_hfsplus_xinfo_data *hfs_data= NULL;
4015  char buf[10], *bufpt;
4016  size_t l;
4017  int ret;
4018  static char *name= "isofs.hx";
4019 
4020  /* Register as non-persistent xinfo */
4021  hfs_data= iso_hfsplus_xinfo_new(0);
4022  if(hfs_data == NULL) {
4023  Xorriso_no_malloc_memory(xorriso, NULL, 0);
4024  return(-1);
4025  }
4026  memcpy(hfs_data->creator_code, creator, 4);
4027  memcpy(hfs_data->type_code, hfs_type, 4);
4028  ret= iso_node_add_xinfo(node, iso_hfsplus_xinfo_func, (void *) hfs_data);
4029  Xorriso_process_msg_queues(xorriso, 0);
4030  if(ret < 0) {
4031  Xorriso_report_iso_error(xorriso, path, ret,
4032  "Cannot attach HFS+ creator and type to ISO node", 0, "FAILURE", 1);
4033  goto failure;
4034  } else if(ret == 0) {
4035  strcat(xorriso->info_text,
4036  "Program error: iso_node_add_xinfo refuses to attach HFS+ creator and type");
4037  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4038  goto failure;
4039  }
4040 
4041  /* Register as persistent attribute isofs.hx */
4042  bufpt= buf;
4043  l= 10;
4044  buf[0]= 1;
4045  buf[1]= 0;
4046  memcpy(buf + 2, creator, 4);
4047  memcpy(buf + 6, hfs_type, 4);
4048  ret= Xorriso_setfattr(xorriso, node, path,
4049  (size_t) 1, &name, &l, &bufpt, 2 | 8);
4050  if(ret <= 0)
4051  goto failure;
4052  Xorriso_set_change_pending(xorriso, 0);
4053  return(1);
4054 
4055 failure:
4056  if(hfs_data != NULL)
4057  iso_hfsplus_xinfo_func(hfs_data, 1);
4058  return(0);
4059 }
4060 
4061 
4062 /* @param flag bit0= only check creator and hfs_type for compliance.
4063  bit1= with bit0: check for search rather than for setting
4064  bit2= copy 2 times 4 bytes without any check
4065 */
4066 int Xorriso_hfsplus_file_creator_type(struct XorrisO *xorriso, char *path,
4067  void *in_node,
4068  char *creator, char *hfs_type, int flag)
4069 {
4070  int ret;
4071  IsoNode *node;
4072 
4073  if(in_node == NULL && !(flag & 1)) {
4074  ret= Xorriso_node_from_path(xorriso, NULL, path, &node, 0);
4075  if(ret <= 0)
4076  return(ret);
4077  } else
4078  node= (IsoNode *) in_node;
4079  if(flag & 4) {
4080  ;
4081  } else if((creator[0] == 0 && hfs_type[0] == 0) ||
4082  strcmp(creator, "--delete") == 0) {
4083  if(flag & 2) {
4084  strcpy(xorriso->info_text,
4085  "Attempt to use HFS+ file pseudo-creator '--delete' for searching");
4086  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4087  strcpy(xorriso->info_text,
4088  "Suitable are strings of length 4 or length 1");
4089  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
4090  return(0);
4091  }
4092  if(flag & 1)
4093  return(1);
4094  ret= Xorriso_remove_hfsplus_crtp(xorriso, node, path, 0);
4095  if(ret < 0)
4096  return(ret);
4097  return(1);
4098  } else if((strlen(creator) != 4 && !(strlen(creator) == 1 &&
4099  (flag & 3) == 3)) ||
4100  (strlen(hfs_type) != 4 && !(strlen(hfs_type) == 1 &&
4101  (flag & 3) == 3))) {
4102  if(flag & 2) {
4103  strcpy(xorriso->info_text,
4104  "HFS+ file creator code or type code for searching are not exactly 1 or 4 characters long");
4105  } else {
4106  strcpy(xorriso->info_text,
4107  "HFS+ file creator code or type code are not exactly 4 characters long");
4108  }
4109  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4110  return(0);
4111  }
4112  if(flag & 1)
4113  return(1);
4114 
4115  ret= Xorriso_remove_hfsplus_crtp(xorriso, node, path, 1);
4116  if(ret <= 0)
4117  return(ret);
4118  ret= Xorriso_set_hfsplus_crtp(xorriso, node, path, creator, hfs_type, 0);
4119  if(ret <= 0)
4120  return(ret);
4121  return(1);
4122 }
4123 
4124 
4125 /*
4126  @param node
4127  If node is NULL and path is empty, then the blessing will be
4128  revoked from any node which bears it.
4129  @param flag
4130  Bitfield for control purposes.
4131  bit0= Revoke blessing if node != NULL bears it.
4132  bit1= Revoke any blessing of the node, regardless of parameter
4133  blessing. If node is NULL, then revoke all blessings.
4134  bit2= Only check parameter blessing.
4135  Return blessing index + 1 instead of issuing the blessing.
4136  bit3= With bit2:
4137  Allow blessing "any" and map to index ISO_HFSPLUS_BLESS_MAX.
4138  Elsewise, blessing "none" is mapped to ISO_HFSPLUS_BLESS_MAX.
4139 */
4140 int Xorriso_hfsplus_bless(struct XorrisO *xorriso, char *path,
4141  void *in_node, char *blessing, int flag)
4142 {
4143  int ret, bless_max;
4144  IsoNode *node, **blessed_nodes;
4145  IsoImage *volume= NULL;
4146  enum IsoHfsplusBlessings bless_code = ISO_HFSPLUS_BLESS_MAX; /* = invalid */
4147  char *hb = "";
4148  size_t l= 0;
4149  static char *name= "isofs.hb";
4150 
4151  if(strcmp(blessing, "ppc_bootdir") == 0 ||
4152  strcmp(blessing, "p") == 0 || strcmp(blessing, "P") == 0) {
4153  bless_code= ISO_HFSPLUS_BLESS_PPC_BOOTDIR;
4154  hb= "p";
4155  } else if(strcmp(blessing, "intel_bootfile") == 0 ||
4156  strcmp(blessing, "i") == 0 || strcmp(blessing, "I") == 0) {
4158  hb= "i";
4159  } else if(strcmp(blessing, "show_folder") == 0 ||
4160  strcmp(blessing, "s") == 0 || strcmp(blessing, "S") == 0) {
4161  bless_code= ISO_HFSPLUS_BLESS_SHOWFOLDER;
4162  hb= "s";
4163  } else if(strcmp(blessing, "os9_folder") == 0 ||
4164  strcmp(blessing, "9") == 0) {
4165  bless_code= ISO_HFSPLUS_BLESS_OS9_FOLDER;
4166  hb= "9";
4167  } else if(strcmp(blessing, "osx_folder") == 0 ||
4168  strcmp(blessing, "x") == 0 || strcmp(blessing, "X") == 0) {
4169  bless_code= ISO_HFSPLUS_BLESS_OSX_FOLDER;
4170  hb= "x";
4171  } else if((!(flag & 8)) && (strcmp(blessing, "none") == 0 ||
4172  strcmp(blessing, "n") == 0 || strcmp(blessing, "N") == 0)) {
4173  bless_code= ISO_HFSPLUS_BLESS_MAX;
4174  flag |= 2;
4175  } else if((flag & 8) && (flag & 4) &&
4176  (strcmp(blessing, "any") == 0 ||
4177  strcmp(blessing, "a") == 0 || strcmp(blessing, "A") == 0)) {
4178  bless_code= ISO_HFSPLUS_BLESS_MAX;
4179  } else {
4180  sprintf(xorriso->info_text, "Unknown blessing type ");
4181  Text_shellsafe(blessing, xorriso->info_text, 1);
4182  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4183  return(0);
4184  }
4185  if(flag & 4)
4186  return(1 + bless_code);
4187 
4188  if(in_node == NULL && path[0]) {
4189  ret= Xorriso_node_from_path(xorriso, NULL, path, &node, 0);
4190  if(ret <= 0)
4191  return(ret);
4192  } else
4193  node= (IsoNode *) in_node;
4194  ret= Xorriso_get_volume(xorriso, &volume, 0);
4195  if(ret <= 0)
4196  return(ret);
4197 
4198  if(!(flag & 2)) {
4199  /* Remove persistent bless mark from current bearer */
4200  ret= iso_image_hfsplus_get_blessed(volume, &blessed_nodes, &bless_max, 0);
4201  Xorriso_process_msg_queues(xorriso, 0);
4202  if(ret < 0) {
4203  Xorriso_report_iso_error(xorriso, "", ret,
4204  "Error when trying to bless a file",
4205  0, "FAILURE", 1);
4206  return(0);
4207  }
4208  if((int) bless_code < bless_max) {
4209  if(blessed_nodes[(int) bless_code] != NULL) {
4210  ret= Xorriso_setfattr(xorriso, blessed_nodes[(int) bless_code], "",
4211  (size_t) 1, &name, &l, &hb, 4 | 8);
4212  if(ret <= 0)
4213  return(ret);
4214  }
4215  }
4216  }
4217 
4218  /* Bless node */
4219  ret= iso_image_hfsplus_bless(volume, bless_code, node, flag & 3);
4220  Xorriso_process_msg_queues(xorriso, 0);
4221  if(ret == 0 && path[0]) {
4222  if((flag & 3)) {
4223  sprintf(xorriso->info_text,
4224  "Attempt to revoke blessing of unblessed file");
4225  } else {
4226  sprintf(xorriso->info_text,
4227  "Multiple blessing to same file or inappropriate file type");
4228  }
4229  if(path[0]) {
4230  strcat(xorriso->info_text, ": ");
4231  Text_shellsafe(path, xorriso->info_text, 1);
4232  }
4233  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4234  return(0);
4235  } else if (ret < 0) {
4236  Xorriso_report_iso_error(xorriso, "", ret,
4237  "Error when trying to bless a file",
4238  0, "FAILURE", 1);
4239  return(0);
4240  }
4241 
4242  /* Attach persistent AAIP bless mark to node */
4243  if(!(flag & 3)) {
4244  l= 1;
4245  ret= Xorriso_setfattr(xorriso, node, path, (size_t) 1, &name, &l, &hb,
4246  2 | 8);
4247  if(ret <= 0)
4248  return(ret);
4249  }
4250 
4251  Xorriso_set_change_pending(xorriso, 0);
4252  return(1);
4253 }
4254 
4255 
4256 int Xorriso_get_blessing(struct XorrisO *xorriso, IsoNode *node,
4257  int *bless_idx, char bless_code[17], int flag)
4258 {
4259  IsoNode **blessed_nodes;
4260  int bless_max, ret, i;
4261 
4262  if(xorriso->in_volset_handle == NULL)
4263  return(0);
4264 
4266  &blessed_nodes, &bless_max, 0);
4267  Xorriso_process_msg_queues(xorriso, 0);
4268  if(ret < 0) {
4269  Xorriso_report_iso_error(xorriso, "", ret,
4270  "Error when trying to inquire HFS+ file blessings",
4271  0, "FAILURE", 1);
4272  return(-1);
4273  }
4274  for(i= 0; i < bless_max; i++) {
4275  if(blessed_nodes[i] == node) {
4276  switch (i) {
4278  strcpy(bless_code, "ppc_bootdir");
4280  strcpy(bless_code, "intel_bootfile");
4281  break; case ISO_HFSPLUS_BLESS_SHOWFOLDER:
4282  strcpy(bless_code, "show_folder");
4283  break; case ISO_HFSPLUS_BLESS_OS9_FOLDER:
4284  strcpy(bless_code, "os9_folder");
4285  break; case ISO_HFSPLUS_BLESS_OSX_FOLDER:
4286  strcpy(bless_code, "osx_folder");
4287  break; default:
4288  strcpy(bless_code, "unknown_blessing");
4289  }
4290  *bless_idx= i;
4291  return(1);
4292  }
4293  }
4294  return(0);
4295 }
4296 
4297 
4298 /* @param flag bit0= use file addresses as search patterns
4299 */
4300 int Xorriso_apply_sort_file(struct XorrisO *xorriso, char *path, int flag)
4301 {
4302  int ret, linecount= 0, filec= 0, zero, i;
4303  FILE *fp= NULL;
4304  char *sret, *line= NULL, *spt, *tpt, *patterns[1], **filev= NULL;
4305  char *sort_weight_args[4];
4306  off_t mem= 0;
4307  IsoImage *volume;
4308 
4309  Xorriso_alloc_meM(line, char, SfileadrL);
4310 
4311  ret= Xorriso_get_volume(xorriso, &volume, 0);
4312  if(ret<=0)
4313  goto ex;
4314 
4315  ret= Xorriso_afile_fopen(xorriso, path, "rb", &fp, 2);
4316  if(ret <= 0)
4317  {ret= 0; goto ex;}
4318  while(1) {
4319  sret= Sfile_fgets_n(line, SfileadrL - 1, fp, 0);
4320  if(sret == NULL) {
4321  if(ferror(fp))
4322  {ret= 0; goto ex;}
4323  break;
4324  }
4325  linecount++;
4326 
4327  /* Find first space or tab */
4328  spt= strchr(line, ' ');
4329  tpt= strchr(line, '\t');
4330  if(spt == NULL || (tpt != NULL && tpt < spt))
4331  spt= tpt;
4332  if(spt == NULL) {
4333  sprintf(xorriso->info_text,
4334  "No space or tab character found in line %d of sort weight file ",
4335  linecount);
4336  Text_shellsafe(path, xorriso->info_text, 1);
4337  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4338  ret= 0; goto ex;
4339  }
4340  *spt= 0;
4341 
4342  patterns[0]= spt + 1;
4343  if(flag & 1) {
4344  /* Obtain list of matching files */
4345  ret= Xorriso_expand_pattern(xorriso, 1, patterns, 0,
4346  &filec, &filev, &mem, 4);
4347  if(ret <= 0)
4348  {ret= 0; goto ex;}
4349  } else {
4350  filec= 1;
4351  }
4352 
4353  /* Apply weight to file or directory tree */
4354  for(i= 0; i < filec; i++) {
4355  zero= 0;
4356  if(flag & 1) {
4357  sort_weight_args[0]= filev[i];
4358  } else {
4359  sort_weight_args[0]= patterns[0];
4360  }
4361  sort_weight_args[1]= "-exec";
4362  sort_weight_args[2]= "sort_weight";
4363  sort_weight_args[3]= line;
4364  ret= Xorriso_option_find(xorriso, 4, sort_weight_args, &zero, 2);
4365  if(ret <= 0)
4366  {ret= 0; goto ex;}
4367  }
4368  if(flag & 1)
4369  Sfile_destroy_argv(&filec, &filev, 0);
4370  }
4371  ret= 1;
4372 ex:
4373  if(fp != NULL)
4374  fclose(fp);
4375  Xorriso_free_meM(line);
4376  Sfile_destroy_argv(&filec, &filev, 0);
4377  return(ret);
4378 }
4379 
4380 
4381 /* @param flag bit0= tolerate truncated files of old length
4382  and mangle collisions
4383 */
4384 int Xorriso_set_file_name_limit(struct XorrisO *xorriso, int value, int flag)
4385 {
4386  int ret;
4387  IsoImage *volume= NULL;
4388  struct FindjoB *job= NULL;
4389  struct stat dir_stbuf;
4390 
4391  ret= Xorriso_get_volume(xorriso, &volume, 1);
4392  if(ret < 0)
4393  goto ex;
4394  if (ret == 1 && volume != NULL) {
4395  /* Check whether there are non-refreshable truncated names */
4396  ret= Findjob_new(&job, "/", 0);
4397  if(ret<=0) {
4398  Xorriso_no_findjob(xorriso, "xorriso", 0);
4399  {ret= -1; goto ex;}
4400  }
4401  Findjob_set_action_type(job, 55 + 2 * (flag & 1), value, 0);
4402  xorriso->find_unique_trunc_result= 2;
4403  ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, NULL, "/",
4404  &dir_stbuf, 0, 0);
4405  if(ret < 0)
4406  goto ex;
4407  xorriso->request_to_abort= 0;
4408  if(xorriso->find_unique_trunc_result == 0 && !(flag & 1)) {
4409  Xorriso_msgs_submit(xorriso, 0,
4410  "-file_name_limit may not be changed because truncated files exist or collisions would occur",
4411  0, "SORRY", 0);
4412  ret= 0; goto ex;
4413  }
4414 
4415  xorriso->file_name_limit= value;
4416  iso_image_set_truncate_mode(volume, 1, value);
4417 
4418  /* truncations are necessary */;
4419  if(xorriso->find_unique_trunc_result == 1) {
4420  Findjob_set_action_type(job, 54 + 2 * (flag & 1),
4421  xorriso->file_name_limit, 0);
4422  xorriso->find_unique_trunc_result= 2;
4423  ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, NULL, "/",
4424  &dir_stbuf, 0, 0);
4425  if(ret < 0)
4426  goto ex;
4427  if(xorriso->find_unique_trunc_result == 0) {
4428 
4429  /* >>> Did not work . What to do ? */;
4430 
4431  }
4432  }
4433  }
4434  xorriso->file_name_limit= value;
4435  ret= 1;
4436 ex:;
4437  Findjob_destroy(&job, 0);
4438  return(ret);
4439 }
4440 
4441 
4442 /* @param flag bit0= test for uniqueness, do not change name
4443  bit1= tolerate existing truncated names and mangle collisions
4444  bit2= be silent about non-uniquely truncatables
4445  do not set xorriso->request_to_abort
4446 */
4447 int Xorriso_truncate_uniquely(struct XorrisO *xorriso, int length,
4448  IsoNode *node, char *abs_path, char *show_path,
4449  int flag)
4450 {
4451  int ret, l, i;
4452  unsigned int mangleno;
4453  char *name, *trunc= NULL, *old_name= NULL;
4454  IsoDir *dir;
4455  IsoNode *collider;
4456  IsoImage *volume= NULL;
4457 
4458  name= (char *) iso_node_get_name(node);
4459  l= strlen(name);
4460 
4461  /* Check for truncated name */
4462  if(l == xorriso->file_name_limit && l != length && !(flag & 2)) {
4463  i= 0;
4464  if(name[l - 33] == ':') {
4465  for(i= l - 32; i < l; i++)
4466  if((name[i] < '0' || name[i] > '9') &&
4467  (name[i] < 'a' || name[i] > 'f'))
4468  break;
4469  }
4470  if(i == l) {
4471  if(!(flag & 4)) {
4472  sprintf(xorriso->info_text, "Truncated name of current limit found: ");
4473  Text_shellsafe(name, xorriso->info_text, 1);
4474  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
4475  }
4476  xorriso->find_unique_trunc_result= 0;
4477  {ret= 0; goto ex;}
4478  }
4479  }
4480 
4481  /* Check for need to truncate */
4482  if(l <= length)
4483  {ret= 1; goto ex;}
4484 
4485  if(xorriso->find_unique_trunc_result > 1)
4486  xorriso->find_unique_trunc_result= 1;
4487  trunc= strdup(name);
4488  old_name= strdup(name);
4489  if(trunc == NULL || old_name == NULL) {
4490  Xorriso_no_malloc_memory(xorriso, NULL, 0);
4491  ret= -1; goto ex;
4492  }
4493  ret= iso_truncate_leaf_name(1, length, trunc, 0);
4494  if(ret < 0) {
4495  Xorriso_process_msg_queues(xorriso, 0);
4496  Xorriso_report_iso_error(xorriso, "", ret,
4497  "Error when truncating file name", 0, "SORRY", 1);
4498  xorriso->find_unique_trunc_result= 0;
4499  {ret= 0; goto ex;}
4500  }
4501 
4502  dir= iso_node_get_parent(node);
4503  if(dir != NULL) {
4504  /* (intentionally using deprecated call which does not truncate by itself)*/
4505  ret= iso_dir_get_node(dir, trunc, &collider);
4506  if(ret == 1) {
4507  if((flag & 1) && !(flag & 2)) {
4508  if(!(flag & 4)) {
4509  sprintf(xorriso->info_text,
4510  "Truncated name collides with existing name: ");
4511  Text_shellsafe(name, xorriso->info_text, 1);
4512  strcat(xorriso->info_text, " -> ");
4513  Text_shellsafe(trunc, xorriso->info_text, 1);
4514  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
4515  }
4516  xorriso->find_unique_trunc_result= 0;
4517  {ret= 0; goto ex;}
4518  } else {
4519  /* Mangle */
4520  for(mangleno= 0; mangleno < 0xffffffff; mangleno++) {
4521  Sfile_flatten_utf8_heads(trunc, length - 33 - 9, 0);
4522  sprintf(trunc + length - 33 - 9, ":%-8.8X", mangleno);
4523  trunc [length - 33] = ':';
4524  ret= iso_dir_get_node(dir, trunc, &collider);
4525  if(ret == 0)
4526  break;
4527  }
4528  }
4529  }
4530  }
4531 
4532  /* If only for testing: done now */
4533  if(flag & 1)
4534  {ret= 1; goto ex;}
4535  if(xorriso->file_name_limit != length)
4536  {ret= -1; goto ex;} /* Programming error */
4537  ret= Xorriso_get_volume(xorriso, &volume, 1);
4538  if(ret < 0)
4539  {ret= -1; goto ex;} /* Programming error */
4540 
4541  /* Set truncated name */
4542  ret= iso_image_set_node_name(volume, node, trunc, 0);
4543  if(ret < 0) {
4544  Xorriso_process_msg_queues(xorriso, 0);
4545  xorriso->find_unique_trunc_result= 0;
4546  {ret= 0; goto ex;}
4547  }
4548  Xorriso_set_change_pending(xorriso, 0);
4549  sprintf(xorriso->info_text, "Truncated: ");
4550  Text_shellsafe(old_name, xorriso->info_text, 1);
4551  strcat(xorriso->info_text, " -> ");
4552  Text_shellsafe(trunc, xorriso->info_text, 1);
4553  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
4554 
4555  ret= 1;
4556 ex:;
4557  if(ret == 0 && (flag & 1) && !(flag & 4))
4558  xorriso->request_to_abort= 1;
4559  Xorriso_free_meM(old_name);
4560  Xorriso_free_meM(trunc);
4561  return(ret);
4562 }
4563 
int Dirseq_destroy(struct DirseQ **o, int flag)
Definition: aux_objects.c:336
int Linkitem_reset_stack(struct LinkiteM **o, struct LinkiteM *to, int flag)
Definition: aux_objects.c:895
int Dirseq_next_adr(struct DirseQ *o, char reply[4096], int flag)
Definition: aux_objects.c:384
struct Xorriso_lsT * Xorriso_lst_get_next(struct Xorriso_lsT *entry, int flag)
Definition: aux_objects.c:624
char * Xorriso_lst_get_text(struct Xorriso_lsT *entry, int flag)
Definition: aux_objects.c:636
int Splitpart__compose(char *adr, int partno, int total_parts, off_t offset, off_t bytes, off_t total_bytes, int flag)
Definition: aux_objects.c:218
int Dirseq_new(struct DirseQ **o, char *adr, int flag)
Definition: aux_objects.c:291
int Xorriso_destroy_node_array(struct XorrisO *xorriso, int flag)
Definition: base_obj.c:656
int Xorriso_new_node_array(struct XorrisO *xorriso, off_t mem_limit, int addon_nodes, int flag)
Definition: base_obj.c:728
int Xorriso_pfx_disk_path(struct XorrisO *xorriso, char *iso_path, char *iso_prefix, char *disk_prefix, char disk_path[4096], int flag)
Definition: cmp_update.c:686
int Xorriso_find_compare(struct XorrisO *xorriso, void *boss_iter, void *node, char *iso_path, char *iso_prefix, char *disk_prefix, int flag)
Definition: cmp_update.c:721
int Xorriso_update_interpreter(struct XorrisO *xorriso, void *boss_iter, void *node, int compare_result, char *disk_path, char *iso_rr_path, int flag)
Definition: cmp_update.c:792
int Xorriso_afile_fopen(struct XorrisO *xorriso, char *filename, char *mode, FILE **ret_fp, int flag)
Definition: disk_ops.c:1780
int Xorriso_resolve_link(struct XorrisO *xorriso, char *link_path, char result_path[4096], int flag)
Definition: disk_ops.c:45
int Xorriso_convert_uidstring(struct XorrisO *xorriso, char *uid_string, uid_t *uid, int flag)
Definition: disk_ops.c:154
int Xorriso_hop_link(struct XorrisO *xorriso, char *link_path, struct LinkiteM **link_stack, struct stat *stbuf, int flag)
Definition: disk_ops.c:304
int Xorriso_convert_gidstring(struct XorrisO *xorriso, char *gid_string, gid_t *gid, int flag)
Definition: disk_ops.c:178
int Xorriso_set_filter(struct XorrisO *xorriso, void *in_node, char *path, char *filter_name, int flag)
Definition: filters.c:265
int Findjob_set_found_path(struct FindjoB *o, char *path, int flag)
Definition: findjob.c:1091
int Findjob_get_start_path(struct FindjoB *o, char **start_path, int flag)
Definition: findjob.c:434
int Findjob_get_action(struct FindjoB *o, int flag)
Definition: findjob.c:1120
int Findjob_test_2(struct XorrisO *xorriso, struct FindjoB *o, void *node, char *name, char *path, struct stat *boss_stbuf, struct stat *stbuf, int flag)
Definition: findjob.c:1147
int Findjob_set_action_target(struct FindjoB *o, int action, char *target, int flag)
Definition: findjob.c:1163
int Findjob_set_action_type(struct FindjoB *o, int action, int type, int flag)
Definition: findjob.c:1172
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_set_start_path(struct FindjoB *o, char *start_path, int flag)
Definition: findjob.c:420
int Findjob_get_action_parms(struct FindjoB *o, char **target, char **text_2, uid_t *user, gid_t *group, mode_t *mode_and, mode_t *mode_or, int *type, time_t *date, struct FindjoB **subjob, int flag)
Definition: findjob.c:1128
static int Sfile_bsl_interpreter(char *text, int upto, int *eaten, int flag)
static int Sfile_destroy_argv(int *argc, char ***argv, int flag)
#define SfileadrL
int iso_local_get_perms_wo_acl(char *disk_path, mode_t *st_mode, int flag)
Definition: fs_local.c:922
int iso_local_get_attrs(char *disk_path, size_t *num_attrs, char ***names, size_t **value_lengths, char ***values, int flag)
Definition: fs_local.c:863
struct iso_hfsplus_xinfo_data * iso_hfsplus_xinfo_new(int flag)
Definition: hfsplus.c:1849
int iso_hfsplus_xinfo_func(void *data, int flag)
Definition: hfsplus.c:1841
IsoDir * iso_image_get_root(const IsoImage *image)
Definition: image.c:334
int iso_image_hfsplus_bless(IsoImage *img, enum IsoHfsplusBlessings blessing, IsoNode *node, int flag)
Definition: image.c:907
int iso_image_hfsplus_get_blessed(IsoImage *img, IsoNode ***blessed_nodes, int *bless_max, int flag)
Definition: image.c:960
int iso_image_set_truncate_mode(IsoImage *img, int mode, int length)
Definition: image.c:1100
int Xorriso_set_change_pending(struct XorrisO *xorriso, int flag)
Definition: iso_img.c:1004
int Xorriso_record_cmd_line(struct XorrisO *xorriso, char *buf, char **cmds, int *cmd_count, int flag)
Definition: iso_img.c:1492
int Xorriso_get_volume(struct XorrisO *xorriso, IsoImage **volume, int flag)
Definition: iso_img.c:966
int Xorriso_set_to_mtime(struct XorrisO *xorriso, char *show_path, IsoNode *node, int flag)
Definition: iso_manip.c:2496
int Xorriso_set_file_name_limit(struct XorrisO *xorriso, int value, int flag)
Definition: iso_manip.c:4384
int Xorriso_perform_acl_from_list(struct XorrisO *xorriso, char *file_path, char *uid, char *gid, char *acl, int flag)
Definition: iso_manip.c:3741
int Xorriso_cannot_create_iter(struct XorrisO *xorriso, int iso_error, int flag)
Definition: iso_manip.c:2509
int Xorriso_overwrite_dest(struct XorrisO *xorriso, void *boss_iter, char *eff_dest, int dest_ret, char *activity, int flag)
Definition: iso_manip.c:1599
static int Xorriso_remove_hfsplus_crtp(struct XorrisO *xorriso, IsoNode *node, char *path, int flag)
Definition: iso_manip.c:3981
int Xorriso_get_blessing(struct XorrisO *xorriso, IsoNode *node, int *bless_idx, char bless_code[17], int flag)
Definition: iso_manip.c:4256
int Xorriso_rename(struct XorrisO *xorriso, void *boss_iter, char *origin, char *dest, int flag)
Definition: iso_manip.c:1635
int Xorriso_cut_out(struct XorrisO *xorriso, char *disk_path, off_t startbyte, off_t bytecount, char *iso_rr_path, int flag)
Definition: iso_manip.c:1230
int Xorriso_cannot_clone(struct XorrisO *xorriso, char *eff_origin, char *eff_dest, int iso_error, int flag)
Definition: iso_manip.c:1793
int Xorriso_findi_iter(struct XorrisO *xorriso, IsoDir *dir_node, off_t *mem, IsoDirIter **iter, IsoNode ***node_array, int *node_count, int *node_idx, IsoNode **iterated_node, int flag)
Definition: iso_manip.c:2528
int Xorriso_graft_in(struct XorrisO *xorriso, void *boss_iter, char *disk_path, char *img_path, off_t offset, off_t cut_size, int flag)
Definition: iso_manip.c:789
int Xorriso_apply_sort_file(struct XorrisO *xorriso, char *path, int flag)
Definition: iso_manip.c:4300
int Xorriso_mkdir(struct XorrisO *xorriso, char *path, int flag)
Definition: iso_manip.c:1306
int Xorriso_mark_update_merge(struct XorrisO *xorriso, char *path, void *in_node, int flag)
Definition: iso_manip.c:3915
int Xorriso_estimate_file_size(struct XorrisO *xorriso, struct FindjoB *job, char *basename, mode_t st_mode, off_t st_size, int flag)
Definition: iso_manip.c:2390
int Xorriso_set_uid(struct XorrisO *xorriso, char *in_path, uid_t uid, int flag)
Definition: iso_manip.c:2008
int Xorriso_setfacl(struct XorrisO *xorriso, void *in_node, char *path, char *access_text, char *default_text, int flag)
Definition: iso_manip.c:2094
int Xorriso_copy_implicit_properties(struct XorrisO *xorriso, IsoDir *dir, char *full_img_path, char *img_path, char *full_disk_path, int flag)
Definition: iso_manip.c:652
int Xorriso_set_st_mode(struct XorrisO *xorriso, char *in_path, mode_t mode_and, mode_t mode_or, int flag)
Definition: iso_manip.c:1979
int Xorriso_graft_split(struct XorrisO *xorriso, IsoImage *volume, IsoDir *dir, char *disk_path, char *img_name, char *nominal_source, char *nominal_target, off_t size, IsoNode **node, int flag)
Definition: iso_manip.c:118
int Xorriso_set_hidden(struct XorrisO *xorriso, void *in_node, char *path, int hide_state, int flag)
Definition: iso_manip.c:2362
int Xorriso_clone_tree(struct XorrisO *xorriso, void *boss_iter, char *origin, char *dest, int flag)
Definition: iso_manip.c:1808
int Xorriso_truncate_uniquely(struct XorrisO *xorriso, int length, IsoNode *node, char *abs_path, char *show_path, int flag)
Definition: iso_manip.c:4447
int Xorriso_rmi(struct XorrisO *xorriso, void *boss_iter, off_t boss_mem, char *path, int flag)
Definition: iso_manip.c:1359
int Xorriso_perform_attr_from_list(struct XorrisO *xorriso, char *path, struct Xorriso_lsT *lst_start, int flag)
Definition: iso_manip.c:3814
int Xorriso_tree_graft_node(struct XorrisO *xorriso, IsoImage *volume, IsoDir *dir, char *disk_path, char *img_name, char *nominal_source, char *nominal_target, off_t offset, off_t cut_size, IsoNode **node, int flag)
Definition: iso_manip.c:175
int Xorriso_mkisofs_lower_r(struct XorrisO *xorriso, IsoNode *node, int flag)
Definition: iso_manip.c:2069
int Xorriso_clone_under(struct XorrisO *xorriso, char *origin, char *dest, int flag)
Definition: iso_manip.c:1909
int Xorriso_test_outchar(struct XorrisO *xorriso, void *node_pt, int name_space, int flag)
Definition: iso_manip.c:2413
int Xorriso_all_node_array(struct XorrisO *xorriso, int addon_nodes, int flag)
Definition: iso_manip.c:3709
int Xorriso__mark_update_cloner(void *old_data, void **new_data, int flag)
Definition: iso_manip.c:3897
int Xorriso_add_symlink(struct XorrisO *xorriso, IsoDir *parent, char *link_target, char *leaf_name, char *nominal_path, int flag)
Definition: iso_manip.c:750
int Exprtest_match_disk_name(struct XorrisO *xorriso, struct ExprtesT *ftest, IsoNode *node, int flag)
Definition: iso_manip.c:2980
int Xorriso_findi_headline(struct XorrisO *xorriso, struct FindjoB *job, int flag)
Definition: iso_manip.c:3327
int Xorriso_add_tree(struct XorrisO *xorriso, IsoDir *dir, char *img_dir_path, char *disk_dir_path, struct LinkiteM *link_stack, int flag)
Definition: iso_manip.c:356
int Xorriso__mark_update_xinfo(void *data, int flag)
Definition: iso_manip.c:3890
int Xorriso_set_time(struct XorrisO *xorriso, char *in_path, time_t t, int flag)
Definition: iso_manip.c:2043
int Xorriso_findi_sorted(struct XorrisO *xorriso, struct FindjoB *job, off_t boss_mem, int filec, char **filev, int flag)
Definition: iso_manip.c:3572
int Xorriso_record_dev_inode(struct XorrisO *xorriso, char *disk_path, dev_t dev, ino_t ino, void *in_node, char *iso_path, int flag)
Definition: iso_manip.c:2235
int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, IsoDirIter *boss_iter, off_t boss_mem, char *abs_path, char *show_path, IsoNode *node, int depth, int flag)
Definition: iso_manip.c:2635
int Xorriso_findi_test(struct XorrisO *xorriso, struct FindjoB *job, IsoNode *node, char *name, char *path, struct stat *boss_stbuf, struct stat *stbuf, int depth, int flag)
Definition: iso_manip.c:3312
int Xorriso_path_setfattr(struct XorrisO *xorriso, void *in_node, char *path, char *name, size_t value_length, char *value, int flag)
Definition: iso_manip.c:3775
int Xorriso_hfsplus_bless(struct XorrisO *xorriso, char *path, void *in_node, char *blessing, int flag)
Definition: iso_manip.c:4140
int Xoriso_handle_collision(struct XorrisO *xorriso, void *boss_iter, IsoNode **node, char *img_path, char *full_img_path, char *disk_path, char *show_path, int flag)
Definition: iso_manip.c:298
int Exprtest_match(struct XorrisO *xorriso, struct ExprtesT *ftest, void *node_pt, char *name, char *path, struct stat *boss_stbuf, struct stat *stbuf, int flag)
Definition: iso_manip.c:3018
int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf, char *disk_path, IsoNode *node, int flag)
Definition: iso_manip.c:48
static int Xorriso_set_hfsplus_crtp(struct XorrisO *xorriso, IsoNode *node, char *path, char *creator, char *hfs_type, int flag)
Definition: iso_manip.c:4010
int Xorriso_hfsplus_file_creator_type(struct XorrisO *xorriso, char *path, void *in_node, char *creator, char *hfs_type, int flag)
Definition: iso_manip.c:4066
int Xorriso_setfattr(struct XorrisO *xorriso, void *in_node, char *path, size_t in_num_attrs, char **in_names, size_t *in_value_lengths, char **in_values, int flag)
Definition: iso_manip.c:2140
int Xorriso_set_gid(struct XorrisO *xorriso, char *in_path, gid_t gid, int flag)
Definition: iso_manip.c:2025
int Xorriso_widen_hardlink(struct XorrisO *xorriso, void *boss_iter, IsoNode *node, char *abs_path, char *iso_prefix, char *disk_prefix, int flag)
Definition: iso_manip.c:2315
int Xorriso_copy_properties(struct XorrisO *xorriso, char *disk_path, char *img_path, int flag)
Definition: iso_manip.c:726
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__file_start_lba(IsoNode *node, int *lba, int flag)
Definition: iso_tree.c:2259
int Xorriso_get_md5(struct XorrisO *xorriso, void *in_node, char *path, char md5[16], int flag)
Definition: iso_tree.c:1339
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_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_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_report_damage(struct XorrisO *xorriso, char *show_path, IsoNode *node, int flag)
Definition: iso_tree.c:2570
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_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__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_is_split(struct XorrisO *xorriso, char *path, void *node, int flag)
Definition: iso_tree.c:633
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_normalize_img_path(struct XorrisO *xorriso, char *wd, char *img_path, char eff_path[], int flag)
Definition: iso_tree.c:55
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
int isoburn_igopt_new(struct isoburn_imgen_opts **new_o, int flag)
Definition: isoburn.c:1125
int isoburn_igopt_destroy(struct isoburn_imgen_opts **o, int flag)
Definition: isoburn.c:1216
int isoburn_conv_name_chars(struct isoburn_imgen_opts *opts, char *name, size_t name_len, char **result, size_t *result_len, int flag)
Definition: isoburn.c:2038
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)
Definition: lib_mgt.c:519
#define isoburn_igopt_omit_version_numbers
Definition: libisoburn.h:1356
void iso_node_set_permissions(IsoNode *node, mode_t mode)
Definition: node.c:453
IsoStream * iso_file_get_stream(IsoFile *file)
Definition: node.c:1161
int iso_image_add_new_symlink(IsoImage *image, IsoDir *parent, const char *name, const char *dest, IsoSymlink **link)
Definition: tree.c:191
int iso_image_add_new_dir(IsoImage *image, IsoDir *parent, const char *name, IsoDir **dir)
Definition: tree.c:103
void iso_node_unref(IsoNode *node)
Definition: node.c:56
int iso_image_tree_clone(IsoImage *image, IsoNode *node, IsoDir *new_parent, char *new_name, IsoNode **new_node, int flag)
Definition: tree.c:1563
int iso_node_set_attrs(IsoNode *node, size_t num_attrs, char **names, size_t *value_lengths, char **values, int flag)
Definition: node.c:1973
@ LIBISO_DIR
Definition: libisofs.h:229
int iso_dir_get_node(IsoDir *dir, const char *name, IsoNode **node)
Definition: node.c:632
int iso_dir_get_children(const IsoDir *dir, IsoDirIter **iter)
Definition: node.c:1001
off_t iso_file_get_size(IsoFile *file)
Definition: node.c:1144
int iso_node_remove_xinfo(IsoNode *node, iso_node_xinfo_func proc)
Definition: node.c:172
IsoStream * iso_stream_get_input_stream(IsoStream *stream, int flag)
Definition: stream.c:867
int iso_node_get_xinfo(IsoNode *node, iso_node_xinfo_func proc, void **data)
Definition: node.c:213
int iso_node_set_acl_text(IsoNode *node, char *access_text, char *default_text, int flag)
Definition: node.c:2205
int iso_node_take(IsoNode *node)
Definition: node.c:810
void iso_node_set_gid(IsoNode *node, gid_t gid)
Definition: node.c:497
#define ISO_XINFO_NO_CLONE
Definition: libisofs.h:9093
const char * iso_node_get_name(const IsoNode *node)
Definition: node.c:415
int iso_dir_add_node(IsoDir *dir, IsoNode *child, enum iso_replace_mode replace)
Definition: node.c:591
#define ISO_RR_PATH_TOO_LONG
Definition: libisofs.h:9105
int iso_dir_iter_remove(IsoDirIter *iter)
Definition: node.c:1069
IsoDir * iso_node_get_parent(IsoNode *node)
Definition: node.c:908
void iso_node_set_ctime(IsoNode *node, time_t time)
Definition: node.c:545
void iso_node_set_hidden(IsoNode *node, int hide_attrs)
Definition: node.c:558
void iso_node_set_mtime(IsoNode *node, time_t time)
Definition: node.c:513
void iso_node_ref(IsoNode *node)
Definition: node.c:46
int aaip_xinfo_func(void *data, int flag)
Definition: rockridge.c:1118
int iso_node_add_xinfo(IsoNode *node, iso_node_xinfo_func proc, void *data)
Definition: node.c:136
int iso_dir_iter_next(IsoDirIter *iter, IsoNode **node)
Definition: node.c:1035
@ LIBISO_HIDE_ON_JOLIET
Definition: libisofs.h:304
@ LIBISO_HIDE_BUT_WRITE
Definition: libisofs.h:326
@ LIBISO_HIDE_ON_HFSPLUS
Definition: libisofs.h:311
@ LIBISO_HIDE_ON_RR
Definition: libisofs.h:302
mode_t iso_node_get_permissions(const IsoNode *node)
Definition: node.c:462
int iso_image_dir_get_node(IsoImage *image, IsoDir *dir, const char *name, IsoNode **node, int flag)
Definition: node.c:679
#define ISO_RR_NAME_RESERVED
Definition: libisofs.h:9102
void iso_node_set_atime(IsoNode *node, time_t time)
Definition: node.c:529
void iso_dir_iter_free(IsoDirIter *iter)
Definition: node.c:1051
enum IsoNodeType iso_node_get_type(IsoNode *node)
Definition: node.c:321
int iso_node_get_hidden(IsoNode *node)
Definition: node.c:566
void iso_node_set_uid(IsoNode *node, uid_t uid)
Definition: node.c:480
IsoHfsplusBlessings
Definition: libisofs.h:8585
@ ISO_HFSPLUS_BLESS_SHOWFOLDER
Definition: libisofs.h:8593
@ ISO_HFSPLUS_BLESS_OSX_FOLDER
Definition: libisofs.h:8595
@ ISO_HFSPLUS_BLESS_PPC_BOOTDIR
Definition: libisofs.h:8587
@ ISO_HFSPLUS_BLESS_MAX
Definition: libisofs.h:8598
@ ISO_HFSPLUS_BLESS_INTEL_BOOTFILE
Definition: libisofs.h:8590
@ ISO_HFSPLUS_BLESS_OS9_FOLDER
Definition: libisofs.h:8594
#define ISO_RR_NAME_TOO_LONG
Definition: libisofs.h:9099
int iso_node_remove(IsoNode *node)
Definition: node.c:850
time_t iso_node_get_mtime(const IsoNode *node)
Definition: node.c:521
int iso_image_set_node_name(IsoImage *image, IsoNode *node, const char *name, int flag)
Definition: node.c:401
int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name, const char *path, IsoNode **node)
Definition: tree.c:621
int iso_truncate_leaf_name(int mode, int length, char *name, int flag)
Definition: util.c:2477
#define ISO_NODE_NAME_NOT_UNIQUE
Definition: libisofs.h:8766
void iso_node_set_sort_weight(IsoNode *node, int w)
Definition: node.c:1119
int iso_tree_add_new_cut_out_node(IsoImage *image, IsoDir *parent, const char *name, const char *path, off_t offset, off_t size, IsoNode **node)
Definition: tree.c:674
char * Text_shellsafe(char *in_text, char *out_text, int flag)
Definition: misc_funct.c:1044
char * Ftypetxt(mode_t st_mode, int flag)
Definition: misc_funct.c:732
int Xorriso_option_find(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag)
Definition: opts_d_h.c:818
int Xorriso_option_setfacli(struct XorrisO *xorriso, char *acl_text, int argc, char **argv, int *idx, int flag)
Definition: opts_p_z.c:980
int Xorriso_eval_problem_status(struct XorrisO *xorriso, int ret, int flag)
Definition: parse_exec.c:307
int Xorriso_make_abs_adr(struct XorrisO *xorriso, char *wd, char *name, char adr[], int flag)
Definition: parse_exec.c:2812
int Xorriso_path_is_excluded(struct XorrisO *xorriso, char *path, int flag)
Definition: parse_exec.c:3130
int Xorriso_path_is_hidden(struct XorrisO *xorriso, char *path, int flag)
Definition: parse_exec.c:3155
int Xorriso_check_temp_mem_limit(struct XorrisO *xorriso, off_t mem, int flag)
Definition: parse_exec.c:2896
int Xorriso_check_md5(struct XorrisO *xorriso, void *in_node, char *path, int flag)
Definition: read_run.c:2595
int Sfile_type(char *filename, int flag)
Definition: sfile.c:225
int Sfile_count_components(char *path, int flag)
Definition: sfile.c:61
char * Sfile_fgets_n(char *line, int maxl, FILE *fp, int flag)
Definition: sfile.c:33
int Sfile_flatten_utf8_heads(char *name, int idx, int flag)
Definition: sfile.c:971
int Sfile_str(char target[4096], char *source, int flag)
Definition: sfile.c:836
int Sfile_scale(double value, char *result, int siz, double thresh, int flag)
Definition: sfile.c:331
#define Xorriso_free_meM(pt)
Definition: sfile.h:27
#define Xorriso_alloc_meM(pt, typ, count)
Definition: sfile.h:19
int Xorriso_invalidate_di_item(struct XorrisO *xorriso, IsoNode *node, int flag)
Definition: sort_cmp.c:250
int Xorriso_sort_node_array(struct XorrisO *xorriso, int flag)
Definition: sort_cmp.c:82
int Xorriso_search_di_range(struct XorrisO *xorriso, IsoNode *node, int *idx, int *low, int *high, int flag)
Definition: sort_cmp.c:272
int Xorriso__node_lba_cmp(const void *node1, const void *node2)
Definition: sort_cmp.c:308
struct FindjoB * boss
Definition: findjob.h:26
void * arg2
Definition: findjob.h:62
void * arg1
Definition: findjob.h:61
int invert
Definition: findjob.h:28
int test_type
Definition: findjob.h:59
int use_pattern
Definition: findjob.h:191
unsigned long match_count
Definition: findjob.h:220
int action
Definition: findjob.h:189
uint32_t last_data_file_block
Definition: findjob.h:206
char * start_path
Definition: findjob.h:118
int prune
Definition: findjob.h:190
off_t estim_lower_size
Definition: findjob.h:204
off_t estim_upper_size
Definition: findjob.h:203
struct FindjoB * subjob
Definition: findjob.h:205
int depth
Definition: findjob.h:223
Definition: node.h:140
Definition: node.h:149
Definition: node.h:100
off_t pacifier_count
int do_follow_mount
off_t file_size_limit
int find_unique_trunc_result
off_t split_size
int show_hfs_cmd_count
void ** di_array
off_t pacifier_byte_count
int do_follow_links
int find_check_md5_result
char * di_do_widen
int ino_behavior
int do_overwrite
char result_line[10 *4096]
char info_text[10 *4096]
int file_name_limit
int show_hfs_cmd_flag
int request_to_abort
void ** node_array
char ** show_hfs_cmds
int request_not_to_ask
void * in_volset_handle
int update_flags
int node_counter
char wdx[4096]
int node_array_size
int do_follow_param
int temp_mem_limit
int relax_compliance
off_t pacifier_total
char wdi[4096]
uint8_t creator_code[4]
Definition: libisofs.h:8548
uint8_t type_code[4]
Definition: libisofs.h:8549
int Xorriso_msgs_submit(struct XorrisO *xorriso, int error_code, char msg_text[], int os_errno, char severity[], int flag)
Definition: text_io.c:2504
int Xorriso_no_findjob(struct XorrisO *xorriso, char *cmd, int flag)
Definition: text_io.c:4110
int Xorriso_request_confirmation(struct XorrisO *xorriso, int flag)
Definition: text_io.c:493
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
int Xorriso_make_iso_write_opts(struct XorrisO *xorriso, IsoImage *image, struct isoburn_imgen_opts *sopts, int flag)
Definition: write_run.c:866
#define Xorriso_IFBOOT
Definition: xorrisoburn.h:573