add directory study

This commit is contained in:
gohigh
2024-02-19 00:25:23 -05:00
parent b1306b38b1
commit f3774e2f8c
4001 changed files with 2285787 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
SHELL = /bin/sh
CFLAGS =
CC = cc
all: from to rsh sherver master
from: from.s
$(CC) -o $@ from.s
to: to.s
$(CC) -o $@ to.s
rsh: rsh.s prot.s
$(CC) -o $@ rsh.s prot.s
chmem =500 $@
sherver: sherver.s prot.s
$(CC) -o $@ sherver.s prot.s
chmem =500 $@
master: master.s
$(CC) -o $@ master.s
chmem =500 $@
sherver.s: sherver.h
rsh.s: sherver.h
clean:
rm -f sherver.s from.s to.s master.s rsh.s prot.s
rm -f sherver from to master rsh

View File

@@ -0,0 +1,29 @@
This directory contains the sources for amoeba based utilities. These are
mainly of interest if you have an ethernet connection. Master and sherver
should not be installed if you do not have an ethernet connection since they
will take up precious memory.
Installation:
1. Type make
2. Copy files as follows:
cp rsh /usr/bin
cp rcp /usr/bin
cp to /usr/bin
cp from /usr/bin
3. Edit /etc/rc and add the lines:
echo "Starting sherver(s)"
/usr/bin/master 1 <uid> <gid> /etc/sherver port
where port is the name that your node is to be known by. It should not be
more than 6 characters long. It can be made up of any characters you like.
Note that the flags <uid> and <gid> are the uid and group id that the
sherver will run under.

View File

@@ -0,0 +1,79 @@
#include <stdio.h>
#include <signal.h>
#include "amoeba.h"
#define BUFSIZE 20480
char * cmd;
catchalarm()
{
fprintf(stderr, "%s: timeout\n", cmd);
exit(1);
}
main(argc, argv)
int argc;
char ** argv;
{
unshort getreq();
unshort putrep();
char * malloc();
int catchalarm();
char * buf;
header hdr;
unshort cnt;
unshort bufsize = BUFSIZE;
unsigned tim = 15 * 60; /* #secs before timeout */
cmd = *argv;
if (argc > 1 && strncmp(argv[1], "-t", 2) == 0)
{
tim = atoi(&argv[1][2]);
argc--;
argv++;
}
if (tim)
signal(SIGALRM, catchalarm);
if (argc != 2 && argc != 3) /* if (!(argc & 2))?? */
{
fprintf(stderr, "Usage: %s [-ttime] [bufsize] port\n", cmd);
exit(-1);
}
if (argc == 3)
bufsize = atoi(argv[2]);
if ((buf = malloc(bufsize * sizeof (char))) == NULL)
{
fprintf(stderr, "%s: out of memory\n", cmd);
exit(-1);
}
strncpy(&hdr.h_port, argv[1], PORTSIZE);
for (;;)
{
if (tim)
alarm(tim);
cnt = getreq(&hdr, buf, bufsize);
if (tim)
alarm(0);
if ((short)cnt < 0)
{
fprintf(stderr, "%s: getreq failed\n", cmd);
exit(-3);
}
hdr.h_status = 0;
if (cnt != 0)
if (write(1, buf, cnt) < 0)
{
perror(cmd);
hdr.h_status = -1;
}
putrep(&hdr, NILBUF, 0);
if (hdr.h_status)
exit(-4);
if (cnt == 0)
exit(0);
}
}

View File

