From 65bdef55ab12bf07aa52fb9c184c073cbf562e3b Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Tue, 19 Jan 2016 15:10:29 +0000 Subject: move the container code to gtk directory as its only ever used there. --- utils/container.c | 763 ------------------------------------------------------ utils/container.h | 53 ---- 2 files changed, 816 deletions(-) delete mode 100644 utils/container.c delete mode 100644 utils/container.h (limited to 'utils') diff --git a/utils/container.c b/utils/container.c deleted file mode 100644 index 68ea32211..000000000 --- a/utils/container.c +++ /dev/null @@ -1,763 +0,0 @@ -/* - * Copyright 2006 Rob Kendrick - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* To build a stand-alone command-line utility to create and dismantal - * these theme files, build this thusly: - * - * gcc -I../ -DNSTHEME -o themetool container.c - * - * [needs a c99 compiler] - * - * then for instance to create a theme file called mythemefilename - * ./themetool --verbose --create -n"My theme name" mythemefilename\ - * --author "Myname" /path/to/directory/containing/theme/files/ - */ - -/** \file - * Container format handling for themes etc. */ - -#include -#include -#include -#include -#include -#include -#include -#include "utils/config.h" -#include "utils/container.h" -#include "utils/log.h" -#include "utils/messages.h" -#include "utils/utils.h" - -#ifdef WITH_MMAP -#include -#endif - -#ifdef NSTHEME -bool verbose_log = true; -#endif - -struct container_dirent { - unsigned char filename[64]; - u_int32_t startoffset; - u_int32_t len; - u_int32_t flags1; - u_int32_t flags2; -}; - -struct container_header { - u_int32_t magic; /* 0x4d54534e little endian */ - u_int32_t parser; - unsigned char name[32]; - unsigned char author[64]; - u_int32_t diroffset; -}; - -struct container_ctx { - FILE *fh; - bool creating; - bool processed; - struct container_header header; - unsigned int entries; - unsigned char *data; - struct container_dirent *directory; -}; - -inline static size_t container_filelen(FILE *fd) -{ - long o; - long a; - - o = ftell(fd); - if (o == -1) { - LOG("Could not get current stream position"); - return 0; - } - - if (fseek(fd, 0, SEEK_END) != 0) { - LOG("Could not get seek to end of file"); - return 0; - } - a = ftell(fd); - - if (fseek(fd, o, SEEK_SET) != 0) { - LOG("Could not reset seek position in file"); - return 0; - } - if (a == -1) { - LOG("could not ascertain size of file in theme container; omitting"); - return 0; - } - if (((unsigned long) a) > SIZE_MAX) { - LOG("overlarge file in theme container; possible truncation"); - return SIZE_MAX; - } - return (size_t) a; -} - -static void container_add_to_dir(struct container_ctx *ctx, - const unsigned char *entryname, - const u_int32_t offset, - const u_int32_t length) -{ - struct container_dirent *temp; - temp = realloc(ctx->directory, ctx->entries * - sizeof(struct container_dirent)); - if (temp == NULL) { - printf("error adding entry for %s to theme container\n", entryname); - return; - } - ctx->entries += 1; - ctx->directory = temp; - - snprintf((char*)ctx->directory[ctx->entries - 1].filename, - sizeof(ctx->directory[ctx->entries - 1].filename), - "%s", (char *)entryname); - - ctx->directory[ctx->entries - 1].startoffset = offset; - ctx->directory[ctx->entries - 1].len = length; - ctx->directory[ctx->entries - 1].flags1 = 0; - ctx->directory[ctx->entries - 1].flags2 = 0; -} - -struct container_ctx *container_open(const char *filename) -{ - size_t val; - struct container_ctx *ctx = calloc(sizeof(struct container_ctx), 1); - - ctx->fh = fopen(filename, "rb"); - - if (ctx->fh == NULL) { - free(ctx); - return NULL; - } - - /* we don't actually load any of the data (including directory) - * until we need to, such that _get_name and _get_author are as quick - * as possible. When we have, this gets set to true. - */ - ctx->processed = false; - - val = fread(&ctx->header.magic, 4, 1, ctx->fh); - if (val == 0) - LOG("empty read magic"); - ctx->header.magic = ntohl(ctx->header.magic); - - val = fread(&ctx->header.parser, 4, 1, ctx->fh); - if (val == 0) - LOG("empty read parser"); - ctx->header.parser = ntohl(ctx->header.parser); - - val = fread(ctx->header.name, 32, 1, ctx->fh); - if (val == 0) - LOG("empty read name"); - val = fread(ctx->header.author, 64, 1, ctx->fh); - if (val == 0) - LOG("empty read author"); - - val = fread(&ctx->header.diroffset, 4, 1, ctx->fh); - if (val == 0) - LOG("empty read diroffset"); - ctx->header.diroffset = ntohl(ctx->header.diroffset); - - if (ctx->header.magic != 0x4e53544d || ctx->header.parser != 3) { - fclose(ctx->fh); - free(ctx); - return NULL; - } - - return ctx; -} - -static void container_process(struct container_ctx *ctx) -{ - size_t val; - unsigned char filename[64]; - u_int32_t start, len, flags1, flags2; - -#ifdef WITH_MMAP - ctx->data = mmap(NULL, ctx->header.diroffset, PROT_READ, MAP_PRIVATE, - fileno(ctx->fh), 0); -#else - ctx->data = malloc(ctx->header.diroffset); - if (fseek(ctx->fh, 0, SEEK_SET) != 0) { - return; - } - val = fread(ctx->data, ctx->header.diroffset, 1, ctx->fh); - if (val == 0) - LOG("empty read diroffset"); -#endif - if (fseek(ctx->fh, ctx->header.diroffset, SEEK_SET) != 0) { - return; - } - /* now work through the directory structure taking it apart into - * our structure */ -#define BEREAD(x) do { val = fread(&(x), 4, 1, ctx->fh); if (val == 0)\ - LOG("empty read");(x) = ntohl((x)); } while (0) - do { - val = fread(filename, 64, 1, ctx->fh); - if (val == 0) - LOG("empty read filename"); - BEREAD(start); - BEREAD(len); - BEREAD(flags1); - BEREAD(flags2); - if (filename[0] != '\0') - container_add_to_dir(ctx, filename, start, len); - } while (filename[0] != '\0'); -#undef BEREAD - ctx->processed = true; -} - -static const struct container_dirent *container_lookup( - struct container_ctx *ctx, - const unsigned char *entryname) -{ - unsigned int i; - - for (i = 1; i <= ctx->entries; i++) { - struct container_dirent *e = ctx->directory + i - 1; - if (strcmp((char *)e->filename, (char *)entryname) == 0) - return e; - } - - return NULL; -} - -const unsigned char *container_get(struct container_ctx *ctx, - const unsigned char *entryname, - u_int32_t *size) -{ - const struct container_dirent *e; - - if (ctx->processed == false) - container_process(ctx); - - e = container_lookup(ctx, entryname); - - if (e == NULL) - return NULL; - - *size = e->len; - - return &ctx->data[e->startoffset]; -} - -const unsigned char *container_iterate(struct container_ctx *ctx, int *state) -{ - struct container_dirent *e; - unsigned char *r; - - if (ctx->processed == false) - container_process(ctx); - - e = ctx->directory + *state; - - r = e->filename; - - if (r == NULL || r[0] == '\0') - r = NULL; - - *state += 1; - - return r; -} - -const unsigned char *container_get_name(struct container_ctx *ctx) -{ - return ctx->header.name; -} - -const unsigned char *container_get_author(struct container_ctx *ctx) -{ - return ctx->header.author; -} - - -static void container_write_dir(struct container_ctx *ctx) -{ - size_t val; - unsigned int i; - u_int32_t tmp; -#define BEWRITE(x) do {tmp = htonl((x)); val = fwrite(&tmp, 4, 1, ctx->fh);\ - if (val == 0) LOG("empty write"); } while(0) - for (i = 1; i <= ctx->entries; i++) { - struct container_dirent *e = ctx->directory + i - 1; - val = fwrite(e->filename, 64, 1, ctx->fh); - if (val == 0) - LOG("empty write filename"); - BEWRITE(e->startoffset); - BEWRITE(e->len); - BEWRITE(e->flags1); - BEWRITE(e->flags2); - } -#undef BEWRITE - /* empty entry signifies end of directory */ - tmp = 0; - val = fwrite(&tmp, 4, 8, ctx->fh); - if (val == 0) - LOG("empty write end"); -} - -struct container_ctx *container_create(const char *filename, - const unsigned char *name, - const unsigned char *author) -{ - size_t val; - struct container_ctx *ctx = calloc(sizeof(struct container_ctx), 1); - - ctx->fh = fopen(filename, "wb"); - - if (ctx->fh == NULL) { - free(ctx); - return NULL; - } - - ctx->creating = true; - ctx->entries = 0; - ctx->directory = NULL; - ctx->header.parser = htonl(3); - - snprintf((char *)ctx->header.name, - sizeof(ctx->header.name), - "%s", (char *)name); - - snprintf((char *)ctx->header.author, - sizeof(ctx->header.author), - "%s", (char *)author); - - val = fwrite("NSTM", 4, 1, ctx->fh); - if (val == 0) - LOG("empty write NSTM"); - val = fwrite(&ctx->header.parser, 4, 1, ctx->fh); - if (val == 0) - LOG("empty write parser"); - val = fwrite(ctx->header.name, 32, 1, ctx->fh); - if (val == 0) - LOG("empty write name"); - val = fwrite(ctx->header.author, 64, 1, ctx->fh); - if (val == 0) - LOG("empty write author"); - - ctx->header.diroffset = 108; - - /* skip over the directory offset for now, and fill it in later. - * we don't know where it'll be yet! - */ - - if (fseek(ctx->fh, 108, SEEK_SET) == -1) { - LOG("directory offset seek failed"); - free(ctx); - return NULL; - } - - return ctx; -} - -void container_add(struct container_ctx *ctx, const unsigned char *entryname, - const unsigned char *data, - const u_int32_t datalen) -{ - size_t val; - container_add_to_dir(ctx, entryname, ftell(ctx->fh), datalen); - val = fwrite(data, datalen, 1, ctx->fh); - if (val == 0) - LOG("empty write add file"); -} - -void container_close(struct container_ctx *ctx) -{ - if (ctx->creating == true) { - size_t flen, nflen, val; - - /* discover where the directory's going to go. */ - flen = container_filelen(ctx->fh); - flen = (flen + 3) & (~3); /* round up to nearest 4 bytes */ - - /* write this location to the header */ - if (fseek(ctx->fh, 104, SEEK_SET) == 0) { - nflen = htonl(flen); - val = fwrite(&nflen, 4, 1, ctx->fh); - if (val == 0) - LOG("empty write directory location"); - - /* seek to where the directory will be, and write it */ - if (fseek(ctx->fh, flen, SEEK_SET) == 0) { - container_write_dir(ctx); - } - } - - } else if (ctx->processed) { -#ifdef WITH_MMAP - munmap(ctx->data, ctx->header.diroffset); -#else - free(ctx->data); -#endif - } - - fclose(ctx->fh); - free(ctx); -} - -#ifdef WITH_THEME_INSTALL - -/** - * install theme from container - * \param themefile a file containing the containerized theme - * \param dirbasename a directory basename including trailing path sep; the - * full path of the theme is then a subdirectory of that - * caller owns reference to returned string, NULL for error - */ - -char *container_extract_theme(const char *themefile, const char *dirbasename) -{ - struct stat statbuf; - struct container_ctx *cctx; - FILE *fh; - size_t val; - const unsigned char *e, *d; - char *themename, *dirname; - char path[PATH_MAX]; - int state = 0; - unsigned int i; - u_int32_t flen; - - cctx = container_open(themefile); - if (cctx == NULL) { - warn_user("FileOpenError", themefile); - return NULL; - } - themename = strdup((const char *)container_get_name(cctx)); - if (themename == NULL) { - warn_user("NoMemory", 0); - container_close(cctx); - return NULL; - } - LOG("theme name: %s", themename); - LOG("theme author: %s", container_get_author(cctx)); - - dirname = malloc(strlen(dirbasename) + strlen(themename) + 2); - if (dirname == NULL) { - warn_user(messages_get("NoMemory"), 0); - free(themename); - container_close(cctx); - return NULL; - } - strcpy(dirname, dirbasename); - strcat(dirname, themename); - if (stat(dirname, &statbuf) != -1) { - /* directory exists */ - warn_user("DirectoryError", dirname); - container_close(cctx); - free(dirname); - free(themename); - return NULL; - } - if (mkdir(dirname, S_IRWXU) != 0) { - warn_user("DirectoryError", dirname); - container_close(cctx); - free(dirname); - free(themename); - return NULL; - } - - for (e = container_iterate(cctx, &state), i = 0; i < cctx->entries; - e = container_iterate(cctx, &state), i++) { - LOG("extracting %s", e); - snprintf(path, PATH_MAX, "%s/%s", dirname, e); - fh = fopen(path, "wb"); - if (fh == NULL) { - warn_user("FileOpenError", (char *)e); - } else { - d = container_get(cctx, e, &flen); - val = fwrite(d, flen, 1, fh); - if (val == 0) - LOG("empty write"); - fclose(fh); - } - } - LOG("theme container unpacked"); - container_close(cctx); - free(dirname); - return themename; - -} - -#endif - -#ifdef TEST_RIG -int main(int argc, char *argv[]) -{ - struct container_ctx *ctx = container_create("test.theme", "Test theme", - "Rob Kendrick"); - u_int32_t size; - int state = 0; - char *n; - - container_add(ctx, "CHEESE", "This is a test of some cheese.", sizeof("This is a test of some cheese.")); - container_add(ctx, "FOO", "This is a test of some cheese.", sizeof("This is a test of some cheese.")); - - container_close(ctx); - - ctx = container_open("test.theme"); - - printf("Theme name: %s\n", container_get_name(ctx)); - printf("Theme author: %s\n", container_get_author(ctx)); - - printf("Test string: %s\n", container_get(ctx, "CHEESE", &size)); - printf("Length of text: %d\n", size); - - while ( (n = container_iterate(ctx, &state)) ) { - printf("%s\n", n); - } - - container_close(ctx); - - exit(0); -} -#endif - -#ifdef NSTHEME - /* code to implement a simple container creator/extractor */ -#include -#include -#include -#include - -static bool verbose = false; - -static void show_usage(const char *argv0) -{ - fprintf(stderr, "%s [options] \n", argv0); - fprintf(stderr, " --help This text\n"); - fprintf(stderr, " --create Create theme file from directory\n"); - fprintf(stderr, " --extract Extract theme file into directory\n"); - fprintf(stderr, " --name x Set theme's name when creating\n"); - fprintf(stderr, " --author x Set theme's author when creating\n"); - fprintf(stderr, " --verbose Print progress information\n"); - fprintf(stderr, "\nOne and only one of --create or --extract must be specified.\n"); -} - -static void extract_theme(const char *themefile, const char *dirname) -{ - struct stat statbuf; - struct container_ctx *cctx; - FILE *fh; - const unsigned char *e, *d; - char path[PATH_MAX]; - int i, state = 0; - u_int32_t flen; - - - if (stat(dirname, &statbuf) != -1) { - fprintf(stderr, "error: directory '%s' already exists.\n", - dirname); - exit(1); - } - - mkdir(dirname, S_IRWXU); - - cctx = container_open(themefile); - if (cctx == NULL) { - fprintf(stderr, "error: unable to open theme file '%s'\n", - themefile); - exit(1); - } - - if (verbose == true) { - printf("theme name: %s\n", container_get_name(cctx)); - printf("theme author: %s\n", container_get_author(cctx)); - } - - for (e = container_iterate(cctx, &state), i = 0; i < cctx->entries; - e = container_iterate(cctx, &state), i++) { - if (verbose == true) - printf("extracting %s\n", e); - snprintf(path, PATH_MAX, "%s/%s", dirname, e); - fh = fopen(path, "wb"); - if (fh == NULL) { - perror("warning: unable to open file for output"); - } else { - d = container_get(cctx, e, &flen); - fwrite(d, flen, 1, fh); - fclose(fh); - } - } - - container_close(cctx); - -} - -static void create_theme(const char *themefile, const char *dirname, - const unsigned char *name, - const unsigned char *author) -{ - DIR *dir = opendir(dirname); - FILE *fh; - struct dirent *e; - struct stat statbuf; - struct container_ctx *cctx; - unsigned char *data; - char path[PATH_MAX]; - size_t flen; - int t; - - if (dir == NULL) { - perror("error: unable to open directory"); - exit(1); - } - - cctx = container_create(themefile, name, author); - - errno = 0; /* to distinguish between end of dir and err */ - - while ((e = readdir(dir)) != NULL) { - if (strcmp(e->d_name, ".") != 0 && - strcmp(e->d_name, "..") != 0) { - /* not the metadirs, so we want to process this. */ - if (verbose == true) - printf("adding %s\n", e->d_name); - if (strlen(e->d_name) > 63) { - fprintf(stderr, - "warning: name truncated to length 63.\n"); - } - - snprintf(path, PATH_MAX, "%s/%s", dirname, e->d_name); - - stat(path, &statbuf); - if (S_ISDIR(statbuf.st_mode)) { - fprintf(stderr, - "warning: skipping directory '%s'\n", - e->d_name); - continue; - } - - fh = fopen(path, "rb"); - if (fh == NULL) { - fprintf(stderr, - "warning: unable to open, skipping."); - } else { - flen = statbuf.st_size; - data = malloc(flen); - t = fread(data, flen, 1, fh); - fclose(fh); - container_add(cctx, (unsigned char *)e->d_name, - data, flen); - free(data); - } - } - errno = 0; - } - - if (errno != 0) { - perror("error: couldn't enumerate directory"); - closedir(dir); - container_close(cctx); - exit(1); - } - - closedir(dir); - container_close(cctx); -} - -int main(int argc, char *argv[]) -{ - static struct option l_opts[] = { - { "help", 0, 0, 'h' }, - { "create", 0, 0, 'c' }, - { "extract", 0, 0, 'x' }, - { "name", 1, 0, 'n' }, - { "author", 1, 0, 'a' }, - { "verbose", 0, 0, 'v' }, - - { NULL, 0, 0, 0 } - }; - - static char *s_opts = "hcxn:a:v"; - int optch, optidx; - bool creating = false, extracting = false; - unsigned char name[32] = { '\0' }, author[64] = { '\0' }; - char *themefile, *dirname; - - while ((optch = getopt_long(argc, argv, s_opts, l_opts, &optidx)) != -1) - switch (optch) { - case 'h': - show_usage(argv[0]); - exit(0); - break; - case 'c': - creating = true; - break; - case 'x': - extracting = true; - break; - case 'n': - strncpy((char *)name, optarg, 31); - if (strlen(optarg) > 32) - fprintf(stderr, "warning: theme name truncated to 32 characters.\n"); - break; - case 'a': - strncpy((char *)author, optarg, 63); - if (strlen(optarg) > 64) - fprintf(stderr, "warning: theme author truncated to 64 characters.\n"); - break; - case 'v': - verbose = true; - break; - default: - show_usage(argv[0]); - exit(1); - break; - } - - if (creating == extracting) { - show_usage(argv[0]); - exit(1); - } - - if ((argc - optind) < 2) { - show_usage(argv[0]); - exit(1); - } - - if (creating == true && - (strlen((char *)name) == 0 || strlen((char *)author) == 0)) { - fprintf(stderr, "No theme name and/or author specified.\n"); - show_usage(argv[0]); - exit(1); - } - - themefile = strdup(argv[optind]); - dirname = strdup(argv[optind + 1]); - - if (verbose == true) - printf("%s '%s' %s directory '%s'\n", - creating ? "creating" : "extracting", themefile, - creating ? "from" : "to", dirname); - - if (creating) { - if (verbose == true) - printf("name = %s, author = %s\n", name, author); - create_theme(themefile, dirname, name, author); - } else { - extract_theme(themefile, dirname); - } - - return 0; -} -#endif diff --git a/utils/container.h b/utils/container.h deleted file mode 100644 index de880ecd5..000000000 --- a/utils/container.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2006 Rob Kendrick - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** \file - * Container format handling for themes etc. */ - -#ifndef __CONTAINER_H__ -#define __CONTAINER_H__ - -#include - -struct container_ctx; - -/* reading interface */ -struct container_ctx *container_open(const char *filename); -const unsigned char *container_get(struct container_ctx *ctx, - const unsigned char *entryname, - u_int32_t *size); -const unsigned char *container_get_name(struct container_ctx *ctx); -const unsigned char *container_get_author(struct container_ctx *ctx); -const unsigned char *container_iterate(struct container_ctx *ctx, - int *state); - -/* creating interface */ -struct container_ctx *container_create(const char *filename, - const unsigned char *name, - const unsigned char *author); -void container_add(struct container_ctx *ctx, const unsigned char *entryname, - const unsigned char *data, - const u_int32_t datalen); - -/* common interface */ -void container_close(struct container_ctx *ctx); - -#ifdef WITH_THEME_INSTALL -char *container_extract_theme(const char *themefile, const char *dirbasename); -#endif -#endif /* __CONTAINER_H__ */ -- cgit v1.2.3