Implemented option -follow

This commit is contained in:
Thomas Schmitt 2007-12-15 18:31:39 +00:00
parent 1ae0ee9b08
commit 20313a4654
6 changed files with 696 additions and 154 deletions

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps .\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1) .\" other parameters are allowed: see man(7), man(1)
.TH XORRISO 1 "December 7, 2007" .TH XORRISO 1 "December 15, 2007"
.\" Please adjust this date whenever revising the manpage. .\" Please adjust this date whenever revising the manpage.
.\" .\"
.\" Some roff macros, for reference: .\" Some roff macros, for reference:
@ -71,7 +71,7 @@ Rock Ridge, POSIX, X/Open
.br .br
Command processing Command processing
.br .br
Result pager Dialog, Readline, Result pager
.sp 1 .sp 1
Maybe you first want to have a look at section EXAMPLES near the end of Maybe you first want to have a look at section EXAMPLES near the end of
this text before reading the next few hundred lines of background information. this text before reading the next few hundred lines of background information.
@ -105,7 +105,7 @@ together form a single filesystem image.
Adding a session to an existing ISO image is in this text referred as Adding a session to an existing ISO image is in this text referred as
\fBgrowing\fR. \fBgrowing\fR.
.br .br
The multi-session model of the MMC standard does not apply to all all media The multi-session model of the MMC standard does not apply to all media
types. But program growisofs by Andy Polyakov showed how to extend this types. But program growisofs by Andy Polyakov showed how to extend this
functionality to overwriteable media or disk files which carry valid ISO 9660 functionality to overwriteable media or disk files which carry valid ISO 9660
filesystems. This expansion method is referred as as emulated growing. filesystems. This expansion method is referred as as emulated growing.
@ -220,8 +220,8 @@ filesystem objects as source and/or target media.
.B Libburn drives: .B Libburn drives:
.br .br
Input drive, i.e. source of an existing or empty ISO image, can be any random Input drive, i.e. source of an existing or empty ISO image, can be any random
access readable libburn drive: optical media with readable data or blank, access readable libburn drive: optical media with readable data,
regular files, block devices. blank optical media, regular files, block devices.
.br .br
Rock Ridge info must be present in existing ISO images and it will be generated Rock Ridge info must be present in existing ISO images and it will be generated
by the program unconditionally. by the program unconditionally.
@ -255,6 +255,7 @@ If path leads to a regular file or to a block device then the emulated drive
is random access readable and can be used for the method of growing if it is random access readable and can be used for the method of growing if it
already contains a valid ISO 9660 image. Any other file type is not readable already contains a valid ISO 9660 image. Any other file type is not readable
via "stdio:" and can only be used as target for the method of modifying. via "stdio:" and can only be used as target for the method of modifying.
Non existing paths in existing directories are handled as empty regular files.
.PP .PP
Be aware that especially the superuser can write into any accessible file or Be aware that especially the superuser can write into any accessible file or
device by using its path with the "stdio:" prefix. Addresses without prefix device by using its path with the "stdio:" prefix. Addresses without prefix
@ -317,7 +318,23 @@ The program ends either by command -end, or by the end of program arguments
if not dialog was enabled up to that moment, or by a problem if not dialog was enabled up to that moment, or by a problem
event which triggers the threshold of command -abort_on. event which triggers the threshold of command -abort_on.
.SS .SS
.B Result pager: .B Dialog, Readline, Result pager:
.br
Dialog mode prompts for an input line, parses it into words, and performs
them as commands with their parameters. It provides assisting services
to make dialog more comfortable.
.PP
Readline is an enhancement for the input line. You may know it already from
the bash shell.
.br
It allows to move the cursor over the text in the line by help of the
leftward and the rightward arrow key.
Text may be inserted at the cursor position. The delete key removes the
character under the cursor. Upward and Downward arrow keys navigate through
the history of previous input lines.
.br
See man readline for more info about libreadline.
.PP
Option -page activates a builtin result text pager which may be convenient in Option -page activates a builtin result text pager which may be convenient in
dialog. After an action has put out the given number of terminal lines, dialog. After an action has put out the given number of terminal lines,
the pager prompts the user for a line of input. the pager prompts the user for a line of input.
@ -351,7 +368,7 @@ from file addresses.
.B Aquiring source and target drive: .B Aquiring source and target drive:
.TP .TP
\fB\-dev\fR address \fB\-dev\fR address
Set input and output drive to the same address and load eventual ISO image. Set input and output drive to the same address and load an eventual ISO image.
If there is no ISO image then create a blank one. If there is no ISO image then create a blank one.
Set the image expansion method to growing. Set the image expansion method to growing.
.br .br
@ -470,9 +487,9 @@ If -pathspecs is set to "off" then eventual -disk_pattern expansion applies.
The resulting words are used as both, iso_rr_path and disk path. Eventually The resulting words are used as both, iso_rr_path and disk path. Eventually
-cdx gets prepended. -cdx gets prepended.
.TP .TP
\fB\-path-list\fR disk_path \fB\-path_list\fR disk_path
Like -add but read the pathspecs from file disk_path. Like -add but read the parameter words from file disk_path.
One pathspec per line. One pathspec resp. disk_path pattern per line.
.TP .TP
> \fB\-cp_r\fR disk_path [***] iso_rr_path > \fB\-cp_r\fR disk_path [***] iso_rr_path
Insert the given files or directory trees from filesystem Insert the given files or directory trees from filesystem
@ -576,7 +593,7 @@ Discard the manipulated ISO image and reload it from -indev.
.TP .TP
\fB\-commit\fR \fB\-commit\fR
Perform the write operation. Afterwards eventually make the Perform the write operation. Afterwards eventually make the
-outdev the new -indev and load the image from there. -outdev the new -dev and load the image from there.
Switch from eventual modifiying mode to growing mode. Switch from eventual modifiying mode to growing mode.
(A subsequent -outdev will activate modification mode.) (A subsequent -outdev will activate modification mode.)
-commit is performed automatically at end of program if there -commit is performed automatically at end of program if there
@ -587,8 +604,8 @@ To suppress a final write, execute -rollback -end.
.br .br
Writing can last quite a while. It is not unnormal with several Writing can last quite a while. It is not unnormal with several
types of media if there is no progress visible for the first types of media that there is no progress visible for the first
few minutes and if the drive gnaws on the media for a few few minutes or that the drive gnaws on the media for a few
minutes after all data have been transmitted. minutes after all data have been transmitted.
xorriso and the drives are in a client-server relationship. xorriso and the drives are in a client-server relationship.
The drives have much freedom about what to do with the media. The drives have much freedom about what to do with the media.
@ -629,7 +646,7 @@ SORRY event occured.
\fB\-format\fR mode \fB\-format\fR mode
Convert unformatted DVD-RW into overwriteable ones, Convert unformatted DVD-RW into overwriteable ones,
"de-ice" DVD+RW. "de-ice" DVD+RW.
As mode submit the word "full" for now. For now, mode should be the word "full".
.br .br
This action has no effect on media if -dummy is activated. This action has no effect on media if -dummy is activated.
.br .br
@ -638,6 +655,9 @@ to the media's health. DVD+RW get formatted as far as needed
during writing, but an entirely formatted media might be better during writing, but an entirely formatted media might be better
readable in some DVD players. readable in some DVD players.
.br .br
On the other hand unreliable DVD+RW can sometimes be repaired by
re-formatting.
.br
The progress reports issued by some drives while formatting are The progress reports issued by some drives while formatting are
quite unrealistic. Do not conclude success or failure from the quite unrealistic. Do not conclude success or failure from the
@ -646,13 +666,45 @@ SORRY event occured.
.TP .TP
.B Settings for data insertion: .B Settings for data insertion:
.TP .TP
> \fB\-follow\fR "on"|"off" \fB\-follow\fR occasion[:occasion[...]]
Enable or disable resolution of symbolic links under disk_paths. Enable or disable resolution of symbolic links and mount points under
If disabled by "off" then symbolic links are added as link objects with disk_paths. This applies to actions -add, -du*x, -ls*x and to -disk_pattern
unchanged target address. If enabled by "on", then the link target gets added. expansion.
.br
There are two kinds of follow decisison to be made:
.br
"link" is the hop from a symbolic link to its target file object.
If enabled then symbolic links are handled as their target file objects,
else symbolic links are handled as themselves.
.br
"mount" is the hop from one filesystem to another subordinate filesystem.
If enabled then mount point directories are handled as any other directory,
else mount points are handled as empty directories if they are encountered in
directory tree traversals.
.br
Less general then above occasions:
.br
"pattern" is mount and link hopping, but only during -disk_pattern expansion.
.br
"param" is link hopping for parameter words (after eventual pattern expansion).
If enabled then -ls*x will show the link targets rather than the links
themselves. -du*x and -add will process the link targets but not follow links
in an eventual directory tree below the targets (unless "link" is enabled).
.br
Occasions can be combined in a colon separated list. All occasions
mentioned in the list will then lead to a positive follow decision.
.br
"off" prevents any positive follow decision. Use it if no other occasion
applies.
.br
Shortcuts:
.br
"default" is equivalent to "pattern:mount".
.br
"on" always decides positive. Equivalent to "link:mount".
.TP .TP
\fB\-pathspecs\fR "on"|"off" \fB\-pathspecs\fR "on"|"off"
Control parameter interpretation with xorriso action -add. Control parameter interpretation with xorriso actions -add and -path_list.
.br .br
"on" enables pathspecs of the form "on" enables pathspecs of the form
.B target=source .B target=source
@ -696,7 +748,7 @@ for their own decision.
.TP .TP
\fB\-dummy\fR "on"|"off" \fB\-dummy\fR "on"|"off"
If "on" simulate burning or refuse with SORRY event if If "on" simulate burning or refuse with SORRY event if
no simulation is possible. If "on" do not blank or format. no simulation is possible, do neither blank nor format.
.TP .TP
\fB-fs\fR number["k"|"m"] \fB-fs\fR number["k"|"m"]
Set the size of the fifo buffer which smoothens the data Set the size of the fifo buffer which smoothens the data
@ -754,11 +806,20 @@ Enable or disable to enter dialog mode after all arguments
are processed. In dialog mode input lines get prompted via are processed. In dialog mode input lines get prompted via
readline or from stdin. readline or from stdin.
.TP .TP
\fB\-page\fR len width \fB\-page\fR length width
Describe terminal to the text pager. See above, paragraph Result pager. Describe terminal to the text pager. See also above, paragraph Result pager.
.br
If parameter length is nonzero then the user gets prompted after that
number of terminal lines. Zero length disables paging.
.br
Parameter width is the number of characters per terminal line. It is used
to compute the number of terminal lines which get occupied by an output line.
A usual terminal width is 80.
.TP .TP
\fB\-use_readline\fR "on"|"off" \fB\-use_readline\fR "on"|"off"
If "on" then use readline for dialog. Else use plain stdin. If "on" then use readline for dialog. Else use plain stdin.
.br
See also above, paragraph Dialog, Readline, Result pager.
.TP .TP
\fB\-reassure\fR "on"|"tree"|"off" \fB\-reassure\fR "on"|"tree"|"off"
If "on" then ask the user for "y" or "n" If "on" then ask the user for "y" or "n"
@ -797,7 +858,7 @@ This is only possible when no ISO image changes are pending.
After this option was executed, there is no drive current After this option was executed, there is no drive current
and no image loaded. Eventually one has to aquire a drive again. and no image loaded. Eventually one has to aquire a drive again.
.br .br
In order to be visible a device has to offer rw-permissions In order to be visible, a device has to offer rw-permissions
with its libburn standard device file. Thus it might be only the with its libburn standard device file. Thus it might be only the
.B superuser .B superuser
who is able to see all drives. who is able to see all drives.

