contrib/userspace-nvram:
authorJo-Philipp Wich <jow@openwrt.org>
Fri, 24 Apr 2009 23:38:45 +0000 (23:38 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Fri, 24 Apr 2009 23:38:45 +0000 (23:38 +0000)
- fix checksum calculation
- better handle invalid cli invokation
- get rid of hard coded erase size
- fix data type of crc8 function

contrib/userspace-nvram/cli.c
contrib/userspace-nvram/crc.c
contrib/userspace-nvram/nvram.c
contrib/userspace-nvram/nvram.h

index 3a07199..e3cd826 100644 (file)
@@ -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;
 }
index 22a3665..454a5a6 100644 (file)
@@ -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 */
 ) {
index a2ded14..a7425ec 100644 (file)
 
 #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 )
                {
index 4061991..86cc883 100644 (file)
@@ -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