@@ -0,0 +1,78 @@
#include <signal.h>
char console[] = "/dev/console";
run(uid, gid, argv)
char **argv;
{
for (;;)
switch (fork()) {
default:
return;
case 0:
if (setgid(gid) < 0) perror("can't set gid");
if (setuid(uid) < 0) perror("can't set uid");
/*
execvp(*argv, argv);
*/
execv(*argv, argv);
perror("master: exec'ing");
prints("can't execute %s\n", *argv);
/*
kill(getppid(), SIGTERM);
*/
/* If the exec failed, don't try it again immediately.
* Give the kernel a chance to do something else.
*/
sleep (5);
_exit(1);
case -1:
sleep(10);
}
}
main(argc, argv)
char **argv;
{
register n, uid, gid;
/* Minix can't do this
setpgrp(getpid(), getpid());
*/
if (argc < 4) {
prints("Usage: master # uid gid command args ...\n");
return(1);
}
n = atoi(argv[1]);
if (n < 1 || n > 20) {
prints("Bad count.\n");
return(1);
}
signal(SIGHUP, SIG_IGN);
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
/* Put the program into the background. */
switch (fork()) {
case 0:
break;
case -1:
perror(argv[0]);
return 1;
default:
return 0;
}
uid = atoi(argv[2]);
gid = atoi(argv[3]);
/* Start n copies of the program. */
do
run(uid, gid, &argv[4]);
while (--n);
/* Replace each one that dies. */
while (wait((int *) 0) > 0)
run(uid, gid, &argv[4]);
return(0);
}

View File

@@ -0,0 +1,78 @@
#include <stdio.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#define isblank(c) ((c) == ' ' || (c) == '\t' || (c) == '\n')
#define MAXTOKEN 16
static char *gettok(fp)
FILE *fp;
{
static char buf[MAXTOKEN + 1];
register char c, *p = buf;
do /* skip blanks */
if ((c = getc(fp)) == EOF)
return(0);
while (isblank(c));
do {
if (c == '#') { /* skip comment */
while ((c = getc(fp)) != EOF)
if (c == '\n') break;
break;
}
*p++ = c;
} while (c != ':' && (c = getc(fp)) != EOF && !isblank(c));
*p++ = 0;
return(buf);
}
static number(p)
char *p;
{
int n;
return sscanf(p, "%d", &n) == 1 ? n : -1;
}
chkprot(chkfil, chkdefault, uid, gid)
char *chkfil;
char *chkdefault;
{
register userchk = 0, n;
register FILE *fp;
register char *p;
register struct passwd *pw;
register struct group *gr;
extern FILE *fopen();
extern struct passwd *getpwuid();
extern struct group *getgrgid();
pw = getpwuid(uid);
endpwent();
gr = getgrgid(gid);
endgrent();
if ((fp = fopen(chkfil, "r")) == NULL && (fp = fopen(chkdefault, "r")) == NULL)
return(-1);
while ((p = gettok(fp)) != 0)
if (strcmp(p, "group:") == 0)
userchk = 0;
else if (strcmp(p, "user:") == 0)
userchk = 1;
else if (userchk) {
if (pw && strcmp(p, pw->pw_name) == 0 ||
uid == number(p)) {
fclose(fp);
return(1);
}
}
else
if (gr && strcmp(p, gr->gr_name) == 0 ||
gid == number(p)) {
fclose(fp);
return(1);
}
return(0);
}

View File

@@ -0,0 +1,76 @@
: Copy a file from any machine to any other machine.
usage="Usage: $0 [machine!]from-file [machine!]to-file"
PATH=/usr/local:/bin:/usr/bin
CDPATH=
case $# in
2) :
;;
*) echo "$usage" 1>&2
exit 1
esac
from=$1 to=$2
case $from in
*!*) IFS="!"
set $from
case $# in
2) from_mach=$1 from_file=$2 IFS=" "
;;
*) echo "$usage" 1>&2
exit 1
esac
;;
*) from_file=$from
esac
case "$from_file" in
"") echo "$usage" 1>&2
exit 1
esac
case $to in
*!*) IFS="!"
set $to
case $# in
2) to_mach=$1 to_file=$2 IFS=" "
;;
*) echo "$usage" 1>&2
exit 1
esac
;;
*) to_file=$to
esac
case "$to_file" in
"") echo "$usage" 1>&2
exit 1
esac
case "$from_mach" in
"$to_mach")
: machines equal
case "$to_mach" in
"") : local
cp "$from_file" "$to_file"
;;
*) : remote
rsh "$to_mach" "cp $from_file $to_file"
;;
esac
;;
*) : machines not equal
case "$to_mach" in
"") : to local
if test -d "$to_file"
then rsh -e "$from_mach" "cat $from_file" >"$to_file/`basename $from_file`"
else rsh -e "$from_mach" "cat $from_file" >"$to_file"
fi
;;
*) : to remote
case "$from_mach" in
"") : from local
rsh -i "$to_mach" "if test -d $to_file; then cat >$to_file/`basename $from_file`; else cat >$to_file; fi" <"$from_file"
;;
*) : from remote
rsh -e "$from_mach" "cat $from_file" | rsh -i "$to_mach" "if test -d $to_file; then cat >$to_file/`basename $from_file`; else cat >$to_file; fi"
;;
esac
;;
esac
;;
esac

