summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Bolte <sbolte@lavabit.com>2013-05-18 15:56:38 +0200
committerStefan Bolte <sbolte@lavabit.com>2013-05-18 15:56:38 +0200
commitba7890100660fc69c100bf3c8badb5d19f09273a (patch)
tree9e48b8d83e510a079d05c6ef2f744e66d458a0e2
parent892552bcfbc3b881b9b6bf51af14e3a68821fdaa (diff)
downloaddwb-ba7890100660fc69c100bf3c8badb5d19f09273a.zip
New option for dwbem --archive
-rw-r--r--Makefile4
-rw-r--r--dwbem/dwbem.c144
-rw-r--r--exar/main.c97
3 files changed, 188 insertions, 57 deletions
diff --git a/Makefile b/Makefile
index 422604a6..ee33b5f4 100644
--- a/Makefile
+++ b/Makefile
@@ -6,8 +6,8 @@ all: options $(TARGET)
options:
@echo Build options:
- @echo CC = $(CC)
- @echo CFLAGS = $(CFLAGS_OPTIONS)
+ @echo CC = $(CC)
+ @echo CFLAGS = $(CFLAGS_OPTIONS)
@echo LDFLAGS = $(LDFLAGS)
@echo CPPFLAGS = $(CPPFLAGS)
diff --git a/dwbem/dwbem.c b/dwbem/dwbem.c
index 85c016aa..93cc02e1 100644
--- a/dwbem/dwbem.c
+++ b/dwbem/dwbem.c
@@ -63,6 +63,19 @@
#define EXT(name) "\033[1m"#name"\033[0m"
#define FREE0(X) (X == NULL ? NULL : (X = (g_free(X), NULL)))
+enum {
+ EXAR_FLAG_V = 1<<0,
+ EXAR_FLAG_P = 1<<3,
+ EXAR_FLAG_U = 1<<4,
+ EXAR_FLAG_C = 1<<5,
+ EXAR_FLAG_E = 1<<6,
+ EXAR_FLAG_D = 1<<7,
+ EXAR_FLAG_I = 1<<8,
+ EXAR_FLAG_S = 1<<9,
+};
+#define EXAR_OPTION_FLAG (0xffff & ~(0x7))
+#define EXAR_CHECK_FLAG(x, flag) !!(((x) & (flag)) && !((x) & ( (EXAR_OPTION_FLAG)^(flag) ) ))
+
enum
{
F_NO_CONFIG = 1<<0,
@@ -1150,18 +1163,119 @@ cl_edit(const char *name, int flags)
}
return -1;
}
-static int
-cl_exar_pack(const char *path, int flags)
+void
+exar_help(int ret)
{
- (void) flags;
- return exar_pack(path);
+ printf("USAGE: \n"
+ " dwbem --archive option [arguments]\n\n"
+ "OPTIONS:\n"
+ " h Print this help and exit.\n"
+ " c[v] archive file Concatenates a file, directory or archive to \n"
+ " an existing archive.\n"
+ " d[v] archive file Deletes a file from an archive, the file path is the\n"
+ " relative file path of the file in the archive\n"
+ " e[v] archive file Extracts a file from an archive and writes the content\n"
+ " to stdout, the archive is not modified, the file path \n"
+ " is the relative file path of the file in the archive.\n"
+ " i[v] archive Prints info about an archive\n"
+ " p[v] path Pack file or directory 'path'.\n"
+ " s[v] archive file Search for a file and write the content to stdout, the \n"
+ " archive is not modified, the filename is the basename\n"
+ " plus suffix of the file in the archive, all directory\n"
+ " parts are stripped\n"
+ " u[v] file [dir] Pack 'file' to directory 'dir' or to current directory.\n"
+ " v Verbose, pass multiple times (up to 3) to \n"
+ " get more verbose messages.\n\n"
+ "EXAMPLES:\n"
+ " dwbem --archive p /tmp/foo -- pack /tmp/foo to foo.exar\n"
+ " dwbem --archive c foo.exar bar.txt -- Concatenates bar.txt to archive foo.exar\n"
+ " dwbem --archive c foo.exar bar.exar -- Concatenates archive bar.exar to archive foo.exar\n"
+ " dwbem --archive s foo.js > foo.js -- Extract foo.js from the archive\n"
+ " dwbem --archive uvvv foo.exar -- unpack foo.exar to current directory,\n"
+ " verbosity level 3\n"
+ " dwbem --archive vu foo.exar /tmp -- unpack foo.exar to /tmp, verbosity\n"
+ " level 1\n");
+ exit(ret);
}
-
-static int
-cl_exar_unpack(const char *path, int flags)
+static void
+exar_xextract(const char *archive, const char *path,
+ unsigned char * (*extract_func)(const char *, const char *, size_t *))
{
- (void) flags;
- return exar_unpack(path, NULL);
+ size_t s;
+ unsigned char *content = extract_func(archive, path, &s);
+ if (content != NULL)
+ {
+ fwrite(content, 1, s, stdout);
+ free(content);
+ }
+}
+void
+parse_exar_options(char **argv)
+{
+ int argc = 0, flag = 0;
+ const char *options;
+
+ if (argv == NULL)
+ exar_help(EXIT_FAILURE);
+
+ argc = g_strv_length(argv);
+ if (argc < 2)
+ exar_help(EXIT_FAILURE);
+ options = argv[0];
+ while (*options)
+ {
+ switch (*options)
+ {
+ case 'p' :
+ flag |= EXAR_FLAG_P;
+ break;
+ case 'u' :
+ flag |= EXAR_FLAG_U;
+ break;
+ case 'c' :
+ flag |= EXAR_FLAG_C;
+ break;
+ case 'e' :
+ flag |= EXAR_FLAG_E;
+ break;
+ case 'd' :
+ flag |= EXAR_FLAG_D;
+ break;
+ case 'i' :
+ flag |= EXAR_FLAG_I;
+ break;
+ case 's' :
+ flag |= EXAR_FLAG_S;
+ break;
+ case 'v' :
+ flag |= MAX(EXAR_FLAG_V, MIN(EXAR_VERBOSE_MASK, ((flag & EXAR_VERBOSE_MASK) << 1)));
+ break;
+ case 'h' :
+ exar_help(EXIT_SUCCESS);
+ default :
+ exar_help(EXIT_FAILURE);
+ }
+ options++;
+ }
+ if (flag & EXAR_VERBOSE_MASK)
+ exar_verbose(flag);
+
+ if (EXAR_CHECK_FLAG(flag, EXAR_FLAG_U))
+ exar_unpack(argv[1], argv[2]);
+ else if (EXAR_CHECK_FLAG(flag, EXAR_FLAG_P))
+ exar_pack(argv[1]);
+ else if (EXAR_CHECK_FLAG(flag, EXAR_FLAG_I))
+ exar_info(argv[1]);
+ else if (EXAR_CHECK_FLAG(flag, EXAR_FLAG_C) && argc > 2)
+ exar_cat(argv[1], argv[2]);
+ else if (EXAR_CHECK_FLAG(flag, EXAR_FLAG_D) && argc > 2)
+ exar_delete(argv[1], argv[2]);
+ else if (EXAR_CHECK_FLAG(flag, EXAR_FLAG_E) && argc > 2)
+ exar_xextract(argv[1], argv[2], exar_extract);
+ else if (EXAR_CHECK_FLAG(flag, EXAR_FLAG_S) && argc > 2)
+ exar_xextract(argv[1], argv[2], exar_search_extract);
+ else
+ exar_help(EXIT_FAILURE);
}
int
@@ -1186,8 +1300,8 @@ main(int argc, char **argv)
char **o_show_config = NULL;
char **o_edit = NULL;
char *o_proxy = NULL;
- char **o_pack = NULL;
- char **o_unpack = NULL;
+ char **o_archive_options = NULL;
+ gboolean o_archive = NULL;
gboolean o_noconfig = false;
gboolean o_update = false;
gboolean o_list_installed = false;
@@ -1213,8 +1327,8 @@ main(int argc, char **argv)
{ "proxy", 'p', 0, G_OPTION_ARG_STRING, &o_proxy, "HTTP-proxy to use", NULL },
{ "upgrade", 'u', 0, G_OPTION_ARG_NONE, &o_update, "Update all extensions", NULL },
{ "update", 'U', 0, G_OPTION_ARG_STRING_ARRAY, &o_update_ext, "Update <extension>", "<extension>" },
- { "archive-pack", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &o_pack, "Pack <path> to an archive", "<path>" },
- { "archive-unpack", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &o_unpack, "Unpack <archive>", "<archive>" },
+ { "archive", 0, 0, G_OPTION_ARG_NONE, &o_archive, "Create, open or modify extension archives", NULL },
+ { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &o_archive_options, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL },
};
@@ -1279,6 +1393,8 @@ main(int argc, char **argv)
list(m_installed, "Installed extensions", false);
if (o_update)
cl_update(flags);
+ if (o_archive)
+ parse_exar_options(o_archive_options);
for_each(o_update_ext, flags, cl_update_ext);
for_each(o_info, flags, cl_info);
@@ -1290,8 +1406,6 @@ main(int argc, char **argv)
for_each(o_install, flags, cl_install);
for_each(o_show_config, flags, cl_show_config);
for_each(o_edit, flags, cl_edit);
- for_each(o_pack, flags, cl_exar_pack);
- for_each(o_unpack, flags, cl_exar_unpack);
clean_up();
return 0;
diff --git a/exar/main.c b/exar/main.c
index 3e8474bc..c401c4ec 100644
--- a/exar/main.c
+++ b/exar/main.c
@@ -21,13 +21,14 @@
#include "exar.h"
enum {
- FLAG_V = 1<<0,
- FLAG_P = 1<<3,
- FLAG_U = 1<<4,
- FLAG_C = 1<<5,
- FLAG_E = 1<<6,
- FLAG_D = 1<<7,
- FLAG_I = 1<<8,
+ EXAR_FLAG_V = 1<<0,
+ EXAR_FLAG_P = 1<<3,
+ EXAR_FLAG_U = 1<<4,
+ EXAR_FLAG_C = 1<<5,
+ EXAR_FLAG_E = 1<<6,
+ EXAR_FLAG_D = 1<<7,
+ EXAR_FLAG_I = 1<<8,
+ EXAR_FLAG_S = 1<<9,
};
#ifndef MIN
#define MIN(X, Y) ((X) > (Y) ? (Y) : (X))
@@ -37,35 +38,54 @@ enum {
#endif
-#define OPTION_FLAG (0xffff & ~(0x7))
-#define CHECK_FLAG(x, flag) !!(((x) & (flag)) && !((x) & ( (OPTION_FLAG)^(flag) ) ))
+#define EXAR_OPTION_FLAG (0xffff & ~(0x7))
+#define EXAR_CHECK_FLAG(x, flag) !!(((x) & (flag)) && !((x) & ( (EXAR_OPTION_FLAG)^(flag) ) ))
void
help(int ret)
{
printf("USAGE: \n"
" exar option [arguments]\n\n"
"OPTIONS:\n"
- " h : Print this help and exit.\n"
- " c[v] archive file : Concatenates a file, directory or archive to \n"
+ " h Print this help and exit.\n"
+ " c[v] archive file Concatenates a file, directory or archive to \n"
" an existing archive.\n"
- " e[v] archive file : Extracts an file from an archive and writes the content\n"
+ " d[v] archive file Deletes a file from an archive, the file path is the\n"
+ " relative file path of the file in the archive\n"
+ " e[v] archive file Extracts a file from an archive and writes the content\n"
" to stdout, the archive is not modified, the file path \n"
" is the relative file path of the file in the archive.\n"
- " p[v] path : Pack file or directory 'path'.\n"
- " u[v] file [dir] : Pack 'file' to directory 'dir' or to \n"
- " current directory.\n"
- " v : Verbose, pass multiple times (up to 3) to \n"
+ " i[v] archive Prints info about an archive\n"
+ " p[v] path Pack file or directory 'path'.\n"
+ " s[v] archive file Search for a file and write the content to stdout, the \n"
+ " archive is not modified, the filename is the basename\n"
+ " plus suffix of the file in the archive, all directory\n"
+ " parts are stripped\n"
+ " u[v] file [dir] Pack 'file' to directory 'dir' or to current directory.\n"
+ " v Verbose, pass multiple times (up to 3) to \n"
" get more verbose messages.\n\n"
"EXAMPLES:\n"
" exar p /tmp/foo -- pack /tmp/foo to foo.exar\n"
" exar c foo.exar bar.txt -- Concatenates bar.txt to archive foo.exar\n"
" exar c foo.exar bar.exar -- Concatenates archive bar.exar to archive foo.exar\n"
- " exar uvvv foo.exar -- unpack foo.exar to current directory, \n"
+ " exar s foo.js > foo.js -- Extract foo.js from the archive\n"
+ " exar uvvv foo.exar -- unpack foo.exar to current directory,\n"
" verbosity level 3\n"
- " exar vu foo.exar /tmp -- unpack foo.exar to /tmp, verbosity \n"
+ " exar vu foo.exar /tmp -- unpack foo.exar to /tmp, verbosity\n"
" level 1\n");
exit(ret);
}
+static void
+extract(const char *archive, const char *path,
+ unsigned char * (*extract_func)(const char *, const char *, size_t *))
+{
+ size_t s;
+ unsigned char *content = extract_func(archive, path, &s);
+ if (content != NULL)
+ {
+ fwrite(content, 1, s, stdout);
+ free(content);
+ }
+}
int
main (int argc, char **argv)
{
@@ -80,25 +100,28 @@ main (int argc, char **argv)
switch (*options)
{
case 'p' :
- flag |= FLAG_P;
+ flag |= EXAR_FLAG_P;
break;
case 'u' :
- flag |= FLAG_U;
+ flag |= EXAR_FLAG_U;
break;
case 'c' :
- flag |= FLAG_C;
+ flag |= EXAR_FLAG_C;
break;
case 'e' :
- flag |= FLAG_E;
+ flag |= EXAR_FLAG_E;
break;
case 'd' :
- flag |= FLAG_D;
+ flag |= EXAR_FLAG_D;
break;
case 'i' :
- flag |= FLAG_I;
+ flag |= EXAR_FLAG_I;
+ break;
+ case 's' :
+ flag |= EXAR_FLAG_S;
break;
case 'v' :
- flag |= MAX(FLAG_V, MIN(EXAR_VERBOSE_MASK, ((flag & EXAR_VERBOSE_MASK) << 1)));
+ flag |= MAX(EXAR_FLAG_V, MIN(EXAR_VERBOSE_MASK, ((flag & EXAR_VERBOSE_MASK) << 1)));
break;
case 'h' :
help(EXIT_SUCCESS);
@@ -110,26 +133,20 @@ main (int argc, char **argv)
if (flag & EXAR_VERBOSE_MASK)
exar_verbose(flag);
- if (CHECK_FLAG(flag, FLAG_U))
+ if (EXAR_CHECK_FLAG(flag, EXAR_FLAG_U))
exar_unpack(argv[2], argv[3]);
- else if (CHECK_FLAG(flag, FLAG_P))
+ else if (EXAR_CHECK_FLAG(flag, EXAR_FLAG_P))
exar_pack(argv[2]);
- else if (CHECK_FLAG(flag, FLAG_I))
+ else if (EXAR_CHECK_FLAG(flag, EXAR_FLAG_I))
exar_info(argv[2]);
- else if (CHECK_FLAG(flag, FLAG_C) && argc > 3)
+ else if (EXAR_CHECK_FLAG(flag, EXAR_FLAG_C) && argc > 3)
exar_cat(argv[2], argv[3]);
- else if (CHECK_FLAG(flag, FLAG_D) && argc > 3)
+ else if (EXAR_CHECK_FLAG(flag, EXAR_FLAG_D) && argc > 3)
exar_delete(argv[2], argv[3]);
- else if (CHECK_FLAG(flag, FLAG_E) && argc > 3)
- {
- size_t s;
- unsigned char *content = exar_search_extract(argv[2], argv[3], &s);
- if (content != NULL)
- {
- fwrite(content, 1, s, stdout);
- free(content);
- }
- }
+ else if (EXAR_CHECK_FLAG(flag, EXAR_FLAG_E) && argc > 3)
+ extract(argv[2], argv[3], exar_extract);
+ else if (EXAR_CHECK_FLAG(flag, EXAR_FLAG_S) && argc > 3)
+ extract(argv[2], argv[3], exar_search_extract);
else
help(EXIT_FAILURE);