diff options
author | rgrimes <rgrimes@FreeBSD.org> | 1994-05-27 12:33:43 +0000 |
---|---|---|
committer | rgrimes <rgrimes@FreeBSD.org> | 1994-05-27 12:33:43 +0000 |
commit | f9ab90d9d6d02989a075d0f0074496d5b1045e4b (patch) | |
tree | add7e996bac5289cdc55e6935750c352505560a9 /usr.bin/uucp | |
parent | be22b15ae2ff8d7fe06b6e14fddf0c5b444a95da (diff) | |
download | FreeBSD-src-f9ab90d9d6d02989a075d0f0074496d5b1045e4b.zip FreeBSD-src-f9ab90d9d6d02989a075d0f0074496d5b1045e4b.tar.gz |
BSD 4.4 Lite Usr.bin Sources
Diffstat (limited to 'usr.bin/uucp')
-rw-r--r-- | usr.bin/uucp/acucntrl/Makefile | 10 | ||||
-rw-r--r-- | usr.bin/uucp/acucntrl/acucntrl.8 | 164 | ||||
-rw-r--r-- | usr.bin/uucp/acucntrl/acucntrl.c | 814 | ||||
-rw-r--r-- | usr.bin/uucp/uupoll/Makefile | 10 | ||||
-rw-r--r-- | usr.bin/uucp/uupoll/uupoll.8 | 111 | ||||
-rw-r--r-- | usr.bin/uucp/uupoll/uupoll.c | 129 | ||||
-rw-r--r-- | usr.bin/uucp/uuq/Makefile | 9 | ||||
-rw-r--r-- | usr.bin/uucp/uuq/uuq.1 | 126 | ||||
-rw-r--r-- | usr.bin/uucp/uuq/uuq.c | 435 | ||||
-rw-r--r-- | usr.bin/uucp/uusend/Makefile | 6 | ||||
-rw-r--r-- | usr.bin/uucp/uusend/uusend.1 | 96 | ||||
-rw-r--r-- | usr.bin/uucp/uusend/uusend.c | 403 | ||||
-rw-r--r-- | usr.bin/uucp/uusnap/Makefile | 8 | ||||
-rw-r--r-- | usr.bin/uucp/uusnap/uusnap.8 | 80 | ||||
-rw-r--r-- | usr.bin/uucp/uusnap/uusnap.c | 348 |
15 files changed, 2749 insertions, 0 deletions
diff --git a/usr.bin/uucp/acucntrl/Makefile b/usr.bin/uucp/acucntrl/Makefile new file mode 100644 index 0000000..85bbfe4 --- /dev/null +++ b/usr.bin/uucp/acucntrl/Makefile @@ -0,0 +1,10 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= acucntrl +CFLAGS+=-I${.CURDIR}/../includes +BINDIR= ${LIBDIR} +BINOWN= root +BINMODE=6550 +MAN8= acucntrl.0 + +.include <bsd.prog.mk> diff --git a/usr.bin/uucp/acucntrl/acucntrl.8 b/usr.bin/uucp/acucntrl/acucntrl.8 new file mode 100644 index 0000000..57ce495 --- /dev/null +++ b/usr.bin/uucp/acucntrl/acucntrl.8 @@ -0,0 +1,164 @@ +.\" Copyright (c) 1985, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)acucntrl.8 8.2 (Berkeley) 12/11/93 +.\" +.TH ACUCNTRL 8 "December 11, 1993" +.UC 6 +.SH NAME +acucntrl \- turn around tty line between dialin and dialout +.SH SYNOPSIS +.B /usr/lib/uucp/acucntrl +keyword ttyline +.SH DESCRIPTION +.PP +.I Acucntrl +turns around the 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. +.PP +This program must be run setuid to root. +.PP +.I keyword +is chosen from the list: +.I disable +or +.IR dialout , +to condition a line for dialout; +and +.I enable +or +.IR dialin , +to condition a line for dialin. +.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. +.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), +and if the process is not running as the superuser. +The last condition is to allow the superuser to clear the state of the line. +.PP +Turning modem control on or off is handled by poking into /dev/kmem. +It is currently implemented for dz, dh, and dmf lines. +.PP +Under 4.2 BSD the program will also refuse to disable a line if carrier is +sensed on it. This is to avoid the dead period where someone has just dialed +in and made the connection but has not yet logged in. +.PP +.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. +.PP +Steps taken when disabling +.RI ( i . e . +setup for dialing out) +.IP 1) +check input arguments +.IP 2) +look in /etc/utmp to check that the line is not in use by another user +.IP 3) +disable modem control on line +.IP 4) +check for carrier on device +.IP 5) +change owner of device to real uid +.IP 6) +edit /etc/ttys, changing the first character of the appropriate line to 0 +.IP 7) +send a hangup to process 1 to poke init to disable getty +.IP 8) +post uid name in capitals in /etc/utmp to let world know device has been grabbed +.IP 9) +make sure that DTR is on +.PP +Steps taken when enabling +.RI ( i . e . +setup for dialing in) +.IP 1) +check input arguments +.IP 2) +look in /etc/utmp to check that the line is not in use by another user +.IP 3) +make sure modem control on line is disabled +.IP 4) +turn off DTR to make sure line is hung up +.IP 5) +condition line: clear exclusive use and set hangup on close modes +.IP 6) +turn on modem control +.IP 7) +edit /etc/ttys, changing the first character of the appropriate line to 1 +.IP 8) +send a hangup to process 1 to poke init to enable getty +.IP 9) +clear uid name for /etc/utmp +.SH HISTORY +.PP +First written by Allan Wilkes (fisher!allan) +.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 +.PP +Worked over many times by W.Sebok +.RI ( i . e . +hacked to death) +.SH FILES +/dev/kmem, /vmunix, /etc/ttys, /etc/utmp, /dev/tty* +.SH BUGS +.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. +.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. +.PP +Previously there were similar synchronization problems 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. diff --git a/usr.bin/uucp/acucntrl/acucntrl.c b/usr.bin/uucp/acucntrl/acucntrl.c new file mode 100644 index 0000000..deba6ba --- /dev/null +++ b/usr.bin/uucp/acucntrl/acucntrl.c @@ -0,0 +1,814 @@ +/*- + * Copyright (c) 1985, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1985, 1986, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)acucntrl.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* 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 _PATH_UTMP to check that the line is not in use by another + * (3) disable modem control on terminal + * (4) check for carrier on device + * (5) change owner of device to real id + * (6) edit _PATH_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 _PATH_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 _PATH_UTMP to check that the line is not in use by another + * (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 _PATH_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 _PATH_UTMP + */ + +/* #define SENSECARRIER */ + +#include "uucp.h" +#ifdef DIALINOUT +#include <sys/buf.h> +#include <signal.h> +#include <sys/conf.h> +#ifdef vax +#ifdef BSD4_2 +#include <vaxuba/ubavar.h> +#else +#include <sys/ubavar.h> +#endif +#endif /* vax */ +#include <sys/stat.h> +#include <nlist.h> +#include <sgtty.h> +#include <utmp.h> +#include <pwd.h> +#include <stdio.h> +#include <sys/file.h> +#include "pathnames.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 Etcttys[] = _PATH_TTYS; +#ifdef BSD4_3 +FILE *ttysfile, *nttysfile; +char NEtcttys[] = _PATH_NEWTTYS; +extern long ftell(); +#endif BSD4_3 +char Devhome[] = _PATH_DEV; + +char usage[] = "Usage: acucntrl {dis|en}able ttydX\n"; + +struct utmp utmp; +char resettty, resetmodem; +int etcutmp; +off_t utmploc; +off_t ttyslnbeg; +extern int errno; +extern char *sys_errlist[]; +off_t lseek(); + +#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; + struct passwd *getpwuid(); + char *rindex(); + + /* check input arguments */ + if (argc!=3 && argc != 4) { + fprintf(stderr, usage); + exit(1); + } + + /* interpret command type */ + 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; + + opnttys(device); + +#ifdef vax + /* Get nlist info */ + nlist(_PATH_UNIX, nl); +#endif vax + + /* 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); + } + + if (strcmp(p, "uucp") == 0 && argc == 4) + p = argv[3]; + + /* to upper case */ + i = 0; + do { + uname[i] = *p; + Uname[i++] = (*p>='a' && *p<='z') ? (*p - ('a'-'A')) : *p; + } while (*p++ && i<NAMSIZ); + + /* check to see if line is being used */ + if( (etcutmp = open(_PATH_UTMP, 2)) < 0) { + fprintf(stderr, "On open %s open: %s\n", + _PATH_UTMP, sys_errlist[errno]); + exit(1); + } + + (void)lseek(etcutmp, utmploc, 0); + + i = read(etcutmp, (char *)&utmp, sizeof(struct utmp)); + + if( + i == sizeof(struct utmp) && + utmp.ut_line[0] != '\0' && + utmp.ut_name[0] != '\0' && + ( + !upcase(utmp.ut_name, NAMSIZ) || + ( + uid != 0 && + strncmp(utmp.ut_name, Uname, NAMSIZ) != 0 + ) + ) + ) { + fprintf(stderr, "%s in use by %s\n", device, utmp.ut_name); + exit(2); + } + +#ifndef sequent + /* Disable modem control */ + if (setmodem(device, DISABLE) < 0) { + fprintf(stderr, "Unable to disable modem control\n"); + exit(1); + } +#endif !sequent + + if (enable) { +#ifdef sequent + if (setmodem(device, ENABLE) < 0) { + fprintf(stderr, "Cannot Enable modem control\n"); + (void)setmodem(device, i); + exit(1); + } +#endif sequent +#ifndef sequent + 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, (int)TIOCCDTR, (char *)0) < 0) + fprintf(stderr, "On TIOCCDTR ioctl: %s\n", + sys_errlist[errno]); + + if (ioctl(devfile, (int)TIOCNXCL, (char *)0) < 0) + fprintf(stderr, + "Cannot clear Exclusive Use on %s: %s\n", + device, sys_errlist[errno]); + + if (ioctl(devfile, (int)TIOCHPCL, (char *)0) < 0) + fprintf(stderr, + "Cannot set hangup on close on %s: %s\n", + device, sys_errlist[errno]); + +#endif !sequent + i = resetmodem; + +#ifndef sequent + if (setmodem(device, ENABLE) < 0) { + fprintf(stderr, "Cannot Enable modem control\n"); + (void)setmodem(device, i); + exit(1); + } +#endif sequent + resetmodem=i; + + if (settys(ENABLE)) { + fprintf(stderr, "%s already enabled\n", device); + } else { + pokeinit(device, Uname, enable); + } + post(device, ""); + + } else { +#if defined(TIOCMGET) && defined(SENSECARRIER) + if (uid!=0) { + int linestat = 0; + + /* check for presence of carrier */ + sleep(2); /* need time after modem control turnoff */ + + if((devfile = open(device, 1)) < 0) { + fprintf(stderr, "On open of %s: %s\n", + device, sys_errlist[errno]); + (void)setmodem(device, resetmodem); + exit(1); + } + + (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); + } + (void)close(devfile); + } +#endif TIOCMGET + /* chown device */ + if(chown(device, uid, gid) < 0) + fprintf(stderr, "Cannot chown %s: %s\n", + device, sys_errlist[errno]); + + + /* poke init */ + if(settys(DISABLE)) { + fprintf(stderr, "%s already disabled\n", device); + } else { + pokeinit(device, Uname, enable); + } + post(device, Uname); +#ifdef sequent + /* Disable modem control */ + if (setmodem(device, DISABLE) < 0) { + fprintf(stderr, "Unable to disable modem control\n"); + exit(1); + } +#endif sequent + if((devfile = open(device, O_RDWR|O_NDELAY)) < 0) { + fprintf(stderr, "On %s open: %s\n", + device, sys_errlist[errno]); + } else { + if(ioctl(devfile, (int)TIOCSDTR, (char *)0) < 0) + fprintf(stderr, + "Cannot set DTR on %s: %s\n", + device, sys_errlist[errno]); + } + } + + exit(0); +} + +/* 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); +} + +/* Post name to public */ +post(device, name) +char *device, *name; +{ + (void)time((time_t *)&utmp.ut_time); + strncpy(utmp.ut_line, device, LINSIZ); + strncpy(utmp.ut_name, name, NAMSIZ); + if (lseek(etcutmp, utmploc, 0) < 0) + fprintf(stderr, "on lseek in %s: %s", + _PATH_UTMP, sys_errlist[errno]); + if (write(etcutmp, (char *)&utmp, sizeof(utmp)) < 0) + fprintf(stderr, "on write in %s: %s", + _PATH_UTMP, sys_errlist[errno]); +} + +/* poke process 1 and wait for it to do its thing */ +pokeinit(device, uname, enable) +char *uname, *device; int enable; +{ + struct utmp utmp; + register int i; + + post(device, uname); + + /* poke init */ + if (kill(1, SIGHUP)) { + fprintf(stderr, + "Cannot send hangup to init process: %s\n", + sys_errlist[errno]); + (void)settys(resettty); + (void)setmodem(device, resetmodem); + exit(1); + } + + if (enable) + return; + + /* wait till init has responded, clearing the utmp entry */ + i = 100; + do { + sleep(1); + if (lseek(etcutmp, utmploc, 0) < 0) + fprintf(stderr, "On lseek in %s: %s", + _PATH_UTMP, sys_errlist[errno]); + if (read(etcutmp, (char *)&utmp, sizeof utmp) < 0) + fprintf(stderr, "On read from %s: %s", + _PATH_UTMP, sys_errlist[errno]); + } while (utmp.ut_name[0] != '\0' && --i > 0); +} + +#ifdef BSD4_3 +/* identify terminal line in ttys */ +opnttys(device) +char *device; +{ + register int ndevice; + register char *p; + char *index(); + char linebuf[BUFSIZ]; + + ttysfile = NULL; + do { + if (ttysfile != NULL) { + fclose(ttysfile); + sleep(5); + } + ttysfile = fopen(Etcttys, "r"); + if(ttysfile == NULL) { + fprintf(stderr, "Cannot open %s: %s\n", Etcttys, + sys_errlist[errno]); + exit(1); + } + } while (flock(fileno(ttysfile), LOCK_NB|LOCK_EX) < 0); + nttysfile = fopen(NEtcttys, "w"); + if(nttysfile == NULL) { + fprintf(stderr, "Cannot open %s: %s\n", Etcttys, + sys_errlist[errno]); + exit(1); + } + + ndevice = strlen(device); +#ifndef BRL4_2 + utmploc = sizeof(utmp); +#else BRL4_2 + utmploc = 0; +#endif BRL4_2 + + while(fgets(linebuf, sizeof(linebuf) - 1, ttysfile) != NULL) { + if(strncmp(device, linebuf, ndevice) == 0) + return; + ttyslnbeg += strlen(linebuf); + if (linebuf[0] != '#' && linebuf[0] != '\0') + utmploc += sizeof(utmp); + if (fputs(linebuf, nttysfile) == NULL) { + fprintf(stderr, "On %s write: %s\n", + Etcttys, sys_errlist[errno]); + exit(1); + } + + } + fprintf(stderr, "%s not found in %s\n", device, Etcttys); + exit(1); +} + +/* modify appropriate line in _PATH_TTYS to turn on/off the device */ +settys(enable) +int enable; +{ + register char *cp, *cp2; + char lbuf[BUFSIZ]; + int i; + char c1, c2; + + (void) fseek(ttysfile, ttyslnbeg, 0); + if(fgets(lbuf, BUFSIZ, ttysfile) == NULL) { + fprintf(stderr, "On %s read: %s\n", + Etcttys, sys_errlist[errno]); + exit(1); + } + /* format is now */ + /* ttyd0 std.100 dialup on secure # comment */ + /* except, 2nd item may have embedded spaces inside quotes, Hubert */ + cp = lbuf; + for (i=0;*cp && i<3;i++) { + if (*cp == '"') { + cp++; + while (*cp && *cp != '"') + cp++; + if (*cp != '\0') + cp++; + }else { + while (*cp && *cp != ' ' && *cp != '\t') + cp++; + } + while (*cp && (*cp == ' ' || *cp == '\t')) + cp++; + } + if (*cp == '\0') { + fprintf(stderr,"Badly formatted line in %s:\n%s", + _PATH_TTYS, lbuf); + exit(1); + } + c1 = *--cp; + *cp++ = '\0'; + cp2 = cp; + while (*cp && *cp != ' ' && *cp != '\t' && *cp != '\n') + cp++; + if (*cp == '\0') { + fprintf(stderr,"Badly formatted line in %s:\n%s", + _PATH_TTYS, lbuf); + exit(1); + } + c2 = *cp; + *cp++ = '\0'; + while (*cp && (*cp == ' ' || *cp == '\t')) + cp++; + resettty = strcmp("on", cp2) != 0; + fprintf(nttysfile,"%s%c%s%c%s", lbuf, c1, enable ? "on" : "off", c2, cp); + if (ferror(nttysfile)) { + fprintf(stderr, "On %s fprintf: %s\n", + NEtcttys, sys_errlist[errno]); + exit(1); + } + while(fgets(lbuf, sizeof(lbuf) - 1, ttysfile) != NULL) { + if (fputs(lbuf, nttysfile) == NULL) { + fprintf(stderr, "On %s write: %s\n", + NEtcttys, sys_errlist[errno]); + exit(1); + } + } + + if (enable^resettty) + (void) unlink(NEtcttys); + else { + struct stat statb; + if (stat(Etcttys, &statb) == 0) { + fchmod(fileno(nttysfile) ,statb.st_mode); + fchown(fileno(nttysfile), statb.st_uid, statb.st_gid); + } + (void) rename(NEtcttys, Etcttys); + } + (void) fclose(nttysfile); + (void) fclose(ttysfile); + return enable^resettty; +} + +#else !BSD4_3 + +/* identify terminal line in ttys */ +opnttys(device) +char *device; +{ + register FILE *ttysfile; + register int ndevice, lnsiz; + register char *p; + char *index(); + char linebuf[BUFSIZ]; + + ttysfile = fopen(Etcttys, "r"); + if(ttysfile == NULL) { + fprintf(stderr, "Cannot open %s: %s\n", Etcttys, + sys_errlist[errno]); + exit(1); + } + + ndevice = strlen(device); + ttyslnbeg = 0; + utmploc = 0; + + while(fgets(linebuf, sizeof(linebuf) - 1, ttysfile) != NULL) { + lnsiz = strlen(linebuf); + if ((p = index(linebuf, '\n')) != NULL) + *p = '\0'; + if(strncmp(device, &linebuf[2], ndevice) == 0) { + (void)fclose(ttysfile); +#ifdef sequent + /* Why is the sequent off by one? */ + utmploc += sizeof(utmp); +#endif sequent + return; + } + ttyslnbeg += lnsiz; + utmploc += sizeof(utmp); + } + fprintf(stderr, "%s not found in %s\n", device, Etcttys); + exit(1); +} + +/* modify appropriate line in _PATH_TTYS to turn on/off the device */ +settys(enable) +int enable; +{ + int ittysfil; + char out, in; + + ittysfil = open(Etcttys, 2); + if(ittysfil < 0) { + fprintf(stderr, "Cannot open %s for output: %s\n", + Etcttys, sys_errlist[errno]); + exit(1); + } + (void)lseek(ittysfil, ttyslnbeg, 0); + if(read(ittysfil, &in, 1)<0) { + fprintf(stderr, "On %s write: %s\n", + Etcttys, sys_errlist[errno]); + exit(1); + } + resettty = (in == '1'); + out = enable ? '1' : '0'; + (void)lseek(ittysfil, ttyslnbeg, 0); + if(write(ittysfil, &out, 1)<0) { + fprintf(stderr, "On %s write: %s\n", + Etcttys, sys_errlist[errno]); + exit(1); + } + (void)close(ittysfil); + return(in==out); +} +#endif !BSD4_3 + +#ifdef sequent +setmodem(ttyline, enable) +char *ttyline; int enable; +{ + char *sysbuf[BUFSIZ]; + sprintf(sysbuf,"/etc/ttyconfig /dev/%s -special %s", ttyline, + enable ? "-carrier" : "-nocarrier"); + system(sysbuf); +} +#endif /* sequent */ +#ifdef vax +/* + * 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; + int devtype=0; + char cflags; short sflags; +#ifdef BSD4_2 + int flags; +#else + short flags; +#endif + struct uba_device *ubinfo; + struct stat statb; + struct cdevsw cdevsw; + + if(nl[CDEVSW].n_type == 0) { + fprintf(stderr, "No namelist.\n"); + return(-1); + } + + if((kmem = open(_PATH_KMEM, 2)) < 0) { + fprintf(stderr, "%s open: %s\n", _PATH_KMEM, + 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, + (off_t) &(((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, (off_t) 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, (off_t) 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, (off_t) 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, (off_t)addr, 0); + (void)read(kmem, (char *) &ubinfo, sizeof ubinfo); + (void)lseek(kmem, (off_t) &(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, (off_t) &(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); + } + cflags = flags; + (void)lseek(kmem, (off_t) &(((char *)addr)[unit]), 0); + (void)write(kmem, (char *) &cflags, sizeof cflags); + break; + case DH11: + if((addr = NLVALUE(DHSCAR)) == 0) { + fprintf(stderr, "No dhsoftCAR.\n"); + return(-1); + } + sflags = flags; + (void)lseek(kmem, (off_t) &(((short *)addr)[unit]), 0); + (void)write(kmem, (char *) &sflags, sizeof sflags); + break; + case DMF: + if((addr = NLVALUE(DMFSCAR)) == 0) { + fprintf(stderr, "No dmfsoftCAR.\n"); + return(-1); + } + cflags = flags; + (void)lseek(kmem, (off_t) &(((char *)addr)[unit]), 0); + (void)write(kmem, (char *) &cflags, sizeof cflags); + break; + default: + fprintf(stderr, "Unknown device type\n"); + return(-1); + } + return(0); +} +#endif /* vax */ + +prefix(s1, s2) + register char *s1, *s2; +{ + register char c; + + while ((c = *s1++) == *s2++) + if (c == '\0') + return (1); + return (c == '\0'); +} +#else /* !DIALINOUT */ +main() +{ + fprintf(stderr,"acucntrl is not supported on this system\n"); +} +#endif /* !DIALINOUT */ diff --git a/usr.bin/uucp/uupoll/Makefile b/usr.bin/uucp/uupoll/Makefile new file mode 100644 index 0000000..fd39c3c --- /dev/null +++ b/usr.bin/uucp/uupoll/Makefile @@ -0,0 +1,10 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= uupoll +CFLAGS+=-I${.CURDIR}/../includes +BINMODE=6555 +DPADD= ${LIBCOMPAT} +LDADD= ${LIBUU} -lcompat +MAN8= uupoll.0 + +.include <bsd.prog.mk> diff --git a/usr.bin/uucp/uupoll/uupoll.8 b/usr.bin/uucp/uupoll/uupoll.8 new file mode 100644 index 0000000..f6ee49b --- /dev/null +++ b/usr.bin/uucp/uupoll/uupoll.8 @@ -0,0 +1,111 @@ +.\" Copyright (c) 1986, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)uupoll.8 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt UUPOLL 8 +.Os BSD 4.3 +.Sh NAME +.Nm uupoll +.Nd poll a remote +.Tn UUCP +site +.Sh SYNOPSIS +.Nm uupoll +.Op Fl g Ns Ar grade +.Op Fl n +.Ar system +.Sh DESCRIPTION +.Nm Uupoll +is used to force a poll of a remote system. It queues a null job for the +remote system and then invokes +.Xr uucico 8 . +.Pp +The following options are available: +.Bl -tag -width Fl +.It Fl g Ns Ar grade +Only send jobs of grade +.Ar grade +or higher on this call. +.It Fl n +Queue the null job, but do not invoke +.Xr uucico . +.El +.Pp +.Nm Uupoll +is usually run by +.Xr cron 5 +or by a user who wants to hurry a job along. A typical entry in +.Em crontab +could be: +.Bd -literal +0 0,8,16 * * * daemon /usr/bin/uupoll ihnp4 +0 4,12,20 * * * daemon /usr/bin/uupoll ucbvax +.Ed +.Pp +This will poll +.Em ihnp4 +at midnight, 0800, and 1600, and +.Em ucbvax +at 0400, noon, and 2000. +.Pp +If the local machine is already running +.Xr uucico +every +hour and has a limited number of outgoing modems, a more elegant approach +might be: +.Bd -literal +0 0,8,16 * * * daemon /usr/bin/uupoll -n ihnp4 +0 4,12,20 * * * daemon /usr/bin/uupoll -n ucbvax +5 * * * * daemon /usr/lib/uucp/uucico -r1 +.Ed +.Pp +This will queue null jobs for the remote sites at the top of hour; they +will be processed by +.Xr uucico +when it runs five minutes later. +.Sh FILES +.Bl -tag -width /usr/lib/uucp/UUCP -compact +.It Pa /usr/lib/uucp/UUCP +internal files/utilities +.It Pa /var/spool/uucp/ +Spool directory +.El +.Sh SEE ALSO +.Xr uucp 1 , +.Xr uux 1 , +.Xr uucico 8 +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.3 . diff --git a/usr.bin/uucp/uupoll/uupoll.c b/usr.bin/uucp/uupoll/uupoll.c new file mode 100644 index 0000000..5d5e662 --- /dev/null +++ b/usr.bin/uucp/uupoll/uupoll.c @@ -0,0 +1,129 @@ +/*- + * Copyright (c) 1986, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1986, 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)uupoll.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * Poll named system(s). + * + * The poll occurs even if recent attempts have failed, + * but not if L.sys prohibits the call (e.g. wrong time of day). + * + * Original Author: Tom Truscott (rti!trt) + */ + +#include "uucp.h" + +int TransferSucceeded = 1; +struct timeb Now; + +main(argc, argv) +int argc; +char **argv; +{ + char wrkpre[MAXFULLNAME]; + char file[MAXFULLNAME]; + char grade = 'A'; + int nocall = 0; + int c; + char *sysname; + extern char *optarg; + extern int optind; + + if (argc < 2) { + fprintf(stderr, "usage: uupoll [-gX] [-n] system ...\n"); + cleanup(1); + } + + if (chdir(Spool) < 0) { + syslog(LOG_WARNING, "chdir(%s) failed: %m", Spool); + cleanup(1); + } + strcpy(Progname, "uupoll"); + uucpname(Myname); + + while ((c = getopt(argc, argv, "g:n")) != EOF) + switch(c) { + case 'g': + grade = *optarg; + break; + case 'n': + nocall++; + break; + case '?': + default: + fprintf(stderr, "unknown option %s\n", + argv[optind-1]); + } + + while(optind < argc) { + sysname = argv[optind++]; + if (strcmp(sysname, Myname) == SAME) { + fprintf(stderr, "This *is* %s!\n", Myname); + continue; + } + + if (versys(&sysname)) { + fprintf(stderr, "%s: unknown system.\n", sysname); + continue; + } + /* Remove any STST file that might stop the poll */ + sprintf(wrkpre, "%s/LCK..%.*s", LOCKDIR, MAXBASENAME, sysname); + if (access(wrkpre, 0) < 0) + rmstat(sysname); + sprintf(wrkpre, "%c.%.*s", CMDPRE, SYSNSIZE, sysname); + if (!iswrk(file, "chk", Spool, wrkpre)) { + sprintf(file, "%s/%c.%.*s%cPOLL", subdir(Spool, CMDPRE), + CMDPRE, SYSNSIZE, sysname, grade); + close(creat(file, 0666)); + } + /* Attempt the call */ + if (!nocall) + xuucico(sysname); + } + cleanup(0); +} + +cleanup(code) +int code; +{ + exit(code); +} diff --git a/usr.bin/uucp/uuq/Makefile b/usr.bin/uucp/uuq/Makefile new file mode 100644 index 0000000..60dbe0b --- /dev/null +++ b/usr.bin/uucp/uuq/Makefile @@ -0,0 +1,9 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= uuq +CFLAGS+=-I${.CURDIR}/../includes +BINMODE=6555 +DPADD= ${LIBCOMPAT} +LDADD= ${LIBUU} -lcompat + +.include <bsd.prog.mk> diff --git a/usr.bin/uucp/uuq/uuq.1 b/usr.bin/uucp/uuq/uuq.1 new file mode 100644 index 0000000..783d486 --- /dev/null +++ b/usr.bin/uucp/uuq/uuq.1 @@ -0,0 +1,126 @@ +.\" Copyright (c) 1988, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)uuq.1 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt UUQ 1 +.Os BSD 4.3 +.Sh NAME +.Nm uuq +.Nd examine or manipulate the uucp queue +.Sh SYNOPSIS +.Nm uuq +.Op Fl l +.Op Fl h +.Op Fl s Ns Ar system +.Op Fl u Ns Ar user +.Op Fl d Ns Ar jobno +.Op Fl r Ns Ar sdir +.Op Fl b Ns Ar baud +.Sh DESCRIPTION +.Nm Uuq +is used to examine (and possibly delete) entries in the uucp queue. +.Pp +When listing jobs, +.Nm uuq +uses a format reminiscent of +.Xr ls . +For the long format, +information for each job listed includes +job number, number of files to transfer, user who +spooled the job, number of bytes to send, type of command requested +(S for sending files, R for receiving files, X for remote uucp), +and file or command desired. +.Pp +Several options are available: +.Bl -tag -width Ar +.It Fl h +Print only the summary lines for each system. Summary lines give system +name, number of jobs for the system, and total number of bytes to send. +.It Fl l +Specifies a long format listing. The default is to list only the +job numbers sorted across the page. +.It Fl s Ns Ar system +Limit output to jobs for systems whose system names begin with +.Ar system . +.It Fl u Ns Ar user +Limit output to jobs for users whose login names begin with +.Ar user . +.It Fl d Ns Ar jobno +Delete job number +.Ar jobno +(as obtained from a previous +.Nm uuq +command) +from the uucp queue. +Only the +.Tn UUCP +Administrator is permitted to delete jobs. +.It Fl r Ns Ar sdir +Look for files in the spooling directory +.Ar sdir +instead of the default +directory. +.It Fl b Ns Ar baud +Use +.Ar baud +to compute the transfer time instead of the default +1200 baud. +.El +.Sh FILES +.Bl -tag -width /usr/spool/uucp/Dhostname./D.x -compact +.It Pa /usr/spool/uucp/ +Default spool directory +.It Pa /usr/spool/uucp/C./C.* +Control files +.It Pa /usr/spool/uucp/D Ns Em hostname ./D.* +Outgoing data files +.It Pa /usr/spool/uucp/X./X.* +Outgoing execution files +.El +.Sh SEE ALSO +.Xr uucp 1 , +.Xr uux 1 , +.Xr uulog 1 , +.Xr uusnap 8 +.Sh BUGS +No information is available on work requested by the remote machine. +.Pp +The user who requests a remote uucp command is unknown. +.Pp +.Dq Li uq \-l +can be horrendously slow. +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.3 . diff --git a/usr.bin/uucp/uuq/uuq.c b/usr.bin/uucp/uuq/uuq.c new file mode 100644 index 0000000..7abb25c --- /dev/null +++ b/usr.bin/uucp/uuq/uuq.c @@ -0,0 +1,435 @@ +/*- + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1988, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)uuq.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * uuq - looks at uucp queues + * + * Lou Salkind + * New York University + * + */ + +#include "uucp.h" +#include <stdio.h> + +#ifdef NDIR +#include "libndir/ndir.h" +#else !NDIR +#include <sys/dir.h> +#endif !NDIR +#include <sys/stat.h> + +#define NOSYS (struct sys *)0 + +#define W_TYPE wrkvec[0] +#define W_FILE1 wrkvec[1] +#define W_FILE2 wrkvec[2] +#define W_USER wrkvec[3] +#define W_OPTNS wrkvec[4] +#define W_DFILE wrkvec[5] +#define W_MODE wrkvec[6] +#define WSUFSIZE 5 /* work file name suffix size */ + +struct sys { + char s_name[8]; + int s_njobs; + off_t s_bytes; + struct job *s_jobp; + struct sys *s_sysp; +}; + +struct job { + int j_files; + int j_flags; + char j_jobno[WSUFSIZE]; + char j_user[22]; + char j_fname[128]; + char j_grade; + off_t j_bytes; + time_t j_date; + struct job *j_jobp; +}; + +struct sys *syshead; +struct sys *getsys(); +int jcompare(); +char *sysname; +char *user; +char *rmjob; +int hflag; +int lflag; + +char *malloc(), *calloc(); +double atof(); +float baudrate = 2400.; +char Username[BUFSIZ]; +char Filename[BUFSIZ]; +int Maxulen = 0; +struct timeb Now; + +main(argc, argv) +int argc; +char **argv; +{ + register int i; + register struct sys *sp; + register struct job *jp; + struct job **sortjob; + int nsys; + extern char *optarg; + extern int optind; + + strcpy(Progname, "uuq"); + uucpname(Myname); + + while ((i = getopt(argc, argv, "r:S:s:u:d:b:hl")) != EOF) + switch (i) { + case 'r': + case 'S': + Spool = optarg; + break; + case 's': + sysname = optarg; + if (strlen(sysname) > SYSNSIZE) + sysname[SYSNSIZE] = '\0'; + break; + case 'u': + user = optarg; + break; + case 'd': + rmjob = optarg; + break; + case 'b': + baudrate = atof(optarg); + break; + case 'h': + hflag++; + break; + case 'l': + lflag++; + break; + default: + fprintf(stderr, + "usage: uuq [-l] [-h] [-ssystem] [-uuser] [-djobno] [-rspool] [-bbaudrate]\n"); + exit(0); + } + + subchdir(Spool); + baudrate *= 0.7; /* reduce speed because of protocol overhead */ + baudrate *= 7.5; /* convert to chars/minute (60/8) */ + gather(); + nsys = 0; + for (sp = syshead; sp; sp = sp->s_sysp) { + if (sp->s_njobs == 0) + continue; + if (!hflag && nsys++ > 0) + putchar('\n'); + printf("%s: %d %s", sp->s_name, + sp->s_njobs, sp->s_njobs > 1 ? "jobs" : "job"); + if (lflag) { + float minutes; + int hours; + /* The 80 * njobs is because of the uucp handshaking */ + minutes = (float)(sp->s_bytes + 80 * sp->s_njobs)/baudrate; + hours = minutes/60; + printf(", %ld bytes, ", sp->s_bytes); + if (minutes > 60){ + printf("%d hour%s, ",hours, + hours > 1 ? "s": ""); + minutes -= 60 * hours; + } + printf("%3.1f minutes (@ effective baudrate of %d)", + minutes,(int)(baudrate/6)); + } + putchar('\n'); + if (hflag) + continue; + /* sort them babies! */ + sortjob = (struct job **)calloc(sp->s_njobs, sizeof (struct job *)); + for (i=0, jp=sp->s_jobp; i < sp->s_njobs; i++, jp=jp->j_jobp) + sortjob[i] = jp; + qsort(sortjob, sp->s_njobs, sizeof (struct job *), jcompare); + for (i = 0; i < sp->s_njobs; i++) { + jp = sortjob[i]; + if (lflag) { + printf("%s %2d %-*s%7ld%5.1f %-12.12s %c %.*s\n", + jp->j_jobno, jp->j_files, Maxulen, jp->j_user, jp->j_bytes, jp->j_bytes/baudrate, + ctime(&jp->j_date) + 4, jp->j_flags, sizeof (jp->j_fname), jp->j_fname + ); + } else { + printf("%s", jp->j_jobno); + putchar((i+1)%10 ? '\t' : '\n'); + } + /* There's no need to keep the force poll if jobs > 1*/ + if (sp->s_njobs > 1 && strcmp("POLL", jp->j_jobno)==0) { + char pbuf[BUFSIZ]; + sprintf(pbuf,"%s/%c.%s%cPOLL", + subdir(Spool, CMDPRE), CMDPRE, + sp->s_name, jp->j_grade); + (void) unlink(pbuf); + } + } + if (!lflag && (sp->s_njobs%10)) + putchar('\n'); + } + exit(0); +} + +jcompare(j1, j2) +struct job **j1, **j2; +{ + int delta; + + delta = (*j1)->j_grade - (*j2)->j_grade; + if (delta) + return delta; + return(strcmp((*j1)->j_jobno,(*j2)->j_jobno)); +} + +/* + * Get all the command file names + */ +gather() +{ + struct direct *d; + DIR *df; + + /* + * Find all the spool files in the spooling directory + */ + if ((df = opendir(subdir(Spool, CMDPRE))) == NULL) { + fprintf(stderr, "can't examine spooling area\n"); + exit(1); + } + for (;;) { + if ((d = readdir(df)) == NULL) + break; + if (d->d_namlen <= 2 || d->d_name[0] != CMDPRE || + d->d_name[1] != '.') + continue; + if (analjob(d->d_name) < 0) { + fprintf(stderr, "out of memory\n"); + break; + } + } + closedir(df); +} + +/* + * analjob does the grunge work of verifying jobs + */ +#include <pwd.h> +analjob(filename) +char *filename; +{ + struct job *jp; + struct sys *sp; + char sbuf[MAXNAMLEN+1], str[256], nbuf[256]; + char *jptr, *wrkvec[20]; + char grade; + FILE *fp, *df; + struct stat statb; + int files, gotname, i; + off_t bytes; + + strncpy(sbuf, filename, MAXNAMLEN); + sbuf[MAXNAMLEN] = '\0'; + jptr = sbuf + strlen(sbuf) - WSUFSIZE; + grade = *jptr; + *jptr++ = 0; + /* + * sbuf+2 now points to sysname name (null terminated) + * jptr now points to job number (null terminated) + */ + if (rmjob) { + if (strcmp(rmjob, jptr)) + return(0); + } else { + if ((sp = getsys(sbuf+2)) == NOSYS) + return(0); + if (!lflag) { + /* SHOULD USE A SMALLER STRUCTURE HERE */ + jp = (struct job *)malloc(sizeof(struct job)); + if (jp == (struct job *)0) + return(-1); + strcpy(jp->j_jobno, jptr); + jp->j_jobp = sp->s_jobp; + jp->j_grade = grade; + sp->s_jobp = jp; + sp->s_njobs++; + return(1); + } + } + if ((fp = fopen(subfile(filename), "r")) == NULL) { + perror(subfile(filename)); + return(0); + } + files = 0; + bytes = 0; + gotname = 0; + while (fgets(str, sizeof str, fp)) { + if (getargs(str, wrkvec, 20) <= 0) + continue; + if (rmjob) { + int myuid; + struct passwd *pw; + /* + * Make sure person who is removing data files is + * the person who created it or root. + */ + myuid = getuid(); + pw = getpwnam(W_USER); + if (myuid && (pw == NULL || myuid != pw->pw_uid)) { + fprintf(stderr, "Permission denied.\n"); + exit(1); + } + if (W_TYPE[0] == 'S' && !index(W_OPTNS, 'c')) { + unlink(subfile(W_DFILE)); + fprintf(stderr, "Removing data file %s\n", W_DFILE); + } + continue; + } + if (user && (W_TYPE[0] == 'X' || !prefix(user, W_USER))) { + fclose(fp); + return(0); + } + files++; + if (W_TYPE[0] == 'S') { + if (strcmp(W_DFILE, "D.0") && + stat(subfile(W_DFILE), &statb) >= 0) + bytes += statb.st_size; + else if (stat(subfile(W_FILE1), &statb) >= 0) + bytes += statb.st_size; + } + /* amusing heuristic */ +#define isXfile(s) (s[0]=='D' && s[strlen(s)-WSUFSIZE]=='X') + if (gotname == 0 && isXfile(W_FILE1)) { + if ((df = fopen(subfile(W_FILE1), "r")) == NULL) + continue; + while (fgets(nbuf, sizeof nbuf, df)) { + nbuf[strlen(nbuf) - 1] = '\0'; + if (nbuf[0] == 'C' && nbuf[1] == ' ') { + strcpy(Filename, nbuf+2); + gotname++; + } else if (nbuf[0] == 'R' && nbuf[1] == ' ') { + register char *p, *q, *r; + r = q = p = nbuf+2; + do { + if (*p == '!' || *p == '@'){ + r = q; + q = p+1; + } + } while (*p++); + + strcpy(Username, r); + W_USER = Username; + } + } + fclose(df); + } + } + fclose(fp); + if (rmjob) { + unlink(subfile(filename)); + fprintf(stderr, "Removing command file %s\n", filename); + exit(0); + } + if (files == 0) { + static char *wtype = "X"; + static char *wfile = "forced poll"; + if (strcmp("POLL", &filename[strlen(filename)-4])) { + fprintf(stderr, "%.14s: empty command file\n", filename); + return(0); + } + W_TYPE = wtype; + W_FILE1 = wfile; + } + jp = (struct job *)malloc(sizeof(struct job)); + if (jp == (struct job *)0) + return(-1); + strcpy(jp->j_jobno, jptr); + jp->j_files = files; + jp->j_bytes = bytes; + jp->j_grade = grade; + jp->j_flags = W_TYPE[0]; + strncpy(jp->j_user, W_TYPE[0]=='X' ? "---" : W_USER, 20 ); + jp->j_user[20] = '\0'; + i = strlen(jp->j_user); + if (i > Maxulen) + Maxulen = i; + /* SHOULD ADD ALL INFORMATION IN THE WHILE LOOP */ + if (gotname) + strncpy(jp->j_fname, Filename, sizeof jp->j_fname); + else + strncpy(jp->j_fname, W_FILE1, sizeof jp->j_fname); + stat(subfile(filename), &statb); + jp->j_date = statb.st_mtime; + jp->j_jobp = sp->s_jobp; + sp->s_jobp = jp; + sp->s_njobs++; + sp->s_bytes += jp->j_bytes; + return(1); +} + +struct sys * +getsys(s) +register char *s; +{ + register struct sys *sp; + + for (sp = syshead; sp; sp = sp->s_sysp) + if (strcmp(s, sp->s_name) == 0) + return(sp); + if (sysname && !prefix(sysname, s)) + return(NOSYS); + sp = (struct sys *)malloc(sizeof(struct sys)); + if (sp == NOSYS) + return(NOSYS); + strcpy(sp->s_name, s); + sp->s_njobs = 0; + sp->s_jobp = (struct job *)0; + sp->s_sysp = syshead; + sp->s_bytes = 0; + syshead = sp; + return(sp); +} diff --git a/usr.bin/uucp/uusend/Makefile b/usr.bin/uucp/uusend/Makefile new file mode 100644 index 0000000..6c13fb4 --- /dev/null +++ b/usr.bin/uucp/uusend/Makefile @@ -0,0 +1,6 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= uusend +LINKS= ${BINDIR}/uusend ${BINDIR}/ruusend + +.include <bsd.prog.mk> diff --git a/usr.bin/uucp/uusend/uusend.1 b/usr.bin/uucp/uusend/uusend.1 new file mode 100644 index 0000000..9379307 --- /dev/null +++ b/usr.bin/uucp/uusend/uusend.1 @@ -0,0 +1,96 @@ +.\" Copyright (c) 1980, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)uusend.1 8.3 (Berkeley) 2/16/94 +.\" +.Dd February 16, 1994 +.Dt UUSEND 1 +.Os BSD 4 +.Sh NAME +.Nm uusend +.Nd send a file to a remote host +.Sh SYNOPSIS +.Nm uusend +.Op Fl m Ar mode +.Ar sourcefile +.Ar sys1!sys2!..!remotefile +.Sh DESCRIPTION +.Nm Uusend +sends a file to a given location on a remote system. +The system need not be directly connected to the local +system, but a chain of +.Xr uucp 1 +links must to connect the two systems. +.Pp +Available option: +.Bl -tag -width Fl +.It Fl m Ar mode +The mode of the file on the remote +end is taken from the octal number given. +Otherwise, the mode of the input file will be used. +.El +.Pp +The sourcefile +can be +.Ql Fl , +meaning to use the standard input. +Both of these options are primarily intended for internal use of +.Nm uusend . +.Pp +The remotefile can include the +.Em ~userid +syntax. +.Sh DIAGNOSTICS +If anything goes wrong any further away than the first system down +the line, you will never hear about it. +.Sh SEE ALSO +.Xr uux 1 , +.Xr uucp 1 , +.Xr uuencode 1 +.Sh BUGS +This command should not exist, since +.Xr uucp +should handle it. +.Pp +All systems along the line must have the +.Nm uusend +command available and allow remote execution of it. +.Pp +Some uucp systems have a bug where binary files cannot be the +input to a +.Xr uux 1 +command. If this bug exists in any system along the line, +the file will show up severely munged. +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.0 . diff --git a/usr.bin/uucp/uusend/uusend.c b/usr.bin/uucp/uusend/uusend.c new file mode 100644 index 0000000..207108e --- /dev/null +++ b/usr.bin/uucp/uusend/uusend.c @@ -0,0 +1,403 @@ +/*- + * Copyright (c) 1980, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1980, 1991, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)uusend.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +/* + * uusend: primitive operation to allow uucp like copy of binary files + * but handle indirection over systems. + * + * usage: uusend [-r] [-m ooo] localfile sysname1!sysname2!...!destfile + * uusend [-r] [-m ooo] - sysname1!sysname2!...!destfile + * + * Author: Mark Horton, May 1980. + * + * "-r" switch added. Has same effect as "-r" in uux. 11/82 CCW + * + * Error recovery (a la uucp) added & ifdefs for ruusend (as in rmail). + * Checks for illegal access to /usr/lib/uucp. + * February 1983 Christopher Woodbury + * Fixed mode set[ug]id loophole. 4/8/83 CCW + * + * Add '-f' to make uusend syntax more similar to UUCP. "destname" + * can now be a directory. June 1983 CCW + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> +#include <pwd.h> + +/* + * define RECOVER to permit requests like 'uusend file sys1!sys2!~uucp' + * (abbreviation for 'uusend file sys1!sys2!~uucp/file'). + * define DEBUG to keep log of uusend uusage. + * define RUUSEND if neighboring sites permit 'ruusend', + * which they certainly should to avoid security holes + */ +#define RECOVER +/*#define DEBUG "/usr/spool/uucp/uusend.log"/**/ + +FILE *in, *out; +FILE *dout; + +extern FILE *popen(); +extern char *index(), *strcpy(), *strcat(), *ctime(); + +#ifdef RUUSEND +int rsend; +#endif RUUSEND +int mode = -1; /* mode to chmod new file to */ +char *nextsys; /* next system in the chain */ +char dnbuf[200]; /* buffer for result of ~user/file */ +char cmdbuf[256]; /* buffer to build uux command in */ +char *rflg = ""; /* default value of rflg ccw -- 1 Nov '82 */ + +struct passwd *user; /* entry in /etc/passwd for ~user */ +struct passwd *getpwnam(); +struct stat stbuf; + +char *excl; /* location of first ! in destname */ +char *sl; /* location of first / in destname */ +char *sourcename; /* argv[1] */ +char *destname; /* argv[2] */ +char *UULIB = "/usr/lib/uucp"; /* UUCP lib directory */ + +#ifdef RECOVER +char *UUPUB = "/usr/spool/uucppublic/"; /* public UUCP directory */ +char *filename; /* file name from end of destname */ +char *getfname(); /* routine to get filename from destname */ +int fflg; +char f[100]; /* name of default output file */ +#else !RECOVER +char *f = ""; /* so we waste a little space */ +#endif !RECOVER + +main(argc, argv) +int argc; +char **argv; +{ + register int c; + long count; + extern char **environ; + +#ifdef DEBUG + long t; + umask(022); + dout = fopen(DEBUG, "a"); + if (dout == NULL) { + printf("Cannot append to %s\n", DEBUG); + exit(1); + } + freopen(DEBUG, "a", stdout); + fprintf(dout, "\nuusend run: "); + for (c=0; c<argc; c++) + fprintf(dout, "%s ", argv[c]); + time(&t); + fprintf(dout, "%s", ctime(&t)); +#endif DEBUG + +#ifdef RUUSEND + if(argv[0][0] == 'r') + rsend++; +#endif RUUSEND + while (argc > 1 && argv[1][0] == '-' && argv[1][1]) { + switch(argv[1][1]) { + case 'm': + sscanf(argv[2], "%o", &mode); + mode &= 0777; /* fix set[ug]id loophole */ + argc--; argv++; + break; + case 'r': /* -r flag for uux */ + rflg = "-r "; + break; +#ifdef RECOVER + case 'f': + fflg++; + strcpy(f, argv[1]); + break; +#endif RECOVER + default: + fprintf(stderr, "Bad flag: %s\n", argv[1]); + break; + } + argc--; argv++; + } + + if (argc != 3) { + fprintf(stderr, "Usage: uusend [-m ooo] [-r] -/file sys!sys!..!rfile\n"); + exit(1); + } + + sourcename = argv[1]; + destname = argv[2]; + + if (sourcename[0] == '-') + in = stdin; + else { +#ifdef RUUSEND + if (rsend) { + fprintf(stderr, "illegal input\n"); + exit(2); + } +#endif RUUSEND + in = fopen(sourcename, "r"); + if (in == NULL) { + perror(argv[1]); + exit(2); + } + if (!fflg || f[2] == '\0') { + strcpy(f, "-f"); + strcat(f, getfname(sourcename)); + fflg++; + } + } + + excl = index(destname, '!'); + if (excl) { + /* + * destname is on a remote system. + */ + nextsys = destname; + *excl++ = 0; + destname = excl; + if (mode < 0) { + fstat(fileno(in), &stbuf); + mode = stbuf.st_mode & 0777; + } +#ifdef RUUSEND + sprintf(cmdbuf,"uux -gn -z %s- \"%s!ruusend %s -m %o - (%s)\"", +#else !RUUSEND + sprintf(cmdbuf, "uux -gn -z %s- \"%s!uusend %s -m %o - (%s)\"", +#endif !RUUSEND + rflg, nextsys, f, mode, destname); +#ifdef DEBUG + fprintf(dout, "remote: nextsys='%s', destname='%s', cmd='%s'\n", nextsys, destname, cmdbuf); +#endif DEBUG + out = popen(cmdbuf, "w"); + } else { + /* + * destname is local. + */ + if (destname[0] == '~') { +#ifdef DEBUG + fprintf(dout, "before ~: '%s'\n", destname); +fflush(dout); +#endif DEBUG + sl = index(destname, '/'); +#ifdef RECOVER + if (sl == NULL && !fflg) { + fprintf(stderr, "Illegal ~user\n"); + exit(3); + } + for (sl = destname; *sl != '\0'; sl++) + ; /* boy, is this a hack! */ +#else !RECOVER + if (sl == NULL) { + fprintf(stderr, "Illegal ~user\n"); + exit(3); + } + *sl++ = 0; +#endif !RECOVER + user = getpwnam(destname+1); + if (user == NULL) { + fprintf(stderr, "No such user as %s\n", + destname); +#ifdef RECOVER + if ((filename =getfname(sl)) == NULL && + !fflg) + exit(4); + strcpy(dnbuf, UUPUB); + if (fflg) + strcat(dnbuf, &f[2]); + else + strcat(dnbuf, filename); + } + else { + strcpy(dnbuf, user->pw_dir); + strcat(dnbuf, "/"); + strcat(dnbuf, sl); + } +#else !RECOVER + exit(4); + } + strcpy(dnbuf, user->pw_dir); + strcat(dnbuf, "/"); + strcat(dnbuf, sl); +#endif !RECOVER + destname = dnbuf; + } +#ifdef RECOVER + else + destname = strcpy(dnbuf, destname); +#endif !RECOVER + if(strncmp(UULIB, destname, strlen(UULIB)) == 0) { + fprintf(stderr, "illegal file: %s", destname); + exit(4); + } +#ifdef RECOVER + if (stat(destname, &stbuf) == 0 && + (stbuf.st_mode & S_IFMT) == S_IFDIR && + fflg) { + strcat(destname, "/"); + strcat(destname, &f[2]); + } +#endif RECOVER + out = fopen(destname, "w"); +#ifdef DEBUG + fprintf(dout, "local, file='%s'\n", destname); +#endif DEBUG + if (out == NULL) { + perror(destname); +#ifdef RECOVER + if (strncmp(destname,UUPUB,strlen(UUPUB)) == 0) + exit(5); /* forget it! */ + filename = getfname(destname); + if (destname == dnbuf) /* cmdbuf is scratch */ + filename = strcpy(cmdbuf, filename); + destname = strcpy(dnbuf, UUPUB); + if (user != NULL) { + strcat(destname, user->pw_name); + if (stat(destname, &stbuf) == -1) { + mkdir(destname, 0777); + } + strcat(destname, "/"); + } + if (fflg) + strcat(destname, &f[2]); + else + strcat(destname, filename); + if ((out = fopen(destname, "w")) == NULL) + exit(5); /* all for naught! */ +#else !RECOVER + exit(5); +#endif !RECOVER + } + if (mode > 0) + chmod(destname, mode); /* don't bother to check it */ + } + + /* + * Now, in any case, copy from in to out. + */ + + count = 0; + while ((c=getc(in)) != EOF) { + putc(c, out); + count++; + } +#ifdef DEBUG + fprintf(dout, "count %ld bytes\n", count); + fclose(dout); +#endif DEBUG + + fclose(in); + fclose(out); /* really should pclose in that case */ + exit(0); +} + +/* + * Return the ptr in sp at which the character c appears; + * NULL if not found. Included so I don't have to fight the + * index/strchr battle. + */ + +#define NULL 0 + +char * +index(sp, c) +register char *sp, c; +{ + do { + if (*sp == c) + return(sp); + } while (*sp++); + return(NULL); +} + +#ifdef RECOVER +char * +getfname(p) +register char *p; +{ + register char *s; + s = p; + while (*p != '\0') + p++; + if (p == s) + return (NULL); + for (;p != s; p--) + if (*p == '/') { + p++; + break; + } + return (p); +} + +#ifndef BSD4_2 +makedir(dirname, mode) +char *dirname; +int mode; +{ + register int pid; + int retcode, status; + switch ((pid = fork())) { + case -1: /* error */ + return (-1); + case 0: /* child */ + umask(0); + execl("/bin/mkdir", "mkdir", dirname, (char *)0); + exit(1); + /* NOTREACHED */ + default: /* parent */ + while ((retcode=wait(&status)) != pid && retcode != -1) + ; + if (retcode == -1) + return -1; + else { + chmod(dirname, mode); + return status; + } + } + /* NOTREACHED */ +} +#endif !BSD4_2 +#endif RECOVER diff --git a/usr.bin/uucp/uusnap/Makefile b/usr.bin/uucp/uusnap/Makefile new file mode 100644 index 0000000..6bf9137 --- /dev/null +++ b/usr.bin/uucp/uusnap/Makefile @@ -0,0 +1,8 @@ +# @(#)Makefile 8.1 (Berkeley) 6/6/93 + +PROG= uusnap +CFLAGS+=-I${.CURDIR}/../includes +BINMODE=6555 +MAN8= uusnap.0 + +.include <bsd.prog.mk> diff --git a/usr.bin/uucp/uusnap/uusnap.8 b/usr.bin/uucp/uusnap/uusnap.8 new file mode 100644 index 0000000..92f0e330 --- /dev/null +++ b/usr.bin/uucp/uusnap/uusnap.8 @@ -0,0 +1,80 @@ +.\" Copyright (c) 1983, 1991, 1993 +.\" The Regents of the University of California. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)uusnap.8 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt UUSNAP 8 +.Os BSD 4.2 +.Sh NAME +.Nm uusnap +.Nd show snapshot of the +.Tn UUCP +system +.Sh SYNOPSIS +.Nm uusnap +.Sh DESCRIPTION +.Nm Uusnap +displays in tabular format a synopsis of the current +.Tn UUCP +situation. The format of each line is as follows: +.Bd -literal -offset indent -compact + +site N Cmds N Data N Xqts Message + +.Ed +Where "site" is the name of the site with work, "N" is a count of +each of the three possible types of work (command, data, or remote execute), +and "Message" is the current status message for that +site as found in the +.Tn STST +file. +.Pp +Included in "Message" may be the time left before +.Tn UUCP +can re-try the +call, and the count of the number of times that +.Tn UUCP +has tried +(unsuccessfully) to reach the site. +.Sh SEE ALSO +.Xr uucp 1 , +.Xr uux 1 , +.Xr uuq 1 , +.Xr uucico 8 +.Rs +.%T "UUCP Implementation Guide" +.Re +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.2 . diff --git a/usr.bin/uucp/uusnap/uusnap.c b/usr.bin/uucp/uusnap/uusnap.c new file mode 100644 index 0000000..565c52a --- /dev/null +++ b/usr.bin/uucp/uusnap/uusnap.c @@ -0,0 +1,348 @@ +/*- + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Rick Adams. Originally by RJKing WECo-MG6565 May 83. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1988, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)uusnap.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include "uucp.h" +#include <sys/stat.h> +#ifdef NDIR +#include "ndir.h" +#else +#include <sys/dir.h> +#endif +#include <ctype.h> + +#define NSYSTEM 300 /* max # of systems queued */ + +#define CMDSLEN 5 /* Length of trailer */ +#define DATALEN 5 /* Length of trailer */ +#define XEQTLEN 5 /* Length of trailer */ +#define NUMCTRS 3 /* # file types to count */ +#define CMDTYPE 0 /* Index into scnt.cntr */ +#define DATTYPE 1 /* Index into scnt.cntr */ +#define XEQTYPE 2 /* Index into scnt.cntr */ + +struct scnt { /* System count structure */ + char name[MAXBASENAME+1]; /* Name of system */ + short cntr[NUMCTRS]; /* Count */ + char stst[32]; /* STST Message */ + time_t locked; /* If LCK..sys present */ + int st_type; /* STST Type */ + int st_count; /* STST Count */ + time_t st_lastime; /* STST Last time tried */ + time_t st_retry; /* STST Secs to retry */ + }; + +int sndx; /* Number of systems */ +struct scnt sys[NSYSTEM]; /* Systems queued */ +int xqtisrunning = 0; + +main() +{ + register int i, j, nlen = 0; + time_t curtime, t; + + dodir(CMDSDIR, "C.", CMDSLEN, '\0', CMDTYPE); + dodir(DATADIR, "D.", DATALEN, '\0', DATTYPE); + dodir(XEQTDIR, "X.", XEQTLEN, 'X', XEQTYPE); + getstst(SPOOL); + time(&curtime); + for(i=0; i<sndx; ++i) + if((j = strlen(sys[i].name)) > nlen) + nlen = j; + for(i=0; i<sndx; ++i) { + t = (sys[i].st_lastime +sys[i].st_retry) - curtime; + + /* decide if STST text is worth printing */ + if (-t < ONEDAY*2 && sys[i].st_type == SS_WRONGTIME) { + sys[i].stst[0] = '\0'; + if (sys[i].cntr[0]+sys[i].cntr[1]+sys[i].cntr[2] == 0) + continue; /* ignore entire line */ + } + + printf("%-*.*s ", nlen, nlen, sys[i].name); + if(sys[i].cntr[CMDTYPE]) + printf("%3.d Cmd%s ", sys[i].cntr[CMDTYPE], + sys[i].cntr[CMDTYPE]>1?"s":" "); + else + printf(" --- "); + if(sys[i].cntr[DATTYPE]) + printf("%3.d Data ", sys[i].cntr[DATTYPE]); + else + printf(" --- "); + if(sys[i].cntr[XEQTYPE]) + printf("%3.d Xqt%s ", sys[i].cntr[XEQTYPE], + sys[i].cntr[XEQTYPE]>1?"s":" "); + else + printf(" --- "); + if(*sys[i].stst == '\0' || sys[i].locked > sys[i].st_lastime) { + if(sys[i].locked) + printf("LOCKED\n"); + else + printf("\n"); + continue; + } + printf("%s ", sys[i].stst); + /* decide if STST info is worth pursuing */ + if (-t < ONEDAY*2 && (sys[i].st_count == 0 + || sys[i].st_type == SS_WRONGTIME + || (sys[i].st_type == SS_INPROGRESS && sys[i].locked))) { + printf("\n"); + continue; + } + t = (sys[i].st_lastime +sys[i].st_retry) - curtime; + if (-t < ONEDAY*2 && sys[i].st_type != SS_FAIL) + t = 0; + + if (sys[i].st_count > MAXRECALLS) + printf("at MAX RECALLS"); + else if (-t >= ONEDAY*2) + printf("%ld days ago", (long)-t/ONEDAY); + else if (t <= 0) + printf("Retry time reached"); + else if (t < 60) + printf("Retry time %ld sec%s", (long)(t%60), + (t%60)!=1? "s": ""); + else + printf("Retry time %ld min%s", (long)(t/60), + (t/60)!=1? "s": ""); + if(sys[i].st_count > 1) + printf(" Count: %d\n", sys[i].st_count); + else + printf("\n"); + } + if (xqtisrunning) + printf("\nUuxqt is running\n"); + exit(0); +} + +dodir(dnam, prfx, flen, fchr, type) +char *dnam, *prfx; +int flen; +char fchr; +int type; +{ + register struct direct *dentp; + register DIR *dirp; + register int i, fnamlen, plen; + char fnam[MAXNAMLEN+1]; + + plen = strlen(prfx); + if(chdir(dnam) < 0) { + perror(dnam); + exit(1); + } + if ((dirp = opendir(".")) == NULL) { + perror(dnam); + exit(1); + } + while((dentp = readdir(dirp)) != NULL) { + if(*dentp->d_name == '.') + continue; + if(strncmp(dentp->d_name, prfx, plen) != SAME) { + fprintf(stderr, "strange file (%s) in %s\n", + dentp->d_name, dnam); + continue; + } + strcpy(fnam, &dentp->d_name[plen]); + fnamlen = strlen(fnam); + if(flen > 0) { + fnamlen -= flen; + fnam[fnamlen] = '\0'; + fnamlen = MAXBASENAME; /* yes, after = '\0'*/ + } else { + for(; fnamlen>0; --fnamlen) { + if(fnam[fnamlen] == fchr) { + fnam[fnamlen] = '\0'; + break; + } + } + fnamlen = MAXBASENAME; + } + for(i=0; i<sndx; ++i) { + if(strncmp(fnam, sys[i].name, fnamlen) == SAME) { + ++sys[i].cntr[type]; + break; + } + } + if(i == sndx) { + strcpy(sys[i].name, fnam); + ++sys[i].cntr[type]; + if(++sndx >= NSYSTEM) { + sndx = NSYSTEM-1; + fprintf(stderr,"Too many system names.\n"); + } + } + } + closedir(dirp); +} + +getstst(sdir) +char *sdir; +{ + register int i, csys; + register char *tp; + char fnam[MAXNAMLEN+1], buff[128]; + register struct direct *dentp; + register DIR *dirp; + register FILE *st; + struct stat stbuf; + long atol(); + + if (chdir(sdir) < 0) { + perror(sdir); + exit(1); + } + if ((dirp = opendir(LOCKDIR)) == NULL) { + perror(sdir); + exit(1); + } + while ((dentp = readdir(dirp)) != NULL) { + if (strcmp(&dentp->d_name[5], X_LOCK) == SAME) { + xqtisrunning++; + continue; + } + if(strncmp(dentp->d_name, "LCK..", 5) == SAME) { + if(strncmp(&dentp->d_name[5], "tty", 3) == SAME || + strncmp(&dentp->d_name[5], "cul", 3) == SAME) + continue; + strcpy(fnam, dentp->d_name); + for(csys=0; csys<sndx; ++csys) { + if(strncmp(&fnam[5], sys[csys].name, SYSNSIZE) + == SAME) + break; + } + strcpy(sys[csys].name, &fnam[5]); + if(csys == sndx) { + ++sndx; + } + if (stat(fnam, &stbuf) < 0) + sys[csys].locked = 1; + else + sys[csys].locked = stbuf.st_mtime; + continue; + } + } + closedir(dirp); + if (chdir("STST") < 0) { + perror("STST"); + exit(1); + } + if ((dirp = opendir(".")) == NULL) { + perror("STST"); + exit(1); + } + while ((dentp = readdir(dirp)) != NULL) { + if(*dentp->d_name == '.') + continue; + strcpy(fnam, dentp->d_name); + for(csys=0; csys<sndx; ++csys) { + if(strncmp(fnam, sys[csys].name, SYSNSIZE) == SAME) + break; + } + strcpy(sys[csys].name, fnam); + if(csys == sndx) { + ++sndx; + } + if((st = fopen(fnam, "r")) == NULL) { + sys[csys].stst[0] = '\0'; + continue; + } + buff[0] = '\0'; + fgets(buff, sizeof(buff), st); + fclose(st); + if(tp = rindex(buff, ' ')) + *tp = '\0'; /* drop system name */ + else + continue; + for(i=0, tp=buff; i<4; ++i, ++tp) + if((tp = index(tp, ' ')) == NULL) + break; + if(i != 4) + continue; + strncpy(sys[csys].stst, tp, sizeof(sys[csys].stst)); + tp = buff; + sys[csys].st_type = atoi(tp); + tp = index(tp+1, ' '); + sys[csys].st_count = atoi(tp+1); + tp = index(tp+1, ' '); + sys[csys].st_lastime = atol(tp+1); + tp = index(tp+1, ' '); + sys[csys].st_retry = atol(tp+1); + } +} +/* + * Return the ptr in sp at which the character c appears; + * NULL if not found + */ + +char * +index(sp, c) +register char *sp, c; +{ + do { + if (*sp == c) + return sp; + } while (*sp++); + return NULL; +} + +/* + * Return the ptr in sp at which the character c last + * appears; NULL if not found +*/ + +char * +rindex(sp, c) +register char *sp, c; +{ + register char *r; + + r = NULL; + do { + if (*sp == c) + r = sp; + } while (*sp++); + return r; +} |