Enabled osirrox of more file types, curbed with device files

This commit is contained in:
Thomas Schmitt 2008-05-24 09:25:26 +00:00
parent 4f1456769f
commit 50a0258a78
5 changed files with 205 additions and 50 deletions

View File

@ -1596,18 +1596,31 @@ pseudo-drives or as log files.
But its alter ego, osirrox, is able to extract file objects But its alter ego, osirrox, is able to extract file objects
from ISO images and to create, overwrite, or delete file objects on disk. from ISO images and to create, overwrite, or delete file objects on disk.
.TP .TP
\fB\-osirrox\fR "on"|"off" \fB\-osirrox\fR "on"|"device_files"|"off"
Setting "off" disables disk filesystem manipulations. This is the default Setting "off" disables disk filesystem manipulations. This is the default
unless the program was started with leafname "osirrox". Elsewise unless the program was started with leafname "osirrox". Elsewise
the capability to restore files can be enabled explicitly by -osirrox "on". the capability to restore files can be enabled explicitly by -osirrox "on".
.br
To enable restoring of special files by "device_files" is potentially
dangerous.
The meaning of the number st_rdev (see man 2 stat) depends much on the
operating system. Best is to restore device files only to the same system
from where they were copied. If not enabled, device files in the ISO image
are ignored during restore operations.
.br
Due to a bug of previous versions, device files from previous sessions might
have been altered to major=0, minor=1. So this combination does not get
restored.
.TP .TP
\fB\-cpx\fR iso_rr_path [***] disk_path \fB\-cpx\fR iso_rr_path [***] disk_path
Extract regular files from the ISO image and store them under the address given Extract single leaf file objects from the ISO image and store them under
by disk_path. If more then one iso_rr_path is given then disk_path must be the address given by disk_path. If more then one iso_rr_path is given then
a directory or non-existent. In the latter case it gets created and the disk_path must be a directory or non-existent. In the latter case it gets
extracted files get installed in it with the same leafnames. created. The extracted files get installed in it with the same leafnames.
.br .br
Missing directory components in disk_path will get created, if possible. Missing directory components in disk_path will get created, if possible.
Disk file exclusions are in effect. If this is undesired then perform
-not_mgt "off" first.
.TP .TP
.B Command compatibility emulations: .B Command compatibility emulations:
.PP .PP

View File

