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 # cat xorriso/xorriso_buildstamp.h
xorriso_xorriso_CPPFLAGS = -Ilibisoburn xorriso_xorriso_CPPFLAGS = -Ilibisoburn
xorriso_xorriso_CFLAGS = -DXorriso_with_maiN \ xorriso_xorriso_CFLAGS = $(READLINE_DEF) $(LIBACL_DEF) $(XATTR_DEF) \
$(READLINE_DEF) $(LIBACL_DEF) $(XATTR_DEF) \
$(EXTF_DEF) $(EXTF_SUID_DEF) $(ZLIB_DEF) \ $(EXTF_DEF) $(EXTF_SUID_DEF) $(ZLIB_DEF) \
$(XORRISO_DVD_OBS_64K) $(XORRISO_DVD_OBS_64K)
@ -61,9 +60,55 @@ xorriso_xorriso_LDADD = libisoburn/libisoburn.la -lisofs -lburn \
xorriso_xorriso_SOURCES = \ xorriso_xorriso_SOURCES = \
xorriso/xorriso.h \ xorriso/xorriso.h \
xorriso/xorriso_private.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.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_timestamp.h \
xorriso/xorriso_buildstamp.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]= 0;
m->errfile_log[0]= 0;
m->errfile_mode= 0;
m->errfile_fp= NULL;
m->img_read_error_mode= 2; /* abort faulty image reading with FATAL */
m->extract_error_mode= 1; /* keep extracted files after read error */
strcpy(m->return_with_text, "SORRY");
Xorriso__text_to_sev(m->return_with_text, &m->return_with_severity, 0);
m->return_with_value= 32;
m->eternal_problem_status= 0;
m->eternal_problem_status_text[0]= 0;
m->re= NULL;
/* >>> ??? how to initialize m->match[0] ? */
m->re_constants= NULL;
m->re_count= 0;
m->re_fill= 0;
m->reg_expr[0]= 0;
m->run_state= 0;
m->is_dialog= 0;
m->bar_is_fresh= 0;
m->pending_option[0]= 0;
m->request_to_abort= 0;
m->request_not_to_ask= 0;
m->idle_time= 0.0;
m->re_failed_at= -1;
m->prepended_wd= 0;
m->insert_count= 0;
m->insert_bytes= 0;
m->error_count= 0;
m->pacifier_style= 0;
m->pacifier_interval= 1.0;
m->pacifier_count= 0;
m->pacifier_total= 0;
m->pacifier_byte_count= 0;
m->pacifier_fifo= NULL;
m->start_time= 0.0;
m->last_update_time= 0.0;
m->find_compare_result= 1;
m->find_check_md5_result= 0;
m->node_counter= 0;
m->node_array_size= 0;
m->node_array= NULL;
m->node_disk_prefixes= NULL;
m->node_img_prefixes= NULL;
m->hln_count= 0;
m->hln_array= NULL;
m->hln_targets= NULL;
m->hln_change_pending= 0;
m->di_do_widen= NULL;
m->di_disk_paths= NULL;
m->di_iso_paths= NULL;
m->node_targets_availmem= 0;
m->di_count= 0;
m->di_array= NULL;
m->perm_stack= NULL;
m->result_line[0]= 0;
m->result_line_counter= 0;
m->result_page_counter= 0;
m->result_open_line_len= 0;
m->info_text[0]= 0;
ret= Sfile_leafname(progname, leafname, 0);
if(ret<=0)
goto failure;
if(strcmp(leafname, "osirrox")==0) {
m->allow_restore= 1;
m->drives_exclusive= 0;
} else if(strcmp(leafname, "xorrisofs")==0 || strcmp(leafname, "genisofs")==0 ||
strcmp(leafname, "mkisofs")==0 || strcmp(leafname, "genisoimage")==0) {
m->argument_emulation= 1;
m->pacifier_style= 1;
Xorriso_protect_stdout(*xorriso, 0);
} else if(strcmp(leafname, "xorrecord")==0 || strcmp(leafname, "wodim")==0 ||
strcmp(leafname, "cdrecord")==0 || strcmp(leafname, "cdrskin")==0) {
m->argument_emulation= 2;
m->pacifier_style= 2;
}
ret= Exclusions_new(&(m->disk_exclusions), 0);
if(ret<=0)
goto failure;
Xorriso_relax_compliance(m, "default", 0);
ret= Xorriso_lst_new(&(m->drive_greylist), "/dev", m->drive_greylist, 1);
if(ret <= 0)
goto failure;
return(1);
failure:;
Xorriso_destroy(xorriso, 0);
return(-1);
}
int Xorriso_destroy_re(struct XorrisO *m, int flag)
{
int i;
if(m->re!=NULL) {
for(i=0;i<m->re_fill;i++) {
if(m->re_constants!=NULL)
if(m->re_constants[i]!=NULL)
continue; /* ,->re[i] was never subject to regcomp() */
regfree(&(m->re[i]));
}
free((char *) m->re);
m->re= NULL;
}
if(m->re_constants!=NULL) {
for(i=0;i<m->re_fill;i++)
if(m->re_constants[i]!=NULL)
free(m->re_constants[i]);
free((char *) m->re_constants);
m->re_constants= NULL;
}
m->re_count= 0;
m->re_fill= 0;
return(1);
}
/* @param flag bit0= global shutdown of libraries */
int Xorriso_destroy(struct XorrisO **xorriso, int flag)
{
struct XorrisO *m;
m= *xorriso;
if(m==NULL)
return(0);
if(m->in_charset!=NULL)
free(m->in_charset);
if(m->out_charset!=NULL)
free(m->out_charset);
Xorriso_destroy_re(m,0);
Exclusions_destroy(&(m->disk_exclusions), 0);
Xorriso_destroy_all_extf(m, 0);
Xorriso_lst_destroy_all(&(m->drive_blacklist), 0);
Xorriso_lst_destroy_all(&(m->drive_greylist), 0);
Xorriso_lst_destroy_all(&(m->drive_whitelist), 0);
Xorriso_destroy_node_array(m, 0);
Xorriso_destroy_hln_array(m, 0);
Xorriso_destroy_di_array(m, 0);
Xorriso_detach_libraries(m, flag&1);
free((char *) m);
*xorriso= NULL;
return(1);
}
int Xorriso_destroy_node_array(struct XorrisO *xorriso, int flag)
{
int i;
if(xorriso->node_array != NULL) {
for(i= 0; i < xorriso->node_counter; i++)
iso_node_unref((IsoNode *) xorriso->node_array[i]);
free(xorriso->node_array);
}
xorriso->node_array= NULL;
xorriso->node_counter= xorriso->node_array_size= 0;
Xorriso_lst_destroy_all(&(xorriso->node_disk_prefixes), 0);
Xorriso_lst_destroy_all(&(xorriso->node_img_prefixes), 0);
return(1);
}
/* @param flag bit0= do not destroy hln_array but only hln_targets
*/
int Xorriso_destroy_hln_array(struct XorrisO *xorriso, int flag)
{
int i;
if(xorriso->hln_array != NULL && !(flag & 1)) {
for(i= 0; i < xorriso->hln_count; i++)
iso_node_unref((IsoNode *) xorriso->hln_array[i]);
free(xorriso->hln_array);
xorriso->hln_array= NULL;
xorriso->hln_count= 0;
}
if(xorriso->hln_targets != NULL) {
for(i= 0; i < xorriso->hln_count; i++)
if(xorriso->hln_targets[i] != NULL)
free(xorriso->hln_targets[i]);
free(xorriso->hln_targets);
xorriso->hln_targets= NULL;
}
xorriso->node_targets_availmem= 0;
return(1);
}
int Xorriso_destroy_di_array(struct XorrisO *xorriso, int flag)
{
int i;
if(xorriso->di_array != NULL) {
for(i= 0; i < xorriso->di_count; i++)
if(xorriso->di_array[i] != NULL)
iso_node_unref((IsoNode *) xorriso->di_array[i]);
free(xorriso->di_array);
xorriso->di_array= NULL;
}
if(xorriso->di_do_widen != NULL) {
free(xorriso->di_do_widen);
xorriso->di_do_widen= NULL;
}
Xorriso_lst_destroy_all(&(xorriso->di_disk_paths), 0);
Xorriso_lst_destroy_all(&(xorriso->di_iso_paths), 0);
xorriso->di_count= 0;
#ifdef NIX
/* <<< */
fprintf(stderr, "xorriso_DEBUG: get_di_count= %lu\n",
Xorriso_get_di_counteR);
#endif /* NIX */
return(1);
}
int Xorriso_new_node_array(struct XorrisO *xorriso, off_t mem_limit,
int addon_nodes, int flag)
{
int i;
if(xorriso->node_counter <= 0)
return(1);
xorriso->node_array= calloc(xorriso->node_counter + addon_nodes,
sizeof(IsoNode *));
if(xorriso->node_array == NULL) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
return(-1);
}
for(i= 0; i < xorriso->node_counter + addon_nodes; i++)
xorriso->node_array[i]= NULL;
xorriso->node_array_size= xorriso->node_counter + addon_nodes;
xorriso->node_counter= 0;
return(1);
}
/* @param flag bit0= do not allocate hln_array but only hln_targets
*/
int Xorriso_new_hln_array(struct XorrisO *xorriso, off_t mem_limit, int flag)
{
int i;
Xorriso_destroy_hln_array(xorriso, flag & 1);
if(xorriso->hln_count <= 0)
return(1);
if(!(flag & 1)) {
xorriso->hln_array= calloc(xorriso->hln_count, sizeof(char *));
if(xorriso->hln_array == NULL) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
return(-1);
}
for(i= 0; i < xorriso->hln_count; i++)
xorriso->hln_array[i]= NULL;
}
xorriso->hln_targets= calloc(xorriso->hln_count, sizeof(char *));
if(xorriso->hln_targets == NULL) {
if(!(flag & 1)) {
free(xorriso->hln_array);
xorriso->hln_array= NULL;
}
Xorriso_no_malloc_memory(xorriso, NULL, 0);
return(-1);
}
for(i= 0; i < xorriso->hln_count; i++)
xorriso->hln_targets[i]= NULL;
xorriso->node_targets_availmem= mem_limit
- xorriso->hln_count * sizeof(void *)
- xorriso->hln_count * sizeof(char *);
if(xorriso->node_targets_availmem < 0)
xorriso->node_targets_availmem= 0;
return(1);
}
int Xorriso__preset_signal_behavior(int behavior, int flag)
{
if(behavior < 0 || behavior > 1)
return(0);
Xorriso_signal_behavioR= behavior;
return(1);
}
int Xorriso__get_signal_behavior(int flag)
{
return(Xorriso_signal_behavioR);
}

31
xorriso/base_obj.h Normal file
View File

@ -0,0 +1,31 @@
/* 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 functions which perform the
fundamental operations of the XorrisO object.
*/
#ifndef Xorriso_pvt_base_obj_includeD
#define Xorriso_pvt_base_obj_includeD yes
#ifdef NIX
/* <<< */
unsigned long Xorriso_get_di_counteR= 0;
#endif /* NIX */
struct XorrisO;
int Xorriso_destroy_re(struct XorrisO *m, int flag);
int Xorriso__get_signal_behavior(int flag);
#endif /* ! Xorriso_pvt_base_obj_includeD */

1102
xorriso/check_media.c Normal file

File diff suppressed because it is too large Load Diff

181
xorriso/check_media.h Normal file
View File

@ -0,0 +1,181 @@
/* 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 SpotlistiteM, SpotlisT,
SectorbitmaP, CheckmediajoB which represent media checks and their outcome.
*/
#ifndef Xorriso_pvt_check_includeD
#define Xorriso_pvt_check_includeD yes
struct SpotlisT; /* List of intervals with different read qualities */
struct CheckmediajoB; /* Parameters for Xorriso_check_media() */
int Xorriso_check_media_setup_job(struct XorrisO *xorriso,
struct CheckmediajoB *job,
char **argv, int old_idx, int end_idx, int flag);
int Xorriso_sectormap_to_spotlist(struct XorrisO *xorriso,
struct CheckmediajoB *job,
struct SpotlisT **spotlist,
int flag);
/* @param flag bit0= mark untested areas as valid
*/
int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso,
struct SpotlisT *spotlist,
int read_chunk,
struct SectorbitmaP **map,
int flag);
/* Opens the -check_media data copy in for reading and writing
*/
int Xorriso_open_job_data_to(struct XorrisO *xorriso,
struct CheckmediajoB *job, int flag);
/* @param report Buffer of at least 10*SfileadrL
@param flag bit0= only report non-default settings
@return <=0 error , 1 ok , 2 with bit0: every option is on default setting
*/
int Xorriso_check_media_list_job(struct XorrisO *xorriso,
struct CheckmediajoB *job,
char *report, int flag);
int Xorriso_update_in_sector_map(struct XorrisO *xorriso,
struct SpotlisT *spotlist, int read_chunk,
struct CheckmediajoB *job, int flag);
/* Distiniction between valid and invalid sectors */
struct SectorbitmaP {
int sectors;
int sector_size;
unsigned char *map;
int map_size;
};
int Spotlist_new(struct SpotlisT **o, int flag);
int Spotlist_destroy(struct SpotlisT **o, int flag);
int Spotlist_add_item(struct SpotlisT *o, int start_lba, int blocks,
int quality, int flag);
int Spotlist_count(struct SpotlisT *o, int flag);
int Spotlist_block_count(struct SpotlisT *o, int flag);
int Spotlist_sector_size(struct SpotlisT *o, int read_chunk, int flag);
int Spotlist_get_item(struct SpotlisT *o, int idx,
int *start_lba, int *blocks, int *quality, int flag);
char *Spotlist__quality_name(int quality, char name[80], int bad_limit,
int flag);
#define Xorriso_read_quality_gooD 0x7fffffff
#define Xorriso_read_quality_md5_matcH 0x70000000
#define Xorriso_read_quality_sloW 0x60000000
#define Xorriso_read_quality_partiaL 0x50000000
#define Xorriso_read_quality_valiD 0x40000000
#define Xorriso_read_quality_untesteD 0x3fffffff
#define Xorriso_read_quality_invaliD 0x3ffffffe
#define Xorriso_read_quality_tao_enD 0x28000000
#define Xorriso_read_quality_off_tracK 0x20000000
#define Xorriso_read_quality_md5_mismatcH 0x10000000
#define Xorriso_read_quality_unreadablE 0x00000000
struct CheckmediajoB {
int use_dev; /* 0= use indev , 1= use outdev , 2= use sector map*/
int min_lba; /* if >=0 : begin checking at this address */
int max_lba; /* if >=0 : read up to this address, else use mode */
int min_block_size; /* granularity desired by user
*/
int mode; /* 0= track by track
1= single sweep over libisoburn media capacity
>>> 2= single sweep over libburn media capacity
*/
time_t start_time;
int time_limit; /* Number of seconds after which to abort */
int item_limit; /* Maximum number of media check list items as result */
char abort_file_path[SfileadrL];
char data_to_path[SfileadrL];
int data_to_fd;
off_t data_to_offset; /* usually 0 with image copy, negative with file copy */
off_t data_to_limit; /* used with file copy */
int patch_lba0;
int patch_lba0_msc1;
char sector_map_path[SfileadrL];
struct SectorbitmaP *sector_map;
int map_with_volid; /* 0=add quick toc to map file,
1=read ISO heads for toc
*/
int retry; /* -1= only try full read_chunk, 1=retry with 2k blocks
0= retry with CD, full chunk else
*/
int report_mode; /* 0= print MCL items
1= print damaged files
*/
char event_severity[20]; /* If not "ALL": trigger event of given severity
at the end of a check job if bad blocks were
discovered.
*/
double slow_threshold_seq; /* Time limit in seconds for the decision whether
a read operation is considered slow. This does
not apply to thr first read of an interval.
*/
int untested_valid; /* 1= mark untested data blocks as valid when calling
Xorriso_spotlist_to_sectormap()
*/
};
int Checkmediajob_new(struct CheckmediajoB **o, int flag);
int Checkmediajob_destroy(struct CheckmediajoB **o, int flag);
int Checkmediajob_copy(struct CheckmediajoB *from, struct CheckmediajoB *to,
int flag);
int Sectorbitmap_new(struct SectorbitmaP **o, int sectors, int sector_size,
int flag);
int Sectorbitmap_destroy(struct SectorbitmaP **o, int flag);
int Sectorbitmap_from_file(struct SectorbitmaP **o, char *path, char *msg,
int *os_errno, int flag);
int Sectorbitmap_to_file(struct SectorbitmaP *o, char *path, char *info,
char *msg, int *os_errno, int flag);
int Sectorbitmap_set(struct SectorbitmaP *o, int sector, int flag);
int Sectorbitmap_set_range(struct SectorbitmaP *o,
int start_sector, int sectors, int flag);
int Sectorbitmap_is_set(struct SectorbitmaP *o, int sector, int flag);
int Sectorbitmap_bytes_are_set(struct SectorbitmaP *o,
off_t start_byte, off_t end_byte, int flag);
int Sectorbitmap_get_layout(struct SectorbitmaP *o,
int *sectors, int *sector_size, int flag);
int Sectorbitmap_copy(struct SectorbitmaP *from, struct SectorbitmaP *to,
int flag);
int Sectorbitmap_clone(struct SectorbitmaP *from, struct SectorbitmaP **clone,
int flag);
#endif /* ! Xorriso_pvt_check_includeD */

947
xorriso/cmp_update.c Normal file
View File

@ -0,0 +1,947 @@
/* 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 implementation of actions which compare or update
files between disk filesystem and ISO filesystem.
*/
#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 <fcntl.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
#include "xorriso.h"
#include "xorriso_private.h"
#include "xorrisoburn.h"
/*
@param result Bitfield indicationg type of mismatch
bit11= cannot open regular disk file
bit12= cannot open iso file
bit13= early eof of disk file
bit14= early eof of iso file
bit15= content bytes differ
@param flag bit0= mtimes of both file objects are equal
bit29= do not issue pacifier messages
bit31= do not issue result messages
@return >0 ok , <=0 error
*/
int Xorriso_compare_2_contents(struct XorrisO *xorriso, char *common_adr,
char *disk_adr, off_t disk_size,
off_t offset, off_t bytes,
char *iso_adr, off_t iso_size,
int *result, int flag)
{
int fd1= -1, ret, r1, r2, done, wanted, i, was_error= 0, use_md5= 0;
void *stream2= NULL;
off_t r1count= 0, r2count= 0, diffcount= 0, first_diff= -1;
char *respt, buf1[32*1024], buf2[32*1024], offset_text[80];
char disk_md5[16], iso_md5[16];
void *ctx= NULL;
respt= xorriso->result_line;
fd1= open(disk_adr, O_RDONLY);
if(fd1==-1) {
sprintf(respt, "- %s (DISK) : cannot open() : %s\n",
disk_adr, strerror(errno));
cannot_address:;
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
(*result)|= 2048;
{ret= 0; goto ex;}
}
if(offset>0)
if(lseek(fd1, offset, SEEK_SET)==-1) {
sprintf(respt, "- %s (DISK) : cannot lseek(%.f) : %s\n",
disk_adr, (double) offset, strerror(errno));
close(fd1);
goto cannot_address;
}
if(xorriso->do_md5 & 16) {
use_md5= 1;
ret= Xorriso_is_plain_image_file(xorriso, NULL, iso_adr, 0);
if(ret <= 0)
ret= 0; /* (reverse) filtered files are likely not to match their MD5 */
else
ret= Xorriso_get_md5(xorriso, NULL, iso_adr, iso_md5, 1);
if(ret <= 0)
use_md5= 0;
else {
ret= Xorriso_md5_start(xorriso, &ctx, 0);
if(ret <= 0)
use_md5= 0;
}
}
if (! use_md5) {
ret= Xorriso_iso_file_open(xorriso, iso_adr, NULL, &stream2, 0);
if(ret<=0) {
sprintf(respt, "- %s (ISO) : cannot open() file in ISO image\n",iso_adr);
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
close(fd1);
(*result)|= 4096;
{ret= 0; goto ex;}
}
}
done= 0;
while(!done) {
wanted= sizeof(buf1);
if(r1count+offset+wanted>disk_size)
wanted= disk_size-r1count-offset;
if(r1count+wanted>bytes)
wanted= bytes-r1count;
r1= 0;
while(wanted>0) {
ret= read(fd1, buf1, wanted);
if(ret<=0)
break;
wanted-= ret;
r1+= ret;
}
wanted= sizeof(buf2);
if(r2count+wanted>iso_size)
wanted= iso_size-r2count;
/*
if(r2count+wanted>bytes)
wanted= bytes-r2count;
*/
if(use_md5)
r2= r1;
else if(wanted>0)
r2= Xorriso_iso_file_read(xorriso, stream2, buf2, wanted, 0);
else
r2= 0;
if(r1<0 || r2<0)
was_error= 1;
if(r1<=0 && r2<=0)
break;
if(r1<=0) {
if(r1<0)
r1= 0;
if(disk_size > r1count + r1 + offset) {
sprintf(respt, "- %s (DISK) : early EOF after %.f bytes\n",
disk_adr, (double) r1count);
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
(*result)|= 8196;
}
(*result)|= (1<<15);
}
r1count+= r1;
if(r2<=0 || r2<r1) {
if(r2<0)
r2= 0;
if(iso_size > r2count + r2) {
sprintf(respt, "- %s (ISO) : early EOF after %.f bytes\n",
iso_adr, (double) r2count);
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
(*result)|= (1<<14);
}
(*result)|= (1<<15);
done= 1;
}
if(r2>r1) {
if(disk_size > r1count + r1 + offset) {
sprintf(respt, "- %s (DISK) : early EOF after %.f bytes\n",
disk_adr, (double) r1count);
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
(*result)|= 8196;
}
(*result)|= (1<<15);
done= 1;
}
r2count+= r2;
if(r1>r2)
r1= r2;
if(use_md5) {
Xorriso_md5_compute(xorriso, ctx, buf1, r1, 0);
} else {
for(i= 0; i<r1; i++) {
if(buf1[i]!=buf2[i]) {
if(first_diff<0)
first_diff= r1count - r1 + i;
diffcount++;
}
}
}
if(!(flag&(1<<29))) {
xorriso->pacifier_count+= r1;
xorriso->pacifier_byte_count+= r1;
if(flag&(1<<31))
Xorriso_pacifier_callback(xorriso, "content bytes read",
xorriso->pacifier_count, 0, "", 0);
else
Xorriso_pacifier_callback(xorriso, "bytes", xorriso->pacifier_count, 0,
"", 1<<6);
}
}
if(use_md5) {
ret= Xorriso_md5_end(xorriso, &ctx, disk_md5, 0);
if(ret <= 0) {
*result |= (1 << 15);
ret= -1; goto ex;
}
for(i= 0; i < 16; i++)
if(iso_md5[i] != disk_md5[i])
break;
if(i < 16 ) {
offset_text[0]= 0;
if(offset>0)
sprintf(offset_text, "%.f+", (double) offset);
sprintf(respt, "%s %s : differs by MD5 sums.\n",
common_adr, (flag&1 ? "CONTENT": "content"));
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
(*result)|= (1<<15);
}
} else if(diffcount>0 || r1count!=r2count) {
if(first_diff<0)
first_diff= (r1count>r2count ? r2count : r1count);
offset_text[0]= 0;
if(offset>0)
sprintf(offset_text, "%.f+", (double) offset);
sprintf(respt, "%s %s : differs by at least %.f bytes. First at %s%.f\n",
common_adr, (flag&1 ? "CONTENT": "content"),
(double) (diffcount + abs(r1count-r2count)),
offset_text, (double) first_diff);
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
(*result)|= (1<<15);
}
if(fd1!=-1)
close(fd1);
if(! use_md5)
Xorriso_iso_file_close(xorriso, &stream2, 0);
if(was_error)
{ret= -1; goto ex;}
ret= 1;
ex:;
if(ctx != NULL)
Xorriso_md5_end(xorriso, &ctx, disk_md5, 0);
return(ret);
}
/*
@param result Bitfield indicationg type of mismatch
bit0= disk_adr not existing
bit1= iso_adr not existing
bit2= access permissions
bit3= file type
bit4= user id
bit5= group id
bit6= minor, major with device file
bit7= size
bit8= mtime
bit9= atime
bit10= ctime
bit11= cannot open regular disk file
bit12= cannot open iso file
bit13= early eof of disk file
bit14= early eof of iso file
bit15= content bytes differ
bit16= symbolic link on disk pointing to dir, dir in iso
bit17= file chunks detected and compared
bit18= incomplete chunk collection encountered
bit19= ACL differs (this condition sets also bit2)
bit20= xattr differ
bit21= mismatch of recorded dev,inode
bit22= no recorded dev,inode found in node
bit23= timestamps younger than xorriso->isofs_st_in
bit24= hardlink split
bit25= hardlink fusion
@param flag bit0= compare atime
bit1= compare ctime
bit2= check only existence of both file objects
count one or both missing as "difference"
bit27= for Xorriso_path_is_excluded(): bit0
bit28= examine eventual disk_path link target rather than link
bit29= do not issue pacifier messages
bit30= omit adr_common_tail in report messages
bit31= do not issue result messages
@return 1=files match properly , 0=difference detected , -1=error
*/
int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr,
char *iso_adr, char *adr_common_tail,
int *result, int flag)
{
struct stat s1, s2, stbuf;
int ret, missing= 0, is_split= 0, i, was_error= 0, diff_count= 0;
int content_shortcut= 0;
char *respt;
char a[5*SfileadrL], sfe[5*SfileadrL];
char ttx1[40], ttx2[40];
char *a1_acl= NULL, *a2_acl= NULL, *d1_acl= NULL, *d2_acl= NULL;
char *attrlist1= NULL, *attrlist2= NULL;
struct SplitparT *split_parts= NULL;
int split_count= 0;
time_t stamp;
char part_path[SfileadrL], *part_name;
int partno, total_parts= 0;
off_t offset, bytes, total_bytes;
*result= 0;
respt= xorriso->result_line;
if(!(xorriso->disk_excl_mode&8)) {
ret= Xorriso_path_is_excluded(xorriso, disk_adr, 2 | !!(flag&(1<<27)));
if(ret>0) {
sprintf(respt , "? %s (DISK) : exluded by %s\n",
Text_shellsafe(disk_adr, sfe, 0),
(ret==1 ? "-not_paths" : "-not_leaf"));
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
missing= 1;
(*result)|= 1;
}
}
if(!missing) {
if(flag&(1<<28))
ret= stat(disk_adr, &s1);
else
ret= lstat(disk_adr, &s1);
if(ret==-1) {
sprintf(respt , "? %s (DISK) : cannot lstat() : %s\n",
Text_shellsafe(disk_adr, sfe, 0), strerror(errno));
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
missing= 1;
(*result)|= 1;
}
}
if(missing)
strcpy(a, "?");
else
strcpy(a, Ftypetxt(s1.st_mode, 1));
strcat(a, " ");
if(adr_common_tail[0])
strcat(a, Text_shellsafe(adr_common_tail, sfe, 0));
else {
Text_shellsafe(disk_adr, a+strlen(a), 0);
strcat(a, " (DISK)");
/*
strcat(a, "'.'");
*/
}
strcat(a, " :");
if(flag&(1<<30))
a[0]= 0;
ret= Xorriso_iso_lstat(xorriso, iso_adr, &s2, 0);
if(ret<0) {
sprintf(respt, "? %s (ISO) : cannot find this file in ISO image\n",
Text_shellsafe(iso_adr, sfe, 0));
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
missing= 1;
(*result)|= 2;
}
if((flag&4)||missing)
{ret= !missing; goto ex;}
/* Splitfile parts */
if((S_ISREG(s1.st_mode) || S_ISBLK(s1.st_mode)) && S_ISDIR(s2.st_mode)) {
is_split= Xorriso_identify_split(xorriso, iso_adr, NULL, &split_parts,
&split_count, &s2, 0);
if(is_split>0)
(*result)|= (1<<17);
else
is_split= 0;
}
/* Attributes */
if(s1.st_mode != s2.st_mode) {
if((s1.st_mode&~S_IFMT)!=(s2.st_mode&~S_IFMT)) {
sprintf(respt, "%s st_mode : %7.7o <> %7.7o\n",
a, (unsigned int) (s1.st_mode & ~S_IFMT),
(unsigned int) (s2.st_mode & ~S_IFMT));
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
(*result)|= 4;
}
if((s1.st_mode&S_IFMT)!=(s2.st_mode&S_IFMT)) {
sprintf(respt, "%s type : %s <> %s\n",
a, Ftypetxt(s1.st_mode, 0), Ftypetxt(s2.st_mode, 0));
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
(*result)|= 8;
if((s1.st_mode&S_IFMT) == S_IFLNK) {
/* check whether link target type matches */
ret= stat(disk_adr, &stbuf);
if(ret!=-1)
if(S_ISDIR(stbuf.st_mode) && S_ISDIR(s2.st_mode))
(*result)|= (1<<16);
}
}
}
/* ACL */
if(xorriso->do_aaip & 3) {
Xorriso_local_getfacl(xorriso, disk_adr, &a1_acl,
16 | ((flag & (1 << 28)) >> 23));
if(S_ISDIR(s1.st_mode))
Xorriso_local_getfacl(xorriso, disk_adr, &d1_acl, 1);
ret= Xorriso_getfacl(xorriso, NULL, iso_adr, &a2_acl, 1 | 4 | 16);
if(ret < 0)
goto ex;
if(S_ISDIR(s1.st_mode)) {
ret= Xorriso_getfacl(xorriso, NULL, iso_adr, &d2_acl, 1 | 8);
if(ret < 0)
goto ex;
}
ret= Compare_text_lines(a1_acl, a2_acl, &diff_count, 0);
if(ret < 0)
goto ex;
if(ret == 0)
(*result)|= 4 | (1 << 19);
ret= Compare_text_lines(d1_acl, d2_acl, &diff_count, 1);
if(ret < 0)
goto ex;
if(ret == 0)
(*result)|= 4 | (1 << 19);
if((*result) & (1 << 19)) {
sprintf(respt, "%s ACL : %d difference%s\n",
a, diff_count, diff_count == 1 ? "" : "s");
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
}
}
/* xattr */
if(xorriso->do_aaip & 12) {
ret= Xorriso_getfattr(xorriso, NULL, disk_adr, &attrlist1,
1 | 2 | ((flag & (1 << 28)) >> 23));
if(ret < 0)
goto ex;
ret= Xorriso_getfattr(xorriso, NULL, iso_adr, &attrlist2, 1);
if(ret < 0)
goto ex;
ret= Compare_text_lines(attrlist1, attrlist2, &diff_count, 0);
if(ret < 0)
goto ex;
if(ret == 0) {
(*result)|= (1 << 20);
sprintf(respt, "%s xattr : %d difference%s\n",
a, diff_count, diff_count == 1 ? "" : "s");
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
}
}
if(s1.st_uid != s2.st_uid) {
sprintf(respt, "%s st_uid : %lu <> %lu\n", a,
(unsigned long) s1.st_uid, (unsigned long) s2.st_uid);
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
(*result)|= 16;
}
if(s1.st_gid != s2.st_gid) {
sprintf(respt, "%s st_gid : %lu <> %lu\n", a,
(unsigned long) s1.st_gid, (unsigned long) s2.st_gid);
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
(*result)|= 32;
}
if((S_ISCHR(s1.st_mode) && S_ISCHR(s2.st_mode)) ||
(S_ISBLK(s1.st_mode) && S_ISBLK(s2.st_mode))) {
if(s1.st_rdev != s2.st_rdev) {
sprintf(respt, "%s %s st_rdev : %lu <> %lu\n", a,
(S_ISCHR(s1.st_mode) ? "S_IFCHR" : "S_IFBLK"),
(unsigned long) s1.st_rdev, (unsigned long) s1.st_rdev);
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
(*result)|= 64;
}
}
if((!(xorriso->do_aaip & 32)) &&
S_ISREG(s2.st_mode) && s1.st_size != s2.st_size) {
sprintf(respt, "%s st_size : %.f <> %.f diff= %.f\n",
a, (double) s1.st_size, (double) s2.st_size,
((double) s1.st_size) - (double) s2.st_size);
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
(*result)|= 128;
}
if(s1.st_mtime != s2.st_mtime) {
sprintf(respt, "%s st_mtime : %s <> %s diff= %.f s\n",
a, Ftimetxt(s1.st_mtime, ttx1, 0),
Ftimetxt(s2.st_mtime, ttx2, 0),
((double) s1.st_mtime) - (double) s2.st_mtime);
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
(*result)|= 256;
}
if(flag&1) {
if(s1.st_atime != s2.st_atime) {
sprintf(respt, "%s st_atime : %s <> %s diff= %.f s\n",
a, Ftimetxt(s1.st_atime, ttx1, 0),
Ftimetxt(s2.st_atime, ttx2, 0),
((double) s1.st_atime) - (double) s2.st_atime);
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
(*result)|= 512;
}
}
if(flag&2) {
if(s1.st_ctime != s2.st_ctime) {
sprintf(respt, "%s st_ctime : %s <> %s diff= %.f s\n",
a, Ftimetxt(s1.st_ctime, ttx1, 0),
Ftimetxt(s2.st_ctime, ttx2, 0),
((double) s1.st_ctime) - (double) s2.st_ctime);
if(!(flag&(1<<31)))
Xorriso_result(xorriso,0);
(*result)|= 1024;
}
}
if(xorriso->isofs_st_in > 0 &&
(xorriso->isofs_st_in <= s2.st_mtime ||
((flag & 1) && xorriso->isofs_st_in <= s2.st_atime) ||
((flag & 2) && xorriso->isofs_st_in <= s2.st_ctime)))
(*result)|= 1 << 23;
if((xorriso->do_aaip & 32) || !(xorriso->ino_behavior & 2)) {
/* dev,inode comparison.
For skipping content comparison or for hardlink detection.
*/
ret= Xorriso_record_dev_inode(xorriso, "", s1.st_dev, s1.st_ino, NULL,
iso_adr, 1 | 2 | ((flag & (1 << 28)) >> 23) | (xorriso->do_aaip & 128));
if(ret < 0) {
ret= -1; goto ex;
} else if(ret == 0) { /* match */
if((xorriso->do_aaip & 64) && S_ISREG(s1.st_mode) && S_ISREG(s2.st_mode)){
if(xorriso->do_aaip & 32)
content_shortcut= 1;
if((*result) & (8 | 128 | 256 | 512 | 1024 | (1 << 23))) {
(*result)|= (1 << 15); /* content bytes differ */
if(((*result) & (1 << 23)) &&
!((*result) & (8 | 128 | 256 | 512 | 1024))) {
sprintf(respt,
"%s content : node timestamp younger than image timestamp\n", a);
if((xorriso->do_aaip & 32) && !(flag&(1<<31)))
Xorriso_result(xorriso,0);
stamp= s2.st_mtime;
if((flag & 1) && s2.st_atime >= stamp)
stamp= s2.st_atime;
if((flag & 2) && s2.st_ctime >= stamp)
stamp= s2.st_ctime;
sprintf(respt, "%s content : %s > %s diff= %.f s\n",
a, Ftimetxt(stamp, ttx1, 3 << 1),
Ftimetxt(xorriso->isofs_st_in, ttx2, 3 << 1),
((double) stamp) - (double) xorriso->isofs_st_in);
if((xorriso->do_aaip & 32) && !(flag&(1<<31)))
Xorriso_result(xorriso,0);
}
sprintf(respt,
"%s content : assuming inequality due to size or timestamps\n", a);
if((xorriso->do_aaip & 32) && !(flag&(1<<31)))
Xorriso_result(xorriso,0);
}
}
} else if(ret == 1) { /* mismatch */
(*result)|= (1 << 21);
sprintf(respt, "%s dev_ino : differing\n", a);
if((xorriso->do_aaip & 32) && !(flag&(1<<31)))
Xorriso_result(xorriso,0);
if((xorriso->do_aaip & 64) && S_ISREG(s1.st_mode) && S_ISREG(s2.st_mode)){
if(xorriso->do_aaip & 32)
content_shortcut= 1;
(*result)|= (1 << 15); /* content bytes differ */
sprintf(respt,
"%s content : assuming inequality after dev_ino mismatch\n", a);
if((xorriso->do_aaip & 32) && !(flag&(1<<31)))
Xorriso_result(xorriso,0);
}
} else {
sprintf(respt, "%s dev_ino : no dev_ino stored with image node\n", a);
if((xorriso->do_aaip & 32) && !(flag&(1<<31)))
Xorriso_result(xorriso,0);
(*result)|= (1 << 22);
}
}
if(S_ISREG(s1.st_mode) && S_ISREG(s2.st_mode) && !content_shortcut) {
/* Content */
if(is_split) {
for(i= 0; i<split_count; i++) {
Splitparts_get(split_parts, i, &part_name, &partno, &total_parts,
&offset, &bytes, &total_bytes, 0);
strcpy(part_path, iso_adr);
if(Sfile_add_to_path(part_path, part_name, 0)<=0) {
Xorriso_much_too_long(xorriso, strlen(iso_adr)+strlen(part_name)+1,
2);
{ret= -1; goto ex;}
}
ret= Xorriso_iso_lstat(xorriso, part_path, &stbuf, 0);
if(ret<0)
continue;
ret= Xorriso_compare_2_contents(xorriso, a, disk_adr, s1.st_size,
offset, bytes,
part_path, stbuf.st_size, result,
(s1.st_mtime==s2.st_mtime) | (flag&((1<<29)|(1<<31))));
if(ret<0)
was_error= 1;
}
if(total_parts>0 && split_count!=total_parts) {
sprintf(xorriso->info_text,
"- %s/* (ISO) : Not all split parts present (%d of %d)\n",
iso_adr, split_count, total_parts);
if(!(flag&(1<<31)))
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 1);
(*result)|= 1<<18;
}
} else {
ret= Xorriso_compare_2_contents(xorriso, a, disk_adr, s1.st_size,
(off_t) 0, s1.st_size,
iso_adr, s2.st_size, result,
(s1.st_mtime==s2.st_mtime) | (flag&((1<<29)|(1<<31))));
if(ret<0)
was_error= 1;
}
}
if(was_error)
ret= -1;
else
ret= (((*result) & ~((1 << 17) | (1 << 18) | (1 << 23)))==0);
ex:;
if(split_parts!=NULL)
Splitparts_destroy(&split_parts, split_count, 0);
Xorriso_local_getfacl(xorriso, disk_adr, &a1_acl, 1 << 15);
Xorriso_local_getfacl(xorriso, disk_adr, &d1_acl, 1 << 15);
if(a2_acl != NULL)
free(a2_acl);
if(d2_acl != NULL)
free(d2_acl);
return(ret);
}
int Xorriso_pfx_disk_path(struct XorrisO *xorriso, char *iso_path,
char *iso_prefix, char *disk_prefix,
char disk_path[SfileadrL], int flag)
{
int ret;
char adrc[SfileadrL];
if(strncmp(iso_path, iso_prefix, strlen(iso_prefix))!=0)
return(-1);
if(strlen(disk_prefix) + strlen(iso_path) - strlen(iso_prefix)+1 >= SfileadrL)
return(-1);
if(iso_path[strlen(iso_prefix)] == '/')
strcpy(adrc, iso_path + strlen(iso_prefix) + 1);
else
strcpy(adrc, iso_path + strlen(iso_prefix));
ret= Xorriso_make_abs_adr(xorriso, disk_prefix, adrc, disk_path, 4 | 8);
if(ret <= 0)
return(ret);
return(1);
}
/* @param boss_iter Opaque handle to be forwarded to actions in ISO image
Set to NULL if calling this function from outside ISO world
@param flag bit0= update rather than compare
bit1= find[ix] is in recursion
@return <=0 error, 1= ok , 2= iso_path was deleted
3=ok, do not dive into directory (e.g. because it is a split file)
*/
int Xorriso_find_compare(struct XorrisO *xorriso, void *boss_iter,
char *iso_path, char *iso_prefix, char *disk_prefix,
int flag)
{
int ret, result, uret, follow_links, deleted= 0;
char disk_path[SfileadrL];
ret= Xorriso_pfx_disk_path(xorriso, iso_path, iso_prefix, disk_prefix,
disk_path, 0);
if(ret <= 0)
return(ret);
/* compare exclusions against disk_path resp. leaf name */
if(xorriso->disk_excl_mode&8)
ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&2));
else
ret= 0;
if(ret<0)
return(ret);
if(ret>0)
return(3);
follow_links= (xorriso->do_follow_links ||
(xorriso->do_follow_param && !(flag&2))) <<28;
ret= Xorriso_compare_2_files(xorriso, disk_path, iso_path, "", &result,
2 | follow_links | ((!(flag&2))<<27) | ((flag&1)<<31));
/* was once: | ((!(flag&1))<<29) */
if(ret<xorriso->find_compare_result)
xorriso->find_compare_result= ret;
if(flag&1) {
if(ret<=0) {
if(ret<0)
if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0)
return(ret);
uret= Xorriso_update_interpreter(xorriso, boss_iter, result,
disk_path, iso_path, (flag&2)<<1);
if(uret<=0)
ret= 0;
if(uret==2)
deleted= 1;
}
}
if(ret<0)
return(ret);
if(deleted)
return(2);
if(result&(1<<17))
return(3);
return(ret);
}
/* @param boss_iter Opaque handle to be forwarded to actions in ISO image
Set to NULL if calling this function from outside ISO world
@param flag bit0= widen hardlink sibling:
Do not call Xorriso_hardlink_update()
Overwrite exactly if normal mode would not,
else do nothing
bit2= -follow: this is not a command parameter
@return <=0 error, 1= ok , 2= iso_rr_path node object has been deleted ,
3= no action taken
*/
int Xorriso_update_interpreter(struct XorrisO *xorriso, void *boss_iter,
int compare_result, char *disk_path,
char *iso_rr_path, int flag)
{
int ret, deleted= 0, is_split= 0, i, loop_count, late_hardlink_update= 0;
char sfe[5*SfileadrL];
struct stat stbuf;
struct SplitparT *split_parts= NULL;
int split_count= 0;
char part_path[SfileadrL], *part_name;
int partno, total_parts, new_total_parts;
off_t offset, bytes, total_bytes, disk_size, first_bytes;
if((compare_result&3)==3) {
sprintf(xorriso->info_text, "Missing on disk and in ISO: disk_path %s",
Text_shellsafe(disk_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 1);
xorriso->find_compare_result= -1;
ret= 3; goto ex;
}
if(compare_result&((1<<11)|(1<<13))) {
if(flag & 1)
{ret= 3; goto ex;}
/* cannot open regular disk file, early eof of disk file */
sprintf(xorriso->info_text, "Problems with reading disk file %s",
Text_shellsafe(disk_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 1);
xorriso->find_compare_result= -1;
ret= 1; goto ex;
}
xorriso->info_text[0]= 0;
is_split= !!(compare_result & (1<<17));
if((!(xorriso->ino_behavior & 2)) && (compare_result & (2 | (3 << 21))) &&
!(flag & 1)) {
if(compare_result & 2) {
/* File is not yet in image */
late_hardlink_update= 1;
} else {
/* Hard link relation has changed resp. was not recorded. */
ret= Xorriso_hardlink_update(xorriso, &compare_result,
disk_path, iso_rr_path, flag & 4);
if(ret < 0)
goto ex;
if(ret == 2)
{ret= 1; goto ex;}
}
}
if(compare_result&(8|64)) {
/* file type, minor+major with device file */
if(flag & 1)
{ret= 3; goto ex;}
ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, iso_rr_path, 1); /* rm_r */
if(ret>0) {
deleted= 1;
ret= Xorriso_graft_in(xorriso, boss_iter, disk_path, iso_rr_path,
(off_t) 0, (off_t) 0, 2|(flag&4));
}
sprintf(xorriso->info_text, "Deleted and re-added ");
} else if(compare_result&(1)) {
delete:;
/* disk_adr not existing */
ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, iso_rr_path, 1);
deleted= 1;
sprintf(xorriso->info_text, "Deleted ");
} else if(compare_result&(2|128|(1<<12)|(1<<14)|(1<<15))) {
/* iso_adr not existing, size, cannot open iso file, early eof of iso file
content bytes differ */
if(flag & 1)
{ret= 3; goto ex;}
overwrite:;
if(is_split) {
ret= Xorriso_identify_split(xorriso, iso_rr_path, NULL,
&split_parts, &split_count, &stbuf, 0);
if(ret<=0)
{ret= -1; goto ex;} /* (should not happen) */
ret= lstat(disk_path, &stbuf);
if(ret==-1)
goto delete;
disk_size= stbuf.st_size;
Splitparts_get(split_parts, 0, &part_name, &partno, &total_parts,
&offset, &first_bytes, &total_bytes, 0);
new_total_parts= disk_size/first_bytes;
if(disk_size % first_bytes)
new_total_parts++;
loop_count= split_count;
/* If disk file grew over part limit and all parts are present:
add new parts */
if(new_total_parts > total_parts && split_count == total_parts)
loop_count= new_total_parts;
for(i= 0; i<loop_count; i++) {
if(i<split_count) {
/* Delete old part */
Splitparts_get(split_parts, i, &part_name, &partno, &total_parts,
&offset, &bytes, &total_bytes, 0);
strcpy(part_path, iso_rr_path);
if(Sfile_add_to_path(part_path, part_name, 0)<=0) {
Xorriso_much_too_long(xorriso,
strlen(iso_rr_path)+strlen(part_path)+1, 2);
{ret= -1; goto ex;}
}
ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, part_path, 1);
if(ret<=0)
goto ex;
deleted= 1;
} else {
partno= i+1;
offset= i*first_bytes;
bytes= first_bytes;
}
if(disk_size<=offset)
continue;
/* Insert new part */
if(strlen(part_path)+160>SfileadrL) {
Xorriso_much_too_long(xorriso, strlen(part_path)+160, 2);
ret= 0; goto ex;
}
Splitpart__compose(part_path+strlen(iso_rr_path)+1, partno,
new_total_parts, offset, first_bytes, disk_size, 0);
ret= Xorriso_graft_in(xorriso, boss_iter, disk_path, part_path,
offset, bytes, 2|(flag&4)|8|128);
if(ret<=0)
goto ex;
}
/* Copy file attributes to iso_rr_path, augment r-perms by x-perms */
ret= Xorriso_copy_properties(xorriso, disk_path, iso_rr_path, 2 | 4);
if(ret<=0)
goto ex;
} else {
ret= Xorriso_graft_in(xorriso, boss_iter, disk_path, iso_rr_path,
(off_t) 0, (off_t) 0, 2|(flag&4));
if(ret>0 && !(compare_result&2))
deleted= 1;
}
if(late_hardlink_update) {
/* Handle eventual hardlink siblings of newly created file */
ret= Xorriso_hardlink_update(xorriso, &compare_result,
disk_path, iso_rr_path, 1 | (flag & 4));
if(ret < 0)
goto ex;
}
if(flag & 1)
sprintf(xorriso->info_text, "Widened hard link ");
else
sprintf(xorriso->info_text, "Added/overwrote ");
} else if(compare_result&(4|16|32|256|512|1024|(1<<19)|(1<<20)|(1<<22))) {
/* access permissions, user id, group id, mtime, atime, ctime, ACL, xattr,
dev_ino missing */
if(flag & 1)
goto overwrite;
if(is_split) {
ret= Xorriso_identify_split(xorriso, iso_rr_path, NULL,
&split_parts, &split_count, &stbuf, 0);
if(ret<=0)
{ret= -1; goto ex;} /* (should not happen) */
for(i= 0; i<split_count; i++) {
Splitparts_get(split_parts, i, &part_name, &partno, &total_parts,
&offset, &bytes, &total_bytes, 0);
strcpy(part_path, iso_rr_path);
if(Sfile_add_to_path(part_path, part_name, 0)<=0) {
Xorriso_much_too_long(xorriso,
strlen(iso_rr_path)+strlen(part_path)+1, 2);
{ret= -1; goto ex;}
}
ret= Xorriso_copy_properties(xorriso, disk_path, part_path,
4 * !(compare_result & (1<<21)));
/* do not update eventually mismatching dev_ino */
if(ret<=0)
goto ex;
}
/* Copy file attributes to iso_rr_path, augment r-perms by x-perms */
ret= Xorriso_copy_properties(xorriso, disk_path, iso_rr_path, 2 | 4);
if(ret<=0)
goto ex;
} else
ret= Xorriso_copy_properties(xorriso, disk_path, iso_rr_path, 4);
sprintf(xorriso->info_text, "Adjusted attributes of ");
} else if(flag & 1) {
goto overwrite;
} else
ret= 1;
if(ret>0 && xorriso->info_text[0]) {
strcat(xorriso->info_text, Text_shellsafe(iso_rr_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
}
ret= 1;
ex:;
if(split_parts!=NULL)
Splitparts_destroy(&split_parts, split_count, 0);
if(ret<=0)
return(ret);
if(deleted)
return(2);
return(ret);
}

40
xorriso/cmp_update.h Normal file
View File

@ -0,0 +1,40 @@
/* 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 class DirseQ which
crawls along a directory's content list.
*/
#ifndef Xorriso_pvt_cmp_includeD
#define Xorriso_pvt_cmp_includeD yes
int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr,
char *iso_adr, char *adr_common_tail,
int *result, int flag);
int Xorriso_pfx_disk_path(struct XorrisO *xorriso, char *iso_path,
char *iso_prefix, char *disk_prefix,
char disk_path[SfileadrL], int flag);
/* @param boss_iter Opaque handle to be forwarded to actions in ISO image
Set to NULL if calling this function from outside ISO world
@param flag bit0= update rather than compare
*/
int Xorriso_find_compare(struct XorrisO *xorriso, void *boss_iter,
char *iso_path, char *iso_prefix, char *disk_prefix,
int flag);
/* @param boss_iter Opaque handle to be forwarded to actions in ISO image
Set to NULL if calling this function from outside ISO world
*/
int Xorriso_update_interpreter(struct XorrisO *xorriso, void *boss_iter,
int compare_result, char *disk_path,
char *iso_rr_path, int flag);
#endif /* ! Xorriso_pvt_cmp_includeD */

