Example #1
0
/*
 * Open device and perform command
 */
int
main(int argc, char **argv)
{
	struct k8048 k;
	char *execdup, *execname;

	/* Initialise to NULL/0 */
	memset(&k, 0, sizeof(k));

	/* Get exec name */
	execdup = (char *)strdup(argv[0]);
	if (execdup == NULL) {
		printf("%s: fatal error: strdup failed\n", __func__);
		io_exit(&k, EX_OSERR); /* Panic */
	}
	execname = basename(execdup);
	if (execname == NULL) {
		printf("%s: fatal error: basename failed\n", __func__);
		io_exit(&k, EX_OSERR); /* Panic */
	}

	/* Get configuration */
	getconf(&k);
	
	/* Command: k8048 */
	if (strcmp(execname, "k8048") == 0) {
		resetuid(&k);
		usage_k8048(&k);
	}
#ifdef TTY
	/* Command: kload */
	if (strcmp(execname, "kload") == 0) {
		resetuid(&k);
		if (argc < 3)
			usage_kload(&k, "Missing arg");
		if (argc > 5)
			usage_kload(&k, "Too many args");

		int prog_mode = tolower((int)argv[1][0]);
		if (prog_mode != 'p' && prog_mode != 'v')
			usage_kload(&k, "Invalid mode");

		if (argv[2][0] == '/' && strstr(argv[2], "/dev/tty") != argv[2])
			usage_kload(&k, "Invalid tty");

		char file[STRLEN];
		strcpy(file, "-");
		if (argc >= 4)
			strncpy(file, argv[3], STRMAX);

		int target = 'n';
		if (argc == 5) {
			target = tolower((int)argv[4][0]);
			if (target != 'a')
				usage_kload(&k, "Invalid target");
		}

		io_signal_on(k); // !SIGPIPE
		stk500v2_load(&k, prog_mode, argv[2], file, target);
		io_exit(&k, EX_OK);
	}
#endif
	/* Open device */
	if (io_open(&k) < 0) {
#ifdef KTEST
		if (strcmp(execname, "ktest") == 0)
			usage_ktest(&k, io_error(&k));
#endif
		usage(&k, execname, io_error(&k));
	}

	/* Raise priority */
	setpriority(PRIO_PROCESS, 0, -20);

	/* Reset user */
	resetuid(&k);
#ifdef KCTRL
	/* Command: kctrl */
	if (strcmp(execname, "kctrl") == 0) {
		if (argc < 2)
			usage_kctrl(&k, "Missing arg");
		if (argc > 2)
			usage_kctrl(&k, "Too many args");
		if (strcasecmp(argv[1], "RUN") == 0) {
			io_close(&k, HIGH);
			printf("RUN\n");
		} else if (strcasecmp(argv[1], "STOP") == 0) {
			io_close(&k, LOW);
			printf("STOP\n");
		} else if (strcasecmp(argv[1], "RESTORE") == 0) {
			io_set_vpp(&k, LOW);
			io_usleep(&k, 10);
			io_close(&k, HIGH);
			printf("RESTORE\n");
		}
		io_exit(&k, EX_OK);
	}
#endif
#ifdef KTEST
	/* Command: ktest */
	if (strcmp(execname, "ktest") == 0) {
		if (argc < 3)
			usage_ktest(&k, "Missing args");
		if (argc > 3)
			usage_ktest(&k, "Too many args");
		int32_t testarg = strtol(argv[2], NULL, 0);
		if (testarg < 0)
			usage_ktest(&k, "Invalid arg");

		if (strcasecmp(argv[1], "VPP") == 0) 
			io_test0(&k, 0, testarg);
		else if (strcasecmp(argv[1], "PGC") == 0)
			io_test0(&k, 1, testarg);
		else if (strcasecmp(argv[1], "PGD") == 0)
			io_test0(&k, 2, testarg);
		else if (strcasecmp(argv[1], "PGM") == 0)
			io_test0(&k, 3, testarg);
		else if (argv[1][0] >= '0' && argv[1][0] <= '9') {
			int32_t test = strtol(argv[1], NULL, 0);
			switch (test) {
#ifdef RPI
			case 0: gpio_test(&k, testarg);break;
#endif
			case 1: io_test1(&k, testarg); break;
			case 2: io_test2(&k, testarg); break;
			case 3: io_test3(&k, testarg); break;
			case 4: io_test4(&k, testarg); break;
#if defined(KTEST) && defined(KIO)
			case 5: io_test5(&k, testarg); break;
#endif
			default:usage_ktest(&k, "Invalid arg");break;
			}
		} else {
			usage_ktest(&k, "Invalid arg");
		}
		io_exit(&k, EX_OK);
	}
#endif
	/* Determine arch: k12 | k14 | k16 | k24 | k32 */
	if (pic_arch(&k, execname) == 0)
		usage_k8048(&k);
	if (argc < 2)
		usage(&k, execname, "Missing arg(s)");

	/* Device selection */
	int argv1 = tolower((int)argv[1][0]);
	if (argv1 == 's') { /* Select device */
		if (argc < 3) {
			pic_selector(&k);
			io_exit(&k, EX_OK);
		}
		if (mystrcasestr(argv[2], "dspic") == argv[2]) {
			strncpy(k.devicename, argv[2], STRLEN);
		} else if (mystrcasestr(argv[2], "pic") == argv[2]) {
			strncpy(k.devicename, argv[2], STRLEN);
		} else {
			int32_t temp = strtol(argv[2], NULL, 0);
			if (temp < 10 || temp > 33) {
				usage(&k, execname, "Invalid arg [select]");
			}
			if (temp == 30 || temp == 33) {
				strcpy(k.devicename, "dspic");
				strncpy(&k.devicename[5], argv[2], STRLEN - 5);
			} else {
				strcpy(k.devicename, "pic");
				strncpy(&k.devicename[3], argv[2], STRLEN - 3);
			}
		}
		argc -= 2;
		argv += 2;
		if (argc < 2)
			usage(&k, execname, "Missing arg(s)");
	} else if (k.pic->arch == ARCH12BIT) {
		usage(&k, execname, "Missing select");
	}

	/* Key entry */
	argv1 = tolower((int)argv[1][0]);
	if (argv1 == 'l') {			/* LVP 32-bit key entry */
		if (k.pic->arch == ARCH12BIT) {
			usage(&k, execname, "Invalid arg [lvp]");
		}
		/* ARCH14BIT || ARCH16BIT || ARCH24BIT || ARCH32BIT */
		k.key = LVPKEY;
		argc -= 1;
		argv += 1;
		if (argc < 2)
			usage(&k, execname, "Missing arg(s)");
	}
	else if (argv1 == 'h') {		/* HVP 32-bit key entry */
		if (k.pic->arch == ARCH12BIT || k.pic->arch == ARCH14BIT || k.pic->arch == ARCH32BIT) {
			usage(&k, execname, "Invalid arg [hvp]");
		}
		/* ARCH16BIT || ARCH24BIT */
		k.key = HVPKEY;
		argc -= 1;
		argv += 1;
		if (argc < 2)
			usage(&k, execname, "Missing arg(s)");
	}
	else if (k.pic->arch == ARCH32BIT) {	/* LVP 32-bit key entry */
		/* ARCH32BIT */
		k.key = LVPKEY;
	}
	else {					/* No key entry */
		/* ARCH12BIT || ARCH14BIT || ARCH16BIT || ARCH24BIT */
		k.key = NOKEY;
	}

	/* Command */
	argv1 = tolower((int)argv[1][0]);
	int argv11 = tolower((int)argv[1][1]);
	switch (argv1) {
	case 'b':	if (argv11 == 'o') {		/* BOOT */
				uint32_t addr = UINT32_MAX, words = UINT32_MAX;
				if (argc > 4)
					usage(&k, execname, "Too many args [boot]");
				if (argc >= 3) {
					words = strtoul(argv[2], NULL, 0);
					if (words == 0)
						usage(&k, execname, "Invalid arg [boot]");
				}
				if (argc == 4) {
					addr = strtoul(argv[3], NULL, 0);
				}
				pic_dumpboot(&k, addr, words);
			} else {			/* BLANK */
				if (argc > 2)
					usage(&k, execname, "Too many args [blank]");
				if (areyousure("Blank device"))
					pic_blank(&k);
			}
			break;

	case 'c':	if (argc > 3)
				usage(&k, execname, "Too many args [config]");
			if (argc == 2)
				pic_dumpconfig(&k);
			else
				pic_writebandgap(&k, strtoul(argv[2], NULL, 0));
			break;
	
	case 'd':	if (argv11 == 'a') {		/* DATA */
				if (argc > 2)
					usage(&k, execname, "Too many args [data]");
				pic_dumpdata(&k);
			} else if (argv11 == 'e') { 	/* DEBUG */
				printf("Hello world!\n");
			} else {			/* DUMP */
				if (argc > 2)
					usage(&k, execname, "Too many args [dump]");
				pic_dumpdevice(&k);
			}
			break;

	case 'e':	if (argv11 == 'r') {		/* ERASE FLASH | ID | ROW[NROWS] */
				uint32_t row = 0, nrows = 1;
				char prompt[STRLEN] = {0}, *endptr = NULL;

				if (argc < 3)
					usage(&k, execname, "Missing arg [erase]");
				if (argc > 4)
					usage(&k, execname, "Too many args [erase]");
				
				int argv2 = tolower((int)argv[2][0]);
				switch (argv2) {
				case 'i': /* IDLOCATION    */
				case 'u': /* USERID/CONFIG */
					row = PIC_ERASE_ID;
					strncpy(prompt, "Erase id", STRLEN);
					break;
				case 'c': /* CONFIG */
					row = PIC_ERASE_CONFIG;
					strncpy(prompt, "Erase config", STRLEN);
					break;
				case 'e': /* EEPROM */
					row = PIC_ERASE_EEPROM;
					strncpy(prompt, "Erase EEPROM", STRLEN);
					break;
				case 'f': /* FLASH */
					nrows = UINT32_MAX;
					strncpy(prompt, "Erase program flash", STRLEN);
					break;
				default:  /* FLASH ROW */
					row = strtoul(argv[2], &endptr, 0);
					if (endptr == argv[2])
						usage(&k, execname, "Invalid arg [erase]");
					if (argc == 4) {
						nrows = strtoul(argv[3], NULL, 0);
						if (nrows == 0)
							usage(&k, execname, "Invalid arg [erase]");
					}
					snprintf(prompt, STRLEN, "Erase %u row(s) at row %u",
						nrows, row);
					break;
				}
				if (areyousure(prompt))
					pic_erase(&k, row, nrows);
			} else if (argv11 == 'x') {	/* EXECUTIVE */
				uint32_t addr = UINT32_MAX, words = UINT32_MAX;
				if (argc > 4)
					usage(&k, execname, "Too many args [executive]");
				if (argc >= 3) {
					words = strtoul(argv[2], NULL, 0);
					if (words == 0)
						usage(&k, execname, "Invalid arg [executive]");
				}
				if (argc == 4) {
					addr = strtoul(argv[3], NULL, 0);
				}
				pic_dumpexec(&k, addr, words);
			} else {			/* EEPROM */
				if (argc > 2)
					usage(&k, execname, "Too many args [eeprom]");
				pic_dumpdata(&k);
			}
			break;

	case 'f':	{
			uint32_t words = UINT32_MAX, addr = UINT32_MAX;
			if (argc > 4)
				usage(&k, execname, "Too many args [program flash]");
			if (argc >= 3) {
				words = strtoul(argv[2], NULL, 0);
				if (words == 0)
					usage(&k, execname, "Invalid arg [program flash]");
			}
			if (argc == 4) {
				addr = strtoul(argv[3], NULL, 0);
			}
			pic_dumpprogram(&k, addr, words);
			}
			break;

	case 'i':	if (argc > 2)
				usage(&k, execname, "Too many args [id]");
			pic_dumpdeviceid(&k);
			break;

	case 'o':	if (argc > 3)
				usage(&k, execname, "Too many args [osccal]");
			if (argc == 2)
				pic_dumposccal(&k);
			else
				pic_writeosccal(&k, strtoul(argv[2], NULL, 0));
			break;

	case 'p':	{
			int blank = 1;
			if (argc > 4)
				usage(&k, execname, "Too many args [program]");
			if (argc == 4) switch (argv[3][0]) {
				case 'n':
				case 'N':
				case '0': blank = 0;
					break;
				case 'y':
				case 'Y':
				case '1': blank = 1;
					break;
				default:usage(&k, execname, "Invalid arg [program]");
					break;
			}
			if (argc < 3)
				pic_program(&k, "-", 1);
			else
				pic_program(&k, argv[2], blank);
			}
			break;

	case 'v':	if (argv11 == 'i') {		/* VIEW */
				if (argc > 3)
					usage(&k, execname, "Too many args [view]");
				if (argc < 3)
					pic_view(&k, "-");
				else
					pic_view(&k, argv[2]);
			} else {			/* VERIFY */
				if (argc > 3)
					usage(&k, execname, "Too many args [verify]");
				if (argc < 3)
					pic_verify(&k, "-");
				else
					pic_verify(&k, argv[2]);
			}
			break;
#ifdef TTY
	case '/':	if (strstr(argv[1], "/dev/tty") != argv[1]) {
				usage(&k, execname, "Invalid device [TTY]");
			}
			if (strstr(argv[1], k.device) != NULL) {
				usage(&k, execname, "Device in use [TTY]");
			}
			stk500v2_listen(&k, argv[1], 0);
			break;

	case '8':	stk500v2_listen(&k, "0.0.0.0", 8048);
			break;
#endif
	default:	usage(&k, execname, "Unknown operation");
			break;
	}

	free(execdup);
	io_exit(&k, EX_OK);
}
Example #2
0
/*
 * Open device and perform command
 */
