diff --git a/Makefile.am b/Makefile.am index 72b9a9bb..88e7c0d4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -50,8 +50,7 @@ bin_PROGRAMS = \ # cat xorriso/xorriso_buildstamp.h xorriso_xorriso_CPPFLAGS = -Ilibisoburn -xorriso_xorriso_CFLAGS = -DXorriso_with_maiN \ - $(READLINE_DEF) $(LIBACL_DEF) $(XATTR_DEF) \ +xorriso_xorriso_CFLAGS = $(READLINE_DEF) $(LIBACL_DEF) $(XATTR_DEF) \ $(EXTF_DEF) $(EXTF_SUID_DEF) $(ZLIB_DEF) \ $(XORRISO_DVD_OBS_64K) @@ -61,9 +60,55 @@ xorriso_xorriso_LDADD = libisoburn/libisoburn.la -lisofs -lburn \ xorriso_xorriso_SOURCES = \ xorriso/xorriso.h \ xorriso/xorriso_private.h \ - xorriso/xorriso.c \ + xorriso/xorriso_main.c \ + xorriso/sfile.h \ + xorriso/sfile.c \ + xorriso/aux_objects.h \ + xorriso/aux_objects.c \ + xorriso/findjob.h \ + xorriso/findjob.c \ + xorriso/check_media.h \ + xorriso/check_media.c \ + xorriso/misc_funct.h \ + xorriso/misc_funct.c \ + xorriso/text_io.h \ + xorriso/text_io.c \ + xorriso/match.h \ + xorriso/match.c \ + xorriso/emulators.h \ + xorriso/emulators.c \ + xorriso/disk_ops.h \ + xorriso/disk_ops.c \ + xorriso/cmp_update.h \ + xorriso/cmp_update.c \ + xorriso/parse_exec.h \ + xorriso/parse_exec.c \ + xorriso/opts_a_c.c \ + xorriso/opts_d_h.c \ + xorriso/opts_i_o.c \ + xorriso/opts_p_z.c \ +\ xorriso/xorrisoburn.h \ - xorriso/xorrisoburn.c \ + xorriso/base_obj.h \ + xorriso/base_obj.c \ + xorriso/lib_mgt.h \ + xorriso/lib_mgt.c \ + xorriso/sort_cmp.h \ + xorriso/sort_cmp.c \ + xorriso/drive_mgt.h \ + xorriso/drive_mgt.c \ + xorriso/iso_img.h \ + xorriso/iso_img.c \ + xorriso/iso_tree.h \ + xorriso/iso_tree.c \ + xorriso/iso_manip.h \ + xorriso/iso_manip.c \ + xorriso/write_run.h \ + xorriso/write_run.c \ + xorriso/read_run.h \ + xorriso/read_run.c \ + xorriso/filters.h \ + xorriso/filters.c \ xorriso/xorriso_timestamp.h \ xorriso/xorriso_buildstamp.h diff --git a/xorriso/aux_objects.c b/xorriso/aux_objects.c new file mode 100644 index 00000000..2cbbf525 --- /dev/null +++ b/xorriso/aux_objects.c @@ -0,0 +1,995 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#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 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->partnopartno) + return(-1); + if(p1->offset>p2->offset) + return(1); + if(p1->offsetoffset) + 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;ibuffer_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_fillbuffer_size && o->buffer_fill>0) + Sort_argv(o->buffer_fill,o->buffer,0); + } + if(o->buffer_rptbuffer_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;itext= 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; inot_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; inot_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 ----------------------------- */ + diff --git a/xorriso/aux_objects.h b/xorriso/aux_objects.h new file mode 100644 index 00000000..a4073195 --- /dev/null +++ b/xorriso/aux_objects.h @@ -0,0 +1,182 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/base_obj.c b/xorriso/base_obj.c new file mode 100644 index 00000000..cdf2d97b --- /dev/null +++ b/xorriso/base_obj.c @@ -0,0 +1,537 @@ + + + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains functions which are needed to read data + from ISO image. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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;irc_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;ire_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;ire_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); +} + diff --git a/xorriso/base_obj.h b/xorriso/base_obj.h new file mode 100644 index 00000000..7fb60eba --- /dev/null +++ b/xorriso/base_obj.h @@ -0,0 +1,31 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/check_media.c b/xorriso/check_media.c new file mode 100644 index 00000000..a02f39e0 --- /dev/null +++ b/xorriso/check_media.c @@ -0,0 +1,1102 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains the implementation of classes SpotlistiteM, SectorbitmaP, + CheckmediajoB which perform verifying runs on media resp. images. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xorriso.h" +#include "xorriso_private.h" +#include "xorrisoburn.h" + + +/* ------------------------------ SpotlisT -------------------------------- */ + + +struct SpotlistiteM { + int start_lba; + int blocks; + int quality; + struct SpotlistiteM *next; +}; + + +int Spotlistitem_new(struct SpotlistiteM **o, int start_lba, int blocks, + int quality, int flag) +{ + struct SpotlistiteM *m; + + m= TSOB_FELD(struct SpotlistiteM,1); + if(m==NULL) + return(-1); + *o= m; + m->start_lba= start_lba; + m->blocks= blocks; + m->quality= quality; + m->next= NULL; + return(1); +} + + +int Spotlistitem_destroy(struct SpotlistiteM **o, int flag) +{ + if((*o) == NULL) + return(0); + free((char *) *o); + *o= NULL; + return(1); +} + + +struct SpotlisT { + struct SpotlistiteM *list_start; + struct SpotlistiteM *list_end; + int list_count; + struct SpotlistiteM *current_item; + int current_idx; +}; + + +int Spotlist_new(struct SpotlisT **o, int flag) +{ + struct SpotlisT *m; + + m= TSOB_FELD(struct SpotlisT,1); + if(m==NULL) + return(-1); + *o= m; + m->list_start= NULL; + m->list_end= NULL; + m->list_count= 0; + m->current_item= NULL; + m->current_idx= -1; + return(1); +} + + +int Spotlist_destroy(struct SpotlisT **o, int flag) +{ + struct SpotlisT *m; + struct SpotlistiteM *li, *next_li; + + if((*o) == NULL) + return(0); + m= *o; + for(li= m->list_start; li != NULL; li= next_li) { + next_li= li->next; + Spotlistitem_destroy(&li, 0); + } + free((char *) *o); + *o= NULL; + return(1); +} + + +int Spotlist_add_item(struct SpotlisT *o, int start_lba, int blocks, + int quality, int flag) +{ + int ret; + struct SpotlistiteM *li; + static int debug_verbous= 0; + + ret= Spotlistitem_new(&li, start_lba, blocks, quality, 0); + if(ret <= 0) + return(ret); + if(o->list_end != NULL) + o->list_end->next= li; + o->list_end= li; + if(o->list_start == NULL) + o->list_start= li; + (o->list_count)++; + + if(debug_verbous) {char quality_name[80]; + fprintf(stderr, "debug: lba %10d , size %10d , quality '%s'\n", + start_lba, blocks, Spotlist__quality_name(quality, quality_name, + Xorriso_read_quality_invaliD, 0) + 2); + } + + return(1); +} + + +int Spotlist_count(struct SpotlisT *o, int flag) +{ + return o->list_count; +} + + +int Spotlist_block_count(struct SpotlisT *o, int flag) +{ + int list_blocks= 0; + struct SpotlistiteM *li; + + for(li= o->list_start; li != NULL; li= li->next) { + if(li->start_lba + li->blocks > list_blocks) + list_blocks= li->start_lba + li->blocks; + } + return(list_blocks); +} + + +int Spotlist_sector_size(struct SpotlisT *o, int read_chunk, int flag) +{ + int sector_size; + struct SpotlistiteM *li; + + sector_size= read_chunk * 2048; + for(li= o->list_start; li != NULL; li= li->next) { + if((li->start_lba % read_chunk) || (li->blocks % read_chunk)) { + sector_size= 2048; + break; + } + } + return(sector_size); +} + + +int Spotlist_get_item(struct SpotlisT *o, int idx, + int *start_lba, int *blocks, int *quality, int flag) +{ + int i; + struct SpotlistiteM *li; + + if(idx < 0 || idx > o->list_count) + return(0); + if(idx == o->current_idx && o->current_item != NULL) + li= o->current_item; + else if(idx == o->current_idx + 1 && o->current_item != NULL) { + li= o->current_item->next; + } else { + li= o->list_start; + for(i= 0; i < idx; i++) + li= li->next; + } + o->current_item= li; + o->current_idx= idx; + *start_lba= li->start_lba; + *blocks= li->blocks; + *quality= li->quality; + return(1); +} + + +char *Spotlist__quality_name(int quality, char name[80], int bad_limit, + int flag) +{ + if(quality == Xorriso_read_quality_untesteD || + quality == Xorriso_read_quality_tao_enD || + quality == Xorriso_read_quality_off_tracK) + strcpy(name, "0 "); + else if(quality <= bad_limit) + strcpy(name, "- "); + else + strcpy(name, "+ "); + if(quality == Xorriso_read_quality_gooD) + strcat(name, "good"); + else if(quality == Xorriso_read_quality_md5_matcH) + strcat(name, "md5_match"); + else if(quality == Xorriso_read_quality_sloW) + strcat(name, "slow"); + else if(quality == Xorriso_read_quality_partiaL) + strcat(name, "partial"); + else if(quality == Xorriso_read_quality_valiD) + strcat(name, "valid"); + else if(quality == Xorriso_read_quality_untesteD) + strcat(name, "untested"); + else if(quality == Xorriso_read_quality_invaliD) + strcat(name, "invalid"); + else if(quality == Xorriso_read_quality_tao_enD) + strcat(name, "tao_end"); + else if(quality == Xorriso_read_quality_off_tracK) + strcat(name, "off_track"); + else if(quality == Xorriso_read_quality_md5_mismatcH) + strcat(name, "md5_mismatch"); + else if(quality == Xorriso_read_quality_unreadablE) + strcat(name, "unreadable"); + else + sprintf(name, "0 0x%8.8X", (unsigned int) quality); + return(name); +} + + +/* ---------------------------- End SpotlisT ------------------------------ */ + +/* ---------------------------- SectorbitmaP ------------------------------ */ + +int Sectorbitmap_new(struct SectorbitmaP **o, int sectors, int sector_size, + int flag) +{ + struct SectorbitmaP *m; + + m= TSOB_FELD(struct SectorbitmaP,1); + if(m==NULL) + return(-1); + *o= m; + m->sectors= sectors; + m->sector_size= sector_size; + m->map= NULL; + m->map_size= sectors / 8 + 1; + + m->map= calloc(m->map_size, 1); + if(m->map == NULL) + goto failure; + return(1); +failure:; + Sectorbitmap_destroy(o, 0); + return(-1); +} + + +int Sectorbitmap_destroy(struct SectorbitmaP **o, int flag) +{ + if((*o) == NULL) + return(0); + if((*o)->map != NULL) + free((char *) (*o)->map); + free((char *) *o); + *o= NULL; + return(1); +} + + +int Sectorbitmap_from_file(struct SectorbitmaP **o, char *path, char *msg, + int *os_errno, int flag) +{ + int ret, fd= -1, sectors, sector_size, i, todo, map_size, skip; + unsigned char *map; + unsigned char buf[1024]; + + *os_errno= 0; + if(msg != NULL) + msg[0]= 0; + fd= open(path, O_RDONLY); + if(fd == -1) { + *os_errno= errno; + if(msg != NULL) { + strcpy(msg, "Cannot open path "); + Text_shellsafe(path, msg+strlen(msg), 0); + } + return(0); + } + ret= read(fd, buf, 32); + if(ret < 32) { +wrong_filetype:; + if(ret == -1) + *os_errno= errno; + if(msg != NULL) { + strcpy(msg, "Not a sector bitmap file: "); + Text_shellsafe(path, msg+strlen(msg), 0); + } + ret= 0; goto ex; + } + if(strncmp((char *) buf, "xorriso sector bitmap v1 ", 32) == 0) + /* ok */; + else if(strncmp((char *) buf, "xorriso sector bitmap v2 ", 25) == 0) { + skip= -1; + sscanf(((char *) buf) + 25, "%d", &skip); + if(skip < 0) + {ret= 0; goto wrong_filetype;} + for(i= 0; i < skip; i+= sizeof(buf)) { + todo= sizeof(buf); + if(i + todo > skip) + todo= skip - i; + ret= read(fd, buf, todo); + if(ret < todo) + goto wrong_filetype; + } + } else + {ret= 0; goto wrong_filetype;} + ret= read(fd, buf, 8); + if(ret < 4) + goto wrong_filetype; + sectors= (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; + sector_size= (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]; + if(sectors <= 0 || sector_size <= 0) + goto wrong_filetype; + ret= Sectorbitmap_new(o, sectors, sector_size, 0); + if(ret <= 0) { + if(msg != NULL) + sprintf(msg, "Cannot allocate bitmap memory for %d sectors", sectors); + ret= -1; goto ex; + } + map= (*o)->map; + map_size= (*o)->map_size; + for(i= 0; i < map_size; i+= sizeof(buf)) { + todo= sizeof(buf); + if(i + todo > map_size) + todo= map_size - i; + ret= read(fd, buf, todo); + if(ret != todo) + goto wrong_filetype; + memcpy(map + i, buf, todo); + } + ret= 1; +ex:; + if(fd != -1) + close(fd); + if(ret <= 0) + Sectorbitmap_destroy(o, 0); + return(ret); +} + + +int Sectorbitmap_to_file(struct SectorbitmaP *o, char *path, char *info, + char *msg, int *os_errno, int flag) +{ + int ret, fd= -1, j, l; + unsigned char buf[40]; + + *os_errno= 0; + fd= open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); + if(fd == -1) { + *os_errno= errno; + if(msg != NULL) { + strcpy(msg, "Cannot open path "); + Text_shellsafe(path, msg+strlen(msg), 0); + } + return(0); + } + + l= 0; + if(info != NULL) + l= strlen(info); + if(l > 999999) { + strcpy(msg, "Info string is longer than 999999 bytes"); + return(0); + } + sprintf((char *) buf, "xorriso sector bitmap v2 %-6d\n", l); + + ret= write(fd, buf, 32); + if(ret != 32) { +cannot_write:; + *os_errno= errno; + if(msg != NULL) { + strcpy(msg, "Cannot write to "); + Text_shellsafe(path, msg+strlen(msg), 0); + } + ret= 0; goto ex; + } + if(l > 0) { + ret= write(fd, info, l); + if(ret != l) + goto cannot_write; + } + + for(j= 0; j < 4; j++) { + buf[j]= o->sectors >> (24 - j * 8); + buf[j+4]= o->sector_size >> (24 - j * 8); + } + ret= write(fd, buf, 8); + if(ret != 8) + goto cannot_write; + ret= write(fd, o->map, o->map_size); + if(ret != o->map_size) + goto cannot_write; + + ret= 1; +ex:; + if(fd != -1) + close(fd); + return(ret); +} + + +/* @param flag bit0= sector bit value +*/ +int Sectorbitmap_set(struct SectorbitmaP *o, int sector, int flag) +{ + if(sector < 0 || sector >= o->sectors) + return(0); + if(flag & 1) + o->map[sector / 8]|= 1 << (sector % 8); + else + o->map[sector / 8]&= ~(1 << (sector % 8)); + return(1); +} + + +/* @param flag bit0= sector bit value +*/ +int Sectorbitmap_set_range(struct SectorbitmaP *o, + int start_sector, int sectors, int flag) +{ + int start_i, end_i, i; + unsigned char value; + + if(start_sector < 0 || start_sector + sectors > o->sectors || sectors < 1) + return(0); + if(flag & 1) + value= ~0; + else + value= 0; + start_i= start_sector / 8; + end_i= (start_sector + sectors - 1) / 8; + for(i= start_sector; i / 8 == start_i && i < start_sector + sectors; i++) + Sectorbitmap_set(o, i, flag & 1); + for(i= start_i + 1; i < end_i; i++) + o->map[i]= value; + if(end_i > start_i) + for(i= end_i * 8; i < start_sector + sectors; i++) + Sectorbitmap_set(o, i, flag & 1); + return(1); +} + + +int Sectorbitmap_is_set(struct SectorbitmaP *o, int sector, int flag) +{ + if(sector < 0 || sector >= o->sectors) + return(0); + return(!! (o->map[sector / 8] & (1 << (sector % 8)))); +} + + +int Sectorbitmap_bytes_are_set(struct SectorbitmaP *o, + off_t start_byte, off_t end_byte, int flag) +{ + int end_sector, i; + + end_sector= end_byte / o->sector_size; + for(i= start_byte / o->sector_size; i <= end_sector; i++) + if(!Sectorbitmap_is_set(o, i, 0)) + return(0); + return(1); +} + + +int Sectorbitmap_get_layout(struct SectorbitmaP *o, + int *sectors, int *sector_size, int flag) +{ + *sectors= o->sectors; + *sector_size= o->sector_size; + return(1); +} + + +int Sectorbitmap_copy(struct SectorbitmaP *from, struct SectorbitmaP *to, + int flag) +{ + int i, run_start, run_value, start_sec, limit_sec, start_aligned; + int end_complete; + + if(((off_t) from->sectors) * ((off_t) from->sector_size) > + ((off_t) to->sectors) * ((off_t) to->sector_size)) + return(-1); + if(from->sector_size == to->sector_size) { + for(i= 0; i < from->map_size; i++) + to->map[i]= from->map[i]; + return(1); + } + run_start= 0; + run_value= Sectorbitmap_is_set(from, 0, 0); + for(i= 1; i <= from->sectors; i++) { + if(i < from->sectors) + if(Sectorbitmap_is_set(from, i, 0) == run_value) + continue; + start_sec= run_start * from->sector_size / to->sector_size; + start_aligned= + (start_sec * to->sector_size == run_start * from->sector_size); + limit_sec= i * from->sector_size / to->sector_size; + end_complete= (limit_sec * to->sector_size == i * from->sector_size); + if(run_value) { + if(!start_aligned) + start_sec++; + } else { + if(!end_complete) + limit_sec++; + } + if(start_sec < limit_sec) + Sectorbitmap_set_range(to, start_sec, limit_sec - 1 - start_sec, + !!run_value); + run_value= !run_value; + run_start= i; + } + return(1); +} + + +int Sectorbitmap_clone(struct SectorbitmaP *from, struct SectorbitmaP **clone, + int flag) +{ + int ret; + + ret= Sectorbitmap_new(clone, from->sectors, from->sector_size, 0); + if(ret <= 0) + return(ret); + ret= Sectorbitmap_copy(from, *clone, 0); + if(ret <= 0) + Sectorbitmap_destroy(clone, 0); + return(ret); +} + + +/* -------------------------- End SectorbitmaP ---------------------------- */ + +/* ---------------------------- CheckmediajoB ----------------------------- */ + +int Checkmediajob_new(struct CheckmediajoB **o, int flag) +{ + struct CheckmediajoB *m; + + m= TSOB_FELD(struct CheckmediajoB,1); + if(m==NULL) + return(-1); + *o= m; + m->use_dev= 0; + m->min_lba= -1; + m->max_lba= -1; + m->min_block_size= 0; + m->mode= 0; + m->start_time= time(NULL); + m->time_limit= 28800; + m->item_limit= 100000; + strcpy(m->abort_file_path, "/var/opt/xorriso/do_abort_check_media"); + m->data_to_path[0]= 0; + m->data_to_fd= -1; + m->data_to_offset= 0; + m->data_to_limit= -1; + m->patch_lba0= 0; + m->patch_lba0_msc1= -1; + m->sector_map_path[0]= 0; + m->sector_map= NULL; + m->map_with_volid= 0; + m->retry= 0; + m->report_mode= 0; + strcpy(m->event_severity, "ALL"); + m->slow_threshold_seq= 1.0; + m->untested_valid= 0; + return(1); +} + + +int Checkmediajob_destroy(struct CheckmediajoB **o, int flag) +{ + if((*o) == NULL) + return(0); + if((*o)->data_to_fd != -1) + close((*o)->data_to_fd); + Sectorbitmap_destroy(&((*o)->sector_map), 0); + free((char *) *o); + *o= NULL; + return(1); +} + + +int Checkmediajob_copy(struct CheckmediajoB *from, struct CheckmediajoB *to, + int flag) +{ + to->use_dev= from->use_dev; + to->min_lba= from->min_lba; + to->max_lba= from->max_lba; + to->min_block_size= from->min_block_size; + to->mode= from->mode; + to->time_limit= from->time_limit; + to->item_limit= from->item_limit; + strcpy(to->abort_file_path, from->abort_file_path); + strcpy(to->data_to_path, from->data_to_path); + /* not copied: data_to_fd */ + to->data_to_offset= from->data_to_offset; + to->data_to_limit= from->data_to_limit; + to->patch_lba0= from->patch_lba0; + to->patch_lba0_msc1= from->patch_lba0_msc1; + strcpy(to->sector_map_path, from->sector_map_path); + /* not copied: sector_map */ + to->map_with_volid= from->map_with_volid; + to->retry= from->retry; + to->report_mode= from->report_mode; + strcpy(to->event_severity, from->event_severity); + to->slow_threshold_seq= from->slow_threshold_seq; + to->untested_valid= from->untested_valid; + return(1); +} + + +/* -------------------------- End CheckmediajoB --------------------------- */ + + +int Xorriso_check_media_setup_job(struct XorrisO *xorriso, + struct CheckmediajoB *job, + char **argv, int old_idx, int end_idx, int flag) +{ + int ret, i, sev; + double num; + struct CheckmediajoB *default_job; + char sev_text[20]; + + if(xorriso->check_media_default != NULL) + Checkmediajob_copy(xorriso->check_media_default, job, 0); + for(i= old_idx; i < end_idx; i++) { + if(strncmp(argv[i], "abort_file=", 11) == 0) { + ret= Sfile_str(job->abort_file_path, argv[i] + 11, 0); + if(ret <= 0) + goto ex; + } else if(strncmp(argv[i], "bad_limit=", 10) == 0) { + if(strcmp(argv[i] + 10, "good") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_gooD; + else if(strcmp(argv[i] + 10, "md5_match") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_md5_matcH; + else if(strcmp(argv[i] + 10, "slow") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_sloW; + else if(strcmp(argv[i] + 10, "partial") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_partiaL; + else if(strcmp(argv[i] + 10, "valid") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_valiD; + else if(strcmp(argv[i] + 10, "untested") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_untesteD; + else if(strcmp(argv[i] + 10, "invalid") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_invaliD; + else if(strcmp(argv[i] + 10, "tao_end") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_tao_enD; + else if(strcmp(argv[i] + 10, "off_track") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_off_tracK; + else if(strcmp(argv[i] + 10, "md5_mismatch") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_md5_mismatcH; + else if(strcmp(argv[i] + 10, "unreadable") == 0) + xorriso->check_media_bad_limit= Xorriso_read_quality_unreadablE; + else + goto unknown_value; + } else if(strncmp(argv[i], "data_to=", 8) == 0) { + ret= Sfile_str(job->data_to_path, argv[i] + 8, 0); + if(ret <= 0) + goto ex; + } else if(strncmp(argv[i], "chunk_size=", 11) == 0) { + num= Scanf_io_size(argv[i] + 11, 1); + if(num >= 2048 || num == 0) + job->min_block_size= num / 2048; + else + goto unknown_value; + } else if(strncmp(argv[i], "event=", 6) == 0) { + strncpy(sev_text, argv[i] + 6, 19); + sev_text[19]= 0; + ret= Xorriso__text_to_sev(sev_text, &sev, 0); + if(ret <= 0) { + strcpy(xorriso->info_text, "-check_media event="); + Text_shellsafe(sev_text, xorriso->info_text, 1); + strcat(xorriso->info_text, " : Not a known severity name"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + goto ex; + } + strcpy(job->event_severity, sev_text); + } else if(strncmp(argv[i], "map_with_volid=", 15) == 0) { + if(strcmp(argv[i] + 15, "on") == 0) + job->map_with_volid= 1; + else if(strcmp(argv[i] + 15, "off") == 0) + job->map_with_volid= 0; + else + goto unknown_value; + } else if(strncmp(argv[i], "max_lba=", 8) == 0 || + strncmp(argv[i], "min_lba=", 8) == 0) { + num= -1; + sscanf(argv[i] + 8, "%lf", &num); + if(num > 0x7fffffff || num < 0) + num= -1; + if(strncmp(argv[i], "max_lba=", 8) == 0) + job->max_lba= num; + else + job->min_lba= num; + } else if(strncmp(argv[i], "patch_lba0=", 11) == 0) { + job->patch_lba0_msc1= -1; + if(strcmp(argv[i] + 11, "on") == 0) + job->patch_lba0= 1; + else if(strcmp(argv[i] + 11, "off") == 0) + job->patch_lba0= 0; + else if(strcmp(argv[i] + 11, "force") == 0) + job->patch_lba0= 2; + else if(argv[i][11] >= '1' && argv[i][11] <= '9') { + num= -1; + sscanf(argv[i] + 11, "%lf", &num); + if(num > 0x7fffffff || num < 0) + goto unknown_value; + job->patch_lba0_msc1= num; + job->patch_lba0= (num >= 32) + (strstr(argv[i] + 11, ":force") != NULL); + } else + goto unknown_value; + } else if(strncmp(argv[i], "report=", 7) == 0) { + if(strcmp(argv[i] + 7, "blocks") == 0) + job->report_mode= 0; + else if(strcmp(argv[i] + 7, "files") == 0) + job->report_mode= 1; + else if(strcmp(argv[i] + 7, "blocks_files") == 0) + job->report_mode= 2; + else + goto unknown_value; + } else if(strcmp(argv[i], "reset=now") == 0) { + ret= Checkmediajob_new(&default_job, 0); + if(ret <= 0) { + sprintf(xorriso->info_text, + "-check_media: Cannot reset options due to lack of resources"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + ret= -1; goto ex; + } + Checkmediajob_copy(default_job, job, 0); + Checkmediajob_destroy(&default_job, 0); + xorriso->check_media_bad_limit= Xorriso_read_quality_invaliD; + } else if(strncmp(argv[i], "retry=", 6) == 0) { + if(strcmp(argv[i] + 6, "on") == 0) + job->retry= 1; + else if(strcmp(argv[i] + 6, "off") == 0) + job->retry= -1; + else if(strcmp(argv[i] + 6, "default") == 0) + job->retry= 0; + else + goto unknown_value; + } else if(strncmp(argv[i], "sector_map=", 11) == 0) { + ret= Sfile_str(job->sector_map_path, argv[i] + 11, 0); + if(ret <= 0) + goto ex; + } else if(strncmp(argv[i], "slow_limit=", 11) == 0) { + sscanf(argv[i] + 11, "%lf", &(job->slow_threshold_seq)); + } else if(strncmp(argv[i], "time_limit=", 11) == 0 || + strncmp(argv[i], "item_limit=", 11) == 0 ) { + num= -1; + sscanf(argv[i] + 11, "%lf", &num); + if(num > 0x7fffffff || num < 0) + num= -1; + if(strncmp(argv[i], "time_limit=", 11) == 0) + job->time_limit= num; + else + job->item_limit= num; + +#ifdef NIX + } else if(strncmp(argv[i], "untested=", 9) == 0) { + if(strcmp(argv[i] + 9, "damaged") == 0) + job->untested_valid= 0; + if(strcmp(argv[i] + 9, "undamaged") == 0 || + strcmp(argv[i] + 9, "ok") == 0) + job->untested_valid= 1; + else + goto unknown_value; +#endif + + } else if(strncmp(argv[i], "use=", 4) == 0) { + if(strcmp(argv[i] + 4, "outdev") == 0) + job->use_dev= 1; + else if(strcmp(argv[i] + 4, "indev") == 0) + job->use_dev= 0; + else if(strcmp(argv[i] + 4, "sector_map") == 0) + job->use_dev= 2; + else + goto unknown_value; + } else if(strncmp(argv[i], "what=", 5) == 0) { + if(strcmp(argv[i]+5, "tracks") == 0) + job->mode= 0; + else if(strcmp(argv[i]+5, "disc")== 0) + job->mode= 1; + else { +unknown_value:; + sprintf(xorriso->info_text, + "-check_media: Unknown value with option %s", argv[i]); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + } else { + sprintf(xorriso->info_text, "-check_media: Unknown option '%s'", argv[i]); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + } + ret= 1; +ex:; + return(ret); +} + + +/* @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 all, ret; + char default_report[161], quality_name[80]; + struct CheckmediajoB *dflt= NULL; + + all= !(flag&1); + report[0]= 0; + ret= Checkmediajob_new(&dflt, 0); + if(ret <= 0) + return(-1); + sprintf(report, "-check_media_defaults"); + if(!all) + strcat(report, " reset=now"); + if(all || job->use_dev != dflt->use_dev) + sprintf(report + strlen(report), " use=%s", + job->use_dev == 1 ? "outdev" : + job->use_dev == 2 ? "sector_map" : "indev"); + if(all || job->mode != dflt->mode) + sprintf(report + strlen(report), " what=%s", + job->mode == 1 ? "disc" : "tracks"); + if(all || job->min_lba != dflt->min_lba) + sprintf(report + strlen(report), " min_lba=%d", job->min_lba); + if(all || job->max_lba != dflt->max_lba) + sprintf(report + strlen(report), " max_lba=%d", job->max_lba); + if(all || job->retry != dflt->retry) + sprintf(report + strlen(report), " retry=%s", + job->retry == 1 ? "on" : job->retry == -1 ? "off" : "default"); + if(all || job->time_limit != dflt->time_limit) + sprintf(report + strlen(report), " time_limit=%d", job->time_limit); + if(all || job->item_limit != dflt->item_limit) + sprintf(report + strlen(report), " item_limit=%d", job->item_limit); + if(all || strcmp(job->abort_file_path, dflt->abort_file_path)) { + strcat(report, " abort_file="); + Text_shellsafe(job->abort_file_path, report + strlen(report), 0); + } + if(strlen(report) > 4 * SfileadrL) + {ret= 0; goto ex;} + if(all || strcmp(job->data_to_path, dflt->data_to_path)) { + strcat(report, " data_to="); + Text_shellsafe(job->data_to_path, report + strlen(report), 0); + } + if(strlen(report) > 4 * SfileadrL) + {ret= 0; goto ex;} + if(all || strcmp(job->sector_map_path, dflt->sector_map_path)) { + strcat(report, " sector_map="); + Text_shellsafe(job->sector_map_path, report + strlen(report), 0); + } + if(all || job->map_with_volid != dflt->map_with_volid) + sprintf(report + strlen(report), " map_with_volid=%s", + job->map_with_volid == 1 ? "on" : "off"); + if(all || job->patch_lba0 != dflt->patch_lba0) { + sprintf(report + strlen(report), " patch_lba0="); + if(job->patch_lba0 == 0) + sprintf(report + strlen(report), "off"); + else if(job->patch_lba0_msc1 >= 0) + sprintf(report + strlen(report), "%d%s", + job->patch_lba0_msc1, job->patch_lba0 == 2 ? ":force" : ""); + else + sprintf(report + strlen(report), "%s", + job->patch_lba0 == 2 ? "force" : "on"); + } + if(all || job->report_mode != dflt->report_mode) + sprintf(report + strlen(report), " report=%s", + job->report_mode == 0 ? "blocks" : + job->report_mode == 1 ? "files" : "blocks_files"); + if(all || job->slow_threshold_seq != dflt->slow_threshold_seq) + sprintf(report + strlen(report), " slow_limit=%f", job->slow_threshold_seq); + if(all || xorriso->check_media_bad_limit != Xorriso_read_quality_invaliD) + sprintf(report + strlen(report), " bad_limit=%s", + Spotlist__quality_name(xorriso->check_media_bad_limit, quality_name, + Xorriso_read_quality_invaliD, 0) + 2); + if(all || job->min_block_size != dflt->min_block_size) + sprintf(report + strlen(report), " chunk_size=%ds", job->min_block_size); + if(all || strcmp(job->event_severity, "ALL") != 0) + sprintf(report + strlen(report), " event=%s", job->event_severity); + if(strlen(report) > 4 * SfileadrL) + {ret= 0; goto ex;} + ret= 1; +ex:; + strcat(report, " "); + strcat(report, xorriso->list_delimiter); + Checkmediajob_destroy(&dflt, 0); + sprintf(default_report, "-check_media_defaults reset=now %s", + xorriso->list_delimiter); + if(ret > 0 && strcmp(report, default_report) == 0) + return(2); + return(ret); +} + + +int Xorriso_sectormap_to_spotlist(struct XorrisO *xorriso, + struct CheckmediajoB *job, + struct SpotlisT **spotlist, + int flag) +{ + struct SectorbitmaP *map; + int ret, i, sectors, sector_size, value, old_value= -1, old_start= -1; + + map= job->sector_map; + if(map == NULL) + return(-1); + ret= Spotlist_new(spotlist, 0); + if(ret <= 0) + {ret= -1; goto ex;} + Sectorbitmap_get_layout(map, §ors, §or_size, 0); + sector_size/= 2048; + if(job->max_lba >= 0) + sectors= (job->max_lba + 1) / sector_size; + i= 0; + if(job->min_lba >= 0) + i= job->min_lba / sector_size; + for(; i < sectors; i++) { + value= Sectorbitmap_is_set(map, i, 0); + if(value == old_value) + continue; + if(old_value >= 0) { + ret= Spotlist_add_item(*spotlist, old_start, i * sector_size - old_start, + (old_value ? Xorriso_read_quality_valiD : + Xorriso_read_quality_invaliD), 0); + if(ret <= 0) + goto ex; + if(job->item_limit > 0 && + Spotlist_count(*spotlist, 0) + 1 >= job->item_limit) { + sprintf(xorriso->info_text, "-check_media: Reached item_limit=%d", + job->item_limit); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + if(sectors - i > 1) { + ret= Spotlist_add_item(*spotlist, i * sector_size, + (sectors - i - 1) * sector_size, + Xorriso_read_quality_untesteD, 0); + if(ret <= 0) + goto ex; + } + ret= 2; goto ex; + } + } + old_value= value; + old_start= i * sector_size; + } + if(old_value >= 0) { + ret= Spotlist_add_item(*spotlist, old_start, i * sector_size - old_start, + (old_value ? Xorriso_read_quality_valiD : + Xorriso_read_quality_invaliD), 0); + if(ret <= 0) + goto ex; + } + ret= 1; +ex:; + if(ret <= 0) + Spotlist_destroy(spotlist, 0); + return(ret); +} + + +/* @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) +{ + struct SectorbitmaP *m; + int map_sectors= -1, map_sector_size= -1, valid; + int list_sectors, list_blocks, sector_size, sector_blocks; + int replace_map= 0, count, i, lba, blocks, quality, ret, pass; + + sector_size= Spotlist_sector_size(spotlist, read_chunk, 0); + sector_blocks= sector_size / 2048; + if(*map != NULL) + Sectorbitmap_get_layout(*map, &map_sectors, &map_sector_size, 0); + + count= Spotlist_count(spotlist, 0); + list_blocks= Spotlist_block_count(spotlist, 0); + + /* >>> ??? insist in list_blocks % sector_blocks == 0 */ + + list_sectors= list_blocks / sector_blocks; + if(list_sectors * sector_blocks < list_blocks) + list_sectors++; + if(*map != NULL && map_sectors * (map_sector_size / 2048) >= list_blocks && + map_sector_size == sector_size) + m= *map; + else { + if(*map != NULL) { + if(((off_t) (*map)->sectors) * ((off_t) (*map)->sector_size) > + ((off_t) list_sectors) * ((off_t) sector_size)) + list_sectors= (((off_t) (*map)->sectors) * + ((off_t) (*map)->sector_size)) / ((off_t) sector_size) + + 1; + } + ret= Sectorbitmap_new(&m, list_sectors, sector_size, 0); + if(ret <= 0) + return(-1); + replace_map= 1; + if(*map != NULL) { + ret= Sectorbitmap_copy(*map, m, 0); + if(ret <= 0) { + Sectorbitmap_destroy(&m, 0); + return(0); + } + } + } + + count= Spotlist_count(spotlist, 0); + /* first set good bits, then eventually override by bad bits */ + for(pass= 0; pass < 2; pass++) { + for(i= 0; i < count; i++) { + ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0); + if(ret <= 0) + continue; + valid= quality > xorriso->check_media_bad_limit; + if(quality == Xorriso_read_quality_untesteD && (flag & 1)) + valid= 1; + else if(pass == 0 && !valid) + continue; + else if(pass == 1 && valid) + continue; + Sectorbitmap_set_range(m, lba / sector_blocks, blocks / sector_blocks, + valid); + } + } + if(replace_map) { + Sectorbitmap_destroy(map, 0); + *map= m; + } + return(1); +} + + +int Xorriso_open_job_data_to(struct XorrisO *xorriso, + struct CheckmediajoB *job, int flag) +{ + char sfe[5*SfileadrL]; + + if(job->data_to_path[0] == 0) + return(2); + job->data_to_fd= open(job->data_to_path, O_RDWR | O_CREAT, + S_IRUSR | S_IWUSR); + if(job->data_to_fd == -1) { + sprintf(xorriso->info_text, "Cannot open path %s", + Text_shellsafe(job->data_to_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + return(0); + } + return(1); +} + + +int Xorriso_update_in_sector_map(struct XorrisO *xorriso, + struct SpotlisT *spotlist, int read_chunk, + struct CheckmediajoB *job, int flag) +{ + int sectors, sector_size, sector_blocks, ret; + struct SectorbitmaP *map; + + Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); + if(job->use_dev == 1) + return(1); + map= job->sector_map; + sectors= Spotlist_block_count(spotlist, 0); + if(sectors <= 0) + return(0); + sector_size= Spotlist_sector_size(spotlist, read_chunk, 0); + sector_blocks= sector_size / 2048; + if(sector_blocks > 1) + sectors= sectors / sector_blocks + !!(sectors % sector_blocks); + ret= Sectorbitmap_new(&(xorriso->in_sector_map), sectors, sector_size, 0); + if(ret <= 0) + return(ret); + if(map != NULL) + Sectorbitmap_copy(map, xorriso->in_sector_map, 0); + ret= Xorriso_spotlist_to_sectormap(xorriso, spotlist, read_chunk, + &(xorriso->in_sector_map), 1); + return(ret); +} + diff --git a/xorriso/check_media.h b/xorriso/check_media.h new file mode 100644 index 00000000..7f8bedf7 --- /dev/null +++ b/xorriso/check_media.h @@ -0,0 +1,181 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/cmp_update.c b/xorriso/cmp_update.c new file mode 100644 index 00000000..5eaaa617 --- /dev/null +++ b/xorriso/cmp_update.c @@ -0,0 +1,947 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#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 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; ipacifier_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; i0 && 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(retfind_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; iSfileadrL) { + 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; iinfo_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); +} + diff --git a/xorriso/cmp_update.h b/xorriso/cmp_update.h new file mode 100644 index 00000000..1e35fb94 --- /dev/null +++ b/xorriso/cmp_update.h @@ -0,0 +1,40 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/compile_xorriso.sh b/xorriso/compile_xorriso.sh index fcac371b..5f34e2ca 100755 --- a/xorriso/compile_xorriso.sh +++ b/xorriso/compile_xorriso.sh @@ -117,9 +117,33 @@ cc -I. -DXorriso_with_maiN $def_libreadline \ \ -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"/debug.o \ diff --git a/xorriso/disk_ops.c b/xorriso/disk_ops.c new file mode 100644 index 00000000..67d77eec --- /dev/null +++ b/xorriso/disk_ops.c @@ -0,0 +1,1838 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains the implementation of actions on onjects of disk + filesystems. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "xorriso.h" +#include "xorriso_private.h" +#include "xorrisoburn.h" + + + +/* @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) +{ + ssize_t l; + struct stat stbuf; + int link_count= 0, ret, show_errno= 0; + char buf[SfileadrL], dirbuf[SfileadrL], *lpt, *spt, sfe[5*SfileadrL]; + static int link_limit= 100; + + if(!(flag&1)) + if(stat(link_path, &stbuf)==-1) + if(errno==ELOOP) { + show_errno= errno; + goto too_many_hops; + } + lpt= link_path; + while(1) { + l= readlink(lpt, buf, SfileadrL-1); + if(l==-1) { +handle_error:; + Xorriso_msgs_submit(xorriso, 0, link_path, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, "Cannot obtain link target of : %s", + Text_shellsafe(link_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); +handle_abort:; + if(strcmp(lpt, link_path)!=0) { + sprintf(xorriso->info_text, + "Problem occured with intermediate path : %s", + Text_shellsafe(lpt, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0); + } + return(0); + } + buf[l]= 0; + if(l==0) { + Xorriso_msgs_submit(xorriso, 0, link_path, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, "Empty link target with : %s", + Text_shellsafe(link_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); + goto handle_abort; + } + + if(flag&1) { + strcpy(result_path, buf); + return(1); + } + + /* normalize relative to disk_path */ + if(Sfile_str(dirbuf, lpt, 0)<=0) + return(-1); + while(1) { + spt= strrchr(dirbuf,'/'); + if(spt!=NULL) { + *spt= 0; + if(*(spt+1)!=0) + break; + } else + break; + } + ret= Xorriso_normalize_img_path(xorriso, dirbuf, buf, result_path, 2|4); + if(ret<=0) + return(ret); + + if(lstat(result_path, &stbuf)==-1) { + lpt= result_path; + goto handle_error; + } + if(!S_ISLNK(stbuf.st_mode)) + break; + + lpt= result_path; + link_count++; + if(link_count>link_limit) { +too_many_hops:; + Xorriso_msgs_submit(xorriso, 0, link_path, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, "Too many link hops with : %s", + Text_shellsafe(link_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, show_errno, + "FAILURE",0); + return(0); + } + } + return(1); +} + + +int Xorriso_convert_uidstring(struct XorrisO *xorriso, char *uid_string, + uid_t *uid, int flag) +{ + double num; + char text[80]; + struct passwd *pwd; + + sscanf(uid_string, "%lf", &num); + sprintf(text,"%.f",num); + if(strcmp(text,uid_string)==0) { + *uid= num; + return(1); + } + pwd= getpwnam(uid_string); + if(pwd==NULL) { + sprintf(xorriso->info_text, "-uid: Not a known user: '%s'", uid_string); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + *uid= pwd->pw_uid; + return(1); +} + + +int Xorriso_convert_gidstring(struct XorrisO *xorriso, char *gid_string, + gid_t *gid, int flag) +{ + double num; + char text[80]; + struct group *grp; + + sscanf(gid_string, "%lf", &num); + sprintf(text,"%.f",num); + if(strcmp(text,gid_string)==0) { + *gid= num; + return(1); + } + grp= getgrnam(gid_string); + if(grp==NULL) { + sprintf(xorriso->info_text, "-gid: Not a known group: '%s'", gid_string); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + *gid= grp->gr_gid; + return(1); +} + + +int Xorriso_convert_modstring(struct XorrisO *xorriso, char *cmd, char *mode, + mode_t *mode_and, mode_t *mode_or, int flag) +{ + int who_val= 0; + char sfe[5*SfileadrL], *mpt, *vpt, *opt; + unsigned int num= 0; + mode_t mode_val,mask; + + *mode_and= ~0; + *mode_or= 0; + if(mode[0]=='0') { + *mode_and= 0; + sscanf(mode,"%o",&num); + *mode_or= num; + } else if(strchr(mode,'+')!=NULL || strchr(mode,'-')!=NULL + || strchr(mode,'=')!=NULL) { + /* [ugoa][+-][rwxst] */; + for(mpt= mode; mpt!=NULL; mpt= strchr(mpt, ',')) { + if(*mpt==',') + mpt++; + if(strlen(mpt)<2) + goto unrecognizable; + who_val= 0; + for(vpt= mpt; *vpt!='+' && *vpt!='-' && *vpt!='='; vpt++) { + if(*vpt=='u') + who_val|= 4; + else if(*vpt=='g') + who_val|= 2; + else if(*vpt=='o') + who_val|= 1; + else if(*vpt=='a') + who_val|= 7; + else + goto unrecognizable; + } + opt= vpt; + mode_val= 0; + for(vpt= opt+1; *vpt!=0 && *vpt!=','; vpt++) { + if(*vpt=='r') { + if(who_val&4) + mode_val|= S_IRUSR; + if(who_val&2) + mode_val|= S_IRGRP; + if(who_val&1) + mode_val|= S_IROTH; + } else if(*vpt=='w') { + if(who_val&4) + mode_val|= S_IWUSR; + if(who_val&2) + mode_val|= S_IWGRP; + if(who_val&1) + mode_val|= S_IWOTH; + } else if(*vpt=='x') { + if(who_val&4) + mode_val|= S_IXUSR; + if(who_val&2) + mode_val|= S_IXGRP; + if(who_val&1) + mode_val|= S_IXOTH; + } else if(*vpt=='s') { + if(who_val&4) + mode_val|= S_ISUID; + if(who_val&2) + mode_val|= S_ISGID; + } else if(*vpt=='t') { + if(who_val&1) + mode_val|= S_ISVTX; + } else + goto unrecognizable; + } + if(*opt=='+') { + (*mode_or)|= mode_val; + } else if(*opt=='=') { + mask= 0; + if(who_val&1) + mask|= S_IRWXO|S_ISVTX; + if(who_val&2) + mask|= S_IRWXG|S_ISGID; + if(who_val&4) + mask|= S_IRWXU|S_ISUID; + (*mode_and)&= ~(mask); + (*mode_or)= ((*mode_or) & ~mask) | mode_val; + } else if(*opt=='-') { + (*mode_or)&= ~mode_val; + (*mode_and)&= ~mode_val; + } + } + } else { +unrecognizable:; + sprintf(xorriso->info_text, + "%s: Unrecognizable or faulty permission mode %s\n", cmd, + Text_shellsafe(mode, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + return(1); +} + + +/* @param flag bit0= for Xorriso_msgs_submit: use pager + bit1= do not issue warnings +*/ +int Xorriso_hop_link(struct XorrisO *xorriso, char *link_path, + struct LinkiteM **link_stack, struct stat *stbuf, int flag) +{ + int ret; + struct LinkiteM *litm; + char sfe[5*SfileadrL]; + + if(*link_stack != NULL) { + if(Linkitem_get_link_count(*link_stack, 0) >= xorriso->follow_link_limit) { + sprintf(xorriso->info_text, + "Too many symbolic links in single tree branch at : %s", + Text_shellsafe(link_path, sfe, 0)); + if(!(flag&2)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,"WARNING",flag&1); + return(0); + } + } + ret= stat(link_path, stbuf); + if(ret==-1) + return(0); + ret= Linkitem_find(*link_stack, stbuf->st_dev, stbuf->st_ino, &litm, 0); + if(ret>0) { + sprintf(xorriso->info_text, + "Detected symbolic link loop around : %s", + Text_shellsafe(link_path, sfe, 0)); + if(!(flag&2)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", flag&1); + return(0); + } + ret= Linkitem_new(&litm, link_path, stbuf->st_dev, stbuf->st_ino, + *link_stack, 0); + if(ret<=0) { + sprintf(xorriso->info_text, + "Cannot add new item to link loop prevention stack"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", flag&1); + return(-1); + } + *link_stack= litm; + return(1); +} + + +/* @param flag bit0= do not only sum up sizes but also print subdirs + bit1= this is a recursion + @return <=0 error , 1 ok , 2 could not open directory +*/ +int Xorriso_show_dux_subs(struct XorrisO *xorriso, + char *abs_path, char *rel_path, off_t *size, + off_t boss_mem, + struct LinkiteM *link_stack, + int flag) +{ + int i, ret, no_sort= 0, filec= 0, l, j, fc, no_dive, is_link; + char **filev= NULL, *namept; + off_t sub_size, report_size, mem= 0; + struct DirseQ *dirseq= NULL; + struct stat stbuf; + dev_t dir_dev; + struct LinkiteM *own_link_stack; + char *path= NULL, *show_path= NULL, *name= NULL, *sfe= NULL; + + sfe= malloc(5*SfileadrL); + path= malloc(SfileadrL); + show_path= malloc(SfileadrL); + name= malloc(SfileadrL); + if(path==NULL || show_path==NULL || name==NULL || sfe==NULL) { + Xorriso_no_malloc_memory(xorriso, &sfe, 0); + {ret= -1; goto ex;} + } + own_link_stack= link_stack; + namept= name; + *size= 0; + + if(lstat(abs_path, &stbuf)==-1) + {ret= 2; goto ex;} + dir_dev= stbuf.st_dev; + if(S_ISLNK(stbuf.st_mode)) { + if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&2)))) + {ret= 2; goto ex;} + if(stat(abs_path, &stbuf)==-1) + {ret= 2; goto ex;} + if(dir_dev != stbuf.st_dev && + !(xorriso->do_follow_mount || (xorriso->do_follow_param && !(flag&2)))) + {ret= 2; goto ex;} + } + ret= Dirseq_new(&dirseq, abs_path, 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) { + Linkitem_reset_stack(&own_link_stack, link_stack, 0); + ret= Dirseq_next_adr(dirseq,name,0); + if(ret<0) + goto ex; + if(ret==0) + break; + + sub_size= 0; + strcpy(show_path, rel_path); + if(Sfile_add_to_path(show_path, name, 0)<=0) + goto much_too_long; + + strcpy(path, abs_path); + if(Sfile_add_to_path(path, name, 0)<=0) { +much_too_long:; + Xorriso_much_too_long(xorriso, strlen(path)+strlen(name)+1, 2); + {ret= -1; goto ex;} + } + no_dive= 0; + + ret= lstat(path, &stbuf); + if(ret==-1) + continue; + is_link= S_ISLNK(stbuf.st_mode); + if(is_link && xorriso->do_follow_links) { + ret= Xorriso_hop_link(xorriso, path, &own_link_stack, &stbuf, 1); + if(ret<0) + {ret= -1; goto ex;} + if(ret!=1) + no_dive= 1; + } + if(!S_ISDIR(stbuf.st_mode)) + no_dive= 1; + if(dir_dev != stbuf.st_dev && !xorriso->do_follow_mount) + no_dive= 1; + if(!no_dive) { + filec++; + l= strlen(rel_path)+1; + mem+= l; + if(l % sizeof(char *)) + mem+= sizeof(char *)-(l % sizeof(char *)); + if(flag&1) /* diving and counting is done further below */ + continue; + ret= Xorriso_show_dux_subs(xorriso, path, show_path, &sub_size, boss_mem, + own_link_stack,2); + if(ret<0) + goto ex; + if(ret==0) + continue; + } + +/* + sub_size+= stbuf.st_size+strlen(name)+1; +*/ + sub_size+= stbuf.st_size+2048; + if(sub_size>0) + (*size)+= sub_size; + } + + if(filec<=0 || !(flag&1)) + {ret= 1; goto ex;} + + /* Try to get a sorted list of directory names */ + mem+= (filec+1)*sizeof(char *); + ret= Xorriso_check_temp_mem_limit(xorriso, mem+boss_mem, 2); + if(ret<0) + goto ex; + Dirseq_rewind(dirseq, 0); + if(ret==0) { +no_sort_possible:; + no_sort= 1; + } else { + filev= (char **) calloc(filec+1, sizeof(char *)); + if(filev==NULL) + goto no_sort_possible; + else { + for(i= 0; ido_follow_links) { + ret= stat(path,&stbuf); + if(ret==-1) + continue; + } + if(!S_ISDIR(stbuf.st_mode)) + continue; + if(dir_dev != stbuf.st_dev && !xorriso->do_follow_mount) + continue; + + if(fc>=filec) { /* Number of files changed (or programming error) */ +revoke_sorting:; + for(j=0; j1) + Sort_argv(filec, filev, 0); + } + } + + for(i= 0; (no_sort || irequest_to_abort); i++) { + Linkitem_reset_stack(&own_link_stack, link_stack, 0); + if(no_sort) { + ret= Dirseq_next_adr(dirseq,name,0); + if(ret<0) + goto ex; + if(ret==0) + break; + } else + namept= filev[i]; + + sub_size= 0; + strcpy(show_path, rel_path); + if(Sfile_add_to_path(show_path, namept, 0)<=0) + goto much_too_long; + strcpy(path, abs_path); + if(Sfile_add_to_path(path, namept, 0)<=0) + goto much_too_long; + no_dive= 0; + + ret= lstat(path,&stbuf); + if(ret==-1) + continue; + is_link= S_ISLNK(stbuf.st_mode); + if(is_link && xorriso->do_follow_links) { + ret= Xorriso_hop_link(xorriso, path, &own_link_stack, &stbuf, 1); + if(ret<0) + {ret= -1; goto ex;} + if(ret!=1) + continue; + } + if(!S_ISDIR(stbuf.st_mode)) + continue; + if(dir_dev == stbuf.st_dev || xorriso->do_follow_mount) { + ret= Xorriso_show_dux_subs(xorriso, path, show_path, &sub_size, + boss_mem+mem, own_link_stack, 2|(flag&1)); + if(ret<0) + goto ex; + } + +/* + sub_size+= stbuf.st_size+strlen(namept)+1; +*/ + sub_size+= stbuf.st_size+2048; + if(sub_size>0) + (*size)+= sub_size; + report_size= sub_size/1024; + if(report_size*1024result_line, "%7.f ",(double) (report_size)); + sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n", + Text_shellsafe(show_path, sfe, 0)); + Xorriso_result(xorriso, 0); + } + + ret= 1; +ex:; + if(sfe!=NULL) + free(sfe); + if(path!=NULL) + free(path); + if(show_path!=NULL) + free(show_path); + if(name!=NULL) + free(name); + Linkitem_reset_stack(&own_link_stack, link_stack, 0); + Dirseq_destroy(&dirseq, 0); + if(filev!=NULL) { + for(i=0; iresult_line; + rpt[0]= 0; + st_mode= stbuf->st_mode; + + if(S_ISDIR(st_mode)) + strcat(rpt, "d"); + else if(S_ISREG(st_mode)) + strcat(rpt, "-"); + else if(S_ISLNK(st_mode)) + strcat(rpt, "l"); + else if(S_ISBLK(st_mode)) { + strcat(rpt, "b"); + show_major_minor= 1; + } else if(S_ISCHR(st_mode)) { + strcat(rpt, "c"); + show_major_minor= 1; + } else if(S_ISFIFO(st_mode)) + strcat(rpt, "p"); + else if(S_ISSOCK(st_mode)) + strcat(rpt, "s"); + else if((flag & 1) && (st_mode & S_IFMT) == Xorriso_IFBOOT) + strcat(rpt, "e"); + else + strcat(rpt, "?"); + + Xorriso__mode_to_perms(st_mode, perms, flag & 2); + strcat(rpt, perms); + + sprintf(rpt+strlen(rpt)," %3u ",(unsigned int) stbuf->st_nlink); + + sprintf(rpt+strlen(rpt), "%-8lu ", (unsigned long) stbuf->st_uid); + sprintf(rpt+strlen(rpt), "%-8lu ", (unsigned long) stbuf->st_gid); + if(show_major_minor) { + dev= stbuf->st_rdev; + + /* according to /usr/include/sys/sysmacros.h : gnu_dev_major(),_minor() + >>> but this looks as if it should go to some system dependency + >>> in FreeBSD dev_t is 32 bit + */ + if(sizeof(dev_t) > 4) { + high_shift= 32; + high_mask= ~0xfff; + } + major= (((dev >> 8) & 0xfff) | + ((unsigned int) (dev >> high_shift) & high_mask)) + & 0xffffffff; + minor= (((dev & 0xff) | ((unsigned int) (dev >> 12) & ~0xff))) & 0xffffffff; + + sprintf(mm_text, "%u,%u", (unsigned int) major, (unsigned int) minor); + sprintf(rpt+strlen(rpt), "%8s ", mm_text); + } else + sprintf(rpt+strlen(rpt), "%8.f ", (double) stbuf->st_size); + + Ftimetxt(stbuf->st_mtime, rpt+strlen(rpt), 0); + strcat(rpt, " "); + + return(1); +} + + +struct DirentrY { + char *adr; + struct DirentrY *next; +}; + + +int Xorriso_sorted_dir_x(struct XorrisO *xorriso, char *dir_path, + int *filec, char ***filev, off_t boss_mem, int flag) +{ + int count= 0, ret; + char name[SfileadrL]; + struct DirseQ *dirseq= NULL; + off_t mem; + struct DirentrY *last= NULL, *current= NULL; + + *filec= 0; + *filev= NULL; + mem= boss_mem; + ret= Dirseq_new(&dirseq, dir_path, 1); + if(ret<=0) + goto ex; + while(1) { /* loop over directory content */ + ret= Dirseq_next_adr(dirseq,name,0); + if(ret==0) + break; + if(ret<0) + goto ex; + mem+= strlen(name)+8+sizeof(struct DirentrY)+sizeof(char *); + if(mem>xorriso->temp_mem_limit) + {ret= 0; goto ex;} + + current= (struct DirentrY *) calloc(1, sizeof(struct DirentrY)); + if(current==NULL) + {ret= -1; goto ex;} + current->adr= NULL; + current->next= last; + last= current; + last->adr= strdup(name); + if(last->adr==NULL) + {ret= -1; goto ex;} + count++; + } + *filec= count; + if(count==0) + {ret= 1; goto ex;} + (*filev)= (char **) calloc(count, sizeof(char *)); + if(*filev==NULL) + {ret= -1; goto ex; } + count= 0; + for(current= last; current!=NULL; current= last) { + last= current->next; + (*filev)[count++]= current->adr; + free((char *) current); + } + Sort_argv(*filec, *filev, 0); + ret= 1; +ex:; + for(current= last; current!=NULL; current= last) { + last= current->next; + free(current->adr); + free((char *) current); + } + return(ret); +} + + +/* @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) +{ + int i, ret, was_error= 0, dfilec= 0, pass, passes; + char sfe[5*SfileadrL], sfe2[5*SfileadrL], path[SfileadrL], *acl_text= NULL; + char *rpt, link_target[SfileadrL], **dfilev= NULL; + off_t size; + struct stat stbuf; + + rpt= xorriso->result_line; + + Sort_argv(filec, filev, 0); + + /* Count valid nodes, warn of invalid ones */ + for(i= 0; iinfo_text, "Not found in local filesystem: %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 1); + was_error++; + continue; + } + } + + if((flag&8) && !(flag&(2|4))) { + sprintf(xorriso->info_text,"Valid local files found: %d\n",filec-was_error); + Xorriso_info(xorriso,1); + if(filec-was_error<=0) + return(!was_error); + } + + passes= 1+!(flag&(4|8)); + for(pass= 0; passrequest_to_abort); i++) { + ret= Xorriso_make_abs_adr(xorriso, wd, filev[i], path, 1|2|4); + if(ret<=0) + continue; + ret= lstat(path, &stbuf); + if(ret==-1) + continue; + if(S_ISLNK(stbuf.st_mode) && + (xorriso->do_follow_links || xorriso->do_follow_param)) { + ret= stat(path, &stbuf); + if(ret==-1) + ret= lstat(path, &stbuf); + if(ret==-1) + continue; + } + if(S_ISDIR(stbuf.st_mode) && !(flag&(4|8))) { + if(pass==0) + continue; + if(filec>1) { + strcpy(xorriso->result_line, "\n"); + Xorriso_result(xorriso,0); + sprintf(xorriso->result_line, "%s:\n", Text_shellsafe(filev[i], sfe,0)); + Xorriso_result(xorriso,0); + } + ret= Xorriso_sorted_dir_x(xorriso, path, &dfilec, &dfilev, boss_mem, 0); + if(ret<=0) { + + /* >>> DirseQ loop and single item Xorriso_lsx_filev() */; + + } else { + if(flag&1) { + sprintf(xorriso->result_line, "total %d\n", dfilec); + Xorriso_result(xorriso,0); + } + Xorriso_lsx_filev(xorriso, path, + dfilec, dfilev, boss_mem, (flag&1)|2|8); + } + if(dfilec>0) + Sfile_destroy_argv(&dfilec, &dfilev, 0); + continue; + } else + if(pass>0) + continue; + link_target[0]= 0; + rpt[0]= 0; + if((flag&5)==1) { + Xorriso_local_getfacl(xorriso, path, &acl_text, 16); + ret= Xorriso_format_ls_l(xorriso, &stbuf, (acl_text != NULL) << 1); + Xorriso_local_getfacl(xorriso, path, &acl_text, 1 << 15); + if(ret<=0) + continue; + if(S_ISLNK(stbuf.st_mode)) { + ret= Xorriso_resolve_link(xorriso, path, link_target, 1); + if(ret<=0) + link_target[0]= 0; + } + } else if(flag&4) { /* -du or -dus */ + size= stbuf.st_size; + if(S_ISDIR(stbuf.st_mode)) { + ret= Xorriso_show_dux_subs(xorriso, path, filev[i], &size, boss_mem, + NULL, flag&1); + if(ret<0) + return(-1); + if(ret==0) + continue; + } + sprintf(rpt, "%7.f ",(double) (size/1024)); + } + if(link_target[0]) + sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s -> %s\n", + Text_shellsafe(filev[i], sfe, 0), + Text_shellsafe(link_target, sfe2, 0)); + else + sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n", + Text_shellsafe(filev[i], sfe, 0)); + Xorriso_result(xorriso, 0); + } + return(!was_error); +} + + +/* + @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 + bit6= permission to call Xorriso_make_accessible() + @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 ret, is_dir= 0, made_accessible= 0; + struct stat victim_stbuf, *victim_node= NULL; + struct DirseQ *dirseq= NULL; + char *sfe= NULL, *sub_path= NULL; + struct PermiteM *perm_stack_mem; + + perm_stack_mem= xorriso->perm_stack; + + /* Avoiding large local memory objects in order to save stack space */ + sfe= malloc(5*SfileadrL); + sub_path= malloc(2*SfileadrL); + if(sfe==NULL || sub_path==NULL) { + Xorriso_no_malloc_memory(xorriso, &sfe, 0); + {ret= -1; goto ex;} + } + + if(Xorriso_much_too_long(xorriso, strlen(path), 0)<=0) + {ret= 0; goto ex;} + + ret= lstat(path, &victim_stbuf); + if(ret==-1) { + if((flag & 64) && errno == EACCES) { + ret= Xorriso_make_accessible(xorriso, path, 0); + if(ret < 0) + goto ex; + made_accessible= 1; + ret= lstat(path, &victim_stbuf); + } + if(ret==-1) { + sprintf(xorriso->info_text, "Cannot lstat(%s)", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + {ret= 0; goto ex;} + } + } + if(strcmp(path, "/")==0) { + sprintf(xorriso->info_text, "May not delete root directory"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + victim_node= &victim_stbuf; + if(S_ISDIR(victim_stbuf.st_mode)) + is_dir= 1; + if(!is_dir) { + if(flag&2) { /* rmdir */ + sprintf(xorriso->info_text, "%s in disk filesystem is not a directory", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + } else { + if(flag&1) { /* rm -r */ + +#ifdef Osirrox_not_yeT + /* >>> */ + + if((xorriso->do_reassure==1 && !xorriso->request_not_to_ask) || + (flag&32)) { + /* Iterate over subordinates and delete them */ + mem= boss_mem; + + ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, + &iter, &node_array, &node_count, &node_idx, + &node, 1|2); + if(ret<=0) { +cannot_create_iter:; + Xorriso_cannot_create_iter(xorriso, ret, 0); + ret= -1; goto ex; + } + pl= strlen(path); + strcpy(sub_path, path); + if(pl==0 || sub_path[pl-1]!='/') { + sub_path[pl++]= '/'; + sub_path[pl]= 0; + } + sub_name= sub_path+pl; + while(1) { + ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, &iter, + &node_array, &node_count, &node_idx, &node, 0); + if(ret<0) + goto ex; + if(ret==0 || xorriso->request_to_abort) + break; + name= (char *) iso_node_get_name(node); + if(Xorriso_much_too_long(xorriso, pl+1+strlen(name), 0)<=0) + {ret= 0; goto rm_r_problem_handler;} + strcpy(sub_name, name); + ret= Xorriso_rmi(xorriso, iter, mem, sub_path, (flag&(1|2|8|16))|4); + if(ret==3 || ret<=0 || xorriso->request_to_abort) { +rm_r_problem_handler:; + not_removed= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret<0) + goto dir_not_removed; + } + } + if(flag&32) + {ret= 2; goto ex;} + + if(not_removed) { +dir_not_removed:; + sprintf(xorriso->info_text, "Directory not removed: %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + if(ret>0) + ret= 3; + goto ex; + } + } + +#else /* Osirrox_not_yeT */ + + sprintf(xorriso->info_text, "-rm_rx is not implemented yet"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + +#endif /* !Osirrox_not_yeT */ + + } else { + if(!(flag&2)) { /* not rmdir */ + sprintf(xorriso->info_text, "%s in disk filesystem is a directory", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + ret= Dirseq_new(&dirseq, path, 1); + if(ret>0) { + ret= Dirseq_next_adr(dirseq, sfe, 0); + if(ret>0) { + sprintf(xorriso->info_text, + "Directory not empty on attempt to delete: %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + } + } + } + if(xorriso->request_to_abort) + {ret= 3; goto ex;} + ret= Xorriso_reassure_restore(xorriso, path, (flag&(4|8)) | !!is_dir); + if(ret<=0 || ret==3) + goto ex; + if(is_dir) + ret= rmdir(path); + else + ret= unlink(path); + if(ret == -1) { + if((flag & 64) && errno == EACCES && !made_accessible) { + ret= Xorriso_make_accessible(xorriso, path, 0); + if(ret < 0) + goto ex; + made_accessible= 1; + if(is_dir) + ret= rmdir(path); + else + ret= unlink(path); + } + if(ret == -1) { + sprintf(xorriso->info_text, "Cannot delete from disk filesystem %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + ret= -1; goto ex; + } + } + if(flag&16) + xorriso->pacifier_count++; + ret= 1+!!is_dir; +ex:; + if(made_accessible) + Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0); + if(sfe!=NULL) + free(sfe); + if(sub_path!=NULL) + free(sub_path); + Dirseq_destroy(&dirseq, 0); + return(ret); +} + + +/* @param flag bit0= recursion +*/ +int Xorriso_findx_action(struct XorrisO *xorriso, struct FindjoB *job, + char *abs_path, char *show_path, int depth, int flag) +{ + int ret= 0, type, action= 0, dpl= 0, compare_result, uret; + uid_t user= 0; + gid_t group= 0; + time_t date= 0; + mode_t mode_or= 0, mode_and= ~1; + char *target, *text_2, sfe[5*SfileadrL], *disk_prefix, iso_path[SfileadrL]; + struct FindjoB *subjob; + struct stat stbuf; + + action= Findjob_get_action_parms(job, &target, &text_2, &user, &group, + &mode_and, &mode_or, &type, &date, &subjob, 0); + if(action<0) + action= 0; + if(action<0) + action= 0; + if(action==15 || action==16 || action==18 || action==19 || action==20) { + /* in_iso , not_in_iso, add_missing , empty_iso_dir , is_full_in_iso */ + Findjob_get_start_path(job, &disk_prefix, 0); + if(strncmp(abs_path, disk_prefix, strlen(disk_prefix))!=0) + {ret= -1; goto ex;} + dpl= strlen(disk_prefix); + if(strlen(target)+strlen(abs_path)-dpl >= SfileadrL) + {ret= -1; goto ex;} + if(abs_path[dpl]=='/') + dpl++; + ret= Xorriso_make_abs_adr(xorriso, target, abs_path+dpl, iso_path, 4); + if(ret<=0) + {goto ex;} + + } + if(action==15) { /* in_iso */ + ret= Xorriso_iso_lstat(xorriso, iso_path, &stbuf, 0); + if(ret<0) + {ret= 1; goto ex;} + sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0)); + Xorriso_result(xorriso, 0); + ret= 1; + } else if(action==16) { /* not_in_iso */ + ret= Xorriso_compare_2_files(xorriso, abs_path, iso_path, abs_path+dpl, + &compare_result, 4); + if(retfind_compare_result) + xorriso->find_compare_result= ret; + if(ret>=0) + ret= 1; + } else if(action==18) { /* add_missing */ + ret= Xorriso_compare_2_files(xorriso, abs_path, iso_path, abs_path+dpl, + &compare_result, 4|(1<<31)); + if(retfind_compare_result) + xorriso->find_compare_result= ret; + if(ret==0) { + uret= Xorriso_update_interpreter(xorriso, NULL, compare_result, + abs_path, iso_path, (flag&1)<<2); + if(uret<=0) + ret= 0; + } + if(ret>=0) + ret= 1; + } else if(action==19) { /* empty_iso_dir */ + ret= Xorriso_iso_lstat(xorriso, iso_path, &stbuf, 0); + if(ret<0) + {ret= 1; goto ex;} + if(!S_ISDIR(stbuf.st_mode)) + {ret= 1; goto ex;} + ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, iso_path, 1|32); + if(ret>0) { + sprintf(xorriso->info_text, "Emptied directory %s", + Text_shellsafe(iso_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0); + } + } else if(action==20) { /* is_full_in_iso */ + ret= Xorriso_iso_lstat(xorriso, iso_path, &stbuf, 0); + if(ret<0) + {ret= 1; goto ex;} + if(!S_ISDIR(stbuf.st_mode)) + {ret= 1; goto ex;} + strcpy(sfe, xorriso->wdi); + strcpy(xorriso->wdi, iso_path); + ret= Xorriso_ls(xorriso, 4|8); + strcpy(xorriso->wdi, sfe); + if(ret>0) { + sprintf(xorriso->result_line, + "d %s (ISO) : non-empty directory (would not match mount point)\n", + Text_shellsafe(iso_path, sfe, 0)); + Xorriso_result(xorriso,0); + } + {ret= 1; goto ex;} + } else { + sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0)); + Xorriso_result(xorriso, 0); + ret= 1; + } +ex:; + if(action==15 || action==16 || action==18 || action==19 || action==20) + if(xorriso->no_volset_present) + xorriso->request_to_abort= 1; /* Need an image. No use to try again. */ + return(ret); +} + + +/* @param flag bit0=recursion +*/ +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) +{ + int ret,is_link, no_dive; + struct DirseQ *dirseq= NULL; + struct stat stbuf; + struct LinkiteM *own_link_stack; + char *abs_dir_path, *namept; + char *name= NULL, *path= NULL, *sfe= NULL; + char *abs_dir_path_data= NULL, *abs_path= NULL; + + if(xorriso->request_to_abort) + {ret= 0; goto ex;} + + sfe= malloc(5*SfileadrL); + name= malloc(SfileadrL); + path= malloc(SfileadrL); + abs_dir_path_data= malloc(SfileadrL); + abs_path= malloc(SfileadrL); + if(name==NULL || sfe==NULL || path==NULL || + abs_dir_path_data==NULL || abs_path==NULL) { + Xorriso_no_malloc_memory(xorriso, &sfe, 0); + {ret= -1; goto ex;} + } + own_link_stack= link_stack; + abs_dir_path= abs_dir_parm; + if(abs_dir_path[0]==0) { + ret= Xorriso_make_abs_adr(xorriso, xorriso->wdx, dir_path, + abs_dir_path_data, 1|2|8); + if(ret<=0) + goto ex; + abs_dir_path= abs_dir_path_data; + ret= Xorriso_path_is_excluded(xorriso, abs_dir_path, !(flag&1)); + if(ret<0) + goto ex; + if(ret>0) + {ret= 0; goto ex;} + ret= lstat(abs_dir_path, dir_stbuf); + if(ret==-1) + {ret= 0; goto ex;} + if(S_ISLNK(dir_stbuf->st_mode) && + (xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1)))) + if(stat(abs_dir_path, &stbuf)!=-1) + if(dir_stbuf->st_dev == stbuf.st_dev || + (xorriso->do_follow_mount || (xorriso->do_follow_param && !(flag&1)))) + memcpy(dir_stbuf, &stbuf, sizeof(struct stat)); + + namept= strrchr(dir_path, '/'); + if(namept==NULL) + namept= dir_path; + else + namept++; + + ret= Findjob_test_2(xorriso, job, NULL, namept, dir_path, NULL, dir_stbuf, + 0); + if(ret<0) + goto ex; + if(ret>0) { + ret= Xorriso_findx_action(xorriso, job, abs_dir_path, dir_path, depth, + flag&1); + if(xorriso->request_to_abort) + {ret= 0; goto ex;} + if(ret<=0) { + if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0) + goto ex; + } + } + } + if(xorriso->request_to_abort) + {ret= 1; goto ex;} + if(!S_ISDIR(dir_stbuf->st_mode)) + {ret= 2; goto ex;} + + ret= Dirseq_new(&dirseq, abs_dir_path, 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(!xorriso->request_to_abort) { + Linkitem_reset_stack(&own_link_stack, link_stack, 0); + 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, abs_dir_path, name, abs_path, 1); + if(ret<=0) + goto ex; + ret= Xorriso_make_abs_adr(xorriso, dir_path, name, path, 4); + if(ret<=0) + goto ex; + ret= Xorriso_path_is_excluded(xorriso, abs_path, 0); /* (is never param) */ + if(ret<0) + goto ex; + if(ret>0) + continue; + ret= lstat(abs_path, &stbuf); + if(ret==-1) + continue; + no_dive= 0; + + is_link= S_ISLNK(stbuf.st_mode); + if(is_link && xorriso->do_follow_links) { + ret= Xorriso_hop_link(xorriso, abs_path, &own_link_stack, &stbuf, 2); + if(ret<0) + {ret= -1; goto ex;} + if(ret!=1) + no_dive= 1; + } + + ret= Findjob_test_2(xorriso, job, NULL, name, path, dir_stbuf, &stbuf, 0); + if(ret<0) + goto ex; + if(ret>0) { + ret= Xorriso_findx_action(xorriso, job, abs_path, path, depth, flag&1); + if(xorriso->request_to_abort) + {ret= 0; goto ex;} + if(ret<=0) { + if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0) + goto ex; + } + } + if(!S_ISDIR(stbuf.st_mode)) + no_dive= 1; + if(dir_stbuf->st_dev != stbuf.st_dev && !xorriso->do_follow_mount) + no_dive= 1; + if(!no_dive) { + ret= Xorriso_findx(xorriso, job, abs_path, path, &stbuf, depth+1, + own_link_stack, flag|1); + if(ret<0) + goto ex; + } + } + + ret= 1; +ex:; + if(sfe!=NULL) + free(sfe); + if(name!=NULL) + free(name); + if(path!=NULL) + free(path); + if(abs_dir_path_data!=NULL) + free(abs_dir_path_data); + if(abs_path!=NULL) + free(abs_path); + Dirseq_destroy(&dirseq, 0); + return(ret); +} + + +/* @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) +{ + int i, ret, with_node_array= 0, hflag= 0, hret; + + if(!(((xorriso->ino_behavior & 16) && xorriso->do_restore_sort_lba) || + (xorriso->ino_behavior & 4) || (flag & 1))) { + ret= Xorriso_make_hln_array(xorriso, 0); + if(ret<=0) + goto ex; + } + if(xorriso->do_restore_sort_lba) { + /* Count affected nodes */ + Xorriso_destroy_node_array(xorriso, 0); + for(i= 0; i < count; i++) { + if(src_array[i] == NULL || tgt_array[i] == NULL) + continue; + /* sort_lba : Make directories plus node_array and then + run array extractor (with eventual hardlink detection) + */ + hflag= (1 << 7) | ((!!(flag & 2)) << 9); + ret= Xorriso_restore(xorriso, src_array[i], tgt_array[i], + (off_t) 0, (off_t) 0, hflag); + if(ret <= 0) { + hret= Xorriso_eval_problem_status(xorriso, ret, 0); + if(ret < 0) + goto ex; + } + with_node_array= 1; + } + } + + if(with_node_array) { + /* Allocate and fill node array */ + if(xorriso->node_counter <= 0) + {ret= 2; goto ex;} + ret= Xorriso_new_node_array(xorriso, xorriso->temp_mem_limit, 0, + !xorriso->do_restore_sort_lba); + if(ret<=0) + goto ex; + for(i= 0; i < count; i++) { + if(src_array[i] == NULL || tgt_array[i] == NULL) + continue; + ret= Xorriso_restore(xorriso, src_array[i], tgt_array[i], + (off_t) 0, (off_t) 0, 2 << 7); + if(ret <= 0) { + hret= Xorriso_eval_problem_status(xorriso, ret, 0); + if(ret < 0) + goto ex; + } + } + } + + /* Perform restore operations */ + if(xorriso->do_restore_sort_lba) { + ret= Xorriso_restore_node_array(xorriso, 0); + if(ret <= 0) + goto ex; + } else { + for(i= 0; i < count; i++) { + if(src_array[i] == NULL || tgt_array[i] == NULL) + continue; + ret= Xorriso_restore(xorriso, src_array[i], tgt_array[i], + (off_t) 0, (off_t) 0, 0); + if(ret <= 0) { + hret= Xorriso_eval_problem_status(xorriso, ret, flag & 32); + if(ret < 0) + goto ex; + } + } + } + + ret= 1; +ex:; + return(ret); +} + + +/* @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) +{ + int ret; + char sfe[5*SfileadrL]; + + while((xorriso->do_reassure==1 || (xorriso->do_reassure==2 && !(flag&4))) + && !xorriso->request_not_to_ask) { + /* ls -ld */ + Xorriso_lsx_filev(xorriso, xorriso->wdx, 1, &path, (off_t) 0, 1|2|8); + if(flag&1) /* du -s */ + Xorriso_lsx_filev(xorriso, xorriso->wdx, 1, &path, (off_t) 0, 2|4); + if(flag&8) + sprintf(xorriso->info_text, + "File exists. Remove ? n= keep old, y= remove, x= abort, @= stop asking\n"); + else + sprintf(xorriso->info_text, + "Remove above file ? n= keep it, y= remove it, x= abort, @= stop asking\n"); + Xorriso_info(xorriso, 4); + ret= Xorriso_request_confirmation(xorriso, 1|2|4|16); + if(ret<=0) + goto ex; + if(xorriso->request_to_abort) { + sprintf(xorriso->info_text, + "Removal operation aborted by user before file: %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + ret= 3; goto ex; + } + if(ret==3) + continue; + if(ret==6) /* yes */ + break; + if(ret==4) { /* yes, do not ask again */ + xorriso->request_not_to_ask= 1; + break; + } + if(ret==1) { /* no */ + sprintf(xorriso->info_text, "Kept in existing state: %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + ret= 3; goto ex; + } + } + ret= 1; +ex: + return(ret); +} + + +/* @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) +{ + char *cpt; + + cpt= strrchr(orig_path, '/'); + if(cpt==NULL) + tmp_path[0]= 0; + else { + strncpy(tmp_path, orig_path, cpt+1-orig_path); + tmp_path[cpt+1-orig_path]= 0; + } + strcat(tmp_path, "_tmp_xorriso_restore_XXXXXX"); + *fd= mkstemp(tmp_path); + if(*fd==-1) { + if(errno == EACCES && (flag & 128)) + return(4); + strcpy(xorriso->info_text, "Cannot create temporary file : "); + Text_shellsafe(tmp_path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + return(0); + } + fchmod(*fd, S_IRUSR|S_IWUSR); + return(1); +} + + +/* @param flag bit0= change regardless of xorriso->do_auto_chmod + bit1= desired is only rx + @return -1=severe error , -2= cannot chmod, 0= nothing to do, 1 = chmoded +*/ +int Xorriso_auto_chmod(struct XorrisO *xorriso, char *disk_path, int flag) +{ + int ret, is_link= 0; + char *path_pt, sfe[5*SfileadrL], link_target[SfileadrL]; + mode_t mode, desired= S_IRUSR | S_IWUSR | S_IXUSR; + struct stat stbuf; + + if(!(xorriso->do_auto_chmod || (flag & 1))) + return(0); + + if(flag & 2) + desired &= ~S_IWUSR; + path_pt= disk_path; + ret= lstat(path_pt, &stbuf); + if(ret==-1) + return(0); + if(S_ISLNK(stbuf.st_mode)) { + is_link= 1; + ret= stat(path_pt, &stbuf); + if(ret==-1) + return(0); + } + if(!S_ISDIR(stbuf.st_mode)) + return(0); + if(is_link) { + ret= Xorriso_resolve_link(xorriso, path_pt, link_target, 0); + if(ret<=0) + return(ret); + path_pt= link_target; + } + if((stbuf.st_mode & desired) == desired) + return(0); + if(stbuf.st_uid!=geteuid()) + return(-2); + + mode= (stbuf.st_mode | desired) & 07777; + ret= chmod(path_pt, mode); + if(ret==-1) { + sprintf(xorriso->info_text, + "Cannot change access permissions of disk directory: chmod %o %s", + (unsigned int) (mode & 07777), Text_shellsafe(path_pt, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "SORRY", 0); + return(-2); + } + ret= Permstack_push(&(xorriso->perm_stack), path_pt, &stbuf, 0); + if(ret<=0) + return(ret); + return(1); +} + + +int Xorriso_make_accessible(struct XorrisO *xorriso, char *disk_path, int flag) +{ + int done= 0, ret, just_rx= 2; + char *npt, *apt, path[SfileadrL], *wpt; + + apt= disk_path; + wpt= path; + for(npt= apt; !done; apt= npt + 1) { + npt= strchr(apt, '/'); + if(npt == NULL) + break; + if(strchr(npt + 1, '/') == NULL) + just_rx= 0; + strncpy(wpt, apt, npt + 1 - apt); + wpt+= npt + 1 - apt; + *wpt= 0; + ret= Xorriso_auto_chmod(xorriso, path, just_rx); + if(ret == -1) + return(-1); + if(ret == -2) + return(0); + } + return(1); +} + + +/* @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 li; + struct Xorriso_lsT *s, *d, *found_s= NULL, *found_d= NULL; + char *ipfx, *dpfx; + + /* Obtain disk_path by replacing start piece of img_path */ + + d= *disk_prefixes; + for(s= *img_prefixes; s != NULL; + s= Xorriso_lst_get_next(s, 0), d= Xorriso_lst_get_next(d, 0)) { + + ipfx= Xorriso_lst_get_text(s, 0); + li= strlen(ipfx); + dpfx= Xorriso_lst_get_text(d, 0); + if(strncmp(img_path, ipfx, li) != 0) + continue; + if(img_path[li] != 0 && img_path[li] != '/') + continue; + if(strlen(dpfx) + strlen(img_path) - li + 1 >= SfileadrL) + return(-1); + if(img_path[li]=='/') + sprintf(disk_path, "%s/%s", dpfx, img_path + strlen(ipfx) + 1); + else + strcpy(disk_path, dpfx); + found_s= s; + found_d= d; + if(s != *img_prefixes || !(flag & 1)) + break; + } + *img_prefixes= found_s; + *disk_prefixes= found_d; + return(found_s != NULL); +} + + +/* @param flag bit0=permission to run Xorriso_make_accessible +*/ +int Xorriso_restore_make_hl(struct XorrisO *xorriso, + char *old_path, char *new_path, int flag) +{ + int ret; + struct PermiteM *perm_stack_mem; + + ret= link(old_path, new_path); + if(ret == 0) + return(1); + if(errno == EACCES && (flag & 1)) { + perm_stack_mem= xorriso->perm_stack; + ret= Xorriso_make_accessible(xorriso, new_path, 0); + if(ret > 0) { + ret= link(old_path, new_path); + if(ret == 0) { + Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0); + return(1); + } + } + Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0); + } + + sprintf(xorriso->info_text, "Hardlinking failed: "); + Text_shellsafe(new_path, xorriso->info_text, 1); + strcat(xorriso->info_text, " -> "); + Text_shellsafe(old_path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "WARNING", 0); + return(0); +} + + +int Xorriso_afile_fopen(struct XorrisO *xorriso, + char *filename, char *mode, FILE **ret_fp, int flag) +/* + bit0= do not print error message on failure + bit1= do not open stdin +*/ +{ + FILE *fp= NULL; + + *ret_fp= NULL; + if(strcmp(filename,"-")==0) { + if(mode[0]=='a' || mode[0]=='w' || + (mode[0]=='r' && mode[1]=='+') || + (mode[0]=='r' && mode[1]=='b' && mode[2]=='+')) + fp= stdout; + else if(flag & 2) { + Xorriso_msgs_submit(xorriso, 0, "Not allowed as input path: '-'", 0, + "FAILURE", 0); + return(0); + } else { + Xorriso_msgs_submit(xorriso, 0, "Ready for data at standard input", 0, + "NOTE", 0); + fp= stdin; + } + } else if(strncmp(filename,"tcp:",4)==0){ + Xorriso_msgs_submit(xorriso, 0, "TCP/IP service isn't implemented yet.", 0, + "FAILURE", 0); + } else if(strncmp(filename,"file:",5)==0){ + fp= fopen(filename+5,mode); + } else { + fp= fopen(filename,mode); + } + if(fp==NULL){ + if(!(flag&1)) { + sprintf(xorriso->info_text, + "Failed to open file '%s' in %s mode\n", filename, mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + } + return(0); + } + *ret_fp= fp; + return(1); +} + + +/* + @param flag bit0= make absolute command paths with known systems + bit1= do not allow prefixes with cmd + bit2= interpret unprefixed cmd as shell: +*/ +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 ret, reg_file= 0, is_safe= 0, sys_code= 0; + char form[6*SfileadrL], session_text[12], track_text[12], lba_text[12]; + char *vars[5][2], sfe[5*SfileadrL], volid_sfe[5*80+1], *cpt, *sysname; + struct stat stbuf; + + if(strlen(cmd) > SfileadrL) { +/* +too_long:; +*/ + Xorriso_msgs_submit(xorriso, 0, "Argument much too long", 0, "FAILURE", 0); + return(0); + } + ret= stat(devadr, &stbuf); + if(ret != -1) + if(S_ISREG(stbuf.st_mode)) + reg_file= 1; + if(strncmp(cmd, "linux:", 6) == 0 && !(flag & 2)) { + cpt= cmd + 6; + sys_code= 1; + } else if(strncmp(cmd, "freebsd:", 8) == 0 && !(flag & 2)) { + cpt= cmd + 8; + sys_code= 2; + } else if(strncmp(cmd, "string:", 7) == 0 && !(flag & 2)) { + cpt= cmd + 7; + strcpy(form, cpt); + } else if(flag & 4) { + cpt= cmd; + strcpy(form, cpt); + } else { + cpt= cmd; + ret= System_uname(&sysname, NULL, NULL, NULL, 0); + if(ret <= 0) { + Xorriso_msgs_submit(xorriso, 0, + "-mount*: Cannot determine current system type", + 0, "FAILURE", 0); + return(0); + } else if(strcmp(sysname, "FreeBSD") == 0 || + strcmp(sysname, "GNU/kFreeBSD") == 0) { + /* "GNU/kFreeBSD" = Debian kfreebsd */ + sys_code= 2; + } else if(strcmp(sysname, "Linux") == 0) { + sys_code= 1; + } else { + sprintf(xorriso->info_text, "-mount*: Unsupported system type %s", + Text_shellsafe(sysname, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + + if(sys_code == 1) { /* GNU/Linux */ + sprintf(form, + "%smount -t iso9660 -o %snodev,noexec,nosuid,ro,sbsector=%%sbsector%% %%device%% %s", + (flag & 1 ? "/bin/" : ""), + (reg_file || (xorriso->mount_opts_flag & 1) ? "loop," : ""), + Text_shellsafe(cpt, sfe, 0)); + is_safe= 1; + } else if(sys_code == 2) { /* FreeBSD */ + if(reg_file) { + +/* <<< Considered to create vnode as of + J.R. Oldroyd , 20 Nov 2008 + but for now refraining from creating that persistent file object + + strcpy(form, "n=$(mdconfig -a -t vnode -f %device%)"); + sprintf(form + strlen(form), + " && mount -t cd9660 -o noexec,nosuid -s %%sbsector%% /dev/\"$n\" %s", + Text_shellsafe(cmd+8, sfe, 0)); +*/ + + Xorriso_msgs_submit(xorriso, 0, + "Detected regular file as mount device with FreeBSD style command.", + 0, "FAILURE", 0); + Xorriso_msgs_submit(xorriso, 0, +"Command mdconfig -a -t vnode -f can create a device node which uses the file", + 0, "HINT", 0); + return(0); + } else { + sprintf(form, + "%smount_cd9660 -o noexec,nosuid -s %%sbsector%% %%device%% %s", + (flag & 1 ? "/sbin/" : ""), Text_shellsafe(cmd+8, sfe, 0)); + /* + Not working on FreeBSD 7.2 according to Zsolt Kuti, 11 Oct 2009: + "%smount -t cd9660 -o noexec,nosuid -o -s %%sbsector%% %%device%% %s", + */ + } + is_safe= 1; + } + sprintf(session_text, "%d", session); + sprintf(track_text, "%d", track); + sprintf(lba_text, "%d", lba); + vars[0][0]= "sbsector"; + vars[0][1]= lba_text; + vars[1][0]= "track"; + vars[1][1]= track_text; + vars[2][0]= "session"; + vars[2][1]= session_text; + vars[3][0]= "volid"; + vars[3][1]= Text_shellsafe(volid, volid_sfe, 0); + vars[4][0]= "device"; + vars[4][1]= Text_shellsafe(devadr, sfe, 0); + ret= Sregex_resolve_var(form, vars, 5, "%", "%", "%", result, SfileadrL, 0); + if(ret <= 0) + return(ret); + return(1 + is_safe); +} + + +int Xorriso_append_scdbackup_record(struct XorrisO *xorriso, int flag) +{ + FILE *fp= NULL; + char dummy[81], name[81], timestamp[81], size[81], md5[81]; + + if(xorriso->scdbackup_tag_written[0] == 0) + return(1); + + name[0]= timestamp[0]= size[0]= md5[0]= 0; + sscanf(xorriso->scdbackup_tag_written, "%s %s %s %s %s %s %s", + dummy, dummy, dummy, name, timestamp, size, md5); + sprintf(xorriso->info_text, "scdbackup tag written : %s %s %s %s\n", + name, timestamp, size, md5); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + + if(xorriso->scdbackup_tag_listname[0]) { + fp= fopen(xorriso->scdbackup_tag_listname, "a"); + if(fp==0) { + strcpy(xorriso->info_text, "-scdbackup_tag: Cannot open file "); + Text_shellsafe(xorriso->scdbackup_tag_listname, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + fprintf(fp, "%s %s %s %s\n", name, timestamp, size, md5); + fclose(fp); + } + return(1); +} + diff --git a/xorriso/disk_ops.h b/xorriso/disk_ops.h new file mode 100644 index 00000000..265965ed --- /dev/null +++ b/xorriso/disk_ops.h @@ -0,0 +1,116 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/drive_mgt.c b/xorriso/drive_mgt.c new file mode 100644 index 00000000..e5680076 --- /dev/null +++ b/xorriso/drive_mgt.c @@ -0,0 +1,2242 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains functions which operate on drives and media. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "xorriso.h" +#include "xorriso_private.h" + +#include "lib_mgt.h" +#include "drive_mgt.h" +#include "iso_img.h" +#include "sort_cmp.h" +#include "write_run.h" +#include "read_run.h" + + +static const char *un0(const char *text) +{ + if(text == NULL) + return(""); + return(text); +} + + + + +int Xorriso_auto_driveadr(struct XorrisO *xorriso, char *adr, char *result, + int flag) +{ + int ret, is_known_mmc= 0; + char *path_pt, libburn_adr[BURN_DRIVE_ADR_LEN + SfileadrL]; + char *abs_pt, abs_adr[SfileadrL]; + + path_pt= adr; + if(strncmp(adr, "stdio:", 6) == 0) + path_pt= adr + 6; + else if(strncmp(adr, "mmc:", 4) == 0) + path_pt= adr + 4; + + + /* <<< replace by Xorriso_normalize_img_path() ? */; + + if(path_pt[0] != '/') { + abs_pt= getcwd(abs_adr, SfileadrL - 1); + if(abs_pt == NULL) { + Xorriso_msgs_submit(xorriso, 0, + "Relative drive path given. Cannot determine working directory.", + errno, "FAILURE", 0); + return(-1); + } + ret= Sfile_add_to_path(abs_adr, path_pt, 0); + if(ret <= 0) + return(-1); + } + + is_known_mmc= burn_drive_convert_fs_adr(path_pt, libburn_adr); + Xorriso_process_msg_queues(xorriso,0); + + ret= Xorriso_is_in_patternlist(xorriso, xorriso->drive_whitelist, path_pt, 0); + if(ret > 0) + goto ok; + ret= Xorriso_is_in_patternlist(xorriso, xorriso->drive_blacklist, path_pt, 0); + if(ret < 0) + return(ret); + if(ret) { + strcpy(xorriso->info_text, "Drive address "); + Text_shellsafe(adr, xorriso->info_text, 1); + strcat(xorriso->info_text, + " rejected because: -drive_class 'banned' "); + Text_shellsafe(Xorriso_get_pattern(xorriso, xorriso->drive_blacklist, + ret - 1, 0), + xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + /* if in greylist and not MMC and not stdio prefix: reject */ + if(is_known_mmc < 0) + return(ret); + if(adr == path_pt && !is_known_mmc) { /* no prefix, no MMC */ + ret= Xorriso_is_in_patternlist(xorriso, xorriso->drive_greylist, path_pt,0); + if(ret < 0) + return(ret); + if(ret) { + strcpy(xorriso->info_text, "Drive address "); + Text_shellsafe(adr, xorriso->info_text, 1); + strcat(xorriso->info_text, + " rejected because: not MMC and -drive_class 'risky' "); + Text_shellsafe(Xorriso_get_pattern(xorriso,xorriso->drive_greylist, + ret - 1, 0), + xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + Xorriso_msgs_submit(xorriso, 0, + "If the address is a legitimate target, prepend \"stdio:\"", + 0, "HINT", 0); + return(0); + } + } +ok:; + if(strncmp(adr, "mmc:", 4) == 0) { + if(Sfile_str(result, path_pt, 0) <= 0) + return(0); + } else if(adr == path_pt && is_known_mmc <= 0) { + Sfile_str(result, "stdio:", 0); + if(Sfile_str(result, adr, 1) <= 0) + return(0); + } else { + if(Sfile_str(result, adr, 0) <= 0) + return(0); + } + if(strncmp(result, "stdio:", 6)==0) { + if(xorriso->ban_stdio_write) { + strcpy(xorriso->info_text, "Drive address banned by -ban_stdio_write : "); + Text_shellsafe(result, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + return(1); +} + + +/* @param flag bit0= aquire as isoburn input drive + bit1= aquire as libburn output drive (as isoburn drive if bit0) + bit2= regard overwriteable media as blank + bit3= if the drive is a regular disk file: truncate it to + the write start address + bit5= do not print toc + bit6= do not calm down drive after aquiring it + @return <=0 failure , 1= ok + 2=success, but not writeable with bit1 + 3=success, but not blank and not ISO with bit0 +*/ +int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag) +{ + int ret, hret, not_writeable= 0, has_what, aquire_flag, load_lba, ext; + int lba, track, session, params_flag, adr_mode, read_ret; + uint32_t size; + struct burn_drive_info *dinfo= NULL, *out_dinfo, *in_dinfo; + struct burn_drive *drive= NULL, *out_drive, *in_drive; + enum burn_disc_status state; + IsoImage *volset = NULL; + IsoNode *root_node; + struct isoburn_read_opts *ropts= NULL; + char libburn_adr[SfileadrL], *boot_fate, *sev; + size_t value_length; + char *value= NULL; + double num; + char volid[33], adr_data[163], *adr_pt; + + if((flag&3)==0) { + sprintf(xorriso->info_text, + "XORRISOBURN program error : Xorriso_aquire_drive bit0+bit1 not set"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + return(-1); + } + ret= Xorriso_give_up_drive(xorriso, (flag&3)|8); + if(ret<=0) + return(ret); + if(flag & 1) + xorriso->isofs_st_out= time(0) - 1; + + ret= Xorriso_auto_driveadr(xorriso, adr, libburn_adr, 0); + if(ret <= 0) + return(ret); + if(strcmp(libburn_adr,"stdio:/dev/fd/1")==0) { + if(xorriso->dev_fd_1<0) { + sprintf(xorriso->info_text, + "-*dev \"stdio:/dev/fd/1\" was not a start argument. Cannot use it now."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } else { + sprintf(libburn_adr, "stdio:/dev/fd/%d", xorriso->dev_fd_1); + } + } + + if((flag&3)==1 && xorriso->out_drive_handle!=NULL) { + ret= Xorriso_get_drive_handles(xorriso, &out_dinfo, &out_drive, + "on attempt to compare new indev with outdev", 2); + if(ret<=0) + goto ex; + ret= burn_drive_equals_adr(out_drive, libburn_adr, 1); + if(ret==1) { + dinfo= out_dinfo; + xorriso->indev_is_exclusive= xorriso->outdev_is_exclusive; + } + } else if((flag&3)==2 && xorriso->in_drive_handle!=NULL) { + ret= Xorriso_get_drive_handles(xorriso, &in_dinfo, &in_drive, + "on attempt to compare new outdev with indev", 0); + if(ret<=0) + goto ex; + ret= burn_drive_equals_adr(in_drive, libburn_adr, 1); + if(ret==1) { + dinfo= in_dinfo; + xorriso->outdev_is_exclusive= xorriso->indev_is_exclusive; + } + } + + if(dinfo==NULL) { + aquire_flag= 1 | ((flag&(8|4))>>1) | ((xorriso->toc_emulation_flag & 3)<<3); + if(xorriso->toc_emulation_flag & 4) + aquire_flag|= 128; + if(!(xorriso->do_aaip & 1)) + aquire_flag|= 32; + if((xorriso->ino_behavior & (1 | 2)) && !(xorriso->do_aaip & (4 | 32))) + aquire_flag|= 64; + burn_preset_device_open(xorriso->drives_exclusive, 0, 0); + ret= isoburn_drive_aquire(&dinfo, libburn_adr, aquire_flag); + burn_preset_device_open(1, 0, 0); + Xorriso_process_msg_queues(xorriso,0); + if(ret<=0) { + sprintf(xorriso->info_text,"Cannot aquire drive '%s'", adr); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + if(flag&1) + if(xorriso->image_start_mode&(1<<31)) /* used up setting */ + xorriso->image_start_mode= 0; /* no need to perform auto setting */ + if(flag & 1) + xorriso->indev_is_exclusive= xorriso->drives_exclusive; + if(flag & 2) + xorriso->outdev_is_exclusive= xorriso->drives_exclusive; + } + drive= dinfo[0].drive; + if(flag&1) { + if(xorriso->image_start_mode&(1<<31)) /* used up setting */ + xorriso->image_start_mode&= ~0xffff; /* perform auto setting */ + if((xorriso->image_start_mode&(1<<30))) { /* if enabled at all */ + adr_pt= xorriso->image_start_value; + adr_mode= xorriso->image_start_mode & 0xffff; + if(adr_mode == 4 && strlen(adr_pt) <= 80) { + /* Convert volid search expression into lba */ + params_flag= 0; + ret= Xorriso__bourne_to_reg(xorriso->image_start_value, adr_data, 0); + if(ret == 1) + params_flag|= 4; + ret= isoburn_get_mount_params(drive, 4, adr_data, &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, + "-load : Given address does not point to an ISO 9660 session", + 0, "FAILURE", 0); + ret= 0; goto ex; + } + sprintf(volid, "%d", lba); + adr_pt= volid; + adr_mode= 3; + } + ret= isoburn_set_msc1(drive, adr_mode, adr_pt, + !!(xorriso->image_start_mode & (1<<16))); + if(ret<=0) + goto ex; + if(xorriso->image_start_mode&(1<<31)) + xorriso->image_start_mode= 0; /* disable msc1 setting completely */ + else + xorriso->image_start_mode|= (1<<31); /* mark as used up */ + } + } + state= isoburn_disc_get_status(drive); + Xorriso_process_msg_queues(xorriso,0); + if(flag&1) { + volset= isoburn_get_attached_image(drive); + if(volset != NULL) { /* The image object is already created */ + iso_image_unref(volset); + } + } + + if(flag&2) { + xorriso->out_drive_handle= dinfo; + if(Sfile_str(xorriso->outdev, adr, 0)<=0) + {ret= -1; goto ex;} + if(state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE) { + sprintf(xorriso->info_text, "Disc status unsuitable for writing"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + not_writeable= 1; + } + } + if(flag&1) { + xorriso->in_drive_handle= dinfo; + if(Sfile_str(xorriso->indev, adr, 0)<=0) + {ret= -1; goto ex;} + } else if(flag&2) { + if(xorriso->in_volset_handle==NULL) { + /* No volume loaded: create empty one */ + ret= Xorriso_create_empty_iso(xorriso, 0); + if(ret<=0) + goto ex; + } else { + iso_image_ref((IsoImage *) xorriso->in_volset_handle); + ret= isoburn_attach_image(drive, (IsoImage *) xorriso->in_volset_handle); + if(ret<=0) { + sprintf(xorriso->info_text, + "Failed to attach ISO image object to outdev"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + {ret= -1; goto ex;} + } + } + if(!(flag&32)) + Xorriso_toc(xorriso, 1 | 2 | 8); + {ret= 1+not_writeable; goto ex;} + } + + 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_hln_array(xorriso, 0); + Xorriso_destroy_di_array(xorriso, 0); + + /* check for invalid state */ + if(state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE && + state != BURN_DISC_FULL) { + sprintf(xorriso->info_text, + "Disc status not blank and unsuitable for reading"); + sev= "FAILURE"; + if(xorriso->img_read_error_mode==2) + sev= "FATAL"; + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, sev, 0); + Xorriso_give_up_drive(xorriso, 1|((flag&32)>>2)); + ret= 3; goto ex; + } + /* fill read opts */ + ret= isoburn_ropt_new(&ropts, 0); + if(ret<=0) + goto ex; + + ext= isoburn_ropt_noiso1999; + if((xorriso->ino_behavior & (1 | 2)) && !(xorriso->do_aaip & (1 | 4 | 32)) + && !(xorriso->do_md5 & 1)) + ext|= isoburn_ropt_noaaip; + if(!(xorriso->do_aaip & 1)) + ext|= isoburn_ropt_noacl; + if(!(xorriso->do_aaip & 4)) + ext|= isoburn_ropt_noea; + if(xorriso->ino_behavior & 1) + ext|= isoburn_ropt_noino; + +#ifdef isoburn_ropt_nomd5 + if(!(xorriso->do_md5 & 1)) + ext|= isoburn_ropt_nomd5; +#endif + + isoburn_ropt_set_extensions(ropts, ext); + + isoburn_ropt_set_default_perms(ropts, (uid_t) 0, (gid_t) 0, (mode_t) 0555); + isoburn_ropt_set_input_charset(ropts, xorriso->in_charset); + isoburn_ropt_set_auto_incharset(ropts, !!(xorriso->do_aaip & 512)); + + Xorriso_set_image_severities(xorriso, 1); /* No DEBUG messages */ + Xorriso_pacifier_reset(xorriso, 0); + isoburn_set_read_pacifier(drive, Xorriso__read_pacifier, (void *) xorriso); + + /* <<< Trying to work around too much tolerance on bad image trees. + Better would be a chance to instruct libisofs what to do in + case of image read errors. There is a risk to mistake other SORRYs. + */ + if(xorriso->img_read_error_mode>0) + iso_set_abort_severity("SORRY"); + + if(state != BURN_DISC_BLANK) { + ret= isoburn_disc_get_msc1(drive, &load_lba); + if(ret > 0) { + sprintf(xorriso->info_text, + "Loading ISO image tree from LBA %d", load_lba); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } + ret= Xorriso_assert_volid(xorriso, load_lba, 0); + if(ret <= 0) + goto ex; + } + + read_ret= ret= isoburn_read_image(drive, ropts, &volset); + + /* <<< Resetting to normal thresholds */ + if(xorriso->img_read_error_mode>0) + Xorriso_set_abort_severity(xorriso, 0); + + if(ret<=0) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_set_image_severities(xorriso, 0); + Xorriso_give_up_drive(xorriso, 1|((flag&32)>>2)); + sprintf(xorriso->info_text,"Cannot read ISO image tree"); + sev= "FAILURE"; + if(xorriso->img_read_error_mode==2) + sev= "FATAL"; + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, sev, 0); + if(read_ret == ISO_SB_TREE_CORRUPTED && (xorriso->do_md5 & 1)) { + Xorriso_msgs_submit(xorriso, 0, + "You might get a questionable ISO image tree by option -md5 'off'.", + 0, "HINT", 0); + } else if(xorriso->img_read_error_mode!=0) { + Xorriso_msgs_submit(xorriso, 0, "You might get a partial or altered ISO image tree by option -error_behavior 'image_loading' 'best_effort' if -abort_on is set to be tolerant enough.", + 0, "HINT", 0); + } + + + ret= 3; goto ex; + } + Xorriso_pacifier_callback(xorriso, "nodes read", xorriso->pacifier_count, 0, + "", 1); /* report end count */ + xorriso->in_volset_handle= (void *) volset; + xorriso->in_sector_map= NULL; + Xorriso_set_image_severities(xorriso, 0); + + Xorriso_update_volid(xorriso, 0); + strncpy(xorriso->application_id, + un0(iso_image_get_application_id(volset)), 128); + xorriso->application_id[128]= 0; + strncpy(xorriso->publisher, un0(iso_image_get_publisher_id(volset)), 128); + xorriso->publisher[128]= 0; + strncpy(xorriso->system_id, un0(iso_image_get_system_id(volset)), 32); + xorriso->system_id[32]= 0; + strncpy(xorriso->volset_id, un0(iso_image_get_volset_id(volset)), 128); + xorriso->volset_id[128]= 0; + + /* <<< can be removed as soon as libisofs-0.6.24 is mandatory + */ + if(strcmp(un0(iso_image_get_copyright_file_id(volset)), "_") == 0 && + strcmp(un0(iso_image_get_abstract_file_id(volset)), "_") == 0 && + strcmp(un0(iso_image_get_biblio_file_id(volset)), "_") == 0) { + /* This is bug output from libisofs <= 0.6.23 . The texts mean file names + and should have been empty to indicate that there are no such files. + It is obvious that not all three roles can be fulfilled by one file "_" + so that one cannot spoil anything by assuming them empty now. + Modern versions of libisofs are supposed to do this themselves. + */ + iso_image_set_copyright_file_id(volset, ""); + iso_image_set_abstract_file_id(volset, ""); + iso_image_set_biblio_file_id(volset, ""); + } + + if(xorriso->out_drive_handle != NULL && + xorriso->out_drive_handle != xorriso->in_drive_handle) { + ret= Xorriso_get_drive_handles(xorriso, &out_dinfo, &out_drive, + "on attempt to attach ISO image volset to outdev", 2); + if(ret<=0) + goto ex; + iso_image_ref((IsoImage *) xorriso->in_volset_handle); + isoburn_attach_image(out_drive, xorriso->in_volset_handle); + } + Xorriso_process_msg_queues(xorriso,0); + isoburn_ropt_get_size_what(ropts, &size, &has_what); + if(has_what & isoburn_ropt_has_el_torito) { + if(xorriso->boot_image_bin_path[0]) + boot_fate= "replaced by new boot image"; + else if(xorriso->patch_isolinux_image & 1) + boot_fate= "patched at boot info table"; + else if(xorriso->keep_boot_image) + boot_fate= "kept unchanged"; + else + boot_fate= "discarded"; + sprintf(xorriso->info_text, + "Detected El-Torito boot information which currently is set to be %s", + boot_fate); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + Xorriso_record_boot_info(xorriso, 0); + } + + if(flag & 1) { + /* Look for isofs.st and put it into xorriso->isofs_st_in */; + root_node= (IsoNode *) iso_image_get_root(volset); + ret= iso_node_lookup_attr(root_node, "isofs.st", &value_length, &value, 0); + if(ret > 0) { + if(value_length > 0) { + sscanf(value, "%lf", &num); + if(num > 0) + xorriso->isofs_st_in= num; + } + free(value); + } + } + + if(!(flag&32)) { + Xorriso_toc(xorriso, 1 | 8); + if(xorriso->loaded_volid[0]!=0) { + sprintf(xorriso->info_text,"Volume id : '%s'\n", + xorriso->loaded_volid); + Xorriso_info(xorriso, 0); + if(strcmp(xorriso->loaded_volid, xorriso->volid) != 0 && + !xorriso->volid_default) { + sprintf(xorriso->info_text, "New volume id: '%s'\n", xorriso->volid); + Xorriso_info(xorriso, 0); + } + } + } + + ret= 1+not_writeable; +ex: + Xorriso_process_msg_queues(xorriso,0); + if(ret<=0) { + hret= Xorriso_give_up_drive(xorriso, (flag&3)|((flag&32)>>2)); + if(hretdo_calm_drive & 1) && !(flag & 64)) + burn_drive_snooze(drive, 0); /* No need to make noise from start */ + } + if(ropts!=NULL) + isoburn_ropt_destroy(&ropts, 0); + return(ret); +} + + +/* @param flag bit0=input drive + bit1=output drive + bit2=eject + bit3=no info message or toc +*/ +int Xorriso_give_up_drive(struct XorrisO *xorriso, int flag) +{ + int in_is_out_too, ret, do_eject; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + char sfe[5*SfileadrL]; + + in_is_out_too= (xorriso->in_drive_handle == xorriso->out_drive_handle); + if((flag&4) && in_is_out_too && (flag&(1|2))) { + if((flag&3)!=3) { + sprintf(xorriso->info_text,"Giving up for -eject whole -dev %s", + Text_shellsafe(xorriso->indev, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } + flag|= 3; /* give up in/out drive to eject it */ + } + + if((flag&1) && xorriso->in_drive_handle != NULL) { + Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to give up drive", 0); + + if(!in_is_out_too) { + do_eject= !!(flag&4); + if((flag & 4) && !xorriso->indev_is_exclusive) { + sprintf(xorriso->info_text, + "Will not eject media in non-exclusively aquired input drive."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + do_eject= 0; + } + if(drive!=NULL) + isoburn_drive_release(drive, do_eject); + if(dinfo!=NULL) + burn_drive_info_free(dinfo); + } + xorriso->in_drive_handle= NULL; + xorriso->indev[0]= 0; + + 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->isofs_st_out= time(0) - 1; + xorriso->isofs_st_in= 0; + xorriso->volset_change_pending= 0; + xorriso->no_volset_present= 0; + xorriso->loaded_boot_bin_lba= 0; + xorriso->loaded_boot_cat_path[0]= 0; + xorriso->boot_count= 0; + in_is_out_too= 0; + } + if((flag&2) && xorriso->out_drive_handle!=NULL) { + do_eject= !!(flag&4); + if((flag & 4) && !xorriso->outdev_is_exclusive) { + sprintf(xorriso->info_text, + "Will not eject media in non-exclusively aquired drive."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + do_eject= 0; + } + Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to give up drive", 2); + if(!in_is_out_too) { + if(drive!=NULL) + isoburn_drive_release(drive, do_eject); + if(dinfo!=NULL) + burn_drive_info_free(dinfo); + } + xorriso->out_drive_handle= NULL; + xorriso->outdev[0]= 0; + } else if((flag&1) && xorriso->out_drive_handle!=NULL) { + ret= Xorriso_create_empty_iso(xorriso, 0); + if(ret<=0) + return(ret); + if(!(flag&8)) { + sprintf(xorriso->info_text, + "Only the output drive remains. Created empty ISO image.\n"); + Xorriso_info(xorriso, 0); + Xorriso_toc(xorriso, 1 | 2 | 8); + } + } + Xorriso_process_msg_queues(xorriso,0); + return(1); +} + + +int Xorriso_may_burn(struct XorrisO *xorriso, int flag) +{ + + if(xorriso->outdev_is_exclusive) + return(1); + sprintf(xorriso->info_text, "The output drive was not aquired exclusively."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + sprintf(xorriso->info_text, "A possible remedy is: -osirrox 'o_excl_on'"); + if(xorriso->outdev[0]) { + strcat(xorriso->info_text," -outdev "); + Text_shellsafe(xorriso->outdev, xorriso->info_text, 1); + } + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0); + return(0); +} + + +/* @param flag bit2=do not try to read ISO heads +*/ +int Xorriso_toc_to_string(struct XorrisO *xorriso, char **toc_text, int flag) +{ + int ret, stack_handle, toc_ret, l; + struct Xorriso_lsT *results= NULL, *infos= NULL, *lpt; + + *toc_text= NULL; + ret= Xorriso_push_outlists(xorriso, &stack_handle, 1); + if(ret <= 0) + goto ex; + toc_ret= Xorriso_toc(xorriso, flag & 4); + ret= Xorriso_pull_outlists(xorriso, stack_handle, &results, &infos, 0); + if(ret <= 0) + goto ex; + if(toc_ret <= 0) + {ret= toc_ret; goto ex;} + l= 0; + for(lpt= results; lpt != NULL; lpt= Xorriso_lst_get_next(lpt, 0)) + l+= strlen(Xorriso_lst_get_text(lpt, 0)); + *toc_text= calloc(l + 1, 1); + l= 0; + for(lpt= results; lpt != NULL; lpt= Xorriso_lst_get_next(lpt, 0)) { + strcpy((*toc_text) + l, Xorriso_lst_get_text(lpt, 0)); + l+= strlen(Xorriso_lst_get_text(lpt, 0)); + } +ex:; + Xorriso_lst_destroy_all(&results, 0); + Xorriso_lst_destroy_all(&infos, 0); + return(ret); +} + + +/* @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) +{ + int ret, aq_flag; + char drive_name[SfileadrL], sfe[5*SfileadrL]; + + aq_flag= flag&3; + strcpy(drive_name, xorriso->outdev); + Xorriso_give_up_drive(xorriso, aq_flag); + if(aq_flag==0) { + sprintf(xorriso->info_text,"Gave up -outdev %s", + Text_shellsafe(xorriso->outdev, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(1); + } + sprintf(xorriso->info_text,"Re-aquiring -outdev %s", + Text_shellsafe(drive_name, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + ret= Xorriso_aquire_drive(xorriso, drive_name, aq_flag); + if(ret<=0) { + sprintf(xorriso->info_text,"Could not re-aquire -outdev %s", + Text_shellsafe(xorriso->outdev, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(ret); + } + return(1); +} + + +/* @param flag + bit3=report to info channel (else to result channel) +*/ +int Xorriso_toc_line(struct XorrisO *xorriso, int flag) +{ + if(!(flag & 8)) { + Xorriso_result(xorriso,0); + return(1); + } + strcpy(xorriso->info_text, xorriso->result_line); + Xorriso_info(xorriso, 0); + return(1); +} + + +/* @param flag + bit1=report about output drive + bit3=report to info channel (else to result channel) + bit4=do no report failure if no drive aquired +*/ +int Xorriso_media_product(struct XorrisO *xorriso, int flag) +{ + int ret, profile_no; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + char *product_id= NULL, *media_code1= NULL, *media_code2= NULL; + char *book_type= NULL, *manuf= NULL, profile_name[80], *respt; + + respt= xorriso->result_line; + + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to print media product info", + flag & (2 | 16)); + if(ret <= 0) + return(ret); + ret= burn_disc_get_media_id(drive, &product_id, &media_code1, &media_code2, + &book_type, 0); + if(ret > 0) { + ret= burn_disc_get_profile(drive, &profile_no, profile_name); + if(ret <= 0) + return(ret); + sprintf(respt, "Media product: %s , ", product_id); + manuf= burn_guess_manufacturer(profile_no, media_code1, media_code2, 0); + if(manuf != NULL) { + if(strncmp(manuf, "Unknown ", 8) == 0) + sprintf(respt + strlen(respt), "(not found in manufacturer list)\n"); + else + sprintf(respt + strlen(respt), "%s\n", manuf); + } else + sprintf(respt + strlen(respt), "(error during manufacturer lookup)\n"); + free(product_id); + free(media_code1); + free(media_code2); + if(book_type != NULL) + free(book_type); + if(manuf != NULL) + free(manuf); + Xorriso_toc_line(xorriso, flag & 8); + } + Xorriso_process_msg_queues(xorriso,0); + + return(1); +} + + +/* @param flag bit0=short report form + bit1=report about output drive + bit2=do not try to read ISO heads + bit3=report to info channel (else to result channel) + bit4=do no report failure if no drive aquired + bit5=only report "Drive current" and "Drive type" + bit6=report "Media product" with bit0 + bit7=only report "Drive current" +*/ +int Xorriso_toc(struct XorrisO *xorriso, int flag) +{ + int num_sessions= 0, num_tracks= 0, lba= 0, nwa= -1, pmin, psec, pframe, ret; + int track_count= 0, session_no, track_no, profile_no= -1, track_size; + int last_track_start= 0, last_track_size= -1, num_data= 0, is_data= 0; + int is_inout_drive= 0, drive_role, status, num_formats, emul_lba; + int num_payload= 0, num_wasted= 0, num_nondata= 0, not_reconizable= 0; + char profile_name[80],*respt,*devadr, *typetext= ""; + struct burn_toc_entry toc_entry; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + enum burn_disc_status s; + char mem_text[80]; + off_t start_byte= 0, num_free= 0, size; + unsigned dummy; + struct isoburn_toc_disc *disc= NULL; + struct isoburn_toc_session **sessions; + struct isoburn_toc_track **tracks; + int image_blocks= 0; + char volume_id[33]; + struct burn_toc_entry next_toc_entry; + + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to print Table Of Content", + flag & (2 | 16)); + if(ret<=0) + {ret= 0; goto ex;} + + respt= xorriso->result_line; + + if(strcmp(xorriso->indev, xorriso->outdev)==0) + is_inout_drive= 1; + if(flag&2) + devadr= xorriso->outdev; + else + devadr= xorriso->indev; + sprintf(respt, "Drive current: %s '%s'\n", + (is_inout_drive ? "-dev" : (flag&2 ? "-outdev" : "-indev")), + devadr); + Xorriso_toc_line(xorriso, flag & 8); + if(flag & 128) + {ret= 1; goto ex;} + sprintf(respt, "Drive type : vendor '%s' product '%s' revision '%s'\n", + dinfo[0].vendor, dinfo[0].product, dinfo[0].revision); + if((flag & 32) | !(flag & 1)) + Xorriso_toc_line(xorriso, flag & 8); + if(flag & 32) + {ret= 1; goto ex;} + + ret= burn_disc_get_profile(drive, &profile_no, profile_name); + s= isoburn_disc_get_status(drive); + if(profile_no == 0x0002 && s == BURN_DISC_EMPTY) + profile_no= 0; + sprintf(respt, "Media current: "); + if (profile_no > 0 && ret > 0) { + if (profile_name[0]) + sprintf(respt+strlen(respt), "%s", profile_name); + else + sprintf(respt+strlen(respt), "%4.4Xh", profile_no); + drive_role= burn_drive_get_drive_role(drive); + if(drive_role==2) + sprintf(respt+strlen(respt), ", overwriteable"); + else if(drive_role==0 || drive_role==3) + sprintf(respt+strlen(respt), ", sequential"); + strcat(respt, "\n"); + } else { + sprintf(respt+strlen(respt), "is not recognizable\n"); + not_reconizable= 1; + } + Xorriso_toc_line(xorriso, flag & 8); + + if((flag & 64) || !(flag & 1)) { + Xorriso_media_product(xorriso, flag & (2 | 8 | 16)); + if(xorriso->request_to_abort) + {ret= 1; goto ex;} + } + + sprintf(respt, "Media status : "); + if (s == BURN_DISC_FULL) { + if(not_reconizable) + sprintf(respt+strlen(respt), "is not recognizable\n"); + else + sprintf(respt+strlen(respt), "is written , is closed\n"); + } else if (s == BURN_DISC_APPENDABLE) { + sprintf(respt+strlen(respt), "is written , is appendable\n"); + } else if (s == BURN_DISC_BLANK) { + sprintf(respt+strlen(respt), "is blank\n"); + } else if (s == BURN_DISC_EMPTY) + sprintf(respt+strlen(respt), "is not present\n"); + else + sprintf(respt+strlen(respt), "is not recognizable\n"); + Xorriso_toc_line(xorriso, flag & 8); + + if(s == BURN_DISC_BLANK) { + sprintf(respt, "Media summary: 0 sessions, 0 data blocks, 0 data"); + num_free= isoburn_disc_available_space(drive, NULL); + Sfile_scale((double) num_free, mem_text,5,1e4,1); + sprintf(respt+strlen(respt), ", %s free\n", mem_text); + Xorriso_toc_line(xorriso, flag & 8); + } + if(s != BURN_DISC_FULL && s != BURN_DISC_APPENDABLE) + {ret= 1; goto ex;} + if(xorriso->request_to_abort) + {ret= 1; goto ex;} + + if(!(flag & 2)) + Xorriso_show_boot_info(xorriso, 1 | (flag & 8) | ((flag & 1) << 1)); + + disc= isoburn_toc_drive_get_disc(drive); + if(flag & 4) + sprintf(respt, "TOC layout : %3s , %9s , %10s\n", + "Idx", "sbsector", "Size"); + else + sprintf(respt, "TOC layout : %3s , %9s , %10s , %s\n", + "Idx", "sbsector", "Size", "Volume Id"); + if(!(flag&1)) + Xorriso_toc_line(xorriso, flag & 8); + + if (disc==NULL) { + Xorriso_process_msg_queues(xorriso,0); + ret= isoburn_get_min_start_byte(drive, &start_byte, 0); + nwa= start_byte / 2048; + if(ret<=0) { + Xorriso_process_msg_queues(xorriso,0); + if(flag&1) + {ret= 0; goto ex;} + sprintf(xorriso->info_text, "Cannot obtain Table Of Content"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + {ret= 0; goto ex;} + } + + /* fabricate TOC */ + typetext= "Other session"; + if(flag & 4) { + ret= 0; + typetext= "Session "; + } else + ret= isoburn_read_iso_head(drive, 0, &image_blocks, volume_id, 1); + if(ret>0) { + sprintf(respt, "ISO session : %3d , %9d , %9ds , %s\n", + 1, 0, image_blocks, volume_id); + nwa= image_blocks; + } else { + nwa= 0; + ret= burn_disc_get_formats(drive, &status, &size, &dummy, + &num_formats); + if(ret>0 && status==BURN_FORMAT_IS_FORMATTED) + nwa= size/2048; + sprintf(respt, "%13s: %3d , %9d , %9ds , \n", + typetext, 1, 0, nwa); + } + if(!(flag&1)) + Xorriso_toc_line(xorriso, flag & 8); + last_track_start= lba; + num_payload= num_data= last_track_size= nwa; + num_sessions= 1; + } else { + sessions= isoburn_toc_disc_get_sessions(disc, &num_sessions); + for (session_no= 0; session_norequest_to_abort); + session_no++) { + tracks= isoburn_toc_session_get_tracks(sessions[session_no], &num_tracks); + if (tracks==NULL) + continue; + for(track_no= 0; track_norequest_to_abort); + track_no++) { + track_count++; + is_data= 0; + isoburn_toc_track_get_entry(tracks[track_no], &toc_entry); + if (toc_entry.extensions_valid & 1) { + /* DVD extension valid */ + lba= toc_entry.start_lba; + track_size= toc_entry.track_blocks; + } else { + lba= burn_msf_to_lba(toc_entry.pmin, toc_entry.psec, + toc_entry.pframe); + if(track_no==num_tracks-1) { + isoburn_toc_session_get_leadout_entry(sessions[session_no], + &next_toc_entry); + } else { + isoburn_toc_track_get_entry(tracks[track_no+1], &next_toc_entry); + } + track_size= burn_msf_to_lba(next_toc_entry.pmin, next_toc_entry.psec, + next_toc_entry.pframe) - lba; + } + if(flag&(1|4)) + ret= 0; + else { + ret= isoburn_toc_track_get_emul(tracks[track_no], &emul_lba, + &image_blocks, volume_id, 0); + if(ret <= 0) + ret= isoburn_read_iso_head(drive, lba, &image_blocks, volume_id, 1); + if(image_blocks > track_size) { + sprintf(xorriso->info_text, + "Session %d bears ISO image size %ds larger than track size %ds", + session_no + 1, image_blocks, track_size); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", + 0); + image_blocks= track_size; + } + } + if(ret>0 && track_no==0) { + sprintf(respt, "ISO session : %3d , %9d , %9ds , %s\n", + session_no+1, lba, image_blocks , volume_id); + } else if(ret>0) { + sprintf(respt, "ISO track : %3d , %9d , %9ds , %s\n", + track_count, lba, image_blocks , volume_id); + } else if(track_no==0) { + typetext= "Other session"; + if(flag & 4) + typetext= "Session "; + sprintf(respt, "%13s: %3d , %9d , %9ds , \n", + typetext, session_no+1, lba, track_size); + } else { + typetext= "Other track "; + if(flag & 4) + typetext= "Track "; + sprintf(respt, "%13s: %3d , %9d , %9ds , \n", + typetext, track_count, lba, track_size); + } + if(!(flag&1)) + Xorriso_toc_line(xorriso, flag & 8); + if(track_no>0) + num_payload+= lba - last_track_start; + last_track_start= lba; + if((toc_entry.control&7)>=4) /* data track */ + is_data= 1; + } + isoburn_toc_session_get_leadout_entry(sessions[session_no], &toc_entry); + if (toc_entry.extensions_valid & 1) { + lba= toc_entry.start_lba; + burn_lba_to_msf(lba, &pmin, &psec, &pframe); + } else { + lba= burn_msf_to_lba(pmin, psec, pframe); + lba= burn_msf_to_lba(toc_entry.pmin, toc_entry.psec, toc_entry.pframe); + } + last_track_size= lba - last_track_start; + num_payload+= last_track_size; + if(is_data) + num_data+= last_track_size; + } + } + if(xorriso->request_to_abort) + {ret= 1; goto ex;} + num_wasted= lba - num_payload; + num_nondata= lba - num_data; + Sfile_scale(((double) num_data) * 2048.0, mem_text,5,1e4,1); + + sprintf(respt, "Media summary: %d session%s, %d data blocks, %s data", + num_sessions, (num_sessions==1 ? "" : "s"), num_data, mem_text); + num_free= isoburn_disc_available_space(drive, NULL); + Sfile_scale((double) num_free, mem_text,5,1e4,1); + sprintf(respt+strlen(respt), ", %s free", mem_text); + + sprintf(respt+strlen(respt), "\n"); + Xorriso_toc_line(xorriso, flag & 8); + + if (s==BURN_DISC_APPENDABLE && nwa!=0) { + ret= isoburn_disc_track_lba_nwa(drive, NULL, 0, &lba, &nwa); + if(ret>0) { + sprintf(respt, "Media nwa : %ds\n", nwa); + if(!(flag&1)) + Xorriso_toc_line(xorriso, flag & 8); + } + } + + if (disc!=NULL) + isoburn_toc_disc_free(disc); + Xorriso_process_msg_queues(xorriso,0); + ret= 1; +ex:; + return(ret); +} + + +int Xorriso_show_devices(struct XorrisO *xorriso, int flag) +{ + char adr[BURN_DRIVE_ADR_LEN]; + int i, j, max_dev_len= 1, pad; + struct burn_drive_info *drive_list= NULL; + unsigned int drive_count; + char *respt, perms[8]; + struct stat stbuf; + + sprintf(xorriso->info_text, "Beginning to scan for devices ...\n"); + Xorriso_info(xorriso,0); + + burn_drive_clear_whitelist(); + while(!burn_drive_scan(&drive_list, &drive_count)) { + Xorriso_process_msg_queues(xorriso,0); + usleep(100000); + } + Xorriso_process_msg_queues(xorriso,0); + if(drive_count <= 0) { + + /* >>> was a drive_list created at all ? */ + /* >>> must it be freed ? */ + + sprintf(xorriso->info_text, "No drives found"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + sprintf(xorriso->info_text, "Full drive scan done\n"); + Xorriso_info(xorriso,0); + + sprintf(xorriso->info_text, "-----------------------------------------------------------------------------\n"); + Xorriso_info(xorriso,0); + respt= xorriso->result_line; + for(i= 0; i < drive_count && !(xorriso->request_to_abort); i++) { + if(burn_drive_get_adr(&(drive_list[i]), adr)<=0) + strcpy(adr, "-get_adr_failed-"); + Xorriso_process_msg_queues(xorriso,0); + if(strlen(adr)>max_dev_len) + max_dev_len= strlen(adr); + } + for(i= 0; i < drive_count && !(xorriso->request_to_abort); i++) { + if(burn_drive_get_adr(&(drive_list[i]), adr)<=0) + strcpy(adr, "-get_adr_failed-"); + Xorriso_process_msg_queues(xorriso,0); + if(stat(adr,&stbuf)==-1) { + sprintf(perms,"errno=%d",errno); + } else { + strcpy(perms,"------"); + if(stbuf.st_mode&S_IRUSR) perms[0]= 'r'; + if(stbuf.st_mode&S_IWUSR) perms[1]= 'w'; + if(stbuf.st_mode&S_IRGRP) perms[2]= 'r'; + if(stbuf.st_mode&S_IWGRP) perms[3]= 'w'; + if(stbuf.st_mode&S_IROTH) perms[4]= 'r'; + if(stbuf.st_mode&S_IWOTH) perms[5]= 'w'; + } + sprintf(respt, "%d -dev '%s' ", i, adr); + pad= max_dev_len-strlen(adr); + if(pad>0) + for(j= 0; jinfo_text, "-----------------------------------------------------------------------------\n"); + Xorriso_info(xorriso,0); + + burn_drive_info_free(drive_list); + Xorriso_process_msg_queues(xorriso,0); + return(1); +} + + +int Xorriso_tell_media_space(struct XorrisO *xorriso, + int *media_space, int *free_space, int flag) +{ + int ret; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + struct burn_write_opts *burn_options; + + (*free_space)= (*media_space)= 0; + + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to -tell_media_space", 2); + if(ret<=0) + return(0); + + ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0); + if(ret<=0) + return(-1); + (*free_space)= (*media_space)= + isoburn_disc_available_space(drive, burn_options) / (off_t) 2048; + burn_write_opts_free(burn_options); + + if(xorriso->volset_change_pending) { + ret= Xorriso_write_session(xorriso, 1); + if(ret>0) + (*free_space)-= ret; + } + Xorriso_process_msg_queues(xorriso,0); + return(1); +} + + +/* @return <=0 error, 1 success +*/ +int Xorriso_list_formats(struct XorrisO *xorriso, int flag) +{ + int ret, i, status, num_formats, profile_no, type; + off_t size; + unsigned dummy; + char status_text[80], profile_name[90], *respt; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + + respt= xorriso->result_line; + + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to obtain format descriptor list", 1 | 2); + if(ret<=0) + return(0); + if(ret == 2) + goto ex; + ret = burn_disc_get_formats(drive, &status, &size, &dummy, + &num_formats); + if(ret<=0) { + sprintf(xorriso->info_text, "Cannot obtain format list info"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + ret= Xorriso_toc(xorriso, 3); + if(ret<=0) + goto ex; + ret= burn_disc_get_profile(drive, &profile_no, profile_name); + if(ret<=0) + goto ex; + + if(status == BURN_FORMAT_IS_UNFORMATTED) + sprintf(status_text, "unformatted, up to %.1f MiB", + ((double) size) / 1024.0 / 1024.0); + else if(status == BURN_FORMAT_IS_FORMATTED) { + if(profile_no==0x12 || profile_no==0x13 || profile_no==0x1a || + profile_no==0x43) + sprintf(status_text, "formatted, with %.1f MiB", + ((double) size) / 1024.0 / 1024.0); + else + sprintf(status_text, "written, with %.1f MiB", + ((double) size) / 1024.0 / 1024.0); + } else if(status == BURN_FORMAT_IS_UNKNOWN) { + if (profile_no > 0) + sprintf(status_text, "intermediate or unknown"); + else + sprintf(status_text, "no media or unknown media"); + } else + sprintf(status_text, "illegal status according to MMC-5"); + sprintf(respt, "Format status: %s\n", status_text); + Xorriso_result(xorriso,0); + + for (i= 0; i < num_formats; i++) { + ret= burn_disc_get_format_descr(drive, i, &type, &size, &dummy); + if (ret <= 0) + continue; + sprintf(respt, "Format idx %-2d: %2.2Xh , %.fs , %.1f MiB\n", + i, type, ((double) size) / 2048.0, ((double) size) / 1024.0/1024.0); + Xorriso_result(xorriso,0); + } + ret= 1; +ex:; + return(ret); +} + + +/* @param flag bit0= cdrecord style + bit1= obtain outdrive, else indrive + @return <=0 error, 1 success +*/ +int Xorriso_list_profiles(struct XorrisO *xorriso, int flag) +{ + int ret, i; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + int num_profiles, profiles[64]; + char is_current[64], profile_name[90], *respt; + + respt= xorriso->result_line; + + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to obtain profile list", 1 | (flag & 2)); + if(ret<=0) + return(0); + burn_drive_get_all_profiles(drive, &num_profiles, profiles, is_current); + for(i= 0; i < num_profiles; i++) { + ret= burn_obtain_profile_name(profiles[i], profile_name); + if(ret <= 0) + strcpy(profile_name, "unknown"); + sprintf(respt, "%s 0x%4.4X (%s)%s\n", + flag & 1 ? "Profile:" : "Profile :", + (unsigned int) profiles[i], + profile_name, is_current[i] ? " (current)" : ""); + Xorriso_result(xorriso,0); + } + return(1); +} + + +/* @param flag bit0= -inq + bit1= -checkdrive +*/ +int Xorriso_atip(struct XorrisO *xorriso, int flag) +{ + int ret, profile_number= 0; + char *respt, profile_name[80]; + double x_speed_max, x_speed_min= -1.0; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + enum burn_disc_status s; + char *manuf= NULL, *media_code1= NULL, *media_code2= NULL; + char *book_type= NULL, *product_id= NULL; + + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to print drive and media info", 2); + if(ret<=0) + return(0); + respt= xorriso->result_line; + sprintf(respt, "Device type : "); + ret= burn_drive_get_drive_role(drive); + if(ret==0) + sprintf(respt+strlen(respt), "%s\n", "Emulated (null-drive)"); + else if(ret==2) + sprintf(respt+strlen(respt), "%s\n", + "Emulated (stdio-drive, 2k random read-write)"); + else if(ret==3) + sprintf(respt+strlen(respt), "%s\n", + "Emulated (stdio-drive, sequential write-only)"); + else if(ret!=1) + sprintf(respt+strlen(respt), "%s\n","Emulated (stdio-drive)"); + else + sprintf(respt+strlen(respt), "%s\n","Removable CD-ROM"); + sprintf(respt+strlen(respt), "Vendor_info : '%s'\n",dinfo->vendor); + sprintf(respt+strlen(respt), "Identifikation : '%s'\n",dinfo->product); + sprintf(respt+strlen(respt), "Revision : '%s'\n",dinfo->revision); + Xorriso_result(xorriso,1); + if(flag&1) + return(1); + sprintf(respt, "Driver flags : BURNFREE\n"); + sprintf(respt+strlen(respt), "Supported modes: SAO TAO\n"); + Xorriso_result(xorriso,1); + if(flag&2) + return(1); + + s= burn_disc_get_status(drive); + ret= burn_disc_get_profile(drive,&profile_number,profile_name); + if(ret<=0) { + profile_number= 0; + strcpy(profile_name, "-unidentified-"); + } + if(s != BURN_DISC_UNSUITABLE) { + ret= burn_disc_read_atip(drive); + if(ret>0) { + ret= burn_drive_get_min_write_speed(drive); + x_speed_min= ((double) ret)/176.4; + } + } + if(s==BURN_DISC_EMPTY) { + sprintf(respt, "Current: none\n"); + Xorriso_result(xorriso,1); + return(1); + } else + sprintf(respt, "Current: %s\n",profile_name); + Xorriso_result(xorriso,1); + Xorriso_list_profiles(xorriso, 1 | 2); + if(strstr(profile_name,"BD")==profile_name) { + printf("Mounted Media: %2.2Xh, %s\n", profile_number, profile_name); + } else if(strstr(profile_name,"DVD")==profile_name) { + sprintf(respt, "book type: %s (emulated booktype)\n", profile_name); + Xorriso_result(xorriso,1); + if(profile_number == 0x13) { + sprintf(respt, "xorriso: message for sdvdbackup: \"(growisofs mode Restricted Overwrite)\"\n"); + Xorriso_result(xorriso,1); + } + } else { + sprintf(respt, "ATIP info from disk:\n"); + Xorriso_result(xorriso,1); + if(burn_disc_erasable(drive)) + sprintf(respt, " Is erasable\n"); + else + sprintf(respt, " Is not erasable\n"); + Xorriso_result(xorriso,1); + { int start_lba,end_lba,min,sec,fr; + ret= burn_drive_get_start_end_lba(drive,&start_lba,&end_lba,0); + if(ret>0) { + burn_lba_to_msf(start_lba,&min,&sec,&fr); + sprintf(respt, " ATIP start of lead in: %d (%-2.2d:%-2.2d/%-2.2d)\n", + start_lba,min,sec,fr); + Xorriso_result(xorriso,1); + burn_lba_to_msf(end_lba,&min,&sec,&fr); + sprintf(respt, " ATIP start of lead out: %d (%-2.2d:%-2.2d/%-2.2d)\n", + end_lba,min,sec,fr); + Xorriso_result(xorriso,1); + } + } + ret= burn_drive_get_write_speed(drive); + x_speed_max= ((double) ret)/176.4; + if(x_speed_min<0) + x_speed_min= x_speed_max; + sprintf(respt, + " 1T speed low: %.f 1T speed high: %.f\n",x_speed_min,x_speed_max); + Xorriso_result(xorriso,1); + } + + ret= burn_disc_get_media_id(drive, &product_id, &media_code1, &media_code2, + &book_type, 0); + if(ret > 0 && media_code1 != NULL && media_code2 != NULL) + manuf= burn_guess_manufacturer(profile_number, media_code1, media_code2, 0); + if(product_id != NULL) { + sprintf(respt, "Product Id: %s\n", product_id); + Xorriso_result(xorriso,1); + } + if(manuf != NULL) { + sprintf(respt, "Producer: %s\n", manuf); + Xorriso_result(xorriso, 1); + } + if(profile_number == 0x09 || profile_number == 0x0a) { + sprintf(respt, "Manufacturer: %s\n", manuf); + Xorriso_result(xorriso, 1); + } else if(product_id != NULL && media_code1 != NULL && media_code2 != NULL){ + free(product_id); + free(media_code1); + free(media_code2); + if(book_type != NULL) + free(book_type); + product_id= media_code1= media_code2= book_type= NULL; + ret= burn_disc_get_media_id(drive, &product_id, &media_code1, &media_code2, + &book_type, 1); + if(ret > 0) { + sprintf(respt, "Manufacturer: '%s'\n", media_code1); + Xorriso_result(xorriso, 1); + if(media_code2[0]) { + sprintf(respt, "Media type: '%s'\n", media_code2); + Xorriso_result(xorriso, 1); + } + } + } + if(manuf != NULL) + free(manuf); + if(media_code1 != NULL) + free(media_code1); + if(media_code2 != NULL) + free(media_code2); + if(book_type != NULL) + free(book_type); + if(product_id != NULL) + free(product_id); + return(1); +} + + +/* @param flag bit1= outdev rather than indev + @return <0 error, 0 = no profile to see , 1= ok , 2= ok, is CD profile + 3= ok, is BD profile +*/ +int Xorriso_get_profile(struct XorrisO *xorriso, int *profile_number, + char profile_name[80], int flag) +{ + int ret; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + + *profile_number= 0; + profile_name[0]= 0; + if(((flag&2) && xorriso->out_drive_handle==NULL) || + ((!(flag&2)) && xorriso->in_drive_handle==NULL)) + return(0); + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to determine media type", flag&2); + if(ret<=0) + return(0); + ret=burn_disc_get_profile(drive, profile_number, profile_name); + if(ret<=0) + return(ret); + if(*profile_number==0x08 || *profile_number==0x09 || *profile_number==0x0a) + return(2); + if(*profile_number == 0x40 || *profile_number == 0x41 || + *profile_number == 0x42 || *profile_number == 0x43) + return(3); + return(0); +} + + +/* @param flag bit0= grow_overwriteable_iso + bit1= obtain info from outdev + bit2= no need to obtain msc2 (NWA) +*/ +int Xorriso_msinfo(struct XorrisO *xorriso, int *msc1, int *msc2, int flag) +{ + int ret, dummy; + struct burn_drive *drive; + struct burn_drive_info *dinfo; + enum burn_disc_status disc_state; + + *msc1= *msc2= -1; + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to obtain msinfo", flag&2); + if(ret<=0) + return(ret); + + if(flag&1) + disc_state= isoburn_disc_get_status(drive); + else + disc_state= burn_disc_get_status(drive); + if(disc_state != BURN_DISC_APPENDABLE && + !(disc_state == BURN_DISC_FULL && (flag & 4))) { + Xorriso_process_msg_queues(xorriso,0); + if(!(flag & 4)) { + sprintf(xorriso->info_text, + "%s media is not appendable. Cannot obtain -msinfo.", + (flag&2) ? "Output" : "Input"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } + return(0); + } + ret= isoburn_disc_get_msc1(drive, msc1); + if(ret<=0) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, "Cannot obtain address of most recent session"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if(flag & 4) + return(1); + ret= isoburn_disc_track_lba_nwa(drive, NULL, 0, &dummy, msc2); + if(ret<0) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, "Cannot obtain next writeable address on media"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + return(1); +} + + +/* @param flag bit0=input drive + bit1=output drive + bit2= wake up rather than calm down +*/ +int Xorriso_drive_snooze(struct XorrisO *xorriso, int flag) +{ + int in_is_out_too, ret; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + + in_is_out_too= (xorriso->in_drive_handle == xorriso->out_drive_handle); + if((flag & 1) && xorriso->in_drive_handle != NULL) { + Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to calm drive", 0); + burn_drive_snooze(drive, !!(flag & 4)); + if(in_is_out_too) + {ret= 1; goto ex;} + } + if((flag&2) && xorriso->out_drive_handle!=NULL) { + Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to calm drive", 2); + burn_drive_snooze(drive, !!(flag & 4)); + } + ret= 1; +ex:; + Xorriso_process_msg_queues(xorriso,0); + return(ret); +} + + +/* @param flag bit0= enable SCSI command logging to stderr */ +int Xorriso_scsi_log(struct XorrisO *xorriso, int flag) +{ + if(flag == 0) + burn_set_scsi_logging(0); + else + burn_set_scsi_logging(2|4); + return(1); +} + +int Xorriso_check_md5_range(struct XorrisO *xorriso, off_t start_lba, + off_t end_lba, char md5[16], int flag) +{ + int ret; + struct burn_drive_info *dinfo= NULL; + struct burn_drive *drive= NULL; + off_t pos, data_count, to_read; + char data[64 * 1024], data_md5[16]; + void *ctx = NULL; + + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to check session MD5 checksum", 0); + if(ret <= 0) + goto ex; + ret= iso_md5_start(&ctx); + if(ret <= 0) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + goto ex; + } + for(pos= start_lba; pos < end_lba; pos+= 32) { + to_read= 32; + if(pos + to_read > end_lba) + to_read= end_lba - pos; + ret= burn_read_data(drive, pos * (off_t) 2048, data, + to_read * (off_t) 2048, &data_count, 0); + if(ret <= 0) + goto ex; + iso_md5_compute(ctx, data, (int) data_count); + xorriso->pacifier_count+= data_count; + xorriso->pacifier_byte_count+= data_count; + Xorriso_pacifier_callback(xorriso, "content bytes read", + xorriso->pacifier_count, 0, "", 0); + } + iso_md5_end(&ctx, data_md5); + ret= 1; + if(! iso_md5_match(md5, data_md5)) + ret= 0; +ex:; + Xorriso_process_msg_queues(xorriso,0); + if(ctx != NULL) + iso_md5_end(&ctx, data_md5); + return(ret); +} + + +int Xorriso_check_session_md5(struct XorrisO *xorriso, char *severity, + int flag) +{ + int ret, i; + IsoImage *image; + uint32_t start_lba, end_lba; + char md5[16], md5_text[33]; + + 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(ret); + if(ret == 0) { + sprintf(xorriso->info_text, + "No session MD5 is recorded with the loaded session"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + return(0); + } + + sprintf(xorriso->info_text, "Checking loaded session by its recorded MD5.\n"); + Xorriso_info(xorriso, 0); + for(i= 0; i < 16; i++) + sprintf(md5_text + 2 * i, "%2.2x", ((unsigned char *) md5)[i]); + sprintf(xorriso->result_line, + "Session MD5 %s , LBA %.f , %.f blocks\n", + md5_text, (double) start_lba, (double) end_lba - start_lba); + Xorriso_result(xorriso,0); + ret= Xorriso_check_md5_range(xorriso, (off_t) start_lba, (off_t) end_lba, + md5, 0); + return(ret); +} + + +/* @param flag bit0= this is a follow-up session (i.e. on CD: TAO) + bit1= no pacifier messages + bit2= compute stream MD5 and look out for checksum tag + @return <=0 error, 1= done, 2= aborted due to limit +*/ +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 i, j, ret, total_count= 0, sectors= -1, sector_size= -1, skip_reading; + int prev_quality= -1, quality= -1, retry= 0, profile_no, is_cd= 0; + int start_sec, end_sec, first_value, fret; + char profile_name[80]; + int start_lba= 0; + struct burn_drive *drive; + struct burn_drive_info *dinfo; + char data[64*1024], sfe[5*SfileadrL]; + off_t data_count, to_read, read_count= 0, write_amount; + double pre_read_time, post_read_time, time_diff, total_time_diff= 0; + double last_abort_file_time= 0; + struct stat stbuf; + void *ctx= NULL, *cloned_ctx= NULL; + char md5[16], tag_md5[16]; + uint32_t pos, range_start, range_size, next_tag= 0, lba, md5_spot_lba= 0; + int md5_spot_value= Xorriso_read_quality_untesteD, chain_broken= 0; + int tag_type= 0, valid, was_sb_tag= 0, in_track_gap= 0; + char *comparison= "", *sev_text= "DEBUG", *tag_type_name= ""; + + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to check media readability", + 2 * !!job->use_dev); + if(ret<=0) + goto ex; + ret= burn_disc_get_profile(drive, &profile_no, profile_name); + if(ret > 0) + if(profile_no >= 0x08 && profile_no <= 0x0a) + is_cd= 1; + + if(job->sector_map != NULL) { + Sectorbitmap_get_layout(job->sector_map, §ors, §or_size, 0); + sector_size/= 2048; + } + + if(job->retry > 0) + retry= 1; + else if(job->retry == 0 && is_cd) + retry= 1; + + if(flag & 4) { + ret= iso_md5_start(&ctx); + if(ret < 0) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + } + + start_lba= from_lba; + to_read= read_chunk; + post_read_time= Sfile_microtime(0); + for(i= 0; i < block_count; i+= to_read) { + skip_reading= 0; + + if(job->abort_file_path[0]) { + if(post_read_time - last_abort_file_time >= 0.1) { + if(stat(job->abort_file_path, &stbuf) != -1) { + if(stbuf.st_mtime >= xorriso->start_time) { + sprintf(xorriso->info_text, + "-check_media: Found fresh abort_file=%s", + job->abort_file_path); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + goto abort_check; + } + } + last_abort_file_time= post_read_time; + } + } + if(job->item_limit > 0 && + Spotlist_count(spotlist, 0) + 2 >= job->item_limit) { + sprintf(xorriso->info_text, "-check_media: Reached item_limit=%d", + job->item_limit); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + goto abort_check; + } + pre_read_time= Sfile_microtime(0); + if(job->time_limit > 0 + && job->start_time + job->time_limit < pre_read_time) { + sprintf(xorriso->info_text, "-check_media: Reached time_limit=%d", + job->time_limit); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); +abort_check:; + if(prev_quality >= 0) { + ret= Spotlist_add_item(spotlist, start_lba, i + from_lba - start_lba, + prev_quality, 0); + if(ret <= 0) + goto ex; + } + ret= Spotlist_add_item(spotlist, i + from_lba, block_count - i, + Xorriso_read_quality_untesteD, 0); + if(ret > 0) + ret= 2; + goto ex; + } + + to_read= read_chunk; + if(i + to_read > block_count) + to_read= block_count - i; + if(is_cd && i + to_read + 2 >= block_count) { + /* Read last 2 blocks of CD track separately, because with TAO tracks + they are always unreadable but with SAO tracks they contain data. + */ + if(to_read > 2) + to_read-= 2; + else if(to_read > 1) { + if(flag & 1) { + quality= Xorriso_read_quality_tao_enD; + skip_reading= 1; + } else + to_read--; + } + } + + if(sector_size == read_chunk && from_lba % read_chunk == 0 + && !skip_reading) { + if(Sectorbitmap_is_set(job->sector_map, (i + from_lba) / sector_size, 0)){ + quality= Xorriso_read_quality_valiD; + skip_reading= 1; + } + } else if(sector_size > 0 && !skip_reading) { + start_sec= (i + from_lba) / sector_size; + end_sec= (i + to_read + from_lba) / sector_size; + first_value= Sectorbitmap_is_set(job->sector_map, start_sec, 0); + for(j= start_sec; j < end_sec; j++) + if(Sectorbitmap_is_set(job->sector_map, j, 0) != first_value) + break; + to_read= j * sector_size - i - from_lba; + skip_reading= !!first_value; + if(skip_reading) + quality= Xorriso_read_quality_valiD; + } + + if(skip_reading) { + pre_read_time= post_read_time= Sfile_microtime(0); + } else { + data_count= 0; + pre_read_time= Sfile_microtime(0); + ret= burn_read_data(drive, ((off_t) (i + from_lba)) * (off_t) 2048, data, + to_read * (off_t) 2048, &data_count, 4 * !retry); + post_read_time= Sfile_microtime(0); + time_diff= post_read_time - pre_read_time; + total_time_diff+= time_diff; + total_count++; + if(ret <= 0) { + Xorriso_process_msg_queues(xorriso,0); + if(data_count / 2048 < to_read) { + if(data_count > 0 && retry) { + if(prev_quality >= 0) { + ret= Spotlist_add_item(spotlist, start_lba, + i + from_lba - start_lba, prev_quality, 0); + if(ret <= 0) + goto ex; + } + ret= Spotlist_add_item(spotlist, i + from_lba, data_count / 2048, + Xorriso_read_quality_partiaL, 0); + if(ret <= 0) + goto ex; + start_lba= i + from_lba + data_count / 2048; + prev_quality= Xorriso_read_quality_unreadablE; + } + quality= Xorriso_read_quality_unreadablE; + if(retry) + to_read= data_count / 2048 + 1; + } else + quality= Xorriso_read_quality_partiaL; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret<0) + goto ex; + } else { + quality= Xorriso_read_quality_gooD; + if(time_diff > job->slow_threshold_seq && job->slow_threshold_seq > 0 && + i > 0) + quality= Xorriso_read_quality_sloW; + } + + /* MD5 checksumming */ + if(ctx != NULL) { + for(j= 0; j < to_read; j++) { + lba= i + j + from_lba; + if(lba < md5_start) + continue; + ret= 0; + if(lba > md5_start + 16 && + (next_tag == 0 || chain_broken || lba == next_tag)) { + ret= iso_util_decode_md5_tag(data + j * 2048, &tag_type, + &pos, &range_start, &range_size, + &next_tag, tag_md5, !!chain_broken); + } + valid= (ret == 1 || ret == ISO_MD5_AREA_CORRUPTED) && pos == lba; + if(valid && tag_type == 2 && (lba < md5_start + 32 || in_track_gap)) { + tag_type_name= "superblock"; + was_sb_tag= 1; + if(in_track_gap && range_start != md5_start && range_start < lba && + lba - range_start <= j) { + /* Looking for next session : start computing in hindsight. + Session start and superblock tag are supposed to be in the + same 64 kB chunk. + */ + iso_md5_end(&ctx, md5); + ret= iso_md5_start(&ctx); + if(ret < 0) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + iso_md5_compute(&ctx, data + (j - (lba - range_start)) * 2048, + (lba - range_start) * 2048); + md5_start= range_start; + in_track_gap= 0; + } + } else if(valid && tag_type == 4 && lba < 32) { + tag_type_name= "relocated 64kB superblock"; + }else if(valid && tag_type == 3 && was_sb_tag) { + tag_type_name= "tree"; + }else if(valid && tag_type == 1) { + + /* >>> ??? allow this without superblock and tree tag ? */ + + tag_type_name= "session"; + } else { + tag_type_name= ""; + } + if (tag_type_name[0]) { + if(range_start != md5_start) { + sprintf(xorriso->info_text, + "Found MD5 %s tag which covers different data range", + tag_type_name); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0); + sprintf(xorriso->info_text, + " Expected: %u Found: %u", + (unsigned int) md5_start, range_start); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0); + chain_broken= 1; + valid= 0; + } else { + ret= iso_md5_clone(ctx, &cloned_ctx); + if(ret <= 0) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + iso_md5_end(&cloned_ctx, md5); + + if(ret == ISO_MD5_AREA_CORRUPTED) { + comparison= "CORRUPTED"; + sev_text= "WARNING"; + md5_spot_value= Xorriso_read_quality_md5_mismatcH; + chain_broken= 1; + } else if(! iso_md5_match(tag_md5, md5)) { + comparison= "NON-MATCHING"; + sev_text= "WARNING"; + md5_spot_value= Xorriso_read_quality_md5_mismatcH; + chain_broken= 1; + } else { + comparison= "matching"; + sev_text= "UPDATE"; + md5_spot_value= Xorriso_read_quality_md5_matcH; + } + md5_spot_lba= lba; + sprintf(xorriso->info_text, + "Found %s MD5 %s tag: start=%d size=%d", + comparison, tag_type_name, md5_start, lba - md5_start); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, + sev_text, 0); + } + if(valid && (tag_type == 1 || + (tag_type == 4 && pos == lba && lba < 32))) { + if(md5_spot_value != Xorriso_read_quality_untesteD) { + ret= Spotlist_add_item(spotlist, md5_start, + md5_spot_lba - md5_start, md5_spot_value, 0); + if(ret <= 0) + goto ex; + } + md5_spot_value= Xorriso_read_quality_untesteD; + md5_start = lba + 1; + if (md5_start % 32) + md5_start= md5_start + (32 - (md5_start % 32)); + next_tag= 0; + + iso_md5_end(&ctx, md5); + ret= iso_md5_start(&ctx); + if(ret < 0) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + if(tag_type == 1) + in_track_gap= 1; + continue; + } + } + iso_md5_compute(ctx, data + j * 2048, 2048); + } + } + + write_amount= data_count; + if(data_count > 0) { + read_count+= data_count; + if(job->data_to_limit >= 0 && read_count > job->data_to_limit) + write_amount-= (read_count - job->data_to_limit); + } + if(write_amount > 0) { + if(job->data_to_fd >= 0) { + ret= lseek(job->data_to_fd, + ((off_t) (i + from_lba)) * (off_t) 2048 + job->data_to_offset, + SEEK_SET); + if(ret == -1) { +failed_to_write:; + sprintf(xorriso->info_text, "Cannot write %d bytes to lba %d of %s", + (int) data_count, i + from_lba, + Text_shellsafe(job->data_to_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, + "FAILURE", 0); + {ret= 0; goto ex;} + } + ret= write(job->data_to_fd, data, write_amount); + if(ret == -1) + goto failed_to_write; + } + } + } + if(quality != prev_quality) { + if(prev_quality >= 0) { + ret= Spotlist_add_item(spotlist, start_lba, i + from_lba - start_lba, + prev_quality, 0); + if(ret <= 0) + goto ex; + } + start_lba= i + from_lba; + prev_quality= quality; + } + if(!(flag & 2)) { + xorriso->pacifier_count+= to_read; + if(post_read_time - xorriso->last_update_time >= + xorriso->pacifier_interval) + Xorriso_pacifier_callback(xorriso, "sectors examined", + xorriso->pacifier_count, xorriso->pacifier_total, "", 0); + } + } + if(prev_quality >= 0) { + ret= Spotlist_add_item(spotlist, start_lba, + block_count + from_lba - start_lba, prev_quality, 0); + if(ret <= 0) + goto ex; + } + + /* <<< for calibration of quality */ + if(total_count > 0) { + sprintf(xorriso->info_text, "Xorriso_check_interval: %.1f s / %d = %f", + total_time_diff, total_count, total_time_diff / total_count); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + } + + + /* MD5 checksumming : register result */ + + /* >>> ??? allow chain_broken to be a match ? */ + + if(next_tag > 0) { + sprintf(xorriso->info_text, "Missing announced MD5 tag: start=%d pos=%d", + md5_start, next_tag); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + md5_spot_value= Xorriso_read_quality_md5_mismatcH; + md5_spot_lba= next_tag; + } + if(md5_spot_value != Xorriso_read_quality_untesteD) { + ret= Spotlist_add_item(spotlist, md5_start, md5_spot_lba - md5_start, + md5_spot_value, 0); + if(ret <= 0) + goto ex; + } + + ret= 1; +ex: + if(ctx != NULL) + iso_md5_end(&ctx, md5); + return(ret); +} + + +int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist, + struct CheckmediajoB *job, int flag) +{ + int media_blocks= 0, read_chunk= 16, ret, mode, start_lba= 0; + int blocks, os_errno, i, j, last_track_end= -1, track_blocks, track_lba; + int num_sessions, num_tracks, declare_untested= 0, md5_start; + int read_capacity= -1, end_lba, hret, count, quality; + char *toc_info= NULL; + struct burn_drive *drive; + struct burn_drive_info *dinfo; + struct isoburn_toc_disc *isoburn_disc= NULL; + struct isoburn_toc_session **isoburn_sessions; + struct isoburn_toc_track **iso_burn_tracks; + struct burn_toc_entry isoburn_entry; + struct stat stbuf; + struct burn_multi_caps *caps= NULL; + + *spotlist= NULL; + + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to check media readability", + 2 * !!job->use_dev); + if(ret<=0) + goto ex; + + /* >>> determine media type dependent blocking factor: + 32 kB for CD (with 2kB retry) and DVD, 64 kB for BD + eventually adjust read_chunk + */; + if(job->min_block_size != 0) + read_chunk= job->min_block_size; + + ret= Spotlist_new(spotlist, 0); + if(ret <= 0) + {ret= -1; goto ex;} + + if(job->sector_map_path[0]) { + Sectorbitmap_destroy(&(job->sector_map), 0); + if(stat(job->sector_map_path, &stbuf) != -1) { + ret= Sectorbitmap_from_file(&(job->sector_map), job->sector_map_path, + xorriso->info_text, &os_errno, 0); + if(ret <= 0) { + if(xorriso->info_text[0]) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, os_errno, + "FAILURE", 0); + goto ex; + } + } + Xorriso_toc_to_string(xorriso, &toc_info, 4 * !job->map_with_volid); + } + ret= Xorriso_open_job_data_to(xorriso, job, 0); + if(ret <= 0) + goto ex; + Xorriso_pacifier_reset(xorriso, 0); + job->start_time= time(NULL); + mode= job->mode; + if(job->min_lba > 0) { + start_lba= job->min_lba; + ret= Spotlist_add_item(*spotlist, 0, job->min_lba, + Xorriso_read_quality_untesteD, 0); + if(ret <= 0) + goto ex; + } + ret= burn_get_read_capacity(drive, &read_capacity, 0); + if(ret <= 0) + read_capacity= -1; + + if(job->max_lba >= 0) { + blocks= job->max_lba + 1 - start_lba; + xorriso->pacifier_total= blocks; + ret= Xorriso_check_interval(xorriso, *spotlist, job, start_lba, blocks, + read_chunk, 0, 0); + if(ret <= 0) + goto ex; + + } else if(mode == 0) { /* track by track */ + isoburn_disc= isoburn_toc_drive_get_disc(drive); + if(isoburn_disc == NULL) + goto no_content_visible; + isoburn_sessions= + isoburn_toc_disc_get_sessions(isoburn_disc, &num_sessions); + for(i= 0; i < num_sessions; i++) { + iso_burn_tracks= isoburn_toc_session_get_tracks(isoburn_sessions[i], + &num_tracks); + for(j= 0; j < num_tracks; j++) { + isoburn_toc_track_get_entry(iso_burn_tracks[j], &isoburn_entry); + if(!(isoburn_entry.extensions_valid & 1)) /* should not happen */ + continue; + track_lba= isoburn_entry.start_lba; + track_blocks= isoburn_entry.track_blocks; + md5_start= track_lba; + if(i == 0 && j == 0) { + if(track_lba == 32) { + ret= burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0); + if(ret > 0) { + if(caps->start_adr) { + /* block 0 to 31 are the overall mount entry of overwriteable */ + track_lba= 0; + track_blocks+= 32; + } + } + } + } + if(last_track_end >= 0 && last_track_end < track_lba && + last_track_end >= start_lba) { + ret= Spotlist_add_item(*spotlist, last_track_end, + track_lba - last_track_end, + Xorriso_read_quality_off_tracK, 0); + if(ret <= 0) + goto ex; + xorriso->pacifier_count+= track_lba - last_track_end; + } + last_track_end= track_lba + track_blocks; + + if(track_lba < start_lba) { + track_blocks-= start_lba - track_lba; + track_lba= start_lba; + } + if(track_blocks <= 0) + continue; + if(declare_untested) { + ret= Spotlist_add_item(*spotlist, track_lba, track_blocks, + Xorriso_read_quality_untesteD, 0); + if(ret <= 0) + goto ex; + } else { + ret= Xorriso_check_interval(xorriso, *spotlist, job, track_lba, + track_blocks, read_chunk, md5_start, + (i > 0) | (4 * (xorriso->do_md5 & 1))); + if(ret <= 0) + goto ex; + if(ret == 2) + declare_untested= 1; + } + } + } + + } else if(mode == 1) { /* isoburn disc capacity */ + isoburn_disc= isoburn_toc_drive_get_disc(drive); + if(isoburn_disc == NULL) { +no_content_visible:; + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, "No content detected on media"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + blocks= media_blocks= isoburn_toc_disc_get_sectors(isoburn_disc); + if(start_lba >= 0) + blocks-= start_lba; + if(media_blocks <= 0) + goto no_content_visible; + xorriso->pacifier_total= blocks; + ret= Xorriso_check_interval(xorriso, *spotlist, job, start_lba, blocks, + read_chunk, 0, 0); + if(ret <= 0) + goto ex; + } else if(mode == 2) { + + /* >>> single sweep over libburn media capacity */; + + } + + Xorriso_pacifier_callback(xorriso, "sectors examined", + xorriso->pacifier_count, xorriso->pacifier_total, "", 1); + ret= 1; +ex:; + + if(job->data_to_fd != -1) + close(job->data_to_fd); + job->data_to_fd= -1; + + if(read_capacity >= 0) { + count= Spotlist_count(*spotlist, 0); + end_lba= 0; + for(i= 0; i < count; i++) { + Spotlist_get_item(*spotlist, i, &start_lba, &blocks, &quality, 0); + if(start_lba + blocks > end_lba) + end_lba= start_lba + blocks; + } + if(read_capacity > end_lba) { + hret= Spotlist_add_item(*spotlist, end_lba, read_capacity - end_lba, + Xorriso_read_quality_untesteD, 0); + if(hret < ret) + ret= hret; + } + } + + if(ret > 0) + ret= Xorriso_update_in_sector_map(xorriso, *spotlist, read_chunk, job, 0); + + if(ret > 0) { + ret= Xorriso_spotlist_to_sectormap(xorriso, *spotlist, read_chunk, + &(job->sector_map), !!job->untested_valid); + if(ret > 0 && job->sector_map_path[0]) { + ret= Sectorbitmap_to_file(job->sector_map, job->sector_map_path, toc_info, + xorriso->info_text, &os_errno, 0); + if(ret <= 0) { + if(xorriso->info_text[0]) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, os_errno, + "FAILURE", 0); + } + } + } + if(toc_info != NULL) + free(toc_info); + if(ret <= 0) + Spotlist_destroy(spotlist, 0); + if(caps!=NULL) + burn_disc_free_multi_caps(&caps); + return(ret); +} + + +/* @param flag + bit0= if not MMC drive print NOTE and return 2 + bit1= obtain outdrive, else indrive + bit4= do not report failure +*/ +int Xorriso_get_drive_handles(struct XorrisO *xorriso, + struct burn_drive_info **dinfo, + struct burn_drive **drive, + char *attempt, int flag) +{ + int ret; + + if(flag&2) + *dinfo= (struct burn_drive_info *) xorriso->out_drive_handle; + else + *dinfo= (struct burn_drive_info *) xorriso->in_drive_handle; + if(*dinfo==NULL && !(flag & 16)) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, "No %s drive aquired %s", + (flag&2 ? "output" : "input"), attempt); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } + if(*dinfo==NULL) + return(0); + *drive= (*dinfo)[0].drive; + if(flag & 1) { + ret= burn_drive_get_drive_role(*drive); + if(ret != 1) { + sprintf(xorriso->info_text, + "Output device is not an MMC drive. Desired operation does not apply."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(2); + } + } + return((*drive)!=NULL); +} + diff --git a/xorriso/drive_mgt.h b/xorriso/drive_mgt.h new file mode 100644 index 00000000..a0f2db6d --- /dev/null +++ b/xorriso/drive_mgt.h @@ -0,0 +1,37 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/emulators.c b/xorriso/emulators.c new file mode 100644 index 00000000..66614357 --- /dev/null +++ b/xorriso/emulators.c @@ -0,0 +1,1248 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains the implementation of emulators for mkisofs and cdrecord. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xorriso.h" +#include "xorriso_private.h" +#include "xorrisoburn.h" + + +int Xorriso_cdrskin_help(struct XorrisO *xorriso, int flag) +{ + static char helptext[][80]= { +"Usage: xorriso -as cdrecord [options|source_addresses]", +"Note: This is not cdrecord. See xorriso -help, xorriso -version, man xorriso", +"Options:", +"\t-version\tprint version information and exit emulation", +"\t--devices\tprint list of available MMC drives and exit emulation", +"\tdev=target\tpseudo-SCSI target to use as CD-Recorder", +"\t-v\t\tincrement verbose level by one", +"\t-checkdrive\tcheck if a driver for the drive is present", +"\t-inq\t\tdo an inquiry for the drive and exit emulation", +"\tspeed=#\t\tset speed of drive", +"\tblank=type\tblank a CD-RW disc (see blank=help)", +"\tfs=#\t\tSet fifo size to # (0 to disable, default is 4 MB)", +"\t-eject\t\teject the disk after doing the work", +"\t-dummy\t\tdo everything with laser turned off", +"\t-msinfo\t\tretrieve multi-session info for mkisofs >= 1.10", +"\t-toc\t\tretrieve and print TOC/PMA data", +"\t-atip\t\tretrieve media state, print \"Is *erasable\"", +"\t-multi\t\tgenerate a TOC that allows multi session", +"\t-waiti\t\twait until input is available before opening SCSI", +"\ttsize=#\t\tannounces exact size of source data", +"\tpadsize=#\tAmount of padding", +"\t-data\t\tSubsequent tracks are CD-ROM data mode 1 (default)", +"\t-isosize\tUse iso9660 file system size for next data track", +"\t-pad\t\tpadsize=30k", +"\t-nopad\t\tDo not pad", +"\t--grow_overwriteable_iso\temulate multi-session on DVD+RW, BD-RE", +"\twrite_start_address=#\t\twrite to byte address on DVD+RW, BD-RE", +"\tstream_recording=on|number\ttry to get full speed on DVD-RAM, BD", +"\tdvd_obs=default|32k|64k\t\tbytes per DVD/BD write operation", +"\tstdio_sync=on|off|number\twhether to fsync output to \"stdio:\"", +"\t-help\t\tprint this text to stderr and exit emulation", +"Actually this is the integrated ISO RockRidge filesystem manipulator xorriso", +"lending its libburn capabilities to a very limited cdrecord emulation. Only", +"a single data track can be burnt to blank, appendable or overwriteable media.", +"A much more elaborate cdrecord emulator is cdrskin from the same project.", +"@End_of_helptexT@" +}; + int i; + + for(i= 0; strcmp(helptext[i], "@End_of_helptexT@")!=0; i++) { + sprintf(xorriso->info_text, "%s\n", helptext[i]); + Xorriso_info(xorriso,0); + } + return(1); +} + + +/* micro version of cdrskin */ +int Xorriso_cdrskin(struct XorrisO *xorriso, char *whom, int argc, char **argv, + int flag) +{ + int ret, i, k, mem_do_close, aq_ret, eject_ret, msc1, msc2, hflag; + int do_atip= 0, do_checkdrive= 0, do_eject= 0, do_scanbus= 0; + int do_toc= 0, do_verbous= 0, do_version= 0, do_help= 0, do_waiti= 0; + int do_multi= 0, do_msinfo= 0, do_grow= 0, do_isosize= 0, do_xa1= 0; + double write_start_address= -1.0, tsize= -1.0; + char track_source[SfileadrL], sfe[5*SfileadrL], dev_adr[SfileadrL], *cpt; + char mem_report_about_text[80], *report_about= "SORRY", blank_mode[80]; + char speed[80]; + + /* cdrecord 2.01 options which are not scheduled for implementation, yet */ + static char ignored_partial_options[][41]= { + "timeout=", "debug=", "kdebug=", "kd=", "driver=", "ts=", + "pregap=", "defpregap=", "mcn=", "isrc=", "index=", "textfile=", + "pktsize=", "cuefile=", + "gracetime=", "minbuf=", + + "assert_write_lba=", "fifo_start_at=", "dev_translation=", + "drive_scsi_dev_family=", "fallback_program=", "modesty_on_drive=", + "tao_to_sao_tsize=", + + "direct_write_amount=", "msifile=", + + "" + }; + static char ignored_full_options[][41]= { + "-d", "-Verbose", "-V", "-silent", "-s", "-setdropts", "-prcap", + "-reset", "-abort", "-overburn", "-ignsize", "-useinfo", + "-fix", "-nofix", + "-raw", "-raw96p", "-raw16", + "-clone", "-text", + "-cdi", "-preemp", "-nopreemp", "-copy", "-nocopy", + "-scms", "-shorttrack", "-noshorttrack", "-packet", "-noclose", + "-media-info", "-minfo", + "-load", "-lock", "-raw96r", "-sao", "-dao", "-swab", + "-tao", "-force", "-format", + + "--adjust_speed_to_drive", "--allow_emulated_drives", "--allow_setuid", + "--allow_untested_media", "--any_track", "--demand_a_drive", + "--fifo_disable", "--fifo_start_empty", "--fill_up_media", + "--list_ignored_options", "--no_rc", "--no_convert_fs_adr", + "--prodvd_cli_compatible", "--single_track", + "--tell_media_space", + + "" + }; + +static char blank_help[][80]= { +"Blanking options:", +"\tall\t\tblank the entire disk", +"\tdisc\t\tblank the entire disk", +"\tdisk\t\tblank the entire disk", +"\tfast\t\tminimally blank the entire disk", +"\tminimal\t\tminimally blank the entire disk", +"\tas_needed\tblank or format media to make it ready for (re-)use", +"\tdeformat\t\tblank a formatted DVD-RW", +"\tdeformat_quickest\tminimally blank a formatted DVD-RW to DAO only", +"\tformat_overwrite\tformat a DVD-RW to \"Restricted Overwrite\"", +"@End_of_helptexT@" +}; + + strcpy(mem_report_about_text, xorriso->report_about_text); + mem_do_close= xorriso->do_close; + + track_source[0]= 0; + dev_adr[0]= 0; + blank_mode[0]= 0; + speed[0]= 0; + + if(xorriso->in_drive_handle != NULL) { + ret= Xorriso_option_dev(xorriso, "", 1|32); /* give up indev */ + if(ret!=1) + return(ret); + } + + + /* Assess plan, make settings */ + for(i= 0; iinfo_text, "-as %s: %s", + whom, Text_shellsafe(argv[i], sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + + for(k=0;ignored_partial_options[k][0]!=0;k++) { + if(argv[i][0]=='-') + if(strncmp(argv[i]+1,ignored_partial_options[k], + strlen(ignored_partial_options[k]))==0) + goto no_volunteer; + if(strncmp(argv[i],ignored_partial_options[k], + strlen(ignored_partial_options[k]))==0) + goto no_volunteer; + } + for(k=0;ignored_full_options[k][0]!=0;k++) + if(strcmp(argv[i],ignored_full_options[k])==0) + goto no_volunteer; + if(0) { +no_volunteer:; + sprintf(xorriso->info_text, "-as %s: Ignored option %s", + whom, Text_shellsafe(argv[i], sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + continue; + } + + if(strcmp(argv[i], "-atip")==0) { + do_atip= 1; + } else if(strcmp(argv[i], "-audio")==0) { + sprintf(xorriso->info_text, "-as %s: Option -audio not supported.", whom); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } else if(strncmp(argv[i], "-blank=", 7)==0 || + strncmp(argv[i], "blank=", 6)==0) { + cpt= strchr(argv[i], '=')+1; + if(strcmp(cpt,"all")==0 || strcmp(cpt,"disc")==0 + || strcmp(cpt,"disk")==0) { + strcpy(blank_mode, "all"); + } else if(strcmp(cpt,"fast")==0 || strcmp(cpt,"minimal")==0) { + strcpy(blank_mode, "fast"); + } else if(strcmp(cpt,"help")==0) { + strcpy(blank_mode, "help"); + } else if(strcmp(cpt,"deformat")==0 || + strcmp(cpt,"deformat_sequential")==0 || + strcmp(cpt,"deformat_quickest")==0 || + strcmp(cpt,"deformat_sequential_quickest")==0) { + strcpy(blank_mode, cpt); + } else if(strcmp(cpt,"format_overwrite")==0) { + strcpy(blank_mode, "format_overwrite"); + } else if(strcmp(cpt,"as_needed")==0) { + strcpy(blank_mode, "as_needed"); + } else { + sprintf(xorriso->info_text, + "-as %s: blank=%s not supported. See blank=help .", + whom, Text_shellsafe(argv[i], sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + } else if(strcmp(argv[i], "-checkdrive")==0) { + do_checkdrive= 1; + } else if(strcmp(argv[i], "-data")==0) { + /* ok */; + } else if(strncmp(argv[i], "-dev=", 5)==0 || + strncmp(argv[i], "dev=", 4)==0) { + cpt= strchr(argv[i], '=')+1; + strcpy(dev_adr, cpt); + } else if(strcmp(argv[i], "--devices")==0) { + do_scanbus= 2; + } else if(strncmp(argv[i],"driveropts=", 11)==0 || + strncmp(argv[i],"-driveropts=", 12)==0) { + if(strcmp(argv[i]+11, "help")==0) { + fprintf(stderr,"Driver options:\n"); + fprintf(stderr, + "burnfree\tPrepare writer to use BURN-Free technology\n"); + } + } else if(strcmp(argv[i], "-dummy")==0) { + xorriso->do_dummy= 1; + } else if(strcmp(argv[i], "-eject")==0) { + do_eject= 1; + } else if(strncmp(argv[i], "-fs=", 4)==0 || strncmp(argv[i], "fs=", 3)==0) { + cpt= strchr(argv[i], '=')+1; + ret= Xorriso_option_fs(xorriso, cpt, 0); + if(ret<=0) + goto ex; + } else if(strcmp(argv[i], "--grow_overwriteable_iso")==0) { + do_grow= 1; + } else if(strcmp(argv[i], "-help")==0) { + do_help= 1; + } else if(strcmp(argv[i], "-isosize")==0) { + do_isosize= 1; + } else if(strcmp(argv[i], "-inq")==0) { + do_checkdrive= 2; + } else if(strcmp(argv[i], "-mode2")==0) { + Xorriso_msgs_submit(xorriso, 0, + "Defaulting option -mode2 to option -data", 0, "NOTE", 0); + } else if(strcmp(argv[i], "-msinfo")==0) { + do_msinfo= 1; + } else if(strcmp(argv[i], "-multi")==0) { + do_multi= 1; + } else if(strcmp(argv[i], "-nopad")==0) { + xorriso->padding= 0; + } else if(strcmp(argv[i], "-pad")==0) { + xorriso->padding= 15*2048; + } else if(strncmp(argv[i], "-padsize=", 9)==0 || + strncmp(argv[i], "padsize=", 8)==0) { + cpt= strchr(argv[i], '=')+1; + ret= Xorriso_option_padding(xorriso, cpt, 0); + if(ret<=0) + goto ex; + } else if(strcmp(argv[i], "-scanbus")==0) { + sprintf(xorriso->info_text, "-as %s: Option -scanbus not supported.", + whom); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + +/* do_scanbus= 1; */ + } else if(strncmp(argv[i], "-speed=", 7)==0 || + strncmp(argv[i], "speed=", 6)==0) { + cpt= strchr(argv[i], '=')+1; + strncpy(speed, cpt, 79); + speed[79]= 0; + + } else if(strncmp(argv[i], "-stream_recording=", 18)==0 || + strncmp(argv[i], "stream_recording=", 17)==0) { + cpt= strchr(argv[i], '=')+1; + Xorriso_option_stream_recording(xorriso, cpt, 0); + + } else if(strncmp(argv[i], "-dvd_obs=", 9)==0 || + strncmp(argv[i], "dvd_obs=", 8)==0) { + cpt= strchr(argv[i], '=') + 1; + Xorriso_option_dvd_obs(xorriso, cpt, 0); + + } else if(strncmp(argv[i], "-stdio_sync=", 12)==0 || + strncmp(argv[i], "stdio_sync=", 11)==0) { + cpt= strchr(argv[i], '=') + 1; + Xorriso_option_stdio_sync(xorriso, cpt, 0); + + } else if(strcmp(argv[i], "-toc")==0 || strcmp(argv[i], "--long_toc")==0) { + do_toc= 1; + } else if(strncmp(argv[i], "-tsize=", 7)==0 || + strncmp(argv[i], "tsize=", 6)==0) { + cpt= strchr(argv[i], '=')+1; + tsize= Scanf_io_size(cpt, 1); + if(tsize > 1024.0*1024.0*1024.0*1024.0*1024.0) { + sprintf(xorriso->info_text, "-as %s: much too large: %s",whom, argv[i]); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + } else if(strcmp(argv[i], "-v")==0 || strcmp(argv[i],"-verbose")==0) { + do_verbous++; + } else if(strcmp(argv[i], "-vv")==0) { + do_verbous+= 2; + } else if(strcmp(argv[i], "-vvv")==0) { + do_verbous+= 3; + } else if(strcmp(argv[i], "-version")==0) { + do_version= 1; + } else if(strcmp(argv[i], "-waiti")==0) { + do_waiti= 1; + } else if(strncmp(argv[i], "write_start_address=", 20)==0) { + write_start_address= Scanf_io_size(argv[i]+20,0); + } else if(strcmp(argv[i], "-xa")==0) { + Xorriso_msgs_submit(xorriso, 0, + "Defaulting option -xa to option -data", 0, "NOTE", 0); + } else if(strcmp(argv[i], "-xa1")==0) { + if(do_xa1 == 0) + do_xa1= 1; + } else if(strcmp(argv[i], "--xa1-ignore")==0) { + do_xa1= -1; + } else if(strcmp(argv[i], "-xa2")==0) { + Xorriso_msgs_submit(xorriso, 0, + "Defaulting option -xa2 to option -data", 0, "NOTE", 0); + } else if(strcmp(argv[i], "-xamix")==0) { + Xorriso_msgs_submit(xorriso, 0, + "Option -xamix not implemented and data not yet convertible to other modes", + 0, "FATAL", 0); + ret= 0; goto ex; + } else if(argv[i][0]=='-' && argv[i][1]!=0) { + sprintf(xorriso->info_text, "-as %s: Unknown option %s", + whom, Text_shellsafe(argv[i], sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } else { + if(track_source[0]) { + sprintf(xorriso->info_text, "-as %s: Surplus track source %s", + whom, Text_shellsafe(argv[i], sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + sprintf(xorriso->info_text, "First and only track source is %s", + Text_shellsafe(track_source, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + ret= 0; goto ex; + } + if(Sfile_str(track_source, argv[i], 0)<=0) + {ret= -1; goto ex;} + } + } + + /* Perform actions */ + Xorriso_option_report_about(xorriso, "NOTE", 0); + if(do_version) { + sprintf(xorriso->result_line, "Cdrecord 2.01-Emulation Copyright (C) 2010 see libburnia-project.org xorriso\n"); + Xorriso_result(xorriso, 1); + Xorriso_option_version(xorriso, 0); + ret= 1; goto ex; + } + if(do_waiti) { + sprintf(xorriso->info_text, + "xorriso: Option -waiti pauses program until input appears at stdin\n"); + Xorriso_info(xorriso,0); + sprintf(xorriso->result_line, "Waiting for data on stdin...\n"); + Xorriso_result(xorriso, 1); + for(ret= 0; ret==0; ) + ret= Wait_for_input(0,1000000,0); + if(ret<0 || feof(stdin)) { + Xorriso_msgs_submit(xorriso, 0, + "stdin produces exception rather than data", 0, "NOTE", 0); + } + sprintf(xorriso->info_text, "xorriso: Option -waiti pausing is done.\n"); + } + if(dev_adr[0]) { + hflag= 2 | 32 | 64; + if(!do_grow) + hflag|= 8; /* consider overwriteables as blank */ + ret= Xorriso_option_dev(xorriso, dev_adr, hflag); + if(ret<=0) + goto ex; + } + + if(do_help) { + Xorriso_cdrskin_help(xorriso, 0); + ret= 1; goto ex; + } + if(do_scanbus) { + if(do_scanbus==1) + /* >>> would need -scanbus compatible output and input format */; + else + Xorriso_option_devices(xorriso, 0); + ret= 1; goto ex; + } + if(strcmp(blank_mode, "help")==0) { + for(i= 0; strcmp(blank_help[i], "@End_of_helptexT@")!=0; i++) { + sprintf(xorriso->info_text, "%s\n", blank_help[i]); + Xorriso_info(xorriso,0); + } + ret= 1; goto ex; + } + + if(!(do_checkdrive || do_atip || do_toc || blank_mode[0] || track_source[0] || + do_eject || do_msinfo)) + {ret= 1; goto ex;} + + if(xorriso->out_drive_handle==NULL) { + sprintf(xorriso->info_text, "-as %s: No output drive selected", whom); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + + if(do_msinfo) { + ret= Xorriso_msinfo(xorriso, &msc1, &msc2, 2 | !!do_grow); + if(ret<=0) + goto ex; + sprintf(xorriso->result_line, "%d,%d\n", msc1, msc2); + Xorriso_result(xorriso, 1); + } + + if(speed[0]) { + ret= Xorriso_option_speed(xorriso, speed, 0); + if(ret<=0) + goto ex; + } + + if(do_verbous<=0) + report_about= "SORRY"; + else if(do_verbous<=2) + report_about= "UPDATE"; + else if(do_verbous==3) + report_about= "DEBUG"; + else + report_about= "ALL"; + Xorriso_option_report_about(xorriso, report_about, 0); + + if(do_checkdrive) { + ret= Xorriso_atip(xorriso, 2-(do_checkdrive==2)); + if(ret<=0) + goto ex; + } + if(do_atip) { + ret= Xorriso_atip(xorriso, 0); + if(ret<=0) + goto ex; + } + if(do_toc) { + ret= Xorriso_option_toc(xorriso, 0); + if(ret<=0) + goto ex; + } + if(strcmp(blank_mode, "format_overwrite")==0) { + ret= Xorriso_option_blank(xorriso, "fast", 1); + if(ret<=0) + goto ex; + } else if(blank_mode[0]) { + ret= Xorriso_option_blank(xorriso, blank_mode, 0); + if(ret<=0) + goto ex; + } + if(track_source[0]) { + xorriso->do_close= !do_multi; + ret= Xorriso_burn_track(xorriso, (off_t) write_start_address, + track_source, (off_t) tsize, + (!!do_grow) | ((!!do_isosize) << 1) | ((do_xa1 == 1) << 2)); + aq_ret= Xorriso_reaquire_outdev(xorriso, 2*(ret>0)); + if(ret<=0 && ret=0) { + eject_ret= Xorriso_option_eject(xorriso, "out", 0); + if(eject_retinfo_text, "-as %s: Job could not be performed properly.", + whom); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } + Xorriso_option_report_about(xorriso, mem_report_about_text, 0); + xorriso->do_close= mem_do_close; + return(ret); +} + + +/* @param flag bit0= do not report eventual ignore decision +*/ +int Xorriso_genisofs_ignore(struct XorrisO *xorriso, char *whom, + char **argv, int *i, int flag) +{ + /* mkisofs 2.01 options which are not scheduled for implementation, yet */ + static char ignored_arg0_options[][41]= { + "-allow-leading-dots", "-ldots", "-allow-lowercase", "-allow-multidot", + "-cache-inodes", "-no-cache-inodes", "-check-oldnames", "-d", "-D", + "-joliet-long", "-l", "-L", "-max-iso9660-filenames", "-N", "-nobak", + "-no-bak", "-force-rr", "-relaxed-filenames", "-T", "-U", + "-no-iso-translate", + "" + }; + static char ignored_arg1_options[][41]= { + "-biblio", "-check-session", "-p", "-root", + "-old-root", "-table-name", "-volset-seqno", "-volset-size", + "" + }; + int k, idx_offset= 0; + char sfe[5*SfileadrL]; + + for(k=0;ignored_arg0_options[k][0]!=0;k++) + if(strcmp(argv[*i],ignored_arg0_options[k])==0) + goto no_volunteer; + for(k=0;ignored_arg1_options[k][0]!=0;k++) + if(strcmp(argv[*i],ignored_arg1_options[k])==0) { + (*i)++; + idx_offset= -1; + goto no_volunteer; + } + return(0); +no_volunteer:; + sprintf(xorriso->info_text, "-as %s: Ignored option %s", + whom, Text_shellsafe(argv[(*i)+idx_offset], sfe, 0)); + if(!(flag & 1)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(1); +} + + +int Xorriso_genisofs_add_boot(struct XorrisO *xorriso, char *whom, + int *option_b, int *no_emul_boot, int flag) +{ + int ret; + + if(*option_b && !*no_emul_boot) { + xorriso->boot_image_bin_path[0]= 0; + sprintf(xorriso->info_text, + "-as %s: Option -b is supported only if option -no-emul-boot is given", + whom); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= Xorriso_attach_boot_image(xorriso, 0); + if(ret <= 0) + xorriso->boot_image_bin_path[0]= 0; + *option_b= 0; + *no_emul_boot= 1; + return(ret); +} + + +int Xorriso_genisofs_help(struct XorrisO *xorriso, int flag) +{ + static char helptext[][160]= { +"Usage: xorriso -as mkisofs [options] file...", +"Note: This is not mkisofs. See xorriso -help, xorriso -version, man xorriso", +"Options:", +" -f, -follow-links Follow symbolic links", +" -graft-points Allow to use graft points for filenames", +" -help Print option help", +" -input-charset CHARSET Local input charset for file name conversion", +" -output-charset CHARSET Output charset for file name conversion", +" -iso-level LEVEL Set ISO9660 conformance level (1..3)", +" -J, -joliet Generate Joliet directory information", +" -o FILE, -output FILE Set output file name", +" -m GLOBFILE, -exclude GLOBFILE", +" Exclude file name", +" -exclude-list FILE File with list of file names to exclude", +" -pad Pad output by 300k (default)", +" -no-pad Do not pad output", +" -M FILE, -prev-session FILE Set path to previous session to merge", +" -C PARAMS, -cdrecord-params PARAMS", +" Magic paramters from cdrecord", +" -path-list FILE File with list of pathnames to process", +" --quoted_path_list FILE File with list of quoted pathnames to process", +" -print-size Print estimated filesystem size and exit", +" -quiet Run quietly", +" -R, -rock Generate Rock Ridge directory information", +" -r, -rational-rock Generate rationalized Rock Ridge directory information", +" --hardlinks Record eventual hard link relations of files", +" --acl Record eventual ACLs of files", +" --xattr Record eventual user space xattr of files", +" --md5 Compute and record MD5 checksums of data files", +" --scdbackup_tag PATH NAME With --md5 record a scdbackup checksum tag", +" --for_backup Use all options which improve backup fidelity", +" -V ID, -volid ID Set Volume ID", +" -volset ID Set Volume set ID", +" -publisher PUB Set Volume publisher", +" -A ID, -appid ID Set Application ID", +" -sysid ID Set System ID", +" -b FILE, -eltorito-boot FILE", +" Set El Torito boot image name", +" -eltorito-alt-boot Start specifying alternative El Torito boot parameters", +" --efi-boot FILE Set El Torito EFI boot image name and type", +" -c FILE, -eltorito-catalog FILE", +" Set El Torito boot catalog name", +" -boot-load-size # Set numbers of load sectors", +" -no-emul-boot Boot image is 'no emulation' image", +" -boot-info-table Patch boot image with info table", +" -G FILE, -generic-boot FILE Set generic boot image name", +" --protective-msdos-label Patch System Area by partition table", +" --modification-date=YYYYMMDDhhmmsscc", +" Override date of creation and modification", +" -isohybrid-mbr FILE Set SYSLINUX mbr/isohdp[fp]x*.bin for isohybrid", +#ifdef Xorriso_with_isohybriD +" isolinux_mbr=on|auto|off Control eventual isohybrid MBR generation", +#endif +" --sort-weight NUMBER FILE Set LBA weight number to file or file tree", +" --stdio_sync on|off|number Control forced output to disk files", +" -z, -transparent-compression", +" Enable transparent compression of files", +" -v, -verbose Verbose", +" -version Print the current version", +"@End_of_helptexT@" +}; + char ra_text[80]; + int i; + + strcpy(ra_text, xorriso->report_about_text); + + Xorriso_option_report_about(xorriso, "NOTE", 0); + for(i= 0; strcmp(helptext[i], "@End_of_helptexT@")!=0; i++) { + sprintf(xorriso->info_text, "%s\n", helptext[i]); + Xorriso_info(xorriso, 1); + } + Xorriso_option_report_about(xorriso, ra_text, 0); + return(1); +} + + +/* micro emulation of mkisofs */ +int Xorriso_genisofs(struct XorrisO *xorriso, char *whom, + int argc, char **argv, int flag) +{ + int ret, i, j, was_path= 0, was_other_option= 0, mem_graft_points, mem; + int do_print_size= 0, fd, idx, iso_level= 0, no_emul_boot= 0; + int option_b= 0, was_failure= 0, fret, lower_r= 0, zero= 0; + int *weight_list= NULL, weight_count= 0; + int *boot_opt_list= NULL, boot_opt_count= 0; + char sfe[5*SfileadrL], adr[SfileadrL+8], ra_text[80], pathspec[2*SfileadrL]; + char *ept, *add_pt, eff_path[SfileadrL], indev[SfileadrL+8], msc[80], *cpt; + char *boot_path; + static char *lower_r_args[3]= {"/", "-exec", "mkisofs_r"}; + static char *sort_weight_args[4]= {"", "-exec", "sort_weight", ""}; + + strcpy(ra_text, xorriso->report_about_text); + + weight_list= TSOB_FELD(int, (argc / 3) + 1); + if(weight_list == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + return(-1); + } + boot_opt_list= TSOB_FELD(int, argc + 1); + if(boot_opt_list == NULL) { + cpt= (char *) weight_list; + Xorriso_no_malloc_memory(xorriso, &cpt, 0); + return(-1); + } + + adr[0]= indev[0]= msc[0]= 0; + for(i= 0; iresult_line, +"mkisofs 2.01-Emulation Copyright (C) 2010 see libburnia-project.org xorriso\n" + ); + fd= xorriso->dev_fd_1; + if(fd<0) + fd= 1; + write(fd, xorriso->result_line, strlen(xorriso->result_line)); + fsync(fd); + Xorriso_option_version(xorriso, 0); + + } else if(strcmp(argv[i], "-o")==0 || strcmp(argv[i], "-output")==0) { + if(i+1>=argc) + goto not_enough_args; + i++; + adr[0]= 0; + if(strcmp(argv[i],"-")!=0 && strncmp(argv[i], "stdio:", 6)!=0) + strcpy(adr, "stdio:"); + if(Sfile_str(adr+strlen(adr), argv[i], 0)<=0) + {ret= -1; goto ex;} + } else if(strcmp(argv[i], "-M")==0 || strcmp(argv[i], "-dev")==0 || + strcmp(argv[i], "-prev-session")==0) { + if(i+1>=argc) + goto not_enough_args; + i++; + if(strncmp(argv[i], "stdio:", 6)!=0) + strcpy(indev, "stdio:"); + if(Sfile_str(indev+strlen(indev), argv[i], 0)<=0) + {ret= -1; goto ex;} + } else if(strcmp(argv[i], "-C")==0 || + strcmp(argv[i], "-cdrecord-params")==0) { + if(i+1>=argc) + goto not_enough_args; + i++; + strncpy(msc, argv[i], sizeof(msc)-1); + msc[sizeof(msc)-1]= 0; + } else if(strcmp(argv[i], "-help")==0) { + Xorriso_genisofs_help(xorriso, 0); + } else if(strcmp(argv[i], "-v")==0 || strcmp(argv[i], "-verbose")==0) { + strcpy(ra_text, "UPDATE"); + } else if(strcmp(argv[i], "-quiet")==0) { + strcpy(ra_text, "SORRY"); + } else if(strcmp(argv[i], "-f")==0 || strcmp(argv[i], "-follow-links")==0) { + ret= Xorriso_option_follow(xorriso, "on", 0); + if(ret<=0) + goto problem_handler_1; + } else if(strcmp(argv[i], "-iso-level")==0) { + if(i+1>=argc) + goto not_enough_args; + i++; + sscanf(argv[i], "%d", &iso_level); + if(iso_level < 1 || iso_level > 3) { + sprintf(xorriso->info_text, + "-as %s: unsupported -iso-level '%s' (use one of: 1,2,3)", + whom, argv[i]); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto problem_handler_1; + } + if(iso_level < 3) + xorriso->file_size_limit= + ((off_t) 4) * ((off_t) 1024*1024*1024) - ((off_t) 1); + else + xorriso->file_size_limit= 0; + + } else if(strcmp(argv[i], "-input-charset")==0) { + if(i+1>=argc) + goto not_enough_args; + i++; + /* -local_charset */ + if(strcmp(argv[i], "default") == 0) + ret= Xorriso_option_charset(xorriso, "ISO-8859-1", 4); + else + ret= Xorriso_option_charset(xorriso, argv[i], 4); + if(ret <= 0) + goto problem_handler_1; + } else if(strcmp(argv[i], "-output-charset")==0) { + if(i+1>=argc) + goto not_enough_args; + i++; + /* -charset */ + if(strcmp(argv[i], "default") == 0) + ret= Xorriso_option_charset(xorriso, "ISO-8859-1", 3); + else + ret= Xorriso_option_charset(xorriso, argv[i], 3); + if(ret <= 0) + goto problem_handler_1; + } else if(strcmp(argv[i], "--hardlinks")==0) { + Xorriso_option_hardlinks(xorriso, "on", 0); + } else if(strcmp(argv[i], "--acl")==0) { + Xorriso_option_acl(xorriso, "on", 0); + } else if(strcmp(argv[i], "--xattr")==0) { + Xorriso_option_xattr(xorriso, "on", 0); + } else if(strcmp(argv[i], "--md5")==0) { + Xorriso_option_md5(xorriso, "on", 0); + } else if(strcmp(argv[i], "--scdbackup_tag")==0) { + if(i + 2 >= argc) + goto not_enough_args; + i+= 2; + ret= Xorriso_option_scdbackup_tag(xorriso, argv[i-1], argv[i], 0); + if(ret <= 0) + goto problem_handler_1; + } else if(strcmp(argv[i], "--for_backup")==0) { + Xorriso_option_hardlinks(xorriso, "on", 0); + Xorriso_option_acl(xorriso, "on", 0); + Xorriso_option_xattr(xorriso, "on", 0); + Xorriso_option_md5(xorriso, "on", 0); + } else if(strcmp(argv[i], "-z")==0 || + strcmp(argv[i], "-transparent-compression")==0) { + Xorriso_option_zisofs(xorriso, "by_magic=on", 0); + } else if(strcmp(argv[i], "--stdio_sync")==0) { + if(i+1>=argc) + goto not_enough_args; + i++; + Xorriso_option_stdio_sync(xorriso, argv[i], 0); + } else + was_other_option= 1; + + continue; /* regular bottom of loop */ +problem_handler_1:; + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + goto ex; + } + Xorriso_option_report_about(xorriso, ra_text, 0); + if(adr[0]) { + if(strncmp(adr, "stdio:", 6)==0 && strncmp(adr, "stdio:/dev/fd/", 14)!=0) { + ret= Sfile_type(adr+6, 1); + if(ret==-1) { + /* ok */; + } else if(ret==2 || ret==3) { + sprintf(xorriso->info_text, + "-as %s: Cannot accept %s as target: -o %s", + whom, (ret==3 ? "symbolic link" : "directory"), + Text_shellsafe(adr+6, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + } + /* Regard overwriteable as blank, truncate regular files on write start */ + ret= Xorriso_option_dev(xorriso, adr, 2|8|16); + if(ret<=0) + goto ex; + } + + if(was_other_option && xorriso->out_drive_handle==NULL) { + ret= Xorriso_option_dev(xorriso, "-", 2|4); /* set outdev to stdout */ + if(ret<=0) + goto ex; + } + + if(msc[0]) { + cpt= strchr(msc, ','); + if(cpt==NULL) { +illegal_c:; + sprintf(xorriso->info_text, + "-as %s: unusable parameter with option -C: %s", + whom, Text_shellsafe(msc, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } else if(cpt==msc || msc[1]==0) + goto illegal_c; + strncpy(sfe, msc, cpt-msc); + sfe[cpt-msc]= 0; + if(xorriso->in_drive_handle!=NULL && indev[0]) { + /* give up indev before setting the load address */ + ret= Xorriso_option_dev(xorriso, "", 1); + if(ret<=0) + goto ex; + } + /* growisofs submits msc1+16 to avoid a theoretical bug in mkisofs. + Therefore this bug has to be emulated here. Sigh. + */ + ret= Xorriso_option_load(xorriso, "sbsector", sfe, 1); + if(ret<=0) + goto ex; + ret= Xorriso_option_grow_blindly(xorriso, cpt+1, 0); + if(ret<=0) + goto ex; + } + if(indev[0]) { + ret= Xorriso_option_dev(xorriso, indev, 1); + if(ret<=0) + goto ex; + } + + if(!was_other_option) + {ret= 1; goto ex;} + + xorriso->padding= 300*1024; + + for(i= 0; iinfo_text, "-as %s: %s", + whom, Text_shellsafe(argv[i], sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + ret= Xorriso_genisofs_ignore(xorriso, whom, argv, &i, 0); + if(ret == 1) + continue; + if(strcmp(argv[i], "-version")==0) { + /* was already handled in first argument scan */; + + } else if(strcmp(argv[i], "-R")==0 || strcmp(argv[i], "-rock")==0) { + /* ok */; + } else if(strcmp(argv[i], "-r")==0 || strcmp(argv[i], "-rational-rock")==0){ + lower_r= 1; + } else if(strcmp(argv[i], "-J")==0 || strcmp(argv[i], "-joliet")==0) { + xorriso->do_joliet= 1; + } else if(strcmp(argv[i], "-graft-points")==0) { + xorriso->allow_graft_points= 1; + } else if(strcmp(argv[i], "-path-list")==0 || + strcmp(argv[i], "--quoted_path_list")==0) { + if(i+1>=argc) { +not_enough_args:; + sprintf(xorriso->info_text, "-as %s: Not enough arguments to option %s", + whom, argv[i]); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + i++; + was_path= 1; + xorriso->pacifier_style= 1; + ret= Xorriso_option_path_list(xorriso, argv[i], + (strcmp(argv[i-1], "--quoted_path_list")==0)); + if(ret<=0) + goto problem_handler_2; + } else if(strcmp(argv[i], "-f")==0 || strcmp(argv[i], "-follow-links")==0) { + /* was already handled in first argument scan */; + } else if(strcmp(argv[i], "-pad")==0) { + xorriso->padding= 300*1024; + } else if(strcmp(argv[i], "-no-pad")==0) { + xorriso->padding= 0; + } else if(strcmp(argv[i], "-print-size")==0) { + do_print_size= 1; + } else if(strcmp(argv[i], "-o")==0) { + i++; + /* was already handled in first argument scan */; + } else if(strcmp(argv[i], "-M")==0 || strcmp(argv[i], "-dev")==0) { + i++; + /* was already handled in first argument scan */; + } else if(strcmp(argv[i], "-C")==0) { + i++; + /* was already handled in first argument scan */; + } else if(strcmp(argv[i], "-help")==0) { + /* was already handled in first argument scan */; + } else if(strcmp(argv[i], "-V")==0 || strcmp(argv[i], "-volid")==0) { + if(i+1>=argc) + goto not_enough_args; + i++; + ret= Xorriso_option_volid(xorriso, argv[i], 0); + if(ret<=0) + goto problem_handler_2; + } else if(strcmp(argv[i], "-volset")==0) { + if(i+1>=argc) + goto not_enough_args; + i++; + ret= Xorriso_option_volid(xorriso, argv[i], 0); + if(ret<=0) + goto problem_handler_2; + } else if(strcmp(argv[i], "-P")==0 || strcmp(argv[i], "-publisher")==0) { + if(i+1>=argc) + goto not_enough_args; + i++; + ret= Xorriso_option_publisher(xorriso, argv[i], 0); + if(ret<=0) + goto problem_handler_2; + } else if(strcmp(argv[i], "-A")==0 || strcmp(argv[i], "-appid")==0) { + if(i+1>=argc) + goto not_enough_args; + i++; + ret= Xorriso_option_application_id(xorriso, argv[i], 0); + if(ret<=0) + goto problem_handler_2; + } else if(strcmp(argv[i], "-sysid")==0) { + if(i+1>=argc) + goto not_enough_args; + i++; + ret= Xorriso_option_system_id(xorriso, argv[i], 0); + if(ret<=0) + goto problem_handler_2; + } else if(strcmp(argv[i], "-m")==0 || strcmp(argv[i], "-exclude")==0 || + strcmp(argv[i], "-x")==0 || strcmp(argv[i], "-old-exclude")==0) { + if(i+1>=argc) + goto not_enough_args; + i++; + mem= xorriso->do_disk_pattern; + xorriso->do_disk_pattern= 1; + if(strchr(argv[i], '/')!=NULL) { + idx= i; + ret= Xorriso_option_not_paths(xorriso, i+1, argv, &idx, 0); + } else + ret= Xorriso_option_not_leaf(xorriso, argv[i], 0); + xorriso->do_disk_pattern= mem; + if(ret<=0) + goto problem_handler_2; + } else if(strcmp(argv[i], "-exclude-list")==0) { + if(i+1>=argc) + goto not_enough_args; + i++; + mem= xorriso->do_disk_pattern; + xorriso->do_disk_pattern= 1; + ret= Xorriso_option_not_list(xorriso, argv[i], 0); + xorriso->do_disk_pattern= mem; + if(ret<=0) + goto problem_handler_2; + } else if(strcmp(argv[i], "-v")==0 || strcmp(argv[i], "-quiet")==0) { + /* was already handled in first argument scan */; + + } else if(strcmp(argv[i], "-iso-level")==0) { + i++; + /* was already handled in first argument scan */; + } else if(strcmp(argv[i], "-no-emul-boot")==0 || + strcmp(argv[i], "-boot-info-table")==0 || + strncmp(argv[i], "isolinux_mbr=", 13)==0 || + strncmp(argv[i], "isolinux_mbr=", 13)==0 || + strcmp(argv[i], "-eltorito-alt-boot")==0 || + strcmp(argv[i], "--protective-msdos-label")==0) { + boot_opt_list[boot_opt_count++]= i; + } else if(strcmp(argv[i], "-b") == 0 || + strcmp(argv[i], "-eltorito-boot") == 0 || + strcmp(argv[i], "--efi-boot") == 0 || + strcmp(argv[i], "-c") == 0 || + strcmp(argv[i], "-eltorito-catalog") == 0 || + strcmp(argv[i], "-boot-load-size") == 0 || + strcmp(argv[i], "--embedded-boot")==0 || + strcmp(argv[i], "-generic-boot")==0 || + strcmp(argv[i], "-G") == 0 || + strcmp(argv[i], "-isohybrid-mbr")==0) { + if(i+1>=argc) + goto not_enough_args; + boot_opt_list[boot_opt_count++]= i; + i++; + } else if(strncmp(argv[i], "--modification-date=", 20)==0) { + ret= Xorriso_option_volume_date(xorriso, "uuid", argv[i] + 20, 0); + if(ret <= 0) + goto problem_handler_1; + + } else if(strcmp(argv[i], "-input-charset")==0) { + i++; + /* was already handled in first argument scan */; + } else if(strcmp(argv[i], "-output-charset")==0) { + i++; + /* was already handled in first argument scan */; + } else if(strcmp(argv[i], "--hardlinks")==0 || + strcmp(argv[i], "--acl")==0 || + strcmp(argv[i], "--xattr")==0 || + strcmp(argv[i], "--md5")==0 || + strcmp(argv[i], "--for_backup")==0) { + /* was already handled in first argument scan */; + } else if(strcmp(argv[i], "--scdbackup_tag")==0) { + /* was already handled in first argument scan */; + i+= 2; + } else if(strcmp(argv[i], "--sort-weight")==0) { + if(i + 2 >= argc) + goto not_enough_args; + i+= 2; + /* memorize for find runs after pathspecs have been added */ + weight_list[weight_count++]= i - 2; + } else if(strcmp(argv[i], "-z")==0 || + strcmp(argv[i], "-transparent-compression")==0) { + /* was already handled in first argument scan */; + } else if(argv[i][0]=='-' && argv[i][1]!=0) { + sprintf(xorriso->info_text, "-as %s: Unknown option %s", + whom, Text_shellsafe(argv[i], sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } else { + int zero= 0; + + /* implementing mkisofs tendency to map single-path pathspecs to / */ + if((!xorriso->allow_graft_points) || + Fileliste__target_source_limit(argv[i], '=', &ept, 0)<=0) { + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, argv[i], + eff_path, 2|4); + if(ret<=0) + goto problem_handler_2; + ret= Sfile_type(eff_path, + 1|((xorriso->do_follow_param||xorriso->do_follow_links)<<2)); + if(ret==2) { + strcpy(pathspec, "/="); + } else { + pathspec[0]= '/'; + pathspec[1]= 0; + ret= Sfile_leafname(eff_path, pathspec+1, 0); + if(ret>0) + strcat(pathspec, "="); + else + pathspec[0]= 0; + } + strcat(pathspec, eff_path); + add_pt= pathspec; + } else + add_pt= argv[i]; + mem_graft_points= xorriso->allow_graft_points; + xorriso->allow_graft_points= 1; + ret= Xorriso_option_add(xorriso, 1, &add_pt, &zero, was_path<<1); + xorriso->allow_graft_points= mem_graft_points; + if(ret<=0) + goto problem_handler_2; + was_path= 1; + xorriso->pacifier_style= 1; + } + continue; /* regular bottom of loop */ +problem_handler_2:; + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + goto ex; + } + if(do_print_size) { + ret= Xorriso_option_print_size(xorriso, 1); + if(ret<=0) + goto ex; + } + if(lower_r) { + zero= 0; + ret= Xorriso_option_find(xorriso, 3, lower_r_args, &zero, 2); + if(ret<=0) + goto ex; + } + + for(j= 0; j < weight_count; j++) { + i= weight_list[j]; + /* find argv[i+2] -exec sort_weight argv[i+1] */ + zero= 0; + sort_weight_args[0]= argv[i + 2]; + sort_weight_args[3]= argv[i + 1]; + ret= Xorriso_option_find(xorriso, 4, sort_weight_args, &zero, 2); + if(ret > 0) + continue; + /* Problem handler */ + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + goto ex; + } + + /* After all pathspecs are added: perform boot related options */ + for(j= 0; j < boot_opt_count; j++) { + i= boot_opt_list[j]; + if(strcmp(argv[i], "-no-emul-boot")==0) { + no_emul_boot= 1; + } else if(strcmp(argv[i], "-boot-info-table")==0) { + xorriso->patch_isolinux_image= 1; + } else if(strcmp(argv[i], "-b") == 0 || + strcmp(argv[i], "-eltorito-boot") == 0 || + strcmp(argv[i], "--efi-boot") == 0) { + i++; + if(strcmp(argv[i - 1], "--efi-boot") == 0) { + if(xorriso->boot_image_bin_path[0]) { + ret= Xorriso_genisofs_add_boot(xorriso, whom, + &option_b, &no_emul_boot, 0); + if(ret <= 0) + goto problem_handler_boot; + } + boot_path= xorriso->boot_image_bin_path; + xorriso->boot_efi_default= 1; + } else { + boot_path= xorriso->boot_image_bin_path; + xorriso->boot_platform_id= 0x00; + xorriso->boot_efi_default= 0; + option_b= 1; + } + boot_path[0]= 0; + if(argv[i][0] != '/') + strcat(boot_path, "/"); + ret= Sfile_str(boot_path + strlen(boot_path), argv[i], 0); + if(ret <= 0) + goto ex; + if(xorriso->boot_efi_default && xorriso->boot_image_bin_path[0]) { + option_b= 0; + ret= Xorriso_genisofs_add_boot(xorriso, whom, + &option_b, &no_emul_boot, 0); + if(ret <= 0) + goto problem_handler_boot; + } + xorriso->keep_boot_image= 0; + } else if(strcmp(argv[i], "-c") == 0 || + strcmp(argv[i], "-eltorito-catalog") == 0) { + if(i+1>=argc) + goto not_enough_args; + i++; + xorriso->boot_image_cat_path[0]= 0; + if(argv[i][0] != '/') + strcat(xorriso->boot_image_cat_path, "/"); + ret= Sfile_str(xorriso->boot_image_cat_path + + strlen(xorriso->boot_image_cat_path), argv[i], 0); + if(ret <= 0) + goto ex; + } else if(strcmp(argv[i], "-boot-load-size") == 0) { + if(i+1>=argc) + goto not_enough_args; + i++; + sscanf(argv[i], "%d", &ret); + xorriso->boot_image_load_size= ret * 512; + } else if(strncmp(argv[i], "isolinux_mbr=", 13)==0) { + sprintf(sfe, "isohybrid=%s", argv[i] + 13); + ret= Xorriso_option_boot_image(xorriso, "isolinux", sfe, 0); + if(ret <= 0) + goto problem_handler_boot; + } else if(strcmp(argv[i], "-eltorito-alt-boot")==0) { + ret= Xorriso_genisofs_add_boot(xorriso, whom, + &option_b, &no_emul_boot, 0); + if(ret <= 0) + goto problem_handler_boot; + } else if(strcmp(argv[i], "--embedded-boot")==0 || + strcmp(argv[i], "-generic-boot")==0 || + strcmp(argv[i], "-G") == 0 || + strcmp(argv[i], "-isohybrid-mbr")==0) { + if(i+1>=argc) + goto not_enough_args; + i++; + ret= Xorriso_set_system_area_path(xorriso, argv[i], 0); + if(ret <= 0) + goto problem_handler_boot; + if(strcmp(argv[i - 1], "-isohybrid-mbr")==0) + xorriso->system_area_options= (xorriso->system_area_options & ~3) | 2; + } else if(strcmp(argv[i], "--protective-msdos-label")==0) { + xorriso->system_area_options= (xorriso->system_area_options & ~3) | 1; + } + continue; /* regular bottom of loop */ +problem_handler_boot:; + /* Problem handler */ + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + goto ex; + } + if(xorriso->boot_image_bin_path[0]) { + ret= Xorriso_genisofs_add_boot(xorriso, whom, &option_b, &no_emul_boot, 0); + if(ret <= 0) + goto ex; + } + + ret= !was_failure; +ex:; + if(was_path && !do_print_size) + Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count, + xorriso->pacifier_total, "", 1); + if(do_print_size && xorriso->volset_change_pending) + Xorriso_option_rollback(xorriso, 0); + if(weight_list != NULL) + free(weight_list); + if(boot_opt_list != NULL) + free(boot_opt_list); + return(ret); +} + + +int Xorriso_as_genisofs(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int end_idx, ret, idx_count, old_idx; + + old_idx= *idx; + end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); + (*idx)= end_idx; + idx_count= end_idx-old_idx; + if(end_idx<=0 || old_idx>=argc) + return(1); + ret= Xorriso_genisofs(xorriso, "genisofs", end_idx-old_idx, argv+old_idx, 0); + return(ret); +} + + +int Xorriso_as_cdrskin(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int end_idx, ret, idx_count, old_idx; + + old_idx= *idx; + end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); + (*idx)= end_idx; + idx_count= end_idx-old_idx; + if(end_idx<=0 || old_idx>=argc) + return(1); + ret= Xorriso_cdrskin(xorriso, "cdrskin", end_idx-old_idx, argv+old_idx, 0); + return(ret); +} + diff --git a/xorriso/emulators.h b/xorriso/emulators.h new file mode 100644 index 00000000..c6799f67 --- /dev/null +++ b/xorriso/emulators.h @@ -0,0 +1,34 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/filters.c b/xorriso/filters.c new file mode 100644 index 00000000..b5c3e940 --- /dev/null +++ b/xorriso/filters.c @@ -0,0 +1,694 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains functions which operate on data filter objects. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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); +} + diff --git a/xorriso/filters.h b/xorriso/filters.h new file mode 100644 index 00000000..1be6db84 --- /dev/null +++ b/xorriso/filters.h @@ -0,0 +1,31 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/findjob.c b/xorriso/findjob.c new file mode 100644 index 00000000..1ccdc2de --- /dev/null +++ b/xorriso/findjob.c @@ -0,0 +1,1178 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains the implementation of classes FindjoB, ExprnodE, + ExprtesT which perform tree searches in libisofs or in POSIX filesystem +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "xorriso.h" +#include "xorriso_private.h" +#include "xorrisoburn.h" + + +/* ----------------------- Exprtest ----------------------- */ + + +int Exprtest_new( struct ExprtesT **ftest, struct FindjoB *boss, int flag) +{ + struct ExprtesT *f; + + *ftest= f= TSOB_FELD(struct ExprtesT,1); + if(f==NULL) + return(-1); + f->boss= boss; + f->invert= 0; + f->test_type= -1; + f->arg1= NULL; + f->arg2= NULL; + return(1); +} + + +int Exprtest_destroy(struct ExprtesT **ftest, int flag) +{ + struct ExprtesT *f; + + f= *ftest; + if(f==NULL) + return(0); + + if(f->test_type == 1) { + if(f->arg1 != NULL) + free(f->arg1); + if(f->arg2 != NULL) { + regfree(f->arg2); + free(f->arg2); + } + } else if(f->test_type == 9) { + /* arg1 is not an allocated value */; + } else { + if(f->arg1 != NULL) + free(f->arg1); + if(f->arg2 != NULL) + free(f->arg2); + } + free((char *) f); + *ftest= NULL; + return(1); +} + + +/* ----------------------- Nttpfnode ----------------------- */ + + +int Exprnode_new(struct ExprnodE **fnode, struct FindjoB *job, + struct ExprnodE *up, char *origin, int flag) +/* + bit0= set invert-property + bit1= set use_shortcuts +*/ +{ + struct ExprnodE *n; + int ret,i; + + *fnode= n= TSOB_FELD(struct ExprnodE,1); + if(n == NULL) + return(-1); + for(i= 0; i < sizeof(n->origin); i++) + n->origin[i]= 0; + strncpy(n->origin, origin, sizeof(n->origin) - 1); + n->up= up; + n->invert= (flag & 1); + n->assoc= 0; + n->use_shortcuts= !!(flag & 2); + n->left= NULL; + n->left_op= -1; + n->right= NULL; + n->right_op= -1; + n->sub= NULL; + n->is_if_then_else= 0; + n->true_branch= NULL; + n->false_branch= NULL; + n->test= NULL; + n->own_value= -1; + n->composed_value= -1; + + ret= Exprtest_new(&(n->test), job, 0); + if(ret<=0){ + Exprnode_destroy(fnode, 0); + return(-1); + } + return(1); +} + + +int Exprnode_destroy(struct ExprnodE **fnode, int flag) +{ + if(*fnode == NULL) + return(0); + Exprnode_destroy(&((*fnode)->right),0); + Exprnode_destroy(&((*fnode)->sub),0); + Exprnode_destroy(&((*fnode)->true_branch),0); + Exprnode_destroy(&((*fnode)->false_branch),0); + Exprtest_destroy(&((*fnode)->test),0); + free((char *) *fnode); + *fnode= NULL; + return(1); +} + + +int Exprnode_set_is_if(struct ExprnodE *fnode, int value, int flag) +{ + fnode->is_if_then_else= value; + return(1); +} + + +int Exprnode_is_if(struct ExprnodE *fnode, int flag) +{ + return(fnode->is_if_then_else); +} + + +int Exprnode_set_branch(struct ExprnodE *fnode, struct ExprnodE *target, + int flag) +/* + bit0= false_branch (else true_branch) +*/ +{ + struct ExprnodE **branch; + + if(flag&1) + branch= &(fnode->false_branch); + else + branch= &(fnode->true_branch); + Exprnode_destroy(branch,0); + (*branch)= target; + return(1); +} + + +int Exprnode_get_branch(struct ExprnodE *fnode, struct ExprnodE **branch, + int flag) +/* + bit0= false_branch (else true_branch) +*/ +{ + if(flag&1) + (*branch)= fnode->false_branch; + else + (*branch)= fnode->true_branch; + return(1); +} + + +int Exprnode_is_defined(struct ExprnodE *fnode, int flag) +{ + struct ExprtesT *ftest; + + if(fnode==NULL) + return(0); + if(fnode->sub!=NULL) + return(1); + ftest= fnode->test; + if(ftest==NULL) + return(0); + if(ftest->test_type>=0) + return(1); + return(0); +} + + +int Exprnode_own_value(struct XorrisO *xorriso, struct ExprnodE *fnode, + void *node, char *name, char *path, + struct stat *boss_stbuf, struct stat *stbuf, int flag) +/* +flag: +return: (also from Exprtest_match() and Exprnode_tree_value() ) + <0 = error + 0 = does not match + 1 = does match + 2 = immediate decision : does not match + 3 = immediate decision : does match +*/ +{ + int ret; + + if(fnode==NULL) + return(1); + if(fnode->sub!=NULL) { + ret= Exprnode_tree_value(xorriso, fnode->sub, -1, + node, name, path, boss_stbuf, stbuf, 0); + } else { + ret= Exprtest_match(xorriso, fnode->test, node, name, path, + boss_stbuf, stbuf, 0); + } + if(ret<0) + return(ret); + if(ret>1) + return(ret); + if(fnode->invert) + ret= !ret; + return(ret); +} + + +int Exprnode_op(int value1, int value2, int op, int flag) +{ + int ret; + + if(op==0) + ret= value1 || value2 ; + else + ret= value1 && value2 ; + return(ret); +} + + +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) +/* + bit0-7= testmode: 0=head , 1=filename +return: (also from Nntpftest_match() and Nntpfnode_own_value() ) + <0 = error + 0 = does not match + 1 = does match + 2 = immediate decision : does not match + 3 = immediate decision : does match +*/ +{ + int value= 1,ret; + + if(fnode==NULL) + return(1); + if(!Exprnode_is_defined(fnode,0)) + return(1); + + if(fnode->use_shortcuts && fnode->left!=NULL){ + fnode->composed_value= left_value; + if(fnode->left_op==0) {/* OR */ + if(left_value!=0) + goto ex; + } else { /* AND */ + if(left_value==0) + goto ex; + } + } + fnode->composed_value= fnode->own_value= + Exprnode_own_value(xorriso, fnode, node, name, path, boss_stbuf, stbuf, 0); + if(fnode->own_value < 0 || fnode->own_value > 1) + return(fnode->own_value); + + if(fnode->assoc == 0){ /* left associative */ + if(fnode->left != NULL && left_value >= 0) + fnode->composed_value= + Exprnode_op(left_value, fnode->own_value, fnode->left_op, 0); + /* compute right value */ + /* is the right value relevant ? */ + if(fnode->right!=NULL){ + if(fnode->use_shortcuts){ + if(fnode->right_op==0) {/* OR */ + if(fnode->composed_value!=0) + goto ex; + } else { /* AND */ + if(fnode->composed_value==0) + goto ex; + } + } + value= Exprnode_tree_value(xorriso, fnode->right,fnode->composed_value, + node, name, path, boss_stbuf, stbuf, 0); + if(value<0 || value>1) + return(value); + fnode->composed_value= value; + } + }else{ /* right associative */ + if(fnode->right!=NULL){ + /* is the right value relevant ? */ + if(fnode->use_shortcuts){ + if(fnode->right_op==0) {/* OR */ + if(fnode->composed_value!=0) + goto ex; + } else { /* AND */ + if(fnode->composed_value==0) + goto ex; + } + } + value= Exprnode_tree_value(xorriso, fnode->right,fnode->own_value, + node, name, path, boss_stbuf, stbuf, 0); + if(value<0||value>1) + return(value); + } else + value= fnode->own_value; + fnode->composed_value= value; + if(fnode->left!=NULL && left_value>=0) + fnode->composed_value= + Exprnode_op(left_value,fnode->composed_value,fnode->left_op,0); + } +ex: + ret= fnode->composed_value; + if(fnode->is_if_then_else) { + /* The if-condition is evaluated. Now follow the chosen branch */ + struct ExprnodE *branch; + if(ret>0) + branch= fnode->true_branch; + else + branch= fnode->false_branch; + if(branch!=NULL) { + ret= Exprnode_tree_value(xorriso, branch, -1, + node, name, path, boss_stbuf, stbuf, 0); + if(ret<0) + return(ret); + if(ret>1) + return(ret); + } + fnode->composed_value= ret; + } + return(fnode->composed_value); +} + + +/* --------------------- Findjob -------------------- */ + + +int Findjob_new(struct FindjoB **o, char *start_path, int flag) +{ + struct FindjoB *m; + int ret; + + m= *o= TSOB_FELD(struct FindjoB,1); + if(m==NULL) + return(-1); + m->start_path= NULL; + m->test_tree= NULL; + m->cursor= NULL; + m->invert= 0; + m->use_shortcuts= 1; + m->action= 0; /* print */ + m->prune= 0; + m->target= NULL; /* a mere pointer, not managed memory */ + m->text_2= NULL; /* a mere pointer, not managed memory */ + m->user= 0; + m->group= 0; + m->type= 0; + m->date= 0; + m->start_path= strdup(start_path); + if(m->start_path==NULL) + goto failed; + m->found_path= NULL; + m->subjob= NULL; + + ret= Exprnode_new(&(m->test_tree), m, NULL, "-find", (m->use_shortcuts)<<1); + if(ret<=0) + goto failed; + m->cursor= m->test_tree; + return(1); + +failed:; + Findjob_destroy(o, 0); + return(-1); +} + + +int Findjob_destroy(struct FindjoB **o, int flag) +{ + struct FindjoB *m; + + m= *o; + if(m==NULL) + return(0); + if(m->test_tree != NULL) + Exprnode_destroy(&(m->test_tree), 0); + if(m->start_path != NULL) + free(m->start_path); + free((char *) *o); + *o= NULL; + return(1); +} + + +int Findjob_set_start_path(struct FindjoB *o, char *start_path, int flag) +{ + if(o->start_path!=NULL) + free(o->start_path); + if(start_path!=NULL) { + o->start_path= strdup(start_path); + if(o->start_path==NULL) + return(-1); + } else + o->start_path= NULL; + return(1); +} + + +int Findjob_get_start_path(struct FindjoB *o, char **start_path, int flag) +{ + *start_path= o->start_path; + return(1); +} + + +int Findjob_cursor_complete( struct FindjoB *job, int flag) +{ + int ret; + + if(job==NULL) + return(0); + ret= Exprnode_is_defined(job->cursor,0); + return(ret); +} + + +int Findjob_is_restrictive(struct FindjoB *job, int flag) +{ + if(job == NULL) + return(0); + if(job->test_tree == NULL) + return(0); + if(!Exprnode_is_defined(job->test_tree, 0)) + return(0); + return(1); +} + + +int Findjob_new_node(struct FindjoB *job, struct ExprnodE **fnode, + char *origin, int flag) +/* + bit0= open new branch + bit1= with bit1 : do not register as sub-node of job->cursor +*/ +{ + int ret; + struct ExprnodE *f; + + ret= Exprnode_new(fnode,job,NULL,origin, + job->invert|((job->use_shortcuts)<<1)); + if(ret<=0) + return(ret); + f= *fnode; + if(flag&1) { + f->up= job->cursor; + if(job->cursor!=NULL && !(flag&2)) { + if(job->cursor->sub!=NULL) { + /* This would become a memory leak */ + job->errn= -2; + sprintf(job->errmsg, + "Program error while parsing -job : sub branch overwrite"); + return(0); + } else + job->cursor->sub= f; + } + } else { + f->up= job->cursor->up; + f->left= job->cursor; + if(job->cursor!=NULL) + job->cursor->right= f; + } + job->invert= 0; + return(1); +} + + +/* If an operator is expected : use -and + @param flag bit0= prepare for a pseudo-test: + if an operator is expected, do nothing and return 2 +*/ +int Findjob_default_and(struct FindjoB *o, int flag) +{ + int ret; + + if(Findjob_cursor_complete(o, 0)) { + if(flag & 1) + return(2); + ret= Findjob_and(o, 0); + if(ret <= 0) + return(ret); + } + return(1); +} + + +int Findjob_open_bracket(struct FindjoB *job, int flag) +{ + int ret; + struct ExprnodE *fnode; + + ret= Findjob_default_and(job, 0); + if(ret <= 0) + return(ret); + ret= Findjob_new_node(job, &fnode, "-sub", 1); + if(ret <= 0) + return(ret); + job->cursor= fnode; + return(1); +} + + +int Findjob_close_bracket(struct FindjoB *job, int flag) +{ + if(!Findjob_cursor_complete(job, 0)) { + job->errn= -3; + sprintf(job->errmsg, + "Unary operator or expression expected, closing-bracket found"); + return(0); + } + + if(job->cursor->up==NULL){ + job->errn= -1; + sprintf(job->errmsg, + "No bracket open when encountering closing bracket."); + return(0); + } + job->cursor= job->cursor->up; + return(1); +} + + +int Findjob_not(struct FindjoB *job, int flag) +{ + int ret; + + ret= Findjob_default_and(job, 0); + if(ret <= 0) + return(ret); + job->cursor->invert= !job->cursor->invert; + return(1); +} + + +int Findjob_and(struct FindjoB *job, int flag) +{ + int ret; + struct ExprnodE *fnode; + + if(!Findjob_cursor_complete(job, 0)) { + job->errn= -3; + sprintf(job->errmsg, + "Unary operator or expression expected, binary operator found"); + return(0); + } + + ret= Findjob_new_node(job, &fnode, "-and", 0); + if(ret<=0) + return(ret); + job->cursor->right_op= 1; + job->cursor->assoc= 1; /* compute right side first */ + fnode->left_op= 1; + fnode->assoc= 0; /* compute left side first */ + job->cursor= fnode; + return(1); +} + + +int Findjob_or(struct FindjoB *job, int flag) +{ + int ret; + struct ExprnodE *fnode; + + if(!Findjob_cursor_complete(job, 0)) { + job->errn= -3; + sprintf(job->errmsg, + "Unary operator or expression expected, binary operator found"); + return(0); + } + + ret= Findjob_new_node(job, &fnode, "-or", 0); + if(ret<=0) + return(ret); + job->cursor->right= fnode; + job->cursor->right_op= 0; + /* if existing : compute left side first */ + job->cursor->assoc= (job->cursor->left == NULL); + fnode->left= job->cursor; + fnode->left_op= 0; + fnode->assoc= 0; /* no right side yet : compute left side first */ + job->cursor= fnode; + return(1); +} + + +int Findjob_if(struct FindjoB *job, int flag) +{ + int ret; + struct ExprnodE *fnode; + + ret= Findjob_default_and(job, 0); + if(ret <= 0) + return(ret); + ret= Findjob_new_node(job, &fnode, "-if", 1); + if(ret<=0) + return(ret); + Exprnode_set_is_if(fnode,1,0); + job->cursor= fnode; + return(1); +} + + +int Findjob_then(struct FindjoB *job, int flag) +{ + int ret; + struct ExprnodE *fnode,*branch= NULL; + + if(! Findjob_cursor_complete(job,0)) { + job->errn= -3; + sprintf(job->errmsg, + "Unary operator or expression expected, -then-operator found"); + return(0); + } + /* Finding the -if that matches this -then + Do not go up one node but look for the leftmost one. + If everything is right we are at level of the -if node */ + while(job->cursor->left!=NULL) + job->cursor= job->cursor->left; + Exprnode_get_branch(job->cursor, &branch, 0); + if(!Exprnode_is_if(job->cursor, 0) || branch != NULL) { + job->errn= -5; + sprintf(job->errmsg, "-then-operator found outside its proper range."); + return(0); + } + ret= Findjob_new_node(job, &fnode, "-then", 1|2); + if(ret <= 0) + return(ret); + Exprnode_set_branch(job->cursor, fnode, 0); + job->cursor= fnode; + return(1); +} + + +int Findjob_else(struct FindjoB *job, int flag) +{ + int ret; + struct ExprnodE *fnode, *true_branch, *false_branch; + + if(! Findjob_cursor_complete(job, 0)) { + job->errn= -3; + sprintf(job->errmsg, + "Unary operator or expression expected, -else-operator found"); + return(0); + } + if(job->cursor->up == NULL) + goto improper_range; + job->cursor= job->cursor->up; + Exprnode_get_branch(job->cursor, &true_branch, 0); + Exprnode_get_branch(job->cursor, &false_branch, 1); + if(!Exprnode_is_if(job->cursor, 0) || + true_branch == NULL || false_branch != NULL) { +improper_range:; + job->errn= -5; + sprintf(job->errmsg, "-else-operator found outside its proper range."); + return(0); + } + ret= Findjob_new_node(job, &fnode, "-else", 1 | 2); + if(ret <= 0) + return(ret); + Exprnode_set_branch(job->cursor, fnode, 1); + job->cursor= fnode; + return(1); +} + + +int Findjob_elseif(struct FindjoB *job, int flag) +{ + int ret; + struct ExprnodE *true_branch, *false_branch; + + if(!Findjob_cursor_complete(job, 0)) { + job->errn= -3; + sprintf(job->errmsg, + "Unary operator or expression expected, -elseif-operator found"); + return(0); + } + if(job->cursor->up == NULL) + goto improper_range; + job->cursor= job->cursor->up; + Exprnode_get_branch(job->cursor, &true_branch, 0); + Exprnode_get_branch(job->cursor, &false_branch, 1); + if(!Exprnode_is_if(job->cursor, 0) || + true_branch==NULL || false_branch!=NULL) { +improper_range:; + job->errn= -5; + sprintf(job->errmsg, + "-elseif-operator found outside its proper range."); + return(0); + } + job->cursor= job->cursor->up; + /* -elseif is equivalent to the three-step sequence : -endif -or -if + ( -endif has already been performed by following job->cursor->up ) */ + ret= Findjob_or(job, 0); + if(ret <= 0) + return(0); + ret= Findjob_if(job, 0); + if(ret <= 0) + return(0); + return(1); +} + + +int Findjob_endif(struct FindjoB *job, int flag) +{ + struct ExprnodE *true_branch; + + if(!Findjob_cursor_complete(job,0)) { + job->errn= -3; + sprintf(job->errmsg, + "Unary operator or expression expected, -endif found"); + return(0); + } + if(job->cursor->up==NULL) + goto improper_range; + /* test wether parent node is -if */ + job->cursor= job->cursor->up; + Exprnode_get_branch(job->cursor, &true_branch, 0); + if(!Exprnode_is_if(job->cursor,0) || true_branch == NULL) { +improper_range:; + job->errn= -5; + sprintf(job->errmsg, "-endif-mark found outside its proper range."); + return(0); + } + /* go to grand parent node */ + job->cursor= job->cursor->up; + return(1); +} + + +/* @param flag bit0= -wholename rather than -name +*/ +int Findjob_set_name_expr(struct FindjoB *o, char *name_expr, int flag) +{ + char regexpr[2*SfileadrL+2]; + regex_t *name_re; + struct ExprtesT *t; + int ret; + + if(strlen(name_expr)>=SfileadrL) + return(0); + + ret= Findjob_default_and(o, 0); + if(ret <= 0) + return(ret); + t= o->cursor->test; + t->test_type= (flag & 1 ? 13 : 1); + name_re= (regex_t *) calloc(1, sizeof(regex_t)); + if(name_re == NULL) + return(-1); + t->arg1= strdup(name_expr); + if(t->arg1 == NULL) { + free((char *) name_re); + return(-1); + } + Xorriso__bourne_to_reg(name_expr, regexpr, 0); + if(regcomp(name_re, regexpr, 0) != 0) + return(0); + t->arg2= name_re; + return(1); +} + + +int Findjob_set_file_type(struct FindjoB *o, char file_type, int flag) +{ + static char known[]= {"bcdpf-lsmeX"}; + struct ExprtesT *t; + int ret; + + ret= Findjob_default_and(o, 0); + if(ret <= 0) + return(ret); + + if(file_type != 0) + if(strchr(known, file_type) == NULL) + return(0); + t= o->cursor->test; + t->test_type= 2; + t->arg1= calloc(1, 1); + if(t->arg1 == NULL) + return(-1); + *((char *) t->arg1)= file_type; + return(1); +} + + +/* @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) +{ + struct ExprtesT *t; + int ret; + + ret= Findjob_default_and(o, flag & 1); + if(ret <= 0 || ret == 2) + return(ret); + + t= o->cursor->test; + t->test_type= test_type; + if(value < 0) + t->invert= !t->invert; + return(1); +} + + +/* @param value -1= only undamaged files, 1= only damaged files +*/ +int Findjob_set_damage_filter(struct FindjoB *o, int value, int flag) +{ + int ret; + + ret= Findjob_set_prop_filter(o, 3, value, 0); + return(ret); +} + + +int Findjob_set_lba_range(struct FindjoB *o, int start_lba, int count, + int flag) +{ + struct ExprtesT *t; + int ret; + + ret= Findjob_default_and(o, 0); + if(ret <= 0) + return(ret); + + t= o->cursor->test; + t->test_type= 4; + t->arg1= calloc(sizeof(int), 1); + t->arg2= calloc(sizeof(int), 1); + if(t->arg1 == NULL || t->arg2 == NULL) + return(-1); + *((int *) t->arg1)= start_lba; + if(start_lba > 0) + *((int *) t->arg2)= start_lba + count - 1; + else + *((int *) t->arg2)= start_lba - count + 1; + return(1); +} + + +/* @param value -1= files without ACL, 1= only files with ACL +*/ +int Findjob_set_acl_filter(struct FindjoB *o, int value, int flag) +{ + int ret; + + ret= Findjob_set_prop_filter(o, 5, value, 0); + return(ret); +} + + +/* @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) +{ + int ret; + + ret= Findjob_set_prop_filter(o, (flag & 1 ? 14 : 6), value, 0); + return(ret); +} + + +/* @param value -1= files without aaip, 1= only files with aaip +*/ +int Findjob_set_aaip_filter(struct FindjoB *o, int value, int flag) +{ + int ret; + + ret= Findjob_set_prop_filter(o, 7, value, 0); + return(ret); +} + + +/* @param value -1= files without filter, 1= files with filter +*/ +int Findjob_set_filter_filter(struct FindjoB *o, int value, int flag) +{ + int ret; + + ret= Findjob_set_prop_filter(o, 8, value, 0); + return(ret); +} + + +int Findjob_set_wanted_node(struct FindjoB *o, void *wanted_node, int flag) +{ + struct ExprtesT *t; + int ret; + + ret= Findjob_default_and(o, 0); + if(ret <= 0) + return(ret); + + t= o->cursor->test; + t->test_type= 9; + t->arg1= wanted_node; + return(1); +} + + +int Findjob_set_commit_filter_2(struct FindjoB *o, int flag) +{ + int ret; + + ret= Findjob_default_and(o, 0); + if(ret <= 0) + return(ret); + + o->cursor->test->test_type= 10; + return(1); +} + + +int Findjob_set_decision(struct FindjoB *o, char *decision, int flag) +{ + struct ExprtesT *t; + int ret; + + ret= Findjob_default_and(o, 0); + if(ret <= 0) + return(ret); + + t= o->cursor->test; + t->test_type= 11; + t->arg1= strdup(decision); + if(t->arg1 == NULL) + return(-1); + return(1); +} + + +/* @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 ret; + + ret= Findjob_set_prop_filter(o, 0, value, flag & 1); + return(ret); +} + + +int Findjob_set_prune(struct FindjoB *o, int flag) +{ + int ret; + + ret= Findjob_set_prop_filter(o, 12, 0, 0); + return(ret); +} + + +int Findjob_set_found_path(struct FindjoB *o, char *path, int flag) +{ + if(o->found_path != NULL) + free(o->found_path); + if(path != NULL) { + o->found_path= strdup(path); + if(o->found_path == NULL) + return(-1); + } else + o->found_path= NULL; + return(1); +} + + +int Findjob_get_found_path(struct FindjoB *o, char **path, int flag) +{ + *path= o->found_path; + return(1); +} + + +int Findjob_get_action(struct FindjoB *o, int flag) +{ + return(o->action); +} + + +/* @return <0 error, >=0 see above 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) +{ + *target= o->target; + *text_2= o->text_2; + *user= o->user; + *group= o->group; + *mode_and= o->mode_and; + *mode_or= o->mode_or; + *type= o->type; + *date= o->date; + *subjob= o->subjob; + return(o->action); +} + + +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 ret; + + ret= Exprnode_tree_value(xorriso, o->test_tree, -1, + node, name, path, boss_stbuf, stbuf, 0); + if(ret == 3) + ret= 1; + else if(ret == 2) + ret= 0; + return(ret); +} + + +int Findjob_set_action_target(struct FindjoB *o, int action, char *target, + int flag) +{ + o->action= action; + o->target= target; + return(1); +} + + +int Findjob_set_action_type(struct FindjoB *o, int action, int type, + int flag) +{ + o->action= action; + o->type= type; + return(1); +} + + +int Findjob_set_action_text_2(struct FindjoB *o, int action, char *target, + char* text_2, int flag) +{ + o->action= action; + o->target= target; + o->text_2= text_2; + return(1); +} + + +/* @param flag bit0= recursive +*/ +int Findjob_set_action_chown(struct FindjoB *o, uid_t user,int flag) +{ + int ret; + + if(flag&1) { + o->action= 0; + Findjob_destroy(&(o->subjob), 0); + ret= Findjob_new(&(o->subjob), "", 0); + if(ret<=0) + return(-1); + Findjob_set_action_chown(o->subjob, user, 0); + o->action= 9; + } else { + o->action= 4; + o->user= user; + } + return(1); +} + + +/* @param flag bit0= recursive +*/ +int Findjob_set_action_chgrp(struct FindjoB *o, gid_t group, int flag) +{ + int ret; + + if(flag&1) { + o->action= 0; + Findjob_destroy(&(o->subjob), 0); + ret= Findjob_new(&(o->subjob), "", 0); + if(ret<=0) + return(-1); + Findjob_set_action_chgrp(o->subjob, group, 0); + o->action= 10; + } else { + o->action= 5; + o->group= group; + } + return(1); +} + + +/* @param flag bit0= recursive +*/ +int Findjob_set_action_chmod(struct FindjoB *o, + mode_t mode_and, mode_t mode_or, int flag) +{ + int ret; + + if(flag&1) { + o->action= 0; + Findjob_destroy(&(o->subjob), 0); + ret= Findjob_new(&(o->subjob), "", 0); + if(ret<=0) + return(-1); + Findjob_set_action_chmod(o->subjob, mode_and, mode_or, 0); + o->action= 11; + } else { + o->action= 6; + o->mode_and= mode_and; + o->mode_or= mode_or; + } + return(1); +} + + +/* @param flag bit0= recursive +*/ +int Findjob_set_action_ad(struct FindjoB *o, int type, time_t date, int flag) +{ + int ret; + + if(flag&1) { + o->action= 0; + Findjob_destroy(&(o->subjob), 0); + ret= Findjob_new(&(o->subjob), "", 0); + if(ret<=0) + return(-1); + Findjob_set_action_ad(o->subjob, type, date, 0); + o->action= 12; + } else { + o->action= 7; + o->type= type; + o->date= date; + } + return(1); +} + + +int Findjob_set_action_subjob(struct FindjoB *o, int action, + struct FindjoB *subjob, int flag) +{ + o->action= action; + Findjob_destroy(&(o->subjob), 0); + o->subjob= subjob; + return(1); +} + + +int Findjob_set_action_found_path(struct FindjoB *o, int flag) +{ + o->action= 23; + Findjob_set_found_path(o, NULL, 0); + return(1); +} + diff --git a/xorriso/findjob.h b/xorriso/findjob.h new file mode 100644 index 00000000..4e8de633 --- /dev/null +++ b/xorriso/findjob.h @@ -0,0 +1,400 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/iso_img.c b/xorriso/iso_img.c new file mode 100644 index 00000000..02db9db7 --- /dev/null +++ b/xorriso/iso_img.c @@ -0,0 +1,950 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains functions which operate on ISO images and their + global properties. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#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); +} + diff --git a/xorriso/iso_img.h b/xorriso/iso_img.h new file mode 100644 index 00000000..33f260ed --- /dev/null +++ b/xorriso/iso_img.h @@ -0,0 +1,44 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/iso_manip.c b/xorriso/iso_manip.c new file mode 100644 index 00000000..28898107 --- /dev/null +++ b/xorriso/iso_manip.c @@ -0,0 +1,2637 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains functions which manipulate the libisofs tree model. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "xorriso.h" +#include "xorriso_private.h" +#include "xorrisoburn.h" + +#include "lib_mgt.h" +#include "iso_img.h" +#include "iso_tree.h" +#include "iso_manip.h" +#include "sort_cmp.h" + + + +/* @param flag bit0= give directory x-permission where is r-permission + bit1= do not transfer ACL or xattr + bit2= record dev,inode (only if enabled by xorriso) + bit5= transfer ACL or xattr from eventual link target +*/ +int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf, + char *disk_path, IsoNode *node, int flag) +{ + mode_t mode; + int ret= 1; + size_t num_attrs= 0, *value_lengths= NULL; + char **names= NULL, **values= NULL; + + mode= stbuf->st_mode; + + if((!(flag & 2)) && !(xorriso->do_aaip & 1)) + /* Will drop ACL. Update mode S_IRWXG by eventual group:: ACL entry */ + iso_local_get_perms_wo_acl(disk_path, &mode, flag & 32); + + if((flag&1) && S_ISDIR(mode)) { + if(mode&S_IRUSR) + mode|= S_IXUSR; + if(mode&S_IRGRP) + mode|= S_IXGRP; + if(mode&S_IROTH) + mode|= S_IXOTH; + } + iso_node_set_permissions(node, mode & 07777); + iso_node_set_uid(node, stbuf->st_uid); + iso_node_set_gid(node, stbuf->st_gid); + iso_node_set_atime(node, stbuf->st_atime); + iso_node_set_mtime(node, stbuf->st_mtime); + iso_node_set_ctime(node, stbuf->st_ctime); + + if((xorriso->do_aaip & 5) && !(flag & 2)) { + ret= iso_local_get_attrs(disk_path, &num_attrs, &names, &value_lengths, + &values, ((xorriso->do_aaip & 1) && !(flag & 2)) + | ((!(xorriso->do_aaip & 4)) << 2) + | (flag & 32)); + if(ret < 0) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_report_iso_error(xorriso, disk_path, ret, + "Error when obtaining local ACL and xattr", 0, + "FAILURE", 1 | 2); + ret= 0; goto ex; + } + ret= iso_node_set_attrs(node, num_attrs, names, value_lengths, values, + 1 | 8); + if(ret < 0) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_report_iso_error(xorriso, "", ret, + "Error when setting ACL and xattr to image node", + 0, "FAILURE", 1); + ret= 0; goto ex; + } + } + + if((flag & 4) && ((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2))) { + ret= Xorriso_record_dev_inode(xorriso, disk_path, (dev_t) 0, (ino_t) 0, + (void *) node, "", flag & 32); + if(ret <= 0) + goto ex; + } + + ret= 1; +ex:; + Xorriso_process_msg_queues(xorriso,0); + iso_local_get_attrs(disk_path, &num_attrs, &names, &value_lengths, + &values, 1 << 15); /* free memory */ + return(ret); +} + + +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 ret; + IsoDir *new_dir= NULL; + IsoNode *part_node; + int partno, total_parts; + off_t offset; + char part_name[SfileadrL], sfe[5*SfileadrL]; + + ret= iso_tree_add_new_dir(dir, img_name, &new_dir); + if(ret<0) + return(ret); + *node= (IsoNode *) new_dir; + total_parts= size / xorriso->split_size; + if(size % xorriso->split_size) + total_parts++; + for(partno= 1; partno<=total_parts; partno++) { + offset = xorriso->split_size * (off_t) (partno-1); + Splitpart__compose(part_name, partno, total_parts, offset, + xorriso->split_size, size, 0); + ret= Xorriso_tree_graft_node(xorriso, volume, + new_dir, disk_path, part_name, + nominal_source, nominal_target, + offset, xorriso->split_size, + &part_node, 8); + if(ret<=0) + return(0); + } + sprintf(xorriso->info_text, "Split into %d parts: %s", + total_parts, Text_shellsafe(nominal_target, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(1); +} + + +/* + @param flag bit3= cut_out_node: offset and size are valid +*/ +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 ret, stbuf_valid= 0; + struct stat stbuf; + char sfe[5*SfileadrL]; + off_t size= 0; + + if(lstat(disk_path, &stbuf) != -1) { + stbuf_valid= 1; + if(S_ISREG(stbuf.st_mode)) + size= stbuf.st_size; + } + if(flag&8) { + if(cut_size > xorriso->file_size_limit && xorriso->file_size_limit > 0) { + sprintf(xorriso->info_text, + "File piece exceeds size limit of %.f bytes: %.f from %s\n", + (double) xorriso->file_size_limit, (double) cut_size, + Text_shellsafe(disk_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= iso_tree_add_new_cut_out_node(volume, dir, img_name, disk_path, + offset, cut_size, node); + if(ret<0) + goto ex; + } else { + if(xorriso->split_size > 0 && size > xorriso->split_size) { + ret= Xorriso_graft_split(xorriso, volume, dir, disk_path, img_name, + nominal_source, nominal_target, size, + node, 0); + if(ret<=0) + goto ex; + } else if(size > xorriso->file_size_limit && xorriso->file_size_limit > 0) { + sprintf(xorriso->info_text, + "File exceeds size limit of %.f bytes: %s\n", + (double) xorriso->file_size_limit, + Text_shellsafe(disk_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } else { + ret= iso_tree_add_new_node(volume, dir, img_name, disk_path, node); + if(ret<0) + goto ex; + } + } + + if(stbuf_valid && ((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2))) { + ret= Xorriso_record_dev_inode(xorriso, disk_path, + stbuf.st_dev, stbuf.st_ino, (void *) *node, "", 1); + if(ret <= 0) + goto ex; + } + +ex:; + if(ret<0) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_report_iso_error(xorriso, nominal_source, ret, + "Cannot add node to tree", 0, "FAILURE", 1|2); + return(ret); + } + if(LIBISO_ISREG(*node)) + xorriso->pacifier_byte_count+= iso_file_get_size((IsoFile *) *node); + return(1); +} + + +/* @param flag bit0= recursion is active + bit1= do not report added files + bit6= do not delete eventually existing node from di_array + bit7= no special handling of split file directories +*/ +int Xorriso_add_tree(struct XorrisO *xorriso, IsoDir *dir, + char *img_dir_path, char *disk_dir_path, + struct LinkiteM *link_stack, int flag) +{ + IsoImage *volume; + IsoNode *node; + int ret, target_is_dir, source_is_dir, source_is_link, fret, was_failure= 0; + int do_not_dive, target_is_split= 0; + struct DirseQ *dirseq= NULL; + char *name, *img_name, *srcpt, *stbuf_src= ""; + struct stat stbuf, hstbuf; + dev_t dir_dev; + struct LinkiteM *own_link_stack; + char *sfe= NULL, *sfe2= NULL; + char *disk_path= NULL, *img_path= NULL, *link_target= NULL; + + /* Avoiding large local memory objects in order to save stack space */ + sfe= malloc(5*SfileadrL); + sfe2= malloc(5*SfileadrL); + disk_path= malloc(2*SfileadrL); + img_path= malloc(2*SfileadrL); + link_target= calloc(SfileadrL, 1); + if(sfe==NULL || sfe2==NULL || disk_path==NULL || img_path==NULL || + link_target==NULL) { + Xorriso_no_malloc_memory(xorriso, &sfe, 0); + {ret= -1; goto ex;} + } + + own_link_stack= link_stack; + + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + goto ex; + + stbuf_src= disk_dir_path; + if(lstat(disk_dir_path, &stbuf)==-1) + goto cannot_open_dir; + dir_dev= stbuf.st_dev; + if(S_ISLNK(stbuf.st_mode)) { + if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1)))) + {ret= 2; goto ex;} + stbuf_src= disk_dir_path; + if(stat(disk_dir_path, &stbuf)==-1) + goto cannot_open_dir; + if(dir_dev != stbuf.st_dev && + !(xorriso->do_follow_mount || (xorriso->do_follow_param && !(flag&1)))) + {ret= 2; goto ex;} + } + ret= Dirseq_new(&dirseq, disk_dir_path, 1); + if(ret<0) { + sprintf(xorriso->info_text,"Failed to create source filesystem iterator"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + {ret= -1; goto ex;} + } + if(ret==0) { +cannot_open_dir:; + Xorriso_msgs_submit(xorriso, 0, disk_dir_path, 0, "ERRFILE", 0); + sprintf(xorriso->info_text,"Cannot open as source directory: %s", + Text_shellsafe(disk_dir_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + + if(Sfile_str(disk_path, disk_dir_path,0)<=0) + {ret= -1; goto ex;} + if(disk_path[0]==0 || disk_path[strlen(disk_path)-1]!='/') + strcat(disk_path,"/"); + name= disk_path+strlen(disk_path); + if(Sfile_str(img_path, img_dir_path, 0)<=0) + {ret= -1; goto ex;} + if(img_path[0] || img_path[strlen(img_path)-1]!='/') + strcat(img_path,"/"); + img_name= img_path+strlen(img_path); + + while(1) { /* loop over directory content */ + stbuf_src= ""; + Linkitem_reset_stack(&own_link_stack, link_stack, 0); + srcpt= disk_path; + Xorriso_process_msg_queues(xorriso,0); + ret= Dirseq_next_adr(dirseq,name,0); /* name is a pointer into disk_path */ + 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;} + } + + /* compare exclusions against disk_path resp. name */ + ret= Xorriso_path_is_excluded(xorriso, disk_path, 0); /* (is never param) */ + if(ret<0) + {ret= -1; goto ex;} + if(ret>0) + continue; + + strcpy(img_name, name); + if(Xorriso_much_too_long(xorriso, strlen(img_path), 0)<=0) + {ret= 0; goto was_problem;} + if(Xorriso_much_too_long(xorriso, strlen(srcpt), 0)<=0) + {ret= 0; goto was_problem;} + stbuf_src= srcpt; + if(lstat(srcpt, &stbuf)==-1) { +cannot_lstat:; + Xorriso_msgs_submit(xorriso, 0, srcpt, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, + "Cannot determine attributes of source file %s", + Text_shellsafe(srcpt, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + ret= 0; goto was_problem; + } + source_is_dir= 0; + source_is_link= S_ISLNK(stbuf.st_mode); + if(xorriso->do_follow_links && source_is_link) { + /* Xorriso_hop_link checks for wide link loops */ + ret= Xorriso_hop_link(xorriso, srcpt, &own_link_stack, &hstbuf, 0); + if(ret<0) + goto was_problem; + if(ret==1) { + ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 0); + if(ret<=0) + goto was_problem; + srcpt= link_target; + stbuf_src= srcpt; + if(lstat(srcpt, &stbuf)==-1) + goto cannot_lstat; + } else { + if(Xorriso_eval_problem_status(xorriso, 0, 1|2)<0) + {ret= 0; goto was_problem;} + ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1); + if(ret<=0) + goto was_problem; + } + } else if (S_ISLNK(stbuf.st_mode)) { + ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1); + if(ret<=0) + goto was_problem; + } + do_not_dive= 0; + if(S_ISDIR(stbuf.st_mode)) { + source_is_dir= 1; + if(dir_dev != stbuf.st_dev && !xorriso->do_follow_mount) + do_not_dive= 1; + } + + /* does a node exist with this name ? */ + node= NULL; + ret= Xorriso_node_from_path(xorriso, volume, img_path, &node, 1); + if(ret>0) { + target_is_dir= LIBISO_ISDIR(node); + target_is_split= 0; + if(target_is_dir && !(flag & 128)) + target_is_split= Xorriso_is_split(xorriso, "", (void *) node, 1 | 2); + + if(!((target_is_dir && !target_is_split) && source_is_dir)) { + Xorriso_process_msg_queues(xorriso,0); + + /* handle overwrite situation */; + if(xorriso->do_overwrite==1 || + (xorriso->do_overwrite==2 && !(target_is_dir && !target_is_split))) { + ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, img_path, + 1 | 8 | (flag & 64)); + if(ret<=0) + goto was_problem; + if(ret==3) { + sprintf(xorriso->info_text, "User revoked adding of: %s", + Text_shellsafe(img_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + ret= 0; goto was_problem; + } + node= NULL; + } else { + Xorriso_msgs_submit(xorriso, 0, srcpt, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, + "While grafting %s : file object exists and may not be overwritten by %s", + Text_shellsafe(img_path,sfe,0), Text_shellsafe(stbuf_src,sfe2,0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto was_problem; + } + } + } + + if(node==NULL) { + ret= Xorriso_tree_graft_node(xorriso, volume, dir, srcpt, img_name, + "", img_path, (off_t) 0, (off_t) 0, + &node, 0); + } + if(node==NULL) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_msgs_submit(xorriso, 0, stbuf_src, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, "Grafting failed: %s = %s", + Text_shellsafe(img_path,sfe,0), Text_shellsafe(stbuf_src,sfe2,0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto was_problem; + } + + xorriso->pacifier_count++; + if((xorriso->pacifier_count%100)==0) + Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count, + xorriso->pacifier_total, "", 0); + + Xorriso_set_change_pending(xorriso, 0); + if(source_is_dir) { + if(do_not_dive) { + sprintf(xorriso->info_text, "Did not follow mount point : %s", + Text_shellsafe(disk_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } else { + ret= Xorriso_add_tree(xorriso, (IsoDir *) node, + img_path, disk_path, own_link_stack, + 1 | (flag & (2 | 64 | 128))); + } + if(ret<=0) + goto was_problem; + } + + continue; /* regular bottom of loop */ +was_problem:; + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret<0) + goto ex; + } + + ret= 1; +ex: + if(sfe!=NULL) + free(sfe); + if(sfe2!=NULL) + free(sfe2); + if(disk_path!=NULL) + free(disk_path); + if(img_path!=NULL) + free(img_path); + if(link_target!=NULL) + free(link_target); + Xorriso_process_msg_queues(xorriso,0); + Linkitem_reset_stack(&own_link_stack, link_stack, 0); + Dirseq_destroy(&dirseq, 0); + if(ret<=0) + return(ret); + return(!was_failure); +} + + +/* @param flag bit0= cut_out mode : base on leaf parent directory +*/ +int Xorriso_copy_implicit_properties(struct XorrisO *xorriso, IsoDir *dir, + char *full_img_path, char *img_path, char *full_disk_path, int flag) +{ + int ret, nfic, nic, nfdc, d, i; + char nfi[SfileadrL], ni[SfileadrL], nfd[SfileadrL], *cpt; + char sfe[5*SfileadrL]; + struct stat stbuf; + + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, full_img_path, nfi, + 1|2); + if(ret<=0) + return(ret); + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, img_path, ni, 1|2); + if(ret<=0) + return(ret); + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, full_disk_path, nfd, + 1|2|4); + if(ret<=0) + return(ret); + nfic= Sfile_count_components(nfi, 0); + nic= Sfile_count_components(ni, 0); + nfdc= Sfile_count_components(nfd, 0); + d= nfic-(flag&1)-nic; + if(d<0) + return(-1); + if(d>nfdc) + return(0); + for(i= 0; iinfo_text, + "Copied properties for %s", Text_shellsafe(ni, sfe, 0)); + sprintf(xorriso->info_text+strlen(xorriso->info_text), + " from %s", Text_shellsafe(nfd, sfe, 0)); + if(!((flag&1) && d==0)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + return(1); +} + + +/* @param bit0= copy link target properties rather than link properties + bit1= give directory x-permission where is r-permission + bit2= record dev,inode (only if enabled by xorriso) +*/ +int Xorriso_copy_properties(struct XorrisO *xorriso, + char *disk_path, char *img_path, int flag) +{ + int ret; + IsoNode *node; + struct stat stbuf; + + ret= Xorriso_get_node_by_path(xorriso, img_path, NULL, &node, 0); + if(ret<=0) + return(ret); + if(flag & 1) { + if(stat(disk_path, &stbuf)==-1) + return(0); + } else { + if(lstat(disk_path, &stbuf)==-1) + return(0); + } + Xorriso_transfer_properties(xorriso, &stbuf, disk_path, node, + ((flag & 2) >> 1) | ((flag & 1) << 5) | (flag & 4)); + Xorriso_set_change_pending(xorriso, 0); + 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= mkdir: graft in as empty directory, not as copy from disk + bit1= do not report added files + bit2= -follow, -not_*: this is not a command parameter + bit3= use offset and cut_size for cut_out_node + bit4= return 3 on rejection by exclusion or user + bit5= if directory then do not add sub tree + bit6= do not delete eventually existing node from di_array + bit7= no special handling of split file directories + @return <=0 = error , 1 = added simple node , 2 = added directory , + 3 = rejected +*/ +int Xorriso_graft_in(struct XorrisO *xorriso, void *boss_iter, + char *disk_path, char *img_path, + off_t offset, off_t cut_size, int flag) +{ + IsoImage *volume; + char path[SfileadrL], *apt, *npt, *cpt, sfe[5*SfileadrL], sfe2[5*SfileadrL]; + char *disk_path_pt, resolved_disk_path[SfileadrL]; + IsoDir *dir, *hdir; + IsoNode *node; + int done= 0, is_dir= 0, l, ret, target_is_dir, source_is_dir, resolve_link= 0; + int target_is_split; + struct stat stbuf; + + ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&4)); + if(ret<0) + return(ret); + if(ret>0) + return(3*!!(flag&16)); + + for(cpt= img_path; 1; cpt++) { + cpt= strstr(cpt,"/."); + if(cpt==NULL) + break; + if(cpt[2]=='.') { + if(cpt[3]=='/' || cpt[3]==0) + break; + } else if(cpt[2]=='/' || cpt[2]==0) + break; + } + if(cpt!=NULL) { + Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, + "Unsupported relative addressing in iso_rr_path %s (disk: %s)", + Text_shellsafe(img_path, sfe, 0), Text_shellsafe(disk_path, sfe2, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + return(0); + } + + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + return(ret); + + strncpy(path, img_path, sizeof(path)-1); + path[sizeof(path)-1]= 0; + apt= npt= path; + + if(!(flag&1)) { + ret= lstat(disk_path, &stbuf); + if(ret!=-1) { + if(S_ISDIR(stbuf.st_mode)) + is_dir= 1; + else if((stbuf.st_mode&S_IFMT)==S_IFLNK && + (xorriso->do_follow_links || + (xorriso->do_follow_param && !(flag&4)))) { + resolve_link= 1; + ret= stat(disk_path, &stbuf); + if(ret!=-1) { + if(S_ISDIR(stbuf.st_mode)) + is_dir= 1; + } + } + } + if(ret == -1) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, + "Cannot determine attributes of source file %s", + Text_shellsafe(disk_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + return(0); + } + if(S_ISDIR(stbuf.st_mode)) { + is_dir= 1; + } else { + l= strlen(img_path); + if(l>0) + if(img_path[l-1]=='/') + l= 0; + if(l==0) { + Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, + "Source %s is not a directory. Target %s would be.", + Text_shellsafe(disk_path, sfe, 0), Text_shellsafe(img_path, sfe2, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + } + + dir= iso_image_get_root(volume); + if(dir==NULL) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "While grafting '%s' : no root node available", img_path); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + return(0); + } + for(npt= apt; !done; apt= npt+1) { + npt= strchr(apt, '/'); + if(npt==NULL) { + npt= apt+strlen(apt); + done= 1; + } else + *npt= 0; + if(*apt==0) { + *apt= '/'; + apt++; + if(done) + goto attach_source; + continue; + } + source_is_dir= (is_dir || (flag&1) || !done); + ret= Xorriso_node_from_path(xorriso, volume, path, &node, 1); + if(ret>0) { + target_is_dir= LIBISO_ISDIR(node); + + target_is_split= 0; + if(target_is_dir && !(flag & 128)) + target_is_split= Xorriso_is_split(xorriso, "", (void *) node, 1 | 2); + + if(!((target_is_dir && !target_is_split) && source_is_dir)) { + Xorriso_process_msg_queues(xorriso,0); + + /* handle overwrite situation */; + if(xorriso->do_overwrite==1 || + (xorriso->do_overwrite==2 && !(target_is_dir && !target_is_split))) { + ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, path, + 1 | 8 | (flag & 64)); + if(ret<=0) + return(ret); + if(ret==3) { + sprintf(xorriso->info_text, "User revoked adding of: %s", + Text_shellsafe(disk_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(3*!!(flag&16)); + } + node= NULL; + goto handle_path_node; + } + + Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, + "While grafting '%s' : '%s' exists and may not be overwritten", + img_path, path); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + dir= (IsoDir *) node; + } + +handle_path_node:; + if(node==NULL && source_is_dir) { /* make a directory */ + ret= iso_tree_add_new_dir(dir, apt, &hdir); + if(ret<0) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); + Xorriso_report_iso_error(xorriso, img_path, ret, + "Cannot create directory", 0, "FAILURE", 1); + sprintf(xorriso->info_text, + "While grafting '%s' : could not insert '%s'", img_path, path); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + dir= hdir; + Xorriso_set_change_pending(xorriso, 0); + iso_node_set_ctime((IsoNode *) dir, time(NULL)); + iso_node_set_uid((IsoNode *) dir, geteuid()); + iso_node_set_gid((IsoNode *) dir, getegid()); + + if(disk_path!=NULL && !done) + Xorriso_copy_implicit_properties(xorriso, dir, img_path, path, disk_path, + !!(flag&8)); + + } + if(done) { +attach_source:; + if(flag&1) { + /* directory node was created above */; + + } else if(is_dir) { + Xorriso_transfer_properties(xorriso, &stbuf, disk_path, + (IsoNode *) dir, 4 | 32); + if(!(flag&32)) { + ret= Xorriso_add_tree(xorriso, dir, img_path, disk_path, NULL, + flag & (2 | 64 | 128)); + if(ret<=0) + return(ret); + } + } else { + if(resolve_link) { + ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0); + if(ret<=0) + return(ret); + disk_path_pt= resolved_disk_path; + } else + disk_path_pt= disk_path; + + ret= Xorriso_tree_graft_node(xorriso, volume, dir, disk_path_pt, apt, + disk_path, img_path, + offset, cut_size, &node, flag&8); + if(ret<=0) { + sprintf(xorriso->info_text, "Grafting failed: %s = %s", + Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + Xorriso_set_change_pending(xorriso, 0); + iso_node_set_name(node, apt); + + xorriso->pacifier_count++; + if(xorriso->pacifier_count%100 && !(flag&2)) + Xorriso_pacifier_callback(xorriso, "files added", + xorriso->pacifier_count, + xorriso->pacifier_total, "", 0); + } + } else + *npt= '/'; + } + Xorriso_process_msg_queues(xorriso,0); + return(1+!!is_dir); +} + + +/* @param flag bit0= -follow: disk_path is not a command parameter +*/ +int Xorriso_cut_out(struct XorrisO *xorriso, char *disk_path, + off_t startbyte, off_t bytecount, char *iso_rr_path, int flag) +{ + int ret; + char eff_source[SfileadrL], eff_dest[SfileadrL], sfe[SfileadrL*5]; + struct stat stbuf; + + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_source, + 2|4); + if(ret<=0) + return(ret); + ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&1)); + if(ret!=0) + return(0); + + if(lstat(eff_source, &stbuf)==-1) { + Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, "-cut_out: Cannot determine type of %s", + Text_shellsafe(eff_source, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + return(0); + } + + if((stbuf.st_mode&S_IFMT) == S_IFLNK) { + if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1)))) + goto unsupported_type; + if(stat(eff_source, &stbuf)==-1) { + Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, + "-cut_out: Cannot determine link target type of %s", + Text_shellsafe(eff_source, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); + return(0); + } + } + if(S_ISREG(stbuf.st_mode)) { + if(stbuf.st_sizeinfo_text, + "-cut_out: Byte offset %.f larger than file size %.f", + (double) startbyte, (double) stbuf.st_size); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "SORRY", 0); + return(0); + } + } else { +unsupported_type:; + Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, "-cut_out: Unsupported file type (%s) with %s", + Ftypetxt(stbuf.st_mode, 0), Text_shellsafe(eff_source, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + return(0); + } + + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, iso_rr_path, eff_dest, + 2); + if(ret<=0) + return(ret); + + ret= Xorriso_graft_in(xorriso, NULL, eff_source, eff_dest, + startbyte, bytecount, 8); + return(ret); +} + + +/* @param flag bit0= do not produce info message on success + @return 1=success, + 0=was already directory, -1=was other type, -2=other error +*/ +int Xorriso_mkdir(struct XorrisO *xorriso, char *path, int flag) +{ + int ret; + char eff_path[SfileadrL], sfe[5*SfileadrL]; + + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 1); + if(ret<0) + return(-2); + if(ret>0) { + sprintf(xorriso->info_text,"-mkdir: Address already existing %s", + Text_shellsafe(eff_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, + (ret==2 ? "WARNING" : "FAILURE"), 0); + return(-1+(ret==2)); + } + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 2); + if(ret<0) + return(-2); + ret= Xorriso_graft_in(xorriso, NULL, NULL, eff_path, (off_t) 0, (off_t) 0, 1); + if(ret<=0) + return(-2); + if(!(flag&1)) { + sprintf(xorriso->info_text, "Created directory in ISO image: %s\n", + Text_shellsafe(eff_path,sfe,0)); + Xorriso_info(xorriso, 0); + } + return(1); +} + + +/* @param boss_iter If not NULL then this is an iterator suitable for + iso_dir_iter_remove() which is then to be used instead + of iso_node_remove(). + @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 + bit6= do not delete eventually existing node from di_array + @return <=0 = error + 1 = removed simple node + 2 = removed directory or tree + 3 = did not remove on user revocation +*/ +int Xorriso_rmi(struct XorrisO *xorriso, void *boss_iter, off_t boss_mem, + char *path, int flag) +{ + int ret, is_dir= 0, pl, not_removed= 0, fret; + IsoNode *victim_node, *node; + IsoDir *boss_node, *root_dir; + IsoDirIter *iter= NULL; + IsoImage *volume; + char *sub_name, *name; + char *sfe= NULL, *sub_path= NULL; + off_t mem; + IsoNode **node_array= NULL; + int node_count= 0, node_idx; + + /* Avoiding large local memory objects in order to save stack space */ + sfe= malloc(5*SfileadrL); + sub_path= malloc(2*SfileadrL); + if(sfe==NULL || sub_path==NULL) { + Xorriso_no_malloc_memory(xorriso, &sfe, 0); + {ret= -1; goto ex;} + } + +#ifndef Libisofs_iso_dir_iter_sufficienT + /* Ticket 127: A80301 - A80302 + I do not not deem IsoDirIter safe for node list manipulations. + The parameter boss_iter once was intended to allow such but + has now been downgraded to a mere check for eventual programming bugs. + */ + if(boss_iter!=NULL) { + sprintf(xorriso->info_text, + "Program error: Xorriso_rmi() was requested to delete iterated node %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + ret= -1; goto ex; + } +#endif /* Libisofs_iso_dir_iter_sufficienT */ + + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + goto ex; + + if(Xorriso_much_too_long(xorriso, strlen(path), 0)<=0) + {ret= 0; goto ex;} + ret= Xorriso_node_from_path(xorriso, volume, path, &victim_node, 0); + if(ret<=0) + goto ex; + root_dir= iso_image_get_root(volume); + if(((void *) root_dir) == ((void *) victim_node)) { + sprintf(xorriso->info_text, "May not delete root directory"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + + if(LIBISO_ISDIR(victim_node)) + is_dir= 1; + if(!is_dir) { + if(flag&2) { /* rmdir */ + sprintf(xorriso->info_text, "%s in loaded ISO image is not a directory", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + } else { + if(flag&1) { /* rm -r */ + if((xorriso->do_reassure==1 && !xorriso->request_not_to_ask) || + (flag&32)) { + /* Iterate over subordinates and delete them */ + mem= boss_mem; + + ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, + &iter, &node_array, &node_count, &node_idx, + &node, 1|2); + if(ret<=0) { +cannot_create_iter:; + Xorriso_cannot_create_iter(xorriso, ret, 0); + ret= -1; goto ex; + } + pl= strlen(path); + strcpy(sub_path, path); + if(pl==0 || sub_path[pl-1]!='/') { + sub_path[pl++]= '/'; + sub_path[pl]= 0; + } + sub_name= sub_path+pl; + while(1) { + ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, &iter, + &node_array, &node_count, &node_idx, &node, 0); + if(ret<0) + goto ex; + if(ret==0 || xorriso->request_to_abort) + break; + name= (char *) iso_node_get_name(node); + if(Xorriso_much_too_long(xorriso, pl+1+strlen(name), 0)<=0) + {ret= 0; goto rm_r_problem_handler;} + strcpy(sub_name, name); + ret= Xorriso_rmi(xorriso, iter, mem, sub_path, + (flag & ( 1 | 2 | 8 | 16 | 64)) | 4); + if(ret==3 || ret<=0 || xorriso->request_to_abort) { +rm_r_problem_handler:; + not_removed= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret<0) + goto dir_not_removed; + } + } + if(flag&32) + {ret= 2; goto ex;} + + if(not_removed) { +dir_not_removed:; + sprintf(xorriso->info_text, "Directory not removed: %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + if(ret>0) + ret= 3; + goto ex; + } + } + } else { + if(!(flag&2)) { /* not rmdir */ + sprintf(xorriso->info_text, "%s in loaded ISO image is a directory", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + + ret= iso_dir_get_children((IsoDir *) victim_node, &iter); + Xorriso_process_msg_queues(xorriso,0); + if(ret<0) + goto cannot_create_iter; + if(ret>0) { + if(iso_dir_iter_next(iter, &node) == 1) { + sprintf(xorriso->info_text, + "Directory not empty on attempt to delete: %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + } + } + } + + if(xorriso->request_to_abort) + {ret= 3; goto ex;} + boss_node= iso_node_get_parent(victim_node); + Xorriso_process_msg_queues(xorriso,0); + if(boss_node==NULL) { + sprintf(xorriso->info_text, + "Cannot find parent node of %s in loaded ISO image", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + + while((xorriso->do_reassure==1 || (xorriso->do_reassure==2 && !(flag&4))) + && !xorriso->request_not_to_ask) { + /* ls -ld */ + Xorriso_ls_filev(xorriso, xorriso->wdi, 1, &path, (off_t) 0, 1|2|8); + if(is_dir) /* du -s */ + Xorriso_ls_filev(xorriso, xorriso->wdi, 1, &path, (off_t) 0, 2|4); + if(flag&8) + sprintf(xorriso->info_text, + "File exists. Remove ? n= keep old, y= remove, x= abort, @= stop asking\n"); + else + sprintf(xorriso->info_text, + "Remove above file ? n= keep it, y= remove it, x= abort, @= stop asking\n"); + Xorriso_info(xorriso, 4); + ret= Xorriso_request_confirmation(xorriso, 1|2|4|16); + if(ret<=0) + goto ex; + if(xorriso->request_to_abort) { + sprintf(xorriso->info_text, + "Removal operation aborted by user before file: %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + ret= 3; goto ex; + } + if(ret==3) + continue; + if(ret==6) /* yes */ + break; + if(ret==4) { /* yes, do not ask again */ + xorriso->request_not_to_ask= 1; + break; + } + if(ret==1) { /* no */ + sprintf(xorriso->info_text, "Kept in existing state: %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + ret= 3; goto ex; + } + } + + if(!(flag & 64)) + Xorriso_invalidate_di_item(xorriso, victim_node, 0); + +#ifdef Libisofs_iso_dir_iter_sufficienT + + if(boss_iter!=NULL) { + ret= iso_dir_iter_remove((IsoDirIter *) boss_iter); + if(ret<0) + ret= -1; + } else + ret= iso_node_remove(victim_node); + +#else /* ! Libisofs_iso_dir_iter_sufficienT */ + + ret= iso_node_remove(victim_node); + +#endif /* Libisofs_iso_dir_iter_sufficienT */ + + Xorriso_process_msg_queues(xorriso,0); + if(ret<0) { + Xorriso_report_iso_error(xorriso, path, ret, "Cannot remove node", 0, + "FATAL", 1); + sprintf(xorriso->info_text, + "Internal failure to remove %s from loaded ISO image", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + ret= -1; goto ex; + } + + if(flag&16) + xorriso->pacifier_count++; + Xorriso_set_change_pending(xorriso, 0); + ret= 1+!!is_dir; +ex:; + if(sfe!=NULL) + free(sfe); + if(sub_path!=NULL) + free(sub_path); + Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, &iter, + &node_array, &node_count, &node_idx, &node, (1<<31)); + 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 +*/ +int Xorriso_rename(struct XorrisO *xorriso, void *boss_iter, + char *origin, char *dest, int flag) +{ + int ret, ol, dest_ret; + char sfe[5*SfileadrL], eff_dest[SfileadrL], dir_adr[SfileadrL], *cpt; + char *leafname, eff_origin[SfileadrL], sfe2[5*SfileadrL], *old_leafname; + IsoImage *volume; + IsoDir *origin_dir, *dest_dir; + IsoNode *node, *iso_node; + +#ifndef Libisofs_iso_dir_iter_sufficienT + /* Ticket 127: A80301 - A80302 + I do not not deem IsoDirIter safe for node list manipulations. + The parameter boss_iter once was intended to allow such but + has now been downgraded to a mere check for eventual programming bugs. + */ + if(boss_iter!=NULL) { + sprintf(xorriso->info_text, + "Program error: Xorriso_rename() was requested to delete iterated node %s", + Text_shellsafe(origin, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + return(-1); + } +#endif /* Libisofs_iso_dir_iter_sufficienT */ + + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, origin, eff_origin, 0); + if(ret<=0) + return(ret); + dest_ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, dest, eff_dest,1); + if(dest_ret<0) + return(dest_ret); + if(dest_ret==0) { /* obtain eff_dest address despite it does not exist */ + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, dest, eff_dest, 2); + if(ret<=0) + return(ret); + } + + /* Prevent that destination is a subordinate of origin + (that would be a black hole plopping out of the universe) */ + ol= strlen(eff_origin); + if(ol==0) { + sprintf(xorriso->info_text, "May not rename root directory"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } else if(strcmp(eff_origin, eff_dest)==0) { + sprintf(xorriso->info_text, "Ignored attempt to rename %s to itself", + Text_shellsafe(eff_origin,sfe,0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + return(0); + } else if(strncmp(eff_origin, eff_dest, ol)==0 && + (eff_dest[ol]==0 || eff_dest[ol]=='/')) { + sprintf(xorriso->info_text, + "May not rename %s to its own sub address %s", + Text_shellsafe(eff_origin,sfe,0), Text_shellsafe(eff_dest,sfe2,0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + + /* Check whether destination exists and may be not overwriteable */ + if(dest_ret==2 && xorriso->do_overwrite!=1) { + sprintf(xorriso->info_text, "Renaming may not overwrite directory: %s", + Text_shellsafe(eff_dest, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } else if (dest_ret==1 && !xorriso->do_overwrite) { + sprintf(xorriso->info_text, "Renaming may not overwite: %s", + Text_shellsafe(eff_dest, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } else if(dest_ret>0) { + ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, eff_dest, 1|8); + if(ret<=0) + return(0); + if(ret==3) { + sprintf(xorriso->info_text, "User revoked renaming of: %s", + Text_shellsafe(eff_origin, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(0); + } + } + + /* Ensure existence of destination directory */ + strcpy(dir_adr, eff_dest); + cpt= strrchr(dir_adr, '/'); + if(cpt==NULL) + cpt= dir_adr+strlen(dir_adr); + *cpt= 0; + if(dir_adr[0]!=0) { + ret= Xorriso_graft_in(xorriso, boss_iter, NULL, dir_adr, + (off_t) 0, (off_t) 0, 1); + if(ret<=0) + return(ret); + } + + /* Move node */ + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + return(ret); + Xorriso_node_from_path(xorriso, volume, dir_adr, &iso_node, 0); + dest_dir= (IsoDir *) iso_node; + strcpy(dir_adr, eff_origin); + cpt= strrchr(dir_adr, '/'); + if(cpt==NULL) + cpt= dir_adr+strlen(dir_adr); + *cpt= 0; + Xorriso_node_from_path(xorriso, volume, dir_adr, &iso_node, 0); + origin_dir= (IsoDir *) iso_node; + Xorriso_node_from_path(xorriso, volume, eff_origin, &node, 0); + if(dest_dir==NULL || origin_dir==NULL || node==NULL) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "Internal error on rename: confirmed node turns out as NULL"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + return(-1); + } + ret= iso_node_take(node); + if(ret<0) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_report_iso_error(xorriso, eff_dest, 0, "Cannot take", 0, "FATAL",1); + sprintf(xorriso->info_text, + "Internal error on rename: failed to take node"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + return(-1); + } + leafname= strrchr(eff_dest, '/'); + if(leafname==NULL) + leafname= eff_dest; + else + leafname++; + + old_leafname= (char *) iso_node_get_name(node); + if(strcmp(leafname, old_leafname)!=0) + ret= iso_node_set_name(node, leafname); + else + ret= 1; + if(ret<0) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_report_iso_error(xorriso, eff_dest, 0, "Cannot set name", 0, + "FAILURE", 1); + return(-1); + } + Xorriso_process_msg_queues(xorriso,0); + ret= iso_dir_add_node(dest_dir, node, 0); + if(ret<0) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_report_iso_error(xorriso, eff_dest, 0, "Cannot add", 0, "FATAL", 1); + sprintf(xorriso->info_text, + "Internal error on rename: failed to insert node"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + return(-1); + } + return(1); +} + + +int Xorriso_set_st_mode(struct XorrisO *xorriso, char *in_path, + mode_t mode_and, mode_t mode_or, int flag) +{ + mode_t mode= 0; + int ret; + IsoNode *node; + char sfe[5*SfileadrL], path[SfileadrL]; + + ret= Xorriso_get_node_by_path(xorriso, in_path, path, &node, 0); + if(ret<=0) + return(ret); + mode= iso_node_get_permissions(node); + mode= (mode & mode_and) | mode_or; + iso_node_set_permissions(node, mode); + iso_node_set_ctime(node, time(NULL)); + sprintf(xorriso->info_text,"Permissions now: %-5.5o %s", + (unsigned int) (mode & 0xffff), Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + Xorriso_set_change_pending(xorriso, 0); + Xorriso_process_msg_queues(xorriso,0); + return(1); +} + + +int Xorriso_set_uid(struct XorrisO *xorriso, char *in_path, uid_t uid, + int flag) +{ + int ret; + IsoNode *node; + + ret= Xorriso_get_node_by_path(xorriso, in_path, NULL, &node, 0); + if(ret<=0) + return(ret); + iso_node_set_uid(node, uid); + iso_node_set_ctime(node, time(NULL)); + Xorriso_set_change_pending(xorriso, 0); + Xorriso_process_msg_queues(xorriso,0); + return(1); +} + + +int Xorriso_set_gid(struct XorrisO *xorriso, char *in_path, gid_t gid, + int flag) +{ + int ret; + IsoNode *node; + + ret= Xorriso_get_node_by_path(xorriso, in_path, NULL, &node, 0); + if(ret<=0) + return(ret); + iso_node_set_gid(node, gid); + iso_node_set_ctime(node, time(NULL)); + Xorriso_set_change_pending(xorriso, 0); + Xorriso_process_msg_queues(xorriso,0); + return(1); +} + + +/* @parm flag bit0= atime, bit1= ctime, bit2= mtime, bit8=no auto ctime */ +int Xorriso_set_time(struct XorrisO *xorriso, char *in_path, time_t t, + int flag) +{ + int ret; + IsoNode *node; + + ret= Xorriso_get_node_by_path(xorriso, in_path, NULL, &node, 0); + if(ret<=0) + return(ret); + if(flag&1) + iso_node_set_atime(node, t); + if(flag&2) + iso_node_set_ctime(node, t); + if(flag&4) + iso_node_set_mtime(node, t); + if(!(flag&(2|256))) + iso_node_set_ctime(node, time(NULL)); + Xorriso_set_change_pending(xorriso, 0); + Xorriso_process_msg_queues(xorriso,0); + return(1); +} + + +/* + Apply the effect of mkisofs -r to a single node +*/ +int Xorriso_mkisofs_lower_r(struct XorrisO *xorriso, IsoNode *node, int flag) +{ + mode_t perms; + + perms= iso_node_get_permissions(node); + iso_node_set_uid(node, (uid_t) 0); + iso_node_set_gid(node, (gid_t) 0); + perms|= S_IRUSR | S_IRGRP | S_IROTH; + perms&= ~(S_IWUSR | S_IWGRP | S_IWOTH); + if(perms & (S_IXUSR | S_IXGRP | S_IXOTH)) + perms|= (S_IXUSR | S_IXGRP | S_IXOTH); + perms&= ~(S_ISUID | S_ISGID | S_ISVTX); + iso_node_set_permissions(node, perms); + return(1); +} + + +/* @param node Opaque handle to IsoNode which is to be manipulated + instead of path if it is not NULL. + @param path is used as address if node is NULL. + @param access_text "access" ACL in long text form + @param default_text "default" ACL in long text form + @param flag bit0= do not warn of root directory if not capable of AAIP + @return >0 success , <=0 failure +*/ +int Xorriso_setfacl(struct XorrisO *xorriso, void *in_node, char *path, + char *access_text, char *default_text, int flag) +{ + int ret; + IsoNode *node; + + node= (IsoNode *) in_node; + if(node == NULL) { + ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); + if(ret<=0) + goto ex; + } + ret= iso_node_set_acl_text(node, access_text, default_text, 0); + if(ret <= 0) { + if(path != NULL && path[0] != 0) { + strcpy(xorriso->info_text, "Error with setting ACL of "); + Text_shellsafe(path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } + ret= 0; goto ex; + } + Xorriso_set_change_pending(xorriso, 0); + ret= 1; +ex:; + Xorriso_process_msg_queues(xorriso,0); + return(ret); +} + + +/* @param in_node Opaque handle to IsoNode which is to be manipulated + instead of path if it is not NULL. + @param path is used as address if node is NULL. + @param num_attrs Number of attributes + @param names Array of pointers to 0 terminated name strings + @param value_lengths Array of byte lengths for each attribute payload + @param values Array of pointers to the attribute payload bytes + @param flag bit0= Do not maintain eventual existing ACL of the node + bit1= Do not clear the existing attribute list + bit2= Delete the attributes with the given names + bit3= Allow non-user attributes. + bit4= do not warn of root if incapable of AAIP + @return >0 success , <=0 failure +*/ +int Xorriso_setfattr(struct XorrisO *xorriso, void *in_node, char *path, + size_t num_attrs, char **names, + size_t *value_lengths, char **values, int flag) +{ + int ret; + IsoNode *node; + + node= (IsoNode *) in_node; + if(node == NULL) { + ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); + if(ret<=0) + goto ex; + } + ret= iso_node_set_attrs(node, num_attrs, names, value_lengths, values, + flag & (1 | 2 | 4 | 8)); + Xorriso_process_msg_queues(xorriso,0); + if(ret <= 0) { + Xorriso_report_iso_error(xorriso, "", ret, + "Error when setting ACL and xattr to image node", + 0, "FAILURE", 1); + if(path != NULL && path[0] != 0) { + strcpy(xorriso->info_text, "Error with setting xattr of "); + Text_shellsafe(path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } + ret= 0; goto ex; + } + Xorriso_set_change_pending(xorriso, 0); + ret= 1; +ex:; + Xorriso_process_msg_queues(xorriso,0); + return(ret); +} + + +/* + @param flag bit0= use parameters dev,ino rather than disk_path + bit1= compare attribute rather than setting it + return: 0=dev,ino match, 1=mismatch, 2=no node attribute + -1=error + bit5= if not bit0: + transfer dev,inode from eventual link target + bit7= omit dev check mit bit1 +*/ +int Xorriso_record_dev_inode(struct XorrisO *xorriso, char *disk_path, + dev_t dev, ino_t ino, + void *in_node, char *iso_path, int flag) +{ + size_t l, di_l= 0; + int i, ret; + dev_t hdev; + ino_t hino; + char buf[66], *bufpt, *wpt, *di= NULL; + static char *name= "isofs.di"; + struct stat stbuf; + + if(!(flag & 1)) { + if(flag & 32) { + if(stat(disk_path, &stbuf) == -1) + return(-1); + } else { + if(lstat(disk_path, &stbuf) == -1) + return(-1); + } + dev= stbuf.st_dev; + ino= stbuf.st_ino; + } + + wpt= buf; + hdev= dev; + for(i= 0; hdev != 0; i++) + hdev= hdev >> 8; + l= i; + *(wpt++)= l; + for(i= 0; i < l; i++) + *(wpt++)= dev >> (8 * (l - i - 1)); + hino= ino; + for(i= 0; hino != 0; i++) + hino= hino >> 8; + l= i; + *(wpt++)= l; + for(i= 0; i < l; i++) + *(wpt++)= ino >> (8 * (l - i - 1)); + l= wpt - buf; + bufpt= buf; + + if(flag & 2) { + /* Compare node attribute with bufpt,l */ + ret= Xorriso_get_attr_value(xorriso, in_node, iso_path, + "isofs.di", &di_l, &di, 0); + if(ret < 0) + goto ex; + if(ret == 0) + {ret= 2; goto ex;} + if(flag & 128) { + if(di_l <= 0) + {ret= 1; goto ex;} + hino= 0; + for(i= di[0] + 2; i < di_l && i - di[0] - 2 < di[(int) di[0] + 1]; i++) + hino= (hino << 8) | ((unsigned char *) di)[i]; + if(hino != ino) + {ret= 1; goto ex;} + } else { + if(l != di_l) + {ret= 1; goto ex;} + for(i= 0; i < l; i++) + if(di[i] != buf[i]) + {ret= 1; goto ex;} + } + ret= 0; + } else { + ret= Xorriso_setfattr(xorriso, in_node, iso_path, + (size_t) 1, &name, &l, &bufpt, 2 | 8); + } +ex:; + if(di != NULL) + free(di); + return(ret); +} + + +/* @return see Xorriso_update_interpreter() +*/ +int Xorriso_widen_hardlink(struct XorrisO *xorriso, void * boss_iter, + IsoNode *node, + char *abs_path, char *iso_prefix, char *disk_prefix, + int flag) +{ + int ret= 0, idx, low, high, i, do_widen= 0, compare_result= 0; + char disk_path[SfileadrL]; + + /* Lookup all di_array instances of node */ + if(LIBISO_ISDIR(node)) + return(3); + ret= Xorriso_search_di_range(xorriso, node, &idx, &low, &high, 2); + if(ret <= 0) + return(3); + /* Check and reset di_do_widen bits */ + for(i= low; i <= high; i++) { + if(node != xorriso->di_array[i]) /* might be NULL */ + continue; + if(xorriso->di_do_widen[i / 8] & (1 << (i % 8))) + do_widen= 1; + xorriso->di_do_widen[i / 8]&= ~(1 << (i % 8)); + } + if(idx < 0 || !do_widen) + return(3); + + ret= Xorriso_pfx_disk_path(xorriso, abs_path, iso_prefix, disk_prefix, + disk_path, 0); + if(ret <= 0) + return(ret); + ret= Sfile_type(disk_path, 1); + if(ret < 0) + return(3); /* does not exist on disk */ + + /* >>> compare_result bit17 = is_split */; + + ret= Xorriso_update_interpreter(xorriso, boss_iter, compare_result, disk_path, + abs_path, 1); + if(ret <= 0) + return(ret); + return(ret); +} + + +int Xorriso_cannot_create_iter(struct XorrisO *xorriso, int iso_error,int flag) +{ + Xorriso_process_msg_queues(xorriso,0); + Xorriso_report_iso_error(xorriso, "", iso_error, "Cannot create iter", 0, + "FATAL", 1); + sprintf(xorriso->info_text, "Cannot create IsoDirIter object"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + return(1); +} + + +/* The caller shall make no assumptions about the meaning of iter, node_array, + node_count, node_idx ! They are just opaque handles for which the caller + provides the memory of proper type. + @param flag bit0= initialize iteration + bit1= action needs full freedom of object manipulation + bit2= action needs LBA sorted iteration + bit31= end iteration (mandatory !) +*/ +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 ret, i; + IsoNode *node; + off_t new_mem= 0; + char mem_text[80], limit_text[80]; + + if(flag&1) { + *node_array= NULL; + *node_count= -1; + *node_idx= 0; + *iter= NULL; + ret= iso_dir_get_children(dir_node, iter); + if(ret<0) { +cannot_iter:; + Xorriso_cannot_create_iter(xorriso, ret, 0); + return(-1); + } + if((flag&2)|(flag&4)) { + /* copy list of nodes and prepare soft iterator */ + *node_count= 0; + while(iso_dir_iter_next(*iter, &node) == 1) + (*node_count)++; + iso_dir_iter_free(*iter); + *iter= NULL; + + new_mem= ((*node_count)+1) * sizeof(IsoNode *); + if(new_mem > xorriso->temp_mem_limit) { + Sfile_scale((double) new_mem, mem_text, 5,1e4, 0); + Sfile_scale((double) xorriso->temp_mem_limit, limit_text, 5,1e4, 0); + sprintf(xorriso->info_text, + "Stacked directory snapshots exceed -temp_mem_limit (%s > %s)", + mem_text, limit_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + *node_count= -1; + return(-1); + } + (*node_array)= (IsoNode **) calloc((*node_count)+1, sizeof(IsoNode *)); + if(*node_array == NULL) { + sprintf(xorriso->info_text, + "Could not allocate inode list of %.f bytes", + ((double) (*node_count)+1) * (double) sizeof(IsoNode *)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + *node_count= -1; + return(-1); + } + *mem= new_mem; + ret= iso_dir_get_children(dir_node, iter); + if(ret<0) + goto cannot_iter; + while(iso_dir_iter_next(*iter, &node) == 1 && *node_idx < *node_count) { + (*node_array)[*node_idx]= node; + iso_node_ref(node); + (*node_idx)++; + } + iso_dir_iter_free(*iter); + *iter= NULL; + *node_count= *node_idx; + *node_idx= 0; + if((flag&4) && *node_count>1) + qsort(*node_array, *node_count, sizeof(IsoNode *), + Xorriso__node_lba_cmp); + } + } + + if(flag&(1<<31)) { + if(*node_count>=0 && *node_array!=NULL) { + for(i= 0; i<*node_count; i++) + iso_node_unref((*node_array)[i]); + free(*node_array); + *node_array= NULL; + *node_count= -1; + *node_idx= 0; + } else { + if(*iter!=NULL) + iso_dir_iter_free(*iter); + *iter= NULL; + } + } + + if(flag&(1|(1<<31))) + return(1); + if(*node_count>=0) { + /* return next node_array element */ + if(*node_idx>=*node_count) + return(0); + *iterated_node= (*node_array)[*node_idx]; + (*node_idx)++; + } else { + ret= iso_dir_iter_next(*iter, iterated_node); + return(ret == 1); + } + return(1); +} + + +/* @param flag bit0= not a command parameter (directory iteration or recursion) + bit1= do not count deleted files with rm and rm_r + @return <=0 error, + 1=ok + 2=ok, node has been deleted, + 3=ok, do not dive into directory (e.g. because it is a split file) +*/ +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 ret= 0, type, action= 0, hflag, deleted= 0, no_dive= 0; + uid_t user= 0; + gid_t group= 0; + time_t date= 0; + mode_t mode_or= 0, mode_and= ~1; + char *target, *text_2, sfe[5*SfileadrL], *iso_prefix, md5[16]; + struct FindjoB *subjob; + struct stat dir_stbuf; + + action= Findjob_get_action_parms(job, &target, &text_2, &user, &group, + &mode_and, &mode_or, &type, &date, &subjob, 0); + if(action<0) + action= 0; + + hflag= 16*!(flag&2); + ret= 1; + if(action==1) { /* rm (including rmdir) */ + ret= Xorriso_fake_stbuf(xorriso, abs_path, &dir_stbuf, &node, 1); + if(ret>0) { + if(S_ISDIR(dir_stbuf.st_mode)) + hflag= 2; + ret= Xorriso_rmi(xorriso, boss_iter, boss_mem, abs_path, hflag); + deleted= 1; + } + } else if(action==2) { /* rm_r */ + ret= Xorriso_rmi(xorriso, boss_iter, boss_mem, abs_path, 1|hflag); + deleted= 1; + } else if(action==3) { + + /* >>> mv target */; + + } else if(action==4) { /* chown */ + ret= Xorriso_set_uid(xorriso, abs_path, user, 0); + } else if(action==5) { /* chgrp */ + ret= Xorriso_set_gid(xorriso, abs_path, group, 0); + } else if(action==6) { /* chmod */ + ret= Xorriso_set_st_mode(xorriso, abs_path, mode_and, mode_or, 0); + } else if(action==7) { /* alter_date */ + ret= Xorriso_set_time(xorriso, abs_path, date, type&7); + } else if(action==8) { /* lsdl */ + ret= Xorriso_ls_filev(xorriso, "", 1, &abs_path, (off_t) 0, 1|2|8); + } else if(action>=9 && action<=13) { /* actions which have own findjobs */ + Findjob_set_start_path(subjob, abs_path, 0); + ret= Xorriso_findi(xorriso, subjob, boss_iter, boss_mem, NULL, + abs_path, &dir_stbuf, depth, 1); + } else if(action==14 || action==17) { /* compare , update */ + Findjob_get_start_path(job, &iso_prefix, 0); + ret= Xorriso_find_compare(xorriso, (void *) boss_iter, abs_path, + iso_prefix, target, (action==17)|((flag&1)<<1)); + if(ret==2) + deleted= 1; + if(ret==3) + no_dive= 1; + if(ret>=0) + ret= 1; + } else if(action==16 || action==18) { /* not_in_iso , add_missing */ + ; + } else if(action == 21) { /* report_damage */ + ret= Xorriso_report_damage(xorriso, show_path, node, 0); + } else if(action == 22) { + ret= Xorriso_report_lba(xorriso, show_path, node, 0); + } else if(action == 23) { /* internal: memorize path of last matching node */ + ret= Findjob_set_found_path(job, show_path, 0); + } else if(action == 24) { + ret= Xorriso_getfacl(xorriso, (void *) node, show_path, NULL, 0); + } else if(action == 25) { + if(target == NULL || target[0] || text_2 == NULL || text_2[0]) + ret= Xorriso_setfacl(xorriso, (void *) node, show_path, target, text_2,0); + } else if(action == 26) { + ret= Xorriso_getfattr(xorriso, (void *) node, show_path, NULL, 0); + } else if(action == 27) { + ret= Xorriso_path_setfattr(xorriso, (void *) node, show_path, + target, strlen(text_2), text_2, 0); + } else if(action == 28) { /* set_filter */ + ret= Xorriso_set_filter(xorriso, (void *) node, show_path, target, 1 | 2); + } else if(action == 29) { /* show_stream */ + ret= Xorriso_show_stream(xorriso, (void *) node, show_path, 1 | 2); + } else if(action == 30) { /* internal: count */ + xorriso->node_counter++; + } else if(action == 31) { /* internal: register */ + if(xorriso->node_counter < xorriso->node_array_size) { + xorriso->node_array[xorriso->node_counter++]= (void *) node; + iso_node_ref(node); /* In case node gets deleted from tree during + the lifetime of xorriso->node_array */ + } + } else if(action == 32) { /* internal: widen_hardlinks disk_equiv */ + Findjob_get_start_path(job, &iso_prefix, 0); + ret= Xorriso_widen_hardlink(xorriso, (void *) boss_iter, node, abs_path, + iso_prefix, target, 0); + if(ret==2) + deleted= 1; + } else if(action == 33) { /* get_any_xattr */ + ret= Xorriso_getfattr(xorriso, (void *) node, show_path, NULL, 8); + } else if(action == 34) { /* get_md5 */ + ret= Xorriso_get_md5(xorriso, (void *) node, show_path, md5, 0); + if(ret >= 0) + ret= 1; + } else if(action == 35) { /* check_md5 */ + ret= Xorriso_check_md5(xorriso, (void *) node, show_path, 2); + if(ret == 0) + xorriso->find_check_md5_result|= 1; + else if(ret < 0) + xorriso->find_check_md5_result|= 2; + else if(ret == 1) + xorriso->find_check_md5_result|= 8; + else if(ret == 2) + xorriso->find_check_md5_result|= 4; + if(ret >= 0) + ret= 1; + } else if(action == 36) { /* make_md5 */ + ret= Xorriso_make_md5(xorriso, (void *) node, show_path, 0); + if(ret >= 0) + ret= 1; + } else if(action == 37) { /* mkisofs_r */ + ret= Xorriso_mkisofs_lower_r(xorriso, node, 0); + } else if(action == 38) { /* sort_weight */ + iso_node_set_sort_weight(node, type); + } else { /* includes : 15 in_iso */ + sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0)); + Xorriso_result(xorriso, 0); + ret= 1; + } + if(ret<=0) + return(ret); + if(deleted) + return(2); + if(no_dive) + return(3); + return(1); +} + + +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) +/* +return: + <0 = error + 0 = does not match + 1 = does match + 2 = immediate decision : does not match + 3 = immediate decision : does match +*/ +{ + int value=0, ret, start_lba, end_lba; + int lba_count, *file_end_lbas= NULL, *file_start_lbas= NULL, i; + void *arg1, *arg2; + char ft, *decision, md5[16]; + regmatch_t name_match; + off_t damage_start, damage_end, size; + void *xinfo_dummy; + IsoNode *node; + IsoStream *stream; + + if(ftest == NULL) + return(1); + + node= (IsoNode *) node_pt; + arg1= ftest->arg1; + arg2= ftest->arg2; + + if(node == NULL) { + if(ftest->test_type > 2 && ftest->test_type != 4) { + value= 0; + goto ex; + } + } + + switch(ftest->test_type) { + case 0: /* -false */ + value= 0; + + break; case 1: /* -name *arg1 (regex in *arg2) */ + ret= regexec(arg2, name, 1, &name_match, 0); + value= !ret; + + break; case 2: /* -type *arg1 */ + value= 1; + ft= *((char *) arg1); + if(ft!=0) { + if(S_ISBLK(stbuf->st_mode)) { + if(ft!='b') + value= 0; + } else if(S_ISCHR(stbuf->st_mode)) { + if(ft!='c') + value= 0; + } else if(S_ISDIR(stbuf->st_mode)) { + if(ft=='m') { + if(node != NULL) + value= 0; + else if(boss_stbuf==NULL) + value= 0; + else if(boss_stbuf->st_dev == stbuf->st_dev) + value= 0; + } else if(ft!='d') + value= 0; + } else if(S_ISFIFO(stbuf->st_mode)) { + if(ft!='p') + value= 0; + } else if(S_ISREG(stbuf->st_mode)) { + if(ft!='f' && ft!='-') + value= 0; + } else if(((stbuf->st_mode)&S_IFMT)==S_IFLNK) { + if(ft!='l') + value= 0; + } else if(((stbuf->st_mode)&S_IFMT)==S_IFSOCK) { + if(ft!='s') + value= 0; + } else if((flag & 1) && ((stbuf->st_mode) & S_IFMT) == Xorriso_IFBOOT) { + if(ft!='e' || node == NULL) + value= 0; + } else { + if(ft!='X') + value= 0; + } + } + + break; case 3: /* -damaged */; + value= Xorriso_file_eval_damage(xorriso, node, &damage_start, &damage_end, + 0); + if(value > 0) + value= 1; + + break; case 4: /* -lba_range *arg1 *arg2 */ + value= 1; + start_lba= *((int *) ftest->arg1); + end_lba= *((int *) ftest->arg2); + if(node == NULL) { + value= !(start_lba >= 0); + goto ex; + } + ret= Xorriso__start_end_lbas(node, &lba_count, + &file_start_lbas, &file_end_lbas, &size, 0); + if(ret <= 0) { + if(ret < 0) + Xorriso_process_msg_queues(xorriso, 0); + if(start_lba >= 0) + value= 0; + } else { + for(i= 0; i < lba_count; i++) { + if(start_lba >= 0) { + if(file_end_lbas[i] < start_lba || file_start_lbas[i] > end_lba) + value= 0; + } else { + if(file_end_lbas[i] >= -start_lba && file_start_lbas[i] <= -end_lba) + value= 0; + } + } + } + + break; case 5: /* -has_acl */ + ret = Xorriso_getfacl(xorriso, (void *) node, "", NULL, 2); + if(ret <= 0) { + value= -1; + Xorriso_process_msg_queues(xorriso, 0); + goto ex; + } + value= (ret == 1); + + break; case 6: /* -has_xattr */ + case 14: /* -has_any_xattr */ + ret = Xorriso_getfattr(xorriso, (void *) node, "", NULL, + 64 | (8 * (ftest->test_type == 14))); + if(ret < 0) { + value= -1; + Xorriso_process_msg_queues(xorriso, 0); + goto ex; + } + value= (ret > 0); + + break; case 7: /* -has_aaip */ + ret= iso_node_get_xinfo(node, aaip_xinfo_func, &xinfo_dummy); + if(ret < 0) { + value= -1; + Xorriso_process_msg_queues(xorriso, 0); + goto ex; + } + value= (ret > 0); + + break; case 8: /* -has_filter */ + value= 0; + if(LIBISO_ISREG(node)) { + stream= iso_file_get_stream((IsoFile *) node); + if(iso_stream_get_input_stream(stream, 0) != NULL) + value= 1; + } + + break; case 9: /* -wanted_node arg1 (for internal use) */ + value= (((IsoNode *) arg1) == node); + + break; case 10: /* -pending_data */ + value= 1; + if(!LIBISO_ISREG(node)) { + value= 0; + } else { + ret= Xorriso__file_start_lba(node, &start_lba, 0); + if(ret > 0 && start_lba >= 0) + value= 0; + } + + break; case 11: /* -decision */ + value= 2; + decision= (char *) arg1; + if(strcmp(decision, "yes") == 0 || strcmp(decision, "true") == 0) + value= 3; + + break; case 12: /* -prune */ + value= 1; + ftest->boss->prune= 1; + + break; case 13: /* -wholename *arg1 (regex in *arg2) */ + ret= regexec(arg2, path, 1, &name_match, 0); + value= !ret; + + break; case 15: /* -has_md5 */ + ret= Xorriso_get_md5(xorriso, node, path, md5, 1); + value= (ret > 0); + + break; default: + + /* >>> complain about unknown test type */; + + value= -1; + + } + +ex:; + if(ftest->invert && value<=1 && value>=0) + value= !value; + if(file_start_lbas != NULL) + free((char *) file_start_lbas); + if(file_end_lbas != NULL) + free((char *) file_end_lbas); + return(value); +} + + +/* @return <0 = error , 0 = no match , 1 = match */ +int Xorriso_findi_test(struct XorrisO *xorriso, struct FindjoB *job, + IsoNode *node, char *name, char *path, + struct stat *boss_stbuf, struct stat *stbuf, + int depth, int flag) +{ + int ret; + + job->prune= 0; + ret= Findjob_test_2(xorriso, job, node, name, path, boss_stbuf, stbuf, 1); + if(ret <= 0) + return(ret); + return(1); +} + + +int Xorriso_findi_headline(struct XorrisO *xorriso, struct FindjoB *job, + int flag) +{ + int action; + + action= Findjob_get_action(job, 0); + if(action == 21) { /* report_damage */ + sprintf(xorriso->result_line, "Report layout: %8s , %8s , %8s , %s\n", + "at byte", "Range", "Filesize", "ISO image path"); + Xorriso_result(xorriso, 0); + } else if(action == 22) { /* report_lba */ + sprintf(xorriso->result_line, + "Report layout: %2s , %8s , %8s , %8s , %s\n", + "xt", "Startlba", "Blocks", "Filesize", "ISO image path"); + Xorriso_result(xorriso, 0); + } + return(1); +} + + +/* @param flag bit0= recursion + bit1= do not count deleted files with rm and rm_r + bit2= do not dive into split file directories + (implicitly given with actions 14=compare and 17=update) + @return <=0 error, 1= ok , 2= dir node and path has been deleted +*/ +int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, + void *boss_iter, off_t boss_mem, + void *dir_node_generic, char *dir_path, + struct stat *dir_stbuf, int depth, int flag) +{ + int ret, action= 0, hflag, deleted= 0, no_dive= 0; + IsoDirIter *iter= NULL; + IsoDir *dir_node= NULL; + IsoNode *node, *iso_node; + IsoImage *volume= NULL; + struct stat stbuf; + char *name; + off_t mem; + IsoNode **node_array= NULL; + int node_count, node_idx; + char *path= NULL, *abs_path= NULL; + + if(xorriso->request_to_abort) + {ret= 0; goto ex;} + + path= malloc(SfileadrL); + abs_path= malloc(SfileadrL); + if(path==NULL || abs_path==NULL) { + Xorriso_no_malloc_memory(xorriso, &path, 0); + {ret= -1; goto ex;} + } + + action= Findjob_get_action(job, 0); + if(action<0) + action= 0; + if(!(flag & 1)) + Xorriso_findi_headline(xorriso, job, 0); + + dir_node= (IsoDir *) dir_node_generic; + if(dir_node==NULL) { + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + {ret= -1; goto ex;} + ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, dir_path, path, 1|2|4); + if(ret<=0) + goto ex; + ret= Xorriso_node_from_path(xorriso, volume, path, &iso_node, 0); + dir_node= (IsoDir *) iso_node; + if(ret<=0) + {ret= 0; goto ex;} + ret= Xorriso_fake_stbuf(xorriso, "", dir_stbuf, &iso_node, 1); + if(ret<=0) + goto ex; + + name= strrchr(dir_path, '/'); + if(name==NULL) + name= dir_path; + else + name++; + + ret= Xorriso_findi_test(xorriso, job, iso_node, name, path, NULL, dir_stbuf, + depth, 0); + if(ret<0) + goto ex; + if(job->prune) + no_dive= 1; + if(ret>0) { + iso_node_ref(iso_node); /* protect from real disposal */ + ret= Xorriso_findi_action(xorriso, job, + (IsoDirIter *) boss_iter, boss_mem, + path, dir_path, iso_node, depth, + flag&(1|2)); + deleted= (iso_node_get_parent(iso_node) == NULL); /* still in tree ? */ + iso_node_unref(iso_node); /* eventually do real disposal */ + if(ret<=0) + goto ex; + if(xorriso->request_to_abort) + {ret= 0; goto ex;} + if(ret==2 || deleted) { + /* re-determine dir_node in case it has a new persona */ + ret= Xorriso_node_from_path(xorriso, volume, path, &iso_node, 1); + if(ret==0) { + deleted= 1; + {ret= 2; goto ex;} + } + if(ret<0) + {ret= 0; goto ex;} + dir_node= (IsoDir *) iso_node; + ret= Xorriso_fake_stbuf(xorriso, "", dir_stbuf, &iso_node, 1); + if(ret<=0) + goto ex; + } + if(ret==3) + no_dive= 1; + } + } + if(no_dive || !LIBISO_ISDIR((IsoNode *) dir_node)) + {ret= 1; goto ex;} + if(action == 14 || action == 17 || (flag & 4)) + if(Xorriso_is_split(xorriso, dir_path, (IsoNode *) dir_node, 1)>0) + {ret= 1; goto ex;} + + mem= boss_mem; + hflag= 1; + if(action==1 || action==2 || action==3 || action==17 || action == 28 || + action == 32) + hflag|= 2; /* need freedom to manipulate image */ + if(action==14 || action==17 || action == 28 || action == 35 || action == 36) + hflag|= 4; /* need LBA sorted iteration for good data reading performance */ + ret= Xorriso_findi_iter(xorriso, dir_node, &mem, + &iter, &node_array, &node_count, &node_idx, + &node, hflag); + if(ret<=0) + goto ex; + while(1) { + ret= Xorriso_findi_iter(xorriso, dir_node, &mem, &iter, + &node_array, &node_count, &node_idx, &node, 0); + if(ret<0) + goto ex; + if(ret==0) + break; + name= (char *) iso_node_get_name(node); + ret= Xorriso_make_abs_adr(xorriso, dir_path, name, path, 4); + if(ret<=0) + goto ex; + ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1); + if(ret<0) + goto ex; + if(ret==0) + continue; + +/* ??? This seems to be redundant with the single test above + ??? Should i dive in unconditionally and leave out test and action here ? + ??? Then do above test unconditionally ? + --- Seems that the current configuration represents the special + handling of the find start path with mount points. Dangerous to change. +*/ + + ret= Xorriso_findi_test(xorriso, job, node, name, path, dir_stbuf, &stbuf, + depth, 0); + if(ret<0) + goto ex; + if(job->prune) + no_dive= 1; + if(ret>0) { + ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, path, abs_path, 1|2|4); + if(ret<=0) + goto ex; + ret= Xorriso_findi_action(xorriso, job, iter, mem, + abs_path, path, node, depth, 1|(flag&2)); + if(xorriso->request_to_abort) + {ret= 0; goto ex;} + if(ret==2) { /* node has been deleted */ + /* re-determine node in case it has a new persona */ + if(volume==NULL) { + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + {ret= -1; goto ex;} + } + ret= Xorriso_node_from_path(xorriso, volume, abs_path, &node, 1); + if(ret==0) + continue; + if(ret<0) + {ret= 0; goto ex;} + ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1); + if(ret<0) + goto ex; + if(ret==0) + continue; + } + no_dive= (ret==3); + if(ret<=0) { + if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0) + goto ex; + } + } + + if(S_ISDIR(stbuf.st_mode) && !no_dive) { + ret= Xorriso_findi(xorriso, job, (void *) iter, mem, + (void *) node, path, &stbuf, depth+1, flag|1); + if(ret<0) + goto ex; + } + } + + ret= 1; +ex:; + if(path!=NULL) + free(path); + if(abs_path!=NULL) + free(abs_path); + Xorriso_process_msg_queues(xorriso,0); + + Xorriso_findi_iter(xorriso, dir_node, &mem, &iter, &node_array, &node_count, + &node_idx, &node, (1<<31)); + if(ret<=0) + return(ret); + if(deleted) + return(2); + return(1); +} + + +/* @param flag bit0= do not dive into trees + bit1= do not perform job->action on resulting node array + bit2= do not free node_array after all actions are done +*/ +int Xorriso_findi_sorted(struct XorrisO *xorriso, struct FindjoB *job, + off_t boss_mem, int filec, char **filev, int flag) +{ + int i, ret, find_flag= 0; + struct FindjoB array_job, *proxy_job= NULL, *hindmost= NULL, *hmboss= NULL; + struct stat dir_stbuf; + IsoNode *node; + char abs_path[SfileadrL]; + off_t mem_needed= 0; + + array_job.start_path= NULL; + + if(job->action == 14 || job->action == 17) + find_flag|= 4; + if(job->action>=9 && job->action<=13) { /* actions which have own findjobs */ + /* array_job replaces the hindmost job in the chain */ + for(hindmost= job; hindmost->subjob != NULL; hindmost= hindmost->subjob) + hmboss= hindmost; + if(hmboss == NULL) + {ret= -1; goto ex;} + memcpy(&array_job, hindmost, sizeof(struct FindjoB)); + hmboss->subjob= &array_job; + proxy_job= job; + } else { + memcpy(&array_job, job, sizeof(struct FindjoB)); + proxy_job= &array_job; + hindmost= job; + } + array_job.start_path= NULL; /* is owned by the original, not by array_job */ + + /* Count matching nodes */ + Xorriso_destroy_node_array(xorriso, 0); + array_job.action= 30; /* internal: count */ + for(i= 0; i < filec; i++) { + if(flag & 1) { + xorriso->node_counter++; + continue; + } + ret= Findjob_set_start_path(proxy_job, filev[i], 0); + if(ret <= 0) + goto ex; + ret= Xorriso_findi(xorriso, proxy_job, NULL, boss_mem, NULL, + filev[i], &dir_stbuf, 0, find_flag); + if(ret <= 0) + goto ex; + } + if(xorriso->node_counter <= 0) + {ret= 1; goto ex;} + + mem_needed= boss_mem + xorriso->node_counter * sizeof(IsoNode *); + if(!(flag &1)) { + ret= Xorriso_check_temp_mem_limit(xorriso, mem_needed, 0); + if(ret <= 0) { + /* Memory curbed : Perform unsorted find jobs */ + if(hmboss != NULL) + hmboss->subjob= hindmost; + for(i= 0; i < filec; i++) { + ret= Findjob_set_start_path(job, filev[i], 0); + if(ret <= 0) + goto ex; + ret= Xorriso_findi(xorriso, job, NULL, boss_mem, NULL, + filev[i], &dir_stbuf, 0, find_flag); + if(ret <= 0) + if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0) + goto ex; + } + {ret= 1; goto ex;} + } + } + + /* Copy matching nodes into allocated array */ + ret= Xorriso_new_node_array(xorriso, xorriso->temp_mem_limit, 0, 0); + if(ret <= 0) + goto ex; + array_job.action= 31; /* internal: register */ + xorriso->node_counter= 0; + for(i= 0; i < filec; i++) { + if(flag & 1) { + ret= Xorriso_get_node_by_path(xorriso, filev[i], NULL, &node, 0); + if(ret <= 0) + goto ex; + if(xorriso->node_counter < xorriso->node_array_size) { + xorriso->node_array[xorriso->node_counter++]= (void *) node; + iso_node_ref(node); + } + continue; + } + ret= Findjob_set_start_path(proxy_job, filev[i], 0); + if(ret <= 0) + goto ex; + ret= Xorriso_findi(xorriso, proxy_job, NULL, mem_needed, NULL, + filev[i], &dir_stbuf, 0, find_flag); + if(ret <= 0) + goto ex; + } + + Xorriso_sort_node_array(xorriso, 0); + if(flag & 2) + {ret= 1; goto ex;} + + /* Perform job->action on xorriso->node_array */ + + /* Headlines of actions report_damage , report_lba */; + Xorriso_findi_headline(xorriso, job, 0); + + for(i= 0; i < xorriso->node_counter; i++) { + node= xorriso->node_array[i]; + ret= Xorriso_path_from_node(xorriso, node, abs_path, 0); + if(ret < 0) + goto ex; + if(ret == 0) + continue; /* node is deleted from tree meanwhile */ + + ret= Xorriso_findi_action(xorriso, hindmost, NULL, (off_t) 0, + abs_path, abs_path, node, 0, 1); + if(ret <= 0 || xorriso->request_to_abort) + if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0) + goto ex; + } + + ret= 1; +ex:; + if(!(flag & (2 | 4))) + Xorriso_destroy_node_array(xorriso, 0); + if(hmboss != NULL) + hmboss->subjob= hindmost; + if(array_job.start_path != NULL) + free(array_job.start_path); + return(ret); +} + + +int Xorriso_all_node_array(struct XorrisO *xorriso, int addon_nodes, int flag) +{ + int ret; + struct FindjoB *job= NULL; + struct stat dir_stbuf; + + ret= Findjob_new(&job, "/", 0); + if(ret<=0) { + Xorriso_no_findjob(xorriso, "xorriso", 0); + {ret= -1; goto ex;} + } + Findjob_set_action_target(job, 30, NULL, 0); + Xorriso_destroy_node_array(xorriso, 0); + ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, NULL, "/", + &dir_stbuf, 0, 0); + if(ret <= 0) + goto ex; + ret= Xorriso_new_node_array(xorriso, xorriso->temp_mem_limit, addon_nodes, 0); + if(ret <= 0) + goto ex; + Findjob_set_action_target(job, 31, NULL, 0); + ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, NULL, "/", + &dir_stbuf, 0, 0); + if(ret <= 0) + goto ex; + ret= 1; +ex:; + Findjob_destroy(&job, 0); + return(ret); +} + + +int Xorriso_perform_acl_from_list(struct XorrisO *xorriso, char *file_path, + char *uid, char *gid, char *acl, int flag) +{ + int ret, zero= 0; + uid_t uid_number; + gid_t gid_number; + + /* Set group and owner */ + if(gid[0]) { + ret= Xorriso_convert_gidstring(xorriso, gid, &gid_number, 0); + if(ret<=0) + return(ret); + ret= Xorriso_set_gid(xorriso, file_path, gid_number, 0); + if(ret<=0) + return(ret); + } + if(uid[0]) { + ret= Xorriso_convert_uidstring(xorriso, uid, &uid_number, 0); + if(ret<=0) + return(ret); + ret= Xorriso_set_uid(xorriso, file_path, uid_number, 0); + if(ret<=0) + return(ret); + } + ret= Xorriso_option_setfacli(xorriso, acl, 1, &file_path, &zero, 0); + if(ret <= 0) + return(ret); + return(1); +} + + +/* + @param flag bit0= do not perform setfattr but only check input +*/ +int Xorriso_path_setfattr(struct XorrisO *xorriso, void *in_node, char *path, + char *name, size_t value_length, char *value, int flag) +{ + int ret, hflag; + size_t num_attrs= 1; + char *name_pt; + + hflag= 2; + name_pt= name; + if(name[0] == 0) { + sprintf(xorriso->info_text, + "-setfattr: Empty attribute name is not allowed"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } else if(strcmp(name, "--remove-all") == 0) { + if(value[0]) { + sprintf(xorriso->info_text, + "-setfattr: Value is not empty with pseudo name --remove-all"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + num_attrs= 0; + hflag= 0; + } else if(name[0] == '-') { + name_pt++; + hflag|= 4; + } else if(name[0] == '=' || name[0] == '+') { + name_pt++; + } + if(flag & 1) + return(1); + ret= Xorriso_setfattr(xorriso, in_node, path, + num_attrs, &name_pt, &value_length, &value, hflag); + return(ret); +} + + +/* Warning: The text content of lst gets mangled by 0s and unescaping. +*/ +int Xorriso_perform_attr_from_list(struct XorrisO *xorriso, char *path, + struct Xorriso_lsT *lst_start, int flag) +{ + int ret, eaten; + char *valuept, *ept, *line, **names= NULL, **values= NULL; + size_t num_attr= 0, *value_lengths= NULL, v_len; + struct Xorriso_lsT *lst; + + for(lst= lst_start; lst != NULL; lst= Xorriso_lst_get_next(lst, 0)) + num_attr++; + if(num_attr == 0) { + ret= Xorriso_setfattr(xorriso, NULL, path, num_attr, NULL, NULL, NULL, 0); + goto ex; + } + + names= calloc(num_attr, sizeof(char *)); + if(names == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + value_lengths= calloc(num_attr, sizeof(size_t)); + if(value_lengths== NULL) { + free(names); + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + values= calloc(num_attr, sizeof(char *)); + if(values== NULL) { + free(names); + free(value_lengths); + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + + num_attr= 0; + for(lst= lst_start; lst != NULL; lst= Xorriso_lst_get_next(lst, 0)) { + line= Xorriso_lst_get_text(lst, 0); + ept= strchr(line, '='); + if(ept == NULL) + continue; + /* Split into name and content */; + *ept= 0; + valuept= ept + 1; + + /* Strip quotes from value */ + v_len= strlen(valuept); + if(v_len < 2 || *valuept != '"' || *(valuept + v_len - 1) != '"') + continue; + *valuept= 0; + *(valuept + v_len - 1)= 0; + valuept++; + v_len-= 2; + + /* Unescape backslashes , values eventually with 0-bytes */ + ret= Sfile_bsl_interpreter(line, strlen(line), &eaten, 0); + if(ret <= 0) + continue; + ret= Sfile_bsl_interpreter(valuept, (int) v_len, &eaten, 2); + if(ret <= 0) + continue; + + names[num_attr]= line; + values[num_attr]= valuept; + value_lengths[num_attr]= v_len - eaten; + num_attr++; + } + ret= Xorriso_setfattr(xorriso, NULL, path, num_attr, names, + value_lengths, values, 0); +ex:; + if(names != NULL) + free(names); + if(value_lengths != NULL) + free(value_lengths); + if(values != NULL) + free(values); + return(ret); +} + diff --git a/xorriso/iso_manip.h b/xorriso/iso_manip.h new file mode 100644 index 00000000..7c1a2a5c --- /dev/null +++ b/xorriso/iso_manip.h @@ -0,0 +1,72 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/iso_tree.c b/xorriso/iso_tree.c new file mode 100644 index 00000000..adb4ba1b --- /dev/null +++ b/xorriso/iso_tree.c @@ -0,0 +1,2146 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains functions which access nodes of the + libisofs tree model. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +#include "xorriso.h" +#include "xorriso_private.h" +#include "xorrisoburn.h" + +#include "lib_mgt.h" +#include "iso_img.h" +#include "iso_tree.h" +#include "iso_manip.h" +#include "sort_cmp.h" + + +/* @param eff_path returns resulting effective path. + Must provide at least SfileadrL bytes of storage. + @param flag bit0= do not produce problem events (unless faulty path format) + bit1= work purely literally, do not use libisofs + bit2= (with bit1) this is an address in the disk world + bit3= return root directory as "/" and not as "" + bit4= (with bit2) determine type of disk file eff_path + and return 0 if not existing + bit5= (with bit3) this is not a parameter + bit6= insist in having an ISO image, even with bits1+2 + @return -1 = faulty path format, 0 = not found , + 1 = found simple node , 2 = found directory +*/ +int Xorriso_normalize_img_path(struct XorrisO *xorriso, char *wd, + char *img_path, char eff_path[], int flag) +{ + int ret, is_dir= 0, done= 0; + IsoImage *volume; + IsoDir *dir= NULL; + IsoNode *node= NULL; + char path[SfileadrL], *apt, *npt, sfe[5*SfileadrL], *cpt; + + if((flag&64) || !(flag&2)) { + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + return(ret); + } + + eff_path[0]= 0; + if(img_path[0]==0) { + if(flag&8) + strcpy(eff_path, "/"); + return(2); /* root directory */ + } + + apt= npt= path; + if(img_path[0]!='/') { + strcpy(path, wd); + ret= Sfile_add_to_path(path, img_path, 0); + if(ret<=0) + goto much_too_long; + } else + if(Sfile_str(path, img_path, 0)<=0) + return(-1); + + if(path[0]!='/') { + sprintf(xorriso->info_text, + "Internal error: Unresolvable relative addressing in iso_rr_path '%s'", + img_path); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FATAL", 0); + return(-1); + } else if(path[1]==0) { + if(flag&8) + strcpy(eff_path, "/"); + return(2); /* root directory */ + } + + for(npt= apt; !done; apt= npt+1) { + npt= strchr(apt, '/'); + if(npt==NULL) { + npt= apt+strlen(apt); + done= 1; + } else + *npt= 0; + if(*apt==0) { + *apt= '/'; + apt++; + if(done) + break; + continue; + } + if(strcmp(apt,".")==0) { + is_dir= 1; + continue; + } + if(strcmp(apt,"..")==0) { + if(!(flag&2)) { + node= (IsoNode *) dir; + if(node==NULL) { +bonked_root:; + sprintf(xorriso->info_text, + "Relative addressing in path exceeds root directory: %s", + Text_shellsafe(img_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(-1); + } + dir= iso_node_get_parent(node); + } + /* truncate eff_path */; + cpt= strrchr(eff_path, '/'); + if(cpt==NULL) /* ??? if not flag&2 then this is a bug */ + goto bonked_root; + *cpt= 0; + is_dir= 1; + continue; + } + ret= Sfile_add_to_path(eff_path, apt, 0); + if(ret<=0) { +much_too_long:; + sprintf(xorriso->info_text, "Effective path gets much too long (%d)", + (int) (strlen(eff_path)+strlen(apt)+1)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(-1); + } + if(!(flag&2)) { + dir= (IsoDir *) node; + ret= Xorriso_node_from_path(xorriso, volume, eff_path, &node, flag&1); + if(ret<=0) + return(0); + if(dir==NULL) /* could be false with "/dir/.." */ + dir= iso_node_get_parent(node); + is_dir= LIBISO_ISDIR(node); + } + } + if(flag&16) { + ret= Sfile_type(eff_path, + 1|(4*(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&32))) + )); + if(ret<0) + return(0); + if(ret==2) + is_dir= 1; + } + return(1+!!is_dir); +} + + +int Xorriso_get_node_by_path(struct XorrisO *xorriso, + char *in_path, char *eff_path, + IsoNode **node, int flag) +{ + int ret; + char path[SfileadrL]; + IsoImage *volume; + + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, in_path, path, 0); + if(ret<=0) + return(ret); + if(eff_path!=NULL) + strcpy(eff_path, path); + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + return(ret); + ret= Xorriso_node_from_path(xorriso, volume, path, node, 0); + if(ret<=0) + return(0); + return(1); +} + + +/* @param flag +*/ +int Xorriso_node_get_dev(struct XorrisO *xorriso, IsoNode *node, + char *path, dev_t *dev, int flag) +{ + *dev= iso_special_get_dev((IsoSpecial *) node); + return(1); +} + + +/* @param flag bit0= *node is already valid + bit1= add extra block for size estimation + bit2= complain loudely if path is missing in image + bit3= stbuf is to be used without eventual ACL + bit4= try to obtain a better st_nlink count if hardlinks + are enabled +*/ +int Xorriso_fake_stbuf(struct XorrisO *xorriso, char *path, struct stat *stbuf, + IsoNode **node, int flag) +{ + int ret, min_hl, max_hl, node_idx, i; + IsoImage *volume; + + memset((char *) stbuf, 0, sizeof(struct stat)); + if(!(flag&1)) { + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + return(-1); + ret= Xorriso_node_from_path(xorriso, volume, path, node, !(flag&4)); + if(ret<=0) + *node= NULL; + } + if(*node==NULL) + return(0); + + /* >>> stbuf->st_dev */ + /* >>> stbuf->st_ino */ + + if(flag & 8) + stbuf->st_mode= iso_node_get_perms_wo_acl(*node) & 07777; + else + stbuf->st_mode= iso_node_get_permissions(*node) & 07777; + if(LIBISO_ISDIR(*node)) + stbuf->st_mode|= S_IFDIR; + else if(LIBISO_ISREG(*node)) + stbuf->st_mode|= S_IFREG; + else if(LIBISO_ISLNK(*node)) + stbuf->st_mode|= S_IFLNK; + else if(LIBISO_ISCHR(*node)) { + stbuf->st_mode|= S_IFCHR; + Xorriso_node_get_dev(xorriso, *node, path, &(stbuf->st_rdev), 0); + } else if(LIBISO_ISBLK(*node)) { + stbuf->st_mode|= S_IFBLK; + Xorriso_node_get_dev(xorriso, *node, path, &(stbuf->st_rdev), 0); + } else if(LIBISO_ISFIFO(*node)) + stbuf->st_mode|= S_IFIFO; + else if(LIBISO_ISSOCK(*node)) + stbuf->st_mode|= S_IFSOCK; + else if(LIBISO_ISBOOT(*node)) + stbuf->st_mode|= Xorriso_IFBOOT; + + /* >>> With directories this should be : number of subdirs + 2 */ + /* >>> ??? How to obtain RR hardlink number for other types ? */ + /* This may get overriden farther down */ + stbuf->st_nlink= 1; + + stbuf->st_uid= iso_node_get_uid(*node); + stbuf->st_gid= iso_node_get_gid(*node); + + if(LIBISO_ISREG(*node)) + stbuf->st_size= iso_file_get_size((IsoFile *) *node)+ (2048 * !!(flag&2)); + else + stbuf->st_size= 0; + + stbuf->st_blksize= 2048; + stbuf->st_blocks= stbuf->st_size / (off_t) 2048; + if(stbuf->st_blocks * (off_t) 2048 != stbuf->st_size) + stbuf->st_blocks++; + + stbuf->st_atime= iso_node_get_atime(*node); + stbuf->st_mtime= iso_node_get_mtime(*node); + stbuf->st_ctime= iso_node_get_ctime(*node); + + if(LIBISO_ISDIR(*node) || (xorriso->ino_behavior & 1) || (!(flag & 16)) || + xorriso->hln_array == NULL) + return(1); + + /* Try to obtain a better link count */ + ret= Xorriso_search_hardlinks(xorriso, *node, &node_idx, &min_hl, &max_hl, 0); + if(ret < 0) + return(ret); + if(ret > 0 && node_idx >= 0) { + for(i= min_hl; i <= max_hl; i++) { + if(i == node_idx) + continue; + /* Check whether node is still valid */ + if(iso_node_get_parent(xorriso->hln_array[i]) != NULL) + stbuf->st_nlink++; + } + } + return(1); +} + + +/* @param flag >>> bit0= follow links (i.e. stat() rather than lstat() + bit1= do not return -2 on severe errors + bit2= complain loudely if path is missing in image +*/ +int Xorriso_iso_lstat(struct XorrisO *xorriso, char *path, struct stat *stbuf, + int flag) +{ + int ret; + IsoNode *node; + + if(flag&1) { + + /* >>> follow link in ISO image */; + + } + + ret= Xorriso_fake_stbuf(xorriso, path, stbuf, &node, flag&4); + if(ret>0) + return(0); + if(ret<0 && !(flag&2)) + return(-2); + return(-1); +} + + +int Xorriso_node_is_valid(struct XorrisO *xorriso, IsoNode *in_node, int flag) +{ + IsoNode *node, *parent; + + for(node= in_node; 1; node= parent) { + parent= (IsoNode *) iso_node_get_parent(node); + if(parent == node) + break; + if(parent == NULL) + return(0); /* Node is not in the tree (any more) */ + } + return(1); +} + + +int Xorriso_path_from_node(struct XorrisO *xorriso, IsoNode *in_node, + char path[SfileadrL], int flag) +{ + int ret, i, comp_count= 0; + IsoNode *node, *parent, **components= NULL; + char *wpt, *npt; + + for(node= in_node; 1; node= parent) { + parent= (IsoNode *) iso_node_get_parent(node); + if(parent == node) + break; + if(parent == NULL) + return(0); /* Node is not in the tree (any more) */ + comp_count++; + } + if(comp_count == 0) { + strcpy(path, "/"); + return(1); + } + components= calloc(comp_count, sizeof(IsoNode *)); + if(components == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + i= comp_count; + for(node= in_node; 1; node= parent) { + parent= (IsoNode *) iso_node_get_parent(node); + if(parent == node) + break; + components[--i]= node; + } + + wpt= path; + for(i= 0; i < comp_count; i++) { + npt= (char *) iso_node_get_name(components[i]); + if((wpt - path) + strlen(npt) + 1 >= SfileadrL) { + + /* >>> path is getting much too long */; + + ret= -1; goto ex; + } + *(wpt++)= '/'; + strcpy(wpt, npt); + wpt+= strlen(npt); + *wpt= 0; + } + ret= 1; +ex:; + if(components != NULL) + free(components); + return(ret); +} + + +/* <<< The lookup from node pointer will be done by Xorriso_path_from_node() + (Currently it runs a full tree traversal) + Parameter node and flag bit0 will vanish then +*/ +/* @param flag bit0= use lba rather than node pointer +*/ +int Xorriso_path_from_lba(struct XorrisO *xorriso, IsoNode *node, int lba, + char path[SfileadrL], int flag) +{ + int ret; + struct FindjoB *job= NULL; + struct stat dir_stbuf; + char *found_path; + + path[0]= 0; + if((flag & 1) && lba <= 0) + return(0); + + ret= Findjob_new(&job, "/", 0); + if(ret <= 0) { + Xorriso_no_findjob(xorriso, "path_from_node", 0); + return(ret); + } + if(flag & 1) + Findjob_set_lba_range(job, lba, 1, 0); + else + Findjob_set_wanted_node(job, (void *) node, 0); + Findjob_set_action_found_path(job, 0); + ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, + NULL, "/", &dir_stbuf, 0, 0); + if(ret > 0) { + ret= 1; + Findjob_get_found_path(job, &found_path, 0); + if(found_path == NULL) + ret= 0; + else if(Sfile_str(path, found_path, 0) <= 0) + ret= -1; + } + Findjob_destroy(&job, 0); + return(ret); +} + + +/* @param flag bit0= in_node is valid, do not resolve iso_adr + bit2= recognize and parse split parts despite + xorrio->split_size <= 0 +*/ +int Xorriso_identify_split(struct XorrisO *xorriso, char *iso_adr, + void *in_node, + struct SplitparT **parts, int *count, + struct stat *total_stbuf, int flag) +{ + int ret, i, incomplete= 0, overlapping= 0; + int partno, total_parts, first_total_parts= -1; + off_t offset, bytes, total_bytes, first_total_bytes= -1, first_bytes= -1; + off_t size, covered; + + IsoImage *volume; + IsoDir *dir_node; + IsoDirIter *iter= NULL; + IsoNode *node; + char *name; + struct stat stbuf, first_stbuf; + + *count= 0; + *parts= NULL; + + if(xorriso->split_size <= 0 && !(flag & 4)) + return(0); + + if(flag&1) { + node= (IsoNode *) in_node; + } else { + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + return(-1); + ret= Xorriso_node_from_path(xorriso, volume, iso_adr, &node, 1); + if(ret<=0) + return(-1); + } + if(!LIBISO_ISDIR(node)) + return(0); + dir_node= (IsoDir *) node; + + ret= iso_dir_get_children(dir_node, &iter); + if(ret<0) { +cannot_iter:; + Xorriso_cannot_create_iter(xorriso, ret, 0); + return(-1); + } + + for(i= 0; iso_dir_iter_next(iter, &node) == 1; i++) { + name= (char *) iso_node_get_name(node); + ret= Splitpart__parse(name, &partno, &total_parts, + &offset, &bytes, &total_bytes, 0); + if(ret<=0) + {ret= 0; goto ex;} + if(i==0) { + first_total_parts= total_parts; + first_bytes= bytes; + first_total_bytes= total_bytes; + Xorriso_fake_stbuf(xorriso, "", &first_stbuf, &node, 1); + size= first_stbuf.st_size; + } else { + if(first_total_parts!=total_parts || first_total_bytes!=total_bytes || + (first_bytes!=bytes && partno!=total_parts)) + {ret= 0; goto ex;} + Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1); + if(first_stbuf.st_mode != stbuf.st_mode || + first_stbuf.st_uid != stbuf.st_uid || + first_stbuf.st_gid != stbuf.st_gid || + first_stbuf.st_mtime != stbuf.st_mtime || + first_stbuf.st_ctime != stbuf.st_ctime) + {ret= 0; goto ex;} + size= stbuf.st_size; + } + /* check for plausible size */ + if(!((partno != total_parts && size == bytes) || + (partno == total_parts && size <= bytes))) + {ret= 0; goto ex;} + if(offset != first_bytes * (off_t) (partno - 1)) + {ret= 0; goto ex;} + (*count)++; + } + if(*count <= 0 || *count != first_total_parts) + {ret= 0; goto ex;} + + ret= Splitparts_new(parts, (*count)+1, 0); /* (have one end marker item) */ + if(ret<=0) + return(ret); + + iso_dir_iter_free(iter); + ret= iso_dir_get_children(dir_node, &iter); + if(ret<0) + goto cannot_iter; + for(i= 0; i<*count; i++) { + ret= iso_dir_iter_next(iter, &node); + if(ret!=1) + break; + name= (char *) iso_node_get_name(node); + ret= Splitpart__parse(name, &partno, &total_parts, + &offset, &bytes, &total_bytes, 0); + if(ret<=0) + {ret= 0; goto ex;} + ret= Splitparts_set(*parts, i, name, partno, total_parts, offset, bytes, + total_bytes, 0); + if(ret<=0) + goto ex; + } + + Splitparts_sort(*parts, *count, 0); + + covered= 0; + for(i= 0; i<*count; i++) { + Splitparts_get(*parts, i, &name, &partno, &total_parts, &offset, &bytes, + &total_bytes, 0); + if(offset>covered) + incomplete= 1; + else if(offset covered) + covered= offset+bytes; + } + if(total_bytes>covered) + incomplete= 1; + memcpy(total_stbuf, &first_stbuf, sizeof(struct stat)); + total_stbuf->st_size= total_bytes; + ret= !(overlapping || incomplete); +ex:; + if(iter!=NULL) + iso_dir_iter_free(iter); + return(ret); +} + + +/* @param flag bit0= node is valid, do not resolve path + bit1= insist in complete collection of part files +*/ +int Xorriso_is_split(struct XorrisO *xorriso, char *path, void *node, + int flag) +{ + struct SplitparT *split_parts= NULL; + int split_count= 0, ret; + struct stat stbuf; + + ret= Xorriso_identify_split(xorriso, path, node, &split_parts, + &split_count, &stbuf, flag & 3); + if(split_parts!=NULL) + Splitparts_destroy(&split_parts, split_count, 0); + return(ret>0); +} + + +/* @param node Opaque handle to IsoNode which is to be inquired instead of path if it is not NULL. + @param path is used as address if node is NULL. + @param acl_text if acl_text is not NULL, then *acl_text will be set to the + ACL text (without comments) of the file object. In this + case it finally has to be freed by the caller. + @param flag bit0= do not report to result but only retrieve ACL text + bit1= check for existence of true ACL (not fabricated), + do not allocate and set acl_text but return 1 or 2 + bit2-3: what ALC to retrieve: + 0= "access" and "default", mark "default:" + 1= "access" only + 2= "default" only, do not mark "default:" + bit4= get "access" ACL only if not trivial + @return 2 ok, no ACL available, eventual *acl_text will be NULL + 1 ok, ACL available, eventual *acl_text stems from malloc() + <=0 error +*/ +int Xorriso_getfacl(struct XorrisO *xorriso, void *in_node, char *path, + char **acl_text, int flag) +{ + int ret, d_ret, result_len= 0, pass, what; + IsoNode *node; + char *text= NULL, *d_text= NULL, *cpt, *npt; + uid_t uid; + gid_t gid; + struct passwd *pwd; + struct group *grp; + + what= (flag >> 2) & 3; + if(acl_text != NULL) + *acl_text= NULL; + + node= (IsoNode *) in_node; + if(node == NULL) { + ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); + if(ret<=0) + goto ex; + } + ret= iso_node_get_acl_text(node, &text, &d_text, flag & 16); + d_ret= (d_text != NULL); + if(ret < 0 || d_ret < 0) { + if(path != NULL && path[0] != 0) { + strcpy(xorriso->info_text, "Error with obtaining ACL of "); + Text_shellsafe(path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } + ret= 0; goto ex; + } + if(flag & 2) { + ret= 1 + (ret != 1 && d_ret == 0); + goto ex; + } + if((ret == 0 || ret == 2) && d_ret == 0) { + if(flag & 1) { + ret= 1 + (ret == 0); + goto ex; + } + strcpy(xorriso->info_text, "No ACL associated with "); + Text_shellsafe(path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + if(ret == 0) + {ret= 2; goto ex;} + } + + if(!(flag & 1)) { + ret= Xorriso_getfname(xorriso, path, 0); + if(ret <= 0) + goto ex; + uid= iso_node_get_uid(node); + pwd= getpwuid(uid); + if(pwd == NULL) + sprintf(xorriso->result_line, "# owner: %.f\n", (double) uid); + else + sprintf(xorriso->result_line, "# owner: %s\n", pwd->pw_name); + Xorriso_result(xorriso, 0); + gid= iso_node_get_gid(node); + grp= getgrgid(gid); + if(grp == NULL) + sprintf(xorriso->result_line, "# group: %.f\n", (double) gid); + else + sprintf(xorriso->result_line, "# group: %s\n", grp->gr_name); + Xorriso_result(xorriso, 0); + } + + for(pass= 0; pass < 1 + (acl_text != NULL && !(flag & 2)); pass++) { + if(pass) { + *acl_text= calloc(result_len + 1, 1); + if(*acl_text == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + } + if(text != NULL && what <= 1) { + for(npt= cpt= text; npt != NULL; cpt= npt + 1) { + npt= strchr(cpt, '\n'); + if(npt != NULL) + *npt= 0; + if(*cpt == 0) { + if(d_text != NULL || pass) { + if(npt != NULL) + *npt= '\n'; + continue; + } + } else + result_len+= strlen(cpt) + 1; + if(pass) { + sprintf(*acl_text + strlen(*acl_text), "%s\n", cpt); + } else if(!(flag & 1)) { + Sfile_str(xorriso->result_line, cpt, 0); + strcat(xorriso->result_line, "\n"); + Xorriso_result(xorriso, 0); + } + if(npt != NULL) + *npt= '\n'; + } + } + if(d_text != NULL && (what == 0 || what == 2)) { + for(npt= cpt= d_text; npt != NULL; cpt= npt + 1) { + npt= strchr(cpt, '\n'); + if(npt != NULL) + *npt= 0; + if(*cpt != 0) { + if(pass) { + if(what == 0) + sprintf(*acl_text + strlen(*acl_text), "default:%s\n", cpt); + else + sprintf(*acl_text + strlen(*acl_text), "%s\n", cpt); + } else { + xorriso->result_line[0]= 0; + if(what == 0) + Sfile_str(xorriso->result_line, "default:", 0); + Sfile_str(xorriso->result_line, cpt, 1); + result_len+= strlen(cpt) + 9; + } + } else + xorriso->result_line[0]= 0; + if(pass== 0 && !(flag & 1)) { + strcat(xorriso->result_line, "\n"); + Xorriso_result(xorriso, 0); + } + if(npt != NULL) + *npt= '\n'; + } + } + } + ret= 1; +ex:; + iso_node_get_acl_text(node, &text, &d_text, 1 << 15); + return(ret); +} + + +/* + @param flag bit0= do not report to result but only retrieve attr text + bit1= path is disk_path + bit3= do not ignore eventual non-user attributes. + bit5= in case of symbolic link on disk: inquire link target + bit6= check for existence of xattr, return 0 or 1 + (depends also on bit3) +*/ +int Xorriso_getfattr(struct XorrisO *xorriso, void *in_node, char *path, + char **attr_text, int flag) +{ + int ret= 1, i, bsl_mem, result_len= 0, pass; + size_t num_attrs= 0, *value_lengths= NULL; + char **names= NULL, **values= NULL, *bsl; + + if(attr_text != NULL) + *attr_text= NULL; + ret= Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names, + &value_lengths, &values, flag & (2 | 8 | 32)); + if(ret <= 0) + goto ex; + if(flag & 64) { + ret= (num_attrs > 0); + goto ex; + } + if(num_attrs == 0) + {ret= 2; goto ex;} + + if(!(flag & 1)) { + ret= Xorriso_getfname(xorriso, path, 0); + if(ret <= 0) + goto ex; + } + for(pass= 0; pass < 1 + (attr_text != NULL); pass++) { + if(pass) { + *attr_text= calloc(result_len + 1, 1); + if(*attr_text == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + } + for(i= 0; i < num_attrs; i++) { + if(strlen(names[i]) + value_lengths[i] >= SfileadrL) { + sprintf(xorriso->result_line, "# oversized: name %d , value %d bytes\n", + (int) strlen(names[i]), (int) value_lengths[i]); + } else { + ret= Sfile_bsl_encoder(&bsl, names[i], strlen(names[i]), 8); + if(ret <= 0) + {ret= -1; goto ex;} + strcpy(xorriso->result_line, bsl); + free(bsl); + ret= Sfile_bsl_encoder(&bsl, values[i], value_lengths[i], 8); + if(ret <= 0) + {ret= -1; goto ex;} + sprintf(xorriso->result_line + strlen(xorriso->result_line), + "=\"%s\"\n", bsl); + free(bsl); + } + /* temporarily disable -backslash_codes with result output */ + result_len+= strlen(xorriso->result_line); + if(pass) { + strcat(*attr_text, xorriso->result_line); + } else if(!(flag & 1)) { + bsl_mem= xorriso->bsl_interpretation; + xorriso->bsl_interpretation= 0; + Xorriso_result(xorriso, 0); + xorriso->bsl_interpretation= bsl_mem; + } + } + } + if(!(flag & 1)) { + strcpy(xorriso->result_line, "\n"); + Xorriso_result(xorriso, 0); + } + ret= 1; +ex:; + Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names, + &value_lengths, &values, 1 << 15); + return(ret); +} + + +/* + @param flag + Bitfield for control purposes + bit0= get default ACL rather than access ACL + bit4= set *text = NULL and return 2 + if the ACL matches st_mode permissions. + bit5= in case of symbolic link: inquire link target + bit15= free text and return 1 + @return + 1 ok + 2 ok, trivial ACL found while bit4 is set, *text is NULL + 0 no ACL manipulation adapter available / ACL not supported by fs + -1 failure of system ACL service (see errno) + -2 attempt to inquire ACL of a symbolic link without bit4 or bit5 + resp. with no suitable link target +*/ +int Xorriso_local_getfacl(struct XorrisO *xorriso, char *disk_path, + char **text, int flag) +{ + int ret, skip= 0, colons= 0, countdown= 0; + char *acl= NULL, *cpt, *wpt; + + if(flag & (1 << 15)) { + if(*text != NULL) + free(*text); + *text= NULL; + return(1); + } + *text= NULL; + ret= iso_local_get_acl_text(disk_path, &acl, flag & (1 | 16 | 32)); + Xorriso_process_msg_queues(xorriso,0); + if(ret < 0 || ret == 2) + return(ret); + if(acl == NULL) + return(0); + *text= strdup(acl); + iso_local_get_acl_text(disk_path, &acl, 1 << 15); + if(*text == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + return(-1); + } + + /* Garbage collection about trailing remarks after 3 permission chars */ + wpt= *text; + for(cpt= *text; *cpt; cpt++) { + if(skip) { + if(*cpt == '\n') + skip= 0; + else + continue; + } + if(*cpt == ':' && !countdown) { + colons++; + if(colons == 2) { + countdown= 4; + colons= 0; + } + } + if(countdown > 0) { + countdown--; + if(countdown == 0) + skip= 1; + } + *wpt= *cpt; + wpt++; + } + *wpt= 0; + + return(1); +} + + +/* + @param flag + bit1= path is disk_path + bit3= do not ignore eventual non-user attributes. + bit5= in case of symbolic link on disk: inquire link target + bit15= free memory +*/ +int Xorriso_get_attrs(struct XorrisO *xorriso, void *in_node, char *path, + size_t *num_attrs, char ***names, + size_t **value_lengths, char ***values, int flag) +{ + int ret, i, widx; + IsoNode *node; + + if(flag & (1 << 15)) { + if(flag & 2) { + iso_local_get_attrs(NULL, num_attrs, names, value_lengths, values, + 1 << 15); + } else { + iso_node_get_attrs(NULL, num_attrs, names, value_lengths, values, + 1 << 15); + } + return(1); + } + + *num_attrs= 0; + if(flag & 2) { + ret= iso_local_get_attrs(path, num_attrs, names, value_lengths, values, + flag & (8 | 32)); + if(ret < 0) { + strcpy(xorriso->info_text, "Error with reading xattr of disk file "); + Text_shellsafe(path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + } + } else { + node= (IsoNode *) in_node; + if(node == NULL) { + ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); + if(ret<=0) + goto ex; + } + ret= iso_node_get_attrs(node, num_attrs, names, value_lengths, values, + 0); + if(ret < 0) { + Xorriso_report_iso_error(xorriso, "", ret, + "Error when obtaining xattr of ISO node", 0, "FAILURE", 1); + goto ex; + } + + if(!(flag & 8)) { + /* Filter away any non-userspace xattr */; + widx= 0; + for(i= 0; i < *num_attrs; i++) { + if(strncmp((*names)[i], "user.", 5) != 0) { + free((*names)[i]); + (*names)[i]= NULL; + if((*values)[i] != NULL) { + free((*values)[i]); + (*values)[i]= NULL; + } + } else { + if(widx != i) { + (*names)[widx]= (*names)[i]; + (*value_lengths)[widx]= (*value_lengths)[i]; + (*values)[widx]= (*values)[i]; + (*names)[i]= NULL; + (*value_lengths)[i]= 0; + (*values)[i]= NULL; + } + widx++; + } + } + *num_attrs= widx; + } + } + ret= 1; +ex:; + Xorriso_process_msg_queues(xorriso,0); + return(ret); +} + + +int Xorriso_get_attr_value(struct XorrisO *xorriso, void *in_node, char *path, + char *name, size_t *value_length, char **value, int flag) +{ + int ret; + size_t num_attrs= 0, *value_lengths= NULL, i; + char **names = NULL, **values= NULL; + + *value= NULL; + *value_length= 0; + ret= Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names, + &value_lengths, &values, 8); + if(ret <= 0) + goto ex; + + for(i= 0; i < num_attrs; i++) { + if(strcmp(name, names[i]) != 0) + continue; + *value= calloc(value_lengths[i] + 1, 1); + if(*value == NULL) + {ret= -1; goto ex;} + memcpy(*value, values[i], value_lengths[i]); + (*value)[value_lengths[i]]= 0; + *value_length= value_lengths[i]; + ret= 1; goto ex; + } + ret= 0; +ex: + Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names, + &value_lengths, &values, 1 << 15); + return(ret); +} + + +int Xorriso_stream_type(struct XorrisO *xorriso, IsoNode *node, + IsoStream *stream, char type_text[], int flag) +{ + int ret, lba; + char text[5]; + + strncpy(text, stream->class->type, 4); + text[4]= 0; + if(strcmp(text, "fsrc") == 0) { + ret= Xorriso__file_start_lba(node, &lba, 0); + if(ret > 0 && lba > 0) + strcpy(type_text, "image"); + else + strcpy(type_text, "disk"); + } else if(strcmp(text, "ziso") == 0) { + strcpy(type_text, "--zisofs"); + } else if(strcmp(text, "osiz") == 0) { + strcpy(type_text, "--zisofs-decode"); + } else if(strcmp(text, "gzip") == 0) { + strcpy(type_text, "--gzip"); + } else if(strcmp(text, "pizg") == 0) { + strcpy(type_text, "--gunzip"); + } else if(strcmp(text, "cout") == 0 || strcmp(text, "boot") == 0 || + strcmp(text, "user") == 0 || strcmp(text, "extf") == 0) { + strcpy(type_text, text); + } else { + Text_shellsafe(text, type_text, 0); + } + return(1); +} + + +/* + @param flag bit0= do not report to result but only retrieve md5 text + @return 1= ok, 0= no md5 available, <0= other error +*/ +int Xorriso_get_md5(struct XorrisO *xorriso, void *in_node, char *path, + char md5[16], int flag) +{ + int ret= 1, i; + char *wpt; + IsoImage *image; + IsoNode *node; + + ret= Xorriso_get_volume(xorriso, &image, 0); + if(ret <= 0) + goto ex; + 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)) + return(0); + ret= iso_file_get_md5(image, (IsoFile *) node, md5, 0); + Xorriso_process_msg_queues(xorriso,0); + if(ret <= 0) + goto ex; + if(flag & 1) + {ret= 1; goto ex;} + + wpt= xorriso->result_line; + for(i= 0; i < 16; i++) { + sprintf(wpt, "%2.2x", ((unsigned char *) md5)[i]); + wpt+= 2; + } + strcpy(wpt, " "); + wpt+= 2; + Xorriso_getfname(xorriso, path, 1 | 2); + ret= 1; +ex:; + return(ret); +} + + +int Xorriso_make_md5(struct XorrisO *xorriso, void *in_node, char *path, + int flag) +{ + int ret; + off_t size; + IsoNode *node; + + node= (IsoNode *) in_node; + if(node == NULL) { + ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); + if(ret <= 0) + return(ret); + } + if(!LIBISO_ISREG(node)) + return(0); + ret= iso_file_make_md5((IsoFile *) node, 0); + size= iso_file_get_size((IsoFile *) node); + xorriso->pacifier_count+= size; + xorriso->pacifier_byte_count+= size; + Xorriso_pacifier_callback(xorriso, "content bytes read", + xorriso->pacifier_count, 0, "", 0); + Xorriso_process_msg_queues(xorriso, 0); + if(ret < 0) { + Xorriso_report_iso_error(xorriso, "", ret, + "Error when computing MD5", 0, "FAILURE", 1); + return(0); + } + Xorriso_set_change_pending(xorriso, 1); + return(1); +} + + +/* @param flag bit0= do not only sum up sizes but also print subdirs +*/ +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 i, ret, no_sort= 0, filec= 0, l; + IsoDirIter *iter= NULL; + IsoNode *node, **node_array= NULL; + char *name; + off_t sub_size, report_size, mem= 0; + char *path= NULL, *show_path= NULL, *sfe= NULL; + + sfe= malloc(5*SfileadrL); + path= malloc(SfileadrL); + show_path= malloc(SfileadrL); + if(path==NULL || show_path==NULL || sfe==NULL) { + Xorriso_no_malloc_memory(xorriso, &sfe, 0); + {ret= -1; goto ex;} + } + + *size= 0; + ret= iso_dir_get_children(dir_node, &iter); + if(ret<0) { +cannot_create_iter:; + Xorriso_cannot_create_iter(xorriso, ret, 0); + {ret= -1; goto ex;} + } + for(i= 0; iso_dir_iter_next(iter, &node) == 1; ) { + sub_size= 0; + name= (char *) iso_node_get_name(node); + strcpy(show_path, rel_path); + if(Sfile_add_to_path(show_path, name, 0)<=0) + goto much_too_long; + if(LIBISO_ISDIR(node)) { + strcpy(path, abs_path); + if(Sfile_add_to_path(path, name, 0)<=0) { +much_too_long:; + Xorriso_much_too_long(xorriso, strlen(path)+strlen(name)+1, 2); + {ret= -1; goto ex;} + } + filec++; + l= strlen(rel_path)+1; + mem+= l; + if(l % sizeof(char *)) + mem+= sizeof(char *)-(l % sizeof(char *)); + if(flag&1) /* diving and counting is done further below */ + continue; + ret= Xorriso_show_du_subs(xorriso, (IsoDir *) node, + path, show_path, &sub_size, boss_mem, 0); + if(ret<0) + goto ex; + if(ret==0) + continue; + } + + if(LIBISO_ISREG(node)) { + sub_size+= iso_file_get_size((IsoFile *) node)+2048; +/* + sub_size+= iso_file_get_size((IsoFile *) node)+strlen(name)+1; +*/ + } + + if(sub_size>0) + (*size)+= sub_size; + Xorriso_process_msg_queues(xorriso,0); + } + + if(filec<=0 || !(flag&1)) + {ret= 1; goto ex;} + + /* Reset iteration */ + iso_dir_iter_free(iter); + iter= NULL; + Xorriso_process_msg_queues(xorriso,0); + + ret= Xorriso_sorted_node_array(xorriso, dir_node, &filec, &node_array, + boss_mem, 1|2|4); + if(ret<0) + goto ex; + if(ret==0) { + no_sort= 1; + ret= iso_dir_get_children(dir_node, &iter); + if(ret<0) + goto cannot_create_iter; + } + + for(i= 0; (no_sort || irequest_to_abort); i++) { + if(no_sort) { + ret= iso_dir_iter_next(iter, &node); + if(ret!=1) + break; + if(!LIBISO_ISDIR(node)) + continue; + } else + node= node_array[i]; + + sub_size= 0; + name= (char *) iso_node_get_name(node); + strcpy(show_path, rel_path); + if(Sfile_add_to_path(show_path, name, 0)<=0) + goto much_too_long; + strcpy(path, abs_path); + if(Sfile_add_to_path(path, name, 0)<=0) + goto much_too_long; + ret= Xorriso_show_du_subs(xorriso, (IsoDir *) node, + path, show_path, &sub_size, boss_mem+mem, flag&1); + if(ret<0) + goto ex; + + if(LIBISO_ISREG(node)) { + sub_size+= iso_file_get_size((IsoFile *) node)+2048; +/* + sub_size+= iso_tree_node_get_size((IsoFile *) node)+strlen(name)+1; +*/ + } + if(sub_size>0) + (*size)+= sub_size; + report_size= sub_size/1024; + if(report_size*1024result_line, "%7.f ",(double) (report_size)); + sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n", + Text_shellsafe(show_path, sfe, 0)); + Xorriso_result(xorriso, 0); + } + ret= 1; +ex:; + if(sfe!=NULL) + free(sfe); + if(path!=NULL) + free(path); + if(show_path!=NULL) + free(show_path); + if(iter!=NULL) + iso_dir_iter_free(iter); + if(node_array!=NULL) + free((char *) node_array); + Xorriso_process_msg_queues(xorriso,0); + return(ret); +} + + +int Xorriso_sorted_dir_i(struct XorrisO *xorriso, IsoDir *dir_node, + int *filec, char ***filev, off_t boss_mem, int flag) +{ + int i,j,ret; + IsoDirIter *iter= NULL; + IsoNode *node; + char *name; + off_t mem; + + (*filec)= 0; + (*filev)= NULL; + + ret= iso_dir_get_children(dir_node, &iter); + if(ret<0) { +cannot_iter:; + Xorriso_cannot_create_iter(xorriso, ret, 0); + {ret= -1; goto ex;} + } + mem= 0; + for(i= 0; iso_dir_iter_next(iter, &node) == 1; ) { + name= (char *) iso_node_get_name(node); + mem+= sizeof(char *)+strlen(name)+8; + (*filec)++; + } + iso_dir_iter_free(iter); + iter= NULL; + if(*filec==0) + {ret= 1; goto ex;} + + ret= Xorriso_check_temp_mem_limit(xorriso, mem+boss_mem, 2); + if(ret<=0) + goto ex; + (*filev)= (char **) calloc(*filec, sizeof(char *)); + if(*filev==NULL) + {ret= -1; goto ex; } + ret= iso_dir_get_children(dir_node, &iter); + if(ret<0) + goto cannot_iter; + for(i= 0; i<*filec; i++) { + ret= iso_dir_iter_next(iter, &node); + if(ret!=1) + break; + name= (char *) iso_node_get_name(node); + (*filev)[i]= strdup(name); + if((*filev)[i]==NULL) { + for(j= 0; jresult_line; + + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + return(ret); + + Sort_argv(filec, filev, 0); + + /* Count valid nodes, warn of invalid ones */ + for(i= 0; iinfo_text, "Not found in ISO image: %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + was_error++; + continue; + } + } + + if((flag&8) && !(flag&(2|4))) { + sprintf(xorriso->info_text, "Valid ISO nodes found: %d\n", filec-was_error); + Xorriso_info(xorriso,1); + if(filec-was_error<=0) + return(!was_error); + } + + passes= 1+!(flag&(4|8)); + for(pass= 0; passrequest_to_abort); i++) { + rpt[0]= 0; + ret= Xorriso_make_abs_adr(xorriso, wd, filev[i], path, 1|2|4); + if(ret<=0) + continue; + ret= Xorriso_fake_stbuf(xorriso, path, &stbuf, &node, ((flag&4) >> 1) | 16); + if(ret<=0) + continue; + if(LIBISO_ISDIR(node) && !(flag&(4|8))) { + if(pass==0) + continue; + if(filec>1) { + strcpy(xorriso->result_line, "\n"); + Xorriso_result(xorriso,0); + sprintf(xorriso->result_line, "%s:\n", Text_shellsafe(filev[i], sfe,0)); + Xorriso_result(xorriso,0); + } + ret= Xorriso_sorted_dir_i(xorriso, + (IsoDir *) node, &dfilec, &dfilev, boss_mem, 0); + if(ret<=0) { + + /* >>> libisofs iterator loop and single item Xorriso_lsx_filev() */; + + } else { + if(flag&1) { + sprintf(xorriso->result_line, "total %d\n", dfilec); + Xorriso_result(xorriso,0); + } + Xorriso_ls_filev(xorriso, path, + dfilec, dfilev, boss_mem, (flag&1)|2|8); + } + if(dfilec>0) + Sfile_destroy_argv(&dfilec, &dfilev, 0); + continue; + } else + if(pass>0) + continue; + link_target[0]= 0; + if((flag&5)==1) { /* -ls_l */ + iso_node_get_acl_text(node, &a_text, &d_text, 16); + ret= Xorriso_format_ls_l(xorriso, &stbuf, + 1 | ((a_text != NULL || d_text != NULL) << 1)); + iso_node_get_acl_text(node, &a_text, &d_text, 1 << 15); + if(ret<=0) + continue; + if(LIBISO_ISLNK(node)) { + if(Sfile_str(link_target, (char *) iso_symlink_get_dest( + (IsoSymlink *) node), 0)<=0) + link_target[0]= 0; + } + } else if(flag&4) { /* -du or -dus */ + size= stbuf.st_size; + if(S_ISDIR(stbuf.st_mode)) { + ret= Xorriso_show_du_subs(xorriso, (IsoDir *) node, + path, filev[i], &size, boss_mem, flag&1); + if(ret<0) + return(-1); + if(ret==0) + continue; + } + sprintf(rpt, "%7.f ",(double) (size/1024)); + } + if(link_target[0] && (flag&5)==1) + sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s -> %s\n", + Text_shellsafe(filev[i], sfe, 0), + Text_shellsafe(link_target, sfe2, 0)); + else + sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n", + Text_shellsafe(filev[i], sfe, 0)); + Xorriso_result(xorriso, 0); + } + return(!was_error); +} + + +/* This function needs less buffer memory than Xorriso_ls_filev() but cannot + perform structured pattern matching as done by Xorriso_expand_pattern() + for subsequent Xorriso_ls_filev(). + @param flag bit0= long format + bit1= only check for directory existence + bit2= do not apply search pattern but accept any file + bit3= just count nodes and return number +*/ +int Xorriso_ls(struct XorrisO *xorriso, int flag) +{ + int ret, is_dir= 0, i, filec= 0, failed_at, no_sort= 0; + IsoNode *node, **node_array= NULL; + IsoDir *dir_node; + IsoImage *volume; + IsoDirIter *iter= NULL; + char sfe[5*SfileadrL], sfe2[5*SfileadrL], link_target[SfileadrL], *npt, *rpt; + struct stat stbuf; + + rpt= xorriso->result_line; + + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + return(ret); + + ret= Xorriso_node_from_path(xorriso, volume, xorriso->wdi, &node, 0); + if(ret<=0) + goto wdi_is_not_a_dir; + if(LIBISO_ISDIR(node)) + is_dir= 1; + if(!is_dir) { +wdi_is_not_a_dir:; + sprintf(xorriso->info_text, + "Working directory path does not lead to a directory in ISO image"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + if(flag&2) + {ret= 1; goto ex;} + + dir_node= (IsoDir *) node; + ret= iso_dir_get_children(dir_node, &iter); + if(ret<0) { +cannot_create_iter:; + Xorriso_cannot_create_iter(xorriso, ret, 0); + {ret= -1; goto ex;} + } + Xorriso_process_msg_queues(xorriso,0); + + for(i= 0; iso_dir_iter_next(iter, &node) == 1; ) { + npt= (char *) iso_node_get_name(node); + if(!(flag&4)) { + ret= Xorriso_regexec(xorriso, npt, &failed_at, 0); + if(ret) + continue; /* no match */ + } + filec++; + } + /* Reset iteration */ + iso_dir_iter_free(iter); + iter= NULL; + Xorriso_process_msg_queues(xorriso,0); + if(flag&8) + {ret= filec; goto ex;} + sprintf(xorriso->info_text, "Valid ISO nodes found: %d\n", filec); + Xorriso_info(xorriso,1); + + ret= Xorriso_sorted_node_array(xorriso, dir_node, &filec, &node_array, 0, + flag&4); + if(ret<0) + goto ex; + if(ret==0) { + no_sort= 1; + ret= iso_dir_get_children(dir_node, &iter); + if(ret<0) + goto cannot_create_iter; + } + + for(i= 0; irequest_to_abort); i++) { + if(no_sort) { + ret= iso_dir_iter_next(iter, &node); + if(ret!=1) + break; + npt= (char *) iso_node_get_name(node); + if(!(flag&4)) { + ret= Xorriso_regexec(xorriso, npt, &failed_at, 0); + if(ret) + continue; /* no match */ + } + } else + node= node_array[i]; + + npt= (char *) iso_node_get_name(node); + link_target[0]= 0; + if(LIBISO_ISLNK(node)) { + if(Sfile_str(link_target, (char *) iso_symlink_get_dest( + (IsoSymlink *) node), 0)<=0) + link_target[0]= 0; + } + rpt[0]= 0; + if(flag&1) { + ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1); + if(ret<=0) + continue; + ret= Xorriso_format_ls_l(xorriso, &stbuf, 1); + if(ret<=0) + continue; + } + if(link_target[0] && (flag&1)) + sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s -> %s\n", + Text_shellsafe(npt, sfe, 0), + Text_shellsafe(link_target, sfe2, 0)); + else + sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n", + Text_shellsafe(npt, sfe, 0)); + Xorriso_result(xorriso, 0); + } + + ret= 1; +ex:; + if(iter!=NULL) + iso_dir_iter_free(iter); + Xorriso_process_msg_queues(xorriso,0); + if(node_array!=NULL) + free((char *) node_array); + return(ret); +} + + +/* @param flag bit0= count results rather than storing them + bit1= this is a recursion + bit2= prepend wd (automatically done if wd[0]!=0) +*/ +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 ret, failed_at; + IsoDirIter *iter= NULL; + IsoNode *node; + char *name; + char *adr= NULL; + + adr= malloc(SfileadrL); + if(adr==NULL) { + Xorriso_no_malloc_memory(xorriso, &adr, 0); + {ret= -1; goto ex;} + } + + if(!(flag&2)) + *dive_count= 0; + else + (*dive_count)++; + ret= Xorriso_check_for_root_pattern(xorriso, filec, filev, count_limit, + mem, (flag&1)|2); + if(ret!=2) + goto ex; + + ret= iso_dir_get_children(dir, &iter); + if(ret<0) { + Xorriso_cannot_create_iter(xorriso, ret, 0); + {ret= -1; goto ex;} + } + while(iso_dir_iter_next(iter, &node) == 1) { + name= (char *) iso_node_get_name(node); + 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) { /* no match */ + if(failed_at <= *dive_count) /* no hope for a match */ + continue; + + if(!LIBISO_ISDIR(node)) { + + /* >>> How to deal with softlinks ? */ + + continue; + } + /* dive deeper */ + ret= Xorriso_obtain_pattern_files_i( + xorriso, adr, (IsoDir *) node, + 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)|2); + if(ret<=0) + goto ex; + } + } + ret= 1; +ex:; + if(adr!=NULL) + free(adr); + if(flag&2) + (*dive_count)--; + if(iter != NULL) + iso_dir_iter_free(iter); + return(ret); +} + + +/* @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_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]; + IsoImage *volume; + IsoDir *dir= NULL, *root_dir; + IsoNode *iso_node; + + *filec= 0; + *filev= NULL; + + xorriso->search_mode= 3; + xorriso->structured_search= 1; + + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + return(ret); + root_dir= iso_image_get_root(volume); + if(root_dir==NULL) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "While expanding pattern : Cannot obtain root node of ISO image"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + ret= -1; goto ex; + } + + for(i= 0; iwdi does not exist yet, but one may + not use it as base for relative address searches. + */ + ret= Xorriso_node_from_path(xorriso, volume, xorriso->wdi, &iso_node, 1); + dir= (IsoDir *) iso_node; + if(ret<=0) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "While expanding pattern %s : Working directory does not exist in ISO image", + Text_shellsafe(patterns[i], sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + if(!LIBISO_ISDIR((IsoNode *) dir)) { + sprintf(xorriso->info_text, + "Working directory path does not lead to a directory in ISO image"); + 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_i(xorriso, "", dir, &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++; + Xorriso_eval_nonmatch(xorriso, patterns[i], &nonconst_mismatches, mem, 0); + } + } + + 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; iresult_line, 0); + while(1) { + stream= input_stream; + input_stream= iso_stream_get_input_stream(stream, 0); + if(input_stream == NULL) + break; + strcat(xorriso->result_line, " < "); + Xorriso_stream_type(xorriso, node, stream, type_text, 0); + strcat(xorriso->result_line, type_text); + ret= iso_stream_get_external_filter(stream, &cmd, 0); + if(ret < 0) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_report_iso_error(xorriso, "", ret, + "Error when inquiring filter command of node", 0, "FAILURE", 1); + ret= 0; goto ex; + } + if(ret > 0) { + strcat(xorriso->result_line, ":"); + Text_shellsafe(cmd->name, xorriso->result_line, 1); + } + if(strlen(xorriso->result_line) > SfileadrL) { + Xorriso_result(xorriso, 0); + xorriso->result_line[0]= 0; + } + } + strcat(xorriso->result_line, " < "); + Xorriso_stream_type(xorriso, node, stream, type_text, 0); + strcat(xorriso->result_line, type_text); + + source_path= iso_stream_get_source_path(stream, 0); + if(source_path != NULL) { + strcat(xorriso->result_line, ":"); + Text_shellsafe(source_path, xorriso->result_line, 1); + } + + strcat(xorriso->result_line, "\n"); + Xorriso_result(xorriso, 0); + ret= 1; +ex:; + if(source_path != NULL) + free(source_path); + return(ret); +} + + +/* @param damage_start Returns first damaged byte address + @param damage_end Returns first byte address after last damaged byte + @return <0 error, 0=undamaged , 1=damaged +*/ +int Xorriso_file_eval_damage(struct XorrisO *xorriso, IsoNode *node, + off_t *damage_start, off_t *damage_end, + int flag) +{ + int *start_lbas= NULL, *end_lbas= NULL, lba_count= 0, sect; + int i, sectors, sector_size, ret; + off_t sect_base= 0, size= 0, byte; + struct SectorbitmaP *map; + + *damage_start= *damage_end= -1; + map= xorriso->in_sector_map; + if(map == NULL) + return(0); + Sectorbitmap_get_layout(map, §ors, §or_size, 0); + sector_size/= 2048; + + ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas, + &size, 0); + if(ret <= 0) { + Xorriso_process_msg_queues(xorriso, 0); + return(ret); + } + for(sect= 0; sect < lba_count; sect++) { + for(i= start_lbas[sect]; i <= end_lbas[sect]; i+= sector_size) { + if(Sectorbitmap_is_set(map, i / sector_size, 0) == 0) { + byte= ((off_t) 2048) * ((off_t) (i - start_lbas[sect])) + sect_base; + if(*damage_start < 0 || byte < *damage_start) + *damage_start= byte; + if(byte + (off_t) 2048 > *damage_end) + *damage_end= byte + (off_t) 2048; + } + } + sect_base+= ((off_t) 2048) * + ((off_t) (end_lbas[sect] - start_lbas[sect] + 1)); + } + if(*damage_end > size) + *damage_end= size; + if(start_lbas != NULL) + free((char *) start_lbas); + if(end_lbas != NULL) + free((char *) end_lbas); + if(*damage_start < 0) + return(0); + return(1); +} + + +int Xorriso_report_lba(struct XorrisO *xorriso, char *show_path, + IsoNode *node, int flag) +{ + int ret, *start_lbas= NULL, *end_lbas= NULL, lba_count, i; + off_t size; + char sfe[5*SfileadrL]; + + ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas, + &size, 0); + if(ret < 0) { + Xorriso_process_msg_queues(xorriso, 0); + {ret= -1; goto ex;} + } + if(ret == 0) + {ret= 1; goto ex;} /* it is ok to ignore other types */ + for(i= 0; i < lba_count; i++) { + sprintf(xorriso->result_line, + "File data lba: %2d , %8d , %8d , %8.f , %s\n", + i, start_lbas[i], end_lbas[i] + 1 - start_lbas[i], (double) size, + Text_shellsafe(show_path, sfe, 0)); + Xorriso_result(xorriso, 0); + } + ret= 1; +ex:; + if(start_lbas != NULL) + free((char *) start_lbas); + if(end_lbas != NULL) + free((char *) end_lbas); + return(ret); +} + + +int Xorriso_report_damage(struct XorrisO *xorriso, char *show_path, + IsoNode *node, int flag) +{ + int ret; + off_t size= 0, damage_start, damage_end; + char sfe[5*SfileadrL]; + + ret= Xorriso_file_eval_damage(xorriso, node, &damage_start, &damage_end, 0); + if(ret < 0) + return(0); + + if(LIBISO_ISREG(node)) + size= iso_file_get_size((IsoFile *) node); + if(ret > 0) { + sprintf(xorriso->result_line, "File damaged : %8.f , %8.f , %8.f , %s\n", + (double) damage_start, (double) (damage_end - damage_start) , + (double) size, Text_shellsafe(show_path, sfe, 0)); + Xorriso_result(xorriso, 0); + } else { + sprintf(xorriso->result_line, "File seems ok: %8.f , %8.f , %8.f , %s\n", + -1.0, -1.0, (double) size, Text_shellsafe(show_path, sfe, 0)); + Xorriso_result(xorriso, 0); + } + return(1); +} + + +/* @param flag bit0= do not accept hln_targets[i] != NULL as *node_idx + bit1= use *node_idx as found index rather than searching it + bit2= with bit1: use xorriso->node_array rather than hln_array +*/ +int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node, + int *node_idx, int *min_hl, int *max_hl, int flag) +{ + int idx, ret, i, node_count; + void *np, **node_array; + + node_array= xorriso->hln_array; + node_count= xorriso->hln_count; + *min_hl= *max_hl= -1; + np= node; + if(flag & 2) { + idx= *node_idx; + if(flag & 4) { + node_array= xorriso->node_array; + node_count= xorriso->node_counter; + } + } else { + *node_idx= -1; + ret= Xorriso_search_in_hln_array(xorriso, np, &idx, 0); + if(ret <= 0) + return(ret); + } + for(i= idx - 1; i >= 0 ; i--) + if(Xorriso__findi_sorted_ino_cmp(&(node_array[i]), &np) != 0) + break; + *min_hl= i + 1; + for(i= idx + 1; i < node_count; i++) + if(Xorriso__findi_sorted_ino_cmp(&(node_array[i]), &np) != 0) + break; + *max_hl= i - 1; + + /* Search for *node_idx */ + if(flag & 2) + return(1); + for(i= *min_hl; i <= *max_hl; i++) + if(node_array[i] == np) { + if((flag & 1) && xorriso->hln_targets != NULL && !(flag & 4)) + if(xorriso->hln_targets[i] != NULL) + continue; + *node_idx= i; + break; + } + return(1); +} + + +/* @param flag bit0=do not complain about non existent node */ +int Xorriso_node_from_path(struct XorrisO *xorriso, IsoImage *volume, + char *path, IsoNode **node, int flag) +{ + int ret; + char sfe[5*SfileadrL], *path_pt; + + path_pt= path; + if(path[0]==0) + path_pt= "/"; + if(volume == NULL) { + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret <= 0) + return(ret); + } + *node= NULL; + ret= iso_tree_path_to_node(volume, path_pt, node); + Xorriso_process_msg_queues(xorriso,0); + if(ret<=0 || (*node)==NULL) { + if(!(flag&1)) { + sprintf(xorriso->info_text, "Cannot find path %s in loaded ISO image", + Text_shellsafe(path_pt, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } + return(0); + } + return(1); +} + + +/* + @param flag bit0= do not remove leading slash + bit1= append flatly to result_line and put out +*/ +int Xorriso_getfname(struct XorrisO *xorriso, char *path, int flag) +{ + int ret, path_offset= 0, bsl_mem; + char *bsl_path= NULL; + + if(path[0] == '/' && !(flag & 1)) + path_offset= 1; + + /* backslash escaped path rather than shellsafe path */ + ret= Sfile_bsl_encoder(&bsl_path, path + path_offset, + strlen(path + path_offset), 8); + if(ret <= 0) + return(-1); + if(flag & 2) { + sprintf(xorriso->result_line + strlen(xorriso->result_line), + "%s\n", bsl_path[0] ? bsl_path : "."); + } else { + sprintf(xorriso->result_line, "# file: %s\n", bsl_path[0] ? bsl_path : "."); + } + free(bsl_path); + bsl_path= NULL; + /* temporarily disable -backslash_codes with result output */ + bsl_mem= xorriso->bsl_interpretation; + xorriso->bsl_interpretation= 0; + Xorriso_result(xorriso, 0); + xorriso->bsl_interpretation= bsl_mem; + return(1); +} + + +int Xorriso_is_plain_image_file(struct XorrisO *xorriso, void *in_node, + char *path, int flag) +{ + int ret, lba; + IsoStream *stream; + IsoNode *node; + + node= (IsoNode *) in_node; + if(node == NULL) { + ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); + if(ret<=0) + return(ret); + } + + ret= Xorriso__file_start_lba(node, &lba, 0); + if(ret > 0) { /* Stream source is from loaded image */ + stream= iso_file_get_stream((IsoFile *) node); + if(stream != NULL) + if(iso_stream_get_input_stream(stream, 0) == NULL) + return(1); + } + return(0); +} + diff --git a/xorriso/iso_tree.h b/xorriso/iso_tree.h new file mode 100644 index 00000000..91f260bc --- /dev/null +++ b/xorriso/iso_tree.h @@ -0,0 +1,92 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/lib_mgt.c b/xorriso/lib_mgt.c new file mode 100644 index 00000000..fe7ebabd --- /dev/null +++ b/xorriso/lib_mgt.c @@ -0,0 +1,483 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains functions which manage the relation between xorriso + and the libraries: libburn, libisofs, libisoburn. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* for -charset */ +#include +#include + + +#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, µ); + 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", ¬e_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_numberfailure_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, µ); + 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, µ); + 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, µ); + 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); +} + diff --git a/xorriso/lib_mgt.h b/xorriso/lib_mgt.h new file mode 100644 index 00000000..065ffd13 --- /dev/null +++ b/xorriso/lib_mgt.h @@ -0,0 +1,78 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 + +/* The library which does MMC optical drive operations */ +#include + +/* The library which enhances overwriteable media with ISO 9660 multi-session + capabilities via the method invented by Andy Polyakov for growisofs */ +#include + +/* 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 */ + diff --git a/xorriso/make_xorriso_standalone.sh b/xorriso/make_xorriso_standalone.sh index e2170ae9..acce1f01 100755 --- a/xorriso/make_xorriso_standalone.sh +++ b/xorriso/make_xorriso_standalone.sh @@ -134,10 +134,58 @@ xorriso/convert_man_to_html.sh create_dir "$lone_dir"/xorriso copy_files \ - xorriso/xorrisoburn.[ch] \ - xorriso/xorriso.[ch] \ + xorriso/xorriso.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/changelog.txt \ @@ -237,7 +285,7 @@ then # patch xorriso/xorriso.c to be 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/' \ - "$lone_dir"/xorriso/xorriso.c + "$lone_dir"/xorriso/xorriso_main.c else diff --git a/xorriso/match.c b/xorriso/match.c new file mode 100644 index 00000000..d22fb6e3 --- /dev/null +++ b/xorriso/match.c @@ -0,0 +1,755 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains the implementation of functions for pattern matching. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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;ire_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=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 || ire_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;ire_fill;i++) { + *failed_at= i; + npt= strchr(cpt,'/'); + if(npt==NULL) { + if(ire_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; kre_fill; k++) { + if(xorriso->re_constants[k]==NULL) + break; + if(xorriso->re_constants[k][0]==0) + break; + } + if(kre_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; iwdx); + 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; iwdx); + 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); +} + diff --git a/xorriso/match.h b/xorriso/match.h new file mode 100644 index 00000000..14a457d2 --- /dev/null +++ b/xorriso/match.h @@ -0,0 +1,74 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/misc_funct.c b/xorriso/misc_funct.c new file mode 100644 index 00000000..397996be --- /dev/null +++ b/xorriso/misc_funct.c @@ -0,0 +1,1177 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains the miscellaneous helper functions of xorriso. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "sfile.h" +#include "misc_funct.h" + + +/* --------------------------------- misc --------------------------------- */ + + +int Strcmp(const void *pt1, const void *pt2) +{ + return(strcmp(*((char **) pt1), *((char **) pt2))); +} + + +int Sort_argv(int argc, char **argv, int flag) +{ + if(argc<=0) + return(2); + qsort(argv,(size_t) argc,sizeof(char *),Strcmp); + return(1); +} + + +static int Text_to_argv(char *text, int *argc, char ***argv, int flag) +{ + char *npt, *cpt; + int pass; + + *argv= NULL; + *argc= 0; + for(pass= 0; pass < 2; pass++) { + if(pass) { + if(*argc == 0) + return(1); + (*argv)= calloc(*argc, sizeof(char *)); + if(*argv == NULL) { + *argc= 0; + return(-1); + } + *argc= 0; + } + for(npt= cpt= text; npt != NULL; cpt= npt + 1) { + npt= strchr(cpt, '\n'); + if(pass) { + if(npt != NULL) + *npt= 0; + (*argv)[*argc]= cpt; + } + (*argc)++; + } + } + return(1); +} + + +static int Count_diffs(int argc1, char **argv1, int argc2, char **argv2, + int flag) +{ + int count= 0, i1= 0, i2= 0, cmp, end_corr= 0; + + Sort_argv(argc1, argv1, 0); + Sort_argv(argc2, argv2, 0); + + while(1) { + if(i1 >= argc1) { + count+= argc2 - i2 - end_corr; + break; + } + if(i2 >= argc2) { + count+= argc1 - i1 - end_corr; + break; + } + cmp= strcmp(argv1[i1], argv2[i2]); + if(cmp == 0) { + end_corr= 0; + i1++; + i2++; + } else if(cmp > 0) { + count++; + end_corr= 1; + i2++; + if(i2 < argc2 && i1 < argc1 - 1) + if(strcmp(argv1[i1 + 1], argv2[i2]) == 0) { + i1++; + end_corr= 0; + } + } else { + count++; + end_corr= 1; + i1++; + if(i1 < argc1 && i2 < argc2 - 1) + if(strcmp(argv2[i2 + 1], argv1[i1]) == 0) { + i2++; + end_corr= 0; + } + } + } + return(count); +} + + +/* + @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) +{ + int ret, argc1= 0, argc2= 0; + char **argv1= NULL, **argv2= NULL, *copy1= NULL, *copy2= NULL; + + if(!(flag & 1)) + *diff_count= 0; + if(text1 == NULL && text2 == NULL) + return(1); + if(text1 != NULL) { + copy1= strdup(text1); + if(copy1 == NULL) + {ret= -1; goto ex;} + ret= Text_to_argv(copy1, &argc1, &argv1, 0); + if(ret <= 0) + {ret= -1; goto ex;} + } + if(text2 != NULL) { + copy2= strdup(text2); + if(copy2 == NULL) + {ret= -1; goto ex;} + ret= Text_to_argv(copy2, &argc2, &argv2, 0); + if(ret <= 0) + {ret= -1; goto ex;} + } + ret= Count_diffs(argc1, argv1, argc2, argv2, 1); + if(ret < 0) + goto ex; + *diff_count+= ret; + ret= (*diff_count == 0); +ex:; + if(argv1 != NULL) + free(argv1); + if(argv2 != NULL) + free(argv2); + if(copy1 != NULL) + free(copy1); + if(copy2 != NULL) + free(copy2); + return ret; +} + + +/** 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) +/* + bit0= default value -1 rather than 0 +*/ +{ + int c; + double ret= 0.0; + + if(flag&1) + ret= -1.0; + if(text[0]==0) + return(ret); + sscanf(text,"%lf",&ret); + c= text[strlen(text)-1]; + if(c=='k' || c=='K') ret*= 1024.0; + if(c=='m' || c=='M') ret*= 1024.0*1024.0; + if(c=='g' || c=='G') ret*= 1024.0*1024.0*1024.0; + if(c=='t' || c=='T') ret*= 1024.0*1024.0*1024.0*1024.0; + if(c=='p' || c=='P') ret*= 1024.0*1024.0*1024.0*1024.0*1024.0; + if(c=='e' || c=='E') ret*= 1024.0*1024.0*1024.0*1024.0*1024.0*1024.0; + if(c=='s' || c=='S') ret*= 2048.0; + return(ret); +} + + +int Decode_date_input_format(struct tm *erg, char *text, int flag) +/* MMDDhhmm[[CC]YY][.ss]] */ +{ + int i,l,year; + time_t current_time; + struct tm *now; + + current_time= time(0); + now= localtime(¤t_time); + for(i=0;i'9') + break; + if(i!=8 && i!=10 && i!=12) + return(0); + if(text[i]==0) + goto decode; + if(text[i]!='.' || l!=15) + return(0); + i++; + if(text[i]<'0'||text[i]>'9') + return(0); + i++; + if(text[i]<'0'||text[i]>'9') + return(0); + +decode:; + /* MMDDhhmm[[CC]YY][.ss]] */ + i= 0; + erg->tm_mon= 10*(text[0]-'0')+text[1]-'0'-1; + erg->tm_mday= 10*(text[2]-'0')+text[3]-'0'; + erg->tm_hour= 10*(text[4]-'0')+text[5]-'0'; + erg->tm_min= 10*(text[6]-'0')+text[7]-'0'; + erg->tm_sec= 0; + if(l==8) + return(1); + if(l>10){ + year= 1000*(text[8]-'0')+100*(text[9]-'0')+10*(text[10]-'0')+(text[11]-'0'); + }else{ + year= 1900+10*(text[8]-'0')+(text[9]-'0'); + if(year<1970) + year+= 100; + } + erg->tm_year= year-1900; + if(l<=12) + return(1); + erg->tm_sec= 10*(text[13]-'0')+text[14]-'0'; + return(1); +} + + +int Decode_date_weekday(char *text, int flag) +{ + int i; + static char days[][4]= {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", ""}; + + for(i= 0; days[i][0]!=0; i++) + if(strncmp(text,days[i],3)==0) + return(i); + if((strlen(text)==3 || (strlen(text)==4 && text[3]==',')) && + isalpha(text[0]) && isalpha(text[1]) && isalpha(text[2])) + return(7); + return(-1); +} + + +int Decode_date_month(char *text, int flag) +{ + int i; + static char months[][4]= {"Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""}; + + for(i= 0; months[i][0]!=0; i++) + if(strncmp(text,months[i],3)==0) + return(i); + return(-1); +} + + +/* @return -1=not a number, -2=not a day , 1 to 31 day of month */ +int Decode_date_mday(char *text, int flag) +{ + int ret, i; + + for(i= 0; text[i]!=0; i++) + if(!isdigit(text[i])) + return(-1); + if(strlen(text)>2 || text[0]==0) + return(-2); + sscanf(text, "%d", &ret); + if(ret<=0 || ret>31) + return(-2); + return(ret); +} + +int Decode_date_hms(char *text, struct tm *erg, int flag) +{ + int i, hour= -1, minute= -1, second= 0; + + for(i= 0; i<9; i+= 3) { + if(i==6&&text[i]==0) + break; + if(!isdigit(text[i])) + return(-1); + if(!isdigit(text[i+1])) + return(-1); + if(text[i+2]!=':' && !(text[i+2]==0 && i>=3)) + return(-1); + if(i==0) + sscanf(text+i,"%d",&hour); + else if(i==3) + sscanf(text+i,"%d",&minute); + else + sscanf(text+i,"%d",&second); + } + if(hour<0 || hour>23 || minute<0 || minute>59 || second>59) + return(-1); + erg->tm_hour= hour; + erg->tm_min= minute; + erg->tm_sec= second; + return(1); +} + + +/* @return -1=not a number, -2=not a year , >=0 years AD */ +int Decode_date_year(char *text, int flag) +{ + int ret, i; + + for(i= 0; text[i]!=0; i++) + if(!isdigit(text[i])) + return(-1); + if(strlen(text)!=4) + return(-2); + sscanf(text, "%d", &ret); + if(ret<0 || ret>3000) + return(-2); + return(ret); +} + + +int Decode_date_timezone(char *text, struct tm *erg, int flag) +{ + int i; + static char tzs[][5]= {"GMT", "CET", "CEST", "0000", ""}; + + for(i= 0; tzs[i][0]!=0; i++) + if(strcmp(text,tzs[i])==0) { + + /* ??? >>> what to do with timezone info ? Add to ->tm_hour ? */ + + return(1); + } + if(text[0]=='+' || text[0]=='-') { + for(i= 1; text[i]!=0; i++) + if(!isdigit(text[i])) + return(-1); + if(i!=5) + return(-1); + + /* ??? >>> what to do with timezone info ? Add to ->tm_hour ? */ + + return(1); + } else { + for(i= 0; text[i]!=0; i++) + if(text[i]<'A' || text[i]>'Z') + return(-1); + if(i!=3 && i!=4) + return(-1); + return(2); + } +} + + +int Decode_date_output_format(struct tm *erg, char *text, int flag) +/* Thu Nov 8 09:07:50 CET 2007 */ +/* Sat, 03 Nov 2007 08:58:30 +0100 */ +/* Nov 7 23:24 */ +{ + int ret, i, argc= 0, seen_year= 0, seen_month= 0, seen_day= 0, seen_time= 0; + char **argv= NULL; + struct tm *now; + time_t timep; + + memset(erg, 0, sizeof(*erg)); + erg->tm_isdst= -1; + ret= Sfile_make_argv("xorriso", text, &argc, &argv, 0); + if(ret<=0) + goto ex; + for(i= 1; i=0) { + seen_month= 1; + erg->tm_mon= ret; + continue; + } + } + if(!seen_day) { + ret= Decode_date_mday(argv[i], 0); + if(ret>0) { + seen_day= 1; + erg->tm_mday= ret; + continue; + } + if(ret==-2) /* first pure number must be day of month */ + {ret= 0; goto ex;} + } + if(!seen_time) { + ret= Decode_date_hms(argv[i], erg, 0); + if(ret>0) { + seen_time= 1; + continue; + } + } + if(!seen_year) { + ret= Decode_date_year(argv[i], 0); + if(ret>0) { + erg->tm_year= ret-1900; + seen_year= 1; + continue; + } + } + + /* ignorants have to stay at the end of the loop */ + + ret= Decode_date_timezone(argv[i], erg, 0); + if(ret>=0) + continue; + ret= Decode_date_weekday(argv[i], 0); + if(ret>=0) + continue; /* ignore weekdays */ + + {ret= 0; goto ex;} /* unrecognizable component */ + } + + if(!(seen_day && seen_month)) + {ret= 0; goto ex;} + if(!seen_year) { /* then use this year */ + timep= time(NULL); + now= localtime(&timep); + erg->tm_year= now->tm_year; + } + ret= 1; +ex: + Sfile_make_argv("", "", &argc, &argv, 2); /* release storage */ + return(ret); +} + + +int Decode_ecma119_format(struct tm *erg, char *text, int flag) +/* YYYYMMDDhhmmsscc */ +/* 2010040711405800 */ +{ + int i, l, num; + + memset(erg, 0, sizeof(*erg)); + erg->tm_isdst= -1; + l= strlen(text); + if(l != 16) + return(0); + for(i= 0; i < l; i++) + if(text[i] < '0' || text[i] > '9') + return(0); + num= 0; + for(i= 0; i < 4; i++) + num= num * 10 + text[i] - '0'; + if(num < 1970 || num > 3000) + return(0); + erg->tm_year = num - 1900; + erg->tm_mon= 10*(text[4]-'0')+text[5]-'0'-1; + if(erg->tm_mon > 12) + return(0); + erg->tm_mday= 10*(text[6]-'0')+text[7]-'0'; + if(erg->tm_mday > 31) + return(0); + erg->tm_hour= 10*(text[8]-'0')+text[9]-'0'; + if(erg->tm_hour > 23) + return(0); + erg->tm_min= 10*(text[10]-'0')+text[11]-'0'; + if(erg->tm_min > 59) + return(0); + erg->tm_sec= 10*(text[12]-'0')+text[13]-'0'; + if(erg->tm_sec > 59) + return(0); + return(1); +} + + +int Decode_xorriso_timestamp(struct tm *erg, char *code, int flag) + /* 2007.11.07.225624 */ +{ + char buf[20]; + int year,month,day,hour= 0,minute= 0,second= 0, i, l, mem; + + memset(erg, 0, sizeof(*erg)); + erg->tm_isdst= -1; + + l= strlen(code); + if(l>17 || l<10) + return(0); + strcpy(buf, code); + for(i= 0; buf[i]!=0 && i<4; i++) + if(!isdigit(buf[i])) + return(0); + if(buf[4]!='.') + return(0); + buf[4]= 0; + sscanf(buf, "%d", &year); + if(year<1900 || year>3000) + return(0); + if(!(isdigit(buf[5]) && isdigit(buf[6]) && buf[7]=='.')) + return(0); + buf[7]= 0; + sscanf(buf+5, "%d", &month); + if(month<1 || month>12) + return(0); + if(!(isdigit(buf[8]) && isdigit(buf[9]) && (buf[10]=='.' || buf[10]==0))) + return(0); + buf[10]= 0; + sscanf(buf+8, "%d", &day); + if(day<1 || day>31) + return(0); + if(l==10) + goto done; + if(!(isdigit(buf[11]) && isdigit(buf[12]) && + (isdigit(buf[13]) || buf[13]==0))) + return(0); + mem= buf[13]; + buf[13]= 0; + sscanf(buf+11, "%d", &hour); + buf[13]= mem; + if(hour<0 || hour>23) + return(0); + if(l==13) + goto done; + if(!(isdigit(buf[13]) && isdigit(buf[14]) && + (isdigit(buf[15]) || buf[15]==0))) + return(0); + mem= buf[15]; + buf[15]= 0; + sscanf(buf+13, "%d", &minute); + buf[15]= mem; + if(minute<0 || minute>59) + return(0); + if(l==15) + goto done; + if(!(isdigit(buf[15]) && isdigit(buf[16]) && buf[17]==0)) + return(0); + sscanf(buf+15, "%d", &second); + if(second<0 || second>59) + return(0); + +done:; + erg->tm_year= year-1900; + erg->tm_mon= month-1; + erg->tm_mday= day; + erg->tm_hour= hour; + erg->tm_min= minute; + erg->tm_sec= second; + return(1); +} + + +time_t Decode_timestring(char *code, time_t *date, int flag) +{ + char *cpt,scale_chr; + double value,seconds; + struct tm result_tm; + int seconds_valid= 0; + + *date= 0; + cpt= code; + if(code[0]=='-' || code[0]=='+' || code[0]=='=' || code[0]=='@'){ + if(code[1]==0) + return(0); + if(!isdigit(code[1])) + return(0); + value= -1; + if(code[0]=='=' || code[0]=='@') { + seconds= 0; + sscanf(code+1,"%lf",&value); + } else { + seconds= time(NULL); + sscanf(code,"%lf",&value); + } + scale_chr= code[strlen(code)-1]; + if(isalpha(scale_chr)) + scale_chr= tolower(scale_chr); + if (scale_chr=='s') seconds+= 1.0*value; + else if(scale_chr=='h') seconds+= 3600.0*value; + else if(scale_chr=='d') seconds+= 86400.0*value; + else if(scale_chr=='w') seconds+= 86400.0*7.0*value; + else if(scale_chr=='m') seconds+= 86400.0*31.0*value; + else if(scale_chr=='y') seconds+= 86400.0*(365.25*value+1.0); + else seconds+= 1.0*value; + seconds_valid= 1; + goto completed; + } else if(Sfile_decode_datestr(&result_tm,code,0)>0) { + /* YYMMDD[.hhmm[ss]] */ + result_tm.tm_isdst= -1; + seconds= mktime(&result_tm); + seconds_valid= 1; + goto completed; + } else if(Decode_date_input_format(&result_tm,code,0)>0) { + /* MMDDhhmm[[CC]YY][.ss]] */ + result_tm.tm_isdst= -1; + seconds= mktime(&result_tm); + seconds_valid= 1; + goto completed; + } else if(Decode_xorriso_timestamp(&result_tm, code, 0)>0) { + /* 2007.11.07.225624 */ + seconds= mktime(&result_tm); + seconds_valid= 1; + goto completed; + } else if(Decode_date_output_format(&result_tm, code, 0)>0) { + /* Thu Nov 8 09:07:50 CET 2007 */; + /* Sat, 03 Nov 2007 08:58:30 +0100 */; + /* Nov 7 23:24 */; + seconds= mktime(&result_tm); + seconds_valid= 1; + goto completed; + } else if(Decode_ecma119_format(&result_tm, code, 0)>0) { + /* YYYYMMDDhhmmsscc */ + /* 2010040711405800 */ + seconds= mktime(&result_tm); + seconds_valid= 1; + goto completed; + } + return(0); +completed:; + if(!seconds_valid) + return(0); + *date= seconds; + return(1); +} + + +/* @param flag bit0=with year and seconds + bit1-3= form + 0= ls -l format + 1= timestamp format YYYY.MM.DD.hhmmss + 2= Wdy Mon Day hh:mm:ss Year + 3= Mon Day hh:mm:ss Year + 4= YYMMDD.hhmmss +*/ +char *Ftimetxt(time_t t, char timetext[40], int flag) +{ + char *rpt; + struct tm tms, *tmpt; + static char months[12][4]= { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + static char days[7][4]= {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + int form; + + form= (flag>>1)&7; + tmpt= localtime_r(&t, &tms); + rpt= timetext; + rpt[0]= 0; + if(tmpt==0) + sprintf(rpt+strlen(rpt), "%12.f", (double) t); + else if (form==1) + sprintf(rpt+strlen(rpt), "%4.4d.%2.2d.%2.2d.%2.2d%2.2d%2.2d", + 1900+tms.tm_year, tms.tm_mon+1, tms.tm_mday, + tms.tm_hour, tms.tm_min, tms.tm_sec); + else if (form==2) + sprintf(rpt+strlen(rpt), "%s %s %2.2d %2.2d:%2.2d:%2.2d %4.4d", + days[tms.tm_wday], months[tms.tm_mon], tms.tm_mday, + tms.tm_hour, tms.tm_min, tms.tm_sec, 1900+tms.tm_year); + else if (form==3) + sprintf(rpt+strlen(rpt), "%s %2.2d %2.2d:%2.2d:%2.2d %4.4d", + months[tms.tm_mon], tms.tm_mday, + tms.tm_hour, tms.tm_min, tms.tm_sec, 1900+tms.tm_year); + else if (form == 4) { + if(tms.tm_year>99) + sprintf(rpt+strlen(rpt), "%c", 'A' + (tms.tm_year - 100) / 10); + else + sprintf(rpt+strlen(rpt), "%c", '0' + tms.tm_year / 10); + sprintf(rpt+strlen(rpt), "%1.1d%2.2d%2.2d.%2.2d%2.2d%2.2d", + tms.tm_year % 10, tms.tm_mon + 1, tms.tm_mday, + tms.tm_hour, tms.tm_min, tms.tm_sec); + } else if (flag&1) + sprintf(rpt+strlen(rpt), "%2d %3s %4.4d %2.2d:%2.2d:%2.2d", + tms.tm_mday, months[tms.tm_mon], 1900+tms.tm_year, + tms.tm_hour, tms.tm_min, tms.tm_sec); + else if(time(NULL)-t < 180*86400 && time(NULL)-t >= 0) + sprintf(rpt+strlen(rpt), "%3s %2d %2.2d:%2.2d", + months[tms.tm_mon], tms.tm_mday, tms.tm_hour, tms.tm_min); + else + sprintf(rpt+strlen(rpt), "%3s %2d %4.4d", + months[tms.tm_mon], tms.tm_mday, 1900+tms.tm_year); + return(timetext); +} + + +/* @param flag bit0= single letters */ +char *Ftypetxt(mode_t st_mode, int flag) +{ + if(flag&1) + goto single_letters; + if(S_ISDIR(st_mode)) + return("directory"); + else if(S_ISREG(st_mode)) + return("regular_file"); + else if(S_ISLNK(st_mode)) + return("symbolic_link"); + else if(S_ISBLK(st_mode)) + return("block_device"); + else if(S_ISCHR(st_mode)) + return("char_device"); + else if(S_ISFIFO(st_mode)) + return("name_pipe"); + else if(S_ISSOCK(st_mode)) + return("unix_socket"); + return("unknown"); +single_letters:; + if(S_ISDIR(st_mode)) + return("d"); + else if(S_ISREG(st_mode)) + return("-"); + else if(S_ISLNK(st_mode)) + return("l"); + else if(S_ISBLK(st_mode)) + return("b"); + else if(S_ISCHR(st_mode)) + return("c"); + else if(S_ISFIFO(st_mode)) + return("p"); + else if(S_ISSOCK(st_mode)) + return("s"); + return("?"); +} + + +int Wait_for_input(int fd, int microsec, int flag) +{ + struct timeval wt; + fd_set rds,wts,exs; + int ready; + + FD_ZERO(&rds); + FD_ZERO(&wts); + FD_ZERO(&exs); + FD_SET(fd,&rds); + FD_SET(fd,&exs); + wt.tv_sec= microsec/1000000; + wt.tv_usec= microsec%1000000; + ready= select(fd+1,&rds,&wts,&exs,&wt); + if(ready<=0) + return(0); + if(FD_ISSET(fd,&exs)) + return(-1); + if(FD_ISSET(fd,&rds)) + return(1); + return(0); +} + + +int System_uname(char **sysname, char **release, char **version, + char **machine, int flag) +{ + int ret; + static struct utsname uts; + static int initialized= 0; + + if(initialized == 0) { + ret= uname(&uts); + if(ret != 0) + initialized = -1; + } + if(initialized == -1) + return(0); + if(sysname != NULL) + *sysname= uts.sysname; + if(release != NULL) + *release= uts.release; + if(version != NULL) + *version= uts.version; + if(machine != NULL) + *machine= uts.machine; + return(1); +} + +/* ------------------------------------------------------------------------ */ + + +#ifndef Xorriso_sregex_externaL + +#ifndef Smem_malloC +#define Smem_malloC malloc +#endif +#ifndef Smem_freE +#define Smem_freE free +#endif + + +int Sregex_string_cut(char **handle, char *text, int len, int flag) +/* + bit0= append (text!=NULL) +*/ +{ + int l=0; + char *old_handle; + + if((flag&1)&&*handle!=NULL) + l+= strlen(*handle); + old_handle= *handle; + if(text!=NULL) { + l+= len; + *handle= TSOB_FELD(char,l+1); + if(*handle==NULL) { + *handle= old_handle; + return(0); + } + if((flag&1) && old_handle!=NULL) + strcpy(*handle,old_handle); + else + (*handle)[0]= 0; + if(len>0) + strncat(*handle,text,len); + } else { + *handle= NULL; + } + if(old_handle!=NULL) + Smem_freE(old_handle); + return(1); +} + + +int Sregex_string(char **handle, char *text, int flag) +/* + bit0= append (text!=NULL) +*/ +{ + int ret,l=0; + + if(text!=NULL) + l= strlen(text); + +/* #define Sregex_looking_for_contenT 1 */ +#ifdef Sregex_looking_for_contenT + /* a debugging point if a certain text content has to be caught */ + if(text!=NULL) + if(strcmp(text,"clear")==0) + ret= 0; +#endif + + ret= Sregex_string_cut(handle,text,l,flag&1); + return(ret); +} + + +/* + 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) +{ + int l_e, l_v, l_s, l_esc, i, start_equals_esc; + char *rpt, *wpt, *spt, *npt, *ept; + + if(start[0] == 0) /* It is not allowed to have no start marker */ + return(-1); + l_s= strlen(start); + l_e= strlen(end); + l_esc= strlen(esc); + start_equals_esc= !strcmp(start, esc); + rpt= form; + wpt= result; + wpt[0]= 0; + while(1) { + + /* look for start mark */ + spt= strstr(rpt, start); + if(spt == NULL) { + if((wpt - result) + strlen(rpt) >= result_size) + return(0); + strcpy(wpt, rpt); + wpt+= strlen(wpt); + break; + } + + /* copy cleartext part up to next variable */ + if((wpt - result) + (spt - rpt) >= result_size) + return(0); + strncpy(wpt, rpt, spt - rpt); + wpt+= spt - rpt; + *wpt= 0; + rpt= spt; + npt= spt + l_s; + + /* handle eventual escape */ + if(start_equals_esc) { + if(strncmp(spt + l_s, esc, l_esc) == 0) { + /* copy esc and start */ + if((wpt - result) + l_esc + l_s >= result_size) + return(0); + strncpy(wpt, spt, l_esc + l_s); + wpt+= l_esc + l_s; + rpt+= l_esc + l_s; + *wpt= 0; + continue; + } + } else { + /* escape would be already copied */ + if(l_esc > 0 && spt - form >= l_esc) { + if(strncmp(spt - l_esc, esc, l_esc) == 0) { + /* copy start */ + if((wpt - result) + l_s >= result_size) + return(0); + strncpy(wpt, spt, l_s); + wpt+= l_s; + rpt+= l_s; + *wpt= 0; + continue; + } + } + } + + /* Memorize eventual end mark for default handling */; + ept= NULL; + if(l_e > 0) + ept= strstr(npt, end); + + /* Look for defined variable name */ + for(i = 0; i < num_vars; i++) { + if(strncmp(npt, vars[i][0], strlen(vars[i][0])) == 0 + && (l_e == 0 || strncmp(npt + strlen(vars[i][0]), end, l_e) == 0)) + break; + } + if(i < num_vars) { + /* substitute found variable */ + l_v= strlen(vars[i][0]); + if((wpt - result) + strlen(vars[i][1]) >= result_size) + return(0); + strcpy(wpt, vars[i][1]); + rpt= npt + strlen(vars[i][0]) + l_e; + } else if((flag & 1) && ept != NULL) { + /* skip up to end mark */ + rpt= ept + l_e; + } else if(ept != NULL) { + /* copy start,name,end */ + if((wpt - result) + (ept - rpt) + l_e >= result_size) + return(0); + strncpy(wpt, rpt, (ept - rpt) + l_e); + rpt= ept + l_e; + } else { + /* copy start marker only */ + if((wpt - result) + l_s >= result_size) + return(0); + strncpy(wpt, rpt, l_s); + rpt= rpt + l_s; + } + wpt+= strlen(wpt); + *wpt= 0; + } + return(1); +} + + +/* @param flag bit0= only test expression whether compilable +*/ +int Sregex_match(char *pattern, char *text, int flag) +{ + int ret; + char re_text[2*SfileadrL]; + regex_t re; + regmatch_t match[1]; + + Xorriso__bourne_to_reg(pattern, re_text, 0); + ret= regcomp(&re, re_text, 0); + if(ret != 0) + return(-1); + if(flag & 1) { + regfree(&re); + return(1); + } + ret= regexec(&re, text, 1, match, 0); + regfree(&re); + if(ret != 0) + return(0); + return(1); +} + + +#endif /* Xorriso_sregex_externaL */ + + + +/* @param flag bit0= append to out_text rather than overwrite it +*/ +char *Text_shellsafe(char *in_text, char *out_text, int flag) +{ + int l,i,ol= 0,w=0; + + if(flag&1) + ol= w= strlen(out_text); + /* enclose everything by hard quotes */ + l= strlen(in_text); + out_text[w++]= '\''; + for(i=0;i5*SfileadrL+ol) + goto overflow; + /* escape hard quote within the text */ + out_text[w++]= '\''; + out_text[w++]= '"'; + out_text[w++]= '\''; + out_text[w++]= '"'; + out_text[w++]= '\''; + } else { + if(w+3>5*SfileadrL) { +overflow:; + strncpy(out_text, "'xorriso: TEXT MUCH TOO LONG ... ",33); + break; + } + out_text[w++]= in_text[i]; + } + } + out_text[w++]= '\''; + out_text[w++]= 0; + return(out_text); +} + + +int Hex_to_bin(char *hex, + int bin_size, int *bin_count, unsigned char *bin_data, int flag) +{ + int i, l, acc; + + l= strlen(hex); + if(l % 2 || l == 0) + return(-1); /* malformed */ + *bin_count= 0; + for(i= 0; i < l; i+= 2) { + if(hex[i] >= '0' && hex[i] <= '9') + acc= (hex[i] - '0') << 4; + else if(hex[i] >= 'A' && hex[i] <= 'F') + acc= (hex[i] - 'A' + 10) << 4; + else if(hex[i] >= 'a' && hex[i] <= 'f') + acc= (hex[i] - 'a' + 10) << 4; + else + return(-1); + if(hex[i + 1] >= '0' && hex[i + 1] <= '9') + acc|= (hex[i + 1] - '0'); + else if(hex[i + 1] >= 'A' && hex[i + 1] <= 'F') + acc|= (hex[i + 1] - 'A' + 10); + else if(hex[i + 1] >= 'a' && hex[i + 1] <= 'f') + acc|= (hex[i + 1] - 'a' + 10); + else + return(-1); + if(*bin_count >= bin_size) + return(0); /* overflow */ + bin_data[*bin_count]= acc; + (*bin_count)++; + } + return(1); +} + + +#ifndef Xorriso_fileliste_externaL + +/* ??? ts A71006 : Is this compatible with mkisofs pathspecs ? + I dimly remember so */ + +int Fileliste__target_source_limit(char *line, char sep, char **limit_pt, + int flag) +{ + char *npt; + + for(npt= line;*npt!=0;npt++) { + if(*npt=='\\') { + if(*(npt+1)!=0) + npt++; + continue; + } + if(*npt=='=') + break; + } + if(*npt==0) + npt= NULL; + (*limit_pt)= npt; + return(npt!=NULL); +} + + +int Xorriso__bourne_to_reg(char bourne_expr[], char reg_expr[], int flag) +/* reg_expr should be twice as large as bourne_expr ( + 2 to be exact) */ +/* return: 2= bourne_expr is surely a constant */ +{ + char *wpt,*lpt; + int backslash= 0,is_constant= 1,in_square_brackets= 0; + int first_in_square_brackets=0; + + wpt= reg_expr; + lpt= bourne_expr; + + *(wpt++)= '^'; + + while(*lpt!=0){ + if(first_in_square_brackets>0) + first_in_square_brackets--; + if(!backslash){ + switch(*lpt){ + case '?': + *(wpt++)= '.'; + is_constant= 0; + break;case '*': + *(wpt++)= '.'; + *(wpt++)= '*'; + is_constant= 0; + break;case '.': + *(wpt++)= '\\'; + *(wpt++)= '.'; + break;case '+': + *(wpt++)= '\\'; + *(wpt++)= '+'; + break;case '[': + *(wpt++)= *lpt; + first_in_square_brackets= 2; + in_square_brackets= 1; + is_constant= 0; + break;case ']': + *(wpt++)= *lpt; + in_square_brackets= 0; + break;case '!': + if(first_in_square_brackets) + *(wpt++)= '^'; + else if(in_square_brackets) + *(wpt++)= '!'; + else { + *(wpt++)= '\\'; + *(wpt++)= '!'; + } + break;case '^': + if(in_square_brackets) + *(wpt++)= '^'; + else + *(wpt++)= '\\'; + *(wpt++)= '^'; + break;case '$': + *(wpt++)= '\\'; + *(wpt++)= '$'; + break;case '\\': + backslash= 1; + *(wpt++)= '\\'; + is_constant= 0; + break;default: + *(wpt++)= *lpt; + } + } else { + backslash= 0; + *(wpt++)= *lpt; + } + lpt++; + } + *(wpt++)= '$'; + *wpt= 0; + return(1+(is_constant>0)); +} + + +#endif /* ! Xorriso_fileliste_externaL */ + diff --git a/xorriso/misc_funct.h b/xorriso/misc_funct.h new file mode 100644 index 00000000..286b76bf --- /dev/null +++ b/xorriso/misc_funct.h @@ -0,0 +1,89 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 + + +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 */ + diff --git a/xorriso/opts_a_c.c b/xorriso/opts_a_c.c new file mode 100644 index 00000000..15b57ba5 --- /dev/null +++ b/xorriso/opts_a_c.c @@ -0,0 +1,1901 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains the implementation of options -a* to -c* as mentioned + in man page or info file derived from xorriso.texi. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* for -charset */ +#include +#include +#include + + +#include "xorriso.h" +#include "xorriso_private.h" +#include "xorrisoburn.h" + + +/* Option -abort_on */ +int Xorriso_option_abort_on(struct XorrisO *xorriso, char *severity, int flag) +{ + int ret, sev; + char sfe[5*SfileadrL]; + + ret= Xorriso__text_to_sev(severity, &sev, 0); + if(ret<=0) { + sprintf(xorriso->info_text, + "-abort_on: Not a known severity name : %s", + Text_shellsafe(severity, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(ret); + } + if(Sfile_str(xorriso->abort_on_text,severity,0)<=0) + return(-1); + xorriso->abort_on_severity= sev; + Xorriso_set_abort_severity(xorriso, 0); + return(1); +} + + +/* Option -acl "on"|"off" */ +int Xorriso_option_acl(struct XorrisO *xorriso, char *mode, int flag) +{ + int ret; + + if(strcmp(mode, "off")==0) + xorriso->do_aaip&= ~3; + else if(strcmp(mode, "on")==0) + xorriso->do_aaip|= (1 | 2); + else { + sprintf(xorriso->info_text, "-acl: unknown mode '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= Xorriso_set_ignore_aclea(xorriso, 0); + if(ret <= 0) + return(ret); + return(1); +} + + +/* Option -add */ +/* @param flag bit0=do not report the added item + bit1=do not reset pacifier, no final pacifier message +*/ +int Xorriso_option_add(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int i, end_idx, ret, was_failure= 0, fret, optc= 0, split; + char target[SfileadrL], source[SfileadrL], *ept, eff_path[SfileadrL]; + char **optv= NULL, *rpt, *wpt; + + ret= Xorriso_opt_args(xorriso, "-add", argc, argv, *idx, &end_idx, + &optc, &optv, ((!!xorriso->allow_graft_points)<<2)|2); + if(ret<=0) + goto ex; + + if(!(flag&2)) + Xorriso_pacifier_reset(xorriso, 0); + for(i= 0; iallow_graft_points) { + ret= Fileliste__target_source_limit(target, '=', &ept, 0); + if(ret>0) { + *ept= 0; + strcpy(source, ept+1); + split= 1; + } + /* unescape \= */; + if(split) + rpt= wpt= target; + else + rpt= wpt= source; + for(; *rpt!=0; rpt++) { + if(*rpt=='\\') + if(*(rpt+1)=='=') + continue; + *(wpt++)= *rpt; + } + *wpt= 0; + } + if(split==0) { + strcpy(target, source); + } else if(target[0]!='/') { + ret= Sfile_prepend_path(xorriso->wdi, target, 0); + if(ret<=0) + goto problem_handler; + } + + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, target, eff_path, 2); + if(ret<=0) + goto problem_handler; + strcpy(target, eff_path); + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, source,eff_path,2|4); + if(ret<=0) + goto problem_handler; + strcpy(source, eff_path); + + ret= Xorriso_graft_in(xorriso, NULL, source, target, (off_t)0, (off_t)0, 0); + if(ret<=0 || xorriso->request_to_abort) + goto problem_handler; + sprintf(xorriso->info_text, "Added to ISO image: %s '%s'='%s'\n", + (ret>1 ? "directory" : "file"), (target[0] ? target : "/"), source); + if(!(flag&1)) + Xorriso_info(xorriso, 0); + + continue; /* regular bottom of loop */ +problem_handler:; + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + goto ex; + } + if(!(flag&2)) + Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count, + xorriso->pacifier_total, "", 1); + ret= 1; +ex:; + (*idx)= end_idx; + Xorriso_opt_args(xorriso, "-add", argc, argv, *idx, &end_idx, &optc, &optv, + 256); + if(ret<=0) + return(ret); + return(!was_failure); +} + + +/* Option -add_plainly "none"|"unknown" */ +int Xorriso_option_add_plainly(struct XorrisO *xorriso, char *mode,int flag) +{ + if(strcmp(mode, "none")==0) + xorriso->add_plainly= 0; + if(strcmp(mode, "unknown")==0) + xorriso->add_plainly= 1; + else if(strcmp(mode, "dashed")==0) + xorriso->add_plainly= 2; + else if(strcmp(mode, "any")==0) + xorriso->add_plainly= 3; + else { + sprintf(xorriso->info_text, "-add_plainly: unknown mode '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + return(1); +} + + +/* Option -alter_date , -alter_date_r */ +/* @param flag bit0=recursive (-alter_date_r) +*/ +int Xorriso_option_alter_date(struct XorrisO *xorriso, + char *time_type, char *timestring, + int argc, char **argv, int *idx, int flag) +{ + int i, ret, was_failure= 0, t_type= 0, end_idx, fret; + time_t t; + int optc= 0; + char **optv= NULL; + struct FindjoB *job= NULL; + struct stat dir_stbuf; + + ret= Xorriso_opt_args(xorriso, "-alter_date", argc, argv, *idx, &end_idx, + &optc, &optv, 0); + if(ret<=0) + goto ex; + ret= Xorriso_convert_datestring(xorriso, "-alter_date", time_type, timestring, + &t_type, &t, 0); + if(ret<=0) + goto ex; + for(i= 0; i0 && !xorriso->request_to_abort) + continue; /* regular bottom of loop */ + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + goto ex; + } + ret= 1; +ex:; + (*idx)= end_idx; + Xorriso_opt_args(xorriso, "-alter_date", argc, argv, *idx, &end_idx, &optc, + &optv, 256); + Findjob_destroy(&job, 0); + if(ret<=0) + return(ret); + return(!was_failure); +} + + +/* Option -application_id */ +int Xorriso_option_application_id(struct XorrisO *xorriso, char *name, + int flag) +{ + if(Xorriso_check_name_len(xorriso, name, + (int) sizeof(xorriso->application_id), + "-application_id", 0) <= 0) + return(0); + strcpy(xorriso->application_id,name); + Xorriso_set_change_pending(xorriso, 1); + return(1); +} + + +/* Option -as */ +/* @param flag bit0=do not report the added item + bit1=do not reset pacifier, no final pacifier message +*/ +int Xorriso_option_as(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int end_idx, ret, idx_count; + + end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); + idx_count= end_idx-(*idx); + if(end_idx<=0 || (*idx)>=argc) { + if(idx_count<1) + sprintf(xorriso->info_text, + "-as : Not enough arguments given. Needed: whom do_what %s", + xorriso->list_delimiter); + else + sprintf(xorriso->info_text, + "-as %s : Not enough arguments given. Needed: do_what %s", + argv[*idx], xorriso->list_delimiter); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + if(strcmp(argv[*idx], "cdrecord")==0 || strcmp(argv[*idx], "wodim")==0 || + strcmp(argv[*idx], "cdrskin")==0 || strcmp(argv[*idx], "xorrecord")==0) { + ret= Xorriso_cdrskin(xorriso, argv[*idx], end_idx-(*idx)-1, argv+(*idx)+1, + 0); + if(ret<=0) + goto ex; + } else if(strcmp(argv[*idx], "mkisofs")==0 || + strcmp(argv[*idx], "genisoimage")==0 || + strcmp(argv[*idx], "genisofs")==0 || + strcmp(argv[*idx], "xorrisofs")==0) { + ret= Xorriso_genisofs(xorriso, argv[*idx], end_idx-(*idx)-1, argv+(*idx)+1, + 0); + if(ret<=0) + goto ex; + } else { + sprintf(xorriso->info_text, + "-as : Not a known emulation personality: '%s'", argv[*idx]); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + + ret= 1; +ex:; + (*idx)= end_idx; + return(ret); +} + + +/* Option -assert_volid */ +int Xorriso_option_assert_volid(struct XorrisO *xorriso, char *pattern, + char *severity, int flag) +{ + int ret, sev; + char *sev_text= ""; + + if(strlen(pattern)>=sizeof(xorriso->assert_volid)) { + sprintf(xorriso->info_text, + "Name too long with option -application_id (%d > %d)", + (int) strlen(pattern), (int) sizeof(xorriso->assert_volid)-1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + if(pattern[0]) { + ret= Sregex_match(pattern, "", 1); + if(ret <= 0) { + sprintf(xorriso->info_text, "-assert_volid: Cannot use given pattern."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + if(severity[0] != 0 || pattern[0] != 0) { + if(severity[0] == 0) + sev_text= xorriso->abort_on_text; + else + sev_text= severity; + if(strcmp(sev_text, "NEVER") == 0) + sev_text= "ABORT"; + ret= Xorriso__text_to_sev(sev_text, &sev, 0); + if(ret<=0) { + sprintf(xorriso->info_text, "-assert_volid: Not a known severity name : "); + Text_shellsafe(severity, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(ret); + } + } + if(Sfile_str(xorriso->assert_volid, pattern,0) <= 0) + return(-1); + strcpy(xorriso->assert_volid_sev, sev_text); + return(1); +} + + +/* Option -auto_charset "on"|"off" */ +int Xorriso_option_auto_charset(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode, "off")==0) + xorriso->do_aaip&= ~(256 | 512); + else if(strcmp(mode, "on")==0) + xorriso->do_aaip|= (256 | 512); + else { + sprintf(xorriso->info_text, "-auto_charset: unknown mode '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + return(1); +} + + +/* Option -backslash_codes */ +int Xorriso_option_backslash_codes(struct XorrisO *xorriso, char *mode, + int flag) +{ + char *npt, *cpt; + int l, was; + + was= xorriso->bsl_interpretation; + xorriso->bsl_interpretation= 0; + npt= cpt= mode; + for(; npt!=NULL; cpt= npt+1) { + npt= strchr(cpt,':'); + if(npt==NULL) + l= strlen(cpt); + else + l= npt-cpt; + if(l == 0) + continue; + if(l == 3 && strncmp(cpt, "off", l)==0) { + xorriso->bsl_interpretation= 0; + } else if(l == 16 && strncmp(cpt, "in_double_quotes", l)==0) { + xorriso->bsl_interpretation= (xorriso->bsl_interpretation & ~3) | 1; + } else if(l == 9 && strncmp(cpt, "in_quotes", l)==0) { + xorriso->bsl_interpretation= (xorriso->bsl_interpretation & ~3) | 2; + } else if(l == 17 && strncmp(cpt, "with_quoted_input", l)==0) { + xorriso->bsl_interpretation= (xorriso->bsl_interpretation & ~3) | 3; + } else if(l == 22 && strncmp(cpt, "with_program_arguments", l)==0) { + xorriso->bsl_interpretation= xorriso->bsl_interpretation | 16; + } else if(l == 13 && strncmp(cpt, "encode_output", l)==0) { + xorriso->bsl_interpretation= xorriso->bsl_interpretation | 32 | 64; + } else if(l == 14 && strncmp(cpt, "encode_results", l)==0) { + xorriso->bsl_interpretation= xorriso->bsl_interpretation | 32; + } else if(l == 12 && strncmp(cpt, "encode_infos", l)==0) { + xorriso->bsl_interpretation= xorriso->bsl_interpretation | 64; + } else if(l == 2 && strncmp(cpt, "on", l)==0) { + xorriso->bsl_interpretation= 3 | 16 | 32 | 64; + } else { + if(linfo_text, "-backslash_codes: unknown mode '%s'", cpt); + else + sprintf(xorriso->info_text, + "-backslash_codes: oversized mode parameter (%d)", l); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + xorriso->bsl_interpretation= was; + return(0); + } + } + return(1); +} + + +/* Option -ban_stdio_write */ +int Xorriso_option_ban_stdio_write(struct XorrisO *xorriso, int flag) +{ + xorriso->ban_stdio_write= 1; + return(1); +} + + +/* Option -blank and -format */ +/* @param flag bit0= format rather than blank + @return <=0 error , 1 success, 2 revoked by -reassure +*/ +int Xorriso_option_blank(struct XorrisO *xorriso, char *mode, int flag) +{ + char drive_name[SfileadrL], *cmd= "-blank"; + int aq_ret, ret, aq_flag= 2, mode_flag= 0, as_needed= 0, idx; + off_t size= 0; + + if(flag&1) + cmd= "-format"; + if(xorriso->out_drive_handle == NULL) { + sprintf(xorriso->info_text, + "%s: No output drive set by -dev -or -outdev", cmd); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if(xorriso->in_drive_handle == xorriso->out_drive_handle) { + if(xorriso->volset_change_pending) { + sprintf(xorriso->info_text, + "%s: Image changes pending. -commit or -rollback first.", cmd); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + aq_flag= 3; + } + ret= Xorriso_reassure(xorriso, cmd, + "possibly make unreadable data on outdev", 0); + if(ret<=0) + return(2); + + if(strcmp(mode, "as_needed")==0 || mode[0]==0) + as_needed= 1; + else if(strcmp(mode, "all")==0 || strcmp(mode, "full")==0) + mode_flag= 0; + else if((strcmp(mode, "deformat")==0 || + strcmp(mode, "deformat_sequential")==0) && !(flag&1)) + mode_flag= 2; + else if((strcmp(mode, "deformat_quickest")==0 || + strcmp(mode, "deformat_sequential_quickest")==0) && !(flag&1)) + mode_flag= 3; + else if(strcmp(mode, "fast")==0) + mode_flag= 1; + else if(strncmp(mode, "by_index_", 9)==0 && (flag&1)) { + mode_flag= 128; + idx= -1; + if(strlen(mode)>9) + sscanf(mode+9, "%d", &idx); + if(idx<0 || idx>255) { +unusable_index:; + sprintf(xorriso->info_text, + "-format: mode '%s' provides unusable index number", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + mode_flag|= (idx<<8); + } else if(strncmp(mode, "fast_by_index_", 14)==0 && (flag&1)) { + mode_flag= 1 | 128; + idx= -1; + if(strlen(mode)>14) + sscanf(mode+14, "%d", &idx); + if(idx<0 || idx>255) + goto unusable_index; + mode_flag|= (idx<<8); + } else if(strncmp(mode, "by_size_", 8) == 0 && (flag & 1)) { + size= (off_t) Scanf_io_size(mode + 8, 0); + if(size <= 0) { +unusable_size:; + sprintf(xorriso->info_text, + "-format: mode '%s' provides unusable size value", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + mode_flag= 2; + } else if(strncmp(mode, "fast_by_size_", 13) == 0 && (flag & 1)) { + size= (off_t) Scanf_io_size(mode + 13, 0); + if(size <= 0) + goto unusable_size; + mode_flag= 3; + } else { + sprintf(xorriso->info_text, + "%s: Unknown %s mode '%s'", + cmd, ((flag&1) ? "-format" : "-blank"), mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if(as_needed) + ret= Xorriso_blank_as_needed(xorriso, (flag&1)<<2); + else if(flag&1) + ret= Xorriso_format_media(xorriso, size, mode_flag & 0xff83); + else + ret= Xorriso_blank_media(xorriso, mode_flag&3); + if(ret==0) + return(ret); + strcpy(drive_name, xorriso->outdev); + if(ret <= 0) { /* in case of success, above functions will have re-aquired */ + aq_ret= Xorriso_reaquire_outdev(xorriso, 0); /* actually give up drive */ + if(retboot_count > 0) { +cannot_keep_or_patch:; + sprintf(xorriso->info_text, + "Loaded boot image has already been replaced. Cannot keep or patch it."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if(isolinux_grub) + goto treatment_patch; + xorriso->keep_boot_image= 1; + xorriso->patch_isolinux_image= 0; + xorriso->boot_image_bin_path[0]= 0; + xorriso->patch_system_area= 0; + + } else if(strcmp(treatpt, "patch")==0) { +treatment_patch:; + if(xorriso->boot_count > 0) + goto cannot_keep_or_patch; + xorriso->keep_boot_image= 0; + xorriso->patch_isolinux_image= 1; + xorriso->boot_image_bin_path[0]= 0; + if(strcmp(formpt, "grub") == 0) { + xorriso->patch_isolinux_image|= 2; + xorriso->patch_system_area= 1; + } else if(strcmp(formpt, "isolinux") == 0) + xorriso->patch_system_area= 2; + else + xorriso->patch_system_area= 0; + + } else if(strcmp(treatpt, "discard")==0) { + xorriso->keep_boot_image= 0; + xorriso->patch_isolinux_image= 0; + xorriso->boot_image_bin_path[0]= 0; + xorriso->patch_system_area= 0; + if(xorriso->boot_count > 0) { + ret= Xorriso_attach_boot_image(xorriso, 2); /* dispose boot images */ + if(ret <= 0) + return(ret); + } + + } else if(strcmp(treatpt, "next") == 0) { + ret= Xorriso_attach_boot_image(xorriso, 0); + if(ret <= 0) + return(ret); + + } else if(strcmp(treatpt, "show_status")==0) { + sprintf(xorriso->result_line, "------------------------------------\n"); + Xorriso_result(xorriso, 0); + sprintf(xorriso->result_line, "Status of loaded boot image :\n"); + Xorriso_result(xorriso, 0); + sprintf(xorriso->result_line, "------------------------------------\n"); + Xorriso_result(xorriso, 0); + Xorriso_show_boot_info(xorriso, 0); + sprintf(xorriso->result_line, "------------------------------------\n"); + Xorriso_result(xorriso, 0); + sprintf(xorriso->result_line, "Boot image settings for next commit:\n"); + Xorriso_result(xorriso, 0); + sprintf(xorriso->result_line, "------------------------------------\n"); + Xorriso_result(xorriso, 0); + Xorriso_status(xorriso, "-boot_image", NULL, 0); + sprintf(xorriso->result_line, "------------------------------------\n"); + Xorriso_result(xorriso, 0); + + } else if(strcmp(treatpt, "cat_path=") == 0) { + xorriso->boot_image_cat_path[0] = 0; + } else if(strncmp(treatpt, "cat_path=", 9) == 0) { + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, treatpt + 9, + xorriso->boot_image_cat_path, 2); + if(ret <= 0) + return(ret); + + } else if(strncmp(treatpt, "dir=", 4) == 0) { + if(strcmp(formpt, "isolinux")==0) { + /* ISOLINUX */ + /* The three locations mentioned in http://syslinux.zytor.com/iso.php */ + if(strcmp(treatpt + 4, "/") == 0) + strcpy(xorriso->boot_image_bin_path, "/"); + else if(strcmp(treatpt + 4, "isolinux") == 0 + || strcmp(treatpt + 4, "/isolinux") == 0) + strcpy(xorriso->boot_image_bin_path, "/isolinux/"); + else if(strcmp(treatpt + 4, "boot/isolinux") == 0 + || strcmp(treatpt + 4, "/boot/isolinux") == 0 + || strcmp(treatpt + 4, "boot") == 0 + || strcmp(treatpt + 4, "/boot") == 0) + strcpy(xorriso->boot_image_bin_path, "/boot/isolinux/"); + else { + sprintf(xorriso->info_text, + "Unrecognized keyword with -boot_image %s %s", + form, treatment); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + sprintf(xorriso->info_text, + "Allowed with dir= are / , /isolinux . /boot/isolinux"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0); + return(0); + } + strcpy(xorriso->boot_image_cat_path, xorriso->boot_image_bin_path); + strcat(xorriso->boot_image_bin_path, "isolinux.bin"); + strcat(xorriso->boot_image_cat_path, "boot.cat"); + xorriso->boot_image_load_size= 4 * 512; + xorriso->keep_boot_image= 0; + xorriso->patch_isolinux_image= 1; + strcpy(xorriso->boot_image_bin_form, formpt); + return(1); + + } else if(strcmp(formpt, "grub") == 0) { + + /* >>> GRUB */ + was_ok= 0; + + strcpy(xorriso->boot_image_bin_form, formpt); + + } else + was_ok= 0; + + } else if(strcmp(treatpt, "bin_path=") == 0) { + xorriso->boot_image_bin_path[0] = 0; + xorriso->boot_efi_default= 0; + } else if(strncmp(treatpt, "bin_path=", 9) == 0) { + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, treatpt + 9, + xorriso->boot_image_bin_path, 2); + if(ret <= 0) + return(ret); + xorriso->keep_boot_image= 0; + if(isolinux_grub) { + xorriso->patch_isolinux_image= 1; + if(xorriso->boot_image_bin_path[0]) + xorriso->boot_image_load_size= 4 * 512; + strcpy(xorriso->boot_image_bin_form, formpt); + } else + strcpy(xorriso->boot_image_bin_form, "any"); + xorriso->boot_efi_default= 0; + + } else if(strcmp(treatpt, "efi_path=") == 0) { + xorriso->boot_image_bin_path[0] = 0; + xorriso->boot_efi_default= 0; + } else if(strncmp(treatpt, "efi_path=", 9) == 0) { + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, treatpt + 9, + xorriso->boot_image_bin_path, 2); + if(ret <= 0) + return(ret); + xorriso->keep_boot_image= 0; + xorriso->boot_efi_default= 1; + + } else if(strncmp(treatpt, "boot_info_table=", 16)==0) { + if(strcmp(treatpt + 16, "off") == 0) + xorriso->patch_isolinux_image= 0; + else if(strcmp(treatpt + 16, "on") == 0) + xorriso->patch_isolinux_image= 1 | (2 * (strcmp(treatpt, "grub") == 0)); + else + was_ok= 0; + + } else if(strncmp(treatpt, "load_size=", 10) == 0) { + num= Scanf_io_size(treatpt + 10, 0); + if(num < 512 && isolinux_grub) { + sprintf(xorriso->info_text, + "-boot_image %s : load_size too small (%s < 512)", + formpt, treatpt + 10); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + xorriso->boot_image_load_size= num; + + } else if(strncmp(treatpt, "id_string=", 10) == 0) { + memset(xorriso->boot_id_string, 0, 29); + if(strlen(treatpt + 10) == 56) { + ret= Hex_to_bin(treatpt + 10, 28, &count, xorriso->boot_id_string, 0); + } else + ret= 0; + if(ret <= 0) + strncpy((char *) xorriso->boot_id_string, treatpt + 10, 28); + + } else if(strncmp(treatpt, "sel_crit=", 9) == 0) { + memset(xorriso->boot_selection_crit, 0, 21); + count= 0; + ret= Hex_to_bin(treatpt + 9, 20, &count, xorriso->boot_selection_crit, 0); + if(ret <= 0) { + sprintf(xorriso->info_text, + "-boot_image %s sel_crit= : Wrong form. Need even number of hex digits.", + formpt); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + + } else if(strncmp(treatpt, "system_area=", 12) == 0) { + ret= Xorriso_set_system_area_path(xorriso, treatpt + 12, 0); + if(ret <= 0) + return(ret); + if(strcmp(formpt, "isolinux")==0) + xorriso->system_area_options= (xorriso->system_area_options & ~3) | 2; + + } else if(strncmp(treatpt, "partition_table=", 16)==0) { + if(strcmp(treatpt + 16, "off") == 0) { + xorriso->system_area_options&= ~3; + xorriso->patch_system_area= xorriso->system_area_options; + } else if(strcmp(treatpt + 16, "on") == 0) { + xorriso->system_area_options&= ~3; + if(strcmp(formpt, "isolinux")==0) + xorriso->system_area_options|= 2; + else + xorriso->system_area_options|= 1; + xorriso->patch_system_area= xorriso->system_area_options; + } else + was_ok= 0; + + } else if(strncmp(treatpt, "platform_id=", 12)==0) { + if(strncmp(treatpt + 12, "0x", 2) == 0) + sscanf(treatpt + 14, "%x", &u); + else + sscanf(treatpt + 12, "%u", &u); + if(u > 0xff) { + sprintf(xorriso->info_text, + "-boot_image %s : platform_id too large (%s > 0xff)", + formpt, treatpt + 12); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + xorriso->boot_platform_id= u; + + } else if(strncmp(treatpt, "isohybrid=", 10) == 0 && + strcmp(formpt, "isolinux")==0) { + +#ifdef Xorriso_with_isohybriD + + if(strcmp(treatpt + 10, "off") == 0) + xorriso->boot_image_isohybrid= 0; + else if(strcmp(treatpt + 10, "auto") == 0) + xorriso->boot_image_isohybrid= 1; + else if(strcmp(treatpt + 10, "on") == 0) + xorriso->boot_image_isohybrid= 2; + else if(strcmp(treatpt + 10, "force") == 0) + xorriso->boot_image_isohybrid= 3; + else { + sprintf(xorriso->info_text, + "Unrecognized keyword with -boot_image %s %s", + form, treatment); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + sprintf(xorriso->info_text, + "Allowed with isohybrid= are: off , auto , on , force"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0); + return(0); + } + +#else + + if(strcmp(treatpt + 10, "off") == 0) { + xorriso->boot_image_isohybrid= 0; + } else { + sprintf(xorriso->info_text, + "isohybrid MBR generation has been disabled on request of its inventor H. Peter Anvin on 31 Mar 2010"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + sprintf(xorriso->info_text, + "It has been replaced by -boot_image isolinux system_area=External-File"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0); + } + +#endif /* ! Xorriso_with_isohybriD */ + + } else + was_ok= 0; + + if(!was_ok) { + sprintf(xorriso->info_text, "Unrecognized options with -boot_image: %s %s", + form, treatment); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + return(1); +} + + +/* Option -calm_drive */ +int Xorriso_option_calm_drive(struct XorrisO *xorriso, char *which, int flag) +{ + int gu_flag= 0, ret; + + if(strcmp(which,"in")==0) + gu_flag= 1; + else if(strcmp(which,"out")==0) + gu_flag= 2; + else if(strcmp(which,"on")==0) { + xorriso->do_calm_drive|= 1; + } else if(strcmp(which,"off")==0) { + xorriso->do_calm_drive&= ~1; + } else if(strcmp(which,"revoke")==0) { + gu_flag= 7; + } else + gu_flag= 3; + ret= Xorriso_drive_snooze(xorriso, gu_flag); + return(ret); +} + + +/* Option -cd alias -cdi */ +int Xorriso_option_cdi(struct XorrisO *xorriso, char *iso_rr_path, int flag) +{ + char sfe[5*SfileadrL], path[SfileadrL], eff_path[SfileadrL]; + int ret; + + if (strlen(iso_rr_path)>sizeof(xorriso->wdi)) { + sprintf(xorriso->info_text,"-cdi: iso_rr_path too long (%d > %d)", + (int) strlen(iso_rr_path), (int) sizeof(xorriso->wdi)-1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + Xorriso_warn_of_wildcards(xorriso, iso_rr_path, 1); + sprintf(xorriso->info_text,"previous working directory:\n"); + Xorriso_info(xorriso,0); + sprintf(xorriso->result_line,"%s/\n",Text_shellsafe(xorriso->wdi, sfe, 0)); + Xorriso_result(xorriso,0); + if(strcmp(iso_rr_path,"/")==0 || iso_rr_path[0]==0) { + strcpy(xorriso->wdi,""); + Xorriso_option_pwdi(xorriso, 0); + return(1); + } else if(iso_rr_path[0]!='/') { + strcpy(path, xorriso->wdi); + if(Sfile_add_to_path(path,iso_rr_path,0)<=0) + return(-1); + } else { + if(Sfile_str(path,iso_rr_path,0)<=0) + return(-1); + } + + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 1); + if(ret<0) + return(ret); + if(ret==0) { + sprintf(xorriso->info_text, "-cdi: not existing yet in ISO image : %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 2); + if(ret<=0) + return(ret); + } else if(ret!=2) { + sprintf(xorriso->info_text, "-cdi: not a directory : %s", + Text_shellsafe(eff_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + strcpy(xorriso->wdi, eff_path); + + Xorriso_option_pwdi(xorriso, 0); + return(1); +} + + +/* Option -cdx */ +int Xorriso_option_cdx(struct XorrisO *xorriso, char *disk_path, int flag) +{ + char sfe[5*SfileadrL], path[SfileadrL], eff_path[SfileadrL]; + int ret; + + if (strlen(disk_path)>sizeof(xorriso->wdx)) { + sprintf(xorriso->info_text,"-cdx: disk_path too long (%d > %d)", + (int) strlen(disk_path), (int) sizeof(xorriso->wdx)-1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + Xorriso_warn_of_wildcards(xorriso, disk_path, 1|2); + sprintf(xorriso->info_text,"previous working directory on hard disk:\n"); + Xorriso_info(xorriso,0); + sprintf(xorriso->result_line,"%s/\n",Text_shellsafe(xorriso->wdx, sfe, 0)); + Xorriso_result(xorriso,0); + if(strcmp(disk_path,"/")==0) { + strcpy(xorriso->wdx,""); + Xorriso_option_pwdx(xorriso, 0); + return(1); + } else if(disk_path[0]!='/') { + strcpy(path, xorriso->wdx); + if(Sfile_add_to_path(path,disk_path,0)<=0) + return(-1); + } else { + if(Sfile_str(path,disk_path,0)<=0) + return(-1); + } + + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, path, eff_path, 2|4); + if(ret<=0) + return(ret); + if(eff_path[0]) { + ret= Sfile_type(eff_path,1|4|8); + if(ret<0) { + Xorriso_msgs_submit(xorriso, 0, eff_path, 0, "ERRFILE", 0); + sprintf(xorriso->info_text,"-cdx: file not found : %s", + Text_shellsafe(eff_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if(ret!=2) { + Xorriso_msgs_submit(xorriso, 0, eff_path, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, + "-cdx: not a directory : %s", + Text_shellsafe(eff_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + if(Sfile_str(xorriso->wdx,eff_path,0)<=0) + return(-1); + Xorriso_option_pwdx(xorriso, 0); + return(1); +} + + +/* Option -charset */ +/* @param flag bit0= set in_charset + bit1= set out_charset + bit2= set local_charset +*/ +int Xorriso_option_charset(struct XorrisO *xorriso, char *name, int flag) +{ + int ret; + char *name_pt= NULL, sfe[5 * SfileadrL], *local_charset; + iconv_t iconv_ret= (iconv_t) -1; + + if(name != NULL) + if(name[0] != 0) + name_pt= name; + if(flag & 4) { + ret= Xorriso_set_local_charset(xorriso, name_pt, 0); + if(ret <= 0) + return(ret); + } + if(flag & 1) { + if(name_pt != NULL) { + Xorriso_get_local_charset(xorriso, &local_charset, 0); + iconv_ret= iconv_open(local_charset, name_pt); + if(iconv_ret == (iconv_t) -1) { + sprintf(xorriso->info_text, + "-%scharset: Cannot convert from character set %s", + flag & 2 ? "" : "in_", Text_shellsafe(name_pt, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", + 0); + return(0); + } else + iconv_close(iconv_ret); + } + if(Sregex_string(&(xorriso->in_charset), name_pt, 0) <= 0) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + return(-1); + } + } + if(flag & 2) { + if(name_pt != NULL) { + Xorriso_get_local_charset(xorriso, &local_charset, 0); + iconv_ret= iconv_open(local_charset, name_pt); + if(iconv_ret == (iconv_t) -1) { + sprintf(xorriso->info_text, "-%scharset: Cannot convert to charset %s", + flag & 1 ? "" : "out_", Text_shellsafe(name_pt, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", + 0); + return(0); + } else + iconv_close(iconv_ret); + } + if(Sregex_string(&(xorriso->out_charset), name_pt, 0) <= 0) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + return(-1); + } + } + if(flag & 3) { + if(name_pt == NULL) + Xorriso_get_local_charset(xorriso, &name_pt, 0); + sprintf(xorriso->info_text, "Character set for %sconversion is now: %s", + (flag & 3) == 1 ? "input " : (flag & 3) == 2 ? "output " : "", + Text_shellsafe(name_pt, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } + return(1); +} + + +/* Options -check_md5 and -check_md5_r + @param flag bit0= issue summary message + bit1= do not reset pacifier, no final pacifier message + >>> bit2= do not issue pacifier messages at all + bit3= recursive: -check_md5_r +*/ +int Xorriso_option_check_md5(struct XorrisO *xorriso, + int argc, char **argv, int *idx, int flag) +{ + int ret, i, mem_pci, end_idx, fret, sev, do_report= 0; + int optc= 0; + char **optv= NULL, *cpt, *severity= "ALL"; + struct FindjoB *job= NULL; + double mem_lut= 0.0; + + mem_pci= xorriso->pacifier_interval; + + ret= Xorriso_opt_args(xorriso, "-check_md5", argc, argv, *idx + 1, + &end_idx, &optc, &optv, 128); + if(ret<=0) + goto ex; + + /* Interpret argv[*idx] as severity */ + if(argc <= *idx) { + sprintf(xorriso->info_text, + "-check_md5: No event severity given for case of mismatch"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + severity= argv[*idx]; + ret= Xorriso__text_to_sev(severity, &sev, 0); + if(ret<=0) { + sprintf(xorriso->info_text, "-check_md5: Not a known severity name : "); + Text_shellsafe(severity, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + goto ex; + } + + if(!(flag & (2 | 4))) { + Xorriso_pacifier_reset(xorriso, 0); + mem_lut= xorriso->last_update_time; + } + xorriso->pacifier_interval= 5.0; + + xorriso->find_check_md5_result= 0; + + if(optc == 0) { + ret= Xorriso_check_session_md5(xorriso, severity, 0); + do_report= 1; + goto ex; + } + + for(i= 0; i < optc; i++) { + if(flag & 8) { + ret= Findjob_new(&job, optv[i], 0); + if(ret<=0) { + Xorriso_no_findjob(xorriso, "-check_md5_r", 0); + {ret= -1; goto ex;} + } + Findjob_set_action_target(job, 35, severity, 0); + cpt= optv[i]; + ret= Xorriso_findi_sorted(xorriso, job, (off_t) 0, 1, &cpt, 0); + Findjob_destroy(&job, 0); + if(ret > 0) + ret= xorriso->find_compare_result; + else { + ret= -1; + xorriso->find_check_md5_result|= 2; + } + } else { + ret= Xorriso_check_md5(xorriso, NULL, optv[i], 4); + if(ret < 0) + xorriso->find_check_md5_result|= 2; + else if(ret == 0) + xorriso->find_check_md5_result|= 1; + else if(ret == 1) + xorriso->find_check_md5_result|= 8; + else if(ret == 2) + xorriso->find_check_md5_result|= 4; + } + if(ret>0 && !xorriso->request_to_abort) + continue; /* regular bottom of loop */ + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + ret= 0; goto report_outcome; + } + ret= 1; + +report_outcome:; + do_report= 1; + +ex:; + if(!(flag & (2 | 4))) { + xorriso->pacifier_interval= mem_pci; + if(mem_lut!=xorriso->last_update_time && !(flag&2)) + Xorriso_pacifier_callback(xorriso, "content bytes read", + xorriso->pacifier_count, 0, "", 1); + } + if(do_report) { + if(optc == 0) { + if(ret <= 0) { + sprintf(xorriso->result_line, + "MD5 MISMATCH WITH DATA OF LOADED SESSION !\n"); + Xorriso_result(xorriso,0); + if(strcmp(severity, "ALL") != 0) { + sprintf(xorriso->info_text, + "Event triggered by MD5 comparison mismatch"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, severity, 0); + } + } else { + sprintf(xorriso->result_line, "Ok, session data match recorded md5.\n"); + Xorriso_result(xorriso,0); + } + } else { + Xorriso_report_md5_outcome(xorriso, severity, 0); + } + } + (*idx)= end_idx; + Xorriso_opt_args(xorriso, "-getfacl", argc, argv, *idx, &end_idx, + &optc, &optv, 256); + Findjob_destroy(&job, 0); + if(ret <= 0) + return(ret); + return((xorriso->find_check_md5_result & 3) == 0); +} + + +/* Option -check_media */ +int Xorriso_option_check_media(struct XorrisO *xorriso, + int argc, char **argv, int *idx, int flag) +{ + int ret, i, count, lba, blocks, quality, pass, was_md5= 0, was_event= 0; + int end_idx, old_idx, os_errno; + char quality_name[80], head_buffer[64*1024]; + struct SpotlisT *spotlist= NULL; + struct CheckmediajoB *job= NULL; + struct FindjoB *findjob= NULL; + struct stat dir_stbuf; + + old_idx= *idx; + end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); + (*idx)= end_idx; + + ret= Checkmediajob_new(&job, 0); + if(ret <= 0) + goto ex; + ret= Xorriso_check_media_setup_job(xorriso, job, argv, old_idx, end_idx, 0); + if(ret <= 0) + goto ex; + + if((job->report_mode == 1 || job->report_mode == 2) && job->use_dev == 1) { + sprintf(xorriso->info_text, + "-check_media: cannot report=*files while use=outdef"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + if(job->patch_lba0 && job->data_to_path[0] == 0) { + sprintf(xorriso->info_text, + "-check_media: cannot apply patch_lba0= while data_to= has empty value"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + + if(job->use_dev == 2) { + if(job->sector_map_path[0] == 0) { + sprintf(xorriso->info_text, + "-check_media: option use=sector_map but sector_map=''"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + ret= Sectorbitmap_from_file(&(job->sector_map), job->sector_map_path, + xorriso->info_text, &os_errno, 0); + if(ret <= 0) { + if(xorriso->info_text[0]) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, os_errno, + "FAILURE", 0); + goto ex; + } + ret= Xorriso_sectormap_to_spotlist(xorriso, job, &spotlist, 0); + if(ret <= 0) + goto ex; + Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); + ret= Sectorbitmap_clone(job->sector_map, &(xorriso->in_sector_map), 0); + if(ret <= 0) + goto ex; + } else { + ret= Xorriso_check_media(xorriso, &spotlist, job, 0); + if(ret <= 0) + goto ex; + } + + if(job->patch_lba0) { + ret= Xorriso_open_job_data_to(xorriso, job, 0); + if(ret <= 0) + goto ex; + if(ret == 1) { + ret= Xorriso_update_iso_lba0(xorriso, job->patch_lba0_msc1, 0, + head_buffer, job, + (8 * (job->patch_lba0 == 1)) | + 4 | (job->patch_lba0_msc1 < 0)); + if(ret <= 0) + goto ex; + } + } + + if(job->report_mode == 0 || job->report_mode == 2) { /* report blocks */ + for(pass= 0; pass < 2; pass++) { + if(pass == 0) { + sprintf(xorriso->result_line, + "Media checks : lba , size , quality\n"); + } else { + if(!was_md5) + break; + sprintf(xorriso->result_line, + "MD5 checks : lba , size , result\n"); + } + Xorriso_result(xorriso,0); + count= Spotlist_count(spotlist, 0); + for(i= 0; i < count; i++) { + ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0); + if(ret <= 0) + continue; + if(pass == 0) { + if(quality == Xorriso_read_quality_md5_mismatcH || + quality == Xorriso_read_quality_unreadablE) { + was_event= 1; + } + if(quality == Xorriso_read_quality_md5_matcH || + quality == Xorriso_read_quality_md5_mismatcH) { + was_md5= 1; + continue; + } + } + else if(pass == 1 && !(quality == Xorriso_read_quality_md5_matcH || + quality == Xorriso_read_quality_md5_mismatcH)) + continue; + sprintf(xorriso->result_line, "%s: %10d , %10d , %s\n", + pass == 0 ? "Media region " : "MD5 tag range", + lba, blocks, Spotlist__quality_name(quality, quality_name, + xorriso->check_media_bad_limit, 0)); + Xorriso_result(xorriso,0); + } + } + } + if(job->report_mode == 1 || job->report_mode == 2) { /* report files */ + ret= Findjob_new(&findjob, "/", 0); + if(ret<=0) { + Xorriso_no_findjob(xorriso, "-check_media report=files", 0); + {ret= -1; goto ex;} + } + Findjob_set_damage_filter(findjob, 1, 0); + Findjob_set_action_target(findjob, 21, NULL, 0); + ret= Xorriso_findi(xorriso, findjob, NULL, (off_t) 0, + NULL, "/", &dir_stbuf, 0, 0); + Findjob_destroy(&findjob, 0); + if(ret <= 0) + goto ex; + } + ret= 1; +ex:; + if(was_event && strcmp(job->event_severity, "ALL") != 0) { + sprintf(xorriso->info_text, + "Event triggered by media read error or MD5 comparison mismatch"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, job->event_severity, + 0); + } + Spotlist_destroy(&spotlist, 0); + Checkmediajob_destroy(&job, 0); + return(ret); +} + + +/* Option -check_media_defaults */ +int Xorriso_option_check_media_defaults(struct XorrisO *xorriso, + int argc, char **argv, int *idx, int flag) +{ + int ret, old_idx, end_idx; + struct CheckmediajoB *job= NULL; + + old_idx= *idx; + end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); + (*idx)= end_idx; + + ret= Checkmediajob_new(&job, 0); + if(ret <= 0) + goto ex; + ret= Xorriso_check_media_setup_job(xorriso, job, argv, old_idx, end_idx, 0); + if(ret <= 0) + goto ex; + Checkmediajob_destroy(&(xorriso->check_media_default), 0); + xorriso->check_media_default= job; + job= NULL; + ret= 1; +ex:; + Checkmediajob_destroy(&job, 0); + return(ret); +} + + +/* Option -chgrp alias -chgrpi , chgrp_r alias chgrpi */ +/* @param flag bit0=recursive (-chgrp_r) +*/ +int Xorriso_option_chgrpi(struct XorrisO *xorriso, char *gid, + int argc, char **argv, int *idx, int flag) +{ + int i, ret, was_failure= 0, end_idx, fret; + gid_t gid_number; + int optc= 0; + char **optv= NULL; + struct FindjoB *job= NULL; + struct stat dir_stbuf; + + ret= Xorriso_opt_args(xorriso, "-chgrpi", argc, argv, *idx, &end_idx, &optc, + &optv, 0); + if(ret<=0) + goto ex; + ret= Xorriso_convert_gidstring(xorriso, gid, &gid_number, 0); + if(ret<=0) + goto ex; + for(i= 0; i0 && !xorriso->request_to_abort) + continue; /* regular bottom of loop */ + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + goto ex; + } + ret= 1; +ex:; + (*idx)= end_idx; + Xorriso_opt_args(xorriso, "-chgrpi", argc, argv, *idx, &end_idx, &optc, &optv, + 256); /* clean up */ + if(ret<=0) + return(ret); + Findjob_destroy(&job, 0); + return(!was_failure); +} + + +/* Option -chmod alias -chmodi , -chmod_r alias chmod_ri */ +/* @param flag bit0=recursive (-chmod_r) +*/ +int Xorriso_option_chmodi(struct XorrisO *xorriso, char *mode, + int argc, char **argv, int *idx, int flag) +{ + int i, ret, was_failure= 0, end_idx, fret; + mode_t mode_and= ~0, mode_or= 0; + int optc= 0; + char **optv= NULL; + struct FindjoB *job= NULL; + struct stat dir_stbuf; + + ret= Xorriso_opt_args(xorriso, "-chmodi", argc, argv, *idx, &end_idx, &optc, + &optv, 0); + if(ret<=0) + goto ex; + ret= Xorriso_convert_modstring(xorriso, "-chmodi", + mode, &mode_and, &mode_or, 0); + if(ret<=0) + goto ex; + for(i= 0; i0 && !xorriso->request_to_abort) + continue; /* regular bottom of loop */ + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + ret= 0; goto ex; + } + ret= 1; +ex:; + (*idx)= end_idx; + Xorriso_opt_args(xorriso, "-chmodi", argc, argv, *idx, &end_idx, &optc, &optv, + 256); + Findjob_destroy(&job, 0); + if(ret<=0) + return(ret); + return(!was_failure); +} + + +/* Option -chown alias -chowni , chown_r alias chown_ri */ +/* @param flag bit0=recursive (-chown_r) +*/ +int Xorriso_option_chowni(struct XorrisO *xorriso, char *uid, + int argc, char **argv, int *idx, int flag) +{ + int i, ret, was_failure= 0, end_idx, fret; + uid_t uid_number; + int optc= 0; + char **optv= NULL; + struct FindjoB *job= NULL; + struct stat dir_stbuf; + + ret= Xorriso_opt_args(xorriso, "-chowni", argc, argv, *idx, &end_idx, + &optc, &optv, 0); + if(ret<=0) + goto ex; + ret= Xorriso_convert_uidstring(xorriso, uid, &uid_number, 0); + if(ret<=0) + goto ex; + for(i= 0; i0 && !xorriso->request_to_abort) + continue; /* regular bottom of loop */ + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + ret= 0; goto ex; + } + ret= 1; +ex:; + (*idx)= end_idx; + Xorriso_opt_args(xorriso, "-chowni", argc, argv, *idx, &end_idx, + &optc, &optv, 256); + Findjob_destroy(&job, 0); + if(ret<=0) + return(ret); + return(!was_failure); +} + + +/* Option -close "on"|"off" */ +int Xorriso_option_close(struct XorrisO *xorriso, char *mode, int flag) +{ + xorriso->do_close= !!strcmp(mode, "off"); + return(1); +} + + +/* Option -close_filter_list */ +int Xorriso_option_close_filter_list(struct XorrisO *xorriso, int flag) +{ + xorriso->filter_list_closed= 1; + return(1); +} + + +/* Option -commit */ +/* @param flag bit0= leave indrive and outdrive aquired as they were, + i.e. do not aquire outdrive as new in-out-drive + bit1= do not perform eventual -reassure + @return <=0 error , 1 success, 2 revoked by -reassure , 3 no change pending +*/ +int Xorriso_option_commit(struct XorrisO *xorriso, int flag) +{ + int ret; + char newdev[SfileadrL]; + + if(!xorriso->volset_change_pending) { + sprintf(xorriso->info_text, "-commit: No image modifications pending"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + return(3); + } + if(!(flag&2)) { + ret= Xorriso_reassure(xorriso, "-commit", + "write the pending image changes to media", 0); + if(ret<=0) + return(2); + } + Xorriso_process_errfile(xorriso, 0, "burn session start", 0, 1); + ret= Xorriso_write_session(xorriso, 0); + Xorriso_process_errfile(xorriso, 0, "burn session end", 0, 1); + if(ret<=0) + return(ret); + Xorriso_write_session_log(xorriso, 0); + xorriso->volset_change_pending= 0; + xorriso->no_volset_present= 0; + if(flag&1) + return(1); + if(Sregex_string(&(xorriso->in_charset), xorriso->out_charset, 0) <= 0) + return(-1); + strcpy(newdev, xorriso->outdev); + if(xorriso->grow_blindly_msc2>=0) + ret= Xorriso_option_dev(xorriso, "", 3|4); + else + ret= Xorriso_option_dev(xorriso, newdev, 3|4); + return(ret); +} + + +/* Option -commit_eject */ +/* @return <=0 error , 1 success, 2 revoked by -reassure +*/ +int Xorriso_option_commit_eject(struct XorrisO *xorriso, char *which, int flag) +{ + int ret, eret; + + ret= Xorriso_option_commit(xorriso, 1); + if(ret<=0 || ret==2 || ret==3) + return(ret); + if(strcmp(which, "none")==0) + eret= 1; + else + eret= Xorriso_option_eject(xorriso, which, 1); + ret= Xorriso_option_dev(xorriso, "", 3|4); + if(eretinfo_text, "-compare: Empty disk_path given"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 1); + return(0); + } + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_origin, + 2|4|8); + if(ret<=0) + return(ret); + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, ipth, eff_dest, 2|8); + if(ret<=0) + return(ret); + + if(xorriso->disk_excl_mode&8) + ret= Xorriso_path_is_excluded(xorriso, eff_origin, 1); + else + ret= 0; + if(ret!=0) + goto report_outcome; + if(!(flag&2)) { + Xorriso_pacifier_reset(xorriso, 0); + mem_lut= xorriso->last_update_time; + } + mem_pci= xorriso->pacifier_interval; + xorriso->pacifier_interval= 5.0; + + if(flag&8) { + xorriso->find_compare_result= 1; + argv[0]= eff_dest; + argv[1]= "-exec"; + argv[2]= "compare"; + argv[3]= eff_origin; + zero= 0; + ret= Xorriso_option_find(xorriso, 4, argv, &zero, 2); /* -findi */ + if(ret>0) { + argv[0]= eff_origin; + argv[1]= "-exec"; + argv[2]= "not_in_iso"; + argv[3]= eff_dest; + zero= 0; + ret= Xorriso_option_find(xorriso, 4, argv, &zero, 1|2); /* -findx */ + if(ret>0 && !xorriso->do_follow_mount) { + argv[0]= eff_origin; + argv[1]= "-type"; + argv[2]= "m"; + argv[3]= "-exec"; + argv[4]= "is_full_in_iso"; + argv[5]= eff_dest; + zero= 0; + ret= Xorriso_option_find(xorriso, 6, argv, &zero, 1|2); /* -findx */ + } + if(ret>0) + ret= xorriso->find_compare_result; + else + ret= -1; + } else + ret= -1; + } else { + follow_links= (xorriso->do_follow_links || xorriso->do_follow_param) << 28; + ret= Xorriso_compare_2_files(xorriso, eff_origin, eff_dest, "", &result, + 2 | follow_links | ((flag&4)<<27) | (1<<30)); + } + + xorriso->pacifier_interval= mem_pci; + if(mem_lut!=xorriso->last_update_time && !(flag&2)) + Xorriso_pacifier_callback(xorriso, "content bytes read", + xorriso->pacifier_count, 0, "", 1); +report_outcome:; + if(ret>0) { + sprintf(xorriso->result_line, + "Both file objects match as far as expectable.\n"); + } else if(ret==0) { + sprintf(xorriso->result_line, "Differences detected.\n"); + } else { + sprintf(xorriso->result_line, "Comparison failed due to error.\n"); + } + if(flag&1) + Xorriso_result(xorriso,0); + if(ret<0) + return(ret); + return(1); +} + + +/* Option -compliance */ +int Xorriso_option_compliance(struct XorrisO *xorriso, char *mode, + int flag) +{ + return(Xorriso_relax_compliance(xorriso, mode, 0)); +} + + +/* Option -cpr alias -cpri */ +int Xorriso_option_cpri(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int i, ret, is_dir= 0, was_failure= 0, fret, end_idx_dummy; + char eff_origin[SfileadrL], eff_dest[SfileadrL]; + char dest_dir[SfileadrL], leafname[SfileadrL]; + int optc= 0; + char **optv= NULL; + + ret= Xorriso_cpmv_args(xorriso, "-cpri", argc, argv, idx, + &optc, &optv, eff_dest, 1|2); + if(ret<=0) + goto ex; + if(ret==2) { + is_dir= 1; + strcpy(dest_dir, eff_dest); + } + + /* Perform graft-ins */ + Xorriso_pacifier_reset(xorriso, 0); + for(i= 0; irequest_to_abort; i++) { + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, optv[i], eff_origin, + 2|4); + if(ret<=0 || xorriso->request_to_abort) + goto problem_handler; + if(is_dir) { + ret= Sfile_leafname(eff_origin, leafname, 0); + if(ret<=0) + goto problem_handler; + strcpy(eff_dest, dest_dir); + ret= Sfile_add_to_path(eff_dest, leafname, 0); + if(ret<=0) { + sprintf(xorriso->info_text, "Effective path gets much too long (%d)", + (int) (strlen(eff_dest)+ strlen(leafname)+1)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + goto problem_handler; + } + } + ret= Xorriso_graft_in(xorriso, NULL, eff_origin, eff_dest, + (off_t) 0, (off_t) 0, 0); + if(ret<=0 || xorriso->request_to_abort) + goto problem_handler; + sprintf(xorriso->info_text, "Added to ISO image: %s '%s'='%s'\n", + (ret>1 ? "directory" : "file"), (eff_dest[0] ? eff_dest : "/"), + eff_origin); + if(!(flag&1)) + Xorriso_info(xorriso, 0); + continue; /* regular bottom of loop */ +problem_handler:; + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + goto ex; + } + Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count, + xorriso->pacifier_total, "", 1); + ret= !was_failure; +ex:; + Xorriso_opt_args(xorriso, "-cpri", + argc, argv, *idx, &end_idx_dummy, &optc, &optv, 256); + return(ret); +} + + +/* Options -cpx , -cpax, -cp_rx , -cp_rax */ +/* @param flag bit0= recursive (-cp_rx, -cp_rax) + bit1= full property restore (-cpax, -cp_rax) +*/ +int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int i, ret, is_dir= 0, was_failure= 0, fret, end_idx_dummy; + char eff_origin[SfileadrL], eff_dest[SfileadrL]; + char dest_dir[SfileadrL], leafname[SfileadrL], sfe[5*SfileadrL]; + char **eff_src_array= NULL, **eff_tgt_array= NULL; + + int optc= 0; + char **optv= NULL; + struct stat stbuf; + + ret= Xorriso_cpmv_args(xorriso, "-cp*x", argc, argv, idx, + &optc, &optv, eff_dest, 1|4); + if(ret<=0) + goto ex; + if(ret==2) { + is_dir= 1; + strcpy(dest_dir, eff_dest); + } + if(xorriso->allow_restore <= 0) { + sprintf(xorriso->info_text, + "-cpx: image-to-disk copies are not enabled by option -osirrox"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + + if(xorriso->do_restore_sort_lba || !(xorriso->ino_behavior & 4)) { + eff_src_array= calloc(optc, sizeof(char *)); + eff_tgt_array= calloc(optc, sizeof(char *)); + if(eff_src_array == NULL || eff_tgt_array == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + for(i= 0; i < optc; i++) + eff_src_array[i]= eff_tgt_array[i]= NULL; + } + + /* Perform copying */ + Xorriso_pacifier_reset(xorriso, 0); + for(i= 0; irequest_to_abort; i++) { + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, optv[i], eff_origin, + 2|8); + if(ret<=0 || xorriso->request_to_abort) + goto problem_handler; + + ret= Xorriso_iso_lstat(xorriso, eff_origin, &stbuf, 2|4); + if(ret==-1) + goto problem_handler; + if(S_ISDIR(stbuf.st_mode) && !(flag&1)) { + /* only allow directories if they actually represent split data files */ + ret= 0; + if(xorriso->do_concat_split) + ret= Xorriso_is_split(xorriso, eff_origin, NULL, 0); + if(ret<0) + goto problem_handler; + if(ret==0) { + sprintf(xorriso->info_text, "-cpx: May not copy directory %s", + Text_shellsafe(eff_origin, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto problem_handler; + } + } + + if(is_dir && strcmp(eff_origin, "/")!=0) { + ret= Sfile_leafname(eff_origin, leafname, 0); + if(ret<=0) + goto problem_handler; + strcpy(eff_dest, dest_dir); + ret= Sfile_add_to_path(eff_dest, leafname, 0); + if(ret<=0) { + sprintf(xorriso->info_text, "Effective path gets much too long (%d)", + (int) (strlen(eff_dest)+strlen(leafname)+1)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + goto problem_handler; + } + } + if(eff_src_array != NULL) { + eff_src_array[i]= strdup(eff_origin); + eff_tgt_array[i]= strdup(eff_dest); + if(eff_src_array[i] == NULL || eff_tgt_array[i] == NULL) { + Xorriso_no_malloc_memory(xorriso, &(eff_src_array[i]), 0); + ret= -1; goto ex; + } + } else { + ret= Xorriso_restore(xorriso, eff_origin, eff_dest, (off_t) 0, (off_t) 0, + 16 | ((!(flag&2))<<6)); + if(ret<=0 || xorriso->request_to_abort) + goto problem_handler; + if(ret==3 || (flag&1)) + continue; + sprintf(xorriso->info_text, + "Copied from ISO image to disk: %s '%s' = '%s'\n", + (ret>1 ? "directory" : "file"), eff_origin, eff_dest); + Xorriso_info(xorriso, 0); + } + continue; /* regular bottom of loop */ +problem_handler:; + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + goto ex; + } + + if(eff_src_array != NULL) { + ret= Xorriso_restore_sorted(xorriso, optc, eff_src_array, eff_tgt_array, 0); + if(ret <= 0) + was_failure= 1; + } + if(xorriso->pacifier_count>0) + Xorriso_pacifier_callback(xorriso, "files restored",xorriso->pacifier_count, + xorriso->pacifier_total, "", 1|4); + ret= !was_failure; +ex:; + i= optc; + Sfile_destroy_argv(&i, &eff_src_array, 0); + i= optc; + Sfile_destroy_argv(&i, &eff_tgt_array, 0); + Xorriso_opt_args(xorriso, "-cp*x", + argc, argv, *idx, &end_idx_dummy, &optc, &optv, 256); + return(ret); +} + + +/* Option -cut_out */ +int Xorriso_option_cut_out(struct XorrisO *xorriso, char *disk_path, + char *start, char *count, char *iso_rr_path, int flag) +{ + int ret; + double num; + off_t startbyte, bytecount; + + num= Scanf_io_size(start, 0); + if(num<0 || num > 1.0e18) { /* 10^18 = 10^3 ^ 6 < 2^10 ^ 6 = 2^60 */ + sprintf(xorriso->info_text, + "-cut_out: startbyte address negative or much too large (%s)", start); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + startbyte= num; + num= Scanf_io_size(count, 0); + if(num<=0 || num > 1.0e18) { + sprintf(xorriso->info_text, + "-cut_out: bytecount zero, negative or much too large (%s)", count); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + bytecount= num; + sprintf(xorriso->info_text, + "-cut_out from %s , byte %.f to %.f, and graft as %s", + disk_path, (double) startbyte, (double) (startbyte+bytecount), + iso_rr_path); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + + ret= Xorriso_cut_out(xorriso, disk_path, startbyte, bytecount, + iso_rr_path, 0); + return(ret); +} + diff --git a/xorriso/opts_d_h.c b/xorriso/opts_d_h.c new file mode 100644 index 00000000..a372e88f --- /dev/null +++ b/xorriso/opts_d_h.c @@ -0,0 +1,1823 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains the implementation of options as mentioned in man page + or info file derived from xorriso.texi. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "xorriso.h" +#include "xorriso_private.h" +#include "xorrisoburn.h" + + +/* Options -dev , -indev, -outdev */ +/** @param flag bit0= use as indev + bit1= use as outdev + bit2= do not -reassure + bit3= regard overwriteable media as blank + bit4= if the drive is a regular disk file: truncate it to + the write start address + bit5= do not print toc of aquired drive + bit6= do not calm down drive after aquiring it + @return <=0 error , 1 success, 2 revoked by -reassure +*/ +int Xorriso_option_dev(struct XorrisO *xorriso, char *in_adr, int flag) +{ + int ret; + char sfe[5*SfileadrL], *adr; + + adr= in_adr; + if(strcmp(in_adr, "-")==0) + adr= "stdio:/dev/fd/1"; + if(strncmp(adr, "stdio:", 6)==0) { + if(strlen(adr)==6 || strcmp(adr, "stdio:/")==0 || + strcmp(adr, "stdio:.")==0 || strcmp(adr, "stdio:..")==0 || + strcmp(adr, "stdio:-")==0) { + sprintf(xorriso->info_text, + "No suitable path given by device address '%s'", adr); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + + if(xorriso->volset_change_pending && (flag&1)) { + sprintf(xorriso->info_text, + "%s: Image changes pending. -commit or -rollback first", + (flag&2) ? "-dev" : "-indev"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if((flag&1) && (xorriso->in_drive_handle != NULL || adr[0]) && !(flag&4)) { + ret= Xorriso_reassure(xorriso, (flag&2) ? "-dev" : "-indev", + "eventually discard the current image", 0); + if(ret<=0) + return(2); + } + + if(adr[0]==0) { + if((flag&1) && xorriso->in_drive_handle != NULL) { + if(xorriso->in_drive_handle == xorriso->out_drive_handle) + sprintf(xorriso->info_text,"Giving up -dev %s", + Text_shellsafe(xorriso->indev, sfe, 0)); + else + sprintf(xorriso->info_text,"Giving up -indev %s", + Text_shellsafe(xorriso->indev, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } + if((flag&2) && xorriso->out_drive_handle != NULL && + xorriso->in_drive_handle != xorriso->out_drive_handle) { + sprintf(xorriso->info_text,"Giving up -outdev %s", + Text_shellsafe(xorriso->outdev, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } + ret= Xorriso_give_up_drive(xorriso, (flag&3)|((flag&32)>>2)); + } else + ret= Xorriso_aquire_drive(xorriso, adr, + (flag & (3 | 32 | 64)) | (((flag & (8 | 16)) >> 1))); + if(ret<=0) + return(ret); + if(xorriso->in_drive_handle == NULL) + xorriso->image_start_mode= 0; /* session setting is invalid by now */ + return(1); +} + + +/* Option -devices */ +/* @return <=0 error , 1 success, 2 revoked by -reassure +*/ +int Xorriso_option_devices(struct XorrisO *xorriso, int flag) +{ + int ret; + char sfe[5*SfileadrL]; + + if(xorriso->volset_change_pending) { + sprintf(xorriso->info_text, + "-devices: Image changes pending. -commit or -rollback first"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= Xorriso_reassure(xorriso, "-devices", + "eventually discard the current image", 0); + if(ret<=0) + return(2); + xorriso->info_text[0]= 0; + if(xorriso->in_drive_handle!=NULL || xorriso->out_drive_handle!=NULL) { + if(xorriso->in_drive_handle == xorriso->out_drive_handle) { + sprintf(xorriso->info_text, "Gave up -dev %s", + Text_shellsafe(xorriso->indev, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + }else { + if(xorriso->in_drive_handle!=NULL) { + sprintf(xorriso->info_text, "Gave up -indev %s", + Text_shellsafe(xorriso->indev, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } + if(xorriso->out_drive_handle!=NULL) { + sprintf(xorriso->info_text, "Gave up -outdev %s", + Text_shellsafe(xorriso->outdev, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } + } + Xorriso_give_up_drive(xorriso, 3); + } + ret= Xorriso_show_devices(xorriso, 0); + return(ret); +} + + +/* Option -dialog "on"|"single_line"|"off" */ +int Xorriso_option_dialog(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode, "on") == 0 || strcmp(mode, "multi_line") == 0) + xorriso->dialog= 2; + else if(strcmp(mode, "single_line") == 0) + xorriso->dialog= 2; + else if(strcmp(mode, "off") == 0) + xorriso->dialog= 0; + else { + sprintf(xorriso->info_text, "-dialog: unknown mode '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + return(1); +} + + +/* Option -disk_dev_ino "on"|"ino_only"|"off" */ +int Xorriso_option_disk_dev_ino(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode, "on") == 0) + xorriso->do_aaip= (xorriso->do_aaip & ~128) | 16 | 32 | 64; + else if(strcmp(mode, "ino_only") == 0) + xorriso->do_aaip|= 16 | 32 | 64 | 128; + else if(strcmp(mode, "off") == 0) + xorriso->do_aaip &= ~(16 | 32 | 64 | 128); + else { + sprintf(xorriso->info_text, "-disk_dev_ino: unknown mode '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + return(1); +} + + +/* Option -disk_pattern "on"|"ls"|"off" */ +int Xorriso_option_disk_pattern(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode, "off")==0) + xorriso->do_disk_pattern= 0; + else if(strcmp(mode, "on")==0) + xorriso->do_disk_pattern= 1; + else if(strcmp(mode, "ls")==0) + xorriso->do_disk_pattern= 2; + else { + sprintf(xorriso->info_text, "-disk_pattern: unknown mode '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + return(1); +} + + +/* Option -drive_class */ +int Xorriso_option_drive_class(struct XorrisO *xorriso, + char *d_class, char *pattern, int flag) +{ + int ret= 1; + + if(strcmp(d_class, "banned") == 0) { + ret= Xorriso_lst_new(&(xorriso->drive_blacklist), pattern, + xorriso->drive_blacklist, 1); + } else if(strcmp(d_class, "caution") == 0) { + ret= Xorriso_lst_new(&(xorriso->drive_greylist), pattern, + xorriso->drive_greylist, 1); + } else if (strcmp(d_class, "harmless") == 0) { + ret= Xorriso_lst_new(&(xorriso->drive_whitelist), pattern, + xorriso->drive_whitelist, 1); + } else if (strcmp(d_class, "clear_list") == 0) { + if(strcmp(pattern, "banned") == 0) + Xorriso_lst_destroy_all(&(xorriso->drive_blacklist), 0); + else if(strcmp(pattern, "caution") == 0) + Xorriso_lst_destroy_all(&(xorriso->drive_greylist), 0); + else if(strcmp(pattern, "harmless") == 0) + Xorriso_lst_destroy_all(&(xorriso->drive_whitelist), 0); + else if(strcmp(pattern, "all") == 0) { + Xorriso_lst_destroy_all(&(xorriso->drive_blacklist), 0); + Xorriso_lst_destroy_all(&(xorriso->drive_greylist), 0); + Xorriso_lst_destroy_all(&(xorriso->drive_whitelist), 0); + } else { + sprintf(xorriso->info_text, "-drive_class clear : unknown class '%s'", + pattern); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= 1; + } else { + sprintf(xorriso->info_text, "-drive_class: unknown class '%s'", d_class); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + return(ret); +} + + +/* Option -dummy "on"|"off" */ +int Xorriso_option_dummy(struct XorrisO *xorriso, char *mode, int flag) +{ + xorriso->do_dummy= !!strcmp(mode, "off"); + return(1); +} + + +/* Option -dvd_obs "default"|"32k"|"64k" */ +int Xorriso_option_dvd_obs(struct XorrisO *xorriso, char *obs, int flag) +{ + double num; + + if(strcmp(obs, "default") == 0) + num= 0; + else + num = Scanf_io_size(obs,0); + if(num != 0 && num != 32768 && num != 65536) { + sprintf(xorriso->info_text, + "-dvd_obs : Bad size. Acceptable are 0, 32k, 64k"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } else + xorriso->dvd_obs= num; + return(1); +} + + +/* Option -eject */ +/* @param flag bit0=do not report toc of eventually remaining drives +*/ +int Xorriso_option_eject(struct XorrisO *xorriso, char *which, int flag) +{ + int gu_flag= 4, ret; + + if(strncmp(which,"in",2)==0) + gu_flag|= 1; + else if(strncmp(which,"out",3)==0) + gu_flag|= 2; + else + gu_flag|= 3; + if((gu_flag&1) && xorriso->volset_change_pending) { + sprintf(xorriso->info_text, + "-eject: Image changes pending. -commit or -rollback first"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if(flag&1) + gu_flag|= 8; + ret= Xorriso_give_up_drive(xorriso, gu_flag); + return(ret); +} + + +/* Options -end , and -rollback_end */ +/* @param flag bit0= discard pending changes + bit1= do not -reassure + @return <=0 error , 1 success, 2 revoked by -reassure +*/ +int Xorriso_option_end(struct XorrisO *xorriso, int flag) +{ + int ret; + char *cmd, *which_will; + + if(flag&1) + cmd= "-rollback_end"; + else + cmd= "-end"; + if(xorriso->volset_change_pending) { + if(flag&1) + which_will= "end the program discarding image changes"; + else + which_will= "commit image changes and then end the program"; + } else { + which_will= "end the program"; + } + if(!(flag&2)) { + ret= Xorriso_reassure(xorriso, cmd, which_will, 0); + if(ret<=0) + return(2); + } + + if(xorriso->volset_change_pending) { + if(flag&1) { + xorriso->volset_change_pending= 0; + } else { + ret= Xorriso_option_commit(xorriso, 1); + xorriso->volset_change_pending= 0; /* no further tries to commit */ + if(ret<=0) + return(ret); + } + } + ret= Xorriso_give_up_drive(xorriso, 3); + if(ret<=0) + return(ret); + return(1); +} + + +/* Option -errfile_log marked|plain path|-|"" */ +int Xorriso_option_errfile_log(struct XorrisO *xorriso, + char *mode, char *path, int flag) +{ + int ret, mode_word; + FILE *fp= NULL; + char sfe[5*SfileadrL]; + + if(path[0]==0 || path[0]=='-') { + /* ok */; + } else { + fp= fopen(path, "a"); + if(fp==0) { + sprintf(xorriso->info_text, "-errfile_log: Cannot open file %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + mode_word= xorriso->errfile_mode; + if(strcmp(mode, "marked")==0) + mode_word|= 1; + else if(strcmp(mode, "plain")==0) + mode_word&= ~1; + else { + sprintf(xorriso->info_text, "-errfile_log: Unknown mode %s", + Text_shellsafe(mode, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + + Xorriso_process_errfile(xorriso, 0, "log end", 0, 1); + if(xorriso->errfile_fp!=NULL) + fclose(xorriso->errfile_fp); + xorriso->errfile_fp= fp; + xorriso->errfile_mode= mode_word; + ret= Sfile_str(xorriso->errfile_log, path, 0); + if(ret>0) + ret= Xorriso_process_errfile(xorriso, 0, "log start", 0, 1); + if(ret<=0) + return(ret); + return(1); +} + + +/* Option -error_behavior */ +int Xorriso_option_error_behavior(struct XorrisO *xorriso, + char *occasion, char *behavior, int flag) +{ + if(strcmp(occasion, "image_loading")==0) { + if(strcmp(behavior, "best_effort")==0) + xorriso->img_read_error_mode= 0; + else if(strcmp(behavior, "failure")==0 || strcmp(behavior, "FAILURE")==0) + xorriso->img_read_error_mode= 1; + else if(strcmp(behavior, "fatal")==0 || strcmp(behavior, "FATAL")==0) + xorriso->img_read_error_mode= 2; + else { +unknown_behavior:; + sprintf(xorriso->info_text, + "-error_behavior: with '%s': unknown behavior '%s'", + occasion, behavior); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } else if(strcmp(occasion, "file_extraction")==0) { + if(strcmp(behavior, "best_effort")==0) + xorriso->extract_error_mode= 0; + else if(strcmp(behavior, "keep")==0) + xorriso->extract_error_mode= 1; + else if(strcmp(behavior, "delete")==0) + xorriso->extract_error_mode= 2; + else + goto unknown_behavior; + } else { + sprintf(xorriso->info_text, "-error_behavior: unknown occasion '%s'", + occasion); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + return(1); +} + + +/* Option -external_filter */ +int Xorriso_option_external_filter(struct XorrisO *xorriso, + int argc, char **argv, int *idx, int flag) +{ + int ret, start_idx, end_idx; + + start_idx= *idx; + end_idx= Xorriso_end_idx(xorriso, argc, argv, start_idx, 1); + (*idx)= end_idx; + if(end_idx - start_idx < 3) { + sprintf(xorriso->info_text, + "-external_filter : Not enough arguments given. Needed: name options path %s", + xorriso->list_delimiter); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= Xorriso_external_filter(xorriso, argv[start_idx], + argv[start_idx + 1], argv[start_idx + 2], + end_idx - start_idx - 3, argv + start_idx + 3, 0); + return(ret); +} + + +/* Options -extract , -extract_single */ +/* @param flag bit0=do not report the restored item + bit1=do not reset pacifier, no final pacifier message + bit2= do not make lba-sorted node array for hardlink detection + bit5= -extract_single: eventually do not insert directory tree +*/ +int Xorriso_option_extract(struct XorrisO *xorriso, char *iso_path, + char *disk_path, int flag) +{ + int ret; + char eff_origin[SfileadrL], eff_dest[SfileadrL], *ipth, *eopt[1], *edpt[1]; + + if(xorriso->allow_restore <= 0) { + sprintf(xorriso->info_text, + "-extract: image-to-disk copies are not enabled by option -osirrox"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + if(!(flag&2)) + Xorriso_pacifier_reset(xorriso, 0); + + ipth= iso_path; + if(ipth[0]==0) + ipth= disk_path; + if(disk_path[0]==0) { + sprintf(xorriso->info_text, "-extract: Empty disk_path given"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 1); + ret= 0; goto ex; + } + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_dest, + 2|4); + if(ret<=0) + goto ex; + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, ipth, eff_origin, 2|8); + if(ret<=0) + goto ex; + + eopt[0]= eff_origin; + edpt[0]= eff_dest; + ret= Xorriso_restore_sorted(xorriso, 1, eopt, edpt, (flag & 32 ? 33 : 0)); + + if(!(flag&2)) + Xorriso_pacifier_callback(xorriso, "files restored",xorriso->pacifier_count, + xorriso->pacifier_total, "", 1|4); + if(ret<=0) + goto ex; + + if(!(flag&1)) { + sprintf(xorriso->info_text, "Extracted from ISO image: %s '%s'='%s'\n", + (ret>1 ? "directory" : "file"), eff_origin, eff_dest); + Xorriso_info(xorriso,0); + } + ret= 1; +ex:; + if(!(flag & (4 | 32))) + Xorriso_destroy_node_array(xorriso, 0); + return(ret); +} + + +/* Option -extract_cut */ +int Xorriso_option_extract_cut(struct XorrisO *xorriso, char *iso_rr_path, + char *start, char *count, char *disk_path, int flag) +{ + int ret; + double num; + off_t startbyte, bytecount; + + num= Scanf_io_size(start, 0); + if(num<0 || num > 1.0e18) { /* 10^18 = 10^3 ^ 6 < 2^10 ^ 6 = 2^60 */ + sprintf(xorriso->info_text, + "-extract_cut: startbyte address negative or much too large (%s)", + start); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + startbyte= num; + num= Scanf_io_size(count, 0); + if(num<=0 || num > 1.0e18) { + sprintf(xorriso->info_text, + "-extract_cut: bytecount zero, negative or much too large (%s)", + count); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + bytecount= num; + sprintf(xorriso->info_text, + "-extract_cut from %s , byte %.f to %.f, and store as %s", + iso_rr_path, (double) startbyte, (double) (startbyte+bytecount), + disk_path); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + + ret= Xorriso_extract_cut(xorriso, iso_rr_path, disk_path, + startbyte, bytecount, 0); + return(ret); +} + + +/* Option -file_size_limit */ +int Xorriso_option_file_size_limit(struct XorrisO *xorriso, + int argc, char **argv, int *idx, int flag) +{ + int ret, i, end_idx; + off_t new_limit= 0; + + end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); + if(*idx >= end_idx) + {ret= 2; goto ex;} + if(*idx + 1 == end_idx && strcmp(argv[*idx], "off") == 0) { + xorriso->file_size_limit= 0; + ret= 1; goto ex; + } + for(i= *idx; i < end_idx; i++) + new_limit+= Scanf_io_size(argv[i], 0); + if(new_limit <= 0) { + sprintf(xorriso->info_text, "-file_size_limit: values sum up to %.f", + (double) new_limit); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 1); + ret= 0; goto ex; + } + xorriso->file_size_limit= new_limit; + ret= 1; +ex:; + (*idx)= end_idx; + if(ret > 0) { + if(xorriso->file_size_limit > 0) + sprintf(xorriso->info_text, "-file_size_limit now at %.f\n", + (double) xorriso->file_size_limit); + else + sprintf(xorriso->info_text, "-file_size_limit now off\n"); + Xorriso_info(xorriso,0); + } + return(ret); +} + + +/* Option -find alias -findi, and -findx */ +/* @param flag bit0= -findx rather than -findi + bit1= do not reset pacifier, no final pacifier message + do not reset find_compare_result + bit2= do not count deleted files with rm and rm_r + bit3= use Xorriso_findi_sorted() rather than Xorriso_findi() + (this can also be ordered by test -sort_lba) +*/ +int Xorriso_option_find(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int ret, i, end_idx, type= 0, action, deleter= 0, start_lba, count; + struct FindjoB *job, *first_job= NULL, *new_job; + char *start_path, sfe[5*SfileadrL], *cpt, other_path_start[SfileadrL]; + char *access_acl_text= NULL, *default_acl_text= NULL; + + struct stat dir_stbuf; + uid_t user= 0; + gid_t group= 0; + time_t date= 0; + mode_t mode_or= 0, mode_and= ~1; + double mem_lut= 0.0; + + end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); + start_path= "."; + if(end_idx > *idx && start_path[0]!=0) + start_path= argv[*idx]; + ret= Findjob_new(&first_job, start_path, 0); + if(ret<=0) { + Xorriso_no_findjob(xorriso, "-find[ix]", 0); + {ret= -1; goto ex;} + } + job= first_job; + if(!(flag&2)) + xorriso->find_compare_result= 1; + for(i= *idx+1; i=end_idx) { +not_enough_arguments:; + sprintf(xorriso->info_text, + "-find[ix]: not enough arguments with test %s", + Text_shellsafe(argv[i], sfe, 0)); + goto sorry_ex; + } + i++; + ret= Findjob_set_name_expr(job, argv[i], 0); + if(ret<=0) { + sprintf(xorriso->info_text, "-find[ix]: cannot set -name expression %s", + Text_shellsafe(argv[i], sfe, 0)); + goto sorry_ex; + } + } else if(strcmp(argv[i], "-wholename")==0) { + if(i+1>=end_idx) + goto not_enough_arguments; + i++; + ret= Findjob_set_name_expr(job, argv[i], 1); + if(ret<=0) { + sprintf(xorriso->info_text, + "-find[ix]: cannot set -wholename expression %s", + Text_shellsafe(argv[i], sfe, 0)); + goto sorry_ex; + } + } else if(strcmp(argv[i], "-type")==0) { + if(i+1>=end_idx) + goto not_enough_arguments; + i++; + ret= Findjob_set_file_type(job, argv[i][0], 0); + if(ret<=0) { + sprintf(xorriso->info_text, "-find[ix]: unknown -type '%c'",argv[i][0]); + goto sorry_ex; + } + } else if(strcmp(argv[i], "-damaged")==0) { + Findjob_set_damage_filter(job, 1, 0); + } else if(strcmp(argv[i], "-undamaged")==0) { + Findjob_set_damage_filter(job, -1, 0); + } else if(strcmp(argv[i], "-lba_range")==0) { + if(i+2>=end_idx) + goto not_enough_arguments; + i+= 2; + sscanf(argv[i-1], "%d", &start_lba); + sscanf(argv[i], "%d", &count); + Findjob_set_lba_range(job, start_lba, count, 0); + } else if(strcmp(argv[i], "-pending_data")==0) { + Findjob_set_commit_filter_2(job, 0); + } else if(strcmp(argv[i], "-has_acl")==0) { + Findjob_set_acl_filter(job, 1, 0); + } else if(strcmp(argv[i], "-has_no_acl")==0) { + Findjob_set_acl_filter(job, -1, 0); + } else if(strcmp(argv[i], "-has_xattr")==0) { + Findjob_set_xattr_filter(job, 1, 0); + } else if(strcmp(argv[i], "-has_any_xattr")==0) { + Findjob_set_xattr_filter(job, 1, 1); + } else if(strcmp(argv[i], "-has_no_xattr")==0) { + Findjob_set_xattr_filter(job, -1, 0); + } else if(strcmp(argv[i], "-has_aaip")==0) { + Findjob_set_aaip_filter(job, 1, 0); + } else if(strcmp(argv[i], "-has_no_aaip")==0) { + Findjob_set_aaip_filter(job, -1, 0); + } else if(strcmp(argv[i], "-has_filter")==0) { + Findjob_set_filter_filter(job, 1, 0); + } else if(strcmp(argv[i], "-has_no_filter")==0) { + Findjob_set_filter_filter(job, -1, 0); + } else if(strcmp(argv[i], "-has_md5")==0) { + Findjob_set_prop_filter(job, 15, 1, 0); + } else if(strcmp(argv[i], "-true") == 0) { + ret= Findjob_set_false(job, -1, 0); + } else if(strcmp(argv[i], "-false") == 0) { + ret= Findjob_set_false(job, 1, 0); + } else if(strcmp(argv[i], "-decision") == 0) { + if(i+1>=end_idx) + goto not_enough_arguments; + i++; + ret= Findjob_set_decision(job, argv[i], 0); + } else if(strcmp(argv[i], "-prune") == 0) { + ret= Findjob_set_prune(job, 0); + } else if(strcmp(argv[i], "-sub") == 0 || strcmp(argv[i], "(") == 0) { + ret= Findjob_open_bracket(job, 0); + } else if(strcmp(argv[i], "-subend") == 0 || strcmp(argv[i], ")") == 0) { + ret= Findjob_close_bracket(job, 0); + } else if(strcmp(argv[i], "-not") == 0 || strcmp(argv[i], "!") == 0) { + ret= Findjob_not(job, 0); + } else if(strcmp(argv[i], "-and") == 0 || strcmp(argv[i], "-a") == 0) { + ret= Findjob_and(job, 0); + } else if(strcmp(argv[i], "-or") == 0 || strcmp(argv[i], "-o") == 0) { + ret= Findjob_or(job, 0); + } else if(strcmp(argv[i], "-if") == 0) { + ret= Findjob_if(job, 0); + } else if(strcmp(argv[i], "-then") == 0) { + ret= Findjob_then(job, 0); + } else if(strcmp(argv[i], "-else") == 0) { + ret= Findjob_else(job, 0); + } else if(strcmp(argv[i], "-elseif") == 0) { + ret= Findjob_elseif(job, 0); + } else if(strcmp(argv[i], "-endif") == 0) { + ret= Findjob_endif(job, 0); + } else if(strcmp(argv[i], "-sort_lba") == 0) { + flag|= 8; + /* If an operator is open: insert a -true test, else do nothing */ + ret= Findjob_set_false(job, -1, 1); + if(ret == 2) + ret= 1; + } else if(strcmp(argv[i], "-exec")==0) { + if(i+1>=end_idx) { +not_enough_exec_arguments:; + sprintf(xorriso->info_text, + "-find[ix]: not enough arguments with -exec %s", + Text_shellsafe(argv[i], sfe, 0)); + goto sorry_ex; + } + i++; + cpt= argv[i]; + if(*cpt=='-') + cpt++; + if(strcmp(cpt, "echo")==0) { + Findjob_set_action_target(job, 0, NULL, 0); + } else if(strcmp(cpt, "rm")==0) { + Findjob_set_action_target(job, 1, NULL, 0); + deleter= 1; + } else if(strcmp(cpt, "rm_r")==0) { + Findjob_set_action_target(job, 2, NULL, 0); + deleter= 1; + +#ifdef NIX +/* >>> not implemented yet */; + } else if(strcmp(cpt, "mv")==0) { + if(i+1>=end_idx) + goto not_enough_exec_arguments; + i++; + Findjob_set_action_target(job, 3, argv[i], 0); +#endif + + } else if(strcmp(cpt, "chown")==0 || strcmp(cpt, "chown_r")==0) { + if(i+1>=end_idx) + goto not_enough_exec_arguments; + i++; + ret= Xorriso_convert_uidstring(xorriso, argv[i], &user, 0); + if(ret<=0) + goto ex; + ret= Findjob_set_action_chown(job, user, strlen(cpt)>5); + if(ret<=0) { + Xorriso_no_findjob(xorriso, "-find -exec chown_r", 0); + goto ex; + } + } else if(strcmp(cpt, "chgrp")==0 || strcmp(cpt, "chgrp_r")==0) { + if(i+1>=end_idx) + goto not_enough_exec_arguments; + i++; + ret= Xorriso_convert_gidstring(xorriso, argv[i], &group, 0); + if(ret<=0) + goto ex; + ret= Findjob_set_action_chgrp(job, group, strlen(cpt)>5); + if(ret<=0) { + Xorriso_no_findjob(xorriso, "-find -exec chgrp_r", 0); + goto ex; + } + } else if(strcmp(cpt, "chmod")==0 || strcmp(cpt, "chmod_r")==0) { + if(i+1>=end_idx) + goto not_enough_exec_arguments; + i++; + ret= Xorriso_convert_modstring(xorriso, "-find -exec chmod", + argv[i], &mode_and, &mode_or, 0); + if(ret<=0) + goto ex; + ret= Findjob_set_action_chmod(job, mode_and, mode_or, strlen(cpt)>5); + if(ret<=0) { + Xorriso_no_findjob(xorriso, "-find -exec chmod_r", 0); + goto ex; + } + } else if(strcmp(cpt, "alter_date")==0 || strcmp(cpt, "alter_date_r")==0){ + if(i+2>=end_idx) + goto not_enough_exec_arguments; + i+= 2; + ret= Xorriso_convert_datestring(xorriso, "-find -exec alter_date", + argv[i-1], argv[i], &type, &date, 0); + if(ret<=0) + goto ex; + ret= Findjob_set_action_ad(job, type, date, strlen(cpt)>10); + if(ret<=0) { + Xorriso_no_findjob(xorriso, "-find -exec alter_date_r", 0); + goto ex; + } + } else if(strcmp(cpt, "lsdl")==0) { + Findjob_set_action_target(job, 8, NULL, 0); + + } else if(strcmp(cpt, "find")==0) { + ret= Findjob_new(&new_job, "", 0); + if(ret<=0) { + Xorriso_no_findjob(xorriso, "-find[ix]", 0); + {ret= -1; goto ex;} + } + Findjob_set_action_subjob(job, 13, new_job, 0); + job= new_job; + + } else if(strcmp(cpt, "compare")==0 || strcmp(cpt, "update")==0 || + strcmp(cpt, "widen_hardlinks")==0) { + if(i+1>=end_idx) + goto not_enough_exec_arguments; + i++; + action= 14; + if(strcmp(cpt, "update")==0) + action= 17; + if(strcmp(cpt, "widen_hardlinks")==0) + action= 32; + ret= Xorriso_make_abs_adr(xorriso, xorriso->wdx, argv[i], + other_path_start, 1|2|4|8); + if(ret<=0) + goto ex; + Findjob_set_action_target(job, action, other_path_start, 0); + ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, start_path,sfe, 1|2|4); + if(ret<=0) + goto ex; + Findjob_set_start_path(job, sfe, 0); + if(!(flag&2)) { + Xorriso_pacifier_reset(xorriso, 0); + mem_lut= xorriso->last_update_time; + } + } else if(strcmp(cpt, "in_iso")==0 || + strcmp(cpt, "not_in_iso")==0 || + strcmp(cpt, "add_missing")==0 || + strcmp(cpt, "empty_iso_dir")==0 || + strcmp(cpt, "is_full_in_iso")==0) { + if(i+1>=end_idx) + goto not_enough_exec_arguments; + i++; + ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, argv[i], + other_path_start, 1|2|4); + if(ret<=0) + goto ex; + if(strcmp(cpt, "in_iso")==0) + action= 15; + else if(strcmp(cpt, "add_missing")==0) + action= 18; + else if(strcmp(cpt, "empty_iso_dir")==0) + action= 19; + else if(strcmp(cpt, "is_full_in_iso")==0) + action= 20; + else + action= 16; + Findjob_set_action_target(job, action, other_path_start, 0); + ret= Xorriso_make_abs_adr(xorriso, xorriso->wdx, start_path, sfe, + 1|2|4|8); + if(ret<=0) + goto ex; + Findjob_set_start_path(job, sfe, 0); + + } else if(strcmp(cpt, "report_damage")==0) { + Findjob_set_action_target(job, 21, NULL, 0); + } else if(strcmp(cpt, "report_lba")==0) { + Findjob_set_action_target(job, 22, NULL, 0); + } else if(strcmp(cpt, "getfacl")==0) { + Findjob_set_action_target(job, 24, NULL, 0); + } else if(strcmp(cpt, "setfacl")==0) { + if(i+1>=end_idx) + goto not_enough_exec_arguments; + i++; + ret= Xorriso_normalize_acl_text(xorriso, argv[i], + &access_acl_text, &default_acl_text, 0); + if(ret <= 0) + goto ex; + Findjob_set_action_text_2(job, 25, access_acl_text, default_acl_text, + 0); + } else if(strcmp(cpt, "getfattr")==0) { + Findjob_set_action_target(job, 26, NULL, 0); + } else if(strcmp(cpt, "setfattr")==0) { + if(i + 2 >= end_idx) + goto not_enough_exec_arguments; + i+= 2; + /* check input */ + ret= Xorriso_path_setfattr(xorriso, NULL, "", argv[i - 1], + strlen(argv[i]), argv[i], 1); + if(ret <= 0) + goto ex; + Findjob_set_action_text_2(job, 27, argv[i - 1], argv[i], 0); + } else if(strcmp(cpt, "set_filter")==0) { + if(i + 1 >= end_idx) + goto not_enough_exec_arguments; + i+= 1; + Findjob_set_action_target(job, 28, argv[i], 0); + if(!(flag&2)) { + Xorriso_pacifier_reset(xorriso, 0); + mem_lut= xorriso->last_update_time; + } + } else if(strcmp(cpt, "show_stream")==0) { + Findjob_set_action_target(job, 29, NULL, 0); + } else if(strcmp(cpt, "get_any_xattr")==0) { + Findjob_set_action_target(job, 33, NULL, 0); + } else if(strcmp(cpt, "get_md5")==0) { + Findjob_set_action_target(job, 34, NULL, 0); + } else if(strcmp(cpt, "check_md5")==0) { + if(i + 1 >= end_idx) + goto not_enough_exec_arguments; + i+= 1; + Findjob_set_action_target(job, 35, argv[i], 0); + flag|= 8; + if(!(flag&2)) { + Xorriso_pacifier_reset(xorriso, 0); + mem_lut= xorriso->last_update_time; + } + if(!(flag & 1)) + xorriso->find_check_md5_result= 0; + } else if(strcmp(cpt, "make_md5")==0) { + Findjob_set_action_target(job, 36, NULL, 0); + flag|= 8; + if(!(flag&2)) { + Xorriso_pacifier_reset(xorriso, 0); + mem_lut= xorriso->last_update_time; + } + } else if(strcmp(cpt, "mkisofs_r")==0) { + Findjob_set_action_target(job, 37, NULL, 0); + } else if(strcmp(cpt, "sort_weight")==0) { + if(i + 1 >= end_idx) + goto not_enough_exec_arguments; + i+= 1; + sscanf(argv[i], "%d", &type); + Findjob_set_action_type(job, 38, type, 0); + } else { + sprintf(xorriso->info_text, "-find -exec: unknown action %s", + Text_shellsafe(argv[i], sfe, 0)); + goto sorry_ex; + } + } else { + sprintf(xorriso->info_text, "-find[ix]: unknown option %s", + Text_shellsafe(argv[i], sfe, 0)); +sorry_ex:; + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + } + if(flag&1) + ret= Xorriso_findx(xorriso, first_job, "", start_path, &dir_stbuf, 0, NULL, + 0); + else if(flag & 8) { + cpt= start_path; + ret= Xorriso_findi_sorted(xorriso, first_job, (off_t) 0, 1, &cpt, 0); + } else + ret= Xorriso_findi(xorriso, first_job, NULL, (off_t) 0, NULL, + start_path, &dir_stbuf, 0, (flag&4)>>1); +ex:; + if(deleter && !(flag&2)) + Xorriso_pacifier_callback(xorriso, "iso_rr_paths deleted", + xorriso->pacifier_count, 0, "", 1|2); + else if(first_job->action == 28 && !(flag&2)) + Xorriso_pacifier_callback(xorriso, "file filters processed", + xorriso->pacifier_count, 0, "", 1 | 2); + else if(mem_lut!=xorriso->last_update_time && mem_lut!=0.0 && !(flag&2)) + Xorriso_pacifier_callback(xorriso, "content bytes read", + xorriso->pacifier_count, 0, "", 1); + if(first_job->action == 35 && !(flag & 1)) + Xorriso_report_md5_outcome(xorriso, first_job->target, 0); + if(access_acl_text != NULL) + free(access_acl_text); + if(default_acl_text != NULL) + free(default_acl_text); + Findjob_destroy(&first_job, 0); + (*idx)= end_idx; + return(ret); +} + + +/* Option -follow */ +int Xorriso_option_follow(struct XorrisO *xorriso, char *mode, int flag) +{ + int was_fl, was_fm, was_fpr, was_fpt, l; + double num; + char *cpt, *npt; + + was_fpt= xorriso->do_follow_pattern; + was_fpr= xorriso->do_follow_param; + was_fl= xorriso->do_follow_links; + was_fm= xorriso->do_follow_mount; + xorriso->do_follow_pattern= 0; + xorriso->do_follow_param= 0; + xorriso->do_follow_links= 0; + xorriso->do_follow_mount= 0; + npt= cpt= mode; + for(cpt= mode; npt!=NULL; cpt= npt+1) { + npt= strchr(cpt,':'); + if(npt==NULL) + l= strlen(cpt); + else + l= npt-cpt; + if(l==0) + goto unknown_mode; + if(strncmp(cpt, "off", l)==0) { + xorriso->do_follow_pattern= 0; + xorriso->do_follow_param= 0; + xorriso->do_follow_links= 0; + xorriso->do_follow_mount= 0; + } else if(strncmp(cpt, "on", l)==0) { + xorriso->do_follow_pattern= 1; + xorriso->do_follow_param= 1; + xorriso->do_follow_links= 1; + xorriso->do_follow_mount= 1; + } else if(strncmp(cpt, "default", l)==0) { + xorriso->do_follow_pattern= 1; + xorriso->do_follow_param= 0; + xorriso->do_follow_links= 0; + xorriso->do_follow_mount= 1; + xorriso->follow_link_limit= 100; + } else if(strncmp(cpt, "link", l)==0 || strncmp(cpt,"links", l)==0) { + xorriso->do_follow_links= 1; + } else if(strncmp(cpt, "mount", l)==0) { + xorriso->do_follow_mount= 1; + } else if(strncmp(cpt,"param", l)==0) { + xorriso->do_follow_param= 1; + } else if(strncmp(cpt, "pattern", l)==0) { + xorriso->do_follow_pattern= 1; + } else if(strncmp(cpt, "limit=", 6)==0) { + sscanf(cpt+6, "%lf", &num); + if(num<=0 || num>1.0e6) { + sprintf(xorriso->info_text, "-follow: Value too %s with '%s'", + num<=0 ? "small" : "large", cpt+6); + goto sorry_ex; + } + xorriso->follow_link_limit= num; + } else { +unknown_mode:; + if(linfo_text, "-follow: unknown mode '%s'", cpt); + else + sprintf(xorriso->info_text, "-follow: oversized mode parameter (%d)",l); +sorry_ex: + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + xorriso->do_follow_pattern= was_fpt; + xorriso->do_follow_param= was_fpr; + xorriso->do_follow_links= was_fl; + xorriso->do_follow_mount= was_fm; + return(0); + } + } + return(1); +} + + +/* Option -fs */ +int Xorriso_option_fs(struct XorrisO *xorriso, char *size, int flag) +{ + double num; + + num= Scanf_io_size(size, 0); + if(num < 64*1024 || num > 1024.0 * 1024.0 * 1024.0) { + sprintf(xorriso->info_text, "-fs: wrong size %.f (allowed: %.f - %.f)", + num, 64.0 * 1024.0, 1024.0 * 1024.0 * 1024.0); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + xorriso->fs= num / 2048.0; + if(xorriso->fs * 2048 < num) + xorriso->fs++; + return(1); +} + + +/* Optionis -getfacl alias -getfacli, -getfacl_r alias -getfacl_ri + -getfattr alias getfattri +*/ +/* @param flag bit0= recursive -getfacl_r + bit1= getfattr rather than getfacl + bit3= with bit1: do not ignore eventual non-user attributes +*/ +int Xorriso_option_getfacli(struct XorrisO *xorriso, + int argc, char **argv, int *idx, int flag) +{ + int i, ret, was_failure= 0, end_idx, fret; + int optc= 0; + char **optv= NULL; + struct FindjoB *job= NULL; + struct stat dir_stbuf; + + ret= Xorriso_opt_args(xorriso, "-getfacl", argc, argv, *idx, &end_idx, &optc, + &optv, 0); + if(ret<=0) + goto ex; + for(i= 0; i0 && !xorriso->request_to_abort) + continue; /* regular bottom of loop */ + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + ret= 0; goto ex; + } + ret= 1; +ex:; + (*idx)= end_idx; + Xorriso_opt_args(xorriso, "-getfacl", argc, argv, *idx, &end_idx, + &optc, &optv, 256); + Findjob_destroy(&job, 0); + if(ret<=0) + return(ret); + return(!was_failure); +} + + +/* Option -gid */ +int Xorriso_option_gid(struct XorrisO *xorriso, char *gid, int flag) +{ + int ret; + + xorriso->do_global_gid= 0; + if(gid[0]==0 || strcmp(gid,"-")==0) + return(1); + ret= Xorriso_convert_gidstring(xorriso, gid, &(xorriso->global_gid), 0); + if(ret>0) + xorriso->do_global_gid= 1; + return(ret); +} + + +/* Option -grow_blindly */ +int Xorriso_option_grow_blindly(struct XorrisO *xorriso, char *msc2, int flag) +{ + double num; + int l; + + if(msc2[0]==0 || msc2[0]=='-' || strcmp(msc2, "off")==0) { + xorriso->grow_blindly_msc2= -1; + return(1); + } + num= Scanf_io_size(msc2, 0); + l= strlen(msc2); + if(msc2[l-1]<'0' || msc2[l-1]>'9') + num/= 2048.0; + xorriso->grow_blindly_msc2= num; + return(1); +} + + +/* Option -hardlinks "on"|"off" */ +int Xorriso_option_hardlinks(struct XorrisO *xorriso, char *mode, int flag) +{ + int ret; + char what_data[SfileadrL], *what, *what_next; + + if(Sfile_str(what_data, mode, 0)<=0) { + sprintf(xorriso->info_text, + "-hardlinks: mode string is much too long (%d)", + (int) strlen(mode)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + for(what= what_data; what != NULL; what= what_next) { + what_next= strchr(what, ':'); + if(what_next != NULL) { + *what_next= 0; + what_next++; + } + if(strcmp(what, "off") == 0) { + Xorriso_finish_hl_update(xorriso, 0); + xorriso->ino_behavior|= 1 | 2 | 4; + xorriso->ino_behavior&= ~8; + } else if(strcmp(what, "on") == 0) { + xorriso->ino_behavior&= ~(1 | 2 | 4 | 8); + } else if(strcmp(what, "without_update") == 0) { + Xorriso_finish_hl_update(xorriso, 0); + xorriso->ino_behavior&= ~(1 | 2 | 4); + xorriso->ino_behavior|= 8; + } else if(strcmp(what, "start_update") == 0) { + xorriso->ino_behavior&= ~(1 | 2 | 4 | 8); + ret= Xorriso_make_di_array(xorriso, 1); + if(ret <= 0) + return(ret); + } else if(strcmp(what, "end_update") == 0) { + Xorriso_finish_hl_update(xorriso, 0); + } else if(strcmp(what, "perform_update") == 0) { + Xorriso_finish_hl_update(xorriso, 0); + } else if(strcmp(what, "start_extract") == 0) { + xorriso->ino_behavior&= ~(1 | 2 | 4); + ret= Xorriso_make_hln_array(xorriso, 1); + if(ret <= 0) + return(ret); + } else if(strcmp(what, "end_extract") == 0) { + Xorriso_destroy_hln_array(xorriso, 0); + } else if(strcmp(what, "discard_extract") == 0) { + Xorriso_destroy_hln_array(xorriso, 0); + } else if(strcmp(what, "normal_extract") == 0) { + xorriso->ino_behavior&= ~16; + } else if(strcmp(what, "cheap_sorted_extract") == 0) { + xorriso->ino_behavior|= 16; + } else { + sprintf(xorriso->info_text, "-hardlinks: unknown mode '%s' in '%s'", + what, mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + if(xorriso->ino_behavior & 2) + Xorriso_option_compliance(xorriso, "new_rr", 0); + + return(1); +} + + +/* Option -help and part of -prog_help */ +int Xorriso_option_help(struct XorrisO *xorriso, int flag) +{ + static char text[][80]={ + +#ifdef Xorriso_no_helP + +"This binary program does not contain a help text.", +"If available, read: man 1 xorriso", + +#else + +"This program creates, loads, manipulates and writes ISO 9660 filesystem", +"images with Rock Ridge extensions. Write targets can be drives with optical", +"media or local filesystem objects.", +"", +"Preparation options:", +"Drive addresses are either /dev/... as listed with option -devices or", +"disk files, eventually with prefix \"stdio:\" if non-CD-drive in /dev tree.", +"E.g. /dev/sr0 , /tmp/pseudo_drive , stdio:/dev/sdc", +" -dev address Set input and output drive and load eventual ISO image.", +" Set the image expansion method to growing.", +" -indev address Set input drive and load eventual ISO image. Use expansion", +" methods modifying or blind growing.", +" -outdev address", +" Set output drive and use modifying or blind growing.", +" -drive_class \"harmless\"|\"banned\"|\"risky\"|\"clear_list\" disk_pattern", +" Add a drive path pattern to one of the safety lists or make", +" those lists empty. Defaulty entry in \"risky\" is \"/dev\".", +" -grow_blindly \"off\"|predicted_nwa", +" Switch between modifying and blind growing.", +" -load \"session\"|\"track\"|\"lba\"|\"sbsector\"|\"volid\"|\"auto\" id", +" Load a particular (outdated) ISO image from a -dev or", +" -indev which hosts more than one session.", +" -rom_toc_scan \"on\"|\"force\"|\"off\"[:\"emul_on\"|\"emul_off\"]", +" Enable scanning for ISO sessions on read-only drives/media", +" resp. on overwriteable media with emulated TOC.", +" -calm_drive \"in\"|\"out\"|\"all\"|\"on\"|\"off\"", +" Reduce drive noise until it gets actually used again.", +" -assert_volid pattern severity", +" Accept input image only if its volume id matches pattern.", +" -charset name Set the character set name to be used for file name", +" conversion from and to media.", +" -in_charset name", +" Like -charset but only for conversion from media.", +" -auto_charset \"on\"|\"off\"", +" Enable writing and reading of character set name in image.", +" -out_charset name", +" Like -charset but only for conversion to media.", +" -local_charset name", +" Override system assumption of the local character set name.", +" -hardlinks mode[:mode ...]", +" Enable resp. disable recording and restoring of hard links.", +" Modes are \"on\", \"off\", \"perform_update\",", +" \"without_update\", \"discard_extract\",", +" \"cheap_sorted_extract\", \"normal_extract\"", +" -acl \"on\"|\"off\"", +" Enable resp. disable reading and writing of ACLs.", +" -xattr \"on\"|\"off\"", +" Enable resp. disable reading and writing of xattr.", +" -for_backup", +" Shortcut for: -hardlinks on -acl on -xattr on -md5 on", +" -disk_dev_ino \"on\"|\"ino_only\"|\"off\"", +" Enable resp. disable recording of disk file dev_t and ino_t", +" and their use in file comparison.", +" -md5 \"on\"|\"all\"|\"off\"", +" Enable resp. disable processing of MD5 checksums.", +" -scdbackup_tag list_path record_name", +" Enable production of scdbackup tag with -md5 on", +" -ban_stdio_write", +" Allow for writing only the usage of optical drives.", +" -blank \"fast\"|\"all\"|\"deformat\"|\"deformat_quickest\"", +" Blank media resp. invalidate ISO image on media.", +" -format \"as_needed\"|\"full\"|\"fast\"|\"by_index_#\"|\"by_size_#\"", +" Format BD-RE, BD-R, DVD-RAM, DVD-RW, DVD+RW.", +" -volid volume_id", +" Specifies the volume ID text. (32 chars out of [A-Z0-9_])", +" -volset_id name", +" Specifies the volume set id. (128 chars)", +" -publisher name", +" Specifies the publisher name. (128 chars)", +" -application_id name", +" Specifies the application id. (128 chars)", +" -system_id name", +" Specifies the system id for the System Area. (32 chars)", +" -volume_date type timestring", +" Specifies volume timestamps. [\"c\",\"m\",\"x\",\"f\",\"uuid\"]", +" -joliet \"on\"|\"off\"", +" Generate Joliet info additional to Rock Ridge info.", +" -compliance rule[:rule...]", +" Allow more or less harmless deviations from strict standards", +" compliance.", +" -boot_image \"any\"|\"isolinux\"|\"grub\"", +" \"discard\"|\"keep\"|\"patch\"|\"dir=\"|\"bin_path=\"|\"cat_path=\"", +" |\"load_size=\"|\"system_area=\"|\"partition_table=on|off\"", +" Whether to discard or keep an exiting El Torito boot image.", +" ISOLINUX can be made bootable by dir=/ or dir=/isolinux", +" or dir=/boot/isolinux. Others, like GRUB, by bin_path=...", +" and cat_path=...", +" The boot image and its helper files need to be added to the", +" ISO image by the usual commands like -map or -add.", +" system_area= and partition_table= are for MBR based booting", +" from USB stick. The system_area= file needs not to be added.", +"", +" -uid uid User id to be used for the whole multi-session ISO image.", +" -gid gid Group id for the same purpose.", +"", +" -devices Show list of available optical drives and their addresses.", +"", +" -toc Show media specific table of content (sessions).", +"", +" -mount_cmd drive entity id path", +" Print to result channel a command suitable to mount the", +" depicted entity (see -load) at the given directory path.", +" -mount_opts \"exclusive\"|\"shared\"", +" Set options for -mount and -mount_cmd.", +" -session_string drive entity id \"linux:\"path|\"freebsd:\"path|form", +" Print foreign OS command or custom line.", +"", +" -list_formats Show media specific list of format descriptors.", +"", +" -list_profiles \"in\"|\"out\"|\"all\"", +" Show list of media types supported by indev resp. outdev.", +" -print_size Print the foreseeable consumption by next -commit.", +"", +" -tell_media_space", +" Print foreseeable available space on output media", +" -pvd_info Print various id strings of the loaded ISO image." +"", +"Options with variable length path list [...] need the list delimiter text", +"as end mark if they are followed by another option. By default this delimiter", +"is \"--\". In dialog and with options read from files, the line end serves", +"as such a mark. With program arguments this mark can be omitted only with", +"the last option in the list of arguments.", +"For brevity the list delimiter is referred as \"--\" throughout this text.", +"", +" -list_delimiter text Set the list delimiter to be used instead of \"--\"", +" It has to be a single word, must not be empty, not longer", +" than 80 characters, may mot contain quotation marks.", +"", +"Manipulation options:", +"disk_path is a path to an object in the local filesystem tree.", +"iso_rr_path is the Rock Ridge name of a file object in the ISO image.", +"pathspec is either a disk_path or (if allowed) a pair: iso_rr_path=disk_path", +"Options marked by [***] have variable argument length and perform pattern", +"expansion if enabled by -iso_rr_pattern resp. -disk_pattern.", +"", +" -pathspecs \"on\"|\"off\" Allow or disallow pathspecs of form ", +" iso_rr_path=disk_path . Only \"off\" allows eventual", +" -disk_pattern expansion.", +" -add pathspec [...] | disk_path [***]", +" Insert the given files or directory trees from", +" filesystem into the ISO image. Much like mkisofs.", +" -add_plainly \"none\"|\"unknown\"|\"dashed\"|\"any\"", +" Whether to add lonely arguments as pathspec resp. disk_path.", +" -path_list disk_path", +" Like -add but read the pathspecs from file disk_path.", +" -quoted_path_list disk_path", +" Like -path_list but with line rules as -dialog \"on\".", +"", +" -map disk_path iso_rr_path", +" Insert disk file object at the given iso_rr_path.", +" -map_single disk_path iso_rr_path", +" Like -map but with directory do not insert its sub tree.", +" -map_l disk_prefix iso_rr_prefix disk_path [***]", +" Performs -map with each disk_path.", +" -update disk_path iso_rr_path", +" Compare both file objects and do what is necessary to make", +" iso_rr_path a matching copy of disk_path.", +" -update_r disk_path iso_rr_path", +" Like -update but affecting all files below directories.", +" -update_l disk_prefix iso_rr_prefix disk_path [***]", +" Performs -update_r with each disk_path.", +" -cut_out disk_path byte_offset byte_count iso_rr_path", +" Map a byte interval of a regular disk file into a regular", +" file in the ISO image.", +"", +" -cpr disk_path [***] iso_rr_path", +" Insert the given files or directory trees from filesystem", +" into the ISO image, according to the rules of cp -r.", +"", +" -rm iso_rr_path [***]", +" Delete the given files from the ISO image.", +" -rm_r iso_rr_path [***]", +" Delete the given directory trees from ISO image.", +" -mv iso_rr_path [***] iso_rr_path", +" Rename the given file objects in the ISO tree to the last", +" argument in the list.", +" -chown uid iso_rr_path [***]", +" Equivalent to chown in the ISO image.", +" -chown_r uid iso_rr_path [***]", +" Like -chown but affecting all files below directories.", +" -chgrp gid iso_rr_path [***]", +" Equivalent to chgrp in the ISO image.", +" -chgrp_r gid iso_rr_path [***]", +" Like -chgrp but affecting all files below directories.", +" -chmod mode iso_rr_path [***]", +" Equivalent to chmod in the ISO image.", +" -chmod_r mode iso_rr_path [***]", +" Like -chmod but affecting all files below directories.", +" -setfacl acl_text iso_rr_path [***]", +" Replace the permissions and eventual ACL of the given files", +" in the ISO image by the ACL which is defined by acl_text.", +" -setfacl_r acl_text iso_rr_path [***]", +" Like -setfacl but affecting all files below directories.", +" -setfacl_list disk_path", +" Read output of getfacl from file disk_path. Set owner,", +" group and ACL of the iso_rr_path given by line \"# file:\".", +" -setfattr [-]name value iso_rr_path [***]", +" Set xattr pair with the given name to the given value, or", +" delete pair if name is prefixed with \"-\" and value is", +" an empty text.", +" -setfattr_r [-]name value iso_rr_path [***]", +" Like -setfattr but affecting all files below directories.", +" -setfattr_list disk_path", +" Read output of getfattr from file disk_path. Replace the", +" xattr of the iso_rr_path given by line \"# file:\".", +" -alter_date type timestring iso_rr_path [***]", +" Alter the date entries of a file in the ISO image. type is", +" one of \"a\", \"m\", \"b\" for:", +" access time, modification time, both times.", +" -alter_date_r type timestring iso_rr_path [***]", +" Like -alter_date but affecting all files below directories.", +" -find iso_rr_path [test [op] [test ...]] [-exec action [params]]", +" performs an action on files below the given directory in", +" the ISO image. Tests:", +" -name pattern, -wholename pattern, -type b|c|d|p|f|l|s|e,", +" -pending_data, -lba_range start count, -damaged,", +" -has_acl, -has_xattr, -has_aaip, -has_filter, -has_md5", +" -has_any_xattr, -prune, -decision yes|no, -true, -false", +" Operators: -not, -or, -and, -sub, (, -subend, ),", +" -if, -then, -elseif, -else, -endif", +" Action may be one of: echo, chown, chown_r, chgrp, chgrp_r", +" chmod, chmod_r, alter_date, alter_date_r, lsdl, compare,", +" rm, rm_r, compare, update, report_damage, report_lba,", +" getfacl, setfacl, getfattr, setfattr, get_any_xattr,", +" get_md5, check_md5, make_md5, set_filter, show_stream,", +" mkisofs_r, find.", +" params are their arguments except iso_rr_path.", +" -mkdir iso_rr_path [...]", +" Create empty directories if they do not exist yet.", +" -rmdir iso_rr_path [***]", +" Delete empty directories.", +" -- Default list delimiter marking the end of action argument", +" list. It may be changed by option -list_delimiter.", +"", +" -not_paths disk_path [***]", +" Add the given paths to the list of excluded absolute paths.", +" -not_leaf pattern", +" Add the given pattern to the list of leafname exclusions.", +" -not_list disk_path", +" Read lines from disk_path and use as -not_paths (with \"/\")", +" or as -not_leaf (without \"/\").", +" -quoted_not_list disk_path", +" Like -not_list but with line rules as -dialog \"on\".", +" -not_mgt \"reset\"|\"on\"|\"off\"|\"param_on\"|\"subtree_on\"|\"ignore_on\"", +" Control effect of exclusion lists.", +" -follow \"on\"|\"pattern:param:link:mount:limit=#\"|\"default\"|\"off\"", +" Follow symbolic links and mount points within disk_path.", +" -overwrite \"on\"|\"nondir\"|\"off\"", +" Allow or disallow to overwrite existing files in ISO image.", +" -split_size number[\"k\"|\"m\"]", +" Set the threshold for automatic splitting of regular files.", +" -reassure \"on\"|\"tree\"|\"off\"", +" If \"on\" then ask the user for \"y\" or \"n\" with any", +" file before deleting or overwriting it in the ISO image.", +"", +"Filter options:", +"External filter processes may produce synthetic file content by reading the", +"original content from stdin and writing to stdout whatever they want.", + +#ifdef Xorriso_allow_external_filterS + +" -external_filter name option[:option] program_path [arguments] --", +" Define an external filter. Options are: suffix=...: ", +" remove_suffix:if_nonempty:if_reduction:if_block_reduction.", +" -unregister_filter name", +" Undefine an external filter.", +" -close_filter_list", +" Irrevocably ban -external_filter and -unregister_filter.", + +#else + +"Sorry: The use of external filters was not enabled at compile time.", +" E.g. by ./configure option --enable-external-filters", + +#endif /* ! Xorriso_allow_external_filterS */ + +" -set_filter name iso_rr_path [***]", +" Apply a defined filter to the given data files.", +" Special name \"--remove-all-filters\" revokes filtering.", +" Builtin filters are --gzip , --gunzip, --zisofs .", +" -set_filter_r name iso_rr_path [***]", +" Like -set_filter but affecting all files below directories.", +"", +"zisofs is a compression format which is recognized by some Linux kernels.", +"xorriso supports it by builtin filter \"--zisofs\" which is to be applied by", +"the user, and by \"--zisofs-decode\" which is applied automatically when", +"compressed content is detected with a file in the ISO image.", +" -zisofs option[:options]", +" Set global zisofs parameters:", +" level=0|...|9 , block_size=32k|64k|128k , by_magic=on|off", +"", +"Write-to-media options:", +" -rollback Discard the manipulated ISO image and reload it.", +"", +" -commit Perform the write operation and then perform -dev outdrive.", +" Hint: To perform a final write operation with no new -dev", +" and no new loading of image, execute option -end.", +" -commit_eject \"in\"|\"out\"|\"all\"|\"none\"", +" Like -commit but rather eject than load image from outdrive.", +" Give up any unejected drive afterwards.", +" -close \"on\"|\"off\"", +" If \"on\" then mark the written media as not appendable.", +" -padding number[\"k\"|\"m\"]", +" Append extra bytes to image stream. (Default is 300k)", +" -dummy \"on\"|\"off\"", +" If \"on\" simulate burning. Refuse if media cannot simulate.", +" -speed number[\"k/s\"|\"m/s\"|\"[x]CD\"|\"[x]DVD\"|\"[x]BD\"]", +" Set the burn speed. Default is 0 = maximum speed.", +" -stream_recording \"on\"|\"off\"", +" Try to circumvent slow checkread on DVD-RAM, BD-RE, BD-R.", +" -dvd_obs \"default\"|\"32k\"|\"64k\"", +" Set number of bytes per DVD/BD write operation.", +" -stdio_sync \"on\"|\"off\"|number", +" Set number of bytes after which to force output to stdio", +" pseudo drives. \"on\" is the same as 16m.", +" -fs number[\"k\"|\"m\"]", +" Set the size of the fifo buffer. (Default is 4m)", +" -eject \"in\"|\"out\"|\"all\"", +" Immediately eject the media in -indev, resp. -outdev,", +" resp. both.", +"", +"Navigation options:", +"", +" -cd iso_rr_path Change working directory in the ISO image. iso_rr_paths", +" which do not begin with '/' will be inserted beginning at", +" the path given with -cd. -ls patterns will eventually", +" looked up at this path.", +" -cdi disk_path Same as -cd disk_path", +" -cdx disk_path Change the current working directory in the local", +" filesystem. disk_paths which do not begin with '/'", +" will be looked up beginning at the path given with -cdx.", +" -lsx patterns will eventually be looked up at this path.", +" -pwd tells the current working directory in the ISO image.", +" -pwdi same as -pwd.", +" -pwdx tells the current working directory in the local filesystem.", +"", +" -iso_rr_pattern \"on\"|\"ls\"|\"off\"", +" Enable or disable pattern expansions for ISO image commands", +" marked by [***]. \"ls\" restricts it to -ls and -du.", +" -disk_pattern \"on\"|\"ls\"|\"off\"", +" Enable or disable pattern expansions for local filesystem", +" commands marked by [***]. \"ls\" restricts to -ls*x and -du*x.", +"", +" -ls pattern [***] lists files of the ISO image which match one of the", +" given shell parser patterns. (I.e. wildcards '*' '?').", +" Directories are listed by their content.", +" -lsd pattern [***] like -ls but listing directories as single items.", +" -lsl pattern [***] like -ls but also telling some file attributes.", +" -lsdl pattern [***] like -lsd but also telling some file attributes.", +"", +" -lsx pattern [***] lists files of the local filesystem which match one", +" of the patterns. Directories are listed by their content.", +" -lsdx pattern [***] like -lsx but listing directories as single items.", +" -lslx pattern [***] like -lsx but also telling some file attributes.", +" -lsdlx pattern [***] like -lsdx but also telling some file attributes.", +" -getfacl pattern [***] list eventual ACLs of the given files.", +" -getfacl_r pattern [***] like -getfacl but listing whole file trees.", +" -getfattr pattern [***] list eventual xattr of the given files.", +" -getfxattr_r pattern [***] like -getfxattr but listing whole file trees.", +"", +" -du pattern [***] recursively lists sizes of files or directories in the", +" ISO image which match one of the shell parser patterns.", +" -dux pattern [***] recursively lists sizes of files or directories in the", +" local filesystem which match one of the shell parser", +" patterns.", +" -dus pattern [***] like -du but summing up subdirectories without", +" listing them explicitely.", +" -dusx pattern [***] like -dux but summing up subdirectories without", +" listing them explicitely.", +"", +" -findx disk_path [-name pattern] [-type t] [-exec action [params]]", +" Like -find but operating on local filesystem. Most -exec", +" actions are defaulted to action echo. Supported actions are:", +" in_iso, not_in_iso, is_full_in_iso, add_missing,", +" empty_iso_dir", +"", +" -compare disk_path iso_rr_path", +" compare attributes and in case of regular data files the", +" content of filesystem object and ISO object.", +" -compare_r disk_path iso_rr_path", +" Like -compare but affecting all files below directories.", +" -compare_l disk_prefix iso_rr_prefix disk_path [***]", +" Performs -compare_r with each disk_path.", +"", +" -show_stream iso_rr_path [***]", +" Show content stream chain of data files in the ISO image.", +" -show_stream_r iso_rr_path [***]", +" Like -show_stream but affecting all files below directories.", +"", +"Restore options which copy file objects from ISO image to disk filesystem:", +" -osirrox \"on\"|\"device_files\"|\"off\"|\"banned\"", +" [:\"concat_split_on\"|\"concat_split_off\"]", +" [:\"auto_chmod_on\"|\"auto_chmod_off\"]", +" [:\"sort_lba_on\"|\"sort_lba_off\"]", +" By default \"off\" the inverse operation of xorriso from ISO", +" image to disk filesystem is disabled. \"on\" allows xorriso", +" to create, overwrite, delete files in the disk filesystem.", +" \"banned\" is irrevocably \"off\".", +" -extract iso_rr_path disk_path", +" Copy tree under iso_rr_path onto disk address disk_path.", +" This avoids the pitfalls of cp -r addressing rules.", +" -extract_l iso_rr_prefix disk_prefix iso_rr_path [***]", +" Perform -extract with each iso_rr_path.", +" -extract_single iso_rr_path disk_path", +" Like -extract but with directory do not restore sub tree.", +" -extract_cut iso_rr_path byte_offset byte_count disk_path", +" Copy a byte interval from iso_rr_path to disk_path.", +" This is governed in part by -check_media_defaults.", +" -cpx iso_rr_path [***] disk_path", +" Copy leaf file objects from ISO image to disk filesystem.", +" -cpax iso_rr_path [***] disk_path", +" Like -cpx but trying to restore timestamps and ownership.", +" -cp_rx iso_rr_path [***] disk_path", +" Copy directory trees from ISO image to disk filesystem.", +" -cp_rax iso_rr_path [***] disk_path", +" Like -cp_rx but trying to restore timestamps and ownership.", +" -paste_in iso_rr_path disk_path byte_offset byte_count", +" Copy ISO file content into a byte interval of a disk file.", +" -mount drive entity id path", +" Like -mount_cmd but actually performing that command if", +" not setuid or setgid is active.", +"", +"Evaluation of readability:", +" -check_media [options] --", +" Try to read data blocks from media and report about the", +" outcome. Several options modify the behavior:", +" use=indev|outdev , what=track|session ,", +" min_lba=blockadr , max_lba=blockadr ,", +" abort_file=path , time_limit=seconds , item_limit=number ,", +" retry=on|off|default , data_to=filepath ,", +" sector_map=filepath , map_with_volid=on|off ,", +" patch_lba0=on|off|force|blockadr[:force] ,", +" report=blocks|files|blocks_files event=severity ,", +" bad_limit=quality , slow_limit=seconds , chunk_size=bytes", +" -check_media_defaults [options] --", +" Preset options for runs of -check_media and -extract_cut.", +"", +"Compatibility emulation (argument list may be ended by list delimiter --):", +" -as mkisofs [-help|-version|-o|-R|-r|-J|-V|-P|-f|-m|-exclude-list|", +" -no-pad|-M|-C|-graft-points|-path-list|pathspecs|-z|", +" -no-emul-boot|-b|-c|-boot-info-table|-boot-load-size|-G]", +" Perform some mkisofs gestures, understand pathspecs as mkisofs", +" does. Commit happens outside emulation at usual occasions.", +" -as cdrecord [-help|-v|dev=|speed=|blank=|fs=|-eject|-atip|padsize=|-multi]", +" path|-", +" Perform some cdrecord gestures, eventually write at most one", +" data track to blank, appendable or overwriteable media.", +" -pacifier \"xorriso\"|\"cdrecord\"|\"mkisofs\"", +" Choose format of UPDATE pacifier during write operations.", +"", +"General options:", +" -help Print this text", +" -abort_on severity Set the threshhold for events to abort the program.", +" Useful severities: NEVER, ABORT, FATAL, FAILURE, SORRY, WARNING", +" -return_with severity exit_value Set the threshhold for events to return", +" at program end the given exit_value even if not aborted.", +" exit_value may be 0 or 32 to 63.", +" -report_about severity Set the threshhold for events to be reported.", +" Use -abort_on severities or: HINT, NOTE, UPDATE, DEBUG, ALL", +" -error_behavior \"image_loading\"|\"file_extraction\" behavior", +" Behavior \"best_effort\" is most endurant but may produce", +" results which are correct only on the first glimpse.", +" -dialog \"on\"|\"off\"|\"single_line\"", +" After all arguments are processed, enter dialog mode.", +" \"single_line\" does not support newline characters within", +" open quotation marks and no line continuation by trailing \\.", +" -page len width Prompt user after len output lines (0=no prompt).", +" width (default 80) can adjust line number computation", +" to the output terminal's line width.", +#ifdef Xorriso_with_readlinE +" -use_stdin Use raw standard input even if libreadline is available", +" -use_readline Use libreadline for dialog if available", +" -history text Copy text into libreadline history. This command", +" itself is not copied to the history list.", +#endif /* Xorriso_with_readlinE */ +" -backslash_codes \"on\"|\"off\"|", +" \"in_double_quotes\"|\"in_quotes\"|\"with_quoted_input\"", +" [:\"with_program_arguments\"][:\"encode_output\"]", +" Disable or enable interpretation of \\a \\b \\e \\f \\n \\r \\t \\v", +" \\\\ \\NNN \\xNN \\cC in input or program arguments.", +" -pkt_output \"on\"|\"off\" Direct output to stdout and prefix each line", +" by a short header which tells channel id and a mode number.", +" Each such output packet is finalized by a newline.", +" Channel ids are 'R:' for result lines, 'I:' for notes", +" and error messages, 'M:' for -mark texts. Bit 0 of the", +" mode number tells whether the newline is also part of the", +" packet payload. Example of a info message with newline:", +" I:1: enter option text :", +" -pkt_output:on is intended for use by frontend programs.", +" -logfile channel fileaddress Copy output of a channel to the given file.", +" channel may be 'R','I','M' as with -pkt_output or '.'", +" for the consolidated -pkt_output stream.", +" -mark text If text is not empty it will get put out each time an", +" option is completed.", +" -temp_mem_limit number[\"k\"|\"m\"]", +" Set the maximum size for pattern expansion. (Default is 16m)", +" -prog text Use text as this program's name in subsequent messages", +" -prog_help text Use text as this program's name and perform -help", +" -status mode|filter Report the current settings of persistent options.", +" Modes:", +" short... print only important or altered options", +" long ... print options even if they have default settings", +" long_history like long plus -history: lines", +" Filters begin with '-' and are compared literally against the", +" output lines of -status long_history. A line is put out only", +" if its start matches the filter.", +" -status_history_max number Maximum number of history lines to be reported", +" with -status:long_history", +" -options_from_file fileaddress", +" Reads lines from the given file and executes them as program", +" options.", +" -no_rc Only if used as first command line argument this option", +" prevents reading and interpretation of startup files.", +" -print text", +" Print a text to result channel.", +" -prompt text", +" Wait for Enter key resp. for a line of input at stdin.", +" -errfile_log mode path|channel", +" Log disk paths of files involved in problem events.", +" -session_log path", +" Set path of a file where a log record gets appended after", +" each session. Form: timestamp start_lba size volume-id", +" -scsi_log \"on\"|\"off\"", +" Enable or disable logging of SCSI commands to stderr.", +" # any text Is ignored. In dialog mode the input line will be stored in", +" the eventual readline history, nevertheless.", +" -version Tell program and version number", +" -end End program. Commit eventual pending changes.", +" -rollback_end", +" End program. Discard pending changes.", +"", +"", +"Option -page causes a user prompt after the given number of result lines.", +"Empty input resumes output until the next prompt. Other input may be:", +" @ suppresses paging until the current action is done", +" @@ suppresses further result output but continues the action", +" @@@ aborts the current action", +" other aborts the current action and executes input as new", +" option", +"", + +#endif /* ! Xorriso_no_helP */ + +"@ENDE_OF_HELPTEXT_(HOPEFULLY_UNIQUELY_SILLY_TEXT)@" + }; + + char *tpt= NULL; + int i,pass; + + Xorriso_restxt(xorriso,"\n"); + sprintf(xorriso->result_line,"usage: %s [settings|actions]\n", + xorriso->progname); + Xorriso_result(xorriso,0); + Xorriso_restxt(xorriso,"\n"); + for(pass=0;pass<1;pass++) { + for(i=0;1;i++) { + if(pass==0) + tpt= text[i]; + + if(strcmp(tpt,"@ENDE_OF_HELPTEXT_(HOPEFULLY_UNIQUELY_SILLY_TEXT)@")==0) + break; + sprintf(xorriso->result_line,"%s\n",tpt); + Xorriso_result(xorriso,0); + if(xorriso->request_to_abort) + return(1); + } + } + Xorriso_restxt(xorriso,"\n"); + return(1); +} + + +/* Option -history */ +int Xorriso_option_history(struct XorrisO *xorriso, char *line, int flag) +{ + Xorriso_dialog_input(xorriso,line,strlen(line)+1,2); + return(1); +} + diff --git a/xorriso/opts_i_o.c b/xorriso/opts_i_o.c new file mode 100644 index 00000000..52a60a07 --- /dev/null +++ b/xorriso/opts_i_o.c @@ -0,0 +1,1179 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains the implementation of options as mentioned in man page + or info file derived from xorriso.texi. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xorriso.h" +#include "xorriso_private.h" +#include "xorrisoburn.h" + + +/* Option -iso_rr_pattern "on"|"ls"|"off" */ +int Xorriso_option_iso_rr_pattern(struct XorrisO *xorriso, char *mode,int flag) +{ + if(strcmp(mode, "off")==0) + xorriso->do_iso_rr_pattern= 0; + else if(strcmp(mode, "on")==0) + xorriso->do_iso_rr_pattern= 1; + else if(strcmp(mode, "ls")==0) + xorriso->do_iso_rr_pattern= 2; + else { + sprintf(xorriso->info_text, "-iso_rr_pattern: unknown mode '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + return(1); +} + + +/* Option -joliet "on"|"off" */ +int Xorriso_option_joliet(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode, "off")==0) + xorriso->do_joliet= 0; + else if(strcmp(mode, "on")==0) + xorriso->do_joliet= 1; + else { + sprintf(xorriso->info_text, "-joliet: unknown mode '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + return(1); +} + + +/* Option -list_delimiter */ +int Xorriso_option_list_delimiter(struct XorrisO *xorriso, char *text, + int flag) +{ + int ret, argc; + char **argv= NULL; + + if(text[0] == 0) { + sprintf(xorriso->info_text, + "-list_delimiter: New delimiter text is empty"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if(strlen(text) > 80) { + sprintf(xorriso->info_text, + "-list_delimiter: New delimiter text is too long"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= Sfile_make_argv(xorriso->progname, text, &argc, &argv, 4); + if(ret > 0) { + if(argc > 2) { + sprintf(xorriso->info_text, + "-list_delimiter: New delimiter text contains more than one word"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } + Sfile_make_argv(xorriso->progname, text, &argc, &argv, 2); + if(argc > 2) + return(0); + } + if(strchr(text, '"') != NULL || strchr(text, '\'') != NULL) { + sprintf(xorriso->info_text, + "-list_delimiter: New delimiter text contains quotation marks"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + strcpy(xorriso->list_delimiter, text); + return(1); +} + + +/* Option -list_formats */ +int Xorriso_option_list_formats(struct XorrisO *xorriso, int flag) +{ + int ret; + + ret= Xorriso_list_formats(xorriso, 0); + return(ret); +} + + +/* Option -list_profiles */ +int Xorriso_option_list_profiles(struct XorrisO *xorriso, char *which, + int flag) +{ + int ret; + int mode= 0; + + if(strncmp(which,"in",2)==0) + mode|= 1; + else if(strncmp(which,"out",3)==0) + mode|= 2; + else + mode|= 3; + if(mode & 1) { + ret= Xorriso_toc(xorriso, 1 | 16 | 32); + if(ret > 0) + Xorriso_list_profiles(xorriso, 0); + } + if((mode & 2) && xorriso->in_drive_handle != xorriso->out_drive_handle) { + ret= Xorriso_toc(xorriso, 1 | 2 | 16 | 32); + if(ret > 0) + Xorriso_list_profiles(xorriso, 2); + } + return(1); +} + + +/* Option -load session|track|sbsector value */ +/* @param flag bit0= with adr_mode sbsector: adr_value is possibly 16 too high + @return <=0 error , 1 success, 2 revoked by -reassure +*/ +int Xorriso_option_load(struct XorrisO *xorriso, char *adr_mode, + char *adr_value, int flag) +{ + int ret; + + if(xorriso->volset_change_pending) { + sprintf(xorriso->info_text, + "-load: Image changes pending. -commit or -rollback first"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= Xorriso_reassure(xorriso, "-load", "loads an alternative image", 0); + if(ret<=0) + return(2); + ret= Xorriso_decode_load_adr(xorriso, "-load", adr_mode, adr_value, + &(xorriso->image_start_mode), + xorriso->image_start_value, flag & 1); + if(ret <= 0) + return(ret); + xorriso->image_start_mode|= (1<<30); /* enable non-default msc1 processing */ + if(strlen(xorriso->indev)>0) { + ret= Xorriso_option_rollback(xorriso, 1); /* Load image, no -reassure */ + if(ret<=0) + return(ret); + } + return(1); +} + + +/* Option -logfile */ +int Xorriso_option_logfile(struct XorrisO *xorriso, char *channel, + char *fileadr, int flag) +{ + int hflag,channel_no= 0, ret; + + if(channel[0]==0) { +logfile_wrong_form:; + sprintf(xorriso->info_text,"Wrong form. Correct would be: -logfile \".\"|\"R\"|\"I\"|\"M\" file_address"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + hflag= 2; + if(channel[0]=='R') + channel_no= 1; + else if(channel[0]=='I') + channel_no= 2; + else if(channel[0]=='M') + channel_no= 3; + else if(channel[0]=='.') + hflag= 4; + else + goto logfile_wrong_form; + if(strcmp(fileadr,"-")==0 || fileadr[0]==0) + hflag|= (1<<15); + xorriso->logfile[channel_no][0]= 0; + ret= Xorriso_write_to_channel(xorriso, fileadr, channel_no, hflag); + if(ret<=0) { + sprintf(xorriso->info_text, "Cannot open logfile: %s", fileadr); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + } else if(!(hflag&(1<<15))) + if(Sfile_str(xorriso->logfile[channel_no], fileadr, 0)<=0) + return(-1); + return(ret>0); +} + + +/* Options -ls alias -lsi and -lsl alias -lsli + and -lsd alias -lsdi and -lsdl alias -lsdli + and -du alias -dui and -dus alias -dusi + @param flag bit0= long format (-lsl , -du) + bit1= do not expand patterns but use literally + bit2= du rather than ls + bit3= list directories as themselves (ls -d) +*/ +int Xorriso_option_lsi(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int ret, end_idx, filec= 0, nump, i; + char **filev= NULL, **patterns= NULL; + off_t mem= 0; + struct stat stbuf; + + end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); + if(xorriso->do_iso_rr_pattern==0) + flag|= 2; + + nump= end_idx - *idx; + if((flag&2) && nump>0 ) { + ; + } else if(nump <= 0) { + if(Xorriso_iso_lstat(xorriso, xorriso->wdi, &stbuf, 0)<0) { + sprintf(xorriso->info_text, + "Current -cd path does not yet exist in the ISO image"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + {ret= 0; goto ex;} + } + if(!S_ISDIR(stbuf.st_mode)) { + sprintf(xorriso->info_text, + "Current -cd meanwhile points to a non-directory in ISO image"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + {ret= 0; goto ex;} + } + patterns= calloc(1, sizeof(char *)); + if(patterns == NULL) { +no_memory:; + sprintf(xorriso->info_text, + "Cannot allocate enough memory for pattern expansion"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + {ret= -1; goto ex;} + } + nump= 1; + if(flag&8) + patterns[0]= "."; + else + patterns[0]= "*"; + flag&= ~2; + } else { + patterns= calloc(nump, sizeof(char *)); + if(patterns==NULL) + goto no_memory; + for(i= 0; iino_behavior & 1)) { + ret= Xorriso_make_hln_array(xorriso, 0); /* for stbuf.st_nlink */ + if(ret < 0) + return(ret); + } + if(flag&2) { + ret= Xorriso_ls_filev(xorriso, xorriso->wdi, nump, argv + (*idx), mem, + flag&(1|4|8)); + } else if(nump==1 && strcmp(patterns[0],"*")==0 && !(flag&4)){ + /* save temporary memory by calling simpler function */ + ret= Xorriso_ls(xorriso, (flag&1)|4); + } else { + ret= Xorriso_expand_pattern(xorriso, nump, patterns, 0, &filec, &filev, + &mem, 0); + if(ret<=0) + {ret= 0; goto ex;} + ret= Xorriso_ls_filev(xorriso, xorriso->wdi, filec, filev, mem, + flag&(1|4|8)); + } + if(ret<=0) + {ret= 0; goto ex;} + + ret= 1; +ex:; + if(patterns!=NULL) + free((char *) patterns); + Sfile_destroy_argv(&filec, &filev, 0); + (*idx)= end_idx; + return(ret); +} + + +/* Options -lsx, -lslx, -lsdx , -lsdlx , -dux , -dusx + @param flag bit0= long format (-lslx , -dux) + bit1= do not expand patterns but use literally + bit2= du rather than ls + bit3= list directories as themselves (ls -d) +*/ +int Xorriso_option_lsx(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int ret, end_idx, filec= 0, nump, i; + char **filev= NULL, **patterns= NULL; + off_t mem= 0; + + end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1|2); + if(xorriso->do_disk_pattern==0) + flag|= 2; + + nump= end_idx - *idx; + if((flag&2) && nump>0) { + ; + } else if(nump <= 0) { + patterns= calloc(1, sizeof(char *)); + if(patterns == NULL) { +no_memory:; + sprintf(xorriso->info_text, + "Cannot allocate enough memory for pattern expansion"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + {ret= -1; goto ex;} + } + nump= 1; + if(flag&8) + patterns[0]= "."; + else + patterns[0]= "*"; + flag&= ~2; + } else { + patterns= calloc(nump, sizeof(char *)); + if(patterns==NULL) + goto no_memory; + for(i= 0; iwdx, + nump, argv + (*idx), mem, flag&(1|4|8)); + +#ifdef Not_yeT + } else if(nump==1 && strcmp(patterns[0],"*")==0 && !(flag&4)){ + /* save temporary memory by calling simpler function */ + ret= Xorriso_ls(xorriso, (flag&1)|4); +#endif + + } else { + ret= Xorriso_expand_disk_pattern(xorriso, nump, patterns, 0, &filec, &filev, + &mem, 0); + if(ret<=0) + {ret= 0; goto ex;} + ret= Xorriso_lsx_filev(xorriso, xorriso->wdx, filec, filev, mem, + flag&(1|4|8)); + } + if(ret<=0) + {ret= 0; goto ex;} + + ret= 1; +ex:; + if(patterns!=NULL) + free((char *) patterns); + Sfile_destroy_argv(&filec, &filev, 0); + (*idx)= end_idx; + return(ret); +} + + +/* Option -map , -map_single */ +/* @param flag bit0=do not report the added item + bit1=do not reset pacifier, no final pacifier message + bit5=eventually do not insert directory tree +*/ +int Xorriso_option_map(struct XorrisO *xorriso, char *disk_path, + char *iso_path, int flag) +{ + int ret; + char eff_origin[SfileadrL], eff_dest[SfileadrL], *ipth; + + if(!(flag&2)) + Xorriso_pacifier_reset(xorriso, 0); + + ipth= iso_path; + if(ipth[0]==0) + ipth= disk_path; + if(disk_path[0]==0) { + sprintf(xorriso->info_text, "-map: Empty disk_path given"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 1); + return(0); + } + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_origin, + 2|4); + if(ret<=0) + return(ret); + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, ipth, eff_dest, 2); + if(ret<=0) + return(ret); + ret= Xorriso_graft_in(xorriso, NULL, eff_origin, eff_dest, + (off_t) 0, (off_t) 0, 2|(flag&32)); + if(!(flag&2)) + Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count, + xorriso->pacifier_total, "", 1); + if(ret<=0) + return(ret); + + if(!(flag&1)) { + sprintf(xorriso->info_text, "Added to ISO image: %s '%s'='%s'\n", + (ret>1 ? "directory" : "file"), (eff_dest[0] ? eff_dest : "/"), + eff_origin); + Xorriso_info(xorriso,0); + } + return(1); +} + + +/* Options -map_l , -compare_l , -update_l , -extract_l */ +/* @param flag bit4= do not establish and dispose xorriso->di_array + for update_l + bit8-11= mode 0= -map_l + 1= -compare_l + 2= -update_l + 3= -extract_l +*/ +int Xorriso_option_map_l(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int ret, end_idx, optc= 0, was_failure= 1, i, fret, mode; + int ns_flag= 2|4, nt_flag= 2, opt_args_flag= 2, made_di_array= 0; + char source_prefix[SfileadrL], target_prefix[SfileadrL], *cmd, **optv= NULL; + char eff_source[SfileadrL], eff_target[SfileadrL], *source_pt, *s_wd, *t_wd; + char sfe[5*SfileadrL], **eff_src_array= NULL, **eff_tgt_array= NULL; + + cmd= "-map_l"; + s_wd= xorriso->wdx; + t_wd= xorriso->wdi; + Xorriso_pacifier_reset(xorriso, 0); + mode= (flag>>8) & 15; + + if(mode==1) + cmd= "-compare_l"; + else if(mode==2) + cmd= "-update_l"; + else if(mode==3) { + cmd= "-extract_l"; + ns_flag= 2; + s_wd= xorriso->wdi; + nt_flag= 2|4; + t_wd= xorriso->wdx; + opt_args_flag= 0; + } + + end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1|2); + if(end_idx - (*idx) < 3) { + sprintf(xorriso->info_text, "%s: Not enough arguments given (%d < 3)", cmd, + end_idx - (*idx)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 1); + ret= 0; goto ex; + } + ret= Xorriso_normalize_img_path(xorriso, s_wd, argv[*idx], + source_prefix, ns_flag | 64); + if(ret<=0) + goto ex; + ret= Xorriso_normalize_img_path(xorriso, t_wd, argv[(*idx)+1], + target_prefix, nt_flag); + if(ret<=0) + goto ex; + ret= Xorriso_opt_args(xorriso, cmd, argc, argv, (*idx)+2, &end_idx, + &optc, &optv, opt_args_flag); + if(ret<=0) + goto ex; + + + if(mode == 3 && + (xorriso->do_restore_sort_lba || !(xorriso->ino_behavior & 4))) { + eff_src_array= calloc(optc, sizeof(char *)); + eff_tgt_array= calloc(optc, sizeof(char *)); + if(eff_src_array == NULL || eff_tgt_array == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; goto ex; + } + for(i= 0; i < optc; i++) + eff_src_array[i]= eff_tgt_array[i]= NULL; + } + if(mode == 2 && !((xorriso->ino_behavior & 2) || (flag & 16) || + xorriso->di_array != NULL)) { + /* Create all-image node array sorted by isofs.di */ + ret= Xorriso_make_di_array(xorriso, 0); + if(ret <= 0) + goto ex; + made_di_array= 1; + } + + for(i= 0; iinfo_text, + "%s: disk_path %s does not begin with disk_prefix ", cmd, + Text_shellsafe(eff_source, sfe, 0)); + Text_shellsafe(source_prefix, + xorriso->info_text+strlen(xorriso->info_text), 0); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 1); + ret= 0; goto ex; + } + source_pt+= strlen(source_prefix); + } + strcat(eff_target, source_pt); + + if(mode==0) + ret= Xorriso_option_map(xorriso, eff_source, eff_target, 2); + else if(mode==1) + ret= Xorriso_option_compare(xorriso, eff_source, eff_target, 2|8); + else if(mode==2) + ret= Xorriso_option_update(xorriso, eff_source, eff_target, 2 | 8 | 16); + else if(mode==3) { + if(eff_src_array != NULL) { + eff_src_array[i]= strdup(eff_source); + eff_tgt_array[i]= strdup(eff_target); + if(eff_src_array[i] == NULL || eff_tgt_array[i] == NULL) { + Xorriso_no_malloc_memory(xorriso, &(eff_src_array[i]), 0); + ret= -1; goto ex; + } + } else { + ret= Xorriso_option_extract(xorriso, eff_source, eff_target, 2 | 4); + } + } + + if(ret>0 && !xorriso->request_to_abort) + continue; /* regular bottom of loop */ + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 2); + if(fret>=0) + continue; + goto ex; + } + + ret= 1; + if(mode == 3 && eff_src_array != NULL) { + ret= Xorriso_lst_append_binary(&(xorriso->node_disk_prefixes), + target_prefix, strlen(target_prefix) + 1, 0); + if(ret <= 0) + goto ex; + ret= Xorriso_lst_append_binary(&(xorriso->node_img_prefixes), + source_prefix, strlen(source_prefix) + 1, 0); + if(ret <= 0) + goto ex; + ret= Xorriso_restore_sorted(xorriso, optc, eff_src_array, eff_tgt_array, 0); + } + if(mode==0) + Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count, + xorriso->pacifier_total, "", 1); + else if(mode==1 || mode==2) + Xorriso_pacifier_callback(xorriso, "content bytes read", + xorriso->pacifier_count, 0, "", 1); + else if(mode==3) + Xorriso_pacifier_callback(xorriso, "files restored",xorriso->pacifier_count, + xorriso->pacifier_total, "", 1|4); +ex:; + Xorriso_destroy_node_array(xorriso, 0); + i= optc; + Sfile_destroy_argv(&i, &eff_src_array, 0); + i= optc; + Sfile_destroy_argv(&i, &eff_tgt_array, 0); + (*idx)= end_idx; + Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, &optc, &optv, 256); + if(ret<=0) + return(ret); + return(!was_failure); +} + + +/* Option -mark */ +int Xorriso_option_mark(struct XorrisO *xorriso, char *mark, int flag) +{ + if(mark[0]==0) + xorriso->mark_text[0]= 0; + else + strncpy(xorriso->mark_text,mark,sizeof(xorriso->mark_text)-1); + xorriso->mark_text[sizeof(xorriso->mark_text)-1]= 0; + return(1); +} + + +/* Option -md5 "on"|"all"|"off" */ +int Xorriso_option_md5(struct XorrisO *xorriso, char *mode, int flag) +{ + char *npt, *cpt; + int l; + + npt= cpt= mode; + for(; npt!=NULL; cpt= npt+1) { + npt= strchr(cpt,':'); + if(npt==NULL) + l= strlen(cpt); + else + l= npt-cpt; + if(l == 0) + continue; + if(l == 3 && strncmp(cpt, "off", l) == 0) + xorriso->do_md5&= ~31; + else if(l == 2 && strncmp(cpt, "on", l) == 0) + xorriso->do_md5= (xorriso->do_md5 & ~31) | 7 | 16; + else if(l == 3 && strncmp(cpt, "all", l) == 0) + xorriso->do_md5|= 31; + else if(l == 18 && strncmp(cpt, "stability_check_on", l) == 0) + xorriso->do_md5|= 8; + else if(l == 19 && strncmp(cpt, "stability_check_off", l) == 0) + xorriso->do_md5&= ~8; + else { + sprintf(xorriso->info_text, "-md5: unknown mode "); + Text_shellsafe(cpt, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + return(1); +} + + +/* Option -mkdir alias -mkdiri */ +int Xorriso_option_mkdiri(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int i, end_idx, ret, was_failure= 0, fret; + + end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 0); + + for(i= *idx; i0 && !xorriso->request_to_abort) + continue; /* regular bottom of loop */ + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + goto ex; + } + ret= 1; +ex:; + (*idx)= end_idx; + if(ret<=0) + return(ret); + return(!was_failure); +} + + +/* Options -mount , -mount_cmd , -session_string */ +/* @param bit0= -mount_cmd: print mount command to result channel rather + than performing it + bit1= perform -session_string rather than -mount_cmd +*/ +int Xorriso_option_mount(struct XorrisO *xorriso, char *dev, char *adr_mode, + char *adr, char *cmd, int flag) +{ + int ret, entity_code= 0, m_flag; + char entity_id[81], *mnt; + + if(flag & 1) + mnt= "-mount_cmd"; + else if(flag & 2) + mnt= "-session_string"; + else { + mnt= "-mount"; + if(xorriso->allow_restore <= 0) { + sprintf(xorriso->info_text, + "-mount: image-to-disk features are not enabled by option -osirrox"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if(xorriso->volset_change_pending) { + sprintf(xorriso->info_text, + "%s: Image changes pending. -commit or -rollback first", mnt); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + ret= Xorriso_decode_load_adr(xorriso, mnt, adr_mode, adr, + &entity_code, entity_id, 0); + if(ret <= 0) + return(ret); + if(flag & 2) + m_flag= 1 | 4; + else + m_flag= (flag & 1) | 2; + ret= Xorriso_mount(xorriso, dev, entity_code, entity_id, cmd, m_flag); + return(ret); +} + + +/* Option -mount_opts option[:...] */ +int Xorriso_option_mount_opts(struct XorrisO *xorriso, char *mode, int flag) +{ + int was, l; + char *cpt, *npt; + + was= xorriso->mount_opts_flag; + npt= cpt= mode; + for(cpt= mode; npt!=NULL; cpt= npt+1) { + npt= strchr(cpt,':'); + if(npt==NULL) + l= strlen(cpt); + else + l= npt-cpt; + if(l==0) + goto unknown_mode; + if(strncmp(cpt, "shared", l)==0) { + xorriso->mount_opts_flag|= 1; + } else if(strncmp(cpt, "exclusive", l)==0) { + xorriso->mount_opts_flag&= ~1; + } else { +unknown_mode:; + if(linfo_text, "-mount_opts: unknown option '%s'", cpt); + else + sprintf(xorriso->info_text, "-mount_opts: oversized parameter (%d)",l); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + xorriso->mount_opts_flag= was; + return(0); + } + } + return(1); +} + + +/* Option -mv alias -mvi */ +int Xorriso_option_mvi(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int i, end_idx_dummy, ret, is_dir= 0, was_failure= 0, fret; + char sfe[5*SfileadrL], sfe2[5*SfileadrL]; + char eff_origin[SfileadrL], eff_dest[SfileadrL], dest_dir[SfileadrL]; + char leafname[SfileadrL]; + int optc= 0; + char **optv= NULL; + + ret= Xorriso_cpmv_args(xorriso, "-mvi", argc, argv, idx, + &optc, &optv, eff_dest, 0); + if(ret<=0) + goto ex; + if(ret==2) { + is_dir= 1; + strcpy(dest_dir, eff_dest); + } + /* Perform movements */ + for(i= 0; iwdi,optv[i],eff_origin,0); + if(ret<=0 || xorriso->request_to_abort) + goto problem_handler; + if(is_dir) { + ret= Sfile_leafname(eff_origin, leafname, 0); + if(ret<=0) + goto problem_handler; + strcpy(eff_dest, dest_dir); + ret= Sfile_add_to_path(eff_dest, leafname, 0); + if(ret<=0) { + sprintf(xorriso->info_text, "Effective path gets much too long (%d)", + (int) (strlen(eff_dest)+strlen(leafname)+1)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + goto problem_handler; + } + } + ret= Xorriso_rename(xorriso, NULL, eff_origin, eff_dest, 0); + if(ret<=0 || xorriso->request_to_abort) + goto problem_handler; + sprintf(xorriso->info_text, "Renamed in ISO image: %s to %s\n", + Text_shellsafe(eff_origin,sfe,0),Text_shellsafe(eff_dest,sfe2,0)); + Xorriso_info(xorriso, 0); + + continue; /* regular bottom of loop */ +problem_handler:; + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + goto ex; + } + ret= !was_failure; +ex:; + Xorriso_opt_args(xorriso, "-mvi", + argc, argv, *idx, &end_idx_dummy, &optc, &optv, 256); + return(ret); +} + + +/* Option -no_rc */ +int Xorriso_option_no_rc(struct XorrisO *xorriso, int flag) +{ + xorriso->no_rc= 1; + return(1); +} + + +/* Option -not_leaf */ +int Xorriso_option_not_leaf(struct XorrisO *xorriso, char *pattern, int flag) +{ + regex_t re; + char regexpr[2*SfileadrL+2], sfe[5*SfileadrL]; + int ret= 0; + + if(pattern[0]==0) + {ret= 0; goto cannot_add;} + Xorriso__bourne_to_reg(pattern, regexpr, 0); + if(regcomp(&re, regexpr, 0)!=0) + {ret= 0; goto cannot_add;} + ret= Exclusions_add_not_leafs(xorriso->disk_exclusions, pattern, &re, 0); + if(ret<=0) { +cannot_add:; + sprintf(xorriso->info_text,"Cannot add pattern: -not_leaf %s", + Text_shellsafe(pattern, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(ret); + } + return(1); +} + + +/* Option -not_list , -quoted_not_list */ +/* @param flag bit0= -quoted_not_list */ +int Xorriso_option_not_list(struct XorrisO *xorriso, char *adr, int flag) +{ + int ret, linecount= 0, insertcount= 0, null= 0, argc= 0, i; + FILE *fp= NULL; + char sfe[5*SfileadrL], **argv= NULL; + + Xorriso_pacifier_reset(xorriso, 0); + if(adr[0]==0) { + sprintf(xorriso->info_text, "Empty file name given with %s", + (flag & 1) ? "-quoted_not_list" : "-not_list"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= Xorriso_afile_fopen(xorriso, adr, "rb", &fp, 0); + if(ret <= 0) + return(0); + while(1) { + ret= Xorriso_read_lines(xorriso, fp, &linecount, &argc, &argv, + 4 | (flag & 1) ); + if(ret <= 0) + goto ex; + if(ret == 2) + break; + for(i= 0; i < argc; i++) { + if(argv[i][0] == 0) + continue; + if(strchr(argv[i], '/')!=NULL) { + null= 0; + ret= Xorriso_option_not_paths(xorriso, 1, argv + i, &null, 0); + } else + ret= Xorriso_option_not_leaf(xorriso, argv[i], 0); + if(ret<=0) + goto ex; + insertcount++; + } + } + ret= 1; +ex:; + if(fp != NULL && fp != stdin) + fclose(fp); + Xorriso_read_lines(xorriso, fp, &linecount, &argc, &argv, 2); + if(ret<=0) { + sprintf(xorriso->info_text, "Aborted reading of file %s in line number %d", + Text_shellsafe(adr, sfe, 0), linecount); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } + sprintf(xorriso->info_text, "Added %d exclusion list items from file %s\n", + insertcount, Text_shellsafe(adr, sfe, 0)); + Xorriso_info(xorriso,0); + return(ret); +} + + +/* Option -not_mgt */ +int Xorriso_option_not_mgt(struct XorrisO *xorriso, char *setting, int flag) +{ + int ret; + char what_data[SfileadrL], *what, *what_next; + + if(Sfile_str(what_data, setting, 0)<=0) { + sprintf(xorriso->info_text, + "-not_mgt: setting string is much too long (%d)", + (int) strlen(setting)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + for(what= what_data; what!=NULL; what= what_next) { + what_next= strchr(what, ':'); + if(what_next!=NULL) { + *what_next= 0; + what_next++; + } + + if(strcmp(what, "reset")==0 || strcmp(what, "erase")==0) { + if(strcmp(what, "reset")==0) + xorriso->disk_excl_mode= 1; + Exclusions_destroy(&(xorriso->disk_exclusions), 0); + ret= Exclusions_new(&(xorriso->disk_exclusions), 0); + if(ret<=0) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + return(ret); + } + } else if(strcmp(what, "on")==0) { + xorriso->disk_excl_mode|= 1; + } else if(strcmp(what, "off")==0) { + xorriso->disk_excl_mode&= ~1; + } else if(strcmp(what, "param_on")==0) { + xorriso->disk_excl_mode|= 2; + } else if(strcmp(what, "param_off")==0) { + xorriso->disk_excl_mode&= ~2; + } else if(strcmp(what, "subtree_on")==0) { + xorriso->disk_excl_mode|= 4; + } else if(strcmp(what, "subtree_off")==0) { + xorriso->disk_excl_mode&= ~4; + } else if(strcmp(what, "ignore_on")==0) { + xorriso->disk_excl_mode|= 8; + } else if(strcmp(what, "ignore_off")==0) { + xorriso->disk_excl_mode&= ~8; + } else { + sprintf(xorriso->info_text, "-not_mgt: unknown setting '%s'", what); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + return(1); +} + + +/* Option -not_paths */ +int Xorriso_option_not_paths(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int ret, end_idx, num_descr, dummy, optc= 0, i; + char **descr= NULL, **optv= NULL, sfe[5*SfileadrL], eff_path[SfileadrL]; + + + end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, + (xorriso->do_disk_pattern==1) | 2); + if(end_idx<=0) + return(end_idx); + num_descr= end_idx - *idx; + if(num_descr<=0) + {ret= 1; goto ex;} + + /* produce absolute patterns */ + descr= TSOB_FELD(char *, num_descr); + if(descr==NULL) { +no_memory:; + Xorriso_no_pattern_memory(xorriso, sizeof(char *) * (off_t) num_descr, 0); + ret= -1; goto ex; + } + for(i= 0; iwdx, argv[i+*idx], + eff_path, 2|4); + if(ret<=0) + goto ex; + descr[i]= strdup(eff_path); + if(descr[i]==NULL) + goto no_memory; + } + + ret= Xorriso_opt_args(xorriso, "-not_paths", + num_descr, descr, 0, &dummy, &optc, &optv, 2); + if(ret<=0) + goto ex; + ret= Exclusions_add_not_paths(xorriso->disk_exclusions, + num_descr, descr, optc, optv, 0); + if(ret<=0) { + sprintf(xorriso->info_text,"Cannot add path list: -not_paths %s%s %s", + Text_shellsafe(argv[*idx], sfe, 0), (num_descr>1 ? " ..." : ""), + xorriso->list_delimiter); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } +ex:; + (*idx)= end_idx; + Xorriso_opt_args(xorriso, "-not_paths", + num_descr, descr, 0, &dummy, &optc, &optv, 256); + if(descr!=NULL) { + for(i= 0; iinfo_text,"Empty file name given with -options_from_file"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + Text_shellsafe(adr,shellsafe,0); + if(xorriso->is_dialog) { + sprintf(xorriso->info_text,"+ performing command lines from file %s :\n", + shellsafe); + Xorriso_info(xorriso,1); + } + ret= Xorriso_afile_fopen(xorriso, adr, "rb", &fp, 0); + if(ret <= 0) + return(0); + while(1) { + ret= Xorriso_read_lines(xorriso, fp, &linecount, &linec, &linev, 1 | 8); + if(ret <= 0) + goto ex; /* no problem_handler because there is no sense in going on */ + if(ret == 2) + break; + line= linev[0]; + if(line[0]==0 || line[0]=='#') + continue; + + if(flag&1) { + ret= Sfile_make_argv(xorriso->progname, line, &argc, &argv, + 4 | 8 | ((xorriso->bsl_interpretation & 3) << 5)); + if(ret<=0) + goto problem_handler; + ret= Xorriso_prescan_args(xorriso,argc,argv,1); + if(ret==0) + {ret= 3; goto ex;} + if(ret<0) + goto problem_handler; + } else { + if(xorriso->is_dialog) { + sprintf(xorriso->info_text,"+ %d: %s\n",linecount,line); + Xorriso_info(xorriso,1); + } + ret= Xorriso_execute_option(xorriso,line,1|(1<<16)); + if(ret==3) + goto ex; + if(ret<=0) + goto problem_handler; + } + + continue; /* regular bottom of loop */ +problem_handler:; + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1); + if(fret>=0) + continue; + goto ex; + } + ret= 1; +ex:; + Sfile_make_argv("", "", &argc, &argv, 2); /* release memory */ + Xorriso_read_lines(xorriso, fp, &linecount, &linec, &linev, 2); + Xorriso_reset_counters(xorriso,0); + if(fp != NULL && fp != stdin) + fclose(fp); + if(ret<=0) { + sprintf(xorriso->info_text, + "error triggered by line %d of file:\n %s\n", + linecount,shellsafe); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 1); + } + if(ret!=1) + return(ret); + return(!was_failure); +} + + +/* Option -osirrox "on"|"off" */ +int Xorriso_option_osirrox(struct XorrisO *xorriso, char *mode, int flag) +{ + int l, allow_restore; + char *npt, *cpt; + + allow_restore= xorriso->allow_restore; + + npt= cpt= mode; + for(cpt= mode; npt!=NULL; cpt= npt+1) { + npt= strchr(cpt,':'); + if(npt==NULL) + l= strlen(cpt); + else + l= npt-cpt; + if(l==0 && mode[0]!=0) + goto unknown_mode; + if(strncmp(cpt, "off", l)==0) + allow_restore= 0; + else if(strncmp(cpt, "banned", l)==0) + allow_restore= -1; + else if(strncmp(cpt, "device_files", l)==0) + allow_restore= 2; + else if(strncmp(cpt, "on", l)==0 || mode[0]==0) + allow_restore= 1; + else if(strncmp(cpt, "concat_split_on", l)==0) + xorriso->do_concat_split= 1; + else if(strncmp(cpt, "concat_split_off", l)==0) + xorriso->do_concat_split= 0; + else if(strncmp(cpt, "auto_chmod_on", l)==0) + xorriso->do_auto_chmod= 1; + else if(strncmp(cpt, "auto_chmod_off", l)==0) + xorriso->do_auto_chmod= 0; + else if(strncmp(cpt, "sort_lba_on", l)==0) + xorriso->do_restore_sort_lba= 1; + else if(strncmp(cpt, "sort_lba_off", l)==0) + xorriso->do_restore_sort_lba= 0; + else if(strncmp(cpt, "o_excl_off", l)==0) + xorriso->drives_exclusive= 0; + else if(strncmp(cpt, "o_excl_on", l)==0) + xorriso->drives_exclusive= 1; + else { +unknown_mode:; + sprintf(xorriso->info_text, "-osirrox: unknown mode '%s'", cpt); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + if(allow_restore > 0 && xorriso->allow_restore == -1) { + sprintf(xorriso->info_text, + "-osirrox: was already permanently disabled by setting 'banned'"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if(xorriso->allow_restore != -1) + xorriso->allow_restore= allow_restore; + sprintf(xorriso->info_text, + "Copying of file objects from ISO image to disk filesystem is: %s\n", + xorriso->allow_restore > 0 ? "Enabled" : "Disabled"); + Xorriso_info(xorriso, 0); + return(1); +} + + +/* Option -overwrite "on"|"nondir"|"off" */ +int Xorriso_option_overwrite(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode, "off")==0) + xorriso->do_overwrite= 0; + else if(strcmp(mode, "on")==0) + xorriso->do_overwrite= 1; + else if(strcmp(mode, "nondir")==0) + xorriso->do_overwrite= 2; + else { + sprintf(xorriso->info_text, "-overwrite: unknown mode '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + return(1); +} + + diff --git a/xorriso/opts_p_z.c b/xorriso/opts_p_z.c new file mode 100644 index 00000000..96fde228 --- /dev/null +++ b/xorriso/opts_p_z.c @@ -0,0 +1,1764 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains the implementation of options -p* to -z* as mentioned + in man page or info file derived from xorriso.texi. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "xorriso.h" +#include "xorriso_private.h" +#include "xorrisoburn.h" + + +/* Option -pacifier */ +int Xorriso_option_pacifier(struct XorrisO *xorriso, char *style, int flag) +{ + if(strcmp(style, "xorriso")==0 || strcmp(style, "default")==0) + xorriso->pacifier_style= 0; + else if(strcmp(style, "mkisofs")==0 || strcmp(style, "genisofs")==0 || + strcmp(style, "genisoimage")==0 || strcmp(style, "xorrisofs")==0) + xorriso->pacifier_style= 1; + else if(strcmp(style, "cdrecord")==0 || strcmp(style, "cdrskin")==0 || + strcmp(style, "wodim")==0 || strcmp(style, "xorrecord")==0) + xorriso->pacifier_style= 2; + else { + sprintf(xorriso->info_text, "-pacifier: unknown behavior code '%s'", style); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + return(1); +} + + +/* Option -padding */ +int Xorriso_option_padding(struct XorrisO *xorriso, char *size, int flag) +{ + double num; + + num= Scanf_io_size(size, 0); + if(num < 0 || num > 1024.0 * 1024.0 * 1024.0) { + sprintf(xorriso->info_text, "-padding: wrong size %.f (allowed: %.f - %.f)", + num, 0.0, 1024.0 * 1024.0 * 1024.0); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + xorriso->padding= num; + if(xorriso->padding/2048 != num/2048.0) + xorriso->padding++; + return(1); +} + + +/* Option -page */ +int Xorriso_option_page(struct XorrisO *xorriso, int len, int width, int flag) +{ + if(len<0 || width<=0) { + sprintf(xorriso->info_text, + "Improper numeric value of arguments of -page: %d %d", + len, width); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + xorriso->result_page_length= len; + xorriso->result_page_width= width; + return(1); +} + + +/* Option -paste_in */ +int Xorriso_option_paste_in(struct XorrisO *xorriso, char *iso_rr_path, + char *disk_path, char *start, char *count, int flag) +{ + int ret; + double num; + off_t startbyte, bytecount; + + num= Scanf_io_size(start, 0); + if(num<0 || num > 1.0e18) { /* 10^18 = 10^3 ^ 6 < 2^10 ^ 6 = 2^60 */ + sprintf(xorriso->info_text, + "-paste_in: startbyte address negative or much too large (%s)", start); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + startbyte= num; + num= Scanf_io_size(count, 0); + if(num<=0 || num > 1.0e18) { + sprintf(xorriso->info_text, + "-paste_in : bytecount zero, negative or much too large (%s)", count); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + bytecount= num; + sprintf(xorriso->info_text, "-paste_in from %s to %s, byte %.f to %.f", + disk_path, iso_rr_path, + (double) startbyte, (double) (startbyte+bytecount)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + + ret= Xorriso_paste_in(xorriso, disk_path, startbyte, bytecount, + iso_rr_path, 0); + return(ret); +} + + +/* Option -path_list , -quoted_path_list */ +/* @param flag bit0= -quoted_path_list */ +int Xorriso_option_path_list(struct XorrisO *xorriso, char *adr, int flag) +{ + int ret,linecount= 0, insertcount= 0, null= 0, was_failure= 0, fret= 0; + int was_ferror= 0, argc= 0, i; + FILE *fp= NULL; + char sfe[5*SfileadrL], **argv= NULL; + + Xorriso_pacifier_reset(xorriso, 0); + if(adr[0]==0) { + sprintf(xorriso->info_text,"Empty file name given with %s", + flag & 1 ? "-quoted_path_list" : "-path_list"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + return(0); + } + ret= Xorriso_afile_fopen(xorriso, adr, "rb", &fp, 0); + if(ret <= 0) + return(0); + while(1) { + ret= Xorriso_read_lines(xorriso, fp, &linecount, &argc, &argv, + 4 | (flag & 1) ); + if(ret <= 0) + goto ex; + if(ret == 2) + break; + for(i= 0; i < argc; i++) { + if(argv[i][0] == 0) + continue; + null= 0; + ret= Xorriso_option_add(xorriso, 1, argv + i, &null, 1|2); + if(ret<=0 || xorriso->request_to_abort) + goto problem_handler; + insertcount++; + } + + continue; /* regular bottom of loop */ +problem_handler:; + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + goto ex; + } + ret= 1; +ex:; + if(flag & 1) + Xorriso_read_lines(xorriso, fp, &linecount, &argc, &argv, 2); + + if(fp != NULL && fp != stdin) + fclose(fp); + Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count, + xorriso->pacifier_total, "", 1); + if(ret<=0) { + sprintf(xorriso->info_text, "Aborted reading of file %s in line number %d", + Text_shellsafe(adr, sfe, 0), linecount); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, + (fret==-2 ? "NOTE" : "FAILURE"), 0); + } else + ret= !was_ferror; + sprintf(xorriso->info_text, "Added %d items from file %s\n", + insertcount, Text_shellsafe(adr, sfe, 0)); + Xorriso_info(xorriso,0); + if(ret<=0) + return(ret); + return(!was_failure); +} + + +/* Option -pathspecs */ +int Xorriso_option_pathspecs(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode, "off")==0) + xorriso->allow_graft_points= 0; + else if(strcmp(mode, "on")==0) + xorriso->allow_graft_points= 1; + else { + sprintf(xorriso->info_text, "-pathspecs: unknown mode '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + return(1); +} + + +/* Option -pkt_output */ +int Xorriso_option_pkt_output(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode,"off")==0) + xorriso->packet_output= 0; + else + xorriso->packet_output= 1; + return(1); +} + + +/* Option -print */ +int Xorriso_option_print(struct XorrisO *xorriso, char *text, int flag) +{ + sprintf(xorriso->result_line,"%s\n",text); + Xorriso_result(xorriso,1); + return(1); +} + + +/* Option -print_size + @param flag bit0= report in mkisofs compatible form on real stdout +*/ +int Xorriso_option_print_size(struct XorrisO *xorriso, int flag) +{ + int ret, fd; + + if(!xorriso->volset_change_pending) { + sprintf(xorriso->info_text,"-print_size: No image modifications pending"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + sprintf(xorriso->result_line,"Image size : 0s\n"); + Xorriso_result(xorriso,0); + return(2); + } + ret= Xorriso_write_session(xorriso, 1); + if(ret<=0) { + sprintf(xorriso->info_text,"-print_size: Failed to set up virtual -commit"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + if(flag&1) { + sprintf(xorriso->result_line,"%d\n", ret); + fd= xorriso->dev_fd_1; + if(fd<0) + fd= 1; + write(fd, xorriso->result_line, strlen(xorriso->result_line)); + fsync(fd); + } else { + sprintf(xorriso->result_line,"Image size : %ds\n", ret); + Xorriso_result(xorriso,0); + } + return(1); +} + + +/* Option -prog */ +int Xorriso_option_prog(struct XorrisO *xorriso, char *name, int flag) +{ + if(strlen(name)>=sizeof(xorriso->progname)) { + sprintf(xorriso->info_text, + "Name too long with option -prog (%d > %d)", + (int) strlen(name), (int) sizeof(xorriso->progname)-1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + if(Sfile_str(xorriso->progname,name,0)<=0) + return(-1); + return(1); +} + + +/* Option -prog_help */ +int Xorriso_option_prog_help(struct XorrisO *xorriso, char *name, int flag) +{ + int ret; + + ret= Xorriso_option_prog(xorriso, name, 0); + if(ret<=0) + return(ret); + ret= Xorriso_option_help(xorriso, 0); + return(ret); +} + + +/* Option -prompt */ +int Xorriso_option_prompt(struct XorrisO *xorriso, char *text, int flag) +{ + int ret; + char line[80]; + + strncpy(xorriso->result_line,text,sizeof(xorriso->result_line)-1); + xorriso->result_line[sizeof(xorriso->result_line)-1]= 0; + Xorriso_result(xorriso,0); + ret= Xorriso_dialog_input(xorriso, line, sizeof(line),1); + return(ret); +} + + +/* Option -publisher */ +int Xorriso_option_publisher(struct XorrisO *xorriso, char *name, int flag) +{ + if(Xorriso_check_name_len(xorriso, name, (int) sizeof(xorriso->publisher), + "-publisher", 0) <= 0) + return(0); + strcpy(xorriso->publisher,name); + Xorriso_set_change_pending(xorriso, 1); + return(1); +} + + +/* Option -pvd_info */ +int Xorriso_option_pvd_info(struct XorrisO *xorriso, int flag) +{ + return(Xorriso_pvd_info(xorriso, 0)); +} + + +/* Option -pwd alias -pwdi */ +int Xorriso_option_pwdi(struct XorrisO *xorriso, int flag) +{ + char sfe[5 * SfileadrL]; + + sprintf(xorriso->info_text,"current working directory in ISO image:\n"); + Xorriso_info(xorriso,0); + sprintf(xorriso->result_line,"%s/\n", Text_shellsafe(xorriso->wdi, sfe, 0)); + Xorriso_result(xorriso,0); + return(1); +} + + +/* Option -pwdx */ +int Xorriso_option_pwdx(struct XorrisO *xorriso, int flag) +{ + sprintf(xorriso->info_text,"current working directory on hard disk:\n"); + Xorriso_info(xorriso,0); + sprintf(xorriso->result_line,"%s/\n",xorriso->wdx); + Xorriso_result(xorriso,0); + return(1); +} + + +/* Option -reassure "on"|"tree"|"off" */ +int Xorriso_option_reassure(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode, "off")==0) + xorriso->do_reassure= 0; + else if(strcmp(mode, "on")==0) + xorriso->do_reassure= 1; + else if(strcmp(mode, "tree")==0) + xorriso->do_reassure= 2; + else { + sprintf(xorriso->info_text, "-reassure: unknown mode '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + return(1); +} + + +/* Option -unregister_filter */ +int Xorriso_option_unregister_filter(struct XorrisO *xorriso, char *name, + int flag) +{ + int ret; + + ret= Xorriso_external_filter(xorriso, name, "", "", 0, NULL, 1); + return(ret); +} + + +/* Option -report_about */ +int Xorriso_option_report_about(struct XorrisO *xorriso, char *severity, + int flag) +{ + int ret, sev; + char sfe[5*SfileadrL]; + + ret= Xorriso__text_to_sev(severity, &sev, 0); + if(ret<=0) { + sprintf(xorriso->info_text, + "-report_about: Not a known severity name : %s", + Text_shellsafe(severity, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + return(ret); + } + if(Sfile_str(xorriso->report_about_text,severity,0)<=0) + return(-1); + xorriso->report_about_severity= sev; + return(1); +} + + +/* Option -return_with */ +int Xorriso_option_return_with(struct XorrisO *xorriso, char *severity, + int exit_value, int flag) +{ + int ret, sev; + char sfe[5*SfileadrL]; + + ret= Xorriso__text_to_sev(severity, &sev, 0); + if(ret<=0) { + sprintf(xorriso->info_text, + "-return_with: Not a known severity name : %s", + Text_shellsafe(severity, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(ret); + } + if(exit_value && (exit_value < 32 || exit_value > 63)) { + sprintf(xorriso->info_text, + "-return_with: Not an allowed exit_value. Use 0, or 32 to 63."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if(Sfile_str(xorriso->return_with_text,severity,0)<=0) + return(-1); + xorriso->return_with_severity= sev; + xorriso->return_with_value= exit_value; + return(1); +} + + +/* Options -rm alias -rmi , -rm_r alias -rm_ri , -rmdir alias -rmdiri */ +/* @param flag bit0=recursive , bit1= remove empty directory: rmdir */ +int Xorriso_option_rmi(struct XorrisO *xorriso, int argc, char **argv, + int *idx, int flag) +{ + int i, ret, end_idx, was_failure= 0, fret; + char path[SfileadrL], eff_path[SfileadrL], sfe[5*SfileadrL]; + int optc= 0; + char **optv= NULL; + + ret= Xorriso_opt_args(xorriso, "-rm*i", + argc, argv, *idx, &end_idx, &optc, &optv, 0); + if(ret<=0) + goto ex; + for(i= 0; iwdi, path, 0); + if(ret<=0) + goto problem_handler; + } + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 1); + if(ret<0) + goto problem_handler; + if(ret==0) { + sprintf(xorriso->info_text, + "Cannot find path %s in loaded ISO image for removal", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + goto problem_handler; + } + strcpy(path, eff_path); + + ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, path, flag&(1|2)); + if(ret<=0 || xorriso->request_to_abort) + goto problem_handler; + if(ret<3) { + sprintf(xorriso->info_text, "Removed from ISO image: %s '%s'\n", + ((flag&2) ? "directory" : (ret>1 ? "subtree" : "file")), path); + Xorriso_info(xorriso, 0); + } + + continue; /* regular bottom of loop */ +problem_handler:; + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + goto ex; + } + ret= 1; +ex:; + (*idx)= end_idx; + Xorriso_opt_args(xorriso, "-rm*i", + argc, argv, *idx, &end_idx, &optc, &optv, 256); + if(ret<=0) + return(ret); + return(!was_failure); +} + + +/* Option -rollback */ +/* @param flag bit0= do not -reassure + @return <=0 error , 1 success, 2 revoked by -reassure +*/ +int Xorriso_option_rollback(struct XorrisO *xorriso, int flag) +{ + int ret; + char indev[SfileadrL], *which_will; + + if(xorriso->volset_change_pending) + which_will= "revoke the pending image changes"; + else + which_will= "reload the image"; + if(!(flag&1)) { + ret= Xorriso_reassure(xorriso, "-rollback", which_will, 0); + if(ret<=0) + return(2); + } + + if(Sfile_str(indev, xorriso->indev, 0)<=0) + return(-1); + ret= Xorriso_give_up_drive(xorriso, 1|8); + if(ret<=0) + return(ret); + xorriso->image_start_mode&= ~(1<<31); /* reactivate eventual -load address */ + ret= Xorriso_option_dev(xorriso, indev, 1|4); + return(ret); +} + + +/* Option -rom_toc_scan */ +int Xorriso_option_rom_toc_scan(struct XorrisO *xorriso, char *mode, int flag) +{ + int l; + char *cpt, *npt; + + xorriso->toc_emulation_flag= 0; + npt= cpt= mode; + for(cpt= mode; npt != NULL; cpt= npt + 1) { + npt= strchr(cpt,':'); + if(npt==NULL) + l= strlen(cpt); + else + l= npt-cpt; + if(l==0) + goto unknown_mode; + xorriso->toc_emulation_flag&= ~4; + if(strncmp(cpt, "off", l) == 0) + xorriso->toc_emulation_flag&= ~1; + else if(strncmp(cpt, "on", l) == 0) + xorriso->toc_emulation_flag|= 1; + else if(strncmp(cpt, "force", l) == 0) + xorriso->toc_emulation_flag|= 4; + else if(strncmp(cpt, "emul_off", l) == 0) + xorriso->toc_emulation_flag|= 2; + else if(strncmp(cpt, "emul_on", l) == 0) + xorriso->toc_emulation_flag&= ~2; + else { +unknown_mode:; + sprintf(xorriso->info_text, "-rom_toc_scan: unknown mode in '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + return(1); +} + + +/* Option -scdbackup_tag list_path record_name */ +int Xorriso_option_scdbackup_tag(struct XorrisO *xorriso, char *listname, + char *recname, int flag) +{ + if(strlen(recname) > 80) { + sprintf(xorriso->info_text, + "Unsuitable record name given with -scdbackup_tag"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + strcpy(xorriso->scdbackup_tag_name, recname); + xorriso->scdbackup_tag_time[0]= 0; + if(Sfile_str(xorriso->scdbackup_tag_listname, listname, 0) <= 0) + return(-1); + return(1); +} + + +/* Option -scsi_log */ +int Xorriso_option_scsi_log(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode, "on") == 0) + xorriso->scsi_log= 1; + else if(strcmp(mode, "off") == 0) + xorriso->scsi_log= 0; + else { + sprintf(xorriso->info_text, "-scsi_log: unknown mode '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + Xorriso_scsi_log(xorriso, !!xorriso->scsi_log); + return(1); +} + + +/* Option -session_log */ +int Xorriso_option_session_log(struct XorrisO *xorriso, char *path, int flag) +{ + if(Sfile_str(xorriso->session_logfile, path, 0)<=0) + return(-1); + return(1); +} + + + +/* Option -setfacl_list alias -setfacl_listi */ +int Xorriso_option_setfacl_listi(struct XorrisO *xorriso, char *path, int flag) +{ + int ret, eaten; + size_t buf_size= 0, buf_add= 64 * 1024, l, linecount= 0; + char line[SfileadrL * 4], *buf= NULL, *wpt, *new_buf, limit_text[80]; + char file_path[SfileadrL], uid[161], gid[161]; + FILE *fp= NULL; + + Xorriso_pacifier_reset(xorriso, 0); + if(path[0]==0) { + sprintf(xorriso->info_text, "Empty file name given with -setfacl_list"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= Xorriso_afile_fopen(xorriso, path, "rb", &fp, 0); + if(ret <= 0) + return(0); + + buf_size= buf_add; + buf= calloc(buf_size, 1); + if(buf == NULL) + goto out_of_mem; + wpt= buf; + *wpt= 0; + uid[0]= gid[0]= 0; + + while(1) { + if(Sfile_fgets_n(line, sizeof(line), fp, 0) == NULL) + break; + linecount++; + if(strncmp(line, "# file: ", 8) ==0) { + if(wpt != buf && file_path[0]) { + /* Commit previous list */ + ret= Xorriso_perform_acl_from_list(xorriso, file_path, + uid, gid, buf, 0); + if(ret<=0) + goto ex; + wpt= buf; + *wpt= 0; + file_path[0]= uid[0]= gid[0]= 0; + } + /* Unescape line and register as file path */ + Sfile_bsl_interpreter(line + 8, strlen(line + 8), &eaten, 0); + if(strlen(line + 8) >= SfileadrL) { + sprintf(xorriso->info_text, "-setfacl_list: Oversized file path"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + strcpy(file_path, line + 8); + continue; + } else if(strncmp(line, "# owner: ", 9) == 0) { + if(strlen(line + 9) > 160) { + sprintf(xorriso->info_text, "-setfacl_list: Oversized owner id"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + strcpy(uid, line + 9); + continue; + } else if(strncmp(line, "# group: ", 9) == 0) { + if(strlen(line + 9) > 160) { + sprintf(xorriso->info_text, "-setfacl_list: Oversized group id"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + strcpy(gid, line + 9); + continue; + } else if(line[0] == '#' || line[0] == 0) { + continue; + } else if(strcmp(line, "@") == 0) { + Xorriso_msgs_submit(xorriso, 0, + "-setfacl_list input ended by '@'", 0, "NOTE", 0); + break; + } else if(strcmp(line, "@@@") == 0) { + Xorriso_msgs_submit(xorriso, 0, + "-setfacl_list aborted by input line '@@@'", 0, "WARNING", 0); + ret= 0; goto ex; + } + + /* Register ACL entry */ + l= strlen(line); + if(wpt + l + 2 - buf > buf_size) { + if(buf_size + buf_add > xorriso->temp_mem_limit) { + Sfile_scale((double) xorriso->temp_mem_limit, limit_text,5,1e4,1); + sprintf(xorriso->info_text, + "-setfacl_list: List entry for a single file exceeds -temp_mem_limit %s", + limit_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + buf_size+= buf_add; + new_buf= realloc(buf, buf_size); + if(new_buf == NULL) + goto out_of_mem; + buf= new_buf; + } + memcpy(wpt, line, l); + *(wpt + l)= '\n'; + wpt+= l + 1; + *wpt= 0; + } + if(wpt != buf && file_path[0]) { + /* Commit last list */ + ret= Xorriso_perform_acl_from_list(xorriso, file_path, uid, gid, buf, 0); + if(ret<=0) + goto ex; + } else { + sprintf(xorriso->info_text, "-setfacl_list: Unexpected end of file "); + Text_shellsafe(path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + } + ret= 1; +ex:; + if(buf != NULL) + free(buf); + if(fp != NULL && fp != stdin) + fclose(fp); + if(ret <= 0) { + sprintf(xorriso->info_text, "-setfacl_list "); + Text_shellsafe(path, xorriso->info_text, 1); + sprintf(xorriso->info_text + strlen(xorriso->info_text), + " aborted in line %.f\n", (double) linecount); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } + return(ret); +out_of_mem:; + Xorriso_no_malloc_memory(xorriso, &buf, 0); + ret= -1; + goto ex; +} + + +/* Options -setfacl alias -setfacli, -setfacl_r alias -setfacl_ri */ +/* @param flag bit0=recursive -setfacl_r +*/ +int Xorriso_option_setfacli(struct XorrisO *xorriso, char *acl_text, + int argc, char **argv, int *idx, int flag) +{ + int i, ret, was_failure= 0, end_idx, fret; + int optc= 0; + char **optv= NULL, *access_acl_text= NULL, *default_acl_text= NULL; + struct FindjoB *job= NULL; + struct stat dir_stbuf; + + ret= Xorriso_opt_args(xorriso, "-setfacl", argc, argv, *idx, &end_idx, &optc, + &optv, 0); + if(ret <= 0) + goto ex; + + ret= Xorriso_normalize_acl_text(xorriso, acl_text, + &access_acl_text, &default_acl_text, 0); + if(access_acl_text != NULL && default_acl_text != NULL) { + sprintf(xorriso->info_text, "Access-ACL :\n%s", access_acl_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + sprintf(xorriso->info_text, "Default-ACL :\n%s", default_acl_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + } else if(access_acl_text == NULL && default_acl_text == NULL) { + sprintf(xorriso->info_text, "Will delete Access-ACL and Default-ACL"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + } + if(ret <= 0) + goto ex; + + for(i= 0; i0 && !xorriso->request_to_abort) + continue; /* regular bottom of loop */ + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + ret= 0; goto ex; + } + ret= 1; +ex:; + (*idx)= end_idx; + Xorriso_opt_args(xorriso, "-setfacl", argc, argv, *idx, &end_idx, + &optc, &optv, 256); + Findjob_destroy(&job, 0); + if(access_acl_text != NULL) + free(access_acl_text); + if(default_acl_text != NULL) + free(default_acl_text); + if(ret<=0) + return(ret); + return(!was_failure); +} + + +/* Options -setfattr alias -setfattri, -setfattr_r alias -setfattr_ri */ +/* @param flag bit0=recursive -setfattr_r +*/ +int Xorriso_option_setfattri(struct XorrisO *xorriso, char *name, char *value, + int argc, char **argv, int *idx, int flag) +{ + int i, ret, was_failure= 0, end_idx, fret; + int optc= 0; + char **optv= NULL; + struct FindjoB *job= NULL; + struct stat dir_stbuf; + + ret= Xorriso_opt_args(xorriso, "-setfattr", argc, argv, *idx, &end_idx, &optc, + &optv, 0); + if(ret <= 0) + goto ex; + + /* check input */ + ret= Xorriso_path_setfattr(xorriso, NULL, "", name, strlen(value), value, 1); + if(ret <= 0) + goto ex; + + for(i= 0; i0 && !xorriso->request_to_abort) + continue; /* regular bottom of loop */ + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + ret= 0; goto ex; + } + ret= 1; +ex:; + (*idx)= end_idx; + Xorriso_opt_args(xorriso, "-setfattr", argc, argv, *idx, &end_idx, + &optc, &optv, 256); + Findjob_destroy(&job, 0); + if(ret<=0) + return(ret); + return(!was_failure); +} + + +/* Option -setfattr_list alias -setfattr_listi */ +int Xorriso_option_setfattr_listi(struct XorrisO *xorriso, char *path, + int flag) +{ + int ret, eaten; + size_t linecount= 0, mem_used= 0, num_attr= 0, v_len; + char line[SfileadrL * 4], limit_text[80], *ept, *valuept; + char file_path[SfileadrL]; + FILE *fp= NULL; + struct Xorriso_lsT *lst_curr= NULL, *lst_start= NULL; + + Xorriso_pacifier_reset(xorriso, 0); + if(path[0]==0) { + sprintf(xorriso->info_text, "Empty file name given with -setfattr_list"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= Xorriso_afile_fopen(xorriso, path, "rb", &fp, 0); + if(ret <= 0) + return(0); + + while(1) { + if(Sfile_fgets_n(line, sizeof(line), fp, 0) == NULL) + break; + linecount++; + if(strncmp(line, "# file: ", 8) ==0) { + if(num_attr > 0 && file_path[0]) { + /* Commit previous list */ + ret= Xorriso_perform_attr_from_list(xorriso, file_path, lst_start, 0); + if(ret<=0) + goto ex; + num_attr= 0; + file_path[0]= 0; + Xorriso_lst_destroy_all(&lst_start, 0); + lst_curr= NULL; + } + /* Unescape line and register as file path */ + Sfile_bsl_interpreter(line + 8, strlen(line + 8), &eaten, 0); + if(strlen(line + 8) >= SfileadrL) { + sprintf(xorriso->info_text, "-setfattr_list: Oversized file path"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + strcpy(file_path, line + 8); + continue; + } else if(line[0] == '#' || line[0] == 0) { + continue; + } else if(strcmp(line, "@") == 0) { + Xorriso_msgs_submit(xorriso, 0, + "-setfattr_list input ended by '@'", 0, "NOTE", 0); + break; + } else if(strcmp(line, "@@@") == 0) { + Xorriso_msgs_submit(xorriso, 0, + "-setfattr_list aborted by input line '@@@'", 0, "WARNING", 0); + ret= 1; goto ex; + } + mem_used+= strlen(line) + 1; + if(mem_used > xorriso->temp_mem_limit) { + Sfile_scale((double) xorriso->temp_mem_limit, limit_text,5,1e4,1); + sprintf(xorriso->info_text, + "-setfattr_list: List entry for a single file exceeds -temp_mem_limit %s", + limit_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + + /* Register attr pair */ + + ept= strchr(line, '='); + if(ept == NULL) { + sprintf(xorriso->info_text, "-setfattr_list: "); + Text_shellsafe(path, xorriso->info_text, 1); + sprintf(xorriso->info_text + strlen(xorriso->info_text), + " : Line %.f : No separator '=' found", + (double) linecount); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + continue; + } + valuept= ept + 1; + v_len= strlen(valuept); + for(ept= valuept + v_len - 1; ept > valuept; ept--) + if(isspace(*ept)) + *ept= 0; + else + break; + v_len= strlen(valuept); + if(v_len < 2 || *valuept != '"' || *(valuept + v_len -1) != '"') { + sprintf(xorriso->info_text, "-setfattr_list: "); + Text_shellsafe(path, xorriso->info_text, 1); + sprintf(xorriso->info_text + strlen(xorriso->info_text), + " : Line %.f : Value not enclosed in quotes", + (double) linecount); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + + continue; + } + + ret= Xorriso_lst_new(&lst_curr, line, lst_curr, 0); + if(ret <= 0) + goto out_of_mem; + if(lst_start == NULL) + lst_start= lst_curr; + num_attr++; + } + + if(file_path[0]) { + /* Commit last list */ + ret= Xorriso_perform_attr_from_list(xorriso, file_path, lst_start, 0); + if(ret<=0) + goto ex; + } else { + sprintf(xorriso->info_text, "-setfattr_list: Unexpected end of file "); + Text_shellsafe(path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + } + ret= 1; +ex:; + if(fp != NULL && fp != stdin) + fclose(fp); + Xorriso_lst_destroy_all(&lst_start, 0); + if(ret <= 0) { + sprintf(xorriso->info_text, "-setfattr_list "); + Text_shellsafe(path, xorriso->info_text, 1); + sprintf(xorriso->info_text + strlen(xorriso->info_text), + " aborted in line %.f\n", (double) linecount); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } + return(ret); +out_of_mem:; + Xorriso_no_malloc_memory(xorriso, NULL, 0); + ret= -1; + goto ex; +} + + +/* Options -set_filter , -set_filter_r , -show_stream , -show_stream_r */ +/* @param flag bit0=recursive -set_filter_r + bit1= do not reset pacifier, no final pacifier message + bit2= -show_stream rather than -set_filter +*/ +int Xorriso_option_set_filter(struct XorrisO *xorriso, char *name, + int argc, char **argv, int *idx, int flag) +{ + int i, ret, was_failure= 0, end_idx, fret; + int optc= 0; + char **optv= NULL; + struct FindjoB *job= NULL; + struct stat dir_stbuf; + char *cmd= "-set_filter"; + + switch(flag & 5) { + case 0: cmd= "-set_filter"; + break; case 1: cmd= "-set_filter_r"; + break; case 4: cmd= "-show_stream"; + break; case 5: cmd= "-show_stream_r"; + } + + ret= Xorriso_opt_args(xorriso, cmd, + argc, argv, *idx, &end_idx, &optc, &optv, 0); + if(ret <= 0) + goto ex; + if(!(flag&2)) + Xorriso_pacifier_reset(xorriso, 0); + + for(i= 0; i0 && !xorriso->request_to_abort) + continue; /* regular bottom of loop */ + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + ret= 0; goto ex; + } + if(!(flag&2)) + Xorriso_pacifier_callback(xorriso, "file filters processed", + xorriso->pacifier_count, 0, "", 1); + ret= 1; +ex:; + (*idx)= end_idx; + Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, + &optc, &optv, 256); + Findjob_destroy(&job, 0); + if(ret<=0) + return(ret); + return(!was_failure); +} + + +/* Option -speed */ +int Xorriso_option_speed(struct XorrisO *xorriso, char *speed, int flag) +{ + int is_cd= 1, unit_found= 0, ret, profile_number; + double num; + char *cpt, profile_name[80]; + + if(speed[0]==0 || strcmp(speed, "any")==0) { + xorriso->speed= 0; /* full speed */ + return(1); + } + + sscanf(speed,"%lf",&num); + for(cpt= speed+strlen(speed)-1; cpt>=speed; cpt--) + if(isdigit(*cpt) || *cpt=='.') + break; + cpt++; + + if(*cpt=='k' || *cpt=='K') { + /* is merchand kilobyte, stays merchand kilobyte */ + unit_found= 1; + } else if(*cpt=='m' || *cpt=='M') { + num*= 1000; + unit_found= 1; + } else if(*cpt=='x' || *cpt=='X') + cpt++; + + if (unit_found) { + ; + } else if(*cpt=='c' || *cpt=='C') { +cd_speed:; + num*= 176.4; + } else if(*cpt=='d' || *cpt=='D') { +dvd_speed:; + num*= 1385; + } else if(*cpt=='b' || *cpt=='B') { +bd_speed:; + num*= 4495.625; + } else { + ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2); + is_cd= (ret==2); + if(is_cd) + goto cd_speed; + else if (ret == 3) + goto bd_speed; + else + goto dvd_speed; + } + + if(num> 2.0e9) { + sprintf(xorriso->info_text, + "-speed: Value too large or not recognizable: '%s'", speed); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + xorriso->speed= num; + if(xorriso->speedspeed++; + return(1); +} + + +/* Option -split_size */ +int Xorriso_option_split_size(struct XorrisO *xorriso, char *size, int flag) +{ + double num; + + num= Scanf_io_size(size, 0); + if(num > xorriso->file_size_limit && xorriso->file_size_limit > 0) { + sprintf(xorriso->info_text, "-split_size: too large %.f (allowed: %.f)", + num, (double) xorriso->file_size_limit); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } else if(num < 0) + num= 0.0; + xorriso->split_size= num; + return(1); +} + + +/* Option -status */ +int Xorriso_option_status(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode,"short")==0) + Xorriso_status(xorriso,NULL,NULL,1); + else if(strcmp(mode,"long")==0) + Xorriso_status(xorriso,NULL,NULL,0); + else if(strcmp(mode,"long_history")==0) + Xorriso_status(xorriso,NULL,NULL,8); + else if(mode[0]=='-') + Xorriso_status(xorriso,mode,NULL,8); + else + Xorriso_status(xorriso,NULL,NULL,1); + return(1); +} + + +/* Option -status_history_max */ +int Xorriso_option_status_history_max(struct XorrisO *xorriso, int num, + int flag) +{ + if(num>=0 && num<1000000) + xorriso->status_history_max= num; + return(1); +} + + +/* Option -stdio_sync "on"|"off"|size */ +int Xorriso_option_stdio_sync(struct XorrisO *xorriso, char *rythm, int flag) +{ + double num; + + if(strcmp(rythm, "default") == 0 || strcmp(rythm, "on") == 0) + num= 0; + if(strcmp(rythm, "off") == 0) + num= -1; + else + num = Scanf_io_size(rythm, 0); + if(num > 0) + num /= 2048; + if(num != -1 && num != 0 && (num < 32 || num > 512 * 1024)) { + sprintf(xorriso->info_text, + "-stdio_sync : Bad size. Acceptable are -1, 0, 32k ... 1g"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } else + xorriso->stdio_sync= num; + return(1); +} + + +/* Option -stream_recording */ +int Xorriso_option_stream_recording(struct XorrisO *xorriso, char *mode, + int flag) +{ + double num; + + if(strcmp(mode,"on")==0 || mode[0]==0) + xorriso->do_stream_recording= 32; + else if(strcmp(mode,"full")==0) + xorriso->do_stream_recording= 1; + else if(strcmp(mode,"data")==0) + xorriso->do_stream_recording= 2; + else if(mode[0] >= '0' && mode[0] <= '9') { + num= Scanf_io_size(mode, 0); + num/= 2048.0; + if(num >= 16 && num <= 0x7FFFFFFF) + xorriso->do_stream_recording= num; + else + xorriso->do_stream_recording= 0; + } else + xorriso->do_stream_recording= 0; + return(1); +} + + +/* Option -system_id */ +int Xorriso_option_system_id(struct XorrisO *xorriso, char *name, int flag) +{ + if(Xorriso_check_name_len(xorriso, name, (int) sizeof(xorriso->system_id), + "-system_id", 0) <= 0) + return(0); + strcpy(xorriso->system_id, name); + Xorriso_set_change_pending(xorriso, 1); + return(1); +} + + +/* Option -tell_media_space */ +int Xorriso_option_tell_media_space(struct XorrisO *xorriso, int flag) +{ + int ret, free_space= 0, media_space= 0; + + ret= Xorriso_tell_media_space(xorriso, &media_space, &free_space, 0); + if(ret<=0) { + sprintf(xorriso->info_text, "Cannot -tell_media_space"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + if(free_space<0) { + sprintf(xorriso->info_text, + "Pending image size larger than free space on media"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + } + sprintf(xorriso->result_line, "Media space : %ds\n", media_space); + Xorriso_result(xorriso, 0); + sprintf(xorriso->result_line, "After commit : %ds\n", free_space); + Xorriso_result(xorriso, 0); + return(1); +} + + +/* Option -temp_mem_limit */ +int Xorriso_option_temp_mem_limit(struct XorrisO *xorriso, char *size, + int flag) +{ + double num; + + num= Scanf_io_size(size, 0); + if(num < 64.0 * 1024.0 || num > 1024.0 * 1024.0 * 1024.0) { + sprintf(xorriso->info_text, + "-temp_mem_limit: wrong size %.f (allowed: %.f - %.f)", + num, 64.0 * 1024.0, 1024.0 * 1024.0 * 1024.0); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + xorriso->temp_mem_limit= num; + return(1); +} + + +/* Option -toc */ +int Xorriso_option_toc(struct XorrisO *xorriso, int flag) +{ + int ret, in_ret= 1000; + + if(strcmp(xorriso->indev,xorriso->outdev)==0) + ret= Xorriso_toc(xorriso, 0); + else { + if(xorriso->indev[0]!=0) + in_ret= Xorriso_toc(xorriso, 0); + if(xorriso->indev[0]!=0 && xorriso->outdev[0]!=0) { + strcpy(xorriso->result_line, "-------------: ---------------------------------------------------------------\n"); + Xorriso_result(xorriso,0); + } + ret= 1; + if(xorriso->outdev[0]!=0) + ret= Xorriso_toc(xorriso, 2); + if(in_retdo_global_uid= 0; + if(uid[0]==0 || strcmp(uid,"-")==0) + return(1); + ret= Xorriso_convert_uidstring(xorriso, uid, &(xorriso->global_uid), 0); + if(ret>0) + xorriso->do_global_uid= 1; + return(ret); +} + + +/* Options -update and -update_r + @param flag bit0= issue start and summary message + bit1= do not reset pacifier, no final pacifier message + bit2= do not issue pacifier messages at all + bit3= recursive: -update_r + bit4= do not establish and dispose xorriso->di_array +*/ +int Xorriso_option_update(struct XorrisO *xorriso, char *disk_path, + char *iso_path, int flag) +{ + int ret, mem_pci, zero= 0, result, uret, follow_links, do_register= 1; + int not_in_iso= 0, not_on_disk= 0, made_di_array= 0; + double mem_lut= 0.0, start_time; + char *ipth, *argv[6], sfe[5*SfileadrL]; + char eff_origin[SfileadrL], eff_dest[SfileadrL]; + struct stat stbuf; + + start_time= Sfile_microtime(0); + + ipth= iso_path; + if(ipth[0]==0) + ipth= disk_path; + if(disk_path[0]==0) { + sprintf(xorriso->info_text, "-update: Empty disk_path given"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 1); + return(0); + } + + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_origin, + 2|4|8); + if(ret<=0) + return(ret); + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, ipth, eff_dest, 2|8); + if(ret<=0) + return(ret); + + if(!(flag&2)) { + Xorriso_pacifier_reset(xorriso, 0); + mem_lut= xorriso->last_update_time; + } + mem_pci= xorriso->pacifier_interval; + xorriso->pacifier_interval= 5.0; + + if(flag&1) { + sprintf(xorriso->info_text, "Updating %s to", + Text_shellsafe(eff_origin, sfe, 0)); + sprintf(xorriso->info_text+strlen(xorriso->info_text), " %s\n", + Text_shellsafe(eff_dest, sfe, 0)); + Xorriso_info(xorriso,0); + } + if(xorriso->disk_excl_mode&8) + ret= Xorriso_path_is_excluded(xorriso, eff_origin, 1); + else + ret= 0; + if(ret!=0) + goto report_outcome; + + if(!(xorriso->ino_behavior & 2)) { + if(!(xorriso->di_array != NULL || (flag & 16))) { + /* Create all-image node array sorted by isofs.di */ + made_di_array= 1; + ret= Xorriso_make_di_array(xorriso, 0); + if(ret <= 0) + goto ex; + } + if(xorriso->di_array != NULL) { + if(!(flag & 8)) { + /* If directory with -update : do not register di_*_paths */ + ret= lstat(eff_origin, &stbuf); + if(ret != -1) + if(S_ISDIR(stbuf.st_mode)) + do_register= 0; + } + if(do_register) { + ret= Xorriso_lst_new(&(xorriso->di_disk_paths), eff_origin, + xorriso->di_disk_paths, 1); + if(ret <= 0) + goto ex; + ret= Xorriso_lst_new(&(xorriso->di_iso_paths), eff_dest, + xorriso->di_iso_paths, 1); + if(ret <= 0) + goto ex; + } + } + } + + if(flag&8) { + xorriso->find_compare_result= 1; + ret= Xorriso_iso_lstat(xorriso, eff_dest, &stbuf, 0); + if(ret >= 0) { + argv[0]= eff_dest; + argv[1]= "-exec"; + argv[2]= "update"; + argv[3]= eff_origin; + zero= 0; + ret= Xorriso_option_find(xorriso, 4, argv, &zero, + 2 | (8 * !((xorriso->do_aaip & 96) == 96))); /* -findi */ + } else if(ret==-2) { /* severe error (e.g. lack of image) */ + ret= -1; + goto report_outcome; + } else { + not_in_iso= 1; + ret= 1; + } + if(ret>0) { + ret= lstat(eff_origin, &stbuf); + if(ret != -1) { + argv[0]= eff_origin; + argv[1]= "-exec"; + argv[2]= "add_missing"; + argv[3]= eff_dest; + zero= 0; + ret= Xorriso_option_find(xorriso, 4, argv, &zero, 1|2); /* -findx */ + if(ret>0 && !xorriso->do_follow_mount) { + argv[0]= eff_origin; + argv[1]= "-type"; + argv[2]= "m"; + argv[3]= "-exec"; + argv[4]= "empty_iso_dir"; + argv[5]= eff_dest; + zero= 0; + ret= Xorriso_option_find(xorriso, 6, argv, &zero, 1|2); /* -findx */ + } + if(ret>0) + ret= xorriso->find_compare_result; + else + ret= -1; + } else { + ret= xorriso->find_compare_result; + not_on_disk= 1; + } + } else + ret= -1; + if(not_on_disk && not_in_iso) { + 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); + ret= -1; + } + } else { + /* compare ctime too, no filename reporting, eventually silent */ + follow_links= (xorriso->do_follow_links || xorriso->do_follow_param) <<28; + ret= Xorriso_compare_2_files(xorriso, eff_origin, eff_dest, "", &result, + 2 | follow_links | ((flag&4)<<27) | (3<<30)); + if(ret==0) { + uret= Xorriso_update_interpreter(xorriso, NULL, result, eff_origin, + eff_dest, 0); + if(uret<=0) + ret= -1; + if(uret==3) + ret= -1; + } + } + xorriso->pacifier_interval= mem_pci; + if(mem_lut!=xorriso->last_update_time && !(flag&2)) + Xorriso_pacifier_callback(xorriso, "content bytes read", + xorriso->pacifier_count, 0, "", 1); +report_outcome:; + if(ret>0) { + sprintf(xorriso->info_text, + "No file object needed update."); + } else if(ret==0) { + sprintf(xorriso->info_text, "Differences detected and updated."); + } else { + sprintf(xorriso->info_text, + "Not ok. Comparison or update failed due to error."); + } + sprintf(xorriso->info_text+strlen(xorriso->info_text), + " (runtime %.1f s)\n", Sfile_microtime(0)-start_time); + if(flag&1) + Xorriso_info(xorriso,0); + +ex:; + if(ret < 0) + return(ret); + return(1); +} + + +/* Option -use_readline */ +int Xorriso_option_use_readline(struct XorrisO *xorriso, char *mode, int flag) +{ + if(strcmp(mode,"off")==0) + xorriso->use_stdin= 1; + else + xorriso->use_stdin= 0; + return(1); +} + + +/* Option -version */ +int Xorriso_option_version(struct XorrisO *xorriso, int flag) +{ +#ifdef Xorriso_GNU_xorrisO + sprintf(xorriso->result_line, "GNU xorriso %s%s\n", + Xorriso_program_versioN, Xorriso_program_patch_leveL); +#else + sprintf(xorriso->result_line, "xorriso %s%s\n", + Xorriso_program_versioN, Xorriso_program_patch_leveL); +#endif /* ! Xorriso_GNU_xorrisO */ + Xorriso_result(xorriso, 0); + sprintf(xorriso->result_line, +"ISO 9660 Rock Ridge filesystem manipulator and CD/DVD/BD burn program\n"); + sprintf(xorriso->result_line+strlen(xorriso->result_line), +"Copyright (C) 2010, Thomas Schmitt , libburnia project.\n"); + Xorriso_result(xorriso, 0); + sprintf(xorriso->result_line, + "xorriso version : %s%s\n", + Xorriso_program_versioN, Xorriso_program_patch_leveL); + sprintf(xorriso->result_line+strlen(xorriso->result_line), + "Version timestamp : %s\n",Xorriso_timestamP); + sprintf(xorriso->result_line+strlen(xorriso->result_line), + "Build timestamp : %s\n",Xorriso_build_timestamP); + Xorriso_result(xorriso, 0); + Xorriso_report_lib_versions(xorriso, 0); + +#ifdef Xorriso_GNU_xorrisO + sprintf(xorriso->result_line, +"License GPLv3+: GNU GPL version 3 or later .\n"); + Xorriso_result(xorriso, 0); + sprintf(xorriso->result_line, +"This is free software: you are free to change and redistribute it.\n"); + Xorriso_result(xorriso, 0); +#else + sprintf(xorriso->result_line, "Provided under GNU GPL version 2 or later.\n"); + Xorriso_result(xorriso, 0); +#endif /* ! Xorriso_GNU_xorrisO */ + + sprintf(xorriso->result_line, +"There is NO WARRANTY, to the extent permitted by law.\n"); + Xorriso_result(xorriso, 0); + return(1); +} + + +/* Option -volid */ +int Xorriso_option_volid(struct XorrisO *xorriso, char *volid, int flag) +{ + int warn_shell= 0, warn_ecma= 0, i, ret; + static char shell_chars[]= { + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-+=:.,~@"}; + static char ecma_chars[]= {"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"}; + + for(i=0; volid[i]!=0; i++) { + if(strchr(shell_chars, volid[i])==NULL) + warn_shell= 1; + if(strchr(ecma_chars, volid[i])==NULL) + warn_ecma= 1; + } + if(i>32) { + sprintf(xorriso->info_text, "-volid: Text too long (%d > 32)", i); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if(warn_shell) { + sprintf(xorriso->info_text, + "-volid text problematic as automatic mount point name"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + } + if(xorriso->do_joliet && strlen(volid)>16) { + sprintf(xorriso->info_text, + "-volid text is too long for Joliet (%d > 16)",(int) strlen(volid)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + } + if(warn_ecma) { + sprintf(xorriso->info_text, + "-volid text does not comply to ISO 9660 / ECMA 119 rules"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + } + strcpy(xorriso->volid, volid); + ret= Xorriso_set_volid(xorriso, volid, 0); + if(ret<=0) + return(ret); + xorriso->volid_default= (strcmp(xorriso->volid, "ISOIMAGE")==0 || + xorriso->volid[0]==0); + return(1); +} + + +/* Option -volset_id */ +int Xorriso_option_volset_id(struct XorrisO *xorriso, char *name, int flag) +{ + if(Xorriso_check_name_len(xorriso, name, (int) sizeof(xorriso->volset_id), + "-volset_id", 0) <= 0) + return(0); + strcpy(xorriso->volset_id, name); + Xorriso_set_change_pending(xorriso, 1); + return(1); +} + + +/* Option -volume_date */ +int Xorriso_option_volume_date(struct XorrisO *xorriso, + char *time_type, char *timestring, int flag) +{ + int ret, t_type= 0; + time_t t; + struct tm erg; + + if(timestring[0] == 0 || strcmp(timestring, "default") == 0 || + strcmp(timestring, "overridden") == 0 ){ + t= 0; + } else if(strcmp(time_type, "uuid") == 0) { + t= time(NULL); /* Just to have some that is not 0 */ + } else { + ret= Xorriso_convert_datestring(xorriso, "-volume_date", + "m", timestring, &t_type, &t, 0); + if(ret<=0) + goto ex; + } + if(strcmp(time_type, "uuid") == 0) { + if(t == 0) { + xorriso->vol_uuid[0]= 0; + ret= 1; goto ex; + } + ret= Decode_ecma119_format(&erg, timestring, 0); + if(ret <= 0) { + sprintf(xorriso->info_text, "-volume_date uuid : Not an ECMA-119 time string. (16 decimal digits, range 1970... to 2999...)"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + strcpy(xorriso->vol_uuid, timestring); + if(erg.tm_year < 138) { + sprintf(xorriso->info_text, + "Understanding ECMA-119 timestring '%s' as: %s", + timestring, asctime(&erg)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + } + + } else if(strcmp(time_type, "c") == 0) { + xorriso->vol_creation_time= t; + } else if(strcmp(time_type, "m") == 0) { + xorriso->vol_modification_time= t; + } else if(strcmp(time_type, "x") == 0) { + xorriso->vol_expiration_time= t; + } else if(strcmp(time_type, "f") == 0) { + xorriso->vol_effective_time= t; + } else { + + /* >>> unknown time type */; + + ret= 0; goto ex; + } + ret= 1; +ex:; + return(ret); +} + + +/* Option -xattr "on"|"off" */ +int Xorriso_option_xattr(struct XorrisO *xorriso, char *mode, int flag) +{ + int ret; + + if(strcmp(mode, "off")==0) + xorriso->do_aaip&= ~12; + else if(strcmp(mode, "on")==0) + xorriso->do_aaip|= (4 | 8); + else { + sprintf(xorriso->info_text, "-xattr: unknown mode '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= Xorriso_set_ignore_aclea(xorriso, 0); + if(ret <= 0) + return(ret); + return(1); +} + + +/* Option -zisofs */ +int Xorriso_option_zisofs(struct XorrisO *xorriso, char *mode, int flag) +{ + int was_level, was_blocksize, ret, l; + double num; + char *cpt, *npt, text[16]; + + was_level= xorriso->zlib_level; + was_blocksize= xorriso->zisofs_block_size; + npt= cpt= mode; + for(cpt= mode; npt!=NULL; cpt= npt+1) { + npt= strchr(cpt,':'); + if(npt==NULL) + l= strlen(cpt); + else + l= npt-cpt; + if(l==0) + goto unknown_mode; + + if(strncmp(cpt, "level=", 6) == 0) { + sscanf(cpt + 6, "%lf", &num); + if(num < 0 || num > 9) { + sprintf(xorriso->info_text, + "-zisofs: Wrong zlib compression level '%s' (allowed 0...9)", + cpt + 6); + goto sorry_ex; + } + xorriso->zlib_level= num; + + } else if(strncmp(cpt, "ziso_used=", 10) == 0 || + strncmp(cpt, "osiz_used=", 10) == 0) { + /* (ignored info from -status) */; + + } else if(strncmp(cpt, "block_size=", 11)==0) { + num= 0.0; + if(l > 11 && l < 27) { + strncpy(text, cpt + 11, l - 11); + text[l - 11]= 0; + num= Scanf_io_size(text, 0); + } + if (num != (1 << 15) && num != (1 << 16) && num != (1 << 17)) { + sprintf(xorriso->info_text, + "-zisofs: Unsupported block size (allowed 32k, 64k, 128k)"); + goto sorry_ex; + } + xorriso->zisofs_block_size= num; + + } else if(strncmp(cpt, "by_magic=", 8)==0) { + if(strncmp(cpt + 9, "on", l - 9) == 0) + xorriso->zisofs_by_magic= 1; + else + xorriso->zisofs_by_magic= 0; + + } else if(strncmp(cpt, "default", l)==0) { + xorriso->zlib_level= xorriso->zlib_level_default; + xorriso->zisofs_block_size= xorriso->zisofs_block_size_default; + xorriso->zisofs_by_magic= 0; + + } else { +unknown_mode:; + if(linfo_text, "-zisofs: unknown mode '%s'", cpt); + else + sprintf(xorriso->info_text, "-zisofs: oversized mode parameter (%d)",l); +sorry_ex: + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + xorriso->zlib_level= was_level; + xorriso->zisofs_block_size= was_blocksize; + return(0); + } + } + ret= Xorriso_set_zisofs_params(xorriso, 0); + return(ret); +} + + diff --git a/xorriso/parse_exec.c b/xorriso/parse_exec.c new file mode 100644 index 00000000..b1229f6e --- /dev/null +++ b/xorriso/parse_exec.c @@ -0,0 +1,2051 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains the implementation of functions which deal with parsing + and interpretation of command input. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#include "xorriso.h" +#include "xorriso_private.h" +#include "xorrisoburn.h" + + +/* @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 i, warned= 0; + + for(i= idx; ilist_delimiter)==0) + break; + if(!((flag&1) || warned)) + warned= Xorriso_warn_of_wildcards(xorriso, argv[i], flag&2); + } + return(i); +} + + +/* Returns a vector of strings which belong to an open ended arg list. + If expansion is enabled, the vector might be allocated, else it is + a pointer into the argv input vector. + Thus the release of that memory is an expert task to be done by this + function only. Use bit8 for that. With bit8 parameter argc MUST be the + same value as with the call which might have allocated memory. + @param xorriso The environment object + @param argc Length of argv + @param argv The vector with arguments, eventual list_delimiter ("--") + and then eventual unrelated words + @param idx Start index in argv of the argument list + @param optc Length of the effective possibly expanded option vector + @param optv The option vector. Maybe a pointer into argv or maybe + an own allocated vector. + @param flag bit0= do not warn of wildcards + bit1= these are disk_paths + bit2= never expand wildcards + bit3= do not expand last argument + bit4= ignore last argument + bit5= demand exactly one match + bit6= with bit5 allow 0 matches if pattern is a constant + bit7= silently tolerate empty argument list + bit8= free the eventually allocated sub_vector +*/ +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 i, do_expand, nump, was_empty= 0, filec= 0, ret; + char **filev= NULL, **patterns= NULL; + off_t mem= 0; + + if(flag&2) + do_expand= xorriso->do_disk_pattern==1 && !(flag&4); + else + do_expand= xorriso->do_iso_rr_pattern==1 && !(flag&4); + if(flag&256) { + if(*optv=argv+argc) + Sfile_destroy_argv(optc, optv, 0); + return(1); + } + if(idx>=argc) { + *end_idx= argc; + *optc= 0; + *optv= NULL; + sprintf(xorriso->info_text, "%s : Not enough arguments given", cmd); + if((flag & 128)) + return(1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + *end_idx= Xorriso_end_idx(xorriso, argc, argv, idx, + ((flag&1) || do_expand) | (flag&2)); + if(*end_idx<0) + return(*end_idx); + if((flag&16) && (*end_idx)>idx) + (*end_idx)--; + *optc= *end_idx - idx; + *optv= argv+idx; + if(*optc<=0 || !do_expand) + return(1); + patterns= calloc(*optc, sizeof(char *)); + if(patterns==NULL) { +no_memory:; + sprintf(xorriso->info_text, + "%s : Cannot allocate enough memory for pattern expansion", cmd); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + {ret= -1; goto ex;} + } + nump= 0; + if(flag&8) { + was_empty= 1; + mem+= strlen(argv[idx + *optc - 1])+1+sizeof(char *); + } + for(i= 0; i<*optc-!!(flag&8); i++) { + if(argv[i + idx][0]==0) { + was_empty++; + mem+= sizeof(char *); /* as upper limit for size of an empty string */ + continue; + } + patterns[nump++]= argv[i + idx]; + } + if(nump<=0) { /* Only empty texts. May the caller get happy with them. */ + free(patterns); + return(1); + } + if(flag&2) + ret= Xorriso_expand_disk_pattern(xorriso, nump, patterns, was_empty, + &filec, &filev, &mem, (flag>>5)&3); + else + ret= Xorriso_expand_pattern(xorriso, nump, patterns, was_empty, + &filec, &filev, &mem, (flag>>5)&3); + if(ret<=0) + {ret= 0; goto ex;} + for(i= 0; iinfo_text, "Pattern expansion yields %d items:", filec); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + l= 0; + xorriso->info_text[0]= 0; + for(i= 0; iinfo_text); + if(l>0 && l+1+strlen(filev[i])>60) { + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + xorriso->info_text[0]= 0; + l= 0; + } + sprintf(xorriso->info_text+l, " %s", filev[i]); + } + l= strlen(xorriso->info_text); + if(l>0) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); +} +#endif /* Xorriso_verbous_pattern_expansioN */ + + ret= 1; +ex:; + if(ret<=0) { + if(patterns!=NULL) + free((char *) patterns); + Sfile_destroy_argv(&filec, &filev, 0); + } else { + *optc= filec; + *optv= filev; + } + return(ret); +} + + +int Xorriso_get_problem_status(struct XorrisO *xorriso, char severity[80], + int flag) +{ + strcpy(severity, xorriso->problem_status_text); + return(xorriso->problem_status); +} + + +int Xorriso_set_problem_status(struct XorrisO *xorriso, char *severity, + int flag) +{ + char *sev_text= "ALL"; + int sev, ret; + + if(severity[0]) + sev_text= severity; + ret= Xorriso__text_to_sev(sev_text, &sev, 0); + if(ret<=0) + return(0); + xorriso->problem_status= sev; + strcpy(xorriso->problem_status_text, sev_text); + if(sev > xorriso->eternal_problem_status) { + xorriso->eternal_problem_status= sev; + strcpy(xorriso->eternal_problem_status_text, sev_text); + } + return(1); +} + + +/** + @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) +{ + static int sev= 0; + if(sev==0) + Xorriso__text_to_sev("SORRY", &sev, 0); + + if((flag&2) && xorriso->request_to_abort) + return(-2); + + Xorriso_process_msg_queues(xorriso, 0); + if(ret>0 && xorriso->problem_status <= 0) + return(1); + + if(xorriso->problem_status < xorriso->abort_on_severity && + xorriso->problem_status > 0) { + if(xorriso->problem_status >= sev && !(flag&1)) { + sprintf(xorriso->info_text, + "xorriso : NOTE : Tolerated problem event of severity '%s'\n", + xorriso->problem_status_text); + Xorriso_info(xorriso, 0);/* submit not as problem event */ + } + ret= 2; + } else if(xorriso->problem_status > 0) { + sprintf(xorriso->info_text, + "xorriso : aborting : -abort_on '%s' encountered '%s'\n", + xorriso->abort_on_text, xorriso->problem_status_text); + if(!(flag&1)) + Xorriso_info(xorriso, 0);/* submit not as problem event */ + ret= -1; + } else if(ret>0) + ret= 1; + else + ret= 2; + return(ret); +} + + +/* @param flag bit0= a non-existing target of multiple sources is a directory + bit1= all paths except the last one are disk_paths + bit2= the last path is a disk_path + @return <=0 is error, 1= leaf file object, 2= directory +*/ +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) +{ + int destc= 0, is_dir=0, end_idx, ret, i; + char **destv= NULL; + char sfe[5*SfileadrL]; + + end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, + (xorriso->do_iso_rr_pattern==1)|(flag&2)); + if(end_idx - *idx < 2) { + sprintf(xorriso->info_text, "%s: not enough arguments", cmd); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + {ret= 0; goto ex;} + } + + ret= Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, optc, optv, + (flag&2)|16); /* ignore last argument */ + if(ret<=0) + goto ex; + /* demand one match, or 0 with a constant */ + ret= Xorriso_opt_args(xorriso, cmd, argc, argv, end_idx, &end_idx, &destc, + &destv, ((flag&4)>>1) | 32 | 64); + if(ret<=0) + goto ex; + + /* Evaluate target address */ + if(flag&4) + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, destv[0], eff_dest, + 2|4|16); + else + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, destv[0], eff_dest, + 1); + if(ret<0) + {ret= 0; goto ex;} + if(ret==2 || ((flag&1) && *optc > 1 && ret==0)) { + is_dir= 1; + } else if(*optc > 1) { + for(i= 0; i<*optc; i++) + Xorriso_msgs_submit(xorriso, 0, (*optv)[i], 0, "ERRFILE", 0); + sprintf(xorriso->info_text, + "%s: more than one origin given, destination is a non-directory: %s", + cmd, Text_shellsafe(destv[0], sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + if(ret==0) { /* compute complete eff_dest */ + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, destv[0], eff_dest, + 2 | (flag&4)); + if(ret<0) + {ret= 0; goto ex;} + } + + ret= 1+is_dir; +ex:; + Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, &destc, &destv, + 256); + (*idx)= end_idx; + return(ret); +} + + +/* @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) +{ + double num; + int l; + + if(strcmp(adr_mode, "auto")==0) + *entity_code= 0; + else if(strcmp(adr_mode, "session")==0) + *entity_code= 1; + else if(strcmp(adr_mode, "track")==0) + *entity_code= 2; + else if(strcmp(adr_mode, "lba")==0 || strcmp(adr_mode, "sbsector")==0) + *entity_code= 3 | ((flag&1) << 16); + else if(strcmp(adr_mode, "volid")==0) + *entity_code= 4; + else { + sprintf(xorriso->info_text, "%s: unknown address mode '%s'", cmd, adr_mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + l= strlen(adr_value); + if(l==0) + *entity_code= 0; + + if(*entity_code>=1 && *entity_code<= 3) { + num= Scanf_io_size(adr_value, 0); + if(*entity_code==3 && + (adr_value[l-1]<'0' || adr_value[l-1]>'9')) + num/= 2048.0; + sprintf(entity_id, "%.f", num); + } else { + if(strlen(adr_value)>80) { + sprintf(xorriso->info_text, "%s: address value too long (80 < %d)", + cmd, (int) strlen(adr_value)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + strcpy(entity_id, adr_value); + } + return(1); +} + + +int Xorriso_check_name_len(struct XorrisO *xorriso, char *name, int size, + char *cmd, int flag) +{ + if(strlen(name) >= size) { + sprintf(xorriso->info_text, + "Name too long with option %s (%d > %d)", cmd, + (int) strlen(name), size - 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + return(1); +} + + + +/* @return <0 error , >=0 number of skipped dashes +*/ +int Xorriso_normalize_command(struct XorrisO *xorriso, char *original_cmd, + int argno, char *cmd_data, int sizeof_cmd_data, + char **cmd, int flag) +{ + int was_dashed= 0; + char *dash_pt; + + if(strlen(original_cmd)>= sizeof_cmd_data) { + if(argno>=0) + sprintf(xorriso->info_text, "Oversized argument #%d (length %d)\n", + argno, (int) strlen(original_cmd)); + else + sprintf(xorriso->info_text, "Oversized option (length %d)\n", + (int) strlen(original_cmd)); + return(-1); + } + strcpy(cmd_data, original_cmd); + *cmd= cmd_data; + if(strcmp(*cmd, xorriso->list_delimiter)==0) + return(1); + while((*cmd)[0]=='-') { + if((*cmd)[1]==0) + break; + was_dashed++; + (*cmd)++; + } + for(dash_pt= *cmd; *dash_pt!=0; dash_pt++) + if(*dash_pt=='-') + *dash_pt= '_'; + return(was_dashed); +} + + +/* @param flag bit0= do not warn of unknown option + @return <=0 error, + 1=count is valid, 2=dashed unknown, 3=undashed unknown +*/ +int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv, + int *count, int flag) +{ + int ret, was_dashed= 0, i; + char *cmd, cmd_data[2*SfileadrL]; + static char arg0_commands[][40]= { + "ban_stdio_write","close_filter_list","commit","devices","end", + "for_backup", "help", + "list_formats","no_rc","print_size","pvd_info","pwd","pwdi","pwdx", + "rollback","rollback_end","tell_media_space","toc","version", + "" + }; + static char arg1_commands[][40]= { + "abort_on","acl","add_plainly","application_id","auto_charset", + "backslash_codes","blank", + "calm_drive","cd","cdi","cdx","charset","close", + "commit_eject","compliance", + "dev","dialog","disk_dev_ino","disk_pattern","dummy","dvd_obs","eject", + "iso_rr_pattern","follow","format","fs","gid","grow_blindly","hardlinks", + "history","indev","in_charset","joliet", + "list_delimiter","list_profiles","local_charset", + "mark","md5","mount_opts","not_leaf","not_list","not_mgt", + "options_from_file","osirrox","outdev","out_charset","overwrite", + "pacifier","padding","path_list","pathspecs","pkt_output","print","prompt", + "prog","prog_help","publisher","quoted_not_list","quoted_path_list", + "reassure","report_about","rom_toc_scan","scsi_log", + "session_log","speed","split_size","status","status_history_max", + "stdio_sync","stream_recording","system_id","temp_mem_limit", + "uid","unregister_filter","use_readline","volid","volset_id", + "xattr","zisofs", + "" + }; + static char arg2_commands[][40]= { + "assert_volid","boot_image","compare","compare_r","drive_class", + "errfile_log","error_behavior","extract","extract_single", + "load","logfile", + "map","map_single","page","return_with", + "scdbackup_tag","update","update_r","volume_date", + "" + }; + static char arg4_commands[][40]= { + "cut_out","extract_cut","mount","mount_cmd","paste_in","session_string", + "" + }; + static char argn_commands[][40]= { + "add","alter_date","alter_date_r","as", + "check_md5","check_md5_r","check_media","check_media_defaults", + "chgrp","chgrpi","chgrp_r","chgrp_ri","chmod","chmodi", + "chmod_r","chmod_ri","chown","chowni","chown_r","chown_ri", + "compare_l","cpr","cpri","cp_rax","cp_rx","cpax","cpx", + "du","dui","dus","dusi","dux","dusx","external_filter","extract_l", + "file_size_limit","find","findi","finds","findx", + "getfacl","getfacli","getfacl_r","getfacl_ri", + "getfattr","getfattri","getfattr_r","getfattr_ri", + "ls","lsi","lsl","lsli","lsd","lsdi","lsdl","lsdli", + "lsx","lslx","lsdx","lsdlx","map_l","mv","mvi","mkdir","mkdiri", + "not_paths","rm","rmi","rm_r","rm_ri","rmdir","rmdiri","update_l", + "setfacl","setfacli","setfacl_list","setfacl_listi", + "setfacl_r","setfacl_ri","setfattr","setfattri", + "setfattr_list","setfattr_listi","setfattr_r","setfattr_ri", + "set_filter","set_filter_r","show_stream","show_stream_r", + "" + }; + + *count= 0; + if(argc<=0) + return(-1); + ret= Xorriso_normalize_command(xorriso, argv[0], -1, + cmd_data, sizeof(cmd_data), &cmd, 0); + if(ret<0) + return(ret); + was_dashed= (ret>0); + if(cmd[0]=='#' || cmd[0]==0 || strcmp(cmd, xorriso->list_delimiter) == 0) { + /* ignore: comment line , empty option , orphaned list delimiter */ + return(1); + } + for(i=0; arg0_commands[i][0]!=0; i++) + if(strcmp(arg0_commands[i], cmd)==0) + return(1); + *count= 1; + for(i=0; arg1_commands[i][0]!=0; i++) + if(strcmp(arg1_commands[i], cmd)==0) + return(1); + *count= 2; + for(i=0; arg2_commands[i][0]!=0; i++) + if(strcmp(arg2_commands[i], cmd)==0) + return(1); + *count= 4; + for(i=0; arg4_commands[i][0]!=0; i++) + if(strcmp(arg4_commands[i], cmd)==0) + return(1); + *count= 0; + for(i=0; argn_commands[i][0]!=0; i++) + if(strcmp(argn_commands[i], cmd)==0) { + ret= Xorriso_end_idx(xorriso, argc, argv, 1, 1); + if(ret<1) + return(ret); + *count= ret-1; + return(1); + } + + if(!(flag&1)) { + sprintf(xorriso->info_text, "Unknown option : '%s'", argv[0]); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + } + + return(2+!was_dashed); +} + + +/* @param flag bit0= recursion + bit1= these are command line arguments + (for xorriso->argument_emulation) +*/ +int Xorriso_interpreter(struct XorrisO *xorriso, + int argc, char **argv, int *idx, int flag) +/* +return: + <=0 error , 1 = success , 2 = problem event ignored , 3 = end program run +*/ +{ + int ret, was_dashed, end_ret, num1, num2; + char *cmd, *original_cmd, cmd_data[2*SfileadrL], *arg1, *arg2; + + if(xorriso==NULL) + return(0); + if(xorriso->is_dialog) { + xorriso->result_line_counter= xorriso->result_page_counter= 0; + if(xorriso->result_page_length<0) + xorriso->result_page_length= -xorriso->result_page_length; + } + +next_command:; + if(flag&2) { + ret= 1; + if(xorriso->argument_emulation==1) + ret= Xorriso_as_genisofs(xorriso, argc, argv, idx, 0); + else if(xorriso->argument_emulation==2) + ret= Xorriso_as_cdrskin(xorriso, argc, argv, idx, 0); + if(xorriso->argument_emulation>0) { + xorriso->argument_emulation= 0; + if(ret<=0) + goto eval_any_problems; + if((*idx)>=argc) + {ret= 1; goto ex;} + } + } + + xorriso->prepended_wd= 0; + xorriso->request_to_abort= xorriso->request_not_to_ask= 0; + Xorriso_set_problem_status(xorriso, "", 0); + if((*idx)add_plainly==3 && cmd[0] && !xorriso->is_dialog) { + (*idx)++; + goto add_plain_argument; + } + was_dashed= 0; + + ret= Xorriso_normalize_command(xorriso, original_cmd, -1, + cmd_data, sizeof(cmd_data), &cmd, 0); + if(ret<0) + goto eval_any_problems; + was_dashed= ret; + + (*idx)++; + if((*idx)10); + + } else if(strcmp(cmd,"application_id")==0) { + (*idx)++; + ret= Xorriso_option_application_id(xorriso, arg1, 0); + + } else if(strcmp(cmd,"as")==0) { + ret= Xorriso_option_as(xorriso, argc, argv, idx, 0); + + } else if(strcmp(cmd,"assert_volid")==0) { + (*idx)+= 2; + ret= Xorriso_option_assert_volid(xorriso, arg1, arg2, 0); + + } else if(strcmp(cmd,"auto_charset")==0) { + (*idx)++; + ret= Xorriso_option_auto_charset(xorriso, arg1, 0); + + } else if(strcmp(cmd,"backslash_codes")==0) { + (*idx)++; + ret= Xorriso_option_backslash_codes(xorriso, arg1, 0); + + } else if(strcmp(cmd,"ban_stdio_write")==0) { + ret= Xorriso_option_ban_stdio_write(xorriso, 0); + + } else if(strcmp(cmd,"blank")==0) { + (*idx)++; + ret= Xorriso_option_blank(xorriso, arg1, 0); + + } else if(strcmp(cmd,"boot_image")==0) { + (*idx)+= 2; + ret= Xorriso_option_boot_image(xorriso, arg1, arg2, 0); + + } else if(strcmp(cmd,"calm_drive")==0) { + (*idx)++; + ret= Xorriso_option_calm_drive(xorriso, arg1, 0); + + } else if(strcmp(cmd,"cd")==0 || strcmp(cmd,"cdi")==0) { + (*idx)++; + ret= Xorriso_option_cdi(xorriso, arg1, 0); + + } else if(strcmp(cmd,"cdx")==0) { + (*idx)++; + ret= Xorriso_option_cdx(xorriso, arg1, 0); + + } else if(strcmp(cmd,"charset")==0) { + (*idx)++; + ret= Xorriso_option_charset(xorriso, arg1, 3); + + } else if(strcmp(cmd,"check_md5")==0) { + ret= Xorriso_option_check_md5(xorriso, argc, argv, idx, 0); + + } else if(strcmp(cmd,"check_md5_r")==0) { + ret= Xorriso_option_check_md5(xorriso, argc, argv, idx, 8); + + } else if(strcmp(cmd,"check_media")==0) { + ret= Xorriso_option_check_media(xorriso, argc, argv, idx, 0); + + } else if(strcmp(cmd,"check_media_defaults")==0) { + ret= Xorriso_option_check_media_defaults(xorriso, argc, argv, idx, 0); + + } else if(strcmp(cmd,"chgrp")==0 || strcmp(cmd,"chgrpi")==0) { + (*idx)+= 1; + ret= Xorriso_option_chgrpi(xorriso, arg1, argc, argv, idx, 0); + + } else if(strcmp(cmd,"chgrp_r")==0 || strcmp(cmd,"chgrp_ri")==0) { + (*idx)+= 1; + ret= Xorriso_option_chgrpi(xorriso, arg1, argc, argv, idx, 1); + + } else if(strcmp(cmd,"chmod")==0 || strcmp(cmd,"chmodi")==0) { + (*idx)+= 1; + ret= Xorriso_option_chmodi(xorriso, arg1, argc, argv, idx, 0); + + } else if(strcmp(cmd,"chmod_r")==0 || strcmp(cmd,"chmod_ri")==0) { + (*idx)+= 1; + ret= Xorriso_option_chmodi(xorriso, arg1, argc, argv, idx, 1); + + } else if(strcmp(cmd,"chown_r")==0 || strcmp(cmd,"chown_ri")==0) { + (*idx)+= 1; + ret= Xorriso_option_chowni(xorriso, arg1, argc, argv, idx, 1); + + } else if(strcmp(cmd,"chown")==0 || strcmp(cmd,"chowni")==0) { + (*idx)+= 1; + ret= Xorriso_option_chowni(xorriso, arg1, argc, argv, idx, 0); + + } else if(strcmp(cmd,"close")==0) { + (*idx)++; + ret= Xorriso_option_close(xorriso, arg1, 0); + + } else if(strcmp(cmd,"close_filter_list")==0) { + ret= Xorriso_option_close_filter_list(xorriso, 0); + + } else if(strcmp(cmd,"commit")==0) { + ret= Xorriso_option_commit(xorriso, 0); + + } else if(strcmp(cmd,"commit_eject")==0) { + (*idx)++; + ret= Xorriso_option_commit_eject(xorriso, arg1, 0); + + } else if(strcmp(cmd,"compare")==0) { + (*idx)+= 2; + ret= Xorriso_option_compare(xorriso, arg1, arg2, 1); + + } else if(strcmp(cmd,"compare_l")==0) { + ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 1<<8); + + } else if(strcmp(cmd,"compare_r")==0) { + (*idx)+= 2; + ret= Xorriso_option_compare(xorriso, arg1, arg2, 1|8); + + } else if(strcmp(cmd,"compliance")==0) { + (*idx)++; + Xorriso_option_compliance(xorriso, arg1, 0); + + } else if(strcmp(cmd,"cpr")==0 || strcmp(cmd,"cpri")==0) { + ret= Xorriso_option_cpri(xorriso, argc, argv, idx, 0); + + } else if(strcmp(cmd,"cp_rx")==0 || strcmp(cmd,"cp_rax")==0) { + ret= Xorriso_option_cpx(xorriso, argc, argv, idx, + 1|((strcmp(cmd,"cp_rax")==0)<<1)); + + } else if(strcmp(cmd,"cpx")==0 || strcmp(cmd,"cpax")==0) { + ret= Xorriso_option_cpx(xorriso, argc, argv, idx, + (strcmp(cmd,"cpax")==0)<<1); + + } else if(strcmp(cmd,"cut_out")==0) { + (*idx)+= 4; + if((*idx)>argc) { + sprintf(xorriso->info_text, + "-cut_out: Not enough arguments. Needed are: disk_path start count so_rr_path"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; + } else + ret= Xorriso_option_cut_out(xorriso, arg1, arg2, + argv[(*idx)-2], argv[(*idx)-1], 0); + + } else if(strcmp(cmd,"dev")==0) { + (*idx)++; + ret= Xorriso_option_dev(xorriso, arg1, 3); + + } else if(strcmp(cmd,"devices")==0) { + ret= Xorriso_option_devices(xorriso, 0); + + } else if(strcmp(cmd,"dialog")==0) { + (*idx)++; + ret= Xorriso_option_dialog(xorriso, arg1, 0); + + } else if(strcmp(cmd,"disk_dev_ino")==0) { + (*idx)++; + ret= Xorriso_option_disk_dev_ino(xorriso, arg1, 0); + + } else if(strcmp(cmd,"disk_pattern")==0) { + (*idx)++; + ret= Xorriso_option_disk_pattern(xorriso, arg1, 0); + + } else if(strcmp(cmd,"drive_class")==0) { + (*idx)+= 2; + ret= Xorriso_option_drive_class(xorriso, arg1, arg2, 0); + + } else if(strcmp(cmd,"du")==0 || strcmp(cmd,"dui")==0 || + strcmp(cmd,"dus")==0 || strcmp(cmd,"dusi")==0) { + ret= Xorriso_option_lsi(xorriso, argc, argv, idx, (cmd[2]!='s')|4); + + } else if(strcmp(cmd,"dummy")==0) { + (*idx)++; + ret= Xorriso_option_dummy(xorriso, arg1, 0); + + } else if(strcmp(cmd,"dvd_obs")==0) { + (*idx)++; + ret= Xorriso_option_dvd_obs(xorriso, arg1, 0); + + } else if(strcmp(cmd,"dux")==0 || strcmp(cmd,"dusx")==0) { + ret= Xorriso_option_lsx(xorriso, argc, argv, idx, (cmd[2]!='s')|4); + + } else if(strcmp(cmd,"eject")==0) { + (*idx)++; + ret= Xorriso_option_eject(xorriso, arg1, 0); + + } else if(strcmp(cmd,"end")==0) { + end_ret= Xorriso_option_end(xorriso, 0); + ret= Xorriso_eval_problem_status(xorriso, ret, 0); + if(ret<0) + return(ret); + if(end_ret!=2) + {ret= 3; goto ex;} + + } else if(strcmp(cmd,"errfile_log")==0) { + (*idx)+= 2; + ret= Xorriso_option_errfile_log(xorriso, arg1, arg2, 0); + + } else if(strcmp(cmd,"error_behavior")==0) { + (*idx)+= 2; + ret= Xorriso_option_error_behavior(xorriso, arg1, arg2, 0); + + } else if(strcmp(cmd,"external_filter")==0) { + ret= Xorriso_option_external_filter(xorriso, argc, argv, idx, 0); + + } else if(strcmp(cmd,"extract")==0) { + (*idx)+= 2; + ret= Xorriso_option_extract(xorriso, arg1, arg2, 0); + + } else if(strcmp(cmd,"extract_cut")==0) { + (*idx)+= 4; + if((*idx)>argc) { + sprintf(xorriso->info_text, + "-extract_cut: Not enough arguments. Needed are: disk_path start count so_rr_path"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; + } else + ret= Xorriso_option_extract_cut(xorriso, arg1, arg2, + argv[(*idx)-2], argv[(*idx)-1], 0); + + } else if(strcmp(cmd,"extract_l")==0) { + ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 3<<8); + + } else if(strcmp(cmd,"extract_single")==0) { + (*idx)+= 2; + ret= Xorriso_option_extract(xorriso, arg1, arg2, 32); + + } else if(strcmp(cmd,"file_size_limit")==0) { + ret= Xorriso_option_file_size_limit(xorriso, argc, argv, idx, 0); + + } else if(strcmp(cmd,"find")==0 || strcmp(cmd,"findi")==0) { + ret= Xorriso_option_find(xorriso, argc, argv, idx, 0); + + } else if(strcmp(cmd,"findx")==0) { + ret= Xorriso_option_find(xorriso, argc, argv, idx, 1); + + } else if(strcmp(cmd,"follow")==0) { + (*idx)++; + ret= Xorriso_option_follow(xorriso, arg1, 0); + + } else if(strcmp(cmd,"for_backup")==0) { + Xorriso_option_hardlinks(xorriso, "on", 0); + Xorriso_option_acl(xorriso, "on", 0); + Xorriso_option_xattr(xorriso, "on", 0); + Xorriso_option_md5(xorriso, "on", 0); + ret= 1; + + } else if(strcmp(cmd,"format")==0) { + (*idx)++; + ret= Xorriso_option_blank(xorriso, arg1, 1); + + } else if(strcmp(cmd,"fs")==0) { + (*idx)++; + ret= Xorriso_option_fs(xorriso, arg1, 0); + + } else if(strcmp(cmd,"getfacl")==0 || strcmp(cmd,"getfacli")==0) { + ret= Xorriso_option_getfacli(xorriso, argc, argv, idx, 0); + + } else if(strcmp(cmd,"getfacl_r")==0 || strcmp(cmd,"getfacl_ri")==0) { + ret= Xorriso_option_getfacli(xorriso, argc, argv, idx, 1); + + } else if(strcmp(cmd,"getfattr")==0 || strcmp(cmd,"getfattri")==0) { + ret= Xorriso_option_getfacli(xorriso, argc, argv, idx, 2); + + } else if(strcmp(cmd,"getfattr_r")==0 || strcmp(cmd,"getfattr_ri")==0) { + ret= Xorriso_option_getfacli(xorriso, argc, argv, idx, 1 | 2); + + } else if(strcmp(cmd,"gid")==0) { + (*idx)++; + ret= Xorriso_option_gid(xorriso,arg1,0); + + } else if(strcmp(cmd,"grow_blindly")==0) { + (*idx)++; + ret= Xorriso_option_grow_blindly(xorriso,arg1,0); + + } else if(strcmp(cmd,"hardlinks")==0) { + (*idx)++; + ret= Xorriso_option_hardlinks(xorriso, arg1, 0); + + } else if(strcmp(cmd,"help")==0) { + Xorriso_option_help(xorriso,0); + + } else if(strcmp(cmd,"history")==0) { + /* add to readline history */ + (*idx)++; + ret= Xorriso_option_history(xorriso, arg1, 0); + + } else if(strcmp(cmd,"indev")==0) { + (*idx)++; + ret= Xorriso_option_dev(xorriso, arg1, 1); + + } else if(strcmp(cmd,"in_charset")==0) { + (*idx)++; + ret= Xorriso_option_charset(xorriso, arg1, 1); + + } else if(strcmp(cmd,"iso_rr_pattern")==0) { + (*idx)++; + ret= Xorriso_option_iso_rr_pattern(xorriso, arg1, 0); + + } else if(strcmp(cmd,"joliet")==0) { + (*idx)++; + ret= Xorriso_option_joliet(xorriso, arg1, 0); + + } else if(strcmp(cmd, "list_delimiter") == 0) { + (*idx)++; + ret= Xorriso_option_list_delimiter(xorriso, arg1, 0); + + } else if(strcmp(cmd,"list_formats")==0) { + ret= Xorriso_option_list_formats(xorriso, 0); + + } else if(strcmp(cmd,"list_profiles")==0) { + (*idx)++; + ret= Xorriso_option_list_profiles(xorriso, arg1, 0); + + } else if(strcmp(cmd,"load")==0) { + (*idx)+= 2; + ret= Xorriso_option_load(xorriso, arg1, arg2, 0); + + } else if(strcmp(cmd,"local_charset")==0) { + (*idx)++; + ret= Xorriso_option_charset(xorriso, arg1, 4); + + } else if(strcmp(cmd,"logfile")==0) { + (*idx)+= 2; + ret= Xorriso_option_logfile(xorriso, arg1, arg2, 0); + + } else if(strcmp(cmd,"ls")==0 || strcmp(cmd,"lsi")==0 || + strcmp(cmd,"lsl")==0 || strcmp(cmd,"lsli")==0) { + ret= Xorriso_option_lsi(xorriso, argc, argv, idx, (cmd[2]=='l')); + + } else if(strcmp(cmd,"lsd")==0 || strcmp(cmd,"lsdi")==0 || + strcmp(cmd,"lsdl")==0 || strcmp(cmd,"lsdli")==0) { + ret= Xorriso_option_lsi(xorriso, argc, argv, idx, (cmd[3]=='l')|8); + + } else if(strcmp(cmd,"lsdx")==0 || strcmp(cmd,"lsdlx")==0) { + ret= Xorriso_option_lsx(xorriso, argc, argv, idx, (cmd[3]=='l')|8); + + } else if(strcmp(cmd,"lsx")==0 || strcmp(cmd,"lslx")==0) { + ret= Xorriso_option_lsx(xorriso, argc, argv, idx, (cmd[2]=='l')); + + } else if(strcmp(cmd,"map")==0) { + (*idx)+= 2; + ret= Xorriso_option_map(xorriso, arg1, arg2, 0); + + } else if(strcmp(cmd,"map_l")==0) { + ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 0); + + } else if(strcmp(cmd,"map_single")==0) { + (*idx)+= 2; + ret= Xorriso_option_map(xorriso, arg1, arg2, 32); + + } else if(strcmp(cmd,"mark")==0) { + (*idx)++; + ret= Xorriso_option_mark(xorriso, arg1, 0); + + } else if(strcmp(cmd, "md5")==0) { + (*idx)++; + ret= Xorriso_option_md5(xorriso, arg1, 0); + + } else if(strcmp(cmd, "mount") == 0 || strcmp(cmd, "mount_cmd") == 0) { + (*idx)+= 4; + if((*idx)>argc) { + sprintf(xorriso->info_text, + "-%s: Not enough arguments. Needed are: device entity id command", + cmd); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; + } else + ret= Xorriso_option_mount(xorriso, arg1, arg2, + argv[(*idx)-2], argv[(*idx)-1], + (strcmp(cmd, "mount_cmd") == 0)); + + } else if(strcmp(cmd, "mount_opts")==0) { + (*idx)++; + ret= Xorriso_option_mount_opts(xorriso, arg1, 0); + + } else if(strcmp(cmd,"mv")==0 || strcmp(cmd,"mvi")==0) { + ret= Xorriso_option_mvi(xorriso, argc, argv, idx, 0); + + } else if(strcmp(cmd,"mkdir")==0 || strcmp(cmd,"mkdiri")==0) { + ret= Xorriso_option_mkdiri(xorriso, argc, argv, idx, 0); + + } else if(strcmp(cmd,"no_rc")==0) { + ret= Xorriso_option_no_rc(xorriso, 0); + + } else if(strcmp(cmd,"not_leaf")==0) { + (*idx)++; + ret= Xorriso_option_not_leaf(xorriso, arg1, 0); + + } else if(strcmp(cmd,"not_list")==0) { + (*idx)++; + ret= Xorriso_option_not_list(xorriso, arg1, 0); + + } else if(strcmp(cmd,"not_mgt")==0) { + (*idx)++; + ret= Xorriso_option_not_mgt(xorriso, arg1, 0); + + } else if(strcmp(cmd,"not_paths")==0) { + ret= Xorriso_option_not_paths(xorriso, argc, argv, idx, 0); + + } else if(strcmp(cmd,"options_from_file")==0) { + (*idx)++; + ret= Xorriso_option_options_from_file(xorriso,arg1,0); + if(ret==3) + goto ex; + + } else if(strcmp(cmd,"osirrox")==0) { + (*idx)++; + ret= Xorriso_option_osirrox(xorriso,arg1,0); + + } else if(strcmp(cmd,"outdev")==0) { + (*idx)++; + ret= Xorriso_option_dev(xorriso, arg1, 2); + + } else if(strcmp(cmd,"out_charset")==0) { + (*idx)++; + ret= Xorriso_option_charset(xorriso, arg1, 2); + + } else if(strcmp(cmd,"overwrite")==0) { + (*idx)++; + ret= Xorriso_option_overwrite(xorriso,arg1,0); + + } else if(strcmp(cmd,"pacifier")==0) { + (*idx)++; + ret= Xorriso_option_pacifier(xorriso, arg1, 0); + + } else if(strcmp(cmd,"padding")==0) { + (*idx)++; + ret= Xorriso_option_padding(xorriso, arg1, 0); + + } else if(strcmp(cmd,"page")==0) { + (*idx)+= 2; + num1= num2= 0; + sscanf(arg1,"%d",&num1); + sscanf(arg2,"%d",&num2); + if(num1<0) + num1= 0; + if(arg1[0]==0) + num1= 16; + if(num2<=0) + num2= 80; + ret= Xorriso_option_page(xorriso, num1, num2, 0); + + } else if(strcmp(cmd,"paste_in")==0) { + (*idx)+= 4; + if((*idx)>argc) { + sprintf(xorriso->info_text, + "-paste_in: Not enough arguments. Needed are: disk_path start count so_rr_path"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; + } else + ret= Xorriso_option_paste_in(xorriso, arg1, arg2, + argv[(*idx)-2], argv[(*idx)-1], 0); + + } else if(strcmp(cmd,"path-list")==0 || strcmp(cmd,"path_list")==0) { + (*idx)++; + ret= Xorriso_option_path_list(xorriso, arg1, 0); + + } else if(strcmp(cmd,"pathspecs")==0) { + (*idx)++; + ret= Xorriso_option_pathspecs(xorriso, arg1, 0); + + } else if(strcmp(cmd,"pkt_output")==0) { + (*idx)++; + ret= Xorriso_option_pkt_output(xorriso, arg1, 0); + + } else if(strcmp(cmd,"print")==0) { + (*idx)++; + ret= Xorriso_option_print(xorriso, arg1, 0); + + } else if(strcmp(cmd,"print_size")==0) { + Xorriso_option_print_size(xorriso, 0); + + } else if(strcmp(cmd,"prompt")==0) { + (*idx)++; + ret= Xorriso_option_prompt(xorriso, arg1, 0); + + } else if(strcmp(cmd,"prog")==0) { + (*idx)++; + ret= Xorriso_option_prog(xorriso, arg1, 0); + + } else if(strcmp(cmd,"publisher")==0) { + (*idx)++; + Xorriso_option_publisher(xorriso, arg1, 0); + + } else if(strcmp(cmd,"pvd_info")==0) { + Xorriso_option_pvd_info(xorriso, 0); + + } else if(strcmp(cmd,"pwd")==0 || strcmp(cmd,"pwdi")==0) { + Xorriso_option_pwdi(xorriso, 0); + + } else if(strcmp(cmd,"pwdx")==0) { + Xorriso_option_pwdx(xorriso, 0); + + } else if(strcmp(cmd,"quoted_not_list")==0) { + (*idx)++; + ret= Xorriso_option_not_list(xorriso, arg1, 1); + + } else if(strcmp(cmd,"quoted_path_list")==0) { + (*idx)++; + ret= Xorriso_option_path_list(xorriso, arg1, 1); + + } else if(strcmp(cmd,"reassure")==0) { + (*idx)++; + ret= Xorriso_option_reassure(xorriso, arg1, 0); + + } else if(strcmp(cmd,"report_about")==0) { + (*idx)++; + ret= Xorriso_option_report_about(xorriso, arg1, 0); + + } else if(strcmp(cmd,"return_with")==0) { + (*idx)+= 2; + num2= 0; + sscanf(arg2,"%d",&num2); + ret= Xorriso_option_return_with(xorriso, arg1, num2, 0); + + } else if(strcmp(cmd,"rm")==0 || strcmp(cmd,"rmi")==0) { + ret= Xorriso_option_rmi(xorriso, argc, argv, idx, 0); + + } else if(strcmp(cmd,"rm_r")==0 || strcmp(cmd,"rm_ri")==0) { + ret= Xorriso_option_rmi(xorriso, argc, argv, idx, 1); + + } else if(strcmp(cmd,"rmdir")==0 || strcmp(cmd,"rmdiri")==0) { + ret= Xorriso_option_rmi(xorriso, argc, argv, idx, 2); + + } else if(strcmp(cmd,"rollback")==0) { + ret= Xorriso_option_rollback(xorriso, 0); + + } else if(strcmp(cmd,"rollback_end")==0) { + end_ret= Xorriso_option_end(xorriso, 1); + ret= Xorriso_eval_problem_status(xorriso, ret, 0); + if(ret<0) + return(ret); + if(end_ret!=2) + {ret= 3; goto ex;} + + } else if(strcmp(cmd,"rom_toc_scan")==0) { + (*idx)++; + Xorriso_option_rom_toc_scan(xorriso, arg1, 0); + + } else if(strcmp(cmd,"scdbackup_tag")==0) { + (*idx)+= 2; + ret= Xorriso_option_scdbackup_tag(xorriso, arg1, arg2, 0); + + } else if(strcmp(cmd, "scsi_log") == 0) { + (*idx)++; + ret= Xorriso_option_scsi_log(xorriso, arg1, 0); + + } else if(strcmp(cmd,"session_log")==0) { + (*idx)++; + ret= Xorriso_option_session_log(xorriso, arg1, 0); + + } else if(strcmp(cmd, "session_string") == 0) { + (*idx)+= 4; + if((*idx)>argc) { + sprintf(xorriso->info_text, + "-%s: Not enough arguments. Needed are: device entity id command", + cmd); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; + } else + ret= Xorriso_option_mount(xorriso, arg1, arg2, + argv[(*idx)-2], argv[(*idx)-1], 2); + + } else if(strcmp(cmd,"setfacl")==0 || strcmp(cmd,"setfacli")==0) { + (*idx)+= 1; + ret= Xorriso_option_setfacli(xorriso, arg1, argc, argv, idx, 0); + + } else if(strcmp(cmd,"setfacl_list")==0 || strcmp(cmd,"setfacl_listi")==0) { + (*idx)+= 1; + ret= Xorriso_option_setfacl_listi(xorriso, arg1, 0); + + } else if(strcmp(cmd,"setfacl_r")==0 || strcmp(cmd,"setfacl_ri")==0) { + (*idx)+= 1; + ret= Xorriso_option_setfacli(xorriso, arg1, argc, argv, idx, 1); + + } else if(strcmp(cmd,"setfattr")==0 || strcmp(cmd,"setfattri")==0) { + (*idx)+= 2; + ret= Xorriso_option_setfattri(xorriso, arg1, arg2, argc, argv, idx, 0); + + } else if(strcmp(cmd,"setfattr_list")==0 || strcmp(cmd,"setfattr_listi")==0) { + (*idx)+= 1; + ret= Xorriso_option_setfattr_listi(xorriso, arg1, 0); + + } else if(strcmp(cmd,"setfattr_r")==0 || strcmp(cmd,"setfattr_ri")==0) { + (*idx)+= 2; + ret= Xorriso_option_setfattri(xorriso, arg1, arg2, argc, argv, idx, 1); + + } else if(strcmp(cmd,"set_filter")==0 || strcmp(cmd,"set_filter_r")==0) { + (*idx)+= 1; + ret= Xorriso_option_set_filter(xorriso, arg1, argc, argv, idx, + strcmp(cmd,"set_filter_r")==0); + + } else if(strcmp(cmd,"show_stream")==0 || strcmp(cmd,"show_stream_r")==0) { + ret= Xorriso_option_set_filter(xorriso, "", argc, argv, idx, + (strcmp(cmd,"show_stream_r")==0) | 2 | 4); + + } else if(strcmp(cmd,"speed")==0) { + (*idx)++; + ret= Xorriso_option_speed(xorriso, arg1, 0); + + } else if(strcmp(cmd,"split_size")==0) { + (*idx)++; + ret= Xorriso_option_split_size(xorriso, arg1, 0); + + } else if(strcmp(cmd,"status")==0) { + (*idx)++; + ret= Xorriso_option_status(xorriso, arg1, 0); + + } else if(strcmp(cmd,"status_history_max")==0) { + (*idx)++; + sscanf(arg1,"%d",&num1); + ret= Xorriso_option_status_history_max(xorriso, num1, 0); + + } else if(strcmp(cmd,"stdio_sync")==0) { + (*idx)++; + ret= Xorriso_option_stdio_sync(xorriso, arg1, 0); + + } else if(strcmp(cmd,"stream_recording")==0) { + (*idx)++; + ret= Xorriso_option_stream_recording(xorriso, arg1, 0); + + } else if(strcmp(cmd,"system_id")==0) { + (*idx)++; + ret= Xorriso_option_system_id(xorriso, arg1, 0); + + } else if(strcmp(cmd,"tell_media_space")==0) { + Xorriso_option_tell_media_space(xorriso, 0); + + } else if(strcmp(cmd,"temp_mem_limit")==0) { + (*idx)++; + ret= Xorriso_option_temp_mem_limit(xorriso, arg1, 0); + + } else if(strcmp(cmd,"test")==0) { /* This option does not exist. */ + + /* install temporary test code here */; + + } else if(strcmp(cmd,"toc")==0) { + Xorriso_option_toc(xorriso, 0); + + } else if(strcmp(cmd,"uid")==0) { + (*idx)++; + ret= Xorriso_option_uid(xorriso,arg1,0); + + } else if(strcmp(cmd,"unregister_filter")==0) { + (*idx)++; + ret= Xorriso_option_unregister_filter(xorriso, arg1, 0); + + } else if(strcmp(cmd,"update")==0) { + (*idx)+= 2; + ret= Xorriso_option_update(xorriso, arg1, arg2, 1); + + } else if(strcmp(cmd,"update_l")==0) { + ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 2<<8); + + } else if(strcmp(cmd,"update_r")==0) { + (*idx)+= 2; + ret= Xorriso_option_update(xorriso, arg1, arg2, 1|8); + + } else if(strcmp(cmd,"use_readline")==0) { + (*idx)++; + ret= Xorriso_option_use_readline(xorriso, arg1, 0); + + } else if(strcmp(cmd,"version")==0){ + ret= Xorriso_option_version(xorriso, 0); + + } else if(strcmp(cmd,"volset_id")==0) { + (*idx)++; + ret= Xorriso_option_volset_id(xorriso, arg1, 0); + + } else if(strcmp(cmd,"volid")==0) { + (*idx)++; + ret= Xorriso_option_volid(xorriso,arg1,0); + + } else if(strcmp(cmd,"volume_date")==0) { + (*idx)+= 2; + ret= Xorriso_option_volume_date(xorriso, arg1, arg2, 0); + + } else if(strcmp(cmd,"xattr")==0) { + (*idx)++; + ret= Xorriso_option_xattr(xorriso, arg1, 0); + + } else if(strcmp(cmd,"zisofs")==0) { + (*idx)++; + ret= Xorriso_option_zisofs(xorriso, arg1, 0); + + } else if(strcmp(cmd, xorriso->list_delimiter)==0){ + /* tis ok */; + + } else if(was_dashed) { + if(xorriso->add_plainly>1) + goto add_plain_argument; +unknown_option:; + sprintf(xorriso->info_text, "Not a known option: '%s'\n", + original_cmd); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto eval_any_problems;} + + } else { + if(xorriso->add_plainly<=0) + goto unknown_option; +add_plain_argument:; + (*idx)--; + ret= Xorriso_option_add(xorriso, (*idx)+1, argv, idx, 0); + (*idx)++; + + } + +eval_any_problems: + ret= Xorriso_eval_problem_status(xorriso, ret, 0); + if(ret<0) + return(ret); + + if(*idxis_dialog) && !(flag&1)) + Xorriso_mark(xorriso,0); + fflush(stdout); + return(ret); +} + + +int Xorriso_execute_option(struct XorrisO *xorriso, char *line, int flag) +/* + bit0-bit15 are forwarded to Xorriso_interpreter + + bit16= no pageing of info lines + bit17= print === bar even if xorriso->found<0 +*/ +{ + int ret,argc= 0, idx= 1; + char **argv= NULL; + double tdiff; + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv,&tz); + Xorriso_reset_counters(xorriso,0); + xorriso->idle_time= 0.0; + tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec); + + /* parse line into args */ + ret= Sfile_make_argv(xorriso->progname, line, &argc, &argv, + 4 | ((xorriso->bsl_interpretation & 3) << 5)); + if(ret < 0) { + Xorriso_msgs_submit(xorriso, 0, + "Severe lack of resources during command line parsing", 0, "FATAL", 0); + goto ex; + } + if(ret == 0) { + sprintf(xorriso->info_text, "Incomplete quotation in command line: %s", + line); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + goto ex; + } + if(argc<2) + {ret= 1; goto ex;} + if(argv[1][0]=='#') + {ret= 1; goto ex;} + + ret= Xorriso_interpreter(xorriso, argc, argv, &idx, flag&0xffff); + if(ret<0) + goto ex; + gettimeofday(&tv,&tz); + tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec)-tdiff-xorriso->idle_time; + if(tdiff<0.001) + tdiff= 0.001; + if(xorriso->error_count>0) { + sprintf(xorriso->info_text, + "----------------------------- %7.f errors encountered\n", + xorriso->error_count); + Xorriso_info(xorriso,!(flag&(1<<16))); + } + + /* ??? >>> print elapsed time tdiff ? */; + + if((flag&(1<<17)) && !xorriso->bar_is_fresh) { + sprintf(xorriso->info_text,"============================\n"); + Xorriso_info(xorriso,0); + xorriso->bar_is_fresh= 1; + } + Xorriso_reset_counters(xorriso,0); +ex:; + Sfile_make_argv("", "", &argc, &argv, 2); /* release memory */ + return(ret); +} + + +int Xorriso_dialog(struct XorrisO *xorriso, int flag) +{ + int ret,first_round; + char line[2*SfileadrL]; + + if(!xorriso->dialog) + return(1); + xorriso->is_dialog= 1; + for(first_round= 1;1;first_round= 0) { + if(xorriso->pending_option[0]!=0) { + Xorriso_mark(xorriso,0); + strcpy(line,xorriso->pending_option); + xorriso->pending_option[0]= 0; + } else { + if(!xorriso->bar_is_fresh) { + sprintf(xorriso->info_text,"============================\n"); + Xorriso_info(xorriso,0); + xorriso->bar_is_fresh= 1; + } + sprintf(xorriso->info_text,"enter option and arguments :\n"); + Xorriso_info(xorriso,0); + Xorriso_mark(xorriso,0); + ret= Xorriso_dialog_input(xorriso,line,sizeof(line),4); + if(ret<=0) + break; + } + sprintf(xorriso->info_text, + "==============================================================\n"); + Xorriso_info(xorriso,0); + + ret= Xorriso_execute_option(xorriso,line,1<<17); + if(ret<0) + goto ex; + if(ret==3) + goto ex; + xorriso->did_something_useful= 1; + xorriso->no_volset_present= 0; /* Re-enable "No ISO image present." */ + } + ret= 1; +ex:; + xorriso->is_dialog= 0; + return(ret); +} + + +int Xorriso_prescan_args(struct XorrisO *xorriso, int argc, char **argv, + int flag) +/* + bit0= do not interpret argv[1] +*/ +/* + return: + <0 error + 0 end program + 1 ok, go on +*/ +{ + int i, ret, was_dashed, num2, arg_count; + int was_report_about= 0, was_abort_on= 0, was_return_with= 0; + char *cmd, *original_cmd, cmd_data[5*SfileadrL], *arg1, *arg2; + char mem_list_delimiter[81]; + + strcpy(mem_list_delimiter, xorriso->list_delimiter); + for(i=1+(flag&1);i1) + xorriso->did_something_useful= 1; + if(i==1 && argc==2) { + if(strcmp(cmd,"prog_help")==0) { + i++; + Xorriso_option_prog_help(xorriso,arg1,0); + xorriso->did_something_useful= 1; + {ret= 0; goto ex;} + } else if(strcmp(cmd,"help")==0) { + if(xorriso->argument_emulation == 1) { + Xorriso_genisofs_help(xorriso, 0); + } else if(xorriso->argument_emulation == 2) { + Xorriso_cdrskin_help(xorriso, 0); + } else { + Xorriso_option_help(xorriso,0); + } + xorriso->did_something_useful= 1; + {ret= 0; goto ex;} + } + } else if(i==1 && strcmp(cmd,"no_rc")==0) { + ret= Xorriso_option_no_rc(xorriso, 0); + if(ret<=0) + goto ex; + + } else if((strcmp(cmd,"dev")==0 || strcmp(cmd,"outdev")==0 || + strcmp(cmd,"indev")==0) && + (strcmp(arg1,"stdio:/dev/fd/1")==0 || strcmp(arg1,"-")==0) && + xorriso->dev_fd_1<0) { + /* Detach fd 1 from externally perceived stdout and attach it to stderr. + Keep dev_fd_1 connected to external stdout. dev_fd_1 is to be used when + "stdio:/dev/fd/1" is interpreted as drive address. + */ +protect_stdout:; + Xorriso_protect_stdout(xorriso, 0); + sprintf(xorriso->info_text, + "Encountered - or stdio:/dev/fd/1 as possible write target."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + sprintf(xorriso->info_text, + "Redirecting nearly all text message output to stderr."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + sprintf(xorriso->info_text, "Disabling use of libreadline."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + + } else if(strcmp(cmd,"abort_on")==0 && was_dashed == 1) { + i++; + if(!was_abort_on) + Xorriso_option_abort_on(xorriso, arg1, 0); + was_abort_on= 1; + + } else if(strcmp(cmd,"report_about")==0 && was_dashed == 1) { + i++; + if(!was_report_about) + Xorriso_option_report_about(xorriso, arg1, 0); + was_report_about= 1; + + } else if(strcmp(cmd,"return_with")==0 && was_dashed == 1) { + i+= 2; + num2= 0; + sscanf(arg2,"%d",&num2); + if(!was_return_with) + Xorriso_option_return_with(xorriso, arg1, num2, 0); + was_return_with= 1; + + } else if(strcmp(cmd,"as")==0 && was_dashed == 1) { + if(strcmp(arg1, "mkisofs")==0 || strcmp(arg1, "genisoimage")==0 || + strcmp(arg1, "genisofs")==0 || strcmp(arg1, "xorrisofs")==0) + goto protect_stdout; + + } else if(strcmp(cmd, "list_delimiter") == 0) { + /* Needed for interpreting other args. Gets reset after prescan. */ + i++; + ret= Xorriso_option_list_delimiter(xorriso, arg1, 0); + if(ret <= 0) + goto ex; + + } else if(strcmp(cmd, "scsi_log") == 0 && was_dashed == 1) { + i++; + Xorriso_option_scsi_log(xorriso, arg1, 0); + + } else { + ret= Xorriso_count_args(xorriso, argc-i, argv+i, &arg_count, 1); + if(ret==1) + i+= arg_count; + } + } + ret= 1; +ex:; + strcpy(xorriso->list_delimiter, mem_list_delimiter); + return(ret); +} + + +int Xorriso_read_rc(struct XorrisO *xorriso, int flag) +{ + int ret,i,was_failure= 0,fret; + + if(xorriso->no_rc) + return(1); + i= xorriso->rc_filename_count-1; + Sfile_home_adr_s(".xorrisorc", xorriso->rc_filenames[i], + sizeof(xorriso->rc_filenames[i]),0); + for(i=0;irc_filename_count;i++) { + ret= Sfile_type(xorriso->rc_filenames[i],1|8); + if(ret!=1) + continue; + ret= Xorriso_option_options_from_file(xorriso,xorriso->rc_filenames[i],0); + if(ret>1) + return(ret); + if(ret==1) + continue; /* regular bottom of loop */ + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1); + if(fret>=0) + continue; + return(ret); + } + return(!was_failure); +} + + +int Xorriso_make_return_value(struct XorrisO *xorriso, int flag) +{ + int exit_value= 0; + + if(xorriso->eternal_problem_status >= xorriso->return_with_severity) + exit_value= xorriso->return_with_value; + if(exit_value) { + sprintf(xorriso->info_text, + "-return_with %s %d triggered by problem severity %s", + xorriso->return_with_text, exit_value, + xorriso->eternal_problem_status_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } + return(exit_value); +} + + +int Xorriso_program_arg_bsl(struct XorrisO *xorriso, int argc, char ***argv, + int flag) +{ + int ret; + + if(!(xorriso->bsl_interpretation & 16)) + return(1); + ret= Sfile_argv_bsl(argc, argv, 0); + return(ret); +} + + +/* @param flag bit0= prepend wd only if name does not begin by '/' + bit1= normalize image path + bit2= prepend wd (automatically done if wd[0]!=0) + bit3= (with bit1) this is an address in the disk world +*/ +int Xorriso_make_abs_adr(struct XorrisO *xorriso, char *wd, char *name, + char adr[], int flag) +{ + char norm_adr[SfileadrL]; + int ret; + + if((wd[0]!=0 || (flag&4)) && !((flag&1) && name[0]=='/')) { + if(strlen(wd)+1>=SfileadrL) + goto much_too_long; + strcpy(adr, wd); + if(name[0]) + if(Sfile_add_to_path(adr, name, 0)<=0) { +much_too_long:; + Xorriso_much_too_long(xorriso, (int) (strlen(adr)+strlen(name)+1), 2); + return(0); + } + } else { + if(strlen(name)+1>=SfileadrL) + goto much_too_long; + strcpy(adr, name); + } + if(flag&2) { + ret= Xorriso_normalize_img_path(xorriso, "", adr, norm_adr, + 1|2|((flag&8)>>1)); + if(ret<=0) + return(ret); + if(norm_adr[0]==0) + strcpy(norm_adr, "/"); + strcpy(adr, norm_adr); + } + return(1); +} + + +/* @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 ret; + + if(strcmp(time_type, "a")==0) + (*t_type)|= 1; + else if(strcmp(time_type, "m")==0) + (*t_type)|= 4; + else if(strcmp(time_type, "b")==0) + (*t_type)|= 5; + else { + sprintf(xorriso->info_text, "%s: Unrecognized type '%s'", cmd, time_type); + if(!(flag & 1)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + ret= Decode_timestring(timestring, t, 0); + if(ret<=0) { + sprintf(xorriso->info_text, "%s: Cannot decode timestring '%s'", cmd, + timestring); + if(!(flag & 1)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + return(0); + } + sprintf(xorriso->info_text, "Understanding timestring '%s' as: %s", + timestring, ctime(t)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + return(1); +} + + +/* @param flag bit1= do not report memory usage as DEBUG +*/ +int Xorriso_check_temp_mem_limit(struct XorrisO *xorriso, off_t mem, int flag) +{ + char mem_text[80], limit_text[80]; + + Sfile_scale((double) mem, mem_text,5,1e4,0); + if(!(flag&2)) { + sprintf(xorriso->info_text, + "Temporary memory needed for result sorting : %s", mem_text); + 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, + "Cannot sort. List of matching files exceeds -temp_mem_limit (%s > %s)", + mem_text, limit_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + return(0); + } + return(1); +} + + +/* + @param flag bit0= use env_path to find the desired program +return: + <=0 : error + 1 : done +*/ +int Xorriso_execv(struct XorrisO *xorriso, char *cmd, char *env_path, + int *status, int flag) +{ + int ret, argc= 0; + char **argv= NULL, *pathlist= NULL, *cpt, *npt, prog[SfileadrL]; + char sfe[5*SfileadrL]; + pid_t child_pid; + struct stat stbuf; + + wait3(NULL,WNOHANG,NULL); /* just to remove any old dead child */ + + ret= Sfile_make_argv("", cmd, &argc, &argv, 1|4|128); + if(ret <= 0) + goto ex; + if(argc < 1) + {ret= 0; goto ex;} + + strcpy(prog, argv[0]); + if((flag & 1) && strchr(argv[0], '/') == NULL) { + if(env_path == NULL) + env_path= "/bin:/sbin"; + else if(env_path[0] == 0) + env_path= "/bin:/sbin"; + if(Sregex_string(&pathlist, env_path, 0) <= 0) + {ret= -1; goto ex;} + for(cpt= npt= pathlist; npt != NULL; cpt= npt + 1) { + npt= strchr(cpt, ':'); + if(npt != NULL) + *npt= 0; + if(strlen(cpt) + strlen(argv[0]) + 1 >= SfileadrL) + {ret= -1; goto ex;} + sprintf(prog, "%s/%s", cpt, argv[0]); + ret= stat(prog, &stbuf); + if(ret != -1) + break; + prog[0]= 0; + } + if(prog[0] == 0) { + sprintf(xorriso->info_text, "Cannot find external program %s", + Text_shellsafe(argv[0], sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + } + + child_pid= fork(); + if(child_pid==-1) + return(-1); + + if(child_pid==0) { + /* this is the child process */ + + sprintf(xorriso->info_text, "Executing external program %s", + Text_shellsafe(prog, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + + execv(prog, argv); /* should never come back */ + fprintf(stderr,"--- execution of shell command failed:\n"); + fprintf(stderr," %s\n",cmd); + exit(127); + } + + + /* this is the original process waiting for child to exit */ + do { + /* try to read and print the reply */; + ret= waitpid(child_pid,status,WNOHANG); + if(ret==-1) { + if(errno!=EINTR) + ret= 0; goto ex; + } else if(ret==0) { + +#ifdef NIX + + /* >>> An interrupt key would be nice. */ + + if((flag&4)) { + ret= Asqueue_event_is_pending(agent->queue,0,0); + if(ret>0) { + Asagent_stderr(agent,"--- shell command interrupted",1); + kill(child_pid,SIGTERM); + ret= 2; goto ex; + } + } +#endif /* NIX */ + + continue; + } else { + break; + } + } while(1); + ret= 1; +ex: + Sfile_make_argv("", "", &argc, &argv, 2); + Sregex_string(&pathlist, NULL, 0); + return(ret); +} + + +/* @param flag bit0= path is a command parameter +*/ +int Xorriso_path_is_excluded(struct XorrisO *xorriso, char *path, int flag) +{ + int ret; + char sfe[5*SfileadrL]; + + if(!(xorriso->disk_excl_mode&1)) /* exclusion is off */ + return(0); + if((flag&1) && !(xorriso->disk_excl_mode&2)) /* params are exempted */ + return(0); + ret= Exclusions_match(xorriso->disk_exclusions, path, + !!(xorriso->disk_excl_mode&4)); + if(ret<0) { + sprintf(xorriso->info_text, + "Error during disk file exclusion decision"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + } + if(ret>0 && (flag&1)) { + sprintf(xorriso->info_text, "Disk path parameter excluded by %s : %s", + (ret==1 ? "-not_paths" : "-not_leaf"), Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } + return(ret); +} + + +/* 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 ret, access_count= 0, default_count= 0, pass, is_default, line_len; + int was_error= 0, line_count= 0, perms; + char *acl_text= NULL, *cpt, *npt, *access_wpt= NULL, *default_wpt= NULL; + char *dpt= NULL, *ddpt= NULL, **wpt, *ppt; + + if(in_text[0] == 0 || strcmp(in_text, "clear") == 0 || + strcmp(in_text, "--remove-all") == 0) { + *access_acl_text= *default_acl_text= NULL; + return(1); + } else if (strcmp(in_text, "--remove-default") == 0) { + + /* >>> protect Access-ACL and delete Default-ACL */; + + /* <<< */ + return(0); + + } + + acl_text= strdup(in_text); + if(acl_text == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + {ret= -1; goto ex;} + } + + /* From comma to newline */ + for(cpt= strchr(acl_text, ','); cpt != NULL; cpt= strchr(cpt + 1, ',')) + *cpt= '\n'; + + /* Normalize to long text form + and sort apart "access" ACL from "default" ACL */; + for(pass= 0; pass < 2; pass++) { + line_count= 0; + for(cpt= acl_text; cpt != NULL; cpt= npt) { + line_count++; + npt= strchr(cpt, '\n'); + if(npt != NULL) + npt++; + if(*cpt == '#' || *cpt == '\n' || *cpt == 0) + continue; + + is_default= 0; + wpt= &access_wpt; + if(*cpt == 'd') { + is_default= 1; + if(pass == 1) + wpt= &default_wpt; + cpt= strchr(cpt, ':'); + if(cpt == NULL) { + was_error= line_count; + continue; + } + cpt++; + } + + line_len= 0; + dpt= strchr(cpt, ':'); + if(dpt != NULL) + ddpt= strchr(dpt + 1, ':'); + if(dpt == NULL || ddpt == NULL) { + was_error= line_count; + continue; + } + if(*cpt == 'u') { + if(pass == 0) { + line_len+= 5; + line_len+= ddpt - dpt; + } else { + strcpy(*wpt, "user:"); + strncpy(*wpt + 5, dpt + 1, ddpt - dpt); + (*wpt)+= 5 + (ddpt - dpt); + } + } else if(*cpt == 'g') { + if(pass == 0) { + line_len+= 6 + (ddpt - dpt); + } else { + strcpy(*wpt, "group:"); + strncpy(*wpt + 6, dpt + 1, ddpt - dpt); + (*wpt)+= 6 + (ddpt - dpt); + } + } else if(*cpt == 'o') { + if(pass == 0) { + if(ddpt - dpt > 1) { + was_error= line_count; + continue; + } + line_len+= 6 + (ddpt - dpt); + } else { + strcpy(*wpt, "other:"); + strncpy(*wpt + 6, dpt + 1, ddpt - dpt); + (*wpt)+= 6 + (ddpt - dpt); + } + } else if(*cpt == 'm') { + if(pass == 0) { + if(ddpt - dpt > 1) { + was_error= line_count; + continue; + } + line_len+= 5 + (ddpt - dpt); + } else { + strcpy(*wpt, "mask:"); + strncpy(*wpt + 5, dpt + 1, ddpt - dpt); + (*wpt)+= 5 + (ddpt - dpt); + } + + } else { + /* Unknown tag type */ + was_error= line_count; + continue; + } + + /* Examine permissions at ddpt + 1 */; + perms= 0; + for(ppt= ddpt + 1; *ppt != 0 && *ppt != '\n'; ppt++) { + if(*ppt == 'r') + perms|= 4; + else if(*ppt == 'w') + perms|= 2; + else if(*ppt == 'x') + perms|= 1; + else if(*ppt == '-' || *ppt == ' ' || *ppt == '\t') + ; + else if(*ppt == '#') + break; + else { + was_error= line_count; + break; + } + } + if(pass == 0) { + line_len+= 4; + } else { + sprintf(*wpt, "%c%c%c\n", + perms & 4 ? 'r' : '-', perms & 2 ? 'w' : '-', perms & 1 ? 'x' : '-'); + (*wpt)+= 4; + } + + if(pass == 0) { + if(is_default) + default_count+= line_len; + else + access_count+= line_len; + } + } + + if(pass == 0) { + *access_acl_text= calloc(access_count + 1, 1); + *default_acl_text= calloc(default_count + 1, 1); + if(access_acl_text == NULL || *default_acl_text == NULL) { + Xorriso_no_malloc_memory(xorriso, access_acl_text, 0); + {ret= -1; goto ex;} + } + access_wpt= *access_acl_text; + default_wpt= *default_acl_text; + } else { + *access_wpt= 0; + *default_wpt= 0; + } + } + + ret= 1; +ex:; + if(acl_text != NULL) + free(acl_text); + if(was_error) { + sprintf(xorriso->info_text, + "Malformed ACL entries encountered. Last one in line number %d.", + was_error); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + return(ret); +} + diff --git a/xorriso/parse_exec.h b/xorriso/parse_exec.h new file mode 100644 index 00000000..c234a3ea --- /dev/null +++ b/xorriso/parse_exec.h @@ -0,0 +1,88 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/read_run.c b/xorriso/read_run.c new file mode 100644 index 00000000..fb651158 --- /dev/null +++ b/xorriso/read_run.c @@ -0,0 +1,2011 @@ + + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains functions which are needed to read data + from ISO image. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +#include "lib_mgt.h" +#include "drive_mgt.h" +#include "iso_img.h" +#include "iso_tree.h" +#include "iso_manip.h" +#include "read_run.h" +#include "sort_cmp.h" + + +int Xorriso__read_pacifier(IsoImage *image, IsoFileSource *filesource) +{ + struct XorrisO *xorriso; + + xorriso= (struct XorrisO *) iso_image_get_attached_data(image); + if(xorriso==NULL) + return(1); + Xorriso_process_msg_queues(xorriso,0); + xorriso->pacifier_count++; + if(xorriso->pacifier_count%10) + return(1); + Xorriso_pacifier_callback(xorriso, "nodes read", xorriso->pacifier_count, 0, + "", 0); + return(1); +} + + +int Xorriso_iso_file_open(struct XorrisO *xorriso, char *pathname, + void *node_pt, void **stream, int flag) +{ + int ret; + char eff_path[SfileadrL]; + IsoNode *node= NULL; + IsoFile *filenode= NULL; + IsoStream *iso_stream= NULL, *input_stream; + + *stream= NULL; + if(flag&1) { + node= (IsoNode *) node_pt; + } else { + ret= Xorriso_get_node_by_path(xorriso, pathname, eff_path, &node, 0); + if(ret<=0) + return(ret); + } + if(!LIBISO_ISREG(node)) { + sprintf(xorriso->info_text, + "Given path does not lead to a regular data file in the image"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + + filenode= (IsoFile *) node; + iso_stream= iso_file_get_stream(filenode); + if(iso_stream==NULL) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "Could not obtain source stream of file in the image for reading"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if(flag & 2) { + /* Dig out the most original stream */ + while(1) { + input_stream= iso_stream_get_input_stream(iso_stream, 0); + if(input_stream == NULL) + break; + iso_stream= input_stream; + } + } + if(!iso_stream_is_repeatable(iso_stream)) { + sprintf(xorriso->info_text, + "The data production of the file in the image is one-time only"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= iso_stream_open(iso_stream); + if(ret<0) { + sprintf(xorriso->info_text, + "Could not open data file in the image for reading"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + Xorriso_process_msg_queues(xorriso,0); + *stream= iso_stream; + +#ifdef NIX + /* <<< */ + { + unsigned int fs_id; + dev_t dev_id; + ino_t ino; + + iso_stream_get_id(iso_stream, &fs_id, &dev_id, &ino); + fprintf(stderr, "xorriso_debug: iso_ino= %ld\n", (long int) ino); + } +#endif + + return(1); +} + + +int Xorriso_iso_file_read(struct XorrisO *xorriso, void *stream, char *buf, + int count, int flag) +{ + int ret, rcnt= 0; + IsoStream *stream_pt; + + stream_pt= (IsoStream *) stream; + + while(rcntvolset_change_pending) + return(0); + if(flag&1) { + node= (IsoNode *) in_node; + } else { + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + return(-1); + ret= Xorriso_node_from_path(xorriso, volume, img_path, &node, 1); + if(ret<=0) + return(-1); + } + ret= Xorriso__file_start_lba(node, &dummy, 0); + if(ret != 0) { + Xorriso_process_msg_queues(xorriso, 0); + return(0); + } + if(!LIBISO_ISREG(node)) + return(0); + stream= iso_file_get_stream((IsoFile *) node); + memcpy(type_text, stream->class->type, 4); + iso_stream_get_id(stream, &fs_id, &dev_id, &ino_id); + if(flag&2) { + sprintf(xorriso->info_text, "%s : fs=%d dev=%.f ino=%.f (%s)", + img_path, fs_id, (double) dev_id, (double) ino_id, type_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + } + ret= stat(disk_path, &stbuf); + if(ret==-1) + return(0); + if(flag&2) { + sprintf(xorriso->info_text, "%s : dev=%.f ino=%.f", + disk_path, (double) stbuf.st_dev, (double) stbuf.st_ino); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + } + if(fs_id!=1) + return(2); + + /* >>> obtain underlying dev_t ino_t of type "cout" */; + + if(strcmp(type_text, "fsrc")!=0) + return(2); + if(stbuf.st_dev==dev_id && stbuf.st_ino==ino_id) + return(1); + return(0); +} + + +/* @param flag bit0= minimal transfer: access permissions only + bit1= keep directory open: keep owner, allow rwx for owner + and push directory onto xorriso->perm_stack +*/ +int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path, + IsoNode *node, int flag) +{ + int ret, is_dir= 0; + mode_t mode; + uid_t uid; + gid_t gid; + struct utimbuf utime_buffer; + char sfe[5*SfileadrL]; + struct stat stbuf; + size_t num_attrs= 0, *value_lengths= NULL; + char **names= NULL, **values= NULL; + + ret= lstat(disk_path, &stbuf); + if(ret==-1) { + sprintf(xorriso->info_text, + "Cannot obtain properties of disk file %s", + Text_shellsafe(disk_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + {ret= 0; goto ex;} + } + uid= stbuf.st_uid; + + is_dir= S_ISDIR(stbuf.st_mode); + + mode= iso_node_get_permissions(node); + + if(xorriso->do_aaip & (2 | 8 | 16)) { + ret= iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values, + (!!(xorriso->do_aaip & 2)) | (!(xorriso->do_aaip & (8 | 16))) << 2); + if (ret < 0) { + strcpy(xorriso->info_text, "Error with obtaining ACL and xattr for "); + Text_shellsafe(disk_path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + if(num_attrs > 0) { + ret= iso_local_set_attrs(disk_path, num_attrs, names, value_lengths, + values, 0); + if(ret < 0) { + sprintf(xorriso->info_text, + "Cannot change ACL or xattr of disk file %s", + Text_shellsafe(disk_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); + {ret= 0; goto ex;} + } + } + Xorriso_process_msg_queues(xorriso,0); + } + if(!(xorriso->do_aaip & 2)) + mode= iso_node_get_perms_wo_acl(node); + + if(is_dir && (flag&2)) { + ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, + 1 | ((!!(xorriso->do_aaip & 2)) << 3)); + if(ret<=0) + {ret= 0; goto ex;} + ret= Permstack_push(&(xorriso->perm_stack), disk_path, &stbuf, 0); + if(ret<=0) { + Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); + strcpy(xorriso->info_text, + "Cannot memorize permissions for disk directory"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + {ret= -1; goto ex;} + } + mode|= S_IRUSR|S_IWUSR|S_IXUSR; + } + ret= chmod(disk_path, mode); + if(ret==-1) { + sprintf(xorriso->info_text, + "Cannot change access permissions of disk file %s", + Text_shellsafe(disk_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + {ret= 0; goto ex;} + } + + if(flag&1) + {ret= 1; goto ex;} + + gid= iso_node_get_gid(node); + if(!(S_ISDIR(stbuf.st_mode) && (flag&2))) + uid= iso_node_get_uid(node); + chown(disk_path, uid, gid); /* don't complain if it fails */ + utime_buffer.actime= iso_node_get_atime(node); + utime_buffer.modtime= iso_node_get_mtime(node); + ret= utime(disk_path,&utime_buffer); + if(ret==-1) { + sprintf(xorriso->info_text, + "Cannot change atime, mtime of disk file %s", + Text_shellsafe(disk_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + {ret= 0; goto ex;} + } + ret= 1; +ex:; + iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values,1 << 15); + return(ret); +} + + +/* @param flag + bit1= minimal transfer: access permissions only + bit2= keep directory open: keep owner, allow rwx for owner + push to xorriso->perm_stack +*/ +int Xorriso_restore_implicit_properties(struct XorrisO *xorriso, + char *full_disk_path, char *disk_path, char *full_img_path, int flag) +{ + int ret, nfic, ndc, nfdc, d, i; + char nfi[SfileadrL], nd[SfileadrL], nfd[SfileadrL], *cpt; + char sfe[5*SfileadrL]; + struct stat stbuf; + IsoNode *node; + + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, full_disk_path, nfd, + 1|2|4); + if(ret<=0) + return(ret); + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, nd, 1|2); + if(ret<=0) + return(ret); + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, full_img_path, nfi, + 1|2); + if(ret<=0) + return(ret); + nfdc= Sfile_count_components(nfd, 0); + ndc= Sfile_count_components(nd, 0); + nfic= Sfile_count_components(nfi, 0); + d= nfdc-ndc; + if(d<0) + return(-1); + if(d>nfic) + return(0); + for(i= 0; i>1)&3)); + if(ret<=0) + return(ret); + sprintf(xorriso->info_text, + "Restored properties for %s", Text_shellsafe(nd, sfe, 0)); + sprintf(xorriso->info_text+strlen(xorriso->info_text), + " from %s", Text_shellsafe(nfi, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + return(1); +} + + +/* @param flag bit0= Minimal transfer: access permissions only + bit1= *_offset and bytes are valid for writing to regular file + bit2= This is not a parameter. Do not report if ignored + bit3= do not restore properties + bit4= issue pacifier messages with long lasting copying + bit7= return 4 if restore fails from denied permission + do not issue error message + @return <0 severe error , 0 failure , 1 success , + 2 regularly not installed (disallowed device, UNIX domain socket) + 4 with bit7: permission to restore was denied +*/ +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 ret= 0, write_fd= -1, wanted, wret, open_flags, l_errno= 0; + int target_deleted= 0; + char *what= "[unknown filetype]", sfe[5*SfileadrL], sfe2[5*SfileadrL]; + char buf[32*1024], type_text[5], temp_path[SfileadrL], *buf_pt; + char *link_target, *open_path_pt= NULL; + off_t todo= 0, size, seek_ret, last_p_count= 0, already_done, read_count= 0; + void *data_stream= NULL; + mode_t mode; + dev_t dev= 0; + struct stat stbuf; + struct utimbuf utime_buffer; + + if(LIBISO_ISDIR(node)) { + what= "directory"; + ret= mkdir(disk_path, 0777); + l_errno= errno; + + } else if(LIBISO_ISREG(node)) { + what= "regular file"; + ret= Xorriso_iso_file_open(xorriso, img_path, (void *) node, &data_stream, + 1); + if(ret<=0) + goto ex; + open_path_pt= disk_path; + ret= stat(open_path_pt, &stbuf); + if(ret == -1 && errno == EACCES && (flag & 128)) + {ret= 4; goto ex;} + if(flag&2) { + if(ret!=-1 && !S_ISREG(stbuf.st_mode)) { + sprintf(xorriso->info_text, + "Restore offset demanded. But filesystem path leads to non-data file %s", + Text_shellsafe(disk_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); + l_errno= 0; + goto cannot_restore; + } + } else { + /* If source and target are the same disk file then do not copy content */ + ret= Xorriso_restore_is_identical(xorriso, (void *) node, img_path, + disk_path, type_text, 1); + if(ret<0) + goto ex; + if(ret==1) { + /* preliminarily emulate touch (might get overridden later) */ + utime_buffer.actime= stbuf.st_atime; + utime_buffer.modtime= time(0); + utime(disk_path,&utime_buffer); + goto restore_properties; + } + if(ret==2) { + /* Extract to temporary file and rename only after copying */ + ret= Xorriso_make_tmp_path(xorriso, disk_path, temp_path, &write_fd, + 128); + if(ret <= 0 || ret == 4) + goto ex; + open_path_pt= temp_path; + } + } + if(write_fd==-1) { + open_flags= O_WRONLY|O_CREAT; + if(disk_offset==0 || !(flag&2)) + open_flags|= O_EXCL; + write_fd= open(open_path_pt, open_flags, S_IRUSR|S_IWUSR); + l_errno= errno; + if(write_fd == -1 && errno == EACCES && (flag & 128)) + {ret= 4; goto ex;} + if(write_fd==-1) + goto cannot_restore; + } + todo= size= iso_file_get_size((IsoFile *) node); + if(flag&2) { + if(bytesinfo_text, + "Cannot address byte %.f in filesystem path %s", + (double) disk_offset, Text_shellsafe(open_path_pt, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); + goto cannot_restore; + } + } + while(todo>0) { + wanted= sizeof(buf); + if(wanted>todo) + wanted= todo; + ret= Xorriso_iso_file_read(xorriso, data_stream, buf, wanted, 0); + if(ret<=0) { + if(xorriso->extract_error_mode == 0 && + Xorriso_is_plain_image_file(xorriso, node, "", 0)) { + close(write_fd); + write_fd= -1; + already_done= (size - todo) / (off_t) 2048; + already_done*= (off_t) 2048; + sprintf(xorriso->info_text, + "Starting best_effort handling on ISO file %s at byte %.f", + Text_shellsafe(img_path, sfe, 0), (double) already_done); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + ret= Xorriso_read_file_data(xorriso, node, img_path, open_path_pt, + already_done, already_done, size - already_done, 2); + if(ret >= 0) + xorriso->pacifier_byte_count+= todo; + if(ret > 0) + todo= 0; + else + todo= -1; + } + if(ret <= 0) { + sprintf(xorriso->info_text, "Cannot read all bytes from ISO file %s", + Text_shellsafe(img_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } + break; + } + read_count+= ret; + buf_pt= buf; + + if(img_offset > read_count - ret) { + /* skip the desired amount of bytes */ + if(read_count <= img_offset) + continue; + buf_pt= buf + (img_offset - (read_count - ret)); + ret= read_count - img_offset; + } + + wret= write(write_fd, buf_pt, ret); + if(wret>=0) { + todo-= wret; + xorriso->pacifier_byte_count+= wret; + if((flag&16) && + xorriso->pacifier_byte_count - last_p_count >= 128*1024) { + Xorriso_pacifier_callback(xorriso, "files restored", + xorriso->pacifier_count, + xorriso->pacifier_total, "", 2|4); + last_p_count= xorriso->pacifier_byte_count; + } + } + if(wret != ret) { + sprintf(xorriso->info_text, + "Cannot write all bytes to disk filesystem path %s", + Text_shellsafe(open_path_pt, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); + break; + } + } + if(write_fd > 0) + close(write_fd); + write_fd= -1; + if(todo > 0 && xorriso->extract_error_mode == 2 && open_path_pt != NULL) { + unlink(open_path_pt); + target_deleted= 1; + } + Xorriso_iso_file_close(xorriso, &data_stream, 0); + data_stream= NULL; + if(temp_path==open_path_pt && !target_deleted) { + ret= rename(temp_path, disk_path); + if(ret==-1) { + sprintf(xorriso->info_text, + "Cannot rename temporary path %s to final disk path %s", + Text_shellsafe(temp_path, sfe, 0), + Text_shellsafe(disk_path, sfe2, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); + unlink(temp_path); + ret= 0; goto ex; + } + } + ret= -(todo > 0); + l_errno= 0; + + } else if(LIBISO_ISLNK(node)) { + what= "symbolic link"; + link_target= (char *) iso_symlink_get_dest((IsoSymlink *) node); + ret= symlink(link_target, disk_path); + l_errno= errno; + + } else if(LIBISO_ISCHR(node)) { + what= "character device"; + if(xorriso->allow_restore!=2) { +ignored:; + if(!(flag&4)) { + sprintf(xorriso->info_text, "Ignored file type: %s %s = %s", what, + Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } + {ret= 2; goto ex;} + } + mode= S_IFCHR | 0777; + ret= Xorriso_node_get_dev(xorriso, node, img_path, &dev, 0); + if(ret<=0) + goto ex; + if(dev == (dev_t) 1) { +probably_damaged:; + sprintf(xorriso->info_text, + "Most probably damaged device file not restored: mknod %s %s 0 1", + Text_shellsafe(disk_path, sfe, 0), LIBISO_ISCHR(node) ? "c" : "b"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + ret= 0; goto ex; + } + ret= mknod(disk_path, mode, dev); + l_errno= errno; + + } else if(LIBISO_ISBLK(node)) { + what= "block device"; + if(xorriso->allow_restore!=2) + goto ignored; + mode= S_IFBLK | 0777; + ret= Xorriso_node_get_dev(xorriso, node, img_path, &dev, 0); + if(ret<=0) + goto ex; + if(dev == (dev_t) 1) + goto probably_damaged; + ret= mknod(disk_path, mode, dev); + l_errno= errno; + + } else if(LIBISO_ISFIFO(node)) { + what= "named pipe"; + mode= S_IFIFO | 0777; + ret= mknod(disk_path, mode, dev); + l_errno= errno; + + } else if(LIBISO_ISSOCK(node)) { + what= "unix socket"; + /* Restoring a socket file is not possible. One rather needs to restart + the service which temporarily created the socket. */ + goto ignored; + + } else { + sprintf(xorriso->info_text, "Cannot restore file type '%s'", what); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + ret= 0; goto ex; + } + if(ret == -1 && l_errno == EACCES && (flag & 128)) + {ret= 4; goto ex;} + if(ret==-1) { +cannot_restore:; + sprintf(xorriso->info_text, + "Cannot restore %s to disk filesystem: %s", + what, Text_shellsafe(img_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, l_errno, "FAILURE", 0); + ret= 0; goto ex; + } + +restore_properties:; + if((flag&8) || LIBISO_ISLNK(node)) + ret= 1; + else + ret= Xorriso_restore_properties(xorriso, disk_path, node, flag&1); + if(todo < 0) + ret= 0; +ex:; + if(write_fd >= 0) { + close(write_fd); + if(ret <= 0 && xorriso->extract_error_mode == 2 && open_path_pt != NULL) + unlink(open_path_pt); + } + if(data_stream!=NULL) + Xorriso_iso_file_close(xorriso, &data_stream, 0); + return(ret); +} + + +/* Handle overwrite situation in disk filesystem. + @param node intended source of overwriting or NULL + @param flag + bit4= return 3 on rejection by exclusion or user + bit6= permission to call Xorriso_make_accessible() +*/ +int Xorriso_restore_overwrite(struct XorrisO *xorriso, + IsoNode *node, char *img_path, + char *path, char *nominal_path, + struct stat *stbuf, int flag) +{ + int ret; + char sfe[5*SfileadrL], sfe2[5*SfileadrL], type_text[5]; + + Xorriso_process_msg_queues(xorriso,0); + if(xorriso->do_overwrite==1 || + (xorriso->do_overwrite==2 && !S_ISDIR(stbuf->st_mode))) { + + ret= Xorriso_restore_is_identical(xorriso, (void *) node, img_path, + path, type_text, (node!=NULL)); + if(ret<0) + return(ret); + if(ret>0) /* will be handled properly by restore functions */ + ret= Xorriso_reassure_restore(xorriso, path, 8); + else + ret= Xorriso_rmx(xorriso, (off_t) 0, path, 8 | (flag & 64)); + if(ret<=0) + return(ret); + if(ret==3) { + sprintf(xorriso->info_text, "User revoked restoring of (ISO) file: %s", + Text_shellsafe(img_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(3*!!(flag&16)); + } + return(1); + } + Xorriso_msgs_submit(xorriso, 0, nominal_path, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, + "While restoring %s : %s exists and may not be overwritten", + Text_shellsafe(nominal_path, sfe, 0), strcmp(nominal_path, path)==0 ? + "file object" : Text_shellsafe(path, sfe2, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); +} + + +/* + @return <0 error, + bit0= hardlink created + bit1= siblings with target NULL found + bit2= siblings with non-NULL target found +*/ +int Xorriso_restore_target_hl(struct XorrisO *xorriso, IsoNode *node, + char *disk_path, int *node_idx, int flag) +{ + int ret, min_hl, max_hl, i, null_target_sibling= 0, link_sibling= 0; + + if(xorriso->hln_targets == NULL) + return(0); + ret= Xorriso_search_hardlinks(xorriso, node, node_idx, &min_hl, &max_hl, 1); + if(ret < 0) + return(ret); + if(ret == 0 || *node_idx < 0 || min_hl == max_hl) + return(0); + for(i= min_hl; i <= max_hl; i++) { + if(xorriso->hln_targets[i] == NULL) { + if(i != *node_idx) + null_target_sibling= 1; + continue; + } + link_sibling= 1; + ret= Xorriso_restore_make_hl(xorriso, xorriso->hln_targets[i], disk_path, + !!xorriso->do_auto_chmod); + if(ret > 0) + return(1); + } + return((null_target_sibling << 1) | (link_sibling << 2)); +} + + +/* + @return <0 error, + bit0= hardlink created + bit2= siblings lower index found +*/ +int Xorriso_restore_prefix_hl(struct XorrisO *xorriso, IsoNode *node, + char *disk_path, int node_idx, int flag) +{ + int ret, min_hl, max_hl, i, link_sibling= 0, hflag; + char old_path[SfileadrL], img_path[SfileadrL]; + struct Xorriso_lsT *img_prefixes= NULL, *disk_prefixes= NULL; + + ret= Xorriso_search_hardlinks(xorriso, node, &node_idx, &min_hl, &max_hl, + 2 | 4); + if(ret < 0) + return(ret); + if(ret == 0 || min_hl == max_hl) + return(0); + + for(i= min_hl; i < node_idx; i++) { + link_sibling= 1; + ret= Xorriso_path_from_node(xorriso, xorriso->node_array[i], img_path, 0); + if(ret < 0) + return(ret); + if(ret == 0) + continue; /* Node is deleted from tree (Should not happen here) */ + hflag= 1; + if(i == min_hl) { + hflag= 0; + } else if(xorriso->node_array[i] != xorriso->node_array[i - 1]) { + hflag= 0; + } + if(hflag == 0) { + img_prefixes= xorriso->node_img_prefixes; + disk_prefixes= xorriso->node_disk_prefixes; + } + ret= Xorriso_make_restore_path(xorriso, &img_prefixes, &disk_prefixes, + img_path, old_path, hflag); + if(ret <= 0) + return(ret); + ret= Xorriso_restore_make_hl(xorriso, old_path, disk_path, + !!xorriso->do_auto_chmod); + if(ret > 0) + return(1); + } + return(link_sibling << 2); +} + + +/* @return <0 = error , 0 = availmem exhausted first time , 1 = ok + 2 = availmem exhausted repeated +*/ +int Xorriso_register_node_target(struct XorrisO *xorriso, int node_idx, + char *disk_path, int flag) +{ + int l; + + if(xorriso->node_targets_availmem == 0) + return(2); + if(xorriso->hln_targets == NULL || node_idx < 0 || + node_idx >= xorriso->hln_count) + return(0); + if(xorriso->hln_targets[node_idx] != NULL) { + xorriso->node_targets_availmem+= strlen(xorriso->hln_targets[node_idx]) +1; + free(xorriso->hln_targets[node_idx]); + } + l= strlen(disk_path); + if(xorriso->node_targets_availmem <= l + 1) { + sprintf(xorriso->info_text, + "Hardlink target buffer exceeds -temp_mem_limit. Hardlinks may get divided."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + xorriso->node_targets_availmem= 0; + return(0); + } + xorriso->hln_targets[node_idx]= strdup(disk_path); + if(xorriso->hln_targets[node_idx] == NULL) { + Xorriso_no_malloc_memory(xorriso, NULL, 0); + return(-1); + } + xorriso->node_targets_availmem-= (l + 1); + return(1); +} + + +/* + @param flag bit0= offset and bytes is valid for writing to regular file + bit1= do not report copied files + bit2= -follow, -not_*: this is not a command parameter + bit3= keep directory open: keep owner, allow rwx for owner + bit4= do not look for hardlinks even if enabled + bit6= this is a copy action: do not fake times and ownership + bit7= return 4 if restore fails from denied permission + do not issue error message + @return <=0 = error , 1 = added leaf file object , 2 = added directory , + 3= regularly not installed (disallowed device, UNIX domain socket) + 4 = with bit7: permission to restore was denied +*/ +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 ret, i, split_count= 0, partno, total_parts, leaf_is_split= 0; + int record_hl_path= 0, node_idx, cannot_register= 0; + off_t total_bytes, was_byte_count; + char *part_name, part_path[SfileadrL], *img_path_pt; + char sfe[5*SfileadrL], sfe2[5*SfileadrL]; + IsoImage *volume; + IsoNode *part_node, *first_part_node= NULL; + struct SplitparT *split_parts= NULL; + struct stat stbuf; + + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + goto ex; + + was_byte_count= xorriso->pacifier_byte_count; + + if(LIBISO_ISDIR(node) && xorriso->do_concat_split) + leaf_is_split= Xorriso_identify_split(xorriso, img_path, node, + &split_parts, &split_count, &stbuf, 1|2); + if(leaf_is_split) { + /* map all files in directory img_path into regular file disk_path */ + + for(i=0 ; itotal_bytes) + bytes= total_bytes-offset; + ret= Xorriso_tree_restore_node(xorriso, part_node, part_path, (off_t) 0, + disk_path, offset, bytes, + (!!(flag&64)) | 2 | (flag & (4 | 128)) | 8 | ( 16 * !(flag&2))); + if(ret<=0) + goto restoring_failed; + if(ret == 4) + goto ex; + } + if(first_part_node!=NULL) + Xorriso_restore_properties(xorriso, disk_path, first_part_node, + !!(flag&64)); + goto went_well; + } + +#ifdef Osirrox_not_yeT + + if(resolve_link) { + ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0); + if(ret<=0) + goto ex; + disk_path_pt= resolved_disk_path; + } else + +#endif /* Osirrox_not_yeT */ + + img_path_pt= img_path; + + if(!((xorriso->ino_behavior & 4) || (flag & (1 | 16)) || LIBISO_ISDIR(node))){ + /* Try to restore as hardlink */ + ret= Xorriso_restore_target_hl(xorriso, node, disk_path, &node_idx, + !!xorriso->do_auto_chmod); + if(ret < 0) { + goto ex; + } else if(ret & 1) { + /* Success, hardlink was created */ + goto went_well; + } else if(ret & 2) { + /* Did not establish hardlink. Hardlink siblings with target NULL found.*/ + record_hl_path= 1; + } + if(ret & 4) { + /* Found siblings with non-NULL target, but did not link. */ + ret= Xorriso_eval_problem_status(xorriso, 1, 0); + if(ret < 0) + {ret= 0; goto ex;} + } + } + + ret= Xorriso_tree_restore_node(xorriso, node, img_path_pt, (off_t) 0, + disk_path, offset, bytes, + (flag&(4 | 8 | 128)) | (!!(flag&64)) | ((flag&1)<<1) | ( 16 * !(flag&2))); + if(ret == 4) + goto ex; + if(ret>0 && (flag&8)) + ret= Xorriso_restore_properties(xorriso, disk_path, node, 2 | !!(flag&64)); + if(ret<=0) { +restoring_failed:; + sprintf(xorriso->info_text, "Restoring failed: %s = %s", + Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + if(ret==2) + {ret= 3; goto ex;} + if(record_hl_path) { /* Start of a disk hardlink family */ + ret= Xorriso_register_node_target(xorriso, node_idx, disk_path, 0); + if(ret < 0) + goto ex; + if(ret == 0) + cannot_register= 1; + } + +went_well:; + xorriso->pacifier_count++; + if(!(flag&2)) + Xorriso_pacifier_callback(xorriso, "files restored", + xorriso->pacifier_count, + xorriso->pacifier_total, "", 4); + ret= 1; +ex:; + if(split_parts!=NULL) + Splitparts_destroy(&split_parts, split_count, 0); + if(ret > 0 && cannot_register) + ret= 0; + return(ret); +} + + +/* @param flag bit0= source is a directory and not to be restored as split file + >>> bit6= permission to call Xorriso_make_accessible() + @return <=0 error , 1=collision handled , 2=no collision , 3=revoked by user +*/ +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 ret, target_is_dir= 0, target_is_link= 0, stat_ret, made_accessible= 0; + struct stat target_stbuf, lt_stbuf; + struct PermiteM *perm_stack_mem; + + perm_stack_mem= xorriso->perm_stack; + + /* does a disk file exist with this name ? */ + *stbuf_ret= lstat(disk_path, &target_stbuf); + if(*stbuf_ret==-1) { + if((flag & 64) && errno == EACCES) { + ret= Xorriso_make_accessible(xorriso, disk_path, 0); + if(ret < 0) + goto ex; + made_accessible= 1; + *stbuf_ret= lstat(disk_path, &target_stbuf); + } + if(*stbuf_ret==-1) + {ret= 2; goto ex;} + } + target_is_link= S_ISLNK(target_stbuf.st_mode); + if(target_is_link) { + stat_ret= stat(disk_path, <_stbuf); + if(stat_ret == -1) { + if((flag & 64) && errno == EACCES && !made_accessible) { + ret= Xorriso_make_accessible(xorriso, disk_path, 0); + if(ret < 0) + goto ex; + made_accessible= 1; + stat_ret= stat(disk_path, <_stbuf); + } + } + if(stat_ret != -1) + target_is_dir= S_ISDIR(lt_stbuf.st_mode); + } else { + target_is_dir= S_ISDIR(target_stbuf.st_mode); + } + if(target_is_dir && (!target_is_link) && !(flag&1)) { + strcpy(xorriso->info_text, "Attempt to replace DISK directory "); + Text_shellsafe(nominal_disk_path, + xorriso->info_text+strlen(xorriso->info_text), 0); + strcat(xorriso->info_text, " by ISO file "); + Text_shellsafe(img_path, xorriso->info_text+strlen(xorriso->info_text), 0); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + + if(!(target_is_dir && (flag&1))) { + Xorriso_process_msg_queues(xorriso,0); + ret= Xorriso_restore_overwrite(xorriso, node, img_path, disk_path, + nominal_disk_path, &target_stbuf, 16 | (flag & 64)); + if(ret==3) + {ret= 3; goto ex;} + if(ret<=0) + goto ex; + *stbuf_ret= -1; /* It might still exist but will be handled properly */ + } + ret= 1; +ex:; + if(made_accessible) + Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0); + return(ret); +} + + +/* @param flag bit0= recursion is active + bit1= do not report restored files + bit6= this is a copy action: do not fake times and ownership + bit8= only register non-directory nodes in xorriso->node_array + bit7+8= + 0= direct operation + 1= create only directories, + count nodes in xorriso->node_counter + 2= only register non-directory nodes in + xorriso->node_array + 3= count nodes in xorriso->node_counter, + create no directory +*/ +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) +{ + IsoImage *volume; + IsoNode *node; + IsoDirIter *iter= NULL; + IsoNode **node_array= NULL; + int node_count, node_idx; + int ret, source_is_dir, source_is_link, fret, was_failure= 0; + int do_not_dive, source_is_split= 0, len_dp, len_ip, stbuf_ret, hflag, hret; + char *name, *disk_name, *leaf_name, *srcpt, *stbuf_src= ""; + struct LinkiteM *own_link_stack; + char *sfe= NULL, *sfe2= NULL; + char *disk_path= NULL, *img_path= NULL, *link_target= NULL; + off_t mem; + struct PermiteM *perm_stack_mem; + struct stat stbuf; + int dir_create= 0, node_register= 0, do_node_count= 0, normal_mode= 0; + + perm_stack_mem= xorriso->perm_stack; + switch((flag >> 7) & 3) { + case 0: normal_mode= 1; + break; case 1: dir_create= 1; + break; case 2: node_register= 1; + break; case 3: do_node_count= 1; + } + + /* Avoiding large local memory objects in order to save stack space */ + sfe= malloc(5*SfileadrL); + sfe2= malloc(5*SfileadrL); + disk_path= malloc(2*SfileadrL); + img_path= malloc(2*SfileadrL); + link_target= malloc(SfileadrL); + if(sfe==NULL || sfe2==NULL || disk_path==NULL || img_path==NULL || + link_target==NULL) { + Xorriso_no_malloc_memory(xorriso, &sfe, 0); + {ret= -1; goto ex;} + } + + own_link_stack= link_stack; + + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + goto ex; + + stbuf_src= img_dir_path; + node= (IsoNode *) dir; + ret= Xorriso_fake_stbuf(xorriso, stbuf_src, &stbuf, &node, 1); + if(ret<=0) { + Xorriso_msgs_submit(xorriso, 0, disk_dir_path, 0, "ERRFILE", 0); + sprintf(xorriso->info_text,"Cannot open as (ISO) source directory: %s", + Text_shellsafe(img_dir_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + +#ifdef Osirrox_not_yeT + + dev_t dir_dev; + dir_dev= stbuf.st_dev; + + if(S_ISLNK(stbuf.st_mode)) { + if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1)))) + {ret= 2; goto ex;} + stbuf_src= disk_dir_path; + if(stat(disk_dir_path, &stbuf)==-1) + goto cannot_open_dir; + if(dir_dev != stbuf.st_dev && + !(xorriso->do_follow_mount || (xorriso->do_follow_param && !(flag&1)))) + {ret= 2; goto ex;} + } + +#endif /* Osirrox_not_yeT */ + + if(!S_ISDIR(stbuf.st_mode)) { + Xorriso_msgs_submit(xorriso, 0, disk_dir_path, 0, "ERRFILE", 0); + sprintf(xorriso->info_text,"Is not a directory in ISO image: %s", + Text_shellsafe(img_dir_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + + mem= boss_mem; + ret= Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count, + &node_idx, &node, + 1 | 4 * (normal_mode && (xorriso->ino_behavior & 4))); + if(ret<=0) + goto ex; + + if(Sfile_str(img_path, img_dir_path,0)<=0) { +much_too_long:; + Xorriso_much_too_long(xorriso, SfileadrL, 2); + {ret= 0; goto ex;} + } + if(img_path[0]==0 || img_path[strlen(img_path)-1]!='/') + strcat(img_path,"/"); + name= img_path+strlen(img_path); + if(Sfile_str(disk_path, disk_dir_path, 0)<=0) + goto much_too_long; + if(disk_path[0]==0 || disk_path[strlen(disk_path)-1]!='/') + strcat(disk_path,"/"); + disk_name= disk_path+strlen(disk_path); + + len_dp= strlen(disk_path); + len_ip= strlen(img_path); + + while(1) { /* loop over ISO directory content */ + stbuf_src= ""; + +#ifdef Osirrox_not_yeT + + Linkitem_reset_stack(&own_link_stack, link_stack, 0); + +#endif + + srcpt= img_path; + Xorriso_process_msg_queues(xorriso,0); + ret= Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count, + &node_idx, &node, 0); + if(ret<0) + goto ex; + if(ret==0 || xorriso->request_to_abort) + break; + leaf_name= (char *) iso_node_get_name(node); + if(Xorriso_much_too_long(xorriso, len_dp + strlen(leaf_name)+1, 0)<=0) + {ret= 0; goto was_problem;} + if(Xorriso_much_too_long(xorriso, len_ip + strlen(leaf_name)+1, 0)<=0) + {ret= 0; goto was_problem;} + /* name is a pointer into img_path */ + strcpy(name, leaf_name); + strcpy(disk_name, leaf_name); + + stbuf_src= srcpt; + ret= Xorriso_fake_stbuf(xorriso, img_path, &stbuf, &node, 1); + if(ret<=0) + goto was_problem; + source_is_dir= 0; + source_is_link= S_ISLNK(stbuf.st_mode); + +#ifdef Osirrox_not_yeT + + /* ??? Link following in the image would cause severe problems + with Xorriso_path_from_node() */ + + if(xorriso->do_follow_links && source_is_link) { + /* Xorriso_hop_link checks for wide link loops */ + ret= Xorriso_hop_link(xorriso, srcpt, &own_link_stack, &hstbuf, 0); + if(ret<0) + goto was_problem; + if(ret==1) { + ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 0); + if(ret<=0) + goto was_problem; + srcpt= link_target; + stbuf_src= srcpt; + if(lstat(srcpt, &stbuf)==-1) + goto cannot_lstat; + } else { + if(Xorriso_eval_problem_status(xorriso, 0, 1|2)<0) + {ret= 0; goto was_problem;} + } + } else if (S_ISLNK(stbuf.st_mode)) { + ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1); + if(ret<=0) + goto was_problem; + } + +#endif /* Osirrox_not_yeT */ + + do_not_dive= 0; + if(S_ISDIR(stbuf.st_mode)) + source_is_dir= 1; + source_is_split= 0; + if(source_is_dir) + source_is_split= Xorriso_is_split(xorriso, img_path, node, 1|2); + if(source_is_split) + do_not_dive= 1; + + if(source_is_dir || !(dir_create || do_node_count || node_register)) { + ret= Xorriso_handle_collision(xorriso, node, img_path, + disk_path, disk_path, &stbuf_ret, + (source_is_dir && !source_is_split)); + if(ret<=0 || ret==3) + goto was_problem; + } else { + stbuf_ret= -1; + } + + if(stbuf_ret!=-1) { /* (Can only happen with directory) */ + Xorriso_auto_chmod(xorriso, disk_path, 0); + } else { + hflag= 4 | (flag & (2|64)); + if(source_is_dir && !do_not_dive) + hflag|= 8; /* keep directory open for user */ + if((dir_create || do_node_count) && !source_is_dir) { + xorriso->node_counter++; + } else if(node_register && !source_is_dir) { + if(xorriso->node_counter < xorriso->node_array_size) { + xorriso->node_array[xorriso->node_counter++]= (void *) node; + iso_node_ref(node); + } + } else if(node_register || do_node_count) { + ret= 1; + } else { + ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path, + (off_t) 0, (off_t) 0, hflag); + } + if(ret<=0) + goto was_problem; + } + if(source_is_dir && !do_not_dive) { + ret= Xorriso_restore_tree(xorriso, (IsoDir *) node, + img_path, disk_path, mem, + own_link_stack, 1 | (flag & (2 | (3 << 7)))); + /* eventually restore exact access permissions of directory */ + hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, + !!(flag&64)); + if(hret<=0 && hretperm_stack), perm_stack_mem, xorriso, !!(flag&64)); + } + + ret= 1; +ex: + Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, !!(flag&64)); + if(sfe!=NULL) + free(sfe); + if(sfe2!=NULL) + free(sfe2); + if(disk_path!=NULL) + free(disk_path); + if(img_path!=NULL) + free(img_path); + if(link_target!=NULL) + free(link_target); + Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count, + &node_idx, &node, (1<<31)); + + Xorriso_process_msg_queues(xorriso,0); + +#ifdef Osirrox_not_yeT + + Linkitem_reset_stack(&own_link_stack, link_stack, 0); + +#endif + + if(ret<=0) + return(ret); + return(!was_failure); +} + + +/* + @param flag + >>> bit0= mkdir: graft in as empty directory, not as copy from iso + bit1= do not report copied files + bit2= -follow, -not_*: this is not a command parameter + bit3= use offset and cut_size for -paste_in + bit4= return 3 on rejection by exclusion or user + bit5= if directory then do not add sub tree + bit6= this is a copy action: do not fake times and ownership + bit7+8= operation mode + 0= direct operation + 1= create only directories, + count nodes in xorriso->node_counter + 2= only register non-directory nodes in + xorriso->node_array + 3= count nodes in xorriso->node_counter, + create no directory + bit9= with operation mode 1 do net register prefixes + @return <=0 = error , 1 = added leaf file object , 2 = added directory , + 3 = rejected +*/ +int Xorriso_restore(struct XorrisO *xorriso, + char *img_path, char *disk_path, + off_t offset, off_t bytes, int flag) +{ + IsoImage *volume; + char path[SfileadrL], *apt, *npt, sfe[5*SfileadrL]; + IsoNode *node= NULL; + int done= 0, is_dir= 0, ret, source_is_dir, stbuf_ret, hret; + int dir_create= 0, node_count= 0, node_register= 0; + int leaf_is_split= 0, source_is_split= 0, new_dir_made= 0; + struct stat stbuf; + struct PermiteM *perm_stack_mem; + + perm_stack_mem= xorriso->perm_stack; + switch((flag >> 7) & 3) { + case 1: dir_create= 1; + break; case 2: node_register= 1; + break; case 3: node_count= 1; + } + + if(dir_create && !(flag & (1 << 9))) { + ret= Xorriso_lst_append_binary(&(xorriso->node_disk_prefixes), + disk_path, strlen(disk_path) + 1, 0); + if(ret <= 0) + goto ex; + ret= Xorriso_lst_append_binary(&(xorriso->node_img_prefixes), + img_path, strlen(img_path) + 1, 0); + if(ret <= 0) + goto ex; + } + + ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&4)); + if(ret<0) + goto ex; + if(ret>0) + {ret= 3*!!(flag&16); goto ex;} + + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + goto ex; + + strncpy(path, disk_path, sizeof(path)-1); + path[sizeof(path)-1]= 0; + apt= npt= path; + + if(!(flag&1)) { + ret= Xorriso_fake_stbuf(xorriso, img_path, &stbuf, &node, 0); + if(ret>0) { + if(S_ISDIR(stbuf.st_mode)) + is_dir= 1; + +#ifdef Osirrox_not_yeT + + /* ??? this would cause severe problems with Xorriso_path_from_node() */ + + else if((stbuf.st_mode&S_IFMT)==S_IFLNK && + (xorriso->do_follow_links || + (xorriso->do_follow_param && !(flag&4)))) { + resolve_link= 1; + ret= Xorriso_iso_lstat(xorriso, img_path, &stbuf, 1|2); + if(ret!=-1) { + if(S_ISDIR(stbuf.st_mode)) + is_dir= 1; + } + } +#endif /* Osirrox_not_yeT */ + + } else { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, + "Cannot determine attributes of (ISO) source file %s", + Text_shellsafe(img_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + ret= 0; goto ex; + } + if(is_dir && xorriso->do_concat_split) + leaf_is_split= Xorriso_is_split(xorriso, img_path, node, 1|2); + } + for(npt= apt; !done; apt= npt+1) { + npt= strchr(apt, '/'); + if(npt==NULL) { + npt= apt+strlen(apt); + done= 1; + } else + *npt= 0; + if(*apt==0) { + *apt= '/'; + apt++; + if(done) + goto attach_source; + continue; + } + source_is_dir= (is_dir || (flag&1) || !done); + source_is_split= done && leaf_is_split; + + stbuf_ret= -1; + if((flag&8) && done) { + + /* ??? move down from Xorriso_paste_in() : + check whether target does not exist or both are regular */; + + } else if(source_is_dir || !(dir_create || node_count || node_register)) { + ret= Xorriso_handle_collision(xorriso, node, img_path, path, disk_path, + &stbuf_ret, (source_is_dir && !source_is_split)); + if(ret<=0 || ret==3) + goto ex; + } + + new_dir_made= 0; + if(stbuf_ret==-1 && (source_is_dir && !source_is_split) && + !(node_count || node_register)) { + /* make a directory */ + ret= mkdir(path, 0777); + if(ret==-1) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, + "While restoring '%s' : could not insert '%s'", disk_path, path); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); + {ret= 0; goto ex;} + } + if(!done) { + /* keep rwx for the owner */ + Xorriso_restore_implicit_properties(xorriso, disk_path, path, + img_path, 4); + } + new_dir_made= 1; + } else if((source_is_dir && !source_is_split)) { + if(!(node_count || node_register)) + Xorriso_auto_chmod(xorriso, path, 0); + } + if(done) { +attach_source:; + + if(flag&1) { + /* directory was created above */; + + } else if(is_dir && !source_is_split) { + + if(!node_register) { + if(new_dir_made) /* keep open and push to Permstack */ + Xorriso_restore_properties(xorriso, disk_path, node, + 2 | !!(flag&64)); + } + if(!(flag&32)) { + ret= Xorriso_restore_tree(xorriso, (IsoDir *) node, img_path, path, + (off_t) 0, NULL, flag & (2 | 64 | (3 << 7))); + if(ret<=0) + goto ex; + if(new_dir_made && !(flag&64)) + /* set timestamps which Permstack_pop() will not set */ + Xorriso_restore_properties(xorriso, disk_path, node, 2); + } + } else { + if(dir_create || node_count) { + xorriso->node_counter++; + } else if(node_register) { + if(xorriso->node_counter < xorriso->node_array_size) { + xorriso->node_array[xorriso->node_counter++]= (void *) node; + iso_node_ref(node); + } + } else { + ret= Xorriso_restore_disk_object(xorriso, img_path, node, path, + offset, bytes, (flag & (2|4|64)) | !!(flag&8)); + if(ret<=0) + goto ex; + } + } + } else + *npt= '/'; + } + Xorriso_process_msg_queues(xorriso,0); + ret= 1 + (is_dir && !leaf_is_split); +ex:; + /* restore exact access permissions of stacked paths */ + hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, + 2 | !!(flag&64)); + if(hret<=0 && hretperm_stack; + + Xorriso_sort_node_array(xorriso, 0); + + disk_path[0]= 0; + for(i= 0; i < xorriso->node_counter; i++) { + node= (IsoNode *) xorriso->node_array[i]; + ret= Xorriso_path_from_node(xorriso, node, img_path, 0); + if(ret < 0) + goto ex; + if(ret == 0) + continue; /* Node is deleted from tree (Should not happen here) */ + hflag= 1; + if(i == 0) { + hflag= 0; + } else if(node != xorriso->node_array[i - 1]) { + hflag= 0; + } + if(hflag == 0) { + img_prefixes= xorriso->node_img_prefixes; + disk_prefixes= xorriso->node_disk_prefixes; + } + ret= Xorriso_make_restore_path(xorriso, &img_prefixes, &disk_prefixes, + img_path, disk_path, hflag); + if(ret<=0) + goto was_problem; + + ret= Xorriso_handle_collision(xorriso, node, img_path, disk_path, disk_path, + &stbuf_ret, 64); + if(ret<=0 || ret==3) + goto was_problem; + if(xorriso->hln_array != NULL && !(xorriso->ino_behavior & 16)) { + /* Eventual lookup of hardlinks will be done in + Xorriso_restore_disk_object() */; + } else if(i > 0 && !(xorriso->ino_behavior & 4)) { + if(Xorriso__findi_sorted_ino_cmp(&(xorriso->node_array[i-1]), + &(xorriso->node_array[i])) == 0) { + if(faulty_family) { + sprintf(xorriso->info_text, "Hardlinking omitted with "); + Text_shellsafe(disk_path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + } else { + /* Try to install hardlink to a sibling */ + ret= Xorriso_restore_prefix_hl(xorriso, node, disk_path, i, 0); + if(ret < 0) { + goto was_problem; + } else if(ret & 1) { + /* Success, hardlink was created */ + xorriso->pacifier_count++; + continue; + } + if(ret & 4) { + /* Found elder siblings, but did not link. */ + ret= Xorriso_eval_problem_status(xorriso, 1, 0); + if(ret < 0) + {ret= 0; goto ex;} + } + } + } else + faulty_family= 0; + } + + ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path, + (off_t) 0, (off_t) 0, + 4 | (xorriso->ino_behavior & 16) | 128); + if(ret<=0) + goto was_problem; + if(ret == 4) { + /* Failed from lack of permission */ + ret= Xorriso_make_accessible(xorriso, disk_path, 0); + if(ret < 0) + goto ex; + ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path, + (off_t) 0, (off_t) 0, 4 | (xorriso->ino_behavior & 16)); + if(ret<=0) + goto was_problem; + Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0); + } + + continue; /* regular bottom of loop */ +was_problem:; + faulty_family= 1; + was_failure= 1; + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret<0) + goto ex; + Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0); + } + ret= 1; +ex:; + Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0); + return(ret); +} + + +/* @param flag bit0= -follow, -not: disk_path is not a command parameter +*/ +int Xorriso_paste_in(struct XorrisO *xorriso, char *disk_path, + off_t startbyte, off_t bytecount, char *iso_rr_path, int flag) +{ + int ret; + char eff_source[SfileadrL], eff_dest[SfileadrL], sfe[SfileadrL*5]; + struct stat stbuf; + IsoNode *node; + + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_dest, + 2|4); + if(ret<=0) + return(ret); + ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&1)); + if(ret!=0) + return(0); + ret= stat(eff_dest, &stbuf); + if(ret!=-1 && !S_ISREG(stbuf.st_mode)) { + Xorriso_msgs_submit(xorriso, 0, eff_dest, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, + "-paste_in: DISK file %s exists and is not a data file", + Text_shellsafe(eff_source, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + return(0); + } + + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, iso_rr_path, + eff_source, 2); + if(ret<=0) + return(ret); + ret= Xorriso_fake_stbuf(xorriso, eff_source, &stbuf, &node, 4); + if(ret<=0) + return(0); + if(!S_ISREG(stbuf.st_mode)) { + Xorriso_msgs_submit(xorriso, 0, eff_dest, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, "-paste_in: ISO file %s is not a data file", + Text_shellsafe(eff_source, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + return(0); + } + + /* >>> eventually obtain parameters from file name */; + + ret= Xorriso_restore(xorriso, eff_source, eff_dest, startbyte, bytecount, 8); + return(ret); +} + + +int Xorriso_extract_cut(struct XorrisO *xorriso, + char *img_path, char *disk_path, + off_t img_offset, off_t bytes, int flag) +{ + int ret, stbuf_ret, read_raw; + double mem_lut= 0.0; + char eff_img_path[SfileadrL], eff_disk_path[SfileadrL], sfe[SfileadrL*5]; + IsoImage *volume; + IsoNode *node; + + ret= Xorriso_get_volume(xorriso, &volume, 0); + if(ret<=0) + return(ret); + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, + img_path, eff_img_path, 0); + if(ret<=0) + return(ret); + ret= Xorriso_node_from_path(xorriso, volume, eff_img_path, &node, 0); + if(ret<=0) + return(ret); + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, + disk_path, eff_disk_path, 2 | 4); + if(ret<=0) + return(ret); + Xorriso_pacifier_reset(xorriso, 0); + mem_lut= xorriso->last_update_time; + + ret= Xorriso_handle_collision(xorriso, node, img_path, eff_disk_path, + disk_path, &stbuf_ret, 0); + if(ret<=0 || ret==3) + return(0); + + /* If it is a non-filtered stream from the ISO image + and img_offset is a multiple of 2048 + then use Xorriso_read_file_data() for random access offset. + */ + if(!LIBISO_ISREG(node)) { + Xorriso_msgs_submit(xorriso, 0, eff_disk_path, 0, "ERRFILE", 0); + sprintf(xorriso->info_text, "-extract_cut: ISO file %s is not a data file", + Text_shellsafe(eff_img_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + read_raw= 0; + if((img_offset % 2048) == 0) { + ret= Xorriso_is_plain_image_file(xorriso, node, "", 0); + if(ret > 0) + read_raw= 1; + } + if (read_raw) { + ret= Xorriso_read_file_data(xorriso, node, eff_img_path, eff_disk_path, + img_offset, (off_t) 0, bytes, 0); + if(ret<=0) + return(ret); + } else { + ret= Xorriso_tree_restore_node(xorriso, node, eff_img_path, img_offset, + eff_disk_path, (off_t) 0, bytes, 2 | 8); + if(ret<=0) + return(ret); + } + + ret= Xorriso_restore_properties(xorriso, eff_disk_path, node, 0); + if(ret<=0) + return(ret); + + if(mem_lut != xorriso->last_update_time) + Xorriso_pacifier_callback(xorriso, "sectors examined", + xorriso->pacifier_count, 0, "", 1); + return(1); +} + + +/* @param flag bit1= for Xorriso_check_interval(): no pacifier messages +*/ +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) +{ + int ret, i, lba_count= 0, *start_lbas= NULL, *end_lbas= NULL, read_chunk= 16; + int lba, count, blocks, quality, spot, bad_extract= 0; + off_t size= 0, file_base_bytes= 0, file_processed_bytes= 0, img_adr; + off_t new_file_base_bytes, upto_file_bytes, start_byte= 0; + char sfe[5*SfileadrL]; + struct SpotlisT *spotlist= NULL; + struct CheckmediajoB *job= NULL; + + upto_file_bytes= img_offset + bytes; + + /* >>> make Xorriso_check_interval() ready for copying in byte granularity */ + if(img_offset % (off_t) 2048) { + sprintf(xorriso->info_text, + "Image address offset is not a multiple of 2048"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + + ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas, &size, + 0); + if(ret <= 0) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "File object %s is currently not a data file from the loaded image", + Text_shellsafe(img_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + goto ex; + } + if(img_offset + bytes < size && bytes > 0) + size= img_offset + bytes; + + ret= Checkmediajob_new(&job, 0); + if(ret <= 0) + goto ex; + if(xorriso->check_media_default != NULL) + Checkmediajob_copy(xorriso->check_media_default, job, 0); + job->min_lba= -1; + job->max_lba= -1; + job->sector_map_path[0]= 0; + + ret= Spotlist_new(&spotlist, 0); + if(ret <= 0) + {ret= -1; goto ex;} + + if(Sfile_str(job->data_to_path, disk_path, 0) <= 0) + {ret= -1; goto ex;} + Xorriso_open_job_data_to(xorriso, job, 0); + if(ret <= 0) + goto ex; + + for(i= 0; i < lba_count && file_base_bytes < upto_file_bytes; i++) { + lba= start_lbas[i]; + count= end_lbas[i] + 1 - start_lbas[i]; + new_file_base_bytes= file_base_bytes + ((off_t) count) * (off_t) 2048; + + /* skip intervals before img_offset */ + if(new_file_base_bytes <= img_offset) { + file_base_bytes= new_file_base_bytes; + continue; + } + /* Eventually adjust first interval start */ + img_adr= ((off_t) lba) * (off_t) 2048; + if(file_base_bytes < img_offset) { + img_adr+= img_offset - file_base_bytes; + lba= img_adr / (off_t) 2048; + count= end_lbas[i] + 1 - lba; + file_base_bytes= img_offset; + } + + /* Eventually omit surplus blocks */ + if(new_file_base_bytes > upto_file_bytes) + count-= (new_file_base_bytes - upto_file_bytes) / (off_t) 2048; + /* Adjust job */ + job->data_to_offset= file_processed_bytes - img_adr + disk_offset; + job->data_to_limit= size - file_base_bytes; + + file_processed_bytes+= ((off_t) count) * (off_t) 2048; + ret= Xorriso_check_interval(xorriso, spotlist, job, lba, count, read_chunk, + 0, (flag & 2)); + if(ret <= 0) + goto ex; + if (ret == 2) { + sprintf(xorriso->info_text, "Attempt aborted to extract data from %s", + Text_shellsafe(img_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + file_base_bytes= new_file_base_bytes; + } + + /* Use spotlist to evaluate damage */ + file_base_bytes= 0; + count= Spotlist_count(spotlist, 0); + for(spot= 0; spot < count; spot++) { + ret= Spotlist_get_item(spotlist, spot, &lba, &blocks, &quality, 0); + if(ret <= 0) + continue; + if(quality < Xorriso_read_quality_valiD) { + for(i= 0; i < lba_count; i++) { + if(start_lbas[i] <= lba && end_lbas[i] >= lba) { + start_byte= (lba - start_lbas[i]) * (off_t) 2048 + file_base_bytes; + break; + } + file_base_bytes+= ((off_t) (end_lbas[i] + 1 - start_lbas[i])) + * (off_t) 2048; + } + if(i < lba_count) { + sprintf(xorriso->info_text, "Bad extract : %14.f , %14.f , %s\n", + (double) start_byte, ((double) blocks) * 2048.0, + Text_shellsafe(disk_path, sfe, 0)); + Xorriso_info(xorriso, 0); + bad_extract= 1; + } + } + } + + ret= !bad_extract; +ex:; + if(start_lbas != NULL) + free((char *) start_lbas); + if(end_lbas != NULL) + free((char *) end_lbas); + Spotlist_destroy(&spotlist, 0); + Checkmediajob_destroy(&job, 0); + return(ret); +} + + +/* @param node Opaque handle to IsoNode which is to be inquired instead of path if it is not NULL. + @param path is used as address if node is NULL. + @param flag bit0= do not report to result but only indicate outcome + by return value + bit1= silently ignore nodes without MD5 + bit2= do not only report mismatches but also matches + @return 3= not a data file + 2= no MD5 attached to node + 1= ok, MD5 compared and matching + 0= not ok, MD5 mismatch + <0= other error +*/ +int Xorriso_check_md5(struct XorrisO *xorriso, void *in_node, char *path, + int flag) +{ + int ret, wanted, rret; + IsoImage *image; + IsoNode *node; + IsoFile *file; + char node_md5[16], data_md5[16], buffer[64 * 1024]; + void *stream= NULL, *ctx= NULL; + off_t todo; + + node= (IsoNode *) in_node; + if(node == NULL) { + ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); + if(ret<=0) + {ret= -1; goto ex;} + } + if(!LIBISO_ISREG(node)) { + strcpy(xorriso->info_text, "-check_md5: Not a data file: "); + Text_shellsafe(path, xorriso->info_text, 1); + if(!(flag & 2)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + ret= 3; goto ex; + } + file= (IsoFile *) node; + + /* obtain MD5 */ + ret= Xorriso_get_volume(xorriso, &image, 0); + if(ret <= 0) + {ret= -1; goto ex;} + ret= iso_file_get_md5(image, file, node_md5, 0); + Xorriso_process_msg_queues(xorriso,0); + if(ret < 0) + {ret= -1; goto ex;} + if(ret == 0) { + strcpy(xorriso->info_text, "-check_md5: No MD5 recorded with file: "); + Text_shellsafe(path, xorriso->info_text, 1); + if(!(flag & 2)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + ret= 2; goto ex; + } + + /* Read file and compute MD5 */; + ret= Xorriso_iso_file_open(xorriso, path, (void *) node, &stream, 1 | 2); + if(ret <= 0) + {ret= -1; goto ex;} + ret= iso_md5_start(&ctx); + if(ret < 0) + goto ex; + todo= iso_stream_get_size(stream); + while(todo > 0) { + if(todo < sizeof(buffer)) + wanted= todo; + else + wanted= sizeof(buffer); + rret = Xorriso_iso_file_read(xorriso, stream, buffer, wanted, 0); + if(rret <= 0) + {ret= -1; goto ex;} + todo-= rret; + ret = iso_md5_compute(ctx, buffer, rret); + if(ret < 0) + goto ex; + xorriso->pacifier_count+= rret; + xorriso->pacifier_byte_count+= rret; + Xorriso_pacifier_callback(xorriso, "content bytes read", + xorriso->pacifier_count, 0, "", 0); + } + ret= iso_md5_end(&ctx, data_md5); + if(ret < 0) + goto ex; + + /* Report outcome */ + Xorriso_process_msg_queues(xorriso,0); + if(! iso_md5_match(node_md5, data_md5)) { + sprintf(xorriso->result_line, "MD5 MISMATCH: "); + Text_shellsafe(path, xorriso->result_line, 1); + strcat(xorriso->result_line, "\n"); + if(!(flag & 1)) + Xorriso_result(xorriso,0); + ret= 0; + } else { + sprintf(xorriso->result_line, "md5 match : "); + Text_shellsafe(path, xorriso->result_line, 1); + strcat(xorriso->result_line, "\n"); + if(flag & 4) + Xorriso_result(xorriso,0); + ret= 1; + } + +ex:; + Xorriso_process_msg_queues(xorriso,0); + Xorriso_iso_file_close(xorriso, &stream, 0); + if(ctx != NULL) + iso_md5_end(&ctx, data_md5); + if(ret < 0) { + sprintf(xorriso->result_line, "NOT READABLE: "); + Text_shellsafe(path, xorriso->result_line, 1); + strcat(xorriso->result_line, "\n"); + if(!(flag & 1)) + Xorriso_result(xorriso,0); + } + return(ret); +} + diff --git a/xorriso/read_run.h b/xorriso/read_run.h new file mode 100644 index 00000000..f06be0e9 --- /dev/null +++ b/xorriso/read_run.h @@ -0,0 +1,70 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/sfile.c b/xorriso/sfile.c new file mode 100644 index 00000000..6fccd07c --- /dev/null +++ b/xorriso/sfile.c @@ -0,0 +1,877 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains the implementation of functions around files and strings. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#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; ist_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(value0) + 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(¤t_time); + for(i=0;i'9' && text[0]<'A') || text[0]>'Z') + return(0); + l= strlen(text); + for(i=1;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'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); +} + + diff --git a/xorriso/sfile.h b/xorriso/sfile.h new file mode 100644 index 00000000..67a71e14 --- /dev/null +++ b/xorriso/sfile.h @@ -0,0 +1,121 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/sort_cmp.c b/xorriso/sort_cmp.c new file mode 100644 index 00000000..3598dd34 --- /dev/null +++ b/xorriso/sort_cmp.c @@ -0,0 +1,710 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains functions which sort and compare tree nodes. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#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); +} + diff --git a/xorriso/sort_cmp.h b/xorriso/sort_cmp.h new file mode 100644 index 00000000..8bc402bd --- /dev/null +++ b/xorriso/sort_cmp.h @@ -0,0 +1,62 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/text_io.c b/xorriso/text_io.c new file mode 100644 index 00000000..82bbc918 --- /dev/null +++ b/xorriso/text_io.c @@ -0,0 +1,1990 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains the implementation of text i/o functions. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* for -charset */ +#include +#include +#include + + +#ifdef Xorriso_with_readlinE +#ifdef Xorriso_with_old_readlinE +#include +#include +#else /* Xorriso_with_old_readlinE */ +#include +#include +#endif /* ! Xorriso_with_old_readlinE */ +#endif /* Xorriso_with_readlinE */ + + +#include "xorriso.h" +#include "xorriso_private.h" +#include "xorrisoburn.h" + + +int Xorriso_protect_stdout(struct XorrisO *xorriso, int flag) +{ + if(xorriso->dev_fd_1>=0) + return(2); + xorriso->dev_fd_1= dup(1); + close(1); + dup2(2,1); + return(1); +} + + +int Xorriso_dialog_input(struct XorrisO *xorriso, char line[], int linesize, + int flag) +/* + bit0= do not write to history + bit1= do not read input (but eventually write to history) + bit2= do not write to history line which begin with "-history:" or "-history " +*/ +{ + char *cpt= NULL, **argv= NULL, *linept, *why_append= ""; + int ret, argc= 0, base_length= 0, l, append_line; +#ifdef Xorriso_with_readlinE + static char last_input[SfileadrL]= {""}; +#endif /* ! Xorriso_with_readlinE */ + double tdiff; + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv,&tz); + tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec); + + fflush(stdout); + linept= line; + +get_single:; +#ifdef Xorriso_with_readlinE + + if(xorriso->use_stdin || xorriso->dev_fd_1>=0) { + if(flag&2) + {ret= 1; goto ex;} + if(Sfile_fgets_n(linept,linesize - base_length - 1, stdin, + (xorriso->dialog == 2)) == NULL) { + /* need a very dramatic end */ + kill(getpid(),SIGHUP); + {ret= -1; goto ex;} + } + goto process_single; + } + if(flag&2) { + cpt= NULL; + } else { + cpt= readline(""); + if(cpt==NULL) { + /* need a very dramatic end */ + kill(getpid(),SIGHUP); + {ret= -1; goto ex;} + } + l= strlen(cpt); + if(l >= linesize - base_length - 1) { + strncpy(linept, cpt, linesize - 1); + line[sizeof(line)-1]= 0; + sprintf(xorriso->info_text,"Input line too long !"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + goto new_empty; + } else + strcpy(linept, cpt); + } + +process_single:; + +#else /* Xorriso_with_readlinE */ + + if(flag&2) + {ret= 1; goto ex;} + if(Sfile_fgets_n(linept, linesize - base_length - 1, stdin, + (xorriso->dialog == 2)) == NULL) { + /* need a very dramatic end */ + kill(getpid(),SIGHUP); + {ret= -1; goto ex;} + } + +#endif /* ! Xorriso_with_readlinE */ + + if(xorriso->dialog == 2) { + append_line= 0; + if(linept != line && strcmp(linept, "@@@") == 0) { + sprintf(xorriso->info_text, "Incomplete input line cleared by %s", + linept); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0); +new_empty:; + line[0]= 0; + linept= line; + sprintf(xorriso->info_text, "-------------------------------------\n"); + Xorriso_info(xorriso,0); + sprintf(xorriso->info_text, "Enter new text for empty input line :\n"); + Xorriso_info(xorriso,0); + goto get_single; + } + l= strlen(line); + ret= Sfile_make_argv("", line, &argc, &argv, 16); + if(ret < 0) + goto ex; + if(ret == 0 && !append_line) { + /* append a newline character */ + if(l >= linesize - 1) { + sprintf(xorriso->info_text,"Input line too long !"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + goto new_empty; + } + line[l]= '\n'; + line[l + 1]= 0; + append_line= 1; + why_append= "Quoted newline char"; + } + if(l > 0 && !append_line) + if(line[l - 1] == '\\') { + line[l - 1]= 0; + append_line= 1; + why_append= "Trailing backslash "; + } + if(append_line) { + base_length= strlen(line); + linept= line + base_length; + sprintf(xorriso->info_text, + "---------------------------------------------------------------\n"); + Xorriso_info(xorriso,0); + sprintf(xorriso->info_text, + "%s : Enter rest of line (or @@@ to clear it) :\n", why_append); + Xorriso_info(xorriso,0); + goto get_single; + } + } + +#ifdef Xorriso_with_readlinE + + if(line[0]!=0 && strcmp(last_input,line)!=0 && !(flag&1)) + if(!((flag&4) && + (strncmp(line,"-history:",9)==0 || strncmp(line,"-history ",9)==0))) { + add_history(line); + strncpy(last_input,line,sizeof(last_input)-1); + last_input[sizeof(last_input)-1]= 0; + } + +#endif /* ! Xorriso_with_readlinE */ + + ret= 1; +ex:; + if(cpt!=NULL) + free(cpt); + gettimeofday(&tv,&tz); + xorriso->idle_time+= tv.tv_sec+(1.e-6*(double) tv.tv_usec)-tdiff; + return(ret); +} + + +int Xorriso_request_confirmation(struct XorrisO *xorriso, int flag) +/* + bit0= important operation going on: + demand confirmation of abort, only abort on @@@ + bit1= mark '@' and '@@' by return 4 + bit2= accept: i|n= ignore | do not remove , r|y= retry | remove , q|x= abort + bit3= @@@ = 'done reading' rather than 'abort' + bit4= in non-dialog mode return 6 rather than 1 +*/ +/* return: <=0 error + 1= go on | do not remove existing file + 2= abort + 3= redo request for confirmation + 4= see flag bit1 + (5= skip volume) + 6= retry failed operation | remove existing file + */ +{ + int ret; + char line[SfileadrL],*cpt,previous_line[SfileadrL]; + char *abort_req_text,*abort_really_text; + + if(!xorriso->dialog) { + if(flag&16) + return(6); + return(1); + } + if(flag&8) { + abort_req_text= "request to end"; + abort_really_text= "done reading"; + } else { + abort_req_text= "request to abort"; + abort_really_text= "abort this command"; + } + ret= Xorriso_dialog_input(xorriso,line,sizeof(line),1); + xorriso->result_line_counter= 0; + xorriso->result_page_counter++; + if(ret<=0) + if(xorriso->result_page_length>0) + xorriso->result_page_length= -xorriso->result_page_length; + + cpt= line; + if(strcmp(cpt,"@@@")==0 || + strcmp(cpt,"x")==0 || strcmp(cpt,"X")==0 || + strcmp(cpt,"q")==0 || strcmp(cpt,"Q")==0) { + if(flag&1) { + strcpy(previous_line,cpt); + sprintf(xorriso->info_text, + "... [%s = %s registered. Really %s ? (y/n) ] ...\n", + cpt,abort_req_text,abort_really_text); + Xorriso_info(xorriso,0); + ret= Xorriso_dialog_input(xorriso,line,sizeof(line),1); + if(ret<=0) + return(ret); + cpt= line; + if(strcmp(cpt,previous_line)==0 || + ((*cpt=='Y' || *cpt=='y' || *cpt=='j' || *cpt=='J' || *cpt=='1') && + *(cpt+1)==0)) { + xorriso->request_to_abort= 1; + sprintf(xorriso->info_text, + "------- ( %s confirmed )\n",abort_req_text); + Xorriso_info(xorriso,0); + return(2); + } + sprintf(xorriso->info_text, "....... ( %s revoked )\n",abort_req_text); + Xorriso_info(xorriso,0); + return(3); + } + xorriso->request_to_abort= 1; + sprintf(xorriso->info_text, +"----------- [%s = request to abort registered. Operation ends ] ------------\n", + cpt); + Xorriso_info(xorriso,0); + return(2); + } else if(*cpt=='@') { + if(strcmp(cpt,"@@")==0) { + goto klammer_affe; + + } else if(strcmp(cpt,"@")==0) { +klammer_affe:; + if(xorriso->result_page_length>0) + xorriso->result_page_length= -xorriso->result_page_length; + if(flag&1) { + sprintf(xorriso->info_text, +"... [@ = prompt suppression registered. Prompting disabled temporarily ] ...\n"); + Xorriso_info(xorriso,0); + } + + } else { + Xorriso_dialog_input(xorriso,cpt,strlen(line)+1,2); /* write to history */ + sprintf(xorriso->info_text, + "--- Unrecognized input beginning with @. Please enter someting else.\n"); + Xorriso_info(xorriso,0); + return(3); + } + if(flag&2) + return(4); + if(flag&1) + return(3); + return(1); + } else if(flag&4) { + + if(strcmp(cpt,"i")==0 || strcmp(cpt,"I")==0 || + strcmp(cpt,"n")==0 || strcmp(cpt,"N")==0 || + *cpt==0) { + return(1); + } else if(strcmp(cpt,"r")==0 || strcmp(cpt,"R")==0 || + strcmp(cpt,"y")==0 || strcmp(cpt,"Y")==0) { + return(6); + } else { + /* >>> unknown input */ + sprintf(xorriso->info_text, + "--- Please enter one of : empty line, i,n, r,y, q,x, @, @@@\n"); + Xorriso_info(xorriso,0); + return(3); + } + + } else if(*cpt!=0 && !(flag&1)) { + Xorriso_dialog_input(xorriso,cpt,strlen(line)+1,2); /* write to history */ + strcpy(xorriso->pending_option,cpt); + xorriso->request_to_abort= 1; + sprintf(xorriso->info_text, +"-------------- [ Input of option registered. Operation ends ] ---------------\n"); + Xorriso_info(xorriso,0); + return(2); + + } else if(*cpt!=0) { + Xorriso_dialog_input(xorriso,cpt,strlen(line)+1,2); /* write to history */ + sprintf(xorriso->info_text, + "--- Please enter one of : empty line, @, @@@\n"); + Xorriso_info(xorriso,0); + return(3); + } + return(1); +} + + +/* @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) +{ + char line[5 * SfileadrL + 2], *linept, *fgot; + int l, base_length, append_line, ret, mem_linecount, i; + + Sfile_make_argv("", line, argc, argv, 2); + if(flag & 2) + return(1); + + mem_linecount= *linecount; + linept= line; + base_length= 0; + while(1) { + fgot= Sfile_fgets_n(linept, SfileadrL - base_length + 1, fp, + !!(flag & (1 | 8))); + if(fgot == NULL) { + if(ferror(fp)) + return(0); + if(linept != line) { + sprintf(xorriso->info_text,"Open quotation mark at end of input"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + return(2); + } + l= strlen(line); + (*linecount)++; + append_line= 0; + if(flag & 1) { /* check whether the line is incomplete yet */ + ret= Sfile_make_argv("", line, argc, argv, 16); + if(ret < 0) + return(ret); + if(ret == 0 && !append_line) { + line[l]= '\n'; + line[l + 1]= 0; + append_line= 1; + } + if(l > 0 && !append_line) + if(line[l - 1] == '\\') { + line[l - 1]= 0; + append_line= 1; + } + } + if(l >= SfileadrL) { + sprintf(xorriso->info_text,"Input line too long !"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if(!append_line) + break; + base_length= strlen(line); + linept= line + base_length; + } + if((flag & 1) && !(flag & 8)) { + ret= Sfile_make_argv("", line, argc, argv, + 1 | ((xorriso->bsl_interpretation & 3) << 5)); + if(ret < 0) + return(ret); + if(flag & 4) + for(i= 0; i < *argc; i++) { + if((*argv)[i][0] == 0) { + sprintf(xorriso->info_text, "Empty text as quoted argument in "); + } else if(strlen((*argv)[i]) >= SfileadrL) { + (*argv)[i][SfileadrL - 1]= 0; + sprintf(xorriso->info_text, + "Input text too long and now truncated in"); + } else + continue; + if(mem_linecount + 1 < *linecount) + sprintf(xorriso->info_text + strlen(xorriso->info_text), + "lines %d to %d", mem_linecount + 1, *linecount); + else + sprintf(xorriso->info_text + strlen(xorriso->info_text), + "line %d", mem_linecount + 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + } + } else { + (*argv)= Smem_malloC(sizeof(char *)); + if(argv == NULL) + return(-1); + (*argv)[0]= strdup(line); + if((*argv)[0] == NULL) + return(-1); + *argc= 1; + } + return(1); +} + + +int Xorriso_predict_linecount(struct XorrisO *xorriso, char *line, + int *linecount, int flag) +{ + int width,l; + char *spt,*ept; + + *linecount= 0; + spt= line; + width= xorriso->result_page_width; + while(1) { + ept= strchr(spt,'\n'); + if(ept==NULL) + l= strlen(spt); + else + l= ept-spt; + l+= xorriso->result_open_line_len; + if(ept!=NULL && l==0) + (*linecount)++; + else { + (*linecount)+= l/width; + if(ept==NULL) { + xorriso->result_open_line_len= l%width; + break; + } + (*linecount)+= !!(l%width); + } + xorriso->result_open_line_len= 0; + spt= ept+1; + } + return(1); +} + + +int Xorriso_pager(struct XorrisO *xorriso, char *line, int flag) +/* + bit1= mark '@' by return 4 +*/ +/* return: <=0 error , 1=go on , 2=abort , 4=see flag bit1*/ +{ + int ret,linecount; + char info_text[10*SfileadrL]; + + if(xorriso->result_page_length<=0 || xorriso->request_not_to_ask || + xorriso->dialog == 0) + return(1); + Xorriso_predict_linecount(xorriso,line,&linecount,0); + if(xorriso->result_line_counter+linecount>xorriso->result_page_length) { +ask_for_page:; + strcpy(info_text,xorriso->info_text); + sprintf(xorriso->info_text,"\n"); + Xorriso_info(xorriso,0); + sprintf(xorriso->info_text, +".... [Press Enter to continue. @,Enter avoids further stops. @@@ aborts] ....\n"); + Xorriso_info(xorriso,0); + ret= Xorriso_request_confirmation(xorriso,flag&2); + strcpy(xorriso->info_text,info_text); + if(ret<=0) + return(ret); + if(ret==2) + return(2); + if(ret==3) + goto ask_for_page; + } + xorriso->result_line_counter+= linecount; + return(1); +} + + +int Xorriso_write_to_channel(struct XorrisO *xorriso, + char *in_text, int channel_no, int flag) +/* + bit0= eventually backslash encode linefeeds + bit1= text is the name of the log file for the given channel + bit2= text is the name of the consolidated packet log file for all channels +bit15= with bit1 or bit2: close depicted log file +*/ +{ + char *rpt, *npt, *text; + int ret= 1, info_redirected= 0, result_redirected= 0; + char prefix[16]; + FILE *logfile_fp, *pktlog_fp; + struct Xorriso_lsT *msglist; + static int num_channels= 4; + static char channel_prefixes[4][4]= {".","R","I","M"}; + + if(channel_no<0 || channel_no>=num_channels) + {ret= -1; goto ex;} + + text= in_text; /* might change due to backslash encoding */ + + /* Logfiles */ + logfile_fp= xorriso->logfile_fp[channel_no]; + pktlog_fp= xorriso->pktlog_fp; + if((flag&2) && logfile_fp!=NULL) { + fprintf(logfile_fp, + "! end ! end ! end ! end ! end ! end ! end ! end xorriso log : %s : %s\n", + channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256)); + fclose(logfile_fp); + xorriso->logfile_fp[channel_no]= logfile_fp= NULL; + } + if((flag&4) && pktlog_fp!=NULL) { + fprintf(pktlog_fp, + "I:1:! end ! end ! end ! end ! end ! end ! end ! end xorriso log : %s : %s\n", + channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256)); + fclose(pktlog_fp); + xorriso->pktlog_fp= pktlog_fp= NULL; + } + if(flag&(1<<15)) + {ret= 1; goto ex;} + if((flag&2)) { + xorriso->logfile_fp[channel_no]= logfile_fp= fopen(text,"a"); + if(logfile_fp==NULL) + {ret= 0; goto ex;} + fprintf(logfile_fp, + "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! xorriso log : %s : %s\n", + channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256)); + fflush(logfile_fp); + } + if((flag&4)) { + xorriso->pktlog_fp= pktlog_fp= fopen(text,"a"); + if(pktlog_fp==NULL) + {ret= 0; goto ex;} + fprintf(pktlog_fp, + "I:1:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! xorriso log : . : %s\n", + Sfile_datestr(time(0),1|2|256)); + fflush(pktlog_fp); + } + if(flag&(2|4)) + {ret= 1; goto ex;} + + /* Eventually perform backslash encoding of non-printable characters */ + if(((xorriso->bsl_interpretation & 32) && channel_no == 1) || + ((xorriso->bsl_interpretation & 64) && channel_no == 2)) { + ret= Sfile_bsl_encoder(&text, text, strlen(text), 1 | 2 | 4); + if(ret <= 0) + {ret= -1; goto ex;} + } + + /* Eventually perform messag redirection */ + if(xorriso->msglist_stackfill > 0) { + if(xorriso->msglist_flags[xorriso->msglist_stackfill - 1] & 1) + result_redirected= 1; + if(xorriso->msglist_flags[xorriso->msglist_stackfill - 1] & 2) + info_redirected= 1; + } + if(result_redirected) { + if(channel_no==1 || channel_no==3) { + msglist= xorriso->result_msglists[xorriso->msglist_stackfill - 1]; + ret= Xorriso_lst_append_binary(&msglist, text, strlen(text) + 1, 0); + if(ret <= 0) + {ret= -1; goto ex;} + if(xorriso->result_msglists[xorriso->msglist_stackfill - 1] == NULL) + xorriso->result_msglists[xorriso->msglist_stackfill - 1]= msglist; + } + } + if(info_redirected) { + if(channel_no==2 || channel_no==3) { + msglist= xorriso->info_msglists[xorriso->msglist_stackfill - 1]; + ret= Xorriso_lst_append_binary(&msglist, text, strlen(text) + 1, 0); + if(ret <= 0) + {ret= -1; goto ex;} + if(xorriso->info_msglists[xorriso->msglist_stackfill - 1] == NULL) + xorriso->info_msglists[xorriso->msglist_stackfill - 1]= msglist; + } + } + if((channel_no == 1 && result_redirected) || + (channel_no == 2 && info_redirected) || + (result_redirected && info_redirected)) + {ret= 1; goto ex;} + + /* Non-redirected output */ + if(!xorriso->packet_output) { + if(channel_no==1 || channel_no==3) { + printf("%s",text); + fflush(stdout); + } + if(channel_no==2 || channel_no==3) + fprintf(stderr,"%s",text); + if(logfile_fp!=NULL) { + fprintf(logfile_fp,"%s",text); + fflush(logfile_fp); + } + if(pktlog_fp==NULL) + {ret= 1; goto ex;} + } + rpt= text; + sprintf(prefix,"%s:x: ",channel_prefixes[channel_no]); + while(*rpt!=0) { + npt= strchr(rpt,'\n'); + if(npt==NULL) + prefix[2]= '0'; + else + prefix[2]= '1'; + if(xorriso->packet_output) { + ret= fwrite(prefix,5,1,stdout); + if(ret<=0) + {ret= 0; goto ex;} + } + if(pktlog_fp!=NULL) { + ret= fwrite(prefix,5,1,pktlog_fp); + if(ret<=0) + {ret= 0; goto ex;} + } + if(npt==NULL) { + if(xorriso->packet_output) { + ret= fwrite(rpt,strlen(rpt),1,stdout); + if(ret<=0) + {ret= 0; goto ex;} + ret= fwrite("\n",1,1,stdout); + if(ret<=0) + {ret= 0; goto ex;} + } + if(pktlog_fp!=NULL) { + ret= fwrite(rpt,strlen(rpt),1,pktlog_fp); + if(ret<=0) + {ret= 0; goto ex;} + ret= fwrite("\n",1,1,pktlog_fp); + if(ret<=0) + {ret= 0; goto ex;} + } + break; + } else { + if(xorriso->packet_output) { + ret= fwrite(rpt,npt+1-rpt,1,stdout); + if(ret<=0) + {ret= 0; goto ex;} + } + if(pktlog_fp!=NULL) { + ret= fwrite(rpt,npt+1-rpt,1,pktlog_fp); + if(ret<=0) + {ret= 0; goto ex;} + } + } + rpt= npt+1; + } + if(xorriso->packet_output) + fflush(stdout); + if(pktlog_fp!=NULL) + fflush(pktlog_fp); + ret= 1; +ex: + if(text != in_text && text != NULL) + free(text); + return(ret); +} + + +int Xorriso_push_outlists(struct XorrisO *xorriso, int *stack_handle, + int flag) +{ + if(xorriso->msglist_stackfill + 1 >= Xorriso_max_outlist_stacK) { + Xorriso_msgs_submit(xorriso, 0, + "Overflow of message output redirection stack", 0, "FATAL", 0); + return(-1); + } + if((flag & 3) == 0) + flag|= 3; + xorriso->msglist_stackfill++; + xorriso->result_msglists[xorriso->msglist_stackfill - 1]= NULL; + xorriso->info_msglists[xorriso->msglist_stackfill - 1]= NULL; + xorriso->msglist_flags[xorriso->msglist_stackfill - 1]= flag & 3; + *stack_handle= xorriso->msglist_stackfill - 1; + return(1); +} + + +int Xorriso_pull_outlists(struct XorrisO *xorriso, int stack_handle, + struct Xorriso_lsT **result_list, + struct Xorriso_lsT **info_list, int flag) +{ + int i; + + if(stack_handle < 0 || stack_handle >= xorriso->msglist_stackfill) { + Xorriso_msgs_submit(xorriso, 0, + "Program error: Wrong message output redirection stack handle", + 0, "FATAL", 0); + return(-1); + } + *result_list= xorriso->result_msglists[stack_handle]; + *info_list= xorriso->info_msglists[stack_handle]; + for(i = stack_handle + 1; i < xorriso->msglist_stackfill - 1; i++) { + xorriso->result_msglists[i - 1]= xorriso->result_msglists[i]; + xorriso->info_msglists[i - 1]= xorriso->info_msglists[i]; + } + xorriso->msglist_stackfill--; + return(1); +} + + +int Xorriso_result(struct XorrisO *xorriso, int flag) +/* + bit0= no considerations or computations or dialog. Just put out. +*/ +{ + int ret, redirected= 0; + + if(flag&1) + goto put_it_out; + if(xorriso->request_to_abort) + return(1); + if(xorriso->msglist_stackfill > 0) + if(xorriso->msglist_flags[xorriso->msglist_stackfill - 1] & 1) + redirected= 1; + if(xorriso->result_page_length>0 && !redirected) { + ret= Xorriso_pager(xorriso,xorriso->result_line,2); + if(ret<=0) + return(ret); + if(ret==2) + return(1); + if(xorriso->request_to_abort) + return(1); + } +put_it_out:; + xorriso->bar_is_fresh= 0; + ret= Xorriso_write_to_channel(xorriso, xorriso->result_line, 1,0); + return(ret); +} + + +int Xorriso_info(struct XorrisO *xorriso, int flag) +/* + bit0= use pager (as with result) + bit1= permission to suppress output + bit2= insist in showing output +*/ +{ + int ret; + static int note_sev= 0; + + if(flag&2) + if(xorriso->request_to_abort) + return(1); + + if(note_sev==0) + Xorriso__text_to_sev("NOTE", ¬e_sev, 0); + if(note_sevreport_about_severity && + note_sevabort_on_severity && !(flag&4)) + return(1); + + if(flag&1) { + ret= Xorriso_pager(xorriso,xorriso->info_text,2); + if(ret<=0) + return(ret); + if(ret==2) + return(1); + if(flag&2) + if(xorriso->request_to_abort) + return(1); + } + xorriso->bar_is_fresh= 0; + ret=Xorriso_write_to_channel(xorriso, xorriso->info_text, 2, 0); + return(ret); +} + + +int Xorriso_mark(struct XorrisO *xorriso, int flag) +{ + int ret= 1,r_ret,i_ret; + + if(xorriso->mark_text[0]==0) + return(1); + if(xorriso->packet_output) + ret=Xorriso_write_to_channel(xorriso, xorriso->mark_text, 3, 0); + else { + sprintf(xorriso->result_line,"%s\n",xorriso->mark_text); + r_ret= Xorriso_result(xorriso,1); + strcpy(xorriso->info_text,xorriso->result_line); + i_ret= Xorriso_info(xorriso,0); + if(r_ret==0 || i_ret==0) + ret= 0; + } + return(ret); +} + + +int Xorriso_restxt(struct XorrisO *xorriso, char *text) +{ + int ret; + + strncpy(xorriso->result_line,text,sizeof(xorriso->result_line)-1); + xorriso->result_line[sizeof(xorriso->result_line)-1]= 0; + ret= Xorriso_result(xorriso,0); + return(ret); +} + + +/* @param flag bit0-7= purpose + 0= ERRFILE + 1= mark line (only to be put out if enabled) +*/ +int Xorriso_process_errfile(struct XorrisO *xorriso, + int error_code, char msg_text[], int os_errno, + int flag) +{ + char ttx[41]; + int purpose; + + if(strlen(msg_text)>SfileadrL) + return(-1); + + purpose= flag&255; + if(purpose==1 && !(xorriso->errfile_mode&1)) + return(2); + if(xorriso->errfile_fp!=NULL) { + if(purpose==1) + fprintf(xorriso->errfile_fp, "----------------- %s %s\n", + msg_text, Ftimetxt(time(0), ttx, 1)); + else + fprintf(xorriso->errfile_fp, "%s\n", msg_text); + fflush(xorriso->errfile_fp); + return(1); + } + if(xorriso->errfile_log[0]==0) + return(1); + if(strcmp(xorriso->errfile_log, "-")==0 || + strcmp(xorriso->errfile_log, "-R")==0) { + if(purpose==1) + sprintf(xorriso->result_line, "----------------- %s %s\n", + msg_text, Ftimetxt(time(0), ttx, 1)); + else + sprintf(xorriso->result_line, "%s\n", msg_text); + Xorriso_result(xorriso, 1); + return(1); + } + if(strcmp(xorriso->errfile_log, "-I")==0) { + if(purpose==1) + sprintf(xorriso->info_text, "ERRFILE_MARK=%s %s\n", + msg_text, Ftimetxt(time(0), ttx, 1)); + else + sprintf(xorriso->info_text, "ERRFILE=%s", msg_text); + Xorriso_info(xorriso, 0); + return(1); + } + return(2); +} + + +/* Note: It is ok to submit xorriso->info_text as msg_text here. */ +/* flag: + bit0= for Xorriso_info() : use pager (as with result) + bit1= for Xorriso_info() : permission to suppress output + bit2..5= name prefix + 0="xorriso" + 1="libisofs" + 2="libburn" + 3="libisoburn" + else: "" + bit6= append carriage return rather than line feed (if not os_errno) + bit7= perform Xorriso_process_msg_queues() first +*/ +int Xorriso_msgs_submit(struct XorrisO *xorriso, + int error_code, char msg_text[], int os_errno, + char severity[], int flag) +{ + int ret, lt, li, sev, i; + char *sev_text= "FATAL", prefix[80]; + static char pfx_list[20][16]= { + "xorriso : ", "libisofs: ", "libburn : ", "libisoburn: ", + "", "", "", "", "", "", "", "", "", "", "", "" }; + + if(flag&128) + Xorriso_process_msg_queues(xorriso, 0); + + if(strcmp(severity, "ERRFILE")==0) + Xorriso_process_errfile(xorriso, error_code, msg_text, os_errno, 0); + + /* Set problem status */ + ret= Xorriso__text_to_sev(severity, &sev, 0); + if(ret<=0) + Xorriso__text_to_sev(sev_text, &sev, 0); + else + sev_text= severity; + if(xorriso->problem_statusproblem_status= sev; + strcpy(xorriso->problem_status_text, sev_text); + } + if(xorriso->eternal_problem_statuseternal_problem_status= sev; + strcpy(xorriso->eternal_problem_status_text, sev_text); + } + + /* Report problem event */ + if(sevreport_about_severity && sevabort_on_severity) + return(2); + sprintf(prefix,"%s%s : ", pfx_list[(flag>>2)&15], sev_text); + li= strlen(prefix); + lt= strlen(msg_text); + if(lt>sizeof(xorriso->info_text)-li-2) + lt= sizeof(xorriso->info_text)-li-2; + if(msg_text==xorriso->info_text) { + for(i= lt; i>=0; i--) + msg_text[i+li]= msg_text[i]; + for(i=0; iinfo_text, prefix); + strncpy(xorriso->info_text+li, msg_text, lt); + } + if((flag&64) && os_errno<=0) + xorriso->info_text[li+lt]= '\r'; + else + xorriso->info_text[li+lt]= '\n'; + xorriso->info_text[li+lt+1]= 0; + Xorriso_info(xorriso,4|(flag&3)); + if(os_errno>0) { + sprintf(xorriso->info_text, "%ssys : %s\n", + pfx_list[(flag>>2)&15], strerror(os_errno)); + Xorriso_info(xorriso,4|(flag&3)); + } + return(1); +} + + +/* To be used with isoburn_set_msgs_submit() +*/ +int Xorriso_msgs_submit_void(void *xorriso, + int error_code, char msg_text[], int os_errno, + char severity[], int flag) +{ + int ret; + + ret= Xorriso_msgs_submit((struct XorrisO *) xorriso, error_code, msg_text, + os_errno, severity, flag); + return(ret); +} + + +/** @return -1= abort , 0= no , 1= yes +*/ +int Xorriso_reassure(struct XorrisO *xorriso, char *cmd, char *which_will, + int flag) +{ + int ret; + + if(!xorriso->do_reassure) + return(1); + sprintf(xorriso->info_text, "Really perform %s which will %s ? (y/n)\n", + cmd, which_will); + Xorriso_info(xorriso, 4); + do { + ret= Xorriso_request_confirmation(xorriso, 2|4|16); + } while(ret==3); + if(ret==6 || ret==4) { + sprintf(xorriso->info_text, "%s confirmed", cmd); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(1); + } + if(ret==2) { + sprintf(xorriso->info_text, "%s aborted", cmd); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(-1); + } + sprintf(xorriso->info_text, "%s revoked", cmd); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(0); +} + + +int Xorriso_write_session_log(struct XorrisO *xorriso, int flag) +{ + FILE *fp= NULL; + char sfe[5*SfileadrL], timetext[40], *rpt, *wpt; + + if(xorriso->session_logfile[0]==0) + return(2); + fp= fopen(xorriso->session_logfile, "a"); + if(fp==0) { + sprintf(xorriso->info_text, "-session_log: Cannot open file %s", + Text_shellsafe(xorriso->session_logfile, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + wpt= sfe; + for(rpt= xorriso->volid; *rpt!=0; rpt++) { + if(*rpt=='\n') { + *(wpt++)= '\\'; + *(wpt++)= 'n'; + } else + *(wpt++)= *rpt; + } + *wpt= 0; + fprintf(fp, "%s %d %d %s\n", + Ftimetxt(time(0), timetext, 2), xorriso->session_lba, + xorriso->session_blocks, sfe); + fclose(fp); + return(1); +} + + +int Xorriso_status_filter(struct XorrisO *xorriso, char *filter, char *line, + int flag) +{ + if(filter!=NULL) + if(filter[0]=='-') + if(strncmp(filter, line, strlen(filter))!=0) + return(0); + return(1); +} + + +int Xorriso_status_result(struct XorrisO *xorriso, char *filter, FILE *fp, + int flag) +/* +bit1= do only report to fp +*/ +{ + int ret; + + ret= Xorriso_status_filter(xorriso, filter, xorriso->result_line, 0); + if(ret <= 0) + return(2); + if(!(flag&2)) + Xorriso_result(xorriso,0); + if(fp!=NULL) { + ret= fwrite(xorriso->result_line,strlen(xorriso->result_line),1,fp); + if(ret<=0) + return(ret); + } + return(1); +} + + +int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) +/* + bit0= do only report non-default settings + bit1= do only report to fp + bit2= report current -resume status even if bit0 is set, but only if valid + bit3= report readline history + bit4= report -resume options indirectly as + -options_from_file:${resume_state_file}_pos +*/ +{ + int is_default, no_defaults, i, ret, adr_mode, do_single; + int show_indev= 1, show_outdev= 1, show_dev= 0; + int part_table_implicit= 0; + char *line, sfe[5 * SfileadrL + 80], mode[80], *form, *treatment; + char *in_pt, *out_pt, *nl_charset, *local_charset, *mode_pt; + char *dev_filter= NULL; + static char channel_prefixes[4][4]= {".","R","I","M"}; + static char load_names[][20]= {"auto", "session", "track", "lba", "volid"}; + static int max_load_mode= 4; + struct Xorriso_lsT *paths, *leafs, *s; + + no_defaults= flag&1; + line= xorriso->result_line; + + if(xorriso->no_rc) { + sprintf(line,"-no_rc\n"); + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + + is_default= strcmp(xorriso->list_delimiter, "--") == 0; + sprintf(line,"-list_delimiter %s\n", xorriso->list_delimiter); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= 0; + if(xorriso->dialog == 2) + sprintf(line,"-dialog on\n"); + else if(xorriso->dialog == 1) + sprintf(line,"-dialog single_line\n"); + else { + sprintf(line,"-dialog off\n"); + is_default= 1; + } + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->result_page_length==0 && xorriso->result_page_width==80); + sprintf(line,"-page %d %d\n", + (xorriso->result_page_length>=0?xorriso->result_page_length + :-xorriso->result_page_length), + xorriso->result_page_width); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->use_stdin==0); + sprintf(line,"-use_readline %s\n", (xorriso->use_stdin?"off":"on")); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->bsl_interpretation == 0); + strcpy(line, "-backslash_codes "); + if(xorriso->bsl_interpretation == 0) + strcat(line, "off"); + else if(xorriso->bsl_interpretation == (3 | 16 | 32 | 64)) + strcat(line, "on"); + else { + if((xorriso->bsl_interpretation & 3) == 1) + strcat(line, "in_double_quotes"); + else if((xorriso->bsl_interpretation & 3) == 2) + strcat(line, "in_quotes"); + else if((xorriso->bsl_interpretation & 3) == 3) + strcat(line, "with_quoted_input"); + if(xorriso->bsl_interpretation & 16) { + if(strlen(line) > 17) + strcat(line, ":"); + strcat(line, "with_program_arguments"); + } + if((xorriso->bsl_interpretation & (32 | 64)) == (32 | 64)) { + if(strlen(line) > 17) + strcat(line, ":"); + strcat(line, "encode_output"); + } else { + if(xorriso->bsl_interpretation & 32) { + if(strlen(line) > 17) + strcat(line, ":"); + strcat(line, "encode_results"); + } + if(xorriso->bsl_interpretation & 64) { + if(strlen(line) > 17) + strcat(line, ":"); + strcat(line, "encode_infos"); + } + } + } + strcat(line, "\n"); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= !xorriso->packet_output; + sprintf(line,"-pkt_output %s\n",(xorriso->packet_output?"on":"off")); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + for(i=0;i<4;i++) { + is_default= (xorriso->logfile[i]!=0); + sprintf(line,"-logfile %s %s\n", + channel_prefixes[i],Text_shellsafe(xorriso->logfile[i],sfe,0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + + is_default= (xorriso->errfile_log[0]==0); + sprintf(line,"-errfile_log %s\n",Text_shellsafe(xorriso->errfile_log,sfe,0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + if(xorriso->check_media_default == NULL) { + is_default= 1; + sprintf(line, "-check_media_defaults reset=now %s\n", + xorriso->list_delimiter); + } else { + ret= Xorriso_check_media_list_job(xorriso, xorriso->check_media_default, + line, no_defaults); + is_default= (ret == 2); + strcat(line, "\n"); + } + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->img_read_error_mode==2); + treatment= "best_effort"; + if(xorriso->img_read_error_mode==1) + treatment= "failure"; + else if(xorriso->img_read_error_mode==2) + treatment= "fatal"; + sprintf(line,"-error_behavior image_loading %s\n", treatment); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + is_default= (xorriso->extract_error_mode == 1); + treatment= "keep"; + if(xorriso->extract_error_mode == 0) + treatment= "best_effort"; + else if(xorriso->extract_error_mode == 2) + treatment= "delete"; + sprintf(line,"-error_behavior file_extraction %s\n", treatment); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->mark_text[0]==0); + sprintf(line,"-mark %s\n",Text_shellsafe(xorriso->mark_text,sfe,0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->temp_mem_limit==16*1024*1024); + if((xorriso->temp_mem_limit/1024/1024)*1024*1024==xorriso->temp_mem_limit) + sprintf(line,"-temp_mem_limit %dm\n", xorriso->temp_mem_limit/1024/1024); + else + sprintf(line,"-temp_mem_limit %dk\n", xorriso->temp_mem_limit/1024); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + + sprintf(line,"-prog %s\n",Text_shellsafe(xorriso->progname,sfe,0)); + Xorriso_status_result(xorriso,filter,fp,flag&2); + + if(xorriso->ban_stdio_write) { + sprintf(line,"-ban_stdio_write\n"); + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + + is_default= (xorriso->allow_restore==0 && xorriso->do_concat_split==1 && + xorriso->do_auto_chmod==0 && xorriso->drives_exclusive == 1); + mode_pt= "off"; + if(xorriso->allow_restore == -1) + mode_pt= "banned"; + else if(xorriso->allow_restore == 1) + mode_pt= "on"; + else if(xorriso->allow_restore == 2) + mode_pt= "device_files"; + if(xorriso->allow_restore == -1) + sprintf(line,"-osirrox %s\n", mode_pt); + else + sprintf(line,"-osirrox %s:%s:%s:%s:%s\n", mode_pt, + xorriso->do_concat_split ? "concat_split_on" : "concat_split_off", + xorriso->do_auto_chmod ? "auto_chmod_on" : "auto_chmod_off", + xorriso->do_restore_sort_lba ? "sort_lba_on" : "sort_lba_off", + xorriso->drives_exclusive ? "o_excl_on" : "o_excl_off" + ); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->mount_opts_flag == 0); + sprintf(line,"-mount_opts %s\n", + xorriso->mount_opts_flag & 1 ? "shared" : "exclusive"); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + Xorriso_boot_image_status(xorriso, filter, fp, flag & 3); + + is_default= (xorriso->system_area_disk_path[0] == 0); + sprintf(line,"-boot_image %s system_area=%s\n", + xorriso->system_area_disk_path[0] && (xorriso->system_area_options & 2) + ? "isolinux" : "any", + Text_shellsafe(xorriso->system_area_disk_path, sfe, 0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + if(xorriso->system_area_disk_path[0] || !part_table_implicit) { + is_default= ((xorriso->system_area_options & 3) == 0); + sprintf(line,"-boot_image %s partition_table=%s\n", + xorriso->system_area_options & 2 ? "isolinux" : "grub", + xorriso->system_area_options & 3 ? "on" : "off"); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + +#ifdef Xorriso_with_isohybriD + if(strcmp(form, "isolinux") == 0) { + static char modes[4][6]= {"off", "auto", "on", "force"}; + is_default= (xorriso->boot_image_isohybrid == 1); + sprintf(line,"-boot_image isolinux isohybrid=%s\n", + modes[xorriso->boot_image_isohybrid & 3]); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + } +#endif /* Xorriso_with_isohybriD */ + + sprintf(line,"-cd %s\n", + (xorriso->wdi[0] ? Text_shellsafe(xorriso->wdi,sfe,0) : "'/'")); + Xorriso_status_result(xorriso,filter,fp,flag&2); + sprintf(line,"-cdx %s\n", + (xorriso->wdx[0] ? Text_shellsafe(xorriso->wdx,sfe,0) : "'/'")); + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->split_size==0); + strcpy(line,"-split_size "); + if(xorriso->split_size % (1024*1024) || xorriso->split_size==0) { + Sfile_off_t_text(line+strlen(line), xorriso->split_size, 0); + } else { + Sfile_off_t_text(line+strlen(line), xorriso->split_size / (1024*1024), 0); + strcat(line, "m"); + } + strcat(line, "\n"); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->add_plainly==0); + sprintf(line,"-add_plainly %s\n", + (xorriso->add_plainly == 1 ? "unknown" : + xorriso->add_plainly == 2 ? "dashed" : + xorriso->add_plainly == 3 ? "any" : "none")); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + ret= Exclusions_get_descrs(xorriso->disk_exclusions, &paths, &leafs, 0); + if(ret>0) { + for(; paths!=NULL; paths= paths->next) { + sprintf(line, "-not_paths %s %s\n", + Text_shellsafe(paths->text, sfe, 0), xorriso->list_delimiter); + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + for(; leafs!=NULL; leafs= leafs->next) { + sprintf(line,"-not_leaf %s\n", Text_shellsafe(leafs->text, sfe, 0)); + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + } + + is_default= (xorriso->file_size_limit == + Xorriso_default_file_size_limiT); + if(xorriso->file_size_limit <= 0) + sprintf(line, "-file_size_limit off %s\n", xorriso->list_delimiter); + else + sprintf(line, "-file_size_limit %.f %s\n", + (double) xorriso->file_size_limit, xorriso->list_delimiter); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->disk_excl_mode==1); + sprintf(line, "-not_mgt %s:%s:%s:%s\n", + (xorriso->disk_excl_mode&1 ? "on" : "off"), + (xorriso->disk_excl_mode&2 ? "param_on" : "param_off"), + (xorriso->disk_excl_mode&4 ? "subtree_on" : "subtree_off"), + (xorriso->disk_excl_mode&8 ? "ignore_on" : "ignore_off")); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->do_iso_rr_pattern==1); + sprintf(line,"-iso_rr_pattern %s\n", + (xorriso->do_iso_rr_pattern == 1 ? "on" : + (xorriso->do_iso_rr_pattern == 2 ? "ls" : "off"))); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->do_disk_pattern==2); + sprintf(line,"-disk_pattern %s\n", + (xorriso->do_disk_pattern == 1 ? "on" : + (xorriso->do_disk_pattern == 2 ? "ls" : "off"))); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= xorriso->volid_default; + sprintf(line,"-volid %s\n",Text_shellsafe(xorriso->volid,sfe,0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + if(is_default && xorriso->loaded_volid[0] && + strcmp(xorriso->loaded_volid, xorriso->volid)!=0 && !no_defaults) { + sprintf(line,"# loaded image effective -volid %s\n", + Text_shellsafe(xorriso->loaded_volid,sfe,0)); + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + + is_default= (xorriso->publisher[0]==0); + sprintf(line,"-publisher %s\n",Text_shellsafe(xorriso->publisher,sfe,0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->application_id[0]==0); + sprintf(line,"-application_id %s\n", + Text_shellsafe(xorriso->application_id,sfe,0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->system_id[0]==0); + sprintf(line,"-system_id %s\n", Text_shellsafe(xorriso->system_id,sfe,0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->volset_id[0]==0); + sprintf(line,"-volset_id %s\n", Text_shellsafe(xorriso->volset_id,sfe,0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->vol_creation_time == 0); + sprintf(line,"-volume_date c %s\n", + is_default ? "default" : + Ftimetxt(xorriso->vol_creation_time, sfe, 2)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->vol_modification_time == 0); + sprintf(line,"-volume_date m %s\n", + xorriso->vol_uuid[0] ? "overridden" : + is_default ? "default" : + Ftimetxt(xorriso->vol_modification_time, sfe, 2)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->vol_expiration_time == 0); + sprintf(line,"-volume_date x %s\n", + is_default ? "default" : + Ftimetxt(xorriso->vol_expiration_time, sfe, 2)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->vol_effective_time == 0); + sprintf(line,"-volume_date f %s\n", + is_default ? "default" : + Ftimetxt(xorriso->vol_effective_time, sfe, 2)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->vol_uuid[0] == 0); + sprintf(line,"-volume_date uuid %s\n", + Text_shellsafe(xorriso->vol_uuid,sfe,0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->do_joliet==0); + sprintf(line,"-joliet %s\n", (xorriso->do_joliet == 1 ? "on" : "off")); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + if(xorriso->do_global_uid) { + sprintf(line,"-uid %lu\n", (unsigned long) xorriso->global_uid); + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + + if(xorriso->do_global_gid) { + sprintf(line,"-gid %lu\n", (unsigned long) xorriso->global_gid); + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + + Xorriso_status_extf(xorriso, filter, fp, flag & 2); + Xorriso_status_zisofs(xorriso, filter, fp, flag & 3); + + is_default= !xorriso->allow_graft_points; + sprintf(line,"-pathspecs %s\n", xorriso->allow_graft_points ? "on" : "off"); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->do_follow_pattern && (!xorriso->do_follow_param) + && xorriso->do_follow_mount && (!xorriso->do_follow_links) + && xorriso->follow_link_limit==100); + mode[0]= 0; + if(xorriso->do_follow_pattern && + !(xorriso->do_follow_links && xorriso->do_follow_mount)) + strcat(mode,":pattern"); + if(xorriso->do_follow_param && !(xorriso->do_follow_links)) + strcat(mode,":param"); + if(xorriso->do_follow_links) + strcat(mode,":link"); + if(xorriso->do_follow_mount) + strcat(mode,":mount"); + if(mode[0]==0) + strcpy(mode, ":off"); + sprintf(mode+strlen(mode), ":limit=%d", xorriso->follow_link_limit); + sprintf(line,"-follow %s\n", mode+1); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->do_overwrite==2); + sprintf(line,"-overwrite %s\n",(xorriso->do_overwrite == 1 ? "on" : + (xorriso->do_overwrite == 2 ? "nondir" : "off"))); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= !xorriso->do_reassure; + sprintf(line,"-reassure %s\n",(xorriso->do_reassure == 1 ? "on" : + (xorriso->do_reassure == 2 ? "tree" : "off"))); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= !xorriso->do_close; + sprintf(line,"-close %s\n",(xorriso->do_close ? "on" : "off")); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= !xorriso->do_dummy; + sprintf(line,"-dummy %s\n",(xorriso->do_dummy ? "on" : "off")); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->speed==0); + sprintf(line,"-speed %dkB/s\n", xorriso->speed); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->do_stream_recording==0); + strcpy(mode, "off"); + if(xorriso->do_stream_recording == 1) + strcpy(mode, "full"); + if(xorriso->do_stream_recording == 2) + strcpy(mode, "data"); + else if(xorriso->do_stream_recording == 32) + strcpy(mode, "on"); + else if(xorriso->do_stream_recording >= 16) + sprintf(mode, "%ds", xorriso->do_stream_recording); + sprintf(line,"-stream_recording %s\n", mode); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->dvd_obs == 0); + strcpy(mode, "default"); + if(xorriso->dvd_obs == 32768 || xorriso->dvd_obs == 65536) + sprintf(mode, "%dk", xorriso->dvd_obs / 1024); + sprintf(line,"-dvd_obs %s\n", mode); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->stdio_sync == 0); + strcpy(line, "-stdio_sync "); + if(xorriso->stdio_sync == -1) + strcat(line, "off"); + else if(xorriso->stdio_sync == 0) + strcat(line, "on"); + else if(xorriso->stdio_sync % 512) { + Sfile_off_t_text(line+strlen(line), (off_t) (xorriso->stdio_sync * 2048), + 0); + } else { + Sfile_off_t_text(line+strlen(line), (off_t) (xorriso->stdio_sync / 512), 0); + strcat(line, "m"); + } + strcat(line, "\n"); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->fs==4*512); + if((xorriso->fs/512)*512==xorriso->fs) + sprintf(line,"-fs %dm\n", xorriso->fs/512); + else + sprintf(line,"-fs %dk\n", xorriso->fs*2); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->padding==300*1024); + sprintf(line,"-padding %dk\n", xorriso->padding/1024); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (strcmp(xorriso->report_about_text,"UPDATE")==0); + sprintf(line,"-report_about %s\n",xorriso->report_about_text); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->scsi_log == 0); + sprintf(line,"-scsi_log %s\n", xorriso->scsi_log ? "on" : "off"); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->session_logfile[0]==0); + sprintf(line,"-session_log %s\n", + Text_shellsafe(xorriso->session_logfile,sfe,0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->pacifier_style==0); + sprintf(line,"-pacifier '%s'\n", + xorriso->pacifier_style==1 ? "mkisofs" : + xorriso->pacifier_style==2 ? "cdrecord" : "xorriso"); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (strcmp(xorriso->return_with_text,"SORRY")==0 && + xorriso->return_with_value==32); + sprintf(line,"-return_with %s %d\n", + xorriso->return_with_text, xorriso->return_with_value); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (strcmp(xorriso->abort_on_text,"FATAL")==0); + sprintf(line,"-abort_on %s\n",xorriso->abort_on_text); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + if(xorriso->status_history_max!=Xorriso_status_history_maX || !no_defaults) { + sprintf(line,"-status_history_max %d\n",xorriso->status_history_max); + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + +#ifdef Xorriso_with_readlinE + + if((flag&8) && xorriso->status_history_max>0) { + HIST_ENTRY **hl; + int hc,i; + + hl= history_list(); + if(hl!=NULL) { + for(hc= 0;hl[hc]!=NULL;hc++); + if(hc>0) + if(strcmp(hl[hc-1]->line,"-end")==0) + hc--; + if(hc>=xorriso->status_history_max) + i= hc-xorriso->status_history_max; + else + i= 0; + for(;iline,sfe,0)); + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + } + } + +#endif /* Xorriso_with_readlinE */ + + is_default= (xorriso->toc_emulation_flag == 0); + sprintf(line,"-rom_toc_scan %s%s\n", + xorriso->toc_emulation_flag & 4 ? "force" : + xorriso->toc_emulation_flag & 1 ? "on" : "off", + xorriso->toc_emulation_flag & 2 ? ":emul_off" : ""); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso, filter, fp, flag & 2); + + adr_mode= xorriso->image_start_mode & 0xffff; + if(adr_mode>=0 && adr_mode<=max_load_mode) { + is_default= (adr_mode==0); + sprintf(line,"-load %s ", load_names[adr_mode]); + if(adr_mode==0) + sprintf(line+strlen(line),"''\n"); + else if(adr_mode>=1 && adr_mode<=3) + sprintf(line+strlen(line),"%s\n", xorriso->image_start_value); + else + sprintf(line+strlen(line),"%s\n", + Text_shellsafe(xorriso->image_start_value, sfe, 0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + + is_default= (xorriso->do_calm_drive & 1); + sprintf(line,"-calm_drive %s\n", xorriso->do_calm_drive & 1 ? "on" : "off"); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->grow_blindly_msc2<0); + sprintf(sfe, "%d", xorriso->grow_blindly_msc2); + sprintf(line,"-grow_blindly %s\n", + xorriso->grow_blindly_msc2 < 0 ? "off" : sfe); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + Xorriso_get_local_charset(xorriso, &local_charset, 0); + nl_charset= nl_langinfo(CODESET); + is_default= (strcmp(local_charset, nl_charset) == 0); + sprintf(line, "-local_charset %s\n", Text_shellsafe(local_charset, sfe, 0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso, filter, fp, flag & 2); + + is_default= (xorriso->out_charset == NULL && xorriso->in_charset == NULL); + in_pt= ""; + if(xorriso->in_charset != NULL) + in_pt= xorriso->in_charset; + out_pt= ""; + if(xorriso->out_charset != NULL) + out_pt= xorriso->out_charset; + do_single= 0; + ret= Xorriso_status_filter(xorriso, filter, "-in_charset", 0); + if(ret <= 0) + ret= Xorriso_status_filter(xorriso, filter, "-out_charset", 0); + if(ret > 0) + do_single= 1; + if(strcmp(in_pt, out_pt) == 0 && !do_single) { + sprintf(line, "-charset %s\n", Text_shellsafe(in_pt, sfe, 0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso, filter, fp, flag & 2); + } else { + sprintf(line, "-in_charset %s\n", Text_shellsafe(in_pt, sfe, 0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso, filter, fp, flag & 2); + sprintf(line, "-out_charset %s\n", Text_shellsafe(out_pt, sfe, 0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso, filter, fp, flag & 2); + } + is_default= ((xorriso->do_aaip & (256 | 512)) == 0); + sprintf(line,"-auto_charset %s\n", (xorriso->do_aaip & 256 ? "on" : "off")); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= ((xorriso->ino_behavior & 31) == 7); + switch (xorriso->ino_behavior & 15) { + case 0: form= "on"; + break; case 8: form= "without_update"; + break; default: form= "off"; + } + sprintf(line,"-hardlinks %s:%s\n", form, + xorriso->ino_behavior & 16 ? + "cheap_sorted_extract" : "normal_extract"); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= ((xorriso->do_aaip & (1 | 4)) == 0); + sprintf(line,"-acl %s\n", (xorriso->do_aaip & 1 ? "on" : "off")); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + is_default= ((xorriso->do_aaip & (2 | 8)) == 0); + sprintf(line,"-xattr %s\n", (xorriso->do_aaip & 4 ? "on" : "off")); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + is_default= ((xorriso->do_aaip & (16 | 32 | 64)) == 0); + sprintf(line,"-disk_dev_ino %s\n", + (xorriso->do_aaip & 16 ? (xorriso->do_aaip & 128 ? "ino_only" : "on" ) + : "off")); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= ((xorriso->do_md5 & 31) == 0); + sprintf(line, "-md5 "); + if(xorriso->do_md5 & 1) { + if((xorriso->do_md5 & (8)) == (8)) { + strcat(line, "all\n"); + } else { + strcat(line, "on"); + if(xorriso->do_md5 & 8) + strcat(line, ":stability_check_on"); + strcat(line, "\n"); + } + } else + strcat(line, "off\n"); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->scdbackup_tag_name[0] == 0 && + xorriso->scdbackup_tag_listname[0] == 0); + sprintf(line, "-scdbackup_tag "); + Text_shellsafe(xorriso->scdbackup_tag_listname, line, 1); + strcat(line, " "); + Text_shellsafe(xorriso->scdbackup_tag_name, line, 1); + strcat(line, "\n"); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (Xorriso_get_relax_text(xorriso, sfe, 0) == 2); + sprintf(line,"-compliance %s\n", sfe); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= (xorriso->assert_volid[0] == 0); + sprintf(line, "-assert_volid "); + Text_shellsafe(xorriso->assert_volid, line, 1); + strcat(line, " "); + Text_shellsafe(xorriso->assert_volid_sev, line, 1); + strcat(line, "\n"); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + + is_default= 1; + if(xorriso->drive_blacklist != NULL || xorriso->drive_whitelist != NULL || + xorriso->drive_greylist == NULL) + is_default= 0; + if(xorriso->drive_greylist != NULL) { + if(strcmp(Xorriso_get_pattern(xorriso, xorriso->drive_greylist, 0, 0), + "/dev") != 0) + is_default= 0; + if(Xorriso_get_pattern(xorriso, xorriso->drive_greylist, 1, 0) != NULL) + is_default= 0; + } + if(!(is_default && no_defaults)) { + for(s= xorriso->drive_blacklist; s != NULL; s= Xorriso_lst_get_next(s, 0)) { + sprintf(line, "-drive_class 'banned' %s\n", + Text_shellsafe(Xorriso_lst_get_text(s, 0), sfe, 0)); + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + for(s= xorriso->drive_greylist; s != NULL; s= Xorriso_lst_get_next(s, 0)) { + sprintf(line, "-drive_class 'caution' %s\n", + Text_shellsafe(Xorriso_lst_get_text(s, 0), sfe, 0)); + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + for(s= xorriso->drive_whitelist; s != NULL; s= Xorriso_lst_get_next(s, 0)) { + sprintf(line, "-drive_class 'harmless' %s\n", + Text_shellsafe(Xorriso_lst_get_text(s, 0), sfe, 0)); + Xorriso_status_result(xorriso,filter,fp,flag&2); + } + } + + do_single= 0; + dev_filter= filter; + if(dev_filter != NULL) { + show_dev= Xorriso_status_filter(xorriso, filter, "-dev", 0); + if(show_dev > 0) + dev_filter= NULL; + } + if(dev_filter != NULL) { + show_indev= Xorriso_status_filter(xorriso, filter, "-indev", 0); + show_outdev= Xorriso_status_filter(xorriso, filter, "-outdev", 0); + if(show_outdev > 0 || show_indev > 0) + do_single= 1; + } + if(xorriso->drives_exclusive != xorriso->indev_is_exclusive && + xorriso->indev[0]) + do_single= 1; + else if(xorriso->drives_exclusive != xorriso->outdev_is_exclusive && + xorriso->outdev[0]) + do_single= 1; + if(strcmp(xorriso->indev, xorriso->outdev) == 0 && !do_single) { + sprintf(line,"-dev %s\n", Text_shellsafe(xorriso->indev,sfe,0)); + Xorriso_status_result(xorriso, dev_filter, fp, flag & 2); + } else { + if(xorriso->drives_exclusive != xorriso->indev_is_exclusive && + xorriso->indev[0] && show_indev) { + sprintf(line,"-osirrox o_excl_%s\n", + xorriso->indev_is_exclusive ? "on" : "off"); + Xorriso_status_result(xorriso, NULL, fp, flag & 2); + } + sprintf(line,"-indev %s\n", Text_shellsafe(xorriso->indev,sfe,0)); + Xorriso_status_result(xorriso, dev_filter, fp, flag & 2); + if(xorriso->drives_exclusive != xorriso->indev_is_exclusive && + xorriso->indev[0] && show_indev) { + sprintf(line,"-osirrox o_excl_%s\n", + xorriso->drives_exclusive ? "on" : "off"); + Xorriso_status_result(xorriso, NULL, fp, flag & 2); + } + + if(xorriso->drives_exclusive != xorriso->outdev_is_exclusive && + xorriso->outdev[0] && show_outdev) { + sprintf(line,"-osirrox o_excl_%s\n", + xorriso->outdev_is_exclusive ? "on" : "off"); + Xorriso_status_result(xorriso, NULL, fp, flag & 2); + } + sprintf(line,"-outdev %s\n", Text_shellsafe(xorriso->outdev,sfe,0)); + Xorriso_status_result(xorriso, dev_filter, fp, flag & 2); + if(xorriso->drives_exclusive != xorriso->outdev_is_exclusive && + xorriso->outdev[0] && show_outdev) { + sprintf(line,"-osirrox o_excl_%s\n", + xorriso->drives_exclusive ? "on" : "off"); + Xorriso_status_result(xorriso, NULL, fp, flag & 2); + } + } + + return(1); +} + + +int Xorriso_pacifier_reset(struct XorrisO *xorriso, int flag) +{ + xorriso->start_time= Sfile_microtime(0); + xorriso->last_update_time= xorriso->start_time; + xorriso->pacifier_count= 0; + xorriso->pacifier_total= 0; + xorriso->pacifier_byte_count= 0; + return(1); +} + + +/* 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 + bit1= report count <=0 (no thank you for being patient then) + bit2= report xorriso->pacifier_byte_count + bit6= report with carriage return rather than line feed +*/ +int Xorriso_pacifier_callback(struct XorrisO *xorriso, char *what_done, + off_t count, off_t todo, char *current_object, + int flag) +{ + double current_time, since; + char count_text[80], byte_text[80]; + + current_time= Sfile_microtime(0); + if(current_time - xorriso->last_update_time < xorriso->pacifier_interval + && !(flag&1)) + return(1); + xorriso->last_update_time= Sfile_microtime(0); + since= current_time - xorriso->start_time; + if((flag&1)&&since<1.0) + since= 1.0; + byte_text[0]= 0; + if(flag&4) { + strcat(byte_text, " ("); + Sfile_scale((double) xorriso->pacifier_byte_count, + byte_text+strlen(byte_text), 7, 1e5, 0); + strcat(byte_text, ")"); + } + if(count<=0.0 && !(flag&2)) { + sprintf(xorriso->info_text, + "Thank you for being patient for %.f seconds", since); + } else if(todo<=0.0) { + if(count<10000000) + sprintf(count_text, "%.f", (double) count); + else + Sfile_scale((double) count, count_text, 7, 1e5, 1); + sprintf(xorriso->info_text, "%s %s%s in %.f %s", + count_text, what_done, byte_text, since, (flag&64) ? "s" : "seconds"); + } else { + sprintf(xorriso->info_text, "%.f of %.f %s%s in %.f seconds", + (double) count, (double) todo, what_done, byte_text, since); + } + if(current_object[0]!=0) + sprintf(xorriso->info_text+strlen(xorriso->info_text), + ", now at %s", current_object); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", (flag&64)); + return(1); +} + + +int Xorriso_reset_counters(struct XorrisO *xorriso, int flag) +{ + xorriso->error_count= 0; + xorriso->insert_count= 0; + xorriso->insert_bytes= 0; + Xorriso_pacifier_reset(xorriso, 0); + return(1); +} + + +int Xorriso_no_malloc_memory(struct XorrisO *xorriso, char **to_free, int flag) +{ + if(to_free!=NULL) + if(*to_free!=NULL) { + /* Eventual memory sacrifice to get on going */ + free(*to_free); + *to_free= NULL; + } + sprintf(xorriso->info_text, "Out of virtual memory"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "ABORT", 0); + return(1); +} + + +/* @param flag bit0=path is in source filesystem , bit1= unconditionally */ +int Xorriso_much_too_long(struct XorrisO *xorriso, int len, int flag) +{ + if(len>=SfileadrL || (flag&2)) { + sprintf(xorriso->info_text, + "Path given for %s is much too long (%d)", + ((flag&1) ? "local filesystem" : "ISO image"), len); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + return(1); +} + + +int Xorriso_no_findjob(struct XorrisO *xorriso, char *cmd, int flag) +{ + sprintf(xorriso->info_text, "%s: cannot create find job object", cmd); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + return(1); +} + + +int Xorriso_report_md5_outcome(struct XorrisO *xorriso, char *severity, + int flag) +{ + int has_md5; + + has_md5= Xorriso_image_has_md5(xorriso, 0); + if(xorriso->find_check_md5_result & 1) { + sprintf(xorriso->result_line, + "Mismatch detected between file contents and MD5 checksums.\n"); + } else if(xorriso->find_check_md5_result & 8) { + sprintf(xorriso->result_line, + "File contents and their MD5 checksums match.\n"); + } else { + sprintf(xorriso->result_line, + "Not a single file with MD5 checksum was found."); + if(has_md5 <= 0) + strcat(xorriso->result_line, + " (There is no MD5 checksum array loaded.)\n"); + else + strcat(xorriso->result_line, "\n"); + } + Xorriso_result(xorriso,0); + if(xorriso->find_check_md5_result & 2) { + sprintf(xorriso->result_line, + "Encountered errors other than non-match during MD5 checking.\n"); + Xorriso_result(xorriso,0); + } + if((xorriso->find_check_md5_result & 4) && has_md5) { + sprintf(xorriso->result_line, + "There were data files which have no MD5 and thus could not be checked.\n"); + Xorriso_result(xorriso,0); + } + if((xorriso->find_check_md5_result & 3) && strcmp(severity, "ALL") != 0) { + sprintf(xorriso->info_text, "Event triggered by MD5 comparison mismatch"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, severity, 0); + } + return(1); +} + diff --git a/xorriso/text_io.h b/xorriso/text_io.h new file mode 100644 index 00000000..7544fac1 --- /dev/null +++ b/xorriso/text_io.h @@ -0,0 +1,90 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/write_run.c b/xorriso/write_run.c new file mode 100644 index 00000000..9cbc438d --- /dev/null +++ b/xorriso/write_run.c @@ -0,0 +1,2106 @@ + + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + Provided under GPL version 2 or later. + + This file contains functions which are needed to write sessions. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "xorriso.h" +#include "xorriso_private.h" + +#include "lib_mgt.h" +#include "drive_mgt.h" +#include "iso_img.h" +#include "iso_tree.h" +#include "write_run.h" + + +int Xorriso_make_write_options( + struct XorrisO *xorriso, struct burn_drive *drive, + struct burn_write_opts **burn_options, int flag) +{ + int drive_role, stream_mode= 0; + + *burn_options= burn_write_opts_new(drive); + if(*burn_options==NULL) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text,"Cannot allocate option set"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + burn_write_opts_set_simulate(*burn_options, !!xorriso->do_dummy); + drive_role= burn_drive_get_drive_role(drive); + burn_write_opts_set_multi(*burn_options, + !(xorriso->do_close || drive_role==0 || drive_role==3)); + burn_drive_set_speed(drive, xorriso->speed, xorriso->speed); + if(xorriso->do_stream_recording == 1) + stream_mode= 1; + else if(xorriso->do_stream_recording == 2) + stream_mode= 51200; /* 100 MB */ + else if(xorriso->do_stream_recording >= 16) + stream_mode= xorriso->do_stream_recording; + burn_write_opts_set_stream_recording(*burn_options, stream_mode); + +#ifdef Xorriso_dvd_obs_default_64K + if(xorriso->dvd_obs == 0) + burn_write_opts_set_dvd_obs(*burn_options, 64 * 1024); + else +#endif + burn_write_opts_set_dvd_obs(*burn_options, xorriso->dvd_obs); + + burn_write_opts_set_stdio_fsync(*burn_options, xorriso->stdio_sync); + burn_write_opts_set_underrun_proof(*burn_options, 1); + return(1); +} + + +/* @param flag bit0= do not write but only prepare and return size in sectors + bit1= do not use isoburn wrappers +*/ +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 ret, img_sectors, num_sessions= 0, num_tracks= 0, padding= 0, profile; + int media_space, lba, nwa; + char profile_name[80]; + struct burn_session **sessions; + struct burn_track **tracks; + + img_sectors= burn_disc_get_sectors(disc); + + sessions= burn_disc_get_sessions(disc, &num_sessions); + if(sessions==NULL || num_sessions < 1) { +no_track:; + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text,"Program error : no track in prepared disc"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + {ret= -1; goto ex;} + } + tracks= burn_session_get_tracks(sessions[0], &num_tracks); + if(tracks==NULL || num_tracks < 1) + goto no_track; + + padding= 0; + ret= burn_disc_get_profile(drive, &profile, profile_name); + padding= xorriso->padding / 2048; + if(xorriso->padding > padding * 2048) + padding++; + if(img_sectors>0 && ret>0 && + (profile==0x09 || profile==0x0a)) { /* CD-R , CD-RW */ + if(img_sectors + padding < Xorriso_cd_min_track_sizE) { + padding= Xorriso_cd_min_track_sizE - img_sectors; + sprintf(xorriso->info_text, + "Expanded track to minimum size of %d sectors", + Xorriso_cd_min_track_sizE); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } + } + if(xorriso->alignment == 0) { + ret= isoburn_needs_emulation(drive); + if(ret > 0) { + /* Take care that the session is padded up to the future NWA. + Else with padding < 32 it could happen that PVDs from older + sessions survive and confuse -rom_toc_scan. + */ + xorriso->alignment= 32; + } + } + if(xorriso->alignment > 0) { + if(img_sectors > 0) { + ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &lba, &nwa); + if(ret <= 0) + nwa= 0; + lba= (nwa + img_sectors + padding) % xorriso->alignment; + if(lba > 0) + padding+= xorriso->alignment - lba; + } else if(padding < xorriso->alignment) + padding= xorriso->alignment; + } + burn_track_define_data(tracks[0], 0, padding * 2048, 0, BURN_MODE1); + Xorriso_process_msg_queues(xorriso,0); + + if(flag&2) + media_space= burn_disc_available_space(drive, burn_options) / + (off_t) 2048; + else + media_space= isoburn_disc_available_space(drive, burn_options) / + (off_t) 2048; + if(media_space < img_sectors + padding) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text,"Image size %ds exceeds free space on media %ds", + img_sectors + padding, media_space); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + if(flag&1) { + ret= img_sectors+padding; + } else + ret= 1; +ex:; + return(ret); +} + + +int Xorriso_auto_format(struct XorrisO *xorriso, int flag) +{ + int ret, profile, status, num_formats; + char profile_name[80]; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + off_t size; + unsigned dummy; + + ret= Xorriso_may_burn(xorriso, 0); + if(ret <= 0) + return(0); + + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to autoformat", 2); + if(ret<=0) + return(0); + ret= burn_disc_get_profile(drive, &profile, profile_name); + if(ret>0 && (profile==0x12 || profile==0x43)) { /* DVD-RAM or BD-RE */ + ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats); + if(ret>0 && status==BURN_FORMAT_IS_UNFORMATTED) { + sprintf(xorriso->info_text, + "Unformatted %s media detected. Trying -format fast.", + profile_name); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + ret= Xorriso_format_media(xorriso, (off_t) 0, 1 | 4); + if(ret<=0) { + sprintf(xorriso->info_text, "Automatic formatting of %s failed", + profile_name); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(ret); + } + } + } + return(1); +} + + +int Xorriso_set_system_area(struct XorrisO *xorriso, struct burn_drive *drive, + IsoImage *img, struct isoburn_imgen_opts *sopts, + int flag) +{ + int ret, options, system_area_options, iso_lba= -1, start_lba, image_blocks; + char volid[33]; + FILE *fp= NULL; + char buf[32768], *bufpt= NULL; + off_t hd_lba; + unsigned char *ub; + ElToritoBootImage *bootimg; + IsoFile *bootimg_node; + + system_area_options= xorriso->system_area_options; + memset(buf, 0, 32768); + if(xorriso->system_area_disk_path[0] == 0) { + if(xorriso->patch_system_area) { + ret= iso_image_get_system_area(img, buf, &options, 0); + if(ret == 0) { + goto do_set; + } else if(ret < 0) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_report_iso_error(xorriso, "", ret, + "Error when inquiring System Area data of ISO 9660 image", + 0, "FAILURE", 1); + {ret= 0; goto ex;} + } else { + system_area_options= xorriso->patch_system_area; + /* Check whether partition 1 ends at image end */; + ub= (unsigned char *) buf; + hd_lba= (ub[454] | (ub[455] << 8) | (ub[456] << 16) | (ub[457] << 24)) + + (ub[458] | (ub[459] << 8) | (ub[460] << 16) | (ub[461] << 24)); + + iso_lba= -1; + ret= isoburn_disc_get_msc1(drive, &start_lba); + if(ret > 0) { + ret= isoburn_read_iso_head(drive, start_lba, &image_blocks, + volid, 1); + if(ret > 0) + iso_lba= start_lba + image_blocks; + } + if(((off_t) iso_lba) * (off_t) 4 > hd_lba) { + system_area_options= 0; + } else if((xorriso->patch_system_area & 1) && + ((off_t) iso_lba) * (off_t) 4 != hd_lba) { + system_area_options= 0; + } else if((xorriso->patch_system_area & 2) && + ((off_t) iso_lba) * (off_t) 4 + (off_t) (63 * 256) < hd_lba) { + system_area_options= 0; + } else if(xorriso->patch_system_area & 2) { /* isohybrid patching */ + /* Check whether bytes 432-345 point to ElTorito LBA */ + hd_lba= ub[432] | (ub[433] << 8) | (ub[434] << 16) | (ub[435] << 24); + ret= iso_image_get_boot_image(img, &bootimg, &bootimg_node, NULL); + if(ret != 1) + system_area_options= 0; + else if(bootimg_node != NULL) { + Xorriso__file_start_lba((IsoNode *) bootimg_node, &(iso_lba), 0); + if(((off_t) iso_lba) * (off_t) 4 != hd_lba) + system_area_options= 0; + } + } + if(system_area_options == 0) { + Xorriso_msgs_submit(xorriso, 0, + "Loaded System Area data are not suitable for MBR patching.", + 0, "DEBUG", 0); + } + } + bufpt= buf; + ret= 1; + } else + ret= 0; + goto do_set; + } + if(strcmp(xorriso->system_area_disk_path, "/dev/zero") == 0) + {ret= 1; goto do_set;} + + ret= Xorriso_afile_fopen(xorriso, xorriso->system_area_disk_path, + "rb", &fp, 2); + if(ret <= 0) + {ret= 0; goto ex;} + ret= fread(buf, 1, 32768, fp); + if(ret < 32768) { + if(ferror(fp)) { + sprintf(xorriso->info_text, + "Error when reading -boot_image system_area="); + Text_shellsafe(xorriso->system_area_disk_path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + {ret= 0; goto ex;} + } + } + bufpt= buf; + +do_set:; + if(ret > 0 && xorriso->system_area_disk_path[0]) { + sprintf(xorriso->info_text, "Copying to System Area: %d bytes from file ", + ret); + Text_shellsafe(xorriso->system_area_disk_path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } + ret= isoburn_igopt_set_system_area(sopts, bufpt, system_area_options); + if(ret != ISO_SUCCESS) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_report_iso_error(xorriso, "", ret, + "Error when attaching System Area data to ISO 9660 image", + 0, "FAILURE", 1); + {ret= 0; goto ex;} + } + ret= 1; +ex:; + if(fp != NULL && fp != stdin) + fclose(fp); + return(ret); +} + + +/* @param flag bit0= do not increment boot_count + and do not reset boot parameters + bit1= dispose attached boot images +*/ +int Xorriso_attach_boot_image(struct XorrisO *xorriso, int flag) +{ + int ret; + char sfe[5*SfileadrL], *cpt; + struct burn_drive_info *source_dinfo; + struct burn_drive *source_drive; + IsoImage *image= NULL; + IsoNode *node; + ElToritoBootImage *bootimg; + enum eltorito_boot_media_type emul_type= ELTORITO_NO_EMUL; + char *bin_path; + int emul, platform_id; + off_t load_size; + struct stat stbuf; + int hflag= 0; + + if(xorriso->boot_image_bin_path[0] == 0 && !(flag & 2)) { + + /* >>> no boot image path given : no op */; + + ret= 2; goto ex; + } + + if(xorriso->in_drive_handle == NULL) + hflag= 2; + ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive, + "on attempt to attach boot image", hflag); + if(ret<=0) + goto ex; + image= isoburn_get_attached_image(source_drive); + if(image == NULL) { + /* (should not happen) */ + sprintf(xorriso->info_text, + "No ISO image present on attempt to attach boot image"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + if(flag & 2) { + iso_image_remove_boot_image(image); + xorriso->boot_count= 0; + ret= 1; goto ex; + } + + bin_path= xorriso->boot_image_bin_path; + emul= xorriso->boot_image_emul; + platform_id= xorriso->boot_platform_id; + load_size= xorriso->boot_image_load_size; + + if(xorriso->boot_efi_default) { + emul= 0; + platform_id= 0xef; + xorriso->patch_isolinux_image= 0; + } + if(platform_id == 0xef || load_size < 0) { + ret= Xorriso_iso_lstat(xorriso, bin_path, &stbuf, 2 | 4); + if(ret != 0) + {ret= 0; goto ex;} + load_size= ((stbuf.st_size / (off_t) 512) + + !!(stbuf.st_size % (off_t) 512)) * 512; + } + sprintf(xorriso->info_text, "Adding boot image %s", + Text_shellsafe(bin_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + + if(emul == 0) + emul_type= ELTORITO_NO_EMUL; + else if(emul == 1) + emul_type= ELTORITO_HARD_DISC_EMUL; + else if(emul == 2) + emul_type= ELTORITO_FLOPPY_EMUL; + + ret= Xorriso_node_from_path(xorriso, image, bin_path, &node, 1); + if(ret <= 0) { + sprintf(xorriso->info_text, + "Cannot find in ISO image: -boot_image ... bin_path=%s", + Text_shellsafe(bin_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + + if(xorriso->boot_count == 0) { + if(xorriso->boot_image_cat_path[0] == 0) { + strcpy(xorriso->boot_image_cat_path, bin_path); + cpt= strrchr(xorriso->boot_image_cat_path, '/'); + if(cpt == NULL) + cpt= xorriso->boot_image_cat_path; + else + cpt++; + strcpy(cpt, "boot.cat"); + } + ret= Xorriso_node_from_path(xorriso, image, xorriso->boot_image_cat_path, + &node, 1); + if(ret > 0) { + if(!xorriso->do_overwrite) { + sprintf(xorriso->info_text, + "May not overwite existing -boot_image ... cat_path=%s", + Text_shellsafe(xorriso->boot_image_cat_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, xorriso->boot_image_cat_path, + 8 | (xorriso->do_overwrite == 1)); + if(ret != 1) { + sprintf(xorriso->info_text, + "Could not remove existing -boot_image cat_path=%s", + Text_shellsafe(xorriso->boot_image_cat_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + } + + /* Discard old boot image, set new one */ + ret= iso_image_get_boot_image(image, &bootimg, NULL, NULL); + if(ret == 1) + iso_image_remove_boot_image(image); + ret= iso_image_set_boot_image(image, bin_path, emul_type, + xorriso->boot_image_cat_path, &bootimg); + if(ret > 0) + iso_image_set_boot_catalog_weight(image, 1000000000); + } else { + ret= iso_image_add_boot_image(image, bin_path, emul_type, 0, &bootimg); + } + if(ret < 0) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_report_iso_error(xorriso, "", ret, + "Error when attaching El-Torito boot image to ISO 9660 image", + 0, "FAILURE", 1); + sprintf(xorriso->info_text, + "Could not attach El-Torito boot image to ISO 9660 image"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + el_torito_set_boot_platform_id(bootimg, (uint8_t) platform_id); + el_torito_set_load_size(bootimg, load_size / 512); + el_torito_set_id_string(bootimg, xorriso->boot_id_string); + el_torito_set_selection_crit(bootimg, xorriso->boot_selection_crit); + ret= Xorriso_set_isolinux_options(xorriso, image, 1); + if(!(flag & 1)) { + /* Register attachment and reset even in case of error return */ + xorriso->boot_count++; + xorriso->boot_platform_id= 0; + xorriso->patch_isolinux_image= 0; + xorriso->boot_image_bin_path[0]= 0; + xorriso->boot_image_bin_form[0]= 0; + xorriso->boot_image_emul= 0; + xorriso->boot_image_load_size= 4 * 512; + memset(xorriso->boot_id_string, 0, sizeof(xorriso->boot_id_string)); + memset(xorriso->boot_selection_crit, 0, + sizeof(xorriso->boot_selection_crit)); + xorriso->boot_efi_default= 0; + } + if(ret <= 0) + goto ex; + + ret= 1; +ex:; + if(image != NULL) + iso_image_unref(image); + return(ret); +} + + +/* @param flag bit0= do not write but only prepare and return size in sectors +*/ +int Xorriso_write_session(struct XorrisO *xorriso, int flag) +{ + int ret, relax= 0, i, pacifier_speed= 0, data_lba, ext, is_bootable= 0; + int major, minor, micro; + char xorriso_id[256], *img_id, sfe[5*SfileadrL], *out_cs; + struct isoburn_imgen_opts *sopts= NULL; + struct burn_drive_info *dinfo, *source_dinfo; + struct burn_drive *drive, *source_drive; + struct burn_disc *disc= NULL; + struct burn_write_opts *burn_options; + off_t readcounter= 0,writecounter= 0; + int num_sessions= 0, num_tracks= 0; + struct burn_session **sessions; + struct burn_track **tracks; + enum burn_disc_status s; + IsoImage *image= NULL; + IsoNode *root_node; + int profile_number; + char profile_name[80]; + IsoBoot *bootcat_node; + + ret= Xorriso_finish_hl_update(xorriso, 0); + if(ret <= 0) + return(ret); + + out_cs= xorriso->out_charset; + if(out_cs == NULL) + Xorriso_get_local_charset(xorriso, &out_cs, 0); + + if(!(flag & 1)) { + ret= Xorriso_auto_format(xorriso, 0); + if(ret <=0 ) + return(0); + } + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to write", 2); + if(ret<=0) + return(0); + if(xorriso->out_drive_handle == xorriso->in_drive_handle) { + source_drive= drive; + } else { + if(xorriso->in_drive_handle == NULL) { + source_drive= drive; + } else { + ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive, + "on attempt to get source for write", 0); + if(ret<=0) + goto ex; + } + s= isoburn_disc_get_status(drive); + if(s!=BURN_DISC_BLANK) { + s= burn_disc_get_status(drive); + if(s!=BURN_DISC_BLANK) + sprintf(xorriso->info_text, + "-indev differs from -outdev and -outdev media is not blank"); + else + sprintf(xorriso->info_text, + "-indev differs from -outdev and -outdev media holds non-zero data"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + } + ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2); + if(ret == 2) + pacifier_speed= 1; + else if(ret == 3) + pacifier_speed= 2; + + ret= isoburn_igopt_new(&sopts, 0); + if(ret<=0) { + Xorriso_process_msg_queues(xorriso, 0); + goto ex; + } + relax= xorriso->relax_compliance; + + xorriso->alignment= 0; + image= isoburn_get_attached_image(source_drive); + if(image != NULL) { + iso_image_set_application_id(image, xorriso->application_id); + iso_image_set_publisher_id(image, xorriso->publisher); + iso_image_set_system_id(image, xorriso->system_id); + iso_image_set_volset_id(image, xorriso->volset_id); + } + + if((xorriso->do_aaip & 256) && out_cs != NULL) { + static char *names = "isofs.cs"; + size_t value_lengths[1]; + + value_lengths[0]= strlen(out_cs); + ret= Xorriso_setfattr(xorriso, NULL, "/", + (size_t) 1, &names, value_lengths, &out_cs, 2 | 8); + if(ret<=0) + goto ex; + } + + ret= Xorriso_set_system_area(xorriso, source_drive, image, sopts, 0); + if(ret <= 0) + goto ex; + + /* Activate, adjust or discard boot image */ + if(image!=NULL && !(flag&1)) { + is_bootable= iso_image_get_boot_image(image, NULL, NULL, &bootcat_node); + if(xorriso->boot_image_bin_path[0]) { + ret= Xorriso_attach_boot_image(xorriso, xorriso->boot_count == 0); + if(ret <= 0) + goto ex; + } + if(xorriso->boot_count > 0) { + /* Eventually rename boot catalog node to changed boot_image_cat_path */ + if(is_bootable > 0) { + ret= Xorriso_path_from_node(xorriso, (IsoNode *) bootcat_node, sfe, 0); + if(ret > 0) { + if(strcmp(sfe, xorriso->boot_image_cat_path) != 0) { + ret= Xorriso_rename(xorriso, NULL, sfe, + xorriso->boot_image_cat_path, 0); + if(ret <= 0) + goto ex; + } + } + } + } else if(xorriso->patch_isolinux_image & 1) { + if(is_bootable == 1) { + relax|= isoburn_igopt_allow_full_ascii; + sprintf(xorriso->info_text, "Patching boot info table"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + + ret= Xorriso_path_from_lba(xorriso, NULL, xorriso->loaded_boot_bin_lba, + sfe, 1); + if(ret < 0) + goto ex; + if(ret == 0) { + sprintf(xorriso->info_text, + "Cannot patch boot image: no file found for its LBA."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + sprintf(xorriso->info_text, + "Probably the loaded boot image file was deleted in this session."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + sprintf(xorriso->info_text, + "Use -boot_image \"any\" \"discard\" or set new boot image"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0); + goto ex; + } + ret= Xorriso_set_isolinux_options(xorriso, image, 0); + if(ret <= 0) + goto ex; + } else { + sprintf(xorriso->info_text, + "Could not find any boot image for -boot_image patching"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); + } + } else if(xorriso->keep_boot_image && is_bootable == 1) { + relax|= isoburn_igopt_allow_full_ascii; + sprintf(xorriso->info_text, "Keeping boot image unchanged"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } else if(is_bootable == 1) { + iso_image_remove_boot_image(image); + sprintf(xorriso->info_text, "Discarded boot image from old session"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } + } + + if((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2)) { + /* Overwrite isofs.st of root node by xorriso->isofs_st_out */ + char *name= "isofs.st"; + char timestamp[16], *value= timestamp; + size_t value_length; + + sprintf(timestamp, "%.f", (double) xorriso->isofs_st_out); + value_length= strlen(timestamp); + Xorriso_setfattr(xorriso, NULL, "/", (size_t) 1, &name, + &value_length, &value, 2 | 8); + } + + isoburn_igopt_set_level(sopts, 3); + ext= isoburn_igopt_rockridge | + ((!!xorriso->do_joliet) * isoburn_igopt_joliet) | + (( !(xorriso->ino_behavior & 2)) * isoburn_igopt_hardlinks) | + (( (!(xorriso->ino_behavior & 2)) || + (xorriso->do_aaip & (2 | 8 | 16 | 256)) || + (xorriso->do_md5 & (2 | 4)) + ) * isoburn_igopt_aaip) | + ((!!(xorriso->do_md5 & 2)) * isoburn_igopt_session_md5) | + ((!!(xorriso->do_md5 & 4)) * isoburn_igopt_file_md5) | + ((!!(xorriso->do_md5 & 8)) * isoburn_igopt_file_stability); + isoburn_igopt_set_extensions(sopts, ext); + isoburn_igopt_set_relaxed(sopts, relax); + isoburn_igopt_set_sort_files(sopts, 1); + isoburn_igopt_set_over_mode(sopts, 0, 0, (mode_t) 0, (mode_t) 0); + isoburn_igopt_set_over_ugid(sopts, 0, 0, (uid_t) 0, (gid_t) 0); + isoburn_igopt_set_out_charset(sopts, out_cs); + isoburn_igopt_set_fifo_size(sopts, xorriso->fs * 2048); + Ftimetxt(time(NULL), xorriso->scdbackup_tag_time, 8); + isoburn_igopt_set_scdbackup_tag(sopts, xorriso->scdbackup_tag_name, + xorriso->scdbackup_tag_time, + xorriso->scdbackup_tag_written); + if(image!=NULL && + strlen(Xorriso_program_versioN)+strlen(Xorriso_timestamP)<80) { + sprintf(xorriso_id, "XORRISO-%s %s", + Xorriso_program_versioN, Xorriso_timestamP); + isoburn_version(&major, &minor, µ); + if(strlen(xorriso_id)<80) + sprintf(xorriso_id+strlen(xorriso_id), + ", LIBISOBURN-%d.%d.%d", major, minor, micro); + iso_lib_version(&major, &minor, µ); + if(strlen(xorriso_id)<80) + sprintf(xorriso_id+strlen(xorriso_id), + ", LIBISOFS-%d.%d.%d", major, minor, micro); + burn_version(&major, &minor, µ); + if(strlen(xorriso_id)<80) + sprintf(xorriso_id+strlen(xorriso_id), + ", LIBBURN-%d.%d.%d", major, minor, micro); + xorriso_id[128]= 0; + img_id= (char *) iso_image_get_data_preparer_id(image); + if(img_id!=NULL) { + for(i= strlen(img_id)-1; i>=0 && img_id[i]==' '; i--); + if(i>0) { + sprintf(xorriso->info_text, "Overwrote previous preparer id '%s'", + img_id); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + } + } + iso_image_set_data_preparer_id(image, xorriso_id); + } + isoburn_igopt_set_pvd_times(sopts, + xorriso->vol_creation_time, xorriso->vol_modification_time, + xorriso->vol_expiration_time, xorriso->vol_effective_time, + xorriso->vol_uuid); + + /* Make final abort check before starting expensive activities */ + ret= Xorriso_eval_problem_status(xorriso, 1, 0); + if(ret<0) + {ret= 0; goto ex;} + + if(xorriso->zisofs_by_magic) { + sprintf(xorriso->info_text, + "Checking disk file content for zisofs compression headers."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0); + root_node= (IsoNode *) iso_image_get_root(image); + ret= iso_node_zf_by_magic(root_node, + (xorriso->out_drive_handle == xorriso->in_drive_handle) | 2 | 16); + if(ret<0) { + Xorriso_report_iso_error(xorriso, "", ret, + "Error when examining file content for zisofs headers", + 0, "FAILURE", 1); + } + ret= Xorriso_eval_problem_status(xorriso, 1, 0); + if(ret<0) + {ret= 0; goto ex;} + sprintf(xorriso->info_text, + "Check for zisofs compression headers done."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0); + } + + /* >>> omit iso_image_update_sizes if the image was filled up very quickly */; + + ret= iso_image_update_sizes(image); + if(ret < 0) { + Xorriso_process_msg_queues(xorriso, 0); + if(ret<0) { + Xorriso_report_iso_error(xorriso, "", ret, + "Error when updating file sizes", + 0, "FAILURE", 1); + } + ret= Xorriso_eval_problem_status(xorriso, 1, 0); + if(ret<0) + {ret= 0; goto ex;} + } + + Xorriso_set_abort_severity(xorriso, 1); + if (xorriso->grow_blindly_msc2 >= 0 && + xorriso->out_drive_handle != xorriso->in_drive_handle) { + ret= isoburn_prepare_blind_grow(source_drive, &disc, sopts, drive, + xorriso->grow_blindly_msc2); + if(ret>0) { + /* Allow the consumer of output to access the input drive */ + source_drive= NULL; + ret= Xorriso_give_up_drive(xorriso, 1|8); + if(ret<=0) + goto ex; + } + } else if(xorriso->out_drive_handle == xorriso->in_drive_handle || + xorriso->in_drive_handle == NULL) { + ret= isoburn_prepare_disc(source_drive, &disc, sopts); + } else { + ret= isoburn_prepare_new_image(source_drive, &disc, sopts, drive); + } + if(ret <= 0) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text,"Failed to prepare session write run"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + + ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0); + if(ret<=0) + goto ex; + isoburn_igopt_get_effective_lba(sopts, &(xorriso->session_lba)); + if(xorriso->do_stream_recording == 2) { + ret= isoburn_igopt_get_data_start(sopts, &data_lba); + if(ret > 0 && data_lba >= 16) + burn_write_opts_set_stream_recording(burn_options, data_lba); + } + + ret= Xorriso_sanitize_image_size(xorriso, drive, disc, burn_options, flag&1); + if(ret<=0 || (flag&1)) { + Xorriso_process_msg_queues(xorriso,0); + if(flag&1) /* set queue severity to FAILURE */ + Xorriso_set_image_severities(xorriso, 2); + isoburn_cancel_prepared_write(source_drive, drive, 0); + if(flag&1) /* reset queue severity */ + Xorriso_set_image_severities(xorriso, 0); + goto ex; + } + + ret= Xorriso_may_burn(xorriso, 0); + if(ret <= 0) + goto ex; + + /* Important: do not return until burn_is_aborting() was checked */ + Xorriso_set_signal_handling(xorriso, 1); + + xorriso->run_state= 1; /* Indicate that burning has started */ + isoburn_disc_write(burn_options, disc); + burn_write_opts_free(burn_options); + + ret= Xorriso_pacifier_loop(xorriso, drive, pacifier_speed << 4); + if(burn_is_aborting(0)) + Xorriso_abort(xorriso, 0); /* Never comes back */ + Xorriso_set_signal_handling(xorriso, 0); + if(ret<=0) + goto ex; + if(!isoburn_drive_wrote_well(drive)) { + isoburn_cancel_prepared_write(source_drive, drive, 0); + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "libburn indicates failure with writing."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + + sessions= burn_disc_get_sessions(disc, &num_sessions); + if(num_sessions>0) { + tracks= burn_session_get_tracks(sessions[0], &num_tracks); + if(tracks!=NULL && num_tracks>0) { + burn_track_get_counters(tracks[0],&readcounter,&writecounter); + xorriso->session_blocks= (int) (writecounter/ (off_t) 2048); + sprintf(xorriso->info_text, + "ISO image produced: %d sectors\nWritten to media : %d sectors at LBA %d\n", + (int) (readcounter/ (off_t) 2048), + xorriso->session_blocks, xorriso->session_lba); + Xorriso_info(xorriso, 0); + } + } + ret= isoburn_activate_session(drive); + Xorriso_process_msg_queues(xorriso,0); + if(ret<=0) { + sprintf(xorriso->info_text, + "Could not write new set of volume descriptors"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + goto ex; + } + /* Done early to free any reference to the libisofs resources via disc */ + if(disc!=NULL) + burn_disc_free(disc); + disc= NULL; + /* To wait for the end of the libisofs threads and their messages. */ + isoburn_sync_after_write(source_drive, drive, 0); + Xorriso_process_msg_queues(xorriso,0); + + sprintf(xorriso->info_text, "Writing to %s completed sucessfully.\n\n", + Text_shellsafe(xorriso->outdev,sfe,0)); + Xorriso_info(xorriso, 0); + ret= 1; +ex:; + xorriso->run_state= 0; /* Indicate that burning has ended */ + Xorriso_set_abort_severity(xorriso, 0); + + if(ret<=0) { + + /* >>> ??? revive discarded boot image */; + + } + if(disc!=NULL) + burn_disc_free(disc); + if(image != NULL) + iso_image_unref(image); + isoburn_igopt_destroy(&sopts, 0); + Xorriso_process_msg_queues(xorriso,0); + Xorriso_append_scdbackup_record(xorriso, 0); + return(ret); +} + + +int Xorriso_check_burn_abort(struct XorrisO *xorriso, int flag) +{ + int ret; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + + if(burn_is_aborting(0)) + return(2); + if(xorriso->run_state!=1) + return(0); + ret= Xorriso_eval_problem_status(xorriso, 1, 1); + if(ret>=0) + return(0); + sprintf(xorriso->info_text, + "-abort_on '%s' encountered '%s' during image writing", + xorriso->abort_on_text, xorriso->problem_status_text); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, + xorriso->problem_status_text, 0); + + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to abort burn run", 2); + if(ret<=0) + return(0); + + burn_drive_cancel(drive); + sprintf(xorriso->info_text, + "libburn has now been urged to cancel its operation"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(1); +} + + +/* This loop watches burn runs until they end. + It issues pacifying update messages to the user. + @param flag bit0-3 = emulation mode + 0= xorriso + 1= mkisofs + 2= cdrecord + bit4= report speed in CD units + bit5= report speed in BD units +*/ +int Xorriso_pacifier_loop(struct XorrisO *xorriso, struct burn_drive *drive, + int flag) +{ + int ret, size, free_bytes, i, aborting= 0, emul, buffer_fill= 50, last_sector; + struct burn_progress progress; + char *status_text, date_text[80], *speed_unit, mem_text[8]; + enum burn_drive_status drive_status; + double start_time, current_time, last_time, base_time= 0.0, base_count= 0.0; + double next_base_time= 0.0, next_base_count= 0.0, first_base_time= 0.0; + double first_base_count= 0.0, norm= 0.0, now_time, fract_offset= 0.0; + double measured_speed, speed_factor= 1385000, quot; + time_t time_prediction; + + start_time= Sfile_microtime(0); + while(burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING) + usleep(100002); + + emul= flag&15; + fract_offset= 0.2 * (double) emul - ((int) (0.2 * (double) emul)); + if(emul==0) + emul= xorriso->pacifier_style; + speed_unit= "D"; + if(flag&16) { + speed_factor= 150.0*1024; + speed_unit= "C"; + } else if(flag & 32) { + speed_factor= 4495625; + speed_unit= "B"; + } + progress.sector= 0; + current_time= Sfile_microtime(0); + measured_speed= 0.0; + while(1) { + last_time= current_time; + last_sector= progress.sector; + drive_status= burn_drive_get_status(drive, &progress); + if(drive_status == BURN_DRIVE_IDLE) + break; + current_time= Sfile_microtime(0); + if(drive_status == BURN_DRIVE_WRITING && progress.sectors > 0) { + if(current_time-last_time>0.2) + measured_speed= (progress.sector - last_sector) * 2048.0 / + (current_time - last_time); + buffer_fill= 50; + if(progress.buffer_capacity>0) + buffer_fill= (double) (progress.buffer_capacity + - progress.buffer_available) * 100.0 + / (double) progress.buffer_capacity; + if(emul==2) { + if(progress.sector<=progress.sectors) + sprintf(xorriso->info_text, "%4d of %4d MB written", + progress.sector / 512, progress.sectors / 512); + else + sprintf(xorriso->info_text, "%4d MB written", + progress.sector / 512); + + if(xorriso->pacifier_fifo!=NULL) + ret= burn_fifo_inquire_status(xorriso->pacifier_fifo, + &size, &free_bytes, &status_text); + else + ret= isoburn_get_fifo_status(drive, &size, &free_bytes, &status_text); + if(ret>0 ) + sprintf(xorriso->info_text+strlen(xorriso->info_text), + " (fifo %2d%%)", + (int) (100.0-100.0*((double) free_bytes)/(double) size)); + + sprintf(xorriso->info_text+strlen(xorriso->info_text), " [buf %3d%%]", + buffer_fill); + + if(current_time-last_time>0.2) + sprintf(xorriso->info_text+strlen(xorriso->info_text), " %4.1fx.", + measured_speed/speed_factor); + + } else if(emul == 1 && + progress.sectors > 0 && progress.sector <= progress.sectors) { + /* "37.87% done, estimate finish Tue Jul 15 18:55:07 2008" */ + + quot= ((double) progress.sector) / ((double) progress.sectors); + sprintf(xorriso->info_text, " %2.2f%% done", quot*100.0); + if(current_time - start_time >= 2 && quot > 0.0 && + (quot >= 0.02 || progress.sector >= 5*1024)) { + if(base_time == 0.0 && progress.sector >= 16*1024) { + first_base_time= base_time= next_base_time= current_time; + first_base_count= next_base_count= progress.sector; + } else if(next_base_time > 0 && current_time - next_base_time >= 10) { + base_time= next_base_time; + base_count= next_base_count; + next_base_time= current_time; + next_base_count= progress.sector; + } + if(first_base_time > 0 && + current_time - first_base_time >= 10 && + progress.sectors > first_base_count && + progress.sector > first_base_count) { + norm= (1.0 - quot); + if(norm < 0.0001) + norm= 0.0001; + quot= ((double) progress.sector - first_base_count) + / ((double) progress.sectors - first_base_count); + time_prediction= norm * (1.0 - quot) / quot + * (current_time - first_base_time); + } else { + time_prediction= (1.0 - quot) / quot * (current_time - start_time); + norm= 1.0; + } + if(base_time > 0 && + current_time - base_time >= 10 && progress.sectors > base_count) { + quot= ((double) progress.sector - base_count) + / ((double) progress.sectors - base_count); + time_prediction+= (1.0 - quot) / quot * (current_time - base_time); + norm+= 1.0; + } + time_prediction/= norm; + if(time_prediction < 30*86400 && time_prediction > 0) { + time_prediction+= current_time + 1; + Ftimetxt(time_prediction, date_text, 4); + sprintf(xorriso->info_text+strlen(xorriso->info_text), + ", estimate finish %s", date_text); + } + } + } else { + if(progress.sector<=progress.sectors) { + if(progress.sectors <= 0) + strcpy(mem_text, " 99.9"); + else + sprintf(mem_text, "%5.1f", + 100.0 * ((double) progress.sector) / ((double) progress.sectors)); + mem_text[5]= 0; + sprintf(xorriso->info_text, "Writing: %10ds %s%% ", + progress.sector, mem_text); + } else { + Sfile_scale(2048.0 * (double) progress.sector, mem_text, 5, 1e4, 1); + sprintf(xorriso->info_text, "Writing: %10ds %s ", + progress.sector, mem_text); + } + ret= isoburn_get_fifo_status(drive, &size, &free_bytes, &status_text); + if(ret>0 ) + sprintf(xorriso->info_text+strlen(xorriso->info_text), + " fifo %3d%% buf %3d%%", + (int) (100.0-100.0*((double) free_bytes)/(double) size), + buffer_fill); + if(current_time-last_time>0.2) + sprintf(xorriso->info_text+strlen(xorriso->info_text), " %5.1fx%s ", + measured_speed/speed_factor, speed_unit); + } + } else if(drive_status == BURN_DRIVE_CLOSING_SESSION || + drive_status == BURN_DRIVE_CLOSING_TRACK) + sprintf(xorriso->info_text, + "Closing track/session. Working since %.f seconds", + current_time-start_time); + else if(drive_status == BURN_DRIVE_FORMATTING) + sprintf(xorriso->info_text, "Formatting. Working since %.f seconds", + current_time-start_time); + else + sprintf(xorriso->info_text, + "Thank you for being patient. Working since %.f seconds.", + current_time-start_time); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0); + + for(i= 0; i<12; i++) { /* 2 usleeps more than supposed to be needed */ + Xorriso_process_msg_queues(xorriso, 0); + if(aborting<=0) + aborting= Xorriso_check_burn_abort(xorriso, 0); + usleep(100000); + now_time= Sfile_microtime(0); + if(((time_t) now_time) - ((time_t) current_time) >= 1 && + now_time - ((time_t) now_time) >= fract_offset) + break; + } + } + return(1); +} + + +/* @param flag bit0= fast + bit1= deformat + bit2= do not re-aquire drive + @return 0=failure, did not touch media , -1=failure, altered media + 1=success, altered media , 2=success, did not touch media +*/ +int Xorriso_blank_media(struct XorrisO *xorriso, int flag) +{ + int ret, do_deformat= 0; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + enum burn_disc_status disc_state; + struct burn_progress p; + double percent = 1.0; + int current_profile; + char current_profile_name[80]; + time_t start_time; + char mode_names[4][80]= {"all", "fast", "deformat", "deformat_quickest"}; + + ret= Xorriso_may_burn(xorriso, 0); + if(ret <= 0) + return(0); + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to -blank", 2); + if(ret<=0) + return(0); + + burn_disc_get_profile(drive, ¤t_profile, current_profile_name); + + disc_state = isoburn_disc_get_status(drive); + if(current_profile == 0x13) { /* overwriteable DVD-RW */ + /* Depending on flag bit1 formatted DVD-RW will get blanked to sequential + state or pseudo blanked by invalidating an eventual ISO image. */ + if(flag&2) + do_deformat= 1; + } else if(current_profile == 0x14) { /* sequential DVD-RW */ + if((flag&1) && !(flag&2)) { + sprintf(xorriso->info_text, + "-blank: DVD-RW present. Mode 'fast' defaulted to mode 'all'."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + sprintf(xorriso->info_text, + "Mode 'deformat_quickest' produces single-session-only media."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0); + flag&= ~1; + } + } else if(disc_state == BURN_DISC_BLANK) { + sprintf(xorriso->info_text,"Blank media detected. Will leave it untouched"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return 2; + } else if(disc_state==BURN_DISC_FULL || disc_state==BURN_DISC_APPENDABLE) { + ; + } else if(disc_state == BURN_DISC_EMPTY) { + sprintf(xorriso->info_text,"No media detected in drive"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return 0; + } else { + sprintf(xorriso->info_text, "Unsuitable drive and media state"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return 0; + } + if(!isoburn_disc_erasable(drive)) { + sprintf(xorriso->info_text, "Media is not of erasable type"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return 0; + } + if(xorriso->do_dummy) { + sprintf(xorriso->info_text, + "-dummy mode prevents blanking of media in mode '%s'.", + mode_names[flag&3]); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(1); + } + sprintf(xorriso->info_text, "Beginning to blank media in mode '%s'.\n", + mode_names[flag&3]); + Xorriso_info(xorriso,0); + + /* Important: do not return until burn_is_aborting() was checked */ + Xorriso_set_signal_handling(xorriso, 1); + + if(do_deformat) + burn_disc_erase(drive, (flag&1)); + else + isoburn_disc_erase(drive, (flag&1)); + start_time= time(0); + usleep(1000000); + while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) { + Xorriso_process_msg_queues(xorriso,0); + if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */ + percent = 1.0 + ((double) p.sector+1.0) / ((double) p.sectors) * 98.0; + sprintf(xorriso->info_text, "Blanking ( %.1f%% done in %d seconds )", + percent, (int) (time(0) - start_time)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0); + usleep(1000000); + } + Xorriso_process_msg_queues(xorriso,0); + if(burn_is_aborting(0)) + Xorriso_abort(xorriso, 0); /* Never comes back */ + Xorriso_set_signal_handling(xorriso, 0); + if(burn_drive_wrote_well(drive)) { + sprintf(xorriso->info_text, "Blanking done\n"); + Xorriso_info(xorriso,0); + } else { + sprintf(xorriso->info_text, "Blanking failed."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } + if(!(flag & 4)) { + ret= Xorriso_reaquire_outdev(xorriso, + 2 + (xorriso->in_drive_handle == xorriso->out_drive_handle)); + if(ret <= 0) + return(-1); + } + return(1); +} + + +/* @param flag bit0= try to achieve faster formatting + bit1= use parameter size (else use default size) + bit2= do not re-aquire drive + bit7= by_index mode: + bit8 to bit15 contain the index of the format to use. + @return 0=failure, did not touch media , -1=failure, altered media + 1=success, altered media , 2=success, did not touch media +*/ +int Xorriso_format_media(struct XorrisO *xorriso, off_t in_size, int flag) +{ + int ret, mode_flag= 0, index, status, num_formats; + unsigned dummy; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + struct burn_progress p; + double percent = 1.0; + int current_profile; + char current_profile_name[80]; + off_t size= 0; + time_t start_time; + enum burn_disc_status disc_state; + + ret= Xorriso_may_burn(xorriso, 0); + if(ret <= 0) + return(0); + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to -format", 2); + if(ret<=0) + return(0); + + if(flag & 2) { + mode_flag= 0; /* format to given size */ + } else { + mode_flag= 4; /* format to full size */ + } + burn_disc_get_profile(drive, ¤t_profile, current_profile_name); + + if(flag&128) { /* by_index */ + index= (flag>>8) & 0xff; + ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats); + if(ret<=0) + num_formats= 0; + if(ret<=0 || index<0 || index>=num_formats) { + if(num_formats>0) + sprintf(xorriso->info_text, + "-format by_index_%d: format descriptors range from index 0 to %d", + index, num_formats-1); + else + sprintf(xorriso->info_text, + "-format by_index_%d: no format descriptors available", index); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + mode_flag|= (flag & 0xff80); + if(flag&1) + mode_flag|= (1<<6); + + } else if(current_profile == 0x12) { /* DVD+RAM */ + if(!(flag & 2)) + mode_flag= 6; /* format to default payload size */ + if(flag&1) + mode_flag|= (1<<6); + + } else if(current_profile == 0x13) { /* DVD-RW */ + if(flag&1) { + sprintf(xorriso->info_text, + "Detected formatted DVD-RW. Thus omitting desired fast format run."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(2); + } + + } else if(current_profile == 0x14) { /* DVD-RW sequential */ + if(flag & 1) { + size= 128*1024*1024; + mode_flag= 1; /* format to size, then write size of zeros */ + } else + mode_flag= 4; + + } else if(current_profile == 0x1a) { /* DVD+RW */ + if(flag&1) { + sprintf(xorriso->info_text, + "Detected DVD+RW. Thus omitting desired fast format run."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(2); + } + + } else if(current_profile == 0x41) { /* BD-R SRM */ + if(!(flag & 2)) + mode_flag= 6; /* format to default payload size */ + if(flag&1) + mode_flag|= (1<<6); + + } else if(current_profile == 0x43) { /* BD-RE */ + if(!(flag & 2)) + mode_flag= 6; /* format to default payload size */ + if(flag&1) + mode_flag|= (1<<6); + + } else { + sprintf(xorriso->info_text, + "-format: Unsuitable media detected."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + sprintf(xorriso->info_text,"Media current: %s (%4.4xh)", + current_profile_name, current_profile); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(0); + } + if(!(flag & 1)) + mode_flag|= 16; /* enable re-formatting */ + + if(xorriso->do_dummy) { + sprintf(xorriso->info_text, "-dummy mode prevents formatting of media."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(1); + } + sprintf(xorriso->info_text, "Beginning to format media.\n"); + Xorriso_info(xorriso, 0); + if(flag & 2) + size= in_size; + + /* Important: do not return until burn_is_aborting() was checked */ + Xorriso_set_signal_handling(xorriso, 1); + + burn_disc_format(drive, size, mode_flag); + + start_time= time(0); + usleep(1000000); + while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) { + Xorriso_process_msg_queues(xorriso,0); + if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */ + percent = 1.0 + ((double) p.sector+1.0) / ((double) p.sectors) * 98.0; + sprintf(xorriso->info_text, "Formatting ( %.1f%% done in %d seconds )", + percent, (int) (time(0) - start_time)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0); + usleep(1000000); + } + Xorriso_process_msg_queues(xorriso,0); + if(burn_is_aborting(0)) + Xorriso_abort(xorriso, 0); /* Never comes back */ + Xorriso_set_signal_handling(xorriso, 0); + + if(burn_drive_wrote_well(drive)) { + sprintf(xorriso->info_text, "Formatting done\n"); + Xorriso_info(xorriso,0); + } else { + sprintf(xorriso->info_text, + "libburn indicates failure with formatting."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(-1); + } + + if(!(flag & 4)) { + ret= Xorriso_reaquire_outdev(xorriso, + 2 + (xorriso->in_drive_handle == xorriso->out_drive_handle)); + if(ret <= 0) + return(-1); + } + disc_state = isoburn_disc_get_status(drive); + if(disc_state==BURN_DISC_FULL && !(flag&1)) { + /* Blank because full format certification pattern might be non-zero */ + ret= Xorriso_blank_media(xorriso, 1); + if(ret <= 0) + return(0); + } + return(1); +} + + +/* @param flag bit2= formatting rather than blanking + @return 0=failure, did not touch media , -1=failure, altered media + 1=success, altered media , 2=success, did not touch media +*/ +int Xorriso_blank_as_needed(struct XorrisO *xorriso, int flag) +{ + int ret, is_formatted= -1, status, num_formats, did_work= 0; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + enum burn_disc_status disc_state; + unsigned dummy; + int current_profile; + char current_profile_name[80]; + off_t size; + + ret= Xorriso_may_burn(xorriso, 0); + if(ret <= 0) + return(0); + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to blank or format", 2); + if(ret<=0) + return(0); + + burn_disc_get_profile(drive, ¤t_profile, current_profile_name); + + ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats); + if(ret>0) { + if(status==BURN_FORMAT_IS_FORMATTED) + is_formatted= 1; + else if(status == BURN_FORMAT_IS_UNFORMATTED) + is_formatted= 0; + } + if(current_profile == 0x12 || current_profile == 0x43) { /* DVD+RAM , BD-RE */ + if(is_formatted<0) { + sprintf(xorriso->info_text, + "-blank or -format: Unclear formatting status of %s", + current_profile_name); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if(!is_formatted) { + ret= Xorriso_format_media(xorriso, (off_t) 0, (current_profile == 0x43)); + if(ret <= 0) + return(ret); + did_work= (ret == 1); + } + } else if(current_profile == 0x14 && (flag&4)) { /* DVD-RW sequential */ + ret= Xorriso_format_media(xorriso, (off_t) 0, 0); + if(ret <= 0) + return(ret); + did_work= (ret == 1); + } else if(current_profile == 0x41) { /* BD-R SRM */ + if(!is_formatted) { + ret= Xorriso_format_media(xorriso, (off_t) 0, 1); + if(ret <= 0) + return(ret); + did_work= (ret == 1); + } + } + + disc_state = isoburn_disc_get_status(drive); + if(disc_state != BURN_DISC_BLANK && !(flag&4)) { + ret= Xorriso_blank_media(xorriso, 1); + return(ret); + } + if(did_work) + return(1); + sprintf(xorriso->info_text, "%s as_needed: no need for action detected", + (flag&4) ? "-format" : "-blank"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(2); +} + + +/* @param write_start_address is valid if >=0 + @param tsize is valid if >0 + @param flag bit0= grow_overwriteable_iso + bit1= do_isosize + bit2= do_xa1 conversion +*/ +int Xorriso_burn_track(struct XorrisO *xorriso, off_t write_start_address, + char *track_source, off_t tsize, int flag) +{ + int ret, fd, unpredicted_size, profile_number, is_cd= 0, dummy, nwa= -1; + int isosize= -1, do_isosize, is_bd= 0; + + struct burn_drive_info *dinfo; + struct burn_drive *drive; + struct burn_write_opts *burn_options; + struct burn_disc *disc= NULL; + struct burn_session *session; + struct burn_track *track; + struct stat stbuf; + off_t fixed_size= 0; + struct burn_source *data_src= NULL, *fifo_src= NULL; + enum burn_disc_status disc_state; + char reasons[BURN_REASONS_LEN], sfe[5*SfileadrL], profile_name[80]; + char head_buffer[64*1024]; + + ret= Xorriso_may_burn(xorriso, 0); + if(ret <= 0) + return(0); + ret= Xorriso_auto_format(xorriso, 0); + if(ret <=0 ) + return(0); + + do_isosize= !!(flag&2); + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to burn track", 2); + if(ret<=0) + return(0); + ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0); + if(ret<=0) + goto ex; + + disc= burn_disc_create(); + session= burn_session_create(); + ret= burn_disc_add_session(disc,session,BURN_POS_END); + if(ret==0) { + sprintf(xorriso->info_text, "Cannot add session object to disc object."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + goto ex; + } + track= burn_track_create(); + if(track_source[0] == '-' && track_source[1] == 0) { + fd= 0; + } else { + if(xorriso->fs >= 64) + fd= burn_os_open_track_src(track_source, O_RDONLY, 0); + else + fd= open(track_source, O_RDONLY); + if(fd>=0) + if(fstat(fd,&stbuf)!=-1) + if((stbuf.st_mode&S_IFMT)==S_IFREG) + fixed_size= stbuf.st_size; + } + if(fixed_size==0) + unpredicted_size= 1; + + if(fd>=0) + data_src= burn_fd_source_new(fd, -1, fixed_size); + if(data_src==NULL) { + sprintf(xorriso->info_text, "Could not open data source %s", + Text_shellsafe(track_source,sfe,0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + ret= 0; goto ex; + } + if((do_isosize || xorriso->fs != 0) && xorriso->fs < 64) + xorriso->fs= 64; + if(xorriso->fs > 0) { + fifo_src= burn_fifo_source_new(data_src, 2048 + 8 * !!(flag & 4), + xorriso->fs, 1); + if(fifo_src == NULL) { + sprintf(xorriso->info_text, "Could not create fifo object of %.f MB", + ((double) xorriso->fs) / 1024.0 / 1024.0); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + ret= 0; goto ex; + } + } + xorriso->pacifier_fifo= fifo_src; + if(burn_track_set_source(track, fifo_src == NULL ? data_src : fifo_src) + != BURN_SOURCE_OK) { + sprintf(xorriso->info_text, + "Cannot attach source object to track object"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + ret= 0; goto ex; + } + burn_track_set_cdxa_conv(track, !!(flag & 4)); + burn_session_add_track(session, track, BURN_POS_END); + burn_source_free(data_src); + + if(flag&1) + /* consider overwriteables with ISO as appendable */ + disc_state= isoburn_disc_get_status(drive); + else + /* handle overwriteables as always blank */ + disc_state= burn_disc_get_status(drive); + + if(disc_state == BURN_DISC_BLANK || disc_state == BURN_DISC_APPENDABLE) { + /* ok */; + } else { + if(disc_state == BURN_DISC_FULL) { + sprintf(xorriso->info_text, + "Closed media with data detected. Need blank or appendable media."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + if(burn_disc_erasable(drive)) { + sprintf(xorriso->info_text, "Try -blank as_needed\n"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0); + } + } else if(disc_state == BURN_DISC_EMPTY) { + sprintf(xorriso->info_text, "No media detected in drive"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } else { + sprintf(xorriso->info_text, + "Cannot recognize state of drive and media"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } + ret= 0; goto ex; + } + if(isoburn_needs_emulation(drive)) + burn_write_opts_set_multi(burn_options, 0); + + if(tsize > 0) { + fixed_size= tsize; + burn_track_set_size(track, fixed_size); + } + if(do_isosize) { + ret= burn_fifo_peek_data(xorriso->pacifier_fifo, head_buffer, 64*1024, 0); + if(ret<=0) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "Cannot obtain first 64 kB from input stream."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + /* read isosize from head_buffer, not from media*/ + ret= isoburn_read_iso_head(drive, 0, &isosize, head_buffer, (1<<13)); + if(ret<=0) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "Option -isosize given but data stream seems not to be ISO 9660"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + sprintf(xorriso->info_text, "Size of ISO 9660 image: %ds", isosize); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + fixed_size= ((off_t) (isosize)) * (off_t) 2048; + burn_track_set_size(track, fixed_size); + } + + ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2); + is_cd= (ret==2); + is_bd= (ret == 3); + + if(isoburn_needs_emulation(drive)) { + if(flag&1) { + ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &dummy, &nwa); + if(ret<=0) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "Cannot obtain next writeable address of emulated multi-session media\n"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + if(nwa==32) + nwa= 0; /* No automatic toc emulation. Formatter might not be aware. */ + burn_write_opts_set_start_byte(burn_options,((off_t) nwa) * (off_t) 2048); + } else { + nwa= 0; + burn_write_opts_set_start_byte(burn_options, (off_t) 0); + } + } + + if(write_start_address>=0) { + nwa= write_start_address / (off_t) 2048; + if(((off_t) nwa) * (off_t) 2048 < write_start_address ) + nwa++; + burn_write_opts_set_start_byte(burn_options, ((off_t) nwa) * (off_t) 2048); + } + + if(burn_write_opts_auto_write_type(burn_options, disc, reasons, 0) == + BURN_WRITE_NONE) { + sprintf(xorriso->info_text, + "Failed to find a suitable write mode with this media.\n"); + sprintf(xorriso->info_text+strlen(xorriso->info_text), + "Reasons given:\n%s", reasons); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + + ret= Xorriso_sanitize_image_size(xorriso, drive, disc, burn_options, 2); + if(ret<=0) + goto ex; + + /* Important: do not return until burn_is_aborting() was checked */ + Xorriso_set_signal_handling(xorriso, 1); + + xorriso->run_state= 1; /* Indicate that burning has started */ + burn_disc_write(burn_options, disc); + + ret= Xorriso_pacifier_loop(xorriso, drive, 2 | (is_cd << 4) | (is_bd << 5)); + if(burn_is_aborting(0)) + Xorriso_abort(xorriso, 0); /* Never comes back */ + Xorriso_set_signal_handling(xorriso, 0); + if(ret<=0) + goto ex; + if(!burn_drive_wrote_well(drive)) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "libburn indicates failure with writing."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + + if(flag & 1) { + ret= Xorriso_update_iso_lba0(xorriso, nwa, isosize, head_buffer, NULL, + flag & 2); + if(ret <= 0) + goto ex; + } + sprintf(xorriso->info_text, "Writing to %s completed sucessfully.\n\n", + Text_shellsafe(xorriso->outdev,sfe,0)); + Xorriso_info(xorriso, 0); + ret= 1; +ex:; + Xorriso_process_msg_queues(xorriso,0); + if(disc!=NULL) + burn_disc_free(disc); + if(xorriso->pacifier_fifo!=NULL) + burn_source_free(xorriso->pacifier_fifo); + xorriso->pacifier_fifo= NULL; + xorriso->run_state= 0; /* Indicate that burning has ended */ + return(ret); +} + +int Xorriso_relax_compliance(struct XorrisO *xorriso, char *mode, + int flag) +{ + char *npt, *cpt; + int l, was; + + was= xorriso->relax_compliance; + npt= cpt= mode; + for(; npt!=NULL; cpt= npt+1) { + npt= strchr(cpt,':'); + if(npt==NULL) + l= strlen(cpt); + else + l= npt-cpt; + if(l == 0) + continue; + if((l == 6 && strncmp(cpt, "strict", l) == 0) || + (l == 5 && strncmp(cpt, "clear", l) == 0)) { + xorriso->relax_compliance= 0; + } else if(l == 7 && strncmp(cpt, "default", l) == 0) { + xorriso->relax_compliance= Xorriso_relax_compliance_defaulT; + + } else if((l == 12 && strncmp(cpt, "omit_version", l) == 0) || + (l == 15 && strncmp(cpt, "omit_version_on", l) == 0) ) { + xorriso->relax_compliance|= isoburn_igopt_omit_version_numbers; + } else if((l == 16 && strncmp(cpt, "omit_version_off", l) == 0)) { + xorriso->relax_compliance&= ~isoburn_igopt_omit_version_numbers; + + } else if((l == 16 && strncmp(cpt, "only_iso_version", l) == 0) || + (l == 19 && strncmp(cpt, "only_iso_version_on", l) == 0) ) { + xorriso->relax_compliance|= isoburn_igopt_only_iso_versions; + } else if((l == 20 && strncmp(cpt, "only_iso_version_off", l) == 0)) { + xorriso->relax_compliance&= ~isoburn_igopt_only_iso_versions; + + } else if((l == 10 && strncmp(cpt, "deep_paths", l) == 0) || + (l == 13 && strncmp(cpt, "deep_paths_on", l) == 0)) { + xorriso->relax_compliance|= isoburn_igopt_allow_deep_paths; + } else if(l == 14 && strncmp(cpt, "deep_paths_off", l) == 0) { + xorriso->relax_compliance&= ~isoburn_igopt_allow_deep_paths; + + } else if((l == 10 && strncmp(cpt, "long_paths", l) == 0) || + (l == 13 && strncmp(cpt, "long_paths_on", l) == 0) ) { + xorriso->relax_compliance|= isoburn_igopt_allow_longer_paths; + } else if(l == 14 && strncmp(cpt, "long_paths_off", l) == 0) { + xorriso->relax_compliance&= ~isoburn_igopt_allow_longer_paths; + + } else if((l == 10 && strncmp(cpt, "long_names", l) == 0) || + (l == 13 && strncmp(cpt, "long_names_on", l) == 0)) { + xorriso->relax_compliance|= isoburn_igopt_max_37_char_filenames; + } else if(l == 14 && strncmp(cpt, "long_names_off", l) == 0) { + xorriso->relax_compliance&= ~isoburn_igopt_max_37_char_filenames; + + } else if((l == 13 && strncmp(cpt, "no_force_dots", l) == 0) || + (l == 16 && strncmp(cpt, "no_force_dots_on", l) == 0)) { + xorriso->relax_compliance|= isoburn_igopt_no_force_dots; + } else if(l == 17 && strncmp(cpt, "no_force_dots_off", l) == 0) { + xorriso->relax_compliance&= ~isoburn_igopt_no_force_dots; + + } else if((l == 15 && strncmp(cpt, "no_j_force_dots", l) == 0) || + (l == 18 && strncmp(cpt, "no_j_force_dots_on", l) == 0)) { + xorriso->relax_compliance|= isoburn_igopt_no_j_force_dots; + } else if(l == 19 && strncmp(cpt, "no_j_force_dots_off", l) == 0) { + xorriso->relax_compliance&= ~isoburn_igopt_no_j_force_dots; + + } else if((l == 9 && strncmp(cpt, "lowercase", l) == 0) || + (l == 12 && strncmp(cpt, "lowercase_on", l) == 0)) { + xorriso->relax_compliance|= isoburn_igopt_allow_lowercase; + } else if(l == 13 && strncmp(cpt, "lowercase_off", l) == 0) { + xorriso->relax_compliance&= ~isoburn_igopt_allow_lowercase; + + } else if((l == 10 && strncmp(cpt, "full_ascii", l) == 0) || + (l == 13 && strncmp(cpt, "full_ascii_on", l) == 0)) { + xorriso->relax_compliance|= isoburn_igopt_allow_full_ascii; + } else if(l == 14 && strncmp(cpt, "full_ascii_off", l) == 0) { + xorriso->relax_compliance&= ~isoburn_igopt_allow_full_ascii; + + } else if((l == 17 && strncmp(cpt, "joliet_long_paths", l) == 0) || + (l == 20 && strncmp(cpt, "joliet_long_paths_on", l) == 0)) { + xorriso->relax_compliance|= isoburn_igopt_joliet_longer_paths; + } else if(l == 21 && strncmp(cpt, "joliet_long_paths_off", l) == 0) { + xorriso->relax_compliance&= ~isoburn_igopt_joliet_longer_paths; + + } else if((l == 10 && strncmp(cpt, "always_gmt", l) == 0) || + (l == 13 && strncmp(cpt, "always_gmt_on", l) == 0)) { + xorriso->relax_compliance|= isoburn_igopt_always_gmt; + } else if(l == 14 && strncmp(cpt, "always_gmt_off", l) == 0) { + xorriso->relax_compliance&= ~isoburn_igopt_always_gmt; + + } else if((l == 9 && strncmp(cpt, "rec_mtime", l) == 0) || + (l == 12 && strncmp(cpt, "rec_mtime_on", l) == 0)) { + xorriso->relax_compliance|= isoburn_igopt_dir_rec_mtime; + } else if(l == 13 && strncmp(cpt, "rec_mtime_off", l) == 0) { + xorriso->relax_compliance&= ~isoburn_igopt_dir_rec_mtime; + + } else if((l == 6 && strncmp(cpt, "old_rr", l) == 0) || + (l == 9 && strncmp(cpt, "old_rr_on", l) == 0) || + (l == 10 && strncmp(cpt, "new_rr_off", l) == 0)) { + xorriso->relax_compliance|= + isoburn_igopt_rrip_version_1_10 | isoburn_igopt_aaip_susp_1_10; + } else if((l == 10 && strncmp(cpt, "old_rr_off", l) == 0) || + (l == 9 && strncmp(cpt, "new_rr_on", l) == 0) || + (l == 6 && strncmp(cpt, "new_rr", l) == 0)) { + xorriso->relax_compliance&= + ~(isoburn_igopt_rrip_version_1_10 | isoburn_igopt_aaip_susp_1_10); + + } else if((l == 14 && strncmp(cpt, "aaip_susp_1_10", l) == 0) || + (l == 17 && strncmp(cpt, "aaip_susp_1_10_on", l) == 0) || + (l == 18 && strncmp(cpt, "aaip_susp_1_12_off", l) == 0)) { + xorriso->relax_compliance|= isoburn_igopt_aaip_susp_1_10; + } else if((l == 18 && strncmp(cpt, "aaip_susp_1_10_off", l) == 0) || + (l == 17 && strncmp(cpt, "aaip_susp_1_12_on", l) == 0) || + (l == 14 && strncmp(cpt, "aaip_susp_1_12", l) == 0)) { + xorriso->relax_compliance&= ~isoburn_igopt_aaip_susp_1_10; + + } else if((l == 8 && strncmp(cpt, "iso_9660", l) == 0) || + (l == 11 && strncmp(cpt, "iso_9660_on", l) == 0)) { + /* may have a meaning in future */; + } else if(l == 12 && strncmp(cpt, "iso_9660_off", l) == 0) { + /* may have a meaning in future */; + Xorriso_msgs_submit(xorriso, 0, + "-compliance -iso_9660_off : Cannot do anything else but ISO 9660", + 0, "FAILURE", 0); + + } else { + if(linfo_text, "-compliance: unknown rule '%s'", + cpt); + else + sprintf(xorriso->info_text, + "-compliance: oversized rule parameter (%d)", l); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + xorriso->relax_compliance= was; + return(0); + } + } + return(1); +} + + +/* @return 1=ok 2=ok, is default setting */ +int Xorriso_get_relax_text(struct XorrisO *xorriso, char mode[1024], + int flag) +{ + int r; + + r= xorriso->relax_compliance; + if(r == 0) { + strcpy(mode, "strict"); + return(1); + } + strcpy(mode, "clear"); + if(r & isoburn_igopt_omit_version_numbers) + strcat(mode, ":omit_version"); + if(r & isoburn_igopt_only_iso_versions) + strcat(mode, ":only_iso_version"); + if(r & isoburn_igopt_allow_deep_paths) + strcat(mode, ":deep_paths"); + if(r & isoburn_igopt_allow_longer_paths) + strcat(mode, ":long_paths"); + if(r & isoburn_igopt_max_37_char_filenames) + strcat(mode, ":long_names"); + if(r & isoburn_igopt_no_force_dots) + strcat(mode, ":no_force_dots"); + if(r & isoburn_igopt_no_j_force_dots) + strcat(mode, ":no_j_force_dots"); + if(r & isoburn_igopt_allow_lowercase) + strcat(mode, ":lowercase"); + if(r & isoburn_igopt_allow_full_ascii) + strcat(mode, ":full_ascii"); + if(r & isoburn_igopt_joliet_longer_paths) + strcat(mode, ":joliet_long_paths"); + if(r & isoburn_igopt_always_gmt) + strcat(mode, ":always_gmt"); + if(r & isoburn_igopt_dir_rec_mtime) + strcat(mode, ":rec_mtime"); + if(r & isoburn_igopt_rrip_version_1_10) { + strcat(mode, ":old_rr"); + if(!(r & isoburn_igopt_aaip_susp_1_10)) + strcat(mode, ":aaip_susp_1_10_off"); + } else { + strcat(mode, ":new_rr"); + if(r & isoburn_igopt_aaip_susp_1_10) + strcat(mode, ":aaip_susp_1_10"); + } + + return(1 + (r == Xorriso_relax_compliance_defaulT)); +} + + +/* @param flag bit0= operating on newly attached boot image +*/ +int Xorriso_set_isolinux_options(struct XorrisO *xorriso, + IsoImage *image, int flag) +{ + int make_isohybrid_mbr= 0, ret, patch_table= 0, num_boots, i; + ElToritoBootImage *bootimg, **boots = NULL; + IsoFile *bootimg_node, **bootnodes = NULL; + + ret= iso_image_get_boot_image(image, &bootimg, &bootimg_node, NULL); + Xorriso_process_msg_queues(xorriso,0); + if(ret != 1) { + sprintf(xorriso->info_text, "Programming error: No boot image available in Xorriso_set_isolinux_options()"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); + ret= -1; goto ex; + } + ret= iso_image_get_all_boot_imgs(image, &num_boots, &boots, &bootnodes, 0); + Xorriso_process_msg_queues(xorriso,0); + if(ret != 1) { + Xorriso_report_iso_error(xorriso, "", ret, "Cannot inquire boot images", 0, + "FATAL", 1); + ret= -1; goto ex; + } + patch_table= xorriso->patch_isolinux_image & 1; + if((flag & 1) && num_boots > 1) { + ret= el_torito_set_isolinux_options(boots[num_boots - 1], patch_table, 0); + ret= (ret == 1); goto ex; + } + + /* Handle patching of first attached boot image or of imported boot images + */ + for(i= 0; i < num_boots; i++) { + patch_table = xorriso->patch_isolinux_image & 1; + if(patch_table && !(flag & 1)) { + if(!el_torito_seems_boot_info_table(boots[i], 0)) + patch_table= 0; + else if((xorriso->patch_isolinux_image & 2) && + el_torito_get_boot_platform_id(boots[i]) == 0xef) + patch_table= 0; + } + if(i > 0 || xorriso->boot_image_isohybrid == 0) { + ret= el_torito_set_isolinux_options(boots[i], patch_table, 0); + if(ret != 1) + {ret= 0; goto ex;} + continue; + } + if(xorriso->boot_image_isohybrid == 3) { + make_isohybrid_mbr= 1; + } else { + ret= Xorriso_is_isohybrid(xorriso, bootimg_node, 0); + if(ret < 0) + {ret= 0; goto ex;} + if(ret > 0) + make_isohybrid_mbr= 1; + } + + if(xorriso->boot_image_isohybrid == 2 && !make_isohybrid_mbr) { + sprintf(xorriso->info_text, + "Isohybrid signature is demanded but not found in boot image file."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + if(make_isohybrid_mbr) { + sprintf(xorriso->info_text, "Will write isohybrid MBR."); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + xorriso->alignment= 512; + } + ret= el_torito_set_isolinux_options(bootimg, + patch_table | (make_isohybrid_mbr << 1),0); + if(ret != 1) + {ret= 0; goto ex;} + } +ex: + Xorriso_process_msg_queues(xorriso,0); + if(boots != NULL) + free(boots); + if(bootnodes != NULL) + free(bootnodes); + return(ret); +} + + +/* + @param flag bit0= obtain iso_lba from indev + bit1= head_buffer already contains a valid head + bit2= issue message about success + bit3= check whether source blocks are banned by in_sector_map +*/ +int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize, + char *head_buffer, struct CheckmediajoB *job, + int flag) +{ + int ret, full_size, i; + char *headpt; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + off_t seek_ret; + + ret= Xorriso_may_burn(xorriso, 0); + if(ret <= 0) + return(0); + if(flag & 1) { + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to learn current session lba", 1); + if(ret<=0) + return(0); + ret= isoburn_disc_get_msc1(drive, &iso_lba); + if(ret<=0) + return(0); + drive= NULL; /* indev will not be used furtherly */ + } + if(job == NULL) { + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to update at lba 0 to 31", 2); + if(ret<=0) + return(0); + } + if(iso_lba < 32) + return(2); + if(!(flag & 2)) { + /* head_buffer was not filled yet. Read it from output media. */ + if(job != NULL && job->data_to_fd >= 0) { + if((flag & 8) && job->sector_map != NULL) { + ret= Sectorbitmap_bytes_are_set(job->sector_map, + ((off_t) iso_lba) * (off_t) 2048, + ((off_t) (iso_lba + 32)) * ((off_t) 2048) - (off_t) 1, 0); + if(ret <= 0) { + sprintf(xorriso->info_text, + "ISO image head at lba %d is marked as invalid blocks in file copy", + iso_lba); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", + 0); + return(0); + } + } + seek_ret= lseek(job->data_to_fd, ((off_t) 2048) * (off_t) iso_lba, + SEEK_SET); + if(seek_ret == -1) + ret= 0; + else + ret= read(job->data_to_fd, head_buffer, 64 * 1024); + if(ret < 64 * 1024) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "Cannot read ISO image head from file copy"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); + return(0); + } + } else { + ret= isoburn_read_iso_head(drive, iso_lba, &isosize, head_buffer, 2); + if(ret<=0) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "Cannot read freshly written ISO image head"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + } + /* patch ISO header */ + full_size= iso_lba + isosize; + headpt= head_buffer + 32*1024; + for(i=0;i<4;i++) + headpt[87-i]= headpt[80+i]= (full_size >> (8*i)) & 0xff; + + if(job != NULL) { + seek_ret= lseek(job->data_to_fd, (off_t) 0, SEEK_SET); + if(seek_ret == -1) + ret= 0; + else + ret= write(job->data_to_fd, head_buffer, 64 * 1024); + if(ret < 64 * 1024) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "Cannot write ISO image head to file copy"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); + return(0); + } + } else { + ret= burn_random_access_write(drive, (off_t) 0, head_buffer, + (off_t) (64*1024), 1); + if(ret<=0) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "Cannot write new ISO image head to LBA 0"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + if(flag & 4) { + sprintf(xorriso->info_text, + "Overwrote LBA 0 to 31 by 64 KiB from LBA %d", iso_lba); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } + return(1); +} + + +int Xorriso_set_system_area_path(struct XorrisO *xorriso, char *path, int flag) +{ + int ret; + char eff_src[SfileadrL]; + + if(path[0] == 0) { + xorriso->system_area_disk_path[0]= 0; + return(1); + } + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, path, eff_src, 2|4|16); + if(ret < 0) + return(ret); + if(ret == 0) { + sprintf(xorriso->info_text, + "Given path does not exist on disk: -boot_image system_area="); + Text_shellsafe(eff_src, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } + if(ret == 2) { + sprintf(xorriso->info_text, + "Given path leads to a directory: -boot_image system_area="); + Text_shellsafe(eff_src, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= Sfile_str(xorriso->system_area_disk_path, eff_src, 0); + if(ret <= 0) + return(-1); + return(1); +} + diff --git a/xorriso/write_run.h b/xorriso/write_run.h new file mode 100644 index 00000000..f245f025 --- /dev/null +++ b/xorriso/write_run.h @@ -0,0 +1,53 @@ + +/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. + + Copyright 2007-2010 Thomas Schmitt, + + 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 */ + diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c deleted file mode 100644 index a2e5c902..00000000 --- a/xorriso/xorriso.c +++ /dev/null @@ -1,21301 +0,0 @@ - -/* - - ( cd .. ; libisoburn-develop/xorriso/compile_xorriso.sh -g ) - -or - - cc -g -DXorriso_with_maiN -DXorriso_with_readlinE \ - -DXorriso_build_timestamP='"'"$(date -u '+%Y.%m.%d.%H%M%S')"'"' \ - -Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -o xorriso/xorriso \ - xorriso/xorriso.c xorriso/xorrisoburn.c \ - -lz -lacl -lpthread -lreadline -lburn -lisofs -lisoburn - -or - - cc -g -DXorriso_with_readlinE \ - -DXorriso_build_timestamP='"'"$(date -u '+%Y.%m.%d.%H%M%S')"'"' \ - -Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ - -c \ - xorriso/xorriso.c xorriso/xorrisoburn.c - -*/ - -/* Command line oriented batch and dialog tool which creates, loads, - manipulates and burns ISO 9660 filesystem images. - - Copyright 2007-2010 Thomas Schmitt, - - 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. - - xorrisoburn.[ch] encapsulate any usage of the libraries by xorriso. - - 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. - - xorriso_private.h is not to be included by other software. It encapsulates - the inner interfaces of xorriso. - - xorriso.c provides the command interpreter as described in xorriso.1. - It performs any activity that does not demand a reference to a symbol - of the library APIs. This includes: - - Interpretation of user input from arguments, dialog, and scripting. - - Output of result text and event messages. - - POSIX filesystem operations. - - Public functions which perform the particular xorriso commands. - - The main() function, if enabled by #define Xorriso_with_maiN. - -*/ - -/* This may be changed to Xorriso_GNU_xorrisO in order to create GNU xorriso */ -#define Xorriso_libburnia_xorrisO yes - - -#ifdef Xorriso_without_subS - - - -#include -#include -#include -#include -#include -#include - -#include - -/* The official xorriso options API. "No shortcuts" */ -#include "xorriso.h" - - - -#else /* Xorriso_without_subS */ - - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* for -charset */ -#include -#include -#include - -/* eventually, this is done in xorriso_private.h : #include */ - -#ifdef Xorriso_with_readlinE -#ifdef Xorriso_with_old_readlinE -#include -#include -#else /* Xorriso_with_old_readlinE */ -#include -#include -#endif /* ! Xorriso_with_old_readlinE */ -#endif /* Xorriso_with_readlinE */ - -#define TSOB_FELD(typ,anz) (typ *) calloc(1, (anz)*sizeof(typ)); - - -/* Diet facility: exclude help texts from binaries */ -/* This will eventually be redefined to eat up its content */ -#define AlN(x) x - - -/* There is only one stage of diet: Xorriso_no_helP */ -#ifdef Xorriso_no_helP -#undef AlN -#define AlN(x) -#endif - - -/* ------------------------------------------------------------------------ */ - - -/* The official xorriso options API. "No shortcuts" */ -#include "xorriso.h" - -/* The inner description of XorrisO */ -#define Xorriso_is_xorriso_selF 1 -#include "xorriso_private.h" - -/* The inner isofs- and burn-library interface */ -#include "xorrisoburn.h" - - -/* See Xorriso__preset_signal_behavior() */ -static int Xorriso_signal_behavioR= 1; - - -/* ------------------------------------------------------------------------ */ - - -#ifndef Xorriso_sfile_externaL -/* @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; ist_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(value0) - 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(¤t_time); - for(i=0;i'9' && text[0]<'A') || text[0]>'Z') - return(0); - l= strlen(text); - for(i=1;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'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); -} - -#endif /* Xorriso_sfile_externaL */ - - -/* --------------------------------- misc --------------------------------- */ - - -int Strcmp(const void *pt1, const void *pt2) -{ - return(strcmp(*((char **) pt1), *((char **) pt2))); -} - - -int Sort_argv(int argc, char **argv, int flag) -{ - if(argc<=0) - return(2); - qsort(argv,(size_t) argc,sizeof(char *),Strcmp); - return(1); -} - - -static int Text_to_argv(char *text, int *argc, char ***argv, int flag) -{ - char *npt, *cpt; - int pass; - - *argv= NULL; - *argc= 0; - for(pass= 0; pass < 2; pass++) { - if(pass) { - if(*argc == 0) - return(1); - (*argv)= calloc(*argc, sizeof(char *)); - if(*argv == NULL) { - *argc= 0; - return(-1); - } - *argc= 0; - } - for(npt= cpt= text; npt != NULL; cpt= npt + 1) { - npt= strchr(cpt, '\n'); - if(pass) { - if(npt != NULL) - *npt= 0; - (*argv)[*argc]= cpt; - } - (*argc)++; - } - } - return(1); -} - - -static int Count_diffs(int argc1, char **argv1, int argc2, char **argv2, - int flag) -{ - int count= 0, i1= 0, i2= 0, cmp, end_corr= 0; - - Sort_argv(argc1, argv1, 0); - Sort_argv(argc2, argv2, 0); - - while(1) { - if(i1 >= argc1) { - count+= argc2 - i2 - end_corr; - break; - } - if(i2 >= argc2) { - count+= argc1 - i1 - end_corr; - break; - } - cmp= strcmp(argv1[i1], argv2[i2]); - if(cmp == 0) { - end_corr= 0; - i1++; - i2++; - } else if(cmp > 0) { - count++; - end_corr= 1; - i2++; - if(i2 < argc2 && i1 < argc1 - 1) - if(strcmp(argv1[i1 + 1], argv2[i2]) == 0) { - i1++; - end_corr= 0; - } - } else { - count++; - end_corr= 1; - i1++; - if(i1 < argc1 && i2 < argc2 - 1) - if(strcmp(argv2[i2 + 1], argv1[i1]) == 0) { - i2++; - end_corr= 0; - } - } - } - return(count); -} - - -/* - @flag bit0= do not initialize *diff_count - @return <0 error , 0 = mismatch , 1 = match -*/ -static int Compare_text_lines(char *text1, char *text2, int *diff_count, - int flag) -{ - int ret, argc1= 0, argc2= 0; - char **argv1= NULL, **argv2= NULL, *copy1= NULL, *copy2= NULL; - - if(!(flag & 1)) - *diff_count= 0; - if(text1 == NULL && text2 == NULL) - return(1); - if(text1 != NULL) { - copy1= strdup(text1); - if(copy1 == NULL) - {ret= -1; goto ex;} - ret= Text_to_argv(copy1, &argc1, &argv1, 0); - if(ret <= 0) - {ret= -1; goto ex;} - } - if(text2 != NULL) { - copy2= strdup(text2); - if(copy2 == NULL) - {ret= -1; goto ex;} - ret= Text_to_argv(copy2, &argc2, &argv2, 0); - if(ret <= 0) - {ret= -1; goto ex;} - } - ret= Count_diffs(argc1, argv1, argc2, argv2, 1); - if(ret < 0) - goto ex; - *diff_count+= ret; - ret= (*diff_count == 0); -ex:; - if(argv1 != NULL) - free(argv1); - if(argv2 != NULL) - free(argv2); - if(copy1 != NULL) - free(copy1); - if(copy2 != NULL) - free(copy2); - return ret; -} - - -/** 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) -/* - bit0= default value -1 rather than 0 -*/ -{ - int c; - double ret= 0.0; - - if(flag&1) - ret= -1.0; - if(text[0]==0) - return(ret); - sscanf(text,"%lf",&ret); - c= text[strlen(text)-1]; - if(c=='k' || c=='K') ret*= 1024.0; - if(c=='m' || c=='M') ret*= 1024.0*1024.0; - if(c=='g' || c=='G') ret*= 1024.0*1024.0*1024.0; - if(c=='t' || c=='T') ret*= 1024.0*1024.0*1024.0*1024.0; - if(c=='p' || c=='P') ret*= 1024.0*1024.0*1024.0*1024.0*1024.0; - if(c=='e' || c=='E') ret*= 1024.0*1024.0*1024.0*1024.0*1024.0*1024.0; - if(c=='s' || c=='S') ret*= 2048.0; - return(ret); -} - - -int Decode_date_input_format(struct tm *erg, char *text, int flag) -/* MMDDhhmm[[CC]YY][.ss]] */ -{ - int i,l,year; - time_t current_time; - struct tm *now; - - current_time= time(0); - now= localtime(¤t_time); - for(i=0;i'9') - break; - if(i!=8 && i!=10 && i!=12) - return(0); - if(text[i]==0) - goto decode; - if(text[i]!='.' || l!=15) - return(0); - i++; - if(text[i]<'0'||text[i]>'9') - return(0); - i++; - if(text[i]<'0'||text[i]>'9') - return(0); - -decode:; - /* MMDDhhmm[[CC]YY][.ss]] */ - i= 0; - erg->tm_mon= 10*(text[0]-'0')+text[1]-'0'-1; - erg->tm_mday= 10*(text[2]-'0')+text[3]-'0'; - erg->tm_hour= 10*(text[4]-'0')+text[5]-'0'; - erg->tm_min= 10*(text[6]-'0')+text[7]-'0'; - erg->tm_sec= 0; - if(l==8) - return(1); - if(l>10){ - year= 1000*(text[8]-'0')+100*(text[9]-'0')+10*(text[10]-'0')+(text[11]-'0'); - }else{ - year= 1900+10*(text[8]-'0')+(text[9]-'0'); - if(year<1970) - year+= 100; - } - erg->tm_year= year-1900; - if(l<=12) - return(1); - erg->tm_sec= 10*(text[13]-'0')+text[14]-'0'; - return(1); -} - - -int Decode_date_weekday(char *text, int flag) -{ - int i; - static char days[][4]= {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", ""}; - - for(i= 0; days[i][0]!=0; i++) - if(strncmp(text,days[i],3)==0) - return(i); - if((strlen(text)==3 || (strlen(text)==4 && text[3]==',')) && - isalpha(text[0]) && isalpha(text[1]) && isalpha(text[2])) - return(7); - return(-1); -} - - -int Decode_date_month(char *text, int flag) -{ - int i; - static char months[][4]= {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""}; - - for(i= 0; months[i][0]!=0; i++) - if(strncmp(text,months[i],3)==0) - return(i); - return(-1); -} - - -/* @return -1=not a number, -2=not a day , 1 to 31 day of month */ -int Decode_date_mday(char *text, int flag) -{ - int ret, i; - - for(i= 0; text[i]!=0; i++) - if(!isdigit(text[i])) - return(-1); - if(strlen(text)>2 || text[0]==0) - return(-2); - sscanf(text, "%d", &ret); - if(ret<=0 || ret>31) - return(-2); - return(ret); -} - -int Decode_date_hms(char *text, struct tm *erg, int flag) -{ - int i, hour= -1, minute= -1, second= 0; - - for(i= 0; i<9; i+= 3) { - if(i==6&&text[i]==0) - break; - if(!isdigit(text[i])) - return(-1); - if(!isdigit(text[i+1])) - return(-1); - if(text[i+2]!=':' && !(text[i+2]==0 && i>=3)) - return(-1); - if(i==0) - sscanf(text+i,"%d",&hour); - else if(i==3) - sscanf(text+i,"%d",&minute); - else - sscanf(text+i,"%d",&second); - } - if(hour<0 || hour>23 || minute<0 || minute>59 || second>59) - return(-1); - erg->tm_hour= hour; - erg->tm_min= minute; - erg->tm_sec= second; - return(1); -} - - -/* @return -1=not a number, -2=not a year , >=0 years AD */ -int Decode_date_year(char *text, int flag) -{ - int ret, i; - - for(i= 0; text[i]!=0; i++) - if(!isdigit(text[i])) - return(-1); - if(strlen(text)!=4) - return(-2); - sscanf(text, "%d", &ret); - if(ret<0 || ret>3000) - return(-2); - return(ret); -} - - -int Decode_date_timezone(char *text, struct tm *erg, int flag) -{ - int i; - static char tzs[][5]= {"GMT", "CET", "CEST", "0000", ""}; - - for(i= 0; tzs[i][0]!=0; i++) - if(strcmp(text,tzs[i])==0) { - - /* ??? >>> what to do with timezone info ? Add to ->tm_hour ? */ - - return(1); - } - if(text[0]=='+' || text[0]=='-') { - for(i= 1; text[i]!=0; i++) - if(!isdigit(text[i])) - return(-1); - if(i!=5) - return(-1); - - /* ??? >>> what to do with timezone info ? Add to ->tm_hour ? */ - - return(1); - } else { - for(i= 0; text[i]!=0; i++) - if(text[i]<'A' || text[i]>'Z') - return(-1); - if(i!=3 && i!=4) - return(-1); - return(2); - } -} - - -int Decode_date_output_format(struct tm *erg, char *text, int flag) -/* Thu Nov 8 09:07:50 CET 2007 */ -/* Sat, 03 Nov 2007 08:58:30 +0100 */ -/* Nov 7 23:24 */ -{ - int ret, i, argc= 0, seen_year= 0, seen_month= 0, seen_day= 0, seen_time= 0; - char **argv= NULL; - struct tm *now; - time_t timep; - - memset(erg, 0, sizeof(*erg)); - erg->tm_isdst= -1; - ret= Sfile_make_argv("xorriso", text, &argc, &argv, 0); - if(ret<=0) - goto ex; - for(i= 1; i=0) { - seen_month= 1; - erg->tm_mon= ret; - continue; - } - } - if(!seen_day) { - ret= Decode_date_mday(argv[i], 0); - if(ret>0) { - seen_day= 1; - erg->tm_mday= ret; - continue; - } - if(ret==-2) /* first pure number must be day of month */ - {ret= 0; goto ex;} - } - if(!seen_time) { - ret= Decode_date_hms(argv[i], erg, 0); - if(ret>0) { - seen_time= 1; - continue; - } - } - if(!seen_year) { - ret= Decode_date_year(argv[i], 0); - if(ret>0) { - erg->tm_year= ret-1900; - seen_year= 1; - continue; - } - } - - /* ignorants have to stay at the end of the loop */ - - ret= Decode_date_timezone(argv[i], erg, 0); - if(ret>=0) - continue; - ret= Decode_date_weekday(argv[i], 0); - if(ret>=0) - continue; /* ignore weekdays */ - - {ret= 0; goto ex;} /* unrecognizable component */ - } - - if(!(seen_day && seen_month)) - {ret= 0; goto ex;} - if(!seen_year) { /* then use this year */ - timep= time(NULL); - now= localtime(&timep); - erg->tm_year= now->tm_year; - } - ret= 1; -ex: - Sfile_make_argv("", "", &argc, &argv, 2); /* release storage */ - return(ret); -} - - -int Decode_ecma119_format(struct tm *erg, char *text, int flag) -/* YYYYMMDDhhmmsscc */ -/* 2010040711405800 */ -{ - int i, l, num; - - memset(erg, 0, sizeof(*erg)); - erg->tm_isdst= -1; - l= strlen(text); - if(l != 16) - return(0); - for(i= 0; i < l; i++) - if(text[i] < '0' || text[i] > '9') - return(0); - num= 0; - for(i= 0; i < 4; i++) - num= num * 10 + text[i] - '0'; - if(num < 1970 || num > 3000) - return(0); - erg->tm_year = num - 1900; - erg->tm_mon= 10*(text[4]-'0')+text[5]-'0'-1; - if(erg->tm_mon > 12) - return(0); - erg->tm_mday= 10*(text[6]-'0')+text[7]-'0'; - if(erg->tm_mday > 31) - return(0); - erg->tm_hour= 10*(text[8]-'0')+text[9]-'0'; - if(erg->tm_hour > 23) - return(0); - erg->tm_min= 10*(text[10]-'0')+text[11]-'0'; - if(erg->tm_min > 59) - return(0); - erg->tm_sec= 10*(text[12]-'0')+text[13]-'0'; - if(erg->tm_sec > 59) - return(0); - return(1); -} - - -int Decode_xorriso_timestamp(struct tm *erg, char *code, int flag) - /* 2007.11.07.225624 */ -{ - char buf[20]; - int year,month,day,hour= 0,minute= 0,second= 0, i, l, mem; - - memset(erg, 0, sizeof(*erg)); - erg->tm_isdst= -1; - - l= strlen(code); - if(l>17 || l<10) - return(0); - strcpy(buf, code); - for(i= 0; buf[i]!=0 && i<4; i++) - if(!isdigit(buf[i])) - return(0); - if(buf[4]!='.') - return(0); - buf[4]= 0; - sscanf(buf, "%d", &year); - if(year<1900 || year>3000) - return(0); - if(!(isdigit(buf[5]) && isdigit(buf[6]) && buf[7]=='.')) - return(0); - buf[7]= 0; - sscanf(buf+5, "%d", &month); - if(month<1 || month>12) - return(0); - if(!(isdigit(buf[8]) && isdigit(buf[9]) && (buf[10]=='.' || buf[10]==0))) - return(0); - buf[10]= 0; - sscanf(buf+8, "%d", &day); - if(day<1 || day>31) - return(0); - if(l==10) - goto done; - if(!(isdigit(buf[11]) && isdigit(buf[12]) && - (isdigit(buf[13]) || buf[13]==0))) - return(0); - mem= buf[13]; - buf[13]= 0; - sscanf(buf+11, "%d", &hour); - buf[13]= mem; - if(hour<0 || hour>23) - return(0); - if(l==13) - goto done; - if(!(isdigit(buf[13]) && isdigit(buf[14]) && - (isdigit(buf[15]) || buf[15]==0))) - return(0); - mem= buf[15]; - buf[15]= 0; - sscanf(buf+13, "%d", &minute); - buf[15]= mem; - if(minute<0 || minute>59) - return(0); - if(l==15) - goto done; - if(!(isdigit(buf[15]) && isdigit(buf[16]) && buf[17]==0)) - return(0); - sscanf(buf+15, "%d", &second); - if(second<0 || second>59) - return(0); - -done:; - erg->tm_year= year-1900; - erg->tm_mon= month-1; - erg->tm_mday= day; - erg->tm_hour= hour; - erg->tm_min= minute; - erg->tm_sec= second; - return(1); -} - - -time_t Decode_timestring(char *code, time_t *date, int flag) -{ - char *cpt,scale_chr; - double value,seconds; - struct tm result_tm; - int seconds_valid= 0; - - *date= 0; - cpt= code; - if(code[0]=='-' || code[0]=='+' || code[0]=='=' || code[0]=='@'){ - if(code[1]==0) - return(0); - if(!isdigit(code[1])) - return(0); - value= -1; - if(code[0]=='=' || code[0]=='@') { - seconds= 0; - sscanf(code+1,"%lf",&value); - } else { - seconds= time(NULL); - sscanf(code,"%lf",&value); - } - scale_chr= code[strlen(code)-1]; - if(isalpha(scale_chr)) - scale_chr= tolower(scale_chr); - if (scale_chr=='s') seconds+= 1.0*value; - else if(scale_chr=='h') seconds+= 3600.0*value; - else if(scale_chr=='d') seconds+= 86400.0*value; - else if(scale_chr=='w') seconds+= 86400.0*7.0*value; - else if(scale_chr=='m') seconds+= 86400.0*31.0*value; - else if(scale_chr=='y') seconds+= 86400.0*(365.25*value+1.0); - else seconds+= 1.0*value; - seconds_valid= 1; - goto completed; - } else if(Sfile_decode_datestr(&result_tm,code,0)>0) { - /* YYMMDD[.hhmm[ss]] */ - result_tm.tm_isdst= -1; - seconds= mktime(&result_tm); - seconds_valid= 1; - goto completed; - } else if(Decode_date_input_format(&result_tm,code,0)>0) { - /* MMDDhhmm[[CC]YY][.ss]] */ - result_tm.tm_isdst= -1; - seconds= mktime(&result_tm); - seconds_valid= 1; - goto completed; - } else if(Decode_xorriso_timestamp(&result_tm, code, 0)>0) { - /* 2007.11.07.225624 */ - seconds= mktime(&result_tm); - seconds_valid= 1; - goto completed; - } else if(Decode_date_output_format(&result_tm, code, 0)>0) { - /* Thu Nov 8 09:07:50 CET 2007 */; - /* Sat, 03 Nov 2007 08:58:30 +0100 */; - /* Nov 7 23:24 */; - seconds= mktime(&result_tm); - seconds_valid= 1; - goto completed; - } else if(Decode_ecma119_format(&result_tm, code, 0)>0) { - /* YYYYMMDDhhmmsscc */ - /* 2010040711405800 */ - seconds= mktime(&result_tm); - seconds_valid= 1; - goto completed; - } - return(0); -completed:; - if(!seconds_valid) - return(0); - *date= seconds; - return(1); -} - - -/* @param flag bit0=with year and seconds - bit1-3= form - 0= ls -l format - 1= timestamp format YYYY.MM.DD.hhmmss - 2= Wdy Mon Day hh:mm:ss Year - 3= Mon Day hh:mm:ss Year - 4= YYMMDD.hhmmss -*/ -char *Ftimetxt(time_t t, char timetext[40], int flag) -{ - char *rpt; - struct tm tms, *tmpt; - static char months[12][4]= { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - static char days[7][4]= {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; - int form; - - form= (flag>>1)&7; - tmpt= localtime_r(&t, &tms); - rpt= timetext; - rpt[0]= 0; - if(tmpt==0) - sprintf(rpt+strlen(rpt), "%12.f", (double) t); - else if (form==1) - sprintf(rpt+strlen(rpt), "%4.4d.%2.2d.%2.2d.%2.2d%2.2d%2.2d", - 1900+tms.tm_year, tms.tm_mon+1, tms.tm_mday, - tms.tm_hour, tms.tm_min, tms.tm_sec); - else if (form==2) - sprintf(rpt+strlen(rpt), "%s %s %2.2d %2.2d:%2.2d:%2.2d %4.4d", - days[tms.tm_wday], months[tms.tm_mon], tms.tm_mday, - tms.tm_hour, tms.tm_min, tms.tm_sec, 1900+tms.tm_year); - else if (form==3) - sprintf(rpt+strlen(rpt), "%s %2.2d %2.2d:%2.2d:%2.2d %4.4d", - months[tms.tm_mon], tms.tm_mday, - tms.tm_hour, tms.tm_min, tms.tm_sec, 1900+tms.tm_year); - else if (form == 4) { - if(tms.tm_year>99) - sprintf(rpt+strlen(rpt), "%c", 'A' + (tms.tm_year - 100) / 10); - else - sprintf(rpt+strlen(rpt), "%c", '0' + tms.tm_year / 10); - sprintf(rpt+strlen(rpt), "%1.1d%2.2d%2.2d.%2.2d%2.2d%2.2d", - tms.tm_year % 10, tms.tm_mon + 1, tms.tm_mday, - tms.tm_hour, tms.tm_min, tms.tm_sec); - } else if (flag&1) - sprintf(rpt+strlen(rpt), "%2d %3s %4.4d %2.2d:%2.2d:%2.2d", - tms.tm_mday, months[tms.tm_mon], 1900+tms.tm_year, - tms.tm_hour, tms.tm_min, tms.tm_sec); - else if(time(NULL)-t < 180*86400 && time(NULL)-t >= 0) - sprintf(rpt+strlen(rpt), "%3s %2d %2.2d:%2.2d", - months[tms.tm_mon], tms.tm_mday, tms.tm_hour, tms.tm_min); - else - sprintf(rpt+strlen(rpt), "%3s %2d %4.4d", - months[tms.tm_mon], tms.tm_mday, 1900+tms.tm_year); - return(timetext); -} - - -/* @param flag bit0= single letters */ -char *Ftypetxt(mode_t st_mode, int flag) -{ - if(flag&1) - goto single_letters; - if(S_ISDIR(st_mode)) - return("directory"); - else if(S_ISREG(st_mode)) - return("regular_file"); - else if(S_ISLNK(st_mode)) - return("symbolic_link"); - else if(S_ISBLK(st_mode)) - return("block_device"); - else if(S_ISCHR(st_mode)) - return("char_device"); - else if(S_ISFIFO(st_mode)) - return("name_pipe"); - else if(S_ISSOCK(st_mode)) - return("unix_socket"); - return("unknown"); -single_letters:; - if(S_ISDIR(st_mode)) - return("d"); - else if(S_ISREG(st_mode)) - return("-"); - else if(S_ISLNK(st_mode)) - return("l"); - else if(S_ISBLK(st_mode)) - return("b"); - else if(S_ISCHR(st_mode)) - return("c"); - else if(S_ISFIFO(st_mode)) - return("p"); - else if(S_ISSOCK(st_mode)) - return("s"); - return("?"); -} - - -int Wait_for_input(int fd, int microsec, int flag) -{ - struct timeval wt; - fd_set rds,wts,exs; - int ready; - - FD_ZERO(&rds); - FD_ZERO(&wts); - FD_ZERO(&exs); - FD_SET(fd,&rds); - FD_SET(fd,&exs); - wt.tv_sec= microsec/1000000; - wt.tv_usec= microsec%1000000; - ready= select(fd+1,&rds,&wts,&exs,&wt); - if(ready<=0) - return(0); - if(FD_ISSET(fd,&exs)) - return(-1); - if(FD_ISSET(fd,&rds)) - return(1); - return(0); -} - - -int System_uname(char **sysname, char **release, char **version, - char **machine, int flag) -{ - int ret; - static struct utsname uts; - static int initialized= 0; - - if(initialized == 0) { - ret= uname(&uts); - if(ret != 0) - initialized = -1; - } - if(initialized == -1) - return(0); - if(sysname != NULL) - *sysname= uts.sysname; - if(release != NULL) - *release= uts.release; - if(version != NULL) - *version= uts.version; - if(machine != NULL) - *machine= uts.machine; - return(1); -} - -/* ------------------------------------------------------------------------ */ - - -#ifndef Xorriso_sregex_externaL - -#ifndef Smem_malloC -#define Smem_malloC malloc -#endif -#ifndef Smem_freE -#define Smem_freE free -#endif - - -int Sregex_string_cut(char **handle, char *text, int len, int flag) -/* - bit0= append (text!=NULL) -*/ -{ - int l=0; - char *old_handle; - - if((flag&1)&&*handle!=NULL) - l+= strlen(*handle); - old_handle= *handle; - if(text!=NULL) { - l+= len; - *handle= TSOB_FELD(char,l+1); - if(*handle==NULL) { - *handle= old_handle; - return(0); - } - if((flag&1) && old_handle!=NULL) - strcpy(*handle,old_handle); - else - (*handle)[0]= 0; - if(len>0) - strncat(*handle,text,len); - } else { - *handle= NULL; - } - if(old_handle!=NULL) - Smem_freE(old_handle); - return(1); -} - - -int Sregex_string(char **handle, char *text, int flag) -/* - bit0= append (text!=NULL) -*/ -{ - int ret,l=0; - - if(text!=NULL) - l= strlen(text); - -/* #define Sregex_looking_for_contenT 1 */ -#ifdef Sregex_looking_for_contenT - /* a debugging point if a certain text content has to be caught */ - if(text!=NULL) - if(strcmp(text,"clear")==0) - ret= 0; -#endif - - ret= Sregex_string_cut(handle,text,l,flag&1); - return(ret); -} - - -/* - 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) -{ - int l_e, l_v, l_s, l_esc, i, start_equals_esc; - char *rpt, *wpt, *spt, *npt, *ept; - - if(start[0] == 0) /* It is not allowed to have no start marker */ - return(-1); - l_s= strlen(start); - l_e= strlen(end); - l_esc= strlen(esc); - start_equals_esc= !strcmp(start, esc); - rpt= form; - wpt= result; - wpt[0]= 0; - while(1) { - - /* look for start mark */ - spt= strstr(rpt, start); - if(spt == NULL) { - if((wpt - result) + strlen(rpt) >= result_size) - return(0); - strcpy(wpt, rpt); - wpt+= strlen(wpt); - break; - } - - /* copy cleartext part up to next variable */ - if((wpt - result) + (spt - rpt) >= result_size) - return(0); - strncpy(wpt, rpt, spt - rpt); - wpt+= spt - rpt; - *wpt= 0; - rpt= spt; - npt= spt + l_s; - - /* handle eventual escape */ - if(start_equals_esc) { - if(strncmp(spt + l_s, esc, l_esc) == 0) { - /* copy esc and start */ - if((wpt - result) + l_esc + l_s >= result_size) - return(0); - strncpy(wpt, spt, l_esc + l_s); - wpt+= l_esc + l_s; - rpt+= l_esc + l_s; - *wpt= 0; - continue; - } - } else { - /* escape would be already copied */ - if(l_esc > 0 && spt - form >= l_esc) { - if(strncmp(spt - l_esc, esc, l_esc) == 0) { - /* copy start */ - if((wpt - result) + l_s >= result_size) - return(0); - strncpy(wpt, spt, l_s); - wpt+= l_s; - rpt+= l_s; - *wpt= 0; - continue; - } - } - } - - /* Memorize eventual end mark for default handling */; - ept= NULL; - if(l_e > 0) - ept= strstr(npt, end); - - /* Look for defined variable name */ - for(i = 0; i < num_vars; i++) { - if(strncmp(npt, vars[i][0], strlen(vars[i][0])) == 0 - && (l_e == 0 || strncmp(npt + strlen(vars[i][0]), end, l_e) == 0)) - break; - } - if(i < num_vars) { - /* substitute found variable */ - l_v= strlen(vars[i][0]); - if((wpt - result) + strlen(vars[i][1]) >= result_size) - return(0); - strcpy(wpt, vars[i][1]); - rpt= npt + strlen(vars[i][0]) + l_e; - } else if((flag & 1) && ept != NULL) { - /* skip up to end mark */ - rpt= ept + l_e; - } else if(ept != NULL) { - /* copy start,name,end */ - if((wpt - result) + (ept - rpt) + l_e >= result_size) - return(0); - strncpy(wpt, rpt, (ept - rpt) + l_e); - rpt= ept + l_e; - } else { - /* copy start marker only */ - if((wpt - result) + l_s >= result_size) - return(0); - strncpy(wpt, rpt, l_s); - rpt= rpt + l_s; - } - wpt+= strlen(wpt); - *wpt= 0; - } - return(1); -} - - -/* @param flag bit0= only test expression whether compilable -*/ -int Sregex_match(char *pattern, char *text, int flag) -{ - int ret; - char re_text[2*SfileadrL]; - regex_t re; - regmatch_t match[1]; - - Xorriso__bourne_to_reg(pattern, re_text, 0); - ret= regcomp(&re, re_text, 0); - if(ret != 0) - return(-1); - if(flag & 1) { - regfree(&re); - return(1); - } - ret= regexec(&re, text, 1, match, 0); - regfree(&re); - if(ret != 0) - return(0); - return(1); -} - - -#endif /* Xorriso_sregex_externaL */ - - - -/* @param flag bit0= append to out_text rather than overwrite it -*/ -char *Text_shellsafe(char *in_text, char *out_text, int flag) -{ - int l,i,ol= 0,w=0; - - if(flag&1) - ol= w= strlen(out_text); - /* enclose everything by hard quotes */ - l= strlen(in_text); - out_text[w++]= '\''; - for(i=0;i5*SfileadrL+ol) - goto overflow; - /* escape hard quote within the text */ - out_text[w++]= '\''; - out_text[w++]= '"'; - out_text[w++]= '\''; - out_text[w++]= '"'; - out_text[w++]= '\''; - } else { - if(w+3>5*SfileadrL) { -overflow:; - strncpy(out_text, "'xorriso: TEXT MUCH TOO LONG ... ",33); - break; - } - out_text[w++]= in_text[i]; - } - } - out_text[w++]= '\''; - out_text[w++]= 0; - return(out_text); -} - - -int Hex_to_bin(char *hex, - int bin_size, int *bin_count, unsigned char *bin_data, int flag) -{ - int i, l, acc; - - l= strlen(hex); - if(l % 2 || l == 0) - return(-1); /* malformed */ - *bin_count= 0; - for(i= 0; i < l; i+= 2) { - if(hex[i] >= '0' && hex[i] <= '9') - acc= (hex[i] - '0') << 4; - else if(hex[i] >= 'A' && hex[i] <= 'F') - acc= (hex[i] - 'A' + 10) << 4; - else if(hex[i] >= 'a' && hex[i] <= 'f') - acc= (hex[i] - 'a' + 10) << 4; - else - return(-1); - if(hex[i + 1] >= '0' && hex[i + 1] <= '9') - acc|= (hex[i + 1] - '0'); - else if(hex[i + 1] >= 'A' && hex[i + 1] <= 'F') - acc|= (hex[i + 1] - 'A' + 10); - else if(hex[i + 1] >= 'a' && hex[i + 1] <= 'f') - acc|= (hex[i + 1] - 'a' + 10); - else - return(-1); - if(*bin_count >= bin_size) - return(0); /* overflow */ - bin_data[*bin_count]= acc; - (*bin_count)++; - } - return(1); -} - - -#ifndef Xorriso_fileliste_externaL - -/* ??? ts A71006 : Is this compatible with mkisofs pathspecs ? - I dimly remember so */ - -int Fileliste__target_source_limit(char *line, char sep, char **limit_pt, - int flag) -{ - char *npt; - - for(npt= line;*npt!=0;npt++) { - if(*npt=='\\') { - if(*(npt+1)!=0) - npt++; - continue; - } - if(*npt=='=') - break; - } - if(*npt==0) - npt= NULL; - (*limit_pt)= npt; - return(npt!=NULL); -} - -#endif /* ! Xorriso_fileliste_externaL */ - - -/* ------------------------------------------------------------------------ */ -/* DirseQ : crawl along a directory's content list */ - -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;ibuffer_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_fillbuffer_size && o->buffer_fill>0) - Sort_argv(o->buffer_fill,o->buffer,0); - } - if(o->buffer_rptbuffer_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;itext= 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); -} - - -/* ------------------------------ LinkiteM -------------------------------- */ - -struct LinkiteM { - char *link_path; - dev_t target_dev; - ino_t target_ino; - int link_count; - struct LinkiteM *next; -}; - -int Linkitem_destroy(struct LinkiteM **o, int flag); - - -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); -} - - -/* ----------------------- Exprtest ----------------------- */ - - -int Exprtest_new( struct ExprtesT **ftest, struct FindjoB *boss, int flag) -{ - struct ExprtesT *f; - - *ftest= f= TSOB_FELD(struct ExprtesT,1); - if(f==NULL) - return(-1); - f->boss= boss; - f->invert= 0; - f->test_type= -1; - f->arg1= NULL; - f->arg2= NULL; - return(1); -} - - -int Exprtest_destroy(struct ExprtesT **ftest, int flag) -{ - struct ExprtesT *f; - - f= *ftest; - if(f==NULL) - return(0); - - if(f->test_type == 1) { - if(f->arg1 != NULL) - free(f->arg1); - if(f->arg2 != NULL) { - regfree(f->arg2); - free(f->arg2); - } - } else if(f->test_type == 9) { - /* arg1 is not an allocated value */; - } else { - if(f->arg1 != NULL) - free(f->arg1); - if(f->arg2 != NULL) - free(f->arg2); - } - free((char *) f); - *ftest= NULL; - return(1); -} - - -/* ----------------------- Nttpfnode ----------------------- */ - - -int Exprnode_new(struct ExprnodE **fnode, struct FindjoB *job, - struct ExprnodE *up, char *origin, int flag) -/* - bit0= set invert-property - bit1= set use_shortcuts -*/ -{ - struct ExprnodE *n; - int ret,i; - - *fnode= n= TSOB_FELD(struct ExprnodE,1); - if(n == NULL) - return(-1); - for(i= 0; i < sizeof(n->origin); i++) - n->origin[i]= 0; - strncpy(n->origin, origin, sizeof(n->origin) - 1); - n->up= up; - n->invert= (flag & 1); - n->assoc= 0; - n->use_shortcuts= !!(flag & 2); - n->left= NULL; - n->left_op= -1; - n->right= NULL; - n->right_op= -1; - n->sub= NULL; - n->is_if_then_else= 0; - n->true_branch= NULL; - n->false_branch= NULL; - n->test= NULL; - n->own_value= -1; - n->composed_value= -1; - - ret= Exprtest_new(&(n->test), job, 0); - if(ret<=0){ - Exprnode_destroy(fnode, 0); - return(-1); - } - return(1); -} - - -int Exprnode_destroy(struct ExprnodE **fnode, int flag) -{ - if(*fnode == NULL) - return(0); - Exprnode_destroy(&((*fnode)->right),0); - Exprnode_destroy(&((*fnode)->sub),0); - Exprnode_destroy(&((*fnode)->true_branch),0); - Exprnode_destroy(&((*fnode)->false_branch),0); - Exprtest_destroy(&((*fnode)->test),0); - free((char *) *fnode); - *fnode= NULL; - return(1); -} - - -int Exprnode_set_is_if(struct ExprnodE *fnode, int value, int flag) -{ - fnode->is_if_then_else= value; - return(1); -} - - -int Exprnode_is_if(struct ExprnodE *fnode, int flag) -{ - return(fnode->is_if_then_else); -} - - -int Exprnode_set_branch(struct ExprnodE *fnode, struct ExprnodE *target, - int flag) -/* - bit0= false_branch (else true_branch) -*/ -{ - struct ExprnodE **branch; - - if(flag&1) - branch= &(fnode->false_branch); - else - branch= &(fnode->true_branch); - Exprnode_destroy(branch,0); - (*branch)= target; - return(1); -} - - -int Exprnode_get_branch(struct ExprnodE *fnode, struct ExprnodE **branch, - int flag) -/* - bit0= false_branch (else true_branch) -*/ -{ - if(flag&1) - (*branch)= fnode->false_branch; - else - (*branch)= fnode->true_branch; - return(1); -} - - -int Exprnode_is_defined(struct ExprnodE *fnode, int flag) -{ - struct ExprtesT *ftest; - - if(fnode==NULL) - return(0); - if(fnode->sub!=NULL) - return(1); - ftest= fnode->test; - if(ftest==NULL) - return(0); - if(ftest->test_type>=0) - return(1); - return(0); -} - - -int Exprnode_own_value(struct XorrisO *xorriso, struct ExprnodE *fnode, - void *node, char *name, char *path, - struct stat *boss_stbuf, struct stat *stbuf, int flag) -/* -flag: -return: (also from Exprtest_match() and Exprnode_tree_value() ) - <0 = error - 0 = does not match - 1 = does match - 2 = immediate decision : does not match - 3 = immediate decision : does match -*/ -{ - int ret; - - if(fnode==NULL) - return(1); - if(fnode->sub!=NULL) { - ret= Exprnode_tree_value(xorriso, fnode->sub, -1, - node, name, path, boss_stbuf, stbuf, 0); - } else { - ret= Exprtest_match(xorriso, fnode->test, node, name, path, - boss_stbuf, stbuf, 0); - } - if(ret<0) - return(ret); - if(ret>1) - return(ret); - if(fnode->invert) - ret= !ret; - return(ret); -} - - -int Exprnode_op(int value1, int value2, int op, int flag) -{ - int ret; - - if(op==0) - ret= value1 || value2 ; - else - ret= value1 && value2 ; - return(ret); -} - - -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) -/* - bit0-7= testmode: 0=head , 1=filename -return: (also from Nntpftest_match() and Nntpfnode_own_value() ) - <0 = error - 0 = does not match - 1 = does match - 2 = immediate decision : does not match - 3 = immediate decision : does match -*/ -{ - int value= 1,ret; - - if(fnode==NULL) - return(1); - if(!Exprnode_is_defined(fnode,0)) - return(1); - - if(fnode->use_shortcuts && fnode->left!=NULL){ - fnode->composed_value= left_value; - if(fnode->left_op==0) {/* OR */ - if(left_value!=0) - goto ex; - } else { /* AND */ - if(left_value==0) - goto ex; - } - } - fnode->composed_value= fnode->own_value= - Exprnode_own_value(xorriso, fnode, node, name, path, boss_stbuf, stbuf, 0); - if(fnode->own_value < 0 || fnode->own_value > 1) - return(fnode->own_value); - - if(fnode->assoc == 0){ /* left associative */ - if(fnode->left != NULL && left_value >= 0) - fnode->composed_value= - Exprnode_op(left_value, fnode->own_value, fnode->left_op, 0); - /* compute right value */ - /* is the right value relevant ? */ - if(fnode->right!=NULL){ - if(fnode->use_shortcuts){ - if(fnode->right_op==0) {/* OR */ - if(fnode->composed_value!=0) - goto ex; - } else { /* AND */ - if(fnode->composed_value==0) - goto ex; - } - } - value= Exprnode_tree_value(xorriso, fnode->right,fnode->composed_value, - node, name, path, boss_stbuf, stbuf, 0); - if(value<0 || value>1) - return(value); - fnode->composed_value= value; - } - }else{ /* right associative */ - if(fnode->right!=NULL){ - /* is the right value relevant ? */ - if(fnode->use_shortcuts){ - if(fnode->right_op==0) {/* OR */ - if(fnode->composed_value!=0) - goto ex; - } else { /* AND */ - if(fnode->composed_value==0) - goto ex; - } - } - value= Exprnode_tree_value(xorriso, fnode->right,fnode->own_value, - node, name, path, boss_stbuf, stbuf, 0); - if(value<0||value>1) - return(value); - } else - value= fnode->own_value; - fnode->composed_value= value; - if(fnode->left!=NULL && left_value>=0) - fnode->composed_value= - Exprnode_op(left_value,fnode->composed_value,fnode->left_op,0); - } -ex: - ret= fnode->composed_value; - if(fnode->is_if_then_else) { - /* The if-condition is evaluated. Now follow the chosen branch */ - struct ExprnodE *branch; - if(ret>0) - branch= fnode->true_branch; - else - branch= fnode->false_branch; - if(branch!=NULL) { - ret= Exprnode_tree_value(xorriso, branch, -1, - node, name, path, boss_stbuf, stbuf, 0); - if(ret<0) - return(ret); - if(ret>1) - return(ret); - } - fnode->composed_value= ret; - } - return(fnode->composed_value); -} - - -/* --------------------- Findjob -------------------- */ - - -int Findjob_new(struct FindjoB **o, char *start_path, int flag) -{ - struct FindjoB *m; - int ret; - - m= *o= TSOB_FELD(struct FindjoB,1); - if(m==NULL) - return(-1); - m->start_path= NULL; - m->test_tree= NULL; - m->cursor= NULL; - m->invert= 0; - m->use_shortcuts= 1; - m->action= 0; /* print */ - m->prune= 0; - m->target= NULL; /* a mere pointer, not managed memory */ - m->text_2= NULL; /* a mere pointer, not managed memory */ - m->user= 0; - m->group= 0; - m->type= 0; - m->date= 0; - m->start_path= strdup(start_path); - if(m->start_path==NULL) - goto failed; - m->found_path= NULL; - m->subjob= NULL; - - ret= Exprnode_new(&(m->test_tree), m, NULL, "-find", (m->use_shortcuts)<<1); - if(ret<=0) - goto failed; - m->cursor= m->test_tree; - return(1); - -failed:; - Findjob_destroy(o, 0); - return(-1); -} - - -int Findjob_destroy(struct FindjoB **o, int flag) -{ - struct FindjoB *m; - - m= *o; - if(m==NULL) - return(0); - if(m->test_tree != NULL) - Exprnode_destroy(&(m->test_tree), 0); - if(m->start_path != NULL) - free(m->start_path); - free((char *) *o); - *o= NULL; - return(1); -} - - -int Findjob_set_start_path(struct FindjoB *o, char *start_path, int flag) -{ - if(o->start_path!=NULL) - free(o->start_path); - if(start_path!=NULL) { - o->start_path= strdup(start_path); - if(o->start_path==NULL) - return(-1); - } else - o->start_path= NULL; - return(1); -} - - -int Findjob_get_start_path(struct FindjoB *o, char **start_path, int flag) -{ - *start_path= o->start_path; - return(1); -} - - -int Findjob_cursor_complete( struct FindjoB *job, int flag) -{ - int ret; - - if(job==NULL) - return(0); - ret= Exprnode_is_defined(job->cursor,0); - return(ret); -} - - -int Findjob_is_restrictive(struct FindjoB *job, int flag) -{ - if(job == NULL) - return(0); - if(job->test_tree == NULL) - return(0); - if(!Exprnode_is_defined(job->test_tree, 0)) - return(0); - return(1); -} - - -int Findjob_new_node(struct FindjoB *job, struct ExprnodE **fnode, - char *origin, int flag) -/* - bit0= open new branch - bit1= with bit1 : do not register as sub-node of job->cursor -*/ -{ - int ret; - struct ExprnodE *f; - - ret= Exprnode_new(fnode,job,NULL,origin, - job->invert|((job->use_shortcuts)<<1)); - if(ret<=0) - return(ret); - f= *fnode; - if(flag&1) { - f->up= job->cursor; - if(job->cursor!=NULL && !(flag&2)) { - if(job->cursor->sub!=NULL) { - /* This would become a memory leak */ - job->errn= -2; - sprintf(job->errmsg, - "Program error while parsing -job : sub branch overwrite"); - return(0); - } else - job->cursor->sub= f; - } - } else { - f->up= job->cursor->up; - f->left= job->cursor; - if(job->cursor!=NULL) - job->cursor->right= f; - } - job->invert= 0; - return(1); -} - - -/* If an operator is expected : use -and - @param flag bit0= prepare for a pseudo-test: - if an operator is expected, do nothing and return 2 -*/ -int Findjob_default_and(struct FindjoB *o, int flag) -{ - int ret; - - if(Findjob_cursor_complete(o, 0)) { - if(flag & 1) - return(2); - ret= Findjob_and(o, 0); - if(ret <= 0) - return(ret); - } - return(1); -} - - -int Findjob_open_bracket(struct FindjoB *job, int flag) -{ - int ret; - struct ExprnodE *fnode; - - ret= Findjob_default_and(job, 0); - if(ret <= 0) - return(ret); - ret= Findjob_new_node(job, &fnode, "-sub", 1); - if(ret <= 0) - return(ret); - job->cursor= fnode; - return(1); -} - - -int Findjob_close_bracket(struct FindjoB *job, int flag) -{ - if(!Findjob_cursor_complete(job, 0)) { - job->errn= -3; - sprintf(job->errmsg, - "Unary operator or expression expected, closing-bracket found"); - return(0); - } - - if(job->cursor->up==NULL){ - job->errn= -1; - sprintf(job->errmsg, - "No bracket open when encountering closing bracket."); - return(0); - } - job->cursor= job->cursor->up; - return(1); -} - - -int Findjob_not(struct FindjoB *job, int flag) -{ - int ret; - - ret= Findjob_default_and(job, 0); - if(ret <= 0) - return(ret); - job->cursor->invert= !job->cursor->invert; - return(1); -} - - -int Findjob_and(struct FindjoB *job, int flag) -{ - int ret; - struct ExprnodE *fnode; - - if(!Findjob_cursor_complete(job, 0)) { - job->errn= -3; - sprintf(job->errmsg, - "Unary operator or expression expected, binary operator found"); - return(0); - } - - ret= Findjob_new_node(job, &fnode, "-and", 0); - if(ret<=0) - return(ret); - job->cursor->right_op= 1; - job->cursor->assoc= 1; /* compute right side first */ - fnode->left_op= 1; - fnode->assoc= 0; /* compute left side first */ - job->cursor= fnode; - return(1); -} - - -int Findjob_or(struct FindjoB *job, int flag) -{ - int ret; - struct ExprnodE *fnode; - - if(!Findjob_cursor_complete(job, 0)) { - job->errn= -3; - sprintf(job->errmsg, - "Unary operator or expression expected, binary operator found"); - return(0); - } - - ret= Findjob_new_node(job, &fnode, "-or", 0); - if(ret<=0) - return(ret); - job->cursor->right= fnode; - job->cursor->right_op= 0; - /* if existing : compute left side first */ - job->cursor->assoc= (job->cursor->left == NULL); - fnode->left= job->cursor; - fnode->left_op= 0; - fnode->assoc= 0; /* no right side yet : compute left side first */ - job->cursor= fnode; - return(1); -} - - -int Findjob_if(struct FindjoB *job, int flag) -{ - int ret; - struct ExprnodE *fnode; - - ret= Findjob_default_and(job, 0); - if(ret <= 0) - return(ret); - ret= Findjob_new_node(job, &fnode, "-if", 1); - if(ret<=0) - return(ret); - Exprnode_set_is_if(fnode,1,0); - job->cursor= fnode; - return(1); -} - - -int Findjob_then(struct FindjoB *job, int flag) -{ - int ret; - struct ExprnodE *fnode,*branch= NULL; - - if(! Findjob_cursor_complete(job,0)) { - job->errn= -3; - sprintf(job->errmsg, - "Unary operator or expression expected, -then-operator found"); - return(0); - } - /* Finding the -if that matches this -then - Do not go up one node but look for the leftmost one. - If everything is right we are at level of the -if node */ - while(job->cursor->left!=NULL) - job->cursor= job->cursor->left; - Exprnode_get_branch(job->cursor, &branch, 0); - if(!Exprnode_is_if(job->cursor, 0) || branch != NULL) { - job->errn= -5; - sprintf(job->errmsg, "-then-operator found outside its proper range."); - return(0); - } - ret= Findjob_new_node(job, &fnode, "-then", 1|2); - if(ret <= 0) - return(ret); - Exprnode_set_branch(job->cursor, fnode, 0); - job->cursor= fnode; - return(1); -} - - -int Findjob_else(struct FindjoB *job, int flag) -{ - int ret; - struct ExprnodE *fnode, *true_branch, *false_branch; - - if(! Findjob_cursor_complete(job, 0)) { - job->errn= -3; - sprintf(job->errmsg, - "Unary operator or expression expected, -else-operator found"); - return(0); - } - if(job->cursor->up == NULL) - goto improper_range; - job->cursor= job->cursor->up; - Exprnode_get_branch(job->cursor, &true_branch, 0); - Exprnode_get_branch(job->cursor, &false_branch, 1); - if(!Exprnode_is_if(job->cursor, 0) || - true_branch == NULL || false_branch != NULL) { -improper_range:; - job->errn= -5; - sprintf(job->errmsg, "-else-operator found outside its proper range."); - return(0); - } - ret= Findjob_new_node(job, &fnode, "-else", 1 | 2); - if(ret <= 0) - return(ret); - Exprnode_set_branch(job->cursor, fnode, 1); - job->cursor= fnode; - return(1); -} - - -int Findjob_elseif(struct FindjoB *job, int flag) -{ - int ret; - struct ExprnodE *true_branch, *false_branch; - - if(!Findjob_cursor_complete(job, 0)) { - job->errn= -3; - sprintf(job->errmsg, - "Unary operator or expression expected, -elseif-operator found"); - return(0); - } - if(job->cursor->up == NULL) - goto improper_range; - job->cursor= job->cursor->up; - Exprnode_get_branch(job->cursor, &true_branch, 0); - Exprnode_get_branch(job->cursor, &false_branch, 1); - if(!Exprnode_is_if(job->cursor, 0) || - true_branch==NULL || false_branch!=NULL) { -improper_range:; - job->errn= -5; - sprintf(job->errmsg, - "-elseif-operator found outside its proper range."); - return(0); - } - job->cursor= job->cursor->up; - /* -elseif is equivalent to the three-step sequence : -endif -or -if - ( -endif has already been performed by following job->cursor->up ) */ - ret= Findjob_or(job, 0); - if(ret <= 0) - return(0); - ret= Findjob_if(job, 0); - if(ret <= 0) - return(0); - return(1); -} - - -int Findjob_endif(struct FindjoB *job, int flag) -{ - struct ExprnodE *true_branch; - - if(!Findjob_cursor_complete(job,0)) { - job->errn= -3; - sprintf(job->errmsg, - "Unary operator or expression expected, -endif found"); - return(0); - } - if(job->cursor->up==NULL) - goto improper_range; - /* test wether parent node is -if */ - job->cursor= job->cursor->up; - Exprnode_get_branch(job->cursor, &true_branch, 0); - if(!Exprnode_is_if(job->cursor,0) || true_branch == NULL) { -improper_range:; - job->errn= -5; - sprintf(job->errmsg, "-endif-mark found outside its proper range."); - return(0); - } - /* go to grand parent node */ - job->cursor= job->cursor->up; - return(1); -} - - -/* @param flag bit0= -wholename rather than -name -*/ -int Findjob_set_name_expr(struct FindjoB *o, char *name_expr, int flag) -{ - char regexpr[2*SfileadrL+2]; - regex_t *name_re; - struct ExprtesT *t; - int ret; - - if(strlen(name_expr)>=SfileadrL) - return(0); - - ret= Findjob_default_and(o, 0); - if(ret <= 0) - return(ret); - t= o->cursor->test; - t->test_type= (flag & 1 ? 13 : 1); - name_re= (regex_t *) calloc(1, sizeof(regex_t)); - if(name_re == NULL) - return(-1); - t->arg1= strdup(name_expr); - if(t->arg1 == NULL) { - free((char *) name_re); - return(-1); - } - Xorriso__bourne_to_reg(name_expr, regexpr, 0); - if(regcomp(name_re, regexpr, 0) != 0) - return(0); - t->arg2= name_re; - return(1); -} - - -int Findjob_set_file_type(struct FindjoB *o, char file_type, int flag) -{ - static char known[]= {"bcdpf-lsmeX"}; - struct ExprtesT *t; - int ret; - - ret= Findjob_default_and(o, 0); - if(ret <= 0) - return(ret); - - if(file_type != 0) - if(strchr(known, file_type) == NULL) - return(0); - t= o->cursor->test; - t->test_type= 2; - t->arg1= calloc(1, 1); - if(t->arg1 == NULL) - return(-1); - *((char *) t->arg1)= file_type; - return(1); -} - - -/* @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) -{ - struct ExprtesT *t; - int ret; - - ret= Findjob_default_and(o, flag & 1); - if(ret <= 0 || ret == 2) - return(ret); - - t= o->cursor->test; - t->test_type= test_type; - if(value < 0) - t->invert= !t->invert; - return(1); -} - - -/* @param value -1= only undamaged files, 1= only damaged files -*/ -int Findjob_set_damage_filter(struct FindjoB *o, int value, int flag) -{ - int ret; - - ret= Findjob_set_prop_filter(o, 3, value, 0); - return(ret); -} - - -int Findjob_set_lba_range(struct FindjoB *o, int start_lba, int count, - int flag) -{ - struct ExprtesT *t; - int ret; - - ret= Findjob_default_and(o, 0); - if(ret <= 0) - return(ret); - - t= o->cursor->test; - t->test_type= 4; - t->arg1= calloc(sizeof(int), 1); - t->arg2= calloc(sizeof(int), 1); - if(t->arg1 == NULL || t->arg2 == NULL) - return(-1); - *((int *) t->arg1)= start_lba; - if(start_lba > 0) - *((int *) t->arg2)= start_lba + count - 1; - else - *((int *) t->arg2)= start_lba - count + 1; - return(1); -} - - -/* @param value -1= files without ACL, 1= only files with ACL -*/ -int Findjob_set_acl_filter(struct FindjoB *o, int value, int flag) -{ - int ret; - - ret= Findjob_set_prop_filter(o, 5, value, 0); - return(ret); -} - - -/* @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) -{ - int ret; - - ret= Findjob_set_prop_filter(o, (flag & 1 ? 14 : 6), value, 0); - return(ret); -} - - -/* @param value -1= files without aaip, 1= only files with aaip -*/ -int Findjob_set_aaip_filter(struct FindjoB *o, int value, int flag) -{ - int ret; - - ret= Findjob_set_prop_filter(o, 7, value, 0); - return(ret); -} - - -/* @param value -1= files without filter, 1= files with filter -*/ -int Findjob_set_filter_filter(struct FindjoB *o, int value, int flag) -{ - int ret; - - ret= Findjob_set_prop_filter(o, 8, value, 0); - return(ret); -} - - -int Findjob_set_wanted_node(struct FindjoB *o, void *wanted_node, int flag) -{ - struct ExprtesT *t; - int ret; - - ret= Findjob_default_and(o, 0); - if(ret <= 0) - return(ret); - - t= o->cursor->test; - t->test_type= 9; - t->arg1= wanted_node; - return(1); -} - - -int Findjob_set_commit_filter_2(struct FindjoB *o, int flag) -{ - int ret; - - ret= Findjob_default_and(o, 0); - if(ret <= 0) - return(ret); - - o->cursor->test->test_type= 10; - return(1); -} - - -int Findjob_set_decision(struct FindjoB *o, char *decision, int flag) -{ - struct ExprtesT *t; - int ret; - - ret= Findjob_default_and(o, 0); - if(ret <= 0) - return(ret); - - t= o->cursor->test; - t->test_type= 11; - t->arg1= strdup(decision); - if(t->arg1 == NULL) - return(-1); - return(1); -} - - -/* @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 ret; - - ret= Findjob_set_prop_filter(o, 0, value, flag & 1); - return(ret); -} - - -int Findjob_set_prune(struct FindjoB *o, int flag) -{ - int ret; - - ret= Findjob_set_prop_filter(o, 12, 0, 0); - return(ret); -} - - -int Findjob_set_found_path(struct FindjoB *o, char *path, int flag) -{ - if(o->found_path != NULL) - free(o->found_path); - if(path != NULL) { - o->found_path= strdup(path); - if(o->found_path == NULL) - return(-1); - } else - o->found_path= NULL; - return(1); -} - - -int Findjob_get_found_path(struct FindjoB *o, char **path, int flag) -{ - *path= o->found_path; - return(1); -} - - -int Findjob_get_action(struct FindjoB *o, int flag) -{ - return(o->action); -} - - -/* @return <0 error, >=0 see above 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) -{ - *target= o->target; - *text_2= o->text_2; - *user= o->user; - *group= o->group; - *mode_and= o->mode_and; - *mode_or= o->mode_or; - *type= o->type; - *date= o->date; - *subjob= o->subjob; - return(o->action); -} - - -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 ret; - - ret= Exprnode_tree_value(xorriso, o->test_tree, -1, - node, name, path, boss_stbuf, stbuf, 0); - if(ret == 3) - ret= 1; - else if(ret == 2) - ret= 0; - return(ret); -} - - -int Findjob_set_action_target(struct FindjoB *o, int action, char *target, - int flag) -{ - o->action= action; - o->target= target; - return(1); -} - - -int Findjob_set_action_type(struct FindjoB *o, int action, int type, - int flag) -{ - o->action= action; - o->type= type; - return(1); -} - - -int Findjob_set_action_text_2(struct FindjoB *o, int action, char *target, - char* text_2, int flag) -{ - o->action= action; - o->target= target; - o->text_2= text_2; - return(1); -} - - -/* @param flag bit0= recursive -*/ -int Findjob_set_action_chown(struct FindjoB *o, uid_t user,int flag) -{ - int ret; - - if(flag&1) { - o->action= 0; - Findjob_destroy(&(o->subjob), 0); - ret= Findjob_new(&(o->subjob), "", 0); - if(ret<=0) - return(-1); - Findjob_set_action_chown(o->subjob, user, 0); - o->action= 9; - } else { - o->action= 4; - o->user= user; - } - return(1); -} - - -/* @param flag bit0= recursive -*/ -int Findjob_set_action_chgrp(struct FindjoB *o, gid_t group, int flag) -{ - int ret; - - if(flag&1) { - o->action= 0; - Findjob_destroy(&(o->subjob), 0); - ret= Findjob_new(&(o->subjob), "", 0); - if(ret<=0) - return(-1); - Findjob_set_action_chgrp(o->subjob, group, 0); - o->action= 10; - } else { - o->action= 5; - o->group= group; - } - return(1); -} - - -/* @param flag bit0= recursive -*/ -int Findjob_set_action_chmod(struct FindjoB *o, - mode_t mode_and, mode_t mode_or, int flag) -{ - int ret; - - if(flag&1) { - o->action= 0; - Findjob_destroy(&(o->subjob), 0); - ret= Findjob_new(&(o->subjob), "", 0); - if(ret<=0) - return(-1); - Findjob_set_action_chmod(o->subjob, mode_and, mode_or, 0); - o->action= 11; - } else { - o->action= 6; - o->mode_and= mode_and; - o->mode_or= mode_or; - } - return(1); -} - - -/* @param flag bit0= recursive -*/ -int Findjob_set_action_ad(struct FindjoB *o, int type, time_t date, int flag) -{ - int ret; - - if(flag&1) { - o->action= 0; - Findjob_destroy(&(o->subjob), 0); - ret= Findjob_new(&(o->subjob), "", 0); - if(ret<=0) - return(-1); - Findjob_set_action_ad(o->subjob, type, date, 0); - o->action= 12; - } else { - o->action= 7; - o->type= type; - o->date= date; - } - return(1); -} - - -int Findjob_set_action_subjob(struct FindjoB *o, int action, - struct FindjoB *subjob, int flag) -{ - o->action= action; - Findjob_destroy(&(o->subjob), 0); - o->subjob= subjob; - return(1); -} - - -int Findjob_set_action_found_path(struct FindjoB *o, int flag) -{ - o->action= 23; - Findjob_set_found_path(o, NULL, 0); - return(1); -} - - -/* ---------------------------- 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 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->partnopartno) - return(-1); - if(p1->offset>p2->offset) - return(1); - if(p1->offsetoffset) - 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 ------------------------- */ - -/* ------------------------------ 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; inot_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; inot_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 ---------------------------- */ - -/* ------------------------------ 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 ----------------------------- */ - -/* ------------------------------ SpotlisT -------------------------------- */ - -struct SpotlistiteM { - int start_lba; - int blocks; - int quality; - struct SpotlistiteM *next; -}; - - -int Spotlistitem_new(struct SpotlistiteM **o, int start_lba, int blocks, - int quality, int flag) -{ - struct SpotlistiteM *m; - - m= TSOB_FELD(struct SpotlistiteM,1); - if(m==NULL) - return(-1); - *o= m; - m->start_lba= start_lba; - m->blocks= blocks; - m->quality= quality; - m->next= NULL; - return(1); -} - - -int Spotlistitem_destroy(struct SpotlistiteM **o, int flag) -{ - if((*o) == NULL) - return(0); - free((char *) *o); - *o= NULL; - return(1); -} - - -struct SpotlisT { - struct SpotlistiteM *list_start; - struct SpotlistiteM *list_end; - int list_count; - struct SpotlistiteM *current_item; - int current_idx; -}; - - -int Spotlist_new(struct SpotlisT **o, int flag) -{ - struct SpotlisT *m; - - m= TSOB_FELD(struct SpotlisT,1); - if(m==NULL) - return(-1); - *o= m; - m->list_start= NULL; - m->list_end= NULL; - m->list_count= 0; - m->current_item= NULL; - m->current_idx= -1; - return(1); -} - - -int Spotlist_destroy(struct SpotlisT **o, int flag) -{ - struct SpotlisT *m; - struct SpotlistiteM *li, *next_li; - - if((*o) == NULL) - return(0); - m= *o; - for(li= m->list_start; li != NULL; li= next_li) { - next_li= li->next; - Spotlistitem_destroy(&li, 0); - } - free((char *) *o); - *o= NULL; - return(1); -} - - -int Spotlist_add_item(struct SpotlisT *o, int start_lba, int blocks, - int quality, int flag) -{ - int ret; - struct SpotlistiteM *li; - static int debug_verbous= 0; - - ret= Spotlistitem_new(&li, start_lba, blocks, quality, 0); - if(ret <= 0) - return(ret); - if(o->list_end != NULL) - o->list_end->next= li; - o->list_end= li; - if(o->list_start == NULL) - o->list_start= li; - (o->list_count)++; - - if(debug_verbous) {char quality_name[80]; - fprintf(stderr, "debug: lba %10d , size %10d , quality '%s'\n", - start_lba, blocks, Spotlist__quality_name(quality, quality_name, - Xorriso_read_quality_invaliD, 0) + 2); - } - - return(1); -} - - -int Spotlist_count(struct SpotlisT *o, int flag) -{ - return o->list_count; -} - - -int Spotlist_block_count(struct SpotlisT *o, int flag) -{ - int list_blocks= 0; - struct SpotlistiteM *li; - - for(li= o->list_start; li != NULL; li= li->next) { - if(li->start_lba + li->blocks > list_blocks) - list_blocks= li->start_lba + li->blocks; - } - return(list_blocks); -} - - -int Spotlist_sector_size(struct SpotlisT *o, int read_chunk, int flag) -{ - int sector_size; - struct SpotlistiteM *li; - - sector_size= read_chunk * 2048; - for(li= o->list_start; li != NULL; li= li->next) { - if((li->start_lba % read_chunk) || (li->blocks % read_chunk)) { - sector_size= 2048; - break; - } - } - return(sector_size); -} - - -int Spotlist_get_item(struct SpotlisT *o, int idx, - int *start_lba, int *blocks, int *quality, int flag) -{ - int i; - struct SpotlistiteM *li; - - if(idx < 0 || idx > o->list_count) - return(0); - if(idx == o->current_idx && o->current_item != NULL) - li= o->current_item; - else if(idx == o->current_idx + 1 && o->current_item != NULL) { - li= o->current_item->next; - } else { - li= o->list_start; - for(i= 0; i < idx; i++) - li= li->next; - } - o->current_item= li; - o->current_idx= idx; - *start_lba= li->start_lba; - *blocks= li->blocks; - *quality= li->quality; - return(1); -} - - -char *Spotlist__quality_name(int quality, char name[80], int bad_limit, - int flag) -{ - if(quality == Xorriso_read_quality_untesteD || - quality == Xorriso_read_quality_tao_enD || - quality == Xorriso_read_quality_off_tracK) - strcpy(name, "0 "); - else if(quality <= bad_limit) - strcpy(name, "- "); - else - strcpy(name, "+ "); - if(quality == Xorriso_read_quality_gooD) - strcat(name, "good"); - else if(quality == Xorriso_read_quality_md5_matcH) - strcat(name, "md5_match"); - else if(quality == Xorriso_read_quality_sloW) - strcat(name, "slow"); - else if(quality == Xorriso_read_quality_partiaL) - strcat(name, "partial"); - else if(quality == Xorriso_read_quality_valiD) - strcat(name, "valid"); - else if(quality == Xorriso_read_quality_untesteD) - strcat(name, "untested"); - else if(quality == Xorriso_read_quality_invaliD) - strcat(name, "invalid"); - else if(quality == Xorriso_read_quality_tao_enD) - strcat(name, "tao_end"); - else if(quality == Xorriso_read_quality_off_tracK) - strcat(name, "off_track"); - else if(quality == Xorriso_read_quality_md5_mismatcH) - strcat(name, "md5_mismatch"); - else if(quality == Xorriso_read_quality_unreadablE) - strcat(name, "unreadable"); - else - sprintf(name, "0 0x%8.8X", (unsigned int) quality); - return(name); -} - - -/* ---------------------------- End SpotlisT ------------------------------ */ - -/* ---------------------------- SectorbitmaP ------------------------------ */ - -struct SectorbitmaP { - int sectors; - int sector_size; - unsigned char *map; - int map_size; -}; - - -int Sectorbitmap_new(struct SectorbitmaP **o, int sectors, int sector_size, - int flag) -{ - struct SectorbitmaP *m; - - m= TSOB_FELD(struct SectorbitmaP,1); - if(m==NULL) - return(-1); - *o= m; - m->sectors= sectors; - m->sector_size= sector_size; - m->map= NULL; - m->map_size= sectors / 8 + 1; - - m->map= calloc(m->map_size, 1); - if(m->map == NULL) - goto failure; - return(1); -failure:; - Sectorbitmap_destroy(o, 0); - return(-1); -} - - -int Sectorbitmap_destroy(struct SectorbitmaP **o, int flag) -{ - if((*o) == NULL) - return(0); - if((*o)->map != NULL) - free((char *) (*o)->map); - free((char *) *o); - *o= NULL; - return(1); -} - - -int Sectorbitmap_from_file(struct SectorbitmaP **o, char *path, char *msg, - int *os_errno, int flag) -{ - int ret, fd= -1, sectors, sector_size, i, todo, map_size, skip; - unsigned char *map; - unsigned char buf[1024]; - - *os_errno= 0; - if(msg != NULL) - msg[0]= 0; - fd= open(path, O_RDONLY); - if(fd == -1) { - *os_errno= errno; - if(msg != NULL) { - strcpy(msg, "Cannot open path "); - Text_shellsafe(path, msg+strlen(msg), 0); - } - return(0); - } - ret= read(fd, buf, 32); - if(ret < 32) { -wrong_filetype:; - if(ret == -1) - *os_errno= errno; - if(msg != NULL) { - strcpy(msg, "Not a sector bitmap file: "); - Text_shellsafe(path, msg+strlen(msg), 0); - } - ret= 0; goto ex; - } - if(strncmp((char *) buf, "xorriso sector bitmap v1 ", 32) == 0) - /* ok */; - else if(strncmp((char *) buf, "xorriso sector bitmap v2 ", 25) == 0) { - skip= -1; - sscanf(((char *) buf) + 25, "%d", &skip); - if(skip < 0) - {ret= 0; goto wrong_filetype;} - for(i= 0; i < skip; i+= sizeof(buf)) { - todo= sizeof(buf); - if(i + todo > skip) - todo= skip - i; - ret= read(fd, buf, todo); - if(ret < todo) - goto wrong_filetype; - } - } else - {ret= 0; goto wrong_filetype;} - ret= read(fd, buf, 8); - if(ret < 4) - goto wrong_filetype; - sectors= (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; - sector_size= (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]; - if(sectors <= 0 || sector_size <= 0) - goto wrong_filetype; - ret= Sectorbitmap_new(o, sectors, sector_size, 0); - if(ret <= 0) { - if(msg != NULL) - sprintf(msg, "Cannot allocate bitmap memory for %d sectors", sectors); - ret= -1; goto ex; - } - map= (*o)->map; - map_size= (*o)->map_size; - for(i= 0; i < map_size; i+= sizeof(buf)) { - todo= sizeof(buf); - if(i + todo > map_size) - todo= map_size - i; - ret= read(fd, buf, todo); - if(ret != todo) - goto wrong_filetype; - memcpy(map + i, buf, todo); - } - ret= 1; -ex:; - if(fd != -1) - close(fd); - if(ret <= 0) - Sectorbitmap_destroy(o, 0); - return(ret); -} - - -int Sectorbitmap_to_file(struct SectorbitmaP *o, char *path, char *info, - char *msg, int *os_errno, int flag) -{ - int ret, fd= -1, j, l; - unsigned char buf[40]; - - *os_errno= 0; - fd= open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); - if(fd == -1) { - *os_errno= errno; - if(msg != NULL) { - strcpy(msg, "Cannot open path "); - Text_shellsafe(path, msg+strlen(msg), 0); - } - return(0); - } - - l= 0; - if(info != NULL) - l= strlen(info); - if(l > 999999) { - strcpy(msg, "Info string is longer than 999999 bytes"); - return(0); - } - sprintf((char *) buf, "xorriso sector bitmap v2 %-6d\n", l); - - ret= write(fd, buf, 32); - if(ret != 32) { -cannot_write:; - *os_errno= errno; - if(msg != NULL) { - strcpy(msg, "Cannot write to "); - Text_shellsafe(path, msg+strlen(msg), 0); - } - ret= 0; goto ex; - } - if(l > 0) { - ret= write(fd, info, l); - if(ret != l) - goto cannot_write; - } - - for(j= 0; j < 4; j++) { - buf[j]= o->sectors >> (24 - j * 8); - buf[j+4]= o->sector_size >> (24 - j * 8); - } - ret= write(fd, buf, 8); - if(ret != 8) - goto cannot_write; - ret= write(fd, o->map, o->map_size); - if(ret != o->map_size) - goto cannot_write; - - ret= 1; -ex:; - if(fd != -1) - close(fd); - return(ret); -} - - -/* @param flag bit0= sector bit value -*/ -int Sectorbitmap_set(struct SectorbitmaP *o, int sector, int flag) -{ - if(sector < 0 || sector >= o->sectors) - return(0); - if(flag & 1) - o->map[sector / 8]|= 1 << (sector % 8); - else - o->map[sector / 8]&= ~(1 << (sector % 8)); - return(1); -} - - -/* @param flag bit0= sector bit value -*/ -int Sectorbitmap_set_range(struct SectorbitmaP *o, - int start_sector, int sectors, int flag) -{ - int start_i, end_i, i; - unsigned char value; - - if(start_sector < 0 || start_sector + sectors > o->sectors || sectors < 1) - return(0); - if(flag & 1) - value= ~0; - else - value= 0; - start_i= start_sector / 8; - end_i= (start_sector + sectors - 1) / 8; - for(i= start_sector; i / 8 == start_i && i < start_sector + sectors; i++) - Sectorbitmap_set(o, i, flag & 1); - for(i= start_i + 1; i < end_i; i++) - o->map[i]= value; - if(end_i > start_i) - for(i= end_i * 8; i < start_sector + sectors; i++) - Sectorbitmap_set(o, i, flag & 1); - return(1); -} - - -int Sectorbitmap_is_set(struct SectorbitmaP *o, int sector, int flag) -{ - if(sector < 0 || sector >= o->sectors) - return(0); - return(!! (o->map[sector / 8] & (1 << (sector % 8)))); -} - - -int Sectorbitmap_bytes_are_set(struct SectorbitmaP *o, - off_t start_byte, off_t end_byte, int flag) -{ - int end_sector, i; - - end_sector= end_byte / o->sector_size; - for(i= start_byte / o->sector_size; i <= end_sector; i++) - if(!Sectorbitmap_is_set(o, i, 0)) - return(0); - return(1); -} - - -int Sectorbitmap_get_layout(struct SectorbitmaP *o, - int *sectors, int *sector_size, int flag) -{ - *sectors= o->sectors; - *sector_size= o->sector_size; - return(1); -} - - -int Sectorbitmap_copy(struct SectorbitmaP *from, struct SectorbitmaP *to, - int flag) -{ - int i, run_start, run_value, start_sec, limit_sec, start_aligned; - int end_complete; - - if(((off_t) from->sectors) * ((off_t) from->sector_size) > - ((off_t) to->sectors) * ((off_t) to->sector_size)) - return(-1); - if(from->sector_size == to->sector_size) { - for(i= 0; i < from->map_size; i++) - to->map[i]= from->map[i]; - return(1); - } - run_start= 0; - run_value= Sectorbitmap_is_set(from, 0, 0); - for(i= 1; i <= from->sectors; i++) { - if(i < from->sectors) - if(Sectorbitmap_is_set(from, i, 0) == run_value) - continue; - start_sec= run_start * from->sector_size / to->sector_size; - start_aligned= - (start_sec * to->sector_size == run_start * from->sector_size); - limit_sec= i * from->sector_size / to->sector_size; - end_complete= (limit_sec * to->sector_size == i * from->sector_size); - if(run_value) { - if(!start_aligned) - start_sec++; - } else { - if(!end_complete) - limit_sec++; - } - if(start_sec < limit_sec) - Sectorbitmap_set_range(to, start_sec, limit_sec - 1 - start_sec, - !!run_value); - run_value= !run_value; - run_start= i; - } - return(1); -} - - -int Sectorbitmap_clone(struct SectorbitmaP *from, struct SectorbitmaP **clone, - int flag) -{ - int ret; - - ret= Sectorbitmap_new(clone, from->sectors, from->sector_size, 0); - if(ret <= 0) - return(ret); - ret= Sectorbitmap_copy(from, *clone, 0); - if(ret <= 0) - Sectorbitmap_destroy(clone, 0); - return(ret); -} - - -/* -------------------------- End SectorbitmaP ---------------------------- */ - -/* ---------------------------- CheckmediajoB ----------------------------- */ - -int Checkmediajob_new(struct CheckmediajoB **o, int flag) -{ - struct CheckmediajoB *m; - - m= TSOB_FELD(struct CheckmediajoB,1); - if(m==NULL) - return(-1); - *o= m; - m->use_dev= 0; - m->min_lba= -1; - m->max_lba= -1; - m->min_block_size= 0; - m->mode= 0; - m->start_time= time(NULL); - m->time_limit= 28800; - m->item_limit= 100000; - strcpy(m->abort_file_path, "/var/opt/xorriso/do_abort_check_media"); - m->data_to_path[0]= 0; - m->data_to_fd= -1; - m->data_to_offset= 0; - m->data_to_limit= -1; - m->patch_lba0= 0; - m->patch_lba0_msc1= -1; - m->sector_map_path[0]= 0; - m->sector_map= NULL; - m->map_with_volid= 0; - m->retry= 0; - m->report_mode= 0; - strcpy(m->event_severity, "ALL"); - m->slow_threshold_seq= 1.0; - m->untested_valid= 0; - return(1); -} - - -int Checkmediajob_destroy(struct CheckmediajoB **o, int flag) -{ - if((*o) == NULL) - return(0); - if((*o)->data_to_fd != -1) - close((*o)->data_to_fd); - Sectorbitmap_destroy(&((*o)->sector_map), 0); - free((char *) *o); - *o= NULL; - return(1); -} - - -int Checkmediajob_copy(struct CheckmediajoB *from, struct CheckmediajoB *to, - int flag) -{ - to->use_dev= from->use_dev; - to->min_lba= from->min_lba; - to->max_lba= from->max_lba; - to->min_block_size= from->min_block_size; - to->mode= from->mode; - to->time_limit= from->time_limit; - to->item_limit= from->item_limit; - strcpy(to->abort_file_path, from->abort_file_path); - strcpy(to->data_to_path, from->data_to_path); - /* not copied: data_to_fd */ - to->data_to_offset= from->data_to_offset; - to->data_to_limit= from->data_to_limit; - to->patch_lba0= from->patch_lba0; - to->patch_lba0_msc1= from->patch_lba0_msc1; - strcpy(to->sector_map_path, from->sector_map_path); - /* not copied: sector_map */ - to->map_with_volid= from->map_with_volid; - to->retry= from->retry; - to->report_mode= from->report_mode; - strcpy(to->event_severity, from->event_severity); - to->slow_threshold_seq= from->slow_threshold_seq; - to->untested_valid= from->untested_valid; - return(1); -} - - -/* -------------------------- End CheckmediajoB --------------------------- */ - -/* ------------------------------- Xorriso -------------------------------- */ - - -/** 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;irc_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;ire_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;ire_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__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); -} - - -int Xorriso_dialog_input(struct XorrisO *xorriso, char line[], int linesize, - int flag) -/* - bit0= do not write to history - bit1= do not read input (but eventually write to history) - bit2= do not write to history line which begin with "-history:" or "-history " -*/ -{ - char *cpt= NULL, **argv= NULL, *linept, *why_append= ""; - int ret, argc= 0, base_length= 0, l, append_line; -#ifdef Xorriso_with_readlinE - static char last_input[SfileadrL]= {""}; -#endif /* ! Xorriso_with_readlinE */ - double tdiff; - struct timeval tv; - struct timezone tz; - - gettimeofday(&tv,&tz); - tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec); - - fflush(stdout); - linept= line; - -get_single:; -#ifdef Xorriso_with_readlinE - - if(xorriso->use_stdin || xorriso->dev_fd_1>=0) { - if(flag&2) - {ret= 1; goto ex;} - if(Sfile_fgets_n(linept,linesize - base_length - 1, stdin, - (xorriso->dialog == 2)) == NULL) { - /* need a very dramatic end */ - kill(getpid(),SIGHUP); - {ret= -1; goto ex;} - } - goto process_single; - } - if(flag&2) { - cpt= NULL; - } else { - cpt= readline(""); - if(cpt==NULL) { - /* need a very dramatic end */ - kill(getpid(),SIGHUP); - {ret= -1; goto ex;} - } - l= strlen(cpt); - if(l >= linesize - base_length - 1) { - strncpy(linept, cpt, linesize - 1); - line[sizeof(line)-1]= 0; - sprintf(xorriso->info_text,"Input line too long !"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - goto new_empty; - } else - strcpy(linept, cpt); - } - -process_single:; - -#else /* Xorriso_with_readlinE */ - - if(flag&2) - {ret= 1; goto ex;} - if(Sfile_fgets_n(linept, linesize - base_length - 1, stdin, - (xorriso->dialog == 2)) == NULL) { - /* need a very dramatic end */ - kill(getpid(),SIGHUP); - {ret= -1; goto ex;} - } - -#endif /* ! Xorriso_with_readlinE */ - - if(xorriso->dialog == 2) { - append_line= 0; - if(linept != line && strcmp(linept, "@@@") == 0) { - sprintf(xorriso->info_text, "Incomplete input line cleared by %s", - linept); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0); -new_empty:; - line[0]= 0; - linept= line; - sprintf(xorriso->info_text, "-------------------------------------\n"); - Xorriso_info(xorriso,0); - sprintf(xorriso->info_text, "Enter new text for empty input line :\n"); - Xorriso_info(xorriso,0); - goto get_single; - } - l= strlen(line); - ret= Sfile_make_argv("", line, &argc, &argv, 16); - if(ret < 0) - goto ex; - if(ret == 0 && !append_line) { - /* append a newline character */ - if(l >= linesize - 1) { - sprintf(xorriso->info_text,"Input line too long !"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - goto new_empty; - } - line[l]= '\n'; - line[l + 1]= 0; - append_line= 1; - why_append= "Quoted newline char"; - } - if(l > 0 && !append_line) - if(line[l - 1] == '\\') { - line[l - 1]= 0; - append_line= 1; - why_append= "Trailing backslash "; - } - if(append_line) { - base_length= strlen(line); - linept= line + base_length; - sprintf(xorriso->info_text, - "---------------------------------------------------------------\n"); - Xorriso_info(xorriso,0); - sprintf(xorriso->info_text, - "%s : Enter rest of line (or @@@ to clear it) :\n", why_append); - Xorriso_info(xorriso,0); - goto get_single; - } - } - -#ifdef Xorriso_with_readlinE - - if(line[0]!=0 && strcmp(last_input,line)!=0 && !(flag&1)) - if(!((flag&4) && - (strncmp(line,"-history:",9)==0 || strncmp(line,"-history ",9)==0))) { - add_history(line); - strncpy(last_input,line,sizeof(last_input)-1); - last_input[sizeof(last_input)-1]= 0; - } - -#endif /* ! Xorriso_with_readlinE */ - - ret= 1; -ex:; - if(cpt!=NULL) - free(cpt); - gettimeofday(&tv,&tz); - xorriso->idle_time+= tv.tv_sec+(1.e-6*(double) tv.tv_usec)-tdiff; - return(ret); -} - - -int Xorriso_request_confirmation(struct XorrisO *xorriso, int flag) -/* - bit0= important operation going on: - demand confirmation of abort, only abort on @@@ - bit1= mark '@' and '@@' by return 4 - bit2= accept: i|n= ignore | do not remove , r|y= retry | remove , q|x= abort - bit3= @@@ = 'done reading' rather than 'abort' - bit4= in non-dialog mode return 6 rather than 1 -*/ -/* return: <=0 error - 1= go on | do not remove existing file - 2= abort - 3= redo request for confirmation - 4= see flag bit1 - (5= skip volume) - 6= retry failed operation | remove existing file - */ -{ - int ret; - char line[SfileadrL],*cpt,previous_line[SfileadrL]; - char *abort_req_text,*abort_really_text; - - if(!xorriso->dialog) { - if(flag&16) - return(6); - return(1); - } - if(flag&8) { - abort_req_text= "request to end"; - abort_really_text= "done reading"; - } else { - abort_req_text= "request to abort"; - abort_really_text= "abort this command"; - } - ret= Xorriso_dialog_input(xorriso,line,sizeof(line),1); - xorriso->result_line_counter= 0; - xorriso->result_page_counter++; - if(ret<=0) - if(xorriso->result_page_length>0) - xorriso->result_page_length= -xorriso->result_page_length; - - cpt= line; - if(strcmp(cpt,"@@@")==0 || - strcmp(cpt,"x")==0 || strcmp(cpt,"X")==0 || - strcmp(cpt,"q")==0 || strcmp(cpt,"Q")==0) { - if(flag&1) { - strcpy(previous_line,cpt); - sprintf(xorriso->info_text, - "... [%s = %s registered. Really %s ? (y/n) ] ...\n", - cpt,abort_req_text,abort_really_text); - Xorriso_info(xorriso,0); - ret= Xorriso_dialog_input(xorriso,line,sizeof(line),1); - if(ret<=0) - return(ret); - cpt= line; - if(strcmp(cpt,previous_line)==0 || - ((*cpt=='Y' || *cpt=='y' || *cpt=='j' || *cpt=='J' || *cpt=='1') && - *(cpt+1)==0)) { - xorriso->request_to_abort= 1; - sprintf(xorriso->info_text, - "------- ( %s confirmed )\n",abort_req_text); - Xorriso_info(xorriso,0); - return(2); - } - sprintf(xorriso->info_text, "....... ( %s revoked )\n",abort_req_text); - Xorriso_info(xorriso,0); - return(3); - } - xorriso->request_to_abort= 1; - sprintf(xorriso->info_text, -"----------- [%s = request to abort registered. Operation ends ] ------------\n", - cpt); - Xorriso_info(xorriso,0); - return(2); - } else if(*cpt=='@') { - if(strcmp(cpt,"@@")==0) { - goto klammer_affe; - - } else if(strcmp(cpt,"@")==0) { -klammer_affe:; - if(xorriso->result_page_length>0) - xorriso->result_page_length= -xorriso->result_page_length; - if(flag&1) { - sprintf(xorriso->info_text, -"... [@ = prompt suppression registered. Prompting disabled temporarily ] ...\n"); - Xorriso_info(xorriso,0); - } - - } else { - Xorriso_dialog_input(xorriso,cpt,strlen(line)+1,2); /* write to history */ - sprintf(xorriso->info_text, - "--- Unrecognized input beginning with @. Please enter someting else.\n"); - Xorriso_info(xorriso,0); - return(3); - } - if(flag&2) - return(4); - if(flag&1) - return(3); - return(1); - } else if(flag&4) { - - if(strcmp(cpt,"i")==0 || strcmp(cpt,"I")==0 || - strcmp(cpt,"n")==0 || strcmp(cpt,"N")==0 || - *cpt==0) { - return(1); - } else if(strcmp(cpt,"r")==0 || strcmp(cpt,"R")==0 || - strcmp(cpt,"y")==0 || strcmp(cpt,"Y")==0) { - return(6); - } else { - /* >>> unknown input */ - sprintf(xorriso->info_text, - "--- Please enter one of : empty line, i,n, r,y, q,x, @, @@@\n"); - Xorriso_info(xorriso,0); - return(3); - } - - } else if(*cpt!=0 && !(flag&1)) { - Xorriso_dialog_input(xorriso,cpt,strlen(line)+1,2); /* write to history */ - strcpy(xorriso->pending_option,cpt); - xorriso->request_to_abort= 1; - sprintf(xorriso->info_text, -"-------------- [ Input of option registered. Operation ends ] ---------------\n"); - Xorriso_info(xorriso,0); - return(2); - - } else if(*cpt!=0) { - Xorriso_dialog_input(xorriso,cpt,strlen(line)+1,2); /* write to history */ - sprintf(xorriso->info_text, - "--- Please enter one of : empty line, @, @@@\n"); - Xorriso_info(xorriso,0); - return(3); - } - return(1); -} - - -/* @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) -{ - char line[5 * SfileadrL + 2], *linept, *fgot; - int l, base_length, append_line, ret, mem_linecount, i; - - Sfile_make_argv("", line, argc, argv, 2); - if(flag & 2) - return(1); - - mem_linecount= *linecount; - linept= line; - base_length= 0; - while(1) { - fgot= Sfile_fgets_n(linept, SfileadrL - base_length + 1, fp, - !!(flag & (1 | 8))); - if(fgot == NULL) { - if(ferror(fp)) - return(0); - if(linept != line) { - sprintf(xorriso->info_text,"Open quotation mark at end of input"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - return(2); - } - l= strlen(line); - (*linecount)++; - append_line= 0; - if(flag & 1) { /* check whether the line is incomplete yet */ - ret= Sfile_make_argv("", line, argc, argv, 16); - if(ret < 0) - return(ret); - if(ret == 0 && !append_line) { - line[l]= '\n'; - line[l + 1]= 0; - append_line= 1; - } - if(l > 0 && !append_line) - if(line[l - 1] == '\\') { - line[l - 1]= 0; - append_line= 1; - } - } - if(l >= SfileadrL) { - sprintf(xorriso->info_text,"Input line too long !"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - if(!append_line) - break; - base_length= strlen(line); - linept= line + base_length; - } - if((flag & 1) && !(flag & 8)) { - ret= Sfile_make_argv("", line, argc, argv, - 1 | ((xorriso->bsl_interpretation & 3) << 5)); - if(ret < 0) - return(ret); - if(flag & 4) - for(i= 0; i < *argc; i++) { - if((*argv)[i][0] == 0) { - sprintf(xorriso->info_text, "Empty text as quoted argument in "); - } else if(strlen((*argv)[i]) >= SfileadrL) { - (*argv)[i][SfileadrL - 1]= 0; - sprintf(xorriso->info_text, - "Input text too long and now truncated in"); - } else - continue; - if(mem_linecount + 1 < *linecount) - sprintf(xorriso->info_text + strlen(xorriso->info_text), - "lines %d to %d", mem_linecount + 1, *linecount); - else - sprintf(xorriso->info_text + strlen(xorriso->info_text), - "line %d", mem_linecount + 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - } - } else { - (*argv)= Smem_malloC(sizeof(char *)); - if(argv == NULL) - return(-1); - (*argv)[0]= strdup(line); - if((*argv)[0] == NULL) - return(-1); - *argc= 1; - } - return(1); -} - - -int Xorriso_predict_linecount(struct XorrisO *xorriso, char *line, - int *linecount, int flag) -{ - int width,l; - char *spt,*ept; - - *linecount= 0; - spt= line; - width= xorriso->result_page_width; - while(1) { - ept= strchr(spt,'\n'); - if(ept==NULL) - l= strlen(spt); - else - l= ept-spt; - l+= xorriso->result_open_line_len; - if(ept!=NULL && l==0) - (*linecount)++; - else { - (*linecount)+= l/width; - if(ept==NULL) { - xorriso->result_open_line_len= l%width; - break; - } - (*linecount)+= !!(l%width); - } - xorriso->result_open_line_len= 0; - spt= ept+1; - } - return(1); -} - - -int Xorriso_pager(struct XorrisO *xorriso, char *line, int flag) -/* - bit1= mark '@' by return 4 -*/ -/* return: <=0 error , 1=go on , 2=abort , 4=see flag bit1*/ -{ - int ret,linecount; - char info_text[10*SfileadrL]; - - if(xorriso->result_page_length<=0 || xorriso->request_not_to_ask || - xorriso->dialog == 0) - return(1); - Xorriso_predict_linecount(xorriso,line,&linecount,0); - if(xorriso->result_line_counter+linecount>xorriso->result_page_length) { -ask_for_page:; - strcpy(info_text,xorriso->info_text); - sprintf(xorriso->info_text,"\n"); - Xorriso_info(xorriso,0); - sprintf(xorriso->info_text, -".... [Press Enter to continue. @,Enter avoids further stops. @@@ aborts] ....\n"); - Xorriso_info(xorriso,0); - ret= Xorriso_request_confirmation(xorriso,flag&2); - strcpy(xorriso->info_text,info_text); - if(ret<=0) - return(ret); - if(ret==2) - return(2); - if(ret==3) - goto ask_for_page; - } - xorriso->result_line_counter+= linecount; - return(1); -} - - -int Xorriso_write_to_channel(struct XorrisO *xorriso, - char *in_text, int channel_no, int flag) -/* - bit0= eventually backslash encode linefeeds - bit1= text is the name of the log file for the given channel - bit2= text is the name of the consolidated packet log file for all channels -bit15= with bit1 or bit2: close depicted log file -*/ -{ - char *rpt, *npt, *text; - int ret= 1, info_redirected= 0, result_redirected= 0; - char prefix[16]; - FILE *logfile_fp, *pktlog_fp; - struct Xorriso_lsT *msglist; - static int num_channels= 4; - static char channel_prefixes[4][4]= {".","R","I","M"}; - - if(channel_no<0 || channel_no>=num_channels) - {ret= -1; goto ex;} - - text= in_text; /* might change due to backslash encoding */ - - /* Logfiles */ - logfile_fp= xorriso->logfile_fp[channel_no]; - pktlog_fp= xorriso->pktlog_fp; - if((flag&2) && logfile_fp!=NULL) { - fprintf(logfile_fp, - "! end ! end ! end ! end ! end ! end ! end ! end xorriso log : %s : %s\n", - channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256)); - fclose(logfile_fp); - xorriso->logfile_fp[channel_no]= logfile_fp= NULL; - } - if((flag&4) && pktlog_fp!=NULL) { - fprintf(pktlog_fp, - "I:1:! end ! end ! end ! end ! end ! end ! end ! end xorriso log : %s : %s\n", - channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256)); - fclose(pktlog_fp); - xorriso->pktlog_fp= pktlog_fp= NULL; - } - if(flag&(1<<15)) - {ret= 1; goto ex;} - if((flag&2)) { - xorriso->logfile_fp[channel_no]= logfile_fp= fopen(text,"a"); - if(logfile_fp==NULL) - {ret= 0; goto ex;} - fprintf(logfile_fp, - "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! xorriso log : %s : %s\n", - channel_prefixes[channel_no],Sfile_datestr(time(0),1|2|256)); - fflush(logfile_fp); - } - if((flag&4)) { - xorriso->pktlog_fp= pktlog_fp= fopen(text,"a"); - if(pktlog_fp==NULL) - {ret= 0; goto ex;} - fprintf(pktlog_fp, - "I:1:!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! xorriso log : . : %s\n", - Sfile_datestr(time(0),1|2|256)); - fflush(pktlog_fp); - } - if(flag&(2|4)) - {ret= 1; goto ex;} - - /* Eventually perform backslash encoding of non-printable characters */ - if(((xorriso->bsl_interpretation & 32) && channel_no == 1) || - ((xorriso->bsl_interpretation & 64) && channel_no == 2)) { - ret= Sfile_bsl_encoder(&text, text, strlen(text), 1 | 2 | 4); - if(ret <= 0) - {ret= -1; goto ex;} - } - - /* Eventually perform messag redirection */ - if(xorriso->msglist_stackfill > 0) { - if(xorriso->msglist_flags[xorriso->msglist_stackfill - 1] & 1) - result_redirected= 1; - if(xorriso->msglist_flags[xorriso->msglist_stackfill - 1] & 2) - info_redirected= 1; - } - if(result_redirected) { - if(channel_no==1 || channel_no==3) { - msglist= xorriso->result_msglists[xorriso->msglist_stackfill - 1]; - ret= Xorriso_lst_append_binary(&msglist, text, strlen(text) + 1, 0); - if(ret <= 0) - {ret= -1; goto ex;} - if(xorriso->result_msglists[xorriso->msglist_stackfill - 1] == NULL) - xorriso->result_msglists[xorriso->msglist_stackfill - 1]= msglist; - } - } - if(info_redirected) { - if(channel_no==2 || channel_no==3) { - msglist= xorriso->info_msglists[xorriso->msglist_stackfill - 1]; - ret= Xorriso_lst_append_binary(&msglist, text, strlen(text) + 1, 0); - if(ret <= 0) - {ret= -1; goto ex;} - if(xorriso->info_msglists[xorriso->msglist_stackfill - 1] == NULL) - xorriso->info_msglists[xorriso->msglist_stackfill - 1]= msglist; - } - } - if((channel_no == 1 && result_redirected) || - (channel_no == 2 && info_redirected) || - (result_redirected && info_redirected)) - {ret= 1; goto ex;} - - /* Non-redirected output */ - if(!xorriso->packet_output) { - if(channel_no==1 || channel_no==3) { - printf("%s",text); - fflush(stdout); - } - if(channel_no==2 || channel_no==3) - fprintf(stderr,"%s",text); - if(logfile_fp!=NULL) { - fprintf(logfile_fp,"%s",text); - fflush(logfile_fp); - } - if(pktlog_fp==NULL) - {ret= 1; goto ex;} - } - rpt= text; - sprintf(prefix,"%s:x: ",channel_prefixes[channel_no]); - while(*rpt!=0) { - npt= strchr(rpt,'\n'); - if(npt==NULL) - prefix[2]= '0'; - else - prefix[2]= '1'; - if(xorriso->packet_output) { - ret= fwrite(prefix,5,1,stdout); - if(ret<=0) - {ret= 0; goto ex;} - } - if(pktlog_fp!=NULL) { - ret= fwrite(prefix,5,1,pktlog_fp); - if(ret<=0) - {ret= 0; goto ex;} - } - if(npt==NULL) { - if(xorriso->packet_output) { - ret= fwrite(rpt,strlen(rpt),1,stdout); - if(ret<=0) - {ret= 0; goto ex;} - ret= fwrite("\n",1,1,stdout); - if(ret<=0) - {ret= 0; goto ex;} - } - if(pktlog_fp!=NULL) { - ret= fwrite(rpt,strlen(rpt),1,pktlog_fp); - if(ret<=0) - {ret= 0; goto ex;} - ret= fwrite("\n",1,1,pktlog_fp); - if(ret<=0) - {ret= 0; goto ex;} - } - break; - } else { - if(xorriso->packet_output) { - ret= fwrite(rpt,npt+1-rpt,1,stdout); - if(ret<=0) - {ret= 0; goto ex;} - } - if(pktlog_fp!=NULL) { - ret= fwrite(rpt,npt+1-rpt,1,pktlog_fp); - if(ret<=0) - {ret= 0; goto ex;} - } - } - rpt= npt+1; - } - if(xorriso->packet_output) - fflush(stdout); - if(pktlog_fp!=NULL) - fflush(pktlog_fp); - ret= 1; -ex: - if(text != in_text && text != NULL) - free(text); - return(ret); -} - - -int Xorriso_push_outlists(struct XorrisO *xorriso, int *stack_handle, - int flag) -{ - if(xorriso->msglist_stackfill + 1 >= Xorriso_max_outlist_stacK) { - Xorriso_msgs_submit(xorriso, 0, - "Overflow of message output redirection stack", 0, "FATAL", 0); - return(-1); - } - if((flag & 3) == 0) - flag|= 3; - xorriso->msglist_stackfill++; - xorriso->result_msglists[xorriso->msglist_stackfill - 1]= NULL; - xorriso->info_msglists[xorriso->msglist_stackfill - 1]= NULL; - xorriso->msglist_flags[xorriso->msglist_stackfill - 1]= flag & 3; - *stack_handle= xorriso->msglist_stackfill - 1; - return(1); -} - - -int Xorriso_pull_outlists(struct XorrisO *xorriso, int stack_handle, - struct Xorriso_lsT **result_list, - struct Xorriso_lsT **info_list, int flag) -{ - int i; - - if(stack_handle < 0 || stack_handle >= xorriso->msglist_stackfill) { - Xorriso_msgs_submit(xorriso, 0, - "Program error: Wrong message output redirection stack handle", - 0, "FATAL", 0); - return(-1); - } - *result_list= xorriso->result_msglists[stack_handle]; - *info_list= xorriso->info_msglists[stack_handle]; - for(i = stack_handle + 1; i < xorriso->msglist_stackfill - 1; i++) { - xorriso->result_msglists[i - 1]= xorriso->result_msglists[i]; - xorriso->info_msglists[i - 1]= xorriso->info_msglists[i]; - } - xorriso->msglist_stackfill--; - return(1); -} - - -int Xorriso_result(struct XorrisO *xorriso, int flag) -/* - bit0= no considerations or computations or dialog. Just put out. -*/ -{ - int ret, redirected= 0; - - if(flag&1) - goto put_it_out; - if(xorriso->request_to_abort) - return(1); - if(xorriso->msglist_stackfill > 0) - if(xorriso->msglist_flags[xorriso->msglist_stackfill - 1] & 1) - redirected= 1; - if(xorriso->result_page_length>0 && !redirected) { - ret= Xorriso_pager(xorriso,xorriso->result_line,2); - if(ret<=0) - return(ret); - if(ret==2) - return(1); - if(xorriso->request_to_abort) - return(1); - } -put_it_out:; - xorriso->bar_is_fresh= 0; - ret= Xorriso_write_to_channel(xorriso, xorriso->result_line, 1,0); - return(ret); -} - - -int Xorriso_info(struct XorrisO *xorriso, int flag) -/* - bit0= use pager (as with result) - bit1= permission to suppress output - bit2= insist in showing output -*/ -{ - int ret; - static int note_sev= 0; - - if(flag&2) - if(xorriso->request_to_abort) - return(1); - - if(note_sev==0) - Xorriso__text_to_sev("NOTE", ¬e_sev, 0); - if(note_sevreport_about_severity && - note_sevabort_on_severity && !(flag&4)) - return(1); - - if(flag&1) { - ret= Xorriso_pager(xorriso,xorriso->info_text,2); - if(ret<=0) - return(ret); - if(ret==2) - return(1); - if(flag&2) - if(xorriso->request_to_abort) - return(1); - } - xorriso->bar_is_fresh= 0; - ret=Xorriso_write_to_channel(xorriso, xorriso->info_text, 2, 0); - return(ret); -} - - -int Xorriso_mark(struct XorrisO *xorriso, int flag) -{ - int ret= 1,r_ret,i_ret; - - if(xorriso->mark_text[0]==0) - return(1); - if(xorriso->packet_output) - ret=Xorriso_write_to_channel(xorriso, xorriso->mark_text, 3, 0); - else { - sprintf(xorriso->result_line,"%s\n",xorriso->mark_text); - r_ret= Xorriso_result(xorriso,1); - strcpy(xorriso->info_text,xorriso->result_line); - i_ret= Xorriso_info(xorriso,0); - if(r_ret==0 || i_ret==0) - ret= 0; - } - return(ret); -} - - -int Xorriso_restxt(struct XorrisO *xorriso, char *text) -{ - int ret; - - strncpy(xorriso->result_line,text,sizeof(xorriso->result_line)-1); - xorriso->result_line[sizeof(xorriso->result_line)-1]= 0; - ret= Xorriso_result(xorriso,0); - return(ret); -} - - -int Xorriso_pacifier_reset(struct XorrisO *xorriso, int flag) -{ - xorriso->start_time= Sfile_microtime(0); - xorriso->last_update_time= xorriso->start_time; - xorriso->pacifier_count= 0; - xorriso->pacifier_total= 0; - xorriso->pacifier_byte_count= 0; - return(1); -} - - -/* 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 - bit1= report count <=0 (no thank you for being patient then) - bit2= report xorriso->pacifier_byte_count - bit6= report with carriage return rather than line feed -*/ -int Xorriso_pacifier_callback(struct XorrisO *xorriso, char *what_done, - off_t count, off_t todo, char *current_object, - int flag) -{ - double current_time, since; - char count_text[80], byte_text[80]; - - current_time= Sfile_microtime(0); - if(current_time - xorriso->last_update_time < xorriso->pacifier_interval - && !(flag&1)) - return(1); - xorriso->last_update_time= Sfile_microtime(0); - since= current_time - xorriso->start_time; - if((flag&1)&&since<1.0) - since= 1.0; - byte_text[0]= 0; - if(flag&4) { - strcat(byte_text, " ("); - Sfile_scale((double) xorriso->pacifier_byte_count, - byte_text+strlen(byte_text), 7, 1e5, 0); - strcat(byte_text, ")"); - } - if(count<=0.0 && !(flag&2)) { - sprintf(xorriso->info_text, - "Thank you for being patient for %.f seconds", since); - } else if(todo<=0.0) { - if(count<10000000) - sprintf(count_text, "%.f", (double) count); - else - Sfile_scale((double) count, count_text, 7, 1e5, 1); - sprintf(xorriso->info_text, "%s %s%s in %.f %s", - count_text, what_done, byte_text, since, (flag&64) ? "s" : "seconds"); - } else { - sprintf(xorriso->info_text, "%.f of %.f %s%s in %.f seconds", - (double) count, (double) todo, what_done, byte_text, since); - } - if(current_object[0]!=0) - sprintf(xorriso->info_text+strlen(xorriso->info_text), - ", now at %s", current_object); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", (flag&64)); - return(1); -} - - -int Xorriso_reset_counters(struct XorrisO *xorriso, int flag) -{ - xorriso->error_count= 0; - xorriso->insert_count= 0; - xorriso->insert_bytes= 0; - Xorriso_pacifier_reset(xorriso, 0); - return(1); -} - - -int Xorriso__bourne_to_reg(char bourne_expr[], char reg_expr[], int flag) -/* reg_expr should be twice as large as bourne_expr ( + 2 to be exact) */ -/* return: 2= bourne_expr is surely a constant */ -{ - char *wpt,*lpt; - int backslash= 0,is_constant= 1,in_square_brackets= 0; - int first_in_square_brackets=0; - - wpt= reg_expr; - lpt= bourne_expr; - - *(wpt++)= '^'; - - while(*lpt!=0){ - if(first_in_square_brackets>0) - first_in_square_brackets--; - if(!backslash){ - switch(*lpt){ - case '?': - *(wpt++)= '.'; - is_constant= 0; - break;case '*': - *(wpt++)= '.'; - *(wpt++)= '*'; - is_constant= 0; - break;case '.': - *(wpt++)= '\\'; - *(wpt++)= '.'; - break;case '+': - *(wpt++)= '\\'; - *(wpt++)= '+'; - break;case '[': - *(wpt++)= *lpt; - first_in_square_brackets= 2; - in_square_brackets= 1; - is_constant= 0; - break;case ']': - *(wpt++)= *lpt; - in_square_brackets= 0; - break;case '!': - if(first_in_square_brackets) - *(wpt++)= '^'; - else if(in_square_brackets) - *(wpt++)= '!'; - else { - *(wpt++)= '\\'; - *(wpt++)= '!'; - } - break;case '^': - if(in_square_brackets) - *(wpt++)= '^'; - else - *(wpt++)= '\\'; - *(wpt++)= '^'; - break;case '$': - *(wpt++)= '\\'; - *(wpt++)= '$'; - break;case '\\': - backslash= 1; - *(wpt++)= '\\'; - is_constant= 0; - break;default: - *(wpt++)= *lpt; - } - } else { - backslash= 0; - *(wpt++)= *lpt; - } - lpt++; - } - *(wpt++)= '$'; - *wpt= 0; - return(1+(is_constant>0)); -} - - -/* @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;ire_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=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 || ire_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;ire_fill;i++) { - *failed_at= i; - npt= strchr(cpt,'/'); - if(npt==NULL) { - if(ire_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 bit0= simple readlink(): no normalization, no multi-hop -*/ -int Xorriso_resolve_link(struct XorrisO *xorriso, - char *link_path, char result_path[SfileadrL], int flag) -{ - ssize_t l; - struct stat stbuf; - int link_count= 0, ret, show_errno= 0; - char buf[SfileadrL], dirbuf[SfileadrL], *lpt, *spt, sfe[5*SfileadrL]; - static int link_limit= 100; - - if(!(flag&1)) - if(stat(link_path, &stbuf)==-1) - if(errno==ELOOP) { - show_errno= errno; - goto too_many_hops; - } - lpt= link_path; - while(1) { - l= readlink(lpt, buf, SfileadrL-1); - if(l==-1) { -handle_error:; - Xorriso_msgs_submit(xorriso, 0, link_path, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, "Cannot obtain link target of : %s", - Text_shellsafe(link_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); -handle_abort:; - if(strcmp(lpt, link_path)!=0) { - sprintf(xorriso->info_text, - "Problem occured with intermediate path : %s", - Text_shellsafe(lpt, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0); - } - return(0); - } - buf[l]= 0; - if(l==0) { - Xorriso_msgs_submit(xorriso, 0, link_path, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, "Empty link target with : %s", - Text_shellsafe(link_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); - goto handle_abort; - } - - if(flag&1) { - strcpy(result_path, buf); - return(1); - } - - /* normalize relative to disk_path */ - if(Sfile_str(dirbuf, lpt, 0)<=0) - return(-1); - while(1) { - spt= strrchr(dirbuf,'/'); - if(spt!=NULL) { - *spt= 0; - if(*(spt+1)!=0) - break; - } else - break; - } - ret= Xorriso_normalize_img_path(xorriso, dirbuf, buf, result_path, 2|4); - if(ret<=0) - return(ret); - - if(lstat(result_path, &stbuf)==-1) { - lpt= result_path; - goto handle_error; - } - if(!S_ISLNK(stbuf.st_mode)) - break; - - lpt= result_path; - link_count++; - if(link_count>link_limit) { -too_many_hops:; - Xorriso_msgs_submit(xorriso, 0, link_path, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, "Too many link hops with : %s", - Text_shellsafe(link_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, show_errno, - "FAILURE",0); - return(0); - } - } - return(1); -} - - -int Xorriso_status_filter(struct XorrisO *xorriso, char *filter, char *line, - int flag) -{ - if(filter!=NULL) - if(filter[0]=='-') - if(strncmp(filter, line, strlen(filter))!=0) - return(0); - return(1); -} - - -int Xorriso_status_result(struct XorrisO *xorriso, char *filter, FILE *fp, - int flag) -/* -bit1= do only report to fp -*/ -{ - int ret; - - ret= Xorriso_status_filter(xorriso, filter, xorriso->result_line, 0); - if(ret <= 0) - return(2); - if(!(flag&2)) - Xorriso_result(xorriso,0); - if(fp!=NULL) { - ret= fwrite(xorriso->result_line,strlen(xorriso->result_line),1,fp); - if(ret<=0) - return(ret); - } - return(1); -} - - -int Xorriso_check_media_setup_job(struct XorrisO *xorriso, - struct CheckmediajoB *job, - char **argv, int old_idx, int end_idx, int flag) -{ - int ret, i, sev; - double num; - struct CheckmediajoB *default_job; - char sev_text[20]; - - if(xorriso->check_media_default != NULL) - Checkmediajob_copy(xorriso->check_media_default, job, 0); - for(i= old_idx; i < end_idx; i++) { - if(strncmp(argv[i], "abort_file=", 11) == 0) { - ret= Sfile_str(job->abort_file_path, argv[i] + 11, 0); - if(ret <= 0) - goto ex; - } else if(strncmp(argv[i], "bad_limit=", 10) == 0) { - if(strcmp(argv[i] + 10, "good") == 0) - xorriso->check_media_bad_limit= Xorriso_read_quality_gooD; - else if(strcmp(argv[i] + 10, "md5_match") == 0) - xorriso->check_media_bad_limit= Xorriso_read_quality_md5_matcH; - else if(strcmp(argv[i] + 10, "slow") == 0) - xorriso->check_media_bad_limit= Xorriso_read_quality_sloW; - else if(strcmp(argv[i] + 10, "partial") == 0) - xorriso->check_media_bad_limit= Xorriso_read_quality_partiaL; - else if(strcmp(argv[i] + 10, "valid") == 0) - xorriso->check_media_bad_limit= Xorriso_read_quality_valiD; - else if(strcmp(argv[i] + 10, "untested") == 0) - xorriso->check_media_bad_limit= Xorriso_read_quality_untesteD; - else if(strcmp(argv[i] + 10, "invalid") == 0) - xorriso->check_media_bad_limit= Xorriso_read_quality_invaliD; - else if(strcmp(argv[i] + 10, "tao_end") == 0) - xorriso->check_media_bad_limit= Xorriso_read_quality_tao_enD; - else if(strcmp(argv[i] + 10, "off_track") == 0) - xorriso->check_media_bad_limit= Xorriso_read_quality_off_tracK; - else if(strcmp(argv[i] + 10, "md5_mismatch") == 0) - xorriso->check_media_bad_limit= Xorriso_read_quality_md5_mismatcH; - else if(strcmp(argv[i] + 10, "unreadable") == 0) - xorriso->check_media_bad_limit= Xorriso_read_quality_unreadablE; - else - goto unknown_value; - } else if(strncmp(argv[i], "data_to=", 8) == 0) { - ret= Sfile_str(job->data_to_path, argv[i] + 8, 0); - if(ret <= 0) - goto ex; - } else if(strncmp(argv[i], "chunk_size=", 11) == 0) { - num= Scanf_io_size(argv[i] + 11, 1); - if(num >= 2048 || num == 0) - job->min_block_size= num / 2048; - else - goto unknown_value; - } else if(strncmp(argv[i], "event=", 6) == 0) { - strncpy(sev_text, argv[i] + 6, 19); - sev_text[19]= 0; - ret= Xorriso__text_to_sev(sev_text, &sev, 0); - if(ret <= 0) { - strcpy(xorriso->info_text, "-check_media event="); - Text_shellsafe(sev_text, xorriso->info_text, 1); - strcat(xorriso->info_text, " : Not a known severity name"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - goto ex; - } - strcpy(job->event_severity, sev_text); - } else if(strncmp(argv[i], "map_with_volid=", 15) == 0) { - if(strcmp(argv[i] + 15, "on") == 0) - job->map_with_volid= 1; - else if(strcmp(argv[i] + 15, "off") == 0) - job->map_with_volid= 0; - else - goto unknown_value; - } else if(strncmp(argv[i], "max_lba=", 8) == 0 || - strncmp(argv[i], "min_lba=", 8) == 0) { - num= -1; - sscanf(argv[i] + 8, "%lf", &num); - if(num > 0x7fffffff || num < 0) - num= -1; - if(strncmp(argv[i], "max_lba=", 8) == 0) - job->max_lba= num; - else - job->min_lba= num; - } else if(strncmp(argv[i], "patch_lba0=", 11) == 0) { - job->patch_lba0_msc1= -1; - if(strcmp(argv[i] + 11, "on") == 0) - job->patch_lba0= 1; - else if(strcmp(argv[i] + 11, "off") == 0) - job->patch_lba0= 0; - else if(strcmp(argv[i] + 11, "force") == 0) - job->patch_lba0= 2; - else if(argv[i][11] >= '1' && argv[i][11] <= '9') { - num= -1; - sscanf(argv[i] + 11, "%lf", &num); - if(num > 0x7fffffff || num < 0) - goto unknown_value; - job->patch_lba0_msc1= num; - job->patch_lba0= (num >= 32) + (strstr(argv[i] + 11, ":force") != NULL); - } else - goto unknown_value; - } else if(strncmp(argv[i], "report=", 7) == 0) { - if(strcmp(argv[i] + 7, "blocks") == 0) - job->report_mode= 0; - else if(strcmp(argv[i] + 7, "files") == 0) - job->report_mode= 1; - else if(strcmp(argv[i] + 7, "blocks_files") == 0) - job->report_mode= 2; - else - goto unknown_value; - } else if(strcmp(argv[i], "reset=now") == 0) { - ret= Checkmediajob_new(&default_job, 0); - if(ret <= 0) { - sprintf(xorriso->info_text, - "-check_media: Cannot reset options due to lack of resources"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - ret= -1; goto ex; - } - Checkmediajob_copy(default_job, job, 0); - Checkmediajob_destroy(&default_job, 0); - xorriso->check_media_bad_limit= Xorriso_read_quality_invaliD; - } else if(strncmp(argv[i], "retry=", 6) == 0) { - if(strcmp(argv[i] + 6, "on") == 0) - job->retry= 1; - else if(strcmp(argv[i] + 6, "off") == 0) - job->retry= -1; - else if(strcmp(argv[i] + 6, "default") == 0) - job->retry= 0; - else - goto unknown_value; - } else if(strncmp(argv[i], "sector_map=", 11) == 0) { - ret= Sfile_str(job->sector_map_path, argv[i] + 11, 0); - if(ret <= 0) - goto ex; - } else if(strncmp(argv[i], "slow_limit=", 11) == 0) { - sscanf(argv[i] + 11, "%lf", &(job->slow_threshold_seq)); - } else if(strncmp(argv[i], "time_limit=", 11) == 0 || - strncmp(argv[i], "item_limit=", 11) == 0 ) { - num= -1; - sscanf(argv[i] + 11, "%lf", &num); - if(num > 0x7fffffff || num < 0) - num= -1; - if(strncmp(argv[i], "time_limit=", 11) == 0) - job->time_limit= num; - else - job->item_limit= num; - -#ifdef NIX - } else if(strncmp(argv[i], "untested=", 9) == 0) { - if(strcmp(argv[i] + 9, "damaged") == 0) - job->untested_valid= 0; - if(strcmp(argv[i] + 9, "undamaged") == 0 || - strcmp(argv[i] + 9, "ok") == 0) - job->untested_valid= 1; - else - goto unknown_value; -#endif - - } else if(strncmp(argv[i], "use=", 4) == 0) { - if(strcmp(argv[i] + 4, "outdev") == 0) - job->use_dev= 1; - else if(strcmp(argv[i] + 4, "indev") == 0) - job->use_dev= 0; - else if(strcmp(argv[i] + 4, "sector_map") == 0) - job->use_dev= 2; - else - goto unknown_value; - } else if(strncmp(argv[i], "what=", 5) == 0) { - if(strcmp(argv[i]+5, "tracks") == 0) - job->mode= 0; - else if(strcmp(argv[i]+5, "disc")== 0) - job->mode= 1; - else { -unknown_value:; - sprintf(xorriso->info_text, - "-check_media: Unknown value with option %s", argv[i]); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - } else { - sprintf(xorriso->info_text, "-check_media: Unknown option '%s'", argv[i]); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - } - ret= 1; -ex:; - return(ret); -} - - -/* @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 all, ret; - char default_report[161], quality_name[80]; - struct CheckmediajoB *dflt= NULL; - - all= !(flag&1); - report[0]= 0; - ret= Checkmediajob_new(&dflt, 0); - if(ret <= 0) - return(-1); - sprintf(report, "-check_media_defaults"); - if(!all) - strcat(report, " reset=now"); - if(all || job->use_dev != dflt->use_dev) - sprintf(report + strlen(report), " use=%s", - job->use_dev == 1 ? "outdev" : - job->use_dev == 2 ? "sector_map" : "indev"); - if(all || job->mode != dflt->mode) - sprintf(report + strlen(report), " what=%s", - job->mode == 1 ? "disc" : "tracks"); - if(all || job->min_lba != dflt->min_lba) - sprintf(report + strlen(report), " min_lba=%d", job->min_lba); - if(all || job->max_lba != dflt->max_lba) - sprintf(report + strlen(report), " max_lba=%d", job->max_lba); - if(all || job->retry != dflt->retry) - sprintf(report + strlen(report), " retry=%s", - job->retry == 1 ? "on" : job->retry == -1 ? "off" : "default"); - if(all || job->time_limit != dflt->time_limit) - sprintf(report + strlen(report), " time_limit=%d", job->time_limit); - if(all || job->item_limit != dflt->item_limit) - sprintf(report + strlen(report), " item_limit=%d", job->item_limit); - if(all || strcmp(job->abort_file_path, dflt->abort_file_path)) { - strcat(report, " abort_file="); - Text_shellsafe(job->abort_file_path, report + strlen(report), 0); - } - if(strlen(report) > 4 * SfileadrL) - {ret= 0; goto ex;} - if(all || strcmp(job->data_to_path, dflt->data_to_path)) { - strcat(report, " data_to="); - Text_shellsafe(job->data_to_path, report + strlen(report), 0); - } - if(strlen(report) > 4 * SfileadrL) - {ret= 0; goto ex;} - if(all || strcmp(job->sector_map_path, dflt->sector_map_path)) { - strcat(report, " sector_map="); - Text_shellsafe(job->sector_map_path, report + strlen(report), 0); - } - if(all || job->map_with_volid != dflt->map_with_volid) - sprintf(report + strlen(report), " map_with_volid=%s", - job->map_with_volid == 1 ? "on" : "off"); - if(all || job->patch_lba0 != dflt->patch_lba0) { - sprintf(report + strlen(report), " patch_lba0="); - if(job->patch_lba0 == 0) - sprintf(report + strlen(report), "off"); - else if(job->patch_lba0_msc1 >= 0) - sprintf(report + strlen(report), "%d%s", - job->patch_lba0_msc1, job->patch_lba0 == 2 ? ":force" : ""); - else - sprintf(report + strlen(report), "%s", - job->patch_lba0 == 2 ? "force" : "on"); - } - if(all || job->report_mode != dflt->report_mode) - sprintf(report + strlen(report), " report=%s", - job->report_mode == 0 ? "blocks" : - job->report_mode == 1 ? "files" : "blocks_files"); - if(all || job->slow_threshold_seq != dflt->slow_threshold_seq) - sprintf(report + strlen(report), " slow_limit=%f", job->slow_threshold_seq); - if(all || xorriso->check_media_bad_limit != Xorriso_read_quality_invaliD) - sprintf(report + strlen(report), " bad_limit=%s", - Spotlist__quality_name(xorriso->check_media_bad_limit, quality_name, - Xorriso_read_quality_invaliD, 0) + 2); - if(all || job->min_block_size != dflt->min_block_size) - sprintf(report + strlen(report), " chunk_size=%ds", job->min_block_size); - if(all || strcmp(job->event_severity, "ALL") != 0) - sprintf(report + strlen(report), " event=%s", job->event_severity); - if(strlen(report) > 4 * SfileadrL) - {ret= 0; goto ex;} - ret= 1; -ex:; - strcat(report, " "); - strcat(report, xorriso->list_delimiter); - Checkmediajob_destroy(&dflt, 0); - sprintf(default_report, "-check_media_defaults reset=now %s", - xorriso->list_delimiter); - if(ret > 0 && strcmp(report, default_report) == 0) - return(2); - return(ret); -} - - -int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) -/* - bit0= do only report non-default settings - bit1= do only report to fp - bit2= report current -resume status even if bit0 is set, but only if valid - bit3= report readline history - bit4= report -resume options indirectly as - -options_from_file:${resume_state_file}_pos -*/ -{ - int is_default, no_defaults, i, ret, adr_mode, do_single; - int show_indev= 1, show_outdev= 1, show_dev= 0; - int part_table_implicit= 0; - char *line, sfe[5 * SfileadrL + 80], mode[80], *form, *treatment; - char *in_pt, *out_pt, *nl_charset, *local_charset, *mode_pt; - char *dev_filter= NULL; - static char channel_prefixes[4][4]= {".","R","I","M"}; - static char load_names[][20]= {"auto", "session", "track", "lba", "volid"}; - static int max_load_mode= 4; - struct Xorriso_lsT *paths, *leafs, *s; - - no_defaults= flag&1; - line= xorriso->result_line; - - if(xorriso->no_rc) { - sprintf(line,"-no_rc\n"); - Xorriso_status_result(xorriso,filter,fp,flag&2); - } - - is_default= strcmp(xorriso->list_delimiter, "--") == 0; - sprintf(line,"-list_delimiter %s\n", xorriso->list_delimiter); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= 0; - if(xorriso->dialog == 2) - sprintf(line,"-dialog on\n"); - else if(xorriso->dialog == 1) - sprintf(line,"-dialog single_line\n"); - else { - sprintf(line,"-dialog off\n"); - is_default= 1; - } - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->result_page_length==0 && xorriso->result_page_width==80); - sprintf(line,"-page %d %d\n", - (xorriso->result_page_length>=0?xorriso->result_page_length - :-xorriso->result_page_length), - xorriso->result_page_width); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->use_stdin==0); - sprintf(line,"-use_readline %s\n", (xorriso->use_stdin?"off":"on")); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->bsl_interpretation == 0); - strcpy(line, "-backslash_codes "); - if(xorriso->bsl_interpretation == 0) - strcat(line, "off"); - else if(xorriso->bsl_interpretation == (3 | 16 | 32 | 64)) - strcat(line, "on"); - else { - if((xorriso->bsl_interpretation & 3) == 1) - strcat(line, "in_double_quotes"); - else if((xorriso->bsl_interpretation & 3) == 2) - strcat(line, "in_quotes"); - else if((xorriso->bsl_interpretation & 3) == 3) - strcat(line, "with_quoted_input"); - if(xorriso->bsl_interpretation & 16) { - if(strlen(line) > 17) - strcat(line, ":"); - strcat(line, "with_program_arguments"); - } - if((xorriso->bsl_interpretation & (32 | 64)) == (32 | 64)) { - if(strlen(line) > 17) - strcat(line, ":"); - strcat(line, "encode_output"); - } else { - if(xorriso->bsl_interpretation & 32) { - if(strlen(line) > 17) - strcat(line, ":"); - strcat(line, "encode_results"); - } - if(xorriso->bsl_interpretation & 64) { - if(strlen(line) > 17) - strcat(line, ":"); - strcat(line, "encode_infos"); - } - } - } - strcat(line, "\n"); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= !xorriso->packet_output; - sprintf(line,"-pkt_output %s\n",(xorriso->packet_output?"on":"off")); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - for(i=0;i<4;i++) { - is_default= (xorriso->logfile[i]!=0); - sprintf(line,"-logfile %s %s\n", - channel_prefixes[i],Text_shellsafe(xorriso->logfile[i],sfe,0)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - } - - is_default= (xorriso->errfile_log[0]==0); - sprintf(line,"-errfile_log %s\n",Text_shellsafe(xorriso->errfile_log,sfe,0)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - if(xorriso->check_media_default == NULL) { - is_default= 1; - sprintf(line, "-check_media_defaults reset=now %s\n", - xorriso->list_delimiter); - } else { - ret= Xorriso_check_media_list_job(xorriso, xorriso->check_media_default, - line, no_defaults); - is_default= (ret == 2); - strcat(line, "\n"); - } - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->img_read_error_mode==2); - treatment= "best_effort"; - if(xorriso->img_read_error_mode==1) - treatment= "failure"; - else if(xorriso->img_read_error_mode==2) - treatment= "fatal"; - sprintf(line,"-error_behavior image_loading %s\n", treatment); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - is_default= (xorriso->extract_error_mode == 1); - treatment= "keep"; - if(xorriso->extract_error_mode == 0) - treatment= "best_effort"; - else if(xorriso->extract_error_mode == 2) - treatment= "delete"; - sprintf(line,"-error_behavior file_extraction %s\n", treatment); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->mark_text[0]==0); - sprintf(line,"-mark %s\n",Text_shellsafe(xorriso->mark_text,sfe,0)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->temp_mem_limit==16*1024*1024); - if((xorriso->temp_mem_limit/1024/1024)*1024*1024==xorriso->temp_mem_limit) - sprintf(line,"-temp_mem_limit %dm\n", xorriso->temp_mem_limit/1024/1024); - else - sprintf(line,"-temp_mem_limit %dk\n", xorriso->temp_mem_limit/1024); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - - sprintf(line,"-prog %s\n",Text_shellsafe(xorriso->progname,sfe,0)); - Xorriso_status_result(xorriso,filter,fp,flag&2); - - if(xorriso->ban_stdio_write) { - sprintf(line,"-ban_stdio_write\n"); - Xorriso_status_result(xorriso,filter,fp,flag&2); - } - - is_default= (xorriso->allow_restore==0 && xorriso->do_concat_split==1 && - xorriso->do_auto_chmod==0 && xorriso->drives_exclusive == 1); - mode_pt= "off"; - if(xorriso->allow_restore == -1) - mode_pt= "banned"; - else if(xorriso->allow_restore == 1) - mode_pt= "on"; - else if(xorriso->allow_restore == 2) - mode_pt= "device_files"; - if(xorriso->allow_restore == -1) - sprintf(line,"-osirrox %s\n", mode_pt); - else - sprintf(line,"-osirrox %s:%s:%s:%s:%s\n", mode_pt, - xorriso->do_concat_split ? "concat_split_on" : "concat_split_off", - xorriso->do_auto_chmod ? "auto_chmod_on" : "auto_chmod_off", - xorriso->do_restore_sort_lba ? "sort_lba_on" : "sort_lba_off", - xorriso->drives_exclusive ? "o_excl_on" : "o_excl_off" - ); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->mount_opts_flag == 0); - sprintf(line,"-mount_opts %s\n", - xorriso->mount_opts_flag & 1 ? "shared" : "exclusive"); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - Xorriso_boot_image_status(xorriso, filter, fp, flag & 3); - - is_default= (xorriso->system_area_disk_path[0] == 0); - sprintf(line,"-boot_image %s system_area=%s\n", - xorriso->system_area_disk_path[0] && (xorriso->system_area_options & 2) - ? "isolinux" : "any", - Text_shellsafe(xorriso->system_area_disk_path, sfe, 0)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - if(xorriso->system_area_disk_path[0] || !part_table_implicit) { - is_default= ((xorriso->system_area_options & 3) == 0); - sprintf(line,"-boot_image %s partition_table=%s\n", - xorriso->system_area_options & 2 ? "isolinux" : "grub", - xorriso->system_area_options & 3 ? "on" : "off"); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - } - -#ifdef Xorriso_with_isohybriD - if(strcmp(form, "isolinux") == 0) { - static char modes[4][6]= {"off", "auto", "on", "force"}; - is_default= (xorriso->boot_image_isohybrid == 1); - sprintf(line,"-boot_image isolinux isohybrid=%s\n", - modes[xorriso->boot_image_isohybrid & 3]); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - } -#endif /* Xorriso_with_isohybriD */ - - sprintf(line,"-cd %s\n", - (xorriso->wdi[0] ? Text_shellsafe(xorriso->wdi,sfe,0) : "'/'")); - Xorriso_status_result(xorriso,filter,fp,flag&2); - sprintf(line,"-cdx %s\n", - (xorriso->wdx[0] ? Text_shellsafe(xorriso->wdx,sfe,0) : "'/'")); - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->split_size==0); - strcpy(line,"-split_size "); - if(xorriso->split_size % (1024*1024) || xorriso->split_size==0) { - Sfile_off_t_text(line+strlen(line), xorriso->split_size, 0); - } else { - Sfile_off_t_text(line+strlen(line), xorriso->split_size / (1024*1024), 0); - strcat(line, "m"); - } - strcat(line, "\n"); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->add_plainly==0); - sprintf(line,"-add_plainly %s\n", - (xorriso->add_plainly == 1 ? "unknown" : - xorriso->add_plainly == 2 ? "dashed" : - xorriso->add_plainly == 3 ? "any" : "none")); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - ret= Exclusions_get_descrs(xorriso->disk_exclusions, &paths, &leafs, 0); - if(ret>0) { - for(; paths!=NULL; paths= paths->next) { - sprintf(line, "-not_paths %s %s\n", - Text_shellsafe(paths->text, sfe, 0), xorriso->list_delimiter); - Xorriso_status_result(xorriso,filter,fp,flag&2); - } - for(; leafs!=NULL; leafs= leafs->next) { - sprintf(line,"-not_leaf %s\n", Text_shellsafe(leafs->text, sfe, 0)); - Xorriso_status_result(xorriso,filter,fp,flag&2); - } - } - - is_default= (xorriso->file_size_limit == - Xorriso_default_file_size_limiT); - if(xorriso->file_size_limit <= 0) - sprintf(line, "-file_size_limit off %s\n", xorriso->list_delimiter); - else - sprintf(line, "-file_size_limit %.f %s\n", - (double) xorriso->file_size_limit, xorriso->list_delimiter); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->disk_excl_mode==1); - sprintf(line, "-not_mgt %s:%s:%s:%s\n", - (xorriso->disk_excl_mode&1 ? "on" : "off"), - (xorriso->disk_excl_mode&2 ? "param_on" : "param_off"), - (xorriso->disk_excl_mode&4 ? "subtree_on" : "subtree_off"), - (xorriso->disk_excl_mode&8 ? "ignore_on" : "ignore_off")); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->do_iso_rr_pattern==1); - sprintf(line,"-iso_rr_pattern %s\n", - (xorriso->do_iso_rr_pattern == 1 ? "on" : - (xorriso->do_iso_rr_pattern == 2 ? "ls" : "off"))); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->do_disk_pattern==2); - sprintf(line,"-disk_pattern %s\n", - (xorriso->do_disk_pattern == 1 ? "on" : - (xorriso->do_disk_pattern == 2 ? "ls" : "off"))); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= xorriso->volid_default; - sprintf(line,"-volid %s\n",Text_shellsafe(xorriso->volid,sfe,0)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - if(is_default && xorriso->loaded_volid[0] && - strcmp(xorriso->loaded_volid, xorriso->volid)!=0 && !no_defaults) { - sprintf(line,"# loaded image effective -volid %s\n", - Text_shellsafe(xorriso->loaded_volid,sfe,0)); - Xorriso_status_result(xorriso,filter,fp,flag&2); - } - - is_default= (xorriso->publisher[0]==0); - sprintf(line,"-publisher %s\n",Text_shellsafe(xorriso->publisher,sfe,0)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->application_id[0]==0); - sprintf(line,"-application_id %s\n", - Text_shellsafe(xorriso->application_id,sfe,0)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->system_id[0]==0); - sprintf(line,"-system_id %s\n", Text_shellsafe(xorriso->system_id,sfe,0)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->volset_id[0]==0); - sprintf(line,"-volset_id %s\n", Text_shellsafe(xorriso->volset_id,sfe,0)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->vol_creation_time == 0); - sprintf(line,"-volume_date c %s\n", - is_default ? "default" : - Ftimetxt(xorriso->vol_creation_time, sfe, 2)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->vol_modification_time == 0); - sprintf(line,"-volume_date m %s\n", - xorriso->vol_uuid[0] ? "overridden" : - is_default ? "default" : - Ftimetxt(xorriso->vol_modification_time, sfe, 2)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->vol_expiration_time == 0); - sprintf(line,"-volume_date x %s\n", - is_default ? "default" : - Ftimetxt(xorriso->vol_expiration_time, sfe, 2)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->vol_effective_time == 0); - sprintf(line,"-volume_date f %s\n", - is_default ? "default" : - Ftimetxt(xorriso->vol_effective_time, sfe, 2)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->vol_uuid[0] == 0); - sprintf(line,"-volume_date uuid %s\n", - Text_shellsafe(xorriso->vol_uuid,sfe,0)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->do_joliet==0); - sprintf(line,"-joliet %s\n", (xorriso->do_joliet == 1 ? "on" : "off")); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - if(xorriso->do_global_uid) { - sprintf(line,"-uid %lu\n", (unsigned long) xorriso->global_uid); - Xorriso_status_result(xorriso,filter,fp,flag&2); - } - - if(xorriso->do_global_gid) { - sprintf(line,"-gid %lu\n", (unsigned long) xorriso->global_gid); - Xorriso_status_result(xorriso,filter,fp,flag&2); - } - - Xorriso_status_extf(xorriso, filter, fp, flag & 2); - Xorriso_status_zisofs(xorriso, filter, fp, flag & 3); - - is_default= !xorriso->allow_graft_points; - sprintf(line,"-pathspecs %s\n", xorriso->allow_graft_points ? "on" : "off"); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->do_follow_pattern && (!xorriso->do_follow_param) - && xorriso->do_follow_mount && (!xorriso->do_follow_links) - && xorriso->follow_link_limit==100); - mode[0]= 0; - if(xorriso->do_follow_pattern && - !(xorriso->do_follow_links && xorriso->do_follow_mount)) - strcat(mode,":pattern"); - if(xorriso->do_follow_param && !(xorriso->do_follow_links)) - strcat(mode,":param"); - if(xorriso->do_follow_links) - strcat(mode,":link"); - if(xorriso->do_follow_mount) - strcat(mode,":mount"); - if(mode[0]==0) - strcpy(mode, ":off"); - sprintf(mode+strlen(mode), ":limit=%d", xorriso->follow_link_limit); - sprintf(line,"-follow %s\n", mode+1); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->do_overwrite==2); - sprintf(line,"-overwrite %s\n",(xorriso->do_overwrite == 1 ? "on" : - (xorriso->do_overwrite == 2 ? "nondir" : "off"))); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= !xorriso->do_reassure; - sprintf(line,"-reassure %s\n",(xorriso->do_reassure == 1 ? "on" : - (xorriso->do_reassure == 2 ? "tree" : "off"))); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= !xorriso->do_close; - sprintf(line,"-close %s\n",(xorriso->do_close ? "on" : "off")); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= !xorriso->do_dummy; - sprintf(line,"-dummy %s\n",(xorriso->do_dummy ? "on" : "off")); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->speed==0); - sprintf(line,"-speed %dkB/s\n", xorriso->speed); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->do_stream_recording==0); - strcpy(mode, "off"); - if(xorriso->do_stream_recording == 1) - strcpy(mode, "full"); - if(xorriso->do_stream_recording == 2) - strcpy(mode, "data"); - else if(xorriso->do_stream_recording == 32) - strcpy(mode, "on"); - else if(xorriso->do_stream_recording >= 16) - sprintf(mode, "%ds", xorriso->do_stream_recording); - sprintf(line,"-stream_recording %s\n", mode); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->dvd_obs == 0); - strcpy(mode, "default"); - if(xorriso->dvd_obs == 32768 || xorriso->dvd_obs == 65536) - sprintf(mode, "%dk", xorriso->dvd_obs / 1024); - sprintf(line,"-dvd_obs %s\n", mode); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->stdio_sync == 0); - strcpy(line, "-stdio_sync "); - if(xorriso->stdio_sync == -1) - strcat(line, "off"); - else if(xorriso->stdio_sync == 0) - strcat(line, "on"); - else if(xorriso->stdio_sync % 512) { - Sfile_off_t_text(line+strlen(line), (off_t) (xorriso->stdio_sync * 2048), - 0); - } else { - Sfile_off_t_text(line+strlen(line), (off_t) (xorriso->stdio_sync / 512), 0); - strcat(line, "m"); - } - strcat(line, "\n"); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->fs==4*512); - if((xorriso->fs/512)*512==xorriso->fs) - sprintf(line,"-fs %dm\n", xorriso->fs/512); - else - sprintf(line,"-fs %dk\n", xorriso->fs*2); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->padding==300*1024); - sprintf(line,"-padding %dk\n", xorriso->padding/1024); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (strcmp(xorriso->report_about_text,"UPDATE")==0); - sprintf(line,"-report_about %s\n",xorriso->report_about_text); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->scsi_log == 0); - sprintf(line,"-scsi_log %s\n", xorriso->scsi_log ? "on" : "off"); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->session_logfile[0]==0); - sprintf(line,"-session_log %s\n", - Text_shellsafe(xorriso->session_logfile,sfe,0)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->pacifier_style==0); - sprintf(line,"-pacifier '%s'\n", - xorriso->pacifier_style==1 ? "mkisofs" : - xorriso->pacifier_style==2 ? "cdrecord" : "xorriso"); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (strcmp(xorriso->return_with_text,"SORRY")==0 && - xorriso->return_with_value==32); - sprintf(line,"-return_with %s %d\n", - xorriso->return_with_text, xorriso->return_with_value); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (strcmp(xorriso->abort_on_text,"FATAL")==0); - sprintf(line,"-abort_on %s\n",xorriso->abort_on_text); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - if(xorriso->status_history_max!=Xorriso_status_history_maX || !no_defaults) { - sprintf(line,"-status_history_max %d\n",xorriso->status_history_max); - Xorriso_status_result(xorriso,filter,fp,flag&2); - } - -#ifdef Xorriso_with_readlinE - - if((flag&8) && xorriso->status_history_max>0) { - HIST_ENTRY **hl; - int hc,i; - - hl= history_list(); - if(hl!=NULL) { - for(hc= 0;hl[hc]!=NULL;hc++); - if(hc>0) - if(strcmp(hl[hc-1]->line,"-end")==0) - hc--; - if(hc>=xorriso->status_history_max) - i= hc-xorriso->status_history_max; - else - i= 0; - for(;iline,sfe,0)); - Xorriso_status_result(xorriso,filter,fp,flag&2); - } - } - } - -#endif /* Xorriso_with_readlinE */ - - is_default= (xorriso->toc_emulation_flag == 0); - sprintf(line,"-rom_toc_scan %s%s\n", - xorriso->toc_emulation_flag & 4 ? "force" : - xorriso->toc_emulation_flag & 1 ? "on" : "off", - xorriso->toc_emulation_flag & 2 ? ":emul_off" : ""); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso, filter, fp, flag & 2); - - adr_mode= xorriso->image_start_mode & 0xffff; - if(adr_mode>=0 && adr_mode<=max_load_mode) { - is_default= (adr_mode==0); - sprintf(line,"-load %s ", load_names[adr_mode]); - if(adr_mode==0) - sprintf(line+strlen(line),"''\n"); - else if(adr_mode>=1 && adr_mode<=3) - sprintf(line+strlen(line),"%s\n", xorriso->image_start_value); - else - sprintf(line+strlen(line),"%s\n", - Text_shellsafe(xorriso->image_start_value, sfe, 0)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - } - - is_default= (xorriso->do_calm_drive & 1); - sprintf(line,"-calm_drive %s\n", xorriso->do_calm_drive & 1 ? "on" : "off"); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->grow_blindly_msc2<0); - sprintf(sfe, "%d", xorriso->grow_blindly_msc2); - sprintf(line,"-grow_blindly %s\n", - xorriso->grow_blindly_msc2 < 0 ? "off" : sfe); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - Xorriso_get_local_charset(xorriso, &local_charset, 0); - nl_charset= nl_langinfo(CODESET); - is_default= (strcmp(local_charset, nl_charset) == 0); - sprintf(line, "-local_charset %s\n", Text_shellsafe(local_charset, sfe, 0)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso, filter, fp, flag & 2); - - is_default= (xorriso->out_charset == NULL && xorriso->in_charset == NULL); - in_pt= ""; - if(xorriso->in_charset != NULL) - in_pt= xorriso->in_charset; - out_pt= ""; - if(xorriso->out_charset != NULL) - out_pt= xorriso->out_charset; - do_single= 0; - ret= Xorriso_status_filter(xorriso, filter, "-in_charset", 0); - if(ret <= 0) - ret= Xorriso_status_filter(xorriso, filter, "-out_charset", 0); - if(ret > 0) - do_single= 1; - if(strcmp(in_pt, out_pt) == 0 && !do_single) { - sprintf(line, "-charset %s\n", Text_shellsafe(in_pt, sfe, 0)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso, filter, fp, flag & 2); - } else { - sprintf(line, "-in_charset %s\n", Text_shellsafe(in_pt, sfe, 0)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso, filter, fp, flag & 2); - sprintf(line, "-out_charset %s\n", Text_shellsafe(out_pt, sfe, 0)); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso, filter, fp, flag & 2); - } - is_default= ((xorriso->do_aaip & (256 | 512)) == 0); - sprintf(line,"-auto_charset %s\n", (xorriso->do_aaip & 256 ? "on" : "off")); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= ((xorriso->ino_behavior & 31) == 7); - switch (xorriso->ino_behavior & 15) { - case 0: form= "on"; - break; case 8: form= "without_update"; - break; default: form= "off"; - } - sprintf(line,"-hardlinks %s:%s\n", form, - xorriso->ino_behavior & 16 ? - "cheap_sorted_extract" : "normal_extract"); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= ((xorriso->do_aaip & (1 | 4)) == 0); - sprintf(line,"-acl %s\n", (xorriso->do_aaip & 1 ? "on" : "off")); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - is_default= ((xorriso->do_aaip & (2 | 8)) == 0); - sprintf(line,"-xattr %s\n", (xorriso->do_aaip & 4 ? "on" : "off")); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - is_default= ((xorriso->do_aaip & (16 | 32 | 64)) == 0); - sprintf(line,"-disk_dev_ino %s\n", - (xorriso->do_aaip & 16 ? (xorriso->do_aaip & 128 ? "ino_only" : "on" ) - : "off")); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= ((xorriso->do_md5 & 31) == 0); - sprintf(line, "-md5 "); - if(xorriso->do_md5 & 1) { - if((xorriso->do_md5 & (8)) == (8)) { - strcat(line, "all\n"); - } else { - strcat(line, "on"); - if(xorriso->do_md5 & 8) - strcat(line, ":stability_check_on"); - strcat(line, "\n"); - } - } else - strcat(line, "off\n"); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->scdbackup_tag_name[0] == 0 && - xorriso->scdbackup_tag_listname[0] == 0); - sprintf(line, "-scdbackup_tag "); - Text_shellsafe(xorriso->scdbackup_tag_listname, line, 1); - strcat(line, " "); - Text_shellsafe(xorriso->scdbackup_tag_name, line, 1); - strcat(line, "\n"); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (Xorriso_get_relax_text(xorriso, sfe, 0) == 2); - sprintf(line,"-compliance %s\n", sfe); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= (xorriso->assert_volid[0] == 0); - sprintf(line, "-assert_volid "); - Text_shellsafe(xorriso->assert_volid, line, 1); - strcat(line, " "); - Text_shellsafe(xorriso->assert_volid_sev, line, 1); - strcat(line, "\n"); - if(!(is_default && no_defaults)) - Xorriso_status_result(xorriso,filter,fp,flag&2); - - is_default= 1; - if(xorriso->drive_blacklist != NULL || xorriso->drive_whitelist != NULL || - xorriso->drive_greylist == NULL) - is_default= 0; - if(xorriso->drive_greylist != NULL) { - if(strcmp(Xorriso_get_pattern(xorriso, xorriso->drive_greylist, 0, 0), - "/dev") != 0) - is_default= 0; - if(Xorriso_get_pattern(xorriso, xorriso->drive_greylist, 1, 0) != NULL) - is_default= 0; - } - if(!(is_default && no_defaults)) { - for(s= xorriso->drive_blacklist; s != NULL; s= Xorriso_lst_get_next(s, 0)) { - sprintf(line, "-drive_class 'banned' %s\n", - Text_shellsafe(Xorriso_lst_get_text(s, 0), sfe, 0)); - Xorriso_status_result(xorriso,filter,fp,flag&2); - } - for(s= xorriso->drive_greylist; s != NULL; s= Xorriso_lst_get_next(s, 0)) { - sprintf(line, "-drive_class 'caution' %s\n", - Text_shellsafe(Xorriso_lst_get_text(s, 0), sfe, 0)); - Xorriso_status_result(xorriso,filter,fp,flag&2); - } - for(s= xorriso->drive_whitelist; s != NULL; s= Xorriso_lst_get_next(s, 0)) { - sprintf(line, "-drive_class 'harmless' %s\n", - Text_shellsafe(Xorriso_lst_get_text(s, 0), sfe, 0)); - Xorriso_status_result(xorriso,filter,fp,flag&2); - } - } - - do_single= 0; - dev_filter= filter; - if(dev_filter != NULL) { - show_dev= Xorriso_status_filter(xorriso, filter, "-dev", 0); - if(show_dev > 0) - dev_filter= NULL; - } - if(dev_filter != NULL) { - show_indev= Xorriso_status_filter(xorriso, filter, "-indev", 0); - show_outdev= Xorriso_status_filter(xorriso, filter, "-outdev", 0); - if(show_outdev > 0 || show_indev > 0) - do_single= 1; - } - if(xorriso->drives_exclusive != xorriso->indev_is_exclusive && - xorriso->indev[0]) - do_single= 1; - else if(xorriso->drives_exclusive != xorriso->outdev_is_exclusive && - xorriso->outdev[0]) - do_single= 1; - if(strcmp(xorriso->indev, xorriso->outdev) == 0 && !do_single) { - sprintf(line,"-dev %s\n", Text_shellsafe(xorriso->indev,sfe,0)); - Xorriso_status_result(xorriso, dev_filter, fp, flag & 2); - } else { - if(xorriso->drives_exclusive != xorriso->indev_is_exclusive && - xorriso->indev[0] && show_indev) { - sprintf(line,"-osirrox o_excl_%s\n", - xorriso->indev_is_exclusive ? "on" : "off"); - Xorriso_status_result(xorriso, NULL, fp, flag & 2); - } - sprintf(line,"-indev %s\n", Text_shellsafe(xorriso->indev,sfe,0)); - Xorriso_status_result(xorriso, dev_filter, fp, flag & 2); - if(xorriso->drives_exclusive != xorriso->indev_is_exclusive && - xorriso->indev[0] && show_indev) { - sprintf(line,"-osirrox o_excl_%s\n", - xorriso->drives_exclusive ? "on" : "off"); - Xorriso_status_result(xorriso, NULL, fp, flag & 2); - } - - if(xorriso->drives_exclusive != xorriso->outdev_is_exclusive && - xorriso->outdev[0] && show_outdev) { - sprintf(line,"-osirrox o_excl_%s\n", - xorriso->outdev_is_exclusive ? "on" : "off"); - Xorriso_status_result(xorriso, NULL, fp, flag & 2); - } - sprintf(line,"-outdev %s\n", Text_shellsafe(xorriso->outdev,sfe,0)); - Xorriso_status_result(xorriso, dev_filter, fp, flag & 2); - if(xorriso->drives_exclusive != xorriso->outdev_is_exclusive && - xorriso->outdev[0] && show_outdev) { - sprintf(line,"-osirrox o_excl_%s\n", - xorriso->drives_exclusive ? "on" : "off"); - Xorriso_status_result(xorriso, NULL, fp, flag & 2); - } - } - - return(1); -} - - -/* @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= prepend wd only if name does not begin by '/' - bit1= normalize image path - bit2= prepend wd (automatically done if wd[0]!=0) - bit3= (with bit1) this is an address in the disk world -*/ -int Xorriso_make_abs_adr(struct XorrisO *xorriso, char *wd, char *name, - char adr[], int flag) -{ - char norm_adr[SfileadrL]; - int ret; - - if((wd[0]!=0 || (flag&4)) && !((flag&1) && name[0]=='/')) { - if(strlen(wd)+1>=SfileadrL) - goto much_too_long; - strcpy(adr, wd); - if(name[0]) - if(Sfile_add_to_path(adr, name, 0)<=0) { -much_too_long:; - Xorriso_much_too_long(xorriso, (int) (strlen(adr)+strlen(name)+1), 2); - return(0); - } - } else { - if(strlen(name)+1>=SfileadrL) - goto much_too_long; - strcpy(adr, name); - } - if(flag&2) { - ret= Xorriso_normalize_img_path(xorriso, "", adr, norm_adr, - 1|2|((flag&8)>>1)); - if(ret<=0) - return(ret); - if(norm_adr[0]==0) - strcpy(norm_adr, "/"); - strcpy(adr, norm_adr); - } - return(1); -} - - -/* - @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 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; ipacifier_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; i0 && 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(retfind_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 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; kre_fill; k++) { - if(xorriso->re_constants[k]==NULL) - break; - if(xorriso->re_constants[k][0]==0) - break; - } - if(kre_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_no_malloc_memory(struct XorrisO *xorriso, char **to_free, int flag) -{ - if(to_free!=NULL) - if(*to_free!=NULL) { - /* Eventual memory sacrifice to get on going */ - free(*to_free); - *to_free= NULL; - } - sprintf(xorriso->info_text, "Out of virtual memory"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "ABORT", 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; iwdx); - 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; iwdx); - 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); -} - - -/* @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 i, warned= 0; - - for(i= idx; ilist_delimiter)==0) - break; - if(!((flag&1) || warned)) - warned= Xorriso_warn_of_wildcards(xorriso, argv[i], flag&2); - } - return(i); -} - - -/* Returns a vector of strings which belong to an open ended arg list. - If expansion is enabled, the vector might be allocated, else it is - a pointer into the argv input vector. - Thus the release of that memory is an expert task to be done by this - function only. Use bit8 for that. With bit8 parameter argc MUST be the - same value as with the call which might have allocated memory. - @param xorriso The environment object - @param argc Length of argv - @param argv The vector with arguments, eventual list_delimiter ("--") - and then eventual unrelated words - @param idx Start index in argv of the argument list - @param optc Length of the effective possibly expanded option vector - @param optv The option vector. Maybe a pointer into argv or maybe - an own allocated vector. - @param flag bit0= do not warn of wildcards - bit1= these are disk_paths - bit2= never expand wildcards - bit3= do not expand last argument - bit4= ignore last argument - bit5= demand exactly one match - bit6= with bit5 allow 0 matches if pattern is a constant - bit7= silently tolerate empty argument list - bit8= free the eventually allocated sub_vector -*/ -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 i, do_expand, nump, was_empty= 0, filec= 0, ret; - char **filev= NULL, **patterns= NULL; - off_t mem= 0; - - if(flag&2) - do_expand= xorriso->do_disk_pattern==1 && !(flag&4); - else - do_expand= xorriso->do_iso_rr_pattern==1 && !(flag&4); - if(flag&256) { - if(*optv=argv+argc) - Sfile_destroy_argv(optc, optv, 0); - return(1); - } - if(idx>=argc) { - *end_idx= argc; - *optc= 0; - *optv= NULL; - sprintf(xorriso->info_text, "%s : Not enough arguments given", cmd); - if((flag & 128)) - return(1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - *end_idx= Xorriso_end_idx(xorriso, argc, argv, idx, - ((flag&1) || do_expand) | (flag&2)); - if(*end_idx<0) - return(*end_idx); - if((flag&16) && (*end_idx)>idx) - (*end_idx)--; - *optc= *end_idx - idx; - *optv= argv+idx; - if(*optc<=0 || !do_expand) - return(1); - patterns= calloc(*optc, sizeof(char *)); - if(patterns==NULL) { -no_memory:; - sprintf(xorriso->info_text, - "%s : Cannot allocate enough memory for pattern expansion", cmd); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - {ret= -1; goto ex;} - } - nump= 0; - if(flag&8) { - was_empty= 1; - mem+= strlen(argv[idx + *optc - 1])+1+sizeof(char *); - } - for(i= 0; i<*optc-!!(flag&8); i++) { - if(argv[i + idx][0]==0) { - was_empty++; - mem+= sizeof(char *); /* as upper limit for size of an empty string */ - continue; - } - patterns[nump++]= argv[i + idx]; - } - if(nump<=0) { /* Only empty texts. May the caller get happy with them. */ - free(patterns); - return(1); - } - if(flag&2) - ret= Xorriso_expand_disk_pattern(xorriso, nump, patterns, was_empty, - &filec, &filev, &mem, (flag>>5)&3); - else - ret= Xorriso_expand_pattern(xorriso, nump, patterns, was_empty, - &filec, &filev, &mem, (flag>>5)&3); - if(ret<=0) - {ret= 0; goto ex;} - for(i= 0; iinfo_text, "Pattern expansion yields %d items:", filec); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - l= 0; - xorriso->info_text[0]= 0; - for(i= 0; iinfo_text); - if(l>0 && l+1+strlen(filev[i])>60) { - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - xorriso->info_text[0]= 0; - l= 0; - } - sprintf(xorriso->info_text+l, " %s", filev[i]); - } - l= strlen(xorriso->info_text); - if(l>0) - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); -} -#endif /* Xorriso_verbous_pattern_expansioN */ - - ret= 1; -ex:; - if(ret<=0) { - if(patterns!=NULL) - free((char *) patterns); - Sfile_destroy_argv(&filec, &filev, 0); - } else { - *optc= filec; - *optv= filev; - } - return(ret); -} - - -int Xorriso_get_problem_status(struct XorrisO *xorriso, char severity[80], - int flag) -{ - strcpy(severity, xorriso->problem_status_text); - return(xorriso->problem_status); -} - - -int Xorriso_set_problem_status(struct XorrisO *xorriso, char *severity, - int flag) -{ - char *sev_text= "ALL"; - int sev, ret; - - if(severity[0]) - sev_text= severity; - ret= Xorriso__text_to_sev(sev_text, &sev, 0); - if(ret<=0) - return(0); - xorriso->problem_status= sev; - strcpy(xorriso->problem_status_text, sev_text); - if(sev > xorriso->eternal_problem_status) { - xorriso->eternal_problem_status= sev; - strcpy(xorriso->eternal_problem_status_text, sev_text); - } - return(1); -} - - -/* @param flag bit0-7= purpose - 0= ERRFILE - 1= mark line (only to be put out if enabled) -*/ -int Xorriso_process_errfile(struct XorrisO *xorriso, - int error_code, char msg_text[], int os_errno, - int flag) -{ - char ttx[41]; - int purpose; - - if(strlen(msg_text)>SfileadrL) - return(-1); - - purpose= flag&255; - if(purpose==1 && !(xorriso->errfile_mode&1)) - return(2); - if(xorriso->errfile_fp!=NULL) { - if(purpose==1) - fprintf(xorriso->errfile_fp, "----------------- %s %s\n", - msg_text, Ftimetxt(time(0), ttx, 1)); - else - fprintf(xorriso->errfile_fp, "%s\n", msg_text); - fflush(xorriso->errfile_fp); - return(1); - } - if(xorriso->errfile_log[0]==0) - return(1); - if(strcmp(xorriso->errfile_log, "-")==0 || - strcmp(xorriso->errfile_log, "-R")==0) { - if(purpose==1) - sprintf(xorriso->result_line, "----------------- %s %s\n", - msg_text, Ftimetxt(time(0), ttx, 1)); - else - sprintf(xorriso->result_line, "%s\n", msg_text); - Xorriso_result(xorriso, 1); - return(1); - } - if(strcmp(xorriso->errfile_log, "-I")==0) { - if(purpose==1) - sprintf(xorriso->info_text, "ERRFILE_MARK=%s %s\n", - msg_text, Ftimetxt(time(0), ttx, 1)); - else - sprintf(xorriso->info_text, "ERRFILE=%s", msg_text); - Xorriso_info(xorriso, 0); - return(1); - } - return(2); -} - - -/* Note: It is ok to submit xorriso->info_text as msg_text here. */ -/* flag: - bit0= for Xorriso_info() : use pager (as with result) - bit1= for Xorriso_info() : permission to suppress output - bit2..5= name prefix - 0="xorriso" - 1="libisofs" - 2="libburn" - 3="libisoburn" - else: "" - bit6= append carriage return rather than line feed (if not os_errno) - bit7= perform Xorriso_process_msg_queues() first -*/ -int Xorriso_msgs_submit(struct XorrisO *xorriso, - int error_code, char msg_text[], int os_errno, - char severity[], int flag) -{ - int ret, lt, li, sev, i; - char *sev_text= "FATAL", prefix[80]; - static char pfx_list[20][16]= { - "xorriso : ", "libisofs: ", "libburn : ", "libisoburn: ", - "", "", "", "", "", "", "", "", "", "", "", "" }; - - if(flag&128) - Xorriso_process_msg_queues(xorriso, 0); - - if(strcmp(severity, "ERRFILE")==0) - Xorriso_process_errfile(xorriso, error_code, msg_text, os_errno, 0); - - /* Set problem status */ - ret= Xorriso__text_to_sev(severity, &sev, 0); - if(ret<=0) - Xorriso__text_to_sev(sev_text, &sev, 0); - else - sev_text= severity; - if(xorriso->problem_statusproblem_status= sev; - strcpy(xorriso->problem_status_text, sev_text); - } - if(xorriso->eternal_problem_statuseternal_problem_status= sev; - strcpy(xorriso->eternal_problem_status_text, sev_text); - } - - /* Report problem event */ - if(sevreport_about_severity && sevabort_on_severity) - return(2); - sprintf(prefix,"%s%s : ", pfx_list[(flag>>2)&15], sev_text); - li= strlen(prefix); - lt= strlen(msg_text); - if(lt>sizeof(xorriso->info_text)-li-2) - lt= sizeof(xorriso->info_text)-li-2; - if(msg_text==xorriso->info_text) { - for(i= lt; i>=0; i--) - msg_text[i+li]= msg_text[i]; - for(i=0; iinfo_text, prefix); - strncpy(xorriso->info_text+li, msg_text, lt); - } - if((flag&64) && os_errno<=0) - xorriso->info_text[li+lt]= '\r'; - else - xorriso->info_text[li+lt]= '\n'; - xorriso->info_text[li+lt+1]= 0; - Xorriso_info(xorriso,4|(flag&3)); - if(os_errno>0) { - sprintf(xorriso->info_text, "%ssys : %s\n", - pfx_list[(flag>>2)&15], strerror(os_errno)); - Xorriso_info(xorriso,4|(flag&3)); - } - return(1); -} - - -/* To be used with isoburn_set_msgs_submit() -*/ -int Xorriso_msgs_submit_void(void *xorriso, - int error_code, char msg_text[], int os_errno, - char severity[], int flag) -{ - int ret; - - ret= Xorriso_msgs_submit((struct XorrisO *) xorriso, error_code, msg_text, - os_errno, severity, flag); - return(ret); -} - - -/** - @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) -{ - static int sev= 0; - if(sev==0) - Xorriso__text_to_sev("SORRY", &sev, 0); - - if((flag&2) && xorriso->request_to_abort) - return(-2); - - Xorriso_process_msg_queues(xorriso, 0); - if(ret>0 && xorriso->problem_status <= 0) - return(1); - - if(xorriso->problem_status < xorriso->abort_on_severity && - xorriso->problem_status > 0) { - if(xorriso->problem_status >= sev && !(flag&1)) { - sprintf(xorriso->info_text, - "xorriso : NOTE : Tolerated problem event of severity '%s'\n", - xorriso->problem_status_text); - Xorriso_info(xorriso, 0);/* submit not as problem event */ - } - ret= 2; - } else if(xorriso->problem_status > 0) { - sprintf(xorriso->info_text, - "xorriso : aborting : -abort_on '%s' encountered '%s'\n", - xorriso->abort_on_text, xorriso->problem_status_text); - if(!(flag&1)) - Xorriso_info(xorriso, 0);/* submit not as problem event */ - ret= -1; - } else if(ret>0) - ret= 1; - else - ret= 2; - return(ret); -} - - -int Xorriso_convert_uidstring(struct XorrisO *xorriso, char *uid_string, - uid_t *uid, int flag) -{ - double num; - char text[80]; - struct passwd *pwd; - - sscanf(uid_string, "%lf", &num); - sprintf(text,"%.f",num); - if(strcmp(text,uid_string)==0) { - *uid= num; - return(1); - } - pwd= getpwnam(uid_string); - if(pwd==NULL) { - sprintf(xorriso->info_text, "-uid: Not a known user: '%s'", uid_string); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - *uid= pwd->pw_uid; - return(1); -} - - -int Xorriso_convert_gidstring(struct XorrisO *xorriso, char *gid_string, - gid_t *gid, int flag) -{ - double num; - char text[80]; - struct group *grp; - - sscanf(gid_string, "%lf", &num); - sprintf(text,"%.f",num); - if(strcmp(text,gid_string)==0) { - *gid= num; - return(1); - } - grp= getgrnam(gid_string); - if(grp==NULL) { - sprintf(xorriso->info_text, "-gid: Not a known group: '%s'", gid_string); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - *gid= grp->gr_gid; - return(1); -} - - -int Xorriso_convert_modstring(struct XorrisO *xorriso, char *cmd, char *mode, - mode_t *mode_and, mode_t *mode_or, int flag) -{ - int who_val= 0; - char sfe[5*SfileadrL], *mpt, *vpt, *opt; - unsigned int num= 0; - mode_t mode_val,mask; - - *mode_and= ~0; - *mode_or= 0; - if(mode[0]=='0') { - *mode_and= 0; - sscanf(mode,"%o",&num); - *mode_or= num; - } else if(strchr(mode,'+')!=NULL || strchr(mode,'-')!=NULL - || strchr(mode,'=')!=NULL) { - /* [ugoa][+-][rwxst] */; - for(mpt= mode; mpt!=NULL; mpt= strchr(mpt, ',')) { - if(*mpt==',') - mpt++; - if(strlen(mpt)<2) - goto unrecognizable; - who_val= 0; - for(vpt= mpt; *vpt!='+' && *vpt!='-' && *vpt!='='; vpt++) { - if(*vpt=='u') - who_val|= 4; - else if(*vpt=='g') - who_val|= 2; - else if(*vpt=='o') - who_val|= 1; - else if(*vpt=='a') - who_val|= 7; - else - goto unrecognizable; - } - opt= vpt; - mode_val= 0; - for(vpt= opt+1; *vpt!=0 && *vpt!=','; vpt++) { - if(*vpt=='r') { - if(who_val&4) - mode_val|= S_IRUSR; - if(who_val&2) - mode_val|= S_IRGRP; - if(who_val&1) - mode_val|= S_IROTH; - } else if(*vpt=='w') { - if(who_val&4) - mode_val|= S_IWUSR; - if(who_val&2) - mode_val|= S_IWGRP; - if(who_val&1) - mode_val|= S_IWOTH; - } else if(*vpt=='x') { - if(who_val&4) - mode_val|= S_IXUSR; - if(who_val&2) - mode_val|= S_IXGRP; - if(who_val&1) - mode_val|= S_IXOTH; - } else if(*vpt=='s') { - if(who_val&4) - mode_val|= S_ISUID; - if(who_val&2) - mode_val|= S_ISGID; - } else if(*vpt=='t') { - if(who_val&1) - mode_val|= S_ISVTX; - } else - goto unrecognizable; - } - if(*opt=='+') { - (*mode_or)|= mode_val; - } else if(*opt=='=') { - mask= 0; - if(who_val&1) - mask|= S_IRWXO|S_ISVTX; - if(who_val&2) - mask|= S_IRWXG|S_ISGID; - if(who_val&4) - mask|= S_IRWXU|S_ISUID; - (*mode_and)&= ~(mask); - (*mode_or)= ((*mode_or) & ~mask) | mode_val; - } else if(*opt=='-') { - (*mode_or)&= ~mode_val; - (*mode_and)&= ~mode_val; - } - } - } else { -unrecognizable:; - sprintf(xorriso->info_text, - "%s: Unrecognizable or faulty permission mode %s\n", cmd, - Text_shellsafe(mode, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - return(1); -} - - -/* @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 ret; - - if(strcmp(time_type, "a")==0) - (*t_type)|= 1; - else if(strcmp(time_type, "m")==0) - (*t_type)|= 4; - else if(strcmp(time_type, "b")==0) - (*t_type)|= 5; - else { - sprintf(xorriso->info_text, "%s: Unrecognized type '%s'", cmd, time_type); - if(!(flag & 1)) - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - ret= Decode_timestring(timestring, t, 0); - if(ret<=0) { - sprintf(xorriso->info_text, "%s: Cannot decode timestring '%s'", cmd, - timestring); - if(!(flag & 1)) - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - sprintf(xorriso->info_text, "Understanding timestring '%s' as: %s", - timestring, ctime(t)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - return(1); -} - - -/* @param flag bit0=path is in source filesystem , bit1= unconditionally */ -int Xorriso_much_too_long(struct XorrisO *xorriso, int len, int flag) -{ - if(len>=SfileadrL || (flag&2)) { - sprintf(xorriso->info_text, - "Path given for %s is much too long (%d)", - ((flag&1) ? "local filesystem" : "ISO image"), len); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - return(1); -} - - -int Xorriso_no_findjob(struct XorrisO *xorriso, char *cmd, int flag) -{ - sprintf(xorriso->info_text, "%s: cannot create find job object", cmd); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - return(1); -} - - -/* @param flag bit1= do not report memory usage as DEBUG -*/ -int Xorriso_check_temp_mem_limit(struct XorrisO *xorriso, off_t mem, int flag) -{ - char mem_text[80], limit_text[80]; - - Sfile_scale((double) mem, mem_text,5,1e4,0); - if(!(flag&2)) { - sprintf(xorriso->info_text, - "Temporary memory needed for result sorting : %s", mem_text); - 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, - "Cannot sort. List of matching files exceeds -temp_mem_limit (%s > %s)", - mem_text, limit_text); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - return(0); - } - return(1); -} - - -/* @param flag bit0= for Xorriso_msgs_submit: use pager - bit1= do not issue warnings -*/ -int Xorriso_hop_link(struct XorrisO *xorriso, char *link_path, - struct LinkiteM **link_stack, struct stat *stbuf, int flag) -{ - int ret; - struct LinkiteM *litm; - char sfe[5*SfileadrL]; - - if(*link_stack != NULL) { - if((*link_stack)->link_count>=xorriso->follow_link_limit) { - sprintf(xorriso->info_text, - "Too many symbolic links in single tree branch at : %s", - Text_shellsafe(link_path, sfe, 0)); - if(!(flag&2)) - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,"WARNING",flag&1); - return(0); - } - } - ret= stat(link_path, stbuf); - if(ret==-1) - return(0); - ret= Linkitem_find(*link_stack, stbuf->st_dev, stbuf->st_ino, &litm, 0); - if(ret>0) { - sprintf(xorriso->info_text, - "Detected symbolic link loop around : %s", - Text_shellsafe(link_path, sfe, 0)); - if(!(flag&2)) - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", flag&1); - return(0); - } - ret= Linkitem_new(&litm, link_path, stbuf->st_dev, stbuf->st_ino, - *link_stack, 0); - if(ret<=0) { - sprintf(xorriso->info_text, - "Cannot add new item to link loop prevention stack"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", flag&1); - return(-1); - } - *link_stack= litm; - return(1); -} - - -/* @param flag bit0= do not only sum up sizes but also print subdirs - bit1= this is a recursion - @return <=0 error , 1 ok , 2 could not open directory -*/ -int Xorriso_show_dux_subs(struct XorrisO *xorriso, - char *abs_path, char *rel_path, off_t *size, - off_t boss_mem, - struct LinkiteM *link_stack, - int flag) -{ - int i, ret, no_sort= 0, filec= 0, l, j, fc, no_dive, is_link; - char **filev= NULL, *namept; - off_t sub_size, report_size, mem= 0; - struct DirseQ *dirseq= NULL; - struct stat stbuf; - dev_t dir_dev; - struct LinkiteM *own_link_stack; - char *path= NULL, *show_path= NULL, *name= NULL, *sfe= NULL; - - sfe= malloc(5*SfileadrL); - path= malloc(SfileadrL); - show_path= malloc(SfileadrL); - name= malloc(SfileadrL); - if(path==NULL || show_path==NULL || name==NULL || sfe==NULL) { - Xorriso_no_malloc_memory(xorriso, &sfe, 0); - {ret= -1; goto ex;} - } - own_link_stack= link_stack; - namept= name; - *size= 0; - - if(lstat(abs_path, &stbuf)==-1) - {ret= 2; goto ex;} - dir_dev= stbuf.st_dev; - if(S_ISLNK(stbuf.st_mode)) { - if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&2)))) - {ret= 2; goto ex;} - if(stat(abs_path, &stbuf)==-1) - {ret= 2; goto ex;} - if(dir_dev != stbuf.st_dev && - !(xorriso->do_follow_mount || (xorriso->do_follow_param && !(flag&2)))) - {ret= 2; goto ex;} - } - ret= Dirseq_new(&dirseq, abs_path, 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) { - Linkitem_reset_stack(&own_link_stack, link_stack, 0); - ret= Dirseq_next_adr(dirseq,name,0); - if(ret<0) - goto ex; - if(ret==0) - break; - - sub_size= 0; - strcpy(show_path, rel_path); - if(Sfile_add_to_path(show_path, name, 0)<=0) - goto much_too_long; - - strcpy(path, abs_path); - if(Sfile_add_to_path(path, name, 0)<=0) { -much_too_long:; - Xorriso_much_too_long(xorriso, strlen(path)+strlen(name)+1, 2); - {ret= -1; goto ex;} - } - no_dive= 0; - - ret= lstat(path, &stbuf); - if(ret==-1) - continue; - is_link= S_ISLNK(stbuf.st_mode); - if(is_link && xorriso->do_follow_links) { - ret= Xorriso_hop_link(xorriso, path, &own_link_stack, &stbuf, 1); - if(ret<0) - {ret= -1; goto ex;} - if(ret!=1) - no_dive= 1; - } - if(!S_ISDIR(stbuf.st_mode)) - no_dive= 1; - if(dir_dev != stbuf.st_dev && !xorriso->do_follow_mount) - no_dive= 1; - if(!no_dive) { - filec++; - l= strlen(rel_path)+1; - mem+= l; - if(l % sizeof(char *)) - mem+= sizeof(char *)-(l % sizeof(char *)); - if(flag&1) /* diving and counting is done further below */ - continue; - ret= Xorriso_show_dux_subs(xorriso, path, show_path, &sub_size, boss_mem, - own_link_stack,2); - if(ret<0) - goto ex; - if(ret==0) - continue; - } - -/* - sub_size+= stbuf.st_size+strlen(name)+1; -*/ - sub_size+= stbuf.st_size+2048; - if(sub_size>0) - (*size)+= sub_size; - } - - if(filec<=0 || !(flag&1)) - {ret= 1; goto ex;} - - /* Try to get a sorted list of directory names */ - mem+= (filec+1)*sizeof(char *); - ret= Xorriso_check_temp_mem_limit(xorriso, mem+boss_mem, 2); - if(ret<0) - goto ex; - Dirseq_rewind(dirseq, 0); - if(ret==0) { -no_sort_possible:; - no_sort= 1; - } else { - filev= (char **) calloc(filec+1, sizeof(char *)); - if(filev==NULL) - goto no_sort_possible; - else { - for(i= 0; ido_follow_links) { - ret= stat(path,&stbuf); - if(ret==-1) - continue; - } - if(!S_ISDIR(stbuf.st_mode)) - continue; - if(dir_dev != stbuf.st_dev && !xorriso->do_follow_mount) - continue; - - if(fc>=filec) { /* Number of files changed (or programming error) */ -revoke_sorting:; - for(j=0; j1) - Sort_argv(filec, filev, 0); - } - } - - for(i= 0; (no_sort || irequest_to_abort); i++) { - Linkitem_reset_stack(&own_link_stack, link_stack, 0); - if(no_sort) { - ret= Dirseq_next_adr(dirseq,name,0); - if(ret<0) - goto ex; - if(ret==0) - break; - } else - namept= filev[i]; - - sub_size= 0; - strcpy(show_path, rel_path); - if(Sfile_add_to_path(show_path, namept, 0)<=0) - goto much_too_long; - strcpy(path, abs_path); - if(Sfile_add_to_path(path, namept, 0)<=0) - goto much_too_long; - no_dive= 0; - - ret= lstat(path,&stbuf); - if(ret==-1) - continue; - is_link= S_ISLNK(stbuf.st_mode); - if(is_link && xorriso->do_follow_links) { - ret= Xorriso_hop_link(xorriso, path, &own_link_stack, &stbuf, 1); - if(ret<0) - {ret= -1; goto ex;} - if(ret!=1) - continue; - } - if(!S_ISDIR(stbuf.st_mode)) - continue; - if(dir_dev == stbuf.st_dev || xorriso->do_follow_mount) { - ret= Xorriso_show_dux_subs(xorriso, path, show_path, &sub_size, - boss_mem+mem, own_link_stack, 2|(flag&1)); - if(ret<0) - goto ex; - } - -/* - sub_size+= stbuf.st_size+strlen(namept)+1; -*/ - sub_size+= stbuf.st_size+2048; - if(sub_size>0) - (*size)+= sub_size; - report_size= sub_size/1024; - if(report_size*1024result_line, "%7.f ",(double) (report_size)); - sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n", - Text_shellsafe(show_path, sfe, 0)); - Xorriso_result(xorriso, 0); - } - - ret= 1; -ex:; - if(sfe!=NULL) - free(sfe); - if(path!=NULL) - free(path); - if(show_path!=NULL) - free(show_path); - if(name!=NULL) - free(name); - Linkitem_reset_stack(&own_link_stack, link_stack, 0); - Dirseq_destroy(&dirseq, 0); - if(filev!=NULL) { - for(i=0; iresult_line; - rpt[0]= 0; - st_mode= stbuf->st_mode; - - if(S_ISDIR(st_mode)) - strcat(rpt, "d"); - else if(S_ISREG(st_mode)) - strcat(rpt, "-"); - else if(S_ISLNK(st_mode)) - strcat(rpt, "l"); - else if(S_ISBLK(st_mode)) { - strcat(rpt, "b"); - show_major_minor= 1; - } else if(S_ISCHR(st_mode)) { - strcat(rpt, "c"); - show_major_minor= 1; - } else if(S_ISFIFO(st_mode)) - strcat(rpt, "p"); - else if(S_ISSOCK(st_mode)) - strcat(rpt, "s"); - else if((flag & 1) && (st_mode & S_IFMT) == Xorriso_IFBOOT) - strcat(rpt, "e"); - else - strcat(rpt, "?"); - - Xorriso__mode_to_perms(st_mode, perms, flag & 2); - strcat(rpt, perms); - - sprintf(rpt+strlen(rpt)," %3u ",(unsigned int) stbuf->st_nlink); - - sprintf(rpt+strlen(rpt), "%-8lu ", (unsigned long) stbuf->st_uid); - sprintf(rpt+strlen(rpt), "%-8lu ", (unsigned long) stbuf->st_gid); - if(show_major_minor) { - dev= stbuf->st_rdev; - - /* according to /usr/include/sys/sysmacros.h : gnu_dev_major(),_minor() - >>> but this looks as if it should go to some system dependency - >>> in FreeBSD dev_t is 32 bit - */ - if(sizeof(dev_t) > 4) { - high_shift= 32; - high_mask= ~0xfff; - } - major= (((dev >> 8) & 0xfff) | - ((unsigned int) (dev >> high_shift) & high_mask)) - & 0xffffffff; - minor= (((dev & 0xff) | ((unsigned int) (dev >> 12) & ~0xff))) & 0xffffffff; - - sprintf(mm_text, "%u,%u", (unsigned int) major, (unsigned int) minor); - sprintf(rpt+strlen(rpt), "%8s ", mm_text); - } else - sprintf(rpt+strlen(rpt), "%8.f ", (double) stbuf->st_size); - - Ftimetxt(stbuf->st_mtime, rpt+strlen(rpt), 0); - strcat(rpt, " "); - - return(1); -} - - -struct DirentrY { - char *adr; - struct DirentrY *next; -}; - - -int Xorriso_sorted_dir_x(struct XorrisO *xorriso, char *dir_path, - int *filec, char ***filev, off_t boss_mem, int flag) -{ - int count= 0, ret; - char name[SfileadrL]; - struct DirseQ *dirseq= NULL; - off_t mem; - struct DirentrY *last= NULL, *current= NULL; - - *filec= 0; - *filev= NULL; - mem= boss_mem; - ret= Dirseq_new(&dirseq, dir_path, 1); - if(ret<=0) - goto ex; - while(1) { /* loop over directory content */ - ret= Dirseq_next_adr(dirseq,name,0); - if(ret==0) - break; - if(ret<0) - goto ex; - mem+= strlen(name)+8+sizeof(struct DirentrY)+sizeof(char *); - if(mem>xorriso->temp_mem_limit) - {ret= 0; goto ex;} - - current= (struct DirentrY *) calloc(1, sizeof(struct DirentrY)); - if(current==NULL) - {ret= -1; goto ex;} - current->adr= NULL; - current->next= last; - last= current; - last->adr= strdup(name); - if(last->adr==NULL) - {ret= -1; goto ex;} - count++; - } - *filec= count; - if(count==0) - {ret= 1; goto ex;} - (*filev)= (char **) calloc(count, sizeof(char *)); - if(*filev==NULL) - {ret= -1; goto ex; } - count= 0; - for(current= last; current!=NULL; current= last) { - last= current->next; - (*filev)[count++]= current->adr; - free((char *) current); - } - Sort_argv(*filec, *filev, 0); - ret= 1; -ex:; - for(current= last; current!=NULL; current= last) { - last= current->next; - free(current->adr); - free((char *) current); - } - return(ret); -} - - -/* @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) -{ - int i, ret, was_error= 0, dfilec= 0, pass, passes; - char sfe[5*SfileadrL], sfe2[5*SfileadrL], path[SfileadrL], *acl_text= NULL; - char *rpt, link_target[SfileadrL], **dfilev= NULL; - off_t size; - struct stat stbuf; - - rpt= xorriso->result_line; - - Sort_argv(filec, filev, 0); - - /* Count valid nodes, warn of invalid ones */ - for(i= 0; iinfo_text, "Not found in local filesystem: %s", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 1); - was_error++; - continue; - } - } - - if((flag&8) && !(flag&(2|4))) { - sprintf(xorriso->info_text,"Valid local files found: %d\n",filec-was_error); - Xorriso_info(xorriso,1); - if(filec-was_error<=0) - return(!was_error); - } - - passes= 1+!(flag&(4|8)); - for(pass= 0; passrequest_to_abort); i++) { - ret= Xorriso_make_abs_adr(xorriso, wd, filev[i], path, 1|2|4); - if(ret<=0) - continue; - ret= lstat(path, &stbuf); - if(ret==-1) - continue; - if(S_ISLNK(stbuf.st_mode) && - (xorriso->do_follow_links || xorriso->do_follow_param)) { - ret= stat(path, &stbuf); - if(ret==-1) - ret= lstat(path, &stbuf); - if(ret==-1) - continue; - } - if(S_ISDIR(stbuf.st_mode) && !(flag&(4|8))) { - if(pass==0) - continue; - if(filec>1) { - strcpy(xorriso->result_line, "\n"); - Xorriso_result(xorriso,0); - sprintf(xorriso->result_line, "%s:\n", Text_shellsafe(filev[i], sfe,0)); - Xorriso_result(xorriso,0); - } - ret= Xorriso_sorted_dir_x(xorriso, path, &dfilec, &dfilev, boss_mem, 0); - if(ret<=0) { - - /* >>> DirseQ loop and single item Xorriso_lsx_filev() */; - - } else { - if(flag&1) { - sprintf(xorriso->result_line, "total %d\n", dfilec); - Xorriso_result(xorriso,0); - } - Xorriso_lsx_filev(xorriso, path, - dfilec, dfilev, boss_mem, (flag&1)|2|8); - } - if(dfilec>0) - Sfile_destroy_argv(&dfilec, &dfilev, 0); - continue; - } else - if(pass>0) - continue; - link_target[0]= 0; - rpt[0]= 0; - if((flag&5)==1) { - Xorriso_local_getfacl(xorriso, path, &acl_text, 16); - ret= Xorriso_format_ls_l(xorriso, &stbuf, (acl_text != NULL) << 1); - Xorriso_local_getfacl(xorriso, path, &acl_text, 1 << 15); - if(ret<=0) - continue; - if(S_ISLNK(stbuf.st_mode)) { - ret= Xorriso_resolve_link(xorriso, path, link_target, 1); - if(ret<=0) - link_target[0]= 0; - } - } else if(flag&4) { /* -du or -dus */ - size= stbuf.st_size; - if(S_ISDIR(stbuf.st_mode)) { - ret= Xorriso_show_dux_subs(xorriso, path, filev[i], &size, boss_mem, - NULL, flag&1); - if(ret<0) - return(-1); - if(ret==0) - continue; - } - sprintf(rpt, "%7.f ",(double) (size/1024)); - } - if(link_target[0]) - sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s -> %s\n", - Text_shellsafe(filev[i], sfe, 0), - Text_shellsafe(link_target, sfe2, 0)); - else - sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n", - Text_shellsafe(filev[i], sfe, 0)); - Xorriso_result(xorriso, 0); - } - return(!was_error); -} - - -/* @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) -{ - int ret; - char sfe[5*SfileadrL]; - - while((xorriso->do_reassure==1 || (xorriso->do_reassure==2 && !(flag&4))) - && !xorriso->request_not_to_ask) { - /* ls -ld */ - Xorriso_lsx_filev(xorriso, xorriso->wdx, 1, &path, (off_t) 0, 1|2|8); - if(flag&1) /* du -s */ - Xorriso_lsx_filev(xorriso, xorriso->wdx, 1, &path, (off_t) 0, 2|4); - if(flag&8) - sprintf(xorriso->info_text, - "File exists. Remove ? n= keep old, y= remove, x= abort, @= stop asking\n"); - else - sprintf(xorriso->info_text, - "Remove above file ? n= keep it, y= remove it, x= abort, @= stop asking\n"); - Xorriso_info(xorriso, 4); - ret= Xorriso_request_confirmation(xorriso, 1|2|4|16); - if(ret<=0) - goto ex; - if(xorriso->request_to_abort) { - sprintf(xorriso->info_text, - "Removal operation aborted by user before file: %s", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - ret= 3; goto ex; - } - if(ret==3) - continue; - if(ret==6) /* yes */ - break; - if(ret==4) { /* yes, do not ask again */ - xorriso->request_not_to_ask= 1; - break; - } - if(ret==1) { /* no */ - sprintf(xorriso->info_text, "Kept in existing state: %s", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - ret= 3; goto ex; - } - } - ret= 1; -ex: - return(ret); -} - - -/* - @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 - bit6= permission to call Xorriso_make_accessible() - @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 ret, is_dir= 0, made_accessible= 0; - struct stat victim_stbuf, *victim_node= NULL; - struct DirseQ *dirseq= NULL; - char *sfe= NULL, *sub_path= NULL; - struct PermiteM *perm_stack_mem; - - perm_stack_mem= xorriso->perm_stack; - - /* Avoiding large local memory objects in order to save stack space */ - sfe= malloc(5*SfileadrL); - sub_path= malloc(2*SfileadrL); - if(sfe==NULL || sub_path==NULL) { - Xorriso_no_malloc_memory(xorriso, &sfe, 0); - {ret= -1; goto ex;} - } - - if(Xorriso_much_too_long(xorriso, strlen(path), 0)<=0) - {ret= 0; goto ex;} - - ret= lstat(path, &victim_stbuf); - if(ret==-1) { - if((flag & 64) && errno == EACCES) { - ret= Xorriso_make_accessible(xorriso, path, 0); - if(ret < 0) - goto ex; - made_accessible= 1; - ret= lstat(path, &victim_stbuf); - } - if(ret==-1) { - sprintf(xorriso->info_text, "Cannot lstat(%s)", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - {ret= 0; goto ex;} - } - } - if(strcmp(path, "/")==0) { - sprintf(xorriso->info_text, "May not delete root directory"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - victim_node= &victim_stbuf; - if(S_ISDIR(victim_stbuf.st_mode)) - is_dir= 1; - if(!is_dir) { - if(flag&2) { /* rmdir */ - sprintf(xorriso->info_text, "%s in disk filesystem is not a directory", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - } else { - if(flag&1) { /* rm -r */ - -#ifdef Osirrox_not_yeT - /* >>> */ - - if((xorriso->do_reassure==1 && !xorriso->request_not_to_ask) || - (flag&32)) { - /* Iterate over subordinates and delete them */ - mem= boss_mem; - - ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, - &iter, &node_array, &node_count, &node_idx, - &node, 1|2); - if(ret<=0) { -cannot_create_iter:; - Xorriso_cannot_create_iter(xorriso, ret, 0); - ret= -1; goto ex; - } - pl= strlen(path); - strcpy(sub_path, path); - if(pl==0 || sub_path[pl-1]!='/') { - sub_path[pl++]= '/'; - sub_path[pl]= 0; - } - sub_name= sub_path+pl; - while(1) { - ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, &iter, - &node_array, &node_count, &node_idx, &node, 0); - if(ret<0) - goto ex; - if(ret==0 || xorriso->request_to_abort) - break; - name= (char *) iso_node_get_name(node); - if(Xorriso_much_too_long(xorriso, pl+1+strlen(name), 0)<=0) - {ret= 0; goto rm_r_problem_handler;} - strcpy(sub_name, name); - ret= Xorriso_rmi(xorriso, iter, mem, sub_path, (flag&(1|2|8|16))|4); - if(ret==3 || ret<=0 || xorriso->request_to_abort) { -rm_r_problem_handler:; - not_removed= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret<0) - goto dir_not_removed; - } - } - if(flag&32) - {ret= 2; goto ex;} - - if(not_removed) { -dir_not_removed:; - sprintf(xorriso->info_text, "Directory not removed: %s", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - if(ret>0) - ret= 3; - goto ex; - } - } - -#else /* Osirrox_not_yeT */ - - sprintf(xorriso->info_text, "-rm_rx is not implemented yet"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - -#endif /* !Osirrox_not_yeT */ - - } else { - if(!(flag&2)) { /* not rmdir */ - sprintf(xorriso->info_text, "%s in disk filesystem is a directory", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - ret= Dirseq_new(&dirseq, path, 1); - if(ret>0) { - ret= Dirseq_next_adr(dirseq, sfe, 0); - if(ret>0) { - sprintf(xorriso->info_text, - "Directory not empty on attempt to delete: %s", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - } - } - } - if(xorriso->request_to_abort) - {ret= 3; goto ex;} - ret= Xorriso_reassure_restore(xorriso, path, (flag&(4|8)) | !!is_dir); - if(ret<=0 || ret==3) - goto ex; - if(is_dir) - ret= rmdir(path); - else - ret= unlink(path); - if(ret == -1) { - if((flag & 64) && errno == EACCES && !made_accessible) { - ret= Xorriso_make_accessible(xorriso, path, 0); - if(ret < 0) - goto ex; - made_accessible= 1; - if(is_dir) - ret= rmdir(path); - else - ret= unlink(path); - } - if(ret == -1) { - sprintf(xorriso->info_text, "Cannot delete from disk filesystem %s", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - ret= -1; goto ex; - } - } - if(flag&16) - xorriso->pacifier_count++; - ret= 1+!!is_dir; -ex:; - if(made_accessible) - Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0); - if(sfe!=NULL) - free(sfe); - if(sub_path!=NULL) - free(sub_path); - Dirseq_destroy(&dirseq, 0); - return(ret); -} - - -/* @param flag bit0= recursion -*/ -int Xorriso_findx_action(struct XorrisO *xorriso, struct FindjoB *job, - char *abs_path, char *show_path, int depth, int flag) -{ - int ret= 0, type, action= 0, dpl= 0, compare_result, uret; - uid_t user= 0; - gid_t group= 0; - time_t date= 0; - mode_t mode_or= 0, mode_and= ~1; - char *target, *text_2, sfe[5*SfileadrL], *disk_prefix, iso_path[SfileadrL]; - struct FindjoB *subjob; - struct stat stbuf; - - action= Findjob_get_action_parms(job, &target, &text_2, &user, &group, - &mode_and, &mode_or, &type, &date, &subjob, 0); - if(action<0) - action= 0; - if(action<0) - action= 0; - if(action==15 || action==16 || action==18 || action==19 || action==20) { - /* in_iso , not_in_iso, add_missing , empty_iso_dir , is_full_in_iso */ - Findjob_get_start_path(job, &disk_prefix, 0); - if(strncmp(abs_path, disk_prefix, strlen(disk_prefix))!=0) - {ret= -1; goto ex;} - dpl= strlen(disk_prefix); - if(strlen(target)+strlen(abs_path)-dpl >= SfileadrL) - {ret= -1; goto ex;} - if(abs_path[dpl]=='/') - dpl++; - ret= Xorriso_make_abs_adr(xorriso, target, abs_path+dpl, iso_path, 4); - if(ret<=0) - {goto ex;} - - } - if(action==15) { /* in_iso */ - ret= Xorriso_iso_lstat(xorriso, iso_path, &stbuf, 0); - if(ret<0) - {ret= 1; goto ex;} - sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0)); - Xorriso_result(xorriso, 0); - ret= 1; - } else if(action==16) { /* not_in_iso */ - ret= Xorriso_compare_2_files(xorriso, abs_path, iso_path, abs_path+dpl, - &compare_result, 4); - if(retfind_compare_result) - xorriso->find_compare_result= ret; - if(ret>=0) - ret= 1; - } else if(action==18) { /* add_missing */ - ret= Xorriso_compare_2_files(xorriso, abs_path, iso_path, abs_path+dpl, - &compare_result, 4|(1<<31)); - if(retfind_compare_result) - xorriso->find_compare_result= ret; - if(ret==0) { - uret= Xorriso_update_interpreter(xorriso, NULL, compare_result, - abs_path, iso_path, (flag&1)<<2); - if(uret<=0) - ret= 0; - } - if(ret>=0) - ret= 1; - } else if(action==19) { /* empty_iso_dir */ - ret= Xorriso_iso_lstat(xorriso, iso_path, &stbuf, 0); - if(ret<0) - {ret= 1; goto ex;} - if(!S_ISDIR(stbuf.st_mode)) - {ret= 1; goto ex;} - ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, iso_path, 1|32); - if(ret>0) { - sprintf(xorriso->info_text, "Emptied directory %s", - Text_shellsafe(iso_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0); - } - } else if(action==20) { /* is_full_in_iso */ - ret= Xorriso_iso_lstat(xorriso, iso_path, &stbuf, 0); - if(ret<0) - {ret= 1; goto ex;} - if(!S_ISDIR(stbuf.st_mode)) - {ret= 1; goto ex;} - strcpy(sfe, xorriso->wdi); - strcpy(xorriso->wdi, iso_path); - ret= Xorriso_ls(xorriso, 4|8); - strcpy(xorriso->wdi, sfe); - if(ret>0) { - sprintf(xorriso->result_line, - "d %s (ISO) : non-empty directory (would not match mount point)\n", - Text_shellsafe(iso_path, sfe, 0)); - Xorriso_result(xorriso,0); - } - {ret= 1; goto ex;} - } else { - sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0)); - Xorriso_result(xorriso, 0); - ret= 1; - } -ex:; - if(action==15 || action==16 || action==18 || action==19 || action==20) - if(xorriso->no_volset_present) - xorriso->request_to_abort= 1; /* Need an image. No use to try again. */ - return(ret); -} - - -/* @param flag bit0=recursion -*/ -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) -{ - int ret,is_link, no_dive; - struct DirseQ *dirseq= NULL; - struct stat stbuf; - struct LinkiteM *own_link_stack; - char *abs_dir_path, *namept; - char *name= NULL, *path= NULL, *sfe= NULL; - char *abs_dir_path_data= NULL, *abs_path= NULL; - - if(xorriso->request_to_abort) - {ret= 0; goto ex;} - - sfe= malloc(5*SfileadrL); - name= malloc(SfileadrL); - path= malloc(SfileadrL); - abs_dir_path_data= malloc(SfileadrL); - abs_path= malloc(SfileadrL); - if(name==NULL || sfe==NULL || path==NULL || - abs_dir_path_data==NULL || abs_path==NULL) { - Xorriso_no_malloc_memory(xorriso, &sfe, 0); - {ret= -1; goto ex;} - } - own_link_stack= link_stack; - abs_dir_path= abs_dir_parm; - if(abs_dir_path[0]==0) { - ret= Xorriso_make_abs_adr(xorriso, xorriso->wdx, dir_path, - abs_dir_path_data, 1|2|8); - if(ret<=0) - goto ex; - abs_dir_path= abs_dir_path_data; - ret= Xorriso_path_is_excluded(xorriso, abs_dir_path, !(flag&1)); - if(ret<0) - goto ex; - if(ret>0) - {ret= 0; goto ex;} - ret= lstat(abs_dir_path, dir_stbuf); - if(ret==-1) - {ret= 0; goto ex;} - if(S_ISLNK(dir_stbuf->st_mode) && - (xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1)))) - if(stat(abs_dir_path, &stbuf)!=-1) - if(dir_stbuf->st_dev == stbuf.st_dev || - (xorriso->do_follow_mount || (xorriso->do_follow_param && !(flag&1)))) - memcpy(dir_stbuf, &stbuf, sizeof(struct stat)); - - namept= strrchr(dir_path, '/'); - if(namept==NULL) - namept= dir_path; - else - namept++; - - ret= Findjob_test_2(xorriso, job, NULL, namept, dir_path, NULL, dir_stbuf, - 0); - if(ret<0) - goto ex; - if(ret>0) { - ret= Xorriso_findx_action(xorriso, job, abs_dir_path, dir_path, depth, - flag&1); - if(xorriso->request_to_abort) - {ret= 0; goto ex;} - if(ret<=0) { - if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0) - goto ex; - } - } - } - if(xorriso->request_to_abort) - {ret= 1; goto ex;} - if(!S_ISDIR(dir_stbuf->st_mode)) - {ret= 2; goto ex;} - - ret= Dirseq_new(&dirseq, abs_dir_path, 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(!xorriso->request_to_abort) { - Linkitem_reset_stack(&own_link_stack, link_stack, 0); - 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, abs_dir_path, name, abs_path, 1); - if(ret<=0) - goto ex; - ret= Xorriso_make_abs_adr(xorriso, dir_path, name, path, 4); - if(ret<=0) - goto ex; - ret= Xorriso_path_is_excluded(xorriso, abs_path, 0); /* (is never param) */ - if(ret<0) - goto ex; - if(ret>0) - continue; - ret= lstat(abs_path, &stbuf); - if(ret==-1) - continue; - no_dive= 0; - - is_link= S_ISLNK(stbuf.st_mode); - if(is_link && xorriso->do_follow_links) { - ret= Xorriso_hop_link(xorriso, abs_path, &own_link_stack, &stbuf, 2); - if(ret<0) - {ret= -1; goto ex;} - if(ret!=1) - no_dive= 1; - } - - ret= Findjob_test_2(xorriso, job, NULL, name, path, dir_stbuf, &stbuf, 0); - if(ret<0) - goto ex; - if(ret>0) { - ret= Xorriso_findx_action(xorriso, job, abs_path, path, depth, flag&1); - if(xorriso->request_to_abort) - {ret= 0; goto ex;} - if(ret<=0) { - if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0) - goto ex; - } - } - if(!S_ISDIR(stbuf.st_mode)) - no_dive= 1; - if(dir_stbuf->st_dev != stbuf.st_dev && !xorriso->do_follow_mount) - no_dive= 1; - if(!no_dive) { - ret= Xorriso_findx(xorriso, job, abs_path, path, &stbuf, depth+1, - own_link_stack, flag|1); - if(ret<0) - goto ex; - } - } - - ret= 1; -ex:; - if(sfe!=NULL) - free(sfe); - if(name!=NULL) - free(name); - if(path!=NULL) - free(path); - if(abs_dir_path_data!=NULL) - free(abs_dir_path_data); - if(abs_path!=NULL) - free(abs_path); - Dirseq_destroy(&dirseq, 0); - return(ret); -} - - -/* @param flag bit0= a non-existing target of multiple sources is a directory - bit1= all paths except the last one are disk_paths - bit2= the last path is a disk_path - @return <=0 is error, 1= leaf file object, 2= directory -*/ -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) -{ - int destc= 0, is_dir=0, end_idx, ret, i; - char **destv= NULL; - char sfe[5*SfileadrL]; - - end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, - (xorriso->do_iso_rr_pattern==1)|(flag&2)); - if(end_idx - *idx < 2) { - sprintf(xorriso->info_text, "%s: not enough arguments", cmd); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - {ret= 0; goto ex;} - } - - ret= Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, optc, optv, - (flag&2)|16); /* ignore last argument */ - if(ret<=0) - goto ex; - /* demand one match, or 0 with a constant */ - ret= Xorriso_opt_args(xorriso, cmd, argc, argv, end_idx, &end_idx, &destc, - &destv, ((flag&4)>>1) | 32 | 64); - if(ret<=0) - goto ex; - - /* Evaluate target address */ - if(flag&4) - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, destv[0], eff_dest, - 2|4|16); - else - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, destv[0], eff_dest, - 1); - if(ret<0) - {ret= 0; goto ex;} - if(ret==2 || ((flag&1) && *optc > 1 && ret==0)) { - is_dir= 1; - } else if(*optc > 1) { - for(i= 0; i<*optc; i++) - Xorriso_msgs_submit(xorriso, 0, (*optv)[i], 0, "ERRFILE", 0); - sprintf(xorriso->info_text, - "%s: more than one origin given, destination is a non-directory: %s", - cmd, Text_shellsafe(destv[0], sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - if(ret==0) { /* compute complete eff_dest */ - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, destv[0], eff_dest, - 2 | (flag&4)); - if(ret<0) - {ret= 0; goto ex;} - } - - ret= 1+is_dir; -ex:; - Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, &destc, &destv, - 256); - (*idx)= end_idx; - return(ret); -} - - -/** @return -1= abort , 0= no , 1= yes -*/ -int Xorriso_reassure(struct XorrisO *xorriso, char *cmd, char *which_will, - int flag) -{ - int ret; - - if(!xorriso->do_reassure) - return(1); - sprintf(xorriso->info_text, "Really perform %s which will %s ? (y/n)\n", - cmd, which_will); - Xorriso_info(xorriso, 4); - do { - ret= Xorriso_request_confirmation(xorriso, 2|4|16); - } while(ret==3); - if(ret==6 || ret==4) { - sprintf(xorriso->info_text, "%s confirmed", cmd); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(1); - } - if(ret==2) { - sprintf(xorriso->info_text, "%s aborted", cmd); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(-1); - } - sprintf(xorriso->info_text, "%s revoked", cmd); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(0); -} - - -/* @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) -{ - int ret, aq_flag; - char drive_name[SfileadrL], sfe[5*SfileadrL]; - - aq_flag= flag&3; - strcpy(drive_name, xorriso->outdev); - Xorriso_give_up_drive(xorriso, aq_flag); - if(aq_flag==0) { - sprintf(xorriso->info_text,"Gave up -outdev %s", - Text_shellsafe(xorriso->outdev, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(1); - } - sprintf(xorriso->info_text,"Re-aquiring -outdev %s", - Text_shellsafe(drive_name, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - ret= Xorriso_aquire_drive(xorriso, drive_name, aq_flag); - if(ret<=0) { - sprintf(xorriso->info_text,"Could not re-aquire -outdev %s", - Text_shellsafe(xorriso->outdev, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(ret); - } - return(1); -} - - -int Xorriso_set_system_area_path(struct XorrisO *xorriso, char *path, int flag) -{ - int ret; - char eff_src[SfileadrL]; - - if(path[0] == 0) { - xorriso->system_area_disk_path[0]= 0; - return(1); - } - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, path, eff_src, 2|4|16); - if(ret < 0) - return(ret); - if(ret == 0) { - sprintf(xorriso->info_text, - "Given path does not exist on disk: -boot_image system_area="); - Text_shellsafe(eff_src, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } - if(ret == 2) { - sprintf(xorriso->info_text, - "Given path leads to a directory: -boot_image system_area="); - Text_shellsafe(eff_src, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - ret= Sfile_str(xorriso->system_area_disk_path, eff_src, 0); - if(ret <= 0) - return(-1); - return(1); -} - - -int Xorriso_cdrskin_help(struct XorrisO *xorriso, int flag) -{ - static char helptext[][80]= { -"Usage: xorriso -as cdrecord [options|source_addresses]", -"Note: This is not cdrecord. See xorriso -help, xorriso -version, man xorriso", -"Options:", -"\t-version\tprint version information and exit emulation", -"\t--devices\tprint list of available MMC drives and exit emulation", -"\tdev=target\tpseudo-SCSI target to use as CD-Recorder", -"\t-v\t\tincrement verbose level by one", -"\t-checkdrive\tcheck if a driver for the drive is present", -"\t-inq\t\tdo an inquiry for the drive and exit emulation", -"\tspeed=#\t\tset speed of drive", -"\tblank=type\tblank a CD-RW disc (see blank=help)", -"\tfs=#\t\tSet fifo size to # (0 to disable, default is 4 MB)", -"\t-eject\t\teject the disk after doing the work", -"\t-dummy\t\tdo everything with laser turned off", -"\t-msinfo\t\tretrieve multi-session info for mkisofs >= 1.10", -"\t-toc\t\tretrieve and print TOC/PMA data", -"\t-atip\t\tretrieve media state, print \"Is *erasable\"", -"\t-multi\t\tgenerate a TOC that allows multi session", -"\t-waiti\t\twait until input is available before opening SCSI", -"\ttsize=#\t\tannounces exact size of source data", -"\tpadsize=#\tAmount of padding", -"\t-data\t\tSubsequent tracks are CD-ROM data mode 1 (default)", -"\t-isosize\tUse iso9660 file system size for next data track", -"\t-pad\t\tpadsize=30k", -"\t-nopad\t\tDo not pad", -"\t--grow_overwriteable_iso\temulate multi-session on DVD+RW, BD-RE", -"\twrite_start_address=#\t\twrite to byte address on DVD+RW, BD-RE", -"\tstream_recording=on|number\ttry to get full speed on DVD-RAM, BD", -"\tdvd_obs=default|32k|64k\t\tbytes per DVD/BD write operation", -"\tstdio_sync=on|off|number\twhether to fsync output to \"stdio:\"", -"\t-help\t\tprint this text to stderr and exit emulation", -"Actually this is the integrated ISO RockRidge filesystem manipulator xorriso", -"lending its libburn capabilities to a very limited cdrecord emulation. Only", -"a single data track can be burnt to blank, appendable or overwriteable media.", -"A much more elaborate cdrecord emulator is cdrskin from the same project.", -"@End_of_helptexT@" -}; - int i; - - for(i= 0; strcmp(helptext[i], "@End_of_helptexT@")!=0; i++) { - sprintf(xorriso->info_text, "%s\n", helptext[i]); - Xorriso_info(xorriso,0); - } - return(1); -} - - -/* micro version of cdrskin */ -int Xorriso_cdrskin(struct XorrisO *xorriso, char *whom, int argc, char **argv, - int flag) -{ - int ret, i, k, mem_do_close, aq_ret, eject_ret, msc1, msc2, hflag; - int do_atip= 0, do_checkdrive= 0, do_eject= 0, do_scanbus= 0; - int do_toc= 0, do_verbous= 0, do_version= 0, do_help= 0, do_waiti= 0; - int do_multi= 0, do_msinfo= 0, do_grow= 0, do_isosize= 0, do_xa1= 0; - double write_start_address= -1.0, tsize= -1.0; - char track_source[SfileadrL], sfe[5*SfileadrL], dev_adr[SfileadrL], *cpt; - char mem_report_about_text[80], *report_about= "SORRY", blank_mode[80]; - char speed[80]; - - /* cdrecord 2.01 options which are not scheduled for implementation, yet */ - static char ignored_partial_options[][41]= { - "timeout=", "debug=", "kdebug=", "kd=", "driver=", "ts=", - "pregap=", "defpregap=", "mcn=", "isrc=", "index=", "textfile=", - "pktsize=", "cuefile=", - "gracetime=", "minbuf=", - - "assert_write_lba=", "fifo_start_at=", "dev_translation=", - "drive_scsi_dev_family=", "fallback_program=", "modesty_on_drive=", - "tao_to_sao_tsize=", - - "direct_write_amount=", "msifile=", - - "" - }; - static char ignored_full_options[][41]= { - "-d", "-Verbose", "-V", "-silent", "-s", "-setdropts", "-prcap", - "-reset", "-abort", "-overburn", "-ignsize", "-useinfo", - "-fix", "-nofix", - "-raw", "-raw96p", "-raw16", - "-clone", "-text", - "-cdi", "-preemp", "-nopreemp", "-copy", "-nocopy", - "-scms", "-shorttrack", "-noshorttrack", "-packet", "-noclose", - "-media-info", "-minfo", - "-load", "-lock", "-raw96r", "-sao", "-dao", "-swab", - "-tao", "-force", "-format", - - "--adjust_speed_to_drive", "--allow_emulated_drives", "--allow_setuid", - "--allow_untested_media", "--any_track", "--demand_a_drive", - "--fifo_disable", "--fifo_start_empty", "--fill_up_media", - "--list_ignored_options", "--no_rc", "--no_convert_fs_adr", - "--prodvd_cli_compatible", "--single_track", - "--tell_media_space", - - "" - }; - -static char blank_help[][80]= { -"Blanking options:", -"\tall\t\tblank the entire disk", -"\tdisc\t\tblank the entire disk", -"\tdisk\t\tblank the entire disk", -"\tfast\t\tminimally blank the entire disk", -"\tminimal\t\tminimally blank the entire disk", -"\tas_needed\tblank or format media to make it ready for (re-)use", -"\tdeformat\t\tblank a formatted DVD-RW", -"\tdeformat_quickest\tminimally blank a formatted DVD-RW to DAO only", -"\tformat_overwrite\tformat a DVD-RW to \"Restricted Overwrite\"", -"@End_of_helptexT@" -}; - - strcpy(mem_report_about_text, xorriso->report_about_text); - mem_do_close= xorriso->do_close; - - track_source[0]= 0; - dev_adr[0]= 0; - blank_mode[0]= 0; - speed[0]= 0; - - if(xorriso->in_drive_handle != NULL) { - ret= Xorriso_option_dev(xorriso, "", 1|32); /* give up indev */ - if(ret!=1) - return(ret); - } - - - /* Assess plan, make settings */ - for(i= 0; iinfo_text, "-as %s: %s", - whom, Text_shellsafe(argv[i], sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - - for(k=0;ignored_partial_options[k][0]!=0;k++) { - if(argv[i][0]=='-') - if(strncmp(argv[i]+1,ignored_partial_options[k], - strlen(ignored_partial_options[k]))==0) - goto no_volunteer; - if(strncmp(argv[i],ignored_partial_options[k], - strlen(ignored_partial_options[k]))==0) - goto no_volunteer; - } - for(k=0;ignored_full_options[k][0]!=0;k++) - if(strcmp(argv[i],ignored_full_options[k])==0) - goto no_volunteer; - if(0) { -no_volunteer:; - sprintf(xorriso->info_text, "-as %s: Ignored option %s", - whom, Text_shellsafe(argv[i], sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - continue; - } - - if(strcmp(argv[i], "-atip")==0) { - do_atip= 1; - } else if(strcmp(argv[i], "-audio")==0) { - sprintf(xorriso->info_text, "-as %s: Option -audio not supported.", whom); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } else if(strncmp(argv[i], "-blank=", 7)==0 || - strncmp(argv[i], "blank=", 6)==0) { - cpt= strchr(argv[i], '=')+1; - if(strcmp(cpt,"all")==0 || strcmp(cpt,"disc")==0 - || strcmp(cpt,"disk")==0) { - strcpy(blank_mode, "all"); - } else if(strcmp(cpt,"fast")==0 || strcmp(cpt,"minimal")==0) { - strcpy(blank_mode, "fast"); - } else if(strcmp(cpt,"help")==0) { - strcpy(blank_mode, "help"); - } else if(strcmp(cpt,"deformat")==0 || - strcmp(cpt,"deformat_sequential")==0 || - strcmp(cpt,"deformat_quickest")==0 || - strcmp(cpt,"deformat_sequential_quickest")==0) { - strcpy(blank_mode, cpt); - } else if(strcmp(cpt,"format_overwrite")==0) { - strcpy(blank_mode, "format_overwrite"); - } else if(strcmp(cpt,"as_needed")==0) { - strcpy(blank_mode, "as_needed"); - } else { - sprintf(xorriso->info_text, - "-as %s: blank=%s not supported. See blank=help .", - whom, Text_shellsafe(argv[i], sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - } else if(strcmp(argv[i], "-checkdrive")==0) { - do_checkdrive= 1; - } else if(strcmp(argv[i], "-data")==0) { - /* ok */; - } else if(strncmp(argv[i], "-dev=", 5)==0 || - strncmp(argv[i], "dev=", 4)==0) { - cpt= strchr(argv[i], '=')+1; - strcpy(dev_adr, cpt); - } else if(strcmp(argv[i], "--devices")==0) { - do_scanbus= 2; - } else if(strncmp(argv[i],"driveropts=", 11)==0 || - strncmp(argv[i],"-driveropts=", 12)==0) { - if(strcmp(argv[i]+11, "help")==0) { - fprintf(stderr,"Driver options:\n"); - fprintf(stderr, - "burnfree\tPrepare writer to use BURN-Free technology\n"); - } - } else if(strcmp(argv[i], "-dummy")==0) { - xorriso->do_dummy= 1; - } else if(strcmp(argv[i], "-eject")==0) { - do_eject= 1; - } else if(strncmp(argv[i], "-fs=", 4)==0 || strncmp(argv[i], "fs=", 3)==0) { - cpt= strchr(argv[i], '=')+1; - ret= Xorriso_option_fs(xorriso, cpt, 0); - if(ret<=0) - goto ex; - } else if(strcmp(argv[i], "--grow_overwriteable_iso")==0) { - do_grow= 1; - } else if(strcmp(argv[i], "-help")==0) { - do_help= 1; - } else if(strcmp(argv[i], "-isosize")==0) { - do_isosize= 1; - } else if(strcmp(argv[i], "-inq")==0) { - do_checkdrive= 2; - } else if(strcmp(argv[i], "-mode2")==0) { - Xorriso_msgs_submit(xorriso, 0, - "Defaulting option -mode2 to option -data", 0, "NOTE", 0); - } else if(strcmp(argv[i], "-msinfo")==0) { - do_msinfo= 1; - } else if(strcmp(argv[i], "-multi")==0) { - do_multi= 1; - } else if(strcmp(argv[i], "-nopad")==0) { - xorriso->padding= 0; - } else if(strcmp(argv[i], "-pad")==0) { - xorriso->padding= 15*2048; - } else if(strncmp(argv[i], "-padsize=", 9)==0 || - strncmp(argv[i], "padsize=", 8)==0) { - cpt= strchr(argv[i], '=')+1; - ret= Xorriso_option_padding(xorriso, cpt, 0); - if(ret<=0) - goto ex; - } else if(strcmp(argv[i], "-scanbus")==0) { - sprintf(xorriso->info_text, "-as %s: Option -scanbus not supported.", - whom); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - -/* do_scanbus= 1; */ - } else if(strncmp(argv[i], "-speed=", 7)==0 || - strncmp(argv[i], "speed=", 6)==0) { - cpt= strchr(argv[i], '=')+1; - strncpy(speed, cpt, 79); - speed[79]= 0; - - } else if(strncmp(argv[i], "-stream_recording=", 18)==0 || - strncmp(argv[i], "stream_recording=", 17)==0) { - cpt= strchr(argv[i], '=')+1; - Xorriso_option_stream_recording(xorriso, cpt, 0); - - } else if(strncmp(argv[i], "-dvd_obs=", 9)==0 || - strncmp(argv[i], "dvd_obs=", 8)==0) { - cpt= strchr(argv[i], '=') + 1; - Xorriso_option_dvd_obs(xorriso, cpt, 0); - - } else if(strncmp(argv[i], "-stdio_sync=", 12)==0 || - strncmp(argv[i], "stdio_sync=", 11)==0) { - cpt= strchr(argv[i], '=') + 1; - Xorriso_option_stdio_sync(xorriso, cpt, 0); - - } else if(strcmp(argv[i], "-toc")==0 || strcmp(argv[i], "--long_toc")==0) { - do_toc= 1; - } else if(strncmp(argv[i], "-tsize=", 7)==0 || - strncmp(argv[i], "tsize=", 6)==0) { - cpt= strchr(argv[i], '=')+1; - tsize= Scanf_io_size(cpt, 1); - if(tsize > 1024.0*1024.0*1024.0*1024.0*1024.0) { - sprintf(xorriso->info_text, "-as %s: much too large: %s",whom, argv[i]); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - } else if(strcmp(argv[i], "-v")==0 || strcmp(argv[i],"-verbose")==0) { - do_verbous++; - } else if(strcmp(argv[i], "-vv")==0) { - do_verbous+= 2; - } else if(strcmp(argv[i], "-vvv")==0) { - do_verbous+= 3; - } else if(strcmp(argv[i], "-version")==0) { - do_version= 1; - } else if(strcmp(argv[i], "-waiti")==0) { - do_waiti= 1; - } else if(strncmp(argv[i], "write_start_address=", 20)==0) { - write_start_address= Scanf_io_size(argv[i]+20,0); - } else if(strcmp(argv[i], "-xa")==0) { - Xorriso_msgs_submit(xorriso, 0, - "Defaulting option -xa to option -data", 0, "NOTE", 0); - } else if(strcmp(argv[i], "-xa1")==0) { - if(do_xa1 == 0) - do_xa1= 1; - } else if(strcmp(argv[i], "--xa1-ignore")==0) { - do_xa1= -1; - } else if(strcmp(argv[i], "-xa2")==0) { - Xorriso_msgs_submit(xorriso, 0, - "Defaulting option -xa2 to option -data", 0, "NOTE", 0); - } else if(strcmp(argv[i], "-xamix")==0) { - Xorriso_msgs_submit(xorriso, 0, - "Option -xamix not implemented and data not yet convertible to other modes", - 0, "FATAL", 0); - ret= 0; goto ex; - } else if(argv[i][0]=='-' && argv[i][1]!=0) { - sprintf(xorriso->info_text, "-as %s: Unknown option %s", - whom, Text_shellsafe(argv[i], sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } else { - if(track_source[0]) { - sprintf(xorriso->info_text, "-as %s: Surplus track source %s", - whom, Text_shellsafe(argv[i], sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - sprintf(xorriso->info_text, "First and only track source is %s", - Text_shellsafe(track_source, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - ret= 0; goto ex; - } - if(Sfile_str(track_source, argv[i], 0)<=0) - {ret= -1; goto ex;} - } - } - - /* Perform actions */ - Xorriso_option_report_about(xorriso, "NOTE", 0); - if(do_version) { - sprintf(xorriso->result_line, "Cdrecord 2.01-Emulation Copyright (C) 2010 see libburnia-project.org xorriso\n"); - Xorriso_result(xorriso, 1); - Xorriso_option_version(xorriso, 0); - ret= 1; goto ex; - } - if(do_waiti) { - sprintf(xorriso->info_text, - "xorriso: Option -waiti pauses program until input appears at stdin\n"); - Xorriso_info(xorriso,0); - sprintf(xorriso->result_line, "Waiting for data on stdin...\n"); - Xorriso_result(xorriso, 1); - for(ret= 0; ret==0; ) - ret= Wait_for_input(0,1000000,0); - if(ret<0 || feof(stdin)) { - Xorriso_msgs_submit(xorriso, 0, - "stdin produces exception rather than data", 0, "NOTE", 0); - } - sprintf(xorriso->info_text, "xorriso: Option -waiti pausing is done.\n"); - } - if(dev_adr[0]) { - hflag= 2 | 32 | 64; - if(!do_grow) - hflag|= 8; /* consider overwriteables as blank */ - ret= Xorriso_option_dev(xorriso, dev_adr, hflag); - if(ret<=0) - goto ex; - } - - if(do_help) { - Xorriso_cdrskin_help(xorriso, 0); - ret= 1; goto ex; - } - if(do_scanbus) { - if(do_scanbus==1) - /* >>> would need -scanbus compatible output and input format */; - else - Xorriso_option_devices(xorriso, 0); - ret= 1; goto ex; - } - if(strcmp(blank_mode, "help")==0) { - for(i= 0; strcmp(blank_help[i], "@End_of_helptexT@")!=0; i++) { - sprintf(xorriso->info_text, "%s\n", blank_help[i]); - Xorriso_info(xorriso,0); - } - ret= 1; goto ex; - } - - if(!(do_checkdrive || do_atip || do_toc || blank_mode[0] || track_source[0] || - do_eject || do_msinfo)) - {ret= 1; goto ex;} - - if(xorriso->out_drive_handle==NULL) { - sprintf(xorriso->info_text, "-as %s: No output drive selected", whom); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - - if(do_msinfo) { - ret= Xorriso_msinfo(xorriso, &msc1, &msc2, 2 | !!do_grow); - if(ret<=0) - goto ex; - sprintf(xorriso->result_line, "%d,%d\n", msc1, msc2); - Xorriso_result(xorriso, 1); - } - - if(speed[0]) { - ret= Xorriso_option_speed(xorriso, speed, 0); - if(ret<=0) - goto ex; - } - - if(do_verbous<=0) - report_about= "SORRY"; - else if(do_verbous<=2) - report_about= "UPDATE"; - else if(do_verbous==3) - report_about= "DEBUG"; - else - report_about= "ALL"; - Xorriso_option_report_about(xorriso, report_about, 0); - - if(do_checkdrive) { - ret= Xorriso_atip(xorriso, 2-(do_checkdrive==2)); - if(ret<=0) - goto ex; - } - if(do_atip) { - ret= Xorriso_atip(xorriso, 0); - if(ret<=0) - goto ex; - } - if(do_toc) { - ret= Xorriso_option_toc(xorriso, 0); - if(ret<=0) - goto ex; - } - if(strcmp(blank_mode, "format_overwrite")==0) { - ret= Xorriso_option_blank(xorriso, "fast", 1); - if(ret<=0) - goto ex; - } else if(blank_mode[0]) { - ret= Xorriso_option_blank(xorriso, blank_mode, 0); - if(ret<=0) - goto ex; - } - if(track_source[0]) { - xorriso->do_close= !do_multi; - ret= Xorriso_burn_track(xorriso, (off_t) write_start_address, - track_source, (off_t) tsize, - (!!do_grow) | ((!!do_isosize) << 1) | ((do_xa1 == 1) << 2)); - aq_ret= Xorriso_reaquire_outdev(xorriso, 2*(ret>0)); - if(ret<=0 && ret=0) { - eject_ret= Xorriso_option_eject(xorriso, "out", 0); - if(eject_retinfo_text, "-as %s: Job could not be performed properly.", - whom); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } - Xorriso_option_report_about(xorriso, mem_report_about_text, 0); - xorriso->do_close= mem_do_close; - return(ret); -} - - -/* @param flag bit0= do not report eventual ignore decision -*/ -int Xorriso_genisofs_ignore(struct XorrisO *xorriso, char *whom, - char **argv, int *i, int flag) -{ - /* mkisofs 2.01 options which are not scheduled for implementation, yet */ - static char ignored_arg0_options[][41]= { - "-allow-leading-dots", "-ldots", "-allow-lowercase", "-allow-multidot", - "-cache-inodes", "-no-cache-inodes", "-check-oldnames", "-d", "-D", - "-joliet-long", "-l", "-L", "-max-iso9660-filenames", "-N", "-nobak", - "-no-bak", "-force-rr", "-relaxed-filenames", "-T", "-U", - "-no-iso-translate", - "" - }; - static char ignored_arg1_options[][41]= { - "-biblio", "-check-session", "-p", "-root", - "-old-root", "-table-name", "-volset-seqno", "-volset-size", - "" - }; - int k, idx_offset= 0; - char sfe[5*SfileadrL]; - - for(k=0;ignored_arg0_options[k][0]!=0;k++) - if(strcmp(argv[*i],ignored_arg0_options[k])==0) - goto no_volunteer; - for(k=0;ignored_arg1_options[k][0]!=0;k++) - if(strcmp(argv[*i],ignored_arg1_options[k])==0) { - (*i)++; - idx_offset= -1; - goto no_volunteer; - } - return(0); -no_volunteer:; - sprintf(xorriso->info_text, "-as %s: Ignored option %s", - whom, Text_shellsafe(argv[(*i)+idx_offset], sfe, 0)); - if(!(flag & 1)) - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(1); -} - - -int Xorriso_genisofs_add_boot(struct XorrisO *xorriso, char *whom, - int *option_b, int *no_emul_boot, int flag) -{ - int ret; - - if(*option_b && !*no_emul_boot) { - xorriso->boot_image_bin_path[0]= 0; - sprintf(xorriso->info_text, - "-as %s: Option -b is supported only if option -no-emul-boot is given", - whom); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - ret= Xorriso_attach_boot_image(xorriso, 0); - if(ret <= 0) - xorriso->boot_image_bin_path[0]= 0; - *option_b= 0; - *no_emul_boot= 1; - return(ret); -} - - -int Xorriso_genisofs_help(struct XorrisO *xorriso, int flag) -{ - static char helptext[][160]= { -"Usage: xorriso -as mkisofs [options] file...", -"Note: This is not mkisofs. See xorriso -help, xorriso -version, man xorriso", -"Options:", -" -f, -follow-links Follow symbolic links", -" -graft-points Allow to use graft points for filenames", -" -help Print option help", -" -input-charset CHARSET Local input charset for file name conversion", -" -output-charset CHARSET Output charset for file name conversion", -" -iso-level LEVEL Set ISO9660 conformance level (1..3)", -" -J, -joliet Generate Joliet directory information", -" -o FILE, -output FILE Set output file name", -" -m GLOBFILE, -exclude GLOBFILE", -" Exclude file name", -" -exclude-list FILE File with list of file names to exclude", -" -pad Pad output by 300k (default)", -" -no-pad Do not pad output", -" -M FILE, -prev-session FILE Set path to previous session to merge", -" -C PARAMS, -cdrecord-params PARAMS", -" Magic paramters from cdrecord", -" -path-list FILE File with list of pathnames to process", -" --quoted_path_list FILE File with list of quoted pathnames to process", -" -print-size Print estimated filesystem size and exit", -" -quiet Run quietly", -" -R, -rock Generate Rock Ridge directory information", -" -r, -rational-rock Generate rationalized Rock Ridge directory information", -" --hardlinks Record eventual hard link relations of files", -" --acl Record eventual ACLs of files", -" --xattr Record eventual user space xattr of files", -" --md5 Compute and record MD5 checksums of data files", -" --scdbackup_tag PATH NAME With --md5 record a scdbackup checksum tag", -" --for_backup Use all options which improve backup fidelity", -" -V ID, -volid ID Set Volume ID", -" -volset ID Set Volume set ID", -" -publisher PUB Set Volume publisher", -" -A ID, -appid ID Set Application ID", -" -sysid ID Set System ID", -" -b FILE, -eltorito-boot FILE", -" Set El Torito boot image name", -" -eltorito-alt-boot Start specifying alternative El Torito boot parameters", -" --efi-boot FILE Set El Torito EFI boot image name and type", -" -c FILE, -eltorito-catalog FILE", -" Set El Torito boot catalog name", -" -boot-load-size # Set numbers of load sectors", -" -no-emul-boot Boot image is 'no emulation' image", -" -boot-info-table Patch boot image with info table", -" -G FILE, -generic-boot FILE Set generic boot image name", -" --protective-msdos-label Patch System Area by partition table", -" --modification-date=YYYYMMDDhhmmsscc", -" Override date of creation and modification", -" -isohybrid-mbr FILE Set SYSLINUX mbr/isohdp[fp]x*.bin for isohybrid", -#ifdef Xorriso_with_isohybriD -" isolinux_mbr=on|auto|off Control eventual isohybrid MBR generation", -#endif -" --sort-weight NUMBER FILE Set LBA weight number to file or file tree", -" --stdio_sync on|off|number Control forced output to disk files", -" -z, -transparent-compression", -" Enable transparent compression of files", -" -v, -verbose Verbose", -" -version Print the current version", -"@End_of_helptexT@" -}; - char ra_text[80]; - int i; - - strcpy(ra_text, xorriso->report_about_text); - - Xorriso_option_report_about(xorriso, "NOTE", 0); - for(i= 0; strcmp(helptext[i], "@End_of_helptexT@")!=0; i++) { - sprintf(xorriso->info_text, "%s\n", helptext[i]); - Xorriso_info(xorriso, 1); - } - Xorriso_option_report_about(xorriso, ra_text, 0); - return(1); -} - - -/* micro emulation of mkisofs */ -int Xorriso_genisofs(struct XorrisO *xorriso, char *whom, - int argc, char **argv, int flag) -{ - int ret, i, j, was_path= 0, was_other_option= 0, mem_graft_points, mem; - int do_print_size= 0, fd, idx, iso_level= 0, no_emul_boot= 0; - int option_b= 0, was_failure= 0, fret, lower_r= 0, zero= 0; - int *weight_list= NULL, weight_count= 0; - int *boot_opt_list= NULL, boot_opt_count= 0; - char sfe[5*SfileadrL], adr[SfileadrL+8], ra_text[80], pathspec[2*SfileadrL]; - char *ept, *add_pt, eff_path[SfileadrL], indev[SfileadrL+8], msc[80], *cpt; - char *boot_path; - static char *lower_r_args[3]= {"/", "-exec", "mkisofs_r"}; - static char *sort_weight_args[4]= {"", "-exec", "sort_weight", ""}; - - strcpy(ra_text, xorriso->report_about_text); - - weight_list= TSOB_FELD(int, (argc / 3) + 1); - if(weight_list == NULL) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - return(-1); - } - boot_opt_list= TSOB_FELD(int, argc + 1); - if(boot_opt_list == NULL) { - cpt= (char *) weight_list; - Xorriso_no_malloc_memory(xorriso, &cpt, 0); - return(-1); - } - - adr[0]= indev[0]= msc[0]= 0; - for(i= 0; iresult_line, -"mkisofs 2.01-Emulation Copyright (C) 2010 see libburnia-project.org xorriso\n" - ); - fd= xorriso->dev_fd_1; - if(fd<0) - fd= 1; - write(fd, xorriso->result_line, strlen(xorriso->result_line)); - fsync(fd); - Xorriso_option_version(xorriso, 0); - - } else if(strcmp(argv[i], "-o")==0 || strcmp(argv[i], "-output")==0) { - if(i+1>=argc) - goto not_enough_args; - i++; - adr[0]= 0; - if(strcmp(argv[i],"-")!=0 && strncmp(argv[i], "stdio:", 6)!=0) - strcpy(adr, "stdio:"); - if(Sfile_str(adr+strlen(adr), argv[i], 0)<=0) - {ret= -1; goto ex;} - } else if(strcmp(argv[i], "-M")==0 || strcmp(argv[i], "-dev")==0 || - strcmp(argv[i], "-prev-session")==0) { - if(i+1>=argc) - goto not_enough_args; - i++; - if(strncmp(argv[i], "stdio:", 6)!=0) - strcpy(indev, "stdio:"); - if(Sfile_str(indev+strlen(indev), argv[i], 0)<=0) - {ret= -1; goto ex;} - } else if(strcmp(argv[i], "-C")==0 || - strcmp(argv[i], "-cdrecord-params")==0) { - if(i+1>=argc) - goto not_enough_args; - i++; - strncpy(msc, argv[i], sizeof(msc)-1); - msc[sizeof(msc)-1]= 0; - } else if(strcmp(argv[i], "-help")==0) { - Xorriso_genisofs_help(xorriso, 0); - } else if(strcmp(argv[i], "-v")==0 || strcmp(argv[i], "-verbose")==0) { - strcpy(ra_text, "UPDATE"); - } else if(strcmp(argv[i], "-quiet")==0) { - strcpy(ra_text, "SORRY"); - } else if(strcmp(argv[i], "-f")==0 || strcmp(argv[i], "-follow-links")==0) { - ret= Xorriso_option_follow(xorriso, "on", 0); - if(ret<=0) - goto problem_handler_1; - } else if(strcmp(argv[i], "-iso-level")==0) { - if(i+1>=argc) - goto not_enough_args; - i++; - sscanf(argv[i], "%d", &iso_level); - if(iso_level < 1 || iso_level > 3) { - sprintf(xorriso->info_text, - "-as %s: unsupported -iso-level '%s' (use one of: 1,2,3)", - whom, argv[i]); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto problem_handler_1; - } - if(iso_level < 3) - xorriso->file_size_limit= - ((off_t) 4) * ((off_t) 1024*1024*1024) - ((off_t) 1); - else - xorriso->file_size_limit= 0; - - } else if(strcmp(argv[i], "-input-charset")==0) { - if(i+1>=argc) - goto not_enough_args; - i++; - /* -local_charset */ - if(strcmp(argv[i], "default") == 0) - ret= Xorriso_option_charset(xorriso, "ISO-8859-1", 4); - else - ret= Xorriso_option_charset(xorriso, argv[i], 4); - if(ret <= 0) - goto problem_handler_1; - } else if(strcmp(argv[i], "-output-charset")==0) { - if(i+1>=argc) - goto not_enough_args; - i++; - /* -charset */ - if(strcmp(argv[i], "default") == 0) - ret= Xorriso_option_charset(xorriso, "ISO-8859-1", 3); - else - ret= Xorriso_option_charset(xorriso, argv[i], 3); - if(ret <= 0) - goto problem_handler_1; - } else if(strcmp(argv[i], "--hardlinks")==0) { - Xorriso_option_hardlinks(xorriso, "on", 0); - } else if(strcmp(argv[i], "--acl")==0) { - Xorriso_option_acl(xorriso, "on", 0); - } else if(strcmp(argv[i], "--xattr")==0) { - Xorriso_option_xattr(xorriso, "on", 0); - } else if(strcmp(argv[i], "--md5")==0) { - Xorriso_option_md5(xorriso, "on", 0); - } else if(strcmp(argv[i], "--scdbackup_tag")==0) { - if(i + 2 >= argc) - goto not_enough_args; - i+= 2; - ret= Xorriso_option_scdbackup_tag(xorriso, argv[i-1], argv[i], 0); - if(ret <= 0) - goto problem_handler_1; - } else if(strcmp(argv[i], "--for_backup")==0) { - Xorriso_option_hardlinks(xorriso, "on", 0); - Xorriso_option_acl(xorriso, "on", 0); - Xorriso_option_xattr(xorriso, "on", 0); - Xorriso_option_md5(xorriso, "on", 0); - } else if(strcmp(argv[i], "-z")==0 || - strcmp(argv[i], "-transparent-compression")==0) { - Xorriso_option_zisofs(xorriso, "by_magic=on", 0); - } else if(strcmp(argv[i], "--stdio_sync")==0) { - if(i+1>=argc) - goto not_enough_args; - i++; - Xorriso_option_stdio_sync(xorriso, argv[i], 0); - } else - was_other_option= 1; - - continue; /* regular bottom of loop */ -problem_handler_1:; - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - goto ex; - } - Xorriso_option_report_about(xorriso, ra_text, 0); - if(adr[0]) { - if(strncmp(adr, "stdio:", 6)==0 && strncmp(adr, "stdio:/dev/fd/", 14)!=0) { - ret= Sfile_type(adr+6, 1); - if(ret==-1) { - /* ok */; - } else if(ret==2 || ret==3) { - sprintf(xorriso->info_text, - "-as %s: Cannot accept %s as target: -o %s", - whom, (ret==3 ? "symbolic link" : "directory"), - Text_shellsafe(adr+6, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - } - /* Regard overwriteable as blank, truncate regular files on write start */ - ret= Xorriso_option_dev(xorriso, adr, 2|8|16); - if(ret<=0) - goto ex; - } - - if(was_other_option && xorriso->out_drive_handle==NULL) { - ret= Xorriso_option_dev(xorriso, "-", 2|4); /* set outdev to stdout */ - if(ret<=0) - goto ex; - } - - if(msc[0]) { - cpt= strchr(msc, ','); - if(cpt==NULL) { -illegal_c:; - sprintf(xorriso->info_text, - "-as %s: unusable parameter with option -C: %s", - whom, Text_shellsafe(msc, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } else if(cpt==msc || msc[1]==0) - goto illegal_c; - strncpy(sfe, msc, cpt-msc); - sfe[cpt-msc]= 0; - if(xorriso->in_drive_handle!=NULL && indev[0]) { - /* give up indev before setting the load address */ - ret= Xorriso_option_dev(xorriso, "", 1); - if(ret<=0) - goto ex; - } - /* growisofs submits msc1+16 to avoid a theoretical bug in mkisofs. - Therefore this bug has to be emulated here. Sigh. - */ - ret= Xorriso_option_load(xorriso, "sbsector", sfe, 1); - if(ret<=0) - goto ex; - ret= Xorriso_option_grow_blindly(xorriso, cpt+1, 0); - if(ret<=0) - goto ex; - } - if(indev[0]) { - ret= Xorriso_option_dev(xorriso, indev, 1); - if(ret<=0) - goto ex; - } - - if(!was_other_option) - {ret= 1; goto ex;} - - xorriso->padding= 300*1024; - - for(i= 0; iinfo_text, "-as %s: %s", - whom, Text_shellsafe(argv[i], sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - ret= Xorriso_genisofs_ignore(xorriso, whom, argv, &i, 0); - if(ret == 1) - continue; - if(strcmp(argv[i], "-version")==0) { - /* was already handled in first argument scan */; - - } else if(strcmp(argv[i], "-R")==0 || strcmp(argv[i], "-rock")==0) { - /* ok */; - } else if(strcmp(argv[i], "-r")==0 || strcmp(argv[i], "-rational-rock")==0){ - lower_r= 1; - } else if(strcmp(argv[i], "-J")==0 || strcmp(argv[i], "-joliet")==0) { - xorriso->do_joliet= 1; - } else if(strcmp(argv[i], "-graft-points")==0) { - xorriso->allow_graft_points= 1; - } else if(strcmp(argv[i], "-path-list")==0 || - strcmp(argv[i], "--quoted_path_list")==0) { - if(i+1>=argc) { -not_enough_args:; - sprintf(xorriso->info_text, "-as %s: Not enough arguments to option %s", - whom, argv[i]); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - i++; - was_path= 1; - xorriso->pacifier_style= 1; - ret= Xorriso_option_path_list(xorriso, argv[i], - (strcmp(argv[i-1], "--quoted_path_list")==0)); - if(ret<=0) - goto problem_handler_2; - } else if(strcmp(argv[i], "-f")==0 || strcmp(argv[i], "-follow-links")==0) { - /* was already handled in first argument scan */; - } else if(strcmp(argv[i], "-pad")==0) { - xorriso->padding= 300*1024; - } else if(strcmp(argv[i], "-no-pad")==0) { - xorriso->padding= 0; - } else if(strcmp(argv[i], "-print-size")==0) { - do_print_size= 1; - } else if(strcmp(argv[i], "-o")==0) { - i++; - /* was already handled in first argument scan */; - } else if(strcmp(argv[i], "-M")==0 || strcmp(argv[i], "-dev")==0) { - i++; - /* was already handled in first argument scan */; - } else if(strcmp(argv[i], "-C")==0) { - i++; - /* was already handled in first argument scan */; - } else if(strcmp(argv[i], "-help")==0) { - /* was already handled in first argument scan */; - } else if(strcmp(argv[i], "-V")==0 || strcmp(argv[i], "-volid")==0) { - if(i+1>=argc) - goto not_enough_args; - i++; - ret= Xorriso_option_volid(xorriso, argv[i], 0); - if(ret<=0) - goto problem_handler_2; - } else if(strcmp(argv[i], "-volset")==0) { - if(i+1>=argc) - goto not_enough_args; - i++; - ret= Xorriso_option_volid(xorriso, argv[i], 0); - if(ret<=0) - goto problem_handler_2; - } else if(strcmp(argv[i], "-P")==0 || strcmp(argv[i], "-publisher")==0) { - if(i+1>=argc) - goto not_enough_args; - i++; - ret= Xorriso_option_publisher(xorriso, argv[i], 0); - if(ret<=0) - goto problem_handler_2; - } else if(strcmp(argv[i], "-A")==0 || strcmp(argv[i], "-appid")==0) { - if(i+1>=argc) - goto not_enough_args; - i++; - ret= Xorriso_option_application_id(xorriso, argv[i], 0); - if(ret<=0) - goto problem_handler_2; - } else if(strcmp(argv[i], "-sysid")==0) { - if(i+1>=argc) - goto not_enough_args; - i++; - ret= Xorriso_option_system_id(xorriso, argv[i], 0); - if(ret<=0) - goto problem_handler_2; - } else if(strcmp(argv[i], "-m")==0 || strcmp(argv[i], "-exclude")==0 || - strcmp(argv[i], "-x")==0 || strcmp(argv[i], "-old-exclude")==0) { - if(i+1>=argc) - goto not_enough_args; - i++; - mem= xorriso->do_disk_pattern; - xorriso->do_disk_pattern= 1; - if(strchr(argv[i], '/')!=NULL) { - idx= i; - ret= Xorriso_option_not_paths(xorriso, i+1, argv, &idx, 0); - } else - ret= Xorriso_option_not_leaf(xorriso, argv[i], 0); - xorriso->do_disk_pattern= mem; - if(ret<=0) - goto problem_handler_2; - } else if(strcmp(argv[i], "-exclude-list")==0) { - if(i+1>=argc) - goto not_enough_args; - i++; - mem= xorriso->do_disk_pattern; - xorriso->do_disk_pattern= 1; - ret= Xorriso_option_not_list(xorriso, argv[i], 0); - xorriso->do_disk_pattern= mem; - if(ret<=0) - goto problem_handler_2; - } else if(strcmp(argv[i], "-v")==0 || strcmp(argv[i], "-quiet")==0) { - /* was already handled in first argument scan */; - - } else if(strcmp(argv[i], "-iso-level")==0) { - i++; - /* was already handled in first argument scan */; - } else if(strcmp(argv[i], "-no-emul-boot")==0 || - strcmp(argv[i], "-boot-info-table")==0 || - strncmp(argv[i], "isolinux_mbr=", 13)==0 || - strncmp(argv[i], "isolinux_mbr=", 13)==0 || - strcmp(argv[i], "-eltorito-alt-boot")==0 || - strcmp(argv[i], "--protective-msdos-label")==0) { - boot_opt_list[boot_opt_count++]= i; - } else if(strcmp(argv[i], "-b") == 0 || - strcmp(argv[i], "-eltorito-boot") == 0 || - strcmp(argv[i], "--efi-boot") == 0 || - strcmp(argv[i], "-c") == 0 || - strcmp(argv[i], "-eltorito-catalog") == 0 || - strcmp(argv[i], "-boot-load-size") == 0 || - strcmp(argv[i], "--embedded-boot")==0 || - strcmp(argv[i], "-generic-boot")==0 || - strcmp(argv[i], "-G") == 0 || - strcmp(argv[i], "-isohybrid-mbr")==0) { - if(i+1>=argc) - goto not_enough_args; - boot_opt_list[boot_opt_count++]= i; - i++; - } else if(strncmp(argv[i], "--modification-date=", 20)==0) { - ret= Xorriso_option_volume_date(xorriso, "uuid", argv[i] + 20, 0); - if(ret <= 0) - goto problem_handler_1; - - } else if(strcmp(argv[i], "-input-charset")==0) { - i++; - /* was already handled in first argument scan */; - } else if(strcmp(argv[i], "-output-charset")==0) { - i++; - /* was already handled in first argument scan */; - } else if(strcmp(argv[i], "--hardlinks")==0 || - strcmp(argv[i], "--acl")==0 || - strcmp(argv[i], "--xattr")==0 || - strcmp(argv[i], "--md5")==0 || - strcmp(argv[i], "--for_backup")==0) { - /* was already handled in first argument scan */; - } else if(strcmp(argv[i], "--scdbackup_tag")==0) { - /* was already handled in first argument scan */; - i+= 2; - } else if(strcmp(argv[i], "--sort-weight")==0) { - if(i + 2 >= argc) - goto not_enough_args; - i+= 2; - /* memorize for find runs after pathspecs have been added */ - weight_list[weight_count++]= i - 2; - } else if(strcmp(argv[i], "-z")==0 || - strcmp(argv[i], "-transparent-compression")==0) { - /* was already handled in first argument scan */; - } else if(argv[i][0]=='-' && argv[i][1]!=0) { - sprintf(xorriso->info_text, "-as %s: Unknown option %s", - whom, Text_shellsafe(argv[i], sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } else { - int zero= 0; - - /* implementing mkisofs tendency to map single-path pathspecs to / */ - if((!xorriso->allow_graft_points) || - Fileliste__target_source_limit(argv[i], '=', &ept, 0)<=0) { - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, argv[i], - eff_path, 2|4); - if(ret<=0) - goto problem_handler_2; - ret= Sfile_type(eff_path, - 1|((xorriso->do_follow_param||xorriso->do_follow_links)<<2)); - if(ret==2) { - strcpy(pathspec, "/="); - } else { - pathspec[0]= '/'; - pathspec[1]= 0; - ret= Sfile_leafname(eff_path, pathspec+1, 0); - if(ret>0) - strcat(pathspec, "="); - else - pathspec[0]= 0; - } - strcat(pathspec, eff_path); - add_pt= pathspec; - } else - add_pt= argv[i]; - mem_graft_points= xorriso->allow_graft_points; - xorriso->allow_graft_points= 1; - ret= Xorriso_option_add(xorriso, 1, &add_pt, &zero, was_path<<1); - xorriso->allow_graft_points= mem_graft_points; - if(ret<=0) - goto problem_handler_2; - was_path= 1; - xorriso->pacifier_style= 1; - } - continue; /* regular bottom of loop */ -problem_handler_2:; - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - goto ex; - } - if(do_print_size) { - ret= Xorriso_option_print_size(xorriso, 1); - if(ret<=0) - goto ex; - } - if(lower_r) { - zero= 0; - ret= Xorriso_option_find(xorriso, 3, lower_r_args, &zero, 2); - if(ret<=0) - goto ex; - } - - for(j= 0; j < weight_count; j++) { - i= weight_list[j]; - /* find argv[i+2] -exec sort_weight argv[i+1] */ - zero= 0; - sort_weight_args[0]= argv[i + 2]; - sort_weight_args[3]= argv[i + 1]; - ret= Xorriso_option_find(xorriso, 4, sort_weight_args, &zero, 2); - if(ret > 0) - continue; - /* Problem handler */ - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - goto ex; - } - - /* After all pathspecs are added: perform boot related options */ - for(j= 0; j < boot_opt_count; j++) { - i= boot_opt_list[j]; - if(strcmp(argv[i], "-no-emul-boot")==0) { - no_emul_boot= 1; - } else if(strcmp(argv[i], "-boot-info-table")==0) { - xorriso->patch_isolinux_image= 1; - } else if(strcmp(argv[i], "-b") == 0 || - strcmp(argv[i], "-eltorito-boot") == 0 || - strcmp(argv[i], "--efi-boot") == 0) { - i++; - if(strcmp(argv[i - 1], "--efi-boot") == 0) { - if(xorriso->boot_image_bin_path[0]) { - ret= Xorriso_genisofs_add_boot(xorriso, whom, - &option_b, &no_emul_boot, 0); - if(ret <= 0) - goto problem_handler_boot; - } - boot_path= xorriso->boot_image_bin_path; - xorriso->boot_efi_default= 1; - } else { - boot_path= xorriso->boot_image_bin_path; - xorriso->boot_platform_id= 0x00; - xorriso->boot_efi_default= 0; - option_b= 1; - } - boot_path[0]= 0; - if(argv[i][0] != '/') - strcat(boot_path, "/"); - ret= Sfile_str(boot_path + strlen(boot_path), argv[i], 0); - if(ret <= 0) - goto ex; - if(xorriso->boot_efi_default && xorriso->boot_image_bin_path[0]) { - option_b= 0; - ret= Xorriso_genisofs_add_boot(xorriso, whom, - &option_b, &no_emul_boot, 0); - if(ret <= 0) - goto problem_handler_boot; - } - xorriso->keep_boot_image= 0; - } else if(strcmp(argv[i], "-c") == 0 || - strcmp(argv[i], "-eltorito-catalog") == 0) { - if(i+1>=argc) - goto not_enough_args; - i++; - xorriso->boot_image_cat_path[0]= 0; - if(argv[i][0] != '/') - strcat(xorriso->boot_image_cat_path, "/"); - ret= Sfile_str(xorriso->boot_image_cat_path - + strlen(xorriso->boot_image_cat_path), argv[i], 0); - if(ret <= 0) - goto ex; - } else if(strcmp(argv[i], "-boot-load-size") == 0) { - if(i+1>=argc) - goto not_enough_args; - i++; - sscanf(argv[i], "%d", &ret); - xorriso->boot_image_load_size= ret * 512; - } else if(strncmp(argv[i], "isolinux_mbr=", 13)==0) { - sprintf(sfe, "isohybrid=%s", argv[i] + 13); - ret= Xorriso_option_boot_image(xorriso, "isolinux", sfe, 0); - if(ret <= 0) - goto problem_handler_boot; - } else if(strcmp(argv[i], "-eltorito-alt-boot")==0) { - ret= Xorriso_genisofs_add_boot(xorriso, whom, - &option_b, &no_emul_boot, 0); - if(ret <= 0) - goto problem_handler_boot; - } else if(strcmp(argv[i], "--embedded-boot")==0 || - strcmp(argv[i], "-generic-boot")==0 || - strcmp(argv[i], "-G") == 0 || - strcmp(argv[i], "-isohybrid-mbr")==0) { - if(i+1>=argc) - goto not_enough_args; - i++; - ret= Xorriso_set_system_area_path(xorriso, argv[i], 0); - if(ret <= 0) - goto problem_handler_boot; - if(strcmp(argv[i - 1], "-isohybrid-mbr")==0) - xorriso->system_area_options= (xorriso->system_area_options & ~3) | 2; - } else if(strcmp(argv[i], "--protective-msdos-label")==0) { - xorriso->system_area_options= (xorriso->system_area_options & ~3) | 1; - } - continue; /* regular bottom of loop */ -problem_handler_boot:; - /* Problem handler */ - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - goto ex; - } - if(xorriso->boot_image_bin_path[0]) { - ret= Xorriso_genisofs_add_boot(xorriso, whom, &option_b, &no_emul_boot, 0); - if(ret <= 0) - goto ex; - } - - ret= !was_failure; -ex:; - if(was_path && !do_print_size) - Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count, - xorriso->pacifier_total, "", 1); - if(do_print_size && xorriso->volset_change_pending) - Xorriso_option_rollback(xorriso, 0); - if(weight_list != NULL) - free(weight_list); - if(boot_opt_list != NULL) - free(boot_opt_list); - return(ret); -} - - -int Xorriso_as_genisofs(struct XorrisO *xorriso, int argc, char **argv, - int *idx, int flag) -{ - int end_idx, ret, idx_count, old_idx; - - old_idx= *idx; - end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); - (*idx)= end_idx; - idx_count= end_idx-old_idx; - if(end_idx<=0 || old_idx>=argc) - return(1); - ret= Xorriso_genisofs(xorriso, "genisofs", end_idx-old_idx, argv+old_idx, 0); - return(ret); -} - - -int Xorriso_as_cdrskin(struct XorrisO *xorriso, int argc, char **argv, - int *idx, int flag) -{ - int end_idx, ret, idx_count, old_idx; - - old_idx= *idx; - end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); - (*idx)= end_idx; - idx_count= end_idx-old_idx; - if(end_idx<=0 || old_idx>=argc) - return(1); - ret= Xorriso_cdrskin(xorriso, "cdrskin", end_idx-old_idx, argv+old_idx, 0); - 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; iSfileadrL) { - 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; iinfo_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); -} - - -int Xorriso_write_session_log(struct XorrisO *xorriso, int flag) -{ - FILE *fp= NULL; - char sfe[5*SfileadrL], timetext[40], *rpt, *wpt; - - if(xorriso->session_logfile[0]==0) - return(2); - fp= fopen(xorriso->session_logfile, "a"); - if(fp==0) { - sprintf(xorriso->info_text, "-session_log: Cannot open file %s", - Text_shellsafe(xorriso->session_logfile, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - wpt= sfe; - for(rpt= xorriso->volid; *rpt!=0; rpt++) { - if(*rpt=='\n') { - *(wpt++)= '\\'; - *(wpt++)= 'n'; - } else - *(wpt++)= *rpt; - } - *wpt= 0; - fprintf(fp, "%s %d %d %s\n", - Ftimetxt(time(0), timetext, 2), xorriso->session_lba, - xorriso->session_blocks, sfe); - fclose(fp); - return(1); -} - - -/* @param flag bit0= path is a command parameter -*/ -int Xorriso_path_is_excluded(struct XorrisO *xorriso, char *path, int flag) -{ - int ret; - char sfe[5*SfileadrL]; - - if(!(xorriso->disk_excl_mode&1)) /* exclusion is off */ - return(0); - if((flag&1) && !(xorriso->disk_excl_mode&2)) /* params are exempted */ - return(0); - ret= Exclusions_match(xorriso->disk_exclusions, path, - !!(xorriso->disk_excl_mode&4)); - if(ret<0) { - sprintf(xorriso->info_text, - "Error during disk file exclusion decision"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - } - if(ret>0 && (flag&1)) { - sprintf(xorriso->info_text, "Disk path parameter excluded by %s : %s", - (ret==1 ? "-not_paths" : "-not_leaf"), Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - } - return(ret); -} - - -/* @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) -{ - char *cpt; - - cpt= strrchr(orig_path, '/'); - if(cpt==NULL) - tmp_path[0]= 0; - else { - strncpy(tmp_path, orig_path, cpt+1-orig_path); - tmp_path[cpt+1-orig_path]= 0; - } - strcat(tmp_path, "_tmp_xorriso_restore_XXXXXX"); - *fd= mkstemp(tmp_path); - if(*fd==-1) { - if(errno == EACCES && (flag & 128)) - return(4); - strcpy(xorriso->info_text, "Cannot create temporary file : "); - Text_shellsafe(tmp_path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - return(0); - } - fchmod(*fd, S_IRUSR|S_IWUSR); - return(1); -} - - -/* @param flag bit0= change regardless of xorriso->do_auto_chmod - bit1= desired is only rx - @return -1=severe error , -2= cannot chmod, 0= nothing to do, 1 = chmoded -*/ -int Xorriso_auto_chmod(struct XorrisO *xorriso, char *disk_path, int flag) -{ - int ret, is_link= 0; - char *path_pt, sfe[5*SfileadrL], link_target[SfileadrL]; - mode_t mode, desired= S_IRUSR | S_IWUSR | S_IXUSR; - struct stat stbuf; - - if(!(xorriso->do_auto_chmod || (flag & 1))) - return(0); - - if(flag & 2) - desired &= ~S_IWUSR; - path_pt= disk_path; - ret= lstat(path_pt, &stbuf); - if(ret==-1) - return(0); - if(S_ISLNK(stbuf.st_mode)) { - is_link= 1; - ret= stat(path_pt, &stbuf); - if(ret==-1) - return(0); - } - if(!S_ISDIR(stbuf.st_mode)) - return(0); - if(is_link) { - ret= Xorriso_resolve_link(xorriso, path_pt, link_target, 0); - if(ret<=0) - return(ret); - path_pt= link_target; - } - if((stbuf.st_mode & desired) == desired) - return(0); - if(stbuf.st_uid!=geteuid()) - return(-2); - - mode= (stbuf.st_mode | desired) & 07777; - ret= chmod(path_pt, mode); - if(ret==-1) { - sprintf(xorriso->info_text, - "Cannot change access permissions of disk directory: chmod %o %s", - (unsigned int) (mode & 07777), Text_shellsafe(path_pt, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "SORRY", 0); - return(-2); - } - ret= Permstack_push(&(xorriso->perm_stack), path_pt, &stbuf, 0); - if(ret<=0) - return(ret); - return(1); -} - - -int Xorriso_make_accessible(struct XorrisO *xorriso, char *disk_path, int flag) -{ - int done= 0, ret, just_rx= 2; - char *npt, *apt, path[SfileadrL], *wpt; - - apt= disk_path; - wpt= path; - for(npt= apt; !done; apt= npt + 1) { - npt= strchr(apt, '/'); - if(npt == NULL) - break; - if(strchr(npt + 1, '/') == NULL) - just_rx= 0; - strncpy(wpt, apt, npt + 1 - apt); - wpt+= npt + 1 - apt; - *wpt= 0; - ret= Xorriso_auto_chmod(xorriso, path, just_rx); - if(ret == -1) - return(-1); - if(ret == -2) - return(0); - } - return(1); -} - - -/* @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 li; - struct Xorriso_lsT *s, *d, *found_s= NULL, *found_d= NULL; - char *ipfx, *dpfx; - - /* Obtain disk_path by replacing start piece of img_path */ - - d= *disk_prefixes; - for(s= *img_prefixes; s != NULL; - s= Xorriso_lst_get_next(s, 0), d= Xorriso_lst_get_next(d, 0)) { - - ipfx= Xorriso_lst_get_text(s, 0); - li= strlen(ipfx); - dpfx= Xorriso_lst_get_text(d, 0); - if(strncmp(img_path, ipfx, li) != 0) - continue; - if(img_path[li] != 0 && img_path[li] != '/') - continue; - if(strlen(dpfx) + strlen(img_path) - li + 1 >= SfileadrL) - return(-1); - if(img_path[li]=='/') - sprintf(disk_path, "%s/%s", dpfx, img_path + strlen(ipfx) + 1); - else - strcpy(disk_path, dpfx); - found_s= s; - found_d= d; - if(s != *img_prefixes || !(flag & 1)) - break; - } - *img_prefixes= found_s; - *disk_prefixes= found_d; - return(found_s != NULL); -} - - -/* @param flag bit0=permission to run Xorriso_make_accessible -*/ -int Xorriso_restore_make_hl(struct XorrisO *xorriso, - char *old_path, char *new_path, int flag) -{ - int ret; - struct PermiteM *perm_stack_mem; - - ret= link(old_path, new_path); - if(ret == 0) - return(1); - if(errno == EACCES && (flag & 1)) { - perm_stack_mem= xorriso->perm_stack; - ret= Xorriso_make_accessible(xorriso, new_path, 0); - if(ret > 0) { - ret= link(old_path, new_path); - if(ret == 0) { - Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0); - return(1); - } - } - Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0); - } - - sprintf(xorriso->info_text, "Hardlinking failed: "); - Text_shellsafe(new_path, xorriso->info_text, 1); - strcat(xorriso->info_text, " -> "); - Text_shellsafe(old_path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "WARNING", 0); - return(0); -} - - -/* @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) -{ - struct SectorbitmaP *m; - int map_sectors= -1, map_sector_size= -1, valid; - int list_sectors, list_blocks, sector_size, sector_blocks; - int replace_map= 0, count, i, lba, blocks, quality, ret, pass; - - sector_size= Spotlist_sector_size(spotlist, read_chunk, 0); - sector_blocks= sector_size / 2048; - if(*map != NULL) - Sectorbitmap_get_layout(*map, &map_sectors, &map_sector_size, 0); - - count= Spotlist_count(spotlist, 0); - list_blocks= Spotlist_block_count(spotlist, 0); - - /* >>> ??? insist in list_blocks % sector_blocks == 0 */ - - list_sectors= list_blocks / sector_blocks; - if(list_sectors * sector_blocks < list_blocks) - list_sectors++; - if(*map != NULL && map_sectors * (map_sector_size / 2048) >= list_blocks && - map_sector_size == sector_size) - m= *map; - else { - if(*map != NULL) { - if(((off_t) (*map)->sectors) * ((off_t) (*map)->sector_size) > - ((off_t) list_sectors) * ((off_t) sector_size)) - list_sectors= (((off_t) (*map)->sectors) * - ((off_t) (*map)->sector_size)) / ((off_t) sector_size) - + 1; - } - ret= Sectorbitmap_new(&m, list_sectors, sector_size, 0); - if(ret <= 0) - return(-1); - replace_map= 1; - if(*map != NULL) { - ret= Sectorbitmap_copy(*map, m, 0); - if(ret <= 0) { - Sectorbitmap_destroy(&m, 0); - return(0); - } - } - } - - count= Spotlist_count(spotlist, 0); - /* first set good bits, then eventually override by bad bits */ - for(pass= 0; pass < 2; pass++) { - for(i= 0; i < count; i++) { - ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0); - if(ret <= 0) - continue; - valid= quality > xorriso->check_media_bad_limit; - if(quality == Xorriso_read_quality_untesteD && (flag & 1)) - valid= 1; - else if(pass == 0 && !valid) - continue; - else if(pass == 1 && valid) - continue; - Sectorbitmap_set_range(m, lba / sector_blocks, blocks / sector_blocks, - valid); - } - } - if(replace_map) { - Sectorbitmap_destroy(map, 0); - *map= m; - } - return(1); -} - - -int Xorriso_sectormap_to_spotlist(struct XorrisO *xorriso, - struct CheckmediajoB *job, - struct SpotlisT **spotlist, - int flag) -{ - struct SectorbitmaP *map; - int ret, i, sectors, sector_size, value, old_value= -1, old_start= -1; - - map= job->sector_map; - if(map == NULL) - return(-1); - ret= Spotlist_new(spotlist, 0); - if(ret <= 0) - {ret= -1; goto ex;} - Sectorbitmap_get_layout(map, §ors, §or_size, 0); - sector_size/= 2048; - if(job->max_lba >= 0) - sectors= (job->max_lba + 1) / sector_size; - i= 0; - if(job->min_lba >= 0) - i= job->min_lba / sector_size; - for(; i < sectors; i++) { - value= Sectorbitmap_is_set(map, i, 0); - if(value == old_value) - continue; - if(old_value >= 0) { - ret= Spotlist_add_item(*spotlist, old_start, i * sector_size - old_start, - (old_value ? Xorriso_read_quality_valiD : - Xorriso_read_quality_invaliD), 0); - if(ret <= 0) - goto ex; - if(job->item_limit > 0 && - Spotlist_count(*spotlist, 0) + 1 >= job->item_limit) { - sprintf(xorriso->info_text, "-check_media: Reached item_limit=%d", - job->item_limit); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - if(sectors - i > 1) { - ret= Spotlist_add_item(*spotlist, i * sector_size, - (sectors - i - 1) * sector_size, - Xorriso_read_quality_untesteD, 0); - if(ret <= 0) - goto ex; - } - ret= 2; goto ex; - } - } - old_value= value; - old_start= i * sector_size; - } - if(old_value >= 0) { - ret= Spotlist_add_item(*spotlist, old_start, i * sector_size - old_start, - (old_value ? Xorriso_read_quality_valiD : - Xorriso_read_quality_invaliD), 0); - if(ret <= 0) - goto ex; - } - ret= 1; -ex:; - if(ret <= 0) - Spotlist_destroy(spotlist, 0); - return(ret); -} - - -int Xorriso_afile_fopen(struct XorrisO *xorriso, - char *filename, char *mode, FILE **ret_fp, int flag) -/* - bit0= do not print error message on failure - bit1= do not open stdin -*/ -{ - FILE *fp= NULL; - - *ret_fp= NULL; - if(strcmp(filename,"-")==0) { - if(mode[0]=='a' || mode[0]=='w' || - (mode[0]=='r' && mode[1]=='+') || - (mode[0]=='r' && mode[1]=='b' && mode[2]=='+')) - fp= stdout; - else if(flag & 2) { - Xorriso_msgs_submit(xorriso, 0, "Not allowed as input path: '-'", 0, - "FAILURE", 0); - return(0); - } else { - Xorriso_msgs_submit(xorriso, 0, "Ready for data at standard input", 0, - "NOTE", 0); - fp= stdin; - } - } else if(strncmp(filename,"tcp:",4)==0){ - Xorriso_msgs_submit(xorriso, 0, "TCP/IP service isn't implemented yet.", 0, - "FAILURE", 0); - } else if(strncmp(filename,"file:",5)==0){ - fp= fopen(filename+5,mode); - } else { - fp= fopen(filename,mode); - } - if(fp==NULL){ - if(!(flag&1)) { - sprintf(xorriso->info_text, - "Failed to open file '%s' in %s mode\n", filename, mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - } - return(0); - } - *ret_fp= fp; - return(1); -} - - -/* @param flag bit2=do not try to read ISO heads -*/ -int Xorriso_toc_to_string(struct XorrisO *xorriso, char **toc_text, int flag) -{ - int ret, stack_handle, toc_ret, l; - struct Xorriso_lsT *results= NULL, *infos= NULL, *lpt; - - *toc_text= NULL; - ret= Xorriso_push_outlists(xorriso, &stack_handle, 1); - if(ret <= 0) - goto ex; - toc_ret= Xorriso_toc(xorriso, flag & 4); - ret= Xorriso_pull_outlists(xorriso, stack_handle, &results, &infos, 0); - if(ret <= 0) - goto ex; - if(toc_ret <= 0) - {ret= toc_ret; goto ex;} - l= 0; - for(lpt= results; lpt != NULL; lpt= Xorriso_lst_get_next(lpt, 0)) - l+= strlen(Xorriso_lst_get_text(lpt, 0)); - *toc_text= calloc(l + 1, 1); - l= 0; - for(lpt= results; lpt != NULL; lpt= Xorriso_lst_get_next(lpt, 0)) { - strcpy((*toc_text) + l, Xorriso_lst_get_text(lpt, 0)); - l+= strlen(Xorriso_lst_get_text(lpt, 0)); - } -ex:; - Xorriso_lst_destroy_all(&results, 0); - Xorriso_lst_destroy_all(&infos, 0); - return(ret); -} - - -int Xorriso_open_job_data_to(struct XorrisO *xorriso, - struct CheckmediajoB *job, int flag) -{ - char sfe[5*SfileadrL]; - - if(job->data_to_path[0] == 0) - return(2); - job->data_to_fd= open(job->data_to_path, O_RDWR | O_CREAT, - S_IRUSR | S_IWUSR); - if(job->data_to_fd == -1) { - sprintf(xorriso->info_text, "Cannot open path %s", - Text_shellsafe(job->data_to_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - return(0); - } - return(1); -} - -/* - @param flag bit0= make absolute command paths with known systems - bit1= do not allow prefixes with cmd - bit2= interpret unprefixed cmd as shell: -*/ -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 ret, reg_file= 0, is_safe= 0, sys_code= 0; - char form[6*SfileadrL], session_text[12], track_text[12], lba_text[12]; - char *vars[5][2], sfe[5*SfileadrL], volid_sfe[5*80+1], *cpt, *sysname; - struct stat stbuf; - - if(strlen(cmd) > SfileadrL) { -/* -too_long:; -*/ - Xorriso_msgs_submit(xorriso, 0, "Argument much too long", 0, "FAILURE", 0); - return(0); - } - ret= stat(devadr, &stbuf); - if(ret != -1) - if(S_ISREG(stbuf.st_mode)) - reg_file= 1; - if(strncmp(cmd, "linux:", 6) == 0 && !(flag & 2)) { - cpt= cmd + 6; - sys_code= 1; - } else if(strncmp(cmd, "freebsd:", 8) == 0 && !(flag & 2)) { - cpt= cmd + 8; - sys_code= 2; - } else if(strncmp(cmd, "string:", 7) == 0 && !(flag & 2)) { - cpt= cmd + 7; - strcpy(form, cpt); - } else if(flag & 4) { - cpt= cmd; - strcpy(form, cpt); - } else { - cpt= cmd; - ret= System_uname(&sysname, NULL, NULL, NULL, 0); - if(ret <= 0) { - Xorriso_msgs_submit(xorriso, 0, - "-mount*: Cannot determine current system type", - 0, "FAILURE", 0); - return(0); - } else if(strcmp(sysname, "FreeBSD") == 0 || - strcmp(sysname, "GNU/kFreeBSD") == 0) { - /* "GNU/kFreeBSD" = Debian kfreebsd */ - sys_code= 2; - } else if(strcmp(sysname, "Linux") == 0) { - sys_code= 1; - } else { - sprintf(xorriso->info_text, "-mount*: Unsupported system type %s", - Text_shellsafe(sysname, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - } - - if(sys_code == 1) { /* GNU/Linux */ - sprintf(form, - "%smount -t iso9660 -o %snodev,noexec,nosuid,ro,sbsector=%%sbsector%% %%device%% %s", - (flag & 1 ? "/bin/" : ""), - (reg_file || (xorriso->mount_opts_flag & 1) ? "loop," : ""), - Text_shellsafe(cpt, sfe, 0)); - is_safe= 1; - } else if(sys_code == 2) { /* FreeBSD */ - if(reg_file) { - -/* <<< Considered to create vnode as of - J.R. Oldroyd , 20 Nov 2008 - but for now refraining from creating that persistent file object - - strcpy(form, "n=$(mdconfig -a -t vnode -f %device%)"); - sprintf(form + strlen(form), - " && mount -t cd9660 -o noexec,nosuid -s %%sbsector%% /dev/\"$n\" %s", - Text_shellsafe(cmd+8, sfe, 0)); -*/ - - Xorriso_msgs_submit(xorriso, 0, - "Detected regular file as mount device with FreeBSD style command.", - 0, "FAILURE", 0); - Xorriso_msgs_submit(xorriso, 0, -"Command mdconfig -a -t vnode -f can create a device node which uses the file", - 0, "HINT", 0); - return(0); - } else { - sprintf(form, - "%smount_cd9660 -o noexec,nosuid -s %%sbsector%% %%device%% %s", - (flag & 1 ? "/sbin/" : ""), Text_shellsafe(cmd+8, sfe, 0)); - /* - Not working on FreeBSD 7.2 according to Zsolt Kuti, 11 Oct 2009: - "%smount -t cd9660 -o noexec,nosuid -o -s %%sbsector%% %%device%% %s", - */ - } - is_safe= 1; - } - sprintf(session_text, "%d", session); - sprintf(track_text, "%d", track); - sprintf(lba_text, "%d", lba); - vars[0][0]= "sbsector"; - vars[0][1]= lba_text; - vars[1][0]= "track"; - vars[1][1]= track_text; - vars[2][0]= "session"; - vars[2][1]= session_text; - vars[3][0]= "volid"; - vars[3][1]= Text_shellsafe(volid, volid_sfe, 0); - vars[4][0]= "device"; - vars[4][1]= Text_shellsafe(devadr, sfe, 0); - ret= Sregex_resolve_var(form, vars, 5, "%", "%", "%", result, SfileadrL, 0); - if(ret <= 0) - return(ret); - return(1 + is_safe); -} - - -/* @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) -{ - double num; - int l; - - if(strcmp(adr_mode, "auto")==0) - *entity_code= 0; - else if(strcmp(adr_mode, "session")==0) - *entity_code= 1; - else if(strcmp(adr_mode, "track")==0) - *entity_code= 2; - else if(strcmp(adr_mode, "lba")==0 || strcmp(adr_mode, "sbsector")==0) - *entity_code= 3 | ((flag&1) << 16); - else if(strcmp(adr_mode, "volid")==0) - *entity_code= 4; - else { - sprintf(xorriso->info_text, "%s: unknown address mode '%s'", cmd, adr_mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - l= strlen(adr_value); - if(l==0) - *entity_code= 0; - - if(*entity_code>=1 && *entity_code<= 3) { - num= Scanf_io_size(adr_value, 0); - if(*entity_code==3 && - (adr_value[l-1]<'0' || adr_value[l-1]>'9')) - num/= 2048.0; - sprintf(entity_id, "%.f", num); - } else { - if(strlen(adr_value)>80) { - sprintf(xorriso->info_text, "%s: address value too long (80 < %d)", - cmd, (int) strlen(adr_value)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - strcpy(entity_id, adr_value); - } - return(1); -} - - -/* - @param flag bit0= use env_path to find the desired program -return: - <=0 : error - 1 : done -*/ -int Xorriso_execv(struct XorrisO *xorriso, char *cmd, char *env_path, - int *status, int flag) -{ - int ret, argc= 0; - char **argv= NULL, *pathlist= NULL, *cpt, *npt, prog[SfileadrL]; - char sfe[5*SfileadrL]; - pid_t child_pid; - struct stat stbuf; - - wait3(NULL,WNOHANG,NULL); /* just to remove any old dead child */ - - ret= Sfile_make_argv("", cmd, &argc, &argv, 1|4|128); - if(ret <= 0) - goto ex; - if(argc < 1) - {ret= 0; goto ex;} - - strcpy(prog, argv[0]); - if((flag & 1) && strchr(argv[0], '/') == NULL) { - if(env_path == NULL) - env_path= "/bin:/sbin"; - else if(env_path[0] == 0) - env_path= "/bin:/sbin"; - if(Sregex_string(&pathlist, env_path, 0) <= 0) - {ret= -1; goto ex;} - for(cpt= npt= pathlist; npt != NULL; cpt= npt + 1) { - npt= strchr(cpt, ':'); - if(npt != NULL) - *npt= 0; - if(strlen(cpt) + strlen(argv[0]) + 1 >= SfileadrL) - {ret= -1; goto ex;} - sprintf(prog, "%s/%s", cpt, argv[0]); - ret= stat(prog, &stbuf); - if(ret != -1) - break; - prog[0]= 0; - } - if(prog[0] == 0) { - sprintf(xorriso->info_text, "Cannot find external program %s", - Text_shellsafe(argv[0], sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - } - - child_pid= fork(); - if(child_pid==-1) - return(-1); - - if(child_pid==0) { - /* this is the child process */ - - sprintf(xorriso->info_text, "Executing external program %s", - Text_shellsafe(prog, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - - execv(prog, argv); /* should never come back */ - fprintf(stderr,"--- execution of shell command failed:\n"); - fprintf(stderr," %s\n",cmd); - exit(127); - } - - - /* this is the original process waiting for child to exit */ - do { - /* try to read and print the reply */; - ret= waitpid(child_pid,status,WNOHANG); - if(ret==-1) { - if(errno!=EINTR) - ret= 0; goto ex; - } else if(ret==0) { - -#ifdef NIX - - /* >>> An interrupt key would be nice. */ - - if((flag&4)) { - ret= Asqueue_event_is_pending(agent->queue,0,0); - if(ret>0) { - Asagent_stderr(agent,"--- shell command interrupted",1); - kill(child_pid,SIGTERM); - ret= 2; goto ex; - } - } -#endif /* NIX */ - - continue; - } else { - break; - } - } while(1); - ret= 1; -ex: - Sfile_make_argv("", "", &argc, &argv, 2); - Sregex_string(&pathlist, NULL, 0); - return(ret); -} - - -/* 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 ret, access_count= 0, default_count= 0, pass, is_default, line_len; - int was_error= 0, line_count= 0, perms; - char *acl_text= NULL, *cpt, *npt, *access_wpt= NULL, *default_wpt= NULL; - char *dpt= NULL, *ddpt= NULL, **wpt, *ppt; - - if(in_text[0] == 0 || strcmp(in_text, "clear") == 0 || - strcmp(in_text, "--remove-all") == 0) { - *access_acl_text= *default_acl_text= NULL; - return(1); - } else if (strcmp(in_text, "--remove-default") == 0) { - - /* >>> protect Access-ACL and delete Default-ACL */; - - /* <<< */ - return(0); - - } - - acl_text= strdup(in_text); - if(acl_text == NULL) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - {ret= -1; goto ex;} - } - - /* From comma to newline */ - for(cpt= strchr(acl_text, ','); cpt != NULL; cpt= strchr(cpt + 1, ',')) - *cpt= '\n'; - - /* Normalize to long text form - and sort apart "access" ACL from "default" ACL */; - for(pass= 0; pass < 2; pass++) { - line_count= 0; - for(cpt= acl_text; cpt != NULL; cpt= npt) { - line_count++; - npt= strchr(cpt, '\n'); - if(npt != NULL) - npt++; - if(*cpt == '#' || *cpt == '\n' || *cpt == 0) - continue; - - is_default= 0; - wpt= &access_wpt; - if(*cpt == 'd') { - is_default= 1; - if(pass == 1) - wpt= &default_wpt; - cpt= strchr(cpt, ':'); - if(cpt == NULL) { - was_error= line_count; - continue; - } - cpt++; - } - - line_len= 0; - dpt= strchr(cpt, ':'); - if(dpt != NULL) - ddpt= strchr(dpt + 1, ':'); - if(dpt == NULL || ddpt == NULL) { - was_error= line_count; - continue; - } - if(*cpt == 'u') { - if(pass == 0) { - line_len+= 5; - line_len+= ddpt - dpt; - } else { - strcpy(*wpt, "user:"); - strncpy(*wpt + 5, dpt + 1, ddpt - dpt); - (*wpt)+= 5 + (ddpt - dpt); - } - } else if(*cpt == 'g') { - if(pass == 0) { - line_len+= 6 + (ddpt - dpt); - } else { - strcpy(*wpt, "group:"); - strncpy(*wpt + 6, dpt + 1, ddpt - dpt); - (*wpt)+= 6 + (ddpt - dpt); - } - } else if(*cpt == 'o') { - if(pass == 0) { - if(ddpt - dpt > 1) { - was_error= line_count; - continue; - } - line_len+= 6 + (ddpt - dpt); - } else { - strcpy(*wpt, "other:"); - strncpy(*wpt + 6, dpt + 1, ddpt - dpt); - (*wpt)+= 6 + (ddpt - dpt); - } - } else if(*cpt == 'm') { - if(pass == 0) { - if(ddpt - dpt > 1) { - was_error= line_count; - continue; - } - line_len+= 5 + (ddpt - dpt); - } else { - strcpy(*wpt, "mask:"); - strncpy(*wpt + 5, dpt + 1, ddpt - dpt); - (*wpt)+= 5 + (ddpt - dpt); - } - - } else { - /* Unknown tag type */ - was_error= line_count; - continue; - } - - /* Examine permissions at ddpt + 1 */; - perms= 0; - for(ppt= ddpt + 1; *ppt != 0 && *ppt != '\n'; ppt++) { - if(*ppt == 'r') - perms|= 4; - else if(*ppt == 'w') - perms|= 2; - else if(*ppt == 'x') - perms|= 1; - else if(*ppt == '-' || *ppt == ' ' || *ppt == '\t') - ; - else if(*ppt == '#') - break; - else { - was_error= line_count; - break; - } - } - if(pass == 0) { - line_len+= 4; - } else { - sprintf(*wpt, "%c%c%c\n", - perms & 4 ? 'r' : '-', perms & 2 ? 'w' : '-', perms & 1 ? 'x' : '-'); - (*wpt)+= 4; - } - - if(pass == 0) { - if(is_default) - default_count+= line_len; - else - access_count+= line_len; - } - } - - if(pass == 0) { - *access_acl_text= calloc(access_count + 1, 1); - *default_acl_text= calloc(default_count + 1, 1); - if(access_acl_text == NULL || *default_acl_text == NULL) { - Xorriso_no_malloc_memory(xorriso, access_acl_text, 0); - {ret= -1; goto ex;} - } - access_wpt= *access_acl_text; - default_wpt= *default_acl_text; - } else { - *access_wpt= 0; - *default_wpt= 0; - } - } - - ret= 1; -ex:; - if(acl_text != NULL) - free(acl_text); - if(was_error) { - sprintf(xorriso->info_text, - "Malformed ACL entries encountered. Last one in line number %d.", - was_error); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - return(ret); -} - - -int Xorriso_perform_acl_from_list(struct XorrisO *xorriso, char *file_path, - char *uid, char *gid, char *acl, int flag) -{ - int ret, zero= 0; - uid_t uid_number; - gid_t gid_number; - - /* Set group and owner */ - if(gid[0]) { - ret= Xorriso_convert_gidstring(xorriso, gid, &gid_number, 0); - if(ret<=0) - return(ret); - ret= Xorriso_set_gid(xorriso, file_path, gid_number, 0); - if(ret<=0) - return(ret); - } - if(uid[0]) { - ret= Xorriso_convert_uidstring(xorriso, uid, &uid_number, 0); - if(ret<=0) - return(ret); - ret= Xorriso_set_uid(xorriso, file_path, uid_number, 0); - if(ret<=0) - return(ret); - } - ret= Xorriso_option_setfacli(xorriso, acl, 1, &file_path, &zero, 0); - if(ret <= 0) - return(ret); - return(1); -} - - -/* - @param flag bit0= do not perform setfattr but only check input -*/ -int Xorriso_path_setfattr(struct XorrisO *xorriso, void *in_node, char *path, - char *name, size_t value_length, char *value, int flag) -{ - int ret, hflag; - size_t num_attrs= 1; - char *name_pt; - - hflag= 2; - name_pt= name; - if(name[0] == 0) { - sprintf(xorriso->info_text, - "-setfattr: Empty attribute name is not allowed"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } else if(strcmp(name, "--remove-all") == 0) { - if(value[0]) { - sprintf(xorriso->info_text, - "-setfattr: Value is not empty with pseudo name --remove-all"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - num_attrs= 0; - hflag= 0; - } else if(name[0] == '-') { - name_pt++; - hflag|= 4; - } else if(name[0] == '=' || name[0] == '+') { - name_pt++; - } - if(flag & 1) - return(1); - ret= Xorriso_setfattr(xorriso, in_node, path, - num_attrs, &name_pt, &value_length, &value, hflag); - return(ret); -} - - -/* Warning: The text content of lst gets mangled by 0s and unescaping. -*/ -int Xorriso_perform_attr_from_list(struct XorrisO *xorriso, char *path, - struct Xorriso_lsT *lst_start, int flag) -{ - int ret, eaten; - char *valuept, *ept, *line, **names= NULL, **values= NULL; - size_t num_attr= 0, *value_lengths= NULL, v_len; - struct Xorriso_lsT *lst; - - for(lst= lst_start; lst != NULL; lst= Xorriso_lst_get_next(lst, 0)) - num_attr++; - if(num_attr == 0) { - ret= Xorriso_setfattr(xorriso, NULL, path, num_attr, NULL, NULL, NULL, 0); - goto ex; - } - - names= calloc(num_attr, sizeof(char *)); - if(names == NULL) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - ret= -1; goto ex; - } - value_lengths= calloc(num_attr, sizeof(size_t)); - if(value_lengths== NULL) { - free(names); - Xorriso_no_malloc_memory(xorriso, NULL, 0); - ret= -1; goto ex; - } - values= calloc(num_attr, sizeof(char *)); - if(values== NULL) { - free(names); - free(value_lengths); - Xorriso_no_malloc_memory(xorriso, NULL, 0); - ret= -1; goto ex; - } - - num_attr= 0; - for(lst= lst_start; lst != NULL; lst= Xorriso_lst_get_next(lst, 0)) { - line= Xorriso_lst_get_text(lst, 0); - ept= strchr(line, '='); - if(ept == NULL) - continue; - /* Split into name and content */; - *ept= 0; - valuept= ept + 1; - - /* Strip quotes from value */ - v_len= strlen(valuept); - if(v_len < 2 || *valuept != '"' || *(valuept + v_len - 1) != '"') - continue; - *valuept= 0; - *(valuept + v_len - 1)= 0; - valuept++; - v_len-= 2; - - /* Unescape backslashes , values eventually with 0-bytes */ - ret= Sfile_bsl_interpreter(line, strlen(line), &eaten, 0); - if(ret <= 0) - continue; - ret= Sfile_bsl_interpreter(valuept, (int) v_len, &eaten, 2); - if(ret <= 0) - continue; - - names[num_attr]= line; - values[num_attr]= valuept; - value_lengths[num_attr]= v_len - eaten; - num_attr++; - } - ret= Xorriso_setfattr(xorriso, NULL, path, num_attr, names, - value_lengths, values, 0); -ex:; - if(names != NULL) - free(names); - if(value_lengths != NULL) - free(value_lengths); - if(values != NULL) - free(values); - return(ret); -} - - -/* @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) -{ - int i, ret, with_node_array= 0, hflag= 0, hret; - - if(!(((xorriso->ino_behavior & 16) && xorriso->do_restore_sort_lba) || - (xorriso->ino_behavior & 4) || (flag & 1))) { - ret= Xorriso_make_hln_array(xorriso, 0); - if(ret<=0) - goto ex; - } - if(xorriso->do_restore_sort_lba) { - /* Count affected nodes */ - Xorriso_destroy_node_array(xorriso, 0); - for(i= 0; i < count; i++) { - if(src_array[i] == NULL || tgt_array[i] == NULL) - continue; - /* sort_lba : Make directories plus node_array and then - run array extractor (with eventual hardlink detection) - */ - hflag= (1 << 7) | ((!!(flag & 2)) << 9); - ret= Xorriso_restore(xorriso, src_array[i], tgt_array[i], - (off_t) 0, (off_t) 0, hflag); - if(ret <= 0) { - hret= Xorriso_eval_problem_status(xorriso, ret, 0); - if(ret < 0) - goto ex; - } - with_node_array= 1; - } - } - - if(with_node_array) { - /* Allocate and fill node array */ - if(xorriso->node_counter <= 0) - {ret= 2; goto ex;} - ret= Xorriso_new_node_array(xorriso, xorriso->temp_mem_limit, 0, - !xorriso->do_restore_sort_lba); - if(ret<=0) - goto ex; - for(i= 0; i < count; i++) { - if(src_array[i] == NULL || tgt_array[i] == NULL) - continue; - ret= Xorriso_restore(xorriso, src_array[i], tgt_array[i], - (off_t) 0, (off_t) 0, 2 << 7); - if(ret <= 0) { - hret= Xorriso_eval_problem_status(xorriso, ret, 0); - if(ret < 0) - goto ex; - } - } - } - - /* Perform restore operations */ - if(xorriso->do_restore_sort_lba) { - ret= Xorriso_restore_node_array(xorriso, 0); - if(ret <= 0) - goto ex; - } else { - for(i= 0; i < count; i++) { - if(src_array[i] == NULL || tgt_array[i] == NULL) - continue; - ret= Xorriso_restore(xorriso, src_array[i], tgt_array[i], - (off_t) 0, (off_t) 0, 0); - if(ret <= 0) { - hret= Xorriso_eval_problem_status(xorriso, ret, flag & 32); - if(ret < 0) - goto ex; - } - } - } - - ret= 1; -ex:; - return(ret); -} - - -int Xorriso_report_md5_outcome(struct XorrisO *xorriso, char *severity, - int flag) -{ - int has_md5; - - has_md5= Xorriso_image_has_md5(xorriso, 0); - if(xorriso->find_check_md5_result & 1) { - sprintf(xorriso->result_line, - "Mismatch detected between file contents and MD5 checksums.\n"); - } else if(xorriso->find_check_md5_result & 8) { - sprintf(xorriso->result_line, - "File contents and their MD5 checksums match.\n"); - } else { - sprintf(xorriso->result_line, - "Not a single file with MD5 checksum was found."); - if(has_md5 <= 0) - strcat(xorriso->result_line, - " (There is no MD5 checksum array loaded.)\n"); - else - strcat(xorriso->result_line, "\n"); - } - Xorriso_result(xorriso,0); - if(xorriso->find_check_md5_result & 2) { - sprintf(xorriso->result_line, - "Encountered errors other than non-match during MD5 checking.\n"); - Xorriso_result(xorriso,0); - } - if((xorriso->find_check_md5_result & 4) && has_md5) { - sprintf(xorriso->result_line, - "There were data files which have no MD5 and thus could not be checked.\n"); - Xorriso_result(xorriso,0); - } - if((xorriso->find_check_md5_result & 3) && strcmp(severity, "ALL") != 0) { - sprintf(xorriso->info_text, "Event triggered by MD5 comparison mismatch"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, severity, 0); - } - return(1); -} - - -int Xorriso_append_scdbackup_record(struct XorrisO *xorriso, int flag) -{ - FILE *fp= NULL; - char dummy[81], name[81], timestamp[81], size[81], md5[81]; - - if(xorriso->scdbackup_tag_written[0] == 0) - return(1); - - name[0]= timestamp[0]= size[0]= md5[0]= 0; - sscanf(xorriso->scdbackup_tag_written, "%s %s %s %s %s %s %s", - dummy, dummy, dummy, name, timestamp, size, md5); - sprintf(xorriso->info_text, "scdbackup tag written : %s %s %s %s\n", - name, timestamp, size, md5); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - - if(xorriso->scdbackup_tag_listname[0]) { - fp= fopen(xorriso->scdbackup_tag_listname, "a"); - if(fp==0) { - strcpy(xorriso->info_text, "-scdbackup_tag: Cannot open file "); - Text_shellsafe(xorriso->scdbackup_tag_listname, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - fprintf(fp, "%s %s %s %s\n", name, timestamp, size, md5); - fclose(fp); - } - return(1); -} - - -int Xorriso_may_burn(struct XorrisO *xorriso, int flag) -{ - - if(xorriso->outdev_is_exclusive) - return(1); - sprintf(xorriso->info_text, "The output drive was not aquired exclusively."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - sprintf(xorriso->info_text, "A possible remedy is: -osirrox 'o_excl_on'"); - if(xorriso->outdev[0]) { - strcat(xorriso->info_text," -outdev "); - Text_shellsafe(xorriso->outdev, xorriso->info_text, 1); - } - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0); - return(0); -} - - -int Xorriso_check_name_len(struct XorrisO *xorriso, char *name, int size, - char *cmd, int flag) -{ - if(strlen(name) >= size) { - sprintf(xorriso->info_text, - "Name too long with option %s (%d > %d)", cmd, - (int) strlen(name), size - 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - return(1); -} - - -/* ---------------------------- Options API ------------------------ */ - - -/* Option -abort_on */ -int Xorriso_option_abort_on(struct XorrisO *xorriso, char *severity, int flag) -{ - int ret, sev; - char sfe[5*SfileadrL]; - - ret= Xorriso__text_to_sev(severity, &sev, 0); - if(ret<=0) { - sprintf(xorriso->info_text, - "-abort_on: Not a known severity name : %s", - Text_shellsafe(severity, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(ret); - } - if(Sfile_str(xorriso->abort_on_text,severity,0)<=0) - return(-1); - xorriso->abort_on_severity= sev; - Xorriso_set_abort_severity(xorriso, 0); - return(1); -} - - -/* Option -acl "on"|"off" */ -int Xorriso_option_acl(struct XorrisO *xorriso, char *mode, int flag) -{ - int ret; - - if(strcmp(mode, "off")==0) - xorriso->do_aaip&= ~3; - else if(strcmp(mode, "on")==0) - xorriso->do_aaip|= (1 | 2); - else { - sprintf(xorriso->info_text, "-acl: unknown mode '%s'", mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - ret= Xorriso_set_ignore_aclea(xorriso, 0); - if(ret <= 0) - return(ret); - return(1); -} - - -/* Option -add */ -/* @param flag bit0=do not report the added item - bit1=do not reset pacifier, no final pacifier message -*/ -int Xorriso_option_add(struct XorrisO *xorriso, int argc, char **argv, - int *idx, int flag) -{ - int i, end_idx, ret, was_failure= 0, fret, optc= 0, split; - char target[SfileadrL], source[SfileadrL], *ept, eff_path[SfileadrL]; - char **optv= NULL, *rpt, *wpt; - - ret= Xorriso_opt_args(xorriso, "-add", argc, argv, *idx, &end_idx, - &optc, &optv, ((!!xorriso->allow_graft_points)<<2)|2); - if(ret<=0) - goto ex; - - if(!(flag&2)) - Xorriso_pacifier_reset(xorriso, 0); - for(i= 0; iallow_graft_points) { - ret= Fileliste__target_source_limit(target, '=', &ept, 0); - if(ret>0) { - *ept= 0; - strcpy(source, ept+1); - split= 1; - } - /* unescape \= */; - if(split) - rpt= wpt= target; - else - rpt= wpt= source; - for(; *rpt!=0; rpt++) { - if(*rpt=='\\') - if(*(rpt+1)=='=') - continue; - *(wpt++)= *rpt; - } - *wpt= 0; - } - if(split==0) { - strcpy(target, source); - } else if(target[0]!='/') { - ret= Sfile_prepend_path(xorriso->wdi, target, 0); - if(ret<=0) - goto problem_handler; - } - - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, target, eff_path, 2); - if(ret<=0) - goto problem_handler; - strcpy(target, eff_path); - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, source,eff_path,2|4); - if(ret<=0) - goto problem_handler; - strcpy(source, eff_path); - - ret= Xorriso_graft_in(xorriso, NULL, source, target, (off_t)0, (off_t)0, 0); - if(ret<=0 || xorriso->request_to_abort) - goto problem_handler; - sprintf(xorriso->info_text, "Added to ISO image: %s '%s'='%s'\n", - (ret>1 ? "directory" : "file"), (target[0] ? target : "/"), source); - if(!(flag&1)) - Xorriso_info(xorriso, 0); - - continue; /* regular bottom of loop */ -problem_handler:; - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - goto ex; - } - if(!(flag&2)) - Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count, - xorriso->pacifier_total, "", 1); - ret= 1; -ex:; - (*idx)= end_idx; - Xorriso_opt_args(xorriso, "-add", argc, argv, *idx, &end_idx, &optc, &optv, - 256); - if(ret<=0) - return(ret); - return(!was_failure); -} - - -/* Option -add_plainly "none"|"unknown" */ -int Xorriso_option_add_plainly(struct XorrisO *xorriso, char *mode,int flag) -{ - if(strcmp(mode, "none")==0) - xorriso->add_plainly= 0; - if(strcmp(mode, "unknown")==0) - xorriso->add_plainly= 1; - else if(strcmp(mode, "dashed")==0) - xorriso->add_plainly= 2; - else if(strcmp(mode, "any")==0) - xorriso->add_plainly= 3; - else { - sprintf(xorriso->info_text, "-add_plainly: unknown mode '%s'", mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - return(1); -} - - -/* Option -alter_date , -alter_date_r */ -/* @param flag bit0=recursive (-alter_date_r) -*/ -int Xorriso_option_alter_date(struct XorrisO *xorriso, - char *time_type, char *timestring, - int argc, char **argv, int *idx, int flag) -{ - int i, ret, was_failure= 0, t_type= 0, end_idx, fret; - time_t t; - int optc= 0; - char **optv= NULL; - struct FindjoB *job= NULL; - struct stat dir_stbuf; - - ret= Xorriso_opt_args(xorriso, "-alter_date", argc, argv, *idx, &end_idx, - &optc, &optv, 0); - if(ret<=0) - goto ex; - ret= Xorriso_convert_datestring(xorriso, "-alter_date", time_type, timestring, - &t_type, &t, 0); - if(ret<=0) - goto ex; - for(i= 0; i0 && !xorriso->request_to_abort) - continue; /* regular bottom of loop */ - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - goto ex; - } - ret= 1; -ex:; - (*idx)= end_idx; - Xorriso_opt_args(xorriso, "-alter_date", argc, argv, *idx, &end_idx, &optc, - &optv, 256); - Findjob_destroy(&job, 0); - if(ret<=0) - return(ret); - return(!was_failure); -} - - -/* Option -application_id */ -int Xorriso_option_application_id(struct XorrisO *xorriso, char *name, - int flag) -{ - if(Xorriso_check_name_len(xorriso, name, - (int) sizeof(xorriso->application_id), - "-application_id", 0) <= 0) - return(0); - strcpy(xorriso->application_id,name); - Xorriso_set_change_pending(xorriso, 1); - return(1); -} - - -/* Option -as */ -/* @param flag bit0=do not report the added item - bit1=do not reset pacifier, no final pacifier message -*/ -int Xorriso_option_as(struct XorrisO *xorriso, int argc, char **argv, - int *idx, int flag) -{ - int end_idx, ret, idx_count; - - end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); - idx_count= end_idx-(*idx); - if(end_idx<=0 || (*idx)>=argc) { - if(idx_count<1) - sprintf(xorriso->info_text, - "-as : Not enough arguments given. Needed: whom do_what %s", - xorriso->list_delimiter); - else - sprintf(xorriso->info_text, - "-as %s : Not enough arguments given. Needed: do_what %s", - argv[*idx], xorriso->list_delimiter); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - if(strcmp(argv[*idx], "cdrecord")==0 || strcmp(argv[*idx], "wodim")==0 || - strcmp(argv[*idx], "cdrskin")==0 || strcmp(argv[*idx], "xorrecord")==0) { - ret= Xorriso_cdrskin(xorriso, argv[*idx], end_idx-(*idx)-1, argv+(*idx)+1, - 0); - if(ret<=0) - goto ex; - } else if(strcmp(argv[*idx], "mkisofs")==0 || - strcmp(argv[*idx], "genisoimage")==0 || - strcmp(argv[*idx], "genisofs")==0 || - strcmp(argv[*idx], "xorrisofs")==0) { - ret= Xorriso_genisofs(xorriso, argv[*idx], end_idx-(*idx)-1, argv+(*idx)+1, - 0); - if(ret<=0) - goto ex; - } else { - sprintf(xorriso->info_text, - "-as : Not a known emulation personality: '%s'", argv[*idx]); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - - ret= 1; -ex:; - (*idx)= end_idx; - return(ret); -} - - -/* Option -assert_volid */ -int Xorriso_option_assert_volid(struct XorrisO *xorriso, char *pattern, - char *severity, int flag) -{ - int ret, sev; - char *sev_text= ""; - - if(strlen(pattern)>=sizeof(xorriso->assert_volid)) { - sprintf(xorriso->info_text, - "Name too long with option -application_id (%d > %d)", - (int) strlen(pattern), (int) sizeof(xorriso->assert_volid)-1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - if(pattern[0]) { - ret= Sregex_match(pattern, "", 1); - if(ret <= 0) { - sprintf(xorriso->info_text, "-assert_volid: Cannot use given pattern."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - } - if(severity[0] != 0 || pattern[0] != 0) { - if(severity[0] == 0) - sev_text= xorriso->abort_on_text; - else - sev_text= severity; - if(strcmp(sev_text, "NEVER") == 0) - sev_text= "ABORT"; - ret= Xorriso__text_to_sev(sev_text, &sev, 0); - if(ret<=0) { - sprintf(xorriso->info_text, "-assert_volid: Not a known severity name : "); - Text_shellsafe(severity, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(ret); - } - } - if(Sfile_str(xorriso->assert_volid, pattern,0) <= 0) - return(-1); - strcpy(xorriso->assert_volid_sev, sev_text); - return(1); -} - - -/* Option -auto_charset "on"|"off" */ -int Xorriso_option_auto_charset(struct XorrisO *xorriso, char *mode, int flag) -{ - if(strcmp(mode, "off")==0) - xorriso->do_aaip&= ~(256 | 512); - else if(strcmp(mode, "on")==0) - xorriso->do_aaip|= (256 | 512); - else { - sprintf(xorriso->info_text, "-auto_charset: unknown mode '%s'", mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - return(1); -} - - -/* Option -backslash_codes */ -int Xorriso_option_backslash_codes(struct XorrisO *xorriso, char *mode, - int flag) -{ - char *npt, *cpt; - int l, was; - - was= xorriso->bsl_interpretation; - xorriso->bsl_interpretation= 0; - npt= cpt= mode; - for(; npt!=NULL; cpt= npt+1) { - npt= strchr(cpt,':'); - if(npt==NULL) - l= strlen(cpt); - else - l= npt-cpt; - if(l == 0) - continue; - if(l == 3 && strncmp(cpt, "off", l)==0) { - xorriso->bsl_interpretation= 0; - } else if(l == 16 && strncmp(cpt, "in_double_quotes", l)==0) { - xorriso->bsl_interpretation= (xorriso->bsl_interpretation & ~3) | 1; - } else if(l == 9 && strncmp(cpt, "in_quotes", l)==0) { - xorriso->bsl_interpretation= (xorriso->bsl_interpretation & ~3) | 2; - } else if(l == 17 && strncmp(cpt, "with_quoted_input", l)==0) { - xorriso->bsl_interpretation= (xorriso->bsl_interpretation & ~3) | 3; - } else if(l == 22 && strncmp(cpt, "with_program_arguments", l)==0) { - xorriso->bsl_interpretation= xorriso->bsl_interpretation | 16; - } else if(l == 13 && strncmp(cpt, "encode_output", l)==0) { - xorriso->bsl_interpretation= xorriso->bsl_interpretation | 32 | 64; - } else if(l == 14 && strncmp(cpt, "encode_results", l)==0) { - xorriso->bsl_interpretation= xorriso->bsl_interpretation | 32; - } else if(l == 12 && strncmp(cpt, "encode_infos", l)==0) { - xorriso->bsl_interpretation= xorriso->bsl_interpretation | 64; - } else if(l == 2 && strncmp(cpt, "on", l)==0) { - xorriso->bsl_interpretation= 3 | 16 | 32 | 64; - } else { - if(linfo_text, "-backslash_codes: unknown mode '%s'", cpt); - else - sprintf(xorriso->info_text, - "-backslash_codes: oversized mode parameter (%d)", l); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - xorriso->bsl_interpretation= was; - return(0); - } - } - return(1); -} - - -/* Option -ban_stdio_write */ -int Xorriso_option_ban_stdio_write(struct XorrisO *xorriso, int flag) -{ - xorriso->ban_stdio_write= 1; - return(1); -} - - -/* Option -blank and -format */ -/* @param flag bit0= format rather than blank - @return <=0 error , 1 success, 2 revoked by -reassure -*/ -int Xorriso_option_blank(struct XorrisO *xorriso, char *mode, int flag) -{ - char drive_name[SfileadrL], *cmd= "-blank"; - int aq_ret, ret, aq_flag= 2, mode_flag= 0, as_needed= 0, idx; - off_t size= 0; - - if(flag&1) - cmd= "-format"; - if(xorriso->out_drive_handle == NULL) { - sprintf(xorriso->info_text, - "%s: No output drive set by -dev -or -outdev", cmd); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - if(xorriso->in_drive_handle == xorriso->out_drive_handle) { - if(xorriso->volset_change_pending) { - sprintf(xorriso->info_text, - "%s: Image changes pending. -commit or -rollback first.", cmd); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - aq_flag= 3; - } - ret= Xorriso_reassure(xorriso, cmd, - "possibly make unreadable data on outdev", 0); - if(ret<=0) - return(2); - - if(strcmp(mode, "as_needed")==0 || mode[0]==0) - as_needed= 1; - else if(strcmp(mode, "all")==0 || strcmp(mode, "full")==0) - mode_flag= 0; - else if((strcmp(mode, "deformat")==0 || - strcmp(mode, "deformat_sequential")==0) && !(flag&1)) - mode_flag= 2; - else if((strcmp(mode, "deformat_quickest")==0 || - strcmp(mode, "deformat_sequential_quickest")==0) && !(flag&1)) - mode_flag= 3; - else if(strcmp(mode, "fast")==0) - mode_flag= 1; - else if(strncmp(mode, "by_index_", 9)==0 && (flag&1)) { - mode_flag= 128; - idx= -1; - if(strlen(mode)>9) - sscanf(mode+9, "%d", &idx); - if(idx<0 || idx>255) { -unusable_index:; - sprintf(xorriso->info_text, - "-format: mode '%s' provides unusable index number", mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - mode_flag|= (idx<<8); - } else if(strncmp(mode, "fast_by_index_", 14)==0 && (flag&1)) { - mode_flag= 1 | 128; - idx= -1; - if(strlen(mode)>14) - sscanf(mode+14, "%d", &idx); - if(idx<0 || idx>255) - goto unusable_index; - mode_flag|= (idx<<8); - } else if(strncmp(mode, "by_size_", 8) == 0 && (flag & 1)) { - size= (off_t) Scanf_io_size(mode + 8, 0); - if(size <= 0) { -unusable_size:; - sprintf(xorriso->info_text, - "-format: mode '%s' provides unusable size value", mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - mode_flag= 2; - } else if(strncmp(mode, "fast_by_size_", 13) == 0 && (flag & 1)) { - size= (off_t) Scanf_io_size(mode + 13, 0); - if(size <= 0) - goto unusable_size; - mode_flag= 3; - } else { - sprintf(xorriso->info_text, - "%s: Unknown %s mode '%s'", - cmd, ((flag&1) ? "-format" : "-blank"), mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - if(as_needed) - ret= Xorriso_blank_as_needed(xorriso, (flag&1)<<2); - else if(flag&1) - ret= Xorriso_format_media(xorriso, size, mode_flag & 0xff83); - else - ret= Xorriso_blank_media(xorriso, mode_flag&3); - if(ret==0) - return(ret); - strcpy(drive_name, xorriso->outdev); - if(ret <= 0) { /* in case of success, above functions will have re-aquired */ - aq_ret= Xorriso_reaquire_outdev(xorriso, 0); /* actually give up drive */ - if(retboot_count > 0) { -cannot_keep_or_patch:; - sprintf(xorriso->info_text, - "Loaded boot image has already been replaced. Cannot keep or patch it."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - if(isolinux_grub) - goto treatment_patch; - xorriso->keep_boot_image= 1; - xorriso->patch_isolinux_image= 0; - xorriso->boot_image_bin_path[0]= 0; - xorriso->patch_system_area= 0; - - } else if(strcmp(treatpt, "patch")==0) { -treatment_patch:; - if(xorriso->boot_count > 0) - goto cannot_keep_or_patch; - xorriso->keep_boot_image= 0; - xorriso->patch_isolinux_image= 1; - xorriso->boot_image_bin_path[0]= 0; - if(strcmp(formpt, "grub") == 0) { - xorriso->patch_isolinux_image|= 2; - xorriso->patch_system_area= 1; - } else if(strcmp(formpt, "isolinux") == 0) - xorriso->patch_system_area= 2; - else - xorriso->patch_system_area= 0; - - } else if(strcmp(treatpt, "discard")==0) { - xorriso->keep_boot_image= 0; - xorriso->patch_isolinux_image= 0; - xorriso->boot_image_bin_path[0]= 0; - xorriso->patch_system_area= 0; - if(xorriso->boot_count > 0) { - ret= Xorriso_attach_boot_image(xorriso, 2); /* dispose boot images */ - if(ret <= 0) - return(ret); - } - - } else if(strcmp(treatpt, "next") == 0) { - ret= Xorriso_attach_boot_image(xorriso, 0); - if(ret <= 0) - return(ret); - - } else if(strcmp(treatpt, "show_status")==0) { - sprintf(xorriso->result_line, "------------------------------------\n"); - Xorriso_result(xorriso, 0); - sprintf(xorriso->result_line, "Status of loaded boot image :\n"); - Xorriso_result(xorriso, 0); - sprintf(xorriso->result_line, "------------------------------------\n"); - Xorriso_result(xorriso, 0); - Xorriso_show_boot_info(xorriso, 0); - sprintf(xorriso->result_line, "------------------------------------\n"); - Xorriso_result(xorriso, 0); - sprintf(xorriso->result_line, "Boot image settings for next commit:\n"); - Xorriso_result(xorriso, 0); - sprintf(xorriso->result_line, "------------------------------------\n"); - Xorriso_result(xorriso, 0); - Xorriso_status(xorriso, "-boot_image", NULL, 0); - sprintf(xorriso->result_line, "------------------------------------\n"); - Xorriso_result(xorriso, 0); - - } else if(strcmp(treatpt, "cat_path=") == 0) { - xorriso->boot_image_cat_path[0] = 0; - } else if(strncmp(treatpt, "cat_path=", 9) == 0) { - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, treatpt + 9, - xorriso->boot_image_cat_path, 2); - if(ret <= 0) - return(ret); - - } else if(strncmp(treatpt, "dir=", 4) == 0) { - if(strcmp(formpt, "isolinux")==0) { - /* ISOLINUX */ - /* The three locations mentioned in http://syslinux.zytor.com/iso.php */ - if(strcmp(treatpt + 4, "/") == 0) - strcpy(xorriso->boot_image_bin_path, "/"); - else if(strcmp(treatpt + 4, "isolinux") == 0 - || strcmp(treatpt + 4, "/isolinux") == 0) - strcpy(xorriso->boot_image_bin_path, "/isolinux/"); - else if(strcmp(treatpt + 4, "boot/isolinux") == 0 - || strcmp(treatpt + 4, "/boot/isolinux") == 0 - || strcmp(treatpt + 4, "boot") == 0 - || strcmp(treatpt + 4, "/boot") == 0) - strcpy(xorriso->boot_image_bin_path, "/boot/isolinux/"); - else { - sprintf(xorriso->info_text, - "Unrecognized keyword with -boot_image %s %s", - form, treatment); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - sprintf(xorriso->info_text, - "Allowed with dir= are / , /isolinux . /boot/isolinux"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0); - return(0); - } - strcpy(xorriso->boot_image_cat_path, xorriso->boot_image_bin_path); - strcat(xorriso->boot_image_bin_path, "isolinux.bin"); - strcat(xorriso->boot_image_cat_path, "boot.cat"); - xorriso->boot_image_load_size= 4 * 512; - xorriso->keep_boot_image= 0; - xorriso->patch_isolinux_image= 1; - strcpy(xorriso->boot_image_bin_form, formpt); - return(1); - - } else if(strcmp(formpt, "grub") == 0) { - - /* >>> GRUB */ - was_ok= 0; - - strcpy(xorriso->boot_image_bin_form, formpt); - - } else - was_ok= 0; - - } else if(strcmp(treatpt, "bin_path=") == 0) { - xorriso->boot_image_bin_path[0] = 0; - xorriso->boot_efi_default= 0; - } else if(strncmp(treatpt, "bin_path=", 9) == 0) { - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, treatpt + 9, - xorriso->boot_image_bin_path, 2); - if(ret <= 0) - return(ret); - xorriso->keep_boot_image= 0; - if(isolinux_grub) { - xorriso->patch_isolinux_image= 1; - if(xorriso->boot_image_bin_path[0]) - xorriso->boot_image_load_size= 4 * 512; - strcpy(xorriso->boot_image_bin_form, formpt); - } else - strcpy(xorriso->boot_image_bin_form, "any"); - xorriso->boot_efi_default= 0; - - } else if(strcmp(treatpt, "efi_path=") == 0) { - xorriso->boot_image_bin_path[0] = 0; - xorriso->boot_efi_default= 0; - } else if(strncmp(treatpt, "efi_path=", 9) == 0) { - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, treatpt + 9, - xorriso->boot_image_bin_path, 2); - if(ret <= 0) - return(ret); - xorriso->keep_boot_image= 0; - xorriso->boot_efi_default= 1; - - } else if(strncmp(treatpt, "boot_info_table=", 16)==0) { - if(strcmp(treatpt + 16, "off") == 0) - xorriso->patch_isolinux_image= 0; - else if(strcmp(treatpt + 16, "on") == 0) - xorriso->patch_isolinux_image= 1 | (2 * (strcmp(treatpt, "grub") == 0)); - else - was_ok= 0; - - } else if(strncmp(treatpt, "load_size=", 10) == 0) { - num= Scanf_io_size(treatpt + 10, 0); - if(num < 512 && isolinux_grub) { - sprintf(xorriso->info_text, - "-boot_image %s : load_size too small (%s < 512)", - formpt, treatpt + 10); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - xorriso->boot_image_load_size= num; - - } else if(strncmp(treatpt, "id_string=", 10) == 0) { - memset(xorriso->boot_id_string, 0, 29); - if(strlen(treatpt + 10) == 56) { - ret= Hex_to_bin(treatpt + 10, 28, &count, xorriso->boot_id_string, 0); - } else - ret= 0; - if(ret <= 0) - strncpy((char *) xorriso->boot_id_string, treatpt + 10, 28); - - } else if(strncmp(treatpt, "sel_crit=", 9) == 0) { - memset(xorriso->boot_selection_crit, 0, 21); - count= 0; - ret= Hex_to_bin(treatpt + 9, 20, &count, xorriso->boot_selection_crit, 0); - if(ret <= 0) { - sprintf(xorriso->info_text, - "-boot_image %s sel_crit= : Wrong form. Need even number of hex digits.", - formpt); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - - } else if(strncmp(treatpt, "system_area=", 12) == 0) { - ret= Xorriso_set_system_area_path(xorriso, treatpt + 12, 0); - if(ret <= 0) - return(ret); - if(strcmp(formpt, "isolinux")==0) - xorriso->system_area_options= (xorriso->system_area_options & ~3) | 2; - - } else if(strncmp(treatpt, "partition_table=", 16)==0) { - if(strcmp(treatpt + 16, "off") == 0) { - xorriso->system_area_options&= ~3; - xorriso->patch_system_area= xorriso->system_area_options; - } else if(strcmp(treatpt + 16, "on") == 0) { - xorriso->system_area_options&= ~3; - if(strcmp(formpt, "isolinux")==0) - xorriso->system_area_options|= 2; - else - xorriso->system_area_options|= 1; - xorriso->patch_system_area= xorriso->system_area_options; - } else - was_ok= 0; - - } else if(strncmp(treatpt, "platform_id=", 12)==0) { - if(strncmp(treatpt + 12, "0x", 2) == 0) - sscanf(treatpt + 14, "%x", &u); - else - sscanf(treatpt + 12, "%u", &u); - if(u > 0xff) { - sprintf(xorriso->info_text, - "-boot_image %s : platform_id too large (%s > 0xff)", - formpt, treatpt + 12); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - xorriso->boot_platform_id= u; - - } else if(strncmp(treatpt, "isohybrid=", 10) == 0 && - strcmp(formpt, "isolinux")==0) { - -#ifdef Xorriso_with_isohybriD - - if(strcmp(treatpt + 10, "off") == 0) - xorriso->boot_image_isohybrid= 0; - else if(strcmp(treatpt + 10, "auto") == 0) - xorriso->boot_image_isohybrid= 1; - else if(strcmp(treatpt + 10, "on") == 0) - xorriso->boot_image_isohybrid= 2; - else if(strcmp(treatpt + 10, "force") == 0) - xorriso->boot_image_isohybrid= 3; - else { - sprintf(xorriso->info_text, - "Unrecognized keyword with -boot_image %s %s", - form, treatment); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - sprintf(xorriso->info_text, - "Allowed with isohybrid= are: off , auto , on , force"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0); - return(0); - } - -#else - - if(strcmp(treatpt + 10, "off") == 0) { - xorriso->boot_image_isohybrid= 0; - } else { - sprintf(xorriso->info_text, - "isohybrid MBR generation has been disabled on request of its inventor H. Peter Anvin on 31 Mar 2010"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - sprintf(xorriso->info_text, - "It has been replaced by -boot_image isolinux system_area=External-File"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0); - } - -#endif /* ! Xorriso_with_isohybriD */ - - } else - was_ok= 0; - - if(!was_ok) { - sprintf(xorriso->info_text, "Unrecognized options with -boot_image: %s %s", - form, treatment); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - return(1); -} - - -/* Option -calm_drive */ -int Xorriso_option_calm_drive(struct XorrisO *xorriso, char *which, int flag) -{ - int gu_flag= 0, ret; - - if(strcmp(which,"in")==0) - gu_flag= 1; - else if(strcmp(which,"out")==0) - gu_flag= 2; - else if(strcmp(which,"on")==0) { - xorriso->do_calm_drive|= 1; - } else if(strcmp(which,"off")==0) { - xorriso->do_calm_drive&= ~1; - } else if(strcmp(which,"revoke")==0) { - gu_flag= 7; - } else - gu_flag= 3; - ret= Xorriso_drive_snooze(xorriso, gu_flag); - return(ret); -} - - -/* Option -cd alias -cdi */ -int Xorriso_option_cdi(struct XorrisO *xorriso, char *iso_rr_path, int flag) -{ - char sfe[5*SfileadrL], path[SfileadrL], eff_path[SfileadrL]; - int ret; - - if (strlen(iso_rr_path)>sizeof(xorriso->wdi)) { - sprintf(xorriso->info_text,"-cdi: iso_rr_path too long (%d > %d)", - (int) strlen(iso_rr_path), (int) sizeof(xorriso->wdi)-1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - Xorriso_warn_of_wildcards(xorriso, iso_rr_path, 1); - sprintf(xorriso->info_text,"previous working directory:\n"); - Xorriso_info(xorriso,0); - sprintf(xorriso->result_line,"%s/\n",Text_shellsafe(xorriso->wdi, sfe, 0)); - Xorriso_result(xorriso,0); - if(strcmp(iso_rr_path,"/")==0 || iso_rr_path[0]==0) { - strcpy(xorriso->wdi,""); - Xorriso_option_pwdi(xorriso, 0); - return(1); - } else if(iso_rr_path[0]!='/') { - strcpy(path, xorriso->wdi); - if(Sfile_add_to_path(path,iso_rr_path,0)<=0) - return(-1); - } else { - if(Sfile_str(path,iso_rr_path,0)<=0) - return(-1); - } - - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 1); - if(ret<0) - return(ret); - if(ret==0) { - sprintf(xorriso->info_text, "-cdi: not existing yet in ISO image : %s", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 2); - if(ret<=0) - return(ret); - } else if(ret!=2) { - sprintf(xorriso->info_text, "-cdi: not a directory : %s", - Text_shellsafe(eff_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - strcpy(xorriso->wdi, eff_path); - - Xorriso_option_pwdi(xorriso, 0); - return(1); -} - - -/* Option -cdx */ -int Xorriso_option_cdx(struct XorrisO *xorriso, char *disk_path, int flag) -{ - char sfe[5*SfileadrL], path[SfileadrL], eff_path[SfileadrL]; - int ret; - - if (strlen(disk_path)>sizeof(xorriso->wdx)) { - sprintf(xorriso->info_text,"-cdx: disk_path too long (%d > %d)", - (int) strlen(disk_path), (int) sizeof(xorriso->wdx)-1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - Xorriso_warn_of_wildcards(xorriso, disk_path, 1|2); - sprintf(xorriso->info_text,"previous working directory on hard disk:\n"); - Xorriso_info(xorriso,0); - sprintf(xorriso->result_line,"%s/\n",Text_shellsafe(xorriso->wdx, sfe, 0)); - Xorriso_result(xorriso,0); - if(strcmp(disk_path,"/")==0) { - strcpy(xorriso->wdx,""); - Xorriso_option_pwdx(xorriso, 0); - return(1); - } else if(disk_path[0]!='/') { - strcpy(path, xorriso->wdx); - if(Sfile_add_to_path(path,disk_path,0)<=0) - return(-1); - } else { - if(Sfile_str(path,disk_path,0)<=0) - return(-1); - } - - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, path, eff_path, 2|4); - if(ret<=0) - return(ret); - if(eff_path[0]) { - ret= Sfile_type(eff_path,1|4|8); - if(ret<0) { - Xorriso_msgs_submit(xorriso, 0, eff_path, 0, "ERRFILE", 0); - sprintf(xorriso->info_text,"-cdx: file not found : %s", - Text_shellsafe(eff_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - if(ret!=2) { - Xorriso_msgs_submit(xorriso, 0, eff_path, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, - "-cdx: not a directory : %s", - Text_shellsafe(eff_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - } - if(Sfile_str(xorriso->wdx,eff_path,0)<=0) - return(-1); - Xorriso_option_pwdx(xorriso, 0); - return(1); -} - - -/* Option -charset */ -/* @param flag bit0= set in_charset - bit1= set out_charset - bit2= set local_charset -*/ -int Xorriso_option_charset(struct XorrisO *xorriso, char *name, int flag) -{ - int ret; - char *name_pt= NULL, sfe[5 * SfileadrL], *local_charset; - iconv_t iconv_ret= (iconv_t) -1; - - if(name != NULL) - if(name[0] != 0) - name_pt= name; - if(flag & 4) { - ret= Xorriso_set_local_charset(xorriso, name_pt, 0); - if(ret <= 0) - return(ret); - } - if(flag & 1) { - if(name_pt != NULL) { - Xorriso_get_local_charset(xorriso, &local_charset, 0); - iconv_ret= iconv_open(local_charset, name_pt); - if(iconv_ret == (iconv_t) -1) { - sprintf(xorriso->info_text, - "-%scharset: Cannot convert from character set %s", - flag & 2 ? "" : "in_", Text_shellsafe(name_pt, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", - 0); - return(0); - } else - iconv_close(iconv_ret); - } - if(Sregex_string(&(xorriso->in_charset), name_pt, 0) <= 0) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - return(-1); - } - } - if(flag & 2) { - if(name_pt != NULL) { - Xorriso_get_local_charset(xorriso, &local_charset, 0); - iconv_ret= iconv_open(local_charset, name_pt); - if(iconv_ret == (iconv_t) -1) { - sprintf(xorriso->info_text, "-%scharset: Cannot convert to charset %s", - flag & 1 ? "" : "out_", Text_shellsafe(name_pt, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", - 0); - return(0); - } else - iconv_close(iconv_ret); - } - if(Sregex_string(&(xorriso->out_charset), name_pt, 0) <= 0) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - return(-1); - } - } - if(flag & 3) { - if(name_pt == NULL) - Xorriso_get_local_charset(xorriso, &name_pt, 0); - sprintf(xorriso->info_text, "Character set for %sconversion is now: %s", - (flag & 3) == 1 ? "input " : (flag & 3) == 2 ? "output " : "", - Text_shellsafe(name_pt, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - } - return(1); -} - - -/* Options -check_md5 and -check_md5_r - @param flag bit0= issue summary message - bit1= do not reset pacifier, no final pacifier message - >>> bit2= do not issue pacifier messages at all - bit3= recursive: -check_md5_r -*/ -int Xorriso_option_check_md5(struct XorrisO *xorriso, - int argc, char **argv, int *idx, int flag) -{ - int ret, i, mem_pci, end_idx, fret, sev, do_report= 0; - int optc= 0; - char **optv= NULL, *cpt, *severity= "ALL"; - struct FindjoB *job= NULL; - double mem_lut= 0.0; - - mem_pci= xorriso->pacifier_interval; - - ret= Xorriso_opt_args(xorriso, "-check_md5", argc, argv, *idx + 1, - &end_idx, &optc, &optv, 128); - if(ret<=0) - goto ex; - - /* Interpret argv[*idx] as severity */ - if(argc <= *idx) { - sprintf(xorriso->info_text, - "-check_md5: No event severity given for case of mismatch"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - severity= argv[*idx]; - ret= Xorriso__text_to_sev(severity, &sev, 0); - if(ret<=0) { - sprintf(xorriso->info_text, "-check_md5: Not a known severity name : "); - Text_shellsafe(severity, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - goto ex; - } - - if(!(flag & (2 | 4))) { - Xorriso_pacifier_reset(xorriso, 0); - mem_lut= xorriso->last_update_time; - } - xorriso->pacifier_interval= 5.0; - - xorriso->find_check_md5_result= 0; - - if(optc == 0) { - ret= Xorriso_check_session_md5(xorriso, severity, 0); - do_report= 1; - goto ex; - } - - for(i= 0; i < optc; i++) { - if(flag & 8) { - ret= Findjob_new(&job, optv[i], 0); - if(ret<=0) { - Xorriso_no_findjob(xorriso, "-check_md5_r", 0); - {ret= -1; goto ex;} - } - Findjob_set_action_target(job, 35, severity, 0); - cpt= optv[i]; - ret= Xorriso_findi_sorted(xorriso, job, (off_t) 0, 1, &cpt, 0); - Findjob_destroy(&job, 0); - if(ret > 0) - ret= xorriso->find_compare_result; - else { - ret= -1; - xorriso->find_check_md5_result|= 2; - } - } else { - ret= Xorriso_check_md5(xorriso, NULL, optv[i], 4); - if(ret < 0) - xorriso->find_check_md5_result|= 2; - else if(ret == 0) - xorriso->find_check_md5_result|= 1; - else if(ret == 1) - xorriso->find_check_md5_result|= 8; - else if(ret == 2) - xorriso->find_check_md5_result|= 4; - } - if(ret>0 && !xorriso->request_to_abort) - continue; /* regular bottom of loop */ - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - ret= 0; goto report_outcome; - } - ret= 1; - -report_outcome:; - do_report= 1; - -ex:; - if(!(flag & (2 | 4))) { - xorriso->pacifier_interval= mem_pci; - if(mem_lut!=xorriso->last_update_time && !(flag&2)) - Xorriso_pacifier_callback(xorriso, "content bytes read", - xorriso->pacifier_count, 0, "", 1); - } - if(do_report) { - if(optc == 0) { - if(ret <= 0) { - sprintf(xorriso->result_line, - "MD5 MISMATCH WITH DATA OF LOADED SESSION !\n"); - Xorriso_result(xorriso,0); - if(strcmp(severity, "ALL") != 0) { - sprintf(xorriso->info_text, - "Event triggered by MD5 comparison mismatch"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, severity, 0); - } - } else { - sprintf(xorriso->result_line, "Ok, session data match recorded md5.\n"); - Xorriso_result(xorriso,0); - } - } else { - Xorriso_report_md5_outcome(xorriso, severity, 0); - } - } - (*idx)= end_idx; - Xorriso_opt_args(xorriso, "-getfacl", argc, argv, *idx, &end_idx, - &optc, &optv, 256); - Findjob_destroy(&job, 0); - if(ret <= 0) - return(ret); - return((xorriso->find_check_md5_result & 3) == 0); -} - - -/* Option -check_media */ -int Xorriso_option_check_media(struct XorrisO *xorriso, - int argc, char **argv, int *idx, int flag) -{ - int ret, i, count, lba, blocks, quality, pass, was_md5= 0, was_event= 0; - int end_idx, old_idx, os_errno; - char quality_name[80], head_buffer[64*1024]; - struct SpotlisT *spotlist= NULL; - struct CheckmediajoB *job= NULL; - struct FindjoB *findjob= NULL; - struct stat dir_stbuf; - - old_idx= *idx; - end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); - (*idx)= end_idx; - - ret= Checkmediajob_new(&job, 0); - if(ret <= 0) - goto ex; - ret= Xorriso_check_media_setup_job(xorriso, job, argv, old_idx, end_idx, 0); - if(ret <= 0) - goto ex; - - if((job->report_mode == 1 || job->report_mode == 2) && job->use_dev == 1) { - sprintf(xorriso->info_text, - "-check_media: cannot report=*files while use=outdef"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - if(job->patch_lba0 && job->data_to_path[0] == 0) { - sprintf(xorriso->info_text, - "-check_media: cannot apply patch_lba0= while data_to= has empty value"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - - if(job->use_dev == 2) { - if(job->sector_map_path[0] == 0) { - sprintf(xorriso->info_text, - "-check_media: option use=sector_map but sector_map=''"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - ret= Sectorbitmap_from_file(&(job->sector_map), job->sector_map_path, - xorriso->info_text, &os_errno, 0); - if(ret <= 0) { - if(xorriso->info_text[0]) - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, os_errno, - "FAILURE", 0); - goto ex; - } - ret= Xorriso_sectormap_to_spotlist(xorriso, job, &spotlist, 0); - if(ret <= 0) - goto ex; - Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); - ret= Sectorbitmap_clone(job->sector_map, &(xorriso->in_sector_map), 0); - if(ret <= 0) - goto ex; - } else { - ret= Xorriso_check_media(xorriso, &spotlist, job, 0); - if(ret <= 0) - goto ex; - } - - if(job->patch_lba0) { - ret= Xorriso_open_job_data_to(xorriso, job, 0); - if(ret <= 0) - goto ex; - if(ret == 1) { - ret= Xorriso_update_iso_lba0(xorriso, job->patch_lba0_msc1, 0, - head_buffer, job, - (8 * (job->patch_lba0 == 1)) | - 4 | (job->patch_lba0_msc1 < 0)); - if(ret <= 0) - goto ex; - } - } - - if(job->report_mode == 0 || job->report_mode == 2) { /* report blocks */ - for(pass= 0; pass < 2; pass++) { - if(pass == 0) { - sprintf(xorriso->result_line, - "Media checks : lba , size , quality\n"); - } else { - if(!was_md5) - break; - sprintf(xorriso->result_line, - "MD5 checks : lba , size , result\n"); - } - Xorriso_result(xorriso,0); - count= Spotlist_count(spotlist, 0); - for(i= 0; i < count; i++) { - ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0); - if(ret <= 0) - continue; - if(pass == 0) { - if(quality == Xorriso_read_quality_md5_mismatcH || - quality == Xorriso_read_quality_unreadablE) { - was_event= 1; - } - if(quality == Xorriso_read_quality_md5_matcH || - quality == Xorriso_read_quality_md5_mismatcH) { - was_md5= 1; - continue; - } - } - else if(pass == 1 && !(quality == Xorriso_read_quality_md5_matcH || - quality == Xorriso_read_quality_md5_mismatcH)) - continue; - sprintf(xorriso->result_line, "%s: %10d , %10d , %s\n", - pass == 0 ? "Media region " : "MD5 tag range", - lba, blocks, Spotlist__quality_name(quality, quality_name, - xorriso->check_media_bad_limit, 0)); - Xorriso_result(xorriso,0); - } - } - } - if(job->report_mode == 1 || job->report_mode == 2) { /* report files */ - ret= Findjob_new(&findjob, "/", 0); - if(ret<=0) { - Xorriso_no_findjob(xorriso, "-check_media report=files", 0); - {ret= -1; goto ex;} - } - Findjob_set_damage_filter(findjob, 1, 0); - Findjob_set_action_target(findjob, 21, NULL, 0); - ret= Xorriso_findi(xorriso, findjob, NULL, (off_t) 0, - NULL, "/", &dir_stbuf, 0, 0); - Findjob_destroy(&findjob, 0); - if(ret <= 0) - goto ex; - } - ret= 1; -ex:; - if(was_event && strcmp(job->event_severity, "ALL") != 0) { - sprintf(xorriso->info_text, - "Event triggered by media read error or MD5 comparison mismatch"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, job->event_severity, - 0); - } - Spotlist_destroy(&spotlist, 0); - Checkmediajob_destroy(&job, 0); - return(ret); -} - - -/* Option -check_media_defaults */ -int Xorriso_option_check_media_defaults(struct XorrisO *xorriso, - int argc, char **argv, int *idx, int flag) -{ - int ret, old_idx, end_idx; - struct CheckmediajoB *job= NULL; - - old_idx= *idx; - end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); - (*idx)= end_idx; - - ret= Checkmediajob_new(&job, 0); - if(ret <= 0) - goto ex; - ret= Xorriso_check_media_setup_job(xorriso, job, argv, old_idx, end_idx, 0); - if(ret <= 0) - goto ex; - Checkmediajob_destroy(&(xorriso->check_media_default), 0); - xorriso->check_media_default= job; - job= NULL; - ret= 1; -ex:; - Checkmediajob_destroy(&job, 0); - return(ret); -} - - -/* Option -chgrp alias -chgrpi , chgrp_r alias chgrpi */ -/* @param flag bit0=recursive (-chgrp_r) -*/ -int Xorriso_option_chgrpi(struct XorrisO *xorriso, char *gid, - int argc, char **argv, int *idx, int flag) -{ - int i, ret, was_failure= 0, end_idx, fret; - gid_t gid_number; - int optc= 0; - char **optv= NULL; - struct FindjoB *job= NULL; - struct stat dir_stbuf; - - ret= Xorriso_opt_args(xorriso, "-chgrpi", argc, argv, *idx, &end_idx, &optc, - &optv, 0); - if(ret<=0) - goto ex; - ret= Xorriso_convert_gidstring(xorriso, gid, &gid_number, 0); - if(ret<=0) - goto ex; - for(i= 0; i0 && !xorriso->request_to_abort) - continue; /* regular bottom of loop */ - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - goto ex; - } - ret= 1; -ex:; - (*idx)= end_idx; - Xorriso_opt_args(xorriso, "-chgrpi", argc, argv, *idx, &end_idx, &optc, &optv, - 256); /* clean up */ - if(ret<=0) - return(ret); - Findjob_destroy(&job, 0); - return(!was_failure); -} - - -/* Option -chmod alias -chmodi , -chmod_r alias chmod_ri */ -/* @param flag bit0=recursive (-chmod_r) -*/ -int Xorriso_option_chmodi(struct XorrisO *xorriso, char *mode, - int argc, char **argv, int *idx, int flag) -{ - int i, ret, was_failure= 0, end_idx, fret; - mode_t mode_and= ~0, mode_or= 0; - int optc= 0; - char **optv= NULL; - struct FindjoB *job= NULL; - struct stat dir_stbuf; - - ret= Xorriso_opt_args(xorriso, "-chmodi", argc, argv, *idx, &end_idx, &optc, - &optv, 0); - if(ret<=0) - goto ex; - ret= Xorriso_convert_modstring(xorriso, "-chmodi", - mode, &mode_and, &mode_or, 0); - if(ret<=0) - goto ex; - for(i= 0; i0 && !xorriso->request_to_abort) - continue; /* regular bottom of loop */ - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - ret= 0; goto ex; - } - ret= 1; -ex:; - (*idx)= end_idx; - Xorriso_opt_args(xorriso, "-chmodi", argc, argv, *idx, &end_idx, &optc, &optv, - 256); - Findjob_destroy(&job, 0); - if(ret<=0) - return(ret); - return(!was_failure); -} - - -/* Option -chown alias -chowni , chown_r alias chown_ri */ -/* @param flag bit0=recursive (-chown_r) -*/ -int Xorriso_option_chowni(struct XorrisO *xorriso, char *uid, - int argc, char **argv, int *idx, int flag) -{ - int i, ret, was_failure= 0, end_idx, fret; - uid_t uid_number; - int optc= 0; - char **optv= NULL; - struct FindjoB *job= NULL; - struct stat dir_stbuf; - - ret= Xorriso_opt_args(xorriso, "-chowni", argc, argv, *idx, &end_idx, - &optc, &optv, 0); - if(ret<=0) - goto ex; - ret= Xorriso_convert_uidstring(xorriso, uid, &uid_number, 0); - if(ret<=0) - goto ex; - for(i= 0; i0 && !xorriso->request_to_abort) - continue; /* regular bottom of loop */ - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - ret= 0; goto ex; - } - ret= 1; -ex:; - (*idx)= end_idx; - Xorriso_opt_args(xorriso, "-chowni", argc, argv, *idx, &end_idx, - &optc, &optv, 256); - Findjob_destroy(&job, 0); - if(ret<=0) - return(ret); - return(!was_failure); -} - - -/* Option -close "on"|"off" */ -int Xorriso_option_close(struct XorrisO *xorriso, char *mode, int flag) -{ - xorriso->do_close= !!strcmp(mode, "off"); - return(1); -} - - -/* Option -close_filter_list */ -int Xorriso_option_close_filter_list(struct XorrisO *xorriso, int flag) -{ - xorriso->filter_list_closed= 1; - return(1); -} - - -/* Option -commit */ -/* @param flag bit0= leave indrive and outdrive aquired as they were, - i.e. do not aquire outdrive as new in-out-drive - bit1= do not perform eventual -reassure - @return <=0 error , 1 success, 2 revoked by -reassure , 3 no change pending -*/ -int Xorriso_option_commit(struct XorrisO *xorriso, int flag) -{ - int ret; - char newdev[SfileadrL]; - - if(!xorriso->volset_change_pending) { - sprintf(xorriso->info_text, "-commit: No image modifications pending"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - return(3); - } - if(!(flag&2)) { - ret= Xorriso_reassure(xorriso, "-commit", - "write the pending image changes to media", 0); - if(ret<=0) - return(2); - } - Xorriso_process_errfile(xorriso, 0, "burn session start", 0, 1); - ret= Xorriso_write_session(xorriso, 0); - Xorriso_process_errfile(xorriso, 0, "burn session end", 0, 1); - if(ret<=0) - return(ret); - Xorriso_write_session_log(xorriso, 0); - xorriso->volset_change_pending= 0; - xorriso->no_volset_present= 0; - if(flag&1) - return(1); - if(Sregex_string(&(xorriso->in_charset), xorriso->out_charset, 0) <= 0) - return(-1); - strcpy(newdev, xorriso->outdev); - if(xorriso->grow_blindly_msc2>=0) - ret= Xorriso_option_dev(xorriso, "", 3|4); - else - ret= Xorriso_option_dev(xorriso, newdev, 3|4); - return(ret); -} - - -/* Option -commit_eject */ -/* @return <=0 error , 1 success, 2 revoked by -reassure -*/ -int Xorriso_option_commit_eject(struct XorrisO *xorriso, char *which, int flag) -{ - int ret, eret; - - ret= Xorriso_option_commit(xorriso, 1); - if(ret<=0 || ret==2 || ret==3) - return(ret); - if(strcmp(which, "none")==0) - eret= 1; - else - eret= Xorriso_option_eject(xorriso, which, 1); - ret= Xorriso_option_dev(xorriso, "", 3|4); - if(eretinfo_text, "-compare: Empty disk_path given"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 1); - return(0); - } - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_origin, - 2|4|8); - if(ret<=0) - return(ret); - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, ipth, eff_dest, 2|8); - if(ret<=0) - return(ret); - - if(xorriso->disk_excl_mode&8) - ret= Xorriso_path_is_excluded(xorriso, eff_origin, 1); - else - ret= 0; - if(ret!=0) - goto report_outcome; - if(!(flag&2)) { - Xorriso_pacifier_reset(xorriso, 0); - mem_lut= xorriso->last_update_time; - } - mem_pci= xorriso->pacifier_interval; - xorriso->pacifier_interval= 5.0; - - if(flag&8) { - xorriso->find_compare_result= 1; - argv[0]= eff_dest; - argv[1]= "-exec"; - argv[2]= "compare"; - argv[3]= eff_origin; - zero= 0; - ret= Xorriso_option_find(xorriso, 4, argv, &zero, 2); /* -findi */ - if(ret>0) { - argv[0]= eff_origin; - argv[1]= "-exec"; - argv[2]= "not_in_iso"; - argv[3]= eff_dest; - zero= 0; - ret= Xorriso_option_find(xorriso, 4, argv, &zero, 1|2); /* -findx */ - if(ret>0 && !xorriso->do_follow_mount) { - argv[0]= eff_origin; - argv[1]= "-type"; - argv[2]= "m"; - argv[3]= "-exec"; - argv[4]= "is_full_in_iso"; - argv[5]= eff_dest; - zero= 0; - ret= Xorriso_option_find(xorriso, 6, argv, &zero, 1|2); /* -findx */ - } - if(ret>0) - ret= xorriso->find_compare_result; - else - ret= -1; - } else - ret= -1; - } else { - follow_links= (xorriso->do_follow_links || xorriso->do_follow_param) << 28; - ret= Xorriso_compare_2_files(xorriso, eff_origin, eff_dest, "", &result, - 2 | follow_links | ((flag&4)<<27) | (1<<30)); - } - - xorriso->pacifier_interval= mem_pci; - if(mem_lut!=xorriso->last_update_time && !(flag&2)) - Xorriso_pacifier_callback(xorriso, "content bytes read", - xorriso->pacifier_count, 0, "", 1); -report_outcome:; - if(ret>0) { - sprintf(xorriso->result_line, - "Both file objects match as far as expectable.\n"); - } else if(ret==0) { - sprintf(xorriso->result_line, "Differences detected.\n"); - } else { - sprintf(xorriso->result_line, "Comparison failed due to error.\n"); - } - if(flag&1) - Xorriso_result(xorriso,0); - if(ret<0) - return(ret); - return(1); -} - - -/* Option -compliance */ -int Xorriso_option_compliance(struct XorrisO *xorriso, char *mode, - int flag) -{ - return(Xorriso_relax_compliance(xorriso, mode, 0)); -} - - -/* Option -cpr alias -cpri */ -int Xorriso_option_cpri(struct XorrisO *xorriso, int argc, char **argv, - int *idx, int flag) -{ - int i, ret, is_dir= 0, was_failure= 0, fret, end_idx_dummy; - char eff_origin[SfileadrL], eff_dest[SfileadrL]; - char dest_dir[SfileadrL], leafname[SfileadrL]; - int optc= 0; - char **optv= NULL; - - ret= Xorriso_cpmv_args(xorriso, "-cpri", argc, argv, idx, - &optc, &optv, eff_dest, 1|2); - if(ret<=0) - goto ex; - if(ret==2) { - is_dir= 1; - strcpy(dest_dir, eff_dest); - } - - /* Perform graft-ins */ - Xorriso_pacifier_reset(xorriso, 0); - for(i= 0; irequest_to_abort; i++) { - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, optv[i], eff_origin, - 2|4); - if(ret<=0 || xorriso->request_to_abort) - goto problem_handler; - if(is_dir) { - ret= Sfile_leafname(eff_origin, leafname, 0); - if(ret<=0) - goto problem_handler; - strcpy(eff_dest, dest_dir); - ret= Sfile_add_to_path(eff_dest, leafname, 0); - if(ret<=0) { - sprintf(xorriso->info_text, "Effective path gets much too long (%d)", - (int) (strlen(eff_dest)+ strlen(leafname)+1)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - goto problem_handler; - } - } - ret= Xorriso_graft_in(xorriso, NULL, eff_origin, eff_dest, - (off_t) 0, (off_t) 0, 0); - if(ret<=0 || xorriso->request_to_abort) - goto problem_handler; - sprintf(xorriso->info_text, "Added to ISO image: %s '%s'='%s'\n", - (ret>1 ? "directory" : "file"), (eff_dest[0] ? eff_dest : "/"), - eff_origin); - if(!(flag&1)) - Xorriso_info(xorriso, 0); - continue; /* regular bottom of loop */ -problem_handler:; - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - goto ex; - } - Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count, - xorriso->pacifier_total, "", 1); - ret= !was_failure; -ex:; - Xorriso_opt_args(xorriso, "-cpri", - argc, argv, *idx, &end_idx_dummy, &optc, &optv, 256); - return(ret); -} - - -/* Options -cpx , -cpax, -cp_rx , -cp_rax */ -/* @param flag bit0= recursive (-cp_rx, -cp_rax) - bit1= full property restore (-cpax, -cp_rax) -*/ -int Xorriso_option_cpx(struct XorrisO *xorriso, int argc, char **argv, - int *idx, int flag) -{ - int i, ret, is_dir= 0, was_failure= 0, fret, end_idx_dummy; - char eff_origin[SfileadrL], eff_dest[SfileadrL]; - char dest_dir[SfileadrL], leafname[SfileadrL], sfe[5*SfileadrL]; - char **eff_src_array= NULL, **eff_tgt_array= NULL; - - int optc= 0; - char **optv= NULL; - struct stat stbuf; - - ret= Xorriso_cpmv_args(xorriso, "-cp*x", argc, argv, idx, - &optc, &optv, eff_dest, 1|4); - if(ret<=0) - goto ex; - if(ret==2) { - is_dir= 1; - strcpy(dest_dir, eff_dest); - } - if(xorriso->allow_restore <= 0) { - sprintf(xorriso->info_text, - "-cpx: image-to-disk copies are not enabled by option -osirrox"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - - if(xorriso->do_restore_sort_lba || !(xorriso->ino_behavior & 4)) { - eff_src_array= calloc(optc, sizeof(char *)); - eff_tgt_array= calloc(optc, sizeof(char *)); - if(eff_src_array == NULL || eff_tgt_array == NULL) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - ret= -1; goto ex; - } - for(i= 0; i < optc; i++) - eff_src_array[i]= eff_tgt_array[i]= NULL; - } - - /* Perform copying */ - Xorriso_pacifier_reset(xorriso, 0); - for(i= 0; irequest_to_abort; i++) { - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, optv[i], eff_origin, - 2|8); - if(ret<=0 || xorriso->request_to_abort) - goto problem_handler; - - ret= Xorriso_iso_lstat(xorriso, eff_origin, &stbuf, 2|4); - if(ret==-1) - goto problem_handler; - if(S_ISDIR(stbuf.st_mode) && !(flag&1)) { - /* only allow directories if they actually represent split data files */ - ret= 0; - if(xorriso->do_concat_split) - ret= Xorriso_is_split(xorriso, eff_origin, NULL, 0); - if(ret<0) - goto problem_handler; - if(ret==0) { - sprintf(xorriso->info_text, "-cpx: May not copy directory %s", - Text_shellsafe(eff_origin, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto problem_handler; - } - } - - if(is_dir && strcmp(eff_origin, "/")!=0) { - ret= Sfile_leafname(eff_origin, leafname, 0); - if(ret<=0) - goto problem_handler; - strcpy(eff_dest, dest_dir); - ret= Sfile_add_to_path(eff_dest, leafname, 0); - if(ret<=0) { - sprintf(xorriso->info_text, "Effective path gets much too long (%d)", - (int) (strlen(eff_dest)+strlen(leafname)+1)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - goto problem_handler; - } - } - if(eff_src_array != NULL) { - eff_src_array[i]= strdup(eff_origin); - eff_tgt_array[i]= strdup(eff_dest); - if(eff_src_array[i] == NULL || eff_tgt_array[i] == NULL) { - Xorriso_no_malloc_memory(xorriso, &(eff_src_array[i]), 0); - ret= -1; goto ex; - } - } else { - ret= Xorriso_restore(xorriso, eff_origin, eff_dest, (off_t) 0, (off_t) 0, - 16 | ((!(flag&2))<<6)); - if(ret<=0 || xorriso->request_to_abort) - goto problem_handler; - if(ret==3 || (flag&1)) - continue; - sprintf(xorriso->info_text, - "Copied from ISO image to disk: %s '%s' = '%s'\n", - (ret>1 ? "directory" : "file"), eff_origin, eff_dest); - Xorriso_info(xorriso, 0); - } - continue; /* regular bottom of loop */ -problem_handler:; - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - goto ex; - } - - if(eff_src_array != NULL) { - ret= Xorriso_restore_sorted(xorriso, optc, eff_src_array, eff_tgt_array, 0); - if(ret <= 0) - was_failure= 1; - } - if(xorriso->pacifier_count>0) - Xorriso_pacifier_callback(xorriso, "files restored",xorriso->pacifier_count, - xorriso->pacifier_total, "", 1|4); - ret= !was_failure; -ex:; - i= optc; - Sfile_destroy_argv(&i, &eff_src_array, 0); - i= optc; - Sfile_destroy_argv(&i, &eff_tgt_array, 0); - Xorriso_opt_args(xorriso, "-cp*x", - argc, argv, *idx, &end_idx_dummy, &optc, &optv, 256); - return(ret); -} - - -/* Option -cut_out */ -int Xorriso_option_cut_out(struct XorrisO *xorriso, char *disk_path, - char *start, char *count, char *iso_rr_path, int flag) -{ - int ret; - double num; - off_t startbyte, bytecount; - - num= Scanf_io_size(start, 0); - if(num<0 || num > 1.0e18) { /* 10^18 = 10^3 ^ 6 < 2^10 ^ 6 = 2^60 */ - sprintf(xorriso->info_text, - "-cut_out: startbyte address negative or much too large (%s)", start); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - startbyte= num; - num= Scanf_io_size(count, 0); - if(num<=0 || num > 1.0e18) { - sprintf(xorriso->info_text, - "-cut_out: bytecount zero, negative or much too large (%s)", count); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - bytecount= num; - sprintf(xorriso->info_text, - "-cut_out from %s , byte %.f to %.f, and graft as %s", - disk_path, (double) startbyte, (double) (startbyte+bytecount), - iso_rr_path); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - - ret= Xorriso_cut_out(xorriso, disk_path, startbyte, bytecount, - iso_rr_path, 0); - return(ret); -} - - -/* Options -dev , -indev, -outdev */ -/** @param flag bit0= use as indev - bit1= use as outdev - bit2= do not -reassure - bit3= regard overwriteable media as blank - bit4= if the drive is a regular disk file: truncate it to - the write start address - bit5= do not print toc of aquired drive - bit6= do not calm down drive after aquiring it - @return <=0 error , 1 success, 2 revoked by -reassure -*/ -int Xorriso_option_dev(struct XorrisO *xorriso, char *in_adr, int flag) -{ - int ret; - char sfe[5*SfileadrL], *adr; - - adr= in_adr; - if(strcmp(in_adr, "-")==0) - adr= "stdio:/dev/fd/1"; - if(strncmp(adr, "stdio:", 6)==0) { - if(strlen(adr)==6 || strcmp(adr, "stdio:/")==0 || - strcmp(adr, "stdio:.")==0 || strcmp(adr, "stdio:..")==0 || - strcmp(adr, "stdio:-")==0) { - sprintf(xorriso->info_text, - "No suitable path given by device address '%s'", adr); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - } - - if(xorriso->volset_change_pending && (flag&1)) { - sprintf(xorriso->info_text, - "%s: Image changes pending. -commit or -rollback first", - (flag&2) ? "-dev" : "-indev"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - if((flag&1) && (xorriso->in_drive_handle != NULL || adr[0]) && !(flag&4)) { - ret= Xorriso_reassure(xorriso, (flag&2) ? "-dev" : "-indev", - "eventually discard the current image", 0); - if(ret<=0) - return(2); - } - - if(adr[0]==0) { - if((flag&1) && xorriso->in_drive_handle != NULL) { - if(xorriso->in_drive_handle == xorriso->out_drive_handle) - sprintf(xorriso->info_text,"Giving up -dev %s", - Text_shellsafe(xorriso->indev, sfe, 0)); - else - sprintf(xorriso->info_text,"Giving up -indev %s", - Text_shellsafe(xorriso->indev, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - } - if((flag&2) && xorriso->out_drive_handle != NULL && - xorriso->in_drive_handle != xorriso->out_drive_handle) { - sprintf(xorriso->info_text,"Giving up -outdev %s", - Text_shellsafe(xorriso->outdev, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - } - ret= Xorriso_give_up_drive(xorriso, (flag&3)|((flag&32)>>2)); - } else - ret= Xorriso_aquire_drive(xorriso, adr, - (flag & (3 | 32 | 64)) | (((flag & (8 | 16)) >> 1))); - if(ret<=0) - return(ret); - if(xorriso->in_drive_handle == NULL) - xorriso->image_start_mode= 0; /* session setting is invalid by now */ - return(1); -} - - -/* Option -devices */ -/* @return <=0 error , 1 success, 2 revoked by -reassure -*/ -int Xorriso_option_devices(struct XorrisO *xorriso, int flag) -{ - int ret; - char sfe[5*SfileadrL]; - - if(xorriso->volset_change_pending) { - sprintf(xorriso->info_text, - "-devices: Image changes pending. -commit or -rollback first"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - ret= Xorriso_reassure(xorriso, "-devices", - "eventually discard the current image", 0); - if(ret<=0) - return(2); - xorriso->info_text[0]= 0; - if(xorriso->in_drive_handle!=NULL || xorriso->out_drive_handle!=NULL) { - if(xorriso->in_drive_handle == xorriso->out_drive_handle) { - sprintf(xorriso->info_text, "Gave up -dev %s", - Text_shellsafe(xorriso->indev, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - }else { - if(xorriso->in_drive_handle!=NULL) { - sprintf(xorriso->info_text, "Gave up -indev %s", - Text_shellsafe(xorriso->indev, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - } - if(xorriso->out_drive_handle!=NULL) { - sprintf(xorriso->info_text, "Gave up -outdev %s", - Text_shellsafe(xorriso->outdev, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - } - } - Xorriso_give_up_drive(xorriso, 3); - } - ret= Xorriso_show_devices(xorriso, 0); - return(ret); -} - - -/* Option -dialog "on"|"single_line"|"off" */ -int Xorriso_option_dialog(struct XorrisO *xorriso, char *mode, int flag) -{ - if(strcmp(mode, "on") == 0 || strcmp(mode, "multi_line") == 0) - xorriso->dialog= 2; - else if(strcmp(mode, "single_line") == 0) - xorriso->dialog= 2; - else if(strcmp(mode, "off") == 0) - xorriso->dialog= 0; - else { - sprintf(xorriso->info_text, "-dialog: unknown mode '%s'", mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - return(1); -} - - -/* Option -disk_dev_ino "on"|"ino_only"|"off" */ -int Xorriso_option_disk_dev_ino(struct XorrisO *xorriso, char *mode, int flag) -{ - if(strcmp(mode, "on") == 0) - xorriso->do_aaip= (xorriso->do_aaip & ~128) | 16 | 32 | 64; - else if(strcmp(mode, "ino_only") == 0) - xorriso->do_aaip|= 16 | 32 | 64 | 128; - else if(strcmp(mode, "off") == 0) - xorriso->do_aaip &= ~(16 | 32 | 64 | 128); - else { - sprintf(xorriso->info_text, "-disk_dev_ino: unknown mode '%s'", mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - return(1); -} - - -/* Option -disk_pattern "on"|"ls"|"off" */ -int Xorriso_option_disk_pattern(struct XorrisO *xorriso, char *mode, int flag) -{ - if(strcmp(mode, "off")==0) - xorriso->do_disk_pattern= 0; - else if(strcmp(mode, "on")==0) - xorriso->do_disk_pattern= 1; - else if(strcmp(mode, "ls")==0) - xorriso->do_disk_pattern= 2; - else { - sprintf(xorriso->info_text, "-disk_pattern: unknown mode '%s'", mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - return(1); -} - - -/* Option -drive_class */ -int Xorriso_option_drive_class(struct XorrisO *xorriso, - char *d_class, char *pattern, int flag) -{ - int ret= 1; - - if(strcmp(d_class, "banned") == 0) { - ret= Xorriso_lst_new(&(xorriso->drive_blacklist), pattern, - xorriso->drive_blacklist, 1); - } else if(strcmp(d_class, "caution") == 0) { - ret= Xorriso_lst_new(&(xorriso->drive_greylist), pattern, - xorriso->drive_greylist, 1); - } else if (strcmp(d_class, "harmless") == 0) { - ret= Xorriso_lst_new(&(xorriso->drive_whitelist), pattern, - xorriso->drive_whitelist, 1); - } else if (strcmp(d_class, "clear_list") == 0) { - if(strcmp(pattern, "banned") == 0) - Xorriso_lst_destroy_all(&(xorriso->drive_blacklist), 0); - else if(strcmp(pattern, "caution") == 0) - Xorriso_lst_destroy_all(&(xorriso->drive_greylist), 0); - else if(strcmp(pattern, "harmless") == 0) - Xorriso_lst_destroy_all(&(xorriso->drive_whitelist), 0); - else if(strcmp(pattern, "all") == 0) { - Xorriso_lst_destroy_all(&(xorriso->drive_blacklist), 0); - Xorriso_lst_destroy_all(&(xorriso->drive_greylist), 0); - Xorriso_lst_destroy_all(&(xorriso->drive_whitelist), 0); - } else { - sprintf(xorriso->info_text, "-drive_class clear : unknown class '%s'", - pattern); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - ret= 1; - } else { - sprintf(xorriso->info_text, "-drive_class: unknown class '%s'", d_class); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - return(ret); -} - - -/* Option -dummy "on"|"off" */ -int Xorriso_option_dummy(struct XorrisO *xorriso, char *mode, int flag) -{ - xorriso->do_dummy= !!strcmp(mode, "off"); - return(1); -} - - -/* Option -dvd_obs "default"|"32k"|"64k" */ -int Xorriso_option_dvd_obs(struct XorrisO *xorriso, char *obs, int flag) -{ - double num; - - if(strcmp(obs, "default") == 0) - num= 0; - else - num = Scanf_io_size(obs,0); - if(num != 0 && num != 32768 && num != 65536) { - sprintf(xorriso->info_text, - "-dvd_obs : Bad size. Acceptable are 0, 32k, 64k"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } else - xorriso->dvd_obs= num; - return(1); -} - - -/* Option -eject */ -/* @param flag bit0=do not report toc of eventually remaining drives -*/ -int Xorriso_option_eject(struct XorrisO *xorriso, char *which, int flag) -{ - int gu_flag= 4, ret; - - if(strncmp(which,"in",2)==0) - gu_flag|= 1; - else if(strncmp(which,"out",3)==0) - gu_flag|= 2; - else - gu_flag|= 3; - if((gu_flag&1) && xorriso->volset_change_pending) { - sprintf(xorriso->info_text, - "-eject: Image changes pending. -commit or -rollback first"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - if(flag&1) - gu_flag|= 8; - ret= Xorriso_give_up_drive(xorriso, gu_flag); - return(ret); -} - - -/* Options -end , and -rollback_end */ -/* @param flag bit0= discard pending changes - bit1= do not -reassure - @return <=0 error , 1 success, 2 revoked by -reassure -*/ -int Xorriso_option_end(struct XorrisO *xorriso, int flag) -{ - int ret; - char *cmd, *which_will; - - if(flag&1) - cmd= "-rollback_end"; - else - cmd= "-end"; - if(xorriso->volset_change_pending) { - if(flag&1) - which_will= "end the program discarding image changes"; - else - which_will= "commit image changes and then end the program"; - } else { - which_will= "end the program"; - } - if(!(flag&2)) { - ret= Xorriso_reassure(xorriso, cmd, which_will, 0); - if(ret<=0) - return(2); - } - - if(xorriso->volset_change_pending) { - if(flag&1) { - xorriso->volset_change_pending= 0; - } else { - ret= Xorriso_option_commit(xorriso, 1); - xorriso->volset_change_pending= 0; /* no further tries to commit */ - if(ret<=0) - return(ret); - } - } - ret= Xorriso_give_up_drive(xorriso, 3); - if(ret<=0) - return(ret); - return(1); -} - - -/* Option -errfile_log marked|plain path|-|"" */ -int Xorriso_option_errfile_log(struct XorrisO *xorriso, - char *mode, char *path, int flag) -{ - int ret, mode_word; - FILE *fp= NULL; - char sfe[5*SfileadrL]; - - if(path[0]==0 || path[0]=='-') { - /* ok */; - } else { - fp= fopen(path, "a"); - if(fp==0) { - sprintf(xorriso->info_text, "-errfile_log: Cannot open file %s", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - } - mode_word= xorriso->errfile_mode; - if(strcmp(mode, "marked")==0) - mode_word|= 1; - else if(strcmp(mode, "plain")==0) - mode_word&= ~1; - else { - sprintf(xorriso->info_text, "-errfile_log: Unknown mode %s", - Text_shellsafe(mode, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - - Xorriso_process_errfile(xorriso, 0, "log end", 0, 1); - if(xorriso->errfile_fp!=NULL) - fclose(xorriso->errfile_fp); - xorriso->errfile_fp= fp; - xorriso->errfile_mode= mode_word; - ret= Sfile_str(xorriso->errfile_log, path, 0); - if(ret>0) - ret= Xorriso_process_errfile(xorriso, 0, "log start", 0, 1); - if(ret<=0) - return(ret); - return(1); -} - - -/* Option -error_behavior */ -int Xorriso_option_error_behavior(struct XorrisO *xorriso, - char *occasion, char *behavior, int flag) -{ - if(strcmp(occasion, "image_loading")==0) { - if(strcmp(behavior, "best_effort")==0) - xorriso->img_read_error_mode= 0; - else if(strcmp(behavior, "failure")==0 || strcmp(behavior, "FAILURE")==0) - xorriso->img_read_error_mode= 1; - else if(strcmp(behavior, "fatal")==0 || strcmp(behavior, "FATAL")==0) - xorriso->img_read_error_mode= 2; - else { -unknown_behavior:; - sprintf(xorriso->info_text, - "-error_behavior: with '%s': unknown behavior '%s'", - occasion, behavior); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - } else if(strcmp(occasion, "file_extraction")==0) { - if(strcmp(behavior, "best_effort")==0) - xorriso->extract_error_mode= 0; - else if(strcmp(behavior, "keep")==0) - xorriso->extract_error_mode= 1; - else if(strcmp(behavior, "delete")==0) - xorriso->extract_error_mode= 2; - else - goto unknown_behavior; - } else { - sprintf(xorriso->info_text, "-error_behavior: unknown occasion '%s'", - occasion); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - return(1); -} - - -/* Option -external_filter */ -int Xorriso_option_external_filter(struct XorrisO *xorriso, - int argc, char **argv, int *idx, int flag) -{ - int ret, start_idx, end_idx; - - start_idx= *idx; - end_idx= Xorriso_end_idx(xorriso, argc, argv, start_idx, 1); - (*idx)= end_idx; - if(end_idx - start_idx < 3) { - sprintf(xorriso->info_text, - "-external_filter : Not enough arguments given. Needed: name options path %s", - xorriso->list_delimiter); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - ret= Xorriso_external_filter(xorriso, argv[start_idx], - argv[start_idx + 1], argv[start_idx + 2], - end_idx - start_idx - 3, argv + start_idx + 3, 0); - return(ret); -} - - -/* Options -extract , -extract_single */ -/* @param flag bit0=do not report the restored item - bit1=do not reset pacifier, no final pacifier message - bit2= do not make lba-sorted node array for hardlink detection - bit5= -extract_single: eventually do not insert directory tree -*/ -int Xorriso_option_extract(struct XorrisO *xorriso, char *iso_path, - char *disk_path, int flag) -{ - int ret; - char eff_origin[SfileadrL], eff_dest[SfileadrL], *ipth, *eopt[1], *edpt[1]; - - if(xorriso->allow_restore <= 0) { - sprintf(xorriso->info_text, - "-extract: image-to-disk copies are not enabled by option -osirrox"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - if(!(flag&2)) - Xorriso_pacifier_reset(xorriso, 0); - - ipth= iso_path; - if(ipth[0]==0) - ipth= disk_path; - if(disk_path[0]==0) { - sprintf(xorriso->info_text, "-extract: Empty disk_path given"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 1); - ret= 0; goto ex; - } - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_dest, - 2|4); - if(ret<=0) - goto ex; - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, ipth, eff_origin, 2|8); - if(ret<=0) - goto ex; - - eopt[0]= eff_origin; - edpt[0]= eff_dest; - ret= Xorriso_restore_sorted(xorriso, 1, eopt, edpt, (flag & 32 ? 33 : 0)); - - if(!(flag&2)) - Xorriso_pacifier_callback(xorriso, "files restored",xorriso->pacifier_count, - xorriso->pacifier_total, "", 1|4); - if(ret<=0) - goto ex; - - if(!(flag&1)) { - sprintf(xorriso->info_text, "Extracted from ISO image: %s '%s'='%s'\n", - (ret>1 ? "directory" : "file"), eff_origin, eff_dest); - Xorriso_info(xorriso,0); - } - ret= 1; -ex:; - if(!(flag & (4 | 32))) - Xorriso_destroy_node_array(xorriso, 0); - return(ret); -} - - -/* Option -extract_cut */ -int Xorriso_option_extract_cut(struct XorrisO *xorriso, char *iso_rr_path, - char *start, char *count, char *disk_path, int flag) -{ - int ret; - double num; - off_t startbyte, bytecount; - - num= Scanf_io_size(start, 0); - if(num<0 || num > 1.0e18) { /* 10^18 = 10^3 ^ 6 < 2^10 ^ 6 = 2^60 */ - sprintf(xorriso->info_text, - "-extract_cut: startbyte address negative or much too large (%s)", - start); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - startbyte= num; - num= Scanf_io_size(count, 0); - if(num<=0 || num > 1.0e18) { - sprintf(xorriso->info_text, - "-extract_cut: bytecount zero, negative or much too large (%s)", - count); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - bytecount= num; - sprintf(xorriso->info_text, - "-extract_cut from %s , byte %.f to %.f, and store as %s", - iso_rr_path, (double) startbyte, (double) (startbyte+bytecount), - disk_path); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - - ret= Xorriso_extract_cut(xorriso, iso_rr_path, disk_path, - startbyte, bytecount, 0); - return(ret); -} - - -/* Option -file_size_limit */ -int Xorriso_option_file_size_limit(struct XorrisO *xorriso, - int argc, char **argv, int *idx, int flag) -{ - int ret, i, end_idx; - off_t new_limit= 0; - - end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); - if(*idx >= end_idx) - {ret= 2; goto ex;} - if(*idx + 1 == end_idx && strcmp(argv[*idx], "off") == 0) { - xorriso->file_size_limit= 0; - ret= 1; goto ex; - } - for(i= *idx; i < end_idx; i++) - new_limit+= Scanf_io_size(argv[i], 0); - if(new_limit <= 0) { - sprintf(xorriso->info_text, "-file_size_limit: values sum up to %.f", - (double) new_limit); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 1); - ret= 0; goto ex; - } - xorriso->file_size_limit= new_limit; - ret= 1; -ex:; - (*idx)= end_idx; - if(ret > 0) { - if(xorriso->file_size_limit > 0) - sprintf(xorriso->info_text, "-file_size_limit now at %.f\n", - (double) xorriso->file_size_limit); - else - sprintf(xorriso->info_text, "-file_size_limit now off\n"); - Xorriso_info(xorriso,0); - } - return(ret); -} - - -/* Option -find alias -findi, and -findx */ -/* @param flag bit0= -findx rather than -findi - bit1= do not reset pacifier, no final pacifier message - do not reset find_compare_result - bit2= do not count deleted files with rm and rm_r - bit3= use Xorriso_findi_sorted() rather than Xorriso_findi() - (this can also be ordered by test -sort_lba) -*/ -int Xorriso_option_find(struct XorrisO *xorriso, int argc, char **argv, - int *idx, int flag) -{ - int ret, i, end_idx, type= 0, action, deleter= 0, start_lba, count; - struct FindjoB *job, *first_job= NULL, *new_job; - char *start_path, sfe[5*SfileadrL], *cpt, other_path_start[SfileadrL]; - char *access_acl_text= NULL, *default_acl_text= NULL; - - struct stat dir_stbuf; - uid_t user= 0; - gid_t group= 0; - time_t date= 0; - mode_t mode_or= 0, mode_and= ~1; - double mem_lut= 0.0; - - end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); - start_path= "."; - if(end_idx > *idx && start_path[0]!=0) - start_path= argv[*idx]; - ret= Findjob_new(&first_job, start_path, 0); - if(ret<=0) { - Xorriso_no_findjob(xorriso, "-find[ix]", 0); - {ret= -1; goto ex;} - } - job= first_job; - if(!(flag&2)) - xorriso->find_compare_result= 1; - for(i= *idx+1; i=end_idx) { -not_enough_arguments:; - sprintf(xorriso->info_text, - "-find[ix]: not enough arguments with test %s", - Text_shellsafe(argv[i], sfe, 0)); - goto sorry_ex; - } - i++; - ret= Findjob_set_name_expr(job, argv[i], 0); - if(ret<=0) { - sprintf(xorriso->info_text, "-find[ix]: cannot set -name expression %s", - Text_shellsafe(argv[i], sfe, 0)); - goto sorry_ex; - } - } else if(strcmp(argv[i], "-wholename")==0) { - if(i+1>=end_idx) - goto not_enough_arguments; - i++; - ret= Findjob_set_name_expr(job, argv[i], 1); - if(ret<=0) { - sprintf(xorriso->info_text, - "-find[ix]: cannot set -wholename expression %s", - Text_shellsafe(argv[i], sfe, 0)); - goto sorry_ex; - } - } else if(strcmp(argv[i], "-type")==0) { - if(i+1>=end_idx) - goto not_enough_arguments; - i++; - ret= Findjob_set_file_type(job, argv[i][0], 0); - if(ret<=0) { - sprintf(xorriso->info_text, "-find[ix]: unknown -type '%c'",argv[i][0]); - goto sorry_ex; - } - } else if(strcmp(argv[i], "-damaged")==0) { - Findjob_set_damage_filter(job, 1, 0); - } else if(strcmp(argv[i], "-undamaged")==0) { - Findjob_set_damage_filter(job, -1, 0); - } else if(strcmp(argv[i], "-lba_range")==0) { - if(i+2>=end_idx) - goto not_enough_arguments; - i+= 2; - sscanf(argv[i-1], "%d", &start_lba); - sscanf(argv[i], "%d", &count); - Findjob_set_lba_range(job, start_lba, count, 0); - } else if(strcmp(argv[i], "-pending_data")==0) { - Findjob_set_commit_filter_2(job, 0); - } else if(strcmp(argv[i], "-has_acl")==0) { - Findjob_set_acl_filter(job, 1, 0); - } else if(strcmp(argv[i], "-has_no_acl")==0) { - Findjob_set_acl_filter(job, -1, 0); - } else if(strcmp(argv[i], "-has_xattr")==0) { - Findjob_set_xattr_filter(job, 1, 0); - } else if(strcmp(argv[i], "-has_any_xattr")==0) { - Findjob_set_xattr_filter(job, 1, 1); - } else if(strcmp(argv[i], "-has_no_xattr")==0) { - Findjob_set_xattr_filter(job, -1, 0); - } else if(strcmp(argv[i], "-has_aaip")==0) { - Findjob_set_aaip_filter(job, 1, 0); - } else if(strcmp(argv[i], "-has_no_aaip")==0) { - Findjob_set_aaip_filter(job, -1, 0); - } else if(strcmp(argv[i], "-has_filter")==0) { - Findjob_set_filter_filter(job, 1, 0); - } else if(strcmp(argv[i], "-has_no_filter")==0) { - Findjob_set_filter_filter(job, -1, 0); - } else if(strcmp(argv[i], "-has_md5")==0) { - Findjob_set_prop_filter(job, 15, 1, 0); - } else if(strcmp(argv[i], "-true") == 0) { - ret= Findjob_set_false(job, -1, 0); - } else if(strcmp(argv[i], "-false") == 0) { - ret= Findjob_set_false(job, 1, 0); - } else if(strcmp(argv[i], "-decision") == 0) { - if(i+1>=end_idx) - goto not_enough_arguments; - i++; - ret= Findjob_set_decision(job, argv[i], 0); - } else if(strcmp(argv[i], "-prune") == 0) { - ret= Findjob_set_prune(job, 0); - } else if(strcmp(argv[i], "-sub") == 0 || strcmp(argv[i], "(") == 0) { - ret= Findjob_open_bracket(job, 0); - } else if(strcmp(argv[i], "-subend") == 0 || strcmp(argv[i], ")") == 0) { - ret= Findjob_close_bracket(job, 0); - } else if(strcmp(argv[i], "-not") == 0 || strcmp(argv[i], "!") == 0) { - ret= Findjob_not(job, 0); - } else if(strcmp(argv[i], "-and") == 0 || strcmp(argv[i], "-a") == 0) { - ret= Findjob_and(job, 0); - } else if(strcmp(argv[i], "-or") == 0 || strcmp(argv[i], "-o") == 0) { - ret= Findjob_or(job, 0); - } else if(strcmp(argv[i], "-if") == 0) { - ret= Findjob_if(job, 0); - } else if(strcmp(argv[i], "-then") == 0) { - ret= Findjob_then(job, 0); - } else if(strcmp(argv[i], "-else") == 0) { - ret= Findjob_else(job, 0); - } else if(strcmp(argv[i], "-elseif") == 0) { - ret= Findjob_elseif(job, 0); - } else if(strcmp(argv[i], "-endif") == 0) { - ret= Findjob_endif(job, 0); - } else if(strcmp(argv[i], "-sort_lba") == 0) { - flag|= 8; - /* If an operator is open: insert a -true test, else do nothing */ - ret= Findjob_set_false(job, -1, 1); - if(ret == 2) - ret= 1; - } else if(strcmp(argv[i], "-exec")==0) { - if(i+1>=end_idx) { -not_enough_exec_arguments:; - sprintf(xorriso->info_text, - "-find[ix]: not enough arguments with -exec %s", - Text_shellsafe(argv[i], sfe, 0)); - goto sorry_ex; - } - i++; - cpt= argv[i]; - if(*cpt=='-') - cpt++; - if(strcmp(cpt, "echo")==0) { - Findjob_set_action_target(job, 0, NULL, 0); - } else if(strcmp(cpt, "rm")==0) { - Findjob_set_action_target(job, 1, NULL, 0); - deleter= 1; - } else if(strcmp(cpt, "rm_r")==0) { - Findjob_set_action_target(job, 2, NULL, 0); - deleter= 1; - -#ifdef NIX -/* >>> not implemented yet */; - } else if(strcmp(cpt, "mv")==0) { - if(i+1>=end_idx) - goto not_enough_exec_arguments; - i++; - Findjob_set_action_target(job, 3, argv[i], 0); -#endif - - } else if(strcmp(cpt, "chown")==0 || strcmp(cpt, "chown_r")==0) { - if(i+1>=end_idx) - goto not_enough_exec_arguments; - i++; - ret= Xorriso_convert_uidstring(xorriso, argv[i], &user, 0); - if(ret<=0) - goto ex; - ret= Findjob_set_action_chown(job, user, strlen(cpt)>5); - if(ret<=0) { - Xorriso_no_findjob(xorriso, "-find -exec chown_r", 0); - goto ex; - } - } else if(strcmp(cpt, "chgrp")==0 || strcmp(cpt, "chgrp_r")==0) { - if(i+1>=end_idx) - goto not_enough_exec_arguments; - i++; - ret= Xorriso_convert_gidstring(xorriso, argv[i], &group, 0); - if(ret<=0) - goto ex; - ret= Findjob_set_action_chgrp(job, group, strlen(cpt)>5); - if(ret<=0) { - Xorriso_no_findjob(xorriso, "-find -exec chgrp_r", 0); - goto ex; - } - } else if(strcmp(cpt, "chmod")==0 || strcmp(cpt, "chmod_r")==0) { - if(i+1>=end_idx) - goto not_enough_exec_arguments; - i++; - ret= Xorriso_convert_modstring(xorriso, "-find -exec chmod", - argv[i], &mode_and, &mode_or, 0); - if(ret<=0) - goto ex; - ret= Findjob_set_action_chmod(job, mode_and, mode_or, strlen(cpt)>5); - if(ret<=0) { - Xorriso_no_findjob(xorriso, "-find -exec chmod_r", 0); - goto ex; - } - } else if(strcmp(cpt, "alter_date")==0 || strcmp(cpt, "alter_date_r")==0){ - if(i+2>=end_idx) - goto not_enough_exec_arguments; - i+= 2; - ret= Xorriso_convert_datestring(xorriso, "-find -exec alter_date", - argv[i-1], argv[i], &type, &date, 0); - if(ret<=0) - goto ex; - ret= Findjob_set_action_ad(job, type, date, strlen(cpt)>10); - if(ret<=0) { - Xorriso_no_findjob(xorriso, "-find -exec alter_date_r", 0); - goto ex; - } - } else if(strcmp(cpt, "lsdl")==0) { - Findjob_set_action_target(job, 8, NULL, 0); - - } else if(strcmp(cpt, "find")==0) { - ret= Findjob_new(&new_job, "", 0); - if(ret<=0) { - Xorriso_no_findjob(xorriso, "-find[ix]", 0); - {ret= -1; goto ex;} - } - Findjob_set_action_subjob(job, 13, new_job, 0); - job= new_job; - - } else if(strcmp(cpt, "compare")==0 || strcmp(cpt, "update")==0 || - strcmp(cpt, "widen_hardlinks")==0) { - if(i+1>=end_idx) - goto not_enough_exec_arguments; - i++; - action= 14; - if(strcmp(cpt, "update")==0) - action= 17; - if(strcmp(cpt, "widen_hardlinks")==0) - action= 32; - ret= Xorriso_make_abs_adr(xorriso, xorriso->wdx, argv[i], - other_path_start, 1|2|4|8); - if(ret<=0) - goto ex; - Findjob_set_action_target(job, action, other_path_start, 0); - ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, start_path,sfe, 1|2|4); - if(ret<=0) - goto ex; - Findjob_set_start_path(job, sfe, 0); - if(!(flag&2)) { - Xorriso_pacifier_reset(xorriso, 0); - mem_lut= xorriso->last_update_time; - } - } else if(strcmp(cpt, "in_iso")==0 || - strcmp(cpt, "not_in_iso")==0 || - strcmp(cpt, "add_missing")==0 || - strcmp(cpt, "empty_iso_dir")==0 || - strcmp(cpt, "is_full_in_iso")==0) { - if(i+1>=end_idx) - goto not_enough_exec_arguments; - i++; - ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, argv[i], - other_path_start, 1|2|4); - if(ret<=0) - goto ex; - if(strcmp(cpt, "in_iso")==0) - action= 15; - else if(strcmp(cpt, "add_missing")==0) - action= 18; - else if(strcmp(cpt, "empty_iso_dir")==0) - action= 19; - else if(strcmp(cpt, "is_full_in_iso")==0) - action= 20; - else - action= 16; - Findjob_set_action_target(job, action, other_path_start, 0); - ret= Xorriso_make_abs_adr(xorriso, xorriso->wdx, start_path, sfe, - 1|2|4|8); - if(ret<=0) - goto ex; - Findjob_set_start_path(job, sfe, 0); - - } else if(strcmp(cpt, "report_damage")==0) { - Findjob_set_action_target(job, 21, NULL, 0); - } else if(strcmp(cpt, "report_lba")==0) { - Findjob_set_action_target(job, 22, NULL, 0); - } else if(strcmp(cpt, "getfacl")==0) { - Findjob_set_action_target(job, 24, NULL, 0); - } else if(strcmp(cpt, "setfacl")==0) { - if(i+1>=end_idx) - goto not_enough_exec_arguments; - i++; - ret= Xorriso_normalize_acl_text(xorriso, argv[i], - &access_acl_text, &default_acl_text, 0); - if(ret <= 0) - goto ex; - Findjob_set_action_text_2(job, 25, access_acl_text, default_acl_text, - 0); - } else if(strcmp(cpt, "getfattr")==0) { - Findjob_set_action_target(job, 26, NULL, 0); - } else if(strcmp(cpt, "setfattr")==0) { - if(i + 2 >= end_idx) - goto not_enough_exec_arguments; - i+= 2; - /* check input */ - ret= Xorriso_path_setfattr(xorriso, NULL, "", argv[i - 1], - strlen(argv[i]), argv[i], 1); - if(ret <= 0) - goto ex; - Findjob_set_action_text_2(job, 27, argv[i - 1], argv[i], 0); - } else if(strcmp(cpt, "set_filter")==0) { - if(i + 1 >= end_idx) - goto not_enough_exec_arguments; - i+= 1; - Findjob_set_action_target(job, 28, argv[i], 0); - if(!(flag&2)) { - Xorriso_pacifier_reset(xorriso, 0); - mem_lut= xorriso->last_update_time; - } - } else if(strcmp(cpt, "show_stream")==0) { - Findjob_set_action_target(job, 29, NULL, 0); - } else if(strcmp(cpt, "get_any_xattr")==0) { - Findjob_set_action_target(job, 33, NULL, 0); - } else if(strcmp(cpt, "get_md5")==0) { - Findjob_set_action_target(job, 34, NULL, 0); - } else if(strcmp(cpt, "check_md5")==0) { - if(i + 1 >= end_idx) - goto not_enough_exec_arguments; - i+= 1; - Findjob_set_action_target(job, 35, argv[i], 0); - flag|= 8; - if(!(flag&2)) { - Xorriso_pacifier_reset(xorriso, 0); - mem_lut= xorriso->last_update_time; - } - if(!(flag & 1)) - xorriso->find_check_md5_result= 0; - } else if(strcmp(cpt, "make_md5")==0) { - Findjob_set_action_target(job, 36, NULL, 0); - flag|= 8; - if(!(flag&2)) { - Xorriso_pacifier_reset(xorriso, 0); - mem_lut= xorriso->last_update_time; - } - } else if(strcmp(cpt, "mkisofs_r")==0) { - Findjob_set_action_target(job, 37, NULL, 0); - } else if(strcmp(cpt, "sort_weight")==0) { - if(i + 1 >= end_idx) - goto not_enough_exec_arguments; - i+= 1; - sscanf(argv[i], "%d", &type); - Findjob_set_action_type(job, 38, type, 0); - } else { - sprintf(xorriso->info_text, "-find -exec: unknown action %s", - Text_shellsafe(argv[i], sfe, 0)); - goto sorry_ex; - } - } else { - sprintf(xorriso->info_text, "-find[ix]: unknown option %s", - Text_shellsafe(argv[i], sfe, 0)); -sorry_ex:; - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - } - if(flag&1) - ret= Xorriso_findx(xorriso, first_job, "", start_path, &dir_stbuf, 0, NULL, - 0); - else if(flag & 8) { - cpt= start_path; - ret= Xorriso_findi_sorted(xorriso, first_job, (off_t) 0, 1, &cpt, 0); - } else - ret= Xorriso_findi(xorriso, first_job, NULL, (off_t) 0, NULL, - start_path, &dir_stbuf, 0, (flag&4)>>1); -ex:; - if(deleter && !(flag&2)) - Xorriso_pacifier_callback(xorriso, "iso_rr_paths deleted", - xorriso->pacifier_count, 0, "", 1|2); - else if(first_job->action == 28 && !(flag&2)) - Xorriso_pacifier_callback(xorriso, "file filters processed", - xorriso->pacifier_count, 0, "", 1 | 2); - else if(mem_lut!=xorriso->last_update_time && mem_lut!=0.0 && !(flag&2)) - Xorriso_pacifier_callback(xorriso, "content bytes read", - xorriso->pacifier_count, 0, "", 1); - if(first_job->action == 35 && !(flag & 1)) - Xorriso_report_md5_outcome(xorriso, first_job->target, 0); - if(access_acl_text != NULL) - free(access_acl_text); - if(default_acl_text != NULL) - free(default_acl_text); - Findjob_destroy(&first_job, 0); - (*idx)= end_idx; - return(ret); -} - - -/* Option -follow */ -int Xorriso_option_follow(struct XorrisO *xorriso, char *mode, int flag) -{ - int was_fl, was_fm, was_fpr, was_fpt, l; - double num; - char *cpt, *npt; - - was_fpt= xorriso->do_follow_pattern; - was_fpr= xorriso->do_follow_param; - was_fl= xorriso->do_follow_links; - was_fm= xorriso->do_follow_mount; - xorriso->do_follow_pattern= 0; - xorriso->do_follow_param= 0; - xorriso->do_follow_links= 0; - xorriso->do_follow_mount= 0; - npt= cpt= mode; - for(cpt= mode; npt!=NULL; cpt= npt+1) { - npt= strchr(cpt,':'); - if(npt==NULL) - l= strlen(cpt); - else - l= npt-cpt; - if(l==0) - goto unknown_mode; - if(strncmp(cpt, "off", l)==0) { - xorriso->do_follow_pattern= 0; - xorriso->do_follow_param= 0; - xorriso->do_follow_links= 0; - xorriso->do_follow_mount= 0; - } else if(strncmp(cpt, "on", l)==0) { - xorriso->do_follow_pattern= 1; - xorriso->do_follow_param= 1; - xorriso->do_follow_links= 1; - xorriso->do_follow_mount= 1; - } else if(strncmp(cpt, "default", l)==0) { - xorriso->do_follow_pattern= 1; - xorriso->do_follow_param= 0; - xorriso->do_follow_links= 0; - xorriso->do_follow_mount= 1; - xorriso->follow_link_limit= 100; - } else if(strncmp(cpt, "link", l)==0 || strncmp(cpt,"links", l)==0) { - xorriso->do_follow_links= 1; - } else if(strncmp(cpt, "mount", l)==0) { - xorriso->do_follow_mount= 1; - } else if(strncmp(cpt,"param", l)==0) { - xorriso->do_follow_param= 1; - } else if(strncmp(cpt, "pattern", l)==0) { - xorriso->do_follow_pattern= 1; - } else if(strncmp(cpt, "limit=", 6)==0) { - sscanf(cpt+6, "%lf", &num); - if(num<=0 || num>1.0e6) { - sprintf(xorriso->info_text, "-follow: Value too %s with '%s'", - num<=0 ? "small" : "large", cpt+6); - goto sorry_ex; - } - xorriso->follow_link_limit= num; - } else { -unknown_mode:; - if(linfo_text, "-follow: unknown mode '%s'", cpt); - else - sprintf(xorriso->info_text, "-follow: oversized mode parameter (%d)",l); -sorry_ex: - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - xorriso->do_follow_pattern= was_fpt; - xorriso->do_follow_param= was_fpr; - xorriso->do_follow_links= was_fl; - xorriso->do_follow_mount= was_fm; - return(0); - } - } - return(1); -} - - -/* Option -fs */ -int Xorriso_option_fs(struct XorrisO *xorriso, char *size, int flag) -{ - double num; - - num= Scanf_io_size(size, 0); - if(num < 64*1024 || num > 1024.0 * 1024.0 * 1024.0) { - sprintf(xorriso->info_text, "-fs: wrong size %.f (allowed: %.f - %.f)", - num, 64.0 * 1024.0, 1024.0 * 1024.0 * 1024.0); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - xorriso->fs= num / 2048.0; - if(xorriso->fs * 2048 < num) - xorriso->fs++; - return(1); -} - - -/* Optionis -getfacl alias -getfacli, -getfacl_r alias -getfacl_ri - -getfattr alias getfattri -*/ -/* @param flag bit0= recursive -getfacl_r - bit1= getfattr rather than getfacl - bit3= with bit1: do not ignore eventual non-user attributes -*/ -int Xorriso_option_getfacli(struct XorrisO *xorriso, - int argc, char **argv, int *idx, int flag) -{ - int i, ret, was_failure= 0, end_idx, fret; - int optc= 0; - char **optv= NULL; - struct FindjoB *job= NULL; - struct stat dir_stbuf; - - ret= Xorriso_opt_args(xorriso, "-getfacl", argc, argv, *idx, &end_idx, &optc, - &optv, 0); - if(ret<=0) - goto ex; - for(i= 0; i0 && !xorriso->request_to_abort) - continue; /* regular bottom of loop */ - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - ret= 0; goto ex; - } - ret= 1; -ex:; - (*idx)= end_idx; - Xorriso_opt_args(xorriso, "-getfacl", argc, argv, *idx, &end_idx, - &optc, &optv, 256); - Findjob_destroy(&job, 0); - if(ret<=0) - return(ret); - return(!was_failure); -} - - -/* Option -gid */ -int Xorriso_option_gid(struct XorrisO *xorriso, char *gid, int flag) -{ - int ret; - - xorriso->do_global_gid= 0; - if(gid[0]==0 || strcmp(gid,"-")==0) - return(1); - ret= Xorriso_convert_gidstring(xorriso, gid, &(xorriso->global_gid), 0); - if(ret>0) - xorriso->do_global_gid= 1; - return(ret); -} - - -/* Option -grow_blindly */ -int Xorriso_option_grow_blindly(struct XorrisO *xorriso, char *msc2, int flag) -{ - double num; - int l; - - if(msc2[0]==0 || msc2[0]=='-' || strcmp(msc2, "off")==0) { - xorriso->grow_blindly_msc2= -1; - return(1); - } - num= Scanf_io_size(msc2, 0); - l= strlen(msc2); - if(msc2[l-1]<'0' || msc2[l-1]>'9') - num/= 2048.0; - xorriso->grow_blindly_msc2= num; - return(1); -} - - -/* Option -hardlinks "on"|"off" */ -int Xorriso_option_hardlinks(struct XorrisO *xorriso, char *mode, int flag) -{ - int ret; - char what_data[SfileadrL], *what, *what_next; - - if(Sfile_str(what_data, mode, 0)<=0) { - sprintf(xorriso->info_text, - "-hardlinks: mode string is much too long (%d)", - (int) strlen(mode)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - for(what= what_data; what != NULL; what= what_next) { - what_next= strchr(what, ':'); - if(what_next != NULL) { - *what_next= 0; - what_next++; - } - if(strcmp(what, "off") == 0) { - Xorriso_finish_hl_update(xorriso, 0); - xorriso->ino_behavior|= 1 | 2 | 4; - xorriso->ino_behavior&= ~8; - } else if(strcmp(what, "on") == 0) { - xorriso->ino_behavior&= ~(1 | 2 | 4 | 8); - } else if(strcmp(what, "without_update") == 0) { - Xorriso_finish_hl_update(xorriso, 0); - xorriso->ino_behavior&= ~(1 | 2 | 4); - xorriso->ino_behavior|= 8; - } else if(strcmp(what, "start_update") == 0) { - xorriso->ino_behavior&= ~(1 | 2 | 4 | 8); - ret= Xorriso_make_di_array(xorriso, 1); - if(ret <= 0) - return(ret); - } else if(strcmp(what, "end_update") == 0) { - Xorriso_finish_hl_update(xorriso, 0); - } else if(strcmp(what, "perform_update") == 0) { - Xorriso_finish_hl_update(xorriso, 0); - } else if(strcmp(what, "start_extract") == 0) { - xorriso->ino_behavior&= ~(1 | 2 | 4); - ret= Xorriso_make_hln_array(xorriso, 1); - if(ret <= 0) - return(ret); - } else if(strcmp(what, "end_extract") == 0) { - Xorriso_destroy_hln_array(xorriso, 0); - } else if(strcmp(what, "discard_extract") == 0) { - Xorriso_destroy_hln_array(xorriso, 0); - } else if(strcmp(what, "normal_extract") == 0) { - xorriso->ino_behavior&= ~16; - } else if(strcmp(what, "cheap_sorted_extract") == 0) { - xorriso->ino_behavior|= 16; - } else { - sprintf(xorriso->info_text, "-hardlinks: unknown mode '%s' in '%s'", - what, mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - } - if(xorriso->ino_behavior & 2) - Xorriso_option_compliance(xorriso, "new_rr", 0); - - return(1); -} - - -/* Option -help and part of -prog_help */ -int Xorriso_option_help(struct XorrisO *xorriso, int flag) -{ - static char text[][80]={ - -#ifdef Xorriso_no_helP - -"This binary program does not contain a help text.", -"If available, read: man 1 xorriso", - -#else - -"This program creates, loads, manipulates and writes ISO 9660 filesystem", -"images with Rock Ridge extensions. Write targets can be drives with optical", -"media or local filesystem objects.", -"", -"Preparation options:", -"Drive addresses are either /dev/... as listed with option -devices or", -"disk files, eventually with prefix \"stdio:\" if non-CD-drive in /dev tree.", -"E.g. /dev/sr0 , /tmp/pseudo_drive , stdio:/dev/sdc", -" -dev address Set input and output drive and load eventual ISO image.", -" Set the image expansion method to growing.", -" -indev address Set input drive and load eventual ISO image. Use expansion", -" methods modifying or blind growing.", -" -outdev address", -" Set output drive and use modifying or blind growing.", -" -drive_class \"harmless\"|\"banned\"|\"risky\"|\"clear_list\" disk_pattern", -" Add a drive path pattern to one of the safety lists or make", -" those lists empty. Defaulty entry in \"risky\" is \"/dev\".", -" -grow_blindly \"off\"|predicted_nwa", -" Switch between modifying and blind growing.", -" -load \"session\"|\"track\"|\"lba\"|\"sbsector\"|\"volid\"|\"auto\" id", -" Load a particular (outdated) ISO image from a -dev or", -" -indev which hosts more than one session.", -" -rom_toc_scan \"on\"|\"force\"|\"off\"[:\"emul_on\"|\"emul_off\"]", -" Enable scanning for ISO sessions on read-only drives/media", -" resp. on overwriteable media with emulated TOC.", -" -calm_drive \"in\"|\"out\"|\"all\"|\"on\"|\"off\"", -" Reduce drive noise until it gets actually used again.", -" -assert_volid pattern severity", -" Accept input image only if its volume id matches pattern.", -" -charset name Set the character set name to be used for file name", -" conversion from and to media.", -" -in_charset name", -" Like -charset but only for conversion from media.", -" -auto_charset \"on\"|\"off\"", -" Enable writing and reading of character set name in image.", -" -out_charset name", -" Like -charset but only for conversion to media.", -" -local_charset name", -" Override system assumption of the local character set name.", -" -hardlinks mode[:mode ...]", -" Enable resp. disable recording and restoring of hard links.", -" Modes are \"on\", \"off\", \"perform_update\",", -" \"without_update\", \"discard_extract\",", -" \"cheap_sorted_extract\", \"normal_extract\"", -" -acl \"on\"|\"off\"", -" Enable resp. disable reading and writing of ACLs.", -" -xattr \"on\"|\"off\"", -" Enable resp. disable reading and writing of xattr.", -" -for_backup", -" Shortcut for: -hardlinks on -acl on -xattr on -md5 on", -" -disk_dev_ino \"on\"|\"ino_only\"|\"off\"", -" Enable resp. disable recording of disk file dev_t and ino_t", -" and their use in file comparison.", -" -md5 \"on\"|\"all\"|\"off\"", -" Enable resp. disable processing of MD5 checksums.", -" -scdbackup_tag list_path record_name", -" Enable production of scdbackup tag with -md5 on", -" -ban_stdio_write", -" Allow for writing only the usage of optical drives.", -" -blank \"fast\"|\"all\"|\"deformat\"|\"deformat_quickest\"", -" Blank media resp. invalidate ISO image on media.", -" -format \"as_needed\"|\"full\"|\"fast\"|\"by_index_#\"|\"by_size_#\"", -" Format BD-RE, BD-R, DVD-RAM, DVD-RW, DVD+RW.", -" -volid volume_id", -" Specifies the volume ID text. (32 chars out of [A-Z0-9_])", -" -volset_id name", -" Specifies the volume set id. (128 chars)", -" -publisher name", -" Specifies the publisher name. (128 chars)", -" -application_id name", -" Specifies the application id. (128 chars)", -" -system_id name", -" Specifies the system id for the System Area. (32 chars)", -" -volume_date type timestring", -" Specifies volume timestamps. [\"c\",\"m\",\"x\",\"f\",\"uuid\"]", -" -joliet \"on\"|\"off\"", -" Generate Joliet info additional to Rock Ridge info.", -" -compliance rule[:rule...]", -" Allow more or less harmless deviations from strict standards", -" compliance.", -" -boot_image \"any\"|\"isolinux\"|\"grub\"", -" \"discard\"|\"keep\"|\"patch\"|\"dir=\"|\"bin_path=\"|\"cat_path=\"", -" |\"load_size=\"|\"system_area=\"|\"partition_table=on|off\"", -" Whether to discard or keep an exiting El Torito boot image.", -" ISOLINUX can be made bootable by dir=/ or dir=/isolinux", -" or dir=/boot/isolinux. Others, like GRUB, by bin_path=...", -" and cat_path=...", -" The boot image and its helper files need to be added to the", -" ISO image by the usual commands like -map or -add.", -" system_area= and partition_table= are for MBR based booting", -" from USB stick. The system_area= file needs not to be added.", -"", -" -uid uid User id to be used for the whole multi-session ISO image.", -" -gid gid Group id for the same purpose.", -"", -" -devices Show list of available optical drives and their addresses.", -"", -" -toc Show media specific table of content (sessions).", -"", -" -mount_cmd drive entity id path", -" Print to result channel a command suitable to mount the", -" depicted entity (see -load) at the given directory path.", -" -mount_opts \"exclusive\"|\"shared\"", -" Set options for -mount and -mount_cmd.", -" -session_string drive entity id \"linux:\"path|\"freebsd:\"path|form", -" Print foreign OS command or custom line.", -"", -" -list_formats Show media specific list of format descriptors.", -"", -" -list_profiles \"in\"|\"out\"|\"all\"", -" Show list of media types supported by indev resp. outdev.", -" -print_size Print the foreseeable consumption by next -commit.", -"", -" -tell_media_space", -" Print foreseeable available space on output media", -" -pvd_info Print various id strings of the loaded ISO image." -"", -"Options with variable length path list [...] need the list delimiter text", -"as end mark if they are followed by another option. By default this delimiter", -"is \"--\". In dialog and with options read from files, the line end serves", -"as such a mark. With program arguments this mark can be omitted only with", -"the last option in the list of arguments.", -"For brevity the list delimiter is referred as \"--\" throughout this text.", -"", -" -list_delimiter text Set the list delimiter to be used instead of \"--\"", -" It has to be a single word, must not be empty, not longer", -" than 80 characters, may mot contain quotation marks.", -"", -"Manipulation options:", -"disk_path is a path to an object in the local filesystem tree.", -"iso_rr_path is the Rock Ridge name of a file object in the ISO image.", -"pathspec is either a disk_path or (if allowed) a pair: iso_rr_path=disk_path", -"Options marked by [***] have variable argument length and perform pattern", -"expansion if enabled by -iso_rr_pattern resp. -disk_pattern.", -"", -" -pathspecs \"on\"|\"off\" Allow or disallow pathspecs of form ", -" iso_rr_path=disk_path . Only \"off\" allows eventual", -" -disk_pattern expansion.", -" -add pathspec [...] | disk_path [***]", -" Insert the given files or directory trees from", -" filesystem into the ISO image. Much like mkisofs.", -" -add_plainly \"none\"|\"unknown\"|\"dashed\"|\"any\"", -" Whether to add lonely arguments as pathspec resp. disk_path.", -" -path_list disk_path", -" Like -add but read the pathspecs from file disk_path.", -" -quoted_path_list disk_path", -" Like -path_list but with line rules as -dialog \"on\".", -"", -" -map disk_path iso_rr_path", -" Insert disk file object at the given iso_rr_path.", -" -map_single disk_path iso_rr_path", -" Like -map but with directory do not insert its sub tree.", -" -map_l disk_prefix iso_rr_prefix disk_path [***]", -" Performs -map with each disk_path.", -" -update disk_path iso_rr_path", -" Compare both file objects and do what is necessary to make", -" iso_rr_path a matching copy of disk_path.", -" -update_r disk_path iso_rr_path", -" Like -update but affecting all files below directories.", -" -update_l disk_prefix iso_rr_prefix disk_path [***]", -" Performs -update_r with each disk_path.", -" -cut_out disk_path byte_offset byte_count iso_rr_path", -" Map a byte interval of a regular disk file into a regular", -" file in the ISO image.", -"", -" -cpr disk_path [***] iso_rr_path", -" Insert the given files or directory trees from filesystem", -" into the ISO image, according to the rules of cp -r.", -"", -" -rm iso_rr_path [***]", -" Delete the given files from the ISO image.", -" -rm_r iso_rr_path [***]", -" Delete the given directory trees from ISO image.", -" -mv iso_rr_path [***] iso_rr_path", -" Rename the given file objects in the ISO tree to the last", -" argument in the list.", -" -chown uid iso_rr_path [***]", -" Equivalent to chown in the ISO image.", -" -chown_r uid iso_rr_path [***]", -" Like -chown but affecting all files below directories.", -" -chgrp gid iso_rr_path [***]", -" Equivalent to chgrp in the ISO image.", -" -chgrp_r gid iso_rr_path [***]", -" Like -chgrp but affecting all files below directories.", -" -chmod mode iso_rr_path [***]", -" Equivalent to chmod in the ISO image.", -" -chmod_r mode iso_rr_path [***]", -" Like -chmod but affecting all files below directories.", -" -setfacl acl_text iso_rr_path [***]", -" Replace the permissions and eventual ACL of the given files", -" in the ISO image by the ACL which is defined by acl_text.", -" -setfacl_r acl_text iso_rr_path [***]", -" Like -setfacl but affecting all files below directories.", -" -setfacl_list disk_path", -" Read output of getfacl from file disk_path. Set owner,", -" group and ACL of the iso_rr_path given by line \"# file:\".", -" -setfattr [-]name value iso_rr_path [***]", -" Set xattr pair with the given name to the given value, or", -" delete pair if name is prefixed with \"-\" and value is", -" an empty text.", -" -setfattr_r [-]name value iso_rr_path [***]", -" Like -setfattr but affecting all files below directories.", -" -setfattr_list disk_path", -" Read output of getfattr from file disk_path. Replace the", -" xattr of the iso_rr_path given by line \"# file:\".", -" -alter_date type timestring iso_rr_path [***]", -" Alter the date entries of a file in the ISO image. type is", -" one of \"a\", \"m\", \"b\" for:", -" access time, modification time, both times.", -" -alter_date_r type timestring iso_rr_path [***]", -" Like -alter_date but affecting all files below directories.", -" -find iso_rr_path [test [op] [test ...]] [-exec action [params]]", -" performs an action on files below the given directory in", -" the ISO image. Tests:", -" -name pattern, -wholename pattern, -type b|c|d|p|f|l|s|e,", -" -pending_data, -lba_range start count, -damaged,", -" -has_acl, -has_xattr, -has_aaip, -has_filter, -has_md5", -" -has_any_xattr, -prune, -decision yes|no, -true, -false", -" Operators: -not, -or, -and, -sub, (, -subend, ),", -" -if, -then, -elseif, -else, -endif", -" Action may be one of: echo, chown, chown_r, chgrp, chgrp_r", -" chmod, chmod_r, alter_date, alter_date_r, lsdl, compare,", -" rm, rm_r, compare, update, report_damage, report_lba,", -" getfacl, setfacl, getfattr, setfattr, get_any_xattr,", -" get_md5, check_md5, make_md5, set_filter, show_stream,", -" mkisofs_r, find.", -" params are their arguments except iso_rr_path.", -" -mkdir iso_rr_path [...]", -" Create empty directories if they do not exist yet.", -" -rmdir iso_rr_path [***]", -" Delete empty directories.", -" -- Default list delimiter marking the end of action argument", -" list. It may be changed by option -list_delimiter.", -"", -" -not_paths disk_path [***]", -" Add the given paths to the list of excluded absolute paths.", -" -not_leaf pattern", -" Add the given pattern to the list of leafname exclusions.", -" -not_list disk_path", -" Read lines from disk_path and use as -not_paths (with \"/\")", -" or as -not_leaf (without \"/\").", -" -quoted_not_list disk_path", -" Like -not_list but with line rules as -dialog \"on\".", -" -not_mgt \"reset\"|\"on\"|\"off\"|\"param_on\"|\"subtree_on\"|\"ignore_on\"", -" Control effect of exclusion lists.", -" -follow \"on\"|\"pattern:param:link:mount:limit=#\"|\"default\"|\"off\"", -" Follow symbolic links and mount points within disk_path.", -" -overwrite \"on\"|\"nondir\"|\"off\"", -" Allow or disallow to overwrite existing files in ISO image.", -" -split_size number[\"k\"|\"m\"]", -" Set the threshold for automatic splitting of regular files.", -" -reassure \"on\"|\"tree\"|\"off\"", -" If \"on\" then ask the user for \"y\" or \"n\" with any", -" file before deleting or overwriting it in the ISO image.", -"", -"Filter options:", -"External filter processes may produce synthetic file content by reading the", -"original content from stdin and writing to stdout whatever they want.", - -#ifdef Xorriso_allow_external_filterS - -" -external_filter name option[:option] program_path [arguments] --", -" Define an external filter. Options are: suffix=...: ", -" remove_suffix:if_nonempty:if_reduction:if_block_reduction.", -" -unregister_filter name", -" Undefine an external filter.", -" -close_filter_list", -" Irrevocably ban -external_filter and -unregister_filter.", - -#else - -"Sorry: The use of external filters was not enabled at compile time.", -" E.g. by ./configure option --enable-external-filters", - -#endif /* ! Xorriso_allow_external_filterS */ - -" -set_filter name iso_rr_path [***]", -" Apply a defined filter to the given data files.", -" Special name \"--remove-all-filters\" revokes filtering.", -" Builtin filters are --gzip , --gunzip, --zisofs .", -" -set_filter_r name iso_rr_path [***]", -" Like -set_filter but affecting all files below directories.", -"", -"zisofs is a compression format which is recognized by some Linux kernels.", -"xorriso supports it by builtin filter \"--zisofs\" which is to be applied by", -"the user, and by \"--zisofs-decode\" which is applied automatically when", -"compressed content is detected with a file in the ISO image.", -" -zisofs option[:options]", -" Set global zisofs parameters:", -" level=0|...|9 , block_size=32k|64k|128k , by_magic=on|off", -"", -"Write-to-media options:", -" -rollback Discard the manipulated ISO image and reload it.", -"", -" -commit Perform the write operation and then perform -dev outdrive.", -" Hint: To perform a final write operation with no new -dev", -" and no new loading of image, execute option -end.", -" -commit_eject \"in\"|\"out\"|\"all\"|\"none\"", -" Like -commit but rather eject than load image from outdrive.", -" Give up any unejected drive afterwards.", -" -close \"on\"|\"off\"", -" If \"on\" then mark the written media as not appendable.", -" -padding number[\"k\"|\"m\"]", -" Append extra bytes to image stream. (Default is 300k)", -" -dummy \"on\"|\"off\"", -" If \"on\" simulate burning. Refuse if media cannot simulate.", -" -speed number[\"k/s\"|\"m/s\"|\"[x]CD\"|\"[x]DVD\"|\"[x]BD\"]", -" Set the burn speed. Default is 0 = maximum speed.", -" -stream_recording \"on\"|\"off\"", -" Try to circumvent slow checkread on DVD-RAM, BD-RE, BD-R.", -" -dvd_obs \"default\"|\"32k\"|\"64k\"", -" Set number of bytes per DVD/BD write operation.", -" -stdio_sync \"on\"|\"off\"|number", -" Set number of bytes after which to force output to stdio", -" pseudo drives. \"on\" is the same as 16m.", -" -fs number[\"k\"|\"m\"]", -" Set the size of the fifo buffer. (Default is 4m)", -" -eject \"in\"|\"out\"|\"all\"", -" Immediately eject the media in -indev, resp. -outdev,", -" resp. both.", -"", -"Navigation options:", -"", -" -cd iso_rr_path Change working directory in the ISO image. iso_rr_paths", -" which do not begin with '/' will be inserted beginning at", -" the path given with -cd. -ls patterns will eventually", -" looked up at this path.", -" -cdi disk_path Same as -cd disk_path", -" -cdx disk_path Change the current working directory in the local", -" filesystem. disk_paths which do not begin with '/'", -" will be looked up beginning at the path given with -cdx.", -" -lsx patterns will eventually be looked up at this path.", -" -pwd tells the current working directory in the ISO image.", -" -pwdi same as -pwd.", -" -pwdx tells the current working directory in the local filesystem.", -"", -" -iso_rr_pattern \"on\"|\"ls\"|\"off\"", -" Enable or disable pattern expansions for ISO image commands", -" marked by [***]. \"ls\" restricts it to -ls and -du.", -" -disk_pattern \"on\"|\"ls\"|\"off\"", -" Enable or disable pattern expansions for local filesystem", -" commands marked by [***]. \"ls\" restricts to -ls*x and -du*x.", -"", -" -ls pattern [***] lists files of the ISO image which match one of the", -" given shell parser patterns. (I.e. wildcards '*' '?').", -" Directories are listed by their content.", -" -lsd pattern [***] like -ls but listing directories as single items.", -" -lsl pattern [***] like -ls but also telling some file attributes.", -" -lsdl pattern [***] like -lsd but also telling some file attributes.", -"", -" -lsx pattern [***] lists files of the local filesystem which match one", -" of the patterns. Directories are listed by their content.", -" -lsdx pattern [***] like -lsx but listing directories as single items.", -" -lslx pattern [***] like -lsx but also telling some file attributes.", -" -lsdlx pattern [***] like -lsdx but also telling some file attributes.", -" -getfacl pattern [***] list eventual ACLs of the given files.", -" -getfacl_r pattern [***] like -getfacl but listing whole file trees.", -" -getfattr pattern [***] list eventual xattr of the given files.", -" -getfxattr_r pattern [***] like -getfxattr but listing whole file trees.", -"", -" -du pattern [***] recursively lists sizes of files or directories in the", -" ISO image which match one of the shell parser patterns.", -" -dux pattern [***] recursively lists sizes of files or directories in the", -" local filesystem which match one of the shell parser", -" patterns.", -" -dus pattern [***] like -du but summing up subdirectories without", -" listing them explicitely.", -" -dusx pattern [***] like -dux but summing up subdirectories without", -" listing them explicitely.", -"", -" -findx disk_path [-name pattern] [-type t] [-exec action [params]]", -" Like -find but operating on local filesystem. Most -exec", -" actions are defaulted to action echo. Supported actions are:", -" in_iso, not_in_iso, is_full_in_iso, add_missing,", -" empty_iso_dir", -"", -" -compare disk_path iso_rr_path", -" compare attributes and in case of regular data files the", -" content of filesystem object and ISO object.", -" -compare_r disk_path iso_rr_path", -" Like -compare but affecting all files below directories.", -" -compare_l disk_prefix iso_rr_prefix disk_path [***]", -" Performs -compare_r with each disk_path.", -"", -" -show_stream iso_rr_path [***]", -" Show content stream chain of data files in the ISO image.", -" -show_stream_r iso_rr_path [***]", -" Like -show_stream but affecting all files below directories.", -"", -"Restore options which copy file objects from ISO image to disk filesystem:", -" -osirrox \"on\"|\"device_files\"|\"off\"|\"banned\"", -" [:\"concat_split_on\"|\"concat_split_off\"]", -" [:\"auto_chmod_on\"|\"auto_chmod_off\"]", -" [:\"sort_lba_on\"|\"sort_lba_off\"]", -" By default \"off\" the inverse operation of xorriso from ISO", -" image to disk filesystem is disabled. \"on\" allows xorriso", -" to create, overwrite, delete files in the disk filesystem.", -" \"banned\" is irrevocably \"off\".", -" -extract iso_rr_path disk_path", -" Copy tree under iso_rr_path onto disk address disk_path.", -" This avoids the pitfalls of cp -r addressing rules.", -" -extract_l iso_rr_prefix disk_prefix iso_rr_path [***]", -" Perform -extract with each iso_rr_path.", -" -extract_single iso_rr_path disk_path", -" Like -extract but with directory do not restore sub tree.", -" -extract_cut iso_rr_path byte_offset byte_count disk_path", -" Copy a byte interval from iso_rr_path to disk_path.", -" This is governed in part by -check_media_defaults.", -" -cpx iso_rr_path [***] disk_path", -" Copy leaf file objects from ISO image to disk filesystem.", -" -cpax iso_rr_path [***] disk_path", -" Like -cpx but trying to restore timestamps and ownership.", -" -cp_rx iso_rr_path [***] disk_path", -" Copy directory trees from ISO image to disk filesystem.", -" -cp_rax iso_rr_path [***] disk_path", -" Like -cp_rx but trying to restore timestamps and ownership.", -" -paste_in iso_rr_path disk_path byte_offset byte_count", -" Copy ISO file content into a byte interval of a disk file.", -" -mount drive entity id path", -" Like -mount_cmd but actually performing that command if", -" not setuid or setgid is active.", -"", -"Evaluation of readability:", -" -check_media [options] --", -" Try to read data blocks from media and report about the", -" outcome. Several options modify the behavior:", -" use=indev|outdev , what=track|session ,", -" min_lba=blockadr , max_lba=blockadr ,", -" abort_file=path , time_limit=seconds , item_limit=number ,", -" retry=on|off|default , data_to=filepath ,", -" sector_map=filepath , map_with_volid=on|off ,", -" patch_lba0=on|off|force|blockadr[:force] ,", -" report=blocks|files|blocks_files event=severity ,", -" bad_limit=quality , slow_limit=seconds , chunk_size=bytes", -" -check_media_defaults [options] --", -" Preset options for runs of -check_media and -extract_cut.", -"", -"Compatibility emulation (argument list may be ended by list delimiter --):", -" -as mkisofs [-help|-version|-o|-R|-r|-J|-V|-P|-f|-m|-exclude-list|", -" -no-pad|-M|-C|-graft-points|-path-list|pathspecs|-z|", -" -no-emul-boot|-b|-c|-boot-info-table|-boot-load-size|-G]", -" Perform some mkisofs gestures, understand pathspecs as mkisofs", -" does. Commit happens outside emulation at usual occasions.", -" -as cdrecord [-help|-v|dev=|speed=|blank=|fs=|-eject|-atip|padsize=|-multi]", -" path|-", -" Perform some cdrecord gestures, eventually write at most one", -" data track to blank, appendable or overwriteable media.", -" -pacifier \"xorriso\"|\"cdrecord\"|\"mkisofs\"", -" Choose format of UPDATE pacifier during write operations.", -"", -"General options:", -" -help Print this text", -" -abort_on severity Set the threshhold for events to abort the program.", -" Useful severities: NEVER, ABORT, FATAL, FAILURE, SORRY, WARNING", -" -return_with severity exit_value Set the threshhold for events to return", -" at program end the given exit_value even if not aborted.", -" exit_value may be 0 or 32 to 63.", -" -report_about severity Set the threshhold for events to be reported.", -" Use -abort_on severities or: HINT, NOTE, UPDATE, DEBUG, ALL", -" -error_behavior \"image_loading\"|\"file_extraction\" behavior", -" Behavior \"best_effort\" is most endurant but may produce", -" results which are correct only on the first glimpse.", -" -dialog \"on\"|\"off\"|\"single_line\"", -" After all arguments are processed, enter dialog mode.", -" \"single_line\" does not support newline characters within", -" open quotation marks and no line continuation by trailing \\.", -" -page len width Prompt user after len output lines (0=no prompt).", -" width (default 80) can adjust line number computation", -" to the output terminal's line width.", -#ifdef Xorriso_with_readlinE -" -use_stdin Use raw standard input even if libreadline is available", -" -use_readline Use libreadline for dialog if available", -" -history text Copy text into libreadline history. This command", -" itself is not copied to the history list.", -#endif /* Xorriso_with_readlinE */ -" -backslash_codes \"on\"|\"off\"|", -" \"in_double_quotes\"|\"in_quotes\"|\"with_quoted_input\"", -" [:\"with_program_arguments\"][:\"encode_output\"]", -" Disable or enable interpretation of \\a \\b \\e \\f \\n \\r \\t \\v", -" \\\\ \\NNN \\xNN \\cC in input or program arguments.", -" -pkt_output \"on\"|\"off\" Direct output to stdout and prefix each line", -" by a short header which tells channel id and a mode number.", -" Each such output packet is finalized by a newline.", -" Channel ids are 'R:' for result lines, 'I:' for notes", -" and error messages, 'M:' for -mark texts. Bit 0 of the", -" mode number tells whether the newline is also part of the", -" packet payload. Example of a info message with newline:", -" I:1: enter option text :", -" -pkt_output:on is intended for use by frontend programs.", -" -logfile channel fileaddress Copy output of a channel to the given file.", -" channel may be 'R','I','M' as with -pkt_output or '.'", -" for the consolidated -pkt_output stream.", -" -mark text If text is not empty it will get put out each time an", -" option is completed.", -" -temp_mem_limit number[\"k\"|\"m\"]", -" Set the maximum size for pattern expansion. (Default is 16m)", -" -prog text Use text as this program's name in subsequent messages", -" -prog_help text Use text as this program's name and perform -help", -" -status mode|filter Report the current settings of persistent options.", -" Modes:", -" short... print only important or altered options", -" long ... print options even if they have default settings", -" long_history like long plus -history: lines", -" Filters begin with '-' and are compared literally against the", -" output lines of -status long_history. A line is put out only", -" if its start matches the filter.", -" -status_history_max number Maximum number of history lines to be reported", -" with -status:long_history", -" -options_from_file fileaddress", -" Reads lines from the given file and executes them as program", -" options.", -" -no_rc Only if used as first command line argument this option", -" prevents reading and interpretation of startup files.", -" -print text", -" Print a text to result channel.", -" -prompt text", -" Wait for Enter key resp. for a line of input at stdin.", -" -errfile_log mode path|channel", -" Log disk paths of files involved in problem events.", -" -session_log path", -" Set path of a file where a log record gets appended after", -" each session. Form: timestamp start_lba size volume-id", -" -scsi_log \"on\"|\"off\"", -" Enable or disable logging of SCSI commands to stderr.", -" # any text Is ignored. In dialog mode the input line will be stored in", -" the eventual readline history, nevertheless.", -" -version Tell program and version number", -" -end End program. Commit eventual pending changes.", -" -rollback_end", -" End program. Discard pending changes.", -"", -"", -"Option -page causes a user prompt after the given number of result lines.", -"Empty input resumes output until the next prompt. Other input may be:", -" @ suppresses paging until the current action is done", -" @@ suppresses further result output but continues the action", -" @@@ aborts the current action", -" other aborts the current action and executes input as new", -" option", -"", - -#endif /* ! Xorriso_no_helP */ - -"@ENDE_OF_HELPTEXT_(HOPEFULLY_UNIQUELY_SILLY_TEXT)@" - }; - - char *tpt= NULL; - int i,pass; - - Xorriso_restxt(xorriso,"\n"); - sprintf(xorriso->result_line,"usage: %s [settings|actions]\n", - xorriso->progname); - Xorriso_result(xorriso,0); - Xorriso_restxt(xorriso,"\n"); - for(pass=0;pass<1;pass++) { - for(i=0;1;i++) { - if(pass==0) - tpt= text[i]; - - if(strcmp(tpt,"@ENDE_OF_HELPTEXT_(HOPEFULLY_UNIQUELY_SILLY_TEXT)@")==0) - break; - sprintf(xorriso->result_line,"%s\n",tpt); - Xorriso_result(xorriso,0); - if(xorriso->request_to_abort) - return(1); - } - } - Xorriso_restxt(xorriso,"\n"); - return(1); -} - - -/* Option -history */ -int Xorriso_option_history(struct XorrisO *xorriso, char *line, int flag) -{ - Xorriso_dialog_input(xorriso,line,strlen(line)+1,2); - return(1); -} - - -/* Option -iso_rr_pattern "on"|"ls"|"off" */ -int Xorriso_option_iso_rr_pattern(struct XorrisO *xorriso, char *mode,int flag) -{ - if(strcmp(mode, "off")==0) - xorriso->do_iso_rr_pattern= 0; - else if(strcmp(mode, "on")==0) - xorriso->do_iso_rr_pattern= 1; - else if(strcmp(mode, "ls")==0) - xorriso->do_iso_rr_pattern= 2; - else { - sprintf(xorriso->info_text, "-iso_rr_pattern: unknown mode '%s'", mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - return(1); -} - - -/* Option -joliet "on"|"off" */ -int Xorriso_option_joliet(struct XorrisO *xorriso, char *mode, int flag) -{ - if(strcmp(mode, "off")==0) - xorriso->do_joliet= 0; - else if(strcmp(mode, "on")==0) - xorriso->do_joliet= 1; - else { - sprintf(xorriso->info_text, "-joliet: unknown mode '%s'", mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - return(1); -} - - -/* Option -list_delimiter */ -int Xorriso_option_list_delimiter(struct XorrisO *xorriso, char *text, - int flag) -{ - int ret, argc; - char **argv= NULL; - - if(text[0] == 0) { - sprintf(xorriso->info_text, - "-list_delimiter: New delimiter text is empty"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - if(strlen(text) > 80) { - sprintf(xorriso->info_text, - "-list_delimiter: New delimiter text is too long"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - ret= Sfile_make_argv(xorriso->progname, text, &argc, &argv, 4); - if(ret > 0) { - if(argc > 2) { - sprintf(xorriso->info_text, - "-list_delimiter: New delimiter text contains more than one word"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } - Sfile_make_argv(xorriso->progname, text, &argc, &argv, 2); - if(argc > 2) - return(0); - } - if(strchr(text, '"') != NULL || strchr(text, '\'') != NULL) { - sprintf(xorriso->info_text, - "-list_delimiter: New delimiter text contains quotation marks"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - strcpy(xorriso->list_delimiter, text); - return(1); -} - - -/* Option -list_formats */ -int Xorriso_option_list_formats(struct XorrisO *xorriso, int flag) -{ - int ret; - - ret= Xorriso_list_formats(xorriso, 0); - return(ret); -} - - -/* Option -list_profiles */ -int Xorriso_option_list_profiles(struct XorrisO *xorriso, char *which, - int flag) -{ - int ret; - int mode= 0; - - if(strncmp(which,"in",2)==0) - mode|= 1; - else if(strncmp(which,"out",3)==0) - mode|= 2; - else - mode|= 3; - if(mode & 1) { - ret= Xorriso_toc(xorriso, 1 | 16 | 32); - if(ret > 0) - Xorriso_list_profiles(xorriso, 0); - } - if((mode & 2) && xorriso->in_drive_handle != xorriso->out_drive_handle) { - ret= Xorriso_toc(xorriso, 1 | 2 | 16 | 32); - if(ret > 0) - Xorriso_list_profiles(xorriso, 2); - } - return(1); -} - - -/* Option -load session|track|sbsector value */ -/* @param flag bit0= with adr_mode sbsector: adr_value is possibly 16 too high - @return <=0 error , 1 success, 2 revoked by -reassure -*/ -int Xorriso_option_load(struct XorrisO *xorriso, char *adr_mode, - char *adr_value, int flag) -{ - int ret; - - if(xorriso->volset_change_pending) { - sprintf(xorriso->info_text, - "-load: Image changes pending. -commit or -rollback first"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - ret= Xorriso_reassure(xorriso, "-load", "loads an alternative image", 0); - if(ret<=0) - return(2); - ret= Xorriso_decode_load_adr(xorriso, "-load", adr_mode, adr_value, - &(xorriso->image_start_mode), - xorriso->image_start_value, flag & 1); - if(ret <= 0) - return(ret); - xorriso->image_start_mode|= (1<<30); /* enable non-default msc1 processing */ - if(strlen(xorriso->indev)>0) { - ret= Xorriso_option_rollback(xorriso, 1); /* Load image, no -reassure */ - if(ret<=0) - return(ret); - } - return(1); -} - - -/* Option -logfile */ -int Xorriso_option_logfile(struct XorrisO *xorriso, char *channel, - char *fileadr, int flag) -{ - int hflag,channel_no= 0, ret; - - if(channel[0]==0) { -logfile_wrong_form:; - sprintf(xorriso->info_text,"Wrong form. Correct would be: -logfile \".\"|\"R\"|\"I\"|\"M\" file_address"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - hflag= 2; - if(channel[0]=='R') - channel_no= 1; - else if(channel[0]=='I') - channel_no= 2; - else if(channel[0]=='M') - channel_no= 3; - else if(channel[0]=='.') - hflag= 4; - else - goto logfile_wrong_form; - if(strcmp(fileadr,"-")==0 || fileadr[0]==0) - hflag|= (1<<15); - xorriso->logfile[channel_no][0]= 0; - ret= Xorriso_write_to_channel(xorriso, fileadr, channel_no, hflag); - if(ret<=0) { - sprintf(xorriso->info_text, "Cannot open logfile: %s", fileadr); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - } else if(!(hflag&(1<<15))) - if(Sfile_str(xorriso->logfile[channel_no], fileadr, 0)<=0) - return(-1); - return(ret>0); -} - - -/* Options -ls alias -lsi and -lsl alias -lsli - and -lsd alias -lsdi and -lsdl alias -lsdli - and -du alias -dui and -dus alias -dusi - @param flag bit0= long format (-lsl , -du) - bit1= do not expand patterns but use literally - bit2= du rather than ls - bit3= list directories as themselves (ls -d) -*/ -int Xorriso_option_lsi(struct XorrisO *xorriso, int argc, char **argv, - int *idx, int flag) -{ - int ret, end_idx, filec= 0, nump, i; - char **filev= NULL, **patterns= NULL; - off_t mem= 0; - struct stat stbuf; - - end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1); - if(xorriso->do_iso_rr_pattern==0) - flag|= 2; - - nump= end_idx - *idx; - if((flag&2) && nump>0 ) { - ; - } else if(nump <= 0) { - if(Xorriso_iso_lstat(xorriso, xorriso->wdi, &stbuf, 0)<0) { - sprintf(xorriso->info_text, - "Current -cd path does not yet exist in the ISO image"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - {ret= 0; goto ex;} - } - if(!S_ISDIR(stbuf.st_mode)) { - sprintf(xorriso->info_text, - "Current -cd meanwhile points to a non-directory in ISO image"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - {ret= 0; goto ex;} - } - patterns= calloc(1, sizeof(char *)); - if(patterns == NULL) { -no_memory:; - sprintf(xorriso->info_text, - "Cannot allocate enough memory for pattern expansion"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - {ret= -1; goto ex;} - } - nump= 1; - if(flag&8) - patterns[0]= "."; - else - patterns[0]= "*"; - flag&= ~2; - } else { - patterns= calloc(nump, sizeof(char *)); - if(patterns==NULL) - goto no_memory; - for(i= 0; iino_behavior & 1)) { - ret= Xorriso_make_hln_array(xorriso, 0); /* for stbuf.st_nlink */ - if(ret < 0) - return(ret); - } - if(flag&2) { - ret= Xorriso_ls_filev(xorriso, xorriso->wdi, nump, argv + (*idx), mem, - flag&(1|4|8)); - } else if(nump==1 && strcmp(patterns[0],"*")==0 && !(flag&4)){ - /* save temporary memory by calling simpler function */ - ret= Xorriso_ls(xorriso, (flag&1)|4); - } else { - ret= Xorriso_expand_pattern(xorriso, nump, patterns, 0, &filec, &filev, - &mem, 0); - if(ret<=0) - {ret= 0; goto ex;} - ret= Xorriso_ls_filev(xorriso, xorriso->wdi, filec, filev, mem, - flag&(1|4|8)); - } - if(ret<=0) - {ret= 0; goto ex;} - - ret= 1; -ex:; - if(patterns!=NULL) - free((char *) patterns); - Sfile_destroy_argv(&filec, &filev, 0); - (*idx)= end_idx; - return(ret); -} - - -/* Options -lsx, -lslx, -lsdx , -lsdlx , -dux , -dusx - @param flag bit0= long format (-lslx , -dux) - bit1= do not expand patterns but use literally - bit2= du rather than ls - bit3= list directories as themselves (ls -d) -*/ -int Xorriso_option_lsx(struct XorrisO *xorriso, int argc, char **argv, - int *idx, int flag) -{ - int ret, end_idx, filec= 0, nump, i; - char **filev= NULL, **patterns= NULL; - off_t mem= 0; - - end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1|2); - if(xorriso->do_disk_pattern==0) - flag|= 2; - - nump= end_idx - *idx; - if((flag&2) && nump>0) { - ; - } else if(nump <= 0) { - patterns= calloc(1, sizeof(char *)); - if(patterns == NULL) { -no_memory:; - sprintf(xorriso->info_text, - "Cannot allocate enough memory for pattern expansion"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - {ret= -1; goto ex;} - } - nump= 1; - if(flag&8) - patterns[0]= "."; - else - patterns[0]= "*"; - flag&= ~2; - } else { - patterns= calloc(nump, sizeof(char *)); - if(patterns==NULL) - goto no_memory; - for(i= 0; iwdx, - nump, argv + (*idx), mem, flag&(1|4|8)); - -#ifdef Not_yeT - } else if(nump==1 && strcmp(patterns[0],"*")==0 && !(flag&4)){ - /* save temporary memory by calling simpler function */ - ret= Xorriso_ls(xorriso, (flag&1)|4); -#endif - - } else { - ret= Xorriso_expand_disk_pattern(xorriso, nump, patterns, 0, &filec, &filev, - &mem, 0); - if(ret<=0) - {ret= 0; goto ex;} - ret= Xorriso_lsx_filev(xorriso, xorriso->wdx, filec, filev, mem, - flag&(1|4|8)); - } - if(ret<=0) - {ret= 0; goto ex;} - - ret= 1; -ex:; - if(patterns!=NULL) - free((char *) patterns); - Sfile_destroy_argv(&filec, &filev, 0); - (*idx)= end_idx; - return(ret); -} - - -/* Option -map , -map_single */ -/* @param flag bit0=do not report the added item - bit1=do not reset pacifier, no final pacifier message - bit5=eventually do not insert directory tree -*/ -int Xorriso_option_map(struct XorrisO *xorriso, char *disk_path, - char *iso_path, int flag) -{ - int ret; - char eff_origin[SfileadrL], eff_dest[SfileadrL], *ipth; - - if(!(flag&2)) - Xorriso_pacifier_reset(xorriso, 0); - - ipth= iso_path; - if(ipth[0]==0) - ipth= disk_path; - if(disk_path[0]==0) { - sprintf(xorriso->info_text, "-map: Empty disk_path given"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 1); - return(0); - } - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_origin, - 2|4); - if(ret<=0) - return(ret); - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, ipth, eff_dest, 2); - if(ret<=0) - return(ret); - ret= Xorriso_graft_in(xorriso, NULL, eff_origin, eff_dest, - (off_t) 0, (off_t) 0, 2|(flag&32)); - if(!(flag&2)) - Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count, - xorriso->pacifier_total, "", 1); - if(ret<=0) - return(ret); - - if(!(flag&1)) { - sprintf(xorriso->info_text, "Added to ISO image: %s '%s'='%s'\n", - (ret>1 ? "directory" : "file"), (eff_dest[0] ? eff_dest : "/"), - eff_origin); - Xorriso_info(xorriso,0); - } - return(1); -} - - -/* Options -map_l , -compare_l , -update_l , -extract_l */ -/* @param flag bit4= do not establish and dispose xorriso->di_array - for update_l - bit8-11= mode 0= -map_l - 1= -compare_l - 2= -update_l - 3= -extract_l -*/ -int Xorriso_option_map_l(struct XorrisO *xorriso, int argc, char **argv, - int *idx, int flag) -{ - int ret, end_idx, optc= 0, was_failure= 1, i, fret, mode; - int ns_flag= 2|4, nt_flag= 2, opt_args_flag= 2, made_di_array= 0; - char source_prefix[SfileadrL], target_prefix[SfileadrL], *cmd, **optv= NULL; - char eff_source[SfileadrL], eff_target[SfileadrL], *source_pt, *s_wd, *t_wd; - char sfe[5*SfileadrL], **eff_src_array= NULL, **eff_tgt_array= NULL; - - cmd= "-map_l"; - s_wd= xorriso->wdx; - t_wd= xorriso->wdi; - Xorriso_pacifier_reset(xorriso, 0); - mode= (flag>>8) & 15; - - if(mode==1) - cmd= "-compare_l"; - else if(mode==2) - cmd= "-update_l"; - else if(mode==3) { - cmd= "-extract_l"; - ns_flag= 2; - s_wd= xorriso->wdi; - nt_flag= 2|4; - t_wd= xorriso->wdx; - opt_args_flag= 0; - } - - end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1|2); - if(end_idx - (*idx) < 3) { - sprintf(xorriso->info_text, "%s: Not enough arguments given (%d < 3)", cmd, - end_idx - (*idx)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 1); - ret= 0; goto ex; - } - ret= Xorriso_normalize_img_path(xorriso, s_wd, argv[*idx], - source_prefix, ns_flag | 64); - if(ret<=0) - goto ex; - ret= Xorriso_normalize_img_path(xorriso, t_wd, argv[(*idx)+1], - target_prefix, nt_flag); - if(ret<=0) - goto ex; - ret= Xorriso_opt_args(xorriso, cmd, argc, argv, (*idx)+2, &end_idx, - &optc, &optv, opt_args_flag); - if(ret<=0) - goto ex; - - - if(mode == 3 && - (xorriso->do_restore_sort_lba || !(xorriso->ino_behavior & 4))) { - eff_src_array= calloc(optc, sizeof(char *)); - eff_tgt_array= calloc(optc, sizeof(char *)); - if(eff_src_array == NULL || eff_tgt_array == NULL) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - ret= -1; goto ex; - } - for(i= 0; i < optc; i++) - eff_src_array[i]= eff_tgt_array[i]= NULL; - } - if(mode == 2 && !((xorriso->ino_behavior & 2) || (flag & 16) || - xorriso->di_array != NULL)) { - /* Create all-image node array sorted by isofs.di */ - ret= Xorriso_make_di_array(xorriso, 0); - if(ret <= 0) - goto ex; - made_di_array= 1; - } - - for(i= 0; iinfo_text, - "%s: disk_path %s does not begin with disk_prefix ", cmd, - Text_shellsafe(eff_source, sfe, 0)); - Text_shellsafe(source_prefix, - xorriso->info_text+strlen(xorriso->info_text), 0); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 1); - ret= 0; goto ex; - } - source_pt+= strlen(source_prefix); - } - strcat(eff_target, source_pt); - - if(mode==0) - ret= Xorriso_option_map(xorriso, eff_source, eff_target, 2); - else if(mode==1) - ret= Xorriso_option_compare(xorriso, eff_source, eff_target, 2|8); - else if(mode==2) - ret= Xorriso_option_update(xorriso, eff_source, eff_target, 2 | 8 | 16); - else if(mode==3) { - if(eff_src_array != NULL) { - eff_src_array[i]= strdup(eff_source); - eff_tgt_array[i]= strdup(eff_target); - if(eff_src_array[i] == NULL || eff_tgt_array[i] == NULL) { - Xorriso_no_malloc_memory(xorriso, &(eff_src_array[i]), 0); - ret= -1; goto ex; - } - } else { - ret= Xorriso_option_extract(xorriso, eff_source, eff_target, 2 | 4); - } - } - - if(ret>0 && !xorriso->request_to_abort) - continue; /* regular bottom of loop */ - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 2); - if(fret>=0) - continue; - goto ex; - } - - ret= 1; - if(mode == 3 && eff_src_array != NULL) { - ret= Xorriso_lst_append_binary(&(xorriso->node_disk_prefixes), - target_prefix, strlen(target_prefix) + 1, 0); - if(ret <= 0) - goto ex; - ret= Xorriso_lst_append_binary(&(xorriso->node_img_prefixes), - source_prefix, strlen(source_prefix) + 1, 0); - if(ret <= 0) - goto ex; - ret= Xorriso_restore_sorted(xorriso, optc, eff_src_array, eff_tgt_array, 0); - } - if(mode==0) - Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count, - xorriso->pacifier_total, "", 1); - else if(mode==1 || mode==2) - Xorriso_pacifier_callback(xorriso, "content bytes read", - xorriso->pacifier_count, 0, "", 1); - else if(mode==3) - Xorriso_pacifier_callback(xorriso, "files restored",xorriso->pacifier_count, - xorriso->pacifier_total, "", 1|4); -ex:; - Xorriso_destroy_node_array(xorriso, 0); - i= optc; - Sfile_destroy_argv(&i, &eff_src_array, 0); - i= optc; - Sfile_destroy_argv(&i, &eff_tgt_array, 0); - (*idx)= end_idx; - Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, &optc, &optv, 256); - if(ret<=0) - return(ret); - return(!was_failure); -} - - -/* Option -mark */ -int Xorriso_option_mark(struct XorrisO *xorriso, char *mark, int flag) -{ - if(mark[0]==0) - xorriso->mark_text[0]= 0; - else - strncpy(xorriso->mark_text,mark,sizeof(xorriso->mark_text)-1); - xorriso->mark_text[sizeof(xorriso->mark_text)-1]= 0; - return(1); -} - - -/* Option -md5 "on"|"all"|"off" */ -int Xorriso_option_md5(struct XorrisO *xorriso, char *mode, int flag) -{ - char *npt, *cpt; - int l; - - npt= cpt= mode; - for(; npt!=NULL; cpt= npt+1) { - npt= strchr(cpt,':'); - if(npt==NULL) - l= strlen(cpt); - else - l= npt-cpt; - if(l == 0) - continue; - if(l == 3 && strncmp(cpt, "off", l) == 0) - xorriso->do_md5&= ~31; - else if(l == 2 && strncmp(cpt, "on", l) == 0) - xorriso->do_md5= (xorriso->do_md5 & ~31) | 7 | 16; - else if(l == 3 && strncmp(cpt, "all", l) == 0) - xorriso->do_md5|= 31; - else if(l == 18 && strncmp(cpt, "stability_check_on", l) == 0) - xorriso->do_md5|= 8; - else if(l == 19 && strncmp(cpt, "stability_check_off", l) == 0) - xorriso->do_md5&= ~8; - else { - sprintf(xorriso->info_text, "-md5: unknown mode "); - Text_shellsafe(cpt, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - } - return(1); -} - - -/* Option -mkdir alias -mkdiri */ -int Xorriso_option_mkdiri(struct XorrisO *xorriso, int argc, char **argv, - int *idx, int flag) -{ - int i, end_idx, ret, was_failure= 0, fret; - - end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 0); - - for(i= *idx; i0 && !xorriso->request_to_abort) - continue; /* regular bottom of loop */ - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - goto ex; - } - ret= 1; -ex:; - (*idx)= end_idx; - if(ret<=0) - return(ret); - return(!was_failure); -} - - -/* Options -mount , -mount_cmd , -session_string */ -/* @param bit0= -mount_cmd: print mount command to result channel rather - than performing it - bit1= perform -session_string rather than -mount_cmd -*/ -int Xorriso_option_mount(struct XorrisO *xorriso, char *dev, char *adr_mode, - char *adr, char *cmd, int flag) -{ - int ret, entity_code= 0, m_flag; - char entity_id[81], *mnt; - - if(flag & 1) - mnt= "-mount_cmd"; - else if(flag & 2) - mnt= "-session_string"; - else { - mnt= "-mount"; - if(xorriso->allow_restore <= 0) { - sprintf(xorriso->info_text, - "-mount: image-to-disk features are not enabled by option -osirrox"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - if(xorriso->volset_change_pending) { - sprintf(xorriso->info_text, - "%s: Image changes pending. -commit or -rollback first", mnt); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - } - ret= Xorriso_decode_load_adr(xorriso, mnt, adr_mode, adr, - &entity_code, entity_id, 0); - if(ret <= 0) - return(ret); - if(flag & 2) - m_flag= 1 | 4; - else - m_flag= (flag & 1) | 2; - ret= Xorriso_mount(xorriso, dev, entity_code, entity_id, cmd, m_flag); - return(ret); -} - - -/* Option -mount_opts option[:...] */ -int Xorriso_option_mount_opts(struct XorrisO *xorriso, char *mode, int flag) -{ - int was, l; - char *cpt, *npt; - - was= xorriso->mount_opts_flag; - npt= cpt= mode; - for(cpt= mode; npt!=NULL; cpt= npt+1) { - npt= strchr(cpt,':'); - if(npt==NULL) - l= strlen(cpt); - else - l= npt-cpt; - if(l==0) - goto unknown_mode; - if(strncmp(cpt, "shared", l)==0) { - xorriso->mount_opts_flag|= 1; - } else if(strncmp(cpt, "exclusive", l)==0) { - xorriso->mount_opts_flag&= ~1; - } else { -unknown_mode:; - if(linfo_text, "-mount_opts: unknown option '%s'", cpt); - else - sprintf(xorriso->info_text, "-mount_opts: oversized parameter (%d)",l); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - xorriso->mount_opts_flag= was; - return(0); - } - } - return(1); -} - - -/* Option -mv alias -mvi */ -int Xorriso_option_mvi(struct XorrisO *xorriso, int argc, char **argv, - int *idx, int flag) -{ - int i, end_idx_dummy, ret, is_dir= 0, was_failure= 0, fret; - char sfe[5*SfileadrL], sfe2[5*SfileadrL]; - char eff_origin[SfileadrL], eff_dest[SfileadrL], dest_dir[SfileadrL]; - char leafname[SfileadrL]; - int optc= 0; - char **optv= NULL; - - ret= Xorriso_cpmv_args(xorriso, "-mvi", argc, argv, idx, - &optc, &optv, eff_dest, 0); - if(ret<=0) - goto ex; - if(ret==2) { - is_dir= 1; - strcpy(dest_dir, eff_dest); - } - /* Perform movements */ - for(i= 0; iwdi,optv[i],eff_origin,0); - if(ret<=0 || xorriso->request_to_abort) - goto problem_handler; - if(is_dir) { - ret= Sfile_leafname(eff_origin, leafname, 0); - if(ret<=0) - goto problem_handler; - strcpy(eff_dest, dest_dir); - ret= Sfile_add_to_path(eff_dest, leafname, 0); - if(ret<=0) { - sprintf(xorriso->info_text, "Effective path gets much too long (%d)", - (int) (strlen(eff_dest)+strlen(leafname)+1)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - goto problem_handler; - } - } - ret= Xorriso_rename(xorriso, NULL, eff_origin, eff_dest, 0); - if(ret<=0 || xorriso->request_to_abort) - goto problem_handler; - sprintf(xorriso->info_text, "Renamed in ISO image: %s to %s\n", - Text_shellsafe(eff_origin,sfe,0),Text_shellsafe(eff_dest,sfe2,0)); - Xorriso_info(xorriso, 0); - - continue; /* regular bottom of loop */ -problem_handler:; - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - goto ex; - } - ret= !was_failure; -ex:; - Xorriso_opt_args(xorriso, "-mvi", - argc, argv, *idx, &end_idx_dummy, &optc, &optv, 256); - return(ret); -} - - -/* Option -no_rc */ -int Xorriso_option_no_rc(struct XorrisO *xorriso, int flag) -{ - xorriso->no_rc= 1; - return(1); -} - - -/* Option -not_leaf */ -int Xorriso_option_not_leaf(struct XorrisO *xorriso, char *pattern, int flag) -{ - regex_t re; - char regexpr[2*SfileadrL+2], sfe[5*SfileadrL]; - int ret= 0; - - if(pattern[0]==0) - {ret= 0; goto cannot_add;} - Xorriso__bourne_to_reg(pattern, regexpr, 0); - if(regcomp(&re, regexpr, 0)!=0) - {ret= 0; goto cannot_add;} - ret= Exclusions_add_not_leafs(xorriso->disk_exclusions, pattern, &re, 0); - if(ret<=0) { -cannot_add:; - sprintf(xorriso->info_text,"Cannot add pattern: -not_leaf %s", - Text_shellsafe(pattern, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(ret); - } - return(1); -} - - -/* Option -not_list , -quoted_not_list */ -/* @param flag bit0= -quoted_not_list */ -int Xorriso_option_not_list(struct XorrisO *xorriso, char *adr, int flag) -{ - int ret, linecount= 0, insertcount= 0, null= 0, argc= 0, i; - FILE *fp= NULL; - char sfe[5*SfileadrL], **argv= NULL; - - Xorriso_pacifier_reset(xorriso, 0); - if(adr[0]==0) { - sprintf(xorriso->info_text, "Empty file name given with %s", - (flag & 1) ? "-quoted_not_list" : "-not_list"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - ret= Xorriso_afile_fopen(xorriso, adr, "rb", &fp, 0); - if(ret <= 0) - return(0); - while(1) { - ret= Xorriso_read_lines(xorriso, fp, &linecount, &argc, &argv, - 4 | (flag & 1) ); - if(ret <= 0) - goto ex; - if(ret == 2) - break; - for(i= 0; i < argc; i++) { - if(argv[i][0] == 0) - continue; - if(strchr(argv[i], '/')!=NULL) { - null= 0; - ret= Xorriso_option_not_paths(xorriso, 1, argv + i, &null, 0); - } else - ret= Xorriso_option_not_leaf(xorriso, argv[i], 0); - if(ret<=0) - goto ex; - insertcount++; - } - } - ret= 1; -ex:; - if(fp != NULL && fp != stdin) - fclose(fp); - Xorriso_read_lines(xorriso, fp, &linecount, &argc, &argv, 2); - if(ret<=0) { - sprintf(xorriso->info_text, "Aborted reading of file %s in line number %d", - Text_shellsafe(adr, sfe, 0), linecount); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } - sprintf(xorriso->info_text, "Added %d exclusion list items from file %s\n", - insertcount, Text_shellsafe(adr, sfe, 0)); - Xorriso_info(xorriso,0); - return(ret); -} - - -/* Option -not_mgt */ -int Xorriso_option_not_mgt(struct XorrisO *xorriso, char *setting, int flag) -{ - int ret; - char what_data[SfileadrL], *what, *what_next; - - if(Sfile_str(what_data, setting, 0)<=0) { - sprintf(xorriso->info_text, - "-not_mgt: setting string is much too long (%d)", - (int) strlen(setting)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - for(what= what_data; what!=NULL; what= what_next) { - what_next= strchr(what, ':'); - if(what_next!=NULL) { - *what_next= 0; - what_next++; - } - - if(strcmp(what, "reset")==0 || strcmp(what, "erase")==0) { - if(strcmp(what, "reset")==0) - xorriso->disk_excl_mode= 1; - Exclusions_destroy(&(xorriso->disk_exclusions), 0); - ret= Exclusions_new(&(xorriso->disk_exclusions), 0); - if(ret<=0) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - return(ret); - } - } else if(strcmp(what, "on")==0) { - xorriso->disk_excl_mode|= 1; - } else if(strcmp(what, "off")==0) { - xorriso->disk_excl_mode&= ~1; - } else if(strcmp(what, "param_on")==0) { - xorriso->disk_excl_mode|= 2; - } else if(strcmp(what, "param_off")==0) { - xorriso->disk_excl_mode&= ~2; - } else if(strcmp(what, "subtree_on")==0) { - xorriso->disk_excl_mode|= 4; - } else if(strcmp(what, "subtree_off")==0) { - xorriso->disk_excl_mode&= ~4; - } else if(strcmp(what, "ignore_on")==0) { - xorriso->disk_excl_mode|= 8; - } else if(strcmp(what, "ignore_off")==0) { - xorriso->disk_excl_mode&= ~8; - } else { - sprintf(xorriso->info_text, "-not_mgt: unknown setting '%s'", what); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - } - return(1); -} - - -/* Option -not_paths */ -int Xorriso_option_not_paths(struct XorrisO *xorriso, int argc, char **argv, - int *idx, int flag) -{ - int ret, end_idx, num_descr, dummy, optc= 0, i; - char **descr= NULL, **optv= NULL, sfe[5*SfileadrL], eff_path[SfileadrL]; - - - end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, - (xorriso->do_disk_pattern==1) | 2); - if(end_idx<=0) - return(end_idx); - num_descr= end_idx - *idx; - if(num_descr<=0) - {ret= 1; goto ex;} - - /* produce absolute patterns */ - descr= TSOB_FELD(char *, num_descr); - if(descr==NULL) { -no_memory:; - Xorriso_no_pattern_memory(xorriso, sizeof(char *) * (off_t) num_descr, 0); - ret= -1; goto ex; - } - for(i= 0; iwdx, argv[i+*idx], - eff_path, 2|4); - if(ret<=0) - goto ex; - descr[i]= strdup(eff_path); - if(descr[i]==NULL) - goto no_memory; - } - - ret= Xorriso_opt_args(xorriso, "-not_paths", - num_descr, descr, 0, &dummy, &optc, &optv, 2); - if(ret<=0) - goto ex; - ret= Exclusions_add_not_paths(xorriso->disk_exclusions, - num_descr, descr, optc, optv, 0); - if(ret<=0) { - sprintf(xorriso->info_text,"Cannot add path list: -not_paths %s%s %s", - Text_shellsafe(argv[*idx], sfe, 0), (num_descr>1 ? " ..." : ""), - xorriso->list_delimiter); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } -ex:; - (*idx)= end_idx; - Xorriso_opt_args(xorriso, "-not_paths", - num_descr, descr, 0, &dummy, &optc, &optv, 256); - if(descr!=NULL) { - for(i= 0; iinfo_text,"Empty file name given with -options_from_file"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - Text_shellsafe(adr,shellsafe,0); - if(xorriso->is_dialog) { - sprintf(xorriso->info_text,"+ performing command lines from file %s :\n", - shellsafe); - Xorriso_info(xorriso,1); - } - ret= Xorriso_afile_fopen(xorriso, adr, "rb", &fp, 0); - if(ret <= 0) - return(0); - while(1) { - ret= Xorriso_read_lines(xorriso, fp, &linecount, &linec, &linev, 1 | 8); - if(ret <= 0) - goto ex; /* no problem_handler because there is no sense in going on */ - if(ret == 2) - break; - line= linev[0]; - if(line[0]==0 || line[0]=='#') - continue; - - if(flag&1) { - ret= Sfile_make_argv(xorriso->progname, line, &argc, &argv, - 4 | 8 | ((xorriso->bsl_interpretation & 3) << 5)); - if(ret<=0) - goto problem_handler; - ret= Xorriso_prescan_args(xorriso,argc,argv,1); - if(ret==0) - {ret= 3; goto ex;} - if(ret<0) - goto problem_handler; - } else { - if(xorriso->is_dialog) { - sprintf(xorriso->info_text,"+ %d: %s\n",linecount,line); - Xorriso_info(xorriso,1); - } - ret= Xorriso_execute_option(xorriso,line,1|(1<<16)); - if(ret==3) - goto ex; - if(ret<=0) - goto problem_handler; - } - - continue; /* regular bottom of loop */ -problem_handler:; - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1); - if(fret>=0) - continue; - goto ex; - } - ret= 1; -ex:; - Sfile_make_argv("", "", &argc, &argv, 2); /* release memory */ - Xorriso_read_lines(xorriso, fp, &linecount, &linec, &linev, 2); - Xorriso_reset_counters(xorriso,0); - if(fp != NULL && fp != stdin) - fclose(fp); - if(ret<=0) { - sprintf(xorriso->info_text, - "error triggered by line %d of file:\n %s\n", - linecount,shellsafe); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 1); - } - if(ret!=1) - return(ret); - return(!was_failure); -} - - -/* Option -osirrox "on"|"off" */ -int Xorriso_option_osirrox(struct XorrisO *xorriso, char *mode, int flag) -{ - int l, allow_restore; - char *npt, *cpt; - - allow_restore= xorriso->allow_restore; - - npt= cpt= mode; - for(cpt= mode; npt!=NULL; cpt= npt+1) { - npt= strchr(cpt,':'); - if(npt==NULL) - l= strlen(cpt); - else - l= npt-cpt; - if(l==0 && mode[0]!=0) - goto unknown_mode; - if(strncmp(cpt, "off", l)==0) - allow_restore= 0; - else if(strncmp(cpt, "banned", l)==0) - allow_restore= -1; - else if(strncmp(cpt, "device_files", l)==0) - allow_restore= 2; - else if(strncmp(cpt, "on", l)==0 || mode[0]==0) - allow_restore= 1; - else if(strncmp(cpt, "concat_split_on", l)==0) - xorriso->do_concat_split= 1; - else if(strncmp(cpt, "concat_split_off", l)==0) - xorriso->do_concat_split= 0; - else if(strncmp(cpt, "auto_chmod_on", l)==0) - xorriso->do_auto_chmod= 1; - else if(strncmp(cpt, "auto_chmod_off", l)==0) - xorriso->do_auto_chmod= 0; - else if(strncmp(cpt, "sort_lba_on", l)==0) - xorriso->do_restore_sort_lba= 1; - else if(strncmp(cpt, "sort_lba_off", l)==0) - xorriso->do_restore_sort_lba= 0; - else if(strncmp(cpt, "o_excl_off", l)==0) - xorriso->drives_exclusive= 0; - else if(strncmp(cpt, "o_excl_on", l)==0) - xorriso->drives_exclusive= 1; - else { -unknown_mode:; - sprintf(xorriso->info_text, "-osirrox: unknown mode '%s'", cpt); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - } - if(allow_restore > 0 && xorriso->allow_restore == -1) { - sprintf(xorriso->info_text, - "-osirrox: was already permanently disabled by setting 'banned'"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - if(xorriso->allow_restore != -1) - xorriso->allow_restore= allow_restore; - sprintf(xorriso->info_text, - "Copying of file objects from ISO image to disk filesystem is: %s\n", - xorriso->allow_restore > 0 ? "Enabled" : "Disabled"); - Xorriso_info(xorriso, 0); - return(1); -} - - -/* Option -overwrite "on"|"nondir"|"off" */ -int Xorriso_option_overwrite(struct XorrisO *xorriso, char *mode, int flag) -{ - if(strcmp(mode, "off")==0) - xorriso->do_overwrite= 0; - else if(strcmp(mode, "on")==0) - xorriso->do_overwrite= 1; - else if(strcmp(mode, "nondir")==0) - xorriso->do_overwrite= 2; - else { - sprintf(xorriso->info_text, "-overwrite: unknown mode '%s'", mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - return(1); -} - - -/* Option -pacifier */ -int Xorriso_option_pacifier(struct XorrisO *xorriso, char *style, int flag) -{ - if(strcmp(style, "xorriso")==0 || strcmp(style, "default")==0) - xorriso->pacifier_style= 0; - else if(strcmp(style, "mkisofs")==0 || strcmp(style, "genisofs")==0 || - strcmp(style, "genisoimage")==0 || strcmp(style, "xorrisofs")==0) - xorriso->pacifier_style= 1; - else if(strcmp(style, "cdrecord")==0 || strcmp(style, "cdrskin")==0 || - strcmp(style, "wodim")==0 || strcmp(style, "xorrecord")==0) - xorriso->pacifier_style= 2; - else { - sprintf(xorriso->info_text, "-pacifier: unknown behavior code '%s'", style); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - return(1); -} - - -/* Option -padding */ -int Xorriso_option_padding(struct XorrisO *xorriso, char *size, int flag) -{ - double num; - - num= Scanf_io_size(size, 0); - if(num < 0 || num > 1024.0 * 1024.0 * 1024.0) { - sprintf(xorriso->info_text, "-padding: wrong size %.f (allowed: %.f - %.f)", - num, 0.0, 1024.0 * 1024.0 * 1024.0); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - xorriso->padding= num; - if(xorriso->padding/2048 != num/2048.0) - xorriso->padding++; - return(1); -} - - -/* Option -page */ -int Xorriso_option_page(struct XorrisO *xorriso, int len, int width, int flag) -{ - if(len<0 || width<=0) { - sprintf(xorriso->info_text, - "Improper numeric value of arguments of -page: %d %d", - len, width); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - xorriso->result_page_length= len; - xorriso->result_page_width= width; - return(1); -} - - -/* Option -paste_in */ -int Xorriso_option_paste_in(struct XorrisO *xorriso, char *iso_rr_path, - char *disk_path, char *start, char *count, int flag) -{ - int ret; - double num; - off_t startbyte, bytecount; - - num= Scanf_io_size(start, 0); - if(num<0 || num > 1.0e18) { /* 10^18 = 10^3 ^ 6 < 2^10 ^ 6 = 2^60 */ - sprintf(xorriso->info_text, - "-paste_in: startbyte address negative or much too large (%s)", start); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - startbyte= num; - num= Scanf_io_size(count, 0); - if(num<=0 || num > 1.0e18) { - sprintf(xorriso->info_text, - "-paste_in : bytecount zero, negative or much too large (%s)", count); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - bytecount= num; - sprintf(xorriso->info_text, "-paste_in from %s to %s, byte %.f to %.f", - disk_path, iso_rr_path, - (double) startbyte, (double) (startbyte+bytecount)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - - ret= Xorriso_paste_in(xorriso, disk_path, startbyte, bytecount, - iso_rr_path, 0); - return(ret); -} - - -/* Option -path_list , -quoted_path_list */ -/* @param flag bit0= -quoted_path_list */ -int Xorriso_option_path_list(struct XorrisO *xorriso, char *adr, int flag) -{ - int ret,linecount= 0, insertcount= 0, null= 0, was_failure= 0, fret= 0; - int was_ferror= 0, argc= 0, i; - FILE *fp= NULL; - char sfe[5*SfileadrL], **argv= NULL; - - Xorriso_pacifier_reset(xorriso, 0); - if(adr[0]==0) { - sprintf(xorriso->info_text,"Empty file name given with %s", - flag & 1 ? "-quoted_path_list" : "-path_list"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - return(0); - } - ret= Xorriso_afile_fopen(xorriso, adr, "rb", &fp, 0); - if(ret <= 0) - return(0); - while(1) { - ret= Xorriso_read_lines(xorriso, fp, &linecount, &argc, &argv, - 4 | (flag & 1) ); - if(ret <= 0) - goto ex; - if(ret == 2) - break; - for(i= 0; i < argc; i++) { - if(argv[i][0] == 0) - continue; - null= 0; - ret= Xorriso_option_add(xorriso, 1, argv + i, &null, 1|2); - if(ret<=0 || xorriso->request_to_abort) - goto problem_handler; - insertcount++; - } - - continue; /* regular bottom of loop */ -problem_handler:; - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - goto ex; - } - ret= 1; -ex:; - if(flag & 1) - Xorriso_read_lines(xorriso, fp, &linecount, &argc, &argv, 2); - - if(fp != NULL && fp != stdin) - fclose(fp); - Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count, - xorriso->pacifier_total, "", 1); - if(ret<=0) { - sprintf(xorriso->info_text, "Aborted reading of file %s in line number %d", - Text_shellsafe(adr, sfe, 0), linecount); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, - (fret==-2 ? "NOTE" : "FAILURE"), 0); - } else - ret= !was_ferror; - sprintf(xorriso->info_text, "Added %d items from file %s\n", - insertcount, Text_shellsafe(adr, sfe, 0)); - Xorriso_info(xorriso,0); - if(ret<=0) - return(ret); - return(!was_failure); -} - - -/* Option -pathspecs */ -int Xorriso_option_pathspecs(struct XorrisO *xorriso, char *mode, int flag) -{ - if(strcmp(mode, "off")==0) - xorriso->allow_graft_points= 0; - else if(strcmp(mode, "on")==0) - xorriso->allow_graft_points= 1; - else { - sprintf(xorriso->info_text, "-pathspecs: unknown mode '%s'", mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - return(1); -} - - -/* Option -pkt_output */ -int Xorriso_option_pkt_output(struct XorrisO *xorriso, char *mode, int flag) -{ - if(strcmp(mode,"off")==0) - xorriso->packet_output= 0; - else - xorriso->packet_output= 1; - return(1); -} - - -/* Option -print */ -int Xorriso_option_print(struct XorrisO *xorriso, char *text, int flag) -{ - sprintf(xorriso->result_line,"%s\n",text); - Xorriso_result(xorriso,1); - return(1); -} - - -/* Option -print_size - @param flag bit0= report in mkisofs compatible form on real stdout -*/ -int Xorriso_option_print_size(struct XorrisO *xorriso, int flag) -{ - int ret, fd; - - if(!xorriso->volset_change_pending) { - sprintf(xorriso->info_text,"-print_size: No image modifications pending"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - sprintf(xorriso->result_line,"Image size : 0s\n"); - Xorriso_result(xorriso,0); - return(2); - } - ret= Xorriso_write_session(xorriso, 1); - if(ret<=0) { - sprintf(xorriso->info_text,"-print_size: Failed to set up virtual -commit"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - if(flag&1) { - sprintf(xorriso->result_line,"%d\n", ret); - fd= xorriso->dev_fd_1; - if(fd<0) - fd= 1; - write(fd, xorriso->result_line, strlen(xorriso->result_line)); - fsync(fd); - } else { - sprintf(xorriso->result_line,"Image size : %ds\n", ret); - Xorriso_result(xorriso,0); - } - return(1); -} - - -/* Option -prog */ -int Xorriso_option_prog(struct XorrisO *xorriso, char *name, int flag) -{ - if(strlen(name)>=sizeof(xorriso->progname)) { - sprintf(xorriso->info_text, - "Name too long with option -prog (%d > %d)", - (int) strlen(name), (int) sizeof(xorriso->progname)-1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - if(Sfile_str(xorriso->progname,name,0)<=0) - return(-1); - return(1); -} - - -/* Option -prog_help */ -int Xorriso_option_prog_help(struct XorrisO *xorriso, char *name, int flag) -{ - int ret; - - ret= Xorriso_option_prog(xorriso, name, 0); - if(ret<=0) - return(ret); - ret= Xorriso_option_help(xorriso, 0); - return(ret); -} - - -/* Option -prompt */ -int Xorriso_option_prompt(struct XorrisO *xorriso, char *text, int flag) -{ - int ret; - char line[80]; - - strncpy(xorriso->result_line,text,sizeof(xorriso->result_line)-1); - xorriso->result_line[sizeof(xorriso->result_line)-1]= 0; - Xorriso_result(xorriso,0); - ret= Xorriso_dialog_input(xorriso, line, sizeof(line),1); - return(ret); -} - - -/* Option -publisher */ -int Xorriso_option_publisher(struct XorrisO *xorriso, char *name, int flag) -{ - if(Xorriso_check_name_len(xorriso, name, (int) sizeof(xorriso->publisher), - "-publisher", 0) <= 0) - return(0); - strcpy(xorriso->publisher,name); - Xorriso_set_change_pending(xorriso, 1); - return(1); -} - - -/* Option -pvd_info */ -int Xorriso_option_pvd_info(struct XorrisO *xorriso, int flag) -{ - return(Xorriso_pvd_info(xorriso, 0)); -} - - -/* Option -pwd alias -pwdi */ -int Xorriso_option_pwdi(struct XorrisO *xorriso, int flag) -{ - char sfe[5 * SfileadrL]; - - sprintf(xorriso->info_text,"current working directory in ISO image:\n"); - Xorriso_info(xorriso,0); - sprintf(xorriso->result_line,"%s/\n", Text_shellsafe(xorriso->wdi, sfe, 0)); - Xorriso_result(xorriso,0); - return(1); -} - - -/* Option -pwdx */ -int Xorriso_option_pwdx(struct XorrisO *xorriso, int flag) -{ - sprintf(xorriso->info_text,"current working directory on hard disk:\n"); - Xorriso_info(xorriso,0); - sprintf(xorriso->result_line,"%s/\n",xorriso->wdx); - Xorriso_result(xorriso,0); - return(1); -} - - -/* Option -reassure "on"|"tree"|"off" */ -int Xorriso_option_reassure(struct XorrisO *xorriso, char *mode, int flag) -{ - if(strcmp(mode, "off")==0) - xorriso->do_reassure= 0; - else if(strcmp(mode, "on")==0) - xorriso->do_reassure= 1; - else if(strcmp(mode, "tree")==0) - xorriso->do_reassure= 2; - else { - sprintf(xorriso->info_text, "-reassure: unknown mode '%s'", mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - return(1); -} - - -/* Option -unregister_filter */ -int Xorriso_option_unregister_filter(struct XorrisO *xorriso, char *name, - int flag) -{ - int ret; - - ret= Xorriso_external_filter(xorriso, name, "", "", 0, NULL, 1); - return(ret); -} - - -/* Option -report_about */ -int Xorriso_option_report_about(struct XorrisO *xorriso, char *severity, - int flag) -{ - int ret, sev; - char sfe[5*SfileadrL]; - - ret= Xorriso__text_to_sev(severity, &sev, 0); - if(ret<=0) { - sprintf(xorriso->info_text, - "-report_about: Not a known severity name : %s", - Text_shellsafe(severity, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - return(ret); - } - if(Sfile_str(xorriso->report_about_text,severity,0)<=0) - return(-1); - xorriso->report_about_severity= sev; - return(1); -} - - -/* Option -return_with */ -int Xorriso_option_return_with(struct XorrisO *xorriso, char *severity, - int exit_value, int flag) -{ - int ret, sev; - char sfe[5*SfileadrL]; - - ret= Xorriso__text_to_sev(severity, &sev, 0); - if(ret<=0) { - sprintf(xorriso->info_text, - "-return_with: Not a known severity name : %s", - Text_shellsafe(severity, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(ret); - } - if(exit_value && (exit_value < 32 || exit_value > 63)) { - sprintf(xorriso->info_text, - "-return_with: Not an allowed exit_value. Use 0, or 32 to 63."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - if(Sfile_str(xorriso->return_with_text,severity,0)<=0) - return(-1); - xorriso->return_with_severity= sev; - xorriso->return_with_value= exit_value; - return(1); -} - - -/* Options -rm alias -rmi , -rm_r alias -rm_ri , -rmdir alias -rmdiri */ -/* @param flag bit0=recursive , bit1= remove empty directory: rmdir */ -int Xorriso_option_rmi(struct XorrisO *xorriso, int argc, char **argv, - int *idx, int flag) -{ - int i, ret, end_idx, was_failure= 0, fret; - char path[SfileadrL], eff_path[SfileadrL], sfe[5*SfileadrL]; - int optc= 0; - char **optv= NULL; - - ret= Xorriso_opt_args(xorriso, "-rm*i", - argc, argv, *idx, &end_idx, &optc, &optv, 0); - if(ret<=0) - goto ex; - for(i= 0; iwdi, path, 0); - if(ret<=0) - goto problem_handler; - } - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 1); - if(ret<0) - goto problem_handler; - if(ret==0) { - sprintf(xorriso->info_text, - "Cannot find path %s in loaded ISO image for removal", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - goto problem_handler; - } - strcpy(path, eff_path); - - ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, path, flag&(1|2)); - if(ret<=0 || xorriso->request_to_abort) - goto problem_handler; - if(ret<3) { - sprintf(xorriso->info_text, "Removed from ISO image: %s '%s'\n", - ((flag&2) ? "directory" : (ret>1 ? "subtree" : "file")), path); - Xorriso_info(xorriso, 0); - } - - continue; /* regular bottom of loop */ -problem_handler:; - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - goto ex; - } - ret= 1; -ex:; - (*idx)= end_idx; - Xorriso_opt_args(xorriso, "-rm*i", - argc, argv, *idx, &end_idx, &optc, &optv, 256); - if(ret<=0) - return(ret); - return(!was_failure); -} - - -/* Option -rollback */ -/* @param flag bit0= do not -reassure - @return <=0 error , 1 success, 2 revoked by -reassure -*/ -int Xorriso_option_rollback(struct XorrisO *xorriso, int flag) -{ - int ret; - char indev[SfileadrL], *which_will; - - if(xorriso->volset_change_pending) - which_will= "revoke the pending image changes"; - else - which_will= "reload the image"; - if(!(flag&1)) { - ret= Xorriso_reassure(xorriso, "-rollback", which_will, 0); - if(ret<=0) - return(2); - } - - if(Sfile_str(indev, xorriso->indev, 0)<=0) - return(-1); - ret= Xorriso_give_up_drive(xorriso, 1|8); - if(ret<=0) - return(ret); - xorriso->image_start_mode&= ~(1<<31); /* reactivate eventual -load address */ - ret= Xorriso_option_dev(xorriso, indev, 1|4); - return(ret); -} - - -/* Option -rom_toc_scan */ -int Xorriso_option_rom_toc_scan(struct XorrisO *xorriso, char *mode, int flag) -{ - int l; - char *cpt, *npt; - - xorriso->toc_emulation_flag= 0; - npt= cpt= mode; - for(cpt= mode; npt != NULL; cpt= npt + 1) { - npt= strchr(cpt,':'); - if(npt==NULL) - l= strlen(cpt); - else - l= npt-cpt; - if(l==0) - goto unknown_mode; - xorriso->toc_emulation_flag&= ~4; - if(strncmp(cpt, "off", l) == 0) - xorriso->toc_emulation_flag&= ~1; - else if(strncmp(cpt, "on", l) == 0) - xorriso->toc_emulation_flag|= 1; - else if(strncmp(cpt, "force", l) == 0) - xorriso->toc_emulation_flag|= 4; - else if(strncmp(cpt, "emul_off", l) == 0) - xorriso->toc_emulation_flag|= 2; - else if(strncmp(cpt, "emul_on", l) == 0) - xorriso->toc_emulation_flag&= ~2; - else { -unknown_mode:; - sprintf(xorriso->info_text, "-rom_toc_scan: unknown mode in '%s'", mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - } - return(1); -} - - -/* Option -scdbackup_tag list_path record_name */ -int Xorriso_option_scdbackup_tag(struct XorrisO *xorriso, char *listname, - char *recname, int flag) -{ - if(strlen(recname) > 80) { - sprintf(xorriso->info_text, - "Unsuitable record name given with -scdbackup_tag"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - strcpy(xorriso->scdbackup_tag_name, recname); - xorriso->scdbackup_tag_time[0]= 0; - if(Sfile_str(xorriso->scdbackup_tag_listname, listname, 0) <= 0) - return(-1); - return(1); -} - - -/* Option -scsi_log */ -int Xorriso_option_scsi_log(struct XorrisO *xorriso, char *mode, int flag) -{ - if(strcmp(mode, "on") == 0) - xorriso->scsi_log= 1; - else if(strcmp(mode, "off") == 0) - xorriso->scsi_log= 0; - else { - sprintf(xorriso->info_text, "-scsi_log: unknown mode '%s'", mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - Xorriso_scsi_log(xorriso, !!xorriso->scsi_log); - return(1); -} - - -/* Option -session_log */ -int Xorriso_option_session_log(struct XorrisO *xorriso, char *path, int flag) -{ - if(Sfile_str(xorriso->session_logfile, path, 0)<=0) - return(-1); - return(1); -} - - - -/* Option -setfacl_list alias -setfacl_listi */ -int Xorriso_option_setfacl_listi(struct XorrisO *xorriso, char *path, int flag) -{ - int ret, eaten; - size_t buf_size= 0, buf_add= 64 * 1024, l, linecount= 0; - char line[SfileadrL * 4], *buf= NULL, *wpt, *new_buf, limit_text[80]; - char file_path[SfileadrL], uid[161], gid[161]; - FILE *fp= NULL; - - Xorriso_pacifier_reset(xorriso, 0); - if(path[0]==0) { - sprintf(xorriso->info_text, "Empty file name given with -setfacl_list"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - ret= Xorriso_afile_fopen(xorriso, path, "rb", &fp, 0); - if(ret <= 0) - return(0); - - buf_size= buf_add; - buf= calloc(buf_size, 1); - if(buf == NULL) - goto out_of_mem; - wpt= buf; - *wpt= 0; - uid[0]= gid[0]= 0; - - while(1) { - if(Sfile_fgets_n(line, sizeof(line), fp, 0) == NULL) - break; - linecount++; - if(strncmp(line, "# file: ", 8) ==0) { - if(wpt != buf && file_path[0]) { - /* Commit previous list */ - ret= Xorriso_perform_acl_from_list(xorriso, file_path, - uid, gid, buf, 0); - if(ret<=0) - goto ex; - wpt= buf; - *wpt= 0; - file_path[0]= uid[0]= gid[0]= 0; - } - /* Unescape line and register as file path */ - Sfile_bsl_interpreter(line + 8, strlen(line + 8), &eaten, 0); - if(strlen(line + 8) >= SfileadrL) { - sprintf(xorriso->info_text, "-setfacl_list: Oversized file path"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - strcpy(file_path, line + 8); - continue; - } else if(strncmp(line, "# owner: ", 9) == 0) { - if(strlen(line + 9) > 160) { - sprintf(xorriso->info_text, "-setfacl_list: Oversized owner id"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - strcpy(uid, line + 9); - continue; - } else if(strncmp(line, "# group: ", 9) == 0) { - if(strlen(line + 9) > 160) { - sprintf(xorriso->info_text, "-setfacl_list: Oversized group id"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - strcpy(gid, line + 9); - continue; - } else if(line[0] == '#' || line[0] == 0) { - continue; - } else if(strcmp(line, "@") == 0) { - Xorriso_msgs_submit(xorriso, 0, - "-setfacl_list input ended by '@'", 0, "NOTE", 0); - break; - } else if(strcmp(line, "@@@") == 0) { - Xorriso_msgs_submit(xorriso, 0, - "-setfacl_list aborted by input line '@@@'", 0, "WARNING", 0); - ret= 0; goto ex; - } - - /* Register ACL entry */ - l= strlen(line); - if(wpt + l + 2 - buf > buf_size) { - if(buf_size + buf_add > xorriso->temp_mem_limit) { - Sfile_scale((double) xorriso->temp_mem_limit, limit_text,5,1e4,1); - sprintf(xorriso->info_text, - "-setfacl_list: List entry for a single file exceeds -temp_mem_limit %s", - limit_text); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - buf_size+= buf_add; - new_buf= realloc(buf, buf_size); - if(new_buf == NULL) - goto out_of_mem; - buf= new_buf; - } - memcpy(wpt, line, l); - *(wpt + l)= '\n'; - wpt+= l + 1; - *wpt= 0; - } - if(wpt != buf && file_path[0]) { - /* Commit last list */ - ret= Xorriso_perform_acl_from_list(xorriso, file_path, uid, gid, buf, 0); - if(ret<=0) - goto ex; - } else { - sprintf(xorriso->info_text, "-setfacl_list: Unexpected end of file "); - Text_shellsafe(path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - } - ret= 1; -ex:; - if(buf != NULL) - free(buf); - if(fp != NULL && fp != stdin) - fclose(fp); - if(ret <= 0) { - sprintf(xorriso->info_text, "-setfacl_list "); - Text_shellsafe(path, xorriso->info_text, 1); - sprintf(xorriso->info_text + strlen(xorriso->info_text), - " aborted in line %.f\n", (double) linecount); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } - return(ret); -out_of_mem:; - Xorriso_no_malloc_memory(xorriso, &buf, 0); - ret= -1; - goto ex; -} - - -/* Options -setfacl alias -setfacli, -setfacl_r alias -setfacl_ri */ -/* @param flag bit0=recursive -setfacl_r -*/ -int Xorriso_option_setfacli(struct XorrisO *xorriso, char *acl_text, - int argc, char **argv, int *idx, int flag) -{ - int i, ret, was_failure= 0, end_idx, fret; - int optc= 0; - char **optv= NULL, *access_acl_text= NULL, *default_acl_text= NULL; - struct FindjoB *job= NULL; - struct stat dir_stbuf; - - ret= Xorriso_opt_args(xorriso, "-setfacl", argc, argv, *idx, &end_idx, &optc, - &optv, 0); - if(ret <= 0) - goto ex; - - ret= Xorriso_normalize_acl_text(xorriso, acl_text, - &access_acl_text, &default_acl_text, 0); - if(access_acl_text != NULL && default_acl_text != NULL) { - sprintf(xorriso->info_text, "Access-ACL :\n%s", access_acl_text); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - sprintf(xorriso->info_text, "Default-ACL :\n%s", default_acl_text); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - } else if(access_acl_text == NULL && default_acl_text == NULL) { - sprintf(xorriso->info_text, "Will delete Access-ACL and Default-ACL"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - } - if(ret <= 0) - goto ex; - - for(i= 0; i0 && !xorriso->request_to_abort) - continue; /* regular bottom of loop */ - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - ret= 0; goto ex; - } - ret= 1; -ex:; - (*idx)= end_idx; - Xorriso_opt_args(xorriso, "-setfacl", argc, argv, *idx, &end_idx, - &optc, &optv, 256); - Findjob_destroy(&job, 0); - if(access_acl_text != NULL) - free(access_acl_text); - if(default_acl_text != NULL) - free(default_acl_text); - if(ret<=0) - return(ret); - return(!was_failure); -} - - -/* Options -setfattr alias -setfattri, -setfattr_r alias -setfattr_ri */ -/* @param flag bit0=recursive -setfattr_r -*/ -int Xorriso_option_setfattri(struct XorrisO *xorriso, char *name, char *value, - int argc, char **argv, int *idx, int flag) -{ - int i, ret, was_failure= 0, end_idx, fret; - int optc= 0; - char **optv= NULL; - struct FindjoB *job= NULL; - struct stat dir_stbuf; - - ret= Xorriso_opt_args(xorriso, "-setfattr", argc, argv, *idx, &end_idx, &optc, - &optv, 0); - if(ret <= 0) - goto ex; - - /* check input */ - ret= Xorriso_path_setfattr(xorriso, NULL, "", name, strlen(value), value, 1); - if(ret <= 0) - goto ex; - - for(i= 0; i0 && !xorriso->request_to_abort) - continue; /* regular bottom of loop */ - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - ret= 0; goto ex; - } - ret= 1; -ex:; - (*idx)= end_idx; - Xorriso_opt_args(xorriso, "-setfattr", argc, argv, *idx, &end_idx, - &optc, &optv, 256); - Findjob_destroy(&job, 0); - if(ret<=0) - return(ret); - return(!was_failure); -} - - -/* Option -setfattr_list alias -setfattr_listi */ -int Xorriso_option_setfattr_listi(struct XorrisO *xorriso, char *path, - int flag) -{ - int ret, eaten; - size_t linecount= 0, mem_used= 0, num_attr= 0, v_len; - char line[SfileadrL * 4], limit_text[80], *ept, *valuept; - char file_path[SfileadrL]; - FILE *fp= NULL; - struct Xorriso_lsT *lst_curr= NULL, *lst_start= NULL; - - Xorriso_pacifier_reset(xorriso, 0); - if(path[0]==0) { - sprintf(xorriso->info_text, "Empty file name given with -setfattr_list"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - ret= Xorriso_afile_fopen(xorriso, path, "rb", &fp, 0); - if(ret <= 0) - return(0); - - while(1) { - if(Sfile_fgets_n(line, sizeof(line), fp, 0) == NULL) - break; - linecount++; - if(strncmp(line, "# file: ", 8) ==0) { - if(num_attr > 0 && file_path[0]) { - /* Commit previous list */ - ret= Xorriso_perform_attr_from_list(xorriso, file_path, lst_start, 0); - if(ret<=0) - goto ex; - num_attr= 0; - file_path[0]= 0; - Xorriso_lst_destroy_all(&lst_start, 0); - lst_curr= NULL; - } - /* Unescape line and register as file path */ - Sfile_bsl_interpreter(line + 8, strlen(line + 8), &eaten, 0); - if(strlen(line + 8) >= SfileadrL) { - sprintf(xorriso->info_text, "-setfattr_list: Oversized file path"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - strcpy(file_path, line + 8); - continue; - } else if(line[0] == '#' || line[0] == 0) { - continue; - } else if(strcmp(line, "@") == 0) { - Xorriso_msgs_submit(xorriso, 0, - "-setfattr_list input ended by '@'", 0, "NOTE", 0); - break; - } else if(strcmp(line, "@@@") == 0) { - Xorriso_msgs_submit(xorriso, 0, - "-setfattr_list aborted by input line '@@@'", 0, "WARNING", 0); - ret= 1; goto ex; - } - mem_used+= strlen(line) + 1; - if(mem_used > xorriso->temp_mem_limit) { - Sfile_scale((double) xorriso->temp_mem_limit, limit_text,5,1e4,1); - sprintf(xorriso->info_text, - "-setfattr_list: List entry for a single file exceeds -temp_mem_limit %s", - limit_text); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - - /* Register attr pair */ - - ept= strchr(line, '='); - if(ept == NULL) { - sprintf(xorriso->info_text, "-setfattr_list: "); - Text_shellsafe(path, xorriso->info_text, 1); - sprintf(xorriso->info_text + strlen(xorriso->info_text), - " : Line %.f : No separator '=' found", - (double) linecount); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - continue; - } - valuept= ept + 1; - v_len= strlen(valuept); - for(ept= valuept + v_len - 1; ept > valuept; ept--) - if(isspace(*ept)) - *ept= 0; - else - break; - v_len= strlen(valuept); - if(v_len < 2 || *valuept != '"' || *(valuept + v_len -1) != '"') { - sprintf(xorriso->info_text, "-setfattr_list: "); - Text_shellsafe(path, xorriso->info_text, 1); - sprintf(xorriso->info_text + strlen(xorriso->info_text), - " : Line %.f : Value not enclosed in quotes", - (double) linecount); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - - continue; - } - - ret= Xorriso_lst_new(&lst_curr, line, lst_curr, 0); - if(ret <= 0) - goto out_of_mem; - if(lst_start == NULL) - lst_start= lst_curr; - num_attr++; - } - - if(file_path[0]) { - /* Commit last list */ - ret= Xorriso_perform_attr_from_list(xorriso, file_path, lst_start, 0); - if(ret<=0) - goto ex; - } else { - sprintf(xorriso->info_text, "-setfattr_list: Unexpected end of file "); - Text_shellsafe(path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - } - ret= 1; -ex:; - if(fp != NULL && fp != stdin) - fclose(fp); - Xorriso_lst_destroy_all(&lst_start, 0); - if(ret <= 0) { - sprintf(xorriso->info_text, "-setfattr_list "); - Text_shellsafe(path, xorriso->info_text, 1); - sprintf(xorriso->info_text + strlen(xorriso->info_text), - " aborted in line %.f\n", (double) linecount); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } - return(ret); -out_of_mem:; - Xorriso_no_malloc_memory(xorriso, NULL, 0); - ret= -1; - goto ex; -} - - -/* Options -set_filter , -set_filter_r , -show_stream , -show_stream_r */ -/* @param flag bit0=recursive -set_filter_r - bit1= do not reset pacifier, no final pacifier message - bit2= -show_stream rather than -set_filter -*/ -int Xorriso_option_set_filter(struct XorrisO *xorriso, char *name, - int argc, char **argv, int *idx, int flag) -{ - int i, ret, was_failure= 0, end_idx, fret; - int optc= 0; - char **optv= NULL; - struct FindjoB *job= NULL; - struct stat dir_stbuf; - char *cmd= "-set_filter"; - - switch(flag & 5) { - case 0: cmd= "-set_filter"; - break; case 1: cmd= "-set_filter_r"; - break; case 4: cmd= "-show_stream"; - break; case 5: cmd= "-show_stream_r"; - } - - ret= Xorriso_opt_args(xorriso, cmd, - argc, argv, *idx, &end_idx, &optc, &optv, 0); - if(ret <= 0) - goto ex; - if(!(flag&2)) - Xorriso_pacifier_reset(xorriso, 0); - - for(i= 0; i0 && !xorriso->request_to_abort) - continue; /* regular bottom of loop */ - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret>=0) - continue; - ret= 0; goto ex; - } - if(!(flag&2)) - Xorriso_pacifier_callback(xorriso, "file filters processed", - xorriso->pacifier_count, 0, "", 1); - ret= 1; -ex:; - (*idx)= end_idx; - Xorriso_opt_args(xorriso, cmd, argc, argv, *idx, &end_idx, - &optc, &optv, 256); - Findjob_destroy(&job, 0); - if(ret<=0) - return(ret); - return(!was_failure); -} - - -/* Option -speed */ -int Xorriso_option_speed(struct XorrisO *xorriso, char *speed, int flag) -{ - int is_cd= 1, unit_found= 0, ret, profile_number; - double num; - char *cpt, profile_name[80]; - - if(speed[0]==0 || strcmp(speed, "any")==0) { - xorriso->speed= 0; /* full speed */ - return(1); - } - - sscanf(speed,"%lf",&num); - for(cpt= speed+strlen(speed)-1; cpt>=speed; cpt--) - if(isdigit(*cpt) || *cpt=='.') - break; - cpt++; - - if(*cpt=='k' || *cpt=='K') { - /* is merchand kilobyte, stays merchand kilobyte */ - unit_found= 1; - } else if(*cpt=='m' || *cpt=='M') { - num*= 1000; - unit_found= 1; - } else if(*cpt=='x' || *cpt=='X') - cpt++; - - if (unit_found) { - ; - } else if(*cpt=='c' || *cpt=='C') { -cd_speed:; - num*= 176.4; - } else if(*cpt=='d' || *cpt=='D') { -dvd_speed:; - num*= 1385; - } else if(*cpt=='b' || *cpt=='B') { -bd_speed:; - num*= 4495.625; - } else { - ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2); - is_cd= (ret==2); - if(is_cd) - goto cd_speed; - else if (ret == 3) - goto bd_speed; - else - goto dvd_speed; - } - - if(num> 2.0e9) { - sprintf(xorriso->info_text, - "-speed: Value too large or not recognizable: '%s'", speed); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - xorriso->speed= num; - if(xorriso->speedspeed++; - return(1); -} - - -/* Option -split_size */ -int Xorriso_option_split_size(struct XorrisO *xorriso, char *size, int flag) -{ - double num; - - num= Scanf_io_size(size, 0); - if(num > xorriso->file_size_limit && xorriso->file_size_limit > 0) { - sprintf(xorriso->info_text, "-split_size: too large %.f (allowed: %.f)", - num, (double) xorriso->file_size_limit); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } else if(num < 0) - num= 0.0; - xorriso->split_size= num; - return(1); -} - - -/* Option -status */ -int Xorriso_option_status(struct XorrisO *xorriso, char *mode, int flag) -{ - if(strcmp(mode,"short")==0) - Xorriso_status(xorriso,NULL,NULL,1); - else if(strcmp(mode,"long")==0) - Xorriso_status(xorriso,NULL,NULL,0); - else if(strcmp(mode,"long_history")==0) - Xorriso_status(xorriso,NULL,NULL,8); - else if(mode[0]=='-') - Xorriso_status(xorriso,mode,NULL,8); - else - Xorriso_status(xorriso,NULL,NULL,1); - return(1); -} - - -/* Option -status_history_max */ -int Xorriso_option_status_history_max(struct XorrisO *xorriso, int num, - int flag) -{ - if(num>=0 && num<1000000) - xorriso->status_history_max= num; - return(1); -} - - -/* Option -stdio_sync "on"|"off"|size */ -int Xorriso_option_stdio_sync(struct XorrisO *xorriso, char *rythm, int flag) -{ - double num; - - if(strcmp(rythm, "default") == 0 || strcmp(rythm, "on") == 0) - num= 0; - if(strcmp(rythm, "off") == 0) - num= -1; - else - num = Scanf_io_size(rythm, 0); - if(num > 0) - num /= 2048; - if(num != -1 && num != 0 && (num < 32 || num > 512 * 1024)) { - sprintf(xorriso->info_text, - "-stdio_sync : Bad size. Acceptable are -1, 0, 32k ... 1g"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } else - xorriso->stdio_sync= num; - return(1); -} - - -/* Option -stream_recording */ -int Xorriso_option_stream_recording(struct XorrisO *xorriso, char *mode, - int flag) -{ - double num; - - if(strcmp(mode,"on")==0 || mode[0]==0) - xorriso->do_stream_recording= 32; - else if(strcmp(mode,"full")==0) - xorriso->do_stream_recording= 1; - else if(strcmp(mode,"data")==0) - xorriso->do_stream_recording= 2; - else if(mode[0] >= '0' && mode[0] <= '9') { - num= Scanf_io_size(mode, 0); - num/= 2048.0; - if(num >= 16 && num <= 0x7FFFFFFF) - xorriso->do_stream_recording= num; - else - xorriso->do_stream_recording= 0; - } else - xorriso->do_stream_recording= 0; - return(1); -} - - -/* Option -system_id */ -int Xorriso_option_system_id(struct XorrisO *xorriso, char *name, int flag) -{ - if(Xorriso_check_name_len(xorriso, name, (int) sizeof(xorriso->system_id), - "-system_id", 0) <= 0) - return(0); - strcpy(xorriso->system_id, name); - Xorriso_set_change_pending(xorriso, 1); - return(1); -} - - -/* Option -tell_media_space */ -int Xorriso_option_tell_media_space(struct XorrisO *xorriso, int flag) -{ - int ret, free_space= 0, media_space= 0; - - ret= Xorriso_tell_media_space(xorriso, &media_space, &free_space, 0); - if(ret<=0) { - sprintf(xorriso->info_text, "Cannot -tell_media_space"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - if(free_space<0) { - sprintf(xorriso->info_text, - "Pending image size larger than free space on media"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - } - sprintf(xorriso->result_line, "Media space : %ds\n", media_space); - Xorriso_result(xorriso, 0); - sprintf(xorriso->result_line, "After commit : %ds\n", free_space); - Xorriso_result(xorriso, 0); - return(1); -} - - -/* Option -temp_mem_limit */ -int Xorriso_option_temp_mem_limit(struct XorrisO *xorriso, char *size, - int flag) -{ - double num; - - num= Scanf_io_size(size, 0); - if(num < 64.0 * 1024.0 || num > 1024.0 * 1024.0 * 1024.0) { - sprintf(xorriso->info_text, - "-temp_mem_limit: wrong size %.f (allowed: %.f - %.f)", - num, 64.0 * 1024.0, 1024.0 * 1024.0 * 1024.0); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - xorriso->temp_mem_limit= num; - return(1); -} - - -/* Option -toc */ -int Xorriso_option_toc(struct XorrisO *xorriso, int flag) -{ - int ret, in_ret= 1000; - - if(strcmp(xorriso->indev,xorriso->outdev)==0) - ret= Xorriso_toc(xorriso, 0); - else { - if(xorriso->indev[0]!=0) - in_ret= Xorriso_toc(xorriso, 0); - if(xorriso->indev[0]!=0 && xorriso->outdev[0]!=0) { - strcpy(xorriso->result_line, "-------------: ---------------------------------------------------------------\n"); - Xorriso_result(xorriso,0); - } - ret= 1; - if(xorriso->outdev[0]!=0) - ret= Xorriso_toc(xorriso, 2); - if(in_retdo_global_uid= 0; - if(uid[0]==0 || strcmp(uid,"-")==0) - return(1); - ret= Xorriso_convert_uidstring(xorriso, uid, &(xorriso->global_uid), 0); - if(ret>0) - xorriso->do_global_uid= 1; - return(ret); -} - - -/* Options -update and -update_r - @param flag bit0= issue start and summary message - bit1= do not reset pacifier, no final pacifier message - bit2= do not issue pacifier messages at all - bit3= recursive: -update_r - bit4= do not establish and dispose xorriso->di_array -*/ -int Xorriso_option_update(struct XorrisO *xorriso, char *disk_path, - char *iso_path, int flag) -{ - int ret, mem_pci, zero= 0, result, uret, follow_links, do_register= 1; - int not_in_iso= 0, not_on_disk= 0, made_di_array= 0; - double mem_lut= 0.0, start_time; - char *ipth, *argv[6], sfe[5*SfileadrL]; - char eff_origin[SfileadrL], eff_dest[SfileadrL]; - struct stat stbuf; - - start_time= Sfile_microtime(0); - - ipth= iso_path; - if(ipth[0]==0) - ipth= disk_path; - if(disk_path[0]==0) { - sprintf(xorriso->info_text, "-update: Empty disk_path given"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 1); - return(0); - } - - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_origin, - 2|4|8); - if(ret<=0) - return(ret); - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, ipth, eff_dest, 2|8); - if(ret<=0) - return(ret); - - if(!(flag&2)) { - Xorriso_pacifier_reset(xorriso, 0); - mem_lut= xorriso->last_update_time; - } - mem_pci= xorriso->pacifier_interval; - xorriso->pacifier_interval= 5.0; - - if(flag&1) { - sprintf(xorriso->info_text, "Updating %s to", - Text_shellsafe(eff_origin, sfe, 0)); - sprintf(xorriso->info_text+strlen(xorriso->info_text), " %s\n", - Text_shellsafe(eff_dest, sfe, 0)); - Xorriso_info(xorriso,0); - } - if(xorriso->disk_excl_mode&8) - ret= Xorriso_path_is_excluded(xorriso, eff_origin, 1); - else - ret= 0; - if(ret!=0) - goto report_outcome; - - if(!(xorriso->ino_behavior & 2)) { - if(!(xorriso->di_array != NULL || (flag & 16))) { - /* Create all-image node array sorted by isofs.di */ - made_di_array= 1; - ret= Xorriso_make_di_array(xorriso, 0); - if(ret <= 0) - goto ex; - } - if(xorriso->di_array != NULL) { - if(!(flag & 8)) { - /* If directory with -update : do not register di_*_paths */ - ret= lstat(eff_origin, &stbuf); - if(ret != -1) - if(S_ISDIR(stbuf.st_mode)) - do_register= 0; - } - if(do_register) { - ret= Xorriso_lst_new(&(xorriso->di_disk_paths), eff_origin, - xorriso->di_disk_paths, 1); - if(ret <= 0) - goto ex; - ret= Xorriso_lst_new(&(xorriso->di_iso_paths), eff_dest, - xorriso->di_iso_paths, 1); - if(ret <= 0) - goto ex; - } - } - } - - if(flag&8) { - xorriso->find_compare_result= 1; - ret= Xorriso_iso_lstat(xorriso, eff_dest, &stbuf, 0); - if(ret >= 0) { - argv[0]= eff_dest; - argv[1]= "-exec"; - argv[2]= "update"; - argv[3]= eff_origin; - zero= 0; - ret= Xorriso_option_find(xorriso, 4, argv, &zero, - 2 | (8 * !((xorriso->do_aaip & 96) == 96))); /* -findi */ - } else if(ret==-2) { /* severe error (e.g. lack of image) */ - ret= -1; - goto report_outcome; - } else { - not_in_iso= 1; - ret= 1; - } - if(ret>0) { - ret= lstat(eff_origin, &stbuf); - if(ret != -1) { - argv[0]= eff_origin; - argv[1]= "-exec"; - argv[2]= "add_missing"; - argv[3]= eff_dest; - zero= 0; - ret= Xorriso_option_find(xorriso, 4, argv, &zero, 1|2); /* -findx */ - if(ret>0 && !xorriso->do_follow_mount) { - argv[0]= eff_origin; - argv[1]= "-type"; - argv[2]= "m"; - argv[3]= "-exec"; - argv[4]= "empty_iso_dir"; - argv[5]= eff_dest; - zero= 0; - ret= Xorriso_option_find(xorriso, 6, argv, &zero, 1|2); /* -findx */ - } - if(ret>0) - ret= xorriso->find_compare_result; - else - ret= -1; - } else { - ret= xorriso->find_compare_result; - not_on_disk= 1; - } - } else - ret= -1; - if(not_on_disk && not_in_iso) { - 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); - ret= -1; - } - } else { - /* compare ctime too, no filename reporting, eventually silent */ - follow_links= (xorriso->do_follow_links || xorriso->do_follow_param) <<28; - ret= Xorriso_compare_2_files(xorriso, eff_origin, eff_dest, "", &result, - 2 | follow_links | ((flag&4)<<27) | (3<<30)); - if(ret==0) { - uret= Xorriso_update_interpreter(xorriso, NULL, result, eff_origin, - eff_dest, 0); - if(uret<=0) - ret= -1; - if(uret==3) - ret= -1; - } - } - xorriso->pacifier_interval= mem_pci; - if(mem_lut!=xorriso->last_update_time && !(flag&2)) - Xorriso_pacifier_callback(xorriso, "content bytes read", - xorriso->pacifier_count, 0, "", 1); -report_outcome:; - if(ret>0) { - sprintf(xorriso->info_text, - "No file object needed update."); - } else if(ret==0) { - sprintf(xorriso->info_text, "Differences detected and updated."); - } else { - sprintf(xorriso->info_text, - "Not ok. Comparison or update failed due to error."); - } - sprintf(xorriso->info_text+strlen(xorriso->info_text), - " (runtime %.1f s)\n", Sfile_microtime(0)-start_time); - if(flag&1) - Xorriso_info(xorriso,0); - -ex:; - if(ret < 0) - return(ret); - return(1); -} - - -/* Option -use_readline */ -int Xorriso_option_use_readline(struct XorrisO *xorriso, char *mode, int flag) -{ - if(strcmp(mode,"off")==0) - xorriso->use_stdin= 1; - else - xorriso->use_stdin= 0; - return(1); -} - - -/* Option -version */ -int Xorriso_option_version(struct XorrisO *xorriso, int flag) -{ -#ifdef Xorriso_GNU_xorrisO - sprintf(xorriso->result_line, "GNU xorriso %s%s\n", - Xorriso_program_versioN, Xorriso_program_patch_leveL); -#else - sprintf(xorriso->result_line, "xorriso %s%s\n", - Xorriso_program_versioN, Xorriso_program_patch_leveL); -#endif /* ! Xorriso_GNU_xorrisO */ - Xorriso_result(xorriso, 0); - sprintf(xorriso->result_line, -"ISO 9660 Rock Ridge filesystem manipulator and CD/DVD/BD burn program\n"); - sprintf(xorriso->result_line+strlen(xorriso->result_line), -"Copyright (C) 2010, Thomas Schmitt , libburnia project.\n"); - Xorriso_result(xorriso, 0); - sprintf(xorriso->result_line, - "xorriso version : %s%s\n", - Xorriso_program_versioN, Xorriso_program_patch_leveL); - sprintf(xorriso->result_line+strlen(xorriso->result_line), - "Version timestamp : %s\n",Xorriso_timestamP); - sprintf(xorriso->result_line+strlen(xorriso->result_line), - "Build timestamp : %s\n",Xorriso_build_timestamP); - Xorriso_result(xorriso, 0); - Xorriso_report_lib_versions(xorriso, 0); - -#ifdef Xorriso_GNU_xorrisO - sprintf(xorriso->result_line, -"License GPLv3+: GNU GPL version 3 or later .\n"); - Xorriso_result(xorriso, 0); - sprintf(xorriso->result_line, -"This is free software: you are free to change and redistribute it.\n"); - Xorriso_result(xorriso, 0); -#else - sprintf(xorriso->result_line, "Provided under GNU GPL version 2 or later.\n"); - Xorriso_result(xorriso, 0); -#endif /* ! Xorriso_GNU_xorrisO */ - - sprintf(xorriso->result_line, -"There is NO WARRANTY, to the extent permitted by law.\n"); - Xorriso_result(xorriso, 0); - return(1); -} - - -/* Option -volid */ -int Xorriso_option_volid(struct XorrisO *xorriso, char *volid, int flag) -{ - int warn_shell= 0, warn_ecma= 0, i, ret; - static char shell_chars[]= { - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-+=:.,~@"}; - static char ecma_chars[]= {"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"}; - - for(i=0; volid[i]!=0; i++) { - if(strchr(shell_chars, volid[i])==NULL) - warn_shell= 1; - if(strchr(ecma_chars, volid[i])==NULL) - warn_ecma= 1; - } - if(i>32) { - sprintf(xorriso->info_text, "-volid: Text too long (%d > 32)", i); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - if(warn_shell) { - sprintf(xorriso->info_text, - "-volid text problematic as automatic mount point name"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - } - if(xorriso->do_joliet && strlen(volid)>16) { - sprintf(xorriso->info_text, - "-volid text is too long for Joliet (%d > 16)",(int) strlen(volid)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - } - if(warn_ecma) { - sprintf(xorriso->info_text, - "-volid text does not comply to ISO 9660 / ECMA 119 rules"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - } - strcpy(xorriso->volid, volid); - ret= Xorriso_set_volid(xorriso, volid, 0); - if(ret<=0) - return(ret); - xorriso->volid_default= (strcmp(xorriso->volid, "ISOIMAGE")==0 || - xorriso->volid[0]==0); - return(1); -} - - -/* Option -volset_id */ -int Xorriso_option_volset_id(struct XorrisO *xorriso, char *name, int flag) -{ - if(Xorriso_check_name_len(xorriso, name, (int) sizeof(xorriso->volset_id), - "-volset_id", 0) <= 0) - return(0); - strcpy(xorriso->volset_id, name); - Xorriso_set_change_pending(xorriso, 1); - return(1); -} - - -/* Option -volume_date */ -int Xorriso_option_volume_date(struct XorrisO *xorriso, - char *time_type, char *timestring, int flag) -{ - int ret, t_type= 0; - time_t t; - struct tm erg; - - if(timestring[0] == 0 || strcmp(timestring, "default") == 0 || - strcmp(timestring, "overridden") == 0 ){ - t= 0; - } else if(strcmp(time_type, "uuid") == 0) { - t= time(NULL); /* Just to have some that is not 0 */ - } else { - ret= Xorriso_convert_datestring(xorriso, "-volume_date", - "m", timestring, &t_type, &t, 0); - if(ret<=0) - goto ex; - } - if(strcmp(time_type, "uuid") == 0) { - if(t == 0) { - xorriso->vol_uuid[0]= 0; - ret= 1; goto ex; - } - ret= Decode_ecma119_format(&erg, timestring, 0); - if(ret <= 0) { - sprintf(xorriso->info_text, "-volume_date uuid : Not an ECMA-119 time string. (16 decimal digits, range 1970... to 2999...)"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - strcpy(xorriso->vol_uuid, timestring); - if(erg.tm_year < 138) { - sprintf(xorriso->info_text, - "Understanding ECMA-119 timestring '%s' as: %s", - timestring, asctime(&erg)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - } - - } else if(strcmp(time_type, "c") == 0) { - xorriso->vol_creation_time= t; - } else if(strcmp(time_type, "m") == 0) { - xorriso->vol_modification_time= t; - } else if(strcmp(time_type, "x") == 0) { - xorriso->vol_expiration_time= t; - } else if(strcmp(time_type, "f") == 0) { - xorriso->vol_effective_time= t; - } else { - - /* >>> unknown time type */; - - ret= 0; goto ex; - } - ret= 1; -ex:; - return(ret); -} - - -/* Option -xattr "on"|"off" */ -int Xorriso_option_xattr(struct XorrisO *xorriso, char *mode, int flag) -{ - int ret; - - if(strcmp(mode, "off")==0) - xorriso->do_aaip&= ~12; - else if(strcmp(mode, "on")==0) - xorriso->do_aaip|= (4 | 8); - else { - sprintf(xorriso->info_text, "-xattr: unknown mode '%s'", mode); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - ret= Xorriso_set_ignore_aclea(xorriso, 0); - if(ret <= 0) - return(ret); - return(1); -} - - -/* Option -zisofs */ -int Xorriso_option_zisofs(struct XorrisO *xorriso, char *mode, int flag) -{ - int was_level, was_blocksize, ret, l; - double num; - char *cpt, *npt, text[16]; - - was_level= xorriso->zlib_level; - was_blocksize= xorriso->zisofs_block_size; - npt= cpt= mode; - for(cpt= mode; npt!=NULL; cpt= npt+1) { - npt= strchr(cpt,':'); - if(npt==NULL) - l= strlen(cpt); - else - l= npt-cpt; - if(l==0) - goto unknown_mode; - - if(strncmp(cpt, "level=", 6) == 0) { - sscanf(cpt + 6, "%lf", &num); - if(num < 0 || num > 9) { - sprintf(xorriso->info_text, - "-zisofs: Wrong zlib compression level '%s' (allowed 0...9)", - cpt + 6); - goto sorry_ex; - } - xorriso->zlib_level= num; - - } else if(strncmp(cpt, "ziso_used=", 10) == 0 || - strncmp(cpt, "osiz_used=", 10) == 0) { - /* (ignored info from -status) */; - - } else if(strncmp(cpt, "block_size=", 11)==0) { - num= 0.0; - if(l > 11 && l < 27) { - strncpy(text, cpt + 11, l - 11); - text[l - 11]= 0; - num= Scanf_io_size(text, 0); - } - if (num != (1 << 15) && num != (1 << 16) && num != (1 << 17)) { - sprintf(xorriso->info_text, - "-zisofs: Unsupported block size (allowed 32k, 64k, 128k)"); - goto sorry_ex; - } - xorriso->zisofs_block_size= num; - - } else if(strncmp(cpt, "by_magic=", 8)==0) { - if(strncmp(cpt + 9, "on", l - 9) == 0) - xorriso->zisofs_by_magic= 1; - else - xorriso->zisofs_by_magic= 0; - - } else if(strncmp(cpt, "default", l)==0) { - xorriso->zlib_level= xorriso->zlib_level_default; - xorriso->zisofs_block_size= xorriso->zisofs_block_size_default; - xorriso->zisofs_by_magic= 0; - - } else { -unknown_mode:; - if(linfo_text, "-zisofs: unknown mode '%s'", cpt); - else - sprintf(xorriso->info_text, "-zisofs: oversized mode parameter (%d)",l); -sorry_ex: - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - xorriso->zlib_level= was_level; - xorriso->zisofs_block_size= was_blocksize; - return(0); - } - } - ret= Xorriso_set_zisofs_params(xorriso, 0); - return(ret); -} - - -/* ---------------------------- End Options API ------------------------ */ - - -/* @return <0 error , >=0 number of skipped dashes -*/ -int Xorriso_normalize_command(struct XorrisO *xorriso, char *original_cmd, - int argno, char *cmd_data, int sizeof_cmd_data, - char **cmd, int flag) -{ - int was_dashed= 0; - char *dash_pt; - - if(strlen(original_cmd)>= sizeof_cmd_data) { - if(argno>=0) - sprintf(xorriso->info_text, "Oversized argument #%d (length %d)\n", - argno, (int) strlen(original_cmd)); - else - sprintf(xorriso->info_text, "Oversized option (length %d)\n", - (int) strlen(original_cmd)); - return(-1); - } - strcpy(cmd_data, original_cmd); - *cmd= cmd_data; - if(strcmp(*cmd, xorriso->list_delimiter)==0) - return(1); - while((*cmd)[0]=='-') { - if((*cmd)[1]==0) - break; - was_dashed++; - (*cmd)++; - } - for(dash_pt= *cmd; *dash_pt!=0; dash_pt++) - if(*dash_pt=='-') - *dash_pt= '_'; - return(was_dashed); -} - - -/* @param flag bit0= do not warn of unknown option - @return <=0 error, - 1=count is valid, 2=dashed unknown, 3=undashed unknown -*/ -int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv, - int *count, int flag) -{ - int ret, was_dashed= 0, i; - char *cmd, cmd_data[2*SfileadrL]; - static char arg0_commands[][40]= { - "ban_stdio_write","close_filter_list","commit","devices","end", - "for_backup", "help", - "list_formats","no_rc","print_size","pvd_info","pwd","pwdi","pwdx", - "rollback","rollback_end","tell_media_space","toc","version", - "" - }; - static char arg1_commands[][40]= { - "abort_on","acl","add_plainly","application_id","auto_charset", - "backslash_codes","blank", - "calm_drive","cd","cdi","cdx","charset","close", - "commit_eject","compliance", - "dev","dialog","disk_dev_ino","disk_pattern","dummy","dvd_obs","eject", - "iso_rr_pattern","follow","format","fs","gid","grow_blindly","hardlinks", - "history","indev","in_charset","joliet", - "list_delimiter","list_profiles","local_charset", - "mark","md5","mount_opts","not_leaf","not_list","not_mgt", - "options_from_file","osirrox","outdev","out_charset","overwrite", - "pacifier","padding","path_list","pathspecs","pkt_output","print","prompt", - "prog","prog_help","publisher","quoted_not_list","quoted_path_list", - "reassure","report_about","rom_toc_scan","scsi_log", - "session_log","speed","split_size","status","status_history_max", - "stdio_sync","stream_recording","system_id","temp_mem_limit", - "uid","unregister_filter","use_readline","volid","volset_id", - "xattr","zisofs", - "" - }; - static char arg2_commands[][40]= { - "assert_volid","boot_image","compare","compare_r","drive_class", - "errfile_log","error_behavior","extract","extract_single", - "load","logfile", - "map","map_single","page","return_with", - "scdbackup_tag","update","update_r","volume_date", - "" - }; - static char arg4_commands[][40]= { - "cut_out","extract_cut","mount","mount_cmd","paste_in","session_string", - "" - }; - static char argn_commands[][40]= { - "add","alter_date","alter_date_r","as", - "check_md5","check_md5_r","check_media","check_media_defaults", - "chgrp","chgrpi","chgrp_r","chgrp_ri","chmod","chmodi", - "chmod_r","chmod_ri","chown","chowni","chown_r","chown_ri", - "compare_l","cpr","cpri","cp_rax","cp_rx","cpax","cpx", - "du","dui","dus","dusi","dux","dusx","external_filter","extract_l", - "file_size_limit","find","findi","finds","findx", - "getfacl","getfacli","getfacl_r","getfacl_ri", - "getfattr","getfattri","getfattr_r","getfattr_ri", - "ls","lsi","lsl","lsli","lsd","lsdi","lsdl","lsdli", - "lsx","lslx","lsdx","lsdlx","map_l","mv","mvi","mkdir","mkdiri", - "not_paths","rm","rmi","rm_r","rm_ri","rmdir","rmdiri","update_l", - "setfacl","setfacli","setfacl_list","setfacl_listi", - "setfacl_r","setfacl_ri","setfattr","setfattri", - "setfattr_list","setfattr_listi","setfattr_r","setfattr_ri", - "set_filter","set_filter_r","show_stream","show_stream_r", - "" - }; - - *count= 0; - if(argc<=0) - return(-1); - ret= Xorriso_normalize_command(xorriso, argv[0], -1, - cmd_data, sizeof(cmd_data), &cmd, 0); - if(ret<0) - return(ret); - was_dashed= (ret>0); - if(cmd[0]=='#' || cmd[0]==0 || strcmp(cmd, xorriso->list_delimiter) == 0) { - /* ignore: comment line , empty option , orphaned list delimiter */ - return(1); - } - for(i=0; arg0_commands[i][0]!=0; i++) - if(strcmp(arg0_commands[i], cmd)==0) - return(1); - *count= 1; - for(i=0; arg1_commands[i][0]!=0; i++) - if(strcmp(arg1_commands[i], cmd)==0) - return(1); - *count= 2; - for(i=0; arg2_commands[i][0]!=0; i++) - if(strcmp(arg2_commands[i], cmd)==0) - return(1); - *count= 4; - for(i=0; arg4_commands[i][0]!=0; i++) - if(strcmp(arg4_commands[i], cmd)==0) - return(1); - *count= 0; - for(i=0; argn_commands[i][0]!=0; i++) - if(strcmp(argn_commands[i], cmd)==0) { - ret= Xorriso_end_idx(xorriso, argc, argv, 1, 1); - if(ret<1) - return(ret); - *count= ret-1; - return(1); - } - - if(!(flag&1)) { - sprintf(xorriso->info_text, "Unknown option : '%s'", argv[0]); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - } - - return(2+!was_dashed); -} - - -/* @param flag bit0= recursion - bit1= these are command line arguments - (for xorriso->argument_emulation) -*/ -int Xorriso_interpreter(struct XorrisO *xorriso, - int argc, char **argv, int *idx, int flag) -/* -return: - <=0 error , 1 = success , 2 = problem event ignored , 3 = end program run -*/ -{ - int ret, was_dashed, end_ret, num1, num2; - char *cmd, *original_cmd, cmd_data[2*SfileadrL], *arg1, *arg2; - - if(xorriso==NULL) - return(0); - if(xorriso->is_dialog) { - xorriso->result_line_counter= xorriso->result_page_counter= 0; - if(xorriso->result_page_length<0) - xorriso->result_page_length= -xorriso->result_page_length; - } - -next_command:; - if(flag&2) { - ret= 1; - if(xorriso->argument_emulation==1) - ret= Xorriso_as_genisofs(xorriso, argc, argv, idx, 0); - else if(xorriso->argument_emulation==2) - ret= Xorriso_as_cdrskin(xorriso, argc, argv, idx, 0); - if(xorriso->argument_emulation>0) { - xorriso->argument_emulation= 0; - if(ret<=0) - goto eval_any_problems; - if((*idx)>=argc) - {ret= 1; goto ex;} - } - } - - xorriso->prepended_wd= 0; - xorriso->request_to_abort= xorriso->request_not_to_ask= 0; - Xorriso_set_problem_status(xorriso, "", 0); - if((*idx)add_plainly==3 && cmd[0] && !xorriso->is_dialog) { - (*idx)++; - goto add_plain_argument; - } - was_dashed= 0; - - ret= Xorriso_normalize_command(xorriso, original_cmd, -1, - cmd_data, sizeof(cmd_data), &cmd, 0); - if(ret<0) - goto eval_any_problems; - was_dashed= ret; - - (*idx)++; - if((*idx)10); - - } else if(strcmp(cmd,"application_id")==0) { - (*idx)++; - ret= Xorriso_option_application_id(xorriso, arg1, 0); - - } else if(strcmp(cmd,"as")==0) { - ret= Xorriso_option_as(xorriso, argc, argv, idx, 0); - - } else if(strcmp(cmd,"assert_volid")==0) { - (*idx)+= 2; - ret= Xorriso_option_assert_volid(xorriso, arg1, arg2, 0); - - } else if(strcmp(cmd,"auto_charset")==0) { - (*idx)++; - ret= Xorriso_option_auto_charset(xorriso, arg1, 0); - - } else if(strcmp(cmd,"backslash_codes")==0) { - (*idx)++; - ret= Xorriso_option_backslash_codes(xorriso, arg1, 0); - - } else if(strcmp(cmd,"ban_stdio_write")==0) { - ret= Xorriso_option_ban_stdio_write(xorriso, 0); - - } else if(strcmp(cmd,"blank")==0) { - (*idx)++; - ret= Xorriso_option_blank(xorriso, arg1, 0); - - } else if(strcmp(cmd,"boot_image")==0) { - (*idx)+= 2; - ret= Xorriso_option_boot_image(xorriso, arg1, arg2, 0); - - } else if(strcmp(cmd,"calm_drive")==0) { - (*idx)++; - ret= Xorriso_option_calm_drive(xorriso, arg1, 0); - - } else if(strcmp(cmd,"cd")==0 || strcmp(cmd,"cdi")==0) { - (*idx)++; - ret= Xorriso_option_cdi(xorriso, arg1, 0); - - } else if(strcmp(cmd,"cdx")==0) { - (*idx)++; - ret= Xorriso_option_cdx(xorriso, arg1, 0); - - } else if(strcmp(cmd,"charset")==0) { - (*idx)++; - ret= Xorriso_option_charset(xorriso, arg1, 3); - - } else if(strcmp(cmd,"check_md5")==0) { - ret= Xorriso_option_check_md5(xorriso, argc, argv, idx, 0); - - } else if(strcmp(cmd,"check_md5_r")==0) { - ret= Xorriso_option_check_md5(xorriso, argc, argv, idx, 8); - - } else if(strcmp(cmd,"check_media")==0) { - ret= Xorriso_option_check_media(xorriso, argc, argv, idx, 0); - - } else if(strcmp(cmd,"check_media_defaults")==0) { - ret= Xorriso_option_check_media_defaults(xorriso, argc, argv, idx, 0); - - } else if(strcmp(cmd,"chgrp")==0 || strcmp(cmd,"chgrpi")==0) { - (*idx)+= 1; - ret= Xorriso_option_chgrpi(xorriso, arg1, argc, argv, idx, 0); - - } else if(strcmp(cmd,"chgrp_r")==0 || strcmp(cmd,"chgrp_ri")==0) { - (*idx)+= 1; - ret= Xorriso_option_chgrpi(xorriso, arg1, argc, argv, idx, 1); - - } else if(strcmp(cmd,"chmod")==0 || strcmp(cmd,"chmodi")==0) { - (*idx)+= 1; - ret= Xorriso_option_chmodi(xorriso, arg1, argc, argv, idx, 0); - - } else if(strcmp(cmd,"chmod_r")==0 || strcmp(cmd,"chmod_ri")==0) { - (*idx)+= 1; - ret= Xorriso_option_chmodi(xorriso, arg1, argc, argv, idx, 1); - - } else if(strcmp(cmd,"chown_r")==0 || strcmp(cmd,"chown_ri")==0) { - (*idx)+= 1; - ret= Xorriso_option_chowni(xorriso, arg1, argc, argv, idx, 1); - - } else if(strcmp(cmd,"chown")==0 || strcmp(cmd,"chowni")==0) { - (*idx)+= 1; - ret= Xorriso_option_chowni(xorriso, arg1, argc, argv, idx, 0); - - } else if(strcmp(cmd,"close")==0) { - (*idx)++; - ret= Xorriso_option_close(xorriso, arg1, 0); - - } else if(strcmp(cmd,"close_filter_list")==0) { - ret= Xorriso_option_close_filter_list(xorriso, 0); - - } else if(strcmp(cmd,"commit")==0) { - ret= Xorriso_option_commit(xorriso, 0); - - } else if(strcmp(cmd,"commit_eject")==0) { - (*idx)++; - ret= Xorriso_option_commit_eject(xorriso, arg1, 0); - - } else if(strcmp(cmd,"compare")==0) { - (*idx)+= 2; - ret= Xorriso_option_compare(xorriso, arg1, arg2, 1); - - } else if(strcmp(cmd,"compare_l")==0) { - ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 1<<8); - - } else if(strcmp(cmd,"compare_r")==0) { - (*idx)+= 2; - ret= Xorriso_option_compare(xorriso, arg1, arg2, 1|8); - - } else if(strcmp(cmd,"compliance")==0) { - (*idx)++; - Xorriso_option_compliance(xorriso, arg1, 0); - - } else if(strcmp(cmd,"cpr")==0 || strcmp(cmd,"cpri")==0) { - ret= Xorriso_option_cpri(xorriso, argc, argv, idx, 0); - - } else if(strcmp(cmd,"cp_rx")==0 || strcmp(cmd,"cp_rax")==0) { - ret= Xorriso_option_cpx(xorriso, argc, argv, idx, - 1|((strcmp(cmd,"cp_rax")==0)<<1)); - - } else if(strcmp(cmd,"cpx")==0 || strcmp(cmd,"cpax")==0) { - ret= Xorriso_option_cpx(xorriso, argc, argv, idx, - (strcmp(cmd,"cpax")==0)<<1); - - } else if(strcmp(cmd,"cut_out")==0) { - (*idx)+= 4; - if((*idx)>argc) { - sprintf(xorriso->info_text, - "-cut_out: Not enough arguments. Needed are: disk_path start count so_rr_path"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; - } else - ret= Xorriso_option_cut_out(xorriso, arg1, arg2, - argv[(*idx)-2], argv[(*idx)-1], 0); - - } else if(strcmp(cmd,"dev")==0) { - (*idx)++; - ret= Xorriso_option_dev(xorriso, arg1, 3); - - } else if(strcmp(cmd,"devices")==0) { - ret= Xorriso_option_devices(xorriso, 0); - - } else if(strcmp(cmd,"dialog")==0) { - (*idx)++; - ret= Xorriso_option_dialog(xorriso, arg1, 0); - - } else if(strcmp(cmd,"disk_dev_ino")==0) { - (*idx)++; - ret= Xorriso_option_disk_dev_ino(xorriso, arg1, 0); - - } else if(strcmp(cmd,"disk_pattern")==0) { - (*idx)++; - ret= Xorriso_option_disk_pattern(xorriso, arg1, 0); - - } else if(strcmp(cmd,"drive_class")==0) { - (*idx)+= 2; - ret= Xorriso_option_drive_class(xorriso, arg1, arg2, 0); - - } else if(strcmp(cmd,"du")==0 || strcmp(cmd,"dui")==0 || - strcmp(cmd,"dus")==0 || strcmp(cmd,"dusi")==0) { - ret= Xorriso_option_lsi(xorriso, argc, argv, idx, (cmd[2]!='s')|4); - - } else if(strcmp(cmd,"dummy")==0) { - (*idx)++; - ret= Xorriso_option_dummy(xorriso, arg1, 0); - - } else if(strcmp(cmd,"dvd_obs")==0) { - (*idx)++; - ret= Xorriso_option_dvd_obs(xorriso, arg1, 0); - - } else if(strcmp(cmd,"dux")==0 || strcmp(cmd,"dusx")==0) { - ret= Xorriso_option_lsx(xorriso, argc, argv, idx, (cmd[2]!='s')|4); - - } else if(strcmp(cmd,"eject")==0) { - (*idx)++; - ret= Xorriso_option_eject(xorriso, arg1, 0); - - } else if(strcmp(cmd,"end")==0) { - end_ret= Xorriso_option_end(xorriso, 0); - ret= Xorriso_eval_problem_status(xorriso, ret, 0); - if(ret<0) - return(ret); - if(end_ret!=2) - {ret= 3; goto ex;} - - } else if(strcmp(cmd,"errfile_log")==0) { - (*idx)+= 2; - ret= Xorriso_option_errfile_log(xorriso, arg1, arg2, 0); - - } else if(strcmp(cmd,"error_behavior")==0) { - (*idx)+= 2; - ret= Xorriso_option_error_behavior(xorriso, arg1, arg2, 0); - - } else if(strcmp(cmd,"external_filter")==0) { - ret= Xorriso_option_external_filter(xorriso, argc, argv, idx, 0); - - } else if(strcmp(cmd,"extract")==0) { - (*idx)+= 2; - ret= Xorriso_option_extract(xorriso, arg1, arg2, 0); - - } else if(strcmp(cmd,"extract_cut")==0) { - (*idx)+= 4; - if((*idx)>argc) { - sprintf(xorriso->info_text, - "-extract_cut: Not enough arguments. Needed are: disk_path start count so_rr_path"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; - } else - ret= Xorriso_option_extract_cut(xorriso, arg1, arg2, - argv[(*idx)-2], argv[(*idx)-1], 0); - - } else if(strcmp(cmd,"extract_l")==0) { - ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 3<<8); - - } else if(strcmp(cmd,"extract_single")==0) { - (*idx)+= 2; - ret= Xorriso_option_extract(xorriso, arg1, arg2, 32); - - } else if(strcmp(cmd,"file_size_limit")==0) { - ret= Xorriso_option_file_size_limit(xorriso, argc, argv, idx, 0); - - } else if(strcmp(cmd,"find")==0 || strcmp(cmd,"findi")==0) { - ret= Xorriso_option_find(xorriso, argc, argv, idx, 0); - - } else if(strcmp(cmd,"findx")==0) { - ret= Xorriso_option_find(xorriso, argc, argv, idx, 1); - - } else if(strcmp(cmd,"follow")==0) { - (*idx)++; - ret= Xorriso_option_follow(xorriso, arg1, 0); - - } else if(strcmp(cmd,"for_backup")==0) { - Xorriso_option_hardlinks(xorriso, "on", 0); - Xorriso_option_acl(xorriso, "on", 0); - Xorriso_option_xattr(xorriso, "on", 0); - Xorriso_option_md5(xorriso, "on", 0); - ret= 1; - - } else if(strcmp(cmd,"format")==0) { - (*idx)++; - ret= Xorriso_option_blank(xorriso, arg1, 1); - - } else if(strcmp(cmd,"fs")==0) { - (*idx)++; - ret= Xorriso_option_fs(xorriso, arg1, 0); - - } else if(strcmp(cmd,"getfacl")==0 || strcmp(cmd,"getfacli")==0) { - ret= Xorriso_option_getfacli(xorriso, argc, argv, idx, 0); - - } else if(strcmp(cmd,"getfacl_r")==0 || strcmp(cmd,"getfacl_ri")==0) { - ret= Xorriso_option_getfacli(xorriso, argc, argv, idx, 1); - - } else if(strcmp(cmd,"getfattr")==0 || strcmp(cmd,"getfattri")==0) { - ret= Xorriso_option_getfacli(xorriso, argc, argv, idx, 2); - - } else if(strcmp(cmd,"getfattr_r")==0 || strcmp(cmd,"getfattr_ri")==0) { - ret= Xorriso_option_getfacli(xorriso, argc, argv, idx, 1 | 2); - - } else if(strcmp(cmd,"gid")==0) { - (*idx)++; - ret= Xorriso_option_gid(xorriso,arg1,0); - - } else if(strcmp(cmd,"grow_blindly")==0) { - (*idx)++; - ret= Xorriso_option_grow_blindly(xorriso,arg1,0); - - } else if(strcmp(cmd,"hardlinks")==0) { - (*idx)++; - ret= Xorriso_option_hardlinks(xorriso, arg1, 0); - - } else if(strcmp(cmd,"help")==0) { - Xorriso_option_help(xorriso,0); - - } else if(strcmp(cmd,"history")==0) { - /* add to readline history */ - (*idx)++; - ret= Xorriso_option_history(xorriso, arg1, 0); - - } else if(strcmp(cmd,"indev")==0) { - (*idx)++; - ret= Xorriso_option_dev(xorriso, arg1, 1); - - } else if(strcmp(cmd,"in_charset")==0) { - (*idx)++; - ret= Xorriso_option_charset(xorriso, arg1, 1); - - } else if(strcmp(cmd,"iso_rr_pattern")==0) { - (*idx)++; - ret= Xorriso_option_iso_rr_pattern(xorriso, arg1, 0); - - } else if(strcmp(cmd,"joliet")==0) { - (*idx)++; - ret= Xorriso_option_joliet(xorriso, arg1, 0); - - } else if(strcmp(cmd, "list_delimiter") == 0) { - (*idx)++; - ret= Xorriso_option_list_delimiter(xorriso, arg1, 0); - - } else if(strcmp(cmd,"list_formats")==0) { - ret= Xorriso_option_list_formats(xorriso, 0); - - } else if(strcmp(cmd,"list_profiles")==0) { - (*idx)++; - ret= Xorriso_option_list_profiles(xorriso, arg1, 0); - - } else if(strcmp(cmd,"load")==0) { - (*idx)+= 2; - ret= Xorriso_option_load(xorriso, arg1, arg2, 0); - - } else if(strcmp(cmd,"local_charset")==0) { - (*idx)++; - ret= Xorriso_option_charset(xorriso, arg1, 4); - - } else if(strcmp(cmd,"logfile")==0) { - (*idx)+= 2; - ret= Xorriso_option_logfile(xorriso, arg1, arg2, 0); - - } else if(strcmp(cmd,"ls")==0 || strcmp(cmd,"lsi")==0 || - strcmp(cmd,"lsl")==0 || strcmp(cmd,"lsli")==0) { - ret= Xorriso_option_lsi(xorriso, argc, argv, idx, (cmd[2]=='l')); - - } else if(strcmp(cmd,"lsd")==0 || strcmp(cmd,"lsdi")==0 || - strcmp(cmd,"lsdl")==0 || strcmp(cmd,"lsdli")==0) { - ret= Xorriso_option_lsi(xorriso, argc, argv, idx, (cmd[3]=='l')|8); - - } else if(strcmp(cmd,"lsdx")==0 || strcmp(cmd,"lsdlx")==0) { - ret= Xorriso_option_lsx(xorriso, argc, argv, idx, (cmd[3]=='l')|8); - - } else if(strcmp(cmd,"lsx")==0 || strcmp(cmd,"lslx")==0) { - ret= Xorriso_option_lsx(xorriso, argc, argv, idx, (cmd[2]=='l')); - - } else if(strcmp(cmd,"map")==0) { - (*idx)+= 2; - ret= Xorriso_option_map(xorriso, arg1, arg2, 0); - - } else if(strcmp(cmd,"map_l")==0) { - ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 0); - - } else if(strcmp(cmd,"map_single")==0) { - (*idx)+= 2; - ret= Xorriso_option_map(xorriso, arg1, arg2, 32); - - } else if(strcmp(cmd,"mark")==0) { - (*idx)++; - ret= Xorriso_option_mark(xorriso, arg1, 0); - - } else if(strcmp(cmd, "md5")==0) { - (*idx)++; - ret= Xorriso_option_md5(xorriso, arg1, 0); - - } else if(strcmp(cmd, "mount") == 0 || strcmp(cmd, "mount_cmd") == 0) { - (*idx)+= 4; - if((*idx)>argc) { - sprintf(xorriso->info_text, - "-%s: Not enough arguments. Needed are: device entity id command", - cmd); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; - } else - ret= Xorriso_option_mount(xorriso, arg1, arg2, - argv[(*idx)-2], argv[(*idx)-1], - (strcmp(cmd, "mount_cmd") == 0)); - - } else if(strcmp(cmd, "mount_opts")==0) { - (*idx)++; - ret= Xorriso_option_mount_opts(xorriso, arg1, 0); - - } else if(strcmp(cmd,"mv")==0 || strcmp(cmd,"mvi")==0) { - ret= Xorriso_option_mvi(xorriso, argc, argv, idx, 0); - - } else if(strcmp(cmd,"mkdir")==0 || strcmp(cmd,"mkdiri")==0) { - ret= Xorriso_option_mkdiri(xorriso, argc, argv, idx, 0); - - } else if(strcmp(cmd,"no_rc")==0) { - ret= Xorriso_option_no_rc(xorriso, 0); - - } else if(strcmp(cmd,"not_leaf")==0) { - (*idx)++; - ret= Xorriso_option_not_leaf(xorriso, arg1, 0); - - } else if(strcmp(cmd,"not_list")==0) { - (*idx)++; - ret= Xorriso_option_not_list(xorriso, arg1, 0); - - } else if(strcmp(cmd,"not_mgt")==0) { - (*idx)++; - ret= Xorriso_option_not_mgt(xorriso, arg1, 0); - - } else if(strcmp(cmd,"not_paths")==0) { - ret= Xorriso_option_not_paths(xorriso, argc, argv, idx, 0); - - } else if(strcmp(cmd,"options_from_file")==0) { - (*idx)++; - ret= Xorriso_option_options_from_file(xorriso,arg1,0); - if(ret==3) - goto ex; - - } else if(strcmp(cmd,"osirrox")==0) { - (*idx)++; - ret= Xorriso_option_osirrox(xorriso,arg1,0); - - } else if(strcmp(cmd,"outdev")==0) { - (*idx)++; - ret= Xorriso_option_dev(xorriso, arg1, 2); - - } else if(strcmp(cmd,"out_charset")==0) { - (*idx)++; - ret= Xorriso_option_charset(xorriso, arg1, 2); - - } else if(strcmp(cmd,"overwrite")==0) { - (*idx)++; - ret= Xorriso_option_overwrite(xorriso,arg1,0); - - } else if(strcmp(cmd,"pacifier")==0) { - (*idx)++; - ret= Xorriso_option_pacifier(xorriso, arg1, 0); - - } else if(strcmp(cmd,"padding")==0) { - (*idx)++; - ret= Xorriso_option_padding(xorriso, arg1, 0); - - } else if(strcmp(cmd,"page")==0) { - (*idx)+= 2; - num1= num2= 0; - sscanf(arg1,"%d",&num1); - sscanf(arg2,"%d",&num2); - if(num1<0) - num1= 0; - if(arg1[0]==0) - num1= 16; - if(num2<=0) - num2= 80; - ret= Xorriso_option_page(xorriso, num1, num2, 0); - - } else if(strcmp(cmd,"paste_in")==0) { - (*idx)+= 4; - if((*idx)>argc) { - sprintf(xorriso->info_text, - "-paste_in: Not enough arguments. Needed are: disk_path start count so_rr_path"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; - } else - ret= Xorriso_option_paste_in(xorriso, arg1, arg2, - argv[(*idx)-2], argv[(*idx)-1], 0); - - } else if(strcmp(cmd,"path-list")==0 || strcmp(cmd,"path_list")==0) { - (*idx)++; - ret= Xorriso_option_path_list(xorriso, arg1, 0); - - } else if(strcmp(cmd,"pathspecs")==0) { - (*idx)++; - ret= Xorriso_option_pathspecs(xorriso, arg1, 0); - - } else if(strcmp(cmd,"pkt_output")==0) { - (*idx)++; - ret= Xorriso_option_pkt_output(xorriso, arg1, 0); - - } else if(strcmp(cmd,"print")==0) { - (*idx)++; - ret= Xorriso_option_print(xorriso, arg1, 0); - - } else if(strcmp(cmd,"print_size")==0) { - Xorriso_option_print_size(xorriso, 0); - - } else if(strcmp(cmd,"prompt")==0) { - (*idx)++; - ret= Xorriso_option_prompt(xorriso, arg1, 0); - - } else if(strcmp(cmd,"prog")==0) { - (*idx)++; - ret= Xorriso_option_prog(xorriso, arg1, 0); - - } else if(strcmp(cmd,"publisher")==0) { - (*idx)++; - Xorriso_option_publisher(xorriso, arg1, 0); - - } else if(strcmp(cmd,"pvd_info")==0) { - Xorriso_option_pvd_info(xorriso, 0); - - } else if(strcmp(cmd,"pwd")==0 || strcmp(cmd,"pwdi")==0) { - Xorriso_option_pwdi(xorriso, 0); - - } else if(strcmp(cmd,"pwdx")==0) { - Xorriso_option_pwdx(xorriso, 0); - - } else if(strcmp(cmd,"quoted_not_list")==0) { - (*idx)++; - ret= Xorriso_option_not_list(xorriso, arg1, 1); - - } else if(strcmp(cmd,"quoted_path_list")==0) { - (*idx)++; - ret= Xorriso_option_path_list(xorriso, arg1, 1); - - } else if(strcmp(cmd,"reassure")==0) { - (*idx)++; - ret= Xorriso_option_reassure(xorriso, arg1, 0); - - } else if(strcmp(cmd,"report_about")==0) { - (*idx)++; - ret= Xorriso_option_report_about(xorriso, arg1, 0); - - } else if(strcmp(cmd,"return_with")==0) { - (*idx)+= 2; - num2= 0; - sscanf(arg2,"%d",&num2); - ret= Xorriso_option_return_with(xorriso, arg1, num2, 0); - - } else if(strcmp(cmd,"rm")==0 || strcmp(cmd,"rmi")==0) { - ret= Xorriso_option_rmi(xorriso, argc, argv, idx, 0); - - } else if(strcmp(cmd,"rm_r")==0 || strcmp(cmd,"rm_ri")==0) { - ret= Xorriso_option_rmi(xorriso, argc, argv, idx, 1); - - } else if(strcmp(cmd,"rmdir")==0 || strcmp(cmd,"rmdiri")==0) { - ret= Xorriso_option_rmi(xorriso, argc, argv, idx, 2); - - } else if(strcmp(cmd,"rollback")==0) { - ret= Xorriso_option_rollback(xorriso, 0); - - } else if(strcmp(cmd,"rollback_end")==0) { - end_ret= Xorriso_option_end(xorriso, 1); - ret= Xorriso_eval_problem_status(xorriso, ret, 0); - if(ret<0) - return(ret); - if(end_ret!=2) - {ret= 3; goto ex;} - - } else if(strcmp(cmd,"rom_toc_scan")==0) { - (*idx)++; - Xorriso_option_rom_toc_scan(xorriso, arg1, 0); - - } else if(strcmp(cmd,"scdbackup_tag")==0) { - (*idx)+= 2; - ret= Xorriso_option_scdbackup_tag(xorriso, arg1, arg2, 0); - - } else if(strcmp(cmd, "scsi_log") == 0) { - (*idx)++; - ret= Xorriso_option_scsi_log(xorriso, arg1, 0); - - } else if(strcmp(cmd,"session_log")==0) { - (*idx)++; - ret= Xorriso_option_session_log(xorriso, arg1, 0); - - } else if(strcmp(cmd, "session_string") == 0) { - (*idx)+= 4; - if((*idx)>argc) { - sprintf(xorriso->info_text, - "-%s: Not enough arguments. Needed are: device entity id command", - cmd); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; - } else - ret= Xorriso_option_mount(xorriso, arg1, arg2, - argv[(*idx)-2], argv[(*idx)-1], 2); - - } else if(strcmp(cmd,"setfacl")==0 || strcmp(cmd,"setfacli")==0) { - (*idx)+= 1; - ret= Xorriso_option_setfacli(xorriso, arg1, argc, argv, idx, 0); - - } else if(strcmp(cmd,"setfacl_list")==0 || strcmp(cmd,"setfacl_listi")==0) { - (*idx)+= 1; - ret= Xorriso_option_setfacl_listi(xorriso, arg1, 0); - - } else if(strcmp(cmd,"setfacl_r")==0 || strcmp(cmd,"setfacl_ri")==0) { - (*idx)+= 1; - ret= Xorriso_option_setfacli(xorriso, arg1, argc, argv, idx, 1); - - } else if(strcmp(cmd,"setfattr")==0 || strcmp(cmd,"setfattri")==0) { - (*idx)+= 2; - ret= Xorriso_option_setfattri(xorriso, arg1, arg2, argc, argv, idx, 0); - - } else if(strcmp(cmd,"setfattr_list")==0 || strcmp(cmd,"setfattr_listi")==0) { - (*idx)+= 1; - ret= Xorriso_option_setfattr_listi(xorriso, arg1, 0); - - } else if(strcmp(cmd,"setfattr_r")==0 || strcmp(cmd,"setfattr_ri")==0) { - (*idx)+= 2; - ret= Xorriso_option_setfattri(xorriso, arg1, arg2, argc, argv, idx, 1); - - } else if(strcmp(cmd,"set_filter")==0 || strcmp(cmd,"set_filter_r")==0) { - (*idx)+= 1; - ret= Xorriso_option_set_filter(xorriso, arg1, argc, argv, idx, - strcmp(cmd,"set_filter_r")==0); - - } else if(strcmp(cmd,"show_stream")==0 || strcmp(cmd,"show_stream_r")==0) { - ret= Xorriso_option_set_filter(xorriso, "", argc, argv, idx, - (strcmp(cmd,"show_stream_r")==0) | 2 | 4); - - } else if(strcmp(cmd,"speed")==0) { - (*idx)++; - ret= Xorriso_option_speed(xorriso, arg1, 0); - - } else if(strcmp(cmd,"split_size")==0) { - (*idx)++; - ret= Xorriso_option_split_size(xorriso, arg1, 0); - - } else if(strcmp(cmd,"status")==0) { - (*idx)++; - ret= Xorriso_option_status(xorriso, arg1, 0); - - } else if(strcmp(cmd,"status_history_max")==0) { - (*idx)++; - sscanf(arg1,"%d",&num1); - ret= Xorriso_option_status_history_max(xorriso, num1, 0); - - } else if(strcmp(cmd,"stdio_sync")==0) { - (*idx)++; - ret= Xorriso_option_stdio_sync(xorriso, arg1, 0); - - } else if(strcmp(cmd,"stream_recording")==0) { - (*idx)++; - ret= Xorriso_option_stream_recording(xorriso, arg1, 0); - - } else if(strcmp(cmd,"system_id")==0) { - (*idx)++; - ret= Xorriso_option_system_id(xorriso, arg1, 0); - - } else if(strcmp(cmd,"tell_media_space")==0) { - Xorriso_option_tell_media_space(xorriso, 0); - - } else if(strcmp(cmd,"temp_mem_limit")==0) { - (*idx)++; - ret= Xorriso_option_temp_mem_limit(xorriso, arg1, 0); - - } else if(strcmp(cmd,"test")==0) { /* This option does not exist. */ - - /* install temporary test code here */; - - } else if(strcmp(cmd,"toc")==0) { - Xorriso_option_toc(xorriso, 0); - - } else if(strcmp(cmd,"uid")==0) { - (*idx)++; - ret= Xorriso_option_uid(xorriso,arg1,0); - - } else if(strcmp(cmd,"unregister_filter")==0) { - (*idx)++; - ret= Xorriso_option_unregister_filter(xorriso, arg1, 0); - - } else if(strcmp(cmd,"update")==0) { - (*idx)+= 2; - ret= Xorriso_option_update(xorriso, arg1, arg2, 1); - - } else if(strcmp(cmd,"update_l")==0) { - ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 2<<8); - - } else if(strcmp(cmd,"update_r")==0) { - (*idx)+= 2; - ret= Xorriso_option_update(xorriso, arg1, arg2, 1|8); - - } else if(strcmp(cmd,"use_readline")==0) { - (*idx)++; - ret= Xorriso_option_use_readline(xorriso, arg1, 0); - - } else if(strcmp(cmd,"version")==0){ - ret= Xorriso_option_version(xorriso, 0); - - } else if(strcmp(cmd,"volset_id")==0) { - (*idx)++; - ret= Xorriso_option_volset_id(xorriso, arg1, 0); - - } else if(strcmp(cmd,"volid")==0) { - (*idx)++; - ret= Xorriso_option_volid(xorriso,arg1,0); - - } else if(strcmp(cmd,"volume_date")==0) { - (*idx)+= 2; - ret= Xorriso_option_volume_date(xorriso, arg1, arg2, 0); - - } else if(strcmp(cmd,"xattr")==0) { - (*idx)++; - ret= Xorriso_option_xattr(xorriso, arg1, 0); - - } else if(strcmp(cmd,"zisofs")==0) { - (*idx)++; - ret= Xorriso_option_zisofs(xorriso, arg1, 0); - - } else if(strcmp(cmd, xorriso->list_delimiter)==0){ - /* tis ok */; - - } else if(was_dashed) { - if(xorriso->add_plainly>1) - goto add_plain_argument; -unknown_option:; - sprintf(xorriso->info_text, "Not a known option: '%s'\n", - original_cmd); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto eval_any_problems;} - - } else { - if(xorriso->add_plainly<=0) - goto unknown_option; -add_plain_argument:; - (*idx)--; - ret= Xorriso_option_add(xorriso, (*idx)+1, argv, idx, 0); - (*idx)++; - - } - -eval_any_problems: - ret= Xorriso_eval_problem_status(xorriso, ret, 0); - if(ret<0) - return(ret); - - if(*idxis_dialog) && !(flag&1)) - Xorriso_mark(xorriso,0); - fflush(stdout); - return(ret); -} - - -int Xorriso_execute_option(struct XorrisO *xorriso, char *line, int flag) -/* - bit0-bit15 are forwarded to Xorriso_interpreter - - bit16= no pageing of info lines - bit17= print === bar even if xorriso->found<0 -*/ -{ - int ret,argc= 0, idx= 1; - char **argv= NULL; - double tdiff; - struct timeval tv; - struct timezone tz; - - gettimeofday(&tv,&tz); - Xorriso_reset_counters(xorriso,0); - xorriso->idle_time= 0.0; - tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec); - - /* parse line into args */ - ret= Sfile_make_argv(xorriso->progname, line, &argc, &argv, - 4 | ((xorriso->bsl_interpretation & 3) << 5)); - if(ret < 0) { - Xorriso_msgs_submit(xorriso, 0, - "Severe lack of resources during command line parsing", 0, "FATAL", 0); - goto ex; - } - if(ret == 0) { - sprintf(xorriso->info_text, "Incomplete quotation in command line: %s", - line); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - goto ex; - } - if(argc<2) - {ret= 1; goto ex;} - if(argv[1][0]=='#') - {ret= 1; goto ex;} - - ret= Xorriso_interpreter(xorriso, argc, argv, &idx, flag&0xffff); - if(ret<0) - goto ex; - gettimeofday(&tv,&tz); - tdiff= tv.tv_sec+(1.e-6*(double) tv.tv_usec)-tdiff-xorriso->idle_time; - if(tdiff<0.001) - tdiff= 0.001; - if(xorriso->error_count>0) { - sprintf(xorriso->info_text, - "----------------------------- %7.f errors encountered\n", - xorriso->error_count); - Xorriso_info(xorriso,!(flag&(1<<16))); - } - - /* ??? >>> print elapsed time tdiff ? */; - - if((flag&(1<<17)) && !xorriso->bar_is_fresh) { - sprintf(xorriso->info_text,"============================\n"); - Xorriso_info(xorriso,0); - xorriso->bar_is_fresh= 1; - } - Xorriso_reset_counters(xorriso,0); -ex:; - Sfile_make_argv("", "", &argc, &argv, 2); /* release memory */ - return(ret); -} - - -int Xorriso_dialog(struct XorrisO *xorriso, int flag) -{ - int ret,first_round; - char line[2*SfileadrL]; - - if(!xorriso->dialog) - return(1); - xorriso->is_dialog= 1; - for(first_round= 1;1;first_round= 0) { - if(xorriso->pending_option[0]!=0) { - Xorriso_mark(xorriso,0); - strcpy(line,xorriso->pending_option); - xorriso->pending_option[0]= 0; - } else { - if(!xorriso->bar_is_fresh) { - sprintf(xorriso->info_text,"============================\n"); - Xorriso_info(xorriso,0); - xorriso->bar_is_fresh= 1; - } - sprintf(xorriso->info_text,"enter option and arguments :\n"); - Xorriso_info(xorriso,0); - Xorriso_mark(xorriso,0); - ret= Xorriso_dialog_input(xorriso,line,sizeof(line),4); - if(ret<=0) - break; - } - sprintf(xorriso->info_text, - "==============================================================\n"); - Xorriso_info(xorriso,0); - - ret= Xorriso_execute_option(xorriso,line,1<<17); - if(ret<0) - goto ex; - if(ret==3) - goto ex; - xorriso->did_something_useful= 1; - xorriso->no_volset_present= 0; /* Re-enable "No ISO image present." */ - } - ret= 1; -ex:; - xorriso->is_dialog= 0; - return(ret); -} - - -int Xorriso_change_is_pending(struct XorrisO *xorriso, int flag) -{ - return(!!xorriso->volset_change_pending); -} - - -int Xorriso_protect_stdout(struct XorrisO *xorriso, int flag) -{ - if(xorriso->dev_fd_1>=0) - return(2); - xorriso->dev_fd_1= dup(1); - close(1); - dup2(2,1); - return(1); -} - - -int Xorriso_prescan_args(struct XorrisO *xorriso, int argc, char **argv, - int flag) -/* - bit0= do not interpret argv[1] -*/ -/* - return: - <0 error - 0 end program - 1 ok, go on -*/ -{ - int i, ret, was_dashed, num2, arg_count; - int was_report_about= 0, was_abort_on= 0, was_return_with= 0; - char *cmd, *original_cmd, cmd_data[5*SfileadrL], *arg1, *arg2; - char mem_list_delimiter[81]; - - strcpy(mem_list_delimiter, xorriso->list_delimiter); - for(i=1+(flag&1);i1) - xorriso->did_something_useful= 1; - if(i==1 && argc==2) { - if(strcmp(cmd,"prog_help")==0) { - i++; - Xorriso_option_prog_help(xorriso,arg1,0); - xorriso->did_something_useful= 1; - {ret= 0; goto ex;} - } else if(strcmp(cmd,"help")==0) { - if(xorriso->argument_emulation == 1) { - Xorriso_genisofs_help(xorriso, 0); - } else if(xorriso->argument_emulation == 2) { - Xorriso_cdrskin_help(xorriso, 0); - } else { - Xorriso_option_help(xorriso,0); - } - xorriso->did_something_useful= 1; - {ret= 0; goto ex;} - } - } else if(i==1 && strcmp(cmd,"no_rc")==0) { - ret= Xorriso_option_no_rc(xorriso, 0); - if(ret<=0) - goto ex; - - } else if((strcmp(cmd,"dev")==0 || strcmp(cmd,"outdev")==0 || - strcmp(cmd,"indev")==0) && - (strcmp(arg1,"stdio:/dev/fd/1")==0 || strcmp(arg1,"-")==0) && - xorriso->dev_fd_1<0) { - /* Detach fd 1 from externally perceived stdout and attach it to stderr. - Keep dev_fd_1 connected to external stdout. dev_fd_1 is to be used when - "stdio:/dev/fd/1" is interpreted as drive address. - */ -protect_stdout:; - Xorriso_protect_stdout(xorriso, 0); - sprintf(xorriso->info_text, - "Encountered - or stdio:/dev/fd/1 as possible write target."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - sprintf(xorriso->info_text, - "Redirecting nearly all text message output to stderr."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - sprintf(xorriso->info_text, "Disabling use of libreadline."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - - } else if(strcmp(cmd,"abort_on")==0 && was_dashed == 1) { - i++; - if(!was_abort_on) - Xorriso_option_abort_on(xorriso, arg1, 0); - was_abort_on= 1; - - } else if(strcmp(cmd,"report_about")==0 && was_dashed == 1) { - i++; - if(!was_report_about) - Xorriso_option_report_about(xorriso, arg1, 0); - was_report_about= 1; - - } else if(strcmp(cmd,"return_with")==0 && was_dashed == 1) { - i+= 2; - num2= 0; - sscanf(arg2,"%d",&num2); - if(!was_return_with) - Xorriso_option_return_with(xorriso, arg1, num2, 0); - was_return_with= 1; - - } else if(strcmp(cmd,"as")==0 && was_dashed == 1) { - if(strcmp(arg1, "mkisofs")==0 || strcmp(arg1, "genisoimage")==0 || - strcmp(arg1, "genisofs")==0 || strcmp(arg1, "xorrisofs")==0) - goto protect_stdout; - - } else if(strcmp(cmd, "list_delimiter") == 0) { - /* Needed for interpreting other args. Gets reset after prescan. */ - i++; - ret= Xorriso_option_list_delimiter(xorriso, arg1, 0); - if(ret <= 0) - goto ex; - - } else if(strcmp(cmd, "scsi_log") == 0 && was_dashed == 1) { - i++; - Xorriso_option_scsi_log(xorriso, arg1, 0); - - } else { - ret= Xorriso_count_args(xorriso, argc-i, argv+i, &arg_count, 1); - if(ret==1) - i+= arg_count; - } - } - ret= 1; -ex:; - strcpy(xorriso->list_delimiter, mem_list_delimiter); - return(ret); -} - - -int Xorriso_read_rc(struct XorrisO *xorriso, int flag) -{ - int ret,i,was_failure= 0,fret; - - if(xorriso->no_rc) - return(1); - i= xorriso->rc_filename_count-1; - Sfile_home_adr_s(".xorrisorc", xorriso->rc_filenames[i], - sizeof(xorriso->rc_filenames[i]),0); - for(i=0;irc_filename_count;i++) { - ret= Sfile_type(xorriso->rc_filenames[i],1|8); - if(ret!=1) - continue; - ret= Xorriso_option_options_from_file(xorriso,xorriso->rc_filenames[i],0); - if(ret>1) - return(ret); - if(ret==1) - continue; /* regular bottom of loop */ - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1); - if(fret>=0) - continue; - return(ret); - } - return(!was_failure); -} - - -int Xorriso_make_return_value(struct XorrisO *xorriso, int flag) -{ - int exit_value= 0; - - if(xorriso->eternal_problem_status >= xorriso->return_with_severity) - exit_value= xorriso->return_with_value; - if(exit_value) { - sprintf(xorriso->info_text, - "-return_with %s %d triggered by problem severity %s", - xorriso->return_with_text, exit_value, - xorriso->eternal_problem_status_text); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - } - return(exit_value); -} - - -int Xorriso_program_arg_bsl(struct XorrisO *xorriso, int argc, char ***argv, - int flag) -{ - int ret; - - if(!(xorriso->bsl_interpretation & 16)) - return(1); - ret= Sfile_argv_bsl(argc, argv, 0); - return(ret); -} - - -char *Xorriso__get_version_text(int flag) -{ - return(Xorriso_program_versioN); -} - - -char *Xorriso__get_patch_level_text(int flag) -{ - return(Xorriso_program_patch_leveL); -} - - - -#endif /* ! Xorriso_without_subS */ - - - -#ifdef Xorriso_with_maiN - - -#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); -} - -#endif /* Xorriso_with_maiN */ - - diff --git a/xorriso/xorriso.h b/xorriso/xorriso.h index 49d94cfa..1519749e 100644 --- a/xorriso/xorriso.h +++ b/xorriso/xorriso.h @@ -574,6 +574,9 @@ int Xorriso_option_chowni(struct XorrisO *xorriso, char *uid, /* Option -close "on"|"off" */ 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 */ /* @param flag bit0= leave indrive and outdrive aquired as they were, 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, char *iso_path, int flag); +/* Option -compliance */ +int Xorriso_option_compliance(struct XorrisO *xorriso, char *mode, int flag); + /* Option -cpr alias -cpri */ int Xorriso_option_cpri( struct XorrisO *xorriso, int argc, char **argv, 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, char *start, char *count, char *disk_path, int flag); -/* Option -follow */ -int Xorriso_option_follow(struct XorrisO *xorriso, char *mode, int flag); +/* Option -file_size_limit */ +int Xorriso_option_file_size_limit(struct XorrisO *xorriso, + int argc, char **argv, int *idx, int flag); + /* Option -find alias -findi, and -findx */ /* @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 *idx, int flag); +/* Option -follow */ +int Xorriso_option_follow(struct XorrisO *xorriso, char *mode, int flag); + /* Option -fs */ 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 */ 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 */ int Xorriso_option_not_paths(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag); @@ -860,6 +874,9 @@ int Xorriso_option_print_size(struct XorrisO *xorriso, int flag); /* Option -prog */ 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 */ int Xorriso_option_prog_help(struct XorrisO *xorriso, char *name, int flag); diff --git a/xorriso/xorriso_main.c b/xorriso/xorriso_main.c new file mode 100644 index 00000000..ac9ee1e6 --- /dev/null +++ b/xorriso/xorriso_main.c @@ -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, + + 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 +#include +#include +#include +#include +#include + +#include + +/* 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); +} + + diff --git a/xorriso/xorriso_makefile_am.txt b/xorriso/xorriso_makefile_am.txt index 96933140..fe1ff9d0 100644 --- a/xorriso/xorriso_makefile_am.txt +++ b/xorriso/xorriso_makefile_am.txt @@ -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 # 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) \ $(EXTF_DEF) $(EXTF_SUID_DEF) $(ZLIB_DEF) \ $(LIBCDIO_DEF) \ @@ -48,9 +48,56 @@ xorriso_xorriso_SOURCES = \ \ xorriso/xorriso.h \ xorriso/xorriso_private.h \ - xorriso/xorriso.c \ + xorriso/xorriso_main.c \ + xorriso/sfile.h \ + xorriso/sfile.c \ + xorriso/aux_objects.h \ + xorriso/aux_objects.c \ + xorriso/findjob.h \ + xorriso/findjob.c \ + xorriso/check_media.h \ + xorriso/check_media.c \ + xorriso/misc_funct.h \ + xorriso/misc_funct.c \ + xorriso/text_io.h \ + xorriso/text_io.c \ + xorriso/match.h \ + xorriso/match.c \ + xorriso/emulators.h \ + xorriso/emulators.c \ + xorriso/disk_ops.h \ + xorriso/disk_ops.c \ + xorriso/cmp_update.h \ + xorriso/cmp_update.c \ + xorriso/parse_exec.h \ + xorriso/parse_exec.c \ + xorriso/opts_a_c.c \ + xorriso/opts_d_h.c \ + xorriso/opts_i_o.c \ + xorriso/opts_p_z.c \ + \ xorriso/xorrisoburn.h \ - xorriso/xorrisoburn.c \ + xorriso/base_obj.h \ + xorriso/base_obj.c \ + xorriso/lib_mgt.h \ + xorriso/lib_mgt.c \ + xorriso/sort_cmp.h \ + xorriso/sort_cmp.c \ + xorriso/drive_mgt.h \ + xorriso/drive_mgt.c \ + xorriso/iso_img.h \ + xorriso/iso_img.c \ + xorriso/iso_tree.h \ + xorriso/iso_tree.c \ + xorriso/iso_manip.h \ + xorriso/iso_manip.c \ + xorriso/write_run.h \ + xorriso/write_run.c \ + xorriso/read_run.h \ + xorriso/read_run.c \ + xorriso/filters.h \ + xorriso/filters.c \ + \ xorriso/xorriso_timestamp.h \ xorriso/xorriso_buildstamp.h \ \ diff --git a/xorriso/xorriso_private.h b/xorriso/xorriso_private.h index 3a831fe8..95b2dff1 100644 --- a/xorriso/xorriso_private.h +++ b/xorriso/xorriso_private.h @@ -33,19 +33,16 @@ #define Xorriso_build_timestamP "-none-given-" #endif -#include + +#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 PermiteM; /* Stack of temporarily altered access permissions */ -struct SpotlisT; /* List of intervals with different read qualities */ struct CheckmediajoB; /* Parameters for Xorriso_check_media() */ 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 */ @@ -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 */ diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 15ff87f1..a2004cec 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2010.05.05.194248" +#define Xorriso_timestamP "2010.05.15.184604" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c deleted file mode 100644 index a947b0d7..00000000 --- a/xorriso/xorrisoburn.c +++ /dev/null @@ -1,13703 +0,0 @@ - - -/* Adapter to libisoburn, libisofs and libburn for xorriso, - a command line oriented batch and dialog tool which creates, loads, - manipulates and burns ISO 9660 filesystem images. - - Copyright 2007-2010 Thomas Schmitt, - - Provided under GPL version 2 or later. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* for -charset */ -#include -#include - - -/* ------------------------------------------------------------------------ */ - -#ifndef Xorriso_standalonE - -/* The library which does the ISO 9660 / RockRidge manipulations */ -#include - -/* The library which does MMC optical drive operations */ -#include - -/* The library which enhances overwriteable media with ISO 9660 multi-session - capabilities via the method invented by Andy Polyakov for growisofs */ -#include - -/* 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 */ - - -/* Some private in advance declarations */ -int Xorriso_pacifier_loop(struct XorrisO *xorriso, struct burn_drive *drive, - int flag); - -int Xorriso__read_pacifier(IsoImage *image, IsoFileSource *filesource); - -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_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__file_start_lba(IsoNode *node, int *lba, 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); - -int Xorriso_path_from_node(struct XorrisO *xorriso, IsoNode *in_node, - char path[SfileadrL], int flag); - -int Xorriso_node_from_path(struct XorrisO *xorriso, IsoImage *volume, - char *path, IsoNode **node, int flag); - -int Xorriso_path_from_lba(struct XorrisO *xorriso, IsoNode *node, int lba, - char path[SfileadrL], int flag); - -int Xorriso__node_lba_cmp(const void *node1, const void *node2); - -int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node, - int *node_idx, int *min_hl, int *max_hl, int flag); - - -#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) - - -/* 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) - -#ifdef NIX -/* <<< */ -unsigned long Xorriso_get_di_counteR= 0; -#endif /* NIX */ - - -/* ------------------------------------------------------------------------ */ - - -static const char *un0(const char *text) -{ - if(text == NULL) - return(""); - return(text); -} - - -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); -} - - -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__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)); -} - - -/* ------------------------------------------------------------------------ */ - -/* @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, µ); - 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= if not MMC drive print NOTE and return 2 - bit1= obtain outdrive, else indrive - bit4= do not report failure -*/ -int Xorriso_get_drive_handles(struct XorrisO *xorriso, - struct burn_drive_info **dinfo, - struct burn_drive **drive, - char *attempt, int flag) -{ - int ret; - - if(flag&2) - *dinfo= (struct burn_drive_info *) xorriso->out_drive_handle; - else - *dinfo= (struct burn_drive_info *) xorriso->in_drive_handle; - if(*dinfo==NULL && !(flag & 16)) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, "No %s drive aquired %s", - (flag&2 ? "output" : "input"), attempt); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } - if(*dinfo==NULL) - return(0); - *drive= (*dinfo)[0].drive; - if(flag & 1) { - ret= burn_drive_get_drive_role(*drive); - if(ret != 1) { - sprintf(xorriso->info_text, - "Output device is not an MMC drive. Desired operation does not apply."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(2); - } - } - return((*drive)!=NULL); -} - - -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); -} - - -/* @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); -} - - -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); -} - - -/* @param flag bit0= aquire as isoburn input drive - bit1= aquire as libburn output drive (as isoburn drive if bit0) - bit2= regard overwriteable media as blank - bit3= if the drive is a regular disk file: truncate it to - the write start address - bit5= do not print toc - bit6= do not calm down drive after aquiring it - @return <=0 failure , 1= ok - 2=success, but not writeable with bit1 - 3=success, but not blank and not ISO with bit0 -*/ -int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag) -{ - int ret, hret, not_writeable= 0, has_what, aquire_flag, load_lba, ext; - int lba, track, session, params_flag, adr_mode, read_ret; - uint32_t size; - struct burn_drive_info *dinfo= NULL, *out_dinfo, *in_dinfo; - struct burn_drive *drive= NULL, *out_drive, *in_drive; - enum burn_disc_status state; - IsoImage *volset = NULL; - IsoNode *root_node; - struct isoburn_read_opts *ropts= NULL; - char libburn_adr[SfileadrL], *boot_fate, *sev; - size_t value_length; - char *value= NULL; - double num; - char volid[33], adr_data[163], *adr_pt; - - if((flag&3)==0) { - sprintf(xorriso->info_text, - "XORRISOBURN program error : Xorriso_aquire_drive bit0+bit1 not set"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - return(-1); - } - ret= Xorriso_give_up_drive(xorriso, (flag&3)|8); - if(ret<=0) - return(ret); - if(flag & 1) - xorriso->isofs_st_out= time(0) - 1; - - ret= Xorriso_auto_driveadr(xorriso, adr, libburn_adr, 0); - if(ret <= 0) - return(ret); - if(strcmp(libburn_adr,"stdio:/dev/fd/1")==0) { - if(xorriso->dev_fd_1<0) { - sprintf(xorriso->info_text, - "-*dev \"stdio:/dev/fd/1\" was not a start argument. Cannot use it now."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } else { - sprintf(libburn_adr, "stdio:/dev/fd/%d", xorriso->dev_fd_1); - } - } - - if((flag&3)==1 && xorriso->out_drive_handle!=NULL) { - ret= Xorriso_get_drive_handles(xorriso, &out_dinfo, &out_drive, - "on attempt to compare new indev with outdev", 2); - if(ret<=0) - goto ex; - ret= burn_drive_equals_adr(out_drive, libburn_adr, 1); - if(ret==1) { - dinfo= out_dinfo; - xorriso->indev_is_exclusive= xorriso->outdev_is_exclusive; - } - } else if((flag&3)==2 && xorriso->in_drive_handle!=NULL) { - ret= Xorriso_get_drive_handles(xorriso, &in_dinfo, &in_drive, - "on attempt to compare new outdev with indev", 0); - if(ret<=0) - goto ex; - ret= burn_drive_equals_adr(in_drive, libburn_adr, 1); - if(ret==1) { - dinfo= in_dinfo; - xorriso->outdev_is_exclusive= xorriso->indev_is_exclusive; - } - } - - if(dinfo==NULL) { - aquire_flag= 1 | ((flag&(8|4))>>1) | ((xorriso->toc_emulation_flag & 3)<<3); - if(xorriso->toc_emulation_flag & 4) - aquire_flag|= 128; - if(!(xorriso->do_aaip & 1)) - aquire_flag|= 32; - if((xorriso->ino_behavior & (1 | 2)) && !(xorriso->do_aaip & (4 | 32))) - aquire_flag|= 64; - burn_preset_device_open(xorriso->drives_exclusive, 0, 0); - ret= isoburn_drive_aquire(&dinfo, libburn_adr, aquire_flag); - burn_preset_device_open(1, 0, 0); - Xorriso_process_msg_queues(xorriso,0); - if(ret<=0) { - sprintf(xorriso->info_text,"Cannot aquire drive '%s'", adr); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - if(flag&1) - if(xorriso->image_start_mode&(1<<31)) /* used up setting */ - xorriso->image_start_mode= 0; /* no need to perform auto setting */ - if(flag & 1) - xorriso->indev_is_exclusive= xorriso->drives_exclusive; - if(flag & 2) - xorriso->outdev_is_exclusive= xorriso->drives_exclusive; - } - drive= dinfo[0].drive; - if(flag&1) { - if(xorriso->image_start_mode&(1<<31)) /* used up setting */ - xorriso->image_start_mode&= ~0xffff; /* perform auto setting */ - if((xorriso->image_start_mode&(1<<30))) { /* if enabled at all */ - adr_pt= xorriso->image_start_value; - adr_mode= xorriso->image_start_mode & 0xffff; - if(adr_mode == 4 && strlen(adr_pt) <= 80) { - /* Convert volid search expression into lba */ - params_flag= 0; - ret= Xorriso__bourne_to_reg(xorriso->image_start_value, adr_data, 0); - if(ret == 1) - params_flag|= 4; - ret= isoburn_get_mount_params(drive, 4, adr_data, &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, - "-load : Given address does not point to an ISO 9660 session", - 0, "FAILURE", 0); - ret= 0; goto ex; - } - sprintf(volid, "%d", lba); - adr_pt= volid; - adr_mode= 3; - } - ret= isoburn_set_msc1(drive, adr_mode, adr_pt, - !!(xorriso->image_start_mode & (1<<16))); - if(ret<=0) - goto ex; - if(xorriso->image_start_mode&(1<<31)) - xorriso->image_start_mode= 0; /* disable msc1 setting completely */ - else - xorriso->image_start_mode|= (1<<31); /* mark as used up */ - } - } - state= isoburn_disc_get_status(drive); - Xorriso_process_msg_queues(xorriso,0); - if(flag&1) { - volset= isoburn_get_attached_image(drive); - if(volset != NULL) { /* The image object is already created */ - iso_image_unref(volset); - } - } - - if(flag&2) { - xorriso->out_drive_handle= dinfo; - if(Sfile_str(xorriso->outdev, adr, 0)<=0) - {ret= -1; goto ex;} - if(state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE) { - sprintf(xorriso->info_text, "Disc status unsuitable for writing"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - not_writeable= 1; - } - } - if(flag&1) { - xorriso->in_drive_handle= dinfo; - if(Sfile_str(xorriso->indev, adr, 0)<=0) - {ret= -1; goto ex;} - } else if(flag&2) { - if(xorriso->in_volset_handle==NULL) { - /* No volume loaded: create empty one */ - ret= Xorriso_create_empty_iso(xorriso, 0); - if(ret<=0) - goto ex; - } else { - iso_image_ref((IsoImage *) xorriso->in_volset_handle); - ret= isoburn_attach_image(drive, (IsoImage *) xorriso->in_volset_handle); - if(ret<=0) { - sprintf(xorriso->info_text, - "Failed to attach ISO image object to outdev"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - {ret= -1; goto ex;} - } - } - if(!(flag&32)) - Xorriso_toc(xorriso, 1 | 2 | 8); - {ret= 1+not_writeable; goto ex;} - } - - 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_hln_array(xorriso, 0); - Xorriso_destroy_di_array(xorriso, 0); - - /* check for invalid state */ - if(state != BURN_DISC_BLANK && state != BURN_DISC_APPENDABLE && - state != BURN_DISC_FULL) { - sprintf(xorriso->info_text, - "Disc status not blank and unsuitable for reading"); - sev= "FAILURE"; - if(xorriso->img_read_error_mode==2) - sev= "FATAL"; - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, sev, 0); - Xorriso_give_up_drive(xorriso, 1|((flag&32)>>2)); - ret= 3; goto ex; - } - /* fill read opts */ - ret= isoburn_ropt_new(&ropts, 0); - if(ret<=0) - goto ex; - - ext= isoburn_ropt_noiso1999; - if((xorriso->ino_behavior & (1 | 2)) && !(xorriso->do_aaip & (1 | 4 | 32)) - && !(xorriso->do_md5 & 1)) - ext|= isoburn_ropt_noaaip; - if(!(xorriso->do_aaip & 1)) - ext|= isoburn_ropt_noacl; - if(!(xorriso->do_aaip & 4)) - ext|= isoburn_ropt_noea; - if(xorriso->ino_behavior & 1) - ext|= isoburn_ropt_noino; - -#ifdef isoburn_ropt_nomd5 - if(!(xorriso->do_md5 & 1)) - ext|= isoburn_ropt_nomd5; -#endif - - isoburn_ropt_set_extensions(ropts, ext); - - isoburn_ropt_set_default_perms(ropts, (uid_t) 0, (gid_t) 0, (mode_t) 0555); - isoburn_ropt_set_input_charset(ropts, xorriso->in_charset); - isoburn_ropt_set_auto_incharset(ropts, !!(xorriso->do_aaip & 512)); - - Xorriso_set_image_severities(xorriso, 1); /* No DEBUG messages */ - Xorriso_pacifier_reset(xorriso, 0); - isoburn_set_read_pacifier(drive, Xorriso__read_pacifier, (void *) xorriso); - - /* <<< Trying to work around too much tolerance on bad image trees. - Better would be a chance to instruct libisofs what to do in - case of image read errors. There is a risk to mistake other SORRYs. - */ - if(xorriso->img_read_error_mode>0) - iso_set_abort_severity("SORRY"); - - if(state != BURN_DISC_BLANK) { - ret= isoburn_disc_get_msc1(drive, &load_lba); - if(ret > 0) { - sprintf(xorriso->info_text, - "Loading ISO image tree from LBA %d", load_lba); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - } - ret= Xorriso_assert_volid(xorriso, load_lba, 0); - if(ret <= 0) - goto ex; - } - - read_ret= ret= isoburn_read_image(drive, ropts, &volset); - - /* <<< Resetting to normal thresholds */ - if(xorriso->img_read_error_mode>0) - Xorriso_set_abort_severity(xorriso, 0); - - if(ret<=0) { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_set_image_severities(xorriso, 0); - Xorriso_give_up_drive(xorriso, 1|((flag&32)>>2)); - sprintf(xorriso->info_text,"Cannot read ISO image tree"); - sev= "FAILURE"; - if(xorriso->img_read_error_mode==2) - sev= "FATAL"; - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, sev, 0); - if(read_ret == ISO_SB_TREE_CORRUPTED && (xorriso->do_md5 & 1)) { - Xorriso_msgs_submit(xorriso, 0, - "You might get a questionable ISO image tree by option -md5 'off'.", - 0, "HINT", 0); - } else if(xorriso->img_read_error_mode!=0) { - Xorriso_msgs_submit(xorriso, 0, "You might get a partial or altered ISO image tree by option -error_behavior 'image_loading' 'best_effort' if -abort_on is set to be tolerant enough.", - 0, "HINT", 0); - } - - - ret= 3; goto ex; - } - Xorriso_pacifier_callback(xorriso, "nodes read", xorriso->pacifier_count, 0, - "", 1); /* report end count */ - xorriso->in_volset_handle= (void *) volset; - xorriso->in_sector_map= NULL; - Xorriso_set_image_severities(xorriso, 0); - - Xorriso_update_volid(xorriso, 0); - strncpy(xorriso->application_id, - un0(iso_image_get_application_id(volset)), 128); - xorriso->application_id[128]= 0; - strncpy(xorriso->publisher, un0(iso_image_get_publisher_id(volset)), 128); - xorriso->publisher[128]= 0; - strncpy(xorriso->system_id, un0(iso_image_get_system_id(volset)), 32); - xorriso->system_id[32]= 0; - strncpy(xorriso->volset_id, un0(iso_image_get_volset_id(volset)), 128); - xorriso->volset_id[128]= 0; - - /* <<< can be removed as soon as libisofs-0.6.24 is mandatory - */ - if(strcmp(un0(iso_image_get_copyright_file_id(volset)), "_") == 0 && - strcmp(un0(iso_image_get_abstract_file_id(volset)), "_") == 0 && - strcmp(un0(iso_image_get_biblio_file_id(volset)), "_") == 0) { - /* This is bug output from libisofs <= 0.6.23 . The texts mean file names - and should have been empty to indicate that there are no such files. - It is obvious that not all three roles can be fulfilled by one file "_" - so that one cannot spoil anything by assuming them empty now. - Modern versions of libisofs are supposed to do this themselves. - */ - iso_image_set_copyright_file_id(volset, ""); - iso_image_set_abstract_file_id(volset, ""); - iso_image_set_biblio_file_id(volset, ""); - } - - if(xorriso->out_drive_handle != NULL && - xorriso->out_drive_handle != xorriso->in_drive_handle) { - ret= Xorriso_get_drive_handles(xorriso, &out_dinfo, &out_drive, - "on attempt to attach ISO image volset to outdev", 2); - if(ret<=0) - goto ex; - iso_image_ref((IsoImage *) xorriso->in_volset_handle); - isoburn_attach_image(out_drive, xorriso->in_volset_handle); - } - Xorriso_process_msg_queues(xorriso,0); - isoburn_ropt_get_size_what(ropts, &size, &has_what); - if(has_what & isoburn_ropt_has_el_torito) { - if(xorriso->boot_image_bin_path[0]) - boot_fate= "replaced by new boot image"; - else if(xorriso->patch_isolinux_image & 1) - boot_fate= "patched at boot info table"; - else if(xorriso->keep_boot_image) - boot_fate= "kept unchanged"; - else - boot_fate= "discarded"; - sprintf(xorriso->info_text, - "Detected El-Torito boot information which currently is set to be %s", - boot_fate); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - Xorriso_record_boot_info(xorriso, 0); - } - - if(flag & 1) { - /* Look for isofs.st and put it into xorriso->isofs_st_in */; - root_node= (IsoNode *) iso_image_get_root(volset); - ret= iso_node_lookup_attr(root_node, "isofs.st", &value_length, &value, 0); - if(ret > 0) { - if(value_length > 0) { - sscanf(value, "%lf", &num); - if(num > 0) - xorriso->isofs_st_in= num; - } - free(value); - } - } - - if(!(flag&32)) { - Xorriso_toc(xorriso, 1 | 8); - if(xorriso->loaded_volid[0]!=0) { - sprintf(xorriso->info_text,"Volume id : '%s'\n", - xorriso->loaded_volid); - Xorriso_info(xorriso, 0); - if(strcmp(xorriso->loaded_volid, xorriso->volid) != 0 && - !xorriso->volid_default) { - sprintf(xorriso->info_text, "New volume id: '%s'\n", xorriso->volid); - Xorriso_info(xorriso, 0); - } - } - } - - ret= 1+not_writeable; -ex: - Xorriso_process_msg_queues(xorriso,0); - if(ret<=0) { - hret= Xorriso_give_up_drive(xorriso, (flag&3)|((flag&32)>>2)); - if(hretdo_calm_drive & 1) && !(flag & 64)) - burn_drive_snooze(drive, 0); /* No need to make noise from start */ - } - if(ropts!=NULL) - isoburn_ropt_destroy(&ropts, 0); - return(ret); -} - - -/* @param flag bit0=input drive - bit1=output drive - bit2=eject - bit3=no info message or toc -*/ -int Xorriso_give_up_drive(struct XorrisO *xorriso, int flag) -{ - int in_is_out_too, ret, do_eject; - struct burn_drive_info *dinfo; - struct burn_drive *drive; - char sfe[5*SfileadrL]; - - in_is_out_too= (xorriso->in_drive_handle == xorriso->out_drive_handle); - if((flag&4) && in_is_out_too && (flag&(1|2))) { - if((flag&3)!=3) { - sprintf(xorriso->info_text,"Giving up for -eject whole -dev %s", - Text_shellsafe(xorriso->indev, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - } - flag|= 3; /* give up in/out drive to eject it */ - } - - if((flag&1) && xorriso->in_drive_handle != NULL) { - Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to give up drive", 0); - - if(!in_is_out_too) { - do_eject= !!(flag&4); - if((flag & 4) && !xorriso->indev_is_exclusive) { - sprintf(xorriso->info_text, - "Will not eject media in non-exclusively aquired input drive."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - do_eject= 0; - } - if(drive!=NULL) - isoburn_drive_release(drive, do_eject); - if(dinfo!=NULL) - burn_drive_info_free(dinfo); - } - xorriso->in_drive_handle= NULL; - xorriso->indev[0]= 0; - - 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->isofs_st_out= time(0) - 1; - xorriso->isofs_st_in= 0; - xorriso->volset_change_pending= 0; - xorriso->no_volset_present= 0; - xorriso->loaded_boot_bin_lba= 0; - xorriso->loaded_boot_cat_path[0]= 0; - xorriso->boot_count= 0; - in_is_out_too= 0; - } - if((flag&2) && xorriso->out_drive_handle!=NULL) { - do_eject= !!(flag&4); - if((flag & 4) && !xorriso->outdev_is_exclusive) { - sprintf(xorriso->info_text, - "Will not eject media in non-exclusively aquired drive."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - do_eject= 0; - } - Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to give up drive", 2); - if(!in_is_out_too) { - if(drive!=NULL) - isoburn_drive_release(drive, do_eject); - if(dinfo!=NULL) - burn_drive_info_free(dinfo); - } - xorriso->out_drive_handle= NULL; - xorriso->outdev[0]= 0; - } else if((flag&1) && xorriso->out_drive_handle!=NULL) { - ret= Xorriso_create_empty_iso(xorriso, 0); - if(ret<=0) - return(ret); - if(!(flag&8)) { - sprintf(xorriso->info_text, - "Only the output drive remains. Created empty ISO image.\n"); - Xorriso_info(xorriso, 0); - Xorriso_toc(xorriso, 1 | 2 | 8); - } - } - Xorriso_process_msg_queues(xorriso,0); - return(1); -} - - -int Xorriso_make_write_options( - struct XorrisO *xorriso, struct burn_drive *drive, - struct burn_write_opts **burn_options, int flag) -{ - int drive_role, stream_mode= 0; - - *burn_options= burn_write_opts_new(drive); - if(*burn_options==NULL) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text,"Cannot allocate option set"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - burn_write_opts_set_simulate(*burn_options, !!xorriso->do_dummy); - drive_role= burn_drive_get_drive_role(drive); - burn_write_opts_set_multi(*burn_options, - !(xorriso->do_close || drive_role==0 || drive_role==3)); - burn_drive_set_speed(drive, xorriso->speed, xorriso->speed); - if(xorriso->do_stream_recording == 1) - stream_mode= 1; - else if(xorriso->do_stream_recording == 2) - stream_mode= 51200; /* 100 MB */ - else if(xorriso->do_stream_recording >= 16) - stream_mode= xorriso->do_stream_recording; - burn_write_opts_set_stream_recording(*burn_options, stream_mode); - -#ifdef Xorriso_dvd_obs_default_64K - if(xorriso->dvd_obs == 0) - burn_write_opts_set_dvd_obs(*burn_options, 64 * 1024); - else -#endif - burn_write_opts_set_dvd_obs(*burn_options, xorriso->dvd_obs); - - burn_write_opts_set_stdio_fsync(*burn_options, xorriso->stdio_sync); - burn_write_opts_set_underrun_proof(*burn_options, 1); - return(1); -} - - -/* @param flag bit0= do not write but only prepare and return size in sectors - bit1= do not use isoburn wrappers -*/ -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 ret, img_sectors, num_sessions= 0, num_tracks= 0, padding= 0, profile; - int media_space, lba, nwa; - char profile_name[80]; - struct burn_session **sessions; - struct burn_track **tracks; - - img_sectors= burn_disc_get_sectors(disc); - - sessions= burn_disc_get_sessions(disc, &num_sessions); - if(sessions==NULL || num_sessions < 1) { -no_track:; - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text,"Program error : no track in prepared disc"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - {ret= -1; goto ex;} - } - tracks= burn_session_get_tracks(sessions[0], &num_tracks); - if(tracks==NULL || num_tracks < 1) - goto no_track; - - padding= 0; - ret= burn_disc_get_profile(drive, &profile, profile_name); - padding= xorriso->padding / 2048; - if(xorriso->padding > padding * 2048) - padding++; - if(img_sectors>0 && ret>0 && - (profile==0x09 || profile==0x0a)) { /* CD-R , CD-RW */ - if(img_sectors + padding < Xorriso_cd_min_track_sizE) { - padding= Xorriso_cd_min_track_sizE - img_sectors; - sprintf(xorriso->info_text, - "Expanded track to minimum size of %d sectors", - Xorriso_cd_min_track_sizE); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - } - } - if(xorriso->alignment == 0) { - ret= isoburn_needs_emulation(drive); - if(ret > 0) { - /* Take care that the session is padded up to the future NWA. - Else with padding < 32 it could happen that PVDs from older - sessions survive and confuse -rom_toc_scan. - */ - xorriso->alignment= 32; - } - } - if(xorriso->alignment > 0) { - if(img_sectors > 0) { - ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &lba, &nwa); - if(ret <= 0) - nwa= 0; - lba= (nwa + img_sectors + padding) % xorriso->alignment; - if(lba > 0) - padding+= xorriso->alignment - lba; - } else if(padding < xorriso->alignment) - padding= xorriso->alignment; - } - burn_track_define_data(tracks[0], 0, padding * 2048, 0, BURN_MODE1); - Xorriso_process_msg_queues(xorriso,0); - - if(flag&2) - media_space= burn_disc_available_space(drive, burn_options) / - (off_t) 2048; - else - media_space= isoburn_disc_available_space(drive, burn_options) / - (off_t) 2048; - if(media_space < img_sectors + padding) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text,"Image size %ds exceeds free space on media %ds", - img_sectors + padding, media_space); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - if(flag&1) { - ret= img_sectors+padding; - } else - ret= 1; -ex:; - 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); -} - - -/* @param flag bit0= operating on newly attached boot image -*/ -int Xorriso_set_isolinux_options(struct XorrisO *xorriso, - IsoImage *image, int flag) -{ - int make_isohybrid_mbr= 0, ret, patch_table= 0, num_boots, i; - ElToritoBootImage *bootimg, **boots = NULL; - IsoFile *bootimg_node, **bootnodes = NULL; - - ret= iso_image_get_boot_image(image, &bootimg, &bootimg_node, NULL); - Xorriso_process_msg_queues(xorriso,0); - if(ret != 1) { - sprintf(xorriso->info_text, "Programming error: No boot image available in Xorriso_set_isolinux_options()"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - ret= -1; goto ex; - } - ret= iso_image_get_all_boot_imgs(image, &num_boots, &boots, &bootnodes, 0); - Xorriso_process_msg_queues(xorriso,0); - if(ret != 1) { - Xorriso_report_iso_error(xorriso, "", ret, "Cannot inquire boot images", 0, - "FATAL", 1); - ret= -1; goto ex; - } - patch_table= xorriso->patch_isolinux_image & 1; - if((flag & 1) && num_boots > 1) { - ret= el_torito_set_isolinux_options(boots[num_boots - 1], patch_table, 0); - ret= (ret == 1); goto ex; - } - - /* Handle patching of first attached boot image or of imported boot images - */ - for(i= 0; i < num_boots; i++) { - patch_table = xorriso->patch_isolinux_image & 1; - if(patch_table && !(flag & 1)) { - if(!el_torito_seems_boot_info_table(boots[i], 0)) - patch_table= 0; - else if((xorriso->patch_isolinux_image & 2) && - el_torito_get_boot_platform_id(boots[i]) == 0xef) - patch_table= 0; - } - if(i > 0 || xorriso->boot_image_isohybrid == 0) { - ret= el_torito_set_isolinux_options(boots[i], patch_table, 0); - if(ret != 1) - {ret= 0; goto ex;} - continue; - } - if(xorriso->boot_image_isohybrid == 3) { - make_isohybrid_mbr= 1; - } else { - ret= Xorriso_is_isohybrid(xorriso, bootimg_node, 0); - if(ret < 0) - {ret= 0; goto ex;} - if(ret > 0) - make_isohybrid_mbr= 1; - } - - if(xorriso->boot_image_isohybrid == 2 && !make_isohybrid_mbr) { - sprintf(xorriso->info_text, - "Isohybrid signature is demanded but not found in boot image file."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - if(make_isohybrid_mbr) { - sprintf(xorriso->info_text, "Will write isohybrid MBR."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - xorriso->alignment= 512; - } - ret= el_torito_set_isolinux_options(bootimg, - patch_table | (make_isohybrid_mbr << 1),0); - if(ret != 1) - {ret= 0; goto ex;} - } -ex: - Xorriso_process_msg_queues(xorriso,0); - if(boots != NULL) - free(boots); - if(bootnodes != NULL) - free(bootnodes); - return(ret); -} - - -int Xorriso_auto_format(struct XorrisO *xorriso, int flag) -{ - int ret, profile, status, num_formats; - char profile_name[80]; - struct burn_drive_info *dinfo; - struct burn_drive *drive; - off_t size; - unsigned dummy; - - ret= Xorriso_may_burn(xorriso, 0); - if(ret <= 0) - return(0); - - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to autoformat", 2); - if(ret<=0) - return(0); - ret= burn_disc_get_profile(drive, &profile, profile_name); - if(ret>0 && (profile==0x12 || profile==0x43)) { /* DVD-RAM or BD-RE */ - ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats); - if(ret>0 && status==BURN_FORMAT_IS_UNFORMATTED) { - sprintf(xorriso->info_text, - "Unformatted %s media detected. Trying -format fast.", - profile_name); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - ret= Xorriso_format_media(xorriso, (off_t) 0, 1 | 4); - if(ret<=0) { - sprintf(xorriso->info_text, "Automatic formatting of %s failed", - profile_name); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(ret); - } - } - } - return(1); -} - - -int Xorriso_set_system_area(struct XorrisO *xorriso, struct burn_drive *drive, - IsoImage *img, struct isoburn_imgen_opts *sopts, - int flag) -{ - int ret, options, system_area_options, iso_lba= -1, start_lba, image_blocks; - char volid[33]; - FILE *fp= NULL; - char buf[32768], *bufpt= NULL; - off_t hd_lba; - unsigned char *ub; - ElToritoBootImage *bootimg; - IsoFile *bootimg_node; - - system_area_options= xorriso->system_area_options; - memset(buf, 0, 32768); - if(xorriso->system_area_disk_path[0] == 0) { - if(xorriso->patch_system_area) { - ret= iso_image_get_system_area(img, buf, &options, 0); - if(ret == 0) { - goto do_set; - } else if(ret < 0) { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_report_iso_error(xorriso, "", ret, - "Error when inquiring System Area data of ISO 9660 image", - 0, "FAILURE", 1); - {ret= 0; goto ex;} - } else { - system_area_options= xorriso->patch_system_area; - /* Check whether partition 1 ends at image end */; - ub= (unsigned char *) buf; - hd_lba= (ub[454] | (ub[455] << 8) | (ub[456] << 16) | (ub[457] << 24)) + - (ub[458] | (ub[459] << 8) | (ub[460] << 16) | (ub[461] << 24)); - - iso_lba= -1; - ret= isoburn_disc_get_msc1(drive, &start_lba); - if(ret > 0) { - ret= isoburn_read_iso_head(drive, start_lba, &image_blocks, - volid, 1); - if(ret > 0) - iso_lba= start_lba + image_blocks; - } - if(((off_t) iso_lba) * (off_t) 4 > hd_lba) { - system_area_options= 0; - } else if((xorriso->patch_system_area & 1) && - ((off_t) iso_lba) * (off_t) 4 != hd_lba) { - system_area_options= 0; - } else if((xorriso->patch_system_area & 2) && - ((off_t) iso_lba) * (off_t) 4 + (off_t) (63 * 256) < hd_lba) { - system_area_options= 0; - } else if(xorriso->patch_system_area & 2) { /* isohybrid patching */ - /* Check whether bytes 432-345 point to ElTorito LBA */ - hd_lba= ub[432] | (ub[433] << 8) | (ub[434] << 16) | (ub[435] << 24); - ret= iso_image_get_boot_image(img, &bootimg, &bootimg_node, NULL); - if(ret != 1) - system_area_options= 0; - else if(bootimg_node != NULL) { - Xorriso__file_start_lba((IsoNode *) bootimg_node, &(iso_lba), 0); - if(((off_t) iso_lba) * (off_t) 4 != hd_lba) - system_area_options= 0; - } - } - if(system_area_options == 0) { - Xorriso_msgs_submit(xorriso, 0, - "Loaded System Area data are not suitable for MBR patching.", - 0, "DEBUG", 0); - } - } - bufpt= buf; - ret= 1; - } else - ret= 0; - goto do_set; - } - if(strcmp(xorriso->system_area_disk_path, "/dev/zero") == 0) - {ret= 1; goto do_set;} - - ret= Xorriso_afile_fopen(xorriso, xorriso->system_area_disk_path, - "rb", &fp, 2); - if(ret <= 0) - {ret= 0; goto ex;} - ret= fread(buf, 1, 32768, fp); - if(ret < 32768) { - if(ferror(fp)) { - sprintf(xorriso->info_text, - "Error when reading -boot_image system_area="); - Text_shellsafe(xorriso->system_area_disk_path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - {ret= 0; goto ex;} - } - } - bufpt= buf; - -do_set:; - if(ret > 0 && xorriso->system_area_disk_path[0]) { - sprintf(xorriso->info_text, "Copying to System Area: %d bytes from file ", - ret); - Text_shellsafe(xorriso->system_area_disk_path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - } - ret= isoburn_igopt_set_system_area(sopts, bufpt, system_area_options); - if(ret != ISO_SUCCESS) { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_report_iso_error(xorriso, "", ret, - "Error when attaching System Area data to ISO 9660 image", - 0, "FAILURE", 1); - {ret= 0; goto ex;} - } - ret= 1; -ex:; - if(fp != NULL && fp != stdin) - fclose(fp); - return(ret); -} - - -/* - 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); -} - - -/* @param flag bit0= do not increment boot_count - and do not reset boot parameters - bit1= dispose attached boot images -*/ -int Xorriso_attach_boot_image(struct XorrisO *xorriso, int flag) -{ - int ret; - char sfe[5*SfileadrL], *cpt; - struct burn_drive_info *source_dinfo; - struct burn_drive *source_drive; - IsoImage *image= NULL; - IsoNode *node; - ElToritoBootImage *bootimg; - enum eltorito_boot_media_type emul_type= ELTORITO_NO_EMUL; - char *bin_path; - int emul, platform_id; - off_t load_size; - struct stat stbuf; - int hflag= 0; - - if(xorriso->boot_image_bin_path[0] == 0 && !(flag & 2)) { - - /* >>> no boot image path given : no op */; - - ret= 2; goto ex; - } - - if(xorriso->in_drive_handle == NULL) - hflag= 2; - ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive, - "on attempt to attach boot image", hflag); - if(ret<=0) - goto ex; - image= isoburn_get_attached_image(source_drive); - if(image == NULL) { - /* (should not happen) */ - sprintf(xorriso->info_text, - "No ISO image present on attempt to attach boot image"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - if(flag & 2) { - iso_image_remove_boot_image(image); - xorriso->boot_count= 0; - ret= 1; goto ex; - } - - bin_path= xorriso->boot_image_bin_path; - emul= xorriso->boot_image_emul; - platform_id= xorriso->boot_platform_id; - load_size= xorriso->boot_image_load_size; - - if(xorriso->boot_efi_default) { - emul= 0; - platform_id= 0xef; - xorriso->patch_isolinux_image= 0; - } - if(platform_id == 0xef || load_size < 0) { - ret= Xorriso_iso_lstat(xorriso, bin_path, &stbuf, 2 | 4); - if(ret != 0) - {ret= 0; goto ex;} - load_size= ((stbuf.st_size / (off_t) 512) + - !!(stbuf.st_size % (off_t) 512)) * 512; - } - sprintf(xorriso->info_text, "Adding boot image %s", - Text_shellsafe(bin_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - - if(emul == 0) - emul_type= ELTORITO_NO_EMUL; - else if(emul == 1) - emul_type= ELTORITO_HARD_DISC_EMUL; - else if(emul == 2) - emul_type= ELTORITO_FLOPPY_EMUL; - - ret= Xorriso_node_from_path(xorriso, image, bin_path, &node, 1); - if(ret <= 0) { - sprintf(xorriso->info_text, - "Cannot find in ISO image: -boot_image ... bin_path=%s", - Text_shellsafe(bin_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - - if(xorriso->boot_count == 0) { - if(xorriso->boot_image_cat_path[0] == 0) { - strcpy(xorriso->boot_image_cat_path, bin_path); - cpt= strrchr(xorriso->boot_image_cat_path, '/'); - if(cpt == NULL) - cpt= xorriso->boot_image_cat_path; - else - cpt++; - strcpy(cpt, "boot.cat"); - } - ret= Xorriso_node_from_path(xorriso, image, xorriso->boot_image_cat_path, - &node, 1); - if(ret > 0) { - if(!xorriso->do_overwrite) { - sprintf(xorriso->info_text, - "May not overwite existing -boot_image ... cat_path=%s", - Text_shellsafe(xorriso->boot_image_cat_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, xorriso->boot_image_cat_path, - 8 | (xorriso->do_overwrite == 1)); - if(ret != 1) { - sprintf(xorriso->info_text, - "Could not remove existing -boot_image cat_path=%s", - Text_shellsafe(xorriso->boot_image_cat_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - } - - /* Discard old boot image, set new one */ - ret= iso_image_get_boot_image(image, &bootimg, NULL, NULL); - if(ret == 1) - iso_image_remove_boot_image(image); - ret= iso_image_set_boot_image(image, bin_path, emul_type, - xorriso->boot_image_cat_path, &bootimg); - if(ret > 0) - iso_image_set_boot_catalog_weight(image, 1000000000); - } else { - ret= iso_image_add_boot_image(image, bin_path, emul_type, 0, &bootimg); - } - if(ret < 0) { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_report_iso_error(xorriso, "", ret, - "Error when attaching El-Torito boot image to ISO 9660 image", - 0, "FAILURE", 1); - sprintf(xorriso->info_text, - "Could not attach El-Torito boot image to ISO 9660 image"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - el_torito_set_boot_platform_id(bootimg, (uint8_t) platform_id); - el_torito_set_load_size(bootimg, load_size / 512); - el_torito_set_id_string(bootimg, xorriso->boot_id_string); - el_torito_set_selection_crit(bootimg, xorriso->boot_selection_crit); - ret= Xorriso_set_isolinux_options(xorriso, image, 1); - if(!(flag & 1)) { - /* Register attachment and reset even in case of error return */ - xorriso->boot_count++; - xorriso->boot_platform_id= 0; - xorriso->patch_isolinux_image= 0; - xorriso->boot_image_bin_path[0]= 0; - xorriso->boot_image_bin_form[0]= 0; - xorriso->boot_image_emul= 0; - xorriso->boot_image_load_size= 4 * 512; - memset(xorriso->boot_id_string, 0, sizeof(xorriso->boot_id_string)); - memset(xorriso->boot_selection_crit, 0, - sizeof(xorriso->boot_selection_crit)); - xorriso->boot_efi_default= 0; - } - if(ret <= 0) - goto ex; - - ret= 1; -ex:; - if(image != NULL) - iso_image_unref(image); - return(ret); -} - - -/* #define Xorriso_boot_dummY 1 */ - - -/* @param flag bit0= do not write but only prepare and return size in sectors -*/ -int Xorriso_write_session(struct XorrisO *xorriso, int flag) -{ - int ret, relax= 0, i, pacifier_speed= 0, data_lba, ext, is_bootable= 0; - int major, minor, micro; - char xorriso_id[256], *img_id, sfe[5*SfileadrL], *out_cs; - struct isoburn_imgen_opts *sopts= NULL; - struct burn_drive_info *dinfo, *source_dinfo; - struct burn_drive *drive, *source_drive; - struct burn_disc *disc= NULL; - struct burn_write_opts *burn_options; - off_t readcounter= 0,writecounter= 0; - int num_sessions= 0, num_tracks= 0; - struct burn_session **sessions; - struct burn_track **tracks; - enum burn_disc_status s; - IsoImage *image= NULL; - IsoNode *root_node; - int profile_number; - char profile_name[80]; - IsoBoot *bootcat_node; - - ret= Xorriso_finish_hl_update(xorriso, 0); - if(ret <= 0) - return(ret); - - out_cs= xorriso->out_charset; - if(out_cs == NULL) - Xorriso_get_local_charset(xorriso, &out_cs, 0); - - if(!(flag & 1)) { - ret= Xorriso_auto_format(xorriso, 0); - if(ret <=0 ) - return(0); - } - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to write", 2); - if(ret<=0) - return(0); - if(xorriso->out_drive_handle == xorriso->in_drive_handle) { - source_drive= drive; - } else { - if(xorriso->in_drive_handle == NULL) { - source_drive= drive; - } else { - ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive, - "on attempt to get source for write", 0); - if(ret<=0) - goto ex; - } - s= isoburn_disc_get_status(drive); - if(s!=BURN_DISC_BLANK) { - s= burn_disc_get_status(drive); - if(s!=BURN_DISC_BLANK) - sprintf(xorriso->info_text, - "-indev differs from -outdev and -outdev media is not blank"); - else - sprintf(xorriso->info_text, - "-indev differs from -outdev and -outdev media holds non-zero data"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - } - ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2); - if(ret == 2) - pacifier_speed= 1; - else if(ret == 3) - pacifier_speed= 2; - - ret= isoburn_igopt_new(&sopts, 0); - if(ret<=0) { - Xorriso_process_msg_queues(xorriso, 0); - goto ex; - } - relax= xorriso->relax_compliance; - - xorriso->alignment= 0; - image= isoburn_get_attached_image(source_drive); - if(image != NULL) { - iso_image_set_application_id(image, xorriso->application_id); - iso_image_set_publisher_id(image, xorriso->publisher); - iso_image_set_system_id(image, xorriso->system_id); - iso_image_set_volset_id(image, xorriso->volset_id); - } - - if((xorriso->do_aaip & 256) && out_cs != NULL) { - static char *names = "isofs.cs"; - size_t value_lengths[1]; - - value_lengths[0]= strlen(out_cs); - ret= Xorriso_setfattr(xorriso, NULL, "/", - (size_t) 1, &names, value_lengths, &out_cs, 2 | 8); - if(ret<=0) - goto ex; - } - - ret= Xorriso_set_system_area(xorriso, source_drive, image, sopts, 0); - if(ret <= 0) - goto ex; - - /* Activate, adjust or discard boot image */ - if(image!=NULL && !(flag&1)) { - is_bootable= iso_image_get_boot_image(image, NULL, NULL, &bootcat_node); - if(xorriso->boot_image_bin_path[0]) { - ret= Xorriso_attach_boot_image(xorriso, xorriso->boot_count == 0); - if(ret <= 0) - goto ex; - } - if(xorriso->boot_count > 0) { - /* Eventually rename boot catalog node to changed boot_image_cat_path */ - if(is_bootable > 0) { - ret= Xorriso_path_from_node(xorriso, (IsoNode *) bootcat_node, sfe, 0); - if(ret > 0) { - if(strcmp(sfe, xorriso->boot_image_cat_path) != 0) { - ret= Xorriso_rename(xorriso, NULL, sfe, - xorriso->boot_image_cat_path, 0); - if(ret <= 0) - goto ex; - } - } - } - } else if(xorriso->patch_isolinux_image & 1) { - if(is_bootable == 1) { - relax|= isoburn_igopt_allow_full_ascii; - sprintf(xorriso->info_text, "Patching boot info table"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - - ret= Xorriso_path_from_lba(xorriso, NULL, xorriso->loaded_boot_bin_lba, - sfe, 1); - if(ret < 0) - goto ex; - if(ret == 0) { - sprintf(xorriso->info_text, - "Cannot patch boot image: no file found for its LBA."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - sprintf(xorriso->info_text, - "Probably the loaded boot image file was deleted in this session."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - sprintf(xorriso->info_text, - "Use -boot_image \"any\" \"discard\" or set new boot image"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0); - goto ex; - } - ret= Xorriso_set_isolinux_options(xorriso, image, 0); - if(ret <= 0) - goto ex; - } else { - sprintf(xorriso->info_text, - "Could not find any boot image for -boot_image patching"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - } - } else if(xorriso->keep_boot_image && is_bootable == 1) { - relax|= isoburn_igopt_allow_full_ascii; - sprintf(xorriso->info_text, "Keeping boot image unchanged"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - } else if(is_bootable == 1) { - iso_image_remove_boot_image(image); - sprintf(xorriso->info_text, "Discarded boot image from old session"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - } - } - - if((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2)) { - /* Overwrite isofs.st of root node by xorriso->isofs_st_out */ - char *name= "isofs.st"; - char timestamp[16], *value= timestamp; - size_t value_length; - - sprintf(timestamp, "%.f", (double) xorriso->isofs_st_out); - value_length= strlen(timestamp); - Xorriso_setfattr(xorriso, NULL, "/", (size_t) 1, &name, - &value_length, &value, 2 | 8); - } - - isoburn_igopt_set_level(sopts, 3); - ext= isoburn_igopt_rockridge | - ((!!xorriso->do_joliet) * isoburn_igopt_joliet) | - (( !(xorriso->ino_behavior & 2)) * isoburn_igopt_hardlinks) | - (( (!(xorriso->ino_behavior & 2)) || - (xorriso->do_aaip & (2 | 8 | 16 | 256)) || - (xorriso->do_md5 & (2 | 4)) - ) * isoburn_igopt_aaip) | - ((!!(xorriso->do_md5 & 2)) * isoburn_igopt_session_md5) | - ((!!(xorriso->do_md5 & 4)) * isoburn_igopt_file_md5) | - ((!!(xorriso->do_md5 & 8)) * isoburn_igopt_file_stability); - isoburn_igopt_set_extensions(sopts, ext); - isoburn_igopt_set_relaxed(sopts, relax); - isoburn_igopt_set_sort_files(sopts, 1); - isoburn_igopt_set_over_mode(sopts, 0, 0, (mode_t) 0, (mode_t) 0); - isoburn_igopt_set_over_ugid(sopts, 0, 0, (uid_t) 0, (gid_t) 0); - isoburn_igopt_set_out_charset(sopts, out_cs); - isoburn_igopt_set_fifo_size(sopts, xorriso->fs * 2048); - Ftimetxt(time(NULL), xorriso->scdbackup_tag_time, 8); - isoburn_igopt_set_scdbackup_tag(sopts, xorriso->scdbackup_tag_name, - xorriso->scdbackup_tag_time, - xorriso->scdbackup_tag_written); - if(image!=NULL && - strlen(Xorriso_program_versioN)+strlen(Xorriso_timestamP)<80) { - sprintf(xorriso_id, "XORRISO-%s %s", - Xorriso_program_versioN, Xorriso_timestamP); - isoburn_version(&major, &minor, µ); - if(strlen(xorriso_id)<80) - sprintf(xorriso_id+strlen(xorriso_id), - ", LIBISOBURN-%d.%d.%d", major, minor, micro); - iso_lib_version(&major, &minor, µ); - if(strlen(xorriso_id)<80) - sprintf(xorriso_id+strlen(xorriso_id), - ", LIBISOFS-%d.%d.%d", major, minor, micro); - burn_version(&major, &minor, µ); - if(strlen(xorriso_id)<80) - sprintf(xorriso_id+strlen(xorriso_id), - ", LIBBURN-%d.%d.%d", major, minor, micro); - xorriso_id[128]= 0; - img_id= (char *) iso_image_get_data_preparer_id(image); - if(img_id!=NULL) { - for(i= strlen(img_id)-1; i>=0 && img_id[i]==' '; i--); - if(i>0) { - sprintf(xorriso->info_text, "Overwrote previous preparer id '%s'", - img_id); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - } - } - iso_image_set_data_preparer_id(image, xorriso_id); - } - isoburn_igopt_set_pvd_times(sopts, - xorriso->vol_creation_time, xorriso->vol_modification_time, - xorriso->vol_expiration_time, xorriso->vol_effective_time, - xorriso->vol_uuid); - - /* Make final abort check before starting expensive activities */ - ret= Xorriso_eval_problem_status(xorriso, 1, 0); - if(ret<0) - {ret= 0; goto ex;} - - if(xorriso->zisofs_by_magic) { - sprintf(xorriso->info_text, - "Checking disk file content for zisofs compression headers."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0); - root_node= (IsoNode *) iso_image_get_root(image); - ret= iso_node_zf_by_magic(root_node, - (xorriso->out_drive_handle == xorriso->in_drive_handle) | 2 | 16); - if(ret<0) { - Xorriso_report_iso_error(xorriso, "", ret, - "Error when examining file content for zisofs headers", - 0, "FAILURE", 1); - } - ret= Xorriso_eval_problem_status(xorriso, 1, 0); - if(ret<0) - {ret= 0; goto ex;} - sprintf(xorriso->info_text, - "Check for zisofs compression headers done."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0); - } - - /* >>> omit iso_image_update_sizes if the image was filled up very quickly */; - - ret= iso_image_update_sizes(image); - if(ret < 0) { - Xorriso_process_msg_queues(xorriso, 0); - if(ret<0) { - Xorriso_report_iso_error(xorriso, "", ret, - "Error when updating file sizes", - 0, "FAILURE", 1); - } - ret= Xorriso_eval_problem_status(xorriso, 1, 0); - if(ret<0) - {ret= 0; goto ex;} - } - - Xorriso_set_abort_severity(xorriso, 1); - if (xorriso->grow_blindly_msc2 >= 0 && - xorriso->out_drive_handle != xorriso->in_drive_handle) { - ret= isoburn_prepare_blind_grow(source_drive, &disc, sopts, drive, - xorriso->grow_blindly_msc2); - if(ret>0) { - /* Allow the consumer of output to access the input drive */ - source_drive= NULL; - ret= Xorriso_give_up_drive(xorriso, 1|8); - if(ret<=0) - goto ex; - } - } else if(xorriso->out_drive_handle == xorriso->in_drive_handle || - xorriso->in_drive_handle == NULL) { - ret= isoburn_prepare_disc(source_drive, &disc, sopts); - } else { - ret= isoburn_prepare_new_image(source_drive, &disc, sopts, drive); - } - if(ret <= 0) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text,"Failed to prepare session write run"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - - ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0); - if(ret<=0) - goto ex; - isoburn_igopt_get_effective_lba(sopts, &(xorriso->session_lba)); - if(xorriso->do_stream_recording == 2) { - ret= isoburn_igopt_get_data_start(sopts, &data_lba); - if(ret > 0 && data_lba >= 16) - burn_write_opts_set_stream_recording(burn_options, data_lba); - } - - ret= Xorriso_sanitize_image_size(xorriso, drive, disc, burn_options, flag&1); - if(ret<=0 || (flag&1)) { - Xorriso_process_msg_queues(xorriso,0); - if(flag&1) /* set queue severity to FAILURE */ - Xorriso_set_image_severities(xorriso, 2); - isoburn_cancel_prepared_write(source_drive, drive, 0); - if(flag&1) /* reset queue severity */ - Xorriso_set_image_severities(xorriso, 0); - goto ex; - } - - ret= Xorriso_may_burn(xorriso, 0); - if(ret <= 0) - goto ex; - - /* Important: do not return until burn_is_aborting() was checked */ - Xorriso_set_signal_handling(xorriso, 1); - - xorriso->run_state= 1; /* Indicate that burning has started */ - isoburn_disc_write(burn_options, disc); - burn_write_opts_free(burn_options); - - ret= Xorriso_pacifier_loop(xorriso, drive, pacifier_speed << 4); - if(burn_is_aborting(0)) - Xorriso_abort(xorriso, 0); /* Never comes back */ - Xorriso_set_signal_handling(xorriso, 0); - if(ret<=0) - goto ex; - if(!isoburn_drive_wrote_well(drive)) { - isoburn_cancel_prepared_write(source_drive, drive, 0); - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, - "libburn indicates failure with writing."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - - sessions= burn_disc_get_sessions(disc, &num_sessions); - if(num_sessions>0) { - tracks= burn_session_get_tracks(sessions[0], &num_tracks); - if(tracks!=NULL && num_tracks>0) { - burn_track_get_counters(tracks[0],&readcounter,&writecounter); - xorriso->session_blocks= (int) (writecounter/ (off_t) 2048); - sprintf(xorriso->info_text, - "ISO image produced: %d sectors\nWritten to media : %d sectors at LBA %d\n", - (int) (readcounter/ (off_t) 2048), - xorriso->session_blocks, xorriso->session_lba); - Xorriso_info(xorriso, 0); - } - } - ret= isoburn_activate_session(drive); - Xorriso_process_msg_queues(xorriso,0); - if(ret<=0) { - sprintf(xorriso->info_text, - "Could not write new set of volume descriptors"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - goto ex; - } - /* Done early to free any reference to the libisofs resources via disc */ - if(disc!=NULL) - burn_disc_free(disc); - disc= NULL; - /* To wait for the end of the libisofs threads and their messages. */ - isoburn_sync_after_write(source_drive, drive, 0); - Xorriso_process_msg_queues(xorriso,0); - - sprintf(xorriso->info_text, "Writing to %s completed sucessfully.\n\n", - Text_shellsafe(xorriso->outdev,sfe,0)); - Xorriso_info(xorriso, 0); - ret= 1; -ex:; - xorriso->run_state= 0; /* Indicate that burning has ended */ - Xorriso_set_abort_severity(xorriso, 0); - - if(ret<=0) { - - /* >>> ??? revive discarded boot image */; - - } - if(disc!=NULL) - burn_disc_free(disc); - if(image != NULL) - iso_image_unref(image); - isoburn_igopt_destroy(&sopts, 0); - Xorriso_process_msg_queues(xorriso,0); - Xorriso_append_scdbackup_record(xorriso, 0); - return(ret); -} - - -int Xorriso_check_burn_abort(struct XorrisO *xorriso, int flag) -{ - int ret; - struct burn_drive_info *dinfo; - struct burn_drive *drive; - - if(burn_is_aborting(0)) - return(2); - if(xorriso->run_state!=1) - return(0); - ret= Xorriso_eval_problem_status(xorriso, 1, 1); - if(ret>=0) - return(0); - sprintf(xorriso->info_text, - "-abort_on '%s' encountered '%s' during image writing", - xorriso->abort_on_text, xorriso->problem_status_text); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, - xorriso->problem_status_text, 0); - - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to abort burn run", 2); - if(ret<=0) - return(0); - - burn_drive_cancel(drive); - sprintf(xorriso->info_text, - "libburn has now been urged to cancel its operation"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(1); -} - - -/* This loop watches burn runs until they end. - It issues pacifying update messages to the user. - @param flag bit0-3 = emulation mode - 0= xorriso - 1= mkisofs - 2= cdrecord - bit4= report speed in CD units - bit5= report speed in BD units -*/ -int Xorriso_pacifier_loop(struct XorrisO *xorriso, struct burn_drive *drive, - int flag) -{ - int ret, size, free_bytes, i, aborting= 0, emul, buffer_fill= 50, last_sector; - struct burn_progress progress; - char *status_text, date_text[80], *speed_unit, mem_text[8]; - enum burn_drive_status drive_status; - double start_time, current_time, last_time, base_time= 0.0, base_count= 0.0; - double next_base_time= 0.0, next_base_count= 0.0, first_base_time= 0.0; - double first_base_count= 0.0, norm= 0.0, now_time, fract_offset= 0.0; - double measured_speed, speed_factor= 1385000, quot; - time_t time_prediction; - - start_time= Sfile_microtime(0); - while(burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING) - usleep(100002); - - emul= flag&15; - fract_offset= 0.2 * (double) emul - ((int) (0.2 * (double) emul)); - if(emul==0) - emul= xorriso->pacifier_style; - speed_unit= "D"; - if(flag&16) { - speed_factor= 150.0*1024; - speed_unit= "C"; - } else if(flag & 32) { - speed_factor= 4495625; - speed_unit= "B"; - } - progress.sector= 0; - current_time= Sfile_microtime(0); - measured_speed= 0.0; - while(1) { - last_time= current_time; - last_sector= progress.sector; - drive_status= burn_drive_get_status(drive, &progress); - if(drive_status == BURN_DRIVE_IDLE) - break; - current_time= Sfile_microtime(0); - if(drive_status == BURN_DRIVE_WRITING && progress.sectors > 0) { - if(current_time-last_time>0.2) - measured_speed= (progress.sector - last_sector) * 2048.0 / - (current_time - last_time); - buffer_fill= 50; - if(progress.buffer_capacity>0) - buffer_fill= (double) (progress.buffer_capacity - - progress.buffer_available) * 100.0 - / (double) progress.buffer_capacity; - if(emul==2) { - if(progress.sector<=progress.sectors) - sprintf(xorriso->info_text, "%4d of %4d MB written", - progress.sector / 512, progress.sectors / 512); - else - sprintf(xorriso->info_text, "%4d MB written", - progress.sector / 512); - - if(xorriso->pacifier_fifo!=NULL) - ret= burn_fifo_inquire_status(xorriso->pacifier_fifo, - &size, &free_bytes, &status_text); - else - ret= isoburn_get_fifo_status(drive, &size, &free_bytes, &status_text); - if(ret>0 ) - sprintf(xorriso->info_text+strlen(xorriso->info_text), - " (fifo %2d%%)", - (int) (100.0-100.0*((double) free_bytes)/(double) size)); - - sprintf(xorriso->info_text+strlen(xorriso->info_text), " [buf %3d%%]", - buffer_fill); - - if(current_time-last_time>0.2) - sprintf(xorriso->info_text+strlen(xorriso->info_text), " %4.1fx.", - measured_speed/speed_factor); - - } else if(emul == 1 && - progress.sectors > 0 && progress.sector <= progress.sectors) { - /* "37.87% done, estimate finish Tue Jul 15 18:55:07 2008" */ - - quot= ((double) progress.sector) / ((double) progress.sectors); - sprintf(xorriso->info_text, " %2.2f%% done", quot*100.0); - if(current_time - start_time >= 2 && quot > 0.0 && - (quot >= 0.02 || progress.sector >= 5*1024)) { - if(base_time == 0.0 && progress.sector >= 16*1024) { - first_base_time= base_time= next_base_time= current_time; - first_base_count= next_base_count= progress.sector; - } else if(next_base_time > 0 && current_time - next_base_time >= 10) { - base_time= next_base_time; - base_count= next_base_count; - next_base_time= current_time; - next_base_count= progress.sector; - } - if(first_base_time > 0 && - current_time - first_base_time >= 10 && - progress.sectors > first_base_count && - progress.sector > first_base_count) { - norm= (1.0 - quot); - if(norm < 0.0001) - norm= 0.0001; - quot= ((double) progress.sector - first_base_count) - / ((double) progress.sectors - first_base_count); - time_prediction= norm * (1.0 - quot) / quot - * (current_time - first_base_time); - } else { - time_prediction= (1.0 - quot) / quot * (current_time - start_time); - norm= 1.0; - } - if(base_time > 0 && - current_time - base_time >= 10 && progress.sectors > base_count) { - quot= ((double) progress.sector - base_count) - / ((double) progress.sectors - base_count); - time_prediction+= (1.0 - quot) / quot * (current_time - base_time); - norm+= 1.0; - } - time_prediction/= norm; - if(time_prediction < 30*86400 && time_prediction > 0) { - time_prediction+= current_time + 1; - Ftimetxt(time_prediction, date_text, 4); - sprintf(xorriso->info_text+strlen(xorriso->info_text), - ", estimate finish %s", date_text); - } - } - } else { - if(progress.sector<=progress.sectors) { - if(progress.sectors <= 0) - strcpy(mem_text, " 99.9"); - else - sprintf(mem_text, "%5.1f", - 100.0 * ((double) progress.sector) / ((double) progress.sectors)); - mem_text[5]= 0; - sprintf(xorriso->info_text, "Writing: %10ds %s%% ", - progress.sector, mem_text); - } else { - Sfile_scale(2048.0 * (double) progress.sector, mem_text, 5, 1e4, 1); - sprintf(xorriso->info_text, "Writing: %10ds %s ", - progress.sector, mem_text); - } - ret= isoburn_get_fifo_status(drive, &size, &free_bytes, &status_text); - if(ret>0 ) - sprintf(xorriso->info_text+strlen(xorriso->info_text), - " fifo %3d%% buf %3d%%", - (int) (100.0-100.0*((double) free_bytes)/(double) size), - buffer_fill); - if(current_time-last_time>0.2) - sprintf(xorriso->info_text+strlen(xorriso->info_text), " %5.1fx%s ", - measured_speed/speed_factor, speed_unit); - } - } else if(drive_status == BURN_DRIVE_CLOSING_SESSION || - drive_status == BURN_DRIVE_CLOSING_TRACK) - sprintf(xorriso->info_text, - "Closing track/session. Working since %.f seconds", - current_time-start_time); - else if(drive_status == BURN_DRIVE_FORMATTING) - sprintf(xorriso->info_text, "Formatting. Working since %.f seconds", - current_time-start_time); - else - sprintf(xorriso->info_text, - "Thank you for being patient. Working since %.f seconds.", - current_time-start_time); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0); - - for(i= 0; i<12; i++) { /* 2 usleeps more than supposed to be needed */ - Xorriso_process_msg_queues(xorriso, 0); - if(aborting<=0) - aborting= Xorriso_check_burn_abort(xorriso, 0); - usleep(100000); - now_time= Sfile_microtime(0); - if(((time_t) now_time) - ((time_t) current_time) >= 1 && - now_time - ((time_t) now_time) >= fract_offset) - break; - } - } - return(1); -} - - -int Xorriso__read_pacifier(IsoImage *image, IsoFileSource *filesource) -{ - struct XorrisO *xorriso; - - xorriso= (struct XorrisO *) iso_image_get_attached_data(image); - if(xorriso==NULL) - return(1); - Xorriso_process_msg_queues(xorriso,0); - xorriso->pacifier_count++; - if(xorriso->pacifier_count%10) - return(1); - Xorriso_pacifier_callback(xorriso, "nodes read", xorriso->pacifier_count, 0, - "", 0); - return(1); -} - -/* @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); -} - - -/* @param flag bit0=do not complain about non existent node */ -int Xorriso_node_from_path(struct XorrisO *xorriso, IsoImage *volume, - char *path, IsoNode **node, int flag) -{ - int ret; - char sfe[5*SfileadrL], *path_pt; - - path_pt= path; - if(path[0]==0) - path_pt= "/"; - if(volume == NULL) { - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret <= 0) - return(ret); - } - *node= NULL; - ret= iso_tree_path_to_node(volume, path_pt, node); - Xorriso_process_msg_queues(xorriso,0); - if(ret<=0 || (*node)==NULL) { - if(!(flag&1)) { - sprintf(xorriso->info_text, "Cannot find path %s in loaded ISO image", - Text_shellsafe(path_pt, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } - return(0); - } - return(1); -} - - -/* @param eff_path returns resulting effective path. - Must provide at least SfileadrL bytes of storage. - @param flag bit0= do not produce problem events (unless faulty path format) - bit1= work purely literally, do not use libisofs - bit2= (with bit1) this is an address in the disk world - bit3= return root directory as "/" and not as "" - bit4= (with bit2) determine type of disk file eff_path - and return 0 if not existing - bit5= (with bit3) this is not a parameter - bit6= insist in having an ISO image, even with bits1+2 - @return -1 = faulty path format, 0 = not found , - 1 = found simple node , 2 = found directory -*/ -int Xorriso_normalize_img_path(struct XorrisO *xorriso, char *wd, - char *img_path, char eff_path[], int flag) -{ - int ret, is_dir= 0, done= 0; - IsoImage *volume; - IsoDir *dir= NULL; - IsoNode *node= NULL; - char path[SfileadrL], *apt, *npt, sfe[5*SfileadrL], *cpt; - - if((flag&64) || !(flag&2)) { - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - return(ret); - } - - eff_path[0]= 0; - if(img_path[0]==0) { - if(flag&8) - strcpy(eff_path, "/"); - return(2); /* root directory */ - } - - apt= npt= path; - if(img_path[0]!='/') { - strcpy(path, wd); - ret= Sfile_add_to_path(path, img_path, 0); - if(ret<=0) - goto much_too_long; - } else - if(Sfile_str(path, img_path, 0)<=0) - return(-1); - - if(path[0]!='/') { - sprintf(xorriso->info_text, - "Internal error: Unresolvable relative addressing in iso_rr_path '%s'", - img_path); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FATAL", 0); - return(-1); - } else if(path[1]==0) { - if(flag&8) - strcpy(eff_path, "/"); - return(2); /* root directory */ - } - - for(npt= apt; !done; apt= npt+1) { - npt= strchr(apt, '/'); - if(npt==NULL) { - npt= apt+strlen(apt); - done= 1; - } else - *npt= 0; - if(*apt==0) { - *apt= '/'; - apt++; - if(done) - break; - continue; - } - if(strcmp(apt,".")==0) { - is_dir= 1; - continue; - } - if(strcmp(apt,"..")==0) { - if(!(flag&2)) { - node= (IsoNode *) dir; - if(node==NULL) { -bonked_root:; - sprintf(xorriso->info_text, - "Relative addressing in path exceeds root directory: %s", - Text_shellsafe(img_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(-1); - } - dir= iso_node_get_parent(node); - } - /* truncate eff_path */; - cpt= strrchr(eff_path, '/'); - if(cpt==NULL) /* ??? if not flag&2 then this is a bug */ - goto bonked_root; - *cpt= 0; - is_dir= 1; - continue; - } - ret= Sfile_add_to_path(eff_path, apt, 0); - if(ret<=0) { -much_too_long:; - sprintf(xorriso->info_text, "Effective path gets much too long (%d)", - (int) (strlen(eff_path)+strlen(apt)+1)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(-1); - } - if(!(flag&2)) { - dir= (IsoDir *) node; - ret= Xorriso_node_from_path(xorriso, volume, eff_path, &node, flag&1); - if(ret<=0) - return(0); - if(dir==NULL) /* could be false with "/dir/.." */ - dir= iso_node_get_parent(node); - is_dir= LIBISO_ISDIR(node); - } - } - if(flag&16) { - ret= Sfile_type(eff_path, - 1|(4*(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&32))) - )); - if(ret<0) - return(0); - if(ret==2) - is_dir= 1; - } - return(1+!!is_dir); -} - - -int Xorriso_get_node_by_path(struct XorrisO *xorriso, - char *in_path, char *eff_path, - IsoNode **node, int flag) -{ - int ret; - char path[SfileadrL]; - IsoImage *volume; - - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, in_path, path, 0); - if(ret<=0) - return(ret); - if(eff_path!=NULL) - strcpy(eff_path, path); - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - return(ret); - ret= Xorriso_node_from_path(xorriso, volume, path, node, 0); - if(ret<=0) - return(0); - return(1); -} - - -/* @param flag -*/ -int Xorriso_node_get_dev(struct XorrisO *xorriso, IsoNode *node, - char *path, dev_t *dev, int flag) -{ - *dev= iso_special_get_dev((IsoSpecial *) node); - return(1); -} - - -/* @param flag bit0= *node is already valid - bit1= add extra block for size estimation - bit2= complain loudely if path is missing in image - bit3= stbuf is to be used without eventual ACL - bit4= try to obtain a better st_nlink count if hardlinks - are enabled -*/ -int Xorriso_fake_stbuf(struct XorrisO *xorriso, char *path, struct stat *stbuf, - IsoNode **node, int flag) -{ - int ret, min_hl, max_hl, node_idx, i; - IsoImage *volume; - - memset((char *) stbuf, 0, sizeof(struct stat)); - if(!(flag&1)) { - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - return(-1); - ret= Xorriso_node_from_path(xorriso, volume, path, node, !(flag&4)); - if(ret<=0) - *node= NULL; - } - if(*node==NULL) - return(0); - - /* >>> stbuf->st_dev */ - /* >>> stbuf->st_ino */ - - if(flag & 8) - stbuf->st_mode= iso_node_get_perms_wo_acl(*node) & 07777; - else - stbuf->st_mode= iso_node_get_permissions(*node) & 07777; - if(LIBISO_ISDIR(*node)) - stbuf->st_mode|= S_IFDIR; - else if(LIBISO_ISREG(*node)) - stbuf->st_mode|= S_IFREG; - else if(LIBISO_ISLNK(*node)) - stbuf->st_mode|= S_IFLNK; - else if(LIBISO_ISCHR(*node)) { - stbuf->st_mode|= S_IFCHR; - Xorriso_node_get_dev(xorriso, *node, path, &(stbuf->st_rdev), 0); - } else if(LIBISO_ISBLK(*node)) { - stbuf->st_mode|= S_IFBLK; - Xorriso_node_get_dev(xorriso, *node, path, &(stbuf->st_rdev), 0); - } else if(LIBISO_ISFIFO(*node)) - stbuf->st_mode|= S_IFIFO; - else if(LIBISO_ISSOCK(*node)) - stbuf->st_mode|= S_IFSOCK; - else if(LIBISO_ISBOOT(*node)) - stbuf->st_mode|= Xorriso_IFBOOT; - - /* >>> With directories this should be : number of subdirs + 2 */ - /* >>> ??? How to obtain RR hardlink number for other types ? */ - /* This may get overriden farther down */ - stbuf->st_nlink= 1; - - stbuf->st_uid= iso_node_get_uid(*node); - stbuf->st_gid= iso_node_get_gid(*node); - - if(LIBISO_ISREG(*node)) - stbuf->st_size= iso_file_get_size((IsoFile *) *node)+ (2048 * !!(flag&2)); - else - stbuf->st_size= 0; - - stbuf->st_blksize= 2048; - stbuf->st_blocks= stbuf->st_size / (off_t) 2048; - if(stbuf->st_blocks * (off_t) 2048 != stbuf->st_size) - stbuf->st_blocks++; - - stbuf->st_atime= iso_node_get_atime(*node); - stbuf->st_mtime= iso_node_get_mtime(*node); - stbuf->st_ctime= iso_node_get_ctime(*node); - - if(LIBISO_ISDIR(*node) || (xorriso->ino_behavior & 1) || (!(flag & 16)) || - xorriso->hln_array == NULL) - return(1); - - /* Try to obtain a better link count */ - ret= Xorriso_search_hardlinks(xorriso, *node, &node_idx, &min_hl, &max_hl, 0); - if(ret < 0) - return(ret); - if(ret > 0 && node_idx >= 0) { - for(i= min_hl; i <= max_hl; i++) { - if(i == node_idx) - continue; - /* Check whether node is still valid */ - if(iso_node_get_parent(xorriso->hln_array[i]) != NULL) - stbuf->st_nlink++; - } - } - return(1); -} - - -/* @param flag >>> bit0= follow links (i.e. stat() rather than lstat() - bit1= do not return -2 on severe errors - bit2= complain loudely if path is missing in image -*/ -int Xorriso_iso_lstat(struct XorrisO *xorriso, char *path, struct stat *stbuf, - int flag) -{ - int ret; - IsoNode *node; - - if(flag&1) { - - /* >>> follow link in ISO image */; - - } - - ret= Xorriso_fake_stbuf(xorriso, path, stbuf, &node, flag&4); - if(ret>0) - return(0); - if(ret<0 && !(flag&2)) - return(-2); - return(-1); -} - - -/* @param flag bit0= give directory x-permission where is r-permission - bit1= do not transfer ACL or xattr - bit2= record dev,inode (only if enabled by xorriso) - bit5= transfer ACL or xattr from eventual link target -*/ -int Xorriso_transfer_properties(struct XorrisO *xorriso, struct stat *stbuf, - char *disk_path, IsoNode *node, int flag) -{ - mode_t mode; - int ret= 1; - size_t num_attrs= 0, *value_lengths= NULL; - char **names= NULL, **values= NULL; - - mode= stbuf->st_mode; - - if((!(flag & 2)) && !(xorriso->do_aaip & 1)) - /* Will drop ACL. Update mode S_IRWXG by eventual group:: ACL entry */ - iso_local_get_perms_wo_acl(disk_path, &mode, flag & 32); - - if((flag&1) && S_ISDIR(mode)) { - if(mode&S_IRUSR) - mode|= S_IXUSR; - if(mode&S_IRGRP) - mode|= S_IXGRP; - if(mode&S_IROTH) - mode|= S_IXOTH; - } - iso_node_set_permissions(node, mode & 07777); - iso_node_set_uid(node, stbuf->st_uid); - iso_node_set_gid(node, stbuf->st_gid); - iso_node_set_atime(node, stbuf->st_atime); - iso_node_set_mtime(node, stbuf->st_mtime); - iso_node_set_ctime(node, stbuf->st_ctime); - - if((xorriso->do_aaip & 5) && !(flag & 2)) { - ret= iso_local_get_attrs(disk_path, &num_attrs, &names, &value_lengths, - &values, ((xorriso->do_aaip & 1) && !(flag & 2)) - | ((!(xorriso->do_aaip & 4)) << 2) - | (flag & 32)); - if(ret < 0) { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_report_iso_error(xorriso, disk_path, ret, - "Error when obtaining local ACL and xattr", 0, - "FAILURE", 1 | 2); - ret= 0; goto ex; - } - ret= iso_node_set_attrs(node, num_attrs, names, value_lengths, values, - 1 | 8); - if(ret < 0) { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_report_iso_error(xorriso, "", ret, - "Error when setting ACL and xattr to image node", - 0, "FAILURE", 1); - ret= 0; goto ex; - } - } - - if((flag & 4) && ((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2))) { - ret= Xorriso_record_dev_inode(xorriso, disk_path, (dev_t) 0, (ino_t) 0, - (void *) node, "", flag & 32); - if(ret <= 0) - goto ex; - } - - ret= 1; -ex:; - Xorriso_process_msg_queues(xorriso,0); - iso_local_get_attrs(disk_path, &num_attrs, &names, &value_lengths, - &values, 1 << 15); /* free memory */ - return(ret); -} - - -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 ret; - IsoDir *new_dir= NULL; - IsoNode *part_node; - int partno, total_parts; - off_t offset; - char part_name[SfileadrL], sfe[5*SfileadrL]; - - ret= iso_tree_add_new_dir(dir, img_name, &new_dir); - if(ret<0) - return(ret); - *node= (IsoNode *) new_dir; - total_parts= size / xorriso->split_size; - if(size % xorriso->split_size) - total_parts++; - for(partno= 1; partno<=total_parts; partno++) { - offset = xorriso->split_size * (off_t) (partno-1); - Splitpart__compose(part_name, partno, total_parts, offset, - xorriso->split_size, size, 0); - ret= Xorriso_tree_graft_node(xorriso, volume, - new_dir, disk_path, part_name, - nominal_source, nominal_target, - offset, xorriso->split_size, - &part_node, 8); - if(ret<=0) - return(0); - } - sprintf(xorriso->info_text, "Split into %d parts: %s", - total_parts, Text_shellsafe(nominal_target, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(1); -} - - -/* - @param flag bit3= cut_out_node: offset and size are valid -*/ -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 ret, stbuf_valid= 0; - struct stat stbuf; - char sfe[5*SfileadrL]; - off_t size= 0; - - if(lstat(disk_path, &stbuf) != -1) { - stbuf_valid= 1; - if(S_ISREG(stbuf.st_mode)) - size= stbuf.st_size; - } - if(flag&8) { - if(cut_size > xorriso->file_size_limit && xorriso->file_size_limit > 0) { - sprintf(xorriso->info_text, - "File piece exceeds size limit of %.f bytes: %.f from %s\n", - (double) xorriso->file_size_limit, (double) cut_size, - Text_shellsafe(disk_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - ret= iso_tree_add_new_cut_out_node(volume, dir, img_name, disk_path, - offset, cut_size, node); - if(ret<0) - goto ex; - } else { - if(xorriso->split_size > 0 && size > xorriso->split_size) { - ret= Xorriso_graft_split(xorriso, volume, dir, disk_path, img_name, - nominal_source, nominal_target, size, - node, 0); - if(ret<=0) - goto ex; - } else if(size > xorriso->file_size_limit && xorriso->file_size_limit > 0) { - sprintf(xorriso->info_text, - "File exceeds size limit of %.f bytes: %s\n", - (double) xorriso->file_size_limit, - Text_shellsafe(disk_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } else { - ret= iso_tree_add_new_node(volume, dir, img_name, disk_path, node); - if(ret<0) - goto ex; - } - } - - if(stbuf_valid && ((xorriso->do_aaip & 16) || !(xorriso->ino_behavior & 2))) { - ret= Xorriso_record_dev_inode(xorriso, disk_path, - stbuf.st_dev, stbuf.st_ino, (void *) *node, "", 1); - if(ret <= 0) - goto ex; - } - -ex:; - if(ret<0) { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_report_iso_error(xorriso, nominal_source, ret, - "Cannot add node to tree", 0, "FAILURE", 1|2); - return(ret); - } - if(LIBISO_ISREG(*node)) - xorriso->pacifier_byte_count+= iso_file_get_size((IsoFile *) *node); - return(1); -} - - -/* @param flag bit0= recursion is active - bit1= do not report added files - bit6= do not delete eventually existing node from di_array - bit7= no special handling of split file directories -*/ -int Xorriso_add_tree(struct XorrisO *xorriso, IsoDir *dir, - char *img_dir_path, char *disk_dir_path, - struct LinkiteM *link_stack, int flag) -{ - IsoImage *volume; - IsoNode *node; - int ret, target_is_dir, source_is_dir, source_is_link, fret, was_failure= 0; - int do_not_dive, target_is_split= 0; - struct DirseQ *dirseq= NULL; - char *name, *img_name, *srcpt, *stbuf_src= ""; - struct stat stbuf, hstbuf; - dev_t dir_dev; - struct LinkiteM *own_link_stack; - char *sfe= NULL, *sfe2= NULL; - char *disk_path= NULL, *img_path= NULL, *link_target= NULL; - - /* Avoiding large local memory objects in order to save stack space */ - sfe= malloc(5*SfileadrL); - sfe2= malloc(5*SfileadrL); - disk_path= malloc(2*SfileadrL); - img_path= malloc(2*SfileadrL); - link_target= calloc(SfileadrL, 1); - if(sfe==NULL || sfe2==NULL || disk_path==NULL || img_path==NULL || - link_target==NULL) { - Xorriso_no_malloc_memory(xorriso, &sfe, 0); - {ret= -1; goto ex;} - } - - own_link_stack= link_stack; - - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - goto ex; - - stbuf_src= disk_dir_path; - if(lstat(disk_dir_path, &stbuf)==-1) - goto cannot_open_dir; - dir_dev= stbuf.st_dev; - if(S_ISLNK(stbuf.st_mode)) { - if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1)))) - {ret= 2; goto ex;} - stbuf_src= disk_dir_path; - if(stat(disk_dir_path, &stbuf)==-1) - goto cannot_open_dir; - if(dir_dev != stbuf.st_dev && - !(xorriso->do_follow_mount || (xorriso->do_follow_param && !(flag&1)))) - {ret= 2; goto ex;} - } - ret= Dirseq_new(&dirseq, disk_dir_path, 1); - if(ret<0) { - sprintf(xorriso->info_text,"Failed to create source filesystem iterator"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - {ret= -1; goto ex;} - } - if(ret==0) { -cannot_open_dir:; - Xorriso_msgs_submit(xorriso, 0, disk_dir_path, 0, "ERRFILE", 0); - sprintf(xorriso->info_text,"Cannot open as source directory: %s", - Text_shellsafe(disk_dir_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - - if(Sfile_str(disk_path, disk_dir_path,0)<=0) - {ret= -1; goto ex;} - if(disk_path[0]==0 || disk_path[strlen(disk_path)-1]!='/') - strcat(disk_path,"/"); - name= disk_path+strlen(disk_path); - if(Sfile_str(img_path, img_dir_path, 0)<=0) - {ret= -1; goto ex;} - if(img_path[0] || img_path[strlen(img_path)-1]!='/') - strcat(img_path,"/"); - img_name= img_path+strlen(img_path); - - while(1) { /* loop over directory content */ - stbuf_src= ""; - Linkitem_reset_stack(&own_link_stack, link_stack, 0); - srcpt= disk_path; - Xorriso_process_msg_queues(xorriso,0); - ret= Dirseq_next_adr(dirseq,name,0); /* name is a pointer into disk_path */ - 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;} - } - - /* compare exclusions against disk_path resp. name */ - ret= Xorriso_path_is_excluded(xorriso, disk_path, 0); /* (is never param) */ - if(ret<0) - {ret= -1; goto ex;} - if(ret>0) - continue; - - strcpy(img_name, name); - if(Xorriso_much_too_long(xorriso, strlen(img_path), 0)<=0) - {ret= 0; goto was_problem;} - if(Xorriso_much_too_long(xorriso, strlen(srcpt), 0)<=0) - {ret= 0; goto was_problem;} - stbuf_src= srcpt; - if(lstat(srcpt, &stbuf)==-1) { -cannot_lstat:; - Xorriso_msgs_submit(xorriso, 0, srcpt, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, - "Cannot determine attributes of source file %s", - Text_shellsafe(srcpt, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - ret= 0; goto was_problem; - } - source_is_dir= 0; - source_is_link= S_ISLNK(stbuf.st_mode); - if(xorriso->do_follow_links && source_is_link) { - /* Xorriso_hop_link checks for wide link loops */ - ret= Xorriso_hop_link(xorriso, srcpt, &own_link_stack, &hstbuf, 0); - if(ret<0) - goto was_problem; - if(ret==1) { - ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 0); - if(ret<=0) - goto was_problem; - srcpt= link_target; - stbuf_src= srcpt; - if(lstat(srcpt, &stbuf)==-1) - goto cannot_lstat; - } else { - if(Xorriso_eval_problem_status(xorriso, 0, 1|2)<0) - {ret= 0; goto was_problem;} - ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1); - if(ret<=0) - goto was_problem; - } - } else if (S_ISLNK(stbuf.st_mode)) { - ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1); - if(ret<=0) - goto was_problem; - } - do_not_dive= 0; - if(S_ISDIR(stbuf.st_mode)) { - source_is_dir= 1; - if(dir_dev != stbuf.st_dev && !xorriso->do_follow_mount) - do_not_dive= 1; - } - - /* does a node exist with this name ? */ - node= NULL; - ret= Xorriso_node_from_path(xorriso, volume, img_path, &node, 1); - if(ret>0) { - target_is_dir= LIBISO_ISDIR(node); - target_is_split= 0; - if(target_is_dir && !(flag & 128)) - target_is_split= Xorriso_is_split(xorriso, "", (void *) node, 1 | 2); - - if(!((target_is_dir && !target_is_split) && source_is_dir)) { - Xorriso_process_msg_queues(xorriso,0); - - /* handle overwrite situation */; - if(xorriso->do_overwrite==1 || - (xorriso->do_overwrite==2 && !(target_is_dir && !target_is_split))) { - ret= Xorriso_rmi(xorriso, NULL, (off_t) 0, img_path, - 1 | 8 | (flag & 64)); - if(ret<=0) - goto was_problem; - if(ret==3) { - sprintf(xorriso->info_text, "User revoked adding of: %s", - Text_shellsafe(img_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - ret= 0; goto was_problem; - } - node= NULL; - } else { - Xorriso_msgs_submit(xorriso, 0, srcpt, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, - "While grafting %s : file object exists and may not be overwritten by %s", - Text_shellsafe(img_path,sfe,0), Text_shellsafe(stbuf_src,sfe2,0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto was_problem; - } - } - } - - if(node==NULL) { - ret= Xorriso_tree_graft_node(xorriso, volume, dir, srcpt, img_name, - "", img_path, (off_t) 0, (off_t) 0, - &node, 0); - } - if(node==NULL) { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_msgs_submit(xorriso, 0, stbuf_src, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, "Grafting failed: %s = %s", - Text_shellsafe(img_path,sfe,0), Text_shellsafe(stbuf_src,sfe2,0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto was_problem; - } - - xorriso->pacifier_count++; - if((xorriso->pacifier_count%100)==0) - Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count, - xorriso->pacifier_total, "", 0); - - Xorriso_set_change_pending(xorriso, 0); - if(source_is_dir) { - if(do_not_dive) { - sprintf(xorriso->info_text, "Did not follow mount point : %s", - Text_shellsafe(disk_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - } else { - ret= Xorriso_add_tree(xorriso, (IsoDir *) node, - img_path, disk_path, own_link_stack, - 1 | (flag & (2 | 64 | 128))); - } - if(ret<=0) - goto was_problem; - } - - continue; /* regular bottom of loop */ -was_problem:; - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret<0) - goto ex; - } - - ret= 1; -ex: - if(sfe!=NULL) - free(sfe); - if(sfe2!=NULL) - free(sfe2); - if(disk_path!=NULL) - free(disk_path); - if(img_path!=NULL) - free(img_path); - if(link_target!=NULL) - free(link_target); - Xorriso_process_msg_queues(xorriso,0); - Linkitem_reset_stack(&own_link_stack, link_stack, 0); - Dirseq_destroy(&dirseq, 0); - if(ret<=0) - return(ret); - return(!was_failure); -} - - -/* @param flag bit0= cut_out mode : base on leaf parent directory -*/ -int Xorriso_copy_implicit_properties(struct XorrisO *xorriso, IsoDir *dir, - char *full_img_path, char *img_path, char *full_disk_path, int flag) -{ - int ret, nfic, nic, nfdc, d, i; - char nfi[SfileadrL], ni[SfileadrL], nfd[SfileadrL], *cpt; - char sfe[5*SfileadrL]; - struct stat stbuf; - - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, full_img_path, nfi, - 1|2); - if(ret<=0) - return(ret); - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, img_path, ni, 1|2); - if(ret<=0) - return(ret); - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, full_disk_path, nfd, - 1|2|4); - if(ret<=0) - return(ret); - nfic= Sfile_count_components(nfi, 0); - nic= Sfile_count_components(ni, 0); - nfdc= Sfile_count_components(nfd, 0); - d= nfic-(flag&1)-nic; - if(d<0) - return(-1); - if(d>nfdc) - return(0); - for(i= 0; iinfo_text, - "Copied properties for %s", Text_shellsafe(ni, sfe, 0)); - sprintf(xorriso->info_text+strlen(xorriso->info_text), - " from %s", Text_shellsafe(nfd, sfe, 0)); - if(!((flag&1) && d==0)) - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - return(1); -} - - -/* @param bit0= copy link target properties rather than link properties - bit1= give directory x-permission where is r-permission - bit2= record dev,inode (only if enabled by xorriso) -*/ -int Xorriso_copy_properties(struct XorrisO *xorriso, - char *disk_path, char *img_path, int flag) -{ - int ret; - IsoNode *node; - struct stat stbuf; - - ret= Xorriso_get_node_by_path(xorriso, img_path, NULL, &node, 0); - if(ret<=0) - return(ret); - if(flag & 1) { - if(stat(disk_path, &stbuf)==-1) - return(0); - } else { - if(lstat(disk_path, &stbuf)==-1) - return(0); - } - Xorriso_transfer_properties(xorriso, &stbuf, disk_path, node, - ((flag & 2) >> 1) | ((flag & 1) << 5) | (flag & 4)); - Xorriso_set_change_pending(xorriso, 0); - 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= mkdir: graft in as empty directory, not as copy from disk - bit1= do not report added files - bit2= -follow, -not_*: this is not a command parameter - bit3= use offset and cut_size for cut_out_node - bit4= return 3 on rejection by exclusion or user - bit5= if directory then do not add sub tree - bit6= do not delete eventually existing node from di_array - bit7= no special handling of split file directories - @return <=0 = error , 1 = added simple node , 2 = added directory , - 3 = rejected -*/ -int Xorriso_graft_in(struct XorrisO *xorriso, void *boss_iter, - char *disk_path, char *img_path, - off_t offset, off_t cut_size, int flag) -{ - IsoImage *volume; - char path[SfileadrL], *apt, *npt, *cpt, sfe[5*SfileadrL], sfe2[5*SfileadrL]; - char *disk_path_pt, resolved_disk_path[SfileadrL]; - IsoDir *dir, *hdir; - IsoNode *node; - int done= 0, is_dir= 0, l, ret, target_is_dir, source_is_dir, resolve_link= 0; - int target_is_split; - struct stat stbuf; - - ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&4)); - if(ret<0) - return(ret); - if(ret>0) - return(3*!!(flag&16)); - - for(cpt= img_path; 1; cpt++) { - cpt= strstr(cpt,"/."); - if(cpt==NULL) - break; - if(cpt[2]=='.') { - if(cpt[3]=='/' || cpt[3]==0) - break; - } else if(cpt[2]=='/' || cpt[2]==0) - break; - } - if(cpt!=NULL) { - Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, - "Unsupported relative addressing in iso_rr_path %s (disk: %s)", - Text_shellsafe(img_path, sfe, 0), Text_shellsafe(disk_path, sfe2, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - return(0); - } - - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - return(ret); - - strncpy(path, img_path, sizeof(path)-1); - path[sizeof(path)-1]= 0; - apt= npt= path; - - if(!(flag&1)) { - ret= lstat(disk_path, &stbuf); - if(ret!=-1) { - if(S_ISDIR(stbuf.st_mode)) - is_dir= 1; - else if((stbuf.st_mode&S_IFMT)==S_IFLNK && - (xorriso->do_follow_links || - (xorriso->do_follow_param && !(flag&4)))) { - resolve_link= 1; - ret= stat(disk_path, &stbuf); - if(ret!=-1) { - if(S_ISDIR(stbuf.st_mode)) - is_dir= 1; - } - } - } - if(ret == -1) { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, - "Cannot determine attributes of source file %s", - Text_shellsafe(disk_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - return(0); - } - if(S_ISDIR(stbuf.st_mode)) { - is_dir= 1; - } else { - l= strlen(img_path); - if(l>0) - if(img_path[l-1]=='/') - l= 0; - if(l==0) { - Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, - "Source %s is not a directory. Target %s would be.", - Text_shellsafe(disk_path, sfe, 0), Text_shellsafe(img_path, sfe2, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - } - } - - dir= iso_image_get_root(volume); - if(dir==NULL) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, - "While grafting '%s' : no root node available", img_path); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - return(0); - } - for(npt= apt; !done; apt= npt+1) { - npt= strchr(apt, '/'); - if(npt==NULL) { - npt= apt+strlen(apt); - done= 1; - } else - *npt= 0; - if(*apt==0) { - *apt= '/'; - apt++; - if(done) - goto attach_source; - continue; - } - source_is_dir= (is_dir || (flag&1) || !done); - ret= Xorriso_node_from_path(xorriso, volume, path, &node, 1); - if(ret>0) { - target_is_dir= LIBISO_ISDIR(node); - - target_is_split= 0; - if(target_is_dir && !(flag & 128)) - target_is_split= Xorriso_is_split(xorriso, "", (void *) node, 1 | 2); - - if(!((target_is_dir && !target_is_split) && source_is_dir)) { - Xorriso_process_msg_queues(xorriso,0); - - /* handle overwrite situation */; - if(xorriso->do_overwrite==1 || - (xorriso->do_overwrite==2 && !(target_is_dir && !target_is_split))) { - ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, path, - 1 | 8 | (flag & 64)); - if(ret<=0) - return(ret); - if(ret==3) { - sprintf(xorriso->info_text, "User revoked adding of: %s", - Text_shellsafe(disk_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(3*!!(flag&16)); - } - node= NULL; - goto handle_path_node; - } - - Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, - "While grafting '%s' : '%s' exists and may not be overwritten", - img_path, path); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - dir= (IsoDir *) node; - } - -handle_path_node:; - if(node==NULL && source_is_dir) { /* make a directory */ - ret= iso_tree_add_new_dir(dir, apt, &hdir); - if(ret<0) { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); - Xorriso_report_iso_error(xorriso, img_path, ret, - "Cannot create directory", 0, "FAILURE", 1); - sprintf(xorriso->info_text, - "While grafting '%s' : could not insert '%s'", img_path, path); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - dir= hdir; - Xorriso_set_change_pending(xorriso, 0); - iso_node_set_ctime((IsoNode *) dir, time(NULL)); - iso_node_set_uid((IsoNode *) dir, geteuid()); - iso_node_set_gid((IsoNode *) dir, getegid()); - - if(disk_path!=NULL && !done) - Xorriso_copy_implicit_properties(xorriso, dir, img_path, path, disk_path, - !!(flag&8)); - - } - if(done) { -attach_source:; - if(flag&1) { - /* directory node was created above */; - - } else if(is_dir) { - Xorriso_transfer_properties(xorriso, &stbuf, disk_path, - (IsoNode *) dir, 4 | 32); - if(!(flag&32)) { - ret= Xorriso_add_tree(xorriso, dir, img_path, disk_path, NULL, - flag & (2 | 64 | 128)); - if(ret<=0) - return(ret); - } - } else { - if(resolve_link) { - ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0); - if(ret<=0) - return(ret); - disk_path_pt= resolved_disk_path; - } else - disk_path_pt= disk_path; - - ret= Xorriso_tree_graft_node(xorriso, volume, dir, disk_path_pt, apt, - disk_path, img_path, - offset, cut_size, &node, flag&8); - if(ret<=0) { - sprintf(xorriso->info_text, "Grafting failed: %s = %s", - Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - Xorriso_set_change_pending(xorriso, 0); - iso_node_set_name(node, apt); - - xorriso->pacifier_count++; - if(xorriso->pacifier_count%100 && !(flag&2)) - Xorriso_pacifier_callback(xorriso, "files added", - xorriso->pacifier_count, - xorriso->pacifier_total, "", 0); - } - } else - *npt= '/'; - } - Xorriso_process_msg_queues(xorriso,0); - return(1+!!is_dir); -} - - -/* @param flag bit0= -follow: disk_path is not a command parameter -*/ -int Xorriso_cut_out(struct XorrisO *xorriso, char *disk_path, - off_t startbyte, off_t bytecount, char *iso_rr_path, int flag) -{ - int ret; - char eff_source[SfileadrL], eff_dest[SfileadrL], sfe[SfileadrL*5]; - struct stat stbuf; - - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_source, - 2|4); - if(ret<=0) - return(ret); - ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&1)); - if(ret!=0) - return(0); - - if(lstat(eff_source, &stbuf)==-1) { - Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, "-cut_out: Cannot determine type of %s", - Text_shellsafe(eff_source, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - return(0); - } - - if((stbuf.st_mode&S_IFMT) == S_IFLNK) { - if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1)))) - goto unsupported_type; - if(stat(eff_source, &stbuf)==-1) { - Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, - "-cut_out: Cannot determine link target type of %s", - Text_shellsafe(eff_source, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); - return(0); - } - } - if(S_ISREG(stbuf.st_mode)) { - if(stbuf.st_sizeinfo_text, - "-cut_out: Byte offset %.f larger than file size %.f", - (double) startbyte, (double) stbuf.st_size); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "SORRY", 0); - return(0); - } - } else { -unsupported_type:; - Xorriso_msgs_submit(xorriso, 0, eff_source, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, "-cut_out: Unsupported file type (%s) with %s", - Ftypetxt(stbuf.st_mode, 0), Text_shellsafe(eff_source, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - return(0); - } - - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, iso_rr_path, eff_dest, - 2); - if(ret<=0) - return(ret); - - ret= Xorriso_graft_in(xorriso, NULL, eff_source, eff_dest, - startbyte, bytecount, 8); - return(ret); -} - - -/* @param flag bit0= in_node is valid, do not resolve img_path - bit1= test mode: print DEBUG messages - @return <0 = error, - 0 = surely not identical regular files , - 1 = surely identical - 2 = potentially depending on unknown disk file (e.g. -cut_out) -*/ -int Xorriso_restore_is_identical(struct XorrisO *xorriso, void *in_node, - char *img_path, char *disk_path, - char type_text[5], int flag) -{ - int ret; - unsigned int fs_id; - dev_t dev_id; - ino_t ino_id; - IsoStream *stream; - IsoImage *volume; - IsoNode *node; - struct stat stbuf; - int dummy; - - memset(type_text, 0, 5); - if(!xorriso->volset_change_pending) - return(0); - if(flag&1) { - node= (IsoNode *) in_node; - } else { - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - return(-1); - ret= Xorriso_node_from_path(xorriso, volume, img_path, &node, 1); - if(ret<=0) - return(-1); - } - ret= Xorriso__file_start_lba(node, &dummy, 0); - if(ret != 0) { - Xorriso_process_msg_queues(xorriso, 0); - return(0); - } - if(!LIBISO_ISREG(node)) - return(0); - stream= iso_file_get_stream((IsoFile *) node); - memcpy(type_text, stream->class->type, 4); - iso_stream_get_id(stream, &fs_id, &dev_id, &ino_id); - if(flag&2) { - sprintf(xorriso->info_text, "%s : fs=%d dev=%.f ino=%.f (%s)", - img_path, fs_id, (double) dev_id, (double) ino_id, type_text); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - } - ret= stat(disk_path, &stbuf); - if(ret==-1) - return(0); - if(flag&2) { - sprintf(xorriso->info_text, "%s : dev=%.f ino=%.f", - disk_path, (double) stbuf.st_dev, (double) stbuf.st_ino); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - } - if(fs_id!=1) - return(2); - - /* >>> obtain underlying dev_t ino_t of type "cout" */; - - if(strcmp(type_text, "fsrc")!=0) - return(2); - if(stbuf.st_dev==dev_id && stbuf.st_ino==ino_id) - return(1); - return(0); -} - - -/* @param flag bit0= minimal transfer: access permissions only - bit1= keep directory open: keep owner, allow rwx for owner - and push directory onto xorriso->perm_stack -*/ -int Xorriso_restore_properties(struct XorrisO *xorriso, char *disk_path, - IsoNode *node, int flag) -{ - int ret, is_dir= 0; - mode_t mode; - uid_t uid; - gid_t gid; - struct utimbuf utime_buffer; - char sfe[5*SfileadrL]; - struct stat stbuf; - size_t num_attrs= 0, *value_lengths= NULL; - char **names= NULL, **values= NULL; - - ret= lstat(disk_path, &stbuf); - if(ret==-1) { - sprintf(xorriso->info_text, - "Cannot obtain properties of disk file %s", - Text_shellsafe(disk_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - {ret= 0; goto ex;} - } - uid= stbuf.st_uid; - - is_dir= S_ISDIR(stbuf.st_mode); - - mode= iso_node_get_permissions(node); - - if(xorriso->do_aaip & (2 | 8 | 16)) { - ret= iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values, - (!!(xorriso->do_aaip & 2)) | (!(xorriso->do_aaip & (8 | 16))) << 2); - if (ret < 0) { - strcpy(xorriso->info_text, "Error with obtaining ACL and xattr for "); - Text_shellsafe(disk_path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - if(num_attrs > 0) { - ret= iso_local_set_attrs(disk_path, num_attrs, names, value_lengths, - values, 0); - if(ret < 0) { - sprintf(xorriso->info_text, - "Cannot change ACL or xattr of disk file %s", - Text_shellsafe(disk_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); - {ret= 0; goto ex;} - } - } - Xorriso_process_msg_queues(xorriso,0); - } - if(!(xorriso->do_aaip & 2)) - mode= iso_node_get_perms_wo_acl(node); - - if(is_dir && (flag&2)) { - ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, - 1 | ((!!(xorriso->do_aaip & 2)) << 3)); - if(ret<=0) - {ret= 0; goto ex;} - ret= Permstack_push(&(xorriso->perm_stack), disk_path, &stbuf, 0); - if(ret<=0) { - Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); - strcpy(xorriso->info_text, - "Cannot memorize permissions for disk directory"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - {ret= -1; goto ex;} - } - mode|= S_IRUSR|S_IWUSR|S_IXUSR; - } - ret= chmod(disk_path, mode); - if(ret==-1) { - sprintf(xorriso->info_text, - "Cannot change access permissions of disk file %s", - Text_shellsafe(disk_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - {ret= 0; goto ex;} - } - - if(flag&1) - {ret= 1; goto ex;} - - gid= iso_node_get_gid(node); - if(!(S_ISDIR(stbuf.st_mode) && (flag&2))) - uid= iso_node_get_uid(node); - chown(disk_path, uid, gid); /* don't complain if it fails */ - utime_buffer.actime= iso_node_get_atime(node); - utime_buffer.modtime= iso_node_get_mtime(node); - ret= utime(disk_path,&utime_buffer); - if(ret==-1) { - sprintf(xorriso->info_text, - "Cannot change atime, mtime of disk file %s", - Text_shellsafe(disk_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - {ret= 0; goto ex;} - } - ret= 1; -ex:; - iso_node_get_attrs(node, &num_attrs, &names, &value_lengths, &values,1 << 15); - return(ret); -} - - -/* @param flag - bit1= minimal transfer: access permissions only - bit2= keep directory open: keep owner, allow rwx for owner - push to xorriso->perm_stack -*/ -int Xorriso_restore_implicit_properties(struct XorrisO *xorriso, - char *full_disk_path, char *disk_path, char *full_img_path, int flag) -{ - int ret, nfic, ndc, nfdc, d, i; - char nfi[SfileadrL], nd[SfileadrL], nfd[SfileadrL], *cpt; - char sfe[5*SfileadrL]; - struct stat stbuf; - IsoNode *node; - - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, full_disk_path, nfd, - 1|2|4); - if(ret<=0) - return(ret); - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, nd, 1|2); - if(ret<=0) - return(ret); - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, full_img_path, nfi, - 1|2); - if(ret<=0) - return(ret); - nfdc= Sfile_count_components(nfd, 0); - ndc= Sfile_count_components(nd, 0); - nfic= Sfile_count_components(nfi, 0); - d= nfdc-ndc; - if(d<0) - return(-1); - if(d>nfic) - return(0); - for(i= 0; i>1)&3)); - if(ret<=0) - return(ret); - sprintf(xorriso->info_text, - "Restored properties for %s", Text_shellsafe(nd, sfe, 0)); - sprintf(xorriso->info_text+strlen(xorriso->info_text), - " from %s", Text_shellsafe(nfi, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - return(1); -} - - -int Xorriso_is_plain_image_file(struct XorrisO *xorriso, void *in_node, - char *path, int flag) -{ - int ret, lba; - IsoStream *stream; - IsoNode *node; - - node= (IsoNode *) in_node; - if(node == NULL) { - ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); - if(ret<=0) - return(ret); - } - - ret= Xorriso__file_start_lba(node, &lba, 0); - if(ret > 0) { /* Stream source is from loaded image */ - stream= iso_file_get_stream((IsoFile *) node); - if(stream != NULL) - if(iso_stream_get_input_stream(stream, 0) == NULL) - return(1); - } - return(0); -} - - -/* @param flag bit0= Minimal transfer: access permissions only - bit1= *_offset and bytes are valid for writing to regular file - bit2= This is not a parameter. Do not report if ignored - bit3= do not restore properties - bit4= issue pacifier messages with long lasting copying - bit7= return 4 if restore fails from denied permission - do not issue error message - @return <0 severe error , 0 failure , 1 success , - 2 regularly not installed (disallowed device, UNIX domain socket) - 4 with bit7: permission to restore was denied -*/ -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 ret= 0, write_fd= -1, wanted, wret, open_flags, l_errno= 0; - int target_deleted= 0; - char *what= "[unknown filetype]", sfe[5*SfileadrL], sfe2[5*SfileadrL]; - char buf[32*1024], type_text[5], temp_path[SfileadrL], *buf_pt; - char *link_target, *open_path_pt= NULL; - off_t todo= 0, size, seek_ret, last_p_count= 0, already_done, read_count= 0; - void *data_stream= NULL; - mode_t mode; - dev_t dev= 0; - struct stat stbuf; - struct utimbuf utime_buffer; - - if(LIBISO_ISDIR(node)) { - what= "directory"; - ret= mkdir(disk_path, 0777); - l_errno= errno; - - } else if(LIBISO_ISREG(node)) { - what= "regular file"; - ret= Xorriso_iso_file_open(xorriso, img_path, (void *) node, &data_stream, - 1); - if(ret<=0) - goto ex; - open_path_pt= disk_path; - ret= stat(open_path_pt, &stbuf); - if(ret == -1 && errno == EACCES && (flag & 128)) - {ret= 4; goto ex;} - if(flag&2) { - if(ret!=-1 && !S_ISREG(stbuf.st_mode)) { - sprintf(xorriso->info_text, - "Restore offset demanded. But filesystem path leads to non-data file %s", - Text_shellsafe(disk_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); - l_errno= 0; - goto cannot_restore; - } - } else { - /* If source and target are the same disk file then do not copy content */ - ret= Xorriso_restore_is_identical(xorriso, (void *) node, img_path, - disk_path, type_text, 1); - if(ret<0) - goto ex; - if(ret==1) { - /* preliminarily emulate touch (might get overridden later) */ - utime_buffer.actime= stbuf.st_atime; - utime_buffer.modtime= time(0); - utime(disk_path,&utime_buffer); - goto restore_properties; - } - if(ret==2) { - /* Extract to temporary file and rename only after copying */ - ret= Xorriso_make_tmp_path(xorriso, disk_path, temp_path, &write_fd, - 128); - if(ret <= 0 || ret == 4) - goto ex; - open_path_pt= temp_path; - } - } - if(write_fd==-1) { - open_flags= O_WRONLY|O_CREAT; - if(disk_offset==0 || !(flag&2)) - open_flags|= O_EXCL; - write_fd= open(open_path_pt, open_flags, S_IRUSR|S_IWUSR); - l_errno= errno; - if(write_fd == -1 && errno == EACCES && (flag & 128)) - {ret= 4; goto ex;} - if(write_fd==-1) - goto cannot_restore; - } - todo= size= iso_file_get_size((IsoFile *) node); - if(flag&2) { - if(bytesinfo_text, - "Cannot address byte %.f in filesystem path %s", - (double) disk_offset, Text_shellsafe(open_path_pt, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); - goto cannot_restore; - } - } - while(todo>0) { - wanted= sizeof(buf); - if(wanted>todo) - wanted= todo; - ret= Xorriso_iso_file_read(xorriso, data_stream, buf, wanted, 0); - if(ret<=0) { - if(xorriso->extract_error_mode == 0 && - Xorriso_is_plain_image_file(xorriso, node, "", 0)) { - close(write_fd); - write_fd= -1; - already_done= (size - todo) / (off_t) 2048; - already_done*= (off_t) 2048; - sprintf(xorriso->info_text, - "Starting best_effort handling on ISO file %s at byte %.f", - Text_shellsafe(img_path, sfe, 0), (double) already_done); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - ret= Xorriso_read_file_data(xorriso, node, img_path, open_path_pt, - already_done, already_done, size - already_done, 2); - if(ret >= 0) - xorriso->pacifier_byte_count+= todo; - if(ret > 0) - todo= 0; - else - todo= -1; - } - if(ret <= 0) { - sprintf(xorriso->info_text, "Cannot read all bytes from ISO file %s", - Text_shellsafe(img_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } - break; - } - read_count+= ret; - buf_pt= buf; - - if(img_offset > read_count - ret) { - /* skip the desired amount of bytes */ - if(read_count <= img_offset) - continue; - buf_pt= buf + (img_offset - (read_count - ret)); - ret= read_count - img_offset; - } - - wret= write(write_fd, buf_pt, ret); - if(wret>=0) { - todo-= wret; - xorriso->pacifier_byte_count+= wret; - if((flag&16) && - xorriso->pacifier_byte_count - last_p_count >= 128*1024) { - Xorriso_pacifier_callback(xorriso, "files restored", - xorriso->pacifier_count, - xorriso->pacifier_total, "", 2|4); - last_p_count= xorriso->pacifier_byte_count; - } - } - if(wret != ret) { - sprintf(xorriso->info_text, - "Cannot write all bytes to disk filesystem path %s", - Text_shellsafe(open_path_pt, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); - break; - } - } - if(write_fd > 0) - close(write_fd); - write_fd= -1; - if(todo > 0 && xorriso->extract_error_mode == 2 && open_path_pt != NULL) { - unlink(open_path_pt); - target_deleted= 1; - } - Xorriso_iso_file_close(xorriso, &data_stream, 0); - data_stream= NULL; - if(temp_path==open_path_pt && !target_deleted) { - ret= rename(temp_path, disk_path); - if(ret==-1) { - sprintf(xorriso->info_text, - "Cannot rename temporary path %s to final disk path %s", - Text_shellsafe(temp_path, sfe, 0), - Text_shellsafe(disk_path, sfe2, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); - unlink(temp_path); - ret= 0; goto ex; - } - } - ret= -(todo > 0); - l_errno= 0; - - } else if(LIBISO_ISLNK(node)) { - what= "symbolic link"; - link_target= (char *) iso_symlink_get_dest((IsoSymlink *) node); - ret= symlink(link_target, disk_path); - l_errno= errno; - - } else if(LIBISO_ISCHR(node)) { - what= "character device"; - if(xorriso->allow_restore!=2) { -ignored:; - if(!(flag&4)) { - sprintf(xorriso->info_text, "Ignored file type: %s %s = %s", what, - Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - } - {ret= 2; goto ex;} - } - mode= S_IFCHR | 0777; - ret= Xorriso_node_get_dev(xorriso, node, img_path, &dev, 0); - if(ret<=0) - goto ex; - if(dev == (dev_t) 1) { -probably_damaged:; - sprintf(xorriso->info_text, - "Most probably damaged device file not restored: mknod %s %s 0 1", - Text_shellsafe(disk_path, sfe, 0), LIBISO_ISCHR(node) ? "c" : "b"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - ret= 0; goto ex; - } - ret= mknod(disk_path, mode, dev); - l_errno= errno; - - } else if(LIBISO_ISBLK(node)) { - what= "block device"; - if(xorriso->allow_restore!=2) - goto ignored; - mode= S_IFBLK | 0777; - ret= Xorriso_node_get_dev(xorriso, node, img_path, &dev, 0); - if(ret<=0) - goto ex; - if(dev == (dev_t) 1) - goto probably_damaged; - ret= mknod(disk_path, mode, dev); - l_errno= errno; - - } else if(LIBISO_ISFIFO(node)) { - what= "named pipe"; - mode= S_IFIFO | 0777; - ret= mknod(disk_path, mode, dev); - l_errno= errno; - - } else if(LIBISO_ISSOCK(node)) { - what= "unix socket"; - /* Restoring a socket file is not possible. One rather needs to restart - the service which temporarily created the socket. */ - goto ignored; - - } else { - sprintf(xorriso->info_text, "Cannot restore file type '%s'", what); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - ret= 0; goto ex; - } - if(ret == -1 && l_errno == EACCES && (flag & 128)) - {ret= 4; goto ex;} - if(ret==-1) { -cannot_restore:; - sprintf(xorriso->info_text, - "Cannot restore %s to disk filesystem: %s", - what, Text_shellsafe(img_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, l_errno, "FAILURE", 0); - ret= 0; goto ex; - } - -restore_properties:; - if((flag&8) || LIBISO_ISLNK(node)) - ret= 1; - else - ret= Xorriso_restore_properties(xorriso, disk_path, node, flag&1); - if(todo < 0) - ret= 0; -ex:; - if(write_fd >= 0) { - close(write_fd); - if(ret <= 0 && xorriso->extract_error_mode == 2 && open_path_pt != NULL) - unlink(open_path_pt); - } - if(data_stream!=NULL) - Xorriso_iso_file_close(xorriso, &data_stream, 0); - return(ret); -} - - -/* Handle overwrite situation in disk filesystem. - @param node intended source of overwriting or NULL - @param flag - bit4= return 3 on rejection by exclusion or user - bit6= permission to call Xorriso_make_accessible() -*/ -int Xorriso_restore_overwrite(struct XorrisO *xorriso, - IsoNode *node, char *img_path, - char *path, char *nominal_path, - struct stat *stbuf, int flag) -{ - int ret; - char sfe[5*SfileadrL], sfe2[5*SfileadrL], type_text[5]; - - Xorriso_process_msg_queues(xorriso,0); - if(xorriso->do_overwrite==1 || - (xorriso->do_overwrite==2 && !S_ISDIR(stbuf->st_mode))) { - - ret= Xorriso_restore_is_identical(xorriso, (void *) node, img_path, - path, type_text, (node!=NULL)); - if(ret<0) - return(ret); - if(ret>0) /* will be handled properly by restore functions */ - ret= Xorriso_reassure_restore(xorriso, path, 8); - else - ret= Xorriso_rmx(xorriso, (off_t) 0, path, 8 | (flag & 64)); - if(ret<=0) - return(ret); - if(ret==3) { - sprintf(xorriso->info_text, "User revoked restoring of (ISO) file: %s", - Text_shellsafe(img_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(3*!!(flag&16)); - } - return(1); - } - Xorriso_msgs_submit(xorriso, 0, nominal_path, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, - "While restoring %s : %s exists and may not be overwritten", - Text_shellsafe(nominal_path, sfe, 0), strcmp(nominal_path, path)==0 ? - "file object" : Text_shellsafe(path, sfe2, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); -} - - -/* @param flag bit0= do not accept hln_targets[i] != NULL as *node_idx - bit1= use *node_idx as found index rather than searching it - bit2= with bit1: use xorriso->node_array rather than hln_array -*/ -int Xorriso_search_hardlinks(struct XorrisO *xorriso, IsoNode *node, - int *node_idx, int *min_hl, int *max_hl, int flag) -{ - int idx, ret, i, node_count; - void *np, **node_array; - - node_array= xorriso->hln_array; - node_count= xorriso->hln_count; - *min_hl= *max_hl= -1; - np= node; - if(flag & 2) { - idx= *node_idx; - if(flag & 4) { - node_array= xorriso->node_array; - node_count= xorriso->node_counter; - } - } else { - *node_idx= -1; - ret= Xorriso_search_in_hln_array(xorriso, np, &idx, 0); - if(ret <= 0) - return(ret); - } - for(i= idx - 1; i >= 0 ; i--) - if(Xorriso__findi_sorted_ino_cmp(&(node_array[i]), &np) != 0) - break; - *min_hl= i + 1; - for(i= idx + 1; i < node_count; i++) - if(Xorriso__findi_sorted_ino_cmp(&(node_array[i]), &np) != 0) - break; - *max_hl= i - 1; - - /* Search for *node_idx */ - if(flag & 2) - return(1); - for(i= *min_hl; i <= *max_hl; i++) - if(node_array[i] == np) { - if((flag & 1) && xorriso->hln_targets != NULL && !(flag & 4)) - if(xorriso->hln_targets[i] != NULL) - continue; - *node_idx= i; - break; - } - return(1); -} - - -/* - @return <0 error, - bit0= hardlink created - bit1= siblings with target NULL found - bit2= siblings with non-NULL target found -*/ -int Xorriso_restore_target_hl(struct XorrisO *xorriso, IsoNode *node, - char *disk_path, int *node_idx, int flag) -{ - int ret, min_hl, max_hl, i, null_target_sibling= 0, link_sibling= 0; - - if(xorriso->hln_targets == NULL) - return(0); - ret= Xorriso_search_hardlinks(xorriso, node, node_idx, &min_hl, &max_hl, 1); - if(ret < 0) - return(ret); - if(ret == 0 || *node_idx < 0 || min_hl == max_hl) - return(0); - for(i= min_hl; i <= max_hl; i++) { - if(xorriso->hln_targets[i] == NULL) { - if(i != *node_idx) - null_target_sibling= 1; - continue; - } - link_sibling= 1; - ret= Xorriso_restore_make_hl(xorriso, xorriso->hln_targets[i], disk_path, - !!xorriso->do_auto_chmod); - if(ret > 0) - return(1); - } - return((null_target_sibling << 1) | (link_sibling << 2)); -} - - -/* - @return <0 error, - bit0= hardlink created - bit2= siblings lower index found -*/ -int Xorriso_restore_prefix_hl(struct XorrisO *xorriso, IsoNode *node, - char *disk_path, int node_idx, int flag) -{ - int ret, min_hl, max_hl, i, link_sibling= 0, hflag; - char old_path[SfileadrL], img_path[SfileadrL]; - struct Xorriso_lsT *img_prefixes= NULL, *disk_prefixes= NULL; - - ret= Xorriso_search_hardlinks(xorriso, node, &node_idx, &min_hl, &max_hl, - 2 | 4); - if(ret < 0) - return(ret); - if(ret == 0 || min_hl == max_hl) - return(0); - - for(i= min_hl; i < node_idx; i++) { - link_sibling= 1; - ret= Xorriso_path_from_node(xorriso, xorriso->node_array[i], img_path, 0); - if(ret < 0) - return(ret); - if(ret == 0) - continue; /* Node is deleted from tree (Should not happen here) */ - hflag= 1; - if(i == min_hl) { - hflag= 0; - } else if(xorriso->node_array[i] != xorriso->node_array[i - 1]) { - hflag= 0; - } - if(hflag == 0) { - img_prefixes= xorriso->node_img_prefixes; - disk_prefixes= xorriso->node_disk_prefixes; - } - ret= Xorriso_make_restore_path(xorriso, &img_prefixes, &disk_prefixes, - img_path, old_path, hflag); - if(ret <= 0) - return(ret); - ret= Xorriso_restore_make_hl(xorriso, old_path, disk_path, - !!xorriso->do_auto_chmod); - if(ret > 0) - return(1); - } - return(link_sibling << 2); -} - - -/* @return <0 = error , 0 = availmem exhausted first time , 1 = ok - 2 = availmem exhausted repeated -*/ -int Xorriso_register_node_target(struct XorrisO *xorriso, int node_idx, - char *disk_path, int flag) -{ - int l; - - if(xorriso->node_targets_availmem == 0) - return(2); - if(xorriso->hln_targets == NULL || node_idx < 0 || - node_idx >= xorriso->hln_count) - return(0); - if(xorriso->hln_targets[node_idx] != NULL) { - xorriso->node_targets_availmem+= strlen(xorriso->hln_targets[node_idx]) +1; - free(xorriso->hln_targets[node_idx]); - } - l= strlen(disk_path); - if(xorriso->node_targets_availmem <= l + 1) { - sprintf(xorriso->info_text, - "Hardlink target buffer exceeds -temp_mem_limit. Hardlinks may get divided."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - xorriso->node_targets_availmem= 0; - return(0); - } - xorriso->hln_targets[node_idx]= strdup(disk_path); - if(xorriso->hln_targets[node_idx] == NULL) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - return(-1); - } - xorriso->node_targets_availmem-= (l + 1); - return(1); -} - - -/* - @param flag bit0= offset and bytes is valid for writing to regular file - bit1= do not report copied files - bit2= -follow, -not_*: this is not a command parameter - bit3= keep directory open: keep owner, allow rwx for owner - bit4= do not look for hardlinks even if enabled - bit6= this is a copy action: do not fake times and ownership - bit7= return 4 if restore fails from denied permission - do not issue error message - @return <=0 = error , 1 = added leaf file object , 2 = added directory , - 3= regularly not installed (disallowed device, UNIX domain socket) - 4 = with bit7: permission to restore was denied -*/ -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 ret, i, split_count= 0, partno, total_parts, leaf_is_split= 0; - int record_hl_path= 0, node_idx, cannot_register= 0; - off_t total_bytes, was_byte_count; - char *part_name, part_path[SfileadrL], *img_path_pt; - char sfe[5*SfileadrL], sfe2[5*SfileadrL]; - IsoImage *volume; - IsoNode *part_node, *first_part_node= NULL; - struct SplitparT *split_parts= NULL; - struct stat stbuf; - - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - goto ex; - - was_byte_count= xorriso->pacifier_byte_count; - - if(LIBISO_ISDIR(node) && xorriso->do_concat_split) - leaf_is_split= Xorriso_identify_split(xorriso, img_path, node, - &split_parts, &split_count, &stbuf, 1|2); - if(leaf_is_split) { - /* map all files in directory img_path into regular file disk_path */ - - for(i=0 ; itotal_bytes) - bytes= total_bytes-offset; - ret= Xorriso_tree_restore_node(xorriso, part_node, part_path, (off_t) 0, - disk_path, offset, bytes, - (!!(flag&64)) | 2 | (flag & (4 | 128)) | 8 | ( 16 * !(flag&2))); - if(ret<=0) - goto restoring_failed; - if(ret == 4) - goto ex; - } - if(first_part_node!=NULL) - Xorriso_restore_properties(xorriso, disk_path, first_part_node, - !!(flag&64)); - goto went_well; - } - -#ifdef Osirrox_not_yeT - - if(resolve_link) { - ret= Xorriso_resolve_link(xorriso, disk_path, resolved_disk_path, 0); - if(ret<=0) - goto ex; - disk_path_pt= resolved_disk_path; - } else - -#endif /* Osirrox_not_yeT */ - - img_path_pt= img_path; - - if(!((xorriso->ino_behavior & 4) || (flag & (1 | 16)) || LIBISO_ISDIR(node))){ - /* Try to restore as hardlink */ - ret= Xorriso_restore_target_hl(xorriso, node, disk_path, &node_idx, - !!xorriso->do_auto_chmod); - if(ret < 0) { - goto ex; - } else if(ret & 1) { - /* Success, hardlink was created */ - goto went_well; - } else if(ret & 2) { - /* Did not establish hardlink. Hardlink siblings with target NULL found.*/ - record_hl_path= 1; - } - if(ret & 4) { - /* Found siblings with non-NULL target, but did not link. */ - ret= Xorriso_eval_problem_status(xorriso, 1, 0); - if(ret < 0) - {ret= 0; goto ex;} - } - } - - ret= Xorriso_tree_restore_node(xorriso, node, img_path_pt, (off_t) 0, - disk_path, offset, bytes, - (flag&(4 | 8 | 128)) | (!!(flag&64)) | ((flag&1)<<1) | ( 16 * !(flag&2))); - if(ret == 4) - goto ex; - if(ret>0 && (flag&8)) - ret= Xorriso_restore_properties(xorriso, disk_path, node, 2 | !!(flag&64)); - if(ret<=0) { -restoring_failed:; - sprintf(xorriso->info_text, "Restoring failed: %s = %s", - Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - if(ret==2) - {ret= 3; goto ex;} - if(record_hl_path) { /* Start of a disk hardlink family */ - ret= Xorriso_register_node_target(xorriso, node_idx, disk_path, 0); - if(ret < 0) - goto ex; - if(ret == 0) - cannot_register= 1; - } - -went_well:; - xorriso->pacifier_count++; - if(!(flag&2)) - Xorriso_pacifier_callback(xorriso, "files restored", - xorriso->pacifier_count, - xorriso->pacifier_total, "", 4); - ret= 1; -ex:; - if(split_parts!=NULL) - Splitparts_destroy(&split_parts, split_count, 0); - if(ret > 0 && cannot_register) - ret= 0; - return(ret); -} - - -/* @param flag bit0= source is a directory and not to be restored as split file - >>> bit6= permission to call Xorriso_make_accessible() - @return <=0 error , 1=collision handled , 2=no collision , 3=revoked by user -*/ -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 ret, target_is_dir= 0, target_is_link= 0, stat_ret, made_accessible= 0; - struct stat target_stbuf, lt_stbuf; - struct PermiteM *perm_stack_mem; - - perm_stack_mem= xorriso->perm_stack; - - /* does a disk file exist with this name ? */ - *stbuf_ret= lstat(disk_path, &target_stbuf); - if(*stbuf_ret==-1) { - if((flag & 64) && errno == EACCES) { - ret= Xorriso_make_accessible(xorriso, disk_path, 0); - if(ret < 0) - goto ex; - made_accessible= 1; - *stbuf_ret= lstat(disk_path, &target_stbuf); - } - if(*stbuf_ret==-1) - {ret= 2; goto ex;} - } - target_is_link= S_ISLNK(target_stbuf.st_mode); - if(target_is_link) { - stat_ret= stat(disk_path, <_stbuf); - if(stat_ret == -1) { - if((flag & 64) && errno == EACCES && !made_accessible) { - ret= Xorriso_make_accessible(xorriso, disk_path, 0); - if(ret < 0) - goto ex; - made_accessible= 1; - stat_ret= stat(disk_path, <_stbuf); - } - } - if(stat_ret != -1) - target_is_dir= S_ISDIR(lt_stbuf.st_mode); - } else { - target_is_dir= S_ISDIR(target_stbuf.st_mode); - } - if(target_is_dir && (!target_is_link) && !(flag&1)) { - strcpy(xorriso->info_text, "Attempt to replace DISK directory "); - Text_shellsafe(nominal_disk_path, - xorriso->info_text+strlen(xorriso->info_text), 0); - strcat(xorriso->info_text, " by ISO file "); - Text_shellsafe(img_path, xorriso->info_text+strlen(xorriso->info_text), 0); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - - if(!(target_is_dir && (flag&1))) { - Xorriso_process_msg_queues(xorriso,0); - ret= Xorriso_restore_overwrite(xorriso, node, img_path, disk_path, - nominal_disk_path, &target_stbuf, 16 | (flag & 64)); - if(ret==3) - {ret= 3; goto ex;} - if(ret<=0) - goto ex; - *stbuf_ret= -1; /* It might still exist but will be handled properly */ - } - ret= 1; -ex:; - if(made_accessible) - Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0); - return(ret); -} - - -/* @param flag bit0= recursion is active - bit1= do not report restored files - bit6= this is a copy action: do not fake times and ownership - bit8= only register non-directory nodes in xorriso->node_array - bit7+8= - 0= direct operation - 1= create only directories, - count nodes in xorriso->node_counter - 2= only register non-directory nodes in - xorriso->node_array - 3= count nodes in xorriso->node_counter, - create no directory -*/ -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) -{ - IsoImage *volume; - IsoNode *node; - IsoDirIter *iter= NULL; - IsoNode **node_array= NULL; - int node_count, node_idx; - int ret, source_is_dir, source_is_link, fret, was_failure= 0; - int do_not_dive, source_is_split= 0, len_dp, len_ip, stbuf_ret, hflag, hret; - char *name, *disk_name, *leaf_name, *srcpt, *stbuf_src= ""; - struct LinkiteM *own_link_stack; - char *sfe= NULL, *sfe2= NULL; - char *disk_path= NULL, *img_path= NULL, *link_target= NULL; - off_t mem; - struct PermiteM *perm_stack_mem; - struct stat stbuf; - int dir_create= 0, node_register= 0, do_node_count= 0, normal_mode= 0; - - perm_stack_mem= xorriso->perm_stack; - switch((flag >> 7) & 3) { - case 0: normal_mode= 1; - break; case 1: dir_create= 1; - break; case 2: node_register= 1; - break; case 3: do_node_count= 1; - } - - /* Avoiding large local memory objects in order to save stack space */ - sfe= malloc(5*SfileadrL); - sfe2= malloc(5*SfileadrL); - disk_path= malloc(2*SfileadrL); - img_path= malloc(2*SfileadrL); - link_target= malloc(SfileadrL); - if(sfe==NULL || sfe2==NULL || disk_path==NULL || img_path==NULL || - link_target==NULL) { - Xorriso_no_malloc_memory(xorriso, &sfe, 0); - {ret= -1; goto ex;} - } - - own_link_stack= link_stack; - - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - goto ex; - - stbuf_src= img_dir_path; - node= (IsoNode *) dir; - ret= Xorriso_fake_stbuf(xorriso, stbuf_src, &stbuf, &node, 1); - if(ret<=0) { - Xorriso_msgs_submit(xorriso, 0, disk_dir_path, 0, "ERRFILE", 0); - sprintf(xorriso->info_text,"Cannot open as (ISO) source directory: %s", - Text_shellsafe(img_dir_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - -#ifdef Osirrox_not_yeT - - dev_t dir_dev; - dir_dev= stbuf.st_dev; - - if(S_ISLNK(stbuf.st_mode)) { - if(!(xorriso->do_follow_links || (xorriso->do_follow_param && !(flag&1)))) - {ret= 2; goto ex;} - stbuf_src= disk_dir_path; - if(stat(disk_dir_path, &stbuf)==-1) - goto cannot_open_dir; - if(dir_dev != stbuf.st_dev && - !(xorriso->do_follow_mount || (xorriso->do_follow_param && !(flag&1)))) - {ret= 2; goto ex;} - } - -#endif /* Osirrox_not_yeT */ - - if(!S_ISDIR(stbuf.st_mode)) { - Xorriso_msgs_submit(xorriso, 0, disk_dir_path, 0, "ERRFILE", 0); - sprintf(xorriso->info_text,"Is not a directory in ISO image: %s", - Text_shellsafe(img_dir_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - - mem= boss_mem; - ret= Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count, - &node_idx, &node, - 1 | 4 * (normal_mode && (xorriso->ino_behavior & 4))); - if(ret<=0) - goto ex; - - if(Sfile_str(img_path, img_dir_path,0)<=0) { -much_too_long:; - Xorriso_much_too_long(xorriso, SfileadrL, 2); - {ret= 0; goto ex;} - } - if(img_path[0]==0 || img_path[strlen(img_path)-1]!='/') - strcat(img_path,"/"); - name= img_path+strlen(img_path); - if(Sfile_str(disk_path, disk_dir_path, 0)<=0) - goto much_too_long; - if(disk_path[0]==0 || disk_path[strlen(disk_path)-1]!='/') - strcat(disk_path,"/"); - disk_name= disk_path+strlen(disk_path); - - len_dp= strlen(disk_path); - len_ip= strlen(img_path); - - while(1) { /* loop over ISO directory content */ - stbuf_src= ""; - -#ifdef Osirrox_not_yeT - - Linkitem_reset_stack(&own_link_stack, link_stack, 0); - -#endif - - srcpt= img_path; - Xorriso_process_msg_queues(xorriso,0); - ret= Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count, - &node_idx, &node, 0); - if(ret<0) - goto ex; - if(ret==0 || xorriso->request_to_abort) - break; - leaf_name= (char *) iso_node_get_name(node); - if(Xorriso_much_too_long(xorriso, len_dp + strlen(leaf_name)+1, 0)<=0) - {ret= 0; goto was_problem;} - if(Xorriso_much_too_long(xorriso, len_ip + strlen(leaf_name)+1, 0)<=0) - {ret= 0; goto was_problem;} - /* name is a pointer into img_path */ - strcpy(name, leaf_name); - strcpy(disk_name, leaf_name); - - stbuf_src= srcpt; - ret= Xorriso_fake_stbuf(xorriso, img_path, &stbuf, &node, 1); - if(ret<=0) - goto was_problem; - source_is_dir= 0; - source_is_link= S_ISLNK(stbuf.st_mode); - -#ifdef Osirrox_not_yeT - - /* ??? Link following in the image would cause severe problems - with Xorriso_path_from_node() */ - - if(xorriso->do_follow_links && source_is_link) { - /* Xorriso_hop_link checks for wide link loops */ - ret= Xorriso_hop_link(xorriso, srcpt, &own_link_stack, &hstbuf, 0); - if(ret<0) - goto was_problem; - if(ret==1) { - ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 0); - if(ret<=0) - goto was_problem; - srcpt= link_target; - stbuf_src= srcpt; - if(lstat(srcpt, &stbuf)==-1) - goto cannot_lstat; - } else { - if(Xorriso_eval_problem_status(xorriso, 0, 1|2)<0) - {ret= 0; goto was_problem;} - } - } else if (S_ISLNK(stbuf.st_mode)) { - ret= Xorriso_resolve_link(xorriso, srcpt, link_target, 1); - if(ret<=0) - goto was_problem; - } - -#endif /* Osirrox_not_yeT */ - - do_not_dive= 0; - if(S_ISDIR(stbuf.st_mode)) - source_is_dir= 1; - source_is_split= 0; - if(source_is_dir) - source_is_split= Xorriso_is_split(xorriso, img_path, node, 1|2); - if(source_is_split) - do_not_dive= 1; - - if(source_is_dir || !(dir_create || do_node_count || node_register)) { - ret= Xorriso_handle_collision(xorriso, node, img_path, - disk_path, disk_path, &stbuf_ret, - (source_is_dir && !source_is_split)); - if(ret<=0 || ret==3) - goto was_problem; - } else { - stbuf_ret= -1; - } - - if(stbuf_ret!=-1) { /* (Can only happen with directory) */ - Xorriso_auto_chmod(xorriso, disk_path, 0); - } else { - hflag= 4 | (flag & (2|64)); - if(source_is_dir && !do_not_dive) - hflag|= 8; /* keep directory open for user */ - if((dir_create || do_node_count) && !source_is_dir) { - xorriso->node_counter++; - } else if(node_register && !source_is_dir) { - if(xorriso->node_counter < xorriso->node_array_size) { - xorriso->node_array[xorriso->node_counter++]= (void *) node; - iso_node_ref(node); - } - } else if(node_register || do_node_count) { - ret= 1; - } else { - ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path, - (off_t) 0, (off_t) 0, hflag); - } - if(ret<=0) - goto was_problem; - } - if(source_is_dir && !do_not_dive) { - ret= Xorriso_restore_tree(xorriso, (IsoDir *) node, - img_path, disk_path, mem, - own_link_stack, 1 | (flag & (2 | (3 << 7)))); - /* eventually restore exact access permissions of directory */ - hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, - !!(flag&64)); - if(hret<=0 && hretperm_stack), perm_stack_mem, xorriso, !!(flag&64)); - } - - ret= 1; -ex: - Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, !!(flag&64)); - if(sfe!=NULL) - free(sfe); - if(sfe2!=NULL) - free(sfe2); - if(disk_path!=NULL) - free(disk_path); - if(img_path!=NULL) - free(img_path); - if(link_target!=NULL) - free(link_target); - Xorriso_findi_iter(xorriso, dir, &mem, &iter, &node_array, &node_count, - &node_idx, &node, (1<<31)); - - Xorriso_process_msg_queues(xorriso,0); - -#ifdef Osirrox_not_yeT - - Linkitem_reset_stack(&own_link_stack, link_stack, 0); - -#endif - - if(ret<=0) - return(ret); - return(!was_failure); -} - - -/* - @param flag - >>> bit0= mkdir: graft in as empty directory, not as copy from iso - bit1= do not report copied files - bit2= -follow, -not_*: this is not a command parameter - bit3= use offset and cut_size for -paste_in - bit4= return 3 on rejection by exclusion or user - bit5= if directory then do not add sub tree - bit6= this is a copy action: do not fake times and ownership - bit7+8= operation mode - 0= direct operation - 1= create only directories, - count nodes in xorriso->node_counter - 2= only register non-directory nodes in - xorriso->node_array - 3= count nodes in xorriso->node_counter, - create no directory - bit9= with operation mode 1 do net register prefixes - @return <=0 = error , 1 = added leaf file object , 2 = added directory , - 3 = rejected -*/ -int Xorriso_restore(struct XorrisO *xorriso, - char *img_path, char *disk_path, - off_t offset, off_t bytes, int flag) -{ - IsoImage *volume; - char path[SfileadrL], *apt, *npt, sfe[5*SfileadrL]; - IsoNode *node= NULL; - int done= 0, is_dir= 0, ret, source_is_dir, stbuf_ret, hret; - int dir_create= 0, node_count= 0, node_register= 0; - int leaf_is_split= 0, source_is_split= 0, new_dir_made= 0; - struct stat stbuf; - struct PermiteM *perm_stack_mem; - - perm_stack_mem= xorriso->perm_stack; - switch((flag >> 7) & 3) { - case 1: dir_create= 1; - break; case 2: node_register= 1; - break; case 3: node_count= 1; - } - - if(dir_create && !(flag & (1 << 9))) { - ret= Xorriso_lst_append_binary(&(xorriso->node_disk_prefixes), - disk_path, strlen(disk_path) + 1, 0); - if(ret <= 0) - goto ex; - ret= Xorriso_lst_append_binary(&(xorriso->node_img_prefixes), - img_path, strlen(img_path) + 1, 0); - if(ret <= 0) - goto ex; - } - - ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&4)); - if(ret<0) - goto ex; - if(ret>0) - {ret= 3*!!(flag&16); goto ex;} - - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - goto ex; - - strncpy(path, disk_path, sizeof(path)-1); - path[sizeof(path)-1]= 0; - apt= npt= path; - - if(!(flag&1)) { - ret= Xorriso_fake_stbuf(xorriso, img_path, &stbuf, &node, 0); - if(ret>0) { - if(S_ISDIR(stbuf.st_mode)) - is_dir= 1; - -#ifdef Osirrox_not_yeT - - /* ??? this would cause severe problems with Xorriso_path_from_node() */ - - else if((stbuf.st_mode&S_IFMT)==S_IFLNK && - (xorriso->do_follow_links || - (xorriso->do_follow_param && !(flag&4)))) { - resolve_link= 1; - ret= Xorriso_iso_lstat(xorriso, img_path, &stbuf, 1|2); - if(ret!=-1) { - if(S_ISDIR(stbuf.st_mode)) - is_dir= 1; - } - } -#endif /* Osirrox_not_yeT */ - - } else { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, - "Cannot determine attributes of (ISO) source file %s", - Text_shellsafe(img_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - ret= 0; goto ex; - } - if(is_dir && xorriso->do_concat_split) - leaf_is_split= Xorriso_is_split(xorriso, img_path, node, 1|2); - } - for(npt= apt; !done; apt= npt+1) { - npt= strchr(apt, '/'); - if(npt==NULL) { - npt= apt+strlen(apt); - done= 1; - } else - *npt= 0; - if(*apt==0) { - *apt= '/'; - apt++; - if(done) - goto attach_source; - continue; - } - source_is_dir= (is_dir || (flag&1) || !done); - source_is_split= done && leaf_is_split; - - stbuf_ret= -1; - if((flag&8) && done) { - - /* ??? move down from Xorriso_paste_in() : - check whether target does not exist or both are regular */; - - } else if(source_is_dir || !(dir_create || node_count || node_register)) { - ret= Xorriso_handle_collision(xorriso, node, img_path, path, disk_path, - &stbuf_ret, (source_is_dir && !source_is_split)); - if(ret<=0 || ret==3) - goto ex; - } - - new_dir_made= 0; - if(stbuf_ret==-1 && (source_is_dir && !source_is_split) && - !(node_count || node_register)) { - /* make a directory */ - ret= mkdir(path, 0777); - if(ret==-1) { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_msgs_submit(xorriso, 0, disk_path, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, - "While restoring '%s' : could not insert '%s'", disk_path, path); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); - {ret= 0; goto ex;} - } - if(!done) { - /* keep rwx for the owner */ - Xorriso_restore_implicit_properties(xorriso, disk_path, path, - img_path, 4); - } - new_dir_made= 1; - } else if((source_is_dir && !source_is_split)) { - if(!(node_count || node_register)) - Xorriso_auto_chmod(xorriso, path, 0); - } - if(done) { -attach_source:; - - if(flag&1) { - /* directory was created above */; - - } else if(is_dir && !source_is_split) { - - if(!node_register) { - if(new_dir_made) /* keep open and push to Permstack */ - Xorriso_restore_properties(xorriso, disk_path, node, - 2 | !!(flag&64)); - } - if(!(flag&32)) { - ret= Xorriso_restore_tree(xorriso, (IsoDir *) node, img_path, path, - (off_t) 0, NULL, flag & (2 | 64 | (3 << 7))); - if(ret<=0) - goto ex; - if(new_dir_made && !(flag&64)) - /* set timestamps which Permstack_pop() will not set */ - Xorriso_restore_properties(xorriso, disk_path, node, 2); - } - } else { - if(dir_create || node_count) { - xorriso->node_counter++; - } else if(node_register) { - if(xorriso->node_counter < xorriso->node_array_size) { - xorriso->node_array[xorriso->node_counter++]= (void *) node; - iso_node_ref(node); - } - } else { - ret= Xorriso_restore_disk_object(xorriso, img_path, node, path, - offset, bytes, (flag & (2|4|64)) | !!(flag&8)); - if(ret<=0) - goto ex; - } - } - } else - *npt= '/'; - } - Xorriso_process_msg_queues(xorriso,0); - ret= 1 + (is_dir && !leaf_is_split); -ex:; - /* restore exact access permissions of stacked paths */ - hret= Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, - 2 | !!(flag&64)); - if(hret<=0 && hretperm_stack; - - Xorriso_sort_node_array(xorriso, 0); - - disk_path[0]= 0; - for(i= 0; i < xorriso->node_counter; i++) { - node= (IsoNode *) xorriso->node_array[i]; - ret= Xorriso_path_from_node(xorriso, node, img_path, 0); - if(ret < 0) - goto ex; - if(ret == 0) - continue; /* Node is deleted from tree (Should not happen here) */ - hflag= 1; - if(i == 0) { - hflag= 0; - } else if(node != xorriso->node_array[i - 1]) { - hflag= 0; - } - if(hflag == 0) { - img_prefixes= xorriso->node_img_prefixes; - disk_prefixes= xorriso->node_disk_prefixes; - } - ret= Xorriso_make_restore_path(xorriso, &img_prefixes, &disk_prefixes, - img_path, disk_path, hflag); - if(ret<=0) - goto was_problem; - - ret= Xorriso_handle_collision(xorriso, node, img_path, disk_path, disk_path, - &stbuf_ret, 64); - if(ret<=0 || ret==3) - goto was_problem; - if(xorriso->hln_array != NULL && !(xorriso->ino_behavior & 16)) { - /* Eventual lookup of hardlinks will be done in - Xorriso_restore_disk_object() */; - } else if(i > 0 && !(xorriso->ino_behavior & 4)) { - if(Xorriso__findi_sorted_ino_cmp(&(xorriso->node_array[i-1]), - &(xorriso->node_array[i])) == 0) { - if(faulty_family) { - sprintf(xorriso->info_text, "Hardlinking omitted with "); - Text_shellsafe(disk_path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - } else { - /* Try to install hardlink to a sibling */ - ret= Xorriso_restore_prefix_hl(xorriso, node, disk_path, i, 0); - if(ret < 0) { - goto was_problem; - } else if(ret & 1) { - /* Success, hardlink was created */ - xorriso->pacifier_count++; - continue; - } - if(ret & 4) { - /* Found elder siblings, but did not link. */ - ret= Xorriso_eval_problem_status(xorriso, 1, 0); - if(ret < 0) - {ret= 0; goto ex;} - } - } - } else - faulty_family= 0; - } - - ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path, - (off_t) 0, (off_t) 0, - 4 | (xorriso->ino_behavior & 16) | 128); - if(ret<=0) - goto was_problem; - if(ret == 4) { - /* Failed from lack of permission */ - ret= Xorriso_make_accessible(xorriso, disk_path, 0); - if(ret < 0) - goto ex; - ret= Xorriso_restore_disk_object(xorriso, img_path, node, disk_path, - (off_t) 0, (off_t) 0, 4 | (xorriso->ino_behavior & 16)); - if(ret<=0) - goto was_problem; - Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0); - } - - continue; /* regular bottom of loop */ -was_problem:; - faulty_family= 1; - was_failure= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret<0) - goto ex; - Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0); - } - ret= 1; -ex:; - Permstack_pop(&(xorriso->perm_stack), perm_stack_mem, xorriso, 0); - return(ret); -} - - -/* @param flag bit0= -follow, -not: disk_path is not a command parameter -*/ -int Xorriso_paste_in(struct XorrisO *xorriso, char *disk_path, - off_t startbyte, off_t bytecount, char *iso_rr_path, int flag) -{ - int ret; - char eff_source[SfileadrL], eff_dest[SfileadrL], sfe[SfileadrL*5]; - struct stat stbuf; - IsoNode *node; - - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_path, eff_dest, - 2|4); - if(ret<=0) - return(ret); - ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&1)); - if(ret!=0) - return(0); - ret= stat(eff_dest, &stbuf); - if(ret!=-1 && !S_ISREG(stbuf.st_mode)) { - Xorriso_msgs_submit(xorriso, 0, eff_dest, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, - "-paste_in: DISK file %s exists and is not a data file", - Text_shellsafe(eff_source, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - return(0); - } - - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, iso_rr_path, - eff_source, 2); - if(ret<=0) - return(ret); - ret= Xorriso_fake_stbuf(xorriso, eff_source, &stbuf, &node, 4); - if(ret<=0) - return(0); - if(!S_ISREG(stbuf.st_mode)) { - Xorriso_msgs_submit(xorriso, 0, eff_dest, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, "-paste_in: ISO file %s is not a data file", - Text_shellsafe(eff_source, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - return(0); - } - - /* >>> eventually obtain parameters from file name */; - - ret= Xorriso_restore(xorriso, eff_source, eff_dest, startbyte, bytecount, 8); - return(ret); -} - - -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); -} - - -/* @param flag - bit3=report to info channel (else to result channel) -*/ -int Xorriso_toc_line(struct XorrisO *xorriso, int flag) -{ - if(!(flag & 8)) { - Xorriso_result(xorriso,0); - return(1); - } - strcpy(xorriso->info_text, xorriso->result_line); - Xorriso_info(xorriso, 0); - return(1); -} - - -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 - bit1=report about output drive - bit3=report to info channel (else to result channel) - bit4=do no report failure if no drive aquired -*/ -int Xorriso_media_product(struct XorrisO *xorriso, int flag) -{ - int ret, profile_no; - struct burn_drive_info *dinfo; - struct burn_drive *drive; - char *product_id= NULL, *media_code1= NULL, *media_code2= NULL; - char *book_type= NULL, *manuf= NULL, profile_name[80], *respt; - - respt= xorriso->result_line; - - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to print media product info", - flag & (2 | 16)); - if(ret <= 0) - return(ret); - ret= burn_disc_get_media_id(drive, &product_id, &media_code1, &media_code2, - &book_type, 0); - if(ret > 0) { - ret= burn_disc_get_profile(drive, &profile_no, profile_name); - if(ret <= 0) - return(ret); - sprintf(respt, "Media product: %s , ", product_id); - manuf= burn_guess_manufacturer(profile_no, media_code1, media_code2, 0); - if(manuf != NULL) { - if(strncmp(manuf, "Unknown ", 8) == 0) - sprintf(respt + strlen(respt), "(not found in manufacturer list)\n"); - else - sprintf(respt + strlen(respt), "%s\n", manuf); - } else - sprintf(respt + strlen(respt), "(error during manufacturer lookup)\n"); - free(product_id); - free(media_code1); - free(media_code2); - if(book_type != NULL) - free(book_type); - if(manuf != NULL) - free(manuf); - Xorriso_toc_line(xorriso, flag & 8); - } - Xorriso_process_msg_queues(xorriso,0); - - return(1); -} - - -/* @param flag bit0=short report form - bit1=report about output drive - bit2=do not try to read ISO heads - bit3=report to info channel (else to result channel) - bit4=do no report failure if no drive aquired - bit5=only report "Drive current" and "Drive type" - bit6=report "Media product" with bit0 - bit7=only report "Drive current" -*/ -int Xorriso_toc(struct XorrisO *xorriso, int flag) -{ - int num_sessions= 0, num_tracks= 0, lba= 0, nwa= -1, pmin, psec, pframe, ret; - int track_count= 0, session_no, track_no, profile_no= -1, track_size; - int last_track_start= 0, last_track_size= -1, num_data= 0, is_data= 0; - int is_inout_drive= 0, drive_role, status, num_formats, emul_lba; - int num_payload= 0, num_wasted= 0, num_nondata= 0, not_reconizable= 0; - char profile_name[80],*respt,*devadr, *typetext= ""; - struct burn_toc_entry toc_entry; - struct burn_drive_info *dinfo; - struct burn_drive *drive; - enum burn_disc_status s; - char mem_text[80]; - off_t start_byte= 0, num_free= 0, size; - unsigned dummy; - struct isoburn_toc_disc *disc= NULL; - struct isoburn_toc_session **sessions; - struct isoburn_toc_track **tracks; - int image_blocks= 0; - char volume_id[33]; - struct burn_toc_entry next_toc_entry; - - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to print Table Of Content", - flag & (2 | 16)); - if(ret<=0) - {ret= 0; goto ex;} - - respt= xorriso->result_line; - - if(strcmp(xorriso->indev, xorriso->outdev)==0) - is_inout_drive= 1; - if(flag&2) - devadr= xorriso->outdev; - else - devadr= xorriso->indev; - sprintf(respt, "Drive current: %s '%s'\n", - (is_inout_drive ? "-dev" : (flag&2 ? "-outdev" : "-indev")), - devadr); - Xorriso_toc_line(xorriso, flag & 8); - if(flag & 128) - {ret= 1; goto ex;} - sprintf(respt, "Drive type : vendor '%s' product '%s' revision '%s'\n", - dinfo[0].vendor, dinfo[0].product, dinfo[0].revision); - if((flag & 32) | !(flag & 1)) - Xorriso_toc_line(xorriso, flag & 8); - if(flag & 32) - {ret= 1; goto ex;} - - ret= burn_disc_get_profile(drive, &profile_no, profile_name); - s= isoburn_disc_get_status(drive); - if(profile_no == 0x0002 && s == BURN_DISC_EMPTY) - profile_no= 0; - sprintf(respt, "Media current: "); - if (profile_no > 0 && ret > 0) { - if (profile_name[0]) - sprintf(respt+strlen(respt), "%s", profile_name); - else - sprintf(respt+strlen(respt), "%4.4Xh", profile_no); - drive_role= burn_drive_get_drive_role(drive); - if(drive_role==2) - sprintf(respt+strlen(respt), ", overwriteable"); - else if(drive_role==0 || drive_role==3) - sprintf(respt+strlen(respt), ", sequential"); - strcat(respt, "\n"); - } else { - sprintf(respt+strlen(respt), "is not recognizable\n"); - not_reconizable= 1; - } - Xorriso_toc_line(xorriso, flag & 8); - - if((flag & 64) || !(flag & 1)) { - Xorriso_media_product(xorriso, flag & (2 | 8 | 16)); - if(xorriso->request_to_abort) - {ret= 1; goto ex;} - } - - sprintf(respt, "Media status : "); - if (s == BURN_DISC_FULL) { - if(not_reconizable) - sprintf(respt+strlen(respt), "is not recognizable\n"); - else - sprintf(respt+strlen(respt), "is written , is closed\n"); - } else if (s == BURN_DISC_APPENDABLE) { - sprintf(respt+strlen(respt), "is written , is appendable\n"); - } else if (s == BURN_DISC_BLANK) { - sprintf(respt+strlen(respt), "is blank\n"); - } else if (s == BURN_DISC_EMPTY) - sprintf(respt+strlen(respt), "is not present\n"); - else - sprintf(respt+strlen(respt), "is not recognizable\n"); - Xorriso_toc_line(xorriso, flag & 8); - - if(s == BURN_DISC_BLANK) { - sprintf(respt, "Media summary: 0 sessions, 0 data blocks, 0 data"); - num_free= isoburn_disc_available_space(drive, NULL); - Sfile_scale((double) num_free, mem_text,5,1e4,1); - sprintf(respt+strlen(respt), ", %s free\n", mem_text); - Xorriso_toc_line(xorriso, flag & 8); - } - if(s != BURN_DISC_FULL && s != BURN_DISC_APPENDABLE) - {ret= 1; goto ex;} - if(xorriso->request_to_abort) - {ret= 1; goto ex;} - - if(!(flag & 2)) - Xorriso_show_boot_info(xorriso, 1 | (flag & 8) | ((flag & 1) << 1)); - - disc= isoburn_toc_drive_get_disc(drive); - if(flag & 4) - sprintf(respt, "TOC layout : %3s , %9s , %10s\n", - "Idx", "sbsector", "Size"); - else - sprintf(respt, "TOC layout : %3s , %9s , %10s , %s\n", - "Idx", "sbsector", "Size", "Volume Id"); - if(!(flag&1)) - Xorriso_toc_line(xorriso, flag & 8); - - if (disc==NULL) { - Xorriso_process_msg_queues(xorriso,0); - ret= isoburn_get_min_start_byte(drive, &start_byte, 0); - nwa= start_byte / 2048; - if(ret<=0) { - Xorriso_process_msg_queues(xorriso,0); - if(flag&1) - {ret= 0; goto ex;} - sprintf(xorriso->info_text, "Cannot obtain Table Of Content"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - {ret= 0; goto ex;} - } - - /* fabricate TOC */ - typetext= "Other session"; - if(flag & 4) { - ret= 0; - typetext= "Session "; - } else - ret= isoburn_read_iso_head(drive, 0, &image_blocks, volume_id, 1); - if(ret>0) { - sprintf(respt, "ISO session : %3d , %9d , %9ds , %s\n", - 1, 0, image_blocks, volume_id); - nwa= image_blocks; - } else { - nwa= 0; - ret= burn_disc_get_formats(drive, &status, &size, &dummy, - &num_formats); - if(ret>0 && status==BURN_FORMAT_IS_FORMATTED) - nwa= size/2048; - sprintf(respt, "%13s: %3d , %9d , %9ds , \n", - typetext, 1, 0, nwa); - } - if(!(flag&1)) - Xorriso_toc_line(xorriso, flag & 8); - last_track_start= lba; - num_payload= num_data= last_track_size= nwa; - num_sessions= 1; - } else { - sessions= isoburn_toc_disc_get_sessions(disc, &num_sessions); - for (session_no= 0; session_norequest_to_abort); - session_no++) { - tracks= isoburn_toc_session_get_tracks(sessions[session_no], &num_tracks); - if (tracks==NULL) - continue; - for(track_no= 0; track_norequest_to_abort); - track_no++) { - track_count++; - is_data= 0; - isoburn_toc_track_get_entry(tracks[track_no], &toc_entry); - if (toc_entry.extensions_valid & 1) { - /* DVD extension valid */ - lba= toc_entry.start_lba; - track_size= toc_entry.track_blocks; - } else { - lba= burn_msf_to_lba(toc_entry.pmin, toc_entry.psec, - toc_entry.pframe); - if(track_no==num_tracks-1) { - isoburn_toc_session_get_leadout_entry(sessions[session_no], - &next_toc_entry); - } else { - isoburn_toc_track_get_entry(tracks[track_no+1], &next_toc_entry); - } - track_size= burn_msf_to_lba(next_toc_entry.pmin, next_toc_entry.psec, - next_toc_entry.pframe) - lba; - } - if(flag&(1|4)) - ret= 0; - else { - ret= isoburn_toc_track_get_emul(tracks[track_no], &emul_lba, - &image_blocks, volume_id, 0); - if(ret <= 0) - ret= isoburn_read_iso_head(drive, lba, &image_blocks, volume_id, 1); - if(image_blocks > track_size) { - sprintf(xorriso->info_text, - "Session %d bears ISO image size %ds larger than track size %ds", - session_no + 1, image_blocks, track_size); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", - 0); - image_blocks= track_size; - } - } - if(ret>0 && track_no==0) { - sprintf(respt, "ISO session : %3d , %9d , %9ds , %s\n", - session_no+1, lba, image_blocks , volume_id); - } else if(ret>0) { - sprintf(respt, "ISO track : %3d , %9d , %9ds , %s\n", - track_count, lba, image_blocks , volume_id); - } else if(track_no==0) { - typetext= "Other session"; - if(flag & 4) - typetext= "Session "; - sprintf(respt, "%13s: %3d , %9d , %9ds , \n", - typetext, session_no+1, lba, track_size); - } else { - typetext= "Other track "; - if(flag & 4) - typetext= "Track "; - sprintf(respt, "%13s: %3d , %9d , %9ds , \n", - typetext, track_count, lba, track_size); - } - if(!(flag&1)) - Xorriso_toc_line(xorriso, flag & 8); - if(track_no>0) - num_payload+= lba - last_track_start; - last_track_start= lba; - if((toc_entry.control&7)>=4) /* data track */ - is_data= 1; - } - isoburn_toc_session_get_leadout_entry(sessions[session_no], &toc_entry); - if (toc_entry.extensions_valid & 1) { - lba= toc_entry.start_lba; - burn_lba_to_msf(lba, &pmin, &psec, &pframe); - } else { - lba= burn_msf_to_lba(pmin, psec, pframe); - lba= burn_msf_to_lba(toc_entry.pmin, toc_entry.psec, toc_entry.pframe); - } - last_track_size= lba - last_track_start; - num_payload+= last_track_size; - if(is_data) - num_data+= last_track_size; - } - } - if(xorriso->request_to_abort) - {ret= 1; goto ex;} - num_wasted= lba - num_payload; - num_nondata= lba - num_data; - Sfile_scale(((double) num_data) * 2048.0, mem_text,5,1e4,1); - - sprintf(respt, "Media summary: %d session%s, %d data blocks, %s data", - num_sessions, (num_sessions==1 ? "" : "s"), num_data, mem_text); - num_free= isoburn_disc_available_space(drive, NULL); - Sfile_scale((double) num_free, mem_text,5,1e4,1); - sprintf(respt+strlen(respt), ", %s free", mem_text); - - sprintf(respt+strlen(respt), "\n"); - Xorriso_toc_line(xorriso, flag & 8); - - if (s==BURN_DISC_APPENDABLE && nwa!=0) { - ret= isoburn_disc_track_lba_nwa(drive, NULL, 0, &lba, &nwa); - if(ret>0) { - sprintf(respt, "Media nwa : %ds\n", nwa); - if(!(flag&1)) - Xorriso_toc_line(xorriso, flag & 8); - } - } - - if (disc!=NULL) - isoburn_toc_disc_free(disc); - Xorriso_process_msg_queues(xorriso,0); - ret= 1; -ex:; - return(ret); -} - - -int Xorriso_show_devices(struct XorrisO *xorriso, int flag) -{ - char adr[BURN_DRIVE_ADR_LEN]; - int i, j, max_dev_len= 1, pad; - struct burn_drive_info *drive_list= NULL; - unsigned int drive_count; - char *respt, perms[8]; - struct stat stbuf; - - sprintf(xorriso->info_text, "Beginning to scan for devices ...\n"); - Xorriso_info(xorriso,0); - - burn_drive_clear_whitelist(); - while(!burn_drive_scan(&drive_list, &drive_count)) { - Xorriso_process_msg_queues(xorriso,0); - usleep(100000); - } - Xorriso_process_msg_queues(xorriso,0); - if(drive_count <= 0) { - - /* >>> was a drive_list created at all ? */ - /* >>> must it be freed ? */ - - sprintf(xorriso->info_text, "No drives found"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); - return(0); - } - sprintf(xorriso->info_text, "Full drive scan done\n"); - Xorriso_info(xorriso,0); - - sprintf(xorriso->info_text, "-----------------------------------------------------------------------------\n"); - Xorriso_info(xorriso,0); - respt= xorriso->result_line; - for(i= 0; i < drive_count && !(xorriso->request_to_abort); i++) { - if(burn_drive_get_adr(&(drive_list[i]), adr)<=0) - strcpy(adr, "-get_adr_failed-"); - Xorriso_process_msg_queues(xorriso,0); - if(strlen(adr)>max_dev_len) - max_dev_len= strlen(adr); - } - for(i= 0; i < drive_count && !(xorriso->request_to_abort); i++) { - if(burn_drive_get_adr(&(drive_list[i]), adr)<=0) - strcpy(adr, "-get_adr_failed-"); - Xorriso_process_msg_queues(xorriso,0); - if(stat(adr,&stbuf)==-1) { - sprintf(perms,"errno=%d",errno); - } else { - strcpy(perms,"------"); - if(stbuf.st_mode&S_IRUSR) perms[0]= 'r'; - if(stbuf.st_mode&S_IWUSR) perms[1]= 'w'; - if(stbuf.st_mode&S_IRGRP) perms[2]= 'r'; - if(stbuf.st_mode&S_IWGRP) perms[3]= 'w'; - if(stbuf.st_mode&S_IROTH) perms[4]= 'r'; - if(stbuf.st_mode&S_IWOTH) perms[5]= 'w'; - } - sprintf(respt, "%d -dev '%s' ", i, adr); - pad= max_dev_len-strlen(adr); - if(pad>0) - for(j= 0; jinfo_text, "-----------------------------------------------------------------------------\n"); - Xorriso_info(xorriso,0); - - burn_drive_info_free(drive_list); - Xorriso_process_msg_queues(xorriso,0); - return(1); -} - - -int Xorriso_tell_media_space(struct XorrisO *xorriso, - int *media_space, int *free_space, int flag) -{ - int ret; - struct burn_drive_info *dinfo; - struct burn_drive *drive; - struct burn_write_opts *burn_options; - - (*free_space)= (*media_space)= 0; - - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to -tell_media_space", 2); - if(ret<=0) - return(0); - - ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0); - if(ret<=0) - return(-1); - (*free_space)= (*media_space)= - isoburn_disc_available_space(drive, burn_options) / (off_t) 2048; - burn_write_opts_free(burn_options); - - if(xorriso->volset_change_pending) { - ret= Xorriso_write_session(xorriso, 1); - if(ret>0) - (*free_space)-= ret; - } - Xorriso_process_msg_queues(xorriso,0); - return(1); -} - - -/* @param flag bit0= fast - bit1= deformat - bit2= do not re-aquire drive - @return 0=failure, did not touch media , -1=failure, altered media - 1=success, altered media , 2=success, did not touch media -*/ -int Xorriso_blank_media(struct XorrisO *xorriso, int flag) -{ - int ret, do_deformat= 0; - struct burn_drive_info *dinfo; - struct burn_drive *drive; - enum burn_disc_status disc_state; - struct burn_progress p; - double percent = 1.0; - int current_profile; - char current_profile_name[80]; - time_t start_time; - char mode_names[4][80]= {"all", "fast", "deformat", "deformat_quickest"}; - - ret= Xorriso_may_burn(xorriso, 0); - if(ret <= 0) - return(0); - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to -blank", 2); - if(ret<=0) - return(0); - - burn_disc_get_profile(drive, ¤t_profile, current_profile_name); - - disc_state = isoburn_disc_get_status(drive); - if(current_profile == 0x13) { /* overwriteable DVD-RW */ - /* Depending on flag bit1 formatted DVD-RW will get blanked to sequential - state or pseudo blanked by invalidating an eventual ISO image. */ - if(flag&2) - do_deformat= 1; - } else if(current_profile == 0x14) { /* sequential DVD-RW */ - if((flag&1) && !(flag&2)) { - sprintf(xorriso->info_text, - "-blank: DVD-RW present. Mode 'fast' defaulted to mode 'all'."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - sprintf(xorriso->info_text, - "Mode 'deformat_quickest' produces single-session-only media."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0); - flag&= ~1; - } - } else if(disc_state == BURN_DISC_BLANK) { - sprintf(xorriso->info_text,"Blank media detected. Will leave it untouched"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return 2; - } else if(disc_state==BURN_DISC_FULL || disc_state==BURN_DISC_APPENDABLE) { - ; - } else if(disc_state == BURN_DISC_EMPTY) { - sprintf(xorriso->info_text,"No media detected in drive"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return 0; - } else { - sprintf(xorriso->info_text, "Unsuitable drive and media state"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return 0; - } - if(!isoburn_disc_erasable(drive)) { - sprintf(xorriso->info_text, "Media is not of erasable type"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return 0; - } - if(xorriso->do_dummy) { - sprintf(xorriso->info_text, - "-dummy mode prevents blanking of media in mode '%s'.", - mode_names[flag&3]); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(1); - } - sprintf(xorriso->info_text, "Beginning to blank media in mode '%s'.\n", - mode_names[flag&3]); - Xorriso_info(xorriso,0); - - /* Important: do not return until burn_is_aborting() was checked */ - Xorriso_set_signal_handling(xorriso, 1); - - if(do_deformat) - burn_disc_erase(drive, (flag&1)); - else - isoburn_disc_erase(drive, (flag&1)); - start_time= time(0); - usleep(1000000); - while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) { - Xorriso_process_msg_queues(xorriso,0); - if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */ - percent = 1.0 + ((double) p.sector+1.0) / ((double) p.sectors) * 98.0; - sprintf(xorriso->info_text, "Blanking ( %.1f%% done in %d seconds )", - percent, (int) (time(0) - start_time)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0); - usleep(1000000); - } - Xorriso_process_msg_queues(xorriso,0); - if(burn_is_aborting(0)) - Xorriso_abort(xorriso, 0); /* Never comes back */ - Xorriso_set_signal_handling(xorriso, 0); - if(burn_drive_wrote_well(drive)) { - sprintf(xorriso->info_text, "Blanking done\n"); - Xorriso_info(xorriso,0); - } else { - sprintf(xorriso->info_text, "Blanking failed."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } - if(!(flag & 4)) { - ret= Xorriso_reaquire_outdev(xorriso, - 2 + (xorriso->in_drive_handle == xorriso->out_drive_handle)); - if(ret <= 0) - return(-1); - } - return(1); -} - - -/* @param flag bit0= try to achieve faster formatting - bit1= use parameter size (else use default size) - bit2= do not re-aquire drive - bit7= by_index mode: - bit8 to bit15 contain the index of the format to use. - @return 0=failure, did not touch media , -1=failure, altered media - 1=success, altered media , 2=success, did not touch media -*/ -int Xorriso_format_media(struct XorrisO *xorriso, off_t in_size, int flag) -{ - int ret, mode_flag= 0, index, status, num_formats; - unsigned dummy; - struct burn_drive_info *dinfo; - struct burn_drive *drive; - struct burn_progress p; - double percent = 1.0; - int current_profile; - char current_profile_name[80]; - off_t size= 0; - time_t start_time; - enum burn_disc_status disc_state; - - ret= Xorriso_may_burn(xorriso, 0); - if(ret <= 0) - return(0); - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to -format", 2); - if(ret<=0) - return(0); - - if(flag & 2) { - mode_flag= 0; /* format to given size */ - } else { - mode_flag= 4; /* format to full size */ - } - burn_disc_get_profile(drive, ¤t_profile, current_profile_name); - - if(flag&128) { /* by_index */ - index= (flag>>8) & 0xff; - ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats); - if(ret<=0) - num_formats= 0; - if(ret<=0 || index<0 || index>=num_formats) { - if(num_formats>0) - sprintf(xorriso->info_text, - "-format by_index_%d: format descriptors range from index 0 to %d", - index, num_formats-1); - else - sprintf(xorriso->info_text, - "-format by_index_%d: no format descriptors available", index); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - mode_flag|= (flag & 0xff80); - if(flag&1) - mode_flag|= (1<<6); - - } else if(current_profile == 0x12) { /* DVD+RAM */ - if(!(flag & 2)) - mode_flag= 6; /* format to default payload size */ - if(flag&1) - mode_flag|= (1<<6); - - } else if(current_profile == 0x13) { /* DVD-RW */ - if(flag&1) { - sprintf(xorriso->info_text, - "Detected formatted DVD-RW. Thus omitting desired fast format run."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(2); - } - - } else if(current_profile == 0x14) { /* DVD-RW sequential */ - if(flag & 1) { - size= 128*1024*1024; - mode_flag= 1; /* format to size, then write size of zeros */ - } else - mode_flag= 4; - - } else if(current_profile == 0x1a) { /* DVD+RW */ - if(flag&1) { - sprintf(xorriso->info_text, - "Detected DVD+RW. Thus omitting desired fast format run."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(2); - } - - } else if(current_profile == 0x41) { /* BD-R SRM */ - if(!(flag & 2)) - mode_flag= 6; /* format to default payload size */ - if(flag&1) - mode_flag|= (1<<6); - - } else if(current_profile == 0x43) { /* BD-RE */ - if(!(flag & 2)) - mode_flag= 6; /* format to default payload size */ - if(flag&1) - mode_flag|= (1<<6); - - } else { - sprintf(xorriso->info_text, - "-format: Unsuitable media detected."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - sprintf(xorriso->info_text,"Media current: %s (%4.4xh)", - current_profile_name, current_profile); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(0); - } - if(!(flag & 1)) - mode_flag|= 16; /* enable re-formatting */ - - if(xorriso->do_dummy) { - sprintf(xorriso->info_text, "-dummy mode prevents formatting of media."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(1); - } - sprintf(xorriso->info_text, "Beginning to format media.\n"); - Xorriso_info(xorriso, 0); - if(flag & 2) - size= in_size; - - /* Important: do not return until burn_is_aborting() was checked */ - Xorriso_set_signal_handling(xorriso, 1); - - burn_disc_format(drive, size, mode_flag); - - start_time= time(0); - usleep(1000000); - while (burn_drive_get_status(drive, &p) != BURN_DRIVE_IDLE) { - Xorriso_process_msg_queues(xorriso,0); - if(p.sectors>0 && p.sector>=0) /* display 1 to 99 percent */ - percent = 1.0 + ((double) p.sector+1.0) / ((double) p.sectors) * 98.0; - sprintf(xorriso->info_text, "Formatting ( %.1f%% done in %d seconds )", - percent, (int) (time(0) - start_time)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0); - usleep(1000000); - } - Xorriso_process_msg_queues(xorriso,0); - if(burn_is_aborting(0)) - Xorriso_abort(xorriso, 0); /* Never comes back */ - Xorriso_set_signal_handling(xorriso, 0); - - if(burn_drive_wrote_well(drive)) { - sprintf(xorriso->info_text, "Formatting done\n"); - Xorriso_info(xorriso,0); - } else { - sprintf(xorriso->info_text, - "libburn indicates failure with formatting."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(-1); - } - - if(!(flag & 4)) { - ret= Xorriso_reaquire_outdev(xorriso, - 2 + (xorriso->in_drive_handle == xorriso->out_drive_handle)); - if(ret <= 0) - return(-1); - } - disc_state = isoburn_disc_get_status(drive); - if(disc_state==BURN_DISC_FULL && !(flag&1)) { - /* Blank because full format certification pattern might be non-zero */ - ret= Xorriso_blank_media(xorriso, 1); - if(ret <= 0) - return(0); - } - return(1); -} - - -/* @param flag bit2= formatting rather than blanking - @return 0=failure, did not touch media , -1=failure, altered media - 1=success, altered media , 2=success, did not touch media -*/ -int Xorriso_blank_as_needed(struct XorrisO *xorriso, int flag) -{ - int ret, is_formatted= -1, status, num_formats, did_work= 0; - struct burn_drive_info *dinfo; - struct burn_drive *drive; - enum burn_disc_status disc_state; - unsigned dummy; - int current_profile; - char current_profile_name[80]; - off_t size; - - ret= Xorriso_may_burn(xorriso, 0); - if(ret <= 0) - return(0); - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to blank or format", 2); - if(ret<=0) - return(0); - - burn_disc_get_profile(drive, ¤t_profile, current_profile_name); - - ret= burn_disc_get_formats(drive, &status, &size, &dummy, &num_formats); - if(ret>0) { - if(status==BURN_FORMAT_IS_FORMATTED) - is_formatted= 1; - else if(status == BURN_FORMAT_IS_UNFORMATTED) - is_formatted= 0; - } - if(current_profile == 0x12 || current_profile == 0x43) { /* DVD+RAM , BD-RE */ - if(is_formatted<0) { - sprintf(xorriso->info_text, - "-blank or -format: Unclear formatting status of %s", - current_profile_name); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - if(!is_formatted) { - ret= Xorriso_format_media(xorriso, (off_t) 0, (current_profile == 0x43)); - if(ret <= 0) - return(ret); - did_work= (ret == 1); - } - } else if(current_profile == 0x14 && (flag&4)) { /* DVD-RW sequential */ - ret= Xorriso_format_media(xorriso, (off_t) 0, 0); - if(ret <= 0) - return(ret); - did_work= (ret == 1); - } else if(current_profile == 0x41) { /* BD-R SRM */ - if(!is_formatted) { - ret= Xorriso_format_media(xorriso, (off_t) 0, 1); - if(ret <= 0) - return(ret); - did_work= (ret == 1); - } - } - - disc_state = isoburn_disc_get_status(drive); - if(disc_state != BURN_DISC_BLANK && !(flag&4)) { - ret= Xorriso_blank_media(xorriso, 1); - return(ret); - } - if(did_work) - return(1); - sprintf(xorriso->info_text, "%s as_needed: no need for action detected", - (flag&4) ? "-format" : "-blank"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(2); -} - - -/* @return <=0 error, 1 success -*/ -int Xorriso_list_formats(struct XorrisO *xorriso, int flag) -{ - int ret, i, status, num_formats, profile_no, type; - off_t size; - unsigned dummy; - char status_text[80], profile_name[90], *respt; - struct burn_drive_info *dinfo; - struct burn_drive *drive; - - respt= xorriso->result_line; - - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to obtain format descriptor list", 1 | 2); - if(ret<=0) - return(0); - if(ret == 2) - goto ex; - ret = burn_disc_get_formats(drive, &status, &size, &dummy, - &num_formats); - if(ret<=0) { - sprintf(xorriso->info_text, "Cannot obtain format list info"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - ret= Xorriso_toc(xorriso, 3); - if(ret<=0) - goto ex; - ret= burn_disc_get_profile(drive, &profile_no, profile_name); - if(ret<=0) - goto ex; - - if(status == BURN_FORMAT_IS_UNFORMATTED) - sprintf(status_text, "unformatted, up to %.1f MiB", - ((double) size) / 1024.0 / 1024.0); - else if(status == BURN_FORMAT_IS_FORMATTED) { - if(profile_no==0x12 || profile_no==0x13 || profile_no==0x1a || - profile_no==0x43) - sprintf(status_text, "formatted, with %.1f MiB", - ((double) size) / 1024.0 / 1024.0); - else - sprintf(status_text, "written, with %.1f MiB", - ((double) size) / 1024.0 / 1024.0); - } else if(status == BURN_FORMAT_IS_UNKNOWN) { - if (profile_no > 0) - sprintf(status_text, "intermediate or unknown"); - else - sprintf(status_text, "no media or unknown media"); - } else - sprintf(status_text, "illegal status according to MMC-5"); - sprintf(respt, "Format status: %s\n", status_text); - Xorriso_result(xorriso,0); - - for (i= 0; i < num_formats; i++) { - ret= burn_disc_get_format_descr(drive, i, &type, &size, &dummy); - if (ret <= 0) - continue; - sprintf(respt, "Format idx %-2d: %2.2Xh , %.fs , %.1f MiB\n", - i, type, ((double) size) / 2048.0, ((double) size) / 1024.0/1024.0); - Xorriso_result(xorriso,0); - } - ret= 1; -ex:; - return(ret); -} - - -/* @param flag bit0= cdrecord style - bit1= obtain outdrive, else indrive - @return <=0 error, 1 success -*/ -int Xorriso_list_profiles(struct XorrisO *xorriso, int flag) -{ - int ret, i; - struct burn_drive_info *dinfo; - struct burn_drive *drive; - int num_profiles, profiles[64]; - char is_current[64], profile_name[90], *respt; - - respt= xorriso->result_line; - - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to obtain profile list", 1 | (flag & 2)); - if(ret<=0) - return(0); - burn_drive_get_all_profiles(drive, &num_profiles, profiles, is_current); - for(i= 0; i < num_profiles; i++) { - ret= burn_obtain_profile_name(profiles[i], profile_name); - if(ret <= 0) - strcpy(profile_name, "unknown"); - sprintf(respt, "%s 0x%4.4X (%s)%s\n", - flag & 1 ? "Profile:" : "Profile :", - (unsigned int) profiles[i], - profile_name, is_current[i] ? " (current)" : ""); - Xorriso_result(xorriso,0); - } - return(1); -} - - -int Xorriso_cannot_create_iter(struct XorrisO *xorriso, int iso_error,int flag) -{ - Xorriso_process_msg_queues(xorriso,0); - Xorriso_report_iso_error(xorriso, "", iso_error, "Cannot create iter", 0, - "FATAL", 1); - sprintf(xorriso->info_text, "Cannot create IsoDirIter object"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - return(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); -} - -/* The caller shall make no assumptions about the meaning of iter, node_array, - node_count, node_idx ! They are just opaque handles for which the caller - provides the memory of proper type. - @param flag bit0= initialize iteration - bit1= action needs full freedom of object manipulation - bit2= action needs LBA sorted iteration - bit31= end iteration (mandatory !) -*/ -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 ret, i; - IsoNode *node; - off_t new_mem= 0; - char mem_text[80], limit_text[80]; - - if(flag&1) { - *node_array= NULL; - *node_count= -1; - *node_idx= 0; - *iter= NULL; - ret= iso_dir_get_children(dir_node, iter); - if(ret<0) { -cannot_iter:; - Xorriso_cannot_create_iter(xorriso, ret, 0); - return(-1); - } - if((flag&2)|(flag&4)) { - /* copy list of nodes and prepare soft iterator */ - *node_count= 0; - while(iso_dir_iter_next(*iter, &node) == 1) - (*node_count)++; - iso_dir_iter_free(*iter); - *iter= NULL; - - new_mem= ((*node_count)+1) * sizeof(IsoNode *); - if(new_mem > xorriso->temp_mem_limit) { - Sfile_scale((double) new_mem, mem_text, 5,1e4, 0); - Sfile_scale((double) xorriso->temp_mem_limit, limit_text, 5,1e4, 0); - sprintf(xorriso->info_text, - "Stacked directory snapshots exceed -temp_mem_limit (%s > %s)", - mem_text, limit_text); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - *node_count= -1; - return(-1); - } - (*node_array)= (IsoNode **) calloc((*node_count)+1, sizeof(IsoNode *)); - if(*node_array == NULL) { - sprintf(xorriso->info_text, - "Could not allocate inode list of %.f bytes", - ((double) (*node_count)+1) * (double) sizeof(IsoNode *)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - *node_count= -1; - return(-1); - } - *mem= new_mem; - ret= iso_dir_get_children(dir_node, iter); - if(ret<0) - goto cannot_iter; - while(iso_dir_iter_next(*iter, &node) == 1 && *node_idx < *node_count) { - (*node_array)[*node_idx]= node; - iso_node_ref(node); - (*node_idx)++; - } - iso_dir_iter_free(*iter); - *iter= NULL; - *node_count= *node_idx; - *node_idx= 0; - if((flag&4) && *node_count>1) - qsort(*node_array, *node_count, sizeof(IsoNode *), - Xorriso__node_lba_cmp); - } - } - - if(flag&(1<<31)) { - if(*node_count>=0 && *node_array!=NULL) { - for(i= 0; i<*node_count; i++) - iso_node_unref((*node_array)[i]); - free(*node_array); - *node_array= NULL; - *node_count= -1; - *node_idx= 0; - } else { - if(*iter!=NULL) - iso_dir_iter_free(*iter); - *iter= NULL; - } - } - - if(flag&(1|(1<<31))) - return(1); - if(*node_count>=0) { - /* return next node_array element */ - if(*node_idx>=*node_count) - return(0); - *iterated_node= (*node_array)[*node_idx]; - (*node_idx)++; - } else { - ret= iso_dir_iter_next(*iter, iterated_node); - return(ret == 1); - } - return(1); -} - - -/* @param boss_iter If not NULL then this is an iterator suitable for - iso_dir_iter_remove() which is then to be used instead - of iso_node_remove(). - @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 - bit6= do not delete eventually existing node from di_array - @return <=0 = error - 1 = removed simple node - 2 = removed directory or tree - 3 = did not remove on user revocation -*/ -int Xorriso_rmi(struct XorrisO *xorriso, void *boss_iter, off_t boss_mem, - char *path, int flag) -{ - int ret, is_dir= 0, pl, not_removed= 0, fret; - IsoNode *victim_node, *node; - IsoDir *boss_node, *root_dir; - IsoDirIter *iter= NULL; - IsoImage *volume; - char *sub_name, *name; - char *sfe= NULL, *sub_path= NULL; - off_t mem; - IsoNode **node_array= NULL; - int node_count= 0, node_idx; - - /* Avoiding large local memory objects in order to save stack space */ - sfe= malloc(5*SfileadrL); - sub_path= malloc(2*SfileadrL); - if(sfe==NULL || sub_path==NULL) { - Xorriso_no_malloc_memory(xorriso, &sfe, 0); - {ret= -1; goto ex;} - } - -#ifndef Libisofs_iso_dir_iter_sufficienT - /* Ticket 127: A80301 - A80302 - I do not not deem IsoDirIter safe for node list manipulations. - The parameter boss_iter once was intended to allow such but - has now been downgraded to a mere check for eventual programming bugs. - */ - if(boss_iter!=NULL) { - sprintf(xorriso->info_text, - "Program error: Xorriso_rmi() was requested to delete iterated node %s", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - ret= -1; goto ex; - } -#endif /* Libisofs_iso_dir_iter_sufficienT */ - - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - goto ex; - - if(Xorriso_much_too_long(xorriso, strlen(path), 0)<=0) - {ret= 0; goto ex;} - ret= Xorriso_node_from_path(xorriso, volume, path, &victim_node, 0); - if(ret<=0) - goto ex; - root_dir= iso_image_get_root(volume); - if(((void *) root_dir) == ((void *) victim_node)) { - sprintf(xorriso->info_text, "May not delete root directory"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - - if(LIBISO_ISDIR(victim_node)) - is_dir= 1; - if(!is_dir) { - if(flag&2) { /* rmdir */ - sprintf(xorriso->info_text, "%s in loaded ISO image is not a directory", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - } else { - if(flag&1) { /* rm -r */ - if((xorriso->do_reassure==1 && !xorriso->request_not_to_ask) || - (flag&32)) { - /* Iterate over subordinates and delete them */ - mem= boss_mem; - - ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, - &iter, &node_array, &node_count, &node_idx, - &node, 1|2); - if(ret<=0) { -cannot_create_iter:; - Xorriso_cannot_create_iter(xorriso, ret, 0); - ret= -1; goto ex; - } - pl= strlen(path); - strcpy(sub_path, path); - if(pl==0 || sub_path[pl-1]!='/') { - sub_path[pl++]= '/'; - sub_path[pl]= 0; - } - sub_name= sub_path+pl; - while(1) { - ret= Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, &iter, - &node_array, &node_count, &node_idx, &node, 0); - if(ret<0) - goto ex; - if(ret==0 || xorriso->request_to_abort) - break; - name= (char *) iso_node_get_name(node); - if(Xorriso_much_too_long(xorriso, pl+1+strlen(name), 0)<=0) - {ret= 0; goto rm_r_problem_handler;} - strcpy(sub_name, name); - ret= Xorriso_rmi(xorriso, iter, mem, sub_path, - (flag & ( 1 | 2 | 8 | 16 | 64)) | 4); - if(ret==3 || ret<=0 || xorriso->request_to_abort) { -rm_r_problem_handler:; - not_removed= 1; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret<0) - goto dir_not_removed; - } - } - if(flag&32) - {ret= 2; goto ex;} - - if(not_removed) { -dir_not_removed:; - sprintf(xorriso->info_text, "Directory not removed: %s", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - if(ret>0) - ret= 3; - goto ex; - } - } - } else { - if(!(flag&2)) { /* not rmdir */ - sprintf(xorriso->info_text, "%s in loaded ISO image is a directory", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - - ret= iso_dir_get_children((IsoDir *) victim_node, &iter); - Xorriso_process_msg_queues(xorriso,0); - if(ret<0) - goto cannot_create_iter; - if(ret>0) { - if(iso_dir_iter_next(iter, &node) == 1) { - sprintf(xorriso->info_text, - "Directory not empty on attempt to delete: %s", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - } - } - } - - if(xorriso->request_to_abort) - {ret= 3; goto ex;} - boss_node= iso_node_get_parent(victim_node); - Xorriso_process_msg_queues(xorriso,0); - if(boss_node==NULL) { - sprintf(xorriso->info_text, - "Cannot find parent node of %s in loaded ISO image", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - - while((xorriso->do_reassure==1 || (xorriso->do_reassure==2 && !(flag&4))) - && !xorriso->request_not_to_ask) { - /* ls -ld */ - Xorriso_ls_filev(xorriso, xorriso->wdi, 1, &path, (off_t) 0, 1|2|8); - if(is_dir) /* du -s */ - Xorriso_ls_filev(xorriso, xorriso->wdi, 1, &path, (off_t) 0, 2|4); - if(flag&8) - sprintf(xorriso->info_text, - "File exists. Remove ? n= keep old, y= remove, x= abort, @= stop asking\n"); - else - sprintf(xorriso->info_text, - "Remove above file ? n= keep it, y= remove it, x= abort, @= stop asking\n"); - Xorriso_info(xorriso, 4); - ret= Xorriso_request_confirmation(xorriso, 1|2|4|16); - if(ret<=0) - goto ex; - if(xorriso->request_to_abort) { - sprintf(xorriso->info_text, - "Removal operation aborted by user before file: %s", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - ret= 3; goto ex; - } - if(ret==3) - continue; - if(ret==6) /* yes */ - break; - if(ret==4) { /* yes, do not ask again */ - xorriso->request_not_to_ask= 1; - break; - } - if(ret==1) { /* no */ - sprintf(xorriso->info_text, "Kept in existing state: %s", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - ret= 3; goto ex; - } - } - - if(!(flag & 64)) - Xorriso_invalidate_di_item(xorriso, victim_node, 0); - -#ifdef Libisofs_iso_dir_iter_sufficienT - - if(boss_iter!=NULL) { - ret= iso_dir_iter_remove((IsoDirIter *) boss_iter); - if(ret<0) - ret= -1; - } else - ret= iso_node_remove(victim_node); - -#else /* ! Libisofs_iso_dir_iter_sufficienT */ - - ret= iso_node_remove(victim_node); - -#endif /* Libisofs_iso_dir_iter_sufficienT */ - - Xorriso_process_msg_queues(xorriso,0); - if(ret<0) { - Xorriso_report_iso_error(xorriso, path, ret, "Cannot remove node", 0, - "FATAL", 1); - sprintf(xorriso->info_text, - "Internal failure to remove %s from loaded ISO image", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - ret= -1; goto ex; - } - - if(flag&16) - xorriso->pacifier_count++; - Xorriso_set_change_pending(xorriso, 0); - ret= 1+!!is_dir; -ex:; - if(sfe!=NULL) - free(sfe); - if(sub_path!=NULL) - free(sub_path); - Xorriso_findi_iter(xorriso, (IsoDir *) victim_node, &mem, &iter, - &node_array, &node_count, &node_idx, &node, (1<<31)); - return(ret); -} - - -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); -} - - -/* @param flag bit0= do not only sum up sizes but also print subdirs -*/ -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 i, ret, no_sort= 0, filec= 0, l; - IsoDirIter *iter= NULL; - IsoNode *node, **node_array= NULL; - char *name; - off_t sub_size, report_size, mem= 0; - char *path= NULL, *show_path= NULL, *sfe= NULL; - - sfe= malloc(5*SfileadrL); - path= malloc(SfileadrL); - show_path= malloc(SfileadrL); - if(path==NULL || show_path==NULL || sfe==NULL) { - Xorriso_no_malloc_memory(xorriso, &sfe, 0); - {ret= -1; goto ex;} - } - - *size= 0; - ret= iso_dir_get_children(dir_node, &iter); - if(ret<0) { -cannot_create_iter:; - Xorriso_cannot_create_iter(xorriso, ret, 0); - {ret= -1; goto ex;} - } - for(i= 0; iso_dir_iter_next(iter, &node) == 1; ) { - sub_size= 0; - name= (char *) iso_node_get_name(node); - strcpy(show_path, rel_path); - if(Sfile_add_to_path(show_path, name, 0)<=0) - goto much_too_long; - if(LIBISO_ISDIR(node)) { - strcpy(path, abs_path); - if(Sfile_add_to_path(path, name, 0)<=0) { -much_too_long:; - Xorriso_much_too_long(xorriso, strlen(path)+strlen(name)+1, 2); - {ret= -1; goto ex;} - } - filec++; - l= strlen(rel_path)+1; - mem+= l; - if(l % sizeof(char *)) - mem+= sizeof(char *)-(l % sizeof(char *)); - if(flag&1) /* diving and counting is done further below */ - continue; - ret= Xorriso_show_du_subs(xorriso, (IsoDir *) node, - path, show_path, &sub_size, boss_mem, 0); - if(ret<0) - goto ex; - if(ret==0) - continue; - } - - if(LIBISO_ISREG(node)) { - sub_size+= iso_file_get_size((IsoFile *) node)+2048; -/* - sub_size+= iso_file_get_size((IsoFile *) node)+strlen(name)+1; -*/ - } - - if(sub_size>0) - (*size)+= sub_size; - Xorriso_process_msg_queues(xorriso,0); - } - - if(filec<=0 || !(flag&1)) - {ret= 1; goto ex;} - - /* Reset iteration */ - iso_dir_iter_free(iter); - iter= NULL; - Xorriso_process_msg_queues(xorriso,0); - - ret= Xorriso_sorted_node_array(xorriso, dir_node, &filec, &node_array, - boss_mem, 1|2|4); - if(ret<0) - goto ex; - if(ret==0) { - no_sort= 1; - ret= iso_dir_get_children(dir_node, &iter); - if(ret<0) - goto cannot_create_iter; - } - - for(i= 0; (no_sort || irequest_to_abort); i++) { - if(no_sort) { - ret= iso_dir_iter_next(iter, &node); - if(ret!=1) - break; - if(!LIBISO_ISDIR(node)) - continue; - } else - node= node_array[i]; - - sub_size= 0; - name= (char *) iso_node_get_name(node); - strcpy(show_path, rel_path); - if(Sfile_add_to_path(show_path, name, 0)<=0) - goto much_too_long; - strcpy(path, abs_path); - if(Sfile_add_to_path(path, name, 0)<=0) - goto much_too_long; - ret= Xorriso_show_du_subs(xorriso, (IsoDir *) node, - path, show_path, &sub_size, boss_mem+mem, flag&1); - if(ret<0) - goto ex; - - if(LIBISO_ISREG(node)) { - sub_size+= iso_file_get_size((IsoFile *) node)+2048; -/* - sub_size+= iso_tree_node_get_size((IsoFile *) node)+strlen(name)+1; -*/ - } - if(sub_size>0) - (*size)+= sub_size; - report_size= sub_size/1024; - if(report_size*1024result_line, "%7.f ",(double) (report_size)); - sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n", - Text_shellsafe(show_path, sfe, 0)); - Xorriso_result(xorriso, 0); - } - ret= 1; -ex:; - if(sfe!=NULL) - free(sfe); - if(path!=NULL) - free(path); - if(show_path!=NULL) - free(show_path); - if(iter!=NULL) - iso_dir_iter_free(iter); - if(node_array!=NULL) - free((char *) node_array); - Xorriso_process_msg_queues(xorriso,0); - return(ret); -} - - -int Xorriso_sorted_dir_i(struct XorrisO *xorriso, IsoDir *dir_node, - int *filec, char ***filev, off_t boss_mem, int flag) -{ - int i,j,ret; - IsoDirIter *iter= NULL; - IsoNode *node; - char *name; - off_t mem; - - (*filec)= 0; - (*filev)= NULL; - - ret= iso_dir_get_children(dir_node, &iter); - if(ret<0) { -cannot_iter:; - Xorriso_cannot_create_iter(xorriso, ret, 0); - {ret= -1; goto ex;} - } - mem= 0; - for(i= 0; iso_dir_iter_next(iter, &node) == 1; ) { - name= (char *) iso_node_get_name(node); - mem+= sizeof(char *)+strlen(name)+8; - (*filec)++; - } - iso_dir_iter_free(iter); - iter= NULL; - if(*filec==0) - {ret= 1; goto ex;} - - ret= Xorriso_check_temp_mem_limit(xorriso, mem+boss_mem, 2); - if(ret<=0) - goto ex; - (*filev)= (char **) calloc(*filec, sizeof(char *)); - if(*filev==NULL) - {ret= -1; goto ex; } - ret= iso_dir_get_children(dir_node, &iter); - if(ret<0) - goto cannot_iter; - for(i= 0; i<*filec; i++) { - ret= iso_dir_iter_next(iter, &node); - if(ret!=1) - break; - name= (char *) iso_node_get_name(node); - (*filev)[i]= strdup(name); - if((*filev)[i]==NULL) { - for(j= 0; jresult_line; - - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - return(ret); - - Sort_argv(filec, filev, 0); - - /* Count valid nodes, warn of invalid ones */ - for(i= 0; iinfo_text, "Not found in ISO image: %s", - Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - was_error++; - continue; - } - } - - if((flag&8) && !(flag&(2|4))) { - sprintf(xorriso->info_text, "Valid ISO nodes found: %d\n", filec-was_error); - Xorriso_info(xorriso,1); - if(filec-was_error<=0) - return(!was_error); - } - - passes= 1+!(flag&(4|8)); - for(pass= 0; passrequest_to_abort); i++) { - rpt[0]= 0; - ret= Xorriso_make_abs_adr(xorriso, wd, filev[i], path, 1|2|4); - if(ret<=0) - continue; - ret= Xorriso_fake_stbuf(xorriso, path, &stbuf, &node, ((flag&4) >> 1) | 16); - if(ret<=0) - continue; - if(LIBISO_ISDIR(node) && !(flag&(4|8))) { - if(pass==0) - continue; - if(filec>1) { - strcpy(xorriso->result_line, "\n"); - Xorriso_result(xorriso,0); - sprintf(xorriso->result_line, "%s:\n", Text_shellsafe(filev[i], sfe,0)); - Xorriso_result(xorriso,0); - } - ret= Xorriso_sorted_dir_i(xorriso, - (IsoDir *) node, &dfilec, &dfilev, boss_mem, 0); - if(ret<=0) { - - /* >>> libisofs iterator loop and single item Xorriso_lsx_filev() */; - - } else { - if(flag&1) { - sprintf(xorriso->result_line, "total %d\n", dfilec); - Xorriso_result(xorriso,0); - } - Xorriso_ls_filev(xorriso, path, - dfilec, dfilev, boss_mem, (flag&1)|2|8); - } - if(dfilec>0) - Sfile_destroy_argv(&dfilec, &dfilev, 0); - continue; - } else - if(pass>0) - continue; - link_target[0]= 0; - if((flag&5)==1) { /* -ls_l */ - iso_node_get_acl_text(node, &a_text, &d_text, 16); - ret= Xorriso_format_ls_l(xorriso, &stbuf, - 1 | ((a_text != NULL || d_text != NULL) << 1)); - iso_node_get_acl_text(node, &a_text, &d_text, 1 << 15); - if(ret<=0) - continue; - if(LIBISO_ISLNK(node)) { - if(Sfile_str(link_target, (char *) iso_symlink_get_dest( - (IsoSymlink *) node), 0)<=0) - link_target[0]= 0; - } - } else if(flag&4) { /* -du or -dus */ - size= stbuf.st_size; - if(S_ISDIR(stbuf.st_mode)) { - ret= Xorriso_show_du_subs(xorriso, (IsoDir *) node, - path, filev[i], &size, boss_mem, flag&1); - if(ret<0) - return(-1); - if(ret==0) - continue; - } - sprintf(rpt, "%7.f ",(double) (size/1024)); - } - if(link_target[0] && (flag&5)==1) - sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s -> %s\n", - Text_shellsafe(filev[i], sfe, 0), - Text_shellsafe(link_target, sfe2, 0)); - else - sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n", - Text_shellsafe(filev[i], sfe, 0)); - Xorriso_result(xorriso, 0); - } - return(!was_error); -} - - -/* This function needs less buffer memory than Xorriso_ls_filev() but cannot - perform structured pattern matching as done by Xorriso_expand_pattern() - for subsequent Xorriso_ls_filev(). - @param flag bit0= long format - bit1= only check for directory existence - bit2= do not apply search pattern but accept any file - bit3= just count nodes and return number -*/ -int Xorriso_ls(struct XorrisO *xorriso, int flag) -{ - int ret, is_dir= 0, i, filec= 0, failed_at, no_sort= 0; - IsoNode *node, **node_array= NULL; - IsoDir *dir_node; - IsoImage *volume; - IsoDirIter *iter= NULL; - char sfe[5*SfileadrL], sfe2[5*SfileadrL], link_target[SfileadrL], *npt, *rpt; - struct stat stbuf; - - rpt= xorriso->result_line; - - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - return(ret); - - ret= Xorriso_node_from_path(xorriso, volume, xorriso->wdi, &node, 0); - if(ret<=0) - goto wdi_is_not_a_dir; - if(LIBISO_ISDIR(node)) - is_dir= 1; - if(!is_dir) { -wdi_is_not_a_dir:; - sprintf(xorriso->info_text, - "Working directory path does not lead to a directory in ISO image"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - if(flag&2) - {ret= 1; goto ex;} - - dir_node= (IsoDir *) node; - ret= iso_dir_get_children(dir_node, &iter); - if(ret<0) { -cannot_create_iter:; - Xorriso_cannot_create_iter(xorriso, ret, 0); - {ret= -1; goto ex;} - } - Xorriso_process_msg_queues(xorriso,0); - - for(i= 0; iso_dir_iter_next(iter, &node) == 1; ) { - npt= (char *) iso_node_get_name(node); - if(!(flag&4)) { - ret= Xorriso_regexec(xorriso, npt, &failed_at, 0); - if(ret) - continue; /* no match */ - } - filec++; - } - /* Reset iteration */ - iso_dir_iter_free(iter); - iter= NULL; - Xorriso_process_msg_queues(xorriso,0); - if(flag&8) - {ret= filec; goto ex;} - sprintf(xorriso->info_text, "Valid ISO nodes found: %d\n", filec); - Xorriso_info(xorriso,1); - - ret= Xorriso_sorted_node_array(xorriso, dir_node, &filec, &node_array, 0, - flag&4); - if(ret<0) - goto ex; - if(ret==0) { - no_sort= 1; - ret= iso_dir_get_children(dir_node, &iter); - if(ret<0) - goto cannot_create_iter; - } - - for(i= 0; irequest_to_abort); i++) { - if(no_sort) { - ret= iso_dir_iter_next(iter, &node); - if(ret!=1) - break; - npt= (char *) iso_node_get_name(node); - if(!(flag&4)) { - ret= Xorriso_regexec(xorriso, npt, &failed_at, 0); - if(ret) - continue; /* no match */ - } - } else - node= node_array[i]; - - npt= (char *) iso_node_get_name(node); - link_target[0]= 0; - if(LIBISO_ISLNK(node)) { - if(Sfile_str(link_target, (char *) iso_symlink_get_dest( - (IsoSymlink *) node), 0)<=0) - link_target[0]= 0; - } - rpt[0]= 0; - if(flag&1) { - ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1); - if(ret<=0) - continue; - ret= Xorriso_format_ls_l(xorriso, &stbuf, 1); - if(ret<=0) - continue; - } - if(link_target[0] && (flag&1)) - sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s -> %s\n", - Text_shellsafe(npt, sfe, 0), - Text_shellsafe(link_target, sfe2, 0)); - else - sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n", - Text_shellsafe(npt, sfe, 0)); - Xorriso_result(xorriso, 0); - } - - ret= 1; -ex:; - if(iter!=NULL) - iso_dir_iter_free(iter); - Xorriso_process_msg_queues(xorriso,0); - if(node_array!=NULL) - free((char *) node_array); - 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 -*/ -int Xorriso_rename(struct XorrisO *xorriso, void *boss_iter, - char *origin, char *dest, int flag) -{ - int ret, ol, dest_ret; - char sfe[5*SfileadrL], eff_dest[SfileadrL], dir_adr[SfileadrL], *cpt; - char *leafname, eff_origin[SfileadrL], sfe2[5*SfileadrL], *old_leafname; - IsoImage *volume; - IsoDir *origin_dir, *dest_dir; - IsoNode *node, *iso_node; - -#ifndef Libisofs_iso_dir_iter_sufficienT - /* Ticket 127: A80301 - A80302 - I do not not deem IsoDirIter safe for node list manipulations. - The parameter boss_iter once was intended to allow such but - has now been downgraded to a mere check for eventual programming bugs. - */ - if(boss_iter!=NULL) { - sprintf(xorriso->info_text, - "Program error: Xorriso_rename() was requested to delete iterated node %s", - Text_shellsafe(origin, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - return(-1); - } -#endif /* Libisofs_iso_dir_iter_sufficienT */ - - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, origin, eff_origin, 0); - if(ret<=0) - return(ret); - dest_ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, dest, eff_dest,1); - if(dest_ret<0) - return(dest_ret); - if(dest_ret==0) { /* obtain eff_dest address despite it does not exist */ - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, dest, eff_dest, 2); - if(ret<=0) - return(ret); - } - - /* Prevent that destination is a subordinate of origin - (that would be a black hole plopping out of the universe) */ - ol= strlen(eff_origin); - if(ol==0) { - sprintf(xorriso->info_text, "May not rename root directory"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } else if(strcmp(eff_origin, eff_dest)==0) { - sprintf(xorriso->info_text, "Ignored attempt to rename %s to itself", - Text_shellsafe(eff_origin,sfe,0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - return(0); - } else if(strncmp(eff_origin, eff_dest, ol)==0 && - (eff_dest[ol]==0 || eff_dest[ol]=='/')) { - sprintf(xorriso->info_text, - "May not rename %s to its own sub address %s", - Text_shellsafe(eff_origin,sfe,0), Text_shellsafe(eff_dest,sfe2,0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - - /* Check whether destination exists and may be not overwriteable */ - if(dest_ret==2 && xorriso->do_overwrite!=1) { - sprintf(xorriso->info_text, "Renaming may not overwrite directory: %s", - Text_shellsafe(eff_dest, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } else if (dest_ret==1 && !xorriso->do_overwrite) { - sprintf(xorriso->info_text, "Renaming may not overwite: %s", - Text_shellsafe(eff_dest, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } else if(dest_ret>0) { - ret= Xorriso_rmi(xorriso, boss_iter, (off_t) 0, eff_dest, 1|8); - if(ret<=0) - return(0); - if(ret==3) { - sprintf(xorriso->info_text, "User revoked renaming of: %s", - Text_shellsafe(eff_origin, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - return(0); - } - } - - /* Ensure existence of destination directory */ - strcpy(dir_adr, eff_dest); - cpt= strrchr(dir_adr, '/'); - if(cpt==NULL) - cpt= dir_adr+strlen(dir_adr); - *cpt= 0; - if(dir_adr[0]!=0) { - ret= Xorriso_graft_in(xorriso, boss_iter, NULL, dir_adr, - (off_t) 0, (off_t) 0, 1); - if(ret<=0) - return(ret); - } - - /* Move node */ - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - return(ret); - Xorriso_node_from_path(xorriso, volume, dir_adr, &iso_node, 0); - dest_dir= (IsoDir *) iso_node; - strcpy(dir_adr, eff_origin); - cpt= strrchr(dir_adr, '/'); - if(cpt==NULL) - cpt= dir_adr+strlen(dir_adr); - *cpt= 0; - Xorriso_node_from_path(xorriso, volume, dir_adr, &iso_node, 0); - origin_dir= (IsoDir *) iso_node; - Xorriso_node_from_path(xorriso, volume, eff_origin, &node, 0); - if(dest_dir==NULL || origin_dir==NULL || node==NULL) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, - "Internal error on rename: confirmed node turns out as NULL"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - return(-1); - } - ret= iso_node_take(node); - if(ret<0) { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_report_iso_error(xorriso, eff_dest, 0, "Cannot take", 0, "FATAL",1); - sprintf(xorriso->info_text, - "Internal error on rename: failed to take node"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - return(-1); - } - leafname= strrchr(eff_dest, '/'); - if(leafname==NULL) - leafname= eff_dest; - else - leafname++; - - old_leafname= (char *) iso_node_get_name(node); - if(strcmp(leafname, old_leafname)!=0) - ret= iso_node_set_name(node, leafname); - else - ret= 1; - if(ret<0) { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_report_iso_error(xorriso, eff_dest, 0, "Cannot set name", 0, - "FAILURE", 1); - return(-1); - } - Xorriso_process_msg_queues(xorriso,0); - ret= iso_dir_add_node(dest_dir, node, 0); - if(ret<0) { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_report_iso_error(xorriso, eff_dest, 0, "Cannot add", 0, "FATAL", 1); - sprintf(xorriso->info_text, - "Internal error on rename: failed to insert node"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - return(-1); - } - return(1); -} - - -/* @param flag bit0= do not produce info message on success - @return 1=success, - 0=was already directory, -1=was other type, -2=other error -*/ -int Xorriso_mkdir(struct XorrisO *xorriso, char *path, int flag) -{ - int ret; - char eff_path[SfileadrL], sfe[5*SfileadrL]; - - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 1); - if(ret<0) - return(-2); - if(ret>0) { - sprintf(xorriso->info_text,"-mkdir: Address already existing %s", - Text_shellsafe(eff_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, - (ret==2 ? "WARNING" : "FAILURE"), 0); - return(-1+(ret==2)); - } - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 2); - if(ret<0) - return(-2); - ret= Xorriso_graft_in(xorriso, NULL, NULL, eff_path, (off_t) 0, (off_t) 0, 1); - if(ret<=0) - return(-2); - if(!(flag&1)) { - sprintf(xorriso->info_text, "Created directory in ISO image: %s\n", - Text_shellsafe(eff_path,sfe,0)); - Xorriso_info(xorriso, 0); - } - 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) -*/ -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 ret, failed_at; - IsoDirIter *iter= NULL; - IsoNode *node; - char *name; - char *adr= NULL; - - adr= malloc(SfileadrL); - if(adr==NULL) { - Xorriso_no_malloc_memory(xorriso, &adr, 0); - {ret= -1; goto ex;} - } - - if(!(flag&2)) - *dive_count= 0; - else - (*dive_count)++; - ret= Xorriso_check_for_root_pattern(xorriso, filec, filev, count_limit, - mem, (flag&1)|2); - if(ret!=2) - goto ex; - - ret= iso_dir_get_children(dir, &iter); - if(ret<0) { - Xorriso_cannot_create_iter(xorriso, ret, 0); - {ret= -1; goto ex;} - } - while(iso_dir_iter_next(iter, &node) == 1) { - name= (char *) iso_node_get_name(node); - 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) { /* no match */ - if(failed_at <= *dive_count) /* no hope for a match */ - continue; - - if(!LIBISO_ISDIR(node)) { - - /* >>> How to deal with softlinks ? */ - - continue; - } - /* dive deeper */ - ret= Xorriso_obtain_pattern_files_i( - xorriso, adr, (IsoDir *) node, - 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)|2); - if(ret<=0) - goto ex; - } - } - ret= 1; -ex:; - if(adr!=NULL) - free(adr); - if(flag&2) - (*dive_count)--; - if(iter != NULL) - iso_dir_iter_free(iter); - return(ret); -} - - -/* @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_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]; - IsoImage *volume; - IsoDir *dir= NULL, *root_dir; - IsoNode *iso_node; - - *filec= 0; - *filev= NULL; - - xorriso->search_mode= 3; - xorriso->structured_search= 1; - - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - return(ret); - root_dir= iso_image_get_root(volume); - if(root_dir==NULL) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, - "While expanding pattern : Cannot obtain root node of ISO image"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - ret= -1; goto ex; - } - - for(i= 0; iwdi does not exist yet, but one may - not use it as base for relative address searches. - */ - ret= Xorriso_node_from_path(xorriso, volume, xorriso->wdi, &iso_node, 1); - dir= (IsoDir *) iso_node; - if(ret<=0) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, - "While expanding pattern %s : Working directory does not exist in ISO image", - Text_shellsafe(patterns[i], sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - if(!LIBISO_ISDIR((IsoNode *) dir)) { - sprintf(xorriso->info_text, - "Working directory path does not lead to a directory in ISO image"); - 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_i(xorriso, "", dir, &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++; - Xorriso_eval_nonmatch(xorriso, patterns[i], &nonconst_mismatches, mem, 0); - } - } - - 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; iinfo_text,"Permissions now: %-5.5o %s", - (unsigned int) (mode & 0xffff), Text_shellsafe(path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - Xorriso_set_change_pending(xorriso, 0); - Xorriso_process_msg_queues(xorriso,0); - return(1); -} - - -int Xorriso_set_uid(struct XorrisO *xorriso, char *in_path, uid_t uid, - int flag) -{ - int ret; - IsoNode *node; - - ret= Xorriso_get_node_by_path(xorriso, in_path, NULL, &node, 0); - if(ret<=0) - return(ret); - iso_node_set_uid(node, uid); - iso_node_set_ctime(node, time(NULL)); - Xorriso_set_change_pending(xorriso, 0); - Xorriso_process_msg_queues(xorriso,0); - return(1); -} - - -int Xorriso_set_gid(struct XorrisO *xorriso, char *in_path, gid_t gid, - int flag) -{ - int ret; - IsoNode *node; - - ret= Xorriso_get_node_by_path(xorriso, in_path, NULL, &node, 0); - if(ret<=0) - return(ret); - iso_node_set_gid(node, gid); - iso_node_set_ctime(node, time(NULL)); - Xorriso_set_change_pending(xorriso, 0); - Xorriso_process_msg_queues(xorriso,0); - return(1); -} - - -/* @parm flag bit0= atime, bit1= ctime, bit2= mtime, bit8=no auto ctime */ -int Xorriso_set_time(struct XorrisO *xorriso, char *in_path, time_t t, - int flag) -{ - int ret; - IsoNode *node; - - ret= Xorriso_get_node_by_path(xorriso, in_path, NULL, &node, 0); - if(ret<=0) - return(ret); - if(flag&1) - iso_node_set_atime(node, t); - if(flag&2) - iso_node_set_ctime(node, t); - if(flag&4) - iso_node_set_mtime(node, t); - if(!(flag&(2|256))) - iso_node_set_ctime(node, time(NULL)); - Xorriso_set_change_pending(xorriso, 0); - Xorriso_process_msg_queues(xorriso,0); - return(1); -} - - -int Xorriso__start_end_lbas(IsoNode *node, - int *lba_count, int **start_lbas, int **end_lbas, - off_t *size, int flag) -{ - int section_count= 0, ret, i; - struct iso_file_section *sections= NULL; - - *lba_count= 0; - *start_lbas= *end_lbas= NULL; - *size= 0; - if(!LIBISO_ISREG(node)) - return(0); - *size= iso_file_get_size((IsoFile *) node); - ret= iso_file_get_old_image_sections((IsoFile *) node, §ion_count, - §ions, 0); - if(ret < 0) - {ret= -1; goto ex;} - if(ret != 1 || section_count <= 0) - {ret= 0; goto ex;} - *start_lbas= calloc(section_count, sizeof(int)); - *end_lbas= calloc(section_count, sizeof(int)); - if(*start_lbas == NULL || *end_lbas == NULL) - {ret= -1; goto ex;} - for(i= 0; i < section_count; i++) { - (*start_lbas)[i]= sections[i].block; - (*end_lbas)[i]= sections[i].block + sections[i].size / 2048 - 1; - if(sections[i].size % 2048) - (*end_lbas)[i]++; - } - *lba_count= section_count; - ret= 1; -ex:; - if(sections != NULL) - free((char *) sections); - if(ret <= 0) { - if((*start_lbas) != NULL) - free((char *) *start_lbas); - if((*end_lbas) != NULL) - free((char *) *end_lbas); - *start_lbas= *end_lbas= NULL; - *lba_count= 0; - } - return(ret); -} - - -int Xorriso__file_start_lba(IsoNode *node, - int *lba, int flag) -{ - int *start_lbas= NULL, *end_lbas= NULL, lba_count= 0, i, ret; - off_t size; - - *lba= -1; - ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas, - &size, 0); - if(ret <= 0) - return(ret); - for(i= 0; i < lba_count; i++) { - if(*lba < 0 || start_lbas[i] < *lba) - *lba= start_lbas[i]; - } - if(start_lbas != NULL) - free((char *) start_lbas); - if(end_lbas != NULL) - free((char *) end_lbas); - if(*lba < 0) - return(0); - return(1); -} - - -/* @param damage_start Returns first damaged byte address - @param damage_end Returns first byte address after last damaged byte - @return <0 error, 0=undamaged , 1=damaged -*/ -int Xorriso_file_eval_damage(struct XorrisO *xorriso, IsoNode *node, - off_t *damage_start, off_t *damage_end, - int flag) -{ - int *start_lbas= NULL, *end_lbas= NULL, lba_count= 0, sect; - int i, sectors, sector_size, ret; - off_t sect_base= 0, size= 0, byte; - struct SectorbitmaP *map; - - *damage_start= *damage_end= -1; - map= xorriso->in_sector_map; - if(map == NULL) - return(0); - Sectorbitmap_get_layout(map, §ors, §or_size, 0); - sector_size/= 2048; - - ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas, - &size, 0); - if(ret <= 0) { - Xorriso_process_msg_queues(xorriso, 0); - return(ret); - } - for(sect= 0; sect < lba_count; sect++) { - for(i= start_lbas[sect]; i <= end_lbas[sect]; i+= sector_size) { - if(Sectorbitmap_is_set(map, i / sector_size, 0) == 0) { - byte= ((off_t) 2048) * ((off_t) (i - start_lbas[sect])) + sect_base; - if(*damage_start < 0 || byte < *damage_start) - *damage_start= byte; - if(byte + (off_t) 2048 > *damage_end) - *damage_end= byte + (off_t) 2048; - } - } - sect_base+= ((off_t) 2048) * - ((off_t) (end_lbas[sect] - start_lbas[sect] + 1)); - } - if(*damage_end > size) - *damage_end= size; - if(start_lbas != NULL) - free((char *) start_lbas); - if(end_lbas != NULL) - free((char *) end_lbas); - if(*damage_start < 0) - return(0); - return(1); -} - - -int Xorriso_report_lba(struct XorrisO *xorriso, char *show_path, - IsoNode *node, int flag) -{ - int ret, *start_lbas= NULL, *end_lbas= NULL, lba_count, i; - off_t size; - char sfe[5*SfileadrL]; - - ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas, - &size, 0); - if(ret < 0) { - Xorriso_process_msg_queues(xorriso, 0); - {ret= -1; goto ex;} - } - if(ret == 0) - {ret= 1; goto ex;} /* it is ok to ignore other types */ - for(i= 0; i < lba_count; i++) { - sprintf(xorriso->result_line, - "File data lba: %2d , %8d , %8d , %8.f , %s\n", - i, start_lbas[i], end_lbas[i] + 1 - start_lbas[i], (double) size, - Text_shellsafe(show_path, sfe, 0)); - Xorriso_result(xorriso, 0); - } - ret= 1; -ex:; - if(start_lbas != NULL) - free((char *) start_lbas); - if(end_lbas != NULL) - free((char *) end_lbas); - return(ret); -} - - -int Xorriso_report_damage(struct XorrisO *xorriso, char *show_path, - IsoNode *node, int flag) -{ - int ret; - off_t size= 0, damage_start, damage_end; - char sfe[5*SfileadrL]; - - ret= Xorriso_file_eval_damage(xorriso, node, &damage_start, &damage_end, 0); - if(ret < 0) - return(0); - - if(LIBISO_ISREG(node)) - size= iso_file_get_size((IsoFile *) node); - if(ret > 0) { - sprintf(xorriso->result_line, "File damaged : %8.f , %8.f , %8.f , %s\n", - (double) damage_start, (double) (damage_end - damage_start) , - (double) size, Text_shellsafe(show_path, sfe, 0)); - Xorriso_result(xorriso, 0); - } else { - sprintf(xorriso->result_line, "File seems ok: %8.f , %8.f , %8.f , %s\n", - -1.0, -1.0, (double) size, Text_shellsafe(show_path, sfe, 0)); - Xorriso_result(xorriso, 0); - } - return(1); -} - - -/* @return see Xorriso_update_interpreter() -*/ -int Xorriso_widen_hardlink(struct XorrisO *xorriso, void * boss_iter, - IsoNode *node, - char *abs_path, char *iso_prefix, char *disk_prefix, - int flag) -{ - int ret= 0, idx, low, high, i, do_widen= 0, compare_result= 0; - char disk_path[SfileadrL]; - - /* Lookup all di_array instances of node */ - if(LIBISO_ISDIR(node)) - return(3); - ret= Xorriso_search_di_range(xorriso, node, &idx, &low, &high, 2); - if(ret <= 0) - return(3); - /* Check and reset di_do_widen bits */ - for(i= low; i <= high; i++) { - if(node != xorriso->di_array[i]) /* might be NULL */ - continue; - if(xorriso->di_do_widen[i / 8] & (1 << (i % 8))) - do_widen= 1; - xorriso->di_do_widen[i / 8]&= ~(1 << (i % 8)); - } - if(idx < 0 || !do_widen) - return(3); - - ret= Xorriso_pfx_disk_path(xorriso, abs_path, iso_prefix, disk_prefix, - disk_path, 0); - if(ret <= 0) - return(ret); - ret= Sfile_type(disk_path, 1); - if(ret < 0) - return(3); /* does not exist on disk */ - - /* >>> compare_result bit17 = is_split */; - - ret= Xorriso_update_interpreter(xorriso, boss_iter, compare_result, disk_path, - abs_path, 1); - if(ret <= 0) - return(ret); - return(ret); -} - - -/* - Apply the effect of mkisofs -r to a single node -*/ -int Xorriso_mkisofs_lower_r(struct XorrisO *xorriso, IsoNode *node, int flag) -{ - mode_t perms; - - perms= iso_node_get_permissions(node); - iso_node_set_uid(node, (uid_t) 0); - iso_node_set_gid(node, (gid_t) 0); - perms|= S_IRUSR | S_IRGRP | S_IROTH; - perms&= ~(S_IWUSR | S_IWGRP | S_IWOTH); - if(perms & (S_IXUSR | S_IXGRP | S_IXOTH)) - perms|= (S_IXUSR | S_IXGRP | S_IXOTH); - perms&= ~(S_ISUID | S_ISGID | S_ISVTX); - iso_node_set_permissions(node, perms); - return(1); -} - - -/* @param flag bit0= not a command parameter (directory iteration or recursion) - bit1= do not count deleted files with rm and rm_r - @return <=0 error, - 1=ok - 2=ok, node has been deleted, - 3=ok, do not dive into directory (e.g. because it is a split file) -*/ -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 ret= 0, type, action= 0, hflag, deleted= 0, no_dive= 0; - uid_t user= 0; - gid_t group= 0; - time_t date= 0; - mode_t mode_or= 0, mode_and= ~1; - char *target, *text_2, sfe[5*SfileadrL], *iso_prefix, md5[16]; - struct FindjoB *subjob; - struct stat dir_stbuf; - - action= Findjob_get_action_parms(job, &target, &text_2, &user, &group, - &mode_and, &mode_or, &type, &date, &subjob, 0); - if(action<0) - action= 0; - - hflag= 16*!(flag&2); - ret= 1; - if(action==1) { /* rm (including rmdir) */ - ret= Xorriso_fake_stbuf(xorriso, abs_path, &dir_stbuf, &node, 1); - if(ret>0) { - if(S_ISDIR(dir_stbuf.st_mode)) - hflag= 2; - ret= Xorriso_rmi(xorriso, boss_iter, boss_mem, abs_path, hflag); - deleted= 1; - } - } else if(action==2) { /* rm_r */ - ret= Xorriso_rmi(xorriso, boss_iter, boss_mem, abs_path, 1|hflag); - deleted= 1; - } else if(action==3) { - - /* >>> mv target */; - - } else if(action==4) { /* chown */ - ret= Xorriso_set_uid(xorriso, abs_path, user, 0); - } else if(action==5) { /* chgrp */ - ret= Xorriso_set_gid(xorriso, abs_path, group, 0); - } else if(action==6) { /* chmod */ - ret= Xorriso_set_st_mode(xorriso, abs_path, mode_and, mode_or, 0); - } else if(action==7) { /* alter_date */ - ret= Xorriso_set_time(xorriso, abs_path, date, type&7); - } else if(action==8) { /* lsdl */ - ret= Xorriso_ls_filev(xorriso, "", 1, &abs_path, (off_t) 0, 1|2|8); - } else if(action>=9 && action<=13) { /* actions which have own findjobs */ - Findjob_set_start_path(subjob, abs_path, 0); - ret= Xorriso_findi(xorriso, subjob, boss_iter, boss_mem, NULL, - abs_path, &dir_stbuf, depth, 1); - } else if(action==14 || action==17) { /* compare , update */ - Findjob_get_start_path(job, &iso_prefix, 0); - ret= Xorriso_find_compare(xorriso, (void *) boss_iter, abs_path, - iso_prefix, target, (action==17)|((flag&1)<<1)); - if(ret==2) - deleted= 1; - if(ret==3) - no_dive= 1; - if(ret>=0) - ret= 1; - } else if(action==16 || action==18) { /* not_in_iso , add_missing */ - ; - } else if(action == 21) { /* report_damage */ - ret= Xorriso_report_damage(xorriso, show_path, node, 0); - } else if(action == 22) { - ret= Xorriso_report_lba(xorriso, show_path, node, 0); - } else if(action == 23) { /* internal: memorize path of last matching node */ - ret= Findjob_set_found_path(job, show_path, 0); - } else if(action == 24) { - ret= Xorriso_getfacl(xorriso, (void *) node, show_path, NULL, 0); - } else if(action == 25) { - if(target == NULL || target[0] || text_2 == NULL || text_2[0]) - ret= Xorriso_setfacl(xorriso, (void *) node, show_path, target, text_2,0); - } else if(action == 26) { - ret= Xorriso_getfattr(xorriso, (void *) node, show_path, NULL, 0); - } else if(action == 27) { - ret= Xorriso_path_setfattr(xorriso, (void *) node, show_path, - target, strlen(text_2), text_2, 0); - } else if(action == 28) { /* set_filter */ - ret= Xorriso_set_filter(xorriso, (void *) node, show_path, target, 1 | 2); - } else if(action == 29) { /* show_stream */ - ret= Xorriso_show_stream(xorriso, (void *) node, show_path, 1 | 2); - } else if(action == 30) { /* internal: count */ - xorriso->node_counter++; - } else if(action == 31) { /* internal: register */ - if(xorriso->node_counter < xorriso->node_array_size) { - xorriso->node_array[xorriso->node_counter++]= (void *) node; - iso_node_ref(node); /* In case node gets deleted from tree during - the lifetime of xorriso->node_array */ - } - } else if(action == 32) { /* internal: widen_hardlinks disk_equiv */ - Findjob_get_start_path(job, &iso_prefix, 0); - ret= Xorriso_widen_hardlink(xorriso, (void *) boss_iter, node, abs_path, - iso_prefix, target, 0); - if(ret==2) - deleted= 1; - } else if(action == 33) { /* get_any_xattr */ - ret= Xorriso_getfattr(xorriso, (void *) node, show_path, NULL, 8); - } else if(action == 34) { /* get_md5 */ - ret= Xorriso_get_md5(xorriso, (void *) node, show_path, md5, 0); - if(ret >= 0) - ret= 1; - } else if(action == 35) { /* check_md5 */ - ret= Xorriso_check_md5(xorriso, (void *) node, show_path, 2); - if(ret == 0) - xorriso->find_check_md5_result|= 1; - else if(ret < 0) - xorriso->find_check_md5_result|= 2; - else if(ret == 1) - xorriso->find_check_md5_result|= 8; - else if(ret == 2) - xorriso->find_check_md5_result|= 4; - if(ret >= 0) - ret= 1; - } else if(action == 36) { /* make_md5 */ - ret= Xorriso_make_md5(xorriso, (void *) node, show_path, 0); - if(ret >= 0) - ret= 1; - } else if(action == 37) { /* mkisofs_r */ - ret= Xorriso_mkisofs_lower_r(xorriso, node, 0); - } else if(action == 38) { /* sort_weight */ - iso_node_set_sort_weight(node, type); - } else { /* includes : 15 in_iso */ - sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0)); - Xorriso_result(xorriso, 0); - ret= 1; - } - if(ret<=0) - return(ret); - if(deleted) - return(2); - if(no_dive) - return(3); - return(1); -} - - -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) -/* -return: - <0 = error - 0 = does not match - 1 = does match - 2 = immediate decision : does not match - 3 = immediate decision : does match -*/ -{ - int value=0, ret, start_lba, end_lba; - int lba_count, *file_end_lbas= NULL, *file_start_lbas= NULL, i; - void *arg1, *arg2; - char ft, *decision, md5[16]; - regmatch_t name_match; - off_t damage_start, damage_end, size; - void *xinfo_dummy; - IsoNode *node; - IsoStream *stream; - - if(ftest == NULL) - return(1); - - node= (IsoNode *) node_pt; - arg1= ftest->arg1; - arg2= ftest->arg2; - - if(node == NULL) { - if(ftest->test_type > 2 && ftest->test_type != 4) { - value= 0; - goto ex; - } - } - - switch(ftest->test_type) { - case 0: /* -false */ - value= 0; - - break; case 1: /* -name *arg1 (regex in *arg2) */ - ret= regexec(arg2, name, 1, &name_match, 0); - value= !ret; - - break; case 2: /* -type *arg1 */ - value= 1; - ft= *((char *) arg1); - if(ft!=0) { - if(S_ISBLK(stbuf->st_mode)) { - if(ft!='b') - value= 0; - } else if(S_ISCHR(stbuf->st_mode)) { - if(ft!='c') - value= 0; - } else if(S_ISDIR(stbuf->st_mode)) { - if(ft=='m') { - if(node != NULL) - value= 0; - else if(boss_stbuf==NULL) - value= 0; - else if(boss_stbuf->st_dev == stbuf->st_dev) - value= 0; - } else if(ft!='d') - value= 0; - } else if(S_ISFIFO(stbuf->st_mode)) { - if(ft!='p') - value= 0; - } else if(S_ISREG(stbuf->st_mode)) { - if(ft!='f' && ft!='-') - value= 0; - } else if(((stbuf->st_mode)&S_IFMT)==S_IFLNK) { - if(ft!='l') - value= 0; - } else if(((stbuf->st_mode)&S_IFMT)==S_IFSOCK) { - if(ft!='s') - value= 0; - } else if((flag & 1) && ((stbuf->st_mode) & S_IFMT) == Xorriso_IFBOOT) { - if(ft!='e' || node == NULL) - value= 0; - } else { - if(ft!='X') - value= 0; - } - } - - break; case 3: /* -damaged */; - value= Xorriso_file_eval_damage(xorriso, node, &damage_start, &damage_end, - 0); - if(value > 0) - value= 1; - - break; case 4: /* -lba_range *arg1 *arg2 */ - value= 1; - start_lba= *((int *) ftest->arg1); - end_lba= *((int *) ftest->arg2); - if(node == NULL) { - value= !(start_lba >= 0); - goto ex; - } - ret= Xorriso__start_end_lbas(node, &lba_count, - &file_start_lbas, &file_end_lbas, &size, 0); - if(ret <= 0) { - if(ret < 0) - Xorriso_process_msg_queues(xorriso, 0); - if(start_lba >= 0) - value= 0; - } else { - for(i= 0; i < lba_count; i++) { - if(start_lba >= 0) { - if(file_end_lbas[i] < start_lba || file_start_lbas[i] > end_lba) - value= 0; - } else { - if(file_end_lbas[i] >= -start_lba && file_start_lbas[i] <= -end_lba) - value= 0; - } - } - } - - break; case 5: /* -has_acl */ - ret = Xorriso_getfacl(xorriso, (void *) node, "", NULL, 2); - if(ret <= 0) { - value= -1; - Xorriso_process_msg_queues(xorriso, 0); - goto ex; - } - value= (ret == 1); - - break; case 6: /* -has_xattr */ - case 14: /* -has_any_xattr */ - ret = Xorriso_getfattr(xorriso, (void *) node, "", NULL, - 64 | (8 * (ftest->test_type == 14))); - if(ret < 0) { - value= -1; - Xorriso_process_msg_queues(xorriso, 0); - goto ex; - } - value= (ret > 0); - - break; case 7: /* -has_aaip */ - ret= iso_node_get_xinfo(node, aaip_xinfo_func, &xinfo_dummy); - if(ret < 0) { - value= -1; - Xorriso_process_msg_queues(xorriso, 0); - goto ex; - } - value= (ret > 0); - - break; case 8: /* -has_filter */ - value= 0; - if(LIBISO_ISREG(node)) { - stream= iso_file_get_stream((IsoFile *) node); - if(iso_stream_get_input_stream(stream, 0) != NULL) - value= 1; - } - - break; case 9: /* -wanted_node arg1 (for internal use) */ - value= (((IsoNode *) arg1) == node); - - break; case 10: /* -pending_data */ - value= 1; - if(!LIBISO_ISREG(node)) { - value= 0; - } else { - ret= Xorriso__file_start_lba(node, &start_lba, 0); - if(ret > 0 && start_lba >= 0) - value= 0; - } - - break; case 11: /* -decision */ - value= 2; - decision= (char *) arg1; - if(strcmp(decision, "yes") == 0 || strcmp(decision, "true") == 0) - value= 3; - - break; case 12: /* -prune */ - value= 1; - ftest->boss->prune= 1; - - break; case 13: /* -wholename *arg1 (regex in *arg2) */ - ret= regexec(arg2, path, 1, &name_match, 0); - value= !ret; - - break; case 15: /* -has_md5 */ - ret= Xorriso_get_md5(xorriso, node, path, md5, 1); - value= (ret > 0); - - break; default: - - /* >>> complain about unknown test type */; - - value= -1; - - } - -ex:; - if(ftest->invert && value<=1 && value>=0) - value= !value; - if(file_start_lbas != NULL) - free((char *) file_start_lbas); - if(file_end_lbas != NULL) - free((char *) file_end_lbas); - return(value); -} - - -/* @return <0 = error , 0 = no match , 1 = match */ -int Xorriso_findi_test(struct XorrisO *xorriso, struct FindjoB *job, - IsoNode *node, char *name, char *path, - struct stat *boss_stbuf, struct stat *stbuf, - int depth, int flag) -{ - int ret; - - job->prune= 0; - ret= Findjob_test_2(xorriso, job, node, name, path, boss_stbuf, stbuf, 1); - if(ret <= 0) - return(ret); - return(1); -} - - -int Xorriso_findi_headline(struct XorrisO *xorriso, struct FindjoB *job, - int flag) -{ - int action; - - action= Findjob_get_action(job, 0); - if(action == 21) { /* report_damage */ - sprintf(xorriso->result_line, "Report layout: %8s , %8s , %8s , %s\n", - "at byte", "Range", "Filesize", "ISO image path"); - Xorriso_result(xorriso, 0); - } else if(action == 22) { /* report_lba */ - sprintf(xorriso->result_line, - "Report layout: %2s , %8s , %8s , %8s , %s\n", - "xt", "Startlba", "Blocks", "Filesize", "ISO image path"); - Xorriso_result(xorriso, 0); - } - return(1); -} - - -/* @param flag bit0= recursion - bit1= do not count deleted files with rm and rm_r - bit2= do not dive into split file directories - (implicitly given with actions 14=compare and 17=update) - @return <=0 error, 1= ok , 2= dir node and path has been deleted -*/ -int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, - void *boss_iter, off_t boss_mem, - void *dir_node_generic, char *dir_path, - struct stat *dir_stbuf, int depth, int flag) -{ - int ret, action= 0, hflag, deleted= 0, no_dive= 0; - IsoDirIter *iter= NULL; - IsoDir *dir_node= NULL; - IsoNode *node, *iso_node; - IsoImage *volume= NULL; - struct stat stbuf; - char *name; - off_t mem; - IsoNode **node_array= NULL; - int node_count, node_idx; - char *path= NULL, *abs_path= NULL; - - if(xorriso->request_to_abort) - {ret= 0; goto ex;} - - path= malloc(SfileadrL); - abs_path= malloc(SfileadrL); - if(path==NULL || abs_path==NULL) { - Xorriso_no_malloc_memory(xorriso, &path, 0); - {ret= -1; goto ex;} - } - - action= Findjob_get_action(job, 0); - if(action<0) - action= 0; - if(!(flag & 1)) - Xorriso_findi_headline(xorriso, job, 0); - - dir_node= (IsoDir *) dir_node_generic; - if(dir_node==NULL) { - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - {ret= -1; goto ex;} - ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, dir_path, path, 1|2|4); - if(ret<=0) - goto ex; - ret= Xorriso_node_from_path(xorriso, volume, path, &iso_node, 0); - dir_node= (IsoDir *) iso_node; - if(ret<=0) - {ret= 0; goto ex;} - ret= Xorriso_fake_stbuf(xorriso, "", dir_stbuf, &iso_node, 1); - if(ret<=0) - goto ex; - - name= strrchr(dir_path, '/'); - if(name==NULL) - name= dir_path; - else - name++; - - ret= Xorriso_findi_test(xorriso, job, iso_node, name, path, NULL, dir_stbuf, - depth, 0); - if(ret<0) - goto ex; - if(job->prune) - no_dive= 1; - if(ret>0) { - iso_node_ref(iso_node); /* protect from real disposal */ - ret= Xorriso_findi_action(xorriso, job, - (IsoDirIter *) boss_iter, boss_mem, - path, dir_path, iso_node, depth, - flag&(1|2)); - deleted= (iso_node_get_parent(iso_node) == NULL); /* still in tree ? */ - iso_node_unref(iso_node); /* eventually do real disposal */ - if(ret<=0) - goto ex; - if(xorriso->request_to_abort) - {ret= 0; goto ex;} - if(ret==2 || deleted) { - /* re-determine dir_node in case it has a new persona */ - ret= Xorriso_node_from_path(xorriso, volume, path, &iso_node, 1); - if(ret==0) { - deleted= 1; - {ret= 2; goto ex;} - } - if(ret<0) - {ret= 0; goto ex;} - dir_node= (IsoDir *) iso_node; - ret= Xorriso_fake_stbuf(xorriso, "", dir_stbuf, &iso_node, 1); - if(ret<=0) - goto ex; - } - if(ret==3) - no_dive= 1; - } - } - if(no_dive || !LIBISO_ISDIR((IsoNode *) dir_node)) - {ret= 1; goto ex;} - if(action == 14 || action == 17 || (flag & 4)) - if(Xorriso_is_split(xorriso, dir_path, (IsoNode *) dir_node, 1)>0) - {ret= 1; goto ex;} - - mem= boss_mem; - hflag= 1; - if(action==1 || action==2 || action==3 || action==17 || action == 28 || - action == 32) - hflag|= 2; /* need freedom to manipulate image */ - if(action==14 || action==17 || action == 28 || action == 35 || action == 36) - hflag|= 4; /* need LBA sorted iteration for good data reading performance */ - ret= Xorriso_findi_iter(xorriso, dir_node, &mem, - &iter, &node_array, &node_count, &node_idx, - &node, hflag); - if(ret<=0) - goto ex; - while(1) { - ret= Xorriso_findi_iter(xorriso, dir_node, &mem, &iter, - &node_array, &node_count, &node_idx, &node, 0); - if(ret<0) - goto ex; - if(ret==0) - break; - name= (char *) iso_node_get_name(node); - ret= Xorriso_make_abs_adr(xorriso, dir_path, name, path, 4); - if(ret<=0) - goto ex; - ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1); - if(ret<0) - goto ex; - if(ret==0) - continue; - -/* ??? This seems to be redundant with the single test above - ??? Should i dive in unconditionally and leave out test and action here ? - ??? Then do above test unconditionally ? - --- Seems that the current configuration represents the special - handling of the find start path with mount points. Dangerous to change. -*/ - - ret= Xorriso_findi_test(xorriso, job, node, name, path, dir_stbuf, &stbuf, - depth, 0); - if(ret<0) - goto ex; - if(job->prune) - no_dive= 1; - if(ret>0) { - ret= Xorriso_make_abs_adr(xorriso, xorriso->wdi, path, abs_path, 1|2|4); - if(ret<=0) - goto ex; - ret= Xorriso_findi_action(xorriso, job, iter, mem, - abs_path, path, node, depth, 1|(flag&2)); - if(xorriso->request_to_abort) - {ret= 0; goto ex;} - if(ret==2) { /* node has been deleted */ - /* re-determine node in case it has a new persona */ - if(volume==NULL) { - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - {ret= -1; goto ex;} - } - ret= Xorriso_node_from_path(xorriso, volume, abs_path, &node, 1); - if(ret==0) - continue; - if(ret<0) - {ret= 0; goto ex;} - ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1); - if(ret<0) - goto ex; - if(ret==0) - continue; - } - no_dive= (ret==3); - if(ret<=0) { - if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0) - goto ex; - } - } - - if(S_ISDIR(stbuf.st_mode) && !no_dive) { - ret= Xorriso_findi(xorriso, job, (void *) iter, mem, - (void *) node, path, &stbuf, depth+1, flag|1); - if(ret<0) - goto ex; - } - } - - ret= 1; -ex:; - if(path!=NULL) - free(path); - if(abs_path!=NULL) - free(abs_path); - Xorriso_process_msg_queues(xorriso,0); - - Xorriso_findi_iter(xorriso, dir_node, &mem, &iter, &node_array, &node_count, - &node_idx, &node, (1<<31)); - if(ret<=0) - return(ret); - if(deleted) - return(2); - return(1); -} - - -int Xorriso_node_is_valid(struct XorrisO *xorriso, IsoNode *in_node, int flag) -{ - IsoNode *node, *parent; - - for(node= in_node; 1; node= parent) { - parent= (IsoNode *) iso_node_get_parent(node); - if(parent == node) - break; - if(parent == NULL) - return(0); /* Node is not in the tree (any more) */ - } - return(1); -} - - -int Xorriso_path_from_node(struct XorrisO *xorriso, IsoNode *in_node, - char path[SfileadrL], int flag) -{ - int ret, i, comp_count= 0; - IsoNode *node, *parent, **components= NULL; - char *wpt, *npt; - - for(node= in_node; 1; node= parent) { - parent= (IsoNode *) iso_node_get_parent(node); - if(parent == node) - break; - if(parent == NULL) - return(0); /* Node is not in the tree (any more) */ - comp_count++; - } - if(comp_count == 0) { - strcpy(path, "/"); - return(1); - } - components= calloc(comp_count, sizeof(IsoNode *)); - if(components == NULL) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - ret= -1; goto ex; - } - i= comp_count; - for(node= in_node; 1; node= parent) { - parent= (IsoNode *) iso_node_get_parent(node); - if(parent == node) - break; - components[--i]= node; - } - - wpt= path; - for(i= 0; i < comp_count; i++) { - npt= (char *) iso_node_get_name(components[i]); - if((wpt - path) + strlen(npt) + 1 >= SfileadrL) { - - /* >>> path is getting much too long */; - - ret= -1; goto ex; - } - *(wpt++)= '/'; - strcpy(wpt, npt); - wpt+= strlen(npt); - *wpt= 0; - } - ret= 1; -ex:; - if(components != NULL) - free(components); - return(ret); -} - - -/* <<< The lookup from node pointer will be done by Xorriso_path_from_node() - (Currently it runs a full tree traversal) - Parameter node and flag bit0 will vanish then -*/ -/* @param flag bit0= use lba rather than node pointer -*/ -int Xorriso_path_from_lba(struct XorrisO *xorriso, IsoNode *node, int lba, - char path[SfileadrL], int flag) -{ - int ret; - struct FindjoB *job= NULL; - struct stat dir_stbuf; - char *found_path; - - path[0]= 0; - if((flag & 1) && lba <= 0) - return(0); - - ret= Findjob_new(&job, "/", 0); - if(ret <= 0) { - Xorriso_no_findjob(xorriso, "path_from_node", 0); - return(ret); - } - if(flag & 1) - Findjob_set_lba_range(job, lba, 1, 0); - else - Findjob_set_wanted_node(job, (void *) node, 0); - Findjob_set_action_found_path(job, 0); - ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, - NULL, "/", &dir_stbuf, 0, 0); - if(ret > 0) { - ret= 1; - Findjob_get_found_path(job, &found_path, 0); - if(found_path == NULL) - ret= 0; - else if(Sfile_str(path, found_path, 0) <= 0) - ret= -1; - } - Findjob_destroy(&job, 0); - return(ret); -} - - -/* @param flag bit0= do not dive into trees - bit1= do not perform job->action on resulting node array - bit2= do not free node_array after all actions are done -*/ -int Xorriso_findi_sorted(struct XorrisO *xorriso, struct FindjoB *job, - off_t boss_mem, int filec, char **filev, int flag) -{ - int i, ret, find_flag= 0; - struct FindjoB array_job, *proxy_job= NULL, *hindmost= NULL, *hmboss= NULL; - struct stat dir_stbuf; - IsoNode *node; - char abs_path[SfileadrL]; - off_t mem_needed= 0; - - array_job.start_path= NULL; - - if(job->action == 14 || job->action == 17) - find_flag|= 4; - if(job->action>=9 && job->action<=13) { /* actions which have own findjobs */ - /* array_job replaces the hindmost job in the chain */ - for(hindmost= job; hindmost->subjob != NULL; hindmost= hindmost->subjob) - hmboss= hindmost; - if(hmboss == NULL) - {ret= -1; goto ex;} - memcpy(&array_job, hindmost, sizeof(struct FindjoB)); - hmboss->subjob= &array_job; - proxy_job= job; - } else { - memcpy(&array_job, job, sizeof(struct FindjoB)); - proxy_job= &array_job; - hindmost= job; - } - array_job.start_path= NULL; /* is owned by the original, not by array_job */ - - /* Count matching nodes */ - Xorriso_destroy_node_array(xorriso, 0); - array_job.action= 30; /* internal: count */ - for(i= 0; i < filec; i++) { - if(flag & 1) { - xorriso->node_counter++; - continue; - } - ret= Findjob_set_start_path(proxy_job, filev[i], 0); - if(ret <= 0) - goto ex; - ret= Xorriso_findi(xorriso, proxy_job, NULL, boss_mem, NULL, - filev[i], &dir_stbuf, 0, find_flag); - if(ret <= 0) - goto ex; - } - if(xorriso->node_counter <= 0) - {ret= 1; goto ex;} - - mem_needed= boss_mem + xorriso->node_counter * sizeof(IsoNode *); - if(!(flag &1)) { - ret= Xorriso_check_temp_mem_limit(xorriso, mem_needed, 0); - if(ret <= 0) { - /* Memory curbed : Perform unsorted find jobs */ - if(hmboss != NULL) - hmboss->subjob= hindmost; - for(i= 0; i < filec; i++) { - ret= Findjob_set_start_path(job, filev[i], 0); - if(ret <= 0) - goto ex; - ret= Xorriso_findi(xorriso, job, NULL, boss_mem, NULL, - filev[i], &dir_stbuf, 0, find_flag); - if(ret <= 0) - if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0) - goto ex; - } - {ret= 1; goto ex;} - } - } - - /* Copy matching nodes into allocated array */ - ret= Xorriso_new_node_array(xorriso, xorriso->temp_mem_limit, 0, 0); - if(ret <= 0) - goto ex; - array_job.action= 31; /* internal: register */ - xorriso->node_counter= 0; - for(i= 0; i < filec; i++) { - if(flag & 1) { - ret= Xorriso_get_node_by_path(xorriso, filev[i], NULL, &node, 0); - if(ret <= 0) - goto ex; - if(xorriso->node_counter < xorriso->node_array_size) { - xorriso->node_array[xorriso->node_counter++]= (void *) node; - iso_node_ref(node); - } - continue; - } - ret= Findjob_set_start_path(proxy_job, filev[i], 0); - if(ret <= 0) - goto ex; - ret= Xorriso_findi(xorriso, proxy_job, NULL, mem_needed, NULL, - filev[i], &dir_stbuf, 0, find_flag); - if(ret <= 0) - goto ex; - } - - Xorriso_sort_node_array(xorriso, 0); - if(flag & 2) - {ret= 1; goto ex;} - - /* Perform job->action on xorriso->node_array */ - - /* Headlines of actions report_damage , report_lba */; - Xorriso_findi_headline(xorriso, job, 0); - - for(i= 0; i < xorriso->node_counter; i++) { - node= xorriso->node_array[i]; - ret= Xorriso_path_from_node(xorriso, node, abs_path, 0); - if(ret < 0) - goto ex; - if(ret == 0) - continue; /* node is deleted from tree meanwhile */ - - ret= Xorriso_findi_action(xorriso, hindmost, NULL, (off_t) 0, - abs_path, abs_path, node, 0, 1); - if(ret <= 0 || xorriso->request_to_abort) - if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0) - goto ex; - } - - ret= 1; -ex:; - if(!(flag & (2 | 4))) - Xorriso_destroy_node_array(xorriso, 0); - if(hmboss != NULL) - hmboss->subjob= hindmost; - if(array_job.start_path != NULL) - free(array_job.start_path); - return(ret); -} - - -/* @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); -} - - -/* @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", ¬e_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_numberfailure_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, µ); - 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, µ); - 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, µ); - 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); -} - - -/* @param flag bit0= -inq - bit1= -checkdrive -*/ -int Xorriso_atip(struct XorrisO *xorriso, int flag) -{ - int ret, profile_number= 0; - char *respt, profile_name[80]; - double x_speed_max, x_speed_min= -1.0; - struct burn_drive_info *dinfo; - struct burn_drive *drive; - enum burn_disc_status s; - char *manuf= NULL, *media_code1= NULL, *media_code2= NULL; - char *book_type= NULL, *product_id= NULL; - - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to print drive and media info", 2); - if(ret<=0) - return(0); - respt= xorriso->result_line; - sprintf(respt, "Device type : "); - ret= burn_drive_get_drive_role(drive); - if(ret==0) - sprintf(respt+strlen(respt), "%s\n", "Emulated (null-drive)"); - else if(ret==2) - sprintf(respt+strlen(respt), "%s\n", - "Emulated (stdio-drive, 2k random read-write)"); - else if(ret==3) - sprintf(respt+strlen(respt), "%s\n", - "Emulated (stdio-drive, sequential write-only)"); - else if(ret!=1) - sprintf(respt+strlen(respt), "%s\n","Emulated (stdio-drive)"); - else - sprintf(respt+strlen(respt), "%s\n","Removable CD-ROM"); - sprintf(respt+strlen(respt), "Vendor_info : '%s'\n",dinfo->vendor); - sprintf(respt+strlen(respt), "Identifikation : '%s'\n",dinfo->product); - sprintf(respt+strlen(respt), "Revision : '%s'\n",dinfo->revision); - Xorriso_result(xorriso,1); - if(flag&1) - return(1); - sprintf(respt, "Driver flags : BURNFREE\n"); - sprintf(respt+strlen(respt), "Supported modes: SAO TAO\n"); - Xorriso_result(xorriso,1); - if(flag&2) - return(1); - - s= burn_disc_get_status(drive); - ret= burn_disc_get_profile(drive,&profile_number,profile_name); - if(ret<=0) { - profile_number= 0; - strcpy(profile_name, "-unidentified-"); - } - if(s != BURN_DISC_UNSUITABLE) { - ret= burn_disc_read_atip(drive); - if(ret>0) { - ret= burn_drive_get_min_write_speed(drive); - x_speed_min= ((double) ret)/176.4; - } - } - if(s==BURN_DISC_EMPTY) { - sprintf(respt, "Current: none\n"); - Xorriso_result(xorriso,1); - return(1); - } else - sprintf(respt, "Current: %s\n",profile_name); - Xorriso_result(xorriso,1); - Xorriso_list_profiles(xorriso, 1 | 2); - if(strstr(profile_name,"BD")==profile_name) { - printf("Mounted Media: %2.2Xh, %s\n", profile_number, profile_name); - } else if(strstr(profile_name,"DVD")==profile_name) { - sprintf(respt, "book type: %s (emulated booktype)\n", profile_name); - Xorriso_result(xorriso,1); - if(profile_number == 0x13) { - sprintf(respt, "xorriso: message for sdvdbackup: \"(growisofs mode Restricted Overwrite)\"\n"); - Xorriso_result(xorriso,1); - } - } else { - sprintf(respt, "ATIP info from disk:\n"); - Xorriso_result(xorriso,1); - if(burn_disc_erasable(drive)) - sprintf(respt, " Is erasable\n"); - else - sprintf(respt, " Is not erasable\n"); - Xorriso_result(xorriso,1); - { int start_lba,end_lba,min,sec,fr; - ret= burn_drive_get_start_end_lba(drive,&start_lba,&end_lba,0); - if(ret>0) { - burn_lba_to_msf(start_lba,&min,&sec,&fr); - sprintf(respt, " ATIP start of lead in: %d (%-2.2d:%-2.2d/%-2.2d)\n", - start_lba,min,sec,fr); - Xorriso_result(xorriso,1); - burn_lba_to_msf(end_lba,&min,&sec,&fr); - sprintf(respt, " ATIP start of lead out: %d (%-2.2d:%-2.2d/%-2.2d)\n", - end_lba,min,sec,fr); - Xorriso_result(xorriso,1); - } - } - ret= burn_drive_get_write_speed(drive); - x_speed_max= ((double) ret)/176.4; - if(x_speed_min<0) - x_speed_min= x_speed_max; - sprintf(respt, - " 1T speed low: %.f 1T speed high: %.f\n",x_speed_min,x_speed_max); - Xorriso_result(xorriso,1); - } - - ret= burn_disc_get_media_id(drive, &product_id, &media_code1, &media_code2, - &book_type, 0); - if(ret > 0 && media_code1 != NULL && media_code2 != NULL) - manuf= burn_guess_manufacturer(profile_number, media_code1, media_code2, 0); - if(product_id != NULL) { - sprintf(respt, "Product Id: %s\n", product_id); - Xorriso_result(xorriso,1); - } - if(manuf != NULL) { - sprintf(respt, "Producer: %s\n", manuf); - Xorriso_result(xorriso, 1); - } - if(profile_number == 0x09 || profile_number == 0x0a) { - sprintf(respt, "Manufacturer: %s\n", manuf); - Xorriso_result(xorriso, 1); - } else if(product_id != NULL && media_code1 != NULL && media_code2 != NULL){ - free(product_id); - free(media_code1); - free(media_code2); - if(book_type != NULL) - free(book_type); - product_id= media_code1= media_code2= book_type= NULL; - ret= burn_disc_get_media_id(drive, &product_id, &media_code1, &media_code2, - &book_type, 1); - if(ret > 0) { - sprintf(respt, "Manufacturer: '%s'\n", media_code1); - Xorriso_result(xorriso, 1); - if(media_code2[0]) { - sprintf(respt, "Media type: '%s'\n", media_code2); - Xorriso_result(xorriso, 1); - } - } - } - if(manuf != NULL) - free(manuf); - if(media_code1 != NULL) - free(media_code1); - if(media_code2 != NULL) - free(media_code2); - if(book_type != NULL) - free(book_type); - if(product_id != NULL) - free(product_id); - return(1); -} - - -int Xorriso_update_in_sector_map(struct XorrisO *xorriso, - struct SpotlisT *spotlist, int read_chunk, - struct CheckmediajoB *job, int flag) -{ - int sectors, sector_size, sector_blocks, ret; - struct SectorbitmaP *map; - - Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); - if(job->use_dev == 1) - return(1); - map= job->sector_map; - sectors= Spotlist_block_count(spotlist, 0); - if(sectors <= 0) - return(0); - sector_size= Spotlist_sector_size(spotlist, read_chunk, 0); - sector_blocks= sector_size / 2048; - if(sector_blocks > 1) - sectors= sectors / sector_blocks + !!(sectors % sector_blocks); - ret= Sectorbitmap_new(&(xorriso->in_sector_map), sectors, sector_size, 0); - if(ret <= 0) - return(ret); - if(map != NULL) - Sectorbitmap_copy(map, xorriso->in_sector_map, 0); - ret= Xorriso_spotlist_to_sectormap(xorriso, spotlist, read_chunk, - &(xorriso->in_sector_map), 1); - return(ret); -} - - -/* - @param flag bit0= obtain iso_lba from indev - bit1= head_buffer already contains a valid head - bit2= issue message about success - bit3= check whether source blocks are banned by in_sector_map -*/ -int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize, - char *head_buffer, struct CheckmediajoB *job, - int flag) -{ - int ret, full_size, i; - char *headpt; - struct burn_drive_info *dinfo; - struct burn_drive *drive; - off_t seek_ret; - - ret= Xorriso_may_burn(xorriso, 0); - if(ret <= 0) - return(0); - if(flag & 1) { - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to learn current session lba", 1); - if(ret<=0) - return(0); - ret= isoburn_disc_get_msc1(drive, &iso_lba); - if(ret<=0) - return(0); - drive= NULL; /* indev will not be used furtherly */ - } - if(job == NULL) { - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to update at lba 0 to 31", 2); - if(ret<=0) - return(0); - } - if(iso_lba < 32) - return(2); - if(!(flag & 2)) { - /* head_buffer was not filled yet. Read it from output media. */ - if(job != NULL && job->data_to_fd >= 0) { - if((flag & 8) && job->sector_map != NULL) { - ret= Sectorbitmap_bytes_are_set(job->sector_map, - ((off_t) iso_lba) * (off_t) 2048, - ((off_t) (iso_lba + 32)) * ((off_t) 2048) - (off_t) 1, 0); - if(ret <= 0) { - sprintf(xorriso->info_text, - "ISO image head at lba %d is marked as invalid blocks in file copy", - iso_lba); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", - 0); - return(0); - } - } - seek_ret= lseek(job->data_to_fd, ((off_t) 2048) * (off_t) iso_lba, - SEEK_SET); - if(seek_ret == -1) - ret= 0; - else - ret= read(job->data_to_fd, head_buffer, 64 * 1024); - if(ret < 64 * 1024) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, - "Cannot read ISO image head from file copy"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); - return(0); - } - } else { - ret= isoburn_read_iso_head(drive, iso_lba, &isosize, head_buffer, 2); - if(ret<=0) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, - "Cannot read freshly written ISO image head"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - } - } - /* patch ISO header */ - full_size= iso_lba + isosize; - headpt= head_buffer + 32*1024; - for(i=0;i<4;i++) - headpt[87-i]= headpt[80+i]= (full_size >> (8*i)) & 0xff; - - if(job != NULL) { - seek_ret= lseek(job->data_to_fd, (off_t) 0, SEEK_SET); - if(seek_ret == -1) - ret= 0; - else - ret= write(job->data_to_fd, head_buffer, 64 * 1024); - if(ret < 64 * 1024) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, - "Cannot write ISO image head to file copy"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); - return(0); - } - } else { - ret= burn_random_access_write(drive, (off_t) 0, head_buffer, - (off_t) (64*1024), 1); - if(ret<=0) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, - "Cannot write new ISO image head to LBA 0"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - } - if(flag & 4) { - sprintf(xorriso->info_text, - "Overwrote LBA 0 to 31 by 64 KiB from LBA %d", iso_lba); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - } - return(1); -} - - -/* @param write_start_address is valid if >=0 - @param tsize is valid if >0 - @param flag bit0= grow_overwriteable_iso - bit1= do_isosize - bit2= do_xa1 conversion -*/ -int Xorriso_burn_track(struct XorrisO *xorriso, off_t write_start_address, - char *track_source, off_t tsize, int flag) -{ - int ret, fd, unpredicted_size, profile_number, is_cd= 0, dummy, nwa= -1; - int isosize= -1, do_isosize, is_bd= 0; - - struct burn_drive_info *dinfo; - struct burn_drive *drive; - struct burn_write_opts *burn_options; - struct burn_disc *disc= NULL; - struct burn_session *session; - struct burn_track *track; - struct stat stbuf; - off_t fixed_size= 0; - struct burn_source *data_src= NULL, *fifo_src= NULL; - enum burn_disc_status disc_state; - char reasons[BURN_REASONS_LEN], sfe[5*SfileadrL], profile_name[80]; - char head_buffer[64*1024]; - - ret= Xorriso_may_burn(xorriso, 0); - if(ret <= 0) - return(0); - ret= Xorriso_auto_format(xorriso, 0); - if(ret <=0 ) - return(0); - - do_isosize= !!(flag&2); - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to burn track", 2); - if(ret<=0) - return(0); - ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0); - if(ret<=0) - goto ex; - - disc= burn_disc_create(); - session= burn_session_create(); - ret= burn_disc_add_session(disc,session,BURN_POS_END); - if(ret==0) { - sprintf(xorriso->info_text, "Cannot add session object to disc object."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - goto ex; - } - track= burn_track_create(); - if(track_source[0] == '-' && track_source[1] == 0) { - fd= 0; - } else { - if(xorriso->fs >= 64) - fd= burn_os_open_track_src(track_source, O_RDONLY, 0); - else - fd= open(track_source, O_RDONLY); - if(fd>=0) - if(fstat(fd,&stbuf)!=-1) - if((stbuf.st_mode&S_IFMT)==S_IFREG) - fixed_size= stbuf.st_size; - } - if(fixed_size==0) - unpredicted_size= 1; - - if(fd>=0) - data_src= burn_fd_source_new(fd, -1, fixed_size); - if(data_src==NULL) { - sprintf(xorriso->info_text, "Could not open data source %s", - Text_shellsafe(track_source,sfe,0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - ret= 0; goto ex; - } - if((do_isosize || xorriso->fs != 0) && xorriso->fs < 64) - xorriso->fs= 64; - if(xorriso->fs > 0) { - fifo_src= burn_fifo_source_new(data_src, 2048 + 8 * !!(flag & 4), - xorriso->fs, 1); - if(fifo_src == NULL) { - sprintf(xorriso->info_text, "Could not create fifo object of %.f MB", - ((double) xorriso->fs) / 1024.0 / 1024.0); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - ret= 0; goto ex; - } - } - xorriso->pacifier_fifo= fifo_src; - if(burn_track_set_source(track, fifo_src == NULL ? data_src : fifo_src) - != BURN_SOURCE_OK) { - sprintf(xorriso->info_text, - "Cannot attach source object to track object"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0); - ret= 0; goto ex; - } - burn_track_set_cdxa_conv(track, !!(flag & 4)); - burn_session_add_track(session, track, BURN_POS_END); - burn_source_free(data_src); - - if(flag&1) - /* consider overwriteables with ISO as appendable */ - disc_state= isoburn_disc_get_status(drive); - else - /* handle overwriteables as always blank */ - disc_state= burn_disc_get_status(drive); - - if(disc_state == BURN_DISC_BLANK || disc_state == BURN_DISC_APPENDABLE) { - /* ok */; - } else { - if(disc_state == BURN_DISC_FULL) { - sprintf(xorriso->info_text, - "Closed media with data detected. Need blank or appendable media."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - if(burn_disc_erasable(drive)) { - sprintf(xorriso->info_text, "Try -blank as_needed\n"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0); - } - } else if(disc_state == BURN_DISC_EMPTY) { - sprintf(xorriso->info_text, "No media detected in drive"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } else { - sprintf(xorriso->info_text, - "Cannot recognize state of drive and media"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } - ret= 0; goto ex; - } - if(isoburn_needs_emulation(drive)) - burn_write_opts_set_multi(burn_options, 0); - - if(tsize > 0) { - fixed_size= tsize; - burn_track_set_size(track, fixed_size); - } - if(do_isosize) { - ret= burn_fifo_peek_data(xorriso->pacifier_fifo, head_buffer, 64*1024, 0); - if(ret<=0) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, - "Cannot obtain first 64 kB from input stream."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - /* read isosize from head_buffer, not from media*/ - ret= isoburn_read_iso_head(drive, 0, &isosize, head_buffer, (1<<13)); - if(ret<=0) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, - "Option -isosize given but data stream seems not to be ISO 9660"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - sprintf(xorriso->info_text, "Size of ISO 9660 image: %ds", isosize); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - fixed_size= ((off_t) (isosize)) * (off_t) 2048; - burn_track_set_size(track, fixed_size); - } - - ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2); - is_cd= (ret==2); - is_bd= (ret == 3); - - if(isoburn_needs_emulation(drive)) { - if(flag&1) { - ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &dummy, &nwa); - if(ret<=0) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, - "Cannot obtain next writeable address of emulated multi-session media\n"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - if(nwa==32) - nwa= 0; /* No automatic toc emulation. Formatter might not be aware. */ - burn_write_opts_set_start_byte(burn_options,((off_t) nwa) * (off_t) 2048); - } else { - nwa= 0; - burn_write_opts_set_start_byte(burn_options, (off_t) 0); - } - } - - if(write_start_address>=0) { - nwa= write_start_address / (off_t) 2048; - if(((off_t) nwa) * (off_t) 2048 < write_start_address ) - nwa++; - burn_write_opts_set_start_byte(burn_options, ((off_t) nwa) * (off_t) 2048); - } - - if(burn_write_opts_auto_write_type(burn_options, disc, reasons, 0) == - BURN_WRITE_NONE) { - sprintf(xorriso->info_text, - "Failed to find a suitable write mode with this media.\n"); - sprintf(xorriso->info_text+strlen(xorriso->info_text), - "Reasons given:\n%s", reasons); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - - ret= Xorriso_sanitize_image_size(xorriso, drive, disc, burn_options, 2); - if(ret<=0) - goto ex; - - /* Important: do not return until burn_is_aborting() was checked */ - Xorriso_set_signal_handling(xorriso, 1); - - xorriso->run_state= 1; /* Indicate that burning has started */ - burn_disc_write(burn_options, disc); - - ret= Xorriso_pacifier_loop(xorriso, drive, 2 | (is_cd << 4) | (is_bd << 5)); - if(burn_is_aborting(0)) - Xorriso_abort(xorriso, 0); /* Never comes back */ - Xorriso_set_signal_handling(xorriso, 0); - if(ret<=0) - goto ex; - if(!burn_drive_wrote_well(drive)) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, - "libburn indicates failure with writing."); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - - if(flag & 1) { - ret= Xorriso_update_iso_lba0(xorriso, nwa, isosize, head_buffer, NULL, - flag & 2); - if(ret <= 0) - goto ex; - } - sprintf(xorriso->info_text, "Writing to %s completed sucessfully.\n\n", - Text_shellsafe(xorriso->outdev,sfe,0)); - Xorriso_info(xorriso, 0); - ret= 1; -ex:; - Xorriso_process_msg_queues(xorriso,0); - if(disc!=NULL) - burn_disc_free(disc); - if(xorriso->pacifier_fifo!=NULL) - burn_source_free(xorriso->pacifier_fifo); - xorriso->pacifier_fifo= NULL; - xorriso->run_state= 0; /* Indicate that burning has ended */ - return(ret); -} - - -/* @param flag bit1= outdev rather than indev - @return <0 error, 0 = no profile to see , 1= ok , 2= ok, is CD profile - 3= ok, is BD profile -*/ -int Xorriso_get_profile(struct XorrisO *xorriso, int *profile_number, - char profile_name[80], int flag) -{ - int ret; - struct burn_drive_info *dinfo; - struct burn_drive *drive; - - *profile_number= 0; - profile_name[0]= 0; - if(((flag&2) && xorriso->out_drive_handle==NULL) || - ((!(flag&2)) && xorriso->in_drive_handle==NULL)) - return(0); - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to determine media type", flag&2); - if(ret<=0) - return(0); - ret=burn_disc_get_profile(drive, profile_number, profile_name); - if(ret<=0) - return(ret); - if(*profile_number==0x08 || *profile_number==0x09 || *profile_number==0x0a) - return(2); - if(*profile_number == 0x40 || *profile_number == 0x41 || - *profile_number == 0x42 || *profile_number == 0x43) - return(3); - return(0); -} - - - -int Xorriso_iso_file_open(struct XorrisO *xorriso, char *pathname, - void *node_pt, void **stream, int flag) -{ - int ret; - char eff_path[SfileadrL]; - IsoNode *node= NULL; - IsoFile *filenode= NULL; - IsoStream *iso_stream= NULL, *input_stream; - - *stream= NULL; - if(flag&1) { - node= (IsoNode *) node_pt; - } else { - ret= Xorriso_get_node_by_path(xorriso, pathname, eff_path, &node, 0); - if(ret<=0) - return(ret); - } - if(!LIBISO_ISREG(node)) { - sprintf(xorriso->info_text, - "Given path does not lead to a regular data file in the image"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - - filenode= (IsoFile *) node; - iso_stream= iso_file_get_stream(filenode); - if(iso_stream==NULL) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, - "Could not obtain source stream of file in the image for reading"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - if(flag & 2) { - /* Dig out the most original stream */ - while(1) { - input_stream= iso_stream_get_input_stream(iso_stream, 0); - if(input_stream == NULL) - break; - iso_stream= input_stream; - } - } - if(!iso_stream_is_repeatable(iso_stream)) { - sprintf(xorriso->info_text, - "The data production of the file in the image is one-time only"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - ret= iso_stream_open(iso_stream); - if(ret<0) { - sprintf(xorriso->info_text, - "Could not open data file in the image for reading"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - Xorriso_process_msg_queues(xorriso,0); - *stream= iso_stream; - -#ifdef NIX - /* <<< */ - { - unsigned int fs_id; - dev_t dev_id; - ino_t ino; - - iso_stream_get_id(iso_stream, &fs_id, &dev_id, &ino); - fprintf(stderr, "xorriso_debug: iso_ino= %ld\n", (long int) ino); - } -#endif - - return(1); -} - - -int Xorriso_iso_file_read(struct XorrisO *xorriso, void *stream, char *buf, - int count, int flag) -{ - int ret, rcnt= 0; - IsoStream *stream_pt; - - stream_pt= (IsoStream *) stream; - - while(rcntsplit_size <= 0 -*/ -int Xorriso_identify_split(struct XorrisO *xorriso, char *iso_adr, - void *in_node, - struct SplitparT **parts, int *count, - struct stat *total_stbuf, int flag) -{ - int ret, i, incomplete= 0, overlapping= 0; - int partno, total_parts, first_total_parts= -1; - off_t offset, bytes, total_bytes, first_total_bytes= -1, first_bytes= -1; - off_t size, covered; - - IsoImage *volume; - IsoDir *dir_node; - IsoDirIter *iter= NULL; - IsoNode *node; - char *name; - struct stat stbuf, first_stbuf; - - *count= 0; - *parts= NULL; - - if(xorriso->split_size <= 0 && !(flag & 4)) - return(0); - - if(flag&1) { - node= (IsoNode *) in_node; - } else { - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - return(-1); - ret= Xorriso_node_from_path(xorriso, volume, iso_adr, &node, 1); - if(ret<=0) - return(-1); - } - if(!LIBISO_ISDIR(node)) - return(0); - dir_node= (IsoDir *) node; - - ret= iso_dir_get_children(dir_node, &iter); - if(ret<0) { -cannot_iter:; - Xorriso_cannot_create_iter(xorriso, ret, 0); - return(-1); - } - - for(i= 0; iso_dir_iter_next(iter, &node) == 1; i++) { - name= (char *) iso_node_get_name(node); - ret= Splitpart__parse(name, &partno, &total_parts, - &offset, &bytes, &total_bytes, 0); - if(ret<=0) - {ret= 0; goto ex;} - if(i==0) { - first_total_parts= total_parts; - first_bytes= bytes; - first_total_bytes= total_bytes; - Xorriso_fake_stbuf(xorriso, "", &first_stbuf, &node, 1); - size= first_stbuf.st_size; - } else { - if(first_total_parts!=total_parts || first_total_bytes!=total_bytes || - (first_bytes!=bytes && partno!=total_parts)) - {ret= 0; goto ex;} - Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1); - if(first_stbuf.st_mode != stbuf.st_mode || - first_stbuf.st_uid != stbuf.st_uid || - first_stbuf.st_gid != stbuf.st_gid || - first_stbuf.st_mtime != stbuf.st_mtime || - first_stbuf.st_ctime != stbuf.st_ctime) - {ret= 0; goto ex;} - size= stbuf.st_size; - } - /* check for plausible size */ - if(!((partno != total_parts && size == bytes) || - (partno == total_parts && size <= bytes))) - {ret= 0; goto ex;} - if(offset != first_bytes * (off_t) (partno - 1)) - {ret= 0; goto ex;} - (*count)++; - } - if(*count <= 0 || *count != first_total_parts) - {ret= 0; goto ex;} - - ret= Splitparts_new(parts, (*count)+1, 0); /* (have one end marker item) */ - if(ret<=0) - return(ret); - - iso_dir_iter_free(iter); - ret= iso_dir_get_children(dir_node, &iter); - if(ret<0) - goto cannot_iter; - for(i= 0; i<*count; i++) { - ret= iso_dir_iter_next(iter, &node); - if(ret!=1) - break; - name= (char *) iso_node_get_name(node); - ret= Splitpart__parse(name, &partno, &total_parts, - &offset, &bytes, &total_bytes, 0); - if(ret<=0) - {ret= 0; goto ex;} - ret= Splitparts_set(*parts, i, name, partno, total_parts, offset, bytes, - total_bytes, 0); - if(ret<=0) - goto ex; - } - - Splitparts_sort(*parts, *count, 0); - - covered= 0; - for(i= 0; i<*count; i++) { - Splitparts_get(*parts, i, &name, &partno, &total_parts, &offset, &bytes, - &total_bytes, 0); - if(offset>covered) - incomplete= 1; - else if(offset covered) - covered= offset+bytes; - } - if(total_bytes>covered) - incomplete= 1; - memcpy(total_stbuf, &first_stbuf, sizeof(struct stat)); - total_stbuf->st_size= total_bytes; - ret= !(overlapping || incomplete); -ex:; - if(iter!=NULL) - iso_dir_iter_free(iter); - return(ret); -} - - -/* @param flag bit0= node is valid, do not resolve path - bit1= insist in complete collection of part files -*/ -int Xorriso_is_split(struct XorrisO *xorriso, char *path, void *node, - int flag) -{ - struct SplitparT *split_parts= NULL; - int split_count= 0, ret; - struct stat stbuf; - - ret= Xorriso_identify_split(xorriso, path, node, &split_parts, - &split_count, &stbuf, flag & 3); - if(split_parts!=NULL) - Splitparts_destroy(&split_parts, split_count, 0); - return(ret>0); -} - - -/* @param flag bit0= grow_overwriteable_iso - bit1= obtain info from outdev - bit2= no need to obtain msc2 (NWA) -*/ -int Xorriso_msinfo(struct XorrisO *xorriso, int *msc1, int *msc2, int flag) -{ - int ret, dummy; - struct burn_drive *drive; - struct burn_drive_info *dinfo; - enum burn_disc_status disc_state; - - *msc1= *msc2= -1; - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to obtain msinfo", flag&2); - if(ret<=0) - return(ret); - - if(flag&1) - disc_state= isoburn_disc_get_status(drive); - else - disc_state= burn_disc_get_status(drive); - if(disc_state != BURN_DISC_APPENDABLE && - !(disc_state == BURN_DISC_FULL && (flag & 4))) { - Xorriso_process_msg_queues(xorriso,0); - if(!(flag & 4)) { - sprintf(xorriso->info_text, - "%s media is not appendable. Cannot obtain -msinfo.", - (flag&2) ? "Output" : "Input"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } - return(0); - } - ret= isoburn_disc_get_msc1(drive, msc1); - if(ret<=0) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, "Cannot obtain address of most recent session"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - if(flag & 4) - return(1); - ret= isoburn_disc_track_lba_nwa(drive, NULL, 0, &dummy, msc2); - if(ret<0) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, "Cannot obtain next writeable address on media"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - return(1); -} - -/* @param flag bit0= this is a follow-up session (i.e. on CD: TAO) - bit1= no pacifier messages - bit2= compute stream MD5 and look out for checksum tag - @return <=0 error, 1= done, 2= aborted due to limit -*/ -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 i, j, ret, total_count= 0, sectors= -1, sector_size= -1, skip_reading; - int prev_quality= -1, quality= -1, retry= 0, profile_no, is_cd= 0; - int start_sec, end_sec, first_value, fret; - char profile_name[80]; - int start_lba= 0; - struct burn_drive *drive; - struct burn_drive_info *dinfo; - char data[64*1024], sfe[5*SfileadrL]; - off_t data_count, to_read, read_count= 0, write_amount; - double pre_read_time, post_read_time, time_diff, total_time_diff= 0; - double last_abort_file_time= 0; - struct stat stbuf; - void *ctx= NULL, *cloned_ctx= NULL; - char md5[16], tag_md5[16]; - uint32_t pos, range_start, range_size, next_tag= 0, lba, md5_spot_lba= 0; - int md5_spot_value= Xorriso_read_quality_untesteD, chain_broken= 0; - int tag_type= 0, valid, was_sb_tag= 0, in_track_gap= 0; - char *comparison= "", *sev_text= "DEBUG", *tag_type_name= ""; - - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to check media readability", - 2 * !!job->use_dev); - if(ret<=0) - goto ex; - ret= burn_disc_get_profile(drive, &profile_no, profile_name); - if(ret > 0) - if(profile_no >= 0x08 && profile_no <= 0x0a) - is_cd= 1; - - if(job->sector_map != NULL) { - Sectorbitmap_get_layout(job->sector_map, §ors, §or_size, 0); - sector_size/= 2048; - } - - if(job->retry > 0) - retry= 1; - else if(job->retry == 0 && is_cd) - retry= 1; - - if(flag & 4) { - ret= iso_md5_start(&ctx); - if(ret < 0) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - ret= -1; goto ex; - } - } - - start_lba= from_lba; - to_read= read_chunk; - post_read_time= Sfile_microtime(0); - for(i= 0; i < block_count; i+= to_read) { - skip_reading= 0; - - if(job->abort_file_path[0]) { - if(post_read_time - last_abort_file_time >= 0.1) { - if(stat(job->abort_file_path, &stbuf) != -1) { - if(stbuf.st_mtime >= xorriso->start_time) { - sprintf(xorriso->info_text, - "-check_media: Found fresh abort_file=%s", - job->abort_file_path); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - goto abort_check; - } - } - last_abort_file_time= post_read_time; - } - } - if(job->item_limit > 0 && - Spotlist_count(spotlist, 0) + 2 >= job->item_limit) { - sprintf(xorriso->info_text, "-check_media: Reached item_limit=%d", - job->item_limit); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - goto abort_check; - } - pre_read_time= Sfile_microtime(0); - if(job->time_limit > 0 - && job->start_time + job->time_limit < pre_read_time) { - sprintf(xorriso->info_text, "-check_media: Reached time_limit=%d", - job->time_limit); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); -abort_check:; - if(prev_quality >= 0) { - ret= Spotlist_add_item(spotlist, start_lba, i + from_lba - start_lba, - prev_quality, 0); - if(ret <= 0) - goto ex; - } - ret= Spotlist_add_item(spotlist, i + from_lba, block_count - i, - Xorriso_read_quality_untesteD, 0); - if(ret > 0) - ret= 2; - goto ex; - } - - to_read= read_chunk; - if(i + to_read > block_count) - to_read= block_count - i; - if(is_cd && i + to_read + 2 >= block_count) { - /* Read last 2 blocks of CD track separately, because with TAO tracks - they are always unreadable but with SAO tracks they contain data. - */ - if(to_read > 2) - to_read-= 2; - else if(to_read > 1) { - if(flag & 1) { - quality= Xorriso_read_quality_tao_enD; - skip_reading= 1; - } else - to_read--; - } - } - - if(sector_size == read_chunk && from_lba % read_chunk == 0 - && !skip_reading) { - if(Sectorbitmap_is_set(job->sector_map, (i + from_lba) / sector_size, 0)){ - quality= Xorriso_read_quality_valiD; - skip_reading= 1; - } - } else if(sector_size > 0 && !skip_reading) { - start_sec= (i + from_lba) / sector_size; - end_sec= (i + to_read + from_lba) / sector_size; - first_value= Sectorbitmap_is_set(job->sector_map, start_sec, 0); - for(j= start_sec; j < end_sec; j++) - if(Sectorbitmap_is_set(job->sector_map, j, 0) != first_value) - break; - to_read= j * sector_size - i - from_lba; - skip_reading= !!first_value; - if(skip_reading) - quality= Xorriso_read_quality_valiD; - } - - if(skip_reading) { - pre_read_time= post_read_time= Sfile_microtime(0); - } else { - data_count= 0; - pre_read_time= Sfile_microtime(0); - ret= burn_read_data(drive, ((off_t) (i + from_lba)) * (off_t) 2048, data, - to_read * (off_t) 2048, &data_count, 4 * !retry); - post_read_time= Sfile_microtime(0); - time_diff= post_read_time - pre_read_time; - total_time_diff+= time_diff; - total_count++; - if(ret <= 0) { - Xorriso_process_msg_queues(xorriso,0); - if(data_count / 2048 < to_read) { - if(data_count > 0 && retry) { - if(prev_quality >= 0) { - ret= Spotlist_add_item(spotlist, start_lba, - i + from_lba - start_lba, prev_quality, 0); - if(ret <= 0) - goto ex; - } - ret= Spotlist_add_item(spotlist, i + from_lba, data_count / 2048, - Xorriso_read_quality_partiaL, 0); - if(ret <= 0) - goto ex; - start_lba= i + from_lba + data_count / 2048; - prev_quality= Xorriso_read_quality_unreadablE; - } - quality= Xorriso_read_quality_unreadablE; - if(retry) - to_read= data_count / 2048 + 1; - } else - quality= Xorriso_read_quality_partiaL; - fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); - if(fret<0) - goto ex; - } else { - quality= Xorriso_read_quality_gooD; - if(time_diff > job->slow_threshold_seq && job->slow_threshold_seq > 0 && - i > 0) - quality= Xorriso_read_quality_sloW; - } - - /* MD5 checksumming */ - if(ctx != NULL) { - for(j= 0; j < to_read; j++) { - lba= i + j + from_lba; - if(lba < md5_start) - continue; - ret= 0; - if(lba > md5_start + 16 && - (next_tag == 0 || chain_broken || lba == next_tag)) { - ret= iso_util_decode_md5_tag(data + j * 2048, &tag_type, - &pos, &range_start, &range_size, - &next_tag, tag_md5, !!chain_broken); - } - valid= (ret == 1 || ret == ISO_MD5_AREA_CORRUPTED) && pos == lba; - if(valid && tag_type == 2 && (lba < md5_start + 32 || in_track_gap)) { - tag_type_name= "superblock"; - was_sb_tag= 1; - if(in_track_gap && range_start != md5_start && range_start < lba && - lba - range_start <= j) { - /* Looking for next session : start computing in hindsight. - Session start and superblock tag are supposed to be in the - same 64 kB chunk. - */ - iso_md5_end(&ctx, md5); - ret= iso_md5_start(&ctx); - if(ret < 0) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - ret= -1; goto ex; - } - iso_md5_compute(&ctx, data + (j - (lba - range_start)) * 2048, - (lba - range_start) * 2048); - md5_start= range_start; - in_track_gap= 0; - } - } else if(valid && tag_type == 4 && lba < 32) { - tag_type_name= "relocated 64kB superblock"; - }else if(valid && tag_type == 3 && was_sb_tag) { - tag_type_name= "tree"; - }else if(valid && tag_type == 1) { - - /* >>> ??? allow this without superblock and tree tag ? */ - - tag_type_name= "session"; - } else { - tag_type_name= ""; - } - if (tag_type_name[0]) { - if(range_start != md5_start) { - sprintf(xorriso->info_text, - "Found MD5 %s tag which covers different data range", - tag_type_name); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0); - sprintf(xorriso->info_text, - " Expected: %u Found: %u", - (unsigned int) md5_start, range_start); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0); - chain_broken= 1; - valid= 0; - } else { - ret= iso_md5_clone(ctx, &cloned_ctx); - if(ret <= 0) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - ret= -1; goto ex; - } - iso_md5_end(&cloned_ctx, md5); - - if(ret == ISO_MD5_AREA_CORRUPTED) { - comparison= "CORRUPTED"; - sev_text= "WARNING"; - md5_spot_value= Xorriso_read_quality_md5_mismatcH; - chain_broken= 1; - } else if(! iso_md5_match(tag_md5, md5)) { - comparison= "NON-MATCHING"; - sev_text= "WARNING"; - md5_spot_value= Xorriso_read_quality_md5_mismatcH; - chain_broken= 1; - } else { - comparison= "matching"; - sev_text= "UPDATE"; - md5_spot_value= Xorriso_read_quality_md5_matcH; - } - md5_spot_lba= lba; - sprintf(xorriso->info_text, - "Found %s MD5 %s tag: start=%d size=%d", - comparison, tag_type_name, md5_start, lba - md5_start); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, - sev_text, 0); - } - if(valid && (tag_type == 1 || - (tag_type == 4 && pos == lba && lba < 32))) { - if(md5_spot_value != Xorriso_read_quality_untesteD) { - ret= Spotlist_add_item(spotlist, md5_start, - md5_spot_lba - md5_start, md5_spot_value, 0); - if(ret <= 0) - goto ex; - } - md5_spot_value= Xorriso_read_quality_untesteD; - md5_start = lba + 1; - if (md5_start % 32) - md5_start= md5_start + (32 - (md5_start % 32)); - next_tag= 0; - - iso_md5_end(&ctx, md5); - ret= iso_md5_start(&ctx); - if(ret < 0) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - ret= -1; goto ex; - } - if(tag_type == 1) - in_track_gap= 1; - continue; - } - } - iso_md5_compute(ctx, data + j * 2048, 2048); - } - } - - write_amount= data_count; - if(data_count > 0) { - read_count+= data_count; - if(job->data_to_limit >= 0 && read_count > job->data_to_limit) - write_amount-= (read_count - job->data_to_limit); - } - if(write_amount > 0) { - if(job->data_to_fd >= 0) { - ret= lseek(job->data_to_fd, - ((off_t) (i + from_lba)) * (off_t) 2048 + job->data_to_offset, - SEEK_SET); - if(ret == -1) { -failed_to_write:; - sprintf(xorriso->info_text, "Cannot write %d bytes to lba %d of %s", - (int) data_count, i + from_lba, - Text_shellsafe(job->data_to_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, - "FAILURE", 0); - {ret= 0; goto ex;} - } - ret= write(job->data_to_fd, data, write_amount); - if(ret == -1) - goto failed_to_write; - } - } - } - if(quality != prev_quality) { - if(prev_quality >= 0) { - ret= Spotlist_add_item(spotlist, start_lba, i + from_lba - start_lba, - prev_quality, 0); - if(ret <= 0) - goto ex; - } - start_lba= i + from_lba; - prev_quality= quality; - } - if(!(flag & 2)) { - xorriso->pacifier_count+= to_read; - if(post_read_time - xorriso->last_update_time >= - xorriso->pacifier_interval) - Xorriso_pacifier_callback(xorriso, "sectors examined", - xorriso->pacifier_count, xorriso->pacifier_total, "", 0); - } - } - if(prev_quality >= 0) { - ret= Spotlist_add_item(spotlist, start_lba, - block_count + from_lba - start_lba, prev_quality, 0); - if(ret <= 0) - goto ex; - } - - /* <<< for calibration of quality */ - if(total_count > 0) { - sprintf(xorriso->info_text, "Xorriso_check_interval: %.1f s / %d = %f", - total_time_diff, total_count, total_time_diff / total_count); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - } - - - /* MD5 checksumming : register result */ - - /* >>> ??? allow chain_broken to be a match ? */ - - if(next_tag > 0) { - sprintf(xorriso->info_text, "Missing announced MD5 tag: start=%d pos=%d", - md5_start, next_tag); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - md5_spot_value= Xorriso_read_quality_md5_mismatcH; - md5_spot_lba= next_tag; - } - if(md5_spot_value != Xorriso_read_quality_untesteD) { - ret= Spotlist_add_item(spotlist, md5_start, md5_spot_lba - md5_start, - md5_spot_value, 0); - if(ret <= 0) - goto ex; - } - - ret= 1; -ex: - if(ctx != NULL) - iso_md5_end(&ctx, md5); - return(ret); -} - - -int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist, - struct CheckmediajoB *job, int flag) -{ - int media_blocks= 0, read_chunk= 16, ret, mode, start_lba= 0; - int blocks, os_errno, i, j, last_track_end= -1, track_blocks, track_lba; - int num_sessions, num_tracks, declare_untested= 0, md5_start; - int read_capacity= -1, end_lba, hret, count, quality; - char *toc_info= NULL; - struct burn_drive *drive; - struct burn_drive_info *dinfo; - struct isoburn_toc_disc *isoburn_disc= NULL; - struct isoburn_toc_session **isoburn_sessions; - struct isoburn_toc_track **iso_burn_tracks; - struct burn_toc_entry isoburn_entry; - struct stat stbuf; - struct burn_multi_caps *caps= NULL; - - *spotlist= NULL; - - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to check media readability", - 2 * !!job->use_dev); - if(ret<=0) - goto ex; - - /* >>> determine media type dependent blocking factor: - 32 kB for CD (with 2kB retry) and DVD, 64 kB for BD - eventually adjust read_chunk - */; - if(job->min_block_size != 0) - read_chunk= job->min_block_size; - - ret= Spotlist_new(spotlist, 0); - if(ret <= 0) - {ret= -1; goto ex;} - - if(job->sector_map_path[0]) { - Sectorbitmap_destroy(&(job->sector_map), 0); - if(stat(job->sector_map_path, &stbuf) != -1) { - ret= Sectorbitmap_from_file(&(job->sector_map), job->sector_map_path, - xorriso->info_text, &os_errno, 0); - if(ret <= 0) { - if(xorriso->info_text[0]) - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, os_errno, - "FAILURE", 0); - goto ex; - } - } - Xorriso_toc_to_string(xorriso, &toc_info, 4 * !job->map_with_volid); - } - ret= Xorriso_open_job_data_to(xorriso, job, 0); - if(ret <= 0) - goto ex; - Xorriso_pacifier_reset(xorriso, 0); - job->start_time= time(NULL); - mode= job->mode; - if(job->min_lba > 0) { - start_lba= job->min_lba; - ret= Spotlist_add_item(*spotlist, 0, job->min_lba, - Xorriso_read_quality_untesteD, 0); - if(ret <= 0) - goto ex; - } - ret= burn_get_read_capacity(drive, &read_capacity, 0); - if(ret <= 0) - read_capacity= -1; - - if(job->max_lba >= 0) { - blocks= job->max_lba + 1 - start_lba; - xorriso->pacifier_total= blocks; - ret= Xorriso_check_interval(xorriso, *spotlist, job, start_lba, blocks, - read_chunk, 0, 0); - if(ret <= 0) - goto ex; - - } else if(mode == 0) { /* track by track */ - isoburn_disc= isoburn_toc_drive_get_disc(drive); - if(isoburn_disc == NULL) - goto no_content_visible; - isoburn_sessions= - isoburn_toc_disc_get_sessions(isoburn_disc, &num_sessions); - for(i= 0; i < num_sessions; i++) { - iso_burn_tracks= isoburn_toc_session_get_tracks(isoburn_sessions[i], - &num_tracks); - for(j= 0; j < num_tracks; j++) { - isoburn_toc_track_get_entry(iso_burn_tracks[j], &isoburn_entry); - if(!(isoburn_entry.extensions_valid & 1)) /* should not happen */ - continue; - track_lba= isoburn_entry.start_lba; - track_blocks= isoburn_entry.track_blocks; - md5_start= track_lba; - if(i == 0 && j == 0) { - if(track_lba == 32) { - ret= burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0); - if(ret > 0) { - if(caps->start_adr) { - /* block 0 to 31 are the overall mount entry of overwriteable */ - track_lba= 0; - track_blocks+= 32; - } - } - } - } - if(last_track_end >= 0 && last_track_end < track_lba && - last_track_end >= start_lba) { - ret= Spotlist_add_item(*spotlist, last_track_end, - track_lba - last_track_end, - Xorriso_read_quality_off_tracK, 0); - if(ret <= 0) - goto ex; - xorriso->pacifier_count+= track_lba - last_track_end; - } - last_track_end= track_lba + track_blocks; - - if(track_lba < start_lba) { - track_blocks-= start_lba - track_lba; - track_lba= start_lba; - } - if(track_blocks <= 0) - continue; - if(declare_untested) { - ret= Spotlist_add_item(*spotlist, track_lba, track_blocks, - Xorriso_read_quality_untesteD, 0); - if(ret <= 0) - goto ex; - } else { - ret= Xorriso_check_interval(xorriso, *spotlist, job, track_lba, - track_blocks, read_chunk, md5_start, - (i > 0) | (4 * (xorriso->do_md5 & 1))); - if(ret <= 0) - goto ex; - if(ret == 2) - declare_untested= 1; - } - } - } - - } else if(mode == 1) { /* isoburn disc capacity */ - isoburn_disc= isoburn_toc_drive_get_disc(drive); - if(isoburn_disc == NULL) { -no_content_visible:; - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, "No content detected on media"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - {ret= 0; goto ex;} - } - blocks= media_blocks= isoburn_toc_disc_get_sectors(isoburn_disc); - if(start_lba >= 0) - blocks-= start_lba; - if(media_blocks <= 0) - goto no_content_visible; - xorriso->pacifier_total= blocks; - ret= Xorriso_check_interval(xorriso, *spotlist, job, start_lba, blocks, - read_chunk, 0, 0); - if(ret <= 0) - goto ex; - } else if(mode == 2) { - - /* >>> single sweep over libburn media capacity */; - - } - - Xorriso_pacifier_callback(xorriso, "sectors examined", - xorriso->pacifier_count, xorriso->pacifier_total, "", 1); - ret= 1; -ex:; - - if(job->data_to_fd != -1) - close(job->data_to_fd); - job->data_to_fd= -1; - - if(read_capacity >= 0) { - count= Spotlist_count(*spotlist, 0); - end_lba= 0; - for(i= 0; i < count; i++) { - Spotlist_get_item(*spotlist, i, &start_lba, &blocks, &quality, 0); - if(start_lba + blocks > end_lba) - end_lba= start_lba + blocks; - } - if(read_capacity > end_lba) { - hret= Spotlist_add_item(*spotlist, end_lba, read_capacity - end_lba, - Xorriso_read_quality_untesteD, 0); - if(hret < ret) - ret= hret; - } - } - - if(ret > 0) - ret= Xorriso_update_in_sector_map(xorriso, *spotlist, read_chunk, job, 0); - - if(ret > 0) { - ret= Xorriso_spotlist_to_sectormap(xorriso, *spotlist, read_chunk, - &(job->sector_map), !!job->untested_valid); - if(ret > 0 && job->sector_map_path[0]) { - ret= Sectorbitmap_to_file(job->sector_map, job->sector_map_path, toc_info, - xorriso->info_text, &os_errno, 0); - if(ret <= 0) { - if(xorriso->info_text[0]) - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, os_errno, - "FAILURE", 0); - } - } - } - if(toc_info != NULL) - free(toc_info); - if(ret <= 0) - Spotlist_destroy(spotlist, 0); - if(caps!=NULL) - burn_disc_free_multi_caps(&caps); - return(ret); -} - - -/* @param flag bit1= for Xorriso_check_interval(): no pacifier messages -*/ -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) -{ - int ret, i, lba_count= 0, *start_lbas= NULL, *end_lbas= NULL, read_chunk= 16; - int lba, count, blocks, quality, spot, bad_extract= 0; - off_t size= 0, file_base_bytes= 0, file_processed_bytes= 0, img_adr; - off_t new_file_base_bytes, upto_file_bytes, start_byte= 0; - char sfe[5*SfileadrL]; - struct SpotlisT *spotlist= NULL; - struct CheckmediajoB *job= NULL; - - upto_file_bytes= img_offset + bytes; - - /* >>> make Xorriso_check_interval() ready for copying in byte granularity */ - if(img_offset % (off_t) 2048) { - sprintf(xorriso->info_text, - "Image address offset is not a multiple of 2048"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - - ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas, &size, - 0); - if(ret <= 0) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, - "File object %s is currently not a data file from the loaded image", - Text_shellsafe(img_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - goto ex; - } - if(img_offset + bytes < size && bytes > 0) - size= img_offset + bytes; - - ret= Checkmediajob_new(&job, 0); - if(ret <= 0) - goto ex; - if(xorriso->check_media_default != NULL) - Checkmediajob_copy(xorriso->check_media_default, job, 0); - job->min_lba= -1; - job->max_lba= -1; - job->sector_map_path[0]= 0; - - ret= Spotlist_new(&spotlist, 0); - if(ret <= 0) - {ret= -1; goto ex;} - - if(Sfile_str(job->data_to_path, disk_path, 0) <= 0) - {ret= -1; goto ex;} - Xorriso_open_job_data_to(xorriso, job, 0); - if(ret <= 0) - goto ex; - - for(i= 0; i < lba_count && file_base_bytes < upto_file_bytes; i++) { - lba= start_lbas[i]; - count= end_lbas[i] + 1 - start_lbas[i]; - new_file_base_bytes= file_base_bytes + ((off_t) count) * (off_t) 2048; - - /* skip intervals before img_offset */ - if(new_file_base_bytes <= img_offset) { - file_base_bytes= new_file_base_bytes; - continue; - } - /* Eventually adjust first interval start */ - img_adr= ((off_t) lba) * (off_t) 2048; - if(file_base_bytes < img_offset) { - img_adr+= img_offset - file_base_bytes; - lba= img_adr / (off_t) 2048; - count= end_lbas[i] + 1 - lba; - file_base_bytes= img_offset; - } - - /* Eventually omit surplus blocks */ - if(new_file_base_bytes > upto_file_bytes) - count-= (new_file_base_bytes - upto_file_bytes) / (off_t) 2048; - /* Adjust job */ - job->data_to_offset= file_processed_bytes - img_adr + disk_offset; - job->data_to_limit= size - file_base_bytes; - - file_processed_bytes+= ((off_t) count) * (off_t) 2048; - ret= Xorriso_check_interval(xorriso, spotlist, job, lba, count, read_chunk, - 0, (flag & 2)); - if(ret <= 0) - goto ex; - if (ret == 2) { - sprintf(xorriso->info_text, "Attempt aborted to extract data from %s", - Text_shellsafe(img_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - file_base_bytes= new_file_base_bytes; - } - - /* Use spotlist to evaluate damage */ - file_base_bytes= 0; - count= Spotlist_count(spotlist, 0); - for(spot= 0; spot < count; spot++) { - ret= Spotlist_get_item(spotlist, spot, &lba, &blocks, &quality, 0); - if(ret <= 0) - continue; - if(quality < Xorriso_read_quality_valiD) { - for(i= 0; i < lba_count; i++) { - if(start_lbas[i] <= lba && end_lbas[i] >= lba) { - start_byte= (lba - start_lbas[i]) * (off_t) 2048 + file_base_bytes; - break; - } - file_base_bytes+= ((off_t) (end_lbas[i] + 1 - start_lbas[i])) - * (off_t) 2048; - } - if(i < lba_count) { - sprintf(xorriso->info_text, "Bad extract : %14.f , %14.f , %s\n", - (double) start_byte, ((double) blocks) * 2048.0, - Text_shellsafe(disk_path, sfe, 0)); - Xorriso_info(xorriso, 0); - bad_extract= 1; - } - } - } - - ret= !bad_extract; -ex:; - if(start_lbas != NULL) - free((char *) start_lbas); - if(end_lbas != NULL) - free((char *) end_lbas); - Spotlist_destroy(&spotlist, 0); - Checkmediajob_destroy(&job, 0); - return(ret); -} - - -int Xorriso_extract_cut(struct XorrisO *xorriso, - char *img_path, char *disk_path, - off_t img_offset, off_t bytes, int flag) -{ - int ret, stbuf_ret, read_raw; - double mem_lut= 0.0; - char eff_img_path[SfileadrL], eff_disk_path[SfileadrL], sfe[SfileadrL*5]; - IsoImage *volume; - IsoNode *node; - - ret= Xorriso_get_volume(xorriso, &volume, 0); - if(ret<=0) - return(ret); - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, - img_path, eff_img_path, 0); - if(ret<=0) - return(ret); - ret= Xorriso_node_from_path(xorriso, volume, eff_img_path, &node, 0); - if(ret<=0) - return(ret); - ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, - disk_path, eff_disk_path, 2 | 4); - if(ret<=0) - return(ret); - Xorriso_pacifier_reset(xorriso, 0); - mem_lut= xorriso->last_update_time; - - ret= Xorriso_handle_collision(xorriso, node, img_path, eff_disk_path, - disk_path, &stbuf_ret, 0); - if(ret<=0 || ret==3) - return(0); - - /* If it is a non-filtered stream from the ISO image - and img_offset is a multiple of 2048 - then use Xorriso_read_file_data() for random access offset. - */ - if(!LIBISO_ISREG(node)) { - Xorriso_msgs_submit(xorriso, 0, eff_disk_path, 0, "ERRFILE", 0); - sprintf(xorriso->info_text, "-extract_cut: ISO file %s is not a data file", - Text_shellsafe(eff_img_path, sfe, 0)); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - read_raw= 0; - if((img_offset % 2048) == 0) { - ret= Xorriso_is_plain_image_file(xorriso, node, "", 0); - if(ret > 0) - read_raw= 1; - } - if (read_raw) { - ret= Xorriso_read_file_data(xorriso, node, eff_img_path, eff_disk_path, - img_offset, (off_t) 0, bytes, 0); - if(ret<=0) - return(ret); - } else { - ret= Xorriso_tree_restore_node(xorriso, node, eff_img_path, img_offset, - eff_disk_path, (off_t) 0, bytes, 2 | 8); - if(ret<=0) - return(ret); - } - - ret= Xorriso_restore_properties(xorriso, eff_disk_path, node, 0); - if(ret<=0) - return(ret); - - if(mem_lut != xorriso->last_update_time) - Xorriso_pacifier_callback(xorriso, "sectors examined", - xorriso->pacifier_count, 0, "", 1); - return(1); -} - - -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_relax_compliance(struct XorrisO *xorriso, char *mode, - int flag) -{ - char *npt, *cpt; - int l, was; - - was= xorriso->relax_compliance; - npt= cpt= mode; - for(; npt!=NULL; cpt= npt+1) { - npt= strchr(cpt,':'); - if(npt==NULL) - l= strlen(cpt); - else - l= npt-cpt; - if(l == 0) - continue; - if((l == 6 && strncmp(cpt, "strict", l) == 0) || - (l == 5 && strncmp(cpt, "clear", l) == 0)) { - xorriso->relax_compliance= 0; - } else if(l == 7 && strncmp(cpt, "default", l) == 0) { - xorriso->relax_compliance= Xorriso_relax_compliance_defaulT; - - } else if((l == 12 && strncmp(cpt, "omit_version", l) == 0) || - (l == 15 && strncmp(cpt, "omit_version_on", l) == 0) ) { - xorriso->relax_compliance|= isoburn_igopt_omit_version_numbers; - } else if((l == 16 && strncmp(cpt, "omit_version_off", l) == 0)) { - xorriso->relax_compliance&= ~isoburn_igopt_omit_version_numbers; - - } else if((l == 16 && strncmp(cpt, "only_iso_version", l) == 0) || - (l == 19 && strncmp(cpt, "only_iso_version_on", l) == 0) ) { - xorriso->relax_compliance|= isoburn_igopt_only_iso_versions; - } else if((l == 20 && strncmp(cpt, "only_iso_version_off", l) == 0)) { - xorriso->relax_compliance&= ~isoburn_igopt_only_iso_versions; - - } else if((l == 10 && strncmp(cpt, "deep_paths", l) == 0) || - (l == 13 && strncmp(cpt, "deep_paths_on", l) == 0)) { - xorriso->relax_compliance|= isoburn_igopt_allow_deep_paths; - } else if(l == 14 && strncmp(cpt, "deep_paths_off", l) == 0) { - xorriso->relax_compliance&= ~isoburn_igopt_allow_deep_paths; - - } else if((l == 10 && strncmp(cpt, "long_paths", l) == 0) || - (l == 13 && strncmp(cpt, "long_paths_on", l) == 0) ) { - xorriso->relax_compliance|= isoburn_igopt_allow_longer_paths; - } else if(l == 14 && strncmp(cpt, "long_paths_off", l) == 0) { - xorriso->relax_compliance&= ~isoburn_igopt_allow_longer_paths; - - } else if((l == 10 && strncmp(cpt, "long_names", l) == 0) || - (l == 13 && strncmp(cpt, "long_names_on", l) == 0)) { - xorriso->relax_compliance|= isoburn_igopt_max_37_char_filenames; - } else if(l == 14 && strncmp(cpt, "long_names_off", l) == 0) { - xorriso->relax_compliance&= ~isoburn_igopt_max_37_char_filenames; - - } else if((l == 13 && strncmp(cpt, "no_force_dots", l) == 0) || - (l == 16 && strncmp(cpt, "no_force_dots_on", l) == 0)) { - xorriso->relax_compliance|= isoburn_igopt_no_force_dots; - } else if(l == 17 && strncmp(cpt, "no_force_dots_off", l) == 0) { - xorriso->relax_compliance&= ~isoburn_igopt_no_force_dots; - - } else if((l == 15 && strncmp(cpt, "no_j_force_dots", l) == 0) || - (l == 18 && strncmp(cpt, "no_j_force_dots_on", l) == 0)) { - xorriso->relax_compliance|= isoburn_igopt_no_j_force_dots; - } else if(l == 19 && strncmp(cpt, "no_j_force_dots_off", l) == 0) { - xorriso->relax_compliance&= ~isoburn_igopt_no_j_force_dots; - - } else if((l == 9 && strncmp(cpt, "lowercase", l) == 0) || - (l == 12 && strncmp(cpt, "lowercase_on", l) == 0)) { - xorriso->relax_compliance|= isoburn_igopt_allow_lowercase; - } else if(l == 13 && strncmp(cpt, "lowercase_off", l) == 0) { - xorriso->relax_compliance&= ~isoburn_igopt_allow_lowercase; - - } else if((l == 10 && strncmp(cpt, "full_ascii", l) == 0) || - (l == 13 && strncmp(cpt, "full_ascii_on", l) == 0)) { - xorriso->relax_compliance|= isoburn_igopt_allow_full_ascii; - } else if(l == 14 && strncmp(cpt, "full_ascii_off", l) == 0) { - xorriso->relax_compliance&= ~isoburn_igopt_allow_full_ascii; - - } else if((l == 17 && strncmp(cpt, "joliet_long_paths", l) == 0) || - (l == 20 && strncmp(cpt, "joliet_long_paths_on", l) == 0)) { - xorriso->relax_compliance|= isoburn_igopt_joliet_longer_paths; - } else if(l == 21 && strncmp(cpt, "joliet_long_paths_off", l) == 0) { - xorriso->relax_compliance&= ~isoburn_igopt_joliet_longer_paths; - - } else if((l == 10 && strncmp(cpt, "always_gmt", l) == 0) || - (l == 13 && strncmp(cpt, "always_gmt_on", l) == 0)) { - xorriso->relax_compliance|= isoburn_igopt_always_gmt; - } else if(l == 14 && strncmp(cpt, "always_gmt_off", l) == 0) { - xorriso->relax_compliance&= ~isoburn_igopt_always_gmt; - - } else if((l == 9 && strncmp(cpt, "rec_mtime", l) == 0) || - (l == 12 && strncmp(cpt, "rec_mtime_on", l) == 0)) { - xorriso->relax_compliance|= isoburn_igopt_dir_rec_mtime; - } else if(l == 13 && strncmp(cpt, "rec_mtime_off", l) == 0) { - xorriso->relax_compliance&= ~isoburn_igopt_dir_rec_mtime; - - } else if((l == 6 && strncmp(cpt, "old_rr", l) == 0) || - (l == 9 && strncmp(cpt, "old_rr_on", l) == 0) || - (l == 10 && strncmp(cpt, "new_rr_off", l) == 0)) { - xorriso->relax_compliance|= - isoburn_igopt_rrip_version_1_10 | isoburn_igopt_aaip_susp_1_10; - } else if((l == 10 && strncmp(cpt, "old_rr_off", l) == 0) || - (l == 9 && strncmp(cpt, "new_rr_on", l) == 0) || - (l == 6 && strncmp(cpt, "new_rr", l) == 0)) { - xorriso->relax_compliance&= - ~(isoburn_igopt_rrip_version_1_10 | isoburn_igopt_aaip_susp_1_10); - - } else if((l == 14 && strncmp(cpt, "aaip_susp_1_10", l) == 0) || - (l == 17 && strncmp(cpt, "aaip_susp_1_10_on", l) == 0) || - (l == 18 && strncmp(cpt, "aaip_susp_1_12_off", l) == 0)) { - xorriso->relax_compliance|= isoburn_igopt_aaip_susp_1_10; - } else if((l == 18 && strncmp(cpt, "aaip_susp_1_10_off", l) == 0) || - (l == 17 && strncmp(cpt, "aaip_susp_1_12_on", l) == 0) || - (l == 14 && strncmp(cpt, "aaip_susp_1_12", l) == 0)) { - xorriso->relax_compliance&= ~isoburn_igopt_aaip_susp_1_10; - - } else if((l == 8 && strncmp(cpt, "iso_9660", l) == 0) || - (l == 11 && strncmp(cpt, "iso_9660_on", l) == 0)) { - /* may have a meaning in future */; - } else if(l == 12 && strncmp(cpt, "iso_9660_off", l) == 0) { - /* may have a meaning in future */; - Xorriso_msgs_submit(xorriso, 0, - "-compliance -iso_9660_off : Cannot do anything else but ISO 9660", - 0, "FAILURE", 0); - - } else { - if(linfo_text, "-compliance: unknown rule '%s'", - cpt); - else - sprintf(xorriso->info_text, - "-compliance: oversized rule parameter (%d)", l); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - xorriso->relax_compliance= was; - return(0); - } - } - return(1); -} - - -/* @return 1=ok 2=ok, is default setting */ -int Xorriso_get_relax_text(struct XorrisO *xorriso, char mode[1024], - int flag) -{ - int r; - - r= xorriso->relax_compliance; - if(r == 0) { - strcpy(mode, "strict"); - return(1); - } - strcpy(mode, "clear"); - if(r & isoburn_igopt_omit_version_numbers) - strcat(mode, ":omit_version"); - if(r & isoburn_igopt_only_iso_versions) - strcat(mode, ":only_iso_version"); - if(r & isoburn_igopt_allow_deep_paths) - strcat(mode, ":deep_paths"); - if(r & isoburn_igopt_allow_longer_paths) - strcat(mode, ":long_paths"); - if(r & isoburn_igopt_max_37_char_filenames) - strcat(mode, ":long_names"); - if(r & isoburn_igopt_no_force_dots) - strcat(mode, ":no_force_dots"); - if(r & isoburn_igopt_no_j_force_dots) - strcat(mode, ":no_j_force_dots"); - if(r & isoburn_igopt_allow_lowercase) - strcat(mode, ":lowercase"); - if(r & isoburn_igopt_allow_full_ascii) - strcat(mode, ":full_ascii"); - if(r & isoburn_igopt_joliet_longer_paths) - strcat(mode, ":joliet_long_paths"); - if(r & isoburn_igopt_always_gmt) - strcat(mode, ":always_gmt"); - if(r & isoburn_igopt_dir_rec_mtime) - strcat(mode, ":rec_mtime"); - if(r & isoburn_igopt_rrip_version_1_10) { - strcat(mode, ":old_rr"); - if(!(r & isoburn_igopt_aaip_susp_1_10)) - strcat(mode, ":aaip_susp_1_10_off"); - } else { - strcat(mode, ":new_rr"); - if(r & isoburn_igopt_aaip_susp_1_10) - strcat(mode, ":aaip_susp_1_10"); - } - - return(1 + (r == Xorriso_relax_compliance_defaulT)); -} - - -/** - @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); -} - - -int Xorriso_auto_driveadr(struct XorrisO *xorriso, char *adr, char *result, - int flag) -{ - int ret, is_known_mmc= 0; - char *path_pt, libburn_adr[BURN_DRIVE_ADR_LEN + SfileadrL]; - char *abs_pt, abs_adr[SfileadrL]; - - path_pt= adr; - if(strncmp(adr, "stdio:", 6) == 0) - path_pt= adr + 6; - else if(strncmp(adr, "mmc:", 4) == 0) - path_pt= adr + 4; - - - /* <<< replace by Xorriso_normalize_img_path() ? */; - - if(path_pt[0] != '/') { - abs_pt= getcwd(abs_adr, SfileadrL - 1); - if(abs_pt == NULL) { - Xorriso_msgs_submit(xorriso, 0, - "Relative drive path given. Cannot determine working directory.", - errno, "FAILURE", 0); - return(-1); - } - ret= Sfile_add_to_path(abs_adr, path_pt, 0); - if(ret <= 0) - return(-1); - } - - is_known_mmc= burn_drive_convert_fs_adr(path_pt, libburn_adr); - Xorriso_process_msg_queues(xorriso,0); - - ret= Xorriso_is_in_patternlist(xorriso, xorriso->drive_whitelist, path_pt, 0); - if(ret > 0) - goto ok; - ret= Xorriso_is_in_patternlist(xorriso, xorriso->drive_blacklist, path_pt, 0); - if(ret < 0) - return(ret); - if(ret) { - strcpy(xorriso->info_text, "Drive address "); - Text_shellsafe(adr, xorriso->info_text, 1); - strcat(xorriso->info_text, - " rejected because: -drive_class 'banned' "); - Text_shellsafe(Xorriso_get_pattern(xorriso, xorriso->drive_blacklist, - ret - 1, 0), - xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - /* if in greylist and not MMC and not stdio prefix: reject */ - if(is_known_mmc < 0) - return(ret); - if(adr == path_pt && !is_known_mmc) { /* no prefix, no MMC */ - ret= Xorriso_is_in_patternlist(xorriso, xorriso->drive_greylist, path_pt,0); - if(ret < 0) - return(ret); - if(ret) { - strcpy(xorriso->info_text, "Drive address "); - Text_shellsafe(adr, xorriso->info_text, 1); - strcat(xorriso->info_text, - " rejected because: not MMC and -drive_class 'risky' "); - Text_shellsafe(Xorriso_get_pattern(xorriso,xorriso->drive_greylist, - ret - 1, 0), - xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - Xorriso_msgs_submit(xorriso, 0, - "If the address is a legitimate target, prepend \"stdio:\"", - 0, "HINT", 0); - return(0); - } - } -ok:; - if(strncmp(adr, "mmc:", 4) == 0) { - if(Sfile_str(result, path_pt, 0) <= 0) - return(0); - } else if(adr == path_pt && is_known_mmc <= 0) { - Sfile_str(result, "stdio:", 0); - if(Sfile_str(result, adr, 1) <= 0) - return(0); - } else { - if(Sfile_str(result, adr, 0) <= 0) - return(0); - } - if(strncmp(result, "stdio:", 6)==0) { - if(xorriso->ban_stdio_write) { - strcpy(xorriso->info_text, "Drive address banned by -ban_stdio_write : "); - Text_shellsafe(result, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } - } - return(1); -} - - -/* - @param flag bit0= do not remove leading slash - bit1= append flatly to result_line and put out -*/ -int Xorriso_getfname(struct XorrisO *xorriso, char *path, int flag) -{ - int ret, path_offset= 0, bsl_mem; - char *bsl_path= NULL; - - if(path[0] == '/' && !(flag & 1)) - path_offset= 1; - - /* backslash escaped path rather than shellsafe path */ - ret= Sfile_bsl_encoder(&bsl_path, path + path_offset, - strlen(path + path_offset), 8); - if(ret <= 0) - return(-1); - if(flag & 2) { - sprintf(xorriso->result_line + strlen(xorriso->result_line), - "%s\n", bsl_path[0] ? bsl_path : "."); - } else { - sprintf(xorriso->result_line, "# file: %s\n", bsl_path[0] ? bsl_path : "."); - } - free(bsl_path); - bsl_path= NULL; - /* temporarily disable -backslash_codes with result output */ - bsl_mem= xorriso->bsl_interpretation; - xorriso->bsl_interpretation= 0; - Xorriso_result(xorriso, 0); - xorriso->bsl_interpretation= bsl_mem; - return(1); -} - - -/* @param node Opaque handle to IsoNode which is to be inquired instead of path if it is not NULL. - @param path is used as address if node is NULL. - @param acl_text if acl_text is not NULL, then *acl_text will be set to the - ACL text (without comments) of the file object. In this - case it finally has to be freed by the caller. - @param flag bit0= do not report to result but only retrieve ACL text - bit1= check for existence of true ACL (not fabricated), - do not allocate and set acl_text but return 1 or 2 - bit2-3: what ALC to retrieve: - 0= "access" and "default", mark "default:" - 1= "access" only - 2= "default" only, do not mark "default:" - bit4= get "access" ACL only if not trivial - @return 2 ok, no ACL available, eventual *acl_text will be NULL - 1 ok, ACL available, eventual *acl_text stems from malloc() - <=0 error -*/ -int Xorriso_getfacl(struct XorrisO *xorriso, void *in_node, char *path, - char **acl_text, int flag) -{ - int ret, d_ret, result_len= 0, pass, what; - IsoNode *node; - char *text= NULL, *d_text= NULL, *cpt, *npt; - uid_t uid; - gid_t gid; - struct passwd *pwd; - struct group *grp; - - what= (flag >> 2) & 3; - if(acl_text != NULL) - *acl_text= NULL; - - node= (IsoNode *) in_node; - if(node == NULL) { - ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); - if(ret<=0) - goto ex; - } - ret= iso_node_get_acl_text(node, &text, &d_text, flag & 16); - d_ret= (d_text != NULL); - if(ret < 0 || d_ret < 0) { - if(path != NULL && path[0] != 0) { - strcpy(xorriso->info_text, "Error with obtaining ACL of "); - Text_shellsafe(path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } - ret= 0; goto ex; - } - if(flag & 2) { - ret= 1 + (ret != 1 && d_ret == 0); - goto ex; - } - if((ret == 0 || ret == 2) && d_ret == 0) { - if(flag & 1) { - ret= 1 + (ret == 0); - goto ex; - } - strcpy(xorriso->info_text, "No ACL associated with "); - Text_shellsafe(path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); - if(ret == 0) - {ret= 2; goto ex;} - } - - if(!(flag & 1)) { - ret= Xorriso_getfname(xorriso, path, 0); - if(ret <= 0) - goto ex; - uid= iso_node_get_uid(node); - pwd= getpwuid(uid); - if(pwd == NULL) - sprintf(xorriso->result_line, "# owner: %.f\n", (double) uid); - else - sprintf(xorriso->result_line, "# owner: %s\n", pwd->pw_name); - Xorriso_result(xorriso, 0); - gid= iso_node_get_gid(node); - grp= getgrgid(gid); - if(grp == NULL) - sprintf(xorriso->result_line, "# group: %.f\n", (double) gid); - else - sprintf(xorriso->result_line, "# group: %s\n", grp->gr_name); - Xorriso_result(xorriso, 0); - } - - for(pass= 0; pass < 1 + (acl_text != NULL && !(flag & 2)); pass++) { - if(pass) { - *acl_text= calloc(result_len + 1, 1); - if(*acl_text == NULL) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - ret= -1; goto ex; - } - } - if(text != NULL && what <= 1) { - for(npt= cpt= text; npt != NULL; cpt= npt + 1) { - npt= strchr(cpt, '\n'); - if(npt != NULL) - *npt= 0; - if(*cpt == 0) { - if(d_text != NULL || pass) { - if(npt != NULL) - *npt= '\n'; - continue; - } - } else - result_len+= strlen(cpt) + 1; - if(pass) { - sprintf(*acl_text + strlen(*acl_text), "%s\n", cpt); - } else if(!(flag & 1)) { - Sfile_str(xorriso->result_line, cpt, 0); - strcat(xorriso->result_line, "\n"); - Xorriso_result(xorriso, 0); - } - if(npt != NULL) - *npt= '\n'; - } - } - if(d_text != NULL && (what == 0 || what == 2)) { - for(npt= cpt= d_text; npt != NULL; cpt= npt + 1) { - npt= strchr(cpt, '\n'); - if(npt != NULL) - *npt= 0; - if(*cpt != 0) { - if(pass) { - if(what == 0) - sprintf(*acl_text + strlen(*acl_text), "default:%s\n", cpt); - else - sprintf(*acl_text + strlen(*acl_text), "%s\n", cpt); - } else { - xorriso->result_line[0]= 0; - if(what == 0) - Sfile_str(xorriso->result_line, "default:", 0); - Sfile_str(xorriso->result_line, cpt, 1); - result_len+= strlen(cpt) + 9; - } - } else - xorriso->result_line[0]= 0; - if(pass== 0 && !(flag & 1)) { - strcat(xorriso->result_line, "\n"); - Xorriso_result(xorriso, 0); - } - if(npt != NULL) - *npt= '\n'; - } - } - } - ret= 1; -ex:; - iso_node_get_acl_text(node, &text, &d_text, 1 << 15); - return(ret); -} - - -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); -} - - -/* @param node Opaque handle to IsoNode which is to be manipulated - instead of path if it is not NULL. - @param path is used as address if node is NULL. - @param access_text "access" ACL in long text form - @param default_text "default" ACL in long text form - @param flag bit0= do not warn of root directory if not capable of AAIP - @return >0 success , <=0 failure -*/ -int Xorriso_setfacl(struct XorrisO *xorriso, void *in_node, char *path, - char *access_text, char *default_text, int flag) -{ - int ret; - IsoNode *node; - - node= (IsoNode *) in_node; - if(node == NULL) { - ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); - if(ret<=0) - goto ex; - } - ret= iso_node_set_acl_text(node, access_text, default_text, 0); - if(ret <= 0) { - if(path != NULL && path[0] != 0) { - strcpy(xorriso->info_text, "Error with setting ACL of "); - Text_shellsafe(path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } - ret= 0; goto ex; - } - Xorriso_set_change_pending(xorriso, 0); - ret= 1; -ex:; - Xorriso_process_msg_queues(xorriso,0); - return(ret); -} - - -/* - @param flag bit0= do not report to result but only retrieve attr text - bit1= path is disk_path - bit3= do not ignore eventual non-user attributes. - bit5= in case of symbolic link on disk: inquire link target - bit6= check for existence of xattr, return 0 or 1 - (depends also on bit3) -*/ -int Xorriso_getfattr(struct XorrisO *xorriso, void *in_node, char *path, - char **attr_text, int flag) -{ - int ret= 1, i, bsl_mem, result_len= 0, pass; - size_t num_attrs= 0, *value_lengths= NULL; - char **names= NULL, **values= NULL, *bsl; - - if(attr_text != NULL) - *attr_text= NULL; - ret= Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names, - &value_lengths, &values, flag & (2 | 8 | 32)); - if(ret <= 0) - goto ex; - if(flag & 64) { - ret= (num_attrs > 0); - goto ex; - } - if(num_attrs == 0) - {ret= 2; goto ex;} - - if(!(flag & 1)) { - ret= Xorriso_getfname(xorriso, path, 0); - if(ret <= 0) - goto ex; - } - for(pass= 0; pass < 1 + (attr_text != NULL); pass++) { - if(pass) { - *attr_text= calloc(result_len + 1, 1); - if(*attr_text == NULL) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - ret= -1; goto ex; - } - } - for(i= 0; i < num_attrs; i++) { - if(strlen(names[i]) + value_lengths[i] >= SfileadrL) { - sprintf(xorriso->result_line, "# oversized: name %d , value %d bytes\n", - (int) strlen(names[i]), (int) value_lengths[i]); - } else { - ret= Sfile_bsl_encoder(&bsl, names[i], strlen(names[i]), 8); - if(ret <= 0) - {ret= -1; goto ex;} - strcpy(xorriso->result_line, bsl); - free(bsl); - ret= Sfile_bsl_encoder(&bsl, values[i], value_lengths[i], 8); - if(ret <= 0) - {ret= -1; goto ex;} - sprintf(xorriso->result_line + strlen(xorriso->result_line), - "=\"%s\"\n", bsl); - free(bsl); - } - /* temporarily disable -backslash_codes with result output */ - result_len+= strlen(xorriso->result_line); - if(pass) { - strcat(*attr_text, xorriso->result_line); - } else if(!(flag & 1)) { - bsl_mem= xorriso->bsl_interpretation; - xorriso->bsl_interpretation= 0; - Xorriso_result(xorriso, 0); - xorriso->bsl_interpretation= bsl_mem; - } - } - } - if(!(flag & 1)) { - strcpy(xorriso->result_line, "\n"); - Xorriso_result(xorriso, 0); - } - ret= 1; -ex:; - Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names, - &value_lengths, &values, 1 << 15); - return(ret); -} - - -/* @param in_node Opaque handle to IsoNode which is to be manipulated - instead of path if it is not NULL. - @param path is used as address if node is NULL. - @param num_attrs Number of attributes - @param names Array of pointers to 0 terminated name strings - @param value_lengths Array of byte lengths for each attribute payload - @param values Array of pointers to the attribute payload bytes - @param flag bit0= Do not maintain eventual existing ACL of the node - bit1= Do not clear the existing attribute list - bit2= Delete the attributes with the given names - bit3= Allow non-user attributes. - bit4= do not warn of root if incapable of AAIP - @return >0 success , <=0 failure -*/ -int Xorriso_setfattr(struct XorrisO *xorriso, void *in_node, char *path, - size_t num_attrs, char **names, - size_t *value_lengths, char **values, int flag) -{ - int ret; - IsoNode *node; - - node= (IsoNode *) in_node; - if(node == NULL) { - ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); - if(ret<=0) - goto ex; - } - ret= iso_node_set_attrs(node, num_attrs, names, value_lengths, values, - flag & (1 | 2 | 4 | 8)); - Xorriso_process_msg_queues(xorriso,0); - if(ret <= 0) { - Xorriso_report_iso_error(xorriso, "", ret, - "Error when setting ACL and xattr to image node", - 0, "FAILURE", 1); - if(path != NULL && path[0] != 0) { - strcpy(xorriso->info_text, "Error with setting xattr of "); - Text_shellsafe(path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - } - ret= 0; goto ex; - } - Xorriso_set_change_pending(xorriso, 0); - ret= 1; -ex:; - Xorriso_process_msg_queues(xorriso,0); - return(ret); -} - - -/* - @param flag - Bitfield for control purposes - bit0= get default ACL rather than access ACL - bit4= set *text = NULL and return 2 - if the ACL matches st_mode permissions. - bit5= in case of symbolic link: inquire link target - bit15= free text and return 1 - @return - 1 ok - 2 ok, trivial ACL found while bit4 is set, *text is NULL - 0 no ACL manipulation adapter available / ACL not supported by fs - -1 failure of system ACL service (see errno) - -2 attempt to inquire ACL of a symbolic link without bit4 or bit5 - resp. with no suitable link target -*/ -int Xorriso_local_getfacl(struct XorrisO *xorriso, char *disk_path, - char **text, int flag) -{ - int ret, skip= 0, colons= 0, countdown= 0; - char *acl= NULL, *cpt, *wpt; - - if(flag & (1 << 15)) { - if(*text != NULL) - free(*text); - *text= NULL; - return(1); - } - *text= NULL; - ret= iso_local_get_acl_text(disk_path, &acl, flag & (1 | 16 | 32)); - Xorriso_process_msg_queues(xorriso,0); - if(ret < 0 || ret == 2) - return(ret); - if(acl == NULL) - return(0); - *text= strdup(acl); - iso_local_get_acl_text(disk_path, &acl, 1 << 15); - if(*text == NULL) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - return(-1); - } - - /* Garbage collection about trailing remarks after 3 permission chars */ - wpt= *text; - for(cpt= *text; *cpt; cpt++) { - if(skip) { - if(*cpt == '\n') - skip= 0; - else - continue; - } - if(*cpt == ':' && !countdown) { - colons++; - if(colons == 2) { - countdown= 4; - colons= 0; - } - } - if(countdown > 0) { - countdown--; - if(countdown == 0) - skip= 1; - } - *wpt= *cpt; - wpt++; - } - *wpt= 0; - - return(1); -} - - -/* - @param flag - bit1= path is disk_path - bit3= do not ignore eventual non-user attributes. - bit5= in case of symbolic link on disk: inquire link target - bit15= free memory -*/ -int Xorriso_get_attrs(struct XorrisO *xorriso, void *in_node, char *path, - size_t *num_attrs, char ***names, - size_t **value_lengths, char ***values, int flag) -{ - int ret, i, widx; - IsoNode *node; - - if(flag & (1 << 15)) { - if(flag & 2) { - iso_local_get_attrs(NULL, num_attrs, names, value_lengths, values, - 1 << 15); - } else { - iso_node_get_attrs(NULL, num_attrs, names, value_lengths, values, - 1 << 15); - } - return(1); - } - - *num_attrs= 0; - if(flag & 2) { - ret= iso_local_get_attrs(path, num_attrs, names, value_lengths, values, - flag & (8 | 32)); - if(ret < 0) { - strcpy(xorriso->info_text, "Error with reading xattr of disk file "); - Text_shellsafe(path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); - } - } else { - node= (IsoNode *) in_node; - if(node == NULL) { - ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); - if(ret<=0) - goto ex; - } - ret= iso_node_get_attrs(node, num_attrs, names, value_lengths, values, - 0); - if(ret < 0) { - Xorriso_report_iso_error(xorriso, "", ret, - "Error when obtaining xattr of ISO node", 0, "FAILURE", 1); - goto ex; - } - - if(!(flag & 8)) { - /* Filter away any non-userspace xattr */; - widx= 0; - for(i= 0; i < *num_attrs; i++) { - if(strncmp((*names)[i], "user.", 5) != 0) { - free((*names)[i]); - (*names)[i]= NULL; - if((*values)[i] != NULL) { - free((*values)[i]); - (*values)[i]= NULL; - } - } else { - if(widx != i) { - (*names)[widx]= (*names)[i]; - (*value_lengths)[widx]= (*value_lengths)[i]; - (*values)[widx]= (*values)[i]; - (*names)[i]= NULL; - (*value_lengths)[i]= 0; - (*values)[i]= NULL; - } - widx++; - } - } - *num_attrs= widx; - } - } - ret= 1; -ex:; - Xorriso_process_msg_queues(xorriso,0); - return(ret); -} - - -int Xorriso_get_attr_value(struct XorrisO *xorriso, void *in_node, char *path, - char *name, size_t *value_length, char **value, int flag) -{ - int ret; - size_t num_attrs= 0, *value_lengths= NULL, i; - char **names = NULL, **values= NULL; - - *value= NULL; - *value_length= 0; - ret= Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names, - &value_lengths, &values, 8); - if(ret <= 0) - goto ex; - - for(i= 0; i < num_attrs; i++) { - if(strcmp(name, names[i]) != 0) - continue; - *value= calloc(value_lengths[i] + 1, 1); - if(*value == NULL) - {ret= -1; goto ex;} - memcpy(*value, values[i], value_lengths[i]); - (*value)[value_lengths[i]]= 0; - *value_length= value_lengths[i]; - ret= 1; goto ex; - } - ret= 0; -ex: - Xorriso_get_attrs(xorriso, in_node, path, &num_attrs, &names, - &value_lengths, &values, 1 << 15); - return(ret); -} - - -/* - @param flag bit0= use parameters dev,ino rather than disk_path - bit1= compare attribute rather than setting it - return: 0=dev,ino match, 1=mismatch, 2=no node attribute - -1=error - bit5= if not bit0: - transfer dev,inode from eventual link target - bit7= omit dev check mit bit1 -*/ -int Xorriso_record_dev_inode(struct XorrisO *xorriso, char *disk_path, - dev_t dev, ino_t ino, - void *in_node, char *iso_path, int flag) -{ - size_t l, di_l= 0; - int i, ret; - dev_t hdev; - ino_t hino; - char buf[66], *bufpt, *wpt, *di= NULL; - static char *name= "isofs.di"; - struct stat stbuf; - - if(!(flag & 1)) { - if(flag & 32) { - if(stat(disk_path, &stbuf) == -1) - return(-1); - } else { - if(lstat(disk_path, &stbuf) == -1) - return(-1); - } - dev= stbuf.st_dev; - ino= stbuf.st_ino; - } - - wpt= buf; - hdev= dev; - for(i= 0; hdev != 0; i++) - hdev= hdev >> 8; - l= i; - *(wpt++)= l; - for(i= 0; i < l; i++) - *(wpt++)= dev >> (8 * (l - i - 1)); - hino= ino; - for(i= 0; hino != 0; i++) - hino= hino >> 8; - l= i; - *(wpt++)= l; - for(i= 0; i < l; i++) - *(wpt++)= ino >> (8 * (l - i - 1)); - l= wpt - buf; - bufpt= buf; - - if(flag & 2) { - /* Compare node attribute with bufpt,l */ - ret= Xorriso_get_attr_value(xorriso, in_node, iso_path, - "isofs.di", &di_l, &di, 0); - if(ret < 0) - goto ex; - if(ret == 0) - {ret= 2; goto ex;} - if(flag & 128) { - if(di_l <= 0) - {ret= 1; goto ex;} - hino= 0; - for(i= di[0] + 2; i < di_l && i - di[0] - 2 < di[(int) di[0] + 1]; i++) - hino= (hino << 8) | ((unsigned char *) di)[i]; - if(hino != ino) - {ret= 1; goto ex;} - } else { - if(l != di_l) - {ret= 1; goto ex;} - for(i= 0; i < l; i++) - if(di[i] != buf[i]) - {ret= 1; goto ex;} - } - ret= 0; - } else { - ret= Xorriso_setfattr(xorriso, in_node, iso_path, - (size_t) 1, &name, &l, &bufpt, 2 | 8); - } -ex:; - if(di != NULL) - free(di); - return(ret); -} - - -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_stream_type(struct XorrisO *xorriso, IsoNode *node, - IsoStream *stream, char type_text[], int flag) -{ - int ret, lba; - char text[5]; - - strncpy(text, stream->class->type, 4); - text[4]= 0; - if(strcmp(text, "fsrc") == 0) { - ret= Xorriso__file_start_lba(node, &lba, 0); - if(ret > 0 && lba > 0) - strcpy(type_text, "image"); - else - strcpy(type_text, "disk"); - } else if(strcmp(text, "ziso") == 0) { - strcpy(type_text, "--zisofs"); - } else if(strcmp(text, "osiz") == 0) { - strcpy(type_text, "--zisofs-decode"); - } else if(strcmp(text, "gzip") == 0) { - strcpy(type_text, "--gzip"); - } else if(strcmp(text, "pizg") == 0) { - strcpy(type_text, "--gunzip"); - } else if(strcmp(text, "cout") == 0 || strcmp(text, "boot") == 0 || - strcmp(text, "user") == 0 || strcmp(text, "extf") == 0) { - strcpy(type_text, text); - } else { - Text_shellsafe(text, type_text, 0); - } - return(1); -} - -int Xorriso_show_stream(struct XorrisO *xorriso, void *in_node, - char *path, int flag) -{ - int ret; - IsoNode *node; - IsoFile *file; - IsoStream *stream= NULL, *input_stream; - IsoExternalFilterCommand *cmd; - char type_text[16], *source_path= NULL; - - 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)) - {ret= 2; goto ex;} - file= (IsoFile *) node; - input_stream= iso_file_get_stream(file); - Text_shellsafe(path, xorriso->result_line, 0); - while(1) { - stream= input_stream; - input_stream= iso_stream_get_input_stream(stream, 0); - if(input_stream == NULL) - break; - strcat(xorriso->result_line, " < "); - Xorriso_stream_type(xorriso, node, stream, type_text, 0); - strcat(xorriso->result_line, type_text); - ret= iso_stream_get_external_filter(stream, &cmd, 0); - if(ret < 0) { - Xorriso_process_msg_queues(xorriso,0); - Xorriso_report_iso_error(xorriso, "", ret, - "Error when inquiring filter command of node", 0, "FAILURE", 1); - ret= 0; goto ex; - } - if(ret > 0) { - strcat(xorriso->result_line, ":"); - Text_shellsafe(cmd->name, xorriso->result_line, 1); - } - if(strlen(xorriso->result_line) > SfileadrL) { - Xorriso_result(xorriso, 0); - xorriso->result_line[0]= 0; - } - } - strcat(xorriso->result_line, " < "); - Xorriso_stream_type(xorriso, node, stream, type_text, 0); - strcat(xorriso->result_line, type_text); - - source_path= iso_stream_get_source_path(stream, 0); - if(source_path != NULL) { - strcat(xorriso->result_line, ":"); - Text_shellsafe(source_path, xorriso->result_line, 1); - } - - strcat(xorriso->result_line, "\n"); - Xorriso_result(xorriso, 0); - ret= 1; -ex:; - if(source_path != NULL) - free(source_path); - return(ret); -} - - -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); -} - - -int Xorriso_all_node_array(struct XorrisO *xorriso, int addon_nodes, int flag) -{ - int ret; - struct FindjoB *job= NULL; - struct stat dir_stbuf; - - ret= Findjob_new(&job, "/", 0); - if(ret<=0) { - Xorriso_no_findjob(xorriso, "xorriso", 0); - {ret= -1; goto ex;} - } - Findjob_set_action_target(job, 30, NULL, 0); - Xorriso_destroy_node_array(xorriso, 0); - ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, NULL, "/", - &dir_stbuf, 0, 0); - if(ret <= 0) - goto ex; - ret= Xorriso_new_node_array(xorriso, xorriso->temp_mem_limit, addon_nodes, 0); - if(ret <= 0) - goto ex; - Findjob_set_action_target(job, 31, NULL, 0); - ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, NULL, "/", - &dir_stbuf, 0, 0); - if(ret <= 0) - goto ex; - ret= 1; -ex:; - Findjob_destroy(&job, 0); - return(ret); -} - - -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); -} - - -/* - @param flag bit0= do not report to result but only retrieve md5 text - @return 1= ok, 0= no md5 available, <0= other error -*/ -int Xorriso_get_md5(struct XorrisO *xorriso, void *in_node, char *path, - char md5[16], int flag) -{ - int ret= 1, i; - char *wpt; - IsoImage *image; - IsoNode *node; - - ret= Xorriso_get_volume(xorriso, &image, 0); - if(ret <= 0) - goto ex; - 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)) - return(0); - ret= iso_file_get_md5(image, (IsoFile *) node, md5, 0); - Xorriso_process_msg_queues(xorriso,0); - if(ret <= 0) - goto ex; - if(flag & 1) - {ret= 1; goto ex;} - - wpt= xorriso->result_line; - for(i= 0; i < 16; i++) { - sprintf(wpt, "%2.2x", ((unsigned char *) md5)[i]); - wpt+= 2; - } - strcpy(wpt, " "); - wpt+= 2; - Xorriso_getfname(xorriso, path, 1 | 2); - ret= 1; -ex:; - return(ret); -} - - -int Xorriso_make_md5(struct XorrisO *xorriso, void *in_node, char *path, - int flag) -{ - int ret; - off_t size; - IsoNode *node; - - node= (IsoNode *) in_node; - if(node == NULL) { - ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); - if(ret <= 0) - return(ret); - } - if(!LIBISO_ISREG(node)) - return(0); - ret= iso_file_make_md5((IsoFile *) node, 0); - size= iso_file_get_size((IsoFile *) node); - xorriso->pacifier_count+= size; - xorriso->pacifier_byte_count+= size; - Xorriso_pacifier_callback(xorriso, "content bytes read", - xorriso->pacifier_count, 0, "", 0); - Xorriso_process_msg_queues(xorriso, 0); - if(ret < 0) { - Xorriso_report_iso_error(xorriso, "", ret, - "Error when computing MD5", 0, "FAILURE", 1); - return(0); - } - Xorriso_set_change_pending(xorriso, 1); - return(1); -} - - -/* @param node Opaque handle to IsoNode which is to be inquired instead of path if it is not NULL. - @param path is used as address if node is NULL. - @param flag bit0= do not report to result but only indicate outcome - by return value - bit1= silently ignore nodes without MD5 - bit2= do not only report mismatches but also matches - @return 3= not a data file - 2= no MD5 attached to node - 1= ok, MD5 compared and matching - 0= not ok, MD5 mismatch - <0= other error -*/ -int Xorriso_check_md5(struct XorrisO *xorriso, void *in_node, char *path, - int flag) -{ - int ret, wanted, rret; - IsoImage *image; - IsoNode *node; - IsoFile *file; - char node_md5[16], data_md5[16], buffer[64 * 1024]; - void *stream= NULL, *ctx= NULL; - off_t todo; - - node= (IsoNode *) in_node; - if(node == NULL) { - ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); - if(ret<=0) - {ret= -1; goto ex;} - } - if(!LIBISO_ISREG(node)) { - strcpy(xorriso->info_text, "-check_md5: Not a data file: "); - Text_shellsafe(path, xorriso->info_text, 1); - if(!(flag & 2)) - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - ret= 3; goto ex; - } - file= (IsoFile *) node; - - /* obtain MD5 */ - ret= Xorriso_get_volume(xorriso, &image, 0); - if(ret <= 0) - {ret= -1; goto ex;} - ret= iso_file_get_md5(image, file, node_md5, 0); - Xorriso_process_msg_queues(xorriso,0); - if(ret < 0) - {ret= -1; goto ex;} - if(ret == 0) { - strcpy(xorriso->info_text, "-check_md5: No MD5 recorded with file: "); - Text_shellsafe(path, xorriso->info_text, 1); - if(!(flag & 2)) - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); - ret= 2; goto ex; - } - - /* Read file and compute MD5 */; - ret= Xorriso_iso_file_open(xorriso, path, (void *) node, &stream, 1 | 2); - if(ret <= 0) - {ret= -1; goto ex;} - ret= iso_md5_start(&ctx); - if(ret < 0) - goto ex; - todo= iso_stream_get_size(stream); - while(todo > 0) { - if(todo < sizeof(buffer)) - wanted= todo; - else - wanted= sizeof(buffer); - rret = Xorriso_iso_file_read(xorriso, stream, buffer, wanted, 0); - if(rret <= 0) - {ret= -1; goto ex;} - todo-= rret; - ret = iso_md5_compute(ctx, buffer, rret); - if(ret < 0) - goto ex; - xorriso->pacifier_count+= rret; - xorriso->pacifier_byte_count+= rret; - Xorriso_pacifier_callback(xorriso, "content bytes read", - xorriso->pacifier_count, 0, "", 0); - } - ret= iso_md5_end(&ctx, data_md5); - if(ret < 0) - goto ex; - - /* Report outcome */ - Xorriso_process_msg_queues(xorriso,0); - if(! iso_md5_match(node_md5, data_md5)) { - sprintf(xorriso->result_line, "MD5 MISMATCH: "); - Text_shellsafe(path, xorriso->result_line, 1); - strcat(xorriso->result_line, "\n"); - if(!(flag & 1)) - Xorriso_result(xorriso,0); - ret= 0; - } else { - sprintf(xorriso->result_line, "md5 match : "); - Text_shellsafe(path, xorriso->result_line, 1); - strcat(xorriso->result_line, "\n"); - if(flag & 4) - Xorriso_result(xorriso,0); - ret= 1; - } - -ex:; - Xorriso_process_msg_queues(xorriso,0); - Xorriso_iso_file_close(xorriso, &stream, 0); - if(ctx != NULL) - iso_md5_end(&ctx, data_md5); - if(ret < 0) { - sprintf(xorriso->result_line, "NOT READABLE: "); - Text_shellsafe(path, xorriso->result_line, 1); - strcat(xorriso->result_line, "\n"); - if(!(flag & 1)) - Xorriso_result(xorriso,0); - } - return(ret); -} - - -int Xorriso_check_md5_range(struct XorrisO *xorriso, off_t start_lba, - off_t end_lba, char md5[16], int flag) -{ - int ret; - struct burn_drive_info *dinfo= NULL; - struct burn_drive *drive= NULL; - off_t pos, data_count, to_read; - char data[64 * 1024], data_md5[16]; - void *ctx = NULL; - - ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to check session MD5 checksum", 0); - if(ret <= 0) - goto ex; - ret= iso_md5_start(&ctx); - if(ret <= 0) { - Xorriso_no_malloc_memory(xorriso, NULL, 0); - goto ex; - } - for(pos= start_lba; pos < end_lba; pos+= 32) { - to_read= 32; - if(pos + to_read > end_lba) - to_read= end_lba - pos; - ret= burn_read_data(drive, pos * (off_t) 2048, data, - to_read * (off_t) 2048, &data_count, 0); - if(ret <= 0) - goto ex; - iso_md5_compute(ctx, data, (int) data_count); - xorriso->pacifier_count+= data_count; - xorriso->pacifier_byte_count+= data_count; - Xorriso_pacifier_callback(xorriso, "content bytes read", - xorriso->pacifier_count, 0, "", 0); - } - iso_md5_end(&ctx, data_md5); - ret= 1; - if(! iso_md5_match(md5, data_md5)) - ret= 0; -ex:; - Xorriso_process_msg_queues(xorriso,0); - if(ctx != NULL) - iso_md5_end(&ctx, data_md5); - return(ret); -} - - -int Xorriso_check_session_md5(struct XorrisO *xorriso, char *severity, - int flag) -{ - int ret, i; - IsoImage *image; - uint32_t start_lba, end_lba; - char md5[16], md5_text[33]; - - 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(ret); - if(ret == 0) { - sprintf(xorriso->info_text, - "No session MD5 is recorded with the loaded session"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); - return(0); - } - - sprintf(xorriso->info_text, "Checking loaded session by its recorded MD5.\n"); - Xorriso_info(xorriso, 0); - for(i= 0; i < 16; i++) - sprintf(md5_text + 2 * i, "%2.2x", ((unsigned char *) md5)[i]); - sprintf(xorriso->result_line, - "Session MD5 %s , LBA %.f , %.f blocks\n", - md5_text, (double) start_lba, (double) end_lba - start_lba); - Xorriso_result(xorriso,0); - ret= Xorriso_check_md5_range(xorriso, (off_t) start_lba, (off_t) end_lba, - md5, 0); - return(ret); -} - - -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); -} - - -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); -} - - -/* @param flag bit0=input drive - bit1=output drive - bit2= wake up rather than calm down -*/ -int Xorriso_drive_snooze(struct XorrisO *xorriso, int flag) -{ - int in_is_out_too, ret; - struct burn_drive_info *dinfo; - struct burn_drive *drive; - - in_is_out_too= (xorriso->in_drive_handle == xorriso->out_drive_handle); - if((flag & 1) && xorriso->in_drive_handle != NULL) { - Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to calm drive", 0); - burn_drive_snooze(drive, !!(flag & 4)); - if(in_is_out_too) - {ret= 1; goto ex;} - } - if((flag&2) && xorriso->out_drive_handle!=NULL) { - Xorriso_get_drive_handles(xorriso, &dinfo, &drive, - "on attempt to calm drive", 2); - burn_drive_snooze(drive, !!(flag & 4)); - } - ret= 1; -ex:; - Xorriso_process_msg_queues(xorriso,0); - return(ret); -} - - -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 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= enable SCSI command logging to stderr */ -int Xorriso_scsi_log(struct XorrisO *xorriso, int flag) -{ - if(flag == 0) - burn_set_scsi_logging(0); - else - burn_set_scsi_logging(2|4); - return(1); -} diff --git a/xorriso/xorrisoburn.h b/xorriso/xorrisoburn.h index 6834176a..db1d83d5 100644 --- a/xorriso/xorrisoburn.h +++ b/xorriso/xorrisoburn.h @@ -412,6 +412,15 @@ int Xorriso_setfattr(struct XorrisO *xorriso, void *in_node, char *path, size_t num_attrs, char **names, 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, dev_t dev, ino_t ino, 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 +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 */