#include "global.h" char imgName[PATH_MAX], imgFile[PATH_MAX]; off_t imgSize, fSize, iSize; int Verbose; extern char compiled[], compiledby[], compilehost[]; static void Usage() { printf( "IMGUPD is tool for management of images\n" "=== %s === %s@%s ===\n\n" " Syntax: imgupd [options] \n\n" "\t-v\t\tVerbose ...\n" "\t-s \tStorage size\n" "\t-f \tStorage file name\n" "\n", compiled, compiledby, compilehost); } static int EmptyStore(int img) { register int i; u_char buf[IMGBLOCK_SIZE]; ssize_t wlen; VERB(1) printf("Erase store %s\n", imgName); memset(buf, 0, sizeof buf); for (i = 0; i < howmany(imgSize, IMGBLOCK_SIZE); i++) if ((wlen = write(img, buf, sizeof buf)) == -1 || wlen != sizeof buf) { EERROR(EIO, "Error at chunk %d init %d bytes, should be %u\n", i, wlen, sizeof buf); return -1; } else VERB(1) printf("+Written chunk #%d\n", i); iSize = lseek(img, 0, SEEK_END); return iSize; } static int FillStore(int img, int fd) { register int i; u_char buf[IMGBLOCK_SIZE]; ssize_t rlen, wlen; VERB(1) printf("Fill store %s from image file %s\n", imgName, imgFile); for (i = 0; i < howmany(imgSize, IMGBLOCK_SIZE); i++) { memset(buf, 0, sizeof buf); rlen = read(fd, buf, sizeof buf); if (rlen == -1) { ESYSERR(0); return -1; } else if (!rlen) break; else VERB(1) printf("+Readed %d bytes for chunk #%d\n", rlen, i); wlen = write(img, buf, rlen); if (wlen == -1) { ESYSERR(0); return -1; } else if (!wlen || wlen != rlen) { EERROR(EIO, "Readed %d bytes are not equal to written %d bytes\n", rlen, wlen); } else VERB(1) printf("+Written %d bytes at chunk #%d\n", wlen, i); } return 0; } int main(int argc, char **argv) { char ch; int fd, img; while ((ch = getopt(argc, argv, "hvs:f:")) != -1) switch (ch) { case 'f': strlcpy(imgName, optarg, sizeof imgName); break; case 's': imgSize = strtoll(optarg, NULL, 0); if (!imgSize) { Usage(); return 1; } break; case 'v': Verbose++; break; case 'h': default: Usage(); return 1; } argc -= optind; argv += optind; if (!argc || !*imgName || !imgSize) { Usage(); return 1; } else strlcpy(imgFile, *argv, sizeof imgFile); VERB(1) printf("imgSize=%llu imgName=%s imgFile=%s\n", imgSize, imgName, imgFile); /* open image file */ fd = open(imgFile, O_RDONLY); if (fd == -1) { ESYSERR(0); return 2; } else fSize = lseek(fd, 0, SEEK_END); if (fSize == -1 || fSize > imgSize) { close(fd); printf("Error:: file size %llu is greater from storage size %llu\n", fSize, imgSize); return 2; } else lseek(fd, 0, SEEK_SET); /* open storage device */ img = open(imgName, O_RDWR | O_CREAT, 0644); if (img == -1) { ESYSERR(0); close(fd); return 3; } if (EmptyStore(img) == -1 || iSize < imgSize) { close(fd); close(img); unlink(imgName); printf("Error:: current storage size %llu is smaller from storage size %llu\n", iSize, imgSize); return 3; } else lseek(img, 0, SEEK_SET); if (FillStore(img, fd) == -1) { close(fd); close(img); unlink(imgName); return 4; } close(img); close(fd); return 0; }