#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", imgfd);
printf("FW Image empty byte: 0x%02x\n\n", fillCh);
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)
{
u_char buf[BUFSIZ];
int wlen;
size_t siz;
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) {
memset(buf, fillCh, sizeof buf);
imgsiz = siz = (size_t) strtol(args[1], NULL, 0);
if (ftruncate(imgfd, imgsiz) == -1) {
ESYSERR(0);
imageClose();
unlink(image);
return -1;
}
lseek(imgfd, 0, SEEK_SET);
while (siz > 0) {
wlen = MIN(siz, sizeof buf);
wlen = write(imgfd, buf, wlen);
if (wlen < 1) {
ESYSERR(0);
imageClose();
unlink(image);
return -1;
} else
siz -= wlen;
}
EVERBOSE(1, "Image '%s' created successful with size=%lu/remain=#%lu bytes\n",
image, imgsiz, siz);
}
} else {
printf("Error:: unknown command '%s'\n", args[0]);
return -1;
}
return 0;
}
int
cmd_FillCh(void *lb, int idx, char **args)
{
char str[STRSIZ];
ETRACE();
args++;
if (!args[0]) {
if (!dialog(lb, "Byte=", str, sizeof str))
fillCh = (u_char) strtol(str, NULL, 0);
else
return -1;
} else
fillCh = (u_char) strtol(args[0], NULL, 0);
return 0;
}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>