DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T s

⟦1b50ac591⟧ TextFile

    Length: 18613 (0x48b5)
    Types: TextFile
    Names: »system.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/unaxcess/system.c« 

TextFile

/*
 *	@(#)system.c	1.2 (TDI) 2/3/87
 *	@(#)Copyright (C) 1984, 85, 86, 87 by Brandon S. Allbery.
 *	@(#)This file is part of UNaXcess version 1.0.2.
 *
 *	Permission is hereby granted to copy and distribute this program
 *	freely.  Permission is NOT given to modify this program or distribute
 *	it at cost, except for charging a reasonable media/copying fee.
 */

#ifndef lint
static char _FileID_[] = "@(#)system.c	1.2 (TDI) 2/3/87";
static char _UAID_[]   = "@(#)UNaXcess version 1.0.2";
#endif lint

#include "ua.h"

struct sys parms = {
#ifdef NOAUTOPATH
	NOAUTOPATH,
#else
	"/usr/unaxcess",
#endif NOAUTOPATH
	1,
	0,
	"/bin/sh",
	1,
	"unaxcess",
	30,
	"sysop",
	1,
	0,
	"",
	"",
	3,
	"trap '' 2; stty -echo; echo 'Begin sending your file.  End with a CONTROL-D.'; cat - > %s; stty echo",
	"trap '' 2; cat %s",
	"umodem -rbld",
	"umodem -sbld",
	"kermit -iwr ;:",
	"kermit -iws",
	A_GUEST,
};

#define NUM		0
#define STR		1
#define BOOL		2

struct rparm {
	char *parmname;
	char parmtype;
	char *parmval;
} sysparms[] = {
	"bbs-directory",STR,	parms.ua_home,
	"readonly",	BOOL,	&parms.ua_roc,
	"restricted",	BOOL,	&parms.ua_xrc,
	"shell",	STR,	parms.ua_shell,
	"read-env",	BOOL,	&parms.ua_env,
	"bbs-user",	STR,	parms.ua_bbs,
	"time-limit",	NUM,	&parms.ua_tlimit,
	"sysop",	STR,	parms.ua_sysop,
 	"private-msgs",	BOOL,	&parms.ua_pm,
	"logging",	BOOL,	&parms.ua_log,
	"banner",	STR,	parms.ua_bnr,
	"login-msg",	STR,	parms.ua_login,
	"login-tries",	NUM,	&parms.ua_nla,
	"ascii-upload",	STR,	parms.ua_auc,
	"ascii-download",STR,	parms.ua_adc,
	"xmodem-upload",STR,	parms.ua_xuc,
	"xmodem-download",STR,	parms.ua_xdc,
	"kermit-upload",STR,	parms.ua_kuc,
	"kermit-download",STR,	parms.ua_kdc,
	"validation-level",NUM,	&parms.ua_vaxs,
	0,		0,	0,
};

static FILE *lfp;
static int __tlog = 0;
short critical = 0;
short quitc = 0;
short intr = 0;
short alrm = 0;
short warned = 0;

logon() {
	struct stat sb;
	char *cp;

	if (!parms.ua_log || stat(LOG, &sb) < 0) {		/* no logfile => no logging */
		lfp = NULL;
		return;
	}
	if ((lfp = fopen(LOG, "a")) == NULL) {
		io_off();
		perror(LOG);
		fprintf(stderr, "panic: log\n");
		exit(2);
	}
}

