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

« back to all changes in this revision

Viewing changes to xorriso/aux_objects.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
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
 
3
 
 
4
   Copyright 2007-2010 Thomas Schmitt, <scdbackup@gmx.net>
 
5
 
 
6
   Provided under GPL version 2 or later.
 
7
 
 
8
   This file contains the implementations of classes:
 
9
 
 
10
   - SplitparT which represents byte intervals of data files.
 
11
 
 
12
   - DirseQ which crawls along a directory's content list.
 
13
 
 
14
   - ExclusionS which manages the list of excluded file paths and
 
15
     leaf patterns.
 
16
     Because of its structural identity it is also used for disk address
 
17
     oriented hiding at insert time as of mkisofs.
 
18
 
 
19
   - Xorriso_lsT which provides a generic double-linked list.
 
20
 
 
21
   - LinkiteM, PermiteM which temporarily record relations and states.
 
22
 
 
23
*/
 
24
 
 
25
#ifdef HAVE_CONFIG_H
 
26
#include "../config.h"
 
27
#endif
 
28
 
 
29
#include <ctype.h>
 
30
#include <sys/types.h>
 
31
#include <unistd.h>
 
32
#include <stdlib.h>
 
33
#include <stdio.h>
 
34
#include <string.h>
 
35
#include <sys/stat.h>
 
36
#include <sys/time.h>
 
37
#include <time.h>
 
38
#include <utime.h>
 
39
#include <dirent.h>
 
40
#include <errno.h>
 
41
 
 
42
 
 
43
#include "xorriso.h"
 
44
#include "xorriso_private.h"
 
45
 
 
46
 
 
47
/* ---------------------------- SplitparT ------------------------- */
 
48
 
 
49
 
 
50
struct SplitparT {
 
51
 char *name;
 
52
 int partno;
 
53
 int total_parts;
 
54
 off_t offset;
 
55
 off_t bytes;
 
56
 off_t total_bytes;
 
57
};
 
58
 
 
59
static char Splitpart_wordS[][16]= {"part_", "_of_", "_at_", "_with_", "_of_"};
 
60
 
 
61
 
 
62
int Splitparts_new(struct SplitparT **o, int count, int flag)
 
63
{
 
64
 int i;
 
65
 
 
66
 (*o)= TSOB_FELD(struct SplitparT, count);
 
67
 if((*o)==NULL)
 
68
   return(-1);
 
69
 for(i= 0; i<count; i++) {
 
70
   (*o)[i].name= NULL;
 
71
   (*o)[i].partno= 0;
 
72
   (*o)[i].total_parts= 0;
 
73
   (*o)[i].offset= 0;
 
74
   (*o)[i].bytes= 0;
 
75
   (*o)[i].total_bytes= 0;
 
76
 }
 
77
 return(1);
 
78
}
 
79
 
 
80
 
 
81
int Splitparts_destroy(struct SplitparT **o, int count, int flag)
 
82
{
 
83
 int i;
 
84
 
 
85
 if((*o)==NULL)
 
86
   return(0);
 
87
 for(i= 0; i<count; i++) {
 
88
   if((*o)[i].name!=NULL)
 
89
     free((*o)[i].name);
 
90
 }
 
91
 free(*o);
 
92
 *o= NULL;
 
93
 return(1);
 
94
}
 
95
 
 
96
 
 
97
int Splitparts_set(struct SplitparT *o, int idx,
 
98
                   char *name, int partno, int total_parts,
 
99
                   off_t offset, off_t bytes, off_t total_bytes, int flag)
 
100
{
 
101
 if(o[idx].name!=NULL)
 
102
   free(o[idx].name);
 
103
 o[idx].name= strdup(name);
 
104
 if(o[idx].name==NULL)
 
105
   return(-1);
 
106
 o[idx].partno= partno;
 
107
 o[idx].total_parts= total_parts;
 
108
 o[idx].offset= offset;
 
109
 o[idx].bytes= bytes;
 
110
 o[idx].total_bytes= total_bytes;
 
111
 return(1);
 
112
}
 
113
 
 
114
 
 
115
int Splitparts_get(struct SplitparT *o, int idx, char **name, int *partno,
 
116
                   int *total_parts, off_t *offset, off_t *bytes,
 
117
                   off_t *total_bytes, int flag)
 
118
{
 
119
 *name= o[idx].name;
 
120
 *partno= o[idx].partno;
 
121
 *total_parts= o[idx].total_parts;
 
122
 *offset= o[idx].offset;
 
123
 *bytes= o[idx].bytes;
 
124
 *total_bytes= o[idx].total_bytes;
 
125
 return(1);
 
126
}
 
127
 
 
128
 
 
129
int Splitpart__read_next_num(char *base_pt, char **next_pt, off_t *num,
 
130
                             int flag)
 