View File

@@ -0,0 +1,245 @@
/* rsh [-ei] machine command
*
* -b: run remote process in background
* -e: separate error output
* -i: send input
*/
#include <stdio.h>
#include <signal.h>
#include "amoeba.h"
#include "sherver.h"
char *prog, *mach, buf[BUFFERSIZE];
usage(){
fprintf(stderr, "Usage: %s [-bei] machine command ...\n", prog);
exit(1);
}
panic(s)
char *s;
{
fprintf(stderr, "%s: %s\n", prog, s);
exit(1);
}
char *collect(buf, vec, sep)
char *buf, **vec, sep;
{
register char *p;
while ((p = *vec++) != 0) {
while (*p != 0) {
*buf++ = *p++;
if (buf == &buf[BUFFERSIZE])
panic("environment too large\n");
}
*buf++ = *vec == 0 ? 0 : sep;
}
return(buf);
}
char *setupbuf(argv, flags)
char **argv;
int *flags;
{
register char *p;
extern char **environ, *getenv();
if (*argv == 0) {
if ((p = getenv("SHELL")) == 0)
p = "/bin/sh";
if (strlen(p) > BUFFERSIZE - 10) /* 10 > strlen("exec -i") */
panic("pathname of shell too large");
sprintf(buf, "exec %s -i", p);
p = &buf[strlen(buf) + 1];
*flags |= IFLG;
}
else
p = collect(buf, argv, ' ');
return collect(p, environ, 0);
}
execute(hdr, p, flags)
header *hdr;
char *p;
{
register unshort cnt;
timeout(50);
strncpy(&hdr->h_port, mach, PORTSIZE);
hdr->h_command = EXEC_COMMAND;
hdr->h_size = p - buf;
hdr->h_extra = flags;
cnt = trans(hdr, buf, p - buf, hdr, buf, BUFFERSIZE);
if ((short) cnt < 0) {
fprintf(stderr, "%s: %s not available\n", prog, mach);
return(0);
}
if (hdr->h_status != COMM_DONE) {
if (cnt == 0)
fprintf(stderr, "can't execute command\n");
else
fprintf(stderr, "%.*s\n", cnt, buf);
return(0);
}
return(1);
}
alrm(){
fprintf(stderr, "rsh: getreq timed out\n");
exit(1);
}
commandloop(hdr)
header *hdr;
{
register unshort cnt;
for (;;) {
alarm(12*60*60);
cnt = getreq(hdr, buf, BUFFERSIZE);
alarm(0);
if ((short) cnt < 0) {
fprintf(stderr, "getreq failed\n");
return(-1);
}
switch (hdr->h_command) {
case READ_FD:
if (hdr->h_extra < NFD)
cnt = read(hdr->h_extra, buf, hdr->h_size);
else
fprintf(stderr, "read: bad fd\n");
hdr->h_size = (unshort) cnt;
putrep(hdr, buf, cnt < 0 ? 0 : cnt);
if (cnt == 0)
return(0);
break;
case WRITE_FD:
if (hdr->h_extra < NFD)
if (cnt == 0)
close(hdr->h_extra);
else
write(hdr->h_extra, buf, cnt);
else
fprintf(stderr, "write: bad fd\n");
putrep(hdr, NILBUF, 0);
break;
case EXIT_STATUS:
if (cnt != 0) {
write(2, "Remote message: ", 16);
write(2, buf, cnt);
write(2, "\n", 1);
}
putrep(hdr, NILBUF, 0);
return(hdr->h_extra >> 8);
break;
default:
fprintf(stderr, "unknown command\n");
putrep(hdr, NILBUF, 0);
}
}
}
setupin(hdr)
header *hdr;
{
register pid;
uniqport(&hdr->h_priv.prv_random);
if ((pid = fork()) < 0) {
perror(prog);
exit(-1);
}
if (pid == 0) {
hdr->h_port = hdr->h_priv.prv_random;
_exit(commandloop(hdr)); /* get read commands from sherver */
}
return(pid);
}
main(argc, argv)
char **argv;
{
char *p;
header hdr;
register pid, status;
int flags;
#ifdef sun
put_user_name_in_env();
#endif
prog = *argv++;
if (argc == 1)
usage();
signal(SIGALRM, alrm);
while (*argv != 0 && **argv == '-') {
while (*++*argv)
switch (**argv) {
case 'b': flags |= BFLG; break;
case 'e': flags |= EFLG; break;
case 'i': flags |= IFLG; break;
default: usage();
}
argv++;
}
if ((mach = *argv++) == 0)
usage();
chkperm(mach);
p = setupbuf(argv, &flags); /* get command and environment */
if (flags & IFLG) /* set up input process */
pid = setupin(&hdr);
if (!execute(&hdr, p, flags)) { /* send command to sherver */
if (flags & IFLG)
kill(pid, SIGKILL);
exit(1);
}
if (!(flags & BFLG)) /* get commands from sherver */
status = commandloop(&hdr);
if (flags & IFLG) { /* wait for input process */
close(0); close(1); close(2);
while (wait((int *) 0) != pid)
;
}
exit(status);
}
chkperm(svport)
char *svport;
{
static char chkfil[] = "/etc/XXXXXXXXXXXXXX";
extern char *strchr();
sprintf(strchr(chkfil, 'X'), "rsh:%.14s", svport);
if (chkprot(chkfil, "/etc/rsh:default", geteuid(), getegid()) == 0)
panic("permission denied");
}
char *strchr(s, c)
register char *s;
{
while (*s) {
if (*s == c)
return s;
s++;
}
return 0;
}
#ifdef sun
#include <pwd.h>
put_user_name_in_env()
{
extern struct passwd *getpwuid();
register struct passwd *pw;
static char buf[512];
char host[10];
gethostname(host, sizeof host);
pw = getpwuid(getuid());
sprintf(buf, "UserName=%s@%s", pw ? pw->pw_name : "???", host);
putenv(buf);
}
#endif sun

