diff options
author | portix <portix@gmx.net> | 2014-03-01 14:38:57 +0100 |
---|---|---|
committer | portix <portix@gmx.net> | 2014-03-01 14:38:57 +0100 |
commit | e99f0b6f536d025e65887246d5f99b632d5d9890 (patch) | |
tree | 6592b99009234a5755019719b7487a43ff5495a6 | |
parent | 7344c775a2bd483f27e6bdb9549f13a1ceb177a7 (diff) | |
parent | 3751c1c0e5f530a9f8d743e35c2dd6b741c5cddc (diff) | |
download | dwb-e99f0b6f536d025e65887246d5f99b632d5d9890.zip |
Merge branch 'dwbem'
Conflicts:
src/scripts.c
-rw-r--r-- | dwbem/Makefile | 2 | ||||
-rw-r--r-- | dwbem/dwbem.c | 106 | ||||
-rw-r--r-- | exar/Makefile | 4 | ||||
-rw-r--r-- | exar/exar.c | 197 | ||||
-rw-r--r-- | exar/exar.h | 42 | ||||
-rw-r--r-- | exar/main.c | 10 | ||||
-rw-r--r-- | src/dwb.c | 6 | ||||
-rw-r--r-- | src/scripts.c | 27 |
8 files changed, 308 insertions, 86 deletions
diff --git a/dwbem/Makefile b/dwbem/Makefile index ef0b5860..d67a767f 100644 --- a/dwbem/Makefile +++ b/dwbem/Makefile @@ -15,7 +15,7 @@ SYSTEM_EXTENSION_DIR=$(PREFIX)/share/dwb/extensions CFLAGS := $(CFLAGS) CFLAGS += -std=c99 -CFLAGS += -Wall -g +CFLAGS += -Wall -g -O0 CFLAGS += -Wextra -Werror=format-security CFLAGS += $(shell pkg-config --cflags $(LIBS)) CFLAGS += -DSYSTEM_EXTENSION_DIR=\"$(SYSTEM_EXTENSION_DIR)\" diff --git a/dwbem/dwbem.c b/dwbem/dwbem.c index 374240ca..660df898 100644 --- a/dwbem/dwbem.c +++ b/dwbem/dwbem.c @@ -241,7 +241,7 @@ static char * get_data(const char *name, const char *data, const char *template, int flags) { char *ret = NULL; - char *content = NULL, *regex = NULL; + char *content = NULL, *regex = NULL, *econtent = NULL; const char *new_data = NULL; const char *format; const char *nname = name == NULL ? "" : name; @@ -252,12 +252,19 @@ get_data(const char *name, const char *data, const char *template, int flags) format = "(?<=^|\n)//<%s%s|//>%s%s\\s*(?=\n|$)"; regex = g_strdup_printf(format, nname, template, nname, template); - if (flags & F_MATCH_CONTENT) + if (flags & F_MATCH_CONTENT) { new_data = data; + } else { - g_file_get_contents(data, &content, NULL, NULL); - new_data = content; + if (exar_check_version(data) == 0) { + econtent = (char*)exar_search_extract(data, "main.js", NULL); + new_data = econtent; + } + else { + g_file_get_contents(data, &content, NULL, NULL); + new_data = content; + } } if (new_data != NULL) { @@ -267,6 +274,7 @@ get_data(const char *name, const char *data, const char *template, int flags) g_strfreev(matches); } g_free(content); + exar_free(econtent); g_free(regex); return ret; } @@ -430,11 +438,19 @@ diff(const char *text1, const char *text2, char **ret, int ntf) char *text2_new = g_strdup_printf("// THIS FILE WILL BE DISCARDED\n%s// THIS FILE WILL BE DISCARDED", text2); if (g_file_set_contents(file1, text1, -1, &e) && g_file_set_contents(file2, text2_new, -1, &e)) { - char *args[4]; - args[0] = (char *)m_diff; - args[1] = file1; - args[2] = file2; - args[3] = NULL; + gboolean use_vim = strcmp(m_diff, "vimdiff") == 0; + int nargs = use_vim ? 6 : 4; + int argc = 0; + + char *args[nargs]; + args[argc++] = (char *)m_diff; + if (use_vim) { + args[argc++] = "-c"; + args[argc++] = "set ft=javascript"; + } + args[argc++] = file1; + args[argc++] = file2; + args[argc++] = NULL; spawn_success = g_spawn_sync(NULL, args, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_CHILD_INHERITS_STDIN, NULL, NULL, NULL, NULL, NULL, NULL); if (spawn_success) @@ -467,10 +483,18 @@ edit(const char *text) if (g_file_set_contents(file, text, -1, NULL)) { - char *args[3]; - args[0] = (char*)m_editor; - args[1] = file; - args[2] = NULL; + gboolean use_vim = strcmp(m_editor, "vim") == 0; + int nargs = use_vim ? 5 : 3; + int argc = 0; + + char *args[nargs]; + args[argc++] = (char*)m_editor; + if (use_vim) { + args[argc++] = "-c"; + args[argc++] = "set ft=javascript"; + } + args[argc++] = file; + args[argc++] = NULL; spawn_success = g_spawn_sync(NULL, args, NULL, G_SPAWN_SEARCH_PATH | G_SPAWN_CHILD_INHERITS_STDIN, NULL, NULL, NULL, NULL, NULL, NULL); if (spawn_success) @@ -539,7 +563,7 @@ set_loader(const char *name, const char *config, int flags) } if (! g_file_test(m_loader, G_FILE_TEST_EXISTS) ) { - char *file_content = g_strdup_printf("//!javascript\n%s", script); + char *file_content = g_strdup_printf("//!javascript\n/*\n * AUTOGENERATED - DO NOT EDIT THIS FILE, USE dwbem -E <extension> INSTEAD!\n */\n\n%s", script); g_file_set_contents(m_loader, file_content, -1, NULL); g_free(file_content); } @@ -690,6 +714,7 @@ install_extension(const char *name, int flags) char buffer[512]; char meta[128]; char *content = NULL; + const char *tmp = NULL; if (grep(m_meta_data, name, meta, sizeof(meta)) == -1) die(1, "extension %s not found", name); @@ -698,7 +723,16 @@ install_extension(const char *name, int flags) if (g_file_test(buffer, G_FILE_TEST_EXISTS)) { notify("Using %s", buffer); - if (g_file_get_contents(buffer, &content, NULL, NULL) ) + if (exar_check_version(buffer) == 0) { + content = (char*) exar_search_extract(buffer, "main.js", NULL); + if (add_to_loader(name, content, flags) == 0) + { + update_installed(name, meta); + ret = 0; + } + exar_free(content); + } + else if (g_file_get_contents(buffer, &content, NULL, NULL) ) { if (add_to_loader(name, content, flags) == 0) { @@ -722,11 +756,19 @@ install_extension(const char *name, int flags) snprintf(buffer, sizeof(buffer), "%s/%s", m_user_dir, name); if (set_content(buffer, msg->response_body->data, msg->response_body->length)) { - if (add_to_loader(name, msg->response_body->data, flags) == 0) + if (exar_check_version(buffer) == 0) { + content = (char *)exar_search_extract(buffer, "main.js", NULL); + tmp = content; + } + else { + tmp = msg->response_body->data; + } + if (add_to_loader(name, tmp, flags) == 0) { update_installed(name, meta); ret = 0; } + exar_free(content); } else print_error("Saving %s failed", name); @@ -1091,30 +1133,42 @@ cl_info(const char *name, int flags) (void) flags; SoupMessage *msg = NULL; - char *data = NULL, *path; + char *path, *data = NULL; const char *tmp; path = g_build_filename(m_system_dir, name, NULL); - if ((data = get_data(NULL, path, "INFO", F_MATCH_MULTILINE)) != NULL) + if ((data = get_data(NULL, path, "INFO", F_MATCH_MULTILINE)) != NULL) { + tmp = data; goto unwind; - FREE0(data); + } g_free(path); path = g_build_filename(m_user_dir, name, NULL); - if ((data = get_data(NULL, path, "INFO", F_MATCH_MULTILINE)) != NULL) + if ((data = get_data(NULL, path, "INFO", F_MATCH_MULTILINE)) != NULL) { + tmp = data; goto unwind; - FREE0(data); + } g_free(path); path = g_strconcat(REPO_BASE REPO_TREE, "/", name, NULL); msg = soup_message_new("GET", path); int status = soup_session_send_message(session, msg); - if (status == 200) - data = get_data(NULL, msg->response_body->data, "INFO", F_MATCH_MULTILINE | F_MATCH_CONTENT); + if (status == 200) { + if (exar_check_version_from_data((unsigned char *)msg->response_body->data, msg->response_body->length) == 0) { + char *mainfile = (char *)exar_search_extract_from_data((unsigned char *)msg->response_body->data, "main.js", NULL); + if (mainfile != NULL) { + data = get_data(NULL, mainfile, "INFO", F_MATCH_MULTILINE | F_MATCH_CONTENT); + exar_free(mainfile); + } + } + else { + data = get_data(NULL, msg->response_body->data, "INFO", F_MATCH_MULTILINE | F_MATCH_CONTENT); + } + tmp = data; + } unwind: - if (data != NULL) + if (tmp != NULL) { - tmp = data; SKIP_SPACE(tmp); printf("\033[1m%s\033[0m - %s", name, tmp); } @@ -1226,7 +1280,7 @@ exar_xextract(const char *archive, const char *path, { fprintf(stderr, "Error extracting %s from %s\n", path, archive); } - free(content); + exar_free(content); } } void diff --git a/exar/Makefile b/exar/Makefile index f6717ef4..4f8e99da 100644 --- a/exar/Makefile +++ b/exar/Makefile @@ -1,6 +1,6 @@ ORIG_CFLAGS := $(CFLAGS) -CFLAGS := -Wall -pedantic -Werror -Wextra -std=c99 -Os +CFLAGS := -Wall -pedantic -Werror -Wextra -std=c99 -O0 -g CFLAGS += $(ORIG_CFLAGS) DCFLAGS += -g -O0 -Wall -pedantic -Werror -Wextra -std=c99 @@ -25,7 +25,7 @@ debug: make CFLAGS="$(DCFLAGS)" cgdb: - make CFLAGS="$(DCFLAGS)" + make CFLAGS="$(DCFLAGS)" exar cgdb exar clean: diff --git a/exar/exar.c b/exar/exar.c index 298c0631..f2d9231a 100644 --- a/exar/exar.c +++ b/exar/exar.c @@ -112,23 +112,13 @@ get_offset(char *buffer, size_t n, const char *path, int *end) return offset; } static int -check_version(FILE *f, int verbose) -{ - unsigned char version[SZ_VERSION] = {0}; +version_cmp(const unsigned char *data, int verbose) { unsigned char orig_version[SZ_VERSION] = {0}; - LOG(2, "Reading version header\n"); - if (fread(version, 1, SZ_VERSION, f) != SZ_VERSION) - { - if (feof(f)) - return EE_EOF; - else - { - if (verbose) - fprintf(stderr, "Not an exar file?\n"); - return EE_ERROR; - } - } + unsigned char version[SZ_VERSION] = {0}; + + memcpy(version, data, sizeof(version)); memcpy(orig_version, EXAR_VERSION, sizeof(orig_version)); + LOG(2, "Checking filetype\n"); if (strncmp((char*)version, EXAR_VERSION_BASE, 5)) { @@ -137,7 +127,7 @@ check_version(FILE *f, int verbose) return EE_ERROR; } - LOG(2, "Found version %s\n", version); + LOG(2, "Found version %s\n", data); if (memcmp(version, orig_version, SZ_VERSION)) { if (verbose) @@ -146,6 +136,24 @@ check_version(FILE *f, int verbose) } return EE_OK; } +static int +check_version(FILE *f, int verbose) +{ + unsigned char version[SZ_VERSION] = {0}; + LOG(2, "Reading version header\n"); + if (fread(version, 1, SZ_VERSION, f) != SZ_VERSION) + { + if (feof(f)) + return EE_EOF; + else + { + if (verbose) + fprintf(stderr, "Not an exar file?\n"); + return EE_ERROR; + } + } + return version_cmp(version, verbose); +} /* * Opens archive and checks version, mode is either read or read-write * */ @@ -172,11 +180,35 @@ close_file(FILE *f, const char *archive) } static int +check_header(struct exar_header_s *head, const char *size) { + char *endptr; + off_t fs; + if (head->eh_flag != DIR_FLAG && head->eh_flag != FILE_FLAG) + { + LOG(1, "No file flag found\n"); + fprintf(stderr, "The archive seems to be corrupted\n"); + return EE_ERROR; + } + if (head->eh_flag == FILE_FLAG) + { + fs = strtol(size, &endptr, 16); + if (*endptr) + { + LOG(1, "Cannot determine file size\n"); + fprintf(stderr, "The archive seems to be corrupted\n"); + return EE_ERROR; + } + head->eh_size = fs; + } + else + head->eh_size = 0; + return EE_OK; +} + +static int get_file_header(FILE *f, struct exar_header_s *head) { - char *endptr; char header[HDR_NAME]; - off_t fs; char rb; size_t i = 0; int st_version = 0; @@ -193,25 +225,9 @@ get_file_header(FILE *f, struct exar_header_s *head) head->eh_flag = header[HDR_DFLAG]; - if (head->eh_flag != DIR_FLAG && head->eh_flag != FILE_FLAG) - { - LOG(1, "No file flag found\n"); - fprintf(stderr, "The archive seems to be corrupted\n"); + if (check_header(head, &header[HDR_SIZE]) == EE_ERROR) { return EE_ERROR; } - if (head->eh_flag == FILE_FLAG) - { - fs = strtol(&header[HDR_SIZE], &endptr, 16); - if (*endptr) - { - LOG(1, "Cannot determine file size\n"); - fprintf(stderr, "The archive seems to be corrupted\n"); - return EE_ERROR; - } - head->eh_size = fs; - } - else - head->eh_size = 0; while (fread(&rb, 1, 1, f) > 0) { @@ -230,6 +246,50 @@ get_file_header(FILE *f, struct exar_header_s *head) return EE_OK; } static int +get_file_header_from_data(const unsigned char *data, int *offset, struct exar_header_s *head) +{ + char size[SZ_SIZE]; + size_t i = 0; + int st_version = 0; + const unsigned char *tmp = data;; + + *offset = 0; + + if ((st_version = version_cmp(tmp, 0)) != EE_OK) + return st_version; + tmp += SZ_VERSION; + + LOG(2, "Reading file header\n"); + memcpy(&(head->eh_flag), tmp, SZ_DFLAG); + tmp += SZ_DFLAG; + memcpy(size, tmp, SZ_SIZE); + tmp += SZ_SIZE; + + if (check_header(head, size) == EE_ERROR) { + return EE_ERROR; + } + *offset = SZ_VERSION + SZ_DFLAG + SZ_SIZE; + while (*tmp && *tmp != '\0') + { + head->eh_name[i] = *tmp; + i++; + tmp++; + if (i == EXAR_NAME_MAX) + { + fprintf(stderr, "Cannot get filename\n"); + return EE_ERROR; + } + } + if (*tmp != '\0') { + LOG(1, "The archive seems to be corrupted\n"); + return EE_ERROR; + } + *offset += i+1; + + LOG(2, "Found file header (%s, %c, %jd)\n", head->eh_name, head->eh_flag, (intmax_t)head->eh_size); + return EE_OK; +} +static int next_file(FILE *f, struct exar_header_s *header) { if (*(header->eh_name)) @@ -247,7 +307,7 @@ next_file(FILE *f, struct exar_header_s *header) static int find_cmp(const char *name, const char *search) { - char buffer[EXAR_NAME_MAX]; + char buffer[EXAR_NAME_MAX] = {0}; if (strcmp(name, search) != 0) { size_t offset = get_offset(buffer, EXAR_NAME_MAX, name, NULL); @@ -284,7 +344,7 @@ extract(const char *archive, const char *file, off_t *s, int (*cmp)(const char * FILE *f = NULL; unsigned char *ret = NULL; if (s != NULL) - *s = 0; + *s = -1; if ((f = open_archive(archive, "r")) == NULL) goto finish; @@ -299,15 +359,14 @@ extract(const char *archive, const char *file, off_t *s, int (*cmp)(const char * if (fread(ret, 1, header.eh_size, f) != (size_t)header.eh_size) { fprintf(stderr, "Failed to read %s\n", header.eh_name); - *s = -1; - free(ret); - ret = NULL; + exar_free(ret); } else if (s != NULL) *s = header.eh_size; } - else + else { fprintf(stderr, "%s is a directory, only regular files can be extracted\n", file); + } goto finish; } else if (header.eh_flag == FILE_FLAG) @@ -321,6 +380,37 @@ finish: close_file(f, archive); return ret; } +static unsigned char * +extract_from_data(const unsigned char *data, const char *file, off_t *s, int (*cmp)(const char *, const char *)) { + (void) data, (void) s, (void) cmp, (void) file; + unsigned char *ret = NULL; + struct exar_header_s header = EXAR_HEADER_EMPTY; + int offset = 0; + + if (s != NULL) + *s = -1; + + while((get_file_header_from_data(data, &offset, &header) == EE_OK)) { + data += offset; + if (cmp(header.eh_name, file) == 0) { + if (header.eh_flag == FILE_FLAG) { + ret = xcalloc(header.eh_size, sizeof(unsigned char)); + memcpy(ret, data, header.eh_size); + if (s != NULL) { + *s = header.eh_size; + } + return ret; + } + else { + fprintf(stderr, "%s is a directory, only regular files can be extracted\n", file); + return NULL; + } + } + data += header.eh_size; + } + fprintf(stderr, "File %s was not found.\n", file); + return NULL; +} static int write_file_header(FILE *f, const char *name, char flag, off_t r) @@ -569,6 +659,20 @@ exar_search_extract(const char *archive, const char *file, off_t *s) return extract(archive, file, s, find_cmp); } +unsigned char * +exar_extract_from_data(const unsigned char *data, const char *file, off_t *s) +{ + assert(data != NULL); + + return extract_from_data(data, file, s, strcmp); +} +unsigned char * +exar_search_extract_from_data(const unsigned char *data, const char *file, off_t *s) +{ + assert(data != NULL); + + return extract_from_data(data, file, s, find_cmp); +} int exar_delete(const char *archive, const char *file) { @@ -696,8 +800,17 @@ exar_check_version(const char *archive) close_file(f, archive); return result; } +int +exar_check_version_from_data(const unsigned char *data, size_t s) +{ + assert(data != NULL); + + if (s < SZ_VERSION) + return EE_ERROR; + return version_cmp(data, 0) == EE_OK ? EE_OK : EE_ERROR; +} void -exar_verbose(unsigned char v) +exar_verbose(const unsigned char v) { s_verbose = v & EXAR_VERBOSE_MASK; } diff --git a/exar/exar.h b/exar/exar.h index 5bae266c..805c7f0e 100644 --- a/exar/exar.h +++ b/exar/exar.h @@ -46,6 +46,7 @@ enum { EXAR_VERBOSE_L3 = 1<<2, }; #define EXAR_VERBOSE_MASK (0x7) +#define exar_free(x) ((x) = (x) == NULL ? NULL : (free(x), NULL)) /* * Packs a file or directory @@ -102,6 +103,34 @@ exar_extract(const char *archive, const char *file, off_t *size); unsigned char * exar_search_extract(const char *archive, const char *search, off_t *size); +/* + * Searches for a file and extracts the content from raw archive data. + * + * @data The data + * @file The path of the file in the archive + * @size Return location for the size, if an error occurs size will be set to -1 + * + * @returns A newly allocated char buffer with the file content or NULL if an error + * occured or the file was not found in the archive + * */ +unsigned char * +exar_extract_from_data(const unsigned char *data, const char *file, off_t *size); + +/* + * Searches for a file and extracts the content from raw archive data + * + * @data The data + * @search The search term. The search term must either match the full path or + * the filename + * @size Return location for the size, if an error occurs size will be set to -1 + * + * @returns A newly allocated char buffer with the file content or NULL if an error + * occured or the file was not found in the archive + * */ + +unsigned char * +exar_search_extract_from_data(const unsigned char *data, const char *file, off_t *size); + /* * Deletes a file from the archive, if it is a directory it is removed * recursively. @@ -118,7 +147,6 @@ exar_delete(const char *archive, const char *file); * Checks if the file is an archive file with compatible version number * * @archive The archive - * @verbose Whether to print error messages to stderr * * @returns 0 on success and -1 on error */ @@ -126,6 +154,16 @@ int exar_check_version(const char *archive); /* + * Checks if the given data is an archive file with compatible version number + * + * @data The raw archive data + * + * @returns 0 on success and -1 on error + */ +int +exar_check_version_from_data(const unsigned char *data, size_t s); + +/* * Print info about the archive to stdout. * * @archive The archive @@ -161,5 +199,5 @@ exar_search_contains(const char *archive, const char *search); * @v_flags */ void -exar_verbose(unsigned char v_flags); +exar_verbose(const unsigned char v_flags); #endif diff --git a/exar/main.c b/exar/main.c index 0255f397..48217039 100644 --- a/exar/main.c +++ b/exar/main.c @@ -91,6 +91,16 @@ int main (int argc, char **argv) { int flag = 0; + char buffer[4096] = {0}; + FILE *f = fopen(argv[1], "r"); + exar_verbose(EXAR_VERBOSE_MASK); + fread(buffer, 1, 4096, f); + puts(buffer); + char *data = (char*)exar_extract_from_data((unsigned char *)buffer, "foo/main.js", NULL); + puts(data); + //printf("%d %lu\n", exar_check_version_from_data(buffer), strlen(buffer)); + fclose(f); + return 0; if (argc < 3) { help(EXIT_FAILURE); @@ -3632,9 +3632,11 @@ dwb_get_scripts() if (exar_check_version(path) == 0) { content = (char *) exar_search_extract(path, "main.js", NULL); - if (content != NULL) + if (content != NULL) { scripts_init_archive(path, content); - goto loop_end; + exar_free(content); + } + continue; } else if ( (f = fopen(path, "r")) != NULL) { diff --git a/src/scripts.c b/src/scripts.c index de8e749b..5bfaf671 100644 --- a/src/scripts.c +++ b/src/scripts.c @@ -2348,7 +2348,8 @@ global_include(JSContextRef ctx, JSObjectRef f, JSObjectRef this, size_t argc, c { JSValueRef ret = NIL; gboolean global = false; - char *path = NULL, *content = NULL; + char *path = NULL, *content = NULL, *econtent = NULL; + const char *script; JSValueRef exports[1]; gboolean is_archive = false; @@ -2363,34 +2364,38 @@ global_include(JSContextRef ctx, JSObjectRef f, JSObjectRef this, size_t argc, c if (exar_check_version(path) == 0) { - content = (char*) exar_search_extract(path, "main.js", NULL); - if (content == NULL) + econtent = (char*) exar_search_extract(path, "main.js", NULL); + if (econtent == NULL) { js_make_exception(ctx, exc, EXCEPTION("include: main.js was not found in %s."), path); goto error_out; } exports[0] = get_exports(ctx, path); is_archive = true; + script = econtent; } - else if ( (content = util_get_file_content(path, NULL)) == NULL) + else if ( (content = util_get_file_content(path, NULL)) != NULL) { + script = content; + } + else { js_make_exception(ctx, exc, EXCEPTION("include: reading %s failed."), path); goto error_out; } - const char *tmp = content; - if (*tmp == '#') + if (*script == '#') { do { - tmp++; - } while(*tmp && *tmp != '\n'); - tmp++; + script++; + } while(*script && *script != '\n'); + script++; } - ret = do_include(ctx, path, tmp, global, is_archive, is_archive ? 1 : 0, is_archive ? exports : NULL, exc); + ret = do_include(ctx, path, script, global, is_archive, is_archive ? 1 : 0, is_archive ? exports : NULL, exc); error_out: g_free(content); + exar_free(econtent); g_free(path); return ret; }/*}}}*/ @@ -2531,7 +2536,7 @@ global_xinclude(JSContextRef ctx, JSObjectRef f, JSObjectRef thisObject, size_t ret = do_include(ctx, archive, content, false, true, 1, exports, exc); } g_free(archive); - g_free(content); + exar_free(content); return ret; } |