/* * params.c -- Device parameter file handling. * * Copyright (C) 2016 Tomasz Kramkowski * * This program 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, either version 3 of the License, or * (at your option) any later version. * * This program 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 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "eprintf.h" #include "params.h" #include "util.h" /* TODO: make this dynamic */ #define SZMAX_PFILE 1024 char *datadir; /* readparams: read a file's param definition */ void readparams(struct flashparams *fp, const char *file) { char cont[SZMAX_PFILE], *pos; size_t contsz; FILE *f; assert(file); assert(fp); f = fopen(file, "r"); if (f == NULL) eprintf("Could not open '%s':", file); contsz = fread(cont, 1, SZMAX_PFILE, f); if (contsz >= sizeof cont) eprintf("Parameter file '%s' is longer than %zu", file, sizeof cont - 1); pos = cont; for (int i = 0; i < 4; i++) { char *end; unsigned long long val; errno = 0; val = strtoull(pos, &end, 0); if (pos == end) eprintf("Parameter file '%s' is malformed (offset:%zd not a number)", file, pos - cont); pos = end; if (errno == ERANGE || val > SIZE_MAX) eprintf("Parameter file '%s' is malformed (offset:%zd number too large)", file, pos - cont); switch (i) { case 0: fp->memsz = val; break; case 1: fp->blksz = val; break; case 2: fp->cmdsz = val; break; case 3: fp->addrshft = val; break; } } fclose(f); } static void printcname(const char *file) { bool wasspace; FILE *f; int c, field; assert(file); f = fopen(file, "r"); if (f == NULL) { printf(": Malformed file '%s'", file); return; } field = 0; wasspace = false; while (c = fgetc(f), c != EOF) { if (isspace(c)) { wasspace = true; continue; } if (wasspace) { wasspace = false; field++; } if (field >= 4) { ungetc(c, f); break; } } if (c == EOF) return; printf(": "); while (c = fgetc(f), c != EOF) if (c != '\n') putchar(c); } /* listparams: Print a list of the parameter files which could be found */ void listparams(void) { char pathbuf[PATH_MAX], *fullpath; struct dirent *de; size_t pathsize; DIR *dir; fullpath = pathbuf; pathsize = sizeof pathbuf; dir = opendir(datadir); if (dir == NULL) eprintf("Could not open directory '%s':", datadir); while (errno = 0, de = readdir(dir), de != NULL) { int size; if (de->d_name[0] == '.') continue; size = snprintf(NULL, 0, "%s/%s", datadir, de->d_name); assert(size > 0); if ((size_t)size > pathsize) { if (fullpath == pathbuf) fullpath = NULL; fullpath = erealloc(fullpath, size); pathsize = size; } size = snprintf(fullpath, pathsize, "%s/%s", datadir, de->d_name); assert(size > 0); assert((size_t)size < pathsize); printf("%s", de->d_name); printcname(fullpath); putchar('\n'); } if (errno) weprintf("Could not read directory '%s':", datadir); if (fullpath != pathbuf) free(fullpath); if (closedir(dir) == -1) eprintf("Could not close directory '%s':", datadir); }