josh@hi.uucp (Josh Siegel ) (04/16/87)
Contain below is my network library which I have been developing over the last few weeks because I got tired of doing the same thing over and over again... It does: 1) Basic networking (IP/TCP) 2) pty's 3) IO control 4) Other misc functions... This is the FIRST release and so the edges have not been worked off. Please, send any comments or bug reports to me. Also, this uses sockets so that it does not work on System V. Sorry... It also does not make use of XDR. This means that transfering data from machine to machine is still ugly. If only BSD4.3 had XDR.... Have fun with it... lets see some network games! --- Josh Siegel (siegel@hc.dspo.gov) (505) 277-2497 (Home) I'm a mathematician, not a programmer! --- # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. -----cut here-----cut here-----cut here-----cut here----- #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # network # This archive created: Wed Apr 15 22:15:16 1987 echo shar: creating directory network mkdir network cd network echo shar: extracting README '(922 characters)' sed 's/^XX//' << \SHAR_EOF > README XX--- XX Copyright 1987, Josh Siegel XX All rights reserved. XX XX Josh Siegel (siegel@hc.dspo.gov) XX Dept of Electrical and Computer Engineering, XX University of New Mexico, XX Albuquerque , New Mexico XX--- XX XXThis directory contains the first release of my network XXroutines. XX XXOne of the problems with it is that I really don't have a XXreal manual for it so users are going to have to use my XXexamples to figure out how it works. There is a "man" page XXfor the library but it is not very helpful. Hopefully I XXmade the examples clear and consise so that they do the XXtrick for now. I plan to change this in the future. XX XXIf you make any changes, please mark the changes clearly XXso that I don't get blaimed for the mistakes down the XXline. Also, mail me the changes so that I can incorporate XXthem into the master copy. XX XXAlso, I am not responsible for any loss of time or damage XXdue to this software (I had to say it). XX XX --Josh Siegel SHAR_EOF if test 922 -ne "`wc -c README`" then echo shar: error transmitting README '(should have been 922 characters)' fi echo shar: extracting basic.c '(4772 characters)' sed 's/^XX//' << \SHAR_EOF > basic.c XX#ifndef lint XXstatic char *RCSid = "$Header: basic.c,v 1.1 87/04/15 21:28:59 josh Exp $"; XX#endif XX XX/* XX *------------------------------------------------------------------ XX * Copyright 1987, Josh Siegel XX * All rights reserved. XX * XX * Josh Siegel (siegel@hc.dspo.gov) XX * Dept of Electrical and Computer Engineering, XX * University of New Mexico, XX * Albuquerque , New Mexico XX * (505) 277-2497 XX * XX *------------------------------------------------------------------ XX * XX * $Source: /usr/pcb/josh/other/network/RCS/basic.c,v $ XX * $Revision: 1.1 $ XX * $Date: 87/04/15 21:28:59 $ XX * $State: Exp $ XX * $Author: josh $ XX * $Locker: josh $ XX * XX *------------------------------------------------------------------ XX * XX * $Log: basic.c,v $ XX * Revision 1.1 87/04/15 21:28:59 josh XX * Initial revision XX * XX * XX *------------------------------------------------------------------ XX */ XX XX XXextern char *user_errlist[]; XXextern int errno; XX XX#include "net.h" XX XXpkill(fd) XXint fd; XX{ XX shutdown(fd,2); XX if(close(fd)<0) XX return(-1); XX} XX XXchar *useport(port) XXint port; XX{ XX static char buff[8]; XX XX sprintf(buff,"#%d",port); XX XX return(buff); XX} XX XX/* Myport: I wrote this so that if 100 students are using the routines, XX they have a way of avoiding using the same socket address. XX This uses getuid() to figure out what to choose as a XX port. XX XX Problems: Could this be done cleaner ? XX*/ XX XXchar *myport() XX{ XX static char buff[8]; /* Its static! Don't try to free it */ XX XX sprintf(buff,"#%d",MYPORT+getuid()); XX XX return(buff); XX} XX XX/* XXattach: XX This is used to establish a port to which other processes XX can connect. It is very standard code except for the XX useport() and myport() hacks. XX XX*/ XX XXattach(s) XX char s[]; XX{ XX int f,*p; XX struct sockaddr_in sin; XX struct servent *sp; XX char buff[255]; XX XX bzero((char *) &sin,sizeof(sin)); XX XX /* Is this something passed to us from useport and myport? */ XX XX if(s[0]=='#') { XX sin.sin_port = htons(atoi(s+1)); XX } else { XX sp = getservbyname(s, "tcp"); XX if (sp == NULL) { XX user_errlist[0]="service unknown"; XX errno=255; XX return(-1); XX } XX sin.sin_port = sp->s_port; XX } XX XX f = socket(AF_INET, SOCK_STREAM, 0); XX if (bind(f, (struct sockaddr *) & sin, sizeof(sin)) < 0) { XX return(-1); XX } XX listen(f, 5); XX return (f); XX} XX XX XX/* XXAnswer: Excepts connection requests from clients. XX XXProblem: I could make it make note of where the connection came XX from but I never felt I had a need XX XX*/ XX XXanswer(s) XX int s; XX{ XX int tmp; XX struct sockaddr_in from; XX int len = sizeof(from); XX XX bzero((char *) & from,len); XX XX tmp = accept(s, &from, &len); XX return (tmp); XX} XX/* XXPhone: Connects to a established port setup by accept(). Again, XX very clean code except for the useport() and myport() XX hacks. XX XXThings to do: XX I could try to make this function call a interupt handler XX when connected so that it does not block for 30 or 40 seconds XX if the machine is down or something */ XX XXphone(service, host) XX char service[], host[]; XX{ XX XX struct sockaddr_in sin; XX struct servent *sp; XX struct hostent *hp; XX int s,*p; XX char buff[255]; XX XX bzero((char *) &sin, sizeof(sin)); XX XX if(service[0]!='#') { XX sp = getservbyname(service, "tcp"); XX if (sp == NULL) { XX user_errlist[0]="service unknown"; XX errno=255; XX return(-1); XX } XX sin.sin_port = sp->s_port; XX } else { XX /* Lets try to figure out something better... Ok? */ XX XX sin.sin_port = htons(atoi(service+1)); XX } XX XX hp = gethostbyname(host); XX if(hp==NULL) { XX errno=65; XX return(-1); XX } XX bcopy(hp->h_addr, (char *) &sin.sin_addr, hp->h_length); XX sin.sin_family = hp->h_addrtype; XX s = socket(AF_INET, SOCK_STREAM, 0); XX if (s < 0) XX return(-1); XX XX if (connect(s, &sin, sizeof(sin)) < 0) XX return(-1); XX XX XX return (s); XX} XX XX/* Give them users the ability to choose what they wish to block! */ XX XXaddfd(x) XXint x; XX{ XX naddfd(netblk.nmask,x); XX} XXdelfd(x) XXint x; XX{ XX ndelfd(netblk.nmask,x); XX} XXinitfd() XX{ XX netblk.nmask[0]=0; XX netblk.nmask[1]=0; XX} XX XX/* XXblock: Blocks until their is something in the Que waiting XX to be read in. Remembers old stuff and goes in a XX round robin mannor of handling stuff on sockets. XX This means that if the user reads from a socket XX that I have not returned but will it a little XX while, this program will be lying! In general, XX the use of isignal() can over come many if not XX all of these problems. Infact, block might not XX even be needed anymore. I sure never use it. XX*/ XX XXblock() XX{ XX static long flags[2] ; XX static int first=1; XX int n; XX XX XX if(first) { XX flags[0]=0; XX flags[1]=0; XX first=0; XX } XX XX if (!flags[0] || !flags[1]) { XX flags[0] = netblk.nmask[0]; XX flags[1] = netblk.nmask[1]; XX select(64, flags, 0, 0, 0); XX } XX for (n = 0; n < 64; n++) XX if (nisset(flags,n)) { XX naddfd(flags,n); XX return (n); XX } XX return (-1); XX XX} SHAR_EOF if test 4772 -ne "`wc -c basic.c`" then echo shar: error transmitting basic.c '(should have been 4772 characters)' fi echo shar: extracting ident.c '(1251 characters)' sed 's/^XX//' << \SHAR_EOF > ident.c XX#ifndef lint XXstatic char *RCSid = "$Header: ident.c,v 1.1 87/04/15 21:29:14 josh Exp $"; XX#endif XX XX/* XX *------------------------------------------------------------------ XX * Copyright 1987, Josh Siegel XX * All rights reserved. XX * XX * Josh Siegel (siegel@hc.dspo.gov) XX * Dept of Electrical and Computer Engineering, XX * University of New Mexico, XX * Albuquerque , New Mexico XX * (505) 277-2497 XX * XX *------------------------------------------------------------------ XX * XX * $Source: /usr/pcb/josh/other/network/RCS/ident.c,v $ XX * $Revision: 1.1 $ XX * $Date: 87/04/15 21:29:14 $ XX * $State: Exp $ XX * $Author: josh $ XX * $Locker: josh $ XX * XX *------------------------------------------------------------------ XX * XX * $Log: ident.c,v $ XX * Revision 1.1 87/04/15 21:29:14 josh XX * Initial revision XX * XX * XX *------------------------------------------------------------------ XX */ XX XX XX#include <pwd.h> XX XX/* XXwhoami: Returns a string of who the caller is in the XX form name@machine where machine is in the XX form returned by gethostname. XX XX*/ XXchar *hostname() XX{ XX static char buff[255]; XX XX gethostname(buff,255); XX XX return(buff); XX} XX XXchar *whoami() XX{ XX static char buff[64]; XX struct passwd *pass; XX XX pass=getpwent(); XX XX sprintf(buff,"%s@%s",pass->pw_name,hostname()); XX XX return(buff); XX} SHAR_EOF if test 1251 -ne "`wc -c ident.c`" then echo shar: error transmitting ident.c '(should have been 1251 characters)' fi echo shar: extracting isignal.c '(1627 characters)' sed 's/^XX//' << \SHAR_EOF > isignal.c XX#ifndef lint XXstatic char *RCSid = "$Header: isignal.c,v 1.1 87/04/15 21:29:17 josh Exp $"; XX#endif XX XX/* XX *------------------------------------------------------------------ XX * Copyright 1987, Josh Siegel XX * All rights reserved. XX * XX * Josh Siegel (siegel@hc.dspo.gov) XX * Dept of Electrical and Computer Engineering, XX * University of New Mexico, XX * Albuquerque , New Mexico XX * (505) 277-2497 XX * XX *------------------------------------------------------------------ XX * XX * $Source: /usr/pcb/josh/other/network/RCS/isignal.c,v $ XX * $Revision: 1.1 $ XX * $Date: 87/04/15 21:29:17 $ XX * $State: Exp $ XX * $Author: josh $ XX * $Locker: josh $ XX * XX *------------------------------------------------------------------ XX * XX * $Log: isignal.c,v $ XX * Revision 1.1 87/04/15 21:29:17 josh XX * Initial revision XX * XX * XX *------------------------------------------------------------------ XX */ XX XX XX#include "net.h" XX XX/* XX * Here we go... the IOSIG handler. If this is called, we assume we got a XX * IOSIG signal and something is coming down one of the pipes. Only testing XX * will prove if it is otherwise XX */ XX XXiosighand() XX{ XX XX static int flags[2]; XX int n; XX XX flags[0] = netblk.imask[0]; XX flags[1] = netblk.imask[1]; XX XX select(64, flags, 0, 0, 0); XX XX for (n = 0; n < 64; n++) XX if (nisset(flags,n)) XX (netblk.protab[n]) (n); XX} XX XXisignal(x, proc) XX int x; XX int (*proc) (); XX{ XX if (proc) { XX XX naddfd(netblk.imask, x); XX XX fcntl(x, F_SETFL, FASYNC); XX XX#ifndef SIGIO XX#define SIGIO SIGPOLL XX#endif NSIG XX XX signal(SIGIO, iosighand); XX XX netblk.protab[x] = proc; XX XX } else { XX ndelfd(netblk.imask, x); XX fcntl(x, F_SETFL, 0); XX } XX} SHAR_EOF if test 1627 -ne "`wc -c isignal.c`" then echo shar: error transmitting isignal.c '(should have been 1627 characters)' fi echo shar: extracting openpty.c '(2166 characters)' sed 's/^XX//' << \SHAR_EOF > openpty.c XX#ifndef lint XXstatic char *RCSid = "$Header: openpty.c,v 1.1 87/04/15 21:29:20 josh Exp $"; XX#endif XX XX/* XX *------------------------------------------------------------------ XX * Copyright 1987, Josh Siegel XX * All rights reserved. XX * XX * Josh Siegel (siegel@hc.dspo.gov) XX * Dept of Electrical and Computer Engineering, XX * University of New Mexico, XX * Albuquerque , New Mexico XX * (505) 277-2497 XX * XX *------------------------------------------------------------------ XX * XX * $Source: /usr/pcb/josh/other/network/RCS/openpty.c,v $ XX * $Revision: 1.1 $ XX * $Date: 87/04/15 21:29:20 $ XX * $State: Exp $ XX * $Author: josh $ XX * $Locker: josh $ XX * XX *------------------------------------------------------------------ XX * XX * $Log: openpty.c,v $ XX * Revision 1.1 87/04/15 21:29:20 josh XX * Initial revision XX * XX * XX *------------------------------------------------------------------ XX */ XX XX XX#include "netw.h" XX#include "openpty.h" XX#include <sys/ioctl.h> XX XX_loadtty(cond) XXTCOND *cond; XX{ XX ioctl(0, TIOCGETP, (char *) &cond->sgttyb); XX ioctl(0, TIOCGETC, (char *) &cond->tchars); XX ioctl(0, TIOCGLTC, (char *) &cond->ltchars); XX ioctl(0, TIOCGETD, (char *) &cond->l); XX ioctl(0, TIOCLGET, (char *) &cond->lb); XX} XX XXsettty(cond) XXTCOND cond; XX{ XX ioctl(0, TIOCSETP, (char *) &cond.sgttyb); XX ioctl(0, TIOCSETC, (char *) &cond.tchars); XX ioctl(0, TIOCSLTC, (char *) &cond.ltchars); XX ioctl(0, TIOCSETD, (char *) &cond.l); XX ioctl(0, TIOCLSET, (char *) &cond.lb); XX} XX XX/* XXopenpty: XX executes a function with a pty between the two sides. XX It works very much like popen() except the process XX is on a completly seperate tty. The returned XX file discripter works exactly like a two way XX socket XX*/ XX XXopenpty(cond,task) XXTCOND cond; XX int (*task) (); XX{ XX XX struct ptydesc proc; XX int t; XX XX if (_openpty(&proc) == -1) XX return (-1); XX XX XX if (fork()) { XX close(proc.pt_tfd); XX return (proc.pt_pfd); XX } XX XX t = open("/dev/tty", 2); XX XX if (t >= 0) { XX ioctl(t, TIOCNOTTY, 0); XX close(t); XX } XX dup2(proc.pt_tfd, 0); XX dup2(proc.pt_tfd, 1); XX dup2(proc.pt_tfd, 2); XX XX for (t = 3; t < 64; t++) XX (void) close(t); XX XX settty(cond); XX XX (task) (); XX exit(0); XX} SHAR_EOF if test 2166 -ne "`wc -c openpty.c`" then echo shar: error transmitting openpty.c '(should have been 2166 characters)' fi echo shar: extracting perror.c '(1076 characters)' sed 's/^XX//' << \SHAR_EOF > perror.c XX#ifndef lint XXstatic char *RCSid = "$Header: perror.c,v 1.1 87/04/15 21:29:26 josh Exp $"; XX#endif XX XX/* XX *------------------------------------------------------------------ XX * Copyright 1987, Josh Siegel XX * All rights reserved. XX * XX * Josh Siegel (siegel@hc.dspo.gov) XX * Dept of Electrical and Computer Engineering, XX * University of New Mexico, XX * Albuquerque , New Mexico XX * (505) 277-2497 XX * XX *------------------------------------------------------------------ XX * XX * $Source: /usr/pcb/josh/other/network/RCS/perror.c,v $ XX * $Revision: 1.1 $ XX * $Date: 87/04/15 21:29:26 $ XX * $State: Exp $ XX * $Author: josh $ XX * $Locker: josh $ XX * XX *------------------------------------------------------------------ XX * XX * $Log: perror.c,v $ XX * Revision 1.1 87/04/15 21:29:26 josh XX * Initial revision XX * XX * XX *------------------------------------------------------------------ XX */ XX XXextern char *sys_errlist[]; XX XXchar *user_errlist[255]; XX XXextern int errno; XX XXperror(s) XXchar *s; XX{ XX if(errno<255) XX printf("%s: %s\n",s,sys_errlist[errno]); XX else XX printf("%s: %s\n",s,user_errlist[errno-255]); XX} SHAR_EOF if test 1076 -ne "`wc -c perror.c`" then echo shar: error transmitting perror.c '(should have been 1076 characters)' fi echo shar: extracting net.h '(750 characters)' sed 's/^XX//' << \SHAR_EOF > net.h XX/* XX * $Header: net.h,v 1.1 87/04/15 21:29:42 josh Exp $ XX * XX * $Log: net.h,v $ XX * Revision 1.1 87/04/15 21:29:42 josh XX * Initial revision XX * XX */ XX XX XX#include <sys/types.h> XX#include <sys/socket.h> XX#include <netinet/in.h> XX#include <netdb.h> XX#include <stdio.h> XX#include <signal.h> XX#include <fcntl.h> XX XXstruct { XX int imask[2],nmask[2]; XX /* imask: mask of pipes that are interupt handled */ XX /* nmask: mask of pipes handled by the user */ XX XX int (*protab[64])(); XX /* protab: The table of processes that handle pipes */ XX XX } _netblk; XX XX#define netblk _netblk XX XX#define MYPORT 3000 XX XX XX#define naddfd(x,y) (x[y>>5] |= (1<< (y>31 ? y-32 : y))) XX#define ndelfd(x,y) (x[y>>5] &= ~(1<< (y>31 ? y-32 : y))) XX#define nisset(x,y) (x[y>>5] & (1<< (y>31 ? y-32 : y))) SHAR_EOF if test 750 -ne "`wc -c net.h`" then echo shar: error transmitting net.h '(should have been 750 characters)' fi echo shar: extracting netw.h '(517 characters)' sed 's/^XX//' << \SHAR_EOF > netw.h XX/* XX * $Header: netw.h,v 1.1 87/04/15 21:29:45 josh Exp $ XX * XX * $Log: netw.h,v $ XX * Revision 1.1 87/04/15 21:29:45 josh XX * Initial revision XX * XX */ XX XX XX#include <sys/ioctl.h> XX XXtypedef struct { XX struct sgttyb sgttyb; XX struct tchars tchars; XX struct ltchars ltchars; XX int l, lb; XX } TCOND; XX XX#define loadtty(x) _loadtty(&x) XX XX#define stty(x,y,z) _stty(&x,y,z) XX XX#define COOKED 0 XX#define BAUD 1 XX XX#ifndef FALSE XX#define FALSE 0 XX#endif FALSE XX XX#ifndef TRUE XX#define TRUE 1 XX#endif TRUE SHAR_EOF if test 517 -ne "`wc -c netw.h`" then echo shar: error transmitting netw.h '(should have been 517 characters)' fi echo shar: extracting tty.c '(1627 characters)' sed 's/^XX//' << \SHAR_EOF > tty.c XX#ifndef lint XXstatic char *RCSid = "$Header: tty.c,v 1.1 87/04/15 21:29:36 josh Exp $"; XX#endif XX XX/* XX *------------------------------------------------------------------ XX * Copyright 1987, Josh Siegel XX * All rights reserved. XX * XX * Josh Siegel (siegel@hc.dspo.gov) XX * Dept of Electrical and Computer Engineering, XX * University of New Mexico, XX * Albuquerque , New Mexico XX * (505) 277-2497 XX * XX *------------------------------------------------------------------ XX * XX * $Source: /usr/pcb/josh/other/network/RCS/tty.c,v $ XX * $Revision: 1.1 $ XX * $Date: 87/04/15 21:29:36 $ XX * $State: Exp $ XX * $Author: josh $ XX * $Locker: josh $ XX * XX *------------------------------------------------------------------ XX * XX * $Log: tty.c,v $ XX * Revision 1.1 87/04/15 21:29:36 josh XX * Initial revision XX * XX * XX *------------------------------------------------------------------ XX */ XX XX XX#include "netw.h" XX XX_stty(object, change, status) XX TCOND *object; XX int change, status; XX{ XX switch (change) { XX case COOKED: /* 0x0 */ XX object->sgttyb.sg_flags &= ~RAW; XX object->sgttyb.sg_flags &= ~CBREAK; XX break; XX case CBREAK: /* 0x2 */ XX object->sgttyb.sg_flags |= CBREAK; XX break; XX case LCASE: /* 0x4 */ XX if (status) XX object->sgttyb.sg_flags |= LCASE; XX else XX object->sgttyb.sg_flags &= ~LCASE; XX break; XX case RAW: /* 0x20 */ XX object->sgttyb.sg_flags |= RAW; XX break; XX case ECHO: /* 0x8 */ XX if (status) XX object->sgttyb.sg_flags |= ECHO; XX else XX object->sgttyb.sg_flags &= ~ECHO; XX break; XX case BAUD: /* 0x1 */ XX object->sgttyb.sg_ispeed = status; XX object->sgttyb.sg_ospeed = status; XX break; XX default: XX return(-1); XX break; XX } XX} SHAR_EOF if test 1627 -ne "`wc -c tty.c`" then echo shar: error transmitting tty.c '(should have been 1627 characters)' fi echo shar: extracting Makefile '(1359 characters)' sed 's/^XX//' << \SHAR_EOF > Makefile XXCFLAGS = -O XX XXDEST = /usr/local/lib XX XXMDEST = /usr/man/man3 XX XXEXTHDRS = /usr/include/fcntl.h XX XXHDRS = net.h \ XX netw.h \ XX openpty.h XX XXLIBRARY = libnet.a XX XXMAKEFILE = Makefile XX XXOBJS = basic.o \ XX ident.o \ XX isignal.o \ XX openpty.o \ XX perror.o \ XX proutines.o \ XX tty.o \ XX utmp.o XX XXPRINT = imprint -O -2 XX XXSRCS = basic.c \ XX ident.c \ XX isignal.c \ XX openpty.c \ XX perror.c \ XX proutines.c \ XX tty.c \ XX utmp.c XX XX XX.c.o: XX $(CC) $(CFLAGS) -c $< XX XXall: $(LIBRARY) XX XX$(LIBRARY): $(OBJS) XX @echo -n "Loading $(LIBRARY) ... " XX @ar cru $(LIBRARY) $(OBJS) XX @ranlib $(LIBRARY) XX @echo "done" XX XXclean: XX @rm -f $(OBJS) libnet.a XX XXdepend:; @mkmf -f $(MAKEFILE) LIBRARY=$(LIBRARY) DEST=$(DEST) XX XXextract:; @ar xo $(DEST)/$(LIBRARY) XX @rm -f __.SYMDEF XX XXindex:; @ctags -wx $(HDRS) $(SRCS) XX XXinstall: $(LIBRARY) XX @echo Installing $(LIBRARY) in $(DEST) XX install $(LIBRARY) $(DEST) XX ranlib $(DEST)/$(LIBRARY) XX @echo Copying the manual page to ${MDEST} XX cp netw.3 ${MDEST} XX @echo Copying the header file XX cp netw.h /usr/include XX XXlibrary: $(LIBRARY) XX XXprint:; @$(PRINT) $(HDRS) $(SRCS) XX XXtags: $(HDRS) $(SRCS); @ctags $(HDRS) $(SRCS) XX XXupdate: $(DEST)/$(LIBRARY) XX XX$(DEST)/$(LIBRARY): $(SRCS) $(HDRS) $(EXTHDRS) XX @-ar xo $(DEST)/$(LIBRARY) XX @make -f $(MAKEFILE) DEST=$(DEST) install clean XX### SHAR_EOF if test 1359 -ne "`wc -c Makefile`" then echo shar: error transmitting Makefile '(should have been 1359 characters)' fi echo shar: creating directory examples mkdir examples cd examples echo shar: extracting Makefile '(583 characters)' sed 's/^XX//' << \SHAR_EOF > Makefile XXCFLAGS = -g XX XXLIBS = ../libnet.a XX XXall: server client login2 test1 test2 ptest XX XXserver: server.o getopt.o XX ${CC} ${CFLAGS} -o server server.o getopt.o ${LIBS} XX XXclient: client.o getopt.o XX ${CC} ${CFLAGS} -o client client.o getopt.o ${LIBS} XX XXlogin2:login.o XX ${CC} ${CFLAGS} -o login2 login.o ${LIBS} XX XXtest1:test1.o XX ${CC} ${CFLAGS} -o test1 test1.o ${LIBS} XX XXtest2:test2.o XX ${CC} ${CFLAGS} -o test2 test2.o ${LIBS} XX XXptest:ptest.o XX ${CC} ${CFLAGS} -o ptest ptest.o ${LIBS} XX XXgetopt.o:getopt.c XX ${CC} ${CFLAGS} -DVMUNIX -c getopt.c XX XXclean: XX @rm -f *.o server client login2 test1 test2 ptest SHAR_EOF if test 583 -ne "`wc -c Makefile`" then echo shar: error transmitting Makefile '(should have been 583 characters)' fi echo shar: extracting README '(1341 characters)' sed 's/^XX//' << \SHAR_EOF > README XX XXSamples: XX login.c - opens a pty and executes a /bin/login in it. XX XX test1.c/test2.c - Establishes a basic connection between two points XX Very simple XX XX client.c/server.c - Complicated example showing XX a server maintaining multiple connections and XX a client that connects to it. XX XX ptest.c - Test the modified perror routine. XX XX XXIndex of function usage: XX XXFUNCTION FILE ROUTINE LINE XX---------------------------------------------------------- XXaddfd() client.c do_prog 63 65 XX server.c do_prog 75 84 XX XXanswer() server.c do_prog 80 XX XXattach() server.c do_prog 64 XX test1.c main 7 XX XXblock() client.c do_prog 68 XX server.c do_prog 78 XX XXclrutmp() login.c gork 20 XX XXdelfd() server.c do_prog 93 XX XXhostname() ptest.c main 9 XX test2.c main 4 XX XXinitfd() client.c do_prog 61 XX server.c do_prog 73 XX XXisignal() login.c main 55 XX XXloadtty() login.c -- 46 XX XXopenpty() login.c main 48 XX XXphone() client.c do_prog 57 59 XX ptest.c main 9 13 XX test2.c main 4 XX XXpkill() server.c do_prog 71 95 XX server.c exiter 18 XX test1.c main 12 13 XX test2.c main 7 XX XXstty() login.c main 50 51 64 65 XX XXuseport() client.c do_prog 57 59 XX server.c do_prog 64 XX test1.c main 7 XX test2.c main 4 SHAR_EOF if test 1341 -ne "`wc -c README`" then echo shar: error transmitting README '(should have been 1341 characters)' fi echo shar: extracting client.c '(1319 characters)' sed 's/^XX//' << \SHAR_EOF > client.c XX#ifndef lint XXstatic char rcsid[] = "$Header$"; XX#endif XX XX#include <stdio.h> XX#include <ctype.h> XX XXtypedef enum { false = 0, true = 1} bool; XX XXchar *progname; XX XXint p_val; XXchar *h_string; XXmain (argc, argv) XX int argc; XX char *argv[]; XX{ XX extern int opterr; XX extern char *optarg; XX int c; XX opterr = 1; XX progname = argv[0]; XX XX p_val = 2500; XX h_string = (char *) 0; XX XX while ((c = getopt (argc, argv, "p:h:")) != EOF) XX switch (c) XX { XX case 'p': XX p_val = atoi (optarg); XX break; XX case 'h': XX h_string = optarg; XX break; XX case '?': XX usage (); XX break; XX } XX XX do_prog (); XX exit (0); XX} XXusage () XX{ XX fprintf (stderr, "Usage: %s [ -p port ] [ -h host ]\n", progname); XX exit (1); XX} XXdo_prog () XX{ XX int p, XX n, XX c; XX char buff[255]; XX if (h_string) XX p = phone (useport (p_val), h_string); XX else XX p = phone (useport (p_val), hostname()); XX XX initfd (); XX XX addfd (0); XX XX addfd (p); XX XX while (1) XX { XX c = block (); XX XX if (c == 0) XX { XX if (gets (buff) == NULL) XX goto leave; XX write (p, buff, strlen (buff)); XX } XX else XX { XX n = read (c, buff, 255); XX if (n) XX printf ("Strange... the daemon talked back\n"); XX else XX { XX printf ("Daemon died\n"); XX exit (0); XX } XX } XX } XXleave: XX printf ("Quiting...\n"); XX} SHAR_EOF if test 1319 -ne "`wc -c client.c`" then echo shar: error transmitting client.c '(should have been 1319 characters)' fi echo shar: extracting getopt.c '(1262 characters)' sed 's/^XX//' << \SHAR_EOF > getopt.c XX/* getopt.c 1.1 85/05/30 */ XX /* getopt.c 1.1 10/26/79 11:50:14 */ XX#include <stdio.h> XX#ifdef VMUNIX XX#define strchr index XX#endif XX#define ERR(s, c) if(opterr){ fputs (argv[0], stderr); fputs (s, stderr); fputc (c, stderr); fputc ('\n', stderr); } XX XXint opterr = 1; XXint optind = 1; XXint optopt; XXchar *optarg; XXchar *strchr (); XX XXint XX getopt (argc, argv, opts) XXchar **argv, XX *opts; XX{ XX static int sp = 1; XX register c; XX register char *cp; XX XX if (sp == 1) XX if (optind >= argc || XX argv[optind][0] != '-' || argv[optind][1] == '\0') XX return EOF; XX else XX if (strcmp (argv[optind], "--") == NULL) { XX optind++; XX return EOF; XX } XX optopt = c = argv[optind][sp]; XX if (c == ':' || (cp = strchr (opts, c)) == NULL) { XX ERR (": illegal option -- ", c); XX if (argv[optind][++sp] == '\0') { XX optind++; XX sp = 1; XX } XX return '?'; XX } XX if (*++cp == ':') { XX if (argv[optind][sp + 1] != '\0') XX optarg = &argv[optind++][sp + 1]; XX else XX if (++optind >= argc) { XX ERR (": option requires an argument -- ", c); XX sp = 1; XX return '?'; XX } XX else XX optarg = argv[optind++]; XX sp = 1; XX } XX else { XX if (argv[optind][++sp] == '\0') { XX sp = 1; XX optind++; XX } XX optarg = NULL; XX } XX return c; XX} SHAR_EOF if test 1262 -ne "`wc -c getopt.c`" then echo shar: error transmitting getopt.c '(should have been 1262 characters)' fi echo shar: extracting login.c '(2128 characters)' sed 's/^XX//' << \SHAR_EOF > login.c XX#include <sys/ioctl.h> XX#include <stdio.h> XX#include "../netw.h" XX/* XX * Gork is the routine that shows up on the other end of the pty. As far as XX * it can tell, it is on its own terminal. In this example, I call XX * /bin/login so that I can log in. Note: On a machine where the /etc/utmp XX * file is locked up, this sometimes leaves strange entries when you type XX * w(1) after to log back out. Don't worry, they will go away after reboot XX * or you can use my rename(l) package to clear out the entry. XX */ XX XXchar **env; XXgork () XX{ XX char *buf[2]; XX buf[0] = "login"; XX buf[1] = 0; XX XX if (vfork () == 0) XX execve ("/bin/login", buf, 0); XX XX printf ("Connected.\n"); XX XX (void) wait (0); XX XX /* clrutmp has no effect on machines where /etc/utmp is locked up */ XX clrutmp (); XX XX printf ("\nDisconnected...\n"); XX} XXint s; XX/* Read from the keyboard */ XXrread (fd) XX int fd; XX{ XX int n; XX char buff[255]; XX n = read (fd, buff, 255); XX write (s, buff, n); XX} XXmain (argc, argv, argp) XX int argc; XX char *argv[]; XXchar *argp[]; XX{ XX TCOND tdef; XX XX char buff[255]; XX int n; XX struct sgttyb b, XX sbuf; XX env = argp; XX XX loadtty (tdef); /* Load my terminal XX * configuration */ XX XX s = openpty (tdef, gork); /* Put the function gork on XX * the other end of the file XX * descripter using the XX * terminal defined in tdef. */ XX XX stty (tdef, RAW, 0); /* Change the definition to XX * be raw */ XX stty (tdef, ECHO, FALSE); /* Have it not echo */ XX XX settty (tdef); /* Set my terminal to tdef */ XX XX isignal (0, rread); /* Set rread to be called XX * when something comes in XX * on the keyboard */ XX XX while (1) XX { XX n = read (s, buff, 255); /* Read from the keyboard */ XX if (n == EOF) /* Has the other end closed? */ XX break; /* Guess so */ XX write (1, buff, n); /* Write out whats been XX * gotten from the pty */ XX } XX XX stty (tdef, COOKED, 0); /* Make tdef cooked again */ XX stty (tdef, ECHO, TRUE); /* Turn echo back on */ XX XX settty (tdef); /* Set it */ XX} SHAR_EOF if test 2128 -ne "`wc -c login.c`" then echo shar: error transmitting login.c '(should have been 2128 characters)' fi echo shar: extracting ptest.c '(282 characters)' sed 's/^XX//' << \SHAR_EOF > ptest.c XXmain() XX{ XX int s; XX XX XX printf("You should see two sets of duplicate lines\n\n"); XX XX printf("phone: service unknown\n"); XX s=phone("stuff_xyzzy",hostname()); XX XX if(s<0) perror("phone"); XX XX s=phone("ftp","non_existant"); XX XX printf("phone: Host is unreachable\n"); XX if(s<0) perror("phone"); XX} SHAR_EOF if test 282 -ne "`wc -c ptest.c`" then echo shar: error transmitting ptest.c '(should have been 282 characters)' fi echo shar: extracting server.c '(1350 characters)' sed 's/^XX//' << \SHAR_EOF > server.c XX#ifndef lint XXstatic char rcsid[] = "$Header$"; XX#endif XX XX#include <stdio.h> XX#include <ctype.h> XX#include <signal.h> XX XXtypedef enum { false = 0, true = 1} bool; XX XXchar *progname; XX XXint p_val,s; XX XXexiter() XX{ XX fprintf(stderr,"Shutting down...\n"); XX pkill(s); XX exit(0); XX} XX XXmain(argc, argv) XX int argc; XX char *argv[]; XX{ XX extern int opterr; XX extern char *optarg; XX int c; XX XX opterr = 1; XX progname = argv[0]; XX XX p_val = 2500; XX XX while ((c = getopt(argc, argv, "p:")) != EOF) XX switch (c) { XX case 'p': XX p_val = atoi(optarg); XX break; XX case '?': XX usage(); XX break; XX } XX XX signal(SIGHUP,exiter); XX signal(SIGINT,exiter); XX signal(SIGQUIT,exiter); XX signal(SIGTERM,exiter); XX XX do_prog(); XX exit(0); XX} XX XXusage() XX{ XX fprintf(stderr, "Usage: %s [ -p port ] \n", progname); XX exit(1); XX} XXdo_prog() XX{ XX int c,q,n; XX char buff[1024]; XX XX s=attach(useport(p_val)); XX XX if(s==-1) { XX perror("attach"); XX exit(-1); XX } XX XX pkill(0); XX XX initfd(); XX XX addfd(s); XX XX while(1) { XX c=block(); XX if(c==s) { XX q=answer(s); XX if(q==-1) { XX perror("answer"); XX } else { XX addfd(q); XX printf("Conenction accepted: %d\n",q); XX } XX } else { XX n=read(c,buff,sizeof(buff)-1); XX if(n) { XX buff[n]=0; XX printf("%d: %s\n",c,buff); XX } else { XX delfd(c); XX printf("File descriptor closed: %d\n",c); XX pkill(c); XX } XX } XX } XX} SHAR_EOF if test 1350 -ne "`wc -c server.c`" then echo shar: error transmitting server.c '(should have been 1350 characters)' fi echo shar: extracting test1.c '(131 characters)' sed 's/^XX//' << \SHAR_EOF > test1.c XXmain() XX{ XX int s,q; XX XX printf("attach\n"); XX XX s=attach(useport(2501)); XX XX printf("accept\n"); XX q=answer(s); XX XX pkill(q); XX pkill(s); XX} XX XX SHAR_EOF if test 131 -ne "`wc -c test1.c`" then echo shar: error transmitting test1.c '(should have been 131 characters)' fi echo shar: extracting test2.c '(89 characters)' sed 's/^XX//' << \SHAR_EOF > test2.c XXmain() { XX int s; XX XX s=phone(useport(2501),hostname()); XX printf("Done\n"); XX XX pkill(s); XX} XX SHAR_EOF if test 89 -ne "`wc -c test2.c`" then echo shar: error transmitting test2.c '(should have been 89 characters)' fi echo shar: done with directory examples cd .. echo shar: extracting netw.3 '(6725 characters)' sed 's/^XX//' << \SHAR_EOF > netw.3 XX.\" @(#)netw.3 1.1 87/4/15 SMI; from UCB 4.2 XX.TH NETW L "14 March 1987" XX.SH NAME XXpkill,addfd, answer, attach, block, useport, delfd, initfd, myport, phone, clrutmp, setutmp, isignal, openpty, loadtty, settty, whoami, hostname, stty \- Some Nice Network/IO Functions XX.SH SYNOPSIS XX.nf XX.B #include <netw.h> XX.LP XX.B int pkill(fd) XX.B int fd; XX.LP XX.B int attach(s) XX.B char *s; XX.LP XX.B int answer(s) XX.B int s; XX.LP XX.B int phone(service,host) XX.B char *service,*host; XX.LP XX.B char *useport(port) XX.B int port XX.LP XX.B char *myport() XX.LP XX.B int answer(s) XX.B int s; XX.LP XX.B initfd() XX.LP XX.B addfd(x) XX.B int x; XX.LP XX.B delfd(x) XX.B int x; XX.LP XX.B int block() XX.LP XX.B char *whoami() XX.LP XX.B setutmp(string) XX.B char *string; XX.LP XX.B clrutmp() XX.LP XX.B isignal(fd.proc) XX.B int fd; XX.B int (*proc)(); XX.LP XX.B loadtty(cond) XX.B TCOND cond; XX.LP XX.B settty(cond) XX.B TCOND cond; XX.LP XX.B openpty(cond,task) XX.B TCOND cond; XX.B int (*task)(); XX.LP XX.B char *hostname(); XX.LP XX.B stty (tcond,change,value) XX.B TCOND tcond; XX.B int change,value; XX.SH DESCRIPTION XX.LP XX.I pkill XXis used to close down ANY kind of connection. Much like XX.I close XXexcept that it is more exacting. Still, when closing a XXa socket setup by XX.I attach XXit might not work correctly. XX.LP XX.I Attach XXis used to setup a listening post at a socket location. The string XXpassed to XX.I attach XXcontains the service the server is going to be. It XXwill error if the service passed to it does not exist or if the process XXcannot use the port. XX.I Attach XXreturns the file descripter to the listening post. XX XX tmp = attach("game"); XX XXNormally this function is used only by a server process. XX XX.LP XX.I answer XXaccepts a XX.I phone XXfrom a person. XX XX s = attach(myport(),hostname()) XX XX d = answer(s) XX XX.LP XX.I phone XXis the routine used to connect to one of the services(5) that the XXprogram has access to. The first argument is the service that XXit is connecting to. The second argument is the machine on which XXthe other process (the one it is connecting too) lives. XXIt returns a file descripter that can be XXused for commincation between the two processes. XX XX x = phone("game","sol"); XX XXNormally this function is used only by the client process. XX XX.LP XX.I useport XXand XX.I myport XXwill let XX.I phone XXand XX.I attach XXconnect to a specific port instead of them going through the XX.I services(5) XXdatabase like they normally do. XX XX x = attach(useport(3000)); XX XX y = phone(useport(3000)); XX XX z = answer(myport()); XX XX.I myport XXis special because it uses your uid to calculate which port XXit is going to use. This is useful if several students are using XXsockets and you do not wish them to overlap. The port a person XXuses is getuid()+OFFSET. OFFSET is defined at compile time. XX.I WARNING: XXunless you are root, you cannot access any ports less then 1024. XX.LP XX.I answer XXis used by the server to answer a phone call by the client. The XXargument is the file descripter returned by XX.I attach. XXIt returns a socket that can be used for two directional XXcommunication between XXthe two processes. It is the counter-point to phone. XX XX y = answer(tmp); XX XX.LP XX.I initfd, addfd, delfd XXare the helpful functions that are used to control how XX.I block XXreacts to external stimulus. XX.I initfd XXshould be called first to initalize the common variables. XX.I addfd XXis used to add a file descripter to the descripters that XX.I block XXreacts to. XX.I delfd XXwill delete the file descripter that is passed to XX.I delfd XXfrom the descripters that XX.I block XXreacts to. XX XX initfd(); XX XX addfd(s); XX XX delfd(s); XX XX.LP XX.I block XXis the bottom routine that returns which file descripter has data XXcoming through it. It XX.I only XXchecks the file descripters that are told to it using XX.I addfd. XXIt returns the file descripter that is currently making noise. XXAlso, XX.I block XXacts in a round robbin type mannor. If a new message comes XXin along a file descripter, that descripter will not be returned XXtill all the descripters that previously have had messages XXsent down them have been handled. Then and only then will XXit start again and look for new messages on sockets. XX.I block XXwill block if there are no messages on any of the file descripters XXthat it knows about. XX XX c=block(); XX XX.LP XX.I whoami XXreturns a pointer to a string that contains who the caller is in the XXform of "name@hostname". This will even work if the process owner does XXnot have a entry in the utmp file. XX XX name = whoami(); XX.LP XX.I setutmp XXsets a utmp entry for the terminal. On most systems this call is XXnot allowed except by the super-user and will return a error (<0). XXThe string passed is used as the host that is shown when XXthe command XX.I who(1) XXis called. XX.LP XX.I clrutmp XXwill clear the current utmp entry. The restrictions are the XXsame as in XX.I setutmp. XX.LP XX.I isignal XXallows you to set a function to handle a pipe in the same XXway what XX.I signal(3) XXallows you to set a function to handle a signal. The function XXis called with the file descripter as the first argument. XX.LP XX.I openpty XXallows easy use of a pseudo terminal( XX.I pty(4) XX) withen a program. The first argument is a terminal XXcondition as returned by XX.I loadtty. XXThe second is the function that you wish to XXcall. It returns a file descripter to the pty. XX.I (see example below) XX.LP XX.I loadtty XXloads a terminals current settings into the named buffer. See XX.I stty(1) XXfor more details. XX.LP XX.I settty XXsets the current terminal settings from the named buffer. See XX.I stty(1) XXfor more details. XX.LP XX.I hostname XXreturns a pointer to a string that contains the hostname. XX.LP XX.I stty XXis a function that can be used to change the current parameters XXof a TCOND block. It is very much like XX.I stty(1) XXin purpose. XX.PP XXIn the following example I use stty ,loadtty,and settty to change XXmake my terminal stop echoing. XX XX TCOND block; XX XX loadtty(block); XX stty(block,ECHO,FALSE); XX settty(block); XX XX.PP XXThe values XX.I stty XXunderstands are the following: XX.nf XX XX options: XX COOKED: Make all IO cooked. XX CBREAK: Make IO half-baked. XX RAW: Do no IO processing XX LCASE: Change how upper and lowercase is handled XX ECHO: Turn on or off echo. XX BAUD: Set the baud rate. XX.fi XX.PP XXRead the XX.I stty(1) XXmanual for more information on what this means. XX XX XX.SH COMMENTS XX XXEvery routine that returns a pointer to a string is really XXreturning a pointer to a static string within the function. This XXmeans that you should not try to free it AND you should copy it XXelsewhere so that it does not get overwritten. XX XX.SH BUGS XX.PP XXWhen dealing with sockets created using attach, there is no XXgood way to close the socket and sometimes they are left open. XXLuckly, the system will clear them out in about 30 seconds. XX.PP XXAnother problem is that isignal is not triggered when the socket XXis closed at the other end. I have not figured out how to handle XXthis yet. XX.SH AUTHOR XXJosh Siegel SHAR_EOF if test 6725 -ne "`wc -c netw.3`" then echo shar: error transmitting netw.3 '(should have been 6725 characters)' fi echo shar: extracting proutines.c '(3948 characters)' sed 's/^XX//' << \SHAR_EOF > proutines.c XX/* XX * openpty - open a pseudo-terminal XX * XX * The first time that the routine is called, the device directory is XX * searched and a list of all candidate pseudo-terminals is compiled. XX * Candidates are defined to be those entries in "/dev" whose names XX * (1) are the same length as PTY_PROTO and (2) start with the XX * initial string PTY_PREFIX. Further, the master and slave sides XX * must both exist. XX * XX * openpty() attempts to find an unused pseudo-terminal from the list XX * of candidates. If one is found, the master and slave sides are XX * opened and the file descriptors and names of these two devices are XX * returned in a "ptydesc" structure. (The address of this structure XX * is supplied by the caller. Zero is returned if openpty() was XX * successful, -1 is returned if no pty could be found. XX * XX * written by John Bruner <unmvax!unm-la!lanl!cmcl2!seismo!mordor!jdb> XX */ XX XX#include <sys/types.h> XX#include <sys/dir.h> XX#include <fcntl.h> XX#include <strings.h> XX#include "openpty.h" XX XX#define DEV_DIR "/dev" /* directory where devices live */ XX#define PT_INDEX (sizeof DEV_DIR) /* location of 'p' in "pty" */ XX XX#define PTY_PROTO "ptyp0" /* prototype for pty names */ XX#define PTY_PREFIX "pty" /* prefix required for name of pty */ XX XXstruct ptyinfo { XX struct ptyinfo *pi_next; XX char *pi_pty; XX char *pi_tty; XX}; XX XXstatic struct ptyinfo *ptylist; XX XXextern char *malloc(); XX XXstatic char * devname(name) XXchar *name; XX{ XX register char *fullname; XX XX /* XX * Construct the full name of a device in DEV_DIR. Returns XX * NULL if it failed (because malloc() failed). XX */ XX XX fullname = malloc((unsigned)(sizeof DEV_DIR + 1 + strlen(name))); XX if (fullname != NULL) { XX (void)strcpy(fullname, DEV_DIR); XX (void)strcat(fullname, "/"); XX (void)strcat(fullname, name); XX } XX return(fullname); XX} XX XXstatic isapty(dp) XXstruct direct *dp; XX{ XX static struct ptyinfo *pi; XX XX /* XX * We don't care about the gory details of the directory entry. XX * Instead, what we really want is an array of pointers to XX * device names (with DEV_DIR prepended). Therefore, we create XX * this array ourselves and tell scandir() to ignore every XX * directory entry. XX * XX * If malloc() fails, the current directory entry is ignored. XX */ XX XX if (pi == NULL && XX (pi = (struct ptyinfo *)malloc((unsigned)sizeof *pi)) == NULL) XX return(0); XX XX if (strlen(dp->d_name) == sizeof PTY_PROTO - 1 && XX strncmp(dp->d_name, PTY_PREFIX, sizeof PTY_PREFIX - 1) == 0) { XX pi->pi_pty = devname(dp->d_name); XX if (pi->pi_pty == NULL) XX return(0); XX pi->pi_tty = malloc((unsigned)(strlen(pi->pi_pty) + 1)); XX if (pi->pi_tty == NULL) { XX free(pi->pi_pty); XX return(0); XX } XX (void)strcpy(pi->pi_tty, pi->pi_pty); XX pi->pi_tty[PT_INDEX] = 't'; XX if (access(pi->pi_pty, 0) == 0 && access(pi->pi_tty, 0) == 0) { XX pi->pi_next = ptylist; XX ptylist = pi; XX pi = NULL; XX } else { XX free(pi->pi_pty); XX free(pi->pi_tty); XX } XX } XX return(0); XX} XX XX_openpty(pt) XXstruct ptydesc *pt; XX{ XX register struct ptyinfo *pi; XX static int fail; XX auto struct direct **dirlist; XX extern char *re_comp(); XX extern int alphasort(); XX XX /* XX * If scandir() fails or no possible pty's are found, then "fail" XX * is set non-zero. If "fail" is non-zero then the routine bombs XX * out immediately. Otherwise, the list of candidates is examined XX * starting with the entry following the last one chosen. XX */ XX XX if (fail) XX return(-1); XX XX if (!ptylist) { /* first time */ XX if (scandir(DEV_DIR, &dirlist, isapty, alphasort) < 0 || XX ptylist == NULL) { XX fail = 1; XX return(-1); XX } XX for (pi=ptylist; pi->pi_next; pi=pi->pi_next) XX ; XX pi->pi_next = ptylist; /* make the list circular */ XX } XX XX pi = ptylist; XX do { XX if ((pt->pt_pfd = open(pi->pi_pty, O_RDWR)) >= 0) { XX if ((pt->pt_tfd = open(pi->pi_tty, O_RDWR)) >= 0) { XX ptylist = pi->pi_next; XX pt->pt_pname = pi->pi_pty; XX pt->pt_tname = pi->pi_tty; XX return(0); XX } else XX (void)close(pt->pt_pfd); XX } XX pi = pi->pi_next; XX } while (pi != ptylist); XX return(-1); XX} XX SHAR_EOF if test 3948 -ne "`wc -c proutines.c`" then echo shar: error transmitting proutines.c '(should have been 3948 characters)' fi echo shar: extracting openpty.h '(466 characters)' sed 's/^XX//' << \SHAR_EOF > openpty.h XX/* XX * $Header: openpty.h,v 1.1 87/04/15 21:29:48 josh Exp $ XX * XX * $Log: openpty.h,v $ XX * Revision 1.1 87/04/15 21:29:48 josh XX * Initial revision XX * XX */ XX XX XX/* XX * This file defines the "ptydesc" structure which is returned XX * by the routine "openpty". XX */ XX XXstruct ptydesc { XX int pt_pfd; /* file descriptor of master side */ XX int pt_tfd; /* file descriptor of slave side */ XX char *pt_pname; /* master device name */ XX char *pt_tname; /* slave device name */ XX}; SHAR_EOF if test 466 -ne "`wc -c openpty.h`" then echo shar: error transmitting openpty.h '(should have been 466 characters)' fi echo shar: extracting utmp.c '(2928 characters)' sed 's/^XX//' << \SHAR_EOF > utmp.c XX#ifndef lint XXstatic char *RCSid = "$Header: utmp.c,v 1.1 87/04/15 21:29:39 josh Exp $"; XX#endif XX XX/* XX *------------------------------------------------------------------ XX * Copyright 1987, Josh Siegel XX * All rights reserved. XX * XX * Josh Siegel (siegel@hc.dspo.gov) XX * Dept of Electrical and Computer Engineering, XX * University of New Mexico, XX * Albuquerque , New Mexico XX * (505) 277-2497 XX * XX *------------------------------------------------------------------ XX * XX * $Source: /usr/pcb/josh/other/network/RCS/utmp.c,v $ XX * $Revision: 1.1 $ XX * $Date: 87/04/15 21:29:39 $ XX * $State: Exp $ XX * $Author: josh $ XX * $Locker: josh $ XX * XX *------------------------------------------------------------------ XX * XX * $Log: utmp.c,v $ XX * Revision 1.1 87/04/15 21:29:39 josh XX * Initial revision XX * XX * XX *------------------------------------------------------------------ XX */ XX XX XX#include <stdio.h> XX#include <utmp.h> XX#include <pwd.h> XX#include <sys/file.h> XX XX/* XX * Allow the user to creat a entry in the utmp file. The problem is that this XX * shows the normal hack how to really cause problems via /etc/utmp. I have XX * a program for the Sun and BSD43 that allows you to edit entries in XX * /etc/utmp but this is another story XX */ XX XXsetutmp(host) XX char host[]; XX{ XX struct passwd *passwd; XX struct utmp utmp; XX int t, f; XX char *p, *ttyname(); XX XX /* Get the tty slot in the /etc/utmp file */ XX t = ttyslot(); XX XX if (t == 0) XX return (-2); /* Not on a tty? */ XX XX /* XX * We are going to let the user set the host because it can't hurt XX * and I use it for my window managers XX */ XX XX strncpy(utmp.ut_host, host, 8); XX XX /* Set the login time to the current time */ XX XX utmp.ut_time = time(0); XX XX /* Lets get a path to the tty device */ XX XX p = ttyname(0); XX XX if (p == NULL) XX return (-1); /* No device and a tty slot? weard! */ XX XX strcpy(utmp.ut_line, p + 5); XX XX /* Who is the bum we are dealing with */ XX XX passwd = getpwuid(getuid()); XX XX strcpy(utmp.ut_name, passwd->pw_name); XX XX /* Can I open the utmp file? On Suns I can */ XX XX f = open("/etc/utmp", O_WRONLY); XX XX if (f == -1) XX return (-3); /* Guess your not on a sun or not root */ XX XX lseek(f, (long) (t * sizeof(utmp)), 0); /* Move out to the place */ XX write(f, (char *) &utmp, sizeof(utmp)); /* Write it */ XX close(f); /* Close it */ XX XX /* What a nice guy I am :-) */ XX} XX XX/* XX * Clear the entry from the utmp file. This only clears the entry your 0 XX * descripter is attached to. Work it out... Its a hack! XX */ XX XXclrutmp() XX{ XX int t, f; XX struct utmp utmp; XX XX t = ttyslot(); XX XX if (t == 0) XX return (-1); /* descripter 0/1/2 not on a tty */ XX bzero((char *) &utmp, sizeof(utmp)); XX /* I don't trust machines to give me clean stack each time */ XX XX f = open("/etc/utmp", O_WRONLY); XX if (f < 0) XX return (-1); /* Must not have access to /etc/utmp. */ XX XX lseek(f, (long) (t * sizeof(utmp)), 0); XX write(f, (char *) &utmp, sizeof(utmp)); /* Clear the entry */ XX close(f); XX return(0); XX} SHAR_EOF if test 2928 -ne "`wc -c utmp.c`" then echo shar: error transmitting utmp.c '(should have been 2928 characters)' fi echo shar: extracting INSTALL '(398 characters)' sed 's/^XX//' << \SHAR_EOF > INSTALL XXTo install: XX XX1) Look at the Makefile to make sure I did not install XX any trojan horses and to configure as you wish. XX XX2) Type "make install" (as root if need be) XX XX If you just type "make" it will make a version of XX libnet.a in the current directory. This is the XX configuration the examples/Makefile is setup for. XX XX3) Watch the fun. XX XX4) Look at the examples in the directory "examples". XX XX XX SHAR_EOF if test 398 -ne "`wc -c INSTALL`" then echo shar: error transmitting INSTALL '(should have been 398 characters)' fi echo shar: done with directory network cd .. # End of shell archive exit 0 -- Josh Siegel (siegel@hc.dspo.gov) (505) 277-2497 (Home) I'm a mathematician, not a programmen?
guy@gorodish.UUCP (04/16/87)
> It also does not make use of XDR. This means that > transfering data from machine to machine is still > ugly. If only BSD4.3 had XDR.... If you count the "User Contributed Software", 4.3BSD *does* have XDR *and* Sun RPC; look in "/usr/src/new/sunrpc".
josh@hi.uucp (Josh Siegel ) (04/18/87)
In article <16852@sun.uucp> guy%gorodish@Sun.COM (Guy Harris) writes: >> It also does not make use of XDR. This means that >> transfering data from machine to machine is still >> ugly. If only BSD4.3 had XDR.... > >If you count the "User Contributed Software", 4.3BSD *does* have XDR >*and* Sun RPC; look in "/usr/src/new/sunrpc". Great! This means I can use XDR! On other points (I got some mail...): I am not sure how far the source went so if you get this message and not the source, send me a note so I check on why not... Also, I put the following in my code: * Copyright 1987, Josh Siegel * All rights reserved. ... well.. Thats not true and I am changing the header in my files. I grant full permission to copy and distribute, just as long as you DON'T sell it. (Now I am asking for it..) choose one of the following and paste it on top of all the files! <<;-)=<-' or ;-) Actually, since in the original posting, I didn't expressly allow you to patch my code, you can't do this.... --Josh Siegel --- (Credit to Larry Wall for this humorious copyright notice) You may copy this software in whole or in part as long as you don't try to make money off of it or pretend you wrote it. --- (Credit to Kurt Zeilenga for this verbose translation) /* Copyright 1987 Josh B. Siegel This notice and any statement of authorship must be reproduced on all copies. The author does not make any warranty expressed or implied, or assumes any liability or responsiblity for the use of this software. Any distributor of copies of this software shall grant the recipient permission for further redistribution as permitted by this notice. Any distributor must distribute this software without any fee or other monetary gains, unless expressed written permission is granted by the author. This software or its use shall not be: sold, rented, leased, traded, or otherwise marketed without the expressed written permission of the author. Permission is hereby granted to copy, reproduce, redistribute or otherwise use this software as long as the conditions above are meet. */ --- -- Josh Siegel (siegel@hc.dspo.gov) (505) 277-2497 (Home) I'm a mathematician, not a programmer!