3
/* Adapter to libisoburn, libisofs and libburn for xorriso,
4
a command line oriented batch and dialog tool which creates, loads,
5
manipulates and burns ISO 9660 filesystem images.
7
Copyright 2007-2010 Thomas Schmitt, <scdbackup@gmx.net>
9
Provided under GPL version 2 or later.
13
#include <sys/types.h>
32
/* ------------------------------------------------------------------------ */
34
#ifndef Xorriso_standalonE
36
/* The library which does the ISO 9660 / RockRidge manipulations */
37
#include <libisofs/libisofs.h>
39
/* The library which does MMC optical drive operations */
40
#include <libburn/libburn.h>
42
/* The library which enhances overwriteable media with ISO 9660 multi-session
43
capabilities via the method invented by Andy Polyakov for growisofs */
44
#include <libisoburn/libisoburn.h>
46
/* The official xorriso options API. "No shortcuts" */
49
/* The inner description of XorrisO */
50
#include "xorriso_private.h"
52
/* The inner isofs- and burn-library interface */
53
#include "xorrisoburn.h"
55
#else /* ! Xorriso_standalonE */
57
#include "../libisofs/libisofs.h"
58
#include "../libburn/libburn.h"
59
#include "../libisoburn/libisoburn.h"
61
#include "xorriso_private.h"
62
#include "xorrisoburn.h"
64
#endif /* Xorriso_standalonE */
67
/* Some private in advance declarations */
68
int Xorriso_pacifier_loop(struct XorrisO *xorriso, struct burn_drive *drive,
71
int Xorriso__read_pacifier(IsoImage *image, IsoFileSource *filesource);
73
int Xorriso_tree_graft_node(struct XorrisO *xorriso, IsoImage *volume,
74
IsoDir *dir, char *disk_path, char *img_name,
75
char *nominal_source, char *nominal_target,
76
off_t offset, off_t cut_size,
77
IsoNode **node, int flag);
79
int Xorriso_findi_iter(struct XorrisO *xorriso, IsoDir *dir_node, off_t *mem,
81
IsoNode ***node_array, int *node_count, int *node_idx,
82
IsoNode **iterated_node, int flag);
84
int Xorriso__file_start_lba(IsoNode *node, int *lba, int flag);
86
int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node,
87
char *img_path, char *disk_path,
88
off_t img_offset, off_t disk_offset,
89
off_t bytes, int flag);
91
int Xorriso_path_from_node(struct XorrisO *xorriso, IsoNode *in_node,
92
char path[SfileadrL], int flag);
94
int Xorriso_node_from_path(struct XorrisO *xorriso, IsoImage *volume,
95
char *path, IsoNode **node, int flag);
97
int Xorriso_path_from_lba(struct XorrisO *xorriso, IsoNode *node, int lba,
98
char path[SfileadrL], int flag);
100
int Xorriso__node_lba_cmp(const void *node1, const void *node2);
102
int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node,
103
int *node_idx, int *min_hl, int *max_hl, int flag);
106
#define LIBISO_ISDIR(node) (iso_node_get_type(node) == LIBISO_DIR)
107
#define LIBISO_ISREG(node) (iso_node_get_type(node) == LIBISO_FILE)
108
#define LIBISO_ISLNK(node) (iso_node_get_type(node) == LIBISO_SYMLINK)
109
#define LIBISO_ISCHR(node) (iso_node_get_type(node) == LIBISO_SPECIAL && \
110
S_ISCHR(iso_node_get_mode(node)))
111
#define LIBISO_ISBLK(node) (iso_node_get_type(node) == LIBISO_SPECIAL && \
112
S_ISBLK(iso_node_get_mode(node)))
113
#define LIBISO_ISFIFO(node) (iso_node_get_type(node) == LIBISO_SPECIAL && \
114
S_ISFIFO(iso_node_get_mode(node)))
115
#define LIBISO_ISSOCK(node) (iso_node_get_type(node) == LIBISO_SPECIAL && \
116
S_ISSOCK(iso_node_get_mode(node)))
117
#define LIBISO_ISBOOT(node) (iso_node_get_type(node) == LIBISO_BOOT)
120
/* CD specs say one shall not write tracks < 600 kiB */
121
#define Xorriso_cd_min_track_sizE 300
124
/* Default setting for -compliance */
125
#define Xorriso_relax_compliance_defaulT \
126
(isoburn_igopt_allow_deep_paths | isoburn_igopt_allow_longer_paths | \
127
isoburn_igopt_always_gmt | \
128
isoburn_igopt_rrip_version_1_10 | isoburn_igopt_aaip_susp_1_10 | \
129
isoburn_igopt_only_iso_versions | isoburn_igopt_no_j_force_dots)
133
unsigned long Xorriso_get_di_counteR= 0;
137
/* ------------------------------------------------------------------------ */
140
static const char *un0(const char *text)
148
int Xorriso_abort(struct XorrisO *xorriso, int flag)
152
ret= burn_abort(4440, burn_abort_pacifier, "xorriso : ");
155
"\nxorriso : ABORT : Cannot cancel burn session and release drive.\n");
159
"xorriso : ABORT : Drive is released and library is shut down now.\n");
161
"xorriso : ABORT : Program done. Even if you do not see a shell prompt.\n");
162
fprintf(stderr, "\n");
167
int Xorriso_destroy_node_array(struct XorrisO *xorriso, int flag)
171
if(xorriso->node_array != NULL) {
172
for(i= 0; i < xorriso->node_counter; i++)
173
iso_node_unref((IsoNode *) xorriso->node_array[i]);
174
free(xorriso->node_array);
176
xorriso->node_array= NULL;
177
xorriso->node_counter= xorriso->node_array_size= 0;
178
Xorriso_lst_destroy_all(&(xorriso->node_disk_prefixes), 0);
179
Xorriso_lst_destroy_all(&(xorriso->node_img_prefixes), 0);
184
/* @param flag bit0= do not destroy hln_array but only hln_targets
186
int Xorriso_destroy_hln_array(struct XorrisO *xorriso, int flag)
191
if(xorriso->hln_array != NULL && !(flag & 1)) {
192
for(i= 0; i < xorriso->hln_count; i++)
193
iso_node_unref((IsoNode *) xorriso->hln_array[i]);
194
free(xorriso->hln_array);
195
xorriso->hln_array= NULL;
196
xorriso->hln_count= 0;
198
if(xorriso->hln_targets != NULL) {
199
for(i= 0; i < xorriso->hln_count; i++)
200
if(xorriso->hln_targets[i] != NULL)
201
free(xorriso->hln_targets[i]);
202
free(xorriso->hln_targets);
203
xorriso->hln_targets= NULL;
205
xorriso->node_targets_availmem= 0;
210
int Xorriso_destroy_di_array(struct XorrisO *xorriso, int flag)
214
if(xorriso->di_array != NULL) {
215
for(i= 0; i < xorriso->di_count; i++)
216
if(xorriso->di_array[i] != NULL)
217
iso_node_unref((IsoNode *) xorriso->di_array[i]);
218
free(xorriso->di_array);
219
xorriso->di_array= NULL;
221
if(xorriso->di_do_widen != NULL) {
222
free(xorriso->di_do_widen);
223
xorriso->di_do_widen= NULL;
225
Xorriso_lst_destroy_all(&(xorriso->di_disk_paths), 0);
226
Xorriso_lst_destroy_all(&(xorriso->di_iso_paths), 0);
227
xorriso->di_count= 0;
231
fprintf(stderr, "xorriso_DEBUG: get_di_count= %lu\n",
232
Xorriso_get_di_counteR);
239
int Xorriso_new_node_array(struct XorrisO *xorriso, off_t mem_limit,
240
int addon_nodes, int flag)
244
if(xorriso->node_counter <= 0)
247
xorriso->node_array= calloc(xorriso->node_counter + addon_nodes,
249
if(xorriso->node_array == NULL) {
250
Xorriso_no_malloc_memory(xorriso, NULL, 0);
253
for(i= 0; i < xorriso->node_counter + addon_nodes; i++)
254
xorriso->node_array[i]= NULL;
255
xorriso->node_array_size= xorriso->node_counter + addon_nodes;
256
xorriso->node_counter= 0;
261
/* @param flag bit0= do not allocate hln_array but only hln_targets
263
int Xorriso_new_hln_array(struct XorrisO *xorriso, off_t mem_limit, int flag)
267
Xorriso_destroy_hln_array(xorriso, flag & 1);
268
if(xorriso->hln_count <= 0)
272
xorriso->hln_array= calloc(xorriso->hln_count, sizeof(char *));
273
if(xorriso->hln_array == NULL) {
274
Xorriso_no_malloc_memory(xorriso, NULL, 0);
277
for(i= 0; i < xorriso->hln_count; i++)
278
xorriso->hln_array[i]= NULL;
281
xorriso->hln_targets= calloc(xorriso->hln_count, sizeof(char *));
282
if(xorriso->hln_targets == NULL) {
284
free(xorriso->hln_array);
285
xorriso->hln_array= NULL;
287
Xorriso_no_malloc_memory(xorriso, NULL, 0);
290
for(i= 0; i < xorriso->hln_count; i++)
291
xorriso->hln_targets[i]= NULL;
292
xorriso->node_targets_availmem= mem_limit
293
- xorriso->hln_count * sizeof(void *)
294
- xorriso->hln_count * sizeof(char *);
295
if(xorriso->node_targets_availmem < 0)
296
xorriso->node_targets_availmem= 0;
301
int Xorriso__findi_sorted_ino_cmp(const void *p1, const void *p2)
306
n1= *((IsoNode **) p1);
307
n2= *((IsoNode **) p2);
309
ret= Xorriso__node_lba_cmp(&n1, &n2);
311
return (ret > 0 ? 1 : -1);
312
ret= iso_node_cmp_ino(n1, n2, 0);
317
/* Not suitable for qsort() but for cross-array comparisons.
318
p1 and p2 are actually IsoNode *p1, IsoNode *p2
320
int Xorriso__hln_cmp(const void *p1, const void *p2)
324
ret= Xorriso__findi_sorted_ino_cmp(&p1, &p2);
326
return (ret > 0 ? 1 : -1);
328
return(p1 < p2 ? -1 : 1);
334
p1 and p2 are actually IsoNode **p1, IsoNode **p2
336
int Xorriso__findi_sorted_cmp(const void *p1, const void *p2)
340
ret= Xorriso__findi_sorted_ino_cmp(p1, p2);
342
return (ret > 0 ? 1 : -1);
344
return(p1 < p2 ? -1 : 1);
349
int Xorriso_sort_node_array(struct XorrisO *xorriso, int flag)
351
if(xorriso->node_counter <= 0)
353
qsort(xorriso->node_array, xorriso->node_counter, sizeof(IsoNode *),
354
Xorriso__findi_sorted_cmp);
359
int Xorriso__search_node(void *node_array[], int n,
360
int (*cmp)(const void *p1, const void *p2),
361
void *node, int *idx, int flag)
363
int ret, l, r, p, pos;
375
/* NULL elements may indicate invalid nodes. Their first valid right neigbor
376
will serve as proxy. If none exists, then the test pushes leftwards.
378
for(pos= p - 1; pos < n; pos++)
379
if(node_array[pos] != NULL)
382
ret= (*cmp)(&(node_array[pos]), &node);
399
int Xorriso_search_in_hln_array(struct XorrisO *xorriso,
400
void *node, int *idx, int flag)
404
if(xorriso->hln_array == NULL || xorriso->hln_count <= 0)
406
ret= Xorriso__search_node(xorriso->hln_array, xorriso->hln_count,
407
Xorriso__findi_sorted_ino_cmp, node, idx, 0);
412
int Xorriso__get_di(IsoNode *node, dev_t *dev, ino_t *ino, int flag)
414
int ret, i, i_end, imgid, error_code;
415
size_t value_length= 0;
416
char *value= NULL, msg[ISO_MSGS_MESSAGE_LEN], severity[80];
418
static char *name= "isofs.di";
422
Xorriso_get_di_counteR++;
427
ret= iso_node_lookup_attr(node, name, &value_length, &value, 0);
429
/* Drop any pending messages because there is no xorriso to take them */
430
iso_obtain_msgs("NEVER", &error_code, &imgid, msg, severity);
433
vpt= (unsigned char *) value;
434
for(i= 1; i <= vpt[0] && i < value_length; i++)
435
*dev= ((*dev) << 8) | vpt[i];
436
i_end= i + vpt[i] + 1;
437
for(i++; i < i_end && i < value_length; i++)
438
*ino= ((*ino) << 8) | vpt[i];
444
int Xorriso__di_ino_cmp(const void *p1, const void *p2)
451
n1= *((IsoNode **) p1);
452
n2= *((IsoNode **) p2);
454
ret= Xorriso__get_di(n1, &d1, &i1, 0);
457
ret= Xorriso__get_di(n2, &d2, &i2, 0);
469
if(d1 == 0 && i1 == 0 && n1 != n2)
470
return(n1 < n2 ? -1 : 1);
475
int Xorriso__di_cmp(const void *p1, const void *p2)
480
ret= Xorriso__di_ino_cmp(p1, p2);
483
n1= *((IsoNode **) p1);
484
n2= *((IsoNode **) p2);
486
return(n1 < n2 ? -1 : 1);
491
int Xorriso__sort_di(void *node_array[], int count, int flag)
495
qsort(node_array, count, sizeof(IsoNode *), Xorriso__di_cmp);
500
int Xorriso_invalidate_di_item(struct XorrisO *xorriso, IsoNode *node,
505
if(xorriso->di_array == NULL)
507
ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count,
508
Xorriso__di_cmp, node, &idx, 0);
511
if(xorriso->di_array[idx] != NULL)
512
iso_node_unref(xorriso->di_array[idx]);
513
xorriso->di_array[idx]= NULL;
518
/* @param flag bit0= return 1 even if matching nodes were found but node is
520
bit1= use Xorriso__di_cmp() rather than Xorriso__di_ino_cmp()
522
int Xorriso_search_di_range(struct XorrisO *xorriso, IsoNode *node,
523
int *idx, int *low, int *high, int flag)
526
int (*cmp)(const void *p1, const void *p2)= Xorriso__di_ino_cmp;
529
cmp= Xorriso__di_cmp;
531
*high= *low= *idx= -1;
532
ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count,
533
cmp, node, &found, 0);
537
for(i= found + 1; i < xorriso->di_count; i++)
538
if(xorriso->di_array[i] != NULL) {
539
if((*cmp)(&node, &(xorriso->di_array[i])) != 0)
543
for(i= found - 1; i >= 0; i--)
544
if(xorriso->di_array[i] != NULL) {
545
if((*cmp)(&node, &(xorriso->di_array[i])) != 0)
549
for(i= *low; i <= *high; i++)
550
if(xorriso->di_array[i] == node) {
554
return(*idx >= 0 || (flag & 1));
558
/* ------------------------------------------------------------------------ */
560
/* @param flag bit0= asynchronous handling (else catch thread, wait, and exit)
562
int Xorriso_set_signal_handling(struct XorrisO *xorriso, int flag)
564
char *handler_prefix= NULL;
566
if(Xorriso__get_signal_behavior(0) != 1)
568
handler_prefix= calloc(strlen(xorriso->progname)+3+1, 1);
569
if(handler_prefix==NULL) {
570
sprintf(xorriso->info_text,
571
"Cannot allocate memory for for setting signal handler");
572
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
575
sprintf(handler_prefix, "%s : ", xorriso->progname);
576
burn_set_signal_handling(handler_prefix, NULL, (flag & 1) * 0x30);
577
free(handler_prefix);
582
int Xorriso_startup_libraries(struct XorrisO *xorriso, int flag)
584
int ret, major, minor, micro;
585
char *queue_sev, *print_sev, reason[1024];
586
struct iso_zisofs_ctrl zisofs_ctrl= {0, 6, 15};
589
/* First an ugly compile time check for header version compatibility.
590
If everthing matches, then no C code is produced. In case of mismatch,
591
intentionally faulty C code will be inserted.
594
/* The minimum requirement of xorriso towards the libisoburn header
595
at compile time is defined in xorriso/xorrisoburn.h
596
xorriso_libisoburn_req_major
597
xorriso_libisoburn_req_minor
598
xorriso_libisoburn_req_micro
599
It gets compared against the version macros in libburn/libburn.h :
600
isoburn_header_version_major
601
isoburn_header_version_minor
602
isoburn_header_version_micro
603
If the header is too old then the following code shall cause failure of
604
cdrskin compilation rather than to allow production of a program with
605
unpredictable bugs or memory corruption.
606
The compiler messages supposed to appear in this case are:
607
error: 'LIBISOBURN_MISCONFIGURATION' undeclared (first use in this function)
608
error: 'INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libisoburn_dot_h_TOO_OLD__SEE_xorrisoburn_dot_c' undeclared (first use in this function)
609
error: 'LIBISOBURN_MISCONFIGURATION_' undeclared (first use in this function)
611
/* The indendation is an advise of man gcc to help old compilers ignoring */
612
#if xorriso_libisoburn_req_major > isoburn_header_version_major
613
#define Isoburn_libisoburn_dot_h_too_olD 1
615
#if xorriso_libisoburn_req_major == isoburn_header_version_major && xorriso_libisoburn_req_minor > isoburn_header_version_minor
616
#define Isoburn_libisoburn_dot_h_too_olD 1
618
#if xorriso_libisoburn_req_minor == isoburn_header_version_minor && xorriso_libisoburn_req_micro > isoburn_header_version_micro
619
#define Isoburn_libisoburn_dot_h_too_olD 1
622
#ifdef Isoburn_libisoburn_dot_h_too_olD
623
LIBISOBURN_MISCONFIGURATION = 0;
624
INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libisoburn_dot_h_TOO_OLD__SEE_xorrisoburn_dot_c = 0;
625
LIBISOBURN_MISCONFIGURATION_ = 0;
628
/* End of ugly compile time test (scroll up for explanation) */
631
ret= isoburn_initialize(reason, 0);
633
sprintf(xorriso->info_text, "Cannot initialize libraries");
635
sprintf(xorriso->info_text+strlen(xorriso->info_text),
636
". Reason given:\n%s", reason);
637
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
640
ret= isoburn_is_compatible(isoburn_header_version_major,
641
isoburn_header_version_minor,
642
isoburn_header_version_micro, 0);
644
isoburn_version(&major, &minor, µ);
645
sprintf(xorriso->info_text,
646
"libisoburn version too old: %d.%d.%d . Need at least: %d.%d.%d .\n",
648
isoburn_header_version_major, isoburn_header_version_minor,
649
isoburn_header_version_micro);
650
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
654
xorriso->libs_are_started= 1;
657
if(xorriso->library_msg_direct_print) {
659
/* >>> need option for controlling this in XorrisO.
660
See also Xorriso_msgs_submit */;
662
print_sev= xorriso->report_about_text;
666
iso_set_msgs_severities(queue_sev, print_sev, "libsofs : ");
667
burn_msgs_set_severities(queue_sev, print_sev, "libburn : ");
669
/* ??? >>> do we want united queues ? */
670
/* burn_set_messenger(iso_get_messenger()); */
672
isoburn_set_msgs_submit(Xorriso_msgs_submit_void, (void *) xorriso,
675
ret= Xorriso_set_signal_handling(xorriso, 0);
679
ret = iso_zisofs_get_params(&zisofs_ctrl, 0);
681
xorriso->zisofs_block_size= xorriso->zisofs_block_size_default=
682
(1 << zisofs_ctrl.block_size_log2);
683
xorriso->zlib_level= xorriso->zlib_level_default=
684
zisofs_ctrl.compression_level;
686
Xorriso_process_msg_queues(xorriso,0);
688
sprintf(xorriso->info_text, "%s", reason);
689
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
691
strcpy(xorriso->info_text, "Using ");
692
strncat(xorriso->info_text, burn_scsi_transport_id(0), 1024);
693
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
698
/* @param flag bit0= global shutdown of libraries */
699
int Xorriso_detach_libraries(struct XorrisO *xorriso, int flag)
701
Xorriso_give_up_drive(xorriso, 3);
702
if(xorriso->in_volset_handle!=NULL) { /* standalone image */
703
iso_image_unref((IsoImage *) xorriso->in_volset_handle);
704
xorriso->in_volset_handle= NULL;
705
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
706
Xorriso_destroy_di_array(xorriso, 0);
707
Xorriso_destroy_hln_array(xorriso, 0);
710
if(xorriso->libs_are_started==0)
719
bit0= if not MMC drive print NOTE and return 2
720
bit1= obtain outdrive, else indrive
721
bit4= do not report failure
723
int Xorriso_get_drive_handles(struct XorrisO *xorriso,
724
struct burn_drive_info **dinfo,
725
struct burn_drive **drive,
726
char *attempt, int flag)
731
*dinfo= (struct burn_drive_info *) xorriso->out_drive_handle;
733
*dinfo= (struct burn_drive_info *) xorriso->in_drive_handle;
734
if(*dinfo==NULL && !(flag & 16)) {
735
Xorriso_process_msg_queues(xorriso,0);
736
sprintf(xorriso->info_text, "No %s drive aquired %s",
737
(flag&2 ? "output" : "input"), attempt);
738
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
742
*drive= (*dinfo)[0].drive;
744
ret= burn_drive_get_drive_role(*drive);
746
sprintf(xorriso->info_text,
747
"Output device is not an MMC drive. Desired operation does not apply.");
748
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
752
return((*drive)!=NULL);
756
int Xorriso__sev_to_text(int severity, char **severity_name,
761
ret= iso_sev_to_text(severity, severity_name);
764
ret= burn_sev_to_text(severity, severity_name, 0);
772
int Xorriso__text_to_sev(char *severity_name, int *severity_number, int flag)
776
ret= iso_text_to_sev(severity_name, severity_number);
779
ret= burn_text_to_sev(severity_name, severity_number, 0);
784
/* @param flag bit0= report libisofs error text
785
bit1= victim is disk_path
786
bit2= do not inquire libisofs, report msg_text and min_severity
788
int Xorriso_report_iso_error(struct XorrisO *xorriso, char *victim,
789
int iso_error_code, char msg_text[], int os_errno,
790
char min_severity[], int flag)
792
int error_code, iso_sev, min_sev, ret;
793
char *sev_text_pt, *msg_text_pt= NULL;
794
char sfe[6*SfileadrL];
795
static int sorry_sev= -1;
798
Xorriso__text_to_sev("SORRY", &sorry_sev, 0);
801
error_code= 0x00050000;
802
Xorriso__text_to_sev(min_severity, &iso_sev, 0);
804
error_code= iso_error_get_code(iso_error_code);
805
if(error_code < 0x00030000 || error_code >= 0x00040000)
806
error_code= (error_code & 0xffff) | 0x00050000;
808
msg_text_pt= (char *) iso_error_to_msg(iso_error_code);
809
iso_sev= iso_error_get_severity(iso_error_code);
811
if(msg_text_pt==NULL)
812
msg_text_pt= msg_text;
814
if(iso_sev >= sorry_sev && (flag & 2) && victim[0])
815
Xorriso_msgs_submit(xorriso, 0, victim, 0, "ERRFILE", 0);
816
sev_text_pt= min_severity;
817
Xorriso__text_to_sev(min_severity, &min_sev, 0);
818
if(min_sev < iso_sev && !(flag&4))
819
Xorriso__sev_to_text(iso_sev, &sev_text_pt, 0);
820
strcpy(sfe, msg_text_pt);
823
Text_shellsafe(victim, sfe+strlen(sfe), 0);
825
ret= Xorriso_msgs_submit(xorriso, error_code, sfe, os_errno, sev_text_pt, 4);
830
/* @param flag bit0= suppress messages below UPDATE
831
bit1= suppress messages below FAILURE
833
int Xorriso_set_image_severities(struct XorrisO *xorriso, int flag)
835
char *queue_sev, *print_sev;
838
queue_sev= "FAILURE";
843
if(xorriso->library_msg_direct_print)
844
print_sev= xorriso->report_about_text;
847
iso_set_msgs_severities(queue_sev, print_sev, "libisofs : ");
852
int Xorriso_update_volid(struct XorrisO *xorriso, int flag)
856
gret= Xorriso_get_volid(xorriso, xorriso->loaded_volid, 0);
857
if(gret<=0 || (!xorriso->volid_default) || xorriso->loaded_volid[0]==0)
858
sret= Xorriso_set_volid(xorriso, xorriso->volid, 1);
859
return(gret>0 && sret>0);
863
int Xorriso_create_empty_iso(struct XorrisO *xorriso, int flag)
867
struct isoburn_read_opts *ropts;
868
struct burn_drive_info *dinfo= NULL;
869
struct burn_drive *drive= NULL;
871
if(xorriso->out_drive_handle != NULL) {
872
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
873
"on attempt to attach volset to drive", 2);
877
if(xorriso->in_volset_handle!=NULL) {
878
iso_image_unref((IsoImage *) xorriso->in_volset_handle);
879
xorriso->in_volset_handle= NULL;
880
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
881
Xorriso_destroy_di_array(xorriso, 0);
882
Xorriso_destroy_hln_array(xorriso, 0);
883
xorriso->loaded_volid[0]= 0;
884
xorriso->volset_change_pending= 0;
885
xorriso->no_volset_present= 0;
888
ret= isoburn_ropt_new(&ropts, 0);
891
/* Note: no return before isoburn_ropt_destroy() */
892
isoburn_ropt_set_extensions(ropts, isoburn_ropt_pretend_blank);
893
isoburn_ropt_set_input_charset(ropts, xorriso->in_charset);
894
isoburn_set_read_pacifier(drive, NULL, NULL);
895
ret= isoburn_read_image(drive, ropts, &volset);
896
Xorriso_process_msg_queues(xorriso,0);
897
isoburn_ropt_destroy(&ropts, 0);
899
sprintf(xorriso->info_text, "Failed to create new empty ISO image object");
900
Xorriso_report_iso_error(xorriso, "", ret, xorriso->info_text, 0, "FATAL",
904
xorriso->in_volset_handle= (void *) volset;
905
xorriso->in_sector_map= NULL;
906
Xorriso_update_volid(xorriso, 0);
907
xorriso->volset_change_pending= 0;
908
xorriso->no_volset_present= 0;
913
int Xorriso_record_boot_info(struct XorrisO *xorriso, int flag)
916
struct burn_drive_info *dinfo;
917
struct burn_drive *drive;
919
ElToritoBootImage *bootimg;
920
IsoFile *bootimg_node;
921
IsoBoot *bootcat_node;
923
xorriso->loaded_boot_bin_lba= -1;
924
xorriso->loaded_boot_cat_path[0]= 0;
925
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
926
"on attempt to record boot LBAs", 0);
929
image= isoburn_get_attached_image(drive);
932
ret= iso_image_get_boot_image(image, &bootimg,
933
&bootimg_node, &bootcat_node);
934
iso_image_unref(image); /* release obtained reference */
937
if(bootimg_node != NULL)
938
Xorriso__file_start_lba((IsoNode *) bootimg_node,
939
&(xorriso->loaded_boot_bin_lba), 0);
940
if(bootcat_node != NULL)
941
Xorriso_path_from_lba(xorriso, (IsoNode *) bootcat_node, 0,
942
xorriso->loaded_boot_cat_path, 0);
947
int Xorriso_assert_volid(struct XorrisO *xorriso, int msc1, int flag)
949
int ret, image_blocks;
951
struct burn_drive_info *dinfo;
952
struct burn_drive *drive;
954
if(xorriso->assert_volid[0] == 0)
956
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
957
"on attempt to perform -assert_volid", 0);
960
ret= isoburn_read_iso_head(drive, msc1, &image_blocks, volid, 1);
961
Xorriso_process_msg_queues(xorriso,0);
963
sprintf(xorriso->info_text,
964
"-assert_volid: Cannot determine Volume Id at LBA %d.", msc1);
965
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
966
xorriso->assert_volid_sev, 0);
969
ret= Sregex_match(xorriso->assert_volid, volid, 0);
973
strcpy(xorriso->info_text,
974
"-assert_volid: Volume id does not match pattern: ");
975
Text_shellsafe(xorriso->assert_volid, xorriso->info_text, 1);
976
strcat(xorriso->info_text, " <> ");
977
Text_shellsafe(volid, xorriso->info_text, 1);
978
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
979
xorriso->assert_volid_sev, 0);
986
/* @param flag bit0= aquire as isoburn input drive
987
bit1= aquire as libburn output drive (as isoburn drive if bit0)
988
bit2= regard overwriteable media as blank
989
bit3= if the drive is a regular disk file: truncate it to
990
the write start address
991
bit5= do not print toc
992
bit6= do not calm down drive after aquiring it
993
@return <=0 failure , 1= ok
994
2=success, but not writeable with bit1
995
3=success, but not blank and not ISO with bit0
997
int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag)
999
int ret, hret, not_writeable= 0, has_what, aquire_flag, load_lba, ext;
1000
int lba, track, session, params_flag, adr_mode, read_ret;
1002
struct burn_drive_info *dinfo= NULL, *out_dinfo, *in_dinfo;
1003
struct burn_drive *drive= NULL, *out_drive, *in_drive;
1004
enum burn_disc_status state;
1005
IsoImage *volset = NULL;
1007
struct isoburn_read_opts *ropts= NULL;
1008
char libburn_adr[SfileadrL], *boot_fate, *sev;
1009
size_t value_length;
1012
char volid[33], adr_data[163], *adr_pt;
1015
sprintf(xorriso->info_text,
1016
"XORRISOBURN program error : Xorriso_aquire_drive bit0+bit1 not set");
1017
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
1020
ret= Xorriso_give_up_drive(xorriso, (flag&3)|8);
1024
xorriso->isofs_st_out= time(0) - 1;
1026
ret= Xorriso_auto_driveadr(xorriso, adr, libburn_adr, 0);
1029
if(strcmp(libburn_adr,"stdio:/dev/fd/1")==0) {
1030
if(xorriso->dev_fd_1<0) {
1031
sprintf(xorriso->info_text,
1032
"-*dev \"stdio:/dev/fd/1\" was not a start argument. Cannot use it now.");
1033
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1036
sprintf(libburn_adr, "stdio:/dev/fd/%d", xorriso->dev_fd_1);
1040
if((flag&3)==1 && xorriso->out_drive_handle!=NULL) {
1041
ret= Xorriso_get_drive_handles(xorriso, &out_dinfo, &out_drive,
1042
"on attempt to compare new indev with outdev", 2);
1045
ret= burn_drive_equals_adr(out_drive, libburn_adr, 1);
1048
xorriso->indev_is_exclusive= xorriso->outdev_is_exclusive;
1050
} else if((flag&3)==2 && xorriso->in_drive_handle!=NULL) {
1051
ret= Xorriso_get_drive_handles(xorriso, &in_dinfo, &in_drive,
1052
"on attempt to compare new outdev with indev", 0);
1055
ret= burn_drive_equals_adr(in_drive, libburn_adr, 1);
1058
xorriso->outdev_is_exclusive= xorriso->indev_is_exclusive;
1063
aquire_flag= 1 | ((flag&(8|4))>>1) | ((xorriso->toc_emulation_flag & 3)<<3);
1064
if(xorriso->toc_emulation_flag & 4)
1066
if(!(xorriso->do_aaip & 1))
1068
if((xorriso->ino_behavior & (1 | 2)) && !(xorriso->do_aaip & (4 | 32)))
1070
burn_preset_device_open(xorriso->drives_exclusive, 0, 0);
1071
ret= isoburn_drive_aquire(&dinfo, libburn_adr, aquire_flag);
1072
burn_preset_device_open(1, 0, 0);
1073
Xorriso_process_msg_queues(xorriso,0);
1075
sprintf(xorriso->info_text,"Cannot aquire drive '%s'", adr);
1076
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1080
if(xorriso->image_start_mode&(1<<31)) /* used up setting */
1081
xorriso->image_start_mode= 0; /* no need to perform auto setting */
1083
xorriso->indev_is_exclusive= xorriso->drives_exclusive;
1085
xorriso->outdev_is_exclusive= xorriso->drives_exclusive;
1087
drive= dinfo[0].drive;
1089
if(xorriso->image_start_mode&(1<<31)) /* used up setting */
1090
xorriso->image_start_mode&= ~0xffff; /* perform auto setting */
1091
if((xorriso->image_start_mode&(1<<30))) { /* if enabled at all */
1092
adr_pt= xorriso->image_start_value;
1093
adr_mode= xorriso->image_start_mode & 0xffff;
1094
if(adr_mode == 4 && strlen(adr_pt) <= 80) {
1095
/* Convert volid search expression into lba */
1097
ret= Xorriso__bourne_to_reg(xorriso->image_start_value, adr_data, 0);
1100
ret= isoburn_get_mount_params(drive, 4, adr_data, &lba, &track,
1101
&session, volid, params_flag);
1102
Xorriso_process_msg_queues(xorriso,0);
1105
if(session <= 0 || track <= 0 || ret == 2) {
1106
Xorriso_msgs_submit(xorriso, 0,
1107
"-load : Given address does not point to an ISO 9660 session",
1111
sprintf(volid, "%d", lba);
1115
ret= isoburn_set_msc1(drive, adr_mode, adr_pt,
1116
!!(xorriso->image_start_mode & (1<<16)));
1119
if(xorriso->image_start_mode&(1<<31))
1120
xorriso->image_start_mode= 0; /* disable msc1 setting completely */
1122
xorriso->image_start_mode|= (1<<31); /* mark as used up */
1125
state= isoburn_disc_get_status(drive);
1126
Xorriso_process_msg_queues(xorriso,0);
1128
volset= isoburn_get_attached_image(drive);
1129
if(volset != NULL) { /* The image object is already created */
1130
iso_image_unref(volset);
1135
xorriso->out_drive_handle= dinfo;
1136
if(Sfile_str(xorriso->outdev, adr, 0)<=0)
1138
if(state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE) {
1139
sprintf(xorriso->info_text, "Disc status unsuitable for writing");
1140
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1145
xorriso->in_drive_handle= dinfo;
1146
if(Sfile_str(xorriso->indev, adr, 0)<=0)
1149
if(xorriso->in_volset_handle==NULL) {
1150
/* No volume loaded: create empty one */
1151
ret= Xorriso_create_empty_iso(xorriso, 0);
1155
iso_image_ref((IsoImage *) xorriso->in_volset_handle);
1156
ret= isoburn_attach_image(drive, (IsoImage *) xorriso->in_volset_handle);
1158
sprintf(xorriso->info_text,
1159
"Failed to attach ISO image object to outdev");
1160
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
1165
Xorriso_toc(xorriso, 1 | 2 | 8);
1166
{ret= 1+not_writeable; goto ex;}
1169
if(xorriso->in_volset_handle!=NULL)
1170
iso_image_unref((IsoImage *) xorriso->in_volset_handle);
1171
xorriso->in_volset_handle= NULL;
1172
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
1173
Xorriso_destroy_hln_array(xorriso, 0);
1174
Xorriso_destroy_di_array(xorriso, 0);
1176
/* check for invalid state */
1177
if(state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE &&
1178
state != BURN_DISC_FULL) {
1179
sprintf(xorriso->info_text,
1180
"Disc status not blank and unsuitable for reading");
1182
if(xorriso->img_read_error_mode==2)
1184
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, sev, 0);
1185
Xorriso_give_up_drive(xorriso, 1|((flag&32)>>2));
1188
/* fill read opts */
1189
ret= isoburn_ropt_new(&ropts, 0);
1193
ext= isoburn_ropt_noiso1999;
1194
if((xorriso->ino_behavior & (1 | 2)) && !(xorriso->do_aaip & (1 | 4 | 32))
1195
&& !(xorriso->do_md5 & 1))
1196
ext|= isoburn_ropt_noaaip;
1197
if(!(xorriso->do_aaip & 1))
1198
ext|= isoburn_ropt_noacl;
1199
if(!(xorriso->do_aaip & 4))
1200
ext|= isoburn_ropt_noea;
1201
if(xorriso->ino_behavior & 1)
1202
ext|= isoburn_ropt_noino;
1204
#ifdef isoburn_ropt_nomd5
1205
if(!(xorriso->do_md5 & 1))
1206
ext|= isoburn_ropt_nomd5;
1209
isoburn_ropt_set_extensions(ropts, ext);
1211
isoburn_ropt_set_default_perms(ropts, (uid_t) 0, (gid_t) 0, (mode_t) 0555);
1212
isoburn_ropt_set_input_charset(ropts, xorriso->in_charset);
1213
isoburn_ropt_set_auto_incharset(ropts, !!(xorriso->do_aaip & 512));
1215
Xorriso_set_image_severities(xorriso, 1); /* No DEBUG messages */
1216
Xorriso_pacifier_reset(xorriso, 0);
1217
isoburn_set_read_pacifier(drive, Xorriso__read_pacifier, (void *) xorriso);
1219
/* <<< Trying to work around too much tolerance on bad image trees.
1220
Better would be a chance to instruct libisofs what to do in
1221
case of image read errors. There is a risk to mistake other SORRYs.
1223
if(xorriso->img_read_error_mode>0)
1224
iso_set_abort_severity("SORRY");
1226
if(state != BURN_DISC_BLANK) {
1227
ret= isoburn_disc_get_msc1(drive, &load_lba);
1229
sprintf(xorriso->info_text,
1230
"Loading ISO image tree from LBA %d", load_lba);
1231
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1233
ret= Xorriso_assert_volid(xorriso, load_lba, 0);
1238
read_ret= ret= isoburn_read_image(drive, ropts, &volset);
1240
/* <<< Resetting to normal thresholds */
1241
if(xorriso->img_read_error_mode>0)
1242
Xorriso_set_abort_severity(xorriso, 0);
1245
Xorriso_process_msg_queues(xorriso,0);
1246
Xorriso_set_image_severities(xorriso, 0);
1247
Xorriso_give_up_drive(xorriso, 1|((flag&32)>>2));
1248
sprintf(xorriso->info_text,"Cannot read ISO image tree");
1250
if(xorriso->img_read_error_mode==2)
1252
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, sev, 0);
1253
if(read_ret == ISO_SB_TREE_CORRUPTED && (xorriso->do_md5 & 1)) {
1254
Xorriso_msgs_submit(xorriso, 0,
1255
"You might get a questionable ISO image tree by option -md5 'off'.",
1257
} else if(xorriso->img_read_error_mode!=0) {
1258
Xorriso_msgs_submit(xorriso, 0, "You might get a partial or altered ISO image tree by option -error_behavior 'image_loading' 'best_effort' if -abort_on is set to be tolerant enough.",
1265
Xorriso_pacifier_callback(xorriso, "nodes read", xorriso->pacifier_count, 0,
1266
"", 1); /* report end count */
1267
xorriso->in_volset_handle= (void *) volset;
1268
xorriso->in_sector_map= NULL;
1269
Xorriso_set_image_severities(xorriso, 0);
1271
Xorriso_update_volid(xorriso, 0);
1272
strncpy(xorriso->application_id,
1273
un0(iso_image_get_application_id(volset)), 128);
1274
xorriso->application_id[128]= 0;
1275
strncpy(xorriso->publisher, un0(iso_image_get_publisher_id(volset)), 128);
1276
xorriso->publisher[128]= 0;
1277
strncpy(xorriso->system_id, un0(iso_image_get_system_id(volset)), 32);
1278
xorriso->system_id[32]= 0;
1279
strncpy(xorriso->volset_id, un0(iso_image_get_volset_id(volset)), 128);
1280
xorriso->volset_id[128]= 0;
1282
/* <<< can be removed as soon as libisofs-0.6.24 is mandatory
1284
if(strcmp(un0(iso_image_get_copyright_file_id(volset)), "_") == 0 &&
1285
strcmp(un0(iso_image_get_abstract_file_id(volset)), "_") == 0 &&
1286
strcmp(un0(iso_image_get_biblio_file_id(volset)), "_") == 0) {
1287
/* This is bug output from libisofs <= 0.6.23 . The texts mean file names
1288
and should have been empty to indicate that there are no such files.
1289
It is obvious that not all three roles can be fulfilled by one file "_"
1290
so that one cannot spoil anything by assuming them empty now.
1291
Modern versions of libisofs are supposed to do this themselves.
1293
iso_image_set_copyright_file_id(volset, "");
1294
iso_image_set_abstract_file_id(volset, "");
1295
iso_image_set_biblio_file_id(volset, "");
1298
if(xorriso->out_drive_handle != NULL &&
1299
xorriso->out_drive_handle != xorriso->in_drive_handle) {
1300
ret= Xorriso_get_drive_handles(xorriso, &out_dinfo, &out_drive,
1301
"on attempt to attach ISO image volset to outdev", 2);
1304
iso_image_ref((IsoImage *) xorriso->in_volset_handle);
1305
isoburn_attach_image(out_drive, xorriso->in_volset_handle);
1307
Xorriso_process_msg_queues(xorriso,0);
1308
isoburn_ropt_get_size_what(ropts, &size, &has_what);
1309
if(has_what & isoburn_ropt_has_el_torito) {
1310
if(xorriso->boot_image_bin_path[0])
1311
boot_fate= "replaced by new boot image";
1312
else if(xorriso->patch_isolinux_image & 1)
1313
boot_fate= "patched at boot info table";
1314
else if(xorriso->keep_boot_image)
1315
boot_fate= "kept unchanged";
1317
boot_fate= "discarded";
1318
sprintf(xorriso->info_text,
1319
"Detected El-Torito boot information which currently is set to be %s",
1321
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1322
Xorriso_record_boot_info(xorriso, 0);
1326
/* Look for isofs.st and put it into xorriso->isofs_st_in */;
1327
root_node= (IsoNode *) iso_image_get_root(volset);
1328
ret= iso_node_lookup_attr(root_node, "isofs.st", &value_length, &value, 0);
1330
if(value_length > 0) {
1331
sscanf(value, "%lf", &num);
1333
xorriso->isofs_st_in= num;
1340
Xorriso_toc(xorriso, 1 | 8);
1341
if(xorriso->loaded_volid[0]!=0) {
1342
sprintf(xorriso->info_text,"Volume id : '%s'\n",
1343
xorriso->loaded_volid);
1344
Xorriso_info(xorriso, 0);
1345
if(strcmp(xorriso->loaded_volid, xorriso->volid) != 0 &&
1346
!xorriso->volid_default) {
1347
sprintf(xorriso->info_text, "New volume id: '%s'\n", xorriso->volid);
1348
Xorriso_info(xorriso, 0);
1353
ret= 1+not_writeable;
1355
Xorriso_process_msg_queues(xorriso,0);
1357
hret= Xorriso_give_up_drive(xorriso, (flag&3)|((flag&32)>>2));
1361
if(drive != NULL && (xorriso->do_calm_drive & 1) && !(flag & 64))
1362
burn_drive_snooze(drive, 0); /* No need to make noise from start */
1365
isoburn_ropt_destroy(&ropts, 0);
1370
/* @param flag bit0=input drive
1373
bit3=no info message or toc
1375
int Xorriso_give_up_drive(struct XorrisO *xorriso, int flag)
1377
int in_is_out_too, ret, do_eject;
1378
struct burn_drive_info *dinfo;
1379
struct burn_drive *drive;
1380
char sfe[5*SfileadrL];
1382
in_is_out_too= (xorriso->in_drive_handle == xorriso->out_drive_handle);
1383
if((flag&4) && in_is_out_too && (flag&(1|2))) {
1385
sprintf(xorriso->info_text,"Giving up for -eject whole -dev %s",
1386
Text_shellsafe(xorriso->indev, sfe, 0));
1387
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1389
flag|= 3; /* give up in/out drive to eject it */
1392
if((flag&1) && xorriso->in_drive_handle != NULL) {
1393
Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
1394
"on attempt to give up drive", 0);
1396
if(!in_is_out_too) {
1397
do_eject= !!(flag&4);
1398
if((flag & 4) && !xorriso->indev_is_exclusive) {
1399
sprintf(xorriso->info_text,
1400
"Will not eject media in non-exclusively aquired input drive.");
1401
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
1405
isoburn_drive_release(drive, do_eject);
1407
burn_drive_info_free(dinfo);
1409
xorriso->in_drive_handle= NULL;
1410
xorriso->indev[0]= 0;
1412
if(xorriso->in_volset_handle!=NULL)
1413
iso_image_unref((IsoImage *) xorriso->in_volset_handle);
1414
xorriso->in_volset_handle= NULL;
1415
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
1416
Xorriso_destroy_di_array(xorriso, 0);
1417
Xorriso_destroy_hln_array(xorriso, 0);
1418
xorriso->loaded_volid[0]= 0;
1419
xorriso->isofs_st_out= time(0) - 1;
1420
xorriso->isofs_st_in= 0;
1421
xorriso->volset_change_pending= 0;
1422
xorriso->no_volset_present= 0;
1423
xorriso->loaded_boot_bin_lba= 0;
1424
xorriso->loaded_boot_cat_path[0]= 0;
1425
xorriso->boot_count= 0;
1428
if((flag&2) && xorriso->out_drive_handle!=NULL) {
1429
do_eject= !!(flag&4);
1430
if((flag & 4) && !xorriso->outdev_is_exclusive) {
1431
sprintf(xorriso->info_text,
1432
"Will not eject media in non-exclusively aquired drive.");
1433
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
1436
Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
1437
"on attempt to give up drive", 2);
1438
if(!in_is_out_too) {
1440
isoburn_drive_release(drive, do_eject);
1442
burn_drive_info_free(dinfo);
1444
xorriso->out_drive_handle= NULL;
1445
xorriso->outdev[0]= 0;
1446
} else if((flag&1) && xorriso->out_drive_handle!=NULL) {
1447
ret= Xorriso_create_empty_iso(xorriso, 0);
1451
sprintf(xorriso->info_text,
1452
"Only the output drive remains. Created empty ISO image.\n");
1453
Xorriso_info(xorriso, 0);
1454
Xorriso_toc(xorriso, 1 | 2 | 8);
1457
Xorriso_process_msg_queues(xorriso,0);
1462
int Xorriso_make_write_options(
1463
struct XorrisO *xorriso, struct burn_drive *drive,
1464
struct burn_write_opts **burn_options, int flag)
1466
int drive_role, stream_mode= 0;
1468
*burn_options= burn_write_opts_new(drive);
1469
if(*burn_options==NULL) {
1470
Xorriso_process_msg_queues(xorriso,0);
1471
sprintf(xorriso->info_text,"Cannot allocate option set");
1472
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1475
burn_write_opts_set_simulate(*burn_options, !!xorriso->do_dummy);
1476
drive_role= burn_drive_get_drive_role(drive);
1477
burn_write_opts_set_multi(*burn_options,
1478
!(xorriso->do_close || drive_role==0 || drive_role==3));
1479
burn_drive_set_speed(drive, xorriso->speed, xorriso->speed);
1480
if(xorriso->do_stream_recording == 1)
1482
else if(xorriso->do_stream_recording == 2)
1483
stream_mode= 51200; /* 100 MB */
1484
else if(xorriso->do_stream_recording >= 16)
1485
stream_mode= xorriso->do_stream_recording;
1486
burn_write_opts_set_stream_recording(*burn_options, stream_mode);
1488
#ifdef Xorriso_dvd_obs_default_64K
1489
if(xorriso->dvd_obs == 0)
1490
burn_write_opts_set_dvd_obs(*burn_options, 64 * 1024);
1493
burn_write_opts_set_dvd_obs(*burn_options, xorriso->dvd_obs);
1495
burn_write_opts_set_stdio_fsync(*burn_options, xorriso->stdio_sync);
1496
burn_write_opts_set_underrun_proof(*burn_options, 1);
1501
/* @param flag bit0= do not write but only prepare and return size in sectors
1502
bit1= do not use isoburn wrappers
1504
int Xorriso_sanitize_image_size(struct XorrisO *xorriso,
1505
struct burn_drive *drive, struct burn_disc *disc,
1506
struct burn_write_opts *burn_options, int flag)
1508
int ret, img_sectors, num_sessions= 0, num_tracks= 0, padding= 0, profile;
1509
int media_space, lba, nwa;
1510
char profile_name[80];
1511
struct burn_session **sessions;
1512
struct burn_track **tracks;
1514
img_sectors= burn_disc_get_sectors(disc);
1516
sessions= burn_disc_get_sessions(disc, &num_sessions);
1517
if(sessions==NULL || num_sessions < 1) {
1519
Xorriso_process_msg_queues(xorriso,0);
1520
sprintf(xorriso->info_text,"Program error : no track in prepared disc");
1521
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
1524
tracks= burn_session_get_tracks(sessions[0], &num_tracks);
1525
if(tracks==NULL || num_tracks < 1)
1529
ret= burn_disc_get_profile(drive, &profile, profile_name);
1530
padding= xorriso->padding / 2048;
1531
if(xorriso->padding > padding * 2048)
1533
if(img_sectors>0 && ret>0 &&
1534
(profile==0x09 || profile==0x0a)) { /* CD-R , CD-RW */
1535
if(img_sectors + padding < Xorriso_cd_min_track_sizE) {
1536
padding= Xorriso_cd_min_track_sizE - img_sectors;
1537
sprintf(xorriso->info_text,
1538
"Expanded track to minimum size of %d sectors",
1539
Xorriso_cd_min_track_sizE);
1540
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1543
if(xorriso->alignment == 0) {
1544
ret= isoburn_needs_emulation(drive);
1546
/* Take care that the session is padded up to the future NWA.
1547
Else with padding < 32 it could happen that PVDs from older
1548
sessions survive and confuse -rom_toc_scan.
1550
xorriso->alignment= 32;
1553
if(xorriso->alignment > 0) {
1554
if(img_sectors > 0) {
1555
ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &lba, &nwa);
1558
lba= (nwa + img_sectors + padding) % xorriso->alignment;
1560
padding+= xorriso->alignment - lba;
1561
} else if(padding < xorriso->alignment)
1562
padding= xorriso->alignment;
1564
burn_track_define_data(tracks[0], 0, padding * 2048, 0, BURN_MODE1);
1565
Xorriso_process_msg_queues(xorriso,0);
1568
media_space= burn_disc_available_space(drive, burn_options) /
1571
media_space= isoburn_disc_available_space(drive, burn_options) /
1573
if(media_space < img_sectors + padding) {
1574
Xorriso_process_msg_queues(xorriso,0);
1575
sprintf(xorriso->info_text,"Image size %ds exceeds free space on media %ds",
1576
img_sectors + padding, media_space);
1577
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1581
ret= img_sectors+padding;
1589
/* @return <0 yes , 0 no , <0 error */
1590
int Xorriso_is_isohybrid(struct XorrisO *xorriso, IsoFile *bootimg_node,
1594
unsigned char buf[68];
1595
void *data_stream= NULL;
1597
ret= Xorriso_iso_file_open(xorriso, "", (void *) bootimg_node,
1601
ret= Xorriso_iso_file_read(xorriso, data_stream, (char *) buf, 68, 0);
1602
Xorriso_iso_file_close(xorriso, &data_stream, 0);
1605
if(buf[64] == 0xfb && buf[65] == 0xc0 && buf[66] == 0x78 && buf[67] == 0x70)
1611
/* @param flag bit0= operating on newly attached boot image
1613
int Xorriso_set_isolinux_options(struct XorrisO *xorriso,
1614
IsoImage *image, int flag)
1616
int make_isohybrid_mbr= 0, ret, patch_table= 0, num_boots, i;
1617
ElToritoBootImage *bootimg, **boots = NULL;
1618
IsoFile *bootimg_node, **bootnodes = NULL;
1620
ret= iso_image_get_boot_image(image, &bootimg, &bootimg_node, NULL);
1621
Xorriso_process_msg_queues(xorriso,0);
1623
sprintf(xorriso->info_text, "Programming error: No boot image available in Xorriso_set_isolinux_options()");
1624
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
1627
ret= iso_image_get_all_boot_imgs(image, &num_boots, &boots, &bootnodes, 0);
1628
Xorriso_process_msg_queues(xorriso,0);
1630
Xorriso_report_iso_error(xorriso, "", ret, "Cannot inquire boot images", 0,
1634
patch_table= xorriso->patch_isolinux_image & 1;
1635
if((flag & 1) && num_boots > 1) {
1636
ret= el_torito_set_isolinux_options(boots[num_boots - 1], patch_table, 0);
1637
ret= (ret == 1); goto ex;
1640
/* Handle patching of first attached boot image or of imported boot images
1642
for(i= 0; i < num_boots; i++) {
1643
patch_table = xorriso->patch_isolinux_image & 1;
1644
if(patch_table && !(flag & 1)) {
1645
if(!el_torito_seems_boot_info_table(boots[i], 0))
1647
else if((xorriso->patch_isolinux_image & 2) &&
1648
el_torito_get_boot_platform_id(boots[i]) == 0xef)
1651
if(i > 0 || xorriso->boot_image_isohybrid == 0) {
1652
ret= el_torito_set_isolinux_options(boots[i], patch_table, 0);
1657
if(xorriso->boot_image_isohybrid == 3) {
1658
make_isohybrid_mbr= 1;
1660
ret= Xorriso_is_isohybrid(xorriso, bootimg_node, 0);
1664
make_isohybrid_mbr= 1;
1667
if(xorriso->boot_image_isohybrid == 2 && !make_isohybrid_mbr) {
1668
sprintf(xorriso->info_text,
1669
"Isohybrid signature is demanded but not found in boot image file.");
1670
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1673
if(make_isohybrid_mbr) {
1674
sprintf(xorriso->info_text, "Will write isohybrid MBR.");
1675
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1676
xorriso->alignment= 512;
1678
ret= el_torito_set_isolinux_options(bootimg,
1679
patch_table | (make_isohybrid_mbr << 1),0);
1684
Xorriso_process_msg_queues(xorriso,0);
1687
if(bootnodes != NULL)
1693
int Xorriso_auto_format(struct XorrisO *xorriso, int flag)
1695
int ret, profile, status, num_formats;
1696
char profile_name[80];
1697
struct burn_drive_info *dinfo;
1698
struct burn_drive *drive;
1702
ret= Xorriso_may_burn(xorriso, 0);
1706
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
1707
"on attempt to autoformat", 2);
1710
ret= burn_disc_get_profile(drive, &profile, profile_name);
1711
if(ret>0 && (profile==0x12 || profile==0x43)) { /* DVD-RAM or BD-RE */
1712
ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats);
1713
if(ret>0 && status==BURN_FORMAT_IS_UNFORMATTED) {
1714
sprintf(xorriso->info_text,
1715
"Unformatted %s media detected. Trying -format fast.",
1717
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1718
ret= Xorriso_format_media(xorriso, (off_t) 0, 1 | 4);
1720
sprintf(xorriso->info_text, "Automatic formatting of %s failed",
1722
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1731
int Xorriso_set_system_area(struct XorrisO *xorriso, struct burn_drive *drive,
1732
IsoImage *img, struct isoburn_imgen_opts *sopts,
1735
int ret, options, system_area_options, iso_lba= -1, start_lba, image_blocks;
1738
char buf[32768], *bufpt= NULL;
1741
ElToritoBootImage *bootimg;
1742
IsoFile *bootimg_node;
1744
system_area_options= xorriso->system_area_options;
1745
memset(buf, 0, 32768);
1746
if(xorriso->system_area_disk_path[0] == 0) {
1747
if(xorriso->patch_system_area) {
1748
ret= iso_image_get_system_area(img, buf, &options, 0);
1751
} else if(ret < 0) {
1752
Xorriso_process_msg_queues(xorriso,0);
1753
Xorriso_report_iso_error(xorriso, "", ret,
1754
"Error when inquiring System Area data of ISO 9660 image",
1758
system_area_options= xorriso->patch_system_area;
1759
/* Check whether partition 1 ends at image end */;
1760
ub= (unsigned char *) buf;
1761
hd_lba= (ub[454] | (ub[455] << 8) | (ub[456] << 16) | (ub[457] << 24)) +
1762
(ub[458] | (ub[459] << 8) | (ub[460] << 16) | (ub[461] << 24));
1765
ret= isoburn_disc_get_msc1(drive, &start_lba);
1767
ret= isoburn_read_iso_head(drive, start_lba, &image_blocks,
1770
iso_lba= start_lba + image_blocks;
1772
if(((off_t) iso_lba) * (off_t) 4 > hd_lba) {
1773
system_area_options= 0;
1774
} else if((xorriso->patch_system_area & 1) &&
1775
((off_t) iso_lba) * (off_t) 4 != hd_lba) {
1776
system_area_options= 0;
1777
} else if((xorriso->patch_system_area & 2) &&
1778
((off_t) iso_lba) * (off_t) 4 + (off_t) (63 * 256) < hd_lba) {
1779
system_area_options= 0;
1780
} else if(xorriso->patch_system_area & 2) { /* isohybrid patching */
1781
/* Check whether bytes 432-345 point to ElTorito LBA */
1782
hd_lba= ub[432] | (ub[433] << 8) | (ub[434] << 16) | (ub[435] << 24);
1783
ret= iso_image_get_boot_image(img, &bootimg, &bootimg_node, NULL);
1785
system_area_options= 0;
1786
else if(bootimg_node != NULL) {
1787
Xorriso__file_start_lba((IsoNode *) bootimg_node, &(iso_lba), 0);
1788
if(((off_t) iso_lba) * (off_t) 4 != hd_lba)
1789
system_area_options= 0;
1792
if(system_area_options == 0) {
1793
Xorriso_msgs_submit(xorriso, 0,
1794
"Loaded System Area data are not suitable for MBR patching.",
1804
if(strcmp(xorriso->system_area_disk_path, "/dev/zero") == 0)
1805
{ret= 1; goto do_set;}
1807
ret= Xorriso_afile_fopen(xorriso, xorriso->system_area_disk_path,
1811
ret= fread(buf, 1, 32768, fp);
1814
sprintf(xorriso->info_text,
1815
"Error when reading -boot_image system_area=");
1816
Text_shellsafe(xorriso->system_area_disk_path, xorriso->info_text, 1);
1817
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
1824
if(ret > 0 && xorriso->system_area_disk_path[0]) {
1825
sprintf(xorriso->info_text, "Copying to System Area: %d bytes from file ",
1827
Text_shellsafe(xorriso->system_area_disk_path, xorriso->info_text, 1);
1828
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1830
ret= isoburn_igopt_set_system_area(sopts, bufpt, system_area_options);
1831
if(ret != ISO_SUCCESS) {
1832
Xorriso_process_msg_queues(xorriso,0);
1833
Xorriso_report_iso_error(xorriso, "", ret,
1834
"Error when attaching System Area data to ISO 9660 image",
1840
if(fp != NULL && fp != stdin)
1847
bit0= do only report non-default settings
1848
bit1= do only report to fp
1850
bit3= append -boot_image any next
1851
bit4= eventually concentrate boot options
1853
int Xorriso_boot_item_status(struct XorrisO *xorriso, char *cat_path,
1854
char *bin_path, int platform_id,
1855
int patch_isolinux, int emul, off_t load_size,
1856
unsigned char *id_string,
1857
unsigned char *selection_crit, char *form,
1858
char *filter, FILE *fp, int flag)
1860
int is_default, no_defaults, i, is_default_id= 0, ret;
1861
char *line, bspec[SfileadrL + 80], zeros[28];
1865
no_defaults= flag & 1;
1866
line= xorriso->result_line;
1869
/* Allow to concentrate boot options. */
1870
memset(zeros, 0, 28);
1871
if(memcmp(id_string, zeros, 28) == 0 &&
1872
memcmp(selection_crit, zeros, 20) == 0)
1875
/* -boot_image isolinux dir= ... */
1877
if(strcmp(form, "isolinux") != 0 && strcmp(form, "any") != 0)
1879
else if(strcmp(bin_path, "/isolinux.bin") == 0 &&
1880
strcmp(cat_path, "/boot.cat") == 0)
1881
strcpy(bspec, "dir=/");
1882
else if(strcmp(bin_path, "/isolinux/isolinux.bin") == 0 &&
1883
strcmp(cat_path, "/isolinux/boot.cat") == 0)
1884
strcpy(bspec, "dir=/isolinux");
1885
else if(strcmp(xorriso->boot_image_bin_path,
1886
"/boot/isolinux/isolinux.bin") == 0
1887
&& strcmp(xorriso->boot_image_cat_path,
1888
"/boot/isolinux/boot.cat") == 0)
1889
strcpy(bspec, "dir=/boot/isolinux");
1890
memset(zeros, 0, 28);
1891
if(bspec[0] && platform_id == 0 && patch_isolinux &&
1892
load_size == 2048 && is_default_id) {
1893
sprintf(line, "-boot_image isolinux %s\n", bspec);
1894
Xorriso_status_result(xorriso,filter,fp,flag&2);
1899
ret= Xorriso_iso_lstat(xorriso, bin_path, &stbuf, 2 | 4);
1901
file_size= ((stbuf.st_size / (off_t) 512) +
1902
!!(stbuf.st_size % (off_t) 512)) * 512;
1903
if(platform_id == 0xef && !patch_isolinux &&
1904
load_size == file_size && is_default_id) {
1905
sprintf(line, "-boot_image any efi_path=");
1906
Text_shellsafe(bin_path, line, 1);
1908
Xorriso_status_result(xorriso,filter,fp,flag&2);
1913
is_default= (bin_path[0] == 0) || (flag & 4);
1914
sprintf(line, "-boot_image %s bin_path=", form);
1915
Text_shellsafe(bin_path, line, 1);
1917
if(!(is_default && no_defaults))
1918
Xorriso_status_result(xorriso,filter,fp,flag&2);
1920
is_default= (platform_id == 0 || (flag & 4));
1921
sprintf(line, "-boot_image %s platform_id=0x%-2.2x\n", form, platform_id);
1922
if(!(is_default && no_defaults))
1923
Xorriso_status_result(xorriso,filter,fp,flag&2);
1925
is_default= ((patch_isolinux & 1) == 0 || bin_path[0] == 0 || (flag & 4));
1926
sprintf(line, "-boot_image %s boot_info_table=%s\n",
1927
(patch_isolinux & 2) ? "grub" : form, patch_isolinux ? "on" : "off");
1928
if(!(is_default && no_defaults))
1929
Xorriso_status_result(xorriso,filter,fp,flag&2);
1931
is_default= (load_size == 2048 || (flag & 4));
1932
sprintf(line, "-boot_image %s load_size=%lu\n",
1933
form, (unsigned long) load_size);
1934
if(!(is_default && no_defaults))
1935
Xorriso_status_result(xorriso,filter,fp,flag&2);
1939
for(i= 0; i < 20; i++)
1940
if(selection_crit[i])
1942
sprintf(line, "-boot_image %s sel_crit=", form);
1943
for(i= 0; i < 20; i++)
1944
sprintf(line + strlen(line), "%-2.2X", (unsigned int) selection_crit[i]);
1946
if(!(is_default && no_defaults))
1947
Xorriso_status_result(xorriso,filter,fp,flag&2);
1951
for(i= 0; i < 28; i++)
1954
sprintf(line, "-boot_image %s id_string=", form);
1955
for(i= 0; i < 28; i++)
1956
sprintf(line + strlen(line), "%-2.2X", (unsigned int) id_string[i]);
1958
if(!(is_default && no_defaults))
1959
Xorriso_status_result(xorriso,filter,fp,flag&2);
1966
bit0= do only report non-default settings
1967
bit1= do only report to fp
1969
int Xorriso_boot_image_status(struct XorrisO *xorriso, char *filter, FILE *fp,
1972
int ret, i, num_boots, hflag;
1973
int bin_path_in_use= 0, is_default, no_defaults;
1974
char sfe[5*SfileadrL], path[SfileadrL], *form= "any", *line;
1975
struct burn_drive_info *dinfo;
1976
struct burn_drive *drive;
1977
IsoImage *image= NULL;
1978
ElToritoBootImage **boots = NULL;
1979
IsoFile **bootnodes = NULL;
1980
int platform_id, patch, load_size;
1981
enum eltorito_boot_media_type media_type;
1982
unsigned char id_string[29], sel_crit[21];
1984
line= xorriso->result_line;
1985
no_defaults= flag & 1;
1987
if(xorriso->boot_count == 0 && xorriso->boot_image_bin_path[0] == 0) {
1988
if(xorriso->patch_isolinux_image & 1) {
1989
sprintf(line, "-boot_image %s patch\n",
1990
xorriso->patch_isolinux_image & 2 ? "grub" : form);
1992
} else if(xorriso->keep_boot_image) {
1993
sprintf(line, "-boot_image %s keep\n", form);
1996
sprintf(line, "-boot_image %s discard\n", form);
1999
if(!(is_default && no_defaults))
2000
Xorriso_status_result(xorriso,filter,fp,flag&2);
2004
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
2005
"on attempt to print boot info", 16);
2008
image= isoburn_get_attached_image(drive);
2009
Xorriso_process_msg_queues(xorriso,0);
2013
if(xorriso->boot_image_bin_path[0] || xorriso->boot_count > 0)
2015
if(xorriso->boot_image_cat_path[0] && bin_path_in_use) {
2017
sprintf(line,"-boot_image %s cat_path=%s\n",
2018
form, Text_shellsafe(xorriso->boot_image_cat_path, sfe, 0));
2019
if(!(is_default && no_defaults))
2020
Xorriso_status_result(xorriso,filter,fp,flag&2);
2023
if(xorriso->boot_count > 0) {
2025
/* show attached boot image info */;
2027
ret= iso_image_get_all_boot_imgs(image, &num_boots, &boots, &bootnodes, 0);
2028
Xorriso_process_msg_queues(xorriso,0);
2029
if(ret == 1 && num_boots > 0) {
2030
for(i= 0; i < num_boots; i++) {
2031
ret= Xorriso_path_from_node(xorriso, (IsoNode *) bootnodes[i], path, 0);
2034
platform_id= el_torito_get_boot_platform_id(boots[i]);
2035
patch= el_torito_get_isolinux_options(boots[i], 0);
2036
el_torito_get_boot_media_type(boots[i], &media_type);
2037
load_size= el_torito_get_load_size(boots[i]) * 512;
2038
el_torito_get_id_string(boots[i], id_string);
2039
el_torito_get_selection_crit(boots[i], sel_crit);
2040
ret= Xorriso_boot_item_status(xorriso, xorriso->boot_image_cat_path,
2041
path, platform_id, patch & 1, media_type,
2042
load_size, id_string, sel_crit, "any",
2043
filter, fp, 16 | (flag & 3));
2046
sprintf(line,"-boot_image %s next\n", form);
2047
Xorriso_status_result(xorriso,filter,fp,flag&2);
2052
/* Show pending boot image info */
2053
if(strcmp(xorriso->boot_image_bin_form, "isolinux") == 0 ||
2054
strcmp(xorriso->boot_image_bin_form, "grub") == 0)
2055
form= xorriso->boot_image_bin_form;
2057
if(xorriso->boot_count > 0 &&
2058
xorriso->boot_platform_id == 0 &&
2059
xorriso->patch_isolinux_image == 0 &&
2060
xorriso->boot_image_bin_path[0] == 0 &&
2061
xorriso->boot_image_emul == 0 &&
2062
xorriso->boot_image_load_size == 4 * 512) {
2063
for(i= 0; i < 20; i++)
2064
if(xorriso->boot_selection_crit[i])
2067
for(i= 0; i < 28; i++)
2068
if(xorriso->boot_id_string[i])
2071
{ret= 1; goto ex;} /* Images registered, pending is still default */
2075
if(xorriso->boot_platform_id == 0xef && !xorriso->boot_efi_default)
2077
ret= Xorriso_boot_item_status(xorriso, xorriso->boot_image_cat_path,
2078
xorriso->boot_image_bin_path, xorriso->boot_platform_id,
2079
xorriso->patch_isolinux_image, xorriso->boot_image_emul,
2080
xorriso->boot_image_load_size, xorriso->boot_id_string,
2081
xorriso->boot_selection_crit, form,
2082
filter, fp, hflag | (flag & 3));
2090
if(bootnodes != NULL)
2096
/* @param flag bit0= do not increment boot_count
2097
and do not reset boot parameters
2098
bit1= dispose attached boot images
2100
int Xorriso_attach_boot_image(struct XorrisO *xorriso, int flag)
2103
char sfe[5*SfileadrL], *cpt;
2104
struct burn_drive_info *source_dinfo;
2105
struct burn_drive *source_drive;
2106
IsoImage *image= NULL;
2108
ElToritoBootImage *bootimg;
2109
enum eltorito_boot_media_type emul_type= ELTORITO_NO_EMUL;
2111
int emul, platform_id;
2116
if(xorriso->boot_image_bin_path[0] == 0 && !(flag & 2)) {
2118
/* >>> no boot image path given : no op */;
2123
if(xorriso->in_drive_handle == NULL)
2125
ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive,
2126
"on attempt to attach boot image", hflag);
2129
image= isoburn_get_attached_image(source_drive);
2131
/* (should not happen) */
2132
sprintf(xorriso->info_text,
2133
"No ISO image present on attempt to attach boot image");
2134
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2138
iso_image_remove_boot_image(image);
2139
xorriso->boot_count= 0;
2143
bin_path= xorriso->boot_image_bin_path;
2144
emul= xorriso->boot_image_emul;
2145
platform_id= xorriso->boot_platform_id;
2146
load_size= xorriso->boot_image_load_size;
2148
if(xorriso->boot_efi_default) {
2151
xorriso->patch_isolinux_image= 0;
2153
if(platform_id == 0xef || load_size < 0) {
2154
ret= Xorriso_iso_lstat(xorriso, bin_path, &stbuf, 2 | 4);
2157
load_size= ((stbuf.st_size / (off_t) 512) +
2158
!!(stbuf.st_size % (off_t) 512)) * 512;
2160
sprintf(xorriso->info_text, "Adding boot image %s",
2161
Text_shellsafe(bin_path, sfe, 0));
2162
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
2165
emul_type= ELTORITO_NO_EMUL;
2167
emul_type= ELTORITO_HARD_DISC_EMUL;
2169
emul_type= ELTORITO_FLOPPY_EMUL;
2171
ret= Xorriso_node_from_path(xorriso, image, bin_path, &node, 1);
2173
sprintf(xorriso->info_text,
2174
"Cannot find in ISO image: -boot_image ... bin_path=%s",
2175
Text_shellsafe(bin_path, sfe, 0));
2176
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2180
if(xorriso->boot_count == 0) {
2181
if(xorriso->boot_image_cat_path[0] == 0) {
2182
strcpy(xorriso->boot_image_cat_path, bin_path);
2183
cpt= strrchr(xorriso->boot_image_cat_path, '/');
2185
cpt= xorriso->boot_image_cat_path;
2188
strcpy(cpt, "boot.cat");
2190
ret= Xorriso_node_from_path(xorriso, image, xorriso->boot_image_cat_path,
2193
if(!xorriso->do_overwrite) {
2194
sprintf(xorriso->info_text,
2195
"May not overwite existing -boot_image ... cat_path=%s",
2196
Text_shellsafe(xorriso->boot_image_cat_path, sfe, 0));
2197
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2200
ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, xorriso->boot_image_cat_path,
2201
8 | (xorriso->do_overwrite == 1));
2203
sprintf(xorriso->info_text,
2204
"Could not remove existing -boot_image cat_path=%s",
2205
Text_shellsafe(xorriso->boot_image_cat_path, sfe, 0));
2206
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2211
/* Discard old boot image, set new one */
2212
ret= iso_image_get_boot_image(image, &bootimg, NULL, NULL);
2214
iso_image_remove_boot_image(image);
2215
ret= iso_image_set_boot_image(image, bin_path, emul_type,
2216
xorriso->boot_image_cat_path, &bootimg);
2218
iso_image_set_boot_catalog_weight(image, 1000000000);
2220
ret= iso_image_add_boot_image(image, bin_path, emul_type, 0, &bootimg);
2223
Xorriso_process_msg_queues(xorriso,0);
2224
Xorriso_report_iso_error(xorriso, "", ret,
2225
"Error when attaching El-Torito boot image to ISO 9660 image",
2227
sprintf(xorriso->info_text,
2228
"Could not attach El-Torito boot image to ISO 9660 image");
2229
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2232
el_torito_set_boot_platform_id(bootimg, (uint8_t) platform_id);
2233
el_torito_set_load_size(bootimg, load_size / 512);
2234
el_torito_set_id_string(bootimg, xorriso->boot_id_string);
2235
el_torito_set_selection_crit(bootimg, xorriso->boot_selection_crit);
2236
ret= Xorriso_set_isolinux_options(xorriso, image, 1);
2238
/* Register attachment and reset even in case of error return */
2239
xorriso->boot_count++;
2240
xorriso->boot_platform_id= 0;
2241
xorriso->patch_isolinux_image= 0;
2242
xorriso->boot_image_bin_path[0]= 0;
2243
xorriso->boot_image_bin_form[0]= 0;
2244
xorriso->boot_image_emul= 0;
2245
xorriso->boot_image_load_size= 4 * 512;
2246
memset(xorriso->boot_id_string, 0, sizeof(xorriso->boot_id_string));
2247
memset(xorriso->boot_selection_crit, 0,
2248
sizeof(xorriso->boot_selection_crit));
2249
xorriso->boot_efi_default= 0;
2257
iso_image_unref(image);
2262
/* #define Xorriso_boot_dummY 1 */
2265
/* @param flag bit0= do not write but only prepare and return size in sectors
2267
int Xorriso_write_session(struct XorrisO *xorriso, int flag)
2269
int ret, relax= 0, i, pacifier_speed= 0, data_lba, ext, is_bootable= 0;
2270
int major, minor, micro;
2271
char xorriso_id[256], *img_id, sfe[5*SfileadrL], *out_cs;
2272
struct isoburn_imgen_opts *sopts= NULL;
2273
struct burn_drive_info *dinfo, *source_dinfo;
2274
struct burn_drive *drive, *source_drive;
2275
struct burn_disc *disc= NULL;
2276
struct burn_write_opts *burn_options;
2277
off_t readcounter= 0,writecounter= 0;
2278
int num_sessions= 0, num_tracks= 0;
2279
struct burn_session **sessions;
2280
struct burn_track **tracks;
2281
enum burn_disc_status s;
2282
IsoImage *image= NULL;
2285
char profile_name[80];
2287
#ifdef Xorriso_multi_booT
2288
IsoBoot *bootcat_node;
2292
ElToritoBootImage *bootimg;
2293
ElToritoBootImage *efi_bootimg;
2294
enum eltorito_boot_media_type emul_type= ELTORITO_NO_EMUL;
2295
int boot_image_emul, boot_platform_id;
2296
off_t boot_image_load_size;
2298
char *boot_image_bin_path;
2299
#endif /* ! Xorriso_multi_booT */
2301
ret= Xorriso_finish_hl_update(xorriso, 0);
2305
out_cs= xorriso->out_charset;
2307
Xorriso_get_local_charset(xorriso, &out_cs, 0);
2310
ret= Xorriso_auto_format(xorriso, 0);
2314
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
2315
"on attempt to write", 2);
2318
if(xorriso->out_drive_handle == xorriso->in_drive_handle) {
2319
source_drive= drive;
2321
if(xorriso->in_drive_handle == NULL) {
2322
source_drive= drive;
2324
ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive,
2325
"on attempt to get source for write", 0);
2329
s= isoburn_disc_get_status(drive);
2330
if(s!=BURN_DISC_BLANK) {
2331
s= burn_disc_get_status(drive);
2332
if(s!=BURN_DISC_BLANK)
2333
sprintf(xorriso->info_text,
2334
"-indev differs from -outdev and -outdev media is not blank");
2336
sprintf(xorriso->info_text,
2337
"-indev differs from -outdev and -outdev media holds non-zero data");
2338
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2342
ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2);
2348
ret= isoburn_igopt_new(&sopts, 0);
2350
Xorriso_process_msg_queues(xorriso, 0);
2353
relax= xorriso->relax_compliance;
2355
xorriso->alignment= 0;
2356
image= isoburn_get_attached_image(source_drive);
2358
iso_image_set_application_id(image, xorriso->application_id);
2359
iso_image_set_publisher_id(image, xorriso->publisher);
2360
iso_image_set_system_id(image, xorriso->system_id);
2361
iso_image_set_volset_id(image, xorriso->volset_id);
2364
if((xorriso->do_aaip & 256) && out_cs != NULL) {
2365
static char *names = "isofs.cs";
2366
size_t value_lengths[1];
2368
value_lengths[0]= strlen(out_cs);
2369
ret= Xorriso_setfattr(xorriso, NULL, "/",
2370
(size_t) 1, &names, value_lengths, &out_cs, 2 | 8);
2375
ret= Xorriso_set_system_area(xorriso, source_drive, image, sopts, 0);
2379
/* Activate, adjust or discard boot image */
2381
#ifdef Xorriso_multi_booT
2383
if(image!=NULL && !(flag&1)) {
2384
is_bootable= iso_image_get_boot_image(image, NULL, NULL, &bootcat_node);
2385
if(xorriso->boot_image_bin_path[0]) {
2386
ret= Xorriso_attach_boot_image(xorriso, xorriso->boot_count == 0);
2390
if(xorriso->boot_count > 0) {
2391
/* Eventually rename boot catalog node to changed boot_image_cat_path */
2392
if(is_bootable > 0) {
2393
ret= Xorriso_path_from_node(xorriso, (IsoNode *) bootcat_node, sfe, 0);
2395
if(strcmp(sfe, xorriso->boot_image_cat_path) != 0) {
2396
ret= Xorriso_rename(xorriso, NULL, sfe,
2397
xorriso->boot_image_cat_path, 0);
2404
#else /* Xorriso_multi_booT */
2406
boot_image_bin_path= xorriso->boot_image_bin_path;
2407
boot_image_emul= xorriso->boot_image_emul;
2408
boot_platform_id= xorriso->boot_platform_id;
2409
boot_image_load_size= xorriso->boot_image_load_size;
2411
/* >>> This is kindof a quick hack.
2412
Needed would be a list of boot images with own parameters each.
2414
if(xorriso->boot_image_efi_path[0]) {
2415
if(xorriso->boot_image_bin_path[0] == 0) {
2416
/* Let EFI boot image be the default image */
2417
boot_image_bin_path= xorriso->boot_image_efi_path;
2419
boot_platform_id= 0xef;
2420
ret= Xorriso_iso_lstat(xorriso, xorriso->boot_image_efi_path,
2424
boot_image_load_size= ((stbuf.st_size / (off_t) 512) +
2425
!!(stbuf.st_size % (off_t) 512)) * 512;
2428
/* >>> ??? move down to libisoburn ? */
2429
if(image!=NULL && !(flag&1)) {
2430
is_bootable= iso_image_get_boot_image(image, &bootimg, NULL, NULL);
2431
if(boot_image_bin_path[0]) {
2432
/* discard old boot image, set new one */
2433
if(is_bootable == 1)
2434
iso_image_remove_boot_image(image);
2435
if(boot_image_emul == 1)
2436
emul_type= ELTORITO_HARD_DISC_EMUL;
2437
else if(boot_image_emul == 2)
2438
emul_type= ELTORITO_FLOPPY_EMUL;
2439
if(xorriso->boot_image_cat_path[0] == 0) {
2440
strcpy(xorriso->boot_image_cat_path, boot_image_bin_path);
2441
cpt= strrchr(xorriso->boot_image_cat_path, '/');
2443
cpt= xorriso->boot_image_cat_path;
2446
strcpy(cpt, "boot.cat");
2448
sprintf(xorriso->info_text, "Activating boot image %s",
2449
Text_shellsafe(boot_image_bin_path, sfe, 0));
2450
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2451
sprintf(xorriso->info_text, "Creating El Torito boot catalog file %s",
2452
Text_shellsafe(xorriso->boot_image_cat_path, sfe, 0));
2453
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2455
ret= Xorriso_node_from_path(xorriso, image, boot_image_bin_path,
2458
sprintf(xorriso->info_text,
2459
"Cannot find in ISO image: -boot_image ... bin_path=%s",
2460
Text_shellsafe(boot_image_bin_path, sfe, 0));
2461
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2464
ret= Xorriso_node_from_path(xorriso, image, xorriso->boot_image_cat_path,
2467
if(!xorriso->do_overwrite) {
2468
sprintf(xorriso->info_text,
2469
"May not overwite existing -boot_image ... cat_path=%s",
2470
Text_shellsafe(xorriso->boot_image_cat_path, sfe, 0));
2471
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2474
ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, xorriso->boot_image_cat_path,
2475
8 | (xorriso->do_overwrite == 1));
2477
sprintf(xorriso->info_text,
2478
"Could not remove existing -boot_image cat_path=%s",
2479
Text_shellsafe(xorriso->boot_image_cat_path, sfe, 0));
2480
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2485
ret= iso_image_set_boot_image(image, boot_image_bin_path,
2486
emul_type, xorriso->boot_image_cat_path,
2489
Xorriso_process_msg_queues(xorriso,0);
2490
Xorriso_report_iso_error(xorriso, "", ret,
2491
"Error when attaching El-Torito boot image to ISO 9660 image",
2493
sprintf(xorriso->info_text,
2494
"Could not attach El-Torito boot image to ISO 9660 image");
2495
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2499
#ifdef Xorriso_boot_dummY
2500
/* <<< for testing only */
2501
if(xorriso->boot_image_bin_path[0] == 0)
2502
el_torito_set_id_string(bootimg,
2503
(unsigned char *) "xorriso EFI 3456789012345678");
2505
el_torito_set_id_string(bootimg,
2506
(unsigned char *) "xorriso 80x86 BIOS 012345678");
2507
#endif /* Xorriso_boot_dummY */
2509
el_torito_set_boot_platform_id(bootimg, (uint8_t) boot_platform_id);
2510
iso_image_set_boot_catalog_weight(image, 1000000000);
2511
el_torito_set_load_size(bootimg, boot_image_load_size / 512);
2512
ret= Xorriso_set_isolinux_options(xorriso, image, 0);
2515
if(boot_image_bin_path == xorriso->boot_image_bin_path &&
2516
xorriso->boot_image_efi_path[0]) {
2518
sprintf(xorriso->info_text, "Activating additional EFI boot image %s",
2519
Text_shellsafe(xorriso->boot_image_efi_path, sfe, 0));
2520
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2521
ret= iso_image_add_boot_image(image, xorriso->boot_image_efi_path,
2522
ELTORITO_NO_EMUL, 0, &efi_bootimg);
2524
Xorriso_process_msg_queues(xorriso,0);
2525
Xorriso_report_iso_error(xorriso, "", ret,
2526
"Error when adding EFI boot image", 0, "FAILURE", 1);
2530
#ifdef Xorriso_boot_dummY
2531
/* <<< for testing only */
2532
el_torito_set_id_string(efi_bootimg,
2533
(unsigned char *) "xorriso EFI 3456789012345678");
2534
el_torito_set_selection_crit(efi_bootimg,
2535
(unsigned char *) "@selection criteria@");
2536
#endif /* Xorriso_boot_dummY */
2538
el_torito_set_boot_platform_id(efi_bootimg, (uint8_t) 0xef);
2539
ret= Xorriso_iso_lstat(xorriso, xorriso->boot_image_efi_path,
2543
boot_image_load_size= ((stbuf.st_size / (off_t) 512) +
2544
!!(stbuf.st_size % (off_t) 512));
2545
el_torito_set_load_size(efi_bootimg, boot_image_load_size);
2547
#ifdef Xorriso_boot_dummY
2548
/* <<< for testing only */
2549
ret= iso_image_add_boot_image(image, "/xxx",
2550
ELTORITO_NO_EMUL, 0, &efi_bootimg);
2552
Xorriso_process_msg_queues(xorriso,0);
2553
Xorriso_report_iso_error(xorriso, "", ret,
2554
"Error when adding EFI boot image 2", 0, "FAILURE", 1);
2557
el_torito_set_id_string(efi_bootimg,
2558
(unsigned char *) "xorriso EFI 3456789012345678");
2559
el_torito_set_selection_crit(efi_bootimg,
2560
(unsigned char *) "@selection crit 2 @");
2561
el_torito_set_boot_platform_id(efi_bootimg, (uint8_t) 0xef);
2562
el_torito_set_load_size(efi_bootimg, boot_image_load_size);
2564
ret= iso_image_add_boot_image(image, "/xxxx",
2565
ELTORITO_NO_EMUL, 0, &efi_bootimg);
2567
Xorriso_process_msg_queues(xorriso,0);
2568
Xorriso_report_iso_error(xorriso, "", ret,
2569
"Error when adding BIOS boot image 2", 0, "FAILURE", 1);
2572
el_torito_set_id_string(efi_bootimg,
2573
(unsigned char *) "xorriso BIOS2 abcdefghijklmn");
2574
el_torito_set_selection_crit(efi_bootimg,
2575
(unsigned char *) "@selection crit 3 @");
2576
el_torito_set_boot_platform_id(efi_bootimg, (uint8_t) 0);
2577
el_torito_set_load_size(efi_bootimg, (uint8_t) 4);
2579
#endif /* Xorriso_boot_dummY */
2583
#endif /* ! Xorriso_multi_booT */
2585
} else if(xorriso->patch_isolinux_image & 1) {
2586
if(is_bootable == 1) {
2587
relax|= isoburn_igopt_allow_full_ascii;
2588
sprintf(xorriso->info_text, "Patching boot info table");
2589
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2591
ret= Xorriso_path_from_lba(xorriso, NULL, xorriso->loaded_boot_bin_lba,
2596
sprintf(xorriso->info_text,
2597
"Cannot patch boot image: no file found for its LBA.");
2598
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2599
sprintf(xorriso->info_text,
2600
"Probably the loaded boot image file was deleted in this session.");
2601
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2602
sprintf(xorriso->info_text,
2603
"Use -boot_image \"any\" \"discard\" or set new boot image");
2604
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
2607
ret= Xorriso_set_isolinux_options(xorriso, image, 0);
2611
sprintf(xorriso->info_text,
2612
"Could not find any boot image for -boot_image patching");
2613
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
2615
} else if(xorriso->keep_boot_image && is_bootable == 1) {
2616
relax|= isoburn_igopt_allow_full_ascii;
2617
sprintf(xorriso->info_text, "Keeping boot image unchanged");
2618
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2619
} else if(is_bootable == 1) {
2620
iso_image_remove_boot_image(image);
2621
sprintf(xorriso->info_text, "Discarded boot image from old session");
2622
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2626
if((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2)) {
2627
/* Overwrite isofs.st of root node by xorriso->isofs_st_out */
2628
char *name= "isofs.st";
2629
char timestamp[16], *value= timestamp;
2630
size_t value_length;
2632
sprintf(timestamp, "%.f", (double) xorriso->isofs_st_out);
2633
value_length= strlen(timestamp);
2634
Xorriso_setfattr(xorriso, NULL, "/", (size_t) 1, &name,
2635
&value_length, &value, 2 | 8);
2638
isoburn_igopt_set_level(sopts, 3);
2639
ext= isoburn_igopt_rockridge |
2640
((!!xorriso->do_joliet) * isoburn_igopt_joliet) |
2641
(( !(xorriso->ino_behavior & 2)) * isoburn_igopt_hardlinks) |
2642
(( (!(xorriso->ino_behavior & 2)) ||
2643
(xorriso->do_aaip & (2 | 8 | 16 | 256)) ||
2644
(xorriso->do_md5 & (2 | 4))
2645
) * isoburn_igopt_aaip) |
2646
((!!(xorriso->do_md5 & 2)) * isoburn_igopt_session_md5) |
2647
((!!(xorriso->do_md5 & 4)) * isoburn_igopt_file_md5) |
2648
((!!(xorriso->do_md5 & 8)) * isoburn_igopt_file_stability);
2649
isoburn_igopt_set_extensions(sopts, ext);
2650
isoburn_igopt_set_relaxed(sopts, relax);
2651
isoburn_igopt_set_sort_files(sopts, 1);
2652
isoburn_igopt_set_over_mode(sopts, 0, 0, (mode_t) 0, (mode_t) 0);
2653
isoburn_igopt_set_over_ugid(sopts, 0, 0, (uid_t) 0, (gid_t) 0);
2654
isoburn_igopt_set_out_charset(sopts, out_cs);
2655
isoburn_igopt_set_fifo_size(sopts, xorriso->fs * 2048);
2656
Ftimetxt(time(NULL), xorriso->scdbackup_tag_time, 8);
2657
isoburn_igopt_set_scdbackup_tag(sopts, xorriso->scdbackup_tag_name,
2658
xorriso->scdbackup_tag_time,
2659
xorriso->scdbackup_tag_written);
2661
strlen(Xorriso_program_versioN)+strlen(Xorriso_timestamP)<80) {
2662
sprintf(xorriso_id, "XORRISO-%s %s",
2663
Xorriso_program_versioN, Xorriso_timestamP);
2664
isoburn_version(&major, &minor, µ);
2665
if(strlen(xorriso_id)<80)
2666
sprintf(xorriso_id+strlen(xorriso_id),
2667
", LIBISOBURN-%d.%d.%d", major, minor, micro);
2668
iso_lib_version(&major, &minor, µ);
2669
if(strlen(xorriso_id)<80)
2670
sprintf(xorriso_id+strlen(xorriso_id),
2671
", LIBISOFS-%d.%d.%d", major, minor, micro);
2672
burn_version(&major, &minor, µ);
2673
if(strlen(xorriso_id)<80)
2674
sprintf(xorriso_id+strlen(xorriso_id),
2675
", LIBBURN-%d.%d.%d", major, minor, micro);
2677
img_id= (char *) iso_image_get_data_preparer_id(image);
2679
for(i= strlen(img_id)-1; i>=0 && img_id[i]==' '; i--);
2681
sprintf(xorriso->info_text, "Overwrote previous preparer id '%s'",
2683
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
2686
iso_image_set_data_preparer_id(image, xorriso_id);
2688
isoburn_igopt_set_pvd_times(sopts,
2689
xorriso->vol_creation_time, xorriso->vol_modification_time,
2690
xorriso->vol_expiration_time, xorriso->vol_effective_time,
2693
/* Make final abort check before starting expensive activities */
2694
ret= Xorriso_eval_problem_status(xorriso, 1, 0);
2698
if(xorriso->zisofs_by_magic) {
2699
sprintf(xorriso->info_text,
2700
"Checking disk file content for zisofs compression headers.");
2701
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
2702
root_node= (IsoNode *) iso_image_get_root(image);
2703
ret= iso_node_zf_by_magic(root_node,
2704
(xorriso->out_drive_handle == xorriso->in_drive_handle) | 2 | 16);
2706
Xorriso_report_iso_error(xorriso, "", ret,
2707
"Error when examining file content for zisofs headers",
2710
ret= Xorriso_eval_problem_status(xorriso, 1, 0);
2713
sprintf(xorriso->info_text,
2714
"Check for zisofs compression headers done.");
2715
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
2718
/* >>> omit iso_image_update_sizes if the image was filled up very quickly */;
2720
ret= iso_image_update_sizes(image);
2722
Xorriso_process_msg_queues(xorriso, 0);
2724
Xorriso_report_iso_error(xorriso, "", ret,
2725
"Error when updating file sizes",
2728
ret= Xorriso_eval_problem_status(xorriso, 1, 0);
2733
Xorriso_set_abort_severity(xorriso, 1);
2734
if (xorriso->grow_blindly_msc2 >= 0 &&
2735
xorriso->out_drive_handle != xorriso->in_drive_handle) {
2736
ret= isoburn_prepare_blind_grow(source_drive, &disc, sopts, drive,
2737
xorriso->grow_blindly_msc2);
2739
/* Allow the consumer of output to access the input drive */
2741
ret= Xorriso_give_up_drive(xorriso, 1|8);
2745
} else if(xorriso->out_drive_handle == xorriso->in_drive_handle ||
2746
xorriso->in_drive_handle == NULL) {
2747
ret= isoburn_prepare_disc(source_drive, &disc, sopts);
2749
ret= isoburn_prepare_new_image(source_drive, &disc, sopts, drive);
2752
Xorriso_process_msg_queues(xorriso,0);
2753
sprintf(xorriso->info_text,"Failed to prepare session write run");
2754
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2758
ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0);
2761
isoburn_igopt_get_effective_lba(sopts, &(xorriso->session_lba));
2762
if(xorriso->do_stream_recording == 2) {
2763
ret= isoburn_igopt_get_data_start(sopts, &data_lba);
2764
if(ret > 0 && data_lba >= 16)
2765
burn_write_opts_set_stream_recording(burn_options, data_lba);
2768
ret= Xorriso_sanitize_image_size(xorriso, drive, disc, burn_options, flag&1);
2769
if(ret<=0 || (flag&1)) {
2770
Xorriso_process_msg_queues(xorriso,0);
2771
if(flag&1) /* set queue severity to FAILURE */
2772
Xorriso_set_image_severities(xorriso, 2);
2773
isoburn_cancel_prepared_write(source_drive, drive, 0);
2774
if(flag&1) /* reset queue severity */
2775
Xorriso_set_image_severities(xorriso, 0);
2779
ret= Xorriso_may_burn(xorriso, 0);
2783
/* Important: do not return until burn_is_aborting() was checked */
2784
Xorriso_set_signal_handling(xorriso, 1);
2786
xorriso->run_state= 1; /* Indicate that burning has started */
2787
isoburn_disc_write(burn_options, disc);
2788
burn_write_opts_free(burn_options);
2790
ret= Xorriso_pacifier_loop(xorriso, drive, pacifier_speed << 4);
2791
if(burn_is_aborting(0))
2792
Xorriso_abort(xorriso, 0); /* Never comes back */
2793
Xorriso_set_signal_handling(xorriso, 0);
2796
if(!isoburn_drive_wrote_well(drive)) {
2797
isoburn_cancel_prepared_write(source_drive, drive, 0);
2798
Xorriso_process_msg_queues(xorriso,0);
2799
sprintf(xorriso->info_text,
2800
"libburn indicates failure with writing.");
2801
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
2805
sessions= burn_disc_get_sessions(disc, &num_sessions);
2806
if(num_sessions>0) {
2807
tracks= burn_session_get_tracks(sessions[0], &num_tracks);
2808
if(tracks!=NULL && num_tracks>0) {
2809
burn_track_get_counters(tracks[0],&readcounter,&writecounter);
2810
xorriso->session_blocks= (int) (writecounter/ (off_t) 2048);
2811
sprintf(xorriso->info_text,
2812
"ISO image produced: %d sectors\nWritten to media : %d sectors at LBA %d\n",
2813
(int) (readcounter/ (off_t) 2048),
2814
xorriso->session_blocks, xorriso->session_lba);
2815
Xorriso_info(xorriso, 0);
2818
ret= isoburn_activate_session(drive);
2819
Xorriso_process_msg_queues(xorriso,0);
2821
sprintf(xorriso->info_text,
2822
"Could not write new set of volume descriptors");
2823
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
2826
/* Done early to free any reference to the libisofs resources via disc */
2828
burn_disc_free(disc);
2830
/* To wait for the end of the libisofs threads and their messages. */
2831
isoburn_sync_after_write(source_drive, drive, 0);
2832
Xorriso_process_msg_queues(xorriso,0);
2834
sprintf(xorriso->info_text, "Writing to %s completed sucessfully.\n\n",
2835
Text_shellsafe(xorriso->outdev,sfe,0));
2836
Xorriso_info(xorriso, 0);
2839
xorriso->run_state= 0; /* Indicate that burning has ended */
2840
Xorriso_set_abort_severity(xorriso, 0);
2844
/* >>> ??? revive discarded boot image */;
2848
burn_disc_free(disc);
2850
iso_image_unref(image);
2851
isoburn_igopt_destroy(&sopts, 0);
2852
Xorriso_process_msg_queues(xorriso,0);
2853
Xorriso_append_scdbackup_record(xorriso, 0);
2858
int Xorriso_check_burn_abort(struct XorrisO *xorriso, int flag)
2861
struct burn_drive_info *dinfo;
2862
struct burn_drive *drive;
2864
if(burn_is_aborting(0))
2866
if(xorriso->run_state!=1)
2868
ret= Xorriso_eval_problem_status(xorriso, 1, 1);
2871
sprintf(xorriso->info_text,
2872
"-abort_on '%s' encountered '%s' during image writing",
2873
xorriso->abort_on_text, xorriso->problem_status_text);
2874
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
2875
xorriso->problem_status_text, 0);
2877
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
2878
"on attempt to abort burn run", 2);
2882
burn_drive_cancel(drive);
2883
sprintf(xorriso->info_text,
2884
"libburn has now been urged to cancel its operation");
2885
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
2890
/* This loop watches burn runs until they end.
2891
It issues pacifying update messages to the user.
2892
@param flag bit0-3 = emulation mode
2896
bit4= report speed in CD units
2897
bit5= report speed in BD units
2899
int Xorriso_pacifier_loop(struct XorrisO *xorriso, struct burn_drive *drive,
2902
int ret, size, free_bytes, i, aborting= 0, emul, buffer_fill= 50, last_sector;
2903
struct burn_progress progress;
2904
char *status_text, date_text[80], *speed_unit, mem_text[8];
2905
enum burn_drive_status drive_status;
2906
double start_time, current_time, last_time, base_time= 0.0, base_count= 0.0;
2907
double next_base_time= 0.0, next_base_count= 0.0, first_base_time= 0.0;
2908
double first_base_count= 0.0, norm= 0.0, now_time, fract_offset= 0.0;
2909
double measured_speed, speed_factor= 1385000, quot;
2910
time_t time_prediction;
2912
start_time= Sfile_microtime(0);
2913
while(burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING)
2917
fract_offset= 0.2 * (double) emul - ((int) (0.2 * (double) emul));
2919
emul= xorriso->pacifier_style;
2922
speed_factor= 150.0*1024;
2924
} else if(flag & 32) {
2925
speed_factor= 4495625;
2929
current_time= Sfile_microtime(0);
2930
measured_speed= 0.0;
2932
last_time= current_time;
2933
last_sector= progress.sector;
2934
drive_status= burn_drive_get_status(drive, &progress);
2935
if(drive_status == BURN_DRIVE_IDLE)
2937
current_time= Sfile_microtime(0);
2938
if(drive_status == BURN_DRIVE_WRITING && progress.sectors > 0) {
2939
if(current_time-last_time>0.2)
2940
measured_speed= (progress.sector - last_sector) * 2048.0 /
2941
(current_time - last_time);
2943
if(progress.buffer_capacity>0)
2944
buffer_fill= (double) (progress.buffer_capacity
2945
- progress.buffer_available) * 100.0
2946
/ (double) progress.buffer_capacity;
2948
if(progress.sector<=progress.sectors)
2949
sprintf(xorriso->info_text, "%4d of %4d MB written",
2950
progress.sector / 512, progress.sectors / 512);
2952
sprintf(xorriso->info_text, "%4d MB written",
2953
progress.sector / 512);
2955
if(xorriso->pacifier_fifo!=NULL)
2956
ret= burn_fifo_inquire_status(xorriso->pacifier_fifo,
2957
&size, &free_bytes, &status_text);
2959
ret= isoburn_get_fifo_status(drive, &size, &free_bytes, &status_text);
2961
sprintf(xorriso->info_text+strlen(xorriso->info_text),
2963
(int) (100.0-100.0*((double) free_bytes)/(double) size));
2965
sprintf(xorriso->info_text+strlen(xorriso->info_text), " [buf %3d%%]",
2968
if(current_time-last_time>0.2)
2969
sprintf(xorriso->info_text+strlen(xorriso->info_text), " %4.1fx.",
2970
measured_speed/speed_factor);
2972
} else if(emul == 1 &&
2973
progress.sectors > 0 && progress.sector <= progress.sectors) {
2974
/* "37.87% done, estimate finish Tue Jul 15 18:55:07 2008" */
2976
quot= ((double) progress.sector) / ((double) progress.sectors);
2977
sprintf(xorriso->info_text, " %2.2f%% done", quot*100.0);
2978
if(current_time - start_time >= 2 && quot > 0.0 &&
2979
(quot >= 0.02 || progress.sector >= 5*1024)) {
2980
if(base_time == 0.0 && progress.sector >= 16*1024) {
2981
first_base_time= base_time= next_base_time= current_time;
2982
first_base_count= next_base_count= progress.sector;
2983
} else if(next_base_time > 0 && current_time - next_base_time >= 10) {
2984
base_time= next_base_time;
2985
base_count= next_base_count;
2986
next_base_time= current_time;
2987
next_base_count= progress.sector;
2989
if(first_base_time > 0 &&
2990
current_time - first_base_time >= 10 &&
2991
progress.sectors > first_base_count &&
2992
progress.sector > first_base_count) {
2996
quot= ((double) progress.sector - first_base_count)
2997
/ ((double) progress.sectors - first_base_count);
2998
time_prediction= norm * (1.0 - quot) / quot
2999
* (current_time - first_base_time);
3001
time_prediction= (1.0 - quot) / quot * (current_time - start_time);
3005
current_time - base_time >= 10 && progress.sectors > base_count) {
3006
quot= ((double) progress.sector - base_count)
3007
/ ((double) progress.sectors - base_count);
3008
time_prediction+= (1.0 - quot) / quot * (current_time - base_time);
3011
time_prediction/= norm;
3012
if(time_prediction < 30*86400 && time_prediction > 0) {
3013
time_prediction+= current_time + 1;
3014
Ftimetxt(time_prediction, date_text, 4);
3015
sprintf(xorriso->info_text+strlen(xorriso->info_text),
3016
", estimate finish %s", date_text);
3020
if(progress.sector<=progress.sectors) {
3021
if(progress.sectors <= 0)
3022
strcpy(mem_text, " 99.9");
3024
sprintf(mem_text, "%5.1f",
3025
100.0 * ((double) progress.sector) / ((double) progress.sectors));
3027
sprintf(xorriso->info_text, "Writing: %10ds %s%% ",
3028
progress.sector, mem_text);
3030
Sfile_scale(2048.0 * (double) progress.sector, mem_text, 5, 1e4, 1);
3031
sprintf(xorriso->info_text, "Writing: %10ds %s ",
3032
progress.sector, mem_text);
3034
ret= isoburn_get_fifo_status(drive, &size, &free_bytes, &status_text);
3036
sprintf(xorriso->info_text+strlen(xorriso->info_text),
3037
" fifo %3d%% buf %3d%%",
3038
(int) (100.0-100.0*((double) free_bytes)/(double) size),
3040
if(current_time-last_time>0.2)
3041
sprintf(xorriso->info_text+strlen(xorriso->info_text), " %5.1fx%s ",
3042
measured_speed/speed_factor, speed_unit);
3044
} else if(drive_status == BURN_DRIVE_CLOSING_SESSION ||
3045
drive_status == BURN_DRIVE_CLOSING_TRACK)
3046
sprintf(xorriso->info_text,
3047
"Closing track/session. Working since %.f seconds",
3048
current_time-start_time);
3049
else if(drive_status == BURN_DRIVE_FORMATTING)
3050
sprintf(xorriso->info_text, "Formatting. Working since %.f seconds",
3051
current_time-start_time);
3053
sprintf(xorriso->info_text,
3054
"Thank you for being patient. Working since %.f seconds.",
3055
current_time-start_time);
3056
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
3058
for(i= 0; i<12; i++) { /* 2 usleeps more than supposed to be needed */
3059
Xorriso_process_msg_queues(xorriso, 0);
3061
aborting= Xorriso_check_burn_abort(xorriso, 0);
3063
now_time= Sfile_microtime(0);
3064
if(((time_t) now_time) - ((time_t) current_time) >= 1 &&
3065
now_time - ((time_t) now_time) >= fract_offset)
3073
int Xorriso__read_pacifier(IsoImage *image, IsoFileSource *filesource)
3075
struct XorrisO *xorriso;
3077
xorriso= (struct XorrisO *) iso_image_get_attached_data(image);
3080
Xorriso_process_msg_queues(xorriso,0);
3081
xorriso->pacifier_count++;
3082
if(xorriso->pacifier_count%10)
3084
Xorriso_pacifier_callback(xorriso, "nodes read", xorriso->pacifier_count, 0,
3089
/* @param flag bit0=silently return 0 if no volume/image is present
3091
int Xorriso_get_volume(struct XorrisO *xorriso, IsoImage **volume,
3094
if(xorriso->in_volset_handle==NULL) {
3097
Xorriso_process_msg_queues(xorriso,0);
3098
sprintf(xorriso->info_text,"No ISO image present.");
3099
if(xorriso->indev[0]==0 && xorriso->outdev[0]==0)
3100
sprintf(xorriso->info_text+strlen(xorriso->info_text),
3101
" No -dev, -indev, or -outdev selected.");
3103
sprintf(xorriso->info_text+strlen(xorriso->info_text),
3104
" Possible program error with drive '%s'.", xorriso->indev);
3106
if(!xorriso->no_volset_present)
3107
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3108
xorriso->no_volset_present= 1;
3111
*volume= (IsoImage *) xorriso->in_volset_handle;
3112
xorriso->no_volset_present= 0;
3113
return(*volume != NULL);
3117
/* @param flag bit0=do not complain about non existent node */
3118
int Xorriso_node_from_path(struct XorrisO *xorriso, IsoImage *volume,
3119
char *path, IsoNode **node, int flag)
3122
char sfe[5*SfileadrL], *path_pt;
3127
if(volume == NULL) {
3128
ret= Xorriso_get_volume(xorriso, &volume, 0);
3133
ret= iso_tree_path_to_node(volume, path_pt, node);
3134
Xorriso_process_msg_queues(xorriso,0);
3135
if(ret<=0 || (*node)==NULL) {
3137
sprintf(xorriso->info_text, "Cannot find path %s in loaded ISO image",
3138
Text_shellsafe(path_pt, sfe, 0));
3139
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3147
/* @param eff_path returns resulting effective path.
3148
Must provide at least SfileadrL bytes of storage.
3149
@param flag bit0= do not produce problem events (unless faulty path format)
3150
bit1= work purely literally, do not use libisofs
3151
bit2= (with bit1) this is an address in the disk world
3152
bit3= return root directory as "/" and not as ""
3153
bit4= (with bit2) determine type of disk file eff_path
3154
and return 0 if not existing
3155
bit5= (with bit3) this is not a parameter
3156
bit6= insist in having an ISO image, even with bits1+2
3157
@return -1 = faulty path format, 0 = not found ,
3158
1 = found simple node , 2 = found directory
3160
int Xorriso_normalize_img_path(struct XorrisO *xorriso, char *wd,
3161
char *img_path, char eff_path[], int flag)
3163
int ret, is_dir= 0, done= 0;
3166
IsoNode *node= NULL;
3167
char path[SfileadrL], *apt, *npt, sfe[5*SfileadrL], *cpt;
3169
if((flag&64) || !(flag&2)) {
3170
ret= Xorriso_get_volume(xorriso, &volume, 0);
3176
if(img_path[0]==0) {
3178
strcpy(eff_path, "/");
3179
return(2); /* root directory */
3183
if(img_path[0]!='/') {
3185
ret= Sfile_add_to_path(path, img_path, 0);
3189
if(Sfile_str(path, img_path, 0)<=0)
3193
sprintf(xorriso->info_text,
3194
"Internal error: Unresolvable relative addressing in iso_rr_path '%s'",
3196
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FATAL", 0);
3198
} else if(path[1]==0) {
3200
strcpy(eff_path, "/");
3201
return(2); /* root directory */
3204
for(npt= apt; !done; apt= npt+1) {
3205
npt= strchr(apt, '/');
3207
npt= apt+strlen(apt);
3218
if(strcmp(apt,".")==0) {
3222
if(strcmp(apt,"..")==0) {
3224
node= (IsoNode *) dir;
3227
sprintf(xorriso->info_text,
3228
"Relative addressing in path exceeds root directory: %s",
3229
Text_shellsafe(img_path, sfe, 0));
3230
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3233
dir= iso_node_get_parent(node);
3235
/* truncate eff_path */;
3236
cpt= strrchr(eff_path, '/');
3237
if(cpt==NULL) /* ??? if not flag&2 then this is a bug */
3243
ret= Sfile_add_to_path(eff_path, apt, 0);
3246
sprintf(xorriso->info_text, "Effective path gets much too long (%d)",
3247
(int) (strlen(eff_path)+strlen(apt)+1));
3248
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3252
dir= (IsoDir *) node;
3253
ret= Xorriso_node_from_path(xorriso, volume, eff_path, &node, flag&1);
3256
if(dir==NULL) /* could be false with "/dir/.." */
3257
dir= iso_node_get_parent(node);
3258
is_dir= LIBISO_ISDIR(node);
3262
ret= Sfile_type(eff_path,
3263
1|(4*(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&32)))
3274
int Xorriso_get_node_by_path(struct XorrisO *xorriso,
3275
char *in_path, char *eff_path,
3276
IsoNode **node, int flag)
3279
char path[SfileadrL];
3282
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, in_path, path, 0);
3286
strcpy(eff_path, path);
3287
ret= Xorriso_get_volume(xorriso, &volume, 0);
3290
ret= Xorriso_node_from_path(xorriso, volume, path, node, 0);
3299
int Xorriso_node_get_dev(struct XorrisO *xorriso, IsoNode *node,
3300
char *path, dev_t *dev, int flag)
3302
*dev= iso_special_get_dev((IsoSpecial *) node);
3307
/* @param flag bit0= *node is already valid
3308
bit1= add extra block for size estimation
3309
bit2= complain loudely if path is missing in image
3310
bit3= stbuf is to be used without eventual ACL
3311
bit4= try to obtain a better st_nlink count if hardlinks
3314
int Xorriso_fake_stbuf(struct XorrisO *xorriso, char *path, struct stat *stbuf,
3315
IsoNode **node, int flag)
3317
int ret, min_hl, max_hl, node_idx, i;
3320
memset((char *) stbuf, 0, sizeof(struct stat));
3322
ret= Xorriso_get_volume(xorriso, &volume, 0);
3325
ret= Xorriso_node_from_path(xorriso, volume, path, node, !(flag&4));
3332
/* >>> stbuf->st_dev */
3333
/* >>> stbuf->st_ino */
3336
stbuf->st_mode= iso_node_get_perms_wo_acl(*node) & 07777;
3338
stbuf->st_mode= iso_node_get_permissions(*node) & 07777;
3339
if(LIBISO_ISDIR(*node))
3340
stbuf->st_mode|= S_IFDIR;
3341
else if(LIBISO_ISREG(*node))
3342
stbuf->st_mode|= S_IFREG;
3343
else if(LIBISO_ISLNK(*node))
3344
stbuf->st_mode|= S_IFLNK;
3345
else if(LIBISO_ISCHR(*node)) {
3346
stbuf->st_mode|= S_IFCHR;
3347
Xorriso_node_get_dev(xorriso, *node, path, &(stbuf->st_rdev), 0);
3348
} else if(LIBISO_ISBLK(*node)) {
3349
stbuf->st_mode|= S_IFBLK;
3350
Xorriso_node_get_dev(xorriso, *node, path, &(stbuf->st_rdev), 0);
3351
} else if(LIBISO_ISFIFO(*node))
3352
stbuf->st_mode|= S_IFIFO;
3353
else if(LIBISO_ISSOCK(*node))
3354
stbuf->st_mode|= S_IFSOCK;
3355
else if(LIBISO_ISBOOT(*node))
3356
stbuf->st_mode|= Xorriso_IFBOOT;
3358
/* >>> With directories this should be : number of subdirs + 2 */
3359
/* >>> ??? How to obtain RR hardlink number for other types ? */
3360
/* This may get overriden farther down */
3363
stbuf->st_uid= iso_node_get_uid(*node);
3364
stbuf->st_gid= iso_node_get_gid(*node);
3366
if(LIBISO_ISREG(*node))
3367
stbuf->st_size= iso_file_get_size((IsoFile *) *node)+ (2048 * !!(flag&2));
3371
stbuf->st_blksize= 2048;
3372
stbuf->st_blocks= stbuf->st_size / (off_t) 2048;
3373
if(stbuf->st_blocks * (off_t) 2048 != stbuf->st_size)
3376
stbuf->st_atime= iso_node_get_atime(*node);
3377
stbuf->st_mtime= iso_node_get_mtime(*node);
3378
stbuf->st_ctime= iso_node_get_ctime(*node);
3380
if(LIBISO_ISDIR(*node) || (xorriso->ino_behavior & 1) || (!(flag & 16)) ||
3381
xorriso->hln_array == NULL)
3384
/* Try to obtain a better link count */
3385
ret= Xorriso_search_hardlinks(xorriso, *node, &node_idx, &min_hl, &max_hl, 0);
3388
if(ret > 0 && node_idx >= 0) {
3389
for(i= min_hl; i <= max_hl; i++) {
3392
/* Check whether node is still valid */
3393
if(iso_node_get_parent(xorriso->hln_array[i]) != NULL)
3401
/* @param flag >>> bit0= follow links (i.e. stat() rather than lstat()
3402
bit1= do not return -2 on severe errors
3403
bit2= complain loudely if path is missing in image
3405
int Xorriso_iso_lstat(struct XorrisO *xorriso, char *path, struct stat *stbuf,
3413
/* >>> follow link in ISO image */;
3417
ret= Xorriso_fake_stbuf(xorriso, path, stbuf, &node, flag&4);
3420
if(ret<0 && !(flag&2))
3426
/* @param flag bit0= give directory x-permission where is r-permission
3427
bit1= do not transfer ACL or xattr
3428
bit2= record dev,inode (only if enabled by xorriso)
3429
bit5= transfer ACL or xattr from eventual link target
3431
int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf,
3432
char *disk_path, IsoNode *node, int flag)
3436
size_t num_attrs= 0, *value_lengths= NULL;
3437
char **names= NULL, **values= NULL;
3439
mode= stbuf->st_mode;
3441
if((!(flag & 2)) && !(xorriso->do_aaip & 1))
3442
/* Will drop ACL. Update mode S_IRWXG by eventual group:: ACL entry */
3443
iso_local_get_perms_wo_acl(disk_path, &mode, flag & 32);
3445
if((flag&1) && S_ISDIR(mode)) {
3453
iso_node_set_permissions(node, mode & 07777);
3454
iso_node_set_uid(node, stbuf->st_uid);
3455
iso_node_set_gid(node, stbuf->st_gid);
3456
iso_node_set_atime(node, stbuf->st_atime);
3457
iso_node_set_mtime(node, stbuf->st_mtime);
3458
iso_node_set_ctime(node, stbuf->st_ctime);
3460
if((xorriso->do_aaip & 5) && !(flag & 2)) {
3461
ret= iso_local_get_attrs(disk_path, &num_attrs, &names, &value_lengths,
3462
&values, ((xorriso->do_aaip & 1) && !(flag & 2))
3463
| ((!(xorriso->do_aaip & 4)) << 2)
3466
Xorriso_process_msg_queues(xorriso,0);
3467
Xorriso_report_iso_error(xorriso, disk_path, ret,
3468
"Error when obtaining local ACL and xattr", 0,
3472
ret= iso_node_set_attrs(node, num_attrs, names, value_lengths, values,
3475
Xorriso_process_msg_queues(xorriso,0);
3476
Xorriso_report_iso_error(xorriso, "", ret,
3477
"Error when setting ACL and xattr to image node",
3483
if((flag & 4) && ((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2))) {
3484
ret= Xorriso_record_dev_inode(xorriso, disk_path, (dev_t) 0, (ino_t) 0,
3485
(void *) node, "", flag & 32);
3492
Xorriso_process_msg_queues(xorriso,0);
3493
iso_local_get_attrs(disk_path, &num_attrs, &names, &value_lengths,
3494
&values, 1 << 15); /* free memory */
3499
int Xorriso_graft_split(struct XorrisO *xorriso, IsoImage *volume,
3500
IsoDir *dir, char *disk_path, char *img_name,
3501
char *nominal_source, char *nominal_target,
3502
off_t size, IsoNode **node, int flag)
3505
IsoDir *new_dir= NULL;
3507
int partno, total_parts;
3509
char part_name[SfileadrL], sfe[5*SfileadrL];
3511
ret= iso_tree_add_new_dir(dir, img_name, &new_dir);
3514
*node= (IsoNode *) new_dir;
3515
total_parts= size / xorriso->split_size;
3516
if(size % xorriso->split_size)
3518
for(partno= 1; partno<=total_parts; partno++) {
3519
offset = xorriso->split_size * (off_t) (partno-1);
3520
Splitpart__compose(part_name, partno, total_parts, offset,
3521
xorriso->split_size, size, 0);
3522
ret= Xorriso_tree_graft_node(xorriso, volume,
3523
new_dir, disk_path, part_name,
3524
nominal_source, nominal_target,
3525
offset, xorriso->split_size,
3530
sprintf(xorriso->info_text, "Split into %d parts: %s",
3531
total_parts, Text_shellsafe(nominal_target, sfe, 0));
3532
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
3538
@param flag bit3= cut_out_node: offset and size are valid
3540
int Xorriso_tree_graft_node(struct XorrisO *xorriso, IsoImage *volume,
3541
IsoDir *dir, char *disk_path, char *img_name,
3542
char *nominal_source, char *nominal_target,
3543
off_t offset, off_t cut_size,
3544
IsoNode **node, int flag)
3546
int ret, stbuf_valid= 0;
3548
char sfe[5*SfileadrL];
3551
if(lstat(disk_path, &stbuf) != -1) {
3553
if(S_ISREG(stbuf.st_mode))
3554
size= stbuf.st_size;
3557
if(cut_size > xorriso->file_size_limit && xorriso->file_size_limit > 0) {
3558
sprintf(xorriso->info_text,
3559
"File piece exceeds size limit of %.f bytes: %.f from %s\n",
3560
(double) xorriso->file_size_limit, (double) cut_size,
3561
Text_shellsafe(disk_path, sfe, 0));
3562
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3565
ret= iso_tree_add_new_cut_out_node(volume, dir, img_name, disk_path,
3566
offset, cut_size, node);
3570
if(xorriso->split_size > 0 && size > xorriso->split_size) {
3571
ret= Xorriso_graft_split(xorriso, volume, dir, disk_path, img_name,
3572
nominal_source, nominal_target, size,
3576
} else if(size > xorriso->file_size_limit && xorriso->file_size_limit > 0) {
3577
sprintf(xorriso->info_text,
3578
"File exceeds size limit of %.f bytes: %s\n",
3579
(double) xorriso->file_size_limit,
3580
Text_shellsafe(disk_path, sfe, 0));
3581
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3584
ret= iso_tree_add_new_node(volume, dir, img_name, disk_path, node);
3590
if(stbuf_valid && ((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2))) {
3591
ret= Xorriso_record_dev_inode(xorriso, disk_path,
3592
stbuf.st_dev, stbuf.st_ino, (void *) *node, "", 1);
3599
Xorriso_process_msg_queues(xorriso,0);
3600
Xorriso_report_iso_error(xorriso, nominal_source, ret,
3601
"Cannot add node to tree", 0, "FAILURE", 1|2);
3604
if(LIBISO_ISREG(*node))
3605
xorriso->pacifier_byte_count+= iso_file_get_size((IsoFile *) *node);
3610
/* @param flag bit0= recursion is active
3611
bit1= do not report added files
3612
bit6= do not delete eventually existing node from di_array
3613
bit7= no special handling of split file directories
3615
int Xorriso_add_tree(struct XorrisO *xorriso, IsoDir *dir,
3616
char *img_dir_path, char *disk_dir_path,
3617
struct LinkiteM *link_stack, int flag)
3621
int ret, target_is_dir, source_is_dir, source_is_link, fret, was_failure= 0;
3622
int do_not_dive, target_is_split= 0;
3623
struct DirseQ *dirseq= NULL;
3624
char *name, *img_name, *srcpt, *stbuf_src= "";
3625
struct stat stbuf, hstbuf;
3627
struct LinkiteM *own_link_stack;
3628
char *sfe= NULL, *sfe2= NULL;
3629
char *disk_path= NULL, *img_path= NULL, *link_target= NULL;
3631
/* Avoiding large local memory objects in order to save stack space */
3632
sfe= malloc(5*SfileadrL);
3633
sfe2= malloc(5*SfileadrL);
3634
disk_path= malloc(2*SfileadrL);
3635
img_path= malloc(2*SfileadrL);
3636
link_target= calloc(SfileadrL, 1);
3637
if(sfe==NULL || sfe2==NULL || disk_path==NULL || img_path==NULL ||
3638
link_target==NULL) {
3639
Xorriso_no_malloc_memory(xorriso, &sfe, 0);
3643
own_link_stack= link_stack;
3645
ret= Xorriso_get_volume(xorriso, &volume, 0);
3649
stbuf_src= disk_dir_path;
3650
if(lstat(disk_dir_path, &stbuf)==-1)
3651
goto cannot_open_dir;
3652
dir_dev= stbuf.st_dev;
3653
if(S_ISLNK(stbuf.st_mode)) {
3654
if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1))))
3656
stbuf_src= disk_dir_path;
3657
if(stat(disk_dir_path, &stbuf)==-1)
3658
goto cannot_open_dir;
3659
if(dir_dev != stbuf.st_dev &&
3660
!(xorriso->do_follow_mount || (xorriso->do_follow_param && !(flag&1))))
3663
ret= Dirseq_new(&dirseq, disk_dir_path, 1);
3665
sprintf(xorriso->info_text,"Failed to create source filesystem iterator");
3666
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
3671
Xorriso_msgs_submit(xorriso, 0, disk_dir_path, 0, "ERRFILE", 0);
3672
sprintf(xorriso->info_text,"Cannot open as source directory: %s",
3673
Text_shellsafe(disk_dir_path, sfe, 0));
3674
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3678
if(Sfile_str(disk_path, disk_dir_path,0)<=0)
3680
if(disk_path[0]==0 || disk_path[strlen(disk_path)-1]!='/')
3681
strcat(disk_path,"/");
3682
name= disk_path+strlen(disk_path);
3683
if(Sfile_str(img_path, img_dir_path, 0)<=0)
3685
if(img_path[0] || img_path[strlen(img_path)-1]!='/')
3686
strcat(img_path,"/");
3687
img_name= img_path+strlen(img_path);
3689
while(1) { /* loop over directory content */
3691
Linkitem_reset_stack(&own_link_stack, link_stack, 0);
3693
Xorriso_process_msg_queues(xorriso,0);
3694
ret= Dirseq_next_adr(dirseq,name,0); /* name is a pointer into disk_path */
3698
sprintf(xorriso->info_text,"Failed to obtain next directory entry");
3699
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
3703
/* compare exclusions against disk_path resp. name */
3704
ret= Xorriso_path_is_excluded(xorriso, disk_path, 0); /* (is never param) */
3710
strcpy(img_name, name);
3711
if(Xorriso_much_too_long(xorriso, strlen(img_path), 0)<=0)
3712
{ret= 0; goto was_problem;}
3713
if(Xorriso_much_too_long(xorriso, strlen(srcpt), 0)<=0)
3714
{ret= 0; goto was_problem;}
3716
if(lstat(srcpt, &stbuf)==-1) {
3718
Xorriso_msgs_submit(xorriso, 0, srcpt, 0, "ERRFILE", 0);
3719
sprintf(xorriso->info_text,
3720
"Cannot determine attributes of source file %s",
3721
Text_shellsafe(srcpt, sfe, 0));
3722
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
3723
ret= 0; goto was_problem;
3726
source_is_link= S_ISLNK(stbuf.st_mode);
3727
if(xorriso->do_follow_links && source_is_link) {
3728
/* Xorriso_hop_link checks for wide link loops */
3729
ret= Xorriso_hop_link(xorriso, srcpt, &own_link_stack, &hstbuf, 0);
3733
ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 0);
3738
if(lstat(srcpt, &stbuf)==-1)
3741
if(Xorriso_eval_problem_status(xorriso, 0, 1|2)<0)
3742
{ret= 0; goto was_problem;}
3743
ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1);
3747
} else if (S_ISLNK(stbuf.st_mode)) {
3748
ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1);
3753
if(S_ISDIR(stbuf.st_mode)) {
3755
if(dir_dev != stbuf.st_dev && !xorriso->do_follow_mount)
3759
/* does a node exist with this name ? */
3761
ret= Xorriso_node_from_path(xorriso, volume, img_path, &node, 1);
3763
target_is_dir= LIBISO_ISDIR(node);
3765
if(target_is_dir && !(flag & 128))
3766
target_is_split= Xorriso_is_split(xorriso, "", (void *) node, 1 | 2);
3768
if(!((target_is_dir && !target_is_split) && source_is_dir)) {
3769
Xorriso_process_msg_queues(xorriso,0);
3771
/* handle overwrite situation */;
3772
if(xorriso->do_overwrite==1 ||
3773
(xorriso->do_overwrite==2 && !(target_is_dir && !target_is_split))) {
3774
ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, img_path,
3775
1 | 8 | (flag & 64));
3779
sprintf(xorriso->info_text, "User revoked adding of: %s",
3780
Text_shellsafe(img_path, sfe, 0));
3781
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
3782
ret= 0; goto was_problem;
3786
Xorriso_msgs_submit(xorriso, 0, srcpt, 0, "ERRFILE", 0);
3787
sprintf(xorriso->info_text,
3788
"While grafting %s : file object exists and may not be overwritten by %s",
3789
Text_shellsafe(img_path,sfe,0), Text_shellsafe(stbuf_src,sfe2,0));
3790
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3791
ret= 0; goto was_problem;
3797
ret= Xorriso_tree_graft_node(xorriso, volume, dir, srcpt, img_name,
3798
"", img_path, (off_t) 0, (off_t) 0,
3802
Xorriso_process_msg_queues(xorriso,0);
3803
Xorriso_msgs_submit(xorriso, 0, stbuf_src, 0, "ERRFILE", 0);
3804
sprintf(xorriso->info_text, "Grafting failed: %s = %s",
3805
Text_shellsafe(img_path,sfe,0), Text_shellsafe(stbuf_src,sfe2,0));
3806
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3807
ret= 0; goto was_problem;
3810
xorriso->pacifier_count++;
3811
if((xorriso->pacifier_count%100)==0)
3812
Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count,
3813
xorriso->pacifier_total, "", 0);
3815
Xorriso_set_change_pending(xorriso, 0);
3818
sprintf(xorriso->info_text, "Did not follow mount point : %s",
3819
Text_shellsafe(disk_path, sfe, 0));
3820
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
3822
ret= Xorriso_add_tree(xorriso, (IsoDir *) node,
3823
img_path, disk_path, own_link_stack,
3824
1 | (flag & (2 | 64 | 128)));
3830
continue; /* regular bottom of loop */
3833
fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
3848
if(link_target!=NULL)
3850
Xorriso_process_msg_queues(xorriso,0);
3851
Linkitem_reset_stack(&own_link_stack, link_stack, 0);
3852
Dirseq_destroy(&dirseq, 0);
3855
return(!was_failure);
3859
/* @param flag bit0= cut_out mode : base on leaf parent directory
3861
int Xorriso_copy_implicit_properties(struct XorrisO *xorriso, IsoDir *dir,
3862
char *full_img_path, char *img_path, char *full_disk_path, int flag)
3864
int ret, nfic, nic, nfdc, d, i;
3865
char nfi[SfileadrL], ni[SfileadrL], nfd[SfileadrL], *cpt;
3866
char sfe[5*SfileadrL];
3869
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, full_img_path, nfi,
3873
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, img_path, ni, 1|2);
3876
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, full_disk_path, nfd,
3880
nfic= Sfile_count_components(nfi, 0);
3881
nic= Sfile_count_components(ni, 0);
3882
nfdc= Sfile_count_components(nfd, 0);
3883
d= nfic-(flag&1)-nic;
3888
for(i= 0; i<d; i++) {
3889
cpt= strrchr(nfd, '/');
3891
return(-1); /* should not happen */
3896
if(stat(nfd, &stbuf)==-1)
3898
Xorriso_transfer_properties(xorriso, &stbuf, nfd, (IsoNode *) dir,
3899
((flag&1) && d==0) | 4 | 32);
3900
sprintf(xorriso->info_text,
3901
"Copied properties for %s", Text_shellsafe(ni, sfe, 0));
3902
sprintf(xorriso->info_text+strlen(xorriso->info_text),
3903
" from %s", Text_shellsafe(nfd, sfe, 0));
3904
if(!((flag&1) && d==0))
3905
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
3910
/* @param bit0= copy link target properties rather than link properties
3911
bit1= give directory x-permission where is r-permission
3912
bit2= record dev,inode (only if enabled by xorriso)
3914
int Xorriso_copy_properties(struct XorrisO *xorriso,
3915
char *disk_path, char *img_path, int flag)
3921
ret= Xorriso_get_node_by_path(xorriso, img_path, NULL, &node, 0);
3925
if(stat(disk_path, &stbuf)==-1)
3928
if(lstat(disk_path, &stbuf)==-1)
3931
Xorriso_transfer_properties(xorriso, &stbuf, disk_path, node,
3932
((flag & 2) >> 1) | ((flag & 1) << 5) | (flag & 4));
3933
Xorriso_set_change_pending(xorriso, 0);
3938
/* @param boss_iter Opaque handle to be forwarded to actions in ISO image
3939
Set to NULL if calling this function from outside ISO world
3940
@param flag bit0= mkdir: graft in as empty directory, not as copy from disk
3941
bit1= do not report added files
3942
bit2= -follow, -not_*: this is not a command parameter
3943
bit3= use offset and cut_size for cut_out_node
3944
bit4= return 3 on rejection by exclusion or user
3945
bit5= if directory then do not add sub tree
3946
bit6= do not delete eventually existing node from di_array
3947
bit7= no special handling of split file directories
3948
@return <=0 = error , 1 = added simple node , 2 = added directory ,
3951
int Xorriso_graft_in(struct XorrisO *xorriso, void *boss_iter,
3952
char *disk_path, char *img_path,
3953
off_t offset, off_t cut_size, int flag)
3956
char path[SfileadrL], *apt, *npt, *cpt, sfe[5*SfileadrL], sfe2[5*SfileadrL];
3957
char *disk_path_pt, resolved_disk_path[SfileadrL];
3960
int done= 0, is_dir= 0, l, ret, target_is_dir, source_is_dir, resolve_link= 0;
3961
int target_is_split;
3964
ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&4));
3968
return(3*!!(flag&16));
3970
for(cpt= img_path; 1; cpt++) {
3971
cpt= strstr(cpt,"/.");
3975
if(cpt[3]=='/' || cpt[3]==0)
3977
} else if(cpt[2]=='/' || cpt[2]==0)
3981
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
3982
sprintf(xorriso->info_text,
3983
"Unsupported relative addressing in iso_rr_path %s (disk: %s)",
3984
Text_shellsafe(img_path, sfe, 0), Text_shellsafe(disk_path, sfe2, 0));
3985
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
3989
ret= Xorriso_get_volume(xorriso, &volume, 0);
3993
strncpy(path, img_path, sizeof(path)-1);
3994
path[sizeof(path)-1]= 0;
3998
ret= lstat(disk_path, &stbuf);
4000
if(S_ISDIR(stbuf.st_mode))
4002
else if((stbuf.st_mode&S_IFMT)==S_IFLNK &&
4003
(xorriso->do_follow_links ||
4004
(xorriso->do_follow_param && !(flag&4)))) {
4006
ret= stat(disk_path, &stbuf);
4008
if(S_ISDIR(stbuf.st_mode))
4014
Xorriso_process_msg_queues(xorriso,0);
4015
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
4016
sprintf(xorriso->info_text,
4017
"Cannot determine attributes of source file %s",
4018
Text_shellsafe(disk_path, sfe, 0));
4019
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
4022
if(S_ISDIR(stbuf.st_mode)) {
4025
l= strlen(img_path);
4027
if(img_path[l-1]=='/')
4030
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
4031
sprintf(xorriso->info_text,
4032
"Source %s is not a directory. Target %s would be.",
4033
Text_shellsafe(disk_path, sfe, 0), Text_shellsafe(img_path, sfe2, 0));
4034
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4040
dir= iso_image_get_root(volume);
4042
Xorriso_process_msg_queues(xorriso,0);
4043
sprintf(xorriso->info_text,
4044
"While grafting '%s' : no root node available", img_path);
4045
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
4048
for(npt= apt; !done; apt= npt+1) {
4049
npt= strchr(apt, '/');
4051
npt= apt+strlen(apt);
4062
source_is_dir= (is_dir || (flag&1) || !done);
4063
ret= Xorriso_node_from_path(xorriso, volume, path, &node, 1);
4065
target_is_dir= LIBISO_ISDIR(node);
4068
if(target_is_dir && !(flag & 128))
4069
target_is_split= Xorriso_is_split(xorriso, "", (void *) node, 1 | 2);
4071
if(!((target_is_dir && !target_is_split) && source_is_dir)) {
4072
Xorriso_process_msg_queues(xorriso,0);
4074
/* handle overwrite situation */;
4075
if(xorriso->do_overwrite==1 ||
4076
(xorriso->do_overwrite==2 && !(target_is_dir && !target_is_split))) {
4077
ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, path,
4078
1 | 8 | (flag & 64));
4082
sprintf(xorriso->info_text, "User revoked adding of: %s",
4083
Text_shellsafe(disk_path, sfe, 0));
4084
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
4085
return(3*!!(flag&16));
4088
goto handle_path_node;
4091
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
4092
sprintf(xorriso->info_text,
4093
"While grafting '%s' : '%s' exists and may not be overwritten",
4095
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4098
dir= (IsoDir *) node;
4102
if(node==NULL && source_is_dir) { /* make a directory */
4103
ret= iso_tree_add_new_dir(dir, apt, &hdir);
4105
Xorriso_process_msg_queues(xorriso,0);
4106
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
4107
Xorriso_report_iso_error(xorriso, img_path, ret,
4108
"Cannot create directory", 0, "FAILURE", 1);
4109
sprintf(xorriso->info_text,
4110
"While grafting '%s' : could not insert '%s'", img_path, path);
4111
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4115
Xorriso_set_change_pending(xorriso, 0);
4116
iso_node_set_ctime((IsoNode *) dir, time(NULL));
4117
iso_node_set_uid((IsoNode *) dir, geteuid());
4118
iso_node_set_gid((IsoNode *) dir, getegid());
4120
if(disk_path!=NULL && !done)
4121
Xorriso_copy_implicit_properties(xorriso, dir, img_path, path, disk_path,
4128
/* directory node was created above */;
4131
Xorriso_transfer_properties(xorriso, &stbuf, disk_path,
4132
(IsoNode *) dir, 4 | 32);
4134
ret= Xorriso_add_tree(xorriso, dir, img_path, disk_path, NULL,
4135
flag & (2 | 64 | 128));
4141
ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0);
4144
disk_path_pt= resolved_disk_path;
4146
disk_path_pt= disk_path;
4148
ret= Xorriso_tree_graft_node(xorriso, volume, dir, disk_path_pt, apt,
4149
disk_path, img_path,
4150
offset, cut_size, &node, flag&8);
4152
sprintf(xorriso->info_text, "Grafting failed: %s = %s",
4153
Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0));
4154
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4157
Xorriso_set_change_pending(xorriso, 0);
4158
iso_node_set_name(node, apt);
4160
xorriso->pacifier_count++;
4161
if(xorriso->pacifier_count%100 && !(flag&2))
4162
Xorriso_pacifier_callback(xorriso, "files added",
4163
xorriso->pacifier_count,
4164
xorriso->pacifier_total, "", 0);
4169
Xorriso_process_msg_queues(xorriso,0);
4174
/* @param flag bit0= -follow: disk_path is not a command parameter
4176
int Xorriso_cut_out(struct XorrisO *xorriso, char *disk_path,
4177
off_t startbyte, off_t bytecount, char *iso_rr_path, int flag)
4180
char eff_source[SfileadrL], eff_dest[SfileadrL], sfe[SfileadrL*5];
4183
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_source,
4187
ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&1));
4191
if(lstat(eff_source, &stbuf)==-1) {
4192
Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0);
4193
sprintf(xorriso->info_text, "-cut_out: Cannot determine type of %s",
4194
Text_shellsafe(eff_source, sfe, 0));
4195
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
4199
if((stbuf.st_mode&S_IFMT) == S_IFLNK) {
4200
if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1))))
4201
goto unsupported_type;
4202
if(stat(eff_source, &stbuf)==-1) {
4203
Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0);
4204
sprintf(xorriso->info_text,
4205
"-cut_out: Cannot determine link target type of %s",
4206
Text_shellsafe(eff_source, sfe, 0));
4207
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
4211
if(S_ISREG(stbuf.st_mode)) {
4212
if(stbuf.st_size<startbyte) {
4213
Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0);
4214
sprintf(xorriso->info_text,
4215
"-cut_out: Byte offset %.f larger than file size %.f",
4216
(double) startbyte, (double) stbuf.st_size);
4217
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "SORRY", 0);
4222
Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0);
4223
sprintf(xorriso->info_text, "-cut_out: Unsupported file type (%s) with %s",
4224
Ftypetxt(stbuf.st_mode, 0), Text_shellsafe(eff_source, sfe, 0));
4225
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
4229
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, iso_rr_path, eff_dest,
4234
ret= Xorriso_graft_in(xorriso, NULL, eff_source, eff_dest,
4235
startbyte, bytecount, 8);
4240
/* @param flag bit0= in_node is valid, do not resolve img_path
4241
bit1= test mode: print DEBUG messages
4243
0 = surely not identical regular files ,
4244
1 = surely identical
4245
2 = potentially depending on unknown disk file (e.g. -cut_out)
4247
int Xorriso_restore_is_identical(struct XorrisO *xorriso, void *in_node,
4248
char *img_path, char *disk_path,
4249
char type_text[5], int flag)
4261
memset(type_text, 0, 5);
4262
if(!xorriso->volset_change_pending)
4265
node= (IsoNode *) in_node;
4267
ret= Xorriso_get_volume(xorriso, &volume, 0);
4270
ret= Xorriso_node_from_path(xorriso, volume, img_path, &node, 1);
4274
ret= Xorriso__file_start_lba(node, &dummy, 0);
4276
Xorriso_process_msg_queues(xorriso, 0);
4279
if(!LIBISO_ISREG(node))
4281
stream= iso_file_get_stream((IsoFile *) node);
4282
memcpy(type_text, stream->class->type, 4);
4283
iso_stream_get_id(stream, &fs_id, &dev_id, &ino_id);
4285
sprintf(xorriso->info_text, "%s : fs=%d dev=%.f ino=%.f (%s)",
4286
img_path, fs_id, (double) dev_id, (double) ino_id, type_text);
4287
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
4289
ret= stat(disk_path, &stbuf);
4293
sprintf(xorriso->info_text, "%s : dev=%.f ino=%.f",
4294
disk_path, (double) stbuf.st_dev, (double) stbuf.st_ino);
4295
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
4300
/* >>> obtain underlying dev_t ino_t of type "cout" */;
4302
if(strcmp(type_text, "fsrc")!=0)
4304
if(stbuf.st_dev==dev_id && stbuf.st_ino==ino_id)
4310
/* @param flag bit0= minimal transfer: access permissions only
4311
bit1= keep directory open: keep owner, allow rwx for owner
4312
and push directory onto xorriso->perm_stack
4314
int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path,
4315
IsoNode *node, int flag)
4321
struct utimbuf utime_buffer;
4322
char sfe[5*SfileadrL];
4324
size_t num_attrs= 0, *value_lengths= NULL;
4325
char **names= NULL, **values= NULL;
4327
ret= lstat(disk_path, &stbuf);
4329
sprintf(xorriso->info_text,
4330
"Cannot obtain properties of disk file %s",
4331
Text_shellsafe(disk_path, sfe, 0));
4332
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
4337
is_dir= S_ISDIR(stbuf.st_mode);
4339
mode= iso_node_get_permissions(node);
4341
if(xorriso->do_aaip & (2 | 8 | 16)) {
4342
ret= iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values,
4343
(!!(xorriso->do_aaip & 2)) | (!(xorriso->do_aaip & (8 | 16))) << 2);
4345
strcpy(xorriso->info_text, "Error with obtaining ACL and xattr for ");
4346
Text_shellsafe(disk_path, xorriso->info_text, 1);
4347
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4351
ret= iso_local_set_attrs(disk_path, num_attrs, names, value_lengths,
4354
sprintf(xorriso->info_text,
4355
"Cannot change ACL or xattr of disk file %s",
4356
Text_shellsafe(disk_path, sfe, 0));
4357
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
4361
Xorriso_process_msg_queues(xorriso,0);
4363
if(!(xorriso->do_aaip & 2))
4364
mode= iso_node_get_perms_wo_acl(node);
4366
if(is_dir && (flag&2)) {
4367
ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node,
4368
1 | ((!!(xorriso->do_aaip & 2)) << 3));
4371
ret= Permstack_push(&(xorriso->perm_stack), disk_path, &stbuf, 0);
4373
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
4374
strcpy(xorriso->info_text,
4375
"Cannot memorize permissions for disk directory");
4376
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
4379
mode|= S_IRUSR|S_IWUSR|S_IXUSR;
4381
ret= chmod(disk_path, mode);
4383
sprintf(xorriso->info_text,
4384
"Cannot change access permissions of disk file %s",
4385
Text_shellsafe(disk_path, sfe, 0));
4386
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
4393
gid= iso_node_get_gid(node);
4394
if(!(S_ISDIR(stbuf.st_mode) && (flag&2)))
4395
uid= iso_node_get_uid(node);
4396
chown(disk_path, uid, gid); /* don't complain if it fails */
4397
utime_buffer.actime= iso_node_get_atime(node);
4398
utime_buffer.modtime= iso_node_get_mtime(node);
4399
ret= utime(disk_path,&utime_buffer);
4401
sprintf(xorriso->info_text,
4402
"Cannot change atime, mtime of disk file %s",
4403
Text_shellsafe(disk_path, sfe, 0));
4404
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
4409
iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values,1 << 15);
4415
bit1= minimal transfer: access permissions only
4416
bit2= keep directory open: keep owner, allow rwx for owner
4417
push to xorriso->perm_stack
4419
int Xorriso_restore_implicit_properties(struct XorrisO *xorriso,
4420
char *full_disk_path, char *disk_path, char *full_img_path, int flag)
4422
int ret, nfic, ndc, nfdc, d, i;
4423
char nfi[SfileadrL], nd[SfileadrL], nfd[SfileadrL], *cpt;
4424
char sfe[5*SfileadrL];
4428
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, full_disk_path, nfd,
4432
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, nd, 1|2);
4435
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, full_img_path, nfi,
4439
nfdc= Sfile_count_components(nfd, 0);
4440
ndc= Sfile_count_components(nd, 0);
4441
nfic= Sfile_count_components(nfi, 0);
4447
for(i= 0; i<d; i++) {
4448
cpt= strrchr(nfi, '/');
4450
return(-1); /* should not happen */
4455
ret= Xorriso_fake_stbuf(xorriso, nfi, &stbuf, &node, 0);
4458
ret= Xorriso_restore_properties(xorriso, nd, node, ((flag>>1)&3));
4461
sprintf(xorriso->info_text,
4462
"Restored properties for %s", Text_shellsafe(nd, sfe, 0));
4463
sprintf(xorriso->info_text+strlen(xorriso->info_text),
4464
" from %s", Text_shellsafe(nfi, sfe, 0));
4465
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
4470
int Xorriso_is_plain_image_file(struct XorrisO *xorriso, void *in_node,
4471
char *path, int flag)
4477
node= (IsoNode *) in_node;
4479
ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
4484
ret= Xorriso__file_start_lba(node, &lba, 0);
4485
if(ret > 0) { /* Stream source is from loaded image */
4486
stream= iso_file_get_stream((IsoFile *) node);
4488
if(iso_stream_get_input_stream(stream, 0) == NULL)
4495
/* @param flag bit0= Minimal transfer: access permissions only
4496
bit1= *_offset and bytes are valid for writing to regular file
4497
bit2= This is not a parameter. Do not report if ignored
4498
bit3= do not restore properties
4499
bit4= issue pacifier messages with long lasting copying
4500
bit7= return 4 if restore fails from denied permission
4501
do not issue error message
4502
@return <0 severe error , 0 failure , 1 success ,
4503
2 regularly not installed (disallowed device, UNIX domain socket)
4504
4 with bit7: permission to restore was denied
4506
int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
4507
char *img_path, off_t img_offset,
4508
char *disk_path, off_t disk_offset, off_t bytes,
4511
int ret= 0, write_fd= -1, wanted, wret, open_flags, l_errno= 0;
4512
int target_deleted= 0;
4513
char *what= "[unknown filetype]", sfe[5*SfileadrL], sfe2[5*SfileadrL];
4514
char buf[32*1024], type_text[5], temp_path[SfileadrL], *buf_pt;
4515
char *link_target, *open_path_pt= NULL;
4516
off_t todo= 0, size, seek_ret, last_p_count= 0, already_done, read_count= 0;
4517
void *data_stream= NULL;
4521
struct utimbuf utime_buffer;
4523
if(LIBISO_ISDIR(node)) {
4525
ret= mkdir(disk_path, 0777);
4528
} else if(LIBISO_ISREG(node)) {
4529
what= "regular file";
4530
ret= Xorriso_iso_file_open(xorriso, img_path, (void *) node, &data_stream,
4534
open_path_pt= disk_path;
4535
ret= stat(open_path_pt, &stbuf);
4536
if(ret == -1 && errno == EACCES && (flag & 128))
4539
if(ret!=-1 && !S_ISREG(stbuf.st_mode)) {
4540
sprintf(xorriso->info_text,
4541
"Restore offset demanded. But filesystem path leads to non-data file %s",
4542
Text_shellsafe(disk_path, sfe, 0));
4543
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
4545
goto cannot_restore;
4548
/* If source and target are the same disk file then do not copy content */
4549
ret= Xorriso_restore_is_identical(xorriso, (void *) node, img_path,
4550
disk_path, type_text, 1);
4554
/* preliminarily emulate touch (might get overridden later) */
4555
utime_buffer.actime= stbuf.st_atime;
4556
utime_buffer.modtime= time(0);
4557
utime(disk_path,&utime_buffer);
4558
goto restore_properties;
4561
/* Extract to temporary file and rename only after copying */
4562
ret= Xorriso_make_tmp_path(xorriso, disk_path, temp_path, &write_fd,
4564
if(ret <= 0 || ret == 4)
4566
open_path_pt= temp_path;
4570
open_flags= O_WRONLY|O_CREAT;
4571
if(disk_offset==0 || !(flag&2))
4572
open_flags|= O_EXCL;
4573
write_fd= open(open_path_pt, open_flags, S_IRUSR|S_IWUSR);
4575
if(write_fd == -1 && errno == EACCES && (flag & 128))
4578
goto cannot_restore;
4580
todo= size= iso_file_get_size((IsoFile *) node);
4584
seek_ret= lseek(write_fd, disk_offset, SEEK_SET);
4586
if(seek_ret == -1) {
4587
sprintf(xorriso->info_text,
4588
"Cannot address byte %.f in filesystem path %s",
4589
(double) disk_offset, Text_shellsafe(open_path_pt, sfe, 0));
4590
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
4591
goto cannot_restore;
4595
wanted= sizeof(buf);
4598
ret= Xorriso_iso_file_read(xorriso, data_stream, buf, wanted, 0);
4600
if(xorriso->extract_error_mode == 0 &&
4601
Xorriso_is_plain_image_file(xorriso, node, "", 0)) {
4604
already_done= (size - todo) / (off_t) 2048;
4605
already_done*= (off_t) 2048;
4606
sprintf(xorriso->info_text,
4607
"Starting best_effort handling on ISO file %s at byte %.f",
4608
Text_shellsafe(img_path, sfe, 0), (double) already_done);
4609
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
4610
ret= Xorriso_read_file_data(xorriso, node, img_path, open_path_pt,
4611
already_done, already_done, size - already_done, 2);
4613
xorriso->pacifier_byte_count+= todo;
4620
sprintf(xorriso->info_text, "Cannot read all bytes from ISO file %s",
4621
Text_shellsafe(img_path, sfe, 0));
4622
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4629
if(img_offset > read_count - ret) {
4630
/* skip the desired amount of bytes */
4631
if(read_count <= img_offset)
4633
buf_pt= buf + (img_offset - (read_count - ret));
4634
ret= read_count - img_offset;
4637
wret= write(write_fd, buf_pt, ret);
4640
xorriso->pacifier_byte_count+= wret;
4642
xorriso->pacifier_byte_count - last_p_count >= 128*1024) {
4643
Xorriso_pacifier_callback(xorriso, "files restored",
4644
xorriso->pacifier_count,
4645
xorriso->pacifier_total, "", 2|4);
4646
last_p_count= xorriso->pacifier_byte_count;
4650
sprintf(xorriso->info_text,
4651
"Cannot write all bytes to disk filesystem path %s",
4652
Text_shellsafe(open_path_pt, sfe, 0));
4653
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
4660
if(todo > 0 && xorriso->extract_error_mode == 2 && open_path_pt != NULL) {
4661
unlink(open_path_pt);
4664
Xorriso_iso_file_close(xorriso, &data_stream, 0);
4666
if(temp_path==open_path_pt && !target_deleted) {
4667
ret= rename(temp_path, disk_path);
4669
sprintf(xorriso->info_text,
4670
"Cannot rename temporary path %s to final disk path %s",
4671
Text_shellsafe(temp_path, sfe, 0),
4672
Text_shellsafe(disk_path, sfe2, 0));
4673
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
4681
} else if(LIBISO_ISLNK(node)) {
4682
what= "symbolic link";
4683
link_target= (char *) iso_symlink_get_dest((IsoSymlink *) node);
4684
ret= symlink(link_target, disk_path);
4687
} else if(LIBISO_ISCHR(node)) {
4688
what= "character device";
4689
if(xorriso->allow_restore!=2) {
4692
sprintf(xorriso->info_text, "Ignored file type: %s %s = %s", what,
4693
Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0));
4694
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
4698
mode= S_IFCHR | 0777;
4699
ret= Xorriso_node_get_dev(xorriso, node, img_path, &dev, 0);
4702
if(dev == (dev_t) 1) {
4704
sprintf(xorriso->info_text,
4705
"Most probably damaged device file not restored: mknod %s %s 0 1",
4706
Text_shellsafe(disk_path, sfe, 0), LIBISO_ISCHR(node) ? "c" : "b");
4707
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
4710
ret= mknod(disk_path, mode, dev);
4713
} else if(LIBISO_ISBLK(node)) {
4714
what= "block device";
4715
if(xorriso->allow_restore!=2)
4717
mode= S_IFBLK | 0777;
4718
ret= Xorriso_node_get_dev(xorriso, node, img_path, &dev, 0);
4721
if(dev == (dev_t) 1)
4722
goto probably_damaged;
4723
ret= mknod(disk_path, mode, dev);
4726
} else if(LIBISO_ISFIFO(node)) {
4728
mode= S_IFIFO | 0777;
4729
ret= mknod(disk_path, mode, dev);
4732
} else if(LIBISO_ISSOCK(node)) {
4733
what= "unix socket";
4734
/* Restoring a socket file is not possible. One rather needs to restart
4735
the service which temporarily created the socket. */
4739
sprintf(xorriso->info_text, "Cannot restore file type '%s'", what);
4740
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
4743
if(ret == -1 && l_errno == EACCES && (flag & 128))
4747
sprintf(xorriso->info_text,
4748
"Cannot restore %s to disk filesystem: %s",
4749
what, Text_shellsafe(img_path, sfe, 0));
4750
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, l_errno, "FAILURE", 0);
4754
restore_properties:;
4755
if((flag&8) || LIBISO_ISLNK(node))
4758
ret= Xorriso_restore_properties(xorriso, disk_path, node, flag&1);
4764
if(ret <= 0 && xorriso->extract_error_mode == 2 && open_path_pt != NULL)
4765
unlink(open_path_pt);
4767
if(data_stream!=NULL)
4768
Xorriso_iso_file_close(xorriso, &data_stream, 0);
4773
/* Handle overwrite situation in disk filesystem.
4774
@param node intended source of overwriting or NULL
4776
bit4= return 3 on rejection by exclusion or user
4777
bit6= permission to call Xorriso_make_accessible()
4779
int Xorriso_restore_overwrite(struct XorrisO *xorriso,
4780
IsoNode *node, char *img_path,
4781
char *path, char *nominal_path,
4782
struct stat *stbuf, int flag)
4785
char sfe[5*SfileadrL], sfe2[5*SfileadrL], type_text[5];
4787
Xorriso_process_msg_queues(xorriso,0);
4788
if(xorriso->do_overwrite==1 ||
4789
(xorriso->do_overwrite==2 && !S_ISDIR(stbuf->st_mode))) {
4791
ret= Xorriso_restore_is_identical(xorriso, (void *) node, img_path,
4792
path, type_text, (node!=NULL));
4795
if(ret>0) /* will be handled properly by restore functions */
4796
ret= Xorriso_reassure_restore(xorriso, path, 8);
4798
ret= Xorriso_rmx(xorriso, (off_t) 0, path, 8 | (flag & 64));
4802
sprintf(xorriso->info_text, "User revoked restoring of (ISO) file: %s",
4803
Text_shellsafe(img_path, sfe, 0));
4804
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
4805
return(3*!!(flag&16));
4809
Xorriso_msgs_submit(xorriso, 0, nominal_path, 0, "ERRFILE", 0);
4810
sprintf(xorriso->info_text,
4811
"While restoring %s : %s exists and may not be overwritten",
4812
Text_shellsafe(nominal_path, sfe, 0), strcmp(nominal_path, path)==0 ?
4813
"file object" : Text_shellsafe(path, sfe2, 0));
4814
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4819
/* @param flag bit0= do not accept hln_targets[i] != NULL as *node_idx
4820
bit1= use *node_idx as found index rather than searching it
4821
bit2= with bit1: use xorriso->node_array rather than hln_array
4823
int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node,
4824
int *node_idx, int *min_hl, int *max_hl, int flag)
4826
int idx, ret, i, node_count;
4827
void *np, **node_array;
4829
node_array= xorriso->hln_array;
4830
node_count= xorriso->hln_count;
4831
*min_hl= *max_hl= -1;
4836
node_array= xorriso->node_array;
4837
node_count= xorriso->node_counter;
4841
ret= Xorriso_search_in_hln_array(xorriso, np, &idx, 0);
4845
for(i= idx - 1; i >= 0 ; i--)
4846
if(Xorriso__findi_sorted_ino_cmp(&(node_array[i]), &np) != 0)
4849
for(i= idx + 1; i < node_count; i++)
4850
if(Xorriso__findi_sorted_ino_cmp(&(node_array[i]), &np) != 0)
4854
/* Search for *node_idx */
4857
for(i= *min_hl; i <= *max_hl; i++)
4858
if(node_array[i] == np) {
4859
if((flag & 1) && xorriso->hln_targets != NULL && !(flag & 4))
4860
if(xorriso->hln_targets[i] != NULL)
4871
bit0= hardlink created
4872
bit1= siblings with target NULL found
4873
bit2= siblings with non-NULL target found
4875
int Xorriso_restore_target_hl(struct XorrisO *xorriso, IsoNode *node,
4876
char *disk_path, int *node_idx, int flag)
4878
int ret, min_hl, max_hl, i, null_target_sibling= 0, link_sibling= 0;
4880
if(xorriso->hln_targets == NULL)
4882
ret= Xorriso_search_hardlinks(xorriso, node, node_idx, &min_hl, &max_hl, 1);
4885
if(ret == 0 || *node_idx < 0 || min_hl == max_hl)
4887
for(i= min_hl; i <= max_hl; i++) {
4888
if(xorriso->hln_targets[i] == NULL) {
4890
null_target_sibling= 1;
4894
ret= Xorriso_restore_make_hl(xorriso, xorriso->hln_targets[i], disk_path,
4895
!!xorriso->do_auto_chmod);
4899
return((null_target_sibling << 1) | (link_sibling << 2));
4905
bit0= hardlink created
4906
bit2= siblings lower index found
4908
int Xorriso_restore_prefix_hl(struct XorrisO *xorriso, IsoNode *node,
4909
char *disk_path, int node_idx, int flag)
4911
int ret, min_hl, max_hl, i, link_sibling= 0, hflag;
4912
char old_path[SfileadrL], img_path[SfileadrL];
4913
struct Xorriso_lsT *img_prefixes= NULL, *disk_prefixes= NULL;
4915
ret= Xorriso_search_hardlinks(xorriso, node, &node_idx, &min_hl, &max_hl,
4919
if(ret == 0 || min_hl == max_hl)
4922
for(i= min_hl; i < node_idx; i++) {
4924
ret= Xorriso_path_from_node(xorriso, xorriso->node_array[i], img_path, 0);
4928
continue; /* Node is deleted from tree (Should not happen here) */
4932
} else if(xorriso->node_array[i] != xorriso->node_array[i - 1]) {
4936
img_prefixes= xorriso->node_img_prefixes;
4937
disk_prefixes= xorriso->node_disk_prefixes;
4939
ret= Xorriso_make_restore_path(xorriso, &img_prefixes, &disk_prefixes,
4940
img_path, old_path, hflag);
4943
ret= Xorriso_restore_make_hl(xorriso, old_path, disk_path,
4944
!!xorriso->do_auto_chmod);
4948
return(link_sibling << 2);
4952
/* @return <0 = error , 0 = availmem exhausted first time , 1 = ok
4953
2 = availmem exhausted repeated
4955
int Xorriso_register_node_target(struct XorrisO *xorriso, int node_idx,
4956
char *disk_path, int flag)
4960
if(xorriso->node_targets_availmem == 0)
4962
if(xorriso->hln_targets == NULL || node_idx < 0 ||
4963
node_idx >= xorriso->hln_count)
4965
if(xorriso->hln_targets[node_idx] != NULL) {
4966
xorriso->node_targets_availmem+= strlen(xorriso->hln_targets[node_idx]) +1;
4967
free(xorriso->hln_targets[node_idx]);
4969
l= strlen(disk_path);
4970
if(xorriso->node_targets_availmem <= l + 1) {
4971
sprintf(xorriso->info_text,
4972
"Hardlink target buffer exceeds -temp_mem_limit. Hardlinks may get divided.");
4973
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4974
xorriso->node_targets_availmem= 0;
4977
xorriso->hln_targets[node_idx]= strdup(disk_path);
4978
if(xorriso->hln_targets[node_idx] == NULL) {
4979
Xorriso_no_malloc_memory(xorriso, NULL, 0);
4982
xorriso->node_targets_availmem-= (l + 1);
4988
@param flag bit0= offset and bytes is valid for writing to regular file
4989
bit1= do not report copied files
4990
bit2= -follow, -not_*: this is not a command parameter
4991
bit3= keep directory open: keep owner, allow rwx for owner
4992
bit4= do not look for hardlinks even if enabled
4993
bit6= this is a copy action: do not fake times and ownership
4994
bit7= return 4 if restore fails from denied permission
4995
do not issue error message
4996
@return <=0 = error , 1 = added leaf file object , 2 = added directory ,
4997
3= regularly not installed (disallowed device, UNIX domain socket)
4998
4 = with bit7: permission to restore was denied
5000
int Xorriso_restore_disk_object(struct XorrisO *xorriso,
5001
char *img_path, IsoNode *node,
5003
off_t offset, off_t bytes, int flag)
5005
int ret, i, split_count= 0, partno, total_parts, leaf_is_split= 0;
5006
int record_hl_path= 0, node_idx, cannot_register= 0;
5007
off_t total_bytes, was_byte_count;
5008
char *part_name, part_path[SfileadrL], *img_path_pt;
5009
char sfe[5*SfileadrL], sfe2[5*SfileadrL];
5011
IsoNode *part_node, *first_part_node= NULL;
5012
struct SplitparT *split_parts= NULL;
5015
ret= Xorriso_get_volume(xorriso, &volume, 0);
5019
was_byte_count= xorriso->pacifier_byte_count;
5021
if(LIBISO_ISDIR(node) && xorriso->do_concat_split)
5022
leaf_is_split= Xorriso_identify_split(xorriso, img_path, node,
5023
&split_parts, &split_count, &stbuf, 1|2);
5025
/* map all files in directory img_path into regular file disk_path */
5027
for(i=0 ; i<split_count; i++) {
5028
Splitparts_get(split_parts, i, &part_name, &partno, &total_parts,
5029
&offset, &bytes, &total_bytes, 0);
5031
strcpy(part_path, img_path);
5032
if(Sfile_add_to_path(part_path, part_name, 0)<=0) {
5033
Xorriso_much_too_long(xorriso, strlen(img_path)+strlen(part_name)+1, 2);
5034
goto restoring_failed;
5036
ret= Xorriso_node_from_path(xorriso, volume, part_path, &part_node, 0);
5038
goto restoring_failed;
5040
first_part_node= part_node;
5041
if(offset+bytes>total_bytes)
5042
bytes= total_bytes-offset;
5043
ret= Xorriso_tree_restore_node(xorriso, part_node, part_path, (off_t) 0,
5044
disk_path, offset, bytes,
5045
(!!(flag&64)) | 2 | (flag & (4 | 128)) | 8 | ( 16 * !(flag&2)));
5047
goto restoring_failed;
5051
if(first_part_node!=NULL)
5052
Xorriso_restore_properties(xorriso, disk_path, first_part_node,
5057
#ifdef Osirrox_not_yeT
5060
ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0);
5063
disk_path_pt= resolved_disk_path;
5066
#endif /* Osirrox_not_yeT */
5068
img_path_pt= img_path;
5070
if(!((xorriso->ino_behavior & 4) || (flag & (1 | 16)) || LIBISO_ISDIR(node))){
5071
/* Try to restore as hardlink */
5072
ret= Xorriso_restore_target_hl(xorriso, node, disk_path, &node_idx,
5073
!!xorriso->do_auto_chmod);
5076
} else if(ret & 1) {
5077
/* Success, hardlink was created */
5079
} else if(ret & 2) {
5080
/* Did not establish hardlink. Hardlink siblings with target NULL found.*/
5084
/* Found siblings with non-NULL target, but did not link. */
5085
ret= Xorriso_eval_problem_status(xorriso, 1, 0);
5091
ret= Xorriso_tree_restore_node(xorriso, node, img_path_pt, (off_t) 0,
5092
disk_path, offset, bytes,
5093
(flag&(4 | 8 | 128)) | (!!(flag&64)) | ((flag&1)<<1) | ( 16 * !(flag&2)));
5096
if(ret>0 && (flag&8))
5097
ret= Xorriso_restore_properties(xorriso, disk_path, node, 2 | !!(flag&64));
5100
sprintf(xorriso->info_text, "Restoring failed: %s = %s",
5101
Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0));
5102
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
5107
if(record_hl_path) { /* Start of a disk hardlink family */
5108
ret= Xorriso_register_node_target(xorriso, node_idx, disk_path, 0);
5116
xorriso->pacifier_count++;
5118
Xorriso_pacifier_callback(xorriso, "files restored",
5119
xorriso->pacifier_count,
5120
xorriso->pacifier_total, "", 4);
5123
if(split_parts!=NULL)
5124
Splitparts_destroy(&split_parts, split_count, 0);
5125
if(ret > 0 && cannot_register)
5131
/* @param flag bit0= source is a directory and not to be restored as split file
5132
>>> bit6= permission to call Xorriso_make_accessible()
5133
@return <=0 error , 1=collision handled , 2=no collision , 3=revoked by user
5135
int Xorriso_handle_collision(struct XorrisO *xorriso,
5136
IsoNode *node, char *img_path,
5137
char *disk_path, char *nominal_disk_path,
5138
int *stbuf_ret, int flag)
5140
int ret, target_is_dir= 0, target_is_link= 0, stat_ret, made_accessible= 0;
5141
struct stat target_stbuf, lt_stbuf;
5142
struct PermiteM *perm_stack_mem;
5144
perm_stack_mem= xorriso->perm_stack;
5146
/* does a disk file exist with this name ? */
5147
*stbuf_ret= lstat(disk_path, &target_stbuf);
5148
if(*stbuf_ret==-1) {
5149
if((flag & 64) && errno == EACCES) {
5150
ret= Xorriso_make_accessible(xorriso, disk_path, 0);
5154
*stbuf_ret= lstat(disk_path, &target_stbuf);
5159
target_is_link= S_ISLNK(target_stbuf.st_mode);
5160
if(target_is_link) {
5161
stat_ret= stat(disk_path, <_stbuf);
5162
if(stat_ret == -1) {
5163
if((flag & 64) && errno == EACCES && !made_accessible) {
5164
ret= Xorriso_make_accessible(xorriso, disk_path, 0);
5168
stat_ret= stat(disk_path, <_stbuf);
5172
target_is_dir= S_ISDIR(lt_stbuf.st_mode);
5174
target_is_dir= S_ISDIR(target_stbuf.st_mode);
5176
if(target_is_dir && (!target_is_link) && !(flag&1)) {
5177
strcpy(xorriso->info_text, "Attempt to replace DISK directory ");
5178
Text_shellsafe(nominal_disk_path,
5179
xorriso->info_text+strlen(xorriso->info_text), 0);
5180
strcat(xorriso->info_text, " by ISO file ");
5181
Text_shellsafe(img_path, xorriso->info_text+strlen(xorriso->info_text), 0);
5182
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
5186
if(!(target_is_dir && (flag&1))) {
5187
Xorriso_process_msg_queues(xorriso,0);
5188
ret= Xorriso_restore_overwrite(xorriso, node, img_path, disk_path,
5189
nominal_disk_path, &target_stbuf, 16 | (flag & 64));
5194
*stbuf_ret= -1; /* It might still exist but will be handled properly */
5199
Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0);
5204
/* @param flag bit0= recursion is active
5205
bit1= do not report restored files
5206
bit6= this is a copy action: do not fake times and ownership
5207
bit8= only register non-directory nodes in xorriso->node_array
5210
1= create only directories,
5211
count nodes in xorriso->node_counter
5212
2= only register non-directory nodes in
5214
3= count nodes in xorriso->node_counter,
5217
int Xorriso_restore_tree(struct XorrisO *xorriso, IsoDir *dir,
5218
char *img_dir_path, char *disk_dir_path,
5220
struct LinkiteM *link_stack, int flag)
5224
IsoDirIter *iter= NULL;
5225
IsoNode **node_array= NULL;
5226
int node_count, node_idx;
5227
int ret, source_is_dir, source_is_link, fret, was_failure= 0;
5228
int do_not_dive, source_is_split= 0, len_dp, len_ip, stbuf_ret, hflag, hret;
5229
char *name, *disk_name, *leaf_name, *srcpt, *stbuf_src= "";
5230
struct LinkiteM *own_link_stack;
5231
char *sfe= NULL, *sfe2= NULL;
5232
char *disk_path= NULL, *img_path= NULL, *link_target= NULL;
5234
struct PermiteM *perm_stack_mem;
5236
int dir_create= 0, node_register= 0, do_node_count= 0, normal_mode= 0;
5238
perm_stack_mem= xorriso->perm_stack;
5239
switch((flag >> 7) & 3) {
5240
case 0: normal_mode= 1;
5241
break; case 1: dir_create= 1;
5242
break; case 2: node_register= 1;
5243
break; case 3: do_node_count= 1;
5246
/* Avoiding large local memory objects in order to save stack space */
5247
sfe= malloc(5*SfileadrL);
5248
sfe2= malloc(5*SfileadrL);
5249
disk_path= malloc(2*SfileadrL);
5250
img_path= malloc(2*SfileadrL);
5251
link_target= malloc(SfileadrL);
5252
if(sfe==NULL || sfe2==NULL || disk_path==NULL || img_path==NULL ||
5253
link_target==NULL) {
5254
Xorriso_no_malloc_memory(xorriso, &sfe, 0);
5258
own_link_stack= link_stack;
5260
ret= Xorriso_get_volume(xorriso, &volume, 0);
5264
stbuf_src= img_dir_path;
5265
node= (IsoNode *) dir;
5266
ret= Xorriso_fake_stbuf(xorriso, stbuf_src, &stbuf, &node, 1);
5268
Xorriso_msgs_submit(xorriso, 0, disk_dir_path, 0, "ERRFILE", 0);
5269
sprintf(xorriso->info_text,"Cannot open as (ISO) source directory: %s",
5270
Text_shellsafe(img_dir_path, sfe, 0));
5271
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
5275
#ifdef Osirrox_not_yeT
5278
dir_dev= stbuf.st_dev;
5280
if(S_ISLNK(stbuf.st_mode)) {
5281
if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1))))
5283
stbuf_src= disk_dir_path;
5284
if(stat(disk_dir_path, &stbuf)==-1)
5285
goto cannot_open_dir;
5286
if(dir_dev != stbuf.st_dev &&
5287
!(xorriso->do_follow_mount || (xorriso->do_follow_param && !(flag&1))))
5291
#endif /* Osirrox_not_yeT */
5293
if(!S_ISDIR(stbuf.st_mode)) {
5294
Xorriso_msgs_submit(xorriso, 0, disk_dir_path, 0, "ERRFILE", 0);
5295
sprintf(xorriso->info_text,"Is not a directory in ISO image: %s",
5296
Text_shellsafe(img_dir_path, sfe, 0));
5297
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
5302
ret= Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count,
5304
1 | 4 * (normal_mode && (xorriso->ino_behavior & 4)));
5308
if(Sfile_str(img_path, img_dir_path,0)<=0) {
5310
Xorriso_much_too_long(xorriso, SfileadrL, 2);
5313
if(img_path[0]==0 || img_path[strlen(img_path)-1]!='/')
5314
strcat(img_path,"/");
5315
name= img_path+strlen(img_path);
5316
if(Sfile_str(disk_path, disk_dir_path, 0)<=0)
5318
if(disk_path[0]==0 || disk_path[strlen(disk_path)-1]!='/')
5319
strcat(disk_path,"/");
5320
disk_name= disk_path+strlen(disk_path);
5322
len_dp= strlen(disk_path);
5323
len_ip= strlen(img_path);
5325
while(1) { /* loop over ISO directory content */
5328
#ifdef Osirrox_not_yeT
5330
Linkitem_reset_stack(&own_link_stack, link_stack, 0);
5335
Xorriso_process_msg_queues(xorriso,0);
5336
ret= Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count,
5337
&node_idx, &node, 0);
5340
if(ret==0 || xorriso->request_to_abort)
5342
leaf_name= (char *) iso_node_get_name(node);
5343
if(Xorriso_much_too_long(xorriso, len_dp + strlen(leaf_name)+1, 0)<=0)
5344
{ret= 0; goto was_problem;}
5345
if(Xorriso_much_too_long(xorriso, len_ip + strlen(leaf_name)+1, 0)<=0)
5346
{ret= 0; goto was_problem;}
5347
/* name is a pointer into img_path */
5348
strcpy(name, leaf_name);
5349
strcpy(disk_name, leaf_name);
5352
ret= Xorriso_fake_stbuf(xorriso, img_path, &stbuf, &node, 1);
5356
source_is_link= S_ISLNK(stbuf.st_mode);
5358
#ifdef Osirrox_not_yeT
5360
/* ??? Link following in the image would cause severe problems
5361
with Xorriso_path_from_node() */
5363
if(xorriso->do_follow_links && source_is_link) {
5364
/* Xorriso_hop_link checks for wide link loops */
5365
ret= Xorriso_hop_link(xorriso, srcpt, &own_link_stack, &hstbuf, 0);
5369
ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 0);
5374
if(lstat(srcpt, &stbuf)==-1)
5377
if(Xorriso_eval_problem_status(xorriso, 0, 1|2)<0)
5378
{ret= 0; goto was_problem;}
5380
} else if (S_ISLNK(stbuf.st_mode)) {
5381
ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1);
5386
#endif /* Osirrox_not_yeT */
5389
if(S_ISDIR(stbuf.st_mode))
5393
source_is_split= Xorriso_is_split(xorriso, img_path, node, 1|2);
5397
if(source_is_dir || !(dir_create || do_node_count || node_register)) {
5398
ret= Xorriso_handle_collision(xorriso, node, img_path,
5399
disk_path, disk_path, &stbuf_ret,
5400
(source_is_dir && !source_is_split));
5401
if(ret<=0 || ret==3)
5407
if(stbuf_ret!=-1) { /* (Can only happen with directory) */
5408
Xorriso_auto_chmod(xorriso, disk_path, 0);
5410
hflag= 4 | (flag & (2|64));
5411
if(source_is_dir && !do_not_dive)
5412
hflag|= 8; /* keep directory open for user */
5413
if((dir_create || do_node_count) && !source_is_dir) {
5414
xorriso->node_counter++;
5415
} else if(node_register && !source_is_dir) {
5416
if(xorriso->node_counter < xorriso->node_array_size) {
5417
xorriso->node_array[xorriso->node_counter++]= (void *) node;
5420
} else if(node_register || do_node_count) {
5423
ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path,
5424
(off_t) 0, (off_t) 0, hflag);
5429
if(source_is_dir && !do_not_dive) {
5430
ret= Xorriso_restore_tree(xorriso, (IsoDir *) node,
5431
img_path, disk_path, mem,
5432
own_link_stack, 1 | (flag & (2 | (3 << 7))));
5433
/* eventually restore exact access permissions of directory */
5434
hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso,
5436
if(hret<=0 && hret<ret)
5442
continue; /* regular bottom of loop */
5445
fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
5448
Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, !!(flag&64));
5453
Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, !!(flag&64));
5462
if(link_target!=NULL)
5464
Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count,
5465
&node_idx, &node, (1<<31));
5467
Xorriso_process_msg_queues(xorriso,0);
5469
#ifdef Osirrox_not_yeT
5471
Linkitem_reset_stack(&own_link_stack, link_stack, 0);
5477
return(!was_failure);
5483
>>> bit0= mkdir: graft in as empty directory, not as copy from iso
5484
bit1= do not report copied files
5485
bit2= -follow, -not_*: this is not a command parameter
5486
bit3= use offset and cut_size for -paste_in
5487
bit4= return 3 on rejection by exclusion or user
5488
bit5= if directory then do not add sub tree
5489
bit6= this is a copy action: do not fake times and ownership
5490
bit7+8= operation mode
5492
1= create only directories,
5493
count nodes in xorriso->node_counter
5494
2= only register non-directory nodes in
5496
3= count nodes in xorriso->node_counter,
5498
bit9= with operation mode 1 do net register prefixes
5499
@return <=0 = error , 1 = added leaf file object , 2 = added directory ,
5502
int Xorriso_restore(struct XorrisO *xorriso,
5503
char *img_path, char *disk_path,
5504
off_t offset, off_t bytes, int flag)
5507
char path[SfileadrL], *apt, *npt, sfe[5*SfileadrL];
5508
IsoNode *node= NULL;
5509
int done= 0, is_dir= 0, ret, source_is_dir, stbuf_ret, hret;
5510
int dir_create= 0, node_count= 0, node_register= 0;
5511
int leaf_is_split= 0, source_is_split= 0, new_dir_made= 0;
5513
struct PermiteM *perm_stack_mem;
5515
perm_stack_mem= xorriso->perm_stack;
5516
switch((flag >> 7) & 3) {
5517
case 1: dir_create= 1;
5518
break; case 2: node_register= 1;
5519
break; case 3: node_count= 1;
5522
if(dir_create && !(flag & (1 << 9))) {
5523
ret= Xorriso_lst_append_binary(&(xorriso->node_disk_prefixes),
5524
disk_path, strlen(disk_path) + 1, 0);
5527
ret= Xorriso_lst_append_binary(&(xorriso->node_img_prefixes),
5528
img_path, strlen(img_path) + 1, 0);
5533
ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&4));
5537
{ret= 3*!!(flag&16); goto ex;}
5539
ret= Xorriso_get_volume(xorriso, &volume, 0);
5543
strncpy(path, disk_path, sizeof(path)-1);
5544
path[sizeof(path)-1]= 0;
5548
ret= Xorriso_fake_stbuf(xorriso, img_path, &stbuf, &node, 0);
5550
if(S_ISDIR(stbuf.st_mode))
5553
#ifdef Osirrox_not_yeT
5555
/* ??? this would cause severe problems with Xorriso_path_from_node() */
5557
else if((stbuf.st_mode&S_IFMT)==S_IFLNK &&
5558
(xorriso->do_follow_links ||
5559
(xorriso->do_follow_param && !(flag&4)))) {
5561
ret= Xorriso_iso_lstat(xorriso, img_path, &stbuf, 1|2);
5563
if(S_ISDIR(stbuf.st_mode))
5567
#endif /* Osirrox_not_yeT */
5570
Xorriso_process_msg_queues(xorriso,0);
5571
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
5572
sprintf(xorriso->info_text,
5573
"Cannot determine attributes of (ISO) source file %s",
5574
Text_shellsafe(img_path, sfe, 0));
5575
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
5578
if(is_dir && xorriso->do_concat_split)
5579
leaf_is_split= Xorriso_is_split(xorriso, img_path, node, 1|2);
5581
for(npt= apt; !done; apt= npt+1) {
5582
npt= strchr(apt, '/');
5584
npt= apt+strlen(apt);
5595
source_is_dir= (is_dir || (flag&1) || !done);
5596
source_is_split= done && leaf_is_split;
5599
if((flag&8) && done) {
5601
/* ??? move down from Xorriso_paste_in() :
5602
check whether target does not exist or both are regular */;
5604
} else if(source_is_dir || !(dir_create || node_count || node_register)) {
5605
ret= Xorriso_handle_collision(xorriso, node, img_path, path, disk_path,
5606
&stbuf_ret, (source_is_dir && !source_is_split));
5607
if(ret<=0 || ret==3)
5612
if(stbuf_ret==-1 && (source_is_dir && !source_is_split) &&
5613
!(node_count || node_register)) {
5614
/* make a directory */
5615
ret= mkdir(path, 0777);
5617
Xorriso_process_msg_queues(xorriso,0);
5618
Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0);
5619
sprintf(xorriso->info_text,
5620
"While restoring '%s' : could not insert '%s'", disk_path, path);
5621
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
5625
/* keep rwx for the owner */
5626
Xorriso_restore_implicit_properties(xorriso, disk_path, path,
5630
} else if((source_is_dir && !source_is_split)) {
5631
if(!(node_count || node_register))
5632
Xorriso_auto_chmod(xorriso, path, 0);
5638
/* directory was created above */;
5640
} else if(is_dir && !source_is_split) {
5642
if(!node_register) {
5643
if(new_dir_made) /* keep open and push to Permstack */
5644
Xorriso_restore_properties(xorriso, disk_path, node,
5648
ret= Xorriso_restore_tree(xorriso, (IsoDir *) node, img_path, path,
5649
(off_t) 0, NULL, flag & (2 | 64 | (3 << 7)));
5652
if(new_dir_made && !(flag&64))
5653
/* set timestamps which Permstack_pop() will not set */
5654
Xorriso_restore_properties(xorriso, disk_path, node, 2);
5657
if(dir_create || node_count) {
5658
xorriso->node_counter++;
5659
} else if(node_register) {
5660
if(xorriso->node_counter < xorriso->node_array_size) {
5661
xorriso->node_array[xorriso->node_counter++]= (void *) node;
5665
ret= Xorriso_restore_disk_object(xorriso, img_path, node, path,
5666
offset, bytes, (flag & (2|4|64)) | !!(flag&8));
5674
Xorriso_process_msg_queues(xorriso,0);
5675
ret= 1 + (is_dir && !leaf_is_split);
5677
/* restore exact access permissions of stacked paths */
5678
hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso,
5680
if(hret<=0 && hret<ret)
5686
int Xorriso_restore_node_array(struct XorrisO *xorriso, int flag)
5688
int i, ret, was_failure= 0, fret, hflag, stbuf_ret, faulty_family= 0;
5689
struct PermiteM *perm_stack_mem;
5690
char img_path[SfileadrL], disk_path[SfileadrL];
5692
struct Xorriso_lsT *img_prefixes= NULL, *disk_prefixes= NULL;
5694
perm_stack_mem= xorriso->perm_stack;
5696
Xorriso_sort_node_array(xorriso, 0);
5699
for(i= 0; i < xorriso->node_counter; i++) {
5700
node= (IsoNode *) xorriso->node_array[i];
5701
ret= Xorriso_path_from_node(xorriso, node, img_path, 0);
5705
continue; /* Node is deleted from tree (Should not happen here) */
5709
} else if(node != xorriso->node_array[i - 1]) {
5713
img_prefixes= xorriso->node_img_prefixes;
5714
disk_prefixes= xorriso->node_disk_prefixes;
5716
ret= Xorriso_make_restore_path(xorriso, &img_prefixes, &disk_prefixes,
5717
img_path, disk_path, hflag);
5721
ret= Xorriso_handle_collision(xorriso, node, img_path, disk_path, disk_path,
5723
if(ret<=0 || ret==3)
5725
if(xorriso->hln_array != NULL && !(xorriso->ino_behavior & 16)) {
5726
/* Eventual lookup of hardlinks will be done in
5727
Xorriso_restore_disk_object() */;
5728
} else if(i > 0 && !(xorriso->ino_behavior & 4)) {
5729
if(Xorriso__findi_sorted_ino_cmp(&(xorriso->node_array[i-1]),
5730
&(xorriso->node_array[i])) == 0) {
5732
sprintf(xorriso->info_text, "Hardlinking omitted with ");
5733
Text_shellsafe(disk_path, xorriso->info_text, 1);
5734
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
5736
/* Try to install hardlink to a sibling */
5737
ret= Xorriso_restore_prefix_hl(xorriso, node, disk_path, i, 0);
5740
} else if(ret & 1) {
5741
/* Success, hardlink was created */
5742
xorriso->pacifier_count++;
5746
/* Found elder siblings, but did not link. */
5747
ret= Xorriso_eval_problem_status(xorriso, 1, 0);
5756
ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path,
5757
(off_t) 0, (off_t) 0,
5758
4 | (xorriso->ino_behavior & 16) | 128);
5762
/* Failed from lack of permission */
5763
ret= Xorriso_make_accessible(xorriso, disk_path, 0);
5766
ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path,
5767
(off_t) 0, (off_t) 0, 4 | (xorriso->ino_behavior & 16));
5770
Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0);
5773
continue; /* regular bottom of loop */
5777
fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
5780
Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0);
5784
Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0);
5789
/* @param flag bit0= -follow, -not: disk_path is not a command parameter
5791
int Xorriso_paste_in(struct XorrisO *xorriso, char *disk_path,
5792
off_t startbyte, off_t bytecount, char *iso_rr_path, int flag)
5795
char eff_source[SfileadrL], eff_dest[SfileadrL], sfe[SfileadrL*5];
5799
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_dest,
5803
ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&1));
5806
ret= stat(eff_dest, &stbuf);
5807
if(ret!=-1 && !S_ISREG(stbuf.st_mode)) {
5808
Xorriso_msgs_submit(xorriso, 0, eff_dest, 0, "ERRFILE", 0);
5809
sprintf(xorriso->info_text,
5810
"-paste_in: DISK file %s exists and is not a data file",
5811
Text_shellsafe(eff_source, sfe, 0));
5812
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
5816
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, iso_rr_path,
5820
ret= Xorriso_fake_stbuf(xorriso, eff_source, &stbuf, &node, 4);
5823
if(!S_ISREG(stbuf.st_mode)) {
5824
Xorriso_msgs_submit(xorriso, 0, eff_dest, 0, "ERRFILE", 0);
5825
sprintf(xorriso->info_text, "-paste_in: ISO file %s is not a data file",
5826
Text_shellsafe(eff_source, sfe, 0));
5827
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
5831
/* >>> eventually obtain parameters from file name */;
5833
ret= Xorriso_restore(xorriso, eff_source, eff_dest, startbyte, bytecount, 8);
5838
int Xorriso_process_msg_queues(struct XorrisO *xorriso, int flag)
5840
int ret, error_code= 0, os_errno= 0, count= 0, pass, imgid, tunneled;
5843
if(!xorriso->libs_are_started)
5845
for(pass= 0; pass< 2; pass++) {
5849
ret= iso_obtain_msgs("ALL", &error_code, &imgid,
5850
xorriso->info_text, severity);
5852
ret= burn_msgs_obtain("ALL", &error_code, xorriso->info_text, &os_errno,
5854
if((error_code>=0x00030000 && error_code<0x00040000) ||
5855
(error_code>=0x00050000 && error_code<0x00060000))
5856
tunneled= -1; /* "libisofs:" */
5857
else if(error_code>=0x00060000 && error_code<0x00070000)
5858
tunneled= 1; /* "libisoburn:" */
5863
/* <<< tunneled MISHAP from libisoburn through libburn
5864
or well known error codes of MISHAP events
5865
With libburn-0.4.4 this is not necessary */
5866
if(error_code==0x5ff73 || error_code==0x3ff73 ||
5867
error_code==0x3feb9 || error_code==0x3feb2)
5868
strcpy(severity, "MISHAP");
5869
else if(error_code==0x51001)
5870
strcpy(severity, "ERRFILE");
5872
Xorriso_msgs_submit(xorriso, error_code, xorriso->info_text, os_errno,
5873
severity, ((pass+tunneled)+1)<<2);
5877
if(xorriso->library_msg_direct_print && count>0) {
5878
sprintf(xorriso->info_text," (%d library messages repeated by xorriso)\n",
5880
Xorriso_info(xorriso, 0);
5887
bit3=report to info channel (else to result channel)
5889
int Xorriso_toc_line(struct XorrisO *xorriso, int flag)
5892
Xorriso_result(xorriso,0);
5895
strcpy(xorriso->info_text, xorriso->result_line);
5896
Xorriso_info(xorriso, 0);
5901
int Xorriso__append_boot_params(char *line, ElToritoBootImage *bootimg,
5904
unsigned int platform_id;
5906
platform_id= el_torito_get_boot_platform_id(bootimg);
5907
if(platform_id != 0)
5908
sprintf(line + strlen(line),
5909
" , platform_id=0x%-2.2X ", (unsigned int) platform_id);
5910
if(el_torito_seems_boot_info_table(bootimg, 0))
5911
sprintf(line + strlen(line), " , boot_info_table=on");
5916
/* @param flag bit0= no output if no boot record was found
5918
bit3= report to info channel (else to result channel)
5920
int Xorriso_show_boot_info(struct XorrisO *xorriso, int flag)
5922
int ret, bin_path_valid= 0,has_isolinux_mbr= 0, i, num_boots;
5923
unsigned int mbr_lba= 0;
5925
char *respt, sfe[5*SfileadrL], path[SfileadrL];
5926
unsigned char lb0[2048];
5927
struct burn_drive_info *dinfo;
5928
struct burn_drive *drive;
5929
IsoImage *image= NULL;
5930
ElToritoBootImage *bootimg, **boots = NULL;
5931
IsoFile *bootimg_node, **bootnodes = NULL;
5932
IsoBoot *bootcat_node;
5934
respt= xorriso->result_line;
5936
if(xorriso->boot_count > 0) {
5938
sprintf(respt, "Boot record : overridden by -boot_image any next\n");
5939
Xorriso_toc_line(xorriso, flag & 8);
5944
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
5945
"on attempt to print boot info", 16);
5948
image= isoburn_get_attached_image(drive);
5953
sprintf(respt, "Boot record : none\n");
5954
Xorriso_toc_line(xorriso, flag & 8);
5959
/* Using the nodes with extreme care . They might be deleted meanwhile. */
5960
ret= iso_image_get_boot_image(image, &bootimg, &bootimg_node, &bootcat_node);
5964
ret= Xorriso_path_from_lba(xorriso, NULL, xorriso->loaded_boot_bin_lba,
5968
sprintf(respt, "Boot record : El Torito");
5970
ret= Xorriso_is_isohybrid(xorriso, bootimg_node, 0);
5974
/* Load and examine potential MBR */
5975
ret= burn_read_data(drive, (off_t) 0, (char *) lb0, (off_t) 2048,
5978
has_isolinux_mbr= 1;
5979
if(lb0[510] != 0x55 || lb0[511] != 0xaa)
5980
has_isolinux_mbr= 0;
5981
mbr_lba= lb0[432] | (lb0[433] << 8) | (lb0[434] << 16) | (lb0[435] << 24);
5983
if(mbr_lba != xorriso->loaded_boot_bin_lba)
5984
has_isolinux_mbr= 0;
5985
if(has_isolinux_mbr) {
5986
for(i= 0; i < 426; i++)
5987
if(strncmp((char *) (lb0 + i), "isolinux", 8) == 0)
5990
has_isolinux_mbr= 0;
5992
for(i= 462; i < 510; i++)
5996
has_isolinux_mbr= 0;
5998
if(has_isolinux_mbr)
5999
strcat(respt, " , ISOLINUX isohybrid MBR pointing to boot image");
6001
strcat(respt, " , ISOLINUX boot image capable of isohybrid");
6003
strcat(respt, "\n");
6004
Xorriso_toc_line(xorriso, flag & 8);
6008
if(xorriso->loaded_boot_cat_path[0])
6009
sprintf(respt, "Boot catalog : %s\n",
6010
Text_shellsafe(xorriso->loaded_boot_cat_path, sfe, 0));
6012
sprintf(respt, "Boot catalog : -not-found-at-load-time-\n");
6013
Xorriso_toc_line(xorriso, flag & 8);
6016
sprintf(respt, "Boot image : %s", Text_shellsafe(path, sfe, 0));
6017
else if(xorriso->loaded_boot_bin_lba <= 0)
6018
sprintf(respt, "Boot image : -not-found-at-load-time-");
6020
sprintf(respt, "Boot image : -not-found-any-more-by-lba=%d",
6021
xorriso->loaded_boot_bin_lba);
6022
Xorriso__append_boot_params(respt, bootimg, 0);
6023
strcat(respt, "\n");
6024
Xorriso_toc_line(xorriso, flag & 8);
6026
ret= iso_image_get_all_boot_imgs(image, &num_boots, &boots, &bootnodes, 0);
6027
Xorriso_process_msg_queues(xorriso,0);
6028
if(ret == 1 && num_boots > 1) {
6029
for(i= 1; i < num_boots; i++) {
6030
ret= Xorriso_path_from_node(xorriso, (IsoNode *) bootnodes[i], path, 0);
6032
sprintf(respt, "Boot image : %s", Text_shellsafe(path, sfe, 0));
6034
sprintf(respt, "Boot image : -not-found-any-more-");
6035
Xorriso__append_boot_params(respt, boots[i], 0);
6036
strcat(respt, "\n");
6037
Xorriso_toc_line(xorriso, flag & 8);
6044
if(bootnodes != NULL);
6047
iso_image_unref(image); /* release obtained reference */
6053
bit1=report about output drive
6054
bit3=report to info channel (else to result channel)
6055
bit4=do no report failure if no drive aquired
6057
int Xorriso_media_product(struct XorrisO *xorriso, int flag)
6059
int ret, profile_no;
6060
struct burn_drive_info *dinfo;
6061
struct burn_drive *drive;
6062
char *product_id= NULL, *media_code1= NULL, *media_code2= NULL;
6063
char *book_type= NULL, *manuf= NULL, profile_name[80], *respt;
6065
respt= xorriso->result_line;
6067
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
6068
"on attempt to print media product info",
6072
ret= burn_disc_get_media_id(drive, &product_id, &media_code1, &media_code2,
6075
ret= burn_disc_get_profile(drive, &profile_no, profile_name);
6078
sprintf(respt, "Media product: %s , ", product_id);
6079
manuf= burn_guess_manufacturer(profile_no, media_code1, media_code2, 0);
6081
if(strncmp(manuf, "Unknown ", 8) == 0)
6082
sprintf(respt + strlen(respt), "(not found in manufacturer list)\n");
6084
sprintf(respt + strlen(respt), "%s\n", manuf);
6086
sprintf(respt + strlen(respt), "(error during manufacturer lookup)\n");
6090
if(book_type != NULL)
6094
Xorriso_toc_line(xorriso, flag & 8);
6096
Xorriso_process_msg_queues(xorriso,0);
6102
/* @param flag bit0=short report form
6103
bit1=report about output drive
6104
bit2=do not try to read ISO heads
6105
bit3=report to info channel (else to result channel)
6106
bit4=do no report failure if no drive aquired
6107
bit5=only report "Drive current" and "Drive type"
6108
bit6=report "Media product" with bit0
6109
bit7=only report "Drive current"
6111
int Xorriso_toc(struct XorrisO *xorriso, int flag)
6113
int num_sessions= 0, num_tracks= 0, lba= 0, nwa= -1, pmin, psec, pframe, ret;
6114
int track_count= 0, session_no, track_no, profile_no= -1, track_size;
6115
int last_track_start= 0, last_track_size= -1, num_data= 0, is_data= 0;
6116
int is_inout_drive= 0, drive_role, status, num_formats, emul_lba;
6117
int num_payload= 0, num_wasted= 0, num_nondata= 0, not_reconizable= 0;
6118
char profile_name[80],*respt,*devadr, *typetext= "";
6119
struct burn_toc_entry toc_entry;
6120
struct burn_drive_info *dinfo;
6121
struct burn_drive *drive;
6122
enum burn_disc_status s;
6124
off_t start_byte= 0, num_free= 0, size;
6126
struct isoburn_toc_disc *disc= NULL;
6127
struct isoburn_toc_session **sessions;
6128
struct isoburn_toc_track **tracks;
6129
int image_blocks= 0;
6131
struct burn_toc_entry next_toc_entry;
6133
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
6134
"on attempt to print Table Of Content",
6139
respt= xorriso->result_line;
6141
if(strcmp(xorriso->indev, xorriso->outdev)==0)
6144
devadr= xorriso->outdev;
6146
devadr= xorriso->indev;
6147
sprintf(respt, "Drive current: %s '%s'\n",
6148
(is_inout_drive ? "-dev" : (flag&2 ? "-outdev" : "-indev")),
6150
Xorriso_toc_line(xorriso, flag & 8);
6153
sprintf(respt, "Drive type : vendor '%s' product '%s' revision '%s'\n",
6154
dinfo[0].vendor, dinfo[0].product, dinfo[0].revision);
6155
if((flag & 32) | !(flag & 1))
6156
Xorriso_toc_line(xorriso, flag & 8);
6160
ret= burn_disc_get_profile(drive, &profile_no, profile_name);
6161
s= isoburn_disc_get_status(drive);
6162
if(profile_no == 0x0002 && s == BURN_DISC_EMPTY)
6164
sprintf(respt, "Media current: ");
6165
if (profile_no > 0 && ret > 0) {
6166
if (profile_name[0])
6167
sprintf(respt+strlen(respt), "%s", profile_name);
6169
sprintf(respt+strlen(respt), "%4.4Xh", profile_no);
6170
drive_role= burn_drive_get_drive_role(drive);
6172
sprintf(respt+strlen(respt), ", overwriteable");
6173
else if(drive_role==0 || drive_role==3)
6174
sprintf(respt+strlen(respt), ", sequential");
6175
strcat(respt, "\n");
6177
sprintf(respt+strlen(respt), "is not recognizable\n");
6180
Xorriso_toc_line(xorriso, flag & 8);
6182
if((flag & 64) || !(flag & 1)) {
6183
Xorriso_media_product(xorriso, flag & (2 | 8 | 16));
6184
if(xorriso->request_to_abort)
6188
sprintf(respt, "Media status : ");
6189
if (s == BURN_DISC_FULL) {
6191
sprintf(respt+strlen(respt), "is not recognizable\n");
6193
sprintf(respt+strlen(respt), "is written , is closed\n");
6194
} else if (s == BURN_DISC_APPENDABLE) {
6195
sprintf(respt+strlen(respt), "is written , is appendable\n");
6196
} else if (s == BURN_DISC_BLANK) {
6197
sprintf(respt+strlen(respt), "is blank\n");
6198
} else if (s == BURN_DISC_EMPTY)
6199
sprintf(respt+strlen(respt), "is not present\n");
6201
sprintf(respt+strlen(respt), "is not recognizable\n");
6202
Xorriso_toc_line(xorriso, flag & 8);
6204
if(s == BURN_DISC_BLANK) {
6205
sprintf(respt, "Media summary: 0 sessions, 0 data blocks, 0 data");
6206
num_free= isoburn_disc_available_space(drive, NULL);
6207
Sfile_scale((double) num_free, mem_text,5,1e4,1);
6208
sprintf(respt+strlen(respt), ", %s free\n", mem_text);
6209
Xorriso_toc_line(xorriso, flag & 8);
6211
if(s != BURN_DISC_FULL && s != BURN_DISC_APPENDABLE)
6213
if(xorriso->request_to_abort)
6217
Xorriso_show_boot_info(xorriso, 1 | (flag & 8) | ((flag & 1) << 1));
6219
disc= isoburn_toc_drive_get_disc(drive);
6221
sprintf(respt, "TOC layout : %3s , %9s , %10s\n",
6222
"Idx", "sbsector", "Size");
6224
sprintf(respt, "TOC layout : %3s , %9s , %10s , %s\n",
6225
"Idx", "sbsector", "Size", "Volume Id");
6227
Xorriso_toc_line(xorriso, flag & 8);
6230
Xorriso_process_msg_queues(xorriso,0);
6231
ret= isoburn_get_min_start_byte(drive, &start_byte, 0);
6232
nwa= start_byte / 2048;
6234
Xorriso_process_msg_queues(xorriso,0);
6237
sprintf(xorriso->info_text, "Cannot obtain Table Of Content");
6238
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
6243
typetext= "Other session";
6246
typetext= "Session ";
6248
ret= isoburn_read_iso_head(drive, 0, &image_blocks, volume_id, 1);
6250
sprintf(respt, "ISO session : %3d , %9d , %9ds , %s\n",
6251
1, 0, image_blocks, volume_id);
6255
ret= burn_disc_get_formats(drive, &status, &size, &dummy,
6257
if(ret>0 && status==BURN_FORMAT_IS_FORMATTED)
6259
sprintf(respt, "%13s: %3d , %9d , %9ds , \n",
6260
typetext, 1, 0, nwa);
6263
Xorriso_toc_line(xorriso, flag & 8);
6264
last_track_start= lba;
6265
num_payload= num_data= last_track_size= nwa;
6268
sessions= isoburn_toc_disc_get_sessions(disc, &num_sessions);
6269
for (session_no= 0; session_no<num_sessions && !(xorriso->request_to_abort);
6271
tracks= isoburn_toc_session_get_tracks(sessions[session_no], &num_tracks);
6274
for(track_no= 0; track_no<num_tracks && !(xorriso->request_to_abort);
6278
isoburn_toc_track_get_entry(tracks[track_no], &toc_entry);
6279
if (toc_entry.extensions_valid & 1) {
6280
/* DVD extension valid */
6281
lba= toc_entry.start_lba;
6282
track_size= toc_entry.track_blocks;
6284
lba= burn_msf_to_lba(toc_entry.pmin, toc_entry.psec,
6286
if(track_no==num_tracks-1) {
6287
isoburn_toc_session_get_leadout_entry(sessions[session_no],
6290
isoburn_toc_track_get_entry(tracks[track_no+1], &next_toc_entry);
6292
track_size= burn_msf_to_lba(next_toc_entry.pmin, next_toc_entry.psec,
6293
next_toc_entry.pframe) - lba;
6298
ret= isoburn_toc_track_get_emul(tracks[track_no], &emul_lba,
6299
&image_blocks, volume_id, 0);
6301
ret= isoburn_read_iso_head(drive, lba, &image_blocks, volume_id, 1);
6302
if(image_blocks > track_size) {
6303
sprintf(xorriso->info_text,
6304
"Session %d bears ISO image size %ds larger than track size %ds",
6305
session_no + 1, image_blocks, track_size);
6306
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING",
6308
image_blocks= track_size;
6311
if(ret>0 && track_no==0) {
6312
sprintf(respt, "ISO session : %3d , %9d , %9ds , %s\n",
6313
session_no+1, lba, image_blocks , volume_id);
6315
sprintf(respt, "ISO track : %3d , %9d , %9ds , %s\n",
6316
track_count, lba, image_blocks , volume_id);
6317
} else if(track_no==0) {
6318
typetext= "Other session";
6320
typetext= "Session ";
6321
sprintf(respt, "%13s: %3d , %9d , %9ds , \n",
6322
typetext, session_no+1, lba, track_size);
6324
typetext= "Other track ";
6327
sprintf(respt, "%13s: %3d , %9d , %9ds , \n",
6328
typetext, track_count, lba, track_size);
6331
Xorriso_toc_line(xorriso, flag & 8);
6333
num_payload+= lba - last_track_start;
6334
last_track_start= lba;
6335
if((toc_entry.control&7)>=4) /* data track */
6338
isoburn_toc_session_get_leadout_entry(sessions[session_no], &toc_entry);
6339
if (toc_entry.extensions_valid & 1) {
6340
lba= toc_entry.start_lba;
6341
burn_lba_to_msf(lba, &pmin, &psec, &pframe);
6343
lba= burn_msf_to_lba(pmin, psec, pframe);
6344
lba= burn_msf_to_lba(toc_entry.pmin, toc_entry.psec, toc_entry.pframe);
6346
last_track_size= lba - last_track_start;
6347
num_payload+= last_track_size;
6349
num_data+= last_track_size;
6352
if(xorriso->request_to_abort)
6354
num_wasted= lba - num_payload;
6355
num_nondata= lba - num_data;
6356
Sfile_scale(((double) num_data) * 2048.0, mem_text,5,1e4,1);
6358
sprintf(respt, "Media summary: %d session%s, %d data blocks, %s data",
6359
num_sessions, (num_sessions==1 ? "" : "s"), num_data, mem_text);
6360
num_free= isoburn_disc_available_space(drive, NULL);
6361
Sfile_scale((double) num_free, mem_text,5,1e4,1);
6362
sprintf(respt+strlen(respt), ", %s free", mem_text);
6364
sprintf(respt+strlen(respt), "\n");
6365
Xorriso_toc_line(xorriso, flag & 8);
6367
if (s==BURN_DISC_APPENDABLE && nwa!=0) {
6368
ret= isoburn_disc_track_lba_nwa(drive, NULL, 0, &lba, &nwa);
6370
sprintf(respt, "Media nwa : %ds\n", nwa);
6372
Xorriso_toc_line(xorriso, flag & 8);
6377
isoburn_toc_disc_free(disc);
6378
Xorriso_process_msg_queues(xorriso,0);
6385
int Xorriso_show_devices(struct XorrisO *xorriso, int flag)
6387
char adr[BURN_DRIVE_ADR_LEN];
6388
int i, j, max_dev_len= 1, pad;
6389
struct burn_drive_info *drive_list= NULL;
6390
unsigned int drive_count;
6391
char *respt, perms[8];
6394
sprintf(xorriso->info_text, "Beginning to scan for devices ...\n");
6395
Xorriso_info(xorriso,0);
6397
burn_drive_clear_whitelist();
6398
while(!burn_drive_scan(&drive_list, &drive_count)) {
6399
Xorriso_process_msg_queues(xorriso,0);
6402
Xorriso_process_msg_queues(xorriso,0);
6403
if(drive_count <= 0) {
6405
/* >>> was a drive_list created at all ? */
6406
/* >>> must it be freed ? */
6408
sprintf(xorriso->info_text, "No drives found");
6409
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
6412
sprintf(xorriso->info_text, "Full drive scan done\n");
6413
Xorriso_info(xorriso,0);
6415
sprintf(xorriso->info_text, "-----------------------------------------------------------------------------\n");
6416
Xorriso_info(xorriso,0);
6417
respt= xorriso->result_line;
6418
for(i= 0; i < drive_count && !(xorriso->request_to_abort); i++) {
6419
if(burn_drive_get_adr(&(drive_list[i]), adr)<=0)
6420
strcpy(adr, "-get_adr_failed-");
6421
Xorriso_process_msg_queues(xorriso,0);
6422
if(strlen(adr)>max_dev_len)
6423
max_dev_len= strlen(adr);
6425
for(i= 0; i < drive_count && !(xorriso->request_to_abort); i++) {
6426
if(burn_drive_get_adr(&(drive_list[i]), adr)<=0)
6427
strcpy(adr, "-get_adr_failed-");
6428
Xorriso_process_msg_queues(xorriso,0);
6429
if(stat(adr,&stbuf)==-1) {
6430
sprintf(perms,"errno=%d",errno);
6432
strcpy(perms,"------");
6433
if(stbuf.st_mode&S_IRUSR) perms[0]= 'r';
6434
if(stbuf.st_mode&S_IWUSR) perms[1]= 'w';
6435
if(stbuf.st_mode&S_IRGRP) perms[2]= 'r';
6436
if(stbuf.st_mode&S_IWGRP) perms[3]= 'w';
6437
if(stbuf.st_mode&S_IROTH) perms[4]= 'r';
6438
if(stbuf.st_mode&S_IWOTH) perms[5]= 'w';
6440
sprintf(respt, "%d -dev '%s' ", i, adr);
6441
pad= max_dev_len-strlen(adr);
6443
for(j= 0; j<pad; j++)
6445
sprintf(respt+strlen(respt), "%s : '%-8.8s' '%s' \n",
6446
perms, drive_list[i].vendor, drive_list[i].product);
6447
Xorriso_result(xorriso,0);
6449
sprintf(xorriso->info_text, "-----------------------------------------------------------------------------\n");
6450
Xorriso_info(xorriso,0);
6452
burn_drive_info_free(drive_list);
6453
Xorriso_process_msg_queues(xorriso,0);
6458
int Xorriso_tell_media_space(struct XorrisO *xorriso,
6459
int *media_space, int *free_space, int flag)
6462
struct burn_drive_info *dinfo;
6463
struct burn_drive *drive;
6464
struct burn_write_opts *burn_options;
6466
(*free_space)= (*media_space)= 0;
6468
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
6469
"on attempt to -tell_media_space", 2);
6473
ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0);
6476
(*free_space)= (*media_space)=
6477
isoburn_disc_available_space(drive, burn_options) / (off_t) 2048;
6478
burn_write_opts_free(burn_options);
6480
if(xorriso->volset_change_pending) {
6481
ret= Xorriso_write_session(xorriso, 1);
6483
(*free_space)-= ret;
6485
Xorriso_process_msg_queues(xorriso,0);
6490
/* @param flag bit0= fast
6492
bit2= do not re-aquire drive
6493
@return 0=failure, did not touch media , -1=failure, altered media
6494
1=success, altered media , 2=success, did not touch media
6496
int Xorriso_blank_media(struct XorrisO *xorriso, int flag)
6498
int ret, do_deformat= 0;
6499
struct burn_drive_info *dinfo;
6500
struct burn_drive *drive;
6501
enum burn_disc_status disc_state;
6502
struct burn_progress p;
6503
double percent = 1.0;
6504
int current_profile;
6505
char current_profile_name[80];
6507
char mode_names[4][80]= {"all", "fast", "deformat", "deformat_quickest"};
6509
ret= Xorriso_may_burn(xorriso, 0);
6512
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
6513
"on attempt to -blank", 2);
6517
burn_disc_get_profile(drive, ¤t_profile, current_profile_name);
6519
disc_state = isoburn_disc_get_status(drive);
6520
if(current_profile == 0x13) { /* overwriteable DVD-RW */
6521
/* Depending on flag bit1 formatted DVD-RW will get blanked to sequential
6522
state or pseudo blanked by invalidating an eventual ISO image. */
6525
} else if(current_profile == 0x14) { /* sequential DVD-RW */
6526
if((flag&1) && !(flag&2)) {
6527
sprintf(xorriso->info_text,
6528
"-blank: DVD-RW present. Mode 'fast' defaulted to mode 'all'.");
6529
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
6530
sprintf(xorriso->info_text,
6531
"Mode 'deformat_quickest' produces single-session-only media.");
6532
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
6535
} else if(disc_state == BURN_DISC_BLANK) {
6536
sprintf(xorriso->info_text,"Blank media detected. Will leave it untouched");
6537
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
6539
} else if(disc_state==BURN_DISC_FULL || disc_state==BURN_DISC_APPENDABLE) {
6541
} else if(disc_state == BURN_DISC_EMPTY) {
6542
sprintf(xorriso->info_text,"No media detected in drive");
6543
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
6546
sprintf(xorriso->info_text, "Unsuitable drive and media state");
6547
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
6550
if(!isoburn_disc_erasable(drive)) {
6551
sprintf(xorriso->info_text, "Media is not of erasable type");
6552
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
6555
if(xorriso->do_dummy) {
6556
sprintf(xorriso->info_text,
6557
"-dummy mode prevents blanking of media in mode '%s'.",
6558
mode_names[flag&3]);
6559
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
6562
sprintf(xorriso->info_text, "Beginning to blank media in mode '%s'.\n",
6563
mode_names[flag&3]);
6564
Xorriso_info(xorriso,0);
6566
/* Important: do not return until burn_is_aborting() was checked */
6567
Xorriso_set_signal_handling(xorriso, 1);
6570
burn_disc_erase(drive, (flag&1));
6572
isoburn_disc_erase(drive, (flag&1));
6573
start_time= time(0);
6575
while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
6576
Xorriso_process_msg_queues(xorriso,0);
6577
if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
6578
percent = 1.0 + ((double) p.sector+1.0) / ((double) p.sectors) * 98.0;
6579
sprintf(xorriso->info_text, "Blanking ( %.1f%% done in %d seconds )",
6580
percent, (int) (time(0) - start_time));
6581
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
6584
Xorriso_process_msg_queues(xorriso,0);
6585
if(burn_is_aborting(0))
6586
Xorriso_abort(xorriso, 0); /* Never comes back */
6587
Xorriso_set_signal_handling(xorriso, 0);
6588
if(burn_drive_wrote_well(drive)) {
6589
sprintf(xorriso->info_text, "Blanking done\n");
6590
Xorriso_info(xorriso,0);
6592
sprintf(xorriso->info_text, "Blanking failed.");
6593
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
6596
ret= Xorriso_reaquire_outdev(xorriso,
6597
2 + (xorriso->in_drive_handle == xorriso->out_drive_handle));
6605
/* @param flag bit0= try to achieve faster formatting
6606
bit1= use parameter size (else use default size)
6607
bit2= do not re-aquire drive
6608
bit7= by_index mode:
6609
bit8 to bit15 contain the index of the format to use.
6610
@return 0=failure, did not touch media , -1=failure, altered media
6611
1=success, altered media , 2=success, did not touch media
6613
int Xorriso_format_media(struct XorrisO *xorriso, off_t in_size, int flag)
6615
int ret, mode_flag= 0, index, status, num_formats;
6617
struct burn_drive_info *dinfo;
6618
struct burn_drive *drive;
6619
struct burn_progress p;
6620
double percent = 1.0;
6621
int current_profile;
6622
char current_profile_name[80];
6625
enum burn_disc_status disc_state;
6627
ret= Xorriso_may_burn(xorriso, 0);
6630
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
6631
"on attempt to -format", 2);
6636
mode_flag= 0; /* format to given size */
6638
mode_flag= 4; /* format to full size */
6640
burn_disc_get_profile(drive, ¤t_profile, current_profile_name);
6642
if(flag&128) { /* by_index */
6643
index= (flag>>8) & 0xff;
6644
ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats);
6647
if(ret<=0 || index<0 || index>=num_formats) {
6649
sprintf(xorriso->info_text,
6650
"-format by_index_%d: format descriptors range from index 0 to %d",
6651
index, num_formats-1);
6653
sprintf(xorriso->info_text,
6654
"-format by_index_%d: no format descriptors available", index);
6655
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
6658
mode_flag|= (flag & 0xff80);
6662
} else if(current_profile == 0x12) { /* DVD+RAM */
6664
mode_flag= 6; /* format to default payload size */
6668
} else if(current_profile == 0x13) { /* DVD-RW */
6670
sprintf(xorriso->info_text,
6671
"Detected formatted DVD-RW. Thus omitting desired fast format run.");
6672
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
6676
} else if(current_profile == 0x14) { /* DVD-RW sequential */
6678
size= 128*1024*1024;
6679
mode_flag= 1; /* format to size, then write size of zeros */
6683
} else if(current_profile == 0x1a) { /* DVD+RW */
6685
sprintf(xorriso->info_text,
6686
"Detected DVD+RW. Thus omitting desired fast format run.");
6687
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
6691
} else if(current_profile == 0x41) { /* BD-R SRM */
6693
mode_flag= 6; /* format to default payload size */
6697
} else if(current_profile == 0x43) { /* BD-RE */
6699
mode_flag= 6; /* format to default payload size */
6704
sprintf(xorriso->info_text,
6705
"-format: Unsuitable media detected.");
6706
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
6707
sprintf(xorriso->info_text,"Media current: %s (%4.4xh)",
6708
current_profile_name, current_profile);
6709
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
6713
mode_flag|= 16; /* enable re-formatting */
6715
if(xorriso->do_dummy) {
6716
sprintf(xorriso->info_text, "-dummy mode prevents formatting of media.");
6717
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
6720
sprintf(xorriso->info_text, "Beginning to format media.\n");
6721
Xorriso_info(xorriso, 0);
6725
/* Important: do not return until burn_is_aborting() was checked */
6726
Xorriso_set_signal_handling(xorriso, 1);
6728
burn_disc_format(drive, size, mode_flag);
6730
start_time= time(0);
6732
while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) {
6733
Xorriso_process_msg_queues(xorriso,0);
6734
if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */
6735
percent = 1.0 + ((double) p.sector+1.0) / ((double) p.sectors) * 98.0;
6736
sprintf(xorriso->info_text, "Formatting ( %.1f%% done in %d seconds )",
6737
percent, (int) (time(0) - start_time));
6738
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
6741
Xorriso_process_msg_queues(xorriso,0);
6742
if(burn_is_aborting(0))
6743
Xorriso_abort(xorriso, 0); /* Never comes back */
6744
Xorriso_set_signal_handling(xorriso, 0);
6746
if(burn_drive_wrote_well(drive)) {
6747
sprintf(xorriso->info_text, "Formatting done\n");
6748
Xorriso_info(xorriso,0);
6750
sprintf(xorriso->info_text,
6751
"libburn indicates failure with formatting.");
6752
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
6757
ret= Xorriso_reaquire_outdev(xorriso,
6758
2 + (xorriso->in_drive_handle == xorriso->out_drive_handle));
6762
disc_state = isoburn_disc_get_status(drive);
6763
if(disc_state==BURN_DISC_FULL && !(flag&1)) {
6764
/* Blank because full format certification pattern might be non-zero */
6765
ret= Xorriso_blank_media(xorriso, 1);
6773
/* @param flag bit2= formatting rather than blanking
6774
@return 0=failure, did not touch media , -1=failure, altered media
6775
1=success, altered media , 2=success, did not touch media
6777
int Xorriso_blank_as_needed(struct XorrisO *xorriso, int flag)
6779
int ret, is_formatted= -1, status, num_formats, did_work= 0;
6780
struct burn_drive_info *dinfo;
6781
struct burn_drive *drive;
6782
enum burn_disc_status disc_state;
6784
int current_profile;
6785
char current_profile_name[80];
6788
ret= Xorriso_may_burn(xorriso, 0);
6791
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
6792
"on attempt to blank or format", 2);
6796
burn_disc_get_profile(drive, ¤t_profile, current_profile_name);
6798
ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats);
6800
if(status==BURN_FORMAT_IS_FORMATTED)
6802
else if(status == BURN_FORMAT_IS_UNFORMATTED)
6805
if(current_profile == 0x12 || current_profile == 0x43) { /* DVD+RAM , BD-RE */
6806
if(is_formatted<0) {
6807
sprintf(xorriso->info_text,
6808
"-blank or -format: Unclear formatting status of %s",
6809
current_profile_name);
6810
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
6814
ret= Xorriso_format_media(xorriso, (off_t) 0, (current_profile == 0x43));
6817
did_work= (ret == 1);
6819
} else if(current_profile == 0x14 && (flag&4)) { /* DVD-RW sequential */
6820
ret= Xorriso_format_media(xorriso, (off_t) 0, 0);
6823
did_work= (ret == 1);
6824
} else if(current_profile == 0x41) { /* BD-R SRM */
6826
ret= Xorriso_format_media(xorriso, (off_t) 0, 1);
6829
did_work= (ret == 1);
6833
disc_state = isoburn_disc_get_status(drive);
6834
if(disc_state != BURN_DISC_BLANK && !(flag&4)) {
6835
ret= Xorriso_blank_media(xorriso, 1);
6840
sprintf(xorriso->info_text, "%s as_needed: no need for action detected",
6841
(flag&4) ? "-format" : "-blank");
6842
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
6847
/* @return <=0 error, 1 success
6849
int Xorriso_list_formats(struct XorrisO *xorriso, int flag)
6851
int ret, i, status, num_formats, profile_no, type;
6854
char status_text[80], profile_name[90], *respt;
6855
struct burn_drive_info *dinfo;
6856
struct burn_drive *drive;
6858
respt= xorriso->result_line;
6860
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
6861
"on attempt to obtain format descriptor list", 1 | 2);
6866
ret = burn_disc_get_formats(drive, &status, &size, &dummy,
6869
sprintf(xorriso->info_text, "Cannot obtain format list info");
6870
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
6873
ret= Xorriso_toc(xorriso, 3);
6876
ret= burn_disc_get_profile(drive, &profile_no, profile_name);
6880
if(status == BURN_FORMAT_IS_UNFORMATTED)
6881
sprintf(status_text, "unformatted, up to %.1f MiB",
6882
((double) size) / 1024.0 / 1024.0);
6883
else if(status == BURN_FORMAT_IS_FORMATTED) {
6884
if(profile_no==0x12 || profile_no==0x13 || profile_no==0x1a ||
6886
sprintf(status_text, "formatted, with %.1f MiB",
6887
((double) size) / 1024.0 / 1024.0);
6889
sprintf(status_text, "written, with %.1f MiB",
6890
((double) size) / 1024.0 / 1024.0);
6891
} else if(status == BURN_FORMAT_IS_UNKNOWN) {
6893
sprintf(status_text, "intermediate or unknown");
6895
sprintf(status_text, "no media or unknown media");
6897
sprintf(status_text, "illegal status according to MMC-5");
6898
sprintf(respt, "Format status: %s\n", status_text);
6899
Xorriso_result(xorriso,0);
6901
for (i= 0; i < num_formats; i++) {
6902
ret= burn_disc_get_format_descr(drive, i, &type, &size, &dummy);
6905
sprintf(respt, "Format idx %-2d: %2.2Xh , %.fs , %.1f MiB\n",
6906
i, type, ((double) size) / 2048.0, ((double) size) / 1024.0/1024.0);
6907
Xorriso_result(xorriso,0);
6915
/* @param flag bit0= cdrecord style
6916
bit1= obtain outdrive, else indrive
6917
@return <=0 error, 1 success
6919
int Xorriso_list_profiles(struct XorrisO *xorriso, int flag)
6922
struct burn_drive_info *dinfo;
6923
struct burn_drive *drive;
6924
int num_profiles, profiles[64];
6925
char is_current[64], profile_name[90], *respt;
6927
respt= xorriso->result_line;
6929
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
6930
"on attempt to obtain profile list", 1 | (flag & 2));
6933
burn_drive_get_all_profiles(drive, &num_profiles, profiles, is_current);
6934
for(i= 0; i < num_profiles; i++) {
6935
ret= burn_obtain_profile_name(profiles[i], profile_name);
6937
strcpy(profile_name, "unknown");
6938
sprintf(respt, "%s 0x%4.4X (%s)%s\n",
6939
flag & 1 ? "Profile:" : "Profile :",
6940
(unsigned int) profiles[i],
6941
profile_name, is_current[i] ? " (current)" : "");
6942
Xorriso_result(xorriso,0);
6948
int Xorriso_cannot_create_iter(struct XorrisO *xorriso, int iso_error,int flag)
6950
Xorriso_process_msg_queues(xorriso,0);
6951
Xorriso_report_iso_error(xorriso, "", iso_error, "Cannot create iter", 0,
6953
sprintf(xorriso->info_text, "Cannot create IsoDirIter object");
6954
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
6959
int Xorriso__node_lba_cmp(const void *node1, const void *node2)
6962
int lba1= 0, lba2= 0;
6964
ret= Xorriso__file_start_lba(*((IsoNode **) node1), &lba1, 0);
6967
ret= Xorriso__file_start_lba(*((IsoNode **) node2), &lba2, 0);
6973
/* The caller shall make no assumptions about the meaning of iter, node_array,
6974
node_count, node_idx ! They are just opaque handles for which the caller
6975
provides the memory of proper type.
6976
@param flag bit0= initialize iteration
6977
bit1= action needs full freedom of object manipulation
6978
bit2= action needs LBA sorted iteration
6979
bit31= end iteration (mandatory !)
6981
int Xorriso_findi_iter(struct XorrisO *xorriso, IsoDir *dir_node, off_t *mem,
6983
IsoNode ***node_array, int *node_count, int *node_idx,
6984
IsoNode **iterated_node, int flag)
6989
char mem_text[80], limit_text[80];
6996
ret= iso_dir_get_children(dir_node, iter);
6999
Xorriso_cannot_create_iter(xorriso, ret, 0);
7002
if((flag&2)|(flag&4)) {
7003
/* copy list of nodes and prepare soft iterator */
7005
while(iso_dir_iter_next(*iter, &node) == 1)
7007
iso_dir_iter_free(*iter);
7010
new_mem= ((*node_count)+1) * sizeof(IsoNode *);
7011
if(new_mem > xorriso->temp_mem_limit) {
7012
Sfile_scale((double) new_mem, mem_text, 5,1e4, 0);
7013
Sfile_scale((double) xorriso->temp_mem_limit, limit_text, 5,1e4, 0);
7014
sprintf(xorriso->info_text,
7015
"Stacked directory snapshots exceed -temp_mem_limit (%s > %s)",
7016
mem_text, limit_text);
7017
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
7021
(*node_array)= (IsoNode **) calloc((*node_count)+1, sizeof(IsoNode *));
7022
if(*node_array == NULL) {
7023
sprintf(xorriso->info_text,
7024
"Could not allocate inode list of %.f bytes",
7025
((double) (*node_count)+1) * (double) sizeof(IsoNode *));
7026
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
7031
ret= iso_dir_get_children(dir_node, iter);
7034
while(iso_dir_iter_next(*iter, &node) == 1 && *node_idx < *node_count) {
7035
(*node_array)[*node_idx]= node;
7039
iso_dir_iter_free(*iter);
7041
*node_count= *node_idx;
7043
if((flag&4) && *node_count>1)
7044
qsort(*node_array, *node_count, sizeof(IsoNode *),
7045
Xorriso__node_lba_cmp);
7050
if(*node_count>=0 && *node_array!=NULL) {
7051
for(i= 0; i<*node_count; i++)
7052
iso_node_unref((*node_array)[i]);
7059
iso_dir_iter_free(*iter);
7064
if(flag&(1|(1<<31)))
7066
if(*node_count>=0) {
7067
/* return next node_array element */
7068
if(*node_idx>=*node_count)
7070
*iterated_node= (*node_array)[*node_idx];
7073
ret= iso_dir_iter_next(*iter, iterated_node);
7080
/* @param boss_iter If not NULL then this is an iterator suitable for
7081
iso_dir_iter_remove() which is then to be used instead
7082
of iso_node_remove().
7083
@param flag bit0= remove whole sub tree: rm -r
7084
bit1= remove empty directory: rmdir
7085
bit2= recursion: do not reassure in mode 2 "tree"
7086
bit3= this is for overwriting and not for plain removal
7087
bit4= count deleted files in xorriso->pacifier_count
7088
bit5= with bit0 only remove directory content, not the directory
7089
bit6= do not delete eventually existing node from di_array
7091
1 = removed simple node
7092
2 = removed directory or tree
7093
3 = did not remove on user revocation
7095
int Xorriso_rmi(struct XorrisO *xorriso, void *boss_iter, off_t boss_mem,
7096
char *path, int flag)
7098
int ret, is_dir= 0, pl, not_removed= 0, fret;
7099
IsoNode *victim_node, *node;
7100
IsoDir *boss_node, *root_dir;
7101
IsoDirIter *iter= NULL;
7103
char *sub_name, *name;
7104
char *sfe= NULL, *sub_path= NULL;
7106
IsoNode **node_array= NULL;
7107
int node_count= 0, node_idx;
7109
/* Avoiding large local memory objects in order to save stack space */
7110
sfe= malloc(5*SfileadrL);
7111
sub_path= malloc(2*SfileadrL);
7112
if(sfe==NULL || sub_path==NULL) {
7113
Xorriso_no_malloc_memory(xorriso, &sfe, 0);
7117
#ifndef Libisofs_iso_dir_iter_sufficienT
7118
/* Ticket 127: A80301 - A80302
7119
I do not not deem IsoDirIter safe for node list manipulations.
7120
The parameter boss_iter once was intended to allow such but
7121
has now been downgraded to a mere check for eventual programming bugs.
7123
if(boss_iter!=NULL) {
7124
sprintf(xorriso->info_text,
7125
"Program error: Xorriso_rmi() was requested to delete iterated node %s",
7126
Text_shellsafe(path, sfe, 0));
7127
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
7130
#endif /* Libisofs_iso_dir_iter_sufficienT */
7132
ret= Xorriso_get_volume(xorriso, &volume, 0);
7136
if(Xorriso_much_too_long(xorriso, strlen(path), 0)<=0)
7138
ret= Xorriso_node_from_path(xorriso, volume, path, &victim_node, 0);
7141
root_dir= iso_image_get_root(volume);
7142
if(((void *) root_dir) == ((void *) victim_node)) {
7143
sprintf(xorriso->info_text, "May not delete root directory");
7144
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
7148
if(LIBISO_ISDIR(victim_node))
7151
if(flag&2) { /* rmdir */
7152
sprintf(xorriso->info_text, "%s in loaded ISO image is not a directory",
7153
Text_shellsafe(path, sfe, 0));
7154
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
7158
if(flag&1) { /* rm -r */
7159
if((xorriso->do_reassure==1 && !xorriso->request_not_to_ask) ||
7161
/* Iterate over subordinates and delete them */
7164
ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem,
7165
&iter, &node_array, &node_count, &node_idx,
7168
cannot_create_iter:;
7169
Xorriso_cannot_create_iter(xorriso, ret, 0);
7173
strcpy(sub_path, path);
7174
if(pl==0 || sub_path[pl-1]!='/') {
7175
sub_path[pl++]= '/';
7178
sub_name= sub_path+pl;
7180
ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, &iter,
7181
&node_array, &node_count, &node_idx, &node, 0);
7184
if(ret==0 || xorriso->request_to_abort)
7186
name= (char *) iso_node_get_name(node);
7187
if(Xorriso_much_too_long(xorriso, pl+1+strlen(name), 0)<=0)
7188
{ret= 0; goto rm_r_problem_handler;}
7189
strcpy(sub_name, name);
7190
ret= Xorriso_rmi(xorriso, iter, mem, sub_path,
7191
(flag & ( 1 | 2 | 8 | 16 | 64)) | 4);
7192
if(ret==3 || ret<=0 || xorriso->request_to_abort) {
7193
rm_r_problem_handler:;
7195
fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
7197
goto dir_not_removed;
7205
sprintf(xorriso->info_text, "Directory not removed: %s",
7206
Text_shellsafe(path, sfe, 0));
7207
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
7214
if(!(flag&2)) { /* not rmdir */
7215
sprintf(xorriso->info_text, "%s in loaded ISO image is a directory",
7216
Text_shellsafe(path, sfe, 0));
7217
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
7221
ret= iso_dir_get_children((IsoDir *) victim_node, &iter);
7222
Xorriso_process_msg_queues(xorriso,0);
7224
goto cannot_create_iter;
7226
if(iso_dir_iter_next(iter, &node) == 1) {
7227
sprintf(xorriso->info_text,
7228
"Directory not empty on attempt to delete: %s",
7229
Text_shellsafe(path, sfe, 0));
7230
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
7237
if(xorriso->request_to_abort)
7239
boss_node= iso_node_get_parent(victim_node);
7240
Xorriso_process_msg_queues(xorriso,0);
7241
if(boss_node==NULL) {
7242
sprintf(xorriso->info_text,
7243
"Cannot find parent node of %s in loaded ISO image",
7244
Text_shellsafe(path, sfe, 0));
7245
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
7249
while((xorriso->do_reassure==1 || (xorriso->do_reassure==2 && !(flag&4)))
7250
&& !xorriso->request_not_to_ask) {
7252
Xorriso_ls_filev(xorriso, xorriso->wdi, 1, &path, (off_t) 0, 1|2|8);
7253
if(is_dir) /* du -s */
7254
Xorriso_ls_filev(xorriso, xorriso->wdi, 1, &path, (off_t) 0, 2|4);
7256
sprintf(xorriso->info_text,
7257
"File exists. Remove ? n= keep old, y= remove, x= abort, @= stop asking\n");
7259
sprintf(xorriso->info_text,
7260
"Remove above file ? n= keep it, y= remove it, x= abort, @= stop asking\n");
7261
Xorriso_info(xorriso, 4);
7262
ret= Xorriso_request_confirmation(xorriso, 1|2|4|16);
7265
if(xorriso->request_to_abort) {
7266
sprintf(xorriso->info_text,
7267
"Removal operation aborted by user before file: %s",
7268
Text_shellsafe(path, sfe, 0));
7269
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
7274
if(ret==6) /* yes */
7276
if(ret==4) { /* yes, do not ask again */
7277
xorriso->request_not_to_ask= 1;
7280
if(ret==1) { /* no */
7281
sprintf(xorriso->info_text, "Kept in existing state: %s",
7282
Text_shellsafe(path, sfe, 0));
7283
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
7289
Xorriso_invalidate_di_item(xorriso, victim_node, 0);
7291
#ifdef Libisofs_iso_dir_iter_sufficienT
7293
if(boss_iter!=NULL) {
7294
ret= iso_dir_iter_remove((IsoDirIter *) boss_iter);
7298
ret= iso_node_remove(victim_node);
7300
#else /* ! Libisofs_iso_dir_iter_sufficienT */
7302
ret= iso_node_remove(victim_node);
7304
#endif /* Libisofs_iso_dir_iter_sufficienT */
7306
Xorriso_process_msg_queues(xorriso,0);
7308
Xorriso_report_iso_error(xorriso, path, ret, "Cannot remove node", 0,
7310
sprintf(xorriso->info_text,
7311
"Internal failure to remove %s from loaded ISO image",
7312
Text_shellsafe(path, sfe, 0));
7313
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
7318
xorriso->pacifier_count++;
7319
Xorriso_set_change_pending(xorriso, 0);
7326
Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, &iter,
7327
&node_array, &node_count, &node_idx, &node, (1<<31));
7332
int Xorriso__node_name_cmp(const void *node1, const void *node2)
7334
char *name1, *name2;
7336
name1= (char *) iso_node_get_name(*((IsoNode **) node1));
7337
name2= (char *) iso_node_get_name(*((IsoNode **) node2));
7338
return(strcmp(name1,name2));
7342
/* @param flag bit0= only accept directory nodes
7343
bit1= do not report memory usage as DEBUG
7344
bit2= do not apply search pattern but accept any node
7346
int Xorriso_sorted_node_array(struct XorrisO *xorriso,
7348
int *nodec, IsoNode ***node_array,
7349
off_t boss_mem, int flag)
7351
int i, ret, failed_at;
7353
IsoDirIter *iter= NULL;
7357
mem= ((*nodec)+1)*sizeof(IsoNode *);
7358
ret= Xorriso_check_temp_mem_limit(xorriso, mem+boss_mem, flag&2);
7362
*node_array= calloc(sizeof(IsoNode *), (*nodec)+1);
7363
if(*node_array==NULL) {
7364
sprintf(xorriso->info_text,
7365
"Cannot allocate memory for %d directory entries", *nodec);
7366
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
7370
ret= iso_dir_get_children(dir_node, &iter);
7372
Xorriso_cannot_create_iter(xorriso, ret, 0);
7376
for(i= 0; iso_dir_iter_next(iter, &node) == 1 && i<*nodec; ) {
7377
npt= (char *) iso_node_get_name(node);
7379
ret= Xorriso_regexec(xorriso, npt, &failed_at, 0);
7381
continue; /* no match */
7384
if(!LIBISO_ISDIR(node))
7386
(*node_array)[i++]= node;
7388
iso_dir_iter_free(iter);
7392
qsort(*node_array, *nodec, sizeof(IsoNode *), Xorriso__node_name_cmp);
7397
/* @param flag bit0= do not only sum up sizes but also print subdirs
7399
int Xorriso_show_du_subs(struct XorrisO *xorriso, IsoDir *dir_node,
7400
char *abs_path, char *rel_path, off_t *size,
7401
off_t boss_mem, int flag)
7403
int i, ret, no_sort= 0, filec= 0, l;
7404
IsoDirIter *iter= NULL;
7405
IsoNode *node, **node_array= NULL;
7407
off_t sub_size, report_size, mem= 0;
7408
char *path= NULL, *show_path= NULL, *sfe= NULL;
7410
sfe= malloc(5*SfileadrL);
7411
path= malloc(SfileadrL);
7412
show_path= malloc(SfileadrL);
7413
if(path==NULL || show_path==NULL || sfe==NULL) {
7414
Xorriso_no_malloc_memory(xorriso, &sfe, 0);
7419
ret= iso_dir_get_children(dir_node, &iter);
7421
cannot_create_iter:;
7422
Xorriso_cannot_create_iter(xorriso, ret, 0);
7425
for(i= 0; iso_dir_iter_next(iter, &node) == 1; ) {
7427
name= (char *) iso_node_get_name(node);
7428
strcpy(show_path, rel_path);
7429
if(Sfile_add_to_path(show_path, name, 0)<=0)
7431
if(LIBISO_ISDIR(node)) {
7432
strcpy(path, abs_path);
7433
if(Sfile_add_to_path(path, name, 0)<=0) {
7435
Xorriso_much_too_long(xorriso, strlen(path)+strlen(name)+1, 2);
7439
l= strlen(rel_path)+1;
7441
if(l % sizeof(char *))
7442
mem+= sizeof(char *)-(l % sizeof(char *));
7443
if(flag&1) /* diving and counting is done further below */
7445
ret= Xorriso_show_du_subs(xorriso, (IsoDir *) node,
7446
path, show_path, &sub_size, boss_mem, 0);
7453
if(LIBISO_ISREG(node)) {
7454
sub_size+= iso_file_get_size((IsoFile *) node)+2048;
7456
sub_size+= iso_file_get_size((IsoFile *) node)+strlen(name)+1;
7462
Xorriso_process_msg_queues(xorriso,0);
7465
if(filec<=0 || !(flag&1))
7468
/* Reset iteration */
7469
iso_dir_iter_free(iter);
7471
Xorriso_process_msg_queues(xorriso,0);
7473
ret= Xorriso_sorted_node_array(xorriso, dir_node, &filec, &node_array,
7479
ret= iso_dir_get_children(dir_node, &iter);
7481
goto cannot_create_iter;
7484
for(i= 0; (no_sort || i<filec) && !(xorriso->request_to_abort); i++) {
7486
ret= iso_dir_iter_next(iter, &node);
7489
if(!LIBISO_ISDIR(node))
7492
node= node_array[i];
7495
name= (char *) iso_node_get_name(node);
7496
strcpy(show_path, rel_path);
7497
if(Sfile_add_to_path(show_path, name, 0)<=0)
7499
strcpy(path, abs_path);
7500
if(Sfile_add_to_path(path, name, 0)<=0)
7502
ret= Xorriso_show_du_subs(xorriso, (IsoDir *) node,
7503
path, show_path, &sub_size, boss_mem+mem, flag&1);
7507
if(LIBISO_ISREG(node)) {
7508
sub_size+= iso_file_get_size((IsoFile *) node)+2048;
7510
sub_size+= iso_tree_node_get_size((IsoFile *) node)+strlen(name)+1;
7515
report_size= sub_size/1024;
7516
if(report_size*1024<sub_size)
7518
sprintf(xorriso->result_line, "%7.f ",(double) (report_size));
7519
sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n",
7520
Text_shellsafe(show_path, sfe, 0));
7521
Xorriso_result(xorriso, 0);
7532
iso_dir_iter_free(iter);
7533
if(node_array!=NULL)
7534
free((char *) node_array);
7535
Xorriso_process_msg_queues(xorriso,0);
7540
int Xorriso_sorted_dir_i(struct XorrisO *xorriso, IsoDir *dir_node,
7541
int *filec, char ***filev, off_t boss_mem, int flag)
7544
IsoDirIter *iter= NULL;
7552
ret= iso_dir_get_children(dir_node, &iter);
7555
Xorriso_cannot_create_iter(xorriso, ret, 0);
7559
for(i= 0; iso_dir_iter_next(iter, &node) == 1; ) {
7560
name= (char *) iso_node_get_name(node);
7561
mem+= sizeof(char *)+strlen(name)+8;
7564
iso_dir_iter_free(iter);
7569
ret= Xorriso_check_temp_mem_limit(xorriso, mem+boss_mem, 2);
7572
(*filev)= (char **) calloc(*filec, sizeof(char *));
7574
{ret= -1; goto ex; }
7575
ret= iso_dir_get_children(dir_node, &iter);
7578
for(i= 0; i<*filec; i++) {
7579
ret= iso_dir_iter_next(iter, &node);
7582
name= (char *) iso_node_get_name(node);
7583
(*filev)[i]= strdup(name);
7584
if((*filev)[i]==NULL) {
7586
if((*filev)[j]!=NULL)
7588
free((char *) (*filev));
7592
Sort_argv(*filec, *filev, 0);
7596
iso_dir_iter_free(iter);
7601
/* @param flag bit0= long format
7602
bit1= do not print count of nodes
7604
bit3= print directories as themselves (ls -d)
7606
int Xorriso_ls_filev(struct XorrisO *xorriso, char *wd,
7607
int filec, char **filev, off_t boss_mem, int flag)
7609
int i, ret, was_error= 0, dfilec= 0, pass, passes;
7612
char sfe[5*SfileadrL], sfe2[5*SfileadrL], path[SfileadrL];
7613
char link_target[SfileadrL], *rpt, **dfilev= NULL;
7614
char *a_text= NULL, *d_text= NULL;
7618
rpt= xorriso->result_line;
7620
ret= Xorriso_get_volume(xorriso, &volume, 0);
7624
Sort_argv(filec, filev, 0);
7626
/* Count valid nodes, warn of invalid ones */
7627
for(i= 0; i<filec; i++) {
7628
ret= Xorriso_make_abs_adr(xorriso, wd, filev[i], path, 1|2|4);
7633
ret= Xorriso_node_from_path(xorriso, volume, path, &node, 1);
7635
sprintf(xorriso->info_text, "Not found in ISO image: %s",
7636
Text_shellsafe(path, sfe, 0));
7637
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
7643
if((flag&8) && !(flag&(2|4))) {
7644
sprintf(xorriso->info_text, "Valid ISO nodes found: %d\n", filec-was_error);
7645
Xorriso_info(xorriso,1);
7646
if(filec-was_error<=0)
7650
passes= 1+!(flag&(4|8));
7651
for(pass= 0; pass<passes; pass++)
7652
for(i= 0; i<filec && !(xorriso->request_to_abort); i++) {
7654
ret= Xorriso_make_abs_adr(xorriso, wd, filev[i], path, 1|2|4);
7657
ret= Xorriso_fake_stbuf(xorriso, path, &stbuf, &node, ((flag&4) >> 1) | 16);
7660
if(LIBISO_ISDIR(node) && !(flag&(4|8))) {
7664
strcpy(xorriso->result_line, "\n");
7665
Xorriso_result(xorriso,0);
7666
sprintf(xorriso->result_line, "%s:\n", Text_shellsafe(filev[i], sfe,0));
7667
Xorriso_result(xorriso,0);
7669
ret= Xorriso_sorted_dir_i(xorriso,
7670
(IsoDir *) node, &dfilec, &dfilev, boss_mem, 0);
7673
/* >>> libisofs iterator loop and single item Xorriso_lsx_filev() */;
7677
sprintf(xorriso->result_line, "total %d\n", dfilec);
7678
Xorriso_result(xorriso,0);
7680
Xorriso_ls_filev(xorriso, path,
7681
dfilec, dfilev, boss_mem, (flag&1)|2|8);
7684
Sfile_destroy_argv(&dfilec, &dfilev, 0);
7690
if((flag&5)==1) { /* -ls_l */
7691
iso_node_get_acl_text(node, &a_text, &d_text, 16);
7692
ret= Xorriso_format_ls_l(xorriso, &stbuf,
7693
1 | ((a_text != NULL || d_text != NULL) << 1));
7694
iso_node_get_acl_text(node, &a_text, &d_text, 1 << 15);
7697
if(LIBISO_ISLNK(node)) {
7698
if(Sfile_str(link_target, (char *) iso_symlink_get_dest(
7699
(IsoSymlink *) node), 0)<=0)
7702
} else if(flag&4) { /* -du or -dus */
7703
size= stbuf.st_size;
7704
if(S_ISDIR(stbuf.st_mode)) {
7705
ret= Xorriso_show_du_subs(xorriso, (IsoDir *) node,
7706
path, filev[i], &size, boss_mem, flag&1);
7712
sprintf(rpt, "%7.f ",(double) (size/1024));
7714
if(link_target[0] && (flag&5)==1)
7715
sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s -> %s\n",
7716
Text_shellsafe(filev[i], sfe, 0),
7717
Text_shellsafe(link_target, sfe2, 0));
7719
sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n",
7720
Text_shellsafe(filev[i], sfe, 0));
7721
Xorriso_result(xorriso, 0);
7727
/* This function needs less buffer memory than Xorriso_ls_filev() but cannot
7728
perform structured pattern matching as done by Xorriso_expand_pattern()
7729
for subsequent Xorriso_ls_filev().
7730
@param flag bit0= long format
7731
bit1= only check for directory existence
7732
bit2= do not apply search pattern but accept any file
7733
bit3= just count nodes and return number
7735
int Xorriso_ls(struct XorrisO *xorriso, int flag)
7737
int ret, is_dir= 0, i, filec= 0, failed_at, no_sort= 0;
7738
IsoNode *node, **node_array= NULL;
7741
IsoDirIter *iter= NULL;
7742
char sfe[5*SfileadrL], sfe2[5*SfileadrL], link_target[SfileadrL], *npt, *rpt;
7745
rpt= xorriso->result_line;
7747
ret= Xorriso_get_volume(xorriso, &volume, 0);
7751
ret= Xorriso_node_from_path(xorriso, volume, xorriso->wdi, &node, 0);
7753
goto wdi_is_not_a_dir;
7754
if(LIBISO_ISDIR(node))
7758
sprintf(xorriso->info_text,
7759
"Working directory path does not lead to a directory in ISO image");
7760
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
7766
dir_node= (IsoDir *) node;
7767
ret= iso_dir_get_children(dir_node, &iter);
7769
cannot_create_iter:;
7770
Xorriso_cannot_create_iter(xorriso, ret, 0);
7773
Xorriso_process_msg_queues(xorriso,0);
7775
for(i= 0; iso_dir_iter_next(iter, &node) == 1; ) {
7776
npt= (char *) iso_node_get_name(node);
7778
ret= Xorriso_regexec(xorriso, npt, &failed_at, 0);
7780
continue; /* no match */
7784
/* Reset iteration */
7785
iso_dir_iter_free(iter);
7787
Xorriso_process_msg_queues(xorriso,0);
7789
{ret= filec; goto ex;}
7790
sprintf(xorriso->info_text, "Valid ISO nodes found: %d\n", filec);
7791
Xorriso_info(xorriso,1);
7793
ret= Xorriso_sorted_node_array(xorriso, dir_node, &filec, &node_array, 0,
7799
ret= iso_dir_get_children(dir_node, &iter);
7801
goto cannot_create_iter;
7804
for(i= 0; i<filec && !(xorriso->request_to_abort); i++) {
7806
ret= iso_dir_iter_next(iter, &node);
7809
npt= (char *) iso_node_get_name(node);
7811
ret= Xorriso_regexec(xorriso, npt, &failed_at, 0);
7813
continue; /* no match */
7816
node= node_array[i];
7818
npt= (char *) iso_node_get_name(node);
7820
if(LIBISO_ISLNK(node)) {
7821
if(Sfile_str(link_target, (char *) iso_symlink_get_dest(
7822
(IsoSymlink *) node), 0)<=0)
7827
ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1);
7830
ret= Xorriso_format_ls_l(xorriso, &stbuf, 1);
7834
if(link_target[0] && (flag&1))
7835
sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s -> %s\n",
7836
Text_shellsafe(npt, sfe, 0),
7837
Text_shellsafe(link_target, sfe2, 0));
7839
sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n",
7840
Text_shellsafe(npt, sfe, 0));
7841
Xorriso_result(xorriso, 0);
7847
iso_dir_iter_free(iter);
7848
Xorriso_process_msg_queues(xorriso,0);
7849
if(node_array!=NULL)
7850
free((char *) node_array);
7855
/* @param boss_iter Opaque handle to be forwarded to actions in ISO image
7856
Set to NULL if calling this function from outside ISO world
7858
int Xorriso_rename(struct XorrisO *xorriso, void *boss_iter,
7859
char *origin, char *dest, int flag)
7861
int ret, ol, dest_ret;
7862
char sfe[5*SfileadrL], eff_dest[SfileadrL], dir_adr[SfileadrL], *cpt;
7863
char *leafname, eff_origin[SfileadrL], sfe2[5*SfileadrL], *old_leafname;
7865
IsoDir *origin_dir, *dest_dir;
7866
IsoNode *node, *iso_node;
7868
#ifndef Libisofs_iso_dir_iter_sufficienT
7869
/* Ticket 127: A80301 - A80302
7870
I do not not deem IsoDirIter safe for node list manipulations.
7871
The parameter boss_iter once was intended to allow such but
7872
has now been downgraded to a mere check for eventual programming bugs.
7874
if(boss_iter!=NULL) {
7875
sprintf(xorriso->info_text,
7876
"Program error: Xorriso_rename() was requested to delete iterated node %s",
7877
Text_shellsafe(origin, sfe, 0));
7878
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
7881
#endif /* Libisofs_iso_dir_iter_sufficienT */
7883
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, origin, eff_origin, 0);
7886
dest_ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, dest, eff_dest,1);
7889
if(dest_ret==0) { /* obtain eff_dest address despite it does not exist */
7890
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, dest, eff_dest, 2);
7895
/* Prevent that destination is a subordinate of origin
7896
(that would be a black hole plopping out of the universe) */
7897
ol= strlen(eff_origin);
7899
sprintf(xorriso->info_text, "May not rename root directory");
7900
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
7902
} else if(strcmp(eff_origin, eff_dest)==0) {
7903
sprintf(xorriso->info_text, "Ignored attempt to rename %s to itself",
7904
Text_shellsafe(eff_origin,sfe,0));
7905
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
7907
} else if(strncmp(eff_origin, eff_dest, ol)==0 &&
7908
(eff_dest[ol]==0 || eff_dest[ol]=='/')) {
7909
sprintf(xorriso->info_text,
7910
"May not rename %s to its own sub address %s",
7911
Text_shellsafe(eff_origin,sfe,0), Text_shellsafe(eff_dest,sfe2,0));
7912
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
7916
/* Check whether destination exists and may be not overwriteable */
7917
if(dest_ret==2 && xorriso->do_overwrite!=1) {
7918
sprintf(xorriso->info_text, "Renaming may not overwrite directory: %s",
7919
Text_shellsafe(eff_dest, sfe, 0));
7920
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
7922
} else if (dest_ret==1 && !xorriso->do_overwrite) {
7923
sprintf(xorriso->info_text, "Renaming may not overwite: %s",
7924
Text_shellsafe(eff_dest, sfe, 0));
7925
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
7927
} else if(dest_ret>0) {
7928
ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, eff_dest, 1|8);
7932
sprintf(xorriso->info_text, "User revoked renaming of: %s",
7933
Text_shellsafe(eff_origin, sfe, 0));
7934
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
7939
/* Ensure existence of destination directory */
7940
strcpy(dir_adr, eff_dest);
7941
cpt= strrchr(dir_adr, '/');
7943
cpt= dir_adr+strlen(dir_adr);
7946
ret= Xorriso_graft_in(xorriso, boss_iter, NULL, dir_adr,
7947
(off_t) 0, (off_t) 0, 1);
7953
ret= Xorriso_get_volume(xorriso, &volume, 0);
7956
Xorriso_node_from_path(xorriso, volume, dir_adr, &iso_node, 0);
7957
dest_dir= (IsoDir *) iso_node;
7958
strcpy(dir_adr, eff_origin);
7959
cpt= strrchr(dir_adr, '/');
7961
cpt= dir_adr+strlen(dir_adr);
7963
Xorriso_node_from_path(xorriso, volume, dir_adr, &iso_node, 0);
7964
origin_dir= (IsoDir *) iso_node;
7965
Xorriso_node_from_path(xorriso, volume, eff_origin, &node, 0);
7966
if(dest_dir==NULL || origin_dir==NULL || node==NULL) {
7967
Xorriso_process_msg_queues(xorriso,0);
7968
sprintf(xorriso->info_text,
7969
"Internal error on rename: confirmed node turns out as NULL");
7970
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
7973
ret= iso_node_take(node);
7975
Xorriso_process_msg_queues(xorriso,0);
7976
Xorriso_report_iso_error(xorriso, eff_dest, 0, "Cannot take", 0, "FATAL",1);
7977
sprintf(xorriso->info_text,
7978
"Internal error on rename: failed to take node");
7979
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
7982
leafname= strrchr(eff_dest, '/');
7988
old_leafname= (char *) iso_node_get_name(node);
7989
if(strcmp(leafname, old_leafname)!=0)
7990
ret= iso_node_set_name(node, leafname);
7994
Xorriso_process_msg_queues(xorriso,0);
7995
Xorriso_report_iso_error(xorriso, eff_dest, 0, "Cannot set name", 0,
7999
Xorriso_process_msg_queues(xorriso,0);
8000
ret= iso_dir_add_node(dest_dir, node, 0);
8002
Xorriso_process_msg_queues(xorriso,0);
8003
Xorriso_report_iso_error(xorriso, eff_dest, 0, "Cannot add", 0, "FATAL", 1);
8004
sprintf(xorriso->info_text,
8005
"Internal error on rename: failed to insert node");
8006
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
8013
/* @param flag bit0= do not produce info message on success
8015
0=was already directory, -1=was other type, -2=other error
8017
int Xorriso_mkdir(struct XorrisO *xorriso, char *path, int flag)
8020
char eff_path[SfileadrL], sfe[5*SfileadrL];
8022
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 1);
8026
sprintf(xorriso->info_text,"-mkdir: Address already existing %s",
8027
Text_shellsafe(eff_path, sfe, 0));
8028
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
8029
(ret==2 ? "WARNING" : "FAILURE"), 0);
8030
return(-1+(ret==2));
8032
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 2);
8035
ret= Xorriso_graft_in(xorriso, NULL, NULL, eff_path, (off_t) 0, (off_t) 0, 1);
8039
sprintf(xorriso->info_text, "Created directory in ISO image: %s\n",
8040
Text_shellsafe(eff_path,sfe,0));
8041
Xorriso_info(xorriso, 0);
8047
/* @param flag bit0= count results rather than storing them
8048
bit1= this is a recursion
8049
bit2= prepend wd (automatically done if wd[0]!=0)
8051
int Xorriso_obtain_pattern_files_i(
8052
struct XorrisO *xorriso, char *wd, IsoDir *dir,
8053
int *filec, char **filev, int count_limit, off_t *mem,
8054
int *dive_count, int flag)
8057
IsoDirIter *iter= NULL;
8062
adr= malloc(SfileadrL);
8064
Xorriso_no_malloc_memory(xorriso, &adr, 0);
8072
ret= Xorriso_check_for_root_pattern(xorriso, filec, filev, count_limit,
8077
ret= iso_dir_get_children(dir, &iter);
8079
Xorriso_cannot_create_iter(xorriso, ret, 0);
8082
while(iso_dir_iter_next(iter, &node) == 1) {
8083
name= (char *) iso_node_get_name(node);
8084
ret= Xorriso_make_abs_adr(xorriso, wd, name, adr, flag&4);
8087
ret= Xorriso_regexec(xorriso, adr, &failed_at, 1);
8088
if(ret) { /* no match */
8089
if(failed_at <= *dive_count) /* no hope for a match */
8092
if(!LIBISO_ISDIR(node)) {
8094
/* >>> How to deal with softlinks ? */
8099
ret= Xorriso_obtain_pattern_files_i(
8100
xorriso, adr, (IsoDir *) node,
8101
filec, filev, count_limit, mem, dive_count, flag|2);
8105
ret= Xorriso_register_matched_adr(xorriso, adr, count_limit,
8106
filec, filev, mem, (flag&1)|2);
8118
iso_dir_iter_free(iter);
8123
/* @param flag bit0= a match count !=1 is a FAILURE event
8124
bit1= with bit0 tolerate 0 matches if pattern is a constant
8126
int Xorriso_expand_pattern(struct XorrisO *xorriso,
8127
int num_patterns, char **patterns, int extra_filec,
8128
int *filec, char ***filev, off_t *mem, int flag)
8130
int ret, count= 0, abs_adr= 0, i, was_count, was_filec;
8131
int nonconst_mismatches= 0, dive_count= 0;
8132
char sfe[5*SfileadrL];
8134
IsoDir *dir= NULL, *root_dir;
8140
xorriso->search_mode= 3;
8141
xorriso->structured_search= 1;
8143
ret= Xorriso_get_volume(xorriso, &volume, 0);
8146
root_dir= iso_image_get_root(volume);
8147
if(root_dir==NULL) {
8148
Xorriso_process_msg_queues(xorriso,0);
8149
sprintf(xorriso->info_text,
8150
"While expanding pattern : Cannot obtain root node of ISO image");
8151
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
8155
for(i= 0; i<num_patterns; i++) {
8156
ret= Xorriso_prepare_expansion_pattern(xorriso, patterns[i], 0);
8161
if(patterns[i][0]=='/' || abs_adr) {
8165
/* This is done so late to allow the following:
8166
It is not an error if xorriso->wdi does not exist yet, but one may
8167
not use it as base for relative address searches.
8169
ret= Xorriso_node_from_path(xorriso, volume, xorriso->wdi, &iso_node, 1);
8170
dir= (IsoDir *) iso_node;
8172
Xorriso_process_msg_queues(xorriso,0);
8173
sprintf(xorriso->info_text,
8174
"While expanding pattern %s : Working directory does not exist in ISO image",
8175
Text_shellsafe(patterns[i], sfe, 0));
8176
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
8179
if(!LIBISO_ISDIR((IsoNode *) dir)) {
8180
sprintf(xorriso->info_text,
8181
"Working directory path does not lead to a directory in ISO image");
8182
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
8187
/* count the matches */
8189
ret= Xorriso_obtain_pattern_files_i(xorriso, "", dir, &count, NULL, 0,
8190
mem, &dive_count, 1 | abs_adr);
8193
if(was_count==count && strcmp(patterns[i],"*")!=0 && (flag&3)!=1) {
8195
Xorriso_eval_nonmatch(xorriso, patterns[i], &nonconst_mismatches, mem, 0);
8199
ret= Xorriso_check_matchcount(xorriso, count, nonconst_mismatches,
8200
num_patterns, patterns, (flag&1)|2);
8203
count+= extra_filec;
8204
mem+= extra_filec*sizeof(char *);
8207
ret= Xorriso_alloc_pattern_mem(xorriso, *mem, count, filev, 0);
8210
/* now store addresses */
8211
for(i= 0; i<num_patterns; i++) {
8212
ret= Xorriso_prepare_expansion_pattern(xorriso, patterns[i], 0);
8219
ret= Xorriso_obtain_pattern_files_i(xorriso, "", dir, filec, *filev, count,
8220
mem, &dive_count, abs_adr);
8223
if(was_filec == *filec && strcmp(patterns[i],"*")!=0) {
8224
(*filev)[*filec]= strdup(patterns[i]);
8225
if((*filev)[*filec]==NULL) {
8226
(*mem)= strlen(patterns[i])+1;
8227
Xorriso_no_pattern_memory(xorriso, *mem, 0);
8237
Sfile_destroy_argv(&count, filev, 0);
8244
int Xorriso_set_st_mode(struct XorrisO *xorriso, char *in_path,
8245
mode_t mode_and, mode_t mode_or, int flag)
8250
char sfe[5*SfileadrL], path[SfileadrL];
8252
ret= Xorriso_get_node_by_path(xorriso, in_path, path, &node, 0);
8255
mode= iso_node_get_permissions(node);
8256
mode= (mode & mode_and) | mode_or;
8257
iso_node_set_permissions(node, mode);
8258
iso_node_set_ctime(node, time(NULL));
8259
sprintf(xorriso->info_text,"Permissions now: %-5.5o %s",
8260
(unsigned int) (mode & 0xffff), Text_shellsafe(path, sfe, 0));
8261
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
8262
Xorriso_set_change_pending(xorriso, 0);
8263
Xorriso_process_msg_queues(xorriso,0);
8268
int Xorriso_set_uid(struct XorrisO *xorriso, char *in_path, uid_t uid,
8274
ret= Xorriso_get_node_by_path(xorriso, in_path, NULL, &node, 0);
8277
iso_node_set_uid(node, uid);
8278
iso_node_set_ctime(node, time(NULL));
8279
Xorriso_set_change_pending(xorriso, 0);
8280
Xorriso_process_msg_queues(xorriso,0);
8285
int Xorriso_set_gid(struct XorrisO *xorriso, char *in_path, gid_t gid,
8291
ret= Xorriso_get_node_by_path(xorriso, in_path, NULL, &node, 0);
8294
iso_node_set_gid(node, gid);
8295
iso_node_set_ctime(node, time(NULL));
8296
Xorriso_set_change_pending(xorriso, 0);
8297
Xorriso_process_msg_queues(xorriso,0);
8302
/* @parm flag bit0= atime, bit1= ctime, bit2= mtime, bit8=no auto ctime */
8303
int Xorriso_set_time(struct XorrisO *xorriso, char *in_path, time_t t,
8309
ret= Xorriso_get_node_by_path(xorriso, in_path, NULL, &node, 0);
8313
iso_node_set_atime(node, t);
8315
iso_node_set_ctime(node, t);
8317
iso_node_set_mtime(node, t);
8319
iso_node_set_ctime(node, time(NULL));
8320
Xorriso_set_change_pending(xorriso, 0);
8321
Xorriso_process_msg_queues(xorriso,0);
8326
int Xorriso__start_end_lbas(IsoNode *node,
8327
int *lba_count, int **start_lbas, int **end_lbas,
8328
off_t *size, int flag)
8330
int section_count= 0, ret, i;
8331
struct iso_file_section *sections= NULL;
8334
*start_lbas= *end_lbas= NULL;
8336
if(!LIBISO_ISREG(node))
8338
*size= iso_file_get_size((IsoFile *) node);
8339
ret= iso_file_get_old_image_sections((IsoFile *) node, §ion_count,
8343
if(ret != 1 || section_count <= 0)
8345
*start_lbas= calloc(section_count, sizeof(int));
8346
*end_lbas= calloc(section_count, sizeof(int));
8347
if(*start_lbas == NULL || *end_lbas == NULL)
8349
for(i= 0; i < section_count; i++) {
8350
(*start_lbas)[i]= sections[i].block;
8351
(*end_lbas)[i]= sections[i].block + sections[i].size / 2048 - 1;
8352
if(sections[i].size % 2048)
8355
*lba_count= section_count;
8358
if(sections != NULL)
8359
free((char *) sections);
8361
if((*start_lbas) != NULL)
8362
free((char *) *start_lbas);
8363
if((*end_lbas) != NULL)
8364
free((char *) *end_lbas);
8365
*start_lbas= *end_lbas= NULL;
8372
int Xorriso__file_start_lba(IsoNode *node,
8375
int *start_lbas= NULL, *end_lbas= NULL, lba_count= 0, i, ret;
8379
ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas,
8383
for(i= 0; i < lba_count; i++) {
8384
if(*lba < 0 || start_lbas[i] < *lba)
8385
*lba= start_lbas[i];
8387
if(start_lbas != NULL)
8388
free((char *) start_lbas);
8389
if(end_lbas != NULL)
8390
free((char *) end_lbas);
8397
/* @param damage_start Returns first damaged byte address
8398
@param damage_end Returns first byte address after last damaged byte
8399
@return <0 error, 0=undamaged , 1=damaged
8401
int Xorriso_file_eval_damage(struct XorrisO *xorriso, IsoNode *node,
8402
off_t *damage_start, off_t *damage_end,
8405
int *start_lbas= NULL, *end_lbas= NULL, lba_count= 0, sect;
8406
int i, sectors, sector_size, ret;
8407
off_t sect_base= 0, size= 0, byte;
8408
struct SectorbitmaP *map;
8410
*damage_start= *damage_end= -1;
8411
map= xorriso->in_sector_map;
8414
Sectorbitmap_get_layout(map, §ors, §or_size, 0);
8417
ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas,
8420
Xorriso_process_msg_queues(xorriso, 0);
8423
for(sect= 0; sect < lba_count; sect++) {
8424
for(i= start_lbas[sect]; i <= end_lbas[sect]; i+= sector_size) {
8425
if(Sectorbitmap_is_set(map, i / sector_size, 0) == 0) {
8426
byte= ((off_t) 2048) * ((off_t) (i - start_lbas[sect])) + sect_base;
8427
if(*damage_start < 0 || byte < *damage_start)
8428
*damage_start= byte;
8429
if(byte + (off_t) 2048 > *damage_end)
8430
*damage_end= byte + (off_t) 2048;
8433
sect_base+= ((off_t) 2048) *
8434
((off_t) (end_lbas[sect] - start_lbas[sect] + 1));
8436
if(*damage_end > size)
8438
if(start_lbas != NULL)
8439
free((char *) start_lbas);
8440
if(end_lbas != NULL)
8441
free((char *) end_lbas);
8442
if(*damage_start < 0)
8448
int Xorriso_report_lba(struct XorrisO *xorriso, char *show_path,
8449
IsoNode *node, int flag)
8451
int ret, *start_lbas= NULL, *end_lbas= NULL, lba_count, i;
8453
char sfe[5*SfileadrL];
8455
ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas,
8458
Xorriso_process_msg_queues(xorriso, 0);
8462
{ret= 1; goto ex;} /* it is ok to ignore other types */
8463
for(i= 0; i < lba_count; i++) {
8464
sprintf(xorriso->result_line,
8465
"File data lba: %2d , %8d , %8d , %8.f , %s\n",
8466
i, start_lbas[i], end_lbas[i] + 1 - start_lbas[i], (double) size,
8467
Text_shellsafe(show_path, sfe, 0));
8468
Xorriso_result(xorriso, 0);
8472
if(start_lbas != NULL)
8473
free((char *) start_lbas);
8474
if(end_lbas != NULL)
8475
free((char *) end_lbas);
8480
int Xorriso_report_damage(struct XorrisO *xorriso, char *show_path,
8481
IsoNode *node, int flag)
8484
off_t size= 0, damage_start, damage_end;
8485
char sfe[5*SfileadrL];
8487
ret= Xorriso_file_eval_damage(xorriso, node, &damage_start, &damage_end, 0);
8491
if(LIBISO_ISREG(node))
8492
size= iso_file_get_size((IsoFile *) node);
8494
sprintf(xorriso->result_line, "File damaged : %8.f , %8.f , %8.f , %s\n",
8495
(double) damage_start, (double) (damage_end - damage_start) ,
8496
(double) size, Text_shellsafe(show_path, sfe, 0));
8497
Xorriso_result(xorriso, 0);
8499
sprintf(xorriso->result_line, "File seems ok: %8.f , %8.f , %8.f , %s\n",
8500
-1.0, -1.0, (double) size, Text_shellsafe(show_path, sfe, 0));
8501
Xorriso_result(xorriso, 0);
8507
/* @return see Xorriso_update_interpreter()
8509
int Xorriso_widen_hardlink(struct XorrisO *xorriso, void * boss_iter,
8511
char *abs_path, char *iso_prefix, char *disk_prefix,
8514
int ret= 0, idx, low, high, i, do_widen= 0, compare_result= 0;
8515
char disk_path[SfileadrL];
8517
/* Lookup all di_array instances of node */
8518
if(LIBISO_ISDIR(node))
8520
ret= Xorriso_search_di_range(xorriso, node, &idx, &low, &high, 2);
8523
/* Check and reset di_do_widen bits */
8524
for(i= low; i <= high; i++) {
8525
if(node != xorriso->di_array[i]) /* might be NULL */
8527
if(xorriso->di_do_widen[i / 8] & (1 << (i % 8)))
8529
xorriso->di_do_widen[i / 8]&= ~(1 << (i % 8));
8531
if(idx < 0 || !do_widen)
8534
ret= Xorriso_pfx_disk_path(xorriso, abs_path, iso_prefix, disk_prefix,
8538
ret= Sfile_type(disk_path, 1);
8540
return(3); /* does not exist on disk */
8542
/* >>> compare_result bit17 = is_split */;
8544
ret= Xorriso_update_interpreter(xorriso, boss_iter, compare_result, disk_path,
8553
Apply the effect of mkisofs -r to a single node
8555
int Xorriso_mkisofs_lower_r(struct XorrisO *xorriso, IsoNode *node, int flag)
8559
perms= iso_node_get_permissions(node);
8560
iso_node_set_uid(node, (uid_t) 0);
8561
iso_node_set_gid(node, (gid_t) 0);
8562
perms|= S_IRUSR | S_IRGRP | S_IROTH;
8563
perms&= ~(S_IWUSR | S_IWGRP | S_IWOTH);
8564
if(perms & (S_IXUSR | S_IXGRP | S_IXOTH))
8565
perms|= (S_IXUSR | S_IXGRP | S_IXOTH);
8566
perms&= ~(S_ISUID | S_ISGID | S_ISVTX);
8567
iso_node_set_permissions(node, perms);
8572
/* @param flag bit0= not a command parameter (directory iteration or recursion)
8573
bit1= do not count deleted files with rm and rm_r
8576
2=ok, node has been deleted,
8577
3=ok, do not dive into directory (e.g. because it is a split file)
8579
int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job,
8580
IsoDirIter *boss_iter, off_t boss_mem,
8581
char *abs_path, char *show_path,
8582
IsoNode *node, int depth, int flag)
8584
int ret= 0, type, action= 0, hflag, deleted= 0, no_dive= 0;
8588
mode_t mode_or= 0, mode_and= ~1;
8589
char *target, *text_2, sfe[5*SfileadrL], *iso_prefix, md5[16];
8590
struct FindjoB *subjob;
8591
struct stat dir_stbuf;
8593
action= Findjob_get_action_parms(job, &target, &text_2, &user, &group,
8594
&mode_and, &mode_or, &type, &date, &subjob, 0);
8598
hflag= 16*!(flag&2);
8600
if(action==1) { /* rm (including rmdir) */
8601
ret= Xorriso_fake_stbuf(xorriso, abs_path, &dir_stbuf, &node, 1);
8603
if(S_ISDIR(dir_stbuf.st_mode))
8605
ret= Xorriso_rmi(xorriso, boss_iter, boss_mem, abs_path, hflag);
8608
} else if(action==2) { /* rm_r */
8609
ret= Xorriso_rmi(xorriso, boss_iter, boss_mem, abs_path, 1|hflag);
8611
} else if(action==3) {
8613
/* >>> mv target */;
8615
} else if(action==4) { /* chown */
8616
ret= Xorriso_set_uid(xorriso, abs_path, user, 0);
8617
} else if(action==5) { /* chgrp */
8618
ret= Xorriso_set_gid(xorriso, abs_path, group, 0);
8619
} else if(action==6) { /* chmod */
8620
ret= Xorriso_set_st_mode(xorriso, abs_path, mode_and, mode_or, 0);
8621
} else if(action==7) { /* alter_date */
8622
ret= Xorriso_set_time(xorriso, abs_path, date, type&7);
8623
} else if(action==8) { /* lsdl */
8624
ret= Xorriso_ls_filev(xorriso, "", 1, &abs_path, (off_t) 0, 1|2|8);
8625
} else if(action>=9 && action<=13) { /* actions which have own findjobs */
8626
Findjob_set_start_path(subjob, abs_path, 0);
8627
ret= Xorriso_findi(xorriso, subjob, boss_iter, boss_mem, NULL,
8628
abs_path, &dir_stbuf, depth, 1);
8629
} else if(action==14 || action==17) { /* compare , update */
8630
Findjob_get_start_path(job, &iso_prefix, 0);
8631
ret= Xorriso_find_compare(xorriso, (void *) boss_iter, abs_path,
8632
iso_prefix, target, (action==17)|((flag&1)<<1));
8639
} else if(action==16 || action==18) { /* not_in_iso , add_missing */
8641
} else if(action == 21) { /* report_damage */
8642
ret= Xorriso_report_damage(xorriso, show_path, node, 0);
8643
} else if(action == 22) {
8644
ret= Xorriso_report_lba(xorriso, show_path, node, 0);
8645
} else if(action == 23) { /* internal: memorize path of last matching node */
8646
ret= Findjob_set_found_path(job, show_path, 0);
8647
} else if(action == 24) {
8648
ret= Xorriso_getfacl(xorriso, (void *) node, show_path, NULL, 0);
8649
} else if(action == 25) {
8650
if(target == NULL || target[0] || text_2 == NULL || text_2[0])
8651
ret= Xorriso_setfacl(xorriso, (void *) node, show_path, target, text_2,0);
8652
} else if(action == 26) {
8653
ret= Xorriso_getfattr(xorriso, (void *) node, show_path, NULL, 0);
8654
} else if(action == 27) {
8655
ret= Xorriso_path_setfattr(xorriso, (void *) node, show_path,
8656
target, strlen(text_2), text_2, 0);
8657
} else if(action == 28) { /* set_filter */
8658
ret= Xorriso_set_filter(xorriso, (void *) node, show_path, target, 1 | 2);
8659
} else if(action == 29) { /* show_stream */
8660
ret= Xorriso_show_stream(xorriso, (void *) node, show_path, 1 | 2);
8661
} else if(action == 30) { /* internal: count */
8662
xorriso->node_counter++;
8663
} else if(action == 31) { /* internal: register */
8664
if(xorriso->node_counter < xorriso->node_array_size) {
8665
xorriso->node_array[xorriso->node_counter++]= (void *) node;
8666
iso_node_ref(node); /* In case node gets deleted from tree during
8667
the lifetime of xorriso->node_array */
8669
} else if(action == 32) { /* internal: widen_hardlinks disk_equiv */
8670
Findjob_get_start_path(job, &iso_prefix, 0);
8671
ret= Xorriso_widen_hardlink(xorriso, (void *) boss_iter, node, abs_path,
8672
iso_prefix, target, 0);
8675
} else if(action == 33) { /* get_any_xattr */
8676
ret= Xorriso_getfattr(xorriso, (void *) node, show_path, NULL, 8);
8677
} else if(action == 34) { /* get_md5 */
8678
ret= Xorriso_get_md5(xorriso, (void *) node, show_path, md5, 0);
8681
} else if(action == 35) { /* check_md5 */
8682
ret= Xorriso_check_md5(xorriso, (void *) node, show_path, 2);
8684
xorriso->find_check_md5_result|= 1;
8686
xorriso->find_check_md5_result|= 2;
8688
xorriso->find_check_md5_result|= 8;
8690
xorriso->find_check_md5_result|= 4;
8693
} else if(action == 36) { /* make_md5 */
8694
ret= Xorriso_make_md5(xorriso, (void *) node, show_path, 0);
8697
} else if(action == 37) { /* mkisofs_r */
8698
ret= Xorriso_mkisofs_lower_r(xorriso, node, 0);
8699
} else if(action == 38) { /* sort_weight */
8700
iso_node_set_sort_weight(node, type);
8701
} else { /* includes : 15 in_iso */
8702
sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0));
8703
Xorriso_result(xorriso, 0);
8716
int Exprtest_match(struct XorrisO *xorriso, struct ExprtesT *ftest,
8717
void *node_pt, char *name, char *path,
8718
struct stat *boss_stbuf, struct stat *stbuf, int flag)
8724
2 = immediate decision : does not match
8725
3 = immediate decision : does match
8728
int value=0, ret, start_lba, end_lba;
8729
int lba_count, *file_end_lbas= NULL, *file_start_lbas= NULL, i;
8731
char ft, *decision, md5[16];
8732
regmatch_t name_match;
8733
off_t damage_start, damage_end, size;
8741
node= (IsoNode *) node_pt;
8746
if(ftest->test_type > 2 && ftest->test_type != 4) {
8752
switch(ftest->test_type) {
8753
case 0: /* -false */
8756
break; case 1: /* -name *arg1 (regex in *arg2) */
8757
ret= regexec(arg2, name, 1, &name_match, 0);
8760
break; case 2: /* -type *arg1 */
8762
ft= *((char *) arg1);
8764
if(S_ISBLK(stbuf->st_mode)) {
8767
} else if(S_ISCHR(stbuf->st_mode)) {
8770
} else if(S_ISDIR(stbuf->st_mode)) {
8774
else if(boss_stbuf==NULL)
8776
else if(boss_stbuf->st_dev == stbuf->st_dev)
8780
} else if(S_ISFIFO(stbuf->st_mode)) {
8783
} else if(S_ISREG(stbuf->st_mode)) {
8784
if(ft!='f' && ft!='-')
8786
} else if(((stbuf->st_mode)&S_IFMT)==S_IFLNK) {
8789
} else if(((stbuf->st_mode)&S_IFMT)==S_IFSOCK) {
8792
} else if((flag & 1) && ((stbuf->st_mode) & S_IFMT) == Xorriso_IFBOOT) {
8793
if(ft!='e' || node == NULL)
8801
break; case 3: /* -damaged */;
8802
value= Xorriso_file_eval_damage(xorriso, node, &damage_start, &damage_end,
8807
break; case 4: /* -lba_range *arg1 *arg2 */
8809
start_lba= *((int *) ftest->arg1);
8810
end_lba= *((int *) ftest->arg2);
8812
value= !(start_lba >= 0);
8815
ret= Xorriso__start_end_lbas(node, &lba_count,
8816
&file_start_lbas, &file_end_lbas, &size, 0);
8819
Xorriso_process_msg_queues(xorriso, 0);
8823
for(i= 0; i < lba_count; i++) {
8824
if(start_lba >= 0) {
8825
if(file_end_lbas[i] < start_lba || file_start_lbas[i] > end_lba)
8828
if(file_end_lbas[i] >= -start_lba && file_start_lbas[i] <= -end_lba)
8834
break; case 5: /* -has_acl */
8835
ret = Xorriso_getfacl(xorriso, (void *) node, "", NULL, 2);
8838
Xorriso_process_msg_queues(xorriso, 0);
8843
break; case 6: /* -has_xattr */
8844
case 14: /* -has_any_xattr */
8845
ret = Xorriso_getfattr(xorriso, (void *) node, "", NULL,
8846
64 | (8 * (ftest->test_type == 14)));
8849
Xorriso_process_msg_queues(xorriso, 0);
8854
break; case 7: /* -has_aaip */
8855
ret= iso_node_get_xinfo(node, aaip_xinfo_func, &xinfo_dummy);
8858
Xorriso_process_msg_queues(xorriso, 0);
8863
break; case 8: /* -has_filter */
8865
if(LIBISO_ISREG(node)) {
8866
stream= iso_file_get_stream((IsoFile *) node);
8867
if(iso_stream_get_input_stream(stream, 0) != NULL)
8871
break; case 9: /* -wanted_node arg1 (for internal use) */
8872
value= (((IsoNode *) arg1) == node);
8874
break; case 10: /* -pending_data */
8876
if(!LIBISO_ISREG(node)) {
8879
ret= Xorriso__file_start_lba(node, &start_lba, 0);
8880
if(ret > 0 && start_lba >= 0)
8884
break; case 11: /* -decision */
8886
decision= (char *) arg1;
8887
if(strcmp(decision, "yes") == 0 || strcmp(decision, "true") == 0)
8890
break; case 12: /* -prune */
8892
ftest->boss->prune= 1;
8894
break; case 13: /* -wholename *arg1 (regex in *arg2) */
8895
ret= regexec(arg2, path, 1, &name_match, 0);
8898
break; case 15: /* -has_md5 */
8899
ret= Xorriso_get_md5(xorriso, node, path, md5, 1);
8904
/* >>> complain about unknown test type */;
8911
if(ftest->invert && value<=1 && value>=0)
8913
if(file_start_lbas != NULL)
8914
free((char *) file_start_lbas);
8915
if(file_end_lbas != NULL)
8916
free((char *) file_end_lbas);
8921
/* @return <0 = error , 0 = no match , 1 = match */
8922
int Xorriso_findi_test(struct XorrisO *xorriso, struct FindjoB *job,
8923
IsoNode *node, char *name, char *path,
8924
struct stat *boss_stbuf, struct stat *stbuf,
8925
int depth, int flag)
8930
ret= Findjob_test_2(xorriso, job, node, name, path, boss_stbuf, stbuf, 1);
8937
int Xorriso_findi_headline(struct XorrisO *xorriso, struct FindjoB *job,
8942
action= Findjob_get_action(job, 0);
8943
if(action == 21) { /* report_damage */
8944
sprintf(xorriso->result_line, "Report layout: %8s , %8s , %8s , %s\n",
8945
"at byte", "Range", "Filesize", "ISO image path");
8946
Xorriso_result(xorriso, 0);
8947
} else if(action == 22) { /* report_lba */
8948
sprintf(xorriso->result_line,
8949
"Report layout: %2s , %8s , %8s , %8s , %s\n",
8950
"xt", "Startlba", "Blocks", "Filesize", "ISO image path");
8951
Xorriso_result(xorriso, 0);
8957
/* @param flag bit0= recursion
8958
bit1= do not count deleted files with rm and rm_r
8959
bit2= do not dive into split file directories
8960
(implicitly given with actions 14=compare and 17=update)
8961
@return <=0 error, 1= ok , 2= dir node and path has been deleted
8963
int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job,
8964
void *boss_iter, off_t boss_mem,
8965
void *dir_node_generic, char *dir_path,
8966
struct stat *dir_stbuf, int depth, int flag)
8968
int ret, action= 0, hflag, deleted= 0, no_dive= 0;
8969
IsoDirIter *iter= NULL;
8970
IsoDir *dir_node= NULL;
8971
IsoNode *node, *iso_node;
8972
IsoImage *volume= NULL;
8976
IsoNode **node_array= NULL;
8977
int node_count, node_idx;
8978
char *path= NULL, *abs_path= NULL;
8980
if(xorriso->request_to_abort)
8983
path= malloc(SfileadrL);
8984
abs_path= malloc(SfileadrL);
8985
if(path==NULL || abs_path==NULL) {
8986
Xorriso_no_malloc_memory(xorriso, &path, 0);
8990
action= Findjob_get_action(job, 0);
8994
Xorriso_findi_headline(xorriso, job, 0);
8996
dir_node= (IsoDir *) dir_node_generic;
8997
if(dir_node==NULL) {
8998
ret= Xorriso_get_volume(xorriso, &volume, 0);
9001
ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, dir_path, path, 1|2|4);
9004
ret= Xorriso_node_from_path(xorriso, volume, path, &iso_node, 0);
9005
dir_node= (IsoDir *) iso_node;
9008
ret= Xorriso_fake_stbuf(xorriso, "", dir_stbuf, &iso_node, 1);
9012
name= strrchr(dir_path, '/');
9018
ret= Xorriso_findi_test(xorriso, job, iso_node, name, path, NULL, dir_stbuf,
9025
iso_node_ref(iso_node); /* protect from real disposal */
9026
ret= Xorriso_findi_action(xorriso, job,
9027
(IsoDirIter *) boss_iter, boss_mem,
9028
path, dir_path, iso_node, depth,
9030
deleted= (iso_node_get_parent(iso_node) == NULL); /* still in tree ? */
9031
iso_node_unref(iso_node); /* eventually do real disposal */
9034
if(xorriso->request_to_abort)
9036
if(ret==2 || deleted) {
9037
/* re-determine dir_node in case it has a new persona */
9038
ret= Xorriso_node_from_path(xorriso, volume, path, &iso_node, 1);
9045
dir_node= (IsoDir *) iso_node;
9046
ret= Xorriso_fake_stbuf(xorriso, "", dir_stbuf, &iso_node, 1);
9054
if(no_dive || !LIBISO_ISDIR((IsoNode *) dir_node))
9056
if(action == 14 || action == 17 || (flag & 4))
9057
if(Xorriso_is_split(xorriso, dir_path, (IsoNode *) dir_node, 1)>0)
9062
if(action==1 || action==2 || action==3 || action==17 || action == 28 ||
9064
hflag|= 2; /* need freedom to manipulate image */
9065
if(action==14 || action==17 || action == 28 || action == 35 || action == 36)
9066
hflag|= 4; /* need LBA sorted iteration for good data reading performance */
9067
ret= Xorriso_findi_iter(xorriso, dir_node, &mem,
9068
&iter, &node_array, &node_count, &node_idx,
9073
ret= Xorriso_findi_iter(xorriso, dir_node, &mem, &iter,
9074
&node_array, &node_count, &node_idx, &node, 0);
9079
name= (char *) iso_node_get_name(node);
9080
ret= Xorriso_make_abs_adr(xorriso, dir_path, name, path, 4);
9083
ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1);
9089
/* ??? This seems to be redundant with the single test above
9090
??? Should i dive in unconditionally and leave out test and action here ?
9091
??? Then do above test unconditionally ?
9092
--- Seems that the current configuration represents the special
9093
handling of the find start path with mount points. Dangerous to change.
9096
ret= Xorriso_findi_test(xorriso, job, node, name, path, dir_stbuf, &stbuf,
9103
ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, path, abs_path, 1|2|4);
9106
ret= Xorriso_findi_action(xorriso, job, iter, mem,
9107
abs_path, path, node, depth, 1|(flag&2));
9108
if(xorriso->request_to_abort)
9110
if(ret==2) { /* node has been deleted */
9111
/* re-determine node in case it has a new persona */
9113
ret= Xorriso_get_volume(xorriso, &volume, 0);
9117
ret= Xorriso_node_from_path(xorriso, volume, abs_path, &node, 1);
9122
ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1);
9130
if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0)
9135
if(S_ISDIR(stbuf.st_mode) && !no_dive) {
9136
ret= Xorriso_findi(xorriso, job, (void *) iter, mem,
9137
(void *) node, path, &stbuf, depth+1, flag|1);
9149
Xorriso_process_msg_queues(xorriso,0);
9151
Xorriso_findi_iter(xorriso, dir_node, &mem, &iter, &node_array, &node_count,
9152
&node_idx, &node, (1<<31));
9161
int Xorriso_node_is_valid(struct XorrisO *xorriso, IsoNode *in_node, int flag)
9163
IsoNode *node, *parent;
9165
for(node= in_node; 1; node= parent) {
9166
parent= (IsoNode *) iso_node_get_parent(node);
9170
return(0); /* Node is not in the tree (any more) */
9176
int Xorriso_path_from_node(struct XorrisO *xorriso, IsoNode *in_node,
9177
char path[SfileadrL], int flag)
9179
int ret, i, comp_count= 0;
9180
IsoNode *node, *parent, **components= NULL;
9183
for(node= in_node; 1; node= parent) {
9184
parent= (IsoNode *) iso_node_get_parent(node);
9188
return(0); /* Node is not in the tree (any more) */
9191
if(comp_count == 0) {
9195
components= calloc(comp_count, sizeof(IsoNode *));
9196
if(components == NULL) {
9197
Xorriso_no_malloc_memory(xorriso, NULL, 0);
9201
for(node= in_node; 1; node= parent) {
9202
parent= (IsoNode *) iso_node_get_parent(node);
9205
components[--i]= node;
9209
for(i= 0; i < comp_count; i++) {
9210
npt= (char *) iso_node_get_name(components[i]);
9211
if((wpt - path) + strlen(npt) + 1 >= SfileadrL) {
9213
/* >>> path is getting much too long */;
9224
if(components != NULL)
9230
/* <<< The lookup from node pointer will be done by Xorriso_path_from_node()
9231
(Currently it runs a full tree traversal)
9232
Parameter node and flag bit0 will vanish then
9234
/* @param flag bit0= use lba rather than node pointer
9236
int Xorriso_path_from_lba(struct XorrisO *xorriso, IsoNode *node, int lba,
9237
char path[SfileadrL], int flag)
9240
struct FindjoB *job= NULL;
9241
struct stat dir_stbuf;
9245
if((flag & 1) && lba <= 0)
9248
ret= Findjob_new(&job, "/", 0);
9250
Xorriso_no_findjob(xorriso, "path_from_node", 0);
9254
Findjob_set_lba_range(job, lba, 1, 0);
9256
Findjob_set_wanted_node(job, (void *) node, 0);
9257
Findjob_set_action_found_path(job, 0);
9258
ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0,
9259
NULL, "/", &dir_stbuf, 0, 0);
9262
Findjob_get_found_path(job, &found_path, 0);
9263
if(found_path == NULL)
9265
else if(Sfile_str(path, found_path, 0) <= 0)
9268
Findjob_destroy(&job, 0);
9273
/* @param flag bit0= do not dive into trees
9274
bit1= do not perform job->action on resulting node array
9275
bit2= do not free node_array after all actions are done
9277
int Xorriso_findi_sorted(struct XorrisO *xorriso, struct FindjoB *job,
9278
off_t boss_mem, int filec, char **filev, int flag)
9280
int i, ret, find_flag= 0;
9281
struct FindjoB array_job, *proxy_job= NULL, *hindmost= NULL, *hmboss= NULL;
9282
struct stat dir_stbuf;
9284
char abs_path[SfileadrL];
9285
off_t mem_needed= 0;
9287
array_job.start_path= NULL;
9289
if(job->action == 14 || job->action == 17)
9291
if(job->action>=9 && job->action<=13) { /* actions which have own findjobs */
9292
/* array_job replaces the hindmost job in the chain */
9293
for(hindmost= job; hindmost->subjob != NULL; hindmost= hindmost->subjob)
9297
memcpy(&array_job, hindmost, sizeof(struct FindjoB));
9298
hmboss->subjob= &array_job;
9301
memcpy(&array_job, job, sizeof(struct FindjoB));
9302
proxy_job= &array_job;
9305
array_job.start_path= NULL; /* is owned by the original, not by array_job */
9307
/* Count matching nodes */
9308
Xorriso_destroy_node_array(xorriso, 0);
9309
array_job.action= 30; /* internal: count */
9310
for(i= 0; i < filec; i++) {
9312
xorriso->node_counter++;
9315
ret= Findjob_set_start_path(proxy_job, filev[i], 0);
9318
ret= Xorriso_findi(xorriso, proxy_job, NULL, boss_mem, NULL,
9319
filev[i], &dir_stbuf, 0, find_flag);
9323
if(xorriso->node_counter <= 0)
9326
mem_needed= boss_mem + xorriso->node_counter * sizeof(IsoNode *);
9328
ret= Xorriso_check_temp_mem_limit(xorriso, mem_needed, 0);
9330
/* Memory curbed : Perform unsorted find jobs */
9332
hmboss->subjob= hindmost;
9333
for(i= 0; i < filec; i++) {
9334
ret= Findjob_set_start_path(job, filev[i], 0);
9337
ret= Xorriso_findi(xorriso, job, NULL, boss_mem, NULL,
9338
filev[i], &dir_stbuf, 0, find_flag);
9340
if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0)
9347
/* Copy matching nodes into allocated array */
9348
ret= Xorriso_new_node_array(xorriso, xorriso->temp_mem_limit, 0, 0);
9351
array_job.action= 31; /* internal: register */
9352
xorriso->node_counter= 0;
9353
for(i= 0; i < filec; i++) {
9355
ret= Xorriso_get_node_by_path(xorriso, filev[i], NULL, &node, 0);
9358
if(xorriso->node_counter < xorriso->node_array_size) {
9359
xorriso->node_array[xorriso->node_counter++]= (void *) node;
9364
ret= Findjob_set_start_path(proxy_job, filev[i], 0);
9367
ret= Xorriso_findi(xorriso, proxy_job, NULL, mem_needed, NULL,
9368
filev[i], &dir_stbuf, 0, find_flag);
9373
Xorriso_sort_node_array(xorriso, 0);
9377
/* Perform job->action on xorriso->node_array */
9379
/* Headlines of actions report_damage , report_lba */;
9380
Xorriso_findi_headline(xorriso, job, 0);
9382
for(i= 0; i < xorriso->node_counter; i++) {
9383
node= xorriso->node_array[i];
9384
ret= Xorriso_path_from_node(xorriso, node, abs_path, 0);
9388
continue; /* node is deleted from tree meanwhile */
9390
ret= Xorriso_findi_action(xorriso, hindmost, NULL, (off_t) 0,
9391
abs_path, abs_path, node, 0, 1);
9392
if(ret <= 0 || xorriso->request_to_abort)
9393
if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0)
9399
if(!(flag & (2 | 4)))
9400
Xorriso_destroy_node_array(xorriso, 0);
9402
hmboss->subjob= hindmost;
9403
if(array_job.start_path != NULL)
9404
free(array_job.start_path);
9409
/* @param flag bit0= do not mark image as changed */
9410
int Xorriso_set_volid(struct XorrisO *xorriso, char *volid, int flag)
9415
if(xorriso->in_volset_handle == NULL)
9417
ret= Xorriso_get_volume(xorriso, &volume, 0);
9420
iso_image_set_volume_id(volume, volid);
9422
Xorriso_set_change_pending(xorriso, 1);
9423
Xorriso_process_msg_queues(xorriso,0);
9424
sprintf(xorriso->info_text,"Volume ID: '%s'",iso_image_get_volume_id(volume));
9425
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
9430
int Xorriso_get_volid(struct XorrisO *xorriso, char volid[33], int flag)
9435
ret= Xorriso_get_volume(xorriso, &volume, 0);
9438
strncpy(volid, iso_image_get_volume_id(volume), 32);
9444
/* @param flag bit0=prepare for a burn run */
9445
int Xorriso_set_abort_severity(struct XorrisO *xorriso, int flag)
9447
int ret, abort_on_number;
9449
static int note_number= -1, failure_number= -1;
9452
Xorriso__text_to_sev("NOTE", ¬e_number, 0);
9453
if(failure_number==-1)
9454
Xorriso__text_to_sev("FAILURE", &failure_number, 0);
9455
sev_text= xorriso->abort_on_text;
9456
ret= Xorriso__text_to_sev(xorriso->abort_on_text, &abort_on_number, 0);
9459
if(abort_on_number<note_number)
9461
else if(abort_on_number>failure_number)
9462
sev_text= "FAILURE";
9463
ret= iso_set_abort_severity(sev_text);
9468
int Xorriso_report_lib_versions(struct XorrisO *xorriso, int flag)
9470
int major, minor, micro;
9471
int req_major, req_minor, req_micro;
9473
iso_lib_version(&major, &minor, µ);
9474
isoburn_libisofs_req(&req_major, &req_minor, &req_micro);
9475
sprintf(xorriso->result_line,
9476
"libisofs in use : %d.%d.%d (min. %d.%d.%d)\n",
9477
major, minor, micro, req_major, req_minor, req_micro);
9478
Xorriso_result(xorriso, 0);
9479
burn_version(&major, &minor, µ);
9480
isoburn_libburn_req(&req_major, &req_minor, &req_micro);
9481
sprintf(xorriso->result_line,
9482
"libburn in use : %d.%d.%d (min. %d.%d.%d)\n",
9483
major, minor, micro, req_major, req_minor, req_micro);
9484
Xorriso_result(xorriso, 0);
9485
strcpy(xorriso->result_line, "libburn OS adapter: ");
9486
strncat(xorriso->result_line, burn_scsi_transport_id(0), 1024);
9487
strcat(xorriso->result_line, "\n");
9488
Xorriso_result(xorriso, 0);
9489
isoburn_version(&major, &minor, µ);
9490
sprintf(xorriso->result_line,
9491
"libisoburn in use : %d.%d.%d (min. %d.%d.%d)\n",
9492
major, minor, micro,
9493
isoburn_header_version_major, isoburn_header_version_minor,
9494
isoburn_header_version_micro);
9495
Xorriso_result(xorriso, 0);
9500
/* @param flag bit0= -inq
9503
int Xorriso_atip(struct XorrisO *xorriso, int flag)
9505
int ret, profile_number= 0;
9506
char *respt, profile_name[80];
9507
double x_speed_max, x_speed_min= -1.0;
9508
struct burn_drive_info *dinfo;
9509
struct burn_drive *drive;
9510
enum burn_disc_status s;
9511
char *manuf= NULL, *media_code1= NULL, *media_code2= NULL;
9512
char *book_type= NULL, *product_id= NULL;
9514
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
9515
"on attempt to print drive and media info", 2);
9518
respt= xorriso->result_line;
9519
sprintf(respt, "Device type : ");
9520
ret= burn_drive_get_drive_role(drive);
9522
sprintf(respt+strlen(respt), "%s\n", "Emulated (null-drive)");
9524
sprintf(respt+strlen(respt), "%s\n",
9525
"Emulated (stdio-drive, 2k random read-write)");
9527
sprintf(respt+strlen(respt), "%s\n",
9528
"Emulated (stdio-drive, sequential write-only)");
9530
sprintf(respt+strlen(respt), "%s\n","Emulated (stdio-drive)");
9532
sprintf(respt+strlen(respt), "%s\n","Removable CD-ROM");
9533
sprintf(respt+strlen(respt), "Vendor_info : '%s'\n",dinfo->vendor);
9534
sprintf(respt+strlen(respt), "Identifikation : '%s'\n",dinfo->product);
9535
sprintf(respt+strlen(respt), "Revision : '%s'\n",dinfo->revision);
9536
Xorriso_result(xorriso,1);
9539
sprintf(respt, "Driver flags : BURNFREE\n");
9540
sprintf(respt+strlen(respt), "Supported modes: SAO TAO\n");
9541
Xorriso_result(xorriso,1);
9545
s= burn_disc_get_status(drive);
9546
ret= burn_disc_get_profile(drive,&profile_number,profile_name);
9549
strcpy(profile_name, "-unidentified-");
9551
if(s != BURN_DISC_UNSUITABLE) {
9552
ret= burn_disc_read_atip(drive);
9554
ret= burn_drive_get_min_write_speed(drive);
9555
x_speed_min= ((double) ret)/176.4;
9558
if(s==BURN_DISC_EMPTY) {
9559
sprintf(respt, "Current: none\n");
9560
Xorriso_result(xorriso,1);
9563
sprintf(respt, "Current: %s\n",profile_name);
9564
Xorriso_result(xorriso,1);
9565
Xorriso_list_profiles(xorriso, 1 | 2);
9566
if(strstr(profile_name,"BD")==profile_name) {
9567
printf("Mounted Media: %2.2Xh, %s\n", profile_number, profile_name);
9568
} else if(strstr(profile_name,"DVD")==profile_name) {
9569
sprintf(respt, "book type: %s (emulated booktype)\n", profile_name);
9570
Xorriso_result(xorriso,1);
9571
if(profile_number == 0x13) {
9572
sprintf(respt, "xorriso: message for sdvdbackup: \"(growisofs mode Restricted Overwrite)\"\n");
9573
Xorriso_result(xorriso,1);
9576
sprintf(respt, "ATIP info from disk:\n");
9577
Xorriso_result(xorriso,1);
9578
if(burn_disc_erasable(drive))
9579
sprintf(respt, " Is erasable\n");
9581
sprintf(respt, " Is not erasable\n");
9582
Xorriso_result(xorriso,1);
9583
{ int start_lba,end_lba,min,sec,fr;
9584
ret= burn_drive_get_start_end_lba(drive,&start_lba,&end_lba,0);
9586
burn_lba_to_msf(start_lba,&min,&sec,&fr);
9587
sprintf(respt, " ATIP start of lead in: %d (%-2.2d:%-2.2d/%-2.2d)\n",
9588
start_lba,min,sec,fr);
9589
Xorriso_result(xorriso,1);
9590
burn_lba_to_msf(end_lba,&min,&sec,&fr);
9591
sprintf(respt, " ATIP start of lead out: %d (%-2.2d:%-2.2d/%-2.2d)\n",
9592
end_lba,min,sec,fr);
9593
Xorriso_result(xorriso,1);
9596
ret= burn_drive_get_write_speed(drive);
9597
x_speed_max= ((double) ret)/176.4;
9599
x_speed_min= x_speed_max;
9601
" 1T speed low: %.f 1T speed high: %.f\n",x_speed_min,x_speed_max);
9602
Xorriso_result(xorriso,1);
9605
ret= burn_disc_get_media_id(drive, &product_id, &media_code1, &media_code2,
9607
if(ret > 0 && media_code1 != NULL && media_code2 != NULL)
9608
manuf= burn_guess_manufacturer(profile_number, media_code1, media_code2, 0);
9609
if(product_id != NULL) {
9610
sprintf(respt, "Product Id: %s\n", product_id);
9611
Xorriso_result(xorriso,1);
9614
sprintf(respt, "Producer: %s\n", manuf);
9615
Xorriso_result(xorriso, 1);
9617
if(profile_number == 0x09 || profile_number == 0x0a) {
9618
sprintf(respt, "Manufacturer: %s\n", manuf);
9619
Xorriso_result(xorriso, 1);
9620
} else if(product_id != NULL && media_code1 != NULL && media_code2 != NULL){
9624
if(book_type != NULL)
9626
product_id= media_code1= media_code2= book_type= NULL;
9627
ret= burn_disc_get_media_id(drive, &product_id, &media_code1, &media_code2,
9630
sprintf(respt, "Manufacturer: '%s'\n", media_code1);
9631
Xorriso_result(xorriso, 1);
9632
if(media_code2[0]) {
9633
sprintf(respt, "Media type: '%s'\n", media_code2);
9634
Xorriso_result(xorriso, 1);
9640
if(media_code1 != NULL)
9642
if(media_code2 != NULL)
9644
if(book_type != NULL)
9646
if(product_id != NULL)
9652
int Xorriso_update_in_sector_map(struct XorrisO *xorriso,
9653
struct SpotlisT *spotlist, int read_chunk,
9654
struct CheckmediajoB *job, int flag)
9656
int sectors, sector_size, sector_blocks, ret;
9657
struct SectorbitmaP *map;
9659
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
9660
if(job->use_dev == 1)
9662
map= job->sector_map;
9663
sectors= Spotlist_block_count(spotlist, 0);
9666
sector_size= Spotlist_sector_size(spotlist, read_chunk, 0);
9667
sector_blocks= sector_size / 2048;
9668
if(sector_blocks > 1)
9669
sectors= sectors / sector_blocks + !!(sectors % sector_blocks);
9670
ret= Sectorbitmap_new(&(xorriso->in_sector_map), sectors, sector_size, 0);
9674
Sectorbitmap_copy(map, xorriso->in_sector_map, 0);
9675
ret= Xorriso_spotlist_to_sectormap(xorriso, spotlist, read_chunk,
9676
&(xorriso->in_sector_map), 1);
9682
@param flag bit0= obtain iso_lba from indev
9683
bit1= head_buffer already contains a valid head
9684
bit2= issue message about success
9685
bit3= check whether source blocks are banned by in_sector_map
9687
int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
9688
char *head_buffer, struct CheckmediajoB *job,
9691
int ret, full_size, i;
9693
struct burn_drive_info *dinfo;
9694
struct burn_drive *drive;
9697
ret= Xorriso_may_burn(xorriso, 0);
9701
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
9702
"on attempt to learn current session lba", 1);
9705
ret= isoburn_disc_get_msc1(drive, &iso_lba);
9708
drive= NULL; /* indev will not be used furtherly */
9711
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
9712
"on attempt to update at lba 0 to 31", 2);
9719
/* head_buffer was not filled yet. Read it from output media. */
9720
if(job != NULL && job->data_to_fd >= 0) {
9721
if((flag & 8) && job->sector_map != NULL) {
9722
ret= Sectorbitmap_bytes_are_set(job->sector_map,
9723
((off_t) iso_lba) * (off_t) 2048,
9724
((off_t) (iso_lba + 32)) * ((off_t) 2048) - (off_t) 1, 0);
9726
sprintf(xorriso->info_text,
9727
"ISO image head at lba %d is marked as invalid blocks in file copy",
9729
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",
9734
seek_ret= lseek(job->data_to_fd, ((off_t) 2048) * (off_t) iso_lba,
9739
ret= read(job->data_to_fd, head_buffer, 64 * 1024);
9740
if(ret < 64 * 1024) {
9741
Xorriso_process_msg_queues(xorriso,0);
9742
sprintf(xorriso->info_text,
9743
"Cannot read ISO image head from file copy");
9744
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
9748
ret= isoburn_read_iso_head(drive, iso_lba, &isosize, head_buffer, 2);
9750
Xorriso_process_msg_queues(xorriso,0);
9751
sprintf(xorriso->info_text,
9752
"Cannot read freshly written ISO image head");
9753
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
9758
/* patch ISO header */
9759
full_size= iso_lba + isosize;
9760
headpt= head_buffer + 32*1024;
9762
headpt[87-i]= headpt[80+i]= (full_size >> (8*i)) & 0xff;
9765
seek_ret= lseek(job->data_to_fd, (off_t) 0, SEEK_SET);
9769
ret= write(job->data_to_fd, head_buffer, 64 * 1024);
9770
if(ret < 64 * 1024) {
9771
Xorriso_process_msg_queues(xorriso,0);
9772
sprintf(xorriso->info_text,
9773
"Cannot write ISO image head to file copy");
9774
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
9778
ret= burn_random_access_write(drive, (off_t) 0, head_buffer,
9779
(off_t) (64*1024), 1);
9781
Xorriso_process_msg_queues(xorriso,0);
9782
sprintf(xorriso->info_text,
9783
"Cannot write new ISO image head to LBA 0");
9784
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
9789
sprintf(xorriso->info_text,
9790
"Overwrote LBA 0 to 31 by 64 KiB from LBA %d", iso_lba);
9791
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
9797
/* @param write_start_address is valid if >=0
9798
@param tsize is valid if >0
9799
@param flag bit0= grow_overwriteable_iso
9801
bit2= do_xa1 conversion
9803
int Xorriso_burn_track(struct XorrisO *xorriso, off_t write_start_address,
9804
char *track_source, off_t tsize, int flag)
9806
int ret, fd, unpredicted_size, profile_number, is_cd= 0, dummy, nwa= -1;
9807
int isosize= -1, do_isosize, is_bd= 0;
9809
struct burn_drive_info *dinfo;
9810
struct burn_drive *drive;
9811
struct burn_write_opts *burn_options;
9812
struct burn_disc *disc= NULL;
9813
struct burn_session *session;
9814
struct burn_track *track;
9816
off_t fixed_size= 0;
9817
struct burn_source *data_src= NULL, *fifo_src= NULL;
9818
enum burn_disc_status disc_state;
9819
char reasons[BURN_REASONS_LEN], sfe[5*SfileadrL], profile_name[80];
9820
char head_buffer[64*1024];
9822
ret= Xorriso_may_burn(xorriso, 0);
9825
ret= Xorriso_auto_format(xorriso, 0);
9829
do_isosize= !!(flag&2);
9830
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
9831
"on attempt to burn track", 2);
9834
ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0);
9838
disc= burn_disc_create();
9839
session= burn_session_create();
9840
ret= burn_disc_add_session(disc,session,BURN_POS_END);
9842
sprintf(xorriso->info_text, "Cannot add session object to disc object.");
9843
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
9846
track= burn_track_create();
9847
if(track_source[0] == '-' && track_source[1] == 0) {
9850
if(xorriso->fs >= 64)
9851
fd= burn_os_open_track_src(track_source, O_RDONLY, 0);
9853
fd= open(track_source, O_RDONLY);
9855
if(fstat(fd,&stbuf)!=-1)
9856
if((stbuf.st_mode&S_IFMT)==S_IFREG)
9857
fixed_size= stbuf.st_size;
9860
unpredicted_size= 1;
9863
data_src= burn_fd_source_new(fd, -1, fixed_size);
9864
if(data_src==NULL) {
9865
sprintf(xorriso->info_text, "Could not open data source %s",
9866
Text_shellsafe(track_source,sfe,0));
9867
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
9870
if((do_isosize || xorriso->fs != 0) && xorriso->fs < 64)
9872
if(xorriso->fs > 0) {
9873
fifo_src= burn_fifo_source_new(data_src, 2048 + 8 * !!(flag & 4),
9875
if(fifo_src == NULL) {
9876
sprintf(xorriso->info_text, "Could not create fifo object of %.f MB",
9877
((double) xorriso->fs) / 1024.0 / 1024.0);
9878
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
9882
xorriso->pacifier_fifo= fifo_src;
9883
if(burn_track_set_source(track, fifo_src == NULL ? data_src : fifo_src)
9884
!= BURN_SOURCE_OK) {
9885
sprintf(xorriso->info_text,
9886
"Cannot attach source object to track object");
9887
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
9890
burn_track_set_cdxa_conv(track, !!(flag & 4));
9891
burn_session_add_track(session, track, BURN_POS_END);
9892
burn_source_free(data_src);
9895
/* consider overwriteables with ISO as appendable */
9896
disc_state= isoburn_disc_get_status(drive);
9898
/* handle overwriteables as always blank */
9899
disc_state= burn_disc_get_status(drive);
9901
if(disc_state == BURN_DISC_BLANK || disc_state == BURN_DISC_APPENDABLE) {
9904
if(disc_state == BURN_DISC_FULL) {
9905
sprintf(xorriso->info_text,
9906
"Closed media with data detected. Need blank or appendable media.");
9907
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
9908
if(burn_disc_erasable(drive)) {
9909
sprintf(xorriso->info_text, "Try -blank as_needed\n");
9910
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
9912
} else if(disc_state == BURN_DISC_EMPTY) {
9913
sprintf(xorriso->info_text, "No media detected in drive");
9914
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
9916
sprintf(xorriso->info_text,
9917
"Cannot recognize state of drive and media");
9918
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
9922
if(isoburn_needs_emulation(drive))
9923
burn_write_opts_set_multi(burn_options, 0);
9927
burn_track_set_size(track, fixed_size);
9930
ret= burn_fifo_peek_data(xorriso->pacifier_fifo, head_buffer, 64*1024, 0);
9932
Xorriso_process_msg_queues(xorriso,0);
9933
sprintf(xorriso->info_text,
9934
"Cannot obtain first 64 kB from input stream.");
9935
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
9938
/* read isosize from head_buffer, not from media*/
9939
ret= isoburn_read_iso_head(drive, 0, &isosize, head_buffer, (1<<13));
9941
Xorriso_process_msg_queues(xorriso,0);
9942
sprintf(xorriso->info_text,
9943
"Option -isosize given but data stream seems not to be ISO 9660");
9944
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
9947
sprintf(xorriso->info_text, "Size of ISO 9660 image: %ds", isosize);
9948
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
9949
fixed_size= ((off_t) (isosize)) * (off_t) 2048;
9950
burn_track_set_size(track, fixed_size);
9953
ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2);
9957
if(isoburn_needs_emulation(drive)) {
9959
ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &dummy, &nwa);
9961
Xorriso_process_msg_queues(xorriso,0);
9962
sprintf(xorriso->info_text,
9963
"Cannot obtain next writeable address of emulated multi-session media\n");
9964
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
9968
nwa= 0; /* No automatic toc emulation. Formatter might not be aware. */
9969
burn_write_opts_set_start_byte(burn_options,((off_t) nwa) * (off_t) 2048);
9972
burn_write_opts_set_start_byte(burn_options, (off_t) 0);
9976
if(write_start_address>=0) {
9977
nwa= write_start_address / (off_t) 2048;
9978
if(((off_t) nwa) * (off_t) 2048 < write_start_address )
9980
burn_write_opts_set_start_byte(burn_options, ((off_t) nwa) * (off_t) 2048);
9983
if(burn_write_opts_auto_write_type(burn_options, disc, reasons, 0) ==
9985
sprintf(xorriso->info_text,
9986
"Failed to find a suitable write mode with this media.\n");
9987
sprintf(xorriso->info_text+strlen(xorriso->info_text),
9988
"Reasons given:\n%s", reasons);
9989
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
9993
ret= Xorriso_sanitize_image_size(xorriso, drive, disc, burn_options, 2);
9997
/* Important: do not return until burn_is_aborting() was checked */
9998
Xorriso_set_signal_handling(xorriso, 1);
10000
xorriso->run_state= 1; /* Indicate that burning has started */
10001
burn_disc_write(burn_options, disc);
10003
ret= Xorriso_pacifier_loop(xorriso, drive, 2 | (is_cd << 4) | (is_bd << 5));
10004
if(burn_is_aborting(0))
10005
Xorriso_abort(xorriso, 0); /* Never comes back */
10006
Xorriso_set_signal_handling(xorriso, 0);
10009
if(!burn_drive_wrote_well(drive)) {
10010
Xorriso_process_msg_queues(xorriso,0);
10011
sprintf(xorriso->info_text,
10012
"libburn indicates failure with writing.");
10013
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
10018
ret= Xorriso_update_iso_lba0(xorriso, nwa, isosize, head_buffer, NULL,
10023
sprintf(xorriso->info_text, "Writing to %s completed sucessfully.\n\n",
10024
Text_shellsafe(xorriso->outdev,sfe,0));
10025
Xorriso_info(xorriso, 0);
10028
Xorriso_process_msg_queues(xorriso,0);
10030
burn_disc_free(disc);
10031
if(xorriso->pacifier_fifo!=NULL)
10032
burn_source_free(xorriso->pacifier_fifo);
10033
xorriso->pacifier_fifo= NULL;
10034
xorriso->run_state= 0; /* Indicate that burning has ended */
10039
/* @param flag bit1= outdev rather than indev
10040
@return <0 error, 0 = no profile to see , 1= ok , 2= ok, is CD profile
10041
3= ok, is BD profile
10043
int Xorriso_get_profile(struct XorrisO *xorriso, int *profile_number,
10044
char profile_name[80], int flag)
10047
struct burn_drive_info *dinfo;
10048
struct burn_drive *drive;
10050
*profile_number= 0;
10051
profile_name[0]= 0;
10052
if(((flag&2) && xorriso->out_drive_handle==NULL) ||
10053
((!(flag&2)) && xorriso->in_drive_handle==NULL))
10055
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
10056
"on attempt to determine media type", flag&2);
10059
ret=burn_disc_get_profile(drive, profile_number, profile_name);
10062
if(*profile_number==0x08 || *profile_number==0x09 || *profile_number==0x0a)
10064
if(*profile_number == 0x40 || *profile_number == 0x41 ||
10065
*profile_number == 0x42 || *profile_number == 0x43)
10072
int Xorriso_iso_file_open(struct XorrisO *xorriso, char *pathname,
10073
void *node_pt, void **stream, int flag)
10076
char eff_path[SfileadrL];
10077
IsoNode *node= NULL;
10078
IsoFile *filenode= NULL;
10079
IsoStream *iso_stream= NULL, *input_stream;
10083
node= (IsoNode *) node_pt;
10085
ret= Xorriso_get_node_by_path(xorriso, pathname, eff_path, &node, 0);
10089
if(!LIBISO_ISREG(node)) {
10090
sprintf(xorriso->info_text,
10091
"Given path does not lead to a regular data file in the image");
10092
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
10096
filenode= (IsoFile *) node;
10097
iso_stream= iso_file_get_stream(filenode);
10098
if(iso_stream==NULL) {
10099
Xorriso_process_msg_queues(xorriso,0);
10100
sprintf(xorriso->info_text,
10101
"Could not obtain source stream of file in the image for reading");
10102
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
10106
/* Dig out the most original stream */
10108
input_stream= iso_stream_get_input_stream(iso_stream, 0);
10109
if(input_stream == NULL)
10111
iso_stream= input_stream;
10114
if(!iso_stream_is_repeatable(iso_stream)) {
10115
sprintf(xorriso->info_text,
10116
"The data production of the file in the image is one-time only");
10117
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
10120
ret= iso_stream_open(iso_stream);
10122
sprintf(xorriso->info_text,
10123
"Could not open data file in the image for reading");
10124
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
10127
Xorriso_process_msg_queues(xorriso,0);
10128
*stream= iso_stream;
10133
unsigned int fs_id;
10137
iso_stream_get_id(iso_stream, &fs_id, &dev_id, &ino);
10138
fprintf(stderr, "xorriso_debug: iso_ino= %ld\n", (long int) ino);
10146
int Xorriso_iso_file_read(struct XorrisO *xorriso, void *stream, char *buf,
10147
int count, int flag)
10150
IsoStream *stream_pt;
10152
stream_pt= (IsoStream *) stream;
10154
while(rcnt<count) {
10155
ret= iso_stream_read(stream_pt, (void *) (buf+rcnt), (size_t) (count-rcnt));
10156
if(ret==0) /* EOF */
10158
if(ret<0) { /* error */
10159
Xorriso_process_msg_queues(xorriso,0);
10160
Xorriso_report_iso_error(xorriso, "", ret, "Error on read",
10161
0, "FAILURE", 1 | ((ret == -1)<<2) );
10170
int Xorriso_iso_file_close(struct XorrisO *xorriso, void **stream, int flag)
10176
ret= iso_stream_close(*stream);
10179
Xorriso_process_msg_queues(xorriso,0);
10184
/* @param flag bit0= in_node is valid, do not resolve iso_adr
10185
bit2= recognize and parse split parts despite
10186
xorrio->split_size <= 0
10188
int Xorriso_identify_split(struct XorrisO *xorriso, char *iso_adr,
10190
struct SplitparT **parts, int *count,
10191
struct stat *total_stbuf, int flag)
10193
int ret, i, incomplete= 0, overlapping= 0;
10194
int partno, total_parts, first_total_parts= -1;
10195
off_t offset, bytes, total_bytes, first_total_bytes= -1, first_bytes= -1;
10196
off_t size, covered;
10200
IsoDirIter *iter= NULL;
10203
struct stat stbuf, first_stbuf;
10208
if(xorriso->split_size <= 0 && !(flag & 4))
10212
node= (IsoNode *) in_node;
10214
ret= Xorriso_get_volume(xorriso, &volume, 0);
10217
ret= Xorriso_node_from_path(xorriso, volume, iso_adr, &node, 1);
10221
if(!LIBISO_ISDIR(node))
10223
dir_node= (IsoDir *) node;
10225
ret= iso_dir_get_children(dir_node, &iter);
10228
Xorriso_cannot_create_iter(xorriso, ret, 0);
10232
for(i= 0; iso_dir_iter_next(iter, &node) == 1; i++) {
10233
name= (char *) iso_node_get_name(node);
10234
ret= Splitpart__parse(name, &partno, &total_parts,
10235
&offset, &bytes, &total_bytes, 0);
10239
first_total_parts= total_parts;
10240
first_bytes= bytes;
10241
first_total_bytes= total_bytes;
10242
Xorriso_fake_stbuf(xorriso, "", &first_stbuf, &node, 1);
10243
size= first_stbuf.st_size;
10245
if(first_total_parts!=total_parts || first_total_bytes!=total_bytes ||
10246
(first_bytes!=bytes && partno!=total_parts))
10248
Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1);
10249
if(first_stbuf.st_mode != stbuf.st_mode ||
10250
first_stbuf.st_uid != stbuf.st_uid ||
10251
first_stbuf.st_gid != stbuf.st_gid ||
10252
first_stbuf.st_mtime != stbuf.st_mtime ||
10253
first_stbuf.st_ctime != stbuf.st_ctime)
10255
size= stbuf.st_size;
10257
/* check for plausible size */
10258
if(!((partno != total_parts && size == bytes) ||
10259
(partno == total_parts && size <= bytes)))
10261
if(offset != first_bytes * (off_t) (partno - 1))
10265
if(*count <= 0 || *count != first_total_parts)
10268
ret= Splitparts_new(parts, (*count)+1, 0); /* (have one end marker item) */
10272
iso_dir_iter_free(iter);
10273
ret= iso_dir_get_children(dir_node, &iter);
10276
for(i= 0; i<*count; i++) {
10277
ret= iso_dir_iter_next(iter, &node);
10280
name= (char *) iso_node_get_name(node);
10281
ret= Splitpart__parse(name, &partno, &total_parts,
10282
&offset, &bytes, &total_bytes, 0);
10285
ret= Splitparts_set(*parts, i, name, partno, total_parts, offset, bytes,
10291
Splitparts_sort(*parts, *count, 0);
10294
for(i= 0; i<*count; i++) {
10295
Splitparts_get(*parts, i, &name, &partno, &total_parts, &offset, &bytes,
10299
else if(offset<covered)
10301
if(offset+bytes > covered)
10302
covered= offset+bytes;
10304
if(total_bytes>covered)
10306
memcpy(total_stbuf, &first_stbuf, sizeof(struct stat));
10307
total_stbuf->st_size= total_bytes;
10308
ret= !(overlapping || incomplete);
10311
iso_dir_iter_free(iter);
10316
/* @param flag bit0= node is valid, do not resolve path
10317
bit1= insist in complete collection of part files
10319
int Xorriso_is_split(struct XorrisO *xorriso, char *path, void *node,
10322
struct SplitparT *split_parts= NULL;
10323
int split_count= 0, ret;
10326
ret= Xorriso_identify_split(xorriso, path, node, &split_parts,
10327
&split_count, &stbuf, flag & 3);
10328
if(split_parts!=NULL)
10329
Splitparts_destroy(&split_parts, split_count, 0);
10334
/* @param flag bit0= grow_overwriteable_iso
10335
bit1= obtain info from outdev
10336
bit2= no need to obtain msc2 (NWA)
10338
int Xorriso_msinfo(struct XorrisO *xorriso, int *msc1, int *msc2, int flag)
10341
struct burn_drive *drive;
10342
struct burn_drive_info *dinfo;
10343
enum burn_disc_status disc_state;
10346
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
10347
"on attempt to obtain msinfo", flag&2);
10352
disc_state= isoburn_disc_get_status(drive);
10354
disc_state= burn_disc_get_status(drive);
10355
if(disc_state != BURN_DISC_APPENDABLE &&
10356
!(disc_state == BURN_DISC_FULL && (flag & 4))) {
10357
Xorriso_process_msg_queues(xorriso,0);
10359
sprintf(xorriso->info_text,
10360
"%s media is not appendable. Cannot obtain -msinfo.",
10361
(flag&2) ? "Output" : "Input");
10362
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
10366
ret= isoburn_disc_get_msc1(drive, msc1);
10368
Xorriso_process_msg_queues(xorriso,0);
10369
sprintf(xorriso->info_text, "Cannot obtain address of most recent session");
10370
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
10375
ret= isoburn_disc_track_lba_nwa(drive, NULL, 0, &dummy, msc2);
10377
Xorriso_process_msg_queues(xorriso,0);
10378
sprintf(xorriso->info_text, "Cannot obtain next writeable address on media");
10379
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
10385
/* @param flag bit0= this is a follow-up session (i.e. on CD: TAO)
10386
bit1= no pacifier messages
10387
bit2= compute stream MD5 and look out for checksum tag
10388
@return <=0 error, 1= done, 2= aborted due to limit
10390
int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
10391
struct CheckmediajoB *job,
10392
int from_lba, int block_count, int read_chunk,
10393
int md5_start, int flag)
10395
int i, j, ret, total_count= 0, sectors= -1, sector_size= -1, skip_reading;
10396
int prev_quality= -1, quality= -1, retry= 0, profile_no, is_cd= 0;
10397
int start_sec, end_sec, first_value, fret;
10398
char profile_name[80];
10400
struct burn_drive *drive;
10401
struct burn_drive_info *dinfo;
10402
char data[64*1024], sfe[5*SfileadrL];
10403
off_t data_count, to_read, read_count= 0, write_amount;
10404
double pre_read_time, post_read_time, time_diff, total_time_diff= 0;
10405
double last_abort_file_time= 0;
10407
void *ctx= NULL, *cloned_ctx= NULL;
10408
char md5[16], tag_md5[16];
10409
uint32_t pos, range_start, range_size, next_tag= 0, lba, md5_spot_lba= 0;
10410
int md5_spot_value= Xorriso_read_quality_untesteD, chain_broken= 0;
10411
int tag_type= 0, valid, was_sb_tag= 0, in_track_gap= 0;
10412
char *comparison= "", *sev_text= "DEBUG", *tag_type_name= "";
10414
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
10415
"on attempt to check media readability",
10416
2 * !!job->use_dev);
10419
ret= burn_disc_get_profile(drive, &profile_no, profile_name);
10421
if(profile_no >= 0x08 && profile_no <= 0x0a)
10424
if(job->sector_map != NULL) {
10425
Sectorbitmap_get_layout(job->sector_map, §ors, §or_size, 0);
10426
sector_size/= 2048;
10431
else if(job->retry == 0 && is_cd)
10435
ret= iso_md5_start(&ctx);
10437
Xorriso_no_malloc_memory(xorriso, NULL, 0);
10442
start_lba= from_lba;
10443
to_read= read_chunk;
10444
post_read_time= Sfile_microtime(0);
10445
for(i= 0; i < block_count; i+= to_read) {
10448
if(job->abort_file_path[0]) {
10449
if(post_read_time - last_abort_file_time >= 0.1) {
10450
if(stat(job->abort_file_path, &stbuf) != -1) {
10451
if(stbuf.st_mtime >= xorriso->start_time) {
10452
sprintf(xorriso->info_text,
10453
"-check_media: Found fresh abort_file=%s",
10454
job->abort_file_path);
10455
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
10459
last_abort_file_time= post_read_time;
10462
if(job->item_limit > 0 &&
10463
Spotlist_count(spotlist, 0) + 2 >= job->item_limit) {
10464
sprintf(xorriso->info_text, "-check_media: Reached item_limit=%d",
10466
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
10469
pre_read_time= Sfile_microtime(0);
10470
if(job->time_limit > 0
10471
&& job->start_time + job->time_limit < pre_read_time) {
10472
sprintf(xorriso->info_text, "-check_media: Reached time_limit=%d",
10474
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
10476
if(prev_quality >= 0) {
10477
ret= Spotlist_add_item(spotlist, start_lba, i + from_lba - start_lba,
10482
ret= Spotlist_add_item(spotlist, i + from_lba, block_count - i,
10483
Xorriso_read_quality_untesteD, 0);
10489
to_read= read_chunk;
10490
if(i + to_read > block_count)
10491
to_read= block_count - i;
10492
if(is_cd && i + to_read + 2 >= block_count) {
10493
/* Read last 2 blocks of CD track separately, because with TAO tracks
10494
they are always unreadable but with SAO tracks they contain data.
10498
else if(to_read > 1) {
10500
quality= Xorriso_read_quality_tao_enD;
10507
if(sector_size == read_chunk && from_lba % read_chunk == 0
10508
&& !skip_reading) {
10509
if(Sectorbitmap_is_set(job->sector_map, (i + from_lba) / sector_size, 0)){
10510
quality= Xorriso_read_quality_valiD;
10513
} else if(sector_size > 0 && !skip_reading) {
10514
start_sec= (i + from_lba) / sector_size;
10515
end_sec= (i + to_read + from_lba) / sector_size;
10516
first_value= Sectorbitmap_is_set(job->sector_map, start_sec, 0);
10517
for(j= start_sec; j < end_sec; j++)
10518
if(Sectorbitmap_is_set(job->sector_map, j, 0) != first_value)
10520
to_read= j * sector_size - i - from_lba;
10521
skip_reading= !!first_value;
10523
quality= Xorriso_read_quality_valiD;
10527
pre_read_time= post_read_time= Sfile_microtime(0);
10530
pre_read_time= Sfile_microtime(0);
10531
ret= burn_read_data(drive, ((off_t) (i + from_lba)) * (off_t) 2048, data,
10532
to_read * (off_t) 2048, &data_count, 4 * !retry);
10533
post_read_time= Sfile_microtime(0);
10534
time_diff= post_read_time - pre_read_time;
10535
total_time_diff+= time_diff;
10538
Xorriso_process_msg_queues(xorriso,0);
10539
if(data_count / 2048 < to_read) {
10540
if(data_count > 0 && retry) {
10541
if(prev_quality >= 0) {
10542
ret= Spotlist_add_item(spotlist, start_lba,
10543
i + from_lba - start_lba, prev_quality, 0);
10547
ret= Spotlist_add_item(spotlist, i + from_lba, data_count / 2048,
10548
Xorriso_read_quality_partiaL, 0);
10551
start_lba= i + from_lba + data_count / 2048;
10552
prev_quality= Xorriso_read_quality_unreadablE;
10554
quality= Xorriso_read_quality_unreadablE;
10556
to_read= data_count / 2048 + 1;
10558
quality= Xorriso_read_quality_partiaL;
10559
fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
10563
quality= Xorriso_read_quality_gooD;
10564
if(time_diff > job->slow_threshold_seq && job->slow_threshold_seq > 0 &&
10566
quality= Xorriso_read_quality_sloW;
10569
/* MD5 checksumming */
10571
for(j= 0; j < to_read; j++) {
10572
lba= i + j + from_lba;
10573
if(lba < md5_start)
10576
if(lba > md5_start + 16 &&
10577
(next_tag == 0 || chain_broken || lba == next_tag)) {
10578
ret= iso_util_decode_md5_tag(data + j * 2048, &tag_type,
10579
&pos, &range_start, &range_size,
10580
&next_tag, tag_md5, !!chain_broken);
10582
valid= (ret == 1 || ret == ISO_MD5_AREA_CORRUPTED) && pos == lba;
10583
if(valid && tag_type == 2 && (lba < md5_start + 32 || in_track_gap)) {
10584
tag_type_name= "superblock";
10586
if(in_track_gap && range_start != md5_start && range_start < lba &&
10587
lba - range_start <= j) {
10588
/* Looking for next session : start computing in hindsight.
10589
Session start and superblock tag are supposed to be in the
10592
iso_md5_end(&ctx, md5);
10593
ret= iso_md5_start(&ctx);
10595
Xorriso_no_malloc_memory(xorriso, NULL, 0);
10598
iso_md5_compute(&ctx, data + (j - (lba - range_start)) * 2048,
10599
(lba - range_start) * 2048);
10600
md5_start= range_start;
10603
} else if(valid && tag_type == 4 && lba < 32) {
10604
tag_type_name= "relocated 64kB superblock";
10605
}else if(valid && tag_type == 3 && was_sb_tag) {
10606
tag_type_name= "tree";
10607
}else if(valid && tag_type == 1) {
10609
/* >>> ??? allow this without superblock and tree tag ? */
10611
tag_type_name= "session";
10615
if (tag_type_name[0]) {
10616
if(range_start != md5_start) {
10617
sprintf(xorriso->info_text,
10618
"Found MD5 %s tag which covers different data range",
10620
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0);
10621
sprintf(xorriso->info_text,
10622
" Expected: %u Found: %u",
10623
(unsigned int) md5_start, range_start);
10624
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0);
10628
ret= iso_md5_clone(ctx, &cloned_ctx);
10630
Xorriso_no_malloc_memory(xorriso, NULL, 0);
10633
iso_md5_end(&cloned_ctx, md5);
10635
if(ret == ISO_MD5_AREA_CORRUPTED) {
10636
comparison= "CORRUPTED";
10637
sev_text= "WARNING";
10638
md5_spot_value= Xorriso_read_quality_md5_mismatcH;
10640
} else if(! iso_md5_match(tag_md5, md5)) {
10641
comparison= "NON-MATCHING";
10642
sev_text= "WARNING";
10643
md5_spot_value= Xorriso_read_quality_md5_mismatcH;
10646
comparison= "matching";
10647
sev_text= "UPDATE";
10648
md5_spot_value= Xorriso_read_quality_md5_matcH;
10651
sprintf(xorriso->info_text,
10652
"Found %s MD5 %s tag: start=%d size=%d",
10653
comparison, tag_type_name, md5_start, lba - md5_start);
10654
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
10657
if(valid && (tag_type == 1 ||
10658
(tag_type == 4 && pos == lba && lba < 32))) {
10659
if(md5_spot_value != Xorriso_read_quality_untesteD) {
10660
ret= Spotlist_add_item(spotlist, md5_start,
10661
md5_spot_lba - md5_start, md5_spot_value, 0);
10665
md5_spot_value= Xorriso_read_quality_untesteD;
10666
md5_start = lba + 1;
10667
if (md5_start % 32)
10668
md5_start= md5_start + (32 - (md5_start % 32));
10671
iso_md5_end(&ctx, md5);
10672
ret= iso_md5_start(&ctx);
10674
Xorriso_no_malloc_memory(xorriso, NULL, 0);
10682
iso_md5_compute(ctx, data + j * 2048, 2048);
10686
write_amount= data_count;
10687
if(data_count > 0) {
10688
read_count+= data_count;
10689
if(job->data_to_limit >= 0 && read_count > job->data_to_limit)
10690
write_amount-= (read_count - job->data_to_limit);
10692
if(write_amount > 0) {
10693
if(job->data_to_fd >= 0) {
10694
ret= lseek(job->data_to_fd,
10695
((off_t) (i + from_lba)) * (off_t) 2048 + job->data_to_offset,
10699
sprintf(xorriso->info_text, "Cannot write %d bytes to lba %d of %s",
10700
(int) data_count, i + from_lba,
10701
Text_shellsafe(job->data_to_path, sfe, 0));
10702
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno,
10706
ret= write(job->data_to_fd, data, write_amount);
10708
goto failed_to_write;
10712
if(quality != prev_quality) {
10713
if(prev_quality >= 0) {
10714
ret= Spotlist_add_item(spotlist, start_lba, i + from_lba - start_lba,
10719
start_lba= i + from_lba;
10720
prev_quality= quality;
10723
xorriso->pacifier_count+= to_read;
10724
if(post_read_time - xorriso->last_update_time >=
10725
xorriso->pacifier_interval)
10726
Xorriso_pacifier_callback(xorriso, "sectors examined",
10727
xorriso->pacifier_count, xorriso->pacifier_total, "", 0);
10730
if(prev_quality >= 0) {
10731
ret= Spotlist_add_item(spotlist, start_lba,
10732
block_count + from_lba - start_lba, prev_quality, 0);
10737
/* <<< for calibration of quality */
10738
if(total_count > 0) {
10739
sprintf(xorriso->info_text, "Xorriso_check_interval: %.1f s / %d = %f",
10740
total_time_diff, total_count, total_time_diff / total_count);
10741
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
10745
/* MD5 checksumming : register result */
10747
/* >>> ??? allow chain_broken to be a match ? */
10750
sprintf(xorriso->info_text, "Missing announced MD5 tag: start=%d pos=%d",
10751
md5_start, next_tag);
10752
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
10753
md5_spot_value= Xorriso_read_quality_md5_mismatcH;
10754
md5_spot_lba= next_tag;
10756
if(md5_spot_value != Xorriso_read_quality_untesteD) {
10757
ret= Spotlist_add_item(spotlist, md5_start, md5_spot_lba - md5_start,
10758
md5_spot_value, 0);
10766
iso_md5_end(&ctx, md5);
10771
int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
10772
struct CheckmediajoB *job, int flag)
10774
int media_blocks= 0, read_chunk= 16, ret, mode, start_lba= 0;
10775
int blocks, os_errno, i, j, last_track_end= -1, track_blocks, track_lba;
10776
int num_sessions, num_tracks, declare_untested= 0, md5_start;
10777
int read_capacity= -1, end_lba, hret, count, quality;
10778
char *toc_info= NULL;
10779
struct burn_drive *drive;
10780
struct burn_drive_info *dinfo;
10781
struct isoburn_toc_disc *isoburn_disc= NULL;
10782
struct isoburn_toc_session **isoburn_sessions;
10783
struct isoburn_toc_track **iso_burn_tracks;
10784
struct burn_toc_entry isoburn_entry;
10786
struct burn_multi_caps *caps= NULL;
10790
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
10791
"on attempt to check media readability",
10792
2 * !!job->use_dev);
10796
/* >>> determine media type dependent blocking factor:
10797
32 kB for CD (with 2kB retry) and DVD, 64 kB for BD
10798
eventually adjust read_chunk
10800
if(job->min_block_size != 0)
10801
read_chunk= job->min_block_size;
10803
ret= Spotlist_new(spotlist, 0);
10805
{ret= -1; goto ex;}
10807
if(job->sector_map_path[0]) {
10808
Sectorbitmap_destroy(&(job->sector_map), 0);
10809
if(stat(job->sector_map_path, &stbuf) != -1) {
10810
ret= Sectorbitmap_from_file(&(job->sector_map), job->sector_map_path,
10811
xorriso->info_text, &os_errno, 0);
10813
if(xorriso->info_text[0])
10814
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, os_errno,
10819
Xorriso_toc_to_string(xorriso, &toc_info, 4 * !job->map_with_volid);
10821
ret= Xorriso_open_job_data_to(xorriso, job, 0);
10824
Xorriso_pacifier_reset(xorriso, 0);
10825
job->start_time= time(NULL);
10827
if(job->min_lba > 0) {
10828
start_lba= job->min_lba;
10829
ret= Spotlist_add_item(*spotlist, 0, job->min_lba,
10830
Xorriso_read_quality_untesteD, 0);
10834
ret= burn_get_read_capacity(drive, &read_capacity, 0);
10838
if(job->max_lba >= 0) {
10839
blocks= job->max_lba + 1 - start_lba;
10840
xorriso->pacifier_total= blocks;
10841
ret= Xorriso_check_interval(xorriso, *spotlist, job, start_lba, blocks,
10846
} else if(mode == 0) { /* track by track */
10847
isoburn_disc= isoburn_toc_drive_get_disc(drive);
10848
if(isoburn_disc == NULL)
10849
goto no_content_visible;
10851
isoburn_toc_disc_get_sessions(isoburn_disc, &num_sessions);
10852
for(i= 0; i < num_sessions; i++) {
10853
iso_burn_tracks= isoburn_toc_session_get_tracks(isoburn_sessions[i],
10855
for(j= 0; j < num_tracks; j++) {
10856
isoburn_toc_track_get_entry(iso_burn_tracks[j], &isoburn_entry);
10857
if(!(isoburn_entry.extensions_valid & 1)) /* should not happen */
10859
track_lba= isoburn_entry.start_lba;
10860
track_blocks= isoburn_entry.track_blocks;
10861
md5_start= track_lba;
10862
if(i == 0 && j == 0) {
10863
if(track_lba == 32) {
10864
ret= burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0);
10866
if(caps->start_adr) {
10867
/* block 0 to 31 are the overall mount entry of overwriteable */
10874
if(last_track_end >= 0 && last_track_end < track_lba &&
10875
last_track_end >= start_lba) {
10876
ret= Spotlist_add_item(*spotlist, last_track_end,
10877
track_lba - last_track_end,
10878
Xorriso_read_quality_off_tracK, 0);
10881
xorriso->pacifier_count+= track_lba - last_track_end;
10883
last_track_end= track_lba + track_blocks;
10885
if(track_lba < start_lba) {
10886
track_blocks-= start_lba - track_lba;
10887
track_lba= start_lba;
10889
if(track_blocks <= 0)
10891
if(declare_untested) {
10892
ret= Spotlist_add_item(*spotlist, track_lba, track_blocks,
10893
Xorriso_read_quality_untesteD, 0);
10897
ret= Xorriso_check_interval(xorriso, *spotlist, job, track_lba,
10898
track_blocks, read_chunk, md5_start,
10899
(i > 0) | (4 * (xorriso->do_md5 & 1)));
10903
declare_untested= 1;
10908
} else if(mode == 1) { /* isoburn disc capacity */
10909
isoburn_disc= isoburn_toc_drive_get_disc(drive);
10910
if(isoburn_disc == NULL) {
10911
no_content_visible:;
10912
Xorriso_process_msg_queues(xorriso,0);
10913
sprintf(xorriso->info_text, "No content detected on media");
10914
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
10917
blocks= media_blocks= isoburn_toc_disc_get_sectors(isoburn_disc);
10919
blocks-= start_lba;
10920
if(media_blocks <= 0)
10921
goto no_content_visible;
10922
xorriso->pacifier_total= blocks;
10923
ret= Xorriso_check_interval(xorriso, *spotlist, job, start_lba, blocks,
10927
} else if(mode == 2) {
10929
/* >>> single sweep over libburn media capacity */;
10933
Xorriso_pacifier_callback(xorriso, "sectors examined",
10934
xorriso->pacifier_count, xorriso->pacifier_total, "", 1);
10938
if(job->data_to_fd != -1)
10939
close(job->data_to_fd);
10940
job->data_to_fd= -1;
10942
if(read_capacity >= 0) {
10943
count= Spotlist_count(*spotlist, 0);
10945
for(i= 0; i < count; i++) {
10946
Spotlist_get_item(*spotlist, i, &start_lba, &blocks, &quality, 0);
10947
if(start_lba + blocks > end_lba)
10948
end_lba= start_lba + blocks;
10950
if(read_capacity > end_lba) {
10951
hret= Spotlist_add_item(*spotlist, end_lba, read_capacity - end_lba,
10952
Xorriso_read_quality_untesteD, 0);
10959
ret= Xorriso_update_in_sector_map(xorriso, *spotlist, read_chunk, job, 0);
10962
ret= Xorriso_spotlist_to_sectormap(xorriso, *spotlist, read_chunk,
10963
&(job->sector_map), !!job->untested_valid);
10964
if(ret > 0 && job->sector_map_path[0]) {
10965
ret= Sectorbitmap_to_file(job->sector_map, job->sector_map_path, toc_info,
10966
xorriso->info_text, &os_errno, 0);
10968
if(xorriso->info_text[0])
10969
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, os_errno,
10974
if(toc_info != NULL)
10977
Spotlist_destroy(spotlist, 0);
10979
burn_disc_free_multi_caps(&caps);
10984
/* @param flag bit1= for Xorriso_check_interval(): no pacifier messages
10986
int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node,
10987
char *img_path, char *disk_path,
10988
off_t img_offset, off_t disk_offset,
10989
off_t bytes, int flag)
10991
int ret, i, lba_count= 0, *start_lbas= NULL, *end_lbas= NULL, read_chunk= 16;
10992
int lba, count, blocks, quality, spot, bad_extract= 0;
10993
off_t size= 0, file_base_bytes= 0, file_processed_bytes= 0, img_adr;
10994
off_t new_file_base_bytes, upto_file_bytes, start_byte= 0;
10995
char sfe[5*SfileadrL];
10996
struct SpotlisT *spotlist= NULL;
10997
struct CheckmediajoB *job= NULL;
10999
upto_file_bytes= img_offset + bytes;
11001
/* >>> make Xorriso_check_interval() ready for copying in byte granularity */
11002
if(img_offset % (off_t) 2048) {
11003
sprintf(xorriso->info_text,
11004
"Image address offset is not a multiple of 2048");
11005
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
11009
ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas, &size,
11012
Xorriso_process_msg_queues(xorriso,0);
11013
sprintf(xorriso->info_text,
11014
"File object %s is currently not a data file from the loaded image",
11015
Text_shellsafe(img_path, sfe, 0));
11016
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
11019
if(img_offset + bytes < size && bytes > 0)
11020
size= img_offset + bytes;
11022
ret= Checkmediajob_new(&job, 0);
11025
if(xorriso->check_media_default != NULL)
11026
Checkmediajob_copy(xorriso->check_media_default, job, 0);
11029
job->sector_map_path[0]= 0;
11031
ret= Spotlist_new(&spotlist, 0);
11033
{ret= -1; goto ex;}
11035
if(Sfile_str(job->data_to_path, disk_path, 0) <= 0)
11036
{ret= -1; goto ex;}
11037
Xorriso_open_job_data_to(xorriso, job, 0);
11041
for(i= 0; i < lba_count && file_base_bytes < upto_file_bytes; i++) {
11042
lba= start_lbas[i];
11043
count= end_lbas[i] + 1 - start_lbas[i];
11044
new_file_base_bytes= file_base_bytes + ((off_t) count) * (off_t) 2048;
11046
/* skip intervals before img_offset */
11047
if(new_file_base_bytes <= img_offset) {
11048
file_base_bytes= new_file_base_bytes;
11051
/* Eventually adjust first interval start */
11052
img_adr= ((off_t) lba) * (off_t) 2048;
11053
if(file_base_bytes < img_offset) {
11054
img_adr+= img_offset - file_base_bytes;
11055
lba= img_adr / (off_t) 2048;
11056
count= end_lbas[i] + 1 - lba;
11057
file_base_bytes= img_offset;
11060
/* Eventually omit surplus blocks */
11061
if(new_file_base_bytes > upto_file_bytes)
11062
count-= (new_file_base_bytes - upto_file_bytes) / (off_t) 2048;
11064
job->data_to_offset= file_processed_bytes - img_adr + disk_offset;
11065
job->data_to_limit= size - file_base_bytes;
11067
file_processed_bytes+= ((off_t) count) * (off_t) 2048;
11068
ret= Xorriso_check_interval(xorriso, spotlist, job, lba, count, read_chunk,
11073
sprintf(xorriso->info_text, "Attempt aborted to extract data from %s",
11074
Text_shellsafe(img_path, sfe, 0));
11075
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
11078
file_base_bytes= new_file_base_bytes;
11081
/* Use spotlist to evaluate damage */
11082
file_base_bytes= 0;
11083
count= Spotlist_count(spotlist, 0);
11084
for(spot= 0; spot < count; spot++) {
11085
ret= Spotlist_get_item(spotlist, spot, &lba, &blocks, &quality, 0);
11088
if(quality < Xorriso_read_quality_valiD) {
11089
for(i= 0; i < lba_count; i++) {
11090
if(start_lbas[i] <= lba && end_lbas[i] >= lba) {
11091
start_byte= (lba - start_lbas[i]) * (off_t) 2048 + file_base_bytes;
11094
file_base_bytes+= ((off_t) (end_lbas[i] + 1 - start_lbas[i]))
11097
if(i < lba_count) {
11098
sprintf(xorriso->info_text, "Bad extract : %14.f , %14.f , %s\n",
11099
(double) start_byte, ((double) blocks) * 2048.0,
11100
Text_shellsafe(disk_path, sfe, 0));
11101
Xorriso_info(xorriso, 0);
11109
if(start_lbas != NULL)
11110
free((char *) start_lbas);
11111
if(end_lbas != NULL)
11112
free((char *) end_lbas);
11113
Spotlist_destroy(&spotlist, 0);
11114
Checkmediajob_destroy(&job, 0);
11119
int Xorriso_extract_cut(struct XorrisO *xorriso,
11120
char *img_path, char *disk_path,
11121
off_t img_offset, off_t bytes, int flag)
11123
int ret, stbuf_ret, read_raw;
11124
double mem_lut= 0.0;
11125
char eff_img_path[SfileadrL], eff_disk_path[SfileadrL], sfe[SfileadrL*5];
11129
ret= Xorriso_get_volume(xorriso, &volume, 0);
11132
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi,
11133
img_path, eff_img_path, 0);
11136
ret= Xorriso_node_from_path(xorriso, volume, eff_img_path, &node, 0);
11139
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx,
11140
disk_path, eff_disk_path, 2 | 4);
11143
Xorriso_pacifier_reset(xorriso, 0);
11144
mem_lut= xorriso->last_update_time;
11146
ret= Xorriso_handle_collision(xorriso, node, img_path, eff_disk_path,
11147
disk_path, &stbuf_ret, 0);
11148
if(ret<=0 || ret==3)
11151
/* If it is a non-filtered stream from the ISO image
11152
and img_offset is a multiple of 2048
11153
then use Xorriso_read_file_data() for random access offset.
11155
if(!LIBISO_ISREG(node)) {
11156
Xorriso_msgs_submit(xorriso, 0, eff_disk_path, 0, "ERRFILE", 0);
11157
sprintf(xorriso->info_text, "-extract_cut: ISO file %s is not a data file",
11158
Text_shellsafe(eff_img_path, sfe, 0));
11159
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
11163
if((img_offset % 2048) == 0) {
11164
ret= Xorriso_is_plain_image_file(xorriso, node, "", 0);
11169
ret= Xorriso_read_file_data(xorriso, node, eff_img_path, eff_disk_path,
11170
img_offset, (off_t) 0, bytes, 0);
11174
ret= Xorriso_tree_restore_node(xorriso, node, eff_img_path, img_offset,
11175
eff_disk_path, (off_t) 0, bytes, 2 | 8);
11180
ret= Xorriso_restore_properties(xorriso, eff_disk_path, node, 0);
11184
if(mem_lut != xorriso->last_update_time)
11185
Xorriso_pacifier_callback(xorriso, "sectors examined",
11186
xorriso->pacifier_count, 0, "", 1);
11191
int Xorriso_get_local_charset(struct XorrisO *xorriso, char **name, int flag)
11193
(*name)= iso_get_local_charset(0);
11198
int Xorriso_set_local_charset(struct XorrisO *xorriso, char *name, int flag)
11201
char *nl_charset, sfe[5 * SfileadrL];
11202
iconv_t iconv_ret= (iconv_t) -1;
11204
nl_charset= nl_langinfo(CODESET);
11209
iconv_ret= iconv_open(nl_charset, name);
11210
if(iconv_ret == (iconv_t) -1)
11213
iconv_close(iconv_ret);
11215
ret= iso_set_local_charset(name, 0);
11218
sprintf(xorriso->info_text,
11219
"-local_charset: Cannot assume as local character set: %s",
11220
Text_shellsafe(name, sfe, 0));
11221
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
11224
sprintf(xorriso->info_text, "Local character set is now assumed as: %s",
11225
Text_shellsafe(name, sfe, 0));
11226
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
11231
int Xorriso_relax_compliance(struct XorrisO *xorriso, char *mode,
11237
was= xorriso->relax_compliance;
11239
for(; npt!=NULL; cpt= npt+1) {
11240
npt= strchr(cpt,':');
11247
if((l == 6 && strncmp(cpt, "strict", l) == 0) ||
11248
(l == 5 && strncmp(cpt, "clear", l) == 0)) {
11249
xorriso->relax_compliance= 0;
11250
} else if(l == 7 && strncmp(cpt, "default", l) == 0) {
11251
xorriso->relax_compliance= Xorriso_relax_compliance_defaulT;
11253
} else if((l == 12 && strncmp(cpt, "omit_version", l) == 0) ||
11254
(l == 15 && strncmp(cpt, "omit_version_on", l) == 0) ) {
11255
xorriso->relax_compliance|= isoburn_igopt_omit_version_numbers;
11256
} else if((l == 16 && strncmp(cpt, "omit_version_off", l) == 0)) {
11257
xorriso->relax_compliance&= ~isoburn_igopt_omit_version_numbers;
11259
} else if((l == 16 && strncmp(cpt, "only_iso_version", l) == 0) ||
11260
(l == 19 && strncmp(cpt, "only_iso_version_on", l) == 0) ) {
11261
xorriso->relax_compliance|= isoburn_igopt_only_iso_versions;
11262
} else if((l == 20 && strncmp(cpt, "only_iso_version_off", l) == 0)) {
11263
xorriso->relax_compliance&= ~isoburn_igopt_only_iso_versions;
11265
} else if((l == 10 && strncmp(cpt, "deep_paths", l) == 0) ||
11266
(l == 13 && strncmp(cpt, "deep_paths_on", l) == 0)) {
11267
xorriso->relax_compliance|= isoburn_igopt_allow_deep_paths;
11268
} else if(l == 14 && strncmp(cpt, "deep_paths_off", l) == 0) {
11269
xorriso->relax_compliance&= ~isoburn_igopt_allow_deep_paths;
11271
} else if((l == 10 && strncmp(cpt, "long_paths", l) == 0) ||
11272
(l == 13 && strncmp(cpt, "long_paths_on", l) == 0) ) {
11273
xorriso->relax_compliance|= isoburn_igopt_allow_longer_paths;
11274
} else if(l == 14 && strncmp(cpt, "long_paths_off", l) == 0) {
11275
xorriso->relax_compliance&= ~isoburn_igopt_allow_longer_paths;
11277
} else if((l == 10 && strncmp(cpt, "long_names", l) == 0) ||
11278
(l == 13 && strncmp(cpt, "long_names_on", l) == 0)) {
11279
xorriso->relax_compliance|= isoburn_igopt_max_37_char_filenames;
11280
} else if(l == 14 && strncmp(cpt, "long_names_off", l) == 0) {
11281
xorriso->relax_compliance&= ~isoburn_igopt_max_37_char_filenames;
11283
} else if((l == 13 && strncmp(cpt, "no_force_dots", l) == 0) ||
11284
(l == 16 && strncmp(cpt, "no_force_dots_on", l) == 0)) {
11285
xorriso->relax_compliance|= isoburn_igopt_no_force_dots;
11286
} else if(l == 17 && strncmp(cpt, "no_force_dots_off", l) == 0) {
11287
xorriso->relax_compliance&= ~isoburn_igopt_no_force_dots;
11289
} else if((l == 15 && strncmp(cpt, "no_j_force_dots", l) == 0) ||
11290
(l == 18 && strncmp(cpt, "no_j_force_dots_on", l) == 0)) {
11291
xorriso->relax_compliance|= isoburn_igopt_no_j_force_dots;
11292
} else if(l == 19 && strncmp(cpt, "no_j_force_dots_off", l) == 0) {
11293
xorriso->relax_compliance&= ~isoburn_igopt_no_j_force_dots;
11295
} else if((l == 9 && strncmp(cpt, "lowercase", l) == 0) ||
11296
(l == 12 && strncmp(cpt, "lowercase_on", l) == 0)) {
11297
xorriso->relax_compliance|= isoburn_igopt_allow_lowercase;
11298
} else if(l == 13 && strncmp(cpt, "lowercase_off", l) == 0) {
11299
xorriso->relax_compliance&= ~isoburn_igopt_allow_lowercase;
11301
} else if((l == 10 && strncmp(cpt, "full_ascii", l) == 0) ||
11302
(l == 13 && strncmp(cpt, "full_ascii_on", l) == 0)) {
11303
xorriso->relax_compliance|= isoburn_igopt_allow_full_ascii;
11304
} else if(l == 14 && strncmp(cpt, "full_ascii_off", l) == 0) {
11305
xorriso->relax_compliance&= ~isoburn_igopt_allow_full_ascii;
11307
} else if((l == 17 && strncmp(cpt, "joliet_long_paths", l) == 0) ||
11308
(l == 20 && strncmp(cpt, "joliet_long_paths_on", l) == 0)) {
11309
xorriso->relax_compliance|= isoburn_igopt_joliet_longer_paths;
11310
} else if(l == 21 && strncmp(cpt, "joliet_long_paths_off", l) == 0) {
11311
xorriso->relax_compliance&= ~isoburn_igopt_joliet_longer_paths;
11313
} else if((l == 10 && strncmp(cpt, "always_gmt", l) == 0) ||
11314
(l == 13 && strncmp(cpt, "always_gmt_on", l) == 0)) {
11315
xorriso->relax_compliance|= isoburn_igopt_always_gmt;
11316
} else if(l == 14 && strncmp(cpt, "always_gmt_off", l) == 0) {
11317
xorriso->relax_compliance&= ~isoburn_igopt_always_gmt;
11319
} else if((l == 9 && strncmp(cpt, "rec_mtime", l) == 0) ||
11320
(l == 12 && strncmp(cpt, "rec_mtime_on", l) == 0)) {
11321
xorriso->relax_compliance|= isoburn_igopt_dir_rec_mtime;
11322
} else if(l == 13 && strncmp(cpt, "rec_mtime_off", l) == 0) {
11323
xorriso->relax_compliance&= ~isoburn_igopt_dir_rec_mtime;
11325
} else if((l == 6 && strncmp(cpt, "old_rr", l) == 0) ||
11326
(l == 9 && strncmp(cpt, "old_rr_on", l) == 0) ||
11327
(l == 10 && strncmp(cpt, "new_rr_off", l) == 0)) {
11328
xorriso->relax_compliance|=
11329
isoburn_igopt_rrip_version_1_10 | isoburn_igopt_aaip_susp_1_10;
11330
} else if((l == 10 && strncmp(cpt, "old_rr_off", l) == 0) ||
11331
(l == 9 && strncmp(cpt, "new_rr_on", l) == 0) ||
11332
(l == 6 && strncmp(cpt, "new_rr", l) == 0)) {
11333
xorriso->relax_compliance&=
11334
~(isoburn_igopt_rrip_version_1_10 | isoburn_igopt_aaip_susp_1_10);
11336
} else if((l == 14 && strncmp(cpt, "aaip_susp_1_10", l) == 0) ||
11337
(l == 17 && strncmp(cpt, "aaip_susp_1_10_on", l) == 0) ||
11338
(l == 18 && strncmp(cpt, "aaip_susp_1_12_off", l) == 0)) {
11339
xorriso->relax_compliance|= isoburn_igopt_aaip_susp_1_10;
11340
} else if((l == 18 && strncmp(cpt, "aaip_susp_1_10_off", l) == 0) ||
11341
(l == 17 && strncmp(cpt, "aaip_susp_1_12_on", l) == 0) ||
11342
(l == 14 && strncmp(cpt, "aaip_susp_1_12", l) == 0)) {
11343
xorriso->relax_compliance&= ~isoburn_igopt_aaip_susp_1_10;
11345
} else if((l == 8 && strncmp(cpt, "iso_9660", l) == 0) ||
11346
(l == 11 && strncmp(cpt, "iso_9660_on", l) == 0)) {
11347
/* may have a meaning in future */;
11348
} else if(l == 12 && strncmp(cpt, "iso_9660_off", l) == 0) {
11349
/* may have a meaning in future */;
11350
Xorriso_msgs_submit(xorriso, 0,
11351
"-compliance -iso_9660_off : Cannot do anything else but ISO 9660",
11356
sprintf(xorriso->info_text, "-compliance: unknown rule '%s'",
11359
sprintf(xorriso->info_text,
11360
"-compliance: oversized rule parameter (%d)", l);
11361
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
11362
xorriso->relax_compliance= was;
11370
/* @return 1=ok 2=ok, is default setting */
11371
int Xorriso_get_relax_text(struct XorrisO *xorriso, char mode[1024],
11376
r= xorriso->relax_compliance;
11378
strcpy(mode, "strict");
11381
strcpy(mode, "clear");
11382
if(r & isoburn_igopt_omit_version_numbers)
11383
strcat(mode, ":omit_version");
11384
if(r & isoburn_igopt_only_iso_versions)
11385
strcat(mode, ":only_iso_version");
11386
if(r & isoburn_igopt_allow_deep_paths)
11387
strcat(mode, ":deep_paths");
11388
if(r & isoburn_igopt_allow_longer_paths)
11389
strcat(mode, ":long_paths");
11390
if(r & isoburn_igopt_max_37_char_filenames)
11391
strcat(mode, ":long_names");
11392
if(r & isoburn_igopt_no_force_dots)
11393
strcat(mode, ":no_force_dots");
11394
if(r & isoburn_igopt_no_j_force_dots)
11395
strcat(mode, ":no_j_force_dots");
11396
if(r & isoburn_igopt_allow_lowercase)
11397
strcat(mode, ":lowercase");
11398
if(r & isoburn_igopt_allow_full_ascii)
11399
strcat(mode, ":full_ascii");
11400
if(r & isoburn_igopt_joliet_longer_paths)
11401
strcat(mode, ":joliet_long_paths");
11402
if(r & isoburn_igopt_always_gmt)
11403
strcat(mode, ":always_gmt");
11404
if(r & isoburn_igopt_dir_rec_mtime)
11405
strcat(mode, ":rec_mtime");
11406
if(r & isoburn_igopt_rrip_version_1_10) {
11407
strcat(mode, ":old_rr");
11408
if(!(r & isoburn_igopt_aaip_susp_1_10))
11409
strcat(mode, ":aaip_susp_1_10_off");
11411
strcat(mode, ":new_rr");
11412
if(r & isoburn_igopt_aaip_susp_1_10)
11413
strcat(mode, ":aaip_susp_1_10");
11416
return(1 + (r == Xorriso_relax_compliance_defaulT));
11421
@param flag bit0= print mount command to result channel rather than
11423
bit1= do not allow prefixes with cmd
11424
bit2= interpret unprefixed cmd as shell:
11426
int Xorriso_mount(struct XorrisO *xorriso, char *dev, int adr_mode,
11427
char *adr_value, char *cmd, int flag)
11429
int ret, lba, track, session, params_flag= 0, is_safe= 0, is_extra_drive= 0;
11430
int give_up= 0, mount_chardev= 0, status;
11431
char volid[33], *devadr, mount_command[SfileadrL], adr_data[163], *adr_pt;
11432
char *dev_path, libburn_adr[BURN_DRIVE_ADR_LEN + SfileadrL];
11433
char sfe[5 * SfileadrL], *dpt, *sysname= "";
11435
struct burn_drive_info *dinfo= NULL;
11436
struct burn_drive *drive= NULL;
11440
if(strcmp(dev, "indev") == 0) {
11441
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
11442
"on attempt to perform -mount \"indev\"", 0);
11445
dev_path= devadr= xorriso->indev;
11446
if(strncmp(dev_path, "stdio:", 6) == 0)
11448
if(xorriso->in_drive_handle == xorriso->out_drive_handle)
11452
} else if(strcmp(dev, "outdev") == 0) {
11453
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
11454
"on attempt to perform -mount \"outdev\"",
11458
dev_path= devadr= xorriso->outdev;
11459
if(strncmp(dev_path, "stdio:", 6) == 0)
11461
if(xorriso->in_drive_handle == xorriso->out_drive_handle)
11468
if(strncmp(dev_path, "stdio:", 6) == 0)
11471
/* do only accept regular files and block devices */
11472
ret= stat(dev_path, &stbuf);
11474
sprintf(xorriso->info_text, "Cannot determine properties of file %s",
11475
Text_shellsafe(dev_path, sfe, 0));
11476
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
11479
ret= System_uname(&sysname, NULL, NULL, NULL, 0);
11480
if(ret > 0 && strcmp(sysname, "FreeBSD") == 0)
11482
if(!(S_ISREG(stbuf.st_mode) || (S_ISBLK(stbuf.st_mode) && !mount_chardev)
11483
|| (S_ISCHR(stbuf.st_mode) && !mount_chardev))) {
11484
sprintf(xorriso->info_text,
11485
"File object is not suitable as mount device: %s",
11486
Text_shellsafe(dev_path, sfe, 0));
11487
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
11491
/* Aquire drive as direct libburn address or via stdio: prefix */
11492
ret= burn_drive_convert_fs_adr(dev, libburn_adr);
11493
Xorriso_process_msg_queues(xorriso,0);
11495
{ret= -1; goto ex;}
11496
if(ret == 0 && strncmp(dev, "stdio:", 6) != 0)
11497
sprintf(libburn_adr, "stdio:%s", dev);
11498
burn_preset_device_open(xorriso->drives_exclusive, 0, 0);
11499
ret= isoburn_drive_aquire(&dinfo, libburn_adr, 1);
11500
burn_preset_device_open(1, 0, 0);
11501
Xorriso_process_msg_queues(xorriso,0);
11504
drive= dinfo[0].drive;
11507
if(adr_mode == 4 && strlen(adr_pt) <= 80) {
11508
ret= Xorriso__bourne_to_reg(adr_pt, adr_data, 0);
11514
ret= isoburn_get_mount_params(drive, adr_mode, adr_pt, &lba, &track,
11515
&session, volid, params_flag);
11516
Xorriso_process_msg_queues(xorriso,0);
11519
if(session <= 0 || track <= 0 || ret == 2) {
11520
Xorriso_msgs_submit(xorriso, 0,
11521
"-mount : Given address does not point to an ISO 9660 session",
11525
if(strstr(devadr, "stdio:") == devadr)
11527
ret= Xorriso_make_mount_cmd(xorriso, cmd, lba, track, session, volid, devadr,
11528
mount_command, flag & (2 | 4));
11534
if(is_extra_drive) {
11535
isoburn_drive_release(drive, 0);
11536
burn_drive_info_free(dinfo);
11538
} else if(give_up > 0 && !((flag & 1) || (xorriso->mount_opts_flag & 1))) {
11539
Xorriso_give_up_drive(xorriso, give_up);
11543
Xorriso_process_msg_queues(xorriso,0);
11545
sprintf(xorriso->info_text, "Volume id : %s\n",
11546
Text_shellsafe(volid, sfe, 0));
11547
Xorriso_info(xorriso, 0);
11549
sprintf(xorriso->result_line, "%s\n", mount_command);
11550
Xorriso_result(xorriso,0);
11552
sprintf(xorriso->info_text, "Mount command: %s\n", mount_command);
11553
Xorriso_info(xorriso, 0);
11555
Xorriso_msgs_submit(xorriso, 0,
11556
"-mount : Will not perform mount command which stems from command template.",
11558
sprintf(xorriso->result_line, "%s\n", mount_command);
11559
Xorriso_result(xorriso,0);
11561
ret= Xorriso_execv(xorriso, mount_command, "/bin:/sbin", &status, 1);
11562
if(WIFEXITED(status) && WEXITSTATUS(status) != 0) {
11563
sprintf(xorriso->info_text,
11564
"-mount : mount command failed with exit value %d",
11565
(int) WEXITSTATUS(ret));
11566
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
11569
sprintf(xorriso->info_text, "\nMounted session %d of device %s",
11570
session, Text_shellsafe(dev_path, sfe, 0));
11571
dpt= strchr(cmd, ':');
11576
sprintf(xorriso->info_text + strlen(xorriso->info_text),
11577
" as directory %s\n", Text_shellsafe(dpt, sfe, 0));
11578
Xorriso_info(xorriso, 0);
11583
if(is_extra_drive && drive != NULL) {
11584
isoburn_drive_release(drive, 0);
11585
burn_drive_info_free(dinfo);
11586
Xorriso_process_msg_queues(xorriso,0);
11592
int Xorriso_auto_driveadr(struct XorrisO *xorriso, char *adr, char *result,
11595
int ret, is_known_mmc= 0;
11596
char *path_pt, libburn_adr[BURN_DRIVE_ADR_LEN + SfileadrL];
11597
char *abs_pt, abs_adr[SfileadrL];
11600
if(strncmp(adr, "stdio:", 6) == 0)
11602
else if(strncmp(adr, "mmc:", 4) == 0)
11606
/* <<< replace by Xorriso_normalize_img_path() ? */;
11608
if(path_pt[0] != '/') {
11609
abs_pt= getcwd(abs_adr, SfileadrL - 1);
11610
if(abs_pt == NULL) {
11611
Xorriso_msgs_submit(xorriso, 0,
11612
"Relative drive path given. Cannot determine working directory.",
11613
errno, "FAILURE", 0);
11616
ret= Sfile_add_to_path(abs_adr, path_pt, 0);
11621
is_known_mmc= burn_drive_convert_fs_adr(path_pt, libburn_adr);
11622
Xorriso_process_msg_queues(xorriso,0);
11624
ret= Xorriso_is_in_patternlist(xorriso, xorriso->drive_whitelist, path_pt, 0);
11627
ret= Xorriso_is_in_patternlist(xorriso, xorriso->drive_blacklist, path_pt, 0);
11631
strcpy(xorriso->info_text, "Drive address ");
11632
Text_shellsafe(adr, xorriso->info_text, 1);
11633
strcat(xorriso->info_text,
11634
" rejected because: -drive_class 'banned' ");
11635
Text_shellsafe(Xorriso_get_pattern(xorriso, xorriso->drive_blacklist,
11637
xorriso->info_text, 1);
11638
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
11641
/* if in greylist and not MMC and not stdio prefix: reject */
11642
if(is_known_mmc < 0)
11644
if(adr == path_pt && !is_known_mmc) { /* no prefix, no MMC */
11645
ret= Xorriso_is_in_patternlist(xorriso, xorriso->drive_greylist, path_pt,0);
11649
strcpy(xorriso->info_text, "Drive address ");
11650
Text_shellsafe(adr, xorriso->info_text, 1);
11651
strcat(xorriso->info_text,
11652
" rejected because: not MMC and -drive_class 'risky' ");
11653
Text_shellsafe(Xorriso_get_pattern(xorriso,xorriso->drive_greylist,
11655
xorriso->info_text, 1);
11656
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
11657
Xorriso_msgs_submit(xorriso, 0,
11658
"If the address is a legitimate target, prepend \"stdio:\"",
11664
if(strncmp(adr, "mmc:", 4) == 0) {
11665
if(Sfile_str(result, path_pt, 0) <= 0)
11667
} else if(adr == path_pt && is_known_mmc <= 0) {
11668
Sfile_str(result, "stdio:", 0);
11669
if(Sfile_str(result, adr, 1) <= 0)
11672
if(Sfile_str(result, adr, 0) <= 0)
11675
if(strncmp(result, "stdio:", 6)==0) {
11676
if(xorriso->ban_stdio_write) {
11677
strcpy(xorriso->info_text, "Drive address banned by -ban_stdio_write : ");
11678
Text_shellsafe(result, xorriso->info_text, 1);
11679
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
11688
@param flag bit0= do not remove leading slash
11689
bit1= append flatly to result_line and put out
11691
int Xorriso_getfname(struct XorrisO *xorriso, char *path, int flag)
11693
int ret, path_offset= 0, bsl_mem;
11694
char *bsl_path= NULL;
11696
if(path[0] == '/' && !(flag & 1))
11699
/* backslash escaped path rather than shellsafe path */
11700
ret= Sfile_bsl_encoder(&bsl_path, path + path_offset,
11701
strlen(path + path_offset), 8);
11705
sprintf(xorriso->result_line + strlen(xorriso->result_line),
11706
"%s\n", bsl_path[0] ? bsl_path : ".");
11708
sprintf(xorriso->result_line, "# file: %s\n", bsl_path[0] ? bsl_path : ".");
11712
/* temporarily disable -backslash_codes with result output */
11713
bsl_mem= xorriso->bsl_interpretation;
11714
xorriso->bsl_interpretation= 0;
11715
Xorriso_result(xorriso, 0);
11716
xorriso->bsl_interpretation= bsl_mem;
11721
/* @param node Opaque handle to IsoNode which is to be inquired instead of path if it is not NULL.
11722
@param path is used as address if node is NULL.
11723
@param acl_text if acl_text is not NULL, then *acl_text will be set to the
11724
ACL text (without comments) of the file object. In this
11725
case it finally has to be freed by the caller.
11726
@param flag bit0= do not report to result but only retrieve ACL text
11727
bit1= check for existence of true ACL (not fabricated),
11728
do not allocate and set acl_text but return 1 or 2
11729
bit2-3: what ALC to retrieve:
11730
0= "access" and "default", mark "default:"
11732
2= "default" only, do not mark "default:"
11733
bit4= get "access" ACL only if not trivial
11734
@return 2 ok, no ACL available, eventual *acl_text will be NULL
11735
1 ok, ACL available, eventual *acl_text stems from malloc()
11738
int Xorriso_getfacl(struct XorrisO *xorriso, void *in_node, char *path,
11739
char **acl_text, int flag)
11741
int ret, d_ret, result_len= 0, pass, what;
11743
char *text= NULL, *d_text= NULL, *cpt, *npt;
11746
struct passwd *pwd;
11749
what= (flag >> 2) & 3;
11750
if(acl_text != NULL)
11753
node= (IsoNode *) in_node;
11755
ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
11759
ret= iso_node_get_acl_text(node, &text, &d_text, flag & 16);
11760
d_ret= (d_text != NULL);
11761
if(ret < 0 || d_ret < 0) {
11762
if(path != NULL && path[0] != 0) {
11763
strcpy(xorriso->info_text, "Error with obtaining ACL of ");
11764
Text_shellsafe(path, xorriso->info_text, 1);
11765
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
11770
ret= 1 + (ret != 1 && d_ret == 0);
11773
if((ret == 0 || ret == 2) && d_ret == 0) {
11775
ret= 1 + (ret == 0);
11778
strcpy(xorriso->info_text, "No ACL associated with ");
11779
Text_shellsafe(path, xorriso->info_text, 1);
11780
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
11786
ret= Xorriso_getfname(xorriso, path, 0);
11789
uid= iso_node_get_uid(node);
11790
pwd= getpwuid(uid);
11792
sprintf(xorriso->result_line, "# owner: %.f\n", (double) uid);
11794
sprintf(xorriso->result_line, "# owner: %s\n", pwd->pw_name);
11795
Xorriso_result(xorriso, 0);
11796
gid= iso_node_get_gid(node);
11797
grp= getgrgid(gid);
11799
sprintf(xorriso->result_line, "# group: %.f\n", (double) gid);
11801
sprintf(xorriso->result_line, "# group: %s\n", grp->gr_name);
11802
Xorriso_result(xorriso, 0);
11805
for(pass= 0; pass < 1 + (acl_text != NULL && !(flag & 2)); pass++) {
11807
*acl_text= calloc(result_len + 1, 1);
11808
if(*acl_text == NULL) {
11809
Xorriso_no_malloc_memory(xorriso, NULL, 0);
11813
if(text != NULL && what <= 1) {
11814
for(npt= cpt= text; npt != NULL; cpt= npt + 1) {
11815
npt= strchr(cpt, '\n');
11819
if(d_text != NULL || pass) {
11825
result_len+= strlen(cpt) + 1;
11827
sprintf(*acl_text + strlen(*acl_text), "%s\n", cpt);
11828
} else if(!(flag & 1)) {
11829
Sfile_str(xorriso->result_line, cpt, 0);
11830
strcat(xorriso->result_line, "\n");
11831
Xorriso_result(xorriso, 0);
11837
if(d_text != NULL && (what == 0 || what == 2)) {
11838
for(npt= cpt= d_text; npt != NULL; cpt= npt + 1) {
11839
npt= strchr(cpt, '\n');
11845
sprintf(*acl_text + strlen(*acl_text), "default:%s\n", cpt);
11847
sprintf(*acl_text + strlen(*acl_text), "%s\n", cpt);
11849
xorriso->result_line[0]= 0;
11851
Sfile_str(xorriso->result_line, "default:", 0);
11852
Sfile_str(xorriso->result_line, cpt, 1);
11853
result_len+= strlen(cpt) + 9;
11856
xorriso->result_line[0]= 0;
11857
if(pass== 0 && !(flag & 1)) {
11858
strcat(xorriso->result_line, "\n");
11859
Xorriso_result(xorriso, 0);
11868
iso_node_get_acl_text(node, &text, &d_text, 1 << 15);
11873
int Xorriso_set_ignore_aclea(struct XorrisO *xorriso, int flag)
11878
ret= Xorriso_get_volume(xorriso, &volume, 1);
11881
hflag= (~xorriso->do_aaip) & 1;
11882
if((xorriso->ino_behavior & (1 | 2)) && !(xorriso->do_aaip & (4 | 16)))
11884
iso_image_set_ignore_aclea(volume, hflag);
11889
/* @param node Opaque handle to IsoNode which is to be manipulated
11890
instead of path if it is not NULL.
11891
@param path is used as address if node is NULL.
11892
@param access_text "access" ACL in long text form
11893
@param default_text "default" ACL in long text form
11894
@param flag bit0= do not warn of root directory if not capable of AAIP
11895
@return >0 success , <=0 failure
11897
int Xorriso_setfacl(struct XorrisO *xorriso, void *in_node, char *path,
11898
char *access_text, char *default_text, int flag)
11903
node= (IsoNode *) in_node;
11905
ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
11909
ret= iso_node_set_acl_text(node, access_text, default_text, 0);
11911
if(path != NULL && path[0] != 0) {
11912
strcpy(xorriso->info_text, "Error with setting ACL of ");
11913
Text_shellsafe(path, xorriso->info_text, 1);
11914
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
11918
Xorriso_set_change_pending(xorriso, 0);
11921
Xorriso_process_msg_queues(xorriso,0);
11927
@param flag bit0= do not report to result but only retrieve attr text
11928
bit1= path is disk_path
11929
bit3= do not ignore eventual non-user attributes.
11930
bit5= in case of symbolic link on disk: inquire link target
11931
bit6= check for existence of xattr, return 0 or 1
11932
(depends also on bit3)
11934
int Xorriso_getfattr(struct XorrisO *xorriso, void *in_node, char *path,
11935
char **attr_text, int flag)
11937
int ret= 1, i, bsl_mem, result_len= 0, pass;
11938
size_t num_attrs= 0, *value_lengths= NULL;
11939
char **names= NULL, **values= NULL, *bsl;
11941
if(attr_text != NULL)
11943
ret= Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names,
11944
&value_lengths, &values, flag & (2 | 8 | 32));
11948
ret= (num_attrs > 0);
11955
ret= Xorriso_getfname(xorriso, path, 0);
11959
for(pass= 0; pass < 1 + (attr_text != NULL); pass++) {
11961
*attr_text= calloc(result_len + 1, 1);
11962
if(*attr_text == NULL) {
11963
Xorriso_no_malloc_memory(xorriso, NULL, 0);
11967
for(i= 0; i < num_attrs; i++) {
11968
if(strlen(names[i]) + value_lengths[i] >= SfileadrL) {
11969
sprintf(xorriso->result_line, "# oversized: name %d , value %d bytes\n",
11970
(int) strlen(names[i]), (int) value_lengths[i]);
11972
ret= Sfile_bsl_encoder(&bsl, names[i], strlen(names[i]), 8);
11974
{ret= -1; goto ex;}
11975
strcpy(xorriso->result_line, bsl);
11977
ret= Sfile_bsl_encoder(&bsl, values[i], value_lengths[i], 8);
11979
{ret= -1; goto ex;}
11980
sprintf(xorriso->result_line + strlen(xorriso->result_line),
11984
/* temporarily disable -backslash_codes with result output */
11985
result_len+= strlen(xorriso->result_line);
11987
strcat(*attr_text, xorriso->result_line);
11988
} else if(!(flag & 1)) {
11989
bsl_mem= xorriso->bsl_interpretation;
11990
xorriso->bsl_interpretation= 0;
11991
Xorriso_result(xorriso, 0);
11992
xorriso->bsl_interpretation= bsl_mem;
11997
strcpy(xorriso->result_line, "\n");
11998
Xorriso_result(xorriso, 0);
12002
Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names,
12003
&value_lengths, &values, 1 << 15);
12008
/* @param in_node Opaque handle to IsoNode which is to be manipulated
12009
instead of path if it is not NULL.
12010
@param path is used as address if node is NULL.
12011
@param num_attrs Number of attributes
12012
@param names Array of pointers to 0 terminated name strings
12013
@param value_lengths Array of byte lengths for each attribute payload
12014
@param values Array of pointers to the attribute payload bytes
12015
@param flag bit0= Do not maintain eventual existing ACL of the node
12016
bit1= Do not clear the existing attribute list
12017
bit2= Delete the attributes with the given names
12018
bit3= Allow non-user attributes.
12019
bit4= do not warn of root if incapable of AAIP
12020
@return >0 success , <=0 failure
12022
int Xorriso_setfattr(struct XorrisO *xorriso, void *in_node, char *path,
12023
size_t num_attrs, char **names,
12024
size_t *value_lengths, char **values, int flag)
12029
node= (IsoNode *) in_node;
12031
ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
12035
ret= iso_node_set_attrs(node, num_attrs, names, value_lengths, values,
12036
flag & (1 | 2 | 4 | 8));
12037
Xorriso_process_msg_queues(xorriso,0);
12039
Xorriso_report_iso_error(xorriso, "", ret,
12040
"Error when setting ACL and xattr to image node",
12042
if(path != NULL && path[0] != 0) {
12043
strcpy(xorriso->info_text, "Error with setting xattr of ");
12044
Text_shellsafe(path, xorriso->info_text, 1);
12045
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
12049
Xorriso_set_change_pending(xorriso, 0);
12052
Xorriso_process_msg_queues(xorriso,0);
12059
Bitfield for control purposes
12060
bit0= get default ACL rather than access ACL
12061
bit4= set *text = NULL and return 2
12062
if the ACL matches st_mode permissions.
12063
bit5= in case of symbolic link: inquire link target
12064
bit15= free text and return 1
12067
2 ok, trivial ACL found while bit4 is set, *text is NULL
12068
0 no ACL manipulation adapter available / ACL not supported by fs
12069
-1 failure of system ACL service (see errno)
12070
-2 attempt to inquire ACL of a symbolic link without bit4 or bit5
12071
resp. with no suitable link target
12073
int Xorriso_local_getfacl(struct XorrisO *xorriso, char *disk_path,
12074
char **text, int flag)
12076
int ret, skip= 0, colons= 0, countdown= 0;
12077
char *acl= NULL, *cpt, *wpt;
12079
if(flag & (1 << 15)) {
12086
ret= iso_local_get_acl_text(disk_path, &acl, flag & (1 | 16 | 32));
12087
Xorriso_process_msg_queues(xorriso,0);
12088
if(ret < 0 || ret == 2)
12092
*text= strdup(acl);
12093
iso_local_get_acl_text(disk_path, &acl, 1 << 15);
12094
if(*text == NULL) {
12095
Xorriso_no_malloc_memory(xorriso, NULL, 0);
12099
/* Garbage collection about trailing remarks after 3 permission chars */
12101
for(cpt= *text; *cpt; cpt++) {
12108
if(*cpt == ':' && !countdown) {
12115
if(countdown > 0) {
12131
bit1= path is disk_path
12132
bit3= do not ignore eventual non-user attributes.
12133
bit5= in case of symbolic link on disk: inquire link target
12136
int Xorriso_get_attrs(struct XorrisO *xorriso, void *in_node, char *path,
12137
size_t *num_attrs, char ***names,
12138
size_t **value_lengths, char ***values, int flag)
12143
if(flag & (1 << 15)) {
12145
iso_local_get_attrs(NULL, num_attrs, names, value_lengths, values,
12148
iso_node_get_attrs(NULL, num_attrs, names, value_lengths, values,
12156
ret= iso_local_get_attrs(path, num_attrs, names, value_lengths, values,
12159
strcpy(xorriso->info_text, "Error with reading xattr of disk file ");
12160
Text_shellsafe(path, xorriso->info_text, 1);
12161
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
12164
node= (IsoNode *) in_node;
12166
ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
12170
ret= iso_node_get_attrs(node, num_attrs, names, value_lengths, values,
12173
Xorriso_report_iso_error(xorriso, "", ret,
12174
"Error when obtaining xattr of ISO node", 0, "FAILURE", 1);
12179
/* Filter away any non-userspace xattr */;
12181
for(i= 0; i < *num_attrs; i++) {
12182
if(strncmp((*names)[i], "user.", 5) != 0) {
12185
if((*values)[i] != NULL) {
12186
free((*values)[i]);
12187
(*values)[i]= NULL;
12191
(*names)[widx]= (*names)[i];
12192
(*value_lengths)[widx]= (*value_lengths)[i];
12193
(*values)[widx]= (*values)[i];
12195
(*value_lengths)[i]= 0;
12196
(*values)[i]= NULL;
12206
Xorriso_process_msg_queues(xorriso,0);
12211
int Xorriso_get_attr_value(struct XorrisO *xorriso, void *in_node, char *path,
12212
char *name, size_t *value_length, char **value, int flag)
12215
size_t num_attrs= 0, *value_lengths= NULL, i;
12216
char **names = NULL, **values= NULL;
12220
ret= Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names,
12221
&value_lengths, &values, 8);
12225
for(i= 0; i < num_attrs; i++) {
12226
if(strcmp(name, names[i]) != 0)
12228
*value= calloc(value_lengths[i] + 1, 1);
12230
{ret= -1; goto ex;}
12231
memcpy(*value, values[i], value_lengths[i]);
12232
(*value)[value_lengths[i]]= 0;
12233
*value_length= value_lengths[i];
12238
Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names,
12239
&value_lengths, &values, 1 << 15);
12245
@param flag bit0= use parameters dev,ino rather than disk_path
12246
bit1= compare attribute rather than setting it
12247
return: 0=dev,ino match, 1=mismatch, 2=no node attribute
12250
transfer dev,inode from eventual link target
12251
bit7= omit dev check mit bit1
12253
int Xorriso_record_dev_inode(struct XorrisO *xorriso, char *disk_path,
12254
dev_t dev, ino_t ino,
12255
void *in_node, char *iso_path, int flag)
12261
char buf[66], *bufpt, *wpt, *di= NULL;
12262
static char *name= "isofs.di";
12267
if(stat(disk_path, &stbuf) == -1)
12270
if(lstat(disk_path, &stbuf) == -1)
12279
for(i= 0; hdev != 0; i++)
12283
for(i= 0; i < l; i++)
12284
*(wpt++)= dev >> (8 * (l - i - 1));
12286
for(i= 0; hino != 0; i++)
12290
for(i= 0; i < l; i++)
12291
*(wpt++)= ino >> (8 * (l - i - 1));
12296
/* Compare node attribute with bufpt,l */
12297
ret= Xorriso_get_attr_value(xorriso, in_node, iso_path,
12298
"isofs.di", &di_l, &di, 0);
12307
for(i= di[0] + 2; i < di_l && i - di[0] - 2 < di[(int) di[0] + 1]; i++)
12308
hino= (hino << 8) | ((unsigned char *) di)[i];
12314
for(i= 0; i < l; i++)
12315
if(di[i] != buf[i])
12320
ret= Xorriso_setfattr(xorriso, in_node, iso_path,
12321
(size_t) 1, &name, &l, &bufpt, 2 | 8);
12330
struct Xorriso_extF {
12332
int flag; /* unused yet */
12334
IsoExternalFilterCommand *cmd;
12338
int Xorriso_extf_destroy(struct XorrisO *xorriso, struct Xorriso_extF **filter,
12342
/* @param flag see struct Xorriso_extF.flag */
12343
int Xorriso_extf_new(struct XorrisO *xorriso, struct Xorriso_extF **filter,
12344
char *path, int argc, char **argv, int behavior,
12345
char *suffix, char *name, int flag)
12348
struct Xorriso_extF *o= NULL;
12349
IsoExternalFilterCommand *cmd;
12351
*filter= o= calloc(sizeof(struct Xorriso_extF), 1);
12356
o->cmd= cmd= calloc(sizeof(IsoExternalFilterCommand), 1);
12364
cmd->argc= argc + 1;
12365
cmd->behavior= behavior;
12367
cmd->suffix= strdup(suffix);
12368
if(cmd->suffix == NULL)
12371
cmd->path= strdup(path);
12372
if(cmd->path == NULL)
12374
cmd->argv= calloc(sizeof(char *), argc + 2);
12375
if(cmd->argv == NULL)
12377
for(i= 0; i < argc + 2; i++)
12378
cmd->argv[i]= NULL;
12379
cmd->argv[0]= strdup(path);
12380
if(cmd->argv[0] == NULL)
12382
for(i= 0; i < argc; i++) {
12383
cmd->argv[i + 1]= strdup(argv[i]);
12384
if(cmd->argv[i] == NULL)
12387
cmd->name= strdup(name);
12388
if(cmd->name == NULL)
12392
Xorriso_extf_destroy(xorriso, filter, 0);
12397
int Xorriso_extf_destroy(struct XorrisO *xorriso, struct Xorriso_extF **filter,
12401
IsoExternalFilterCommand *cmd;
12403
if(*filter == NULL)
12405
cmd= (*filter)->cmd;
12407
if(cmd->refcount > 0)
12409
if(cmd->suffix != NULL)
12411
if(cmd->argv != NULL) {
12412
for(i= 0; i < cmd->argc; i++)
12413
if(cmd->argv[i] != NULL)
12414
free(cmd->argv[i]);
12415
free((char *) cmd->argv);
12417
if(cmd->name != NULL)
12420
free((char *) *filter);
12426
int Xorriso_lookup_extf(struct XorrisO *xorriso, char *name,
12427
struct Xorriso_lsT **found_lst, int flag)
12429
struct Xorriso_extF *filter;
12430
struct Xorriso_lsT *lst;
12432
for(lst= xorriso->filters; lst != NULL; lst= Xorriso_lst_get_next(lst, 0)) {
12433
filter= (struct Xorriso_extF *) Xorriso_lst_get_text(lst, 0);
12434
if(strcmp(filter->cmd->name, name) == 0) {
12443
int Xorriso_destroy_all_extf(struct XorrisO *xorriso, int flag)
12445
struct Xorriso_extF *filter;
12446
struct Xorriso_lsT *lst, *next_lst;
12448
for(lst= xorriso->filters; lst != NULL; lst= next_lst) {
12449
filter= (struct Xorriso_extF *) Xorriso_lst_get_text(lst, 0);
12450
Xorriso_lst_detach_text(lst, 0);
12451
next_lst= Xorriso_lst_get_next(lst, 0);
12452
Xorriso_lst_destroy(&lst, 0);
12453
Xorriso_extf_destroy(xorriso, &filter, 0);
12455
xorriso->filters= NULL;
12461
@param flag bit0= return 2 if renaming is not possible by libisofs
12462
(always: if demanded strip suffix is missing
12463
or if suffix makes name length > 255)
12464
bit1= strip suffix rather than appending it
12466
int Xorriso_rename_suffix(struct XorrisO *xorriso, IsoNode *node, char *suffix,
12467
char *show_path, char new_name[], int flag)
12469
int ret, lo= 0, ls= 0, strip_suffix;
12470
char *old_name= NULL, *show_name;
12472
strip_suffix= !!(flag & 2);
12474
old_name= strdup((char *) iso_node_get_name(node));
12475
show_name= old_name;
12476
if(show_path != NULL)
12477
if(show_path[0] != 0)
12478
show_name= show_path;
12479
lo= strlen(old_name);
12480
ls= strlen(suffix);
12483
/* refuse gracefully */
12486
if(strcmp(old_name + lo - ls, suffix) != 0) {
12489
if(lo >= SfileadrL)
12490
goto cannot_remove_suffix;
12491
strcpy(new_name, old_name);
12492
new_name[lo - ls]= 0;
12493
ret = iso_node_set_name(node, new_name);
12495
Xorriso_process_msg_queues(xorriso,0);
12497
Xorriso_report_iso_error(xorriso, "", ret,
12498
"Error when renaming ISO node", 0, "FAILURE", 1);
12499
cannot_remove_suffix:;
12500
strcpy(xorriso->info_text, "-set_filter: Cannot remove suffix from ");
12501
Text_shellsafe(show_name, xorriso->info_text, 1);
12502
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
12503
(flag & 1) ? "WARNING" : "FAILURE", 0);
12504
ret= 2 * (flag & 1); goto ex;
12507
/* check whether suffix already present */
12509
if(strcmp(old_name + lo - ls, suffix) == 0) {
12510
/* refuse gracefully */
12513
if(lo + ls > 255) {
12514
cannot_append_suffix:;
12515
strcpy(xorriso->info_text, "-set_filter: Cannot append suffix to ");
12516
Text_shellsafe(show_name, xorriso->info_text, 1);
12517
strcat(xorriso->info_text, ". Left unfiltered.");
12518
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
12519
(flag & 1) ? "WARNING" : "FAILURE", 0);
12520
ret= 2 * (flag & 1); goto ex;
12522
sprintf(new_name, "%s%s", old_name, suffix);
12523
ret = iso_node_set_name(node, new_name);
12525
Xorriso_process_msg_queues(xorriso,0);
12527
Xorriso_report_iso_error(xorriso, "", ret,
12528
"Error when renaming ISO node", 0, "FAILURE", 1);
12529
goto cannot_append_suffix;
12535
if(old_name != NULL)
12537
Xorriso_process_msg_queues(xorriso,0);
12543
@param flag bit0= return 2 if renaming is not possible
12544
bit1= print pacifier messages
12546
int Xorriso_set_filter(struct XorrisO *xorriso, void *in_node,
12547
char *path, char *filter_name, int flag)
12549
int ret, strip_suffix= 0, strip_filter= 0, filter_ret= 0;
12550
int explicit_suffix= 0, internal_filter= 0;
12553
struct Xorriso_lsT *found_lst;
12554
struct Xorriso_extF *found_filter;
12555
IsoExternalFilterCommand *cmd = NULL;
12556
char *old_name= NULL, new_name[SfileadrL], *suffix= "";
12562
node= (IsoNode *) in_node;
12564
ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
12568
if(!LIBISO_ISREG(node)) {
12569
strcpy(xorriso->info_text, "-set_filter: Not a regular data file node ");
12570
Text_shellsafe(path, xorriso->info_text, 1);
12571
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
12574
file= (IsoFile *) node;
12576
if(strncmp(filter_name, "--remove-all-filters", 20) == 0) {
12579
if(strlen(filter_name) > 21) {
12580
strip_suffix= (filter_name[20] != '+');
12581
suffix= filter_name + 21;
12582
explicit_suffix= 1;
12584
} else if(strcmp(filter_name, "--zisofs") == 0) {
12585
internal_filter= 1;
12586
} else if(strcmp(filter_name, "--zisofs-decode") == 0) {
12587
internal_filter= 2;
12588
} else if(strcmp(filter_name, "--gzip") == 0) {
12589
internal_filter= 3;
12592
explicit_suffix= 1;
12593
} else if(strcmp(filter_name, "--gunzip") == 0 ||
12594
strcmp(filter_name, "--gzip-decode") == 0) {
12595
internal_filter= 4;
12598
explicit_suffix= 1;
12600
ret= Xorriso_lookup_extf(xorriso, filter_name, &found_lst, 0);
12604
strcpy(xorriso->info_text, "-set_filter: Not a registered filter name ");
12605
Text_shellsafe(filter_name, xorriso->info_text, 1);
12606
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
12609
found_filter= (struct Xorriso_extF *) Xorriso_lst_get_text(found_lst, 0);
12610
cmd= found_filter->cmd;
12611
suffix= cmd->suffix;
12612
strip_suffix= cmd->behavior & 8;
12617
/* >>> would need full iso_rr_path of node for showing */;
12619
old_name= strdup((char *) iso_node_get_name(node));
12620
ret= Xorriso_rename_suffix(xorriso, node, suffix, path, new_name,
12621
(flag & 1) | (strip_suffix ? 2 : 0));
12622
if(ret <= 0 || ret == 2)
12629
if(!explicit_suffix) {
12630
stream= iso_file_get_stream(file);
12632
if(strncmp(stream->class->type, "gzip", 4) == 0) {
12635
} else if(strncmp(stream->class->type, "pizg", 4) == 0) {
12639
ret= iso_stream_get_external_filter(stream, &cmd, 0);
12641
suffix= cmd->suffix;
12642
strip_suffix= !(cmd->behavior & 8);
12647
/* >>> would need the current renaming state of path */;
12649
ret= Xorriso_rename_suffix(xorriso, node, suffix, NULL, new_name,
12650
(flag & 1) | (strip_suffix << 1));
12651
if(ret <= 0 || ret == 2)
12655
ret= iso_file_remove_filter(file, 0);
12660
} else if (internal_filter == 1 || internal_filter == 2) {
12661
filter_ret = iso_file_add_zisofs_filter(file, 1 | (internal_filter & 2));
12662
if(filter_ret < 0) {
12663
Xorriso_process_msg_queues(xorriso,0);
12664
if(!(internal_filter == 2 && filter_ret == ISO_ZISOFS_WRONG_INPUT))
12665
Xorriso_report_iso_error(xorriso, "", filter_ret,
12666
"Error when setting filter to ISO node", 0, "FAILURE", 1);
12668
} else if (internal_filter == 3 || internal_filter == 4) {
12669
filter_ret = iso_file_add_gzip_filter(file,
12670
1 | ((internal_filter == 4) << 1));
12671
if(filter_ret < 0) {
12672
Xorriso_process_msg_queues(xorriso,0);
12673
Xorriso_report_iso_error(xorriso, "", filter_ret,
12674
"Error when setting filter to ISO node", 0, "FAILURE", 1);
12678
#ifndef Xorriso_allow_extf_suiD
12679
/* This is a final safety precaution before iso_file_add_external_filter()
12680
performs fork() and executes the alleged filter program.
12682
if(getuid() != geteuid()) {
12683
sprintf(xorriso->info_text,
12684
"-set_filter: UID and EUID differ. Will not run external programs.");
12685
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
12688
#endif /* ! Xorriso_allow_extf_suiD */
12690
filter_ret = iso_file_add_external_filter(file, cmd, 0);
12691
if(filter_ret < 0) {
12692
Xorriso_process_msg_queues(xorriso,0);
12693
Xorriso_report_iso_error(xorriso, "", filter_ret,
12694
"Error when setting filter to ISO node", 0, "FAILURE", 1);
12697
if(filter_ret != 1 && new_name[0] && old_name != NULL) {
12698
ret = iso_node_set_name(node, old_name);
12700
Xorriso_process_msg_queues(xorriso,0);
12702
Xorriso_report_iso_error(xorriso, "", ret,
12703
"Error when renaming ISO node", 0, "FAILURE", 1);
12707
xorriso->pacifier_count++;
12708
Xorriso_pacifier_callback(xorriso, "file filters processed",
12709
xorriso->pacifier_count, xorriso->pacifier_total, "", 0);
12711
if(filter_ret < 0) {
12717
if(old_name != NULL)
12719
Xorriso_process_msg_queues(xorriso,0);
12724
/* @param flag bit0= delete filter with the given name
12726
int Xorriso_external_filter(struct XorrisO *xorriso,
12727
char *name, char *options, char *path,
12728
int argc, char **argv, int flag)
12730
int ret, delete= 0, behavior= 0, extf_flag= 0, is_banned= 0;
12731
char *what, *what_next, *suffix= "";
12732
struct Xorriso_lsT *lst;
12733
struct Xorriso_extF *found_filter, *new_filter= NULL;
12735
#ifndef Xorriso_allow_external_filterS
12736
/* To be controlled by: configure --enable-external-filters */
12738
sprintf(xorriso->info_text, "%s : Banned at compile time.",
12739
flag & 1 ? "-unregister_filter" : "-external_filter");
12740
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
12741
sprintf(xorriso->info_text,
12742
"This may be changed at compile time by ./configure option --enable-external-filters");
12743
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
12746
#endif /* ! Xorriso_allow_external_filterS */
12748
#ifndef Xorriso_allow_extf_suiD
12749
/* To be controlled by: configure --enable-external-filters-setuid */
12751
if(getuid() != geteuid()) {
12752
sprintf(xorriso->info_text,
12753
"-set_filter: UID and EUID differ. Will not run external programs.");
12754
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
12755
sprintf(xorriso->info_text,
12756
"This may be changed at compile time by ./configure option --enable-external-filters-setuid");
12757
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
12760
#endif /* ! Xorriso_allow_extf_suiD */
12765
if(xorriso->filter_list_closed) {
12766
sprintf(xorriso->info_text,
12767
"%s : Banned by previous command -close_filter_list",
12768
flag & 1 ? "-unregister_filter" : "-external_filter");
12769
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
12772
if((!(flag & 1)) && path[0] != '/') {
12773
sprintf(xorriso->info_text,
12774
"-external_filter : Given command path does not begin by '/' : ");
12775
Text_shellsafe(path, xorriso->info_text, 1);
12776
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
12782
ret= Xorriso_lookup_extf(xorriso, name, &lst, 0);
12787
found_filter= (struct Xorriso_extF *) Xorriso_lst_get_text(lst, 0);
12788
if(found_filter->cmd->refcount > 0) {
12789
sprintf(xorriso->info_text,
12790
"-external_filter: Cannot remove filter because it is in use by %.f nodes : ",
12791
(double) found_filter->cmd->refcount);
12792
Text_shellsafe(name, xorriso->info_text, 1);
12793
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
12796
Xorriso_lst_detach_text(lst, 0);
12797
if(xorriso->filters == lst)
12798
xorriso->filters= Xorriso_lst_get_next(lst, 0);
12799
Xorriso_lst_destroy(&lst, 0);
12800
Xorriso_extf_destroy(xorriso, &found_filter, 0);
12803
strcpy(xorriso->info_text,
12804
"-external_filter: filter with given name already existing: ");
12805
Text_shellsafe(name, xorriso->info_text, 1);
12806
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
12810
strcpy(xorriso->info_text,
12811
"-external_filter: filter with given name does not exist: ");
12812
Text_shellsafe(name, xorriso->info_text, 1);
12813
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
12817
for(what= options; what!=NULL; what= what_next) {
12818
what_next= strchr(what, ':');
12819
if(what_next!=NULL) {
12823
if(strncmp(what, "default", 7) == 0) {
12826
} else if(strncmp(what, "suffix=", 7) == 0) {
12828
} else if(strcmp(what, "remove_suffix") == 0) {
12830
} else if(strcmp(what, "if_nonempty") == 0) {
12832
} else if(strcmp(what, "if_reduction") == 0) {
12834
} else if(strcmp(what, "if_block_reduction") == 0) {
12836
} else if(strncmp(what, "used=", 5) == 0) {
12837
; /* this is informational output from -status */
12838
} else if(what[0]) {
12839
strcpy(xorriso->info_text,
12840
"-external_filter: unknown option ");
12841
Text_shellsafe(what, xorriso->info_text, 1);
12842
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
12847
ret= Xorriso_extf_new(xorriso, &new_filter, path, argc, argv, behavior,
12848
suffix, name, extf_flag);
12851
strcpy(xorriso->info_text,
12852
"-external_filter: Could not create filter object");
12853
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
12856
ret= Xorriso_lst_append_binary(&(xorriso->filters), (char *) new_filter,0, 4);
12858
goto could_not_create;
12862
if(new_filter != NULL)
12863
Xorriso_extf_destroy(xorriso, &new_filter, 0);
12869
int Xorriso_status_extf(struct XorrisO *xorriso, char *filter, FILE *fp,
12872
bit1= do only report to fp
12875
int i, maxl= 4 * SfileadrL;
12876
struct Xorriso_extF *extf;
12877
struct Xorriso_lsT *lst;
12880
line= xorriso->result_line;
12881
for(lst= xorriso->filters; lst != NULL; lst= Xorriso_lst_get_next(lst, 0)) {
12882
extf= (struct Xorriso_extF *) Xorriso_lst_get_text(lst, 0);
12884
strcpy(xorriso->result_line, "-external_filter ");
12885
Text_shellsafe(extf->cmd->name, line, 1);
12886
if(strlen(line) > maxl)
12889
if(extf->cmd->suffix[0]) {
12890
strcat(line, "suffix=");
12891
Text_shellsafe(extf->cmd->suffix, line, 1);
12892
if(strlen(line) > maxl)
12896
if(extf->cmd->behavior & 8)
12897
strcat(line, "remove_suffix:");
12898
if(extf->cmd->behavior & 1)
12899
strcat(line, "if_nonempty:");
12900
if(extf->cmd->behavior & 2)
12901
strcat(line, "if_reduction:");
12902
if(extf->cmd->behavior & 4)
12903
strcat(line, "if_block_reduction:");
12904
sprintf(line + strlen(line), "used=%.f ", (double) extf->cmd->refcount);
12905
if(strlen(line) > maxl)
12907
Text_shellsafe(extf->cmd->path, line, 1);
12908
if(strlen(line) > maxl)
12910
for(i= 1; i < extf->cmd->argc; i++) {
12912
Text_shellsafe(extf->cmd->argv[i], line, 1);
12913
if(strlen(line) > maxl)
12916
if(i < extf->cmd->argc)
12918
strcat(line, " --\n");
12919
Xorriso_status_result(xorriso, filter, fp, flag&2);
12921
if(xorriso->filter_list_closed) {
12922
strcpy(line, "-close_filter_list\n");
12923
Xorriso_status_result(xorriso, filter, fp, flag&2);
12929
int Xorriso_stream_type(struct XorrisO *xorriso, IsoNode *node,
12930
IsoStream *stream, char type_text[], int flag)
12935
strncpy(text, stream->class->type, 4);
12937
if(strcmp(text, "fsrc") == 0) {
12938
ret= Xorriso__file_start_lba(node, &lba, 0);
12939
if(ret > 0 && lba > 0)
12940
strcpy(type_text, "image");
12942
strcpy(type_text, "disk");
12943
} else if(strcmp(text, "ziso") == 0) {
12944
strcpy(type_text, "--zisofs");
12945
} else if(strcmp(text, "osiz") == 0) {
12946
strcpy(type_text, "--zisofs-decode");
12947
} else if(strcmp(text, "gzip") == 0) {
12948
strcpy(type_text, "--gzip");
12949
} else if(strcmp(text, "pizg") == 0) {
12950
strcpy(type_text, "--gunzip");
12951
} else if(strcmp(text, "cout") == 0 || strcmp(text, "boot") == 0 ||
12952
strcmp(text, "user") == 0 || strcmp(text, "extf") == 0) {
12953
strcpy(type_text, text);
12955
Text_shellsafe(text, type_text, 0);
12960
int Xorriso_show_stream(struct XorrisO *xorriso, void *in_node,
12961
char *path, int flag)
12966
IsoStream *stream= NULL, *input_stream;
12967
IsoExternalFilterCommand *cmd;
12968
char type_text[16], *source_path= NULL;
12970
node= (IsoNode *) in_node;
12972
ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
12976
if(!LIBISO_ISREG(node))
12978
file= (IsoFile *) node;
12979
input_stream= iso_file_get_stream(file);
12980
Text_shellsafe(path, xorriso->result_line, 0);
12982
stream= input_stream;
12983
input_stream= iso_stream_get_input_stream(stream, 0);
12984
if(input_stream == NULL)
12986
strcat(xorriso->result_line, " < ");
12987
Xorriso_stream_type(xorriso, node, stream, type_text, 0);
12988
strcat(xorriso->result_line, type_text);
12989
ret= iso_stream_get_external_filter(stream, &cmd, 0);
12991
Xorriso_process_msg_queues(xorriso,0);
12992
Xorriso_report_iso_error(xorriso, "", ret,
12993
"Error when inquiring filter command of node", 0, "FAILURE", 1);
12997
strcat(xorriso->result_line, ":");
12998
Text_shellsafe(cmd->name, xorriso->result_line, 1);
13000
if(strlen(xorriso->result_line) > SfileadrL) {
13001
Xorriso_result(xorriso, 0);
13002
xorriso->result_line[0]= 0;
13005
strcat(xorriso->result_line, " < ");
13006
Xorriso_stream_type(xorriso, node, stream, type_text, 0);
13007
strcat(xorriso->result_line, type_text);
13009
source_path= iso_stream_get_source_path(stream, 0);
13010
if(source_path != NULL) {
13011
strcat(xorriso->result_line, ":");
13012
Text_shellsafe(source_path, xorriso->result_line, 1);
13015
strcat(xorriso->result_line, "\n");
13016
Xorriso_result(xorriso, 0);
13019
if(source_path != NULL)
13025
int Xorriso_set_zisofs_params(struct XorrisO *xorriso, int flag)
13028
struct iso_zisofs_ctrl ctrl;
13031
ctrl.compression_level= xorriso->zlib_level;
13032
if(xorriso->zisofs_block_size == (1 << 16))
13033
ctrl.block_size_log2= 16;
13034
else if(xorriso->zisofs_block_size == (1 << 17))
13035
ctrl.block_size_log2= 17;
13037
ctrl.block_size_log2= 15;
13038
ret= iso_zisofs_set_params(&ctrl, 0);
13039
Xorriso_process_msg_queues(xorriso,0);
13041
Xorriso_report_iso_error(xorriso, "", ret,
13042
"Error when setting zisofs parameters", 0, "FAILURE", 1);
13049
int Xorriso_status_zisofs(struct XorrisO *xorriso, char *filter, FILE *fp,
13052
bit0= do only report non-default settings
13053
bit1= do only report to fp
13056
off_t ziso_count= 0, osiz_count= 0;
13057
off_t gzip_count= 0, gunzip_count= 0;
13059
iso_zisofs_get_refcounts(&ziso_count, &osiz_count, 0);
13060
iso_gzip_get_refcounts(&gzip_count, &gunzip_count, 0);
13061
if((flag & 1) && xorriso->zlib_level == xorriso->zlib_level_default &&
13062
xorriso->zisofs_block_size == xorriso->zisofs_block_size_default &&
13063
xorriso->zisofs_by_magic == 0 &&
13064
ziso_count == 0 && osiz_count == 0 &&
13065
gzip_count == 0 && gunzip_count == 0) {
13071
sprintf(xorriso->result_line,
13072
"-zisofs level=%d:block_size=%dk:by_magic=%s:ziso_used=%.f:osiz_used=%.f",
13073
xorriso->zlib_level, xorriso->zisofs_block_size / 1024,
13074
xorriso->zisofs_by_magic ? "on" : "off",
13075
(double) ziso_count, (double) osiz_count);
13076
sprintf(xorriso->result_line + strlen(xorriso->result_line),
13077
":gzip_used=%.f:gunzip_used=%.f\n",
13078
(double) gzip_count, (double) gunzip_count);
13079
Xorriso_status_result(xorriso, filter, fp, flag&2);
13084
int Xorriso_all_node_array(struct XorrisO *xorriso, int addon_nodes, int flag)
13087
struct FindjoB *job= NULL;
13088
struct stat dir_stbuf;
13090
ret= Findjob_new(&job, "/", 0);
13092
Xorriso_no_findjob(xorriso, "xorriso", 0);
13093
{ret= -1; goto ex;}
13095
Findjob_set_action_target(job, 30, NULL, 0);
13096
Xorriso_destroy_node_array(xorriso, 0);
13097
ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, NULL, "/",
13101
ret= Xorriso_new_node_array(xorriso, xorriso->temp_mem_limit, addon_nodes, 0);
13104
Findjob_set_action_target(job, 31, NULL, 0);
13105
ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, NULL, "/",
13111
Findjob_destroy(&job, 0);
13116
int Xorriso_remake_hln_array(struct XorrisO *xorriso, int flag)
13118
int ret, addon_nodes= 0, i, old_count, old_pt, new_pt;
13119
IsoNode **old_nodes;
13120
char **old_targets;
13122
/* Count hln_targets of which the node has been deleted meanwhile */
13123
for(i= 0; i < xorriso->hln_count; i++) {
13124
if(xorriso->hln_targets[i] == NULL)
13126
if(Xorriso_node_is_valid(xorriso, xorriso->hln_array[i], 0))
13130
ret= Xorriso_all_node_array(xorriso, addon_nodes, 0);
13133
if(addon_nodes > 0) {
13134
/* Transfer delete nodes with hln_target to node array */
13135
for(i= 0; i < xorriso->hln_count; i++) {
13136
if(xorriso->hln_targets[i] == NULL)
13138
if(Xorriso_node_is_valid(xorriso, xorriso->hln_array[i], 0))
13140
if(xorriso->node_counter < xorriso->node_array_size) {
13141
xorriso->node_array[xorriso->node_counter++]= xorriso->hln_array[i];
13142
iso_node_ref(xorriso->node_array[xorriso->node_counter - 1]);
13147
Xorriso_sort_node_array(xorriso, 0);
13148
old_nodes= (IsoNode **) xorriso->hln_array;
13149
old_targets= (char **) xorriso->hln_targets;
13150
old_count= xorriso->hln_count;
13151
xorriso->hln_array= 0;
13152
xorriso->hln_targets= NULL;
13154
/* Transfer node_array to di_array without unrefering nodes */
13155
xorriso->hln_count= xorriso->node_counter;
13156
xorriso->hln_array= xorriso->node_array;
13157
xorriso->node_counter= 0;
13158
xorriso->node_array_size= 0;
13159
xorriso->node_array= NULL;
13161
/* Allocate hln_targets */
13162
ret= Xorriso_new_hln_array(xorriso, xorriso->temp_mem_limit, 1);
13165
xorriso->node_targets_availmem= xorriso->temp_mem_limit;
13166
if(old_targets != NULL) {
13167
/* Transfer targets from old target array */;
13169
while(new_pt < xorriso->hln_count && old_pt < old_count) {
13170
ret= Xorriso__hln_cmp(xorriso->hln_array[new_pt], old_nodes[old_pt]);
13173
} else if(ret > 0) {
13176
xorriso->hln_targets[new_pt]= old_targets[old_pt];
13177
if(old_targets[old_pt] != NULL)
13178
xorriso->temp_mem_limit-= strlen(old_targets[old_pt]) + 1;
13179
old_targets[old_pt]= NULL;
13184
for(old_pt= 0; old_pt < old_count; old_pt++)
13185
if(old_targets[old_pt] != NULL) /* (should not happen) */
13186
free(old_targets[old_pt]);
13187
free((char *) old_targets);
13189
if(old_nodes != NULL) {
13190
for(old_pt= 0; old_pt < old_count; old_pt++)
13191
if(old_nodes[old_pt] != NULL)
13192
iso_node_unref(old_nodes[old_pt]);
13193
free((char *) old_nodes);
13195
xorriso->hln_change_pending= 0;
13202
/* @param flag bit0= overwrite existing hln_array (else return 2)
13204
int Xorriso_make_hln_array(struct XorrisO *xorriso, int flag)
13208
if(xorriso->hln_array != NULL && !(flag & 1)) {
13209
/* If no fresh image manipulations occured: keep old array */
13210
if(!xorriso->hln_change_pending)
13212
ret= Xorriso_remake_hln_array(xorriso, 0);
13215
Xorriso_destroy_hln_array(xorriso, 0);
13217
ret= Xorriso_all_node_array(xorriso, 0, 0);
13220
Xorriso_sort_node_array(xorriso, 0);
13222
/* Transfer node_array to di_array without unrefering nodes */
13223
xorriso->hln_count= xorriso->node_counter;
13224
xorriso->hln_array= xorriso->node_array;
13225
xorriso->node_counter= 0;
13226
xorriso->node_array_size= 0;
13227
xorriso->node_array= NULL;
13229
/* Allocate hln_targets */
13230
ret= Xorriso_new_hln_array(xorriso, xorriso->temp_mem_limit, 1);
13232
Xorriso_destroy_hln_array(xorriso, 0);
13235
xorriso->node_targets_availmem= xorriso->temp_mem_limit;
13236
xorriso->hln_change_pending= 0;
13243
/* @param flag bit0= overwrite existing di_array (else return 2)
13244
bit1= make di_array despite xorriso->ino_behavior bit 3
13246
int Xorriso_make_di_array(struct XorrisO *xorriso, int flag)
13252
unsigned long old_gdic;
13253
old_gdic= Xorriso_get_di_counteR;
13256
if((xorriso->ino_behavior & 8 ) && !(flag & 2))
13258
if(xorriso->di_array != NULL && !(flag & 1))
13260
Xorriso_finish_hl_update(xorriso, 0);
13262
ret= Xorriso_all_node_array(xorriso, 0, 0);
13265
bytes= xorriso->node_array_size / 8 + 1;
13266
xorriso->di_do_widen= calloc(bytes, 1);
13267
if(xorriso->di_do_widen == NULL) {
13268
Xorriso_no_malloc_memory(xorriso, NULL, 0);
13272
/* Transfer node_array to di_array without unrefering nodes */
13273
xorriso->di_count= xorriso->node_counter;
13274
xorriso->di_array= xorriso->node_array;
13275
xorriso->node_counter= 0;
13276
xorriso->node_array_size= 0;
13277
xorriso->node_array= NULL;
13279
Xorriso__sort_di((void *) xorriso->di_array, xorriso->di_count, 0);
13286
fprintf(stderr, "xorriso_DEBUG: sort_count= %lu\n",
13287
Xorriso_get_di_counteR - old_gdic);
13295
@param flag bit0= iso_rr_path is freshly added and up to date
13296
bit2= -follow: this is not a command parameter
13297
@return -1= severe error
13298
0= not applicable for hard links
13299
1= go on with processing
13300
2= iso_rr_path is fully updated
13302
int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result,
13303
char *disk_path, char *iso_rr_path, int flag)
13305
int ret, hret, idx, low, high, i, do_overwrite= 0, did_fake_di= 0;
13306
int follow_links, old_idx= -1;
13312
if(xorriso->di_array == NULL)
13314
follow_links= xorriso->do_follow_links ||
13315
(xorriso->do_follow_param && !(flag & 4));
13316
ret= Xorriso_node_from_path(xorriso, NULL, iso_rr_path, &node, 0);
13319
if(LIBISO_ISDIR(node))
13322
/* Handle eventual hardlink split : */
13323
/* This is achieved by setting the content change bit. Reason:
13324
The node needs to be removed from di_array because its di is
13325
not matching its array index any more. So it becomes invisible for
13326
the join check of eventual later hardlink siblings. Therefore
13327
it must be updated now, even if it has currently no siblings
13328
which it leaves or which it joins.
13333
Xorriso__get_di(node, &old_dev, &old_ino, 0);
13334
ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count,
13335
Xorriso__di_cmp, node, &idx, 0);
13341
/* Handle eventual hardlink joining : */
13344
ret= stat(disk_path, &stbuf);
13346
ret= lstat(disk_path, &stbuf);
13350
/* Are there new dev-ino-siblings in the image ? */
13351
/* Fake isofs.di */
13353
ret= Xorriso_record_dev_inode(xorriso, disk_path, stbuf.st_dev,
13354
stbuf.st_ino, node, iso_rr_path, 1);
13356
{ret= -1; goto ex;}
13358
/* temporarily remove node from di_array so it does not disturb
13359
search by its fake di info */;
13361
xorriso->di_array[old_idx]= NULL;
13363
ret= Xorriso_search_di_range(xorriso, node, &idx, &low, &high, 1);
13365
/* Revoke fake of isofs.di */
13366
hret= Xorriso_record_dev_inode(xorriso, disk_path, old_dev, old_ino,
13367
node, iso_rr_path, 1);
13369
{ret= -1; goto ex;}
13371
xorriso->di_array[old_idx]= node;
13379
#ifdef Xorriso_hardlink_update_debuG
13381
if(low < high || idx < 0) {
13383
"xorriso_DEBUG: old_idx= %d , low= %d , high= %d , iso= '%s' , disk='%s'\n",
13384
old_idx, low, high, iso_rr_path, disk_path);
13386
"xorriso_DEBUG: old_dev= %lu , old_ino= %lu , dev= %lu , ino= %lu\n",
13387
(unsigned long) old_dev, (unsigned long) old_ino,
13388
(unsigned long) stbuf.st_dev, (unsigned long) stbuf.st_ino);
13390
if(idx >= 0 && idx != old_idx)
13391
fprintf(stderr, "xorriso_DEBUG: idx= %d , old_idx = %d\n", idx, old_idx);
13393
#endif /* Xorriso_hardlink_update_debuG */
13395
/* Overwrite all valid siblings : */
13396
for(i= low; i <= high; i++) {
13397
if(i == idx || xorriso->di_array[i] == NULL)
13400
#ifdef Xorriso_hardlink_update_debuG
13406
Xorriso__get_di(xorriso->di_array[i], &dev, &ino, 0);
13407
fprintf(stderr, "xorriso_DEBUG: iso_sibling= '%s' , dev= %lu , ino= %lu\n",
13408
node_path, (unsigned long) dev, (unsigned long) ino);
13410
#endif /* Xorriso_hardlink_update_debuG */
13412
xorriso->di_do_widen[i / 8]|= 1 << (i % 8);
13418
*compare_result|= (1<<15);
13419
if(old_idx >= 0 && (*compare_result & (3 << 21))) {
13420
/* The old di info is obsolete */
13421
if(xorriso->di_array[old_idx] != NULL)
13422
iso_node_unref(xorriso->di_array[old_idx]);
13423
xorriso->di_array[old_idx]= NULL;
13429
/* @param flag bit0= do not destroy di_array
13431
int Xorriso_finish_hl_update(struct XorrisO *xorriso, int flag)
13435
struct Xorriso_lsT *disk_lst, *iso_lst;
13437
if(xorriso->di_array == NULL)
13439
disk_lst= xorriso->di_disk_paths;
13440
iso_lst= xorriso->di_iso_paths;
13441
while(disk_lst != NULL && iso_lst != NULL) {
13442
argv[0]= Xorriso_lst_get_text(iso_lst, 0);
13444
argv[2]= "widen_hardlinks";
13445
argv[3]= Xorriso_lst_get_text(disk_lst, 0);
13447
ret= Xorriso_option_find(xorriso, 4, argv, &zero, 0); /* -findi */
13450
disk_lst= Xorriso_lst_get_next(disk_lst, 0);
13451
iso_lst= Xorriso_lst_get_next(iso_lst, 0);
13456
Xorriso_destroy_di_array(xorriso, 0);
13462
@param flag bit0= do not report to result but only retrieve md5 text
13463
@return 1= ok, 0= no md5 available, <0= other error
13465
int Xorriso_get_md5(struct XorrisO *xorriso, void *in_node, char *path,
13466
char md5[16], int flag)
13473
ret= Xorriso_get_volume(xorriso, &image, 0);
13476
node= (IsoNode *) in_node;
13478
ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
13482
if(!LIBISO_ISREG(node))
13484
ret= iso_file_get_md5(image, (IsoFile *) node, md5, 0);
13485
Xorriso_process_msg_queues(xorriso,0);
13491
wpt= xorriso->result_line;
13492
for(i= 0; i < 16; i++) {
13493
sprintf(wpt, "%2.2x", ((unsigned char *) md5)[i]);
13498
Xorriso_getfname(xorriso, path, 1 | 2);
13505
int Xorriso_make_md5(struct XorrisO *xorriso, void *in_node, char *path,
13512
node= (IsoNode *) in_node;
13514
ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
13518
if(!LIBISO_ISREG(node))
13520
ret= iso_file_make_md5((IsoFile *) node, 0);
13521
size= iso_file_get_size((IsoFile *) node);
13522
xorriso->pacifier_count+= size;
13523
xorriso->pacifier_byte_count+= size;
13524
Xorriso_pacifier_callback(xorriso, "content bytes read",
13525
xorriso->pacifier_count, 0, "", 0);
13526
Xorriso_process_msg_queues(xorriso, 0);
13528
Xorriso_report_iso_error(xorriso, "", ret,
13529
"Error when computing MD5", 0, "FAILURE", 1);
13532
Xorriso_set_change_pending(xorriso, 1);
13537
/* @param node Opaque handle to IsoNode which is to be inquired instead of path if it is not NULL.
13538
@param path is used as address if node is NULL.
13539
@param flag bit0= do not report to result but only indicate outcome
13541
bit1= silently ignore nodes without MD5
13542
bit2= do not only report mismatches but also matches
13543
@return 3= not a data file
13544
2= no MD5 attached to node
13545
1= ok, MD5 compared and matching
13546
0= not ok, MD5 mismatch
13549
int Xorriso_check_md5(struct XorrisO *xorriso, void *in_node, char *path,
13552
int ret, wanted, rret;
13556
char node_md5[16], data_md5[16], buffer[64 * 1024];
13557
void *stream= NULL, *ctx= NULL;
13560
node= (IsoNode *) in_node;
13562
ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
13564
{ret= -1; goto ex;}
13566
if(!LIBISO_ISREG(node)) {
13567
strcpy(xorriso->info_text, "-check_md5: Not a data file: ");
13568
Text_shellsafe(path, xorriso->info_text, 1);
13570
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
13573
file= (IsoFile *) node;
13576
ret= Xorriso_get_volume(xorriso, &image, 0);
13578
{ret= -1; goto ex;}
13579
ret= iso_file_get_md5(image, file, node_md5, 0);
13580
Xorriso_process_msg_queues(xorriso,0);
13582
{ret= -1; goto ex;}
13584
strcpy(xorriso->info_text, "-check_md5: No MD5 recorded with file: ");
13585
Text_shellsafe(path, xorriso->info_text, 1);
13587
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
13591
/* Read file and compute MD5 */;
13592
ret= Xorriso_iso_file_open(xorriso, path, (void *) node, &stream, 1 | 2);
13594
{ret= -1; goto ex;}
13595
ret= iso_md5_start(&ctx);
13598
todo= iso_stream_get_size(stream);
13600
if(todo < sizeof(buffer))
13603
wanted= sizeof(buffer);
13604
rret = Xorriso_iso_file_read(xorriso, stream, buffer, wanted, 0);
13606
{ret= -1; goto ex;}
13608
ret = iso_md5_compute(ctx, buffer, rret);
13611
xorriso->pacifier_count+= rret;
13612
xorriso->pacifier_byte_count+= rret;
13613
Xorriso_pacifier_callback(xorriso, "content bytes read",
13614
xorriso->pacifier_count, 0, "", 0);
13616
ret= iso_md5_end(&ctx, data_md5);
13620
/* Report outcome */
13621
Xorriso_process_msg_queues(xorriso,0);
13622
if(! iso_md5_match(node_md5, data_md5)) {
13623
sprintf(xorriso->result_line, "MD5 MISMATCH: ");
13624
Text_shellsafe(path, xorriso->result_line, 1);
13625
strcat(xorriso->result_line, "\n");
13627
Xorriso_result(xorriso,0);
13630
sprintf(xorriso->result_line, "md5 match : ");
13631
Text_shellsafe(path, xorriso->result_line, 1);
13632
strcat(xorriso->result_line, "\n");
13634
Xorriso_result(xorriso,0);
13639
Xorriso_process_msg_queues(xorriso,0);
13640
Xorriso_iso_file_close(xorriso, &stream, 0);
13642
iso_md5_end(&ctx, data_md5);
13644
sprintf(xorriso->result_line, "NOT READABLE: ");
13645
Text_shellsafe(path, xorriso->result_line, 1);
13646
strcat(xorriso->result_line, "\n");
13648
Xorriso_result(xorriso,0);
13654
int Xorriso_check_md5_range(struct XorrisO *xorriso, off_t start_lba,
13655
off_t end_lba, char md5[16], int flag)
13658
struct burn_drive_info *dinfo= NULL;
13659
struct burn_drive *drive= NULL;
13660
off_t pos, data_count, to_read;
13661
char data[64 * 1024], data_md5[16];
13664
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
13665
"on attempt to check session MD5 checksum", 0);
13668
ret= iso_md5_start(&ctx);
13670
Xorriso_no_malloc_memory(xorriso, NULL, 0);
13673
for(pos= start_lba; pos < end_lba; pos+= 32) {
13675
if(pos + to_read > end_lba)
13676
to_read= end_lba - pos;
13677
ret= burn_read_data(drive, pos * (off_t) 2048, data,
13678
to_read * (off_t) 2048, &data_count, 0);
13681
iso_md5_compute(ctx, data, (int) data_count);
13682
xorriso->pacifier_count+= data_count;
13683
xorriso->pacifier_byte_count+= data_count;
13684
Xorriso_pacifier_callback(xorriso, "content bytes read",
13685
xorriso->pacifier_count, 0, "", 0);
13687
iso_md5_end(&ctx, data_md5);
13689
if(! iso_md5_match(md5, data_md5))
13692
Xorriso_process_msg_queues(xorriso,0);
13694
iso_md5_end(&ctx, data_md5);
13699
int Xorriso_check_session_md5(struct XorrisO *xorriso, char *severity,
13704
uint32_t start_lba, end_lba;
13705
char md5[16], md5_text[33];
13707
ret= Xorriso_get_volume(xorriso, &image, 0);
13710
ret= iso_image_get_session_md5(image, &start_lba, &end_lba, md5, 0);
13711
Xorriso_process_msg_queues(xorriso,0);
13715
sprintf(xorriso->info_text,
13716
"No session MD5 is recorded with the loaded session");
13717
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
13721
sprintf(xorriso->info_text, "Checking loaded session by its recorded MD5.\n");
13722
Xorriso_info(xorriso, 0);
13723
for(i= 0; i < 16; i++)
13724
sprintf(md5_text + 2 * i, "%2.2x", ((unsigned char *) md5)[i]);
13725
sprintf(xorriso->result_line,
13726
"Session MD5 %s , LBA %.f , %.f blocks\n",
13727
md5_text, (double) start_lba, (double) end_lba - start_lba);
13728
Xorriso_result(xorriso,0);
13729
ret= Xorriso_check_md5_range(xorriso, (off_t) start_lba, (off_t) end_lba,
13735
int Xorriso_image_has_md5(struct XorrisO *xorriso, int flag)
13739
uint32_t start_lba, end_lba;
13742
ret= Xorriso_get_volume(xorriso, &image, 0);
13745
ret= iso_image_get_session_md5(image, &start_lba, &end_lba, md5, 0);
13746
Xorriso_process_msg_queues(xorriso,0);
13753
int Xorriso_md5_start(struct XorrisO *xorriso, void **ctx, int flag)
13757
ret= iso_md5_start(ctx);
13760
Xorriso_no_malloc_memory(xorriso, NULL, 0);
13765
int Xorriso_md5_compute(struct XorrisO *xorriso, void *ctx,
13766
char *data, int datalen, int flag)
13768
iso_md5_compute(ctx, data, datalen);
13773
int Xorriso_md5_end(struct XorrisO *xorriso, void **ctx, char md5[16],
13778
ret= iso_md5_end(ctx, md5);
13779
Xorriso_process_msg_queues(xorriso,0);
13786
/* @param flag bit0=input drive
13788
bit2= wake up rather than calm down
13790
int Xorriso_drive_snooze(struct XorrisO *xorriso, int flag)
13792
int in_is_out_too, ret;
13793
struct burn_drive_info *dinfo;
13794
struct burn_drive *drive;
13796
in_is_out_too= (xorriso->in_drive_handle == xorriso->out_drive_handle);
13797
if((flag & 1) && xorriso->in_drive_handle != NULL) {
13798
Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
13799
"on attempt to calm drive", 0);
13800
burn_drive_snooze(drive, !!(flag & 4));
13804
if((flag&2) && xorriso->out_drive_handle!=NULL) {
13805
Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
13806
"on attempt to calm drive", 2);
13807
burn_drive_snooze(drive, !!(flag & 4));
13811
Xorriso_process_msg_queues(xorriso,0);
13816
int Xorriso_pvd_info(struct XorrisO *xorriso, int flag)
13818
int ret, msc1= -1, msc2, i;
13820
struct burn_drive_info *dinfo;
13821
struct burn_drive *drive;
13822
char *msg, block_head[8];
13825
msg= xorriso->result_line;
13826
ret= Xorriso_get_volume(xorriso, &image, 0);
13829
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, "", 16);
13831
ret= Xorriso_msinfo(xorriso, &msc1, &msc2, 1 | 4);
13834
Xorriso_toc(xorriso, 128);
13836
for(i = msc1 + 16; i < msc1 + 32; i++) {
13837
ret= burn_read_data(drive, (off_t) i * (off_t) 2048, block_head,
13838
(off_t) sizeof(block_head), &head_count, 2);
13843
if(block_head[0] == 1 && strncmp(block_head + 1, "CD001", 5) == 0)
13846
if(i < msc1 + 32) {
13847
sprintf(msg, "PVD address : %ds\n", i);
13848
Xorriso_result(xorriso,0);
13852
sprintf(msg, "Volume Id : %s\n", un0(iso_image_get_volume_id(image)));
13853
Xorriso_result(xorriso,0);
13854
sprintf(msg, "Volume Set Id: %s\n", xorriso->volset_id);
13855
Xorriso_result(xorriso,0);
13856
sprintf(msg, "Publisher Id : %s\n", xorriso->publisher);
13857
Xorriso_result(xorriso,0);
13858
sprintf(msg, "Preparer Id : %s\n",
13859
un0(iso_image_get_data_preparer_id(image)));
13860
Xorriso_result(xorriso,0);
13861
sprintf(msg, "App Id : %s\n", xorriso->application_id);
13862
Xorriso_result(xorriso,0);
13863
sprintf(msg, "System Id : %s\n", xorriso->system_id);
13864
Xorriso_result(xorriso,0);
13865
sprintf(msg, "Copyright Id : %s\n",
13866
un0(iso_image_get_copyright_file_id(image)));
13867
Xorriso_result(xorriso,0);
13868
sprintf(msg, "Abstract Id : %s\n",
13869
un0(iso_image_get_abstract_file_id(image)));
13870
Xorriso_result(xorriso,0);
13871
sprintf(msg, "Biblio Id : %s\n", un0(iso_image_get_biblio_file_id(image)));
13872
Xorriso_result(xorriso,0);
13877
/* @param flag bit0= do not set hln_change_pending */
13878
int Xorriso_set_change_pending(struct XorrisO *xorriso, int flag)
13883
ret= Xorriso_get_volume(xorriso, &image, 1);
13886
xorriso->volset_change_pending= 1;
13888
xorriso->hln_change_pending= 1;
13893
/* @param flag bit0= enable SCSI command logging to stderr */
13894
int Xorriso_scsi_log(struct XorrisO *xorriso, int flag)
13897
burn_set_scsi_logging(0);
13899
burn_set_scsi_logging(2|4);