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

read_run.c
Go to the documentation of this file.
1 
2 
3 /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
4 
5  Copyright 2007-2020 Thomas Schmitt, <scdbackup@gmx.net>
6 
7  Provided under GPL version 2 or later.
8 
9  This file contains functions which are needed to read data
10  from ISO image.
11 */
12 
13 #ifdef HAVE_CONFIG_H
14 #include "../config.h"
15 #endif
16 
17 #include <ctype.h>
18 #include <sys/types.h>
19 #include <unistd.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <sys/stat.h>
24 #include <sys/time.h>
25 #include <time.h>
26 #include <errno.h>
27 
28 #include <fcntl.h>
29 #include <utime.h>
30 
31 /* O_BINARY is needed for Cygwin but undefined elsewhere */
32 #ifndef O_BINARY
33 #define O_BINARY 0
34 #endif
35 
36 
37 #include "lib_mgt.h"
38 #include "drive_mgt.h"
39 #include "iso_img.h"
40 #include "iso_tree.h"
41 #include "iso_manip.h"
42 #include "read_run.h"
43 #include "sort_cmp.h"
44 
45 
46 int Xorriso__read_pacifier(IsoImage *image, IsoFileSource *filesource)
47 {
48  struct XorrisO *xorriso;
49 
50  xorriso= (struct XorrisO *) iso_image_get_attached_data(image);
51  if(xorriso==NULL)
52  return(1);
53  Xorriso_process_msg_queues(xorriso,0);
54  xorriso->pacifier_count++;
55  if(xorriso->pacifier_count%10)
56  return(1);
57  Xorriso_pacifier_callback(xorriso, "nodes read", xorriso->pacifier_count, 0,
58  "", 0);
59  return(1);
60 }
61 
62 
63 /* @param flag bit0= open IsoNode *node_pt rather than looking up pathname
64  bit1= dig out the most original stream for reading
65 */
66 int Xorriso_iso_file_open(struct XorrisO *xorriso, char *pathname,
67  void *node_pt, void **stream, int flag)
68 {
69  int ret;
70  char *eff_path= NULL;
71  IsoNode *node= NULL;
72  IsoFile *filenode= NULL;
73  IsoStream *iso_stream= NULL, *input_stream;
74 
75  Xorriso_alloc_meM(eff_path, char, SfileadrL);
76 
77  *stream= NULL;
78  if(flag&1) {
79  node= (IsoNode *) node_pt;
80  } else {
81  ret= Xorriso_get_node_by_path(xorriso, pathname, eff_path, &node, 0);
82  if(ret<=0)
83  goto ex;
84  }
85  if(!LIBISO_ISREG(node)) {
86  sprintf(xorriso->info_text,
87  "Given path does not lead to a regular data file in the image");
88  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
89  {ret= 0; goto ex;}
90  }
91 
92  filenode= (IsoFile *) node;
93  iso_stream= iso_file_get_stream(filenode);
94  if(iso_stream==NULL) {
95  Xorriso_process_msg_queues(xorriso,0);
96  sprintf(xorriso->info_text,
97  "Could not obtain source stream of file in the image for reading");
98  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
99  {ret= 0; goto ex;}
100  }
101  if(flag & 2) {
102  /* Dig out the most original stream */
103  while(1) {
104  input_stream= iso_stream_get_input_stream(iso_stream, 0);
105  if(input_stream == NULL)
106  break;
107  iso_stream= input_stream;
108  }
109  }
110  if(!iso_stream_is_repeatable(iso_stream)) {
111  sprintf(xorriso->info_text,
112  "The data production of the file in the image is one-time only");
113  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
114  {ret= 0; goto ex;}
115  }
116  ret= iso_stream_open(iso_stream);
117  if(ret<0) {
118  sprintf(xorriso->info_text,
119  "Could not open data file in the image for reading");
120  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
121  {ret= 0; goto ex;}
122  }
123  Xorriso_process_msg_queues(xorriso,0);
124  *stream= iso_stream;
125 
126 #ifdef NIX
127  /* <<< */
128  {
129  unsigned int fs_id;
130  dev_t dev_id;
131  ino_t ino;
132 
133  iso_stream_get_id(iso_stream, &fs_id, &dev_id, &ino);
134  fprintf(stderr, "xorriso_debug: iso_ino= %ld\n", (long int) ino);
135  }
136 #endif
137 
138  ret= 1;
139 ex:;
140  Xorriso_free_meM(eff_path);
141  return(ret);
142 }
143 
144 
145 int Xorriso_iso_file_read(struct XorrisO *xorriso, void *stream, char *buf,
146  int count, int flag)
147 {
148  int ret, rcnt= 0;
149  IsoStream *stream_pt;
150 
151  stream_pt= (IsoStream *) stream;
152 
153  while(rcnt<count) {
154  ret= iso_stream_read(stream_pt, (void *) (buf+rcnt), (size_t) (count-rcnt));
155  if(ret==0) /* EOF */
156  break;
157  if(ret<0) { /* error */
158  Xorriso_process_msg_queues(xorriso,0);
159  Xorriso_report_iso_error(xorriso, "", ret, "Error on read",
160  0, "FAILURE", 1 | ((ret == -1)<<2) );
161  return(-1);
162  }
163  rcnt+= ret;
164  }
165  return(rcnt);
166 }
167 
168 
169 int Xorriso_iso_file_close(struct XorrisO *xorriso, void **stream, int flag)
170 {
171  int ret;
172 
173  if(*stream==NULL)
174  return(0);
175  ret= iso_stream_close(*stream);
176  if(ret==1)
177  *stream= NULL;
178  Xorriso_process_msg_queues(xorriso,0);
179  return(ret);
180 }
181 
182 
183 /* @param flag bit0= in_node is valid, do not resolve img_path
184  bit1= test mode: print DEBUG messages
185  @return <0 = error,
186  0 = surely not identical regular files ,
187  1 = surely identical
188  2 = potentially depending on unknown disk file (e.g. -cut_out)
189 */
190 int Xorriso_restore_is_identical(struct XorrisO *xorriso, void *in_node,
191  char *img_path, char *disk_path,
192  char type_text[5], int flag)
193 {
194  int ret;
195  unsigned int fs_id;
196  dev_t dev_id;
197  ino_t ino_id;
198  IsoStream *stream;
199  IsoImage *volume;
200  IsoNode *node;
201  struct stat stbuf;
202  int dummy;
203 
204  memset(type_text, 0, 5);
205  if(!Xorriso_change_is_pending(xorriso, 0))
206  return(0);
207  if(flag&1) {
208  node= (IsoNode *) in_node;
209  } else {
210  ret= Xorriso_get_volume(xorriso, &volume, 0);
211  if(ret<=0)
212  return(-1);
213  ret= Xorriso_node_from_path(xorriso, volume, img_path, &node, 1);
214  if(ret<=0)
215  return(-1);
216  }
217  ret= Xorriso__file_start_lba(node, &dummy, 0);
218  if(ret != 0) {
219  Xorriso_process_msg_queues(xorriso, 0);
220  return(0);
221  }
222  if(!LIBISO_ISREG(node))
223  return(0);
224  stream= iso_file_get_stream((IsoFile *) node);
225  memcpy(type_text, stream->class->type, 4);
226  iso_stream_get_id(stream, &fs_id, &dev_id, &ino_id);
227  if(flag&2) {
228  sprintf(xorriso->info_text, "%s : fs=%d dev=%.f ino=%.f (%s)",
229  img_path, fs_id, (double) dev_id, (double) ino_id, type_text);
230  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
231  }
232  ret= stat(disk_path, &stbuf);
233  if(ret==-1)
234  return(0);
235  if(flag&2) {
236  sprintf(xorriso->info_text, "%s : dev=%.f ino=%.f",
237  disk_path, (double) stbuf.st_dev, (double) stbuf.st_ino);
238  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
239  }
240  if(fs_id!=1)
241  return(2);
242 
243  /* >>> obtain underlying dev_t ino_t of type "cout" */;
244 
245  if(strcmp(type_text, "fsrc")!=0)
246  return(2);
247  if(stbuf.st_dev==dev_id && stbuf.st_ino==ino_id)
248  return(1);
249  return(0);
250 }
251 
252 
253 int Xorriso_iso_file_to_fd(struct XorrisO *xorriso, char *path, int fd,
254  int flag)
255 {
256  int ret, rret, wret, to_write, wanted;
257  void *stream= NULL;
258  char *buffer= NULL, *wpt;
259  off_t todo;
260  static int buffer_size= 64 * 1024;
261 
262  Xorriso_alloc_meM(buffer, char, buffer_size);
263 
264  ret= Xorriso_iso_file_open(xorriso, path, NULL, &stream, 0);
265  if(ret <= 0)
266  goto ex;
267 
268  todo= iso_stream_get_size((IsoStream *) stream);
269  while(todo > 0) {
270  if(todo < buffer_size)
271  wanted= todo;
272  else
273  wanted= buffer_size;
274  rret = Xorriso_iso_file_read(xorriso, stream, buffer, wanted, 0);
275  if(rret <= 0)
276  {ret= -1; goto ex;}
277  todo-= rret;
278  wpt= buffer;
279  for(to_write= rret; to_write > 0;) {
280  wret= write(fd, wpt, to_write);
281  if(wret <= 0) {
282  if(wret == 0)
283  sprintf(xorriso->info_text,
284  "Strange behavior of write(2): return == 0 with ");
285  else
286  sprintf(xorriso->info_text, "Write error with ");
287  Text_shellsafe(path, xorriso->info_text, 1);
288  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text,
289  wret == 0 ? 0 : errno, "FAILURE",0);
290  ret= 0; goto ex;
291  }
292  to_write-= wret;
293  wpt+= wret;
294  }
295  }
296  ret= 1;
297 ex:;
298  if(stream != NULL)
299  Xorriso_iso_file_close(xorriso, &stream, 0);
300  Xorriso_free_meM(buffer);
301  return(ret);
302 }
303 
304 
305 /* @param flag bit0= minimal transfer: access permissions only
306  bit1= keep directory open: keep owner, allow rwx for owner
307  and push directory onto xorriso->perm_stack
308 */
309 int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path,
310  IsoNode *node, int flag)
311 {
312  int ret, is_dir= 0, errno_copy= 0, local_attrs_set= 0, i, err_count;
313  mode_t mode;
314  uid_t uid, disk_uid;
315  gid_t gid, disk_gid;
316  struct utimbuf utime_buffer;
317  struct stat stbuf;
318  size_t num_attrs= 0, *value_lengths= NULL;
319  char **names= NULL, **values= NULL;
320  int *errnos= NULL;
321 
322  ret= lstat(disk_path, &stbuf);
323  if(ret==-1) {
324  sprintf(xorriso->info_text,
325  "Cannot obtain properties of disk file ");
326  Text_shellsafe(disk_path, xorriso->info_text, 1);
327  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
328  {ret= 0; goto ex;}
329  }
330  disk_uid= uid= stbuf.st_uid;
331  disk_gid= stbuf.st_gid;
332 
333  is_dir= S_ISDIR(stbuf.st_mode);
334 
335  mode= iso_node_get_permissions(node);
336 
337  if(xorriso->do_aaip & (2 | 8 | 16)) {
338  ret= iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values,
339  (!!(xorriso->do_aaip & 2)) | (!(xorriso->do_aaip & (8 | 16))) << 2);
340  if (ret < 0) {
341  strcpy(xorriso->info_text, "Error with obtaining ACL and xattr for ");
342  Text_shellsafe(disk_path, xorriso->info_text, 1);
343  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
344  {ret= 0; goto ex;}
345  }
346  if(num_attrs > 0) {
347  Xorriso_alloc_meM(errnos, int, num_attrs);
348  ret= iso_local_set_attrs_errno(disk_path, num_attrs, names, value_lengths,
349  values, errnos,
350  ((!(xorriso->do_strict_acl & 1)) << 6) |
351  ((!!(xorriso->do_aaip & 1024)) << 3) );
352  if(ret < 0) {
353 cannot_set_xattr:;
354  errno_copy= errno;
355  if(ret != (int) ISO_AAIP_NO_SET_LOCAL)
356  errno_copy= 0;
357  Xorriso_report_iso_error(xorriso, "", ret,
358  "Error on iso_local_set_attrs",
359  0, "FAILURE", 1 | ((ret == -1)<<2) );
360  sprintf(xorriso->info_text, "Disk file ");
361  Text_shellsafe(disk_path, xorriso->info_text, 1);
362  err_count= 0;
363  for(i= 0; (unsigned int) i < num_attrs; i++) {
364  if(errnos[i] == 0)
365  continue;
366  if(err_count >= 3) {
367  strcat(xorriso->info_text, " , and more");
368  break;
369  }
370  err_count++;
371  errno_copy= 0; /* Detail errno overrides final errno */
372  if(names[i][0] == 0)
373  sprintf(xorriso->info_text + strlen(xorriso->info_text), " , ACL ");
374  else
375  sprintf(xorriso->info_text + strlen(xorriso->info_text),
376  " , xattr %s ", names[i]);
377  if(errnos[i] < 0)
378  Text_shellsafe("Unknown error", xorriso->info_text, 1);
379  else
380  Text_shellsafe(strerror(errnos[i]), xorriso->info_text, 1);
381  }
382  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno_copy,
383  "FAILURE",0);
384  {ret= 0; goto ex;}
385  }
386  local_attrs_set= 1;
387  }
388  Xorriso_process_msg_queues(xorriso,0);
389  }
390  if(!(xorriso->do_aaip & 2))
391  mode= iso_node_get_perms_wo_acl(node);
392 
393  if(is_dir && (flag&2)) {
394  ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node,
395  1 | ((!!(xorriso->do_aaip & 2)) << 3));
396  if(ret<=0)
397  {ret= 0; goto ex;}
398  ret= Permstack_push(&(xorriso->perm_stack), disk_path, &stbuf, 0);
399  if(ret<=0) {
400  Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
401  strcpy(xorriso->info_text,
402  "Cannot memorize permissions for disk directory");
403  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
404  {ret= -1; goto ex;}
405  }
406  mode|= S_IRUSR|S_IWUSR|S_IXUSR;
407  }
408  ret= chmod(disk_path, mode);
409  if(ret==-1) {
410 cannot_set_perm:;
411  sprintf(xorriso->info_text,
412  "Cannot change access permissions of disk file ");
413  Text_shellsafe(disk_path, xorriso->info_text, 1);
414  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
415  {ret= 0; goto ex;}
416  }
417 
418  if(flag&1)
419  {ret= 1; goto ex;}
420 
421  utime_buffer.actime= iso_node_get_atime(node);
422  utime_buffer.modtime= iso_node_get_mtime(node);
423  ret= utime(disk_path,&utime_buffer);
424  if(ret==-1) {
425  sprintf(xorriso->info_text,
426  "Cannot change atime, mtime of disk file ");
427  Text_shellsafe(disk_path, xorriso->info_text, 1);
428  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
429  {ret= 0; goto ex;}
430  }
431 
432  gid= iso_node_get_gid(node);
433  if(!(S_ISDIR(stbuf.st_mode) && (flag&2)))
434  uid= iso_node_get_uid(node);
435 
436  if(uid != disk_uid || gid != disk_gid) {
437 
438  ret= chown(disk_path, uid, gid); /* don't complain if it fails */
439 
440  /* Check whether xattr are still set and try to set them again if needed.
441  E.g. Linux 3.16 removes security.capability on chown(2).
442  */
443  if(local_attrs_set && (xorriso->do_aaip & 1024)) {
444  ret= iso_local_set_attrs_errno(disk_path, num_attrs, names, value_lengths,
445  values, errnos,
446  1 | ((!!(xorriso->do_aaip & 1024)) << 3) |
447  128);
448  if(ret < 0)
449  goto cannot_set_xattr;
450  }
451 
452  /* Check whether setuid or setgid bits got reset */
453  ret= lstat(disk_path, &stbuf);
454  if(ret != -1) {
455  if((mode ^ stbuf.st_mode) & (S_ISUID | S_ISGID)) {
456  ret= chmod(disk_path, mode);
457  if(ret==-1)
458  goto cannot_set_perm;
459  }
460  }
461 
462  }
463  ret= 1;
464 ex:;
465  iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values,1 << 15);
466  if(errnos != NULL)
467  free(errnos);
468  return(ret);
469 }
470 
471 
472 /* @param flag
473  bit1= minimal transfer: access permissions only
474  bit2= keep directory open: keep owner, allow rwx for owner
475  push to xorriso->perm_stack
476 */
478  char *full_disk_path, char *disk_path, char *full_img_path, int flag)
479 {
480  int ret, nfic, ndc, nfdc, d, i;
481  char *nfi= NULL, *nd= NULL, *nfd= NULL, *cpt;
482  struct stat stbuf;
483  IsoNode *node;
484 
485  Xorriso_alloc_meM(nfi, char, SfileadrL);
486  Xorriso_alloc_meM(nd, char, SfileadrL);
487  Xorriso_alloc_meM(nfd, char, SfileadrL);
488 
489  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, full_disk_path, nfd,
490  1|2|4);
491  if(ret<=0)
492  goto ex;
493  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, nd, 1|2);
494  if(ret<=0)
495  goto ex;
496  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, full_img_path, nfi,
497  1|2);
498  if(ret<=0)
499  goto ex;
500  nfdc= Sfile_count_components(nfd, 0);
501  ndc= Sfile_count_components(nd, 0);
502  nfic= Sfile_count_components(nfi, 0);
503  d= nfdc-ndc;
504  if(d<0)
505  {ret= -1; goto ex;}
506  if(d>nfic)
507  {ret= 0; goto ex;}
508  for(i= 0; i<d; i++) {
509  cpt= strrchr(nfi, '/');
510  if(cpt==NULL)
511  {ret= -1; goto ex;} /* should not happen */
512  *cpt= 0;
513  }
514  if(nfi[0]==0)
515  strcpy(nfi, "/");
516  ret= Xorriso_fake_stbuf(xorriso, nfi, &stbuf, &node, 0);
517  if(ret<=0)
518  {ret= 0; goto ex;}
519  ret= Xorriso_restore_properties(xorriso, nd, node, ((flag>>1)&3));
520  if(ret<=0)
521  goto ex;
522  sprintf(xorriso->info_text, "Restored properties for ");
523  Text_shellsafe(nd, xorriso->info_text, 1);
524  strcat(xorriso->info_text, " from ");
525  Text_shellsafe(nfi, xorriso->info_text, 1 | 2);
526  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
527  ret= 1;
528 ex:;
529  Xorriso_free_meM(nfi);
530  Xorriso_free_meM(nd);
531  Xorriso_free_meM(nfd);
532  return(ret);
533 }
534 
535 
536 /* If defined the position accounting will be done by lseek() and used to
537  * verify the position accounting in struct Xorriso_sparse_statE.
538  * # def ine Xorriso_check_sparsE yes
539  */
540 
543  off_t cur_pos;
545  int warnings;
546 };
547 
548 
549 #ifdef Xorriso_check_sparsE
550 
551 static int Xorriso_sparse_warn(struct XorrisO *xorriso,
552  struct Xorriso_sparse_statE *sparse_state,
553  int occasion, char *msg, int flag)
554 {
555  if(sparse_state->warnings & (1 << occasion))
556  return(1);
557  sparse_state->warnings|= 1 << occasion;
558  Xorriso_msgs_submit(xorriso, 0, msg, 0, "SORRY", 0);
559  return(1);
560 }
561 
562 #endif /* Xorriso_check_sparsE */
563 
564 
565 static int Xorriso_sparse_init(struct XorrisO *xorriso,
566  struct Xorriso_sparse_statE **sparse_state,
567  int write_fd, int flag)
568 {
569  struct Xorriso_sparse_statE *o= NULL;
570  off_t cur_pos;
571  struct stat stbuf;
572  int ret;
573 
574  *sparse_state= NULL;
575 
576  /* Check whether sparse writing is disabled */
577  if(xorriso->sparse_min_gap <= 0)
578  {ret= 0; goto ex;}
579 
580  /* Analyze write_fd */
581  ret= fstat(write_fd, &stbuf);
582  if(ret == -1)
583  {ret= 0; goto ex;}
584  if(!S_ISREG(stbuf.st_mode))
585  {ret= 0; goto ex;}
586  cur_pos= lseek(write_fd, (off_t) 0, SEEK_CUR);
587  if(cur_pos < stbuf.st_size)
588  {ret= 0; goto ex;}
589 
591 
592  /* Initialize sparse_state */
593  o->use_lseek= 1;
594  o->cur_pos= o->after_last_written= cur_pos;
595  o->warnings= 0;
596 
597  ret= 1;
598 ex:;
599  if(ret >= 1)
600  *sparse_state= o;
601  else
602  Xorriso_free_meM(o);
603  return(ret);
604 }
605 
606 
607 static int Xorriso_sparse_zeroize(struct XorrisO *xorriso,
608  struct Xorriso_sparse_statE *sparse_state,
609  int write_fd, off_t start, off_t count,
610  int flag)
611 {
612  int ret, buf_size= 32 * 1024, buf_fill, wret;
613  off_t todo, seek_ret;
614  char *buf= NULL;
615 
616  if(count <= 0)
617  {ret= 2; goto ex;}
618  Xorriso_alloc_meM(buf, char, buf_size);
619 
620  seek_ret= lseek(write_fd, start, SEEK_SET);
621  if(seek_ret == -1)
622  {ret= -1; goto ex;}
623  sparse_state->cur_pos= seek_ret;
624  for(todo= count; todo > 0; ) {
625  if(buf_size < todo)
626  buf_fill= buf_size;
627  else
628  buf_fill= todo;
629  wret= write(write_fd, buf, buf_fill);
630  if(wret <= 0)
631  {ret= wret; goto ex;}
632  todo-= wret;
633  sparse_state->cur_pos+= wret;
634  }
635  ret= 1;
636 ex:;
637  Xorriso_free_meM(buf);
638  return(ret);
639 }
640 
641 
642 /* @param flag bit0= this is the last buffer of the stream
643 */
644 static int Xorriso_sparse_write(struct XorrisO *xorriso,
645  struct Xorriso_sparse_statE *sparse_state,
646  int write_fd, char *buf, int count,
647  int flag)
648 {
649  int wret, i, ret;
650  off_t cur_pos= -1, seek_ret;
651  static char zero[32]= {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
652  0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
653 
654  if(sparse_state == NULL)
655  goto do_write;
656  if(!sparse_state->use_lseek)
657  goto do_write;
658  if(flag & 1)
659  goto do_write;
660 
661 #ifdef Xorriso_check_sparsE
662 
663  cur_pos= lseek(write_fd, (off_t) 0, SEEK_CUR);
664  if(cur_pos == -1)
665  goto do_write;
666  if(cur_pos != sparse_state->cur_pos) {
667  Xorriso_sparse_warn(xorriso, sparse_state, 0,
668  "cur_pos deviation in Xorriso_sparse_write:intro", 0);
669  sparse_state->cur_pos= cur_pos;
670  }
671 
672 #else
673 
674  cur_pos= sparse_state->cur_pos;
675 
676 #endif
677 
678  /* Check for all zeros */
679  if(count % 32)
680  goto do_write;
681  for(i= 0; i < count; i+= 32)
682  if(memcmp(buf + i, zero, 32))
683  break;
684  if(i < count)
685  goto do_write;
686 
687  /* Omit write() until next non-zero buffer or end of writing */
688 
689 #ifdef Xorriso_check_sparsE
690 
691  /* Only for debugging: Do real lseek() instead of write() */
692  seek_ret= lseek(write_fd, cur_pos + count, SEEK_SET);
693  if(seek_ret == -1)
694  return(-1);
695 
696 #endif
697 
698  sparse_state->cur_pos= cur_pos + count;
699  return(count);
700 
701 do_write:
702  if(sparse_state != NULL) {
703  /* Check whether the gap since after_last_written is too small.
704  If so: fill the whole gap by writing zeros.
705  */
706  if(sparse_state->after_last_written < cur_pos) {
707  if(xorriso->sparse_min_gap > cur_pos - sparse_state->after_last_written) {
708  ret= Xorriso_sparse_zeroize(xorriso, sparse_state, write_fd,
709  sparse_state->after_last_written,
710  cur_pos - sparse_state->after_last_written, 0);
711  if(ret < 0)
712  return(ret);
713  if(ret == 0) {
714  seek_ret= lseek(write_fd, cur_pos, SEEK_SET);
715  if(seek_ret == -1)
716  return(-1);
717  sparse_state->cur_pos= seek_ret;
718  }
719  }
720  }
721  }
722 
723 
724  if(sparse_state != NULL) {
725 
726 #ifdef Xorriso_check_sparsE
727 
728  cur_pos= lseek(write_fd, (off_t) 0, SEEK_CUR);
729  if(cur_pos != sparse_state->cur_pos) {
730  Xorriso_sparse_warn(xorriso, sparse_state, 1,
731  "cur_pos deviation in Xorriso_sparse_write:do_write", 0);
732  sparse_state->cur_pos= cur_pos;
733  }
734 
735 #else
736 
737  /* lseek() has been delayed until now */
738  if(sparse_state->after_last_written != sparse_state->cur_pos) {
739  seek_ret= lseek(write_fd, sparse_state->cur_pos, SEEK_SET);
740  if(seek_ret == -1)
741  return(-1);
742  }
743 
744 #endif /* ! Xorriso_check_sparsE */
745 
746  }
747  wret= write(write_fd, buf, count);
748  if(sparse_state != NULL && wret > 0 && cur_pos >= 0)
749  sparse_state->cur_pos= sparse_state->after_last_written= cur_pos + wret;
750  return(wret);
751 }
752 
753 
754 static int Xorriso_sparse_finish(struct XorrisO *xorriso,
755  struct Xorriso_sparse_statE **sparse_state,
756  int write_fd, int flag)
757 {
758  int ret;
759  off_t cur_pos;
760  struct Xorriso_sparse_statE *o;
761 
762  if(sparse_state == NULL)
763  return(0);
764  o= *sparse_state;
765  if(o == NULL)
766  return(1);
767  if(write_fd == -1)
768  {ret= 1; goto ex;}
769 
770 #ifdef Xorriso_check_sparsE
771 
772  cur_pos= lseek(write_fd, (off_t) 0, SEEK_CUR);
773  if(cur_pos == -1)
774  {ret= -1; goto ex;}
775  if(cur_pos != o->cur_pos) {
776  Xorriso_sparse_warn(xorriso, o, 2,
777  "cur_pos deviation in Xorriso_sparse_finish", 0);
778  o->cur_pos= cur_pos;
779  }
780 
781 #else
782 
783  cur_pos= o->cur_pos;
784 
785 #endif /* ! Xorriso_check_sparsE */
786 
787  if(o->after_last_written < cur_pos) {
788  /* Check whether the gap since after_last_written is too small.
789  If so: fill the whole gap by writing zeros, else: write a last zero byte.
790  */
791  if(xorriso->sparse_min_gap > cur_pos - o->after_last_written)
792  ret= Xorriso_sparse_zeroize(xorriso, o, write_fd, o->after_last_written,
793  cur_pos - o->after_last_written, 0);
794  else
795  ret= Xorriso_sparse_zeroize(xorriso, o, write_fd, cur_pos - 1, (off_t) 1,
796  0);
797  if(ret <= 0)
798  goto ex;
799  }
800  ret= 1;
801 ex:;
802  Xorriso_free_meM(o);
803  *sparse_state= NULL;
804  return(ret);
805 }
806 
807 
808 /* @param flag bit0= Minimal transfer: access permissions only
809  bit1= *_offset and bytes are valid for writing to regular file
810  bit2= This is not a parameter. Do not report if ignored
811  bit3= do not restore properties
812  bit4= issue pacifier messages with long lasting copying
813  bit7= return 4 if restore fails from denied permission
814  do not issue error message
815  @return <0 severe error , 0 failure , 1 success ,
816  2 regularly not installed (disallowed device, UNIX domain socket)
817  4 with bit7: permission to restore was denied
818 */
819 int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
820  char *img_path, off_t img_offset,
821  char *disk_path, off_t disk_offset, off_t bytes,
822  int flag)
823 {
824  int ret= 0, write_fd= -1, wanted, wret, open_flags, l_errno= 0;
825  int target_deleted= 0, buf_size= 32 * 1024;
826  char *what= "[unknown filetype]";
827  char *buf= NULL, type_text[5], *temp_path= NULL, *buf_pt;
828  char *link_target, *open_path_pt= NULL;
829  off_t todo= 0, size, seek_ret, last_p_count= 0, already_done, read_count= 0;
830  void *data_stream= NULL;
831  mode_t mode;
832  dev_t dev= 0;
833  struct stat stbuf;
834  struct utimbuf utime_buffer;
835  IsoImage *volume;
836  IsoBoot *bootcat;
837  uint32_t lba;
838  char *catcontent = NULL;
839  off_t catsize;
840  char disk_md5[16], iso_md5[16];
841  void *ctx= NULL;
842  int use_md5= 0, i, sparse_ret= 3;
843  struct Xorriso_sparse_statE *sparse_state= NULL;
844 
845  Xorriso_alloc_meM(buf, char, buf_size);
846  Xorriso_alloc_meM(temp_path, char, SfileadrL);
847 
848  if(!(flag & 2))
849  img_offset= bytes= 0;
850  if(LIBISO_ISDIR(node)) {
851  what= "directory";
852  ret= mkdir(disk_path, 0777);
853  l_errno= errno;
854 
855  } else if(LIBISO_ISREG(node) || ISO_NODE_IS_BOOTCAT(node)) {
856  if(ISO_NODE_IS_BOOTCAT(node)) {
857  what= "boot catalog";
858  } else {
859  what= "regular file";
860  ret= Xorriso_iso_file_open(xorriso, img_path, (void *) node, &data_stream,
861  1);
862  if(ret<=0)
863  goto ex;
864  if((xorriso->do_md5 & 65) == 65 && !(flag & 2)) {
865  ret= Xorriso_is_plain_image_file(xorriso, (void *) node, img_path, 0);
866  if(ret > 0) {
867  ret= Xorriso_get_md5(xorriso, (void *) node, img_path, iso_md5, 1);
868  if(ret > 0)
869  ret= Xorriso_md5_start(xorriso, &ctx, 0);
870  if(ret > 0) {
871  use_md5= 1;
872  } else if(xorriso->do_md5 & 128) {
873  sprintf(xorriso->info_text,
874  "Cannot obtain any recorded MD5 of file ");
875  Text_shellsafe(img_path, xorriso->info_text, 1);
876  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
877  ret= Xorriso_eval_problem_status(xorriso, 0, 1 | 2);
878  if(ret < 0)
879  {ret= 0; goto ex;}
880  }
881  }
882  }
883  }
884  open_path_pt= disk_path;
885  ret= stat(open_path_pt, &stbuf);
886  if(ret == -1 && errno == EACCES && (flag & 128))
887  {ret= 4; goto ex;}
888  if(flag&2) {
889  if(ret!=-1 && !S_ISREG(stbuf.st_mode)) {
890  sprintf(xorriso->info_text,
891  "Restore offset demanded. But filesystem path leads to non-data file ");
892  Text_shellsafe(disk_path, xorriso->info_text, 1);
893  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
894  l_errno= 0;
895  goto cannot_restore;
896  }
897  } else {
898  /* If source and target are the same disk file then do not copy content */
899  ret= Xorriso_restore_is_identical(xorriso, (void *) node, img_path,
900  disk_path, type_text, 1);
901  if(ret<0)
902  goto ex;
903  if(ret==1) {
904  /* preliminarily emulate touch (might get overridden later) */
905  utime_buffer.actime= stbuf.st_atime;
906  utime_buffer.modtime= time(0);
907  utime(disk_path,&utime_buffer);
908  goto restore_properties;
909  }
910  if(ret==2) {
911  /* Extract to temporary file and rename only after copying */
912  ret= Xorriso_make_tmp_path(xorriso, disk_path, temp_path, &write_fd,
913  128);
914  if(ret <= 0 || ret == 4)
915  goto ex;
916  open_path_pt= temp_path;
917  }
918  }
919  if(write_fd==-1) {
920  open_flags= O_WRONLY|O_CREAT;
921  if(disk_offset==0 || !(flag&2))
922  open_flags|= O_EXCL;
923  write_fd= open(open_path_pt, open_flags | O_BINARY, S_IRUSR | S_IWUSR);
924  l_errno= errno;
925  if(write_fd == -1 && errno == EACCES && (flag & 128))
926  {ret= 4; goto ex;}
927  if(write_fd==-1)
928  goto cannot_restore;
929  }
930  if(ISO_NODE_IS_BOOTCAT(node)) {
931  ret= Xorriso_get_volume(xorriso, &volume, 0);
932  if(ret<=0)
933  goto ex;
934  ret= iso_image_get_bootcat(volume, &bootcat, &lba, &catcontent, &catsize);
935  if(ret < 0)
936  goto ex;
937  todo= size= catsize;
938  } else {
939  todo= size= iso_file_get_size((IsoFile *) node);
940  }
941  if(flag&2) {
942  if(bytes<size)
943  todo= size= bytes;
944  seek_ret= lseek(write_fd, disk_offset, SEEK_SET);
945  l_errno= errno;
946  if(seek_ret == -1) {
947  sprintf(xorriso->info_text,
948  "Cannot address byte %.f in filesystem path ",
949  (double) disk_offset);
950  Text_shellsafe(open_path_pt, xorriso->info_text, 1);
951  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
952  goto cannot_restore;
953  }
954  }
955  if(ISO_NODE_IS_FILE(node))
956  Xorriso_sparse_init(xorriso, &sparse_state, write_fd, 0);
957 
958  while(todo>0) {
959  wanted= buf_size;
960  if(wanted>todo)
961  wanted= todo;
962  if(ISO_NODE_IS_BOOTCAT(node)) {
963  ret= todo;
964  buf_pt= catcontent;
965  } else {
966  ret= Xorriso_iso_file_read(xorriso, data_stream, buf, wanted, 0);
967  buf_pt= buf;
968  }
969  if(ret<=0) {
970  if(xorriso->extract_error_mode == 0 &&
971  Xorriso_is_plain_image_file(xorriso, node, "", 0)) {
972  close(write_fd);
973  write_fd= -1;
974  already_done= (size - todo) / (off_t) 2048;
975  already_done*= (off_t) 2048;
976  sprintf(xorriso->info_text,
977  "Starting best_effort handling on ISO file ");
978  Text_shellsafe(img_path, xorriso->info_text, 1);
979  sprintf(xorriso->info_text + strlen(xorriso->info_text),
980  " at byte %.f", (double) already_done);
981  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
982  ret= Xorriso_read_file_data(xorriso, node, img_path, open_path_pt,
983  already_done, already_done, size - already_done, 2);
984  if(ret >= 0)
985  xorriso->pacifier_byte_count+= todo;
986  if(ret > 0)
987  todo= 0;
988  else
989  todo= -1;
990  }
991  if(ret <= 0) {
992  sprintf(xorriso->info_text, "Cannot read all bytes from ISO file ");
993  Text_shellsafe(img_path, xorriso->info_text, 1);
994  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
995  }
996  break;
997  }
998  read_count+= ret;
999  if(use_md5)
1000  Xorriso_md5_compute(xorriso, ctx, buf_pt, ret, 0);
1001 
1002  if(img_offset > read_count - ret) {
1003  /* skip the desired amount of bytes */
1004  if(read_count <= img_offset)
1005  continue;
1006  buf_pt= buf_pt + (img_offset - (read_count - ret));
1007  ret= read_count - img_offset;
1008  }
1009 
1010  if(sparse_state == NULL)
1011  wret= write(write_fd, buf_pt, ret);
1012  else
1013  wret= Xorriso_sparse_write(xorriso, sparse_state, write_fd, buf_pt, ret,
1014  0);
1015  if(wret>=0) {
1016  todo-= wret;
1017  xorriso->pacifier_byte_count+= wret;
1018  if((flag&16) &&
1019  xorriso->pacifier_byte_count - last_p_count >= 128*1024) {
1020  Xorriso_pacifier_callback(xorriso, "files restored",
1021  xorriso->pacifier_count,
1022  xorriso->pacifier_total, "", 2 | 4 | 8);
1023  last_p_count= xorriso->pacifier_byte_count;
1024  }
1025  }
1026  if(wret != ret) {
1027  sprintf(xorriso->info_text,
1028  "Cannot write all bytes to disk filesystem path ");
1029  Text_shellsafe(open_path_pt, xorriso->info_text, 1);
1030  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
1031  break;
1032  }
1033  }
1034 
1035  if(use_md5) {
1036  ret= Xorriso_md5_end(xorriso, &ctx, disk_md5, 0);
1037  if(ret <= 0) {
1038  sprintf(xorriso->info_text,
1039  "Internal problem with obtaining computed MD5 for extracted data of ");
1040  goto bad_md5;
1041  } else {
1042  for(i= 0; i < 16; i++)
1043  if(iso_md5[i] != disk_md5[i])
1044  break;
1045  if(i < 16) {
1046  sprintf(xorriso->info_text,
1047  "MD5 of extracted data does not match recorded MD5 of file ");
1048 bad_md5:;
1049  Text_shellsafe(img_path, xorriso->info_text, 1);
1050  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
1051  ret= Xorriso_eval_problem_status(xorriso, 0, 1 | 2);
1052  if(ret < 0)
1053  {ret= 0; goto ex;}
1054  }
1055  }
1056  }
1057 
1058  if(write_fd != -1) {
1059  sparse_ret= Xorriso_sparse_finish(xorriso, &sparse_state, write_fd, 0);
1060  close(write_fd);
1061  }
1062  write_fd= -1;
1063  if(todo > 0 && xorriso->extract_error_mode == 2) {
1064  unlink(open_path_pt);
1065  target_deleted= 1;
1066  }
1067  if(! ISO_NODE_IS_BOOTCAT(node))
1068  Xorriso_iso_file_close(xorriso, &data_stream, 0);
1069  data_stream= NULL;
1070  if(temp_path==open_path_pt && !target_deleted) {
1071  ret= rename(temp_path, disk_path);
1072  if(ret==-1) {
1073  sprintf(xorriso->info_text, "Cannot rename temporary path ");
1074  Text_shellsafe(temp_path, xorriso->info_text, 1);
1075  strcat(xorriso->info_text, " to final disk path ");
1076  Text_shellsafe(disk_path, xorriso->info_text, 1 | 2);
1077  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
1078  unlink(temp_path);
1079  ret= 0; goto ex;
1080  }
1081  }
1082  ret= -(todo > 0);
1083  l_errno= 0;
1084  if(sparse_ret <= 0) {
1085  strcpy(xorriso->info_text, "Could not finalize sparse extraction of ");
1086  Text_shellsafe(disk_path, xorriso->info_text, 1 | 2);
1087  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text,
1088  sparse_ret < 0 ? errno : 0, "FAILURE", 0);
1089  }
1090 
1091  } else if(LIBISO_ISLNK(node)) {
1092  what= "symbolic link";
1093  link_target= (char *) iso_symlink_get_dest((IsoSymlink *) node);
1094  ret= symlink(link_target, disk_path);
1095  l_errno= errno;
1096 
1097  } else if(LIBISO_ISCHR(node)) {
1098  what= "character device";
1099  if(xorriso->allow_restore!=2) {
1100 ignored:;
1101  if(!(flag&4)) {
1102  sprintf(xorriso->info_text, "Ignored file type: %s ", what);
1103  Text_shellsafe(img_path, xorriso->info_text, 1);
1104  strcat(xorriso->info_text, " = ");
1105  Text_shellsafe(disk_path, xorriso->info_text, 1 | 2);
1106  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1107  }
1108  {ret= 2; goto ex;}
1109  }
1110  mode= S_IFCHR | 0777;
1111  ret= Xorriso_node_get_dev(xorriso, node, img_path, &dev, 0);
1112  if(ret<=0)
1113  goto ex;
1114  if(dev == (dev_t) 1) {
1115 probably_damaged:;
1116  sprintf(xorriso->info_text,
1117  "Most probably damaged device file not restored: mknod ");
1118  Text_shellsafe(disk_path, xorriso->info_text, 1);
1119  sprintf(xorriso->info_text + strlen(xorriso->info_text),
1120  " %s 0 1", LIBISO_ISCHR(node) ? "c" : "b");
1121  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
1122  ret= 0; goto ex;
1123  }
1124  ret= mknod(disk_path, mode, dev);
1125  l_errno= errno;
1126 
1127  } else if(LIBISO_ISBLK(node)) {
1128  what= "block device";
1129  if(xorriso->allow_restore!=2)
1130  goto ignored;
1131  mode= S_IFBLK | 0777;
1132  ret= Xorriso_node_get_dev(xorriso, node, img_path, &dev, 0);
1133  if(ret<=0)
1134  goto ex;
1135  if(dev == (dev_t) 1)
1136  goto probably_damaged;
1137  ret= mknod(disk_path, mode, dev);
1138  l_errno= errno;
1139 
1140  } else if(LIBISO_ISFIFO(node)) {
1141  what= "named pipe";
1142  mode= S_IFIFO | 0777;
1143  ret= mknod(disk_path, mode, dev);
1144  l_errno= errno;
1145 
1146  } else if(LIBISO_ISSOCK(node)) {
1147  what= "unix socket";
1148  /* Restoring a socket file is not possible. One rather needs to restart
1149  the service which temporarily created the socket. */
1150  goto ignored;
1151 
1152  } else {
1153  sprintf(xorriso->info_text, "Cannot restore file type '%s'", what);
1154  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
1155  ret= 0; goto ex;
1156 
1157  }
1158  if(ret == -1 && l_errno == EACCES && (flag & 128))
1159  {ret= 4; goto ex;}
1160  if(ret==-1) {
1161 cannot_restore:;
1162  sprintf(xorriso->info_text,
1163  "Cannot restore %s to disk filesystem: ", what);
1164  Text_shellsafe(img_path, xorriso->info_text, 1);
1165  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, l_errno, "FAILURE", 0);
1166  ret= 0; goto ex;
1167  }
1168 
1169 restore_properties:;
1170  if((flag&8) || LIBISO_ISLNK(node))
1171  ret= 1;
1172  else
1173  ret= Xorriso_restore_properties(xorriso, disk_path, node, flag&1);
1174  if(todo < 0)
1175  ret= 0;
1176 ex:;
1177  if(write_fd != -1) {
1178  close(write_fd);
1179  if(ret <= 0 && xorriso->extract_error_mode == 2 && open_path_pt != NULL)
1180  unlink(open_path_pt);
1181  }
1182  Xorriso_free_meM(buf);
1183  Xorriso_free_meM(temp_path);
1184  if(catcontent != NULL)
1185  free(catcontent);
1186  if(data_stream!=NULL)
1187  Xorriso_iso_file_close(xorriso, &data_stream, 0);
1188  if(ctx != NULL)
1189  Xorriso_md5_end(xorriso, &ctx, disk_md5, 0);
1190  if(sparse_state != NULL)
1191  Xorriso_sparse_finish(xorriso, &sparse_state, -1, 0);
1192  Xorriso_process_msg_queues(xorriso,0);
1193  return(ret);
1194 }
1195 
1196 
1197 /* Handle overwrite situation in disk filesystem.
1198  @param node intended source of overwriting or NULL
1199  @param flag
1200  bit4= return 3 on rejection by exclusion or user
1201  bit6= permission to call Xorriso_make_accessible()
1202 */
1204  IsoNode *node, char *img_path,
1205  char *path, char *nominal_path,
1206  struct stat *stbuf, int flag)
1207 {
1208  int ret;
1209  char type_text[5];
1210 
1211  Xorriso_process_msg_queues(xorriso,0);
1212  if(xorriso->do_overwrite==1 ||
1213  (xorriso->do_overwrite==2 && !S_ISDIR(stbuf->st_mode))) {
1214 
1215  ret= Xorriso_restore_is_identical(xorriso, (void *) node, img_path,
1216  path, type_text, (node!=NULL));
1217  if(ret<0)
1218  return(ret);
1219  if(ret>0) /* will be handled properly by restore functions */
1220  ret= Xorriso_reassure_restore(xorriso, path, 8);
1221  else
1222  ret= Xorriso_rmx(xorriso, (off_t) 0, path, 8 | (flag & 64));
1223  if(ret<=0)
1224  return(ret);
1225  if(ret==3) {
1226  sprintf(xorriso->info_text, "User revoked restoring of (ISO) file: ");
1227  Text_shellsafe(img_path, xorriso->info_text, 1);
1228  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1229  return(3*!!(flag&16));
1230  }
1231  return(1);
1232  }
1233  Xorriso_msgs_submit(xorriso, 0, nominal_path, 0, "ERRFILE", 0);
1234  sprintf(xorriso->info_text, "While restoring ");
1235  Text_shellsafe(nominal_path, xorriso->info_text, 1);
1236  strcat(xorriso->info_text, " : ");
1237  if(strcmp(nominal_path, path) == 0)
1238  strcat(xorriso->info_text, "file object");
1239  else
1240  Text_shellsafe(path, xorriso->info_text, 1 | 2);
1241  strcat(xorriso->info_text, " exists and may not be overwritten");
1242  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1243  return(0);
1244 }
1245 
1246 
1247 /*
1248  @return <0 error,
1249  bit0= hardlink created
1250  bit1= siblings with target NULL found
1251  bit2= siblings with non-NULL target found
1252 */
1253 int Xorriso_restore_target_hl(struct XorrisO *xorriso, IsoNode *node,
1254  char *disk_path, int *node_idx, int flag)
1255 {
1256  int ret, min_hl, max_hl, i, null_target_sibling= 0, link_sibling= 0;
1257 
1258  if(xorriso->hln_targets == NULL)
1259  return(0);
1260  ret= Xorriso_search_hardlinks(xorriso, node, node_idx, &min_hl, &max_hl, 1);
1261  if(ret < 0)
1262  return(ret);
1263  if(ret == 0 || *node_idx < 0 || min_hl == max_hl)
1264  return(0);
1265  for(i= min_hl; i <= max_hl; i++) {
1266  if(xorriso->hln_targets[i] == NULL) {
1267  if(i != *node_idx)
1268  null_target_sibling= 1;
1269  continue;
1270  }
1271  link_sibling= 1;
1272  ret= Xorriso_restore_make_hl(xorriso, xorriso->hln_targets[i], disk_path,
1273  !!xorriso->do_auto_chmod);
1274  if(ret > 0)
1275  return(1);
1276  }
1277  return((null_target_sibling << 1) | (link_sibling << 2));
1278 }
1279 
1280 
1281 /*
1282  @return <0 error,
1283  bit0= hardlink created
1284  bit2= siblings lower index found
1285 */
1286 int Xorriso_restore_prefix_hl(struct XorrisO *xorriso, IsoNode *node,
1287  char *disk_path, int node_idx, int flag)
1288 {
1289  int ret, min_hl, max_hl, i, link_sibling= 0, hflag;
1290  char *old_path= NULL, *img_path= NULL;
1291  struct Xorriso_lsT *img_prefixes= NULL, *disk_prefixes= NULL;
1292 
1293  Xorriso_alloc_meM(old_path, char, SfileadrL);
1294  Xorriso_alloc_meM(img_path, char, SfileadrL);
1295 
1296  ret= Xorriso_search_hardlinks(xorriso, node, &node_idx, &min_hl, &max_hl,
1297  2 | 4);
1298  if(ret < 0)
1299  goto ex;
1300  if(ret == 0 || min_hl == max_hl)
1301  {ret= 0; goto ex;}
1302 
1303  for(i= min_hl; i < node_idx; i++) {
1304  link_sibling= 1;
1305  ret= Xorriso_path_from_node(xorriso, xorriso->node_array[i], img_path, 0);
1306  if(ret < 0)
1307  goto ex;
1308  if(ret == 0)
1309  continue; /* Node is deleted from tree (Should not happen here) */
1310  hflag= 1;
1311  if(i == min_hl) {
1312  hflag= 0;
1313  } else if(xorriso->node_array[i] != xorriso->node_array[i - 1]) {
1314  hflag= 0;
1315  }
1316  if(hflag == 0) {
1317  img_prefixes= xorriso->node_img_prefixes;
1318  disk_prefixes= xorriso->node_disk_prefixes;
1319  }
1320  ret= Xorriso_make_restore_path(xorriso, &img_prefixes, &disk_prefixes,
1321  img_path, old_path, hflag);
1322  if(ret <= 0)
1323  goto ex;
1324  ret= Xorriso_restore_make_hl(xorriso, old_path, disk_path,
1325  !!xorriso->do_auto_chmod);
1326  if(ret > 0)
1327  {ret= 1; goto ex;}
1328  }
1329  ret= link_sibling << 2;
1330 ex:;
1331  Xorriso_free_meM(old_path);
1332  Xorriso_free_meM(img_path);
1333  return(ret);
1334 }
1335 
1336 
1337 /* @return <0 = error , 0 = availmem exhausted first time , 1 = ok
1338  2 = availmem exhausted repeated
1339 */
1340 int Xorriso_register_node_target(struct XorrisO *xorriso, int node_idx,
1341  char *disk_path, int flag)
1342 {
1343  int l;
1344 
1345  if(xorriso->node_targets_availmem == 0)
1346  return(2);
1347  if(xorriso->hln_targets == NULL || node_idx < 0 ||
1348  node_idx >= xorriso->hln_count)
1349  return(0);
1350  if(xorriso->hln_targets[node_idx] != NULL) {
1351  xorriso->node_targets_availmem+= strlen(xorriso->hln_targets[node_idx]) +1;
1352  free(xorriso->hln_targets[node_idx]);
1353  }
1354  l= strlen(disk_path);
1355  if(xorriso->node_targets_availmem <= l + 1) {
1356  sprintf(xorriso->info_text,
1357  "Hardlink target buffer exceeds -temp_mem_limit. Hardlinks may get divided.");
1358  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1359  xorriso->node_targets_availmem= 0;
1360  return(0);
1361  }
1362  xorriso->hln_targets[node_idx]= strdup(disk_path);
1363  if(xorriso->hln_targets[node_idx] == NULL) {
1364  Xorriso_no_malloc_memory(xorriso, NULL, 0);
1365  return(-1);
1366  }
1367  xorriso->node_targets_availmem-= (l + 1);
1368  return(1);
1369 }
1370 
1371 
1372 /*
1373  @param flag bit0= offset and bytes is valid for writing to regular file
1374  bit1= do not report copied files
1375  bit2= -follow, -not_*: this is not a command parameter
1376  bit3= keep directory open: keep owner, allow rwx for owner
1377  bit4= do not look for hardlinks even if enabled
1378  bit6= this is a copy action: do not fake times and ownership
1379  bit7= return 4 if restore fails from denied permission
1380  do not issue error message
1381  @return <=0 = error , 1 = added leaf file object , 2 = added directory ,
1382  3= regularly not installed (disallowed device, UNIX domain socket)
1383  4 = with bit7: permission to restore was denied
1384 */
1386  char *img_path, IsoNode *node,
1387  char *disk_path,
1388  off_t offset, off_t bytes, int flag)
1389 {
1390  int ret, i, split_count= 0, partno, total_parts, leaf_is_split= 0;
1391  int record_hl_path= 0, node_idx, cannot_register= 0;
1392  off_t total_bytes;
1393  char *part_name, *part_path= NULL, *img_path_pt= NULL;
1394  IsoImage *volume;
1395  IsoNode *part_node, *first_part_node= NULL;
1396  struct SplitparT *split_parts= NULL;
1397  struct stat stbuf;
1398 
1399  Xorriso_alloc_meM(part_path, char, SfileadrL);
1400 
1401  ret= Xorriso_get_volume(xorriso, &volume, 0);
1402  if(ret<=0)
1403  goto ex;
1404 
1405  if(LIBISO_ISDIR(node) && xorriso->do_concat_split)
1406  leaf_is_split= Xorriso_identify_split(xorriso, img_path, node,
1407  &split_parts, &split_count, &stbuf, 1 | 4);
1408  if(leaf_is_split) {
1409  /* map all files in directory img_path into regular file disk_path */
1410 
1411  for(i=0 ; i<split_count; i++) {
1412  Splitparts_get(split_parts, i, &part_name, &partno, &total_parts,
1413  &offset, &bytes, &total_bytes, 0);
1414 
1415  strcpy(part_path, img_path);
1416  if(Sfile_add_to_path(part_path, part_name, 0)<=0) {
1417  Xorriso_much_too_long(xorriso, strlen(img_path)+strlen(part_name)+1, 2);
1418  goto restoring_failed;
1419  }
1420  ret= Xorriso_node_from_path(xorriso, volume, part_path, &part_node, 0);
1421  if(ret<=0)
1422  goto restoring_failed;
1423  if(i==0)
1424  first_part_node= part_node;
1425  if(offset+bytes>total_bytes)
1426  bytes= total_bytes-offset;
1427  ret= Xorriso_tree_restore_node(xorriso, part_node, part_path, (off_t) 0,
1428  disk_path, offset, bytes,
1429  (!!(flag&64)) | 2 | (flag & (4 | 128)) | 8 | ( 16 * !(flag&2)));
1430  if(ret<=0)
1431  goto restoring_failed;
1432  if(ret == 4)
1433  goto ex;
1434  }
1435  if(first_part_node!=NULL)
1436  Xorriso_restore_properties(xorriso, disk_path, first_part_node,
1437  !!(flag&64));
1438  goto went_well;
1439  }
1440 
1441 #ifdef Osirrox_not_yeT
1442 
1443  if(resolve_link) {
1444  ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0);
1445  if(ret<=0)
1446  goto ex;
1447  disk_path_pt= resolved_disk_path;
1448  } else
1449 
1450 #endif /* Osirrox_not_yeT */
1451 
1452  img_path_pt= img_path;
1453 
1454  if(!((xorriso->ino_behavior & 4) || (flag & (1 | 16)) || LIBISO_ISDIR(node))){
1455  /* Try to restore as hardlink */
1456  ret= Xorriso_restore_target_hl(xorriso, node, disk_path, &node_idx,
1457  !!xorriso->do_auto_chmod);
1458  if(ret < 0) {
1459  goto ex;
1460  } else if(ret & 1) {
1461  /* Success, hardlink was created */
1462  goto went_well;
1463  } else if(ret & 2) {
1464  /* Did not establish hardlink. Hardlink siblings with target NULL found.*/
1465  record_hl_path= 1;
1466  }
1467  if(ret & 4) {
1468  /* Found siblings with non-NULL target, but did not link. */
1469  ret= Xorriso_eval_problem_status(xorriso, 1, 1 | 2);
1470  if(ret < 0)
1471  {ret= 0; goto ex;}
1472  }
1473  }
1474 
1475  ret= Xorriso_tree_restore_node(xorriso, node, img_path_pt, (off_t) 0,
1476  disk_path, offset, bytes,
1477  (flag&(4 | 8 | 128)) | (!!(flag&64)) | ((flag&1)<<1) | ( 16 * !(flag&2)));
1478  if(ret == 4)
1479  goto ex;
1480  if(ret>0 && (flag&8))
1481  ret= Xorriso_restore_properties(xorriso, disk_path, node, 2 | !!(flag&64));
1482  if(ret<=0) {
1483 restoring_failed:;
1484  sprintf(xorriso->info_text, "Restoring failed: ");
1485  Text_shellsafe(img_path, xorriso->info_text, 1);
1486  strcat(xorriso->info_text, " = ");
1487  Text_shellsafe(disk_path, xorriso->info_text, 1 | 2);
1488  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
1489  {ret= 0; goto ex;}
1490  }
1491  if(ret==2)
1492  {ret= 3; goto ex;}
1493  if(record_hl_path) { /* Start of a disk hardlink family */
1494  ret= Xorriso_register_node_target(xorriso, node_idx, disk_path, 0);
1495  if(ret < 0)
1496  goto ex;
1497  if(ret == 0)
1498  cannot_register= 1;
1499  }
1500 
1501 went_well:;
1502  xorriso->pacifier_count++;
1503  if(!(flag&2))
1504  Xorriso_pacifier_callback(xorriso, "files restored",
1505  xorriso->pacifier_count,
1506  xorriso->pacifier_total, "", 4 | 8);
1507  ret= 1;
1508 ex:;
1509  if(split_parts!=NULL)
1510  Splitparts_destroy(&split_parts, split_count, 0);
1511  Xorriso_free_meM(part_path);
1512  if(ret > 0 && cannot_register)
1513  ret= 0;
1514  return(ret);
1515 }
1516 
1517 
1518 /* @param flag bit0= source is a directory and not to be restored as split file
1519  >>> bit6= permission to call Xorriso_make_accessible()
1520  @return <=0 error , 1=collision handled , 2=no collision , 3=revoked by user
1521 */
1522 int Xorriso_handle_collision(struct XorrisO *xorriso,
1523  IsoNode *node, char *img_path,
1524  char *disk_path, char *nominal_disk_path,
1525  int *stbuf_ret, int flag)
1526 {
1527  int ret, target_is_dir= 0, target_is_link= 0, stat_ret, made_accessible= 0;
1528  struct stat target_stbuf, lt_stbuf;
1529  struct PermiteM *perm_stack_mem;
1530 
1531  perm_stack_mem= xorriso->perm_stack;
1532 
1533  /* does a disk file exist with this name ? */
1534  *stbuf_ret= lstat(disk_path, &target_stbuf);
1535  if(*stbuf_ret==-1) {
1536  if((flag & 64) && errno == EACCES) {
1537  ret= Xorriso_make_accessible(xorriso, disk_path, 0);
1538  if(ret < 0)
1539  goto ex;
1540  made_accessible= 1;
1541  *stbuf_ret= lstat(disk_path, &target_stbuf);
1542  }
1543  if(*stbuf_ret==-1)
1544  {ret= 2; goto ex;}
1545  }
1546  target_is_link= S_ISLNK(target_stbuf.st_mode);
1547  if(target_is_link) {
1548  stat_ret= stat(disk_path, &lt_stbuf);
1549  if(stat_ret == -1) {
1550  if((flag & 64) && errno == EACCES && !made_accessible) {
1551  ret= Xorriso_make_accessible(xorriso, disk_path, 0);
1552  if(ret < 0)
1553  goto ex;
1554  made_accessible= 1;
1555  stat_ret= stat(disk_path, &lt_stbuf);
1556  }
1557  }
1558  if(stat_ret != -1)
1559  target_is_dir= S_ISDIR(lt_stbuf.st_mode);
1560  } else {
1561  target_is_dir= S_ISDIR(target_stbuf.st_mode);
1562  }
1563  if(target_is_dir && (!target_is_link) && !(flag&1)) {
1564  strcpy(xorriso->info_text, "Attempt to replace DISK directory ");
1565  Text_shellsafe(nominal_disk_path,
1566  xorriso->info_text+strlen(xorriso->info_text), 0);
1567  strcat(xorriso->info_text, " by ISO file ");
1568  Text_shellsafe(img_path, xorriso->info_text+strlen(xorriso->info_text), 0);
1569  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1570  ret= 0; goto ex;
1571  }
1572 
1573  if(!(target_is_dir && (flag&1))) {
1574  Xorriso_process_msg_queues(xorriso,0);
1575  ret= Xorriso_restore_overwrite(xorriso, node, img_path, disk_path,
1576  nominal_disk_path, &target_stbuf, 16 | (flag & 64));
1577  if(ret==3)
1578  {ret= 3; goto ex;}
1579  if(ret<=0)
1580  goto ex;
1581  *stbuf_ret= -1; /* It might still exist but will be handled properly */
1582  }
1583  ret= 1;
1584 ex:;
1585  if(made_accessible)
1586  Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0);
1587  return(ret);
1588 }
1589 
1590 
1591 /* @param flag bit0= recursion is active
1592  bit1= do not report restored files
1593  bit6= this is a copy action: do not fake times and ownership
1594  bit8= only register non-directory nodes in xorriso->node_array
1595  bit7+8=
1596  0= direct operation
1597  1= create only directories,
1598  count nodes in xorriso->node_counter
1599  2= only register non-directory nodes in
1600  xorriso->node_array
1601  3= count nodes in xorriso->node_counter,
1602  create no directory
1603 */
1604 int Xorriso_restore_tree(struct XorrisO *xorriso, IsoDir *dir,
1605  char *img_dir_path, char *disk_dir_path,
1606  off_t boss_mem,
1607  struct LinkiteM *link_stack, int flag)
1608 {
1609  IsoImage *volume;
1610  IsoNode *node;
1611  IsoDirIter *iter= NULL;
1612  IsoNode **node_array= NULL;
1613  int node_count= 0, node_idx;
1614  int ret, source_is_dir, fret, was_failure= 0;
1615  int do_not_dive, source_is_split= 0, len_dp, len_ip, stbuf_ret, hflag, hret;
1616  char *name, *disk_name, *leaf_name, *srcpt, *stbuf_src= "";
1617  struct LinkiteM *own_link_stack;
1618  char *sfe= NULL, *sfe2= NULL;
1619  char *disk_path= NULL, *img_path= NULL, *link_target= NULL;
1620  off_t mem;
1621  struct PermiteM *perm_stack_mem;
1622  struct stat stbuf;
1623  int dir_create= 0, node_register= 0, do_node_count= 0, normal_mode= 0;
1624 
1625  perm_stack_mem= xorriso->perm_stack;
1626  switch((flag >> 7) & 3) {
1627  case 0: normal_mode= 1;
1628  break; case 1: dir_create= 1;
1629  break; case 2: node_register= 1;
1630  break; case 3: do_node_count= 1;
1631  }
1632 
1633  /* Avoiding large local memory objects in order to save stack space */
1634  sfe= malloc(5*SfileadrL);
1635  sfe2= malloc(5*SfileadrL);
1636  disk_path= malloc(2*SfileadrL);
1637  img_path= malloc(2*SfileadrL);
1638  link_target= malloc(SfileadrL);
1639  if(sfe==NULL || sfe2==NULL || disk_path==NULL || img_path==NULL ||
1640  link_target==NULL) {
1641  Xorriso_no_malloc_memory(xorriso, &sfe, 0);
1642  {ret= -1; goto ex;}
1643  }
1644 
1645  own_link_stack= link_stack;
1646 
1647  ret= Xorriso_get_volume(xorriso, &volume, 0);
1648  if(ret<=0)
1649  goto ex;
1650 
1651  stbuf_src= img_dir_path;
1652  node= (IsoNode *) dir;
1653  ret= Xorriso_fake_stbuf(xorriso, stbuf_src, &stbuf, &node, 1);
1654  if(ret<=0) {
1655  Xorriso_msgs_submit(xorriso, 0, disk_dir_path, 0, "ERRFILE", 0);
1656  sprintf(xorriso->info_text,"Cannot open as (ISO) source directory: %s",
1657  Text_shellsafe(img_dir_path, sfe, 0));
1658  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1659  {ret= 0; goto ex;}
1660  }
1661 
1662 #ifdef Osirrox_not_yeT
1663 
1664  dev_t dir_dev;
1665  dir_dev= stbuf.st_dev;
1666 
1667  if(S_ISLNK(stbuf.st_mode)) {
1668  if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1))))
1669  {ret= 2; goto ex;}
1670  stbuf_src= disk_dir_path;
1671  if(stat(disk_dir_path, &stbuf)==-1)
1672  goto cannot_open_dir;
1673  if(dir_dev != stbuf.st_dev &&
1674  !(xorriso->do_follow_mount || (xorriso->do_follow_param && !(flag&1))))
1675  {ret= 2; goto ex;}
1676  }
1677 
1678 #endif /* Osirrox_not_yeT */
1679 
1680  if(!S_ISDIR(stbuf.st_mode)) {
1681  Xorriso_msgs_submit(xorriso, 0, disk_dir_path, 0, "ERRFILE", 0);
1682  sprintf(xorriso->info_text,"Is not a directory in ISO image: %s",
1683  Text_shellsafe(img_dir_path, sfe, 0));
1684  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1685  {ret= 0; goto ex;}
1686  }
1687 
1688  mem= boss_mem;
1689  ret= Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count,
1690  &node_idx, &node,
1691  1 | 4 * (normal_mode && (xorriso->ino_behavior & 4)));
1692  if(ret<=0)
1693  goto ex;
1694 
1695  if(Sfile_str(img_path, img_dir_path,0)<=0) {
1696 much_too_long:;
1697  Xorriso_much_too_long(xorriso, SfileadrL, 2);
1698  {ret= 0; goto ex;}
1699  }
1700  if(img_path[0]==0 || img_path[strlen(img_path)-1]!='/')
1701  strcat(img_path,"/");
1702  name= img_path+strlen(img_path);
1703  if(Sfile_str(disk_path, disk_dir_path, 0)<=0)
1704  goto much_too_long;
1705  if(disk_path[0]==0 || disk_path[strlen(disk_path)-1]!='/')
1706  strcat(disk_path,"/");
1707  disk_name= disk_path+strlen(disk_path);
1708 
1709  len_dp= strlen(disk_path);
1710  len_ip= strlen(img_path);
1711 
1712  while(1) { /* loop over ISO directory content */
1713  stbuf_src= "";
1714 
1715 #ifdef Osirrox_not_yeT
1716 
1717  Linkitem_reset_stack(&own_link_stack, link_stack, 0);
1718 
1719 #endif
1720 
1721  srcpt= img_path;
1722  Xorriso_process_msg_queues(xorriso,0);
1723  ret= Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count,
1724  &node_idx, &node, 0);
1725  if(ret<0)
1726  goto ex;
1727  if(ret==0 || xorriso->request_to_abort)
1728  break;
1729  leaf_name= (char *) iso_node_get_name(node);
1730  if(Xorriso_much_too_long(xorriso, len_dp + strlen(leaf_name)+1, 0)<=0)
1731  {ret= 0; goto was_problem;}
1732  if(Xorriso_much_too_long(xorriso, len_ip + strlen(leaf_name)+1, 0)<=0)
1733  {ret= 0; goto was_problem;}
1734  /* name is a pointer into img_path */
1735  strcpy(name, leaf_name);
1736  strcpy(disk_name, leaf_name);
1737 
1738  stbuf_src= srcpt;
1739  ret= Xorriso_fake_stbuf(xorriso, img_path, &stbuf, &node, 1);
1740  if(ret<=0)
1741  goto was_problem;
1742  source_is_dir= 0;
1743 
1744 #ifdef Osirrox_not_yeT
1745 
1746  /* ??? Link following in the image would cause severe problems
1747  with Xorriso_path_from_node() */
1748 
1749  int source_is_link;
1750 
1751  source_is_link= S_ISLNK(stbuf.st_mode);
1752  if(xorriso->do_follow_links && source_is_link) {
1753  /* Xorriso_hop_link checks for wide link loops */
1754  ret= Xorriso_hop_link(xorriso, srcpt, &own_link_stack, &hstbuf, 0);
1755  if(ret<0)
1756  goto was_problem;
1757  if(ret==1) {
1758  ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 0);
1759  if(ret<=0)
1760  goto was_problem;
1761  srcpt= link_target;
1762  stbuf_src= srcpt;
1763  if(lstat(srcpt, &stbuf)==-1)
1764  goto cannot_lstat;
1765  } else {
1766  if(Xorriso_eval_problem_status(xorriso, 0, 1|2)<0)
1767  {ret= 0; goto was_problem;}
1768  }
1769  } else if (S_ISLNK(stbuf.st_mode)) {
1770  ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1);
1771  if(ret<=0)
1772  goto was_problem;
1773  }
1774 
1775 #endif /* Osirrox_not_yeT */
1776 
1777  do_not_dive= 0;
1778  if(S_ISDIR(stbuf.st_mode))
1779  source_is_dir= 1;
1780  source_is_split= 0;
1781  if(source_is_dir)
1782  source_is_split= Xorriso_is_split(xorriso, img_path, node, 1 | 2 | 4);
1783  if(source_is_split)
1784  do_not_dive= 1;
1785 
1786  if(source_is_dir || !(dir_create || do_node_count || node_register)) {
1787  ret= Xorriso_handle_collision(xorriso, node, img_path,
1788  disk_path, disk_path, &stbuf_ret,
1789  (source_is_dir && !source_is_split));
1790  if(ret<=0 || ret==3)
1791  goto was_problem;
1792  } else {
1793  stbuf_ret= -1;
1794  }
1795 
1796  if(stbuf_ret!=-1) { /* (Can only happen with directory) */
1797  Xorriso_auto_chmod(xorriso, disk_path, 0);
1798  } else {
1799  hflag= 4 | (flag & (2|64));
1800  if(source_is_dir && !do_not_dive)
1801  hflag|= 8; /* keep directory open for user */
1802  if((dir_create || do_node_count) && !source_is_dir) {
1803  xorriso->node_counter++;
1804  } else if(node_register && !source_is_dir) {
1805  if(xorriso->node_counter < xorriso->node_array_size) {
1806  xorriso->node_array[xorriso->node_counter++]= (void *) node;
1807  iso_node_ref(node);
1808  }
1809  } else if(node_register || do_node_count) {
1810  ret= 1;
1811  } else {
1812  ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path,
1813  (off_t) 0, (off_t) 0, hflag);
1814  }
1815  if(ret<=0)
1816  goto was_problem;
1817  }
1818  if(source_is_dir && !do_not_dive) {
1819  ret= Xorriso_restore_tree(xorriso, (IsoDir *) node,
1820  img_path, disk_path, mem,
1821  own_link_stack, 1 | (flag & (2 | (3 << 7))));
1822  /* eventually restore exact access permissions of directory */
1823  hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso,
1824  !!(flag&64));
1825  if(hret<=0 && hret<ret)
1826  ret= hret;
1827  if(ret<=0)
1828  goto was_problem;
1829  }
1830 
1831  continue; /* regular bottom of loop */
1832 was_problem:;
1833  was_failure= 1;
1834  fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
1835  if(fret<0)
1836  goto ex;
1837  Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, !!(flag&64));
1838  }
1839 
1840  ret= 1;
1841 ex:
1842  Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, !!(flag&64));
1843  if(sfe!=NULL)
1844  free(sfe);
1845  if(sfe2!=NULL)
1846  free(sfe2);
1847  if(disk_path!=NULL)
1848  free(disk_path);
1849  if(img_path!=NULL)
1850  free(img_path);
1851  if(link_target!=NULL)
1852  free(link_target);
1853  Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count,
1854  &node_idx, &node, (1u<<31));
1855 
1856  Xorriso_process_msg_queues(xorriso,0);
1857 
1858 #ifdef Osirrox_not_yeT
1859 
1860  Linkitem_reset_stack(&own_link_stack, link_stack, 0);
1861 
1862 #endif
1863 
1864  if(ret<=0)
1865  return(ret);
1866  return(!was_failure);
1867 }
1868 
1869 
1870 /*
1871  @param flag
1872  >>> bit0= mkdir: graft in as empty directory, not as copy from iso
1873  bit1= do not report copied files
1874  bit2= -follow, -not_*: this is not a command parameter
1875  bit3= use offset and cut_size for -paste_in
1876  bit4= return 3 on rejection by exclusion or user
1877  bit5= if directory then do not add sub tree
1878  bit6= this is a copy action: do not fake times and ownership
1879  bit7+8= operation mode
1880  0= direct operation
1881  1= create only directories,
1882  count nodes in xorriso->node_counter
1883  2= only register non-directory nodes in
1884  xorriso->node_array
1885  3= count nodes in xorriso->node_counter,
1886  create no directory
1887  bit9= with operation mode 1 do net register prefixes
1888  @return <=0 = error , 1 = added leaf file object , 2 = added directory ,
1889  3 = rejected
1890 */
1891 int Xorriso_restore(struct XorrisO *xorriso,
1892  char *img_path, char *disk_path,
1893  off_t offset, off_t bytes, int flag)
1894 {
1895  IsoImage *volume;
1896  char *path= NULL, *apt, *npt;
1897  IsoNode *node= NULL;
1898  int done= 0, is_dir= 0, ret, source_is_dir, stbuf_ret, hret;
1899  int dir_create= 0, node_count= 0, node_register= 0, path_size;
1900  int leaf_is_split= 0, source_is_split= 0, new_dir_made= 0;
1901  struct stat stbuf;
1902  struct PermiteM *perm_stack_mem;
1903 
1904  perm_stack_mem= xorriso->perm_stack;
1905 
1906  path_size= SfileadrL;
1907  Xorriso_alloc_meM(path, char, path_size);
1908 
1909  switch((flag >> 7) & 3) {
1910  case 1: dir_create= 1;
1911  break; case 2: node_register= 1;
1912  break; case 3: node_count= 1;
1913  }
1914 
1915  if(dir_create && !(flag & (1 << 9))) {
1917  disk_path, strlen(disk_path) + 1, 0);
1918  if(ret <= 0)
1919  goto ex;
1921  img_path, strlen(img_path) + 1, 0);
1922  if(ret <= 0)
1923  goto ex;
1924  }
1925 
1926  ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&4));
1927  if(ret<0)
1928  goto ex;
1929  if(ret>0)
1930  {ret= 3*!!(flag&16); goto ex;}
1931 
1932  ret= Xorriso_get_volume(xorriso, &volume, 0);
1933  if(ret<=0)
1934  goto ex;
1935 
1936  strncpy(path, disk_path, path_size - 1);
1937  path[path_size - 1]= 0;
1938  apt= npt= path;
1939 
1940  if(!(flag&1)) {
1941  ret= Xorriso_fake_stbuf(xorriso, img_path, &stbuf, &node, 0);
1942  if(ret>0) {
1943  if(S_ISDIR(stbuf.st_mode))
1944  is_dir= 1;
1945 
1946 #ifdef Osirrox_not_yeT
1947 
1948  /* ??? this would cause severe problems with Xorriso_path_from_node() */
1949 
1950  else if((stbuf.st_mode&S_IFMT)==S_IFLNK &&
1951  (xorriso->do_follow_links ||
1952  (xorriso->do_follow_param && !(flag&4)))) {
1953  resolve_link= 1;
1954  ret= Xorriso_iso_lstat(xorriso, img_path, &stbuf, 1|2);
1955  if(ret!=-1) {
1956  if(S_ISDIR(stbuf.st_mode))
1957  is_dir= 1;
1958  }
1959  }
1960 #endif /* Osirrox_not_yeT */
1961 
1962  } else {
1963  Xorriso_process_msg_queues(xorriso,0);
1964  Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
1965  sprintf(xorriso->info_text,
1966  "Cannot determine attributes of (ISO) source file ");
1967  Text_shellsafe(img_path, xorriso->info_text, 1);
1968  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
1969  ret= 0; goto ex;
1970  }
1971  if(is_dir && xorriso->do_concat_split)
1972  leaf_is_split= Xorriso_is_split(xorriso, img_path, node, 1 | 2 | 4);
1973  }
1974  for(npt= apt; !done; apt= npt+1) {
1975  npt= strchr(apt, '/');
1976  if(npt==NULL) {
1977  npt= apt+strlen(apt);
1978  done= 1;
1979  } else
1980  *npt= 0;
1981  if(*apt==0) {
1982  *apt= '/';
1983  apt++;
1984  if(done)
1985  goto attach_source;
1986  continue;
1987  }
1988  source_is_dir= (is_dir || (flag&1) || !done);
1989  source_is_split= done && leaf_is_split;
1990 
1991  stbuf_ret= -1;
1992  if((flag&8) && done) {
1993 
1994  /* ??? move down from Xorriso_paste_in() :
1995  check whether target does not exist or both are regular */;
1996 
1997  } else if(source_is_dir || !(dir_create || node_count || node_register)) {
1998  ret= Xorriso_handle_collision(xorriso, node, img_path, path, disk_path,
1999  &stbuf_ret, (source_is_dir && !source_is_split));
2000  if(ret<=0 || ret==3)
2001  goto ex;
2002  }
2003 
2004  new_dir_made= 0;
2005  if(stbuf_ret==-1 && (source_is_dir && !source_is_split) &&
2006  !(node_count || node_register)) {
2007  /* make a directory */
2008  ret= mkdir(path, 0777);
2009  if(ret==-1) {
2010  Xorriso_process_msg_queues(xorriso,0);
2011  Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
2012  sprintf(xorriso->info_text,
2013  "While restoring '%s' : could not insert '%s'", disk_path, path);
2014  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
2015  {ret= 0; goto ex;}
2016  }
2017  if(!done) {
2018  /* keep rwx for the owner */
2020  img_path, 4);
2021  }
2022  new_dir_made= 1;
2023  } else if((source_is_dir && !source_is_split)) {
2024  if(!(node_count || node_register))
2025  Xorriso_auto_chmod(xorriso, path, 0);
2026  }
2027  if(done) {
2028 attach_source:;
2029 
2030  if(flag&1) {
2031  /* directory was created above */;
2032 
2033  } else if(is_dir && !source_is_split) {
2034 
2035  if(!node_register) {
2036  if(new_dir_made) { /* keep open and push to Permstack */
2037  ret= Xorriso_restore_properties(xorriso, disk_path, node,
2038  2 | !!(flag&64));
2039  if(ret <= 0) {
2040  hret= Xorriso_eval_problem_status(xorriso, ret, 1 | 2);
2041  if(hret < 0)
2042  goto ex;
2043  }
2044  }
2045  }
2046  if(!(flag&32)) {
2047  ret= Xorriso_restore_tree(xorriso, (IsoDir *) node, img_path, path,
2048  (off_t) 0, NULL, flag & (2 | 64 | (3 << 7)));
2049  if(ret <= 0) {
2050  hret= Xorriso_eval_problem_status(xorriso, ret, 1 | 2);
2051  if(hret < 0)
2052  goto ex;
2053  }
2054  if(new_dir_made && !(flag&64))
2055  /* set timestamps which Permstack_pop() will not set */
2056  Xorriso_restore_properties(xorriso, disk_path, node, 2);
2057  }
2058  } else {
2059  if(dir_create || node_count) {
2060  xorriso->node_counter++;
2061  } else if(node_register) {
2062  if(xorriso->node_counter < xorriso->node_array_size) {
2063  xorriso->node_array[xorriso->node_counter++]= (void *) node;
2064  iso_node_ref(node);
2065  }
2066  } else {
2067  ret= Xorriso_restore_disk_object(xorriso, img_path, node, path,
2068  offset, bytes, (flag & (2|4|64)) | !!(flag&8));
2069  if(ret <= 0) {
2070  hret= Xorriso_eval_problem_status(xorriso, ret, 1 | 2);
2071  if(hret < 0)
2072  goto ex;
2073  }
2074  }
2075  }
2076  } else
2077  *npt= '/';
2078  }
2079  Xorriso_process_msg_queues(xorriso,0);
2080  ret= 1 + (is_dir && !leaf_is_split);
2081 ex:;
2082  /* restore exact access permissions of stacked paths */
2083  hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso,
2084  2 | !!(flag&64));
2085  if(hret<=0 && hret<ret)
2086  ret= hret;
2087  Xorriso_free_meM(path);
2088  return(ret);
2089 }
2090 
2091 
2092 int Xorriso_restore_node_array(struct XorrisO *xorriso, int flag)
2093 {
2094  int i, ret, fret, hflag, stbuf_ret, faulty_family= 0;
2095  struct PermiteM *perm_stack_mem;
2096  char *img_path= NULL, *disk_path= NULL;
2097  IsoNode *node;
2098  struct Xorriso_lsT *img_prefixes= NULL, *disk_prefixes= NULL;
2099 
2100  perm_stack_mem= xorriso->perm_stack;
2101 
2102  Xorriso_alloc_meM(img_path, char, SfileadrL);
2103  Xorriso_alloc_meM(disk_path, char, SfileadrL);
2104 
2105  Xorriso_sort_node_array(xorriso, 0);
2106 
2107  disk_path[0]= 0;
2108  for(i= 0; i < xorriso->node_counter; i++) {
2109  node= (IsoNode *) xorriso->node_array[i];
2110  ret= Xorriso_path_from_node(xorriso, node, img_path, 0);
2111  if(ret < 0)
2112  goto ex;
2113  if(ret == 0)
2114  continue; /* Node is deleted from tree (Should not happen here) */
2115  hflag= 1;
2116  if(i == 0) {
2117  hflag= 0;
2118  } else if(node != xorriso->node_array[i - 1]) {
2119  hflag= 0;
2120  }
2121  if(hflag == 0) {
2122  img_prefixes= xorriso->node_img_prefixes;
2123  disk_prefixes= xorriso->node_disk_prefixes;
2124  }
2125  ret= Xorriso_make_restore_path(xorriso, &img_prefixes, &disk_prefixes,
2126  img_path, disk_path, hflag);
2127  if(ret<=0)
2128  goto was_problem;
2129 
2130  ret= Xorriso_handle_collision(xorriso, node, img_path, disk_path, disk_path,
2131  &stbuf_ret, 64);
2132  if(ret<=0 || ret==3)
2133  goto was_problem;
2134  if(xorriso->hln_array != NULL && !(xorriso->ino_behavior & 16)) {
2135  /* Eventual lookup of hardlinks will be done in
2136  Xorriso_restore_disk_object() */;
2137  } else if(i > 0 && !(xorriso->ino_behavior & 4)) {
2138  if(Xorriso__findi_sorted_ino_cmp(&(xorriso->node_array[i-1]),
2139  &(xorriso->node_array[i])) == 0) {
2140  if(faulty_family) {
2141  sprintf(xorriso->info_text, "Hardlinking omitted with ");
2142  Text_shellsafe(disk_path, xorriso->info_text, 1);
2143  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
2144  } else {
2145  /* Try to install hardlink to a sibling */
2146  ret= Xorriso_restore_prefix_hl(xorriso, node, disk_path, i, 0);
2147  if(ret < 0) {
2148  goto was_problem;
2149  } else if(ret & 1) {
2150  /* Success, hardlink was created */
2151  xorriso->pacifier_count++;
2152  continue;
2153  }
2154  if(ret & 4) {
2155  /* Found elder siblings, but did not link. */
2156  ret= Xorriso_eval_problem_status(xorriso, 1, 1 | 2);
2157  if(ret < 0)
2158  {ret= 0; goto ex;}
2159  }
2160  }
2161  } else
2162  faulty_family= 0;
2163  }
2164 
2165  ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path,
2166  (off_t) 0, (off_t) 0,
2167  4 | (xorriso->ino_behavior & 16) | 128);
2168  if(ret<=0)
2169  goto was_problem;
2170  if(ret == 4) {
2171  /* Failed from lack of permission */
2172  ret= Xorriso_make_accessible(xorriso, disk_path, 0);
2173  if(ret < 0)
2174  goto ex;
2175  ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path,
2176  (off_t) 0, (off_t) 0, 4 | (xorriso->ino_behavior & 16));
2177  if(ret<=0)
2178  goto was_problem;
2179  Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0);
2180  }
2181 
2182  continue; /* regular bottom of loop */
2183 was_problem:;
2184  faulty_family= 1;
2185  fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
2186  if(fret<0)
2187  goto ex;
2188  Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0);
2189  }
2190  ret= 1;
2191 ex:;
2192  Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0);
2193  Xorriso_free_meM(img_path);
2194  Xorriso_free_meM(disk_path);
2195  return(ret);
2196 }
2197 
2198 
2199 /* @param flag bit0= -follow, -not: disk_path is not a command parameter
2200 */
2201 int Xorriso_paste_in(struct XorrisO *xorriso, char *disk_path,
2202  off_t startbyte, off_t bytecount, char *iso_rr_path, int flag)
2203 {
2204  int ret;
2205  char *eff_source= NULL, *eff_dest= NULL;
2206  struct stat stbuf;
2207  IsoNode *node;
2208 
2209  Xorriso_alloc_meM(eff_source, char, SfileadrL);
2210  Xorriso_alloc_meM(eff_dest, char, SfileadrL);
2211 
2212  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_dest,
2213  2|4);
2214  if(ret<=0)
2215  goto ex;
2216  ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&1));
2217  if(ret!=0)
2218  {ret= 0; goto ex;}
2219  ret= stat(eff_dest, &stbuf);
2220  if(ret!=-1 && !S_ISREG(stbuf.st_mode)) {
2221  Xorriso_msgs_submit(xorriso, 0, eff_dest, 0, "ERRFILE", 0);
2222  sprintf(xorriso->info_text, "-paste_in: DISK file ");
2223  Text_shellsafe(eff_source, xorriso->info_text, 1);
2224  strcat(xorriso->info_text, " exists and is not a data file");
2225  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
2226  {ret= 0; goto ex;}
2227  }
2228 
2229  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, iso_rr_path,
2230  eff_source, 2);
2231  if(ret<=0)
2232  goto ex;
2233  ret= Xorriso_fake_stbuf(xorriso, eff_source, &stbuf, &node, 4);
2234  if(ret<=0)
2235  {ret= 0; goto ex;}
2236  if(!S_ISREG(stbuf.st_mode)) {
2237  Xorriso_msgs_submit(xorriso, 0, eff_dest, 0, "ERRFILE", 0);
2238  sprintf(xorriso->info_text, "-paste_in: ISO file ");
2239  Text_shellsafe(eff_source, xorriso->info_text, 1);
2240  strcat(xorriso->info_text, " is not a data file");
2241  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
2242  {ret= 0; goto ex;}
2243  }
2244 
2245  /* >>> eventually obtain parameters from file name */;
2246 
2247  ret= Xorriso_restore(xorriso, eff_source, eff_dest, startbyte, bytecount, 8);
2248 ex:;
2249  Xorriso_free_meM(eff_source);
2250  Xorriso_free_meM(eff_dest);
2251  return(ret);
2252 }
2253 
2254 
2255 int Xorriso_extract_cut(struct XorrisO *xorriso,
2256  char *img_path, char *disk_path,
2257  off_t img_offset, off_t bytes, int flag)
2258 {
2259  int ret, stbuf_ret, read_raw;
2260  double mem_lut= 0.0;
2261  char *eff_img_path= NULL, *eff_disk_path= NULL;
2262  IsoImage *volume;
2263  IsoNode *node;
2264 
2265  Xorriso_alloc_meM(eff_img_path, char, SfileadrL);
2266  Xorriso_alloc_meM(eff_disk_path, char, SfileadrL);
2267 
2268  ret= Xorriso_get_volume(xorriso, &volume, 0);
2269  if(ret<=0)
2270  goto ex;
2271  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi,
2272  img_path, eff_img_path, 0);
2273  if(ret<=0)
2274  goto ex;
2275  ret= Xorriso_node_from_path(xorriso, volume, eff_img_path, &node, 0);
2276  if(ret<=0)
2277  goto ex;
2278  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx,
2279  disk_path, eff_disk_path, 2 | 4);
2280  if(ret<=0)
2281  goto ex;
2282  Xorriso_pacifier_reset(xorriso, 0);
2283  mem_lut= xorriso->last_update_time;
2284 
2285  ret= Xorriso_handle_collision(xorriso, node, img_path, eff_disk_path,
2286  disk_path, &stbuf_ret, 0);
2287  if(ret<=0 || ret==3)
2288  {ret= 0; goto ex;}
2289 
2290  /* If it is a non-filtered stream from the ISO image
2291  and img_offset is a multiple of 2048
2292  then use Xorriso_read_file_data() for random access offset.
2293  */
2294  if(!LIBISO_ISREG(node)) {
2295  Xorriso_msgs_submit(xorriso, 0, eff_disk_path, 0, "ERRFILE", 0);
2296  sprintf(xorriso->info_text, "-extract_cut: ISO file ");
2297  Text_shellsafe(eff_img_path, xorriso->info_text, 1);
2298  strcat(xorriso->info_text, " is not a data file");
2299  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2300  {ret= 0; goto ex;}
2301  }
2302  read_raw= 0;
2303  if((img_offset % 2048) == 0) {
2304  ret= Xorriso_is_plain_image_file(xorriso, node, "", 0);
2305  if(ret > 0)
2306  read_raw= 1;
2307  }
2308  if (read_raw) {
2309  ret= Xorriso_read_file_data(xorriso, node, eff_img_path, eff_disk_path,
2310  img_offset, (off_t) 0, bytes, 0);
2311  if(ret<=0)
2312  goto ex;
2313  } else {
2314  ret= Xorriso_tree_restore_node(xorriso, node, eff_img_path, img_offset,
2315  eff_disk_path, (off_t) 0, bytes, 2 | 8);
2316  if(ret<=0)
2317  goto ex;
2318  }
2319 
2320  ret= Xorriso_restore_properties(xorriso, eff_disk_path, node, 0);
2321  if(ret<=0)
2322  goto ex;
2323 
2324  if(mem_lut != xorriso->last_update_time)
2325  Xorriso_pacifier_callback(xorriso, "blocks read",
2326  xorriso->pacifier_count, 0, "", 1 | 8 | 16 | 32);
2327  ret= 1;
2328 ex:;
2329  Xorriso_free_meM(eff_img_path);
2330  Xorriso_free_meM(eff_disk_path);
2331  return(ret);
2332 }
2333 
2334 
2335 /* @param flag bit0= ignore node and img_path, operate on whole medium
2336  bit1= for Xorriso_check_interval(): no pacifier messages
2337 */
2338 int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node,
2339  char *img_path, char *disk_path,
2340  off_t img_offset, off_t disk_offset,
2341  off_t bytes, int flag)
2342 {
2343  int ret, i, lba_count= 0, *start_lbas= NULL, *end_lbas= NULL, read_chunk= 16;
2344  int lba, count, blocks, quality, spot, bad_extract= 0;
2345  int data_to_skip= 0;
2346  uint32_t indev_blocks;
2347  off_t size= 0, file_base_bytes= 0, file_processed_bytes= 0, img_adr;
2348  off_t new_file_base_bytes, upto_file_bytes, start_byte= 0;
2349  off_t *section_sizes = NULL;
2350  struct SpotlisT *spotlist= NULL;
2351  struct CheckmediajoB *job= NULL;
2352 
2353  upto_file_bytes= img_offset + bytes;
2354  data_to_skip= img_offset % (off_t) 2048;
2355 
2356  if(flag & 1) {
2357  lba_count= 1;
2358  Xorriso_alloc_meM(start_lbas, int, 1);
2359  Xorriso_alloc_meM(end_lbas, int, 1);
2360  Xorriso_alloc_meM(section_sizes, off_t, 1);
2361  start_lbas[0]= 0;
2362  ret= Xorriso_obtain_indev_readsize(xorriso, &indev_blocks, 0);
2363  if(ret > 0)
2364  end_lbas[0]= indev_blocks - 1;
2365  else
2366  end_lbas[0]= 0x7ffffffe;
2367  size= ((off_t) end_lbas[0]) * 2048;
2368  section_sizes[0]= size;
2369  } else {
2370  ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas,
2371  &section_sizes, &size, 0);
2372  if(ret <= 0) {
2373  Xorriso_process_msg_queues(xorriso,0);
2374  sprintf(xorriso->info_text, "File object ");
2375  Text_shellsafe(img_path, xorriso->info_text, 1);
2376  strcat(xorriso->info_text,
2377  " is currently not a data file from the loaded image");
2378  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2379  goto ex;
2380  }
2381  }
2382  if(img_offset + bytes < size && bytes > 0)
2383  size= img_offset + bytes;
2384 
2385  ret= Checkmediajob_new(&job, 0);
2386  if(ret <= 0)
2387  goto ex;
2388  if(xorriso->check_media_default != NULL)
2389  Checkmediajob_copy(xorriso->check_media_default, job, 0);
2390  job->min_lba= -1;
2391  job->max_lba= -1;
2392  job->sector_map_path[0]= 0;
2393 
2394  ret= Spotlist_new(&spotlist, 0);
2395  if(ret <= 0)
2396  {ret= -1; goto ex;}
2397 
2398  if(Sfile_str(job->data_to_path, disk_path, 0) <= 0)
2399  {ret= -1; goto ex;}
2400  ret= Xorriso_open_job_data_to(xorriso, job, 0);
2401  if(ret <= 0)
2402  goto ex;
2403 
2404  for(i= 0; i < lba_count && file_base_bytes < upto_file_bytes; i++) {
2405  lba= start_lbas[i];
2406  count= end_lbas[i] + 1 - start_lbas[i];
2407  new_file_base_bytes= file_base_bytes + ((off_t) count) * (off_t) 2048;
2408 
2409  /* skip intervals before img_offset */
2410  if(new_file_base_bytes <= img_offset) {
2411  file_base_bytes= new_file_base_bytes;
2412  continue;
2413  }
2414  /* Eventually adjust first interval start */
2415  img_adr= ((off_t) lba) * (off_t) 2048;
2416  if(file_base_bytes < img_offset) {
2417  img_adr+= img_offset - file_base_bytes;
2418  lba= img_adr / (off_t) 2048;
2419  count= end_lbas[i] + 1 - lba;
2420  file_base_bytes= img_offset;
2421  }
2422 
2423  /* Omit surplus blocks */
2424  if(new_file_base_bytes > upto_file_bytes)
2425  count-= (new_file_base_bytes - upto_file_bytes) / (off_t) 2048;
2426  /* Adjust job */
2427  job->data_to_offset= file_processed_bytes - img_adr + disk_offset;
2428  job->data_to_limit= size - file_base_bytes;
2429  job->data_to_skip= data_to_skip;
2430  data_to_skip= 0;
2431  file_processed_bytes+= ((off_t) count) * (off_t) 2048;
2432  ret= Xorriso_check_interval(xorriso, spotlist, job, lba, count, read_chunk,
2433  0, (flag & 2));
2434  if(ret <= 0)
2435  goto ex;
2436  if (ret == 2) {
2437  sprintf(xorriso->info_text, "Attempt aborted to extract data from ");
2438  Text_shellsafe(img_path, xorriso->info_text, 1);
2439  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2440  ret= 0; goto ex;
2441  }
2442  file_base_bytes= new_file_base_bytes;
2443  }
2444 
2445  /* Use spotlist to evaluate damage */
2446  file_base_bytes= 0;
2447  count= Spotlist_count(spotlist, 0);
2448  for(spot= 0; spot < count; spot++) {
2449  ret= Spotlist_get_item(spotlist, spot, &lba, &blocks, &quality, 0);
2450  if(ret <= 0)
2451  continue;
2452  if(quality < Xorriso_read_quality_valiD) {
2453  for(i= 0; i < lba_count; i++) {
2454  if(start_lbas[i] <= lba && end_lbas[i] >= lba) {
2455  start_byte= (lba - start_lbas[i]) * (off_t) 2048 + file_base_bytes;
2456  break;
2457  }
2458  file_base_bytes+= ((off_t) (end_lbas[i] + 1 - start_lbas[i]))
2459  * (off_t) 2048;
2460  }
2461  if(i < lba_count) {
2462  sprintf(xorriso->info_text, "Bad extract : %14.f , %14.f , ",
2463  (double) start_byte, ((double) blocks) * 2048.0);
2464  Text_shellsafe(disk_path, xorriso->info_text, 1);
2465  strcat(xorriso->info_text, "\n");
2466  Xorriso_info(xorriso, 0);
2467  bad_extract= 1;
2468  }
2469  }
2470  }
2471 
2472  ret= !bad_extract;
2473 ex:;
2474  if(start_lbas != NULL)
2475  free((char *) start_lbas);
2476  if(end_lbas != NULL)
2477  free((char *) end_lbas);
2478  if(section_sizes != NULL)
2479  free((char *) section_sizes);
2480  Spotlist_destroy(&spotlist, 0);
2481  Checkmediajob_destroy(&job, 0);
2482  return(ret);
2483 }
2484 
2485 
2486 int Xorriso_extract_boot_images(struct XorrisO *xorriso, char *disk_dir_path,
2487  int flag)
2488 {
2489  int ret, img_count= 0, i, was_problem= 0;
2490  char **imgs= NULL, *eff_path= NULL, *cpt, *eff_namept;
2491  struct stat stbuf;
2492  off_t byte_offset, byte_size;
2493 
2494  Xorriso_alloc_meM(eff_path, char, SfileadrL);
2495  ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_dir_path,
2496  eff_path, 2 | 4);
2497  if(ret <= 0)
2498  goto ex;
2499  if(strlen(eff_path) > SfileadrL - 80) {
2500  sprintf(xorriso->info_text,
2501  "-extract_boot_images: disk_path is too long (%lu)\n",
2502  (unsigned long int) strlen(eff_path));
2503  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2504  ret= 0; goto ex;
2505  }
2506  ret= stat(eff_path, &stbuf);
2507  if(ret == 0) {
2508  if(!S_ISDIR(stbuf.st_mode)) {
2509  sprintf(xorriso->info_text,
2510  "-extract_boot_images: disk_path is not a directory : ");
2511  Text_shellsafe(eff_path, xorriso->info_text, 1);
2512  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2513  ret= 0; goto ex;
2514  }
2515  } else {
2516  ret= mkdir(eff_path, 0777);
2517  if(ret == -1) {
2518  sprintf(xorriso->info_text,
2519  "-extract_boot_images: cannot create directory : ");
2520  Text_shellsafe(eff_path, xorriso->info_text, 1);
2521  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
2522  ret= 0; goto ex;
2523  }
2524  }
2525  strcat(eff_path, "/");
2526  eff_namept= eff_path + strlen(eff_path);
2527 
2528  ret= Xorriso_list_boot_images(xorriso, &imgs, &img_count, 0);
2529  if(ret <= 0)
2530  goto ex;
2531 
2532  /* Interpret list and create files */
2533  for(i= 0; i < img_count; i++) {
2534  ret= Xorriso_eval_problem_status(xorriso, 1, 1 | 2);
2535  if(ret < 0)
2536  {ret= 0; goto ex;}
2537  cpt= strchr(imgs[i], '/');
2538  if(cpt == NULL)
2539  continue;
2540  *cpt= 0;
2541  cpt+= 2;
2542  ret= Sfile_text_to_off_t(cpt, &byte_offset, 0);
2543  if(ret <= 0)
2544  continue;
2545  cpt+= ret;
2546  if(*cpt == 0)
2547  continue;
2548  cpt++;
2549  ret= Sfile_text_to_off_t(cpt, &byte_size, 0);
2550  if(ret <= 0)
2551  continue;
2552 
2553  strcpy(eff_namept, imgs[i]);
2554  sprintf(xorriso->info_text, "%s : offset=%.f size=%.f\n",
2555  eff_path, (double) byte_offset, (double) byte_size);
2556  Xorriso_info(xorriso, 0);
2557 
2558  ret= stat(eff_path, &stbuf);
2559  if(ret != -1) {
2560  sprintf(xorriso->info_text,
2561  "-extract_boot_images: File already exists on disk: ");
2562  Text_shellsafe(eff_path, xorriso->info_text, 1);
2563  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
2564  continue;
2565  }
2566  ret= Xorriso_read_file_data(xorriso, NULL, NULL, eff_path,
2567  byte_offset, (off_t) 0, byte_size, 1);
2568  if(ret <= 0)
2569  was_problem= 1;
2570  }
2571  ret= Xorriso_eval_problem_status(xorriso, 1, 1 | 2);
2572  if(ret < 0 || was_problem)
2573  {ret= 0; goto ex;}
2574 
2575  ret= 1;
2576 ex:;
2577  Xorriso_free_meM(eff_path);
2578  Xorriso_list_boot_images(xorriso, &imgs, &img_count, 1 << 15);
2579  return(ret);
2580 }
2581 
2582 
2583 /* @param node Opaque handle to IsoNode which is to be inquired instead of path if it is not NULL.
2584  @param path is used as address if node is NULL.
2585  @param flag bit0= do not report to result but only indicate outcome
2586  by return value
2587  bit1= silently ignore nodes without MD5
2588  bit2= do not only report mismatches but also matches
2589  @return 3= not a data file
2590  2= no MD5 attached to node
2591  1= ok, MD5 compared and matching
2592  0= not ok, MD5 mismatch
2593  <0= other error
2594 */
2595 int Xorriso_check_md5(struct XorrisO *xorriso, void *in_node, char *path,
2596  int flag)
2597 {
2598  int ret, wanted, rret, buffer_size= 64 * 1024;
2599  IsoImage *image;
2600  IsoNode *node;
2601  IsoFile *file;
2602  char node_md5[16], data_md5[16], *buffer= NULL;
2603  void *stream= NULL, *ctx= NULL;
2604  off_t todo;
2605 
2606  Xorriso_alloc_meM(buffer, char, 64 * 1024);
2607 
2608  node= (IsoNode *) in_node;
2609  if(node == NULL) {
2610  ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
2611  if(ret<=0)
2612  {ret= -1; goto ex;}
2613  }
2614  if(!LIBISO_ISREG(node)) {
2615  strcpy(xorriso->info_text, "-check_md5: Not a data file: ");
2616  Text_shellsafe(path, xorriso->info_text, 1);
2617  if(!(flag & 2))
2618  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2619  ret= 3; goto ex;
2620  }
2621  file= (IsoFile *) node;
2622 
2623  /* obtain MD5 */
2624  ret= Xorriso_get_volume(xorriso, &image, 0);
2625  if(ret <= 0)
2626  {ret= -1; goto ex;}
2627  ret= iso_file_get_md5(image, file, node_md5, 0);
2628  Xorriso_process_msg_queues(xorriso,0);
2629  if(ret < 0)
2630  {ret= -1; goto ex;}
2631  if(ret == 0) {
2632  strcpy(xorriso->info_text, "-check_md5: No MD5 recorded with file: ");
2633  Text_shellsafe(path, xorriso->info_text, 1);
2634  if(!(flag & 2))
2635  Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2636  ret= 2; goto ex;
2637  }
2638 
2639  /* Read file and compute MD5 */;
2640  ret= Xorriso_iso_file_open(xorriso, path, (void *) node, &stream, 1 | 2);
2641  if(ret <= 0)
2642  {ret= -1; goto ex;}
2643  ret= iso_md5_start(&ctx);
2644  if(ret < 0)
2645  goto ex;
2646  todo= iso_stream_get_size(stream);
2647  while(todo > 0) {
2648  if(todo < buffer_size)
2649  wanted= todo;
2650  else
2651  wanted= buffer_size;
2652  rret = Xorriso_iso_file_read(xorriso, stream, buffer, wanted, 0);
2653  if(rret <= 0)
2654  {ret= -1; goto ex;}
2655  todo-= rret;
2656  ret = iso_md5_compute(ctx, buffer, rret);
2657  if(ret < 0)
2658  goto ex;
2659  xorriso->pacifier_count+= rret;
2660  xorriso->pacifier_byte_count+= rret;
2661  Xorriso_pacifier_callback(xorriso, "content bytes read",
2662  xorriso->pacifier_count, 0, "", 8);
2664  xorriso,
2665  xorriso->check_media_default != NULL
2667  : "/var/opt/xorriso/do_abort_check_media",
2668  Sfile_microtime(0), &xorriso->last_abort_file_time, 0);
2669  if(ret == 1)
2670  {ret= -2; goto ex;}
2671  }
2672  ret= iso_md5_end(&ctx, data_md5);
2673  if(ret < 0)
2674  goto ex;
2675 
2676  /* Report outcome */
2677  Xorriso_process_msg_queues(xorriso,0);
2678  if(! iso_md5_match(node_md5, data_md5)) {
2679  sprintf(xorriso->result_line, "MD5 MISMATCH: ");
2680  Text_shellsafe(path, xorriso->result_line, 1);
2681  strcat(xorriso->result_line, "\n");
2682  if(!(flag & 1))
2683  Xorriso_result(xorriso,0);
2684  ret= 0;
2685  } else {
2686  sprintf(xorriso->result_line, "md5 match : ");
2687  Text_shellsafe(path, xorriso->result_line, 1);
2688  strcat(xorriso->result_line, "\n");
2689  if(flag & 4)
2690  Xorriso_result(xorriso,0);
2691  ret= 1;
2692  }
2693 
2694 ex:;
2695  Xorriso_process_msg_queues(xorriso,0);
2696  Xorriso_iso_file_close(xorriso, &stream, 0);
2697  if(ctx != NULL)
2698  iso_md5_end(&ctx, data_md5);
2699  Xorriso_free_meM(buffer);
2700  if(ret < 0) {
2701  if(ret == -2)
2702  sprintf(xorriso->result_line, "Aborted at: ");
2703  else
2704  sprintf(xorriso->result_line, "NOT READABLE: ");
2705  Text_shellsafe(path, xorriso->result_line, 1);
2706  strcat(xorriso->result_line, "\n");
2707  if(!(flag & 1))
2708  Xorriso_result(xorriso,0);
2709  if(ret == -2)
2710  xorriso->request_to_abort= 1;
2711  }
2712  return(ret);
2713 }
2714 
int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf, int flag)
Definition: aux_objects.c:946
int Linkitem_reset_stack(struct LinkiteM **o, struct LinkiteM *to, int flag)
Definition: aux_objects.c:895
int Splitparts_get(struct SplitparT *o, int idx, char **name, int *partno, int *total_parts, off_t *offset, off_t *bytes, off_t *total_bytes, int flag)
Definition: aux_objects.c:115
int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper, struct XorrisO *xorriso, int flag)
Definition: aux_objects.c:975
int Splitparts_destroy(struct SplitparT **o, int count, int flag)
Definition: aux_objects.c:81
int Xorriso_lst_append_binary(struct Xorriso_lsT **entry, char *data, int data_len, int flag)
Create a new list item at the end of a given list.
Definition: aux_objects.c:609
int Spotlist_get_item(struct SpotlisT *o, int idx, int *start_lba, int *blocks, int *quality, int flag)
Definition: check_media.c:182
int Checkmediajob_destroy(struct CheckmediajoB **o, int flag)
Definition: check_media.c:604
int Xorriso_open_job_data_to(struct XorrisO *xorriso, struct CheckmediajoB *job, int flag)
Definition: check_media.c:1082
int Spotlist_destroy(struct SpotlisT **o, int flag)
Definition: check_media.c:102
int Checkmediajob_copy(struct CheckmediajoB *from, struct CheckmediajoB *to, int flag)
Definition: check_media.c:617
int Spotlist_count(struct SpotlisT *o, int flag)
Definition: check_media.c:147
int Checkmediajob_new(struct CheckmediajoB **o, int flag)
Definition: check_media.c:568
int Spotlist_new(struct SpotlisT **o, int flag)
Definition: check_media.c:85
#define Xorriso_read_quality_valiD
Definition: check_media.h:86
int Xorriso_auto_chmod(struct XorrisO *xorriso, char *disk_path, int flag)
Definition: disk_ops.c:1609
int Xorriso_reassure_restore(struct XorrisO *xorriso, char *path, int flag)
Definition: disk_ops.c:1518
int Xorriso_make_restore_path(struct XorrisO *xorriso, struct Xorriso_lsT **img_prefixes, struct Xorriso_lsT **disk_prefixes, char img_path[4096], char disk_path[4096], int flag)
Definition: disk_ops.c:1700
int Xorriso_make_tmp_path(struct XorrisO *xorriso, char *orig_path, char *tmp_path, int *fd, int flag)
Definition: disk_ops.c:1578
int Xorriso_resolve_link(struct XorrisO *xorriso, char *link_path, char result_path[4096], int flag)
Definition: disk_ops.c:45
int Xorriso_make_accessible(struct XorrisO *xorriso, char *disk_path, int flag)
Definition: disk_ops.c:1666
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_restore_make_hl(struct XorrisO *xorriso, char *old_path, char *new_path, int flag)
Definition: disk_ops.c:1749
int Xorriso_rmx(struct XorrisO *xorriso, off_t boss_mem, char *path, int flag)
Definition: disk_ops.c:954
int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist, struct CheckmediajoB *job, int from_lba, int block_count, int read_chunk, int md5_start, int flag)
Definition: drive_mgt.c:2807
int Xorriso_obtain_indev_readsize(struct XorrisO *xorriso, uint32_t *blocks, int flag)
Definition: drive_mgt.c:3606
int Xorriso_check_for_abort(struct XorrisO *xorriso, char *abort_file_path, double post_read_time, double *last_abort_file_time, int flag)
Definition: drive_mgt.c:2466
#define SfileadrL
int Xorriso_change_is_pending(struct XorrisO *xorriso, int flag)
Definition: iso_img.c:995
int Xorriso_list_boot_images(struct XorrisO *xorriso, char ***imgs, int *img_count, int flag)
Definition: iso_img.c:3140
int Xorriso_get_volume(struct XorrisO *xorriso, IsoImage **volume, int flag)
Definition: iso_img.c:966
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__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_fake_stbuf(struct XorrisO *xorriso, char *path, struct stat *stbuf, IsoNode **node, int flag)
Definition: iso_tree.c:245
int Xorriso_iso_lstat(struct XorrisO *xorriso, char *path, struct stat *stbuf, int flag)
Definition: iso_tree.c:363
int Xorriso_path_from_node(struct XorrisO *xorriso, IsoNode *in_node, char path[4096], int flag)
Definition: iso_tree.c:399
int Xorriso_identify_split(struct XorrisO *xorriso, char *iso_adr, void *in_node, struct SplitparT **parts, int *count, struct stat *total_stbuf, int flag)
Definition: iso_tree.c:500
int Xorriso_node_from_path(struct XorrisO *xorriso, IsoImage *volume, char *path, IsoNode **node, int flag)
Definition: iso_tree.c:2650
int Xorriso_is_plain_image_file(struct XorrisO *xorriso, void *in_node, char *path, int flag)
Definition: iso_tree.c:2749
int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node, int *node_idx, int *min_hl, int *max_hl, int flag)
Definition: iso_tree.c:2601
int Xorriso_node_get_dev(struct XorrisO *xorriso, IsoNode *node, char *path, dev_t *dev, int flag)
Definition: iso_tree.c:229
int Xorriso__start_end_lbas(IsoNode *node, int *lba_count, int **start_lbas, int **end_lbas, off_t **section_sizes, off_t *size, int flag)
Definition: iso_tree.c:2210
int Xorriso_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
#define LIBISO_ISREG(node)
Definition: iso_tree.h:18
#define LIBISO_ISDIR(node)
Definition: iso_tree.h:17
#define LIBISO_ISBLK(node)
Definition: iso_tree.h:22
#define LIBISO_ISCHR(node)
Definition: iso_tree.h:20
#define LIBISO_ISSOCK(node)
Definition: iso_tree.h:26
#define LIBISO_ISFIFO(node)
Definition: iso_tree.h:24
#define LIBISO_ISLNK(node)
Definition: iso_tree.h:19
int Xorriso_report_iso_error(struct XorrisO *xorriso, char *victim, int iso_error_code, char msg_text[], int os_errno, char min_severity[], int flag)
Definition: lib_mgt.c:430
int Xorriso_process_msg_queues(struct XorrisO *xorriso, int flag)
Forward any pending messages from the library message queues to the xorriso message system which puts...
Definition: lib_mgt.c:519
int Xorriso_md5_start(struct XorrisO *xorriso, void **ctx, int flag)
Definition: lib_mgt.c:648
int Xorriso_md5_end(struct XorrisO *xorriso, void **ctx, char md5[16], int flag)
Definition: lib_mgt.c:668
int Xorriso_md5_compute(struct XorrisO *xorriso, void *ctx, char *data, int datalen, int flag)
Definition: lib_mgt.c:660
char * Text_shellsafe(char *in_text, char *out_text, int flag)
Definition: misc_funct.c:1044
int Xorriso_eval_problem_status(struct XorrisO *xorriso, int ret, int flag)
Evaluate an advise whether to abort or whether to go on with option processing.
Definition: parse_exec.c:307
int Xorriso_path_is_excluded(struct XorrisO *xorriso, char *path, int flag)
Definition: parse_exec.c:3130
int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node, char *img_path, off_t img_offset, char *disk_path, off_t disk_offset, off_t bytes, int flag)
Definition: read_run.c:819
int Xorriso_iso_file_open(struct XorrisO *xorriso, char *pathname, void *node_pt, void **stream, int flag)
Definition: read_run.c:66
int Xorriso_iso_file_to_fd(struct XorrisO *xorriso, char *path, int fd, int flag)
Definition: read_run.c:253
int Xorriso_restore_target_hl(struct XorrisO *xorriso, IsoNode *node, char *disk_path, int *node_idx, int flag)
Definition: read_run.c:1253
static int Xorriso_sparse_finish(struct XorrisO *xorriso, struct Xorriso_sparse_statE **sparse_state, int write_fd, int flag)
Definition: read_run.c:754
#define O_BINARY
Definition: read_run.c:33
static int Xorriso_sparse_write(struct XorrisO *xorriso, struct Xorriso_sparse_statE *sparse_state, int write_fd, char *buf, int count, int flag)
Definition: read_run.c:644
int Xorriso_extract_boot_images(struct XorrisO *xorriso, char *disk_dir_path, int flag)
Definition: read_run.c:2486
int Xorriso_restore_implicit_properties(struct XorrisO *xorriso, char *full_disk_path, char *disk_path, char *full_img_path, int flag)
Definition: read_run.c:477
static int Xorriso_sparse_init(struct XorrisO *xorriso, struct Xorriso_sparse_statE **sparse_state, int write_fd, int flag)
Definition: read_run.c:565
int Xorriso_restore_disk_object(struct XorrisO *xorriso, char *img_path, IsoNode *node, char *disk_path, off_t offset, off_t bytes, int flag)
Definition: read_run.c:1385
int Xorriso_register_node_target(struct XorrisO *xorriso, int node_idx, char *disk_path, int flag)
Definition: read_run.c:1340
static int Xorriso_sparse_zeroize(struct XorrisO *xorriso, struct Xorriso_sparse_statE *sparse_state, int write_fd, off_t start, off_t count, int flag)
Definition: read_run.c:607
int Xorriso_restore_node_array(struct XorrisO *xorriso, int flag)
Definition: read_run.c:2092
int Xorriso_extract_cut(struct XorrisO *xorriso, char *img_path, char *disk_path, off_t img_offset, off_t bytes, int flag)
Definition: read_run.c:2255
int Xorriso_restore_is_identical(struct XorrisO *xorriso, void *in_node, char *img_path, char *disk_path, char type_text[5], int flag)
Definition: read_run.c:190
int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path, IsoNode *node, int flag)
Definition: read_run.c:309
int Xorriso_paste_in(struct XorrisO *xorriso, char *disk_path, off_t startbyte, off_t bytecount, char *iso_rr_path, int flag)
Definition: read_run.c:2201
int Xorriso_handle_collision(struct XorrisO *xorriso, IsoNode *node, char *img_path, char *disk_path, char *nominal_disk_path, int *stbuf_ret, int flag)
Definition: read_run.c:1522
int Xorriso_restore_overwrite(struct XorrisO *xorriso, IsoNode *node, char *img_path, char *path, char *nominal_path, struct stat *stbuf, int flag)
Definition: read_run.c:1203
int Xorriso_restore_prefix_hl(struct XorrisO *xorriso, IsoNode *node, char *disk_path, int node_idx, int flag)
Definition: read_run.c:1286
int Xorriso_iso_file_close(struct XorrisO *xorriso, void **stream, int flag)
Definition: read_run.c:169
int Xorriso_check_md5(struct XorrisO *xorriso, void *in_node, char *path, int flag)
Definition: read_run.c:2595
int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node, char *img_path, char *disk_path, off_t img_offset, off_t disk_offset, off_t bytes, int flag)
Definition: read_run.c:2338
int Xorriso__read_pacifier(IsoImage *image, IsoFileSource *filesource)
Definition: read_run.c:46
int Xorriso_restore(struct XorrisO *xorriso, char *img_path, char *disk_path, off_t offset, off_t bytes, int flag)
Definition: read_run.c:1891
int Xorriso_iso_file_read(struct XorrisO *xorriso, void *stream, char *buf, int count, int flag)
Definition: read_run.c:145
int Xorriso_restore_tree(struct XorrisO *xorriso, IsoDir *dir, char *img_dir_path, char *disk_dir_path, off_t boss_mem, struct LinkiteM *link_stack, int flag)
Definition: read_run.c:1604
int Sfile_count_components(char *path, int flag)
Definition: sfile.c:61
int Sfile_add_to_path(char path[4096], char *addon, int flag)
Definition: sfile.c:137
double Sfile_microtime(int flag)
Return a double representing seconds and microseconds since 1 Jan 1970.
Definition: sfile.c:883
int Sfile_str(char target[4096], char *source, int flag)
Definition: sfile.c:836
int Sfile_text_to_off_t(char *text, off_t *num, int flag)
Definition: sfile.c:435
#define Xorriso_free_meM(pt)
Definition: sfile.h:27
#define Xorriso_alloc_meM(pt, typ, count)
Definition: sfile.h:19
int Xorriso_sort_node_array(struct XorrisO *xorriso, int flag)
Definition: sort_cmp.c:82
int Xorriso__findi_sorted_ino_cmp(const void *p1, const void *p2)
Definition: sort_cmp.c:34
off_t data_to_offset
Definition: check_media.h:119
char data_to_path[SfileadrL]
Definition: check_media.h:117
char abort_file_path[SfileadrL]
Definition: check_media.h:115
off_t data_to_limit
Definition: check_media.h:120
char sector_map_path[SfileadrL]
Definition: check_media.h:125
char * disk_path
Definition: aux_objects.c:940
struct stat stbuf
Definition: aux_objects.c:941
int do_strict_acl
off_t pacifier_count
int do_follow_mount
void ** hln_array
struct Xorriso_lsT * node_img_prefixes
int allow_restore
off_t sparse_min_gap
struct PermiteM * perm_stack
struct Xorriso_lsT * node_disk_prefixes
off_t pacifier_byte_count
int do_follow_links
int ino_behavior
int do_overwrite
char result_line[10 *4096]
int do_auto_chmod
char info_text[10 *4096]
void ** hln_targets
int do_concat_split
int request_to_abort
void ** node_array
off_t node_targets_availmem
int node_counter
int extract_error_mode
char wdx[4096]
int node_array_size
double last_update_time
int do_follow_param
off_t pacifier_total
struct CheckmediajoB * check_media_default
double last_abort_file_time
char wdi[4096]
off_t after_last_written
Definition: read_run.c:544
int Xorriso_msgs_submit(struct XorrisO *xorriso, int error_code, char msg_text[], int os_errno, char severity[], int flag)
Submit a problem message to the xorriso problem reporting and handling system.
Definition: text_io.c:2504
int Xorriso_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
int Xorriso_pacifier_reset(struct XorrisO *xorriso, int flag)
Definition: text_io.c:3937
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