wswietse@eutrc3.UUCP (Wietse Venema) (04/20/88)
comp.sources.misc: Volume 3, Issue 4 Submitted-By: "Wietse Venema" <wswietse@eutrc3.UUCP> Archive-Name: pcmail/Part3 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 3 (of 8)." # Contents: Installation cmail.c dir.c file.c gphys.c kphys.c # makefile.uts xpres.c # Wrapped by wietse@eutwc1 on Wed Apr 20 16:45:16 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f Installation -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"Installation\" else echo shar: Extracting \"Installation\" \(7515 characters\) sed "s/^X//" >Installation <<'END_OF_Installation' XTHE UNIX SIDE OF THE CONNECTION X XThe pc-mail programs will need a UNIX host to exchange messages Xwith. This automatically gives access to other networks. I sug- Xgest the following strategy: X X - Get a uucp login, say, uuxyz on a UNIX system. This will also Xbecome the uucp-node name of the pc. The file /usr/lib/uucp/L.sys Xshould be extended with an entry, e.g. X X uuxyz Passive X X(on some systems one has to use `Never' instead of `Passive'). It Xmay also be necessary to update the /usr/lib/uucp/USERFILE. X X - Have all mail for user uuxyz forwarded to uuxyz!somebody. On XBSD UNIX systems, this is achieved by placing the address X`uuxyz!somebody' in a file ~uuxyz/.forward; on System-V one Xshould put the text `Forward to uuxyz!somebody' in the file X/usr/mail/uuxyz, which should be read/writeable by group mail. X XIn the above examples, somebody is a name that can be freely Xchosen; it will not be used by the pc. Of course, mail can be Xforwarded to uuxyz!somebody from other accounts as well. X XThe result of all this is that you can send mail to any user on Xthe UNIX host by just specifying her login name; the host name of Xyour pc will not appear in mail headers. People can send mail to Xyou by specifying an address on the UNIX host. There is no need Xto register the pc in the uucp maps. X XIf the above strategy is not what you like, you will have to Xoperate as a "real" uucp node and should #define UUCP_HOST in Xsendwork.c. You should also be registered as a uucp node. There Xis more discussion about this in sendwork.c X XAs a minimum, the UNIX host should support the standard uucp `g' Xprotocol. This protocol was developed for eight-bit data paths. XUnfortunately, modern networks often eat up XON/XOFF and other Xcontrol characters. X XTo handle non-transparent networks I have written a protocol Xcalled `k'. It has been used with the Eindhoven University Sytek Xnetwork for over two years and is part of the pc-mail distribu- Xtion. If you're really desperate (and have UNIX source) build Xthis protocol into the uucico program by adding the following Xline to struct Proto Ptbl[] in cntrl.c: X X 'k', kturnon, krdmsg, kwrmsg, krddata, kwrdata, kturnoff, X Xand linking the uucico objects with kio.c kp.h kphys.c kpres.c Xand ktrans.c. X XTHE PC SIDE OF THE CONNECTION X XTo bring pc-mail up, edit the makefile to reflect the system you Xare using (there are separate makefiles for UNIX and MS-DOS). XThe MS-DOS makefile is for a UNIX-compatible make utility posted Xto usenet near the end of 1986. There is a batch command file X(buidall.bat) for those who do not have a unix-compatible make Xutility. For testing purposes it is convenient to run this stuff Xon a UNIX host. X XSaying `make' should produce five programs: X X - mail, the menu-driven user interface X - cmail, a program that checks if there is new mail X - smail, a program that queues messages for transmission after X doing alias substitution on mail addresses X - cico, the program that performs dialups and file transfers X - rmail, extracts "From" info from mail received by cico X XThe programs access a common data base in the form of a spool Xdirectory with setup file, logfile and message files. There Xshould be no other files in the spool directory, to avoid Xconfusion. You will have to create the spool directory; the Xprograms will not do that. X XYou will have to set some environment variables before running Xthe mail program. X X - MAILDIR, the absolute path to your spool directory X - EDITOR, the name of your favourite editor program X - PATH, in order locate the executables X XThe editor command may be an MS-DOS batch file; in that case you Xshould include the '.bat' suffix in the command name. X XThe following two environment variables are optional. X X - MAILPRN, if printer output should not go to PRN X - MAILCMD, command that is executed when the mail program exits X XAlso, make sure that the limit on the number of open files is Xlarge enough (20 or so). On MS-DOS, this is handled by a line X`files=20' in the CONFIG.SYS file. X XRun the interactive mail program and choose the setup command. On XMS-DOS systems only the com1 port is supported (see file Xcomport.s). Here is my setup (some names changed) for getting Xthrough the TUE port selector: X X communications_port: com1 X baud_rate: 1200 X remote_host_name: eutwc1 X login_name: uutest X dialup_sequence: atm\r OK atdt455215\r CONNECT \0 ease: xyz\r ease: Xxyz\r choice: 1\r called: b076\r CLOSED \r X disconnect_sequence: \0 X XAll entries must be filled or the cico program will complain. XThe MS-DOS version supports the com1 port only. X XThe dial-up sequence requires some explanation. Basically it is a Xlist of words separated by whitespace. The first word is sent to Xthe comm. port. The program will wait until it receives the Xsecond word. And so on. Unlike real uucp (or kermit), there is no Xretry facility. The backslash escape sequences are stolen from Xthe c programming language, with some extensions: X X \b backspace X \f formfeed X \n linefeed X \r carriage return X \s blank X \t tab X \\ backslash X \nnn octal code for a character X XIn order to send or expect an empty string, use the \0 sequence. X XIt is not possible to send null characters. The dial-up sequence Xshould terminate when the UNIX host displays its "login:" prompt; Xthe remainder of the dialup sequence is built into the software. XThis, and having (pc node name) == (uucp login name) are to Xprevent fraud. Thus, assuming a Hayes-compatible modem, your Xdialup sequence could be as simple as: X X atm\r OK atdt455215\r CONNECT \0 X XWhen this dialup sequence succeeds, the program continues with Xits built-in sequence: X X ogin: login_name\r ssword: your_password\r X XThe disconnect sequence uses the same escape sequences as the Xdial-up sequence, but does not use the send/expect protocol. In Xthe above sequence, the disconnect sequence is an empty string. X XIf the cico program has problems communicating with the UNIX host Xyou can run it by hand, for example: X X cico -d 9 -p your_password X Xwhich will produce a lot of debugging output. Setting the Xdebugging level to less than 9 produces less output. Level 4 is Xsufficient to monitor the dial-up and login sequence. X XALIAS DATABASE X XThe user can define aliases for (groups of) mail addresses. The Xformat of the alias data base is simple: it is a text file with Xon each line: X X alias replacement part X XThe replacement part may be one or more words; words are Xseparated by blanks, tabs or commas. Whenever the smail (mail Xspooler) program recognizes an alias, it is replaced by the X`replacement' part. Aliases may be defined in terms of other Xaliases; also the order in which they appear in the alias data Xbase is not important (except when an alias is defined more than Xonce; the program remembers only the last definition of an Xalias). The alias expansion software is smart enough to detect Xinfinite loops and to suppress multiple occurrances of the same Xrecipient. Alias substitution is not case-sensitive. X XBATCH-MODE OPERATION X XThe cmail program can be run from a batch file (say each time the Xpc is turned on), contact the UNIX host, and report if there is Xnew mail. Also, you may want to auto-execute the cmail command Xwhen exiting from the interactive mail shell. See the manual page Xin the cmail.c source. X END_OF_Installation if test 7515 -ne `wc -c <Installation`; then echo shar: \"Installation\" unpacked with wrong size! fi # end of overwriting check fi if test -f cmail.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"cmail.c\" else echo shar: Extracting \"cmail.c\" \(3509 characters\) sed "s/^X//" >cmail.c <<'END_OF_cmail.c' X/*++ X/* NAME X/* cmail 1 X/* SUMMARY X/* report if there are unread messages X/* PROJECT X/* pc-mail X/* PACKAGE X/* cmail X/* SYNOPSIS X/* cmail [-p password] X/* DESCRIPTION X/* cmail reports if there are unread mail messages in the X/* pc-mail spool directory. X/* X/* If the -p option is present, cmail first invokes the cico X/* program to contact the mail server host. X/* X/* Typically cmail is run immediately after system startup, X/* while you are getting your first cup of coffee. X/* X/* The program returns a nonzero exit status if it could not X/* find any mail. X/* COMMANDS X/* cico file transfer program X/* rmail processes new mail X/* FILES X/* Various files in the spool directory X/* X/* LOGFILE system status messages X/* n<seqno> mail messages X/* h<seqno> header line of new mail X/* o<seqno> header line of old mail X/* DIAGNOSTICS X/* Error messages in case the environment is not properly set up. X/* BUGS X/* Invites people to put their mail password into the autoexec file. X/* AUTHOR(S) X/* W.Z. Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Sun Apr 3 19:34:57 MET 1988 X/* LAST MODIFICATION X/* Wed Apr 6 00:18:45 MET 1988 X/* VERSION/RELEASE X/* 1.3 X/*--*/ X X#include <signal.h> X X#include "defs.h" X#include "dir.h" X#include "path.h" X#include "status.h" X Xhidden void parse_args(); /* forward declarations */ Xhidden void usage(); Xhidden void error(); Xhidden int newmail(); X Xhidden char *password = 0; /* set by the -p option */ X Xmain(argc,argv) Xint argc; Xchar **argv; X{ X signal(SIGINT,SIG_IGN); /* disable ctrl-c */ X parse_args(argc,argv); /* parse command args */ X if (pathinit()) /* check path info */ X error("cmail: bad MAILDIR environment variable"); X if (password && *password && X invokelp(CICO,"-p",password,(char *)0) == E_NOPROG) X error("cmail: cannot execute the CICO program"); X if (invokelp(RMAIL,(char *)0) == E_NOPROG) X error("cmail: cannot execute the RMAIL program"); X exit(newmail() == 0); /* look for new mail */ X} X X/* parse_args - process command-line arguments */ X Xhidden void parse_args(argc,argv) Xint argc; Xchar **argv; X{ X while (--argc && *++argv && **argv == '-') { /* process options */ X switch (*++*argv) { X case 'p': /* call cico first */ X if (--argc == 0) X usage("missing password"); X password = *++argv; X break; X default: /* unknown option */ X usage(strcons("invalid option: -%s",*argv)); X break; X } X } X X /* check for extraneous arguments */ X X if (argc > 0) X usage(strcons("unexpected argument: %s",*argv)); X} X X/* scan for new unread mail */ X Xhidden int newmail() X{ X register int dd; X int pfxlen = sizeof(HDRPFX)-1; X char *f; X FILE *fp; X char from[BUFSIZ]; X register int msgcount = 0; X X /* X * Scan the spool directory for unread messages and extract X * the originator address from the corresponding meta file. X */ X X for (dd = opendir(maildir); f = readdir(dd); /* void */) { X int seqno; X if (strncmp(f,HDRPFX,pfxlen) == 0 && sscanf(f+pfxlen,"%d",&seqno)) { X if (fp = fopen(new_meta(seqno),"r")) { X fgets(from,BUFSIZ,fp); X printf("You have new mail from %s",from); X msgcount++; X fclose(fp); X } X } X } X closedir(dd); X return(msgcount); X} X Xhidden void error(str) Xchar *str; X{ X fprintf(stderr,"%s\n",str); X exit(1); X} X Xhidden void usage(str) Xchar *str; X{ X fprintf(stderr,"%s\nusage: cmail [-p password]\n",str); X exit(1); X} END_OF_cmail.c if test 3509 -ne `wc -c <cmail.c`; then echo shar: \"cmail.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f dir.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"dir.c\" else echo shar: Extracting \"dir.c\" \(6998 characters\) sed "s/^X//" >dir.c <<'END_OF_dir.c' X/*++ X/* NAME X/* opendir,readdir,closedir 3 X/* SUMMARY X/* directory search functions X/* PROJECT X/* dos/unix compatibility X/* PACKAGE X/* library routines X/* SYNOPSIS X/* int opendir(path) X/* char *path; X/* X/* char *readdir(id) X/* int dir; X/* X/* closedir(id) X/* int id; X/* DESCRIPTION X/* This package provides a system-independent interface to the file system X/* that allows a program to simultaneously scan one or more directories. X/* X/* The MS-DOS version accepts both forward and backward slash as X/* field delimiter in path names. X/* X/* opendir() accepts a valid path and returns an id which should be used X/* in subsequent calls of readdir()....closedir(). X/* X/* readdir() returns a pointer to a character string with the next file in X/* the directory associated with id, or a null pointer. X/* X/* closedir() terminates the directory search and deallocates X/* memory used to keep track of `certain important data'. X/* FUNCTIONS AND MACROS X/* myalloc() X/* DIAGNOSTICS X/* opendir() returns -1 if all slots are in use. X/* Specifying a wrong id is considered a fatal error condition. X/* Memory allocation errors cause the program to terminate. X/* BUGS X/* readdir() returns a pointer to memory X/* whose contents is overwritten with each call. X/* X/* Despite whatthe names suggest, these functions are not compatible X/* with the BSD directory access routines. X/* X/* Does not work with unix file systems that have variable-length X/* directory entries (BSD). X/* AUTHOR(S) X/* Wietse Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Mon Nov 17 19:38:19 GMT+1:00 1986 X/* LAST MODIFICATION X/* Mon Apr 4 23:38:43 MET 1988 X/* VERSION/RELEASE X/* 1.3 X/*--*/ X X#include "defs.h" X#include "dir.h" X X#ifdef unix X# include <sys/types.h> X# include <sys/dir.h> X#endif X X#ifdef MSDOS X# include <dos.h> X# include <ctype.h> X Xhidden void badslot(); /* forward declarations */ Xhidden void lowcpy(); X X/* X* The Disk Transfer Area as used by MS-DOS when it finds a file name X* during a wild-card scan. X*/ X X#define MAXNAME 13 /* max size of MS-DOS file name + null byte */ X Xtypedef struct Dta { X char reserved[21]; /* start of dta buffer */ X char found; /* attribute found */ X short time; /* file's time */ X short date; /* file's date */ X int losize; /* low order file size */ X int hisize; /* high-order file size */ X char name[MAXNAME]; /* name of file terminated by zero byte */ X} Dta; X X/* macros for easy access to registers with MS-DOS system calls */ X X#define AH regs.h.ah /* ah register */ X#define BX regs.x.bx /* bx register */ X#define CX regs.x.cx /* cx register */ X#define DX regs.x.dx /* dx register */ X#define CF regs.x.cflag /* cflag register */ X#define INT intdos(®s,®s) /* dos system call */ X#define WORD (unsigned) /* cast */ X X#define SET_DTA(d) { AH = 0x1a; DX = WORD d; INT; } X#define GET_DTA(d) { AH = 0x2f; INT; d = BX; } X#define GET_1ST(f,n) { AH = 0x4e; CX = 0x10; DX = WORD n; INT; f = CF; } X#define GET_NXT(f) { AH = 0x4f; CX = 0x10; INT; f = CF; } X X/* information about directory accesses is kept in a table with initially */ X/* empty slots */ X X#define MAXSLOT 20 /* nbr of directories that can be processed */ X Xtypedef struct Slot { X unsigned int dsave; /* temp storage for disk transfer address */ X unsigned int cstat; /* MS-DOS system call return status */ X Dta dta; /* disk transfer area */ X} Slot; X Xhidden Slot *dirslots[20]; /* slots with pointers */ X X#endif /* MSDOS */ X X/* opendir - set up for directory search */ X X#ifdef MSDOS X Xpublic int opendir(name) Xchar *name; X{ X register int id; X register Slot *q; X char buf[BUFSIZ]; X union REGS regs; /* cpu registers in system call */ X char lch; X X for (id = 0; id < MAXSLOT && dirslots[id]; id++) X ; /* search first free slot */ X if (id < MAXSLOT) { /* found a free slot */ X dirslots[id] = q = (Slot *) myalloc(sizeof(Slot)); X GET_DTA(q->dsave); /* save dta address */ X SET_DTA(&q->dta); /* set to current dta */ X strcpy(buf,name); /* construct search path */ X if (*name && index("\\/:",name[strlen(name)-1]) == 0) X strcat(buf,"/"); X strcat(buf,"*.*"); /* append wildest possible file name */ X GET_1ST(q->cstat,buf); /* start search (read one name ahead) */ X SET_DTA(q->dsave); /* restore dta address */ X return(id); /* return offset in slots table */ X } else { X return(-1); /* no free slot available */ X } X} X X#endif /* MSDOS */ X X/* readdir - return next file in directory or null string */ X X#ifdef unix X Xpublic char *readdir(id) Xint id; X{ X static struct direct ent[2]; X X for (;;) { X if (read(id,(char *) ent,sizeof(*ent)) != sizeof(*ent)) X return(0); X if (ent[0].d_ino != 0) X return(ent[0].d_name); X } X} X X#endif /* unix */ X X#ifdef MSDOS X Xpublic char *readdir(id) Xint id; X{ X register Slot *q; X union REGS regs; X static char buf[MAXNAME]; X X if (id < 0 || id >= MAXSLOT || (q = dirslots[id]) == 0) { X badslot("readdir",id); /* serves you well! */ X /* NOTREACHED */ X } else if (q->cstat) { X return(0); /* no name found */ X } else { X lowcpy(buf,q->dta.name); /* keep name (lower case) */ X GET_DTA(q->dsave); /* save dta address */ X SET_DTA(&q->dta); /* setup to search */ X GET_NXT(q->cstat); /* for the next entry */ X SET_DTA(q->dsave); /* in the directory */ X return buf; /* return name */ X } X} X X#endif /* MSDOS */ X X/* closedir - release directory access slot */ X X#ifdef MSDOS X Xpublic int closedir(id) Xint id; X{ X register Slot **p; X X if (id < 0 || id >= MAXSLOT || *(p = dirslots+id) == 0) { X badslot("closedir",id); X /* NOTREACHED */ X } else { X free((char *)*p); /* deallocate slot */ X *p = 0; /* mark as unused */ X return(0); X } X} X X#endif /* MSDOS */ X X#ifdef MSDOS X X/* badslot - the program is obviously corrupted. stop it. */ X Xhidden void badslot(name,id) Xchar *name; Xint id; X{ X fatal("%s: bad slot: %d\n",name,id); X} X X/* lowcpy - copy string and map to lower case */ X Xhidden void lowcpy(out,in) Xchar *out; Xchar *in; X{ X register char *d = out; X register char c; X register char *s = in; X X while (c = *s++) X *d++ = isupper(c) ? tolower(c) : c; X *d = '\0'; X} X X#endif /* MSDOS */ END_OF_dir.c if test 6998 -ne `wc -c <dir.c`; then echo shar: \"dir.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f file.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"file.c\" else echo shar: Extracting \"file.c\" \(6599 characters\) sed "s/^X//" >file.c <<'END_OF_file.c' X/*++ X/* NAME X/* file 3 X/* SUMMARY X/* manipulate ordinary files X/* PROJECT X/* pc-mail X/* PACKAGE X/* mailsh X/* SYNOPSIS X/* int file() X/* X/* int junk_file() X/* DESCRIPTION X/* file() is called when the user selected the "file" option X/* in the main menu. The pager displays a directory listing on the X/* screen. The user may then walk through the file display and X/* select a file or directory. X/* X/* In case a regular file is selected the user may specify X/* an action (send file as mail, delete file, display X/* file, print file, copy file to workfile for subsequent X/* editing etc.). X/* X/* junk_file() should be invoked when the file display is no longer X/* valid. X/* FILES X/* By selecting directory files the user can walk through the whole X/* file system. X/* SEE ALSO X/* kbdinp(3), pager(3) X/* BUGS X/* On some MS-DOS systems, we never get the ".." entry. X/* This is an unsolved problem. X/* X/* Changing the current directory may cause problems if X/* the MAILDIR and EDITOR environment variables hold X/* relative path names. X/* X/* No provision to change default drive on MS-DOS systems. X/* AUTHOR(S) X/* W.Z. Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Sun Apr 5 17:18:06 GMT+1:00 1987 X/* LAST MODIFICATION X/* Mon Apr 4 23:40:13 MET 1988 X/* VERSION/RELEASE X/* 1.3 X/*--*/ X X#include <time.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <ctype.h> X#include "defs.h" X#include "screen.h" X#include "pager.h" X#include "mailsh.h" X#include "dir.h" X#include "path.h" X#include "status.h" X#include "window.h" X Xextern struct tm *localtime(); /* std C library */ X Xhidden File *bldlist(); /* forward declaration */ Xhidden int show_list(); Xhidden int pick_file(); Xhidden int delfile(); Xhidden int show_file(); Xhidden int rmfile(); X Xhidden File *dfile = 0; /* file listing */ Xhidden File *dirfile = 0; /* directory listing */ X X/* file - called from keyboard interpreter, call keyboard driver */ X Xpublic int file() X{ X static Screen screen[] = { X 'C', "Close", 0, initscreen, X 'P', "Print", print, "Print file listing", X 'S', "Save", save, "Save file listing to ordinary file", X PGUP, PgUp, pu_pager,pageup, X PGDN, PgDn, pd_pager,pagedn, X UP, "Up", up_pager,csrup, X DOWN, "Down", dn_pager,csrdn, X ENTER, "Enter", pick_file,"Display file at cursor", X 0, 0, show_list, X "To display a file, select it with cursor keys, then press ENTER", X }; X X kbdinp(screen); /* set up dialogue */ X close_pager(dirfile); /* deallocate pager file */ X dirfile = 0; /* say it's gone */ X return(S_REDRAW); /* force screen update */ X} X X/* show_list - create or refresh file listing */ X Xhidden int show_list() X{ X if (dirfile == 0) { /* no pager file? */ X patience(); X dirfile = bldlist(); /* create one */ X } else { X set_pager(dirfile); /* select existing pager file */ X } X ds_pager(); /* display the thing */ X return(0); /* say screen is up-to-date */ X} X X/* bldlist - build file listing display */ X Xhidden File *bldlist() X{ X register int dd = opendir(THISDIR); /* start directory search */ X register File *pp = open_pager(); /* allocate pager file */ X register char *f; /* file name pointer */ X X while (f = readdir(dd)) { /* read next file name */ X struct stat s; X if (stat(f,&s) == 0) { /* get file info (size, date) */ X app_pager(pp,strcons("%-20s %9ld %s",f, X s.st_size,tstamp(&s.st_mtime))); X } else { X app_pager(pp,f); X } X } X sort_pager(pp,FORW_SORT); /* sort by file name */ X closedir(dd); /* directory search done */ X return(pp); /* current pager file */ X} X X/* pick_file - display selected file or change directory */ X Xhidden int pick_file() X{ X static char botline[80]; X static Screen screen[] = { X 'C', "Close", 0, "Return to file listing", X 'D', "Delete", delfile,"Delete this file", X 'M', "Mail", mailfile,"Mail a copy of this file", X 'P', "Print", print, "Print this file", X 'S', "Save", save, "Save a copy to an ordinary file", X 'W', "Work", makework,"Save a copy to a work file", X PGUP, PgUp, pu_pager,pageup, X PGDN, PgDn, pd_pager,pagedn, X UP, "Up", up_pager,csrup, X DOWN, "Down", dn_pager,csrdn, X 0, 0, show_file, X botline, X }; X struct stat s; X X if (scan_pager(dirfile,"%s",message) == 0) { /* cannot read name */ X beep(); /* "notify" user */ X return(0); /* nothing happened */ X } else if (access(message,04) || stat(message,&s)) {/* cannot read file */ X beep(); /* "notify" user */ X return(0); /* nothing happened */ X } else if ((s.st_mode&S_IFMT) == S_IFDIR) { /* directory file */ X chdir(message); /* change directory */ X close_pager(dirfile); /* purge display */ X dirfile = bldlist(); /* new file display */ X return(S_REDRAW); /* update display */ X } else { /* ordinary file */ X sprintf(botline,"(Reading file \"%s\")",message); X kbdinp(screen); /* look at screen */ X close_pager(dfile); /* and forget it */ X dfile = 0; /* say it's gone */ X return(S_REDRAW); /* force redrawing */ X } X} X X/* show_file - create or refresh display of selected file */ X Xhidden int show_file() X{ X if (dfile) { X set_pager(dfile); /* select dispay */ X } else { X if (rd_pager(dfile = open_pager(),message)) /* try to read file */ X mesg_pager(dfile,m_msgread); /* read error */ X } X ds_pager(); /* rewrite screen */ X return(0); /* screen up-to-date */ X} X X/* delfile - ask confirmation before removing a file */ X Xhidden int delfile() X{ X static Screen screen[] = { X ESCCR, 0, rmfile,int_error, X 0, 0, 0, X "Press ESC to cancel. Confirm with ENTER", X }; X X return(kbdinp(screen)|S_REDRAW); /* "are you sure?" */ X} X X/* rmfile - actually remove file */ X Xhidden int rmfile() X{ X if (unlink(message)) { /* try to remove file */ X errdisp(E_UNLINK); /* notify the user */ X return(S_BREAK|S_REDRAW); /* redisplay, stop caller */ X } else { X junk_file(); /* say file display outdated */ X return(S_BREAK); /* terminate caller */ X } X} X X/* junk_file - directory listing is no longer up to date */ X Xpublic int junk_file() X{ X if (dirfile) { X close_pager(dirfile); /* close pager file */ X dirfile = 0; /* say it is gone */ X } X return(0); /* in case we need that */ X} END_OF_file.c if test 6599 -ne `wc -c <file.c`; then echo shar: \"file.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f gphys.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"gphys.c\" else echo shar: Extracting \"gphys.c\" \(6855 characters\) sed "s/^X//" >gphys.c <<'END_OF_gphys.c' X/*++ X/* NAME X/* gphys 3 X/* SUMMARY X/* g protocol packet input/output X/* PROJECT X/* pc-mail X/* PACKAGE X/* cico X/* SYNOPSIS X/* #include "gp.h" X/* X/* void gsctrl(fd,c) X/* int fd,c; X/* X/* void gsdata(fd,pk,c) X/* int fd,c; X/* Packet *pk; X/* X/* int grpack(fd,pk) X/* int fd; X/* Packet *pk; X/* DESCRIPTION X/* The functions in this module send and receive packets. Interfacing X/* is based on Packet structures. Messages are interpreted elsewhere. X/* X/* gsctrl() sends a control packet to the remote receiver (no data X/* segment). X/* X/* gsdata() sends a data packet to the remote receiver. X/* The Packet structure is completed with a 16-bit checksum. X/* This function expects read/write sequence information in X/* the c parameter. X/* X/* grpack() receives a packet from the remote transmitter and checks X/* its integrity. It fills in the k, c, len and check fields of the X/* Packet structure and returns the type of message (DATA, SHORT, X/* CLOSE, RJ, RR, etcetera). X/* DIAGNOSTICS X/* grpack() returns FAIL if a corrupted packet was received, and X/* TIME if no packet was received within the time-out interval. X/* BUGS X/* No data re-reading in case of transmission errors. X/* Some parts of the code rely on 8-bit bytes, 16-bit short integers. X/* AUTHOR(S) X/* W.Z. Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Sun Apr 19 11:39:27 GMT+1:00 1987 X/* LAST MODIFICATION X/* Mon Apr 4 23:41:15 MET 1988 X/* VERSION/RELEASE X/* 1.3 X/*--*/ X X#include <signal.h> X#include <setjmp.h> X#include "gp.h" X X/* local and forward declarations */ X Xstatic jmp_buf timebuf; Xstatic int chksum(),readhead(),readdata(),clkint(); X X#define READ(fd,cp,n) { if (read(fd,cp,n) != n) clkint(); } X X/* X* "A six byte framing envelope is constructed using the control" X* "byte C of a packet and five other bytes as depicted below." X* <DLE><k><c0><c1><C><x> X* "The <DLE> symbol denotes the ASCII ctrl/P character. If the" X* "envelope is to be followed by a data segment, <k> has the" X* "value log2(size)-4; i.e. 1 <= k < 8. If k is 9, then the" X* "envelope represents a control packet. The <c0> and <c1>" X* "bytes are the low-order and high-order bytes respectively of" X* "0xAAA minus a 16-bit checksum. For control packets, this" X* "16-bit checksum is the same as the control byte C. For data" X* "packets, the checksum is calculated by the program below." X* "The <x> byte is the exclusive-or of <k><c0><c1><C>. Error" X* "control is accomplished by checking a received framing" X* "envelope for compliance with the definition, and comparing a" X* "checksum function of the data segment with <c0><c1>." X*/ X X/* gsctrl - send control packet (no data segment) */ X Xvoid gsctrl(fd,c) Xint fd,c; X{ X char header[6]; X register char chkhdr; X register char *cp = header; X int cksm = MAGIC-c; /* do checksum */ X X *cp++ = CTRL('P'); /* start of header */ X chkhdr = *cp++ = KCTRL; /* k byte (control) */ X chkhdr ^= *cp++ = cksm; /* c0 byte (checksum lsb) */ X chkhdr ^= *cp++ = cksm>>8; /* c1 byte (checksum msb) */ X chkhdr ^= *cp++ = c; /* message|sequence info */ X *cp = chkhdr; /* header checksum */ X X write(fd,header,sizeof(header)); /* send header */ X DEBUG(9,"xmt: %o\n",c&0377); /* show header */ X} X X/* gsdata - send data packet */ X Xvoid gsdata(fd,pk,c) Xint fd,c; Xregister Packet *pk; X{ X char header[6]; X register char chkhdr; X register char *cp = header; X int cval = pk->c|(c&077); /* fold in sequence info */ X X pk->chk = MAGIC-(chksum(pk->data,pk->len)^(0377&cval)); X X *cp++ = CTRL('P'); /* start of header */ X chkhdr = *cp++ = pk->k; /* k byte (message length) */ X chkhdr ^= *cp++ = pk->chk; /* c0 byte (checksum lsb) */ X chkhdr ^= *cp++ = pk->chk>>8; /* c1 byte (checksum msb) */ X chkhdr ^= *cp++ = cval; /* data|sequence info */ X *cp = chkhdr; /* header checksum */ X X write(fd,header,sizeof(header)); /* send header */ X DEBUG(9,"xmt: %o\n",cval&0377); /* show header */ X X write(fd,pk->data,pk->len); /* send data segment */ X DEBUG(9,"xmt: data %d bytes\n",pk->segl); /* show data */ X} X X/* grpack - receive one data or control packet; return packet type info */ X Xint grpack(fd,pk) Xint fd; Xregister Packet *pk; X{ X if (setjmp(timebuf)) /* in case we time out */ X return(TIME); /* it just happened */ X signal(SIGALRM,clkint); /* alarm clock response */ X alarm(ALARM); /* set alarm clock */ X X if (readhead(fd,pk)) { /* read packet header */ X DEBUG(7,"rcv: bad header\n",""); X alarm(0); /* turn timer off */ X return(FAIL); /* header checksum error */ X } else if (pk->k == KCTRL) { X alarm(0); /* turn timer off */ X return(MESG(pk->c)); /* CLOSE | RJ | RR etcetera */ X } else if (readdata(fd,pk)) { X DEBUG(7,"rcv: bad data\n",""); X alarm(0); /* turn timer off */ X return(FAIL); /* data checksum error */ X } else { X alarm(0); /* turn timer off */ X return(TYPE(pk->c)); /* DATA | SHORT */ X } X} X X/* readhead - read header and check header checksum */ X Xstatic int readhead(fd,pk) Xint fd; Xregister Packet *pk; X{ X char header[5]; X int ok; X register char chkhdr; X register char *cp = header; X X do { /* start reading */ X READ(fd,cp,1); /* skip all garbage */ X } while (*cp != CTRL('P')); /* up to packet header */ X X READ(fd,header,sizeof(header)); /* read packet header */ X X chkhdr = pk->k = *cp++; /* data length or control */ X chkhdr ^= pk->chk = *cp++&0377; /* data checksum lsb */ X chkhdr ^= *cp; X pk->chk |= (*cp++&0377)<<8; /* data checksum msb */ X chkhdr ^= pk->c = *cp++; /* control packet or data */ X if (ok = (chkhdr == *cp)) X DEBUG(9,"rcv: %o\n",pk->c&0377); X return(!ok); /* check the checksum */ X} X X/* readdata - read data segment and check data checksum */ X Xstatic int readdata(fd,pk) Xint fd; Xregister Packet *pk; X{ X if (seglen[pk->k] > pk->len) { X DEBUG(7,"rcv: data %d bytes too big\n",seglen[pk->k]); X return(1); X } else { X register int i; X DEBUG(9,"rcv: data %d bytes\n",pk->len = seglen[pk->k]); X for (i = 0; i < pk->len; i++) { X READ(fd,&pk->data[i],1); X } X return(pk->chk+(chksum(pk->data,pk->len)^(pk->c&0377)) != MAGIC); X } X} X X/* clkint - tiny time-out routine */ X Xstatic int clkint() X{ X DEBUG(9,"rcv: timed out\n",""); X longjmp(timebuf,1); X /* NOTREACHED */ X} X X/* chksum - unix packet driver checksum algorithm */ X Xstatic int chksum(s,n) Xregister char *s; Xregister n; X{ X register short sum; X register unsigned short t; X register short x; X X sum = -1; X x = 0; X do { X if (sum < 0) { X sum <<= 1; X sum++; X } else X sum <<= 1; X t = sum; X sum += (unsigned)*s++ & 0377; X x += sum ^ n; X if ((unsigned short)sum <= t) { X sum ^= x; X } X } while (--n > 0); X X return(sum); X} END_OF_gphys.c if test 6855 -ne `wc -c <gphys.c`; then echo shar: \"gphys.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f kphys.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"kphys.c\" else echo shar: Extracting \"kphys.c\" \(7524 characters\) sed "s/^X//" >kphys.c <<'END_OF_kphys.c' X/*++ X/* NAME X/* kphys 3 X/* SUMMARY X/* k protocol packet exchange X/* PACKAGE X/* uucp across the TUEnet X/* SYNOPSIS X/* #include "kp.h" X/* X/* kspack(fd,type,num,size,data) X/* int fd, num, size; X/* char type, data[MAXPACKSIZ]; X/* X/* krpack(fd,num,size,data) X/* int fd, *num, *size; X/* char data[MAXPACKSIZ]; X/* DESCRIPTION X/* The functions in this file take care of data framing and verification. X/* X/* Kspack() sends a packet of the specified type and number, X/* and with len data bytes. X/* X/* Krpack() tries to receive a packet and returns: the packet type plus X/* size and data, or TIME (no packet) or FAIL (bad checksum). X/* X/* The data format has been derived from kermit implementations: X/* X/* .nf X/* .in +5 X/* SOH packet header, ASCII control-P X/* len (size of data, low 6 bits) + 32 X/* len (size of data, high 6 bits) + 32 X/* num (packet number mod 64) + 32 X/* type packet type X/* check one-byte type-1 kermit checksum X/* X/* The header is followed by checksummed data if len >0: X/* X/* .nf X/* .in +5 X/* data len data bytes X/* check1 (upper 2 bits of type-3 kermit 16-bit checksum) + 32 X/* check2 (middle 6 bits of type-3 kermit 16-bit checksum) + 32 X/* check3 (lower 6 bits of type-3 kermit 16-bit checksum) + 32 X/* X/* Every packet is followed by an ASCII carriage return, which is X/* ignored upon reception of a packet. It prevents timeout errors X/* when one byte gets lost (the most common case). X/* BUGS X/* It is yet another convention for data framing. X/* AUTHOR(S) X/* Wietse Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Mon Feb 3 13:38:14 MET 1986 X/* LAST MODIFICATION X/* Mon Apr 4 23:43:13 MET 1988 X/* VERSION/RELEASE X/* 1.5 X/*--*/ X X#include <signal.h> X#include <setjmp.h> X#include "kp.h" X X#define READS(fd,ch) {if (read(fd,&ch,1) < 0) clkint(); if ((ch &= 0177) == SOH) goto SYNC;} X Xjmp_buf env; /* Environment ptr for timeout longjump */ X Xclkint() /* Timer interrupt handler */ X{ X longjmp(env,TRUE); /* Tell krpack to give up */ X} X Xkspack(fd,type,num,len,data) Xint fd; Xchar type, *data; Xint num, len; X{ X char chksum, header[6], chk[3]; /* Checksums, header */ X X DEBUG(7,"xmt: type %c\n",type); X if (len > 0) X DEBUG(7,"xmt: data %d\n",len); X X header[0] = SOH; /* Packet marker (SOH) */ X header[1] = tosix(len); /* Send the character count */ X chksum = header[1]; /* Initialize the checksum */ X header[2] = tosix(len>>OUT); /* Send the character count */ X chksum += header[2]; /* Update checksum */ X header[3] = tochar(num); /* Packet number */ X chksum += header[3]; /* Update checksum */ X header[4] = type; /* Packet type */ X chksum += header[4]; /* Update checksum */ X chksum = (((chksum&0300) >> 6)+chksum)&077; /* Compute header checksum */ X header[5] = tochar(chksum); /* Put it in the packet */ X write(fd,header,6); /* Send the header */ X X if (len > 0) { /* Make data packet */ X write(fd,data,len); /* Send data */ X chk3(data,len,chk); /* Compute 16-bit checksum */ X write(fd,chk,3); /* Send checksum */ X } X write(fd,"\r",1); /* Extra-packet line terminator */ X} X Xkrpack(fd,num,len,data) Xint fd; Xint *num; /* Packet number */ Xint *len; /* Packet length */ Xchar *data; /* Packet data */ X{ X int i; /* Data character number, loop exit */ X char t, /* Current input character */ X type, /* Packet type */ X rchk[3], /* Data checksum from host */ X cchk[3], /* Data checksum computed here */ X cchksum, /* Our (computed) checksum */ X rchksum; /* Header checksum from other host */ X X if (setjmp(env)) { X DEBUG(7,"rcv: timed out\n",""); X return TIME; /* Timed out */ X } X signal(SIGALRM,clkint); /* Setup the timeout */ X alarm(TIMEOUT); X X for (;;) /* Wait for packet header */ X READS(fd,t); XSYNC: /* Got SOH */ X alarm(TIMEOUT); X DEBUG(7,"rcv: found sync\n",""); X READS(fd,t); /* Get character */ X cchksum = t; /* Start the checksum */ X *len = unchar(t); /* Character count, low six bits */ X X READS(fd,t); /* Get character */ X cchksum += t; /* Update checksum */ X *len += (unchar(t)<<OUT); /* Character count, high six bits */ X X READS(fd,t); /* Get character */ X cchksum += t; /* Update checksum */ X *num = unchar(t); /* Packet number */ X X READS(fd,t); /* Get character */ X cchksum += t; /* Update checksum */ X type = t; /* Packet type */ X X READS(fd,t); /* Get header checksum */ X rchksum = unchar(t); /* Convert to numeric */ X /* Fold in bits 7,8 to compute */ X cchksum = (((cchksum&0300) >> 6)+cchksum)&077; /* header checksum */ X X if (cchksum != rchksum) { X DEBUG(7,"rcv: bad header\n",""); X alarm(0); /* Disable the timer interrupt */ X return FAIL; X } X DEBUG(7,"rcv: type %c\n",type); X X if ((*len > 0) && (data != NULLP)) X { X for (i=0; i<*len; i++) /* The data itself, if any */ X { /* Loop for character count */ X READS(fd,t); /* Get character */ X data[i] = t; /* Keep data */ X } X X for (i=0; i<3; i++) /* 16-bit CRC checksum */ X { X READS(fd,t); /* Get character */ X rchk[i] = t; /* Keep data */ X } X X chk3(data,*len,cchk); /* Compute CRC */ X if (strncmp(rchk,cchk,3)) { /* Check with received CRC */ X DEBUG(7,"rcv: bad data\n",""); X alarm(0); /* Disable the timer interrupt */ X return FAIL; X } X DEBUG(7,"rcv: data %d\n",*len); X } X alarm(0); /* Disable the timer interrupt */ X return(type); /* All OK, return packet type */ X} X X/* C H K 3 -- Compute a type-3 Kermit block check. */ X/* XCalculate the 16-bit CRC of a string using a byte-oriented Xtableless algorithm invented by Andy Lowry (Columbia University). The Xmagic number 010201 is derived from the CRC-CCITT polynomial x^16+x^12+x^5+1. X*/ Xstatic chk3(s,len,chk) Xchar *s, *chk; Xint len; X{ X unsigned int c, q; X long crc = 0; X X while (len--) { X c = *s++; X q = (crc ^ c) & 017; /* Low-order nibble */ X crc = (crc >> 4) ^ (q * 010201); X q = (crc ^ (c >> 4)) & 017; /* High order nibble */ X crc = (crc >> 4) ^ (q * 010201); X } X *chk++ = tochar(((unsigned)(crc & 0170000)) >> 12); X *chk++ = tochar((crc & 07700) >> 6); X *chk++ = tochar(crc & 077); X} END_OF_kphys.c if test 7524 -ne `wc -c <kphys.c`; then echo shar: \"kphys.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f makefile.uts -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"makefile.uts\" else echo shar: Extracting \"makefile.uts\" \(6491 characters\) sed "s/^X//" >makefile.uts <<'END_OF_makefile.uts' X# c compiler flags X# -DSIII for AT&T unix System-III or System-V X# for V7, BSD XCFLAGS = -DSIII -g X X# library options X# -lcurses for AT&T unix X# -ltermcap for V7, BSD XLIBS = -lcurses X X# lint options X# -ML for Microport XLINTFL = -Ml X XRETRIEVE= retrieve -d .arch X XSOURCES = README ascf.c ascf.h call.c cico.c cmail.c comm.c comm.h \ X connect.c defs.h desk.c deskutil.c dir.c \ X dir.h email.c errdisp.c file.c getwork.c gp.h \ X gphys.c gpres.c gtrans.c invoke.c kbdinp.c kio.c kp.h \ X kphys.c kpres.c ktrans.c logs.c logs.h mailfile.c \ X mailsh.c makework.c mbox.c myalloc.c \ X newseqno.c pager.c pager.h params.c params.h path.c path.h \ X protomsg.c rmail.c rmtname.c scanwork.c screen.c screen.h \ X sendwork.c setup.c smail.c spoolfil.c startup.c \ X status.h switcher.c sysdep.h window.c window.h \ X work.h xpres.c comport.s str.c alias.c edit.c submit.c \ X unalias.c hsearch.c hsearch.h clmap.h comport.h hsearch.3 \ X buildall.bat kproto.ms Watchit makefile.uts makefile.msc \ X mailsh.h srctoman.sh Installation Implementation termcap X XSHSRC = mailsh.c call.c desk.c file.c screen.c mbox.c kbdinp.c \ X pager.c window.c setup.c errdisp.c invoke.c path.c myalloc.c \ X dir.c params.c newseqno.c email.c spoolfil.c ascf.c \ X makework.c mailfile.c deskutil.c str.c alias.c edit.c submit.c X XSHOBJ = mailsh.o call.o desk.o file.o screen.o mbox.o kbdinp.o \ X pager.o window.o setup.o errdisp.o invoke.o path.o myalloc.o \ X dir.o params.o newseqno.o email.o spoolfil.o ascf.o \ X makework.o mailfile.o deskutil.o str.o alias.o edit.o submit.o X XSMSRC = smail.c path.c dir.c newseqno.c ascf.c spoolfil.c str.c \ X unalias.c hsearch.c XSMOBJ = smail.o path.o dir.o newseqno.o ascf.o spoolfil.o str.o \ X unalias.o hsearch.o X XRMSRC = rmail.c path.c dir.c str.c XRMOBJ = rmail.o path.o dir.o str.o X XCMSRC = cmail.c path.c dir.c invoke.c str.c XCMOBJ = cmail.o path.o dir.o invoke.o str.o X XCISRC = dir.c comm.c connect.c getwork.c kphys.c kpres.c ktrans.c logs.c \ X cico.c myalloc.c newseqno.c params.c path.c protomsg.c rmtname.c \ X scanwork.c sendwork.c startup.c switcher.c xpres.c \ X gpres.c gtrans.c gphys.c str.c X XCIOBJ = dir.o comm.o connect.o getwork.o kphys.o kpres.o ktrans.o logs.o \ X cico.o myalloc.o newseqno.o params.o path.o protomsg.o rmtname.o \ X scanwork.o sendwork.o startup.o switcher.o xpres.o \ X gpres.o gtrans.o gphys.o str.o X Xall: mail smail rmail cico cmail X X$(SOURCES): X $(RETRIEVE) $(SOURCES) X Xmail: $(SHOBJ) X cc $(CFLAGS) -o mail $(SHOBJ) $(LIBS) X Xsmail: $(SMOBJ) X cc $(CFLAGS) -o smail $(SMOBJ) X Xrmail: $(RMOBJ) X cc $(CFLAGS) -o rmail $(RMOBJ) X Xcmail: $(CMOBJ) X cc $(CFLAGS) -o cmail $(CMOBJ) X Xcico: $(CIOBJ) X cc $(CFLAGS) -o cico $(CIOBJ) X Xmlint: X lint $(LINTFL) $(CFLAGS) $(SHSRC) X Xrlint: X lint $(LINTFL) $(CFLAGS) $(RMSRC) X Xslint: X lint $(LINTFL) $(CFLAGS) $(SMSRC) X Xclint: X lint $(LINTFL) $(CFLAGS) $(CISRC) X Xtar: $(SOURCES) X tar cv $(SOURCES) X Xshar: $(SOURCES) X find $(SOURCES) -print | makekit X Xdepend: X @grep '^# *include *"' *.c|sed 's/c:# *include *"\([^"]*\)".*/o: \1/g' X Xalias.o: defs.h Xalias.o: path.h Xalias.o: pager.h Xalias.o: mailsh.h Xalias.o: screen.h Xalias.o: status.h Xascf.o: defs.h Xascf.o: ascf.h Xcall.o: defs.h Xcall.o: path.h Xcall.o: screen.h Xcall.o: pager.h Xcall.o: mailsh.h Xcico.o: defs.h Xcico.o: logs.h Xcico.o: params.h Xcico.o: comm.h Xcico.o: status.h Xcico.o: path.h Xcmail.o: defs.h Xcmail.o: dir.h Xcmail.o: path.h Xcmail.o: status.h Xcomm.o: defs.h Xcomm.o: params.h Xcomm.o: comm.h Xconnect.o: defs.h Xconnect.o: params.h Xconnect.o: status.h Xconnect.o: comm.h Xconnect.o: logs.h Xconnect.o: sysdep.h Xdesk.o: defs.h Xdesk.o: mailsh.h Xdesk.o: path.h Xdesk.o: dir.h Xdesk.o: pager.h Xdesk.o: screen.h Xdesk.o: status.h Xdesk.o: window.h Xdeskutil.o: defs.h Xdeskutil.o: pager.h Xdeskutil.o: mailsh.h Xdeskutil.o: screen.h Xdeskutil.o: status.h Xdir.o: defs.h Xdir.o: dir.h Xedit.o: defs.h Xedit.o: path.h Xedit.o: mailsh.h Xedit.o: status.h Xemail.o: defs.h Xemail.o: path.h Xemail.o: dir.h Xemail.o: pager.h Xemail.o: screen.h Xemail.o: mailsh.h Xemail.o: status.h Xerrdisp.o: defs.h Xerrdisp.o: screen.h Xerrdisp.o: pager.h Xerrdisp.o: status.h Xerrdisp.o: window.h Xfile.o: defs.h Xfile.o: screen.h Xfile.o: pager.h Xfile.o: mailsh.h Xfile.o: dir.h Xfile.o: path.h Xfile.o: status.h Xfile.o: window.h Xgetwork.o: defs.h Xgetwork.o: logs.h Xgetwork.o: status.h Xgetwork.o: work.h Xgetwork.o: params.h Xgetwork.o: comm.h Xgphys.o: gp.h Xgpres.o: gp.h Xgtrans.o: gp.h Xhsearch.o: hsearch.h Xinvoke.o: defs.h Xinvoke.o: status.h Xkbdinp.o: defs.h Xkbdinp.o: mailsh.h Xkbdinp.o: screen.h Xkbdinp.o: window.h Xkphys.o: kp.h Xkpres.o: kp.h Xktrans.o: kp.h Xlogs.o: defs.h Xlogs.o: logs.h Xlogs.o: path.h Xlogs.o: status.h Xmailfile.o: defs.h Xmailfile.o: path.h Xmailfile.o: screen.h Xmailfile.o: mailsh.h Xmailsh.o: defs.h Xmailsh.o: path.h Xmailsh.o: status.h Xmailsh.o: mailsh.h Xmailsh.o: window.h Xmakework.o: defs.h Xmakework.o: path.h Xmakework.o: screen.h Xmakework.o: mailsh.h Xmbox.o: defs.h Xmbox.o: path.h Xmbox.o: pager.h Xmbox.o: screen.h Xmbox.o: mailsh.h Xmyalloc.o: defs.h Xnewseqno.o: defs.h Xnewseqno.o: path.h Xnewseqno.o: dir.h Xpager.o: defs.h Xpager.o: window.h Xpager.o: pager.h Xpager.o: path.h Xpager.o: ascf.h Xparams.o: defs.h Xparams.o: path.h Xparams.o: params.h Xpath.o: defs.h Xpath.o: path.h Xpath.o: status.h Xprotomsg.o: defs.h Xprotomsg.o: params.h Xprotomsg.o: comm.h Xprotomsg.o: logs.h Xprotomsg.o: status.h Xrmail.o: defs.h Xrmail.o: dir.h Xrmail.o: path.h Xrmail.o: status.h Xrmtname.o: defs.h Xrmtname.o: params.h Xrmtname.o: comm.h Xrmtname.o: logs.h Xrmtname.o: status.h Xrmtname.o: path.h Xscanwork.o: defs.h Xscanwork.o: params.h Xscanwork.o: comm.h Xscanwork.o: work.h Xscanwork.o: path.h Xscanwork.o: dir.h Xscanwork.o: logs.h Xscreen.o: defs.h Xscreen.o: screen.h Xsendwork.o: defs.h Xsendwork.o: work.h Xsendwork.o: logs.h Xsendwork.o: status.h Xsendwork.o: params.h Xsendwork.o: comm.h Xsetup.o: defs.h Xsetup.o: path.h Xsetup.o: screen.h Xsetup.o: mailsh.h Xsetup.o: pager.h Xsetup.o: params.h Xsetup.o: status.h Xsetup.o: window.h Xsmail.o: defs.h Xsmail.o: path.h Xsmail.o: status.h Xspoolfil.o: defs.h Xspoolfil.o: path.h Xspoolfil.o: ascf.h Xspoolfil.o: status.h Xstartup.o: defs.h Xstartup.o: params.h Xstartup.o: comm.h Xstartup.o: logs.h Xstartup.o: status.h Xstartup.o: sysdep.h Xstr.o: defs.h Xsubmit.o: defs.h Xsubmit.o: path.h Xswitcher.o: defs.h Xswitcher.o: work.h Xswitcher.o: params.h Xswitcher.o: comm.h Xswitcher.o: logs.h Xswitcher.o: status.h Xunalias.o: defs.h Xunalias.o: hsearch.h Xunalias.o: path.h Xunalias.o: ascf.h Xwindow.o: defs.h Xwindow.o: window.h Xxpres.o: defs.h Xxpres.o: params.h Xxpres.o: comm.h Xxpres.o: status.h Xxpres.o: sysdep.h Xxpres.o: logs.h END_OF_makefile.uts if test 6491 -ne `wc -c <makefile.uts`; then echo shar: \"makefile.uts\" unpacked with wrong size! fi # end of overwriting check fi if test -f xpres.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"xpres.c\" else echo shar: Extracting \"xpres.c\" \(6821 characters\) sed "s/^X//" >xpres.c <<'END_OF_xpres.c' X/*++ X/* NAME X/* xpres 3 X/* SUMMARY X/* communications port i/o X/* PROJECT X/* pc-mail X/* PACKAGE X/* cico X/* SYNOPSIS X/* xopen() X/* X/* xclose() X/* X/* xread(dummy,buf,len) X/* int dummy,len; X/* char *buf; X/* X/* xwrite(dummy,buf,len) X/* int dummy,len; X/* char *buf; X/* X/* xioctl(flag) X/* int flag; X/* DESCRIPTION X/* The functions in this module perform functions analogous X/* to unix system calls, for the serial port of IBM-PC workalikes. X/* X/* xopen() initializes a serial port. Also needed under UNIX. X/* X/* xclose() closes a port. X/* X/* xread(), xwrite() do not use their first argument. Under UNIX X/* one should use the standard read() and write() system calls. X/* X/* xioctl() enables xon/xoff flow control if its argument X/* is nonzero. Not used under UNIX. X/* SEE ALSO X/* comport.asm, IBM-PC comm routines by Tim Pozar X/* DIAGNOSTICS X/* The read functions returns EOF in case of timeout; the write X/* function never detects any failure. X/* BUGS X/* The xioctl() function is utterly primitive. X/* AUTHOR(S) X/* MS-DOS parts derived from uuslave software (John Gilmore) X/* published on usenet early 1987. Bugs fixed & severely hacked by X/* X/* W.Z. Venema X/* Eindhoven University of Technology X/* Department of Mathematics and Computer Science X/* Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands X/* CREATION DATE X/* Sat Mar 28 23:01:43 GMT+1:00 1987 X/* LAST MODIFICATION X/* Mon Apr 4 23:51:55 MET 1988 X/* VERSION/RELEASE X/* 1.3 X/*--*/ X X#include "defs.h" X#include "params.h" X#include "comm.h" /* baud rates, tty ports,... */ X#include "status.h" X#include "sysdep.h" /* other system dependencies */ X#include "logs.h" X X#ifdef unix X# include <sgtty.h> X# include <signal.h> X# include <setjmp.h> X#endif X X#ifdef MSDOS X# define B(x) (115200/(x)) X static int sigint(); X static void get_time(); X#endif X Xtypedef struct { /* baud-rate lookup table */ X char *name; X int code; X} Baud_table; X XBaud_table btable[] = { X#ifdef unix X "50", B50, X "75", B75, X "110", B110, X "134", B134, X "150", B150, X "300", B300, X "600", B600, X "1200", B1200, X "1800", B1800, X "2400", B2400, X "4800", B4800, X "9600", B9600, X#endif X#ifdef MSDOS X "50", B(50), X "75", B(75), X "110", B(110), X "134", B(134), X "150", B(150), X "300", B(300), X "600", B(600), X "1200", B(1200), X "1800", B(1800), X "2400", B(2400), X "4800", B(4800), X "9600", B(9600), X#endif X 0, 0, X}; X X/* xopen - open communications port; parameters taken from setup table */ X Xxopen() X{ X register Baud_table *bp; X#ifdef unix X struct sgttyb ttmode; X#endif X X for (bp = btable; bp->name; bp++) /* look up baud rate */ X if (strcmp(bp->name,COMM_RATE) == 0) X break; X if (bp->name == 0) { /* bad baud rate in setup */ X debug(4)("Invalid baud rate %s\n",COMM_RATE); X exit(E_BADSETUP); X } X X#ifdef unix X if ((ttfd = open(COMM_LINE,2)) < 0) { /* try to access port */ X debug(4)("Cannot access %s\n",COMM_LINE); X exit(E_BADSETUP); X } X#ifndef SIII X if (ioctl(ttfd,TIOCEXCL)) /* exclusive access */ X exit(E_BADSETUP); /* not a terminal */ X#endif X ioctl(ttfd,TIOCHPCL); /* hangup when done */ X gtty(ttfd,&ttmode); /* get port status */ X ttmode.sg_ispeed = ttmode.sg_ospeed = bp->code;/* set baud rate */ X ttmode.sg_flags |= (RAW); /* raw mode */ X#ifdef SIII X ttmode.sg_flags &= ~ECHO; X#else X ttmode.sg_flags &= ~(ECHO|TANDEM|CBREAK); /* no echo, crlf, flow ctrl */ X#endif X stty(ttfd,&ttmode); X#endif X X#ifdef MSDOS X set_tty(bp->code); /* set baud rate, DTR */ X init_comm(); /* turn interrupts on */ X signal(SIGINT,sigint); /* must reset tty */ X inp_flush(); /* flush garbage */ X sleep(3); X#endif X} X X/* xclose - release the communications port */ X Xxclose() X{ X#ifdef unix X close(ttfd); X#endif X X#ifdef MSDOS X uninit_comm(); X#endif X} X X/* xread - read from the serial port */ X X#ifdef MSDOS X Xxread(fd,buf,cnt) Xint fd; Xchar *buf; Xregister int cnt; X{ X register char *p = buf; X register int c; X X while (cnt > 0 && (c = xgetc()) != EOF) { X *p++ = c; X cnt--; X } X return(p-buf ? p-buf : -1); X} X#endif /* MSDOS xwrite() */ X X/* xgetc - read one character from serial port */ X X#ifdef unix Xjmp_buf xbuf; X Xstatic timeout() /* aux function for xgetc */ X{ X longjmp(xbuf,1); X} X Xxgetc() /* return next char */ X{ X char ch; X X if (setjmp(xbuf)) /* in case we time out */ X return(EOF); /* we just did */ X signal(SIGALRM,timeout); /* set timer response */ X alarm(BYTE_TIMEOUT); /* set timer */ X X read(ttfd,&ch,1); /* go wait for character */ X alarm(0); /* turn timer off */ X return(ch&0377); /* successfull termination */ X} X#endif /* unix xgetc() */ X X#ifdef MSDOS X Xxgetc() X{ X char data; X X int i; X unsigned s; X TIME n; X X i = 0; X get_time(&n); X s = n.sec; X X /* X * Implement timeouts by staring at the clock while we wait. X * When the second hand moves, bump our counter. This is a lot X * easier than figuring out the time when we'd time out (in hours, X * minutes, and seconds!) and comparing against that, which is X * what people tend to do in Unix where the time is just an integer X * number of seconds. X */ X while (i < BYTE_TIMEOUT) { X while (s == n.sec) { X if(inp_cnt() != 0) { X data = inp_char(); X return (data & 0xFF); X } X get_time (&n); X } X s = n.sec; X ++i; X } X return(EOF); X} X X/* xwrite - write buffer to serial port */ X Xxwrite(fd,buf,ctr) Xint fd; Xregister char *buf; Xint ctr; X{ X register int i = ctr; X X while (i-- > 0) X outp_char(*buf++); X return ctr; X} X X/* X* Routines specific to MS-DOS X* X* xioctl() enable xon/xoff X* get_timer() read current time X* sigint() clean up interrupt handler and exit X* sleep() unix lookalike X*/ X X/* xioctl - enable xon/xoff protocol */ X Xxioctl(flag) Xint flag; X{ X set_xoff(flag); /* Enable (flag != 0) or disable flow control */ X} X X/* sigint - restore terminal settings on dialout line */ X Xstatic int sigint() X{ X uninit_comm(); X reset_tty(); X exit(0); X} X X/* get_time - read time with dos call */ X Xstatic void get_time(n) XTIME_PTR n; X{ X union REGS inregs; X union REGS outregs; X X inregs.h.ah = 0x2c; /* Please make a #define for this, Tim */ X X int86(0x21, &inregs, &outregs);/* Please #define the 0x21 too */ X X n->hour = outregs.h.ch; X n->minute = outregs.h.cl; X n->sec = outregs.h.dh; X n->hsec = outregs.h.dl; X} X X#define get_sec(n) (get_time(&n),n.sec) X Xsleep(x) Xint x; X{ X TIME n; /* current time record */ X unsigned s = get_sec(n); X X while (x-- > 0) { X while (s == get_sec(n)) X /* void */ ; X s = n.sec; X } X} X X#endif /* MSDOS */ END_OF_xpres.c if test 6821 -ne `wc -c <xpres.c`; then echo shar: \"xpres.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 3 \(of 8\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 5 6 7 8 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 8 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- uucp: mcvax!eutrc3!wswietse | Eindhoven University of Technology bitnet: wswietse@heithe5 | Dept. of Mathematics and Computer Science surf: tuerc5::wswietse | Eindhoven, The Netherlands.