131
{
 
132
 char *cpt, *ept, scale[4];
 
133
 double sfak;
 
134
 
 
135
 *num= 0;
 
136
 for(cpt= base_pt; *cpt!=0 && !isdigit(*cpt); cpt++);
 
137
 if(*cpt==0)
 
138
   return(0);
 
139
 for(ept= cpt; *ept!=0 && isdigit(*ept); ept++)
 
140
   *num= (*num)*10+(*ept)-'0';
 
141
 scale[0]= '1';
 
142
 scale[1]= *ept;
 
143
 scale[2]= 0;
 
144
 sfak= Scanf_io_size(scale, 0);
 
145
 *num *= (off_t) sfak;
 
146
 if(sfak > 1.0)
 
147
   ept++;
 
148
 *next_pt= ept;
 
149
 return(1);
 
150
}
 
151
 
 
152
 
 
153
int Splitpart__parse(char *name, int *partno, int *total_parts,
 
154
                    off_t *offset, off_t *bytes, off_t *total_bytes, int flag)
 
155
 
 
156
{
 
157
 int ret; 
 
158
 off_t num;
 
159
 char *cpt, *ept;
 
160
 
 
161
 cpt= name;
 
162
 if(strncmp(cpt, Splitpart_wordS[0], strlen(Splitpart_wordS[0])) != 0)
 
163
   return(0);
 
164
 ret= Splitpart__read_next_num(cpt, &ept, &num, 0);
 
165
 if(ret<=0)
 
166
   return(ret);
 
167
 *partno= num;
 
168
 cpt= ept;
 
169
 if(strncmp(cpt, Splitpart_wordS[1], strlen(Splitpart_wordS[1])) != 0)
 
170
   return(0);
 
171
 ret= Splitpart__read_next_num(cpt, &ept, &num, 0);
 
172
 if(ret<=0)
 
173
   return(ret);
 
174
 *total_parts= num;
 
175
 cpt= ept;
 
176
 if(strncmp(cpt, Splitpart_wordS[2], strlen(Splitpart_wordS[2])) != 0)
 
177
   return(0);
 
178
 ret= Splitpart__read_next_num(cpt, &ept, offset, 0);
 
179
 if(ret<=0)
 
180
   return(ret);
 
181
 cpt= ept;
 
182
 if(strncmp(cpt, Splitpart_wordS[3], strlen(Splitpart_wordS[3])) != 0)
 
183
   return(0);
 
184
 ret= Splitpart__read_next_num(cpt, &ept, bytes, 0);
 
185
 if(ret<=0)
 
186
   return(ret);
 
187
 cpt= ept;
 
188
 if(strncmp(cpt, Splitpart_wordS[4], strlen(Splitpart_wordS[4])) != 0)
 
189
   return(0);
 
190
 ret= Splitpart__read_next_num(cpt, &ept, total_bytes, 0);
 
191
 if(ret<=0)
 
192
   return(ret);
 
193
 if(*ept != 0)
 
194
   return(0);
 
195
 return(1);
 
196
}
 
197
 
 
198
 
 
199
int Splitpart__is_part_path(char *path, int flag)
 
200
{
 
201
 int partno, total_parts, ret;
 
202
 off_t offset, bytes, total_bytes;
 
203
 char *name;
 
204
 
 
205
 name= strrchr(path, '/');
 
206
 if(name == NULL)
 
207
   name= path;
 
208
 else
 
209
   name++;
 
210
 ret= Splitpart__parse(name, &partno, &total_parts, &offset, &bytes,
 
211
                       &total_bytes, 0);
 
212
 return(ret > 0);
 
213
}
 
214
 
 
215
 
 
216
/* part_#_of_#_at_#_with_#_of_#
 
217
*/
 
218
int Splitpart__compose(char *adr, int partno, int total_parts,
 
219
                       off_t offset, off_t bytes, off_t total_bytes, int flag)
 
220
{
 
221
 sprintf(adr, "%s%d%s%d%s", Splitpart_wordS[0], partno, Splitpart_wordS[1],
 
222
                            total_parts, Splitpart_wordS[2]);
 
223
 if((offset % (1024*1024))==0 && offset>0) {
 
224
   Sfile_off_t_text(adr+strlen(adr), offset / (1024*1024), 0);
 
225
   strcat(adr, "m");
 
226
 } else
 
227
   Sfile_off_t_text(adr+strlen(adr), offset, 0);
 
228
 strcat(adr, Splitpart_wordS[3]); 
 
229
 if((bytes % (1024*1024))==0) {
 
230
   Sfile_off_t_text(adr+strlen(adr), bytes / (1024*1024), 0);
 
231
   strcat(adr, "m");
 
232
 } else
 
233
   Sfile_off_t_text(adr+strlen(adr), bytes, 0);
 
234
 strcat(adr, Splitpart_wordS[4]);
 
235
 Sfile_off_t_text(adr+strlen(adr), total_bytes, 0);
 
236
 return(1);
 
237
}
 
238
 
 
239
 
 
240
int Splitparts_cmp(const void *v1, const void *v2)
 