int
main(int argc, char **argv)
{
	char *execdup, *execname;
	int rc = EX_OK;

	/* Get exec name */
	execdup = (char *)strdup(argv[0]);
	if (execdup == NULL) {
		printf("%s: fatal error: strdup failed\n", __func__);
		io_exit(EX_OSERR); /* Panic */
	}
	execname = basename(execdup);
	if (execname == NULL) {
		printf("%s: fatal error: basename failed\n", __func__);
		io_exit(EX_OSERR); /* Panic */
	}

	/* Get configuration */
	getconf();
	
	/* Open device */
	if (io_open() < 0) {
		usage(execname, io_error());
	}

	/* Raise priority */
	setpriority(PRIO_PROCESS, 0, -20);

	/* Reset uid */
	if (getuid() != geteuid()) {
		if (setuid(getuid()) < 0) {
			printf("%s: fatal error: setuid failed\n", __func__);
			io_exit(EX_OSERR); /* Panic */
		}
	}

	/* Determine arch: 12 | 14 | 16 | 24 | 32 */
	if (pic_arch(execname) == 0)
		usage_pickle();

	/* Perform operation */
	if (argc < 2)
		usage(execname, "Missing arg(s)");

	/* Device selection */
	int argv1 = tolower((int)argv[1][0]);
	if (argv1 == 's') { /* Select device */
		if (argc < 3) {
			pic_selector();
			io_exit(EX_OK);
		}
		if (mystrcasestr(argv[2], "dspic") == argv[2]) {
			strncpy(p.devicename, argv[2], STRLEN);
		} else if (mystrcasestr(argv[2], "pic") == argv[2]) {
			strncpy(p.devicename, argv[2], STRLEN);
		} else {
			int32_t temp = strtol(argv[2], NULL, 0);
			if (temp < 10 || temp > 33) {
				usage(execname, "Invalid arg [select]");
			}
			if (temp == 30 || temp == 33) {
				strcpy(p.devicename, "dspic");
				strncpy(&p.devicename[5], argv[2], STRLEN - 5);
			} else {
				strcpy(p.devicename, "pic");
				strncpy(&p.devicename[3], argv[2], STRLEN - 3);
			}
		}
		argc -= 2;
		argv += 2;
		if (argc < 2)
			usage(execname, "Missing arg(s)");
	} else if (p.pic->arch == ARCH12BIT) {
		usage(execname, "Missing select");
	}

	/* Key entry */
	argv1 = tolower((int)argv[1][0]);
	if (argv1 == 'l') {			/* LVP 32-bit key entry */
		if (p.pic->arch == ARCH12BIT) {
			usage(execname, "Invalid arg [lvp]");
		}
		/* ARCH14BIT || ARCH16BIT || ARCH24BIT || ARCH32BIT */
		p.key = LVPKEY;
		argc -= 1;
		argv += 1;
		if (argc < 2)
			usage(execname, "Missing arg(s)");
	}
	else if (argv1 == 'h') {		/* HVP 32-bit key entry */
		if (p.pic->arch == ARCH12BIT || p.pic->arch == ARCH14BIT || p.pic->arch == ARCH32BIT) {
			usage(execname, "Invalid arg [hvp]");
		}
		/* ARCH16BIT || ARCH24BIT */
		p.key = HVPKEY;
		argc -= 1;
		argv += 1;
		if (argc < 2)
			usage(execname, "Missing arg(s)");
	}
	else if (p.pic->arch == ARCH32BIT) {	/* LVP 32-bit key entry */
		/* ARCH32BIT */
		p.key = LVPKEY;
	}
	else {					/* No key entry */
		/* ARCH12BIT || ARCH14BIT || ARCH16BIT || ARCH24BIT */
		p.key = NOKEY;
	}

	/* Command */
	argv1 = tolower((int)argv[1][0]);
	int argv11 = tolower((int)argv[1][1]);
	switch (argv1) {
	case 'b':	if (argv11 == 'o') {		/* BOOT */
				uint32_t addr = UINT32_MAX, words = UINT32_MAX;
				if (argc > 4)
					usage(execname, "Too many args [boot]");
				if (argc >= 3) {
					words = strtoul(argv[2], NULL, 0);
					if (words == 0)
						usage(execname, "Invalid arg [boot]");
				}
				if (argc == 4) {
					addr = strtoul(argv[3], NULL, 0);
				}
				pic_dumpboot(addr, words);
			} else {			/* BLANK */
				int config = 1;
				if (argc > 3)
					usage(execname, "Too many args [blank]");
				if (argc == 3) switch (argv[2][0]) {
					case 'n':
					case 'N':
					case '0': config = 0;
						break;
					case 'y':
					case 'Y':
					case '1': config = 1;
						break;
					default:usage(execname, "invalid arg [blank]");
						break;
				}
				if (areyousure("Blank device")) {
					pic_blank(config);
				}
			}
			break;

	case 'c':	if (argc > 3)
				usage(execname, "Too many args [config]");
			if (argc == 2)
				pic_dumpconfig();
			else
				pic_writebandgap(strtoul(argv[2], NULL, 0));
			break;
	
	case 'd':	if (argv11 == 'a') {		/* DATA */
				if (argc > 2)
					usage(execname, "Too many args [data]");
				pic_dumpdata();
			} else if (argv11 == 'e') { 	/* DEBUG */
				pic_debug();
			} else {			/* DUMP */
				if (argc > 2)
					usage(execname, "Too many args [dump]");
				pic_dumpdevice();
			}
			break;

	case 'e':	if (argv11 == 'r') {		/* ERASE FLASH | ID | ROW[NROWS] */
				uint32_t row = 0, nrows = 1;
				char prompt[STRLEN] = {0}, *endptr = NULL;

				if (argc < 3)
					usage(execname, "Missing arg [erase]");
				if (argc > 4)
					usage(execname, "Too many args [erase]");
				
				int argv2 = tolower((int)argv[2][0]);
				switch (argv2) {
				case 'i': /* IDLOCATION    */
				case 'u': /* USERID/CONFIG */
					row = PIC_ERASE_ID;
					strncpy(prompt, "Erase id", STRLEN);
					break;
				case 'c': /* CONFIG */
					row = PIC_ERASE_CONFIG;
					strncpy(prompt, "Erase config", STRLEN);
					break;
				case 'e': /* EEPROM */
					row = PIC_ERASE_EEPROM;
					strncpy(prompt, "Erase EEPROM", STRLEN);
					break;
				case 'f': /* FLASH */
					nrows = UINT32_MAX;
					strncpy(prompt, "Erase program flash", STRLEN);
					break;
				default:  /* FLASH ROW */
					row = strtoul(argv[2], &endptr, 0);
					if (endptr == argv[2])
						usage(execname, "Invalid arg [erase]");
					if (argc == 4) {
						nrows = strtoul(argv[3], NULL, 0);
						if (nrows == 0)
							usage(execname, "Invalid arg [erase]");
					}
					snprintf(prompt, STRLEN, "Erase %u row(s) at row %u",
						nrows, row);
					break;
				}
				if (areyousure(prompt))
					pic_erase(row, nrows);
			} else if (argv11 == 'x') {	/* EXECUTIVE */
				uint32_t addr = UINT32_MAX, words = UINT32_MAX;
				if (argc > 4)
					usage(execname, "Too many args [executive]");
				if (argc >= 3) {
					words = strtoul(argv[2], NULL, 0);
					if (words == 0)
						usage(execname, "Invalid arg [executive]");
				}
				if (argc == 4) {
					addr = strtoul(argv[3], NULL, 0);
				}
				pic_dumpexec(addr, words);
			} else {			/* EEPROM */
				if (argc > 2)
					usage(execname, "Too many args [eeprom]");
				pic_dumpdata();
			}
			break;

	case 'f':	{
			uint32_t words = UINT32_MAX, addr = UINT32_MAX;
			if (argc > 4)
				usage(execname, "Too many args [program flash]");
			if (argc >= 3) {
				words = strtoul(argv[2], NULL, 0);
				if (words == 0)
					usage(execname, "Invalid arg [program flash]");
			}
			if (argc == 4) {
				addr = strtoul(argv[3], NULL, 0);
			}
			pic_dumpprogram(addr, words);
			}
			break;

	case 'i':	if (argc > 2)
				usage(execname, "Too many args [id]");
			pic_dumpdeviceid();
			break;

	case 'o':	if (argc > 3)
				usage(execname, "Too many args [osccal]");
			if (argc == 2)
				pic_dumposccal();
			else
				pic_writeosccal(strtoul(argv[2], NULL, 0));
			break;

	case 'p':	{
			int blank = 1;
			if (argc > 4)
				usage(execname, "Too many args [program]");
			if (argc == 4) switch (argv[3][0]) {
				case 'n':
				case 'N':
				case '0': blank = 0;
					break;
				case 'y':
				case 'Y':
				case '1': blank = 1;
					break;
				default:usage(execname, "invalid arg [program]");
					break;
			}
			if (argc < 3)
				pic_program("-", 1);
			else
				pic_program(argv[2], blank);
			}
			break;

	case 'v':	if (argv11 == 'i') {		/* VIEW */
				int raw = 0;
				if (argc > 4)
					usage(execname, "Too many args [view]");
				if (argc == 4) switch (argv[3][0]) {
					case 'r':
					case 'R': raw = 1;
						break;
					default:usage(execname, "invalid arg [view]");
						break;
				}
				if (argc < 3)
					pic_view("-", 0);
				else
					pic_view(argv[2], raw);
			} else {			/* VERIFY */
				if (argc > 3)
					usage(execname, "Too many args [verify]");
				if (argc < 3)
					rc = 0 - pic_verify("-");
				else
					rc = 0 - pic_verify(argv[2]);
			}
			break;
#ifdef TTY
	case '/':	if (strstr(argv[1], "/dev/tty") != argv[1]) {
				usage(execname, "Invalid device [TTY]");
			}
			if (strstr(argv[1], p.device) != NULL) {
				usage(execname, "Device in use [TTY]");
			}
			stk500v2_listen(argv[1], 0);
			break;

	case '8':	stk500v2_listen("0.0.0.0", 8048);
			break;
#endif
	default:	usage(execname, "Unknown operation");
			break;
	}

	free(execdup);
	io_exit(rc);
}