View File

@@ -0,0 +1,420 @@
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include "amoeba.h"
#include "sherver.h"
/* isn't minix wonderful */
#undef BUFFERSIZE
#define BUFFERSIZE 8192
#define COMPATIBLE /* with the new rsh */
#define MAXWAIT (4*60*60) /* maximum waiting time in seconds */
#define Secs *10
#define LOCATETIMER 30 Secs
#ifdef DEBUG
char *
portstr(p) port *p; {
static char strbuf[80];
sprintf(strbuf,"%x:%x:%x:%x:%x:%x",
p->_portbytes[0]&0xFF,
p->_portbytes[1]&0xFF,
p->_portbytes[2]&0xFF,
p->_portbytes[3]&0xFF,
p->_portbytes[4]&0xFF,
p->_portbytes[5]&0xFF);
return strbuf;
}
#endif
header hdr;
char *prog, buf[BUFFERSIZE], *envvec[MAXENV], *errstr;
int pidlist[NFD];
extern errno;
static char *sig[] = {
"signal 0",
"hangup",
"interrupt",
"quit",
"illegal instruction",
"trace/BPT trap",
"IOT trap",
"EMT trap",
"floating exception",
"kill",
"bus error",
"memory fault",
"bad system call",
"broken pipe",
"alarm call",
"terminate",
"urgent socket",
"stop (signal)",
"stop",
"continue",
"child exited",
"stop (tty input)",
"stop (tty output)",
"tty input interrupt",
"cputime limit exceeded",
"filesize limit exceeded",
"virtual time alarm",
"profiling timer alarm",
};
panic(s, arg)
char *s;
{
register FILE *f;
FILE * fopen();
#ifdef DEBUG
#define f stderr
#else
if (f = fopen("/dev/tty0", "w")) {
#endif DEBUG
fprintf(f, "%s: ", prog);
fprintf(f, s, arg);
fprintf(f, "\n");
#ifdef DEBUG
#undef f
#else
fclose(f);
}
#endif DEBUG
_exit(1);
}
alrm(){ /* set alarm again to avoid races */
signal(SIGALRM, alrm);
alarm(MAXWAIT);
}
killall(){ /* kill all the created processes */
register n;
for (n = 0; n < NFD; n++)
if (pidlist[n] != 0)
kill(pidlist[n], SIGKILL);
}
trap(){ /* got SIGAMOEBA */
killall();
_exit(0);
}
copyloop(pp, rfd, wfd)
port *pp;
{
register unshort cnt;
register n;
do {
alarm(MAXWAIT);
n = read(rfd, buf, BUFFERSIZE);
alarm(0); alarm(0);
if (n < 0) {
strcpy(buf, errno==EINTR ? "waited too long for input"
: "read error");
killall();
return(1);
}
hdr.h_port = *pp;
hdr.h_command = WRITE_FD;
hdr.h_size = n;
hdr.h_extra = wfd;
cnt = trans(&hdr, buf, (unshort) n, &hdr, NILBUF, 0);
if (cnt != 0)
panic("trans failed (%d iso 0)", (short) cnt);
} while (n != 0);
return(0);
}
setupin(hdr)
header *hdr;
{
int fd, p[2];
register unshort cnt;
port svport;
if (pipe(p) < 0)
errstr = "can't pipe";
else if (p[0] != 0)
errstr = "pipe returned wrong fd";
else if ((pidlist[0] = fork()) < 0)
errstr = "can't fork";
else if (pidlist[0] == 0) {
close(p[0]);
signal(SIGPIPE, SIG_IGN);
#ifdef COMPATIBLE
if (!NullPort(&hdr->h_signature))
svport = hdr->h_signature;
else
#endif
svport = hdr->h_priv.prv_random;
for (;;) {
hdr->h_port = svport;
hdr->h_command = READ_FD;
hdr->h_size = BUFFERSIZE;
hdr->h_extra = 0;
#ifdef DEBUG
fprintf(stderr,"Using read port %s\n",portstr(&hdr->h_port));
#endif
cnt = trans(hdr, NILBUF, 0, hdr, buf, BUFFERSIZE);
if ((short) cnt < 0)
panic("read trans failed (%d)", (short) cnt);
if (cnt == 0)
_exit(0);
if (write(p[1], buf, cnt) != cnt) {
timeout(300);
hdr->h_port = svport;
hdr->h_command = EXIT_STATUS;
hdr->h_extra = 0x100;
if ((cnt = trans(hdr, NILBUF, 0, hdr, NILBUF, 0)) != 0)
panic("trans failed (%d iso 0)", (short) cnt);
_exit(1);
}
}
}
else
close(p[1]);
}
setuperr(){
int errpipe[2];
if (pipe(errpipe) < 0) {
errstr = "can't pipe";
return(-1);
}
if ((pidlist[2] = fork()) < 0) {
close(errpipe[0]);
close(errpipe[1]);
errstr = "can't fork";
return(-1);
}
if (pidlist[2] == 0) {
close(errpipe[1]);
timeout(LOCATETIMER);
_exit(copyloop(&hdr.h_port, errpipe[0], 2));
}
close(errpipe[0]);
return(errpipe[1]);
}
splitup(size){
register char *p = buf, *top = &buf[size], **vec = envvec;
while (p != top) {
if (vec == &envvec[MAXENV]) {
errstr = "too much environment";
return(0);
}
*vec++ = p;
while (*p++ != 0)
if (p == top) {
errstr = "bad format";
return(0);
}
}
*vec = 0;
return(1);
}
runit(outpipe, errout)
int outpipe[2];
{
register fd;
register char *homedir;
extern char **environ, *getenv();
close(1); close(2);
if (hdr.h_extra & BFLG) {
if ((fd = open("/dev/null", 1)) != 1)
panic("open returned wrong fd (%d iso 1)", fd);
else if ((fd = dup(1)) != 2)
panic("dup returned wrong fd (%d iso 2)", fd);
}
else {
close(outpipe[0]); /* outpipe[0] >= 1 */
if ((fd = dup(outpipe[1])) != 1)
panic("dup returned wrong fd (%d iso 1)", fd);
if (hdr.h_extra & EFLG) {
if ((fd = dup(errout)) != 2)
panic("dup returned wrong fd (%d iso 2)", fd);
else
close(errout);
}
else if ((fd = dup(1)) != 2)
panic("dup returned wrong fd (%d iso 2)", fd);
}
for (fd = 3; fd < 20; fd++)
close(fd);
#ifdef LOG
{
#include <fcntl.h>
register int logfd;
logfd = open("/usr/tmp/rsh.log", O_WRONLY|O_APPEND|O_CREAT, 0244);
if (logfd >= 0) {
#include <time.h>
register char *s;
register struct tm *tm;
long t;
char buf[1024]; /* had better be large enough */
static char *months[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
time(&t);
tm = localtime(&t);
environ = &envvec[1];
s = getenv("UserName");
if (s == 0)
s = getenv("HOME");
if (s == 0)
s = getenv("LOGNAME");
if (s == 0)
s = getenv("USER");
sprintf(buf, "%02d-%s-%02d %02d:%02d:%02d %s\t%s%s\n",
tm->tm_mday, months[tm->tm_mon], tm->tm_year,
tm->tm_hour, tm->tm_min, tm->tm_sec,
s?s:"???", envvec[0],
hdr.h_extra & IFLG ? " (interactive)" : "");
lseek(logfd, 0L, 2);
write(logfd, buf, strlen(buf));
close(logfd);
}
}
#endif
environ = &envvec[1];
if ((homedir = getenv("HOME")) == 0 || chdir(homedir) < 0)
chdir("/");
execl("/bin/sh", "sh", "-c", envvec[0], (char *) 0);
panic("can't execute shell", 0);
}
execomm(size){
int outpipe[2], errout;
if (!splitup(size))
return(-1);
if (!(hdr.h_extra & BFLG)) {
if ((hdr.h_extra & EFLG) && (errout = setuperr()) < 0)
return(-1);
if (pipe(outpipe) < 0) {
if (hdr.h_extra & EFLG)
close(errout);
errstr = "can't pipe";
return(-1);
}
}
if ((pidlist[1] = fork()) < 0) {
if (!(hdr.h_extra & BFLG)) {
if (hdr.h_extra & EFLG)
close(errout);
close(outpipe[0]);
close(outpipe[1]);
}
errstr = "can't fork";
return(-1);
}
if (pidlist[1] == 0)
runit(outpipe, errout);
if (hdr.h_extra & BFLG)
return(0);
if (hdr.h_extra & EFLG)
close(errout);
close(outpipe[1]);
return(outpipe[0]);
}
awaitchild(hdr, status)
header *hdr;
{
register pid, n;
int wstat;
if (status == 0) {
alarm(MAXWAIT);
while ((pid = wait(&wstat)) > 0) {
if (pid == pidlist[1]) {
pidlist[1] = 0;
hdr->h_extra = status;
}
status = wstat;
}
alarm(0); alarm(0);
if (pidlist[1] != 0) {
strcpy(buf, errno == EINTR ? "waited too long"
: "wait error");
killall();
hdr->h_extra = 0x100;
}
else if (status & 0xFF)
if ((status & 0x7F) < sizeof(sig) / sizeof(sig[0]))
strcpy(buf, sig[status & 0x7F]);
else
sprintf(buf, "signal %d", status & 0x7F);
else
buf[0] = 0;
if (status & 0x80)
strcat(buf, " - core dumped");
}
else
hdr->h_extra = status << 8;
timeout(300);
hdr->h_command = EXIT_STATUS;
if ((n = trans(hdr, buf, strlen(buf), hdr, NILBUF, 0)) != 0)
panic("trans failed (%d iso 0)", (short) n);
}
main(argc, argv)
char **argv;
{
register unshort cnt;
register fd;
unshort getreq(), putrep();
prog = argv[0];
if (argc != 2)
panic("usage: sherver machine", 0);
signal(SIGALRM, alrm);
signal(SIGAMOEBA, trap);
strncpy(&hdr.h_port, argv[1], PORTSIZE);
/*cbo*/printf("before first getreq\n");
cnt = getreq(&hdr, buf, BUFFERSIZE);
/*cbo*/printf("after first getreq\n");
if ((short) cnt < 0)
panic("getreq failed (%d)", (short) cnt);
if (hdr.h_size == cnt) {
close(0);
if (hdr.h_extra & IFLG)
setupin(&hdr);
else if (open("/dev/null", 0) != 0)
errstr = "can't open /dev/null";
if (errstr == 0) {
uniqport(&hdr.h_port);
fd = execomm(cnt);
}
}
else
errstr = hdr.h_size > BUFFERSIZE ? "request too large" :
"bad format";
if (errstr == 0) {
hdr.h_status = COMM_DONE;
putrep(&hdr, NILBUF, 0);
if (!(hdr.h_extra & BFLG)) {
timeout(LOCATETIMER);
awaitchild(&hdr, copyloop(&hdr.h_port, fd, 1));
}
}
else {
hdr.h_status = COMM_ERROR;
putrep(&hdr, errstr, strlen(errstr));
}
}

View File

@@ -0,0 +1,20 @@
#define BUFFERSIZE 20480
#define MAXENV 100
#define NFD 3
/* initial command from rsh to sherver */
#define EXEC_COMMAND 1
/* flags in h_extra for EXEC_COMMAND */
#define BFLG 0x01
#define EFLG 0x02
#define IFLG 0x04
/* commands from sherver to rsh (parameter (fd or status) in h_extra) */
#define READ_FD 1
#define WRITE_FD 2
#define EXIT_STATUS 4
/* replies */
#define COMM_DONE 0
#define COMM_ERROR -1

View File

@@ -0,0 +1,50 @@
#include <stdio.h>
#include "amoeba.h"
#define BUFSIZE 20480
main(argc, argv)
char **argv;
{
header hdr;
char *buf, *malloc();
char *cmd = argv[0];
unshort cnt, bufsize = BUFSIZE;
unshort trans();
if (argc > 1 && strncmp(argv[1], "-t", 2) == 0) {
timeout(atoi(&argv[1][2]), 0);
argc--;
argv++;
}
if (argc != 2 && argc != 3) {
fprintf(stderr, "Usage: %s port\n", cmd);
exit(-1);
}
if (argc == 3)
bufsize = atoi(argv[2]);
if ((buf = malloc(bufsize)) == NULL) {
fprintf(stderr, "%s: out of memory\n", cmd);
exit(-1);
}
strncpy(&hdr.h_port, argv[1], PORTSIZE);
for (;;) {
cnt = read(0, buf, bufsize);
if ((short) cnt < 0) {
perror("read");
exit(-3);
}
if (trans(&hdr, buf, cnt, &hdr, NILBUF, 0) != 0) {
fprintf(stderr, "%s: trans failed\n", cmd);
exit(-4);
}
if (hdr.h_status) {
fprintf(stderr, "%s: write failed in from\n", cmd);
exit(-5);
}
if (cnt == 0)
exit(0);
}
}