View File

@ -117,9 +117,33 @@ cc -I. -DXorriso_with_maiN $def_libreadline \
\ \
-o "$xorr"/xorriso \ -o "$xorr"/xorriso \
\ \
"$xorr"/xorriso.c \ "$xorr"/xorriso_main.c \
"$xorr"/sfile.c \
"$xorr"/aux_objects.c \
"$xorr"/findjob.c \
"$xorr"/check_media.c \
"$xorr"/misc_funct.c \
"$xorr"/text_io.c \
"$xorr"/match.c \
"$xorr"/emulators.c \
"$xorr"/disk_ops.c \
"$xorr"/cmp_update.c \
"$xorr"/parse_exec.c \
"$xorr"/opts_a_c.c \
"$xorr"/opts_d_h.c \
"$xorr"/opts_i_o.c \
"$xorr"/opts_p_z.c \
\ \
"$xorr"/xorrisoburn.c \ "$xorr"/base_obj.c \
"$xorr"/lib_mgt.c \
"$xorr"/sort_cmp.c \
"$xorr"/drive_mgt.c \
"$xorr"/iso_img.c \
"$xorr"/iso_tree.c \
"$xorr"/iso_manip.c \
"$xorr"/write_run.c \
"$xorr"/read_run.c \
"$xorr"/filters.c \
\ \
"$burn"/async.o \ "$burn"/async.o \
"$burn"/debug.o \ "$burn"/debug.o \

1838
xorriso/disk_ops.c Normal file

File diff suppressed because it is too large Load Diff

116
xorriso/disk_ops.h Normal file
View File

@ -0,0 +1,116 @@
/* 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 class DirseQ which
crawls along a directory's content list.
*/
#ifndef Xorriso_pvt_diskop_includeD
#define Xorriso_pvt_diskop_includeD yes
/* @param flag bit0= simple readlink(): no normalization, no multi-hop
*/
int Xorriso_resolve_link(struct XorrisO *xorriso,
char *link_path, char result_path[SfileadrL], int flag);
int Xorriso_convert_gidstring(struct XorrisO *xorriso, char *gid_string,
gid_t *gid, int flag);
int Xorriso_convert_modstring(struct XorrisO *xorriso, char *cmd, char *mode,
mode_t *mode_and, mode_t *mode_or, int flag);
int Xorriso_convert_uidstring(struct XorrisO *xorriso, char *uid_string,
uid_t *uid, int flag);
/* @param flag bit0= for Xorriso_msgs_submit: use pager
*/
int Xorriso_hop_link(struct XorrisO *xorriso, char *link_path,
struct LinkiteM **link_stack, struct stat *stbuf, int flag);
int Xorriso__mode_to_perms(mode_t st_mode, char perms[11], int flag);
int Xorriso_format_ls_l(struct XorrisO *xorriso, struct stat *stbuf, int flag);
/* @param flag bit0= long format
bit1= do not print count of nodes
bit2= du format
bit3= print directories as themselves (ls -d)
*/
int Xorriso_lsx_filev(struct XorrisO *xorriso, char *wd,
int filec, char **filev, off_t boss_mem, int flag);
/*
@param flag >>> bit0= remove whole sub tree: rm -r
bit1= remove empty directory: rmdir
bit2= recursion: do not reassure in mode 2 "tree"
bit3= this is for overwriting and not for plain removal
bit4= count deleted files in xorriso->pacifier_count
bit5= with bit0 only remove directory content, not the directory
@return <=0 = error
1 = removed leaf file object
2 = removed directory or tree
3 = did not remove on user revocation
*/
int Xorriso_rmx(struct XorrisO *xorriso, off_t boss_mem, char *path, int flag);
int Xorriso_findx(struct XorrisO *xorriso, struct FindjoB *job,
char *abs_dir_parm, char *dir_path,
struct stat *dir_stbuf, int depth,
struct LinkiteM *link_stack, int flag);
/* @param flag bit0= no hardlink reconstruction
bit1= do not set xorriso->node_*_prefixes
bit5= -extract_single: eventually do not insert directory tree
*/
int Xorriso_restore_sorted(struct XorrisO *xorriso, int count,
char **src_array, char **tgt_array, int flag);
/* @param flag bit0= path is a directory
bit2= recursion: do not reassure in mode 2 "tree"
bit3= this is for overwriting and not for plain removal
*/
int Xorriso_reassure_restore(struct XorrisO *xorriso, char *path, int flag);
/* @param flag bit7= return 4 if restore fails from denied permission
do not issue error message
@return <=0 failure , 1 success ,
4 with bit7: permission to create file was denied
*/
int Xorriso_make_tmp_path(struct XorrisO *xorriso, char *orig_path,
char *tmp_path, int *fd, int flag);
/* @param flag bit0= change regardless of xorriso->do_auto_chmod
bit1= desired is only rx
*/
int Xorriso_auto_chmod(struct XorrisO *xorriso, char *disk_path, int flag);
int Xorriso_make_accessible(struct XorrisO *xorriso, char *disk_path,int flag);
/* @param flag bit0= prefer to find a match after *img_prefixes
(but deliver img_prefixes if no other can be found)
*/
int Xorriso_make_restore_path(struct XorrisO *xorriso,
struct Xorriso_lsT **img_prefixes, struct Xorriso_lsT **disk_prefixes,
char img_path[SfileadrL], char disk_path[SfileadrL], int flag);
int Xorriso_restore_make_hl(struct XorrisO *xorriso,
char *old_path, char *new_path, int flag);
int Xorriso_afile_fopen(struct XorrisO *xorriso,
char *filename, char *mode, FILE **ret_fp, int flag);
int Xorriso_make_mount_cmd(struct XorrisO *xorriso, char *cmd,
int lba, int track, int session, char *volid,
char *devadr, char result[SfileadrL], int flag);
int Xorriso_append_scdbackup_record(struct XorrisO *xorriso, int flag);
#endif /* ! Xorriso_pvt_diskop_includeD */

2242
xorriso/drive_mgt.c Normal file

File diff suppressed because it is too large Load Diff

37
xorriso/drive_mgt.h Normal file
View File

@ -0,0 +1,37 @@
/* 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 functions which operate on drives
and media.
*/
#ifndef Xorriso_pvt_drive_mgt_includeD
#define Xorriso_pvt_drive_mgt_includeD yes
int Xorriso_may_burn(struct XorrisO *xorriso, int flag);
int Xorriso_toc_line(struct XorrisO *xorriso, int flag);
int Xorriso_media_product(struct XorrisO *xorriso, int flag);
int Xorriso_check_md5_range(struct XorrisO *xorriso, off_t start_lba,
off_t end_lba, char md5[16], int flag);
int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
struct CheckmediajoB *job,
int from_lba, int block_count, int read_chunk,
int md5_start, int flag);
int Xorriso_get_drive_handles(struct XorrisO *xorriso,
struct burn_drive_info **dinfo,
struct burn_drive **drive,
char *attempt, int flag);
#endif /* ! Xorriso_pvt_drive_mgt_includeD */

1248
xorriso/emulators.c Normal file

File diff suppressed because it is too large Load Diff

34
xorriso/emulators.h Normal file
View File

@ -0,0 +1,34 @@
/* 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 emulators for mkisofs and cdrecord.
*/
#ifndef Xorriso_pvt_emul_includeD
#define Xorriso_pvt_emul_includeD yes
/* micro version of cdrskin */
int Xorriso_cdrskin(struct XorrisO *xorriso, char *whom, int argc, char **argv,
int flag);
int Xorriso_cdrskin_help(struct XorrisO *xorriso, int flag);
int Xorriso_as_cdrskin(struct XorrisO *xorriso, int argc, char **argv,
int *idx, int flag);
/* micro emulation of mkisofs */
int Xorriso_genisofs(struct XorrisO *xorriso, char *whom,
int argc, char **argv, int flag);
int Xorriso_genisofs_help(struct XorrisO *xorriso, int flag);
int Xorriso_as_genisofs(struct XorrisO *xorriso, int argc, char **argv,
int *idx, int flag);
#endif /* ! Xorriso_pvt_emul_includeD */

694
xorriso/filters.c Normal file
View File

