diff --git a/src/wrap.c b/src/wrap.c index 141bd56..6605a5f 100644 --- a/src/wrap.c +++ b/src/wrap.c @@ -10,58 +10,43 @@ enum { OPT_OUTPATH, OPT_OUTPATH_PATH, - ARG_FILE, + OPT_FILE, + OPT_FILE_PATH, + OPT_EXEC, + OPT_EXEC_PATH, OPT_TAGGED_FILE, OPT_TAGGED_FILE_TAG, OPT_TAGGED_FILE_PATH, + + OPT_TAGGED_EXEC, + OPT_TAGGED_EXEC_TAG, + OPT_TAGGED_EXEC_PATH, + + OPT_IDENT, + OPT_IDENT_VAL, }; -static int wrap( - const b_command *self, - const b_arglist *opt, - const b_array *args) +static enum ec3_status add_file( + struct ec3_writer *writer, + unsigned long type, + uint64_t id, + const char *path) { - const char *in_path = NULL, *out_path = NULL; - b_arglist_get_string(opt, B_COMMAND_INVALID_ID, ARG_FILE, 0, &in_path); - b_arglist_get_string(opt, OPT_OUTPATH, OPT_OUTPATH_PATH, 0, &out_path); - - printf("in path: %s\n", in_path); - printf("out path: %s\n", out_path); - - FILE *inp = fopen(in_path, "rb"); + FILE *inp = fopen(path, "rb"); if (!inp) { - b_err("cannot open '%s'", in_path); + b_err("cannot open '%s'", path); b_i("reason: %s", strerror(errno)); - return -1; - } - - FILE *outp = fopen(out_path, "wb"); - if (!outp) { - b_err("cannot open '%s'", out_path); - b_i("reason: %s", strerror(errno)); - return -1; - } - - struct ec3_writer *writer = NULL; - struct ec3_parameters param = { - .p_outp = outp, - .p_cluster_size = EC3_CLUSTER_16K, - .p_compression_func = EC3_COMPRESSION_ZSTD, - }; - enum ec3_status status = ec3_writer_create(¶m, &writer); - - if (status != EC3_SUCCESS) { - b_err("cannot initialise EC3 writer"); - return -1; + return EC3_ERR_NO_ENTRY; } struct ec3_tag_writer *tag = NULL; - status = ec3_writer_create_tag(writer, EC3_TAG_BLOB, 0, 0, &tag); + enum ec3_status status + = ec3_writer_create_tag(writer, type, id, 0, &tag); if (status != EC3_SUCCESS) { b_err("cannot initialise EC3 tag writer"); - return -1; + return status; } char buf[4096]; @@ -76,9 +61,185 @@ static int wrap( } ec3_tag_writer_finish(tag); + fclose(inp); + + return EC3_SUCCESS; +} + +static int wrap( + const b_command *self, + const b_arglist *opt, + const b_array *args) +{ + const char *out_path = NULL; + b_arglist_get_string(opt, OPT_OUTPATH, OPT_OUTPATH_PATH, 0, &out_path); + + FILE *outp = fopen(out_path, "wb"); + if (!outp) { + b_err("cannot open '%s'", out_path); + b_i("reason: %s", strerror(errno)); + return -1; + } + + enum ec3_status status = EC3_SUCCESS; + + uint64_t ident = 0; + const char *ident_str; + b_arglist_get_string(opt, OPT_IDENT, OPT_IDENT_VAL, 0, &ident_str); + if (ident_str) { + status = ec3_identifier_from_string(ident_str, &ident); + } + + if (status != EC3_SUCCESS) { + b_err("'%s' is not a valid container identifier", ident_str); + return -1; + } + + struct ec3_writer *writer = NULL; + struct ec3_parameters param = { + .p_outp = outp, + .p_cluster_size = EC3_CLUSTER_16K, + .p_compression_func = EC3_COMPRESSION_ZSTD, + .p_ident = ident, + }; + status = ec3_writer_create(¶m, &writer); + + if (status != EC3_SUCCESS) { + b_err("cannot initialise EC3 writer"); + return -1; + } + + uint64_t next_auto_id = 0; + + b_arglist_iterator it = {0}; + b_arglist_foreach_filtered(&it, opt, OPT_FILE, OPT_FILE_PATH) + { + printf("%s\n", it.value->val_str); +#if 1 + status = add_file( + writer, + EC3_TAG_BLOB, + next_auto_id, + it.value->val_str); + next_auto_id++; + + if (status != EC3_SUCCESS) { + b_err("an error occurred while writing to the " + "container"); + return -1; + } +#endif + } + + b_arglist_foreach_filtered(&it, opt, OPT_EXEC, OPT_EXEC_PATH) + { + printf("%s\n", it.value->val_str); +#if 1 + status = add_file( + writer, + EC3_TAG_EXEC, + next_auto_id, + it.value->val_str); + next_auto_id++; + + if (status != EC3_SUCCESS) { + b_err("an error occurred while writing to the " + "container"); + return -1; + } +#endif + } + + for (size_t i = 0;; i++) { + b_arglist_option *option = NULL; + b_status err = b_arglist_get_option( + opt, + OPT_TAGGED_FILE, + i, + &option); + if (!option) { + break; + } + + b_arglist_value *tag = NULL, *path = NULL; + err = b_arglist_option_get_value( + option, + OPT_TAGGED_FILE_TAG, + 0, + &tag); + err = b_arglist_option_get_value( + option, + OPT_TAGGED_FILE_PATH, + 0, + &path); + + printf("%s:%s\n", tag->val_str, path->val_str); + +#if 1 + uint64_t id = 0; + status = ec3_identifier_from_string(tag->val_str, &id); + + if (status != EC3_SUCCESS) { + b_err("'%s' is not a valid tag identifier", id); + return -1; + } + + status = add_file(writer, EC3_TAG_BLOB, id, path->val_str); + + if (status != EC3_SUCCESS) { + b_err("an error occurred while writing to the " + "container"); + return -1; + } +#endif + } + + for (size_t i = 0;; i++) { + b_arglist_option *option = NULL; + b_status err = b_arglist_get_option( + opt, + OPT_TAGGED_EXEC, + i, + &option); + if (!option) { + break; + } + + b_arglist_value *tag = NULL, *path = NULL; + err = b_arglist_option_get_value( + option, + OPT_TAGGED_EXEC_TAG, + 0, + &tag); + err = b_arglist_option_get_value( + option, + OPT_TAGGED_EXEC_PATH, + 0, + &path); + + printf("%s:%s\n", tag->val_str, path->val_str); + +#if 1 + uint64_t id = 0; + status = ec3_identifier_from_string(tag->val_str, &id); + + if (status != EC3_SUCCESS) { + b_err("'%s' is not a valid tag identifier", id); + return -1; + } + + status = add_file(writer, EC3_TAG_EXEC, id, path->val_str); + + if (status != EC3_SUCCESS) { + b_err("an error occurred while writing to the " + "container"); + return -1; + } +#endif + } + ec3_writer_finish(writer); - fclose(inp); fclose(outp); return 0; @@ -89,7 +250,8 @@ B_COMMAND(CMD_WRAP, CMD_ROOT) B_COMMAND_NAME("wrap"); B_COMMAND_SHORT_NAME('W'); B_COMMAND_DESC( - "wrap one or more files into an ec3 container. each file will " + "wrap one or more files into an ec3 container. each " + "file will " "be stored in a separate blob tag within the created " "container."); B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT); @@ -110,24 +272,47 @@ B_COMMAND(CMD_WRAP, CMD_ROOT) } } - B_COMMAND_ARG(ARG_FILE) + B_COMMAND_OPTION(OPT_IDENT) { - B_ARG_NAME("file"); - B_ARG_DESC("a file to add to the container"); + B_OPTION_SHORT_NAME('I'); + B_OPTION_LONG_NAME("ident"); + B_OPTION_DESC( + "the string or number to use as the container " + "identifier"); - B_ARG_NR_VALUES(B_ARG_1_OR_MORE_VALUES); + B_OPTION_ARG(OPT_IDENT_VAL) + { + B_ARG_NAME("value"); + B_ARG_NR_VALUES(1); + } + } + + B_COMMAND_OPTION(OPT_FILE) + { + B_OPTION_SHORT_NAME('f'); + B_OPTION_LONG_NAME("file"); + B_OPTION_DESC("a file to add to the container."); + + B_OPTION_ARG(OPT_FILE_PATH) + { + B_ARG_NAME("path"); + B_ARG_NR_VALUES(1); + } } B_COMMAND_OPTION(OPT_TAGGED_FILE) { - B_OPTION_SHORT_NAME('I'); + B_OPTION_SHORT_NAME('F'); B_OPTION_LONG_NAME("tagged-file"); B_OPTION_DESC( - "a file to add to the container, with an associated " + "a file to add to the container, with an " + "associated " "tag. " - "the tag must be either: (a) a 64-bit hexadecimal " + "the tag must be either: (a) a 64-bit " + "hexadecimal " "number; " - "or (b) a string of no more than 8 characters."); + "or (b) a string of no more than 8 " + "characters."); B_OPTION_ARG(OPT_TAGGED_FILE_TAG) { @@ -143,10 +328,51 @@ B_COMMAND(CMD_WRAP, CMD_ROOT) } } + B_COMMAND_OPTION(OPT_EXEC) + { + B_OPTION_SHORT_NAME('e'); + B_OPTION_LONG_NAME("executable"); + B_OPTION_DESC("an executable file to add to the container."); + + B_OPTION_ARG(OPT_EXEC_PATH) + { + B_ARG_NAME("path"); + B_ARG_NR_VALUES(1); + } + } + + B_COMMAND_OPTION(OPT_TAGGED_EXEC) + { + B_OPTION_SHORT_NAME('E'); + B_OPTION_LONG_NAME("tagged-executable"); + B_OPTION_DESC( + "an executable file to add to the container, with an " + "associated " + "tag. " + "the tag must be either: (a) a 64-bit " + "hexadecimal " + "number; " + "or (b) a string of no more than 8 " + "characters."); + + B_OPTION_ARG(OPT_TAGGED_EXEC_TAG) + { + B_ARG_NAME("tag"); + B_ARG_DESC("the tag!"); + B_ARG_NR_VALUES(1); + } + + B_OPTION_ARG(OPT_TAGGED_EXEC_PATH) + { + B_ARG_NAME("path"); + B_ARG_NR_VALUES(1); + } + } + B_COMMAND_USAGE() { B_COMMAND_USAGE_OPT(OPT_OUTPATH); - B_COMMAND_USAGE_ARG(ARG_FILE); + B_COMMAND_USAGE_OPT(OPT_FILE); } B_COMMAND_USAGE()