Diff for /embedtools/src/imgupd.c between versions 1.4 and 1.8

version 1.4, 2014/02/05 22:53:12 version 1.8, 2017/06/28 15:19:32
Line 12  terms: Line 12  terms:
 All of the documentation and software included in the ELWIX and AITNET  All of the documentation and software included in the ELWIX and AITNET
 Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>  Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
   
Copyright 2004 - 2014Copyright 2004 - 2017
         by Michael Pounov <misho@elwix.org>.  All rights reserved.          by Michael Pounov <misho@elwix.org>.  All rights reserved.
   
 Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
Line 44  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF TH Line 44  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF TH
 SUCH DAMAGE.  SUCH DAMAGE.
 */  */
 #include "global.h"  #include "global.h"
   #include "imgupd.h"
   
   
 char imgName[PATH_MAX], imgFile[PATH_MAX];  char imgName[PATH_MAX], imgFile[PATH_MAX];
off_t imgSize, iSize;off_t imgSize, iSize, fromBegin;
int Verbose, bufSize = IMGBUF_SIZE;int Verbose, nameFlg, fileFlg, bufSize = IMGBUF_SIZE;
 extern char compiled[], compiledby[], compilehost[];  extern char compiled[], compiledby[], compilehost[];
   
 static void  static void
Line 60  Usage() Line 61  Usage()
                 "  Syntax: imgupd [options] [image_file]\n\n"                  "  Syntax: imgupd [options] [image_file]\n\n"
                 "\t-v\t\tVerbose ...\n"                  "\t-v\t\tVerbose ...\n"
                 "\t-R\t\tReboot system after complete\n"                  "\t-R\t\tReboot system after complete\n"
                "\t-p\t\tPipe suitable transfer on little chunks\n"                "\t-i\t\tStart fill storage from begin\n"
                 "\t-g\t\tGet image from Storage\n"                  "\t-g\t\tGet image from Storage\n"
                 "\t-t\t\tTruncate Storage file name\n"                  "\t-t\t\tTruncate Storage file name\n"
                 "\t-s <size>\tStorage size (required for stdin)\n"                  "\t-s <size>\tStorage size (required for stdin)\n"
Line 69  Usage() Line 70  Usage()
 }  }
   
 static int  static int
EmptyStore(int img)getFDtype(int fd)
 {  {
           int type, flg = 0;
           struct stat sb;
   
           if (fstat(fd, &sb) == -1) {
                   ESYSERR(0);
                   return -1;
           }
           if (S_ISREG(sb.st_mode))
                   flg |= FD_TRUNC;
           if (S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode)) {
                   if (ioctl(fd, FIODTYPE, &type) == -1) {
                           ESYSERR(0);
                           return -1;
                   }
                   if (type & D_TAPE)
                           flg |= FD_TAPE;
                   else if (type & (D_DISK | D_MEM))
                           flg |= FD_SEEK;
                   if (S_ISCHR(sb.st_mode) && !(type & D_TAPE))
                           flg |= FD_CHR;
                   goto end;
           }
           errno ^= errno;
           if (lseek(fd, 0, SEEK_CUR) == -1 && errno == ESPIPE)
                   flg |= FD_PIPE;
           else
                   flg |= FD_SEEK;
   end:
           return flg;
   }
   
   static int
   EmptyStore(int img, int flg)
   {
         register int i;          register int i;
         u_char buf[bufSize];          u_char buf[bufSize];
         ssize_t wlen;          ssize_t wlen;
   
         VERB(1) printf("Erase store %s\n", imgName);          VERB(1) printf("Erase store %s\n", imgName);
   
        iSize = lseek(img, 0, SEEK_END);        if (!fromBegin && flg & FD_SEEK) {
        if (iSize == -1) {                iSize = lseek(img, 0, SEEK_END);
                ESYSERR(0);                if (iSize == -1) {
                return -1;                        ESYSERR(0);
                         return -1;
                 } else
                         imgSize += E_ALIGN(iSize, bufSize);
         } else          } else
                imgSize += E_ALIGN(iSize, bufSize);                iSize ^= iSize;
   
         memset(buf, 0, sizeof buf);          memset(buf, 0, sizeof buf);
         for (i = howmany(iSize, bufSize); i < howmany(imgSize, bufSize); i++)          for (i = howmany(iSize, bufSize); i < howmany(imgSize, bufSize); i++)
                if ((wlen = write(img, buf, sizeof buf)) == -1 ||                 if ((wlen = write(img, buf, bufSize)) == -1 || 
                                wlen != sizeof buf) {                                (wlen && wlen != bufSize)) {
                        EERROR(EIO, "Error at chunk %d init %d bytes, should be %u\n",                         if (wlen == -1)
                                        i, wlen, sizeof buf);                                ESYSERR(0);
                         else
                                 EERROR(EIO, "Error at chunk %d init %zd bytes, "
                                                 "should be %d\n", i, wlen, bufSize);
                         return -1;                          return -1;
                 } else                  } else
                         VERB(1) printf("+Written chunk #%d\n", i);                          VERB(1) printf("+Written chunk #%d\n", i);
   
        iSize = lseek(img, iSize, SEEK_SET);        if (flg & FD_SEEK)
                 iSize = lseek(img, iSize, SEEK_SET);
         return iSize;          return iSize;
 }  }
   
 static int  static int
