From 50ce43b4709f1ab27937482fa3aff2fa5f6a0611 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Wed, 30 May 2012 15:34:07 +0000 Subject: [PATCH] New (yet inofficial) -find actions set/get_hfs_crtp, set/get_hfs_bless --- xorriso/findjob.h | 8 +- xorriso/iso_manip.c | 146 ++++++++++++++++++++++++++++++++---- xorriso/iso_manip.h | 3 + xorriso/opts_d_h.c | 23 ++++++ xorriso/xorriso_timestamp.h | 2 +- 5 files changed, 166 insertions(+), 16 deletions(-) diff --git a/xorriso/findjob.h b/xorriso/findjob.h index 8c480bd3..0d4d1baf 100644 --- a/xorriso/findjob.h +++ b/xorriso/findjob.h @@ -1,7 +1,7 @@ /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. - Copyright 2007-2010 Thomas Schmitt, + Copyright 2007-2012 Thomas Schmitt, Provided under GPL version 2 or later. @@ -46,6 +46,8 @@ struct ExprtesT { 15= -has_md5 16= -disk_name char *arg1 (regex_t in *arg2) 17= -hidden int *arg1 (bit0=iso_rr, bit1=joliet) + >>> -has_hfs_crtp + >>> -has_hfs_bless blessing|any */ int test_type; @@ -159,6 +161,10 @@ struct FindjoB { 42= rm_merge 43= clear_merge 44= list_extattr + 45= set_hfs_crtp creator type + 46= get_hfs_crtp + 47= set_hfs_bless blessing + 48= get_hfs_bless */ int action; int prune; diff --git a/xorriso/iso_manip.c b/xorriso/iso_manip.c index e11253a4..319fddcd 100644 --- a/xorriso/iso_manip.c +++ b/xorriso/iso_manip.c @@ -2397,20 +2397,22 @@ cannot_iter:; 1=ok 2=ok, node has been deleted, 3=ok, do not dive into directory (e.g. because it is a split file) + 4=ok, end findjob gracefully */ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, IsoDirIter *boss_iter, off_t boss_mem, char *abs_path, char *show_path, IsoNode *node, int depth, int flag) { - int ret= 0, type, action= 0, hflag, deleted= 0, no_dive= 0; + int ret= 0, type, action= 0, hflag, deleted= 0, no_dive= 0, i, bless_idx; uid_t user= 0; gid_t group= 0; time_t date= 0; mode_t mode_or= 0, mode_and= ~1; - char *target, *text_2, *iso_prefix, md5[16], *basename; + char *target, *text_2, *iso_prefix, md5[16], *basename, bless_code[17]; struct FindjoB *subjob; struct stat dir_stbuf, stbuf; + struct iso_hfsplus_xinfo_data *hfsplus_xinfo; action= Findjob_get_action_parms(job, &target, &text_2, &user, &group, &mode_and, &mode_or, &type, &date, &subjob, 0); @@ -2549,6 +2551,47 @@ int Xorriso_findi_action(struct XorrisO *xorriso, struct FindjoB *job, } else if(action == 44) { /* list_extattr */ ret= Xorriso_list_extattr(xorriso, (void *) node, show_path, show_path, target, 0); + } else if(action == 45) { /* set_hfs_crtp */ + ret= Xorriso_hfsplus_file_creator_type(xorriso, show_path, (void *) node, + target, text_2, 0); + + } else if(action == 46) { /* get_hfs_crtp */ + ret= iso_node_get_xinfo(node, iso_hfsplus_xinfo_func, + (void **) &hfsplus_xinfo); + if(ret < 0) { + Xorriso_process_msg_queues(xorriso, 0); + ret= 0; + } else if(ret == 1) { + for(i= 0; i < 4; i++) + xorriso->result_line[i]= hfsplus_xinfo->creator_code[i]; + xorriso->result_line[4]= ' '; + for(i= 0; i < 4; i++) + xorriso->result_line[5 + i]= hfsplus_xinfo->type_code[i]; + xorriso->result_line[9]= ' '; + xorriso->result_line[10]= 0; + Text_shellsafe(show_path, xorriso->result_line, 1); + strcat(xorriso->result_line, "\n"); + Xorriso_result(xorriso, 0); + } + ret= 1; + } else if(action == 47) { /* set_hfs_bless */ + ret= Xorriso_hfsplus_bless(xorriso, show_path, (void *) node, target, 0); + /* If successful, end -find run gracefully */ + if(ret > 0) { + sprintf(xorriso->info_text, "HFS blessing '%s' issued to ", target); + Text_shellsafe(show_path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + } + return(4); + } else if(action == 48) { /* get_hfs_bless */ + ret= Xorriso_get_blessing(xorriso, node, &bless_idx, bless_code, 0); + if (ret > 0) { + sprintf(xorriso->result_line, "%-16.16s ", bless_code); + Text_shellsafe(show_path, xorriso->result_line, 1); + strcat(xorriso->result_line, "\n"); + Xorriso_result(xorriso, 0); + } else if(ret == 0) + ret= 1; } else { /* includes : 15 in_iso */ Text_shellsafe(show_path, xorriso->result_line, 0); strcat(xorriso->result_line, "\n"); @@ -2852,6 +2895,7 @@ int Xorriso_findi_headline(struct XorrisO *xorriso, struct FindjoB *job, bit2= do not dive into split file directories (implicitly given with actions 14=compare and 17=update) @return <=0 error, 1= ok , 2= dir node and path has been deleted + 4= end gracefully */ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, void *boss_iter, off_t boss_mem, @@ -2922,10 +2966,12 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, flag&(1|2)); deleted= (iso_node_get_parent(iso_node) == NULL); /* still in tree ? */ iso_node_unref(iso_node); /* eventually do real disposal */ - if(ret<=0) - goto ex; if(xorriso->request_to_abort) {ret= 0; goto ex;} + if(ret == 4) + goto ex; + if(ret<=0) + goto ex; if(ret==2 || deleted) { /* re-determine dir_node in case it has a new persona */ ret= Xorriso_node_from_path(xorriso, volume, path, &iso_node, 1); @@ -3001,6 +3047,8 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, abs_path, path, node, depth, 1|(flag&2)); if(xorriso->request_to_abort) {ret= 0; goto ex;} + if(ret == 4) + goto ex; if(ret==2) { /* node has been deleted */ /* re-determine node in case it has a new persona */ if(volume==NULL) { @@ -3031,6 +3079,10 @@ int Xorriso_findi(struct XorrisO *xorriso, struct FindjoB *job, (void *) node, path, &stbuf, depth+1, flag|1); if(ret<0) goto ex; + if(xorriso->request_to_abort) + {ret= 0; goto ex;} + if(ret == 4) + goto ex; } } @@ -3176,6 +3228,8 @@ int Xorriso_findi_sorted(struct XorrisO *xorriso, struct FindjoB *job, if(ret <= 0 || xorriso->request_to_abort) if(Xorriso_eval_problem_status(xorriso, ret, 1|2)<0) goto ex; + if(ret == 4) /* end gracefully */ + break; } ret= 1; @@ -3461,32 +3515,49 @@ set_error:; } +/* @param flag bit0= only check creator and hfs_type for compliance. +*/ int Xorriso_hfsplus_file_creator_type(struct XorrisO *xorriso, char *path, void *in_node, char *creator, char *hfs_type, int flag) { int ret; IsoNode *node; - struct iso_hfsplus_xinfo_data *hfs_data; + struct iso_hfsplus_xinfo_data *hfs_data= NULL; - if(in_node == NULL) { + if(in_node == NULL && !(flag * 1)) { ret= Xorriso_node_from_path(xorriso, NULL, path, &node, 0); if(ret <= 0) return(ret); } else node= (IsoNode *) in_node; + if((creator[0] == 0 && hfs_type[0] == 0) || + strcmp(creator, "--delete") == 0) { + if(flag & 1) + return(1); + ret= iso_node_remove_xinfo(node, iso_hfsplus_xinfo_func); + Xorriso_process_msg_queues(xorriso, 0); + if(ret < 0) { + Xorriso_report_iso_error(xorriso, path, ret, + "Cannot remove HFS+ creator and type of ISO node", + 0, "FAILURE", 1); + goto failure; + } + return(1); + } else if(strlen(creator) != 4 || strlen(hfs_type) != 4) { + strcat(xorriso->info_text, + "HFS+ file creator code or type code are not exactly 4 characters long"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + if(flag & 1) + return(1); hfs_data= iso_hfsplus_xinfo_new(0); if(hfs_data == NULL) { Xorriso_no_malloc_memory(xorriso, NULL, 0); return(-1); } - if(strlen(creator) != 4 || strlen(hfs_type) != 4) { - strcat(xorriso->info_text, - "HFS+ file creator code or type code are not exactly 4 characters long"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - return(0); - } memcpy(hfs_data->creator_code, creator, 4); memcpy(hfs_data->type_code, hfs_type, 4); @@ -3510,11 +3581,11 @@ int Xorriso_hfsplus_file_creator_type(struct XorrisO *xorriso, char *path, Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); goto failure; } - Xorriso_set_change_pending(xorriso, 0); return(1); failure: - iso_hfsplus_xinfo_func(hfs_data, 1); + if(hfs_data != NULL) + iso_hfsplus_xinfo_func(hfs_data, 1); return(0); } @@ -3527,6 +3598,8 @@ failure: bit0= Revoke blessing if node != NULL bears it. bit1= Revoke any blessing of the node, regardless of parameter blessing. If node is NULL, then revoke all blessings in opts. + bit2= Only check parameter blessing. + Return 1 instead of issueing the blessing. */ int Xorriso_hfsplus_bless(struct XorrisO *xorriso, char *path, void *in_node, char *blessing, int flag) @@ -3568,6 +3641,9 @@ int Xorriso_hfsplus_bless(struct XorrisO *xorriso, char *path, return(0); } + if(flag & 4) + return(1); + ret= iso_image_hfsplus_bless(volume, bless_code, node, flag & 3); Xorriso_process_msg_queues(xorriso, 0); if(ret == 0 && path[0]) { @@ -3594,3 +3670,45 @@ int Xorriso_hfsplus_bless(struct XorrisO *xorriso, char *path, return(1); } + +int Xorriso_get_blessing(struct XorrisO *xorriso, IsoNode *node, + int *bless_idx, char bless_code[17], int flag) +{ + IsoNode **blessed_nodes; + int bless_max, ret, i; + + if(xorriso->in_volset_handle == NULL) + return(0); + + ret= iso_image_hfsplus_get_blessed((IsoImage *) xorriso->in_volset_handle, + &blessed_nodes, &bless_max, 0); + Xorriso_process_msg_queues(xorriso, 0); + if(ret < 0) { + Xorriso_report_iso_error(xorriso, "", ret, + "Error when trying to inquire HFS+ file blessings", + 0, "FAILURE", 1); + return(-1); + } + for(i= 0; i < bless_max; i++) { + if(blessed_nodes[i] == node) { + switch (i) { + case ISO_HFSPLUS_BLESS_PPC_BOOTDIR: + strcpy(bless_code, "ppc_bootdir"); + break; case ISO_HFSPLUS_BLESS_INTEL_BOOTFILE: + strcpy(bless_code, "intel_bootfile"); + break; case ISO_HFSPLUS_BLESS_SHOWFOLDER: + strcpy(bless_code, "show_folder"); + break; case ISO_HFSPLUS_BLESS_OS9_FOLDER: + strcpy(bless_code, "os9_folder"); + break; case ISO_HFSPLUS_BLESS_OSX_FOLDER: + strcpy(bless_code, "osx_folder"); + break; default: + strcpy(bless_code, "unknown_blessing"); + } + return(1); + } + } + return(0); +} + + diff --git a/xorriso/iso_manip.h b/xorriso/iso_manip.h index 30780f3b..d5d3f357 100644 --- a/xorriso/iso_manip.h +++ b/xorriso/iso_manip.h @@ -70,5 +70,8 @@ int Xorriso__file_start_lba(IsoNode *node, int *lba, int flag); int Xorriso__mark_update_xinfo(void *data, int flag); int Xorriso__mark_update_cloner(void *old_data, void **new_data, int flag); +int Xorriso_get_blessing(struct XorrisO *xorriso, IsoNode *node, + int *bless_idx, char bless_code[17], int flag); + #endif /* ! Xorriso_pvt_iso_manip_includeD */ diff --git a/xorriso/opts_d_h.c b/xorriso/opts_d_h.c index 47f9cc93..f9a062a1 100644 --- a/xorriso/opts_d_h.c +++ b/xorriso/opts_d_h.c @@ -1081,6 +1081,29 @@ not_enough_exec_arguments:; Findjob_set_action_target(job, 44, argv[i], 0); list_extattr_head= 1; list_extattr_mode= argv[i]; + } else if(strcmp(cpt, "set_hfs_crtp")==0) { + if(i + 2 >= end_idx) + goto not_enough_exec_arguments; + i+= 2; + /* Check creator and type for compliance */ + ret= Xorriso_hfsplus_file_creator_type(xorriso, "", NULL, + argv[i - 1], argv[i], 1); + if(ret <= 0) + goto ex; + Findjob_set_action_text_2(job, 45, argv[i - 1], argv[i], 0); + } else if(strcmp(cpt, "get_hfs_crtp")==0) { + Findjob_set_action_target(job, 46, NULL, 0); + } else if(strcmp(cpt, "set_hfs_bless")==0) { + if(i+1>=end_idx) + goto not_enough_exec_arguments; + i++; + /* Check type of blessing for compliance */ + ret= Xorriso_hfsplus_bless(xorriso, "", NULL, argv[i], 4); + if(ret <= 0) + goto ex; + Findjob_set_action_target(job, 47, argv[i], 0); + } else if(strcmp(cpt, "get_hfs_bless")==0) { + Findjob_set_action_target(job, 48, NULL, 0); } else { sprintf(xorriso->info_text, "-find -exec: unknown action "); Text_shellsafe(argv[i], xorriso->info_text, 1); diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index a3c5f066..2283bc5a 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2012.05.28.133310" +#define Xorriso_timestamP "2012.05.30.153449"