diff options
| author | jtc <jtc@NetBSD.org> | 1994-10-24 22:27:43 +0000 |
|---|---|---|
| committer | jtc <jtc@NetBSD.org> | 1994-10-24 22:27:43 +0000 |
| commit | 18228379029942730c3e8d702e613f34bbecea43 (patch) | |
| tree | 458a0e92b781119788dd7a716fd1ad9ccfed6c9d /gnu/libexec | |
| parent | 83ed75f58e695ed36a677fbb5d37e25e8b03367c (diff) | |
Upgraded to Taylor UUCP 1.05 (Thanks to John Kohl).
Diffstat (limited to 'gnu/libexec')
26 files changed, 2658 insertions, 1146 deletions
diff --git a/gnu/libexec/uucp/uucico/protj.c b/gnu/libexec/uucp/uucico/protj.c index bdf2b856114..91f4c15cdba 100644 --- a/gnu/libexec/uucp/uucico/protj.c +++ b/gnu/libexec/uucp/uucico/protj.c @@ -1,7 +1,7 @@ /* protj.c The 'j' protocol. - Copyright (C) 1992 Ian Lance Taylor + Copyright (C) 1992, 1994 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -20,19 +20,20 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or - c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. */ #include "uucp.h" #if USE_RCS_ID -const char protj_rcsid[] = "$Id: protj.c,v 1.1 1993/08/04 19:36:23 jtc Exp $"; +const char protj_rcsid[] = "$Id: protj.c,v 1.2 1994/10/24 22:27:43 jtc Exp $"; #endif #include <ctype.h> #include <errno.h> #include "uudefs.h" +#include "uuconf.h" #include "conn.h" #include "trans.h" #include "system.h" diff --git a/gnu/libexec/uucp/uucico/prott.c b/gnu/libexec/uucp/uucico/prott.c index 477ccf4f49c..b70a319ebbe 100644 --- a/gnu/libexec/uucp/uucico/prott.c +++ b/gnu/libexec/uucp/uucico/prott.c @@ -20,13 +20,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or - c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. */ #include "uucp.h" #if USE_RCS_ID -const char prott_rcsid[] = "$Id: prott.c,v 1.1 1993/08/04 19:36:24 jtc Exp $"; +const char prott_rcsid[] = "$Id: prott.c,v 1.2 1994/10/24 22:27:48 jtc Exp $"; #endif #include "uudefs.h" @@ -133,7 +133,8 @@ ftsendcmd (qdaemon, z, ilocal, iremote) zalc = zbufalc (csend); memcpy (zalc, z, clen); - bzero (zalc + clen, csend - clen); + if (csend > clen) + bzero (zalc + clen, csend - clen); fret = fsend_data (qdaemon->qconn, zalc, csend, TRUE); ubuffree (zalc); diff --git a/gnu/libexec/uucp/uucico/protz.c b/gnu/libexec/uucp/uucico/protz.c index e593e07e5b0..d9849db5da2 100644 --- a/gnu/libexec/uucp/uucico/protz.c +++ b/gnu/libexec/uucp/uucico/protz.c @@ -181,7 +181,7 @@ #include "uucp.h" #if USE_RCS_ID -const char protz_rcsid[] = "$Id: protz.c,v 1.1 1993/08/04 19:36:25 jtc Exp $"; +const char protz_rcsid[] = "$Id: protz.c,v 1.2 1994/10/24 22:27:56 jtc Exp $"; #endif #include <errno.h> @@ -2084,7 +2084,7 @@ fifi: cZheaders_received++; break; } - DEBUG_MESSAGE2 (DEBUG_PROTO, "izrecv_hdr: %s, data = 0x%x", + DEBUG_MESSAGE2 (DEBUG_PROTO, "izrecv_hdr: %s, data = 0x%lx", ZZHEADER_NAME(c), rclhdr (hdr)); return c; diff --git a/gnu/libexec/uucp/uucico/rec.c b/gnu/libexec/uucp/uucico/rec.c index 160aab705ad..16ccb5140f9 100644 --- a/gnu/libexec/uucp/uucico/rec.c +++ b/gnu/libexec/uucp/uucico/rec.c @@ -1,7 +1,7 @@ /* rec.c Routines to receive a file. - Copyright (C) 1991, 1992 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -20,13 +20,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or - c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. */ #include "uucp.h" #if USE_RCS_ID -const char rec_rcsid[] = "$Id: rec.c,v 1.1 1993/08/04 19:36:28 jtc Exp $"; +const char rec_rcsid[] = "$Id: rec.c,v 1.2 1994/10/24 22:28:04 jtc Exp $"; #endif #include <errno.h> @@ -308,13 +308,22 @@ flocal_rec_send_request (qtrans, qdaemon) boolean fret; qinfo->ztemp = zsysdep_receive_temp (qdaemon->qsys, qinfo->zfile, - (const char *) NULL); + (const char *) NULL, + (qdaemon->qproto->frestart + && (qdaemon->ifeatures + & FEATURE_RESTART) != 0)); if (qinfo->ztemp == NULL) { urrec_free (qtrans); return FALSE; } + qtrans->fcmd = TRUE; + qtrans->precfn = flocal_rec_await_reply; + + if (! fqueue_receive (qdaemon, qtrans)) + return FALSE; + /* Check the amount of free space available for both the temporary file and the real file. */ cbytes = csysdep_bytes_free (qinfo->ztemp); @@ -354,16 +363,11 @@ flocal_rec_send_request (qtrans, qdaemon) fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, zsend, qtrans->ilocal, qtrans->iremote); ubuffree (zsend); - if (! fret) - { - urrec_free (qtrans); - return FALSE; - } - qtrans->fcmd = TRUE; - qtrans->precfn = flocal_rec_await_reply; + if (! fret) + urrec_free (qtrans); - return fqueue_receive (qdaemon, qtrans); + return fret; } /* This is called when a reply is received for the request. */ @@ -377,8 +381,8 @@ flocal_rec_await_reply (qtrans, qdaemon, zdata, cdata) size_t cdata; { struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo; - long crestart; const char *zlog; + char *zend; if (zdata[0] != 'R' || (zdata[1] != 'Y' && zdata[1] != 'N')) @@ -407,6 +411,18 @@ flocal_rec_await_reply (qtrans, qdaemon, zdata, cdata) zerr = "too large to receive now"; fnever = FALSE; } + else if (zdata[2] == '9') + { + /* Remote has run out of channels. */ + zerr = "too many channels for remote"; + fnever = FALSE; + + /* Drop one channel; using exactly one channel causes + slightly different behahaviour in a few places, so don't + decrement to one. */ + if (qdaemon->cchans > 2) + --qdaemon->cchans; + } else zerr = "unknown reason"; @@ -423,16 +439,25 @@ flocal_rec_await_reply (qtrans, qdaemon, zdata, cdata) /* The mode should have been sent as "RY 0%o". If it wasn't, we use 0666. */ qtrans->s.imode = (unsigned int) strtol ((char *) (zdata + 2), - (char **) NULL, 8); + &zend, 8); if (qtrans->s.imode == 0) qtrans->s.imode = 0666; + /* If there is an M after the mode, the remote has requested a + hangup. */ + if (*zend == 'M' && qdaemon->fmaster) + { + DEBUG_MESSAGE0 (DEBUG_UUCP_PROTO, + "flocal_rec_await_reply: Remote has requested transfer of control"); + qdaemon->fhangup_requested = TRUE; + } + /* Open the file to receive into. We just ignore any restart count, since we have no way to tell it to the other side. SVR4 may have some way to do this, but I don't know what it is. */ qtrans->e = esysdep_open_receive (qdaemon->qsys, qinfo->zfile, (const char *) NULL, qinfo->ztemp, - &crestart); + (long *) NULL); if (! ffileisopen (qtrans->e)) return flocal_rec_fail (qtrans, &qtrans->s, qdaemon->qsys, "cannot open file"); @@ -570,7 +595,15 @@ fremote_send_file_init (qdaemon, qcmd, iremote) } else { - zfile = zsysdep_local_file (qcmd->zto, qsys->uuconf_zpubdir); + boolean fbadname; + + zfile = zsysdep_local_file (qcmd->zto, qsys->uuconf_zpubdir, + &fbadname); + if (zfile == NULL && fbadname) + { + ulog (LOG_ERROR, "%s: bad local file name", qcmd->zto); + return fremote_send_fail (qdaemon, qcmd, FAILURE_PERM, iremote); + } if (zfile != NULL) { char *zadd; @@ -603,7 +636,10 @@ fremote_send_file_init (qdaemon, qcmd, iremote) } } - ztemp = zsysdep_receive_temp (qsys, zfile, qcmd->ztemp); + ztemp = zsysdep_receive_temp (qsys, zfile, qcmd->ztemp, + (qdaemon->qproto->frestart + && (qdaemon->ifeatures + & FEATURE_RESTART) != 0)); /* Adjust the number of bytes we are prepared to receive according to the amount of free space we are supposed to leave available @@ -646,7 +682,13 @@ fremote_send_file_init (qdaemon, qcmd, iremote) /* Open the file to receive into. This may find an old copy of the file, which will be used for file restart if the other side supports it. */ - e = esysdep_open_receive (qsys, zfile, qcmd->ztemp, ztemp, &crestart); + crestart = -1; + e = esysdep_open_receive (qsys, zfile, qcmd->ztemp, ztemp, + ((qdaemon->qproto->frestart + && (qdaemon->ifeatures + & FEATURE_RESTART) != 0) + ? &crestart + : (long *) NULL)); if (! ffileisopen (e)) { ubuffree (ztemp); @@ -656,21 +698,16 @@ fremote_send_file_init (qdaemon, qcmd, iremote) if (crestart > 0) { - if ((qdaemon->ifeatures & FEATURE_RESTART) == 0) - crestart = -1; - else + DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO, + "fremote_send_file_init: Restarting receive from %ld", + crestart); + if (! ffileseek (e, crestart)) { - DEBUG_MESSAGE1 (DEBUG_UUCP_PROTO, - "fremote_send_file_init: Restarting receive from %ld", - crestart); - if (! ffileseek (e, crestart)) - { - ulog (LOG_ERROR, "seek: %s", strerror (errno)); - (void) ffileclose (e); - ubuffree (ztemp); - ubuffree (zfile); - return FALSE; - } + ulog (LOG_ERROR, "seek: %s", strerror (errno)); + (void) ffileclose (e); + ubuffree (ztemp); + ubuffree (zfile); + return FALSE; } } @@ -705,8 +742,24 @@ fremote_send_file_init (qdaemon, qcmd, iremote) else zlog = qinfo->zfile; } - qtrans->zlog = zbufalc (sizeof "Receiving " + strlen (zlog)); + qtrans->zlog = zbufalc (sizeof "Receiving ( bytes resume at )" + + strlen (zlog) + 50); sprintf (qtrans->zlog, "Receiving %s", zlog); + if (crestart > 0 || qcmd->cbytes > 0) + { + strcat (qtrans->zlog, " ("); + if (qcmd->cbytes > 0) + { + sprintf (qtrans->zlog + strlen (qtrans->zlog), "%ld bytes", + qcmd->cbytes); + if (crestart > 0) + strcat (qtrans->zlog, " "); + } + if (crestart > 0) + sprintf (qtrans->zlog + strlen (qtrans->zlog), "resume at %ld", + crestart); + strcat (qtrans->zlog, ")"); + } return fqueue_remote (qdaemon, qtrans); } @@ -719,8 +772,20 @@ fremote_send_reply (qtrans, qdaemon) struct sdaemon *qdaemon; { struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo; + boolean fret; char ab[50]; + /* If the file has been completely received, we just want to send + the final confirmation. Otherwise, we must wait for the file + first. */ + qtrans->psendfn = frec_file_send_confirm; + if (qinfo->freceived) + fret = fqueue_send (qdaemon, qtrans); + else + fret = fqueue_receive (qdaemon, qtrans); + if (! fret) + return FALSE; + ab[0] = qtrans->s.bcmd; ab[1] = 'Y'; if (qtrans->ipos <= 0) @@ -751,18 +816,9 @@ fremote_send_reply (qtrans, qdaemon) urrec_free (qtrans); return FALSE; } - if (fhandled) - return TRUE; } - /* If the file has been completely received, we just want to send - the final confirmation. Otherwise, we must wait for the file - first. */ - qtrans->psendfn = frec_file_send_confirm; - if (qinfo->freceived) - return fqueue_send (qdaemon, qtrans); - else - return fqueue_receive (qdaemon, qtrans); + return TRUE; } /* If we can't receive a file, queue up a response to the remote @@ -784,7 +840,7 @@ fremote_send_fail (qdaemon, qcmd, twhy, iremote) /* If the protocol does not support multiple channels (cchans <= 1), then we have essentially already received the entire file. */ - qinfo->freceived = qdaemon->qproto->cchans <= 1; + qinfo->freceived = qdaemon->cchans <= 1; qtrans = qtransalc (qcmd); qtrans->psendfn = fremote_send_fail_send; @@ -807,6 +863,13 @@ fremote_send_fail_send (qtrans, qdaemon) char ab[4]; boolean fret; + /* Wait for the end of file marker if we haven't gotten it yet. */ + if (! qinfo->freceived) + { + if (! fqueue_receive (qdaemon, qtrans)) + return FALSE; + } + ab[0] = qtrans->s.bcmd; ab[1] = 'N'; @@ -840,13 +903,7 @@ fremote_send_fail_send (qtrans, qdaemon) qinfo->fsent = TRUE; - /* Wait for the end of file marker if we haven't gotten it yet. */ - if (! qinfo->freceived) - { - if (! fqueue_receive (qdaemon, qtrans)) - fret = FALSE; - } - else + if (qinfo->freceived) { xfree (qtrans->pinfo); utransfree (qtrans); @@ -902,6 +959,7 @@ frec_file_end (qtrans, qdaemon, zdata, cdata) size_t cdata; { struct srecinfo *qinfo = (struct srecinfo *) qtrans->pinfo; + char *zalc; const char *zerr; boolean fnever; @@ -929,10 +987,13 @@ frec_file_end (qtrans, qdaemon, zdata, cdata) fnever = FALSE; + zalc = NULL; + if (! ffileclose (qtrans->e)) { zerr = strerror (errno); ulog (LOG_ERROR, "%s: close: %s", qtrans->s.zto, zerr); + (void) remove (qinfo->ztemp); } else if (! fsysdep_move_file (qinfo->ztemp, qinfo->zfile, qinfo->fspool, FALSE, ! qinfo->fspool, @@ -940,7 +1001,49 @@ frec_file_end (qtrans, qdaemon, zdata, cdata) ? qtrans->s.zuser : (const char *) NULL))) { - zerr = "could not move to final location"; + long cspace; + + /* Keep the temporary file if there is 1.5 times the amount of + required free space. This is just a random guess, to make an + unusual situtation potentially less painful. */ + cspace = csysdep_bytes_free (qinfo->ztemp); + if (cspace == -1) + cspace = FREE_SPACE_DELTA; + cspace -= (qdaemon->qsys->uuconf_cfree_space + + qdaemon->qsys->uuconf_cfree_space / 2); + if (cspace < 0) + { + (void) remove (qinfo->ztemp); + zerr = "could not move to final location"; + } + else + { + const char *az[20]; + int i; + + zalc = zbufalc (sizeof "could not move to final location (left as )" + + strlen (qinfo->ztemp)); + sprintf (zalc, "could not move to final location (left as %s)", + qinfo->ztemp); + zerr = zalc; + + i = 0; + az[i++] = "The file\n\t"; + az[i++] = qinfo->ztemp; + az[i++] = + "\nwas saved because the move to the final location failed.\n"; + az[i++] = "See the UUCP logs for more details.\n"; + az[i++] = "The file transfer was from\n\t"; + az[i++] = qdaemon->qsys->uuconf_zname; + az[i++] = "!"; + az[i++] = qtrans->s.zfrom; + az[i++] = "\nto\n\t"; + az[i++] = qtrans->s.zto; + az[i++] = "\nand was requested by\n\t"; + az[i++] = qtrans->s.zuser; + az[i++] = "\n"; + (void) fsysdep_mail (OWNER, "UUCP temporary file saved", i, az); + } ulog (LOG_ERROR, "%s: %s", qinfo->zfile, zerr); fnever = TRUE; } @@ -963,12 +1066,10 @@ frec_file_end (qtrans, qdaemon, zdata, cdata) zerr = NULL; } - if (zerr != NULL) - (void) remove (qinfo->ztemp); - ustats (zerr == NULL, qtrans->s.zuser, qdaemon->qsys->uuconf_zname, FALSE, qtrans->cbytes, qtrans->isecs, qtrans->imicros, qdaemon->fmaster); + qdaemon->creceived += qtrans->cbytes; if (zerr == NULL) { @@ -1011,6 +1112,8 @@ frec_file_end (qtrans, qdaemon, zdata, cdata) } } + ubuffree (zalc); + /* If this is an execution request, we must create the execution file itself. */ if (qtrans->s.bcmd == 'E' && zerr == NULL) @@ -1040,7 +1143,10 @@ frec_file_end (qtrans, qdaemon, zdata, cdata) uuxqt might pick up the file before we have finished writing it. */ e = NULL; - ztemp = zsysdep_receive_temp (qdaemon->qsys, zxqtfile, "D.0"); + ztemp = zsysdep_receive_temp (qdaemon->qsys, zxqtfile, "D.0", + (qdaemon->qproto->frestart + && (qdaemon->ifeatures + & FEATURE_RESTART) != 0)); if (ztemp != NULL) e = esysdep_fopen (ztemp, FALSE, FALSE, TRUE); @@ -1077,7 +1183,10 @@ frec_file_end (qtrans, qdaemon, zdata, cdata) { if (! fsysdep_move_file (ztemp, zxqtfile, TRUE, FALSE, FALSE, (const char *) NULL)) - fbad = TRUE; + { + (void) remove (ztemp); + fbad = TRUE; + } } ubuffree (zxqtfile); @@ -1090,6 +1199,21 @@ frec_file_end (qtrans, qdaemon, zdata, cdata) } } + /* See if we should spawn a uuxqt process. */ + if (zerr == NULL + && (qtrans->s.bcmd == 'E' + || (qinfo->fspool && qtrans->s.zto[0] == 'X'))) + { + ++qdaemon->cxfiles_received; + if (qdaemon->irunuuxqt > 0 + && qdaemon->cxfiles_received >= qdaemon->irunuuxqt) + { + if (fspawn_uuxqt (TRUE, qdaemon->qsys->uuconf_zname, + qdaemon->zconfig)) + qdaemon->cxfiles_received = 0; + } + } + /* Prepare to send the completion string to the remote system. If we have not yet replied to the remote send request, we leave the transfer structure on the remote queue. Otherwise we add it to diff --git a/gnu/libexec/uucp/uucico/send.c b/gnu/libexec/uucp/uucico/send.c index 9337de39c69..535cd00dc66 100644 --- a/gnu/libexec/uucp/uucico/send.c +++ b/gnu/libexec/uucp/uucico/send.c @@ -1,7 +1,7 @@ /* send.c Routines to send a file. - Copyright (C) 1991, 1992 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -20,13 +20,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or - c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. */ #include "uucp.h" #if USE_RCS_ID -const char send_rcsid[] = "$Id: send.c,v 1.1 1993/08/04 19:36:29 jtc Exp $"; +const char send_rcsid[] = "$Id: send.c,v 1.2 1994/10/24 22:28:11 jtc Exp $"; #endif #include <errno.h> @@ -51,7 +51,9 @@ struct ssendinfo boolean flocal; /* TRUE if this is a spool directory file. */ boolean fspool; - /* TRUE if the file has been completely sent. */ + /* TRUE if the file has been completely sent. Also used in + flocal_send_cancelled to mean that the file send will never + succeed. */ boolean fsent; /* Execution file for sending an unsupported E request. */ char *zexec; @@ -62,7 +64,7 @@ struct ssendinfo static void usfree_send P((struct stransfer *qtrans)); static boolean flocal_send_fail P((struct stransfer *qtrans, struct scmd *qcmd, - const struct uuconf_system *qsys, + struct sdaemon *qdaemon, const char *zwhy)); static boolean flocal_send_request P((struct stransfer *qtrans, struct sdaemon *qdaemon)); @@ -150,10 +152,9 @@ usfree_send (qtrans) flocal_send_request. If flocal_send_await_reply is called before the entire file has - been sent: if it gets an SN, it calls flocal_send_cancelled to send - an empty data block to inform the remote system that the file - transfer has stopped. If it gets a file position request, it must - adjust the file position accordingly. + been sent: if it gets an SN, it sets the file position to the end + and arranges to call flocal_send_cancelled. If it gets a file + position request, it must adjust the file position accordingly. If flocal_send_await_reply is called after the entire file has been sent: if it gets an SN, it can simply delete the request. It can @@ -197,7 +198,7 @@ flocal_send_file_init (qdaemon, qcmd) is possible, but it might have changed since then. */ if (! qsys->uuconf_fcall_transfer && ! qsys->uuconf_fcalled_transfer) - return flocal_send_fail ((struct stransfer *) NULL, qcmd, qsys, + return flocal_send_fail ((struct stransfer *) NULL, qcmd, qdaemon, "not permitted to transfer files"); /* We can't do the request now, but it may get done later. */ @@ -214,7 +215,7 @@ flocal_send_file_init (qdaemon, qcmd) qsys->uuconf_pzlocal_send, qsys->uuconf_zpubdir, TRUE, TRUE, qcmd->zuser)) - return flocal_send_fail ((struct stransfer *) NULL, qcmd, qsys, + return flocal_send_fail ((struct stransfer *) NULL, qcmd, qdaemon, "not permitted to send"); zfile = zbufcpy (qcmd->zfrom); } @@ -234,12 +235,13 @@ flocal_send_file_init (qdaemon, qcmd) { ubuffree (zfile); if (cbytes != -1) - return FALSE; + return flocal_send_fail ((struct stransfer *) NULL, qcmd, qdaemon, + "can not get size"); /* A cbytes value of -1 means that the file does not exist. This can happen legitimately if it has already been sent from the spool directory. */ if (! fspool) - return flocal_send_fail ((struct stransfer *) NULL, qcmd, qsys, + return flocal_send_fail ((struct stransfer *) NULL, qcmd, qdaemon, "does not exist"); (void) fsysdep_did_work (qcmd->pseq); return TRUE; @@ -264,7 +266,7 @@ flocal_send_file_init (qdaemon, qcmd) if (qdaemon->cmax_ever != -1 && qdaemon->cmax_ever < qcmd->cbytes) - return flocal_send_fail ((struct stransfer *) NULL, qcmd, qsys, + return flocal_send_fail ((struct stransfer *) NULL, qcmd, qdaemon, "too large to send"); return TRUE; @@ -280,7 +282,7 @@ flocal_send_file_init (qdaemon, qcmd) qinfo->zmail = zbufcpy (qcmd->zuser); qinfo->zfile = zfile; qinfo->cbytes = cbytes; - qinfo->flocal = TRUE; + qinfo->flocal = strchr (qcmd->zuser, '!') == NULL; qinfo->fspool = fspool; qinfo->fsent = FALSE; qinfo->zexec = NULL; @@ -296,32 +298,48 @@ flocal_send_file_init (qdaemon, qcmd) this reports an error to the log file and to the user. */ static boolean -flocal_send_fail (qtrans, qcmd, qsys, zwhy) +flocal_send_fail (qtrans, qcmd, qdaemon, zwhy) struct stransfer *qtrans; struct scmd *qcmd; - const struct uuconf_system *qsys; + struct sdaemon *qdaemon; const char *zwhy; { if (zwhy != NULL) { + const char *zfrom; char *zfree; + const char *ztemp; if (qcmd->bcmd != 'E') - zfree = NULL; + { + zfrom = qcmd->zfrom; + zfree = NULL; + } else { - zfree = zbufalc (sizeof "Execution of \"\": " - + strlen (qcmd->zcmd) - + strlen (zwhy)); - sprintf (zfree, "Execution of \"%s\": %s", qcmd->zcmd, zwhy); - zwhy = zfree; + zfree = zbufalc (strlen (qcmd->zfrom) + + sizeof " (execution of \"\")" + + strlen (qcmd->zcmd)); + sprintf (zfree, "%s (execution of \"%s\")", qcmd->zfrom, + qcmd->zcmd); + zfrom = zfree; } - ulog (LOG_ERROR, "%s: %s", qcmd->zfrom, zwhy); + ulog (LOG_ERROR, "%s: %s", zfrom, zwhy); + + /* We only save the temporary file if this is a request from the + local system; otherwise a remote system could launch a denial + of service attack by filling up the .Preserve directory + (local users have much simpler methods for this type of + denial of service attack, so there is little point to using a + more sophisticated scheme). */ + if (strchr (qcmd->zuser, '!') == NULL) + ztemp = zsysdep_save_temp_file (qcmd->pseq); + else + ztemp = NULL; (void) fmail_transfer (FALSE, qcmd->zuser, (const char *) NULL, - zwhy, qcmd->zfrom, (const char *) NULL, - qcmd->zto, qsys->uuconf_zname, - zsysdep_save_temp_file (qcmd->pseq)); + zwhy, zfrom, (const char *) NULL, + qcmd->zto, qdaemon->qsys->uuconf_zname, ztemp); ubuffree (zfree); } @@ -353,9 +371,37 @@ flocal_send_request (qtrans, qdaemon) /* Make sure the file meets any remote size restrictions. */ if (qdaemon->cmax_receive != -1 && qdaemon->cmax_receive < qinfo->cbytes) - return flocal_send_fail (qtrans, &qtrans->s, qdaemon->qsys, + return flocal_send_fail (qtrans, &qtrans->s, qdaemon, "too large for receiver"); + /* Make sure the file still exists--it may have been removed between + the conversation startup and now. After we have sent over the S + command we must give an error if we can't find the file. */ + if (! fsysdep_file_exists (qinfo->zfile)) + { + (void) fsysdep_did_work (qtrans->s.pseq); + usfree_send (qtrans); + return TRUE; + } + + /* If we are using a protocol which can make multiple channels, then + we can open and send the file whenever we are ready. This is + because we will be able to distinguish the response by the + channel it is directed to. This assumes that every protocol + which supports multiple channels also supports sending the file + position in mid-stream, since otherwise we would not be able to + restart files. */ + qtrans->fcmd = TRUE; + qtrans->psendfn = flocal_send_open_file; + qtrans->precfn = flocal_send_await_reply; + + if (qdaemon->cchans > 1) + fret = fqueue_send (qdaemon, qtrans); + else + fret = fqueue_receive (qdaemon, qtrans); + if (! fret) + return FALSE; + /* Construct the notify string to send. If we are going to send a size or an execution command, it must be non-empty. */ znotify = qtrans->s.znotify; @@ -452,27 +498,11 @@ flocal_send_request (qtrans, qdaemon) fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, zsend, qtrans->ilocal, qtrans->iremote); ubuffree (zsend); - if (! fret) - { - usfree_send (qtrans); - return FALSE; - } - /* If we are using a protocol which can make multiple channels, then - we can open and send the file whenever we are ready. This is - because we will be able to distinguish the response by the - channel it is directed to. This assumes that every protocol - which supports multiple channels also supports sending the file - position in mid-stream, since otherwise we would not be able to - restart files. */ - qtrans->fcmd = TRUE; - qtrans->psendfn = flocal_send_open_file; - qtrans->precfn = flocal_send_await_reply; + if (! fret) + usfree_send (qtrans); - if (qdaemon->qproto->cchans > 1) - return fqueue_send (qdaemon, qtrans); - else - return fqueue_receive (qdaemon, qtrans); + return fret; } /* This is called when a reply is received for the send request. As @@ -535,21 +565,36 @@ flocal_send_await_reply (qtrans, qdaemon, zdata, cdata) is no need to resend the file. */ zerr = NULL; } + else if (zdata[2] == '9') + { + /* Remote has run out of channels. */ + zerr = "too many channels for remote"; + fnever = FALSE; + + /* Drop one channel; using exactly one channel causes + slightly different behahaviour in a few places, so don't + decrement to one. */ + if (qdaemon->cchans > 2) + --qdaemon->cchans; + } else zerr = "unknown reason"; - if (! fnever) + if (! fnever + || (qtrans->s.bcmd == 'E' + && (qdaemon->ifeatures & FEATURE_EXEC) == 0 + && qinfo->zexec == NULL)) { if (qtrans->s.bcmd == 'E') - ulog (LOG_ERROR, "Execution of \"%s\": %s", qtrans->s.zcmd, - zerr); + ulog (LOG_ERROR, "%s (execution of \"%s\"): %s", + qtrans->s.zfrom, qtrans->s.zcmd, zerr); else ulog (LOG_ERROR, "%s: %s", qtrans->s.zfrom, zerr); } else { if (! flocal_send_fail ((struct stransfer *) NULL, &qtrans->s, - qdaemon->qsys, zerr)) + qdaemon, zerr)) return FALSE; } @@ -558,16 +603,39 @@ flocal_send_await_reply (qtrans, qdaemon, zdata, cdata) the remote side knows that we have finished sending the file data. If we have already sent the entire file, there will be no confusion. */ - if (qdaemon->qproto->cchans == 1 || qinfo->fsent) + if (qdaemon->cchans == 1 || qinfo->fsent) { + /* If we are breaking a 'E' command into two 'S' commands, + and that was for the first 'S' command, we still have to + send the second one. */ + if (fnever + && qtrans->s.bcmd == 'E' + && (qdaemon->ifeatures & FEATURE_EXEC) == 0 + && qinfo->zexec == NULL) + return fsend_exec_file_init (qtrans, qdaemon); + usfree_send (qtrans); return TRUE; } else { + /* Seek to the end of the file so that the next read will + send end of file. We have to be careful here, because we + may have actually already sent end of file--we could be + being called because of data received while the end of + file block was sent. */ + if (! ffileseekend (qtrans->e)) + { + ulog (LOG_ERROR, "seek to end: %s", strerror (errno)); + usfree_send (qtrans); + return FALSE; + } qtrans->psendfn = flocal_send_cancelled; qtrans->precfn = NULL; - qtrans->fsendfile = FALSE; + + /* Reuse fsent to pass fnever to flocal_send_cancelled. */ + qinfo->fsent = fnever; + return fqueue_send (qdaemon, qtrans); } } @@ -603,7 +671,7 @@ flocal_send_await_reply (qtrans, qdaemon, zdata, cdata) qtrans->precfn = fsend_await_confirm; if (qinfo->fsent) return fqueue_receive (qdaemon, qtrans); - else if (qdaemon->qproto->cchans <= 1) + else if (qdaemon->cchans <= 1) return fqueue_send (qdaemon, qtrans); else return TRUE; @@ -638,7 +706,9 @@ flocal_send_open_file (qtrans, qdaemon) qtrans->s.zfrom, (const char *) NULL, qtrans->s.zto, qdaemon->qsys->uuconf_zname, - zsysdep_save_temp_file (qtrans->s.pseq)); + (qinfo->flocal + ? zsysdep_save_temp_file (qtrans->s.pseq) + : (const char *) NULL)); (void) fsysdep_did_work (qtrans->s.pseq); usfree_send (qtrans); @@ -688,8 +758,15 @@ flocal_send_open_file (qtrans, qdaemon) sprintf (zalc, "%s (%s)", qtrans->s.zcmd, qtrans->s.zfrom); zsend = zalc; } - qtrans->zlog = zbufalc (sizeof "Sending " + strlen (zsend)); - sprintf (qtrans->zlog, "Sending %s", zsend); + + qtrans->zlog = zbufalc (sizeof "Sending ( bytes resume at )" + + strlen (zsend) + 50); + sprintf (qtrans->zlog, "Sending %s (%ld bytes", zsend, qinfo->cbytes); + if (qtrans->ipos > 0) + sprintf (qtrans->zlog + strlen (qtrans->zlog), " resume at %ld", + qtrans->ipos); + strcat (qtrans->zlog, ")"); + ubuffree (zalc); } @@ -698,7 +775,8 @@ flocal_send_open_file (qtrans, qdaemon) boolean fhandled; if (! (*qdaemon->qproto->pffile) (qdaemon, qtrans, TRUE, TRUE, - qinfo->cbytes, &fhandled)) + qinfo->cbytes - qtrans->ipos, + &fhandled)) { usfree_send (qtrans); return FALSE; @@ -719,32 +797,29 @@ flocal_send_open_file (qtrans, qdaemon) return fqueue_send (qdaemon, qtrans); } -/* Cancel a file send by sending an empty buffer. This is only called - for a protocol which supports multiple channels. It is needed - so that both systems agree as to when a channel is no longer - needed. */ +/* Cancel a file send. This is only called for a protocol which + supports multiple channels. It is needed so that both systems + agree as to when a channel is no longer needed. */ static boolean flocal_send_cancelled (qtrans, qdaemon) struct stransfer *qtrans; struct sdaemon *qdaemon; { - char *zdata; - size_t cdata; - boolean fret; - - zdata = (*qdaemon->qproto->pzgetspace) (qdaemon, &cdata); - if (zdata == NULL) - { - usfree_send (qtrans); - return FALSE; - } + struct ssendinfo *qinfo = (struct ssendinfo *) qtrans->pinfo; + + /* If we are breaking a 'E' command into two 'S' commands, and that + was for the first 'S' command, and the first 'S' command will + never be sent (passed as qinfo->fsent), we still have to send the + second one. */ + if (qinfo->fsent + && qtrans->s.bcmd == 'E' + && (qdaemon->ifeatures & FEATURE_EXEC) == 0 + && qinfo->zexec == NULL) + return fsend_exec_file_init (qtrans, qdaemon); - fret = (*qdaemon->qproto->pfsenddata) (qdaemon, zdata, (size_t) 0, - qtrans->ilocal, qtrans->iremote, - qtrans->ipos); usfree_send (qtrans); - return fret; + return TRUE; } /* A remote request to receive a file (meaning that we have to send a @@ -765,6 +840,7 @@ fremote_rec_file_init (qdaemon, qcmd, iremote) { const struct uuconf_system *qsys; char *zfile; + boolean fbadname; long cbytes; unsigned int imode; openfile_t e; @@ -786,7 +862,12 @@ fremote_rec_file_init (qdaemon, qcmd, iremote) return fremote_rec_fail (qdaemon, FAILURE_PERM, iremote); } - zfile = zsysdep_local_file (qcmd->zfrom, qsys->uuconf_zpubdir); + zfile = zsysdep_local_file (qcmd->zfrom, qsys->uuconf_zpubdir, &fbadname); + if (zfile == NULL && fbadname) + { + ulog (LOG_ERROR, "%s: bad local file name", qcmd->zfrom); + return fremote_rec_fail (qdaemon, FAILURE_PERM, iremote); + } if (zfile != NULL) { char *zbased; @@ -875,8 +956,24 @@ fremote_rec_reply (qtrans, qdaemon) struct ssendinfo *qinfo = (struct ssendinfo *) qtrans->pinfo; char absend[50]; - sprintf (absend, "RY 0%o 0x%lx", qtrans->s.imode, - (unsigned long) qinfo->cbytes); + qtrans->fsendfile = TRUE; + qtrans->psendfn = fsend_file_end; + qtrans->precfn = fsend_await_confirm; + + if (! fqueue_send (qdaemon, qtrans)) + return FALSE; + + /* We send the file size because SVR4 UUCP does. We don't look for + it. We send a trailing M if we want to request a hangup. We + send it both after the mode and at the end of the entire string; + I don't know where programs look for it. */ + if (qdaemon->frequest_hangup) + DEBUG_MESSAGE0 (DEBUG_UUCP_PROTO, + "fremote_rec_reply: Requesting remote to transfer control"); + sprintf (absend, "RY 0%o%s 0x%lx%s", qtrans->s.imode, + qdaemon->frequest_hangup ? "M" : "", + (unsigned long) qinfo->cbytes, + qdaemon->frequest_hangup ? "M" : ""); if (! (*qdaemon->qproto->pfsendcmd) (qdaemon, absend, qtrans->ilocal, qtrans->iremote)) { @@ -885,8 +982,10 @@ fremote_rec_reply (qtrans, qdaemon) return FALSE; } - qtrans->zlog = zbufalc (sizeof "Sending " + strlen (qtrans->s.zfrom)); - sprintf (qtrans->zlog, "Sending %s", qtrans->s.zfrom); + qtrans->zlog = zbufalc (sizeof "Sending ( bytes) " + + strlen (qtrans->s.zfrom) + 25); + sprintf (qtrans->zlog, "Sending %s (%ld bytes)", qtrans->s.zfrom, + qinfo->cbytes); if (qdaemon->qproto->pffile != NULL) { @@ -898,16 +997,9 @@ fremote_rec_reply (qtrans, qdaemon) usfree_send (qtrans); return FALSE; } - - if (fhandled) - return TRUE; } - qtrans->fsendfile = TRUE; - qtrans->psendfn = fsend_file_end; - qtrans->precfn = fsend_await_confirm; - - return fqueue_send (qdaemon, qtrans); + return TRUE; } /* If we can't send a file as requested by the remote system, queue up @@ -1057,6 +1149,7 @@ fsend_await_confirm (qtrans, qdaemon, zdata, cdata) ustats (zerr == NULL, qtrans->s.zuser, qdaemon->qsys->uuconf_zname, TRUE, qtrans->cbytes, qtrans->isecs, qtrans->imicros, qdaemon->fmaster); + qdaemon->csent += qtrans->cbytes; if (zerr == NULL) { diff --git a/gnu/libexec/uucp/uucico/time.c b/gnu/libexec/uucp/uucico/time.c index c082662c2bf..4d1f37dfeec 100644 --- a/gnu/libexec/uucp/uucico/time.c +++ b/gnu/libexec/uucp/uucico/time.c @@ -1,7 +1,7 @@ /* time.c Routines to deal with UUCP time spans. - Copyright (C) 1991, 1992 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -20,18 +20,20 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or - c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. */ #include "uucp.h" #if USE_RCS_ID -const char time_rcsid[] = "$Id: time.c,v 1.1 1993/08/04 19:36:30 jtc Exp $"; +const char time_rcsid[] = "$Id: time.c,v 1.2 1994/10/24 22:28:16 jtc Exp $"; #endif #include <ctype.h> -#if HAVE_TIME_H +#if TM_IN_SYS_TIME +#include <sys/time.h> +#else #include <time.h> #endif diff --git a/gnu/libexec/uucp/uucico/trans.c b/gnu/libexec/uucp/uucico/trans.c index 065caa4ac79..c3ca5faf5d1 100644 --- a/gnu/libexec/uucp/uucico/trans.c +++ b/gnu/libexec/uucp/uucico/trans.c @@ -1,7 +1,7 @@ /* trans.c Routines to handle file transfers. - Copyright (C) 1992 Ian Lance Taylor + Copyright (C) 1992, 1993 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -20,13 +20,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or - c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. */ #include "uucp.h" #if USE_RCS_ID -const char trans_rcsid[] = "$Id: trans.c,v 1.1 1993/08/04 19:36:31 jtc Exp $"; +const char trans_rcsid[] = "$Id: trans.c,v 1.2 1994/10/24 22:28:19 jtc Exp $"; #endif #include <errno.h> @@ -233,7 +233,39 @@ fqueue_send (qdaemon, qtrans) ulog (LOG_FATAL, "fqueue_send: Bad call"); #endif utdequeue (qtrans); - utqueue (&qTsend, qtrans, FALSE); + + /* Sort the send queue to always send commands before files, and to + sort jobs by grade. */ + if (qTsend == NULL) + utqueue (&qTsend, qtrans, FALSE); + else + { + register struct stransfer *q; + boolean ffirst; + + ffirst = TRUE; + q = qTsend; + do + { + if (! qtrans->fsendfile && q->fsendfile) + break; + if ((! qtrans->fsendfile || q->fsendfile) + && UUCONF_GRADE_CMP (qtrans->s.bgrade, q->s.bgrade) < 0) + break; + + ffirst = FALSE; + q = q->qnext; + } + while (q != qTsend); + + qtrans->qnext = q; + qtrans->qprev = q->qprev; + q->qprev = qtrans; + qtrans->qprev->qnext = qtrans; + if (ffirst) + qTsend = qtrans; + qtrans->pqqueue = &qTsend; + } /* Since we're now going to wait to send data, don't charge this transfer for receive time. */ @@ -273,7 +305,7 @@ utchanalc (qdaemon, qtrans) do { ++iTchan; - if (iTchan > qdaemon->qproto->cchans) + if (iTchan > qdaemon->cchans) iTchan = 1; } while (aqTchan[iTchan] != NULL); @@ -388,6 +420,7 @@ utransfree (q) } #if DEBUG > 0 + q->e = EFILECLOSED; q->zcmd = NULL; q->s.zfrom = NULL; q->s.zto = NULL; @@ -625,18 +658,12 @@ static boolean fcheck_queue (qdaemon) struct sdaemon *qdaemon; { - int cchans; - /* Only check if we are the master, or if there are multiple channels, or if we aren't already trying to get the other side to hang up. Otherwise, there's nothing we can do with any new jobs we might find. */ - if ((qdaemon->ireliable & UUCONF_RELIABLE_FULLDUPLEX) == 0) - cchans = 1; - else - cchans = qdaemon->qproto->cchans; if (qdaemon->fmaster - || cchans > 1 + || qdaemon->cchans > 1 || ! qdaemon->frequest_hangup) { boolean fany; @@ -649,7 +676,7 @@ fcheck_queue (qdaemon) /* If we found something to do, and we're not the master, and we don't have multiple channels to send new jobs over, try to get the other side to hang up. */ - if (fany && ! qdaemon->fmaster && cchans <= 1) + if (fany && ! qdaemon->fmaster && qdaemon->cchans <= 1) qdaemon->frequest_hangup = TRUE; } @@ -663,17 +690,8 @@ boolean floop (qdaemon) struct sdaemon *qdaemon; { - int cchans; boolean fret; - /* If we are using a half-duplex line, act as though we have only a - single channel; otherwise we might start a send and a receive at - the same time. */ - if ((qdaemon->ireliable & UUCONF_RELIABLE_FULLDUPLEX) == 0) - cchans = 1; - else - cchans = qdaemon->qproto->cchans; - fret = TRUE; while (! qdaemon->fhangup) @@ -759,9 +777,9 @@ floop (qdaemon) /* If we are the master, or if we have multiple channels, try to queue up additional local jobs. */ - if (qdaemon->fmaster || cchans > 1) + if (qdaemon->fmaster || qdaemon->cchans > 1) { - while (qTlocal != NULL && cTchans < cchans) + while (qTlocal != NULL && cTchans < qdaemon->cchans) { /* We have room for an additional channel. */ q = qTlocal; @@ -821,11 +839,14 @@ floop (qdaemon) q->zlog = NULL; } - /* We can read the file in a tight loop until qTremote - changes or until we have transferred the entire file. - We can disregard any changes to qTlocal since we - already have something to send anyhow. */ - while (qTremote == NULL) + /* We can read the file in a tight loop until we have a + command to send, or the file send has been cancelled, + or we have a remote job to deal with. We can + disregard any changes to qTlocal since we already + have something to send anyhow. */ + while (q == qTsend + && q->fsendfile + && qTremote == NULL) { char *zdata; size_t cdata; @@ -865,11 +886,6 @@ floop (qdaemon) break; } - /* It is possible that this transfer has just been - cancelled. */ - if (q != qTsend || ! q->fsendfile) - break; - if (cdata == 0) { /* We must update the time now, because this @@ -978,7 +994,6 @@ fgot_data (qdaemon, zfirst, cfirst, zsecond, csecond, ilocal, iremote, ipos, else { /* Get the transfer structure this data is intended for. */ - q = qtchan (ilocal); } @@ -1014,7 +1029,8 @@ fgot_data (qdaemon, zfirst, cfirst, zsecond, csecond, ilocal, iremote, ipos, else cnew = cfirst; znew = zbufalc (q->ccmd + cnew + 1); - memcpy (znew, q->zcmd, q->ccmd); + if (q->ccmd > 0) + memcpy (znew, q->zcmd, q->ccmd); memcpy (znew + q->ccmd, zfirst, cnew); znew[q->ccmd + cnew] = '\0'; ubuffree (q->zcmd); @@ -1206,6 +1222,12 @@ ftadd_cmd (qdaemon, z, clen, iremote, flast) return TRUE; } + /* Some systems seem to sometimes send garbage at the end of the + command. Avoid interpreting it as a size if sizes are not + supported. */ + if ((qdaemon->ifeatures & FEATURE_SIZES) == 0) + s.cbytes = -1; + if (s.bcmd != 'H' && s.bcmd != 'Y' && s.bcmd != 'N') ulog_user (s.zuser); else @@ -1391,9 +1413,15 @@ ufailed (qdaemon) { if ((q->fsendfile || q->frecfile) && q->cbytes > 0) - ustats (FALSE, q->s.zuser, qdaemon->qsys->uuconf_zname, - q->fsendfile, q->cbytes, q->isecs, q->imicros, - FALSE); + { + ustats (FALSE, q->s.zuser, qdaemon->qsys->uuconf_zname, + q->fsendfile, q->cbytes, q->isecs, q->imicros, + FALSE); + if (q->fsendfile) + qdaemon->csent += q->cbytes; + else + qdaemon->creceived += q->cbytes; + } if (q->frecfile) (void) frec_discard_temp (qdaemon, q); q = q->qnext; @@ -1408,9 +1436,15 @@ ufailed (qdaemon) { if ((q->fsendfile || q->frecfile) && q->cbytes > 0) - ustats (FALSE, q->s.zuser, qdaemon->qsys->uuconf_zname, - q->fsendfile, q->cbytes, q->isecs, q->imicros, - FALSE); + { + ustats (FALSE, q->s.zuser, qdaemon->qsys->uuconf_zname, + q->fsendfile, q->cbytes, q->isecs, q->imicros, + FALSE); + if (q->fsendfile) + qdaemon->csent += q->cbytes; + else + qdaemon->creceived += q->cbytes; + } if (q->frecfile) (void) frec_discard_temp (qdaemon, q); q = q->qnext; diff --git a/gnu/libexec/uucp/uucico/uucico.8 b/gnu/libexec/uucp/uucico/uucico.8 index fba8bb588fc..ddd474c9cbe 100644 --- a/gnu/libexec/uucp/uucico/uucico.8 +++ b/gnu/libexec/uucp/uucico/uucico.8 @@ -1,5 +1,5 @@ -''' $Id: uucico.8,v 1.1 1993/08/04 19:36:33 jtc Exp $ -.TH uucico 8 "Taylor UUCP 1.04" +''' $Id: uucico.8,v 1.2 1994/10/24 22:28:25 jtc Exp $ +.TH uucico 8 "Taylor UUCP 1.05" .SH NAME uucico \- UUCP file transfer daemon .SH SYNOPSIS @@ -23,17 +23,17 @@ entries in the .I crontab table(s). -When invoked with the -.B \-r1 -option or the -.B \-s +When invoked with +.B \-r1, +.B \-\-master, +.B \-s, +.B \-\-system, or -.B \-S -option, the daemon will place a call to a remote system, running in -master mode. -Otherwise the daemon will start in slave mode, accepting a -call from a remote system. Typically a special login name will be set -up for UUCP which automatically invokes +.B \-S, +the daemon will place a call to a remote system, running in master +mode. Otherwise the daemon will start in slave mode, accepting a call +from a remote system. Typically a special login name will be set up +for UUCP which automatically invokes .I uucico when a call is made. @@ -43,6 +43,8 @@ terminates, it invokes the .I uuxqt (8) daemon, unless the .B \-q +or +.B \-\-nouuxqt option is given; .I uuxqt (8) executes any work orders created by @@ -55,28 +57,47 @@ If a call fails, will normally refuse to retry the call until a certain (configurable) amount of time has passed. This may be overriden by the -.B -f -or the +.B -f, +.B --force, +or .B -S option. The -.B \-l +.B \-l, +.B \-\-prompt, +.B \-e, or -.B \-e -option may be used to force +.B \-\-loop +options may be used to force .I uucico to produce its own prompts of "login: " and "Password:". When another -daemon calls in, it will see these prompts and log in as usual; the -login name and password will be checked against a separate list kept -specially for +daemon calls in, it will see these prompts and log in as usual. The +login name and password will normally be checked against a separate +list kept specially for .I uucico rather than the .I /etc/passwd +file; it is possible on some systems to direct +.I uucico +to use the +.I /etc/passwd file. The .B \-l -option will prompt once and then exit. The +or +.B \--prompt +option will prompt once and then exit; in this mode the UUCP +administrator or the superuser may use the +.B \-u +or +.B \--login +option to force a login name, in which case +.I uucico +will not prompt for one. +The .B \-e +or +.B \--loop option will prompt again after the first session is over; in this mode .I uucico will permanently control a port. @@ -87,9 +108,13 @@ receives a SIGQUIT, SIGTERM or SIGPIPE signal, it will cleanly abort any current conversation with a remote system and exit. If it receives a SIGHUP signal it will abort any current conversation, but will continue to place calls to (if invoked with -.B \-r1) +.B \-r1 +or +.B \-\-master) and accept calls from (if invoked with -.B \-e) +.B \-e +or +.B \-\-loop) other systems. If it receives a SIGINT signal it will finish the current conversation, but will not place or accept any more calls. @@ -97,72 +122,91 @@ place or accept any more calls. The following options may be given to .I uucico. .TP 5 -.B \-r1 +.B \-r1, \-\-master Start in master mode (call out to a system); implied by -.B \-s +.B \-s, +.B \-\-system, or .B \-S. If no system is specified, call any system for which work is waiting to be done. .TP 5 -.B \-r0 +.B \-r0, \-\-slave Start in slave mode. This is the default. .TP 5 -.B \-s system +.B \-s system, \-\-system system Call the named system. .TP 5 .B \-S system -Call the named system, ignoring any required wait. +Call the named system, ignoring any required wait. This is equivalent +to +.B \-s system \-f. .TP 5 -.B \-f +.B \-f, \-\-force Ignore any required wait for any systems to be called. .TP 5 -.B \-l +.B \-l, \-\-prompt Prompt for login name and password using "login: " and "Password:". This allows .I uucico to be easily run from .I inetd (8). The login name and password are checked against the UUCP -password file, which has no connection to the file +password file, which probably has no connection to the file .I /etc/passwd. +The +.B \-\-login +option may be used to force a login name, in which cause +.I uucico +will only prompt for a password. .TP 5 -.B \-p port -Specify a port to call out on or to listen to. In slave mode, this -implies -.B \-e. +.B \-p port, \-\-port port +Specify a port to call out on or to listen to. .TP 5 -.B \-e +.B \-e, \-\-loop Enter endless loop of login/password prompts and slave mode daemon execution. The program will not stop by itself; you must use .I kill (1) to shut it down. .TP 5 -.B \-w +.B \-w, \-\-wait After calling out (to a particular system when -.B \-s +.B \-s, +.B \-\-system, or .B \-S -is specifed, or to all systems which have work when +is specifed, or to all systems which have work when just .B \-r1 +or +.B \-\-master is specifed), begin an endless loop as with -.B \-e. +.B \-\-loop. .TP 5 -.B \-q +.B \-q, \-\-nouuxqt Do not start the .I uuxqt (8) daemon when finished. .TP 5 -.B \-c +.B \-c, \-\-quiet If no calls are permitted at this time, then don't make the call, but also do not put an error message in the log file and do not update the system status (as reported by .I uustat (1)). This can be convenient for automated polling scripts, which may want to simply attempt to call every system rather than worry about -which particular systems may be called at the moment. +which particular systems may be called at the moment. This option +also suppresses the log message indicating that there is no work to be +done. .TP 5 -.B \-D +.B \-C, \-\-ifwork +Only call the system named by +.B \-s, +.B \-\-system +or +.B \-S +if there is work for that system. +.TP 5 +.B \-D, \-\-nodetach Do not detach from the controlling terminal. Normally .I uucico detaches from the terminal before each call out to another system and @@ -170,29 +214,57 @@ before invoking .I uuxqt. This option prevents this. .TP 5 -.B \-x type, \-X type +.B \-u name, \-\-login name +Set the login name to use instead of that of the invoking user. This +option may only be used by the UUCP administrator or the superuser. +If used with +.B \-\-prompt, +this will cause +.I uucico +to prompt only for the password, not the login name. +.TP 5 +.B \-z, \-\-try-next +If a call fails after the remote system is reached, try the next +alternate rather than simply exiting. +.TP 5 +.B \-i type, \-\-stdin type +Set the type of port to use when using standard input. The only +support port type is TLI, and this is only available on machines which +support the TLI networking interface. Specifying +.B \-iTLI +causes +.I uucico +to use TLI calls to perform I/O. +.TP 5 +.B \-x type, \-X type, \-\-debug type Turn on particular debugging types. The following types are recognized: abnormal, chat, handshake, uucp-proto, proto, port, config, spooldir, execute, incoming, outgoing. Multiple types may be given, separated by commas, and the -.B \-x +.B \-\-debug option may appear multiple times. A number may also be given, which will turn on that many types from the foregoing list; for example, -.B \-x 2 +.B \-\-debug 2 is equivalent to -.B \-x abnormal,chat. +.B \-\-debug abnormal,chat. The debugging output is sent to the debugging file, usually one of /usr/spool/uucp/Debug, /usr/spool/uucp/DEBUG, or /usr/spool/uucp/.Admin/audit.local. .TP 5 -.B \-I file +.B \-I file, \-\-config file Set configuration file to use. This option may not be available, depending upon how .I uucico was compiled. .TP 5 +.B \-v, \-\-version +Report version information and exit. +.TP 5 +.B \-\-help +Print a help message and exit. +.TP 5 .B \-u login This option is ignored. It is only included because some versions of uucpd invoke @@ -222,4 +294,4 @@ Debugging file. kill(1), uucp(1), uux(1), uustat(1), uuxqt(8) .SH AUTHOR Ian Lance Taylor -(ian@airs.com or uunet!airs!ian) +<ian@airs.com> diff --git a/gnu/libexec/uucp/uucico/uucico.c b/gnu/libexec/uucp/uucico/uucico.c index ecd6c235c80..d0e6efa50ad 100644 --- a/gnu/libexec/uucp/uucico/uucico.c +++ b/gnu/libexec/uucp/uucico/uucico.c @@ -1,7 +1,7 @@ /* uucico.c This is the main UUCP communication program. - Copyright (C) 1991, 1992 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -20,13 +20,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or - c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. */ #include "uucp.h" #if USE_RCS_ID -const char uucico_rcsid[] = "$Id: uucico.c,v 1.1 1993/08/04 19:36:34 jtc Exp $"; +const char uucico_rcsid[] = "$Id: uucico.c,v 1.2 1994/10/24 22:28:29 jtc Exp $"; #endif #include <ctype.h> @@ -45,10 +45,21 @@ const char uucico_rcsid[] = "$Id: uucico.c,v 1.1 1993/08/04 19:36:34 jtc Exp $"; #include "prot.h" #include "trans.h" #include "system.h" - -/* The program name. */ -char abProgram[] = "uucico"; +#if HAVE_ENCRYPTED_PASSWORDS +#ifndef crypt +extern char *crypt (); +#endif +#endif + +/* Coherent already had a different meaning for the -c option. What a + pain. */ +#ifdef __COHERENT__ +#define COHERENT_C_OPTION 1 +#else +#define COHERENT_C_OPTION 0 +#endif + /* Define the known protocols. */ #define TCP_PROTO \ @@ -58,30 +69,33 @@ char abProgram[] = "uucico"; static const struct sprotocol asProtocols[] = { - { 't', TCP_PROTO, 1, + { 't', TCP_PROTO, 1, TRUE, asTproto_params, ftstart, ftshutdown, ftsendcmd, ztgetspace, ftsenddata, ftwait, ftfile }, - { 'e', TCP_PROTO, 1, + { 'e', TCP_PROTO, 1, TRUE, asEproto_params, festart, feshutdown, fesendcmd, zegetspace, fesenddata, fewait, fefile }, - { 'i', UUCONF_RELIABLE_EIGHT, 7, + { 'i', UUCONF_RELIABLE_EIGHT, 7, TRUE, asIproto_params, fistart, fishutdown, fisendcmd, zigetspace, fisenddata, fiwait, NULL }, - { 'a', UUCONF_RELIABLE_EIGHT, 1, + { 'a', UUCONF_RELIABLE_EIGHT, 1, TRUE, asZproto_params, fzstart, fzshutdown, fzsendcmd, zzgetspace, fzsenddata, fzwait, fzfile }, - { 'g', UUCONF_RELIABLE_EIGHT, 1, + { 'g', UUCONF_RELIABLE_EIGHT, 1, TRUE, asGproto_params, fgstart, fgshutdown, fgsendcmd, zggetspace, fgsenddata, fgwait, NULL }, - { 'G', UUCONF_RELIABLE_EIGHT, 1, + { 'G', UUCONF_RELIABLE_EIGHT, 1, TRUE, asGproto_params, fbiggstart, fgshutdown, fgsendcmd, zggetspace, fgsenddata, fgwait, NULL }, - { 'j', UUCONF_RELIABLE_EIGHT, 7, + { 'j', UUCONF_RELIABLE_EIGHT, 7, TRUE, asIproto_params, fjstart, fjshutdown, fisendcmd, zigetspace, fisenddata, fiwait, NULL }, - { 'f', UUCONF_RELIABLE_RELIABLE, 1, + { 'f', UUCONF_RELIABLE_RELIABLE, 1, FALSE, asFproto_params, ffstart, ffshutdown, ffsendcmd, zfgetspace, ffsenddata, ffwait, fffile }, + { 'v', UUCONF_RELIABLE_EIGHT, 1, TRUE, + asGproto_params, fvstart, fgshutdown, fgsendcmd, zggetspace, + fgsenddata, fgwait, NULL } }; #define CPROTOCOLS (sizeof asProtocols / sizeof asProtocols[0]) @@ -112,12 +126,13 @@ struct spass /* Local functions. */ static void uusage P((void)); +static void uhelp P((void)); static void uabort P((void)); -static boolean fcall P((pointer puuconf, +static boolean fcall P((pointer puuconf, const char *zconfig, boolean fuuxqt, const struct uuconf_system *qsys, struct uuconf_port *qport, boolean fifwork, boolean fforce, boolean fdetach, - boolean ftimewarn)); + boolean fquiet, boolean ftrynext)); static boolean fconn_call P((struct sdaemon *qdaemon, struct uuconf_port *qport, struct sstatus *qstat, int cretry, @@ -127,11 +142,19 @@ static boolean fdo_call P((struct sdaemon *qdaemon, const struct uuconf_dialer *qdialer, boolean *pfcalled, enum tstatus_type *pterr)); static int iuport_lock P((struct uuconf_port *qport, pointer pinfo)); -static boolean flogin_prompt P((pointer puuconf, - struct sconnection *qconn)); -static boolean faccept_call P((pointer puuconf, const char *zlogin, +static boolean flogin_prompt P((pointer puuconf, const char *zconfig, + boolean fuuxqt, struct sconnection *qconn, + const char *zlogin)); +static int icallin_cmp P((int iwhich, pointer pinfo, const char *zfile)); +static boolean faccept_call P((pointer puuconf, const char *zconfig, + boolean fuuxqt, const char *zlogin, struct sconnection *qconn, const char **pzsystem)); +static void uaccept_call_cleanup P((pointer puuconf, + struct uuconf_system *qfreesys, + struct uuconf_port *qport, + struct uuconf_port *qfreeport, + char *zloc)); static void uapply_proto_params P((pointer puuconf, int bproto, struct uuconf_cmdtab *qcmds, struct uuconf_proto_param *pas)); @@ -142,21 +165,47 @@ static char *zget_uucp_cmd P((struct sconnection *qconn, static char *zget_typed_line P((struct sconnection *qconn)); /* Long getopt options. */ -static const struct option asLongopts[] = { { NULL, 0, NULL, 0 } }; +static const struct option asLongopts[] = +{ + { "quiet", no_argument, NULL, 2 }, + { "ifwork", no_argument, NULL, 'C' }, + { "nodetach", no_argument, NULL, 'D' }, + { "loop", no_argument, NULL, 'e' }, + { "force", no_argument, NULL, 'f'}, + { "stdin", required_argument, NULL, 'i' }, + { "prompt", no_argument, NULL, 'l' }, + { "port", required_argument, NULL, 'p' }, + { "nouuxqt", no_argument, NULL, 'q' }, + { "master", no_argument, NULL, 3 }, + { "slave", no_argument, NULL, 4 }, + { "system", required_argument, NULL, 's' }, + { "login", required_argument, NULL, 'u' }, + { "wait", no_argument, NULL, 'w' }, + { "try-next", no_argument, NULL, 'z' }, + { "config", required_argument, NULL, 'I' }, + { "debug", required_argument, NULL, 'x' }, + { "version", no_argument, NULL, 'v' }, + { "help", no_argument, NULL, 1 }, + { NULL, 0, NULL, 0 } +}; int main (argc, argv) int argc; char **argv; { - /* -c: Whether to warn if a call is attempted at a bad time. */ - boolean ftimewarn = TRUE; + /* -c: Whether to be quiet. */ + boolean fquiet = FALSE; + /* -C: Only call the system if there is work. */ + boolean fifwork = FALSE; /* -D: don't detach from controlling terminal. */ boolean fdetach = TRUE; /* -e: Whether to do an endless loop of accepting calls. */ boolean fendless = FALSE; /* -f: Whether to force a call despite status of previous call. */ boolean fforce = FALSE; + /* -i type: type of port to use for stdin. */ + enum uuconf_porttype tstdintype = UUCONF_PORTTYPE_STDIN; /* -I file: configuration file name. */ const char *zconfig = NULL; /* -l: Whether to give a single login prompt. */ @@ -172,8 +221,13 @@ main (argc, argv) boolean fmaster = FALSE; /* -s,-S system: system to call. */ const char *zsystem = NULL; + /* -u: Login name to use. */ + const char *zlogin = NULL; /* -w: Whether to wait for a call after doing one. */ boolean fwait = FALSE; + /* -z: Try next alternate if call fails. */ + boolean ftrynext = FALSE; + const char *zopts; int iopt; struct uuconf_port *qport; struct uuconf_port sport; @@ -184,15 +238,40 @@ main (argc, argv) int iholddebug; #endif - while ((iopt = getopt_long (argc, argv, - "cDefI:lp:qr:s:S:u:x:X:w", + zProgram = argv[0]; + + /* When uucico is invoked by login, the first character of the + program will be a dash. We don't want that. */ + if (*zProgram == '-') + ++zProgram; + +#if COHERENT_C_OPTION + zopts = "c:CDefi:I:lp:qr:s:S:u:x:X:vwz"; +#else + zopts = "cCDefi:I:lp:qr:s:S:u:x:X:vwz"; +#endif + + while ((iopt = getopt_long (argc, argv, zopts, asLongopts, (int *) NULL)) != EOF) { +#if COHERENT_C_OPTION + if (iopt == 'c') + { + iopt = 's'; + fifwork = TRUE; + } +#endif switch (iopt) { + case 2: case 'c': - /* Don't warn if a call is attempted at a bad time. */ - ftimewarn = FALSE; + /* Don't warn if a call is attempted at a bad time, and + don't print the "No work" message. */ + fquiet = TRUE; + break; + + case 'C': + fifwork = TRUE; break; case 'D': @@ -211,10 +290,23 @@ main (argc, argv) fforce = TRUE; break; - case 'I': - /* Set configuration file name (default is in sysdep.h). */ - if (fsysdep_other_config (optarg)) - zconfig = optarg; + case 'i': + /* Type of port to use for standard input. Only TLI is + supported here, and only if HAVE_TLI is true. This + permits the Network Listener to tell uucico to use TLI + I/O calls. */ + if (strcasecmp (optarg, "tli") != 0) + fprintf (stderr, "%s: unsupported port type \"%s\"\n", + zProgram, optarg); + else + { +#if HAVE_TLI + tstdintype = UUCONF_PORTTYPE_TLI; +#else + fprintf (stderr, "%s: not compiled with TLI support\n", + zProgram); +#endif + } break; case 'l': @@ -257,31 +349,71 @@ main (argc, argv) case 'u': /* Some versions of uucpd invoke uucico with a -u argument - specifying the login name. I'm told it is safe to ignore - this value, although perhaps we should use it rather than - zsysdep_login_name (). */ + specifying the login name. If invoked by a privileged + user, we use it instead of the result of + zsysdep_login_name. */ + if (fsysdep_privileged ()) + zlogin = optarg; + else + fprintf (stderr, + "%s: ignoring command line login name: not a privileged user\n", + zProgram); + break; + + case 'w': + /* Call out and then wait for a call in */ + fwait = TRUE; + break; + + case 'z': + /* Try next alternate if call fails. */ + ftrynext = TRUE; + break; + + case 'I': + /* Set configuration file name (default is in sysdep.h). */ + if (fsysdep_other_config (optarg)) + zconfig = optarg; break; case 'x': case 'X': #if DEBUG > 1 - /* Set debugging level */ + /* Set debugging level. */ iDebug |= idebug_parse (optarg); #endif break; - case 'w': - /* Call out and then wait for a call in */ - fwait = TRUE; + case 'v': + /* Print version and exit. */ + printf ("%s: Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", + zProgram, VERSION); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + + case 4: + /* --slave. */ + fmaster = FALSE; break; + case 3: + /* --master. */ + fmaster = TRUE; + break; + + case 1: + /* --help. */ + uhelp (); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + case 0: /* Long option found, and flag value set. */ break; default: uusage (); - break; + /*NOTREACHED*/ } } @@ -290,7 +422,7 @@ main (argc, argv) if (fwait && zport == NULL) { - ulog (LOG_ERROR, "-w requires -e"); + fprintf (stderr, "%s: -w requires -p", zProgram); uusage (); } @@ -321,7 +453,7 @@ main (argc, argv) pointer))) NULL, (pointer) NULL, &sport); if (iuuconf == UUCONF_NOT_FOUND) - ulog (LOG_FATAL, "%s: Port not found", zport); + ulog (LOG_FATAL, "%s: port not found", zport); else if (iuuconf != UUCONF_SUCCESS) ulog_uuconf (LOG_FATAL, puuconf, iuuconf); qport = &sport; @@ -384,8 +516,8 @@ main (argc, argv) else { fLocked_system = TRUE; - fret = fcall (puuconf, &sLocked_system, qport, FALSE, - fforce, fdetach, ftimewarn); + fret = fcall (puuconf, zconfig, fuuxqt, &sLocked_system, qport, + fifwork, fforce, fdetach, fquiet, ftrynext); if (fLocked_system) { (void) fsysdep_unlock_system (&sLocked_system); @@ -468,8 +600,9 @@ main (argc, argv) else { fLocked_system = TRUE; - if (! fcall (puuconf, &sLocked_system, qport, TRUE, - fforce, fdetach, ftimewarn)) + if (! fcall (puuconf, zconfig, fuuxqt, &sLocked_system, + qport, TRUE, fforce, fdetach, fquiet, + ftrynext)) fret = FALSE; /* Now ignore any SIGHUP that we got. */ @@ -493,7 +626,7 @@ main (argc, argv) xfree ((pointer) pznames); - if (! fdidone) + if (! fdidone && ! fquiet) ulog (LOG_NORMAL, "No work"); } @@ -520,7 +653,7 @@ main (argc, argv) fret = TRUE; zsystem = NULL; - if (! fconn_init (qport, &sconn)) + if (! fconn_init (qport, &sconn, tstdintype)) fret = FALSE; if (qport != NULL) @@ -531,9 +664,6 @@ main (argc, argv) if (fdetach && qport->uuconf_ttype != UUCONF_PORTTYPE_STDIN) usysdep_detach (); - - /* If a port was given, we loop forever. */ - fendless = TRUE; } if (fconn_lock (&sconn, TRUE)) @@ -558,17 +688,14 @@ main (argc, argv) if (fendless) { while (! FGOT_SIGNAL () - && flogin_prompt (puuconf, &sconn)) + && flogin_prompt (puuconf, zconfig, fuuxqt, &sconn, + (const char *) NULL)) { - /* Now ignore any SIGHUP that we got. */ - afSignal[INDEXSIG_SIGHUP] = FALSE; - - if (fLocked_system) - { - (void) fsysdep_unlock_system (&sLocked_system); - fLocked_system = FALSE; - } - if (! fconn_reset (&sconn)) + /* Close and reopen the port in between calls. */ + if (! fconn_close (&sconn, puuconf, + (struct uuconf_dialer *) NULL, + TRUE) + || ! fconn_open (&sconn, (long) 0, (long) 0, TRUE)) break; } fret = FALSE; @@ -576,13 +703,16 @@ main (argc, argv) else { if (flogin) - fret = flogin_prompt (puuconf, &sconn); + fret = flogin_prompt (puuconf, zconfig, fuuxqt, &sconn, + zlogin); else { #if DEBUG > 1 iholddebug = iDebug; #endif - fret = faccept_call (puuconf, zsysdep_login_name (), + if (zlogin == NULL) + zlogin = zsysdep_login_name (); + fret = faccept_call (puuconf, zconfig, fuuxqt, zlogin, &sconn, &zsystem); #if DEBUG > 1 iDebug = iholddebug; @@ -602,12 +732,6 @@ main (argc, argv) if (flocked) (void) fconn_unlock (&sconn); - if (fLocked_system) - { - (void) fsysdep_unlock_system (&sLocked_system); - fLocked_system = FALSE; - } - uconn_free (&sconn); } @@ -622,19 +746,19 @@ main (argc, argv) if (fuuxqt) { - /* Detach from the controlling terminal before starting up uuxqt, - so that it runs as a true daemon. */ - if (fdetach) - usysdep_detach (); - if (zsystem == NULL) - { - if (! fsysdep_run ("uuxqt", (const char *) NULL, - (const char *) NULL)) - fret = FALSE; - } - else + int irunuuxqt; + + iuuconf = uuconf_runuuxqt (puuconf, &irunuuxqt); + if (iuuconf != UUCONF_SUCCESS) + ulog_uuconf (LOG_ERROR, puuconf, iuuconf); + else if (irunuuxqt == UUCONF_RUNUUXQT_ONCE) { - if (! fsysdep_run ("uuxqt", "-s", zsystem)) + /* Detach from the controlling terminal before starting up uuxqt, + so that it runs as a true daemon. */ + if (fdetach) + usysdep_detach (); + + if (! fspawn_uuxqt (FALSE, zsystem, zconfig)) fret = FALSE; } } @@ -645,40 +769,46 @@ main (argc, argv) return 0; } -/* Print out a usage message. */ +/* Print out a usage message and die. */ static void uusage () { - fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", + fprintf (stderr, "Usage: %s [options]\n", zProgram); + fprintf (stderr, "Use %s --help for help\n", zProgram); + exit (EXIT_FAILURE); +} + +/* Print a help message. */ + +static void +uhelp () +{ + printf ("Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", VERSION); - fprintf (stderr, - "Usage: uucico [options]\n"); - fprintf (stderr, - " -s,-S system: Call system (-S implies -f)\n"); - fprintf (stderr, - " -f: Force call despite system status\n"); - fprintf (stderr, - " -r state: 1 for master, 0 for slave (default)\n"); - fprintf (stderr, - " -p port: Specify port (implies -e)\n"); - fprintf (stderr, - " -l: prompt for login name and password\n"); - fprintf (stderr, - " -e: Endless loop of login prompts and daemon execution\n"); - fprintf (stderr, - " -w: After calling out, wait for incoming calls\n"); - fprintf (stderr, - " -q: Don't start uuxqt when done\n"); - fprintf (stderr, - " -x,-X debug: Set debugging level\n"); + printf ("Usage: %s [options]\n", zProgram); + printf (" -s,-S,--system system: Call system (-S implies -f)\n"); + printf (" -f,--force: Force call despite system status\n"); + printf (" -r state: 1 for master, 0 for slave (default)\n"); + printf (" --master: Act as master\n"); + printf (" --slave: Act as slave (default)\n"); + printf (" -p,--port port: Specify port\n"); + printf (" -l,--prompt: prompt for login name and password\n"); + printf (" -e,--loop: Endless loop of login prompts and daemon execution\n"); + printf (" -w,--wait: After calling out, wait for incoming calls\n"); + printf (" -q,--nouuxqt: Don't start uuxqt when done\n"); + printf (" -c,--quiet: Don't log bad time or no work warnings\n"); + printf (" -C,--ifwork: Only call named system if there is work\n"); + printf (" -D,--nodetach: Don't detach from controlling terminal\n"); + printf (" -u,--login: Set login name (privileged users only)\n"); + printf (" -i,--stdin type: Type of standard input (only TLI supported)\n"); + printf (" -z,--try-next: If a call fails, try the next alternate\n"); + printf (" -x,-X,--debug debug: Set debugging level\n"); #if HAVE_TAYLOR_CONFIG - fprintf (stderr, - " -I file: Set configuration file to use\n"); + printf (" -I,--config file: Set configuration file to use\n"); #endif /* HAVE_TAYLOR_CONFIG */ - - exit (EXIT_FAILURE); + printf (" -v,--version: Print version and exit\n"); + printf (" --help: Print help and exit\n"); } /* This function is called when a LOG_FATAL error occurs. */ @@ -713,28 +843,36 @@ uabort () usysdep_exit (FALSE); } +/* The number of seconds in one day. We must cast to long for this + to be calculated correctly on a machine with 16 bit ints. */ +#define SECS_PER_DAY ((long) 24 * (long) 60 * (long) 60) + /* Call another system, trying all the possible sets of calling instructions. The qsys argument is the system to call. The qport argument is the port to use, and may be NULL. If the fifwork argument is TRUE, the call is only placed if there is work to be done. If the fforce argument is TRUE, a call is forced even if not - enough time has passed since the last failed call. If the - ftimewarn argument is TRUE (the normal case), then a warning is - given if calls are not permitted at this time. */ + enough time has passed since the last failed call. If the fquiet + argument is FALSE (the normal case), then a warning is given if + calls are not permitted at this time. */ static boolean -fcall (puuconf, qorigsys, qport, fifwork, fforce, fdetach, ftimewarn) +fcall (puuconf, zconfig, fuuxqt, qorigsys, qport, fifwork, fforce, fdetach, + fquiet, ftrynext) pointer puuconf; + const char *zconfig; + boolean fuuxqt; const struct uuconf_system *qorigsys; struct uuconf_port *qport; boolean fifwork; boolean fforce; boolean fdetach; - boolean ftimewarn; + boolean fquiet; + boolean ftrynext; { struct sstatus sstat; long inow; - boolean fbadtime, fnevertime; + boolean fbadtime, fnevertime, ffoundwork; const struct uuconf_system *qsys; if (! fsysdep_get_status (qorigsys, &sstat, (boolean *) NULL)) @@ -744,21 +882,24 @@ fcall (puuconf, qorigsys, qport, fifwork, fforce, fdetach, ftimewarn) that we haven't exceeded the maximum number of retries. Even if we are over the limit on retries, we permit a call to be made if 24 hours have passed. This 24 hour limit is still controlled by - the retry time. */ + the retry time. We ignore times in the future, presumably the + result of some sort of error. */ inow = ixsysdep_time ((long *) NULL); if (! fforce) { if (qorigsys->uuconf_cmax_retries > 0 && sstat.cretries >= qorigsys->uuconf_cmax_retries - && sstat.ilast + 24 * 60 * 60 < inow) + && sstat.ilast <= inow + && sstat.ilast + SECS_PER_DAY > inow) { ulog (LOG_ERROR, "Too many retries"); return FALSE; } - if (sstat.ttype == STATUS_COMPLETE - ? sstat.ilast + qorigsys->uuconf_csuccess_wait > inow - : sstat.ilast + sstat.cwait > inow) + if ((sstat.ttype == STATUS_COMPLETE + ? sstat.ilast + qorigsys->uuconf_csuccess_wait > inow + : sstat.ilast + sstat.cwait > inow) + && sstat.ilast <= inow) { ulog (LOG_NORMAL, "Retry time not reached"); return FALSE; @@ -766,14 +907,29 @@ fcall (puuconf, qorigsys, qport, fifwork, fforce, fdetach, ftimewarn) } sDaemon.puuconf = puuconf; + sDaemon.zconfig = zconfig; + if (! fuuxqt) + sDaemon.irunuuxqt = UUCONF_RUNUUXQT_NEVER; + else + { + int iuuconf; + + iuuconf = uuconf_runuuxqt (puuconf, &sDaemon.irunuuxqt); + if (iuuconf != UUCONF_SUCCESS) + ulog_uuconf (LOG_ERROR, puuconf, iuuconf); + } sDaemon.qsys = NULL; sDaemon.zlocalname = NULL; sDaemon.qconn = NULL; sDaemon.qproto = NULL; + sDaemon.cchans = 1; sDaemon.clocal_size = -1; sDaemon.cremote_size = -1; sDaemon.cmax_ever = -2; sDaemon.cmax_receive = -1; + sDaemon.csent = 0; + sDaemon.creceived = 0; + sDaemon.cxfiles_received = 0; sDaemon.ifeatures = 0; sDaemon.frequest_hangup = FALSE; sDaemon.fhangup_requested = FALSE; @@ -785,6 +941,7 @@ fcall (puuconf, qorigsys, qport, fifwork, fforce, fdetach, ftimewarn) fbadtime = TRUE; fnevertime = TRUE; + ffoundwork = FALSE; for (qsys = qorigsys; qsys != NULL; qsys = qsys->uuconf_qalternate) { @@ -804,6 +961,8 @@ fcall (puuconf, qorigsys, qport, fifwork, fforce, fdetach, ftimewarn) &cretry)) continue; + fbadtime = FALSE; + sDaemon.qsys = qsys; /* Queue up any work there is to do. */ @@ -820,7 +979,7 @@ fcall (puuconf, qorigsys, qport, fifwork, fforce, fdetach, ftimewarn) continue; } - fbadtime = FALSE; + ffoundwork = TRUE; fret = fconn_call (&sDaemon, qport, &sstat, cretry, &fcalled); @@ -828,7 +987,7 @@ fcall (puuconf, qorigsys, qport, fifwork, fforce, fdetach, ftimewarn) if (fret) return TRUE; - if (fcalled) + if (fcalled && ! ftrynext) return FALSE; /* Now we have to dump that port so that we can aquire a new @@ -845,9 +1004,16 @@ fcall (puuconf, qorigsys, qport, fifwork, fforce, fdetach, ftimewarn) } } - if (fbadtime && ftimewarn) + /* We only get here if no call succeeded. If fbadtime is TRUE it + was the wrong time for all the alternates. Otherwise, if + ffoundwork is FALSE there was no work for any of the alternates. + Otherwise, we attempted a call and fconn_call logged an error + message. */ + + if (fbadtime) { - ulog (LOG_NORMAL, "Wrong time to call"); + if (! fquiet) + ulog (LOG_NORMAL, "Wrong time to call"); /* Update the status, unless the system can never be called. If the system can never be called, there is little point to @@ -862,6 +1028,12 @@ fcall (puuconf, qorigsys, qport, fifwork, fforce, fdetach, ftimewarn) (void) fsysdep_set_status (qorigsys, &sstat); } } + else if (! ffoundwork) + { + if (! fquiet) + ulog (LOG_NORMAL, "No work"); + return TRUE; + } return FALSE; } @@ -905,7 +1077,7 @@ fconn_call (qdaemon, qport, qstat, cretry, pfcalled) qport = qsys->uuconf_qport; if (qport != NULL) { - if (! fconn_init (qport, &sconn)) + if (! fconn_init (qport, &sconn, UUCONF_PORTTYPE_UNKNOWN)) return FALSE; if (! fconn_lock (&sconn, FALSE)) { @@ -972,6 +1144,7 @@ fconn_call (qdaemon, qport, qstat, cretry, pfcalled) if (! fconn_dial (&sconn, puuconf, qsys, qsys->uuconf_zphone, &sdialer, &tdialer)) { + tdialer = DIALERFOUND_FALSE; terr = STATUS_DIAL_FAILED; fret = FALSE; } @@ -1068,7 +1241,8 @@ fdo_call (qdaemon, qstat, qdialer, pfcalled, pterr) if (strncmp (zstr, "Shere", 5) != 0) { - ulog (LOG_ERROR, "Bad initialization string"); + ulog (LOG_ERROR, "Bad startup string (expected \"Shere\" got \"%s\")", + zstr); ubuffree (zstr); return FALSE; } @@ -1218,7 +1392,7 @@ fdo_call (qdaemon, qstat, qdialer, pfcalled, pterr) if (zstr[0] != 'R') { - ulog (LOG_ERROR, "Bad reponse to handshake string (%s)", + ulog (LOG_ERROR, "Bad response to handshake string (%s)", zstr); ubuffree (zstr); return FALSE; @@ -1376,6 +1550,14 @@ fdo_call (qdaemon, qstat, qdialer, pfcalled, pterr) qdaemon->qproto = &asProtocols[i]; + /* If we are using a half-duplex line, act as though we have only + a single channel; otherwise we might start a send and a receive + at the same time. */ + if ((qdaemon->ireliable & UUCONF_RELIABLE_FULLDUPLEX) == 0) + qdaemon->cchans = 1; + else + qdaemon->cchans = asProtocols[i].cchans; + sprintf (ab, "U%c", qdaemon->qproto->bname); if (! fsend_uucp_cmd (qconn, ab)) return FALSE; @@ -1449,8 +1631,12 @@ fdo_call (qdaemon, qstat, qdialer, pfcalled, pterr) iend_time = ixsysdep_time ((long *) NULL); - ulog (LOG_NORMAL, "Call complete (%ld seconds)", - iend_time - istart_time); + ulog (LOG_NORMAL, "Call complete (%ld seconds %ld bytes %ld bps)", + iend_time - istart_time, + qdaemon->csent + qdaemon->creceived, + (iend_time != istart_time + ? (qdaemon->csent + qdaemon->creceived) / (iend_time - istart_time) + : 0)); if (fret) { @@ -1459,6 +1645,11 @@ fdo_call (qdaemon, qstat, qdialer, pfcalled, pterr) (void) fsysdep_set_status (qsys, qstat); } + if (qdaemon->irunuuxqt == UUCONF_RUNUUXQT_PERCALL + || (qdaemon->irunuuxqt > 0 && qdaemon->cxfiles_received > 0)) + (void) fspawn_uuxqt (TRUE, qdaemon->qsys->uuconf_zname, + qdaemon->zconfig); + return fret; } } @@ -1477,7 +1668,7 @@ iuport_lock (qport, pinfo) q->fmatched = TRUE; - if (! fconn_init (qport, q->qconn)) + if (! fconn_init (qport, q->qconn, UUCONF_PORTTYPE_UNKNOWN)) return UUCONF_NOT_FOUND; else if (! fconn_lock (q->qconn, FALSE)) { @@ -1491,31 +1682,49 @@ iuport_lock (qport, pinfo) } } +/* The information structure used for the uuconf_callin comparison + function. */ + +struct scallin_info +{ + const char *zuser; + const char *zpass; +}; + /* Prompt for a login name and a password, and run as the slave. */ static boolean -flogin_prompt (puuconf, qconn) +flogin_prompt (puuconf, zconfig, fuuxqt, qconn, zlogin) pointer puuconf; + const char *zconfig; + boolean fuuxqt; struct sconnection *qconn; + const char *zlogin; { char *zuser, *zpass; boolean fret; int iuuconf; + struct scallin_info s; DEBUG_MESSAGE0 (DEBUG_HANDSHAKE, "flogin_prompt: Waiting for login"); zuser = NULL; - do + if (zlogin == NULL) { - ubuffree (zuser); - if (! fconn_write (qconn, "login: ", sizeof "login: " - 1)) - return FALSE; - zuser = zget_typed_line (qconn); - } - while (zuser != NULL && *zuser == '\0'); + do + { + ubuffree (zuser); + if (! fconn_write (qconn, "login: ", sizeof "login: " - 1)) + return FALSE; + zuser = zget_typed_line (qconn); + } + while (zuser != NULL && *zuser == '\0'); + + if (zuser == NULL) + return TRUE; - if (zuser == NULL) - return TRUE; + zlogin = zuser; + } if (! fconn_write (qconn, "Password:", sizeof "Password:" - 1)) { @@ -1532,8 +1741,12 @@ flogin_prompt (puuconf, qconn) fret = TRUE; - iuuconf = uuconf_callin (puuconf, zuser, zpass); + s.zuser = zlogin; + s.zpass = zpass; + iuuconf = uuconf_callin (puuconf, icallin_cmp, &s); + ubuffree (zpass); + if (iuuconf == UUCONF_NOT_FOUND) ulog (LOG_ERROR, "Bad login"); else if (iuuconf != UUCONF_SUCCESS) @@ -1553,7 +1766,8 @@ flogin_prompt (puuconf, qconn) #if DEBUG > 1 iholddebug = iDebug; #endif - (void) faccept_call (puuconf, zuser, qconn, (const char **) NULL); + (void) faccept_call (puuconf, zconfig, fuuxqt, zlogin, qconn, + (const char **) NULL); #if DEBUG > 1 iDebug = iholddebug; #endif @@ -1564,12 +1778,43 @@ flogin_prompt (puuconf, qconn) return fret; } +/* The comparison function which we pass to uuconf_callin. This + expands escape sequences in the login name, and either encrypts or + expands escape sequences in the password. */ + +static int +icallin_cmp (iwhich, pinfo, zfile) + int iwhich; + pointer pinfo; + const char *zfile; +{ + struct scallin_info *qinfo = (struct scallin_info *) pinfo; + char *zcopy; + int icmp; + +#if HAVE_ENCRYPTED_PASSWORDS + if (iwhich != 0) + return strcmp (crypt (qinfo->zpass, zfile), zfile) == 0; +#endif + + zcopy = zbufcpy (zfile); + (void) cescape (zcopy); + if (iwhich == 0) + icmp = strcmp (qinfo->zuser, zcopy); + else + icmp = strcmp (qinfo->zpass, zcopy); + ubuffree (zcopy); + return icmp == 0; +} + /* Accept a call from a remote system. If pqsys is not NULL, *pqsys will be set to the system that called in if known. */ static boolean -faccept_call (puuconf, zlogin, qconn, pzsystem) +faccept_call (puuconf, zconfig, fuuxqt, zlogin, qconn, pzsystem) pointer puuconf; + const char *zconfig; + boolean fuuxqt; const char *zlogin; struct sconnection *qconn; const char **pzsystem; @@ -1635,6 +1880,9 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) else if (iuuconf != UUCONF_SUCCESS) { ulog_uuconf (LOG_ERROR, puuconf, iuuconf); + uaccept_call_cleanup (puuconf, (struct uuconf_system *) NULL, + (struct uuconf_port *) NULL, + &sport, (char *) NULL); return FALSE; } else @@ -1669,14 +1917,27 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) } sDaemon.puuconf = puuconf; + sDaemon.zconfig = zconfig; + if (! fuuxqt) + sDaemon.irunuuxqt = UUCONF_RUNUUXQT_NEVER; + else + { + iuuconf = uuconf_runuuxqt (puuconf, &sDaemon.irunuuxqt); + if (iuuconf != UUCONF_SUCCESS) + ulog_uuconf (LOG_ERROR, puuconf, iuuconf); + } sDaemon.qsys = NULL; sDaemon.zlocalname = NULL; sDaemon.qconn = qconn; sDaemon.qproto = NULL; + sDaemon.cchans = 1; sDaemon.clocal_size = -1; sDaemon.cremote_size = -1; sDaemon.cmax_ever = -2; sDaemon.cmax_receive = -1; + sDaemon.csent = 0; + sDaemon.creceived = 0; + sDaemon.cxfiles_received = 0; sDaemon.ifeatures = 0; sDaemon.frequest_hangup = FALSE; sDaemon.fhangup_requested = FALSE; @@ -1695,11 +1956,17 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) { sDaemon.zlocalname = zsysdep_localname (); if (sDaemon.zlocalname == NULL) - return FALSE; + { + uaccept_call_cleanup (puuconf, (struct uuconf_system *) NULL, + qport, &sport, (char *) NULL); + return FALSE; + } } else { ulog_uuconf (LOG_ERROR, puuconf, iuuconf); + uaccept_call_cleanup (puuconf, (struct uuconf_system *) NULL, + qport, &sport, (char *) NULL); return FALSE; } @@ -1709,16 +1976,26 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) fret = fsend_uucp_cmd (qconn, zsend); ubuffree (zsend); if (! fret) - return FALSE; + { + uaccept_call_cleanup (puuconf, (struct uuconf_system *) NULL, + qport, &sport, zloc); + return FALSE; + } zstr = zget_uucp_cmd (qconn, TRUE); if (zstr == NULL) - return FALSE; + { + uaccept_call_cleanup (puuconf, (struct uuconf_system *) NULL, + qport, &sport, zloc); + return FALSE; + } if (zstr[0] != 'S') { ulog (LOG_ERROR, "Bad introduction string"); ubuffree (zstr); + uaccept_call_cleanup (puuconf, (struct uuconf_system *) NULL, + qport, &sport, zloc); return FALSE; } @@ -1740,6 +2017,8 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) xfree ((pointer) zscript); (void) fsend_uucp_cmd (qconn, "RYou are unknown to me"); ubuffree (zstr); + uaccept_call_cleanup (puuconf, (struct uuconf_system *) NULL, + qport, &sport, zloc); return FALSE; } xfree ((pointer) zscript); @@ -1748,6 +2027,8 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) { ulog_uuconf (LOG_ERROR, puuconf, iuuconf); ubuffree (zstr); + uaccept_call_cleanup (puuconf, (struct uuconf_system *) NULL, + qport, &sport, zloc); return FALSE; } @@ -1756,6 +2037,8 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) (void) fsend_uucp_cmd (qconn, "RYou are unknown to me"); ulog (LOG_ERROR, "Call from unknown system %s", zstr + 1); ubuffree (zstr); + uaccept_call_cleanup (puuconf, (struct uuconf_system *) NULL, + qport, &sport, zloc); return FALSE; } } @@ -1763,6 +2046,8 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) { ulog_uuconf (LOG_ERROR, puuconf, iuuconf); ubuffree (zstr); + uaccept_call_cleanup (puuconf, (struct uuconf_system *) NULL, + qport, &sport, zloc); return FALSE; } @@ -1791,6 +2076,7 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) { ulog_uuconf (LOG_ERROR, puuconf, iuuconf); ubuffree (zstr); + uaccept_call_cleanup (puuconf, &ssys, qport, &sport, zloc); return FALSE; } } @@ -1801,6 +2087,7 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) ulog (LOG_ERROR, "System %s used wrong login name %s", zstr + 1, zlogin); ubuffree (zstr); + uaccept_call_cleanup (puuconf, &ssys, qport, &sport, zloc); return FALSE; } @@ -1834,15 +2121,25 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) ubuffree (zsysdep_spool_commands (qsys, UUCONF_GRADE_HIGH, 0, (const struct scmd *) NULL)); ubuffree (zstr); + uaccept_call_cleanup (puuconf, &ssys, qport, &sport, zloc); return TRUE; } /* We only permit one call at a time from a remote system. Lock it. */ if (! fsysdep_lock_system (qsys)) { + if (qsys->uuconf_fsequence) + { + /* At this point the calling system has already incremented + its sequence number, so we increment ours. This will + only cause a mismatch if the other system is not what it + says it is. */ + (void) ixsysdep_get_sequence (qsys); + } (void) fsend_uucp_cmd (qconn, "RLCK"); ulog (LOG_ERROR, "System already locked"); ubuffree (zstr); + uaccept_call_cleanup (puuconf, &ssys, qport, &sport, zloc); return FALSE; } sLocked_system = *qsys; @@ -1946,6 +2243,8 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) (void) fsysdep_set_status (qsys, &sstat); xfree ((pointer) paz); ubuffree (zstr); + uaccept_call_cleanup (puuconf, &ssys, qport, &sport, + zloc); return FALSE; } fgotseq = TRUE; @@ -1983,6 +2282,8 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) iwant = (1 << iwant) - 1; if (qsys->uuconf_zmax_remote_debug != NULL) iwant &= idebug_parse (qsys->uuconf_zmax_remote_debug); + else + iwant &= DEBUG_ABNORMAL | DEBUG_CHAT | DEBUG_HANDSHAKE; if ((iDebug | iwant) != iDebug) { iDebug |= iwant; @@ -2009,6 +2310,7 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) ulog (LOG_ERROR, "No sequence number (call rejected)"); sstat.ttype = STATUS_FAILED; (void) fsysdep_set_status (qsys, &sstat); + uaccept_call_cleanup (puuconf, &ssys, qport, &sport, zloc); return FALSE; } @@ -2047,6 +2349,7 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) { sstat.ttype = STATUS_FAILED; (void) fsysdep_set_status (qsys, &sstat); + uaccept_call_cleanup (puuconf, &ssys, qport, &sport, zloc); return FALSE; } } @@ -2122,6 +2425,7 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) { sstat.ttype = STATUS_FAILED; (void) fsysdep_set_status (qsys, &sstat); + uaccept_call_cleanup (puuconf, &ssys, qport, &sport, zloc); return FALSE; } @@ -2131,15 +2435,17 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) { sstat.ttype = STATUS_FAILED; (void) fsysdep_set_status (qsys, &sstat); + uaccept_call_cleanup (puuconf, &ssys, qport, &sport, zloc); return FALSE; } - if (zstr[0] != 'U' || zstr[2] != '\0') + if (zstr[0] != 'U') { ulog (LOG_ERROR, "Bad protocol response string"); sstat.ttype = STATUS_FAILED; (void) fsysdep_set_status (qsys, &sstat); ubuffree (zstr); + uaccept_call_cleanup (puuconf, &ssys, qport, &sport, zloc); return FALSE; } @@ -2149,6 +2455,7 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) sstat.ttype = STATUS_FAILED; (void) fsysdep_set_status (qsys, &sstat); ubuffree (zstr); + uaccept_call_cleanup (puuconf, &ssys, qport, &sport, zloc); return FALSE; } @@ -2163,11 +2470,20 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) ulog (LOG_ERROR, "No supported protocol"); sstat.ttype = STATUS_FAILED; (void) fsysdep_set_status (qsys, &sstat); + uaccept_call_cleanup (puuconf, &ssys, qport, &sport, zloc); return FALSE; } sDaemon.qproto = &asProtocols[i]; + /* If we are using a half-duplex line, act as though we have only a + single channel; otherwise we might start a send and a receive at + the same time. */ + if ((sDaemon.ireliable & UUCONF_RELIABLE_FULLDUPLEX) == 0) + sDaemon.cchans = 1; + else + sDaemon.cchans = asProtocols[i].cchans; + /* Run the chat script for when a call is received. */ if (! fchat (qconn, puuconf, &qsys->uuconf_scalled_chat, qsys, (const struct uuconf_dialer *) NULL, (const char *) NULL, @@ -2176,6 +2492,7 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) sstat.ttype = STATUS_FAILED; sstat.ilast = ixsysdep_time ((long *) NULL); (void) fsysdep_set_status (qsys, &sstat); + uaccept_call_cleanup (puuconf, &ssys, qport, &sport, zloc); return FALSE; } @@ -2202,15 +2519,16 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) if (qdialer == &sdialer) (void) uuconf_dialer_free (puuconf, &sdialer); - /* Get any jobs queued for the system, and turn on the selected - protocol. */ - if (! fqueue (&sDaemon, (boolean *) NULL) - || ! (*sDaemon.qproto->pfstart) (&sDaemon, &zlog)) + /* Turn on the selected protocol and get any jobs queued for the + system. */ + if (! (*sDaemon.qproto->pfstart) (&sDaemon, &zlog) + || ! fqueue (&sDaemon, (boolean *) NULL)) { uclear_queue (&sDaemon); sstat.ttype = STATUS_FAILED; sstat.ilast = ixsysdep_time ((long *) NULL); (void) fsysdep_set_status (qsys, &sstat); + uaccept_call_cleanup (puuconf, &ssys, qport, &sport, zloc); return FALSE; } @@ -2276,8 +2594,12 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) iend_time = ixsysdep_time ((long *) NULL); - ulog (LOG_NORMAL, "Call complete (%ld seconds)", - iend_time - istart_time); + ulog (LOG_NORMAL, "Call complete (%ld seconds %ld bytes %ld bps)", + iend_time - istart_time, + sDaemon.csent + sDaemon.creceived, + (iend_time != istart_time + ? (sDaemon.csent + sDaemon.creceived) / (iend_time - istart_time) + : 0)); uclear_queue (&sDaemon); @@ -2288,14 +2610,38 @@ faccept_call (puuconf, zlogin, qconn, pzsystem) sstat.ilast = iend_time; (void) fsysdep_set_status (qsys, &sstat); - (void) uuconf_system_free (puuconf, &ssys); - if (qport == &sport) - (void) uuconf_port_free (puuconf, &sport); - xfree ((pointer) zloc); + if (sDaemon.irunuuxqt == UUCONF_RUNUUXQT_PERCALL + || (sDaemon.irunuuxqt > 0 && sDaemon.cxfiles_received > 0)) + (void) fspawn_uuxqt (TRUE, qsys->uuconf_zname, zconfig); + + uaccept_call_cleanup (puuconf, &ssys, qport, &sport, zloc); return fret; } } + +/* Clean up after faccept_call. */ + +static void +uaccept_call_cleanup (puuconf, qfreesys, qport, qfreeport, zloc) + pointer puuconf; + struct uuconf_system *qfreesys; + struct uuconf_port *qport; + struct uuconf_port *qfreeport; + char *zloc; +{ + if (fLocked_system) + { + (void) fsysdep_unlock_system (&sLocked_system); + fLocked_system = FALSE; + } + if (qfreesys != NULL) + (void) uuconf_system_free (puuconf, qfreesys); + if (qport == qfreeport) + (void) uuconf_port_free (puuconf, qfreeport); + xfree ((pointer) zloc); + ulog_system ((const char *) NULL); +} /* Apply protocol parameters, once we know the protocol. */ @@ -2482,7 +2828,8 @@ zget_uucp_cmd (qconn, frequired) calc += CINCREMENT; znew = zbufalc (calc); - memcpy (znew, zalc, cgot); + if (cgot > 0) + memcpy (znew, zalc, cgot); ubuffree (zalc); zalc = znew; } @@ -2518,13 +2865,16 @@ zget_uucp_cmd (qconn, frequired) return NULL; } -/* Read a sequence of characters up to a newline or carriage return, and - return the line without the line terminating character. */ +/* Read a sequence of characters up to a newline or carriage return, + and return the line without the line terminating character. + Remember whether the last string we returned ended in \r; if it + did, ignore a leading \n to account for \r\n pairs. */ static char * zget_typed_line (qconn) struct sconnection *qconn; { + static boolean flastcr; char *zalc; size_t calc; size_t cgot; @@ -2563,11 +2913,15 @@ zget_typed_line (qconn) } #endif ubuffree (zalc); + flastcr = FALSE; return NULL; } if (b == -1) - continue; + { + flastcr = FALSE; + continue; + } #if DEBUG > 1 if (FDEBUGGING (DEBUG_CHAT)) @@ -2586,19 +2940,34 @@ zget_typed_line (qconn) } #endif + if (b == '\n' && cgot == 0 && flastcr) + { + /* Ignore \n in \r\n pair. */ + flastcr = FALSE; + continue; + } + + flastcr = FALSE; + if (cgot >= calc) { char *znew; calc += CINCREMENT; znew = zbufalc (calc); - memcpy (znew, zalc, cgot); + if (cgot > 0) + memcpy (znew, zalc, cgot); ubuffree (zalc); zalc = znew; } - if (b == '\r' || b == '\n') + if (b == '\n') b = '\0'; + else if (b == '\r') + { + flastcr = TRUE; + b = '\0'; + } zalc[cgot] = (char) b; ++cgot; @@ -2616,3 +2985,45 @@ zget_typed_line (qconn) } } } + +/* Spawn a uuxqt job. This probably belongs in some other file, but I + don't have a good place for it. */ + +boolean +fspawn_uuxqt (ffork, zsys, zconfig) + boolean ffork; + const char *zsys; + const char *zconfig; +{ + char *zsysarg; + char *zconfigarg; + boolean fret; + + if (zsys == NULL) + zsysarg = NULL; + else + { + zsysarg = zbufalc (sizeof "-s" + strlen (zsys)); + sprintf (zsysarg, "-s%s", zsys); + } + + if (zconfig == NULL) + zconfigarg = NULL; + else + { + zconfigarg = zbufalc (sizeof "-I" + strlen (zconfig)); + sprintf (zconfigarg, "-I%s", zconfig); + if (zsysarg == NULL) + { + zsysarg = zconfigarg; + zconfigarg = NULL; + } + } + + fret = fsysdep_run (ffork, "uuxqt", zsysarg, zconfigarg); + + ubuffree (zsysarg); + ubuffree (zconfigarg); + + return fret; +} diff --git a/gnu/libexec/uucp/uucico/xcmd.c b/gnu/libexec/uucp/uucico/xcmd.c index 494fe127abd..5d76eda3222 100644 --- a/gnu/libexec/uucp/uucico/xcmd.c +++ b/gnu/libexec/uucp/uucico/xcmd.c @@ -1,7 +1,7 @@ /* xcmd.c Routines to handle work requests. - Copyright (C) 1991, 1992 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -20,13 +20,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or - c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. */ #include "uucp.h" #if USE_RCS_ID -const char xcmd_rcsid[] = "$Id: xcmd.c,v 1.1 1993/08/04 19:36:35 jtc Exp $"; +const char xcmd_rcsid[] = "$Id: xcmd.c,v 1.2 1994/10/24 22:28:38 jtc Exp $"; #endif #include <errno.h> @@ -77,6 +77,13 @@ flocal_xcmd_request (qtrans, qdaemon) ulog (LOG_NORMAL, "Requesting work: %s to %s", qtrans->s.zfrom, qtrans->s.zto); + + qtrans->fcmd = TRUE; + qtrans->precfn = flocal_xcmd_await_reply; + + if (! fqueue_receive (qdaemon, qtrans)) + return FALSE; + /* We send the string X from to user options We put a dash in front of options. */ @@ -89,16 +96,11 @@ flocal_xcmd_request (qtrans, qdaemon) fret = (*qdaemon->qproto->pfsendcmd) (qdaemon, zsend, qtrans->ilocal, qtrans->iremote); ubuffree (zsend); - if (! fret) - { - utransfree (qtrans); - return FALSE; - } - qtrans->fcmd = TRUE; - qtrans->precfn = flocal_xcmd_await_reply; + if (! fret) + utransfree (qtrans); - return fqueue_receive (qdaemon, qtrans); + return fret; } /* Get a reply to an execution request from the remote system. */ @@ -179,7 +181,8 @@ fremote_xcmd_init (qdaemon, qcmd, iremote) else zconst = zexclam + 1; - zdestfile = zsysdep_local_file (zconst, qsys->uuconf_zpubdir); + zdestfile = zsysdep_local_file (zconst, qsys->uuconf_zpubdir, + (boolean *) NULL); if (zdestfile == NULL) return FALSE; @@ -252,7 +255,8 @@ fremote_xcmd_init (qdaemon, qcmd, iremote) /* Now we have to process each source file. The source specification may or may use wildcards. */ - zfrom = zsysdep_local_file (qcmd->zfrom, qsys->uuconf_zpubdir); + zfrom = zsysdep_local_file (qcmd->zfrom, qsys->uuconf_zpubdir, + (boolean *) NULL); if (zfrom == NULL) { ubuffree (zdestfile); @@ -341,6 +345,7 @@ fremote_xcmd_init (qdaemon, qcmd, iremote) char *zjobid; ssend.bcmd = 'S'; + ssend.bgrade = BDEFAULT_UUCP_GRADE; ssend.pseq = NULL; ssend.zfrom = zfile; ssend.zto = zdestfile; diff --git a/gnu/libexec/uucp/uuconv/uuconv.c b/gnu/libexec/uucp/uuconv/uuconv.c index 82f4e35f933..dcf3fd900b9 100644 --- a/gnu/libexec/uucp/uuconv/uuconv.c +++ b/gnu/libexec/uucp/uuconv/uuconv.c @@ -1,7 +1,7 @@ /* uuconv.c Convert one type of UUCP configuration file to another. - Copyright (C) 1991, 1992 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -20,13 +20,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or - c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. */ #include "uucnfi.h" #if USE_RCS_ID -const char uuconv_rcsid[] = "$Id: uuconv.c,v 1.1 1993/08/04 19:36:39 jtc Exp $"; +const char uuconv_rcsid[] = "$Id: uuconv.c,v 1.2 1994/10/24 22:28:45 jtc Exp $"; #endif #include "getopt.h" @@ -34,6 +34,7 @@ const char uuconv_rcsid[] = "$Id: uuconv.c,v 1.1 1993/08/04 19:36:39 jtc Exp $"; /* Local functions. */ static void uvusage P((void)); +static void uvhelp P((void)); static void uvwrite_time P((FILE *e, struct uuconf_timespan *qtime)); static void uvwrite_string P((FILE *e, const char *zarg, const char *zcmd)); static void uvwrite_size P((FILE *e, struct uuconf_timespan *qsize, @@ -76,6 +77,9 @@ static void uvwrite_taylor_dialer P((FILE *e, struct uuconf_dialer *qdialer, static void uvwrite_hdb_dialer P((FILE *e, struct uuconf_dialer *qdialer)); static void uvuuconf_error P((pointer puuconf, int iret)); +/* The program name. */ +const char *zProgram; + /* A list of Permissions entries built when writing out HDB system information. */ static struct shpermissions *qVperms; @@ -89,7 +93,17 @@ enum tconfig }; /* Long getopt options. */ -static const struct option asVlongopts[] = { { NULL, 0, NULL, 0 } }; +static const struct option asVlongopts[] = +{ + { "input", required_argument, NULL, 'i' }, + { "output", required_argument, NULL, 'o' }, + { "program", required_argument, NULL, 'p' }, + { "config", required_argument, NULL, 'I' }, + { "debug", required_argument, NULL, 'x' }, + { "version", no_argument, NULL, 'v' }, + { "help", no_argument, NULL, 1 }, + { NULL, 0, NULL, 0 } +}; int main (argc, argv) @@ -109,7 +123,9 @@ main (argc, argv) int iret; pointer pinput; - while ((iopt = getopt_long (argc, argv, "i:I:o:p:x:", asVlongopts, + zProgram = argv[0]; + + while ((iopt = getopt_long (argc, argv, "i:I:o:p:vx:", asVlongopts, (int *) NULL)) != EOF) { switch (iopt) @@ -138,8 +154,23 @@ main (argc, argv) /* Set the debugging level. */ break; + case 'v': + /* Print version and exit. */ + fprintf + (stderr, + "%s: Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", + zProgram, VERSION); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + + case 1: + /* --help. */ + uvhelp (); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + case 0: - /* Long option found and flag set. */ + /* Long option found, and flag value set. */ break; default: @@ -471,6 +502,9 @@ main (argc, argv) } exit (EXIT_SUCCESS); + + /* Avoid complaints about not returning. */ + return 0; } /* Print out a usage message and die. */ @@ -478,20 +512,35 @@ main (argc, argv) static void uvusage () { + fprintf (stderr, "Usage: %s -i input-type -o output-type [-p program]\n", + zProgram); + fprintf (stderr, "Use %s --help for help\n", zProgram); + exit (EXIT_FAILURE); +} + +/* Print a help message. */ + +static void +uvhelp () +{ fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", + "Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", VERSION); + fprintf (stderr, "Converts UUCP configuration files from one format to another.\n"); fprintf (stderr, - "Usage: uuconv -i input -o output [-p program] [-I file]\n"); + "Usage: %s -i input -o output [-p program] [-I file]\n", zProgram); fprintf (stderr, - " -i input: Set input type (one of taylor, v2, hdb)\n"); + " -i,--input input: Set input type (one of taylor, v2, hdb)\n"); fprintf (stderr, - " -o output: Set output type (one of taylor, v2, hdb)\n"); + " -o,--output output: Set output type (one of taylor, v2, hdb)\n"); fprintf (stderr, - " -p program: Program to convert (e.g., uucp or cu)\n"); + " -p,--program program: Program to convert (e.g., uucp or cu)\n"); fprintf (stderr, - " -I file: Set Taylor UUCP configuration file to use\n"); - exit (EXIT_FAILURE); + " -I,--config file: Set Taylor UUCP configuration file to use\n"); + fprintf (stderr, + " -v,--version: Print version and exit\n"); + fprintf (stderr, + " --help: Print help and exit\n"); } /* Write out a timespan. */ @@ -1229,18 +1278,17 @@ uvwrite_hdb_system (e, qsys) /* Compare two strings from a Permissions entry, returning TRUE if they are the same. */ + static boolean fvperm_string_cmp (z1, z2) const char *z1; const char *z2; { - if (z1 == NULL - ? z2 != NULL - : z2 == NULL) - return FALSE; - if (z1 == NULL) - return TRUE; + return z2 == NULL; + + if (z2 == NULL) + return FALSE; return strcmp (z1, z2) == 0; } @@ -1253,13 +1301,11 @@ fvperm_array_cmp (pz1, pz2) const char **pz1; const char **pz2; { - if (pz1 == NULL - ? pz2 != NULL - : pz2 == NULL) - return FALSE; - if (pz1 == NULL) - return TRUE; + return pz2 == NULL; + + if (pz2 == NULL) + return FALSE; for (; *pz1 != NULL && *pz2 != NULL; pz1++, pz2++) if (strcmp (*pz1, *pz2) != 0) @@ -1629,6 +1675,9 @@ uvwrite_taylor_port (e, qport, zprefix) case UUCONF_PORTTYPE_TLI: ztype = "tli"; break; + case UUCONF_PORTTYPE_PIPE: + ztype = "pipe"; + break; } fprintf (e, "%stype %s\n", zprefix, ztype); @@ -1681,6 +1730,8 @@ uvwrite_taylor_port (e, qport, zprefix) qm->uuconf_ihighbaud); if (! qm->uuconf_fcarrier) fprintf (e, "%scarrier false\n", zprefix); + if (! qm->uuconf_fhardflow) + fprintf (e, "%shardflow false\n", zprefix); if (qm->uuconf_pzdialer != NULL) { if (qm->uuconf_pzdialer[1] == NULL) @@ -1707,12 +1758,23 @@ uvwrite_taylor_port (e, qport, zprefix) fprintf (e, "%sdevice %s\n", zprefix, qd->uuconf_zdevice); if (qd->uuconf_ibaud != 0) fprintf (e, "%sbaud %ld\n", zprefix, qd->uuconf_ibaud); + if (qd->uuconf_fcarrier) + fprintf (e, "%scarrier true\n", zprefix); + if (! qd->uuconf_fhardflow) + fprintf (e, "%shardflow false\n", zprefix); } break; case UUCONF_PORTTYPE_TCP: if (qport->uuconf_u.uuconf_stcp.uuconf_zport != NULL) fprintf (e, "%sservice %s\n", zprefix, qport->uuconf_u.uuconf_stcp.uuconf_zport); + if (qport->uuconf_u.uuconf_stcp.uuconf_pzdialer != NULL) + { + sprintf (ab, "%sdialer-sequence", zprefix); + uvwrite_string_array (e, + qport->uuconf_u.uuconf_stcp.uuconf_pzdialer, + ab); + } break; case UUCONF_PORTTYPE_TLI: { @@ -1738,6 +1800,18 @@ uvwrite_taylor_port (e, qport, zprefix) qt->uuconf_zservaddr); } break; + case UUCONF_PORTTYPE_PIPE: + { + struct uuconf_pipe_port *qp; + + qp = &qport->uuconf_u.uuconf_spipe; + if (qp->uuconf_pzcmd != NULL) + { + sprintf (ab, "%scommad", zprefix); + uvwrite_string_array (e, qp->uuconf_pzcmd, ab); + } + } + break; } } @@ -1849,6 +1923,8 @@ ivwrite_hdb_port (qport, pinfo) } else if (qport->uuconf_ttype == UUCONF_PORTTYPE_TCP) { + char **pz; + fprintf (e, "TCP"); if (qport->uuconf_zprotocols != NULL) fprintf (e, ",%s", qport->uuconf_zprotocols); @@ -1858,6 +1934,10 @@ ivwrite_hdb_port (qport, pinfo) else fprintf (e, "%s", qport->uuconf_u.uuconf_stcp.uuconf_zport); fprintf (e, " - -"); + pz = qport->uuconf_u.uuconf_stcp.uuconf_pzdialer; + if (pz != NULL) + for (; *pz != NULL; pz++) + fprintf (e, " %s", *pz); } else if (qport->uuconf_ttype == UUCONF_PORTTYPE_TLI) { diff --git a/gnu/libexec/uucp/uucp/uucp.1 b/gnu/libexec/uucp/uucp/uucp.1 index 0fa81fe6530..029ddd5331d 100644 --- a/gnu/libexec/uucp/uucp/uucp.1 +++ b/gnu/libexec/uucp/uucp/uucp.1 @@ -1,5 +1,5 @@ -''' $Id: uucp.1,v 1.1 1993/08/04 19:36:43 jtc Exp $ -.TH uucp 1 "Taylor UUCP 1.04" +''' $Id: uucp.1,v 1.2 1994/10/24 22:28:56 jtc Exp $ +.TH uucp 1 "Taylor UUCP 1.05" .SH NAME uucp \- Unix to Unix copy .SH SYNOPSIS @@ -34,6 +34,8 @@ system1!system2!path. Any pathname that does not begin with / or ~ will be appended to the current directory (unless the .B \-W +or +.B \--noexpand option is used); this resulting path will not necessarily exist on a remote system. A pathname beginning with a simple ~ starts at the UUCP public directory; a pathname beginning with ~name starts at the @@ -51,13 +53,15 @@ The copy does not take place immediately, but is queued up for the .I uucico (8) daemon; the daemon is started immediately unless the .B \-r +or +.B \-\-nouucico switch is given. In any case, the next time the remote system is called the file(s) will be copied. .SH OPTIONS The following options may be given to .I uucp. .TP 5 -.B \-c +.B \-c, \-\-nocopy Do not copy local source files to the spool directory. If they are removed before being processed by the .I uucico @@ -65,40 +69,40 @@ removed before being processed by the .I uucico (8) daemon, and by the invoking user. .TP 5 -.B \-C +.B \-C, \-\-copy Copy local source files to the spool directory. This is the default. .TP 5 -.B \-d +.B \-d, \-\-directories Create all necessary directories when doing the copy. This is the default. .TP 5 -.B \-f +.B \-f, \-\-nodirectories If any necessary directories do not exist for the destination path, abort the copy. .TP 5 -.B \-g grade +.B \-g grade, \-\-grade grade Set the grade of the file transfer command. Jobs of a higher grade are executed first. Grades run 0 ... 9 A ... Z a ... z from high to low. .TP 5 -.B \-m +.B \-m, \-\-mail Report completion or failure of the file transfer by .I mail (1). .TP 5 -.B \-n user +.B \-n user, \-\-notify user Report completion or failure of the file transfer by .I mail (1) to the named user on the remote system. .TP 5 -.B \-r +.B \-r, \-\-nouucico Do not start .I uucico (8) daemon immediately; merely queue up the file transfer for later execution. .TP 5 -.B \-j +.B \-j, \-\-jobid Print jobid on standard output. The job may be later cancelled by passing the jobid to the .B \-k @@ -108,18 +112,21 @@ switch of It is possible for some complex operations to produce more than one jobid, in which case each will be printed on a separate line. For example -.EX -uucp sys1!~user1/file1 sys2!~user2/file2 /usr/spool/uucppublic -.EE +.br +.in +0.5i +.nf +uucp sys1!~user1/file1 sys2!~user2/file2 ~user3 +.fi +.in -0.5i will generate two separate jobs, one for the system .I sys1 and one for the system .I sys2. .TP 5 -.B \-W +.B \-W, \-\-noexpand Do not prepend remote relative path names with the current directory. .TP 5 -.B \-x type +.B \-x type, \-\-debug type Turn on particular debugging types. The following types are recognized: abnormal, chat, handshake, uucp-proto, proto, port, config, spooldir, execute, incoming, outgoing. Only abnormal, config, @@ -127,18 +134,24 @@ spooldir and execute are meaningful for .I uucp. Multiple types may be given, separated by commas, and the -.B \-x +.B \-\-debug option may appear multiple times. A number may also be given, which will turn on that many types from the foregoing list; for example, -.B \-x 2 +.B \-\-debug 2 is equivalent to -.B \-x abnormal,chat. +.B \-\-debug abnormal,chat. .TP 5 -.B \-I file +.B \-I file, \-\-config file Set configuration file to use. This option may not be available, depending upon how .I uucp was compiled. +.TP 5 +.B \-v, \-\-version +Report version information and exit. +.TP 5 +.B \-\-help +Print a help message and exit. .SH FILES The file names may be changed at compilation time or by the configuration file, so these are only approximations. @@ -172,4 +185,4 @@ File modes are not preserved, except for the execute bit. The resulting file is owned by the uucp user. .SH AUTHOR Ian Lance Taylor -(ian@airs.com or uunet!airs!ian) +<ian@airs.com> diff --git a/gnu/libexec/uucp/uucp/uucp.c b/gnu/libexec/uucp/uucp/uucp.c index 93e9ff44849..ae8c4749923 100644 --- a/gnu/libexec/uucp/uucp/uucp.c +++ b/gnu/libexec/uucp/uucp/uucp.c @@ -1,7 +1,7 @@ /* uucp.c Prepare to copy a file to or from a remote system. - Copyright (C) 1991, 1992 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -20,13 +20,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or - c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. */ #include "uucp.h" #if USE_RCS_ID -const char uucp_rcsid[] = "$Id: uucp.c,v 1.1 1993/08/04 19:36:44 jtc Exp $"; +const char uucp_rcsid[] = "$Id: uucp.c,v 1.2 1994/10/24 22:29:00 jtc Exp $"; #endif #include <ctype.h> @@ -41,6 +41,7 @@ const char uucp_rcsid[] = "$Id: uucp.c,v 1.1 1993/08/04 19:36:44 jtc Exp $"; /* Local functions. */ static void ucusage P((void)); +static void uchelp P((void)); static void ucdirfile P((const char *zdir, const char *zfile, pointer pinfo)); static void uccopy P((const char *zfile, const char *zdest)); @@ -51,11 +52,29 @@ static const char *zcone_system P((boolean *pfany)); static void ucrecord_file P((const char *zfile)); static void ucabort P((void)); -/* The program name. */ -char abProgram[] = "uucp"; - /* Long getopt options. */ -static const struct option asClongopts[] = { { NULL, 0, NULL, 0 } }; +static const struct option asClongopts[] = +{ + { "copy", no_argument, NULL, 'C' }, + { "nocopy", no_argument, NULL, 'c' }, + { "directories", no_argument, NULL, 'd' }, + { "nodirectories", no_argument, NULL, 'f' }, + { "grade", required_argument, NULL, 'g' }, + { "jobid", no_argument, NULL, 'j' }, + { "mail", no_argument, NULL, 'm' }, + { "notify", required_argument, NULL, 'n' }, + { "nouucico", no_argument, NULL, 'r' }, + { "recursive", no_argument, NULL, 'R' }, + { "status", required_argument, NULL, 's' }, + { "uuto", no_argument, NULL, 't' }, + { "user", required_argument, NULL, 'u' }, + { "noexpand", no_argument, NULL, 'w' }, + { "config", required_argument, NULL, 'I' }, + { "debug", required_argument, NULL, 'x' }, + { "version", no_argument, NULL, 'v' }, + { "help", no_argument, NULL, 1 }, + { NULL, 0, NULL, 0 } +}; /* Local variables. There are a bunch of these, mostly set by the options and the last (the destination) argument. These have file @@ -137,13 +156,16 @@ main (argc, argv) int iuuconf; int i; boolean fgetcwd; + struct uuconf_system slocalsys; char *zexclam; char *zdestfile; const char *zdestsys; char *zoptions; boolean fexit; - while ((iopt = getopt_long (argc, argv, "cCdfg:I:jmn:prRs:tu:Wx:", + zProgram = argv[0]; + + while ((iopt = getopt_long (argc, argv, "cCdfg:I:jmn:prRs:tu:Wvx:", asClongopts, (int *) NULL)) != EOF) { switch (iopt) @@ -232,13 +254,26 @@ main (argc, argv) #endif break; + case 'v': + /* Print version and exit. */ + printf ("%s: Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", + zProgram, VERSION); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + + case 1: + /* --help. */ + uchelp (); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + case 0: /* Long option found and flag set. */ break; default: ucusage (); - break; + /*NOTREACHED*/ } } @@ -335,6 +370,18 @@ main (argc, argv) else if (iuuconf != UUCONF_SUCCESS) ulog_uuconf (LOG_FATAL, puuconf, iuuconf); + /* Get the local system information. */ + iuuconf = uuconf_system_info (puuconf, zClocalname, &slocalsys); + if (iuuconf != UUCONF_SUCCESS) + { + if (iuuconf != UUCONF_NOT_FOUND) + ulog_uuconf (LOG_FATAL, puuconf, iuuconf); + iuuconf = uuconf_system_local (puuconf, &slocalsys); + if (iuuconf != UUCONF_SUCCESS) + ulog_uuconf (LOG_FATAL, puuconf, iuuconf); + slocalsys.uuconf_zname = (char *) zClocalname; + } + /* If we are emulating uuto, translate the destination argument, and notify the destination user. This had better not turn into something that requires the current directory, or we may have @@ -378,6 +425,8 @@ main (argc, argv) *zoptions++ = 'm'; *zoptions = '\0'; + argv[argc - 1] = zremove_local_sys (&slocalsys, argv[argc - 1]); + zexclam = strchr (argv[argc - 1], '!'); if (zexclam == NULL) { @@ -445,7 +494,8 @@ main (argc, argv) /* Turn the destination into an absolute path, unless it is on a remote system and -W was used. */ if (fClocaldest) - zdestfile = zsysdep_local_file_cwd (zdestfile, sCdestsys.uuconf_zpubdir); + zdestfile = zsysdep_local_file_cwd (zdestfile, sCdestsys.uuconf_zpubdir, + (boolean *) NULL); else if (fCexpand) zdestfile = zsysdep_add_cwd (zdestfile); if (zdestfile == NULL) @@ -462,6 +512,8 @@ main (argc, argv) fCneeds_cwd = FALSE; + argv[i] = zremove_local_sys (&slocalsys, argv[i]); + if (strchr (argv[i], '!') != NULL) { flocal = FALSE; @@ -476,7 +528,8 @@ main (argc, argv) if (fsysdep_needs_cwd (argv[i])) fCneeds_cwd = TRUE; zfrom = zsysdep_local_file_cwd (argv[i], - sCdestsys.uuconf_zpubdir); + sCdestsys.uuconf_zpubdir, + (boolean *) NULL); if (zfrom == NULL) ucabort (); } @@ -524,12 +577,35 @@ main (argc, argv) boolean fany; zsys = zcone_system (&fany); - if (zsys != NULL) - fexit = fsysdep_run ("uucico", "-s", zsys); - else if (fany) - fexit = fsysdep_run ("uucico", "-r1", (const char *) NULL); - else + + if (zsys == NULL && ! fany) fexit = TRUE; + else + { + const char *zarg; + char *zconfigarg; + + if (zsys == NULL) + zarg = "-r1"; + else + { + char *z; + + z = zbufalc (sizeof "-Cs" + strlen (zsys)); + sprintf (z, "-Cs%s", zsys); + zarg = z; + } + + if (zconfig == NULL) + zconfigarg = NULL; + else + { + zconfigarg = zbufalc (sizeof "-I" + strlen (zconfig)); + sprintf (zconfigarg, "-I%s", zconfig); + } + + fexit = fsysdep_run (FALSE, "uucico", zarg, zconfigarg); + } } usysdep_exit (fexit); @@ -538,49 +614,45 @@ main (argc, argv) return 0; } +/* Print usage message and die. */ + static void ucusage () { fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", + "Usage: %s [options] file1 [file2 ...] dest\n", zProgram); + fprintf (stderr, "Use %s --help for help\n", zProgram); + exit (EXIT_FAILURE); +} + +/* Print help message. */ + +static void +uchelp () +{ + printf ("Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", VERSION); - fprintf (stderr, - "Usage: uucp [options] file1 [file2 ...] dest\n"); - fprintf (stderr, - " -c: Do not copy local files to spool directory\n"); - fprintf (stderr, - " -C, -p: Copy local files to spool directory (default)\n"); - fprintf (stderr, - " -d: Create necessary directories (default)\n"); - fprintf (stderr, - " -f: Do not create directories (fail if they do not exist)\n"); - fprintf (stderr, - " -g grade: Set job grade (must be alphabetic)\n"); - fprintf (stderr, - " -m: Report status of copy by mail\n"); - fprintf (stderr, - " -n user: Report status of copy by mail to remote user\n"); - fprintf (stderr, - " -R: Copy directories recursively\n"); - fprintf (stderr, - " -r: Do not start uucico daemon\n"); - fprintf (stderr, - " -s file: Report completion status to file\n"); - fprintf (stderr, - " -j: Report job id\n"); - fprintf (stderr, - " -W: Do not add current directory to remote filenames\n"); - fprintf (stderr, - " -t: Emulate uuto\n"); - fprintf (stderr, - " -u name: Set user name\n"); - fprintf (stderr, - " -x debug: Set debugging level\n"); + printf ("Usage: %s [options] file1 [file2 ...] dest\n", zProgram); + printf (" -c,--nocopy: Do not copy local files to spool directory\n"); + printf (" -C,-p,--copy: Copy local files to spool directory (default)\n"); + printf (" -d,--directories: Create necessary directories (default)\n"); + printf (" -f,--nodirectories: Do not create directories (fail if they do not exist)\n"); + printf (" -g,--grade grade: Set job grade (must be alphabetic)\n"); + printf (" -m,--mail: Report status of copy by mail\n"); + printf (" -n,--notify user: Report status of copy by mail to remote user\n"); + printf (" -R,--recursive: Copy directories recursively\n"); + printf (" -r,--nouucico: Do not start uucico daemon\n"); + printf (" -s,--status file: Report completion status to file\n"); + printf (" -j,--jobid: Report job id\n"); + printf (" -W,--noexpand: Do not add current directory to remote filenames\n"); + printf (" -t,--uuto: Emulate uuto\n"); + printf (" -u,--usage name: Set user name\n"); + printf (" -x,--debug debug: Set debugging level\n"); #if HAVE_TAYLOR_CONFIG - fprintf (stderr, - " -I file: Set configuration file to use\n"); + printf (" -I,--config file: Set configuration file to use\n"); #endif /* HAVE_TAYLOR_CONFIG */ - exit (EXIT_FAILURE); + printf (" -v,--version: Print version and exit\n"); + printf (" --help: Print help and exit\n"); } /* This is called for each file in a directory heirarchy. */ @@ -713,7 +785,9 @@ uccopy (zfile, zdest) (fCremote ? (const char *) NULL : zCuser))) - ulog (LOG_FATAL, "Not permitted to send %s", zfile); + ulog (LOG_FATAL, + "Daemon not permitted to send %s (suggest --copy)", + zfile); } else { @@ -730,6 +804,7 @@ uccopy (zfile, zdest) { /* We're not forwarding. Just send the file. */ s.bcmd = 'S'; + s.bgrade = bCgrade; s.pseq = NULL; s.zfrom = zbufcpy (zfile); s.zto = zbufcpy (zdest); @@ -794,6 +869,7 @@ uccopy (zfile, zdest) /* Send the execution file. */ s.bcmd = 'S'; + s.bgrade = bCgrade; s.pseq = NULL; s.zfrom = zbufcpy (abxtname); s.zto = zbufcpy (abxname); @@ -815,6 +891,7 @@ uccopy (zfile, zdest) /* Send the data file. */ s.bcmd = 'S'; + s.bgrade = bCgrade; s.pseq = NULL; s.zfrom = zbufcpy (zfile); s.zto = zbufcpy (abdname); @@ -851,6 +928,7 @@ uccopy (zfile, zdest) clen = zfrom - zexclam - 1; zforward = zbufalc (clen + 1); memcpy (zforward, zexclam + 1, clen); + zforward[clen] = '\0'; } ++zfrom; @@ -925,6 +1003,7 @@ uccopy (zfile, zdest) zto = zbufcpy (zdest); } + s.bgrade = bCgrade; s.pseq = NULL; s.zfrom = zfrom; s.zto = zto; @@ -999,6 +1078,7 @@ uccopy (zfile, zdest) /* Send the execution file. */ s.bcmd = 'S'; + s.bgrade = bCgrade; s.pseq = NULL; s.zfrom = zbufcpy (abtname); s.zto = zbufcpy (abxname); diff --git a/gnu/libexec/uucp/uulog/uulog.c b/gnu/libexec/uucp/uulog/uulog.c index 9a58fffeb22..c6b286ad862 100644 --- a/gnu/libexec/uucp/uulog/uulog.c +++ b/gnu/libexec/uucp/uulog/uulog.c @@ -1,7 +1,7 @@ /* uulog.c Display the UUCP log file. - Copyright (C) 1991, 1992 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -20,13 +20,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or - c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. */ #include "uucp.h" #if USE_RCS_ID -const char uulog_rcsid[] = "$Id: uulog.c,v 1.1 1993/08/04 19:36:47 jtc Exp $"; +const char uulog_rcsid[] = "$Id: uulog.c,v 1.2 1994/10/24 22:29:06 jtc Exp $"; #endif #include <ctype.h> @@ -42,15 +42,27 @@ const char uulog_rcsid[] = "$Id: uulog.c,v 1.1 1993/08/04 19:36:47 jtc Exp $"; is a very useful program anyhow. It only takes a single -s and/or -u switch. When using HAVE_HDB_LOGGING it requires a system. */ -/* The program name. */ -char abProgram[] = "uulog"; - /* Local functions. */ static void ulusage P((void)); +static void ulhelp P((void)); /* Long getopt options. */ -static const struct option asLlongopts[] = { { NULL, 0, NULL, 0 } }; +static const struct option asLlongopts[] = +{ + { "debuglog", no_argument, NULL, 'D' }, + { "follow", optional_argument, NULL, 2 }, + { "lines", required_argument, NULL, 'n' }, + { "system", required_argument, NULL, 's' }, + { "statslog", no_argument, NULL, 'S' }, + { "user", required_argument, NULL, 'u' }, + { "uuxqtlog", no_argument, NULL, 'x' }, + { "config", required_argument, NULL, 'I' }, + { "debug", required_argument, NULL, 'X' }, + { "version", no_argument, NULL, 'v' }, + { "help", no_argument, NULL, 1 }, + { NULL, 0, NULL, 0 } +}; int main (argc, argv) @@ -89,6 +101,8 @@ main (argc, argv) char *zline; size_t cline; + zProgram = argv[0]; + /* Look for a straight number argument, and convert it to -n before passing the arguments to getopt. */ for (i = 0; i < argc; i++) @@ -107,7 +121,7 @@ main (argc, argv) } } - while ((iopt = getopt_long (argc, argv, "Df:FI:n:s:Su:xX:", asLlongopts, + while ((iopt = getopt_long (argc, argv, "Df:FI:n:s:Su:vxX:", asLlongopts, (int *) NULL)) != EOF) { switch (iopt) @@ -170,13 +184,35 @@ main (argc, argv) #endif break; + case 'v': + /* Print version and exit. */ + printf ("%s: Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", + zProgram, VERSION); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + + case 2: + /* --follow. */ + fforever = TRUE; + if (cshow == 0) + cshow = 10; + if (optarg != NULL) + zsystem = optarg; + break; + + case 1: + /* --help. */ + ulhelp (); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + case 0: /* Long option found and flag set. */ break; default: ulusage (); - break; + /*NOTREACHED*/ } } @@ -211,7 +247,7 @@ main (argc, argv) if (iuuconf != UUCONF_SUCCESS) ulog_uuconf (LOG_FATAL, puuconf, iuuconf); - usysdep_initialize (puuconf, 0); + usysdep_initialize (puuconf, INIT_NOCHDIR); if (zsystem != NULL) { @@ -221,15 +257,16 @@ main (argc, argv) { struct uuconf_system ssys; + /* Canonicalize the system name. If we can't find the + system information, just use whatever we were given so + that people can check on systems that logged in + anonymously. */ iuuconf = uuconf_system_info (puuconf, zsystem, &ssys); - if (iuuconf != UUCONF_SUCCESS) + if (iuuconf == UUCONF_SUCCESS) { - if (iuuconf != UUCONF_NOT_FOUND) - ulog_uuconf (LOG_FATAL, puuconf, iuuconf); - ulog (LOG_FATAL, "%s: System not found", zsystem); + zsystem = zbufcpy (ssys.uuconf_zname); + (void) uuconf_system_free (puuconf, &ssys); } - zsystem = zbufcpy (ssys.uuconf_zname); - (void) uuconf_system_free (puuconf, &ssys); } } @@ -247,7 +284,8 @@ main (argc, argv) /* We need a system to find a HDB log file. */ if (zsystem == NULL) - ulusage (); + ulog (LOG_FATAL, + "system name (-s argument) required for HDB format log files"); if (fuuxqt) zprogram = "uuxqt"; @@ -261,6 +299,9 @@ main (argc, argv) sprintf (zalc, zlogfile, zprogram, zsystem); zfile = zalc; + if (! fsysdep_file_exists (zfile)) + ulog (LOG_FATAL, "no log file available for system %s", zsystem); + if (strcmp (zsystem, "ANY") == 0) zsystem = NULL; #endif @@ -344,7 +385,7 @@ main (argc, argv) zlsys = znext; clsys = strcspn (znext, "!"); znext += clsys + 1; - zlsys = znext; + zluser = znext; clsys = strcspn (znext, " \t"); #endif } @@ -411,34 +452,41 @@ static void ulusage () { fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", + "Usage: %s [-n #] [-sf system] [-u user] [-xDSF] [-I file] [-X debug]\n", + zProgram); + fprintf (stderr, "Use %s --help for help\n", zProgram); + exit (EXIT_FAILURE); +} + +/* Print a help message. */ + +static void +ulhelp () +{ + printf ("Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", VERSION); - fprintf (stderr, - "Usage: uulog [-n #] [-sf system] [-u user] [-xDSF] [-I file] [-X debug]\n"); - fprintf (stderr, - " -n: show given number of lines from end of log\n"); - fprintf (stderr, - " -s: print entries for named system\n"); - fprintf (stderr, - " -f: follow entries for named system\n"); - fprintf (stderr, - " -u: print entries for named user\n"); #if HAVE_HDB_LOGGING - fprintf (stderr, - " -x: print uuxqt log rather than uucico log\n"); + printf ("Usage: %s [-n #] [-sf system] [-u user] [-xDS] [-I file] [-X debug]\n", + zProgram); #else - fprintf (stderr, - " -F: follow entries for any system\n"); + printf ("Usage: %s [-n #] [-sf system] [-u user] [-DSF] [-I file] [-X debug]\n", + zProgram); #endif - fprintf (stderr, - " -S: show statistics file\n"); - fprintf (stderr, - " -D: show debugging file\n"); - fprintf (stderr, - " -X debug: Set debugging level (0 for none, 9 is max)\n"); + printf (" -n,--lines: show given number of lines from end of log\n"); + printf (" -s,--system: print entries for named system\n"); + printf (" -f system,--follow=system: follow entries for named system\n"); + printf (" -u,--user user: print entries for named user\n"); +#if HAVE_HDB_LOGGING + printf (" -x,--uuxqt: print uuxqt log rather than uucico log\n"); +#else + printf (" -F,--follow: follow entries for any system\n"); +#endif + printf (" -S,--statslog: show statistics file\n"); + printf (" -D,--debuglog: show debugging file\n"); + printf (" -X,--debug debug: Set debugging level\n"); #if HAVE_TAYLOR_CONFIG - fprintf (stderr, - " -I file: Set configuration file to use\n"); + printf (" -I,--config file: Set configuration file to use\n"); #endif /* HAVE_TAYLOR_CONFIG */ - exit (EXIT_FAILURE); + printf (" -v,--version: Print version and exit\n"); + printf (" --help: Print help and exit\n"); } diff --git a/gnu/libexec/uucp/uuname/uuname.c b/gnu/libexec/uucp/uuname/uuname.c index 54a87dfa392..78222d6b695 100644 --- a/gnu/libexec/uucp/uuname/uuname.c +++ b/gnu/libexec/uucp/uuname/uuname.c @@ -1,7 +1,7 @@ /* uuname.c List the names of known remote UUCP sites. - Copyright (C) 1991, 1992 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -20,13 +20,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or - c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. */ #include "uucp.h" #if USE_RCS_ID -const char uuname_rcsid[] = "$Id: uuname.c,v 1.1 1993/08/04 19:36:52 jtc Exp $"; +const char uuname_rcsid[] = "$Id: uuname.c,v 1.2 1994/10/24 22:29:11 jtc Exp $"; #endif #include "getopt.h" @@ -35,16 +35,22 @@ const char uuname_rcsid[] = "$Id: uuname.c,v 1.1 1993/08/04 19:36:52 jtc Exp $"; #include "uuconf.h" #include "system.h" -/* The program name. */ -char abProgram[] = "uuname"; - /* Local functions. */ static void unusage P((void)); -static void unuuconf_error P((pointer puuconf, int iuuconf)); +static void unhelp P((void)); /* Long getopt options. */ -static const struct option asNlongopts[] = { { NULL, 0, NULL, 0 } }; +static const struct option asNlongopts[] = +{ + { "aliases", no_argument, NULL, 'a' }, + { "local", no_argument, NULL, 'l' }, + { "config", required_argument, NULL, 'I' }, + { "debug", required_argument, NULL, 'x' }, + { "version", no_argument, NULL, 'v' }, + { "help", no_argument, NULL, 1 }, + { NULL, 0, NULL, 0 } +}; int main (argc, argv) @@ -61,7 +67,9 @@ main (argc, argv) pointer puuconf; int iuuconf; - while ((iopt = getopt_long (argc, argv, "alI:x:", asNlongopts, + zProgram = argv[0]; + + while ((iopt = getopt_long (argc, argv, "alI:vx:", asNlongopts, (int *) NULL)) != EOF) { switch (iopt) @@ -89,13 +97,26 @@ main (argc, argv) #endif break; + case 'v': + /* Print version and exit. */ + printf ("%s: Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", + zProgram, VERSION); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + + case 1: + /* --help. */ + unhelp (); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + case 0: /* Long option found and flag set. */ break; default: unusage (); - break; + /*NOTREACHED*/ } } @@ -104,7 +125,7 @@ main (argc, argv) iuuconf = uuconf_init (&puuconf, (const char *) NULL, zconfig); if (iuuconf != UUCONF_SUCCESS) - unuuconf_error (puuconf, iuuconf); + ulog_uuconf (LOG_FATAL, puuconf, iuuconf); #if DEBUG > 1 { @@ -118,7 +139,7 @@ main (argc, argv) } #endif - usysdep_initialize (puuconf, INIT_SUID); + usysdep_initialize (puuconf, INIT_SUID | INIT_NOCHDIR); if (flocal) { @@ -132,7 +153,7 @@ main (argc, argv) usysdep_exit (FALSE); } else if (iuuconf != UUCONF_SUCCESS) - unuuconf_error (puuconf, iuuconf); + ulog_uuconf (LOG_FATAL, puuconf, iuuconf); printf ("%s\n", zlocalname); } else @@ -141,7 +162,7 @@ main (argc, argv) iuuconf = uuconf_system_names (puuconf, &pznames, falias); if (iuuconf != UUCONF_SUCCESS) - unuuconf_error (puuconf, iuuconf); + ulog_uuconf (LOG_FATAL, puuconf, iuuconf); for (pz = pznames; *pz != NULL; pz++) printf ("%s\n", *pz); @@ -159,34 +180,23 @@ static void unusage () { fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", - VERSION); - fprintf (stderr, - "Usage: uuname [-a] [-l] [-I file]\n"); - fprintf (stderr, - " -a: display aliases\n"); - fprintf (stderr, - " -l: print local name\n"); -#if HAVE_TAYLOR_CONFIG - fprintf (stderr, - " -I file: Set configuration file to use\n"); -#endif /* HAVE_TAYLOR_CONFIG */ + "Usage: %s [-a] [-l] [-I file]\n", zProgram); + fprintf (stderr, "Use %s --help for help\n", zProgram); exit (EXIT_FAILURE); } -/* Display a uuconf error and exit. */ +/* Print a help message. */ -static void -unuuconf_error (puuconf, iret) - pointer puuconf; - int iret; +static void unhelp () { - char ab[512]; - - (void) uuconf_error_string (puuconf, iret, ab, sizeof ab); - if ((iret & UUCONF_ERROR_FILENAME) == 0) - fprintf (stderr, "uuname: %s\n", ab); - else - fprintf (stderr, "uuname:%s\n", ab); - exit (EXIT_FAILURE); + printf ("Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", + VERSION); + printf ("Usage: %s [-a] [-l] [-I file]\n", zProgram); + printf (" -a,--aliases: display aliases\n"); + printf (" -l,--local: print local name\n"); +#if HAVE_TAYLOR_CONFIG + printf (" -I,--config file: Set configuration file to use\n"); +#endif /* HAVE_TAYLOR_CONFIG */ + printf (" -v,--version: Print version and exit\n"); + printf (" --help: Print help and exit\n"); } diff --git a/gnu/libexec/uucp/uupick/uupick.c b/gnu/libexec/uucp/uupick/uupick.c index 4e1f1b3affb..6e6858c743d 100644 --- a/gnu/libexec/uucp/uupick/uupick.c +++ b/gnu/libexec/uucp/uupick/uupick.c @@ -1,7 +1,7 @@ /* uupick.c Get files stored in the public directory by uucp -t. - Copyright (C) 1992 Ian Lance Taylor + Copyright (C) 1992, 1993, 1994 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -20,13 +20,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or - c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. */ #include "uucp.h" #if USE_RCS_ID -const char uupick_rcsid[] = "$Id: uupick.c,v 1.1 1993/08/04 19:36:56 jtc Exp $"; +const char uupick_rcsid[] = "$Id: uupick.c,v 1.2 1994/10/24 22:29:22 jtc Exp $"; #endif #include <errno.h> @@ -43,15 +43,21 @@ static void upmovedir P((const char *zfull, const char *zrelative, pointer pinfo)); static void upmove P((const char *zfrom, const char *zto)); -/* The program name. */ -char abProgram[] = "uupick"; - /* Long getopt options. */ -static const struct option asPlongopts[] = { { NULL, 0, NULL, 0 } }; +static const struct option asPlongopts[] = +{ + { "system", required_argument, NULL, 's' }, + { "config", required_argument, NULL, 'I' }, + { "debug", required_argument, NULL, 'x' }, + { "version", no_argument, NULL, 'v' }, + { "help", no_argument, NULL, 1 }, + { NULL, 0, NULL, 0 } +}; /* Local functions. */ static void upusage P((void)); +static void uphelp P((void)); int main (argc, argv) @@ -72,7 +78,9 @@ main (argc, argv) char ab[1000]; boolean fquit; - while ((iopt = getopt_long (argc, argv, "I:s:x:", asPlongopts, + zProgram = "uupick"; + + while ((iopt = getopt_long (argc, argv, "I:s:vx:", asPlongopts, (int *) NULL)) != EOF) { switch (iopt) @@ -95,13 +103,28 @@ main (argc, argv) #endif break; + case 'v': + /* Print version and exit. */ + fprintf + (stderr, + "%s: Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", + zProgram, VERSION); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + + case 1: + /* --help. */ + uphelp (); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + case 0: /* Long option found and flag set. */ break; default: upusage (); - break; + /*NOTREACHED*/ } } @@ -152,6 +175,8 @@ main (argc, argv) do { + boolean fbadname; + fcontinue = FALSE; if (zallsys == NULL @@ -196,9 +221,15 @@ main (argc, argv) case 'a': zto = ab + 1 + strspn (ab + 1, " \t"); zto[strcspn (zto, " \t\n")] = '\0'; - zlocal = zsysdep_uupick_local_file (zto); + zlocal = zsysdep_uupick_local_file (zto, &fbadname); if (zlocal == NULL) - usysdep_exit (FALSE); + { + if (! fbadname) + usysdep_exit (FALSE); + ulog (LOG_ERROR, "%s: bad local file name", zto); + fcontinue = TRUE; + break; + } zto = zsysdep_in_dir (zlocal, zfile); ubuffree (zlocal); if (zto == NULL) @@ -271,25 +302,37 @@ main (argc, argv) return 0; } -/* Print usage message. */ +/* Print usage message and die. */ static void upusage () { fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", - VERSION); + "Usage: %s [-s system] [-I config] [-x debug]\n", zProgram); + fprintf (stderr, "Use %s --help for help\n", zProgram); + exit (EXIT_FAILURE); +} + +/* Print help message. */ + +static void +uphelp () +{ fprintf (stderr, - "Usage: uupick [-s system] [-I config] [-x debug]\n"); + "Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", + VERSION); fprintf (stderr, - " -s system: Only consider files from named system\n"); + " -s,--system system: Only consider files from named system\n"); fprintf (stderr, - " -x debug: Set debugging level\n"); + " -x,--debug debug: Set debugging level\n"); #if HAVE_TAYLOR_CONFIG fprintf (stderr, - " -I file: Set configuration file to use\n"); + " -I,--config file: Set configuration file to use\n"); #endif /* HAVE_TAYLOR_CONFIG */ - exit (EXIT_FAILURE); + fprintf (stderr, + " -v,--version: Print version and exit\n"); + fprintf (stderr, + " --help: Print help and exit\n"); } /* This routine is called by usysdep_walk_tree when moving the diff --git a/gnu/libexec/uucp/uusched/uusched.in b/gnu/libexec/uucp/uusched/uusched.in index e539b902fba..5acb86a5c48 100644 --- a/gnu/libexec/uucp/uusched/uusched.in +++ b/gnu/libexec/uucp/uusched/uusched.in @@ -1,8 +1,8 @@ -: +#!/bin/sh # uusched # Call all systems which have work in a random order # -# Copyright (C) 1992 Ian Lance Taylor +# Copyright (C) 1992, 1993 Ian Lance Taylor # # Please feel free do whatever you like with this exciting shell # script. @@ -10,4 +10,4 @@ # This is pretty trivial, since all the functionality was moved into # uucico itself. # -@SBINDIR@/uucico -r1 $* +exec @SBINDIR@/uucico -r1 $* diff --git a/gnu/libexec/uucp/uustat/Makefile b/gnu/libexec/uucp/uustat/Makefile index 7451292ceaa..5cdee40ae39 100644 --- a/gnu/libexec/uucp/uustat/Makefile +++ b/gnu/libexec/uucp/uustat/Makefile @@ -1,5 +1,5 @@ # Makefile for uustat -# $Id: Makefile,v 1.2 1993/08/05 16:15:22 jtc Exp $ +# $Id: Makefile,v 1.3 1994/10/24 22:29:40 jtc Exp $ BINDIR= $(bindir) BINOWN= $(owner) @@ -9,8 +9,8 @@ PROG= uustat SRCS= uustat.c util.c log.c copy.c LDADD+= $(LIBUNIX) $(LIBUUCONF) $(LIBUUCP) DPADD+= $(LIBUNIX) $(LIBUUCONF) $(LIBUUCP) -CFLAGS+= -I$(.CURDIR)/../common_sources\ - -DOWNER=\"$(owner)\"\ +CFLAGS+= -I$(.CURDIR)/../common_sources \ + -DOWNER=\"$(owner)\" \ -DVERSION=\"$(VERSION)\" .include <bsd.prog.mk> diff --git a/gnu/libexec/uucp/uustat/uustat.1 b/gnu/libexec/uucp/uustat/uustat.1 index b8185216764..f3657016eaf 100644 --- a/gnu/libexec/uucp/uustat/uustat.1 +++ b/gnu/libexec/uucp/uustat/uustat.1 @@ -1,38 +1,102 @@ -''' $Id: uustat.1,v 1.1 1993/08/04 19:37:04 jtc Exp $ -.TH uustat 1 "Taylor UUCP 1.04" +''' $Id: uustat.1,v 1.2 1994/10/24 22:29:44 jtc Exp $ +.TH uustat 1 "Taylor UUCP 1.05" .SH NAME uustat \- UUCP status inquiry and control .SH SYNOPSIS .B uustat \-a .PP +.B uustat \-\-all +.PP .B uustat [ -.B \-eKiMNQ ] [ +.B \-eKRiMNQ ] [ .B \-sS system ] [ .B \-uU user ] [ .B \-cC command ] [ -.B \-o -hours ] [ -.B \-y +.B \-oy hours ] [ .B \-B +lines ] [ +.B \-\-executions +] [ +.B \-\-kill-all +] [ +.B \-\-rejuvenate-all +] [ +.B \-\-prompt +] [ +.B \-\-mail +] [ +.B \-\-notify +] [ +.B \-\-no-list +] [ +.B \-\-system +system ] [ +.B \-\-not-system +system ] [ +.B \-\-user +user ] [ +.B \-\-not-user +user ] [ +.B \-\-command +command ] [ +.B \-\-not-command +command ] [ +.B \-\-older-than +hours ] [ +.B \-\-younger-than +hours ] [ +.B \-\-mail-lines lines ] .PP .B uustat [ -.B \-k +.B \-kr jobid ] [ -.B \-r +.B \-\-kill +jobid ] [ +.B \-\-rejuvenate jobid ] .PP -.B uustat \-q +.B uustat \-q [ +.B \-sS +system ] [ +.B \-oy +hours ] [ +.B \-\-system +system ] [ +.B \-\-not-system +system ] [ +.B \-\-older-than +hours ] [ +.B \-\-younger-than +hours ] +.PP +.B uustat \-\-list [ +.B \-sS +system ] [ +.B \-oy +hours ] [ +.B \-\-system +system ] [ +.B \-\-not-system +system ] [ +.B \-\-older-than +hours ] [ +.B \-\-younger-than +hours ] .PP .B uustat \-m .PP +.B uustat \-\-status +.PP .B uustat \-p +.PP +.B uustat \-\-ps .SH DESCRIPTION The .I uustat @@ -46,35 +110,47 @@ system. It can also be used to cancel or rejuvenate requests made by By default .I uustat displays all jobs queued up for the invoking user, as if given the -.B \-u +.B \-\-user option with the appropriate argument. If any of the .B \-a, +.B \-\-all, .B \-e, +.B \-\-executions, .B \-s, +.B \-\-system, .B \-S, +.B \-\-not-system, .B \-u, +.B \-\-user, .B \-U, +.B \-\-not-user, .B \-c, +.B \-\-command, .B \-C, +.B \-\-not-command, .B \-o, -.B \-y +.B \-\-older-than, +.B \-y, +.B \-\-younger-than options are given, then all jobs which match the combined specifications are displayed. The .B \-K +or +.B \-\-kill-all option may be used to kill off a selected group of jobs, such as all jobs more than 7 days old. .SH OPTIONS The following options may be given to .I uustat. .TP 5 -.B \-a +.B \-a, \-\-all List all queued file transfer requests. .TP 5 -.B \-e +.B \-e, \-\-executions List queued execution requests rather than queued file transfer requests. Queued execution requests are processed by .I uuxqt @@ -86,62 +162,82 @@ of .I uux (1). .TP 5 -.B \-s system -List all jobs queued up for the named system. This option may be +.B \-s system, \-\-system system +List all jobs queued up for the named system. These options may be specified multiple times, in which case all jobs for all the systems -will be listed. +will be listed. If used with +.B \-\-list +only the systems named will be listed. .TP 5 -.B \-S system -List all jobs queued for systems other than the one named. This -option may be specified multiple times, in which case no jobs from any -of the specified systems will be listed. This option may not be used -with -.B \-s. +.B \-S system, \-\-not-system system +List all jobs queued for systems other than the one named. These +options may be specified multiple times, in which case no jobs from +any of the specified systems will be listed. If used with +.B \-\-list +only the systems not named will be listed. These options may not be +used with +.B \-s +or +.B \-\-system. .TP 5 -.B \-u user -List all jobs queued up for the named user. This option may be +.B \-u user, \-\-user user +List all jobs queued up for the named user. These options may be specified multiple times, in which case all jobs for all the users will be listed. .TP 5 -.B \-U user -List all jobs queued up for users other than the one named. This -option may be specified multiple times, in which case no jobs from any -of the specified users will be listed. This option may not be used -with -.B \-u. +.B \-U user, \-\-not-user user +List all jobs queued up for users other than the one named. These +options may be specified multiple times, in which case no jobs from +any of the specified users will be listed. These options may not be +used with +.B \-u +or +.B \-\-user. .TP 5 -.B \-c command +.B \-c command, \-\-command command List all jobs requesting the execution of the named command. If .B command is .I ALL this will list all jobs requesting the execution of some command (as -opposed to simply requesting a file transfer). This option may be +opposed to simply requesting a file transfer). These options may be specified multiple times, in which case all jobs requesting any of the commands will be listed. .TP 5 -.B \-C command +.B \-C command, \-\-not-command command List all jobs requesting execution of some command other than the named command, or, if .B command is .I ALL, list all jobs that simply request a file transfer (as opposed to -requesting the execution of some command). This option may be +requesting the execution of some command). These options may be specified multiple times, in which case no job requesting one of the -specified commands will be listed. This option may not be used with -.B \-c. +specified commands will be listed. These options may not be used with +.B \-c +or +.B \-\-command. .TP 5 -.B \-o hours -List all queued jobs older than the given number of hours. +.B \-o hours, \-\-older-than hours +List all queued jobs older than the given number of hours. If used +with +.B \-\-list +only systems whose oldest job is older than the given number of hours +will be listed. .TP 5 -.B \-y hours -List all queued jobs younger than the given number of hours. +.B \-y hours, \-\-younger-than hours +List all queued jobs younger than the given number of hours. If used +with +.B \-\-list +only systems whose oldest job is younger than the given number of +hours will be listed. .TP 5 -.B \-k jobid +.B \-k jobid, \-\-kill jobid Kill the named job. The job id is shown by the default output format, as well as by the .B \-j +or +.B \-\-jobid option to .I uucp (1) or @@ -149,40 +245,59 @@ option to (1). A job may only be killed by the user who created the job, or by the UUCP administrator or the superuser. The .B \-k -option may be used multiple times on the command line to kill several +or +.B \-\-kill +options may be used multiple times on the command line to kill several jobs. .TP 5 -.B \-r jobid +.B \-r jobid, \-\-rejuvenate jobid Rejuvenate the named job. This will mark it as having been invoked at the current time, affecting the output of the -.B \-o +.B \-o, +.B \-\-older-than, +.B \-y, or -.B \-y +.B \-\-younger-than options and preserving it from any automated cleanup daemon. The job id is shown by the default output format, as well as by the .B \-j -option to +or +.B \-\-jobid +options to .I uucp (1) or .I uux (1). A job may only be rejuvenated by the user who created the job, or by the UUCP administrator or the superuser. The .B \-r -option may be used multiple times on the command line to rejuvenate +or +.B \-\-rejuvenate +options may be used multiple times on the command line to rejuvenate several jobs. .TP 5 -.B \-q +.B \-q, \-\-list Display the status of commands, executions and conversations for all -remote systems for which commands or executions are queued. +remote systems for which commands or executions are queued. The +.B \-s, +.B \-\-system, +.B \-S, +.B \-\-not-system, +.B \-o, +.B \-\-older-than, +.B \-y, +and +.B \-\-younger-than +options may be used to restrict the systems which are listed. Systems +for which no commands or executions are queued will never be listed. .TP 5 -.B \-m +.B \-m, \-\-status Display the status of conversations for all remote systems. .TP 5 -.B \-p +.B \-p, \-\-ps Display the status of all processes holding UUCP locks on systems or ports. .TP 5 -.B \-i +.B \-i, \-\-prompt For each listed job, prompt whether to kill the job or not. If the first character of the input line is .I y @@ -190,53 +305,66 @@ or .I Y the job will be killed. .TP 5 -.B \-K +.B \-K, \-\-kill-all Automatically kill each listed job. This can be useful for automatic cleanup scripts, in conjunction with the -.B \-M +.B \-\-mail and -.B \-N +.B \-\-notify options. .TP 5 -.B \-M +.B \-R, \-\-rejuvenate-all +Automatically rejuvenate each listed job. This may not be used with +.B \-\-kill-all. +.TP 5 +.B \-M, \-\-mail For each listed job, send mail to the UUCP administrator. If the job is killed (due to -.B \-K +.B \-\-kill-all or -.B \-i +.B \-\-prompt with an affirmative response) the mail will indicate that. A comment specified by the -.B \-W +.B \-\-comment option may be included. If the job is an execution, the initial portion of its standard input will be included in the mail message; the number of lines to include may be set with the -.B \-B +.B \-\-mail-lines option (the default is 100). If the standard input contains null characters, it is assumed to be a binary file and is not included. .TP 5 -.B \-N +.B \-N, \-\-notify For each listed job, send mail to the user who requested the job. The mail is identical to that sent by the .B \-M -option. +or +.B \-\-mail +options. .TP 5 -.B \-W +.B \-W, \-\-comment Specify a comment to be included in mail sent with the -.B \-M +.B \-M, +.B \-\-mail, +.B \-N, or -.B \-N +.B \-\-notify options. .TP 5 -.B \-Q +.B \-Q, \-\-no-list Do not actually list the job, but only take any actions indicated by the .B \-i, +.B \-\-prompt, .B \-K, +.B \-\-kill-all, .B \-M, +.B \-\-mail, .B \-N +or +.B \-\-notify options. .TP 5 -.B \-x type +.B \-x type, \-\-debug type Turn on particular debugging types. The following types are recognized: abnormal, chat, handshake, uucp-proto, proto, port, config, spooldir, execute, incoming, outgoing. Only abnormal, config, @@ -244,94 +372,122 @@ spooldir and execute are meaningful for .I uustat. Multiple types may be given, separated by commas, and the -.B \-x +.B \-\-debug option may appear multiple times. A number may also be given, which will turn on that many types from the foregoing list; for example, -.B \-x 2 +.B \-\-debug 2 is equivalent to -.B \-x abnormal,chat. +.B \-\-debug abnormal,chat. .TP 5 -.B \-I file +.B \-I file, \-\-config file Set configuration file to use. This option may not be available, depending upon how .I uustat was compiled. +.TP 5 +.B \-v, \-\-version +Report version information and exit. +.TP 5 +.B \-\-help +Print a help message and exit. .SH EXAMPLES -.EX -uustat -a -.EE +.br +.nf +uustat --all +.fi Display status of all jobs. A sample output line is as follows: -.EX +.br +.in +0.5i +.nf bugsA027h bugs ian 04-01 13:50 Executing rmail ian@airs.com (sending 1283 bytes) -.EE +.fi +.in -0.5i The format is -.EX +.br +.in +0.5i +.nf jobid system user queue-date command (size) -.EE +.fi +.in -0.5i The jobid may be passed to the -.B \-k +.B \-\-kill or -.B \-r +.B \-\-rejuvenate options. The size indicates how much data is to be transferred to the remote system, and is absent for a file receive request. The -.B \-s, -.B \-S, -.B \-u, -.B \-U, -.B \-c, -.B \-C, -.B \-o, +.B \-\-system, +.B \-\-not-system, +.B \-\-user, +.B \-\-not-user, +.B \-\-command, +.B \-\-not-command, +.B \-\-older-than, and -.B \-y +.B \-\-younger-than options may be used to control which jobs are listed. -.EX -uustat -e -.EE +.br +.nf +uustat --executions +.fi Display status of queued up execution requests. A sample output line is as follows: -.EX +.br +.in +0.5i +.nf bugs bugs!ian 05-20 12:51 rmail ian -.EE +.fi +.in -0.5i The format is -.EX +.br +.in +0.5i +.nf system requestor queue-date command -.EE +.fi +.in -0.5i The -.B \-s, -.B \-S, -.B \-u, -.B \-U, -.B \-c, -.B \-C, -.B \-o, +.B \-\-system, +.B \-\-not-system, +.B \-\-user, +.B \-\-not-user, +.B \-\-command, +.B \-\-not-command, +.B \-\-older-than, and -.B \-y +.B \-\-younger-than options may be used to control which requests are listed. -.EX -uustat -q -.EE +.br +.nf +uustat --list +.fi Display status for all systems with queued up commands. A sample output line is as follows: -.EX +.br +.in +0.5i +.nf bugs 4C (1 hour) 0X (0 secs) 04-01 14:45 Dial failed -.EE +.fi +.in -0.5i This indicates the system, the number of queued commands, the age of the oldest queued command, the number of queued local executions, the age of the oldest queued execution, the date of the last conversation, and the status of that conversation. -.EX -uustat -m -.EE +.br +.nf +uustat --status +.fi Display conversation status for all remote systems. A sample output line is as follows: -.EX +.br +.in +0.5i +.nf bugs 04-01 15:51 Conversation complete -.EE +.fi +.in -0.5i This indicates the system, the date of the last conversation, and the status of that conversation. If the last conversation failed, .I uustat @@ -340,9 +496,10 @@ the retry period is currently preventing calls to that system, .I uustat also displays the time when the next call will be permitted. -.EX -uustat -p -.EE +.br +.nf +uustat --ps +.fi Display the status of all processes holding UUCP locks. The output format is system dependent, as .I uustat @@ -350,18 +507,21 @@ simply invokes .I ps (1) on each process holding a lock. -.EX -uustat -c rmail -o 168 -K -Q -M -N -W"Queued for over 1 week" -.EE +.br +.in +0.5i +.nf +uustat --command rmail --older-than 168 --kill-all --no-list --mail --notify --comment "Queued for over 1 week" +.fi +.in -0.5i This will kill all .I rmail commands that have been queued up waiting for delivery for over 1 week (168 hours). For each such command, mail will be sent both to the UUCP administrator and to the user who requested the rmail execution. The mail message sent will include the string given by the -.B \-W +.B \-\-comment option. The -.B \-Q +.B \-\-no-list option prevents any of the jobs from being listed on the terminal, so any output from the program will be error messages. .SH FILES @@ -377,4 +537,4 @@ UUCP spool directory. ps(1), rmail(1), uucp(1), uux(1), uucico(8), uuxqt(8) .SH AUTHOR Ian Lance Taylor -(ian@airs.com or uunet!airs!ian) +(ian@airs.com) diff --git a/gnu/libexec/uucp/uustat/uustat.c b/gnu/libexec/uucp/uustat/uustat.c index 3c1352668c2..6d0a524f89c 100644 --- a/gnu/libexec/uucp/uustat/uustat.c +++ b/gnu/libexec/uucp/uustat/uustat.c @@ -1,7 +1,7 @@ /* uustat.c UUCP status program - Copyright (C) 1991, 1992 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -20,19 +20,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or - c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. */ #include "uucp.h" #if USE_RCS_ID -const char uustat_rcsid[] = "$Id: uustat.c,v 1.1 1993/08/04 19:37:05 jtc Exp $"; +const char uustat_rcsid[] = "$Id: uustat.c,v 1.2 1994/10/24 22:29:51 jtc Exp $"; #endif #include <ctype.h> #include <errno.h> -#if HAVE_TIME_H +#if TM_IN_SYS_TIME +#include <sys/time.h> +#else #include <time.h> #endif @@ -71,16 +73,14 @@ const char uustat_rcsid[] = "$Id: uustat.c,v 1.1 1993/08/04 19:37:05 jtc Exp $"; -xdebug set debugging level -yhour report jobs younger than specified number of hours */ -/* The program name. */ -char abProgram[] = "uustat"; - /* What to do with a job that matches the selection criteria; these values may be or'red together. */ #define JOB_SHOW (01) #define JOB_INQUIRE (02) #define JOB_KILL (04) -#define JOB_MAIL (010) -#define JOB_NOTIFY (020) +#define JOB_REJUVENATE (010) +#define JOB_MAIL (020) +#define JOB_NOTIFY (040) /* This structure is used to accumulate all the lines in a single command file, so that they can all be displayed at once and so that @@ -96,6 +96,7 @@ struct scmdlist /* Local functions. */ static void ususage P((void)); +static void ushelp P((void)); static boolean fsxqt_file_read P((pointer puuconf, const char *zfile)); static void usxqt_file_free P((void)); static int isxqt_cmd P((pointer puuconf, int argc, char **argv, pointer pvar, @@ -139,16 +140,48 @@ static boolean fsexecutions P((pointer puuconf, int icmd, int csystems, static boolean fsnotify P((pointer puuconf, int icmd, const char *zcomment, int cstdin, boolean fkilled, const char *zcmd, struct scmdlist *qcmd, const char *zid, - const char *zuser, + long itime, const char *zuser, const struct uuconf_system *qsys, const char *zstdin, pointer pstdinseq, const char *zrequestor)); -static boolean fsquery P((pointer puuconf)); +static boolean fsquery P((pointer puuconf, int csystems, + char **pazsystems, boolean fnotsystems, + long iold, long iyoung)); static int csunits_show P((long idiff)); static boolean fsmachines P((void)); /* Long getopt options. */ -static const struct option asSlongopts[] = { { NULL, 0, NULL, 0 } }; +static const struct option asSlongopts[] = +{ + { "all", no_argument, NULL, 'a' }, + { "mail-lines", required_argument, NULL, 'B' }, + { "command", required_argument, NULL, 'c' }, + { "not-command", required_argument, NULL, 'C' }, + { "executions", no_argument, NULL, 'e' }, + { "prompt", no_argument, NULL, 'i' }, + { "kill", required_argument, NULL, 'k' }, + { "kill-all", no_argument, NULL, 'K' }, + { "status", no_argument, NULL, 'm' }, + { "mail", no_argument, NULL, 'M' }, + { "notify", no_argument, NULL, 'N' }, + { "older-than", required_argument, NULL, 'o' }, + { "ps", no_argument, NULL, 'p' }, + { "list", no_argument, NULL, 'q' }, + { "no-list", no_argument, NULL, 'Q' }, + { "rejuvenate", required_argument, NULL, 'r' }, + { "rejuvenate-all", no_argument, NULL, 'R' }, + { "system", required_argument, NULL, 's' }, + { "not-system", required_argument, NULL, 'S' }, + { "user", required_argument, NULL, 'u' }, + { "not-user", required_argument, NULL, 'U' }, + { "comment", required_argument, NULL, 'W' }, + { "younger-than", required_argument, NULL, 'y' }, + { "config", required_argument, NULL, 'I' }, + { "debug", required_argument, NULL, 'x' }, + { "version", no_argument, NULL, 'v' }, + { "help", no_argument, NULL, 1 }, + { NULL, 0, NULL, 0 } +}; int main (argc, argv) @@ -204,8 +237,10 @@ main (argc, argv) const char *azoneuser[1]; boolean fret; + zProgram = argv[0]; + while ((iopt = getopt_long (argc, argv, - "aB:c:C:eiI:k:KmMNo:pqQr:s:S:u:U:W:x:y:", + "aB:c:C:eiI:k:KmMNo:pqQr:Rs:S:u:U:vW:x:y:", asSlongopts, (int *) NULL)) != EOF) { switch (iopt) @@ -304,6 +339,11 @@ main (argc, argv) pazrejuvs[crejuvs - 1] = optarg; break; + case 'R': + /* Rejuvenate each listed job. */ + icmd |= JOB_REJUVENATE; + break; + case 'S': /* List jobs for other than specified system. */ fnotsystems = TRUE; @@ -345,13 +385,26 @@ main (argc, argv) iyounghours = (int) strtol (optarg, (char **) NULL, 10); break; + case 'v': + /* Print version and exit. */ + printf ("%s: Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", + zProgram, VERSION); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + + case 1: + /* --help. */ + ushelp (); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + case 0: /* Long option found and flag set. */ break; default: ususage (); - break; + /*NOTREACHED*/ } } @@ -371,15 +424,23 @@ main (argc, argv) ++ccmds; if (fps) ++ccmds; - if (fquery) - ++ccmds; - if (fexecute || csystems > 0 || cusers > 0 || ioldhours != -1 + if (fexecute || fquery || csystems > 0 || cusers > 0 || ioldhours != -1 || iyounghours != -1 || ccommands > 0) ++ccmds; + if (fexecute && fquery) + ++ccmds; if (ccmds > 1) { - ulog (LOG_ERROR, "Too many options"); + fprintf (stderr, "%s: too many options\n", zProgram); + ususage (); + } + + if ((icmd & JOB_KILL) != 0 + && (icmd & JOB_REJUVENATE) != 0) + { + fprintf (stderr, "%s: can not both rejuvenate and kill jobs\n", + zProgram); ususage (); } @@ -453,6 +514,7 @@ main (argc, argv) } if (! fexecute + && ! fquery && (fall || csystems > 0 || cusers > 0 @@ -471,12 +533,22 @@ main (argc, argv) else if (icmd != JOB_SHOW) { ulog (LOG_ERROR, - "-i, -K, -M, -N, -Q not supported with -k, -m, -p, -q, -r"); + "-i, -K, -M, -N, -Q, -R not supported with -k, -m, -p, -q, -r"); ususage (); fret = FALSE; } else if (fquery) - fret = fsquery (puuconf); + { + if (cusers > 0 || ccommands > 0) + { + ulog (LOG_ERROR, "-u, -c not supported with -q"); + ususage (); + fret = FALSE; + } + else + fret = fsquery (puuconf, csystems, pazsystems, fnotsystems, + iold, iyoung); + } else if (fmachine) fret = fsmachines (); else if (ckills > 0 || crejuvs > 0) @@ -515,62 +587,48 @@ main (argc, argv) static void ususage () { - fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", - VERSION); - fprintf (stderr, - "Usage: uustat [options]\n"); - fprintf (stderr, - " -a: list all UUCP jobs\n"); - fprintf (stderr, - " -B num: number of lines to return in -M or -N mail message\n"); - fprintf (stderr, - " -c command: list requests for named command\n"); - fprintf (stderr, - " -C command: list requests for other than named command\n"); - fprintf (stderr, - " -e: list queued executions rather than job requests\n"); - fprintf (stderr, - " -i: prompt for whether to kill each listed job\n"); - fprintf (stderr, - " -k job: kill specified UUCP job\n"); - fprintf (stderr, - " -K: kill each listed job\n"); - fprintf (stderr, - " -m: report status for all remote machines\n"); - fprintf (stderr, - " -M: mail report on each listed job to UUCP administrator\n"); - fprintf (stderr, - " -N: mail report on each listed job to requestor\n"); - fprintf (stderr, - " -o hours: list all jobs older than given number of hours\n"); - fprintf (stderr, - " -p: show status of all processes holding UUCP locks\n"); - fprintf (stderr, - " -q: list number of jobs for each system\n"); - fprintf (stderr, - " -Q: don't list jobs, just take actions (-i, -K, -M, -N)\n"); - fprintf (stderr, - " -r job: rejuvenate specified UUCP job\n"); - fprintf (stderr, - " -s system: list all jobs for specified system\n"); - fprintf (stderr, - " -S system: list all jobs for other than specified system\n"); - fprintf (stderr, - " -u user: list all jobs for specified user\n"); - fprintf (stderr, - " -U user: list all jobs for other than specified user\n"); - fprintf (stderr, - " -W comment: comment to include in mail messages\n"); - fprintf (stderr, - " -y hours: list all jobs younger than given number of hours\n"); - fprintf (stderr, - " -x debug: Set debugging level (0 for none, 9 is max)\n"); + fprintf (stderr, "Usage: %s [options]\n", zProgram); + fprintf (stderr, "Use %s --help for help\n", zProgram); + exit (EXIT_FAILURE); +} + +/* Print a help message. */ + +static void +ushelp () +{ + printf ("Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", + VERSION); + printf ("Usage: %s [options]\n", zProgram); + printf (" -a,--all: list all UUCP jobs\n"); + printf (" -B,--mail-lines num: number of lines to return in -M or -N mail message\n"); + printf (" -c,--command command: list requests for named command\n"); + printf (" -C,--not-command command: list requests for other than named command\n"); + printf (" -e,--executions: list queued executions rather than job requests\n"); + printf (" -i,--prompt: prompt for whether to kill each listed job\n"); + printf (" -k,--kill job: kill specified UUCP job\n"); + printf (" -K,--kill-all: kill each listed job\n"); + printf (" -m,--status: report status for all remote machines\n"); + printf (" -M,--mail: mail report on each listed job to UUCP administrator\n"); + printf (" -N,--notify: mail report on each listed job to requestor\n"); + printf (" -o,--older-than hours: list all jobs older than given number of hours\n"); + printf (" -p,--ps: show status of all processes holding UUCP locks\n"); + printf (" -q,--list: list number of jobs for each system\n"); + printf (" -Q,--no-list: don't list jobs, just take actions (-i, -K, -M, -N)\n"); + printf (" -r,--rejuvenate job: rejuvenate specified UUCP job\n"); + printf (" -R,--rejuvenate-all: rejuvenate each listed job\n"); + printf (" -s,--system system: list all jobs for specified system\n"); + printf (" -S,--not-system system: list all jobs for other than specified system\n"); + printf (" -u,--user user: list all jobs for specified user\n"); + printf (" -U,--not-user user: list all jobs for other than specified user\n"); + printf (" -W,--comment comment: comment to include in mail messages\n"); + printf (" -y,--younger-than hours: list all jobs younger than given number of hours\n"); + printf (" -x,--debug debug: Set debugging level\n"); #if HAVE_TAYLOR_CONFIG - fprintf (stderr, - " -I file: Set configuration file to use\n"); + printf (" -I,--config file: Set configuration file to use\n"); #endif /* HAVE_TAYLOR_CONFIG */ - exit (EXIT_FAILURE); + printf (" -v,--version: Print version and exit\n"); + printf (" --help: Print help and exit\n"); } /* We need to be able to read information from an execution file. */ @@ -1051,15 +1109,12 @@ fsworkfile_show (puuconf, icmd, qsys, qcmd, itime, ccommands, pazcommands, else zfile = zbufcpy (qshow->s.zfrom); if (zfile == NULL) - cbytes = 0; + cbytes = -1; else - { - cbytes = csysdep_size (zfile); - if (cbytes < 0) - cbytes = 0; - } - printf ("Sending %s (%ld bytes) to %s", - qshow->s.zfrom, cbytes, qshow->s.zto); + cbytes = csysdep_size (zfile); + if (cbytes >= 0) + printf ("Sending %s (%ld bytes) to %s", + qshow->s.zfrom, cbytes, qshow->s.zto); ubuffree (zfile); break; case 'R': @@ -1206,25 +1261,28 @@ fsworkfile_show (puuconf, icmd, qsys, qcmd, itime, ccommands, pazcommands, if (fmatch) { - boolean fkill; + boolean fkill_or_rejuv; - fkill = FALSE; + fkill_or_rejuv = FALSE; if ((icmd & JOB_INQUIRE) != 0) { int b; /* Ask stdin whether this job should be killed. */ - fprintf (stderr, "%s: Kill %s? ", abProgram, zlistid); + fprintf (stderr, "%s: %s %s?", + (icmd & JOB_REJUVENATE) != 0 ? "Rejuvenate" : "Kill", + zProgram, zlistid); (void) fflush (stderr); b = getchar (); - fkill = b == 'y' || b == 'Y'; + fkill_or_rejuv = b == 'y' || b == 'Y'; while (b != EOF && b != '\n') b = getchar (); } - else if ((icmd & JOB_KILL) != 0) - fkill = TRUE; + else if ((icmd & JOB_KILL) != 0 + || (icmd & JOB_REJUVENATE) != 0) + fkill_or_rejuv = TRUE; - if (fkill + if (fkill_or_rejuv && (qlist->s.zuser == NULL || strcmp (zsysdep_login_name (), qlist->s.zuser) != 0) && ! fsysdep_privileged ()) @@ -1233,16 +1291,27 @@ fsworkfile_show (puuconf, icmd, qsys, qcmd, itime, ccommands, pazcommands, { if ((icmd & (JOB_MAIL | JOB_NOTIFY)) != 0) { - if (! fsnotify (puuconf, icmd, zcomment, cstdin, fkill, - zcmd, qlist, zlistid, qlist->s.zuser, - qsys, zstdin, qlist->s.pseq, zrequestor)) + if (! fsnotify (puuconf, icmd, zcomment, cstdin, + (fkill_or_rejuv && + (icmd & JOB_REJUVENATE) == 0), + zcmd, qlist, zlistid, qlist->itime, + qlist->s.zuser, qsys, zstdin, + qlist->s.pseq, zrequestor)) return FALSE; } - if (fkill) + if (fkill_or_rejuv) { - if (! fsysdep_kill_job (puuconf, zlistid)) - return FALSE; + if ((icmd & JOB_REJUVENATE) == 0) + { + if (! fsysdep_kill_job (puuconf, zlistid)) + return FALSE; + } + else + { + if (! fsysdep_rejuvenate_job (puuconf, zlistid)) + return FALSE; + } } } } @@ -1433,7 +1502,7 @@ fsexecutions (puuconf, icmd, csystems, pazsystems, fnotsystems, cusers, if (fmatch) { - boolean fbad, fkill; + boolean fbad, fkill_or_rejuv; struct uuconf_system ssys; fbad = FALSE; @@ -1456,23 +1525,26 @@ fsexecutions (puuconf, icmd, csystems, pazsystems, fnotsystems, cusers, printf ("%s\n", zSxqt_cmd); } - fkill = FALSE; + fkill_or_rejuv = FALSE; if ((icmd & JOB_INQUIRE) != 0) { int b; /* Ask stdin whether this job should be killed. */ - fprintf (stderr, "%s: Kill %s? ", abProgram, zSxqt_cmd); + fprintf (stderr, "%s: %s %s?", + (icmd & JOB_REJUVENATE) != 0 ? "Rejuvenate" : "Kill", + zProgram, zSxqt_cmd); (void) fflush (stderr); b = getchar (); - fkill = b == 'y' || b == 'Y'; + fkill_or_rejuv = b == 'y' || b == 'Y'; while (b != EOF && b != '\n') b = getchar (); } - else if ((icmd & JOB_KILL) != 0) - fkill = TRUE; + else if ((icmd & JOB_KILL) != 0 + || (icmd & JOB_REJUVENATE) != 0) + fkill_or_rejuv = TRUE; - if (fkill) + if (fkill_or_rejuv) { if ((strcmp (zSxqt_user, zsysdep_login_name ()) != 0 || strcmp (zsystem, zlocalname) != 0) @@ -1513,9 +1585,10 @@ fsexecutions (puuconf, icmd, csystems, pazsystems, fnotsystems, cusers, if (! fbad && (icmd & (JOB_MAIL | JOB_NOTIFY)) != 0) { - if (! fsnotify (puuconf, icmd, zcomment, cstdin, fkill, + if (! fsnotify (puuconf, icmd, zcomment, cstdin, + fkill_or_rejuv && (icmd & JOB_REJUVENATE) == 0, zSxqt_cmd, (struct scmdlist *) NULL, - (const char *) NULL, zSxqt_user, &ssys, + (const char *) NULL, itime, zSxqt_user, &ssys, zSxqt_stdin, (pointer) NULL, zSxqt_requestor)) { ferr = TRUE; @@ -1526,7 +1599,7 @@ fsexecutions (puuconf, icmd, csystems, pazsystems, fnotsystems, cusers, } } - if (! fbad && fkill) + if (! fbad && fkill_or_rejuv) { for (i = 0; i < cSxqt_files; i++) { @@ -1536,13 +1609,21 @@ fsexecutions (puuconf, icmd, csystems, pazsystems, fnotsystems, cusers, (pointer) NULL); if (z != NULL) { - (void) remove (z); + if ((icmd & JOB_REJUVENATE) != 0) + (void) fsysdep_touch_file (z); + else + (void) remove (z); ubuffree (z); } } - if (remove (zfile) != 0) - ulog (LOG_ERROR, "remove (%s): %s", zfile, - strerror (errno)); + if ((icmd & JOB_REJUVENATE) != 0) + (void) fsysdep_touch_file (zfile); + else + { + if (remove (zfile) != 0) + ulog (LOG_ERROR, "remove (%s): %s", zfile, + strerror (errno)); + } } if (! fbad) @@ -1562,8 +1643,8 @@ fsexecutions (puuconf, icmd, csystems, pazsystems, fnotsystems, cusers, /* When a job is killed, send mail to the appropriate people. */ static boolean -fsnotify (puuconf, icmd, zcomment, cstdin, fkilled, zcmd, qcmd, zid, zuser, - qsys, zstdin, pstdinseq, zrequestor) +fsnotify (puuconf, icmd, zcomment, cstdin, fkilled, zcmd, qcmd, zid, itime, + zuser, qsys, zstdin, pstdinseq, zrequestor) pointer puuconf; int icmd; const char *zcomment; @@ -1572,6 +1653,7 @@ fsnotify (puuconf, icmd, zcomment, cstdin, fkilled, zcmd, qcmd, zid, zuser, const char *zcmd; struct scmdlist *qcmd; const char *zid; + long itime; const char *zuser; const struct uuconf_system *qsys; const char *zstdin; @@ -1581,6 +1663,8 @@ fsnotify (puuconf, icmd, zcomment, cstdin, fkilled, zcmd, qcmd, zid, zuser, const char **pz; int cgot; int i, istdin; + struct tm stime; + char ab[sizeof "1991-12-31 12:00:00"]; const char *zsubject; boolean fret; @@ -1615,7 +1699,14 @@ fsnotify (puuconf, icmd, zcomment, cstdin, fkilled, zcmd, qcmd, zid, zuser, pz[i++] = "\n"; } - pz[i++] = "The job "; + pz[i++] = "The job was queued at "; + usysdep_localtime (itime, &stime); + sprintf (ab, "%04d-%02d-%02d %02d:%02d:%02d", + stime.tm_year + 1900, stime.tm_mon + 1, stime.tm_mday, + stime.tm_hour, stime.tm_min, stime.tm_sec); + pz[i++] = ab; + pz[i++] = ".\nIt "; + if (fkilled) pz[i++] = "was\n"; else @@ -1651,6 +1742,7 @@ fsnotify (puuconf, icmd, zcomment, cstdin, fkilled, zcmd, qcmd, zid, zuser, break; case 'P': pz[i++] = "\tpoll "; + break; #if DEBUG > 0 case 'E': ulog (LOG_FATAL, "fsnotify: Can't happen"); @@ -1677,7 +1769,8 @@ fsnotify (puuconf, icmd, zcomment, cstdin, fkilled, zcmd, qcmd, zid, zuser, if (fspool) zfile = zsysdep_spool_file_name (qsys, zstdin, pstdinseq); else - zfile = zsysdep_local_file (zstdin, qsys->uuconf_zpubdir); + zfile = zsysdep_local_file (zstdin, qsys->uuconf_zpubdir, + (boolean *) NULL); if (zfile != NULL && (fspool @@ -1827,15 +1920,23 @@ struct sxqtlist static boolean fsquery_system P((const struct uuconf_system *qsys, struct sxqtlist **pq, - long inow, const char *zlocalname)); + long inow, const char *zlocalname, + int csystems, char **pazsystems, + boolean fnotsystems, long iold, long iyoung)); static boolean fsquery_show P((const struct uuconf_system *qsys, int cwork, - long ifirstwork, - struct sxqtlist *qxqt, - long inow, const char *zlocalname)); + long ifirstwork, struct sxqtlist *qxqt, + long inow, const char *zlocalname, + int csystems, char **pazsystems, + boolean fnotsystems, long iold, long iyoung)); static boolean -fsquery (puuconf) +fsquery (puuconf, csystems, pazsystems, fnotsystems, iold, iyoung) pointer puuconf; + int csystems; + char **pazsystems; + boolean fnotsystems; + long iold; + long iyoung; { int iuuconf; const char *zlocalname; @@ -1926,7 +2027,8 @@ fsquery (puuconf) continue; } - if (! fsquery_system (&ssys, &qlist, inow, zlocalname)) + if (! fsquery_system (&ssys, &qlist, inow, zlocalname, csystems, + pazsystems, fnotsystems, iold, iyoung)) fret = FALSE; (void) uuconf_system_free (puuconf, &ssys); @@ -1965,7 +2067,9 @@ fsquery (puuconf) ssys.uuconf_zname = (char *) zlocalname; } - if (! fsquery_show (&ssys, 0, 0L, *pq, inow, zlocalname)) + if (! fsquery_show (&ssys, 0, 0L, *pq, inow, zlocalname, + csystems, pazsystems, fnotsystems, + iold, iyoung)) fret = FALSE; (void) uuconf_system_free (puuconf, &ssys); qfree = *pq; @@ -1991,7 +2095,8 @@ fsquery (puuconf) break; } - if (! fsquery_show (&ssys, 0, 0L, qlist, inow, zlocalname)) + if (! fsquery_show (&ssys, 0, 0L, qlist, inow, zlocalname, + csystems, pazsystems, fnotsystems, iold, iyoung)) fret = FALSE; (void) uuconf_system_free (puuconf, &ssys); qnext = qlist->qnext; @@ -2006,11 +2111,17 @@ fsquery (puuconf) /* Query a single known system. */ static boolean -fsquery_system (qsys, pq, inow, zlocalname) +fsquery_system (qsys, pq, inow, zlocalname, csystems, pazsystems, + fnotsystems, iold, iyoung) const struct uuconf_system *qsys; struct sxqtlist **pq; long inow; const char *zlocalname; + int csystems; + char **pazsystems; + boolean fnotsystems; + long iold; + long iyoung; { int cwork; long ifirstwork; @@ -2065,7 +2176,9 @@ fsquery_system (qsys, pq, inow, zlocalname) if (cwork == 0 && *pq == NULL) return TRUE; - fret = fsquery_show (qsys, cwork, ifirstwork, *pq, inow, zlocalname); + fret = fsquery_show (qsys, cwork, ifirstwork, *pq, inow, + zlocalname, csystems, pazsystems, fnotsystems, + iold, iyoung); if (*pq != NULL) { @@ -2084,13 +2197,19 @@ fsquery_system (qsys, pq, inow, zlocalname) local system specially. */ static boolean -fsquery_show (qsys, cwork, ifirstwork, qxqt, inow, zlocalname) +fsquery_show (qsys, cwork, ifirstwork, qxqt, inow, zlocalname, + csystems, pazsystems, fnotsystems, iold, iyoung) const struct uuconf_system *qsys; int cwork; long ifirstwork; struct sxqtlist *qxqt; long inow; const char *zlocalname; + int csystems; + char **pazsystems; + boolean fnotsystems; + long iold; + long iyoung; { boolean flocal; struct sstatus sstat; @@ -2098,6 +2217,34 @@ fsquery_show (qsys, cwork, ifirstwork, qxqt, inow, zlocalname) struct tm stime; int cpad; + /* Make sure this is one of the systems we are printing. */ + if (csystems > 0) + { + boolean fmatch; + int i; + + fmatch = fnotsystems; + for (i = 0; i < csystems; i++) + { + if (strcmp (pazsystems[i], qsys->uuconf_zname) == 0) + { + fmatch = ! fmatch; + break; + } + } + if (! fmatch) + return TRUE; + } + + /* Make sure the commands are within the time bounds. */ + if ((iold != (long) -1 + && (cwork == 0 || ifirstwork > iold) + && (qxqt == NULL || qxqt->ifirst > iold)) + || (iyoung != (long) -1 + && (cwork == 0 || ifirstwork < iyoung) + && (qxqt == NULL || qxqt->ifirst < iyoung))) + return TRUE; + flocal = strcmp (qsys->uuconf_zname, zlocalname) == 0; if (! flocal) diff --git a/gnu/libexec/uucp/uuto/uuto.in b/gnu/libexec/uucp/uuto/uuto.in index 2d7d96a9587..26a0dc7c15f 100644 --- a/gnu/libexec/uucp/uuto/uuto.in +++ b/gnu/libexec/uucp/uuto/uuto.in @@ -1,8 +1,8 @@ -: +#!/bin/sh # uuto # Send files to a user on another system. # -# Copyright (C) 1992 Ian Lance Taylor +# Copyright (C) 1992, 1993 Ian Lance Taylor # # Please feel free do whatever you like with this exciting shell # script. @@ -13,4 +13,4 @@ # -c means to not copy the files to the spool directory (may be # overriden by -C or -p). # -@BINDIR@/uucp -t -R -c $* +exec @BINDIR@/uucp -t -R -c $* diff --git a/gnu/libexec/uucp/uux/uux.1 b/gnu/libexec/uucp/uux/uux.1 index 69c85abb51b..050e433b87e 100644 --- a/gnu/libexec/uucp/uux/uux.1 +++ b/gnu/libexec/uucp/uux/uux.1 @@ -1,5 +1,5 @@ -''' $Id: uux.1,v 1.1 1993/08/04 19:37:13 jtc Exp $ -.TH uux 1 "Taylor UUCP 1.04" +''' $Id: uux.1,v 1.2 1994/10/24 22:30:11 jtc Exp $ +.TH uux 1 "Taylor UUCP 1.05" .SH NAME uux \- Remote command execution over UUCP .SH SYNOPSIS @@ -14,9 +14,11 @@ The command is not executed immediately; the request is queued until the .I uucico (8) daemon calls the system and executes it. The daemon is -started automatically unless the +started automatically unless one of the .B \-r -switch is given. +or +.B \-\-nouucico +options is given. The actual command execution is done by the .I uuxqt @@ -54,9 +56,12 @@ not work. All specified files are gathered together into a single directory before execution of the command begins. This means that each file must have a distinct base name. For example, -.EX +.br +.in +0.5i +.nf uux 'sys1!diff sys2!~user1/foo sys3!~user2/foo >!foo.diff' -.EE +.fi +.in -0.5i will fail because both files will be copied to sys1 and stored under the name foo. @@ -68,11 +73,11 @@ command on a remote system. The following options may be given to .I uux. .TP 5 -.B \-,\-p +.B \-, \-p, \-\-stdin Read standard input and use it as the standard input for the command to be executed. .TP 5 -.B \-c +.B \-c, \-\-nocopy Do not copy local files to the spool directory. This is the default. If they are removed before being processed by the @@ -83,20 +88,22 @@ removed before being processed by the as well as the by the invoker of .I uux. .TP 5 -.B \-C +.B \-C, \-\-copy Copy local files to the spool directory. .TP 5 -.B \-l +.B \-l, \-\-link Link local files into the spool directory. If a file can not be linked because it is on a different device, it will be copied unless -the +one of the .B \-c -option also appears (in other words, use of -.B \-l +or +.B \-\-nocopy +options also appears (in other words, use of +.B \-\-link switches the default from -.B \-c +.B \-\-nocopy to -.B \-C). +.B \-\-copy). If the files are changed before being processed by the .I uucico (8) daemon, the changed versions will be used. The files must be @@ -105,51 +112,50 @@ readable by the (8) daemon, as well as by the invoker of .I uux. .TP 5 -.B \-g grade +.B \-g grade, \-\-grade grade Set the grade of the file transfer command. Jobs of a higher grade are executed first. Grades run 0 ... 9 A ... Z a ... z from high to low. .TP 5 -.B \-n +.B \-n, \-\-notification=no Do not send mail about the status of the job, even if it fails. .TP 5 -.B \-z +.B \-z, \-\-notification=error Send mail about the status of the job if an error occurs. For many .I uuxqt daemons, including the Taylor UUCP .I uuxqt, this is the default action; for those, -.B \-z +.B \-\-notification=error will have no effect. However, some .I uuxqt daemons will send mail if the job succeeds unless the -.B \-z +.B \-\-notification=error option is used, and some other .I uuxqt daemons will not send mail if the job fails unless the -.B \-z +.B \-\-notification=error option is used. .TP 5 -.B \-r +.B \-r, \-\-nouucico Do not start the .I uucico (8) daemon immediately; merely queue up the execution request for later processing. .TP 5 -.B \-j +.B \-j, \-\-jobid Print jobids on standard output. A jobid will be generated for each file copy operation required to perform the operation. These file -copies may be cancelled by -passing the jobid to the -.B \-k +copies may be cancelled by passing the jobid to the +.B \-\-kill switch of .I uustat (1), which will make the execution impossible to complete. .TP 5 -.B \-a address +.B \-a address, \-\-requestor address Report job status to the specified e-mail address. .TP 5 -.B \-x type +.B \-x type, \-\-debug type Turn on particular debugging types. The following types are recognized: abnormal, chat, handshake, uucp-proto, proto, port, config, spooldir, execute, incoming, outgoing. Only abnormal, config, @@ -157,40 +163,51 @@ spooldir and execute are meaningful for .I uux. Multiple types may be given, separated by commas, and the -.B \-x +.B \-\-debug option may appear multiple times. A number may also be given, which will turn on that many types from the foregoing list; for example, -.B \-x 2 +.B \-\-debug 2 is equivalent to -.B \-x abnormal,chat. +.B \-\-debug abnormal,chat. .TP 5 -.B \-I file +.B \-I file, \-\-config file Set configuration file to use. This option may not be available, depending upon how .I uux was compiled. +.TP 5 +.B \-v, \-\-version +Report version information and exit. +.TP 5 +.B \-\-help +Print a help message and exit. .SH EXAMPLES -.EX +.br +.nf uux -z - sys1!rmail user1 -.EE +.fi Execute the command ``rmail user1'' on the system sys1, giving it as standard input whatever is given to .I uux as standard input. If a failure occurs, send a message using .I mail (1). -.EX + +.br +.nf uux 'diff -c sys1!~user1/file1 sys2!~user2/file2 >!file.diff' -.EE +.fi Fetch the two named files from system sys1 and system sys2 and execute .I diff putting the result in file.diff in the current directory. The current directory must be writable by the .I uuxqt (8) daemon for this to work. -.EX + +.br +.nf uux 'sys1!uucp ~user1/file1 (sys2!~user2/file2)' -.EE +.fi Execute .I uucp on the system sys1 copying file1 (on system sys1) to sys2. This @@ -226,9 +243,9 @@ mail(1), uustat(1), uucp(1), uucico(8), uuxqt(8) Files can not be referenced across multiple systems. Too many jobids are output by -.B \-j, +.B \-\-jobid, and there is no good way to cancel a local execution requiring remote files. .SH AUTHOR Ian Lance Taylor -(ian@airs.com or uunet!airs!ian) +(ian@airs.com) diff --git a/gnu/libexec/uucp/uux/uux.c b/gnu/libexec/uucp/uux/uux.c index 5dc98661483..6432392c6c0 100644 --- a/gnu/libexec/uucp/uux/uux.c +++ b/gnu/libexec/uucp/uux/uux.c @@ -1,7 +1,7 @@ /* uux.c Prepare to execute a command on a remote system. - Copyright (C) 1991, 1992 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -20,13 +20,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or - c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. */ #include "uucp.h" #if USE_RCS_ID -const char uux_rcsid[] = "$Id: uux.c,v 1.1 1993/08/04 19:37:14 jtc Exp $"; +const char uux_rcsid[] = "$Id: uux.c,v 1.2 1994/10/24 22:30:16 jtc Exp $"; #endif #include "uudefs.h" @@ -54,9 +54,6 @@ const char uux_rcsid[] = "$Id: uux.c,v 1.1 1993/08/04 19:37:14 jtc Exp $"; operators. */ #define ZSHELLNONREDIRSEPS ";&*| \t" -/* The program name. */ -char abProgram[] = "uux"; - /* The name of the execute file. */ const char *zXxqt_name; @@ -69,9 +66,14 @@ static int cXcmds; /* A file to close if we're forced to exit. */ static FILE *eXclose; + +/* A list of file names which will match the file names which appear + in the uucico logs. */ +static char *zXnames; /* Local functions. */ static void uxusage P((void)); +static void uxhelp P((void)); static void uxadd_xqt_line P((int bchar, const char *z1, const char *z2)); static void uxadd_send_file P((const char *zfrom, const char *zto, const char *zoptions, const char *ztemp, @@ -82,9 +84,29 @@ static void uxadd_send_file P((const char *zfrom, const char *zto, static void uxcopy_stdin P((FILE *e)); static void uxrecord_file P((const char *zfile)); static void uxabort P((void)); +static void uxadd_name P((const char *)); /* Long getopt options. */ -static const struct option asXlongopts[] = { { NULL, 0, NULL, 0 } }; +static const struct option asXlongopts[] = +{ + { "requestor", required_argument, NULL, 'a' }, + { "return-stdin", no_argument, NULL, 'b' }, + { "nocopy", no_argument, NULL, 'c' }, + { "copy", no_argument, NULL, 'C' }, + { "grade", required_argument, NULL, 'g' }, + { "jobid", no_argument, NULL, 'j' }, + { "link", no_argument, NULL, 'l' }, + { "notification", required_argument, NULL, 2 }, + { "stdin", no_argument, NULL, 'p' }, + { "nouucico", no_argument, NULL, 'r' }, + { "status", required_argument, NULL, 's' }, + { "noexpand", no_argument, NULL, 'W' }, + { "config", required_argument, NULL, 'I' }, + { "debug", required_argument, NULL, 'x' }, + { "version", no_argument, NULL, 'v' }, + { "help", no_argument, NULL, 1 }, + { NULL, 0, NULL, 0 } +}; /* The main routine. */ @@ -153,40 +175,31 @@ main (argc, argv) struct uuconf_system slocalsys; boolean fneedshell; char *zfullcmd; + char aboptions[10]; boolean fexit; + zProgram = argv[0]; + /* We need to be able to read a single - as an option, which getopt - won't do. So that we can still use getopt, we run through the - options looking for an option "-"; if we find one we change it to - "-p", which is equivalent to "-". */ - for (i = 1; i < argc; i++) + won't do. We handle this by using getopt to scan the argument + list multiple times, replacing any single "-" with "-p". */ + opterr = 0; + while (1) { - if (argv[i][0] != '-') + while (getopt_long (argc, argv, "+a:bcCg:I:jlnprs:Wvx:z", + asXlongopts, (int *) NULL) != EOF) + ; + if (optind >= argc || strcmp (argv[optind], "-") != 0) break; - if (argv[i][1] == '\0') - argv[i] = zbufcpy ("-p"); - else - { - const char *z; - - for (z = argv[i] + 1; *z != '\0'; z++) - { - /* If the option takes an argument, and the argument is - not appended, then skip the next argument. */ - if (*z == 'a' || *z == 'g' || *z == 'I' - || *z == 's' || *z == 'x') - { - if (z[1] == '\0') - i++; - break; - } - } - } + argv[optind] = zbufcpy ("-p"); + optind = 0; } + opterr = 1; + optind = 0; /* The leading + in the getopt string means to stop processing options as soon as a non-option argument is seen. */ - while ((iopt = getopt_long (argc, argv, "+a:bcCg:I:jlnprs:Wx:z", + while ((iopt = getopt_long (argc, argv, "+a:bcCg:I:jlnprs:Wvx:z", asXlongopts, (int *) NULL)) != EOF) { switch (iopt) @@ -271,6 +284,41 @@ main (argc, argv) ferror_ack = TRUE; break; + case 2: + /* --notify={true,false,error}. */ + if (*optarg == 't' + || *optarg == 'T' + || *optarg == 'y' + || *optarg == 'Y' + || *optarg == 'e' + || *optarg == 'E') + { + ferror_ack = TRUE; + fno_ack = FALSE; + } + else if (*optarg == 'f' + || *optarg == 'F' + || *optarg == 'n' + || *optarg == 'N') + { + ferror_ack = FALSE; + fno_ack = TRUE; + } + break; + + case 'v': + /* Print version and exit. */ + printf ("%s: Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", + zProgram, VERSION); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + + case 1: + /* --help. */ + uxhelp (); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + case 0: /* Long option found and flag set. */ break; @@ -444,32 +492,12 @@ main (argc, argv) iuuconf = uuconf_system_local (puuconf, &slocalsys); if (iuuconf != UUCONF_SUCCESS) ulog_uuconf (LOG_FATAL, puuconf, iuuconf); + slocalsys.uuconf_zname = (char *) zlocalname; } - /* Figure out which system the command is to be executed on. Some - mailers apparently pass local!rmail, so we must explicitly check - for that. */ + /* Figure out which system the command is to be executed on. */ + zcmd = zremove_local_sys (&slocalsys, zcmd); zexclam = strchr (zcmd, '!'); - while (zexclam != NULL) - { - *zexclam = '\0'; - if (strcmp (zcmd, zlocalname) == 0) - ; - else if (slocalsys.uuconf_pzalias == NULL) - break; - else - { - char **pzal; - - for (pzal = slocalsys.uuconf_pzalias; *pzal != NULL; pzal++) - if (strcmp (zcmd, *pzal) == 0) - break; - if (*pzal == NULL) - break; - } - zcmd = zexclam + 1; - zexclam = strchr (zcmd, '!'); - } if (zexclam == NULL) { zsys = zlocalname; @@ -478,6 +506,7 @@ main (argc, argv) } else { + *zexclam = '\0'; zsys = zcmd; zcmd = zexclam + 1; fxqtlocal = FALSE; @@ -587,6 +616,12 @@ main (argc, argv) if (zexclam == NULL && ! finput && ! foutput) continue; + if (zexclam != NULL) + { + pzargs[i] = zremove_local_sys (&slocalsys, pzargs[i]); + zexclam = strchr (pzargs[i], '!'); + } + /* Get the system name and file name for this file. */ if (zexclam == NULL) { @@ -599,22 +634,13 @@ main (argc, argv) { *zexclam = '\0'; zsystem = pzargs[i]; - if (*zsystem != '\0') - flocal = FALSE; - else - { - zsystem = zlocalname; - flocal = TRUE; - } zfile = zexclam + 1; + flocal = FALSE; zexclam = strrchr (zfile, '!'); if (zexclam == NULL) zforw = NULL; else { - if (flocal) - ulog (LOG_FATAL, "!%s: Can't figure out where to get file", - zfile); *zexclam = '\0'; zforw = zfile; zfile = zexclam + 1; @@ -653,7 +679,8 @@ main (argc, argv) /* Turn the file into an absolute path. */ if (flocal) - zfile = zsysdep_local_file_cwd (zfile, sxqtsys.uuconf_zpubdir); + zfile = zsysdep_local_file_cwd (zfile, sxqtsys.uuconf_zpubdir, + (boolean *) NULL); else if (fexpand) zfile = zsysdep_add_cwd (zfile); if (zfile == NULL) @@ -918,6 +945,7 @@ main (argc, argv) spool directory; normally such requests are rejected. This privilege is easy to abuse. */ s.bcmd = 'R'; + s.bgrade = bgrade; s.pseq = NULL; s.zfrom = zfile; s.zto = zbufcpy (abtname); @@ -1113,11 +1141,11 @@ main (argc, argv) if (eXxqt_file == NULL && zinput_from != NULL && zforward == NULL) { struct scmd s; - char aboptions[10]; char *zoptions; /* Set up an E command. */ s.bcmd = 'E'; + s.bgrade = bgrade; s.pseq = NULL; s.zuser = zuser; s.zfrom = zinput_from; @@ -1147,6 +1175,8 @@ main (argc, argv) pasXcmds = (struct scmd *) xrealloc ((pointer) pasXcmds, cXcmds * sizeof (struct scmd)); pasXcmds[cXcmds - 1] = s; + + uxadd_name (zinput_from); } else { @@ -1225,20 +1255,41 @@ main (argc, argv) ulog_system (sxqtsys.uuconf_zname); ulog_user (zuser); - ulog (LOG_NORMAL, "Queuing %s", zfullcmd); + if (zXnames == NULL) + ulog (LOG_NORMAL, "Queuing %s", zfullcmd); + else + ulog (LOG_NORMAL, "Queuing %s (%s)", zfullcmd, zXnames); ulog_close (); - if (! fuucico) + if (! fuucico + || (zcall_system == NULL && ! fcall_any)) fexit = TRUE; else { - if (zcall_system != NULL) - fexit = fsysdep_run ("uucico", "-s", zcall_system); - else if (fcall_any) - fexit = fsysdep_run ("uucico", "-r1", (const char *) NULL); + const char *zcicoarg; + char *zconfigarg; + + if (zcall_system == NULL) + zcicoarg = "-r1"; + else + { + char *z; + + z = zbufalc (sizeof "-Cs" + strlen (zcall_system)); + sprintf (z, "-Cs%s", zcall_system); + zcicoarg = z; + } + + if (zconfig == NULL) + zconfigarg = NULL; else - fexit = TRUE; + { + zconfigarg = zbufalc (sizeof "-I" + strlen (zconfig)); + sprintf (zconfigarg, "-I%s", zconfig); + } + + fexit = fsysdep_run (FALSE, "uucico", zcicoarg, zconfigarg); } usysdep_exit (fexit); @@ -1250,43 +1301,37 @@ main (argc, argv) /* Report command usage. */ static void -uxusage () +uxhelp () { - fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", - VERSION); - fprintf (stderr, - "Usage: uux [options] [-] command\n"); - fprintf (stderr, - " -,-p: Read standard input for standard input of command\n"); - fprintf (stderr, - " -c: Do not copy local files to spool directory (default)\n"); - fprintf (stderr, - " -C: Copy local files to spool directory\n"); - fprintf (stderr, - " -l: link local files to spool directory\n"); - fprintf (stderr, - " -g grade: Set job grade (must be alphabetic)\n"); - fprintf (stderr, - " -n: Do not report completion status\n"); - fprintf (stderr, - " -z: Report completion status only on error\n"); - fprintf (stderr, - " -r: Do not start uucico daemon\n"); - fprintf (stderr, - " -a address: Address to mail status report to\n"); - fprintf (stderr, - " -b: Return standard input with status report\n"); - fprintf (stderr, - " -s file: Report completion status to file\n"); - fprintf (stderr, - " -j: Report job id\n"); - fprintf (stderr, - " -x debug: Set debugging level\n"); + printf ("Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", + VERSION); + printf ("Usage: %s [options] [-] command\n", zProgram); + printf (" -,-p,--stdin: Read standard input for standard input of command\n"); + printf (" -c,--nocopy: Do not copy local files to spool directory (default)\n"); + printf (" -C,--copy: Copy local files to spool directory\n"); + printf (" -l,--link: link local files to spool directory\n"); + printf (" -g,--grade grade: Set job grade (must be alphabetic)\n"); + printf (" -n,--notification=no: Do not report completion status\n"); + printf (" -z,--notification=error: Report completion status only on error\n"); + printf (" -r,--nouucico: Do not start uucico daemon\n"); + printf (" -a,--requestor address: Address to mail status report to\n"); + printf (" -b,--return-stdin: Return standard input with status report\n"); + printf (" -s,--status file: Report completion status to file\n"); + printf (" -j,--jobid: Report job id\n"); + printf (" -x,--debug debug: Set debugging level\n"); #if HAVE_TAYLOR_CONFIG - fprintf (stderr, - " -I file: Set configuration file to use\n"); + printf (" -I,--config file: Set configuration file to use\n"); #endif /* HAVE_TAYLOR_CONFIG */ + printf (" -v,--version: Print version and exit\n"); + printf (" --help: Print help and exit\n"); +} + +static void +uxusage () +{ + fprintf (stderr, + "Usage: %s [options] [-] command\n", zProgram); + fprintf (stderr, "Use %s --help for help\n", zProgram); exit (EXIT_FAILURE); } @@ -1366,6 +1411,7 @@ uxadd_send_file (zfrom, zto, zoptions, ztemp, zforward, qxqtsys, zxqtloc, /* Send the execution file. */ s.bcmd = 'S'; + s.bgrade = bgrade; s.pseq = NULL; s.zfrom = zbufcpy (abtname); s.zto = zbufcpy (abxname); @@ -1383,12 +1429,15 @@ uxadd_send_file (zfrom, zto, zoptions, ztemp, zforward, qxqtsys, zxqtloc, cXcmds * sizeof (struct scmd)); pasXcmds[cXcmds - 1] = s; + uxadd_name (abtname); + /* Send the data file to abdname where the execution file will expect it. */ zto = abdname; } s.bcmd = 'S'; + s.bgrade = bgrade; s.pseq = NULL; s.zfrom = zbufcpy (zfrom); s.zto = zbufcpy (zto); @@ -1405,6 +1454,8 @@ uxadd_send_file (zfrom, zto, zoptions, ztemp, zforward, qxqtsys, zxqtloc, pasXcmds = (struct scmd *) xrealloc ((pointer) pasXcmds, cXcmds * sizeof (struct scmd)); pasXcmds[cXcmds - 1] = s; + + uxadd_name (zfrom); } /* Copy stdin to a file. This is a separate function because it may @@ -1500,3 +1551,31 @@ uxabort () ulog_close (); usysdep_exit (FALSE); } + +/* Add a name to the list of file names we are going to log. We log + all the file names which will appear in the uucico log file. This + permits people to associate the file send in the uucico log with + the uux entry which created the file. Normally only one file name + will appear. */ + +static void +uxadd_name (z) + const char *z; +{ + if (zXnames == NULL) + zXnames = zbufcpy (z); + else + { + size_t cold, cadd; + char *znew; + + cold = strlen (zXnames); + cadd = strlen (z); + znew = zbufalc (cold + 2 + cadd); + memcpy (znew, zXnames, cold); + znew[cold] = ' '; + memcpy (znew + cold + 1, z, cadd + 1); + ubuffree (zXnames); + zXnames = znew; + } +} diff --git a/gnu/libexec/uucp/uuxqt/Makefile b/gnu/libexec/uucp/uuxqt/Makefile index ded44bfad85..949c19c1b10 100644 --- a/gnu/libexec/uucp/uuxqt/Makefile +++ b/gnu/libexec/uucp/uuxqt/Makefile @@ -1,5 +1,5 @@ # Makefile for uuxqt -# $Id: Makefile,v 1.2 1993/08/05 16:15:28 jtc Exp $ +# $Id: Makefile,v 1.3 1994/10/24 22:30:26 jtc Exp $ BINDIR= $(sbindir) BINOWN= $(owner) @@ -9,7 +9,8 @@ PROG= uuxqt SRCS= uuxqt.c util.c log.c copy.c LDADD+= $(LIBUNIX) $(LIBUUCONF) $(LIBUUCP) DPADD+= $(LIBUNIX) $(LIBUUCONF) $(LIBUUCP) -CFLAGS+= -I$(.CURDIR)/../common_sources\ +CFLAGS+= -I$(.CURDIR)/../common_sources \ + -DOWNER=\"$(owner)\" \ -DVERSION=\"$(VERSION)\" MAN8= uuxqt.0 diff --git a/gnu/libexec/uucp/uuxqt/uuxqt.8 b/gnu/libexec/uucp/uuxqt/uuxqt.8 index faee1cf7a81..589a25a12ad 100644 --- a/gnu/libexec/uucp/uuxqt/uuxqt.8 +++ b/gnu/libexec/uucp/uuxqt/uuxqt.8 @@ -1,5 +1,5 @@ -''' $Id: uuxqt.8,v 1.1 1993/08/04 19:37:18 jtc Exp $ -.TH uuxqt 8 "Taylor UUCP 1.04" +''' $Id: uuxqt.8,v 1.2 1994/10/24 22:30:32 jtc Exp $ +.TH uuxqt 8 "Taylor UUCP 1.05" .SH NAME uuxqt \- UUCP execution daemon .SH SYNOPSIS @@ -17,6 +17,8 @@ It is started automatically by the .I uucico (8) is given the .B \-q +or +.B \-\-nouuxqt option). There is normally no need to run this command, since it will be @@ -34,16 +36,19 @@ configuration command. The following options may be given to .I uuxqt. .TP 5 -.B \-c command +.B \-c command, \-\-command command Only execute requests for the specified command. For example: -.EX -uuxqt -c rmail -.EE +.br +.in +0.5i +.nf +uuxqt --command rmail +.fi +.in -0.5i .TP 5 -.B \-s system +.B \-s system, \-\-system system Only execute requests originating from the specified system. .TP 5 -.B \-x type +.B \-x type, \-\-debug type Turn on particular debugging types. The following types are recognized: abnormal, chat, handshake, uucp-proto, proto, port, config, spooldir, execute, incoming, outgoing. Only abnormal, config, @@ -51,22 +56,28 @@ spooldir and execute are meaningful for .I uuxqt. Multiple types may be given, separated by commas, and the -.B \-x +.B \-\-debug option may appear multiple times. A number may also be given, which will turn on that many types from the foregoing list; for example, -.B \-x 2 +.B \-\-debug 2 is equivalent to -.B \-x abnormal,chat. +.B \-\-debug abnormal,chat. The debugging output is sent to the debugging file, usually one of /usr/spool/uucp/Debug, /usr/spool/uucp/DEBUG, or /usr/spool/uucp/.Admin/audit.local. .TP 5 -.B \-I file +.B \-I file, \-\-config Set configuration file to use. This option may not be available, depending upon how .I uuxqt was compiled. +.TP 5 +.B \-v, \-\-version +Report version information and exit. +.TP 5 +.B \-\-help +Print a help message and exit. .SH FILES The file names may be changed at compilation time or by the configuration file, so these are only approximations. @@ -89,4 +100,4 @@ Debugging file. uucp(1), uux(1), uucico(8) .SH AUTHOR Ian Lance Taylor -(ian@airs.com or uunet!airs!ian) +(ian@airs.com) diff --git a/gnu/libexec/uucp/uuxqt/uuxqt.c b/gnu/libexec/uucp/uuxqt/uuxqt.c index 919ea7ecd4e..fb3254fdbe0 100644 --- a/gnu/libexec/uucp/uuxqt/uuxqt.c +++ b/gnu/libexec/uucp/uuxqt/uuxqt.c @@ -1,7 +1,7 @@ /* uuxqt.c Run uux commands. - Copyright (C) 1991, 1992 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -20,13 +20,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or - c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254. + c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. */ #include "uucp.h" #if USE_RCS_ID -const char uuxqt_rcsid[] = "$Id: uuxqt.c,v 1.1 1993/08/04 19:37:19 jtc Exp $"; +const char uuxqt_rcsid[] = "$Id: uuxqt.c,v 1.2 1994/10/24 22:30:37 jtc Exp $"; #endif #include <errno.h> @@ -38,9 +38,6 @@ const char uuxqt_rcsid[] = "$Id: uuxqt.c,v 1.1 1993/08/04 19:37:19 jtc Exp $"; #include "uuconf.h" #include "system.h" -/* The program name. */ -char abProgram[] = "uuxqt"; - /* Static variables used to unlock things if we get a fatal error. */ static int iQlock_seq = -1; static const char *zQunlock_cmd; @@ -54,6 +51,7 @@ static char *zQmail; /* Local functions. */ static void uqusage P((void)); +static void uqhelp P((void)); static void uqabort P((void)); static void uqdo_xqt_file P((pointer puuconf, const char *zfile, const char *zbase, @@ -65,7 +63,16 @@ static boolean fqforward P((const char *zfile, char **pzallowed, const char *zlog, const char *zmail)); /* Long getopt options. */ -static const struct option asQlongopts[] = { { NULL, 0, NULL, 0 } }; +static const struct option asQlongopts[] = +{ + { "command", required_argument, 0, 'c' }, + { "system", required_argument, 0, 's' }, + { "config", required_argument, NULL, 'I' }, + { "debug", required_argument, NULL, 'x' }, + { "version", no_argument, NULL, 'v' }, + { "help", no_argument, NULL, 1 }, + { NULL, 0, NULL, 0 } +}; int main (argc, argv) @@ -88,7 +95,9 @@ main (argc, argv) boolean fsys; struct uuconf_system ssys; - while ((iopt = getopt_long (argc, argv, "c:I:s:x:", asQlongopts, + zProgram = argv[0]; + + while ((iopt = getopt_long (argc, argv, "c:I:s:vx:", asQlongopts, (int *) NULL)) != EOF) { switch (iopt) @@ -115,6 +124,19 @@ main (argc, argv) #endif break; + case 'v': + /* Print version and exit. */ + printf ("%s: Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", + zProgram, VERSION); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + + case 1: + /* --help. */ + uqhelp (); + exit (EXIT_SUCCESS); + /*NOTREACHED*/ + case 0: /* Long option found and flag set. */ break; @@ -181,15 +203,28 @@ main (argc, argv) fsys = FALSE; - /* If we were given a system name, canonicalize it, since the system - dependent layer will not be returning aliases. */ + /* If we were given a system name, canonicalize it. */ if (zdosys != NULL) { iuuconf = uuconf_system_info (puuconf, zdosys, &ssys); - if (iuuconf == UUCONF_NOT_FOUND) - ulog (LOG_FATAL, "%s: System not found", zdosys); - else if (iuuconf != UUCONF_SUCCESS) - ulog_uuconf (LOG_FATAL, puuconf, iuuconf); + if (iuuconf != UUCONF_SUCCESS) + { + if (iuuconf != UUCONF_NOT_FOUND) + ulog_uuconf (LOG_FATAL, puuconf, iuuconf); + + if (strcmp (zdosys, zlocalname) == 0) + { + iuuconf = uuconf_system_local (puuconf, &ssys); + if (iuuconf != UUCONF_SUCCESS) + ulog_uuconf (LOG_FATAL, puuconf, iuuconf); + ssys.uuconf_zname = (char *) zlocalname; + } + else + { + if (! funknown_system (puuconf, zdosys, &ssys)) + ulog (LOG_FATAL, "%s: system not found", zdosys); + } + } zdosys = zbufcpy (ssys.uuconf_zname); fsys = TRUE; @@ -225,15 +260,8 @@ main (argc, argv) boolean fprocessed; char *zbase; - /* It would be more efficient to pass zdosys down to the - routines which retrieve execute files. */ - if (zdosys != NULL && strcmp (zdosys, zgetsys) != 0) - { - ubuffree (z); - ubuffree (zgetsys); - continue; - } - + /* Get the system information for the system returned by + zsysdep_get_xqt. */ if (! fsys || strcmp (ssys.uuconf_zname, zgetsys) != 0) { if (fsys) @@ -260,6 +288,7 @@ main (argc, argv) ubuffree (zgetsys); continue; } + ssys.uuconf_zname = (char *) zlocalname; } else { @@ -287,6 +316,15 @@ main (argc, argv) break; } + /* Make sure we are supposed to be executing jobs for this + system. */ + if (zdosys != NULL && strcmp (zdosys, ssys.uuconf_zname) != 0) + { + ubuffree (z); + ubuffree (zgetsys); + continue; + } + zloc = ssys.uuconf_zlocalname; if (zloc == NULL) zloc = zlocalname; @@ -323,23 +361,27 @@ main (argc, argv) } static void -uqusage () +uqhelp () { - fprintf (stderr, - "Taylor UUCP version %s, copyright (C) 1991, 1992 Ian Lance Taylor\n", + printf ("Taylor UUCP %s, copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor\n", VERSION); - fprintf (stderr, - "Usage: uuxqt [-c cmd] [-I file] [-s system] [-x debug]\n"); - fprintf (stderr, - " -c cmd: Set type of command to execute\n"); - fprintf (stderr, - " -s system: Execute commands only for named system\n"); - fprintf (stderr, - " -x debug: Set debugging level (0 for none, 9 is max)\n"); + printf ("Usage: %s [-c,--command cmd] [-s,--system system]\n", zProgram); + printf (" -c,--command cmd: Set type of command to execute\n"); + printf (" -s,--system system: Execute commands only for named system\n"); + printf (" -x,--debug debug: Set debugging level\n"); #if HAVE_TAYLOR_CONFIG - fprintf (stderr, - " -I file: Set configuration file to use\n"); + printf (" -I,--config file: Set configuration file to use\n"); #endif /* HAVE_TAYLOR_CONFIG */ + printf (" -v,--version: Print version and exit\n"); + printf (" --help: Print help and exit\n"); +} + +static void +uqusage () +{ + fprintf (stderr, + "Usage: %s [-c,--command cmd] [-s,--system system]\n", zProgram); + fprintf (stderr, "Use %s --help for help\n", zProgram); exit (EXIT_FAILURE); } @@ -449,23 +491,25 @@ static int iquser P((pointer puuconf, int argc, char **argv, pointer pvar, static int iqset P((pointer puuconf, int argc, char **argv, pointer pvar, pointer pinfo)); +/* We are lax about the number of arguments the functions accept, + because there is a lot of variation in what other (buggy) UUCP + packages generate. Unused arguments are ignored. */ + static const struct uuconf_cmdtab asQcmds[] = { { "C", UUCONF_CMDTABTYPE_FN | 0, NULL, iqcmd }, { "I", UUCONF_CMDTABTYPE_STRING, (pointer) &zQinput, NULL }, { "O", UUCONF_CMDTABTYPE_FN | 0, NULL, iqout }, { "F", UUCONF_CMDTABTYPE_FN | 0, NULL, iqfile }, - { "R", UUCONF_CMDTABTYPE_FN, NULL, iqrequestor }, - { "U", UUCONF_CMDTABTYPE_FN | 3, NULL, iquser }, - { "N", UUCONF_CMDTABTYPE_FN | 1, (pointer) &fQno_ack, iqset }, - { "n", UUCONF_CMDTABTYPE_FN | 1, (pointer) &fQsuccess_ack, iqset }, - /* Some systems create execution files in which B takes an argument; - I don't know what it means, so I just ignore it. */ + { "R", UUCONF_CMDTABTYPE_FN | 0, NULL, iqrequestor }, + { "U", UUCONF_CMDTABTYPE_FN | 0, NULL, iquser }, + { "N", UUCONF_CMDTABTYPE_FN | 0, (pointer) &fQno_ack, iqset }, + { "n", UUCONF_CMDTABTYPE_FN | 0, (pointer) &fQsuccess_ack, iqset }, { "B", UUCONF_CMDTABTYPE_FN | 0, (pointer) &fQsend_input, iqset }, #if ALLOW_SH_EXECUTION - { "e", UUCONF_CMDTABTYPE_FN | 1, (pointer) &fQuse_sh, iqset }, + { "e", UUCONF_CMDTABTYPE_FN | 0, (pointer) &fQuse_sh, iqset }, #endif - { "E", UUCONF_CMDTABTYPE_FN | 1, (pointer) &fQuse_exec, iqset }, + { "E", UUCONF_CMDTABTYPE_FN | 0, (pointer) &fQuse_exec, iqset }, { "M", UUCONF_CMDTABTYPE_STRING, (pointer) &zQstatus_file, NULL }, { NULL, 0, NULL, NULL } }; @@ -519,17 +563,9 @@ iqout (puuconf, argc, argv, pvar, pinfo) pointer pvar; pointer pinfo; { - const char *zbase = (const char *) pinfo; - - if (argc != 2 && argc != 3) - { - ulog (LOG_ERROR, "%s: %s: Wrong number of arguments", - zbase, argv[0]); - return UUCONF_CMDTABRET_CONTINUE; - } - - zQoutfile = zbufcpy (argv[1]); - if (argc == 3) + if (argc > 1) + zQoutfile = zbufcpy (argv[1]); + if (argc > 2) zQoutsys = zbufcpy (argv[2]); return UUCONF_CMDTABRET_CONTINUE; @@ -546,14 +582,8 @@ iqfile (puuconf, argc, argv, pvar, pinfo) pointer pvar; pointer pinfo; { - const char *zbase = (const char *) pinfo; - - if (argc != 2 && argc != 3) - { - ulog (LOG_ERROR, "%s: %s: Wrong number of arguments", - zbase, argv[0]); - return UUCONF_CMDTABRET_CONTINUE; - } + if (argc < 2) + return UUCONF_CMDTABRET_CONTINUE; /* If this file is not in the spool directory, just ignore it. */ if (! fspool_file (argv[1])) @@ -566,7 +596,7 @@ iqfile (puuconf, argc, argv, pvar, pinfo) cQfiles * sizeof (char *)); azQfiles[cQfiles - 1] = zbufcpy (argv[1]); - if (argc == 3) + if (argc > 2) azQfiles_to[cQfiles - 1] = zbufcpy (argv[2]); else azQfiles_to[cQfiles - 1] = NULL; @@ -585,22 +615,13 @@ iqrequestor (puuconf, argc, argv, pvar, pinfo) pointer pvar; pointer pinfo; { - const char *zbase = (const char *) pinfo; - - if (argc != 2 && argc != 3) - { - ulog (LOG_ERROR, "%s: %s: Wrong number of arguments", - zbase, argv[0]); - return UUCONF_CMDTABRET_CONTINUE; - } - /* We normally have a single argument, which is the ``requestor'' address, to which we should send any success or error messages. Apparently the DOS program UUPC sends two arguments, which are the username and the host. */ if (argc == 2) zQrequestor = zbufcpy (argv[1]); - else + else if (argc > 2) { zQrequestor = zbufalc (strlen (argv[1]) + strlen (argv[2]) + sizeof "!"); @@ -621,8 +642,10 @@ iquser (puuconf, argc, argv, pvar, pinfo) pointer pvar; pointer pinfo; { - zQuser = argv[1]; - zQsystem = argv[2]; + if (argc > 1) + zQuser = argv[1]; + if (argc > 2) + zQsystem = argv[2]; return UUCONF_CMDTABRET_KEEP; } @@ -680,6 +703,7 @@ uqdo_xqt_file (puuconf, zfile, zbase, qsys, zlocalname, zcmd, pfprocessed) const char *zmail; char *zoutput; char *zinput; + boolean fbadname; char abtemp[CFILE_NAME_LEN]; char abdata[CFILE_NAME_LEN]; char *zerror; @@ -724,6 +748,40 @@ uqdo_xqt_file (puuconf, zfile, zbase, qsys, zlocalname, zcmd, pfprocessed) if (iuuconf != UUCONF_SUCCESS) { ulog_uuconf (LOG_ERROR, puuconf, iuuconf); + + /* If we got a non-transient error, we notify the administrator. + We can't bounce it back to the original requestor, because we + don't know how to read the file to figure out who it is (it + would probably be possible to read the file and work it out, + but it doesn't seem worth it for such an unlikely error). */ + if (UUCONF_ERROR_VALUE (iuuconf) == UUCONF_SYNTAX_ERROR + || UUCONF_ERROR_VALUE (iuuconf) == UUCONF_UNKNOWN_COMMAND) + { + const char *az[20]; + char *znew; + + i = 0; + az[i++] = "The execution file\n\t"; + az[i++] = zfile; + az[i++] = "\nfor system\n\t"; + az[i++] = qsys->uuconf_zname; + az[i++] = "\nwas corrupt. "; + znew = zsysdep_save_corrupt_file (zfile); + if (znew == NULL) + { + az[i++] = "The file could not be preserved.\n"; + (void) remove (zfile); + } + else + { + az[i++] = "It has been moved to\n\t"; + az[i++] = znew; + az[i++] = "\n"; + } + (void) fsysdep_mail (OWNER, "Corrupt execution file", i, az); + ubuffree (znew); + } + return; } @@ -780,6 +838,16 @@ uqdo_xqt_file (puuconf, zfile, zbase, qsys, zlocalname, zcmd, pfprocessed) else ulog_user ("unknown"); + /* zQsystem, if it is set, comes from the execution file, which + means that we do not trust it. We only retain it if + qsys->uuconf_zname is a prefix of it, since that can happen with + a job from an anonymous system on certain spool directory types, + and is unlikely to cause any trouble anyhow. */ + if (zQsystem == NULL + || strncmp (zQsystem, qsys->uuconf_zname, + strlen (qsys->uuconf_zname)) != 0) + zQsystem = qsys->uuconf_zname; + /* Make sure that all the required files exist, and get their full names in the spool directory. */ for (i = 0; i < cQfiles; i++) @@ -823,7 +891,6 @@ uqdo_xqt_file (puuconf, zfile, zbase, qsys, zlocalname, zcmd, pfprocessed) else if (zQuser != NULL) zmail = zQuser; if (zmail != NULL - && zQsystem != NULL #if HAVE_INTERNET_MAIL && strchr (zmail, '@') == NULL #endif @@ -846,7 +913,7 @@ uqdo_xqt_file (puuconf, zfile, zbase, qsys, zlocalname, zcmd, pfprocessed) char *zfrom, *zto; boolean fmany; char **azargs; - const char *zuser, *zsystem; + const char *zuser; zfrom = NULL; zto = NULL; @@ -904,12 +971,9 @@ uqdo_xqt_file (puuconf, zfile, zbase, qsys, zlocalname, zcmd, pfprocessed) zuser = zQuser; if (zuser == NULL) zuser = "uucp"; - zsystem = zQsystem; - if (zsystem == NULL) - zsystem = qsys->uuconf_zname; - azargs[1] = zbufalc (strlen (zsystem) + strlen (zuser) + azargs[1] = zbufalc (strlen (zQsystem) + strlen (zuser) + sizeof "-u!"); - sprintf (azargs[1], "-u%s!%s", zsystem, zuser); + sprintf (azargs[1], "-u%s!%s", zQsystem, zuser); memcpy (azargs + 2, azQargs + 1, i * sizeof (char *)); xfree ((pointer) azQargs); azQargs = azargs; @@ -1067,11 +1131,14 @@ uqdo_xqt_file (puuconf, zfile, zbase, qsys, zlocalname, zcmd, pfprocessed) char *zreal; fspool = fspool_file (zQinput); - if (fspool) - zreal = zsysdep_spool_file_name (qsys, zQinput, (pointer) NULL); + if (! fspool) + zreal = zsysdep_local_file (zQinput, qsys->uuconf_zpubdir, &fbadname); else - zreal = zsysdep_local_file (zQinput, qsys->uuconf_zpubdir); - if (zreal == NULL) + { + zreal = zsysdep_spool_file_name (qsys, zQinput, (pointer) NULL); + fbadname = FALSE; + } + if (zreal == NULL && ! fbadname) { /* If we get an error, try again later. */ uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); @@ -1079,13 +1146,17 @@ uqdo_xqt_file (puuconf, zfile, zbase, qsys, zlocalname, zcmd, pfprocessed) return; } - zQinput = zreal; - iclean |= FREE_QINPUT; + if (zreal != NULL) + { + zQinput = zreal; + iclean |= FREE_QINPUT; + } - if (! fspool - && ! fin_directory_list (zQinput, qsys->uuconf_pzremote_send, - qsys->uuconf_zpubdir, TRUE, TRUE, - (const char *) NULL)) + if (zreal == NULL + || (! fspool + && ! fin_directory_list (zQinput, qsys->uuconf_pzremote_send, + qsys->uuconf_zpubdir, TRUE, TRUE, + (const char *) NULL))) { ulog (LOG_ERROR, "Not permitted to read %s", zQinput); @@ -1176,22 +1247,30 @@ uqdo_xqt_file (puuconf, zfile, zbase, qsys, zlocalname, zcmd, pfprocessed) fok = FALSE; else { - zoutput = zsysdep_local_file (zQoutfile, qsys->uuconf_zpubdir); + zoutput = zsysdep_local_file (zQoutfile, qsys->uuconf_zpubdir, + &fbadname); if (zoutput == NULL) { - /* If we get an error, try again later. */ - uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); - *pfprocessed = FALSE; - return; + if (! fbadname) + { + /* If we get an error, try again later. */ + uqcleanup (zfile, iclean &~ (REMOVE_FILE | REMOVE_NEEDED)); + *pfprocessed = FALSE; + return; + } + fok = FALSE; + } + else + { + ubuffree (zQoutfile); + zQoutfile = zoutput; + + /* Make sure it's OK to receive this file. */ + fok = fin_directory_list (zQoutfile, + qsys->uuconf_pzremote_receive, + qsys->uuconf_zpubdir, TRUE, FALSE, + (const char *) NULL); } - ubuffree (zQoutfile); - zQoutfile = zoutput; - - /* Make sure it's OK to receive this file. */ - fok = fin_directory_list (zQoutfile, - qsys->uuconf_pzremote_receive, - qsys->uuconf_zpubdir, TRUE, FALSE, - (const char *) NULL); } if (! fok) @@ -1369,6 +1448,7 @@ uqdo_xqt_file (puuconf, zfile, zbase, qsys, zlocalname, zcmd, pfprocessed) /* Fill in the command structure. */ s.bcmd = 'S'; + s.bgrade = BDEFAULT_UUX_GRADE; s.pseq = NULL; s.zfrom = abtemp; s.zto = zQoutfile; |
