Annotation of embedtools/src/upd.c, revision 1.1.2.7

1.1.2.1   misho       1: #include "global.h"
                      2: #include "upd.h"
                      3: 
                      4: 
1.1.2.7 ! misho       5: int Kill;
        !             6: 
        !             7: 
1.1.2.3   misho       8: static inline int ChkImg(const char *csImg, char *psDir)
1.1.2.1   misho       9: {
1.1.2.3   misho      10:        int res = 0;
1.1.2.2   misho      11: 
1.1.2.3   misho      12:        getcwd(psDir, MAXPATHLEN);
1.1.2.2   misho      13:        if (access(csImg, R_OK) == -1) {
                     14:                printf("Error:: Unable to find new image %s #%d - %s\n", 
                     15:                                csImg, errno, strerror(errno));
1.1.2.3   misho      16:                res = -1;
1.1.2.2   misho      17:        } else {
1.1.2.3   misho      18:                strlcat(psDir, "/", MAXPATHLEN);
                     19:                strlcat(psDir, csImg, MAXPATHLEN);
1.1.2.2   misho      20:        }
                     21: 
1.1.2.3   misho      22:        return res;
                     23: }
                     24: 
                     25: // -------------------------------
                     26: 
                     27: int Activate(const char *csImg)
                     28: {
                     29:        char szDir[MAXPATHLEN];
                     30: 
                     31:        if (ChkImg(csImg, szDir) == -1)
                     32:                return -1;
                     33: 
                     34:        VERB(3) printf("Activate procedure for %s\n", szDir);
                     35: 
1.1.2.2   misho      36:        unlink(FIRMWARE_IMG);
                     37:        if (symlink(szDir, FIRMWARE_IMG) == -1) {
                     38:                printf("Error:: Unable to activate new image %s #%d - %s\n", 
                     39:                                csImg, errno, strerror(errno));
                     40:                return -2;
                     41:        }
                     42: 
                     43:        syslog(LOG_NOTICE, "Activate new image %s", csImg);
                     44:        VERB(1) printf("Activate new image %s\n", csImg);
1.1.2.1   misho      45:        return 0;
                     46: }
                     47: 
1.1.2.4   misho      48: int Install(const char *csImg, const char *psDir)
1.1.2.1   misho      49: {
1.1.2.4   misho      50:        int src, dst, len;
                     51:        u_char buf[BUFSIZ];
                     52:        char szDir[MAXPATHLEN], szFile[MAXPATHLEN];
                     53:        struct stat ss, ds;
1.1.2.1   misho      54: 
1.1.2.4   misho      55:        strlcpy(szFile, psDir, MAXPATHLEN);
                     56:        strlcat(szFile, "/", MAXPATHLEN);
                     57:        strlcat(szFile, csImg, MAXPATHLEN);
                     58:        if (access(szFile, R_OK) == -1) {
                     59:                printf("Error:: Unable to find new image %s #%d - %s\n", 
                     60:                                csImg, errno, strerror(errno));
                     61:                return -1;
                     62:        } else {
                     63:                memset(&ss, 0, sizeof ss);
                     64:                if (stat(szFile, &ss) == -1) {
                     65:                        printf("Error:: Unable to find new image %s #%d - %s\n", 
                     66:                                        csImg, errno, strerror(errno));
                     67:                        return -1;
                     68:                }
                     69:        }
                     70: 
                     71:        getcwd(szDir, MAXPATHLEN);
                     72:        VERB(3) printf("Install procedure from %s to %s\n", szFile, szDir);
                     73:        strlcat(szDir, "/", MAXPATHLEN);
                     74:        strlcat(szDir, csImg, MAXPATHLEN);
                     75:        memset(&ds, 0, sizeof ds);
                     76:        if (stat(szDir, &ds) == -1 && ENOENT != errno) {
                     77:                printf("Error:: Unable to stat target #%d - %s\n", 
                     78:                                errno, strerror(errno));
                     79:                return -1;
                     80:        }
                     81: 
                     82:        if (ss.st_dev == ds.st_dev && ss.st_ino == ds.st_ino) {
                     83:                printf("Error:: Unable to install into self ...\n");
                     84:                return -1;
                     85:        }
                     86: 
                     87:        dst = open(szDir, O_WRONLY | O_CREAT | O_TRUNC, 0644);
                     88:        if (dst == -1) {
                     89:                printf("Error:: in create image %s #%d - %s\n", 
                     90:                                szDir, errno, strerror(errno));
                     91:                return -1;
                     92:        }
                     93:        src = open(szFile, O_RDONLY);
                     94:        if (src == -1) {
                     95:                printf("Error:: in open image %s #%d - %s\n", 
                     96:                                szFile, errno, strerror(errno));
                     97:                close(dst);
                     98:                unlink(szDir);
                     99:                return -1;
                    100:        }
                    101: 
                    102:        while ((len = read(src, buf, BUFSIZ)) > 0)
                    103:                if (write(dst, buf, len) == -1) {
                    104:                        printf("Error:: in write image #%d - %s\n", 
                    105:                                        errno, strerror(errno));
                    106:                        close(src);
                    107:                        close(dst);
                    108:                        unlink(szDir);
                    109: 
                    110:                        len = -1;
                    111:                        break;
                    112:                }
                    113: 
                    114:        close(src);
                    115:        close(dst);
                    116: 
                    117:        if (!len) {
                    118:                syslog(LOG_NOTICE, "Install image %s to %s", csImg, szDir);
                    119:                VERB(1) printf("Install image %s to %s\n", csImg, szDir);
                    120:        }
                    121:        return len;
1.1.2.1   misho     122: }
                    123: 