log(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
char *fmt, *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9; {
	char buf[1024];
	static char lockfile[] = "logfile.lock";

	if (lfp == NULL)			/* logging not enabled */
		return;
	CRIT();
	sprintf(buf, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
	mklock(lockfile);
	fprintf(lfp, "%s (%05d)  %s\n", date(), getpid(), visible(buf));
	fflush(lfp);
	rmlock(lockfile);
	NOCRIT();
}

logsig(sig)
int sig; {
	static int dbl = 0;	/* OOPS!  9 lines added 2/3/87 ++bsa */
	
	if (dbl++) {
		fprintf(stderr, "\r\n\r\nDOUBLE PANIC: SIG %d\r\n\r\n", sig);
		setuid(getuid());
		chdir("/tmp");
		signal(SIGIOT, SIG_DFL);
		kill(getpid(), SIGIOT);
	}
	dolog();
	log("Received signal %d.", sig);
	fprintf(stderr, "\r\n\r\nUNaXcess internal error: %d.\r\n\r\n", sig);
	unlink(RIndex(ttyname(fileno(stdin)), '/') + 1);
	io_off();
	signal(SIGIOT, SIG_DFL);
	setuid(getuid());			/* OOPS!  2 lines added */
	chdir(getpwuid(getuid())->pw_dir);	/*   2/3/87 ++bsa */
	kill(getpid(), SIGIOT);
}

panic(s)
char *s; {
	static int dbl = 0;	/* OOPS!  9 lines added 2/3/87 ++bsa */

	if (dbl++) {
		fprintf(stderr, "\r\n\r\nDOUBLE PANIC: %s\r\n\r\n", s);
		setuid(getuid());
		chdir("/tmp");
		signal(SIGIOT, SIG_DFL);
		kill(getpid(), SIGIOT);
	}
	dolog();
	log("panic: %s", s);
	fprintf(stderr, "\r\n\r\nUNaXcess internal error: %s\r\n\r\n", s);
	io_off();
	unlink(RIndex(ttyname(2), '/') + 1);
	setuid(getuid());
	chdir(getpwuid(getuid())->pw_dir);
	signal(SIGIOT, SIG_DFL);
	kill(getpid(), SIGIOT);
}

quit() {
	char line[256];

	if (critical) {
		quitc++;
		return;
	}
	writes("\n\nFast logout\n");
	signal(SIGQUIT, quit);
	log("Signalled QUIT.");
	writef("\nDo you really want to leave UNaXcess? N\b");
	line[0] = readc();
	if (line[0] == 'Y') {
		writef("OK");
		if (user.u_name[0] != '\0')
			writef(", %s", upstr(user.u_name));
		writef(".  See you later!\n\n\n");
		cleanup();
	}
}

intrp() {
	if (critical) {
		intr++;
		return;
	}
	writes("\n\nAborted.");
	log("Command aborted.");
	signal(SIGINT, intrp);
	longjmp(cmdloop, 1);
}

char *visible(s)
char *s; {
	static char vs[256];
	char *sp, *vp;

	vp = vs;
	for (sp = s; *sp != '\0'; sp++)
	if (!iscntrl(*sp))
		*vp++ = *sp;
	else {
		*vp++ = '^';
		*vp++ = uncntrl(*sp);
	}
	*vp = '\0';
	return vs;
}

shell() {
	short sig;

	if (user.u_access == A_GUEST || user.u_access == A_USER || parms.ua_shell[0] == '\0') {
		writes("You don't have shell access privileges.");
		log("Security violation:  Unauthorized SHELL");
		return 1;
	}
	switch (fork()) {
	case -1:
		log("Error %d forking shell", errno);
		writes("Sorry, the system's full.  Try again later.");
		return 1;
	case 0:
		for (sig = SIGINT; sig <= SIGTERM; sig++)
			signal(sig, SIG_DFL);
		setuid(getuid());
		chdir(getpwuid(getuid())->pw_dir);
		run(parms.ua_shell, 0);
		log("Error %d exec'ing %s", errno, parms.ua_shell);
		writes("Couldn't run the shell.");
		exit(1);
	default:
		CRIT();
		io_off();
		for (sig = SIGINT; sig <= SIGTERM; sig++)
			signal(sig, SIG_IGN);
		signal(SIGALRM, thatsall);	/* trapped by the CRIT() */
		wait(NULL);
		signal(SIGINT, intrp);
		signal(SIGQUIT, quit);
		for (sig = SIGIOT; sig < SIGTERM; sig++)
			signal(sig, logsig);
		signal(SIGALRM, thatsall);
		io_on(0);
		NOCRIT();
	}
	return 1;
}

thatsall() {
	if (critical) {
		alrm++;
		return;
	}
	if (warned) {
		log("Timeout.");
		writes("\nI'm sorry, but you're out of time.\n\n");
		cleanup();
	}
	else {
		log("5-minute warning.");
		writes("\nYou have only five minutes left in this session.\n\n");
		warned = 1;
		alarm(5 * 60);
	}
}

mklock(lockfile)
char *lockfile; {
	char lockpath[50];
	int lock_fd;
	struct stat statbuf;
	long now;
	
	strcpy(lockpath, "lock/");
	strcat(lockpath, lockfile);
	while (stat(lockpath, &statbuf) == 0) {
		time(&now);
		if (now - statbuf.st_mtime > 90) {	/* OOPS!  2/3/87 ++bsa */
			unlink(lockpath);
			break;
		}
		sleep(5);	/* OOPS!  1 line added 2/3/87 ++bsa */
	}
	if ((lock_fd = creat(lockpath, 0600)) < 0) {
		fprintf(stderr, "Errno = %d creating lockfile %s\n", errno, lockpath);
		/* OOPS!  1 line deleted 2/3/87 ++bsa */
		panic(lockpath);
	}
	close(lock_fd);
	sync();	/* insure disk files are updated! */
}

rmlock(lockfile)
char *lockfile; {
	char lockpath[50];
	struct stat statbuf;
	
	sync();
	strcpy(lockpath, "lock/");
	strcat(lockpath, lockfile);
	if (stat(lockpath, &statbuf) < 0) {
		log("Lockfile %s deleted???", lockpath);
		writef("\n\nSomeone futzed with the lockfile.  Please tell %s IMMEDIATELY!!!\nSorry, but this means I have to log you out now.\n\n", parms.ua_sysop);
		panic("LOCKFILE DELETED");
	}
	if (unlink(lockpath) < 0) {
		log("Errno = %d, can't unlink lockfile %s", errno, lockpath);
		writes("\nI've got a lockfile problem.  You won't be able to do some\nthings until it's fixed.  Sorry...\n");
	}
}

CRIT() {
	alrm = 0;
	quitc = 0;
	intr = 0;
	if (critical)
		return;	/* clears pending signals */
	critical = 1;
}

NOCRIT() {
	if (!critical)
		return;
	critical = 0;
	if (alrm)
		thatsall(14);
	if (quitc)
		quit(3);
	if (intr)
		intrp(2);
	alrm = 0;
	quitc = 0;
	intr = 0;
}

run(cmd, arg)
char *cmd, *arg; {
	char cmdbuf[5120];
	
	sprintf(cmdbuf, "%s %s", cmd, (arg? arg: ""));
	execl("/bin/sh", "sh", "-c", cmdbuf, 0);
	return -1;
}

copylink(src, dest)
char *src, *dest; {
	int srcp, destp, cnt;
	char buf[1024];
	
	if (link(src, dest) == 0) {
		unlink(src);
		return 0;
	}
	if ((srcp = open(src, 0)) < 0) {
		perror(src);
		return -1;
	}
	unlink(dest);
	if ((destp = creat(dest, 0600)) < 0) {
		perror(dest);
		return -1;
	}
	while ((cnt = read(srcp, buf, sizeof buf)) > 0)
		write(destp, buf, cnt);
	close(destp);
	close(srcp);
	return 0;
}

s_cmp(s1, s2)
char *s1, *s2; {
	for (; *s1 != '\0' && ToLower(*s1) == ToLower(*s2); s1++, s2++)
		;
	return (!(*s1 == '\0' && *s2 == '\0'));
}

char *upstr(s)
char *s; {
	static char sbuf[512];
	register char *cp, *dp;
	
	for (cp = s, dp = sbuf; *cp != '\0'; cp++, dp++)
		*dp = ToUpper(*cp);
	*dp = '\0';
	return sbuf;
}

ismember(word, list)
char *word, *list; {
	char *cp;
	char oldch;
	
	while (*list != '\0') {
		while (*list == ' ' || *list == '\t')
			list++;
		for (cp = list; *cp != '\0' && *cp != ',' && *cp != ' ' && *cp != '\t'; cp++)
			;
		oldch = '\0';
		if (*cp != '\0') {
			oldch = *cp;
			*cp++ = '\0';
		}
		if (strcmp(word, list) == 0) {
			*(cp - 1) = oldch;
			return 1;
		}
		*(cp - 1) = oldch;
		list = cp;
	}
	return 0;
}

dolog() {
	if (lfp != (FILE *) 0 || __tlog)
		return;
	logon();
	__tlog = 1;
}

nolog() {
	if (!__tlog || lfp == (FILE *) 0)
		return;
	fclose(lfp);
	__tlog = 0;
}

alter() {
	char line[256], uname[256];
	char *p, *q, *okcmds;
	struct user ubuf;
	short crypted, not_FW;
	char cmd;

	if (user.u_access == A_MKUSER) {
		log("An A_MKUSER got into alter()???");
		panic("newalter");
	}
	if (user.u_access != A_WITNESS) {
		not_FW = 1;
		log("Alter by non-Witness; restricting control modes.");
		strcpy(line, user.u_name);
	}
	else {
		line[0] = '\0';
		not_FW = 0;
		writef("Examine which user: ");
		reads(line);
		log("User: %s", line);
		if (line[0] == '\0')
			return 1;
		for (p = line; *p != '\0'; p++)
			*p = ToLower(*p);
		line[32] = '\0';
	}
	if (!getuser(line, &ubuf))
		if (not_FW) {
			log("Can't locate current user in the userfile.");
			panic("user");
		}
		else {
			writef("No such user.  Create him ? N\b");
			strcpy(ubuf.u_name, line);
			line[0] = readc();
			log("New user? %c", line[0]);
			if (line[0] != 'Y')
				return 1;
			ubuf.u_pass[0] = '\0';
			ubuf.u_access = A_USER;
			ubuf.u_llen = 80;
			ubuf.u_nbull = 0;
			strcpy(ubuf.u_lconf, "general");
			ubuf.u_lines = 24;
			crypted = 0;
		}
	else if (strlen(ubuf.u_pass) == 0)
		crypted = 0;
	else
		crypted = 1;
	strcpy(uname, ubuf.u_name);
	for (;;) {
		writec('\n');
		writef("Name: %s\n", ubuf.u_name);
		writef("Password: %s%s\n", ubuf.u_pass, (crypted? " (encrypted)": ""));
		writef("Access level: %s\n", ua_acl(ubuf.u_access));
		if (ubuf.u_access == A_MKUSER) {
			writef("Default access level: %s\n", ua_acl(ubuf.u_llen));
			okcmds = "NPADKQF";
		}
		else {
			writef("UNIX(R) login name: %s\n", ubuf.u_login);
			writef("Login conference: %s\n", ubuf.u_lconf);
			writef("Line size: %d\n", ubuf.u_llen);
			writef("Screen lines: %d\n", ubuf.u_lines);
			if (ubuf.u_access == A_WITNESS && s_cmp(user.u_name, parms.ua_sysop) != 0 && s_cmp(user.u_name, uname) != 0)
				okcmds = "Q";
			else if (user.u_access < A_WITNESS)
				okcmds = "PUCSLQF";
			else if (s_cmp(user.u_name, uname) == 0)
				okcmds = "NPUCSLQF";
			else
				okcmds = "NPAUCLSKQF";
		}
		writef("\nAlter command (");
		for (p = okcmds; *p != '\0'; p++)
			switch (*p) {
			case 'N':
				writef("Name, ");
				break;
			case 'P':
				writef("Password, ");
				break;
			case 'A':
				writef("Access, ");
				break;
			case 'U':
				writef("UNIX(R) login, ");
				break;
			case 'C':
				writef("Conference, ");
				break;
			case 'L':
				writef("Lines, ");
				break;
			case 'S':
				writef("Size, ");
				break;
			case 'D':
				writef("Default access, ");
				break;
			case 'K':
				writef("Kill, ");
				break;
			case 'Q':
				writef("Quit, ");
				break;
			case 'F':
				writef("Finished, ");
				break;
			default:
				log("Invalid internal alter() command: '%c'", *p);
				panic("altercmd");
			}
		writef("or ? for help): ");
		cmd = readc();
		log("Change: %c", cmd);
		if (cmd != '?' && Index(okcmds, cmd) == (char *) 0)
			cmd = ' ';
		switch (cmd) {
		case 'K':
			writef("Kill user -- are you sure? N\b");
			cmd = readc();
			log("Kill user? %c", cmd);
			if (cmd != 'Y')
				break;
			putuser(uname, (struct user *) 0);
			writef("User %s killed.\n", upstr(uname));
			return 1;
		case 'N':
			writef("Enter new name: ");
			reads(line);
			log("Name: %s", line);
			if (line[0] == '\0')
				break;
			for (p = line; *p != '\0'; p++)
				if (*p == ':') {
					log("Illegal colon in name.");
					writes("Can't put a colon in a user name.");
					break;
				}
			for (p = line, q = ubuf.u_name; *p != '\0'; p++, q++)
				*q = ToLower(*p);
			*q = '\0';
			break;
		case 'P':
			strcpy(line, getpass("Enter new password: "));
			if (line[0] == '\0')
				break;
			strcpy(ubuf.u_pass, line);
			crypted = 0;		/* it's not encrypted now */
			break;
		case 'A':
			writef("Access level: Deny access, Guest, Messages, Files, System, Witness, Newuser? ");
			cmd = readc();
			log("Access: %c", cmd);
			if (cmd == 'A' && s_cmp(user.u_name, parms.ua_sysop) != 0) {
				writes("Sorry, only the sysop can administer Witness privileges.");
				log("Security violation: WITNESS administering WITNESS");
				break;
			}
			switch (cmd) {
			case 'G':
				ubuf.u_access = A_GUEST;
				break;
			case 'D':
				ubuf.u_access = A_NONE;
				break;
			case ' ':
				break;
			case 'M':
				ubuf.u_access = A_USER;
				break;
			case 'S':
				ubuf.u_access = A_SYSTEM;
				break;
			case 'W':
				ubuf.u_access = A_WITNESS;
				break;
			case 'N':
				ubuf.u_access = A_MKUSER;
				break;
			case 'F':
				ubuf.u_access = A_FILES;
				break;
			default:
				writes("What?  Valid commands are D, G, M, F, S, W, and N.  Access unchanged.");
			}
			break;
		case 'C':
			writef("Enter the default login conference: ");
			reads(line);
			log("Login conference: %s", line);
			if (line[0] =='\0')
				break;
			if (!isconf(line))
				writes("That conference doesn't exist.");
			else if (uisunsub(ubuf.u_name, line))
				writef("%s isn't subscribed to %s.\n", upstr(ubuf.u_name), line);
			else if (!isrcmem(ubuf.u_name, line))
				writef("%s isn't a member of that conference.\n", upstr(ubuf.u_name));
			else
				strcpy(ubuf.u_lconf, line);
			break;
		case 'S':
			writef("Enter new line size, 32-132: ");
			reads(line);
			log("Line length: %s", line);
			if (line[0] == '\0')
				break;
			ubuf.u_llen = atoi(line);
			if (ubuf.u_llen < 32 || ubuf.u_llen > 132) {
				ubuf.u_llen = 80;
				writes("Garbage line size; using 80.");
			}
			break;
		case 'U':
			writef("UNIX(R) login name? ");
			reads(line);
			log("Login name: %s", line);
			if (strlen(line) > 8) {
				writes("That name is too long.");
				break;
			}
			strcpy(ubuf.u_login, line);
			break;
		case 'D':
			writef("Default Access: Deny access, Guest, Messages, Files, System? ");
			cmd = readc();
			log("Dft Access: %c", cmd);
			switch (cmd) {
			case 'G':
				ubuf.u_llen = A_GUEST;
				break;
			case 'D':
				ubuf.u_llen = A_NONE;
				break;
			case ' ':
				break;
			case 'M':
				ubuf.u_llen = A_USER;
				break;
			case 'S':
				ubuf.u_access = A_SYSTEM;
				break;
			case 'F':
				ubuf.u_access = A_FILES;
				break;
			default:
				writes("What?  Valid commands are D, G, M, F, or S.  Default access unchanged.");
			}
			break;
		case 'Q':
			if (okcmds[1] != '\0') {
				writef("Abort user examine, are you sure? N\b");
				cmd = readc();
				log("Abort? %c", cmd);
				if (cmd != 'Y')
					break;
			}
			return 1;
		case 'F':
			if (!crypted) {
				writes("Encrypting password, please wait...");
				strcpy(ubuf.u_pass, crypt(ubuf.u_pass, ubuf.u_pass) + 2);
			}
			putuser(uname, &ubuf);
			if (s_cmp(uname, user.u_name) == 0)
				user = ubuf;
			return 1;
		case 'L':
			writef("Enter new lines/screen, 0-66: ");
			reads(line);
			log("Lines/screen: %s", line);
			if (line[0] == '\0')
				break;
			ubuf.u_lines = atoi(line);
			if (ubuf.u_lines < 0 || ubuf.u_lines > 66) {
				ubuf.u_lines = 24;
				writes("Garbage lines/screen; using 24.");
			}
			break;
		case '?':
			writef("\nThe commands are self-documenting.  If you don't see a command, it's because you can't perform that command on the current user.\n");
			break;
		default:
			writef("What?  Please enter one of ");
			for (p = okcmds; *p != '\0'; p++) {
				writec(*p);
				writec(',');
				writec(' ');
			}
			writes("or ? for help.");
		}
	}
}

getparms() {
 	char home[512], line[512], var[20], sval[50];
 	FILE *cfp;
 	short cnt, pos, scnt, canon;
 	
#ifdef NOAUTOPATH
	strcpy(home, NOAUTOPATH);
#else
 	strcpy(home, getpwuid(geteuid())->pw_dir);
#endif NOAUTOPATH
	strcpy(parms.ua_home, home);
 	strcpy(line, home);
 	strcat(line, "/");
 	strcat(line, CONFIG);
 	if ((cfp = fopen(line, "r")) == NULL) {
 		fprintf(stderr, "panic: param get, %s\n", line);
 		exit(1);
 	}
 	while (fgets(line, 512, cfp) != NULL) {
 		line[strlen(line) - 1] = '\0';
 		if (Index(line, '#') != NULL)
 			*(Index(line, '#')) = '\0';
 		scnt = 0;
 		pos = 0;
 		while (line[pos] != '\0' && line[pos] != ' ' && line[pos] != '\t')
 			var[scnt++] = line[pos++];
 		var[scnt] = '\0';
 		if (var[0] == '\0')
 			continue;
 		for (cnt = 0; sysparms[cnt].parmname != NULL; cnt++)
 			if (strcmp(sysparms[cnt].parmname, var) == 0)
 				break;
 		if (sysparms[cnt].parmname == NULL) {
 			fprintf(stderr, "Please inform the sysop that there is an invalid parameter\n%s in the setup file.\n", var);
 			continue;
 		}
		while (line[pos] == ' ' || line[pos] == '\t')
			pos++;
 		switch (sysparms[cnt].parmtype) {
 			case NUM:
 				*((char *) sysparms[cnt].parmval) = atoi(&line[pos]) & 0xff;
 				break;
 			case BOOL:
 				if (line[pos] == '\0' || ToLower(line[pos]) == 'y')
 					*((char *) sysparms[cnt].parmval) = 1;
 				else
 					*((char *) sysparms[cnt].parmval) = 0;
 				break;
 			case STR:
 				canon = 0;
 				if (line[pos] == '"') {
 					canon = 1;
 					pos++;
 				}
 				for (scnt = 0; (canon? line[pos] != '"': line[pos] != '\0' && line[pos] != ' ' && line[pos] != '\t'); pos++, scnt++) {	
 					if (canon && line[pos] == '\\') {
 						switch (line[++pos]) {	
 							case 'n':
 								sval[scnt] = '\n';
 								break;
 							case 't':
 								sval[scnt] = '\t';
 								break;
 							case 'r':
 								sval[scnt] = '\r';
 								break;
 							case 'b':
 								sval[scnt] = '\b';
 								break;
 							case 'f':
 								sval[scnt] = '\f';
 								break;
 							case 'e':
 							case 'E':
 								sval[scnt] = '\033';
 								break;
 							case 'a':
 								sval[scnt] = '\7';	/* proposed extension of C string metasyntax */
 								break;
 							case '0':
 							case '1':
 							case '2':
 							case '3':
 							case '4':
 							case '5':
 							case '6':
 							case '7':
 								sval[scnt] = 0;
 								while (Index("01234567", line[pos]) != NULL)
 									sval[scnt] = sval[scnt] * 8 + (line[pos++] - '0');
								pos--;
								break;
							default:
								sval[scnt] = line[pos];
 						}
 					}
 					else
 						sval[scnt] = line[pos];
 				}
 				sval[scnt] = '\0';
 				strcpy(sysparms[cnt].parmval, sval);
 		}
 	}
}