Implemented option -alter_date, corrected write problem with mode and ownership

This commit is contained in:
Thomas Schmitt 2007-11-08 14:43:53 +00:00
parent cba3f85d9e
commit 0b6880e13d
5 changed files with 587 additions and 29 deletions

View File

@ -43,7 +43,7 @@ Copies files from filesystem into the ISO image.
.br
Renames or deletes file objects in the ISO image.
.br
> Changes file properties in the ISO image.
Changes file properties in the ISO image.
.br
> Can write result as completely new image to optical media or filesystem objects.
.br
@ -312,19 +312,44 @@ See also the note with option -rm.
Rename the given file objects in the ISO tree to the last
argument in the list. Use the same rules as with shell command mv.
.TP
> \fB\-chown\fR uid iso_rr_path [...]
\fB\-chown\fR uid iso_rr_path [...]
Equivalent to shell command chown in the ISO image.
.TP
> \fB\-chgrp\fR gid iso_rr_path [...]
\fB\-chgrp\fR gid iso_rr_path [...]
Equivalent to shell command chgrp in the ISO image.
.TP
> \fB\-chmod\fR mode iso_rr_path [...]
\fB\-chmod\fR mode iso_rr_path [...]
Equivalent to shell command chmod in the ISO image.
.TP
> \fB\-alter_date\fR type timestring iso_rr_path [...]
\fB\-alter_date\fR 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.
.br
timestring may be in the following formats
(see also section EXAMPLES):
.br
As expected by program date:
MMDDhhmm[[CC]YY][.ss]]
.br
As produced by program date:
[Day] MMM DD hh:mm:ss [TZON] YYYY
.br
Relative times counted from current clock time:
+|-Number["s"|"h"|"d"|"w"|"m"|"y"]
.br
where "s" means seconds, "h" hours, "d" days, "w" weeks, "m" = 30d, y=365.25d.
.br
Absolute seconds counted from Jan 1 1970:
=Number
.br
xorriso's own timestamps:
YYYY.MM.DD[.hh[mm[ss]]]
.br
scdbackup timestamps:
YYMMDD[.hhmm[ss]]
.br
where "A0" is year 2000, "B0" is 2010, etc.
.TP
\fB\-mkdir\fR iso_rr_path [...]
Create empty directories if they do not exist yet.
@ -688,9 +713,32 @@ Use text as this program's name in subsequent messages
Use text as this program's name and perform -help.
.br
.SH EXAMPLES
>>> to come
.SS
>>> more to come
.br
.SS
.B Examples of input timestrings
.br
As printed by program date:
.B 'Thu Nov 8 14:51:13 CET 2007'
.br
The same without ignored parts:
.B 'Nov 8 14:51:13 2007'
.br
The same as expected by date:
.B 110814512007.13
.br
Four weeks in the future:
.B +4w
.br
The current time:
.B +0
.br
Three hours ago:
.B \-3h
.br
Seconds since Jan 1 1970:
.B =1194531416
.br
.SH FILES
.SS

View File