View File

@ -2333,6 +2333,90 @@ next_in_dirseq:;
} }
/* ------------------------------ 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);
}
/* ------------------------------- Xorriso -------------------------------- */ /* ------------------------------- Xorriso -------------------------------- */
/** The list of startup file names */ /** The list of startup file names */
@ -2370,7 +2454,11 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
strcpy(m->wdx, m->initial_wdx); strcpy(m->wdx, m->initial_wdx);
m->did_something_useful= 0; m->did_something_useful= 0;
m->do_joliet= 0; m->do_joliet= 0;
m->do_follow_pattern= 1;
m->do_follow_param= 0;
m->do_follow_links= 0; m->do_follow_links= 0;
m->follow_link_limit= 100;
m->do_follow_mount= 1;
m->do_global_uid= 0; m->do_global_uid= 0;
m->global_uid= 0; m->global_uid= 0;
m->volid[0]= 0; m->volid[0]= 0;
@ -3307,6 +3395,90 @@ int Xorriso_match_file(struct XorrisO *xorriso, char *to_match, char *adr,
} }
/* @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:;
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, "SORRY",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) {
sprintf(xorriso->info_text, "Empty link target with : %s",
Text_shellsafe(link_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "SORRY",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:;
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,"SORRY",0);
return(0);
}
}
return(1);
}
int Xorriso_status_result(struct XorrisO *xorriso, char *filter, FILE *fp, int Xorriso_status_result(struct XorrisO *xorriso, char *filter, FILE *fp,
int flag) int flag)
/* /*
@ -3343,7 +3515,7 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag)
*/ */
{ {
int is_default,no_defaults,i; int is_default,no_defaults,i;
char *line, sfe[5*SfileadrL]; char *line, sfe[5*SfileadrL], mode[80];
static char channel_prefixes[4][4]= {".","R","I","M"}; static char channel_prefixes[4][4]= {".","R","I","M"};
no_defaults= flag&1; no_defaults= flag&1;
@ -3457,8 +3629,20 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag)
if(!(is_default && no_defaults)) if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2); Xorriso_status_result(xorriso,filter,fp,flag&2);
is_default= !xorriso->do_follow_links; is_default= (xorriso->do_follow_pattern && (!xorriso->do_follow_param)
sprintf(line,"-follow %s\n", xorriso->do_follow_links ? "on" : "off"); && xorriso->do_follow_mount && !xorriso->do_follow_links);
mode[0]= 0;
if(xorriso->do_follow_pattern)
strcat(mode,":pattern");
if(xorriso->do_follow_param)
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(line,"-follow %s\n", mode+1);
if(!(is_default && no_defaults)) if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2); Xorriso_status_result(xorriso,filter,fp,flag&2);
@ -3740,10 +3924,14 @@ int Xorriso_obtain_pattern_files_x(
int *filec, char **filev, int count_limit, off_t *mem, int *filec, char **filev, int count_limit, off_t *mem,
int *dive_count, int flag) int *dive_count, int flag)
{ {
int ret, failed_at; int ret, failed_at, follow_mount, follow_links;
char adr[SfileadrL], name[SfileadrL]; char adr[SfileadrL], name[SfileadrL], path_data[SfileadrL], *path;
struct DirseQ *dirseq; struct DirseQ *dirseq;
struct stat stbuf;
dev_t dir_dev;
follow_mount= (xorriso->do_follow_mount || xorriso->do_follow_pattern);
follow_links= (xorriso->do_follow_links || xorriso->do_follow_pattern);
if(!(flag&2)) if(!(flag&2))
*dive_count= 0; *dive_count= 0;
else else
@ -3754,6 +3942,15 @@ int Xorriso_obtain_pattern_files_x(
if(ret!=2) if(ret!=2)
goto ex; 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); ret= Dirseq_new(&dirseq, dir_adr, 1);
if(ret<0) { if(ret<0) {
sprintf(xorriso->info_text, "Cannot obtain disk directory iterator"); sprintf(xorriso->info_text, "Cannot obtain disk directory iterator");
@ -3781,12 +3978,27 @@ int Xorriso_obtain_pattern_files_x(
if(ret>0) { /* no match */ if(ret>0) { /* no match */
if(failed_at <= *dive_count) /* no hope for a match */ if(failed_at <= *dive_count) /* no hope for a match */
continue; continue;
path= adr;
if(adr[0]!='/') {
path= path_data;
ret= Xorriso_make_pattern_adr(xorriso, xorriso->wdx, adr, path, 1|4);
if(ret<=0)
goto ex;
}
ret= Sfile_type(adr, 1|((xorriso->do_follow_links || !(flag&2))<<2)); if(follow_links)
if(ret!=2) ret= stat(path,&stbuf);
else
ret= lstat(path,&stbuf);
if(ret==-1)
continue; continue;
if(!S_ISDIR(stbuf.st_mode))
continue;
if(dir_dev != stbuf.st_dev && !follow_mount)
continue;
/* dive deeper */ /* dive deeper */
ret= Xorriso_obtain_pattern_files_x(xorriso, adr, adr, ret= Xorriso_obtain_pattern_files_x(xorriso, adr, path,
filec, filev, count_limit, mem, dive_count, flag|2); filec, filev, count_limit, mem, dive_count, flag|2);
if(ret<=0) if(ret<=0)
goto ex; goto ex;
@ -3807,6 +4019,7 @@ ex:;
return(ret); return(ret);
} }
int Xorriso_eval_nonmatch(struct XorrisO *xorriso, char *pattern, int Xorriso_eval_nonmatch(struct XorrisO *xorriso, char *pattern,
int *nonconst_mismatches, off_t *mem, int flag) int *nonconst_mismatches, off_t *mem, int flag)
{ {
@ -4270,7 +4483,7 @@ int Xorriso_msgs_submit(struct XorrisO *xorriso,
1= no problem, go on 1= no problem, go on
0= function failed but xorriso would not abort, go on 0= function failed but xorriso would not abort, go on
<0= do abort <0= do abort
-1 = due to probelm_status -1 = due to problem_status
-2 = due to xorriso->request_to_abort -2 = due to xorriso->request_to_abort
*/ */
int Xorriso_eval_problem_status(struct XorrisO *xorriso, int ret, int flag) int Xorriso_eval_problem_status(struct XorrisO *xorriso, int ret, int flag)
@ -4393,23 +4606,83 @@ int Xorriso_check_temp_mem_limit(struct XorrisO *xorriso, off_t mem, 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 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));
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));
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 /* @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 @return <=0 error , 1 ok , 2 could not open directory
*/ */
int Xorriso_show_dux_subs(struct XorrisO *xorriso, int Xorriso_show_dux_subs(struct XorrisO *xorriso,
char *abs_path, char *rel_path, off_t *size, char *abs_path, char *rel_path, off_t *size,
off_t boss_mem, int flag) off_t boss_mem,
struct LinkiteM *link_stack,
int flag)
{ {
int i, ret, no_sort= 0, filec= 0, l, j, fc; int i, ret, no_sort= 0, filec= 0, l, j, fc, no_dive, is_link;
char path[SfileadrL], show_path[SfileadrL], name[SfileadrL], sfe[5*SfileadrL]; char path[SfileadrL], show_path[SfileadrL], name[SfileadrL], sfe[5*SfileadrL];
char **filev= NULL, *namept; char **filev= NULL, *namept;
off_t sub_size, report_size, mem= 0; off_t sub_size, report_size, mem= 0;
struct DirseQ *dirseq= NULL; struct DirseQ *dirseq= NULL;
struct stat stbuf; struct stat stbuf;
dev_t dir_dev;
struct LinkiteM *own_link_stack;
own_link_stack= link_stack;
namept= name; namept= name;
*size= 0; *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); ret= Dirseq_new(&dirseq, abs_path, 1);
if(ret<0) { if(ret<0) {
sprintf(xorriso->info_text, "Cannot obtain disk directory iterator"); sprintf(xorriso->info_text, "Cannot obtain disk directory iterator");
@ -4420,6 +4693,7 @@ int Xorriso_show_dux_subs(struct XorrisO *xorriso,
{ret= 2; goto ex;} {ret= 2; goto ex;}
while(1) { while(1) {
Linkitem_reset_stack(&own_link_stack, link_stack, 0);
ret= Dirseq_next_adr(dirseq,name,0); ret= Dirseq_next_adr(dirseq,name,0);
if(ret<0) if(ret<0)
goto ex; goto ex;
@ -4437,26 +4711,45 @@ much_too_long:;
Xorriso_much_too_long(xorriso, strlen(path)+strlen(name)+1, 2); Xorriso_much_too_long(xorriso, strlen(path)+strlen(name)+1, 2);
{ret= -1; goto ex;} {ret= -1; goto ex;}
} }
no_dive= 0;
ret= lstat(path, &stbuf); ret= lstat(path, &stbuf);
if(ret==-1) if(ret==-1)
continue; continue;
if(S_ISDIR(stbuf.st_mode)) { 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++; filec++;
l= strlen(rel_path)+1; l= strlen(rel_path)+1;
mem+= l; mem+= l;
if(l % sizeof(char *)) if(l % sizeof(char *))
mem+= sizeof(char *)-(l % sizeof(char *)); mem+= sizeof(char *)-(l % sizeof(char *));
ret= Xorriso_show_dux_subs(xorriso, path,show_path,&sub_size,boss_mem,0); if(flag&1) /* diving and counting is done further down */
continue;
ret= Xorriso_show_dux_subs(xorriso, path, show_path, &sub_size, boss_mem,
own_link_stack,2);
if(ret<0) if(ret<0)
goto ex; goto ex;
if(ret==0) if(ret==0)
continue; continue;
} }
/*
sub_size+= stbuf.st_size+strlen(name)+1; sub_size+= stbuf.st_size+strlen(name)+1;
*/
sub_size+= stbuf.st_size+2048;
if(sub_size>0) if(sub_size>0)
(*size)+= sub_size; (*size)+= sub_size;
Xorriso_process_msg_queues(xorriso,0);
} }
if(filec<=0 || !(flag&1)) if(filec<=0 || !(flag&1))
@ -4488,19 +4781,33 @@ no_sort_possible:;
strcpy(path, abs_path); strcpy(path, abs_path);
if(Sfile_add_to_path(path, name, 0)<=0) if(Sfile_add_to_path(path, name, 0)<=0)
goto much_too_long; goto much_too_long;
ret= lstat(path,&stbuf); ret= lstat(path,&stbuf);
if(ret==-1) if(ret==-1)
continue; continue;
is_link= S_ISLNK(stbuf.st_mode);
if(is_link && xorriso->do_follow_links) {
ret= stat(path,&stbuf);
if(ret==-1)
continue;
}
if(!S_ISDIR(stbuf.st_mode)) if(!S_ISDIR(stbuf.st_mode))
continue; continue;
filev[fc]= strdup(name); if(dir_dev != stbuf.st_dev && !xorriso->do_follow_mount)
if(filev[fc]==NULL) { continue;
if(fc>=filec) { /* Number of files changed (or programming error) */
revoke_sorting:;
for(j=0; j<fc; j++) for(j=0; j<fc; j++)
free((char *) filev[j]); free((char *) filev[j]);
free((char *) filev); free((char *) filev);
filev= NULL; filev= NULL;
goto no_sort_possible; goto no_sort_possible;
} }
filev[fc]= strdup(name);
if(filev[fc]==NULL)
goto revoke_sorting;
fc++; fc++;
} }
filec= fc; filec= fc;
@ -4510,20 +4817,16 @@ no_sort_possible:;
} }
for(i= 0; (no_sort || i<filec) && !(xorriso->request_to_abort); i++) { for(i= 0; (no_sort || i<filec) && !(xorriso->request_to_abort); i++) {
Linkitem_reset_stack(&own_link_stack, link_stack, 0);
if(no_sort) { if(no_sort) {
ret= Dirseq_next_adr(dirseq,name,0); ret= Dirseq_next_adr(dirseq,name,0);
if(ret<0) if(ret<0)
goto ex; goto ex;
if(ret==0) if(ret==0)
break; break;
ret= lstat(path, &stbuf);
if(ret==-1)
continue;
if(!S_ISDIR(stbuf.st_mode))
continue;
} else } else
namept= filev[i]; namept= filev[i];
sub_size= 0; sub_size= 0;
strcpy(show_path, rel_path); strcpy(show_path, rel_path);
if(Sfile_add_to_path(show_path, namept, 0)<=0) if(Sfile_add_to_path(show_path, namept, 0)<=0)
@ -4531,11 +4834,34 @@ no_sort_possible:;
strcpy(path, abs_path); strcpy(path, abs_path);
if(Sfile_add_to_path(path, namept, 0)<=0) if(Sfile_add_to_path(path, namept, 0)<=0)
goto much_too_long; goto much_too_long;
no_dive= 0;
ret= Xorriso_show_dux_subs(xorriso, ret= lstat(path,&stbuf);
path, show_path, &sub_size, boss_mem+mem, flag&1); 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) if(ret<0)
goto ex; 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; report_size= sub_size/1024;
if(report_size*1024<sub_size) if(report_size*1024<sub_size)
report_size++; report_size++;
@ -4547,6 +4873,7 @@ no_sort_possible:;
ret= 1; ret= 1;
ex:; ex:;
Linkitem_reset_stack(&own_link_stack, link_stack, 0);
Dirseq_destroy(&dirseq, 0); Dirseq_destroy(&dirseq, 0);
if(filev!=NULL) { if(filev!=NULL) {
for(i=0; i<filec; i++) for(i=0; i<filec; i++)
@ -4652,7 +4979,8 @@ int Xorriso_lsx_filev(struct XorrisO *xorriso, int filec, char **filev,
off_t boss_mem, int flag) off_t boss_mem, int flag)
{ {
int i, ret, was_error= 0; int i, ret, was_error= 0;
char sfe[5*SfileadrL], path[SfileadrL], *rpt; char sfe[5*SfileadrL], sfe2[5*SfileadrL], path[SfileadrL];
char *rpt, link_target[SfileadrL];
off_t size; off_t size;
struct stat stbuf; struct stat stbuf;
@ -4667,14 +4995,11 @@ int Xorriso_lsx_filev(struct XorrisO *xorriso, int filec, char **filev,
was_error++; was_error++;
continue; continue;
} }
if(xorriso->do_follow_links)
ret= stat(path, &stbuf);
else
ret= lstat(path, &stbuf); ret= lstat(path, &stbuf);
if(ret==-1) { if(ret==-1) {
sprintf(xorriso->info_text, "Not found in local filesystem: %s", sprintf(xorriso->info_text, "Not found in local filesystem: %s",
Text_shellsafe(path, sfe, 0)); Text_shellsafe(path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 1);
was_error++; was_error++;
continue; continue;
} }
@ -4691,22 +5016,33 @@ int Xorriso_lsx_filev(struct XorrisO *xorriso, int filec, char **filev,
ret= Xorriso_make_pattern_adr(xorriso, xorriso->wdx, filev[i], path, 1|4); ret= Xorriso_make_pattern_adr(xorriso, xorriso->wdx, filev[i], path, 1|4);
if(ret<=0) if(ret<=0)
continue; continue;
if(xorriso->do_follow_links)
ret= stat(path, &stbuf);
else
ret= lstat(path, &stbuf); ret= lstat(path, &stbuf);
if(ret==-1) if(ret==-1)
continue; 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;
link_target[0]= 0;
rpt[0]= 0; rpt[0]= 0;
if((flag&5)==1) { if((flag&5)==1) {
ret= Xorriso_format_ls_l(xorriso, &stbuf, 0); ret= Xorriso_format_ls_l(xorriso, &stbuf, 0);
if(ret<=0) if(ret<=0)
continue; 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 -du_s */ } else if(flag&4) { /* -du or -du_s */
size= stbuf.st_size; size= stbuf.st_size;
if(S_ISDIR(stbuf.st_mode)) { if(S_ISDIR(stbuf.st_mode)) {
ret= Xorriso_show_dux_subs(xorriso, ret= Xorriso_show_dux_subs(xorriso, path, filev[i], &size, boss_mem,
path, filev[i], &size, boss_mem, flag&1); NULL, flag&1);
if(ret<0) if(ret<0)
return(-1); return(-1);
if(ret==0) if(ret==0)
@ -4714,6 +5050,11 @@ int Xorriso_lsx_filev(struct XorrisO *xorriso, int filec, char **filev,
} }
sprintf(rpt, "%7.f ",(double) (size/1024)); 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", sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n",
Text_shellsafe(filev[i], sfe, 0)); Text_shellsafe(filev[i], sfe, 0));
Xorriso_result(xorriso, 0); Xorriso_result(xorriso, 0);
@ -4798,11 +5139,11 @@ int Xorriso_option_add(struct XorrisO *xorriso, int argc, char **argv,
goto problem_handler; goto problem_handler;
} }
ret= Xorriso_normalize_img_path(xorriso, target, eff_path, 2); ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, target, eff_path, 2);
if(ret<=0) if(ret<=0)
goto problem_handler; goto problem_handler;
strcpy(target, eff_path); strcpy(target, eff_path);
ret= Xorriso_normalize_img_path(xorriso, source, eff_path, 2|4); ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, source,eff_path,2|4);
if(ret<=0) if(ret<=0)
goto problem_handler; goto problem_handler;
strcpy(source, eff_path); strcpy(source, eff_path);
@ -4998,14 +5339,14 @@ int Xorriso_option_cdi(struct XorrisO *xorriso, char *iso_rr_path, int flag)
return(-1); return(-1);
} }
ret= Xorriso_normalize_img_path(xorriso, path, eff_path, 1); ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 1);
if(ret<0) if(ret<0)
return(ret); return(ret);
if(ret==0) { if(ret==0) {
sprintf(xorriso->info_text, "-cdi: not existing yet in ISO image : %s", sprintf(xorriso->info_text, "-cdi: not existing yet in ISO image : %s",
Text_shellsafe(path, sfe, 0)); Text_shellsafe(path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
ret= Xorriso_normalize_img_path(xorriso, path, eff_path, 2); ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 2);
if(ret<=0) if(ret<=0)
return(ret); return(ret);
} else if(ret!=2) { } else if(ret!=2) {
@ -5051,7 +5392,7 @@ int Xorriso_option_cdx(struct XorrisO *xorriso, char *disk_path, int flag)
return(-1); return(-1);
} }
ret= Xorriso_normalize_img_path(xorriso, path, eff_path, 2|4); ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, path, eff_path, 2|4);
if(ret<=0) if(ret<=0)
return(ret); return(ret);
if(eff_path[0]) { if(eff_path[0]) {
@ -5523,15 +5864,63 @@ int Xorriso_option_iso_rr_pattern(struct XorrisO *xorriso, char *mode,int flag)
/* Option -follow */ /* Option -follow */
int Xorriso_option_follow(struct XorrisO *xorriso, char *mode, int flag) int Xorriso_option_follow(struct XorrisO *xorriso, char *mode, int flag)
{ {
if(strcmp(mode, "off")==0) int was_fl, was_fm, was_fpr, was_fpt, l;
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_links= 0;
else if(strcmp(mode, "on")==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_links= 1;
else { xorriso->do_follow_mount= 1;
sprintf(xorriso->info_text, "-follow: unknown mode '%s'", mode); } 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;
} 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 {
unknown_mode:;
if(l<SfileadrL)
sprintf(xorriso->info_text, "-follow: unknown mode '%s'", cpt);
else
sprintf(xorriso->info_text, "-follow: oversized mode parameter (%d)",l);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 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(0);
} }
}
return(1); return(1);
} }
@ -5695,7 +6084,8 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" Delete empty directories.", " Delete empty directories.",
" -- Mark end of particular action argument list.", " -- Mark end of particular action argument list.",
"", "",
"> -follow \"on\"|\"off\" Follow symbolic links within disk_path.", " -follow \"on\"|\"pattern:param:link:mount\"|\"default\"|\"off\"",
" Follow symbolic links and mount points within disk_path.",
"", "",
" -overwrite \"on\"|\"nondir\"|\"off\"", " -overwrite \"on\"|\"nondir\"|\"off\"",
" Allow or disallow to overwrite existing files in ISO image.", " Allow or disallow to overwrite existing files in ISO image.",
@ -6134,18 +6524,8 @@ int Xorriso_option_mvi(struct XorrisO *xorriso, int argc, char **argv,
if(ret<=0) if(ret<=0)
goto ex; goto ex;
#ifdef NIX
/* <<< */
/* Check existence of old addresses */
for(i= 0; i<optc; i++) {
ret= Xorriso_normalize_img_path(xorriso, optv[i], eff_origin, 0);
if(ret<=0)
{ret= 0; goto ex;}
}
#endif /* NIX */
/* Evaluate target address */ /* Evaluate target address */
ret= Xorriso_normalize_img_path(xorriso, destv[0], eff_dest, 1); ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, destv[0], eff_dest, 1);
if(ret<0) if(ret<0)
{ret= 0; goto ex;} {ret= 0; goto ex;}
if(ret==2) { if(ret==2) {
@ -6159,13 +6539,13 @@ int Xorriso_option_mvi(struct XorrisO *xorriso, int argc, char **argv,
{ret= 0; goto ex;} {ret= 0; goto ex;}
} }
if(ret==0) { /* compute complete eff_dest */ if(ret==0) { /* compute complete eff_dest */
ret= Xorriso_normalize_img_path(xorriso, destv[0], eff_dest, 2); ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, destv[0],eff_dest,2);
if(ret<0) if(ret<0)
{ret= 0; goto ex;} {ret= 0; goto ex;}
} }
/* Perform movements */ /* Perform movements */
for(i= 0; i<optc; i++) { for(i= 0; i<optc; i++) {
ret= Xorriso_normalize_img_path(xorriso, optv[i], eff_origin, 0); ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi,optv[i],eff_origin,0);
if(ret<=0 || xorriso->request_to_abort) if(ret<=0 || xorriso->request_to_abort)
goto problem_handler; goto problem_handler;
if(is_dir) { if(is_dir) {
@ -6580,7 +6960,7 @@ int Xorriso_option_rmi(struct XorrisO *xorriso, int argc, char **argv,
if(ret<=0) if(ret<=0)
goto problem_handler; goto problem_handler;
} }
ret= Xorriso_normalize_img_path(xorriso, path, eff_path, 2); ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 2);
if(ret<=0) if(ret<=0)
goto problem_handler; goto problem_handler;
strcpy(path, eff_path); strcpy(path, eff_path);
@ -6805,7 +7185,7 @@ int Xorriso_option_use_readline(struct XorrisO *xorriso, char *mode, int flag)
} }
/* Option -uid */ /* Option -V */
int Xorriso_option_v_capital(struct XorrisO *xorriso, char *volid, int flag) int Xorriso_option_v_capital(struct XorrisO *xorriso, char *volid, int flag)
{ {
fprintf(stderr, ">>> LIBISOFS : -V %s\n", volid); fprintf(stderr, ">>> LIBISOFS : -V %s\n", volid);
@ -6816,14 +7196,15 @@ int Xorriso_option_v_capital(struct XorrisO *xorriso, char *volid, int flag)
/* Option -version */ /* Option -version */
int Xorriso_option_version(struct XorrisO *xorriso, int flag) int Xorriso_option_version(struct XorrisO *xorriso, int flag)
{ {
sprintf(xorriso->result_line,
/* >>> print rather to result channel */; "xorriso %s : RockRidge filesystem manipulator\n", PROG_VERSION);
sprintf(xorriso->result_line+strlen(xorriso->result_line),
printf("xorriso %s : RockRidge filesystem manipulator\n", PROG_VERSION); "Copyright (C) 2007, Thomas Schmitt <scdbackup@gmx.net>, libburnia project\n");
printf("Copyright (C) 2007, Thomas Schmitt <scdbackup@gmx.net>, libburnia project\n"); sprintf(xorriso->result_line+strlen(xorriso->result_line),
printf("Version timestamp : %s\n",Xorriso_timestamP); "Version timestamp : %s\n",Xorriso_timestamP);
printf("Build timestamp : %s\n",Xorriso_build_timestamP); sprintf(xorriso->result_line+strlen(xorriso->result_line),
"Build timestamp : %s\n",Xorriso_build_timestamP);
Xorriso_result(xorriso, 0);
return(1); return(1);
} }

View File

@ -32,7 +32,7 @@
/* <<< ??? */ /* <<< ??? */
typedef int (*Cleanup_app_handler_T)(); typedef int (*Cleanup_app_handler_T)();
struct LinkiteM;
/* maximum number of history lines to be reported with -status:long_history */ /* maximum number of history lines to be reported with -status:long_history */
#define Xorriso_status_history_maX 100 #define Xorriso_status_history_maX 100
@ -67,7 +67,11 @@ struct XorrisO { /* the global context of xorriso */
/* >>> put libisofs aspects here <<< */ /* >>> put libisofs aspects here <<< */
int do_joliet; int do_joliet;
int do_follow_pattern;
int do_follow_param;
int do_follow_links; int do_follow_links;
int follow_link_limit;
int do_follow_mount;
int do_global_uid; int do_global_uid;
uid_t global_uid; uid_t global_uid;
int do_global_gid; int do_global_gid;
@ -242,6 +246,17 @@ int Xorriso_register_matched_adr(struct XorrisO *xorriso,
int Xorriso_format_ls_l(struct XorrisO *xorriso, struct stat *stbuf, 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);
int Sfile_str(char target[SfileadrL], char *source, int flag); int Sfile_str(char target[SfileadrL], char *source, int flag);
@ -267,5 +282,8 @@ int Dirseq_next_adr(struct DirseQ *o, char reply[SfileadrL], int flag);
int Linkitem_reset_stack(struct LinkiteM **o, struct LinkiteM *to, int flag);
#endif /* Xorriso_private_includeD */ #endif /* Xorriso_private_includeD */

View File

@ -1 +1 @@
#define Xorriso_timestamP "2007.12.15.162039" #define Xorriso_timestamP "2007.12.15.183022"

View File

@ -592,8 +592,8 @@ int Xorriso_get_volume(struct XorrisO *xorriso, struct iso_volume **volume,
@return -1 = faulty path format, 0 = not found , @return -1 = faulty path format, 0 = not found ,
1 = found simple node , 2 = found directory 1 = found simple node , 2 = found directory
*/ */
int Xorriso_normalize_img_path(struct XorrisO *xorriso, char *img_path, int Xorriso_normalize_img_path(struct XorrisO *xorriso, char *wd,
char eff_path[], int flag) char *img_path, char eff_path[], int flag)
{ {
int ret, is_dir= 0, done= 0; int ret, is_dir= 0, done= 0;
struct iso_volume *volume; struct iso_volume *volume;
@ -613,10 +613,7 @@ int Xorriso_normalize_img_path(struct XorrisO *xorriso, char *img_path,
apt= npt= path; apt= npt= path;
if(img_path[0]!='/') { if(img_path[0]!='/') {
if(flag&4) strcpy(path, wd);
strcpy(path, xorriso->wdx);
else
strcpy(path, xorriso->wdi);
ret= Sfile_add_to_path(path, img_path, 0); ret= Sfile_add_to_path(path, img_path, 0);
if(ret<=0) if(ret<=0)
goto much_too_long; goto much_too_long;
@ -705,7 +702,7 @@ int Xorriso_get_node_by_path(struct XorrisO *xorriso,
char sfe[5*SfileadrL], path[SfileadrL]; char sfe[5*SfileadrL], path[SfileadrL];
struct iso_volume *volume; struct iso_volume *volume;
ret= Xorriso_normalize_img_path(xorriso, in_path, path, 0); ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, in_path, path, 0);
if(ret<=0) if(ret<=0)
return(ret); return(ret);
if(eff_path!=NULL) if(eff_path!=NULL)
@ -726,21 +723,39 @@ int Xorriso_get_node_by_path(struct XorrisO *xorriso,
/* @param flag bit0= recursion is active */ /* @param flag bit0= recursion is active */
int Xorriso_add_tree(struct XorrisO *xorriso, struct iso_tree_node_dir *dir, int Xorriso_add_tree(struct XorrisO *xorriso, struct iso_tree_node_dir *dir,
char *img_dir_path, char *disk_dir_path, int flag) char *img_dir_path, char *disk_dir_path,
struct LinkiteM *link_stack, int flag)
{ {
struct iso_volume *volume; struct iso_volume *volume;
struct iso_tree_node *node; struct iso_tree_node *node;
int ret, target_is_dir, source_is_dir, fret, was_failure= 0; int ret, target_is_dir, source_is_dir, source_is_link, fret, was_failure= 0;
int do_not_dive;
struct DirseQ *dirseq= NULL; struct DirseQ *dirseq= NULL;
char sfe[5*SfileadrL], sfe2[5*SfileadrL]; char sfe[5*SfileadrL], sfe2[5*SfileadrL];
char disk_path[2*SfileadrL], img_path[2*SfileadrL]; char disk_path[2*SfileadrL], img_path[2*SfileadrL], link_target[SfileadrL];
char *name, *img_name; char *name, *img_name, *srcpt;
struct stat stbuf; struct stat stbuf, hstbuf;
dev_t dir_dev;
struct LinkiteM *own_link_stack;
own_link_stack= link_stack;
ret= Xorriso_get_volume(xorriso, &volume, 0); ret= Xorriso_get_volume(xorriso, &volume, 0);
if(ret<=0) if(ret<=0)
return(ret); return(ret);
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))))
return(2);
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))))
return(2);
}
ret= Dirseq_new(&dirseq, disk_dir_path, 1); ret= Dirseq_new(&dirseq, disk_dir_path, 1);
if(ret<0) { if(ret<0) {
sprintf(xorriso->info_text,"Failed to create source filesystem iterator"); sprintf(xorriso->info_text,"Failed to create source filesystem iterator");
@ -748,6 +763,7 @@ int Xorriso_add_tree(struct XorrisO *xorriso, struct iso_tree_node_dir *dir,
{ret= -1; goto ex;} {ret= -1; goto ex;}
} }
if(ret==0) { if(ret==0) {
cannot_open_dir:;
sprintf(xorriso->info_text,"Cannot open as source directory: %s", sprintf(xorriso->info_text,"Cannot open as source directory: %s",
Text_shellsafe(disk_dir_path, sfe, 0)); Text_shellsafe(disk_dir_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
@ -766,6 +782,8 @@ int Xorriso_add_tree(struct XorrisO *xorriso, struct iso_tree_node_dir *dir,
img_name= img_path+strlen(img_path); img_name= img_path+strlen(img_path);
while(1) { /* loop over directory content */ while(1) { /* loop over directory content */
Linkitem_reset_stack(&own_link_stack, link_stack, 0);
srcpt= disk_path;
Xorriso_process_msg_queues(xorriso,0); Xorriso_process_msg_queues(xorriso,0);
ret= Dirseq_next_adr(dirseq,name,0); ret= Dirseq_next_adr(dirseq,name,0);
if(ret==0) if(ret==0)
@ -778,21 +796,48 @@ int Xorriso_add_tree(struct XorrisO *xorriso, struct iso_tree_node_dir *dir,
strcpy(img_name, name); strcpy(img_name, name);
if(Xorriso_much_too_long(xorriso, strlen(img_path), 0)<=0) if(Xorriso_much_too_long(xorriso, strlen(img_path), 0)<=0)
{ret= 0; goto was_problem;} {ret= 0; goto was_problem;}
if(Xorriso_much_too_long(xorriso, strlen(disk_path), 0)<=0) if(Xorriso_much_too_long(xorriso, strlen(srcpt), 0)<=0)
{ret= 0; goto was_problem;} {ret= 0; goto was_problem;}
if(lstat(disk_path, &stbuf)==-1) { if(lstat(srcpt, &stbuf)==-1) {
cannot_lstat:;
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"Cannot determine attributes of source file %s", "Cannot determine attributes of source file %s",
Text_shellsafe(disk_path, sfe, 0)); Text_shellsafe(srcpt, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "SORRY", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "SORRY", 0);
ret= 0; goto was_problem; ret= 0; goto was_problem;
} }
source_is_dir= 0; 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;
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;
}
do_not_dive= 0;
if(S_ISDIR(stbuf.st_mode)) { if(S_ISDIR(stbuf.st_mode)) {
source_is_dir= 1; source_is_dir= 1;
if(dir_dev != stbuf.st_dev && !xorriso->do_follow_mount)
do_not_dive= 1;
} else if(!(S_ISREG(stbuf.st_mode) || S_ISLNK(stbuf.st_mode))) { } else if(!(S_ISREG(stbuf.st_mode) || S_ISLNK(stbuf.st_mode))) {
sprintf(xorriso->info_text,"Source file %s is of non-supported file type", sprintf(xorriso->info_text,"Source file %s %s non-supported file type",
Text_shellsafe(disk_path, sfe, 0)); Text_shellsafe(disk_path, sfe, 0),
source_is_link ? "leads to" : "is of");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
ret= 0; goto was_problem; ret= 0; goto was_problem;
} }
@ -812,7 +857,7 @@ int Xorriso_add_tree(struct XorrisO *xorriso, struct iso_tree_node_dir *dir,
goto was_problem; goto was_problem;
if(ret==3) { if(ret==3) {
sprintf(xorriso->info_text, "User revoked adding of: %s", sprintf(xorriso->info_text, "User revoked adding of: %s",
Text_shellsafe(disk_path, sfe, 0)); Text_shellsafe(img_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
ret= 0; goto was_problem; ret= 0; goto was_problem;
} }
@ -827,8 +872,21 @@ int Xorriso_add_tree(struct XorrisO *xorriso, struct iso_tree_node_dir *dir,
} }
} }
if(node==NULL) if(node==NULL) {
node= iso_tree_add_node(dir, disk_path); if(S_ISLNK(stbuf.st_mode)) {
/* <<< One should rather change libisofs so that iso_tree_add_node()
adds a disk_link as RR link, if RR is enabled */
node= iso_tree_add_symlink(dir, img_name, link_target);
if(node!=NULL) {
/* >>> copy all file properties from disk_link to node */;
}
} else
node= iso_tree_add_node(dir, srcpt);
}
if(node == NULL) { if(node == NULL) {
Xorriso_process_msg_queues(xorriso,0); Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
@ -839,10 +897,15 @@ int Xorriso_add_tree(struct XorrisO *xorriso, struct iso_tree_node_dir *dir,
ret=0; goto was_problem; ret=0; goto was_problem;
} }
xorriso->volset_change_pending= 1; xorriso->volset_change_pending= 1;
/* name always equal to disk. Obsolete: iso_tree_node_set_name(node,name);*/
if(source_is_dir) { 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, (struct iso_tree_node_dir *) node, ret= Xorriso_add_tree(xorriso, (struct iso_tree_node_dir *) node,
img_path, disk_path, 1); img_path, disk_path, own_link_stack, 1);
}
if(ret<=0) if(ret<=0)
goto was_problem; goto was_problem;
} }
@ -858,6 +921,7 @@ was_problem:;
ret= 1; ret= 1;
ex: ex:
Xorriso_process_msg_queues(xorriso,0); Xorriso_process_msg_queues(xorriso,0);
Linkitem_reset_stack(&own_link_stack, link_stack, 0);
Dirseq_destroy(&dirseq, 0); Dirseq_destroy(&dirseq, 0);
if(ret<=0) if(ret<=0)
return(ret); return(ret);
@ -907,7 +971,11 @@ int Xorriso_graft_in(struct XorrisO *xorriso, char *disk_path, char *img_path,
apt= npt= path; apt= npt= path;
if(!(flag&1)) { if(!(flag&1)) {
if(lstat(disk_path, &stbuf) == -1) { if(xorriso->do_follow_links || xorriso->do_follow_param)
ret= stat(disk_path, &stbuf);
else
ret= lstat(disk_path, &stbuf);
if(ret == -1) {
Xorriso_process_msg_queues(xorriso,0); Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"Cannot determine attributes of source file '%s'",disk_path); "Cannot determine attributes of source file '%s'",disk_path);
@ -1014,21 +1082,10 @@ attach_source:;
/* directory node was created above */; /* directory node was created above */;
} else if(is_dir) { } else if(is_dir) {
ret= Xorriso_add_tree(xorriso, dir, img_path, disk_path, NULL, 0);
#ifdef Xorriso_on_its_way_ouT
/* <<< */
{ struct iso_tree_radd_dir_behavior behav= {NULL, 0, 0};
iso_tree_radd_dir(dir, disk_path, &behav);
}
#else
ret= Xorriso_add_tree(xorriso, dir, img_path, disk_path, 0);
if(ret<=0) if(ret<=0)
return(ret); return(ret);
#endif /* ! Xorriso_on_its_way_ouT */
} else { } else {
node= iso_tree_add_node(dir, disk_path); node= iso_tree_add_node(dir, disk_path);
if(node == NULL) { if(node == NULL) {
@ -1923,7 +1980,8 @@ int Xorriso_ls_filev(struct XorrisO *xorriso, int filec, char **filev,
int i, ret, was_error= 0; int i, ret, was_error= 0;
struct iso_tree_node *node; struct iso_tree_node *node;
struct iso_volume *volume; struct iso_volume *volume;
char sfe[5*SfileadrL], path[SfileadrL], *rpt; char sfe[5*SfileadrL], sfe2[5*SfileadrL], path[SfileadrL];
char link_target[SfileadrL], *rpt;
off_t size; off_t size;
struct stat stbuf; struct stat stbuf;
@ -1967,10 +2025,16 @@ int Xorriso_ls_filev(struct XorrisO *xorriso, int filec, char **filev,
ret= Xorriso_fake_stbuf(xorriso, path, &stbuf, &node, 0); ret= Xorriso_fake_stbuf(xorriso, path, &stbuf, &node, 0);
if(ret<=0) if(ret<=0)
continue; continue;
link_target[0]= 0;
if((flag&5)==1) { /* -ls_l */ if((flag&5)==1) { /* -ls_l */
ret= Xorriso_format_ls_l(xorriso, &stbuf, 0); ret= Xorriso_format_ls_l(xorriso, &stbuf, 0);
if(ret<=0) if(ret<=0)
continue; continue;
if(LIBISO_ISLNK(node)) {
if(Sfile_str(link_target, (char *) iso_tree_node_symlink_get_dest(
(struct iso_tree_node_symlink *) node), 0)<=0)
link_target[0]= 0;
}
} else if(flag&4) { /* -du or -du_s */ } else if(flag&4) { /* -du or -du_s */
size= stbuf.st_size; size= stbuf.st_size;
if(S_ISDIR(stbuf.st_mode)) { if(S_ISDIR(stbuf.st_mode)) {
@ -1983,6 +2047,11 @@ int Xorriso_ls_filev(struct XorrisO *xorriso, int filec, char **filev,
} }
sprintf(rpt, "%7.f ",(double) (size/1024)); 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", sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n",
Text_shellsafe(filev[i], sfe, 0)); Text_shellsafe(filev[i], sfe, 0));
Xorriso_result(xorriso, 0); Xorriso_result(xorriso, 0);
@ -2005,7 +2074,7 @@ int Xorriso_ls(struct XorrisO *xorriso, int flag)
struct iso_tree_node_dir *dir_node; struct iso_tree_node_dir *dir_node;
struct iso_volume *volume; struct iso_volume *volume;
struct iso_tree_iter *iter= NULL; struct iso_tree_iter *iter= NULL;
char sfe[5*SfileadrL], *npt, *rpt; char sfe[5*SfileadrL], sfe2[5*SfileadrL], link_target[SfileadrL], *npt, *rpt;
struct stat stbuf; struct stat stbuf;
rpt= xorriso->result_line; rpt= xorriso->result_line;
@ -2074,6 +2143,12 @@ wdi_is_not_a_dir:;
node= node_array[i]; node= node_array[i];
npt= (char *) iso_tree_node_get_name(node); npt= (char *) iso_tree_node_get_name(node);
link_target[0]= 0;
if(LIBISO_ISLNK(node)) {
if(Sfile_str(link_target, (char *) iso_tree_node_symlink_get_dest(
(struct iso_tree_node_symlink *) node), 0)<=0)
link_target[0]= 0;
}
rpt[0]= 0; rpt[0]= 0;
if(flag&1) { if(flag&1) {
ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1); ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1);
@ -2083,6 +2158,11 @@ wdi_is_not_a_dir:;
if(ret<=0) if(ret<=0)
continue; 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", sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n",
Text_shellsafe(npt, sfe, 0)); Text_shellsafe(npt, sfe, 0));
Xorriso_result(xorriso, 0); Xorriso_result(xorriso, 0);
@ -2108,14 +2188,14 @@ int Xorriso_rename(struct XorrisO *xorriso, char *origin, char *dest, int flag)
struct iso_tree_node_dir *origin_dir, *dest_dir; struct iso_tree_node_dir *origin_dir, *dest_dir;
struct iso_tree_node *node; struct iso_tree_node *node;
ret= Xorriso_normalize_img_path(xorriso, origin, eff_origin, 0); ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, origin, eff_origin, 0);
if(ret<=0) if(ret<=0)
return(ret); return(ret);
dest_ret= Xorriso_normalize_img_path(xorriso, dest, eff_dest, 1); dest_ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, dest, eff_dest,1);
if(dest_ret<0) if(dest_ret<0)
return(dest_ret); return(dest_ret);
if(dest_ret==0) { /* obtain eff_dest address despite it does not exist */ if(dest_ret==0) { /* obtain eff_dest address despite it does not exist */
ret= Xorriso_normalize_img_path(xorriso, dest, eff_dest, 2); ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, dest, eff_dest, 2);
if(ret<=0) if(ret<=0)
return(ret); return(ret);
} }
@ -2227,7 +2307,7 @@ int Xorriso_mkdir(struct XorrisO *xorriso, char *path, int flag)
int ret; int ret;
char eff_path[SfileadrL], sfe[5*SfileadrL]; char eff_path[SfileadrL], sfe[5*SfileadrL];
ret= Xorriso_normalize_img_path(xorriso, path, eff_path, 1); ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 1);
if(ret<0) if(ret<0)
return(-2); return(-2);
if(ret>0) { if(ret>0) {
@ -2237,7 +2317,7 @@ int Xorriso_mkdir(struct XorrisO *xorriso, char *path, int flag)
(ret==2 ? "WARNING" : "SORRY"), 0); (ret==2 ? "WARNING" : "SORRY"), 0);
return(-1+(ret==2)); return(-1+(ret==2));
} }
ret= Xorriso_normalize_img_path(xorriso, path, eff_path, 2); ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 2);
if(ret<0) if(ret<0)
return(-2); return(-2);
ret= Xorriso_graft_in(xorriso, NULL, eff_path, 1); ret= Xorriso_graft_in(xorriso, NULL, eff_path, 1);

View File

@ -80,7 +80,9 @@ int Xorriso_ls_filev(struct XorrisO *xorriso, int filec, char **filev,
*/ */
int Xorriso_ls(struct XorrisO *xorriso, int flag); int Xorriso_ls(struct XorrisO *xorriso, int flag);
/* @param eff_path returns resulting effective path. /* @param wd Path to prepend in case img_path is not absolute
@param img_path Absolute or relative path to be normalized
@param eff_path returns resulting effective path.
Must provide at least SfileadrL bytes of storage. Must provide at least SfileadrL bytes of storage.
@param flag bit0= do not produce problem events (unless faulty path format) @param flag bit0= do not produce problem events (unless faulty path format)
bit1= work purely literally, do not use libisofs bit1= work purely literally, do not use libisofs
@ -88,8 +90,8 @@ int Xorriso_ls(struct XorrisO *xorriso, int flag);
@return -1 = faulty path format, 0 = not found , @return -1 = faulty path format, 0 = not found ,
1 = found simple node , 2 = found directory 1 = found simple node , 2 = found directory
*/ */
int Xorriso_normalize_img_path(struct XorrisO *xorriso, char *img_path, int Xorriso_normalize_img_path(struct XorrisO *xorriso, char *wd,
char eff_path[], int flag); char *img_path, char eff_path[], int flag);
int Xorriso_rename(struct XorrisO *xorriso, char *origin, char *dest,int flag); int Xorriso_rename(struct XorrisO *xorriso, char *origin, char *dest,int flag);