241
{
 
242
 struct SplitparT *p1, *p2;
 
243
 
 
244
 p1= (struct SplitparT *) v1;
 
245
 p2= (struct SplitparT *) v2;
 
246
 
 
247
 if(p1->partno>p2->partno)
 
248
   return(1);
 
249
 if(p1->partno<p2->partno)
 
250
   return(-1);
 
251
 if(p1->offset>p2->offset)
 
252
   return(1);
 
253
 if(p1->offset<p2->offset)
 
254
   return(-1);
 
255
 return(0);
 
256
}
 
257
 
 
258
 
 
259
int Splitparts_sort(struct SplitparT *o, int count, int flag)
 
260
{
 
261
 qsort(o, (size_t) count, sizeof(struct SplitparT), Splitparts_cmp);
 
262
 return(1);
 
263
}
 
264
 
 
265
 
 
266
/* ---------------------------- End SplitparT ------------------------- */
 
267
 
 
268
 
 
269
/* ------------------------------ DirseQ  ------------------------------ */
 
270
 
 
271
 
 
272
static int Dirseq_buffer_sizE= 100;
 
273
 
 
274
struct DirseQ {
 
275
  char adr[SfileadrL];
 
276
  DIR *dirpt;
 
277
  int count;  
 
278
  char **buffer;
 
279
  int buffer_size;
 
280
  int buffer_fill;
 
281
  int buffer_rpt;
 
282
 
 
283
  struct DirseQ *next;
 
284
};
 
285
 
 
286
int Dirseq_destroy(struct DirseQ **o, int flag);
 
287
int Dirseq_next_adrblock(struct DirseQ *o, char *replies[], int *reply_count,
 
288
                         int max_replies, int flag);
 
289
 
 
290
 
 
291
int Dirseq_new(struct DirseQ **o, char *adr, int flag)
 
292
/*
 
293
 bit0= with non-fatal errors do not complain about failed opendir() 
 
294
*/
 
295
{
 
296
 int ret,i,severe_error;
 
297
 struct DirseQ *m;
 
298
 
 
299
 m= *o= TSOB_FELD(struct DirseQ,1);
 
300
 if(m==NULL)
 
301
   return(-1);
 
302
 m->adr[0]= 0;
 
303
 m->dirpt= NULL;
 
304
 m->count= 0;
 
305
 m->buffer= NULL;
 
306
 m->buffer_size= 0;
 
307
 m->buffer_fill= 0;
 
308
 m->buffer_rpt= 0;
 
309
 m->next= NULL;
 
310
 if(Sfile_str(m->adr, adr, 0)<=0)
 
311
   {ret= 0; goto failed;}
 
312
 m->buffer= TSOB_FELD(char *,Dirseq_buffer_sizE);
 
313
 if(m->buffer==NULL)
 
314
   {ret= -1; goto failed;}
 
315
 m->buffer_size= Dirseq_buffer_sizE;
 
316
 for(i= 0;i<m->buffer_size;i++)
 
317
   m->buffer[i]= NULL;
 
318
 if(adr[0]==0)
 
319
   m->dirpt= opendir(".");
 
320
 else
 
321
   m->dirpt= opendir(adr);
 
322
 if(m->dirpt==NULL) {
 
323
   severe_error= (errno && errno!=ENOENT && errno!=EACCES && errno!=ENOTDIR);
 
324
   if(severe_error || !(flag&1))
 
325
     fprintf(stderr,"opendir(%s) failed : %s\n",adr,strerror(errno));
 
326
   ret= -severe_error;
 
327
   goto failed;
 
328
 }
 
329
 return(1);
 
330
failed:;
 
331
 Dirseq_destroy(o,0);
 
332
 return(ret);
 
333
}
 
334
 
 
335
 
 
336
int Dirseq_destroy(struct DirseQ **o, int flag)
 
337
{
 
338
 int i;
 
339
 
 
340
 if(*o==NULL)
 
341
   return(0);
 
342
 if((*o)->dirpt!=NULL)
 
343
   closedir((*o)->dirpt);
 
344
 if((*o)->buffer!=NULL) {
 
345
   for(i=0;i<(*o)->buffer_size;i++)
 
346
     if((*o)->buffer[i]!=NULL)
 
347
       free((*o)->buffer[i]);
 
348
   free((char *) (*o)->buffer);
 
349
 }
 
350
 free((char *) *o);
 
351
 (*o)= NULL;
 
352
 return(1);
 
353
}
 
354
 
 
355
 
 
356
int Dirseq_set_next(struct DirseQ *o, struct DirseQ *next, int flag)
 
357
{
 
358
 o->next= next;
 
359
 return(1);
 
360
}
 
361
 
 
362
 
 
363
int Dirseq_get_next(struct DirseQ *o, struct DirseQ **next, int flag)
 
364
{
 
365
 *next= o->next;
 
366
 return(1);
 
367
}
 
368
 
 
369
 
 
370
int Dirseq_get_adr(struct DirseQ *o, char **adrpt, int flag)
 
371
{
 
372
 *adrpt= o->adr;
 
373
 return(1);
 
374
}
 