@ -719,6 +719,58 @@ double Sfile_microtime(int flag)
}
int Sfile_decode_datestr(struct tm *reply, char *text, int flag)
/* YYMMDD[.hhmm[ss]] */
{
int i,l;
time_t current_time;
struct tm *now;
current_time= time(0);
now= localtime(&current_time);
for(i=0;i<sizeof(struct tm);i++)
((char *) reply)[i]= ((char *) now)[i];
if(text[0]<'0'|| (text[0]>'9' && text[0]<'A') || text[0]>'Z')
return(0);
l= strlen(text);
for(i=1;i<l;i++)
if(text[i]<'0'||text[i]>'9')
break;
if(i!=6)
return(0);
if(text[i]==0)
goto decode;
if(text[i]!='.' || (l!=11 && l!=13))
return(0);
for(i++;i<l;i++)
if(text[i]<'0'||text[i]>'9')
break;
if(i!=l)
return(0);
decode:;
reply->tm_hour= 0;
reply->tm_min= 0;
reply->tm_sec= 0;
i= 0;
if(text[0]>='A')
reply->tm_year= 100+(text[i]-'A')*10+text[1]-'0';
else
reply->tm_year= 10*(text[0]-'0')+text[1]-'0';
reply->tm_mon= 10*(text[2]-'0')+text[3]-'0'-1;
reply->tm_mday= 10*(text[4]-'0')+text[5]-'0';
if(l==6)
return(1);
reply->tm_hour= 10*(text[7]-'0')+text[8]-'0';
reply->tm_min= 10*(text[9]-'0')+text[10]-'0';
if(l==11)
return(1);
reply->tm_sec= 10*(text[11]-'0')+text[12]-'0';
return(1);
}
#endif /* Xorriso_sfile_externaL */
@ -1122,6 +1174,402 @@ double Scanf_io_size(char *text, int flag)
}
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(&current_time);
for(i=0;i<sizeof(struct tm);i++)
((char *) erg)[i]= ((char *) now)[i];
l= strlen(text);
for(i=0;i<l;i++)
if(text[i]<'0'||text[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<argc; i++) {
if(!seen_month) {
ret= Decode_date_month(argv[i], 0);
if(ret>=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_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]=='='){
if(code[1]==0)
return(0);
if(!isdigit(code[1]))
return(0);
value= -1;
if(code[0]=='=') {
seconds= 0;
sscanf(code+1,"%lf",&value);
} else {
seconds= time(0);
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;
}
return(0);
completed:;
if(!seconds_valid)
return(0);
*date= seconds;
return(1);
}
/* ------------------------------------------------------------------------ */
@ -1776,9 +2224,12 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
m->global_uid= 0;
m->volid[0]= 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->do_overwrite= 2;
m->do_reassure= 0;
m->global_gid= 0;
m->indev[0]= 0;
m->in_drive_handle= NULL;
m->in_volset_handle= NULL;
@ -3265,19 +3716,43 @@ int Xorriso_option_alter_date(struct XorrisO *xorriso,
char *time_type, char *timestring,
int argc, char **argv, int *idx, int flag)
{
int i, end_idx;
int i, end_idx, ret, was_failure= 0, t_type= 0;
time_t t;
end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 0);
fprintf(stderr, ">>> XORRISO : decode timestring %s\n", timestring);
fprintf(stderr, ">>> LIBISOFS : -alter_date %s %s ",
time_type, timestring);
for(i= *idx; i<end_idx; i++)
fprintf(stderr, "%s ", argv[i]);
fprintf(stderr, "\n");
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, "-alter_date: Unrecognized type '%s'",
time_type);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
ret= 0; goto ex;
}
ret= Decode_timestring(timestring, &t, 0);
if(ret<=0) {
sprintf(xorriso->info_text, "-alter_date: Cannot decode timestring '%s'",
timestring);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
ret= 0; goto ex;
}
for(i= *idx; i<end_idx; i++) {
ret= Xorriso_set_time(xorriso, argv[i], t, t_type);
if(ret<0)
goto ex;
if(ret==0)
was_failure= 1;
}
ret= 1;
ex:;
(*idx)= end_idx;
return(1);
if(ret<=0)
return(ret);
return(!was_failure);
}
@ -3502,7 +3977,7 @@ ex:;
int Xorriso_option_chmodi(struct XorrisO *xorriso, char *mode,
int argc, char **argv, int *idx, int flag)
{
int i, end_idx, ret, who_val= 0;
int i, end_idx, ret, who_val= 0, was_failure= 0;
unsigned int num;
mode_t mode_and= ~0, mode_or= 0, mode_val;
char sfe[4*SfileadrL], *mpt, *opt, *vpt;
@ -3589,12 +4064,17 @@ unrecognizable:;
ret= 1;
for(i= *idx; i<end_idx; i++) {
ret= Xorriso_set_st_mode(xorriso, argv[i], mode_and, mode_or, 0);
if(ret<=0)
if(ret<0)
break;
if(ret==0)
was_failure= 1;
}
ret= 1;
ex:;
(*idx)= end_idx;
if(ret<=0)
return(ret);
return(!was_failure);
}

