summaryrefslogtreecommitdiffstats
path: root/usr.bin/uucp
diff options
context:
space:
mode:
authorrgrimes <rgrimes@FreeBSD.org>1994-05-27 12:33:43 +0000
committerrgrimes <rgrimes@FreeBSD.org>1994-05-27 12:33:43 +0000
commitf9ab90d9d6d02989a075d0f0074496d5b1045e4b (patch)
treeadd7e996bac5289cdc55e6935750c352505560a9 /usr.bin/uucp
parentbe22b15ae2ff8d7fe06b6e14fddf0c5b444a95da (diff)
downloadFreeBSD-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/Makefile10
-rw-r--r--usr.bin/uucp/acucntrl/acucntrl.8164
-rw-r--r--usr.bin/uucp/acucntrl/acucntrl.c814
-rw-r--r--usr.bin/uucp/uupoll/Makefile10
-rw-r--r--usr.bin/uucp/uupoll/uupoll.8111
-rw-r--r--usr.bin/uucp/uupoll/uupoll.c129
-rw-r--r--usr.bin/uucp/uuq/Makefile9
-rw-r--r--usr.bin/uucp/uuq/uuq.1126
-rw-r--r--usr.bin/uucp/uuq/uuq.c435
-rw-r--r--usr.bin/uucp/uusend/Makefile6
-rw-r--r--usr.bin/uucp/uusend/uusend.196
-rw-r--r--usr.bin/uucp/uusend/uusend.c403
-rw-r--r--usr.bin/uucp/uusnap/Makefile8
-rw-r--r--usr.bin/uucp/uusnap/uusnap.880
-rw-r--r--usr.bin/uucp/uusnap/uusnap.c348
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;
+}
OpenPOWER on IntegriCloud