FillStore(int img, int fd)FillStore(int img, int iflg, int fd, int fflg)
 {  {
         register int i, j;          register int i, j;
        u_char buf[bufSize];        u_char *pos, buf[bufSize];
        ssize_t rlen, wlen;        ssize_t rlen, wlen, len;
   
         VERB(1) printf("Fill store %s from image file %s\n", imgName, imgFile);          VERB(1) printf("Fill store %s from image file %s\n", imgName, imgFile);
   
         for (j = 0, i = howmany(iSize, bufSize); i < howmany(imgSize, bufSize);           for (j = 0, i = howmany(iSize, bufSize); i < howmany(imgSize, bufSize); 
                         i++, j++) {                          i++, j++) {
                 memset(buf, 0, sizeof buf);                  memset(buf, 0, sizeof buf);
                rlen = read(fd, buf, sizeof buf);                for (len = bufSize, pos = buf; len > 0; len -= rlen, pos += rlen) {
                if (rlen == -1) {                        rlen = read(fd, pos, len);
                        ESYSERR(0);                        if (rlen == -1) {
                        return -1;                                ESYSERR(0);
                } else if (!rlen)                                return -1;
                        break;                        } else if (!rlen)
                else                                break;
                        VERB(1) printf("+Readed %d bytes for chunk #%d\n", rlen, j);                        else
                                 VERB(1) printf("+Readed %zd bytes for chunk #%d\n", rlen, j);
                 }
   
                wlen = write(img, buf, rlen);                wlen = write(img, buf, bufSize);
                 if (wlen == -1) {                  if (wlen == -1) {
                         ESYSERR(0);                          ESYSERR(0);
                         return -1;                          return -1;
                } else if (!wlen || wlen != rlen) {                } else if (wlen && wlen != bufSize) {
                        EERROR(EIO, "Readed %d bytes are not equal to written %d bytes\n",                         EERROR(EIO, "Error at chunk %d written %zd bytes, "
                                        rlen, wlen);                                        "should be %u\n", i, wlen, bufSize);
                 } else                  } else
                        VERB(1) printf("+Written %d bytes at chunk #%d\n", wlen, i);                        VERB(1) printf("+Written %zd bytes at chunk #%d\n", wlen, i);
         }          }
   
         return 0;          return 0;
Line 139  main(int argc, char **argv) Line 183  main(int argc, char **argv)
         char ch, m = 0, R = 0;          char ch, m = 0, R = 0;
         int fd, img, tr = 0;          int fd, img, tr = 0;
   
        while ((ch = getopt(argc, argv, "hvRpgts:f:")) != -1)        while ((ch = getopt(argc, argv, "hvRigts:f:")) != -1)
                 switch (ch) {                  switch (ch) {
                         case 'f':                          case 'f':
                                 strlcpy(imgName, optarg, sizeof imgName);                                  strlcpy(imgName, optarg, sizeof imgName);
Line 156  main(int argc, char **argv) Line 200  main(int argc, char **argv)
                                 break;                                  break;
                         case 'g':                          case 'g':
                                 m = 1;                                  m = 1;
                           case 'i':
                                   fromBegin = 1;
                                 break;                                  break;
                         case 'p':  
                                 bufSize = IMGBUF_SIZE2;  
                                 break;  
                         case 'R':                          case 'R':
                                 R = 1;                                  R = 1;
                                 break;                                  break;
Line 183  main(int argc, char **argv) Line 226  main(int argc, char **argv)
                                 ESYSERR(0);                                  ESYSERR(0);
                                 return 2;                                  return 2;
                         } else                          } else
                                   fileFlg = getFDtype(fd);
   
                           if (fileFlg & FD_SEEK) {
                                 iSize = lseek(fd, 0, SEEK_END);                                  iSize = lseek(fd, 0, SEEK_END);
                        if (!imgSize)                                if (!imgSize)
                                imgSize = E_ALIGN(iSize, bufSize);                                        imgSize = E_ALIGN(iSize, bufSize);
                        if (iSize == -1 || iSize > imgSize) {                                if (iSize == -1 || iSize > imgSize) {
                                         close(fd);
                                         EERROR(ENOSPC, "Error:: file size %llu is "
                                                         "greater from storage size %llu\n", 
                                                         (unsigned long long) iSize, 
                                                         (unsigned long long) imgSize);
                                         return 2;
                                 } else
                                         lseek(fd, 0, SEEK_SET);
                         }
                 } else {
                         fd = STDIN_FILENO;
                         fileFlg = getFDtype(fd);
                 }
 
                 if (!imgSize) {
                         if (fd > 2)
                                 close(fd);                                  close(fd);
                                 EERROR(ENOSPC, "Error:: file size %llu is "  
                                                 "greater from storage size %llu\n",   
                                                 iSize, imgSize);  
                                 return 2;  
                         } else  
                                 lseek(fd, 0, SEEK_SET);  
                 } else if (!imgSize) {  
                         Usage();                          Usage();
                         return 1;                          return 1;
                } else                }
                        fd = STDIN_FILENO; 
         } else {        /* GET */          } else {        /* GET */
                 if (argc) {                  if (argc) {
                         strlcpy(imgFile, *argv, sizeof imgFile);                          strlcpy(imgFile, *argv, sizeof imgFile);
Line 207  main(int argc, char **argv) Line 261  main(int argc, char **argv)
                         if (fd == -1) {                          if (fd == -1) {
                                 ESYSERR(0);                                  ESYSERR(0);
                                 return 2;                                  return 2;
                        }                        } else
                } else if (!imgSize) {                                fileFlg = getFDtype(fd);
                        Usage();                } else {
                        return 1; 
                } else 
                         fd = STDOUT_FILENO;                          fd = STDOUT_FILENO;
                           fileFlg = getFDtype(fd);
                   }
         }          }
   
         VERB(1) printf("imgSize=%llu imgName=%s imgFile=%s\n",           VERB(1) printf("imgSize=%llu imgName=%s imgFile=%s\n", 
                        imgSize, imgName, argc ? imgFile : "<stdin>");                        (unsigned long long) imgSize, imgName, argc ? imgFile : "<stdin>");
   
         if (!m) {          if (!m) {
                 /* open storage device */                  /* open storage device */
Line 226  main(int argc, char **argv) Line 280  main(int argc, char **argv)
                         if (fd > 2)                          if (fd > 2)
                                 close(fd);                                  close(fd);
                         return 3;                          return 3;
                }                } else
                         nameFlg = getFDtype(img);
         } else {        /* GET */          } else {        /* GET */
                 /* open storage device */                  /* open storage device */
                 img = open(imgName, O_RDONLY);                  img = open(imgName, O_RDONLY);
Line 236  main(int argc, char **argv) Line 291  main(int argc, char **argv)
                                 close(fd);                                  close(fd);
                         return 3;                          return 3;
                 } else                  } else
                           nameFlg = getFDtype(img);
   
                   if (nameFlg & FD_SEEK) {
                         iSize = lseek(img, 0, SEEK_END);                          iSize = lseek(img, 0, SEEK_END);
                if (!imgSize)                        if (!imgSize)
                        imgSize = E_ALIGN(iSize, bufSize);                                imgSize = E_ALIGN(iSize, bufSize);
                if (iSize == -1 || iSize > imgSize) {                        if (iSize == -1 || iSize > imgSize) {
                                 if (fd > 2)
                                         close(fd);
                                 close(img);
                                 EERROR(ENOSPC, "Error:: storage size %llu is "
                                                 "greater from file size %llu\n", 
                                                 (unsigned long long) iSize, 
                                                 (unsigned long long) imgSize);
                                 return 3;
                         } else
                                 lseek(img, 0, SEEK_SET);
                 }
 
                 if (!imgSize) {
                         if (fd > 2)                          if (fd > 2)
                                 close(fd);                                  close(fd);
                        close(img);                        Usage();
                        EERROR(ENOSPC, "Error:: storage size %llu is "                        return 1;
                                        "greater from file size %llu\n",                 }
                                        iSize, imgSize); 
                        return 3; 
                } else 
                        lseek(img, 0, SEEK_SET); 
         }          }
   
         if (!m) {          if (!m) {
                if (EmptyStore(img) == -1) {                if (EmptyStore(img, nameFlg) == -1) {
                         if (fd > 2)                          if (fd > 2)
                                 close(fd);                                  close(fd);
                         close(img);                          close(img);
                         return 3;                          return 3;
                 }                  }
                if (FillStore(img, fd) == -1) {                if (FillStore(img, nameFlg, fd, fileFlg) == -1) {
                         if (fd > 2)                          if (fd > 2)
                                 close(fd);                                  close(fd);
                         close(img);                          close(img);
                         return 4;                          return 4;
                 }                  }
         } else {        /* GET */          } else {        /* GET */
                if (EmptyStore(fd) == -1) {                iSize ^= iSize;
                        if (fd > 2)                if (!(fileFlg & FD_PIPE))
                                close(fd);                        if (EmptyStore(fd, fileFlg) == -1) {
                        close(img);                                if (fd > 2)
                        return 3;                                        close(fd);
                }                                close(img);
                if (FillStore(fd, img) == -1) {                                return 3;
                         }
                 if (FillStore(fd, fileFlg, img, nameFlg) == -1) {
                         if (fd > 2)                          if (fd > 2)
                                 close(fd);                                  close(fd);
                         close(img);                          close(img);

Removed from v.1.4  
changed lines
  Added in v.1.8


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