View File

@ -1 +1 @@
#define Xorriso_timestamP "2007.11.07.225624"
#define Xorriso_timestamP "2007.11.08.144451"

View File

@ -314,11 +314,11 @@ int Xorriso_write_growing(struct XorrisO *xorriso, int flag)
sopts.copy_eltorito= 1;
sopts.no_cache_inodes= 0;
sopts.sort_files= 1;
sopts.default_mode= 0;
sopts.replace_dir_mode= 0;
sopts.dir_mode= 0555;
sopts.replace_file_mode= 0;
sopts.file_mode= 0444;
sopts.default_mode= 1;
sopts.replace_dir_mode= xorriso->do_global_mode;
sopts.dir_mode= xorriso->global_dir_mode;
sopts.replace_file_mode= xorriso->do_global_mode;
sopts.file_mode= xorriso->global_file_mode;
sopts.replace_uid= (xorriso->do_global_uid);
sopts.uid= xorriso->global_uid;
sopts.replace_gid= (xorriso->do_global_gid);
@ -879,6 +879,7 @@ handle_path_node:;
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
return(0);
}
iso_tree_node_set_ctime((struct iso_tree_node *) dir, time(NULL));
/* >>> copy properties from correspondent directory in disk_path
if there is any */;
@ -1902,7 +1903,7 @@ much_too_long:;
tmpt= localtime_r(&mtime, &tms);
if(tmpt==0)
sprintf(rpt+strlen(rpt), "%12.f ",(double) mtime);
else if(time(0)-mtime < 180*86400)
else if(time(NULL)-mtime < 180*86400 && time(NULL)-mtime >= 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
@ -2045,7 +2046,7 @@ wdi_is_not_a_dir:;
tmpt= localtime_r(&mtime, &tms);
if(tmpt==0)
sprintf(rpt+strlen(rpt), "%12.f ",(double) mtime);
else if(time(0)-mtime < 180*86400)
else if(time(NULL)-mtime < 180*86400 && time(NULL)-mtime >= 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
@ -2479,6 +2480,7 @@ int Xorriso_set_st_mode(struct XorrisO *xorriso, char *in_path,
mode= iso_tree_node_get_permissions(node);
mode= (mode & mode_and) | mode_or;
iso_tree_node_set_permissions(node, mode);
iso_tree_node_set_ctime(node, time(NULL));
sprintf(xorriso->info_text,"Permissions now: %-5.5o %s",
mode, Text_shellsafe(path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
@ -2497,6 +2499,7 @@ int Xorriso_set_uid(struct XorrisO *xorriso, char *in_path, uid_t uid,
if(ret<=0)
return(ret);
iso_tree_node_set_uid(node, uid);
iso_tree_node_set_ctime(node, time(NULL));
xorriso->volset_change_pending= 1;
return(1);
}
@ -2512,6 +2515,30 @@ int Xorriso_set_gid(struct XorrisO *xorriso, char *in_path, gid_t gid,
if(ret<=0)
return(ret);
iso_tree_node_set_gid(node, gid);
iso_tree_node_set_ctime(node, time(NULL));
xorriso->volset_change_pending= 1;
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;
struct iso_tree_node *node;
ret= Xorriso_get_node_by_path(xorriso, in_path, NULL, &node, 0);
if(ret<=0)
return(ret);
if(flag&1)
iso_tree_node_set_atime(node, t);
if(flag&2)
iso_tree_node_set_ctime(node, t);
if(flag&4)
iso_tree_node_set_mtime(node, t);
if(!(flag&(2|256)))
iso_tree_node_set_ctime(node, time(NULL));
xorriso->volset_change_pending= 1;
return(1);
}

View File

@ -104,6 +104,9 @@ int Xorriso_set_uid(struct XorrisO *xorriso, char *in_path, uid_t uid,
int Xorriso_set_gid(struct XorrisO *xorriso, char *in_path, gid_t gid,
int flag);
/* @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);
#endif /* Xorrisoburn_includeD */