@ -0,0 +1,694 @@
/* 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 operate on data filter objects.
*/
#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 "lib_mgt.h"
#include "iso_tree.h"
/*
#include "xorriso.h"
#include "xorriso_private.h"
#include "xorrisoburn.h"
#include "iso_img.h"
#include "iso_manip.h"
#include "sort_cmp.h"
*/
struct Xorriso_extF {
int flag; /* unused yet */
IsoExternalFilterCommand *cmd;
};
int Xorriso_extf_destroy(struct XorrisO *xorriso, struct Xorriso_extF **filter,
int flag);
/* @param flag see struct Xorriso_extF.flag */
int Xorriso_extf_new(struct XorrisO *xorriso, struct Xorriso_extF **filter,
char *path, int argc, char **argv, int behavior,
char *suffix, char *name, int flag)
{
int i;
struct Xorriso_extF *o= NULL;
IsoExternalFilterCommand *cmd;
*filter= o= calloc(sizeof(struct Xorriso_extF), 1);
if(o == NULL)
goto failure;
o->flag= flag;
o->cmd= NULL;
o->cmd= cmd= calloc(sizeof(IsoExternalFilterCommand), 1);
if(cmd == NULL)
goto failure;
cmd->version= 0;
cmd->refcount= 0;
cmd->name= NULL;
cmd->path= NULL;
cmd->argv= NULL;
cmd->argc= argc + 1;
cmd->behavior= behavior;
cmd->suffix= NULL;
cmd->suffix= strdup(suffix);
if(cmd->suffix == NULL)
goto failure;
cmd->path= strdup(path);
if(cmd->path == NULL)
goto failure;
cmd->argv= calloc(sizeof(char *), argc + 2);
if(cmd->argv == NULL)
goto failure;
for(i= 0; i < argc + 2; i++)
cmd->argv[i]= NULL;
cmd->argv[0]= strdup(path);
if(cmd->argv[0] == NULL)
goto failure;
for(i= 0; i < argc; i++) {
cmd->argv[i + 1]= strdup(argv[i]);
if(cmd->argv[i] == NULL)
goto failure;
}
cmd->name= strdup(name);
if(cmd->name == NULL)
goto failure;
return(1);
failure:;
Xorriso_extf_destroy(xorriso, filter, 0);
return(-1);
}
int Xorriso_extf_destroy(struct XorrisO *xorriso, struct Xorriso_extF **filter,
int flag)
{
int i;
IsoExternalFilterCommand *cmd;
if(*filter == NULL)
return(0);
cmd= (*filter)->cmd;
if(cmd != NULL) {
if(cmd->refcount > 0)
return(0);
if(cmd->suffix != NULL)
free(cmd->suffix);
if(cmd->argv != NULL) {
for(i= 0; i < cmd->argc; i++)
if(cmd->argv[i] != NULL)
free(cmd->argv[i]);
free((char *) cmd->argv);
}
if(cmd->name != NULL)
free(cmd->name);
}
free((char *) *filter);
*filter= NULL;
return(1);
}
int Xorriso_lookup_extf(struct XorrisO *xorriso, char *name,
struct Xorriso_lsT **found_lst, int flag)
{
struct Xorriso_extF *filter;
struct Xorriso_lsT *lst;
for(lst= xorriso->filters; lst != NULL; lst= Xorriso_lst_get_next(lst, 0)) {
filter= (struct Xorriso_extF *) Xorriso_lst_get_text(lst, 0);
if(strcmp(filter->cmd->name, name) == 0) {
*found_lst= lst;
return(1);
}
}
return(0);
}
int Xorriso_destroy_all_extf(struct XorrisO *xorriso, int flag)
{
struct Xorriso_extF *filter;
struct Xorriso_lsT *lst, *next_lst;
for(lst= xorriso->filters; lst != NULL; lst= next_lst) {
filter= (struct Xorriso_extF *) Xorriso_lst_get_text(lst, 0);
Xorriso_lst_detach_text(lst, 0);
next_lst= Xorriso_lst_get_next(lst, 0);
Xorriso_lst_destroy(&lst, 0);
Xorriso_extf_destroy(xorriso, &filter, 0);
}
xorriso->filters= NULL;
return(1);
}
/*
@param flag bit0= return 2 if renaming is not possible by libisofs
(always: if demanded strip suffix is missing
or if suffix makes name length > 255)
bit1= strip suffix rather than appending it
*/
int Xorriso_rename_suffix(struct XorrisO *xorriso, IsoNode *node, char *suffix,
char *show_path, char new_name[], int flag)
{
int ret, lo= 0, ls= 0, strip_suffix;
char *old_name= NULL, *show_name;
strip_suffix= !!(flag & 2);
old_name= strdup((char *) iso_node_get_name(node));
show_name= old_name;
if(show_path != NULL)
if(show_path[0] != 0)
show_name= show_path;
lo= strlen(old_name);
ls= strlen(suffix);
if(strip_suffix) {
if(lo <= ls) {
/* refuse gracefully */
ret= 2; goto ex;
}
if(strcmp(old_name + lo - ls, suffix) != 0) {
ret= 2; goto ex;
}
if(lo >= SfileadrL)
goto cannot_remove_suffix;
strcpy(new_name, old_name);
new_name[lo - ls]= 0;
ret = iso_node_set_name(node, new_name);
if (ret < 0) {
Xorriso_process_msg_queues(xorriso,0);
if (!(flag & 1))
Xorriso_report_iso_error(xorriso, "", ret,
"Error when renaming ISO node", 0, "FAILURE", 1);
cannot_remove_suffix:;
strcpy(xorriso->info_text, "-set_filter: Cannot remove suffix from ");
Text_shellsafe(show_name, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
(flag & 1) ? "WARNING" : "FAILURE", 0);
ret= 2 * (flag & 1); goto ex;
}
} else {
/* check whether suffix already present */
if(lo >= ls)
if(strcmp(old_name + lo - ls, suffix) == 0) {
/* refuse gracefully */
ret= 2; goto ex;
}
if(lo + ls > 255) {
cannot_append_suffix:;
strcpy(xorriso->info_text, "-set_filter: Cannot append suffix to ");
Text_shellsafe(show_name, xorriso->info_text, 1);
strcat(xorriso->info_text, ". Left unfiltered.");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
(flag & 1) ? "WARNING" : "FAILURE", 0);
ret= 2 * (flag & 1); goto ex;
}
sprintf(new_name, "%s%s", old_name, suffix);
ret = iso_node_set_name(node, new_name);
if (ret < 0) {
Xorriso_process_msg_queues(xorriso,0);
if (!(flag & 1))
Xorriso_report_iso_error(xorriso, "", ret,
"Error when renaming ISO node", 0, "FAILURE", 1);
goto cannot_append_suffix;
}
}
ret= 1;
ex:;
if(old_name != NULL)
free(old_name);
Xorriso_process_msg_queues(xorriso,0);
return(ret);
}
/*
@param flag bit0= return 2 if renaming is not possible
bit1= print pacifier messages
*/
int Xorriso_set_filter(struct XorrisO *xorriso, void *in_node,
char *path, char *filter_name, int flag)
{
int ret, strip_suffix= 0, strip_filter= 0, filter_ret= 0;
int explicit_suffix= 0, internal_filter= 0;
IsoNode *node;
IsoFile *file;
struct Xorriso_lsT *found_lst;
struct Xorriso_extF *found_filter;
IsoExternalFilterCommand *cmd = NULL;
char *old_name= NULL, new_name[SfileadrL], *suffix= "";
IsoStream *stream;
int is_renamed= 0;
new_name[0]= 0;
node= (IsoNode *) in_node;
if(node == NULL) {
ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0);
if(ret <= 0)
goto ex;
}
if(!LIBISO_ISREG(node)) {
strcpy(xorriso->info_text, "-set_filter: Not a regular data file node ");
Text_shellsafe(path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
ret= 0; goto ex;
}
file= (IsoFile *) node;
if(strncmp(filter_name, "--remove-all-filters", 20) == 0) {
strip_filter= 1;
strip_suffix= 1;
if(strlen(filter_name) > 21) {
strip_suffix= (filter_name[20] != '+');
suffix= filter_name + 21;
explicit_suffix= 1;
}
} else if(strcmp(filter_name, "--zisofs") == 0) {
internal_filter= 1;
} else if(strcmp(filter_name, "--zisofs-decode") == 0) {
internal_filter= 2;
} else if(strcmp(filter_name, "--gzip") == 0) {
internal_filter= 3;
suffix= ".gz";
strip_suffix= 0;
explicit_suffix= 1;
} else if(strcmp(filter_name, "--gunzip") == 0 ||
strcmp(filter_name, "--gzip-decode") == 0) {
internal_filter= 4;
suffix= ".gz";
strip_suffix= 1;
explicit_suffix= 1;
} else {
ret= Xorriso_lookup_extf(xorriso, filter_name, &found_lst, 0);
if(ret < 0)
goto ex;
if(ret == 0) {
strcpy(xorriso->info_text, "-set_filter: Not a registered filter name ");
Text_shellsafe(filter_name, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
found_filter= (struct Xorriso_extF *) Xorriso_lst_get_text(found_lst, 0);
cmd= found_filter->cmd;
suffix= cmd->suffix;
strip_suffix= cmd->behavior & 8;
}
if(suffix[0]) {
/* >>> would need full iso_rr_path of node for showing */;
old_name= strdup((char *) iso_node_get_name(node));
ret= Xorriso_rename_suffix(xorriso, node, suffix, path, new_name,
(flag & 1) | (strip_suffix ? 2 : 0));
if(ret <= 0 || ret == 2)
goto ex;
is_renamed= 1;
}
if(strip_filter) {
while(1) {
if(!explicit_suffix) {
stream= iso_file_get_stream(file);
if(strncmp(stream->class->type, "gzip", 4) == 0) {
suffix= ".gz";
strip_suffix= 1;
} else if(strncmp(stream->class->type, "pizg", 4) == 0) {
suffix= ".gz";
strip_suffix= 0;
} else {
ret= iso_stream_get_external_filter(stream, &cmd, 0);
if(ret > 0) {
suffix= cmd->suffix;
strip_suffix= !(cmd->behavior & 8);
}
}
if(suffix[0]) {
/* >>> would need the current renaming state of path */;
ret= Xorriso_rename_suffix(xorriso, node, suffix, NULL, new_name,
(flag & 1) | (strip_suffix << 1));
if(ret <= 0 || ret == 2)
goto ex;
}
}
ret= iso_file_remove_filter(file, 0);
if(ret != 1)
break;
}
filter_ret= 1;
} else if (internal_filter == 1 || internal_filter == 2) {
filter_ret = iso_file_add_zisofs_filter(file, 1 | (internal_filter & 2));
if(filter_ret < 0) {
Xorriso_process_msg_queues(xorriso,0);
if(!(internal_filter == 2 && filter_ret == ISO_ZISOFS_WRONG_INPUT))
Xorriso_report_iso_error(xorriso, "", filter_ret,
"Error when setting filter to ISO node", 0, "FAILURE", 1);
}
} else if (internal_filter == 3 || internal_filter == 4) {
filter_ret = iso_file_add_gzip_filter(file,
1 | ((internal_filter == 4) << 1));
if(filter_ret < 0) {
Xorriso_process_msg_queues(xorriso,0);
Xorriso_report_iso_error(xorriso, "", filter_ret,
"Error when setting filter to ISO node", 0, "FAILURE", 1);
}
} else {
#ifndef Xorriso_allow_extf_suiD
/* This is a final safety precaution before iso_file_add_external_filter()
performs fork() and executes the alleged filter program.
*/
if(getuid() != geteuid()) {
sprintf(xorriso->info_text,
"-set_filter: UID and EUID differ. Will not run external programs.");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
return(0);
}
#endif /* ! Xorriso_allow_extf_suiD */
filter_ret = iso_file_add_external_filter(file, cmd, 0);
if(filter_ret < 0) {
Xorriso_process_msg_queues(xorriso,0);
Xorriso_report_iso_error(xorriso, "", filter_ret,
"Error when setting filter to ISO node", 0, "FAILURE", 1);
}
}
if(filter_ret != 1 && new_name[0] && old_name != NULL) {
ret = iso_node_set_name(node, old_name);
if (ret < 0) {
Xorriso_process_msg_queues(xorriso,0);
if (!(flag & 1))
Xorriso_report_iso_error(xorriso, "", ret,
"Error when renaming ISO node", 0, "FAILURE", 1);
}
}
if(flag & 2) {
xorriso->pacifier_count++;
Xorriso_pacifier_callback(xorriso, "file filters processed",
xorriso->pacifier_count, xorriso->pacifier_total, "", 0);
}
if(filter_ret < 0) {
ret= 0; goto ex;
}
ret= filter_ret;
ex:;
if(old_name != NULL)
free(old_name);
Xorriso_process_msg_queues(xorriso,0);
return(ret);
}
/* @param flag bit0= delete filter with the given name
*/
int Xorriso_external_filter(struct XorrisO *xorriso,
char *name, char *options, char *path,
int argc, char **argv, int flag)
{
int ret, delete= 0, behavior= 0, extf_flag= 0, is_banned= 0;
char *what, *what_next, *suffix= "";
struct Xorriso_lsT *lst;
struct Xorriso_extF *found_filter, *new_filter= NULL;
#ifndef Xorriso_allow_external_filterS
/* To be controlled by: configure --enable-external-filters */
sprintf(xorriso->info_text, "%s : Banned at compile time.",
flag & 1 ? "-unregister_filter" : "-external_filter");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
sprintf(xorriso->info_text,
"This may be changed at compile time by ./configure option --enable-external-filters");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
is_banned= 1;
#endif /* ! Xorriso_allow_external_filterS */
#ifndef Xorriso_allow_extf_suiD
/* To be controlled by: configure --enable-external-filters-setuid */
if(getuid() != geteuid()) {
sprintf(xorriso->info_text,
"-set_filter: UID and EUID differ. Will not run external programs.");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
sprintf(xorriso->info_text,
"This may be changed at compile time by ./configure option --enable-external-filters-setuid");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
is_banned= 1;
}
#endif /* ! Xorriso_allow_extf_suiD */
if(is_banned)
return(0);
if(xorriso->filter_list_closed) {
sprintf(xorriso->info_text,
"%s : Banned by previous command -close_filter_list",
flag & 1 ? "-unregister_filter" : "-external_filter");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
if((!(flag & 1)) && path[0] != '/') {
sprintf(xorriso->info_text,
"-external_filter : Given command path does not begin by '/' : ");
Text_shellsafe(path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
delete= flag & 1;
ret= Xorriso_lookup_extf(xorriso, name, &lst, 0);
if(ret < 0)
return(ret);
if(ret > 0) {
if(delete) {
found_filter= (struct Xorriso_extF *) Xorriso_lst_get_text(lst, 0);
if(found_filter->cmd->refcount > 0) {
sprintf(xorriso->info_text,
"-external_filter: Cannot remove filter because it is in use by %.f nodes : ",
(double) found_filter->cmd->refcount);
Text_shellsafe(name, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
Xorriso_lst_detach_text(lst, 0);
if(xorriso->filters == lst)
xorriso->filters= Xorriso_lst_get_next(lst, 0);
Xorriso_lst_destroy(&lst, 0);
Xorriso_extf_destroy(xorriso, &found_filter, 0);
ret= 1; goto ex;
}
strcpy(xorriso->info_text,
"-external_filter: filter with given name already existing: ");
Text_shellsafe(name, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
if(delete) {
strcpy(xorriso->info_text,
"-external_filter: filter with given name does not exist: ");
Text_shellsafe(name, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
for(what= options; what!=NULL; what= what_next) {
what_next= strchr(what, ':');
if(what_next!=NULL) {
*what_next= 0;
what_next++;
}
if(strncmp(what, "default", 7) == 0) {
suffix= "";
behavior= 0;
} else if(strncmp(what, "suffix=", 7) == 0) {
suffix= what + 7;
} else if(strcmp(what, "remove_suffix") == 0) {
behavior|= 8;
} else if(strcmp(what, "if_nonempty") == 0) {
behavior|= 1;
} else if(strcmp(what, "if_reduction") == 0) {
behavior|= 2;
} else if(strcmp(what, "if_block_reduction") == 0) {
behavior|= 4;
} else if(strncmp(what, "used=", 5) == 0) {
; /* this is informational output from -status */
} else if(what[0]) {
strcpy(xorriso->info_text,
"-external_filter: unknown option ");
Text_shellsafe(what, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
}
ret= Xorriso_extf_new(xorriso, &new_filter, path, argc, argv, behavior,
suffix, name, extf_flag);
if(ret <= 0) {
could_not_create:;
strcpy(xorriso->info_text,
"-external_filter: Could not create filter object");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
goto ex;
}
ret= Xorriso_lst_append_binary(&(xorriso->filters), (char *) new_filter,0, 4);
if(ret <= 0)
goto could_not_create;
ret= 1;
ex:;
if(ret <= 0) {
if(new_filter != NULL)
Xorriso_extf_destroy(xorriso, &new_filter, 0);
}
return(ret);
}
int Xorriso_status_extf(struct XorrisO *xorriso, char *filter, FILE *fp,
int flag)
/*
bit1= do only report to fp
*/
{
int i, maxl= 4 * SfileadrL;
struct Xorriso_extF *extf;
struct Xorriso_lsT *lst;
char *line;
line= xorriso->result_line;
for(lst= xorriso->filters; lst != NULL; lst= Xorriso_lst_get_next(lst, 0)) {
extf= (struct Xorriso_extF *) Xorriso_lst_get_text(lst, 0);
strcpy(xorriso->result_line, "-external_filter ");
Text_shellsafe(extf->cmd->name, line, 1);
if(strlen(line) > maxl)
continue;
strcat(line, " ");
if(extf->cmd->suffix[0]) {
strcat(line, "suffix=");
Text_shellsafe(extf->cmd->suffix, line, 1);
if(strlen(line) > maxl)
continue;
strcat(line, ":");
}
if(extf->cmd->behavior & 8)
strcat(line, "remove_suffix:");
if(extf->cmd->behavior & 1)
strcat(line, "if_nonempty:");
if(extf->cmd->behavior & 2)
strcat(line, "if_reduction:");
if(extf->cmd->behavior & 4)
strcat(line, "if_block_reduction:");
sprintf(line + strlen(line), "used=%.f ", (double) extf->cmd->refcount);
if(strlen(line) > maxl)
continue;
Text_shellsafe(extf->cmd->path, line, 1);
if(strlen(line) > maxl)
continue;
for(i= 1; i < extf->cmd->argc; i++) {
strcat(line, " ");
Text_shellsafe(extf->cmd->argv[i], line, 1);
if(strlen(line) > maxl)
break;
}
if(i < extf->cmd->argc)
continue;
strcat(line, " --\n");
Xorriso_status_result(xorriso, filter, fp, flag&2);
}
if(xorriso->filter_list_closed) {
strcpy(line, "-close_filter_list\n");
Xorriso_status_result(xorriso, filter, fp, flag&2);
}
return(1);
}
int Xorriso_set_zisofs_params(struct XorrisO *xorriso, int flag)
{
int ret;
struct iso_zisofs_ctrl ctrl;
ctrl.version= 0;
ctrl.compression_level= xorriso->zlib_level;
if(xorriso->zisofs_block_size == (1 << 16))
ctrl.block_size_log2= 16;
else if(xorriso->zisofs_block_size == (1 << 17))
ctrl.block_size_log2= 17;
else
ctrl.block_size_log2= 15;
ret= iso_zisofs_set_params(&ctrl, 0);
Xorriso_process_msg_queues(xorriso,0);
if(ret < 0) {
Xorriso_report_iso_error(xorriso, "", ret,
"Error when setting zisofs parameters", 0, "FAILURE", 1);
return(0);
}
return(1);
}
int Xorriso_status_zisofs(struct XorrisO *xorriso, char *filter, FILE *fp,
int flag)
/*
bit0= do only report non-default settings
bit1= do only report to fp
*/
{
off_t ziso_count= 0, osiz_count= 0;
off_t gzip_count= 0, gunzip_count= 0;
iso_zisofs_get_refcounts(&ziso_count, &osiz_count, 0);
iso_gzip_get_refcounts(&gzip_count, &gunzip_count, 0);
if((flag & 1) && xorriso->zlib_level == xorriso->zlib_level_default &&
xorriso->zisofs_block_size == xorriso->zisofs_block_size_default &&
xorriso->zisofs_by_magic == 0 &&
ziso_count == 0 && osiz_count == 0 &&
gzip_count == 0 && gunzip_count == 0) {
if(filter == NULL)
return(2);
if(filter[0] == 0)
return 2;
}
sprintf(xorriso->result_line,
"-zisofs level=%d:block_size=%dk:by_magic=%s:ziso_used=%.f:osiz_used=%.f",
xorriso->zlib_level, xorriso->zisofs_block_size / 1024,
xorriso->zisofs_by_magic ? "on" : "off",
(double) ziso_count, (double) osiz_count);
sprintf(xorriso->result_line + strlen(xorriso->result_line),
":gzip_used=%.f:gunzip_used=%.f\n",
(double) gzip_count, (double) gunzip_count);
Xorriso_status_result(xorriso, filter, fp, flag&2);
return(1);
}

31
xorriso/filters.h Normal file
View File

@ -0,0 +1,31 @@
/* 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 functions which operate on
data filter objects.
*/
#ifndef Xorriso_pvt_filters_includeD
#define Xorriso_pvt_filters_includeD yes
int Xorriso_extf_new(struct XorrisO *xorriso, struct Xorriso_extF **filter,
char *path, int argc, char **argv, int behavior,
char *suffix, char *name, int flag);
int Xorriso_extf_destroy(struct XorrisO *xorriso, struct Xorriso_extF **filter,
int flag);
int Xorriso_lookup_extf(struct XorrisO *xorriso, char *name,
struct Xorriso_lsT **found_lst, int flag);
int Xorriso_rename_suffix(struct XorrisO *xorriso, IsoNode *node, char *suffix,
char *show_path, char new_name[], int flag);
#endif /* ! Xorriso_pvt_filters_includeD */

1178
xorriso/findjob.c Normal file

File diff suppressed because it is too large Load Diff

400
xorriso/findjob.h Normal file
View File

@ -0,0 +1,400 @@
/* 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.
*/
#ifndef Xorriso_pvt_findjob_includeD
#define Xorriso_pvt_findjob_includeD yes
#define Xorriso_findjob_on_expR yes
#ifdef Xorriso_findjob_on_expR
/*
A single Testnode.
*/
struct ExprtesT {
struct FindjoB *boss;
int invert; /* 0=normal 1=invert result */
/*
0= -false (with invert : -true)
1= -name char *arg1 (regex_t in *arg2)
2= -type char *arg1
3= -damaged
4= -lba_range int *arg1 int *arg2
5= -has_acl
6= -has_xattr
7= -has_aaip
8= -has_filter
9= -wanted_node IsoNode *arg1 (for internal use, arg1 not allocated)
10= -pending_data
11= -decision char *arg1 ("yes", "no")
12= -prune
13= -wholename char *arg1 (regex_t in *arg2)
14= -has_any_xattr
15= -has_md5
*/
int test_type;
void *arg1;
void *arg2;
};
/*
A computational node.
A tree of these nodes forms the expression.
Sequences of AND/OR operations form branches, brackets spawn new branches,
NOT inverts node's test resp. subtree result.
*/
struct ExprnodE {
struct ExprnodE *up;
char origin[8];
/* Operators */
int invert; /* 0=normal 1=invert own result (subtree or test, but not op) */
int assoc; /*
0= left : compute own value, combine with left value,
compute right value, combine with current value
1= right: compute own value, compute right value,
combine own and right, combine with left value
*/
int use_shortcuts; /* 0= evaluate all tests of -and and -or,
1= evaluate only until the combined result is known
*/
struct ExprnodE *left;
int left_op; /* 0=OR , 1=AND */
struct ExprnodE *right;
int right_op; /* see left_op */
/* Brackets : a pointer to the first node in a subchain */
struct ExprnodE *sub;
int is_if_then_else;
struct ExprnodE *true_branch;
struct ExprnodE *false_branch;
/* elementary test : if sub!=NULL , test is ignored */
struct ExprtesT *test;
/* Result */
int own_value;
int composed_value;
};
struct FindjoB {
char *start_path;
struct ExprnodE *test_tree;
struct ExprnodE *cursor;
int invert; /* 0=normal 1=set invert-property for next new test node */
int use_shortcuts;
/* 0= echo
1= rm (also rmdir)
2= rm_r
>>> 3= mv target
4= chown user
5= chgrp group
6= chmod mode_and mode_or
7= alter_date type date
8= lsdl
9= chown_r user
10= chgrp_r group
11= chmod_r mode_and mode_or
12= alter_date_r type date
13= find
14= compare disk_equivalent_of_start_path
15= in_iso iso_rr_equivalent_of_start_path
16= not_in_iso iso_rr_equiv
17= update disk_equiv
18= add_missing iso_rr_equiv
19= empty_iso_dir iso_rr_equiv
20= is_full_in_iso iso_rr_equiv
21= report_damage
22= report_lba
23= internal: memorize path of last matching node in found_path
24= getfacl
25= setfacl access_acl default_acl
26= getfattr
27= setfattr
28= set_filter name
29= show_stream
30= internal: count by xorriso->node_counter
31= internal: register in xorriso->node_array
32= internal: widen_hardlinks disk_equiv: update nodes marked in di_do_widen
33= get_any_xattr
34= get_md5
35= check_md5
36= make_md5
37= mkisofs_r
38= sort_weight number
*/
int action;
int prune;
/* action specific parameters */
char *target;
char *text_2;
uid_t user;
gid_t group;
mode_t mode_and, mode_or;
int type; /* see Xorriso_set_time flag, also used as weight */
time_t date;
char *found_path;
struct FindjoB *subjob;
/* Errors */
char errmsg[4096];
int errn; /*
>0 = UNIX errno
-1 = close_bracket: no bracket open
-2 = binary operator or closing bracket expected
-3 = unexpected binary operator or closing bracket
-4 = unsupported command
-5 = -then -elseif -else -endif without -if or at wrong place
*/
};
int Exprnode_destroy(struct ExprnodE **fnode, int flag);
int Exprnode_tree_value(struct XorrisO *xorriso, struct ExprnodE *fnode,
int left_value, void *node, char *name, char *path,
struct stat *boss_stbuf, struct stat *stbuf, int flag);
int Findjob_new(struct FindjoB **o, char *start_path, int flag);
int Findjob_destroy(struct FindjoB **o, int flag);
int Findjob_set_start_path(struct FindjoB *o, char *start_path, int flag);
int Findjob_get_start_path(struct FindjoB *o, char **start_path, int flag);
int Findjob_set_commit_filter_2(struct FindjoB *o, int flag);
int Findjob_set_lba_range(struct FindjoB *o, int start_lba, int count,
int flag);
int Findjob_set_wanted_node(struct FindjoB *o, void *wanted_node, int flag);
/* @param value -1= only undamaged files, 1= only damaged files
*/
int Findjob_set_damage_filter(struct FindjoB *o, int value, int flag);
int Findjob_set_decision(struct FindjoB *o, char *decision, int flag);
int Findjob_open_bracket(struct FindjoB *job, int flag);
int Findjob_close_bracket(struct FindjoB *job, int flag);
int Findjob_not(struct FindjoB *job, int flag);
int Findjob_and(struct FindjoB *job, int flag);
int Findjob_or(struct FindjoB *job, int flag);
int Findjob_if(struct FindjoB *job, int flag);
int Findjob_then(struct FindjoB *job, int flag);
int Findjob_else(struct FindjoB *job, int flag);
int Findjob_elseif(struct FindjoB *job, int flag);
int Findjob_endif(struct FindjoB *job, int flag);
int Findjob_test_2(struct XorrisO *xorriso, struct FindjoB *o,
void *node, char *name, char *path,
struct stat *boss_stbuf, struct stat *stbuf, int flag);
int Findjob_set_action_found_path(struct FindjoB *o, int flag);
/* @param flag bit0= recursive
*/
int Findjob_set_action_target(struct FindjoB *o, int action, char *target,
int flag);
/* @param flag bit0= recursive
*/
int Findjob_set_action_ad(struct FindjoB *o, int type, time_t date, int flag);
/* @param flag bit0= recursive
*/
int Findjob_set_action_chgrp(struct FindjoB *o, gid_t group, int flag);
/* @param flag bit0= recursive
*/
int Findjob_set_action_chmod(struct FindjoB *o,
mode_t mode_and, mode_t mode_or, int flag);
/* @param flag bit0= recursive
*/
int Findjob_set_action_chown(struct FindjoB *o, uid_t user,int flag);
/* @param flag bit0= -wholename rather than -name
*/
int Findjob_set_name_expr(struct FindjoB *o, char *name_expr, int flag);
int Findjob_set_file_type(struct FindjoB *o, char file_type, int flag);
/* @param value -1= files without ACL, 1= only files with ACL
*/
int Findjob_set_acl_filter(struct FindjoB *o, int value, int flag);
/* @param value -1= files without xattr, 1= only files with xattr
@param flag bit0=-has_any_xattr rather than -has_xattr
*/
int Findjob_set_xattr_filter(struct FindjoB *o, int value, int flag);
/* @param value -1= files without aaip, 1= only files with aaip
*/
int Findjob_set_aaip_filter(struct FindjoB *o, int value, int flag);
/* @param value -1= files without filter, 1= files with filter
*/
int Findjob_set_filter_filter(struct FindjoB *o, int value, int flag);
/* @param value -1= only without property, 1= only with property
@param flag bit0= pseudo-test:
if no operator is open, do nothing and return 2
*/
int Findjob_set_prop_filter(struct FindjoB *o, int test_type, int value,
int flag);
/* @param value -1= true, 1= false
@param flag bit0= pseudo-test:
if no operator is open, do nothing and return 2
*/
int Findjob_set_false(struct FindjoB *o, int value, int flag);
int Findjob_set_prune(struct FindjoB *o, int flag);
int Findjob_set_action_subjob(struct FindjoB *o, int action,
struct FindjoB *subjob, int flag);
int Findjob_set_action_text_2(struct FindjoB *o, int action, char *target,
char* text_2, int flag);
int Findjob_set_action_type(struct FindjoB *o, int action, int type, int flag);
int Findjob_get_action(struct FindjoB *o, int flag);
int Findjob_get_action_parms(struct FindjoB *o, char **target, char **text_2,
uid_t *user, gid_t *group,
mode_t *mode_and, mode_t *mode_or,
int *type, time_t *date, struct FindjoB **subjob,
int flag);
int Findjob_set_found_path(struct FindjoB *o, char *path, int flag);
int Findjob_get_found_path(struct FindjoB *o, char **path, int flag);
#else /* Xorriso_findjob_on_expR */
struct FindjoB;
int Findjob_new(struct FindjoB **o, char *start_path, int flag);
int Findjob_destroy(struct FindjoB **job, int flag);
/* @return 0=no match , 1=match , <0 = error
*/
int Findjob_test(struct FindjoB *job, char *name,
struct stat *boss_stbuf, struct stat *stbuf,
int depth, int flag);
/* @return <0 error, >=0 see xorriso.c struct FindjoB.action
*/
int Findjob_get_action(struct FindjoB *o, int flag);
/* @return <0 error, >=0 see xorriso.c struct FindjoB.action
*/
int Findjob_get_action_parms(struct FindjoB *o, char **target, char **text_2,
uid_t *user, gid_t *group,
mode_t *mode_and, mode_t *mode_or,
int *type, time_t *date, struct FindjoB **subjob,
int flag);
/* @param flag bit0= recursive
*/
int Findjob_set_action_target(struct FindjoB *o, int action, char *target,
int flag);
/* @param flag bit0= recursive
*/
int Findjob_set_action_chgrp(struct FindjoB *o, gid_t group, int flag);
/* @param flag bit0= recursive
*/
int Findjob_set_action_chmod(struct FindjoB *o,
mode_t mode_and, mode_t mode_or, int flag);
/* @param flag bit0= recursive
*/
int Findjob_set_action_ad(struct FindjoB *o, int type, time_t date, int flag);
int Findjob_set_start_path(struct FindjoB *o, char *start_path, int flag);
int Findjob_set_action_found_path(struct FindjoB *o, int flag);
int Findjob_get_start_path(struct FindjoB *o, char **start_path, int flag);
int Findjob_set_lba_range(struct FindjoB *o, int start_lba, int count,
int flag);
int Findjob_get_lba_damage_filter(struct FindjoB *o, int *start_lba,
int *end_lba, int *damage_filter, int flag);
int Findjob_get_commit_filter(struct FindjoB *o, int *commit_filter, int flag);
int Findjob_get_acl_filter(struct FindjoB *o, int *acl_filter, int flag);
int Findjob_get_xattr_filter(struct FindjoB *o, int *xattr_filter, int flag);
int Findjob_get_aaip_filter(struct FindjoB *o, int *aaip_filter, int flag);
int Findjob_get_filter_filter(struct FindjoB *o, int *value, int flag);
int Findjob_set_wanted_node(struct FindjoB *o, void *wanted_node, int flag);
int Findjob_get_wanted_node(struct FindjoB *o, void **wanted_node, int flag);
int Findjob_set_found_path(struct FindjoB *o, char *path, int flag);
int Findjob_get_found_path(struct FindjoB *o, char **path, int flag);
#endif /* ! Xorriso_findjob_on_expR */
#endif /* ! Xorriso_pvt_findjob_includeD */

950
xorriso/iso_img.c Normal file
View File

@ -0,0 +1,950 @@
/* 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 operate on ISO images and their
global properties.
*/
#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 <sys/wait.h>
#include "xorriso.h"
#include "xorriso_private.h"
#include "xorrisoburn.h"
#include "lib_mgt.h"
#include "iso_img.h"
#include "iso_tree.h"
#include "drive_mgt.h"
int Xorriso_set_ignore_aclea(struct XorrisO *xorriso, int flag)
{
int ret, hflag;
IsoImage *volume;
ret= Xorriso_get_volume(xorriso, &volume, 1);
if(ret<=0)
return(ret);
hflag= (~xorriso->do_aaip) & 1;
if((xorriso->ino_behavior & (1 | 2)) && !(xorriso->do_aaip & (4 | 16)))
hflag|= 2;
iso_image_set_ignore_aclea(volume, hflag);
return(1);
}
int Xorriso_update_volid(struct XorrisO *xorriso, int flag)
{
int gret, sret= 1;
gret= Xorriso_get_volid(xorriso, xorriso->loaded_volid, 0);
if(gret<=0 || (!xorriso->volid_default) || xorriso->loaded_volid[0]==0)
sret= Xorriso_set_volid(xorriso, xorriso->volid, 1);
return(gret>0 && sret>0);
}
int Xorriso_create_empty_iso(struct XorrisO *xorriso, int flag)
{
int ret;
IsoImage *volset;
struct isoburn_read_opts *ropts;
struct burn_drive_info *dinfo= NULL;
struct burn_drive *drive= NULL;
if(xorriso->out_drive_handle != NULL) {
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to attach volset to drive", 2);
if(ret<=0)
return(ret);
}
if(xorriso->in_volset_handle!=NULL) {
iso_image_unref((IsoImage *) xorriso->in_volset_handle);
xorriso->in_volset_handle= NULL;
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
Xorriso_destroy_di_array(xorriso, 0);
Xorriso_destroy_hln_array(xorriso, 0);
xorriso->loaded_volid[0]= 0;
xorriso->volset_change_pending= 0;
xorriso->no_volset_present= 0;
}
ret= isoburn_ropt_new(&ropts, 0);
if(ret<=0)
return(ret);
/* Note: no return before isoburn_ropt_destroy() */
isoburn_ropt_set_extensions(ropts, isoburn_ropt_pretend_blank);
isoburn_ropt_set_input_charset(ropts, xorriso->in_charset);
isoburn_set_read_pacifier(drive, NULL, NULL);
ret= isoburn_read_image(drive, ropts, &volset);
Xorriso_process_msg_queues(xorriso,0);
isoburn_ropt_destroy(&ropts, 0);
if(ret<=0) {
sprintf(xorriso->info_text, "Failed to create new empty ISO image object");
Xorriso_report_iso_error(xorriso, "", ret, xorriso->info_text, 0, "FATAL",
0);
return(-1);
}
xorriso->in_volset_handle= (void *) volset;
xorriso->in_sector_map= NULL;
Xorriso_update_volid(xorriso, 0);
xorriso->volset_change_pending= 0;
xorriso->no_volset_present= 0;
return(1);
}
int Xorriso_record_boot_info(struct XorrisO *xorriso, int flag)
{
int ret;
struct burn_drive_info *dinfo;
struct burn_drive *drive;
IsoImage *image;
ElToritoBootImage *bootimg;
IsoFile *bootimg_node;
IsoBoot *bootcat_node;
xorriso->loaded_boot_bin_lba= -1;
xorriso->loaded_boot_cat_path[0]= 0;
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to record boot LBAs", 0);
if(ret<=0)
return(0);
image= isoburn_get_attached_image(drive);
if(image == NULL)
return(0);
ret= iso_image_get_boot_image(image, &bootimg,
&bootimg_node, &bootcat_node);
iso_image_unref(image); /* release obtained reference */
if(ret != 1)
return(0);
if(bootimg_node != NULL)
Xorriso__file_start_lba((IsoNode *) bootimg_node,
&(xorriso->loaded_boot_bin_lba), 0);
if(bootcat_node != NULL)
Xorriso_path_from_lba(xorriso, (IsoNode *) bootcat_node, 0,
xorriso->loaded_boot_cat_path, 0);
return(1);
}
int Xorriso_assert_volid(struct XorrisO *xorriso, int msc1, int flag)
{
int ret, image_blocks;
char volid[33];
struct burn_drive_info *dinfo;
struct burn_drive *drive;
if(xorriso->assert_volid[0] == 0)
return(1);
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to perform -assert_volid", 0);
if(ret<=0)
return(0);
ret= isoburn_read_iso_head(drive, msc1, &image_blocks, volid, 1);
Xorriso_process_msg_queues(xorriso,0);
if(ret <= 0) {
sprintf(xorriso->info_text,
"-assert_volid: Cannot determine Volume Id at LBA %d.", msc1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
xorriso->assert_volid_sev, 0);
return(0);
}
ret= Sregex_match(xorriso->assert_volid, volid, 0);
if(ret < 0)
return(2);
if(ret == 0) {
strcpy(xorriso->info_text,
"-assert_volid: Volume id does not match pattern: ");
Text_shellsafe(xorriso->assert_volid, xorriso->info_text, 1);
strcat(xorriso->info_text, " <> ");
Text_shellsafe(volid, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
xorriso->assert_volid_sev, 0);
return(0);
}
return(ret);
}
/* @return <0 yes , 0 no , <0 error */
int Xorriso_is_isohybrid(struct XorrisO *xorriso, IsoFile *bootimg_node,
int flag)
{
int ret;
unsigned char buf[68];
void *data_stream= NULL;
ret= Xorriso_iso_file_open(xorriso, "", (void *) bootimg_node,
&data_stream, 1);
if(ret <= 0)
return(-1);
ret= Xorriso_iso_file_read(xorriso, data_stream, (char *) buf, 68, 0);
Xorriso_iso_file_close(xorriso, &data_stream, 0);
if(ret <= 0)
return(0);
if(buf[64] == 0xfb && buf[65] == 0xc0 && buf[66] == 0x78 && buf[67] == 0x70)
return(1);
return(0);
}
int Xorriso_image_has_md5(struct XorrisO *xorriso, int flag)
{
int ret;
IsoImage *image;
uint32_t start_lba, end_lba;
char md5[16];
ret= Xorriso_get_volume(xorriso, &image, 0);
if(ret<=0)
return(ret);
ret= iso_image_get_session_md5(image, &start_lba, &end_lba, md5, 0);
Xorriso_process_msg_queues(xorriso,0);
if(ret <= 0)
return(0);
return(1);
}
static const char *un0(const char *text)
{
if(text == NULL)
return("");
return(text);
}
int Xorriso_pvd_info(struct XorrisO *xorriso, int flag)
{
int ret, msc1= -1, msc2, i;
IsoImage *image;
struct burn_drive_info *dinfo;
struct burn_drive *drive;
char *msg, block_head[8];
off_t head_count;
msg= xorriso->result_line;
ret= Xorriso_get_volume(xorriso, &image, 0);
if(ret<=0)
return(ret);
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, "", 16);
if(ret > 0) {
ret= Xorriso_msinfo(xorriso, &msc1, &msc2, 1 | 4);
if(ret<0)
return(ret);
Xorriso_toc(xorriso, 128);
if(msc1 >= 0) {
for(i = msc1 + 16; i < msc1 + 32; i++) {
ret= burn_read_data(drive, (off_t) i * (off_t) 2048, block_head,
(off_t) sizeof(block_head), &head_count, 2);
if(ret <= 0) {
i= msc1 + 32;
break;
}
if(block_head[0] == 1 && strncmp(block_head + 1, "CD001", 5) == 0)
break;
}
if(i < msc1 + 32) {
sprintf(msg, "PVD address : %ds\n", i);
Xorriso_result(xorriso,0);
}
}
}
sprintf(msg, "Volume Id : %s\n", un0(iso_image_get_volume_id(image)));
Xorriso_result(xorriso,0);
sprintf(msg, "Volume Set Id: %s\n", xorriso->volset_id);
Xorriso_result(xorriso,0);
sprintf(msg, "Publisher Id : %s\n", xorriso->publisher);
Xorriso_result(xorriso,0);
sprintf(msg, "Preparer Id : %s\n",
un0(iso_image_get_data_preparer_id(image)));
Xorriso_result(xorriso,0);
sprintf(msg, "App Id : %s\n", xorriso->application_id);
Xorriso_result(xorriso,0);
sprintf(msg, "System Id : %s\n", xorriso->system_id);
Xorriso_result(xorriso,0);
sprintf(msg, "Copyright Id : %s\n",
un0(iso_image_get_copyright_file_id(image)));
Xorriso_result(xorriso,0);
sprintf(msg, "Abstract Id : %s\n",
un0(iso_image_get_abstract_file_id(image)));
Xorriso_result(xorriso,0);
sprintf(msg, "Biblio Id : %s\n", un0(iso_image_get_biblio_file_id(image)));
Xorriso_result(xorriso,0);
return(1);
}
/* @param flag bit0= do not mark image as changed */
int Xorriso_set_volid(struct XorrisO *xorriso, char *volid, int flag)
{
int ret;
IsoImage *volume;
if(xorriso->in_volset_handle == NULL)
return(2);
ret= Xorriso_get_volume(xorriso, &volume, 0);
if(ret<=0)
return(ret);
iso_image_set_volume_id(volume, volid);
if(!(flag&1))
Xorriso_set_change_pending(xorriso, 1);
Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text,"Volume ID: '%s'",iso_image_get_volume_id(volume));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
return(1);
}
int Xorriso_get_volid(struct XorrisO *xorriso, char volid[33], int flag)
{
int ret;
IsoImage *volume;
ret= Xorriso_get_volume(xorriso, &volume, 0);
if(ret<=0)
return(ret);
strncpy(volid, iso_image_get_volume_id(volume), 32);
volid[32]= 0;
return(1);
}
/*
bit0= do only report non-default settings
bit1= do only report to fp
bit2= is_default
bit3= append -boot_image any next
bit4= eventually concentrate boot options
*/
int Xorriso_boot_item_status(struct XorrisO *xorriso, char *cat_path,
char *bin_path, int platform_id,
int patch_isolinux, int emul, off_t load_size,
unsigned char *id_string,
unsigned char *selection_crit, char *form,
char *filter, FILE *fp, int flag)
{
int is_default, no_defaults, i, is_default_id= 0, ret;
char *line, bspec[SfileadrL + 80], zeros[28];
off_t file_size;
struct stat stbuf;
no_defaults= flag & 1;
line= xorriso->result_line;
if(flag & 16) {
/* Allow to concentrate boot options. */
memset(zeros, 0, 28);
if(memcmp(id_string, zeros, 28) == 0 &&
memcmp(selection_crit, zeros, 20) == 0)
is_default_id= 1;
/* -boot_image isolinux dir= ... */
bspec[0]= 0;
if(strcmp(form, "isolinux") != 0 && strcmp(form, "any") != 0)
;
else if(strcmp(bin_path, "/isolinux.bin") == 0 &&
strcmp(cat_path, "/boot.cat") == 0)
strcpy(bspec, "dir=/");
else if(strcmp(bin_path, "/isolinux/isolinux.bin") == 0 &&
strcmp(cat_path, "/isolinux/boot.cat") == 0)
strcpy(bspec, "dir=/isolinux");
else if(strcmp(xorriso->boot_image_bin_path,
"/boot/isolinux/isolinux.bin") == 0
&& strcmp(xorriso->boot_image_cat_path,
"/boot/isolinux/boot.cat") == 0)
strcpy(bspec, "dir=/boot/isolinux");
memset(zeros, 0, 28);
if(bspec[0] && platform_id == 0 && patch_isolinux &&
load_size == 2048 && is_default_id) {
sprintf(line, "-boot_image isolinux %s\n", bspec);
Xorriso_status_result(xorriso,filter,fp,flag&2);
return(1);
}
file_size= 0;
ret= Xorriso_iso_lstat(xorriso, bin_path, &stbuf, 2 | 4);
if(ret == 0)
file_size= ((stbuf.st_size / (off_t) 512) +
!!(stbuf.st_size % (off_t) 512)) * 512;
if(platform_id == 0xef && !patch_isolinux &&
load_size == file_size && is_default_id) {
sprintf(line, "-boot_image any efi_path=");
Text_shellsafe(bin_path, line, 1);
strcat(line, "\n");
Xorriso_status_result(xorriso,filter,fp,flag&2);
return(1);
}
}
is_default= (bin_path[0] == 0) || (flag & 4);
sprintf(line, "-boot_image %s bin_path=", form);
Text_shellsafe(bin_path, line, 1);
strcat(line, "\n");
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2);
is_default= (platform_id == 0 || (flag & 4));
sprintf(line, "-boot_image %s platform_id=0x%-2.2x\n", form, platform_id);
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2);
is_default= ((patch_isolinux & 1) == 0 || bin_path[0] == 0 || (flag & 4));
sprintf(line, "-boot_image %s boot_info_table=%s\n",
(patch_isolinux & 2) ? "grub" : form, patch_isolinux ? "on" : "off");
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2);
is_default= (load_size == 2048 || (flag & 4));
sprintf(line, "-boot_image %s load_size=%lu\n",
form, (unsigned long) load_size);
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2);
is_default= 1;
if(!(flag & 4))
for(i= 0; i < 20; i++)
if(selection_crit[i])
is_default= 0;
sprintf(line, "-boot_image %s sel_crit=", form);
for(i= 0; i < 20; i++)
sprintf(line + strlen(line), "%-2.2X", (unsigned int) selection_crit[i]);
strcat(line, "\n");
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2);
is_default= 1;
if(!(flag & 4))
for(i= 0; i < 28; i++)
if(id_string[i])
is_default= 0;
sprintf(line, "-boot_image %s id_string=", form);
for(i= 0; i < 28; i++)
sprintf(line + strlen(line), "%-2.2X", (unsigned int) id_string[i]);
strcat(line, "\n");
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2);
return(1);
}
/*
bit0= do only report non-default settings
bit1= do only report to fp
*/
int Xorriso_boot_image_status(struct XorrisO *xorriso, char *filter, FILE *fp,
int flag)
{
int ret, i, num_boots, hflag;
int bin_path_in_use= 0, is_default, no_defaults;
char sfe[5*SfileadrL], path[SfileadrL], *form= "any", *line;
struct burn_drive_info *dinfo;
struct burn_drive *drive;
IsoImage *image= NULL;
ElToritoBootImage **boots = NULL;
IsoFile **bootnodes = NULL;
int platform_id, patch, load_size;
enum eltorito_boot_media_type media_type;
unsigned char id_string[29], sel_crit[21];
line= xorriso->result_line;
no_defaults= flag & 1;
if(xorriso->boot_count == 0 && xorriso->boot_image_bin_path[0] == 0) {
if(xorriso->patch_isolinux_image & 1) {
sprintf(line, "-boot_image %s patch\n",
xorriso->patch_isolinux_image & 2 ? "grub" : form);
is_default= 0;
} else if(xorriso->keep_boot_image) {
sprintf(line, "-boot_image %s keep\n", form);
is_default= 0;
} else {
sprintf(line, "-boot_image %s discard\n", form);
is_default= 1;
}
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2);
ret= 1; goto ex;
}
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to print boot info", 16);
if(ret<=0)
{ret= 0; goto ex;}
image= isoburn_get_attached_image(drive);
Xorriso_process_msg_queues(xorriso,0);
if(image == NULL)
{ret= 0; goto ex;}
if(xorriso->boot_image_bin_path[0] || xorriso->boot_count > 0)
bin_path_in_use= 1;
if(xorriso->boot_image_cat_path[0] && bin_path_in_use) {
is_default= 0;
sprintf(line,"-boot_image %s cat_path=%s\n",
form, Text_shellsafe(xorriso->boot_image_cat_path, sfe, 0));
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2);
}
if(xorriso->boot_count > 0) {
/* show attached boot image info */;
ret= iso_image_get_all_boot_imgs(image, &num_boots, &boots, &bootnodes, 0);
Xorriso_process_msg_queues(xorriso,0);
if(ret == 1 && num_boots > 0) {
for(i= 0; i < num_boots; i++) {
ret= Xorriso_path_from_node(xorriso, (IsoNode *) bootnodes[i], path, 0);
if(ret <= 0)
continue;
platform_id= el_torito_get_boot_platform_id(boots[i]);
patch= el_torito_get_isolinux_options(boots[i], 0);
el_torito_get_boot_media_type(boots[i], &media_type);
load_size= el_torito_get_load_size(boots[i]) * 512;
el_torito_get_id_string(boots[i], id_string);
el_torito_get_selection_crit(boots[i], sel_crit);
ret= Xorriso_boot_item_status(xorriso, xorriso->boot_image_cat_path,
path, platform_id, patch & 1, media_type,
load_size, id_string, sel_crit, "any",
filter, fp, 16 | (flag & 3));
if(ret <= 0)
continue;
sprintf(line,"-boot_image %s next\n", form);
Xorriso_status_result(xorriso,filter,fp,flag&2);
}
}
}
/* Show pending boot image info */
if(strcmp(xorriso->boot_image_bin_form, "isolinux") == 0 ||
strcmp(xorriso->boot_image_bin_form, "grub") == 0)
form= xorriso->boot_image_bin_form;
if(xorriso->boot_count > 0 &&
xorriso->boot_platform_id == 0 &&
xorriso->patch_isolinux_image == 0 &&
xorriso->boot_image_bin_path[0] == 0 &&
xorriso->boot_image_emul == 0 &&
xorriso->boot_image_load_size == 4 * 512) {
for(i= 0; i < 20; i++)
if(xorriso->boot_selection_crit[i])
break;
if(i >= 20)
for(i= 0; i < 28; i++)
if(xorriso->boot_id_string[i])
break;
if(i >= 28)
{ret= 1; goto ex;} /* Images registered, pending is still default */
}
hflag= 16;
if(xorriso->boot_platform_id == 0xef && !xorriso->boot_efi_default)
hflag= 0;
ret= Xorriso_boot_item_status(xorriso, xorriso->boot_image_cat_path,
xorriso->boot_image_bin_path, xorriso->boot_platform_id,
xorriso->patch_isolinux_image, xorriso->boot_image_emul,
xorriso->boot_image_load_size, xorriso->boot_id_string,
xorriso->boot_selection_crit, form,
filter, fp, hflag | (flag & 3));
if(ret <= 0)
goto ex;
ret= 1;
ex:
if(boots != NULL)
free(boots);
if(bootnodes != NULL)
free(bootnodes);
return(ret);
}
int Xorriso__append_boot_params(char *line, ElToritoBootImage *bootimg,
int flag)
{
unsigned int platform_id;
platform_id= el_torito_get_boot_platform_id(bootimg);
if(platform_id != 0)
sprintf(line + strlen(line),
" , platform_id=0x%-2.2X ", (unsigned int) platform_id);
if(el_torito_seems_boot_info_table(bootimg, 0))
sprintf(line + strlen(line), " , boot_info_table=on");
return(1);
}
/* @param flag bit0= no output if no boot record was found
bit1= short form
bit3= report to info channel (else to result channel)
*/
int Xorriso_show_boot_info(struct XorrisO *xorriso, int flag)
{
int ret, bin_path_valid= 0,has_isolinux_mbr= 0, i, num_boots;
unsigned int mbr_lba= 0;
off_t lb0_count;
char *respt, sfe[5*SfileadrL], path[SfileadrL];
unsigned char lb0[2048];
struct burn_drive_info *dinfo;
struct burn_drive *drive;
IsoImage *image= NULL;
ElToritoBootImage *bootimg, **boots = NULL;
IsoFile *bootimg_node, **bootnodes = NULL;
IsoBoot *bootcat_node;
respt= xorriso->result_line;
if(xorriso->boot_count > 0) {
if(!(flag & 1)) {
sprintf(respt, "Boot record : overridden by -boot_image any next\n");
Xorriso_toc_line(xorriso, flag & 8);
}
ret= 1; goto ex;
}
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to print boot info", 16);
if(ret<=0)
goto no_boot;
image= isoburn_get_attached_image(drive);
if(image == NULL) {
ret= 0;
no_boot:;
if(!(flag & 1)) {
sprintf(respt, "Boot record : none\n");
Xorriso_toc_line(xorriso, flag & 8);
}
goto ex;
}
/* Using the nodes with extreme care . They might be deleted meanwhile. */
ret= iso_image_get_boot_image(image, &bootimg, &bootimg_node, &bootcat_node);
if(ret != 1)
goto no_boot;
ret= Xorriso_path_from_lba(xorriso, NULL, xorriso->loaded_boot_bin_lba,
path, 1);
if(ret > 0)
bin_path_valid= 1;
sprintf(respt, "Boot record : El Torito");
if(bin_path_valid)
ret= Xorriso_is_isohybrid(xorriso, bootimg_node, 0);
else
ret= 0;
if(ret > 0) {
/* Load and examine potential MBR */
ret= burn_read_data(drive, (off_t) 0, (char *) lb0, (off_t) 2048,
&lb0_count, 2);
if(ret > 0) {
has_isolinux_mbr= 1;
if(lb0[510] != 0x55 || lb0[511] != 0xaa)
has_isolinux_mbr= 0;
mbr_lba= lb0[432] | (lb0[433] << 8) | (lb0[434] << 16) | (lb0[435] << 24);
mbr_lba/= 4;
if(mbr_lba != xorriso->loaded_boot_bin_lba)
has_isolinux_mbr= 0;
if(has_isolinux_mbr) {
for(i= 0; i < 426; i++)
if(strncmp((char *) (lb0 + i), "isolinux", 8) == 0)
break;
if(i >= 426)
has_isolinux_mbr= 0;
}
for(i= 462; i < 510; i++)
if(lb0[i])
break;
if(i < 510)
has_isolinux_mbr= 0;
}
if(has_isolinux_mbr)
strcat(respt, " , ISOLINUX isohybrid MBR pointing to boot image");
else
strcat(respt, " , ISOLINUX boot image capable of isohybrid");
}
strcat(respt, "\n");
Xorriso_toc_line(xorriso, flag & 8);
if(flag & 2)
{ret= 1; goto ex;}
if(xorriso->loaded_boot_cat_path[0])
sprintf(respt, "Boot catalog : %s\n",
Text_shellsafe(xorriso->loaded_boot_cat_path, sfe, 0));
else
sprintf(respt, "Boot catalog : -not-found-at-load-time-\n");
Xorriso_toc_line(xorriso, flag & 8);
if(bin_path_valid)
sprintf(respt, "Boot image : %s", Text_shellsafe(path, sfe, 0));
else if(xorriso->loaded_boot_bin_lba <= 0)
sprintf(respt, "Boot image : -not-found-at-load-time-");
else
sprintf(respt, "Boot image : -not-found-any-more-by-lba=%d",
xorriso->loaded_boot_bin_lba);
Xorriso__append_boot_params(respt, bootimg, 0);
strcat(respt, "\n");
Xorriso_toc_line(xorriso, flag & 8);
ret= iso_image_get_all_boot_imgs(image, &num_boots, &boots, &bootnodes, 0);
Xorriso_process_msg_queues(xorriso,0);
if(ret == 1 && num_boots > 1) {
for(i= 1; i < num_boots; i++) {
ret= Xorriso_path_from_node(xorriso, (IsoNode *) bootnodes[i], path, 0);
if(ret > 0)
sprintf(respt, "Boot image : %s", Text_shellsafe(path, sfe, 0));
else
sprintf(respt, "Boot image : -not-found-any-more-");
Xorriso__append_boot_params(respt, boots[i], 0);
strcat(respt, "\n");
Xorriso_toc_line(xorriso, flag & 8);
}
}
ret= 1;
ex:;
if(boots != NULL)
free(boots);
if(bootnodes != NULL);
free(bootnodes);
if(image != NULL)
iso_image_unref(image); /* release obtained reference */
return(ret);
}
/* @param flag bit0=silently return 0 if no volume/image is present
*/
int Xorriso_get_volume(struct XorrisO *xorriso, IsoImage **volume,
int flag)
{
if(xorriso->in_volset_handle==NULL) {
if(flag & 1)
return(0);
Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text,"No ISO image present.");
if(xorriso->indev[0]==0 && xorriso->outdev[0]==0)
sprintf(xorriso->info_text+strlen(xorriso->info_text),
" No -dev, -indev, or -outdev selected.");
else
sprintf(xorriso->info_text+strlen(xorriso->info_text),
" Possible program error with drive '%s'.", xorriso->indev);
if(!xorriso->no_volset_present)
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
xorriso->no_volset_present= 1;
return(0);
}
*volume= (IsoImage *) xorriso->in_volset_handle;
xorriso->no_volset_present= 0;
return(*volume != NULL);
}
int Xorriso_change_is_pending(struct XorrisO *xorriso, int flag)
{
return(!!xorriso->volset_change_pending);
}
/* @param flag bit0= do not set hln_change_pending */
int Xorriso_set_change_pending(struct XorrisO *xorriso, int flag)
{
int ret;
IsoImage *image;
ret= Xorriso_get_volume(xorriso, &image, 1);
if(ret <= 0)
return ret;
xorriso->volset_change_pending= 1;
if(!(flag & 1))
xorriso->hln_change_pending= 1;
return(1);
}
/**
@param flag bit0= print mount command to result channel rather than
performing it
bit1= do not allow prefixes with cmd
bit2= interpret unprefixed cmd as shell:
*/
int Xorriso_mount(struct XorrisO *xorriso, char *dev, int adr_mode,
char *adr_value, char *cmd, int flag)
{
int ret, lba, track, session, params_flag= 0, is_safe= 0, is_extra_drive= 0;
int give_up= 0, mount_chardev= 0, status;
char volid[33], *devadr, mount_command[SfileadrL], adr_data[163], *adr_pt;
char *dev_path, libburn_adr[BURN_DRIVE_ADR_LEN + SfileadrL];
char sfe[5 * SfileadrL], *dpt, *sysname= "";
struct stat stbuf;
struct burn_drive_info *dinfo= NULL;
struct burn_drive *drive= NULL;
devadr= dev;
adr_pt= adr_value;
if(strcmp(dev, "indev") == 0) {
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to perform -mount \"indev\"", 0);
if(ret<=0)
goto ex;
dev_path= devadr= xorriso->indev;
if(strncmp(dev_path, "stdio:", 6) == 0)
dev_path+= 6;
if(xorriso->in_drive_handle == xorriso->out_drive_handle)
give_up= 3;
else
give_up= 1;
} else if(strcmp(dev, "outdev") == 0) {
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to perform -mount \"outdev\"",
2);
if(ret<=0)
goto ex;
dev_path= devadr= xorriso->outdev;
if(strncmp(dev_path, "stdio:", 6) == 0)
dev_path+= 6;
if(xorriso->in_drive_handle == xorriso->out_drive_handle)
give_up= 3;
else
give_up= 2;
} else {
is_extra_drive= 1;
dev_path= dev;
if(strncmp(dev_path, "stdio:", 6) == 0)
dev_path+= 6;
/* do only accept regular files and block devices */
ret= stat(dev_path, &stbuf);
if(ret == -1) {
sprintf(xorriso->info_text, "Cannot determine properties of file %s",
Text_shellsafe(dev_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
ret= System_uname(&sysname, NULL, NULL, NULL, 0);
if(ret > 0 && strcmp(sysname, "FreeBSD") == 0)
mount_chardev= 1;
if(!(S_ISREG(stbuf.st_mode) || (S_ISBLK(stbuf.st_mode) && !mount_chardev)
|| (S_ISCHR(stbuf.st_mode) && !mount_chardev))) {
sprintf(xorriso->info_text,
"File object is not suitable as mount device: %s",
Text_shellsafe(dev_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
/* Aquire drive as direct libburn address or via stdio: prefix */
ret= burn_drive_convert_fs_adr(dev, libburn_adr);
Xorriso_process_msg_queues(xorriso,0);
if(ret < 0)
{ret= -1; goto ex;}
if(ret == 0 && strncmp(dev, "stdio:", 6) != 0)
sprintf(libburn_adr, "stdio:%s", dev);
burn_preset_device_open(xorriso->drives_exclusive, 0, 0);
ret= isoburn_drive_aquire(&dinfo, libburn_adr, 1);
burn_preset_device_open(1, 0, 0);
Xorriso_process_msg_queues(xorriso,0);
if(ret <= 0)
{ret= 0; goto ex;}
drive= dinfo[0].drive;
}
if(adr_mode == 4 && strlen(adr_pt) <= 80) {
ret= Xorriso__bourne_to_reg(adr_pt, adr_data, 0);
if(ret == 1) {
params_flag|= 4;
adr_pt= adr_data;
}
}
ret= isoburn_get_mount_params(drive, adr_mode, adr_pt, &lba, &track,
&session, volid, params_flag);
Xorriso_process_msg_queues(xorriso,0);
if(ret <= 0)
goto ex;
if(session <= 0 || track <= 0 || ret == 2) {
Xorriso_msgs_submit(xorriso, 0,
"-mount : Given address does not point to an ISO 9660 session",
0, "FAILURE", 0);
ret= 0; goto ex;
}
if(strstr(devadr, "stdio:") == devadr)
devadr+= 6;
ret= Xorriso_make_mount_cmd(xorriso, cmd, lba, track, session, volid, devadr,
mount_command, flag & (2 | 4));
if(ret <= 0)
goto ex;
if(ret == 2)
is_safe= 1;
if(is_extra_drive) {
isoburn_drive_release(drive, 0);
burn_drive_info_free(dinfo);
drive= NULL;
} else if(give_up > 0 && !((flag & 1) || (xorriso->mount_opts_flag & 1))) {
Xorriso_give_up_drive(xorriso, give_up);
if(ret <= 0)
goto ex;
}
Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text, "Volume id : %s\n",
Text_shellsafe(volid, sfe, 0));
Xorriso_info(xorriso, 0);
if(flag & 1) {
sprintf(xorriso->result_line, "%s\n", mount_command);
Xorriso_result(xorriso,0);
} else {
sprintf(xorriso->info_text, "Mount command: %s\n", mount_command);
Xorriso_info(xorriso, 0);
if(!is_safe) {
Xorriso_msgs_submit(xorriso, 0,
"-mount : Will not perform mount command which stems from command template.",
0, "SORRY", 0);
sprintf(xorriso->result_line, "%s\n", mount_command);
Xorriso_result(xorriso,0);
} else {
ret= Xorriso_execv(xorriso, mount_command, "/bin:/sbin", &status, 1);
if(WIFEXITED(status) && WEXITSTATUS(status) != 0) {
sprintf(xorriso->info_text,
"-mount : mount command failed with exit value %d",
(int) WEXITSTATUS(ret));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
sprintf(xorriso->info_text, "\nMounted session %d of device %s",
session, Text_shellsafe(dev_path, sfe, 0));
dpt= strchr(cmd, ':');
if(dpt == NULL)
dpt= cmd ;
else
dpt++;
sprintf(xorriso->info_text + strlen(xorriso->info_text),
" as directory %s\n", Text_shellsafe(dpt, sfe, 0));
Xorriso_info(xorriso, 0);
}
}
ret= 1;
ex:;
if(is_extra_drive && drive != NULL) {
isoburn_drive_release(drive, 0);
burn_drive_info_free(dinfo);
Xorriso_process_msg_queues(xorriso,0);
}
return(ret);
}

44
xorriso/iso_img.h Normal file
View File

@ -0,0 +1,44 @@
/* 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 functions which operate on ISO images
and their global properties.
*/
#ifndef Xorriso_pvt_iso_img_includeD
#define Xorriso_pvt_iso_img_includeD yes
int Xorriso_update_volid(struct XorrisO *xorriso, int flag);
int Xorriso_record_boot_info(struct XorrisO *xorriso, int flag);
int Xorriso_assert_volid(struct XorrisO *xorriso, int msc1, int flag);
int Xorriso_is_isohybrid(struct XorrisO *xorriso, IsoFile *bootimg_node,
int flag);
int Xorriso_boot_item_status(struct XorrisO *xorriso, char *cat_path,
char *bin_path, int platform_id,
int patch_isolinux, int emul, off_t load_size,
unsigned char *id_string,
unsigned char *selection_crit, char *form,
char *filter, FILE *fp, int flag);
int Xorriso__append_boot_params(char *line, ElToritoBootImage *bootimg,
int flag);
int Xorriso_get_volume(struct XorrisO *xorriso, IsoImage **volume,
int flag);
#endif /* ! Xorriso_pvt_iso_img_includeD */

2637
xorriso/iso_manip.c Normal file

File diff suppressed because it is too large Load Diff

72
xorriso/iso_manip.h Normal file
View File

@ -0,0 +1,72 @@
/* 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 functions which manipulate the
libisofs tree model.
*/
#ifndef Xorriso_pvt_iso_manip_includeD
#define Xorriso_pvt_iso_manip_includeD yes
int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf,
char *disk_path, IsoNode *node, int flag);
int Xorriso_graft_split(struct XorrisO *xorriso, IsoImage *volume,
IsoDir *dir, char *disk_path, char *img_name,
char *nominal_source, char *nominal_target,
off_t size, IsoNode **node, int flag);
int Xorriso_tree_graft_node(struct XorrisO *xorriso, IsoImage *volume,
IsoDir *dir, char *disk_path, char *img_name,
char *nominal_source, char *nominal_target,
off_t offset, off_t cut_size,
IsoNode **node, int flag);
int Xorriso_add_tree(struct XorrisO *xorriso, IsoDir *dir,
char *img_dir_path, char *disk_dir_path,
struct LinkiteM *link_stack, int flag);
int Xorriso_copy_implicit_properties(struct XorrisO *xorriso, IsoDir *dir,
char *full_img_path, char *img_path, char *full_disk_path, int flag);
int Xorriso_mkisofs_lower_r(struct XorrisO *xorriso, IsoNode *node, int flag);
int Xorriso_widen_hardlink(struct XorrisO *xorriso, void * boss_iter,
IsoNode *node,
char *abs_path, char *iso_prefix, char *disk_prefix,
int flag);
int Xorriso_cannot_create_iter(struct XorrisO *xorriso, int iso_error,
int flag);
int Xorriso_findi_iter(struct XorrisO *xorriso, IsoDir *dir_node, off_t *mem,
IsoDirIter **iter,
IsoNode ***node_array, int *node_count, int *node_idx,
IsoNode **iterated_node, int flag);
int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job,
IsoDirIter *boss_iter, off_t boss_mem,
char *abs_path, char *show_path,
IsoNode *node, int depth, int flag);
int Xorriso_findi_headline(struct XorrisO *xorriso, struct FindjoB *job,
int flag);
int Xorriso_findi_sorted(struct XorrisO *xorriso, struct FindjoB *job,
off_t boss_mem, int filec, char **filev, int flag);
int Xorriso_all_node_array(struct XorrisO *xorriso, int addon_nodes, int flag);
int Xorriso__file_start_lba(IsoNode *node, int *lba, int flag);
#endif /* ! Xorriso_pvt_iso_manip_includeD */

2146
xorriso/iso_tree.c Normal file

File diff suppressed because it is too large Load Diff

92
xorriso/iso_tree.h Normal file
View File

@ -0,0 +1,92 @@
/* 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 functions which access nodes of the
libisofs tree model.
*/
#ifndef Xorriso_pvt_iso_tree_includeD
#define Xorriso_pvt_iso_tree_includeD yes
#define LIBISO_ISDIR(node) (iso_node_get_type(node) == LIBISO_DIR)
#define LIBISO_ISREG(node) (iso_node_get_type(node) == LIBISO_FILE)
#define LIBISO_ISLNK(node) (iso_node_get_type(node) == LIBISO_SYMLINK)
#define LIBISO_ISCHR(node) (iso_node_get_type(node) == LIBISO_SPECIAL && \
S_ISCHR(iso_node_get_mode(node)))
#define LIBISO_ISBLK(node) (iso_node_get_type(node) == LIBISO_SPECIAL && \
S_ISBLK(iso_node_get_mode(node)))
#define LIBISO_ISFIFO(node) (iso_node_get_type(node) == LIBISO_SPECIAL && \
S_ISFIFO(iso_node_get_mode(node)))
#define LIBISO_ISSOCK(node) (iso_node_get_type(node) == LIBISO_SPECIAL && \
S_ISSOCK(iso_node_get_mode(node)))
#define LIBISO_ISBOOT(node) (iso_node_get_type(node) == LIBISO_BOOT)
int Xorriso_node_from_path(struct XorrisO *xorriso, IsoImage *volume,
char *path, IsoNode **node, int flag);
int Xorriso_get_node_by_path(struct XorrisO *xorriso,
char *in_path, char *eff_path,
IsoNode **node, int flag);
int Xorriso_node_get_dev(struct XorrisO *xorriso, IsoNode *node,
char *path, dev_t *dev, int flag);
int Xorriso_fake_stbuf(struct XorrisO *xorriso, char *path, struct stat *stbuf,
IsoNode **node, int flag);
int Xorriso_node_is_valid(struct XorrisO *xorriso, IsoNode *in_node, int flag);
int Xorriso_path_from_node(struct XorrisO *xorriso, IsoNode *in_node,
char path[SfileadrL], int flag);
int Xorriso_path_from_lba(struct XorrisO *xorriso, IsoNode *node, int lba,
char path[SfileadrL], int flag);
int Xorriso_get_attr_value(struct XorrisO *xorriso, void *in_node, char *path,
char *name, size_t *value_length, char **value, int flag);
int Xorriso_stream_type(struct XorrisO *xorriso, IsoNode *node,
IsoStream *stream, char type_text[], int flag);
int Xorriso_show_du_subs(struct XorrisO *xorriso, IsoDir *dir_node,
char *abs_path, char *rel_path, off_t *size,
off_t boss_mem, int flag);
int Xorriso_sorted_dir_i(struct XorrisO *xorriso, IsoDir *dir_node,
int *filec, char ***filev, off_t boss_mem, int flag);
int Xorriso_obtain_pattern_files_i(
struct XorrisO *xorriso, char *wd, IsoDir *dir,
int *filec, char **filev, int count_limit, off_t *mem,
int *dive_count, int flag);
int Xorriso__start_end_lbas(IsoNode *node,
int *lba_count, int **start_lbas, int **end_lbas,
off_t *size, int flag);
int Xorriso__file_start_lba(IsoNode *node,
int *lba, int flag);
int Xorriso_file_eval_damage(struct XorrisO *xorriso, IsoNode *node,
off_t *damage_start, off_t *damage_end,
int flag);
int Xorriso_report_lba(struct XorrisO *xorriso, char *show_path,
IsoNode *node, int flag);
int Xorriso_report_damage(struct XorrisO *xorriso, char *show_path,
IsoNode *node, int flag);
int Xorriso_getfname(struct XorrisO *xorriso, char *path, int flag);
#endif /* ! Xorriso_pvt_iso_tree_includeD */

