From 06dfe11e36739f64620acc4f67451f5b1733c0c4 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sun, 29 Mar 2009 16:49:38 +0000 Subject: [PATCH] Experimental -find action -exec set_filter with some hardcoded filter commands --- libisoburn/trunk/xorriso/xorriso.1 | 5 +- libisoburn/trunk/xorriso/xorriso.c | 26 ++- libisoburn/trunk/xorriso/xorriso_timestamp.h | 2 +- libisoburn/trunk/xorriso/xorrisoburn.c | 227 ++++++++++++++++++- libisoburn/trunk/xorriso/xorrisoburn.h | 3 + 5 files changed, 248 insertions(+), 15 deletions(-) diff --git a/libisoburn/trunk/xorriso/xorriso.1 b/libisoburn/trunk/xorriso/xorriso.1 index 2d74dce8..2c8d8fec 100644 --- a/libisoburn/trunk/xorriso/xorriso.1 +++ b/libisoburn/trunk/xorriso/xorriso.1 @@ -156,7 +156,7 @@ useful to store intermediate states and to continue with image manipulations. .B Media types and states: There are two families of media in the MMC standard: .br -\fBMulti-session media\fR are CD-R, CD-RW, DVD-R, DVD+R, DVD+R/DL, and +\fBMulti-session media\fR are CD-R, CD-RW, DVD-R, DVD+R, DVD+R/DL, BD-R, and unformatted DVD-RW. These media provide a table of content which describes their existing sessions. See option \fB-toc\fR. .br @@ -1151,7 +1151,8 @@ matches only files which use data blocks outside the areas marked as damaged. -lba_range start_lba block_count .br matches only files which use data blocks within the range of start_lba -and start_lba+block_count-1. +and start_lba+block_count-1. A negative start_lba matches those files which +would not match the range given by its positive counter part. .br -has_acl , -has_no_acl .br diff --git a/libisoburn/trunk/xorriso/xorriso.c b/libisoburn/trunk/xorriso/xorriso.c index b886c739..132a6639 100644 --- a/libisoburn/trunk/xorriso/xorriso.c +++ b/libisoburn/trunk/xorriso/xorriso.c @@ -2480,6 +2480,8 @@ struct FindjoB { 24= getfacl 25= setfacl access_acl default_acl 26= getfattr + 27= setfattr + 28= set_filter name suffix */ int action; @@ -2506,8 +2508,8 @@ int Findjob_new(struct FindjoB **o, char *start_path, int flag) m->start_path= NULL; m->name_expr= NULL; m->file_type= 0; - m->start_lba= -1; - m->end_lba= -1; + m->start_lba= 0; + m->end_lba= 0; m->damage_filter= 0; m->commit_filter= 0; m->acl_filter= 0; @@ -2611,7 +2613,10 @@ int Findjob_set_lba_range(struct FindjoB *o, int start_lba, int count, int flag) { o->start_lba= start_lba; - o->end_lba= start_lba + count - 1; + if(start_lba > 0) + o->end_lba= start_lba + count - 1; + else + o->end_lba= start_lba - count + 1; return(1); } @@ -6955,7 +6960,8 @@ int Xorriso_compare_2_files(struct XorrisO *xorriso, char *disk_adr, (*result)|= 64; } } - if(S_ISREG(s2.st_mode) && s1.st_size != s2.st_size) { + if((!(xorriso->do_aaip & 32)) && + S_ISREG(s2.st_mode) && s1.st_size != s2.st_size) { sprintf(respt, "%s st_size : %.f <> %.f diff= %.f\n", a, (double) s1.st_size, (double) s2.st_size, ((double) s1.st_size) - (double) s2.st_size); @@ -13696,6 +13702,15 @@ not_enough_arguments:; if(ret <= 0) goto ex; Findjob_set_action_text_2(job, 27, argv[i - 1], argv[i], 0); + } else if(strcmp(cpt, "set_filter")==0) { + if(i+2>=end_idx) + goto not_enough_arguments; + i+= 2; + Findjob_set_action_text_2(job, 28, argv[i - 1], argv[i], 0); + if(!(flag&2)) { + Xorriso_pacifier_reset(xorriso, 0); + mem_lut= xorriso->last_update_time; + } } else { sprintf(xorriso->info_text, "-find -exec: unknown action %s", Text_shellsafe(argv[i], sfe, 0)); @@ -13719,6 +13734,9 @@ ex:; if(deleter && !(flag&2)) Xorriso_pacifier_callback(xorriso, "iso_rr_paths deleted", xorriso->pacifier_count, 0, "", 1|2); + else if(first_job->action == 28 && !(flag&2)) + Xorriso_pacifier_callback(xorriso, "file filters processed", + xorriso->pacifier_count, 0, "", 1 | 2); else if(mem_lut!=xorriso->last_update_time && mem_lut!=0.0 && !(flag&2)) Xorriso_pacifier_callback(xorriso, "content bytes read", xorriso->pacifier_count, 0, "", 1); diff --git a/libisoburn/trunk/xorriso/xorriso_timestamp.h b/libisoburn/trunk/xorriso/xorriso_timestamp.h index fee9273b..73950364 100644 --- a/libisoburn/trunk/xorriso/xorriso_timestamp.h +++ b/libisoburn/trunk/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2009.03.29.164703" +#define Xorriso_timestamP "2009.03.29.164931" diff --git a/libisoburn/trunk/xorriso/xorrisoburn.c b/libisoburn/trunk/xorriso/xorrisoburn.c index 87367115..97b839d5 100644 --- a/libisoburn/trunk/xorriso/xorrisoburn.c +++ b/libisoburn/trunk/xorriso/xorrisoburn.c @@ -6599,6 +6599,9 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, } else if(action == 27) { ret= Xorriso_path_setfattr(xorriso, (void *) node, show_path, target, strlen(text_2), text_2, 0); + } else if(action == 28) { + ret= Xorriso_set_filter(xorriso, (void *) node, show_path, + target, text_2, 1 | 2); } else { /* includes : 15 in_iso */ sprintf(xorriso->result_line, "%s\n", Text_shellsafe(show_path, sfe, 0)); Xorriso_result(xorriso, 0); @@ -6636,16 +6639,23 @@ int Xorriso_findi_test(struct XorrisO *xorriso, struct FindjoB *job, if((damage_filter > 0) != (ret > 0)) return(0); } - if(start_lba >= 0 && end_lba >= 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); - goto ex; - } - for(i= 0; i < lba_count; i++) { - if(file_end_lbas[i] < start_lba || file_start_lbas[i] > end_lba) - {ret= 0; goto ex;} + 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); @@ -6814,9 +6824,9 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, mem= boss_mem; hflag= 1; - if(action==1 || action==2 || action==3 || action==17) + if(action==1 || action==2 || action==3 || action==17 || action == 28) hflag|= 2; /* need freedom to manipulate image */ - if(action==14 || action==17) + if(action==14 || action==17 || action == 28) hflag|= 4; /* need LBA sorted iteration for good data reading performance */ ret= Xorriso_findi_iter(xorriso, dir_node, &mem, &iter, &node_array, &node_count, &node_idx, @@ -9601,3 +9611,204 @@ ex:; return(ret); } + +/* + @pram suffix to be added or stripped if not empty or "-no-suffix-" + @param flag bit0= return 2 if renaming is not possible + bit1= print pacifier messages + */ +int Xorriso_set_filter(struct XorrisO *xorriso, void *in_node, + char *path, char *filter_name, char *suffix, int flag) +{ + int ret, lo= 0, ls= 0, strip_suffix= 0, strip_filter= 0; + IsoNode *node; + IsoFile *file; + IsoExternalFilterCommand *cmd = NULL; + char *old_name= NULL, new_name[SfileadrL]; + + static char *argv_cat[2] = {"cat", NULL}; + static IsoExternalFilterCommand cmd_cat = + {0, 0, "/bin/cat", 1, argv_cat, 1}; + + static char *argv_gzip[2] = {"gzip", NULL}; + static IsoExternalFilterCommand cmd_gzip = + {0, 0, "/usr/bin/gzip", 1, argv_gzip, 4}; + static char *argv_gunzip[2] = {"gunzip", NULL}; + static IsoExternalFilterCommand cmd_gunzip = + {0, 0, "/usr/bin/gunzip", 1, argv_gunzip, 1}; + + static char *argv_sencrypt[6] = + {"sencrypt", "-e", "-g", "-k", "1QwErTy7", NULL}; + static IsoExternalFilterCommand cmd_sencrypt = + {0, 0, "/usr/bin/sencrypt", 5, argv_sencrypt, 1}; + static char *argv_sencrypt_d[6] = + {"sencrypt", "-d", "-g", "-k", "1QwErTy7", NULL}; + static IsoExternalFilterCommand cmd_sencrypt_d = + {0, 0, "/usr/bin/sencrypt", 5, argv_sencrypt_d, 1}; + + static char *argv_sencrypt_f[6] = + {"sencrypt", "-e", "-g", "-f", "/var/opt/xorriso/keys/testkey", NULL}; + static IsoExternalFilterCommand cmd_sencrypt_f = + {0, 0, "/usr/bin/sencrypt", 5, argv_sencrypt_f, 1}; + static char *argv_sencrypt_f_d[6] = + {"sencrypt", "-d", "-g", "-f", "/var/opt/xorriso/keys/testkey", NULL}; + static IsoExternalFilterCommand cmd_sencrypt_f_d = + {0, 0, "/usr/bin/sencrypt", 5, argv_sencrypt_f_d, 1}; + + new_name[0]= 0; + + if(getuid() != geteuid()) { + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + sprintf(xorriso->info_text, + "-set_filter: UID and EUID differ. Will not run external programs."); + return(0); + } + + 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, "-set_filter: Not a regular data file node "); + Text_shellsafe(path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + ret= 0; goto ex; + } + file= (IsoFile *) node; + + /* >>> lookup cmd by filter_name */ + /* <<< this is a dummy for testing */ + if(strcmp(filter_name, "-cat") == 0) { + cmd= &cmd_cat; + } else if(strcmp(filter_name, "-gzip") == 0) { + cmd= &cmd_gzip; + } else if(strcmp(filter_name, "-gunzip") == 0) { + cmd= &cmd_gunzip; + strip_suffix= 1; + } else if(strcmp(filter_name, "-sencrypt") == 0) { + cmd= &cmd_sencrypt; + } else if(strcmp(filter_name, "-sencrypt_d") == 0) { + cmd= &cmd_sencrypt_d; + strip_suffix= 1; + } else if(strcmp(filter_name, "-sencrypt_f") == 0) { + cmd= &cmd_sencrypt_f; + } else if(strcmp(filter_name, "-sencrypt_f_d") == 0) { + cmd= &cmd_sencrypt_f_d; + strip_suffix= 1; + } else if(strcmp(filter_name, "--remove-all-filters") == 0) { + strip_filter= 1; + strip_suffix= 1; + } else { + strcpy(xorriso->info_text, "-set_filter: Not a registered filter name "); + Text_shellsafe(filter_name, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + + if(suffix[0] && strcmp(suffix, "--no-suffix") != 0) { + old_name= strdup((char *) iso_node_get_name(node)); + lo= strlen(old_name); + ls= strlen(suffix); + if(strip_suffix) { + if(lo <= ls) { + /* refuse gracefully */ + ret= 2; goto ex; + } + if(strcmp(old_name + lo - ls, suffix) != 0) { + ret= 2; goto ex; + } + if(lo > sizeof(new_name)) + goto cannot_remove_suffix; + strcpy(new_name, old_name); + new_name[lo - ls]= 0; + ret = iso_node_set_name(node, new_name); + if (ret < 0) { + Xorriso_process_msg_queues(xorriso,0); + if (!(flag & 1)) + Xorriso_report_iso_error(xorriso, "", ret, + "Error when renaming ISO node", 0, "FAILURE", 1); +cannot_remove_suffix:; + + /* >>> would need full iso_rr_path of node */; + + strcpy(xorriso->info_text, "-set_filter: Cannot remove suffix from "); + Text_shellsafe(old_name, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, + (flag & 1) ? "WARNING" : "FAILURE", 0); + ret= 2 * (flag & 1); goto ex; + } + } else { + /* check whether suffix already present */ + if(lo >= ls) + if(strcmp(old_name + lo - ls, suffix) == 0) { + /* refuse gracefully */ + ret= 2; goto ex; + } + if(lo + ls > 255) { +cannot_append_suffix:; + + /* >>> would need full iso_rr_path of node */; + + strcpy(xorriso->info_text, "-set_filter: Cannot append suffix to "); + Text_shellsafe(old_name, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, + (flag & 1) ? "WARNING" : "FAILURE", 0); + ret= 2 * (flag & 1); goto ex; + } + sprintf(new_name, "%s%s", old_name, suffix); + ret = iso_node_set_name(node, new_name); + if (ret < 0) { + Xorriso_process_msg_queues(xorriso,0); + if (!(flag & 1)) + Xorriso_report_iso_error(xorriso, "", ret, + "Error when renaming ISO node", 0, "FAILURE", 1); + goto cannot_append_suffix; + } + } + } + + if(strip_filter) { + while(1) { + ret= iso_file_remove_filter(file, 0); + if(ret != 1) + break; + } + } else { + ret = iso_file_add_external_filter(file, cmd, 0); + } + if(flag & 2) { + xorriso->pacifier_count++; + Xorriso_pacifier_callback(xorriso, "file filters processed", + xorriso->pacifier_count, xorriso->pacifier_total, "", 0); + } + if(ret != 1 && new_name[0] && old_name != NULL) { + ret = iso_node_set_name(node, old_name); + if (ret < 0) { + Xorriso_process_msg_queues(xorriso,0); + if (!(flag & 1)) + Xorriso_report_iso_error(xorriso, "", ret, + "Error when renaming ISO node", 0, "FAILURE", 1); + } + } + if(ret < 0) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_report_iso_error(xorriso, "", ret, + "Error when setting filter to ISO node", 0, "FAILURE", 1); + ret= 0; goto ex; + } + + /* <<< Adding a filter is an initial image change only if node in + old image and indev!=outdev + xorriso->volset_change_pending= 1; + */ + +ex:; + if(old_name != NULL) + free(old_name); + Xorriso_process_msg_queues(xorriso,0); + return(ret); +} + + diff --git a/libisoburn/trunk/xorriso/xorrisoburn.h b/libisoburn/trunk/xorriso/xorrisoburn.h index 9d5ccdbe..6aaeda2f 100644 --- a/libisoburn/trunk/xorriso/xorrisoburn.h +++ b/libisoburn/trunk/xorriso/xorrisoburn.h @@ -431,6 +431,9 @@ int Xorriso_record_dev_inode(struct XorrisO *xorriso, char *disk_path, int Xorriso_local_getfacl(struct XorrisO *xorriso, char *disk_path, char **text, int flag); +int Xorriso_set_filter(struct XorrisO *xorriso, void *in_node, + char *path, char *filter_name, char *suffix, int flag); + /* A pseudo file type for El-Torito bootsectors as in man 2 stat : For now take the highest possible value.