Implemented option -follow

This commit is contained in:
2007-12-15 18:31:39 +00:00
parent 32efb7e144
commit bcf31583c8
6 changed files with 696 additions and 154 deletions

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 ,
1 = found simple node , 2 = found directory
*/
int Xorriso_normalize_img_path(struct XorrisO *xorriso, char *img_path,
char eff_path[], int flag)
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;
struct iso_volume *volume;
@ -613,10 +613,7 @@ int Xorriso_normalize_img_path(struct XorrisO *xorriso, char *img_path,
apt= npt= path;
if(img_path[0]!='/') {
if(flag&4)
strcpy(path, xorriso->wdx);
else
strcpy(path, xorriso->wdi);
strcpy(path, wd);
ret= Sfile_add_to_path(path, img_path, 0);
if(ret<=0)
goto much_too_long;
@ -705,7 +702,7 @@ int Xorriso_get_node_by_path(struct XorrisO *xorriso,
char sfe[5*SfileadrL], path[SfileadrL];
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)
return(ret);
if(eff_path!=NULL)
@ -726,21 +723,39 @@ int Xorriso_get_node_by_path(struct XorrisO *xorriso,
/* @param flag bit0= recursion is active */
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_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;
char sfe[5*SfileadrL], sfe2[5*SfileadrL];
char disk_path[2*SfileadrL], img_path[2*SfileadrL];
char *name, *img_name;
struct stat stbuf;
char disk_path[2*SfileadrL], img_path[2*SfileadrL], link_target[SfileadrL];
char *name, *img_name, *srcpt;
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);
if(ret<=0)
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);
if(ret<0) {
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;}
}
if(ret==0) {
cannot_open_dir:;
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, "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);
while(1) { /* loop over directory content */
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);
if(ret==0)
@ -778,21 +796,48 @@ int Xorriso_add_tree(struct XorrisO *xorriso, struct iso_tree_node_dir *dir,
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(disk_path), 0)<=0)
if(Xorriso_much_too_long(xorriso, strlen(srcpt), 0)<=0)
{ret= 0; goto was_problem;}
if(lstat(disk_path, &stbuf)==-1) {
if(lstat(srcpt, &stbuf)==-1) {
cannot_lstat:;
sprintf(xorriso->info_text,
"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);
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;
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)) {
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))) {
sprintf(xorriso->info_text,"Source file %s is of non-supported file type",
Text_shellsafe(disk_path, sfe, 0));
sprintf(xorriso->info_text,"Source file %s %s non-supported file type",
Text_shellsafe(disk_path, sfe, 0),
source_is_link ? "leads to" : "is of");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
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;
if(ret==3) {
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);
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)
node= iso_tree_add_node(dir, disk_path);
if(node==NULL) {
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) {
Xorriso_process_msg_queues(xorriso,0);
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;
}
xorriso->volset_change_pending= 1;
/* name always equal to disk. Obsolete: iso_tree_node_set_name(node,name);*/
if(source_is_dir) {
ret= Xorriso_add_tree(xorriso, (struct iso_tree_node_dir *) node,
img_path, disk_path, 1);
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,
img_path, disk_path, own_link_stack, 1);
}
if(ret<=0)
goto was_problem;
}
@ -858,6 +921,7 @@ was_problem:;
ret= 1;
ex:
Xorriso_process_msg_queues(xorriso,0);
Linkitem_reset_stack(&own_link_stack, link_stack, 0);
Dirseq_destroy(&dirseq, 0);
if(ret<=0)
return(ret);
@ -907,7 +971,11 @@ int Xorriso_graft_in(struct XorrisO *xorriso, char *disk_path, char *img_path,
apt= npt= path;
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);
sprintf(xorriso->info_text,
"Cannot determine attributes of source file '%s'",disk_path);
@ -1014,21 +1082,10 @@ attach_source:;
/* directory node was created above */;
} else if(is_dir) {
#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);
ret= Xorriso_add_tree(xorriso, dir, img_path, disk_path, NULL, 0);
if(ret<=0)
return(ret);
#endif /* ! Xorriso_on_its_way_ouT */
} else {
node= iso_tree_add_node(dir, disk_path);
if(node == NULL) {
@ -1923,7 +1980,8 @@ int Xorriso_ls_filev(struct XorrisO *xorriso, int filec, char **filev,
int i, ret, was_error= 0;
struct iso_tree_node *node;
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;
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);
if(ret<=0)
continue;
link_target[0]= 0;
if((flag&5)==1) { /* -ls_l */
ret= Xorriso_format_ls_l(xorriso, &stbuf, 0);
if(ret<=0)
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 */
size= stbuf.st_size;
if(S_ISDIR(stbuf.st_mode)) {
@ -1983,8 +2047,13 @@ int Xorriso_ls_filev(struct XorrisO *xorriso, int filec, char **filev,
}
sprintf(rpt, "%7.f ",(double) (size/1024));
}
sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n",
Text_shellsafe(filev[i], sfe, 0));
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);
@ -2005,7 +2074,7 @@ int Xorriso_ls(struct XorrisO *xorriso, int flag)
struct iso_tree_node_dir *dir_node;
struct iso_volume *volume;
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;
rpt= xorriso->result_line;
@ -2074,6 +2143,12 @@ wdi_is_not_a_dir:;
node= node_array[i];
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;
if(flag&1) {
ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1);
@ -2083,8 +2158,13 @@ wdi_is_not_a_dir:;
if(ret<=0)
continue;
}
sprintf(xorriso->result_line+strlen(xorriso->result_line), "%s\n",
Text_shellsafe(npt, sfe, 0));
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);
}
@ -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 *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)
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)
return(dest_ret);
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)
return(ret);
}
@ -2227,7 +2307,7 @@ 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, path, eff_path, 1);
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, path, eff_path, 1);
if(ret<0)
return(-2);
if(ret>0) {
@ -2237,7 +2317,7 @@ int Xorriso_mkdir(struct XorrisO *xorriso, char *path, int flag)
(ret==2 ? "WARNING" : "SORRY"), 0);
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)
return(-2);
ret= Xorriso_graft_in(xorriso, NULL, eff_path, 1);