File:  [ELWIX - Embedded LightWeight unIX -] / embedtools / src / imgupd.c
Revision 1.5: download - view: text, annotated - select for diffs - revision graph
Wed Feb 5 23:11:55 2014 UTC (10 years, 4 months ago) by misho
Branches: MAIN
CVS tags: tools2_4, TOOLS2_3, HEAD
version 2.3

    1: /*************************************************************************
    2:  * (C) 2014 AITNET - Sofia/Bulgaria - <office@aitbg.com>
    3:  *  by Michael Pounov <misho@aitbg.com>
    4:  *
    5:  * $Author: misho $
    6:  * $Id: imgupd.c,v 1.5 2014/02/05 23:11:55 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 - 2014
   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: */
   46: #include "global.h"
   47: 
   48: 
   49: char imgName[PATH_MAX], imgFile[PATH_MAX];
   50: off_t imgSize, iSize;
   51: int Verbose, bufSize = IMGBUF_SIZE;
   52: extern char compiled[], compiledby[], compilehost[];
   53: 
   54: static void
   55: Usage()
   56: {
   57: 
   58: 	printf(	"IMGUPD is tool for management of images\n"
   59: 		"=== %s === %s@%s ===\n\n"
   60: 		"  Syntax: imgupd [options] [image_file]\n\n"
   61: 		"\t-v\t\tVerbose ...\n"
   62: 		"\t-R\t\tReboot system after complete\n"
   63: 		"\t-p\t\tPipe suitable transfer on little chunks\n"
   64: 		"\t-g\t\tGet image from Storage\n"
   65: 		"\t-t\t\tTruncate Storage file name\n"
   66: 		"\t-s <size>\tStorage size (required for stdin)\n"
   67: 		"\t-f <devfile>\tStorage file name\n"
   68: 		"\n", compiled, compiledby, compilehost);
   69: }
   70: 
   71: static int
   72: EmptyStore(int img)
   73: {
   74: 	register int i;
   75: 	u_char buf[bufSize];
   76: 	ssize_t wlen;
   77: 
   78: 	VERB(1) printf("Erase store %s\n", imgName);
   79: 
   80: 	iSize = lseek(img, 0, SEEK_END);
   81: 	if (iSize == -1) {
   82: 		ESYSERR(0);
   83: 		return -1;
   84: 	} else
   85: 		imgSize += E_ALIGN(iSize, bufSize);
   86: 
   87: 	memset(buf, 0, sizeof buf);
   88: 	for (i = howmany(iSize, bufSize); i < howmany(imgSize, bufSize); i++)
   89: 		if ((wlen = write(img, buf, bufSize)) == -1 || 
   90: 				(wlen && wlen != bufSize)) {
   91: 			EERROR(EIO, "Error at chunk %d init %d bytes, "
   92: 					"should be %u\n", i, wlen, bufSize);
   93: 			return -1;
   94: 		} else
   95: 			VERB(1) printf("+Written chunk #%d\n", i);
   96: 
   97: 	iSize = lseek(img, iSize, SEEK_SET);
   98: 	return iSize;
   99: }
  100: 
  101: static int
  102: FillStore(int img, int fd)
  103: {
  104: 	register int i, j;
  105: 	u_char buf[bufSize];
  106: 	ssize_t rlen, wlen;
  107: 
  108: 	VERB(1) printf("Fill store %s from image file %s\n", imgName, imgFile);
  109: 
  110: 	for (j = 0, i = howmany(iSize, bufSize); i < howmany(imgSize, bufSize); 
  111: 			i++, j++) {
  112: 		memset(buf, 0, sizeof buf);
  113: 		rlen = read(fd, buf, bufSize);
  114: 		if (rlen == -1) {
  115: 			ESYSERR(0);
  116: 			return -1;
  117: 		} else if (!rlen)
  118: 			break;
  119: 		else
  120: 			VERB(1) printf("+Readed %d bytes for chunk #%d\n", rlen, j);
  121: 
  122: 		wlen = write(img, buf, rlen);
  123: 		if (wlen == -1) {
  124: 			ESYSERR(0);
  125: 			return -1;
  126: 		} else if (!wlen || wlen != rlen) {
  127: 			EERROR(EIO, "Readed %d bytes are not equal to written %d bytes\n", 
  128: 					rlen, wlen);
  129: 		} else
  130: 			VERB(1) printf("+Written %d bytes at chunk #%d\n", wlen, i);
  131: 	}
  132: 
  133: 	return 0;
  134: }
  135: 
  136: int
  137: main(int argc, char **argv)
  138: {
  139: 	char ch, m = 0, R = 0;
  140: 	int fd, img, tr = 0;
  141: 
  142: 	while ((ch = getopt(argc, argv, "hvRpgts:f:")) != -1)
  143: 		switch (ch) {
  144: 			case 'f':
  145: 				strlcpy(imgName, optarg, sizeof imgName);
  146: 				break;
  147: 			case 's':
  148: 				imgSize = strtoll(optarg, NULL, 0);
  149: 				if (!imgSize) {
  150: 					Usage();
  151: 					return 1;
  152: 				}
  153: 				break;
  154: 			case 't':
  155: 				tr = O_TRUNC;
  156: 				break;
  157: 			case 'g':
  158: 				m = 1;
  159: 				break;
  160: 			case 'p':
  161: 				bufSize = IMGBUF_SIZE2;
  162: 				break;
  163: 			case 'R':
  164: 				R = 1;
  165: 				break;
  166: 			case 'v':
  167: 				Verbose++;
  168: 				break;
  169: 			case 'h':
  170: 			default:
  171: 				Usage();
  172: 				return 1;
  173: 		}
  174: 	argc -= optind;
  175: 	argv += optind;
  176: 
  177: 	if (!m) {
  178: 		if (argc) {
  179: 			strlcpy(imgFile, *argv, sizeof imgFile);
  180: 			/* open image file */
  181: 			fd = open(imgFile, O_RDONLY);
  182: 			if (fd == -1) {
  183: 				ESYSERR(0);
  184: 				return 2;
  185: 			} else
  186: 				iSize = lseek(fd, 0, SEEK_END);
  187: 			if (!imgSize)
  188: 				imgSize = E_ALIGN(iSize, bufSize);
  189: 			if (iSize == -1 || iSize > imgSize) {
  190: 				close(fd);
  191: 				EERROR(ENOSPC, "Error:: file size %llu is "
  192: 						"greater from storage size %llu\n", 
  193: 						iSize, imgSize);
  194: 				return 2;
  195: 			} else
  196: 				lseek(fd, 0, SEEK_SET);
  197: 		} else if (!imgSize) {
  198: 			Usage();
  199: 			return 1;
  200: 		} else
  201: 			fd = STDIN_FILENO;
  202: 	} else {	/* GET */
  203: 		if (argc) {
  204: 			strlcpy(imgFile, *argv, sizeof imgFile);
  205: 			/* open image file */
  206: 			fd = open(imgFile, O_WRONLY | O_TRUNC | O_CREAT, 0644);
  207: 			if (fd == -1) {
  208: 				ESYSERR(0);
  209: 				return 2;
  210: 			}
  211: 		} else if (!imgSize) {
  212: 			Usage();
  213: 			return 1;
  214: 		} else
  215: 			fd = STDOUT_FILENO;
  216: 	}
  217: 
  218: 	VERB(1) printf("imgSize=%llu imgName=%s imgFile=%s\n", 
  219: 			imgSize, imgName, argc ? imgFile : "<stdin>");
  220: 
  221: 	if (!m) {
  222: 		/* open storage device */
  223: 		img = open(imgName, O_RDWR | O_CREAT | tr, 0644);
  224: 		if (img == -1) {
  225: 			ESYSERR(0);
  226: 			if (fd > 2)
  227: 				close(fd);
  228: 			return 3;
  229: 		}
  230: 	} else {	/* GET */
  231: 		/* open storage device */
  232: 		img = open(imgName, O_RDONLY);
  233: 		if (img == -1) {
  234: 			ESYSERR(0);
  235: 			if (fd > 2)
  236: 				close(fd);
  237: 			return 3;
  238: 		} else
  239: 			iSize = lseek(img, 0, SEEK_END);
  240: 		if (!imgSize)
  241: 			imgSize = E_ALIGN(iSize, bufSize);
  242: 		if (iSize == -1 || iSize > imgSize) {
  243: 			if (fd > 2)
  244: 				close(fd);
  245: 			close(img);
  246: 			EERROR(ENOSPC, "Error:: storage size %llu is "
  247: 					"greater from file size %llu\n", 
  248: 					iSize, imgSize);
  249: 			return 3;
  250: 		} else
  251: 			lseek(img, 0, SEEK_SET);
  252: 	}
  253: 
  254: 	if (!m) {
  255: 		if (EmptyStore(img) == -1) {
  256: 			if (fd > 2)
  257: 				close(fd);
  258: 			close(img);
  259: 			return 3;
  260: 		}
  261: 		if (FillStore(img, fd) == -1) {
  262: 			if (fd > 2)
  263: 				close(fd);
  264: 			close(img);
  265: 			return 4;
  266: 		}
  267: 	} else {	/* GET */
  268: 		if (EmptyStore(fd) == -1) {
  269: 			if (fd > 2)
  270: 				close(fd);
  271: 			close(img);
  272: 			return 3;
  273: 		}
  274: 		if (FillStore(fd, img) == -1) {
  275: 			if (fd > 2)
  276: 				close(fd);
  277: 			close(img);
  278: 			return 4;
  279: 		}
  280: 	}
  281: 
  282: 	close(img);
  283: 	if (fd > 2)
  284: 		close(fd);
  285: 
  286: 	if (R)
  287: 		reboot(RB_AUTOBOOT);
  288: 	return 0;
  289: }

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