From 3b05800e084c0f6d33e4115aa8254a7f67079c32 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Tue, 11 Aug 2009 19:55:08 +0000 Subject: [PATCH] New options -check_md5, -check_md5_r, find action check_md5, test -has_md5 --- xorriso/xorriso.c | 758 +++++++------------------------------- xorriso/xorriso.h | 9 + xorriso/xorriso_private.h | 3 + xorriso/xorrisoburn.c | 249 ++++++------- xorriso/xorrisoburn.h | 3 + 5 files changed, 269 insertions(+), 753 deletions(-) diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 1f0742f9..ad6baef7 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -2459,9 +2459,6 @@ int Linkitem_find(struct LinkiteM *stack, dev_t target_dev, ino_t target_ino, } -#ifdef Xorriso_findjob_on_expR - - /* ----------------------- Exprtest ----------------------- */ @@ -3601,585 +3598,6 @@ int Findjob_set_action_found_path(struct FindjoB *o, int flag) } -#else /* Xorriso_findjob_on_expR */ - - -/* ------------------------------- FindjoB -------------------------------- */ - - -struct FindjoB { - char *start_path; - - char *name_expr; - regex_t name_re; - regmatch_t name_match; - - /* b = blockdev - c = chardev - d = directory - p = fifo - f = reg - - = reg - s = socket - m = subordinate mountpoint (does never match find start directory) - X = other - 0x0 = test inactive - */ - char file_type; - - int start_lba; - int end_lba; - int damage_filter; /* -1=only undamaged , 0=all , 1=only damaged */ - int commit_filter; /* bit0= test -pending_data : uncommitted regular files */ - int acl_filter; /* -1=only without ACL , 0=all , 1=only with ACL */ - int xattr_filter; /* -1=only without xattr , 0=all , 1=only with xattr */ - int aaip_filter; /* -1=only without AA string , 0=all , 1=only with AA */ - int filter_filter; /* -1=only unfiltered nodes , 0=all , 1=only filtered */ - - void *wanted_node; /* if not NULL, then only this node address matches */ - - /* 0= echo - 1= rm (also rmdir) - 2= rm_r ->>> 3= mv target - 4= chown user - 5= chgrp group - 6= chmod mode_and mode_or - 7= alter_date type date - 8= lsdl - 9= chown_r user - 10= chgrp_r group - 11= chmod_r mode_and mode_or - 12= alter_date_r type date - 13= find - 14= compare disk_equivalent_of_start_path - 15= in_iso iso_rr_equivalent_of_start_path - 16= not_in_iso iso_rr_equiv - 17= update disk_equiv - 18= add_missing iso_rr_equiv - 19= empty_iso_dir iso_rr_equiv - 20= is_full_in_iso iso_rr_equiv - 21= report_damage - 22= report_lba - 23= internal:memorize path of last matching node in found_path - 24= getfacl - 25= setfacl access_acl default_acl - 26= getfattr - 27= setfattr - 28= set_filter name - 29= show_stream - */ - int action; - - /* action specific parameters */ - char *target; - char *text_2; - uid_t user; - gid_t group; - mode_t mode_and, mode_or; - int type; /* see Xorriso_set_time flag */ - time_t date; - char *found_path; - struct FindjoB *subjob; -}; - - -int Findjob_new(struct FindjoB **o, char *start_path, int flag) -{ - struct FindjoB *m; - - m= *o= TSOB_FELD(struct FindjoB,1); - if(m==NULL) - return(-1); - m->start_path= NULL; - m->name_expr= NULL; - m->file_type= 0; - m->start_lba= 0; - m->end_lba= 0; - m->damage_filter= 0; - m->commit_filter= 0; - m->acl_filter= 0; - m->xattr_filter= 0; - m->aaip_filter= 0; - m->filter_filter= 0; - m->wanted_node= NULL; - m->action= 0; /* print */ - m->target= NULL; /* a mere pointer, not managed memory */ - m->text_2= NULL; /* a mere pointer, not managed memory */ - m->user= 0; - m->group= 0; - m->type= 0; - m->date= 0; - m->start_path= strdup(start_path); - if(m->start_path==NULL) - goto failed; - m->found_path= NULL; - m->subjob= NULL; - return(1); -failed:; - Findjob_destroy(o, 0); - return(-1); -} - - -int Findjob_destroy(struct FindjoB **o, int flag) -{ - struct FindjoB *m; - - m= *o; - if(m==NULL) - return(0); - if(m->start_path!=NULL) - free(m->start_path); - if(m->name_expr!=NULL) { - regfree(&(m->name_re)); - free(m->name_expr); - } - Findjob_destroy(&(m->subjob), 0); - free((char *) m); - *o= NULL; - return(1); -} - - -int Findjob_set_start_path(struct FindjoB *o, char *start_path, int flag) -{ - if(o->start_path!=NULL) - free(o->start_path); - if(start_path!=NULL) { - o->start_path= strdup(start_path); - if(o->start_path==NULL) - return(-1); - } else - o->start_path= NULL; - return(1); -} - - -int Findjob_get_start_path(struct FindjoB *o, char **start_path, int flag) -{ - *start_path= o->start_path; - return(1); -} - - -int Findjob_set_name_expr(struct FindjoB *o, char *name_expr, int flag) -{ - char regexpr[2*SfileadrL+2]; - - if(o->name_expr!=NULL) { - regfree(&(o->name_re)); - free(o->name_expr); - o->name_expr= NULL; - } - if(strlen(name_expr)>=SfileadrL) - return(0); - o->name_expr= strdup(name_expr); - if(o->name_expr==NULL) - return(-1); - Xorriso__bourne_to_reg(name_expr, regexpr, 0); - if(regcomp(&(o->name_re), regexpr, 0)!=0) - return(0); - return(1); -} - - -int Findjob_set_file_type(struct FindjoB *o, char file_type, int flag) -{ - static char known[]= {"bcdpf-lsmeX"}; - - if(file_type!=0) - if(strchr(known, file_type)==NULL) - return(0); - o->file_type= file_type; - return(1); -} - - -int Findjob_set_lba_range(struct FindjoB *o, int start_lba, int count, - int flag) -{ - o->start_lba= start_lba; - if(start_lba > 0) - o->end_lba= start_lba + count - 1; - else - o->end_lba= start_lba - count + 1; - return(1); -} - - -/* @param value -1= only undamaged files, 0= all files, 1= only damaged files -*/ -int Findjob_set_damage_filter(struct FindjoB *o, int value, int flag) -{ - if(value < 0) - o->damage_filter= -1; - else if(value > 0) - o->damage_filter= 1; - else - o->damage_filter= 0; - return(1); -} - - -int Findjob_get_lba_damage_filter(struct FindjoB *o, int *start_lba, - int *end_lba, int *damage_filter, int flag) -{ - *start_lba= o->start_lba; - *end_lba= o->end_lba; - *damage_filter= o->damage_filter; - return(1); -} - - -int Findjob_set_commit_filter(struct FindjoB *o, int mask, int values, - int flag) -{ - o->commit_filter&= ~mask; - o->commit_filter|= (mask & values); - return(1); -} - - -int Findjob_get_commit_filter(struct FindjoB *o, int *commit_filter, int flag) -{ - *commit_filter= o->commit_filter; - return(1); -} - - -/* @param value -1= files without ACL, 0= all files, 1= only files with ACL -*/ -int Findjob_set_acl_filter(struct FindjoB *o, int value, int flag) -{ - if(value < 0) - o->acl_filter= -1; - else if(value > 0) - o->acl_filter= 1; - else - o->acl_filter= 0; - return(1); -} - - -/* @param value -1= files without xattr, 0= all files, 1= only files with xattr -*/ -int Findjob_set_xattr_filter(struct FindjoB *o, int value, int flag) -{ - if(value < 0) - o->xattr_filter= -1; - else if(value > 0) - o->xattr_filter= 1; - else - o->xattr_filter= 0; - return(1); -} - - -/* @param value -1= files without aaip, 0= all files, 1= only files with aaip -*/ -int Findjob_set_aaip_filter(struct FindjoB *o, int value, int flag) -{ - if(value < 0) - o->aaip_filter= -1; - else if(value > 0) - o->aaip_filter= 1; - else - o->aaip_filter= 0; - return(1); -} - - -int Findjob_get_acl_filter(struct FindjoB *o, int *acl_filter, int flag) -{ - *acl_filter= o->acl_filter; - return(1); -} - - -int Findjob_get_xattr_filter(struct FindjoB *o, int *xattr_filter, int flag) -{ - *xattr_filter= o->xattr_filter; - return(1); -} - - -int Findjob_get_aaip_filter(struct FindjoB *o, int *aaip_filter, int flag) -{ - *aaip_filter= o->aaip_filter; - return(1); -} - - -/* @param value -1= files without filter, 0= all files, 1= files with filter -*/ -int Findjob_set_filter_filter(struct FindjoB *o, int value, int flag) -{ - if(value < 0) - o->filter_filter= -1; - else if(value > 0) - o->filter_filter= 1; - else - o->filter_filter= 0; - return(1); -} - - -int Findjob_get_filter_filter(struct FindjoB *o, int *value, int flag) -{ - *value= o->filter_filter; - return(1); -} - - -int Findjob_set_wanted_node(struct FindjoB *o, void *wanted_node, int flag) -{ - o->wanted_node= wanted_node; - return(1); -} - - -int Findjob_get_wanted_node(struct FindjoB *o, void **wanted_node, int flag) -{ - *wanted_node= o->wanted_node; - return(1); -} - - -int Findjob_set_found_path(struct FindjoB *o, char *path, int flag) -{ - if(o->found_path != NULL) - free(o->found_path); - if(path != NULL) { - o->found_path= strdup(path); - if(o->found_path == NULL) - return(-1); - } else - o->found_path= NULL; - return(1); -} - - -int Findjob_get_found_path(struct FindjoB *o, char **path, int flag) -{ - *path= o->found_path; - return(1); -} - - -/* @flag bit0=recognize type "e" = El-Torito - @return 0=no match , 1=match , <0 = error -*/ -int Findjob_test(struct FindjoB *o, char *name, - struct stat *boss_stbuf, struct stat *stbuf, - int depth, int flag) -{ - int ret; - - if(o->name_expr!=NULL) { - ret= regexec(&(o->name_re),name,1,&(o->name_match),0); - if(ret!=0) - return(0); - } - - if(o->file_type!=0) { - if(S_ISBLK(stbuf->st_mode)) { - if(o->file_type!='b') - return(0); - } else if(S_ISCHR(stbuf->st_mode)) { - if(o->file_type!='c') - return(0); - } else if(S_ISDIR(stbuf->st_mode)) { - if(o->file_type=='m') { - if(boss_stbuf==NULL) - return(0); - if(boss_stbuf->st_dev == stbuf->st_dev) - return(0); - } else if(o->file_type!='d') - return(0); - } else if(S_ISFIFO(stbuf->st_mode)) { - if(o->file_type!='p') - return(0); - } else if(S_ISREG(stbuf->st_mode)) { - if(o->file_type!='f' && o->file_type!='-') - return(0); - } else if(((stbuf->st_mode)&S_IFMT)==S_IFLNK) { - if(o->file_type!='l') - return(0); - } else if(((stbuf->st_mode)&S_IFMT)==S_IFSOCK) { - if(o->file_type!='s') - return(0); - } else if((flag & 1) && ((stbuf->st_mode) & S_IFMT) == Xorriso_IFBOOT) { - if(o->file_type!='e') - return(0); - } else { - if(o->file_type!='X') - return(0); - } - } - - /* ??? >>> more tests to come ?*/; - - return(1); -} - - -int Findjob_get_action(struct FindjoB *o, int flag) -{ - return(o->action); -} - - -/* @return <0 error, >=0 see above struct FindjoB.action -*/ -int Findjob_get_action_parms(struct FindjoB *o, char **target, char **text_2, - uid_t *user, gid_t *group, - mode_t *mode_and, mode_t *mode_or, - int *type, time_t *date, struct FindjoB **subjob, - int flag) -{ - *target= o->target; - *text_2= o->text_2; - *user= o->user; - *group= o->group; - *mode_and= o->mode_and; - *mode_or= o->mode_or; - *type= o->type; - *date= o->date; - *subjob= o->subjob; - return(o->action); -} - - -int Findjob_set_action_target(struct FindjoB *o, int action, char *target, - int flag) -{ - o->action= action; - o->target= target; - return(1); -} - - -int Findjob_set_action_text_2(struct FindjoB *o, int action, char *target, - char* text_2, int flag) -{ - o->action= action; - o->target= target; - o->text_2= text_2; - return(1); -} - - -/* @param flag bit0= recursive -*/ -int Findjob_set_action_chown(struct FindjoB *o, uid_t user,int flag) -{ - int ret; - - if(flag&1) { - o->action= 0; - Findjob_destroy(&(o->subjob), 0); - ret= Findjob_new(&(o->subjob), "", 0); - if(ret<=0) - return(-1); - Findjob_set_action_chown(o->subjob, user, 0); - o->action= 9; - } else { - o->action= 4; - o->user= user; - } - return(1); -} - - -/* @param flag bit0= recursive -*/ -int Findjob_set_action_chgrp(struct FindjoB *o, gid_t group, int flag) -{ - int ret; - - if(flag&1) { - o->action= 0; - Findjob_destroy(&(o->subjob), 0); - ret= Findjob_new(&(o->subjob), "", 0); - if(ret<=0) - return(-1); - Findjob_set_action_chgrp(o->subjob, group, 0); - o->action= 10; - } else { - o->action= 5; - o->group= group; - } - return(1); -} - - -/* @param flag bit0= recursive -*/ -int Findjob_set_action_chmod(struct FindjoB *o, - mode_t mode_and, mode_t mode_or, int flag) -{ - int ret; - - if(flag&1) { - o->action= 0; - Findjob_destroy(&(o->subjob), 0); - ret= Findjob_new(&(o->subjob), "", 0); - if(ret<=0) - return(-1); - Findjob_set_action_chmod(o->subjob, mode_and, mode_or, 0); - o->action= 11; - } else { - o->action= 6; - o->mode_and= mode_and; - o->mode_or= mode_or; - } - return(1); -} - - -/* @param flag bit0= recursive -*/ -int Findjob_set_action_ad(struct FindjoB *o, int type, time_t date, int flag) -{ - int ret; - - if(flag&1) { - o->action= 0; - Findjob_destroy(&(o->subjob), 0); - ret= Findjob_new(&(o->subjob), "", 0); - if(ret<=0) - return(-1); - Findjob_set_action_ad(o->subjob, type, date, 0); - o->action= 12; - } else { - o->action= 7; - o->type= type; - o->date= date; - } - return(1); -} - - -int Findjob_set_action_subjob(struct FindjoB *o, int action, - struct FindjoB *subjob, int flag) -{ - o->action= action; - Findjob_destroy(&(o->subjob), 0); - o->subjob= subjob; - return(1); -} - - -int Findjob_set_action_found_path(struct FindjoB *o, int flag) -{ - o->action= 23; - Findjob_set_found_path(o, NULL, 0); - return(1); -} - -#endif /* ! Xorriso_findjob_on_expR */ - /* ---------------------------- SplitparT ------------------------- */ @@ -5411,6 +4829,7 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) m->start_time= 0.0; m->last_update_time= 0.0; m->find_compare_result= 1; + m->find_check_md5_result= 1; m->node_counter= 0; m->node_array_size= 0; @@ -8913,6 +8332,7 @@ int Xorriso_end_idx(struct XorrisO *xorriso, bit4= ignore last argument bit5= demand exactly one match bit6= with bit5 allow 0 matches if pattern is a constant + bit7= silently tolerate empty argument list bit8= free the eventually allocated sub_vector */ int Xorriso_opt_args(struct XorrisO *xorriso, char *cmd, @@ -8937,7 +8357,8 @@ int Xorriso_opt_args(struct XorrisO *xorriso, char *cmd, *optc= 0; *optv= NULL; sprintf(xorriso->info_text, "%s : Not enough arguments given", cmd); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + if(!(flag & 128)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); return(0); } *end_idx= Xorriso_end_idx(xorriso, argc, argv, idx, @@ -10472,19 +9893,8 @@ int Xorriso_findx(struct XorrisO *xorriso, struct FindjoB *job, else namept++; - -#ifdef Xorriso_findjob_on_expR - ret= Findjob_test_2(xorriso, job, NULL, namept, dir_path, NULL, dir_stbuf, 0); - -#else /* Xorriso_findjob_on_expR */ - - ret= Findjob_test(job, namept, NULL, dir_stbuf, depth, 0); - -#endif /* ! Xorriso_findjob_on_expR */ - - if(ret<0) goto ex; if(ret>0) { @@ -10547,16 +9957,7 @@ int Xorriso_findx(struct XorrisO *xorriso, struct FindjoB *job, no_dive= 1; } -#ifdef Xorriso_findjob_on_expR - ret= Findjob_test_2(xorriso, job, NULL, name, path, dir_stbuf, &stbuf, 0); - -#else /* Xorriso_findjob_on_expR */ - - ret= Findjob_test(job, name, dir_stbuf, &stbuf, depth, 0); - -#endif /* ! Xorriso_findjob_on_expR */ - if(ret<0) goto ex; if(ret>0) { @@ -13900,6 +13301,119 @@ int Xorriso_option_charset(struct XorrisO *xorriso, char *name, int flag) } +/* Options -check_md5 and -check_md5_r + @param flag bit0= issue summary message + bit1= do not reset pacifier, no final pacifier message + bit2= do not issue pacifier messages at all + bit3= recursive: -check_md5_r +*/ +int Xorriso_option_check_md5(struct XorrisO *xorriso, + int argc, char **argv, int *idx, int flag) +{ + int ret, i, mem_pci, end_idx, fret, sev; + int optc= 0; + char **optv= NULL, *cpt, *severity; + struct FindjoB *job= NULL; + double mem_lut= 0.0; + + if(!(flag&2)) { + Xorriso_pacifier_reset(xorriso, 0); + mem_lut= xorriso->last_update_time; + } + mem_pci= xorriso->pacifier_interval; + xorriso->pacifier_interval= 5.0; + + /* Interpret argv[*idx] as severity */ + if(argc <= *idx) { + sprintf(xorriso->info_text, + "-check_md5: No event severity given for case of mismatch"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + severity= argv[*idx]; + ret= Xorriso__text_to_sev(severity, &sev, 0); + if(ret<=0) { + sprintf(xorriso->info_text, "-check_md5: Not a known severity name : "); + Text_shellsafe(severity, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(ret); + } + + ret= Xorriso_opt_args(xorriso, "-check_md5", argc, argv, (*idx) + 1, + &end_idx, &optc, &optv, 128); + if(ret<=0) + goto ex; + + if(optc == 0) { + + /* >>> check whole session */; + ret= 1; + + return(ret); + } + + xorriso->find_check_md5_result= 1; + for(i= 0; i < optc; i++) { + if(flag & 8) { + ret= Findjob_new(&job, optv[i], 0); + if(ret<=0) { + Xorriso_no_findjob(xorriso, "-check_md5_r", 0); + {ret= -1; goto ex;} + } + Findjob_set_action_target(job, 35, NULL, 0); + cpt= optv[i]; + ret= Xorriso_findi_sorted(xorriso, job, (off_t) 0, 1, &cpt, 0); + Findjob_destroy(&job, 0); + if(ret > 0) + ret= xorriso->find_compare_result; + else { + ret= -1; + xorriso->find_check_md5_result= -1; + } + } else { + ret= Xorriso_check_md5(xorriso, NULL, optv[i], 4); + if(ret < xorriso->find_check_md5_result) + xorriso->find_check_md5_result= ret; + } + if(ret>0 && !xorriso->request_to_abort) + continue; /* regular bottom of loop */ + fret= Xorriso_eval_problem_status(xorriso, ret, 1|2); + if(fret>=0) + continue; + ret= 0; goto report_outcome; + } + ret= 1; + + xorriso->pacifier_interval= mem_pci; + if(mem_lut!=xorriso->last_update_time && !(flag&2)) + Xorriso_pacifier_callback(xorriso, "content bytes read", + xorriso->pacifier_count, 0, "", 1); +report_outcome:; + if(xorriso->find_check_md5_result > 0) { + sprintf(xorriso->result_line, + "File contents and their MD5 checksums match.\n"); + } else if(xorriso->find_check_md5_result == 0) { + sprintf(xorriso->result_line, + "Differences detected between file contents and MD5 checksums.\n"); + } else { + sprintf(xorriso->result_line, "MD5 checking failed due to error.\n"); + } + Xorriso_result(xorriso,0); + if(xorriso->find_check_md5_result <= 0 && strcmp(severity, "ALL") != 0) { + sprintf(xorriso->info_text, "Event triggered by MD5 comparison mismatch"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, severity, 0); + } +ex:; + (*idx)= end_idx; + Xorriso_opt_args(xorriso, "-getfacl", argc, argv, *idx, &end_idx, + &optc, &optv, 256); + Findjob_destroy(&job, 0); + if(ret <= 0) + return(ret); + return(xorriso->find_check_md5_result > 0); +} + + /* Option -check_media */ int Xorriso_option_check_media(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag) @@ -15234,17 +14748,7 @@ not_enough_arguments:; sscanf(argv[i], "%d", &count); Findjob_set_lba_range(job, start_lba, count, 0); } else if(strcmp(argv[i], "-pending_data")==0) { - -#ifdef Xorriso_findjob_on_expR - Findjob_set_commit_filter_2(job, 0); - -#else /* Xorriso_findjob_on_expR */ - - Findjob_set_commit_filter(job, 1, 1, 0); - -#endif /* ! Xorriso_findjob_on_expR */ - } else if(strcmp(argv[i], "-has_acl")==0) { Findjob_set_acl_filter(job, 1, 0); } else if(strcmp(argv[i], "-has_no_acl")==0) { @@ -15263,9 +14767,8 @@ not_enough_arguments:; Findjob_set_filter_filter(job, 1, 0); } else if(strcmp(argv[i], "-has_no_filter")==0) { Findjob_set_filter_filter(job, -1, 0); - -#ifdef Xorriso_findjob_on_expR - + } else if(strcmp(argv[i], "-has_md5")==0) { + Findjob_set_prop_filter(job, 15, 1, 0); } else if(strcmp(argv[i], "-true") == 0) { ret= Findjob_set_false(job, -1, 0); } else if(strcmp(argv[i], "-false") == 0) { @@ -15297,9 +14800,6 @@ not_enough_arguments:; ret= Findjob_elseif(job, 0); } else if(strcmp(argv[i], "-endif") == 0) { ret= Findjob_endif(job, 0); - -#endif /* Xorriso_findjob_on_expR */ - } else if(strcmp(argv[i], "-sort_lba") == 0) { flag|= 8; /* If an operator is open: insert a -true test, else do nothing */ @@ -15997,15 +15497,15 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " the ISO image. Tests:", " -name pattern, -wholename pattern, -type b|c|d|p|f|l|s|e,", " -pending_data, -lba_range start count, -damaged,", -" -has_acl, -has_xattr, -has_aaip, -has_filter,", -" -prune, -decision yes|no, -true, -false", +" -has_acl, -has_xattr, -has_aaip, -has_filter, -has_md5", +" -has_any_xattr, -prune, -decision yes|no, -true, -false", " Operators: -not, -or, -and, -sub, (, -subend, ),", " -if, -then, -elseif, -else, -endif", " Action may be one of: echo, chown, chown_r, chgrp, chgrp_r", -" chmod, chmod_r, alter_date, alter_date_r, lsdl, compare,", -" rm, rm_r, compare, update, report_damage, report_lba,", -" getfacl, setfacl, getfattr, setfattr, set_filter,", -" show_stream, find.", +" chmod, chmod_r, alter_date, alter_date_r, lsdl, compare,", +" rm, rm_r, compare, update, report_damage, report_lba,", +" getfacl, setfacl, getfattr, setfattr, get_any_xattr,", +" get_md5, check_md5, set_filter, show_stream, find.", " params are their arguments except iso_rr_path.", " -mkdir iso_rr_path [...]", " Create empty directories if they do not exist yet.", @@ -19066,7 +18566,7 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv, }; static char argn_commands[][40]= { "add","alter_date","alter_date_r","as", - "check_media","check_media_defaults", + "check_md5","check_md5_r","check_media","check_media_defaults", "chgrp","chgrpi","chgrp_r","chgrp_ri","chmod","chmodi", "chmod_r","chmod_ri","chown","chowni","chown_r","chown_ri", "compare_l","cpr","cpri","cp_rax","cp_rx","cpax","cpx", @@ -19263,6 +18763,12 @@ next_command:; (*idx)++; ret= Xorriso_option_charset(xorriso, arg1, 3); + } else if(strcmp(cmd,"check_md5")==0) { + ret= Xorriso_option_check_md5(xorriso, argc, argv, idx, 0); + + } else if(strcmp(cmd,"check_md5_r")==0) { + ret= Xorriso_option_check_md5(xorriso, argc, argv, idx, 8); + } else if(strcmp(cmd,"check_media")==0) { ret= Xorriso_option_check_media(xorriso, argc, argv, idx, 0); diff --git a/xorriso/xorriso.h b/xorriso/xorriso.h index 7ab14df8..8f061bd4 100644 --- a/xorriso/xorriso.h +++ b/xorriso/xorriso.h @@ -497,6 +497,15 @@ int Xorriso_option_cdx(struct XorrisO *xorriso, char *disk_path, int flag); */ int Xorriso_option_charset(struct XorrisO *xorriso, char *name, int flag); +/* Options -check_md5 and -check_md5_r + @param flag bit0= issue summary message + bit1= do not reset pacifier, no final pacifier message + bit2= do not issue pacifier messages at all + bit3= recursive: -check_md5_r +*/ +int Xorriso_option_check_md5(struct XorrisO *xorriso, + int argc, char **argv, int *idx, int flag); + /* Option -check_media */ int Xorriso_option_check_media(struct XorrisO *xorriso, int argc, char **argv, int *idx, int flag); diff --git a/xorriso/xorriso_private.h b/xorriso/xorriso_private.h index 55fdfeca..468aa3fb 100644 --- a/xorriso/xorriso_private.h +++ b/xorriso/xorriso_private.h @@ -395,6 +395,7 @@ struct XorrisO { /* the global context of xorriso */ void *pacifier_fifo; int find_compare_result; /* 1=everything matches , 0=mismatch , -1=error */ + int find_check_md5_result; /* 1=everything matches , 0=mismatch , -1=error */ /* Tree node collection and LBA sorting facility */ int node_counter; @@ -841,6 +842,7 @@ struct ExprtesT { 12= -prune 13= -wholename char *arg1 (regex_t in *arg2) 14= -has_any_xattr + 15= -has_md5 */ int test_type; @@ -944,6 +946,7 @@ struct FindjoB { 32= internal: widen_hardlinks disk_equiv: update nodes marked in di_do_widen 33= get_any_xattr 34= get_md5 + 35= check_md5 */ int action; int prune; diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index 4dc34edc..eb7bbe02 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -7594,12 +7594,18 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, iso_prefix, target, 0); if(ret==2) deleted= 1; - } else if(action == 33) { + } else if(action == 33) { /* get_any_xattr */ ret= Xorriso_getfattr(xorriso, (void *) node, show_path, NULL, 8); - } else if(action == 34) { + } else if(action == 34) { /* get_md5 */ ret= Xorriso_get_md5(xorriso, (void *) node, show_path, md5, 0); if(ret >= 0) ret= 1; + } else if(action == 35) { /* check_md5 */ + ret= Xorriso_check_md5(xorriso, (void *) node, show_path, 2); + if(ret < xorriso->find_check_md5_result) + xorriso->find_check_md5_result= ret; + if(ret >= 0) + ret= 1; } else { /* includes : 15 in_iso */ sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0)); Xorriso_result(xorriso, 0); @@ -7615,8 +7621,6 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, } -#ifdef Xorriso_findjob_on_expR - int Exprtest_match(struct XorrisO *xorriso, struct ExprtesT *ftest, void *node_pt, char *name, char *path, struct stat *boss_stbuf, struct stat *stbuf, int flag) @@ -7632,7 +7636,7 @@ return: int value=0, ret, start_lba, end_lba; int lba_count, *file_end_lbas= NULL, *file_start_lbas= NULL, i; void *arg1, *arg2; - char ft, *decision; + char ft, *decision, md5[16]; regmatch_t name_match; off_t damage_start, damage_end, size; void *xinfo_dummy; @@ -7799,6 +7803,10 @@ return: ret= regexec(arg2, path, 1, &name_match, 0); value= !ret; + break; case 15: /* -has_md5 */ + ret= Xorriso_get_md5(xorriso, node, path, md5, 1); + value= (ret > 0); + break; default: /* >>> complain about unknown test type */; @@ -7833,126 +7841,6 @@ int Xorriso_findi_test(struct XorrisO *xorriso, struct FindjoB *job, return(1); } -#else /* Xorriso_findjob_on_expR */ - -int Xorriso_findi_test(struct XorrisO *xorriso, struct FindjoB *job, - IsoNode *node, char *name, char *path, - struct stat *boss_stbuf, struct stat *stbuf, - int depth, int flag) -{ - int ret, start_lba, end_lba, damage_filter, commit_filter, lba, a_filter; - int is_filtered= 0; - off_t damage_start, damage_end, size; - int lba_count, *file_end_lbas= NULL, *file_start_lbas= NULL, i; - void *wanted_node; - IsoStream *stream; - - ret= Findjob_test(job, name, boss_stbuf, stbuf, depth, 1); - if(ret<=0) - return(ret); - - Findjob_get_lba_damage_filter(job, &start_lba, &end_lba, &damage_filter, 0); - if(damage_filter != 0) { - ret= Xorriso_file_eval_damage(xorriso, node, &damage_start, &damage_end, 0); - if(ret < 0) - return(ret); - if((damage_filter > 0) != (ret > 0)) - return(0); - } - if(start_lba != 0) { - ret= Xorriso__start_end_lbas(node, &lba_count, - &file_start_lbas, &file_end_lbas, &size, 0); - if(ret <= 0) { - Xorriso_process_msg_queues(xorriso, 0); - if(start_lba > 0) - goto ex; - } else { - for(i= 0; i < lba_count; i++) { - if(start_lba > 0) { - if(file_end_lbas[i] < start_lba || file_start_lbas[i] > end_lba) - {ret= 0; goto ex;} - } else { - if(file_end_lbas[i] >= -start_lba && file_start_lbas[i] <= -end_lba) - {ret= 0; goto ex;} - } - } - } - } - Findjob_get_commit_filter(job, &commit_filter, 0); - if(commit_filter & 1) { /* -pending_data */ - if(!LIBISO_ISREG(node)) - {ret= 0; goto ex;} - ret= Xorriso__file_start_lba(node, &lba, 0); - if(ret > 0 && lba >= 0) - {ret= 0; goto ex;} - } - Findjob_get_acl_filter(job, &a_filter, 0); - if(a_filter) { - ret = Xorriso_getfacl(xorriso, (void *) node, "", NULL, 2); - if(ret <= 0) { - Xorriso_process_msg_queues(xorriso, 0); - goto ex; - } - if(a_filter < 0 && ret != 2) - {ret= 0; goto ex;} - if(a_filter > 0 && ret == 2) - {ret= 0; goto ex;} - } - Findjob_get_xattr_filter(job, &a_filter, 0); - if(a_filter) { - ret = Xorriso_getfattr(xorriso, (void *) node, "", NULL, 64); - if(ret < 0) { - Xorriso_process_msg_queues(xorriso, 0); - goto ex; - } - if(a_filter < 0 && ret > 0) - {ret= 0; goto ex;} - if(a_filter > 0 && ret == 0) - {ret= 0; goto ex;} - } - Findjob_get_aaip_filter(job, &a_filter, 0); - if(a_filter) { - { void *xinfo_dummy; - ret= iso_node_get_xinfo(node, aaip_xinfo_func, &xinfo_dummy); - } - if(ret < 0) { - Xorriso_process_msg_queues(xorriso, 0); - goto ex; - } - if(a_filter < 0 && ret == 1) - {ret= 0; goto ex;} - if(a_filter > 0 && ret != 1) - {ret= 0; goto ex;} - } - - Findjob_get_filter_filter(job, &a_filter, 0); - if(a_filter) { - is_filtered= 0; - if(LIBISO_ISREG(node)) { - stream= iso_file_get_stream((IsoFile *) node); - if(iso_stream_get_input_stream(stream, 0) != NULL) - is_filtered= 1;; - } - if(a_filter < 0 && is_filtered) - {ret= 0; goto ex;} - if(a_filter > 0 && !is_filtered) - {ret= 0; goto ex;} - } - - Findjob_get_wanted_node(job, &wanted_node, 0); - if(wanted_node != NULL && ((IsoNode *) wanted_node) != node) - {ret= 0; goto ex;} - ret= 1; -ex:; - if(file_start_lbas != NULL) - free((char *) file_start_lbas); - if(file_end_lbas != NULL) - free((char *) file_end_lbas); - return(ret); -} - -#endif /* ! Xorriso_findjob_on_expR */ - /* @param flag bit0= recursion bit1= do not count deleted files with rm and rm_r @@ -12160,7 +12048,7 @@ ex:; /* @param flag bit0= do not report to result but only retrieve md5 text - bit6= check for existence of md5, return 0 or 1 + @return 1= ok, 0= no md5 available, <0= other error */ int Xorriso_get_md5(struct XorrisO *xorriso, void *in_node, char *path, char md5[16], int flag) @@ -12185,7 +12073,6 @@ int Xorriso_get_md5(struct XorrisO *xorriso, void *in_node, char *path, Xorriso_process_msg_queues(xorriso,0); if(ret <= 0) goto ex; - if(flag & 1) {ret= 1; goto ex;} @@ -12203,3 +12090,111 @@ ex:; } +/* @param node Opaque handle to IsoNode which is to be inquired instead of path if it is not NULL. + @param path is used as address if node is NULL. + @param flag bit0= do not report to result but only indicate outcome + by return value + bit1= silently ignore nodes without MD5 + bit2= do not only report mismatches but also matches + @return 2= no MD5 attached to node + 1= ok, MD5 compared and matching + 0= not ok, MD5 mismatch + <0= other error +*/ +int Xorriso_check_md5(struct XorrisO *xorriso, void *in_node, char *path, + int flag) +{ + int i, ret, wanted, rret; + IsoImage *image; + IsoNode *node; + IsoFile *file; + char node_md5[16], data_md5[16], buffer[64 * 1024]; + void *stream= NULL, *ctx= NULL; + off_t todo; + + node= (IsoNode *) in_node; + if(node == NULL) { + ret= Xorriso_get_node_by_path(xorriso, path, NULL, &node, 0); + if(ret<=0) + goto ex; + } + if(!LIBISO_ISREG(node)) { + strcpy(xorriso->info_text, "-check_md5: Not a data file: "); + Text_shellsafe(path, xorriso->info_text, 1); + if(!(flag & 2)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + ret= 2; goto ex; + } + file= (IsoFile *) node; + + /* obtain MD5 */ + ret= Xorriso_get_volume(xorriso, &image, 0); + if(ret <= 0) + goto ex; + ret= iso_file_get_md5(image, file, node_md5, 0); + Xorriso_process_msg_queues(xorriso,0); + if(ret < 0) + {ret= -1; goto ex;} + if(ret == 0) { + strcpy(xorriso->info_text, "-check_md5: No MD5 recorded with file: "); + Text_shellsafe(path, xorriso->info_text, 1); + if(!(flag & 2)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + ret= 2; goto ex; + } + + /* Read file and compute MD5 */; + ret= Xorriso_iso_file_open(xorriso, path, (void *) node, &stream, 1); + if(ret <= 0) + {ret= -1; goto ex;} + ret= iso_md5_start(&ctx); + if(ret < 0) + goto ex; + todo= iso_file_get_size(file); + while(todo > 0) { + if(todo < sizeof(buffer)) + wanted= todo; + else + wanted= sizeof(buffer); + rret = Xorriso_iso_file_read(xorriso, stream, buffer, wanted, 0); + if(rret <= 0) + {ret= -1; goto ex;} + todo-= rret; + ret = iso_md5_compute(ctx, buffer, rret); + if(ret < 0) + goto ex; + xorriso->pacifier_count+= rret; + xorriso->pacifier_byte_count+= rret; + Xorriso_pacifier_callback(xorriso, "content bytes read", + xorriso->pacifier_count, 0, "", 0); + } + ret= iso_md5_end(&ctx, data_md5); + if(ret < 0) + goto ex; + + /* Report outcome */ + for(i= 0; i < 16; i++) + if(node_md5[i] != data_md5[i]) + break; + if(i < 16 ) { + sprintf(xorriso->result_line, "MD5 MISMATCH: "); + Text_shellsafe(path, xorriso->result_line, 1); + strcat(xorriso->result_line, "\n"); + if(!(flag & 1)) + Xorriso_result(xorriso,0); + ret= 0; + } else { + sprintf(xorriso->result_line, "md5 match : "); + Text_shellsafe(path, xorriso->result_line, 1); + strcat(xorriso->result_line, "\n"); + if(flag & 4) + Xorriso_result(xorriso,0); + ret= 1; + } + +ex:; + Xorriso_iso_file_close(xorriso, &stream, 0); + if(ctx != NULL) + iso_md5_end(&ctx, data_md5); + return(ret); +} diff --git a/xorriso/xorrisoburn.h b/xorriso/xorrisoburn.h index d94fd972..558fa232 100644 --- a/xorriso/xorrisoburn.h +++ b/xorriso/xorrisoburn.h @@ -321,6 +321,9 @@ int Xorriso_new_hln_array(struct XorrisO *xorriso, off_t mem_limit, int flag); */ int Xorriso_restore_node_array(struct XorrisO *xorriso, int flag); +int Xorriso_check_md5(struct XorrisO *xorriso, void *in_node, char *path, + int flag); + struct CheckmediajoB { int use_dev; /* 0= use indev , 1= use outdev , 2= use sector map*/