375
 
 
376
 
 
377
int Dirseq_rewind(struct DirseQ *o, int flag)
 
378
{
 
379
 rewinddir(o->dirpt);
 
380
 return(1);
 
381
}
 
382
 
 
383
 
 
384
int Dirseq_next_adr(struct DirseQ *o, char reply[SfileadrL], int flag)
 
385
/*
 
386
flag:
 
387
 bit0= permission to use buffer
 
388
 bit1= do not increment counter
 
389
 bit2= ignore buffer in any case
 
390
 bit3= do not exclude '.' and '..'
 
391
 bit4= sort buffer
 
392
 bit5= sort only incomplete last buffer
 
393
return:
 
394
 <0 error
 
395
 0= no more entries available
 
396
 1= ok, reply is valid
 
397
*/
 
398
{
 
399
 int ret;
 
400
 struct dirent *entry;
 
401
 char *name;
 
402
 
 
403
 static int override_flag_0= 0,override_flag_1= 32;
 
404
 flag= (flag&~override_flag_0)|override_flag_1;
 
405
 
 
406
 if((flag&1) && o->buffer_rpt>=o->buffer_fill) {
 
407
   /* permission to buffer and buffer empty : load a buffer */
 
408
   ret= Dirseq_next_adrblock(o,o->buffer,&(o->buffer_fill),
 
409
                             o->buffer_size,2|4|(flag&16));
 
410
   if(ret<=0)
 
411
     return(ret);
 
412
   o->buffer_rpt= 0;
 
413
   if((flag&32) && o->buffer_fill<o->buffer_size && o->buffer_fill>0) 
 
414
     Sort_argv(o->buffer_fill,o->buffer,0);
 
415
 }
 
416
 if(o->buffer_rpt<o->buffer_fill && !(flag&4)) {
 
417
   ret= Sfile_str(reply,o->buffer[o->buffer_rpt],0);
 
418
   Sregex_string(&(o->buffer[o->buffer_rpt]),NULL,0);
 
419
   if(ret<=0)
 
420
     return(-1);
 
421
   (o->buffer_rpt)++;
 
422
   if(!(flag&2))
 
423
     o->count++;
 
424
   return(1);
 
425
 }
 
426
 do {
 
427
   entry= readdir(o->dirpt);
 
428
   if(entry==NULL) {
 
429
     /* >>> how to distinguish error from EOF , do i need a (FILE *) ? */
 
430
     return(0);
 
431
   }
 
432
   if(strlen(entry->d_name)>=SfileadrL) {
 
433
     fprintf(stderr,"--- oversized directory entry (number %d) :\n    %s",
 
434
                    o->count+1,entry->d_name);
 
435
     return(-1);
 
436
   }
 
437
   name= entry->d_name;
 
438
   if(flag&8)
 
439
 break;
 
440
   /* skip "." and ".." */
 
441
 } while(name[0]=='.' && ((name[1]=='.' && name[2]==0) || name[1]==0));
 
442
 if(Sfile_str(reply,name,0)<=0)
 
443
   return(-1);
 
444
 if(!(flag&2))
 
445
   o->count++;
 
446
 return(1);
 
447
}
 
448
 
 
449
 
 
450
int Dirseq_next_adrblock(struct DirseQ *o, char *replies[], int *reply_count,
 
451
                         int max_replies, int flag)
 
452
/* @param replies A vector of Sregex_string pointers */
 
453
/*
 
454
flag:
 
455
 bit0= permission to use buffer
 
456
 bit1= do not increment counter
 
457
 bit2= ignore buffer in any case
 
458
 bit4= sort replies
 
459
return:
 
460
 <0 error
 
461
 0= no more entries available
 
462
 1= ok, reply is valid
 
463
*/
 
464
{
 
465
 int i,ret;
 
466
 char reply[SfileadrL];
 
467
 
 
468
 *reply_count= 0;
 
469
 for(i=0;i<max_replies;i++) {
 
470
   ret= Dirseq_next_adr(o,reply,flag&(1|2|4));
 
471
   if(ret<0)
 
472
     return(ret);
 
473
   if(ret==0)
 
474
 break;
 
475
   if(Sregex_string(&(replies[i]),reply,0)<=0)
 
476
     return(-1);
 
477
   (*reply_count)++;
 
478
 }
 
479
 if((*reply_count)==0)
 
480
   return(0);
 
481
 if(flag&16) 
 
482
   Sort_argv(*reply_count,replies,0);
 
483
 return(1);
 
484
}
 
485
 
 
486
 
 
487
/* ---------------------------- End DirseQ  ----------------------------- */
 
488
 
 
489
 
 
490
/* ---------------------------- Xorriso_lsT ----------------------------- */
 
491
 
 
492
 
 
493
/*
 
494
 @param flag Bitfield for control purposes
 
495
        bit0= insert before link rather than after it
 
496
        bit1= do not copy data (e.g. because *data is invalid)
 
497
        bit2= attach data directly by pointer rather than by copying
 
498
*/
 