1.1.2.3   misho     124: int Rollback(const char *csImg)
1.1.2.1   misho     125: {
1.1.2.4   misho     126:        int src, dst, len;
                    127:        u_char buf[BUFSIZ];
                    128:        char szDir[MAXPATHLEN], szFile[MAXPATHLEN];
                    129:        struct stat ss, ds;
1.1.2.3   misho     130: 
1.1.2.4   misho     131:        getcwd(szFile, MAXPATHLEN);
                    132:        strlcat(szFile, "/", MAXPATHLEN);
                    133:        strlcat(szFile, FIRMWARE_BAK, MAXPATHLEN);
                    134:        if (access(szFile, R_OK) == -1) {
                    135:                printf("Error:: Unable to find backup image #%d - %s\n", 
                    136:                                errno, strerror(errno));
                    137:                return -1;
                    138:        } else {
                    139:                memset(&ss, 0, sizeof ss);
                    140:                if (stat(szFile, &ss) == -1) {
                    141:                        printf("Error:: Unable to find backup image #%d - %s\n", 
                    142:                                        errno, strerror(errno));
                    143:                        return -1;
                    144:                }
                    145:        }
                    146: 
                    147:        getcwd(szDir, MAXPATHLEN);
                    148:        strlcat(szDir, "/", MAXPATHLEN);
                    149:        strlcat(szDir, csImg, MAXPATHLEN);
                    150:        VERB(3) printf("Rollback procedure for image %s from backup!\n", csImg);
                    151:        memset(&ds, 0, sizeof ds);
                    152:        if (stat(szDir, &ds) == -1 && ENOENT != errno) {
                    153:                printf("Error:: Unable to stat target #%d - %s\n", 
                    154:                                errno, strerror(errno));
                    155:                return -1;
                    156:        }
                    157: 
                    158:        if (ss.st_dev == ds.st_dev && ss.st_ino == ds.st_ino) {
                    159:                printf("Error:: Unable to rollback into self ...\n");
                    160:                return -1;
                    161:        }
                    162: 
                    163:        src = open(szFile, O_RDONLY);
                    164:        if (src == -1) {
                    165:                printf("Error:: in open backup %s #%d - %s\n", 
                    166:                                szFile, errno, strerror(errno));
1.1.2.3   misho     167:                return -1;
1.1.2.4   misho     168:        }
                    169:        dst = open(szDir, O_WRONLY | O_CREAT | O_TRUNC, 0644);
                    170:        if (dst == -1) {
                    171:                printf("Error:: in create image %s #%d - %s\n", 
                    172:                                szDir, errno, strerror(errno));
                    173:                close(src);
                    174:                return -1;
                    175:        }
1.1.2.3   misho     176: 
1.1.2.4   misho     177:        while ((len = read(src, buf, BUFSIZ)) > 0)
                    178:                if (write(dst, buf, len) == -1) {
                    179:                        printf("Error:: in write image #%d - %s\n", 
                    180:                                        errno, strerror(errno));
                    181:                        close(dst);
                    182:                        close(src);
                    183:                        unlink(szDir);
                    184: 
                    185:                        len = -1;
                    186:                        break;
                    187:                }
                    188: 
                    189:        close(dst);
                    190:        close(src);
                    191: 
                    192:        if (!len) {
                    193:                syslog(LOG_NOTICE, "Rollback image %s to %s", csImg, szDir);
                    194:                VERB(1) printf("Rollback image %s to %s\n", csImg, szDir);
                    195:        }
                    196:        return len;
1.1.2.1   misho     197: 
                    198:        return 0;
                    199: }
                    200: 
