Splitted xorriso.c and xorrisoburn.c into smaller source modules

This commit is contained in:
Thomas Schmitt 2010-05-15 18:48:10 +00:00
parent a2b20e3ca2
commit 99e498057f
57 changed files with 37788 additions and 35879 deletions

View File

@ -50,8 +50,7 @@ bin_PROGRAMS = \
# cat xorriso/xorriso_buildstamp.h
xorriso_xorriso_CPPFLAGS = -Ilibisoburn
xorriso_xorriso_CFLAGS = -DXorriso_with_maiN \
$(READLINE_DEF) $(LIBACL_DEF) $(XATTR_DEF) \
xorriso_xorriso_CFLAGS = $(READLINE_DEF) $(LIBACL_DEF) $(XATTR_DEF) \
$(EXTF_DEF) $(EXTF_SUID_DEF) $(ZLIB_DEF) \
$(XORRISO_DVD_OBS_64K)
@ -61,9 +60,55 @@ xorriso_xorriso_LDADD = libisoburn/libisoburn.la -lisofs -lburn \
xorriso_xorriso_SOURCES = \
xorriso/xorriso.h \
xorriso/xorriso_private.h \
xorriso/xorriso.c \
xorriso/xorriso_main.c \
xorriso/sfile.h \
xorriso/sfile.c \
xorriso/aux_objects.h \
xorriso/aux_objects.c \
xorriso/findjob.h \
xorriso/findjob.c \
xorriso/check_media.h \
xorriso/check_media.c \
xorriso/misc_funct.h \
xorriso/misc_funct.c \
xorriso/text_io.h \
xorriso/text_io.c \
xorriso/match.h \
xorriso/match.c \
xorriso/emulators.h \
xorriso/emulators.c \
xorriso/disk_ops.h \
xorriso/disk_ops.c \
xorriso/cmp_update.h \
xorriso/cmp_update.c \
xorriso/parse_exec.h \
xorriso/parse_exec.c \
xorriso/opts_a_c.c \
xorriso/opts_d_h.c \
xorriso/opts_i_o.c \
xorriso/opts_p_z.c \
\
xorriso/xorrisoburn.h \
xorriso/xorrisoburn.c \
xorriso/base_obj.h \
xorriso/base_obj.c \
xorriso/lib_mgt.h \
xorriso/lib_mgt.c \
xorriso/sort_cmp.h \
xorriso/sort_cmp.c \
xorriso/drive_mgt.h \
xorriso/drive_mgt.c \
xorriso/iso_img.h \
xorriso/iso_img.c \
xorriso/iso_tree.h \
xorriso/iso_tree.c \
xorriso/iso_manip.h \
xorriso/iso_manip.c \
xorriso/write_run.h \
xorriso/write_run.c \
xorriso/read_run.h \
xorriso/read_run.c \
xorriso/filters.h \
xorriso/filters.c \
xorriso/xorriso_timestamp.h \
xorriso/xorriso_buildstamp.h

995
xorriso/aux_objects.c Normal file
View File