499
int Xorriso_lst_new_binary(struct Xorriso_lsT **lstring, char *data,
 
500
                           int data_len, struct Xorriso_lsT *link, int flag)
 
501
{
 
502
 int ret;
 
503
 struct Xorriso_lsT *s;
 
504
 
 
505
 s= TSOB_FELD(struct Xorriso_lsT,1);
 
506
 if(s==NULL)
 
507
   return(-1);
 
508
 s->text= NULL;
 
509
 s->next= s->prev= NULL;
 
510
 
 
511
 if(flag & 4) {
 
512
   s->text= data;
 
513
 } else {
 
514
   if(data_len<=0)
 
515
     {ret= -1; goto failed;}
 
516
   s->text= Smem_malloC(data_len);
 
517
   if(s->text==NULL)
 
518
     {ret= -1; goto failed;}
 
519
   if(!(flag&2))
 
520
     memcpy(s->text,data,data_len);
 
521
 }
 
522
 
 
523
 if(link==NULL) {
 
524
   ;
 
525
 } else if(flag&1) {
 
526
   s->next= link;
 
527
   s->prev= link->prev;
 
528
   if(link->prev!=NULL) 
 
529
     link->prev->next= s;
 
530
   link->prev= s;
 
531
 } else {
 
532
   s->prev= link;
 
533
   s->next= link->next;
 
534
   if(link->next!=NULL) 
 
535
     link->next->prev= s;
 
536
   link->next= s;
 
537
 }
 
538
 *lstring= s;
 
539
 return(1);
 
540
failed:;
 
541
 *lstring= s;
 
542
 Xorriso_lst_destroy(lstring,0);
 
543
 return(-1);
 
544
}
 
545
 
 
546
 
 
547
/*
 
548
 @param flag Bitfield for control purposes
 
549
             see Xorriso_lst_new_binary()
 
550
*/
 
551
int Xorriso_lst_new(struct Xorriso_lsT **lstring, char *text,
 
552
                    struct Xorriso_lsT *link, int flag)
 
553
{
 
554
 int ret;
 
555
 
 
556
 ret= Xorriso_lst_new_binary(lstring,text,strlen(text)+1,link,flag);
 
557
 return(ret);
 
558
}
 
559
 
 
560
 
 
561
/*
 
562
 @param flag Bitfield for control purposes
 
563
             bit0= do not set *lstring to NULL
 
564
*/
 
565
int Xorriso_lst_destroy(struct Xorriso_lsT **lstring, int flag)
 
566
{
 
567
 struct Xorriso_lsT *s;
 
568
 
 
569
 s= *lstring;
 
570
 if(s==NULL)
 
571
   return(0);
 
572
 if(s->prev!=NULL)
 
573
   s->prev->next= s->next;
 
574
 if(s->next!=NULL)
 
575
   s->next->prev= s->prev;
 
576
 if(s->text!=NULL)
 
577
   Smem_freE(s->text);
 
578
 Smem_freE((char *) s);
 
579
 if(!(flag&1))
 
580
   *lstring= NULL;
 
581
 return(1);
 
582
}
 
583
 
 
584
 
 
585
int Xorriso_lst_destroy_all(struct Xorriso_lsT **lstring, int flag)
 
586
{
 
587
 struct Xorriso_lsT *s,*next;
 
588
 
 
589
 if(lstring==NULL)
 
590
   return(-1);
 
591
 if((*lstring)==NULL)
 
592
   return(0);
 
593
 for(s= *lstring; s->prev!=NULL; s= s->prev);
 
594
 for(;s!=NULL;s= next){
 
595
   next= s->next;
 
596
   Xorriso_lst_destroy(&s,0);
 
597
 }
 
598
 *lstring= NULL;
 
599
 return(1);
 
600
}
 
601
 
 
602
 
 
603
int Xorriso_lst_append_binary(struct Xorriso_lsT **entry,
 
604
                              char *data, int data_len, int flag)
 
605
{
 
606
 struct Xorriso_lsT *target= NULL,*newby;
 
607
 
 
608
 if(*entry!=NULL)
 
609
   for(target= *entry; target->next!=NULL; target= target->next);
 
610
 if(Xorriso_lst_new_binary(&newby, data, data_len, target, flag & ~1)<=0)
 
611
   return(-1);
 
612
 if(*entry==NULL || (flag & 1))
 
613
   *entry= newby;
 
614
 return(1);
 
615
}
 
616
 
 
617
 
 
618
struct Xorriso_lsT *Xorriso_lst_get_next(struct Xorriso_lsT *entry, int flag)
 
619
{
 
620
 return(entry->next);
 
621
}
 
622
 
 
623
 
 
624
struct Xorriso_lsT *Xorriso_lst_get_prev(struct Xorriso_lsT *entry, int flag)
 
625
{
 
626
 return(entry->prev);
 
627
}
 
