add directory study
This commit is contained in:
33
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/Makefile
Normal file
33
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/Makefile
Normal 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
|
||||
|
||||
|
||||
|
||||
29
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/READ_ME
Normal file
29
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/READ_ME
Normal 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.
|
||||
|
||||
|
||||
|
||||
79
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/from.c
Normal file
79
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/from.c
Normal 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);
|
||||
}
|
||||
}
|
||||
78
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/master.c
Normal file
78
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/master.c
Normal 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);
|
||||
}
|
||||
78
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/prot.c
Normal file
78
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/prot.c
Normal 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);
|
||||
}
|
||||
76
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/rcp
Normal file
76
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/rcp
Normal 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
|
||||
245
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/rsh.c
Normal file
245
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/rsh.c
Normal 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
|
||||
420
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/sherver.c
Normal file
420
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/sherver.c
Normal 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));
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
50
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/to.c
Normal file
50
study/linux-travel/MINIX-1.5/1.5/Source/amoeba/util/to.c
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user