P8000/WEGA/contrib/K5JB/sys5unix.c

521 lines
9.6 KiB
C

/*
FILE: unix.c
Routines: This file contains the following routines:
fileinit() (moved this to main.c so MS-DOS could use it)
sysreset()
eihalt()
kbread()
clksec()
tmpfile() for Coherent - K5JB
restore()
stxrdy()
disable()
memstat()
filedir()
check_time()
getds()
audit()
doshell()
dodir()
rename()
docd()
ether_dump()
mkdir() for those who don't have it
rmdir()
onshellrtn() part of forked shell process
Written by Mikel Matthews, N9DVG
SYS5 stuff added by Jere Sandidge, K4FUM
Further cleanup, maintenance and etc. by Joe Buswell, K5JB
#define FORK_SHELL for a child process that handles foreground
while you are shelled out.
*/
#ifndef _OSK /* none of this applies to _OSK */
#include <stdio.h>
#include <signal.h>
#include <termio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/times.h>
#include <time.h>
#include <fcntl.h> /* K5JB */
#include "global.h"
#include "cmdparse.h"
#include "iface.h"
#include "unix.h"
#include "unixopt.h"
#include "ndir.h"
#include "timer.h"
#define MAXCMD 1024
int asy_attach();
extern struct cmds attab[];
extern struct termio savecon;
extern struct interface *ifaces;
unsigned nasy;
/* action routine for remote reset */
void
sysreset()
{
extern int exitval;
int doexit(); /* in main.c */
exitval = 3;
doexit();
#ifdef NOGOOD /* use exitval and a shell script */
extern char *netexe;
execl(netexe,netexe,0);
execl("net","net",0);
printf("reset failed: exiting\n");
exit();
#endif
}
#ifdef NOTUSED
void
eihalt()
{
tnix_scan();
}
#endif
#ifdef FORKSHELL
extern int mode;
#include "session.h"
int shellpid;
extern int backgrd;
int onquit();
extern int iostop();
#endif
int
kbread()
{
unsigned char c;
#if defined(COH386) && !defined(COH4)
int sleep2();
sleep2(COHWAIT); /* only needed when no async ports are used */
#endif
#ifdef FORKSHELL /* note that if background, kbread won't be called */
if(shellpid) /* might put a micro sleep here to give up cycles */
return -1;
#endif
#ifdef USE_QUIT
if(backgrd)
return -1;
#endif
if (read(fileno(stdin), &c, 1) <= 0)
return -1;
return ((int) c);
}
int
clksec()
{
long tim;
(void) time(&tim);
return ((int) tim);
}
#if defined(COH386) && !defined(COH4)
FILE *
tmpfile()
{
char *buf;
FILE *fp;
#ifdef LATER /* may come back later and do cleanup - K5JB */
static int nr_tmpfiles;
if((buf = (char *)malloc(L_tempnam)) == NULLCHAR)
return 0;
#else
buf = tmpnam(NULLCHAR);
#endif
if((fp = fopen(buf,"w+")) == NULLFILE)
return 0;
return fp;
}
#endif
void
restore()
{
}
int
stxrdy()
{
return 1;
}
int
disable()
{
return 1; /* dummy function -- not used in Unix */
}
int
memstat()
{
return 0;
}
#define NULLDIR (DIR *)0
#define NULLDIRECT (struct direct *)0
/* wildcard filename lookup */
void
filedir(name, times, ret_str)
char *name;
int times;
char *ret_str;
{
static char dname[128], fname[128];
static DIR *dirp = NULLDIR;
struct direct *dp;
struct stat sbuf;
char *cp, temp[128];
/*
* Make sure that the NULL is there in case we don't find anything
*/
ret_str[0] = '\0';
if (times == 0) {
/* default a null name to *.* */
if (name == NULLCHAR || *name == '\0')
name = "*.*";
/* split path into directory and filename */
if ((cp = strrchr(name, '/')) == NULLCHAR) {
strcpy(dname, ".");
strcpy(fname, name);
} else {
strcpy(dname, name);
dname[cp - name] = '\0';
strcpy(fname, cp + 1);
/* root directory */
if (dname[0] == '\0')
strcpy(dname, "/");
/* trailing '/' */
if (fname[0] == '\0')
strcpy(fname, "*.*");
}
/* close directory left over from another call */
if (dirp != NULLDIR)
closedir(dirp);
/* open directory */
if ((dirp = opendir(dname)) == NULLDIR) {
printf("Could not open DIR (%s)\n", dname);
return;
}
} else {
/* for people who don't check return values */
if (dirp == NULLDIR)
return;
}
/* scan directory */
while ((dp = readdir(dirp)) != NULLDIRECT) {
/* test for name match */
if (wildmat(dp->d_name, fname)) {
/* test for regular file */
sprintf(temp, "%s/%s", dname, dp->d_name);
if (stat(temp, &sbuf) < 0)
continue;
if ((sbuf.st_mode & S_IFMT) != S_IFREG)
continue;
strcpy(ret_str, dp->d_name);
break;
}
}
/* close directory if we hit the end */
if (dp == NULLDIRECT) {
closedir(dirp);
dirp = NULLDIR;
}
}
/* checks the time then ticks and updates ISS */
void
check_time()
{
int32 iss();
void tickle();
#if defined(COH386) && !defined(COH4)
long time();
#else
struct tms tb;
#ifndef COH4
long times();
#endif
#endif
static long clkval;
long ntime, offset;
/* With older Coherent, read elapsed real time in seconds, others
* are done in machine clock ticks. Later Coherent has times()
* fixed but it returns an int instead of a long
*/
#if defined(COH386) && !defined(COH4)
time(&ntime);
#else
#ifdef COH4 /* damned thing returns an int */
ntime = (long)times(&tb);
#else
ntime = times(&tb);
#endif
#endif
/* resynchronize if the error is large (10 seconds or more) */
offset = ntime - clkval;
if (offset > (10000/MSPTICK) || offset < 0)
clkval = ntime;
/* Handle possibility of several missed ticks */
while (ntime != clkval) {
++clkval;
icmpclk();
tickle();
(void) iss();
}
}
int
getds()
{
return 0;
}
void
audit()
{
}
#ifdef FORKSHELL
void
onshellrtn()
{
(void)signal(SIGQUIT, onquit); /* restore normal signals */
(void)signal(SIGHUP, iostop);
(void)signal(SIGINT, iostop);
(void)signal(SIGTERM, iostop);
/* in case someone had a session with us while we were gone */
if(mode != CMD_MODE)
mode = CMD_MODE;
}
#endif
int
doshell(argc, argv) /* modified to make shell "stick" K5JB */
char **argv; /* later modified to make shell a child process */
{
#ifndef FORKSHELL
char str[MAXCMD];
int i,retn;
#else
int parentpid;
#endif
char *cp;
struct termio tt_config;
int saverunflg;
char *getenv();
#ifndef FORKSHELL
str[0] = '\0';
for (i = 1; i < argc; i++) {
strcat(str, argv[i]);
strcat(str, " ");
}
ioctl(0, TCGETA, &tt_config);
ioctl(0, TCSETAW, &savecon);
if ((saverunflg = fcntl(0, F_GETFL, 0)) == -1) {
perror("Could not read console flags");
return -1;
}
fcntl(0, F_SETFL, saverunflg & ~O_NDELAY); /* blocking I/O */
if (argc > 1)
retn = system(str);
else if ((cp = getenv("SHELL")) != NULLCHAR && *cp != '\0')
retn = system(cp);
else
retn = system("exec /bin/sh");
fcntl(0, F_SETFL, saverunflg); /* restore non-blocking I/O, if so */
ioctl(0, TCSETAW, &tt_config);
printf("Returning you to net.\n");
return retn;
#else
/* will fork a child process */
signal(SIGQUIT,SIG_IGN); /* ignore these signals, and... */
signal(SIGHUP,SIG_IGN);
signal(SIGINT,SIG_IGN);
signal(SIGTERM,SIG_IGN);
signal(SIGUSR1,onshellrtn); /* on return, this will restore them */
parentpid = getpid(); /* this will work if we don't detach */
printf("Type exit, or do Ctrl-D, to return to NET.\n");
fflush(stdout);
if(!(shellpid = fork())){ /* is child process */
ioctl(0, TCGETA, &tt_config);
ioctl(0, TCSETAW, &savecon);
if ((saverunflg = fcntl(0, F_GETFL, 0)) == -1) {
perror("Could not read console flags");
return -1;
}
fcntl(0, F_SETFL, saverunflg & ~O_NDELAY); /* blocking I/O */
#ifdef LATER_IFNEEDED
while (ifaces != NULLIF) {
if (ifaces->stop != NULLFP)
(*ifaces->stop)(ifaces->dev);
ifaces = ifaces->next;
}
#endif
/* Note that system() can cause problems with forked process */
/* we use it though so we can signal our return with kill() */
if((cp = getenv("SHELL")) != NULLCHAR && *cp != '\0')
system(cp);
else
system("exec /bin/sh");
fcntl(0, F_SETFL, saverunflg); /* restore non-blocking I/O, if so */
ioctl(0, TCSETAW, &tt_config);
kill(parentpid,SIGUSR1); /* first restore signals, then use one */
/* this makes a newline so if we return with Ctrl-D NET> looks better */
printf("\n");
fflush(stdout);
/* apparently need some time before second kill */
sleep(1);
/* this should kill us and restore foreground */
kill(parentpid,SIGQUIT);
sleep(10); /* will probably not awake from this one */
/* but if sleep time was insufficient... */
printf("You MAY have to use Ctrl-\\ to return to NET...\n");
fflush(stdout);
/* quit signal handler will take care of killing child properly */
/* but if it don't... */
exit(0);
}else
return 0;
#endif
}
int
dodir(argc, argv)
int argc;
char **argv;
{
int i, stat;
char str[MAXCMD];
struct termio tt_config;
strcpy(str, "ls -l ");
for (i = 1; i < argc; i++) {
strcat(str, argv[i]);
strcat(str, " ");
}
ioctl(0, TCGETA, &tt_config);
ioctl(0, TCSETAW, &savecon);
stat = system(str);
ioctl(0, TCSETAW, &tt_config);
return stat;
}
int
rename(s1, s2)
char *s1, *s2;
{
char tmp[MAXCMD];
(void) sprintf(tmp, "mv %s %s", s1, s2);
return(system(tmp));
}
/* enabled this command with k28 -- it was incomplete. Tried to do it
in most portable way, though in SysV, it would be appropriate to feed
getcwd a null pointer and free the memory pointed to by getcwd's return
value. This command is used for "pwd" and "cd". - K5JB
*/
int
docd(argc, argv)
int argc;
char **argv;
{
static char tmp[MAXCMD];
char *getcwd();
extern char *homedir;
if(*argv[0] == 'c')
if(chdir(argc > 1 ? argv[1] : homedir) == -1){
printf("Can't change directory\n");
return 1;
}
if (getcwd(tmp, sizeof(tmp) - 2) != NULL)
printf("%s\n", tmp);
return 0;
}
void
ether_dump()
{
}
#ifndef HAVEMKDIR
int
mkdir(s, m)
char *s;
int m;
{
char tmp[MAXCMD];
sprintf(tmp, "mkdir %s", s);
if (system(tmp))
return -1;
if (chmod(s, m) < 0)
return -1;
return 0;
}
#endif
int
rmdir(s)
char *s;
{
char tmp[MAXCMD];
sprintf(tmp, "rmdir %s", s);
if (system(tmp))
return -1;
return 0;
}
#endif /* OSK */