environ.c

Go to the documentation of this file.
00001 /*
00002  * Copyright 2008 by egnite Software GmbH
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the copyright holders nor the names of
00014  *    contributors may be used to endorse or promote products derived
00015  *    from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00018  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00019  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00020  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00021  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00022  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00023  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00024  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00025  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00026  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00027  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00028  * SUCH DAMAGE.
00029  *
00030  * For additional information see http://www.ethernut.de/
00031  */
00032 
00033 #include <dev/nvmem.h>
00034 
00035 #include <stdint.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038 
00039 #include <sys/environ.h>
00040 
00041 NUTENVIRONMENT *nut_environ;
00042 
00043 /*
00044  * Read string from non-volatile memory.
00045  */
00046 static size_t read_string(int *addr, char *buf, size_t siz)
00047 {
00048     size_t rc = 0;
00049     char ch;
00050 
00051     while (rc <= siz) {
00052         if (NutNvMemLoad(*addr, &ch, 1)) {
00053             rc = 0;
00054             break;
00055         }
00056         (*addr)++;
00057         if (ch == 0) {
00058             break;
00059         }
00060         if (buf) {
00061             *buf++ = ch;
00062         }
00063         rc++;
00064     }
00065     if (buf) {
00066         *buf = 0;
00067     }
00068     return rc;
00069 }
00070 
00079 NUTENVIRONMENT *findenv(CONST char *name)
00080 {
00081     NUTENVIRONMENT *envp;
00082     size_t len;
00083     size_t max_len = 0;
00084     char *buf;
00085 
00086     if (nut_environ == NULL) {
00087         /* Load environment from non-volatile memory. */
00088         uint32_t magic;
00089         int addr = ENVIRON_EE_OFFSET;
00090         NUTENVIRONMENT *prvp = NULL;
00091 
00092         if (NutNvMemLoad(addr, &magic, sizeof(magic)) == 0 && magic == ENVIRON_MAGIC) {
00093             addr += 4;
00094             /* Determine the maximum string length. */
00095             while ((len = read_string(&addr, NULL, MAX_ENVIRON_ITEM_SIZE)) > 0) {
00096                 if (len > max_len) {
00097                     max_len = len;
00098                 }
00099                 len = read_string(&addr, NULL, MAX_ENVIRON_ITEM_SIZE);
00100                 if (len > max_len) {
00101                     max_len = len;
00102                 }
00103             }
00104             /* Read the environment. */
00105             addr = ENVIRON_EE_OFFSET + sizeof(magic);
00106             if (max_len && (buf = malloc(max_len + 1)) != NULL) {
00107                 while ((len = read_string(&addr, buf, max_len)) > 0) {
00108                     if ((envp = malloc(sizeof(NUTENVIRONMENT))) == NULL) {
00109                         break;
00110                     }
00111                     memset(envp, 0, sizeof(NUTENVIRONMENT));
00112                     if ((envp->env_name = malloc(len + 1)) == NULL) {
00113                         free(envp);
00114                         break;
00115                     }
00116                 strcpy(envp->env_name, buf);
00117                     len = read_string(&addr, buf, max_len);
00118                     if ((envp->env_value = malloc(len + 1)) == NULL) {
00119                         break;
00120                     }
00121                     strcpy(envp->env_value, buf);
00122                 if (prvp) {
00123                     prvp->env_next = envp;
00124                         envp->env_prev = prvp;
00125                 } else {
00126                 nut_environ = envp;
00127                 }
00128                     prvp = envp;
00129                 }
00130                 free(buf);
00131             }
00132         }
00133     }
00134     for (envp = nut_environ; envp; envp = envp->env_next) {
00135         if (strcmp(envp->env_name, name) == 0) {
00136         break;
00137         }
00138     }
00139     return envp;
00140 }
00141 

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/