File:  [ELWIX - Embedded LightWeight unIX -] / fwmaker / src / cmds.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Sun Jan 4 18:08:18 2026 UTC (13 days, 12 hours ago) by misho
Branches: MAIN
CVS tags: HEAD
Initial revision

#include "global.h"
#include "cmds.h"
#include "image.h"


int
cmd_Show(void *lb, int idx, char **args)
{
	ETRACE();

	printf("FW Image file: %s\n", image);
	printf("FW Image size: %zu\n", imgsiz);
	printf("FW Image descriptor: %d\n\n", imgfd);

	printf("MTD loaded: 0x%zx\n", mtd.mtd_fsiz);
	printf("MTD file: %s\n", mtd.mtd_file);
	printf("MTD offset: 0x%lx\n", mtd.mtd_offset);
	printf("MTD size: 0x%zx\n", mtd.mtd_size);

	return 0;
}

static int
dialog(void *lb, const char *prompt, char *str, int len)
{
	int ret = 0;
	char *p;

	if (!str || len < 1)
		return -1;

	cli_Printf(lb, "%s", prompt);
	p = cliInputLine(lb, -1);
	if (p) {
		cli_freeInput(lb);
		strlcpy(str, p, len);
		e_free(p);

		if ((p = strpbrk(str, "\r\n")))
			*p = 0;
	}

	return ret;
}

static void
loadparams(void *lb, char ** const args)
{
	char str[STRSIZ];

	memset(&mtd, 0, sizeof mtd);
	if (!args[1]) {
		if (!dialog(lb, "Offset=", str, sizeof str))
			mtd.mtd_offset = (off_t) strtol(str, NULL, 0);
	} else
		mtd.mtd_offset = (off_t) strtol(args[1], NULL, 0);
	EVERBOSE(3, "mtd.offset=0x%lx", mtd.mtd_offset);
	if (!args[2]) {
		if (!dialog(lb, "Size=", str, sizeof str))
			mtd.mtd_size = (size_t) strtol(str, NULL, 0);
	} else
		mtd.mtd_size = (size_t) strtol(args[2], NULL, 0);
	EVERBOSE(3, "mtd.size=0x%zx", mtd.mtd_size);
}

static int
openfile(int flgs)
{
	int fd;

	fd = open(mtd.mtd_file, flgs, 0644);
	if (fd == -1) {
		ESYSERR(0);
		return -1;
	}
	if (lseek(imgfd, mtd.mtd_offset, SEEK_SET) == -1) {
		ESYSERR(0);
		close(fd);
		return -1;
	}

	EVERBOSE(1, "mtd_file %s opened #%d", mtd.mtd_file, fd);
	return fd;
}

static void
closefile(int fd)
{
	EVERBOSE(1, "mtd_file closed #%d", fd);
	close(fd);
}