@ -3823,8 +3823,10 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag)
Xorriso_status_result(xorriso,filter,fp,flag&2); Xorriso_status_result(xorriso,filter,fp,flag&2);
} }
is_default= !(xorriso->allow_restore); is_default= (xorriso->allow_restore==0);
sprintf(line,"-osirrox %s\n", xorriso->allow_restore ? "on" : "off"); sprintf(line,"-osirrox %s\n",
xorriso->allow_restore ? xorriso->allow_restore==2 ? "device_files" : "on"
: "off");
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);
@ -5996,7 +5998,8 @@ int Xorriso__mode_to_perms(mode_t st_mode, char perms[10], int flag)
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)
{ {
char *rpt, perms[10]; int show_major_minor= 0;
char *rpt, perms[10], mm_text[80];
mode_t st_mode; mode_t st_mode;
rpt= xorriso->result_line; rpt= xorriso->result_line;
@ -6009,11 +6012,13 @@ int Xorriso_format_ls_l(struct XorrisO *xorriso, struct stat *stbuf, int flag)
strcat(rpt, "-"); strcat(rpt, "-");
else if(S_ISLNK(st_mode)) else if(S_ISLNK(st_mode))
strcat(rpt, "l"); strcat(rpt, "l");
else if(S_ISBLK(st_mode)) else if(S_ISBLK(st_mode)) {
strcat(rpt, "b"); strcat(rpt, "b");
else if(S_ISCHR(st_mode)) show_major_minor= 1;
} else if(S_ISCHR(st_mode)) {
strcat(rpt, "c"); strcat(rpt, "c");
else if(S_ISFIFO(st_mode)) show_major_minor= 1;
} else if(S_ISFIFO(st_mode))
strcat(rpt, "p"); strcat(rpt, "p");
else if(S_ISSOCK(st_mode)) else if(S_ISSOCK(st_mode))
strcat(rpt, "s"); strcat(rpt, "s");
@ -6027,6 +6032,11 @@ int Xorriso_format_ls_l(struct XorrisO *xorriso, struct stat *stbuf, int flag)
sprintf(rpt+strlen(rpt), "%-8lu ", (unsigned long) stbuf->st_uid); sprintf(rpt+strlen(rpt), "%-8lu ", (unsigned long) stbuf->st_uid);
sprintf(rpt+strlen(rpt), "%-8lu ", (unsigned long) stbuf->st_gid); sprintf(rpt+strlen(rpt), "%-8lu ", (unsigned long) stbuf->st_gid);
if(show_major_minor) {
sprintf(mm_text, "%d,%d", (int) ((stbuf->st_rdev>>8)&0xfff),
(int) (((stbuf->st_rdev&~0xfffff)>>12) | (stbuf->st_rdev&0xff)));
sprintf(rpt+strlen(rpt), "%8s ", mm_text);
} else
sprintf(rpt+strlen(rpt), "%8.f ", (double) stbuf->st_size); sprintf(rpt+strlen(rpt), "%8.f ", (double) stbuf->st_size);
Ftimetxt(stbuf->st_mtime, rpt+strlen(rpt), 0); Ftimetxt(stbuf->st_mtime, rpt+strlen(rpt), 0);
@ -7975,7 +7985,7 @@ int Xorriso_option_blank(struct XorrisO *xorriso, char *mode, int flag)
if(ret<=0) if(ret<=0)
return(2); return(2);
if(strcmp(mode, "as_needed")==0) if(strcmp(mode, "as_needed")==0 || mode[0]==0)
as_needed= 1; as_needed= 1;
else if(strcmp(mode, "all")==0 || strcmp(mode, "full")==0) else if(strcmp(mode, "all")==0 || strcmp(mode, "full")==0)
mode_flag= 0; mode_flag= 0;
@ -8008,9 +8018,7 @@ unusable_index:;
if(idx<0 || idx>255) if(idx<0 || idx>255)
goto unusable_index; goto unusable_index;
mode_flag|= (idx<<8); mode_flag|= (idx<<8);
} else if(mode[0]==0) } else {
mode_flag= !(flag&1);
else {
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"%s: Unknown %s mode '%s'", "%s: Unknown %s mode '%s'",
cmd, ((flag&1) ? "-format" : "-blank"), mode); cmd, ((flag&1) ? "-format" : "-blank"), mode);
@ -8669,6 +8677,7 @@ problem_handler:;
continue; continue;
goto ex; goto ex;
} }
if(xorriso->pacifier_count>0)
Xorriso_pacifier_callback(xorriso, "files copied", xorriso->pacifier_count, Xorriso_pacifier_callback(xorriso, "files copied", xorriso->pacifier_count,
xorriso->pacifier_total, "", 1); xorriso->pacifier_total, "", 1);
ret= !was_failure; ret= !was_failure;
@ -9589,12 +9598,12 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" Like -compare but affecting all files below directories.", " Like -compare but affecting all files below directories.",
"", "",
"Restore options (copying file objects from ISO image to disk filesystem):", "Restore options (copying file objects from ISO image to disk filesystem):",
" -osirrox \"on\"|\"off\"", " -osirrox \"on\"|\"device_files\"|\"off\"",
" By default \"off\" the inverse operation of xorriso from ISO", " By default \"off\" the inverse operation of xorriso from ISO",
" image to disk filesystem is disabled. \"on\" allows xorriso", " image to disk filesystem is disabled. \"on\" allows xorriso",
" to create, overwrite, delete files in the disk filesystem.", " to create, overwrite, delete files in the disk filesystem.",
" -cpx iso_rr_path [***] disk_path", " -cpx iso_rr_path [***] disk_path",
" Copy regular files from ISO image to disk filesystem.", " Copy leaf file objects from ISO image to disk filesystem.",
"", "",
"Compatibility emulation (argument list may be ended by --):", "Compatibility emulation (argument list may be ended by --):",
" -as mkisofs [-help|-o|-R|-J|-V|-P|-f|-graft-points|-path-list|pathspecs]", " -as mkisofs [-help|-o|-R|-J|-V|-P|-f|-graft-points|-path-list|pathspecs]",
@ -10473,6 +10482,8 @@ int Xorriso_option_osirrox(struct XorrisO *xorriso, char *mode, int flag)
{ {
if(strcmp(mode, "off")==0) if(strcmp(mode, "off")==0)
xorriso->allow_restore= 0; xorriso->allow_restore= 0;
else if(strcmp(mode, "device_files")==0)
xorriso->allow_restore= 2;
else if(strcmp(mode, "on")==0 || mode[0]==0) else if(strcmp(mode, "on")==0 || mode[0]==0)
xorriso->allow_restore= 1; xorriso->allow_restore= 1;
else { else {

View File

@ -158,7 +158,7 @@ struct XorrisO { /* the global context of xorriso */
/* XORRISO options */ /* XORRISO options */
int allow_graft_points; int allow_graft_points;
int allow_restore; int allow_restore; /* 0= disallowed, 1=allowed, 2=device files allowed */
int dialog; int dialog;

View File

@ -1 +1 @@
#define Xorriso_timestamP "2008.05.22.210835" #define Xorriso_timestamP "2008.05.24.092546"

View File

@ -1474,6 +1474,87 @@ int Xorriso_get_node_by_path(struct XorrisO *xorriso,
} }
/* <<< this is not safe
#define Xorriso_can_get_dev_T 1
#define Xorriso_get_dev_by_botcH 1
*/
#ifndef Xorriso_can_get_dev_T
#ifdef Xorriso_standalonE
/* this is safe */
#define Xorriso_can_get_dev_T 1
#define Xorriso_get_dev_by_botcH 1
#endif /* Xorriso_standalonE */
#endif /* Xorriso_can_get_dev_T */
/* @param flag bit0= do not complain about being unable to retrieve info
*/
int Xorriso_node_get_dev(struct XorrisO *xorriso, IsoNode *node,
char *path, dev_t *dev, int flag)
{
#ifdef Xorriso_can_get_dev_T
/* >>> insert future API call here and remove botch below */
/* <<< */
#ifdef Xorriso_get_dev_by_botcH
/* Drilling a hole into libisofs-0.6.4 in order to substitute for the lack
of an API call which returns the dev_t number of a IsoSpecial (block or
character device).
*/
/* These are clones from libisofs/node.h */
typedef struct iso_extended_info IsoExtendedInfo_0_6_4_xorrisO;
struct Iso_Node_0_6_4_xorrisO
{
int refcount;
enum IsoNodeType type;
char *name;
mode_t mode;
uid_t uid;
gid_t gid;
time_t atime;
time_t mtime;
time_t ctime;
int hidden;
IsoDir *parent;
IsoNode *next;
IsoExtendedInfo_0_6_4_xorrisO *xinfo;
};
struct Iso_Special_0_6_4_xorrisO
{
struct Iso_Node_0_6_4_xorrisO node;
dev_t dev;
};
*dev= ((struct Iso_Special_0_6_4_xorrisO *) node)->dev;
return(1);
#endif /* Xorriso_get_dev_by_botcH */
#else /* Xorriso_can_get_dev_T */
char sfe[SfileadrL];
if(flag&1)
return(0);
sprintf(xorriso->info_text,
"Cannot obtain device major,minor from ISO image file %s",
Text_shellsafe(path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
return(0);
#endif /* ! Xorriso_can_get_dev_T */
}
/* @param flag bit0= *node is already valid /* @param flag bit0= *node is already valid
bit1= add extra block for size estimation bit1= add extra block for size estimation
*/ */
@ -1505,11 +1586,13 @@ int Xorriso_fake_stbuf(struct XorrisO *xorriso, char *path, struct stat *stbuf,
stbuf->st_mode|= S_IFREG; stbuf->st_mode|= S_IFREG;
else if(LIBISO_ISLNK(*node)) else if(LIBISO_ISLNK(*node))
stbuf->st_mode|= S_IFLNK; stbuf->st_mode|= S_IFLNK;
else if(LIBISO_ISCHR(*node)) else if(LIBISO_ISCHR(*node)) {
stbuf->st_mode|= S_IFCHR; stbuf->st_mode|= S_IFCHR;
else if(LIBISO_ISBLK(*node)) Xorriso_node_get_dev(xorriso, *node, path, &(stbuf->st_rdev), 1);
} else if(LIBISO_ISBLK(*node)) {
stbuf->st_mode|= S_IFBLK; stbuf->st_mode|= S_IFBLK;
else if(LIBISO_ISFIFO(*node)) Xorriso_node_get_dev(xorriso, *node, path, &(stbuf->st_rdev), 1);
} else if(LIBISO_ISFIFO(*node))
stbuf->st_mode|= S_IFIFO; stbuf->st_mode|= S_IFIFO;
else if(LIBISO_ISSOCK(*node)) else if(LIBISO_ISSOCK(*node))
stbuf->st_mode|= S_IFSOCK; stbuf->st_mode|= S_IFSOCK;
@ -1524,8 +1607,6 @@ int Xorriso_fake_stbuf(struct XorrisO *xorriso, char *path, struct stat *stbuf,
stbuf->st_uid= iso_node_get_uid(*node); stbuf->st_uid= iso_node_get_uid(*node);
stbuf->st_gid= iso_node_get_gid(*node); stbuf->st_gid= iso_node_get_gid(*node);
/* >>> stbuf->st_rdev */
if(LIBISO_ISREG(*node)) if(LIBISO_ISREG(*node))
stbuf->st_size= iso_file_get_size((IsoFile *) *node)+ (2048 * !!(flag&2)); stbuf->st_size= iso_file_get_size((IsoFile *) *node)+ (2048 * !!(flag&2));
else else
@ -2439,16 +2520,22 @@ int Xorriso_restore_implict_properties(struct XorrisO *xorriso, IsoDir *dir,
#endif /* Osirrox_not_yeT */ #endif /* Osirrox_not_yeT */
/* @param flag bit0= minimal transfer: access permissions only /* @param flag bit0= Minimal transfer: access permissions only
@return <0 severe error , 0 failure , 1 success bit2= This is not a parameter. Do not report if ignored
@return <0 severe error , 0 failure , 1 success ,
2 regularly not installed (disallowed device, UNIX domain socket)
*/ */
int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node, int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
char *img_path, char *disk_path, int flag) char *img_path, char *disk_path, int flag)
{ {
int ret= 0, write_fd= -1, wanted, wret; int ret= 0, write_fd= -1, wanted, wret;
char *what= "[unknown filetype]", sfe[5*SfileadrL], buf[32*1024]; char *what= "[unknown filetype]", sfe[5*SfileadrL], sfe2[5*SfileadrL];
char buf[32*1024];
char *link_target;
off_t todo, size; off_t todo, size;
void *stream2= NULL; void *data_stream= NULL;
mode_t mode;
dev_t dev= 0;
if(LIBISO_ISDIR(node)) { if(LIBISO_ISDIR(node)) {
what= "directory"; what= "directory";
@ -2456,8 +2543,10 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
} else if(LIBISO_ISREG(node)) { } else if(LIBISO_ISREG(node)) {
what= "regular file"; what= "regular file";
/* >>> need to exploit node rather than img_path */ /* >>> need to exploit node rather than img_path */
ret= Xorriso_iso_file_open(xorriso, img_path, &stream2, 0); ret= Xorriso_iso_file_open(xorriso, img_path, &data_stream, 0);
if(ret<=0) if(ret<=0)
goto ex; goto ex;
write_fd= open(disk_path,O_WRONLY|O_EXCL|O_CREAT); write_fd= open(disk_path,O_WRONLY|O_EXCL|O_CREAT);
@ -2468,7 +2557,7 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
wanted= sizeof(buf); wanted= sizeof(buf);
if(wanted>todo) if(wanted>todo)
wanted= todo; wanted= todo;
ret= Xorriso_iso_file_read(xorriso, stream2, buf, wanted, 0); ret= Xorriso_iso_file_read(xorriso, data_stream, buf, wanted, 0);
if(ret<=0) if(ret<=0)
break; break;
wret= write(write_fd, buf, ret); wret= write(write_fd, buf, ret);
@ -2484,40 +2573,77 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
} }
close(write_fd); close(write_fd);
write_fd= -1; write_fd= -1;
Xorriso_iso_file_close(xorriso, &stream2, 0); Xorriso_iso_file_close(xorriso, &data_stream, 0);
stream2= NULL; data_stream= NULL;
ret= (todo==0); ret= (todo==0);
} else if(LIBISO_ISLNK(node)) { } else if(LIBISO_ISLNK(node)) {
what= "symbolic link"; what= "symbolic link";
link_target= (char *) iso_symlink_get_dest((IsoSymlink *) node);
goto not_this_type; ret= symlink(link_target, disk_path);
/* >>> restore symbolic link */;
} else if(LIBISO_ISCHR(node)) { } else if(LIBISO_ISCHR(node)) {
what= "character device"; 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;}
}
#ifdef Xorriso_can_get_dev_T
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);
#else
goto not_this_type; goto not_this_type;
/* >>> restore character device */; #endif
} else if(LIBISO_ISBLK(node)) { } else if(LIBISO_ISBLK(node)) {
what= "block device"; what= "block device";
if(xorriso->allow_restore!=2)
goto ignored;
#ifdef Xorriso_can_get_dev_T
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);
#else
goto not_this_type; goto not_this_type;
/* >>> restore block device */; #endif
} else if(LIBISO_ISFIFO(node)) { } else if(LIBISO_ISFIFO(node)) {
what= "named pipe"; what= "named pipe";
mode= S_IFIFO | 0777;
goto not_this_type; ret= mknod(disk_path, mode, dev);
/* >>> restore fifo */;
} else if(LIBISO_ISSOCK(node)) { } else if(LIBISO_ISSOCK(node)) {
what= ""; what= "unix socket";
/* restoring a socket file makes no sense */; /* Restoring a socket file is not possible. One rather needs to restart
the service which temporarily created the socket. */
goto ignored;
} else { } else {
#ifndef Xorriso_can_get_dev_T
not_this_type:; not_this_type:;
#endif
sprintf(xorriso->info_text, "Cannot restore file type '%s'", what); sprintf(xorriso->info_text, "Cannot restore file type '%s'", what);
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 ex; ret= 0; goto ex;
@ -2530,11 +2656,15 @@ cannot_restore:;
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
ret= 0; goto ex; ret= 0; goto ex;
} }
if(LIBISO_ISLNK(node))
ret= 1;
else
ret= Xorriso_restore_properties(xorriso, disk_path, node, flag&1); ret= Xorriso_restore_properties(xorriso, disk_path, node, flag&1);
ex:; ex:;
if(write_fd>0) if(write_fd>0)
close(write_fd); close(write_fd);
Xorriso_iso_file_close(xorriso, &stream2, 0); if(data_stream!=NULL)
Xorriso_iso_file_close(xorriso, &data_stream, 0);
return(ret); return(ret);
} }
@ -2718,14 +2848,15 @@ attach_source:;
img_path_pt= img_path; img_path_pt= img_path;
ret= Xorriso_tree_restore_node(xorriso, node, img_path_pt, path, ret= Xorriso_tree_restore_node(xorriso, node, img_path_pt, path,
!!(flag&64)); (flag&4) | !!(flag&64));
if(ret<=0) { if(ret<=0) {
sprintf(xorriso->info_text, "Restoring failed: %s = %s", sprintf(xorriso->info_text, "Restoring failed: %s = %s",
Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0)); Text_shellsafe(img_path,sfe,0), Text_shellsafe(disk_path,sfe2,0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0); return(0);
} }
if(ret==2)
return(3);
xorriso->pacifier_count++; xorriso->pacifier_count++;
if(xorriso->pacifier_count%100 && !(flag&2)) if(xorriso->pacifier_count%100 && !(flag&2))
Xorriso_pacifier_callback(xorriso, "files restored", Xorriso_pacifier_callback(xorriso, "files restored",