wls@astrovax.UUCP (William L. Sebok) (12/08/84)
: Run this shell script with "sh" not "csh" PATH=:/bin:/usr/bin:/usr/ucb export PATH all=FALSE if [ $1x = -ax ]; then all=TRUE fi /bin/echo 'Extracting README' sed 's/^X//' <<'//go.sysin dd *' >README The following are diffs to the 4.2 distribution of uucp and tip to make them able to use the same lines for both dialin in and dialing out. This dialin- dialout mechanism runs under a vanilla 4.2 BSD kernel. Similar changes to uucp and tip ran here when we were running 4.1 BSD. We started to use uucp after the dialin lines had been in place for a while. It would have been very unpopular here to remove one of lines from public use to let uucp dial out. The first version of these changes ran here early in 1983. Having this ability is very useful way to make full use of your modems. For one thing, I can smile when a neighoring site complains that their one dialer is tied up from news backed up to one of their neighbors which has been down for a while and has just come back up. For another thing some of our neighbors seem to be reachable better by some modems than by others. For example, I can only reach rocky2 with a Racal Vadic. I can only reach akgua, burl, and sjuvax with a Hayes. When we get our 2400 baud modem in a week or so I can make special note of that --- and I don't have to buy two 2400 baud modems to have two-way 2400 baud capability. The key to this is a program is provided in the file acucntrl.c . This should be installed suid to root in the file /usr/local/lib/acucntrl . A set of diffs for tip and uucp are also provided. There have been other changes here to both tip and uucp so that the "after" line numbers in the diffs will not match. The "before" files are fresh off the 4.2 BSD distribution tape. The most important other change here in uucp was one to allow site names longer that 7 characters. uucp notes: The 3rd field of the L-devices file should contain "inout" for all devices intended for dialin/out use. Devices without the "inout" specification will be used like before: for dialout only. Changes are included to only disable dialins on the line once per dialing session (rather than enabling it and disabling it whenever another site is called). Also included is the fix to the nasty TIOCSPGP bug which caused all dialing attempts after the first unsuccessful one to fail. tip notes: tip runs here setgid to uucp. It assumes that /usr/local/lib/acucntrl is executable by group uucp (in case you want to restrict general execute permission on this program). A change has been included to allow comma separated entries in the "va" field of the remote file. This is the field that specifies the dialer type. With more dialers available it is more likely that they will be of different types. If the number of "va" subfields is less than the number of "dv" (i.e. device name) fields the device type that of the last previously specified device. Example from our own /etc/remote: :dv=/dev/ttyd2,/dev/ttyd1,/dev/ttyd0:at=hayes,vadic: The first modem /dev/ttyd2 is a hayes. The second two modems /dev/ttyd1 and X/dev/ttyd0 are vadics. It is assumed in tip that the dialin/dialout devices have names /dev/ttyd?. Other names will require modifications. Good luck. I want to never go back to reserving modems for dialout. Bill Sebok Princeton University, Astrophysics {allegra,akgua,burl,cbosgd,decvax,ihnp4,noao,princeton,vax135}!astrovax!wls //go.sysin dd * made=TRUE if [ $made = TRUE ]; then /bin/chmod 644 README /bin/echo -n ' '; /bin/ls -ld README fi /bin/echo 'Extracting acucntrl.8l' sed 's/^X//' <<'//go.sysin dd *' >acucntrl.8l X.TH acucntrl 8 local X.SH NAME X.B acucntrl \- turn around tty line between dialin and dialout X.SH SYNOPSIS X.B /usr/lib/local/acucntrl keyword ttyline X.SH DESCRIPTION X.PP X.I Acucntrl turns around terminal line, enabling it to be used for both dialin and dialout. On dialin a terminal line is assumed to have modem control enabled and a getty process in existence waiting for logins. On dialout modem control is disabled and there is no getty process. X.PP This program must be run setuid to root. X.PP X.I keyword is chosen from the list: X.I disable or X.IR dialout , to condition a line for dialout; and X.I enable or X.IR dialin , to condition a line for dialin. X.PP When the line is conditioned for dialing out, the login name of the real uid of the process is placed in /etc/utmp in capitals. This declares that the line is in use and acts as an additional locking mechanism. X.I Acucntrl will refuse to act if the /etc/utmp entry for the line is not null, is not the the user's login name (capitalized or not), or if the process is running as the superuser. The last condition is to allow the superuser to clear the state of the line. X.PP Turning modem control on or off is handled by poking into /dev/kmem. It is currently implemented for dz, dh, and dmf lines. X.PP Under 4.2 BSD the program will also refuse to disable a line if carrier is sensed on it. The is to avoid the dead period where someone has just dialed in and made the connection but has not yet logged in. X.PP X.I Ttyline can be either of the form tty* or /dev/tty*. Enabling/disabling a line whose name does not begin with ttyd? is prohibited unless the real uid of the process is 0 or if the login name corresponding to the real uid is uucp. This is a security precaution. X.PP Steps taken when disabling X.RI ( i . e . setup for dialing out) X.IP 1) check input arguments X.IP 2) look in /etc/utmp to check that the line is not in use by another user X.IP 3) disable modem control on line X.IP 4) check for carrier on device X.IP 5) change owner of device to real uid X.IP 6) edit /etc/ttys, changing the first character of the appropriate line to 0 X.IP 7) send a hangup to process 1 to poke init to disable getty X.IP 8) post uid name in capitals in /etc/utmp to let world know device has been grabbed X.IP 9) make sure that DTR is on X.PP Steps taken when enabling X.RI ( i . e . setup for dialin) X.IP 1) check input arguments X.IP 2) look in /etc/utmp to check that the line is not in use by another user X.IP 3) make sure modem control on line is disabled X.IP 4) turn off DTR to make sure line is hung up X.IP 5) condition line: clear exclusive use and set hangup on close modes X.IP 6) turn on modem control X.IP 7) edit /etc/ttys, changing the first character of the appropriate line to 1 X.IP 8) send a hangup to process 1 to poke init to enable getty X.IP 9) clear uid name for /etc/utmp X.SH HISTORY X.PP First written by Allan Wilkes (fisher!allan) X.PP Modified June 8,1983 by W.Sebok (astrovax!wls) to poke the kernel rather than use a kernel hack to turn on/off modem control, using a subroutine stolen from a program written by Tsutomu Shimomura {astrovax,escher}!tsutomu X.PP Worked over many times by W.Sebok X.RI ( i . e . hacked to death) X.SH FILES X/dev/kmem, /vmunix, /etc/ttys, /etc/utmp, /dev/tty* X.SH BUGS X.PP Sensing carrier requires the 4.2 BSD TIOCMGET ioctl call. Unfortunately this ioctl is not implemented in the vanilla 4.2 BSD dh driver even though the dz and dmf drivers use an emulation of the DH11's modem control bits. This has been fixed here. X.PP Some time (currently 2 seconds) is required between disabling modem control and opening the device. This is probably because of a race with getty whose open is finally being allowed to complete. This time interval may not be enough on a loaded system. Because of this problem and the above problem with the dh driver there is deliberately no error message given when the TIOCMGET ioctl fails. X.PP Previously there was similar synchronization problem with the init process. When dialins are disabled the capitalized name of the process cannot be posted into /etc/utmp until init has finished clearing /etc/utmp. However one does not know how long that will take, and, on a loaded system, it can take quite a while. This was solved by the strategy of 1) posting the name, 2) poking init, 3) going into a loop where the process repeatedly waits a second and checks whether the entry has been cleared from /etc/utmp, and 4) posting the name again. //go.sysin dd * made=TRUE if [ $made = TRUE ]; then /bin/chmod 644 acucntrl.8l /bin/echo -n ' '; /bin/ls -ld acucntrl.8l fi /bin/echo 'Extracting acucntrl.c' sed 's/^X//' <<'//go.sysin dd *' >acucntrl.c X/* acucntrl - turn around tty line between dialin and dialout * * Usage: acucntrl {enable,disable} /dev/ttydX * * History: * First written by Allan Wilkes (fisher!allan) * * Modified June 8,1983 by W.Sebok (astrovax!wls) to poke kernel rather * than use kernel hack to turn on/off modem control, using subroutine * stolen from program written by Tsutomu Shimomura * {astrovax,escher}!tsutomu * * Worked over many times by W.Sebok (i.e. hacked to death) * * Operation: * disable (i.e. setup for dialing out) * (1) check input arguments * (2) look in /etc/utmp to check that the line is not in use by other * (3) disable modem control on terminal * (4) check for carrier on device * (5) change owner of device to real id * (6) edit /etc/ttys, changing the first character of the appropriate * line to 0 * (7) send a hangup to process 1 to poke init to disable getty * (8) post uid name in capitals in /etc/utmp to let world know device has * been grabbed * (9) make sure that DTR is on * * enable (i.e.) restore for dialin * (1) check input arguments * (2) look in /etc/utmp to check that the line is not in use by other * (3) make sure modem control on terminal is disabled * (4) turn off DTR to make sure line is hung up * (5) condition line: clear exclusive use and set hangup on close modes * (6) turn on modem control * (7) edit /etc/ttys, changing the first character of the appropriate * line to 1 * (8) send a hangup to process 1 to poke init to enable getty * (9) clear uid name for /etc/utmp */ #include <sys/param.h> #include <sys/buf.h> #include <signal.h> #ifdef SIGIO # define BSD4_2 /* how else am I to know? */ #endif #include <sys/conf.h> #ifdef BSD4_2 #include "/sys/vaxuba/ubavar.h" #else #include <sys/ubavar.h> #endif #include <sys/stat.h> #include <nlist.h> #include <sgtty.h> #include <utmp.h> #include <pwd.h> #include <stdio.h> #define NDZLINE 8 /* lines/dz */ #define NDHLINE 16 /* lines/dh */ #define NDMFLINE 8 /* lines/dmf */ #define DZ11 1 #define DH11 2 #define DMF 3 #define NLVALUE(val) (nl[val].n_value) struct nlist nl[] = { #define CDEVSW 0 { "_cdevsw" }, #define DZOPEN 1 { "_dzopen" }, #define DZINFO 2 { "_dzinfo" }, #define NDZ11 3 { "_dz_cnt" }, #define DZSCAR 4 { "_dzsoftCAR" }, #define DHOPEN 5 { "_dhopen" }, #define DHINFO 6 { "_dhinfo" }, #define NDH11 7 { "_ndh11" }, #define DHSCAR 8 { "_dhsoftCAR" }, #define DMFOPEN 9 { "_dmfopen" }, #define DMFINFO 10 { "_dmfinfo" }, #define NDMF 11 { "_ndmf" }, #define DMFSCAR 12 { "_dmfsoftCAR" }, { "\0" } }; #define ENABLE 1 #define DISABLE 0 char Etcutmp[] = "/etc/utmp"; char Etcttys[] = "/etc/ttys"; char Devhome[] = "/dev"; char usage[] = "Usage: acucntrl {dis|en}able device\n"; struct utmp utmp; char resettty, resetmodem; int etcutmp; long utmpoff; #define NAMSIZ sizeof(utmp.ut_name) #define LINSIZ sizeof(utmp.ut_line) main(argc, argv) int argc; char *argv[]; { register char *p; register int i; char uname[NAMSIZ], Uname[NAMSIZ]; int enable ; char *device; int devfile; int uid, gid; long lseek(); struct passwd *getpwuid(); char *rindex(); extern int errno; extern char *sys_errlist[]; /* check input arguments */ if (argc!=3) { fprintf(stderr, usage); exit(1); } if (argc != 3) { fprintf(stderr, usage); exit(1); } if (prefix(argv[1], "disable") || strcmp(argv[1],"dialout")==0) enable = 0; else if (prefix(argv[1], "enable") || strcmp(argv[1],"dialin")==0) enable = 1; else { fprintf(stderr, usage); exit(1); } device = rindex(argv[2],'/'); device = (device == NULL) ? argv[2]: device+1; /* Get nlist info */ nlist("/vmunix",nl); /* Chdir to /dev */ if(chdir(Devhome) < 0) { fprintf(stderr, "Cannot chdir to %s: %s\r\n", Devhome, sys_errlist[errno]); exit(1); } /* Get uid information */ uid = getuid(); gid = getgid(); p = getpwuid(uid)->pw_name; if (p==NULL) { fprintf(stderr,"cannot get uid name\n"); exit(1); } /* to upper case */ i = 0; do { uname[i] = *p; Uname[i] = (*p>='a' && *p<='z') ? (*p - ('a'-'A')) : *p; i++; p++; } while (*p && i<NAMSIZ); /* don't let just anyone do this */ if (strncmp(device,"ttyd",4)!=0 && uid!=0 && strcmp(uname,"uucp")!=0) { fprintf(stderr,"Permission Denied.\n"); exit(1); } /* check to see if line is being used */ if( (etcutmp = open(Etcutmp, 2)) < 0) { fprintf(stderr,"On open %s open: %s\n", Etcutmp,sys_errlist[errno]); exit(1); } while(read(etcutmp, &utmp,sizeof(struct utmp)) == sizeof(struct utmp)) { if(strcmp(device, utmp.ut_line) == 0) { if (utmp.ut_name[0] == '\0' || (upcase(utmp.ut_name,NAMSIZ) && (uid==0 || strncmp(utmp.ut_name,Uname,NAMSIZ)==0))) { utmpoff = lseek(etcutmp, (long)(-sizeof(utmp)), 1); break; } else { fprintf(stderr, "%s in use by %s\n", device, utmp.ut_name); exit(2); } } } /* Disable modem control */ if (setmodem(device,DISABLE)<0) { fprintf(stderr,"Unable to disable modem control\n"); exit(1); } if (enable) { if((devfile = open(device, 1)) < 0) { fprintf(stderr,"On open of %s: %s\n", device, sys_errlist[errno]); (void)setmodem(device,resetmodem); exit(1); } /* Try one last time to hang up */ if (ioctl(devfile,TIOCCDTR,0) < 0) fprintf(stderr,"On TIOCCDTR ioctl: %s\n", sys_errlist[errno]); if (ioctl(devfile, TIOCNXCL,0) < 0) fprintf(stderr, "Cannot clear Exclusive Use on %s: %s\n", device, sys_errlist[errno]); if (ioctl(devfile, TIOCHPCL,0) < 0) fprintf(stderr, "Cannot set hangup on close on %s: %s\n", device, sys_errlist[errno]); i = resetmodem; if (setmodem(device,ENABLE) < 0) { fprintf(stderr,"Cannot Enable modem control\n"); (void)setmodem(device,i); exit(1); } resetmodem=i; settys(device,ENABLE); pokeinit(device,Uname,enable); post(device,""); } else { #ifdef TIOCMGET int linestat=0; sleep(2); /* need time after modem control turnoff */ #endif TIOCMGET if((devfile = open(device, 1)) < 0) { fprintf(stderr,"On open of %s: %s\n", device, sys_errlist[errno]); (void)setmodem(device,resetmodem); exit(1); } #ifdef TIOCMGET /* check for presence of carrier */ (void)ioctl(devfile,TIOCMGET,&linestat); if (linestat&TIOCM_CAR) { fprintf(stderr,"%s is in use (Carrier On)\n",device); (void)setmodem(device,resetmodem); exit(2); } #endif TIOCMGET /* chown device */ if(chown(device, uid, gid) < 0) fprintf(stderr, "Cannot chown %s: %s\n", device, sys_errlist[errno]); /* poke init */ settys(device,DISABLE); pokeinit(device,Uname,enable); post(device,Uname); (void)close(devfile); /* close because init did vhangup */ if((devfile = open(device, 1)) < 0) { fprintf(stderr, "On %s open: %s\n", device, sys_errlist[errno]); } else { if(ioctl(devfile, TIOCSDTR, 0) < 0) fprintf(stderr, "Cannot set DTR on %s: %s\n", device, sys_errlist[errno]); } } exit(0); } X/* return true if no lower case */ upcase(str,len) register char *str; register int len; { for (; *str, --len >= 0 ; str++) { if (*str>='a' && *str<='z') return(0); } return(1); } X/* Post name to public */ post(device,name) char *device, *name; { (void)time(&utmp.ut_time); strcpyn(utmp.ut_line, device, LINSIZ); strcpyn(utmp.ut_name, name, NAMSIZ); if (lseek(etcutmp, utmpoff, 0)<0) fprintf(stderr,"on lseek in /etc/utmp: %s", sys_errlist[errno]); if (write(etcutmp, (char *)&utmp, sizeof(utmp))<0) fprintf(stderr,"on write in /etc/utmp: %s", sys_errlist[errno]); } X/* poke process 1 and wait for it to do its thing */ pokeinit(device,uname,enable) char *uname, *device; int enable; { struct utmp utmp; post(device, uname); /* poke init */ if (kill(1, SIGHUP)) { fprintf(stderr, "Cannot send hangup to init process: %s\n", sys_errlist[errno]); settys(device,resettty); (void)setmodem(device,resetmodem); exit(1); } if (enable) return; /* wait till init has responded, clearing the utmp entry */ do { sleep(1); if (lseek(etcutmp,utmpoff,0)<0) fprintf(stderr,"On lseek in /etc/utmp: %s", sys_errlist[errno]); if (read(etcutmp,&utmp,sizeof utmp)<0) fprintf(stderr,"On read from /etc/utmp: %s", sys_errlist[errno]); } while (utmp.ut_name[0] !='\0'); } X/* modify appropriate line in /etc/ttys to turn on/off the device */ settys(device,enable) char *device; int enable; { FILE *ttysfile; int ittysfil; int lnbeg, foundit, ndevice; char linebuf[100]; ttysfile = fopen(Etcttys, "r"); if(ttysfile == NULL) { fprintf(stderr, "Cannot open %s: %s\n", Etcttys, sys_errlist[errno]); exit(1); } ndevice = strlen(device); lnbeg = 0; foundit = 0; while(fgets(linebuf, sizeof(linebuf) - 1, ttysfile) != NULL) { if(strncmp(device, &linebuf[2], ndevice) == 0) { resettty = linebuf[0]; if(enable && resettty == '1' || !enable && resettty == '0') { fprintf(stderr, "%s already %sbled\n", device, enable ? "ena" : "disa"); exit(0); } foundit = 1; break; } lnbeg += strlen(linebuf); } if(foundit == 0) { fprintf(stderr, "%s not found in %s\n", device, Etcttys); exit(1); } (void)fclose(ttysfile); ittysfil = open(Etcttys, 1); if(ittysfil == NULL) { fprintf(stderr, "Cannot open %s for output: %s\n", Etcttys, sys_errlist[errno]); exit(1); } linebuf[0] = enable ? '1' : '0'; (void)lseek(ittysfil,lnbeg,0); if(write(ittysfil,&linebuf[0],1)<0) { fprintf(stderr,"On %s write: %s\n", Etcttys, sys_errlist[errno]); exit(1); } (void)close(ittysfil); } X/* * Excerpted from (June 8,1983 W.Sebok) * > ttymodem.c - enable/disable modem control for tty lines. * > * > Knows about DZ11s and DH11/DM11s. * > 23.3.83 - TS * > modified to know about DMF's (hasn't been tested) Nov 8,1984 - WLS */ setmodem(ttyline,enable) char *ttyline; int enable; { dev_t dev; int kmem; int unit,line,nlines,addr,tflags; struct uba_device *ubinfo; struct stat statb; short flags,devtype=0; struct cdevsw cdevsw; if(nl[CDEVSW].n_type == 0) { fprintf(stderr,"No namelist.\n"); return(-1); } if((kmem = open("/dev/kmem", 2)) < 0) { fprintf(stderr,"/dev/kmem open: %s\n", sys_errlist[errno]); return(-1); } if(stat(ttyline,&statb) < 0) { fprintf(stderr,"%s stat: %s\n", ttyline, sys_errlist[errno]); return(-1); } if(statb.st_mode&S_IFMT != S_IFCHR) { fprintf(stderr,"%s is not a character device.\n",ttyline); return(-1); } dev = statb.st_rdev; (void)lseek(kmem, (int) &(((struct cdevsw *)NLVALUE(CDEVSW))[major(dev)]),0); (void)read(kmem,(char *) &cdevsw,sizeof cdevsw); if((int)(cdevsw.d_open) == NLVALUE(DZOPEN)) { devtype = DZ11; unit = minor(dev) / NDZLINE; line = minor(dev) % NDZLINE; addr = (int) &(((int *)NLVALUE(DZINFO))[unit]); (void)lseek(kmem,(int) NLVALUE(NDZ11),0); } else if((int)(cdevsw.d_open) == NLVALUE(DHOPEN)) { devtype = DH11; unit = minor(dev) / NDHLINE; line = minor(dev) % NDHLINE; addr = (int) &(((int *)NLVALUE(DHINFO))[unit]); (void)lseek(kmem,(int) NLVALUE(NDH11),0); } else if((int)(cdevsw.d_open) == NLVALUE(DMFOPEN)) { devtype = DMF; unit = minor(dev) / NDMFLINE; line = minor(dev) % NDMFLINE; addr = (int) &(((int *)NLVALUE(DMFINFO))[unit]); (void)lseek(kmem,(int) NLVALUE(NDMF),0); } else { fprintf(stderr,"Device %s (%d/%d) unknown.\n",ttyline, major(dev),minor(dev)); return(-1); } (void)read(kmem,(char *) &nlines,sizeof nlines); if(minor(dev) >= nlines) { fprintf(stderr,"Sub-device %d does not exist (only %d).\n", minor(dev),nlines); return(-1); } (void)lseek(kmem,addr,0); (void)read(kmem,(char *) &ubinfo,sizeof ubinfo); (void)lseek(kmem,(int) &(ubinfo->ui_flags),0); (void)read(kmem,(char *) &flags,sizeof flags); tflags = 1<<line; resetmodem = ((flags&tflags) == 0); flags = enable ? (flags & ~tflags) : (flags | tflags); (void)lseek(kmem,(int) &(ubinfo->ui_flags),0); (void)write(kmem,(char *) &flags, sizeof flags); switch(devtype) { case DZ11: if((addr = NLVALUE(DZSCAR)) == 0) { fprintf(stderr,"No dzsoftCAR.\n"); return(-1); } (void)lseek(kmem,(int) &(((char *)addr)[unit]),0); (void)write(kmem,(char *) &flags, sizeof flags); break; case DH11: if((addr = NLVALUE(DHSCAR)) == 0) { fprintf(stderr,"No dhsoftCAR.\n"); return(-1); } (void)lseek(kmem,(int) &(((short *)addr)[unit]),0); (void)write(kmem,(char *) &flags, sizeof flags); break; case DMF: if((addr = NLVALUE(DMFSCAR)) == 0) { fprintf(stderr,"No dmfsoftCAR.\n"); return(-1); } (void)lseek(kmem,(int) &(((short *)addr)[unit]),0); (void)write(kmem,(char *) &flags,2); break; default: fprintf(stderr,"Unknown device type\n"); return(-1); } return(0); } prefix(s1, s2) register char *s1, *s2; { register char c; while ((c = *s1++) == *s2++) if (c == '\0') return (1); return (c == '\0'); } //go.sysin dd * made=TRUE if [ $made = TRUE ]; then /bin/chmod 644 acucntrl.c /bin/echo -n ' '; /bin/ls -ld acucntrl.c fi /bin/echo 'Extracting uucp.DIFF' sed 's/^X//' <<'//go.sysin dd *' >uucp.DIFF diff -rc ORIG/usr.bin/uucp/cico.c /usr/src/usr.bin/uucp/cico.c *** ORIG/usr.bin/uucp/cico.c Wed Nov 2 18:51:44 1983 *************** *** 409,414 } alarm(0); clsacu(); /* rti!trt: is this needed? */ } next: if (!onesys) { --- 426,432 ----- } alarm(0); clsacu(); /* rti!trt: is this needed? */ + /* astrovax!wls: for dialin/out YES!!!! */ } next: if (!onesys) { *************** *** 444,449 ret = ioctl(0, TCSETA, &Savettyb); #endif #ifndef SYSIII /* rti!trt: use more robust hang up sequence */ ret = ioctl(0, TIOCHPCL, STBNULL); ret = ioctl(0, TIOCGETP, &Hupvec); --- 462,473 ----- ret = ioctl(0, TCSETA, &Savettyb); #endif #ifndef SYSIII + #ifdef TIOCSDTR /* WLS 3/2/84 */ + (void)ioctl(0, TIOCCDTR, STBNULL); + sleep(2); + (void)ioctl(0, TIOCSDTR, STBNULL); + (void)ioctl(0, TIOCHPCL, STBNULL); + #else TIOCSDTR /* rti!trt: use more robust hang up sequence */ ret = ioctl(0, TIOCHPCL, STBNULL); ret = ioctl(0, TIOCGETP, &Hupvec); *************** *** 465,470 close(Ifn); close(Ofn); } DEBUG(1, "exit code %d\n", code); if (code == 0) xuuxqt(); --- 493,502 ----- close(Ifn); close(Ofn); } + #ifdef DIALINOUT + /* reenable logins on dialout (WLS Mar 3, 1984) */ + reenable(); + #endif DEBUG(1, "exit code %d\n", code); if (code == 0) xuuxqt(); diff -rc ORIG/usr.bin/uucp/condevs.c /usr/src/usr.bin/uucp/condevs.c *** ORIG/usr.bin/uucp/condevs.c Sat Aug 13 13:23:31 1983 --- /usr/src/usr.bin/uucp/condevs.c Wed Nov 28 14:31:07 1984 *************** *** 193,198 delock(dev.D_line); return(FAIL); } fflush(stdout); fixline(dcr, dev.D_speed); strcpy(devSel, dev.D_line); /* for latter unlock */ --- 193,204 ----- delock(dev.D_line); return(FAIL); } + #ifdef TIOCSPGRP + { /* fix for mysterious "EIO" on read error */ + int pgrp = getpgrp(0); + ioctl(dcr, TIOCSPGRP, &pgrp); + } + #endif fflush(stdout); fixline(dcr, dev.D_speed); strcpy(devSel, dev.D_line); /* for latter unlock */ *************** *** 406,411 } } } fclose(dfp); if (dh < 0) return(CF_NODEV); --- 412,423 ----- } } } + #ifdef TIOCSPGRP + { /* fix for mysterious "EIO" on read error */ + int pgrp = getpgrp(0); + ioctl(dh, TIOCSPGRP, &pgrp); + } + #endif fclose(dfp); if (dh < 0) return(CF_NODEV); *************** *** 478,488 register FILE *dfp; struct Devices dev; ! exphone(flds[F_PHONE], phone); ! devSel[0] = '\0'; ! DEBUG(4, "Dialing %s\n", phone); ! dfp = fopen(DEVFILE, "r"); ! ASSERT(dfp != NULL, "Can't open", DEVFILE, 0); for(cd = condevs; cd->CU_meth != NULL; cd++) { if (snccmp(flds[F_LINE], cd->CU_meth) == SAME) { --- 491,501 ----- struct Devices dev; + int success = 0; ! exphone(flds[F_PHONE], phone); ! devSel[0] = '\0'; ! DEBUG(4, "Dialing %s\n", phone); ! dfp = fopen(DEVFILE, "r"); ! ASSERT(dfp != NULL, "Can't open", DEVFILE, 0); fseek(dfp, (off_t)0, 0); while(rddev(dfp, &dev) != FAIL) { *************** *** 484,493 dfp = fopen(DEVFILE, "r"); ASSERT(dfp != NULL, "Can't open", DEVFILE, 0); ! for(cd = condevs; cd->CU_meth != NULL; cd++) { ! if (snccmp(flds[F_LINE], cd->CU_meth) == SAME) { ! fseek(dfp, (off_t)0, 0); ! while(rddev(dfp, &dev) != FAIL) { if (strcmp(flds[F_CLASS], dev.D_class) != SAME) continue; if (snccmp(flds[F_LINE], dev.D_type) != SAME) --- 497,504 ----- dfp = fopen(DEVFILE, "r"); ASSERT(dfp != NULL, "Can't open", DEVFILE, 0); ! fseek(dfp, (off_t)0, 0); ! while(rddev(dfp, &dev) != FAIL) { if (strcmp(flds[F_CLASS], dev.D_class) != SAME) continue; if (snccmp(flds[F_LINE], dev.D_type) != SAME) *************** *** 496,501 if (dev.D_brand[0] == '\0') logent("Acuopn","No 'brand' name on ACU"); ! else if (snccmp(dev.D_brand, cd->CU_brand) != SAME) ! continue; if (mlock(dev.D_line) == FAIL) continue; --- 508,522 ----- if (dev.D_brand[0] == '\0') { logent("Acuopn","No 'brand' name on ACU"); ! continue; ! } ! for(cd = condevs; cd->CU_meth != NULL; cd++) { ! if (snccmp(flds[F_LINE], cd->CU_meth) == SAME ! && snccmp(dev.D_brand, cd->CU_brand) == SAME) ! break; ! } ! if (cd->CU_meth == NULL) { ! logent(dev.D_brand,"unsupported ACU type"); ! continue; ! } ! if (mlock(dev.D_line) == FAIL) continue; *************** *** 499,504 if (mlock(dev.D_line) == FAIL) continue; DEBUG(4, "Using %s\n", cd->CU_brand); fd = (*(cd->CU_open))(phone, flds, &dev); if (fd > 0) { --- 520,539 ----- if (mlock(dev.D_line) == FAIL) continue; + #ifdef DIALINOUT + if (snccmp("inout",dev.D_calldev) == 0 + && disable(dev.D_line) == FAIL) { + delock(dev.D_line); + continue; + } + #endif + success++; + break; + } + + fclose(dfp); + + if (success) { DEBUG(4, "Using %s\n", cd->CU_brand); fd = (*(cd->CU_open))(phone, flds, &dev); if (fd > 0) { *************** *** 502,513 DEBUG(4, "Using %s\n", cd->CU_brand); fd = (*(cd->CU_open))(phone, flds, &dev); if (fd > 0) { ! CU_end = cd->CU_clos; /* point CU_end at close func */ ! fclose(dfp); ! strcpy(devSel, dev.D_line); /* save for later unlock() */ ! return(fd); ! } ! delock(dev.D_line); } } } --- 537,547 ----- DEBUG(4, "Using %s\n", cd->CU_brand); fd = (*(cd->CU_open))(phone, flds, &dev); if (fd > 0) { ! CU_end = cd->CU_clos; /* point CU_end at close func */ ! strcpy(devSel, dev.D_line); /* save for later unlock()*/ ! return(fd); ! } else { ! delock(dev.D_line); } } return(FAIL); *************** *** 509,515 } delock(dev.D_line); } - } } fclose(dfp); return(FAIL); --- 543,548 ----- } else { delock(dev.D_line); } } return(FAIL); } *************** *** 511,519 } } } ! fclose(dfp); ! return(FAIL); ! } #ifdef DN11 --- 544,551 ----- delock(dev.D_line); } } ! return(FAIL); ! } #ifdef DN11 *************** *** 850,855 /* modem is open */ next_fd = -1; if (dh >= 0) { fixline(dh, dev->D_speed); #ifdef HAYSTONE write(dh, "\rATDT", 5); --- 885,895 ----- /* modem is open */ next_fd = -1; if (dh >= 0) { + #ifdef TIOCSPGRP + /* fix for mysterious "EIO" on read error */ + int pgrp = getpgrp(0); + ioctl(dh, TIOCSPGRP, &pgrp); + #endif fixline(dh, dev->D_speed); if (hayes_sync(dh) == FAIL) { logent(dev->D_line,"Cannot sync Hayes"); *************** *** 978,983 alarm(0); next_fd = -1; fixline(dnf, dev->D_speed); DEBUG(4, "Hayes port - %s, ", dcname); --- 1116,1128 ----- alarm(0); next_fd = -1; + #ifdef TIOCSPGRP + { + /* fix for mysterious "EIO" on read error */ + int pgrp = getpgrp(0); + ioctl(dnf, TIOCSPGRP, &pgrp); + } + #endif fixline(dnf, dev->D_speed); DEBUG(4, "Hayes port - %s, ", dcname); *************** *** 1394,1399 i = CF_NODEV; goto ret; } fixline(va, dev->D_speed); p_chwrite(va, STX); /* access adaptor */ --- 1525,1536 ----- i = CF_NODEV; goto ret; } + #if TIOCSPGRP + { /* fix for mysterious "EIO" on read error */ + int pgrp = getpgrp(0); + ioctl(va, TIOCSPGRP, &pgrp); + } + #endif fixline(va, dev->D_speed); p_chwrite(va, STX); /* access adaptor */ *************** *** 1459,1464 logent("dialup open", "FAILED"); goto failret; } fixline(i, dev->D_speed); goto ret; failret: --- 1596,1607 ----- logent("dialup open", "FAILED"); goto failret; } + #ifdef TIOCSPGRP + { /* fix for mysterious "EIO" on read error */ + int pgrp = getpgrp(0); + ioctl(i, TIOCSPGRP, &pgrp); + } + #endif fixline(i, dev->D_speed); goto ret; failret: *************** *** 1478,1482 p_chwrite(fd, SOH); /* ioctl(fd, TIOCCDTR, NULL);*/ close(fd); } #endif --- 1621,1773 ----- p_chwrite(fd, SOH); /* ioctl(fd, TIOCCDTR, NULL);*/ close(fd); + } + #endif + + #ifdef DIALINOUT + /* DIALIN/OUT CODE (WLS) */ + /*************************************************************************** + * disable and reenable: allow a single line to be use for dialin/dialout * + ***************************************************************************/ + + char enbdev[16]; + + disable(dev) + register char *dev; + { + register char *rdev; + + /* strip of directory prefixes */ + rdev = dev; + while (*rdev) rdev++; + while (--rdev >= dev && *rdev != '/'); + rdev++; + + + if (enbdev[0]) { + if (strcmp(enbdev,rdev) == 0) + return(SUCCESS); /* already disabled */ + delock(enbdev); + reenable(); /* else, reenable the old one */ + } + DEBUG(4, "Disable %s\n", rdev); + if (enbcall("disable", rdev) == FAIL) + return(FAIL); + logent(rdev, "DISABLED LOGIN"); + strcpy(enbdev,rdev); + return(SUCCESS); + } + + reenable() + { + if (enbdev[0] == NULL) return; + DEBUG(4, "Reenable %s\n", enbdev); + (void)enbcall("enable", enbdev); + logent(enbdev, "REENABLED LOGIN"); + enbdev[0] = '\0'; + } + + enbcall(type, dev) + char *type, *dev; + { + register int pid; + int status; + + if ((pid = fork()) == 0) { + DEBUG(4, ACUPROG, 0); + DEBUG(4, " %s", type); + DEBUG(4, " %s\n", dev); + setuid(geteuid()); /* for chown(uid()) in acu program */ + execl(ACUPROG, "acu", type, dev, 0); + exit(999); + } + while(wait(&status) != pid); + return(status ? FAIL : SUCCESS); + } diff -rc ORIG/usr.bin/uucp/uucp.h /usr/src/usr.bin/uucp/uucp.h *** ORIG/usr.bin/uucp/uucp.h Tue Jul 26 23:58:08 1983 --- /usr/src/usr.bin/uucp/uucp.h Sun Dec 2 23:30:30 1984 *************** *** 113,119 /* All users with getuid() <= PRIV_UIDS are 'privileged'. */ /* Was 10, reduced to 3 as suggested by duke!dbl (David Leonard) */ #define PRIV_UIDS 3 #define XQTDIR "/usr/spool/uucp/XTMP" #define SQFILE "/usr/lib/uucp/SQFILE" --- 116,132 ----- /* All users with getuid() <= PRIV_UIDS are 'privileged'. */ /* Was 10, reduced to 3 as suggested by duke!dbl (David Leonard) */ #define PRIV_UIDS 3 ! /* program to disable/reenable logins on dialout line (Mar 3,1984 WLS) */ ! #define ACUPROG "/usr/local/lib/acucntrl" ! #ifdef ACUPROG ! # define DIALINOUT ! #endif #define XQTDIR "/usr/spool/uucp/XTMP" #define SQFILE "/usr/lib/uucp/SQFILE" //go.sysin dd * made=TRUE if [ $made = TRUE ]; then /bin/chmod 644 uucp.DIFF /bin/echo -n ' '; /bin/ls -ld uucp.DIFF fi /bin/echo 'Extracting tip.DIFF' sed 's/^X//' <<'//go.sysin dd *' >tip.DIFF diff -rc ORIG/usr.bin/tip/cu.c /usr/src/usr.bin/tip/cu.c *** ORIG/usr.bin/tip/cu.c Tue Jun 28 03:33:09 1983 --- /usr/src/usr.bin/tip/cu.c Mon May 28 20:23:25 1984 *************** *** 82,88 setbuf(stdout, NULL); loginit(); setuid(getuid()); ! setgid(getgid()); vinit(); setparity("none"); boolean(value(VERBOSE)) = 0; --- 82,88 ----- setbuf(stdout, NULL); loginit(); setuid(getuid()); ! /* setgid(getgid()); */ vinit(); setparity("none"); boolean(value(VERBOSE)) = 0; diff -rc ORIG/usr.bin/tip/remote.c /usr/src/usr.bin/tip/remote.c *** ORIG/usr.bin/tip/remote.c Sat Jun 25 04:19:16 1983 --- /usr/src/usr.bin/tip/remote.c Sat Jun 2 00:40:49 1984 *************** *** 121,126 { register char *cp; static char *next; static int lookedup = 0; if (!lookedup) { --- 123,131 ----- { register char *cp; static char *next; + static char *nextat; /* next AT */ static int lookedup = 0; if (!lookedup) { *************** *** 130,135 } getremcap(host); next = DV; lookedup++; } /* --- 135,143 ----- } getremcap(host); next = DV; + nextat = AT; lookedup++; } /* *************** *** 146,150 DV = next; next = cp; } return (DV); } --- 154,165 ----- DV = next; next = cp; } + if (nextat != NOSTR) { + AT = nextat; + if ((nextat = index(nextat,',')) != NOSTR) + *nextat++ = '\0'; + } return (DV); } =================================== diff -rc ORIG/usr.bin/tip/tip.c /usr/src/usr.bin/tip/tip.c *** ORIG/usr.bin/tip/tip.c Tue Jun 28 03:33:11 1983 --- /usr/src/usr.bin/tip/tip.c Mon May 28 21:14:01 1984 *************** *** 82,87 signal(SIGHUP, cleanup); signal(SIGTERM, cleanup); if ((i = hunt(system)) == 0) { printf("all ports busy\n"); exit(3); --- 82,90 ----- signal(SIGHUP, cleanup); signal(SIGTERM, cleanup); + setbuf(stdout, NULL); + loginit(); + if ((i = hunt(system)) == 0) { printf("all ports busy\n"); exit(3); *************** *** 91,98 delock(uucplock); exit(3); } - setbuf(stdout, NULL); - loginit(); /* * Now that we have the logfile and the ACU open * return to the real uid and gid. These things will --- 94,99 ----- delock(uucplock); exit(3); } /* * Now that we have the logfile and the ACU open * return to the real uid and gid. These things will *************** *** 100,106 * because locking mechanism on the tty and the accounting * will be bypassed. */ ! setgid(getgid()); setuid(getuid()); /* --- 101,107 ----- * because locking mechanism on the tty and the accounting * will be bypassed. */ ! /* setgid(getgid()); */ setuid(getuid()); /* ====================== diff -rc ORIG/usr.bin/tip/uucplock.c /usr/src/usr.bin/tip/uucplock.c *** ORIG/usr.bin/tip/uucplock.c Sat Jun 25 04:19:18 1983 --- /usr/src/usr.bin/tip/uucplock.c Sun Dec 2 23:37:34 1984 *************** *** 4,10 /* * defs that come from uucp.h */ ! #define NAMESIZE 15 #define FAIL -1 #define SAME 0 #define SLCKTIME 28800 /* system/device timeout (LCK.. files) in seconds (8 hours) */ --- 4,12 ----- /* * defs that come from uucp.h */ ! /* program to enable/disable devices */ ! #define ACUPROG "/usr/local/lib/acucntrl" ! #define NAMESIZE 40 #define FAIL -1 #define SAME 0 #define SLCKTIME 28800 /* system/device timeout (LCK.. files) in seconds (8 hours) */ *************** *** 180,186 } /*** ! * delock(s) remove a lock file * char *s; * * return codes: 0 | FAIL --- 182,188 ----- } /*** ! * delock(s) remove a lock file and reenable logins * char *s; * * no return codes *************** *** 190,196 char *s; { char ln[30]; ! sprintf(ln, "%s.%s", LOCKPRE, s); rmlock(ln); } --- 192,199 ----- char *s; { char ln[30]; ! if (strncmp(s, "ttyd", 4) == 0) ! reenable(s); sprintf(ln, "%s.%s", LOCKPRE, s); rmlock(ln); } *************** *** 196,202 } /*** ! * mlock(sys) create system lock * char *sys; * * return codes: 0 | FAIL --- 199,205 ----- } /*** ! * mlock(sys) create system lock and disable logins on port * char *sys; * * return codes: 0 | FAIL *************** *** 207,211 { char lname[30]; sprintf(lname, "%s.%s", LOCKPRE, sys); ! return (ulockf(lname, (time_t) SLCKTIME ) < 0 ? FAIL : 0); } --- 210,268 ----- { char lname[30]; sprintf(lname, "%s.%s", LOCKPRE, sys); ! if (ulockf(lname, (time_t) SLCKTIME ) < 0) ! return(FAIL); ! if (strncmp(sys, "ttyd", 4)!=0) ! return(0); ! if (disable(sys) == 0) ! return(0); ! return(FAIL); ! } ! ! /*************************************************************************** ! * disable and reenable: allow a single line to be use for dialin/dialout * ! * routines added by David Sebok 4/15/84 based on those created by * ! * William Sebok * ! ***************************************************************************/ ! ! static int disableflg=0; ! disable(dev) ! register char *dev; ! { ! printf("disabling %s...",dev); ! fflush(stdout); ! if (enbcall("disable", dev) == FAIL) { ! printf("could not disable %s\n",dev); ! return(FAIL); ! } ! disableflg=1; ! printf(" done\n"); ! return(0); ! } ! ! reenable(dev) ! register char *dev; ! { ! if (disableflg==0) ! return(FAIL); ! printf("reenabling %s...",dev); ! if (enbcall("enable", dev) == FAIL) ! return(FAIL); ! printf(" done\n\r"); ! return(0); ! } ! ! enbcall(type, dev) ! char *type, *dev; ! { ! register int pid; ! int status; ! ! if ((pid = fork()) == 0) { ! setuid(getuid()); /* for chown(uid()) in acu program */ ! execl(ACUPROG, "acu", type, dev, 0); ! exit(9); ! } ! while(wait(&status) != pid); ! return(status ? FAIL : 0); /*FAIL if ACU exits other than 0 */ } ========== //go.sysin dd * made=TRUE if [ $made = TRUE ]; then /bin/chmod 644 tip.DIFF /bin/echo -n ' '; /bin/ls -ld tip.DIFF fi -- Bill Sebok Princeton University, Astrophysics {allegra,akgua,burl,cbosgd,decvax,ihnp4,noao,princeton,vax135}!astrovax!wls