483
xorriso/lib_mgt.c Normal file
View File

@ -0,0 +1,483 @@
/* 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 manage the relation between xorriso
and the libraries: libburn, libisofs, libisoburn.
*/
#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>
/* for -charset */
#include <iconv.h>
#include <langinfo.h>
#include "xorriso.h"
#include "xorriso_private.h"
#include "xorrisoburn.h"
#include "lib_mgt.h"
int Xorriso_abort(struct XorrisO *xorriso, int flag)
{
int ret;
ret= burn_abort(4440, burn_abort_pacifier, "xorriso : ");
if(ret<=0) {
fprintf(stderr,
"\nxorriso : ABORT : Cannot cancel burn session and release drive.\n");
return(0);
}
fprintf(stderr,
"xorriso : ABORT : Drive is released and library is shut down now.\n");
fprintf(stderr,
"xorriso : ABORT : Program done. Even if you do not see a shell prompt.\n");
fprintf(stderr, "\n");
exit(1);
}
/* @param flag bit0= asynchronous handling (else catch thread, wait, and exit)
*/
int Xorriso_set_signal_handling(struct XorrisO *xorriso, int flag)
{
char *handler_prefix= NULL;
if(Xorriso__get_signal_behavior(0) != 1)
return(2);
handler_prefix= calloc(strlen(xorriso->progname)+3+1, 1);
if(handler_prefix==NULL) {
sprintf(xorriso->info_text,
"Cannot allocate memory for for setting signal handler");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
return(-1);
}
sprintf(handler_prefix, "%s : ", xorriso->progname);
burn_set_signal_handling(handler_prefix, NULL, (flag & 1) * 0x30);
free(handler_prefix);
return(1);
}
int Xorriso_startup_libraries(struct XorrisO *xorriso, int flag)
{
int ret, major, minor, micro;
char *queue_sev, *print_sev, reason[1024];
struct iso_zisofs_ctrl zisofs_ctrl= {0, 6, 15};
/* First an ugly compile time check for header version compatibility.
If everthing matches, then no C code is produced. In case of mismatch,
intentionally faulty C code will be inserted.
*/
/* The minimum requirement of xorriso towards the libisoburn header
at compile time is defined in xorriso/xorrisoburn.h
xorriso_libisoburn_req_major
xorriso_libisoburn_req_minor
xorriso_libisoburn_req_micro
It gets compared against the version macros in libburn/libburn.h :
isoburn_header_version_major
isoburn_header_version_minor
isoburn_header_version_micro
If the header is too old then the following code shall cause failure of
cdrskin compilation rather than to allow production of a program with
unpredictable bugs or memory corruption.
The compiler messages supposed to appear in this case are:
error: 'LIBISOBURN_MISCONFIGURATION' undeclared (first use in this function)
error: 'INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libisoburn_dot_h_TOO_OLD__SEE_xorrisoburn_dot_c' undeclared (first use in this function)
error: 'LIBISOBURN_MISCONFIGURATION_' undeclared (first use in this function)
*/
/* The indendation is an advise of man gcc to help old compilers ignoring */
#if xorriso_libisoburn_req_major > isoburn_header_version_major
#define Isoburn_libisoburn_dot_h_too_olD 1
#endif
#if xorriso_libisoburn_req_major == isoburn_header_version_major && xorriso_libisoburn_req_minor > isoburn_header_version_minor
#define Isoburn_libisoburn_dot_h_too_olD 1
#endif
#if xorriso_libisoburn_req_minor == isoburn_header_version_minor && xorriso_libisoburn_req_micro > isoburn_header_version_micro
#define Isoburn_libisoburn_dot_h_too_olD 1
#endif
#ifdef Isoburn_libisoburn_dot_h_too_olD
LIBISOBURN_MISCONFIGURATION = 0;
INTENTIONAL_ABORT_OF_COMPILATION__HEADERFILE_libisoburn_dot_h_TOO_OLD__SEE_xorrisoburn_dot_c = 0;
LIBISOBURN_MISCONFIGURATION_ = 0;
#endif
/* End of ugly compile time test (scroll up for explanation) */
reason[0]= 0;
ret= isoburn_initialize(reason, 0);
if(ret==0) {
sprintf(xorriso->info_text, "Cannot initialize libraries");
if(reason[0])
sprintf(xorriso->info_text+strlen(xorriso->info_text),
". Reason given:\n%s", reason);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
return(0);
}
ret= isoburn_is_compatible(isoburn_header_version_major,
isoburn_header_version_minor,
isoburn_header_version_micro, 0);
if(ret<=0) {
isoburn_version(&major, &minor, &micro);
sprintf(xorriso->info_text,
"libisoburn version too old: %d.%d.%d . Need at least: %d.%d.%d .\n",
major, minor, micro,
isoburn_header_version_major, isoburn_header_version_minor,
isoburn_header_version_micro);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
return(-1);
}
xorriso->libs_are_started= 1;
queue_sev= "ALL";
if(xorriso->library_msg_direct_print) {
/* >>> need option for controlling this in XorrisO.
See also Xorriso_msgs_submit */;
print_sev= xorriso->report_about_text;
} else
print_sev= "NEVER";
iso_set_msgs_severities(queue_sev, print_sev, "libsofs : ");
burn_msgs_set_severities(queue_sev, print_sev, "libburn : ");
/* ??? >>> do we want united queues ? */
/* burn_set_messenger(iso_get_messenger()); */
isoburn_set_msgs_submit(Xorriso_msgs_submit_void, (void *) xorriso,
(3<<2) | 128 , 0);
ret= Xorriso_set_signal_handling(xorriso, 0);
if(ret <= 0)
return(ret);
ret = iso_zisofs_get_params(&zisofs_ctrl, 0);
if (ret == 1) {
xorriso->zisofs_block_size= xorriso->zisofs_block_size_default=
(1 << zisofs_ctrl.block_size_log2);
xorriso->zlib_level= xorriso->zlib_level_default=
zisofs_ctrl.compression_level;
}
Xorriso_process_msg_queues(xorriso,0);
if(reason[0]) {
sprintf(xorriso->info_text, "%s", reason);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
}
strcpy(xorriso->info_text, "Using ");
strncat(xorriso->info_text, burn_scsi_transport_id(0), 1024);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
return(1);
}
/* @param flag bit0= global shutdown of libraries */
int Xorriso_detach_libraries(struct XorrisO *xorriso, int flag)
{
Xorriso_give_up_drive(xorriso, 3);
if(xorriso->in_volset_handle!=NULL) { /* standalone image */
iso_image_unref((IsoImage *) xorriso->in_volset_handle);
xorriso->in_volset_handle= NULL;
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
Xorriso_destroy_di_array(xorriso, 0);
Xorriso_destroy_hln_array(xorriso, 0);
}
if(flag&1) {
if(xorriso->libs_are_started==0)
return(0);
isoburn_finish();
}
return(1);
}
/* @param flag bit0= suppress messages below UPDATE
bit1= suppress messages below FAILURE
*/
int Xorriso_set_image_severities(struct XorrisO *xorriso, int flag)
{
char *queue_sev, *print_sev;
if(flag&2)
queue_sev= "FAILURE";
else if(flag&1)
queue_sev= "UPDATE";
else
queue_sev= "ALL";
if(xorriso->library_msg_direct_print)
print_sev= xorriso->report_about_text;
else
print_sev= "NEVER";
iso_set_msgs_severities(queue_sev, print_sev, "libisofs : ");
return(1);
}
/* @param flag bit0=prepare for a burn run */
int Xorriso_set_abort_severity(struct XorrisO *xorriso, int flag)
{
int ret, abort_on_number;
char *sev_text;
static int note_number= -1, failure_number= -1;
if(note_number==-1)
Xorriso__text_to_sev("NOTE", &note_number, 0);
if(failure_number==-1)
Xorriso__text_to_sev("FAILURE", &failure_number, 0);
sev_text= xorriso->abort_on_text;
ret= Xorriso__text_to_sev(xorriso->abort_on_text, &abort_on_number, 0);
if(ret<=0)
return(ret);
if(abort_on_number<note_number)
sev_text= "NOTE";
else if(abort_on_number>failure_number)
sev_text= "FAILURE";
ret= iso_set_abort_severity(sev_text);
return(ret>=0);
}
int Xorriso_report_lib_versions(struct XorrisO *xorriso, int flag)
{
int major, minor, micro;
int req_major, req_minor, req_micro;
iso_lib_version(&major, &minor, &micro);
isoburn_libisofs_req(&req_major, &req_minor, &req_micro);
sprintf(xorriso->result_line,
"libisofs in use : %d.%d.%d (min. %d.%d.%d)\n",
major, minor, micro, req_major, req_minor, req_micro);
Xorriso_result(xorriso, 0);
burn_version(&major, &minor, &micro);
isoburn_libburn_req(&req_major, &req_minor, &req_micro);
sprintf(xorriso->result_line,
"libburn in use : %d.%d.%d (min. %d.%d.%d)\n",
major, minor, micro, req_major, req_minor, req_micro);
Xorriso_result(xorriso, 0);
strcpy(xorriso->result_line, "libburn OS adapter: ");
strncat(xorriso->result_line, burn_scsi_transport_id(0), 1024);
strcat(xorriso->result_line, "\n");
Xorriso_result(xorriso, 0);
isoburn_version(&major, &minor, &micro);
sprintf(xorriso->result_line,
"libisoburn in use : %d.%d.%d (min. %d.%d.%d)\n",
major, minor, micro,
isoburn_header_version_major, isoburn_header_version_minor,
isoburn_header_version_micro);
Xorriso_result(xorriso, 0);
return(1);
}
int Xorriso__sev_to_text(int severity, char **severity_name,
int flag)
{
int ret;
ret= iso_sev_to_text(severity, severity_name);
if(ret>0)
return(ret);
ret= burn_sev_to_text(severity, severity_name, 0);
if(ret>0)
return(ret);
*severity_name= "";
return(0);
}
int Xorriso__text_to_sev(char *severity_name, int *severity_number, int flag)
{
int ret= 1;
ret= iso_text_to_sev(severity_name, severity_number);
if(ret>0)
return(ret);
ret= burn_text_to_sev(severity_name, severity_number, 0);
return(ret);
}
/* @param flag bit0= report libisofs error text
bit1= victim is disk_path
bit2= do not inquire libisofs, report msg_text and min_severity
*/
int Xorriso_report_iso_error(struct XorrisO *xorriso, char *victim,
int iso_error_code, char msg_text[], int os_errno,
char min_severity[], int flag)
{
int error_code, iso_sev, min_sev, ret;
char *sev_text_pt, *msg_text_pt= NULL;
char sfe[6*SfileadrL];
static int sorry_sev= -1;
if(sorry_sev<0)
Xorriso__text_to_sev("SORRY", &sorry_sev, 0);
if(flag&4) {
error_code= 0x00050000;
Xorriso__text_to_sev(min_severity, &iso_sev, 0);
} else {
error_code= iso_error_get_code(iso_error_code);
if(error_code < 0x00030000 || error_code >= 0x00040000)
error_code= (error_code & 0xffff) | 0x00050000;
if(flag&1)
msg_text_pt= (char *) iso_error_to_msg(iso_error_code);
iso_sev= iso_error_get_severity(iso_error_code);
}
if(msg_text_pt==NULL)
msg_text_pt= msg_text;
if(iso_sev >= sorry_sev && (flag & 2) && victim[0])
Xorriso_msgs_submit(xorriso, 0, victim, 0, "ERRFILE", 0);
sev_text_pt= min_severity;
Xorriso__text_to_sev(min_severity, &min_sev, 0);
if(min_sev < iso_sev && !(flag&4))
Xorriso__sev_to_text(iso_sev, &sev_text_pt, 0);
strcpy(sfe, msg_text_pt);
if(victim[0]) {
strcat(sfe, ": ");
Text_shellsafe(victim, sfe+strlen(sfe), 0);
}
ret= Xorriso_msgs_submit(xorriso, error_code, sfe, os_errno, sev_text_pt, 4);
return(ret);
}
int Xorriso_get_local_charset(struct XorrisO *xorriso, char **name, int flag)
{
(*name)= iso_get_local_charset(0);
return(1);
}
int Xorriso_set_local_charset(struct XorrisO *xorriso, char *name, int flag)
{
int ret;
char *nl_charset, sfe[5 * SfileadrL];
iconv_t iconv_ret= (iconv_t) -1;
nl_charset= nl_langinfo(CODESET);
if(name == NULL)
name= nl_charset;
if(name != NULL) {
iconv_ret= iconv_open(nl_charset, name);
if(iconv_ret == (iconv_t) -1)
goto cannot;
else
iconv_close(iconv_ret);
}
ret= iso_set_local_charset(name, 0);
if(ret <= 0) {
cannot:;
sprintf(xorriso->info_text,
"-local_charset: Cannot assume as local character set: %s",
Text_shellsafe(name, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
return(0);
}
sprintf(xorriso->info_text, "Local character set is now assumed as: %s",
Text_shellsafe(name, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
return(1);
}
int Xorriso_process_msg_queues(struct XorrisO *xorriso, int flag)
{
int ret, error_code= 0, os_errno= 0, count= 0, pass, imgid, tunneled;
char severity[80];
if(!xorriso->libs_are_started)
return(1);
for(pass= 0; pass< 2; pass++) {
while(1) {
tunneled= 0;
if(pass==0)
ret= iso_obtain_msgs("ALL", &error_code, &imgid,
xorriso->info_text, severity);
else {
ret= burn_msgs_obtain("ALL", &error_code, xorriso->info_text, &os_errno,
severity);
if((error_code>=0x00030000 && error_code<0x00040000) ||
(error_code>=0x00050000 && error_code<0x00060000))
tunneled= -1; /* "libisofs:" */
else if(error_code>=0x00060000 && error_code<0x00070000)
tunneled= 1; /* "libisoburn:" */
}
if(ret<=0)
break;
/* <<< tunneled MISHAP from libisoburn through libburn
or well known error codes of MISHAP events
With libburn-0.4.4 this is not necessary */
if(error_code==0x5ff73 || error_code==0x3ff73 ||
error_code==0x3feb9 || error_code==0x3feb2)
strcpy(severity, "MISHAP");
else if(error_code==0x51001)
strcpy(severity, "ERRFILE");
Xorriso_msgs_submit(xorriso, error_code, xorriso->info_text, os_errno,
severity, ((pass+tunneled)+1)<<2);
count++;
}
}
if(xorriso->library_msg_direct_print && count>0) {
sprintf(xorriso->info_text," (%d library messages repeated by xorriso)\n",
count);
Xorriso_info(xorriso, 0);
}
return(1);
}
int Xorriso_md5_start(struct XorrisO *xorriso, void **ctx, int flag)
{
int ret;
ret= iso_md5_start(ctx);
if(ret == 1)
return(1);
Xorriso_no_malloc_memory(xorriso, NULL, 0);
return(-1);
}
int Xorriso_md5_compute(struct XorrisO *xorriso, void *ctx,
char *data, int datalen, int flag)
{
iso_md5_compute(ctx, data, datalen);
return(1);
}
int Xorriso_md5_end(struct XorrisO *xorriso, void **ctx, char md5[16],
int flag)
{
int ret;
ret= iso_md5_end(ctx, md5);
Xorriso_process_msg_queues(xorriso,0);
if(ret <= 0)
return(0);
return(1);
}

78
xorriso/lib_mgt.h Normal file
View File

@ -0,0 +1,78 @@
/* 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 functions which manage the relation
between xorriso and the libraries: libburn, libisofs, and libisoburn.
*/
#ifndef Xorriso_pvt_x_includeD
#define Xorriso_pvt_x_includeD yes
#ifndef Xorriso_standalonE
/* The library which does the ISO 9660 / RockRidge manipulations */
#include <libisofs/libisofs.h>
/* The library which does MMC optical drive operations */
#include <libburn/libburn.h>
/* The library which enhances overwriteable media with ISO 9660 multi-session
capabilities via the method invented by Andy Polyakov for growisofs */
#include <libisoburn/libisoburn.h>
/* The official xorriso options API. "No shortcuts" */
#include "xorriso.h"
/* The inner description of XorrisO */
#include "xorriso_private.h"
/* The inner isofs- and burn-library interface */
#include "xorrisoburn.h"
#else /* ! Xorriso_standalonE */
#include "../libisofs/libisofs.h"
#include "../libburn/libburn.h"
#include "../libisoburn/libisoburn.h"
#include "xorriso.h"
#include "xorriso_private.h"
#include "xorrisoburn.h"
#endif /* Xorriso_standalonE */
int Xorriso_abort(struct XorrisO *xorriso, int flag);
/* @param flag bit0= asynchronous handling (else catch thread, wait, and exit)
*/
int Xorriso_set_signal_handling(struct XorrisO *xorriso, int flag);
/* @param flag bit0= suppress messages below UPDATE
bit1= suppress messages below FAILURE
*/
int Xorriso_set_image_severities(struct XorrisO *xorriso, int flag);
int Xorriso__sev_to_text(int severity, char **severity_name,
int flag);
/* @param flag bit0= report libisofs error text
bit1= victim is disk_path
bit2= do not inquire libisofs, report msg_text and min_severity
*/
int Xorriso_report_iso_error(struct XorrisO *xorriso, char *victim,
int iso_error_code, char msg_text[], int os_errno,
char min_severity[], int flag);
int Xorriso_process_msg_queues(struct XorrisO *xorriso, int flag);
#endif /* ! Xorriso_pvt_x_includeD */

View File

@ -134,10 +134,58 @@ xorriso/convert_man_to_html.sh
create_dir "$lone_dir"/xorriso create_dir "$lone_dir"/xorriso
copy_files \ copy_files \
xorriso/xorrisoburn.[ch] \ xorriso/xorriso.h \
xorriso/xorriso.[ch] \
xorriso/xorriso_private.h \ xorriso/xorriso_private.h \
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/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_main.c \
xorriso/xorriso_timestamp.h \ xorriso/xorriso_timestamp.h \
\ \
xorriso/changelog.txt \ xorriso/changelog.txt \
@ -237,7 +285,7 @@ then
# patch xorriso/xorriso.c to be GNU xorriso # patch xorriso/xorriso.c to be GNU xorriso
sed -e's/define Xorriso_libburnia_xorrisO/define Xorriso_GNU_xorrisO/' \ sed -e's/define Xorriso_libburnia_xorrisO/define Xorriso_GNU_xorrisO/' \
-e's/This may be changed to Xorriso_GNU_xorrisO in order to c/C/' \ -e's/This may be changed to Xorriso_GNU_xorrisO in order to c/C/' \
<xorriso/xorriso.c >"$lone_dir"/xorriso/xorriso.c <xorriso/xorriso_main.c >"$lone_dir"/xorriso/xorriso_main.c
else else

755
xorriso/match.c Normal file
View File

@ -0,0 +1,755 @@
/* 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 implementation of functions for pattern matching.
*/
#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 <fcntl.h>
#include <errno.h>
#include "xorriso.h"
#include "xorriso_private.h"
#include "xorrisoburn.h"
/* @param flag bit0= do not augment relative structured search by xorriso->wdi
bit1= return 2 if bonked at start point by ..
(caller then aborts or retries without bit0)
bit2= eventually prepend wdx rather than wdi
@return <=0 error, 1= ok, 2= with bit1: relative pattern exceeds start point
*/
int Xorriso_prepare_regex(struct XorrisO *xorriso, char *adr, int flag)
{
int l,ret,i,count,bonked= 0,is_constant,is_still_relative= 0;
char *cpt,*npt,adr_part[2*SfileadrL],absolute_adr[2*SfileadrL],*adr_start,*wd;
if(flag&4)
wd= xorriso->wdx;
else
wd= xorriso->wdi;
if(xorriso->search_mode>=2 && xorriso->search_mode<=4) {
if(xorriso->search_mode==3 || xorriso->search_mode==4) {
l= strlen(adr)+strlen(wd)+1;
if(l*2+2>sizeof(xorriso->reg_expr) || l*2+2>sizeof(adr_part)) {
sprintf(xorriso->info_text,"Search pattern too long");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
}
Xorriso_destroy_re(xorriso,0);
if(xorriso->structured_search && xorriso->search_mode==3) {
if(adr[0]!='/')
is_still_relative= 1;
if(is_still_relative && !(flag&1)) {
/* relative expression : prepend working directory */
sprintf(absolute_adr,"%s/%s",wd,adr);
adr_start= absolute_adr;
xorriso->prepended_wd= 1;
is_still_relative= 0;
} else
adr_start= adr;
/* count slashes */;
cpt= adr_start;
while(*cpt=='/')
cpt++;
for(i= 0;1;i++) {
cpt= strchr(cpt,'/');
if(cpt==NULL)
break;
while(*cpt=='/')
cpt++;
}
count= i+1;
xorriso->re= TSOB_FELD(regex_t,count);
if(xorriso->re==NULL)
return(-1);
xorriso->re_constants= TSOB_FELD(char *,count);
if(xorriso->re_constants==NULL)
return(-1);
for(i= 0;i<count;i++)
xorriso->re_constants[i]= NULL;
xorriso->re_count= count;
xorriso->re_fill= 0;
/* loop over slash chunks*/;
cpt= adr_start;
xorriso->re_fill= 0;
while(*cpt=='/')
cpt++;
for(i= 0;i<count;i++) {
npt= strchr(cpt,'/');
if(npt==NULL) {
if(strlen(cpt)>=sizeof(adr_part))
return(-1);
strcpy(adr_part,cpt);
} else {
if(npt-cpt>=sizeof(adr_part))
return(-1);
strncpy(adr_part,cpt,npt-cpt);
adr_part[npt-cpt]= 0;
}
if(adr_part[0]==0)
goto next_adr_part;
if(adr_part[0]=='.' && adr_part[1]==0 &&
(xorriso->re_fill>0 || i<count-1))
goto next_adr_part;
if(adr_part[0]=='.' && adr_part[1]=='.' && adr_part[2]==0) {
/* delete previous part */
if(xorriso->re_fill <= 0) {
bonked= 1;
goto next_adr_part;
}
if(xorriso->re_constants[xorriso->re_fill-1]!=NULL) {
free(xorriso->re_constants[xorriso->re_fill-1]);
xorriso->re_constants[xorriso->re_fill-1]= NULL;
} else
regfree(&(xorriso->re[xorriso->re_fill-1]));
(xorriso->re_fill)--;
goto next_adr_part;
}
if(strcmp(adr_part,"*")==0) {
adr_part[0]= 0;
ret= 2;
} else
ret= Xorriso__bourne_to_reg(adr_part,xorriso->reg_expr,0);
if(ret==2) {
if(Sregex_string(&(xorriso->re_constants[xorriso->re_fill]),adr_part,0)
<=0)
return(-1);
} else {
if(regcomp(&(xorriso->re[xorriso->re_fill]),xorriso->reg_expr,0)!=0)
goto cannot_compile;
}
xorriso->re_fill++;
next_adr_part:;
if(i==count-1)
break;
cpt= npt+1;
while(*cpt=='/')
cpt++;
}
if(bonked) {
if(flag&2)
return(2);
sprintf(xorriso->info_text, "Your '..' bonked at the %s directory.",
is_still_relative ? "working" : "root");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE",0);
return(0);
}
Xorriso__bourne_to_reg(adr_start,xorriso->reg_expr,0); /* just for show */
} else {
is_constant= 0;
if(strcmp(adr,"*")==0 || adr[0]==0) {
is_constant= 1;
} else if(xorriso->search_mode==3 || xorriso->search_mode==4) {
ret= Xorriso__bourne_to_reg(adr,xorriso->reg_expr,0);
is_constant= (ret==2);
} else {
if(strlen(adr)>=sizeof(xorriso->reg_expr))
return(-1);
strcpy(xorriso->reg_expr,adr);
}
xorriso->re_count= 0; /* tells matcher that this is not structured */
xorriso->re_constants= TSOB_FELD(char *,1);
if(xorriso->re_constants==NULL)
return(-1);
xorriso->re_constants[0]= NULL;
if(is_constant) {
if(strcmp(adr,"*")==0) {
if(Sregex_string(&(xorriso->re_constants[0]),"",0)<=0)
return(-1);
} else {
if(Sregex_string(&(xorriso->re_constants[0]),adr,0)<=0)
return(-1);
}
xorriso->re_fill= 1;
} else {
xorriso->re= TSOB_FELD(regex_t,1);
if(xorriso->re==NULL)
return(-1);
if(regcomp(&(xorriso->re[0]),xorriso->reg_expr,0)!=0) {
cannot_compile:;
sprintf(xorriso->info_text, "Cannot compile regular expression : %s",
xorriso->reg_expr);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE",0);
return(0);
}
}
}
}
return(1);
}
/* @param flag bit0= do not shortcut last component of to_match
bit1= consider match if regex matches parent of path
bit2= retry beginning at failed last component
@return 0=match , else no match
*/
int Xorriso_regexec(struct XorrisO *xorriso, char *to_match, int *failed_at,
int flag)
{
int ret,i,re_start= 0,reg_nomatch= -1;
char *cpt,*npt,adr_part[SfileadrL],*mpt;
reg_nomatch= REG_NOMATCH;
*failed_at= 0;
if(!(xorriso->structured_search && xorriso->re_count>0)) {
if(xorriso->re_constants!=NULL)
if(xorriso->re_constants[0]!=NULL) {
if(xorriso->re_constants[0][0]==0)
return(0);
if(strcmp(xorriso->re_constants[0],to_match)!=0)
return(reg_nomatch);
return(0);
}
ret= regexec(&(xorriso->re[0]),to_match,1,xorriso->match,0);
return(ret);
}
cpt= to_match;
while(*cpt=='/')
cpt++;
if(flag&4)
re_start= xorriso->re_failed_at;
if(re_start<0)
re_start= 0;
for(i= re_start;i<xorriso->re_fill;i++) {
*failed_at= i;
npt= strchr(cpt,'/');
if(npt==NULL) {
if(i<xorriso->re_fill-1 && !(flag&1))
return(reg_nomatch); /* this must be the last expression part */
mpt= cpt;
} else {
strncpy(adr_part,cpt,npt-cpt);
adr_part[npt-cpt]= 0;
mpt= adr_part;
}
if(xorriso->re_constants[i]!=NULL) {
if(xorriso->re_constants[i][0]!=0) /* empty constant matches anything */
if(strcmp(xorriso->re_constants[i],mpt)!=0)
return(reg_nomatch);
} else {
ret= regexec(&(xorriso->re[i]),mpt,1,xorriso->match,0);
if(ret!=0)
return(ret);
}
if(npt==NULL) {
if(i>=xorriso->re_fill-1)
return(0); /* MATCH */
*failed_at= i+1;
return(reg_nomatch);
}
cpt= npt+1;
while(*cpt=='/')
cpt++;
}
*failed_at= xorriso->re_fill;
if(flag & 2)
return(0); /* MATCH */
return(reg_nomatch);
}
int Xorriso_is_in_patternlist(struct XorrisO *xorriso,
struct Xorriso_lsT *patternlist, char *path,
int flag)
{
int ret, failed_at, i= 0;
struct Xorriso_lsT *s;
xorriso->search_mode= 3;
xorriso->structured_search= 1;
for(s= patternlist; s != NULL; s= Xorriso_lst_get_next(s, 0)) {
ret= Xorriso_prepare_regex(xorriso, Xorriso_lst_get_text(s, 0), 0);
if(ret <= 0)
return(-1);
/* Match path or parent of path */
ret= Xorriso_regexec(xorriso, path, &failed_at, 2);
if(ret == 0)
return(i + 1);
i++;
}
return(0);
}
char *Xorriso_get_pattern(struct XorrisO *xorriso,
struct Xorriso_lsT *patternlist, int index, int flag)
{
int i= 0;
struct Xorriso_lsT *s;
for(s= patternlist; s != NULL; s= Xorriso_lst_get_next(s, 0)) {
if(i == index)
return(Xorriso_lst_get_text(s, 0));
i++;
}
return(NULL);
}
/* @param flag bit2= this is a disk_pattern
@return <=0 failure , 1 pattern ok , 2 pattern needed prepended wd */
int Xorriso_prepare_expansion_pattern(struct XorrisO *xorriso, char *pattern,
int flag)
{
int ret, prepwd= 0;
ret= Xorriso_prepare_regex(xorriso, pattern, 1|2|(flag&4));
if(ret==2) {
ret= Xorriso_prepare_regex(xorriso, pattern, flag&4);
prepwd= 1;
}
if(ret<=0) {
sprintf(xorriso->info_text,
"Cannot compile pattern to regular expression: %s", pattern);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
return(1+prepwd);
}
/* @param flag bit0= count results rather than storing them
bit1= unexpected change of number is a FATAL event
@return <=0 error , 1 is root (end processing) ,
2 is not root (go on processing)
*/
int Xorriso_check_for_root_pattern(struct XorrisO *xorriso,
int *filec, char **filev, int count_limit, off_t *mem, int flag)
{
if(xorriso->re_fill!=0)
return(2);
/* This is the empty pattern representing root */
if(flag&1) {
(*filec)++;
(*mem)+= 8;
} else {
if(*filec >= count_limit) {
sprintf(xorriso->info_text,
"Number of matching files changed unexpectedly (> %d)",
count_limit);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
(flag&2 ? "FATAL" : "WARNING"), 0);
return(flag&2 ? -1 : 0);
}
filev[*filec]= strdup("/");
if(filev[*filec]==NULL) {
Xorriso_no_pattern_memory(xorriso, (off_t) 2, 0);
return(-1);
}
(*filec)++;
}
return(1);
}
/* @param flag bit0= count result rather than storing it
bit1= unexpected change of number is a FATAL event
*/
int Xorriso_register_matched_adr(struct XorrisO *xorriso,
char *adr, int count_limit,
int *filec, char **filev, off_t *mem, int flag)
{
int l;
if(flag&1) {
(*filec)++;
l= strlen(adr)+1;
(*mem)+= sizeof(char *)+l;
if(l % sizeof(char *))
(*mem)+= sizeof(char *)-(l % sizeof(char *));
} else {
if(*filec >= count_limit) {
sprintf(xorriso->info_text,
"Number of matching files changed unexpectedly (> %d)",
count_limit);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
(flag&2 ? "FATAL" : "WARNING"), 0);
return(flag&2 ? -1 : 0);
}
filev[*filec]= strdup(adr);
if(filev[*filec]==NULL) {
Xorriso_no_pattern_memory(xorriso, (off_t) (strlen(adr)+1), 0);
return(-1);
}
(*filec)++;
}
return(1);
}
/* @param flag bit0= count results rather than storing them
bit1= this is a recursion
bit2= prepend wd (automatically done if wd[0]!=0)
@return <=0 error , 1 ok , 2 could not open directory
*/
int Xorriso_obtain_pattern_files_x(
struct XorrisO *xorriso, char *wd, char *dir_adr,
int *filec, char **filev, int count_limit, off_t *mem,
int *dive_count, int flag)
{
int ret, failed_at, follow_mount, follow_links;
struct DirseQ *dirseq= NULL;
struct stat stbuf;
dev_t dir_dev;
char *path;
char *adr= NULL, *name= NULL, *path_data= NULL;
adr= malloc(SfileadrL);
name= malloc(SfileadrL);
path_data= malloc(SfileadrL);
if(adr==NULL || name==NULL || path_data==NULL) {
Xorriso_no_malloc_memory(xorriso, &adr, 0);
{ret= -1; goto ex;}
}
follow_mount= (xorriso->do_follow_mount || xorriso->do_follow_pattern);
follow_links= (xorriso->do_follow_links || xorriso->do_follow_pattern);
if(!(flag&2))
*dive_count= 0;
else
(*dive_count)++;
ret= Xorriso_check_for_root_pattern(xorriso, filec, filev, count_limit,
mem, flag&1);
if(ret!=2)
goto ex;
if(lstat(dir_adr, &stbuf)==-1)
{ret= 2; goto ex;}
dir_dev= stbuf.st_dev;
if(S_ISLNK(stbuf.st_mode)) {
if(stat(dir_adr, &stbuf)==-1)
{ret= 2; goto ex;}
if(dir_dev != stbuf.st_dev && !follow_mount)
{ret= 2; goto ex;}
}
ret= Dirseq_new(&dirseq, dir_adr, 1);
if(ret<0) {
sprintf(xorriso->info_text, "Cannot obtain disk directory iterator");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
{ret= -1; goto ex;}
}
if(ret==0)
{ret= 2; goto ex;}
while(1) {
ret= Dirseq_next_adr(dirseq,name,0);
if(ret==0)
break;
if(ret<0) {
sprintf(xorriso->info_text,"Failed to obtain next directory entry");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
{ret= -1; goto ex;}
}
ret= Xorriso_make_abs_adr(xorriso, wd, name, adr, flag&4);
if(ret<=0)
goto ex;
ret= Xorriso_regexec(xorriso, adr, &failed_at, 1);
if(ret>0) { /* no match */
if(failed_at <= *dive_count) /* no hope for a match */
continue;
path= adr;
if(adr[0]!='/') {
path= path_data;
ret= Xorriso_make_abs_adr(xorriso, xorriso->wdx, adr, path, 1|4);
if(ret<=0)
goto ex;
}
if(follow_links)
ret= stat(path,&stbuf);
else
ret= lstat(path,&stbuf);
if(ret==-1)
continue;
if(!S_ISDIR(stbuf.st_mode))
continue;
if(dir_dev != stbuf.st_dev && !follow_mount)
continue;
/* dive deeper */
ret= Xorriso_obtain_pattern_files_x(xorriso, adr, path,
filec, filev, count_limit, mem, dive_count, flag|2);
if(ret<=0)
goto ex;
} else {
ret= Xorriso_register_matched_adr(xorriso, adr, count_limit,
filec, filev, mem, flag&1);
if(ret<0)
goto ex;
if(ret==0)
break;
}
}
ret= 1;
ex:;
if(adr!=NULL)
free(adr);
if(name!=NULL)
free(name);
if(path_data!=NULL)
free(path_data);
Dirseq_destroy(&dirseq,0);
if(flag&2)
(*dive_count)--;
return(ret);
}
int Xorriso_eval_nonmatch(struct XorrisO *xorriso, char *pattern,
int *nonconst_mismatches, off_t *mem, int flag)
{
int k,l;
/* Is this a constant pattern ? */
for(k= 0; k<xorriso->re_fill; k++) {
if(xorriso->re_constants[k]==NULL)
break;
if(xorriso->re_constants[k][0]==0)
break;
}
if(k<xorriso->re_fill)
(*nonconst_mismatches)++; /* it is not */
l= strlen(pattern)+1;
(*mem)+= sizeof(char *)+l;
if(l % sizeof(char *))
(*mem)+= sizeof(char *)-(l % sizeof(char *));
return(1);
}
/* @param flag bit0= a match count !=1 is a SORRY event
bit1= a match count !=1 is a FAILURE event
*/
int Xorriso_check_matchcount(struct XorrisO *xorriso,
int count, int nonconst_mismatches, int num_patterns,
char **patterns, int flag)
{
char sfe[5*SfileadrL];
if((flag&1) && (count!=1 || nonconst_mismatches)){
if(count-nonconst_mismatches>0)
sprintf(xorriso->info_text,
"Pattern match with more than one file object");
else
sprintf(xorriso->info_text, "No pattern match with any file object");
if(num_patterns==1)
sprintf(xorriso->info_text+strlen(xorriso->info_text), ": %s",
Text_shellsafe(patterns[0], sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
(flag&2 ? "FAILURE" : "SORRY"), 0);
return(0);
}
return(1);
}
int Xorriso_no_pattern_memory(struct XorrisO *xorriso, off_t mem, int flag)
{
char mem_text[80];
Sfile_scale((double) mem, mem_text,5,1e4,1);
sprintf(xorriso->info_text,
"Cannot allocate enough memory (%s) for pattern expansion",
mem_text);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
return(1);
}
int Xorriso_alloc_pattern_mem(struct XorrisO *xorriso, off_t mem,
int count, char ***filev, int flag)
{
char mem_text[80], limit_text[80];
Sfile_scale((double) mem, mem_text,5,1e4,0);
sprintf(xorriso->info_text,
"Temporary memory needed for pattern expansion : %s", mem_text);
if(!(flag&1))
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
if(mem > xorriso->temp_mem_limit) {
Sfile_scale((double) xorriso->temp_mem_limit, limit_text,5,1e4,1);
sprintf(xorriso->info_text,
"List of matching file addresses exceeds -temp_mem_limit (%s > %s)",
mem_text, limit_text);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
(*filev)= (char **) calloc(count, sizeof(char *));
if(*filev==NULL) {
Xorriso_no_pattern_memory(xorriso, mem, 0);
return(-1);
}
return(1);
}
/* @param flag bit0= a match count !=1 is a FAILURE event
bit1= with bit0 tolerate 0 matches if pattern is a constant
*/
int Xorriso_expand_disk_pattern(struct XorrisO *xorriso,
int num_patterns, char **patterns, int extra_filec,
int *filec, char ***filev, off_t *mem, int flag)
{
int ret, count= 0, abs_adr= 0, i, was_count, was_filec;
int nonconst_mismatches= 0, dive_count= 0;
char sfe[5*SfileadrL], dir_adr[SfileadrL];
*filec= 0;
*filev= NULL;
xorriso->search_mode= 3;
xorriso->structured_search= 1;
for(i= 0; i<num_patterns; i++) {
ret= Xorriso_prepare_expansion_pattern(xorriso, patterns[i], 4);
if(ret<=0)
return(ret);
if(ret==2)
abs_adr= 4;
if(patterns[i][0]=='/' || abs_adr) {
strcpy(dir_adr, "/");
abs_adr= 4;
} else {
strcpy(dir_adr, xorriso->wdx);
if(dir_adr[0]==0)
strcpy(dir_adr, "/");
ret= Sfile_type(dir_adr, 1|4);
if(ret!=2) {
Xorriso_msgs_submit(xorriso, 0, dir_adr, 0, "ERRFILE", 0);
sprintf(xorriso->info_text,
"Address set by -cdx is not a directory: %s",
Text_shellsafe(dir_adr, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
}
/* count the matches */
was_count= count;
ret= Xorriso_obtain_pattern_files_x(xorriso, "", dir_adr, &count, NULL, 0,
mem, &dive_count, 1 | abs_adr);
if(ret<=0)
goto ex;
if(was_count==count && strcmp(patterns[i],"*")!=0 && (flag&3)!=1) {
count++;
ret= Xorriso_eval_nonmatch(xorriso, patterns[i],
&nonconst_mismatches, mem, 0);
if(ret<=0)
goto ex;
}
}
ret= Xorriso_check_matchcount(xorriso, count, nonconst_mismatches,
num_patterns, patterns, (flag&1)|2);
if(ret<=0)
goto ex;
count+= extra_filec;
mem+= extra_filec*sizeof(char *);
if(count<=0)
{ret= 0; goto ex;}
ret= Xorriso_alloc_pattern_mem(xorriso, *mem, count, filev, 0);
if(ret<=0)
goto ex;
/* now store addresses */
for(i= 0; i<num_patterns; i++) {
ret= Xorriso_prepare_expansion_pattern(xorriso, patterns[i], 4);
if(ret<=0)
return(ret);
if(patterns[i][0]=='/' || abs_adr) {
strcpy(dir_adr, "/");
abs_adr= 4;
} else {
strcpy(dir_adr, xorriso->wdx);
if(dir_adr[0]==0)
strcpy(dir_adr, "/");
}
was_filec= *filec;
ret= Xorriso_obtain_pattern_files_x(xorriso, "", dir_adr, filec, *filev,
count, mem, &dive_count, abs_adr);
if(ret<=0)
goto ex;
if(was_filec == *filec && strcmp(patterns[i],"*")!=0) {
(*filev)[*filec]= strdup(patterns[i]);
if((*filev)[*filec]==NULL) {
(*mem)= strlen(patterns[i])+1;
Xorriso_no_pattern_memory(xorriso, *mem, 0);
ret= -1; goto ex;
}
(*filec)++;
}
}
ret= 1;
ex:;
if(ret<=0) {
if(filev!=NULL)
Sfile_destroy_argv(&count, filev, 0);
*filec= 0;
}
return(ret);
}
/* @param flag bit0= command without pattern capability
bit1= disk_pattern rather than iso_rr_pattern
*/
int Xorriso_warn_of_wildcards(struct XorrisO *xorriso, char *path, int flag)
{
if(strchr(path,'*')!=NULL || strchr(path,'?')!=NULL ||
strchr(path,'[')!=NULL) {
if(flag&1) {
sprintf(xorriso->info_text,
"Pattern expansion of wildcards \"*?[\" does not apply to this command");
} else {
sprintf(xorriso->info_text,
"Pattern expansion of wildcards \"*?[\" is disabled by command %s",
(flag&2) ? "-disk_pattern or -pathspecs" : "-iso_rr_pattern");
}
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
sprintf(xorriso->info_text,"Pattern seen: %s\n", path);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
return(1);
}
return(0);
}

74
xorriso/match.h Normal file
View File

@ -0,0 +1,74 @@
/* 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 implementation of functions for pattern matching.
*/
#ifndef Xorriso_pvt_match_includeD
#define Xorriso_pvt_match_includeD yes
int Xorriso_prepare_regex(struct XorrisO *xorriso, char *adr, int flag);
/* @return 0=match , else no match
*/
int Xorriso_regexec(struct XorrisO *xorriso, char *to_match, int *failed_at,
int flag);
int Xorriso_is_in_patternlist(struct XorrisO *xorriso,
struct Xorriso_lsT *patternlist, char *path, int flag);
char *Xorriso_get_pattern(struct XorrisO *xorriso,
struct Xorriso_lsT *patternlist, int index, int flag);
int Xorriso_prepare_expansion_pattern(struct XorrisO *xorriso, char *pattern,
int flag);
/* @param flag bit0= count results rather than storing them
@return <=0 error , 1 is root (end processing) ,
2 is not root (go on processing)
*/
int Xorriso_check_for_root_pattern(struct XorrisO *xorriso,
int *filec, char **filev, int count_limit, off_t *mem, int flag);
/* @param flag bit0= count result rather than storing it
bit1= unexpected change of number is a FATAL event
*/
int Xorriso_register_matched_adr(struct XorrisO *xorriso,
char *adr, int count_limit,
int *filec, char **filev, off_t *mem, int flag);
int Xorriso_eval_nonmatch(struct XorrisO *xorriso, char *pattern,
int *nonconst_mismatches, off_t *mem, int flag);
/* @param flag bit0= a match count !=1 is a SORRY event
*/
int Xorriso_check_matchcount(struct XorrisO *xorriso,
int count, int nonconst_mismatches, int num_patterns,
char **patterns, int flag);
int Xorriso_no_pattern_memory(struct XorrisO *xorriso, off_t mem, int flag);
int Xorriso_alloc_pattern_mem(struct XorrisO *xorriso, off_t mem,
int count, char ***filev, int flag);
/* @param flag bit0= command without pattern capability
bit1= disk_pattern rather than iso_rr_pattern
*/
int Xorriso_warn_of_wildcards(struct XorrisO *xorriso, char *path, int flag);
/* @param flag bit0= a match count !=1 is a FAILURE event
bit1= with bit0 tolerate 0 matches if pattern is a constant
*/
int Xorriso_expand_disk_pattern(struct XorrisO *xorriso,
int num_patterns, char **patterns, int extra_filec,
int *filec, char ***filev, off_t *mem, int flag);
#endif /* ! Xorriso_pvt_match_includeD */

1177
xorriso/misc_funct.c Normal file

File diff suppressed because it is too large Load Diff

89
xorriso/misc_funct.h Normal file
View File

@ -0,0 +1,89 @@
/* 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 cellaneous helper functions of xorriso.
*/
#ifndef Xorriso_pvt_misc_includeD
#define Xorriso_pvt_misc_includeD yes
#include <regex.h>
char *Text_shellsafe(char *in_text, char *out_text, int flag);
int Sort_argv(int argc, char **argv, int flag);
/* @param flag bit0= single letters */
char *Ftypetxt(mode_t st_mode, int flag);
/* @param flag bit0=with year and seconds
bit1=timestamp format YYYY.MM.DD.hhmmss
*/
char *Ftimetxt(time_t t, char timetext[40], int flag);
int System_uname(char **sysname, char **release, char **version,
char **machine, int flag);
/** Convert a text into a number of type double and multiply it by unit code
[kmgtpe] (2^10 to 2^60) or [s] (2048). (Also accepts capital letters.)
@param text Input like "42", "2k", "3.14m" or "-1g"
@param flag Bitfield for control purposes:
bit0= return -1 rathern than 0 on failure
@return The derived double value
*/
double Scanf_io_size(char *text, int flag);
/*
@flag bit0= do not initialize *diff_count
@return <0 error , 0 = mismatch , 1 = match
*/
int Compare_text_lines(char *text1, char *text2, int *diff_count, int flag);
time_t Decode_timestring(char *code, time_t *date, int flag);
int Decode_ecma119_format(struct tm *erg, char *text, int flag);
int Wait_for_input(int fd, int microsec, int flag);
int Fileliste__target_source_limit(char *line, char sep, char **limit_pt,
int flag);
int Hex_to_bin(char *hex,
int bin_size, int *bin_count, unsigned char *bin_data, int flag);
/* bit0= append (text!=NULL) */
int Sregex_string(char **handle, char *text, int flag);
/* @param flag bit0= only test expression whether compilable
*/
int Sregex_match(char *pattern, char *text, int flag);
/*
vars[][0] points to the variable names, vars[][1] to their contents.
start marks the begin of variable names. It must be non-empty. esc before
start disables this meaning. start and esc may be equal but else they must
have disjoint character sets.
end marks the end of a variable name. It may be empty but if non-empty it
must not appear in vars[][0].
@param flag bit0= Substitute unknown variables by empty text
(else copy start,name,end unaltered to result).
Parameter end must be non-empty for that.
*/
int Sregex_resolve_var(char *form, char *vars[][2], int num_vars,
char *start, char *end, char *esc,
char *result, int result_size, int flag);
/* reg_expr should be twice as large as bourne_expr ( + 2 to be exact) */
/* return: 2= bourne_expr is surely a constant */
int Xorriso__bourne_to_reg(char bourne_expr[], char reg_expr[], int flag);
#endif /* ! Xorriso_pvt_misc_includeD */

1901
xorriso/opts_a_c.c Normal file

File diff suppressed because it is too large Load Diff

1823
xorriso/opts_d_h.c Normal file

File diff suppressed because it is too large Load Diff

1179
xorriso/opts_i_o.c Normal file

File diff suppressed because it is too large Load Diff

1764
xorriso/opts_p_z.c Normal file

File diff suppressed because it is too large Load Diff

2051
xorriso/parse_exec.c Normal file

File diff suppressed because it is too large Load Diff

88
xorriso/parse_exec.h Normal file
View File

@ -0,0 +1,88 @@
/* 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 functions which deal with parsing
and interpretation of command input.
*/
#ifndef Xorriso_pvt_cmd_includeD
#define Xorriso_pvt_cmd_includeD yes
/* @param flag bit0= do not warn of wildcards
bit1= these are disk_paths
*/
int Xorriso_end_idx(struct XorrisO *xorriso,
int argc, char **argv, int idx, int flag);
int Xorriso_opt_args(struct XorrisO *xorriso, char *cmd,
int argc, char **argv, int idx,
int *end_idx, int *optc, char ***optv, int flag);
int Xorriso_get_problem_status(struct XorrisO *xorriso, char severity[80],
int flag);
int Xorriso_set_problem_status(struct XorrisO *xorriso, char *severity,
int flag);
/**
@param flag bit0= do not issue own event messages
bit1= take xorriso->request_to_abort as reason for abort
@return Gives the advice:
2= pardon was given, go on
1= no problem, go on
0= function failed but xorriso would not abort, go on
<0= do abort
-1 = due to problem_status
-2 = due to xorriso->request_to_abort
*/
int Xorriso_eval_problem_status(struct XorrisO *xorriso, int ret, int flag);
int Xorriso_cpmv_args(struct XorrisO *xorriso, char *cmd,
int argc, char **argv, int *idx,
int *optc, char ***optv, char eff_dest[SfileadrL],
int flag);
/* @param flag bit0= with adr_mode sbsector: adr_value is possibly 16 too high
*/
int Xorriso_decode_load_adr(struct XorrisO *xorriso, char *cmd,
char *adr_mode, char *adr_value,
int *entity_code, char entity_id[81],
int flag);
int Xorriso_check_name_len(struct XorrisO *xorriso, char *name, int size,
char *cmd, int flag);
/* @param flag bit0= prepend wd only if name does not begin by '/'
bit2= prepend wd (automatically done if wd[0]!=0)
*/
int Xorriso_make_abs_adr(struct XorrisO *xorriso, char *wd, char *name,
char adr[], int flag);
/* @param flag bit0= do not complain in case of error, but set info_text */
int Xorriso_convert_datestring(struct XorrisO *xorriso, char *cmd,
char *time_type, char *timestring,
int *t_type, time_t *t, int flag);
int Xorriso_check_temp_mem_limit(struct XorrisO *xorriso, off_t mem, int flag);
/* @param flag bit0= use env_path to find the desired program
*/
int Xorriso_execv(struct XorrisO *xorriso, char *cmd, char *env_path,
int *status, int flag);
int Xorriso_path_is_excluded(struct XorrisO *xorriso, char *path, int flag);
/* Normalize ACL and sort apart "access" ACL from "default" ACL.
*/
int Xorriso_normalize_acl_text(struct XorrisO *xorriso, char *in_text,
char **access_acl_text, char **default_acl_text, int flag);
#endif /* ! Xorriso_pvt_cmd_includeD */

2011
xorriso/read_run.c Normal file

File diff suppressed because it is too large Load Diff

70
xorriso/read_run.h Normal file
View File

@ -0,0 +1,70 @@
/* 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 functions which
*/
#ifndef Xorriso_pvt_read_run_includeD
#define Xorriso_pvt_read_run_includeD yes
int Xorriso__read_pacifier(IsoImage *image, IsoFileSource *filesource);
int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path,
IsoNode *node, int flag);
int Xorriso_restore_implicit_properties(struct XorrisO *xorriso,
char *full_disk_path, char *disk_path, char *full_img_path, int flag);
int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
char *img_path, off_t img_offset,
char *disk_path, off_t disk_offset, off_t bytes,
int flag);
int Xorriso_restore_overwrite(struct XorrisO *xorriso,
IsoNode *node, char *img_path,
char *path, char *nominal_path,
struct stat *stbuf, int flag);
int Xorriso_restore_target_hl(struct XorrisO *xorriso, IsoNode *node,
char *disk_path, int *node_idx, int flag);
int Xorriso_restore_prefix_hl(struct XorrisO *xorriso, IsoNode *node,
char *disk_path, int node_idx, int flag);
int Xorriso_register_node_target(struct XorrisO *xorriso, int node_idx,
char *disk_path, int flag);
int Xorriso_restore_disk_object(struct XorrisO *xorriso,
char *img_path, IsoNode *node,
char *disk_path,
off_t offset, off_t bytes, int flag);
int Xorriso_handle_collision(struct XorrisO *xorriso,
IsoNode *node, char *img_path,
char *disk_path, char *nominal_disk_path,
int *stbuf_ret, int flag);
int Xorriso_restore_tree(struct XorrisO *xorriso, IsoDir *dir,
char *img_dir_path, char *disk_dir_path,
off_t boss_mem,
struct LinkiteM *link_stack, int flag);
int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node,
char *img_path, char *disk_path,
off_t img_offset, off_t disk_offset,
off_t bytes, int flag);
#endif /* ! Xorriso_pvt_read_run_includeD */

877
xorriso/sfile.c Normal file
View File

@ -0,0 +1,877 @@
/* 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 implementation of functions around files and strings.
*/
#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 <pwd.h>
#include <grp.h>
#include "sfile.h"
/* @param flag bit0= do not clip of carriage return at line end
*/
char *Sfile_fgets_n(char *line, int maxl, FILE *fp, int flag)
{
int l;
char *ret;
ret= fgets(line,maxl,fp);
if(ret==NULL)
return(NULL);
l= strlen(line);
if(l > 0 && !(flag & 1)) if(line[l-1] == '\r') line[--l]= 0;
if(l > 0) if(line[l-1] == '\n') line[--l]= 0;
if(l > 0 && !(flag & 1)) if(line[l-1] == '\r') line[--l]= 0;
return(ret);
}
int Sfile_count_components(char *path, int flag)
/*
bit0= do not ignore trailing slash
bit1= do not ignore empty components (other than the empty root name)
*/
{
int l,count= 0;
char *cpt;
l= strlen(path);
if(l==0)
return(0);
count= 1;
for(cpt= path+l-1;cpt>=path;cpt--) {
if(*cpt=='/') {
if(*(cpt+1)==0 && !(flag&1))
continue;
if(*(cpt+1)=='/' && !(flag&2))
continue;
count++;
}
}
return(count);
}
int Sfile_component_pointer(char *path, char **sourcept, int idx, int flag)
/*
bit0= do not ignore trailing slash
bit1= do not ignore empty components (other than the empty root name)
bit2= accept 0 as '/'
*/
{
int count= 0;
char *spt;
for(spt= path;*spt!=0 || (flag&4);spt++) {
if(count>=idx) {
*sourcept= spt;
return(1);
}
if(*spt=='/' || *spt==0) {
if(*(spt+1)=='/' && !(flag&2))
continue;
if(*(spt+1)==0 && !(flag&1))
continue;
count++;
}
}
if((flag&1) && count>=idx)
return(1);
return(0);
}
int Sfile_leafname(char *path, char leafname[SfileadrL], int flag)
{
int count, ret;
char *lpt;
leafname[0]= 0;
count= Sfile_count_components(path, 0);
if(count==0)
return(0);
ret= Sfile_component_pointer(path, &lpt, count-1, 0);
if(ret<=0)
return(ret);
if(Sfile_str(leafname, lpt, 0)<=0)
return(0);
lpt= strchr(leafname, '/');
if(lpt!=NULL)
*lpt= 0;
return(1);
}
int Sfile_add_to_path(char path[SfileadrL], char *addon, int flag)
{
int l;
l= strlen(path);
if(l+1>=SfileadrL)
return(0);
if(l==0) {
strcpy(path,"/");
l= 1;
} else if(path[l-1]!='/') {
path[l++]= '/';
path[l]= 0;
}
if(l+strlen(addon)>=SfileadrL)
return(0);
if(addon[0]=='/')
strcpy(path+l,addon+1);
else
strcpy(path+l,addon);
return(1);
}
int Sfile_prepend_path(char *prefix, char path[SfileadrL], int flag)
{
int l, i;
l= strlen(path)+strlen(prefix)+1;
if(l>=SfileadrL) {
#ifdef Not_yeT
/* >>> ??? how to transport messages to xorriso ? */
sprintf(xorriso->info_text,
"Combination of wd and relative address too long (%d > %d)",
l,SfileadrL-1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
#endif
return(-1);
}
l-= strlen(path);
for(i= strlen(path)+1; i>=0; i--)
path[i+l]= path[i];
strcpy(path,prefix);
path[l-1]= '/';
return(1);
}
int Sfile_being_group_member(struct stat *stbuf, int flag)
{
int i, suppl_groups;
gid_t *suppl_glist;
if (getegid()==stbuf->st_gid)
return(1);
suppl_groups= getgroups(0, NULL);
suppl_glist= (gid_t *) malloc((suppl_groups + 1) * sizeof(gid_t));
if (suppl_glist==NULL)
return(-1);
suppl_groups= getgroups(suppl_groups+1,suppl_glist);
for (i= 0; i<suppl_groups; i++) {
if (suppl_glist[i]==stbuf->st_gid) {
free((char *) suppl_glist);
return(1);
}
}
free((char *) suppl_glist);
return(0);
}
int Sfile_type(char *filename, int flag)
/*
bit0= return -1 if file is missing
bit1= return a hardlink with siblings as type 5
bit2= evaluate eventual link target rather than the link object itself
bit3= return a socket or a char device as types 7 or 8 rather than 0
*/
/*
return:
0=unknown
1=regular
2=directory
3=symbolic link
4=named pipe
5=multiple hardlink (with bit1)
6=block device
7=socket (with bit3)
8=character device (with bit3)
*/
{
struct stat stbuf;
if(flag&4) {
if(stat(filename,&stbuf)==-1) {
if(flag&1) return(-1);
else return(0);
}
} else {
if(lstat(filename,&stbuf)==-1) {
if(flag&1) return(-1);
else return(0);
}
}
if(S_ISREG(stbuf.st_mode)) {
if(flag&2)
if(stbuf.st_nlink>1)
return(5);
return(1);
}
if(S_ISDIR(stbuf.st_mode))
return(2);
if((stbuf.st_mode&S_IFMT)==S_IFLNK)
return(3);
if(S_ISFIFO(stbuf.st_mode))
return(4);
if(S_ISBLK(stbuf.st_mode))
return(6);
if(flag&8)
if((stbuf.st_mode&S_IFMT)==S_IFSOCK)
return(7);
if(flag&8)
if(S_ISCHR(stbuf.st_mode))
return(8);
return(0);
}
char *Sfile_datestr(time_t tim, short int flag)
/*
bit0=with hours+minutes
bit1=with seconds
bit8= local time rather than UTC
*/
{
static char zeitcode[80]={"000000"};
char puff[80];
struct tm *azt;
if(flag&256)
azt = localtime(&tim);
else
azt = gmtime(&tim);
if(azt->tm_year>99)
sprintf(zeitcode,"%c%1.1d%2.2d%2.2d",
'A'+(azt->tm_year-100)/10,azt->tm_year%10,
azt->tm_mon+1,azt->tm_mday);
else
sprintf(zeitcode,"%2.2d%2.2d%2.2d",
azt->tm_year,azt->tm_mon+1,azt->tm_mday);
if(flag&1){
sprintf(puff,".%2.2d%2.2d",azt->tm_hour,azt->tm_min);
strcat(zeitcode,puff);
}
if(flag&2){
sprintf(puff,"%2.2d",azt->tm_sec);
strcat(zeitcode,puff);
}
return(zeitcode);
}
int Sfile_scale(double value, char *result, int siz, double thresh, int flag)
/*
bit0= eventually ommit 'b'
bit1= make text as short as possible
bit2= no fraction (if it would fit at all)
*/
{
char scale_c,scales[7],form[80], *negpt= NULL, *cpt;
int i,dec_siz= 0,avail_siz= 1;
if(value<0) {
value= -value;
siz--;
result[0]= '-';
negpt= result;
result++;
}
strcpy(scales,"bkmgtp");
scale_c= scales[0];
for(i=1;scales[i]!=0;i++) {
if(value<thresh-0.5)
break;
value/= 1024.0;
scale_c= scales[i];
}
if(scale_c!='b' && !(flag&4)) { /* is there room for fractional part ? */
avail_siz= siz-1;
sprintf(form,"%%.f");
sprintf(result,"%.f",value);
if(strlen(result)<=avail_siz-2)
dec_siz= 1; /* we are very modest */
}
if(scale_c=='b' && (flag&1)) {
if(flag&2)
sprintf(form,"%%.f");
else
sprintf(form,"%%%d.f",siz);
sprintf(result,form,value);
} else {
if(flag&2)
sprintf(form,"%%.f%%c");
else if(dec_siz>0)
sprintf(form,"%%%d.%df%%c",avail_siz,dec_siz);
else
sprintf(form,"%%%d.f%%c",siz-1);
sprintf(result,form,value,scale_c);
}
if(negpt != NULL) {
for(cpt= result; *cpt==' '; cpt++);
if(cpt > result) {
*negpt= ' ';
*(cpt - 1)= '-';
}
}
return(1);
}
int Sfile_off_t_text(char text[80], off_t num, int flag)
{
char *tpt;
off_t hnum, scale= 1;
int digits= 0, d, i;
tpt= text;
hnum= num;
if(hnum<0) {
*(tpt++)= '-';
hnum= -num;
}
if(hnum<0) { /* it can stay nastily persistent */
strcpy(text, "_overflow_");
return(0);
}
for(i= 0; i<23; i++) { /* good for up to 70 bit = 10 exp 21.07... */
if(hnum==0)
break;
hnum/= 10;
if(hnum)
scale*= 10;
}
if(i==0) {
strcpy(text, "0");
return(1);
}
if(i==23) {
strcpy(text, "_overflow_");
return(0);
}
digits= i;
hnum= num;
for(; i>0; i--) {
d= hnum/scale;
tpt[digits-i]= '0'+d;
hnum= hnum%scale;
scale/= 10;
}
tpt[digits]= 0;
return(1);
}
/* Converts backslash codes into single characters:
\a BEL 7 , \b BS 8 , \e ESC 27 , \f FF 12 , \n LF 10 , \r CR 13 ,
\t HT 9 , \v VT 11 , \\ \ 92
\[0-9][0-9][0-9] octal code , \x[0-9a-f][0-9a-f] hex code ,
\cX control-x (ascii(X)-64)
@param upto maximum number of characters to examine for backslash.
The scope of a backslash (0 to 3 characters) is not affected.
@param eaten returns the difference in length between input and output
@param flag bit0= only determine *eaten, do not convert
bit1= allow to convert \000 to binary 0
*/
int Sfile_bsl_interpreter(char *text, int upto, int *eaten, int flag)
{
char *rpt, *wpt, num_text[8], wdummy[8];
unsigned int num= 0;
*eaten= 0;
wpt= text;
for(rpt= text; *rpt != 0 && rpt - text < upto; rpt++) {
if(flag & 1)
wpt= wdummy;
if(*rpt == '\\') {
rpt++;
(*eaten)++;
if(*rpt == 'a') {
*(wpt++)= 7;
} else if(*rpt == 'b') {
*(wpt++)= 8;
} else if(*rpt == 'e') {
*(wpt++)= 27;
} else if(*rpt == 'f') {
*(wpt++)= 12;
} else if(*rpt == 'n') {
*(wpt++)= 10;
} else if(*rpt == 'r') {
*(wpt++)= 13;
} else if(*rpt == 't') {
*(wpt++)= 9;
} else if(*rpt == 'v') {
*(wpt++)= 11;
} else if(*rpt == '\\') {
*(wpt++)= '\\';
} else if(rpt[0] >= '0' && rpt[0] <= '7' &&
rpt[1] >= '0' && rpt[1] <= '7' &&
rpt[2] >= '0' && rpt[2] <= '7') {
num_text[0]= '0';
num_text[1]= *(rpt + 0);
num_text[2]= *(rpt + 1);
num_text[3]= *(rpt + 2);
num_text[4]= 0;
sscanf(num_text, "%o", &num);
if((num > 0 || (flag & 2)) && num <= 255) {
rpt+= 2;
(*eaten)+= 2;
*(wpt++)= num;
} else
goto not_a_code;
} else if(rpt[0] == 'x' &&
((rpt[1] >= '0' && rpt[1] <= '9') ||
(rpt[1] >= 'A' && rpt[1] <= 'F') ||
(rpt[1] >= 'a' && rpt[1] <= 'f'))
&&
((rpt[2] >= '0' && rpt[2] <= '9') ||
(rpt[2] >= 'A' && rpt[2] <= 'F') ||
(rpt[2] >= 'a' && rpt[2] <= 'f'))
) {
num_text[0]= *(rpt + 1);
num_text[1]= *(rpt + 2);
num_text[2]= 0;
sscanf(num_text, "%x", &num);
if(num > 0 && num <= 255) {
rpt+= 2;
(*eaten)+= 2;
*(wpt++)= num;
} else
goto not_a_code;
} else if(*rpt == 'c') {
if(rpt[1] > 64 && rpt[1] < 96) {
*(wpt++)= rpt[1] - 64;
rpt++;
(*eaten)++;
} else
goto not_a_code;
} else {
not_a_code:;
*(wpt++)= '\\';
rpt--;
(*eaten)--;
}
} else
*(wpt++)= *rpt;
}
*wpt= *rpt;
return(1);
}
int Sfile_argv_bsl(int argc, char ***argv, int flag)
{
int i, ret, eaten;
char **new_argv= NULL;
if(argc <= 0)
return(0);
new_argv= (char **) Smem_malloC(argc * sizeof(char *));
if(new_argv == NULL)
return(-1);
for(i= 0; i < argc; i++) {
new_argv[i]= strdup((*argv)[i]);
if(new_argv[i] == NULL)
{ret= -1; goto ex;}
ret= Sfile_bsl_interpreter(new_argv[i], strlen(new_argv[i]), &eaten, 0);
if(ret <= 0)
goto ex;
}
ret= 1;
ex:;
if(ret <= 0) {
if(new_argv != NULL)
free((char *) new_argv);
} else
*argv= new_argv;
return(ret);
}
/* @param flag bit0= only encode inside quotes
bit1= encode < 32 outside quotes except 7, 8, 9, 10, 12, 13
bit2= encode in any case above 126
bit3= encode in any case shellsafe and name-value-safe:
<=42 , 59, 60, 61, 62, 63, 92, 94, 96, >=123
*/
int Sfile_bsl_encoder(char **result, char *text, size_t text_len, int flag)
{
char *rpt, *wpt;
int count, sq_open= 0, dq_open= 0;
count= 0;
for(rpt= text; rpt - text < text_len; rpt++) {
count++;
if(flag & 8) {
if(!(*rpt <= 42 || (*rpt >= 59 && *rpt <= 63) ||
*rpt == 92 || *rpt == 94 || *rpt == 96 || *rpt >= 123))
continue;
} else if(*rpt >= 32 && *rpt <= 126 && *rpt != '\\')
continue;
if(((*rpt >= 7 && *rpt <= 13) || *rpt == 27 || *rpt == '\\') && !(flag & 8))
count++;
else
count+= 3;
}
(*result)= wpt= calloc(count + 1, 1);
if(wpt == NULL)
return(-1);
for(rpt= text; rpt - text < text_len; rpt++) {
if(*rpt == '\'')
sq_open= !(sq_open || dq_open);
if(*rpt == '"')
dq_open= !(sq_open || dq_open);
if(flag & 8) {
if(!(*rpt <= 42 || (*rpt >= 59 && *rpt <= 63) ||
*rpt == 92 || *rpt == 94 || *rpt == 96 || *rpt >= 123)) {
*(wpt++)= *rpt;
continue;
}
} else if(*rpt >= 32 && *rpt <= 126 && *rpt != '\\') {
*(wpt++)= *rpt;
continue;
} else if( ((flag & 1) && !(sq_open || dq_open)) &&
!((flag & 2) && (*rpt >= 1 && * rpt <= 31 &&
!(*rpt == 7 || *rpt == 8 || *rpt == 9 || *rpt == 10 ||
*rpt == 12 || *rpt == 13))) &&
!((flag & 4) && (*rpt > 126 || *rpt < 0)) &&
!((flag & 6) && *rpt == '\\')) {
*(wpt++)= *rpt;
continue;
}
*(wpt++)= '\\';
if(((*rpt >= 7 && *rpt <= 13) || *rpt == 27 || *rpt == '\\') && !(flag&8)) {
if(*rpt == 7)
*(wpt++)= 'a';
else if(*rpt == 8)
*(wpt++)= 'b';
else if(*rpt == 9)
*(wpt++)= 't';
else if(*rpt == 10) {
*(wpt++)= 'n';
} else if(*rpt == 11)
*(wpt++)= 'v';
else if(*rpt == 12)
*(wpt++)= 'f';
else if(*rpt == 13)
*(wpt++)= 'c';
else if(*rpt == 27)
*(wpt++)= 'e';
else if(*rpt == '\\')
*(wpt++)= '\\';
} else {
sprintf(wpt, "%-3.3o", (unsigned int) *((unsigned char *) rpt));
wpt+= 3;
}
}
*wpt= 0;
return(1);
}
int Sfile_destroy_argv(int *argc, char ***argv, int flag)
{
int i;
if(*argc>0 && *argv!=NULL){
for(i=0;i<*argc;i++){
if((*argv)[i]!=NULL)
Smem_freE((*argv)[i]);
}
Smem_freE((char *) *argv);
}
*argc= 0;
*argv= NULL;
return(1);
}
int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv,
int flag)
/*
bit0= read progname as first argument from line
bit1= just release argument list argv and return
bit2= abort with return(0) if incomplete quotes are found
bit3= eventually prepend missing '-' to first argument read from line
bit4= like bit2 but only check quote completeness, do not allocate memory
bit5+6= interpretation of backslashes:
0= no interpretation, leave unchanged
1= only inside double quotes
2= outside single quotes
3= everywhere
bit7= append a NULL element to argv
*/
{
int i,pass,maxl=0,l,argzaehl=0,bufl,line_start_argc, bsl_mode, ret= 0, eaten;
char *cpt,*start;
char *buf= NULL;
Sfile_destroy_argv(argc,argv,0);
if(flag&2)
{ret= 1; goto ex;}
if(flag & 16)
flag|= 4;
bsl_mode= (flag >> 5) & 3;
buf= calloc(strlen(line) + SfileadrL, 1);
if(buf == NULL)
{ret= -1; goto ex;}
for(pass=0;pass<2;pass++) {
cpt= line-1;
if(!(flag&1)){
argzaehl= line_start_argc= 1;
if(pass==0)
maxl= strlen(progname);
else
strcpy((*argv)[0],progname);
} else {
argzaehl= line_start_argc= 0;
if(pass==0) maxl= 0;
}
while(*(++cpt)!=0){
if(isspace(*cpt)) continue;
start= cpt;
buf[0]= 0;
cpt--;
while(*(++cpt)!=0) {
if(isspace(*cpt)) break;
if(*cpt=='"'){
l= cpt-start; bufl= strlen(buf);
if(l>0) {
strncpy(buf + bufl, start, l); buf[bufl + l]= 0;
if(bsl_mode >= 3) {
ret= Sfile_bsl_interpreter(buf, l, &eaten, 0);
if(ret <= 0)
goto ex;
}
}
l= strlen(buf);
start= cpt+1;
while(*(++cpt)!=0) if(*cpt=='"') break;
if((flag&4) && *cpt==0)
{ret= 0; goto ex;}
l= cpt-start; bufl= strlen(buf);
if(l>0) {
strncpy(buf + bufl, start, l);
buf[bufl + l]= 0;
if(bsl_mode >= 1) {
ret= Sfile_bsl_interpreter(buf + bufl, l, &eaten, 0);
if(ret <= 0)
goto ex;
}
}
start= cpt+1;
}else if(*cpt=='\''){
l= cpt-start; bufl= strlen(buf);
if(l>0) {
strncpy(buf + bufl, start, l); buf[bufl + l]= 0;
if(bsl_mode >= 3) {
ret= Sfile_bsl_interpreter(buf, l, &eaten, 0);
if(ret <= 0)
goto ex;
}
}
l= strlen(buf);
start= cpt+1;
while(*(++cpt)!=0) if(*cpt=='\'') break;
if((flag&4) && *cpt==0)
{ret= 0; goto ex;}
l= cpt-start; bufl= strlen(buf);
if(l>0) {
strncat(buf,start,l);buf[bufl+l]= 0;
if(bsl_mode >= 2) {
ret= Sfile_bsl_interpreter(buf + bufl, l, &eaten, 0);
if(ret <= 0)
goto ex;
}
}
start= cpt+1;
}
if(*cpt==0) break;
}
l= cpt-start;
bufl= strlen(buf);
if(l>0) {
strncpy(buf + bufl, start, l); buf[bufl + l]= 0;
if(bsl_mode >= 3) {
ret= Sfile_bsl_interpreter(buf, l, &eaten, 0);
if(ret <= 0)
goto ex;
}
}
l= strlen(buf);
if(pass==0){
if(argzaehl==line_start_argc && (flag&8))
if(buf[0]!='-' && buf[0]!=0 && buf[0]!='#')
l++;
if(l>maxl) maxl= l;
}else{
strcpy((*argv)[argzaehl],buf);
if(argzaehl==line_start_argc && (flag&8))
if(buf[0]!='-' && buf[0]!=0 && buf[0]!='#')
sprintf((*argv)[argzaehl],"-%s", buf);
}
argzaehl++;
if(*cpt==0) break;
}
if(pass==0){
if(flag & 16)
{ret= 1; goto ex;}
*argc= argzaehl;
if(argzaehl>0 || (flag & 128)) {
*argv= (char **) Smem_malloC((argzaehl + !!(flag & 128))
* sizeof(char *));
if(*argv==NULL)
{ret= -1; goto ex;}
}
for(i=0;i<*argc;i++) {
(*argv)[i]= (char *) Smem_malloC((maxl+1));
if((*argv)[i]==NULL)
{ret= -1; goto ex;}
}
if(flag & 128)
(*argv)[*argc]= NULL;
}
}
ret= 1;
ex:
if(buf != NULL)
free(buf);
return(ret);
}
/* @param flag bit0= append */
int Sfile_str(char target[SfileadrL], char *source, int flag)
{
int l;
l= strlen(source);
if(flag&1)
l+= strlen(target);
if(l>=SfileadrL) {
fprintf(stderr, "--- Path string overflow (%d > %d). Malicious input ?\n",
l,SfileadrL-1);
return(0);
}
if(flag&1)
strcat(target, source);
else
strcpy(target, source);
return(1);
}
/** Combine environment variable HOME with given filename
@param filename Address relative to $HOME
@param fileadr Resulting combined address
@param fa_size Size of array fileadr
@param flag Unused yet
@return 1=ok , 0=no HOME variable , -1=result address too long
*/
int Sfile_home_adr_s(char *filename, char *fileadr, int fa_size, int flag)
{
char *home;
strcpy(fileadr,filename);
home= getenv("HOME");
if(home==NULL)
return(0);
if(strlen(home)+strlen(filename)+1>=fa_size)
return(-1);
strcpy(fileadr,home);
if(filename[0]!=0){
strcat(fileadr,"/");
strcat(fileadr,filename);
}
return(1);
}
/** Return a double representing seconds and microseconds since 1 Jan 1970 */
double Sfile_microtime(int flag)
{
struct timeval tv;
struct timezone tz;
gettimeofday(&tv,&tz);
return((double) (tv.tv_sec+1.0e-6*tv.tv_usec));
}
int Sfile_decode_datestr(struct tm *reply, char *text, int flag)
/* YYMMDD[.hhmm[ss]] */
{
int i,l;
time_t current_time;
struct tm *now;
current_time= time(0);
now= localtime(&current_time);
for(i=0;i<sizeof(struct tm);i++)
((char *) reply)[i]= ((char *) now)[i];
if(text[0]<'0'|| (text[0]>'9' && text[0]<'A') || text[0]>'Z')
return(0);
l= strlen(text);
for(i=1;i<l;i++)
if(text[i]<'0'||text[i]>'9')
break;
if(i!=6)
return(0);
if(text[i]==0)
goto decode;
if(text[i]!='.' || (l!=11 && l!=13))
return(0);
for(i++;i<l;i++)
if(text[i]<'0'||text[i]>'9')
break;
if(i!=l)
return(0);
decode:;
reply->tm_hour= 0;
reply->tm_min= 0;
reply->tm_sec= 0;
i= 0;
if(text[0]>='A')
reply->tm_year= 100+(text[i]-'A')*10+text[1]-'0';
else
reply->tm_year= 10*(text[0]-'0')+text[1]-'0';
reply->tm_mon= 10*(text[2]-'0')+text[3]-'0'-1;
reply->tm_mday= 10*(text[4]-'0')+text[5]-'0';
if(l==6)
return(1);
reply->tm_hour= 10*(text[7]-'0')+text[8]-'0';
reply->tm_min= 10*(text[9]-'0')+text[10]-'0';
if(l==11)
return(1);
reply->tm_sec= 10*(text[11]-'0')+text[12]-'0';
return(1);
}

121
xorriso/sfile.h Normal file
View File

@ -0,0 +1,121 @@
/* 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 functions around files and strings.
*/
#ifndef Xorriso_pvt_sfile_includeD
#define Xorriso_pvt_sfile_includeD yes
#define TSOB_FELD(typ,anz) (typ *) calloc(1, (anz)*sizeof(typ));
#define Smem_malloC malloc
#define Smem_freE free
#define SfileadrL 4096
int Sfile_str(char target[SfileadrL], char *source, int flag);
double Sfile_microtime(int flag);
int Sfile_add_to_path(char path[SfileadrL], char *addon, int flag);
int Sfile_scale(double value, char *result, int siz, double thresh, int flag);
int Sfile_destroy_argv(int *argc, char ***argv, int flag);
/*
bit0= do not ignore trailing slash
bit1= do not ignore empty components (other than the empty root name)
*/
int Sfile_count_components(char *path, int flag);
/*
@param flag
bit0= return -1 if file is missing
bit1= return a hardlink with siblings as type 5
bit2= evaluate eventual link target rather than the link object itself
bit3= return a socket or a char device as types 7 or 8 rather than 0
@return
0=unknown
1=regular
2=directory
3=symbolic link
4=named pipe
5=multiple hardlink (with bit1)
6=block device
7=socket (with bit3)
8=character device (with bit3)
*/
int Sfile_type(char *filename, int flag);
/* @param flag bit0= only encode inside quotes
bit1= encode < 32 outside quotes except 7, 8, 9, 10, 12, 13
bit2= encode in any case above 126
bit3= encode in any case shellsafe:
<=42 , 59, 60, 62, 63, 92, 94, 96, >=123
*/
int Sfile_bsl_encoder(char **result, char *text, size_t text_len, int flag);
int Sfile_argv_bsl(int argc, char ***argv, int flag);
/*
bit0= read progname as first argument from line
bit1= just release argument list argv and return
bit2= abort with return(0) if incomplete quotes are found
bit3= eventually prepend missing '-' to first argument read from line
bit4= like bit2 but only check quote completeness, do not allocate memory
bit5+6= interpretation of backslashes:
0= no interpretation, leave unchanged
1= only inside double quotes
2= outside single quotes
3= everywhere
bit7= append a NULL element to argv
*/
int Sfile_make_argv(char *progname, char *line, int *argc, char ***argv,
int flag);
/* YYMMDD[.hhmm[ss]] */
int Sfile_decode_datestr(struct tm *reply, char *text, int flag);
int Sfile_off_t_text(char text[80], off_t num, int flag);
int Sfile_leafname(char *path, char leafname[SfileadrL], int flag);
/* @param flag bit0= do not clip of carriage return at line end
*/
char *Sfile_fgets_n(char *line, int maxl, FILE *fp, int flag);
/*
bit0=with hours+minutes
bit1=with seconds
bit8= local time rather than UTC
*/
char *Sfile_datestr(time_t tim, short int flag);
/* Converts backslash codes into single characters:
\a BEL 7 , \b BS 8 , \e ESC 27 , \f FF 12 , \n LF 10 , \r CR 13 ,
\t HT 9 , \v VT 11 , \\ \ 92
\[0-9][0-9][0-9] octal code , \x[0-9a-f][0-9a-f] hex code ,
\cX control-x (ascii(X)-64)
@param upto maximum number of characters to examine for backslash.
The scope of a backslash (0 to 3 characters) is not affected.
@param eaten returns the difference in length between input and output
@param flag bit0= only determine *eaten, do not convert
bit1= allow to convert \000 to binary 0
*/
int Sfile_bsl_interpreter(char *text, int upto, int *eaten, int flag);
int Sfile_prepend_path(char *prefix, char path[SfileadrL], int flag);
int Sfile_home_adr_s(char *filename, char *fileadr, int fa_size, int flag);
#endif /* ! Xorriso_pvt_sfile_includeD */

710
xorriso/sort_cmp.c Normal file
View File

@ -0,0 +1,710 @@
/* 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 sort and compare tree nodes.
*/
#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 "base_obj.h"
#include "lib_mgt.h"
#include "sort_cmp.h"
#include "iso_tree.h"
#include "iso_manip.h"
int Xorriso__findi_sorted_ino_cmp(const void *p1, const void *p2)
{
int ret;
IsoNode *n1, *n2;
n1= *((IsoNode **) p1);
n2= *((IsoNode **) p2);
ret= Xorriso__node_lba_cmp(&n1, &n2);
if(ret)
return (ret > 0 ? 1 : -1);
ret= iso_node_cmp_ino(n1, n2, 0);
return(ret);
}
/* Not suitable for qsort() but for cross-array comparisons.
p1 and p2 are actually IsoNode *p1, IsoNode *p2
*/
int Xorriso__hln_cmp(const void *p1, const void *p2)
{
int ret;
ret= Xorriso__findi_sorted_ino_cmp(&p1, &p2);
if(ret)
return (ret > 0 ? 1 : -1);
if(p1 != p2)
return(p1 < p2 ? -1 : 1);
return(0);
}
/*
p1 and p2 are actually IsoNode **p1, IsoNode **p2
*/
int Xorriso__findi_sorted_cmp(const void *p1, const void *p2)
{
int ret;
ret= Xorriso__findi_sorted_ino_cmp(p1, p2);
if(ret)
return (ret > 0 ? 1 : -1);
if(p1 != p2)
return(p1 < p2 ? -1 : 1);
return(0);
}
int Xorriso_sort_node_array(struct XorrisO *xorriso, int flag)
{
if(xorriso->node_counter <= 0)
return(0);
qsort(xorriso->node_array, xorriso->node_counter, sizeof(IsoNode *),
Xorriso__findi_sorted_cmp);
return(1);
}
int Xorriso__search_node(void *node_array[], int n,
int (*cmp)(const void *p1, const void *p2),
void *node, int *idx, int flag)
{
int ret, l, r, p, pos;
if(n == 0)
return(0);
l= 0;
r= n + 1;
while(1) {
p= (r - l) / 2;
if(p == 0)
break;
p+= l;
/* NULL elements may indicate invalid nodes. Their first valid right neigbor
will serve as proxy. If none exists, then the test pushes leftwards.
*/
for(pos= p - 1; pos < n; pos++)
if(node_array[pos] != NULL)
break;
if(pos < n)
ret= (*cmp)(&(node_array[pos]), &node);
else
ret= 1;
if(ret < 0)
l= p;
else if(ret > 0)
r= p;
else {
*idx= pos;
return(1);
}
}
return(0);
}
int Xorriso_search_in_hln_array(struct XorrisO *xorriso,
void *node, int *idx, int flag)
{
int ret;
if(xorriso->hln_array == NULL || xorriso->hln_count <= 0)
return(0);
ret= Xorriso__search_node(xorriso->hln_array, xorriso->hln_count,
Xorriso__findi_sorted_ino_cmp, node, idx, 0);
return ret;
}
int Xorriso__get_di(IsoNode *node, dev_t *dev, ino_t *ino, int flag)
{
int ret, i, i_end, imgid, error_code;
size_t value_length= 0;
char *value= NULL, msg[ISO_MSGS_MESSAGE_LEN], severity[80];
unsigned char *vpt;
static char *name= "isofs.di";
#ifdef NIX
/* <<< */
Xorriso_get_di_counteR++;
#endif /* NIX */
*dev= 0;
*ino= 0;
ret= iso_node_lookup_attr(node, name, &value_length, &value, 0);
if(ret <= 0) {
/* Drop any pending messages because there is no xorriso to take them */
iso_obtain_msgs("NEVER", &error_code, &imgid, msg, severity);
return(ret);
}
vpt= (unsigned char *) value;
for(i= 1; i <= vpt[0] && i < value_length; i++)
*dev= ((*dev) << 8) | vpt[i];
i_end= i + vpt[i] + 1;
for(i++; i < i_end && i < value_length; i++)
*ino= ((*ino) << 8) | vpt[i];
free(value);
return(1);
}
int Xorriso__di_ino_cmp(const void *p1, const void *p2)
{
int ret;
IsoNode *n1, *n2;
dev_t d1, d2;
ino_t i1, i2;
n1= *((IsoNode **) p1);
n2= *((IsoNode **) p2);
ret= Xorriso__get_di(n1, &d1, &i1, 0);
if(ret <= 0)
{d1= 0; i1= 0;}
ret= Xorriso__get_di(n2, &d2, &i2, 0);
if(ret <= 0)
{d2= 0; i2= 0;}
if(d1 < d2)
return(-1);
if(d1 > d2)
return(1);
if(i1 < i2)
return(-1);
if(i1 > i2)
return(1);
if(d1 == 0 && i1 == 0 && n1 != n2)
return(n1 < n2 ? -1 : 1);
return(0);
}
int Xorriso__di_cmp(const void *p1, const void *p2)
{
int ret;
IsoNode *n1, *n2;
ret= Xorriso__di_ino_cmp(p1, p2);
if(ret)
return(ret);
n1= *((IsoNode **) p1);
n2= *((IsoNode **) p2);
if(n1 != n2)
return(n1 < n2 ? -1 : 1);
return(0);
}
int Xorriso__sort_di(void *node_array[], int count, int flag)
{
if(count <= 0)
return(0);
qsort(node_array, count, sizeof(IsoNode *), Xorriso__di_cmp);
return(1);
}
int Xorriso_invalidate_di_item(struct XorrisO *xorriso, IsoNode *node,
int flag)
{
int ret, idx;
if(xorriso->di_array == NULL)
return(1);
ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count,
Xorriso__di_cmp, node, &idx, 0);
if(ret <= 0)
return(ret == 0);
if(xorriso->di_array[idx] != NULL)
iso_node_unref(xorriso->di_array[idx]);
xorriso->di_array[idx]= NULL;
return(1);
}
/* @param flag bit0= return 1 even if matching nodes were found but node is
not among them
bit1= use Xorriso__di_cmp() rather than Xorriso__di_ino_cmp()
*/
int Xorriso_search_di_range(struct XorrisO *xorriso, IsoNode *node,
int *idx, int *low, int *high, int flag)
{
int ret, i, found;
int (*cmp)(const void *p1, const void *p2)= Xorriso__di_ino_cmp;
if(flag & 2)
cmp= Xorriso__di_cmp;
*high= *low= *idx= -1;
ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count,
cmp, node, &found, 0);
if(ret <= 0)
return(0);
*low= *high= found;
for(i= found + 1; i < xorriso->di_count; i++)
if(xorriso->di_array[i] != NULL) {
if((*cmp)(&node, &(xorriso->di_array[i])) != 0)
break;
*high= i;
}
for(i= found - 1; i >= 0; i--)
if(xorriso->di_array[i] != NULL) {
if((*cmp)(&node, &(xorriso->di_array[i])) != 0)
break;
*low= i;
}
for(i= *low; i <= *high; i++)
if(xorriso->di_array[i] == node) {
*idx= i;
break;
}
return(*idx >= 0 || (flag & 1));
}
int Xorriso__node_lba_cmp(const void *node1, const void *node2)
{
int ret;
int lba1= 0, lba2= 0;
ret= Xorriso__file_start_lba(*((IsoNode **) node1), &lba1, 0);
if(ret!=1)
lba1= 0;
ret= Xorriso__file_start_lba(*((IsoNode **) node2), &lba2, 0);
if(ret!=1)
lba2= 0;
return(lba1-lba2);
}
int Xorriso__node_name_cmp(const void *node1, const void *node2)
{
char *name1, *name2;
name1= (char *) iso_node_get_name(*((IsoNode **) node1));
name2= (char *) iso_node_get_name(*((IsoNode **) node2));
return(strcmp(name1,name2));
}
/* @param flag bit0= only accept directory nodes
bit1= do not report memory usage as DEBUG
bit2= do not apply search pattern but accept any node
*/
int Xorriso_sorted_node_array(struct XorrisO *xorriso,
IsoDir *dir_node,
int *nodec, IsoNode ***node_array,
off_t boss_mem, int flag)
{
int i, ret, failed_at;
char *npt;
IsoDirIter *iter= NULL;
IsoNode *node;
off_t mem;
mem= ((*nodec)+1)*sizeof(IsoNode *);
ret= Xorriso_check_temp_mem_limit(xorriso, mem+boss_mem, flag&2);
if(ret<=0)
return(ret);
*node_array= calloc(sizeof(IsoNode *), (*nodec)+1);
if(*node_array==NULL) {
sprintf(xorriso->info_text,
"Cannot allocate memory for %d directory entries", *nodec);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
return(-1);
}
ret= iso_dir_get_children(dir_node, &iter);
if(ret<0) {
Xorriso_cannot_create_iter(xorriso, ret, 0);
return(-1);
}
for(i= 0; iso_dir_iter_next(iter, &node) == 1 && i<*nodec; ) {
npt= (char *) iso_node_get_name(node);
if(!(flag&4)) {
ret= Xorriso_regexec(xorriso, npt, &failed_at, 0);
if(ret)
continue; /* no match */
}
if(flag&1)
if(!LIBISO_ISDIR(node))
continue;
(*node_array)[i++]= node;
}
iso_dir_iter_free(iter);
*nodec= i;
if(*nodec<=0)
return(1);
qsort(*node_array, *nodec, sizeof(IsoNode *), Xorriso__node_name_cmp);
return(1);
}
int Xorriso_remake_hln_array(struct XorrisO *xorriso, int flag)
{
int ret, addon_nodes= 0, i, old_count, old_pt, new_pt;
IsoNode **old_nodes;
char **old_targets;
/* Count hln_targets of which the node has been deleted meanwhile */
for(i= 0; i < xorriso->hln_count; i++) {
if(xorriso->hln_targets[i] == NULL)
continue;
if(Xorriso_node_is_valid(xorriso, xorriso->hln_array[i], 0))
continue;
addon_nodes++;
}
ret= Xorriso_all_node_array(xorriso, addon_nodes, 0);
if(ret <= 0)
goto ex;
if(addon_nodes > 0) {
/* Transfer delete nodes with hln_target to node array */
for(i= 0; i < xorriso->hln_count; i++) {
if(xorriso->hln_targets[i] == NULL)
continue;
if(Xorriso_node_is_valid(xorriso, xorriso->hln_array[i], 0))
continue;
if(xorriso->node_counter < xorriso->node_array_size) {
xorriso->node_array[xorriso->node_counter++]= xorriso->hln_array[i];
iso_node_ref(xorriso->node_array[xorriso->node_counter - 1]);
}
}
}
Xorriso_sort_node_array(xorriso, 0);
old_nodes= (IsoNode **) xorriso->hln_array;
old_targets= (char **) xorriso->hln_targets;
old_count= xorriso->hln_count;
xorriso->hln_array= 0;
xorriso->hln_targets= NULL;
/* Transfer node_array to di_array without unrefering nodes */
xorriso->hln_count= xorriso->node_counter;
xorriso->hln_array= xorriso->node_array;
xorriso->node_counter= 0;
xorriso->node_array_size= 0;
xorriso->node_array= NULL;
/* Allocate hln_targets */
ret= Xorriso_new_hln_array(xorriso, xorriso->temp_mem_limit, 1);
if(ret<=0)
goto ex;
xorriso->node_targets_availmem= xorriso->temp_mem_limit;
if(old_targets != NULL) {
/* Transfer targets from old target array */;
new_pt= old_pt= 0;
while(new_pt < xorriso->hln_count && old_pt < old_count) {
ret= Xorriso__hln_cmp(xorriso->hln_array[new_pt], old_nodes[old_pt]);
if(ret < 0) {
new_pt++;
} else if(ret > 0) {
old_pt++;
} else {
xorriso->hln_targets[new_pt]= old_targets[old_pt];
if(old_targets[old_pt] != NULL)
xorriso->temp_mem_limit-= strlen(old_targets[old_pt]) + 1;
old_targets[old_pt]= NULL;
new_pt++;
old_pt++;
}
}
for(old_pt= 0; old_pt < old_count; old_pt++)
if(old_targets[old_pt] != NULL) /* (should not happen) */
free(old_targets[old_pt]);
free((char *) old_targets);
}
if(old_nodes != NULL) {
for(old_pt= 0; old_pt < old_count; old_pt++)
if(old_nodes[old_pt] != NULL)
iso_node_unref(old_nodes[old_pt]);
free((char *) old_nodes);
}
xorriso->hln_change_pending= 0;
ret= 1;
ex:;
return(ret);
}
/* @param flag bit0= overwrite existing hln_array (else return 2)
*/
int Xorriso_make_hln_array(struct XorrisO *xorriso, int flag)
{
int ret;
if(xorriso->hln_array != NULL && !(flag & 1)) {
/* If no fresh image manipulations occured: keep old array */
if(!xorriso->hln_change_pending)
return(2);
ret= Xorriso_remake_hln_array(xorriso, 0);
return(ret);
}
Xorriso_destroy_hln_array(xorriso, 0);
ret= Xorriso_all_node_array(xorriso, 0, 0);
if(ret <= 0)
goto ex;
Xorriso_sort_node_array(xorriso, 0);
/* Transfer node_array to di_array without unrefering nodes */
xorriso->hln_count= xorriso->node_counter;
xorriso->hln_array= xorriso->node_array;
xorriso->node_counter= 0;
xorriso->node_array_size= 0;
xorriso->node_array= NULL;
/* Allocate hln_targets */
ret= Xorriso_new_hln_array(xorriso, xorriso->temp_mem_limit, 1);
if(ret<=0) {
Xorriso_destroy_hln_array(xorriso, 0);
goto ex;
}
xorriso->node_targets_availmem= xorriso->temp_mem_limit;
xorriso->hln_change_pending= 0;
ret= 1;
ex:;
return(ret);
}
/* @param flag bit0= overwrite existing di_array (else return 2)
bit1= make di_array despite xorriso->ino_behavior bit 3
*/
int Xorriso_make_di_array(struct XorrisO *xorriso, int flag)
{
int ret, bytes;
#ifdef NIX
/* <<< */
unsigned long old_gdic;
old_gdic= Xorriso_get_di_counteR;
#endif /* NIX */
if((xorriso->ino_behavior & 8 ) && !(flag & 2))
return(2);
if(xorriso->di_array != NULL && !(flag & 1))
return(2);
Xorriso_finish_hl_update(xorriso, 0);
ret= Xorriso_all_node_array(xorriso, 0, 0);
if(ret <= 0)
goto ex;
bytes= xorriso->node_array_size / 8 + 1;
xorriso->di_do_widen= calloc(bytes, 1);
if(xorriso->di_do_widen == NULL) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
/* Transfer node_array to di_array without unrefering nodes */
xorriso->di_count= xorriso->node_counter;
xorriso->di_array= xorriso->node_array;
xorriso->node_counter= 0;
xorriso->node_array_size= 0;
xorriso->node_array= NULL;
Xorriso__sort_di((void *) xorriso->di_array, xorriso->di_count, 0);
ret= 1;
ex:;
#ifdef NIX
/* <<< */
fprintf(stderr, "xorriso_DEBUG: sort_count= %lu\n",
Xorriso_get_di_counteR - old_gdic);
#endif /* NIX */
return(ret);
}
/*
@param flag bit0= iso_rr_path is freshly added and up to date
bit2= -follow: this is not a command parameter
@return -1= severe error
0= not applicable for hard links
1= go on with processing
2= iso_rr_path is fully updated
*/
int Xorriso_hardlink_update(struct XorrisO *xorriso, int *compare_result,
char *disk_path, char *iso_rr_path, int flag)
{
int ret, hret, idx, low, high, i, do_overwrite= 0, did_fake_di= 0;
int follow_links, old_idx= -1;
IsoNode *node;
struct stat stbuf;
dev_t old_dev;
ino_t old_ino;
if(xorriso->di_array == NULL)
return(1);
follow_links= xorriso->do_follow_links ||
(xorriso->do_follow_param && !(flag & 4));
ret= Xorriso_node_from_path(xorriso, NULL, iso_rr_path, &node, 0);
if(ret <= 0)
return(ret);
if(LIBISO_ISDIR(node))
return(1);
/* Handle eventual hardlink split : */
/* This is achieved by setting the content change bit. Reason:
The node needs to be removed from di_array because its di is
not matching its array index any more. So it becomes invisible for
the join check of eventual later hardlink siblings. Therefore
it must be updated now, even if it has currently no siblings
which it leaves or which it joins.
*/
if(!(flag & 1))
do_overwrite= 1;
Xorriso__get_di(node, &old_dev, &old_ino, 0);
ret= Xorriso__search_node(xorriso->di_array, xorriso->di_count,
Xorriso__di_cmp, node, &idx, 0);
if(ret < 0)
{ret= 0; goto ex;}
if(ret > 0)
old_idx= idx;
/* Handle eventual hardlink joining : */
if(follow_links)
ret= stat(disk_path, &stbuf);
else
ret= lstat(disk_path, &stbuf);
if(ret==-1)
{ret= 0; goto ex;}
/* Are there new dev-ino-siblings in the image ? */
/* Fake isofs.di */
if(!(flag & 1)) {
ret= Xorriso_record_dev_inode(xorriso, disk_path, stbuf.st_dev,
stbuf.st_ino, node, iso_rr_path, 1);
if(ret <= 0)
{ret= -1; goto ex;}
did_fake_di= 1;
/* temporarily remove node from di_array so it does not disturb
search by its fake di info */;
if(old_idx >= 0)
xorriso->di_array[old_idx]= NULL;
}
ret= Xorriso_search_di_range(xorriso, node, &idx, &low, &high, 1);
if(did_fake_di) {
/* Revoke fake of isofs.di */
hret= Xorriso_record_dev_inode(xorriso, disk_path, old_dev, old_ino,
node, iso_rr_path, 1);
if(hret <= 0)
{ret= -1; goto ex;}
if(old_idx >= 0)
xorriso->di_array[old_idx]= node;
}
if(ret == 0)
{ret= 1; goto ex;}
if(ret < 0)
{ret= 0; goto ex;}
#ifdef Xorriso_hardlink_update_debuG
/* <<< */
if(low < high || idx < 0) {
fprintf(stderr,
"xorriso_DEBUG: old_idx= %d , low= %d , high= %d , iso= '%s' , disk='%s'\n",
old_idx, low, high, iso_rr_path, disk_path);
fprintf(stderr,
"xorriso_DEBUG: old_dev= %lu , old_ino= %lu , dev= %lu , ino= %lu\n",
(unsigned long) old_dev, (unsigned long) old_ino,
(unsigned long) stbuf.st_dev, (unsigned long) stbuf.st_ino);
if(idx >= 0 && idx != old_idx)
fprintf(stderr, "xorriso_DEBUG: idx= %d , old_idx = %d\n", idx, old_idx);
}
#endif /* Xorriso_hardlink_update_debuG */
/* Overwrite all valid siblings : */
for(i= low; i <= high; i++) {
if(i == idx || xorriso->di_array[i] == NULL)
continue;
#ifdef Xorriso_hardlink_update_debuG
/* <<< */
{
ino_t ino;
dev_t dev;
Xorriso__get_di(xorriso->di_array[i], &dev, &ino, 0);
fprintf(stderr, "xorriso_DEBUG: iso_sibling= '%s' , dev= %lu , ino= %lu\n",
node_path, (unsigned long) dev, (unsigned long) ino);
}
#endif /* Xorriso_hardlink_update_debuG */
xorriso->di_do_widen[i / 8]|= 1 << (i % 8);
}
ret= 1;
ex:;
if(do_overwrite)
*compare_result|= (1<<15);
if(old_idx >= 0 && (*compare_result & (3 << 21))) {
/* The old di info is obsolete */
if(xorriso->di_array[old_idx] != NULL)
iso_node_unref(xorriso->di_array[old_idx]);
xorriso->di_array[old_idx]= NULL;
}
return(ret);
}
/* @param flag bit0= do not destroy di_array
*/
int Xorriso_finish_hl_update(struct XorrisO *xorriso, int flag)
{
int ret, zero= 0;
char *argv[4];
struct Xorriso_lsT *disk_lst, *iso_lst;
if(xorriso->di_array == NULL)
{ret= 1; goto ex;}
disk_lst= xorriso->di_disk_paths;
iso_lst= xorriso->di_iso_paths;
while(disk_lst != NULL && iso_lst != NULL) {
argv[0]= Xorriso_lst_get_text(iso_lst, 0);
argv[1]= "-exec";
argv[2]= "widen_hardlinks";
argv[3]= Xorriso_lst_get_text(disk_lst, 0);
zero= 0;
ret= Xorriso_option_find(xorriso, 4, argv, &zero, 0); /* -findi */
if(ret < 0)
goto ex;
disk_lst= Xorriso_lst_get_next(disk_lst, 0);
iso_lst= Xorriso_lst_get_next(iso_lst, 0);
}
ret= 1;
ex:;
if(!(flag & 1))
Xorriso_destroy_di_array(xorriso, 0);
return(ret);
}

62
xorriso/sort_cmp.h Normal file
View File

@ -0,0 +1,62 @@
/* 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 functions which sort and compare
tree nodes.
*/
#ifndef Xorriso_pvt_sort_cmp_includeD
#define Xorriso_pvt_sort_cmp_includeD yes
int Xorriso__findi_sorted_ino_cmp(const void *p1, const void *p2);
int Xorriso__hln_cmp(const void *p1, const void *p2);
int Xorriso__findi_sorted_cmp(const void *p1, const void *p2);
int Xorriso__search_node(void *node_array[], int n,
int (*cmp)(const void *p1, const void *p2),
void *node, int *idx, int flag);
int Xorriso_search_in_hln_array(struct XorrisO *xorriso,
void *node, int *idx, int flag);
int Xorriso__get_di(IsoNode *node, dev_t *dev, ino_t *ino, int flag);
int Xorriso__di_ino_cmp(const void *p1, const void *p2);
int Xorriso__di_cmp(const void *p1, const void *p2);
int Xorriso__sort_di(void *node_array[], int count, int flag);
int Xorriso_invalidate_di_item(struct XorrisO *xorriso, IsoNode *node,
int flag);
int Xorriso_search_di_range(struct XorrisO *xorriso, IsoNode *node,
int *idx, int *low, int *high, int flag);
int Xorriso__node_lba_cmp(const void *node1, const void *node2);
int Xorriso__node_name_cmp(const void *node1, const void *node2);
int Xorriso_sorted_node_array(struct XorrisO *xorriso,
IsoDir *dir_node,
int *nodec, IsoNode ***node_array,
off_t boss_mem, int flag);
int Xorriso_remake_hln_array(struct XorrisO *xorriso, int flag);
int Xorriso_make_di_array(struct XorrisO *xorriso, int flag);
int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node,
int *node_idx, int *min_hl, int *max_hl, int flag);
#endif /* ! Xorriso_pvt_sort_cmp_includeD */

1990
xorriso/text_io.c Normal file

File diff suppressed because it is too large Load Diff

90
xorriso/text_io.h Normal file
View File

@ -0,0 +1,90 @@
/* 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 text i/o functions.
*/
#ifndef Xorriso_pvt_textio_includeD
#define Xorriso_pvt_textio_includeD yes
int Xorriso_dialog_input(struct XorrisO *xorriso, char line[], int linesize,
int flag);
/** @return -1= abort , 0= no , 1= yes
*/
int Xorriso_reassure(struct XorrisO *xorriso, char *cmd, char *which_will,
int flag);
int Xorriso_request_confirmation(struct XorrisO *xorriso, int flag);
/* @param flag bit0= quoted multiline mode
bit1= release allocated memory and return 1
bit2= with bit0: warn of empty text arguments
bit3= deliver as single quoted text including all whitespace
and without any backslash interpretation
@return -1=out of memory , 0=line format error , 1=ok, go on , 2=done
*/
int Xorriso_read_lines(struct XorrisO *xorriso, FILE *fp, int *linecount,
int *argc, char ***argv, int flag);
int Xorriso_write_to_channel(struct XorrisO *xorriso,
char *in_text, int channel_no, int flag);
int Xorriso_result(struct XorrisO *xorriso, int flag);
int Xorriso_restxt(struct XorrisO *xorriso, char *text);
int Xorriso_info(struct XorrisO *xorriso, int flag);
int Xorriso_mark(struct XorrisO *xorriso, int flag);
int Xorriso_write_session_log(struct XorrisO *xorriso, int flag);
int Xorriso_status_result(struct XorrisO *xorriso, char *filter, FILE *fp,
int flag);
int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag);
int Xorriso_pacifier_reset(struct XorrisO *xorriso, int flag);
/* This call is to be issued by long running workers in short intervals.
It will check whether enough time has elapsed since the last pacifier
message and eventually issue an update message.
@param what_done A sparse description of the action, preferrably in past
tense. E.g. "done" , "files added".
@param count The number of objects processed so far.
Is ignored if <=0.
@param todo The number of objects to be done in total.
Is ignored if <=0.
@param current_object A string telling the object currently processed.
Ignored if "".
@param flag bit0= report unconditionally, no time check
*/
int Xorriso_pacifier_callback(struct XorrisO *xorriso, char *what_done,
off_t count, off_t todo, char *current_object,
int flag);
int Xorriso_reset_counters(struct XorrisO *xorriso, int flag);
int Xorriso_no_malloc_memory(struct XorrisO *xorriso, char **to_free,
int flag);
int Xorriso_much_too_long(struct XorrisO *xorriso, int len, int flag);
int Xorriso_no_findjob(struct XorrisO *xorriso, char *cmd, int flag);
int Xorriso_report_md5_outcome(struct XorrisO *xorriso, char *severity,
int flag);
int Xorriso_protect_stdout(struct XorrisO *xorriso, int flag);
#endif /* ! Xorriso_pvt_textio_includeD */

2106
xorriso/write_run.c Normal file

File diff suppressed because it is too large Load Diff

53
xorriso/write_run.h Normal file
View File

@ -0,0 +1,53 @@
/* 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 functions which are needed to write
sessions.
*/
#ifndef Xorriso_pvt_write_run_includeD
#define Xorriso_pvt_write_run_includeD yes
/* CD specs say one shall not write tracks < 600 kiB */
#define Xorriso_cd_min_track_sizE 300
/* Default setting for -compliance */
#define Xorriso_relax_compliance_defaulT \
(isoburn_igopt_allow_deep_paths | isoburn_igopt_allow_longer_paths | \
isoburn_igopt_always_gmt | \
isoburn_igopt_rrip_version_1_10 | isoburn_igopt_aaip_susp_1_10 | \
isoburn_igopt_only_iso_versions | isoburn_igopt_no_j_force_dots)
int Xorriso_make_write_options(
struct XorrisO *xorriso, struct burn_drive *drive,
struct burn_write_opts **burn_options, int flag);
int Xorriso_sanitize_image_size(struct XorrisO *xorriso,
struct burn_drive *drive, struct burn_disc *disc,
struct burn_write_opts *burn_options, int flag);
int Xorriso_auto_format(struct XorrisO *xorriso, int flag);
int Xorriso_set_system_area(struct XorrisO *xorriso, struct burn_drive *drive,
IsoImage *img, struct isoburn_imgen_opts *sopts,
int flag);
int Xorriso_check_burn_abort(struct XorrisO *xorriso, int flag);
int Xorriso_pacifier_loop(struct XorrisO *xorriso, struct burn_drive *drive,
int flag);
int Xorriso_set_isolinux_options(struct XorrisO *xorriso,
IsoImage *image, int flag);
#endif /* ! Xorriso_pvt_write_run_includeD */

File diff suppressed because it is too large Load Diff

View File

@ -574,6 +574,9 @@ int Xorriso_option_chowni(struct XorrisO *xorriso, char *uid,
/* Option -close "on"|"off" */ /* Option -close "on"|"off" */
int Xorriso_option_close(struct XorrisO *xorriso, char *mode, int flag); int Xorriso_option_close(struct XorrisO *xorriso, char *mode, int flag);
/* Option -close_filter_list */
int Xorriso_option_close_filter_list(struct XorrisO *xorriso, int flag);
/* Option -commit */ /* Option -commit */
/* @param flag bit0= leave indrive and outdrive aquired as they were, /* @param flag bit0= leave indrive and outdrive aquired as they were,
i.e. do not aquire outdrive as new in-out-drive i.e. do not aquire outdrive as new in-out-drive
@ -596,6 +599,9 @@ int Xorriso_option_commit_eject(struct XorrisO *xorriso, char *which, int flag);
int Xorriso_option_compare(struct XorrisO *xorriso, char *disk_path, int Xorriso_option_compare(struct XorrisO *xorriso, char *disk_path,
char *iso_path, int flag); char *iso_path, int flag);
/* Option -compliance */
int Xorriso_option_compliance(struct XorrisO *xorriso, char *mode, int flag);
/* Option -cpr alias -cpri */ /* Option -cpr alias -cpri */
int Xorriso_option_cpri( struct XorrisO *xorriso, int argc, char **argv, int Xorriso_option_cpri( struct XorrisO *xorriso, int argc, char **argv,
int *idx, int flag); int *idx, int flag);
@ -676,8 +682,10 @@ int Xorriso_option_extract(struct XorrisO *xorriso, char *disk_path,
int Xorriso_option_extract_cut(struct XorrisO *xorriso, char *iso_rr_path, int Xorriso_option_extract_cut(struct XorrisO *xorriso, char *iso_rr_path,
char *start, char *count, char *disk_path, int flag); char *start, char *count, char *disk_path, int flag);
/* Option -follow */ /* Option -file_size_limit */
int Xorriso_option_follow(struct XorrisO *xorriso, char *mode, int flag); int Xorriso_option_file_size_limit(struct XorrisO *xorriso,
int argc, char **argv, int *idx, int flag);
/* Option -find alias -findi, and -findx */ /* Option -find alias -findi, and -findx */
/* @param flag bit0= -findx rather than -findi /* @param flag bit0= -findx rather than -findi
@ -687,6 +695,9 @@ int Xorriso_option_follow(struct XorrisO *xorriso, char *mode, int flag);
int Xorriso_option_find(struct XorrisO *xorriso, int argc, char **argv, int Xorriso_option_find(struct XorrisO *xorriso, int argc, char **argv,
int *idx, int flag); int *idx, int flag);
/* Option -follow */
int Xorriso_option_follow(struct XorrisO *xorriso, char *mode, int flag);
/* Option -fs */ /* Option -fs */
int Xorriso_option_fs(struct XorrisO *xorriso, char *size, int flag); int Xorriso_option_fs(struct XorrisO *xorriso, char *size, int flag);
@ -811,6 +822,9 @@ int Xorriso_option_not_leaf(struct XorrisO *xorriso, char *pattern, int flag);
/* @param flag bit0= -quoted_not_list */ /* @param flag bit0= -quoted_not_list */
int Xorriso_option_not_list(struct XorrisO *xorriso, char *adr, int flag); int Xorriso_option_not_list(struct XorrisO *xorriso, char *adr, int flag);
/* Option -not_mgt */
int Xorriso_option_not_mgt(struct XorrisO *xorriso, char *setting, int flag);
/* Option -not_paths */ /* Option -not_paths */
int Xorriso_option_not_paths(struct XorrisO *xorriso, int argc, char **argv, int Xorriso_option_not_paths(struct XorrisO *xorriso, int argc, char **argv,
int *idx, int flag); int *idx, int flag);
@ -860,6 +874,9 @@ int Xorriso_option_print_size(struct XorrisO *xorriso, int flag);
/* Option -prog */ /* Option -prog */
int Xorriso_option_prog(struct XorrisO *xorriso, char *name, int flag); int Xorriso_option_prog(struct XorrisO *xorriso, char *name, int flag);
/* Option -prompt */
int Xorriso_option_prompt(struct XorrisO *xorriso, char *text, int flag);
/* Option -prog_help */ /* Option -prog_help */
int Xorriso_option_prog_help(struct XorrisO *xorriso, char *name, int flag); int Xorriso_option_prog_help(struct XorrisO *xorriso, char *name, int flag);

229
xorriso/xorriso_main.c Normal file
View File

@ -0,0 +1,229 @@
/*
( cd .. ; libisoburn-develop/xorriso/compile_xorriso.sh -g )
*/
/* Command line oriented batch and dialog tool which creates, loads,
manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2010 Thomas Schmitt, <scdbackup@gmx.net>
Initial code of this program was derived from program src/askme.c out
of scdbackup-0.8.8, Copyright 2007 Thomas Schmitt, BSD-License.
Provided under GPL version 2 or later, with the announcement that this
might get changed in future. I would prefer BSD or LGPL as soon as the
license situation of the library code allows that.
(This announcement affects only future releases of xorriso and it will
always be possible to derive a GPLv2+ from the future license.)
There is a derived package "GNU xorriso" under GPLv3+ which combines the
libburnia libraries and program xorriso to a statically linked binary.
Overview of xorriso architecture:
libburn provides the ability to read and write data.
libisofs interprets and manipulates ISO 9660 directory trees. It generates
the output stream which is handed over to libburn.
libisoburn encapsulates the connectivity issues between libburn and
libisofs. It also enables multi-session emulation on overwritable media
and random access file objects.
xorriso is intended as reference application of libisoburn.
xorriso.h exposes the public functions of xorriso which are intended
to be used by programs which link with xorriso.o. These functions are
direct equivalents of the xorriso interpreter commands.
There is also the API for handling event messages.
The source is divided in two groups:
A set of source modules interacts with the libraries:
base_obj.[ch] fundamental operations of the XorrisO object
lib_mgt.[ch] manages the relation between xorriso and the libraries
drive_mgt.[ch] operates on drives and media
iso_img.[ch] operates on ISO images and their global properties
iso_tree.[ch] access nodes of the libisofs tree model
iso_manip.[ch] manipulates the libisofs tree model
sort_cmp.[ch] sorts and compare tree nodes
write_run.[ch] functions to write sessions
read_run.[ch] functions to read data from ISO image
filters.[ch] operates on data filter objects
xorrisoburn.h declarations needed by the non-library modules
Another set is independent of the liburnia libraries:
parse_exec.c deals with parsing and interpretation of command input
sfile.c functions around files and strings
aux_objects.c various helper classes
misc_funct.c miscellaneous helper functions
findjob.c performs tree searches in libisofs or in POSIX filesystem
check_media.c perform verifying runs on media resp. images
text_io.c text i/o functions
match.c functions for pattern matching
emulators.c emulators for mkisofs and cdrecord
disk_ops.c actions on onjects of disk filesystems
cmp_update.c compare or update files between disk filesystem and
ISO filesystem
opts_a_c.c options -a* to -c*
opts_d_h.c options -d* to -h*
opts_i_o.c options -i* to -o*
opts_p_z.c options -p* to -z*
xorriso_main.c the main program
xorriso_private.h contains the definition of struct Xorriso and for
convenience includes the .h files of the non-library group.
*/
/* This may be changed to Xorriso_GNU_xorrisO in order to create GNU xorriso */
#define Xorriso_libburnia_xorrisO yes
#include <ctype.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <locale.h>
/* The official xorriso options API. "No shortcuts" */
#include "xorriso.h"
#ifdef Xorriso_without_subS
/* xorriso consists only of a main() stub which has an own version to match
the version of libxorriso header and runtime code.
*/
#define Xorriso_main_program_versioN "0.5.7"
#else /* Xorriso_without_subS */
/* Make sure that both version tests always match. */
#define Xorriso_main_program_versioN Xorriso_program_versioN
#endif /* ! Xorriso_without_subS */
static void yell_xorriso()
{
fprintf(stderr,
"%sxorriso %s%s : RockRidge filesystem manipulator, libburnia project.\n\n",
#ifdef Xorriso_GNU_xorrisO
"GNU ",
#else
"",
#endif
Xorriso_main_program_versioN, Xorriso_program_patch_leveL);
}
int main(int argc, char **argv)
{
int ret, i;
struct XorrisO *xorriso= NULL;
char **orig_argv= NULL;
if(strcmp(Xorriso_main_program_versioN, Xorriso_program_versioN)) {
yell_xorriso();
fprintf(stderr,
"xorriso : FATAL : libxorriso compile time version mismatch. Found %s\n\n",
Xorriso_program_versioN);
exit(4);
}
if(strcmp(Xorriso_program_versioN, Xorriso__get_version_text(0))) {
yell_xorriso();
fprintf(stderr,
"xorriso : FATAL : libxorriso runtime version mismatch. Found %s\n\n",
Xorriso__get_version_text(0));
exit(4);
}
if(argc < 2) {
yell_xorriso();
fprintf(stderr,"usage : %s [options]\n", argv[0]);
fprintf(stderr, " More is told by option -help\n");
exit(2);
}
setlocale(LC_CTYPE, "");
ret= Xorriso_new(&xorriso, argv[0], 0);
if(ret <= 0) {
fprintf(stderr,"Creation of XorrisO object failed. (not enough memory ?)\n");
exit(3);
}
/* The prescan of arguments performs actions which have to happen before
the normal processing of startup files and arguments.
*/
ret= Xorriso_prescan_args(xorriso,argc,argv,0);
if(ret == 0)
goto end_sucessfully;
if(ret < 0)
exit(5);
yell_xorriso();
/* The following functions are allowed only after this initialization */
ret= Xorriso_startup_libraries(xorriso, 0);
if(ret <= 0)
{ret= 4; goto emergency_exit;}
Xorriso_process_msg_queues(xorriso, 0);
/* Interpret startup files */
ret= Xorriso_read_rc(xorriso, 0);
if(ret == 3)
goto end_sucessfully;
if(ret <= 0)
{ret= 5; goto emergency_exit;}
/* Interpret program arguments */
orig_argv= argv;
ret= Xorriso_program_arg_bsl(xorriso, argc, &argv, 0);
if(ret <= 0)
{ret= 5; goto emergency_exit;}
i= 1;
ret= Xorriso_interpreter(xorriso, argc, argv, &i, 2);
if(ret == 3)
goto end_sucessfully;
if(ret <= 0)
{ret= 5; goto emergency_exit;}
/* Enter dialog mode if it has been activated meanwhile */
ret= Xorriso_dialog(xorriso, 0);
if(ret <= 0)
{ret= 6; goto emergency_exit;}
end_sucessfully:; /* normal shutdown, including eventual -commit */
Xorriso_process_msg_queues(xorriso, 0);
if(Xorriso_change_is_pending(xorriso, 0))
Xorriso_option_end(xorriso, 2);
Xorriso_process_msg_queues(xorriso, 0);
ret= Xorriso_make_return_value(xorriso, 0);
Xorriso_process_errfile(xorriso, 0, "xorriso end", 0, 1);
Xorriso_destroy(&xorriso, 1);
if(orig_argv != argv && orig_argv != NULL) {
for(i= 0; i < argc; i++)
if(argv[i] != NULL)
free(argv[i]);
free(argv);
}
exit(ret);
emergency_exit:;
if(xorriso != NULL) { /* minimal shutdown */
Xorriso_process_msg_queues(xorriso, 0);
Xorriso_destroy(&xorriso, 1);
}
exit(ret);
}

View File

@ -23,7 +23,7 @@ xorriso_xorriso_CPPFLAGS = -I./libburn -I./libisofs -I./libisoburn -I./xorriso
# No readline in the vanilla version because the necessary headers # No readline in the vanilla version because the necessary headers
# are in a separate readline-development package. # are in a separate readline-development package.
xorriso_xorriso_CFLAGS = -DXorriso_standalonE -DXorriso_with_maiN \ xorriso_xorriso_CFLAGS = -DXorriso_standalonE \
$(READLINE_DEF) $(LIBACL_DEF) $(XATTR_DEF) \ $(READLINE_DEF) $(LIBACL_DEF) $(XATTR_DEF) \
$(EXTF_DEF) $(EXTF_SUID_DEF) $(ZLIB_DEF) \ $(EXTF_DEF) $(EXTF_SUID_DEF) $(ZLIB_DEF) \
$(LIBCDIO_DEF) \ $(LIBCDIO_DEF) \
@ -48,9 +48,56 @@ xorriso_xorriso_SOURCES = \
\ \
xorriso/xorriso.h \ xorriso/xorriso.h \
xorriso/xorriso_private.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.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_timestamp.h \
xorriso/xorriso_buildstamp.h \ xorriso/xorriso_buildstamp.h \
\ \

View File

@ -33,19 +33,16 @@
#define Xorriso_build_timestamP "-none-given-" #define Xorriso_build_timestamP "-none-given-"
#endif #endif
#include <regex.h>
#include "sfile.h"
#include "misc_funct.h"
#define Smem_malloC malloc
#define Smem_freE free
#define SfileadrL 4096
struct LinkiteM; /* Trace of hops during symbolic link resolution */
struct ExclusionS; /* List of -not_* conditions */ struct ExclusionS; /* List of -not_* conditions */
struct PermiteM; /* Stack of temporarily altered access permissions */ struct PermiteM; /* Stack of temporarily altered access permissions */
struct SpotlisT; /* List of intervals with different read qualities */
struct CheckmediajoB; /* Parameters for Xorriso_check_media() */ struct CheckmediajoB; /* Parameters for Xorriso_check_media() */
struct SectorbitmaP; /* Distiniction between valid and invalid sectors */ struct SectorbitmaP; /* Distiniction between valid and invalid sectors */
struct FindjoB; /* Program and status of a find run */
/* maximum number of history lines to be reported with -status:long_history */ /* maximum number of history lines to be reported with -status:long_history */
@ -502,860 +499,18 @@ struct XorrisO { /* the global context of xorriso */
}; };
int Xorriso__get_signal_behavior(int flag); #include "base_obj.h"
#include "aux_objects.h"
#include "findjob.h"
#include "check_media.h"
#include "misc_funct.h"
#include "text_io.h"
#include "match.h"
#include "emulators.h"
#include "disk_ops.h"
#include "cmp_update.h"
#include "parse_exec.h"
int Xorriso_prepare_regex(struct XorrisO *xorriso, char *adr, int flag);
int Xorriso_result(struct XorrisO *xorriso, int flag);
int Xorriso_info(struct XorrisO *xorriso, int flag);
int Xorriso_request_confirmation(struct XorrisO *xorriso, int flag);
/* @return 0=match , else no match
*/
int Xorriso_regexec(struct XorrisO *xorriso, char *to_match, int *failed_at,
int flag);
int Xorriso_prepare_expansion_pattern(struct XorrisO *xorriso, char *pattern,
int flag);
int Xorriso__mode_to_perms(mode_t st_mode, char perms[11], int flag);
int Xorriso_much_too_long(struct XorrisO *xorriso, int len, int flag);
int Xorriso_check_temp_mem_limit(struct XorrisO *xorriso, off_t mem, int flag);
int Xorriso_eval_nonmatch(struct XorrisO *xorriso, char *pattern,
int *nonconst_mismatches, off_t *mem, int flag);
/* @param flag bit0= a match count !=1 is a SORRY event
*/
int Xorriso_check_matchcount(struct XorrisO *xorriso,
int count, int nonconst_mismatches, int num_patterns,
char **patterns, int flag);
int Xorriso_no_pattern_memory(struct XorrisO *xorriso, off_t mem, int flag);
int Xorriso_alloc_pattern_mem(struct XorrisO *xorriso, off_t mem,
int count, char ***filev, int flag);
/* @param flag bit0= count results rather than storing them
@return <=0 error , 1 is root (end processing) ,
2 is not root (go on processing)
*/
int Xorriso_check_for_root_pattern(struct XorrisO *xorriso,
int *filec, char **filev, int count_limit, off_t *mem, int flag);
/* @param flag bit0= prepend wd only if name does not begin by '/'
bit2= prepend wd (automatically done if wd[0]!=0)
*/
int Xorriso_make_abs_adr(struct XorrisO *xorriso, char *wd, char *name,
char adr[], int flag);
/* @param flag bit0= count result rather than storing it
bit1= unexpected change of number is a FATAL event
*/
int Xorriso_register_matched_adr(struct XorrisO *xorriso,
char *adr, int count_limit,
int *filec, char **filev, off_t *mem, int flag);
int Xorriso_format_ls_l(struct XorrisO *xorriso, struct stat *stbuf, int flag);
/* @param flag bit0= simple readlink(): no normalization, no multi-hop
*/
int Xorriso_resolve_link(struct XorrisO *xorriso,
char *link_path, char result_path[SfileadrL], int flag);
/* @param flag bit0= for Xorriso_msgs_submit: use pager
*/
int Xorriso_hop_link(struct XorrisO *xorriso, char *link_path,
struct LinkiteM **link_stack, struct stat *stbuf, int flag);
/* reg_expr should be twice as large as bourne_expr ( + 2 to be exact) */
/* return: 2= bourne_expr is surely a constant */
int Xorriso__bourne_to_reg(char bourne_expr[], char reg_expr[], int flag);
int Xorriso_no_malloc_memory(struct XorrisO *xorriso, char **to_free,
int flag);
int Xorriso_pacifier_reset(struct XorrisO *xorriso, int flag);
/* This call is to be issued by long running workers in short intervals.
It will check whether enough time has elapsed since the last pacifier
message and eventually issue an update message.
@param what_done A sparse description of the action, preferrably in past
tense. E.g. "done" , "files added".
@param count The number of objects processed so far.
Is ignored if <=0.
@param todo The number of objects to be done in total.
Is ignored if <=0.
@param current_object A string telling the object currently processed.
Ignored if "".
@param flag bit0= report unconditionally, no time check
*/
int Xorriso_pacifier_callback(struct XorrisO *xorriso, char *what_done,
off_t count, off_t todo, char *current_object,
int flag);
int Xorriso_pfx_disk_path(struct XorrisO *xorriso, char *iso_path,
char *iso_prefix, char *disk_prefix,
char disk_path[SfileadrL], int flag);
/* @param boss_iter Opaque handle to be forwarded to actions in ISO image
Set to NULL if calling this function from outside ISO world
@param flag bit0= update rather than compare
*/
int Xorriso_find_compare(struct XorrisO *xorriso, void *boss_iter,
char *iso_path, char *iso_prefix, char *disk_prefix,
int flag);
/* @param boss_iter Opaque handle to be forwarded to actions in ISO image
Set to NULL if calling this function from outside ISO world
*/
int Xorriso_update_interpreter(struct XorrisO *xorriso, void *boss_iter,
int compare_result, char *disk_path,
char *iso_rr_path, int flag);
int Xorriso_path_is_excluded(struct XorrisO *xorriso, char *path, int flag);
/* @param flag bit0= long format
bit1= do not print count of nodes
bit2= du format
bit3= print directories as themselves (ls -d)
*/
int Xorriso_lsx_filev(struct XorrisO *xorriso, char *wd,
int filec, char **filev, off_t boss_mem, int flag);
/*
@param flag >>> bit0= remove whole sub tree: rm -r
bit1= remove empty directory: rmdir
bit2= recursion: do not reassure in mode 2 "tree"
bit3= this is for overwriting and not for plain removal
bit4= count deleted files in xorriso->pacifier_count
bit5= with bit0 only remove directory content, not the directory
@return <=0 = error
1 = removed leaf file object
2 = removed directory or tree
3 = did not remove on user revocation
*/
int Xorriso_rmx(struct XorrisO *xorriso, off_t boss_mem, char *path, int flag);
/* @param flag bit7= return 4 if restore fails from denied permission
do not issue error message
@return <=0 failure , 1 success ,
4 with bit7: permission to create file was denied
*/
int Xorriso_make_tmp_path(struct XorrisO *xorriso, char *orig_path,
char *tmp_path, int *fd, int flag);
/* @param flag bit0= path is a directory
bit2= recursion: do not reassure in mode 2 "tree"
bit3= this is for overwriting and not for plain removal
*/
int Xorriso_reassure_restore(struct XorrisO *xorriso, char *path, int flag);
/* @param flag bit0= change regardless of xorriso->do_auto_chmod
bit1= desired is only rx
*/
int Xorriso_auto_chmod(struct XorrisO *xorriso, char *disk_path, int flag);
int Xorriso_make_accessible(struct XorrisO *xorriso, char *disk_path,int flag);
/* @param flag bit0= prefer to find a match after *img_prefixes
(but deliver img_prefixes if no other can be found)
*/
int Xorriso_make_restore_path(struct XorrisO *xorriso,
struct Xorriso_lsT **img_prefixes, struct Xorriso_lsT **disk_prefixes,
char img_path[SfileadrL], char disk_path[SfileadrL], int flag);
int Xorriso_restore_make_hl(struct XorrisO *xorriso,
char *old_path, char *new_path, int flag);
int Xorriso_protect_stdout(struct XorrisO *xorriso, int flag);
/* @param flag bit0= mark untested areas as valid
*/
int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso,
struct SpotlisT *spotlist,
int read_chunk,
struct SectorbitmaP **map,
int flag);
int Xorriso_toc_to_string(struct XorrisO *xorriso, char **toc_text, int flag);
/* @param flag bit0+1= what to aquire after giving up outdev
0=none, 1=indev, 2=outdev, 3=both
*/
int Xorriso_reaquire_outdev(struct XorrisO *xorriso, int flag);
/* Opens the -check_media data copy in for reading and writing
*/
int Xorriso_open_job_data_to(struct XorrisO *xorriso,
struct CheckmediajoB *job, int flag);
int Xorriso_no_findjob(struct XorrisO *xorriso, char *cmd, int flag);
int Xorriso_make_mount_cmd(struct XorrisO *xorriso, char *cmd,
int lba, int track, int session, char *volid,
char *devadr, char result[SfileadrL], int flag);
/* @param flag bit0= use env_path to find the desired program
*/
int Xorriso_execv(struct XorrisO *xorriso, char *cmd, char *env_path,
int *status, int flag);
int Xorriso_is_in_patternlist(struct XorrisO *xorriso,
struct Xorriso_lsT *patternlist, char *path, int flag);
char *Xorriso_get_pattern(struct XorrisO *xorriso,
struct Xorriso_lsT *patternlist, int index, int flag);
/* Normalize ACL and sort apart "access" ACL from "default" ACL.
*/
int Xorriso_normalize_acl_text(struct XorrisO *xorriso, char *in_text,
char **access_acl_text, char **default_acl_text, int flag);
int Xorriso_path_setfattr(struct XorrisO *xorriso, void *in_node, char *path,
char *name, size_t value_length, char *value, int flag);
int Xorriso_status_result(struct XorrisO *xorriso, char *filter, FILE *fp,
int flag);
int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr,
char *iso_adr, char *adr_common_tail,
int *result, int flag);
int Xorriso_report_md5_outcome(struct XorrisO *xorriso, char *severity,
int flag);
int Xorriso_append_scdbackup_record(struct XorrisO *xorriso, int flag);
int Xorriso_may_burn(struct XorrisO *xorriso, int flag);
int Xorriso_afile_fopen(struct XorrisO *xorriso,
char *filename, char *mode, FILE **ret_fp, int flag);
int Sfile_str(char target[SfileadrL], char *source, int flag);
double Sfile_microtime(int flag);
int Sfile_add_to_path(char path[SfileadrL], char *addon, int flag);
int Sfile_scale(double value, char *result, int siz, double thresh, int flag);
int Sfile_destroy_argv(int *argc, char ***argv, int flag);
/*
bit0= do not ignore trailing slash
bit1= do not ignore empty components (other than the empty root name)
*/
int Sfile_count_components(char *path, int flag);
/*
@param flag
bit0= return -1 if file is missing
bit1= return a hardlink with siblings as type 5
bit2= evaluate eventual link target rather than the link object itself
bit3= return a socket or a char device as types 7 or 8 rather than 0
@return
0=unknown
1=regular
2=directory
3=symbolic link
4=named pipe
5=multiple hardlink (with bit1)
6=block device
7=socket (with bit3)
8=character device (with bit3)
*/
int Sfile_type(char *filename, int flag);
/* @param flag bit0= only encode inside quotes
bit1= encode < 32 outside quotes except 7, 8, 9, 10, 12, 13
bit2= encode in any case above 126
bit3= encode in any case shellsafe:
<=42 , 59, 60, 62, 63, 92, 94, 96, >=123
*/
int Sfile_bsl_encoder(char **result, char *text, size_t text_len, int flag);
int Sfile_argv_bsl(int argc, char ***argv, 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
@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);
char *Text_shellsafe(char *in_text, char *out_text, int flag);
int Sort_argv(int argc, char **argv, int flag);
/* @param flag bit0= single letters */
char *Ftypetxt(mode_t st_mode, int flag);
/* @param flag bit0=with year and seconds
bit1=timestamp format YYYY.MM.DD.hhmmss
*/
char *Ftimetxt(time_t t, char timetext[40], int flag);
int System_uname(char **sysname, char **release, char **version,
char **machine, 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 Linkitem_reset_stack(struct LinkiteM **o, struct LinkiteM *to, int flag);
#define Xorriso_findjob_on_expR yes
#ifdef Xorriso_findjob_on_expR
/*
A single Testnode.
*/
struct ExprtesT {
struct FindjoB *boss;
int invert; /* 0=normal 1=invert result */
/*
0= -false (with invert : -true)
1= -name char *arg1 (regex_t in *arg2)
2= -type char *arg1
3= -damaged
4= -lba_range int *arg1 int *arg2
5= -has_acl
6= -has_xattr
7= -has_aaip
8= -has_filter
9= -wanted_node IsoNode *arg1 (for internal use, arg1 not allocated)
10= -pending_data
11= -decision char *arg1 ("yes", "no")
12= -prune
13= -wholename char *arg1 (regex_t in *arg2)
14= -has_any_xattr
15= -has_md5
*/
int test_type;
void *arg1;
void *arg2;
};
/*
A computational node.
A tree of these nodes forms the expression.
Sequences of AND/OR operations form branches, brackets spawn new branches,
NOT inverts node's test resp. subtree result.
*/
struct ExprnodE {
struct ExprnodE *up;
char origin[8];
/* Operators */
int invert; /* 0=normal 1=invert own result (subtree or test, but not op) */
int assoc; /*
0= left : compute own value, combine with left value,
compute right value, combine with current value
1= right: compute own value, compute right value,
combine own and right, combine with left value
*/
int use_shortcuts; /* 0= evaluate all tests of -and and -or,
1= evaluate only until the combined result is known
*/
struct ExprnodE *left;
int left_op; /* 0=OR , 1=AND */
struct ExprnodE *right;
int right_op; /* see left_op */
/* Brackets : a pointer to the first node in a subchain */
struct ExprnodE *sub;
int is_if_then_else;
struct ExprnodE *true_branch;
struct ExprnodE *false_branch;
/* elementary test : if sub!=NULL , test is ignored */
struct ExprtesT *test;
/* Result */
int own_value;
int composed_value;
};
struct FindjoB {
char *start_path;
struct ExprnodE *test_tree;
struct ExprnodE *cursor;
int invert; /* 0=normal 1=set invert-property for next new test node */
int use_shortcuts;
/* 0= echo
1= rm (also rmdir)
2= rm_r
>>> 3= mv target
4= chown user
5= chgrp group
6= chmod mode_and mode_or
7= alter_date type date
8= lsdl
9= chown_r user
10= chgrp_r group
11= chmod_r mode_and mode_or
12= alter_date_r type date
13= find
14= compare disk_equivalent_of_start_path
15= in_iso iso_rr_equivalent_of_start_path
16= not_in_iso iso_rr_equiv
17= update disk_equiv
18= add_missing iso_rr_equiv
19= empty_iso_dir iso_rr_equiv
20= is_full_in_iso iso_rr_equiv
21= report_damage
22= report_lba
23= internal: memorize path of last matching node in found_path
24= getfacl
25= setfacl access_acl default_acl
26= getfattr
27= setfattr
28= set_filter name
29= show_stream
30= internal: count by xorriso->node_counter
31= internal: register in xorriso->node_array
32= internal: widen_hardlinks disk_equiv: update nodes marked in di_do_widen
33= get_any_xattr
34= get_md5
35= check_md5
36= make_md5
37= mkisofs_r
38= sort_weight number
*/
int action;
int prune;
/* action specific parameters */
char *target;
char *text_2;
uid_t user;
gid_t group;
mode_t mode_and, mode_or;
int type; /* see Xorriso_set_time flag, also used as weight */
time_t date;
char *found_path;
struct FindjoB *subjob;
/* Errors */
char errmsg[4096];
int errn; /*
>0 = UNIX errno
-1 = close_bracket: no bracket open
-2 = binary operator or closing bracket expected
-3 = unexpected binary operator or closing bracket
-4 = unsupported command
-5 = -then -elseif -else -endif without -if or at wrong place
*/
};
int Exprtest_match(struct XorrisO *xorriso, struct ExprtesT *ftest,
void *node_pt, char *name, char *path,
struct stat *boss_stbuf, struct stat *stbuf, int flag);
int Exprnode_destroy(struct ExprnodE **fnode, int flag);
int Exprnode_tree_value(struct XorrisO *xorriso, struct ExprnodE *fnode,
int left_value, void *node, char *name, char *path,
struct stat *boss_stbuf, struct stat *stbuf, int flag);
int Findjob_new(struct FindjoB **o, char *start_path, int flag);
int Findjob_destroy(struct FindjoB **o, int flag);
int Findjob_set_start_path(struct FindjoB *o, char *start_path, int flag);
int Findjob_get_start_path(struct FindjoB *o, char **start_path, int flag);
int Findjob_set_commit_filter_2(struct FindjoB *o, int flag);
int Findjob_set_lba_range(struct FindjoB *o, int start_lba, int count,
int flag);
int Findjob_set_wanted_node(struct FindjoB *o, void *wanted_node, int flag);
int Findjob_set_decision(struct FindjoB *o, char *decision, int flag);
int Findjob_open_bracket(struct FindjoB *job, int flag);
int Findjob_close_bracket(struct FindjoB *job, int flag);
int Findjob_not(struct FindjoB *job, int flag);
int Findjob_and(struct FindjoB *job, int flag);
int Findjob_or(struct FindjoB *job, int flag);
int Findjob_if(struct FindjoB *job, int flag);
int Findjob_then(struct FindjoB *job, int flag);
int Findjob_else(struct FindjoB *job, int flag);
int Findjob_elseif(struct FindjoB *job, int flag);
int Findjob_endif(struct FindjoB *job, int flag);
int Findjob_test_2(struct XorrisO *xorriso, struct FindjoB *o,
void *node, char *name, char *path,
struct stat *boss_stbuf, struct stat *stbuf, int flag);
int Findjob_set_action_found_path(struct FindjoB *o, int flag);
/* @param flag bit0= recursive
*/
int Findjob_set_action_target(struct FindjoB *o, int action, char *target,
int flag);
int Findjob_get_action(struct FindjoB *o, int flag);
int Findjob_get_action_parms(struct FindjoB *o, char **target, char **text_2,
uid_t *user, gid_t *group,
mode_t *mode_and, mode_t *mode_or,
int *type, time_t *date, struct FindjoB **subjob,
int flag);
int Findjob_set_found_path(struct FindjoB *o, char *path, int flag);
int Findjob_get_found_path(struct FindjoB *o, char **path, int flag);
#else /* Xorriso_findjob_on_expR */
struct FindjoB;
int Findjob_new(struct FindjoB **o, char *start_path, int flag);
int Findjob_destroy(struct FindjoB **job, int flag);
/* @return 0=no match , 1=match , <0 = error
*/
int Findjob_test(struct FindjoB *job, char *name,
struct stat *boss_stbuf, struct stat *stbuf,
int depth, int flag);
/* @return <0 error, >=0 see xorriso.c struct FindjoB.action
*/
int Findjob_get_action(struct FindjoB *o, int flag);
/* @return <0 error, >=0 see xorriso.c struct FindjoB.action
*/
int Findjob_get_action_parms(struct FindjoB *o, char **target, char **text_2,
uid_t *user, gid_t *group,
mode_t *mode_and, mode_t *mode_or,
int *type, time_t *date, struct FindjoB **subjob,
int flag);
/* @param flag bit0= recursive
*/
int Findjob_set_action_target(struct FindjoB *o, int action, char *target,
int flag);
/* @param flag bit0= recursive
*/
int Findjob_set_action_chgrp(struct FindjoB *o, gid_t group, int flag);
/* @param flag bit0= recursive
*/
int Findjob_set_action_chmod(struct FindjoB *o,
mode_t mode_and, mode_t mode_or, int flag);
/* @param flag bit0= recursive
*/
int Findjob_set_action_ad(struct FindjoB *o, int type, time_t date, int flag);
int Findjob_set_start_path(struct FindjoB *o, char *start_path, int flag);
int Findjob_set_action_found_path(struct FindjoB *o, int flag);
int Findjob_get_start_path(struct FindjoB *o, char **start_path, int flag);
int Findjob_set_lba_range(struct FindjoB *o, int start_lba, int count,
int flag);
int Findjob_get_lba_damage_filter(struct FindjoB *o, int *start_lba,
int *end_lba, int *damage_filter, int flag);
int Findjob_get_commit_filter(struct FindjoB *o, int *commit_filter, int flag);
int Findjob_get_acl_filter(struct FindjoB *o, int *acl_filter, int flag);
int Findjob_get_xattr_filter(struct FindjoB *o, int *xattr_filter, int flag);
int Findjob_get_aaip_filter(struct FindjoB *o, int *aaip_filter, int flag);
int Findjob_get_filter_filter(struct FindjoB *o, int *value, int flag);
int Findjob_set_wanted_node(struct FindjoB *o, void *wanted_node, int flag);
int Findjob_get_wanted_node(struct FindjoB *o, void **wanted_node, int flag);
int Findjob_set_found_path(struct FindjoB *o, char *path, int flag);
int Findjob_get_found_path(struct FindjoB *o, char **path, int flag);
#endif /* ! Xorriso_findjob_on_expR */
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 Splitparts_sort(struct SplitparT *o, int count, int flag);
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);
int Spotlist_new(struct SpotlisT **o, int flag);
int Spotlist_destroy(struct SpotlisT **o, int flag);
int Spotlist_add_item(struct SpotlisT *o, int start_lba, int blocks,
int quality, int flag);
int Spotlist_count(struct SpotlisT *o, int flag);
int Spotlist_block_count(struct SpotlisT *o, int flag);
int Spotlist_sector_size(struct SpotlisT *o, int read_chunk, int flag);
int Spotlist_get_item(struct SpotlisT *o, int idx,
int *start_lba, int *blocks, int *quality, int flag);
char *Spotlist__quality_name(int quality, char name[80], int bad_limit,
int flag);
#define Xorriso_read_quality_gooD 0x7fffffff
#define Xorriso_read_quality_md5_matcH 0x70000000
#define Xorriso_read_quality_sloW 0x60000000
#define Xorriso_read_quality_partiaL 0x50000000
#define Xorriso_read_quality_valiD 0x40000000
#define Xorriso_read_quality_untesteD 0x3fffffff
#define Xorriso_read_quality_invaliD 0x3ffffffe
#define Xorriso_read_quality_tao_enD 0x28000000
#define Xorriso_read_quality_off_tracK 0x20000000
#define Xorriso_read_quality_md5_mismatcH 0x10000000
#define Xorriso_read_quality_unreadablE 0x00000000
struct CheckmediajoB {
int use_dev; /* 0= use indev , 1= use outdev , 2= use sector map*/
int min_lba; /* if >=0 : begin checking at this address */
int max_lba; /* if >=0 : read up to this address, else use mode */
int min_block_size; /* granularity desired by user
*/
int mode; /* 0= track by track
1= single sweep over libisoburn media capacity
>>> 2= single sweep over libburn media capacity
*/
time_t start_time;
int time_limit; /* Number of seconds after which to abort */
int item_limit; /* Maximum number of media check list items as result */
char abort_file_path[SfileadrL];
char data_to_path[SfileadrL];
int data_to_fd;
off_t data_to_offset; /* usually 0 with image copy, negative with file copy */
off_t data_to_limit; /* used with file copy */
int patch_lba0;
int patch_lba0_msc1;
char sector_map_path[SfileadrL];
struct SectorbitmaP *sector_map;
int map_with_volid; /* 0=add quick toc to map file,
1=read ISO heads for toc
*/
int retry; /* -1= only try full read_chunk, 1=retry with 2k blocks
0= retry with CD, full chunk else
*/
int report_mode; /* 0= print MCL items
1= print damaged files
*/
char event_severity[20]; /* If not "ALL": trigger event of given severity
at the end of a check job if bad blocks were
discovered.
*/
double slow_threshold_seq; /* Time limit in seconds for the decision whether
a read operation is considered slow. This does
not apply to thr first read of an interval.
*/
int untested_valid; /* 1= mark untested data blocks as valid when calling
Xorriso_spotlist_to_sectormap()
*/
};
int Checkmediajob_new(struct CheckmediajoB **o, int flag);
int Checkmediajob_destroy(struct CheckmediajoB **o, int flag);
int Checkmediajob_copy(struct CheckmediajoB *from, struct CheckmediajoB *to,
int flag);
int Sectorbitmap_new(struct SectorbitmaP **o, int sectors, int sector_size,
int flag);
int Sectorbitmap_destroy(struct SectorbitmaP **o, int flag);
int Sectorbitmap_from_file(struct SectorbitmaP **o, char *path, char *msg,
int *os_errno, int flag);
int Sectorbitmap_to_file(struct SectorbitmaP *o, char *path, char *info,
char *msg, int *os_errno, int flag);
int Sectorbitmap_set(struct SectorbitmaP *o, int sector, int flag);
int Sectorbitmap_set_range(struct SectorbitmaP *o,
int start_sector, int sectors, int flag);
int Sectorbitmap_is_set(struct SectorbitmaP *o, int sector, int flag);
int Sectorbitmap_bytes_are_set(struct SectorbitmaP *o,
off_t start_byte, off_t end_byte, int flag);
int Sectorbitmap_get_layout(struct SectorbitmaP *o,
int *sectors, int *sector_size, int flag);
int Sectorbitmap_copy(struct SectorbitmaP *from, struct SectorbitmaP *to,
int flag);
/* bit0= append (text!=NULL) */
int Sregex_string(char **handle, char *text, int flag);
/* @param flag bit0= only test expression whether compilable
*/
int Sregex_match(char *pattern, char *text, int flag);
#endif /* Xorriso_private_includeD */ #endif /* Xorriso_private_includeD */

View File

@ -1 +1 @@
#define Xorriso_timestamP "2010.05.05.194248" #define Xorriso_timestamP "2010.05.15.184604"

File diff suppressed because it is too large Load Diff

View File

@ -412,6 +412,15 @@ int Xorriso_setfattr(struct XorrisO *xorriso, void *in_node, char *path,
size_t num_attrs, char **names, size_t num_attrs, char **names,
size_t *value_lengths, char **values, int flag); size_t *value_lengths, char **values, int flag);
int Xorriso_perform_attr_from_list(struct XorrisO *xorriso, char *path,
struct Xorriso_lsT *lst_start, int flag);
int Xorriso_path_setfattr(struct XorrisO *xorriso, void *in_node, char *path,
char *name, size_t value_length, char *value, int flag);
int Xorriso_perform_acl_from_list(struct XorrisO *xorriso, char *file_path,
char *uid, char *gid, char *acl, int flag);
int Xorriso_record_dev_inode(struct XorrisO *xorriso, char *disk_path, int Xorriso_record_dev_inode(struct XorrisO *xorriso, char *disk_path,
dev_t dev, ino_t ino, dev_t dev, ino_t ino,
void *in_node, char *iso_path, int flag); void *in_node, char *iso_path, int flag);
@ -509,5 +518,18 @@ int Xorriso_boot_image_status(struct XorrisO *xorriso, char *filter, FILE *fp,
#define Xorriso_IFBOOT S_IFMT #define Xorriso_IFBOOT S_IFMT
int Exprtest_match(struct XorrisO *xorriso, struct ExprtesT *ftest,
void *node_pt, char *name, char *path,
struct stat *boss_stbuf, struct stat *stbuf, int flag);
int Xorriso_toc_to_string(struct XorrisO *xorriso, char **toc_text, int flag);
int Xorriso_reaquire_outdev(struct XorrisO *xorriso, int flag);
int Xorriso_set_system_area_path(struct XorrisO *xorriso, char *path,
int flag);
#endif /* Xorrisoburn_includeD */ #endif /* Xorrisoburn_includeD */