home *** CD-ROM | disk | FTP | other *** search
- #!/bin/sh
- # shar: SHell ARchive
- # Run the following text through 'sh' to create:
- # CLEAN
- # MAKE
- # README
- # TODO
- # client/getfiles.c
- # client/putfiles.c
- # client/dsoc.c
- # client/draw.c
- # client/dprint.c
- # client/Makefile
- # dnet/channel.h
- # dnet/control.c
- # dnet/TODO3
- # dnet/subs.c
- # This is archive 1 of a 2-part kit.
- # This archive created: Thu Apr 27 15:41:47 1989
- echo "extracting CLEAN"
- sed 's/^X//' << \SHAR_EOF > CLEAN
- X#!/bin/sh
- Xcd dnet
- Xmake clean
- Xcd ../client
- Xmake clean
- Xcd ../server
- Xmake clean
- Xcd ../test
- Xmake clean
- Xcd ../lib
- Xrm -f *.o make.out
- Xcd ..
- Xrm -f *.o make.out MAKE.out
- X
- SHAR_EOF
- echo "extracting MAKE"
- sed 's/^X//' << \SHAR_EOF > MAKE
- X#!/bin/sh
- Xcd lib
- Xmake
- Xcd ../dnet
- Xmake
- Xcd ../client
- Xmake
- Xcd ../server
- Xmake
- X
- SHAR_EOF
- echo "extracting README"
- sed 's/^X//' << \SHAR_EOF > README
- X
- X
- X DNET V2.00 UNIX SIDE
- X
- X BSD4.2/4.3 compatible
- X note: 8 bit connection required to run dnet,
- X which isn't always true if talking to the unix
- X box through a port selector or terminal
- X concentrator.
- X
- X
- X
- X DNET (c)Copyright 1987-1989 Matthew Dillon, All Rights Reserved
- X
- X Matthew Dillon
- X 891 Regal Rd
- X Berkeley, Ca. 94708
- X USA
- X
- X ...!ihnp4!ucbvax!dillon USENET
- X dillon@ucbvax.Berkeley.edu ARPANET
- X ucbvax.berkeley.edu pub/amiga ARPANET-FTP
- X
- X UNIX SETUP
- X
- X The directory structure must remain intact. simply say MAKE
- X in the main directory and it ought to compile. There might be
- X minor problems depending on how compatible your UNIX is with
- X BSD4.3 UNIX .. I have successfully compiled DNet on the following
- X machines:
- X
- X Dec Vax 7xx
- X Sun 3
- X Sequent
- X
- X (1) Create a directory. For example, ~/.DNET WARNING! This
- X directory must be on a local partition. DNET uses a unix
- X domain socket and these do not work over network fileservers.
- X
- X (2) Modify your .cshrc to add the following line:
- X
- X setenv DNETDIR ~/.DNET/
- X
- X (or wherever you put it. NOTE! You MUST HAVE THE TRAILING
- X SLASH!)
- X
- X (3) All binaries are usually kept in dnet.unix/bin, add this
- X directory to your path (in your .cshrc) so DNet can find
- X the clients.
- X
- X (4) Place the file 'dnet.servers' in $DNETDIR. Modify the file
- X according to your home directory and where you have put the
- X servers (usually in dnet.unix/bin). USE ABSOLUTE PATHS,
- X DNET.SERVERS DOES NOT UNDERSTAND ~.
- X
- X NOTE: You may want to chmod $DNETDIR 700 to disallow any
- X unauthorized access to the network.
- X
- X
- X DIALING UP FROM AN AMIGA
- X
- X Follow the installation instructions for the Amiga side. When
- X you dial up the UNIX system you will eventually get a prompt.
- X NOTE! DNET normally uses 7 bit - even parity for dialing up,
- X then switches to 8 bit no parity for the protocol. Sometimes
- X the modem or port selector will switch into 7 bit + parity mode
- X and NOT SWITCH OUT. For this reason, you might want to use the
- X -8 option for the Amiga side of DNET (read the docs in the Amiga
- X section).
- X
- X From the DNET window's CSH prompt, start the protocol with:
- X
- X % dnet
- X
- X That was easy. The DNet window should go away and an FTERM window
- X should open. This does not mean success! If the FTERM window
- X closes again with the message "unable to connect", it was unable
- X to connect. There are several possibilities:
- X
- X (a) You do not have an 8 bit connection from your amiga to the
- X UNIX host (DNet must be able to send and receive all 256
- X character codes).
- X
- X (b) You did not setup the DNETDIR enviroment variable properly
- X
- X (c) You did not copy dnet.servers into $DNETIDR
- X
- X (d) The absolute file path in dnet.servers for server #8192 (that
- X FTerm tires to connect to) is not correct.
- X
- X KILLING DNET
- X
- X In most cases simply turning off the modem will suffice. You can
- X kill dnet more cleanly with the following sequence:
- X
- X (1) From an Amiga CLI, run the QuitDnet command. This will kill
- X the packet protocol and cause the remote DNet to exit.
- X
- X (2) From an Amiga CLI, BREAK the protocol process. You should get
- X the original (small) DNet window and the original login shell.
- X If you get the DNet window but not the shell (you can't type),
- X the protocol may still be running on the other end, in which
- X case you forgot to QuitDnet or it didn't work for some
- X unknown reason. Restart the protocol w/ the appropriate
- X menu option and try again.
- X
- X (3) logout normally and close the DNet window. Turn off your
- X modem.
- X
- X HANGING SERVER PROCESSES
- X
- X The UNIX side servers are normally left running when the protocol
- X dies. These are very very very small and take 0 CPU (they are
- X simply waiting for connections). These servers will still be
- X there when you log in again and DNet will use them.
- X
- X You can kill UNIX side servers at any time.
- X
- X Many of the same clients and servers exist on the UNIX end as
- X on the Amiga end. The UNIX end is missing several. The UNIX
- X end implements two commands called dsoc and draw which can be
- X used to connect to (in cooked or raw tty mode) specific servers
- X (by port #) on the Amiga side. For example, to connect to the
- X printer server on the amiga side:
- X
- X % dsoc 8198
- X This is a test
- X ^D
- X %
- X
- X Dumps to PRT: on the Amiga "This is a test" Gee Wiz!
- X
- X SECURITY W/ UNIX
- X
- X DNet will be as secure as your account, assuming you chmod DNETDIR
- X 700 (so nobody else has access to the unix domain sockets). From
- X Home, I usually RUN DNET -X , login, start the protocol, and leave
- X it running all day.
- X
- X The -X option turns of security (sets all security levels to 9),
- X thus allowing me to drive to the university and at any time from
- X my UNIX account do a getfiles or putfiles from and to my Amiga.
- X
- X Refer to the amiga side documentation for more information.
- X
- X
- X
- SHAR_EOF
- echo "extracting TODO"
- sed 's/^X//' << \SHAR_EOF > TODO
- X
- X -current connect is done synchronously. It should be done asynchronously
- X incase the server is hung, but it really doesn't matter since the
- X servers are so incredibly easy to write and are always accepting new
- X connections (I hope).
- X
- X -packet size reduction should also depend on the baud rate
- X
- SHAR_EOF
- if `test ! -d client`
- then
- mkdir client
- echo "mkdir client"
- fi
- echo "extracting client/getfiles.c"
- sed 's/^X//' << \SHAR_EOF > client/getfiles.c
- X
- X/*
- X * GETFILES.C V1.30
- X *
- X * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
- X *
- X * GETFILES [-dlocaldir] [-c] file/dir file/dir file/dir
- X *
- X * -dlocaldir local directory to place files
- X *
- X * -c Continue from where you left off before. Files that already
- X * exist on the local machine will not be re-transfered. This
- X * will also re-start in the middle of a file that was
- X * partially transfered previously.
- X *
- X * This command assumes the file(s) on both machines have not
- X * been modified since the first attempt. No other checking
- X * is done at the moment.
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/file.h>
- X#include <sys/stat.h>
- X#include "../server/servers.h"
- X
- Xtypedef unsigned char ubyte;
- X
- Xtypedef struct {
- X char Cmd;
- X char Str[64];
- X long Val;
- X} HDR;
- X
- Xchar *NSpaces();
- X
- Xchar Buf[1024];
- X
- Xshort ContMode;
- Xchar *NetId;
- Xlong Chan = -1;
- X
- Xmain(ac,av)
- Xchar *av[];
- X{
- X HDR Hdr;
- X short error;
- X
- X {
- X char *ldir = ".";
- X struct stat stat;
- X ac = DoOption(ac, av, "N%sd%sc", &NetId, &ldir, &ContMode);
- X if (ac <= 1) {
- X puts("GETFILES [-Nnetid -dlocaldir -c] remotefile/dir ...");
- X fail(22);
- X }
- X if (chdir(ldir) < 0) {
- X mkdir(ldir, 0777);
- X if (chdir(ldir) < 0) {
- X printf("Unable to CD or make local directory: \"%s\"\n",ldir);
- X fail(21);
- X }
- X }
- X }
- X Chan = DOpen(NetId, PORT_GFILECOPY, 126, -80);
- X if (Chan < 0) {
- X puts("Unable to connect");
- X fail(20);
- X }
- X error = WriteHeader('H', "Hello, getfiles client V1.30", 0);
- X if (error)
- X fail(LostChannel());
- X switch(ReadHeader(&Hdr)) {
- X case -1:
- X fail(LostChannel());
- X case 'H':
- X printf("%s\n", Hdr.Str);
- X break;
- X }
- X {
- X register short i;
- X long val;
- X
- X for (i = 1; i < ac; ++i) {
- X short error;
- X
- X error = WriteHeader('G', av[i], 0);
- X if (error)
- X fail(LostChannel());
- X switch(ReadHeader(&Hdr)) {
- X case -1:
- X fail(LostChannel());
- X case 'N':
- X printf("Remote error on %s: %s\n", av[i], Hdr.Str);
- X break;
- X case 'F':
- X error = CheckNoPath(Hdr.Str);
- X if (!error) {
- X char svpath[1024];
- X getwd(svpath);
- X error = GetFile(&Hdr, 0);
- X chdir(svpath);
- X }
- X break;
- X case 'D':
- X error = CheckNoPath(Hdr.Str);
- X if (!error) {
- X char svpath[1024];
- X getwd(svpath);
- X error = GetDir(&Hdr, 0);
- X chdir(svpath);
- X }
- X break;
- X case 'S':
- X printf("Access Violation: %s\n", Hdr.Str);
- X break;
- X default:
- X error = UnknownCmd(&Hdr);
- X break;
- X }
- X if (error)
- X fail(error);
- X }
- X if (!error) {
- X error = WriteHeader('E', "bye", 0);
- X if (error)
- X fail(LostChannel());
- X }
- X }
- X fail(0);
- X}
- X
- Xfail(code)
- X{
- X if (Chan >= 0)
- X close(Chan);
- X exit(code);
- X}
- X
- XCheckNoPath(str)
- Xregister char *str;
- X{
- X while (*str) {
- X if (*str == '/' || *str == ':') {
- X puts("SECURITY ALERT: Illegal path spec received");
- X return(40);
- X }
- X ++str;
- X }
- X return(0);
- X}
- X
- XLostChannel()
- X{
- X puts("DATA CHANNEL LOST");
- X return(10);
- X}
- X
- XUnknownCmd(hdr)
- XHDR *hdr;
- X{
- X printf("Unrecognized command code: %02x\n", hdr->Cmd);
- X}
- X
- X/*
- X * retrieve a file. If ContMode set and file exists, try to append to
- X * it.
- X */
- X
- X
- X#define BSSTR "\010\010\010\010\010\010\010\010\010\010\010\010\010"
- X
- XGetFile(hdr, stab)
- XHDR *hdr;
- X{
- X int fd = -1;
- X long pos = 0;
- X short error = 0;
- X
- X printf("%s%-20s ", NSpaces(stab), hdr->Str);
- X fflush(stdout);
- X if (ContMode) {
- X if ((fd = open(hdr->Str, O_WRONLY)) >= 0) { /* already exists */
- X long len;
- X
- X len = lseek(fd, 0L, 2);
- X if (len > hdr->Val) {
- X close(fd);
- X printf("Cont Error, local file is larger than remote!: %s\n",
- X hdr->Str
- X );
- X puts("(not downloaded)");
- X return(0);
- X }
- X if (len == hdr->Val) {
- X close(fd);
- X if (error = WriteHeader('S', NULL, 0))
- X return(LostChannel());
- X puts("HAVE IT, SKIP");
- X return(0);
- X }
- X printf("(HAVE %ld/%ld) ", len, hdr->Val);
- X hdr->Val -= len; /* that much less */
- X pos = len; /* start at offset */
- X }
- X }
- X if (fd < 0) {
- X fd = open(hdr->Str, O_WRONLY|O_CREAT|O_TRUNC, 0666);
- X if (fd < 0) {
- X error = WriteHeader('N', "open error", 0);
- X printf("Unable to open %s for output\n", hdr->Str);
- X if (error)
- X return(LostChannel());
- X return(1);
- X }
- X }
- X error = WriteHeader('Y', NULL, pos); /* yes, gimme gimme */
- X
- X /*
- X * Retrieve the data
- X */
- X
- X if (!error) {
- X register long left = hdr->Val;
- X register long cnt = pos;
- X long total = pos + left;
- X
- X printf(" ");
- X while (left) {
- X register long n = (left > sizeof(Buf)) ? sizeof(Buf) : left;
- X printf("%s%6ld/%6ld", BSSTR, cnt, total);
- X fflush(stdout);
- X if (ggread(Chan, Buf, n) != n) {
- X error = 5;
- X break;
- X }
- X if (write(fd, Buf, n) != n) {
- X puts("Local Write failed!");
- X error = 6;
- X break;
- X }
- X left -= n;
- X cnt += n;
- X }
- X printf("%s%6ld/%6ld %s", BSSTR, cnt, total,
- X ((cnt == total) ? "OK" : "INCOMPLETE")
- X );
- X }
- X puts("");
- X if (error) {
- X fchmod(fd, 0222);
- X close(fd);
- X return(LostChannel());
- X }
- X close(fd);
- X return(error);
- X}
- X
- X/*
- X * Retrieve a directory. Create it if necessary.
- X */
- X
- XGetDir(hdr, stab)
- XHDR *hdr;
- X{
- X short error = 0;
- X long dirlock;
- X static HDR Hdr; /* note: static */
- X char svpath[1024];
- X
- X printf("%s%-20s(DIR)\n", NSpaces(stab), hdr->Str);
- X getwd(svpath);
- X if (chdir(hdr->Str) < 0) {
- X mkdir(hdr->Str, 0777);
- X if (chdir(hdr->Str) < 0) {
- X error = WriteHeader('N', "couldn't create", 0);
- X printf("Unable to create local directory: %s\n", hdr->Str);
- X if (error)
- X return(LostChannel());
- X return(1);
- X }
- X }
- X error = WriteHeader('Y', NULL, 0); /* yes, gimme gimme */
- X while (!error) {
- X switch(ReadHeader(&Hdr)) {
- X case -1:
- X error = 1;
- X break;
- X case 'E': /* end of directory */
- X chdir(svpath);
- X return(0);
- X break;
- X case 'F':
- X error = CheckNoPath(Hdr.Str);
- X if (!error) {
- X char svpath2[1024];
- X getwd(svpath2);
- X error = GetFile(&Hdr, stab + 4);
- X chdir(svpath2);
- X }
- X break;
- X case 'D':
- X error = CheckNoPath(Hdr.Str);
- X if (!error) {
- X char svpath2[1024];
- X getwd(svpath2);
- X error = GetDir(&Hdr, stab + 4);
- X chdir(svpath2);
- X }
- X break;
- X case 'S':
- X printf("Access Violation: %s\n", Hdr.Str);
- X break;
- X case 'N':
- X printf("REMOTE ERROR: %s\n", Hdr.Str);
- X error = 10;
- X break;
- X default:
- X error = UnknownCmd(&Hdr);
- X break;
- X }
- X }
- X chdir(svpath);
- X return(LostChannel());
- X}
- X
- XWriteHeader(c, str, len)
- Xchar c;
- Xchar *str;
- Xlong len;
- X{
- X ubyte sl;
- X
- X if (str == NULL)
- X str = "";
- X sl = strlen(str);
- X
- X if (gwrite(Chan, &c, 1) < 0)
- X return(1);
- X if (gwrite(Chan, &sl,1) < 0)
- X return(1);
- X if (gwrite(Chan, str, sl) != sl)
- X return(1);
- X len = htonl68(len);
- X if (gwrite(Chan, &len, 4) != 4)
- X return(1);
- X return(0);
- X}
- X
- XReadHeader(hdr)
- XHDR *hdr;
- X{
- X ubyte sl;
- X ubyte cmd;
- X
- X hdr->Cmd = -1;
- X if (ggread(Chan, &cmd, 1) != 1)
- X return(-1);
- X if (ggread(Chan, &sl, 1) != 1)
- X return(-1);
- X if (sl >= sizeof(hdr->Str)) {
- X puts("Software error: received file name length too long");
- X return(-1);
- X }
- X if (ggread(Chan, hdr->Str, sl) != sl)
- X return(-1);
- X hdr->Str[sl] = 0;
- X if (ggread(Chan, &hdr->Val, 4) != 4)
- X return(-1);
- X hdr->Val = ntohl68(hdr->Val);
- X hdr->Cmd = cmd;
- X return(hdr->Cmd);
- X}
- X
- Xchar *
- XNSpaces(n)
- Xshort n;
- X{
- X static char Buf[128];
- X static short in = 0;
- X static short last;
- X
- X if (in == 0) {
- X register short i;
- X in = 1;
- X for (i = 0; i < sizeof(Buf); ++i)
- X Buf[i] = ' ';
- X }
- X Buf[last] = ' ';
- X if (n < 127)
- X Buf[n] = 0;
- X last = n;
- X return(Buf);
- X}
- X
- SHAR_EOF
- echo "extracting client/putfiles.c"
- sed 's/^X//' << \SHAR_EOF > client/putfiles.c
- X
- X/*
- X * PUTFILES.C
- X *
- X * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
- X *
- X * Download one or more files from the remote computer
- X *
- X * PUTFILES file/dir1 file/dir2 ... file/dirN
- X *
- X * placed in directory server ran from on remote host.
- X */
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/dir.h>
- X#include <stdio.h>
- X#include <sys/file.h>
- X#include "../server/servers.h"
- X
- Xchar Buf[1024];
- X
- Xtypedef struct stat STAT;
- X
- Xmain(ac,av)
- Xchar *av[];
- X{
- X long chan;
- X long n, len, orig;
- X long fh;
- X short i, j;
- X char fn;
- X
- X if (ac == 1) {
- X puts("putfiles V1.00 (c)Copyright 1987, Matthew Dillon, All Rights Reserved");
- X puts("putfiles file/dir file/dir .....");
- X exit(1);
- X }
- X
- X chan = DOpen(NULL, PORT_FILECOPY, -80, 126);
- X if (chan < 0) {
- X puts("Unable to connect");
- X exit(1);
- X }
- X ggread(chan, &fn, 1);
- X if (fn != 'Y') {
- X puts("Remote Server Software Error");
- X close(chan);
- X }
- X for (i = 1; i < ac; ++i) {
- X if (strncmp(av[i], "-d", 2) == 0) {/*-ddir or -d dir*/
- X char *dir = av[i]+2;
- X if (*dir == 0 && i+1 < ac) {
- X ++i;
- X dir = av[i];
- X }
- X if (writehdr_nc(chan, 'C', dir, 0) != 'Y') {
- X puts ("unable to go to specified remote directory");
- X break;
- X }
- X } else {
- X if (putname(chan, av[i]) < 0)
- X break;
- X }
- X }
- X printf("\nclosing... ");
- X fflush(stdout);
- X close(chan);
- X puts("done");
- X}
- X
- Xputname(chan, file)
- Xchar *file;
- X{
- X STAT sstat;
- X char svdir[256];
- X int ret;
- X
- X printf("%-20s ", file);
- X if (stat(file, &sstat) < 0) {
- X puts("NOT FOUND");
- X return(1);
- X }
- X if (sstat.st_mode & S_IFDIR) {
- X DIR *dir;
- X struct direct *de;
- X
- X getwd(svdir);
- X puts("DIR");
- X chdir(file);
- X if (writehdr(chan, 'X', file, 0) != 'Y') {
- X puts("Remote unable to make directory");
- X goto f1;
- X }
- X if (dir = opendir(".")) {
- X while (de = readdir(dir)) {
- X if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name,"..")==0)
- X continue;
- X if (putname(chan, de->d_name) < 0) {
- X ret = -1;
- X break;
- X }
- X }
- X }
- X writehdr(chan, 'Y', "?", 0);
- Xf1:
- X chdir(svdir);
- X } else {
- X ret = putfile(chan, file);
- X }
- X return(ret);
- X}
- X
- Xputfile(chan, file)
- Xchar *file;
- X{
- X int fd = open(file, O_RDONLY);
- X long n, r, len;
- X long ttl = 0;
- X char co;
- X
- X fflush(stdout);
- X if (fd < 0) {
- X puts("FILE NOT FOUND");
- X return(0);
- X }
- X len = ttl = lseek(fd, 0, 2);
- X lseek(fd, 0, 0);
- X if (writehdr(chan, 'W', file, len) != 'Y') {
- X puts("REMOTE UNABLE TO ACCEPT FILE");
- X close(fd);
- X return(0);
- X }
- X printf("%6ld/%-6ld", ttl - len, ttl);
- X while (len) {
- X fflush(stdout);
- X r = (len > sizeof(Buf)) ? sizeof(Buf) : len;
- X n = read(fd, Buf, r);
- X if (n != r) {
- X puts("Local File error");
- X close(fd);
- X return(-1);
- X }
- X if (gwrite(chan, Buf, n) != n) {
- X puts("Remote error");
- X close(fd);
- X return(-1);
- X }
- X len -= n;
- X printf("\010\010\010\010\010\010\010\010\010\010\010\010\010");
- X printf("%6ld/%-6ld", ttl - len, ttl);
- X }
- X close(fd);
- X if (len) {
- X puts("REMOTE ERROR");
- X return(-1);
- X }
- X printf(" Queued, waiting... ");
- X fflush(stdout);
- X ggread(chan, &co, 1);
- X if (co != 'Y') {
- X puts("Remote Server Software Error");
- X return(-1);
- X }
- X puts("OK");
- X return(0);
- X}
- X
- Xwritehdr(chan, c, name, len)
- Xunsigned char c;
- Xchar *name;
- Xlong len;
- X{
- X short i;
- X for (i = strlen(name) - 1; i >= 0; --i) {
- X if (name[i] == '/' || name[i] == ':')
- X break;
- X }
- X name += i + 1;
- X return(writehdr_nc(chan, c, name, len));
- X}
- X
- Xwritehdr_nc(chan, c, name, len)
- Xunsigned char c;
- Xchar *name;
- Xlong len;
- X{
- X gwrite(chan, &c, 1);
- X c = strlen(name) + 1;
- X gwrite(chan, &c, 1);
- X gwrite(chan, name, c);
- X len = htonl68(len);
- X gwrite(chan, &len, 4);
- X if (ggread(chan, &c, 1) == 1)
- X return(c);
- X return(-1);
- X}
- X
- SHAR_EOF
- echo "extracting client/dsoc.c"
- sed 's/^X//' << \SHAR_EOF > client/dsoc.c
- X
- X/*
- X * DSOC.C
- X *
- X * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
- X *
- X * DSOC [port#]
- X *
- X * Connect to the specified port# .. Used to connect to a remote CLI
- X * (s_shell server on the Amiga, which requires PIPE: to work, port 8196,
- X * is the default)
- X *
- X * Uses standard cooked mode instead of RAW mode.
- X */
- X
- X
- X#include <sys/types.h>
- X#include <sys/ioctl.h>
- X#include <stdio.h>
- X#include <sys/file.h>
- X#include <signal.h>
- X#include <errno.h>
- X#include "../server/servers.h"
- X
- Xint fd;
- Xchar buf[2048];
- X
- Xmain(ac,av)
- Xchar *av[];
- X{
- X int n;
- X extern int handler();
- X int port = (av[1]) ? atoi(av[1]) : PORT_AMIGASHELL;
- X
- X puts("DSOC V1.01 11 March 1988 Connecting");
- X fd = DOpen(NULL, port, 0, 0);
- X if (fd < 0) {
- X perror("DOpen");
- X exit(1);
- X }
- X puts("Connected");
- X signal(SIGIO, handler);
- X fcntl(fd, F_SETOWN, getpid());
- X fcntl(fd, F_SETFL, FNDELAY|FASYNC);
- X while ((n = gread(0, buf, sizeof(buf))) > 0) {
- X gwrite(fd, buf, n);
- X }
- X fprintf(stderr, "EOF\n");
- X DEof(fd);
- X for (;;)
- X pause();
- X}
- X
- Xhandler()
- X{
- X int n;
- X char buf[1024];
- X
- X while ((n = read(fd, buf, sizeof(buf))) > 0)
- X write(1, buf, n);
- X if (n == 0) {
- X write(1, "REMEOF\n", 7);
- X exit(1);
- X }
- X}
- X
- SHAR_EOF
- echo "extracting client/draw.c"
- sed 's/^X//' << \SHAR_EOF > client/draw.c
- X
- X/*
- X * DRAW.C
- X *
- X * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
- X *
- X * DRAW [port#]
- X *
- X * Put terminal into RAW mode and connect to the remote dnet port.
- X * used mainly to test DNET. Can also be used open a TERM window on
- X * the amiga (via the STERM server), which is the default (port 8195)
- X */
- X
- X
- X
- X#include <sys/types.h>
- X#include <sys/ioctl.h>
- X#include <stdio.h>
- X#include <sys/file.h>
- X#include <signal.h>
- X#include <errno.h>
- X#include "../server/servers.h"
- X
- Xint fd;
- Xchar buf[4096];
- X
- Xmain(ac,av)
- Xchar *av[];
- X{
- X int n;
- X extern int handler();
- X int port = (av[1]) ? atoi(av[1]) : PORT_AMIGATERM;
- X
- X puts("DRAW V1.01 11 March 1988 Connecting");
- X fd = DOpen(NULL, port, 0, 0);
- X if (fd < 0) {
- X perror("DOpen");
- X exit(1);
- X }
- X puts("Connected");
- X signal(SIGIO, handler);
- X ttyraw();
- X fcntl(fd, F_SETOWN, getpid());
- X fcntl(fd, F_SETFL, FNDELAY|FASYNC);
- X fcntl(0, F_SETFL, FNDELAY);
- X while ((n = gread(0, buf, sizeof(buf))) > 0) {
- X gwrite(fd, buf, n);
- X }
- X fprintf(stderr, "EOF\n");
- X DEof(fd);
- X for (;;)
- X pause();
- X}
- X
- Xhandler()
- X{
- X int n;
- X char buf[1024];
- X
- X while ((n = read(fd, buf, sizeof(buf))) > 0)
- X write(1, buf, n);
- X if (n == 0) {
- X write(1, "REMEOF\n", 7);
- X ttynormal();
- X exit(1);
- X }
- X}
- X
- Xstatic struct sgttyb ttym;
- X
- Xttyraw()
- X{
- X ioctl (0, TIOCGETP, &ttym);
- X ttym.sg_flags |= RAW;
- X ttym.sg_flags &= ~CBREAK;
- X ttym.sg_flags &= ~ECHO;
- X ioctl (0, TIOCSETP, &ttym);
- X}
- X
- Xttynormal()
- X{
- X ioctl (0, TIOCGETP, &ttym);
- X ttym.sg_flags &= ~RAW;
- X ttym.sg_flags |= CBREAK;
- X ttym.sg_flags |= ECHO;
- X ioctl (0, TIOCSETP, &ttym);
- X}
- X
- SHAR_EOF
- echo "extracting client/dprint.c"
- sed 's/^X//' << \SHAR_EOF > client/dprint.c
- X
- X/*
- X * DPRINT.C
- X *
- X * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
- X *
- X * send files to the other computer's printer.
- X *
- X * DPRINT [files] (stdin if no files specified)
- X */
- X
- X#include <stdio.h>
- X#include "../server/servers.h"
- X
- Xmain(ac,av)
- Xchar *av[];
- X{
- X register short i;
- X long chan;
- X
- X chan = DOpen(NULL, PORT_PRINTER, -80, 126);
- X if (chan < 0) {
- X puts("Unable to connect");
- X exit(1);
- X }
- X for (i = 1; i < ac; ++i) {
- X FILE *fi;
- X
- X printf("%-20s ", av[i]);
- X fflush(stdout);
- X if (fi = fopen(av[i], "r")) {
- X printf("dumping ");
- X fflush(stdout);
- X dump_file(fi, chan);
- X fclose(fi);
- X puts("");
- X }
- X }
- X if (ac == 1)
- X dump_file(stdin, chan);
- X close(chan);
- X}
- X
- Xdump_file(fi, chan)
- XFILE *fi;
- X{
- X int n;
- X char buf[256];
- X
- X while ((n = fread(buf, 1, sizeof(buf), fi)) > 0) {
- X gwrite(chan, buf, n);
- X }
- X}
- X
- SHAR_EOF
- echo "extracting client/Makefile"
- sed 's/^X//' << \SHAR_EOF > client/Makefile
- X
- X# DNET CLIENTS
- X#
- X# DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
- X#
- X
- XNETLIB = ../lib/dnetlib.o
- XBIN = ../bin
- X
- X
- Xall: $(NETLIB) $(BIN)/draw $(BIN)/dsoc $(BIN)/putfiles $(BIN)/dprint \
- X $(BIN)/getfiles
- X
- X$(BIN)/draw: draw.o
- X cc draw.o $(NETLIB) -o $(BIN)/draw
- X
- X$(BIN)/dsoc: dsoc.o
- X cc dsoc.o $(NETLIB) -o $(BIN)/dsoc
- X
- X$(BIN)/getfiles: getfiles.o
- X cc getfiles.o $(NETLIB) -o $(BIN)/getfiles
- X
- X$(BIN)/putfiles: putfiles.o
- X cc putfiles.o $(NETLIB) -o $(BIN)/putfiles
- X
- X$(BIN)/dprint: dprint.o
- X cc dprint.o $(NETLIB) -o $(BIN)/dprint
- X
- Xclean:
- X rm -f *.o make.out
- X
- SHAR_EOF
- if `test ! -d dnet`
- then
- mkdir dnet
- echo "mkdir dnet"
- fi
- echo "extracting dnet/channel.h"
- sed 's/^X//' << \SHAR_EOF > dnet/channel.h
- X
- X/*
- X * CHANNEL.H
- X *
- X * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
- X *
- X * Channel structures for SCMD_* channel commands.
- X *
- X * NOTE: These structures may be ONLY 0,2,4, or 6 bytes in size.
- X */
- X
- X#define CSWITCH struct _CSWITCH
- X#define COPEN struct _COPEN
- X#define CCLOSE struct _CCLOSE
- X#define CACKCMD struct _CACKCMD
- X#define CEOFCMD struct _CEOFCMD
- X#define CIOCTL struct _CIOCTL
- X
- XCSWITCH { /* SWITCH current data channel */
- X ubyte chanh; /* channel to switch to */
- X ubyte chanl;
- X};
- X
- XCOPEN { /* OPEN port on channel */
- X ubyte chanh; /* try to use this channel */
- X ubyte chanl;
- X ubyte porth; /* requested port from client */
- X ubyte portl;
- X ubyte error; /* error return 0=ok */
- X char pri; /* chan. priority -127 to 126 */
- X};
- X
- XCCLOSE { /* CLOSE a channel */
- X ubyte chanh; /* channel to close */
- X ubyte chanl;
- X};
- X
- XCACKCMD { /* Acknowledge an open */
- X ubyte chanh; /* channel */
- X ubyte chanl;
- X ubyte error; /* 0=ok 1=fail 33=retry w/ different channel */
- X ubyte filler;
- X};
- X
- XCEOFCMD { /* Send [R/W] EOF */
- X ubyte chanh; /* channel to send EOF on */
- X ubyte chanl;
- X ubyte flags; /* CHANF_ROK/WOK (bits to clear) */
- X ubyte filler;
- X};
- X
- XCIOCTL {
- X ubyte chanh; /* channel */
- X ubyte chanl;
- X ubyte cmd; /* ioctl command */
- X ubyte valh; /* ioctl value */
- X ubyte vall;
- X ubyte valaux; /* auxillary field */
- X};
- X
- X#define CIO_SETROWS 1 /* PTY's only */
- X#define CIO_SETCOLS 2 /* PTY's only */
- X#define CIO_STOP 3 /* any channel, flow control */
- X#define CIO_START 4 /* any channel, flow control */
- X#define CIO_FLUSH 5 /* any channel, flush pending */
- X /* writes down the toilet */
- X
- X#define CHAN struct _CHAN
- X
- XCHAN {
- X int fd; /* file descriptor for channel */
- X uword port; /* port# (used in open sequence) */
- X ubyte state; /* state of channel */
- X ubyte flags; /* channel flags */
- X char pri; /* priority of channel */
- X};
- X
- SHAR_EOF
- echo "extracting dnet/control.c"
- sed 's/^X//' << \SHAR_EOF > dnet/control.c
- X
- X/*
- X * CONTROL.C
- X *
- X * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
- X *
- X * -handle various actions:
- X * RTO - read timeout
- X * WTO - write timeout (a packet not acked)
- X * RNET - state machine for raw receive packet
- X * WNET - starts timeout sequence if Write occured
- X * WUPDATE - update write windows, send packets
- X * RUPDATE - execute received packets in correct sequence
- X * RECCMD - execute decoded SCMD commands obtained from received
- X * packets.
- X */
- X
- X#include "dnet.h"
- X#include <stdio.h>
- X
- Xextern void do_cmd();
- X
- X/*
- X * RTO: read timeout. Timeout occured while waiting for the rest of
- X * a packet. Reset state and restart read.
- X */
- X
- Xdo_rto()
- X{
- X RState = 0;
- X RcvData = 0;
- X if (DDebug)
- X fprintf(stderr, "RTO\n");
- X}
- X
- X/*
- X * WTO: Write timeout (unresolved output windows exist). Resend a CHECK
- X * command for all unresolved (READY) output windows
- X */
- X
- Xvoid
- Xdo_wto()
- X{
- X register short i;
- X register PKT *pkt;
- X register uword len = 0;
- X
- X if (DDebug)
- X fprintf(stderr, "WTO\n");
- X if (Restart) {
- X WCBuf[0] = SYNC;
- X WCBuf[1] = PKCMD_RESTART;
- X WCBuf[2] = (WCBuf[0]<<1)^WCBuf[1];
- X NetWrite(WCBuf, 3, 1);
- X WTimeout(WTIME);
- X return;
- X }
- X for (i = 0; i < WPUsed; ++i) {
- X pkt = WPak[i];
- X if (pkt->state == READY) { /* send check */
- X WCBuf[len+0] = SYNC;
- X WCBuf[len+1] = PKCMD_CHECK | ((WPStart + i) << 5);
- X WCBuf[len+2] = (WCBuf[len+0] << 1) ^ WCBuf[len+1];
- X len += 3;
- X }
- X }
- X if (len) {
- X NetWrite(WCBuf, len, 1);
- X WTimeout(WTIME);
- X }
- X}
- X
- X/*
- X * RNET: Receved data ready from network. The RNet request will
- X * automagically be reissued on return.
- X */
- X
- Xdo_rnet()
- X{
- X register ubyte *ptr = RcvBuf;
- X register long len = RcvData;
- X long lrd = len;
- X long mark;
- X static uword dlen;
- X static uword dblen;
- X static ubyte dctl;
- X
- X if (DDebug)
- X fprintf(stderr, "NETREAD %08lx %ld\n", RcvBuf, RcvData);
- X while (len) {
- X switch(RState) {
- X case RS_SYNC:
- X --len;
- X if (*ptr++ == SYNC)
- X RState = RS_CTL;
- X break;
- X case RS_CTL:
- X --len;
- X dctl = *ptr++;
- X RState = RS_CCHK;
- X break;
- X case RS_CCHK:
- X /* warning: (ubyte) cast not implemented properly for some
- X * compilers
- X */
- X if ((((SYNC<<1)^dctl) & 0xFF) == *ptr) {
- X ++ptr;
- X --len;
- X if (dctl & PKF_DATA) {
- X RState = RS_LEN1;
- X break;
- X }
- X RState = RS_SYNC;
- X if (DDebug)
- X fprintf(stderr, "DO COMMAND (0DATA) 0x%02lx\n", dctl);
- X do_cmd(dctl, NULL, 0);
- X } else {
- X if (DDebug)
- X fprintf(stderr, "RS_CCHK FAILED\n");
- X if (len) { /* Resync at earliest point */
- X ++len;
- X --ptr;
- X }
- X }
- X RState = RS_SYNC;
- X break;
- X case RS_LEN1:
- X dlen = *ptr;
- X ++ptr;
- X --len;
- X RState = RS_LEN2;
- X break;
- X case RS_LEN2:
- X dlen = (dlen << 8) + *ptr + 2;
- X ++ptr;
- X --len;
- X if (dlen > MAXPKT+2) {
- X if (DDebug)
- X fprintf(stderr,"RAW DATA: LENGTH FAILURE (cmd %02x) %ld\n",
- X dctl, dlen
- X );
- X RState = RS_SYNC;
- X break;
- X }
- X RState = RS_DATA;
- X break;
- X case RS_DATA:
- X if (DDebug)
- X fprintf(stderr, "RS_DATA->");
- X if (dlen <= len) {
- X register uword chk = chkbuf(ptr, dlen - 2);
- X if ((chk >> 8) == ptr[dlen-2] && (chk & 0xFF) == ptr[dlen-1]) {
- X if (DDebug)
- X fprintf(stderr, "DO MPX (%ld DATA) 0x%02lx\n",
- X dlen-2, dctl
- X );
- X do_cmd(dctl, ptr, dlen-2);
- X len -= dlen;
- X ptr += dlen;
- X } else {
- X if (DDebug)
- X fprintf(stderr, "RS_DATA: FAILED\n");
- X }
- X RState = RS_SYNC;
- X } else {
- X if (DDebug)
- X fprintf(stderr, "RS_DATA: INCOMPLETE READ\n");
- X goto break2; /* incomplete read */
- X }
- X break;
- X }
- X }
- Xbreak2:
- X switch(RState) {
- X case RS_DATA:
- X RExpect = dlen - len;
- X if (RExpect < 0) {
- X fprintf(stderr, "panic, RExpect = %ld\n", RExpect);
- X exit(1);
- X }
- X break;
- X default:
- X RExpect = 0;
- X break;
- X }
- X do_cmd(-1, NULL, 0);
- X mark = len;
- X {
- X if (len && ptr != RcvBuf)
- X bcopy(ptr, RcvBuf, len);
- X RcvData = len;
- X }
- X if (RState == RS_DATA) {
- X ;
- X /*
- X *RDisable();
- X *RTimeout(RTIME/1000);
- X */
- X }
- X /* REMOVED 21 Sept 1988
- X * do_wupdate();
- X */
- X return(mark);
- X}
- X
- X/*
- X * WNET: The last data packet has been sent to the network... Start a
- X * timeout sequence (1 second). If this times out we will send
- X * a CHECK packet for all unresolved transmission windows.
- X */
- X
- Xdo_wnet()
- X{
- X if (DidWrite) {
- X DidWrite = 0;
- X if (DDebug)
- X fprintf(stderr, "WNET-STARTTO\n");
- X WTimeout(WTIME);
- X } else {
- X if (DDebug)
- X fprintf(stderr, "WNET-NOP\n");
- X }
- X}
- X
- X/*
- X * DO_WUPDATE()
- X *
- X * (1) Remove EMPTY windows at head of transmit queue.
- X * (2) Fill up transmit queue with pending requests, if any.
- X *
- X * First two bits determine CMD as follows:
- X * 0bbbbbbb DATA 0-127 bytes of DATA
- X * 10bbbccc DATA 0-7 bytes of DATA, ccc=channel
- X * command.
- X * 11bbbbbb bbbbbbbb DATA 0-1023 bytes of DATA
- X */
- X
- Xdo_wupdate()
- X{
- X static short XPri;
- X int maxpktsize;
- X register XIOR *ior;
- X register PKT *pkt;
- X register long len;
- X
- X while (WPUsed && WPak[0]->state == EMPTY) {
- X pkt = WPak[0];
- X WPak[0] = WPak[1];
- X WPak[1] = WPak[2];
- X WPak[2] = WPak[3];
- X WPak[3] = pkt;
- X --WPUsed;
- X ++WPStart;
- X }
- X if (Restart)
- X return(0);
- X
- X while (WPUsed != 4 && (ior = (XIOR *)RemHead(&TxList))) {
- X register long offset = 0;
- X
- X {
- X short npri;
- X
- X if (ior->io_Command == SCMD_DATA)
- X npri = ior->io_Pri << 2;
- X else
- X npri = XPri;
- X if (npri >= XPri) {
- X XPri = npri;
- X } else {
- X if (XPri - npri > 100)
- X XPri -= 10;
- X else if (XPri - npri > 50)
- X XPri -= 5;
- X else
- X --XPri;
- X }
- X maxpktsize = MAXPKT - (XPri - npri);
- X if (DDebug)
- X fprintf(stderr, "**MAXPKTSIZE = %ld XPri %ld npri %ld\n",
- X maxpktsize, XPri, npri
- X );
- X if (maxpktsize < MINPKT)
- X maxpktsize = MINPKT;
- X }
- X
- X pkt = WPak[WPUsed];
- X pkt->state = READY;
- X pkt->sync = SYNC;
- X pkt->ctl = PKCMD_WRITE | PKF_DATA | ((WPStart + WPUsed)<<5);
- X pkt->cchk = (pkt->sync << 1) ^ pkt->ctl;
- X for (;;) {
- X if (offset > (maxpktsize-8)) /* not enough room */
- X break;
- X if (ior->io_Command == SCMD_DATA && ior->io_Channel != WChan) {
- X /* CSWITCH */
- X WChan = ior->io_Channel;
- X pkt->data[offset+0] = 0x80|SCMD_SWITCH|(2<<3);
- X pkt->data[offset+1] = WChan >> 8;
- X pkt->data[offset+2] = WChan;
- X offset += 3;
- X if (DDebug)
- X fprintf(stderr, "SEND SWITCH %ld\n", WChan);
- X }
- X len = ior->io_Length - ior->io_Actual;
- X if (ior->io_Command == SCMD_DATA) { /* DATA */
- X if (DDebug)
- X fprintf(stderr, "SEND DATA %ld bytes\n", len);
- X if (offset + len > (maxpktsize-4))
- X len = (maxpktsize-4) - offset;
- X if (len < 128) {
- X pkt->data[offset] = len;
- X ++offset;
- X } else {
- X pkt->data[offset+0] = (len>>8)|0xC0;
- X pkt->data[offset+1] = len;
- X offset += 2;
- X }
- X } else { /* COMMAND */
- X pkt->data[offset] = 0x80|ior->io_Command|(len<<3);
- X ++offset;
- X }
- X bcopy((char *)ior->io_Data+ior->io_Actual,pkt->data+offset,len);
- X offset += len;
- X ior->io_Actual += len;
- X if (ior->io_Actual == ior->io_Length) {
- X free(ior->io_Data);
- X free(ior);
- X ior = (XIOR *)RemHead(&TxList); /* Next packet */
- X if (ior == NULL)
- X break;
- X }
- X }
- X pkt->iolength = offset + OVERHEAD;
- X pkt->lenh = offset >> 8;
- X pkt->lenl = offset;
- X {
- X register uword chksum = chkbuf(pkt->data, offset);
- X pkt->data[offset+0] = chksum >> 8;
- X pkt->data[offset+1] = chksum;
- X }
- X NetWrite(&pkt->sync, pkt->iolength, 1);
- X if (ior) {
- X ++ior->io_Pri;
- X Enqueue(&TxList, ior);
- X --ior->io_Pri;
- X }
- X ++WPUsed;
- X }
- X}
- X
- Xvoid
- Xdumpcheck(ptr)
- Xregister ubyte *ptr;
- X{
- X register short i;
- X for (i = 0;i < 8; ++i) {
- X if (ptr[i])
- X replywindow(i);
- X ptr[i] = 0;
- X }
- X}
- X
- Xvoid
- Xdo_cmd(ctl, buf, bytes)
- Xshort ctl; /* actually a ubyte */
- Xubyte *buf;
- X{
- X ubyte window = ctl >> 5;
- X ubyte rwindow;
- X static ubyte Chk, Chkwin[8]; /* remember window checks */
- X
- X if (ctl == -1) { /* end of sequence */
- X dumpcheck(Chkwin);
- X Chk = 0;
- X return;
- X }
- X if ((ctl & PKF_MASK) == PKCMD_CHECK) { /* CHECK packet */
- X Chkwin[window] = 1;
- X Chk = 1;
- X return;
- X }
- X if (Chk) { /* NON-CHECK packet*/
- X dumpcheck(Chkwin);
- X Chk = 0;
- X }
- X switch(ctl & PKF_MASK) {
- X case PKCMD_WRITE:
- X rwindow = (window - RPStart) & 7;
- X if (rwindow < 4) {
- X bcopy(buf, RPak[rwindow]->data, bytes);
- X RPak[rwindow]->iolength = bytes;
- X RPak[rwindow]->state = READY;
- X if (rwindow == 0)
- X do_rupdate();
- X }
- X replywindow(window);
- X break;
- X case PKCMD_ACK:
- X rwindow = (window - WPStart) & 7;
- X if (rwindow < WPUsed) /* mark as sent */
- X WPak[rwindow]->state = EMPTY;
- X break;
- X case PKCMD_NAK: /* resend */
- X rwindow = (window - WPStart) & 7;
- X if (rwindow < WPUsed) { /* resend */
- X NetWrite(&WPak[rwindow]->sync, WPak[rwindow]->iolength, 0);
- X } else {
- X fprintf(stderr, "Soft Error: Illegal NAK\n");
- X }
- X break;
- X case PKCMD_ACKRSTART:
- X case PKCMD_RESTART:
- X {
- X uword chan;
- X uword chksum;
- X int len;
- X int fd;
- X
- X if ((ctl & PKF_MASK) == PKCMD_ACKRSTART)
- X Restart = 0;
- X do_netreset();
- X if ((ctl & PKF_MASK) == PKCMD_RESTART) {
- X gethostname(WCBuf+5, sizeof(WCBuf)-5-3);
- X len = strlen(WCBuf+5)+1;
- X WCBuf[0] = SYNC;
- X WCBuf[1] = PKCMD_ACKRSTART | PKF_DATA;
- X WCBuf[2] = (SYNC << 1) ^ WCBuf[1];
- X WCBuf[3] = 0;
- X WCBuf[4] = len;
- X chksum = chkbuf(WCBuf+5, len);
- X WCBuf[5+len] = chksum >> 8;
- X WCBuf[6+len] = chksum;
- X NetWrite(WCBuf, 7+len, 1);
- X }
- X if (bytes)
- X setlistenport(buf);
- X else
- X setlistenport("");
- X do_wupdate();
- X WTimeout(WTIME);
- X }
- X break;
- X }
- X do_rupdate();
- X}
- X
- Xdo_rupdate()
- X{
- X while (RPak[0]->state == READY) {
- X register PKT *pkt = RPak[0];
- X register ubyte *ptr = pkt->data;
- X register uword len;
- X uword iolen = pkt->iolength;
- X ubyte cmd;
- X
- X if (DDebug)
- X fprintf(stderr, "Interpret Received Commands\n");
- X while (iolen) {
- X cmd = SCMD_DATA;
- X len = ptr[0];
- X ++ptr;
- X --iolen;
- X if (len >= 128) {
- X if (len < 0xC0) {
- X cmd = len & 7;
- X len = (len >> 3) & 7;
- X } else {
- X len = ((len << 8) | *ptr) & 0x3FFF;
- X ++ptr;
- X --iolen;
- X }
- X }
- X iolen -= len;
- X if (DDebug)
- X fprintf(stderr, " MPXCMD %ld (%ld bytes)\n", cmd, len);
- X do_reccmd(cmd, ptr, len);
- X ptr += len;
- X }
- X RPak[0] = RPak[1];
- X RPak[1] = RPak[2];
- X RPak[2] = RPak[3];
- X RPak[3] = pkt;
- X pkt->state = EMPTY;
- X ++RPStart;
- X }
- X}
- X
- Xdo_reccmd(cmd, ptr, len)
- Xubyte *ptr;
- X{
- X switch(cmd) {
- X case SCMD_DATA:
- X if (RChan < MAXCHAN && (Chan[RChan].flags & CHANF_ROK))
- X gwrite(Chan[RChan].fd, ptr, len);
- X break;
- X case SCMD_SWITCH:
- X RChan = (ptr[0]<<8)|ptr[1];
- X break;
- X case SCMD_OPEN:
- X {
- X register COPEN *cop = (COPEN *)ptr;
- X CACKCMD ack;
- X uword chan = (cop->chanh << 8) | cop->chanl;
- X
- X ack.chanh = cop->chanh;
- X ack.chanl = cop->chanl;
- X ack.error = 0;
- X
- X if (chan >= MAXCHAN || Chan[chan].state) {
- X ack.error = 33; /* magic */
- X WriteStream(SCMD_ACKCMD, &ack, sizeof(CACKCMD), chan);
- X break;
- X }
- X {
- X int error;
- X int s;
- X uword port = (cop->porth<<8)|cop->portl;
- X
- X if (isinternalport(port)) {
- X error = iconnect(&s, port);
- X } else {
- X struct sockaddr sa;
- X s = socket(PF_UNIX, SOCK_STREAM, 0);
- X if (DDebug)
- X fprintf(stderr, " REC OPEN, CONNECTING ch%d po%d\n",
- X chan, port
- X );
- X sa.sa_family = AF_INET;
- X sprintf(sa.sa_data,".PORT.%ld", port);
- X error = connect(s, &sa, sizeof(sa));
- X if (error < 0) {
- X startserver(port);
- X error = connect(s, &sa, sizeof(sa));
- X }
- X if (DDebug)
- X fprintf(stderr, " CONNECTED err=%ld\n", error);
- X }
- X if (error < 0) {
- X ack.error = 2;
- X } else {
- X extern void do_open();
- X fcntl(s, F_SETFL, FNDELAY);
- X Chan[chan].state = CHAN_OPEN;
- X Chan[chan].flags = CHANF_ROK|CHANF_WOK;
- X Chan[chan].fd = s;
- X Chan[chan].pri= cop->pri;
- X FD_SET(s, &Fdread);
- X FD_SET(s, &Fdexcept);
- X FdChan[s] = chan;
- X Fdstate[s] = do_open;
- X }
- X WriteStream(SCMD_ACKCMD, &ack, sizeof(CACKCMD), -1);
- X }
- X }
- X break;
- X case SCMD_CLOSE: /* receive close */
- X {
- X extern void nop();
- X register CCLOSE *clo = (CCLOSE *)ptr;
- X uword chan = (clo->chanh<<8)|clo->chanl;
- X int fd = Chan[chan].fd;
- X
- X if (DDebug)
- X fprintf(stderr, " SCMD_CLOSE\n");
- X if (chan >= MAXCHAN || Chan[chan].state == CHAN_FREE)
- X break;
- X /*
- X Chan[chan].state = CHAN_CLOSE;
- X Chan[chan].flags |= CHANF_RCLOSE;
- X */
- X Chan[chan].flags &= ~(CHANF_ROK|CHANF_WOK);
- X FD_CLR(fd, &Fdread);
- X FD_CLR(fd, &Fdexcept);
- X Chan[chan].state = CHAN_FREE;
- X Chan[chan].fd = -1;
- X Fdstate[fd] = nop;
- X close(fd);
- X ClearChan(&TxList, chan, 0);
- X
- X if (Chan[chan].flags & CHANF_LCLOSE) {
- X if (DDebug)
- X fprintf(stderr," REMOTE CLOSE %ld, LOCAL ALREADY CLOSED\n",
- X fd
- X );
- X } else {
- X CCLOSE cc;
- X char dummy;
- X cc.chanh = chan >> 8;
- X cc.chanl = chan;
- X WriteStream(SCMD_CLOSE, &cc, sizeof(CCLOSE), chan);
- X /*
- X shutdown(Chan[chan].fd, 2);
- X write(Chan[chan].fd, &dummy, 0);
- X */
- X if (DDebug)
- X fprintf(stderr," REMOTE CLOSE %ld, LOCAL NOT YET CLOSED\n",
- X fd
- X );
- X }
- X }
- X break;
- X case SCMD_ACKCMD: /* acknowledge of my open */
- X {
- X register CACKCMD *cack = (CACKCMD *)ptr;
- X uword chan = (cack->chanh<<8)|cack->chanl;
- X if (chan >= MAXCHAN || Chan[chan].state != CHAN_LOPEN)
- X break;
- X if (DDebug)
- X fprintf(stderr, "ackerr = %ld\n", cack->error);
- X if (cack->error == 33) {
- X uword newchan = alloc_channel();
- X COPEN co;
- X if (newchan < MAXCHAN) {
- X Chan[newchan] = Chan[chan];
- X Chan[chan].state = CHAN_FREE;
- X Chan[chan].fd = -1;
- X co.chanh = newchan >> 8;
- X co.chanl = newchan;
- X co.porth = Chan[chan].port >> 8;
- X co.portl = Chan[chan].port;
- X co.error = 0;
- X co.pri = Chan[chan].pri;
- X WriteStream(SCMD_OPEN, &co, sizeof(COPEN), newchan);
- X break;
- X }
- X }
- X if (cack->error) {
- X extern void nop();
- X ubyte error = cack->error;
- X int fd = Chan[chan].fd;
- X
- X gwrite(fd, &error, 1);
- X Fdstate[fd] = nop;
- X Chan[chan].fd = -1;
- X Chan[chan].state = CHAN_FREE;
- X FD_CLR(fd, &Fdread);
- X FD_CLR(fd, &Fdexcept);
- X close(fd);
- X } else {
- X ubyte error = 0;
- X extern void do_open();
- X gwrite(Chan[chan].fd, &error, 1);
- X Chan[chan].state = CHAN_OPEN;
- X Chan[chan].flags = CHANF_ROK|CHANF_WOK;
- X Fdstate[Chan[chan].fd] = do_open;
- X }
- X }
- X break;
- X case SCMD_EOFCMD: /* EOF on channel */
- X {
- X register CEOFCMD *eof = (CEOFCMD *)ptr;
- X uword chan = (eof->chanh<<8)|eof->chanl;
- X
- X if (chan < MAXCHAN && Chan[chan].state == CHAN_OPEN) {
- X Chan[chan].flags &= ~eof->flags;
- X if (eof->flags & CHANF_ROK) {
- X char dummy;
- X shutdown(Chan[chan].fd, 1);
- X write(Chan[chan].fd, &dummy, 0);
- X }
- X }
- X }
- X break;
- X case SCMD_QUIT:
- X dneterror("QUIT");
- X break;
- X case SCMD_IOCTL:
- X {
- X register CIOCTL *cio = (CIOCTL *)ptr;
- X uword chan = (cio->chanh<<8)|cio->chanl;
- X
- X if (chan < MAXCHAN && Chan[chan].state == CHAN_OPEN) {
- X switch(cio->cmd) {
- X case CIO_SETROWS:
- X isetrows(Chan[chan].fd, (cio->valh<<8)|cio->vall);
- X break;
- X case CIO_SETCOLS:
- X isetcols(Chan[chan].fd, (cio->valh<<8)|cio->vall);
- X break;
- X case CIO_STOP:
- X break;
- X case CIO_START:
- X break;
- X case CIO_FLUSH:
- X ClearChan(&TxList, chan, 0);
- X break;
- X }
- X }
- X }
- X break;
- X default:
- X break;
- X }
- X}
- X
- Xreplywindow(window)
- X{
- X ubyte rwindow = (window - RPStart) & 7;
- X WCBuf[0] = SYNC;
- X
- X if (DDebug) {
- X if (rwindow >= 4 || RPak[rwindow]->state == READY)
- X fprintf(stderr, " ACK WINDOW %ld\n", window);
- X else
- X fprintf(stderr, " NAK WINDOW %ld\n", window);
- X }
- X if (rwindow >= 4 || RPak[rwindow]->state == READY) /* data ready */
- X WCBuf[1] = PKCMD_ACK | (window << 5); /* ack it */
- X else
- X WCBuf[1] = PKCMD_NAK | (window << 5); /* nack it */
- X WCBuf[2] = (SYNC << 1) ^ WCBuf[1];
- X NetWrite(WCBuf, 3, 0);
- X}
- X
- SHAR_EOF
- echo "extracting dnet/TODO3"
- sed 's/^X//' << \SHAR_EOF > dnet/TODO3
- XFrom tlm@newton.physics.purdue.edu Mon Mar 14 13:05:30 1988
- XReceived: by cory (5.57/1.26)
- X id AA00614; Mon, 14 Mar 88 13:00:13 PST
- XReceived: by newton.physics.purdue.edu (5.54/2.1)
- X id AA12775; Mon, 14 Mar 88 15:59:30 EST
- XDate: Mon, 14 Mar 88 15:59:30 EST
- XFrom: tlm@newton.physics.purdue.edu (Timothy Lee Meisenheimer)
- XMessage-Id: <8803142059.AA12775@newton.physics.purdue.edu>
- XApparently-To: dnet@cory.berkeley.edu
- X
- XThanks Matt, but no dice. I still couldn't get it to work in
- Xlocal mode??? What I did do was get the latest version (time
- Xstamp of March 11) and recompiled everything. The host name
- Xproblem is now gone (newton.physics.purdure.edu= --> newton.physics.
- Xpurdue.ed=) but I found that the environment DNETHOST must get
- Xset in the child process when using "dtest" but not in the
- Xparent process. Consequently it was still no go until I set
- Xit by hand. Now I can do the local net just dandy!! I'm playing
- Xaround with how to get the responce .vs. baud right (mucking
- Xaround in control.c). Will let you know what I find out. Bye
- Xthe way does this latest version still have problems with all
- Xthose interupts on the select which was bringing the vaxen to
- Xtheir knees? Guess I'll find out tonight :-).
- X
- X tim.
- X
- X
- SHAR_EOF
- echo "extracting dnet/subs.c"
- sed 's/^X//' << \SHAR_EOF > dnet/subs.c
- X
- X/*
- X * SUBS.C
- X *
- X * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
- X *
- X * Support subroutines
- X *
- X */
- X
- X#include "dnet.h"
- X
- X/*
- X * WRITESTREAM()
- X *
- X * Queues new SCMD_?? level commands to be sent
- X */
- X
- XWriteStream(sdcmd, buf, len, chan)
- Xubyte *buf;
- Xuword chan;
- X{
- X register XIOR *ior = (XIOR *)malloc(sizeof(XIOR));
- X
- X if (DDebug)
- X fprintf(stderr, "**SEND MPX CMD %ld (%ld bytes on channel %ld)\n",
- X sdcmd, len, chan
- X );
- X
- X ior->io_Data = (ubyte *)malloc(len);
- X ior->io_Length = len;
- X ior->io_Actual = 0;
- X ior->io_Command = sdcmd;
- X ior->io_Error = 0;
- X ior->io_Channel = chan;
- X ior->io_Pri = (chan > MAXCHAN) ? 126 : Chan[chan].pri;
- X bcopy(buf, ior->io_Data, len);
- X Enqueue(&TxList, ior);
- X /*
- X * REMOVED 21 SEPT 1988
- X * do_wupdate();
- X */
- X}
- X
- X/*
- X * ALLOC_CHANNEL()
- X *
- X * Allocate a free channel. Used in SCMD_OPEN and SCMD_ACKCMD
- X */
- X
- Xalloc_channel()
- X{
- X static ulong ran = 13;
- X register uword i;
- X
- X ran = ((ran * 13) + 1) ^ (ran >> 9) + time(0);
- X for (i = ran % MAXCHAN; i < MAXCHAN; ++i) {
- X if (Chan[i].state == 0)
- X return(i);
- X }
- X for (i = ran % MAXCHAN; i < MAXCHAN; --i) {
- X if (Chan[i].state == 0)
- X return(i);
- X }
- X return(-1);
- X}
- X
- X/*
- X * Remove all nodes with the given channel ID.
- X */
- X
- XClearChan(list, chan, all)
- XLIST *list;
- Xuword chan;
- X{
- X register XIOR *io, *in;
- X
- X for (io = (XIOR *)list->lh_Head; io != (XIOR *)&list->lh_Tail; io = in) {
- X in = (XIOR *)io->io_Node.ln_Succ;
- X if (io->io_Channel == chan) {
- X if (all || io->io_Command == SCMD_DATA) {
- X io->io_Node.ln_Succ->ln_Pred = io->io_Node.ln_Pred;
- X io->io_Node.ln_Pred->ln_Succ = io->io_Node.ln_Succ;
- X free(io->io_Data);
- X free(io);
- X }
- X }
- X }
- X}
- X
- X/*
- X * Queue a packet into a prioritized list. FIFO is retained for packets
- X * of the same priority. This implements one level of channel priorities,
- X * before the packets actually get queued to the network. Since up to
- X * 4 packets might be queued (200 * 4 = 800 bytes of data or 4 seconds @
- X * 2400 baud), a second level of prioritization will also reduce the
- X * physical packet size when two channels at relatively large differing
- X * priorities are in use.
- X *
- X * These and other list routines compatible with Amiga list routines.
- X */
- X
- XEnqueue(list, ior)
- XLIST *list;
- XXIOR *ior;
- X{
- X register XIOR *io;
- X char pri = ior->io_Pri;
- X
- X io = (XIOR *)list->lh_Head;
- X while (io != (XIOR *)&list->lh_Tail) {
- X if (pri > io->io_Pri)
- X break;
- X io = (XIOR *)io->io_Node.ln_Succ;
- X }
- X ior->io_Node.ln_Succ = (NODE *)io;
- X ior->io_Node.ln_Pred = io->io_Node.ln_Pred;
- X ior->io_Node.ln_Succ->ln_Pred = (NODE *)ior;
- X ior->io_Node.ln_Pred->ln_Succ = (NODE *)ior;
- X}
- X
- XAddTail(list, node)
- XLIST *list;
- XNODE *node;
- X{
- X node->ln_Succ = (NODE *)&list->lh_Tail;
- X node->ln_Pred = list->lh_TailPred;
- X node->ln_Succ->ln_Pred = node;
- X node->ln_Pred->ln_Succ = node;
- X}
- X
- XAddHead(list, node)
- XLIST *list;
- XNODE *node;
- X{
- X node->ln_Succ = list->lh_Head;
- X node->ln_Pred = (NODE *)list;
- X node->ln_Succ->ln_Pred = node;
- X node->ln_Pred->ln_Succ = node;
- X}
- X
- Xubyte *
- XRemHead(list)
- XLIST *list;
- X{
- X NODE *node;
- X
- X node = list->lh_Head;
- X if (node->ln_Succ == NULL)
- X return(NULL);
- X node->ln_Succ->ln_Pred = node->ln_Pred;
- X node->ln_Pred->ln_Succ = node->ln_Succ;
- X return((ubyte *)node);
- X}
- X
- XNewList(list)
- XLIST *list;
- X{
- X list->lh_Head = (NODE *)&list->lh_Tail;
- X list->lh_Tail = NULL;
- X list->lh_TailPred = (NODE *)&list->lh_Head;
- X}
- X
- XGetNext(node)
- XNODE *node;
- X{
- X register NODE *next = node->ln_Succ;
- X if (*(long *)next)
- X return((long)next);
- X return(NULL);
- X}
- X
- X/*
- X * CHKBUF
- X *
- X * Checksum a buffer. Uses a simple, but supposedly very good
- X * scheme.
- X */
- X
- Xchkbuf(buf, bytes)
- Xregister ubyte *buf;
- Xregister uword bytes;
- X{
- X register uword i;
- X register ubyte c1,c2;
- X
- X for (i = c1 = c2 = 0; i < bytes; ++i) {
- X c1 += buf[i];
- X c2 += c1;
- X }
- X c1 = -(c1 + c2);
- X return((c1<<8)|c2);
- X}
- X
- X/*
- X * Write timeout signal handler.
- X */
- X
- Xsigwto()
- X{
- X WTimedout = 1;
- X Wto_act = 0;
- X}
- X
- XTimerOpen()
- X{
- X static struct sigvec SA = { sigwto, 0, 0 };
- X sigvec(SIGALRM, &SA, NULL);
- X}
- X
- XTimerClose()
- X{
- X signal(SIGALRM, SIG_IGN);
- X}
- X
- XWTimeout(us)
- X{
- X static struct itimerval itv;
- X struct itimerval ov;
- X long mask;
- X
- X itv.it_value.tv_sec = us / 1000000;
- X itv.it_value.tv_usec= (us % 1000000);
- X
- X mask = sigblock(sigmask(SIGALRM));
- X setitimer(ITIMER_REAL, &itv, &ov);
- X Wto_act = 1;
- X WTimedout = 0;
- X sigsetmask(mask);
- X if (DDebug)
- X fprintf(stderr, "WTimeout set\n");
- X}
- X
- Xdneterror(str)
- Xchar *str;
- X{
- X register short i;
- X
- X NetClose();
- X TimerClose();
- X exit(1);
- X}
- X
- X/*
- X * setenv(name, str). name must be of the form "NAME="
- X */
- X
- Xsetenv(name, str)
- Xchar *name;
- Xchar *str;
- X{
- X extern char **environ;
- X static char **elist;
- X static int elen;
- X char *ptr;
- X int i, len;
- X
- X len = strlen(name);
- X if (elist == NULL) {
- X for (i = 0; environ[i]; ++i);
- X elist = (char **)malloc((i+3)*sizeof(char *));
- X elen = i + 3;
- X bcopy(environ, elist, i*sizeof(char *));
- X environ = elist;
- X }
- X for (i = 0; elist[i]; ++i) {
- X if (strncmp(elist[i], name, len) == 0)
- X break;
- X }
- X if (i == elen) {
- X elen += 4;
- X elist = environ = (char **)realloc(elist, elen*sizeof(char *));
- X }
- X ptr = (char *)malloc(len + strlen(str) + 1);
- X sprintf(ptr, "%s%s", name, str);
- X if (elist[i]) {
- X elist[i] = ptr;
- X } else {
- X elist[i] = ptr;
- X elist[i+1] = NULL;
- X elen = i + 1;
- X }
- X}
- X
- Xvoid
- Xstartserver(port)
- Xuword port;
- X{
- X char dir[MAXPATHLEN];
- X struct passwd pw_info;
- X FILE *fi;
- X
- X if (!port)
- X return;
- X if (getenv("DNETDIR")) {
- X strcpy(dir, getenv("DNETDIR"));
- X strcat(dir, "dnet.servers");
- X if (fi = fopen(dir, "r")) {
- X if (scan_for_server(fi, port))
- X return;
- X }
- X }
- X pw_info = *getpwuid(getuid());
- X strcpy(dir, pw_info.pw_dir);
- X strcat(dir, "/.dnet/dnet.servers");
- X if (fi = fopen(dir, "r")) {
- X if (scan_for_server(fi, port))
- X return;
- X }
- X /*
- X * LAST TRY
- X */
- X if (fi = fopen(LASTTRYDNETSERVERS, "r")) {
- X if (scan_for_server(fi, port))
- X return;
- X }
- X fprintf(stderr, "Unable to find one of (1) dnet.servers or (2) server\n");
- X fprintf(stderr, "entry for port %d\n", port);
- X fflush(stderr);
- X return;
- X}
- X
- Xscan_for_server(fi, port)
- XFILE *fi;
- Xshort port;
- X{
- X char buf[256];
- X char path[MAXPATHLEN];
- X char cdir[MAXPATHLEN];
- X long portno;
- X short found = 0;
- X void checktilda();
- X
- X while (fgets(buf, 256, fi)) {
- X if (sscanf(buf, "%ld %s %s", &portno, path, cdir) == 3) {
- X checktilda(path);
- X checktilda(cdir);
- X if (portno == port) {
- X if (!fork()) {
- X int i;
- X fclose(fi);
- X setuid(getuid());
- X signal(SIGHUP, SIG_DFL);
- X signal(SIGINT, SIG_DFL);
- X signal(SIGQUIT, SIG_DFL);
- X signal(SIGTERM, SIG_DFL);
- X signal(SIGCHLD, SIG_DFL);
- X signal(SIGTSTP, SIG_IGN);
- X ioctl(open("/dev/tty", 2), TIOCNOTTY, NULL);
- X i = open("/dev/null", O_RDWR, 0);
- X dup2(i, 0);
- X dup2(i, 1);
- X for (i = 3; i < 256; ++i)
- X close(i);
- X sprintf(buf, "server.%ld.%ld", port, getuid());
- X execl(path, buf, cdir, NULL);
- X fprintf(stderr, "Unable to exec server: %s\n", path);
- X fflush(stderr);
- X _exit(1);
- X }
- X sleep(4); /* is a hack */
- X found = 1;
- X break;
- X }
- X }
- X }
- X fclose(fi);
- X return(found);
- X}
- X
- Xvoid
- Xchecktilda(buf)
- Xchar *buf;
- X{
- X if (buf[0] == '~') {
- X short bindex = 1;
- X short pathlen;
- X struct passwd pw_info, *pw;
- X
- X pw_info.pw_dir = getenv("HOME");
- X if (buf[1] && buf[1] != '/') {
- X char username[128];
- X while (buf[bindex] && buf[bindex] != '/')
- X ++bindex;
- X bcopy(buf+1, username, bindex-1);
- X username[bindex-1] = 0;
- X if (pw = getpwnam(username)) {
- X pw_info = *pw;
- X } else {
- X fprintf(stderr, "Unable to find password entry for %s\n",
- X username
- X );
- X fprintf(stderr, "passing /tmp as dir for server");
- X fflush(stderr);
- X pw_info.pw_dir = "/tmp";
- X }
- X }
- X
- X /*
- X * ~[username]<rest of path> -> <basedir><rest of path>
- X */
- X
- X pathlen = strlen(pw_info.pw_dir);
- X bcopy(buf + bindex, buf + pathlen, strlen(buf + bindex) + 1);
- X bcopy(pw_info.pw_dir, buf, pathlen);
- X }
- X fflush(stderr);
- X}
- X
- SHAR_EOF
- echo "End of archive 1 (of 2)"
- # if you want to concatenate archives, remove anything after this line
- exit
-
-
-
-