Annotation of embedtools/src/ub_env.c, revision 1.3

1.2       misho       1: /*************************************************************************
                      2:  * (C) 2014 AITNET - Sofia/Bulgaria - <office@aitbg.com>
                      3:  *  by Michael Pounov <misho@aitbg.com>
                      4:  *
                      5:  * $Author: misho $
1.3     ! misho       6:  * $Id: ub_env.c,v 1.2.14.1 2017/01/22 20:40:10 misho Exp $
1.2       misho       7:  *
                      8:  *************************************************************************
                      9: The ELWIX and AITNET software is distributed under the following
                     10: terms:
                     11: 
                     12: All of the documentation and software included in the ELWIX and AITNET
                     13: Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
                     14: 
1.3     ! misho      15: Copyright 2004 - 2017
1.2       misho      16:        by Michael Pounov <misho@elwix.org>.  All rights reserved.
                     17: 
                     18: Redistribution and use in source and binary forms, with or without
                     19: modification, are permitted provided that the following conditions
                     20: are met:
                     21: 1. Redistributions of source code must retain the above copyright
                     22:    notice, this list of conditions and the following disclaimer.
                     23: 2. Redistributions in binary form must reproduce the above copyright
                     24:    notice, this list of conditions and the following disclaimer in the
                     25:    documentation and/or other materials provided with the distribution.
                     26: 3. All advertising materials mentioning features or use of this software
                     27:    must display the following acknowledgement:
                     28: This product includes software developed by Michael Pounov <misho@elwix.org>
                     29: ELWIX - Embedded LightWeight unIX and its contributors.
                     30: 4. Neither the name of AITNET nor the names of its contributors
                     31:    may be used to endorse or promote products derived from this software
                     32:    without specific prior written permission.
                     33: 
                     34: THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND
                     35: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     36: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     37: ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     38: FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     39: DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     40: OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     41: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     42: LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     43: OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     44: SUCH DAMAGE.
                     45: */
                     46: #include "global.h"
                     47: #include "ub_env.h"
                     48: 
                     49: 
                     50: env_t *env;
                     51: 
                     52: static int
                     53: ub_flash_io(const char *csSec, int mode)
                     54: {
                     55:        int f, l, rlen;
                     56:        const char *str;
                     57:        ssize_t siz, esiz;
                     58:        ait_val_t v;
                     59:        u_int crc;
                     60: 
                     61:        FTRACE(4);
                     62: 
                     63:        str = cfg_getAttribute(&cfg, csSec, "drive_size");
                     64:        siz = strtol(str, NULL, 0);
                     65:        if (!siz)
                     66:                return -1;
                     67:        str = cfg_getAttribute(&cfg, csSec, "env_size");
                     68:        if (!str)
                     69:                esiz = siz - sizeof env->env_crc;
                     70:        else
                     71:                esiz = strtol(str, NULL, 0);
                     72:        str = cfg_getAttribute(&cfg, csSec, "drive_name");
                     73:        if (!str) {
                     74:                printf("Error:: drive not found!\n");
                     75:                return -1;
                     76:        }
                     77: 
                     78:        cfg_loadAttribute(&cfg, "ube", "lock", &v, UBE_LOCK);
                     79:        l = open(AIT_GET_STR(&v), O_CREAT | O_EXCL | O_WRONLY, 0644);
                     80:        if (l == -1) {
                     81:                printf("Error:: Locked u-boot-env map %s\n", AIT_GET_STR(&v));
                     82:                AIT_FREE_VAL(&v);
                     83:                return -1;
                     84:        }
                     85: 
                     86:        f = open(str, mode);
                     87:        if (f == -1) {
                     88:                printf("Error:: Can't access u-boot-env device %s\n", str);
                     89:                close(l);
                     90:                unlink(AIT_GET_STR(&v));
                     91:                AIT_FREE_VAL(&v);
                     92:                return -1;
                     93:        }
                     94: 
                     95:        if (mode & O_RDWR) {
                     96:                env->env_crc = crc_32(0, (u_char*) env->env_data, esiz);
                     97:                VERB(5) printf("Write CRC32 0x%x\n", env->env_crc);
                     98:                rlen = write(f, env, siz);
                     99:                if (rlen != siz)
1.3     ! misho     100:                        printf("Error:: written %d bytes != %zd\n", rlen, siz);
1.2       misho     101:                else
                    102:                        VERB(3) printf("Written %d bytes\n", rlen);
                    103:                lseek(f, 0, SEEK_SET);
                    104:        }
                    105: 
                    106:        rlen = read(f, env, siz);
                    107:        if (rlen != siz)
1.3     ! misho     108:                printf("Error:: readed %d bytes != %zd\n", rlen, siz);
1.2       misho     109:        else
                    110:                VERB(3) printf("Readed %d bytes\n", rlen);
                    111: 
                    112:        crc = crc_32(0, (u_char*) env->env_data, esiz);
                    113:        VERB(5) printf("Calculated CRC32 0x%x\n", crc);
                    114:        if (crc != env->env_crc)
                    115:                VERB(1) printf("Warning:: Bad CRC, Flash crc32 0x%x != 0x%x\n", 
                    116:                                env->env_crc, crc);
                    117: 
                    118:        close(f);
                    119:        close(l);
                    120:        unlink(AIT_GET_STR(&v));
                    121:        AIT_FREE_VAL(&v);
                    122:        return 0;
                    123: }
                    124: 
                    125: static inline const char *
                    126: ub_envmatch(const char *csName, const char *e)
                    127: {
                    128:        while (*csName == *e++)
                    129:                if (*csName++ == '=')
                    130:                        return e;
                    131:        if (!*csName && *(e - 1) == '=')
                    132:                return e;
                    133: 
                    134:        return NULL;
                    135: }
                    136: 
                    137: int
                    138: ub_load(const char *csSec)
                    139: {
                    140:        const char *str;
                    141:        size_t siz;
                    142: 
                    143:        FTRACE(4);
                    144: 
                    145:        str = cfg_getAttribute(&cfg, csSec, "drive_size");
                    146:        siz = strtol(str, NULL, 0);
                    147:        if (!siz)
                    148:                return -1;
                    149: 
                    150:        env = e_malloc(siz);
                    151:        if (!env) {
                    152:                ELIBERR(elwix);
                    153:                return -1;
                    154:        }
                    155: 
                    156:        return ub_flash_io(csSec, O_RDONLY);
                    157: }
                    158: 
                    159: void
                    160: ub_unload()
                    161: {
                    162:        FTRACE(4);
                    163: 
                    164:        if (env)
                    165:                e_free(env);
                    166: }
                    167: 
                    168: const char*
                    169: ub_getenv(const char *csSec, const char *csName)
                    170: {
                    171:        char *e, *nxt;
                    172:        size_t dlen = 0;
                    173:        const char *str = NULL;
                    174: 
                    175:        FTRACE(3);
                    176: 
                    177:        str = cfg_getAttribute(&cfg, csSec, "env_size");
                    178:        if (!str) {
                    179:                str = cfg_getAttribute(&cfg, csSec, "drive_size");
                    180:                if (!str)
                    181:                        return NULL;
                    182:                dlen -= sizeof env->env_crc;
                    183:        }
                    184:        dlen += strtol(str, NULL, 0);
                    185:        if (!dlen)
                    186:                return NULL;
                    187:        else
                    188:                dlen--;
                    189: 
                    190:        for (e = env->env_data; *e; e = nxt + 1) {
                    191:                for (nxt = e; *nxt; nxt++)
                    192:                        if (nxt >= env->env_data + dlen) {
                    193:                                printf("Error:: environment not terminated\n");
                    194:                                return NULL;
                    195:                        }
                    196: 
                    197:                str = ub_envmatch(csName, e);
                    198:                if (str)
                    199:                        break;
                    200:        }
                    201: 
                    202:        return str;
                    203: }
                    204: 
                    205: int
                    206: ub_setenv(const char *csSec, const char *csName, const char *csValue)
                    207: {
                    208:        char *e, *nxt;
                    209:        ssize_t dlen = 0, len;
                    210:        const char *str, *old = NULL;
                    211: 
                    212:        FTRACE(3);
                    213: 
                    214:        str = cfg_getAttribute(&cfg, csSec, "env_size");
                    215:        if (!str) {
                    216:                str = cfg_getAttribute(&cfg, csSec, "drive_size");
                    217:                if (!str)
                    218:                        return -1;
                    219:                dlen -= sizeof env->env_crc;
                    220:        }
                    221:        dlen += strtol(str, NULL, 0);
                    222:        if (!dlen)
                    223:                return -1;
                    224:        else
                    225:                dlen--;
                    226: 
                    227:        for (e = env->env_data; *e; e = nxt + 1) {
                    228:                for (nxt = e; *nxt; nxt++)
                    229:                        if (nxt >= env->env_data + dlen) {
                    230:                                printf("Error:: environment not terminated\n");
                    231:                                return -1;
                    232:                        }
                    233: 
                    234:                old = ub_envmatch(csName, e);
                    235:                if (old)
                    236:                        break;
                    237:        }
                    238: 
                    239:        /* Delete any existing definition */
                    240:        if (old) {
                    241:                if (!*++nxt)
                    242:                        *e = 0;
                    243:                else
                    244:                        while (42) {
                    245:                                *e = *nxt++;
                    246:                                if (!*e && !*nxt)
                    247:                                        break;
                    248:                                e++;
                    249:                        }
                    250:                *++e = 0;
                    251:        }
                    252: 
                    253:        if (csValue) {
                    254:                /* Append new definition at the end */
                    255:                for (e = env->env_data; *e || *(e + 1); e++);
                    256:                if (e > env->env_data)
                    257:                        e++;
                    258:                /* "name" + "=" + "val" +"\0\0" check u-boot-env size */
                    259:                len = strlen(csName) + 2; /* add '=' for first arg, ' ' for all others */
                    260:                len += strlen(csValue) + 1;
                    261:                if (len > env->env_data + dlen - e) {
                    262:                        printf("Error:: Environment overflow!\n");
                    263:                        return -1;
                    264:                }
                    265: 
                    266:                /* av pair */
                    267:                while ((*e = *csName++))
                    268:                        e++;
                    269:                *e = '=';
                    270:                while ((*++e = *csValue++));
                    271: 
                    272:                /* end is marked with double '\0' */
                    273:                *++e = 0;
                    274:        }
                    275: 
                    276:        if (ub_flash_io(csSec, O_RDWR)) {
                    277:                printf("Error:: Can't write environment to flash!\n");
                    278:                return -1;
                    279:        }
                    280: 
                    281:        return 0;
                    282: }
                    283: 
                    284: int
                    285: ub_env(const char *csSec)
                    286: {
                    287:        char *e, *nxt;
                    288:        ssize_t dlen = 0;
                    289:        const char *str;
                    290: 
                    291:        FTRACE(3);
                    292: 
                    293:        str = cfg_getAttribute(&cfg, csSec, "env_size");
                    294:        if (!str) {
                    295:                str = cfg_getAttribute(&cfg, csSec, "drive_size");
                    296:                if (!str)
                    297:                        return -1;
                    298:                dlen -= sizeof env->env_crc;
                    299:        }
                    300:        dlen += strtol(str, NULL, 0);
                    301:        if (!dlen)
                    302:                return -1;
                    303:        else
                    304:                dlen--;
                    305: 
                    306:        for (e = env->env_data; *e; e = nxt + 1) {
                    307:                for (nxt = e; *nxt; nxt++)
                    308:                        if (nxt >= env->env_data + dlen) {
                    309:                                printf("Error:: environment not terminated\n");
                    310:                                return -1;
                    311:                        }
                    312: 
                    313:                printf("%s\n", e);
                    314:        }
                    315: 
                    316:        return 0;
                    317: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>