1.1.2.3   misho     201: int tFTP(const char *csImg, const char *psDir)
1.1.2.1   misho     202: {
1.1.2.5   misho     203:        int src, dst, len;
                    204:        u_char buf[BUFSIZ];
                    205:        char szDir[MAXPATHLEN], szFile[MAXPATHLEN];
                    206:        struct stat ss, ds;
1.1.2.1   misho     207: 
1.1.2.3   misho     208:        if (ChkImg(csImg, szDir) == -1)
                    209:                return -1;
1.1.2.5   misho     210:        else {
                    211:                memset(&ss, 0, sizeof ss);
                    212:                if (stat(szDir, &ss) == -1) {
                    213:                        printf("Error:: Unable to find image %s #%d - %s\n", 
                    214:                                        szDir, errno, strerror(errno));
                    215:                        return -1;
                    216:                }
                    217:        }
1.1.2.3   misho     218: 
                    219:        VERB(3) printf("tFTP procedure for %s to %s\n", szDir, psDir);
1.1.2.5   misho     220:        strlcpy(szFile, psDir, MAXPATHLEN);
                    221:        strlcat(szFile, "/", MAXPATHLEN);
                    222:        strlcat(szFile, csImg, MAXPATHLEN);
                    223:        memset(&ds, 0, sizeof ds);
                    224:        if (stat(szFile, &ds) == -1 && ENOENT != errno) {
                    225:                printf("Error:: Unable to stat target %s #%d - %s\n", 
                    226:                                szFile, errno, strerror(errno));
                    227:                return -1;
                    228:        }
                    229: 
                    230:        if (ss.st_dev == ds.st_dev && ss.st_ino == ds.st_ino) {
                    231:                printf("Error:: Unable to copy into self ...\n");
                    232:                return -1;
                    233:        }
                    234: 
                    235:        dst = open(szFile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
                    236:        if (dst == -1) {
                    237:                printf("Error:: in create backup %s #%d - %s\n", 
                    238:                                szFile, errno, strerror(errno));
                    239:                return -1;
                    240:        }
                    241:        src = open(szDir, O_RDONLY);
                    242:        if (src == -1) {
                    243:                printf("Error:: in open image %s #%d - %s\n", 
                    244:                                szDir, errno, strerror(errno));
                    245:                close(dst);
                    246:                unlink(szFile);
                    247:                return -1;
                    248:        }
                    249: 
                    250:        while ((len = read(src, buf, BUFSIZ)) > 0)
                    251:                if (write(dst, buf, len) == -1) {
                    252:                        printf("Error:: in write backup #%d - %s\n", 
                    253:                                        errno, strerror(errno));
                    254:                        close(src);
                    255:                        close(dst);
                    256:                        unlink(szFile);
1.1.2.3   misho     257: 
1.1.2.5   misho     258:                        len = -1;
                    259:                        break;
                    260:                }
1.1.2.3   misho     261: 
1.1.2.5   misho     262:        close(src);
                    263:        close(dst);
                    264: 
                    265:        if (!len) {
1.1.2.3   misho     266:                syslog(LOG_NOTICE, "Export tFTP image %s to %s", csImg, psDir);
                    267:                VERB(1) printf("Export tFTP image %s to %s\n", csImg, psDir);
                    268:        }
1.1.2.5   misho     269:        return len;
1.1.2.1   misho     270: }
                    271: 
1.1.2.5   misho     272: int Backup(const char *csImg)
1.1.2.1   misho     273: {
1.1.2.3   misho     274:        int src, dst, len;
                    275:        u_char buf[BUFSIZ];
                    276:        char szDir[MAXPATHLEN], szFile[MAXPATHLEN];
1.1.2.1   misho     277: 
1.1.2.3   misho     278:        if (ChkImg(csImg, szDir) == -1)
                    279:                return -1;
                    280: 
1.1.2.5   misho     281:        getcwd(szFile, MAXPATHLEN);
1.1.2.3   misho     282:        strlcat(szFile, "/", MAXPATHLEN);
                    283:        strlcat(szFile, FIRMWARE_BAK, MAXPATHLEN);
1.1.2.5   misho     284:        VERB(3) printf("Backup procedure for %s\n", szDir);
1.1.2.3   misho     285: 
                    286:        dst = open(szFile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
                    287:        if (dst == -1) {
                    288:                printf("Error:: in create backup %s #%d - %s\n", 
                    289:                                szFile, errno, strerror(errno));
                    290:                return -1;
                    291:        }
                    292:        src = open(szDir, O_RDONLY);
                    293:        if (src == -1) {
                    294:                printf("Error:: in open image %s #%d - %s\n", 
                    295:                                szDir, errno, strerror(errno));
                    296:                close(dst);
                    297:                unlink(szFile);
                    298:                return -1;
                    299:        }
                    300: 
                    301:        while ((len = read(src, buf, BUFSIZ)) > 0)
                    302:                if (write(dst, buf, len) == -1) {
                    303:                        printf("Error:: in write backup #%d - %s\n", 
                    304:                                        errno, strerror(errno));
                    305:                        close(src);
                    306:                        close(dst);
                    307:                        unlink(szFile);
1.1.2.4   misho     308: 
                    309:                        len = -1;
                    310:                        break;
1.1.2.3   misho     311:                }
                    312: 
                    313:        close(src);
                    314:        close(dst);
                    315: 
1.1.2.5   misho     316:        if (!len) {
1.1.2.3   misho     317:                syslog(LOG_NOTICE, "Backup image %s", csImg);
                    318:                VERB(1) printf("Backup image %s\n", csImg);
                    319:        }
1.1.2.4   misho     320:        return len;
1.1.2.1   misho     321: }
                    322: 
1.1.2.3   misho     323: int Clean(const char *csImg)
1.1.2.1   misho     324: {
1.1.2.3   misho     325:        char szDir[MAXPATHLEN], szFile[MAXPATHLEN];
                    326: 
                    327:        if (ChkImg(csImg, szDir) == -1)
                    328:                return -1;
                    329: 
                    330:        getcwd(szFile, MAXPATHLEN);
                    331:        strlcat(szFile, "/", MAXPATHLEN);
                    332:        strlcat(szFile, FIRMWARE_BAK, MAXPATHLEN);
                    333: 
                    334:        VERB(3) printf("Clean procedure for %s\n", szDir);
                    335: 
                    336:        if (unlink(szFile) == -1) {
                    337:                printf("Error:: in clean backup #%d - %s\n", errno, strerror(errno));
                    338:                return -1;
                    339:        }
1.1.2.1   misho     340: 
1.1.2.3   misho     341:        syslog(LOG_NOTICE, "Clean backup for image %s", csImg);
                    342:        VERB(1) printf("Clean backup for image %s\n", csImg);
1.1.2.1   misho     343:        return 0;
                    344: }
1.1.2.6   misho     345: 
1.1.2.7 ! misho     346: // ----------------------------------
        !           347: 
        !           348: static void Signal(int sig)
        !           349: {
        !           350:        int stat;
        !           351: 
        !           352:        switch (sig) {
        !           353:                case SIGCHLD:
        !           354:                        while (waitpid(-1, &stat, WNOHANG) > 0);
        !           355:                        break;
        !           356:                case SIGTERM:
        !           357:                        Kill = 1;
        !           358:                        VERB(5) printf("Info(5):: Signal arrived #%d\n", sig);
        !           359:                        break;
        !           360:        }
        !           361: }
        !           362: 
1.1.2.6   misho     363: int Daemonize(struct sockaddr_in sin, const char *csTFTP)
                    364: {
1.1.2.7 ! misho     365:        int s, n = 1;
        !           366:        pid_t pid;
        !           367:        fd_set rfd;
        !           368:        int clilen, len;
        !           369:        struct sockaddr_in cli;
        !           370:        struct sigaction sa;
        !           371:        struct tftphdr *tftp;
        !           372:        u_char buf[TFTP_BUF];
        !           373: 
1.1.2.6   misho     374:        VERB(3) printf("Daemonize procedure for %s:%d to %s\n", 
                    375:                        inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), csTFTP);
                    376: 
1.1.2.7 ! misho     377:        memset(&sa, 0, sizeof sa);
        !           378:        sigemptyset(&sa.sa_mask);
        !           379:        sa.sa_handler = Signal;
        !           380:        sigaction(SIGCHLD, &sa, NULL);
        !           381:        sigaction(SIGTERM, &sa, NULL);
        !           382: 
        !           383:        s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
        !           384:        if (s == -1) {
        !           385:                printf("Error:: in create socket #%d - %s\n", errno, strerror(errno));
        !           386:                return -1;
        !           387:        }
        !           388:        if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof n) == -1) {
        !           389:                printf("Error:: in socket options #%d - %s\n", errno, strerror(errno));
        !           390:                close(s);
        !           391:                return -1;
        !           392:        }
        !           393:        if (bind(s, (struct sockaddr*) &sin, sizeof sin) == -1) {
        !           394:                printf("Error:: in bind #%d - %s\n", errno, strerror(errno));
        !           395:                close(s);
        !           396:                return -1;
        !           397:        }
        !           398: 
        !           399:        switch ((pid = fork())) {
        !           400:                case -1:
        !           401:                        printf("Error:: in socket options #%d - %s\n", errno, strerror(errno));
        !           402:                        close(s);
        !           403:                        return -1;
        !           404:                case 0:
        !           405:                        setsid();
        !           406: 
        !           407:                        while (!Kill) {
        !           408:                                FD_ZERO(&rfd);
        !           409:                                FD_SET(s, &rfd);
        !           410:                                if (select(s + 1, &rfd, NULL, NULL, NULL) == -1)
        !           411:                                        continue;
        !           412: 
        !           413:                                clilen = sizeof cli;
        !           414:                                len = recvfrom(s, buf, TFTP_BUF, 0, (struct sockaddr*) &cli, 
        !           415:                                                (socklen_t*) &clilen);
        !           416:                                if (len == -1)
        !           417:                                        continue;
        !           418:                        }
        !           419: 
        !           420:                        break;
        !           421:        }
        !           422: 
        !           423: 
        !           424:        close(s);
1.1.2.6   misho     425:        return 0;
                    426: }

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