From: Jo-Philipp Wich Date: Fri, 24 Apr 2009 23:38:45 +0000 (+0000) Subject: contrib/userspace-nvram: X-Git-Tag: 0.9.0~505 X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fluci.git;a=commitdiff_plain;h=a8da3a09a3fb34327cf02306726dad640e309f20 contrib/userspace-nvram: - fix checksum calculation - better handle invalid cli invokation - get rid of hard coded erase size - fix data type of crc8 function --- diff --git a/contrib/userspace-nvram/cli.c b/contrib/userspace-nvram/cli.c index 3a071994c..e3cd826d7 100644 --- a/contrib/userspace-nvram/cli.c +++ b/contrib/userspace-nvram/cli.c @@ -89,6 +89,7 @@ int main( int argc, const char *argv[] ) int commit = 0; int write = 0; int stat = 1; + int done = 0; int i; /* Ugly... iterate over arguments to see whether we can expect a write */ @@ -102,42 +103,39 @@ int main( int argc, const char *argv[] ) } - if( (nvram = write ? nvram_open_staging() : nvram_open_rdonly()) != NULL ) + if( (nvram = write ? nvram_open_staging() : nvram_open_rdonly()) != NULL && argc > 1 ) { for( i = 1; i < argc; i++ ) { if( !strcmp(argv[i], "show") ) { stat = do_show(nvram); + done++; } else if( !strcmp(argv[i], "get") && ++i < argc ) { stat = do_get(nvram, argv[i]); + done++; } else if( !strcmp(argv[i], "unset") && ++i < argc ) { stat = do_unset(nvram, argv[i]); + done++; } else if( !strcmp(argv[i], "set") && ++i < argc ) { stat = do_set(nvram, argv[i]); + done++; } else if( !strcmp(argv[i], "commit") ) { commit = 1; + done++; } else { - fprintf(stderr, - "Usage:\n" - " nvram show\n" - " nvram get variable\n" - " nvram set variable=value [set ...]\n" - " nvram unset variable [unset ...]\n" - " nvram commit\n" - ); - - return 1; + done = 0; + break; } } @@ -150,5 +148,31 @@ int main( int argc, const char *argv[] ) stat = staging_to_nvram(); } + if( !nvram ) + { + fprintf(stderr, + "Could not open nvram! Possible reasons are:\n" + " - No device found (/proc not mounted or no nvram present)\n" + " - Insufficient permissions to open mtd device\n" + " - Insufficient memory to complete operation\n" + " - Memory mapping failed or not supported\n" + ); + + stat = 1; + } + else if( !done ) + { + fprintf(stderr, + "Usage:\n" + " nvram show\n" + " nvram get variable\n" + " nvram set variable=value [set ...]\n" + " nvram unset variable [unset ...]\n" + " nvram commit\n" + ); + + stat = 1; + } + return stat; } diff --git a/contrib/userspace-nvram/crc.c b/contrib/userspace-nvram/crc.c index 22a36652a..454a5a682 100644 --- a/contrib/userspace-nvram/crc.c +++ b/contrib/userspace-nvram/crc.c @@ -58,7 +58,7 @@ static const uint8_t crc8_table[256] = { }; uint8_t hndcrc8 ( - uint8_t * pdata, /* pointer to array of data to process */ + const char * pdata, /* pointer to array of data to process */ uint32_t nbytes, /* number of input data bytes to process */ uint8_t crc /* either CRC8_INIT_VALUE or previous return value */ ) { diff --git a/contrib/userspace-nvram/nvram.c b/contrib/userspace-nvram/nvram.c index a2ded149a..a7425ecca 100644 --- a/contrib/userspace-nvram/nvram.c +++ b/contrib/userspace-nvram/nvram.c @@ -14,9 +14,12 @@ #include "nvram.h" -#define TRACE() \ - printf("%s(%i) in %s()\n", \ - __FILE__, __LINE__, __FUNCTION__) +#define TRACE(msg) \ + printf("%s(%i) in %s(): %s\n", \ + __FILE__, __LINE__, __FUNCTION__, msg ? msg : "?") + +size_t nvram_erase_size = 0; + /* * -- Helper functions -- @@ -91,18 +94,15 @@ static nvram_tuple_t * _nvram_realloc( nvram_handle_t *h, nvram_tuple_t *t, /* (Re)initialize the hash table. */ static int _nvram_rehash(nvram_handle_t *h) { - nvram_header_t *header = (nvram_header_t *) &h->mmap[NVRAM_SPACE]; - char buf[] = "0xXXXXXXXX", *name, *value, *end, *eq; + nvram_header_t *header = (nvram_header_t *) &h->mmap[NVRAM_START(nvram_erase_size)]; + char buf[] = "0xXXXXXXXX", *name, *value, *eq; /* (Re)initialize hash table */ _nvram_free(h); /* Parse and set "name=value\0 ... \0\0" */ name = (char *) &header[1]; - /* - end = (char *) header + NVRAM_SPACE - 2; - end[0] = end[1] = '\0'; - */ + for (; *name; name = value + strlen(value) + 1) { if (!(eq = strchr(name, '='))) break; @@ -251,7 +251,7 @@ nvram_tuple_t * nvram_getall(nvram_handle_t *h) /* Regenerate NVRAM. */ int nvram_commit(nvram_handle_t *h) { - nvram_header_t *header = (nvram_header_t *) &h->mmap[NVRAM_SPACE]; + nvram_header_t *header = (nvram_header_t *) &h->mmap[NVRAM_START(nvram_erase_size)]; char *init, *config, *refresh, *ncdl; char *ptr, *end; int i; @@ -280,6 +280,7 @@ int nvram_commit(nvram_handle_t *h) /* Clear data area */ ptr = (char *) header + sizeof(nvram_header_t); memset(ptr, 0xFF, NVRAM_SPACE - sizeof(nvram_header_t)); + memset(&tmp, 0, sizeof(nvram_header_t)); /* Leave space for a double NUL at the end */ end = (char *) header + NVRAM_SPACE - 2; @@ -328,15 +329,28 @@ nvram_handle_t * nvram_open(const char *file, int rdonly) nvram_handle_t *h; nvram_header_t *header; + /* If erase size or file are undefined then try to define them */ + if( (nvram_erase_size == 0) || (file == NULL) ) + { + /* Finding the mtd will set the appropriate erase size */ + if( file == NULL ) + file = nvram_find_mtd(); + else + (void) nvram_find_mtd(); + + if( nvram_erase_size == 0 ) + return NULL; + } + if( (fd = open(file, O_RDWR)) > -1 ) { char *mmap_area = (char *) mmap( - NULL, 0x10000, PROT_READ | PROT_WRITE, + NULL, nvram_erase_size, PROT_READ | PROT_WRITE, ( rdonly == NVRAM_RO ) ? MAP_PRIVATE : MAP_SHARED, fd, 0); if( mmap_area != MAP_FAILED ) { - memset(mmap_area, 0xFF, NVRAM_SPACE); + memset(mmap_area, 0xFF, NVRAM_START(nvram_erase_size)); if((h = (nvram_handle_t *) malloc(sizeof(nvram_handle_t))) != NULL) { @@ -344,9 +358,9 @@ nvram_handle_t * nvram_open(const char *file, int rdonly) h->fd = fd; h->mmap = mmap_area; - h->length = 0x10000; + h->length = nvram_erase_size; - header = (nvram_header_t *) &h->mmap[NVRAM_SPACE]; + header = (nvram_header_t *) &h->mmap[NVRAM_START(nvram_erase_size)]; if( header->magic == NVRAM_MAGIC ) { @@ -379,27 +393,30 @@ int nvram_close(nvram_handle_t *h) /* Determine NVRAM device node. */ const char * nvram_find_mtd(void) { - //return "./samples/nvram.1"; - FILE *fp; - int i; + int i, esz; char dev[PATH_MAX]; - char *path; + char *path = NULL; - // "/dev/mtdblock/" + ( 0 < x < 99 ) + "ro" + \0 = 19 + // "/dev/mtdblock/" + ( 0 < x < 99 ) + \0 = 19 if( (path = (char *) malloc(19)) == NULL ) return NULL; if ((fp = fopen("/proc/mtd", "r"))) { while (fgets(dev, sizeof(dev), fp)) { - if (sscanf(dev, "mtd%d:", &i) && strstr(dev, "nvram")) { - snprintf(path, 19, "/dev/mtdblock/%d", i); + if (strstr(dev, "nvram") && sscanf(dev, "mtd%d: %08x", &i, &esz)) { + if( (path = (char *) malloc(19)) != NULL ) + { + nvram_erase_size = esz; + snprintf(path, 19, "/dev/mtdblock/%d", i); + break; + } } } fclose(fp); } - return (const char *) path; + return path; } /* Check NVRAM staging file. */ @@ -419,12 +436,12 @@ const char * nvram_find_staging(void) int nvram_to_staging(void) { int fdmtd, fdstg, stat; - const char *mtd; - char buf[0x10000]; + const char *mtd = nvram_find_mtd(); + char buf[nvram_erase_size]; stat = -1; - if( (mtd = nvram_find_mtd()) != NULL ) + if( (mtd != NULL) && (nvram_erase_size > 0) ) { if( (fdmtd = open(mtd, O_RDONLY)) > -1 ) { @@ -451,12 +468,12 @@ int nvram_to_staging(void) int staging_to_nvram(void) { int fdmtd, fdstg, stat; - const char *mtd; - char buf[0x10000]; + const char *mtd = nvram_find_mtd(); + char buf[nvram_erase_size]; stat = -1; - if( (mtd = nvram_find_mtd()) != NULL ) + if( (mtd != NULL) && (nvram_erase_size > 0) ) { if( (fdstg = open(NVRAM_STAGING, O_RDONLY)) > -1 ) { diff --git a/contrib/userspace-nvram/nvram.h b/contrib/userspace-nvram/nvram.h index 406199111..86cc883e1 100644 --- a/contrib/userspace-nvram/nvram.h +++ b/contrib/userspace-nvram/nvram.h @@ -82,7 +82,7 @@ int nvram_close(nvram_handle_t *h); #define nvram_safe_get(h, name) (nvram_get(h, name) ? : "") /* Computes a crc8 over the input data. */ -uint8_t hndcrc8 (uint8_t * pdata, uint32_t nbytes, uint8_t crc ); +uint8_t hndcrc8 (const char * pdata, uint32_t nbytes, uint8_t crc ); /* Returns the crc value of the nvram. */ uint8_t nvram_calc_crc(nvram_header_t * nvh); @@ -113,12 +113,13 @@ const char * nvram_find_staging(void); #define NVRAM_SOFTWARE_VERSION "1" /* NVRAM constants */ +#define NVRAM_SPACE 0x8000 +#define NVRAM_START(x) x - NVRAM_SPACE #define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ #define NVRAM_CLEAR_MAGIC 0x0 #define NVRAM_INVALID_MAGIC 0xFFFFFFFF #define NVRAM_VERSION 1 #define NVRAM_HEADER_SIZE 20 -#define NVRAM_SPACE 0x8000 #define NVRAM_MAX_VALUE_LEN 255 #define NVRAM_MAX_PARAM_LEN 64