Diff for /embedtools/src/imgupd.c between versions 1.2 and 1.7

version 1.2, 2014/02/05 15:44:06 version 1.7, 2014/02/06 15:32:11
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;int Verbose, nameFlg, fileFlg, bufSize = IMGBUF_SIZE;
 extern char compiled[], compiledby[], compilehost[];  extern char compiled[], compiledby[], compilehost[];
   
 static void  static void
Line 57  Usage() Line 58  Usage()
   
         printf( "IMGUPD is tool for management of images\n"          printf( "IMGUPD is tool for management of images\n"
                 "=== %s === %s@%s ===\n\n"                  "=== %s === %s@%s ===\n\n"
                "  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-i\t\tStart fill storage from begin\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"
                 "\t-f <devfile>\tStorage file name\n"                  "\t-f <devfile>\tStorage file name\n"
Line 66  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[IMGBUF_SIZE];        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, IMGBUF_SIZE);                iSize ^= iSize;
   
         memset(buf, 0, sizeof buf);          memset(buf, 0, sizeof buf);
        for (i = howmany(iSize, IMGBUF_SIZE); i < howmany(imgSize, IMGBUF_SIZE); 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 %d bytes, "
                                                 "should be %u\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[IMGBUF_SIZE];        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, IMGBUF_SIZE); i < howmany(imgSize, IMGBUF_SIZE);         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 %d 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 %d 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 %d bytes at chunk #%d\n", wlen, i);
         }          }
Line 133  FillStore(int img, int fd) Line 180  FillStore(int img, int fd)
 int  int
 main(int argc, char **argv)  main(int argc, char **argv)
 {  {
        char ch;        char ch, m = 0, R = 0;
         int fd, img, tr = 0;          int fd, img, tr = 0;
   
        while ((ch = getopt(argc, argv, "hvts: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 151  main(int argc, char **argv) Line 198  main(int argc, char **argv)
                         case 't':                          case 't':
                                 tr = O_TRUNC;                                  tr = O_TRUNC;
                                 break;                                  break;
                           case 'g':
                                   m = 1;
                           case 'i':
                                   fromBegin = 1;
                                   break;
                           case 'R':
                                   R = 1;
                                   break;
                         case 'v':                          case 'v':
                                 Verbose++;                                  Verbose++;
                                 break;                                  break;
Line 162  main(int argc, char **argv) Line 217  main(int argc, char **argv)
         argc -= optind;          argc -= optind;
         argv += optind;          argv += optind;
   
        if (argc) {        if (!m) {
                strlcpy(imgFile, *argv, sizeof imgFile);                if (argc) {
                /* open image file */                        strlcpy(imgFile, *argv, sizeof imgFile);
                fd = open(imgFile, O_RDONLY);                        /* open image file */
                if (fd == -1) {                        fd = open(imgFile, O_RDONLY);
                         if (fd == -1) {
                                 ESYSERR(0);
                                 return 2;
                         } else
                                 fileFlg = getFDtype(fd);
 
                         if (fileFlg & FD_SEEK) {
                                 iSize = lseek(fd, 0, SEEK_END);
                                 if (!imgSize)
                                         imgSize = E_ALIGN(iSize, bufSize);
                                 if (iSize == -1 || iSize > imgSize) {
                                         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 {
                         fd = STDIN_FILENO;
                         fileFlg = getFDtype(fd);
                 }
 
                 if (!imgSize) {
                         if (fd > 2)
                                 close(fd);
                         Usage();
                         return 1;
                 }
         } else {        /* GET */
                 if (argc) {
                         strlcpy(imgFile, *argv, sizeof imgFile);
                         /* open image file */
                         fd = open(imgFile, O_WRONLY | O_TRUNC | O_CREAT, 0644);
                         if (fd == -1) {
                                 ESYSERR(0);
                                 return 2;
                         } else
                                 fileFlg = getFDtype(fd);
                 } else {
                         fd = STDOUT_FILENO;
                         fileFlg = getFDtype(fd);
                 }
         }
 
         VERB(1) printf("imgSize=%llu imgName=%s imgFile=%s\n", 
                         imgSize, imgName, argc ? imgFile : "<stdin>");
 
         if (!m) {
                 /* open storage device */
                 img = open(imgName, O_RDWR | O_CREAT | tr, 0644);
                 if (img == -1) {
                         ESYSERR(0);                          ESYSERR(0);
                        return 2;                        if (fd > 2)
                                 close(fd);
                         return 3;
                 } else                  } else
                        iSize = lseek(fd, 0, SEEK_END);                        nameFlg = getFDtype(img);
                if (!imgSize)        } else {        /* GET */
                        imgSize = E_ALIGN(iSize, IMGBUF_SIZE);                /* open storage device */
                if (iSize == -1 || iSize > imgSize) {                img = open(imgName, O_RDONLY);
                        close(fd);                if (img == -1) {
                        EERROR(ENOSPC, "Error:: file size %llu is greater from storage size %llu\n",                         ESYSERR(0);
                                        iSize, imgSize);                        if (fd > 2)
                        return 2;                                close(fd);
                         return 3;
                 } else                  } else
                        lseek(fd, 0, SEEK_SET);                        nameFlg = getFDtype(img);
        } else if (!imgSize) { 
                Usage(); 
                return 1; 
        } else 
                fd = STDIN_FILENO; 
   
        VERB(1) printf("imgSize=%llu imgName=%s imgFile=%s\n",                 if (nameFlg & FD_SEEK) {
                        imgSize, imgName, argc ? imgFile : "<stdin>");                        iSize = lseek(img, 0, SEEK_END);
                         if (!imgSize)
                                 imgSize = E_ALIGN(iSize, bufSize);
                         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", 
                                                 iSize, imgSize);
                                 return 3;
                         } else
                                 lseek(img, 0, SEEK_SET);
                 }
   
        /* open storage device */                if (!imgSize) {
        img = open(imgName, O_RDWR | O_CREAT | tr, 0644);                        if (fd > 2)
        if (img == -1) {                                close(fd);
                ESYSERR(0);                        Usage();
                if (fd > 2)                        return 1;
                        close(fd);                }
                return 3; 
         }          }
         if (EmptyStore(img) == -1) {  
                 if (fd > 2)  
                         close(fd);  
                 close(img);  
                 unlink(imgName);  
                 return 3;  
         }  
   
        if (FillStore(img, fd) == -1) {        if (!m) {
                if (fd > 2)                if (EmptyStore(img, nameFlg) == -1) {
                        close(fd);                        if (fd > 2)
                close(img);                                close(fd);
                unlink(imgName);                        close(img);
                return 4;                        return 3;
                 }
                 if (FillStore(img, nameFlg, fd, fileFlg) == -1) {
                         if (fd > 2)
                                 close(fd);
                         close(img);
                         return 4;
                 }
         } else {        /* GET */
                 iSize ^= iSize;
                 if (!(fileFlg & FD_PIPE))
                         if (EmptyStore(fd, fileFlg) == -1) {
                                 if (fd > 2)
                                         close(fd);
                                 close(img);
                                 return 3;
                         }
                 if (FillStore(fd, fileFlg, img, nameFlg) == -1) {
                         if (fd > 2)
                                 close(fd);
                         close(img);
                         return 4;
                 }
         }          }
   
         close(img);          close(img);
         if (fd > 2)          if (fd > 2)
                 close(fd);                  close(fd);
   
           if (R)
                   reboot(RB_AUTOBOOT);
         return 0;          return 0;
 }  }

Removed from v.1.2  
changed lines
  Added in v.1.7


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