1
0
Files
irix-657m-src/eoe/cmd/vom/exprobe.c
2022-09-29 17:59:04 +03:00

233 lines
4.3 KiB
C

"PR_NOTTOK",
"PR_OPAR",
"PR_CPAR",
"PR_COMMA",
"PR_RWSEQ",
"PR_NUMBER",
"PR_OPAR_or_RWSEQ",
"PR_COM_or_CPAR"
};
#endif
struct Vtuple {
struct Vtuple *next;
char *rwseq;
unsigned long values[4];
};
#define POS_ADDR 0
#define POS_SIZE 1
#define POS_VALUE 2
#define POS_MASK 3
#define V_addr values[POS_ADDR]
#define V_size values[POS_SIZE]
#define V_value values[POS_VALUE]
#define V_mask values[POS_MASK]
static struct Vtuple *Vtuple_list = NULL;
static int nxttok(char *, unsigned long *);
int
exprobe_parse(register int argc, char **argv)
{
register char **argvp = argv;
int openpar = 0;
register int state = PR_START;
register int tok;
register int inseq = 0;
unsigned long number;
struct Vtuple *Vtp = NULL, *tVtp;
free_Vtuple_list();
/* Skip over the "exprobe=", which has already been parsed by caller */
argvp += 2;
argc -= 2;
for (; argc > 0;) {
tok = nxttok(*argvp, &number);
#ifdef PROBEDEBUG
if (tok == PR_NUMBER)
fprintf(stderr,"%s %s %ld\n",*argvp,tokstr[tok],number);
else
fprintf(stderr,"%s %s\n", *argvp, tokstr[tok]);
#endif
switch (tok) {
case PR_NOTTOK:
goto err_ret;
case PR_OPAR:
openpar++;
if (state == PR_START)
state = PR_OPAR_or_RWSEQ;
else if (state == PR_OPAR || state == PR_OPAR_or_RWSEQ)
state = PR_RWSEQ;
else
goto err_ret;
break;
case PR_RWSEQ:
if (state == PR_RWSEQ || state == PR_OPAR_or_RWSEQ) {
tVtp = (struct Vtuple *)mymalloc(sizeof(*Vtp));
if (Vtp)
Vtp->next = tVtp;
else
Vtuple_list = tVtp;
Vtp = tVtp;
Vtp->next = NULL;
Vtp->rwseq = *argvp;
inseq = 1;
state = PR_COMMA;
} else
goto err_ret;
break;
case PR_COMMA:
if (state == PR_COMMA)
state = PR_NUMBER;
else if (state == PR_COM_or_CPAR)
state = PR_OPAR;
else
goto err_ret;
break;
case PR_NUMBER:
if (state == PR_NUMBER) {
if (++inseq == 5)
state = PR_CPAR;
else
state = PR_COMMA;
if (inseq - 2 == POS_SIZE && number > 4) {
fprintf(stderr,
"exprobe: Illegal probe size: %u\n",
number);
goto err_ret;
}
Vtp->values[inseq - 2] = number;
} else
goto err_ret;
break;
case PR_CPAR:
if (--openpar < 0)
goto err_ret;
if (state == PR_CPAR) {
if (openpar == 0)
return (int)(argvp - argv + 1);
else
state = PR_COM_or_CPAR;
} else if (state == PR_COM_or_CPAR) {
if (openpar == 0)
return (int)(argvp - argv + 1);
else
goto err_ret;
} else
goto err_ret;
break;
}
argvp++;
argc--;
}
err_ret:
free_Vtuple_list();
return 0;
}
static int
nxttok(register char *token, register unsigned long *np)
{
char *endtok = token;
switch (*token) {
case '(':
return PR_OPAR;
case ')':
return PR_CPAR;
case ',':
return PR_COMMA;
case 'r':
while (*token == 'r') {
++token;
if (*token == 'n')
++token;
}
if (*token)
return PR_NOTTOK;
return PR_RWSEQ;
case 'w':
while (*++token == 'w');
if (*token)
return PR_NOTTOK;
return PR_RWSEQ;
default:
*np = strtoul(token, &endtok, 0);
if(endtok == token || *endtok)
return PR_NOTTOK;
return PR_NUMBER;
}
}
int
exprobe(void)
{
register struct Vtuple *Vtp = Vtuple_list;
register int fd;
unsigned long buf;
register char *action;
if (Vtp == NULL)
error(ER1, "exprobe called without argument list");
if ((fd = open("/dev/kmem", O_RDWR)) < 0)
error(ER2, "exprobe: open");
for (; Vtp; Vtp = Vtp->next) {
for (action = Vtp->rwseq; *action; action++) {
if (lseek(fd, (off_t)Vtp->V_addr & LBOOT_LSEEK_MASK, 0) < 0)
goto err_ret;
if (*action == 'w') {
buf = Vtp->V_value & Vtp->V_mask;
if (write(fd, &buf, Vtp->V_size) != Vtp->V_size)
goto err_ret;
} else {
buf = 0;
if (read(fd, &buf, Vtp->V_size) != Vtp->V_size)
goto err_ret;
buf >>= (sizeof(ulong) - Vtp->V_size) * 8;
if (action[1] == 'n') {
if ((buf & Vtp->V_mask) ==
(Vtp->V_value & Vtp->V_mask))
goto err_ret;
++action;
} else {
if ((buf & Vtp->V_mask) !=
(Vtp->V_value & Vtp->V_mask))
goto err_ret;
}
}
}
}
(void)close(fd);
return TRUE;
err_ret:
(void)close(fd);
return FALSE;
}
void
free_Vtuple_list(void)
{
register struct Vtuple *Vtp, *nVtp;
for (Vtp = Vtuple_list; Vtp;) {
nVtp = Vtp->next;
free(Vtp);
Vtp = nVtp;
}
Vtuple_list = NULL;
}