summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorportix <portix@gmx.net>2014-02-25 12:25:12 +0100
committerportix <portix@gmx.net>2014-02-25 12:25:12 +0100
commit40ecd77dc6b63a6e2ebb5505dac93aa505b2e864 (patch)
treea5e4aefbb8aa2b3447272971c0e5733987f6f18f
parent18c3d8eb49cba7b1d25d79092134393a23053537 (diff)
downloaddwb-40ecd77dc6b63a6e2ebb5505dac93aa505b2e864.zip
dwbem: install archive files
-rw-r--r--dwbem/Makefile2
-rw-r--r--dwbem/dwbem.c54
-rw-r--r--exar/Makefile4
-rw-r--r--exar/exar.c191
-rw-r--r--exar/exar.h41
-rw-r--r--exar/main.c10
6 files changed, 249 insertions, 53 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..08a887c4 100644
--- a/dwbem/dwbem.c
+++ b/dwbem/dwbem.c
@@ -47,8 +47,10 @@
#include <exar.h>
-#define API_BASE "https://api.bitbucket.org/1.0/repositories/portix/dwb_extensions/src/tip/src/?format=yaml"
-#define REPO_BASE "https://bitbucket.org/portix/dwb_extensions"
+//#define API_BASE "https://api.bitbucket.org/1.0/repositories/portix/dwb_extensions/src/tip/src/?format=yaml"
+#define API_BASE "https://api.bitbucket.org/1.0/repositories/portix/dwbemtest/src/tip/src/?format=yaml"
+//#define REPO_BASE "https://bitbucket.org/portix/dwb_extensions"
+#define REPO_BASE "https://bitbucket.org/portix/dwbemtest"
#define REPO_TREE "/raw/tip/src"
#define SKIP(line, c) do{ \
@@ -252,11 +254,17 @@ 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);
+ if (exar_check_version(data) == 0) {
+ content = (char*)exar_search_extract(data, "main.js", NULL);
+ }
+ else {
+ g_file_get_contents(data, &content, NULL, NULL);
+ }
new_data = content;
}
if (new_data != NULL)
@@ -690,6 +698,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 +707,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;
+ }
+ g_free(content);
+ }
+ else if (g_file_get_contents(buffer, &content, NULL, NULL) )
{
if (add_to_loader(name, content, flags) == 0)
{
@@ -722,11 +740,21 @@ 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;
}
+ if (content != NULL) {
+ g_free(content);
+ }
}
else
print_error("Saving %s failed", name);
@@ -1109,8 +1137,18 @@ cl_info(const char *name, int flags)
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(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);
+ g_free(mainfile);
+ }
+ }
+ else {
+ data = get_data(NULL, msg->response_body->data, "INFO", F_MATCH_MULTILINE | F_MATCH_CONTENT);
+ }
+ }
unwind:
if (data != NULL)
{
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..725d35dd 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,47 @@ 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 != '\0')
+ {
+ head->eh_name[i] = *tmp;
+ i++;
+ tmp++;
+ if (i == EXAR_NAME_MAX)
+ {
+ fprintf(stderr, "Cannot get filename\n");
+ return EE_ERROR;
+ }
+ }
+ // terminating null byte
+ *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 +304,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 +341,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 +356,15 @@ 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;
}
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 +378,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 +657,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 +798,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..34ee5490 100644
--- a/exar/exar.h
+++ b/exar/exar.h
@@ -102,6 +102,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 +146,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 +153,16 @@ int
exar_check_version(const char *archive);
/*
+ * Checks if the given data is an archive file with compatible version number
+ *
+ * @data The archive
+ *
+ * @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 +198,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);