Annotation of fwmaker/src/cmds.c, revision 1.3

1.3     ! misho       1: /*************************************************************************
        !             2: * (C) 2025 AITNET ltd - Sofia/Bulgaria - <misho@aitnet.org>
        !             3: *  by Michael Pounov <misho@elwix.org>
        !             4: *
        !             5: * $Author: misho $
        !             6: * $Id: elwix.c,v 1.11 2024/01/22 15:24:28 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 - 2025
        !            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: */
1.1       misho      46: #include "global.h"
                     47: #include "cmds.h"
                     48: #include "image.h"
                     49: 
                     50: 
                     51: int
                     52: cmd_Show(void *lb, int idx, char **args)
                     53: {
                     54:        ETRACE();
                     55: 
                     56:        printf("FW Image file: %s\n", image);
                     57:        printf("FW Image size: %zu\n", imgsiz);
1.2       misho      58:        printf("FW Image descriptor: %d\n", imgfd);
                     59:        printf("FW Image empty byte: 0x%02x\n\n", fillCh);
1.1       misho      60: 
                     61:        printf("MTD loaded: 0x%zx\n", mtd.mtd_fsiz);
                     62:        printf("MTD file: %s\n", mtd.mtd_file);
                     63:        printf("MTD offset: 0x%lx\n", mtd.mtd_offset);
                     64:        printf("MTD size: 0x%zx\n", mtd.mtd_size);
                     65: 
                     66:        return 0;
                     67: }
                     68: 
                     69: static int
                     70: dialog(void *lb, const char *prompt, char *str, int len)
                     71: {
                     72:        int ret = 0;
                     73:        char *p;
                     74: 
                     75:        if (!str || len < 1)
                     76:                return -1;
                     77: 
                     78:        cli_Printf(lb, "%s", prompt);
                     79:        p = cliInputLine(lb, -1);
                     80:        if (p) {
                     81:                cli_freeInput(lb);
                     82:                strlcpy(str, p, len);
                     83:                e_free(p);
                     84: 
                     85:                if ((p = strpbrk(str, "\r\n")))
                     86:                        *p = 0;
                     87:        }
                     88: 
                     89:        return ret;
                     90: }
                     91: 
                     92: static void
                     93: loadparams(void *lb, char ** const args)
                     94: {
                     95:        char str[STRSIZ];
                     96: 
                     97:        memset(&mtd, 0, sizeof mtd);
                     98:        if (!args[1]) {
                     99:                if (!dialog(lb, "Offset=", str, sizeof str))
                    100:                        mtd.mtd_offset = (off_t) strtol(str, NULL, 0);
                    101:        } else
                    102:                mtd.mtd_offset = (off_t) strtol(args[1], NULL, 0);
                    103:        EVERBOSE(3, "mtd.offset=0x%lx", mtd.mtd_offset);
                    104:        if (!args[2]) {
                    105:                if (!dialog(lb, "Size=", str, sizeof str))
                    106:                        mtd.mtd_size = (size_t) strtol(str, NULL, 0);
                    107:        } else
                    108:                mtd.mtd_size = (size_t) strtol(args[2], NULL, 0);
                    109:        EVERBOSE(3, "mtd.size=0x%zx", mtd.mtd_size);
                    110: }
                    111: 
                    112: static int
                    113: openfile(int flgs)
                    114: {
                    115:        int fd;
                    116: 
                    117:        fd = open(mtd.mtd_file, flgs, 0644);
                    118:        if (fd == -1) {
                    119:                ESYSERR(0);
                    120:                return -1;
                    121:        }
                    122:        if (lseek(imgfd, mtd.mtd_offset, SEEK_SET) == -1) {
                    123:                ESYSERR(0);
                    124:                close(fd);
                    125:                return -1;
                    126:        }
                    127: 
                    128:        EVERBOSE(1, "mtd_file %s opened #%d", mtd.mtd_file, fd);
                    129:        return fd;
                    130: }
                    131: 
                    132: static void
                    133: closefile(int fd)
                    134: {
                    135:        EVERBOSE(1, "mtd_file closed #%d", fd);
                    136:        close(fd);
                    137: }
                    138: 
                    139: int
                    140: cmd_Mtd(void *lb, int idx, char **args)
                    141: {
                    142:        char str[MAXPATHLEN];
                    143:        struct stat st;
                    144:        int fd, wlen = 0, rlen = 0;
                    145:        u_char buf[BUFSIZ] = { 0 };
                    146: 
                    147:        ETRACE();
                    148: 
                    149:        args++;
                    150:        if (!args[0]) {
                    151:                printf("Help: mtd [read|write|erase] <mtd_offset> <mtd_size> [mtd_bin_file]\n");
                    152:                return -1;
                    153:        } else if (!strncmp(args[0], "write", strlen(args[0]))) {
                    154:                loadparams(lb, args);
                    155:                if (!args[3]) {
                    156:                        if (!dialog(lb, "File=", str, sizeof str))
                    157:                                strlcpy(mtd.mtd_file, str, sizeof mtd.mtd_file);
                    158:                } else
                    159:                        strlcpy(mtd.mtd_file, args[3], sizeof mtd.mtd_file);
                    160:                EVERBOSE(3, "mtd.file=%s", mtd.mtd_file);
                    161: 
                    162:                if (stat(mtd.mtd_file, &st) == -1) {
                    163:                        ESYSERR(0);
                    164:                        memset(&mtd, 0, sizeof mtd);
                    165:                        return -1;
                    166:                } else
                    167:                        mtd.mtd_fsiz = st.st_size;
                    168:                EVERBOSE(3, "mtd.fsiz=%lu", mtd.mtd_fsiz);
                    169:                if (mtd.mtd_size < mtd.mtd_fsiz) {
                    170:                        printf("Error:: MTD file is bigger then reserved space!\n");
                    171:                        memset(&mtd, 0, sizeof mtd);
                    172:                        return -1;
                    173:                }
                    174:                if (imgfd < 3) {
                    175:                        printf("Error:: image isn't present!\n");
                    176:                        memset(&mtd, 0, sizeof mtd);
                    177:                        return -1;
                    178:                }
                    179:                if (imgsiz < mtd.mtd_offset + mtd.mtd_size) {
                    180:                        printf("Error:: requested region for write is out of image size\n");
                    181:                        memset(&mtd, 0, sizeof mtd);
                    182:                        return -1;
                    183:                }
                    184: 
                    185:                fd = openfile(O_RDONLY);
                    186:                if (fd == -1) {
                    187:                        memset(&mtd, 0, sizeof mtd);
                    188:                        return -1;
                    189:                }
                    190:                while ((rlen = read(fd, buf, sizeof buf)) > 0)
                    191:                        if ((rlen = write(imgfd, buf, rlen)) == -1)
                    192:                                break;
                    193:                        else
                    194:                                wlen += rlen;
                    195:                if (rlen == -1) {
                    196:                        ESYSERR(0);
                    197:                        memset(&mtd, 0, sizeof mtd);
                    198:                } else if (!rlen)
                    199:                        printf("MTD partition size=%d was written to image\n", wlen);
                    200:                closefile(fd);
                    201:        } else if (!strncmp(args[0], "read", strlen(args[0]))) {
                    202:                loadparams(lb, args);
                    203:                if (!args[3]) {
                    204:                        if (!dialog(lb, "File=", str, sizeof str))
                    205:                                strlcpy(mtd.mtd_file, str, sizeof mtd.mtd_file);
                    206:                } else
                    207:                        strlcpy(mtd.mtd_file, args[3], sizeof mtd.mtd_file);
                    208:                EVERBOSE(3, "mtd.file=%s", mtd.mtd_file);
                    209: 
                    210:                if (imgfd < 3) {
                    211:                        printf("Error:: image isn't present!\n");
                    212:                        memset(&mtd, 0, sizeof mtd);
                    213:                        return -1;
                    214:                }
                    215:                if (imgsiz < mtd.mtd_offset + mtd.mtd_size) {
                    216:                        printf("Error:: requested region for read is out of image size\n");
                    217:                        memset(&mtd, 0, sizeof mtd);
                    218:                        return -1;
                    219:                }
                    220: 
                    221:                fd = openfile(O_WRONLY | O_CREAT);
                    222:                if (fd == -1) {
                    223:                        memset(&mtd, 0, sizeof mtd);
                    224:                        return -1;
                    225:                }
                    226:                while (wlen < mtd.mtd_size &&
                    227:                                (rlen = read(imgfd, buf, MIN(mtd.mtd_size - wlen, sizeof buf))) > 0)
                    228:                        if ((rlen = write(fd, buf, rlen)) == -1)
                    229:                                break;
                    230:                        else
                    231:                                wlen += rlen;
                    232:                if (rlen == -1) {
                    233:                        ESYSERR(0);
                    234:                        memset(&mtd, 0, sizeof mtd);
                    235:                } else
                    236:                        printf("MTD image partition size=%d was transferred file\n", wlen);
                    237:                closefile(fd);
                    238:        } else if (!strncmp(args[0], "erase", strlen(args[0]))) {
                    239:                loadparams(lb, args);
                    240: 
                    241:                if (imgfd < 3) {
                    242:                        printf("Error:: image isn't present!\n");
                    243:                        memset(&mtd, 0, sizeof mtd);
                    244:                        return -1;
                    245:                }
                    246:                if (imgsiz < mtd.mtd_offset + mtd.mtd_size) {
                    247:                        printf("Error:: requested region for erase is out of image size\n");
                    248:                        memset(&mtd, 0, sizeof mtd);
                    249:                        return -1;
                    250:                }
                    251:                if (lseek(imgfd, mtd.mtd_offset, SEEK_SET) == -1) {
                    252:                        ESYSERR(0);
                    253:                        memset(&mtd, 0, sizeof mtd);
                    254:                        return -1;
                    255:                }
                    256:                while (wlen < mtd.mtd_size)
                    257:                        if ((rlen = write(imgfd, buf, MIN(mtd.mtd_size - wlen, sizeof buf))) == -1)
                    258:                                break;
                    259:                        else
                    260:                                wlen += rlen;
                    261:                if (rlen == -1) {
                    262:                        ESYSERR(0);
                    263:                        memset(&mtd, 0, sizeof mtd);
                    264:                } else
                    265:                        printf("MTD image partition size=%d was erased\n", wlen);
                    266:        } else {
                    267:                printf("Error:: unknown command '%s'\n", args[0]);
                    268:                return -1;
                    269:        }
                    270: 
                    271:        return 0;
                    272: }
                    273: 
                    274: int
                    275: cmd_Image(void *lb, int idx, char **args)
                    276: {
1.2       misho     277:        u_char buf[BUFSIZ];
                    278:        int wlen;
                    279:        size_t siz;
                    280: 
1.1       misho     281:        ETRACE();
                    282: 
                    283:        args++;
                    284:        if (!args[0]) {
                    285:                printf("Help: image [mount|umount|erase|name <file>|init <size>]\n");
                    286:                return -1;
                    287:        } else if (!strncmp(args[0], "mount", strlen(args[0]))) {
                    288:                if (imgfd > 2) {
                    289:                        printf("Error:: Image is already mounted ...\n");
                    290:                        return -1;
                    291:                }
                    292:                imageOpen(0);
                    293:        } else if (!strncmp(args[0], "umount", strlen(args[0]))) {
                    294:                imageClose();
                    295:        } else if (!strcmp(args[0], "erase")) {
                    296:                if (imgfd > 2) {
                    297:                        printf("Error:: Image is mounted, cannot be erased ...\n");
                    298:                        return -1;
                    299:                }
                    300:                unlink(image);
                    301:                EVERBOSE(1, "Erase image %s\n", image);
                    302:        } else if (!strncmp(args[0], "name", strlen(args[0]))) {
                    303:                if (imgfd > 2) {
                    304:                        printf("Error:: Image is mounted, cannot be renamed ...\n");
                    305:                        return -1;
                    306:                }
                    307:                if (!args[1]) {
                    308:                        printf("Error:: name isn't found!\n");
                    309:                        return -1;
                    310:                }
                    311:                strlcpy(image, args[1], sizeof image);
                    312:        } else if (!strncmp(args[0], "init", strlen(args[0]))) {
                    313:                if (imgfd > 2) {
                    314:                        printf("Error:: Image is already mounted, cannot be inited ...\n");
                    315:                        return -1;
                    316:                }
                    317:                if (!args[1]) {
                    318:                        printf("Error:: size isn't found!\n");
                    319:                        return -1;
                    320:                }
                    321:                if (imageOpen(O_CREAT) > 2) {
1.2       misho     322:                        memset(buf, fillCh, sizeof buf);
                    323:                        imgsiz = siz = (size_t) strtol(args[1], NULL, 0);
1.1       misho     324:                        if (ftruncate(imgfd, imgsiz) == -1) {
                    325:                                ESYSERR(0);
                    326:                                imageClose();
                    327:                                unlink(image);
                    328:                                return -1;
1.2       misho     329:                        }
                    330:                        lseek(imgfd, 0, SEEK_SET);
                    331:                        while (siz > 0) {
                    332:                                wlen = MIN(siz, sizeof buf);
                    333:                                wlen = write(imgfd, buf, wlen);
                    334:                                if (wlen < 1) {
                    335:                                        ESYSERR(0);
                    336:                                        imageClose();
                    337:                                        unlink(image);
                    338:                                        return -1;
                    339:                                } else
                    340:                                        siz -= wlen;
                    341:                        }
                    342:                        EVERBOSE(1, "Image '%s' created successful with size=%lu/remain=#%lu bytes\n",
                    343:                                        image, imgsiz, siz);
1.1       misho     344:                }
                    345:        } else {
                    346:                printf("Error:: unknown command '%s'\n", args[0]);
                    347:                return -1;
                    348:        }
                    349: 
                    350:        return 0;
                    351: }
1.2       misho     352: 
                    353: int
                    354: cmd_FillCh(void *lb, int idx, char **args)
                    355: {
                    356:        char str[STRSIZ];
                    357: 
                    358:        ETRACE();
                    359: 
                    360:        args++;
                    361:        if (!args[0]) {
                    362:                if (!dialog(lb, "Byte=", str, sizeof str))
                    363:                        fillCh = (u_char) strtol(str, NULL, 0);
                    364:                else
                    365:                        return -1;
                    366:        } else
                    367:                fillCh = (u_char) strtol(args[0], NULL, 0);
                    368: 
                    369:        return 0;
                    370: }

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