@ -0,0 +1,995 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2010 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
This file contains the implementations of classes:
- FindjoB, ExprnodE, ExprtesT which perform tree searches in
libisofs or in POSIX filesystem
- DirseQ which crawls along a directory's content list.
- ExclusionS which manages the list of excluded file paths and
leaf patterns.
- Xorriso_lsT which provides a generic double-linked list.
- LinkiteM, PermiteM which temporarily record relations and states.
*/
#include <ctype.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>
#include <utime.h>
#include <dirent.h>
#include <errno.h>
#include "xorriso.h"
#include "xorriso_private.h"
/* ---------------------------- SplitparT ------------------------- */
struct SplitparT {
char *name;
int partno;
int total_parts;
off_t offset;
off_t bytes;
off_t total_bytes;
};
static char Splitpart_wordS[][16]= {"part_", "_of_", "_at_", "_with_", "_of_"};
int Splitparts_new(struct SplitparT **o, int count, int flag)
{
int i;
(*o)= TSOB_FELD(struct SplitparT, count);
if((*o)==NULL)
return(-1);
for(i= 0; i<count; i++) {
(*o)[i].name= NULL;
(*o)[i].partno= 0;
(*o)[i].total_parts= 0;
(*o)[i].offset= 0;
(*o)[i].bytes= 0;
(*o)[i].total_bytes= 0;
}
return(1);
}
int Splitparts_destroy(struct SplitparT **o, int count, int flag)
{
int i;
if((*o)==NULL)
return(0);
for(i= 0; i<count; i++) {
if((*o)[i].name!=NULL)
free((*o)[i].name);
}
free(*o);
*o= NULL;
return(1);
}
int Splitparts_set(struct SplitparT *o, int idx,
char *name, int partno, int total_parts,
off_t offset, off_t bytes, off_t total_bytes, int flag)
{
if(o[idx].name!=NULL)
free(o[idx].name);
o[idx].name= strdup(name);
if(o[idx].name==NULL)
return(-1);
o[idx].partno= partno;
o[idx].total_parts= total_parts;
o[idx].offset= offset;
o[idx].bytes= bytes;
o[idx].total_bytes= total_bytes;
return(1);
}
int Splitparts_get(struct SplitparT *o, int idx, char **name, int *partno,
int *total_parts, off_t *offset, off_t *bytes,
off_t *total_bytes, int flag)
{
*name= o[idx].name;
*partno= o[idx].partno;
*total_parts= o[idx].total_parts;
*offset= o[idx].offset;
*bytes= o[idx].bytes;
*total_bytes= o[idx].total_bytes;
return(1);
}
int Splitpart__read_next_num(char *base_pt, char **next_pt, off_t *num,
int flag)
{
char *cpt, *ept, scale[4];
double sfak;
*num= 0;
for(cpt= base_pt; *cpt!=0 && !isdigit(*cpt); cpt++);
if(*cpt==0)
return(0);
for(ept= cpt; *ept!=0 && isdigit(*ept); ept++)
*num= (*num)*10+(*ept)-'0';
scale[0]= '1';
scale[1]= *ept;
scale[2]= 0;
sfak= Scanf_io_size(scale, 0);
*num *= (off_t) sfak;
if(sfak > 1.0)
ept++;
*next_pt= ept;
return(1);
}
int Splitpart__parse(char *name, int *partno, int *total_parts,
off_t *offset, off_t *bytes, off_t *total_bytes, int flag)
{
int ret;
off_t num;
char *cpt, *ept;
cpt= name;
if(strncmp(cpt, Splitpart_wordS[0], strlen(Splitpart_wordS[0])) != 0)
return(0);
ret= Splitpart__read_next_num(cpt, &ept, &num, 0);
if(ret<=0)
return(ret);
*partno= num;
cpt= ept;
if(strncmp(cpt, Splitpart_wordS[1], strlen(Splitpart_wordS[1])) != 0)
return(0);
ret= Splitpart__read_next_num(cpt, &ept, &num, 0);
if(ret<=0)
return(ret);
*total_parts= num;
cpt= ept;
if(strncmp(cpt, Splitpart_wordS[2], strlen(Splitpart_wordS[2])) != 0)
return(0);
ret= Splitpart__read_next_num(cpt, &ept, offset, 0);
if(ret<=0)
return(ret);
cpt= ept;
if(strncmp(cpt, Splitpart_wordS[3], strlen(Splitpart_wordS[3])) != 0)
return(0);
ret= Splitpart__read_next_num(cpt, &ept, bytes, 0);
if(ret<=0)
return(ret);
cpt= ept;
if(strncmp(cpt, Splitpart_wordS[4], strlen(Splitpart_wordS[4])) != 0)
return(0);
ret= Splitpart__read_next_num(cpt, &ept, total_bytes, 0);
if(ret<=0)
return(ret);
if(*ept != 0)
return(0);
return(1);
}
int Splitpart__is_part_path(char *path, int flag)
{
int partno, total_parts, ret;
off_t offset, bytes, total_bytes;
char *name;
name= strrchr(path, '/');
if(name == NULL)
name= path;
else
name++;
ret= Splitpart__parse(name, &partno, &total_parts, &offset, &bytes,
&total_bytes, 0);
return(ret > 0);
}
/* part_#_of_#_at_#_with_#_of_#
*/
int Splitpart__compose(char *adr, int partno, int total_parts,
off_t offset, off_t bytes, off_t total_bytes, int flag)
{
sprintf(adr, "%s%d%s%d%s", Splitpart_wordS[0], partno, Splitpart_wordS[1],
total_parts, Splitpart_wordS[2]);
if((offset % (1024*1024))==0 && offset>0) {
Sfile_off_t_text(adr+strlen(adr), offset / (1024*1024), 0);
strcat(adr, "m");
} else
Sfile_off_t_text(adr+strlen(adr), offset, 0);
strcat(adr, Splitpart_wordS[3]);
if((bytes % (1024*1024))==0) {
Sfile_off_t_text(adr+strlen(adr), bytes / (1024*1024), 0);
strcat(adr, "m");
} else
Sfile_off_t_text(adr+strlen(adr), bytes, 0);
strcat(adr, Splitpart_wordS[4]);
Sfile_off_t_text(adr+strlen(adr), total_bytes, 0);
return(1);
}
int Splitparts_cmp(const void *v1, const void *v2)
{
struct SplitparT *p1, *p2;
p1= (struct SplitparT *) v1;
p2= (struct SplitparT *) v2;
if(p1->partno>p2->partno)
return(1);
if(p1->partno<p2->partno)
return(-1);
if(p1->offset>p2->offset)
return(1);
if(p1->offset<p2->offset)
return(-1);
return(0);
}
int Splitparts_sort(struct SplitparT *o, int count, int flag)
{
qsort(o, (size_t) count, sizeof(struct SplitparT), Splitparts_cmp);
return(1);
}
/* ---------------------------- End SplitparT ------------------------- */
/* ------------------------------ DirseQ ------------------------------ */
static int Dirseq_buffer_sizE= 100;
struct DirseQ {
char adr[SfileadrL];
DIR *dirpt;
int count;
char **buffer;
int buffer_size;
int buffer_fill;
int buffer_rpt;
struct DirseQ *next;
};
int Dirseq_destroy(struct DirseQ **o, int flag);
int Dirseq_next_adrblock(struct DirseQ *o, char *replies[], int *reply_count,
int max_replies, int flag);
int Dirseq_new(struct DirseQ **o, char *adr, int flag)
/*
bit0= with non-fatal errors do not complain about failed opendir()
*/
{
int ret,i,severe_error;
struct DirseQ *m;
m= *o= TSOB_FELD(struct DirseQ,1);
if(m==NULL)
return(-1);
m->adr[0]= 0;
m->dirpt= NULL;
m->count= 0;
m->buffer= NULL;
m->buffer_size= 0;
m->buffer_fill= 0;
m->buffer_rpt= 0;
m->next= NULL;
if(Sfile_str(m->adr, adr, 0)<=0)
{ret= 0; goto failed;}
m->buffer= TSOB_FELD(char *,Dirseq_buffer_sizE);
if(m->buffer==NULL)
{ret= -1; goto failed;}
m->buffer_size= Dirseq_buffer_sizE;
for(i= 0;i<m->buffer_size;i++)
m->buffer[i]= NULL;
if(adr[0]==0)
m->dirpt= opendir(".");
else
m->dirpt= opendir(adr);
if(m->dirpt==NULL) {
severe_error= (errno && errno!=ENOENT && errno!=EACCES && errno!=ENOTDIR);
if(severe_error || !(flag&1))
fprintf(stderr,"opendir(%s) failed : %s\n",adr,strerror(errno));
ret= -severe_error;
goto failed;
}
return(1);
failed:;
Dirseq_destroy(o,0);
return(ret);
}
int Dirseq_destroy(struct DirseQ **o, int flag)
{
int i;
if(*o==NULL)
return(0);
if((*o)->dirpt!=NULL)
closedir((*o)->dirpt);
if((*o)->buffer!=NULL) {
for(i=0;i<(*o)->buffer_size;i++)
if((*o)->buffer[i]!=NULL)
free((*o)->buffer[i]);
free((char *) (*o)->buffer);
}
free((char *) *o);
(*o)= NULL;
return(1);
}
int Dirseq_set_next(struct DirseQ *o, struct DirseQ *next, int flag)
{
o->next= next;
return(1);
}
int Dirseq_get_next(struct DirseQ *o, struct DirseQ **next, int flag)
{
*next= o->next;
return(1);
}
int Dirseq_get_adr(struct DirseQ *o, char **adrpt, int flag)
{
*adrpt= o->adr;
return(1);
}
int Dirseq_rewind(struct DirseQ *o, int flag)
{
rewinddir(o->dirpt);
return(1);
}
int Dirseq_next_adr(struct DirseQ *o, char reply[SfileadrL], int flag)
/*
flag:
bit0= permission to use buffer
bit1= do not increment counter
bit2= ignore buffer in any case
bit3= do not exclude '.' and '..'
bit4= sort buffer
bit5= sort only incomplete last buffer
return:
<0 error
0= no more entries available
1= ok, reply is valid
*/
{
int ret;
struct dirent *entry;
char *name;
static int override_flag_0= 0,override_flag_1= 32;
flag= (flag&~override_flag_0)|override_flag_1;
if((flag&1) && o->buffer_rpt>=o->buffer_fill) {
/* permission to buffer and buffer empty : load a buffer */
ret= Dirseq_next_adrblock(o,o->buffer,&(o->buffer_fill),
o->buffer_size,2|4|(flag&16));
if(ret<=0)
return(ret);
o->buffer_rpt= 0;
if((flag&32) && o->buffer_fill<o->buffer_size && o->buffer_fill>0)
Sort_argv(o->buffer_fill,o->buffer,0);
}
if(o->buffer_rpt<o->buffer_fill && !(flag&4)) {
ret= Sfile_str(reply,o->buffer[o->buffer_rpt],0);
Sregex_string(&(o->buffer[o->buffer_rpt]),NULL,0);
if(ret<=0)
return(-1);
(o->buffer_rpt)++;
if(!(flag&2))
o->count++;
return(1);
}
do {
entry= readdir(o->dirpt);
if(entry==NULL) {
/* >>> how to distinguish error from EOF , do i need a (FILE *) ? */
return(0);
}
if(strlen(entry->d_name)>=SfileadrL) {
fprintf(stderr,"--- oversized directory entry (number %d) :\n %s",
o->count+1,entry->d_name);
return(-1);
}
name= entry->d_name;
if(flag&8)
break;
/* skip "." and ".." */
} while(name[0]=='.' && ((name[1]=='.' && name[2]==0) || name[1]==0));
if(Sfile_str(reply,name,0)<=0)
return(-1);
if(!(flag&2))
o->count++;
return(1);
}
int Dirseq_next_adrblock(struct DirseQ *o, char *replies[], int *reply_count,
int max_replies, int flag)
/* @param replies A vector of Sregex_string pointers */
/*
flag:
bit0= permission to use buffer
bit1= do not increment counter
bit2= ignore buffer in any case
bit4= sort replies
return:
<0 error
0= no more entries available
1= ok, reply is valid
*/
{
int i,ret;
char reply[SfileadrL];
*reply_count= 0;
for(i=0;i<max_replies;i++) {
ret= Dirseq_next_adr(o,reply,flag&(1|2|4));
if(ret<0)
return(ret);
if(ret==0)
break;
if(Sregex_string(&(replies[i]),reply,0)<=0)
return(-1);
(*reply_count)++;
}
if((*reply_count)==0)
return(0);
if(flag&16)
Sort_argv(*reply_count,replies,0);
return(1);
}
/* ---------------------------- End DirseQ ----------------------------- */
/* ---------------------------- Xorriso_lsT ----------------------------- */
/*
@param flag Bitfield for control purposes
bit0= insert before link rather than after it
bit1= do not copy data (e.g. because *data is invalid)
bit2= attach data directly by pointer rather than by copying
*/
int Xorriso_lst_new_binary(struct Xorriso_lsT **lstring, char *data,
int data_len, struct Xorriso_lsT *link, int flag)
{
int ret;
struct Xorriso_lsT *s;
s= TSOB_FELD(struct Xorriso_lsT,1);
if(s==NULL)
return(-1);
s->text= NULL;
s->next= s->prev= NULL;
if(flag & 4) {
s->text= data;
} else {
if(data_len<=0)
{ret= -1; goto failed;}
s->text= Smem_malloC(data_len);
if(s->text==NULL)
{ret= -1; goto failed;}
if(!(flag&2))
memcpy(s->text,data,data_len);
}
if(link==NULL) {
;
} else if(flag&1) {
s->next= link;
s->prev= link->prev;
if(link->prev!=NULL)
link->prev->next= s;
link->prev= s;
} else {
s->prev= link;
s->next= link->next;
if(link->next!=NULL)
link->next->prev= s;
link->next= s;
}
*lstring= s;
return(1);
failed:;
*lstring= s;
Xorriso_lst_destroy(lstring,0);
return(-1);
}
/*
@param flag Bitfield for control purposes
see Xorriso_lst_new_binary()
*/
int Xorriso_lst_new(struct Xorriso_lsT **lstring, char *text,
struct Xorriso_lsT *link, int flag)
{
int ret;
ret= Xorriso_lst_new_binary(lstring,text,strlen(text)+1,link,flag);
return(ret);
}
/*
@param flag Bitfield for control purposes
bit0= do not set *lstring to NULL
*/
int Xorriso_lst_destroy(struct Xorriso_lsT **lstring, int flag)
{
struct Xorriso_lsT *s;
s= *lstring;
if(s==NULL)
return(0);
if(s->prev!=NULL)
s->prev->next= s->next;
if(s->next!=NULL)
s->next->prev= s->prev;
if(s->text!=NULL)
Smem_freE(s->text);
Smem_freE((char *) s);
if(!(flag&1))
*lstring= NULL;
return(1);
}
int Xorriso_lst_destroy_all(struct Xorriso_lsT **lstring, int flag)
{
struct Xorriso_lsT *s,*next;
if(lstring==NULL)
return(-1);
if((*lstring)==NULL)
return(0);
for(s= *lstring; s->prev!=NULL; s= s->prev);
for(;s!=NULL;s= next){
next= s->next;
Xorriso_lst_destroy(&s,0);
}
*lstring= NULL;
return(1);
}
int Xorriso_lst_append_binary(struct Xorriso_lsT **entry,
char *data, int data_len, int flag)
{
struct Xorriso_lsT *target= NULL,*newby;
if(*entry!=NULL)
for(target= *entry; target->next!=NULL; target= target->next);
if(Xorriso_lst_new_binary(&newby, data, data_len, target, flag & ~1)<=0)
return(-1);
if(*entry==NULL || (flag & 1))
*entry= newby;
return(1);
}
struct Xorriso_lsT *Xorriso_lst_get_next(struct Xorriso_lsT *entry, int flag)
{
return(entry->next);
}
struct Xorriso_lsT *Xorriso_lst_get_prev(struct Xorriso_lsT *entry, int flag)
{
return(entry->prev);
}
char *Xorriso_lst_get_text(struct Xorriso_lsT *entry, int flag)
{
return(entry->text);
}
int Xorriso_lst_detach_text(struct Xorriso_lsT *entry, int flag)
{
entry->text= NULL;
return(1);
}
/* --------------------------- End Xorriso_lsT ---------------------------- */
/* ------------------------------ ExclusionS ------------------------------ */
struct ExclusionS {
/* Absolute input patterns which lead to not_paths */
struct Xorriso_lsT *not_paths_descr;
/* Actually banned absolute paths */
struct Xorriso_lsT *not_paths;
/* Input patterns which lead to not_leafs */
struct Xorriso_lsT *not_leafs_descr;
/* Compiled not_leaf patterns. Caution: not char[] but regex_t */
struct Xorriso_lsT *not_leafs;
};
int Exclusions_new(struct ExclusionS **o, int flag)
{
struct ExclusionS *m;
m= *o= TSOB_FELD(struct ExclusionS, 1);
if(m==NULL)
return(-1);
m->not_paths_descr= NULL;
m->not_paths= NULL;
m->not_leafs_descr= NULL;
m->not_leafs= NULL;
return(1);
}
int Exclusions_destroy(struct ExclusionS **o, int flag)
{
struct Xorriso_lsT *s,*next;
if((*o)==NULL)
return(0);
Xorriso_lst_destroy_all(&((*o)->not_paths_descr), 0);
Xorriso_lst_destroy_all(&((*o)->not_paths), 0);
Xorriso_lst_destroy_all(&((*o)->not_leafs_descr), 0);
for(s= (*o)->not_leafs; s!=NULL; s= next){
next= s->next;
regfree((regex_t *) s->text);
Xorriso_lst_destroy(&s, 0);
}
free((char *) *o);
(*o)= NULL;
return(1);
}
int Exclusions_add_not_paths(struct ExclusionS *o, int descrc, char **descrs,
int pathc, char **paths, int flag)
{
struct Xorriso_lsT *s, *new_s;
int i, ret;
s= NULL;
if(o->not_paths_descr!=NULL)
for(s= o->not_paths_descr; s->next!=NULL; s= s->next);
for(i= 0; i<descrc; i++) {
ret= Xorriso_lst_new(&new_s, descrs[i], s, 0);
if(ret<=0)
return(ret);
if(o->not_paths_descr==NULL)
o->not_paths_descr= new_s;
s= new_s;
}
s= NULL;
if(o->not_paths!=NULL)
for(s= o->not_paths; s->next!=NULL; s= s->next);
for(i= 0; i<pathc; i++) {
ret= Xorriso_lst_new(&new_s, paths[i], s, 0);
if(ret<=0)
return(ret);
if(o->not_paths==NULL)
o->not_paths= new_s;
s= new_s;
}
return(1);
}
/* @return -1=cannot store , 0=cannot compile regex , 1=ok
*/
int Exclusions_add_not_leafs(struct ExclusionS *o, char *not_leafs_descr,
regex_t *re, int flag)
{
int ret;
ret= Xorriso_lst_append_binary(&(o->not_leafs_descr),
not_leafs_descr, strlen(not_leafs_descr)+1, 0);
if(ret<=0)
return(-1);
ret= Xorriso_lst_append_binary(&(o->not_leafs), (char *) re, sizeof(regex_t), 0);
if(ret<=0)
return(-1);
return(1);
}
/* @param flag bit0= whole subtree is banned with -not_paths
@return 0=no match , 1=not_paths , 2=not_leafs, <0=error
*/
int Exclusions_match(struct ExclusionS *o, char *abs_path, int flag)
{
struct Xorriso_lsT *s;
char leaf[SfileadrL], *leaf_pt;
regmatch_t match[1];
int ret, was_non_slash, l;
/* test abs_paths */
if(flag&1) {
for(s= o->not_paths; s!=NULL; s= s->next) {
l= strlen(s->text);
if(strncmp(abs_path, s->text, l)==0)
if(abs_path[l]=='/' || abs_path[l]==0)
return(1);
}
} else {
for(s= o->not_paths; s!=NULL; s= s->next)
if(strcmp(abs_path, s->text)==0)
return(1);
}
/* determine leafname */
was_non_slash= 0;
for(leaf_pt= abs_path+strlen(abs_path); leaf_pt>abs_path; leaf_pt--) {
if(*leaf_pt=='/') {
if(was_non_slash) {
leaf_pt++;
break;
}
} else if(*leaf_pt!=0)
was_non_slash= 1;
}
if(strlen(leaf_pt)>=SfileadrL)
return(-1);
strcpy(leaf, leaf_pt);
leaf_pt= strchr(leaf, '/');
if(leaf_pt!=NULL)
*leaf_pt= 0;
/* test with leaf expressions */
for(s= o->not_leafs; s!=NULL; s= s->next) {
ret= regexec((regex_t *) s->text, leaf, 1, match, 0);
if(ret==0)
return(2);
}
return(0);
}
int Exclusions_get_descrs(struct ExclusionS *o,
struct Xorriso_lsT **not_paths_descr,
struct Xorriso_lsT **not_leafs_descr, int flag)
{
*not_paths_descr= o->not_paths_descr;
*not_leafs_descr= o->not_leafs_descr;
return(1);
}
/* ---------------------------- End ExclusionS ---------------------------- */
/* ------------------------------ LinkiteM -------------------------------- */
struct LinkiteM {
char *link_path;
dev_t target_dev;
ino_t target_ino;
int link_count;
struct LinkiteM *next;
};
int Linkitem_new(struct LinkiteM **o, char *link_path, dev_t target_dev,
ino_t target_ino, struct LinkiteM *next, int flag)
{
struct LinkiteM *m;
m= *o= TSOB_FELD(struct LinkiteM,1);
if(m==NULL)
return(-1);
m->target_dev= target_dev;
m->target_ino= target_ino;
m->next= next;
m->link_count= 1;
if(next!=NULL)
m->link_count= m->next->link_count+1;
m->link_path= strdup(link_path);
if(m->link_path==NULL)
goto failed;
return(1);
failed:;
Linkitem_destroy(o, 0);
return(-1);
}
int Linkitem_destroy(struct LinkiteM **o, int flag)
{
if((*o)==NULL)
return(0);
if((*o)->link_path!=NULL)
free((*o)->link_path);
free((char *) (*o));
*o= NULL;
return(1);
}
int Linkitem_reset_stack(struct LinkiteM **o, struct LinkiteM *to, int flag)
{
struct LinkiteM *m, *m_next= NULL;
/* Prevent memory corruption */
for(m= *o; m!=to; m= m->next)
if(m==NULL) { /* this may actually not happen */
*o= to;
return(-1);
}
for(m= *o; m!=to; m= m_next) {
m_next= m->next;
Linkitem_destroy(&m, 0);
}
*o= to;
return(1);
}
int Linkitem_find(struct LinkiteM *stack, dev_t target_dev, ino_t target_ino,
struct LinkiteM **result, int flag)
{
struct LinkiteM *m;
for(m= stack; m!=NULL; m= m->next) {
if(target_dev == m->target_dev && target_ino == m->target_ino) {
*result= m;
return(1);
}
}
return(0);
}
int Linkitem_get_link_count(struct LinkiteM *item, int flag)
{
return(item->link_count);
}
/* ------------------------------ PermstacK ------------------------------- */
struct PermiteM {
char *disk_path;
struct stat stbuf;
struct PermiteM *next;
};
int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf,
int flag)
{
struct PermiteM *m;
m= TSOB_FELD(struct PermiteM,1);
if(m==NULL)
return(-1);
m->disk_path= NULL;
memcpy(&(m->stbuf), stbuf, sizeof(struct stat));
m->next= *o;
m->disk_path= strdup(disk_path);
if(m->disk_path==NULL)
goto failed;
*o= m;
return(1);
failed:;
if(m->disk_path!=NULL)
free(m->disk_path);
free((char *) m);
return(-1);
}
/* @param flag bit0= minimal transfer: access permissions only
bit1= do not set timestamps
*/
int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper,
struct XorrisO *xorriso, int flag)
{
int ret;
char sfe[5*SfileadrL];
struct utimbuf utime_buffer;
struct PermiteM *m, *m_next;
if((*o)==stopper)
return(1);
for(m= *o; m!=NULL; m= m->next)
if(m->next==stopper)
break;
if(m==NULL) {
sprintf(xorriso->info_text,
"Program error: Permstack_pop() : cannot find stopper");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
return(-1);
}
for(m= *o; m!=stopper; m= m_next) {
ret= chmod(m->disk_path, m->stbuf.st_mode);
if(ret==-1) {
if(xorriso!=NULL) {
sprintf(xorriso->info_text,
"Cannot change access permissions of disk directory: chmod %o %s",
(unsigned int) (m->stbuf.st_mode & 07777),
Text_shellsafe(m->disk_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",
0);
}
}
if(!(flag&1)) {
chown(m->disk_path, m->stbuf.st_uid, m->stbuf.st_gid);
/* don't complain if it fails */
if(!(flag&2)) {
utime_buffer.actime= m->stbuf.st_atime;
utime_buffer.modtime= m->stbuf.st_mtime;
ret= utime(m->disk_path,&utime_buffer);
if(ret==-1 && xorriso!=NULL) {
sprintf(xorriso->info_text,
"Cannot change timestamps of disk directory: %s",
Text_shellsafe(m->disk_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",
0);
}
}
}
m_next= m->next;
free(m->disk_path);
free((char *) m);
*o= m_next;
}
return(1);
}
/* ---------------------------- End PermstacK ----------------------------- */

182
xorriso/aux_objects.h Normal file
View File

@ -0,0 +1,182 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2010 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
This file contains declarations of classes:
- FindjoB, ExprnodE, ExprtesT which perform tree searches in
libisofs or in POSIX filesystem
- DirseQ which crawls along a directory's content list.
- ExclusionS which manages the list of excluded file paths and
leaf patterns.
- Xorriso_lsT which provides a generic double-linked list.
- LinkiteM, PermiteM which temporarily record relations and states.
*/
#ifndef Xorriso_pvt_auxobj_includeD
#define Xorriso_pvt_auxobj_includeD yes
struct SplitparT;
int Splitparts_new(struct SplitparT **o, int count, int flag);
int Splitparts_destroy(struct SplitparT **o, int count, int flag);
int Splitparts_set(struct SplitparT *o, int idx,
char *name, int partno, int total_parts,
off_t offset, off_t bytes, off_t total_bytes, int flag);
int Splitparts_get(struct SplitparT *o, int idx, char **name, int *partno,
int *total_parts, off_t *offset, off_t *bytes,
off_t *total_bytes, int flag);
int Splitpart__parse(char *name, int *partno, int *total_parts,
off_t *offset, off_t *bytes, off_t *total_bytes, int flag);
int Splitpart__is_part_path(char *path, int flag);
int Splitpart__compose(char *adr, int partno, int total_parts,
off_t offset, off_t bytes, off_t total_bytes, int flag);
int Splitpart__read_next_num(char *base_pt, char **next_pt, off_t *num,
int flag);
int Splitparts_sort(struct SplitparT *o, int count, int flag);
struct DirseQ;
int Dirseq_new(struct DirseQ **o, char *adr, int flag);
int Dirseq_destroy(struct DirseQ **o, int flag);
int Dirseq_next_adr(struct DirseQ *o, char reply[SfileadrL], int flag);
int Dirseq_rewind(struct DirseQ *o, int flag);
struct Xorriso_lsT {
char *text;
struct Xorriso_lsT *prev,*next;
};
/** Create a new list item with arbitrary byte content.
@param lstring The newly created object or NULL on failure
@param data An array of bytes to be copied into the new object
@param data_len Number of bytes to be copied
@param link Xorriso_lsT object to which the new object shall be linked
@param flag Bitfield for control purposes
bit0= insert before link rather than after it
bit1= do not copy data (e.g. because *data is invalid)
bit2= attach data directly by pointer rather than by copying
@return <=0 error, 1 ok
*/
int Xorriso_lst_new_binary(struct Xorriso_lsT **lstring, char *data,
int data_len, struct Xorriso_lsT *link, int flag);
/** Create a new list item with a 0-terminated text as content.
@param lstring The newly created object or NULL on failure
@param text A 0-terminated array of bytes
@param link Xorriso_lsT object to which the new object shall be linked
@param flag see Xorriso_lst_new_binary
@return <=0 error, 1 ok
*/
int Xorriso_lst_new(struct Xorriso_lsT **lstring, char *text,
struct Xorriso_lsT *link, int flag);
/** Create a new list item at the end of a given list.
@param entry Contains as input a pointer to a pointer to any existing
list item. As output this list item pointer may be
changed to the address of the new list item:
if ((*entry == 0) || (flag & 1))
@param data An array of bytes to be copied into the new object
@param data_len Number of bytes to be copied
@param flag Bitfield for control purposes
bit0= Return new object address in *entry
bit1= do not copy data (e.g. because *data is invalid)
bit2= attach data directly by pointer rather than by copying
bit2= attach data directly by pointer rather than by copying
@return <=0 error, 1 ok
*/
int Xorriso_lst_append_binary(struct Xorriso_lsT **entry,
char *data, int data_len, int flag);
/** Destroy a single list item and connect its eventual list neighbors.
@param lstring pointer to the pointer to be freed and set to NULL
@param flag unused yet, submit 0
@return 0= *lstring was alredy NULL, 1= ok
*/
int Xorriso_lst_destroy(struct Xorriso_lsT **lstring, int flag);
struct Xorriso_lsT *Xorriso_lst_get_next(struct Xorriso_lsT *entry, int flag);
struct Xorriso_lsT *Xorriso_lst_get_prev(struct Xorriso_lsT *entry, int flag);
char *Xorriso_lst_get_text(struct Xorriso_lsT *entry, int flag);
int Xorriso_lst_detach_text(struct Xorriso_lsT *entry, int flag);
int Exclusions_new(struct ExclusionS **o, int flag);
int Exclusions_destroy(struct ExclusionS **o, int flag);
int Exclusions_get_descrs(struct ExclusionS *o,
struct Xorriso_lsT **not_paths_descr,
struct Xorriso_lsT **not_leafs_descr, int flag);
/* @param flag bit0= whole subtree is banned with -not_paths
@return 0=no match , 1=not_paths , 2=not_leafs, <0=error
*/
int Exclusions_match(struct ExclusionS *o, char *abs_path, int flag);
int Exclusions_add_not_leafs(struct ExclusionS *o, char *not_leafs_descr,
regex_t *re, int flag);
int Exclusions_add_not_paths(struct ExclusionS *o, int descrc, char **descrs,
int pathc, char **paths, int flag);
struct LinkiteM; /* Trace of hops during symbolic link resolution */
int Linkitem_new(struct LinkiteM **o, char *link_path, dev_t target_dev,
ino_t target_ino, struct LinkiteM *next, int flag);
int Linkitem_destroy(struct LinkiteM **o, int flag);
int Linkitem_reset_stack(struct LinkiteM **o, struct LinkiteM *to, int flag);
int Linkitem_find(struct LinkiteM *stack, dev_t target_dev, ino_t target_ino,
struct LinkiteM **result, int flag);
int Linkitem_get_link_count(struct LinkiteM *item, int flag);
struct PermiteM; /* Stack of temporarily altered access permissions */
int Permstack_push(struct PermiteM **o, char *disk_path, struct stat *stbuf,
int flag);
int Permstack_pop(struct PermiteM **o, struct PermiteM *stopper,
struct XorrisO *xorriso, int flag);
#endif /* ! Xorriso_pvt_auxobj_includeD */

537
xorriso/base_obj.c Normal file
View File

@ -0,0 +1,537 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2010 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
This file contains functions which are needed to read data
from ISO image.
*/
#include <ctype.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include "xorriso.h"
#include "xorriso_private.h"
#include "base_obj.h"
#include "lib_mgt.h"
/* See Xorriso__preset_signal_behavior() */
static int Xorriso_signal_behavioR= 1;
char *Xorriso__get_version_text(int flag)
{
return(Xorriso_program_versioN);
}
char *Xorriso__get_patch_level_text(int flag)
{
return(Xorriso_program_patch_leveL);
}
/** The list of startup file names */
#define Xorriso_rc_nuM 4
static char Xorriso_sys_rc_nameS[Xorriso_rc_nuM][80]= {
"/etc/default/xorriso",
"/etc/opt/xorriso/rc",
"/etc/xorriso/xorriso.conf",
"placeholder for $HOME/.xorrisorc"
};
int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
{
int i, ret;
struct XorrisO *m;
char leafname[SfileadrL];
*xorriso= m= TSOB_FELD(struct XorrisO,1);
if(m==NULL)
return(-1);
m->libs_are_started= 0;
strncpy(m->progname,progname,sizeof(m->progname)-1);
m->progname[sizeof(m->progname)-1]= 0;
if(getcwd(m->initial_wdx,sizeof(m->initial_wdx)-1)==NULL)
m->initial_wdx[0]= 0;
m->no_rc= 0;
m->argument_emulation= 0;
m->rc_filename_count= Xorriso_rc_nuM;
for(i=0;i<m->rc_filename_count-1;i++)
strcpy(m->rc_filenames[i],Xorriso_sys_rc_nameS[i]);
m->rc_filenames[m->rc_filename_count-1][0]= 0;
m->wdi[0]= 0;
strcpy(m->wdx, m->initial_wdx);
m->did_something_useful= 0;
m->add_plainly= 0;
m->split_size= 0;
strcpy(m->list_delimiter, "--");
m->ino_behavior= 7;
m->do_joliet= 0;
m->do_aaip= 0;
m->do_md5= 0;
m->scdbackup_tag_name[0]= 0;
m->scdbackup_tag_time[0]= 0;
m->scdbackup_tag_written[0]= 0;
m->scdbackup_tag_listname[0]= 0;
m->relax_compliance= 0;
m->do_follow_pattern= 1;
m->do_follow_param= 0;
m->do_follow_links= 0;
m->follow_link_limit= 100;
m->do_follow_mount= 1;
m->do_global_uid= 0;
m->global_uid= 0;
strcpy(m->volid, "ISOIMAGE");
m->volid_default= 1;
m->loaded_volid[0]= 0;
m->assert_volid[0]= 0;
m->assert_volid_sev[0]= 0;
m->publisher[0]= 0;
m->application_id[0]= 0;
m->system_id[0]= 0;
m->volset_id[0]= 0;
m->session_logfile[0]= 0;
m->session_lba= -1;
m->session_blocks= 0;
m->do_global_gid= 0;
m->global_gid= 0;
m->do_global_mode= 0;
m->global_dir_mode= 0555;
m->global_file_mode= 0444;
m->filters= NULL;
m->filter_list_closed= 0;
m->zlib_level_default= m->zlib_level= 6;
m->zisofs_block_size= m->zisofs_block_size_default= (1 << 15);
m->zisofs_by_magic= 0;
m->do_overwrite= 2;
m->do_reassure= 0;
m->drive_blacklist= NULL;
m->drive_greylist= NULL;
m->drive_whitelist= NULL;
m->toc_emulation_flag= 0;
m->image_start_mode= 0;
m->image_start_value[0]= 0;
m->drives_exclusive= 1;
m->do_calm_drive= 1;
m->indev[0]= 0;
m->in_drive_handle= NULL;
m->in_volset_handle= NULL;
m->in_charset= NULL;
m->isofs_st_out= time(0) - 1;
m->indev_is_exclusive= 1;
m->isofs_st_in= 0;
m->volset_change_pending= 0;
m->no_volset_present= 0;
m->in_sector_map= NULL;
m->check_media_default= NULL;
m->check_media_bad_limit= Xorriso_read_quality_invaliD;
m->outdev[0]= 0;
m->out_drive_handle= NULL;
m->out_charset= NULL;
m->dev_fd_1= -1;
m->outdev_is_exclusive= 1;
m->grow_blindly_msc2= -1;
m->ban_stdio_write= 0;
m->do_dummy= 0;
m->do_close= 0;
m->speed= 0;
m->fs= 4*512; /* 4 MiB */
m->padding= 300*1024;
m->alignment= 0;
m->do_stream_recording= 0;
m->dvd_obs= 0;
m->stdio_sync= 0;
m->keep_boot_image= 0;
m->boot_image_cat_path[0]= 0;
m->boot_count= 0;
m->boot_platform_id= 0x00; /* El Torito Boot Catalog Platform ID: 0 = 80x86 */
m->patch_isolinux_image= 0;
m->boot_image_bin_path[0]= 0;
m->boot_image_bin_form[0]= 0;
m->boot_image_emul= 0;
m->boot_image_load_size= 4 * 512; /* hearsay out of libisofs/demo/iso.c */
memset(m->boot_id_string, 0, sizeof(m->boot_id_string));
memset(m->boot_selection_crit, 0, sizeof(m->boot_selection_crit));
#ifdef Xorriso_with_isohybriD
m->boot_image_isohybrid= 1;
#else
m->boot_image_isohybrid= 0;
#endif
m->boot_efi_default= 0;
m->system_area_disk_path[0]= 0;
m->system_area_options= 0;
m->patch_system_area= 0;
m->vol_creation_time= 0;
m->vol_modification_time= 0;
m->vol_expiration_time= 0;
m->vol_effective_time= 0;
m->vol_uuid[0]= 0;
m->loaded_boot_bin_lba= 0;
m->loaded_boot_cat_path[0]= 0;
m->allow_graft_points= 0;
m->allow_restore= 0;
m->do_concat_split= 1;
m->do_auto_chmod= 0;
m->do_restore_sort_lba= 0;
m->dialog= 0;
m->bsl_interpretation= 0;
m->search_mode= 0;
m->structured_search= 1;
m->do_iso_rr_pattern= 1;
m->do_disk_pattern= 2;
m->temp_mem_limit= 16*1024*1024;
m->file_size_limit= Xorriso_default_file_size_limiT;
m->disk_exclusions= NULL;
m->disk_excl_mode= 1;
m->use_stdin= 0;
m->result_page_length= 0;
m->result_page_width= 80;
m->mark_text[0]= 0;
m->packet_output= 0;
for(i=0; i<4; i++) {
m->logfile[i][0]= 0;
m->logfile_fp[i]= NULL;
}
m->pktlog_fp= NULL;
for(i= 0; i < Xorriso_max_outlist_stacK; i++) {
m->result_msglists[i]= NULL;
m->info_msglists[i]= NULL;
m->msglist_flags[i]= 0;
}
m->msglist_stackfill= 0;
m->status_history_max= Xorriso_status_history_maX;
m->scsi_log= 0;
strcpy(m->report_about_text, "UPDATE");
Xorriso__text_to_sev(m->report_about_text, &m->report_about_severity, 0);
m->library_msg_direct_print= 0;
strcpy(m->abort_on_text,"FATAL");
Xorriso__text_to_sev(m->abort_on_text, &m->abort_on_severity, 0);
m->problem_status= 0;
m->problem_status_text[0]