diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index 9b44b0fc..ab53f4f1 100644 --- a/xorriso/xorriso.1 +++ b/xorriso/xorriso.1 @@ -1374,6 +1374,26 @@ Show text at beginning of output line and wait for the user to hit the Enter key resp. to send a line via stdin. .TP +\fB\-errfile_log\fR mode path|channel +.br +If problem events are related to input files from the filesystem, then their +disk_paths can be logged to a file or to output channels R or I. +.br +Mode can either be "plain" or "marked". The latter causes marker lines which +give the time of log start, burn session start, burn session end, log end +or program end. In mode "plain", only the file paths are logged. +.br +If path is "-" or "-R" then the log is directed to the result channel. +Path "-I" directs it to the info message channel. Any text that does not +begin with "-" is used as path for a file to append the log lines. +.br +Problematic files can be recorded multiple times during one program run. +If the program run aborts then the list might not be complete because +some input file arguments might not have been processed at all. +.br +The errfile paths are transported as messages of very low priority "ERRFILE". +This transport becomes visible with -report_about "ALL". +.TP \fB\-end\fR .br End program immediately diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 08b24b4b..323b7d68 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -1446,6 +1446,34 @@ completed:; } +/* @param flag bit0=with year and seconds +*/ +char *Ftimetxt(time_t t, char timetext[40], int flag) +{ + char *rpt; + struct tm tms, *tmpt; + static char months[12][4]= { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + + tmpt= localtime_r(&t, &tms); + rpt= timetext; + rpt[0]= 0; + if(tmpt==0) + sprintf(rpt+strlen(rpt), "%12.f", (double) t); + else if (flag&1) + sprintf(rpt+strlen(rpt), "%2d %3s %4.4d %2.2d:%2.2d:%2.2d", + tms.tm_mday, months[tms.tm_mon], 1900+tms.tm_year, + tms.tm_hour, tms.tm_min, tms.tm_sec); + else if(time(NULL)-t < 180*86400 && time(NULL)-t >= 0) + sprintf(rpt+strlen(rpt), "%3s %2d %2.2d:%2.2d", + months[tms.tm_mon], tms.tm_mday, tms.tm_hour, tms.tm_min); + else + sprintf(rpt+strlen(rpt), "%3s %2d %4.4d", + months[tms.tm_mon], tms.tm_mday, 1900+tms.tm_year); + return(timetext); +} + + /* ------------------------------------------------------------------------ */ @@ -2719,6 +2747,8 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) Xorriso__text_to_sev(m->abort_on_text, &m->abort_on_severity, 0); m->problem_status= 0; m->problem_status_text[0]= 0; + m->errfile_log[0]= 0; + m->errfile_fp= NULL; strcpy(m->return_with_text, "SORRY"); Xorriso__text_to_sev(m->return_with_text, &m->return_with_severity, 0); m->return_with_value= 32; @@ -3798,6 +3828,11 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) Xorriso_status_result(xorriso,filter,fp,flag&2); } + is_default= (xorriso->errfile_log[0]==0); + sprintf(line,"-errfile_log %s\n",Text_shellsafe(xorriso->errfile_log,sfe,0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + is_default= (xorriso->mark_text[0]==0); sprintf(line,"-mark %s\n",Text_shellsafe(xorriso->mark_text,sfe,0)); if(!(is_default && no_defaults)) @@ -4889,10 +4924,12 @@ int Xorriso_get_problem_status(struct XorrisO *xorriso, char severity[80], int Xorriso_set_problem_status(struct XorrisO *xorriso, char *severity, int flag) { - char *sev_text= "FATAL"; + char *sev_text= "ALL"; int sev, ret; - ret= Xorriso__text_to_sev(severity, &sev, 0); + if(severity[0]) + sev_text= severity; + ret= Xorriso__text_to_sev(sev_text, &sev, 0); if(ret<=0) return(0); xorriso->problem_status= sev; @@ -4905,6 +4942,57 @@ int Xorriso_set_problem_status(struct XorrisO *xorriso, char *severity, } +/* @param flag bit0-7= purpose + 0= ERRFILE + 1= mark line (only to be put out if enabled) +*/ +int Xorriso_process_errfile(struct XorrisO *xorriso, + int error_code, char msg_text[], int os_errno, + int flag) +{ + char ttx[41]; + int purpose; + + if(strlen(msg_text)>SfileadrL) + return(-1); + + purpose= flag&255; + if(purpose==1 && !(xorriso->errfile_mode&1)) + return(2); + if(xorriso->errfile_fp!=NULL) { + if(purpose==1) + fprintf(xorriso->errfile_fp, "----------------- %s %s\n", + msg_text, Ftimetxt(time(0), ttx, 1)); + else + fprintf(xorriso->errfile_fp, "%s\n", msg_text); + fflush(xorriso->errfile_fp); + return(1); + } + if(xorriso->errfile_log[0]==0) + return(1); + if(strcmp(xorriso->errfile_log, "-")==0 || + strcmp(xorriso->errfile_log, "-R")==0) { + if(purpose==1) + sprintf(xorriso->result_line, "----------------- %s %s\n", + msg_text, Ftimetxt(time(0), ttx, 1)); + else + sprintf(xorriso->result_line, "%s\n", msg_text); + Xorriso_result(xorriso, 1); + return(1); + } + if(strcmp(xorriso->errfile_log, "-I")==0) { + if(purpose==1) + sprintf(xorriso->info_text, "ERRFILE_MARK=%s %s\n", + msg_text, Ftimetxt(time(0), ttx, 1)); + else + sprintf(xorriso->info_text, "ERRFILE=%s", msg_text); + Xorriso_info(xorriso, 0); + return(1); + } + return(2); +} + + /* Note: It is ok to submit xorriso->info_text as msg_text here. */ /* flag: bit0= for Xorriso_info() : use pager (as with result) @@ -4926,6 +5014,9 @@ int Xorriso_msgs_submit(struct XorrisO *xorriso, "xorriso : ", "libisofs: ", "libburn : ", "libisoburn: ", "", "", "", "", "", "", "", "", "", "", "", "" }; + if(strcmp(severity, "ERRFILE")==0) + Xorriso_process_errfile(xorriso, error_code, msg_text, os_errno, 0); + /* Set problem status */ ret= Xorriso__text_to_sev(severity, &sev, 0); if(ret<=0) @@ -5589,10 +5680,13 @@ int Xorriso_format_ls_l(struct XorrisO *xorriso, struct stat *stbuf, int flag) { char *rpt, perms[10]; mode_t st_mode; + +#ifdef NIX time_t mtime; struct tm tms, *tmpt; static char months[12][4]= { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; +#endif rpt= xorriso->result_line; rpt[0]= 0; @@ -5623,6 +5717,10 @@ 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_gid); sprintf(rpt+strlen(rpt), "%8.f ", (double) stbuf->st_size); + +#ifndef NIX + Ftimetxt(stbuf->st_mtime, rpt+strlen(rpt), 0); +#else mtime= stbuf->st_mtime; tmpt= localtime_r(&mtime, &tms); if(tmpt==0) @@ -5633,6 +5731,8 @@ int Xorriso_format_ls_l(struct XorrisO *xorriso, struct stat *stbuf, int flag) else sprintf(rpt+strlen(rpt), "%3s %2d %4.4d ", months[tms.tm_mon], tms.tm_mday, 1900+tms.tm_year); +#endif + return(1); } @@ -7402,7 +7502,9 @@ int Xorriso_option_commit(struct XorrisO *xorriso, int flag) if(ret<=0) return(2); } + Xorriso_process_errfile(xorriso, 0, "burn session start", 0, 1); ret= Xorriso_write_session(xorriso, 0); + Xorriso_process_errfile(xorriso, 0, "burn session end", 0, 1); if(ret<=0) return(ret); xorriso->volset_change_pending= 0; @@ -7734,20 +7836,47 @@ int Xorriso_option_end(struct XorrisO *xorriso, int flag) } -/* Option -iso_rr_pattern "on"|"ls"|"off" */ -int Xorriso_option_iso_rr_pattern(struct XorrisO *xorriso, char *mode,int flag) +/* Option -errfile_log marked|plain path|-|"" */ +int Xorriso_option_errfile_log(struct XorrisO *xorriso, + char *mode, char *path, int flag) { - if(strcmp(mode, "off")==0) - xorriso->do_iso_rr_pattern= 0; - else if(strcmp(mode, "on")==0) - xorriso->do_iso_rr_pattern= 1; - else if(strcmp(mode, "ls")==0) - xorriso->do_iso_rr_pattern= 2; + int ret, mode_word; + FILE *fp= NULL; + char sfe[5*SfileadrL]; + + if(path[0]==0 || path[0]=='-') { + /* ok */; + } else { + fp= fopen(path, "a"); + if(fp==0) { + sprintf(xorriso->info_text, "-errfile_log: Cannot open file %s", + Text_shellsafe(path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + } + mode_word= xorriso->errfile_mode; + if(strcmp(mode, "marked")==0) + mode_word|= 1; + else if(strcmp(mode, "plain")==0) + mode_word&= ~1; else { - sprintf(xorriso->info_text, "-iso_rr_pattern: unknown mode '%s'", mode); + sprintf(xorriso->info_text, "-errfile_log: Unknown mode %s", + Text_shellsafe(mode, sfe, 0)); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); return(0); } + + Xorriso_process_errfile(xorriso, 0, "log end", 0, 1); + if(xorriso->errfile_fp!=NULL) + fclose(xorriso->errfile_fp); + xorriso->errfile_fp= fp; + xorriso->errfile_mode= mode_word; + ret= Sfile_str(xorriso->errfile_log, path, 0); + if(ret>0) + ret= Xorriso_process_errfile(xorriso, 0, "log start", 0, 1); + if(ret<=0) + return(ret); return(1); } @@ -8343,6 +8472,24 @@ int Xorriso_option_history(struct XorrisO *xorriso, char *line, int flag) } +/* Option -iso_rr_pattern "on"|"ls"|"off" */ +int Xorriso_option_iso_rr_pattern(struct XorrisO *xorriso, char *mode,int flag) +{ + if(strcmp(mode, "off")==0) + xorriso->do_iso_rr_pattern= 0; + else if(strcmp(mode, "on")==0) + xorriso->do_iso_rr_pattern= 1; + else if(strcmp(mode, "ls")==0) + xorriso->do_iso_rr_pattern= 2; + else { + sprintf(xorriso->info_text, "-iso_rr_pattern: unknown mode '%s'", mode); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + return(1); +} + + /* Option -joliet "on"|"off" */ int Xorriso_option_joliet(struct XorrisO *xorriso, char *mode, int flag) { @@ -9619,6 +9766,10 @@ next_command:; if(end_ret!=2) {ret= 3; goto ex;} + } else if(strcmp(cmd,"errfile_log")==0) { + (*idx)+= 2; + ret= Xorriso_option_errfile_log(xorriso, arg1, arg2, 0); + } else if(strcmp(cmd,"iso_rr_pattern")==0) { (*idx)++; ret= Xorriso_option_iso_rr_pattern(xorriso, arg1, 0); @@ -10237,6 +10388,7 @@ end_sucessfully:; Xorriso_option_end(xorriso, 2); Xorriso_process_msg_queues(xorriso, 0); ret= Xorriso_make_return_value(xorriso, 0); + Xorriso_process_errfile(xorriso, 0, "xorriso end", 0, 1); Xorriso_destroy(&xorriso,1); exit(ret); } diff --git a/xorriso/xorriso_private.h b/xorriso/xorriso_private.h index 27d81f1b..e4d55ddf 100644 --- a/xorriso/xorriso_private.h +++ b/xorriso/xorriso_private.h @@ -174,6 +174,10 @@ struct XorrisO { /* the global context of xorriso */ int problem_status; /* Severity rank number. 0= no abort condition present */ char problem_status_text[20]; + char errfile_log[SfileadrL]; /* for -errfile_log */ + int errfile_mode; /* bit0= marked */ + FILE *errfile_fp; + char return_with_text[20]; int return_with_severity; int return_with_value;