628
 
 
629
 
 
630
char *Xorriso_lst_get_text(struct Xorriso_lsT *entry, int flag)
 
631
{
 
632
 return(entry->text);
 
633
}
 
634
 
 
635
 
 
636
int Xorriso_lst_detach_text(struct Xorriso_lsT *entry, int flag)
 
637
{
 
638
 entry->text= NULL;
 
639
 return(1);
 
640
}
 
641
 
 
642
 
 
643
int Xorriso_lst_get_last(struct Xorriso_lsT *entry, struct Xorriso_lsT **last,
 
644
                         int flag)
 
645
{
 
646
 *last= NULL;
 
647
 if(entry != NULL)
 
648
   for((*last)= entry; (*last)->next != NULL; (*last)= (*last)->next);
 
649
 return(1);
 
650
 
651
 
 
652
 
 
653
/* --------------------------- End Xorriso_lsT ---------------------------- */
 
654
 
 
655
 
 
656
/* ------------------------------ ExclusionS ------------------------------ */
 
657
 
 
658
 
 
659
struct ExclusionS {
 
660
 
 
661
 /* Absolute input patterns which lead to not_paths */
 
662
 struct Xorriso_lsT *not_paths_descr;
 
663
 
 
664
 /* Actually banned absolute paths */
 
665
 struct Xorriso_lsT *not_paths;
 
666
 
 
667
 /* Input patterns which lead to not_leafs */
 
668
 struct Xorriso_lsT *not_leafs_descr;
 
669
 
 
670
 /* Compiled not_leaf patterns. Caution: not char[] but  regex_t */
 
671
 struct Xorriso_lsT *not_leafs;
 
672
 
 
673
};
 
674
 
 
675
 
 
676
int Exclusions_new(struct ExclusionS **o, int flag)
 
677
{
 
678
 struct ExclusionS *m;
 
679
 
 
680
 m= *o= TSOB_FELD(struct ExclusionS, 1);
 
681
 if(m==NULL)
 
682
   return(-1);
 
683
 m->not_paths_descr= NULL;
 
684
 m->not_paths= NULL;
 
685
 m->not_leafs_descr= NULL;
 
686
 m->not_leafs= NULL;
 
687
 return(1);
 
688
}
 
689
 
 
690
 
 
691
int Exclusions_destroy(struct ExclusionS **o, int flag)
 
692
{
 
693
 struct Xorriso_lsT *s,*next;
 
694
 
 
695
 if((*o)==NULL)
 
696
   return(0);
 
697
 Xorriso_lst_destroy_all(&((*o)->not_paths_descr), 0);
 
698
 Xorriso_lst_destroy_all(&((*o)->not_paths), 0);
 
699
 Xorriso_lst_destroy_all(&((*o)->not_leafs_descr), 0);
 
700
 for(s= (*o)->not_leafs; s!=NULL; s= next){
 
701
   next= s->next;
 
702
   regfree((regex_t *) s->text);
 
703
   Xorriso_lst_destroy(&s, 0);
 
704
 }
 
705
 free((char *) *o);
 
706
 (*o)= NULL;
 
707
 return(1);
 
708
}
 
709
 
 
710
 
 
711
int Exclusions_add_not_paths(struct ExclusionS *o, int descrc, char **descrs,
 
712
                             int pathc, char **paths, int flag)
 
713
{
 
714
 struct Xorriso_lsT *s, *new_s;
 
715
 int i, ret;
 
716
 
 
717
 s= NULL;
 
718
 if(o->not_paths_descr!=NULL) 
 
719
   for(s= o->not_paths_descr; s->next!=NULL; s= s->next);
 
720
 for(i= 0; i<descrc; i++) {
 
721
   ret= Xorriso_lst_new(&new_s, descrs[i], s, 0);
 
722
   if(ret<=0)
 
723
     return(ret);
 
724
   if(o->not_paths_descr==NULL)
 
725
     o->not_paths_descr= new_s;
 
726
   s= new_s;
 
727
 }
 
728
 s= NULL;
 
729
 if(o->not_paths!=NULL) 
 
730
   for(s= o->not_paths; s->next!=NULL; s= s->next);
 
731
 for(i= 0; i<pathc; i++) {
 
732
   ret= Xorriso_lst_new(&new_s, paths[i], s, 0);
 
733
   if(ret<=0)
 
734
     return(ret);
 
735
   if(o->not_paths==NULL)
 
736
     o->not_paths= new_s;
 
737
   s= new_s;
 
738
 }
 
739
 return(1);
 
740
}
 
741
 
 
742
 
 
743
/* @return -1=cannot store , 0=cannot compile regex , 1=ok
 
744
*/
 
745
int Exclusions_add_not_leafs(struct ExclusionS *o, char *not_leafs_descr,
 
746
                             regex_t *re, int flag)
 
747
{
 
748
 int ret;
 
749
 
 
750
 ret= Xorriso_lst_append_binary(&(o->not_leafs_descr),
 
751
                            not_leafs_descr, strlen(not_leafs_descr)+1, 0);
 
752
 if(ret<=0)
 
753
   return(-1);
 
754
 ret= Xorriso_lst_append_binary(&(o->not_leafs), (char *) re, sizeof(regex_t), 0);
 
755
 if(ret<=0)
 
756
   return(-1);
 
757
 return(1);
 
758
}
 
759
 
 
760
 
 
761
/* @param flag bit0= whole subtree is banned with -not_paths 
 
762
   @return 0=no match , 1=not_paths , 2=not_leafs, <0=error
 
763
*/
 
764
int Exclusions_match(struct ExclusionS *o, char *abs_path, int flag)
 
765
{
 
766
 struct Xorriso_lsT *s;
 
767
 char leaf[SfileadrL], *leaf_pt;
 
768
 regmatch_t match[1];
 
769
 int ret, was_non_slash, l;
 
770
 
 
771
 /* test abs_paths */
 
772
 if(flag&1) {
 
773
   for(s= o->not_paths; s!=NULL; s= s->next) {
 
774
     l= strlen(s->text);
 
775
     if(strncmp(abs_path, s->text, l)==0)
 
776
       if(abs_path[l]=='/' || abs_path[l]==0)
 
777
         return(1);
 
778
   }
 
779
 } else {
 
780
   for(s= o->not_paths; s!=NULL; s= s->next)
 
781
     if(strcmp(abs_path, s->text)==0)
 
782
       return(1);
 
783
 }
 
784
 
 
785
 /* determine leafname */
 
786
 was_non_slash= 0;
 
787
 for(leaf_pt= abs_path+strlen(abs_path); leaf_pt >= abs_path; leaf_pt--) {
 
788
   if(*leaf_pt=='/') {
 
789
     if(was_non_slash) {
 
790
       leaf_pt++;
 
791
 break;
 
792
     }
 
793
   } else if(*leaf_pt!=0)
 
794
     was_non_slash= 1;
 
795
 }
 
796
 if(strlen(leaf_pt)>=SfileadrL)
 
797
   return(-1);
 
798
 strcpy(leaf, leaf_pt);
 
799
 leaf_pt= strchr(leaf, '/');
 
800
 if(leaf_pt!=NULL)
 
801
   *leaf_pt= 0;
 
802
 
 
803
 /* test with leaf expressions */
 
804
 for(s= o->not_leafs; s!=NULL; s= s->next) {
 
805
   ret= regexec((regex_t *) s->text, leaf, 1, match, 0);
 
806
   if(ret==0)
 
807
     return(2);
 
808
 }
 
809
 return(0);
 
810
}
 
811
 
 
812
 
 
813
int Exclusions_get_descrs(struct ExclusionS *o,
 
814
                          struct Xorriso_lsT **not_paths_descr,
 
815
                          struct Xorriso_lsT **not_leafs_descr, int flag)
 
816
{
 
817
 *not_paths_descr= o->not_paths_descr;
 
818
 *not_leafs_descr= o->not_leafs_descr;
 
819
 return(1);
 
820
}
 
821
 
 
822
/* ---------------------------- End ExclusionS ---------------------------- */
 
823
 
 
824
 
 
825
/* ------------------------------ LinkiteM -------------------------------- */
 
826
 
 
827
struct LinkiteM {
 
828
 char *link_path;
 
829
 dev_t target_dev;
 
830
 ino_t target_ino;
 
831
 int link_count;
 
832
 struct LinkiteM *next;
 
833
};
 
834
 
 
835
 
 
836
int Linkitem_new(struct LinkiteM **o, char *link_path, dev_t target_dev,
 
837
                 ino_t target_ino, struct LinkiteM *next, int flag)
 
838
{
 
839
 struct LinkiteM *m;
 
840
 
 
841
 m= *o= TSOB_FELD(struct LinkiteM,1);
 
842
 if(m==NULL)
 
843
   return(-1);
 
844
 m->target_dev= target_dev;
 
845
 m->target_ino= target_ino;
 
846
 m->next= next;
 
847
 m->link_count= 1;
 
848
 if(next!=NULL)
 
849
   m->link_count= m->next->link_count+1;
 
850
 m->link_path= strdup(link_path);
 
851
 if(m->link_path==NULL)
 
852
   goto failed;
 
853
 return(1);
 
854
failed:;
 
855
 Linkitem_destroy(o, 0);
 
856
 return(-1);
 
857
}
 
858
 
 
859
 
 
860
int Linkitem_destroy(struct LinkiteM **o, int flag)
 
861
{
 
862
 if((*o)==NULL)
 
863
   return(0);
 
864
 if((*o)->link_path!=NULL)
 
865
   free((*o)->link_path);
 
866
 free((char *) (*o));
 
867
 *o= NULL;
 
868
 return(1);
 
869
}
 
870
 
 
871
 
 
872
int Linkitem_reset_stack(struct LinkiteM **o, struct LinkiteM *to, int flag)
 
873
{
 
874
 struct LinkiteM *m, *m_next= NULL;
 
875
 
 
876
 /* Prevent memory corruption */
 
877
 for(m= *o;  m!=to; m= m->next)
 
878
   if(m==NULL) { /* this may actually not happen */
 
879
     *o= to;
 
880
     return(-1);
 
881
   }
 
882
 
 
883
 for(m= *o; m!=to; m= m_next) {
 
884
   m_next= m->next;
 
885
   Linkitem_destroy(&m, 0);
 
886
 }
 
887
 *o= to;
 
888
 return(1);
 
889
}
 
890
 
 
891
 
 
892
int Linkitem_find(struct LinkiteM *stack, dev_t target_dev, ino_t target_ino,
 
893
                  struct LinkiteM **result, int flag)
 
894
{
 
895
 struct LinkiteM *m;
 
896
 
 
897
 for(m= stack; m!=NULL; m= m->next) {
 
898
   if(target_dev == m->target_dev && target_ino == m->target_ino) {
 
899
     *result= m;
 
900
     return(1);
 
901
   }
 
902
 }
 
903
 return(0);
 
904
}
 
905
 
 
906
 
 
907
int Linkitem_get_link_count(struct LinkiteM *item, int flag)
 
908
{
 
909
 return(item->link_count);
 
910
}
 
911
 
 
912
 
 
913
/* ------------------------------ PermstacK ------------------------------- */
 
914
 
 
915
 
 
916
struct PermiteM {
 
917
 char *disk_path;
 
918
 struct stat stbuf;
 
919
 struct PermiteM *next;
 
920
};
 
921
 
 
922
 
 
923
int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf,
 
924
                   int flag)
 
