Пример #1
0
long
cfg_get_number(const char *name, group_t *head) {
    variable_t *var = cfg_find_var(name, head);
    if (var && var->type == VT_NUMBER)
        return var->number;

    return 0;
}
Пример #2
0
static variable_t*
parse_expr(char **ptr, variable_t *var, group_t *head) {
    char value[MAXLINELEN];
    char *buf = value;
    size_t buflen = sizeof(value);
    int is_str = false;
    char *p = *ptr;
    long number;

    do {
        skip_whitespace(&p);
        if (!is_str && isdigit(*p)) {
            char *end;
            /* parse number */
            number = strtol(p, &end, 0);
            p = end;
        } else if (*p == '"' || *p == '\'') {
            char *s = parse_string(&p, buf, buflen);
            buf += strlen(s);
            buflen -= strlen(s);
            is_str = true;
        } else if (isalpha(*p)) {
            /* parse identifier */
            char ident[MAXIDLEN];
            variable_t *var;
            parse_identifier(&p, ident, sizeof(ident));
            var = cfg_find_var(ident, head);
            if (var  == NULL || var->type == VT_STRING) {
                const char *str = var ? var->str : ident;
                strncpy(buf, str, buflen);
                buflen -= strlen(str);
                buf += strlen(str);
                is_str = true;
            } else if (var && var->type == VT_NUMBER) {
                buflen -= snprintf(buf, buflen, "0x%lx", var->number);
            } else {
                fprintf(stderr, "%s:%d: listitem used in expression!\n", __func__, lineno);
                break;
            }
        } else {
            fprintf(stderr, "%s:%d: unknown token!\n", __func__, lineno);
            break;
        }
        skip_whitespace(&p);
        if (is_str && *p == '.' && p[1] == '.') {
            p += 2;
        } else {
            break;
        }
    } while( true );

    if (is_str) {
        var->type = VT_STRING;
        var->str = strdup(value);
    } else {
        var->type = VT_NUMBER;
        var->number = number;
    }

    *ptr = p;

    return var;
}
Пример #3
0
static int
pack_image(const char *indn, const char *outfn)
{
    struct imagewty_header *header;
    group_t *head, *filelist;
    uint32_t i, num_files;
    variable_t *var;
    FILE *cfp, *ofp;
    void *p;

    /* try to open image configuration */
    cfp = dir_fopen(indn, "image.cfg", "r");
    if (cfp == NULL) {
        fprintf(stderr, "Error: unable to open %s/%s!\n", indn, "image.cfg");
        return -ENOENT;
    }

    ofp = fopen(outfn, "wb");
    if (ofp == NULL) {
        fprintf(stderr, "Error: could not create image file %s!\n", outfn);
        fclose(cfp);
        return -ENOENT;
    }

    /* file is there, now try to load it */
    head = cfg_load(cfp);
    fclose(cfp);
    if (head == NULL) {
        fprintf(stderr, "Error: failed to parse %s/%s!\n", indn, "image.cfg");
        return -EINVAL;
    }

    /* Got configuration, time to start packing it all up! */
    var = cfg_find_var("filelist", head);
    if (var == NULL || var->type != VT_STRING) {
        fprintf(stderr, "Error: Unable to find filelist string "
                        "variable in configuration!\n");
        cfg_free(head);
        return -EINVAL;
    }

    filelist = cfg_find_group(var->str, head);
    if (filelist == NULL) {
        fprintf(stderr, "Error: unable to find group %s!\n", var->str);
        cfg_free(head);
        return -EINVAL;
    }

    num_files = cfg_count_vars(filelist);
    if (!num_files) {
        fprintf(stderr, "Error: no files to pack found in configuration!\n");
        cfg_free(head);
        return -EINVAL;
    }

    p = malloc(1024 + num_files * 1024);
    if (p == NULL) {
        fprintf(stderr, "Error: failed to allocate memory for image!\n");
        cfg_free(head);
        return -ENOMEM;
    }

    /* Initialize image file header */
    memset(p, 0, 1024 + num_files * 1024);
    header = p;
    memcpy(header->magic, IMAGEWTY_MAGIC, sizeof(header->magic));
    header->header_version = 0x0100;
    header->header_size = 0x50; /* should be 0x60 for version == 0x0300 */
    header->ram_base = 0x04D00000;
    header->version = cfg_get_number("version", head);
    header->image_size = 0; /* this will be filled in later on */
    header->image_header_size = 1024;
    header->v1.pid = cfg_get_number("pid", head);
    header->v1.vid = cfg_get_number("vid", head);
    header->v1.hardware_id = cfg_get_number("hardwareid", head);
    header->v1.firmware_id = cfg_get_number("firmwareid", head);
    header->v1.val1 = 1;
    header->v1.val1024 = 1024;
    header->v1.num_files = num_files;
    header->v1.num_files = cfg_count_vars(filelist);
    header->v1.val1024_2 = 1024;

    /* Setup file headers */
    {
        uint32_t offset = (num_files +1) * 1024;
        struct imagewty_file_header *fheaders;
        variable_t *var;

        fheaders = (struct imagewty_file_header*) (p + 1024);
        for(var=filelist->vars; var; var=var->next) {
            variable_t *v, *fn = NULL, *mt = NULL, *st = NULL;
            uint32_t size;
            FILE *fp;
            for (v=var->items; v; v=v->next) {
                if (v->type != VT_STRING)
                    continue;
                if (strcmp(v->name, "filename") == 0)
                    fn = v;
                else if (strcmp(v->name, "maintype") == 0)
                    mt = v;
                else if (strcmp(v->name, "subtype") == 0)
                    st = v;
            }

            if (!fn || !mt || !st) {
                fprintf(stderr, "Error: incomplete filelist item!\n");
                return -EINVAL;
            }

            fheaders->filename_len = IMAGEWTY_FHDR_FILENAME_LEN;
            fheaders->total_header_size = 1024;
            strcpy((char*)fheaders->v1.filename, fn->str);
            strcpy((char*)fheaders->maintype, mt->str);
            strcpy((char*)fheaders->subtype, st->str);

            fp = dir_fopen(indn, fn->str, "rb");
            if (fp) {
                fseek(fp, 0, SEEK_END);
                size = ftell(fp);
                fclose(fp);
            } else {
                fprintf(stderr, "Error: unable to read file '%s'!\n", fn->str);
                continue;
            }

            fheaders->v1.offset = offset;
            fheaders->v1.stored_length =
            fheaders->v1.original_length = size;
            if (fheaders->v1.stored_length & 0x1FF) {
                fheaders->v1.stored_length &= ~0x1FF;
                fheaders->v1.stored_length += 0x200;
            }
            offset += fheaders->v1.stored_length;
            fheaders = (struct imagewty_file_header*) ((uint8_t*)fheaders + 1024);
        }

        /* We now know the total size of the file; patch it into the main header */
        if (offset & 0xFF)
            offset = (offset & 0xFF) + 0x100;

        header->image_size = offset;
    }

    /* Now we have all headers setup in memory, time to write out the image file */
    fwrite(p, 1024, num_files +1, ofp);

    /* now write the file content too */
    for (i = 1; i <= num_files; i++) {
        struct imagewty_file_header *h =
            (struct imagewty_file_header*)(p + i * 1024);

        FILE *fp = dir_fopen(indn, h->v1.filename, "rb");
        if (fp != NULL) {
            char buf[512];
            size_t size = 0;
            while(!feof(fp)) {
                size_t bytesread = fread(buf, 1, 512, fp);
                if (bytesread) {
                    if (bytesread & 0x1ff)
                        bytesread = (bytesread & ~0x1ff) + 0x200;

                    if (flag_encryption_enabled)
                        rc6_encrypt_inplace(buf, bytesread, &filecontent_ctx);
                    fwrite(buf, 1, bytesread, ofp);
                }
                size += bytesread;
            }
            fclose(fp);
        }
    }

    /* Headers no longer used; encrypt and write if requested */
    if (flag_encryption_enabled) {
        void *curr = rc6_encrypt_inplace(p, 1024, &header_ctx);
        rc6_encrypt_inplace(curr, num_files * 1024, &fileheaders_ctx);
        rewind(ofp);
        fwrite(p, 1024, num_files +1, ofp);
    }

    fclose(ofp);

    /* Done, free configuration, no longer needed */
    cfg_free(head);

    return 0;
}