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

1.2     ! misho       1: /*************************************************************************
        !             2:  * (C) 2014 AITNET - Sofia/Bulgaria - <office@aitbg.com>
        !             3:  *  by Michael Pounov <misho@aitbg.com>
        !             4:  *
        !             5:  * $Author: misho $
        !             6:  * $Id: ub_env.c,v 1.1.2.18 2014/01/30 07:36:53 misho Exp $
        !             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: 
        !            15: Copyright 2004 - 2014
        !            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)
        !           100:                        printf("Error:: written %d bytes != %d\n", rlen, siz);
        !           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)
        !           108:                printf("Error:: readed %d bytes != %d\n", rlen, siz);
        !           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>