int
cmd_Mtd(void *lb, int idx, char **args)
{
	char str[MAXPATHLEN];
	struct stat st;
	int fd, wlen = 0, rlen = 0;
	u_char buf[BUFSIZ] = { 0 };

	ETRACE();

	args++;
	if (!args[0]) {
		printf("Help: mtd [read|write|erase] <mtd_offset> <mtd_size> [mtd_bin_file]\n");
		return -1;
	} else if (!strncmp(args[0], "write", strlen(args[0]))) {
		loadparams(lb, args);
		if (!args[3]) {
			if (!dialog(lb, "File=", str, sizeof str))
				strlcpy(mtd.mtd_file, str, sizeof mtd.mtd_file);
		} else
			strlcpy(mtd.mtd_file, args[3], sizeof mtd.mtd_file);
		EVERBOSE(3, "mtd.file=%s", mtd.mtd_file);

		if (stat(mtd.mtd_file, &st) == -1) {
			ESYSERR(0);
			memset(&mtd, 0, sizeof mtd);
			return -1;
		} else
			mtd.mtd_fsiz = st.st_size;
		EVERBOSE(3, "mtd.fsiz=%lu", mtd.mtd_fsiz);
		if (mtd.mtd_size < mtd.mtd_fsiz) {
			printf("Error:: MTD file is bigger then reserved space!\n");
			memset(&mtd, 0, sizeof mtd);
			return -1;
		}
		if (imgfd < 3) {
			printf("Error:: image isn't present!\n");
			memset(&mtd, 0, sizeof mtd);
			return -1;
		}
		if (imgsiz < mtd.mtd_offset + mtd.mtd_size) {
			printf("Error:: requested region for write is out of image size\n");
			memset(&mtd, 0, sizeof mtd);
			return -1;
		}

		fd = openfile(O_RDONLY);
		if (fd == -1) {
			memset(&mtd, 0, sizeof mtd);
			return -1;
		}
		while ((rlen = read(fd, buf, sizeof buf)) > 0)
			if ((rlen = write(imgfd, buf, rlen)) == -1)
				break;
			else
				wlen += rlen;
		if (rlen == -1) {
			ESYSERR(0);
			memset(&mtd, 0, sizeof mtd);
		} else if (!rlen)
			printf("MTD partition size=%d was written to image\n", wlen);
		closefile(fd);
	} else if (!strncmp(args[0], "read", strlen(args[0]))) {
		loadparams(lb, args);
		if (!args[3]) {
			if (!dialog(lb, "File=", str, sizeof str))
				strlcpy(mtd.mtd_file, str, sizeof mtd.mtd_file);
		} else
			strlcpy(mtd.mtd_file, args[3], sizeof mtd.mtd_file);
		EVERBOSE(3, "mtd.file=%s", mtd.mtd_file);

		if (imgfd < 3) {
			printf("Error:: image isn't present!\n");
			memset(&mtd, 0, sizeof mtd);
			return -1;
		}
		if (imgsiz < mtd.mtd_offset + mtd.mtd_size) {
			printf("Error:: requested region for read is out of image size\n");
			memset(&mtd, 0, sizeof mtd);
			return -1;
		}

		fd = openfile(O_WRONLY | O_CREAT);
		if (fd == -1) {
			memset(&mtd, 0, sizeof mtd);
			return -1;
		}
		while (wlen < mtd.mtd_size &&
				(rlen = read(imgfd, buf, MIN(mtd.mtd_size - wlen, sizeof buf))) > 0)
			if ((rlen = write(fd, buf, rlen)) == -1)
				break;
			else
				wlen += rlen;
		if (rlen == -1) {
			ESYSERR(0);
			memset(&mtd, 0, sizeof mtd);
		} else
			printf("MTD image partition size=%d was transferred file\n", wlen);
		closefile(fd);
	} else if (!strncmp(args[0], "erase", strlen(args[0]))) {
		loadparams(lb, args);

		if (imgfd < 3) {
			printf("Error:: image isn't present!\n");
			memset(&mtd, 0, sizeof mtd);
			return -1;
		}
		if (imgsiz < mtd.mtd_offset + mtd.mtd_size) {
			printf("Error:: requested region for erase is out of image size\n");
			memset(&mtd, 0, sizeof mtd);
			return -1;
		}
		if (lseek(imgfd, mtd.mtd_offset, SEEK_SET) == -1) {
			ESYSERR(0);
			memset(&mtd, 0, sizeof mtd);
			return -1;
		}
		while (wlen < mtd.mtd_size)
			if ((rlen = write(imgfd, buf, MIN(mtd.mtd_size - wlen, sizeof buf))) == -1)
				break;
			else
				wlen += rlen;
		if (rlen == -1) {
			ESYSERR(0);
			memset(&mtd, 0, sizeof mtd);
		} else
			printf("MTD image partition size=%d was erased\n", wlen);
	} else {
		printf("Error:: unknown command '%s'\n", args[0]);
		return -1;
	}

	return 0;
}

int
cmd_Image(void *lb, int idx, char **args)
{
	ETRACE();

	args++;
	if (!args[0]) {
		printf("Help: image [mount|umount|erase|name <file>|init <size>]\n");
		return -1;
	} else if (!strncmp(args[0], "mount", strlen(args[0]))) {
		if (imgfd > 2) {
			printf("Error:: Image is already mounted ...\n");
			return -1;
		}
		imageOpen(0);
	} else if (!strncmp(args[0], "umount", strlen(args[0]))) {
		imageClose();
	} else if (!strcmp(args[0], "erase")) {
		if (imgfd > 2) {
			printf("Error:: Image is mounted, cannot be erased ...\n");
			return -1;
		}
		unlink(image);
		EVERBOSE(1, "Erase image %s\n", image);
	} else if (!strncmp(args[0], "name", strlen(args[0]))) {
		if (imgfd > 2) {
			printf("Error:: Image is mounted, cannot be renamed ...\n");
			return -1;
		}
		if (!args[1]) {
			printf("Error:: name isn't found!\n");
			return -1;
		}
		strlcpy(image, args[1], sizeof image);
	} else if (!strncmp(args[0], "init", strlen(args[0]))) {
		if (imgfd > 2) {
			printf("Error:: Image is already mounted, cannot be inited ...\n");
			return -1;
		}
		if (!args[1]) {
			printf("Error:: size isn't found!\n");
			return -1;
		}
		if (imageOpen(O_CREAT) > 2) {
			imgsiz = (size_t) strtol(args[1], NULL, 0);
			if (ftruncate(imgfd, imgsiz) == -1) {
				ESYSERR(0);
				imageClose();
				unlink(image);
				return -1;
			} else
				EVERBOSE(1, "Image '%s' created with size=%lu\n", image, imgsiz);
		}
	} else {
		printf("Error:: unknown command '%s'\n", args[0]);
		return -1;
	}

	return 0;
}

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