925
{
 
926
 struct PermiteM *m;
 
927
 
 
928
 m= TSOB_FELD(struct PermiteM,1);
 
929
 if(m==NULL)
 
930
   return(-1);
 
931
 m->disk_path= NULL;
 
932
 memcpy(&(m->stbuf), stbuf, sizeof(struct stat));
 
933
 m->next= *o;
 
934
 
 
935
 m->disk_path= strdup(disk_path);
 
936
 if(m->disk_path==NULL)
 
937
   goto failed;
 
938
 
 
939
 *o= m;
 
940
 return(1);
 
941
failed:;
 
942
 if(m->disk_path!=NULL)
 
943
   free(m->disk_path);
 
944
 free((char *) m);
 
945
 return(-1);
 
946
}
 
947
 
 
948
 
 
949
/* @param flag bit0= minimal transfer: access permissions only
 
950
               bit1= do not set timestamps
 
951
*/ 
 
952
int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper,
 
953
                  struct XorrisO *xorriso, int flag)
 
954
{
 
955
 int ret;
 
956
 char sfe[5*SfileadrL];
 
957
 struct utimbuf utime_buffer;
 
958
 struct PermiteM *m, *m_next;
 
959
 
 
960
 if((*o)==stopper)
 
961
   return(1);
 
962
 for(m= *o; m!=NULL; m= m->next)
 
963
   if(m->next==stopper)
 
964
 break;
 
965
 if(m==NULL) {
 
966
   sprintf(xorriso->info_text,
 
967
           "Program error: Permstack_pop() : cannot find stopper");
 
968
   Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
 
969
   return(-1);
 
970
 }
 
971
 
 
972
 for(m= *o; m!=stopper; m= m_next) {
 
973
   ret= chmod(m->disk_path, m->stbuf.st_mode);
 
974
   if(ret==-1) {
 
975
     if(xorriso!=NULL) {
 
976
       sprintf(xorriso->info_text,
 
977
             "Cannot change access permissions of disk directory: chmod %o %s",
 
978
             (unsigned int) (m->stbuf.st_mode & 07777),
 
979
             Text_shellsafe(m->disk_path, sfe, 0));
 
980
       Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",
 
981
                           0);
 
982
     }
 
983
   }
 
984
   if(!(flag&1)) {
 
985
     ret= chown(m->disk_path, m->stbuf.st_uid, m->stbuf.st_gid);
 
986
                                               /* don't complain if it fails */
 
987
     if(!(flag&2)) {
 
988
       utime_buffer.actime= m->stbuf.st_atime;
 
989
       utime_buffer.modtime= m->stbuf.st_mtime;
 
990
       ret= utime(m->disk_path,&utime_buffer);
 
991
       if(ret==-1 && xorriso!=NULL) {
 
992
         sprintf(xorriso->info_text,
 
993
                 "Cannot change timestamps of disk directory: %s",
 
994
                 Text_shellsafe(m->disk_path, sfe, 0));
 
995
         Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",
 
996
                             0);
 
997
       }
 
998
     }
 
999
   }
 
1000
   m_next= m->next;
 
1001
   free(m->disk_path);
 
1002
   free((char *) m);
 
1003
   *o= m_next;
 
1004
 }
 
1005
 return(1);
 
1006
}
 
1007
 
 
1008
 
 
1009
/* ---------------------------- End PermstacK ----------------------------- */
 
1010