~ubuntu-branches/ubuntu/precise/libisoburn/precise

« back to all changes in this revision

Viewing changes to xorriso/xorrisoburn.c

  • Committer: Bazaar Package Importer
  • Author(s): George Danchev
  • Date: 2011-05-26 16:21:32 UTC
  • mfrom: (9.1.12 sid)
  • Revision ID: james.westby@ubuntu.com-20110526162132-9lzoagfaggnera53
Tags: 1.0.8.pl00-4
* [MA] Improve package descriptions and README.Debian.
* [MA] Migrate to format "3.0 (quilt)" and compatibility 8.
  + debian/control: Drop build-dep on 'cdbs'. Require debhelper (>= 8).
  + debian/rules: Reformulate using 'dh'.
  + debian/libisoburn{1,-dev,-doc}.docs: New files.
  + debian/xorriso.docs: Addition of upstream documents.
* [GD] Make sure doxygen documentaton (doc package) is not built
       when dpkg-buildpackage -B is called (i.e. autobuilders).
* [GD] Move doxygen, graphviz to Build-Depends-Indep.
* [GD] Add missing copyrights for debian packaging.
* [GD] Standards-Version: 3.9.2 (no changes needed).
* [GD] More package description and README.Debian improvements;
       thanks to Tony Mancill <tmancill@debian.org>.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
 
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.
6
 
 
7
 
   Copyright 2007-2010 Thomas Schmitt, <scdbackup@gmx.net>
8
 
 
9
 
   Provided under GPL version 2 or later.
10
 
*/
11
 
 
12
 
#include <ctype.h>
13
 
#include <sys/types.h>
14
 
#include <unistd.h>
15
 
#include <stdlib.h>
16
 
#include <stdio.h>
17
 
#include <errno.h>
18
 
#include <string.h>
19
 
#include <sys/stat.h>
20
 
#include <time.h>
21
 
#include <fcntl.h>
22
 
#include <utime.h>
23
 
#include <sys/wait.h>
24
 
#include <pwd.h>
25
 
#include <grp.h>
26
 
 
27
 
/* for -charset */
28
 
#include <iconv.h>
29
 
#include <langinfo.h>
30
 
 
31
 
 
32
 
/* ------------------------------------------------------------------------ */
33
 
 
34
 
#ifndef Xorriso_standalonE
35
 
 
36
 
/* The library which does the ISO 9660 / RockRidge manipulations */
37
 
#include <libisofs/libisofs.h>
38
 
 
39
 
/* The library which does MMC optical drive operations */
40
 
#include <libburn/libburn.h>
41
 
 
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>
45
 
 
46
 
/* The official xorriso options API. "No shortcuts" */
47
 
#include "xorriso.h"
48
 
 
49
 
/* The inner description of XorrisO */
50
 
#include "xorriso_private.h"
51
 
 
52
 
/* The inner isofs- and burn-library interface */
53
 
#include "xorrisoburn.h"
54
 
 
55
 
#else /* ! Xorriso_standalonE */
56
 
 
57
 
#include "../libisofs/libisofs.h"
58
 
#include "../libburn/libburn.h"
59
 
#include "../libisoburn/libisoburn.h"
60
 
#include "xorriso.h"
61
 
#include "xorriso_private.h"
62
 
#include "xorrisoburn.h"
63
 
 
64
 
#endif /* Xorriso_standalonE */
65
 
 
66
 
 
67
 
/* Some private in advance declarations */
68
 
int  Xorriso_pacifier_loop(struct XorrisO *xorriso, struct burn_drive *drive,
69
 
                          int flag);
70
 
 
71
 
int Xorriso__read_pacifier(IsoImage *image, IsoFileSource *filesource);
72
 
 
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);
78
 
 
79
 
int Xorriso_findi_iter(struct XorrisO *xorriso, IsoDir *dir_node, off_t *mem,
80
 
                       IsoDirIter **iter,
81
 
                       IsoNode ***node_array, int *node_count, int *node_idx,
82
 
                       IsoNode **iterated_node, int flag);
83
 
 
84
 
int Xorriso__file_start_lba(IsoNode *node, int *lba, int flag);
85
 
 
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);
90
 
 
91
 
int Xorriso_path_from_node(struct XorrisO *xorriso, IsoNode *in_node,
92
 
                           char path[SfileadrL], int flag);
93
 
 
94
 
int Xorriso_node_from_path(struct XorrisO *xorriso, IsoImage *volume,
95
 
                           char *path, IsoNode **node, int flag);
96
 
 
97
 
int Xorriso_path_from_lba(struct XorrisO *xorriso, IsoNode *node, int lba,
98
 
                          char path[SfileadrL], int flag);
99
 
 
100
 
int Xorriso__node_lba_cmp(const void *node1, const void *node2);
101
 
 
102
 
int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node,
103
 
                            int *node_idx, int *min_hl, int *max_hl, int flag);
104
 
 
105
 
 
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)
118
 
 
119
 
 
120
 
/* CD specs say one shall not write tracks < 600 kiB */
121
 
#define Xorriso_cd_min_track_sizE 300
122
 
 
123
 
 
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)
130
 
 
131
 
#ifdef NIX
132
 
/* <<< */
133
 
unsigned long Xorriso_get_di_counteR= 0;
134
 
#endif /* NIX */
135
 
 
136
 
 
137
 
/* ------------------------------------------------------------------------ */
138
 
 
139
 
 
140
 
static const char *un0(const char *text)
141
 
{
142
 
 if(text == NULL)
143
 
   return("");
144
 
 return(text);
145
 
}
146
 
 
147
 
 
148
 
int Xorriso_abort(struct XorrisO *xorriso, int flag)
149
 
{
150
 
 int ret;
151
 
 
152
 
 ret= burn_abort(4440, burn_abort_pacifier, "xorriso : ");
153
 
 if(ret<=0) {
154
 
   fprintf(stderr,
155
 
       "\nxorriso : ABORT : Cannot cancel burn session and release drive.\n");
156
 
   return(0);
157
 
 } 
158
 
 fprintf(stderr,
159
 
   "xorriso : ABORT : Drive is released and library is shut down now.\n");
160
 
 fprintf(stderr,
161
 
   "xorriso : ABORT : Program done. Even if you do not see a shell prompt.\n");
162
 
 fprintf(stderr, "\n");
163
 
 exit(1);
164
 
}
165
 
 
166
 
 
167
 
int Xorriso_destroy_node_array(struct XorrisO *xorriso, int flag)
168
 
{
169
 
 int i;
170
 
 
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);
175
 
 }
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);
180
 
 return(1);
181
 
}
182
 
 
183
 
 
184
 
/* @param flag bit0= do not destroy hln_array but only hln_targets
185
 
*/
186
 
int Xorriso_destroy_hln_array(struct XorrisO *xorriso, int flag)
187
 
{
188
 
 int i;
189
 
 
190
 
 
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;
197
 
 }
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;
204
 
 }
205
 
 xorriso->node_targets_availmem= 0;
206
 
 return(1);
207
 
}
208
 
 
209
 
 
210
 
int Xorriso_destroy_di_array(struct XorrisO *xorriso, int flag)
211
 
{
212
 
 int i;
213
 
 
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;
220
 
 }
221
 
 if(xorriso->di_do_widen != NULL) {
222
 
   free(xorriso->di_do_widen);
223
 
   xorriso->di_do_widen= NULL;
224
 
 }
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;
228
 
 
229
 
#ifdef NIX
230
 
 /* <<< */
231
 
 fprintf(stderr, "xorriso_DEBUG: get_di_count= %lu\n",
232
 
         Xorriso_get_di_counteR);
233
 
#endif /* NIX */
234
 
 
235
 
 return(1);
236
 
}
237
 
 
238
 
 
239
 
int Xorriso_new_node_array(struct XorrisO *xorriso, off_t mem_limit,
240
 
                           int addon_nodes, int flag)
241
 
{
242
 
 int i;
243
 
 
244
 
 if(xorriso->node_counter <= 0)
245
 
   return(1);
246
 
 
247
 
 xorriso->node_array= calloc(xorriso->node_counter + addon_nodes,
248
 
                             sizeof(IsoNode *));
249
 
 if(xorriso->node_array == NULL) {
250
 
   Xorriso_no_malloc_memory(xorriso, NULL, 0);
251
 
   return(-1);
252
 
 }
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;
257
 
 return(1);
258
 
}
259
 
 
260
 
 
261
 
/* @param flag bit0= do not allocate hln_array but only hln_targets
262
 
*/
263
 
int Xorriso_new_hln_array(struct XorrisO *xorriso, off_t mem_limit, int flag)
264
 
{
265
 
 int i;
266
 
 
267
 
 Xorriso_destroy_hln_array(xorriso, flag & 1);
268
 
 if(xorriso->hln_count <= 0)
269
 
   return(1);
270
 
 
271
 
 if(!(flag & 1)) {
272
 
   xorriso->hln_array= calloc(xorriso->hln_count, sizeof(char *));
273
 
   if(xorriso->hln_array == NULL) {
274
 
     Xorriso_no_malloc_memory(xorriso, NULL, 0);
275
 
     return(-1);
276
 
   }
277
 
   for(i= 0; i < xorriso->hln_count; i++)
278
 
     xorriso->hln_array[i]= NULL;
279
 
 }
280
 
 
281
 
 xorriso->hln_targets= calloc(xorriso->hln_count, sizeof(char *));
282
 
 if(xorriso->hln_targets == NULL) {
283
 
   if(!(flag & 1)) {
284
 
     free(xorriso->hln_array);
285
 
     xorriso->hln_array= NULL;
286
 
   }
287
 
   Xorriso_no_malloc_memory(xorriso, NULL, 0);
288
 
   return(-1);
289
 
 }
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;
297
 
 return(1);
298
 
}
299
 
 
300
 
 
301
 
int Xorriso__findi_sorted_ino_cmp(const void *p1, const void *p2)
302
 
{
303
 
 int ret;
304
 
 IsoNode *n1, *n2;
305
 
 
306
 
 n1= *((IsoNode **) p1);
307
 
 n2= *((IsoNode **) p2);
308
 
 
309
 
 ret= Xorriso__node_lba_cmp(&n1, &n2);
310
 
 if(ret)
311
 
   return (ret > 0 ? 1 : -1);
312
 
 ret= iso_node_cmp_ino(n1, n2, 0);
313
 
 return(ret);
314
 
}
315
 
 
316
 
 
317
 
/* Not suitable for qsort() but for cross-array comparisons.
318
 
   p1 and p2 are actually IsoNode *p1, IsoNode *p2
319
 
*/
320
 
int Xorriso__hln_cmp(const void *p1, const void *p2)
321
 
{
322
 
 int ret;
323
 
 
324
 
 ret= Xorriso__findi_sorted_ino_cmp(&p1, &p2);
325
 
 if(ret)
326
 
   return (ret > 0 ? 1 : -1);
327
 
 if(p1 != p2)
328
 
   return(p1 < p2 ? -1 : 1);
329
 
 return(0);
330
 
}
331
 
 
332
 
 
333
 
/* 
334
 
   p1 and p2 are actually IsoNode **p1, IsoNode **p2
335
 
*/
336
 
int Xorriso__findi_sorted_cmp(const void *p1, const void *p2)
337
 
{
338
 
 int ret;
339
 
 
340
 
 ret= Xorriso__findi_sorted_ino_cmp(p1, p2);
341
 
 if(ret)
342
 
   return (ret > 0 ? 1 : -1);
343
 
 if(p1 != p2)
344
 
   return(p1 < p2 ? -1 : 1);
345
 
 return(0);
346
 
}
347
 
 
348
 
 
349
 
int Xorriso_sort_node_array(struct XorrisO *xorriso, int flag)
350
 
{
351
 
 if(xorriso->node_counter <= 0)
352
 
   return(0);
353
 
 qsort(xorriso->node_array, xorriso->node_counter, sizeof(IsoNode *),
354
 
       Xorriso__findi_sorted_cmp);
355
 
 return(1);
356
 
}
357
 
 
358
 
 
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)
362
 
{
363
 
 int ret, l, r, p, pos;
364
 
 
365
 
 if(n == 0)
366
 
   return(0);
367
 
 l= 0;
368
 
 r= n + 1;
369
 
 while(1) {
370
 
   p= (r - l) / 2;
371
 
   if(p == 0)
372
 
 break;
373
 
   p+= l;
374
 
 
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.
377
 
    */
378
 
   for(pos= p - 1; pos < n; pos++)
379
 
     if(node_array[pos] != NULL)
380
 
   break;
381
 
   if(pos < n)
382
 
     ret= (*cmp)(&(node_array[pos]), &node);
383
 
   else
384
 
     ret= 1;
385
 
 
386
 
   if(ret < 0)
387
 
     l= p;
388
 
   else if(ret > 0)
389
 
     r= p;
390
 
   else {
391
 
     *idx= pos;
392
 
     return(1);
393
 
   }
394
 
 }
395
 
 return(0);
396
 
}
397
 
 
398
 
 
399
 
int Xorriso_search_in_hln_array(struct XorrisO *xorriso,
400
 
                                 void *node, int *idx, int flag)
401
 
{
402
 
 int ret;
403
 
 
404
 
 if(xorriso->hln_array == NULL || xorriso->hln_count <= 0)
405
 
   return(0);
406
 
 ret= Xorriso__search_node(xorriso->hln_array, xorriso->hln_count, 
407
 
                           Xorriso__findi_sorted_ino_cmp, node, idx, 0);
408
 
 return ret;
409
 
}
410
 
 
411
 
 
412
 
int Xorriso__get_di(IsoNode *node, dev_t *dev, ino_t *ino, int flag)
413
 
{
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];
417
 
 unsigned char *vpt;
418
 
 static char *name= "isofs.di";
419
 
 
420
 
#ifdef NIX
421
 
 /* <<< */
422
 
 Xorriso_get_di_counteR++;
423
 
#endif /* NIX */
424
 
 
425
 
 *dev= 0;
426
 
 *ino= 0;
427
 
 ret= iso_node_lookup_attr(node, name, &value_length, &value, 0);
428
 
 if(ret <= 0) {
429
 
   /* Drop any pending messages because there is no xorriso to take them */
430
 
   iso_obtain_msgs("NEVER", &error_code, &imgid, msg, severity);
431
 
   return(ret);
432
 
 }
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];
439
 
 free(value);
440
 
 return(1);
441
 
}
442
 
 
443
 
 
444
 
int Xorriso__di_ino_cmp(const void *p1, const void *p2)
445
 
{  
446
 
 int ret; 
447
 
 IsoNode *n1, *n2;
448
 
 dev_t d1, d2;
449
 
 ino_t i1, i2;
450
 
 
451
 
 n1= *((IsoNode **) p1);
452
 
 n2= *((IsoNode **) p2);
453
 
 
454
 
 ret= Xorriso__get_di(n1, &d1, &i1, 0);
455
 
 if(ret <= 0)
456
 
   {d1= 0; i1= 0;}
457
 
 ret= Xorriso__get_di(n2, &d2, &i2, 0);
458
 
 if(ret <= 0)
459
 
   {d2= 0; i2= 0;}
460
 
 
461
 
 if(d1 < d2)
462
 
   return(-1);
463
 
 if(d1 > d2)
464
 
   return(1);
465
 
 if(i1 < i2)
466
 
   return(-1);
467
 
 if(i1 > i2)
468
 
   return(1);
469
 
 if(d1 == 0 && i1 == 0 && n1 != n2)
470
 
   return(n1 < n2 ? -1 : 1);
471
 
 return(0);
472
 
473
 
 
474
 
 
475
 
int Xorriso__di_cmp(const void *p1, const void *p2)
476
 
{  
477
 
 int ret; 
478
 
 IsoNode *n1, *n2;
479
 
 
480
 
 ret= Xorriso__di_ino_cmp(p1, p2);
481
 
 if(ret)
482
 
   return(ret);
483
 
 n1= *((IsoNode **) p1);
484
 
 n2= *((IsoNode **) p2);
485
 
 if(n1 != n2)
486
 
   return(n1 < n2 ? -1 : 1);
487
 
 return(0);
488
 
489
 
 
490
 
 
491
 
int Xorriso__sort_di(void *node_array[], int count, int flag)
492
 
{
493
 
 if(count <= 0)
494
 
   return(0);
495
 
 qsort(node_array, count, sizeof(IsoNode *), Xorriso__di_cmp);
496
 
 return(1);
497
 
}
498
 
 
499
 
 
500
 
int Xorriso_invalidate_di_item(struct XorrisO *xorriso, IsoNode *node,
501
 
                               int flag)
502
 
{
503
 
 int ret, idx;
504
 
 
505
 
 if(xorriso->di_array == NULL)
506
 
   return(1);
507
 
 ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count,
508
 
                           Xorriso__di_cmp, node, &idx, 0);
509
 
 if(ret <= 0)
510
 
   return(ret == 0);
511
 
 if(xorriso->di_array[idx] != NULL)
512
 
   iso_node_unref(xorriso->di_array[idx]);
513
 
 xorriso->di_array[idx]= NULL;
514
 
 return(1);
515
 
}
516
 
 
517
 
 
518
 
/* @param flag bit0= return 1 even if matching nodes were found but node is
519
 
                     not among them
520
 
               bit1= use Xorriso__di_cmp() rather than Xorriso__di_ino_cmp()
521
 
*/
522
 
int Xorriso_search_di_range(struct XorrisO *xorriso, IsoNode *node,
523
 
                            int *idx, int *low, int *high, int flag)
524
 
{
525
 
 int ret, i, found;
526
 
 int (*cmp)(const void *p1, const void *p2)= Xorriso__di_ino_cmp;
527
 
 
528
 
 if(flag & 2)
529
 
   cmp= Xorriso__di_cmp;
530
 
 
531
 
 *high= *low= *idx= -1;                            
532
 
 ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count,
533
 
                           cmp, node, &found, 0);
534
 
 if(ret <= 0)
535
 
   return(0);
536
 
 *low= *high= found;
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)
540
 
 break;
541
 
     *high= i;
542
 
   }
543
 
 for(i= found - 1; i >= 0; i--)
544
 
   if(xorriso->di_array[i] != NULL) {
545
 
     if((*cmp)(&node, &(xorriso->di_array[i])) != 0)
546
 
 break;
547
 
     *low= i;
548
 
   }
549
 
 for(i= *low; i <= *high; i++)
550
 
   if(xorriso->di_array[i] == node) {
551
 
     *idx= i;
552
 
 break;
553
 
   }
554
 
 return(*idx >= 0 || (flag & 1));
555
 
}
556
 
 
557
 
 
558
 
/* ------------------------------------------------------------------------ */
559
 
 
560
 
/* @param flag bit0= asynchronous handling (else catch thread, wait, and exit)
561
 
*/
562
 
int Xorriso_set_signal_handling(struct XorrisO *xorriso, int flag)
563
 
{
564
 
 char *handler_prefix= NULL;
565
 
 
566
 
 if(Xorriso__get_signal_behavior(0) != 1)
567
 
   return(2);
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);
573
 
   return(-1);
574
 
 }
575
 
 sprintf(handler_prefix, "%s : ", xorriso->progname);
576
 
 burn_set_signal_handling(handler_prefix, NULL, (flag & 1) * 0x30);
577
 
 free(handler_prefix);
578
 
 return(1);
579
 
}
580
 
 
581
 
 
582
 
int Xorriso_startup_libraries(struct XorrisO *xorriso, int flag)
583
 
{
584
 
 int ret, major, minor, micro;
585
 
 char *queue_sev, *print_sev, reason[1024];
586
 
 struct iso_zisofs_ctrl zisofs_ctrl= {0, 6, 15};
587
 
 
588
 
 
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.
592
 
*/
593
 
 
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)
610
 
*/
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
614
 
 #endif
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
617
 
 #endif
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
620
 
 #endif
621
 
 
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;
626
 
#endif
627
 
 
628
 
/* End of ugly compile time test (scroll up for explanation) */
629
 
 
630
 
 reason[0]= 0;
631
 
 ret= isoburn_initialize(reason, 0);
632
 
 if(ret==0) {
633
 
   sprintf(xorriso->info_text, "Cannot initialize libraries");
634
 
   if(reason[0])
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);
638
 
   return(0);
639
 
 }
640
 
 ret= isoburn_is_compatible(isoburn_header_version_major,
641
 
                            isoburn_header_version_minor,
642
 
                            isoburn_header_version_micro, 0);
643
 
 if(ret<=0) {
644
 
   isoburn_version(&major, &minor, &micro);
645
 
   sprintf(xorriso->info_text,
646
 
          "libisoburn version too old: %d.%d.%d . Need at least: %d.%d.%d .\n",
647
 
          major, minor, micro,
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);
651
 
   return(-1);
652
 
 }
653
 
 
654
 
 xorriso->libs_are_started= 1;
655
 
 
656
 
 queue_sev= "ALL";
657
 
 if(xorriso->library_msg_direct_print) {
658
 
 
659
 
   /* >>> need option for controlling this in XorrisO.
660
 
          See also Xorriso_msgs_submit */;
661
 
 
662
 
   print_sev= xorriso->report_about_text;
663
 
 } else
664
 
   print_sev= "NEVER";
665
 
 
666
 
 iso_set_msgs_severities(queue_sev, print_sev, "libsofs : ");
667
 
 burn_msgs_set_severities(queue_sev, print_sev, "libburn : ");
668
 
 
669
 
 /* ??? >>> do we want united queues ? */
670
 
 /* burn_set_messenger(iso_get_messenger()); */
671
 
 
672
 
 isoburn_set_msgs_submit(Xorriso_msgs_submit_void, (void *) xorriso,
673
 
                         (3<<2) | 128 , 0);
674
 
 
675
 
 ret= Xorriso_set_signal_handling(xorriso, 0);
676
 
 if(ret <= 0)
677
 
   return(ret);
678
 
 
679
 
 ret = iso_zisofs_get_params(&zisofs_ctrl, 0);
680
 
 if (ret == 1) {
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;
685
 
 }
686
 
 Xorriso_process_msg_queues(xorriso,0);
687
 
 if(reason[0]) {
688
 
   sprintf(xorriso->info_text, "%s", reason);
689
 
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
690
 
 }
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);
694
 
 return(1);
695
 
}
696
 
 
697
 
 
698
 
/* @param flag bit0= global shutdown of libraries */
699
 
int Xorriso_detach_libraries(struct XorrisO *xorriso, int flag)
700
 
{
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);
708
 
 }
709
 
 if(flag&1) {
710
 
   if(xorriso->libs_are_started==0)
711
 
     return(0);
712
 
   isoburn_finish();
713
 
 }
714
 
 return(1);
715
 
}
716
 
 
717
 
 
718
 
/* @param flag
719
 
          bit0= if not MMC drive print NOTE and return 2  
720
 
          bit1= obtain outdrive, else indrive
721
 
          bit4= do not report failure
722
 
*/
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)
727
 
{
728
 
 int ret;
729
 
 
730
 
 if(flag&2)
731
 
   *dinfo= (struct burn_drive_info *) xorriso->out_drive_handle;
732
 
 else
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);
739
 
 }
740
 
 if(*dinfo==NULL)
741
 
   return(0);
742
 
 *drive= (*dinfo)[0].drive;
743
 
 if(flag & 1) {
744
 
   ret= burn_drive_get_drive_role(*drive);
745
 
   if(ret != 1) {
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);
749
 
     return(2);
750
 
   }
751
 
 }
752
 
 return((*drive)!=NULL);
753
 
}
754
 
 
755
 
 
756
 
int Xorriso__sev_to_text(int severity, char **severity_name,
757
 
                         int flag)
758
 
{
759
 
 int ret;
760
 
 
761
 
  ret= iso_sev_to_text(severity, severity_name);
762
 
  if(ret>0)
763
 
    return(ret);
764
 
  ret= burn_sev_to_text(severity, severity_name, 0);
765
 
  if(ret>0)
766
 
    return(ret);
767
 
 *severity_name= "";
768
 
 return(0);
769
 
}
770
 
 
771
 
 
772
 
int Xorriso__text_to_sev(char *severity_name, int *severity_number, int flag)
773
 
{
774
 
 int ret= 1;
775
 
 
776
 
 ret= iso_text_to_sev(severity_name, severity_number);
777
 
 if(ret>0)
778
 
   return(ret);
779
 
   ret= burn_text_to_sev(severity_name, severity_number, 0);
780
 
 return(ret);
781
 
}
782
 
 
783
 
 
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
787
 
*/
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)
791
 
{
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;
796
 
 
797
 
 if(sorry_sev<0)
798
 
   Xorriso__text_to_sev("SORRY", &sorry_sev, 0);
799
 
 
800
 
 if(flag&4) {
801
 
   error_code= 0x00050000;
802
 
   Xorriso__text_to_sev(min_severity, &iso_sev, 0);
803
 
 } else {
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;
807
 
   if(flag&1)
808
 
     msg_text_pt= (char *) iso_error_to_msg(iso_error_code);
809
 
   iso_sev= iso_error_get_severity(iso_error_code);
810
 
 }
811
 
 if(msg_text_pt==NULL)
812
 
   msg_text_pt= msg_text;
813
 
 
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);
821
 
 if(victim[0]) {
822
 
   strcat(sfe, ": ");
823
 
   Text_shellsafe(victim, sfe+strlen(sfe), 0);
824
 
 }
825
 
 ret= Xorriso_msgs_submit(xorriso, error_code, sfe, os_errno, sev_text_pt, 4);
826
 
 return(ret);
827
 
}
828
 
 
829
 
 
830
 
/* @param flag bit0= suppress messages below UPDATE
831
 
               bit1= suppress messages below FAILURE
832
 
*/
833
 
int Xorriso_set_image_severities(struct XorrisO *xorriso, int flag)
834
 
{
835
 
 char *queue_sev, *print_sev;
836
 
 
837
 
 if(flag&2)
838
 
   queue_sev= "FAILURE";
839
 
 else if(flag&1)
840
 
   queue_sev= "UPDATE";
841
 
 else
842
 
   queue_sev= "ALL";
843
 
 if(xorriso->library_msg_direct_print)
844
 
   print_sev= xorriso->report_about_text;
845
 
 else
846
 
   print_sev= "NEVER";
847
 
 iso_set_msgs_severities(queue_sev, print_sev, "libisofs : ");
848
 
 return(1);
849
 
}
850
 
 
851
 
 
852
 
int Xorriso_update_volid(struct XorrisO *xorriso, int flag)
853
 
{
854
 
 int gret, sret= 1;
855
 
 
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);
860
 
861
 
 
862
 
 
863
 
int Xorriso_create_empty_iso(struct XorrisO *xorriso, int flag)
864
 
{
865
 
 int ret;
866
 
 IsoImage *volset;
867
 
 struct isoburn_read_opts *ropts;
868
 
 struct burn_drive_info *dinfo= NULL;
869
 
 struct burn_drive *drive= NULL;
870
 
 
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);
874
 
   if(ret<=0)
875
 
     return(ret);
876
 
 }
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;
886
 
 }
887
 
 
888
 
 ret= isoburn_ropt_new(&ropts, 0);
889
 
 if(ret<=0)
890
 
   return(ret);
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);
898
 
 if(ret<=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",
901
 
                            0);
902
 
   return(-1);
903
 
 }
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;
909
 
 return(1);
910
 
}
911
 
 
912
 
 
913
 
int Xorriso_record_boot_info(struct XorrisO *xorriso, int flag)
914
 
{
915
 
 int ret;
916
 
 struct burn_drive_info *dinfo;
917
 
 struct burn_drive *drive;
918
 
 IsoImage *image;
919
 
 ElToritoBootImage *bootimg;
920
 
 IsoFile *bootimg_node;
921
 
 IsoBoot *bootcat_node;
922
 
 
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);
927
 
 if(ret<=0)
928
 
   return(0);
929
 
 image= isoburn_get_attached_image(drive);
930
 
 if(image == NULL)
931
 
   return(0);
932
 
 ret= iso_image_get_boot_image(image, &bootimg,
933
 
                               &bootimg_node, &bootcat_node);
934
 
 iso_image_unref(image); /* release obtained reference */
935
 
 if(ret != 1)
936
 
   return(0);
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);
943
 
 return(1);
944
 
}
945
 
 
946
 
 
947
 
int Xorriso_assert_volid(struct XorrisO *xorriso, int msc1, int flag)
948
 
{
949
 
 int ret, image_blocks;
950
 
 char volid[33];
951
 
 struct burn_drive_info *dinfo;
952
 
 struct burn_drive *drive;
953
 
 
954
 
 if(xorriso->assert_volid[0] == 0)
955
 
   return(1);
956
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
957
 
                                "on attempt to perform -assert_volid", 0);
958
 
 if(ret<=0)
959
 
   return(0);
960
 
 ret= isoburn_read_iso_head(drive, msc1, &image_blocks, volid, 1);
961
 
 Xorriso_process_msg_queues(xorriso,0);
962
 
 if(ret <= 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);
967
 
   return(0);
968
 
 }
969
 
 ret= Sregex_match(xorriso->assert_volid, volid, 0);
970
 
 if(ret < 0)
971
 
   return(2);
972
 
 if(ret == 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);
980
 
   return(0);
981
 
 }
982
 
 return(ret);
983
 
}
984
 
 
985
 
 
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
996
 
*/
997
 
int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag)
998
 
{
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;
1001
 
 uint32_t size;
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;
1006
 
 IsoNode *root_node;
1007
 
 struct isoburn_read_opts *ropts= NULL;
1008
 
 char libburn_adr[SfileadrL], *boot_fate, *sev;
1009
 
 size_t value_length;
1010
 
 char *value= NULL;
1011
 
 double num;
1012
 
 char volid[33], adr_data[163], *adr_pt;
1013
 
 
1014
 
 if((flag&3)==0) { 
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);
1018
 
   return(-1);
1019
 
 }
1020
 
 ret= Xorriso_give_up_drive(xorriso, (flag&3)|8);
1021
 
 if(ret<=0)
1022
 
   return(ret);
1023
 
 if(flag & 1) 
1024
 
   xorriso->isofs_st_out= time(0) - 1;
1025
 
 
1026
 
 ret= Xorriso_auto_driveadr(xorriso, adr, libburn_adr, 0);
1027
 
 if(ret <= 0)
1028
 
   return(ret);
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);
1034
 
     {ret= 0; goto ex;}
1035
 
   } else {
1036
 
     sprintf(libburn_adr, "stdio:/dev/fd/%d", xorriso->dev_fd_1);
1037
 
   }
1038
 
 }
1039
 
 
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);
1043
 
   if(ret<=0)
1044
 
     goto ex;
1045
 
   ret= burn_drive_equals_adr(out_drive, libburn_adr, 1);
1046
 
   if(ret==1) {
1047
 
     dinfo= out_dinfo;
1048
 
     xorriso->indev_is_exclusive= xorriso->outdev_is_exclusive;
1049
 
   }
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);
1053
 
   if(ret<=0)
1054
 
     goto ex;
1055
 
   ret= burn_drive_equals_adr(in_drive, libburn_adr, 1);
1056
 
   if(ret==1) {
1057
 
     dinfo= in_dinfo;
1058
 
     xorriso->outdev_is_exclusive= xorriso->indev_is_exclusive;
1059
 
   }
1060
 
 }
1061
 
 
1062
 
 if(dinfo==NULL) {
1063
 
   aquire_flag= 1 | ((flag&(8|4))>>1) | ((xorriso->toc_emulation_flag & 3)<<3);
1064
 
   if(xorriso->toc_emulation_flag & 4)
1065
 
     aquire_flag|= 128;
1066
 
   if(!(xorriso->do_aaip & 1))
1067
 
     aquire_flag|= 32;
1068
 
   if((xorriso->ino_behavior & (1 | 2)) && !(xorriso->do_aaip & (4 | 32)))
1069
 
     aquire_flag|= 64;
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);
1074
 
   if(ret<=0) {
1075
 
     sprintf(xorriso->info_text,"Cannot aquire drive '%s'", adr); 
1076
 
     Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1077
 
     ret= 0; goto ex;
1078
 
   }
1079
 
   if(flag&1)
1080
 
     if(xorriso->image_start_mode&(1<<31)) /* used up setting */
1081
 
       xorriso->image_start_mode= 0; /* no need to perform auto setting */
1082
 
   if(flag & 1)
1083
 
     xorriso->indev_is_exclusive= xorriso->drives_exclusive;
1084
 
   if(flag & 2)
1085
 
     xorriso->outdev_is_exclusive= xorriso->drives_exclusive;
1086
 
 }
1087
 
 drive= dinfo[0].drive;
1088
 
 if(flag&1) {
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 */
1096
 
       params_flag= 0;
1097
 
       ret= Xorriso__bourne_to_reg(xorriso->image_start_value, adr_data, 0);
1098
 
       if(ret == 1)
1099
 
         params_flag|= 4;
1100
 
       ret= isoburn_get_mount_params(drive, 4, adr_data, &lba, &track,
1101
 
                                     &session, volid, params_flag);
1102
 
       Xorriso_process_msg_queues(xorriso,0);
1103
 
       if(ret <= 0)
1104
 
         goto ex;
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",
1108
 
                0, "FAILURE", 0);
1109
 
         ret= 0; goto ex;
1110
 
       }
1111
 
       sprintf(volid, "%d", lba);
1112
 
       adr_pt= volid;
1113
 
       adr_mode= 3;
1114
 
     }
1115
 
     ret= isoburn_set_msc1(drive, adr_mode, adr_pt,
1116
 
                           !!(xorriso->image_start_mode & (1<<16)));
1117
 
     if(ret<=0)
1118
 
       goto ex;
1119
 
     if(xorriso->image_start_mode&(1<<31))
1120
 
       xorriso->image_start_mode= 0; /* disable msc1 setting completely */
1121
 
     else
1122
 
       xorriso->image_start_mode|= (1<<31); /* mark as used up */
1123
 
   }
1124
 
 }
1125
 
 state= isoburn_disc_get_status(drive);
1126
 
 Xorriso_process_msg_queues(xorriso,0);
1127
 
 if(flag&1) {
1128
 
   volset= isoburn_get_attached_image(drive);
1129
 
   if(volset != NULL) { /* The image object is already created */
1130
 
     iso_image_unref(volset);
1131
 
   }
1132
 
 }
1133
 
 
1134
 
 if(flag&2) {
1135
 
   xorriso->out_drive_handle= dinfo;
1136
 
   if(Sfile_str(xorriso->outdev, adr, 0)<=0)
1137
 
     {ret= -1; goto ex;}
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);
1141
 
     not_writeable= 1;
1142
 
   }
1143
 
 }
1144
 
 if(flag&1) {
1145
 
   xorriso->in_drive_handle= dinfo;
1146
 
   if(Sfile_str(xorriso->indev, adr, 0)<=0)
1147
 
     {ret= -1; goto ex;}
1148
 
 } else if(flag&2) {
1149
 
   if(xorriso->in_volset_handle==NULL) {
1150
 
     /* No volume loaded: create empty one */
1151
 
     ret= Xorriso_create_empty_iso(xorriso, 0);
1152
 
     if(ret<=0)
1153
 
       goto ex;
1154
 
   } else {
1155
 
     iso_image_ref((IsoImage *) xorriso->in_volset_handle);
1156
 
     ret= isoburn_attach_image(drive, (IsoImage *) xorriso->in_volset_handle);
1157
 
     if(ret<=0) {
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);
1161
 
       {ret= -1; goto ex;}
1162
 
     }
1163
 
   }
1164
 
   if(!(flag&32))
1165
 
     Xorriso_toc(xorriso, 1 | 2 | 8);
1166
 
   {ret= 1+not_writeable; goto ex;}
1167
 
 }
1168
 
 
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);
1175
 
 
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");
1181
 
   sev= "FAILURE";
1182
 
   if(xorriso->img_read_error_mode==2)
1183
 
     sev= "FATAL";
1184
 
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, sev, 0);
1185
 
   Xorriso_give_up_drive(xorriso, 1|((flag&32)>>2));
1186
 
   ret= 3; goto ex;
1187
 
 }
1188
 
 /* fill read opts */ 
1189
 
 ret= isoburn_ropt_new(&ropts, 0);
1190
 
 if(ret<=0)
1191
 
   goto ex;
1192
 
 
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;
1203
 
 
1204
 
#ifdef isoburn_ropt_nomd5
1205
 
 if(!(xorriso->do_md5 & 1))
1206
 
   ext|= isoburn_ropt_nomd5;
1207
 
#endif
1208
 
 
1209
 
 isoburn_ropt_set_extensions(ropts, ext);
1210
 
 
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));
1214
 
 
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);
1218
 
 
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.
1222
 
 */
1223
 
 if(xorriso->img_read_error_mode>0)
1224
 
   iso_set_abort_severity("SORRY");
1225
 
 
1226
 
 if(state != BURN_DISC_BLANK) {
1227
 
   ret= isoburn_disc_get_msc1(drive, &load_lba);
1228
 
   if(ret > 0) {
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); 
1232
 
   }
1233
 
   ret= Xorriso_assert_volid(xorriso, load_lba, 0);
1234
 
   if(ret <= 0)
1235
 
     goto ex;
1236
 
 }
1237
 
 
1238
 
 read_ret= ret= isoburn_read_image(drive, ropts, &volset);
1239
 
 
1240
 
 /* <<< Resetting to normal thresholds */
1241
 
 if(xorriso->img_read_error_mode>0)
1242
 
   Xorriso_set_abort_severity(xorriso, 0);
1243
 
 
1244
 
 if(ret<=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");
1249
 
   sev= "FAILURE";
1250
 
   if(xorriso->img_read_error_mode==2)
1251
 
     sev= "FATAL";
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'.",
1256
 
            0, "HINT", 0);
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.",
1259
 
                         0, "HINT", 0);
1260
 
   }
1261
 
 
1262
 
 
1263
 
   ret= 3; goto ex;
1264
 
 }
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);
1270
 
 
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;
1281
 
 
1282
 
 /* <<< can be removed as soon as libisofs-0.6.24 is mandatory
1283
 
 */
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.
1292
 
    */
1293
 
   iso_image_set_copyright_file_id(volset, "");
1294
 
   iso_image_set_abstract_file_id(volset, "");
1295
 
   iso_image_set_biblio_file_id(volset, "");
1296
 
 }
1297
 
 
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);
1302
 
   if(ret<=0)
1303
 
     goto ex;
1304
 
   iso_image_ref((IsoImage *) xorriso->in_volset_handle);
1305
 
   isoburn_attach_image(out_drive, xorriso->in_volset_handle);
1306
 
 }
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";
1316
 
   else
1317
 
     boot_fate= "discarded";
1318
 
   sprintf(xorriso->info_text,
1319
 
         "Detected El-Torito boot information which currently is set to be %s",
1320
 
         boot_fate);
1321
 
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); 
1322
 
   Xorriso_record_boot_info(xorriso, 0);
1323
 
 }
1324
 
 
1325
 
 if(flag & 1) {
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);
1329
 
   if(ret > 0) {
1330
 
     if(value_length > 0) {
1331
 
       sscanf(value, "%lf", &num);
1332
 
       if(num > 0)
1333
 
         xorriso->isofs_st_in= num;
1334
 
     }
1335
 
     free(value);
1336
 
   }
1337
 
 }
1338
 
 
1339
 
 if(!(flag&32)) {
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);
1349
 
     }
1350
 
   }
1351
 
 }
1352
 
 
1353
 
 ret= 1+not_writeable;
1354
 
ex:
1355
 
 Xorriso_process_msg_queues(xorriso,0);
1356
 
 if(ret<=0) {
1357
 
   hret= Xorriso_give_up_drive(xorriso, (flag&3)|((flag&32)>>2));
1358
 
   if(hret<ret)
1359
 
     ret= hret;
1360
 
 } else {
1361
 
   if(drive != NULL && (xorriso->do_calm_drive & 1) && !(flag & 64))
1362
 
     burn_drive_snooze(drive, 0); /* No need to make noise from start */
1363
 
 }
1364
 
 if(ropts!=NULL)
1365
 
   isoburn_ropt_destroy(&ropts, 0);
1366
 
 return(ret);
1367
 
}
1368
 
 
1369
 
 
1370
 
/* @param flag bit0=input drive
1371
 
               bit1=output drive
1372
 
               bit2=eject
1373
 
               bit3=no info message or toc
1374
 
*/
1375
 
int Xorriso_give_up_drive(struct XorrisO *xorriso, int flag)
1376
 
{
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];
1381
 
 
1382
 
 in_is_out_too= (xorriso->in_drive_handle == xorriso->out_drive_handle);
1383
 
 if((flag&4) && in_is_out_too && (flag&(1|2))) {
1384
 
   if((flag&3)!=3) {
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);
1388
 
   }
1389
 
   flag|= 3; /* give up in/out drive to eject it */
1390
 
 }
1391
 
   
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);
1395
 
 
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);
1402
 
       do_eject= 0;
1403
 
     }
1404
 
     if(drive!=NULL)
1405
 
       isoburn_drive_release(drive, do_eject);
1406
 
     if(dinfo!=NULL)
1407
 
       burn_drive_info_free(dinfo);
1408
 
   }
1409
 
   xorriso->in_drive_handle= NULL;
1410
 
   xorriso->indev[0]= 0;
1411
 
 
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;
1426
 
   in_is_out_too= 0;
1427
 
 }
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);
1434
 
     do_eject= 0;
1435
 
   }
1436
 
   Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
1437
 
                             "on attempt to give up drive", 2);
1438
 
   if(!in_is_out_too) {
1439
 
     if(drive!=NULL)
1440
 
       isoburn_drive_release(drive, do_eject);
1441
 
     if(dinfo!=NULL)
1442
 
       burn_drive_info_free(dinfo);
1443
 
   }
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);
1448
 
   if(ret<=0)
1449
 
     return(ret);
1450
 
   if(!(flag&8)) {
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);
1455
 
   }
1456
 
 }
1457
 
 Xorriso_process_msg_queues(xorriso,0);
1458
 
 return(1);
1459
 
}
1460
 
 
1461
 
 
1462
 
int Xorriso_make_write_options(
1463
 
        struct XorrisO *xorriso, struct burn_drive *drive,
1464
 
        struct burn_write_opts **burn_options, int flag)
1465
 
{
1466
 
 int drive_role, stream_mode= 0;
1467
 
 
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);
1473
 
   return(0);
1474
 
 }
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)
1481
 
   stream_mode= 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);
1487
 
 
1488
 
#ifdef Xorriso_dvd_obs_default_64K
1489
 
 if(xorriso->dvd_obs == 0)
1490
 
   burn_write_opts_set_dvd_obs(*burn_options, 64 * 1024);
1491
 
 else  
1492
 
#endif
1493
 
   burn_write_opts_set_dvd_obs(*burn_options, xorriso->dvd_obs);
1494
 
 
1495
 
 burn_write_opts_set_stdio_fsync(*burn_options, xorriso->stdio_sync);
1496
 
 burn_write_opts_set_underrun_proof(*burn_options, 1);
1497
 
 return(1);
1498
 
}
1499
 
 
1500
 
 
1501
 
/* @param flag bit0= do not write but only prepare and return size in sectors
1502
 
               bit1= do not use isoburn wrappers
1503
 
*/
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)
1507
 
{
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;
1513
 
 
1514
 
 img_sectors= burn_disc_get_sectors(disc);
1515
 
 
1516
 
 sessions= burn_disc_get_sessions(disc, &num_sessions);
1517
 
 if(sessions==NULL || num_sessions < 1) {
1518
 
no_track:;
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);
1522
 
   {ret= -1; goto ex;}
1523
 
 }
1524
 
 tracks= burn_session_get_tracks(sessions[0], &num_tracks);
1525
 
 if(tracks==NULL || num_tracks < 1)
1526
 
   goto no_track;
1527
 
 
1528
 
 padding= 0;
1529
 
 ret= burn_disc_get_profile(drive, &profile, profile_name);
1530
 
 padding= xorriso->padding / 2048;
1531
 
 if(xorriso->padding > padding * 2048)
1532
 
   padding++;
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);
1541
 
   }
1542
 
 }
1543
 
 if(xorriso->alignment == 0) {
1544
 
   ret= isoburn_needs_emulation(drive);
1545
 
   if(ret > 0) {
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.
1549
 
      */
1550
 
     xorriso->alignment= 32;
1551
 
   }
1552
 
 }
1553
 
 if(xorriso->alignment > 0) {
1554
 
   if(img_sectors > 0) {
1555
 
     ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &lba, &nwa);
1556
 
     if(ret <= 0)
1557
 
       nwa= 0;
1558
 
     lba= (nwa + img_sectors + padding) % xorriso->alignment;
1559
 
     if(lba > 0)
1560
 
       padding+= xorriso->alignment - lba;
1561
 
   } else if(padding < xorriso->alignment)
1562
 
     padding= xorriso->alignment;
1563
 
 }
1564
 
 burn_track_define_data(tracks[0], 0, padding * 2048, 0, BURN_MODE1);
1565
 
 Xorriso_process_msg_queues(xorriso,0);
1566
 
 
1567
 
 if(flag&2)
1568
 
   media_space= burn_disc_available_space(drive, burn_options) /
1569
 
                (off_t) 2048;
1570
 
 else
1571
 
   media_space= isoburn_disc_available_space(drive, burn_options) /
1572
 
                (off_t) 2048;
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);
1578
 
   {ret= 0; goto ex;}
1579
 
 }
1580
 
 if(flag&1) {
1581
 
   ret= img_sectors+padding;
1582
 
 } else
1583
 
   ret= 1;
1584
 
ex:;
1585
 
 return(ret);
1586
 
}
1587
 
 
1588
 
 
1589
 
/* @return <0 yes , 0 no , <0 error */
1590
 
int Xorriso_is_isohybrid(struct XorrisO *xorriso, IsoFile *bootimg_node,
1591
 
                         int flag)
1592
 
{
1593
 
 int ret;
1594
 
 unsigned char buf[68];
1595
 
 void *data_stream= NULL;
1596
 
 
1597
 
 ret= Xorriso_iso_file_open(xorriso, "", (void *) bootimg_node,
1598
 
                            &data_stream, 1);
1599
 
 if(ret <= 0)
1600
 
   return(-1);
1601
 
 ret= Xorriso_iso_file_read(xorriso, data_stream, (char *) buf, 68, 0);
1602
 
 Xorriso_iso_file_close(xorriso, &data_stream, 0);
1603
 
 if(ret <= 0)
1604
 
   return(0);
1605
 
 if(buf[64] == 0xfb && buf[65] == 0xc0 && buf[66] == 0x78 && buf[67] == 0x70)
1606
 
   return(1);
1607
 
 return(0);
1608
 
}
1609
 
 
1610
 
 
1611
 
/* @param flag bit0= operating on newly attached boot image
1612
 
*/
1613
 
int Xorriso_set_isolinux_options(struct XorrisO *xorriso,
1614
 
                                 IsoImage *image, int flag)
1615
 
{
1616
 
 int make_isohybrid_mbr= 0, ret, patch_table= 0, num_boots, i;
1617
 
 ElToritoBootImage *bootimg, **boots = NULL;
1618
 
 IsoFile *bootimg_node, **bootnodes = NULL;
1619
 
 
1620
 
 ret= iso_image_get_boot_image(image, &bootimg, &bootimg_node, NULL);
1621
 
 Xorriso_process_msg_queues(xorriso,0);
1622
 
 if(ret != 1) {
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);
1625
 
   ret= -1; goto ex;
1626
 
 }
1627
 
 ret= iso_image_get_all_boot_imgs(image, &num_boots, &boots, &bootnodes, 0);
1628
 
 Xorriso_process_msg_queues(xorriso,0);
1629
 
 if(ret != 1) {
1630
 
   Xorriso_report_iso_error(xorriso, "", ret, "Cannot inquire boot images", 0,
1631
 
                            "FATAL", 1);
1632
 
   ret= -1; goto ex;
1633
 
 }
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;
1638
 
 }
1639
 
 
1640
 
 /* Handle patching of first attached boot image or of imported boot images 
1641
 
 */
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))
1646
 
       patch_table= 0;
1647
 
     else if((xorriso->patch_isolinux_image & 2) &&
1648
 
             el_torito_get_boot_platform_id(boots[i]) == 0xef)
1649
 
       patch_table= 0;
1650
 
   }
1651
 
   if(i > 0 || xorriso->boot_image_isohybrid == 0) {
1652
 
     ret= el_torito_set_isolinux_options(boots[i], patch_table, 0);
1653
 
     if(ret != 1)
1654
 
       {ret= 0; goto ex;}
1655
 
 continue;
1656
 
   }
1657
 
   if(xorriso->boot_image_isohybrid == 3) {
1658
 
     make_isohybrid_mbr= 1;
1659
 
   } else {
1660
 
     ret= Xorriso_is_isohybrid(xorriso, bootimg_node, 0);
1661
 
     if(ret < 0)
1662
 
       {ret= 0; goto ex;}
1663
 
     if(ret > 0)
1664
 
       make_isohybrid_mbr= 1;
1665
 
   }
1666
 
 
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);
1671
 
     {ret= 0; goto ex;}
1672
 
   }
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;
1677
 
   }
1678
 
   ret= el_torito_set_isolinux_options(bootimg,
1679
 
                                    patch_table | (make_isohybrid_mbr << 1),0);
1680
 
   if(ret != 1)
1681
 
     {ret= 0; goto ex;}
1682
 
 }
1683
 
ex:
1684
 
 Xorriso_process_msg_queues(xorriso,0);
1685
 
 if(boots != NULL)
1686
 
   free(boots);
1687
 
 if(bootnodes != NULL)
1688
 
   free(bootnodes);
1689
 
 return(ret);
1690
 
}
1691
 
 
1692
 
 
1693
 
int Xorriso_auto_format(struct XorrisO *xorriso, int flag)
1694
 
{
1695
 
 int ret, profile, status, num_formats;
1696
 
 char profile_name[80];
1697
 
 struct burn_drive_info *dinfo;
1698
 
 struct burn_drive *drive;
1699
 
 off_t size;
1700
 
 unsigned dummy;
1701
 
 
1702
 
 ret= Xorriso_may_burn(xorriso, 0);
1703
 
 if(ret <= 0)
1704
 
   return(0);
1705
 
 
1706
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
1707
 
                                "on attempt to autoformat", 2);
1708
 
 if(ret<=0)
1709
 
   return(0);
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.",
1716
 
             profile_name);
1717
 
     Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1718
 
     ret= Xorriso_format_media(xorriso, (off_t) 0, 1 | 4);
1719
 
     if(ret<=0) {
1720
 
       sprintf(xorriso->info_text, "Automatic formatting of %s failed",
1721
 
               profile_name);
1722
 
       Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
1723
 
       return(ret);
1724
 
     }
1725
 
   }
1726
 
 }
1727
 
 return(1);
1728
 
}
1729
 
 
1730
 
 
1731
 
int Xorriso_set_system_area(struct XorrisO *xorriso, struct burn_drive *drive,
1732
 
                            IsoImage *img, struct isoburn_imgen_opts *sopts,
1733
 
                            int flag)
1734
 
{
1735
 
 int ret, options, system_area_options, iso_lba= -1, start_lba, image_blocks;
1736
 
 char volid[33];
1737
 
 FILE *fp= NULL;
1738
 
 char buf[32768], *bufpt= NULL;
1739
 
 off_t hd_lba;
1740
 
 unsigned char *ub;
1741
 
 ElToritoBootImage *bootimg;
1742
 
 IsoFile *bootimg_node;
1743
 
 
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);
1749
 
     if(ret == 0) {
1750
 
       goto do_set;
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",
1755
 
                     0, "FAILURE", 1);
1756
 
       {ret= 0; goto ex;}
1757
 
     } else {
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));
1763
 
 
1764
 
       iso_lba= -1;
1765
 
       ret= isoburn_disc_get_msc1(drive, &start_lba);
1766
 
       if(ret > 0) {
1767
 
          ret= isoburn_read_iso_head(drive, start_lba, &image_blocks,
1768
 
                                     volid, 1);
1769
 
          if(ret > 0)
1770
 
            iso_lba= start_lba + image_blocks;
1771
 
       }
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);
1784
 
         if(ret != 1)
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;
1790
 
         }
1791
 
       }
1792
 
       if(system_area_options == 0) {
1793
 
         Xorriso_msgs_submit(xorriso, 0,
1794
 
                  "Loaded System Area data are not suitable for MBR patching.",
1795
 
                  0, "DEBUG", 0);
1796
 
       }
1797
 
     }
1798
 
     bufpt= buf;
1799
 
     ret= 1;
1800
 
   } else
1801
 
     ret= 0;
1802
 
   goto do_set;
1803
 
 }
1804
 
 if(strcmp(xorriso->system_area_disk_path, "/dev/zero") == 0)
1805
 
   {ret= 1; goto do_set;}
1806
 
 
1807
 
 ret= Xorriso_afile_fopen(xorriso, xorriso->system_area_disk_path,
1808
 
                          "rb", &fp, 2);
1809
 
 if(ret <= 0)
1810
 
   {ret= 0; goto ex;}
1811
 
 ret= fread(buf, 1, 32768, fp);
1812
 
 if(ret < 32768) {
1813
 
   if(ferror(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);
1818
 
     {ret= 0; goto ex;}
1819
 
   }
1820
 
 }
1821
 
 bufpt= buf;
1822
 
 
1823
 
do_set:;
1824
 
 if(ret > 0 && xorriso->system_area_disk_path[0]) {
1825
 
   sprintf(xorriso->info_text, "Copying to System Area: %d bytes from file ",
1826
 
           ret);
1827
 
   Text_shellsafe(xorriso->system_area_disk_path, xorriso->info_text, 1);
1828
 
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
1829
 
 }
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",
1835
 
                      0, "FAILURE", 1);
1836
 
   {ret= 0; goto ex;}
1837
 
 }
1838
 
 ret= 1;
1839
 
ex:;
1840
 
 if(fp != NULL && fp != stdin)
1841
 
   fclose(fp);
1842
 
 return(ret);
1843
 
1844
 
 
1845
 
 
1846
 
/* 
1847
 
 bit0= do only report non-default settings
1848
 
 bit1= do only report to fp
1849
 
 bit2= is_default
1850
 
 bit3= append -boot_image any next
1851
 
 bit4= eventually concentrate boot options
1852
 
*/
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)
1859
 
{
1860
 
 int is_default, no_defaults, i, is_default_id= 0, ret;
1861
 
 char *line, bspec[SfileadrL + 80], zeros[28];
1862
 
 off_t file_size;
1863
 
 struct stat stbuf;
1864
 
 
1865
 
 no_defaults= flag & 1;
1866
 
 line= xorriso->result_line;
1867
 
 
1868
 
 if(flag & 16) {
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)
1873
 
     is_default_id= 1;
1874
 
 
1875
 
   /* -boot_image isolinux dir= ... */
1876
 
   bspec[0]= 0;
1877
 
   if(strcmp(form, "isolinux") != 0 && strcmp(form, "any") != 0)
1878
 
     ;
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); 
1895
 
     return(1);
1896
 
   }
1897
 
 
1898
 
   file_size= 0;
1899
 
   ret= Xorriso_iso_lstat(xorriso, bin_path, &stbuf, 2 | 4);
1900
 
   if(ret == 0)
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);
1907
 
     strcat(line, "\n");
1908
 
     Xorriso_status_result(xorriso,filter,fp,flag&2);
1909
 
     return(1);
1910
 
   }
1911
 
 }
1912
 
 
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);
1916
 
 strcat(line, "\n");
1917
 
 if(!(is_default && no_defaults))
1918
 
   Xorriso_status_result(xorriso,filter,fp,flag&2);
1919
 
 
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); 
1924
 
 
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); 
1930
 
 
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); 
1936
 
 
1937
 
 is_default= 1;
1938
 
 if(!(flag & 4))
1939
 
   for(i= 0; i < 20; i++)
1940
 
     if(selection_crit[i])
1941
 
       is_default= 0;
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]);
1945
 
 strcat(line, "\n");
1946
 
 if(!(is_default && no_defaults))
1947
 
   Xorriso_status_result(xorriso,filter,fp,flag&2); 
1948
 
 
1949
 
 is_default= 1;
1950
 
 if(!(flag & 4))
1951
 
   for(i= 0; i < 28; i++)
1952
 
     if(id_string[i])
1953
 
       is_default= 0;
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]);
1957
 
 strcat(line, "\n");
1958
 
 if(!(is_default && no_defaults))
1959
 
   Xorriso_status_result(xorriso,filter,fp,flag&2); 
1960
 
 
1961
 
 return(1); 
1962
 
}
1963
 
 
1964
 
 
1965
 
/* 
1966
 
 bit0= do only report non-default settings
1967
 
 bit1= do only report to fp
1968
 
*/
1969
 
int Xorriso_boot_image_status(struct XorrisO *xorriso, char *filter, FILE *fp,
1970
 
                              int flag)
1971
 
{
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];
1983
 
 
1984
 
 line= xorriso->result_line;
1985
 
 no_defaults= flag & 1;
1986
 
 
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);
1991
 
     is_default= 0;
1992
 
   } else if(xorriso->keep_boot_image) {
1993
 
     sprintf(line, "-boot_image %s keep\n", form);
1994
 
     is_default= 0;
1995
 
   } else {
1996
 
     sprintf(line, "-boot_image %s discard\n", form);
1997
 
     is_default= 1;
1998
 
   }
1999
 
   if(!(is_default && no_defaults))
2000
 
      Xorriso_status_result(xorriso,filter,fp,flag&2); 
2001
 
   ret= 1; goto ex;
2002
 
 }
2003
 
 
2004
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
2005
 
                                "on attempt to print boot info", 16);
2006
 
 if(ret<=0)
2007
 
   {ret= 0; goto ex;}
2008
 
 image= isoburn_get_attached_image(drive);
2009
 
 Xorriso_process_msg_queues(xorriso,0);
2010
 
 if(image == NULL) 
2011
 
   {ret= 0; goto ex;}
2012
 
 
2013
 
 if(xorriso->boot_image_bin_path[0] || xorriso->boot_count > 0)
2014
 
   bin_path_in_use= 1;
2015
 
 if(xorriso->boot_image_cat_path[0] && bin_path_in_use) {
2016
 
   is_default= 0;
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);
2021
 
 }
2022
 
 
2023
 
 if(xorriso->boot_count > 0) {
2024
 
 
2025
 
   /* show attached boot image info */;
2026
 
 
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);
2032
 
       if(ret <= 0)
2033
 
    continue;
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));
2044
 
       if(ret <= 0)
2045
 
     continue;
2046
 
       sprintf(line,"-boot_image %s next\n", form);
2047
 
       Xorriso_status_result(xorriso,filter,fp,flag&2);
2048
 
     }
2049
 
   }
2050
 
 } 
2051
 
 
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;
2056
 
 
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])
2065
 
   break;
2066
 
   if(i >= 20)
2067
 
     for(i= 0; i < 28; i++)
2068
 
       if(xorriso->boot_id_string[i])
2069
 
     break;
2070
 
   if(i >= 28)
2071
 
     {ret= 1; goto ex;} /* Images registered, pending is still default */
2072
 
 }
2073
 
  
2074
 
 hflag= 16; 
2075
 
 if(xorriso->boot_platform_id == 0xef && !xorriso->boot_efi_default)
2076
 
   hflag= 0;
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));
2083
 
 if(ret <= 0)
2084
 
   goto ex;
2085
 
 
2086
 
 ret= 1;
2087
 
ex:
2088
 
 if(boots != NULL)
2089
 
   free(boots);
2090
 
 if(bootnodes != NULL)
2091
 
   free(bootnodes);
2092
 
 return(ret);
2093
 
}
2094
 
 
2095
 
 
2096
 
/* @param flag bit0= do not increment boot_count
2097
 
                     and do not reset boot parameters
2098
 
           bit1= dispose attached boot images
2099
 
*/
2100
 
int Xorriso_attach_boot_image(struct XorrisO *xorriso, int flag)
2101
 
{
2102
 
 int ret;
2103
 
 char sfe[5*SfileadrL], *cpt;
2104
 
 struct burn_drive_info *source_dinfo;
2105
 
 struct burn_drive *source_drive;
2106
 
 IsoImage *image= NULL;
2107
 
 IsoNode *node;
2108
 
 ElToritoBootImage *bootimg;
2109
 
 enum eltorito_boot_media_type emul_type= ELTORITO_NO_EMUL;
2110
 
 char *bin_path;
2111
 
 int emul, platform_id;
2112
 
 off_t load_size;
2113
 
 struct stat stbuf;
2114
 
 int hflag= 0;
2115
 
 
2116
 
 if(xorriso->boot_image_bin_path[0] == 0 && !(flag & 2)) {
2117
 
 
2118
 
   /* >>> no boot image path given : no op */;
2119
 
 
2120
 
   ret= 2; goto ex;
2121
 
 }
2122
 
 
2123
 
 if(xorriso->in_drive_handle == NULL)
2124
 
   hflag= 2;
2125
 
 ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive,
2126
 
                                "on attempt to attach boot image", hflag);
2127
 
 if(ret<=0)
2128
 
   goto ex;
2129
 
 image= isoburn_get_attached_image(source_drive);
2130
 
 if(image == NULL) {
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);
2135
 
   ret= 0; goto ex;
2136
 
 }
2137
 
 if(flag & 2) {
2138
 
   iso_image_remove_boot_image(image);
2139
 
   xorriso->boot_count= 0;
2140
 
   ret= 1; goto ex;
2141
 
 }
2142
 
 
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;
2147
 
 
2148
 
 if(xorriso->boot_efi_default) {
2149
 
   emul= 0;
2150
 
   platform_id= 0xef;
2151
 
   xorriso->patch_isolinux_image= 0;
2152
 
 }
2153
 
 if(platform_id == 0xef || load_size < 0) {
2154
 
   ret= Xorriso_iso_lstat(xorriso, bin_path, &stbuf, 2 | 4);
2155
 
   if(ret != 0)
2156
 
     {ret= 0; goto ex;}
2157
 
   load_size= ((stbuf.st_size / (off_t) 512) +
2158
 
              !!(stbuf.st_size % (off_t) 512)) * 512;
2159
 
 }
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);
2163
 
 
2164
 
 if(emul == 0)
2165
 
   emul_type= ELTORITO_NO_EMUL;
2166
 
 else if(emul == 1)
2167
 
   emul_type= ELTORITO_HARD_DISC_EMUL;
2168
 
 else if(emul == 2)
2169
 
   emul_type= ELTORITO_FLOPPY_EMUL;
2170
 
 
2171
 
 ret= Xorriso_node_from_path(xorriso, image, bin_path, &node, 1);
2172
 
 if(ret <= 0) {
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);
2177
 
   {ret= 0; goto ex;}
2178
 
 }
2179
 
 
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, '/');
2184
 
     if(cpt == NULL)
2185
 
       cpt= xorriso->boot_image_cat_path;
2186
 
     else
2187
 
       cpt++;
2188
 
     strcpy(cpt, "boot.cat");
2189
 
   }
2190
 
   ret= Xorriso_node_from_path(xorriso, image, xorriso->boot_image_cat_path,
2191
 
                                &node, 1);
2192
 
   if(ret > 0) {
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);
2198
 
       {ret= 0; goto ex;}
2199
 
     }
2200
 
     ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, xorriso->boot_image_cat_path,
2201
 
                      8 | (xorriso->do_overwrite == 1));
2202
 
     if(ret != 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);
2207
 
       {ret= 0; goto ex;}
2208
 
     }
2209
 
   }
2210
 
 
2211
 
   /* Discard old boot image, set new one */
2212
 
   ret= iso_image_get_boot_image(image, &bootimg, NULL, NULL);
2213
 
   if(ret == 1)
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);
2217
 
   if(ret > 0)
2218
 
     iso_image_set_boot_catalog_weight(image, 1000000000);
2219
 
 } else {
2220
 
   ret= iso_image_add_boot_image(image, bin_path, emul_type, 0, &bootimg);
2221
 
 }
2222
 
 if(ret < 0) {
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",
2226
 
                 0, "FAILURE", 1);
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);
2230
 
   {ret= 0; goto ex;}
2231
 
 }
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);
2237
 
 if(!(flag & 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;
2250
 
 }
2251
 
 if(ret <= 0)
2252
 
   goto ex;
2253
 
 
2254
 
 ret= 1;
2255
 
ex:;
2256
 
 if(image != NULL)
2257
 
   iso_image_unref(image);
2258
 
 return(ret);
2259
 
}
2260
 
 
2261
 
 
2262
 
/* #define Xorriso_boot_dummY 1 */
2263
 
 
2264
 
 
2265
 
/* @param flag bit0= do not write but only prepare and return size in sectors
2266
 
*/
2267
 
int Xorriso_write_session(struct XorrisO *xorriso, int flag)
2268
 
{
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;
2283
 
 IsoNode *root_node;
2284
 
 int profile_number;
2285
 
 char profile_name[80];
2286
 
 
2287
 
#ifdef Xorriso_multi_booT
2288
 
 IsoBoot *bootcat_node;
2289
 
#else
2290
 
 char *cpt;
2291
 
 IsoNode *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;
2297
 
 struct stat stbuf;
2298
 
 char *boot_image_bin_path;
2299
 
#endif /* ! Xorriso_multi_booT */
2300
 
 
2301
 
 ret= Xorriso_finish_hl_update(xorriso, 0);
2302
 
 if(ret <= 0)
2303
 
   return(ret);
2304
 
 
2305
 
 out_cs= xorriso->out_charset;
2306
 
 if(out_cs == NULL)
2307
 
   Xorriso_get_local_charset(xorriso, &out_cs, 0);
2308
 
 
2309
 
 if(!(flag & 1)) {
2310
 
   ret= Xorriso_auto_format(xorriso, 0);
2311
 
   if(ret <=0 )
2312
 
     return(0);
2313
 
 }
2314
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
2315
 
                                "on attempt to write", 2);
2316
 
 if(ret<=0)
2317
 
   return(0);
2318
 
 if(xorriso->out_drive_handle == xorriso->in_drive_handle) {
2319
 
   source_drive= drive;
2320
 
 } else {
2321
 
   if(xorriso->in_drive_handle == NULL) {
2322
 
     source_drive= drive;
2323
 
   } else {
2324
 
     ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive,
2325
 
                                    "on attempt to get source for write", 0);
2326
 
     if(ret<=0)
2327
 
       goto ex;
2328
 
   }
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");
2335
 
     else
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);
2339
 
     {ret= 0; goto ex;}
2340
 
   }
2341
 
 }
2342
 
 ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2);
2343
 
 if(ret == 2)
2344
 
   pacifier_speed= 1;
2345
 
 else if(ret == 3)
2346
 
   pacifier_speed= 2;
2347
 
 
2348
 
 ret= isoburn_igopt_new(&sopts, 0);
2349
 
 if(ret<=0) {
2350
 
   Xorriso_process_msg_queues(xorriso, 0);
2351
 
   goto ex;
2352
 
 }
2353
 
 relax= xorriso->relax_compliance;
2354
 
 
2355
 
 xorriso->alignment= 0;
2356
 
 image= isoburn_get_attached_image(source_drive);
2357
 
 if(image != NULL) {
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);
2362
 
 }
2363
 
 
2364
 
 if((xorriso->do_aaip & 256) && out_cs != NULL) {
2365
 
   static char *names = "isofs.cs";
2366
 
   size_t value_lengths[1];
2367
 
 
2368
 
   value_lengths[0]= strlen(out_cs);
2369
 
   ret= Xorriso_setfattr(xorriso, NULL, "/",
2370
 
                         (size_t) 1, &names, value_lengths, &out_cs, 2 | 8);
2371
 
   if(ret<=0)
2372
 
     goto ex;
2373
 
 }
2374
 
 
2375
 
 ret= Xorriso_set_system_area(xorriso, source_drive, image, sopts, 0);
2376
 
 if(ret <= 0)
2377
 
   goto ex;
2378
 
 
2379
 
 /* Activate, adjust or discard boot image */
2380
 
 
2381
 
#ifdef Xorriso_multi_booT
2382
 
 
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);
2387
 
     if(ret <= 0)
2388
 
       goto ex;
2389
 
   }
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);
2394
 
       if(ret > 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);
2398
 
           if(ret <= 0)
2399
 
             goto ex;
2400
 
         }
2401
 
       }
2402
 
     }
2403
 
 
2404
 
#else /* Xorriso_multi_booT */
2405
 
 
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;
2410
 
 
2411
 
 /* >>> This is kindof a quick hack.
2412
 
        Needed would be a list of boot images with own parameters each.
2413
 
 */
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;
2418
 
     boot_image_emul= 0;
2419
 
     boot_platform_id= 0xef;
2420
 
     ret= Xorriso_iso_lstat(xorriso, xorriso->boot_image_efi_path, 
2421
 
                            &stbuf, 2 | 4);
2422
 
     if(ret != 0)
2423
 
       goto ex;
2424
 
     boot_image_load_size= ((stbuf.st_size / (off_t) 512) +
2425
 
                          !!(stbuf.st_size % (off_t) 512)) * 512;
2426
 
   }
2427
 
 }
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, '/');
2442
 
       if(cpt == NULL)
2443
 
         cpt= xorriso->boot_image_cat_path;
2444
 
       else
2445
 
         cpt++;
2446
 
       strcpy(cpt, "boot.cat");
2447
 
     }
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);
2454
 
 
2455
 
     ret= Xorriso_node_from_path(xorriso, image, boot_image_bin_path,
2456
 
                                 &node, 1);
2457
 
     if(ret <= 0) {
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);
2462
 
       {ret= 0; goto ex;}
2463
 
     }
2464
 
     ret= Xorriso_node_from_path(xorriso, image, xorriso->boot_image_cat_path,
2465
 
                                 &node, 1);
2466
 
     if(ret > 0) {
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);
2472
 
         {ret= 0; goto ex;}
2473
 
       }
2474
 
       ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, xorriso->boot_image_cat_path,
2475
 
                        8 | (xorriso->do_overwrite == 1));
2476
 
       if(ret != 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);
2481
 
         {ret= 0; goto ex;}
2482
 
       }
2483
 
     }
2484
 
 
2485
 
     ret= iso_image_set_boot_image(image, boot_image_bin_path,
2486
 
                                   emul_type, xorriso->boot_image_cat_path,
2487
 
                                   &bootimg);
2488
 
     if(ret < 0) {
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",
2492
 
                 0, "FAILURE", 1);
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);
2496
 
       {ret= 0; goto ex;}
2497
 
     }
2498
 
 
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");
2504
 
     else
2505
 
       el_torito_set_id_string(bootimg,
2506
 
                             (unsigned char *) "xorriso 80x86 BIOS 012345678");
2507
 
#endif /* Xorriso_boot_dummY */
2508
 
 
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);
2513
 
     if(ret <= 0)
2514
 
       goto ex;
2515
 
     if(boot_image_bin_path == xorriso->boot_image_bin_path &&
2516
 
        xorriso->boot_image_efi_path[0]) {
2517
 
       /* Add EFI image */
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);
2523
 
       if(ret < 0) {
2524
 
         Xorriso_process_msg_queues(xorriso,0);
2525
 
         Xorriso_report_iso_error(xorriso, "", ret,
2526
 
                          "Error when adding EFI boot image", 0, "FAILURE", 1);
2527
 
         goto ex;
2528
 
       }
2529
 
 
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 */
2537
 
 
2538
 
       el_torito_set_boot_platform_id(efi_bootimg, (uint8_t) 0xef);
2539
 
       ret= Xorriso_iso_lstat(xorriso, xorriso->boot_image_efi_path, 
2540
 
                            &stbuf, 2 | 4);
2541
 
       if(ret != 0)
2542
 
         goto ex;
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); 
2546
 
 
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);
2551
 
       if(ret < 0) {
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);
2555
 
         goto ex;
2556
 
       }
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); 
2563
 
 
2564
 
       ret= iso_image_add_boot_image(image, "/xxxx",
2565
 
                                      ELTORITO_NO_EMUL, 0, &efi_bootimg);
2566
 
       if(ret < 0) {
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);
2570
 
         goto ex;
2571
 
       }
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); 
2578
 
 
2579
 
#endif /* Xorriso_boot_dummY */
2580
 
 
2581
 
     }
2582
 
 
2583
 
#endif /* ! Xorriso_multi_booT */
2584
 
 
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);
2590
 
 
2591
 
       ret= Xorriso_path_from_lba(xorriso, NULL, xorriso->loaded_boot_bin_lba,
2592
 
                                   sfe, 1);
2593
 
       if(ret < 0)
2594
 
         goto ex;
2595
 
       if(ret == 0) {
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);
2605
 
         goto ex;
2606
 
       }
2607
 
       ret= Xorriso_set_isolinux_options(xorriso, image, 0);
2608
 
       if(ret <= 0)
2609
 
         goto ex;
2610
 
     } else {
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);
2614
 
     }
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);
2623
 
   }
2624
 
 }
2625
 
 
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;
2631
 
 
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);
2636
 
 }
2637
 
 
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);
2660
 
 if(image!=NULL &&
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, &micro);
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, &micro);
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, &micro);
2673
 
   if(strlen(xorriso_id)<80)
2674
 
     sprintf(xorriso_id+strlen(xorriso_id),
2675
 
             ", LIBBURN-%d.%d.%d", major, minor, micro);
2676
 
   xorriso_id[128]= 0;
2677
 
   img_id= (char *) iso_image_get_data_preparer_id(image);
2678
 
   if(img_id!=NULL) {
2679
 
     for(i= strlen(img_id)-1; i>=0 && img_id[i]==' '; i--);
2680
 
     if(i>0) {
2681
 
       sprintf(xorriso->info_text, "Overwrote previous preparer id '%s'",
2682
 
               img_id);
2683
 
       Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
2684
 
     }
2685
 
   }
2686
 
   iso_image_set_data_preparer_id(image, xorriso_id);
2687
 
 }
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,
2691
 
                    xorriso->vol_uuid);
2692
 
 
2693
 
 /* Make final abort check before starting expensive activities */
2694
 
 ret= Xorriso_eval_problem_status(xorriso, 1, 0);
2695
 
 if(ret<0)
2696
 
   {ret= 0; goto ex;}
2697
 
 
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);
2705
 
   if(ret<0) {
2706
 
     Xorriso_report_iso_error(xorriso, "", ret,
2707
 
              "Error when examining file content for zisofs headers",
2708
 
              0, "FAILURE", 1);
2709
 
   }
2710
 
   ret= Xorriso_eval_problem_status(xorriso, 1, 0);
2711
 
   if(ret<0)
2712
 
     {ret= 0; goto ex;}
2713
 
   sprintf(xorriso->info_text,
2714
 
           "Check for zisofs compression headers done.");
2715
 
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
2716
 
 }
2717
 
 
2718
 
 /* >>> omit iso_image_update_sizes if the image was filled up very quickly */;
2719
 
 
2720
 
 ret= iso_image_update_sizes(image);
2721
 
 if(ret < 0) {
2722
 
   Xorriso_process_msg_queues(xorriso, 0);
2723
 
   if(ret<0) {
2724
 
     Xorriso_report_iso_error(xorriso, "", ret,
2725
 
              "Error when updating file sizes",
2726
 
              0, "FAILURE", 1);
2727
 
   }
2728
 
   ret= Xorriso_eval_problem_status(xorriso, 1, 0);
2729
 
   if(ret<0)
2730
 
     {ret= 0; goto ex;}
2731
 
 }
2732
 
 
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);
2738
 
   if(ret>0) {
2739
 
     /* Allow the consumer of output to access the input drive */
2740
 
     source_drive= NULL;
2741
 
     ret= Xorriso_give_up_drive(xorriso, 1|8); 
2742
 
     if(ret<=0)
2743
 
       goto ex;
2744
 
   }
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);
2748
 
 } else {
2749
 
   ret= isoburn_prepare_new_image(source_drive, &disc, sopts, drive);
2750
 
 }
2751
 
 if(ret <= 0) {
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);
2755
 
   {ret= 0; goto ex;}
2756
 
 }
2757
 
 
2758
 
 ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0);
2759
 
 if(ret<=0)
2760
 
   goto ex;
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);
2766
 
 }
2767
 
 
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);
2776
 
   goto ex;
2777
 
 }
2778
 
 
2779
 
 ret= Xorriso_may_burn(xorriso, 0);
2780
 
 if(ret <= 0)
2781
 
   goto ex;
2782
 
 
2783
 
 /* Important: do not return until burn_is_aborting() was checked */
2784
 
 Xorriso_set_signal_handling(xorriso, 1);
2785
 
 
2786
 
 xorriso->run_state= 1; /* Indicate that burning has started */
2787
 
 isoburn_disc_write(burn_options, disc);
2788
 
 burn_write_opts_free(burn_options);
2789
 
 
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);
2794
 
 if(ret<=0)
2795
 
   goto ex;
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);
2802
 
   ret= 0; goto ex;
2803
 
 }
2804
 
 
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);
2816
 
   }
2817
 
 }
2818
 
 ret= isoburn_activate_session(drive);
2819
 
 Xorriso_process_msg_queues(xorriso,0);
2820
 
 if(ret<=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);
2824
 
   goto ex;
2825
 
 }
2826
 
 /* Done early to free any reference to the libisofs resources via disc */
2827
 
 if(disc!=NULL)
2828
 
   burn_disc_free(disc);
2829
 
 disc= NULL;
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);
2833
 
 
2834
 
 sprintf(xorriso->info_text, "Writing to %s completed sucessfully.\n\n",
2835
 
         Text_shellsafe(xorriso->outdev,sfe,0));
2836
 
 Xorriso_info(xorriso, 0);
2837
 
 ret= 1;
2838
 
ex:;
2839
 
 xorriso->run_state= 0; /* Indicate that burning has ended */
2840
 
 Xorriso_set_abort_severity(xorriso, 0);
2841
 
 
2842
 
 if(ret<=0) {
2843
 
 
2844
 
   /* >>> ??? revive discarded boot image */;
2845
 
 
2846
 
 }
2847
 
 if(disc!=NULL)
2848
 
   burn_disc_free(disc);
2849
 
 if(image != NULL)
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);
2854
 
 return(ret);
2855
 
2856
 
 
2857
 
 
2858
 
int Xorriso_check_burn_abort(struct XorrisO *xorriso, int flag)
2859
 
{
2860
 
 int ret;
2861
 
 struct burn_drive_info *dinfo;
2862
 
 struct burn_drive *drive;
2863
 
 
2864
 
 if(burn_is_aborting(0))
2865
 
   return(2);
2866
 
 if(xorriso->run_state!=1)
2867
 
   return(0);
2868
 
 ret= Xorriso_eval_problem_status(xorriso, 1, 1);
2869
 
 if(ret>=0)
2870
 
   return(0);
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);
2876
 
 
2877
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
2878
 
                                "on attempt to abort burn run", 2);
2879
 
 if(ret<=0)
2880
 
   return(0);
2881
 
 
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);
2886
 
 return(1);
2887
 
}
2888
 
 
2889
 
 
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
2893
 
                        0= xorriso
2894
 
                        1= mkisofs
2895
 
                        2= cdrecord
2896
 
               bit4= report speed in CD units
2897
 
               bit5= report speed in BD units
2898
 
*/
2899
 
int Xorriso_pacifier_loop(struct XorrisO *xorriso, struct burn_drive *drive,
2900
 
                          int flag)
2901
 
{
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;
2911
 
 
2912
 
 start_time= Sfile_microtime(0);
2913
 
 while(burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING)
2914
 
   usleep(100002);
2915
 
 
2916
 
 emul= flag&15;
2917
 
 fract_offset= 0.2 * (double) emul - ((int) (0.2 * (double) emul));
2918
 
 if(emul==0)
2919
 
   emul= xorriso->pacifier_style;
2920
 
 speed_unit= "D";
2921
 
 if(flag&16) {
2922
 
   speed_factor= 150.0*1024;
2923
 
   speed_unit= "C";
2924
 
 } else if(flag & 32) {
2925
 
   speed_factor= 4495625;
2926
 
   speed_unit= "B";
2927
 
 }
2928
 
 progress.sector= 0;
2929
 
 current_time= Sfile_microtime(0);
2930
 
 measured_speed= 0.0;
2931
 
 while(1) {
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)
2936
 
 break;
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);
2942
 
     buffer_fill= 50;
2943
 
     if(progress.buffer_capacity>0)
2944
 
       buffer_fill= (double) (progress.buffer_capacity
2945
 
                              - progress.buffer_available) * 100.0
2946
 
                    / (double) progress.buffer_capacity;
2947
 
     if(emul==2) {
2948
 
       if(progress.sector<=progress.sectors)
2949
 
         sprintf(xorriso->info_text, "%4d of %4d MB written",
2950
 
                 progress.sector / 512, progress.sectors / 512);
2951
 
       else
2952
 
         sprintf(xorriso->info_text, "%4d MB written",
2953
 
                 progress.sector / 512);
2954
 
 
2955
 
       if(xorriso->pacifier_fifo!=NULL)
2956
 
         ret= burn_fifo_inquire_status(xorriso->pacifier_fifo,
2957
 
                                       &size, &free_bytes, &status_text);
2958
 
       else
2959
 
         ret= isoburn_get_fifo_status(drive, &size, &free_bytes, &status_text);
2960
 
       if(ret>0 )
2961
 
         sprintf(xorriso->info_text+strlen(xorriso->info_text),
2962
 
                 " (fifo %2d%%)", 
2963
 
                 (int) (100.0-100.0*((double) free_bytes)/(double) size));
2964
 
 
2965
 
       sprintf(xorriso->info_text+strlen(xorriso->info_text), " [buf %3d%%]",
2966
 
               buffer_fill);
2967
 
 
2968
 
       if(current_time-last_time>0.2)
2969
 
         sprintf(xorriso->info_text+strlen(xorriso->info_text), "  %4.1fx.",
2970
 
                 measured_speed/speed_factor);
2971
 
 
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" */
2975
 
 
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;
2988
 
         }
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) {
2993
 
           norm= (1.0 - quot);
2994
 
           if(norm < 0.0001)
2995
 
             norm= 0.0001;
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);
3000
 
         } else {
3001
 
           time_prediction= (1.0 - quot) / quot * (current_time - start_time);
3002
 
           norm= 1.0;
3003
 
         }
3004
 
         if(base_time > 0 && 
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);
3009
 
           norm+= 1.0;
3010
 
         }
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);
3017
 
         }
3018
 
       }
3019
 
     } else {
3020
 
       if(progress.sector<=progress.sectors) {
3021
 
         if(progress.sectors <= 0)
3022
 
           strcpy(mem_text, " 99.9");
3023
 
         else
3024
 
           sprintf(mem_text, "%5.1f",
3025
 
             100.0 * ((double) progress.sector) / ((double) progress.sectors));
3026
 
         mem_text[5]= 0;
3027
 
         sprintf(xorriso->info_text, "Writing: %10ds  %s%% ",
3028
 
                 progress.sector, mem_text);
3029
 
       } else {
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);
3033
 
       }
3034
 
       ret= isoburn_get_fifo_status(drive, &size, &free_bytes, &status_text);
3035
 
       if(ret>0 )
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),
3039
 
                 buffer_fill);
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);
3043
 
     }
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);
3052
 
   else
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);
3057
 
 
3058
 
   for(i= 0; i<12; i++) { /* 2 usleeps more than supposed to be needed */
3059
 
     Xorriso_process_msg_queues(xorriso, 0);
3060
 
     if(aborting<=0)
3061
 
       aborting= Xorriso_check_burn_abort(xorriso, 0);
3062
 
     usleep(100000);
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)
3066
 
   break;
3067
 
   }
3068
 
 }
3069
 
 return(1);
3070
 
}
3071
 
 
3072
 
 
3073
 
int Xorriso__read_pacifier(IsoImage *image, IsoFileSource *filesource)
3074
 
{
3075
 
 struct XorrisO *xorriso;
3076
 
 
3077
 
 xorriso= (struct XorrisO *) iso_image_get_attached_data(image);
3078
 
 if(xorriso==NULL)
3079
 
   return(1);
3080
 
 Xorriso_process_msg_queues(xorriso,0);
3081
 
 xorriso->pacifier_count++;
3082
 
 if(xorriso->pacifier_count%10)
3083
 
   return(1);
3084
 
 Xorriso_pacifier_callback(xorriso, "nodes read", xorriso->pacifier_count, 0,
3085
 
                           "", 0);
3086
 
 return(1);
3087
 
}
3088
 
 
3089
 
/* @param flag    bit0=silently return 0 if no volume/image is present
3090
 
*/
3091
 
int Xorriso_get_volume(struct XorrisO *xorriso, IsoImage **volume,
3092
 
                       int flag)
3093
 
{
3094
 
 if(xorriso->in_volset_handle==NULL) {
3095
 
   if(flag & 1)
3096
 
     return(0);
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.");
3102
 
   else
3103
 
     sprintf(xorriso->info_text+strlen(xorriso->info_text),
3104
 
             " Possible program error with drive '%s'.", xorriso->indev);
3105
 
 
3106
 
   if(!xorriso->no_volset_present)
3107
 
     Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
3108
 
   xorriso->no_volset_present= 1;
3109
 
   return(0);
3110
 
 }
3111
 
 *volume= (IsoImage *) xorriso->in_volset_handle;
3112
 
 xorriso->no_volset_present= 0;
3113
 
 return(*volume != NULL);
3114
 
}
3115
 
 
3116
 
 
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)
3120
 
{
3121
 
 int ret;
3122
 
 char sfe[5*SfileadrL], *path_pt;
3123
 
 
3124
 
 path_pt= path;
3125
 
 if(path[0]==0)
3126
 
   path_pt= "/";
3127
 
 if(volume == NULL) {
3128
 
   ret= Xorriso_get_volume(xorriso, &volume, 0);
3129
 
   if(ret <= 0)
3130
 
     return(ret);
3131
 
 }
3132
 
 *node= NULL;
3133
 
 ret= iso_tree_path_to_node(volume, path_pt, node);
3134
 
 Xorriso_process_msg_queues(xorriso,0);
3135
 
 if(ret<=0 || (*node)==NULL) {
3136
 
   if(!(flag&1)) {
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);
3140
 
   }
3141
 
   return(0);
3142
 
 }
3143
 
 return(1);
3144
 
}
3145
 
 
3146
 
 
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
3159
 
*/
3160
 
int Xorriso_normalize_img_path(struct XorrisO *xorriso, char *wd,
3161
 
                               char *img_path, char eff_path[], int flag)
3162
 
{
3163
 
 int ret, is_dir= 0, done= 0;
3164
 
 IsoImage *volume;
3165
 
 IsoDir *dir= NULL;
3166
 
 IsoNode *node= NULL;
3167
 
 char path[SfileadrL], *apt, *npt, sfe[5*SfileadrL], *cpt;
3168
 
 
3169
 
 if((flag&64) || !(flag&2)) {
3170
 
   ret= Xorriso_get_volume(xorriso, &volume, 0);
3171
 
   if(ret<=0)
3172
 
     return(ret);
3173
 
 }
3174
 
 
3175
 
 eff_path[0]= 0;
3176
 
 if(img_path[0]==0) {
3177
 
   if(flag&8)
3178
 
     strcpy(eff_path, "/");
3179
 
   return(2); /* root directory */
3180
 
 }
3181
 
 
3182
 
 apt= npt= path;
3183
 
 if(img_path[0]!='/') {
3184
 
   strcpy(path, wd);
3185
 
   ret= Sfile_add_to_path(path, img_path, 0);
3186
 
   if(ret<=0)
3187
 
     goto much_too_long;
3188
 
 } else
3189
 
   if(Sfile_str(path, img_path, 0)<=0)
3190
 
     return(-1);
3191
 
 
3192
 
 if(path[0]!='/') {
3193
 
   sprintf(xorriso->info_text,
3194
 
        "Internal error: Unresolvable relative addressing in iso_rr_path '%s'",
3195
 
        img_path);
3196
 
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FATAL", 0);
3197
 
   return(-1);
3198
 
 } else if(path[1]==0) {
3199
 
   if(flag&8)
3200
 
     strcpy(eff_path, "/");
3201
 
   return(2); /* root directory */
3202
 
 }
3203
 
 
3204
 
 for(npt= apt; !done; apt= npt+1) {
3205
 
   npt= strchr(apt, '/');
3206
 
   if(npt==NULL) {
3207
 
     npt= apt+strlen(apt);
3208
 
     done= 1;
3209
 
   } else
3210
 
     *npt= 0;
3211
 
   if(*apt==0) {
3212
 
     *apt= '/';
3213
 
     apt++;
3214
 
     if(done)
3215
 
 break;
3216
 
 continue;
3217
 
   }
3218
 
   if(strcmp(apt,".")==0) {
3219
 
     is_dir= 1;
3220
 
 continue;
3221
 
   }
3222
 
   if(strcmp(apt,"..")==0) {
3223
 
     if(!(flag&2)) {
3224
 
       node= (IsoNode *) dir;
3225
 
       if(node==NULL) {
3226
 
bonked_root:;
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);
3231
 
         return(-1);
3232
 
       }
3233
 
       dir= iso_node_get_parent(node);
3234
 
     }
3235
 
     /* truncate eff_path */;
3236
 
     cpt= strrchr(eff_path, '/');
3237
 
     if(cpt==NULL) /* ??? if not flag&2 then this is a bug */
3238
 
       goto bonked_root;
3239
 
     *cpt= 0;
3240
 
     is_dir= 1;
3241
 
 continue;
3242
 
   }
3243
 
   ret= Sfile_add_to_path(eff_path, apt, 0);
3244
 
   if(ret<=0) {
3245
 
much_too_long:;
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);
3249
 
     return(-1);
3250
 
   }
3251
 
   if(!(flag&2)) {
3252
 
     dir= (IsoDir *) node;
3253
 
     ret= Xorriso_node_from_path(xorriso, volume, eff_path, &node, flag&1);
3254
 
     if(ret<=0) 
3255
 
       return(0);
3256
 
     if(dir==NULL) /* could be false with  "/dir/.." */
3257
 
       dir= iso_node_get_parent(node);
3258
 
     is_dir= LIBISO_ISDIR(node);
3259
 
   }
3260
 
 }
3261
 
 if(flag&16) {
3262
 
   ret= Sfile_type(eff_path,
3263
 
    1|(4*(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&32)))
3264
 
                  ));
3265
 
   if(ret<0)
3266
 
     return(0);
3267
 
   if(ret==2)
3268
 
     is_dir= 1;
3269
 
 }
3270
 
 return(1+!!is_dir);
3271
 
}
3272
 
 
3273
 
 
3274
 
int Xorriso_get_node_by_path(struct XorrisO *xorriso,
3275
 
                             char *in_path, char *eff_path,
3276
 
                             IsoNode **node, int flag)
3277
 
{
3278
 
 int ret;
3279
 
 char path[SfileadrL];
3280
 
 IsoImage *volume;
3281
 
 
3282
 
 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, in_path, path, 0);
3283
 
 if(ret<=0)
3284
 
   return(ret);
3285
 
 if(eff_path!=NULL)
3286
 
   strcpy(eff_path, path);
3287
 
 ret= Xorriso_get_volume(xorriso, &volume, 0);
3288
 
 if(ret<=0)
3289
 
   return(ret);
3290
 
 ret= Xorriso_node_from_path(xorriso, volume, path, node, 0);
3291
 
 if(ret<=0)
3292
 
   return(0);
3293
 
 return(1);
3294
 
}
3295
 
 
3296
 
 
3297
 
/* @param flag
3298
 
*/
3299
 
int Xorriso_node_get_dev(struct XorrisO *xorriso, IsoNode *node,
3300
 
                         char *path, dev_t *dev, int flag)
3301
 
{
3302
 
 *dev= iso_special_get_dev((IsoSpecial *) node);
3303
 
 return(1);
3304
 
}
3305
 
 
3306
 
 
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
3312
 
                     are enabled
3313
 
*/
3314
 
int Xorriso_fake_stbuf(struct XorrisO *xorriso, char *path, struct stat *stbuf,
3315
 
                       IsoNode **node, int flag)
3316
 
{
3317
 
 int ret, min_hl, max_hl, node_idx, i;
3318
 
 IsoImage *volume;
3319
 
 
3320
 
 memset((char *) stbuf, 0, sizeof(struct stat));
3321
 
 if(!(flag&1)) {
3322
 
   ret= Xorriso_get_volume(xorriso, &volume, 0);
3323
 
   if(ret<=0)
3324
 
     return(-1);
3325
 
   ret= Xorriso_node_from_path(xorriso, volume, path, node, !(flag&4));
3326
 
   if(ret<=0)
3327
 
     *node= NULL;
3328
 
 }
3329
 
 if(*node==NULL)
3330
 
   return(0);
3331
 
 
3332
 
 /* >>> stbuf->st_dev */
3333
 
 /* >>> stbuf->st_ino */
3334
 
 
3335
 
 if(flag & 8)
3336
 
   stbuf->st_mode= iso_node_get_perms_wo_acl(*node) & 07777;
3337
 
 else
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;
3357
 
 
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 */
3361
 
 stbuf->st_nlink= 1;
3362
 
 
3363
 
 stbuf->st_uid= iso_node_get_uid(*node);
3364
 
 stbuf->st_gid= iso_node_get_gid(*node);
3365
 
 
3366
 
 if(LIBISO_ISREG(*node))
3367
 
   stbuf->st_size= iso_file_get_size((IsoFile *) *node)+ (2048 * !!(flag&2));
3368
 
 else
3369
 
   stbuf->st_size= 0;
3370
 
 
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)
3374
 
   stbuf->st_blocks++; 
3375
 
 
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);
3379
 
 
3380
 
 if(LIBISO_ISDIR(*node) || (xorriso->ino_behavior & 1) || (!(flag & 16)) ||
3381
 
    xorriso->hln_array == NULL)
3382
 
   return(1);
3383
 
 
3384
 
 /* Try to obtain a better link count */
3385
 
 ret= Xorriso_search_hardlinks(xorriso, *node, &node_idx, &min_hl, &max_hl, 0);
3386
 
 if(ret < 0)
3387
 
   return(ret);
3388
 
 if(ret > 0 && node_idx >= 0) {
3389
 
   for(i= min_hl; i <= max_hl; i++) {
3390
 
     if(i == node_idx)
3391
 
   continue;
3392
 
     /* Check whether node is still valid */
3393
 
     if(iso_node_get_parent(xorriso->hln_array[i]) != NULL)
3394
 
       stbuf->st_nlink++;
3395
 
   }
3396
 
 }
3397
 
 return(1);
3398
 
}
3399
 
 
3400
 
 
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
3404
 
*/
3405
 
int Xorriso_iso_lstat(struct XorrisO *xorriso, char *path, struct stat *stbuf,
3406
 
                      int flag)
3407
 
{
3408
 
 int ret;
3409
 
 IsoNode *node;
3410
 
 
3411
 
 if(flag&1) {
3412
 
 
3413
 
   /* >>> follow link in ISO image */;
3414
 
 
3415
 
 }
3416
 
 
3417
 
 ret= Xorriso_fake_stbuf(xorriso, path, stbuf, &node, flag&4);
3418
 
 if(ret>0)
3419
 
   return(0);
3420
 
 if(ret<0 && !(flag&2))
3421
 
   return(-2);
3422
 
 return(-1);
3423
 
}
3424
 
 
3425
 
 
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
3430
 
*/
3431
 
int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf,
3432
 
                               char *disk_path,  IsoNode *node, int flag)
3433
 
{
3434
 
 mode_t mode;
3435
 
 int ret= 1;
3436
 
 size_t num_attrs= 0, *value_lengths= NULL;
3437
 
 char **names= NULL, **values= NULL;
3438
 
 
3439
 
 mode= stbuf->st_mode;
3440
 
 
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);
3444
 
 
3445
 
 if((flag&1) && S_ISDIR(mode)) {
3446
 
   if(mode&S_IRUSR)
3447
 
     mode|= S_IXUSR;
3448
 
   if(mode&S_IRGRP)
3449
 
     mode|= S_IXGRP;
3450
 
   if(mode&S_IROTH)
3451
 
     mode|= S_IXOTH;
3452
 
 }
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);
3459
 
 
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)
3464
 
                                     | (flag & 32));
3465
 
   if(ret < 0) { 
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,
3469
 
                              "FAILURE", 1 | 2);
3470
 
     ret= 0; goto ex;
3471
 
   }
3472
 
   ret= iso_node_set_attrs(node, num_attrs, names, value_lengths, values,
3473
 
                           1 | 8);
3474
 
   if(ret < 0) {
3475
 
     Xorriso_process_msg_queues(xorriso,0);
3476
 
     Xorriso_report_iso_error(xorriso, "", ret,
3477
 
                              "Error when setting ACL and xattr to image node",
3478
 
                              0, "FAILURE", 1);
3479
 
     ret= 0; goto ex;
3480
 
   }
3481
 
 }
3482
 
 
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);
3486
 
   if(ret <= 0)
3487
 
     goto ex;
3488
 
 }
3489
 
 
3490
 
 ret= 1;
3491
 
ex:;
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 */
3495
 
 return(ret);
3496
 
}
3497
 
 
3498
 
 
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)
3503
 
{
3504
 
 int ret;
3505
 
 IsoDir *new_dir= NULL;
3506
 
 IsoNode *part_node;
3507
 
 int partno, total_parts;
3508
 
 off_t offset;
3509
 
 char part_name[SfileadrL], sfe[5*SfileadrL];
3510
 
 
3511
 
 ret= iso_tree_add_new_dir(dir, img_name, &new_dir);
3512
 
 if(ret<0)
3513
 
   return(ret);
3514
 
 *node= (IsoNode *) new_dir;
3515
 
 total_parts= size / xorriso->split_size;
3516
 
 if(size % xorriso->split_size)
3517
 
   total_parts++;
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,
3526
 
                                &part_node, 8);
3527
 
   if(ret<=0)
3528
 
     return(0);
3529
 
 }
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);
3533
 
 return(1);
3534
 
}
3535
 
 
3536
 
 
3537
 
/* 
3538
 
   @param flag bit3= cut_out_node: offset and size are valid
3539
 
*/
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)
3545
 
{
3546
 
 int ret, stbuf_valid= 0;
3547
 
 struct stat stbuf;
3548
 
 char sfe[5*SfileadrL];
3549
 
 off_t size= 0;
3550
 
 
3551
 
 if(lstat(disk_path, &stbuf) != -1) {
3552
 
   stbuf_valid= 1;
3553
 
   if(S_ISREG(stbuf.st_mode))
3554
 
     size= stbuf.st_size;
3555
 
 }
3556
 
 if(flag&8)  {
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);
3563
 
     return(0);
3564
 
   }
3565
 
   ret= iso_tree_add_new_cut_out_node(volume, dir, img_name, disk_path,
3566
 
                                      offset, cut_size, node);
3567
 
   if(ret<0)
3568
 
     goto ex;
3569
 
 } else {
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,
3573
 
                              node, 0);
3574
 
     if(ret<=0)
3575
 
       goto ex;
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);
3582
 
     return(0);
3583
 
   } else {
3584
 
     ret= iso_tree_add_new_node(volume, dir, img_name, disk_path, node);
3585
 
     if(ret<0)
3586
 
       goto ex;
3587
 
   }
3588
 
 }
3589
 
 
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);
3593
 
   if(ret <= 0)
3594
 
     goto ex;
3595
 
 }
3596
 
 
3597
 
ex:;
3598
 
 if(ret<0) {
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);
3602
 
   return(ret);
3603
 
 }
3604
 
 if(LIBISO_ISREG(*node))
3605
 
   xorriso->pacifier_byte_count+= iso_file_get_size((IsoFile *) *node);
3606
 
 return(1);
3607
 
}
3608
 
 
3609
 
 
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
3614
 
*/
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)
3618
 
{
3619
 
 IsoImage *volume;
3620
 
 IsoNode *node;
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;
3626
 
 dev_t dir_dev;
3627
 
 struct LinkiteM *own_link_stack;
3628
 
 char *sfe= NULL, *sfe2= NULL;
3629
 
 char *disk_path= NULL, *img_path= NULL, *link_target= NULL;
3630
 
 
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);
3640
 
   {ret= -1; goto ex;}
3641
 
 }
3642
 
 
3643
 
 own_link_stack= link_stack;
3644
 
 
3645
 
 ret= Xorriso_get_volume(xorriso, &volume, 0);
3646
 
 if(ret<=0)
3647
 
   goto ex;
3648
 
 
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))))
3655
 
     {ret= 2; goto ex;}
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))))
3661
 
     {ret= 2; goto ex;}
3662
 
 }
3663
 
 ret= Dirseq_new(&dirseq, disk_dir_path, 1);
3664
 
 if(ret<0) {
3665
 
   sprintf(xorriso->info_text,"Failed to create source filesystem iterator");
3666
 
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
3667
 
   {ret= -1; goto ex;}
3668
 
 }
3669
 
 if(ret==0) {
3670
 
cannot_open_dir:;
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);
3675
 
   {ret= 0; goto ex;}
3676
 
 }
3677
 
 
3678
 
 if(Sfile_str(disk_path, disk_dir_path,0)<=0)
3679
 
   {ret= -1; goto ex;}
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)
3684
 
   {ret= -1; goto ex;}
3685
 
 if(img_path[0] || img_path[strlen(img_path)-1]!='/')
3686
 
   strcat(img_path,"/");
3687
 
 img_name= img_path+strlen(img_path);
3688
 
 
3689
 
 while(1) { /* loop over directory content */
3690
 
   stbuf_src= "";
3691
 
   Linkitem_reset_stack(&own_link_stack, link_stack, 0);
3692
 
   srcpt= disk_path;
3693
 
   Xorriso_process_msg_queues(xorriso,0);
3694
 
   ret= Dirseq_next_adr(dirseq,name,0); /* name is a pointer into disk_path */
3695
 
   if(ret==0)
3696
 
 break;
3697
 
   if(ret<0) {
3698
 
     sprintf(xorriso->info_text,"Failed to obtain next directory entry");
3699
 
     Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
3700
 
     {ret= -1; goto ex;}
3701
 
   }
3702
 
 
3703
 
   /* compare exclusions against disk_path resp. name */
3704
 
   ret= Xorriso_path_is_excluded(xorriso, disk_path, 0); /* (is never param) */
3705
 
   if(ret<0)
3706
 
     {ret= -1; goto ex;}
3707
 
   if(ret>0)
3708
 
 continue;
3709
 
 
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;}
3715
 
   stbuf_src= srcpt;
3716
 
   if(lstat(srcpt, &stbuf)==-1) {
3717
 
cannot_lstat:;
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;
3724
 
   }
3725
 
   source_is_dir= 0;
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);
3730
 
     if(ret<0)
3731
 
       goto was_problem;
3732
 
     if(ret==1) {
3733
 
       ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 0);
3734
 
       if(ret<=0)
3735
 
         goto was_problem;
3736
 
       srcpt= link_target;
3737
 
       stbuf_src= srcpt;
3738
 
       if(lstat(srcpt, &stbuf)==-1)
3739
 
         goto cannot_lstat;
3740
 
     } else {
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);
3744
 
       if(ret<=0)
3745
 
         goto was_problem;
3746
 
     }
3747
 
   } else if (S_ISLNK(stbuf.st_mode)) {
3748
 
     ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1);
3749
 
     if(ret<=0)
3750
 
       goto was_problem;
3751
 
   }
3752
 
   do_not_dive= 0;
3753
 
   if(S_ISDIR(stbuf.st_mode)) {
3754
 
     source_is_dir= 1;
3755
 
     if(dir_dev != stbuf.st_dev && !xorriso->do_follow_mount)
3756
 
       do_not_dive= 1;
3757
 
   }
3758
 
 
3759
 
   /* does a node exist with this name ? */
3760
 
   node= NULL;
3761
 
   ret= Xorriso_node_from_path(xorriso, volume, img_path, &node, 1);
3762
 
   if(ret>0) {
3763
 
     target_is_dir= LIBISO_ISDIR(node);
3764
 
     target_is_split= 0;
3765
 
     if(target_is_dir && !(flag & 128))
3766
 
       target_is_split= Xorriso_is_split(xorriso, "", (void *) node, 1 | 2);
3767
 
 
3768
 
     if(!((target_is_dir && !target_is_split) && source_is_dir)) {
3769
 
       Xorriso_process_msg_queues(xorriso,0);
3770
 
 
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));
3776
 
         if(ret<=0)
3777
 
           goto was_problem;
3778
 
         if(ret==3) {
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;
3783
 
         }
3784
 
         node= NULL;
3785
 
       } else {
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;
3792
 
       }
3793
 
     }
3794
 
   }
3795
 
 
3796
 
   if(node==NULL) {
3797
 
     ret= Xorriso_tree_graft_node(xorriso, volume, dir, srcpt, img_name,
3798
 
                                  "", img_path, (off_t) 0, (off_t) 0,
3799
 
                                  &node, 0);
3800
 
   }
3801
 
   if(node==NULL) {
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;
3808
 
   }
3809
 
 
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);
3814
 
 
3815
 
   Xorriso_set_change_pending(xorriso, 0);
3816
 
   if(source_is_dir) {
3817
 
     if(do_not_dive) {
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);
3821
 
     } else {
3822
 
       ret= Xorriso_add_tree(xorriso, (IsoDir *) node,
3823
 
                             img_path, disk_path, own_link_stack,
3824
 
                             1 | (flag & (2 | 64 | 128)));
3825
 
     }
3826
 
     if(ret<=0)
3827
 
       goto was_problem;
3828
 
   }
3829
 
 
3830
 
 continue; /* regular bottom of loop */
3831
 
was_problem:;
3832
 
   was_failure= 1;
3833
 
   fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
3834
 
   if(fret<0)
3835
 
     goto ex;
3836
 
 }
3837
 
 
3838
 
 ret= 1;
3839
 
ex:
3840
 
 if(sfe!=NULL)
3841
 
   free(sfe);
3842
 
 if(sfe2!=NULL)
3843
 
   free(sfe2);
3844
 
 if(disk_path!=NULL)
3845
 
   free(disk_path);
3846
 
 if(img_path!=NULL)
3847
 
   free(img_path);
3848
 
 if(link_target!=NULL)
3849
 
   free(link_target);
3850
 
 Xorriso_process_msg_queues(xorriso,0);
3851
 
 Linkitem_reset_stack(&own_link_stack, link_stack, 0);
3852
 
 Dirseq_destroy(&dirseq, 0);
3853
 
 if(ret<=0)
3854
 
   return(ret);
3855
 
 return(!was_failure);
3856
 
}
3857
 
 
3858
 
 
3859
 
/* @param flag bit0= cut_out mode : base on leaf parent directory
3860
 
*/
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)
3863
 
{
3864
 
 int ret, nfic, nic, nfdc, d, i;
3865
 
 char nfi[SfileadrL], ni[SfileadrL], nfd[SfileadrL], *cpt;
3866
 
 char sfe[5*SfileadrL];
3867
 
 struct stat stbuf;
3868
 
 
3869
 
 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, full_img_path, nfi,
3870
 
                                 1|2);
3871
 
 if(ret<=0)
3872
 
   return(ret);
3873
 
 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, img_path, ni, 1|2);
3874
 
 if(ret<=0)
3875
 
   return(ret);
3876
 
 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, full_disk_path, nfd,
3877
 
                                 1|2|4);
3878
 
 if(ret<=0)
3879
 
   return(ret);
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;
3884
 
 if(d<0)
3885
 
   return(-1);
3886
 
 if(d>nfdc)
3887
 
   return(0);
3888
 
 for(i= 0; i<d; i++) {
3889
 
   cpt= strrchr(nfd, '/');
3890
 
   if(cpt==NULL)
3891
 
     return(-1); /* should not happen */
3892
 
   *cpt= 0;
3893
 
 }
3894
 
 if(nfd[0]==0)
3895
 
   strcpy(nfd, "/");
3896
 
 if(stat(nfd, &stbuf)==-1)
3897
 
   return(0);
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);
3906
 
 return(1);
3907
 
}
3908
 
 
3909
 
 
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)
3913
 
*/
3914
 
int Xorriso_copy_properties(struct XorrisO *xorriso,
3915
 
                            char *disk_path, char *img_path, int flag)
3916
 
{
3917
 
 int ret;
3918
 
 IsoNode *node;
3919
 
 struct stat stbuf;
3920
 
 
3921
 
 ret= Xorriso_get_node_by_path(xorriso, img_path, NULL, &node, 0);
3922
 
 if(ret<=0)
3923
 
   return(ret);
3924
 
 if(flag & 1) {
3925
 
   if(stat(disk_path, &stbuf)==-1)
3926
 
     return(0);
3927
 
 } else {
3928
 
   if(lstat(disk_path, &stbuf)==-1)
3929
 
     return(0);
3930
 
 }
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);
3934
 
 return(1);
3935
 
}
3936
 
 
3937
 
 
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 ,
3949
 
                         3 = rejected 
3950
 
*/
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)
3954
 
{
3955
 
 IsoImage *volume;
3956
 
 char path[SfileadrL], *apt, *npt, *cpt, sfe[5*SfileadrL], sfe2[5*SfileadrL];
3957
 
 char *disk_path_pt, resolved_disk_path[SfileadrL];
3958
 
 IsoDir *dir, *hdir;
3959
 
 IsoNode *node;
3960
 
 int done= 0, is_dir= 0, l, ret, target_is_dir, source_is_dir, resolve_link= 0;
3961
 
 int target_is_split;
3962
 
 struct stat stbuf;
3963
 
 
3964
 
 ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&4));
3965
 
 if(ret<0)
3966
 
   return(ret);
3967
 
 if(ret>0)
3968
 
   return(3*!!(flag&16));
3969
 
 
3970
 
 for(cpt= img_path; 1; cpt++) {
3971
 
   cpt= strstr(cpt,"/.");
3972
 
   if(cpt==NULL)
3973
 
 break;
3974
 
   if(cpt[2]=='.') {
3975
 
     if(cpt[3]=='/' || cpt[3]==0)
3976
 
 break;
3977
 
   } else if(cpt[2]=='/' || cpt[2]==0)
3978
 
 break;
3979
 
 }
3980
 
 if(cpt!=NULL) {
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);
3986
 
   return(0);
3987
 
 }
3988
 
 
3989
 
 ret= Xorriso_get_volume(xorriso, &volume, 0);
3990
 
 if(ret<=0)
3991
 
   return(ret);
3992
 
 
3993
 
 strncpy(path, img_path, sizeof(path)-1);
3994
 
 path[sizeof(path)-1]= 0;
3995
 
 apt= npt= path;
3996
 
 
3997
 
 if(!(flag&1)) {
3998
 
   ret= lstat(disk_path, &stbuf);
3999
 
   if(ret!=-1) {
4000
 
     if(S_ISDIR(stbuf.st_mode))
4001
 
       is_dir= 1;
4002
 
     else if((stbuf.st_mode&S_IFMT)==S_IFLNK &&
4003
 
             (xorriso->do_follow_links ||
4004
 
              (xorriso->do_follow_param && !(flag&4)))) {
4005
 
       resolve_link= 1;
4006
 
       ret= stat(disk_path, &stbuf);
4007
 
       if(ret!=-1) {
4008
 
         if(S_ISDIR(stbuf.st_mode))
4009
 
           is_dir= 1;
4010
 
       }
4011
 
     }
4012
 
   }
4013
 
   if(ret == -1) {
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);
4020
 
     return(0);
4021
 
   }
4022
 
   if(S_ISDIR(stbuf.st_mode)) {
4023
 
     is_dir= 1;
4024
 
   } else {
4025
 
     l= strlen(img_path);
4026
 
     if(l>0)
4027
 
       if(img_path[l-1]=='/')
4028
 
         l= 0;
4029
 
     if(l==0) {
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);
4035
 
       return(0);
4036
 
     }
4037
 
   }
4038
 
 }
4039
 
 
4040
 
 dir= iso_image_get_root(volume);
4041
 
 if(dir==NULL) {
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);
4046
 
   return(0);
4047
 
 }
4048
 
 for(npt= apt; !done; apt= npt+1) {
4049
 
   npt= strchr(apt, '/');
4050
 
   if(npt==NULL) {
4051
 
     npt= apt+strlen(apt);
4052
 
     done= 1;
4053
 
   } else
4054
 
     *npt= 0;
4055
 
   if(*apt==0) {
4056
 
     *apt= '/';
4057
 
     apt++;
4058
 
     if(done)
4059
 
       goto attach_source;
4060
 
 continue;
4061
 
   }
4062
 
   source_is_dir= (is_dir || (flag&1) || !done);
4063
 
   ret= Xorriso_node_from_path(xorriso, volume, path, &node, 1);
4064
 
   if(ret>0) {
4065
 
     target_is_dir= LIBISO_ISDIR(node);
4066
 
 
4067
 
     target_is_split= 0;
4068
 
     if(target_is_dir && !(flag & 128))
4069
 
       target_is_split= Xorriso_is_split(xorriso, "", (void *) node, 1 | 2);
4070
 
 
4071
 
     if(!((target_is_dir && !target_is_split) && source_is_dir)) {
4072
 
       Xorriso_process_msg_queues(xorriso,0);
4073
 
 
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));
4079
 
         if(ret<=0)
4080
 
           return(ret);
4081
 
         if(ret==3) {
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));
4086
 
         }
4087
 
         node= NULL;
4088
 
         goto handle_path_node;
4089
 
       }
4090
 
 
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",
4094
 
              img_path, path);
4095
 
       Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
4096
 
       return(0);
4097
 
     }
4098
 
     dir= (IsoDir *) node;
4099
 
   }
4100
 
 
4101
 
handle_path_node:;
4102
 
   if(node==NULL && source_is_dir) { /* make a directory */
4103
 
     ret= iso_tree_add_new_dir(dir, apt, &hdir);
4104
 
     if(ret<0) {
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);
4112
 
       return(0);
4113
 
     }
4114
 
     dir= hdir;
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());
4119
 
 
4120
 
     if(disk_path!=NULL && !done)
4121
 
       Xorriso_copy_implicit_properties(xorriso, dir, img_path, path, disk_path,
4122
 
                                       !!(flag&8));
4123
 
 
4124
 
   }
4125
 
   if(done) {
4126
 
attach_source:;
4127
 
     if(flag&1) {
4128
 
       /* directory node was created above */;
4129
 
 
4130
 
     } else if(is_dir) {
4131
 
       Xorriso_transfer_properties(xorriso, &stbuf, disk_path,
4132
 
                                   (IsoNode *) dir, 4 | 32);
4133
 
       if(!(flag&32)) {
4134
 
         ret= Xorriso_add_tree(xorriso, dir, img_path, disk_path, NULL,
4135
 
                               flag & (2 | 64 | 128));
4136
 
         if(ret<=0)
4137
 
           return(ret);
4138
 
       }
4139
 
     } else {
4140
 
       if(resolve_link) {
4141
 
         ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0);
4142
 
         if(ret<=0)
4143
 
           return(ret);
4144
 
         disk_path_pt= resolved_disk_path;
4145
 
       } else
4146
 
         disk_path_pt= disk_path;
4147
 
 
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);
4151
 
       if(ret<=0) {
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);
4155
 
         return(0);
4156
 
       }
4157
 
       Xorriso_set_change_pending(xorriso, 0);
4158
 
       iso_node_set_name(node, apt);
4159
 
 
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);
4165
 
     }
4166
 
   } else
4167
 
     *npt= '/';
4168
 
 }
4169
 
 Xorriso_process_msg_queues(xorriso,0);
4170
 
 return(1+!!is_dir);
4171
 
}
4172
 
 
4173
 
 
4174
 
/* @param flag bit0= -follow: disk_path is not a command parameter
4175
 
*/
4176
 
int Xorriso_cut_out(struct XorrisO *xorriso, char *disk_path,
4177
 
                off_t startbyte, off_t bytecount, char *iso_rr_path, int flag)
4178
 
{
4179
 
 int ret;
4180
 
 char eff_source[SfileadrL], eff_dest[SfileadrL], sfe[SfileadrL*5];
4181
 
 struct stat stbuf;
4182
 
 
4183
 
 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_source,
4184
 
                                 2|4);
4185
 
 if(ret<=0)
4186
 
   return(ret);
4187
 
 ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&1));
4188
 
 if(ret!=0)
4189
 
   return(0);
4190
 
 
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);
4196
 
   return(0);
4197
 
 }
4198
 
 
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);
4208
 
     return(0);
4209
 
   }
4210
 
 }
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);
4218
 
     return(0);
4219
 
   }
4220
 
 } else {
4221
 
unsupported_type:;
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);
4226
 
   return(0);
4227
 
 }
4228
 
 
4229
 
 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, iso_rr_path, eff_dest,
4230
 
                                 2);
4231
 
 if(ret<=0)
4232
 
   return(ret);
4233
 
 
4234
 
 ret= Xorriso_graft_in(xorriso, NULL, eff_source, eff_dest,
4235
 
                       startbyte, bytecount, 8);
4236
 
 return(ret);
4237
 
}
4238
 
 
4239
 
 
4240
 
/* @param flag bit0= in_node is valid, do not resolve img_path
4241
 
               bit1= test mode: print DEBUG messages
4242
 
   @return  <0 = error,
4243
 
             0 = surely not identical regular files ,
4244
 
             1 = surely identical
4245
 
             2 = potentially depending on unknown disk file (e.g. -cut_out)
4246
 
*/
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)
4250
 
{
4251
 
 int ret;
4252
 
 unsigned int fs_id;
4253
 
 dev_t dev_id;
4254
 
 ino_t ino_id;
4255
 
 IsoStream *stream;
4256
 
 IsoImage *volume;
4257
 
 IsoNode *node;
4258
 
 struct stat stbuf;
4259
 
 int dummy;
4260
 
 
4261
 
 memset(type_text, 0, 5);
4262
 
 if(!xorriso->volset_change_pending)
4263
 
   return(0);
4264
 
 if(flag&1) {
4265
 
   node= (IsoNode *) in_node;
4266
 
 } else {
4267
 
   ret= Xorriso_get_volume(xorriso, &volume, 0);
4268
 
   if(ret<=0)
4269
 
     return(-1);
4270
 
   ret= Xorriso_node_from_path(xorriso, volume, img_path, &node, 1);
4271
 
   if(ret<=0)
4272
 
     return(-1);
4273
 
 }
4274
 
 ret= Xorriso__file_start_lba(node, &dummy, 0);
4275
 
 if(ret != 0) {
4276
 
   Xorriso_process_msg_queues(xorriso, 0);
4277
 
   return(0);
4278
 
 }
4279
 
 if(!LIBISO_ISREG(node))
4280
 
   return(0);
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);
4284
 
 if(flag&2) {
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);
4288
 
 }
4289
 
 ret= stat(disk_path, &stbuf);
4290
 
 if(ret==-1)
4291
 
   return(0);
4292
 
 if(flag&2) {
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);
4296
 
 }
4297
 
 if(fs_id!=1)
4298
 
   return(2);
4299
 
 
4300
 
 /* >>> obtain underlying dev_t ino_t of type "cout" */;
4301
 
 
4302
 
 if(strcmp(type_text, "fsrc")!=0)
4303
 
   return(2);
4304
 
 if(stbuf.st_dev==dev_id && stbuf.st_ino==ino_id)
4305
 
   return(1);
4306
 
 return(0);
4307
 
}
4308
 
 
4309
 
 
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
4313
 
*/
4314
 
int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path,
4315
 
                                IsoNode *node, int flag)
4316
 
{
4317
 
 int ret, is_dir= 0;
4318
 
 mode_t mode;
4319
 
 uid_t uid;
4320
 
 gid_t gid;
4321
 
 struct utimbuf utime_buffer;
4322
 
 char sfe[5*SfileadrL];
4323
 
 struct stat stbuf;
4324
 
 size_t num_attrs= 0, *value_lengths= NULL;
4325
 
 char **names= NULL, **values= NULL;
4326
 
 
4327
 
 ret= lstat(disk_path, &stbuf);
4328
 
 if(ret==-1) {
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);
4333
 
   {ret= 0; goto ex;}
4334
 
 }
4335
 
 uid= stbuf.st_uid;
4336
 
 
4337
 
 is_dir= S_ISDIR(stbuf.st_mode);
4338
 
 
4339
 
 mode= iso_node_get_permissions(node);
4340
 
 
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);
4344
 
   if (ret < 0) {
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);
4348
 
     {ret= 0; goto ex;}
4349
 
   }
4350
 
   if(num_attrs > 0) {
4351
 
     ret= iso_local_set_attrs(disk_path, num_attrs, names, value_lengths,
4352
 
                              values, 0);
4353
 
     if(ret < 0) {
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);
4358
 
       {ret= 0; goto ex;}
4359
 
     }
4360
 
   }
4361
 
   Xorriso_process_msg_queues(xorriso,0);
4362
 
 }
4363
 
 if(!(xorriso->do_aaip & 2))
4364
 
   mode= iso_node_get_perms_wo_acl(node);
4365
 
 
4366
 
 if(is_dir && (flag&2)) {
4367
 
   ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node,
4368
 
                           1 | ((!!(xorriso->do_aaip & 2)) << 3));
4369
 
   if(ret<=0)
4370
 
     {ret= 0; goto ex;}
4371
 
   ret= Permstack_push(&(xorriso->perm_stack), disk_path, &stbuf, 0);
4372
 
   if(ret<=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);
4377
 
     {ret= -1; goto ex;}
4378
 
   }
4379
 
   mode|= S_IRUSR|S_IWUSR|S_IXUSR;
4380
 
 }
4381
 
 ret= chmod(disk_path, mode);
4382
 
 if(ret==-1) {
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);
4387
 
   {ret= 0; goto ex;}
4388
 
 }
4389
 
 
4390
 
 if(flag&1)
4391
 
   {ret= 1; goto ex;}
4392
 
 
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);
4400
 
 if(ret==-1) {
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);
4405
 
   {ret= 0; goto ex;}
4406
 
 }
4407
 
 ret= 1;
4408
 
ex:;
4409
 
 iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values,1 << 15);
4410
 
 return(ret);
4411
 
}
4412
 
 
4413
 
 
4414
 
/* @param flag
4415
 
               bit1= minimal transfer: access permissions only
4416
 
               bit2= keep directory open: keep owner, allow rwx for owner
4417
 
                     push to xorriso->perm_stack
4418
 
*/
4419
 
int Xorriso_restore_implicit_properties(struct XorrisO *xorriso,
4420
 
          char *full_disk_path, char *disk_path, char *full_img_path, int flag)
4421
 
{
4422
 
 int ret, nfic, ndc, nfdc, d, i;
4423
 
 char nfi[SfileadrL], nd[SfileadrL], nfd[SfileadrL], *cpt;
4424
 
 char sfe[5*SfileadrL];
4425
 
 struct stat stbuf;
4426
 
 IsoNode *node;
4427
 
 
4428
 
 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, full_disk_path, nfd,
4429
 
                                 1|2|4);
4430
 
 if(ret<=0)
4431
 
   return(ret);
4432
 
 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, nd, 1|2);
4433
 
 if(ret<=0)
4434
 
   return(ret);
4435
 
 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, full_img_path, nfi,
4436
 
                                 1|2);
4437
 
 if(ret<=0)
4438
 
   return(ret);
4439
 
 nfdc= Sfile_count_components(nfd, 0);
4440
 
 ndc= Sfile_count_components(nd, 0);
4441
 
 nfic= Sfile_count_components(nfi, 0);
4442
 
 d= nfdc-ndc;
4443
 
 if(d<0)
4444
 
   return(-1);
4445
 
 if(d>nfic)
4446
 
   return(0);
4447
 
 for(i= 0; i<d; i++) {
4448
 
   cpt= strrchr(nfi, '/');
4449
 
   if(cpt==NULL)
4450
 
     return(-1); /* should not happen */
4451
 
   *cpt= 0;
4452
 
 }
4453
 
 if(nfi[0]==0)
4454
 
   strcpy(nfi, "/");
4455
 
 ret= Xorriso_fake_stbuf(xorriso, nfi, &stbuf, &node, 0);
4456
 
 if(ret<=0)
4457
 
   return(0);
4458
 
 ret= Xorriso_restore_properties(xorriso, nd, node, ((flag>>1)&3));
4459
 
 if(ret<=0)
4460
 
   return(ret);
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);
4466
 
 return(1);
4467
 
}
4468
 
 
4469
 
 
4470
 
int Xorriso_is_plain_image_file(struct XorrisO *xorriso, void *in_node,
4471
 
                                char *path, int flag)
4472
 
{
4473
 
 int ret, lba;
4474
 
 IsoStream *stream;
4475
 
 IsoNode *node;
4476
 
 
4477
 
 node= (IsoNode *) in_node;
4478
 
 if(node == NULL) {
4479
 
   ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
4480
 
   if(ret<=0)
4481
 
     return(ret);
4482
 
 }
4483
 
 
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);
4487
 
   if(stream != NULL)
4488
 
     if(iso_stream_get_input_stream(stream, 0) == NULL)
4489
 
       return(1);
4490
 
 }
4491
 
 return(0);
4492
 
}
4493
 
 
4494
 
 
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
4505
 
*/
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,
4509
 
                              int flag)
4510
 
{
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;
4518
 
 mode_t mode;
4519
 
 dev_t dev= 0;
4520
 
 struct stat stbuf;
4521
 
 struct utimbuf utime_buffer;
4522
 
 
4523
 
 if(LIBISO_ISDIR(node)) {
4524
 
   what= "directory";
4525
 
   ret= mkdir(disk_path, 0777);
4526
 
   l_errno= errno;
4527
 
 
4528
 
 } else if(LIBISO_ISREG(node)) {
4529
 
   what= "regular file";
4530
 
   ret= Xorriso_iso_file_open(xorriso, img_path, (void *) node, &data_stream,
4531
 
                              1);
4532
 
   if(ret<=0)
4533
 
     goto ex;
4534
 
   open_path_pt= disk_path;
4535
 
   ret= stat(open_path_pt, &stbuf);
4536
 
   if(ret == -1 && errno == EACCES && (flag & 128))
4537
 
     {ret= 4; goto ex;}
4538
 
   if(flag&2) {
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);
4544
 
       l_errno= 0;
4545
 
       goto cannot_restore;
4546
 
     }
4547
 
   } else {
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);
4551
 
     if(ret<0)
4552
 
       goto ex;
4553
 
     if(ret==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;
4559
 
     }
4560
 
     if(ret==2) {
4561
 
       /* Extract to temporary file and rename only after copying */
4562
 
       ret= Xorriso_make_tmp_path(xorriso, disk_path, temp_path, &write_fd,
4563
 
                                  128);
4564
 
       if(ret <= 0 || ret == 4)
4565
 
         goto ex;
4566
 
       open_path_pt= temp_path;
4567
 
     }
4568
 
   }
4569
 
   if(write_fd==-1) {
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);
4574
 
     l_errno= errno;
4575
 
     if(write_fd == -1 && errno == EACCES && (flag & 128))
4576
 
       {ret= 4; goto ex;}
4577
 
     if(write_fd==-1)
4578
 
       goto cannot_restore;
4579
 
   }
4580
 
   todo= size= iso_file_get_size((IsoFile *) node);
4581
 
   if(flag&2) {
4582
 
     if(bytes<size)
4583
 
       todo= size= bytes;
4584
 
     seek_ret= lseek(write_fd, disk_offset, SEEK_SET);
4585
 
     l_errno= errno;
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;
4592
 
     }
4593
 
   }
4594
 
   while(todo>0) {
4595
 
     wanted= sizeof(buf);
4596
 
     if(wanted>todo)
4597
 
       wanted= todo;
4598
 
     ret= Xorriso_iso_file_read(xorriso, data_stream, buf, wanted, 0);
4599
 
     if(ret<=0) {
4600
 
       if(xorriso->extract_error_mode == 0 &&
4601
 
          Xorriso_is_plain_image_file(xorriso, node, "", 0)) {
4602
 
         close(write_fd);
4603
 
         write_fd= -1;
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);
4612
 
         if(ret >= 0)
4613
 
           xorriso->pacifier_byte_count+= todo;
4614
 
         if(ret > 0)
4615
 
           todo= 0;
4616
 
         else
4617
 
           todo= -1;
4618
 
       }
4619
 
       if(ret <= 0) {
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);
4623
 
       }
4624
 
   break;
4625
 
     }
4626
 
     read_count+= ret;
4627
 
     buf_pt= buf;
4628
 
 
4629
 
     if(img_offset > read_count - ret) {
4630
 
       /* skip the desired amount of bytes */
4631
 
       if(read_count <= img_offset)
4632
 
   continue;
4633
 
       buf_pt= buf + (img_offset - (read_count - ret));
4634
 
       ret= read_count - img_offset;
4635
 
     }
4636
 
 
4637
 
     wret= write(write_fd, buf_pt, ret);
4638
 
     if(wret>=0) {
4639
 
       todo-= wret;
4640
 
       xorriso->pacifier_byte_count+= wret;
4641
 
       if((flag&16) &&
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;
4647
 
       }
4648
 
     }
4649
 
     if(wret != ret) {
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);
4654
 
   break;
4655
 
     }
4656
 
   }  
4657
 
   if(write_fd > 0)
4658
 
     close(write_fd);
4659
 
   write_fd= -1;
4660
 
   if(todo > 0 && xorriso->extract_error_mode == 2 && open_path_pt != NULL) {
4661
 
     unlink(open_path_pt);
4662
 
     target_deleted= 1;
4663
 
   }
4664
 
   Xorriso_iso_file_close(xorriso, &data_stream, 0);
4665
 
   data_stream= NULL;
4666
 
   if(temp_path==open_path_pt && !target_deleted) {
4667
 
     ret= rename(temp_path, disk_path);
4668
 
     if(ret==-1) {
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);
4674
 
       unlink(temp_path);
4675
 
       ret= 0; goto ex;
4676
 
     }
4677
 
   }
4678
 
   ret= -(todo > 0);
4679
 
   l_errno= 0;
4680
 
 
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);
4685
 
   l_errno= errno;
4686
 
 
4687
 
 } else if(LIBISO_ISCHR(node)) {
4688
 
   what= "character device";
4689
 
   if(xorriso->allow_restore!=2) {
4690
 
ignored:;
4691
 
     if(!(flag&4)) {
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);
4695
 
     }
4696
 
     {ret= 2; goto ex;}
4697
 
   }
4698
 
   mode= S_IFCHR | 0777;
4699
 
   ret= Xorriso_node_get_dev(xorriso, node, img_path, &dev, 0);
4700
 
   if(ret<=0)
4701
 
     goto ex;
4702
 
   if(dev == (dev_t) 1) {
4703
 
probably_damaged:;
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);
4708
 
     ret= 0; goto ex;
4709
 
   }
4710
 
   ret= mknod(disk_path, mode, dev);
4711
 
   l_errno= errno;
4712
 
 
4713
 
 } else if(LIBISO_ISBLK(node)) {
4714
 
   what= "block device";
4715
 
   if(xorriso->allow_restore!=2)
4716
 
     goto ignored;
4717
 
   mode= S_IFBLK | 0777;
4718
 
   ret= Xorriso_node_get_dev(xorriso, node, img_path, &dev, 0);
4719
 
   if(ret<=0)
4720
 
     goto ex;
4721
 
   if(dev == (dev_t) 1)
4722
 
     goto probably_damaged;
4723
 
   ret= mknod(disk_path, mode, dev);
4724
 
   l_errno= errno;
4725
 
 
4726
 
 } else if(LIBISO_ISFIFO(node)) {
4727
 
   what= "named pipe";
4728
 
   mode= S_IFIFO | 0777;
4729
 
   ret= mknod(disk_path, mode, dev);
4730
 
   l_errno= errno;
4731
 
 
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. */
4736
 
   goto ignored;
4737
 
 
4738
 
 } else {
4739
 
   sprintf(xorriso->info_text, "Cannot restore file type '%s'", what);
4740
 
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
4741
 
   ret= 0; goto ex;
4742
 
 }
4743
 
 if(ret == -1 && l_errno == EACCES && (flag & 128))
4744
 
   {ret= 4; goto ex;}
4745
 
 if(ret==-1) {
4746
 
cannot_restore:;
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);
4751
 
   ret= 0; goto ex;
4752
 
 }
4753
 
 
4754
 
restore_properties:;
4755
 
 if((flag&8) || LIBISO_ISLNK(node))
4756
 
   ret= 1;
4757
 
 else
4758
 
   ret= Xorriso_restore_properties(xorriso, disk_path, node, flag&1);
4759
 
 if(todo < 0)
4760
 
   ret= 0;
4761
 
ex:;
4762
 
 if(write_fd >= 0) {
4763
 
   close(write_fd);
4764
 
   if(ret <= 0 && xorriso->extract_error_mode == 2 && open_path_pt != NULL)
4765
 
     unlink(open_path_pt);
4766
 
 }
4767
 
 if(data_stream!=NULL)
4768
 
   Xorriso_iso_file_close(xorriso, &data_stream, 0);
4769
 
 return(ret);
4770
 
}
4771
 
 
4772
 
 
4773
 
/* Handle overwrite situation in disk filesystem.
4774
 
   @param node  intended source of overwriting or NULL
4775
 
   @param flag
4776
 
               bit4= return 3 on rejection by exclusion or user
4777
 
               bit6= permission to call Xorriso_make_accessible()
4778
 
*/
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)
4783
 
{
4784
 
 int ret;
4785
 
 char sfe[5*SfileadrL], sfe2[5*SfileadrL], type_text[5];
4786
 
 
4787
 
 Xorriso_process_msg_queues(xorriso,0);
4788
 
 if(xorriso->do_overwrite==1 ||
4789
 
    (xorriso->do_overwrite==2 && !S_ISDIR(stbuf->st_mode))) {
4790
 
 
4791
 
   ret= Xorriso_restore_is_identical(xorriso, (void *) node, img_path,
4792
 
                                     path, type_text, (node!=NULL));
4793
 
   if(ret<0)
4794
 
     return(ret);
4795
 
   if(ret>0) /* will be handled properly by restore functions */
4796
 
     ret= Xorriso_reassure_restore(xorriso, path, 8);
4797
 
   else
4798
 
     ret= Xorriso_rmx(xorriso, (off_t) 0, path, 8 | (flag & 64));
4799
 
   if(ret<=0)
4800
 
     return(ret);
4801
 
   if(ret==3) {
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));
4806
 
   }
4807
 
   return(1);
4808
 
 }
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);
4815
 
 return(0);
4816
 
}
4817
 
 
4818
 
 
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
4822
 
*/
4823
 
int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node,
4824
 
                             int *node_idx, int *min_hl, int *max_hl, int flag)
4825
 
{
4826
 
 int idx, ret, i, node_count;
4827
 
 void *np, **node_array;
4828
 
 
4829
 
 node_array= xorriso->hln_array;
4830
 
 node_count= xorriso->hln_count;
4831
 
 *min_hl= *max_hl= -1;
4832
 
 np= node;
4833
 
 if(flag & 2) {
4834
 
   idx= *node_idx;
4835
 
   if(flag & 4) {
4836
 
     node_array= xorriso->node_array;
4837
 
     node_count= xorriso->node_counter;
4838
 
   }
4839
 
 } else {
4840
 
   *node_idx= -1;
4841
 
   ret= Xorriso_search_in_hln_array(xorriso, np, &idx, 0);
4842
 
   if(ret <= 0)
4843
 
     return(ret);
4844
 
 }
4845
 
 for(i= idx - 1; i >= 0 ; i--)
4846
 
   if(Xorriso__findi_sorted_ino_cmp(&(node_array[i]), &np) != 0)
4847
 
 break;
4848
 
 *min_hl= i + 1;
4849
 
 for(i= idx + 1; i < node_count; i++) 
4850
 
   if(Xorriso__findi_sorted_ino_cmp(&(node_array[i]), &np) != 0)
4851
 
 break;
4852
 
 *max_hl= i - 1;
4853
 
 
4854
 
 /* Search for *node_idx */
4855
 
 if(flag & 2)
4856
 
   return(1);
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)
4861
 
 continue;
4862
 
     *node_idx= i;
4863
 
 break;
4864
 
   }
4865
 
 return(1);
4866
 
}
4867
 
 
4868
 
 
4869
 
/*
4870
 
   @return <0 error,
4871
 
           bit0= hardlink created
4872
 
           bit1= siblings with target NULL found
4873
 
           bit2= siblings with non-NULL target found
4874
 
*/
4875
 
int Xorriso_restore_target_hl(struct XorrisO *xorriso, IsoNode *node,
4876
 
                           char *disk_path, int *node_idx, int flag)
4877
 
{
4878
 
 int ret, min_hl, max_hl, i, null_target_sibling= 0, link_sibling= 0;
4879
 
 
4880
 
 if(xorriso->hln_targets == NULL)
4881
 
   return(0);
4882
 
 ret= Xorriso_search_hardlinks(xorriso, node, node_idx, &min_hl, &max_hl, 1);
4883
 
 if(ret < 0)
4884
 
   return(ret);
4885
 
 if(ret == 0 || *node_idx < 0 || min_hl == max_hl)
4886
 
   return(0);
4887
 
 for(i= min_hl; i <= max_hl; i++) {
4888
 
   if(xorriso->hln_targets[i] == NULL) {
4889
 
     if(i != *node_idx)
4890
 
       null_target_sibling= 1;
4891
 
 continue;
4892
 
   }
4893
 
   link_sibling= 1;
4894
 
   ret= Xorriso_restore_make_hl(xorriso, xorriso->hln_targets[i], disk_path,
4895
 
                                !!xorriso->do_auto_chmod);
4896
 
   if(ret > 0)
4897
 
     return(1);
4898
 
 }
4899
 
 return((null_target_sibling << 1) | (link_sibling << 2));
4900
 
}
4901
 
 
4902
 
 
4903
 
/*
4904
 
   @return <0 error,
4905
 
           bit0= hardlink created
4906
 
           bit2= siblings lower index found
4907
 
*/
4908
 
int Xorriso_restore_prefix_hl(struct XorrisO *xorriso, IsoNode *node,
4909
 
                              char *disk_path, int node_idx, int flag)
4910
 
{
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;
4914
 
 
4915
 
 ret= Xorriso_search_hardlinks(xorriso, node, &node_idx, &min_hl, &max_hl,
4916
 
                               2 | 4);
4917
 
 if(ret < 0)
4918
 
   return(ret);
4919
 
 if(ret == 0 || min_hl == max_hl)
4920
 
   return(0);
4921
 
 
4922
 
 for(i= min_hl; i < node_idx; i++) {
4923
 
   link_sibling= 1;
4924
 
   ret= Xorriso_path_from_node(xorriso, xorriso->node_array[i], img_path, 0);
4925
 
   if(ret < 0)
4926
 
     return(ret);
4927
 
   if(ret == 0)
4928
 
 continue; /* Node is deleted from tree (Should not happen here) */
4929
 
   hflag= 1;
4930
 
   if(i == min_hl) {
4931
 
     hflag= 0;
4932
 
   } else if(xorriso->node_array[i] != xorriso->node_array[i - 1]) {
4933
 
     hflag= 0;
4934
 
   }
4935
 
   if(hflag == 0) {
4936
 
     img_prefixes= xorriso->node_img_prefixes;
4937
 
     disk_prefixes= xorriso->node_disk_prefixes;
4938
 
   }
4939
 
   ret= Xorriso_make_restore_path(xorriso, &img_prefixes, &disk_prefixes,
4940
 
                                  img_path, old_path, hflag);
4941
 
   if(ret <= 0)
4942
 
     return(ret);
4943
 
   ret= Xorriso_restore_make_hl(xorriso, old_path, disk_path,
4944
 
                                !!xorriso->do_auto_chmod);
4945
 
   if(ret > 0)
4946
 
     return(1);
4947
 
 }
4948
 
 return(link_sibling << 2);
4949
 
}
4950
 
 
4951
 
 
4952
 
/* @return <0 = error , 0 = availmem exhausted first time , 1 = ok
4953
 
                        2 = availmem exhausted repeated
4954
 
*/ 
4955
 
int Xorriso_register_node_target(struct XorrisO *xorriso, int node_idx,
4956
 
                                 char *disk_path, int flag)
4957
 
{
4958
 
 int l;
4959
 
 
4960
 
 if(xorriso->node_targets_availmem == 0)
4961
 
   return(2);
4962
 
 if(xorriso->hln_targets == NULL || node_idx < 0 ||
4963
 
    node_idx >= xorriso->hln_count)
4964
 
   return(0);
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]);
4968
 
 }
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;
4975
 
   return(0);
4976
 
 }
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);
4980
 
   return(-1);
4981
 
 }
4982
 
 xorriso->node_targets_availmem-= (l + 1);
4983
 
 return(1);
4984
 
}
4985
 
 
4986
 
 
4987
 
/*
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
4999
 
*/
5000
 
int Xorriso_restore_disk_object(struct XorrisO *xorriso,
5001
 
                                char *img_path, IsoNode *node,
5002
 
                                char *disk_path,
5003
 
                                off_t offset, off_t bytes, int flag)
5004
 
{
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];
5010
 
 IsoImage *volume;
5011
 
 IsoNode *part_node, *first_part_node= NULL;
5012
 
 struct SplitparT *split_parts= NULL;
5013
 
 struct stat stbuf;
5014
 
 
5015
 
 ret= Xorriso_get_volume(xorriso, &volume, 0);
5016
 
 if(ret<=0)
5017
 
   goto ex;
5018
 
 
5019
 
 was_byte_count= xorriso->pacifier_byte_count;
5020
 
  
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);
5024
 
 if(leaf_is_split) {
5025
 
   /* map all files in directory img_path into regular file disk_path */
5026
 
 
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);
5030
 
 
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;
5035
 
     }
5036
 
     ret= Xorriso_node_from_path(xorriso, volume, part_path, &part_node, 0);
5037
 
     if(ret<=0)
5038
 
       goto restoring_failed;
5039
 
     if(i==0)
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)));
5046
 
     if(ret<=0)
5047
 
       goto restoring_failed;
5048
 
     if(ret == 4)
5049
 
       goto ex;
5050
 
   }
5051
 
   if(first_part_node!=NULL)
5052
 
     Xorriso_restore_properties(xorriso, disk_path, first_part_node,
5053
 
                                !!(flag&64));
5054
 
   goto went_well;
5055
 
 }
5056
 
 
5057
 
#ifdef Osirrox_not_yeT
5058
 
 
5059
 
 if(resolve_link) {
5060
 
   ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0);
5061
 
   if(ret<=0)
5062
 
     goto ex;
5063
 
   disk_path_pt= resolved_disk_path;
5064
 
 } else
5065
 
 
5066
 
#endif /* Osirrox_not_yeT */
5067
 
 
5068
 
   img_path_pt= img_path;
5069
 
 
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);
5074
 
   if(ret < 0) {
5075
 
     goto ex;
5076
 
   } else if(ret & 1) {
5077
 
     /* Success, hardlink was created */
5078
 
     goto went_well;
5079
 
   } else if(ret & 2) {
5080
 
     /* Did not establish hardlink. Hardlink siblings with target NULL found.*/
5081
 
     record_hl_path= 1;
5082
 
   }
5083
 
   if(ret & 4) {
5084
 
     /* Found siblings with non-NULL target, but did not link. */
5085
 
     ret= Xorriso_eval_problem_status(xorriso, 1, 0);
5086
 
     if(ret < 0)
5087
 
       {ret= 0; goto ex;}
5088
 
   }
5089
 
 }
5090
 
 
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)));
5094
 
 if(ret == 4)
5095
 
   goto ex;
5096
 
 if(ret>0 && (flag&8))
5097
 
   ret= Xorriso_restore_properties(xorriso, disk_path, node, 2 | !!(flag&64));
5098
 
 if(ret<=0) {
5099
 
restoring_failed:;
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);
5103
 
   {ret= 0; goto ex;}
5104
 
 }
5105
 
 if(ret==2)
5106
 
   {ret= 3; goto ex;}
5107
 
 if(record_hl_path) { /* Start of a disk hardlink family */
5108
 
   ret= Xorriso_register_node_target(xorriso, node_idx, disk_path, 0);
5109
 
   if(ret < 0)
5110
 
     goto ex;
5111
 
   if(ret == 0)
5112
 
     cannot_register= 1;
5113
 
 }
5114
 
 
5115
 
went_well:;
5116
 
 xorriso->pacifier_count++;
5117
 
 if(!(flag&2))
5118
 
   Xorriso_pacifier_callback(xorriso, "files restored",
5119
 
                             xorriso->pacifier_count,
5120
 
                             xorriso->pacifier_total, "", 4);
5121
 
 ret= 1;
5122
 
ex:;
5123
 
 if(split_parts!=NULL) 
5124
 
   Splitparts_destroy(&split_parts, split_count, 0);
5125
 
 if(ret > 0 && cannot_register)
5126
 
   ret= 0;
5127
 
 return(ret);
5128
 
}
5129
 
 
5130
 
 
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
5134
 
*/
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)
5139
 
{
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;
5143
 
 
5144
 
 perm_stack_mem= xorriso->perm_stack;
5145
 
 
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);
5151
 
     if(ret < 0)
5152
 
       goto ex;
5153
 
     made_accessible= 1;
5154
 
     *stbuf_ret= lstat(disk_path, &target_stbuf);
5155
 
   }
5156
 
   if(*stbuf_ret==-1)
5157
 
     {ret= 2; goto ex;}
5158
 
 }
5159
 
 target_is_link= S_ISLNK(target_stbuf.st_mode);
5160
 
 if(target_is_link) {
5161
 
   stat_ret= stat(disk_path, &lt_stbuf);
5162
 
   if(stat_ret == -1) {
5163
 
     if((flag & 64) && errno == EACCES && !made_accessible) {
5164
 
       ret= Xorriso_make_accessible(xorriso, disk_path, 0);
5165
 
       if(ret < 0)
5166
 
         goto ex;
5167
 
       made_accessible= 1;
5168
 
       stat_ret= stat(disk_path, &lt_stbuf);
5169
 
     }
5170
 
   }
5171
 
   if(stat_ret != -1)
5172
 
     target_is_dir= S_ISDIR(lt_stbuf.st_mode);
5173
 
 } else {
5174
 
   target_is_dir= S_ISDIR(target_stbuf.st_mode);
5175
 
 }
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);
5183
 
   ret= 0; goto ex;
5184
 
 }
5185
 
 
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));
5190
 
   if(ret==3)
5191
 
     {ret= 3; goto ex;}
5192
 
   if(ret<=0) 
5193
 
     goto ex;
5194
 
   *stbuf_ret= -1; /* It might still exist but will be handled properly */
5195
 
 }
5196
 
 ret= 1;
5197
 
ex:;
5198
 
 if(made_accessible)
5199
 
   Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0);
5200
 
 return(ret);
5201
 
}
5202
 
 
5203
 
 
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
5208
 
               bit7+8=
5209
 
                     0= direct operation
5210
 
                     1= create only directories,
5211
 
                        count nodes in xorriso->node_counter
5212
 
                     2= only register non-directory nodes in
5213
 
                        xorriso->node_array
5214
 
                     3= count nodes in xorriso->node_counter,
5215
 
                        create no directory
5216
 
*/
5217
 
int Xorriso_restore_tree(struct XorrisO *xorriso, IsoDir *dir,
5218
 
                         char *img_dir_path, char *disk_dir_path,
5219
 
                         off_t boss_mem,
5220
 
                         struct LinkiteM *link_stack, int flag)
5221
 
{
5222
 
 IsoImage *volume;
5223
 
 IsoNode *node;
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;
5233
 
 off_t mem;
5234
 
 struct PermiteM *perm_stack_mem;
5235
 
 struct stat stbuf;
5236
 
 int dir_create= 0, node_register= 0, do_node_count= 0, normal_mode= 0;
5237
 
 
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;
5244
 
 }
5245
 
 
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);
5255
 
   {ret= -1; goto ex;}
5256
 
 }
5257
 
 
5258
 
 own_link_stack= link_stack;
5259
 
 
5260
 
 ret= Xorriso_get_volume(xorriso, &volume, 0);
5261
 
 if(ret<=0)
5262
 
   goto ex;
5263
 
 
5264
 
 stbuf_src= img_dir_path;
5265
 
 node= (IsoNode *) dir;
5266
 
 ret= Xorriso_fake_stbuf(xorriso, stbuf_src, &stbuf, &node, 1);
5267
 
 if(ret<=0) {
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);
5272
 
   {ret= 0; goto ex;}
5273
 
 }
5274
 
 
5275
 
#ifdef Osirrox_not_yeT
5276
 
 
5277
 
 dev_t dir_dev;
5278
 
 dir_dev= stbuf.st_dev;
5279
 
 
5280
 
 if(S_ISLNK(stbuf.st_mode)) {
5281
 
   if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1))))
5282
 
     {ret= 2; goto ex;}
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))))
5288
 
     {ret= 2; goto ex;}
5289
 
 }
5290
 
 
5291
 
#endif /* Osirrox_not_yeT */
5292
 
 
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);
5298
 
   {ret= 0; goto ex;}
5299
 
 }
5300
 
 
5301
 
 mem= boss_mem;
5302
 
 ret= Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count,
5303
 
                         &node_idx, &node,
5304
 
                         1 | 4 * (normal_mode && (xorriso->ino_behavior & 4)));
5305
 
 if(ret<=0)
5306
 
   goto ex;
5307
 
 
5308
 
 if(Sfile_str(img_path, img_dir_path,0)<=0) {
5309
 
much_too_long:;
5310
 
   Xorriso_much_too_long(xorriso, SfileadrL, 2);
5311
 
   {ret= 0; goto ex;}
5312
 
 }
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)
5317
 
   goto much_too_long;
5318
 
 if(disk_path[0]==0 || disk_path[strlen(disk_path)-1]!='/')
5319
 
   strcat(disk_path,"/");
5320
 
 disk_name= disk_path+strlen(disk_path);
5321
 
 
5322
 
 len_dp= strlen(disk_path);
5323
 
 len_ip= strlen(img_path);
5324
 
 
5325
 
 while(1) { /* loop over ISO directory content */
5326
 
   stbuf_src= "";
5327
 
 
5328
 
#ifdef Osirrox_not_yeT
5329
 
 
5330
 
   Linkitem_reset_stack(&own_link_stack, link_stack, 0);
5331
 
 
5332
 
#endif
5333
 
 
5334
 
   srcpt= img_path;
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);
5338
 
   if(ret<0)
5339
 
     goto ex;
5340
 
   if(ret==0 || xorriso->request_to_abort)
5341
 
 break;
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);
5350
 
 
5351
 
   stbuf_src= srcpt;
5352
 
   ret= Xorriso_fake_stbuf(xorriso, img_path, &stbuf, &node, 1);
5353
 
   if(ret<=0)
5354
 
     goto was_problem;
5355
 
   source_is_dir= 0;
5356
 
   source_is_link= S_ISLNK(stbuf.st_mode);
5357
 
 
5358
 
#ifdef Osirrox_not_yeT
5359
 
 
5360
 
   /* ??? Link following in the image would cause severe problems
5361
 
          with Xorriso_path_from_node() */
5362
 
 
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);
5366
 
     if(ret<0)
5367
 
       goto was_problem;
5368
 
     if(ret==1) {
5369
 
       ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 0);
5370
 
       if(ret<=0)
5371
 
         goto was_problem;
5372
 
       srcpt= link_target;
5373
 
       stbuf_src= srcpt;
5374
 
       if(lstat(srcpt, &stbuf)==-1)
5375
 
         goto cannot_lstat;
5376
 
     } else {
5377
 
       if(Xorriso_eval_problem_status(xorriso, 0, 1|2)<0)
5378
 
         {ret= 0; goto was_problem;} 
5379
 
     }
5380
 
   } else if (S_ISLNK(stbuf.st_mode)) {
5381
 
     ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1);
5382
 
     if(ret<=0)
5383
 
       goto was_problem;
5384
 
   }
5385
 
 
5386
 
#endif /* Osirrox_not_yeT */
5387
 
 
5388
 
   do_not_dive= 0;
5389
 
   if(S_ISDIR(stbuf.st_mode))
5390
 
     source_is_dir= 1;
5391
 
   source_is_split= 0;
5392
 
   if(source_is_dir)
5393
 
     source_is_split= Xorriso_is_split(xorriso, img_path, node, 1|2);
5394
 
   if(source_is_split)
5395
 
     do_not_dive= 1;
5396
 
 
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)
5402
 
       goto was_problem;
5403
 
   } else {
5404
 
     stbuf_ret= -1;
5405
 
   }
5406
 
 
5407
 
   if(stbuf_ret!=-1) { /* (Can only happen with directory) */
5408
 
     Xorriso_auto_chmod(xorriso, disk_path, 0);
5409
 
   } else {
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;
5418
 
         iso_node_ref(node);
5419
 
       }
5420
 
     } else if(node_register || do_node_count) {
5421
 
       ret= 1;
5422
 
     } else {
5423
 
       ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path,
5424
 
                                        (off_t) 0, (off_t) 0, hflag);
5425
 
     }
5426
 
     if(ret<=0)
5427
 
       goto was_problem;
5428
 
   }
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,
5435
 
                         !!(flag&64));
5436
 
     if(hret<=0 && hret<ret)
5437
 
       ret= hret;
5438
 
     if(ret<=0)
5439
 
       goto was_problem;
5440
 
   }
5441
 
 
5442
 
 continue; /* regular bottom of loop */
5443
 
was_problem:;
5444
 
   was_failure= 1;
5445
 
   fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
5446
 
   if(fret<0)
5447
 
     goto ex;
5448
 
   Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, !!(flag&64));
5449
 
 }
5450
 
 
5451
 
 ret= 1;
5452
 
ex:
5453
 
 Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, !!(flag&64));
5454
 
 if(sfe!=NULL)
5455
 
   free(sfe);
5456
 
 if(sfe2!=NULL)
5457
 
   free(sfe2);
5458
 
 if(disk_path!=NULL)
5459
 
   free(disk_path);
5460
 
 if(img_path!=NULL)
5461
 
   free(img_path);
5462
 
 if(link_target!=NULL)
5463
 
   free(link_target);
5464
 
 Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count,
5465
 
                    &node_idx, &node, (1<<31));
5466
 
 
5467
 
 Xorriso_process_msg_queues(xorriso,0);
5468
 
 
5469
 
#ifdef Osirrox_not_yeT
5470
 
 
5471
 
 Linkitem_reset_stack(&own_link_stack, link_stack, 0);
5472
 
 
5473
 
#endif
5474
 
 
5475
 
 if(ret<=0)
5476
 
   return(ret);
5477
 
 return(!was_failure);
5478
 
}
5479
 
 
5480
 
 
5481
 
/*
5482
 
   @param flag
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
5491
 
                     0= direct operation
5492
 
                     1= create only directories,
5493
 
                        count nodes in xorriso->node_counter
5494
 
                     2= only register non-directory nodes in
5495
 
                        xorriso->node_array
5496
 
                     3= count nodes in xorriso->node_counter,
5497
 
                        create no directory
5498
 
               bit9= with operation mode 1 do net register prefixes
5499
 
   @return <=0 = error , 1 = added leaf file object , 2 = added directory ,
5500
 
                         3 = rejected 
5501
 
*/
5502
 
int Xorriso_restore(struct XorrisO *xorriso,  
5503
 
                    char *img_path, char *disk_path,
5504
 
                    off_t offset, off_t bytes, int flag)
5505
 
{
5506
 
 IsoImage *volume;
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;
5512
 
 struct stat stbuf;
5513
 
 struct PermiteM *perm_stack_mem;
5514
 
 
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;
5520
 
 }
5521
 
 
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);
5525
 
   if(ret <= 0)
5526
 
     goto ex; 
5527
 
   ret= Xorriso_lst_append_binary(&(xorriso->node_img_prefixes),
5528
 
                                  img_path, strlen(img_path) + 1, 0);
5529
 
   if(ret <= 0)
5530
 
     goto ex; 
5531
 
 }
5532
 
 
5533
 
 ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&4));
5534
 
 if(ret<0)
5535
 
   goto ex;
5536
 
 if(ret>0)
5537
 
   {ret= 3*!!(flag&16); goto ex;}
5538
 
 
5539
 
 ret= Xorriso_get_volume(xorriso, &volume, 0);
5540
 
 if(ret<=0)
5541
 
   goto ex;
5542
 
 
5543
 
 strncpy(path, disk_path, sizeof(path)-1);
5544
 
 path[sizeof(path)-1]= 0;
5545
 
 apt= npt= path;
5546
 
 
5547
 
 if(!(flag&1)) {
5548
 
   ret= Xorriso_fake_stbuf(xorriso, img_path, &stbuf, &node, 0);
5549
 
   if(ret>0) {
5550
 
     if(S_ISDIR(stbuf.st_mode))
5551
 
       is_dir= 1;
5552
 
 
5553
 
#ifdef Osirrox_not_yeT
5554
 
 
5555
 
     /* ??? this would cause severe problems with Xorriso_path_from_node() */
5556
 
 
5557
 
     else if((stbuf.st_mode&S_IFMT)==S_IFLNK &&
5558
 
             (xorriso->do_follow_links ||
5559
 
              (xorriso->do_follow_param && !(flag&4)))) {
5560
 
       resolve_link= 1;
5561
 
       ret= Xorriso_iso_lstat(xorriso, img_path, &stbuf, 1|2);
5562
 
       if(ret!=-1) {
5563
 
         if(S_ISDIR(stbuf.st_mode))
5564
 
           is_dir= 1;
5565
 
       }
5566
 
     }
5567
 
#endif /* Osirrox_not_yeT */
5568
 
 
5569
 
   } else {
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);
5576
 
     ret= 0; goto ex;
5577
 
   }
5578
 
   if(is_dir && xorriso->do_concat_split)
5579
 
     leaf_is_split= Xorriso_is_split(xorriso, img_path, node, 1|2);
5580
 
 }
5581
 
 for(npt= apt; !done; apt= npt+1) {
5582
 
   npt= strchr(apt, '/');
5583
 
   if(npt==NULL) {
5584
 
     npt= apt+strlen(apt);
5585
 
     done= 1;
5586
 
   } else
5587
 
     *npt= 0;
5588
 
   if(*apt==0) {
5589
 
     *apt= '/';
5590
 
     apt++;
5591
 
     if(done)
5592
 
       goto attach_source;
5593
 
 continue;
5594
 
   }
5595
 
   source_is_dir= (is_dir || (flag&1) || !done);
5596
 
   source_is_split= done && leaf_is_split;
5597
 
 
5598
 
   stbuf_ret= -1;
5599
 
   if((flag&8) && done) {
5600
 
 
5601
 
     /* ??? move down from Xorriso_paste_in() :
5602
 
            check whether target does not exist or both are regular */;
5603
 
 
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)
5608
 
       goto ex;
5609
 
   }
5610
 
 
5611
 
   new_dir_made= 0;
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);
5616
 
     if(ret==-1) {
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);
5622
 
       {ret= 0; goto ex;}
5623
 
     }
5624
 
     if(!done) {
5625
 
       /* keep rwx for the owner */
5626
 
       Xorriso_restore_implicit_properties(xorriso, disk_path, path,
5627
 
                                           img_path, 4);
5628
 
     }
5629
 
     new_dir_made= 1;
5630
 
   } else if((source_is_dir && !source_is_split)) {
5631
 
     if(!(node_count || node_register))
5632
 
       Xorriso_auto_chmod(xorriso, path, 0);
5633
 
   }
5634
 
   if(done) {
5635
 
attach_source:;
5636
 
 
5637
 
     if(flag&1) {
5638
 
       /* directory was created above */;
5639
 
 
5640
 
     } else if(is_dir && !source_is_split) {
5641
 
 
5642
 
       if(!node_register) {
5643
 
         if(new_dir_made) /* keep open and push to Permstack */
5644
 
           Xorriso_restore_properties(xorriso, disk_path, node,
5645
 
                                      2 | !!(flag&64));
5646
 
       }
5647
 
       if(!(flag&32)) {
5648
 
         ret= Xorriso_restore_tree(xorriso, (IsoDir *) node, img_path, path,
5649
 
                                  (off_t) 0, NULL, flag & (2 | 64 | (3 << 7)));
5650
 
         if(ret<=0)
5651
 
           goto ex;
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);
5655
 
       }
5656
 
     } else {
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;
5662
 
           iso_node_ref(node);
5663
 
         }
5664
 
       } else {
5665
 
         ret= Xorriso_restore_disk_object(xorriso, img_path, node, path,
5666
 
                                offset, bytes, (flag & (2|4|64)) | !!(flag&8));
5667
 
         if(ret<=0)
5668
 
           goto ex;
5669
 
       }
5670
 
     }
5671
 
   } else
5672
 
     *npt= '/';
5673
 
 }
5674
 
 Xorriso_process_msg_queues(xorriso,0);
5675
 
 ret= 1 + (is_dir && !leaf_is_split); 
5676
 
ex:;
5677
 
 /* restore exact access permissions of stacked paths */
5678
 
 hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso,
5679
 
                     2 | !!(flag&64));
5680
 
 if(hret<=0 && hret<ret)
5681
 
   ret= hret;
5682
 
 return(ret);
5683
 
}
5684
 
 
5685
 
 
5686
 
int Xorriso_restore_node_array(struct XorrisO *xorriso, int flag)
5687
 
{
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];
5691
 
 IsoNode *node;
5692
 
 struct Xorriso_lsT *img_prefixes= NULL, *disk_prefixes= NULL;
5693
 
 
5694
 
 perm_stack_mem= xorriso->perm_stack;
5695
 
 
5696
 
 Xorriso_sort_node_array(xorriso, 0);
5697
 
 
5698
 
 disk_path[0]= 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);
5702
 
   if(ret < 0)
5703
 
     goto ex;
5704
 
   if(ret == 0)
5705
 
 continue; /* Node is deleted from tree (Should not happen here) */
5706
 
   hflag= 1;
5707
 
   if(i == 0) {
5708
 
     hflag= 0;
5709
 
   } else if(node != xorriso->node_array[i - 1]) {
5710
 
     hflag= 0;
5711
 
   }
5712
 
   if(hflag == 0) {
5713
 
     img_prefixes= xorriso->node_img_prefixes;
5714
 
     disk_prefixes= xorriso->node_disk_prefixes;
5715
 
   }
5716
 
   ret= Xorriso_make_restore_path(xorriso, &img_prefixes, &disk_prefixes,
5717
 
                                  img_path, disk_path, hflag);
5718
 
   if(ret<=0)
5719
 
     goto was_problem;
5720
 
 
5721
 
   ret= Xorriso_handle_collision(xorriso, node, img_path, disk_path, disk_path,
5722
 
                                 &stbuf_ret, 64);
5723
 
   if(ret<=0 || ret==3)
5724
 
     goto was_problem;
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) {
5731
 
       if(faulty_family) {
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);
5735
 
       } else {
5736
 
         /* Try to install hardlink to a sibling */
5737
 
         ret= Xorriso_restore_prefix_hl(xorriso, node, disk_path, i, 0);
5738
 
         if(ret < 0) {
5739
 
           goto was_problem;
5740
 
         } else if(ret & 1) {
5741
 
           /* Success, hardlink was created */
5742
 
           xorriso->pacifier_count++;
5743
 
 continue;
5744
 
         }
5745
 
         if(ret & 4) {
5746
 
           /* Found elder siblings, but did not link. */
5747
 
           ret= Xorriso_eval_problem_status(xorriso, 1, 0);
5748
 
           if(ret < 0)
5749
 
             {ret= 0; goto ex;}
5750
 
         }
5751
 
       }
5752
 
     } else
5753
 
       faulty_family= 0;
5754
 
   }
5755
 
 
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);
5759
 
   if(ret<=0)
5760
 
     goto was_problem;
5761
 
   if(ret == 4) {
5762
 
     /* Failed from lack of permission */
5763
 
     ret= Xorriso_make_accessible(xorriso, disk_path, 0);
5764
 
     if(ret < 0)
5765
 
       goto ex;
5766
 
     ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path,
5767
 
                       (off_t) 0, (off_t) 0, 4 | (xorriso->ino_behavior & 16));
5768
 
     if(ret<=0)
5769
 
       goto was_problem;
5770
 
     Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0);
5771
 
   }
5772
 
 
5773
 
 continue; /* regular bottom of loop */
5774
 
was_problem:;
5775
 
   faulty_family= 1;
5776
 
   was_failure= 1;
5777
 
   fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
5778
 
   if(fret<0)
5779
 
     goto ex;
5780
 
   Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0);
5781
 
 }
5782
 
 ret= 1;
5783
 
ex:;
5784
 
 Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0);
5785
 
 return(ret);
5786
 
}
5787
 
 
5788
 
 
5789
 
/* @param flag bit0= -follow, -not: disk_path is not a command parameter
5790
 
*/
5791
 
int Xorriso_paste_in(struct XorrisO *xorriso, char *disk_path,
5792
 
                off_t startbyte, off_t bytecount, char *iso_rr_path, int flag)
5793
 
{
5794
 
 int ret;
5795
 
 char eff_source[SfileadrL], eff_dest[SfileadrL], sfe[SfileadrL*5];
5796
 
 struct stat stbuf;
5797
 
 IsoNode *node;
5798
 
 
5799
 
 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_dest,
5800
 
                                 2|4);
5801
 
 if(ret<=0)
5802
 
   return(ret);
5803
 
 ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&1));
5804
 
 if(ret!=0)
5805
 
   return(0);
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);
5813
 
   return(0);
5814
 
 }
5815
 
 
5816
 
 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, iso_rr_path,
5817
 
                                 eff_source, 2);
5818
 
 if(ret<=0)
5819
 
   return(ret);
5820
 
 ret= Xorriso_fake_stbuf(xorriso, eff_source, &stbuf, &node, 4);
5821
 
 if(ret<=0)
5822
 
   return(0);
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);
5828
 
   return(0);
5829
 
 }
5830
 
 
5831
 
 /* >>> eventually obtain parameters from file name */;
5832
 
 
5833
 
 ret= Xorriso_restore(xorriso, eff_source, eff_dest, startbyte, bytecount, 8);
5834
 
 return(ret);
5835
 
}
5836
 
 
5837
 
 
5838
 
int Xorriso_process_msg_queues(struct XorrisO *xorriso, int flag)
5839
 
{
5840
 
 int ret, error_code= 0, os_errno= 0, count= 0, pass, imgid, tunneled;
5841
 
 char severity[80];
5842
 
 
5843
 
 if(!xorriso->libs_are_started)
5844
 
   return(1);
5845
 
 for(pass= 0; pass< 2; pass++) {
5846
 
   while(1) {
5847
 
     tunneled= 0;
5848
 
     if(pass==0)
5849
 
       ret= iso_obtain_msgs("ALL", &error_code, &imgid,
5850
 
                            xorriso->info_text, severity);
5851
 
     else {
5852
 
       ret= burn_msgs_obtain("ALL", &error_code, xorriso->info_text, &os_errno,
5853
 
                             severity);
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:" */
5859
 
     }
5860
 
     if(ret<=0)
5861
 
   break;
5862
 
 
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");
5871
 
 
5872
 
     Xorriso_msgs_submit(xorriso, error_code, xorriso->info_text, os_errno, 
5873
 
                         severity, ((pass+tunneled)+1)<<2);
5874
 
     count++;
5875
 
   }
5876
 
 }
5877
 
 if(xorriso->library_msg_direct_print && count>0) {
5878
 
   sprintf(xorriso->info_text,"   (%d library messages repeated by xorriso)\n",
5879
 
           count);
5880
 
   Xorriso_info(xorriso, 0);
5881
 
 }
5882
 
 return(1);
5883
 
}
5884
 
 
5885
 
 
5886
 
/* @param flag
5887
 
               bit3=report to info channel (else to result channel)
5888
 
*/
5889
 
int Xorriso_toc_line(struct XorrisO *xorriso, int flag)
5890
 
{
5891
 
 if(!(flag & 8)) {
5892
 
   Xorriso_result(xorriso,0);
5893
 
   return(1);
5894
 
 }
5895
 
 strcpy(xorriso->info_text, xorriso->result_line);
5896
 
 Xorriso_info(xorriso, 0);
5897
 
 return(1);
5898
 
}
5899
 
 
5900
 
 
5901
 
int Xorriso__append_boot_params(char *line, ElToritoBootImage *bootimg,
5902
 
                                int flag)
5903
 
{
5904
 
 unsigned int platform_id;
5905
 
 
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");
5912
 
 return(1);
5913
 
}
5914
 
 
5915
 
 
5916
 
/* @param flag bit0= no output if no boot record was found
5917
 
               bit1= short form
5918
 
               bit3= report to info channel (else to result channel)
5919
 
*/
5920
 
int Xorriso_show_boot_info(struct XorrisO *xorriso, int flag)
5921
 
{
5922
 
 int ret, bin_path_valid= 0,has_isolinux_mbr= 0, i, num_boots;
5923
 
 unsigned int mbr_lba= 0;
5924
 
 off_t lb0_count;
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;
5933
 
 
5934
 
 respt= xorriso->result_line;
5935
 
 
5936
 
 if(xorriso->boot_count > 0) {
5937
 
   if(!(flag & 1)) {
5938
 
     sprintf(respt, "Boot record  : overridden by -boot_image any next\n");
5939
 
     Xorriso_toc_line(xorriso, flag & 8);
5940
 
   }
5941
 
   ret= 1; goto ex;
5942
 
 }
5943
 
 
5944
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
5945
 
                                "on attempt to print boot info", 16);
5946
 
 if(ret<=0)
5947
 
   goto no_boot;
5948
 
 image= isoburn_get_attached_image(drive);
5949
 
 if(image == NULL) {
5950
 
   ret= 0;
5951
 
no_boot:;
5952
 
   if(!(flag & 1)) {
5953
 
     sprintf(respt, "Boot record  : none\n");
5954
 
     Xorriso_toc_line(xorriso, flag & 8);
5955
 
   }
5956
 
   goto ex;
5957
 
 }
5958
 
 
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);
5961
 
 if(ret != 1)
5962
 
   goto no_boot;
5963
 
 
5964
 
 ret= Xorriso_path_from_lba(xorriso, NULL, xorriso->loaded_boot_bin_lba,
5965
 
                             path, 1);
5966
 
 if(ret > 0)
5967
 
   bin_path_valid= 1;
5968
 
 sprintf(respt, "Boot record  : El Torito");
5969
 
 if(bin_path_valid)
5970
 
   ret= Xorriso_is_isohybrid(xorriso, bootimg_node, 0);
5971
 
 else
5972
 
   ret= 0;
5973
 
 if(ret > 0) {
5974
 
   /* Load and examine potential MBR */
5975
 
   ret= burn_read_data(drive, (off_t) 0, (char *) lb0, (off_t) 2048,
5976
 
                       &lb0_count, 2);
5977
 
   if(ret > 0) {
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);
5982
 
     mbr_lba/= 4;
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)
5988
 
       break;
5989
 
       if(i >= 426)
5990
 
         has_isolinux_mbr= 0;
5991
 
     }
5992
 
     for(i= 462; i < 510; i++)
5993
 
       if(lb0[i])
5994
 
     break;
5995
 
     if(i < 510)
5996
 
       has_isolinux_mbr= 0;
5997
 
   }
5998
 
   if(has_isolinux_mbr)
5999
 
     strcat(respt, " , ISOLINUX isohybrid MBR pointing to boot image");
6000
 
   else
6001
 
     strcat(respt, " , ISOLINUX boot image capable of isohybrid");
6002
 
 }
6003
 
 strcat(respt, "\n");
6004
 
 Xorriso_toc_line(xorriso, flag & 8);
6005
 
 if(flag & 2)
6006
 
   {ret= 1; goto ex;}
6007
 
 
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));
6011
 
 else
6012
 
   sprintf(respt, "Boot catalog : -not-found-at-load-time-\n");
6013
 
 Xorriso_toc_line(xorriso, flag & 8);
6014
 
 
6015
 
 if(bin_path_valid)
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-");
6019
 
 else
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);
6025
 
 
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);
6031
 
     if(ret > 0)
6032
 
       sprintf(respt, "Boot image   : %s", Text_shellsafe(path, sfe, 0));
6033
 
     else
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);
6038
 
   }
6039
 
 }
6040
 
 ret= 1;
6041
 
ex:;
6042
 
 if(boots != NULL)
6043
 
   free(boots);
6044
 
 if(bootnodes != NULL);
6045
 
   free(bootnodes);
6046
 
 if(image != NULL)
6047
 
   iso_image_unref(image); /* release obtained reference */
6048
 
 return(ret);
6049
 
6050
 
 
6051
 
 
6052
 
/* @param flag
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
6056
 
*/
6057
 
int Xorriso_media_product(struct XorrisO *xorriso, int flag)
6058
 
{
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;
6064
 
 
6065
 
 respt= xorriso->result_line;
6066
 
 
6067
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
6068
 
                                "on attempt to print media product info",
6069
 
                                 flag & (2 | 16));
6070
 
 if(ret <= 0)
6071
 
   return(ret);
6072
 
 ret= burn_disc_get_media_id(drive, &product_id, &media_code1, &media_code2,
6073
 
                             &book_type, 0);
6074
 
 if(ret > 0) {
6075
 
   ret= burn_disc_get_profile(drive, &profile_no, profile_name);
6076
 
   if(ret <= 0)
6077
 
     return(ret);
6078
 
   sprintf(respt, "Media product: %s , ", product_id);
6079
 
   manuf= burn_guess_manufacturer(profile_no, media_code1, media_code2, 0);
6080
 
   if(manuf != NULL) {
6081
 
     if(strncmp(manuf, "Unknown ", 8) == 0)
6082
 
       sprintf(respt + strlen(respt), "(not found in manufacturer list)\n");
6083
 
     else
6084
 
       sprintf(respt + strlen(respt), "%s\n", manuf);
6085
 
   } else
6086
 
     sprintf(respt + strlen(respt), "(error during manufacturer lookup)\n");
6087
 
   free(product_id);
6088
 
   free(media_code1);
6089
 
   free(media_code2);
6090
 
   if(book_type != NULL)
6091
 
     free(book_type);
6092
 
   if(manuf != NULL)
6093
 
     free(manuf);
6094
 
   Xorriso_toc_line(xorriso, flag & 8);
6095
 
 }
6096
 
 Xorriso_process_msg_queues(xorriso,0);
6097
 
 
6098
 
 return(1);
6099
 
}
6100
 
 
6101
 
 
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"
6110
 
*/
6111
 
int Xorriso_toc(struct XorrisO *xorriso, int flag)
6112
 
{
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;
6123
 
 char mem_text[80];
6124
 
 off_t start_byte= 0, num_free= 0, size;
6125
 
 unsigned dummy;
6126
 
 struct isoburn_toc_disc *disc= NULL;
6127
 
 struct isoburn_toc_session **sessions;
6128
 
 struct isoburn_toc_track **tracks;
6129
 
 int image_blocks= 0;
6130
 
 char volume_id[33];
6131
 
 struct burn_toc_entry next_toc_entry;
6132
 
 
6133
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
6134
 
                                "on attempt to print Table Of Content",
6135
 
                                 flag & (2 | 16));
6136
 
 if(ret<=0)
6137
 
   {ret= 0; goto ex;}
6138
 
 
6139
 
 respt= xorriso->result_line;
6140
 
 
6141
 
 if(strcmp(xorriso->indev, xorriso->outdev)==0)
6142
 
   is_inout_drive= 1;
6143
 
 if(flag&2)
6144
 
   devadr= xorriso->outdev;
6145
 
 else
6146
 
   devadr= xorriso->indev;
6147
 
 sprintf(respt, "Drive current: %s '%s'\n",
6148
 
         (is_inout_drive ? "-dev" : (flag&2 ? "-outdev" : "-indev")),
6149
 
         devadr);
6150
 
 Xorriso_toc_line(xorriso, flag & 8);
6151
 
 if(flag & 128)
6152
 
   {ret= 1; goto ex;}
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);
6157
 
 if(flag & 32)
6158
 
   {ret= 1; goto ex;}
6159
 
 
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)
6163
 
   profile_no= 0;
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);
6168
 
   else
6169
 
     sprintf(respt+strlen(respt), "%4.4Xh", profile_no);
6170
 
   drive_role= burn_drive_get_drive_role(drive);
6171
 
   if(drive_role==2)
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");
6176
 
 } else {
6177
 
    sprintf(respt+strlen(respt), "is not recognizable\n");
6178
 
    not_reconizable= 1;
6179
 
 }
6180
 
 Xorriso_toc_line(xorriso, flag & 8);
6181
 
 
6182
 
 if((flag & 64) || !(flag & 1)) {
6183
 
   Xorriso_media_product(xorriso, flag & (2 | 8 | 16));
6184
 
   if(xorriso->request_to_abort)
6185
 
     {ret= 1; goto ex;}
6186
 
 }
6187
 
 
6188
 
 sprintf(respt, "Media status : ");
6189
 
 if (s == BURN_DISC_FULL) {
6190
 
   if(not_reconizable)
6191
 
     sprintf(respt+strlen(respt), "is not recognizable\n");
6192
 
   else
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");
6200
 
 else
6201
 
   sprintf(respt+strlen(respt), "is not recognizable\n");
6202
 
 Xorriso_toc_line(xorriso, flag & 8);
6203
 
 
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);
6210
 
 }
6211
 
 if(s != BURN_DISC_FULL && s != BURN_DISC_APPENDABLE)
6212
 
   {ret= 1; goto ex;}
6213
 
 if(xorriso->request_to_abort)
6214
 
   {ret= 1; goto ex;}
6215
 
 
6216
 
 if(!(flag & 2))
6217
 
   Xorriso_show_boot_info(xorriso, 1 | (flag & 8) | ((flag & 1) << 1));
6218
 
 
6219
 
 disc= isoburn_toc_drive_get_disc(drive);
6220
 
 if(flag & 4)
6221
 
   sprintf(respt, "TOC layout   : %3s , %9s , %10s\n",
6222
 
           "Idx", "sbsector", "Size");
6223
 
 else
6224
 
   sprintf(respt, "TOC layout   : %3s , %9s , %10s , %s\n",
6225
 
           "Idx", "sbsector", "Size", "Volume Id");
6226
 
 if(!(flag&1))
6227
 
   Xorriso_toc_line(xorriso, flag & 8);
6228
 
 
6229
 
 if (disc==NULL) {
6230
 
   Xorriso_process_msg_queues(xorriso,0);
6231
 
   ret= isoburn_get_min_start_byte(drive, &start_byte, 0);
6232
 
   nwa= start_byte / 2048;
6233
 
   if(ret<=0) {
6234
 
     Xorriso_process_msg_queues(xorriso,0);
6235
 
     if(flag&1)
6236
 
       {ret= 0; goto ex;}
6237
 
     sprintf(xorriso->info_text, "Cannot obtain Table Of Content");
6238
 
     Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
6239
 
     {ret= 0; goto ex;}
6240
 
   }
6241
 
 
6242
 
   /* fabricate TOC */
6243
 
   typetext= "Other session";
6244
 
   if(flag & 4) {
6245
 
     ret= 0;
6246
 
     typetext= "Session      ";
6247
 
   } else
6248
 
     ret= isoburn_read_iso_head(drive, 0, &image_blocks, volume_id, 1);
6249
 
   if(ret>0) {
6250
 
     sprintf(respt, "ISO session  : %3d , %9d , %9ds , %s\n",
6251
 
             1, 0, image_blocks, volume_id);
6252
 
     nwa= image_blocks;
6253
 
   } else {
6254
 
     nwa= 0;
6255
 
     ret= burn_disc_get_formats(drive, &status, &size, &dummy,
6256
 
                                &num_formats);
6257
 
     if(ret>0 && status==BURN_FORMAT_IS_FORMATTED)
6258
 
       nwa= size/2048;
6259
 
     sprintf(respt, "%13s: %3d , %9d , %9ds , \n",
6260
 
             typetext, 1, 0, nwa);
6261
 
   } 
6262
 
   if(!(flag&1))
6263
 
     Xorriso_toc_line(xorriso, flag & 8);
6264
 
   last_track_start= lba;
6265
 
   num_payload= num_data= last_track_size= nwa;
6266
 
   num_sessions= 1;
6267
 
 } else {
6268
 
   sessions= isoburn_toc_disc_get_sessions(disc, &num_sessions);
6269
 
   for (session_no= 0; session_no<num_sessions && !(xorriso->request_to_abort);
6270
 
        session_no++) {
6271
 
     tracks= isoburn_toc_session_get_tracks(sessions[session_no], &num_tracks);
6272
 
     if (tracks==NULL)
6273
 
   continue;
6274
 
     for(track_no= 0; track_no<num_tracks && !(xorriso->request_to_abort);
6275
 
         track_no++) {
6276
 
       track_count++;
6277
 
       is_data= 0;
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;
6283
 
       } else {
6284
 
         lba= burn_msf_to_lba(toc_entry.pmin, toc_entry.psec,
6285
 
                              toc_entry.pframe);
6286
 
         if(track_no==num_tracks-1) {
6287
 
           isoburn_toc_session_get_leadout_entry(sessions[session_no],
6288
 
                                                 &next_toc_entry);
6289
 
         } else {
6290
 
           isoburn_toc_track_get_entry(tracks[track_no+1], &next_toc_entry);
6291
 
         }
6292
 
         track_size= burn_msf_to_lba(next_toc_entry.pmin, next_toc_entry.psec,
6293
 
                                     next_toc_entry.pframe) - lba;
6294
 
       }
6295
 
       if(flag&(1|4))
6296
 
         ret= 0;
6297
 
       else {
6298
 
         ret= isoburn_toc_track_get_emul(tracks[track_no], &emul_lba,
6299
 
                                         &image_blocks, volume_id, 0);
6300
 
         if(ret <= 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",
6307
 
                               0);
6308
 
           image_blocks= track_size;
6309
 
         }
6310
 
       }
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);
6314
 
       } else if(ret>0) {
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";
6319
 
         if(flag & 4)
6320
 
           typetext= "Session      ";
6321
 
         sprintf(respt, "%13s: %3d , %9d , %9ds , \n",
6322
 
                 typetext, session_no+1, lba, track_size);
6323
 
       } else {
6324
 
         typetext= "Other track  ";
6325
 
         if(flag & 4)
6326
 
           typetext= "Track        ";
6327
 
         sprintf(respt, "%13s: %3d , %9d , %9ds , \n",
6328
 
                 typetext, track_count, lba, track_size);
6329
 
       } 
6330
 
       if(!(flag&1))
6331
 
         Xorriso_toc_line(xorriso, flag & 8);
6332
 
       if(track_no>0)
6333
 
         num_payload+= lba - last_track_start;
6334
 
       last_track_start= lba;
6335
 
       if((toc_entry.control&7)>=4) /* data track */
6336
 
         is_data= 1;
6337
 
     }
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);
6342
 
     } else {
6343
 
       lba= burn_msf_to_lba(pmin, psec, pframe);
6344
 
       lba= burn_msf_to_lba(toc_entry.pmin, toc_entry.psec, toc_entry.pframe);
6345
 
     }
6346
 
     last_track_size= lba - last_track_start;
6347
 
     num_payload+= last_track_size;
6348
 
     if(is_data)
6349
 
       num_data+= last_track_size;
6350
 
   }
6351
 
 }
6352
 
 if(xorriso->request_to_abort)
6353
 
   {ret= 1; goto ex;}
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);
6357
 
 
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);
6363
 
 
6364
 
 sprintf(respt+strlen(respt), "\n");
6365
 
 Xorriso_toc_line(xorriso, flag & 8);
6366
 
 
6367
 
 if (s==BURN_DISC_APPENDABLE && nwa!=0) {
6368
 
   ret= isoburn_disc_track_lba_nwa(drive, NULL, 0, &lba, &nwa);
6369
 
   if(ret>0) {
6370
 
     sprintf(respt, "Media nwa    : %ds\n", nwa);
6371
 
     if(!(flag&1))
6372
 
       Xorriso_toc_line(xorriso, flag & 8);
6373
 
   }
6374
 
 }
6375
 
 
6376
 
 if (disc!=NULL)
6377
 
   isoburn_toc_disc_free(disc);
6378
 
 Xorriso_process_msg_queues(xorriso,0);
6379
 
 ret= 1;
6380
 
ex:;
6381
 
 return(ret);
6382
 
}
6383
 
 
6384
 
 
6385
 
int Xorriso_show_devices(struct XorrisO *xorriso, int flag)
6386
 
{
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];
6392
 
 struct stat stbuf;
6393
 
 
6394
 
 sprintf(xorriso->info_text, "Beginning to scan for devices ...\n");
6395
 
 Xorriso_info(xorriso,0);
6396
 
 
6397
 
 burn_drive_clear_whitelist(); 
6398
 
 while(!burn_drive_scan(&drive_list, &drive_count)) {
6399
 
   Xorriso_process_msg_queues(xorriso,0);
6400
 
   usleep(100000);
6401
 
 }
6402
 
 Xorriso_process_msg_queues(xorriso,0);
6403
 
 if(drive_count <= 0) {
6404
 
 
6405
 
   /* >>> was a drive_list created at all ? */
6406
 
   /* >>> must it be freed ? */
6407
 
 
6408
 
   sprintf(xorriso->info_text, "No drives found");
6409
 
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
6410
 
   return(0);
6411
 
 }
6412
 
 sprintf(xorriso->info_text, "Full drive scan done\n");
6413
 
 Xorriso_info(xorriso,0);
6414
 
 
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);
6424
 
 }
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);
6431
 
   } else { 
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';
6439
 
   }
6440
 
   sprintf(respt, "%d  -dev '%s' ", i, adr);
6441
 
   pad= max_dev_len-strlen(adr);
6442
 
   if(pad>0)
6443
 
     for(j= 0; j<pad; j++)
6444
 
       strcat(respt, " ");
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);
6448
 
 }
6449
 
 sprintf(xorriso->info_text, "-----------------------------------------------------------------------------\n");
6450
 
 Xorriso_info(xorriso,0);
6451
 
 
6452
 
 burn_drive_info_free(drive_list);
6453
 
 Xorriso_process_msg_queues(xorriso,0);
6454
 
 return(1);
6455
 
}
6456
 
 
6457
 
 
6458
 
int Xorriso_tell_media_space(struct XorrisO *xorriso,
6459
 
                             int *media_space, int *free_space, int flag)
6460
 
{
6461
 
 int ret;
6462
 
 struct burn_drive_info *dinfo;
6463
 
 struct burn_drive *drive;
6464
 
 struct burn_write_opts *burn_options;
6465
 
 
6466
 
 (*free_space)= (*media_space)= 0;
6467
 
 
6468
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
6469
 
                                "on attempt to -tell_media_space", 2);
6470
 
 if(ret<=0)
6471
 
   return(0);
6472
 
 
6473
 
 ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0);
6474
 
 if(ret<=0)
6475
 
   return(-1);
6476
 
 (*free_space)= (*media_space)=
6477
 
              isoburn_disc_available_space(drive, burn_options) / (off_t) 2048;
6478
 
 burn_write_opts_free(burn_options);
6479
 
 
6480
 
 if(xorriso->volset_change_pending) {
6481
 
   ret= Xorriso_write_session(xorriso, 1);
6482
 
   if(ret>0)
6483
 
     (*free_space)-= ret;
6484
 
 }
6485
 
 Xorriso_process_msg_queues(xorriso,0);
6486
 
 return(1);
6487
 
}
6488
 
 
6489
 
 
6490
 
/* @param flag bit0= fast
6491
 
               bit1= deformat
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
6495
 
*/
6496
 
int Xorriso_blank_media(struct XorrisO *xorriso, int flag)
6497
 
{
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];
6506
 
 time_t start_time;
6507
 
 char mode_names[4][80]= {"all", "fast", "deformat", "deformat_quickest"};
6508
 
 
6509
 
 ret= Xorriso_may_burn(xorriso, 0);
6510
 
 if(ret <= 0)
6511
 
   return(0);
6512
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
6513
 
                                "on attempt to -blank", 2);
6514
 
 if(ret<=0)
6515
 
   return(0);
6516
 
 
6517
 
 burn_disc_get_profile(drive, &current_profile, current_profile_name);
6518
 
 
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. */
6523
 
   if(flag&2)
6524
 
     do_deformat= 1;
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);
6533
 
     flag&= ~1;
6534
 
   }
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);
6538
 
   return 2;
6539
 
 } else if(disc_state==BURN_DISC_FULL || disc_state==BURN_DISC_APPENDABLE) {
6540
 
   ;
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);
6544
 
   return 0;
6545
 
 } else {
6546
 
   sprintf(xorriso->info_text, "Unsuitable drive and media state");
6547
 
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
6548
 
   return 0;
6549
 
 }
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);
6553
 
   return 0;
6554
 
 }
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);
6560
 
   return(1);
6561
 
 }
6562
 
 sprintf(xorriso->info_text, "Beginning to blank media in mode '%s'.\n",
6563
 
         mode_names[flag&3]);
6564
 
 Xorriso_info(xorriso,0);
6565
 
 
6566
 
 /* Important: do not return until burn_is_aborting() was checked */
6567
 
 Xorriso_set_signal_handling(xorriso, 1);
6568
 
 
6569
 
 if(do_deformat)
6570
 
   burn_disc_erase(drive, (flag&1));
6571
 
 else
6572
 
   isoburn_disc_erase(drive, (flag&1));
6573
 
 start_time= time(0);
6574
 
 usleep(1000000);
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);
6582
 
   usleep(1000000);
6583
 
 }
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);
6591
 
 } else {
6592
 
   sprintf(xorriso->info_text, "Blanking failed.");
6593
 
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
6594
 
 }
6595
 
 if(!(flag & 4)) {
6596
 
   ret= Xorriso_reaquire_outdev(xorriso, 
6597
 
                  2 + (xorriso->in_drive_handle == xorriso->out_drive_handle));
6598
 
   if(ret <= 0)
6599
 
     return(-1);
6600
 
 }
6601
 
 return(1);
6602
 
}
6603
 
 
6604
 
 
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
6612
 
*/
6613
 
int Xorriso_format_media(struct XorrisO *xorriso, off_t in_size, int flag)
6614
 
{
6615
 
 int ret, mode_flag= 0, index, status, num_formats;
6616
 
 unsigned dummy;
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];
6623
 
 off_t size= 0;
6624
 
 time_t start_time;
6625
 
 enum burn_disc_status disc_state;
6626
 
 
6627
 
 ret= Xorriso_may_burn(xorriso, 0);
6628
 
 if(ret <= 0)
6629
 
   return(0);
6630
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
6631
 
                                "on attempt to -format", 2);
6632
 
 if(ret<=0)
6633
 
   return(0);
6634
 
 
6635
 
 if(flag & 2) {
6636
 
   mode_flag= 0; /* format to given size */
6637
 
 } else {
6638
 
   mode_flag= 4; /* format to full size */
6639
 
 }
6640
 
 burn_disc_get_profile(drive, &current_profile, current_profile_name);
6641
 
 
6642
 
 if(flag&128) { /* by_index */
6643
 
   index= (flag>>8) & 0xff;
6644
 
   ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats);
6645
 
   if(ret<=0)
6646
 
     num_formats= 0;
6647
 
   if(ret<=0 || index<0 || index>=num_formats) {
6648
 
     if(num_formats>0)
6649
 
       sprintf(xorriso->info_text,
6650
 
            "-format by_index_%d: format descriptors range from index 0 to %d",
6651
 
            index, num_formats-1);
6652
 
     else
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);
6656
 
     return(0);
6657
 
   }
6658
 
   mode_flag|= (flag & 0xff80);
6659
 
   if(flag&1)
6660
 
     mode_flag|= (1<<6);
6661
 
 
6662
 
 } else if(current_profile == 0x12) { /* DVD+RAM */
6663
 
   if(!(flag & 2))
6664
 
     mode_flag= 6; /* format to default payload size */
6665
 
   if(flag&1)
6666
 
     mode_flag|= (1<<6);
6667
 
 
6668
 
 } else if(current_profile == 0x13) { /* DVD-RW */
6669
 
   if(flag&1) {
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);
6673
 
     return(2);
6674
 
   }
6675
 
 
6676
 
 } else if(current_profile == 0x14) { /* DVD-RW sequential */
6677
 
   if(flag & 1) {
6678
 
     size= 128*1024*1024;
6679
 
     mode_flag= 1; /* format to size, then write size of zeros */
6680
 
   } else
6681
 
     mode_flag= 4;
6682
 
 
6683
 
 } else if(current_profile == 0x1a) { /* DVD+RW */
6684
 
   if(flag&1) {
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);
6688
 
     return(2);
6689
 
   }
6690
 
 
6691
 
 } else if(current_profile == 0x41) { /* BD-R SRM */
6692
 
   if(!(flag & 2))
6693
 
     mode_flag= 6; /* format to default payload size */
6694
 
   if(flag&1)
6695
 
     mode_flag|= (1<<6);
6696
 
 
6697
 
 } else if(current_profile == 0x43) { /* BD-RE */
6698
 
   if(!(flag & 2))
6699
 
     mode_flag= 6; /* format to default payload size */
6700
 
   if(flag&1)
6701
 
     mode_flag|= (1<<6);
6702
 
 
6703
 
 } else {
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);
6710
 
   return(0);
6711
 
 }
6712
 
 if(!(flag & 1))
6713
 
   mode_flag|= 16; /* enable re-formatting */
6714
 
 
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);
6718
 
   return(1);
6719
 
 }
6720
 
 sprintf(xorriso->info_text, "Beginning to format media.\n");
6721
 
 Xorriso_info(xorriso, 0);
6722
 
 if(flag & 2)
6723
 
   size= in_size;
6724
 
 
6725
 
 /* Important: do not return until burn_is_aborting() was checked */
6726
 
 Xorriso_set_signal_handling(xorriso, 1);
6727
 
 
6728
 
 burn_disc_format(drive, size, mode_flag);
6729
 
 
6730
 
 start_time= time(0);
6731
 
 usleep(1000000);
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);
6739
 
   usleep(1000000);
6740
 
 }
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);
6745
 
 
6746
 
 if(burn_drive_wrote_well(drive)) {
6747
 
   sprintf(xorriso->info_text, "Formatting done\n");
6748
 
   Xorriso_info(xorriso,0);
6749
 
 } else {
6750
 
   sprintf(xorriso->info_text,
6751
 
           "libburn indicates failure with formatting."); 
6752
 
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
6753
 
   return(-1);
6754
 
 }
6755
 
 
6756
 
 if(!(flag & 4)) {
6757
 
   ret= Xorriso_reaquire_outdev(xorriso, 
6758
 
                  2 + (xorriso->in_drive_handle == xorriso->out_drive_handle));
6759
 
   if(ret <= 0)
6760
 
     return(-1);
6761
 
 }
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);
6766
 
   if(ret <= 0)
6767
 
     return(0);
6768
 
 }
6769
 
 return(1);
6770
 
}
6771
 
 
6772
 
 
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
6776
 
*/
6777
 
int Xorriso_blank_as_needed(struct XorrisO *xorriso, int flag)
6778
 
{
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;
6783
 
 unsigned dummy;
6784
 
 int current_profile;
6785
 
 char current_profile_name[80];
6786
 
 off_t size;
6787
 
 
6788
 
 ret= Xorriso_may_burn(xorriso, 0);
6789
 
 if(ret <= 0)
6790
 
   return(0);
6791
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
6792
 
                                "on attempt to blank or format", 2);
6793
 
 if(ret<=0)
6794
 
   return(0);
6795
 
 
6796
 
 burn_disc_get_profile(drive, &current_profile, current_profile_name);
6797
 
 
6798
 
 ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats);
6799
 
 if(ret>0) {
6800
 
   if(status==BURN_FORMAT_IS_FORMATTED)
6801
 
     is_formatted= 1;
6802
 
   else if(status == BURN_FORMAT_IS_UNFORMATTED)
6803
 
     is_formatted= 0;
6804
 
 }
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);
6811
 
     return(0);
6812
 
   }
6813
 
   if(!is_formatted) {
6814
 
     ret= Xorriso_format_media(xorriso, (off_t) 0, (current_profile == 0x43));
6815
 
     if(ret <= 0)
6816
 
       return(ret);
6817
 
     did_work= (ret == 1);
6818
 
   }
6819
 
 } else if(current_profile == 0x14 && (flag&4)) { /* DVD-RW sequential */
6820
 
   ret= Xorriso_format_media(xorriso, (off_t) 0, 0);
6821
 
   if(ret <= 0)
6822
 
     return(ret);
6823
 
   did_work= (ret == 1);
6824
 
 } else if(current_profile == 0x41) { /* BD-R SRM */
6825
 
   if(!is_formatted) {
6826
 
     ret= Xorriso_format_media(xorriso, (off_t) 0, 1);
6827
 
     if(ret <= 0)
6828
 
       return(ret);
6829
 
     did_work= (ret == 1);
6830
 
   }
6831
 
 }
6832
 
 
6833
 
 disc_state = isoburn_disc_get_status(drive);
6834
 
 if(disc_state != BURN_DISC_BLANK && !(flag&4)) {
6835
 
   ret= Xorriso_blank_media(xorriso, 1);
6836
 
   return(ret);
6837
 
 }
6838
 
 if(did_work)
6839
 
   return(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);
6843
 
 return(2);
6844
 
}
6845
 
 
6846
 
 
6847
 
/* @return <=0 error, 1 success
6848
 
*/
6849
 
int Xorriso_list_formats(struct XorrisO *xorriso, int flag)
6850
 
{
6851
 
 int ret, i, status, num_formats, profile_no, type;
6852
 
 off_t size;
6853
 
 unsigned dummy;
6854
 
 char status_text[80], profile_name[90], *respt;
6855
 
 struct burn_drive_info *dinfo;
6856
 
 struct burn_drive *drive;
6857
 
 
6858
 
 respt= xorriso->result_line;
6859
 
 
6860
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
6861
 
                         "on attempt to obtain format descriptor list", 1 | 2);
6862
 
 if(ret<=0)
6863
 
   return(0);
6864
 
 if(ret == 2)
6865
 
   goto ex;
6866
 
 ret = burn_disc_get_formats(drive, &status, &size, &dummy,
6867
 
                             &num_formats);
6868
 
 if(ret<=0) {
6869
 
   sprintf(xorriso->info_text, "Cannot obtain format list info");
6870
 
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
6871
 
   ret= 0; goto ex;
6872
 
 }
6873
 
 ret= Xorriso_toc(xorriso, 3);
6874
 
 if(ret<=0)
6875
 
   goto ex;
6876
 
 ret= burn_disc_get_profile(drive, &profile_no, profile_name);
6877
 
 if(ret<=0)
6878
 
   goto ex;
6879
 
 
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 ||
6885
 
      profile_no==0x43)
6886
 
     sprintf(status_text, "formatted, with %.1f MiB",
6887
 
                         ((double) size) / 1024.0 / 1024.0);
6888
 
   else
6889
 
     sprintf(status_text, "written, with %.1f MiB",
6890
 
                         ((double) size) / 1024.0 / 1024.0);
6891
 
 } else if(status == BURN_FORMAT_IS_UNKNOWN) {
6892
 
   if (profile_no > 0)
6893
 
     sprintf(status_text, "intermediate or unknown");
6894
 
   else
6895
 
     sprintf(status_text, "no media or unknown media");
6896
 
 } else
6897
 
   sprintf(status_text, "illegal status according to MMC-5");
6898
 
 sprintf(respt, "Format status: %s\n", status_text);
6899
 
 Xorriso_result(xorriso,0);
6900
 
 
6901
 
 for (i= 0; i < num_formats; i++) {
6902
 
   ret= burn_disc_get_format_descr(drive, i, &type, &size, &dummy);
6903
 
   if (ret <= 0)
6904
 
 continue;
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);
6908
 
 }
6909
 
 ret= 1;
6910
 
ex:;
6911
 
 return(ret);
6912
 
}
6913
 
 
6914
 
 
6915
 
/* @param flag bit0= cdrecord style
6916
 
               bit1= obtain outdrive, else indrive
6917
 
   @return <=0 error, 1 success
6918
 
*/
6919
 
int Xorriso_list_profiles(struct XorrisO *xorriso, int flag)
6920
 
{
6921
 
 int ret, i;
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;
6926
 
 
6927
 
 respt= xorriso->result_line;
6928
 
 
6929
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
6930
 
                          "on attempt to obtain profile list", 1 | (flag & 2));
6931
 
 if(ret<=0)
6932
 
   return(0);
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);
6936
 
   if(ret <= 0)
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);
6943
 
 }
6944
 
 return(1);
6945
 
}
6946
 
 
6947
 
 
6948
 
int Xorriso_cannot_create_iter(struct XorrisO *xorriso, int iso_error,int flag)
6949
 
{
6950
 
 Xorriso_process_msg_queues(xorriso,0);
6951
 
 Xorriso_report_iso_error(xorriso, "", iso_error, "Cannot create iter", 0,
6952
 
                          "FATAL", 1);
6953
 
 sprintf(xorriso->info_text, "Cannot create IsoDirIter object");
6954
 
 Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
6955
 
 return(1);
6956
 
}
6957
 
 
6958
 
 
6959
 
int Xorriso__node_lba_cmp(const void *node1, const void *node2)
6960
 
{
6961
 
 int ret;
6962
 
 int lba1= 0, lba2= 0;
6963
 
 
6964
 
 ret= Xorriso__file_start_lba(*((IsoNode **) node1), &lba1, 0);
6965
 
 if(ret!=1) 
6966
 
   lba1= 0;
6967
 
 ret= Xorriso__file_start_lba(*((IsoNode **) node2), &lba2, 0);
6968
 
 if(ret!=1)
6969
 
   lba2= 0;
6970
 
 return(lba1-lba2);  
6971
 
}
6972
 
 
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 !)
6980
 
*/
6981
 
int Xorriso_findi_iter(struct XorrisO *xorriso, IsoDir *dir_node, off_t *mem,
6982
 
                       IsoDirIter **iter, 
6983
 
                       IsoNode ***node_array, int *node_count, int *node_idx,
6984
 
                       IsoNode **iterated_node, int flag)
6985
 
{
6986
 
 int ret, i;
6987
 
 IsoNode *node;
6988
 
 off_t new_mem= 0;
6989
 
 char mem_text[80], limit_text[80];
6990
 
 
6991
 
 if(flag&1) {
6992
 
   *node_array= NULL;
6993
 
   *node_count= -1;
6994
 
   *node_idx= 0;
6995
 
   *iter= NULL;
6996
 
   ret= iso_dir_get_children(dir_node, iter);
6997
 
   if(ret<0) {
6998
 
cannot_iter:;
6999
 
     Xorriso_cannot_create_iter(xorriso, ret, 0);
7000
 
     return(-1);
7001
 
   }
7002
 
   if((flag&2)|(flag&4)) {
7003
 
     /* copy list of nodes and prepare soft iterator */
7004
 
     *node_count= 0;
7005
 
     while(iso_dir_iter_next(*iter, &node) == 1)
7006
 
       (*node_count)++;
7007
 
     iso_dir_iter_free(*iter);
7008
 
     *iter= NULL;
7009
 
 
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);
7018
 
       *node_count= -1;
7019
 
       return(-1);
7020
 
     }
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);
7027
 
       *node_count= -1;
7028
 
       return(-1);
7029
 
     }
7030
 
     *mem= new_mem;
7031
 
     ret= iso_dir_get_children(dir_node, iter);
7032
 
     if(ret<0)
7033
 
       goto cannot_iter;
7034
 
     while(iso_dir_iter_next(*iter, &node) == 1 && *node_idx < *node_count) {
7035
 
       (*node_array)[*node_idx]= node;
7036
 
       iso_node_ref(node);
7037
 
       (*node_idx)++;
7038
 
     }
7039
 
     iso_dir_iter_free(*iter);
7040
 
     *iter= NULL;
7041
 
     *node_count= *node_idx;
7042
 
     *node_idx= 0;
7043
 
     if((flag&4) && *node_count>1)
7044
 
       qsort(*node_array, *node_count, sizeof(IsoNode *),
7045
 
             Xorriso__node_lba_cmp);
7046
 
   }
7047
 
 }
7048
 
 
7049
 
 if(flag&(1<<31)) {
7050
 
   if(*node_count>=0 && *node_array!=NULL) {
7051
 
     for(i= 0; i<*node_count; i++)
7052
 
       iso_node_unref((*node_array)[i]);
7053
 
     free(*node_array);
7054
 
     *node_array= NULL;
7055
 
     *node_count= -1;
7056
 
     *node_idx= 0;
7057
 
   } else {
7058
 
     if(*iter!=NULL)
7059
 
       iso_dir_iter_free(*iter);
7060
 
     *iter= NULL;
7061
 
   }
7062
 
 }
7063
 
 
7064
 
 if(flag&(1|(1<<31))) 
7065
 
   return(1);
7066
 
 if(*node_count>=0) {
7067
 
   /* return next node_array element */
7068
 
   if(*node_idx>=*node_count)
7069
 
     return(0);
7070
 
   *iterated_node= (*node_array)[*node_idx];
7071
 
   (*node_idx)++;
7072
 
 } else {
7073
 
   ret= iso_dir_iter_next(*iter, iterated_node);
7074
 
   return(ret == 1);
7075
 
 }
7076
 
 return(1);
7077
 
}
7078
 
 
7079
 
 
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
7090
 
   @return   <=0 = error
7091
 
               1 = removed simple node 
7092
 
               2 = removed directory or tree
7093
 
               3 = did not remove on user revocation
7094
 
*/
7095
 
int Xorriso_rmi(struct XorrisO *xorriso, void *boss_iter, off_t boss_mem,
7096
 
                char *path, int flag)
7097
 
{
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;
7102
 
 IsoImage *volume;
7103
 
 char *sub_name, *name;
7104
 
 char *sfe= NULL, *sub_path= NULL;
7105
 
 off_t mem;
7106
 
 IsoNode **node_array= NULL;
7107
 
 int node_count= 0, node_idx;
7108
 
 
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);
7114
 
   {ret= -1; goto ex;}
7115
 
 }
7116
 
 
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.
7122
 
 */
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);
7128
 
   ret= -1; goto ex;
7129
 
 }
7130
 
#endif /* Libisofs_iso_dir_iter_sufficienT */
7131
 
 
7132
 
 ret= Xorriso_get_volume(xorriso, &volume, 0);
7133
 
 if(ret<=0)
7134
 
   goto ex;
7135
 
 
7136
 
 if(Xorriso_much_too_long(xorriso, strlen(path), 0)<=0)
7137
 
   {ret= 0; goto ex;}
7138
 
 ret= Xorriso_node_from_path(xorriso, volume, path, &victim_node, 0);
7139
 
 if(ret<=0)
7140
 
   goto ex;
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);
7145
 
   {ret= 0; goto ex;}
7146
 
 }
7147
 
 
7148
 
 if(LIBISO_ISDIR(victim_node))
7149
 
   is_dir= 1;
7150
 
 if(!is_dir) {
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);
7155
 
     ret= 0; goto ex;
7156
 
   }
7157
 
 } else {
7158
 
   if(flag&1) { /* rm -r */
7159
 
     if((xorriso->do_reassure==1 && !xorriso->request_not_to_ask) ||
7160
 
        (flag&32)) {
7161
 
       /* Iterate over subordinates and delete them */
7162
 
       mem= boss_mem;
7163
 
 
7164
 
       ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem,
7165
 
                         &iter, &node_array, &node_count, &node_idx,
7166
 
                         &node, 1|2);
7167
 
       if(ret<=0) {
7168
 
cannot_create_iter:;
7169
 
         Xorriso_cannot_create_iter(xorriso, ret, 0);
7170
 
         ret= -1; goto ex;
7171
 
       }
7172
 
       pl= strlen(path);
7173
 
       strcpy(sub_path, path);
7174
 
       if(pl==0 || sub_path[pl-1]!='/') {
7175
 
         sub_path[pl++]= '/';
7176
 
         sub_path[pl]= 0;
7177
 
       }
7178
 
       sub_name= sub_path+pl;
7179
 
       while(1) { 
7180
 
         ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, &iter,
7181
 
                                &node_array, &node_count, &node_idx, &node, 0);
7182
 
         if(ret<0)
7183
 
           goto ex;
7184
 
         if(ret==0 || xorriso->request_to_abort)
7185
 
       break;
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:;
7194
 
           not_removed= 1;
7195
 
           fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
7196
 
           if(fret<0)
7197
 
             goto dir_not_removed;
7198
 
         }
7199
 
       }
7200
 
       if(flag&32)
7201
 
         {ret= 2; goto ex;}
7202
 
 
7203
 
       if(not_removed) {
7204
 
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);
7208
 
         if(ret>0)
7209
 
           ret= 3;
7210
 
         goto ex;
7211
 
       }
7212
 
     }
7213
 
   } else {
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);
7218
 
       ret= 0; goto ex;
7219
 
     }
7220
 
 
7221
 
     ret= iso_dir_get_children((IsoDir *) victim_node, &iter);
7222
 
     Xorriso_process_msg_queues(xorriso,0);
7223
 
     if(ret<0)
7224
 
       goto cannot_create_iter;
7225
 
     if(ret>0) {
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);
7231
 
         ret= 0; goto ex;
7232
 
       }
7233
 
     }
7234
 
   }
7235
 
 }
7236
 
 
7237
 
 if(xorriso->request_to_abort)
7238
 
   {ret= 3; goto ex;}
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);
7246
 
   ret= 0; goto ex;
7247
 
 }
7248
 
 
7249
 
 while((xorriso->do_reassure==1 || (xorriso->do_reassure==2 && !(flag&4)))
7250
 
       && !xorriso->request_not_to_ask) {
7251
 
   /* ls -ld */
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);
7255
 
   if(flag&8)
7256
 
     sprintf(xorriso->info_text,
7257
 
  "File exists. Remove ?  n= keep old, y= remove, x= abort, @= stop asking\n");
7258
 
   else
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);
7263
 
   if(ret<=0)
7264
 
     goto ex;
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);
7270
 
     ret= 3; goto ex;
7271
 
   }
7272
 
   if(ret==3)
7273
 
 continue;
7274
 
   if(ret==6) /* yes */
7275
 
 break;
7276
 
   if(ret==4) { /* yes, do not ask again */
7277
 
     xorriso->request_not_to_ask= 1;
7278
 
 break;
7279
 
   }
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);
7284
 
     ret= 3; goto ex;
7285
 
   }
7286
 
 }
7287
 
 
7288
 
 if(!(flag & 64))
7289
 
   Xorriso_invalidate_di_item(xorriso, victim_node, 0);
7290
 
 
7291
 
#ifdef Libisofs_iso_dir_iter_sufficienT
7292
 
 
7293
 
 if(boss_iter!=NULL) {
7294
 
   ret= iso_dir_iter_remove((IsoDirIter *) boss_iter);
7295
 
   if(ret<0)
7296
 
     ret= -1;
7297
 
 } else
7298
 
   ret= iso_node_remove(victim_node);
7299
 
 
7300
 
#else /* ! Libisofs_iso_dir_iter_sufficienT */
7301
 
 
7302
 
 ret= iso_node_remove(victim_node);
7303
 
 
7304
 
#endif /* Libisofs_iso_dir_iter_sufficienT */
7305
 
 
7306
 
 Xorriso_process_msg_queues(xorriso,0);
7307
 
 if(ret<0) {
7308
 
   Xorriso_report_iso_error(xorriso, path, ret, "Cannot remove node", 0,
7309
 
                            "FATAL", 1);
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);
7314
 
   ret= -1; goto ex;
7315
 
 }
7316
 
 
7317
 
 if(flag&16)
7318
 
   xorriso->pacifier_count++;
7319
 
 Xorriso_set_change_pending(xorriso, 0);
7320
 
 ret= 1+!!is_dir;
7321
 
ex:;
7322
 
 if(sfe!=NULL)
7323
 
   free(sfe);
7324
 
 if(sub_path!=NULL)
7325
 
   free(sub_path);
7326
 
 Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, &iter,
7327
 
                    &node_array, &node_count, &node_idx, &node, (1<<31));
7328
 
 return(ret);
7329
 
7330
 
 
7331
 
 
7332
 
int Xorriso__node_name_cmp(const void *node1, const void *node2)
7333
 
{
7334
 
 char *name1, *name2;
7335
 
 
7336
 
 name1= (char *) iso_node_get_name(*((IsoNode **) node1));
7337
 
 name2= (char *) iso_node_get_name(*((IsoNode **) node2));
7338
 
 return(strcmp(name1,name2));
7339
 
}
7340
 
 
7341
 
 
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
7345
 
*/
7346
 
int Xorriso_sorted_node_array(struct XorrisO *xorriso, 
7347
 
                              IsoDir *dir_node,
7348
 
                              int *nodec, IsoNode ***node_array,
7349
 
                              off_t boss_mem, int flag)
7350
 
{
7351
 
 int i, ret, failed_at;
7352
 
 char *npt;
7353
 
 IsoDirIter *iter= NULL;
7354
 
 IsoNode *node;
7355
 
 off_t mem;
7356
 
 
7357
 
 mem= ((*nodec)+1)*sizeof(IsoNode *);
7358
 
 ret= Xorriso_check_temp_mem_limit(xorriso, mem+boss_mem, flag&2);
7359
 
 if(ret<=0)
7360
 
   return(ret);
7361
 
 
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);
7367
 
   return(-1);
7368
 
 }
7369
 
 
7370
 
 ret= iso_dir_get_children(dir_node, &iter);
7371
 
 if(ret<0) {
7372
 
   Xorriso_cannot_create_iter(xorriso, ret, 0);
7373
 
   return(-1);
7374
 
 }
7375
 
 
7376
 
 for(i= 0; iso_dir_iter_next(iter, &node) == 1 && i<*nodec; ) {
7377
 
   npt= (char *) iso_node_get_name(node);
7378
 
   if(!(flag&4)) {
7379
 
     ret= Xorriso_regexec(xorriso, npt, &failed_at, 0);
7380
 
     if(ret)
7381
 
 continue; /* no match */
7382
 
   }
7383
 
   if(flag&1)
7384
 
     if(!LIBISO_ISDIR(node))
7385
 
 continue;
7386
 
   (*node_array)[i++]= node;
7387
 
 }
7388
 
 iso_dir_iter_free(iter);
7389
 
 *nodec= i;
7390
 
 if(*nodec<=0)
7391
 
   return(1);
7392
 
 qsort(*node_array, *nodec, sizeof(IsoNode *), Xorriso__node_name_cmp);
7393
 
 return(1);
7394
 
}
7395
 
 
7396
 
 
7397
 
/* @param flag bit0= do not only sum up sizes but also print subdirs
7398
 
*/
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)
7402
 
{
7403
 
 int i, ret, no_sort= 0, filec= 0, l;
7404
 
 IsoDirIter *iter= NULL;
7405
 
 IsoNode *node, **node_array= NULL;
7406
 
 char *name;
7407
 
 off_t sub_size, report_size, mem= 0;
7408
 
 char *path= NULL, *show_path= NULL, *sfe= NULL;
7409
 
 
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);
7415
 
   {ret= -1; goto ex;}
7416
 
 }
7417
 
 
7418
 
 *size= 0;
7419
 
 ret= iso_dir_get_children(dir_node, &iter);
7420
 
 if(ret<0) {
7421
 
cannot_create_iter:;
7422
 
   Xorriso_cannot_create_iter(xorriso, ret, 0);
7423
 
   {ret= -1; goto ex;}
7424
 
 }
7425
 
 for(i= 0; iso_dir_iter_next(iter, &node) == 1; ) {
7426
 
   sub_size= 0;
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)
7430
 
       goto much_too_long;
7431
 
   if(LIBISO_ISDIR(node)) {
7432
 
     strcpy(path, abs_path);
7433
 
     if(Sfile_add_to_path(path, name, 0)<=0) {
7434
 
much_too_long:;
7435
 
       Xorriso_much_too_long(xorriso, strlen(path)+strlen(name)+1, 2);
7436
 
       {ret= -1; goto ex;}
7437
 
     }
7438
 
     filec++;
7439
 
     l= strlen(rel_path)+1;
7440
 
     mem+= l;
7441
 
     if(l % sizeof(char *))
7442
 
       mem+= sizeof(char *)-(l % sizeof(char *));
7443
 
     if(flag&1) /* diving and counting is done further below */
7444
 
 continue;
7445
 
     ret= Xorriso_show_du_subs(xorriso, (IsoDir *) node,
7446
 
                               path, show_path, &sub_size, boss_mem, 0);
7447
 
     if(ret<0)
7448
 
       goto ex;
7449
 
     if(ret==0)
7450
 
 continue;
7451
 
   }
7452
 
 
7453
 
   if(LIBISO_ISREG(node)) {
7454
 
     sub_size+= iso_file_get_size((IsoFile *) node)+2048;
7455
 
/*
7456
 
     sub_size+= iso_file_get_size((IsoFile *) node)+strlen(name)+1;
7457
 
*/
7458
 
   }
7459
 
 
7460
 
   if(sub_size>0)
7461
 
     (*size)+= sub_size;
7462
 
   Xorriso_process_msg_queues(xorriso,0);
7463
 
 }
7464
 
 
7465
 
 if(filec<=0 || !(flag&1))
7466
 
   {ret= 1; goto ex;}
7467
 
 
7468
 
 /* Reset iteration */
7469
 
 iso_dir_iter_free(iter);
7470
 
 iter= NULL;
7471
 
 Xorriso_process_msg_queues(xorriso,0);
7472
 
 
7473
 
 ret= Xorriso_sorted_node_array(xorriso, dir_node, &filec, &node_array,
7474
 
                                boss_mem, 1|2|4);
7475
 
 if(ret<0)
7476
 
   goto ex;
7477
 
 if(ret==0) {
7478
 
   no_sort= 1;
7479
 
   ret= iso_dir_get_children(dir_node, &iter);
7480
 
   if(ret<0)
7481
 
     goto cannot_create_iter;
7482
 
 }
7483
 
 
7484
 
 for(i= 0; (no_sort || i<filec) && !(xorriso->request_to_abort); i++) {
7485
 
   if(no_sort) {
7486
 
     ret= iso_dir_iter_next(iter, &node);
7487
 
     if(ret!=1)
7488
 
 break;
7489
 
     if(!LIBISO_ISDIR(node))
7490
 
 continue;
7491
 
   } else
7492
 
     node= node_array[i];
7493
 
 
7494
 
   sub_size= 0;
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)
7498
 
     goto much_too_long;
7499
 
   strcpy(path, abs_path);
7500
 
   if(Sfile_add_to_path(path, name, 0)<=0)
7501
 
     goto much_too_long;
7502
 
   ret= Xorriso_show_du_subs(xorriso, (IsoDir *) node,
7503
 
                             path, show_path, &sub_size, boss_mem+mem, flag&1);
7504
 
   if(ret<0)
7505
 
     goto ex;
7506
 
 
7507
 
   if(LIBISO_ISREG(node)) {
7508
 
     sub_size+= iso_file_get_size((IsoFile *) node)+2048;
7509
 
/*
7510
 
     sub_size+= iso_tree_node_get_size((IsoFile *) node)+strlen(name)+1;
7511
 
*/
7512
 
   }
7513
 
   if(sub_size>0)
7514
 
     (*size)+= sub_size;
7515
 
   report_size= sub_size/1024;
7516
 
   if(report_size*1024<sub_size)
7517
 
      report_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);
7522
 
 }
7523
 
 ret= 1;
7524
 
ex:;
7525
 
 if(sfe!=NULL)
7526
 
   free(sfe);
7527
 
 if(path!=NULL)
7528
 
   free(path);
7529
 
 if(show_path!=NULL)
7530
 
   free(show_path);
7531
 
 if(iter!=NULL)
7532
 
   iso_dir_iter_free(iter);
7533
 
 if(node_array!=NULL)
7534
 
   free((char *) node_array);
7535
 
 Xorriso_process_msg_queues(xorriso,0);
7536
 
 return(ret);
7537
 
}
7538
 
 
7539
 
 
7540
 
int Xorriso_sorted_dir_i(struct XorrisO *xorriso, IsoDir *dir_node,
7541
 
                         int *filec, char ***filev, off_t boss_mem, int flag)
7542
 
{
7543
 
 int i,j,ret;
7544
 
 IsoDirIter *iter= NULL;
7545
 
 IsoNode *node;
7546
 
 char *name;
7547
 
 off_t mem;
7548
 
 
7549
 
 (*filec)= 0;
7550
 
 (*filev)= NULL;
7551
 
 
7552
 
 ret= iso_dir_get_children(dir_node, &iter);
7553
 
 if(ret<0) {
7554
 
cannot_iter:;
7555
 
   Xorriso_cannot_create_iter(xorriso, ret, 0);
7556
 
   {ret= -1; goto ex;}
7557
 
 }
7558
 
 mem= 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;
7562
 
   (*filec)++;
7563
 
 }
7564
 
 iso_dir_iter_free(iter);
7565
 
 iter= NULL;
7566
 
 if(*filec==0)
7567
 
   {ret= 1; goto ex;}
7568
 
 
7569
 
 ret= Xorriso_check_temp_mem_limit(xorriso, mem+boss_mem, 2);
7570
 
 if(ret<=0)
7571
 
   goto ex;
7572
 
 (*filev)= (char **) calloc(*filec, sizeof(char *));
7573
 
 if(*filev==NULL)
7574
 
   {ret= -1; goto ex; }
7575
 
 ret= iso_dir_get_children(dir_node, &iter);
7576
 
 if(ret<0) 
7577
 
   goto cannot_iter;
7578
 
 for(i= 0; i<*filec; i++) {
7579
 
   ret= iso_dir_iter_next(iter, &node);
7580
 
   if(ret!=1)
7581
 
 break;
7582
 
   name= (char *) iso_node_get_name(node);
7583
 
   (*filev)[i]= strdup(name);
7584
 
   if((*filev)[i]==NULL) {
7585
 
     for(j= 0; j<i; j++)
7586
 
       if((*filev)[j]!=NULL)
7587
 
         free((*filev)[j]);
7588
 
     free((char *) (*filev));
7589
 
     ret= -1; goto ex;
7590
 
   }
7591
 
 }
7592
 
 Sort_argv(*filec, *filev, 0);
7593
 
 ret= 1;
7594
 
ex:;
7595
 
 if(iter!=NULL)
7596
 
   iso_dir_iter_free(iter);
7597
 
 return(ret);
7598
 
}
7599
 
 
7600
 
 
7601
 
/* @param flag bit0= long format
7602
 
               bit1= do not print count of nodes
7603
 
               bit2= du format
7604
 
               bit3= print directories as themselves (ls -d)
7605
 
*/
7606
 
int Xorriso_ls_filev(struct XorrisO *xorriso, char *wd,
7607
 
                     int filec, char **filev, off_t boss_mem, int flag)
7608
 
{
7609
 
 int i, ret, was_error= 0, dfilec= 0, pass, passes;
7610
 
 IsoNode *node;
7611
 
 IsoImage *volume;
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;
7615
 
 off_t size;
7616
 
 struct stat stbuf;
7617
 
 
7618
 
 rpt= xorriso->result_line;
7619
 
 
7620
 
 ret= Xorriso_get_volume(xorriso, &volume, 0);
7621
 
 if(ret<=0)
7622
 
   return(ret);
7623
 
 
7624
 
 Sort_argv(filec, filev, 0);
7625
 
 
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);
7629
 
   if(ret<=0) {
7630
 
     was_error++;
7631
 
 continue;
7632
 
   }
7633
 
   ret= Xorriso_node_from_path(xorriso, volume, path, &node, 1);
7634
 
   if(ret<=0) {
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);
7638
 
     was_error++;
7639
 
 continue;
7640
 
   }
7641
 
 }
7642
 
 
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)
7647
 
     return(!was_error);
7648
 
 }
7649
 
 
7650
 
 passes= 1+!(flag&(4|8));
7651
 
 for(pass= 0; pass<passes; pass++)
7652
 
 for(i= 0; i<filec && !(xorriso->request_to_abort); i++) {
7653
 
   rpt[0]= 0;
7654
 
   ret= Xorriso_make_abs_adr(xorriso, wd, filev[i], path, 1|2|4);
7655
 
   if(ret<=0)
7656
 
 continue;
7657
 
   ret= Xorriso_fake_stbuf(xorriso, path, &stbuf, &node, ((flag&4) >> 1) | 16);
7658
 
   if(ret<=0)
7659
 
 continue;
7660
 
   if(LIBISO_ISDIR(node)  && !(flag&(4|8))) {
7661
 
     if(pass==0)
7662
 
 continue;
7663
 
     if(filec>1) {
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);
7668
 
     }
7669
 
     ret= Xorriso_sorted_dir_i(xorriso, 
7670
 
                               (IsoDir *) node, &dfilec, &dfilev, boss_mem, 0);
7671
 
     if(ret<=0) {
7672
 
 
7673
 
       /* >>> libisofs iterator loop and single item Xorriso_lsx_filev() */;
7674
 
 
7675
 
     } else {
7676
 
       if(flag&1) {
7677
 
         sprintf(xorriso->result_line, "total %d\n", dfilec);
7678
 
         Xorriso_result(xorriso,0);
7679
 
       }
7680
 
       Xorriso_ls_filev(xorriso, path,
7681
 
                        dfilec, dfilev, boss_mem, (flag&1)|2|8);
7682
 
     }
7683
 
     if(dfilec>0)
7684
 
       Sfile_destroy_argv(&dfilec, &dfilev, 0);
7685
 
 continue;
7686
 
   } else
7687
 
     if(pass>0)
7688
 
 continue;
7689
 
   link_target[0]= 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);
7695
 
     if(ret<=0)
7696
 
 continue;
7697
 
     if(LIBISO_ISLNK(node)) {
7698
 
       if(Sfile_str(link_target, (char *) iso_symlink_get_dest(
7699
 
                                                   (IsoSymlink *) node), 0)<=0)
7700
 
         link_target[0]= 0;
7701
 
     }
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);
7707
 
       if(ret<0)
7708
 
         return(-1);
7709
 
       if(ret==0)
7710
 
 continue;
7711
 
     }
7712
 
     sprintf(rpt, "%7.f ",(double) (size/1024));
7713
 
   }
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));
7718
 
   else
7719
 
     sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n",
7720
 
             Text_shellsafe(filev[i], sfe, 0));
7721
 
   Xorriso_result(xorriso, 0);
7722
 
 }
7723
 
 return(!was_error);
7724
 
}
7725
 
 
7726
 
 
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
7734
 
*/
7735
 
int Xorriso_ls(struct XorrisO *xorriso, int flag)
7736
 
{
7737
 
 int ret, is_dir= 0, i, filec= 0, failed_at, no_sort= 0;
7738
 
 IsoNode *node, **node_array= NULL;
7739
 
 IsoDir *dir_node;
7740
 
 IsoImage *volume;
7741
 
 IsoDirIter *iter= NULL;
7742
 
 char sfe[5*SfileadrL], sfe2[5*SfileadrL], link_target[SfileadrL], *npt, *rpt;
7743
 
 struct stat stbuf;
7744
 
 
7745
 
 rpt= xorriso->result_line;
7746
 
 
7747
 
 ret= Xorriso_get_volume(xorriso, &volume, 0);
7748
 
 if(ret<=0)
7749
 
   return(ret);
7750
 
 
7751
 
 ret= Xorriso_node_from_path(xorriso, volume, xorriso->wdi, &node, 0);
7752
 
 if(ret<=0)
7753
 
   goto wdi_is_not_a_dir;
7754
 
 if(LIBISO_ISDIR(node))
7755
 
   is_dir= 1;
7756
 
 if(!is_dir) {
7757
 
wdi_is_not_a_dir:;
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);
7761
 
   ret= 0; goto ex;
7762
 
 }
7763
 
 if(flag&2)
7764
 
   {ret= 1; goto ex;}
7765
 
 
7766
 
 dir_node= (IsoDir *) node;
7767
 
 ret= iso_dir_get_children(dir_node, &iter);
7768
 
 if(ret<0) {
7769
 
cannot_create_iter:;
7770
 
   Xorriso_cannot_create_iter(xorriso, ret, 0);
7771
 
   {ret= -1; goto ex;}
7772
 
 }
7773
 
 Xorriso_process_msg_queues(xorriso,0);
7774
 
 
7775
 
 for(i= 0; iso_dir_iter_next(iter, &node) == 1; ) {
7776
 
   npt= (char *) iso_node_get_name(node);
7777
 
   if(!(flag&4)) {
7778
 
     ret= Xorriso_regexec(xorriso, npt, &failed_at, 0);
7779
 
     if(ret)
7780
 
 continue; /* no match */
7781
 
   }
7782
 
   filec++;
7783
 
 }
7784
 
 /* Reset iteration */
7785
 
 iso_dir_iter_free(iter);
7786
 
 iter= NULL;
7787
 
 Xorriso_process_msg_queues(xorriso,0);
7788
 
 if(flag&8)
7789
 
   {ret= filec; goto ex;}
7790
 
 sprintf(xorriso->info_text, "Valid ISO nodes found: %d\n", filec);
7791
 
 Xorriso_info(xorriso,1);
7792
 
 
7793
 
 ret= Xorriso_sorted_node_array(xorriso, dir_node, &filec, &node_array, 0,
7794
 
                                flag&4);
7795
 
 if(ret<0)
7796
 
   goto ex;
7797
 
 if(ret==0) {
7798
 
   no_sort= 1;
7799
 
   ret= iso_dir_get_children(dir_node, &iter);
7800
 
   if(ret<0)
7801
 
     goto cannot_create_iter;
7802
 
 }
7803
 
 
7804
 
 for(i= 0; i<filec && !(xorriso->request_to_abort); i++) {
7805
 
   if(no_sort) {
7806
 
     ret= iso_dir_iter_next(iter, &node);
7807
 
     if(ret!=1)
7808
 
 break;
7809
 
     npt= (char *) iso_node_get_name(node);
7810
 
     if(!(flag&4)) {
7811
 
       ret= Xorriso_regexec(xorriso, npt, &failed_at, 0);
7812
 
       if(ret)
7813
 
 continue; /* no match */
7814
 
     }
7815
 
   } else
7816
 
     node= node_array[i];
7817
 
 
7818
 
   npt= (char *) iso_node_get_name(node);
7819
 
   link_target[0]= 0;
7820
 
   if(LIBISO_ISLNK(node)) {
7821
 
     if(Sfile_str(link_target, (char *) iso_symlink_get_dest(
7822
 
                                                   (IsoSymlink *) node), 0)<=0)
7823
 
       link_target[0]= 0;
7824
 
   }
7825
 
   rpt[0]= 0;
7826
 
   if(flag&1) {
7827
 
     ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1);
7828
 
     if(ret<=0)
7829
 
 continue;
7830
 
     ret= Xorriso_format_ls_l(xorriso, &stbuf, 1);
7831
 
     if(ret<=0)
7832
 
 continue;
7833
 
   }
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));
7838
 
   else
7839
 
     sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n",
7840
 
             Text_shellsafe(npt, sfe, 0));
7841
 
   Xorriso_result(xorriso, 0);
7842
 
 }
7843
 
 
7844
 
 ret= 1;
7845
 
ex:;
7846
 
 if(iter!=NULL)
7847
 
   iso_dir_iter_free(iter);
7848
 
 Xorriso_process_msg_queues(xorriso,0);
7849
 
 if(node_array!=NULL)
7850
 
   free((char *) node_array);
7851
 
 return(ret);
7852
 
}
7853
 
 
7854
 
 
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
7857
 
*/
7858
 
int Xorriso_rename(struct XorrisO *xorriso, void *boss_iter,
7859
 
                   char *origin, char *dest, int flag)
7860
 
{
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;
7864
 
 IsoImage *volume;
7865
 
 IsoDir *origin_dir, *dest_dir;
7866
 
 IsoNode *node, *iso_node;
7867
 
 
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.
7873
 
 */
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);
7879
 
   return(-1);
7880
 
 }
7881
 
#endif /* Libisofs_iso_dir_iter_sufficienT */
7882
 
 
7883
 
 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, origin, eff_origin, 0);
7884
 
 if(ret<=0)
7885
 
   return(ret);
7886
 
 dest_ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, dest, eff_dest,1);
7887
 
 if(dest_ret<0)
7888
 
   return(dest_ret);
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);
7891
 
   if(ret<=0)
7892
 
     return(ret);
7893
 
 }
7894
 
 
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);
7898
 
 if(ol==0) {
7899
 
   sprintf(xorriso->info_text, "May not rename root directory");
7900
 
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
7901
 
   return(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);
7906
 
   return(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);
7913
 
   return(0);
7914
 
 }
7915
 
 
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);
7921
 
   return(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);
7926
 
   return(0);
7927
 
 } else if(dest_ret>0) {
7928
 
   ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, eff_dest, 1|8);
7929
 
   if(ret<=0)
7930
 
     return(0);
7931
 
   if(ret==3) {
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);
7935
 
     return(0);
7936
 
   }
7937
 
 }
7938
 
 
7939
 
 /* Ensure existence of destination directory */
7940
 
 strcpy(dir_adr, eff_dest);
7941
 
 cpt= strrchr(dir_adr, '/');
7942
 
 if(cpt==NULL)
7943
 
   cpt= dir_adr+strlen(dir_adr);
7944
 
 *cpt= 0;
7945
 
 if(dir_adr[0]!=0) {
7946
 
   ret= Xorriso_graft_in(xorriso, boss_iter, NULL, dir_adr,
7947
 
                         (off_t) 0, (off_t) 0, 1);
7948
 
   if(ret<=0)
7949
 
     return(ret);
7950
 
 }
7951
 
 
7952
 
 /* Move node */
7953
 
 ret= Xorriso_get_volume(xorriso, &volume, 0);
7954
 
 if(ret<=0)
7955
 
   return(ret);
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, '/');
7960
 
 if(cpt==NULL)
7961
 
   cpt= dir_adr+strlen(dir_adr);
7962
 
 *cpt= 0;
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);
7971
 
   return(-1);
7972
 
 }
7973
 
 ret= iso_node_take(node);
7974
 
 if(ret<0) {
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);
7980
 
   return(-1);
7981
 
 }
7982
 
 leafname= strrchr(eff_dest, '/');
7983
 
 if(leafname==NULL)
7984
 
   leafname= eff_dest;
7985
 
 else
7986
 
   leafname++;
7987
 
 
7988
 
 old_leafname= (char *) iso_node_get_name(node);
7989
 
 if(strcmp(leafname, old_leafname)!=0)
7990
 
   ret= iso_node_set_name(node, leafname);
7991
 
 else
7992
 
   ret= 1;
7993
 
 if(ret<0) {
7994
 
   Xorriso_process_msg_queues(xorriso,0);
7995
 
   Xorriso_report_iso_error(xorriso, eff_dest, 0, "Cannot set name", 0,
7996
 
                            "FAILURE", 1);
7997
 
   return(-1);
7998
 
 }
7999
 
 Xorriso_process_msg_queues(xorriso,0);
8000
 
 ret= iso_dir_add_node(dest_dir, node, 0);
8001
 
 if(ret<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);
8007
 
   return(-1);
8008
 
 }
8009
 
 return(1);
8010
 
}
8011
 
 
8012
 
 
8013
 
/* @param flag bit0= do not produce info message on success
8014
 
   @return 1=success,
8015
 
           0=was already directory, -1=was other type, -2=other error
8016
 
*/
8017
 
int Xorriso_mkdir(struct XorrisO *xorriso, char *path, int flag)
8018
 
{
8019
 
 int ret;
8020
 
 char eff_path[SfileadrL], sfe[5*SfileadrL];
8021
 
 
8022
 
 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 1);
8023
 
 if(ret<0)
8024
 
   return(-2);
8025
 
 if(ret>0) {
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));
8031
 
 }
8032
 
 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 2);
8033
 
 if(ret<0)
8034
 
   return(-2);
8035
 
 ret= Xorriso_graft_in(xorriso, NULL, NULL, eff_path, (off_t) 0, (off_t) 0, 1);
8036
 
 if(ret<=0)
8037
 
   return(-2);
8038
 
 if(!(flag&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);
8042
 
 }
8043
 
 return(1);
8044
 
}
8045
 
 
8046
 
 
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)
8050
 
*/
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)
8055
 
{
8056
 
 int ret, failed_at;
8057
 
 IsoDirIter *iter= NULL;
8058
 
 IsoNode *node;
8059
 
 char *name;
8060
 
 char *adr= NULL;
8061
 
 
8062
 
 adr= malloc(SfileadrL);
8063
 
 if(adr==NULL) {
8064
 
   Xorriso_no_malloc_memory(xorriso, &adr, 0);
8065
 
   {ret= -1; goto ex;}
8066
 
 }
8067
 
 
8068
 
 if(!(flag&2))
8069
 
   *dive_count= 0;
8070
 
 else
8071
 
   (*dive_count)++;
8072
 
 ret= Xorriso_check_for_root_pattern(xorriso, filec, filev, count_limit,
8073
 
                                     mem, (flag&1)|2);
8074
 
 if(ret!=2)
8075
 
   goto ex;
8076
 
 
8077
 
 ret= iso_dir_get_children(dir, &iter);
8078
 
 if(ret<0) {
8079
 
   Xorriso_cannot_create_iter(xorriso, ret, 0);
8080
 
   {ret= -1; goto ex;}
8081
 
 }
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);
8085
 
   if(ret<=0)
8086
 
     goto ex;
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 */
8090
 
 continue;
8091
 
 
8092
 
     if(!LIBISO_ISDIR(node)) {
8093
 
 
8094
 
       /* >>> How to deal with softlinks ? */
8095
 
 
8096
 
 continue;
8097
 
     }
8098
 
     /* dive deeper */
8099
 
     ret= Xorriso_obtain_pattern_files_i(
8100
 
                          xorriso, adr, (IsoDir *) node,
8101
 
                          filec, filev, count_limit, mem, dive_count, flag|2);
8102
 
     if(ret<=0)
8103
 
       goto ex;
8104
 
   } else {
8105
 
     ret= Xorriso_register_matched_adr(xorriso, adr, count_limit,
8106
 
                                       filec, filev, mem, (flag&1)|2);
8107
 
     if(ret<=0)
8108
 
       goto ex;
8109
 
   }
8110
 
 } 
8111
 
 ret= 1;
8112
 
ex:;
8113
 
 if(adr!=NULL)
8114
 
   free(adr);
8115
 
 if(flag&2)
8116
 
   (*dive_count)--;
8117
 
 if(iter != NULL)
8118
 
   iso_dir_iter_free(iter);
8119
 
 return(ret);
8120
 
}
8121
 
 
8122
 
 
8123
 
/* @param flag bit0= a match count !=1 is a FAILURE event
8124
 
               bit1= with bit0 tolerate 0 matches if pattern is a constant
8125
 
*/
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)
8129
 
{
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];
8133
 
 IsoImage *volume;
8134
 
 IsoDir *dir= NULL, *root_dir;
8135
 
 IsoNode *iso_node;
8136
 
 
8137
 
 *filec= 0;
8138
 
 *filev= NULL;
8139
 
 
8140
 
 xorriso->search_mode= 3;
8141
 
 xorriso->structured_search= 1;
8142
 
 
8143
 
 ret= Xorriso_get_volume(xorriso, &volume, 0);
8144
 
 if(ret<=0)
8145
 
   return(ret);
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);
8152
 
   ret= -1; goto ex;
8153
 
 }
8154
 
 
8155
 
 for(i= 0; i<num_patterns; i++) {
8156
 
   ret=  Xorriso_prepare_expansion_pattern(xorriso, patterns[i], 0);
8157
 
   if(ret<=0)
8158
 
     return(ret);
8159
 
   if(ret==2)
8160
 
     abs_adr= 4;
8161
 
   if(patterns[i][0]=='/' || abs_adr) {
8162
 
     dir= root_dir;
8163
 
     abs_adr= 4;
8164
 
   } else {
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.
8168
 
     */
8169
 
     ret= Xorriso_node_from_path(xorriso, volume, xorriso->wdi, &iso_node, 1);
8170
 
     dir= (IsoDir *) iso_node;
8171
 
     if(ret<=0) {
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);
8177
 
       ret= 0; goto ex;
8178
 
     }
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);
8183
 
       ret= 0; goto ex;
8184
 
     }
8185
 
   }
8186
 
 
8187
 
   /* count the matches */
8188
 
   was_count= count;
8189
 
   ret= Xorriso_obtain_pattern_files_i(xorriso, "", dir, &count, NULL, 0,
8190
 
                                       mem, &dive_count, 1 | abs_adr);
8191
 
   if(ret<=0)
8192
 
     goto ex;
8193
 
   if(was_count==count && strcmp(patterns[i],"*")!=0 && (flag&3)!=1) {
8194
 
     count++;
8195
 
     Xorriso_eval_nonmatch(xorriso, patterns[i], &nonconst_mismatches, mem, 0);
8196
 
   }
8197
 
 }
8198
 
 
8199
 
 ret= Xorriso_check_matchcount(xorriso, count, nonconst_mismatches,
8200
 
                               num_patterns, patterns, (flag&1)|2);
8201
 
 if(ret<=0)
8202
 
   goto ex;
8203
 
 count+= extra_filec;
8204
 
 mem+= extra_filec*sizeof(char *);
8205
 
 if(count<=0)
8206
 
   {ret= 0; goto ex;}
8207
 
 ret= Xorriso_alloc_pattern_mem(xorriso, *mem, count, filev, 0);
8208
 
 if(ret<=0)
8209
 
   goto ex;
8210
 
 /* now store addresses */
8211
 
 for(i= 0; i<num_patterns; i++) {
8212
 
   ret=  Xorriso_prepare_expansion_pattern(xorriso, patterns[i], 0);
8213
 
   if(ret<=0)
8214
 
     return(ret);
8215
 
   if(ret==2)
8216
 
     abs_adr= 4;
8217
 
 
8218
 
   was_filec= *filec;
8219
 
   ret= Xorriso_obtain_pattern_files_i(xorriso, "", dir, filec, *filev, count,
8220
 
                                       mem, &dive_count, abs_adr);
8221
 
   if(ret<=0)
8222
 
     goto ex;
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);
8228
 
       ret= -1; goto ex;
8229
 
     }
8230
 
     (*filec)++;
8231
 
   } 
8232
 
 }
8233
 
 ret= 1;
8234
 
ex:;
8235
 
 if(ret<=0) {
8236
 
   if(filev!=NULL)
8237
 
     Sfile_destroy_argv(&count, filev, 0);
8238
 
   *filec= 0;
8239
 
 }
8240
 
 return(ret);
8241
 
}
8242
 
 
8243
 
 
8244
 
int Xorriso_set_st_mode(struct XorrisO *xorriso, char *in_path,
8245
 
                        mode_t mode_and, mode_t mode_or, int flag)
8246
 
{
8247
 
 mode_t mode= 0;
8248
 
 int ret;
8249
 
 IsoNode *node;
8250
 
 char sfe[5*SfileadrL], path[SfileadrL];
8251
 
 
8252
 
 ret= Xorriso_get_node_by_path(xorriso, in_path, path, &node, 0);
8253
 
 if(ret<=0)
8254
 
   return(ret);
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);
8264
 
 return(1);
8265
 
}
8266
 
 
8267
 
 
8268
 
int Xorriso_set_uid(struct XorrisO *xorriso, char *in_path, uid_t uid,
8269
 
                    int flag)
8270
 
{
8271
 
 int ret;
8272
 
 IsoNode *node;
8273
 
 
8274
 
 ret= Xorriso_get_node_by_path(xorriso, in_path, NULL, &node, 0);
8275
 
 if(ret<=0)
8276
 
   return(ret);
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);
8281
 
 return(1);
8282
 
}
8283
 
 
8284
 
 
8285
 
int Xorriso_set_gid(struct XorrisO *xorriso, char *in_path, gid_t gid,
8286
 
                    int flag)
8287
 
{
8288
 
 int ret;
8289
 
 IsoNode *node;
8290
 
 
8291
 
 ret= Xorriso_get_node_by_path(xorriso, in_path, NULL, &node, 0);
8292
 
 if(ret<=0)
8293
 
   return(ret);
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);
8298
 
 return(1);
8299
 
}
8300
 
 
8301
 
 
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,
8304
 
                    int flag)
8305
 
{
8306
 
 int ret;
8307
 
 IsoNode *node;
8308
 
 
8309
 
 ret= Xorriso_get_node_by_path(xorriso, in_path, NULL, &node, 0);
8310
 
 if(ret<=0)
8311
 
   return(ret);
8312
 
 if(flag&1)
8313
 
   iso_node_set_atime(node, t);
8314
 
 if(flag&2)
8315
 
   iso_node_set_ctime(node, t);
8316
 
 if(flag&4)
8317
 
   iso_node_set_mtime(node, t);
8318
 
 if(!(flag&(2|256)))
8319
 
   iso_node_set_ctime(node, time(NULL));
8320
 
 Xorriso_set_change_pending(xorriso, 0);
8321
 
 Xorriso_process_msg_queues(xorriso,0);
8322
 
 return(1);
8323
 
}
8324
 
 
8325
 
 
8326
 
int Xorriso__start_end_lbas(IsoNode *node,
8327
 
                            int *lba_count, int **start_lbas, int **end_lbas,
8328
 
                            off_t *size, int flag)
8329
 
{
8330
 
 int section_count= 0, ret, i;
8331
 
 struct iso_file_section *sections= NULL;
8332
 
 
8333
 
 *lba_count= 0;
8334
 
 *start_lbas= *end_lbas= NULL;
8335
 
 *size= 0;
8336
 
 if(!LIBISO_ISREG(node))
8337
 
   return(0);
8338
 
 *size= iso_file_get_size((IsoFile *) node);
8339
 
 ret= iso_file_get_old_image_sections((IsoFile *) node, &section_count,
8340
 
                                      &sections, 0);
8341
 
 if(ret < 0)
8342
 
   {ret= -1; goto ex;}
8343
 
 if(ret != 1 || section_count <= 0)
8344
 
   {ret= 0; goto ex;}
8345
 
 *start_lbas= calloc(section_count, sizeof(int));
8346
 
 *end_lbas= calloc(section_count, sizeof(int));
8347
 
 if(*start_lbas == NULL || *end_lbas == NULL)
8348
 
   {ret= -1; goto ex;}
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)
8353
 
     (*end_lbas)[i]++;
8354
 
 }
8355
 
 *lba_count= section_count;
8356
 
 ret= 1;
8357
 
ex:;
8358
 
 if(sections != NULL)
8359
 
   free((char *) sections);
8360
 
 if(ret <= 0) {
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;
8366
 
   *lba_count= 0;
8367
 
 }
8368
 
 return(ret);
8369
 
}
8370
 
 
8371
 
 
8372
 
int Xorriso__file_start_lba(IsoNode *node,
8373
 
                           int *lba, int flag)
8374
 
{
8375
 
 int *start_lbas= NULL, *end_lbas= NULL, lba_count= 0, i, ret;
8376
 
 off_t size;
8377
 
 
8378
 
 *lba= -1;
8379
 
 ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas,
8380
 
                              &size, 0);
8381
 
 if(ret <= 0)
8382
 
   return(ret);
8383
 
 for(i= 0; i < lba_count; i++) {
8384
 
   if(*lba < 0 || start_lbas[i] < *lba)
8385
 
     *lba= start_lbas[i];
8386
 
 }
8387
 
 if(start_lbas != NULL)
8388
 
   free((char *) start_lbas);
8389
 
 if(end_lbas != NULL)
8390
 
   free((char *) end_lbas);
8391
 
 if(*lba < 0)
8392
 
   return(0);
8393
 
 return(1);
8394
 
}
8395
 
 
8396
 
 
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
8400
 
*/
8401
 
int Xorriso_file_eval_damage(struct XorrisO *xorriso, IsoNode *node,
8402
 
                             off_t *damage_start, off_t *damage_end,
8403
 
                             int flag)
8404
 
{
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;
8409
 
 
8410
 
 *damage_start= *damage_end= -1;
8411
 
 map= xorriso->in_sector_map;
8412
 
 if(map == NULL)
8413
 
   return(0);
8414
 
 Sectorbitmap_get_layout(map, &sectors, &sector_size, 0);
8415
 
 sector_size/= 2048;
8416
 
 
8417
 
 ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas,
8418
 
                              &size, 0);
8419
 
 if(ret <= 0) {
8420
 
   Xorriso_process_msg_queues(xorriso, 0);
8421
 
   return(ret);
8422
 
 }
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;
8431
 
     }
8432
 
   }
8433
 
   sect_base+= ((off_t) 2048) *
8434
 
               ((off_t) (end_lbas[sect] - start_lbas[sect] + 1));
8435
 
 }
8436
 
 if(*damage_end > size)
8437
 
   *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)
8443
 
   return(0);
8444
 
 return(1);
8445
 
}
8446
 
 
8447
 
 
8448
 
int Xorriso_report_lba(struct XorrisO *xorriso, char *show_path,
8449
 
                       IsoNode *node, int flag)
8450
 
{
8451
 
 int ret, *start_lbas= NULL, *end_lbas= NULL, lba_count, i;
8452
 
 off_t size;
8453
 
 char sfe[5*SfileadrL];
8454
 
 
8455
 
 ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas,
8456
 
                              &size, 0);
8457
 
 if(ret < 0) {
8458
 
   Xorriso_process_msg_queues(xorriso, 0);
8459
 
   {ret= -1; goto ex;}
8460
 
 }
8461
 
 if(ret == 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);
8469
 
 }
8470
 
 ret= 1;
8471
 
ex:;
8472
 
 if(start_lbas != NULL)
8473
 
   free((char *) start_lbas);
8474
 
 if(end_lbas != NULL)
8475
 
   free((char *) end_lbas);
8476
 
 return(ret);
8477
 
}
8478
 
 
8479
 
 
8480
 
int Xorriso_report_damage(struct XorrisO *xorriso, char *show_path,
8481
 
                          IsoNode *node, int flag)
8482
 
{
8483
 
 int ret;
8484
 
 off_t size= 0, damage_start, damage_end;
8485
 
 char sfe[5*SfileadrL];
8486
 
 
8487
 
 ret= Xorriso_file_eval_damage(xorriso, node, &damage_start, &damage_end, 0);
8488
 
 if(ret < 0)
8489
 
   return(0);
8490
 
 
8491
 
 if(LIBISO_ISREG(node))
8492
 
   size= iso_file_get_size((IsoFile *) node);
8493
 
 if(ret > 0) {
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);
8498
 
 } else {
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);
8502
 
 }
8503
 
 return(1);
8504
 
}
8505
 
 
8506
 
 
8507
 
/* @return  see Xorriso_update_interpreter()
8508
 
*/
8509
 
int Xorriso_widen_hardlink(struct XorrisO *xorriso, void * boss_iter,
8510
 
                           IsoNode *node,
8511
 
                           char *abs_path, char *iso_prefix, char *disk_prefix,
8512
 
                           int flag)
8513
 
{
8514
 
 int ret= 0, idx, low, high, i, do_widen= 0, compare_result= 0;
8515
 
 char disk_path[SfileadrL];
8516
 
 
8517
 
 /* Lookup all di_array instances of node */
8518
 
 if(LIBISO_ISDIR(node))
8519
 
   return(3);
8520
 
 ret= Xorriso_search_di_range(xorriso, node, &idx, &low, &high, 2);
8521
 
 if(ret <= 0)
8522
 
   return(3);
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 */
8526
 
 continue;
8527
 
   if(xorriso->di_do_widen[i / 8] & (1 << (i % 8)))
8528
 
     do_widen= 1;
8529
 
   xorriso->di_do_widen[i / 8]&= ~(1 << (i % 8));
8530
 
 }
8531
 
 if(idx < 0 || !do_widen)
8532
 
   return(3);
8533
 
 
8534
 
 ret= Xorriso_pfx_disk_path(xorriso, abs_path, iso_prefix, disk_prefix,
8535
 
                            disk_path, 0);
8536
 
 if(ret <= 0)
8537
 
   return(ret);
8538
 
 ret= Sfile_type(disk_path, 1);
8539
 
 if(ret < 0)
8540
 
   return(3); /* does not exist on disk */
8541
 
 
8542
 
 /* >>> compare_result bit17 = is_split */;
8543
 
 
8544
 
 ret= Xorriso_update_interpreter(xorriso, boss_iter, compare_result, disk_path,
8545
 
                                 abs_path, 1);
8546
 
 if(ret <= 0)
8547
 
   return(ret);
8548
 
 return(ret);
8549
 
}
8550
 
 
8551
 
 
8552
 
/*
8553
 
  Apply the effect of mkisofs -r to a single node
8554
 
*/
8555
 
int Xorriso_mkisofs_lower_r(struct XorrisO *xorriso, IsoNode *node, int flag)
8556
 
{
8557
 
 mode_t perms;
8558
 
 
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);
8568
 
 return(1);
8569
 
}
8570
 
 
8571
 
 
8572
 
/* @param flag bit0= not a command parameter (directory iteration or recursion)
8573
 
               bit1= do not count deleted files with rm and rm_r
8574
 
   @return <=0 error,
8575
 
             1=ok
8576
 
             2=ok, node has been deleted,
8577
 
             3=ok, do not dive into directory (e.g. because it is a split file)
8578
 
*/
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)
8583
 
{
8584
 
 int ret= 0, type, action= 0, hflag, deleted= 0, no_dive= 0;
8585
 
 uid_t user= 0;
8586
 
 gid_t group= 0;
8587
 
 time_t date= 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;
8592
 
 
8593
 
 action= Findjob_get_action_parms(job, &target, &text_2, &user, &group,
8594
 
                                &mode_and, &mode_or, &type, &date, &subjob, 0);
8595
 
 if(action<0)
8596
 
   action= 0;
8597
 
 
8598
 
 hflag= 16*!(flag&2);
8599
 
 ret= 1;
8600
 
 if(action==1) { /* rm (including rmdir) */
8601
 
   ret= Xorriso_fake_stbuf(xorriso, abs_path, &dir_stbuf, &node, 1);
8602
 
   if(ret>0) {
8603
 
     if(S_ISDIR(dir_stbuf.st_mode))
8604
 
       hflag= 2;
8605
 
     ret= Xorriso_rmi(xorriso, boss_iter, boss_mem, abs_path, hflag);
8606
 
     deleted= 1;
8607
 
   }
8608
 
 } else if(action==2) { /* rm_r */
8609
 
   ret= Xorriso_rmi(xorriso, boss_iter, boss_mem, abs_path, 1|hflag);
8610
 
   deleted= 1;
8611
 
 } else if(action==3) {
8612
 
 
8613
 
   /* >>> mv target */;
8614
 
 
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));
8633
 
   if(ret==2)
8634
 
     deleted= 1;
8635
 
   if(ret==3)
8636
 
     no_dive= 1;
8637
 
   if(ret>=0)
8638
 
     ret= 1;
8639
 
 } else if(action==16 || action==18) { /* not_in_iso , add_missing */
8640
 
   ;
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 */
8668
 
   }
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);
8673
 
   if(ret==2)
8674
 
     deleted= 1;
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);
8679
 
   if(ret >= 0)
8680
 
     ret= 1;
8681
 
 } else if(action == 35) { /* check_md5 */
8682
 
   ret= Xorriso_check_md5(xorriso, (void *) node, show_path, 2);
8683
 
   if(ret == 0)
8684
 
     xorriso->find_check_md5_result|= 1;
8685
 
   else if(ret < 0)
8686
 
     xorriso->find_check_md5_result|= 2;
8687
 
   else if(ret == 1)
8688
 
     xorriso->find_check_md5_result|= 8;
8689
 
   else if(ret == 2)
8690
 
     xorriso->find_check_md5_result|= 4;
8691
 
   if(ret >= 0)
8692
 
     ret= 1;
8693
 
 } else if(action == 36) { /* make_md5 */
8694
 
   ret= Xorriso_make_md5(xorriso, (void *) node, show_path, 0);
8695
 
   if(ret >= 0)
8696
 
     ret= 1;
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);
8704
 
   ret= 1;
8705
 
 }
8706
 
 if(ret<=0)
8707
 
   return(ret);
8708
 
 if(deleted)
8709
 
   return(2);
8710
 
 if(no_dive)
8711
 
   return(3);
8712
 
 return(1);
8713
 
}
8714
 
 
8715
 
 
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)
8719
 
/*
8720
 
return:
8721
 
 <0 = error
8722
 
  0 = does not match
8723
 
  1 = does match
8724
 
  2 = immediate decision : does not match
8725
 
  3 = immediate decision : does match
8726
 
*/
8727
 
{
8728
 
 int value=0, ret, start_lba, end_lba;
8729
 
 int lba_count, *file_end_lbas= NULL, *file_start_lbas= NULL, i;
8730
 
 void *arg1, *arg2;
8731
 
 char ft, *decision, md5[16];
8732
 
 regmatch_t name_match;
8733
 
 off_t damage_start, damage_end, size;
8734
 
 void *xinfo_dummy;
8735
 
 IsoNode *node;
8736
 
 IsoStream *stream;
8737
 
 
8738
 
 if(ftest == NULL)
8739
 
   return(1);
8740
 
 
8741
 
 node= (IsoNode *) node_pt;
8742
 
 arg1= ftest->arg1;
8743
 
 arg2= ftest->arg2;
8744
 
 
8745
 
 if(node == NULL) {
8746
 
   if(ftest->test_type > 2 && ftest->test_type != 4) {
8747
 
     value= 0;
8748
 
     goto ex;
8749
 
   }
8750
 
 }
8751
 
 
8752
 
 switch(ftest->test_type) {
8753
 
 case 0: /* -false */
8754
 
   value= 0;
8755
 
 
8756
 
 break; case 1: /* -name *arg1 (regex in *arg2) */
8757
 
   ret= regexec(arg2, name, 1, &name_match, 0);
8758
 
   value= !ret;
8759
 
 
8760
 
 break; case 2: /* -type *arg1 */
8761
 
   value= 1;
8762
 
   ft= *((char *) arg1);
8763
 
   if(ft!=0) {
8764
 
     if(S_ISBLK(stbuf->st_mode)) {
8765
 
       if(ft!='b')
8766
 
         value= 0;
8767
 
     } else if(S_ISCHR(stbuf->st_mode)) {
8768
 
       if(ft!='c')
8769
 
         value= 0;
8770
 
     } else if(S_ISDIR(stbuf->st_mode)) {
8771
 
       if(ft=='m') {
8772
 
         if(node != NULL)
8773
 
           value= 0;
8774
 
         else if(boss_stbuf==NULL)
8775
 
           value= 0;
8776
 
         else if(boss_stbuf->st_dev == stbuf->st_dev)
8777
 
           value= 0;
8778
 
       } else if(ft!='d')
8779
 
         value= 0;
8780
 
     } else if(S_ISFIFO(stbuf->st_mode)) {
8781
 
       if(ft!='p')
8782
 
         value= 0;
8783
 
     } else if(S_ISREG(stbuf->st_mode)) {
8784
 
       if(ft!='f' && ft!='-')
8785
 
         value= 0;
8786
 
     } else if(((stbuf->st_mode)&S_IFMT)==S_IFLNK) {
8787
 
       if(ft!='l')
8788
 
         value= 0;
8789
 
     } else if(((stbuf->st_mode)&S_IFMT)==S_IFSOCK) {
8790
 
       if(ft!='s')
8791
 
         value= 0;
8792
 
     } else if((flag & 1) && ((stbuf->st_mode) & S_IFMT) == Xorriso_IFBOOT) {
8793
 
       if(ft!='e' || node == NULL)
8794
 
         value= 0;
8795
 
     } else {
8796
 
       if(ft!='X')
8797
 
         value= 0;
8798
 
     }
8799
 
   }
8800
 
 
8801
 
 break; case 3: /* -damaged */;
8802
 
   value= Xorriso_file_eval_damage(xorriso, node, &damage_start, &damage_end,
8803
 
                                   0);
8804
 
   if(value > 0)
8805
 
     value= 1;
8806
 
 
8807
 
 break; case 4: /* -lba_range *arg1 *arg2 */
8808
 
   value= 1;
8809
 
   start_lba= *((int *) ftest->arg1);
8810
 
   end_lba= *((int *) ftest->arg2);
8811
 
   if(node == NULL) {
8812
 
     value= !(start_lba >= 0);
8813
 
     goto ex;
8814
 
   }
8815
 
   ret= Xorriso__start_end_lbas(node, &lba_count,
8816
 
                                &file_start_lbas, &file_end_lbas, &size, 0);
8817
 
   if(ret <= 0) {
8818
 
     if(ret < 0)
8819
 
       Xorriso_process_msg_queues(xorriso, 0);
8820
 
     if(start_lba >= 0)
8821
 
       value= 0;
8822
 
   } else {
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)
8826
 
           value= 0;
8827
 
       } else {
8828
 
         if(file_end_lbas[i] >= -start_lba && file_start_lbas[i] <= -end_lba)
8829
 
           value= 0;
8830
 
       }
8831
 
     }
8832
 
   }
8833
 
 
8834
 
 break; case 5: /* -has_acl */
8835
 
   ret = Xorriso_getfacl(xorriso, (void *) node, "", NULL, 2);
8836
 
   if(ret <= 0) {
8837
 
     value= -1;
8838
 
     Xorriso_process_msg_queues(xorriso, 0);
8839
 
     goto ex;
8840
 
   }
8841
 
   value= (ret == 1);
8842
 
 
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)));
8847
 
   if(ret < 0) {
8848
 
     value= -1;
8849
 
     Xorriso_process_msg_queues(xorriso, 0);
8850
 
     goto ex;
8851
 
   }
8852
 
   value= (ret > 0);
8853
 
 
8854
 
 break; case 7: /* -has_aaip */
8855
 
   ret= iso_node_get_xinfo(node, aaip_xinfo_func, &xinfo_dummy);
8856
 
   if(ret < 0) {
8857
 
     value= -1;
8858
 
     Xorriso_process_msg_queues(xorriso, 0);
8859
 
     goto ex;
8860
 
   }
8861
 
   value= (ret > 0);
8862
 
 
8863
 
 break; case 8: /* -has_filter */
8864
 
   value= 0;
8865
 
   if(LIBISO_ISREG(node)) {
8866
 
     stream= iso_file_get_stream((IsoFile *) node);
8867
 
     if(iso_stream_get_input_stream(stream, 0) != NULL)
8868
 
       value= 1;
8869
 
   }
8870
 
 
8871
 
 break; case 9: /* -wanted_node arg1 (for internal use) */
8872
 
   value= (((IsoNode *) arg1) == node);
8873
 
 
8874
 
 break; case 10: /* -pending_data */
8875
 
   value= 1;
8876
 
   if(!LIBISO_ISREG(node)) {
8877
 
     value= 0;
8878
 
   } else {
8879
 
     ret= Xorriso__file_start_lba(node, &start_lba, 0);
8880
 
     if(ret > 0 && start_lba >= 0)
8881
 
       value= 0;
8882
 
   }
8883
 
 
8884
 
 break; case 11: /* -decision */
8885
 
   value= 2;
8886
 
   decision= (char *) arg1;
8887
 
   if(strcmp(decision, "yes") == 0 || strcmp(decision, "true") == 0)
8888
 
     value= 3;
8889
 
 
8890
 
 break; case 12: /* -prune */
8891
 
   value= 1;
8892
 
   ftest->boss->prune= 1;
8893
 
 
8894
 
 break; case 13: /* -wholename *arg1 (regex in *arg2) */
8895
 
   ret= regexec(arg2, path, 1, &name_match, 0);
8896
 
   value= !ret;
8897
 
 
8898
 
 break; case 15: /* -has_md5 */
8899
 
   ret= Xorriso_get_md5(xorriso, node, path, md5, 1);
8900
 
   value= (ret > 0);
8901
 
 
8902
 
 break; default:
8903
 
 
8904
 
   /* >>> complain about unknown test type */;
8905
 
 
8906
 
   value= -1;
8907
 
 
8908
 
 }
8909
 
 
8910
 
ex:;
8911
 
 if(ftest->invert && value<=1 && value>=0)
8912
 
   value= !value;
8913
 
 if(file_start_lbas != NULL)
8914
 
   free((char *) file_start_lbas);
8915
 
 if(file_end_lbas != NULL)
8916
 
   free((char *) file_end_lbas);
8917
 
 return(value);
8918
 
}
8919
 
 
8920
 
 
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)
8926
 
{
8927
 
 int ret;
8928
 
 
8929
 
 job->prune= 0;
8930
 
 ret= Findjob_test_2(xorriso, job, node, name, path, boss_stbuf, stbuf, 1);
8931
 
 if(ret <= 0)
8932
 
   return(ret);
8933
 
 return(1);
8934
 
}
8935
 
 
8936
 
 
8937
 
int Xorriso_findi_headline(struct XorrisO *xorriso, struct FindjoB *job,
8938
 
                           int flag)
8939
 
{
8940
 
 int action;
8941
 
 
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);
8952
 
 }
8953
 
 return(1);
8954
 
}
8955
 
 
8956
 
 
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
8962
 
*/
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)
8967
 
{
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;
8973
 
 struct stat stbuf;
8974
 
 char *name;
8975
 
 off_t mem;
8976
 
 IsoNode **node_array= NULL;
8977
 
 int node_count, node_idx;
8978
 
 char *path= NULL, *abs_path= NULL;
8979
 
 
8980
 
 if(xorriso->request_to_abort)
8981
 
   {ret= 0; goto ex;}
8982
 
 
8983
 
 path= malloc(SfileadrL);
8984
 
 abs_path= malloc(SfileadrL);
8985
 
 if(path==NULL || abs_path==NULL) {
8986
 
   Xorriso_no_malloc_memory(xorriso, &path, 0);
8987
 
   {ret= -1; goto ex;}
8988
 
 }
8989
 
 
8990
 
 action= Findjob_get_action(job, 0);
8991
 
 if(action<0)
8992
 
   action= 0;
8993
 
 if(!(flag & 1))
8994
 
   Xorriso_findi_headline(xorriso, job, 0);
8995
 
 
8996
 
 dir_node= (IsoDir *) dir_node_generic;
8997
 
 if(dir_node==NULL) {
8998
 
   ret= Xorriso_get_volume(xorriso, &volume, 0);
8999
 
   if(ret<=0)
9000
 
     {ret= -1; goto ex;}
9001
 
   ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, dir_path, path, 1|2|4);
9002
 
   if(ret<=0)
9003
 
     goto ex;
9004
 
   ret= Xorriso_node_from_path(xorriso, volume, path, &iso_node, 0);
9005
 
   dir_node= (IsoDir *) iso_node;
9006
 
   if(ret<=0)
9007
 
     {ret= 0; goto ex;}
9008
 
   ret= Xorriso_fake_stbuf(xorriso, "", dir_stbuf, &iso_node, 1);
9009
 
   if(ret<=0)
9010
 
     goto ex;
9011
 
 
9012
 
   name= strrchr(dir_path, '/');
9013
 
   if(name==NULL)
9014
 
     name= dir_path;
9015
 
   else
9016
 
     name++;
9017
 
 
9018
 
   ret= Xorriso_findi_test(xorriso, job, iso_node, name, path, NULL, dir_stbuf,
9019
 
                           depth, 0);
9020
 
   if(ret<0)
9021
 
     goto ex;
9022
 
   if(job->prune)
9023
 
     no_dive= 1;
9024
 
   if(ret>0) {
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,
9029
 
                               flag&(1|2));
9030
 
     deleted= (iso_node_get_parent(iso_node) == NULL); /* still in tree ? */
9031
 
     iso_node_unref(iso_node); /* eventually do real disposal */
9032
 
     if(ret<=0)
9033
 
       goto ex;
9034
 
     if(xorriso->request_to_abort)
9035
 
       {ret= 0; goto ex;}
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);
9039
 
       if(ret==0) {
9040
 
         deleted= 1;
9041
 
         {ret= 2; goto ex;}
9042
 
       }
9043
 
       if(ret<0)
9044
 
         {ret= 0; goto ex;}
9045
 
       dir_node= (IsoDir *) iso_node;
9046
 
       ret= Xorriso_fake_stbuf(xorriso, "", dir_stbuf, &iso_node, 1);
9047
 
       if(ret<=0)
9048
 
         goto ex;
9049
 
     }
9050
 
     if(ret==3)
9051
 
       no_dive= 1;
9052
 
   }
9053
 
 }
9054
 
 if(no_dive || !LIBISO_ISDIR((IsoNode *) dir_node))
9055
 
   {ret= 1; goto ex;}
9056
 
 if(action == 14 || action == 17 || (flag & 4))
9057
 
   if(Xorriso_is_split(xorriso, dir_path, (IsoNode *) dir_node, 1)>0)
9058
 
     {ret= 1; goto ex;}
9059
 
 
9060
 
 mem= boss_mem;
9061
 
 hflag= 1;
9062
 
 if(action==1 || action==2 || action==3 || action==17 || action == 28 ||
9063
 
    action == 32)
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,
9069
 
                         &node, hflag);
9070
 
 if(ret<=0)
9071
 
   goto ex;
9072
 
 while(1) {
9073
 
   ret= Xorriso_findi_iter(xorriso, dir_node, &mem, &iter,
9074
 
                           &node_array, &node_count, &node_idx, &node, 0);
9075
 
   if(ret<0)
9076
 
     goto ex;
9077
 
   if(ret==0)
9078
 
 break;
9079
 
   name= (char *) iso_node_get_name(node);
9080
 
   ret= Xorriso_make_abs_adr(xorriso, dir_path, name, path, 4);
9081
 
   if(ret<=0)
9082
 
     goto ex;
9083
 
   ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1);
9084
 
   if(ret<0)
9085
 
     goto ex;
9086
 
   if(ret==0)
9087
 
 continue;
9088
 
 
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.
9094
 
*/
9095
 
 
9096
 
   ret= Xorriso_findi_test(xorriso, job, node, name, path, dir_stbuf, &stbuf,
9097
 
                           depth, 0);
9098
 
   if(ret<0)
9099
 
     goto ex;
9100
 
   if(job->prune)
9101
 
     no_dive= 1;
9102
 
   if(ret>0) {
9103
 
     ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, path, abs_path, 1|2|4);
9104
 
     if(ret<=0)
9105
 
       goto ex;
9106
 
     ret= Xorriso_findi_action(xorriso, job, iter, mem,
9107
 
                               abs_path, path, node, depth, 1|(flag&2));
9108
 
     if(xorriso->request_to_abort)
9109
 
       {ret= 0; goto ex;}
9110
 
     if(ret==2) { /* node has been deleted */
9111
 
       /* re-determine node in case it has a new persona */ 
9112
 
       if(volume==NULL) {
9113
 
         ret= Xorriso_get_volume(xorriso, &volume, 0);
9114
 
         if(ret<=0)
9115
 
           {ret= -1; goto ex;}
9116
 
       }
9117
 
       ret= Xorriso_node_from_path(xorriso, volume, abs_path, &node, 1);
9118
 
       if(ret==0)
9119
 
 continue;
9120
 
       if(ret<0)
9121
 
         {ret= 0; goto ex;}
9122
 
       ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1);
9123
 
       if(ret<0)
9124
 
         goto ex;
9125
 
       if(ret==0)
9126
 
 continue;
9127
 
     }
9128
 
     no_dive= (ret==3);
9129
 
     if(ret<=0) {
9130
 
       if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0)
9131
 
         goto ex;
9132
 
     }
9133
 
   }
9134
 
 
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);
9138
 
     if(ret<0)
9139
 
       goto ex;
9140
 
   }
9141
 
 }
9142
 
 
9143
 
 ret= 1;
9144
 
ex:;
9145
 
 if(path!=NULL)
9146
 
   free(path);
9147
 
 if(abs_path!=NULL)
9148
 
   free(abs_path);
9149
 
 Xorriso_process_msg_queues(xorriso,0);
9150
 
 
9151
 
 Xorriso_findi_iter(xorriso, dir_node, &mem, &iter, &node_array, &node_count,
9152
 
                    &node_idx, &node, (1<<31));
9153
 
 if(ret<=0)
9154
 
   return(ret);
9155
 
 if(deleted)
9156
 
   return(2);
9157
 
 return(1);
9158
 
}
9159
 
 
9160
 
 
9161
 
int Xorriso_node_is_valid(struct XorrisO *xorriso, IsoNode *in_node, int flag)
9162
 
{
9163
 
 IsoNode *node, *parent;
9164
 
 
9165
 
 for(node= in_node; 1; node= parent) {
9166
 
   parent= (IsoNode *) iso_node_get_parent(node);
9167
 
   if(parent == node)
9168
 
 break;
9169
 
   if(parent == NULL)
9170
 
     return(0); /* Node is not in the tree (any more) */
9171
 
 }
9172
 
 return(1);
9173
 
}
9174
 
 
9175
 
 
9176
 
int Xorriso_path_from_node(struct XorrisO *xorriso, IsoNode *in_node,
9177
 
                           char path[SfileadrL], int flag)
9178
 
{
9179
 
 int ret, i, comp_count= 0;
9180
 
 IsoNode *node, *parent, **components= NULL;
9181
 
 char *wpt, *npt;
9182
 
 
9183
 
 for(node= in_node; 1; node= parent) {
9184
 
   parent= (IsoNode *) iso_node_get_parent(node);
9185
 
   if(parent == node)
9186
 
 break;
9187
 
   if(parent == NULL)
9188
 
     return(0); /* Node is not in the tree (any more) */
9189
 
   comp_count++;
9190
 
 }
9191
 
 if(comp_count == 0) {
9192
 
   strcpy(path, "/");
9193
 
   return(1);
9194
 
 }
9195
 
 components= calloc(comp_count, sizeof(IsoNode *));
9196
 
 if(components == NULL) {
9197
 
   Xorriso_no_malloc_memory(xorriso, NULL, 0);
9198
 
   ret= -1; goto ex;
9199
 
 }
9200
 
 i= comp_count;
9201
 
 for(node= in_node; 1; node= parent) {
9202
 
   parent= (IsoNode *) iso_node_get_parent(node);
9203
 
   if(parent == node)
9204
 
 break;
9205
 
   components[--i]= node;
9206
 
 }
9207
 
 
9208
 
 wpt= path;
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) {
9212
 
 
9213
 
     /* >>> path is getting much too long */;
9214
 
 
9215
 
     ret= -1; goto ex;
9216
 
   }
9217
 
   *(wpt++)= '/';
9218
 
   strcpy(wpt, npt);
9219
 
   wpt+= strlen(npt);
9220
 
   *wpt= 0;
9221
 
 }
9222
 
 ret= 1;
9223
 
ex:;
9224
 
 if(components != NULL)
9225
 
   free(components);
9226
 
 return(ret);
9227
 
}
9228
 
 
9229
 
 
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
9233
 
*/
9234
 
/* @param flag bit0= use lba rather than node pointer
9235
 
*/
9236
 
int Xorriso_path_from_lba(struct XorrisO *xorriso, IsoNode *node, int lba,
9237
 
                          char path[SfileadrL], int flag)
9238
 
{
9239
 
 int ret;
9240
 
 struct FindjoB *job= NULL;
9241
 
 struct stat dir_stbuf;
9242
 
 char *found_path;
9243
 
 
9244
 
 path[0]= 0;
9245
 
 if((flag & 1) && lba <= 0)
9246
 
   return(0);
9247
 
 
9248
 
 ret= Findjob_new(&job, "/", 0);
9249
 
 if(ret <= 0) {
9250
 
   Xorriso_no_findjob(xorriso, "path_from_node", 0);
9251
 
   return(ret);
9252
 
 }
9253
 
 if(flag & 1)
9254
 
   Findjob_set_lba_range(job, lba, 1, 0);
9255
 
 else
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);
9260
 
 if(ret > 0) {
9261
 
   ret= 1;
9262
 
   Findjob_get_found_path(job, &found_path, 0);
9263
 
   if(found_path == NULL)
9264
 
     ret= 0;
9265
 
   else if(Sfile_str(path, found_path, 0) <= 0)
9266
 
     ret= -1;
9267
 
 }
9268
 
 Findjob_destroy(&job, 0);
9269
 
 return(ret);
9270
 
}
9271
 
 
9272
 
 
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
9276
 
*/
9277
 
int Xorriso_findi_sorted(struct XorrisO *xorriso, struct FindjoB *job,
9278
 
                         off_t boss_mem, int filec, char **filev, int flag)
9279
 
{
9280
 
 int i, ret, find_flag= 0;
9281
 
 struct FindjoB array_job, *proxy_job= NULL, *hindmost= NULL, *hmboss= NULL;
9282
 
 struct stat dir_stbuf;
9283
 
 IsoNode *node;
9284
 
 char abs_path[SfileadrL];
9285
 
 off_t mem_needed= 0;
9286
 
 
9287
 
 array_job.start_path= NULL;
9288
 
 
9289
 
 if(job->action == 14 || job->action == 17)
9290
 
   find_flag|= 4;
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)
9294
 
     hmboss= hindmost;
9295
 
   if(hmboss == NULL)
9296
 
     {ret= -1; goto ex;}
9297
 
   memcpy(&array_job, hindmost, sizeof(struct FindjoB));
9298
 
   hmboss->subjob= &array_job;
9299
 
   proxy_job= job;
9300
 
 } else {
9301
 
   memcpy(&array_job, job, sizeof(struct FindjoB));
9302
 
   proxy_job= &array_job;
9303
 
   hindmost= job;
9304
 
 }
9305
 
 array_job.start_path= NULL; /* is owned by the original, not by array_job */
9306
 
 
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++) {
9311
 
   if(flag & 1) {
9312
 
     xorriso->node_counter++;
9313
 
 continue;
9314
 
   }
9315
 
   ret= Findjob_set_start_path(proxy_job, filev[i], 0);
9316
 
   if(ret <= 0)
9317
 
     goto ex;
9318
 
   ret= Xorriso_findi(xorriso, proxy_job, NULL, boss_mem, NULL,
9319
 
                      filev[i],  &dir_stbuf, 0, find_flag);
9320
 
   if(ret <= 0)
9321
 
     goto ex;
9322
 
 }
9323
 
 if(xorriso->node_counter <= 0)
9324
 
   {ret= 1; goto ex;}
9325
 
 
9326
 
 mem_needed= boss_mem + xorriso->node_counter * sizeof(IsoNode *);
9327
 
 if(!(flag &1)) {
9328
 
   ret= Xorriso_check_temp_mem_limit(xorriso, mem_needed, 0);
9329
 
   if(ret <= 0) {
9330
 
     /* Memory curbed : Perform unsorted find jobs */
9331
 
     if(hmboss != NULL)
9332
 
       hmboss->subjob= hindmost;
9333
 
     for(i= 0; i < filec; i++) {
9334
 
       ret= Findjob_set_start_path(job, filev[i], 0);
9335
 
       if(ret <= 0)
9336
 
         goto ex;
9337
 
       ret= Xorriso_findi(xorriso, job, NULL, boss_mem, NULL,
9338
 
                          filev[i], &dir_stbuf, 0, find_flag);
9339
 
       if(ret <= 0)
9340
 
         if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0)
9341
 
           goto ex;
9342
 
     }
9343
 
     {ret= 1; goto ex;}
9344
 
   }
9345
 
 }
9346
 
 
9347
 
 /* Copy matching nodes into allocated array */
9348
 
 ret= Xorriso_new_node_array(xorriso, xorriso->temp_mem_limit, 0, 0);
9349
 
 if(ret <= 0)
9350
 
   goto ex;
9351
 
 array_job.action= 31; /* internal: register */
9352
 
 xorriso->node_counter= 0;
9353
 
 for(i= 0; i < filec; i++) {
9354
 
   if(flag & 1) {
9355
 
     ret= Xorriso_get_node_by_path(xorriso, filev[i], NULL, &node, 0);
9356
 
     if(ret <= 0)
9357
 
       goto ex;
9358
 
     if(xorriso->node_counter < xorriso->node_array_size) {
9359
 
       xorriso->node_array[xorriso->node_counter++]= (void *) node;
9360
 
       iso_node_ref(node);
9361
 
     }
9362
 
 continue;
9363
 
   }
9364
 
   ret= Findjob_set_start_path(proxy_job, filev[i], 0);
9365
 
   if(ret <= 0)
9366
 
     goto ex;
9367
 
   ret= Xorriso_findi(xorriso, proxy_job, NULL, mem_needed, NULL,
9368
 
                      filev[i], &dir_stbuf, 0, find_flag);
9369
 
   if(ret <= 0)
9370
 
     goto ex;
9371
 
 }
9372
 
 
9373
 
 Xorriso_sort_node_array(xorriso, 0);
9374
 
 if(flag & 2)
9375
 
   {ret= 1; goto ex;}
9376
 
 
9377
 
 /* Perform job->action on xorriso->node_array */
9378
 
 
9379
 
 /* Headlines of actions report_damage , report_lba */;
9380
 
 Xorriso_findi_headline(xorriso, job, 0);
9381
 
 
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);
9385
 
   if(ret < 0)
9386
 
     goto ex;
9387
 
   if(ret == 0)
9388
 
 continue; /* node is deleted from tree meanwhile */
9389
 
 
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)
9394
 
       goto ex;
9395
 
 }
9396
 
 
9397
 
 ret= 1;
9398
 
ex:;
9399
 
 if(!(flag & (2 | 4)))
9400
 
   Xorriso_destroy_node_array(xorriso, 0);
9401
 
 if(hmboss != NULL)
9402
 
   hmboss->subjob= hindmost;
9403
 
 if(array_job.start_path != NULL)
9404
 
   free(array_job.start_path);
9405
 
 return(ret);
9406
 
}
9407
 
 
9408
 
 
9409
 
/* @param flag bit0= do not mark image as changed */
9410
 
int Xorriso_set_volid(struct XorrisO *xorriso, char *volid, int flag)
9411
 
{
9412
 
 int ret;
9413
 
 IsoImage *volume;
9414
 
 
9415
 
 if(xorriso->in_volset_handle == NULL)
9416
 
   return(2);
9417
 
 ret= Xorriso_get_volume(xorriso, &volume, 0);
9418
 
 if(ret<=0)
9419
 
   return(ret);
9420
 
 iso_image_set_volume_id(volume, volid);
9421
 
 if(!(flag&1))
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);
9426
 
 return(1);
9427
 
}
9428
 
 
9429
 
 
9430
 
int Xorriso_get_volid(struct XorrisO *xorriso, char volid[33], int flag)
9431
 
{
9432
 
 int ret;
9433
 
 IsoImage *volume;
9434
 
 
9435
 
 ret= Xorriso_get_volume(xorriso, &volume, 0);
9436
 
 if(ret<=0)
9437
 
   return(ret);
9438
 
 strncpy(volid, iso_image_get_volume_id(volume), 32);
9439
 
 volid[32]= 0;
9440
 
 return(1);
9441
 
}
9442
 
 
9443
 
 
9444
 
/* @param flag bit0=prepare for a burn run */
9445
 
int Xorriso_set_abort_severity(struct XorrisO *xorriso, int flag)
9446
 
{
9447
 
 int ret, abort_on_number;
9448
 
 char *sev_text;
9449
 
 static int note_number= -1, failure_number= -1;
9450
 
 
9451
 
 if(note_number==-1)
9452
 
   Xorriso__text_to_sev("NOTE", &note_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);
9457
 
 if(ret<=0)
9458
 
   return(ret);
9459
 
 if(abort_on_number<note_number)
9460
 
   sev_text= "NOTE";
9461
 
 else if(abort_on_number>failure_number)
9462
 
   sev_text= "FAILURE";
9463
 
 ret= iso_set_abort_severity(sev_text);
9464
 
 return(ret>=0);
9465
 
}
9466
 
 
9467
 
 
9468
 
int Xorriso_report_lib_versions(struct XorrisO *xorriso, int flag)
9469
 
{
9470
 
 int major, minor, micro;
9471
 
 int req_major, req_minor, req_micro;
9472
 
 
9473
 
 iso_lib_version(&major, &minor, &micro);
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, &micro);
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, &micro);
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);
9496
 
 return(1);
9497
 
}
9498
 
 
9499
 
 
9500
 
/* @param flag bit0= -inq
9501
 
               bit1= -checkdrive
9502
 
*/
9503
 
int Xorriso_atip(struct XorrisO *xorriso, int flag)
9504
 
{
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;
9513
 
 
9514
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
9515
 
                           "on attempt to print drive and media info", 2);
9516
 
 if(ret<=0)
9517
 
   return(0);
9518
 
 respt= xorriso->result_line;
9519
 
 sprintf(respt, "Device type    : ");
9520
 
 ret= burn_drive_get_drive_role(drive);
9521
 
 if(ret==0)
9522
 
   sprintf(respt+strlen(respt), "%s\n", "Emulated (null-drive)");
9523
 
 else if(ret==2)
9524
 
   sprintf(respt+strlen(respt), "%s\n",
9525
 
           "Emulated (stdio-drive, 2k random read-write)");
9526
 
 else if(ret==3)
9527
 
   sprintf(respt+strlen(respt), "%s\n",
9528
 
           "Emulated (stdio-drive, sequential write-only)");
9529
 
 else if(ret!=1)
9530
 
   sprintf(respt+strlen(respt), "%s\n","Emulated (stdio-drive)");
9531
 
 else
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);
9537
 
 if(flag&1)
9538
 
   return(1);
9539
 
 sprintf(respt, "Driver flags   : BURNFREE\n");
9540
 
 sprintf(respt+strlen(respt), "Supported modes: SAO TAO\n");
9541
 
 Xorriso_result(xorriso,1);
9542
 
 if(flag&2)
9543
 
   return(1);
9544
 
 
9545
 
 s= burn_disc_get_status(drive);
9546
 
 ret= burn_disc_get_profile(drive,&profile_number,profile_name);
9547
 
 if(ret<=0) {
9548
 
   profile_number= 0;
9549
 
   strcpy(profile_name, "-unidentified-");
9550
 
 }
9551
 
 if(s != BURN_DISC_UNSUITABLE) {
9552
 
   ret= burn_disc_read_atip(drive);
9553
 
   if(ret>0) {
9554
 
     ret= burn_drive_get_min_write_speed(drive);
9555
 
     x_speed_min= ((double) ret)/176.4;
9556
 
   }
9557
 
 }
9558
 
 if(s==BURN_DISC_EMPTY) {
9559
 
   sprintf(respt, "Current: none\n");
9560
 
   Xorriso_result(xorriso,1);
9561
 
   return(1);
9562
 
 } else 
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);
9574
 
   }
9575
 
 } else {
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");
9580
 
   else
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);
9585
 
     if(ret>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);
9594
 
     }
9595
 
   }
9596
 
   ret= burn_drive_get_write_speed(drive);
9597
 
   x_speed_max= ((double) ret)/176.4;
9598
 
   if(x_speed_min<0)
9599
 
     x_speed_min= x_speed_max;
9600
 
   sprintf(respt,
9601
 
          "  1T speed low:  %.f 1T speed high: %.f\n",x_speed_min,x_speed_max);
9602
 
   Xorriso_result(xorriso,1);
9603
 
 }
9604
 
 
9605
 
 ret= burn_disc_get_media_id(drive, &product_id, &media_code1, &media_code2,
9606
 
                                &book_type, 0);
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);
9612
 
 }
9613
 
 if(manuf != NULL) {
9614
 
   sprintf(respt, "Producer:      %s\n", manuf);
9615
 
   Xorriso_result(xorriso, 1);
9616
 
 }
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){
9621
 
   free(product_id);
9622
 
   free(media_code1);
9623
 
   free(media_code2);
9624
 
   if(book_type != NULL)
9625
 
     free(book_type);
9626
 
   product_id= media_code1= media_code2= book_type= NULL;
9627
 
   ret= burn_disc_get_media_id(drive, &product_id, &media_code1, &media_code2,
9628
 
                               &book_type, 1);
9629
 
   if(ret > 0) {
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);
9635
 
     }
9636
 
   }
9637
 
 }
9638
 
 if(manuf != NULL)
9639
 
   free(manuf);
9640
 
 if(media_code1 != NULL)
9641
 
   free(media_code1);
9642
 
 if(media_code2 != NULL)
9643
 
   free(media_code2);
9644
 
 if(book_type != NULL)
9645
 
   free(book_type);
9646
 
 if(product_id != NULL)
9647
 
   free(product_id);
9648
 
 return(1);
9649
 
}
9650
 
 
9651
 
 
9652
 
int Xorriso_update_in_sector_map(struct XorrisO *xorriso,
9653
 
                                 struct SpotlisT *spotlist, int read_chunk,
9654
 
                                 struct CheckmediajoB *job, int flag)
9655
 
{
9656
 
 int sectors, sector_size, sector_blocks, ret;
9657
 
 struct SectorbitmaP *map;
9658
 
 
9659
 
 Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
9660
 
 if(job->use_dev == 1)
9661
 
   return(1);
9662
 
 map= job->sector_map;
9663
 
 sectors= Spotlist_block_count(spotlist, 0);
9664
 
 if(sectors <= 0)
9665
 
   return(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);
9671
 
 if(ret <= 0)
9672
 
   return(ret);
9673
 
 if(map != NULL)
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);
9677
 
 return(ret);
9678
 
}
9679
 
 
9680
 
 
9681
 
/*
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
9686
 
*/
9687
 
int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
9688
 
                            char *head_buffer, struct CheckmediajoB *job,
9689
 
                            int flag)
9690
 
{
9691
 
 int ret, full_size, i;
9692
 
 char *headpt;
9693
 
 struct burn_drive_info *dinfo;
9694
 
 struct burn_drive *drive;
9695
 
 off_t seek_ret;
9696
 
 
9697
 
 ret= Xorriso_may_burn(xorriso, 0);
9698
 
 if(ret <= 0)
9699
 
   return(0);
9700
 
 if(flag & 1) {
9701
 
   ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
9702
 
                                 "on attempt to learn current session lba", 1);
9703
 
   if(ret<=0)
9704
 
     return(0);
9705
 
   ret= isoburn_disc_get_msc1(drive, &iso_lba);
9706
 
   if(ret<=0)
9707
 
     return(0);
9708
 
   drive= NULL; /* indev will not be used furtherly */
9709
 
 }
9710
 
 if(job == NULL) { 
9711
 
   ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
9712
 
                                  "on attempt to update at lba 0 to 31", 2);
9713
 
   if(ret<=0)
9714
 
     return(0);
9715
 
 }
9716
 
 if(iso_lba < 32)
9717
 
   return(2);
9718
 
 if(!(flag & 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);
9725
 
       if(ret <= 0) {
9726
 
         sprintf(xorriso->info_text,
9727
 
           "ISO image head at lba %d is marked as invalid blocks in file copy",
9728
 
           iso_lba); 
9729
 
         Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",
9730
 
                             0);
9731
 
          return(0);
9732
 
       }
9733
 
     }
9734
 
     seek_ret= lseek(job->data_to_fd, ((off_t) 2048) * (off_t) iso_lba,
9735
 
                     SEEK_SET);
9736
 
     if(seek_ret == -1)
9737
 
       ret= 0;
9738
 
     else
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);
9745
 
       return(0);
9746
 
     }
9747
 
   } else {
9748
 
     ret= isoburn_read_iso_head(drive, iso_lba, &isosize, head_buffer, 2);
9749
 
     if(ret<=0) {
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);
9754
 
       return(0);
9755
 
     }
9756
 
   }
9757
 
 }
9758
 
 /* patch ISO header */
9759
 
 full_size= iso_lba + isosize;
9760
 
 headpt= head_buffer + 32*1024;
9761
 
 for(i=0;i<4;i++)
9762
 
   headpt[87-i]= headpt[80+i]= (full_size >> (8*i)) & 0xff;
9763
 
 
9764
 
 if(job != NULL) {
9765
 
   seek_ret= lseek(job->data_to_fd, (off_t) 0, SEEK_SET);
9766
 
   if(seek_ret == -1)
9767
 
     ret= 0;
9768
 
   else
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);
9775
 
     return(0);
9776
 
   }
9777
 
 } else {
9778
 
   ret= burn_random_access_write(drive, (off_t) 0, head_buffer,
9779
 
                                 (off_t) (64*1024), 1);
9780
 
   if(ret<=0) {
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);
9785
 
     return(0);
9786
 
   }
9787
 
 }
9788
 
 if(flag & 4) {
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);
9792
 
 }
9793
 
 return(1);
9794
 
}
9795
 
 
9796
 
 
9797
 
/* @param write_start_address  is valid if >=0    
9798
 
   @param tsize                is valid if >0
9799
 
   @param flag bit0= grow_overwriteable_iso
9800
 
               bit1= do_isosize
9801
 
               bit2= do_xa1 conversion
9802
 
*/
9803
 
int Xorriso_burn_track(struct XorrisO *xorriso, off_t write_start_address,
9804
 
                       char *track_source, off_t tsize, int flag)
9805
 
{
9806
 
 int ret, fd, unpredicted_size, profile_number, is_cd= 0, dummy, nwa= -1;
9807
 
 int isosize= -1, do_isosize, is_bd= 0;
9808
 
 
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;
9815
 
 struct stat stbuf; 
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];
9821
 
 
9822
 
 ret= Xorriso_may_burn(xorriso, 0);
9823
 
 if(ret <= 0)
9824
 
   return(0);
9825
 
 ret= Xorriso_auto_format(xorriso, 0);
9826
 
 if(ret <=0 )
9827
 
   return(0);
9828
 
 
9829
 
 do_isosize= !!(flag&2);
9830
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
9831
 
                                "on attempt to burn track", 2);
9832
 
 if(ret<=0)
9833
 
   return(0);
9834
 
 ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0);
9835
 
 if(ret<=0)
9836
 
   goto ex;
9837
 
 
9838
 
 disc= burn_disc_create();
9839
 
 session= burn_session_create();
9840
 
 ret= burn_disc_add_session(disc,session,BURN_POS_END);
9841
 
 if(ret==0) {
9842
 
   sprintf(xorriso->info_text, "Cannot add session object to disc object.");
9843
 
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
9844
 
   goto ex;
9845
 
 }
9846
 
 track= burn_track_create();
9847
 
 if(track_source[0] == '-' && track_source[1] == 0) {
9848
 
   fd= 0;
9849
 
 } else {
9850
 
   if(xorriso->fs >= 64)
9851
 
     fd= burn_os_open_track_src(track_source, O_RDONLY, 0);
9852
 
   else
9853
 
     fd= open(track_source, O_RDONLY);
9854
 
   if(fd>=0)
9855
 
     if(fstat(fd,&stbuf)!=-1)
9856
 
       if((stbuf.st_mode&S_IFMT)==S_IFREG)
9857
 
         fixed_size= stbuf.st_size;
9858
 
 }
9859
 
 if(fixed_size==0)
9860
 
   unpredicted_size= 1;
9861
 
 
9862
 
 if(fd>=0)
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);
9868
 
   ret= 0; goto ex;
9869
 
 }
9870
 
 if((do_isosize || xorriso->fs != 0) && xorriso->fs < 64)
9871
 
   xorriso->fs= 64;
9872
 
 if(xorriso->fs > 0) {
9873
 
   fifo_src= burn_fifo_source_new(data_src, 2048 + 8 * !!(flag & 4),
9874
 
                                  xorriso->fs, 1);
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);
9879
 
     ret= 0; goto ex;
9880
 
   }
9881
 
 } 
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);
9888
 
   ret= 0; goto ex;
9889
 
 }
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);
9893
 
 
9894
 
 if(flag&1)
9895
 
   /* consider overwriteables with ISO as appendable */
9896
 
   disc_state= isoburn_disc_get_status(drive);
9897
 
 else
9898
 
   /* handle overwriteables as always blank */
9899
 
   disc_state= burn_disc_get_status(drive);
9900
 
 
9901
 
 if(disc_state == BURN_DISC_BLANK || disc_state == BURN_DISC_APPENDABLE) {
9902
 
   /* ok */;
9903
 
 } else {
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);
9911
 
     }
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);
9915
 
   } else {
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);
9919
 
   }
9920
 
   ret= 0; goto ex;
9921
 
 }
9922
 
 if(isoburn_needs_emulation(drive))
9923
 
   burn_write_opts_set_multi(burn_options, 0);
9924
 
 
9925
 
 if(tsize > 0) {
9926
 
   fixed_size= tsize;
9927
 
   burn_track_set_size(track, fixed_size);
9928
 
 }
9929
 
 if(do_isosize) {
9930
 
   ret= burn_fifo_peek_data(xorriso->pacifier_fifo, head_buffer, 64*1024, 0);
9931
 
   if(ret<=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);
9936
 
     ret= 0; goto ex;
9937
 
   }
9938
 
   /* read isosize from head_buffer, not from media*/
9939
 
   ret= isoburn_read_iso_head(drive, 0, &isosize, head_buffer, (1<<13));
9940
 
   if(ret<=0) {
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);
9945
 
     ret= 0; goto ex;
9946
 
   }
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);
9951
 
 }
9952
 
 
9953
 
 ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2);
9954
 
 is_cd= (ret==2);
9955
 
 is_bd= (ret == 3);
9956
 
 
9957
 
 if(isoburn_needs_emulation(drive)) {
9958
 
   if(flag&1) {
9959
 
     ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &dummy, &nwa);
9960
 
     if(ret<=0) {
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);
9965
 
       ret= 0; goto ex;
9966
 
     }
9967
 
     if(nwa==32)
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);
9970
 
   } else {
9971
 
     nwa= 0;
9972
 
     burn_write_opts_set_start_byte(burn_options, (off_t) 0);
9973
 
   }
9974
 
 }
9975
 
 
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 )
9979
 
     nwa++;
9980
 
   burn_write_opts_set_start_byte(burn_options, ((off_t) nwa) * (off_t) 2048);
9981
 
 }
9982
 
 
9983
 
 if(burn_write_opts_auto_write_type(burn_options, disc, reasons, 0) ==
9984
 
    BURN_WRITE_NONE) {
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);
9990
 
   ret= 0; goto ex;
9991
 
 }
9992
 
 
9993
 
 ret= Xorriso_sanitize_image_size(xorriso, drive, disc, burn_options, 2);
9994
 
 if(ret<=0) 
9995
 
   goto ex;
9996
 
 
9997
 
 /* Important: do not return until burn_is_aborting() was checked */
9998
 
 Xorriso_set_signal_handling(xorriso, 1);
9999
 
 
10000
 
 xorriso->run_state= 1; /* Indicate that burning has started */
10001
 
 burn_disc_write(burn_options, disc);
10002
 
 
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);
10007
 
 if(ret<=0)
10008
 
   goto ex;
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);
10014
 
   ret= 0; goto ex;
10015
 
 }
10016
 
 
10017
 
 if(flag & 1) {
10018
 
   ret= Xorriso_update_iso_lba0(xorriso, nwa, isosize, head_buffer, NULL,
10019
 
                                flag & 2);
10020
 
   if(ret <= 0)
10021
 
     goto ex;
10022
 
 }
10023
 
 sprintf(xorriso->info_text, "Writing to %s completed sucessfully.\n\n",
10024
 
         Text_shellsafe(xorriso->outdev,sfe,0));
10025
 
 Xorriso_info(xorriso, 0);
10026
 
 ret= 1;
10027
 
ex:;
10028
 
 Xorriso_process_msg_queues(xorriso,0);
10029
 
 if(disc!=NULL)
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 */
10035
 
 return(ret);
10036
 
}
10037
 
 
10038
 
 
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
10042
 
*/
10043
 
int Xorriso_get_profile(struct XorrisO *xorriso, int *profile_number, 
10044
 
                        char profile_name[80], int flag)
10045
 
{
10046
 
 int ret;
10047
 
 struct burn_drive_info *dinfo;
10048
 
 struct burn_drive *drive;
10049
 
 
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))
10054
 
   return(0);
10055
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
10056
 
                                "on attempt to determine media type", flag&2);
10057
 
 if(ret<=0)
10058
 
   return(0);
10059
 
 ret=burn_disc_get_profile(drive, profile_number, profile_name);
10060
 
 if(ret<=0)
10061
 
   return(ret);
10062
 
 if(*profile_number==0x08 || *profile_number==0x09 || *profile_number==0x0a)
10063
 
   return(2);
10064
 
 if(*profile_number == 0x40 || *profile_number == 0x41 ||
10065
 
    *profile_number == 0x42 || *profile_number == 0x43)
10066
 
   return(3);
10067
 
 return(0);
10068
 
}
10069
 
 
10070
 
 
10071
 
 
10072
 
int Xorriso_iso_file_open(struct XorrisO *xorriso, char *pathname,
10073
 
                          void *node_pt, void **stream, int flag)
10074
 
{
10075
 
 int ret;
10076
 
 char eff_path[SfileadrL];
10077
 
 IsoNode *node= NULL;
10078
 
 IsoFile *filenode= NULL;
10079
 
 IsoStream *iso_stream= NULL, *input_stream;
10080
 
 
10081
 
 *stream= NULL;
10082
 
 if(flag&1) {
10083
 
   node= (IsoNode *) node_pt;
10084
 
 } else {
10085
 
   ret= Xorriso_get_node_by_path(xorriso, pathname, eff_path, &node, 0);
10086
 
   if(ret<=0)
10087
 
     return(ret);
10088
 
 }
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);
10093
 
   return(0);
10094
 
 }
10095
 
 
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);
10103
 
   return(0);
10104
 
 }
10105
 
 if(flag & 2) {
10106
 
   /* Dig out the most original stream */
10107
 
   while(1) {
10108
 
     input_stream= iso_stream_get_input_stream(iso_stream, 0);
10109
 
     if(input_stream == NULL)
10110
 
   break;
10111
 
     iso_stream= input_stream;
10112
 
   }
10113
 
 }
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);
10118
 
   return(0);
10119
 
 }
10120
 
 ret= iso_stream_open(iso_stream);
10121
 
 if(ret<0) {
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);
10125
 
   return(0);
10126
 
 }
10127
 
 Xorriso_process_msg_queues(xorriso,0);
10128
 
 *stream= iso_stream;
10129
 
 
10130
 
#ifdef NIX
10131
 
 /* <<< */
10132
 
 {
10133
 
   unsigned int fs_id;
10134
 
   dev_t dev_id;
10135
 
   ino_t ino;
10136
 
 
10137
 
   iso_stream_get_id(iso_stream, &fs_id, &dev_id, &ino);
10138
 
   fprintf(stderr, "xorriso_debug: iso_ino= %ld\n", (long int) ino);
10139
 
 }
10140
 
#endif
10141
 
 
10142
 
 return(1);
10143
 
}
10144
 
 
10145
 
 
10146
 
int Xorriso_iso_file_read(struct XorrisO *xorriso, void *stream, char *buf,
10147
 
                          int count, int flag)
10148
 
{
10149
 
 int ret, rcnt= 0;
10150
 
 IsoStream *stream_pt;
10151
 
 
10152
 
 stream_pt= (IsoStream *) stream;
10153
 
 
10154
 
 while(rcnt<count) {
10155
 
   ret= iso_stream_read(stream_pt, (void *) (buf+rcnt), (size_t) (count-rcnt));
10156
 
   if(ret==0) /* EOF */
10157
 
 break;
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) );
10162
 
     return(-1);
10163
 
   }
10164
 
   rcnt+= ret;
10165
 
 }
10166
 
 return(rcnt);
10167
 
}
10168
 
 
10169
 
 
10170
 
int Xorriso_iso_file_close(struct XorrisO *xorriso, void **stream, int flag)
10171
 
{
10172
 
 int ret;
10173
 
 
10174
 
 if(*stream==NULL)
10175
 
   return(0);
10176
 
 ret= iso_stream_close(*stream);
10177
 
 if(ret==1)
10178
 
   *stream= NULL;
10179
 
 Xorriso_process_msg_queues(xorriso,0);
10180
 
 return(ret);
10181
 
}
10182
 
 
10183
 
 
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
10187
 
*/
10188
 
int Xorriso_identify_split(struct XorrisO *xorriso, char *iso_adr,
10189
 
                           void *in_node,
10190
 
                           struct SplitparT **parts, int *count,
10191
 
                           struct stat *total_stbuf,  int flag)
10192
 
{
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;
10197
 
 
10198
 
 IsoImage *volume;
10199
 
 IsoDir *dir_node;
10200
 
 IsoDirIter *iter= NULL;
10201
 
 IsoNode *node;
10202
 
 char *name;
10203
 
 struct stat stbuf, first_stbuf;
10204
 
 
10205
 
 *count= 0;
10206
 
 *parts= NULL;
10207
 
 
10208
 
 if(xorriso->split_size <= 0 && !(flag & 4))
10209
 
   return(0);
10210
 
 
10211
 
 if(flag&1) {
10212
 
   node= (IsoNode *) in_node;
10213
 
 } else {
10214
 
   ret= Xorriso_get_volume(xorriso, &volume, 0);
10215
 
   if(ret<=0)
10216
 
     return(-1);
10217
 
   ret= Xorriso_node_from_path(xorriso, volume, iso_adr, &node, 1);
10218
 
   if(ret<=0)
10219
 
     return(-1);
10220
 
 }
10221
 
 if(!LIBISO_ISDIR(node))
10222
 
   return(0);
10223
 
 dir_node= (IsoDir *) node;
10224
 
 
10225
 
 ret= iso_dir_get_children(dir_node, &iter);
10226
 
 if(ret<0) {
10227
 
cannot_iter:;
10228
 
   Xorriso_cannot_create_iter(xorriso, ret, 0);
10229
 
   return(-1);
10230
 
 }
10231
 
 
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);
10236
 
   if(ret<=0)
10237
 
     {ret= 0; goto ex;}
10238
 
   if(i==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;
10244
 
   } else {
10245
 
     if(first_total_parts!=total_parts || first_total_bytes!=total_bytes ||
10246
 
        (first_bytes!=bytes && partno!=total_parts))
10247
 
       {ret= 0; goto ex;}
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)
10254
 
       {ret= 0; goto ex;} 
10255
 
     size= stbuf.st_size;
10256
 
   }
10257
 
   /* check for plausible size */
10258
 
   if(!((partno != total_parts && size == bytes) ||
10259
 
        (partno == total_parts && size <= bytes)))
10260
 
     {ret= 0; goto ex;} 
10261
 
   if(offset != first_bytes * (off_t) (partno - 1))
10262
 
     {ret= 0; goto ex;}
10263
 
   (*count)++;
10264
 
 }
10265
 
 if(*count <= 0 || *count != first_total_parts)
10266
 
   {ret= 0; goto ex;}
10267
 
 
10268
 
 ret= Splitparts_new(parts, (*count)+1, 0); /* (have one end marker item) */
10269
 
 if(ret<=0)
10270
 
   return(ret);
10271
 
 
10272
 
 iso_dir_iter_free(iter);
10273
 
 ret= iso_dir_get_children(dir_node, &iter);
10274
 
 if(ret<0)
10275
 
   goto cannot_iter;
10276
 
 for(i= 0; i<*count; i++) {
10277
 
   ret= iso_dir_iter_next(iter, &node);
10278
 
   if(ret!=1)
10279
 
 break;
10280
 
   name= (char *) iso_node_get_name(node);
10281
 
   ret= Splitpart__parse(name, &partno, &total_parts,
10282
 
                         &offset, &bytes, &total_bytes, 0);
10283
 
   if(ret<=0)
10284
 
     {ret= 0; goto ex;}
10285
 
   ret= Splitparts_set(*parts, i, name, partno, total_parts, offset, bytes,
10286
 
                       total_bytes, 0);
10287
 
   if(ret<=0)
10288
 
     goto ex;
10289
 
 }
10290
 
 
10291
 
 Splitparts_sort(*parts, *count, 0);
10292
 
 
10293
 
 covered= 0;
10294
 
 for(i= 0; i<*count; i++) {
10295
 
   Splitparts_get(*parts, i, &name, &partno, &total_parts, &offset, &bytes,
10296
 
                  &total_bytes, 0);
10297
 
   if(offset>covered)
10298
 
     incomplete= 1;
10299
 
   else if(offset<covered)
10300
 
     overlapping= 1;
10301
 
   if(offset+bytes > covered)
10302
 
     covered= offset+bytes;
10303
 
 }
10304
 
 if(total_bytes>covered)
10305
 
   incomplete= 1;
10306
 
 memcpy(total_stbuf, &first_stbuf, sizeof(struct stat));
10307
 
 total_stbuf->st_size= total_bytes;
10308
 
 ret= !(overlapping || incomplete);
10309
 
ex:;
10310
 
 if(iter!=NULL)
10311
 
   iso_dir_iter_free(iter);
10312
 
 return(ret);
10313
 
}
10314
 
 
10315
 
 
10316
 
/* @param flag bit0= node is valid, do not resolve path
10317
 
               bit1= insist in complete collection of part files
10318
 
*/
10319
 
int Xorriso_is_split(struct XorrisO *xorriso, char *path, void *node,
10320
 
                     int flag)
10321
 
{
10322
 
 struct SplitparT *split_parts= NULL;
10323
 
 int split_count= 0, ret;
10324
 
 struct stat stbuf;
10325
 
 
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);
10330
 
 return(ret>0);
10331
 
}
10332
 
 
10333
 
 
10334
 
/* @param flag bit0= grow_overwriteable_iso
10335
 
               bit1= obtain info from outdev
10336
 
               bit2= no need to obtain msc2 (NWA)
10337
 
*/
10338
 
int Xorriso_msinfo(struct XorrisO *xorriso, int *msc1, int *msc2, int flag)
10339
 
{
10340
 
 int ret, dummy;
10341
 
 struct burn_drive *drive;
10342
 
 struct burn_drive_info *dinfo;
10343
 
 enum burn_disc_status disc_state;
10344
 
 
10345
 
 *msc1= *msc2= -1;
10346
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
10347
 
                                "on attempt to obtain msinfo", flag&2);
10348
 
 if(ret<=0)
10349
 
   return(ret);
10350
 
 
10351
 
 if(flag&1)
10352
 
   disc_state= isoburn_disc_get_status(drive);
10353
 
 else
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);
10358
 
   if(!(flag & 4)) {
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);
10363
 
   }
10364
 
   return(0);
10365
 
 }
10366
 
 ret= isoburn_disc_get_msc1(drive, msc1);
10367
 
 if(ret<=0) {
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);
10371
 
   return(0);
10372
 
 }
10373
 
 if(flag & 4)
10374
 
   return(1);
10375
 
 ret= isoburn_disc_track_lba_nwa(drive, NULL, 0, &dummy, msc2);
10376
 
 if(ret<0) {
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);
10380
 
   return(0);
10381
 
 }
10382
 
 return(1);
10383
 
}
10384
 
 
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
10389
 
*/
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)
10394
 
{
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];
10399
 
 int start_lba= 0;
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;
10406
 
 struct stat stbuf;
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= "";
10413
 
 
10414
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
10415
 
                                "on attempt to check media readability",
10416
 
                                2 * !!job->use_dev);
10417
 
 if(ret<=0)
10418
 
   goto ex;
10419
 
 ret= burn_disc_get_profile(drive, &profile_no, profile_name);
10420
 
 if(ret > 0)
10421
 
   if(profile_no >= 0x08 && profile_no <= 0x0a)
10422
 
     is_cd= 1;
10423
 
 
10424
 
 if(job->sector_map != NULL) {
10425
 
   Sectorbitmap_get_layout(job->sector_map, &sectors, &sector_size, 0);
10426
 
   sector_size/= 2048;
10427
 
 }
10428
 
 
10429
 
 if(job->retry > 0)
10430
 
   retry= 1;
10431
 
 else if(job->retry == 0 && is_cd)
10432
 
   retry= 1;
10433
 
 
10434
 
 if(flag & 4) {
10435
 
   ret= iso_md5_start(&ctx);
10436
 
   if(ret < 0) {
10437
 
     Xorriso_no_malloc_memory(xorriso, NULL, 0);
10438
 
     ret= -1; goto ex;
10439
 
   }
10440
 
 }
10441
 
 
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) {
10446
 
   skip_reading= 0;
10447
 
 
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);
10456
 
           goto abort_check;
10457
 
         }
10458
 
       }
10459
 
       last_abort_file_time= post_read_time;
10460
 
     }
10461
 
   }
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",
10465
 
             job->item_limit);
10466
 
     Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
10467
 
     goto abort_check;
10468
 
   }
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",
10473
 
             job->time_limit);
10474
 
     Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
10475
 
abort_check:;
10476
 
     if(prev_quality >= 0) {
10477
 
       ret= Spotlist_add_item(spotlist, start_lba, i + from_lba - start_lba,
10478
 
                              prev_quality, 0);
10479
 
       if(ret <= 0)
10480
 
         goto ex;
10481
 
     }
10482
 
     ret= Spotlist_add_item(spotlist, i + from_lba, block_count - i,
10483
 
                            Xorriso_read_quality_untesteD, 0);
10484
 
     if(ret > 0)
10485
 
       ret= 2;
10486
 
     goto ex;
10487
 
   }
10488
 
 
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.
10495
 
     */
10496
 
     if(to_read > 2)
10497
 
       to_read-= 2;
10498
 
     else if(to_read > 1) {
10499
 
       if(flag & 1) {
10500
 
         quality= Xorriso_read_quality_tao_enD;
10501
 
         skip_reading= 1;
10502
 
       } else
10503
 
         to_read--;
10504
 
     }
10505
 
   }
10506
 
 
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;
10511
 
       skip_reading= 1;
10512
 
     }
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)
10519
 
     break;
10520
 
     to_read= j * sector_size - i - from_lba;
10521
 
     skip_reading= !!first_value;
10522
 
     if(skip_reading)
10523
 
       quality= Xorriso_read_quality_valiD;
10524
 
   }
10525
 
 
10526
 
   if(skip_reading) {
10527
 
     pre_read_time= post_read_time= Sfile_microtime(0);
10528
 
   } else {
10529
 
     data_count= 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;
10536
 
     total_count++;
10537
 
     if(ret <= 0) {
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);
10544
 
              if(ret <= 0)
10545
 
                goto ex;
10546
 
           }
10547
 
           ret= Spotlist_add_item(spotlist, i + from_lba, data_count / 2048,
10548
 
                                  Xorriso_read_quality_partiaL, 0);
10549
 
           if(ret <= 0)
10550
 
             goto ex;
10551
 
           start_lba= i + from_lba + data_count / 2048;
10552
 
           prev_quality= Xorriso_read_quality_unreadablE;
10553
 
         }
10554
 
         quality= Xorriso_read_quality_unreadablE;
10555
 
         if(retry)
10556
 
           to_read= data_count / 2048 + 1;
10557
 
       } else
10558
 
         quality= Xorriso_read_quality_partiaL;
10559
 
       fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
10560
 
       if(fret<0)
10561
 
         goto ex;
10562
 
     } else {
10563
 
       quality= Xorriso_read_quality_gooD;
10564
 
       if(time_diff > job->slow_threshold_seq && job->slow_threshold_seq > 0 &&
10565
 
          i > 0)
10566
 
         quality= Xorriso_read_quality_sloW;
10567
 
     }
10568
 
 
10569
 
     /* MD5 checksumming */
10570
 
     if(ctx != NULL) {
10571
 
       for(j= 0; j < to_read; j++) {
10572
 
         lba=  i + j + from_lba;
10573
 
         if(lba < md5_start)
10574
 
       continue;
10575
 
         ret= 0;
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);
10581
 
         }
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";
10585
 
           was_sb_tag= 1;
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
10590
 
                same 64 kB chunk.
10591
 
             */
10592
 
             iso_md5_end(&ctx, md5);
10593
 
             ret= iso_md5_start(&ctx);
10594
 
             if(ret < 0) {
10595
 
               Xorriso_no_malloc_memory(xorriso, NULL, 0);
10596
 
               ret= -1; goto ex;
10597
 
             }
10598
 
             iso_md5_compute(&ctx, data + (j - (lba - range_start)) * 2048,
10599
 
                             (lba - range_start) * 2048);
10600
 
             md5_start= range_start;
10601
 
             in_track_gap= 0;
10602
 
           }
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) {
10608
 
 
10609
 
           /* >>> ??? allow this without superblock and tree tag ? */
10610
 
 
10611
 
           tag_type_name= "session";
10612
 
         } else {
10613
 
           tag_type_name= "";
10614
 
         }
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",
10619
 
                 tag_type_name);
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);
10625
 
             chain_broken= 1;
10626
 
             valid= 0;
10627
 
           } else {
10628
 
             ret= iso_md5_clone(ctx, &cloned_ctx);
10629
 
             if(ret <= 0) {
10630
 
               Xorriso_no_malloc_memory(xorriso, NULL, 0);
10631
 
               ret= -1; goto ex;
10632
 
             }
10633
 
             iso_md5_end(&cloned_ctx, md5);
10634
 
 
10635
 
             if(ret == ISO_MD5_AREA_CORRUPTED) {
10636
 
               comparison= "CORRUPTED";
10637
 
               sev_text= "WARNING";
10638
 
               md5_spot_value= Xorriso_read_quality_md5_mismatcH;
10639
 
               chain_broken= 1;
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;
10644
 
               chain_broken= 1;
10645
 
             } else {
10646
 
               comparison= "matching";
10647
 
               sev_text= "UPDATE";
10648
 
               md5_spot_value= Xorriso_read_quality_md5_matcH;
10649
 
             }
10650
 
             md5_spot_lba= lba;
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,
10655
 
                                 sev_text, 0);
10656
 
           }
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);
10662
 
               if(ret <= 0)
10663
 
               goto ex;
10664
 
             }
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));
10669
 
             next_tag= 0;
10670
 
 
10671
 
             iso_md5_end(&ctx, md5);
10672
 
             ret= iso_md5_start(&ctx);
10673
 
             if(ret < 0) {
10674
 
               Xorriso_no_malloc_memory(xorriso, NULL, 0);
10675
 
               ret= -1; goto ex;
10676
 
             }
10677
 
             if(tag_type == 1)
10678
 
               in_track_gap= 1;
10679
 
       continue;
10680
 
           }
10681
 
         }
10682
 
         iso_md5_compute(ctx, data + j * 2048, 2048);
10683
 
       }
10684
 
     }
10685
 
 
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);
10691
 
     }
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,
10696
 
                 SEEK_SET);
10697
 
         if(ret == -1) {
10698
 
failed_to_write:;
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,
10703
 
                               "FAILURE", 0);
10704
 
           {ret= 0; goto ex;}
10705
 
         }
10706
 
         ret= write(job->data_to_fd, data, write_amount);
10707
 
         if(ret == -1)
10708
 
           goto failed_to_write;
10709
 
       }
10710
 
     }
10711
 
   }
10712
 
   if(quality != prev_quality) {
10713
 
     if(prev_quality >= 0) {
10714
 
       ret= Spotlist_add_item(spotlist, start_lba, i + from_lba - start_lba,
10715
 
                              prev_quality, 0);
10716
 
       if(ret <= 0)
10717
 
         goto ex;
10718
 
     }
10719
 
     start_lba= i + from_lba;
10720
 
     prev_quality= quality;
10721
 
   }
10722
 
   if(!(flag & 2)) {
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);
10728
 
   }
10729
 
 }
10730
 
 if(prev_quality >= 0) {
10731
 
   ret= Spotlist_add_item(spotlist, start_lba,
10732
 
                          block_count + from_lba - start_lba, prev_quality, 0);
10733
 
   if(ret <= 0)
10734
 
     goto ex;
10735
 
 }
10736
 
 
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);
10742
 
 }
10743
 
 
10744
 
 
10745
 
 /* MD5 checksumming : register result */
10746
 
 
10747
 
 /* >>> ??? allow chain_broken to be a match ? */
10748
 
 
10749
 
 if(next_tag > 0) {
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;
10755
 
 }
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);
10759
 
   if(ret <= 0)
10760
 
     goto ex;
10761
 
 }
10762
 
 
10763
 
 ret= 1;
10764
 
ex:
10765
 
 if(ctx != NULL)
10766
 
   iso_md5_end(&ctx, md5);
10767
 
 return(ret);
10768
 
}
10769
 
 
10770
 
 
10771
 
int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
10772
 
                        struct CheckmediajoB *job, int flag)
10773
 
{
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;
10785
 
 struct stat stbuf;
10786
 
 struct burn_multi_caps *caps= NULL;
10787
 
 
10788
 
 *spotlist= NULL;
10789
 
 
10790
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
10791
 
                                "on attempt to check media readability",
10792
 
                                2 * !!job->use_dev);
10793
 
 if(ret<=0)
10794
 
   goto ex;
10795
 
 
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
10799
 
 */;
10800
 
 if(job->min_block_size != 0)
10801
 
   read_chunk= job->min_block_size;
10802
 
 
10803
 
 ret= Spotlist_new(spotlist, 0);
10804
 
 if(ret <= 0)
10805
 
   {ret= -1; goto ex;}
10806
 
 
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);
10812
 
     if(ret <= 0) {
10813
 
       if(xorriso->info_text[0])
10814
 
         Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, os_errno,
10815
 
                             "FAILURE", 0);
10816
 
       goto ex;
10817
 
     }
10818
 
   }
10819
 
   Xorriso_toc_to_string(xorriso, &toc_info, 4 * !job->map_with_volid);
10820
 
 }
10821
 
 ret= Xorriso_open_job_data_to(xorriso, job, 0);
10822
 
 if(ret <= 0)
10823
 
   goto ex;
10824
 
 Xorriso_pacifier_reset(xorriso, 0);
10825
 
 job->start_time= time(NULL);
10826
 
 mode= job->mode;
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);
10831
 
   if(ret <= 0)
10832
 
     goto ex;
10833
 
 }
10834
 
 ret= burn_get_read_capacity(drive, &read_capacity, 0);
10835
 
 if(ret <= 0)
10836
 
   read_capacity= -1;
10837
 
 
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,
10842
 
                               read_chunk, 0, 0);
10843
 
   if(ret <= 0)
10844
 
     goto ex;
10845
 
   
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;
10850
 
   isoburn_sessions=
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],
10854
 
                                                     &num_tracks);
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 */
10858
 
     continue;
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);
10865
 
           if(ret > 0) {
10866
 
             if(caps->start_adr) {
10867
 
               /* block 0 to 31 are the overall mount entry of overwriteable */
10868
 
               track_lba= 0;
10869
 
               track_blocks+= 32;
10870
 
             }
10871
 
           }
10872
 
         }
10873
 
       }
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);
10879
 
         if(ret <= 0)
10880
 
           goto ex;
10881
 
         xorriso->pacifier_count+= track_lba - last_track_end;
10882
 
       }
10883
 
       last_track_end= track_lba + track_blocks;
10884
 
 
10885
 
       if(track_lba < start_lba) {
10886
 
         track_blocks-= start_lba - track_lba;
10887
 
         track_lba= start_lba;
10888
 
       }
10889
 
       if(track_blocks <= 0)
10890
 
     continue;
10891
 
       if(declare_untested) {
10892
 
         ret= Spotlist_add_item(*spotlist, track_lba, track_blocks,
10893
 
                                Xorriso_read_quality_untesteD, 0);
10894
 
         if(ret <= 0)
10895
 
           goto ex;
10896
 
       } else {
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)));
10900
 
         if(ret <= 0)
10901
 
           goto ex;
10902
 
         if(ret == 2)
10903
 
           declare_untested= 1;
10904
 
       }
10905
 
     }
10906
 
   }
10907
 
 
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);
10915
 
     {ret= 0; goto ex;}
10916
 
   }
10917
 
   blocks= media_blocks= isoburn_toc_disc_get_sectors(isoburn_disc);
10918
 
   if(start_lba >= 0)
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,
10924
 
                               read_chunk, 0, 0);
10925
 
   if(ret <= 0)
10926
 
     goto ex;
10927
 
 } else if(mode == 2) {
10928
 
 
10929
 
   /* >>> single sweep over libburn media capacity */;
10930
 
 
10931
 
 }
10932
 
 
10933
 
 Xorriso_pacifier_callback(xorriso, "sectors examined",
10934
 
                      xorriso->pacifier_count, xorriso->pacifier_total, "", 1);
10935
 
 ret= 1;
10936
 
ex:;
10937
 
 
10938
 
 if(job->data_to_fd != -1)
10939
 
   close(job->data_to_fd);
10940
 
 job->data_to_fd= -1;
10941
 
 
10942
 
 if(read_capacity >= 0) {
10943
 
   count= Spotlist_count(*spotlist, 0);
10944
 
   end_lba= 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;
10949
 
   }
10950
 
   if(read_capacity > end_lba) {
10951
 
     hret= Spotlist_add_item(*spotlist, end_lba, read_capacity - end_lba, 
10952
 
                             Xorriso_read_quality_untesteD, 0);
10953
 
     if(hret < ret)
10954
 
       ret= hret;
10955
 
   }
10956
 
 }
10957
 
 
10958
 
 if(ret > 0)
10959
 
   ret= Xorriso_update_in_sector_map(xorriso, *spotlist, read_chunk, job, 0);
10960
 
 
10961
 
 if(ret > 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);
10967
 
     if(ret <= 0) {
10968
 
       if(xorriso->info_text[0])
10969
 
         Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, os_errno,
10970
 
                             "FAILURE", 0);
10971
 
     }
10972
 
   }
10973
 
 }
10974
 
 if(toc_info != NULL)
10975
 
    free(toc_info);
10976
 
 if(ret <= 0)
10977
 
   Spotlist_destroy(spotlist, 0);
10978
 
 if(caps!=NULL)
10979
 
   burn_disc_free_multi_caps(&caps);
10980
 
 return(ret);
10981
 
}
10982
 
 
10983
 
 
10984
 
/* @param flag bit1= for Xorriso_check_interval(): no pacifier messages
10985
 
*/
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)
10990
 
{
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;
10998
 
 
10999
 
 upto_file_bytes= img_offset + bytes;
11000
 
 
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);
11006
 
   ret= 0; goto ex;
11007
 
 }
11008
 
 
11009
 
 ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas, &size,
11010
 
                              0);
11011
 
 if(ret <= 0) {
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);
11017
 
   goto ex;
11018
 
 }
11019
 
 if(img_offset + bytes < size && bytes > 0)
11020
 
   size= img_offset + bytes;
11021
 
 
11022
 
 ret= Checkmediajob_new(&job, 0);
11023
 
 if(ret <= 0)
11024
 
   goto ex;
11025
 
 if(xorriso->check_media_default != NULL)
11026
 
   Checkmediajob_copy(xorriso->check_media_default, job, 0);
11027
 
 job->min_lba= -1;
11028
 
 job->max_lba= -1;
11029
 
 job->sector_map_path[0]= 0;
11030
 
 
11031
 
 ret= Spotlist_new(&spotlist, 0);
11032
 
 if(ret <= 0)
11033
 
   {ret= -1; goto ex;}
11034
 
 
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);
11038
 
 if(ret <= 0)
11039
 
   goto ex;
11040
 
 
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;
11045
 
 
11046
 
   /* skip intervals before img_offset */
11047
 
   if(new_file_base_bytes <= img_offset) {
11048
 
     file_base_bytes= new_file_base_bytes;
11049
 
 continue;
11050
 
   }
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;
11058
 
   }
11059
 
 
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;
11063
 
   /* Adjust job */
11064
 
   job->data_to_offset= file_processed_bytes - img_adr + disk_offset;
11065
 
   job->data_to_limit= size - file_base_bytes;
11066
 
 
11067
 
   file_processed_bytes+= ((off_t) count) * (off_t) 2048;
11068
 
   ret= Xorriso_check_interval(xorriso, spotlist, job, lba, count, read_chunk,
11069
 
                               0, (flag & 2));
11070
 
   if(ret <= 0)
11071
 
     goto ex;
11072
 
   if (ret == 2) {
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);
11076
 
     ret= 0; goto ex;
11077
 
   }
11078
 
   file_base_bytes= new_file_base_bytes;
11079
 
 } 
11080
 
 
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);
11086
 
   if(ret <= 0)
11087
 
 continue;
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;
11092
 
     break;
11093
 
       }
11094
 
       file_base_bytes+= ((off_t) (end_lbas[i] + 1 - start_lbas[i]))
11095
 
                          * (off_t) 2048;
11096
 
     }
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);
11102
 
       bad_extract= 1;
11103
 
     }
11104
 
   }
11105
 
 }
11106
 
 
11107
 
 ret= !bad_extract;
11108
 
ex:;
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);
11115
 
 return(ret);
11116
 
}
11117
 
 
11118
 
 
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)
11122
 
{
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];
11126
 
 IsoImage *volume;
11127
 
 IsoNode *node;
11128
 
 
11129
 
 ret= Xorriso_get_volume(xorriso, &volume, 0); 
11130
 
 if(ret<=0)
11131
 
   return(ret);
11132
 
 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi,
11133
 
                                 img_path, eff_img_path, 0);
11134
 
 if(ret<=0)
11135
 
   return(ret);
11136
 
 ret= Xorriso_node_from_path(xorriso, volume, eff_img_path, &node, 0);
11137
 
 if(ret<=0)
11138
 
   return(ret);
11139
 
 ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx,
11140
 
                                 disk_path, eff_disk_path, 2 | 4);
11141
 
 if(ret<=0)
11142
 
   return(ret);
11143
 
 Xorriso_pacifier_reset(xorriso, 0);
11144
 
 mem_lut= xorriso->last_update_time;
11145
 
 
11146
 
 ret= Xorriso_handle_collision(xorriso, node, img_path, eff_disk_path,
11147
 
                               disk_path, &stbuf_ret, 0);
11148
 
 if(ret<=0 || ret==3)
11149
 
   return(0);
11150
 
 
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.
11154
 
 */
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);
11160
 
   return(0);
11161
 
 }
11162
 
 read_raw= 0;
11163
 
 if((img_offset % 2048) == 0) {
11164
 
   ret= Xorriso_is_plain_image_file(xorriso, node, "", 0);
11165
 
   if(ret > 0)
11166
 
     read_raw= 1;
11167
 
 }
11168
 
 if (read_raw) {
11169
 
   ret= Xorriso_read_file_data(xorriso, node, eff_img_path, eff_disk_path,
11170
 
                               img_offset, (off_t) 0, bytes, 0);
11171
 
   if(ret<=0)
11172
 
     return(ret);
11173
 
 } else {
11174
 
   ret= Xorriso_tree_restore_node(xorriso, node, eff_img_path, img_offset,
11175
 
                                  eff_disk_path, (off_t) 0, bytes, 2 | 8);
11176
 
   if(ret<=0)
11177
 
     return(ret);
11178
 
 }
11179
 
 
11180
 
 ret= Xorriso_restore_properties(xorriso, eff_disk_path, node, 0);
11181
 
 if(ret<=0)
11182
 
   return(ret);
11183
 
 
11184
 
 if(mem_lut != xorriso->last_update_time)
11185
 
   Xorriso_pacifier_callback(xorriso, "sectors examined",
11186
 
                             xorriso->pacifier_count, 0, "", 1);
11187
 
 return(1);
11188
 
}
11189
 
 
11190
 
 
11191
 
int Xorriso_get_local_charset(struct XorrisO *xorriso, char **name, int flag)
11192
 
{
11193
 
 (*name)= iso_get_local_charset(0);
11194
 
 return(1);
11195
 
}
11196
 
 
11197
 
 
11198
 
int Xorriso_set_local_charset(struct XorrisO *xorriso, char *name, int flag)
11199
 
{
11200
 
 int ret;
11201
 
 char *nl_charset, sfe[5 * SfileadrL];
11202
 
 iconv_t iconv_ret= (iconv_t) -1;
11203
 
 
11204
 
 nl_charset= nl_langinfo(CODESET);
11205
 
 if(name == NULL)
11206
 
   name= nl_charset;
11207
 
 
11208
 
 if(name != NULL) {
11209
 
   iconv_ret= iconv_open(nl_charset, name);
11210
 
   if(iconv_ret == (iconv_t) -1)
11211
 
     goto cannot;
11212
 
   else
11213
 
     iconv_close(iconv_ret);
11214
 
 }
11215
 
 ret= iso_set_local_charset(name, 0);
11216
 
 if(ret <= 0) {
11217
 
cannot:;
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);
11222
 
   return(0);
11223
 
 }
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);
11227
 
 return(1);
11228
 
}
11229
 
 
11230
 
 
11231
 
int Xorriso_relax_compliance(struct XorrisO *xorriso, char *mode,
11232
 
                                    int flag)
11233
 
{
11234
 
 char *npt, *cpt;
11235
 
 int l, was;
11236
 
 
11237
 
 was= xorriso->relax_compliance;
11238
 
 npt= cpt= mode;
11239
 
 for(; npt!=NULL; cpt= npt+1) {
11240
 
   npt= strchr(cpt,':');
11241
 
   if(npt==NULL)
11242
 
     l= strlen(cpt);
11243
 
   else
11244
 
     l= npt-cpt;
11245
 
   if(l == 0)
11246
 
 continue;
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;
11252
 
 
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;
11258
 
 
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;
11264
 
 
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;
11270
 
 
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;
11276
 
 
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;
11282
 
 
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;
11288
 
 
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;
11294
 
 
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;
11300
 
 
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;
11306
 
 
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;
11312
 
 
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;
11318
 
 
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;
11324
 
 
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);
11335
 
 
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;
11344
 
 
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",
11352
 
            0, "FAILURE", 0);
11353
 
 
11354
 
   } else {
11355
 
     if(l<SfileadrL)
11356
 
       sprintf(xorriso->info_text, "-compliance: unknown rule '%s'",
11357
 
               cpt);
11358
 
     else
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;
11363
 
     return(0);
11364
 
   }
11365
 
 }
11366
 
 return(1);
11367
 
}
11368
 
 
11369
 
 
11370
 
/* @return 1=ok  2=ok, is default setting */
11371
 
int Xorriso_get_relax_text(struct XorrisO *xorriso, char mode[1024],
11372
 
                           int flag)
11373
 
{
11374
 
 int r;
11375
 
 
11376
 
 r= xorriso->relax_compliance;
11377
 
 if(r == 0) {
11378
 
   strcpy(mode, "strict");
11379
 
   return(1);
11380
 
 }
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");
11410
 
 } else {
11411
 
   strcat(mode, ":new_rr");
11412
 
   if(r & isoburn_igopt_aaip_susp_1_10) 
11413
 
     strcat(mode, ":aaip_susp_1_10");
11414
 
 }
11415
 
 
11416
 
 return(1 + (r == Xorriso_relax_compliance_defaulT));
11417
 
}
11418
 
 
11419
 
 
11420
 
/**
11421
 
    @param flag bit0= print mount command to result channel rather than
11422
 
                      performing it 
11423
 
                bit1= do not allow prefixes with cmd
11424
 
                bit2= interpret unprefixed cmd as shell:
11425
 
*/
11426
 
int Xorriso_mount(struct XorrisO *xorriso, char *dev, int adr_mode,
11427
 
                  char *adr_value, char *cmd, int flag)
11428
 
{
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= "";
11434
 
 struct stat stbuf;
11435
 
 struct burn_drive_info *dinfo= NULL;
11436
 
 struct burn_drive *drive= NULL;
11437
 
 
11438
 
 devadr= dev;
11439
 
 adr_pt= adr_value;
11440
 
 if(strcmp(dev, "indev") == 0) {
11441
 
   ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
11442
 
                                  "on attempt to perform -mount \"indev\"", 0);
11443
 
   if(ret<=0)
11444
 
     goto ex;
11445
 
   dev_path= devadr= xorriso->indev;
11446
 
   if(strncmp(dev_path, "stdio:", 6) == 0)
11447
 
     dev_path+= 6;
11448
 
   if(xorriso->in_drive_handle == xorriso->out_drive_handle)
11449
 
     give_up= 3;
11450
 
   else
11451
 
     give_up= 1;
11452
 
 } else if(strcmp(dev, "outdev") == 0) {
11453
 
   ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
11454
 
                                  "on attempt to perform -mount \"outdev\"", 
11455
 
                                  2);
11456
 
   if(ret<=0)
11457
 
     goto ex;
11458
 
   dev_path= devadr= xorriso->outdev;
11459
 
   if(strncmp(dev_path, "stdio:", 6) == 0)
11460
 
     dev_path+= 6;
11461
 
   if(xorriso->in_drive_handle == xorriso->out_drive_handle)
11462
 
     give_up= 3;
11463
 
   else
11464
 
     give_up= 2;
11465
 
 } else {
11466
 
   is_extra_drive= 1;
11467
 
   dev_path= dev;
11468
 
   if(strncmp(dev_path, "stdio:", 6) == 0)
11469
 
     dev_path+= 6;
11470
 
 
11471
 
   /* do only accept regular files and block devices */
11472
 
   ret= stat(dev_path, &stbuf);
11473
 
   if(ret == -1) {
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);
11477
 
     ret= 0; goto ex;
11478
 
   }
11479
 
   ret= System_uname(&sysname, NULL, NULL, NULL, 0);
11480
 
   if(ret > 0 && strcmp(sysname, "FreeBSD") == 0)
11481
 
     mount_chardev= 1;
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);
11488
 
     ret= 0; goto ex;
11489
 
   }
11490
 
 
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);
11494
 
   if(ret < 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);
11502
 
   if(ret <= 0)
11503
 
     {ret= 0; goto ex;}
11504
 
   drive= dinfo[0].drive;
11505
 
 }
11506
 
 
11507
 
 if(adr_mode == 4 && strlen(adr_pt) <= 80) {
11508
 
   ret= Xorriso__bourne_to_reg(adr_pt, adr_data, 0);
11509
 
   if(ret == 1) {
11510
 
     params_flag|= 4;
11511
 
     adr_pt= adr_data;
11512
 
   }
11513
 
 }
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);
11517
 
 if(ret <= 0)
11518
 
   goto ex;
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",
11522
 
                0, "FAILURE", 0);
11523
 
   ret= 0; goto ex;
11524
 
 }
11525
 
 if(strstr(devadr, "stdio:") == devadr)
11526
 
   devadr+= 6;
11527
 
 ret= Xorriso_make_mount_cmd(xorriso, cmd, lba, track, session, volid, devadr,
11528
 
                             mount_command, flag & (2 | 4));
11529
 
 if(ret <= 0)
11530
 
   goto ex;
11531
 
 if(ret == 2)
11532
 
   is_safe= 1;
11533
 
 
11534
 
 if(is_extra_drive) {
11535
 
   isoburn_drive_release(drive, 0);
11536
 
   burn_drive_info_free(dinfo);
11537
 
   drive= NULL;
11538
 
 } else if(give_up > 0 && !((flag & 1) || (xorriso->mount_opts_flag & 1))) {
11539
 
   Xorriso_give_up_drive(xorriso, give_up);
11540
 
   if(ret <= 0)
11541
 
     goto ex;
11542
 
 }
11543
 
 Xorriso_process_msg_queues(xorriso,0);
11544
 
 
11545
 
 sprintf(xorriso->info_text, "Volume id    : %s\n",
11546
 
                             Text_shellsafe(volid, sfe, 0));
11547
 
 Xorriso_info(xorriso, 0);
11548
 
 if(flag & 1) {
11549
 
   sprintf(xorriso->result_line, "%s\n", mount_command);
11550
 
   Xorriso_result(xorriso,0);
11551
 
 } else {
11552
 
   sprintf(xorriso->info_text, "Mount command: %s\n", mount_command);
11553
 
   Xorriso_info(xorriso, 0);
11554
 
   if(!is_safe) {
11555
 
     Xorriso_msgs_submit(xorriso, 0,
11556
 
  "-mount : Will not perform mount command which stems from command template.",
11557
 
       0, "SORRY", 0);
11558
 
     sprintf(xorriso->result_line, "%s\n", mount_command);
11559
 
     Xorriso_result(xorriso,0);
11560
 
   } else {
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);
11567
 
       ret= 0; goto ex;
11568
 
     }
11569
 
     sprintf(xorriso->info_text, "\nMounted session %d of device %s",
11570
 
                                 session, Text_shellsafe(dev_path, sfe, 0));
11571
 
     dpt= strchr(cmd, ':');
11572
 
     if(dpt == NULL)
11573
 
       dpt= cmd ;
11574
 
     else
11575
 
       dpt++;
11576
 
     sprintf(xorriso->info_text + strlen(xorriso->info_text),
11577
 
             " as directory %s\n", Text_shellsafe(dpt, sfe, 0));
11578
 
     Xorriso_info(xorriso, 0);
11579
 
   }
11580
 
 }
11581
 
 ret= 1;
11582
 
ex:;
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);
11587
 
 }
11588
 
 return(ret);
11589
 
}
11590
 
 
11591
 
 
11592
 
int Xorriso_auto_driveadr(struct XorrisO *xorriso, char *adr, char *result,
11593
 
                          int flag)
11594
 
{
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];
11598
 
 
11599
 
 path_pt= adr;
11600
 
 if(strncmp(adr, "stdio:", 6) == 0)
11601
 
   path_pt= adr + 6;
11602
 
 else if(strncmp(adr, "mmc:", 4) == 0)
11603
 
   path_pt= adr + 4;
11604
 
 
11605
 
 
11606
 
 /* <<< replace by Xorriso_normalize_img_path() ? */;
11607
 
 
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);
11614
 
     return(-1);
11615
 
   }
11616
 
   ret= Sfile_add_to_path(abs_adr, path_pt, 0);
11617
 
   if(ret <= 0)
11618
 
     return(-1);
11619
 
 }
11620
 
 
11621
 
 is_known_mmc= burn_drive_convert_fs_adr(path_pt, libburn_adr);
11622
 
 Xorriso_process_msg_queues(xorriso,0);
11623
 
 
11624
 
 ret= Xorriso_is_in_patternlist(xorriso, xorriso->drive_whitelist, path_pt, 0);
11625
 
 if(ret > 0)
11626
 
   goto ok;
11627
 
 ret= Xorriso_is_in_patternlist(xorriso, xorriso->drive_blacklist, path_pt, 0);
11628
 
 if(ret < 0)
11629
 
   return(ret);
11630
 
 if(ret) {
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,
11636
 
                                      ret - 1, 0),
11637
 
                  xorriso->info_text, 1);
11638
 
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
11639
 
   return(0);
11640
 
 }
11641
 
 /* if in greylist and not MMC and not stdio prefix: reject */
11642
 
 if(is_known_mmc < 0)
11643
 
   return(ret);
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);
11646
 
   if(ret < 0)
11647
 
     return(ret);
11648
 
   if(ret) {
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,
11654
 
                                        ret - 1, 0),
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:\"",
11659
 
                   0, "HINT", 0);
11660
 
     return(0);
11661
 
   }
11662
 
 }
11663
 
ok:;
11664
 
 if(strncmp(adr, "mmc:", 4) == 0) {
11665
 
   if(Sfile_str(result, path_pt, 0) <= 0)
11666
 
     return(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)
11670
 
     return(0);
11671
 
 } else {
11672
 
   if(Sfile_str(result, adr, 0) <= 0)
11673
 
     return(0);
11674
 
 }
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);
11680
 
     return(0);
11681
 
   }
11682
 
 }
11683
 
 return(1);
11684
 
}
11685
 
 
11686
 
 
11687
 
/*
11688
 
  @param flag bit0= do not remove leading slash
11689
 
              bit1= append flatly to result_line and put out
11690
 
*/
11691
 
int Xorriso_getfname(struct XorrisO *xorriso, char *path, int flag)
11692
 
{
11693
 
 int ret, path_offset= 0, bsl_mem;
11694
 
 char *bsl_path= NULL;
11695
 
 
11696
 
 if(path[0] == '/' && !(flag & 1))
11697
 
   path_offset= 1;
11698
 
 
11699
 
 /* backslash escaped path rather than shellsafe path */
11700
 
 ret= Sfile_bsl_encoder(&bsl_path, path + path_offset,
11701
 
                        strlen(path + path_offset), 8);
11702
 
 if(ret <= 0)
11703
 
   return(-1);
11704
 
 if(flag & 2) {
11705
 
   sprintf(xorriso->result_line + strlen(xorriso->result_line),
11706
 
           "%s\n", bsl_path[0] ? bsl_path : ".");
11707
 
 } else {
11708
 
   sprintf(xorriso->result_line, "# file: %s\n", bsl_path[0] ? bsl_path : ".");
11709
 
 }
11710
 
 free(bsl_path);
11711
 
 bsl_path= NULL;
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;
11717
 
 return(1);
11718
 
}
11719
 
 
11720
 
 
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:"
11731
 
                          1= "access" only
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()
11736
 
                  <=0 error
11737
 
*/
11738
 
int Xorriso_getfacl(struct XorrisO *xorriso, void *in_node, char *path,
11739
 
                    char **acl_text, int flag)
11740
 
{
11741
 
 int ret, d_ret, result_len= 0, pass, what;
11742
 
 IsoNode *node;
11743
 
 char *text= NULL, *d_text= NULL, *cpt, *npt;
11744
 
 uid_t uid;
11745
 
 gid_t gid;
11746
 
 struct passwd *pwd;
11747
 
 struct group *grp;
11748
 
 
11749
 
 what= (flag >> 2) & 3;
11750
 
 if(acl_text != NULL)
11751
 
   *acl_text= NULL;
11752
 
 
11753
 
 node= (IsoNode *) in_node;
11754
 
 if(node == NULL) {
11755
 
   ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
11756
 
   if(ret<=0)
11757
 
     goto ex;
11758
 
 }
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);
11766
 
   }
11767
 
   ret= 0; goto ex;
11768
 
 }
11769
 
 if(flag & 2) {
11770
 
   ret= 1 + (ret != 1 && d_ret == 0);
11771
 
   goto ex;
11772
 
 }
11773
 
 if((ret == 0 || ret == 2) && d_ret == 0) {
11774
 
   if(flag & 1) {
11775
 
     ret= 1 + (ret == 0);
11776
 
     goto ex;
11777
 
   }
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);
11781
 
   if(ret == 0)
11782
 
     {ret= 2; goto ex;}
11783
 
 }
11784
 
 
11785
 
 if(!(flag & 1)) {
11786
 
   ret= Xorriso_getfname(xorriso, path, 0);
11787
 
   if(ret <= 0)
11788
 
     goto ex;
11789
 
   uid= iso_node_get_uid(node);
11790
 
   pwd= getpwuid(uid);
11791
 
   if(pwd == NULL)
11792
 
     sprintf(xorriso->result_line, "# owner: %.f\n", (double) uid);
11793
 
   else
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);
11798
 
   if(grp == NULL)
11799
 
     sprintf(xorriso->result_line, "# group: %.f\n", (double) gid);
11800
 
   else
11801
 
     sprintf(xorriso->result_line, "# group: %s\n", grp->gr_name);
11802
 
   Xorriso_result(xorriso, 0);
11803
 
 }
11804
 
 
11805
 
 for(pass= 0; pass < 1 + (acl_text != NULL && !(flag & 2)); pass++) {
11806
 
   if(pass) {
11807
 
     *acl_text= calloc(result_len + 1, 1);
11808
 
     if(*acl_text == NULL) {
11809
 
       Xorriso_no_malloc_memory(xorriso, NULL, 0);
11810
 
       ret= -1; goto ex;
11811
 
     }
11812
 
   }
11813
 
   if(text != NULL && what <= 1) {
11814
 
     for(npt= cpt= text; npt != NULL; cpt= npt + 1) {
11815
 
       npt= strchr(cpt, '\n');
11816
 
       if(npt != NULL)
11817
 
         *npt= 0;
11818
 
       if(*cpt == 0) {
11819
 
         if(d_text != NULL || pass) {
11820
 
           if(npt != NULL)
11821
 
             *npt= '\n';
11822
 
     continue;
11823
 
         }
11824
 
       } else
11825
 
         result_len+= strlen(cpt) + 1;
11826
 
       if(pass) {
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);
11832
 
       }
11833
 
       if(npt != NULL)
11834
 
         *npt= '\n';
11835
 
     }
11836
 
   }
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');
11840
 
       if(npt != NULL)
11841
 
         *npt= 0;
11842
 
       if(*cpt != 0) {
11843
 
         if(pass) {
11844
 
           if(what == 0)
11845
 
             sprintf(*acl_text + strlen(*acl_text), "default:%s\n", cpt);
11846
 
           else
11847
 
             sprintf(*acl_text + strlen(*acl_text), "%s\n", cpt);
11848
 
         } else {
11849
 
           xorriso->result_line[0]= 0;
11850
 
           if(what == 0)
11851
 
             Sfile_str(xorriso->result_line, "default:", 0);
11852
 
           Sfile_str(xorriso->result_line, cpt, 1);
11853
 
           result_len+= strlen(cpt) + 9;
11854
 
         }
11855
 
       } else
11856
 
         xorriso->result_line[0]= 0;
11857
 
       if(pass== 0 && !(flag & 1)) {
11858
 
         strcat(xorriso->result_line, "\n");
11859
 
         Xorriso_result(xorriso, 0);
11860
 
       }
11861
 
       if(npt != NULL)
11862
 
         *npt= '\n';
11863
 
     }
11864
 
   }
11865
 
 }
11866
 
 ret= 1;
11867
 
ex:;
11868
 
 iso_node_get_acl_text(node, &text, &d_text, 1 << 15);
11869
 
 return(ret);
11870
 
}
11871
 
 
11872
 
 
11873
 
int Xorriso_set_ignore_aclea(struct XorrisO *xorriso, int flag)
11874
 
{
11875
 
 int ret, hflag;
11876
 
 IsoImage *volume;
11877
 
 
11878
 
 ret= Xorriso_get_volume(xorriso, &volume, 1); 
11879
 
 if(ret<=0)
11880
 
   return(ret);
11881
 
 hflag= (~xorriso->do_aaip) & 1;
11882
 
 if((xorriso->ino_behavior & (1 | 2)) && !(xorriso->do_aaip & (4 | 16)))
11883
 
   hflag|= 2; 
11884
 
 iso_image_set_ignore_aclea(volume, hflag);
11885
 
 return(1);
11886
 
}
11887
 
 
11888
 
 
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
11896
 
*/
11897
 
int Xorriso_setfacl(struct XorrisO *xorriso, void *in_node, char *path,
11898
 
                    char *access_text, char *default_text, int flag)
11899
 
{
11900
 
 int ret;
11901
 
 IsoNode *node;
11902
 
 
11903
 
 node= (IsoNode *) in_node;
11904
 
 if(node == NULL) {
11905
 
   ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
11906
 
   if(ret<=0)
11907
 
     goto ex;
11908
 
 }
11909
 
 ret= iso_node_set_acl_text(node, access_text, default_text, 0);
11910
 
 if(ret <= 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);
11915
 
   }
11916
 
   ret= 0; goto ex;
11917
 
 }
11918
 
 Xorriso_set_change_pending(xorriso, 0);
11919
 
 ret= 1;
11920
 
ex:;
11921
 
 Xorriso_process_msg_queues(xorriso,0);
11922
 
 return(ret);
11923
 
}
11924
 
 
11925
 
 
11926
 
/*
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)
11933
 
*/
11934
 
int Xorriso_getfattr(struct XorrisO *xorriso, void *in_node, char *path,
11935
 
                     char **attr_text, int flag)
11936
 
{
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;
11940
 
 
11941
 
 if(attr_text != NULL)
11942
 
   *attr_text= NULL;
11943
 
 ret= Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names,
11944
 
                        &value_lengths, &values, flag & (2 | 8 | 32));
11945
 
 if(ret <= 0)
11946
 
   goto ex;
11947
 
 if(flag & 64) {
11948
 
   ret= (num_attrs > 0);
11949
 
   goto ex;
11950
 
 }
11951
 
 if(num_attrs == 0)
11952
 
   {ret= 2; goto ex;}
11953
 
 
11954
 
 if(!(flag & 1)) {
11955
 
   ret= Xorriso_getfname(xorriso, path, 0);
11956
 
   if(ret <= 0)
11957
 
     goto ex;
11958
 
 }
11959
 
 for(pass= 0; pass < 1 + (attr_text != NULL); pass++) {
11960
 
   if(pass) {
11961
 
     *attr_text= calloc(result_len + 1, 1);
11962
 
     if(*attr_text == NULL) {
11963
 
       Xorriso_no_malloc_memory(xorriso, NULL, 0);
11964
 
       ret= -1; goto ex;
11965
 
     }
11966
 
   }
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]);
11971
 
     } else {
11972
 
       ret= Sfile_bsl_encoder(&bsl, names[i], strlen(names[i]), 8);
11973
 
       if(ret <= 0) 
11974
 
         {ret= -1; goto ex;}
11975
 
       strcpy(xorriso->result_line, bsl);
11976
 
       free(bsl);
11977
 
       ret= Sfile_bsl_encoder(&bsl, values[i], value_lengths[i], 8);
11978
 
       if(ret <= 0) 
11979
 
         {ret= -1; goto ex;}
11980
 
       sprintf(xorriso->result_line + strlen(xorriso->result_line),
11981
 
               "=\"%s\"\n", bsl);
11982
 
       free(bsl);
11983
 
     }
11984
 
     /* temporarily disable -backslash_codes with result output */
11985
 
     result_len+= strlen(xorriso->result_line);
11986
 
     if(pass) {
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;
11993
 
     }
11994
 
   }
11995
 
 }
11996
 
 if(!(flag & 1)) {
11997
 
   strcpy(xorriso->result_line, "\n");
11998
 
   Xorriso_result(xorriso, 0);
11999
 
 }
12000
 
 ret= 1;
12001
 
ex:;
12002
 
 Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names,
12003
 
                   &value_lengths, &values, 1 << 15);
12004
 
 return(ret);
12005
 
}
12006
 
 
12007
 
 
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
12021
 
*/
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)
12025
 
{
12026
 
 int ret;
12027
 
 IsoNode *node;
12028
 
 
12029
 
 node= (IsoNode *) in_node;
12030
 
 if(node == NULL) {
12031
 
   ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
12032
 
   if(ret<=0)
12033
 
     goto ex;
12034
 
 }
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);
12038
 
 if(ret <= 0) {
12039
 
   Xorriso_report_iso_error(xorriso, "", ret,
12040
 
                            "Error when setting ACL and xattr to image node",
12041
 
                            0, "FAILURE", 1);
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);
12046
 
   }
12047
 
   ret= 0; goto ex;
12048
 
 }
12049
 
 Xorriso_set_change_pending(xorriso, 0);
12050
 
 ret= 1;
12051
 
ex:;
12052
 
 Xorriso_process_msg_queues(xorriso,0);
12053
 
 return(ret);
12054
 
}
12055
 
 
12056
 
 
12057
 
/*
12058
 
 @param flag
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
12065
 
 @return
12066
 
       1 ok
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
12072
 
*/
12073
 
int Xorriso_local_getfacl(struct XorrisO *xorriso, char *disk_path,
12074
 
                          char **text, int flag)
12075
 
{
12076
 
 int ret, skip= 0, colons= 0, countdown= 0;
12077
 
 char *acl= NULL, *cpt, *wpt;
12078
 
 
12079
 
 if(flag & (1 << 15)) {
12080
 
   if(*text != NULL)
12081
 
     free(*text);
12082
 
   *text= NULL;
12083
 
   return(1);
12084
 
 }
12085
 
 *text= NULL;
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)
12089
 
   return(ret);
12090
 
 if(acl == NULL)
12091
 
   return(0);
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);
12096
 
   return(-1);
12097
 
 }
12098
 
 
12099
 
 /* Garbage collection about trailing remarks after 3 permission chars */
12100
 
 wpt= *text;
12101
 
 for(cpt= *text; *cpt; cpt++) {
12102
 
   if(skip) {
12103
 
     if(*cpt == '\n')
12104
 
       skip= 0;
12105
 
     else
12106
 
 continue;
12107
 
   }
12108
 
   if(*cpt == ':' && !countdown) {
12109
 
     colons++;
12110
 
     if(colons == 2) {
12111
 
       countdown= 4;
12112
 
       colons= 0;
12113
 
     }
12114
 
   }
12115
 
   if(countdown > 0) {
12116
 
     countdown--;
12117
 
     if(countdown == 0)
12118
 
       skip= 1;
12119
 
   }
12120
 
   *wpt= *cpt;
12121
 
   wpt++;
12122
 
 }
12123
 
 *wpt= 0;
12124
 
 
12125
 
 return(1);
12126
 
}
12127
 
 
12128
 
 
12129
 
/*
12130
 
   @param flag
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
12134
 
              bit15= free memory
12135
 
*/
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)
12139
 
{
12140
 
 int ret, i, widx;
12141
 
 IsoNode *node;
12142
 
 
12143
 
 if(flag & (1 << 15)) {
12144
 
   if(flag & 2) {
12145
 
     iso_local_get_attrs(NULL, num_attrs, names, value_lengths, values,
12146
 
                         1 << 15);
12147
 
   } else {
12148
 
     iso_node_get_attrs(NULL, num_attrs, names, value_lengths, values,
12149
 
                        1 << 15);
12150
 
   }
12151
 
   return(1);
12152
 
 }
12153
 
 
12154
 
 *num_attrs= 0;
12155
 
 if(flag & 2) {
12156
 
   ret= iso_local_get_attrs(path, num_attrs, names, value_lengths, values,
12157
 
                            flag & (8 | 32));
12158
 
   if(ret < 0) {
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);
12162
 
   }
12163
 
 } else {
12164
 
   node= (IsoNode *) in_node;
12165
 
   if(node == NULL) {
12166
 
     ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
12167
 
     if(ret<=0)
12168
 
       goto ex;
12169
 
   }
12170
 
   ret= iso_node_get_attrs(node, num_attrs, names, value_lengths, values,
12171
 
                           0);
12172
 
   if(ret < 0) {
12173
 
     Xorriso_report_iso_error(xorriso, "", ret,
12174
 
                    "Error when obtaining xattr of ISO node", 0, "FAILURE", 1);
12175
 
     goto ex;
12176
 
   }
12177
 
 
12178
 
   if(!(flag & 8)) {
12179
 
     /* Filter away any non-userspace xattr */;
12180
 
     widx= 0;
12181
 
     for(i= 0; i < *num_attrs; i++) {
12182
 
       if(strncmp((*names)[i], "user.", 5) != 0) {
12183
 
         free((*names)[i]);
12184
 
         (*names)[i]= NULL;
12185
 
         if((*values)[i] != NULL) {
12186
 
           free((*values)[i]);
12187
 
           (*values)[i]= NULL;
12188
 
         }
12189
 
       } else {
12190
 
         if(widx != i) {
12191
 
           (*names)[widx]= (*names)[i];
12192
 
           (*value_lengths)[widx]= (*value_lengths)[i];
12193
 
           (*values)[widx]= (*values)[i];
12194
 
           (*names)[i]= NULL;
12195
 
           (*value_lengths)[i]= 0;
12196
 
           (*values)[i]= NULL;
12197
 
         }
12198
 
         widx++;
12199
 
       }
12200
 
     }
12201
 
     *num_attrs= widx;
12202
 
   }
12203
 
 }
12204
 
 ret= 1;
12205
 
ex:;
12206
 
 Xorriso_process_msg_queues(xorriso,0);
12207
 
 return(ret);
12208
 
}
12209
 
 
12210
 
 
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)
12213
 
{
12214
 
 int ret;
12215
 
 size_t num_attrs= 0, *value_lengths= NULL, i;
12216
 
 char **names = NULL, **values= NULL;
12217
 
 
12218
 
 *value= NULL;
12219
 
 *value_length= 0;
12220
 
 ret= Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names,
12221
 
                        &value_lengths, &values, 8);
12222
 
 if(ret <= 0)
12223
 
   goto ex;
12224
 
 
12225
 
 for(i= 0; i < num_attrs; i++) {
12226
 
   if(strcmp(name, names[i]) != 0)
12227
 
 continue;
12228
 
   *value= calloc(value_lengths[i] + 1, 1);
12229
 
   if(*value == NULL)
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];
12234
 
   ret= 1; goto ex;
12235
 
 }
12236
 
 ret= 0;
12237
 
ex:
12238
 
 Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names,
12239
 
                        &value_lengths, &values, 1 << 15);
12240
 
 return(ret);
12241
 
}
12242
 
 
12243
 
 
12244
 
/*
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
12248
 
                            -1=error
12249
 
               bit5= if not bit0:
12250
 
                     transfer dev,inode from eventual link target
12251
 
               bit7= omit dev check mit bit1
12252
 
*/
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)
12256
 
{
12257
 
 size_t l, di_l= 0;
12258
 
 int i, ret;
12259
 
 dev_t hdev;
12260
 
 ino_t hino;
12261
 
 char buf[66], *bufpt, *wpt, *di= NULL;
12262
 
 static char *name= "isofs.di";
12263
 
 struct stat stbuf;
12264
 
 
12265
 
 if(!(flag & 1)) {
12266
 
   if(flag & 32) {
12267
 
     if(stat(disk_path, &stbuf) == -1)
12268
 
       return(-1);
12269
 
   } else {
12270
 
     if(lstat(disk_path, &stbuf) == -1)
12271
 
       return(-1);
12272
 
   }
12273
 
   dev= stbuf.st_dev;
12274
 
   ino= stbuf.st_ino;
12275
 
 }
12276
 
   
12277
 
 wpt= buf;
12278
 
 hdev= dev;
12279
 
 for(i= 0; hdev != 0; i++)
12280
 
   hdev= hdev >> 8;
12281
 
 l= i;
12282
 
 *(wpt++)= l;
12283
 
 for(i= 0; i < l; i++)
12284
 
   *(wpt++)= dev >> (8 * (l - i - 1));
12285
 
 hino= ino;
12286
 
 for(i= 0; hino != 0; i++)
12287
 
   hino= hino >> 8;
12288
 
 l= i;
12289
 
 *(wpt++)= l;
12290
 
 for(i= 0; i < l; i++)
12291
 
   *(wpt++)= ino >> (8 * (l - i - 1));
12292
 
 l= wpt - buf; 
12293
 
 bufpt= buf;
12294
 
 
12295
 
 if(flag & 2) {
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);
12299
 
   if(ret < 0)
12300
 
     goto ex;
12301
 
   if(ret == 0)
12302
 
     {ret= 2; goto ex;}
12303
 
   if(flag & 128) {
12304
 
     if(di_l <= 0)
12305
 
       {ret= 1; goto ex;}
12306
 
     hino= 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];
12309
 
     if(hino != ino)
12310
 
       {ret= 1; goto ex;} 
12311
 
   } else {
12312
 
     if(l != di_l)
12313
 
       {ret= 1; goto ex;}
12314
 
     for(i= 0; i < l; i++)
12315
 
       if(di[i] != buf[i])
12316
 
         {ret= 1; goto ex;} 
12317
 
   }
12318
 
   ret= 0;
12319
 
 } else {
12320
 
   ret= Xorriso_setfattr(xorriso, in_node, iso_path,
12321
 
                         (size_t) 1, &name, &l, &bufpt, 2 | 8);
12322
 
 }
12323
 
ex:;
12324
 
 if(di != NULL)
12325
 
   free(di);
12326
 
 return(ret);
12327
 
}
12328
 
 
12329
 
 
12330
 
struct Xorriso_extF {
12331
 
 
12332
 
 int flag; /* unused yet */
12333
 
 
12334
 
 IsoExternalFilterCommand *cmd;
12335
 
 
12336
 
};
12337
 
 
12338
 
int Xorriso_extf_destroy(struct XorrisO *xorriso, struct Xorriso_extF **filter,
12339
 
                         int flag);
12340
 
 
12341
 
 
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)
12346
 
{
12347
 
 int i;
12348
 
 struct Xorriso_extF *o= NULL;
12349
 
 IsoExternalFilterCommand *cmd;
12350
 
 
12351
 
 *filter= o= calloc(sizeof(struct Xorriso_extF), 1);
12352
 
 if(o == NULL)
12353
 
   goto failure;
12354
 
 o->flag= flag;
12355
 
 o->cmd= NULL;
12356
 
 o->cmd= cmd= calloc(sizeof(IsoExternalFilterCommand), 1);
12357
 
 if(cmd == NULL)
12358
 
   goto failure;
12359
 
 cmd->version= 0;
12360
 
 cmd->refcount= 0;
12361
 
 cmd->name= NULL;
12362
 
 cmd->path= NULL;
12363
 
 cmd->argv= NULL;
12364
 
 cmd->argc= argc + 1;
12365
 
 cmd->behavior= behavior;
12366
 
 cmd->suffix= NULL;
12367
 
 cmd->suffix= strdup(suffix);
12368
 
 if(cmd->suffix == NULL)
12369
 
   goto failure;
12370
 
 
12371
 
 cmd->path= strdup(path);
12372
 
 if(cmd->path == NULL)
12373
 
   goto failure;
12374
 
 cmd->argv= calloc(sizeof(char *), argc + 2);
12375
 
 if(cmd->argv == NULL)
12376
 
   goto failure;
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)
12381
 
   goto failure;
12382
 
 for(i= 0; i < argc; i++) {
12383
 
   cmd->argv[i + 1]= strdup(argv[i]);
12384
 
   if(cmd->argv[i] == NULL)
12385
 
     goto failure;
12386
 
 }
12387
 
 cmd->name= strdup(name);
12388
 
 if(cmd->name == NULL)
12389
 
   goto failure;
12390
 
 return(1);
12391
 
failure:;
12392
 
 Xorriso_extf_destroy(xorriso, filter, 0);
12393
 
 return(-1);
12394
 
}
12395
 
 
12396
 
 
12397
 
int Xorriso_extf_destroy(struct XorrisO *xorriso, struct Xorriso_extF **filter,
12398
 
                         int flag)
12399
 
{
12400
 
 int i;
12401
 
 IsoExternalFilterCommand *cmd;
12402
 
 
12403
 
 if(*filter == NULL)
12404
 
   return(0);
12405
 
 cmd= (*filter)->cmd;
12406
 
 if(cmd != NULL) {
12407
 
   if(cmd->refcount > 0)
12408
 
     return(0);
12409
 
   if(cmd->suffix != NULL)
12410
 
     free(cmd->suffix);
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);
12416
 
   }
12417
 
   if(cmd->name != NULL)
12418
 
     free(cmd->name);
12419
 
 }
12420
 
 free((char *) *filter);
12421
 
 *filter= NULL;
12422
 
 return(1);
12423
 
}
12424
 
 
12425
 
 
12426
 
int Xorriso_lookup_extf(struct XorrisO *xorriso, char *name,
12427
 
                        struct Xorriso_lsT **found_lst, int flag)
12428
 
{
12429
 
 struct Xorriso_extF *filter;
12430
 
 struct Xorriso_lsT *lst;
12431
 
 
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) {
12435
 
     *found_lst= lst;
12436
 
     return(1);
12437
 
   }
12438
 
 }
12439
 
 return(0);
12440
 
}
12441
 
 
12442
 
 
12443
 
int Xorriso_destroy_all_extf(struct XorrisO *xorriso, int flag)
12444
 
{
12445
 
 struct Xorriso_extF *filter;
12446
 
 struct Xorriso_lsT *lst, *next_lst;
12447
 
 
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);
12454
 
 }
12455
 
 xorriso->filters= NULL;
12456
 
 return(1);
12457
 
}
12458
 
 
12459
 
 
12460
 
/*
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
12465
 
*/
12466
 
int Xorriso_rename_suffix(struct XorrisO *xorriso, IsoNode *node, char *suffix,
12467
 
                          char *show_path, char new_name[], int flag)
12468
 
{
12469
 
 int ret, lo= 0, ls= 0, strip_suffix;
12470
 
 char *old_name= NULL, *show_name;
12471
 
 
12472
 
 strip_suffix= !!(flag & 2);
12473
 
 
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);
12481
 
 if(strip_suffix) {
12482
 
   if(lo <= ls) {
12483
 
     /* refuse gracefully */
12484
 
     ret= 2; goto ex;
12485
 
   }
12486
 
   if(strcmp(old_name + lo - ls, suffix) != 0) {
12487
 
     ret= 2; goto ex;
12488
 
   }
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);
12494
 
   if (ret < 0) {
12495
 
     Xorriso_process_msg_queues(xorriso,0);
12496
 
     if (!(flag & 1))
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;
12505
 
   }
12506
 
 } else {
12507
 
   /* check whether suffix already present */
12508
 
   if(lo >= ls)
12509
 
     if(strcmp(old_name + lo - ls, suffix) == 0) {
12510
 
       /* refuse gracefully */
12511
 
       ret= 2; goto ex;
12512
 
     }
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;
12521
 
   } 
12522
 
   sprintf(new_name, "%s%s", old_name, suffix);
12523
 
   ret = iso_node_set_name(node, new_name);
12524
 
   if (ret < 0) {
12525
 
     Xorriso_process_msg_queues(xorriso,0);
12526
 
     if (!(flag & 1))
12527
 
       Xorriso_report_iso_error(xorriso, "", ret,
12528
 
                              "Error when renaming ISO node", 0, "FAILURE", 1);
12529
 
     goto cannot_append_suffix;
12530
 
   }
12531
 
 }
12532
 
 
12533
 
 ret= 1;
12534
 
ex:;
12535
 
 if(old_name != NULL)
12536
 
   free(old_name);
12537
 
 Xorriso_process_msg_queues(xorriso,0);
12538
 
 return(ret);
12539
 
}
12540
 
 
12541
 
 
12542
 
/*
12543
 
 @param flag   bit0= return 2 if renaming is not possible
12544
 
               bit1= print pacifier messages
12545
 
 */
12546
 
int Xorriso_set_filter(struct XorrisO *xorriso, void *in_node,
12547
 
                       char *path, char *filter_name, int flag)
12548
 
{
12549
 
 int ret, strip_suffix= 0, strip_filter= 0, filter_ret= 0;
12550
 
 int explicit_suffix= 0, internal_filter= 0;
12551
 
 IsoNode *node;
12552
 
 IsoFile *file;
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= "";
12557
 
 IsoStream *stream;
12558
 
 int is_renamed= 0;
12559
 
 
12560
 
 new_name[0]= 0;
12561
 
 
12562
 
 node= (IsoNode *) in_node;
12563
 
 if(node == NULL) {
12564
 
   ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
12565
 
   if(ret <= 0)
12566
 
     goto ex;
12567
 
 }
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);
12572
 
   ret= 0; goto ex;
12573
 
 }
12574
 
 file= (IsoFile *) node;
12575
 
 
12576
 
 if(strncmp(filter_name, "--remove-all-filters", 20) == 0) {
12577
 
   strip_filter= 1;
12578
 
   strip_suffix= 1;
12579
 
   if(strlen(filter_name) > 21) {
12580
 
     strip_suffix= (filter_name[20] != '+');
12581
 
     suffix= filter_name + 21;
12582
 
     explicit_suffix= 1;
12583
 
   }
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;
12590
 
   suffix= ".gz";
12591
 
   strip_suffix= 0;
12592
 
   explicit_suffix= 1;
12593
 
 } else if(strcmp(filter_name, "--gunzip") == 0 ||
12594
 
           strcmp(filter_name, "--gzip-decode") == 0) {
12595
 
   internal_filter= 4;
12596
 
   suffix= ".gz";
12597
 
   strip_suffix= 1;
12598
 
   explicit_suffix= 1;
12599
 
 } else {
12600
 
   ret= Xorriso_lookup_extf(xorriso, filter_name, &found_lst, 0);
12601
 
   if(ret < 0)
12602
 
     goto ex;
12603
 
   if(ret == 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);
12607
 
     ret= 0; goto ex;
12608
 
   }
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;
12613
 
 }
12614
 
 
12615
 
 if(suffix[0]) {
12616
 
 
12617
 
   /* >>> would need full iso_rr_path of node for showing */;
12618
 
 
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)
12623
 
     goto ex;
12624
 
   is_renamed= 1;
12625
 
 }
12626
 
 
12627
 
 if(strip_filter) {
12628
 
   while(1) {
12629
 
     if(!explicit_suffix) {
12630
 
       stream= iso_file_get_stream(file);
12631
 
 
12632
 
       if(strncmp(stream->class->type, "gzip", 4) == 0) {
12633
 
         suffix= ".gz";
12634
 
         strip_suffix= 1;
12635
 
       } else if(strncmp(stream->class->type, "pizg", 4) == 0) {
12636
 
         suffix= ".gz";
12637
 
         strip_suffix= 0;
12638
 
       } else {
12639
 
         ret= iso_stream_get_external_filter(stream, &cmd, 0);
12640
 
         if(ret > 0) {
12641
 
           suffix= cmd->suffix;
12642
 
           strip_suffix= !(cmd->behavior & 8);
12643
 
         }
12644
 
       }
12645
 
       if(suffix[0]) {
12646
 
 
12647
 
         /* >>> would need the current renaming state of path */;
12648
 
 
12649
 
         ret= Xorriso_rename_suffix(xorriso, node, suffix, NULL, new_name,
12650
 
                                    (flag & 1) | (strip_suffix << 1));
12651
 
         if(ret <= 0 || ret == 2)
12652
 
           goto ex;
12653
 
       }
12654
 
     }
12655
 
     ret= iso_file_remove_filter(file, 0);
12656
 
     if(ret != 1)
12657
 
   break;
12658
 
   }
12659
 
   filter_ret= 1;
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);
12667
 
   }
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);
12675
 
   }
12676
 
 } else {
12677
 
 
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.
12681
 
   */
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);
12686
 
     return(0);
12687
 
   }
12688
 
#endif /* ! Xorriso_allow_extf_suiD */
12689
 
 
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);
12695
 
   }
12696
 
 }
12697
 
 if(filter_ret != 1 && new_name[0] && old_name != NULL) {
12698
 
   ret = iso_node_set_name(node, old_name);
12699
 
   if (ret < 0) {
12700
 
     Xorriso_process_msg_queues(xorriso,0);
12701
 
     if (!(flag & 1))
12702
 
       Xorriso_report_iso_error(xorriso, "", ret,
12703
 
                              "Error when renaming ISO node", 0, "FAILURE", 1);
12704
 
   }
12705
 
 }
12706
 
 if(flag & 2) {
12707
 
   xorriso->pacifier_count++;
12708
 
   Xorriso_pacifier_callback(xorriso, "file filters processed",
12709
 
                      xorriso->pacifier_count, xorriso->pacifier_total, "", 0);
12710
 
 }
12711
 
 if(filter_ret < 0) {
12712
 
   ret= 0; goto ex;
12713
 
 }
12714
 
 
12715
 
 ret= filter_ret;
12716
 
ex:;
12717
 
 if(old_name != NULL)
12718
 
   free(old_name);
12719
 
 Xorriso_process_msg_queues(xorriso,0);
12720
 
 return(ret);
12721
 
}
12722
 
 
12723
 
 
12724
 
/* @param flag bit0= delete filter with the given name
12725
 
*/
12726
 
int Xorriso_external_filter(struct XorrisO *xorriso,
12727
 
                            char *name, char *options, char *path, 
12728
 
                            int argc, char **argv, int flag)
12729
 
{
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;
12734
 
 
12735
 
#ifndef Xorriso_allow_external_filterS
12736
 
 /* To be controlled by: configure --enable-external-filters */
12737
 
 
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);
12744
 
 is_banned= 1;
12745
 
 
12746
 
#endif /* ! Xorriso_allow_external_filterS */
12747
 
 
12748
 
#ifndef Xorriso_allow_extf_suiD
12749
 
 /* To be controlled by: configure --enable-external-filters-setuid */
12750
 
 
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);
12758
 
   is_banned= 1;
12759
 
 }
12760
 
#endif /* ! Xorriso_allow_extf_suiD */
12761
 
 
12762
 
 if(is_banned)
12763
 
   return(0);
12764
 
 
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);
12770
 
   return(0);
12771
 
 } 
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);
12777
 
   return(0);
12778
 
 }
12779
 
 
12780
 
 
12781
 
 delete= flag & 1;
12782
 
 ret= Xorriso_lookup_extf(xorriso, name, &lst, 0);
12783
 
 if(ret < 0)
12784
 
   return(ret);
12785
 
 if(ret > 0) {
12786
 
   if(delete) {
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);
12794
 
       ret= 0; goto ex;
12795
 
     }
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);
12801
 
     ret= 1; goto ex;
12802
 
   }
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);
12807
 
   ret= 0; goto ex;
12808
 
 }
12809
 
 if(delete) {
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);
12814
 
   ret= 0; goto ex;
12815
 
 }
12816
 
 
12817
 
 for(what= options; what!=NULL; what= what_next) {
12818
 
   what_next= strchr(what, ':');
12819
 
   if(what_next!=NULL) {
12820
 
     *what_next= 0;
12821
 
     what_next++;
12822
 
   }
12823
 
   if(strncmp(what, "default", 7) == 0) {
12824
 
     suffix= "";
12825
 
     behavior= 0;
12826
 
   } else if(strncmp(what, "suffix=", 7) == 0) {
12827
 
     suffix= what + 7;
12828
 
   } else if(strcmp(what, "remove_suffix") == 0) {
12829
 
     behavior|= 8;
12830
 
   } else if(strcmp(what, "if_nonempty") == 0) {
12831
 
     behavior|= 1;
12832
 
   } else if(strcmp(what, "if_reduction") == 0) {
12833
 
     behavior|= 2;
12834
 
   } else if(strcmp(what, "if_block_reduction") == 0) {
12835
 
     behavior|= 4;
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);
12843
 
     ret= 0; goto ex;
12844
 
   }
12845
 
 }
12846
 
 
12847
 
 ret= Xorriso_extf_new(xorriso, &new_filter, path, argc, argv, behavior,
12848
 
                       suffix, name, extf_flag);
12849
 
 if(ret <= 0) {
12850
 
could_not_create:;
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);
12854
 
   goto ex;
12855
 
 }
12856
 
 ret= Xorriso_lst_append_binary(&(xorriso->filters), (char *) new_filter,0, 4);
12857
 
 if(ret <= 0)
12858
 
   goto could_not_create;
12859
 
 ret= 1;
12860
 
ex:;
12861
 
 if(ret <= 0) {
12862
 
   if(new_filter != NULL)
12863
 
     Xorriso_extf_destroy(xorriso, &new_filter, 0);
12864
 
 }
12865
 
 return(ret);
12866
 
}
12867
 
 
12868
 
 
12869
 
int Xorriso_status_extf(struct XorrisO *xorriso, char *filter, FILE *fp,
12870
 
                        int flag)
12871
 
/*
12872
 
 bit1= do only report to fp
12873
 
*/ 
12874
 
{
12875
 
 int i, maxl= 4 * SfileadrL;
12876
 
 struct Xorriso_extF *extf;
12877
 
 struct Xorriso_lsT *lst;
12878
 
 char *line;
12879
 
 
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);
12883
 
   
12884
 
   strcpy(xorriso->result_line, "-external_filter ");
12885
 
   Text_shellsafe(extf->cmd->name, line, 1);
12886
 
   if(strlen(line) > maxl)
12887
 
 continue;
12888
 
   strcat(line, " ");
12889
 
   if(extf->cmd->suffix[0]) {
12890
 
     strcat(line, "suffix=");
12891
 
     Text_shellsafe(extf->cmd->suffix, line, 1);
12892
 
     if(strlen(line) > maxl)
12893
 
 continue;
12894
 
     strcat(line, ":");
12895
 
   }
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)
12906
 
 continue;
12907
 
   Text_shellsafe(extf->cmd->path, line, 1);
12908
 
   if(strlen(line) > maxl)
12909
 
 continue;
12910
 
   for(i= 1; i < extf->cmd->argc; i++) {
12911
 
     strcat(line, " ");
12912
 
     Text_shellsafe(extf->cmd->argv[i], line, 1);
12913
 
     if(strlen(line) > maxl)
12914
 
   break;
12915
 
   }
12916
 
   if(i < extf->cmd->argc)
12917
 
 continue;
12918
 
   strcat(line, " --\n");
12919
 
   Xorriso_status_result(xorriso, filter, fp, flag&2);
12920
 
 }
12921
 
 if(xorriso->filter_list_closed) {
12922
 
   strcpy(line, "-close_filter_list\n");
12923
 
   Xorriso_status_result(xorriso, filter, fp, flag&2);
12924
 
 }
12925
 
 return(1);
12926
 
}
12927
 
 
12928
 
 
12929
 
int Xorriso_stream_type(struct XorrisO *xorriso, IsoNode *node,
12930
 
                        IsoStream *stream, char type_text[], int flag)
12931
 
{
12932
 
 int ret, lba;
12933
 
 char text[5];
12934
 
 
12935
 
 strncpy(text, stream->class->type, 4);
12936
 
 text[4]= 0;
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");
12941
 
   else
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);
12954
 
 } else {
12955
 
   Text_shellsafe(text, type_text, 0);
12956
 
 }
12957
 
 return(1);
12958
 
12959
 
 
12960
 
int Xorriso_show_stream(struct XorrisO *xorriso, void *in_node,
12961
 
                        char *path, int flag)
12962
 
{
12963
 
 int ret;
12964
 
 IsoNode *node;
12965
 
 IsoFile *file;
12966
 
 IsoStream *stream= NULL, *input_stream;
12967
 
 IsoExternalFilterCommand *cmd;
12968
 
 char type_text[16], *source_path= NULL;
12969
 
 
12970
 
 node= (IsoNode *) in_node;
12971
 
 if(node == NULL) {
12972
 
   ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
12973
 
   if(ret <= 0)
12974
 
     goto ex;
12975
 
 }
12976
 
 if(!LIBISO_ISREG(node)) 
12977
 
   {ret= 2; goto ex;}
12978
 
 file= (IsoFile *) node;
12979
 
 input_stream= iso_file_get_stream(file);
12980
 
 Text_shellsafe(path, xorriso->result_line, 0);
12981
 
 while(1) {
12982
 
   stream= input_stream;
12983
 
   input_stream= iso_stream_get_input_stream(stream, 0);
12984
 
   if(input_stream == NULL)
12985
 
 break;
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);
12990
 
   if(ret < 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);
12994
 
     ret= 0; goto ex;
12995
 
   }
12996
 
   if(ret > 0) {
12997
 
     strcat(xorriso->result_line, ":");
12998
 
     Text_shellsafe(cmd->name, xorriso->result_line, 1);
12999
 
   }
13000
 
   if(strlen(xorriso->result_line) > SfileadrL) {
13001
 
     Xorriso_result(xorriso, 0);
13002
 
     xorriso->result_line[0]= 0;
13003
 
   }
13004
 
 }
13005
 
 strcat(xorriso->result_line, " < ");
13006
 
 Xorriso_stream_type(xorriso, node, stream, type_text, 0);
13007
 
 strcat(xorriso->result_line, type_text);
13008
 
 
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);
13013
 
 }
13014
 
 
13015
 
 strcat(xorriso->result_line, "\n");
13016
 
 Xorriso_result(xorriso, 0);
13017
 
 ret= 1;
13018
 
ex:;
13019
 
 if(source_path != NULL)
13020
 
   free(source_path);
13021
 
 return(ret); 
13022
 
}
13023
 
 
13024
 
 
13025
 
int Xorriso_set_zisofs_params(struct XorrisO *xorriso, int flag)
13026
 
{
13027
 
 int ret;
13028
 
 struct iso_zisofs_ctrl ctrl;
13029
 
 
13030
 
 ctrl.version= 0;
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;
13036
 
 else
13037
 
   ctrl.block_size_log2= 15;
13038
 
 ret= iso_zisofs_set_params(&ctrl, 0);
13039
 
 Xorriso_process_msg_queues(xorriso,0);
13040
 
 if(ret < 0) {
13041
 
   Xorriso_report_iso_error(xorriso, "", ret,
13042
 
                      "Error when setting zisofs parameters", 0, "FAILURE", 1);
13043
 
   return(0);
13044
 
 }
13045
 
 return(1);
13046
 
}
13047
 
 
13048
 
 
13049
 
int Xorriso_status_zisofs(struct XorrisO *xorriso, char *filter, FILE *fp,
13050
 
                          int flag)
13051
 
/*
13052
 
 bit0= do only report non-default settings
13053
 
 bit1= do only report to fp
13054
 
*/ 
13055
 
{
13056
 
 off_t ziso_count= 0, osiz_count= 0;
13057
 
 off_t gzip_count= 0, gunzip_count= 0;
13058
 
 
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) {
13066
 
   if(filter == NULL)
13067
 
     return(2);
13068
 
   if(filter[0] == 0)
13069
 
     return 2;
13070
 
 }
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);
13080
 
 return(1);
13081
 
}
13082
 
 
13083
 
 
13084
 
int Xorriso_all_node_array(struct XorrisO *xorriso, int addon_nodes, int flag)
13085
 
{  
13086
 
 int ret;
13087
 
 struct FindjoB *job= NULL;
13088
 
 struct stat dir_stbuf;
13089
 
 
13090
 
 ret= Findjob_new(&job, "/", 0);
13091
 
 if(ret<=0) {
13092
 
   Xorriso_no_findjob(xorriso, "xorriso", 0);
13093
 
   {ret= -1; goto ex;}
13094
 
 }
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, "/",
13098
 
                    &dir_stbuf, 0, 0);
13099
 
 if(ret <= 0)
13100
 
   goto ex;
13101
 
 ret= Xorriso_new_node_array(xorriso, xorriso->temp_mem_limit, addon_nodes, 0);
13102
 
 if(ret <= 0)
13103
 
   goto ex;
13104
 
 Findjob_set_action_target(job, 31, NULL, 0);
13105
 
 ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, NULL, "/",
13106
 
                    &dir_stbuf, 0, 0);
13107
 
 if(ret <= 0)
13108
 
   goto ex;
13109
 
 ret= 1;
13110
 
ex:;
13111
 
 Findjob_destroy(&job, 0);
13112
 
 return(ret);
13113
 
}
13114
 
 
13115
 
 
13116
 
int Xorriso_remake_hln_array(struct XorrisO *xorriso, int flag)
13117
 
{  
13118
 
 int ret, addon_nodes= 0, i, old_count, old_pt, new_pt;
13119
 
 IsoNode **old_nodes;
13120
 
 char **old_targets;
13121
 
 
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)
13125
 
 continue;
13126
 
   if(Xorriso_node_is_valid(xorriso, xorriso->hln_array[i], 0))
13127
 
 continue;
13128
 
   addon_nodes++;
13129
 
 }
13130
 
 ret= Xorriso_all_node_array(xorriso, addon_nodes, 0);
13131
 
 if(ret <= 0)
13132
 
   goto ex;
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)
13137
 
   continue;
13138
 
     if(Xorriso_node_is_valid(xorriso, xorriso->hln_array[i], 0))
13139
 
   continue;
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]);
13143
 
     }
13144
 
   }
13145
 
 }
13146
 
 
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;
13153
 
 
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;
13160
 
 
13161
 
 /* Allocate hln_targets */
13162
 
 ret= Xorriso_new_hln_array(xorriso, xorriso->temp_mem_limit, 1);
13163
 
 if(ret<=0)
13164
 
   goto ex;
13165
 
 xorriso->node_targets_availmem= xorriso->temp_mem_limit;
13166
 
 if(old_targets != NULL) {
13167
 
   /* Transfer targets from old target array */;
13168
 
   new_pt= old_pt= 0;
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]);
13171
 
     if(ret < 0) {
13172
 
       new_pt++;
13173
 
     } else if(ret > 0) {
13174
 
       old_pt++;
13175
 
     } else {
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;
13180
 
       new_pt++;
13181
 
       old_pt++;
13182
 
     }
13183
 
   }
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);
13188
 
 }
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);
13194
 
 }
13195
 
 xorriso->hln_change_pending= 0;
13196
 
 ret= 1;
13197
 
ex:;
13198
 
 return(ret);
13199
 
}
13200
 
 
13201
 
 
13202
 
/* @param flag bit0= overwrite existing hln_array (else return 2)
13203
 
*/
13204
 
int Xorriso_make_hln_array(struct XorrisO *xorriso, int flag)
13205
 
{  
13206
 
 int ret;
13207
 
 
13208
 
 if(xorriso->hln_array != NULL && !(flag & 1)) {
13209
 
   /* If no fresh image manipulations occured: keep old array */
13210
 
   if(!xorriso->hln_change_pending)
13211
 
     return(2);
13212
 
   ret= Xorriso_remake_hln_array(xorriso, 0);
13213
 
   return(ret);
13214
 
 }
13215
 
 Xorriso_destroy_hln_array(xorriso, 0);
13216
 
 
13217
 
 ret= Xorriso_all_node_array(xorriso, 0, 0);
13218
 
 if(ret <= 0)
13219
 
   goto ex;
13220
 
 Xorriso_sort_node_array(xorriso, 0);
13221
 
 
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;
13228
 
 
13229
 
 /* Allocate hln_targets */
13230
 
 ret= Xorriso_new_hln_array(xorriso, xorriso->temp_mem_limit, 1);
13231
 
 if(ret<=0) {
13232
 
   Xorriso_destroy_hln_array(xorriso, 0);
13233
 
   goto ex;
13234
 
 }
13235
 
 xorriso->node_targets_availmem= xorriso->temp_mem_limit;
13236
 
 xorriso->hln_change_pending= 0;
13237
 
 ret= 1;
13238
 
ex:;
13239
 
 return(ret);
13240
 
}
13241
 
 
13242
 
 
13243
 
/* @param flag bit0= overwrite existing di_array (else return 2)
13244
 
               bit1= make di_array despite xorriso->ino_behavior bit 3
13245
 
*/
13246
 
int Xorriso_make_di_array(struct XorrisO *xorriso, int flag)
13247
 
{  
13248
 
 int ret, bytes; 
13249
 
 
13250
 
#ifdef NIX
13251
 
 /* <<< */
13252
 
 unsigned long old_gdic;
13253
 
 old_gdic= Xorriso_get_di_counteR;
13254
 
#endif /* NIX */
13255
 
 
13256
 
 if((xorriso->ino_behavior & 8 ) && !(flag & 2))
13257
 
   return(2);
13258
 
 if(xorriso->di_array != NULL && !(flag & 1))
13259
 
   return(2);
13260
 
 Xorriso_finish_hl_update(xorriso, 0);
13261
 
 
13262
 
 ret= Xorriso_all_node_array(xorriso, 0, 0);
13263
 
 if(ret <= 0)
13264
 
   goto ex;
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);
13269
 
   ret= -1; goto ex;
13270
 
 }
13271
 
 
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;
13278
 
 
13279
 
 Xorriso__sort_di((void *) xorriso->di_array, xorriso->di_count, 0);
13280
 
 
13281
 
 ret= 1;
13282
 
ex:;
13283
 
 
13284
 
#ifdef NIX
13285
 
/* <<< */
13286
 
 fprintf(stderr, "xorriso_DEBUG: sort_count= %lu\n",
13287
 
         Xorriso_get_di_counteR - old_gdic);
13288
 
#endif /* NIX */
13289
 
 
13290
 
 return(ret);
13291
 
}
13292
 
 
13293
 
 
13294
 
/*
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
13301
 
 */
13302
 
int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result,
13303
 
                            char *disk_path, char *iso_rr_path, int flag)
13304
 
{
13305
 
 int ret, hret, idx, low, high, i, do_overwrite= 0, did_fake_di= 0;
13306
 
 int follow_links, old_idx= -1;
13307
 
 IsoNode *node;
13308
 
 struct stat stbuf;
13309
 
 dev_t old_dev;
13310
 
 ino_t old_ino;
13311
 
 
13312
 
 if(xorriso->di_array == NULL)
13313
 
   return(1);
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);
13317
 
 if(ret <= 0)
13318
 
   return(ret);
13319
 
 if(LIBISO_ISDIR(node))
13320
 
   return(1);
13321
 
 
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.
13329
 
 */
13330
 
 if(!(flag & 1))
13331
 
   do_overwrite= 1;
13332
 
 
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);
13336
 
 if(ret < 0)
13337
 
   {ret= 0; goto ex;}
13338
 
 if(ret > 0)
13339
 
   old_idx= idx;
13340
 
 
13341
 
 /* Handle eventual hardlink joining : */
13342
 
 
13343
 
 if(follow_links)
13344
 
   ret= stat(disk_path, &stbuf);
13345
 
 else
13346
 
   ret= lstat(disk_path, &stbuf);
13347
 
 if(ret==-1)
13348
 
   {ret= 0; goto ex;}
13349
 
 
13350
 
 /* Are there new dev-ino-siblings in the image ? */
13351
 
 /* Fake isofs.di */
13352
 
 if(!(flag & 1)) {
13353
 
   ret= Xorriso_record_dev_inode(xorriso, disk_path, stbuf.st_dev,
13354
 
                                 stbuf.st_ino, node, iso_rr_path, 1);
13355
 
   if(ret <= 0)
13356
 
     {ret= -1; goto ex;}
13357
 
   did_fake_di= 1;
13358
 
   /* temporarily remove node from di_array so it does not disturb 
13359
 
       search by its fake di info */;
13360
 
   if(old_idx >= 0)
13361
 
     xorriso->di_array[old_idx]= NULL;
13362
 
 }
13363
 
 ret= Xorriso_search_di_range(xorriso, node, &idx, &low, &high, 1);
13364
 
 if(did_fake_di) {
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);
13368
 
   if(hret <= 0)
13369
 
     {ret= -1; goto ex;}
13370
 
   if(old_idx >= 0)
13371
 
     xorriso->di_array[old_idx]= node;
13372
 
 }
13373
 
 if(ret == 0)
13374
 
   {ret= 1; goto ex;}
13375
 
 if(ret < 0)
13376
 
   {ret= 0; goto ex;}
13377
 
 
13378
 
 
13379
 
#ifdef Xorriso_hardlink_update_debuG
13380
 
 /* <<< */
13381
 
 if(low < high || idx < 0) {
13382
 
   fprintf(stderr,
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);
13385
 
   fprintf(stderr,
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);
13389
 
 
13390
 
   if(idx >= 0 && idx != old_idx)
13391
 
     fprintf(stderr, "xorriso_DEBUG: idx= %d , old_idx = %d\n", idx, old_idx);
13392
 
 }
13393
 
#endif /* Xorriso_hardlink_update_debuG */
13394
 
 
13395
 
 /* Overwrite all valid siblings : */
13396
 
 for(i= low; i <= high; i++) {
13397
 
   if(i == idx || xorriso->di_array[i] == NULL)
13398
 
 continue;
13399
 
 
13400
 
#ifdef Xorriso_hardlink_update_debuG
13401
 
 /* <<< */
13402
 
{
13403
 
 ino_t ino;
13404
 
 dev_t dev;
13405
 
 
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);
13409
 
}
13410
 
#endif /* Xorriso_hardlink_update_debuG */
13411
 
 
13412
 
   xorriso->di_do_widen[i / 8]|= 1 << (i % 8);
13413
 
 }
13414
 
 
13415
 
 ret= 1;
13416
 
ex:;
13417
 
 if(do_overwrite)
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;
13424
 
 }
13425
 
 return(ret);
13426
 
}
13427
 
 
13428
 
 
13429
 
/* @param flag bit0= do not destroy di_array
13430
 
*/
13431
 
int Xorriso_finish_hl_update(struct XorrisO *xorriso, int flag)
13432
 
{
13433
 
 int ret, zero= 0;
13434
 
 char *argv[4];
13435
 
 struct Xorriso_lsT *disk_lst, *iso_lst;
13436
 
 
13437
 
 if(xorriso->di_array == NULL)
13438
 
   {ret= 1; goto ex;}
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);
13443
 
   argv[1]= "-exec";
13444
 
   argv[2]= "widen_hardlinks";
13445
 
   argv[3]= Xorriso_lst_get_text(disk_lst, 0);
13446
 
   zero= 0;
13447
 
   ret= Xorriso_option_find(xorriso, 4, argv, &zero, 0); /* -findi */
13448
 
   if(ret < 0)
13449
 
     goto ex;
13450
 
   disk_lst= Xorriso_lst_get_next(disk_lst, 0);
13451
 
   iso_lst= Xorriso_lst_get_next(iso_lst, 0);
13452
 
 }
13453
 
 ret= 1;
13454
 
ex:;
13455
 
 if(!(flag & 1))
13456
 
   Xorriso_destroy_di_array(xorriso, 0);
13457
 
 return(ret);
13458
 
}
13459
 
 
13460
 
 
13461
 
/*
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
13464
 
*/
13465
 
int Xorriso_get_md5(struct XorrisO *xorriso, void *in_node, char *path,
13466
 
                    char md5[16], int flag)
13467
 
{
13468
 
 int ret= 1, i;
13469
 
 char *wpt;
13470
 
 IsoImage *image;
13471
 
 IsoNode *node;
13472
 
 
13473
 
 ret= Xorriso_get_volume(xorriso, &image, 0);
13474
 
 if(ret <= 0)
13475
 
   goto ex;
13476
 
 node= (IsoNode *) in_node;
13477
 
 if(node == NULL) {
13478
 
   ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
13479
 
   if(ret<=0)
13480
 
     goto ex;
13481
 
 }
13482
 
 if(!LIBISO_ISREG(node))
13483
 
   return(0);
13484
 
 ret= iso_file_get_md5(image, (IsoFile *) node, md5, 0);
13485
 
 Xorriso_process_msg_queues(xorriso,0);
13486
 
 if(ret <= 0)
13487
 
   goto ex;
13488
 
 if(flag & 1)
13489
 
   {ret= 1; goto ex;}
13490
 
 
13491
 
 wpt= xorriso->result_line;
13492
 
 for(i= 0; i < 16; i++) {
13493
 
   sprintf(wpt, "%2.2x", ((unsigned char *) md5)[i]);
13494
 
   wpt+= 2;
13495
 
 }
13496
 
 strcpy(wpt, "  ");
13497
 
 wpt+= 2;
13498
 
 Xorriso_getfname(xorriso, path, 1 | 2);
13499
 
 ret= 1;
13500
 
ex:;
13501
 
 return(ret);
13502
 
}
13503
 
 
13504
 
 
13505
 
int Xorriso_make_md5(struct XorrisO *xorriso, void *in_node, char *path,
13506
 
                     int flag)
13507
 
{
13508
 
 int ret;
13509
 
 off_t size;
13510
 
 IsoNode *node;
13511
 
 
13512
 
 node= (IsoNode *) in_node;
13513
 
 if(node == NULL) {
13514
 
   ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
13515
 
   if(ret <= 0)
13516
 
     return(ret);
13517
 
 }
13518
 
 if(!LIBISO_ISREG(node))
13519
 
   return(0);
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);
13527
 
 if(ret < 0) {
13528
 
   Xorriso_report_iso_error(xorriso, "", ret,
13529
 
                            "Error when computing MD5", 0, "FAILURE", 1);
13530
 
   return(0);
13531
 
 }
13532
 
 Xorriso_set_change_pending(xorriso, 1);
13533
 
 return(1);
13534
 
}
13535
 
 
13536
 
 
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
13540
 
                          by return value
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
13547
 
                   <0= other error
13548
 
*/
13549
 
int Xorriso_check_md5(struct XorrisO *xorriso, void *in_node, char *path,
13550
 
                      int flag)
13551
 
{
13552
 
 int ret, wanted, rret;
13553
 
 IsoImage *image;
13554
 
 IsoNode *node;
13555
 
 IsoFile *file;
13556
 
 char node_md5[16], data_md5[16], buffer[64 * 1024];
13557
 
 void *stream= NULL, *ctx= NULL;
13558
 
 off_t todo;
13559
 
 
13560
 
 node= (IsoNode *) in_node;
13561
 
 if(node == NULL) {
13562
 
   ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
13563
 
   if(ret<=0)
13564
 
     {ret= -1; goto ex;}
13565
 
 }
13566
 
 if(!LIBISO_ISREG(node)) {
13567
 
   strcpy(xorriso->info_text, "-check_md5: Not a data file: ");
13568
 
   Text_shellsafe(path, xorriso->info_text, 1);
13569
 
   if(!(flag & 2))
13570
 
     Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
13571
 
   ret= 3; goto ex;
13572
 
 }
13573
 
 file= (IsoFile *) node;
13574
 
 
13575
 
 /* obtain MD5 */
13576
 
 ret= Xorriso_get_volume(xorriso, &image, 0);
13577
 
 if(ret <= 0)
13578
 
   {ret= -1; goto ex;}
13579
 
 ret= iso_file_get_md5(image, file, node_md5, 0);
13580
 
 Xorriso_process_msg_queues(xorriso,0);
13581
 
 if(ret < 0)
13582
 
   {ret= -1; goto ex;}
13583
 
 if(ret == 0) {
13584
 
   strcpy(xorriso->info_text, "-check_md5: No MD5 recorded with file: ");
13585
 
   Text_shellsafe(path, xorriso->info_text, 1);
13586
 
   if(!(flag & 2))
13587
 
     Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
13588
 
   ret= 2; goto ex;
13589
 
 }
13590
 
 
13591
 
 /* Read file and compute MD5 */;
13592
 
 ret= Xorriso_iso_file_open(xorriso, path, (void *) node, &stream, 1 | 2);
13593
 
 if(ret <= 0)
13594
 
   {ret= -1; goto ex;}
13595
 
 ret= iso_md5_start(&ctx);
13596
 
 if(ret < 0)
13597
 
     goto ex;
13598
 
 todo= iso_stream_get_size(stream);
13599
 
 while(todo > 0) {
13600
 
   if(todo < sizeof(buffer))
13601
 
     wanted= todo;
13602
 
   else
13603
 
     wanted= sizeof(buffer);
13604
 
   rret = Xorriso_iso_file_read(xorriso, stream, buffer, wanted, 0);
13605
 
   if(rret <= 0)
13606
 
     {ret= -1; goto ex;}
13607
 
   todo-= rret;
13608
 
   ret = iso_md5_compute(ctx, buffer, rret);
13609
 
   if(ret < 0)
13610
 
     goto ex;
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);
13615
 
 }
13616
 
 ret= iso_md5_end(&ctx, data_md5);
13617
 
 if(ret < 0)
13618
 
     goto ex;
13619
 
 
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");
13626
 
   if(!(flag & 1))
13627
 
     Xorriso_result(xorriso,0);
13628
 
   ret= 0;
13629
 
 } else {
13630
 
   sprintf(xorriso->result_line, "md5 match   : ");
13631
 
   Text_shellsafe(path, xorriso->result_line, 1);
13632
 
   strcat(xorriso->result_line, "\n");
13633
 
   if(flag & 4)
13634
 
     Xorriso_result(xorriso,0);
13635
 
   ret= 1;
13636
 
 }
13637
 
 
13638
 
ex:;
13639
 
 Xorriso_process_msg_queues(xorriso,0);
13640
 
 Xorriso_iso_file_close(xorriso, &stream, 0);
13641
 
 if(ctx != NULL)
13642
 
   iso_md5_end(&ctx, data_md5);
13643
 
 if(ret < 0) {
13644
 
   sprintf(xorriso->result_line, "NOT READABLE: ");
13645
 
   Text_shellsafe(path, xorriso->result_line, 1);
13646
 
   strcat(xorriso->result_line, "\n");
13647
 
   if(!(flag & 1))
13648
 
     Xorriso_result(xorriso,0);
13649
 
 }
13650
 
 return(ret);
13651
 
}
13652
 
 
13653
 
 
13654
 
int Xorriso_check_md5_range(struct XorrisO *xorriso, off_t start_lba,
13655
 
                            off_t end_lba, char md5[16], int flag)
13656
 
{
13657
 
 int ret;
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];
13662
 
 void *ctx = NULL;
13663
 
 
13664
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
13665
 
                                "on attempt to check session MD5 checksum", 0);
13666
 
 if(ret <= 0)
13667
 
   goto ex;
13668
 
 ret= iso_md5_start(&ctx);
13669
 
 if(ret <= 0) {
13670
 
   Xorriso_no_malloc_memory(xorriso, NULL, 0);
13671
 
   goto ex;
13672
 
 }
13673
 
 for(pos= start_lba; pos < end_lba; pos+= 32) {
13674
 
   to_read= 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);
13679
 
   if(ret <= 0)
13680
 
     goto ex;
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);
13686
 
 }
13687
 
 iso_md5_end(&ctx, data_md5);
13688
 
 ret= 1;
13689
 
 if(! iso_md5_match(md5, data_md5))
13690
 
   ret= 0;
13691
 
ex:;
13692
 
 Xorriso_process_msg_queues(xorriso,0);
13693
 
 if(ctx != NULL)
13694
 
   iso_md5_end(&ctx, data_md5);
13695
 
 return(ret);
13696
 
}
13697
 
 
13698
 
 
13699
 
int Xorriso_check_session_md5(struct XorrisO *xorriso, char *severity,
13700
 
                              int flag)
13701
 
{
13702
 
 int ret, i;
13703
 
 IsoImage *image;
13704
 
 uint32_t start_lba, end_lba;
13705
 
 char md5[16], md5_text[33];
13706
 
 
13707
 
 ret= Xorriso_get_volume(xorriso, &image, 0);
13708
 
 if(ret<=0)
13709
 
   return(ret);
13710
 
 ret= iso_image_get_session_md5(image, &start_lba, &end_lba, md5, 0);
13711
 
 Xorriso_process_msg_queues(xorriso,0);
13712
 
 if(ret < 0)
13713
 
   return(ret);
13714
 
 if(ret == 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);
13718
 
   return(0);
13719
 
 }
13720
 
 
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,
13730
 
                              md5, 0);
13731
 
 return(ret);
13732
 
}
13733
 
 
13734
 
 
13735
 
int Xorriso_image_has_md5(struct XorrisO *xorriso, int flag)
13736
 
{
13737
 
 int ret;
13738
 
 IsoImage *image;
13739
 
 uint32_t start_lba, end_lba;
13740
 
 char md5[16];
13741
 
 
13742
 
 ret= Xorriso_get_volume(xorriso, &image, 0);
13743
 
 if(ret<=0)
13744
 
   return(ret);
13745
 
 ret= iso_image_get_session_md5(image, &start_lba, &end_lba, md5, 0);
13746
 
 Xorriso_process_msg_queues(xorriso,0);
13747
 
 if(ret <= 0)
13748
 
   return(0);
13749
 
 return(1);
13750
 
}
13751
 
 
13752
 
 
13753
 
int Xorriso_md5_start(struct XorrisO *xorriso, void **ctx, int flag)
13754
 
{
13755
 
 int ret;
13756
 
 
13757
 
 ret= iso_md5_start(ctx);
13758
 
 if(ret == 1)
13759
 
   return(1);
13760
 
 Xorriso_no_malloc_memory(xorriso, NULL, 0);
13761
 
 return(-1);
13762
 
}
13763
 
 
13764
 
 
13765
 
int Xorriso_md5_compute(struct XorrisO *xorriso, void *ctx,
13766
 
                        char *data, int datalen, int flag)
13767
 
{
13768
 
 iso_md5_compute(ctx, data, datalen);
13769
 
 return(1);
13770
 
}
13771
 
 
13772
 
 
13773
 
int Xorriso_md5_end(struct XorrisO *xorriso, void **ctx, char md5[16],
13774
 
                    int flag)
13775
 
{
13776
 
 int ret;
13777
 
 
13778
 
 ret= iso_md5_end(ctx, md5);
13779
 
 Xorriso_process_msg_queues(xorriso,0);
13780
 
 if(ret <= 0)
13781
 
   return(0);
13782
 
 return(1);
13783
 
}
13784
 
 
13785
 
 
13786
 
/* @param flag bit0=input drive
13787
 
               bit1=output drive
13788
 
               bit2= wake up rather than calm down
13789
 
*/
13790
 
int Xorriso_drive_snooze(struct XorrisO *xorriso, int flag)
13791
 
{
13792
 
 int in_is_out_too, ret;
13793
 
 struct burn_drive_info *dinfo;
13794
 
 struct burn_drive *drive;
13795
 
 
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));
13801
 
   if(in_is_out_too)
13802
 
     {ret= 1; goto ex;}
13803
 
 }
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));
13808
 
 }
13809
 
 ret= 1;
13810
 
ex:;
13811
 
 Xorriso_process_msg_queues(xorriso,0);
13812
 
 return(ret);
13813
 
}
13814
 
 
13815
 
 
13816
 
int Xorriso_pvd_info(struct XorrisO *xorriso, int flag)
13817
 
{
13818
 
 int ret, msc1= -1, msc2, i;
13819
 
 IsoImage *image;
13820
 
 struct burn_drive_info *dinfo;
13821
 
 struct burn_drive *drive;
13822
 
 char *msg, block_head[8];
13823
 
 off_t head_count;
13824
 
 
13825
 
 msg= xorriso->result_line;
13826
 
 ret= Xorriso_get_volume(xorriso, &image, 0);
13827
 
 if(ret<=0)
13828
 
   return(ret);
13829
 
 ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, "", 16);
13830
 
 if(ret > 0) {
13831
 
   ret= Xorriso_msinfo(xorriso, &msc1, &msc2, 1 | 4);
13832
 
   if(ret<0)
13833
 
     return(ret);
13834
 
   Xorriso_toc(xorriso, 128);
13835
 
   if(msc1 >= 0) {
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);
13839
 
       if(ret <= 0) {
13840
 
         i= msc1 + 32;
13841
 
     break;
13842
 
       }
13843
 
       if(block_head[0] == 1 && strncmp(block_head + 1, "CD001", 5) == 0)
13844
 
     break;
13845
 
     }
13846
 
     if(i < msc1 + 32) {
13847
 
       sprintf(msg, "PVD address  : %ds\n", i);
13848
 
       Xorriso_result(xorriso,0);
13849
 
     }
13850
 
   }
13851
 
 }
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);
13873
 
 return(1);
13874
 
}
13875
 
 
13876
 
 
13877
 
/* @param flag bit0= do not set hln_change_pending */
13878
 
int Xorriso_set_change_pending(struct XorrisO *xorriso, int flag)
13879
 
{
13880
 
 int ret;
13881
 
 IsoImage *image;
13882
 
 
13883
 
 ret= Xorriso_get_volume(xorriso, &image, 1);
13884
 
 if(ret <= 0)
13885
 
   return ret;
13886
 
 xorriso->volset_change_pending= 1;
13887
 
 if(!(flag & 1))
13888
 
   xorriso->hln_change_pending= 1;
13889
 
 return(1);
13890
 
}
13891
 
 
13892
 
 
13893
 
/* @param flag bit0= enable SCSI command logging to stderr */
13894
 
int Xorriso_scsi_log(struct XorrisO *xorriso, int flag)
13895
 
{
13896
 
 if(flag == 0)
13897
 
   burn_set_scsi_logging(0);
13898
 
 else
13899
 
   burn_set_scsi_logging(2|4);
13900
 
 return(1);
13901
 
}