diff options
Diffstat (limited to 'gnu/libexec/uucp/libunix')
54 files changed, 2240 insertions, 479 deletions
diff --git a/gnu/libexec/uucp/libunix/MANIFEST b/gnu/libexec/uucp/libunix/MANIFEST index c57f466..342650a 100644 --- a/gnu/libexec/uucp/libunix/MANIFEST +++ b/gnu/libexec/uucp/libunix/MANIFEST @@ -17,6 +17,7 @@ dup2.c efopen.c epopen.c exists.c +failed.c filnam.c fsusg.c fsusg.h @@ -64,11 +65,15 @@ srmdir.c statsb.c status.c strerr.c +sync.c +tcp.c time.c +tli.c tmpfil.c trunc.c uacces.c ufopen.c +uid.c ultspl.c unknwn.c uuto.c diff --git a/gnu/libexec/uucp/libunix/Makefile b/gnu/libexec/uucp/libunix/Makefile index a13b685..f4cc4a6 100644 --- a/gnu/libexec/uucp/libunix/Makefile +++ b/gnu/libexec/uucp/libunix/Makefile @@ -1,17 +1,17 @@ # This subdirectory contains Unix specific support functions. -# $Id: Makefile,v 1.2 1994/05/07 18:10:03 ache Exp $ +# $Id: Makefile,v 1.3 1995/05/13 12:57:23 ache Exp $ LIB= unix SRCS = access.c addbas.c app3.c app4.c basnam.c bytfre.c corrup.c \ chmod.c cohtty.c cusub.c cwd.c detach.c efopen.c epopen.c \ - exists.c filnam.c fsusg.c indir.c init.c isdir.c isfork.c \ - iswait.c jobid.c lcksys.c link.c locfil.c lock.c loctim.c \ - mail.c mkdirs.c mode.c move.c opensr.c pause.c picksb.c pipe.c \ - portnm.c priv.c proctm.c recep.c run.c seq.c serial.c signal.c \ - sindir.c size.c sleep.c spawn.c splcmd.c splnam.c spool.c \ - srmdir.c statsb.c status.c time.c tmpfil.c trunc.c uacces.c \ - ufopen.c ultspl.c unknwn.c uuto.c walk.c wldcrd.c work.c \ - xqtfil.c xqtsub.c ftw.c + exists.c failed.c filnam.c fsusg.c indir.c init.c isdir.c \ + isfork.c iswait.c jobid.c lcksys.c link.c locfil.c lock.c \ + loctim.c mail.c mkdirs.c mode.c move.c opensr.c pause.c \ + picksb.c pipe.c portnm.c priv.c proctm.c recep.c run.c seq.c \ + serial.c signal.c sindir.c size.c sleep.c spawn.c splcmd.c \ + splnam.c spool.c srmdir.c statsb.c status.c sync.c tcp.c \ + time.c tli.c tmpfil.c trunc.c uacces.c ufopen.c uid.c ultspl.c \ + unknwn.c uuto.c walk.c wldcrd.c work.c xqtfil.c xqtsub.c ftw.c CFLAGS+= -I$(.CURDIR)/../common_sources \ -DOWNER=\"$(owner)\" -DSBINDIR=\"$(libxdir)\" diff --git a/gnu/libexec/uucp/libunix/bytfre.c b/gnu/libexec/uucp/libunix/bytfre.c index 568eebe..3091e7a 100644 --- a/gnu/libexec/uucp/libunix/bytfre.c +++ b/gnu/libexec/uucp/libunix/bytfre.c @@ -7,6 +7,12 @@ #include "sysdep.h" #include "fsusg.h" +#if HAVE_LIMITS_H +#include <limits.h> +#else +#define LONG_MAX 2147483647 +#endif + long csysdep_bytes_free (zfile) const char *zfile; @@ -15,5 +21,7 @@ csysdep_bytes_free (zfile) if (get_fs_usage ((char *) zfile, (char *) NULL, &s) < 0) return -1; + if (s.fsu_bavail >= LONG_MAX / (long) 512) + return LONG_MAX; return s.fsu_bavail * (long) 512; } diff --git a/gnu/libexec/uucp/libunix/cohtty.c b/gnu/libexec/uucp/libunix/cohtty.c index 5db3fe7..5a52df9 100644 --- a/gnu/libexec/uucp/libunix/cohtty.c +++ b/gnu/libexec/uucp/libunix/cohtty.c @@ -3,7 +3,7 @@ lightly edited by Ian Lance Taylor. */ /* The bottom part of this file is lock.c. - * This is a hacked lock.c. A full lock.c can be found in the libmisc sources + * This is a hacked lock.c. A full lock.c can be found in the libmisc sources * under /usr/src/misc.tar.Z. * * These are for checking for the existence of locks: @@ -146,7 +146,7 @@ char enable_device[16]; /* this will hold our device name return TRUE; }else{ /* device not enabled */ - return TRUE; + return TRUE; } } } @@ -192,7 +192,7 @@ char *buff; { struct stat sbuf; int status; - + if (0 != (status = stat(path, &sbuf))) { /* Can't stat the file. */ return (NULL); diff --git a/gnu/libexec/uucp/libunix/cusub.c b/gnu/libexec/uucp/libunix/cusub.c index 3486c71..b1bce90 100644 --- a/gnu/libexec/uucp/libunix/cusub.c +++ b/gnu/libexec/uucp/libunix/cusub.c @@ -1,7 +1,7 @@ /* cusub.c System dependent routines for cu. - Copyright (C) 1992, 1993 Ian Lance Taylor + Copyright (C) 1992, 1993, 1995 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -17,16 +17,16 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" #if USE_RCS_ID -const char cusub_rcsid[] = "$Id: cusub.c,v 1.2 1994/05/07 18:10:14 ache Exp $"; +const char cusub_rcsid[] = "$Id: cusub.c,v 1.24 1995/06/21 19:18:53 ian Rel $"; #endif #include "uudefs.h" @@ -330,7 +330,7 @@ fsysdep_cu (qconn, pbcmd, zlocalname) if (c <= 0) break; - if (fstart && b == *zCuvar_escape) + if (fstart && b == *zCuvar_escape && b != '\0') { c = cscu_escape (pbcmd, zlocalname); if (c <= 0) @@ -410,7 +410,7 @@ cscu_escape (pbcmd, zlocalname) usysdep_start_catch (); alarm (1); } - + c = 0; while (TRUE) @@ -426,7 +426,7 @@ cscu_escape (pbcmd, zlocalname) b = ']'; write (1, &b, 1); } - + if (c <= 0) c = read (0, pbcmd, 1); if (c >= 0 || errno != EINTR) @@ -437,7 +437,7 @@ cscu_escape (pbcmd, zlocalname) return c; } } -} +} /* A SIGALRM handler which does nothing but send a signal to the child process and schedule another alarm. POSIX.1 permits kill and alarm @@ -715,7 +715,7 @@ uscu_child (qconn, opipe) cwrite -= c; zbuf += c; } - } + } else { /* On some systems apparently read will return 0 until @@ -788,7 +788,7 @@ fsysdep_terminal_raw (flocalecho) } fSterm = TRUE; - + sSterm_new = sSterm_orig; #if HAVE_BSD_TTY @@ -1114,7 +1114,14 @@ fsysdep_shell (qconn, zcmd, tcmd) int aidescs[3]; pid_t ipid; - azargs[0] = "/bin/sh"; + if (tcmd != SHELL_NORMAL) + azargs[0] = "/bin/sh"; + else + { + azargs[0] = getenv ("SHELL"); + if (azargs[0] == NULL) + azargs[0] = "/bin/sh"; + } if (zcmd == NULL || *zcmd == '\0') azargs[1] = NULL; else @@ -1158,7 +1165,7 @@ fsysdep_shell (qconn, zcmd, tcmd) aidescs[0] = oread; if (tcmd == SHELL_STDOUT_TO_PORT || tcmd == SHELL_STDIO_ON_PORT) aidescs[1] = owrite; - + ipid = ixsspawn (azargs, aidescs, FALSE, TRUE, (const char *) NULL, FALSE, FALSE, (const char *) NULL, (const char *) NULL, (const char *) NULL); diff --git a/gnu/libexec/uucp/libunix/cwd.c b/gnu/libexec/uucp/libunix/cwd.c index 486105a..71d05d1 100644 --- a/gnu/libexec/uucp/libunix/cwd.c +++ b/gnu/libexec/uucp/libunix/cwd.c @@ -37,7 +37,7 @@ zsysdep_local_file_cwd (zfile, zpubdir, pfbadname) return zsysdep_local_file (zfile, zpubdir, pfbadname); else return zsysdep_add_cwd (zfile); -} +} /* Add the current working directory to a remote file name. */ diff --git a/gnu/libexec/uucp/libunix/detach.c b/gnu/libexec/uucp/libunix/detach.c index 3a21b8a..88becf1 100644 --- a/gnu/libexec/uucp/libunix/detach.c +++ b/gnu/libexec/uucp/libunix/detach.c @@ -1,7 +1,7 @@ /* detach.c Detach from the controlling terminal. - Copyright (C) 1992, 1993 Ian Lance Taylor + Copyright (C) 1992, 1993, 1995 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -38,7 +38,7 @@ #ifdef TIOCNOTTY #define HAVE_TIOCNOTTY 1 #else -#define HAVE_TIOCNOTTY 0 +#define HAVE_TIOCNOTTY 0 #endif #if HAVE_FCNTL_H @@ -71,6 +71,11 @@ usysdep_detach () { pid_t igrp; + /* Make sure that we can open the log file. We do this now so that, + if we can't, a message will be written to stderr. After we leave + this routine, stderr will be closed. */ + ulog (LOG_NORMAL, (const char *) NULL); + /* Make sure we are not a process group leader. */ #if HAVE_BSD_PGRP igrp = getpgrp (0); @@ -107,17 +112,24 @@ usysdep_detach () if (! fignored) usset_signal (SIGHUP, ussignal, TRUE, (boolean *) NULL); - DEBUG_MESSAGE2 (DEBUG_PORT, "Forked; old PID %ld, new pid %ld", + DEBUG_MESSAGE2 (DEBUG_PORT, + "usysdep_detach: Forked; old PID %ld, new pid %ld", (long) igrp, (long) ipid); } #if ! HAVE_SETSID && HAVE_TIOCNOTTY /* Lose the original controlling terminal as well as our process - group. If standard input has been reopened to /dev/null, this - will do no harm. If another port has been opened to become the - controlling terminal, it should have been detached when it was - closed. */ - (void) ioctl (0, TIOCNOTTY, (char *) NULL); + group. */ + { + int o; + + o = open ((char *) "/dev/tty", O_RDONLY); + if (o >= 0) + { + (void) ioctl (o, TIOCNOTTY, (char *) NULL); + (void) close (o); + } + } #endif /* ! HAVE_SETSID && HAVE_TIOCNOTTY */ /* Close stdin, stdout and stderr and reopen them on /dev/null, to diff --git a/gnu/libexec/uucp/libunix/dirent.c b/gnu/libexec/uucp/libunix/dirent.c index c7e467e..7ad0ec6 100644 --- a/gnu/libexec/uucp/libunix/dirent.c +++ b/gnu/libexec/uucp/libunix/dirent.c @@ -18,10 +18,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" diff --git a/gnu/libexec/uucp/libunix/dup2.c b/gnu/libexec/uucp/libunix/dup2.c index 8446163..a3fcea5 100644 --- a/gnu/libexec/uucp/libunix/dup2.c +++ b/gnu/libexec/uucp/libunix/dup2.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -47,7 +47,7 @@ dup2 (oold, onew) if (oold == onew) return onew; (void) close (onew); - + #ifdef F_DUPFD return fcntl (oold, F_DUPFD, onew); #else diff --git a/gnu/libexec/uucp/libunix/epopen.c b/gnu/libexec/uucp/libunix/epopen.c index 0ab9725..1873c5c 100644 --- a/gnu/libexec/uucp/libunix/epopen.c +++ b/gnu/libexec/uucp/libunix/epopen.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -78,7 +78,7 @@ espopen (pazargs, frd, pipid) errno = ierr; return NULL; } - + *pipid = ipid; return eret; diff --git a/gnu/libexec/uucp/libunix/failed.c b/gnu/libexec/uucp/libunix/failed.c new file mode 100644 index 0000000..66c98a8 --- /dev/null +++ b/gnu/libexec/uucp/libunix/failed.c @@ -0,0 +1,26 @@ +/* failed.c + Save a file in the .Failed directory. */ + +#include "uucp.h" + +#include "sysdep.h" +#include "uudefs.h" +#include "system.h" + +char * +zsysdep_save_failed_file (zfile) + const char *zfile; +{ + char *zto; + + zto = zsappend3 (zSspooldir, FAILEDDIR, zfile); + + if (! fsysdep_move_file (zfile, zto, TRUE, FALSE, FALSE, + (const char *) NULL)) + { + ubuffree (zto); + return NULL; + } + + return zto; +} diff --git a/gnu/libexec/uucp/libunix/filnam.c b/gnu/libexec/uucp/libunix/filnam.c index 7dd6626..6f804bb 100644 --- a/gnu/libexec/uucp/libunix/filnam.c +++ b/gnu/libexec/uucp/libunix/filnam.c @@ -1,7 +1,7 @@ /* filnam.c Get names to use for UUCP files. - Copyright (C) 1991, 1992, 1993 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1995 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -56,6 +56,23 @@ #define SEEK_SET 0 #endif +/* We use POSIX style fcntl locks if they are available, unless + O_CREAT is not defined. We could use them in the latter case, but + the code would have to become more complex to avoid races + concerning the use of creat. It is very unlikely that there is any + system which does have POSIX style locking but does not have + O_CREAT. */ +#if ! HAVE_BROKEN_SETLKW +#ifdef F_SETLKW +#ifdef O_CREAT +#define USE_POSIX_LOCKS 1 +#endif +#endif +#endif +#ifndef USE_POSIX_LOCKS +#define USE_POSIX_LOCKS 0 +#endif + /* External functions. */ #ifndef lseek extern off_t lseek (); @@ -83,21 +100,31 @@ fscmd_seq (zsystem, zseq) const char *zsystem; char *zseq; { - boolean ferr; + int cdelay; char *zfree; const char *zfile; int o; + boolean flockfile; int i; + boolean fret; - /* Lock the sequence file. This may not be correct for all systems, - but it only matters if the system UUCP and this UUCP are running - at the same time. */ - while (! fsdo_lock ("LCK..SEQ", TRUE, &ferr)) - { - if (ferr || FGOT_SIGNAL ()) - return FALSE; - sleep (5); - } + cdelay = 5; + +#if ! USE_POSIX_LOCKS + { + boolean ferr; + + /* Lock the sequence file. */ + while (! fsdo_lock ("LCK..SEQ", TRUE, &ferr)) + { + if (ferr || FGOT_SIGNAL ()) + return FALSE; + sleep (cdelay); + if (cdelay < 60) + ++cdelay; + } + } +#endif zfree = NULL; @@ -123,12 +150,12 @@ fscmd_seq (zsystem, zseq) #endif /* SPOOLDIR_TAYLOR */ #ifdef O_CREAT - o = open ((char *) zfile, O_RDWR | O_CREAT | O_NOCTTY, IPUBLIC_FILE_MODE); + o = open ((char *) zfile, O_RDWR | O_CREAT | O_NOCTTY, IPRIVATE_FILE_MODE); #else o = open ((char *) zfile, O_RDWR | O_NOCTTY); if (o < 0 && errno == ENOENT) { - o = creat ((char *) zfile, IPUBLIC_FILE_MODE); + o = creat ((char *) zfile, IPRIVATE_FILE_MODE); if (o >= 0) { (void) close (o); @@ -143,15 +170,17 @@ fscmd_seq (zsystem, zseq) { if (! fsysdep_make_dirs (zfile, FALSE)) { +#if ! USE_POSIX_LOCKS (void) fsdo_unlock ("LCK..SEQ", TRUE); +#endif return FALSE; } #ifdef O_CREAT o = open ((char *) zfile, O_RDWR | O_CREAT | O_NOCTTY, - IPUBLIC_FILE_MODE); + IPRIVATE_FILE_MODE); #else - o = creat ((char *) zfile, IPUBLIC_FILE_MODE); + o = creat ((char *) zfile, IPRIVATE_FILE_MODE); if (o >= 0) { (void) close (o); @@ -162,11 +191,79 @@ fscmd_seq (zsystem, zseq) if (o < 0) { ulog (LOG_ERROR, "open (%s): %s", zfile, strerror (errno)); +#if ! USE_POSIX_LOCKS (void) fsdo_unlock ("LCK..SEQ", TRUE); +#endif return FALSE; } } +#if ! USE_POSIX_LOCKS + flockfile = TRUE; +#else + { + struct flock slock; + + flockfile = FALSE; + + slock.l_type = F_WRLCK; + slock.l_whence = SEEK_SET; + slock.l_start = 0; + slock.l_len = 0; + while (fcntl (o, F_SETLKW, &slock) == -1) + { + boolean fagain; + + /* Some systems define F_SETLKW, but it does not work. We try + to catch those systems at runtime, and revert to using a + lock file. */ + if (errno == EINVAL) + { + boolean ferr; + + /* Lock the sequence file. */ + while (! fsdo_lock ("LCK..SEQ", TRUE, &ferr)) + { + if (ferr || FGOT_SIGNAL ()) + { + (void) close (o); + return FALSE; + } + sleep (cdelay); + if (cdelay < 60) + ++cdelay; + } + + flockfile = TRUE; + + break; + } + + fagain = FALSE; + if (errno == ENOMEM) + fagain = TRUE; +#ifdef ENOLCK + if (errno == ENOLCK) + fagain = TRUE; +#endif +#ifdef ENOSPC + if (errno == ENOSPC) + fagain = TRUE; +#endif + if (fagain) + { + sleep (cdelay); + if (cdelay < 60) + ++cdelay; + continue; + } + ulog (LOG_ERROR, "Locking %s: %s", zfile, strerror (errno)); + (void) close (o); + return FALSE; + } + } +#endif + if (read (o, zseq, CSEQLEN) != CSEQLEN) strcpy (zseq, "0000"); zseq[CSEQLEN] = '\0'; @@ -199,19 +296,24 @@ fscmd_seq (zsystem, zseq) } #endif /* SPOOLDIR_ULTRIX || SPOOLDIR_TAYLOR */ + fret = TRUE; + if (lseek (o, (off_t) 0, SEEK_SET) < 0 || write (o, zseq, CSEQLEN) != CSEQLEN || close (o) < 0) { - ulog (LOG_ERROR, "lseek or write or close: %s", strerror (errno)); + ulog (LOG_ERROR, "lseek or write or close %s: %s", + zfile, strerror (errno)); (void) close (o); - (void) fsdo_unlock ("LCK..SEQ", TRUE); - return FALSE; + fret = FALSE; } - (void) fsdo_unlock ("LCK..SEQ", TRUE); + if (flockfile) + (void) fsdo_unlock ("LCK..SEQ", TRUE); + + ubuffree (zfree); - return TRUE; + return fret; } /* Get the name of a command or data file for a remote system. The @@ -266,9 +368,9 @@ zsfile_name (btype, zsystem, zlocalname, bgrade, fxqt, ztname, zdname, zxname) our system name so that remote UUCP's running SPOOLDIR_V2 and the like can distinguish while files come from which systems. */ -#if SPOOLDIR_HDB || SPOOLDIR_SVR4 +#if SPOOLDIR_SVR4 sprintf (absimple, "D.%.7s%c%s", zsystem, bgrade, abseq); -#else /* ! SPOOLDIR_HDB && ! SPOOLDIR_SVR4 */ +#else /* ! SPOOLDIR_SVR4 */ #if ! SPOOLDIR_TAYLOR sprintf (absimple, "D.%.7s%c%s", zlocalname, bgrade, abseq); #else /* SPOOLDIR_TAYLOR */ @@ -329,10 +431,41 @@ zsysdep_data_file_name (qsys, zlocalname, bgrade, fxqt, ztname, zdname, char *zdname; char *zxname; { - return zsfile_name ('D', qsys->uuconf_zname, zlocalname, bgrade, fxqt, + return zsfile_name ('D', qsys->uuconf_zname, zlocalname, bgrade, fxqt, ztname, zdname, zxname); } +#if SPOOLDIR_TAYLOR + +/* Write out a number in base 62 into a given number of characters, + right justified with zero fill. This is used by zscmd_file if + SPOOLDIR_TAYLOR. */ + +static void usput62 P((long i, char *, int c)); + +static void +usput62 (i, z, c) + long i; + char *z; + int c; +{ + for (--c; c >= 0; --c) + { + int d; + + d = i % 62; + i /= 62; + if (d < 26) + z[c] = 'A' + d; + else if (d < 52) + z[c] = 'a' + d - 26; + else + z[c] = '0' + d - 52; + } +} + +#endif /* SPOOLDIR_TAYLOR */ + /* Get a command file name. */ char * @@ -340,9 +473,84 @@ zscmd_file (qsys, bgrade) const struct uuconf_system *qsys; int bgrade; { +#if ! SPOOLDIR_TAYLOR return zsfile_name ('C', qsys->uuconf_zname, (const char *) NULL, bgrade, FALSE, (char *) NULL, (char *) NULL, (char *) NULL); +#else + char *zname; + long isecs, imicros; + pid_t ipid; + + /* This file name is never seen by the remote system, so we don't + actually need to get a sequence number for it. We just need to + get a file name which is unique for this system. We don't try + this optimization for other spool directory formats, mainly due + to compatibility concerns. It would be possible for HDB and SVR4 + spool directory formats. + + We get a unique name by combining the process ID and the current + time. The file name must start with C.g, where g is the grade. + Note that although it is likely that this name will be unique, it + is not guaranteed, so the caller must be careful. */ + + isecs = ixsysdep_time (&imicros); + ipid = getpid (); + + /* We are going to represent the file name as a series of numbers in + base 62 (using the alphanumeric characters). The maximum file + name length is 14 characters, so we may use 11. We use 3 for the + seconds within the day, 3 for the microseconds, and 5 for the + process ID. */ + + /* Cut the seconds down to a number within a day (maximum value + 86399 < 62 ** 3 == 238328). */ + isecs %= (long) 24 * (long) 60 * (long) 60; + /* Divide the microseconds (max 999999) by 5 to make sure they are + less than 62 ** 3. */ + imicros %= 1000000; + imicros /= 5; + + while (TRUE) + { + char ab[15]; + + ab[0] = 'C'; + ab[1] = '.'; + ab[2] = bgrade; + usput62 (isecs, ab + 3, 3); + usput62 (imicros, ab + 6, 3); + usput62 ((long) ipid, ab + 9, 5); + ab[14] = '\0'; + + zname = zsfind_file (ab, qsys->uuconf_zname, bgrade); + if (zname == NULL) + return NULL; + + if (! fsysdep_file_exists (zname)) + break; + + ubuffree (zname); + + /* We hit a duplicate. Move backward in time until we find an + available name. Note that there is still a theoretical race + condition, since 5 base 62 digits might not be enough for the + process ID, and some other process might be running these + checks at the same time as we are. The caller must deal with + this. */ + if (imicros == 0) + { + imicros = (long) 62 * (long) 62 * (long) 62; + if (isecs == 0) + isecs = (long) 62 * (long) 62 * (long) 62; + --isecs; + } + --imicros; + } + + return zname; + +#endif } /* Return a name for an execute file to be created locally. This is diff --git a/gnu/libexec/uucp/libunix/fsusg.c b/gnu/libexec/uucp/libunix/fsusg.c index cee1ff0..9189193 100644 --- a/gnu/libexec/uucp/libunix/fsusg.c +++ b/gnu/libexec/uucp/libunix/fsusg.c @@ -1,5 +1,5 @@ /* fsusage.c -- return space usage of mounted filesystems - Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc. + Copyright (C) 1991, 1992 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,74 +13,70 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. This file was modified slightly by Ian Lance Taylor, December 1992, - for use with Taylor UUCP. */ + and again July 1995, for use with Taylor UUCP. */ #include "uucp.h" #include "uudefs.h" #include "sysdep.h" #include "fsusg.h" -#if STAT_STATFS2_BSIZE -#ifdef __FreeBSD__ +int statfs (); + +#if HAVE_SYS_PARAM_H #include <sys/param.h> -#include <sys/mount.h> -#else -#ifndef _IBMR2 /* 4.3BSD, SunOS 4, HP-UX, AIX PS/2. */ -#include <sys/vfs.h> -#endif -#endif #endif -#if STAT_STATFS2_FSIZE /* 4.4BSD. */ +#if HAVE_SYS_MOUNT_H #include <sys/mount.h> #endif -#if STAT_STATFS2_FS_DATA /* Ultrix. */ -#include <sys/param.h> -#include <sys/mount.h> +#if HAVE_SYS_VFS_H +#include <sys/vfs.h> #endif -#if STAT_USTAT /* SVR2 and others. */ -#include <ustat.h> +#if HAVE_SYS_FILSYS_H +#include <sys/filsys.h> /* SVR2. */ #endif -#if STAT_STATFS4 /* SVR3, Dynix, Irix. */ -#include <sys/statfs.h> +#if HAVE_FCNTL_H +#include <fcntl.h> #endif -#ifdef _AIX -#ifdef _IBMR2 /* AIX RS6000. */ + +#if HAVE_SYS_STATFS_H #include <sys/statfs.h> #endif -#endif -#if STAT_DUSTAT /* AIX PS/2. */ -#include <sys/stat.h> +#if HAVE_SYS_DUSTAT_H /* AIX PS/2. */ #include <sys/dustat.h> #endif -#if STAT_STATVFS /* SVR4. */ +#if HAVE_SYS_STATVFS_H /* SVR4. */ #include <sys/statvfs.h> +int statvfs (); +#endif + +#if HAVE_USTAT_H /* SVR2 and others. */ +#include <ustat.h> #endif #if STAT_DISK_SPACE /* QNX. */ #include <sys/disk.h> -#include <fcntl.h> #include <errno.h> #endif #define STAT_NONE 0 -#if ! STAT_STATVFS +#if ! STAT_STATFS3_OSF1 +#if ! STAT_STATFS2_FS_DATA #if ! STAT_STATFS2_BSIZE #if ! STAT_STATFS2_FSIZE -#if ! STAT_STATFS2_FS_DATA #if ! STAT_STATFS4 -#if ! STAT_DUSTAT -#if ! STAT_USTAT +#if ! STAT_STATVFS #if ! STAT_DISK_SPACE +#if ! STAT_USTAT #undef STAT_NONE #define STAT_NONE 1 #endif @@ -97,19 +93,25 @@ static long adjust_blocks P((long blocks, int fromsize, int tosize)); /* Return the number of TOSIZE-byte blocks used by - BLOCKS FROMSIZE-byte blocks, rounding up. */ + BLOCKS FROMSIZE-byte blocks, rounding away from zero. + TOSIZE must be positive. Return -1 if FROMSIZE is not positive. */ static long adjust_blocks (blocks, fromsize, tosize) long blocks; int fromsize, tosize; { + if (tosize <= 0) + abort (); + if (fromsize <= 0) + return -1; + if (fromsize == tosize) /* E.g., from 512 to 512. */ return blocks; else if (fromsize > tosize) /* E.g., from 2048 to 512. */ return blocks * (fromsize / tosize); else /* E.g., from 256 to 512. */ - return (blocks + 1) / (tosize / fromsize); + return (blocks + (blocks < 0 ? -1 : 1)) / (tosize / fromsize); } #endif @@ -129,25 +131,33 @@ get_fs_usage (path, disk, fsp) return -1; #endif +#if STAT_STATFS3_OSF1 + struct statfs fsd; + + if (statfs (path, &fsd, sizeof (struct statfs)) != 0) + return -1; +#define CONVERT_BLOCKS(b) adjust_blocks ((b), fsd.f_fsize, 512) +#endif /* STAT_STATFS3_OSF1 */ + #if STAT_STATFS2_FS_DATA /* Ultrix. */ struct fs_data fsd; if (statfs (path, &fsd) != 1) return -1; -#define convert_blocks(b) adjust_blocks ((long) (b), 1024, 512) - fsp->fsu_blocks = convert_blocks (fsd.fd_req.btot); - fsp->fsu_bfree = convert_blocks (fsd.fd_req.bfree); - fsp->fsu_bavail = convert_blocks (fsd.fd_req.bfreen); +#define CONVERT_BLOCKS(b) adjust_blocks ((long) (b), 1024, 512) + fsp->fsu_blocks = CONVERT_BLOCKS (fsd.fd_req.btot); + fsp->fsu_bfree = CONVERT_BLOCKS (fsd.fd_req.bfree); + fsp->fsu_bavail = CONVERT_BLOCKS (fsd.fd_req.bfreen); fsp->fsu_files = fsd.fd_req.gtot; fsp->fsu_ffree = fsd.fd_req.gfree; #endif -#if STAT_STATFS2_BSIZE || STAT_DUSTAT /* 4.3BSD, SunOS 4, HP-UX, AIX. */ +#if STAT_STATFS2_BSIZE /* 4.3BSD, SunOS 4, HP-UX, AIX. */ struct statfs fsd; if (statfs (path, &fsd) < 0) return -1; -#define convert_blocks(b) adjust_blocks ((b), fsd.f_bsize, 512) +#define CONVERT_BLOCKS(b) adjust_blocks ((b), fsd.f_bsize, 512) #endif #if STAT_STATFS2_FSIZE /* 4.4BSD. */ @@ -155,7 +165,7 @@ get_fs_usage (path, disk, fsp) if (statfs (path, &fsd) < 0) return -1; -#define convert_blocks(b) adjust_blocks ((b), fsd.f_fsize, 512) +#define CONVERT_BLOCKS(b) adjust_blocks ((b), fsd.f_fsize, 512) #endif #if STAT_STATFS4 /* SVR3, Dynix, Irix. */ @@ -166,10 +176,16 @@ get_fs_usage (path, disk, fsp) /* Empirically, the block counts on most SVR3 and SVR3-derived systems seem to always be in terms of 512-byte blocks, no matter what value f_bsize has. */ -#define convert_blocks(b) (b) -#ifndef _SEQUENT_ /* _SEQUENT_ is DYNIX/ptx. */ -#define f_bavail f_bfree -#endif +# if _AIX +# define CONVERT_BLOCKS(b) adjust_blocks ((b), fsd.f_bsize, 512) +# else +# define CONVERT_BLOCKS(b) (b) +# ifndef _SEQUENT_ /* _SEQUENT_ is DYNIX/ptx. */ +# ifndef DOLPHIN /* DOLPHIN 3.8.alfa/7.18 has f_bavail */ +# define f_bavail f_bfree +# endif +# endif +# endif #endif #if STAT_STATVFS /* SVR4. */ @@ -178,7 +194,7 @@ get_fs_usage (path, disk, fsp) if (statvfs (path, &fsd) < 0) return -1; /* f_frsize isn't guaranteed to be supported. */ -#define convert_blocks(b) \ +#define CONVERT_BLOCKS(b) \ adjust_blocks ((b), fsd.f_frsize ? fsd.f_frsize : fsd.f_bsize, 512) #endif @@ -188,7 +204,7 @@ get_fs_usage (path, disk, fsp) long cfree_blocks, ctotal_blocks; char *zpath; char *zslash; - + zpath = zbufcpy (path); while ((o = open (zpath, O_RDONLY, 0)) == -1 && errno == ENOENT) @@ -247,7 +263,7 @@ get_fs_usage (path, disk, fsp) fsp->fsu_blocks = ctotal_blocks; fsp->fsu_bfree = cfree_blocks; fsp->fsu_bavail = cfree_blocks; - + /* QNX has no limit on the number of inodes. Most inodes are stored directly in the directory entry. */ fsp->fsu_files = -1; @@ -272,9 +288,9 @@ get_fs_usage (path, disk, fsp) #if ! STAT_DISK_SPACE #if ! STAT_USTAT #if ! STAT_NONE - fsp->fsu_blocks = convert_blocks (fsd.f_blocks); - fsp->fsu_bfree = convert_blocks (fsd.f_bfree); - fsp->fsu_bavail = convert_blocks (fsd.f_bavail); + fsp->fsu_blocks = CONVERT_BLOCKS (fsd.f_blocks); + fsp->fsu_bfree = CONVERT_BLOCKS (fsd.f_bfree); + fsp->fsu_bavail = CONVERT_BLOCKS (fsd.f_bavail); fsp->fsu_files = fsd.f_files; fsp->fsu_ffree = fsd.f_ffree; #endif @@ -285,7 +301,8 @@ get_fs_usage (path, disk, fsp) return 0; } -#if STAT_DUSTAT +#ifdef _AIX +#ifdef _I386 /* AIX PS/2 does not supply statfs. */ int @@ -311,4 +328,5 @@ statfs (path, fsb) fsb->f_fsid.val[1] = fsd.du_pckno; return 0; } -#endif /* STAT_DUSTAT */ +#endif /* _I386 */ +#endif /* _AIX */ diff --git a/gnu/libexec/uucp/libunix/fsusg.h b/gnu/libexec/uucp/libunix/fsusg.h index 8d4d054..2b9ddd5 100644 --- a/gnu/libexec/uucp/libunix/fsusg.h +++ b/gnu/libexec/uucp/libunix/fsusg.h @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. This files was modified slightly by Ian Lance Taylor for use with Taylor UUCP. */ diff --git a/gnu/libexec/uucp/libunix/ftw.c b/gnu/libexec/uucp/libunix/ftw.c index c7af06e..f7af66f 100644 --- a/gnu/libexec/uucp/libunix/ftw.c +++ b/gnu/libexec/uucp/libunix/ftw.c @@ -14,8 +14,8 @@ Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 675 Mass Ave, -Cambridge, MA 02139, USA. +not, write to the Free Software Foundation, Inc., 59 Temple Place - +Suite 330, Boston, MA 02111-1307, USA. Modified by Ian Lance Taylor for Taylor UUCP, June 1992, and October 1993. */ @@ -76,7 +76,7 @@ ftw_dir (dirs, level, descriptors, dir, len, func) { size_t namlen; struct stat s; - int flag, ret, newlev; + int flag, ret, newlev = 0; ++got; diff --git a/gnu/libexec/uucp/libunix/getcwd.c b/gnu/libexec/uucp/libunix/getcwd.c index da53b56..d3623bd 100644 --- a/gnu/libexec/uucp/libunix/getcwd.c +++ b/gnu/libexec/uucp/libunix/getcwd.c @@ -48,7 +48,7 @@ getcwd (zbuf, cbuf) cread = 0; } } - + if (cread == 0) { errno = ierr; diff --git a/gnu/libexec/uucp/libunix/indir.c b/gnu/libexec/uucp/libunix/indir.c index de1df70..88cdb0e 100644 --- a/gnu/libexec/uucp/libunix/indir.c +++ b/gnu/libexec/uucp/libunix/indir.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" diff --git a/gnu/libexec/uucp/libunix/init.c b/gnu/libexec/uucp/libunix/init.c index 95822db..8a3c416 100644 --- a/gnu/libexec/uucp/libunix/init.c +++ b/gnu/libexec/uucp/libunix/init.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" diff --git a/gnu/libexec/uucp/libunix/isfork.c b/gnu/libexec/uucp/libunix/isfork.c index f28d65f..f067d07 100644 --- a/gnu/libexec/uucp/libunix/isfork.c +++ b/gnu/libexec/uucp/libunix/isfork.c @@ -1,4 +1,4 @@ -/* isfork.c +/* isfork.c Retry fork several times before giving up. */ #include "uucp.h" diff --git a/gnu/libexec/uucp/libunix/iswait.c b/gnu/libexec/uucp/libunix/iswait.c index 361443a..d13db6e 100644 --- a/gnu/libexec/uucp/libunix/iswait.c +++ b/gnu/libexec/uucp/libunix/iswait.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -134,7 +134,7 @@ ixswait (ipid, zreport) } } #endif /* ! HAVE_WAIT4 */ -#endif /* ! HAVE_WAITPID */ +#endif /* ! HAVE_WAITPID */ DEBUG_MESSAGE2 (DEBUG_EXECUTE, "%s %d", WIFEXITED (istat) ? "Exit status" : "Signal", diff --git a/gnu/libexec/uucp/libunix/jobid.c b/gnu/libexec/uucp/libunix/jobid.c index c8b21cb..b7f9145 100644 --- a/gnu/libexec/uucp/libunix/jobid.c +++ b/gnu/libexec/uucp/libunix/jobid.c @@ -1,7 +1,7 @@ /* jobid.c Convert file names to jobids and vice versa. - Copyright (C) 1991, 1992 Ian Lance Taylor + Copyright (C) 1991, 1992, 1995 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -31,10 +31,7 @@ #include "system.h" /* Translate a file name and an associated system into a job id. - These job ids are used by uustat. We use the system name attached - to the grade and sequence number. This won't work correctly if the - file name was actually created by some other version of uucp that - uses a different length for the sequence number. Too bad. */ + These job ids are used by uustat. */ char * zsfile_to_jobid (qsys, zfile, bgrade) @@ -46,10 +43,50 @@ zsfile_to_jobid (qsys, zfile, bgrade) char *zret; clen = strlen (qsys->uuconf_zname); + +#if ! SPOOLDIR_TAYLOR + + /* We use the system name attached to the grade and sequence number. + This won't work correctly if the file name was actually created + by some other version of uucp that uses a different length for + the sequence number. Too bad. */ + zret = zbufalc (clen + CSEQLEN + 2); memcpy (zret, qsys->uuconf_zname, clen); zret[clen] = bgrade; memcpy (zret + clen + 1, zfile + strlen (zfile) - CSEQLEN, CSEQLEN + 1); + +#else + + /* We use the system name followed by a dot, the grade, and the + sequence number. In this case, the sequence number is a long + string. */ + + { + size_t cseqlen; + + /* zfile is SYS/C./C.gseq. */ + zfile = strrchr (zfile, '/'); + +#if DEBUG > 0 + if (zfile == NULL + || zfile[1] != 'C' + || zfile[2] != '.' + || zfile[3] == '\0') + ulog (LOG_FATAL, "zsfile_to_jobid: Can't happen"); +#endif + + /* Make zfile point at .gseq. */ + zfile += 2; + + cseqlen = strlen (zfile); + zret = zbufalc (clen + cseqlen + 1); + memcpy (zret, qsys->uuconf_zname, clen); + memcpy (zret + clen, zfile, cseqlen + 1); + } + +#endif + return zret; } @@ -61,6 +98,7 @@ zsjobid_to_file (zid, pzsystem, pbgrade) char **pzsystem; char *pbgrade; { +#if ! SPOOLDIR_TAYLOR size_t clen; const char *zend; char *zsys; @@ -81,11 +119,7 @@ zsjobid_to_file (zid, pzsystem, pbgrade) zsys[clen - CSEQLEN - 1] = '\0'; /* This must correspond to zsfile_name. */ -#if ! SPOOLDIR_TAYLOR sprintf (abname, "C.%.7s%s", zsys, zend); -#else - sprintf (abname, "C.%s", zend); -#endif zret = zsfind_file (abname, zsys, *zend); @@ -98,4 +132,38 @@ zsjobid_to_file (zid, pzsystem, pbgrade) *pbgrade = *zend; return zret; +#else /* SPOOLDIR_TAYLOR */ + char *zdot; + size_t csyslen; + char *zsys; + char ab[15]; + char *zret; + + zdot = strrchr (zid, '.'); + if (zdot == NULL) + { + ulog (LOG_ERROR, "%s: Bad job id", zid); + return NULL; + } + + csyslen = zdot - zid; + zsys = zbufalc (csyslen + 1); + memcpy (zsys, zid, csyslen); + zsys[csyslen] = '\0'; + + ab[0] = 'C'; + strcpy (ab + 1, zdot); + + zret = zsfind_file (ab, zsys, zdot[1]); + + if (zret != NULL && pzsystem != NULL) + *pzsystem = zsys; + else + ubuffree (zsys); + + if (pbgrade != NULL) + *pbgrade = zdot[1]; + + return zret; +#endif /* SPOOLDIR_TAYLOR */ } diff --git a/gnu/libexec/uucp/libunix/lcksys.c b/gnu/libexec/uucp/libunix/lcksys.c index c1b0efa..ab2e2c8 100644 --- a/gnu/libexec/uucp/libunix/lcksys.c +++ b/gnu/libexec/uucp/libunix/lcksys.c @@ -8,21 +8,39 @@ #include "sysdep.h" #include "system.h" -/* Get the name of a system lock file. */ +/* Do the actual lock or unlock. */ -static char *zssys_lock_name P((const struct uuconf_system *qsys, char *z)); +static boolean fslock_sys P((boolean, const char *)); -#define LOCKNAMELEN (sizeof "LCK..12345678") - -static char * -zssys_lock_name (qsys, z) - const struct uuconf_system *qsys; - char *z; +static boolean +fslock_sys (flock, zname) + boolean flock; + const char *zname; { - strcpy (z, "LCK.."); - strncpy (z + sizeof "LCK.." - 1, qsys->uuconf_zname, 8); - z[sizeof "LCK.." - 1 + 8] = '\0'; - return z; + size_t clen; + char *z; + boolean fret; + + clen = strlen (zname); + +#if ! HAVE_LONG_FILE_NAMES + if (clen > 8) + clen = 8; +#endif + + z = zbufalc (sizeof "LCK.." + clen); + memcpy (z, "LCK..", sizeof "LCK.." - 1); + memcpy (z + sizeof "LCK.." - 1, zname, clen); + z[sizeof "LCK.." - 1 + clen] = '\0'; + + if (flock) + fret = fsdo_lock (z, FALSE, (boolean *) NULL); + else + fret = fsdo_unlock (z, FALSE); + + ubuffree (z); + + return fret; } /* Lock a remote system. */ @@ -31,9 +49,7 @@ boolean fsysdep_lock_system (qsys) const struct uuconf_system *qsys; { - char ab[LOCKNAMELEN]; - - return fsdo_lock (zssys_lock_name (qsys, ab), FALSE, (boolean *) NULL); + return fslock_sys (TRUE, qsys->uuconf_zname); } /* Unlock a remote system. */ @@ -42,7 +58,5 @@ boolean fsysdep_unlock_system (qsys) const struct uuconf_system *qsys; { - char ab[LOCKNAMELEN]; - - return fsdo_unlock (zssys_lock_name (qsys, ab), FALSE); + return fslock_sys (FALSE, qsys->uuconf_zname); } diff --git a/gnu/libexec/uucp/libunix/locfil.c b/gnu/libexec/uucp/libunix/locfil.c index 4e0a5f9..47581cf 100644 --- a/gnu/libexec/uucp/libunix/locfil.c +++ b/gnu/libexec/uucp/libunix/locfil.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -77,7 +77,7 @@ zsysdep_local_file (zfile, zpubdir, pfbadname) zcopy = zbufalc (cuserlen + 1); memcpy (zcopy, zfile, cuserlen); zcopy[cuserlen] = '\0'; - + q = getpwnam (zcopy); if (q == NULL) { diff --git a/gnu/libexec/uucp/libunix/lock.c b/gnu/libexec/uucp/libunix/lock.c index ad52af8..1be6fbc 100644 --- a/gnu/libexec/uucp/libunix/lock.c +++ b/gnu/libexec/uucp/libunix/lock.c @@ -1,7 +1,7 @@ /* lock.c Lock and unlock a file name. - Copyright (C) 1991, 1992, 1993 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1995 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -17,16 +17,16 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" #if USE_RCS_ID -const char lock_rcsid[] = "$Id: lock.c,v 1.2 1994/05/07 18:10:40 ache Exp $"; +const char lock_rcsid[] = "$Id: lock.c,v 1.20 1995/06/21 19:19:38 ian Rel $"; #endif #include "uudefs.h" @@ -34,6 +34,7 @@ const char lock_rcsid[] = "$Id: lock.c,v 1.2 1994/05/07 18:10:40 ache Exp $"; #include "system.h" #include <errno.h> +#include <ctype.h> #if HAVE_FCNTL_H #include <fcntl.h> @@ -178,7 +179,7 @@ fsdo_lock (zlock, fspooldir, pferr) } #if HAVE_QNX_LOCKFILES - sprintf (ab, "%10ld %10ld\n", (long) ime, (long) inid); + sprintf (ab, "%10ld %10ld\n", (long) ime, (long) inme); cwrote = write (o, ab, strlen (ab)); #else #if HAVE_V2_LOCKFILES @@ -274,6 +275,25 @@ fsdo_lock (zlock, fspooldir, pferr) break; } +#if DEBUG > 0 +#if HAVE_V2_LOCKFILES + { + char ab[10]; + + if (read (o, ab, sizeof ab) > 4 + && isdigit (BUCHAR (ab[0]))) + ulog (LOG_ERROR, + "Lock file %s may be HDB format; check LOCKFILES in policy.h", + zpath); + } +#else + if (cgot == 4) + ulog (LOG_ERROR, + "Lock file %s may be V2 format; check LOCKFILES in policy.h", + zpath); +#endif +#endif /* DEBUG > 0 */ + #if HAVE_QNX_LOCKFILES ab[cgot] = '\0'; ipid = (pid_t) strtol (ab, &zend, 10); @@ -308,17 +328,23 @@ fsdo_lock (zlock, fspooldir, pferr) } } + /* If the lock file is empty (cgot == 0), we assume that it is + stale. This can happen if the system crashed after the lock + file was created but before the process ID was written out. */ + if (cgot > 0) + { #if HAVE_QNX_LOCKFILES - if (! fsqnx_stale ((unsigned long) ipid, (unsigned long) inme, - (unsigned long) inid, pferr)) - break; + if (! fsqnx_stale ((unsigned long) ipid, (unsigned long) inme, + (unsigned long) inid, pferr)) + break; #else - /* If the process still exists, we will get EPERM rather than - ESRCH. We then return FALSE to indicate that we cannot make - the lock. */ - if (kill (ipid, 0) == 0 || errno == EPERM) - break; + /* If the process still exists, we will get EPERM rather + than ESRCH. We then return FALSE to indicate that we + cannot make the lock. */ + if (kill (ipid, 0) == 0 || errno == EPERM) + break; #endif + } if (fstat (o, &st) < 0) strcpy (abtime, "unknown"); @@ -411,7 +437,7 @@ fsdo_lock (zlock, fspooldir, pferr) } #if HAVE_QNX_LOCKFILES - sprintf (ab, "%10ld %10ld\n", (long) ime, (long) inid); + sprintf (ab, "%10ld %10ld\n", (long) ime, (long) inme); cwrote = write (o, ab, strlen (ab)); #else #if HAVE_V2_LOCKFILES @@ -620,7 +646,7 @@ fsqnx_stale (ipid, inme, inid, pferr) /* Use the local pid of the local process manager. */ ivid = PROC_PID; } - + /* Request the process information. */ ifound_pid = qnx_psinfo (ivid /* process manager handling request */, ipid /* get info on this process */, @@ -636,7 +662,7 @@ fsqnx_stale (ipid, inme, inid, pferr) strerror (errno)); errno = isaved_errno; } - + /* If the returned pid matches then the process still holds the lock. */ if ((ifound_pid == ipid) && (spsdata.pid == ipid)) return FALSE; diff --git a/gnu/libexec/uucp/libunix/mail.c b/gnu/libexec/uucp/libunix/mail.c index e1fbaa9..634a593 100644 --- a/gnu/libexec/uucp/libunix/mail.c +++ b/gnu/libexec/uucp/libunix/mail.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" diff --git a/gnu/libexec/uucp/libunix/mkdirs.c b/gnu/libexec/uucp/libunix/mkdirs.c index 9b5b23f..df4f987 100644 --- a/gnu/libexec/uucp/libunix/mkdirs.c +++ b/gnu/libexec/uucp/libunix/mkdirs.c @@ -28,9 +28,18 @@ fsysdep_make_dirs (zfile, fpublic) { if (*z == '/' && z != zcopy) { + /* Some versions of uuto will send a double slash. Some + systems will fail to create a directory ending in a + slash. */ + if (z[-1] == '/') + continue; *z = '\0'; if (mkdir (zcopy, imode) != 0 && errno != EEXIST + && errno != EISDIR +#ifdef EROFS + && errno != EROFS +#endif && (errno != EACCES || ! fsysdep_directory (zcopy))) { ulog (LOG_ERROR, "mkdir (%s): %s", zcopy, @@ -38,10 +47,7 @@ fsysdep_make_dirs (zfile, fpublic) ubuffree (zcopy); return FALSE; } - *z = '/'; /* replace '/' in its place */ - /* now skips over multiple '/' in name */ - while ( (*(z + 1)) && (*(z + 1)) == '/') - z++; + *z = '/'; } } diff --git a/gnu/libexec/uucp/libunix/move.c b/gnu/libexec/uucp/libunix/move.c index 3345bbf..19828c2 100644 --- a/gnu/libexec/uucp/libunix/move.c +++ b/gnu/libexec/uucp/libunix/move.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -152,7 +152,7 @@ fsysdep_move_file (zorig, zto, fmkdirs, fpublic, fcheck, zuser) } (void) close (o); - if (! fcopy_file (zorig, zto, fpublic, fmkdirs)) + if (! fcopy_file (zorig, zto, fpublic, fmkdirs, FALSE)) return FALSE; if (remove (zorig) != 0) diff --git a/gnu/libexec/uucp/libunix/opensr.c b/gnu/libexec/uucp/libunix/opensr.c index c9e531a..5217741 100644 --- a/gnu/libexec/uucp/libunix/opensr.c +++ b/gnu/libexec/uucp/libunix/opensr.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -75,7 +75,7 @@ esysdep_open_send (qsys, zfile, fcheck, zuser) struct stat s; openfile_t e; int o; - + if (fsysdep_directory (zfile)) { ulog (LOG_ERROR, "%s: is a directory", zfile); @@ -148,7 +148,7 @@ zsysdep_receive_temp (qsys, zto, ztemp, frestart) return zsappend3 (".Temp", qsys->uuconf_zname, ztemp); else return zstemp_file (qsys); -} +} /* The number of seconds in one week. We must cast to long for this to be calculated correctly on a machine with 16 bit ints. */ diff --git a/gnu/libexec/uucp/libunix/pause.c b/gnu/libexec/uucp/libunix/pause.c index 8155db3..8b2b698 100644 --- a/gnu/libexec/uucp/libunix/pause.c +++ b/gnu/libexec/uucp/libunix/pause.c @@ -7,27 +7,29 @@ #include "system.h" /* Pick a timing routine to use. I somewhat arbitrarily picked usleep - above nap above napms above poll above select. */ -#if HAVE_USLEEP || HAVE_NAP || HAVE_NAPMS || HAVE_POLL + above napms above poll above select above nap. The nap function is + last because on different systems the argument has different + meanings. */ +#if HAVE_USLEEP || HAVE_NAPMS || HAVE_POLL || HAVE_SELECT +#undef HAVE_NAP +#define HAVE_NAP 0 +#endif + +#if HAVE_USLEEP || HAVE_NAPMS || HAVE_POLL #undef HAVE_SELECT #define HAVE_SELECT 0 #endif -#if HAVE_USLEEP || HAVE_NAP || HAVE_NAPMS +#if HAVE_USLEEP || HAVE_NAPMS #undef HAVE_POLL #define HAVE_POLL 0 #endif -#if HAVE_USLEEP || HAVE_NAP +#if HAVE_USLEEP #undef HAVE_NAPMS #define HAVE_NAPMS 0 #endif -#if HAVE_USLEEP -#undef HAVE_NAP -#define HAVE_NAP 0 -#endif - #if HAVE_SELECT #if HAVE_SYS_TIME_H #include <sys/time.h> @@ -81,6 +83,7 @@ usysdep_pause () /* We need to pass an unused pollfd structure because poll checks the address before checking the number of elements. */ + memset (&sdummy, 0, sizeof sdummy); poll (&sdummy, 0, 500); #endif /* HAVE_POLL */ #if HAVE_SELECT diff --git a/gnu/libexec/uucp/libunix/picksb.c b/gnu/libexec/uucp/libunix/picksb.c index 25b1c4e..43a0b2a 100644 --- a/gnu/libexec/uucp/libunix/picksb.c +++ b/gnu/libexec/uucp/libunix/picksb.c @@ -17,16 +17,16 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" #if USE_RCS_ID -const char picksb_rcsid[] = "$Id: picksb.c,v 1.2 1994/05/07 18:10:54 ache Exp $"; +const char picksb_rcsid[] = "$Id: picksb.c,v 1.10 1995/06/21 19:19:54 ian Rel $"; #endif #include "uudefs.h" @@ -219,7 +219,7 @@ zsysdep_uupick_local_file (zfile, pfbadname) if (zfile[0] != '~' || (zfile[1] != '/' && zfile[1] != '\0')) return zsysdep_local_file_cwd (zfile, (const char *) NULL, pfbadname); - + q = getpwuid (getuid ()); if (q == NULL) { diff --git a/gnu/libexec/uucp/libunix/pipe.c b/gnu/libexec/uucp/libunix/pipe.c index 69763f6..7f69040 100644 --- a/gnu/libexec/uucp/libunix/pipe.c +++ b/gnu/libexec/uucp/libunix/pipe.c @@ -18,16 +18,16 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" #if USE_RCS_ID -const char pipe_rcsid[] = "$Id: pipe.c,v 1.4 1994/03/25 04:09:30 ian Rel $"; +const char pipe_rcsid[] = "$Id: pipe.c,v 1.6 1995/06/21 19:19:57 ian Rel $"; #endif #include "uudefs.h" diff --git a/gnu/libexec/uucp/libunix/proctm.c b/gnu/libexec/uucp/libunix/proctm.c index b9b6eb9..912b11b 100644 --- a/gnu/libexec/uucp/libunix/proctm.c +++ b/gnu/libexec/uucp/libunix/proctm.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" diff --git a/gnu/libexec/uucp/libunix/recep.c b/gnu/libexec/uucp/libunix/recep.c index 152fd0d..a1f893d 100644 --- a/gnu/libexec/uucp/libunix/recep.c +++ b/gnu/libexec/uucp/libunix/recep.c @@ -1,7 +1,7 @@ /* recep.c See whether a file has already been received. - Copyright (C) 1992, 1993 Ian Lance Taylor + Copyright (C) 1992, 1993, 1995 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -50,7 +50,7 @@ static char *zsreceived_name P((const struct uuconf_system *qsys, /* These routines are used to see whether we have already received a file in a previous UUCP connection. It is possible for the acknowledgement of a received file to be lost. The sending system - will then now know that the file was correctly received, and will + will then not know that the file was correctly received, and will send it again. This can be a problem particularly with protocols which support channels, since they may send several small files in a single window, all of which may be received correctly although diff --git a/gnu/libexec/uucp/libunix/run.c b/gnu/libexec/uucp/libunix/run.c index af9b078..d789d37 100644 --- a/gnu/libexec/uucp/libunix/run.c +++ b/gnu/libexec/uucp/libunix/run.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" diff --git a/gnu/libexec/uucp/libunix/seq.c b/gnu/libexec/uucp/libunix/seq.c index bd2cef8..321ed74 100644 --- a/gnu/libexec/uucp/libunix/seq.c +++ b/gnu/libexec/uucp/libunix/seq.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -68,7 +68,7 @@ ixsysdep_get_sequence (qsys) ubuffree (zname); return -1; } - + e = fopen (zname, "r+"); if (e == NULL) { diff --git a/gnu/libexec/uucp/libunix/serial.c b/gnu/libexec/uucp/libunix/serial.c index ae0a943..a38e28c 100644 --- a/gnu/libexec/uucp/libunix/serial.c +++ b/gnu/libexec/uucp/libunix/serial.c @@ -1,7 +1,7 @@ /* serial.c The serial port communication routines for Unix. - Copyright (C) 1991, 1992, 1993, 1994 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1994, 1995 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -17,16 +17,16 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" #if USE_RCS_ID -const char serial_rcsid[] = "$Id: serial.c,v 1.4 1994/05/07 18:11:09 ache Exp $"; +const char serial_rcsid[] = "$Id: serial.c,v 1.65 1995/08/10 00:53:54 ian Rel $"; #endif #include "uudefs.h" @@ -82,7 +82,7 @@ const char serial_rcsid[] = "$Id: serial.c,v 1.4 1994/05/07 18:11:09 ache Exp $" #include <sys/ioctl.h> #endif -#if HAVE_BSD_TTY +#if HAVE_SELECT #if HAVE_SYS_TIME_H #include <sys/time.h> #endif @@ -92,7 +92,7 @@ const char serial_rcsid[] = "$Id: serial.c,v 1.4 1994/05/07 18:11:09 ache Exp $" #endif #if HAVE_TIME_H -#if ! HAVE_SYS_TIME_H || ! HAVE_BSD_TTY || TIME_WITH_SYS_TIME +#if ! HAVE_SYS_TIME_H || ! HAVE_SELECT || TIME_WITH_SYS_TIME #include <time.h> #endif #endif @@ -517,6 +517,9 @@ boolean fsysdep_stdin_init (qconn) struct sconnection *qconn; { + /* chmod /dev/tty to prevent other users from writing messages to + it. This is essentially `mesg n'. */ + (void) chmod ("/dev/tty", S_IRUSR | S_IWUSR); return fsserial_init (qconn, &sstdincmds, (const char *) NULL); } @@ -647,7 +650,7 @@ fsserial_lockfile (flok, qconn) strerror (errno)); return FALSE; } - zalc = zbufalc (sizeof "LK.123.123.123"); + zalc = zbufalc (sizeof "LK.1234567890.1234567890.1234567890"); sprintf (zalc, "LK.%03d.%03d.%03d", major (s.st_dev), major (s.st_rdev), minor (s.st_rdev)); z = zalc; @@ -860,7 +863,7 @@ fsserial_unlock (qconn) } qsysdep->o = -1; } - + if (! fsserial_lockfile (FALSE, qconn)) fret = FALSE; @@ -1748,7 +1751,7 @@ fsmodem_carrier (qconn, fcarrier) return FALSE; #ifdef TIOCNCAR - /* Tell the modem to ignore carrier. */ + /* Tell the modem to ignore carrier. */ if (ioctl (q->o, TIOCNCAR, 0) < 0) { ulog (LOG_ERROR, "ioctl (TIOCNCAR): %s", strerror (errno)); @@ -1782,19 +1785,19 @@ fsmodem_carrier (qconn, fcarrier) ulog (LOG_ERROR, "Can't set CLOCAL: %s", strerror (errno)); return FALSE; } - + #if HAVE_CLOCAL_BUG /* On SCO and AT&T UNIX PC you have to reopen the port. */ { int onew; - + onew = open (q->zdevice, O_RDWR); if (onew < 0) { ulog (LOG_ERROR, "open (%s): %s", q->zdevice, strerror (errno)); return FALSE; } - + if (fcntl (onew, F_SETFD, fcntl (onew, F_GETFD, 0) | FD_CLOEXEC) < 0) { @@ -1817,8 +1820,9 @@ fsmodem_carrier (qconn, fcarrier) /* Tell the port to use hardware flow control. There is no standard mechanism for controlling this. This implementation supports CRTSCTS on SunOS, RTS/CTSFLOW on 386(ish) unix, CTSCD on the 3b1, - and TXADDCD/TXDELCD on AIX. If you know how to do it on other - systems, please implement it and send me the patches. */ + CCTS_OFLOW/CRTS_IFLOW on BSDI, TXADDCD/TXDELCD on AIX, and IRTS on + NCR Tower. If you know how to do it on other systems, please + implement it and send me the patches. */ static boolean fsserial_hardflow (qconn, fhardflow) @@ -1841,12 +1845,16 @@ fsserial_hardflow (qconn, fhardflow) #ifndef CRTSFL #ifndef CRTSCTS #ifndef CTSCD +#ifndef CCTS_OFLOW +#ifndef IRTS #define HAVE_HARDFLOW 0 #endif #endif #endif #endif #endif +#endif +#endif #ifndef HAVE_HARDFLOW #define HAVE_HARDFLOW 1 @@ -1871,6 +1879,12 @@ fsserial_hardflow (qconn, fhardflow) #ifdef CTSCD q->snew.c_cflag |= CTSCD; #endif /* defined (CTSCD) */ +#ifdef CCTS_OFLOW + q->snew.c_cflag |= CCTS_OFLOW | CRTS_IFLOW; +#endif +#ifdef IRTS + q->snew.c_iflag |= IRTS; +#endif #endif /* HAVE_SYSV_TERMIO || HAVE_POSIX_TERMIOS */ if (! fsetterminfo (q->o, &q->snew)) { @@ -1898,6 +1912,12 @@ fsserial_hardflow (qconn, fhardflow) #ifdef CTSCD q->snew.c_cflag &=~ CTSCD; #endif /* defined (CTSCD) */ +#ifdef CCTS_OFLOW + q->snew.c_cflag &=~ (CCTS_OFLOW | CRTS_IFLOW); +#endif +#ifdef IRTS + q->snew.c_iflag &=~ IRTS; +#endif #endif /* HAVE_SYSV_TERMIO || HAVE_POSIX_TERMIOS */ if (! fsetterminfo (q->o, &q->snew)) { @@ -2001,7 +2021,7 @@ fsysdep_modem_end_dial (qconn, qdial) errors. */ { int onew; - + onew = open (q->zdevice, O_RDWR); if (onew >= 0) { @@ -2039,7 +2059,7 @@ fsysdep_modem_end_dial (qconn, qdial) #endif /* ! defined (TIOCWONLINE) */ } - return TRUE; + return TRUE; } /* Read data from a connection, with a timeout. This routine handles @@ -2562,7 +2582,10 @@ fsysdep_conn_io (qconn, zwrite, pcwrite, zread, pcread) write up to SINGLE_WRITE bytes if all data written, return if no data written - blocked write of up to SINGLE_WRITE bytes + if select works + select on the write descriptor with a ten second timeout + else + blocked write of one byte with a ten second alarm This algorithm should work whether the system supports unblocked writes on terminals or not. If the system supports @@ -2572,7 +2595,28 @@ fsysdep_conn_io (qconn, zwrite, pcwrite, zread, pcread) then the write may hang so long that incoming data is lost. This is actually possible at high baud rates on any system when a blocking write is done; there is no solution, except - hardware handshaking. */ + hardware handshaking. + + If we were not able to write any data, then we need to block + until we can write something. The code used to simply do a + blocking write. However, that fails when a bidirectional + protocol is permitted to push out enough bytes to fill the + entire pipe between the two communicating uucico processes. + They can both block on writing, because neither is reading. + + In this case, we use select. We could select on both the + read and write descriptor, but on some systems that would + lead to calling read on each byte, which would be very + inefficient. Instead, we select only on the write + descriptor. After the select succeeds or times out, we retry + the read. + + Of course, some systems don't have select, and on some + systems that have it it doesn't work on terminal devices. If + we can't use select, then we do a blocked write of a single + byte after setting an alarm. We only write a single byte to + avoid any confusion as to whether or not the byte was + actually written. */ /* If we are running on standard input, we switch the file descriptors by hand. */ @@ -2717,38 +2761,105 @@ fsysdep_conn_io (qconn, zwrite, pcwrite, zread, pcread) } else { - /* We didn't write any data. Do a blocking write. */ - - if (q->ord >= 0) - q->o = q->ord; +#if HAVE_SELECT + struct timeval stime; + int imask; + int c; + + /* We didn't write any data. Call select. We use a timeout + long enough for 1024 bytes to be sent. + secs/kbyte == (1024 bytes/kbyte * 10 bits/byte) / baud bits/sec + usecs/kbyte == (((1024 bytes/kbyte * 1000000 usecs/sec) + / baud bits/sec) + * 10 bits/byte) + */ + stime.tv_sec = (long) 10240 / q->ibaud; + stime.tv_usec = ((((long) 1024000000 / q->ibaud) * (long) 10) + % (long) 1000000); + + imask = 1 << q->o; + if (imask == 0) + ulog (LOG_FATAL, "fsysdep_conn_io: File descriptors too large"); - if (! fsblock (q, TRUE)) + /* If we've received a signal, don't continue. */ + if (FGOT_QUIT_SIGNAL ()) return FALSE; - cdo = cwrite; - if (cdo > SINGLE_WRITE) - cdo = SINGLE_WRITE; + DEBUG_MESSAGE0 (DEBUG_PORT, "fsysdep_conn_io: Calling select"); - DEBUG_MESSAGE1 (DEBUG_PORT, - "fsysdep_conn_io: Blocking write of %lu", - (unsigned long) cdo); + /* We don't bother to loop on EINTR. If we get a signal, we + just loop around and try the read and write again. */ + c = select (q->o + 1, (pointer) NULL, (pointer) &imask, + (pointer) NULL, &stime); + if (c < 0 && errno == EINTR) + { + /* We got interrupted by a signal. Log it. */ + ulog (LOG_ERROR, (const char *) NULL); + } + else if (c >= 0) + { + /* The select either discovered that we could write + something, or it timed out. Either way, we go around + the main read/write loop again. */ + } + else +#endif /* HAVE_SELECT */ + { + int ierr; - if (q->owr >= 0) - q->o = q->owr; + /* Either the select failed for some reason other than + EINTR, or the system does not support select at all. + Fall back on a timed write. We don't worry about why + the select might have failed, we just assume that it + will not succeed on this descriptor. */ + +#if HAVE_RESTARTABLE_SYSCALLS + /* If HAVE_RESTARTABLE_SYSCALLS, then receiving an alarm + signal in the middle of a write will not cause the + write to return EINTR, and the only way to interrupt + the write is to longjmp out of it (see sysh.unx). + That is unreliable, because it means that we won't + know whether the byte was actually written or not. + However, I believe that the only system on which we + need to do this longjmp is BSD 4.2, and that system + supports select, so we should never execute this + case. */ + ulog (LOG_FATAL, "fsysdep_conn_io: Unsupported case; see code"); +#endif + + if (q->ord >= 0) + q->o = q->ord; + + if (! fsblock (q, TRUE)) + return FALSE; + + DEBUG_MESSAGE0 (DEBUG_PORT, "fsysdep_conn_io: Blocking write"); + + if (q->owr >= 0) + q->o = q->owr; - /* Loop until we get something besides EINTR. */ - while (TRUE) - { /* If we've received a signal, don't continue. */ if (FGOT_QUIT_SIGNAL ()) return FALSE; + /* Start up an alarm to interrupt the write. Note that + we don't need to use the catch stuff, since we know + that HAVE_RESTARTABLE_SYSCALLS is 0. */ + usset_signal (SIGALRM, usalarm, TRUE, (boolean *) NULL); + alarm ((int) ((long) 10240 / q->ibaud) + 1); + + /* There is a race condition here: on a severely loaded + system, we could get the alarm before we start the + write call. This would not be a disaster; often the + write will succeed anyhow. */ #if HAVE_TLI if (q->ftli) { - cdid = t_snd (q->o, (char *) zwrite, cdo, 0); + cdid = t_snd (q->o, (char *) zwrite, 1, 0); if (cdid < 0 && t_errno != TSYSERR) { + usset_signal (SIGALRM, SIG_IGN, TRUE, (boolean *) NULL); + alarm (0); ulog (LOG_ERROR, "t_snd: %s", (t_errno >= 0 && t_errno < t_nerr ? t_errlist[t_errno] @@ -2758,44 +2869,54 @@ fsysdep_conn_io (qconn, zwrite, pcwrite, zread, pcread) } else #endif - cdid = write (q->o, zwrite, cdo); + cdid = write (q->o, zwrite, 1); - if (cdid >= 0) - break; - if (errno != EINTR) - break; + ierr = errno; - /* We got interrupted by a signal. Log it. */ - ulog (LOG_ERROR, (const char *) NULL); - } + /* Note that we don't really care whether the write + finished because the byte was written out or whether + it finished because the alarm was triggered. Either + way, we are going to loop around and try another + read. */ - if (cdid < 0) - { - ulog (LOG_ERROR, "write: %s", strerror (errno)); - return FALSE; - } + usset_signal (SIGALRM, SIG_IGN, TRUE, (boolean *) NULL); + alarm (0); - if (cdid == 0) - { - /* On some systems write will return 0 if carrier is - lost. If we fail to write anything ten times in a - row, we assume that this has happened. This is - hacked in like this because there seems to be no - reliable way to tell exactly why the write returned - 0. */ - ++czero; - if (czero >= 10) + if (cdid < 0) { - ulog (LOG_ERROR, "Line disconnected"); - return FALSE; + if (ierr == EINTR) + { + /* We got interrupted by a signal. Log it. */ + ulog (LOG_ERROR, (const char *) NULL); + } + else + { + ulog (LOG_ERROR, "write: %s", strerror (ierr)); + return FALSE; + } + } + else if (cdid == 0) + { + /* On some systems write will return 0 if carrier is + lost. If we fail to write anything ten times in + a row, we assume that this has happened. This is + hacked in like this because there seems to be no + reliable way to tell exactly why the write + returned 0. */ + ++czero; + if (czero >= 10) + { + ulog (LOG_ERROR, "Line disconnected"); + return FALSE; + } + } + else + { + cwrite -= cdid; + zwrite += cdid; + *pcwrite += cdid; + czero = 0; } - } - else - { - cwrite -= cdid; - zwrite += cdid; - *pcwrite += cdid; - czero = 0; } } } @@ -2937,7 +3058,7 @@ fsserial_set (qconn, tparity, tstrip, txonxoff) /* Not supported. */ break; } - + if (fdo) { if ((q->snew.c_cflag & iset) != iset @@ -2973,7 +3094,7 @@ fsserial_set (qconn, tparity, tstrip, txonxoff) } #endif -#else /* ! HAVE_BSD_TTY */ +#else /* ! HAVE_BSD_TTY */ fdo = FALSE; switch (tstrip) diff --git a/gnu/libexec/uucp/libunix/signal.c b/gnu/libexec/uucp/libunix/signal.c index 75016c3..6aa899b 100644 --- a/gnu/libexec/uucp/libunix/signal.c +++ b/gnu/libexec/uucp/libunix/signal.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" diff --git a/gnu/libexec/uucp/libunix/spawn.c b/gnu/libexec/uucp/libunix/spawn.c index a56fd84..d39e2ba 100644 --- a/gnu/libexec/uucp/libunix/spawn.c +++ b/gnu/libexec/uucp/libunix/spawn.c @@ -1,7 +1,7 @@ /* spawn.c Spawn a program securely. - Copyright (C) 1992, 1993, 1994 Ian Lance Taylor + Copyright (C) 1992, 1993, 1994, 1995 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -147,7 +147,7 @@ ixsspawn (pazargs, aidescs, fkeepuid, fkeepenv, zchdir, fnosigs, fshell, zspace = azenv[0] + sizeof "PATH=" - 1; while ((zspace = strchr (zspace, ' ')) != NULL) *zspace = ':'; - + azenv[1] = zbufalc (sizeof "HOME=" + strlen (zSspooldir)); sprintf (azenv[1], "HOME=%s", zSspooldir); @@ -158,7 +158,7 @@ ixsspawn (pazargs, aidescs, fkeepuid, fkeepenv, zchdir, fnosigs, fshell, sprintf (azenv[2], "TERM=%s", zterm); azenv[3] = zbufcpy ("SHELL=/bin/sh"); - + azenv[4] = zbufalc (sizeof "USER=" + strlen (OWNER)); sprintf (azenv[4], "USER=%s", OWNER); @@ -275,7 +275,7 @@ ixsspawn (pazargs, aidescs, fkeepuid, fkeepenv, zchdir, fnosigs, fshell, ierr = errno; ferr = TRUE; break; - } + } } } @@ -360,12 +360,22 @@ ixsspawn (pazargs, aidescs, fkeepuid, fkeepenv, zchdir, fnosigs, fshell, { /* Try to force the UUCP uid to be both real and effective user ID, in order to present a consistent environment regardless - of the invoking user. This won't work on System V based - systems, but it will do no harm. It would be possible to use - a setuid root program to force the UID setting, but I don't - think the efficiency loss is worth it. */ + of the invoking user. This won't work on older System V + based systems, where it can cause trouble if ordinary users + wind up executing uuxqt, perhaps via uucico; any program + which uuxqt executes will have an arbitrary real user ID, so + if the program is itself a setuid program, any security + checks it does based on the real user ID will be incorrect. + Fixing this problem would seem to require a special setuid + root program; I have not used this approach because + modern systems should not suffer from it. */ +#if HAVE_SETREUID + (void) setreuid (geteuid (), -1); + (void) setregid (getegid (), -1); +#else (void) setuid (geteuid ()); (void) setgid (getegid ()); +#endif } if (zchdir != NULL) @@ -406,7 +416,7 @@ ixsspawn (pazargs, aidescs, fkeepuid, fkeepenv, zchdir, fnosigs, fshell, { char *zto; const char *azshargs[4]; - + pazargs[0] = zcmd; zto = zshcmd; for (i = 0; pazargs[i] != NULL; i++) diff --git a/gnu/libexec/uucp/libunix/splcmd.c b/gnu/libexec/uucp/libunix/splcmd.c index 7740661..d085cee 100644 --- a/gnu/libexec/uucp/libunix/splcmd.c +++ b/gnu/libexec/uucp/libunix/splcmd.c @@ -1,7 +1,7 @@ /* splcmd.c Spool a command. - Copyright (C) 1991, 1992, 1993 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1995 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -104,31 +104,53 @@ zsysdep_spool_commands (qsys, bgrade, ccmds, pascmds) } } - if (fclose (e) != 0) + if (! fstdiosync (e, ztemp)) { - ulog (LOG_ERROR, "fclose: %s", strerror (errno)); + (void) fclose (e); (void) remove (ztemp); ubuffree (ztemp); return NULL; } - z = zscmd_file (qsys, bgrade); - if (z == NULL) + if (fclose (e) != 0) { + ulog (LOG_ERROR, "fclose: %s", strerror (errno)); (void) remove (ztemp); ubuffree (ztemp); return NULL; } - if (! fsysdep_move_file (ztemp, z, FALSE, FALSE, FALSE, - (const char *) NULL)) + /* The filename returned by zscmd_file is subject to some unlikely + race conditions, so keep trying the link until the destination + file does not already exist. Each call to zscmd_file should + return a file name which does not already exist, so we don't have + to do anything special before calling it again. */ + while (TRUE) { - (void) remove (ztemp); - ubuffree (ztemp); + z = zscmd_file (qsys, bgrade); + if (z == NULL) + { + (void) remove (ztemp); + ubuffree (ztemp); + return NULL; + } + + if (link (ztemp, z) >= 0) + break; + + if (errno != EEXIST) + { + ulog (LOG_ERROR, "link (%s, %s): %s", ztemp, z, strerror (errno)); + (void) remove (ztemp); + ubuffree (ztemp); + ubuffree (z); + return NULL; + } + ubuffree (z); - return NULL; } + (void) remove (ztemp); ubuffree (ztemp); zjobid = zsfile_to_jobid (qsys, z, bgrade); diff --git a/gnu/libexec/uucp/libunix/spool.c b/gnu/libexec/uucp/libunix/spool.c index 4eb3702..8c0a82f 100644 --- a/gnu/libexec/uucp/libunix/spool.c +++ b/gnu/libexec/uucp/libunix/spool.c @@ -17,16 +17,16 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" #if USE_RCS_ID -const char spool_rcsid[] = "$Id: spool.c,v 1.2 1994/05/07 18:11:24 ache Exp $"; +const char spool_rcsid[] = "$Id: spool.c,v 1.11 1995/06/30 21:22:54 ian Rel $"; #endif #include "uudefs.h" @@ -41,7 +41,7 @@ const char spool_rcsid[] = "$Id: spool.c,v 1.2 1994/05/07 18:11:24 ache Exp $"; Command files These contain instructions for uucico indicating what files to transfer to and from what systems. Each line of a work file is a command - beginning with S, R or X. + beginning with S, R, X, or E. #if ! SPOOLDIR_TAYLOR They are named C.ssssssgqqqq, where ssssss is the system name to transfer to or from, g is the grade and qqqq is the sequence number. @@ -55,15 +55,17 @@ const char spool_rcsid[] = "$Id: spool.c,v 1.2 1994/05/07 18:11:24 ache Exp $"; #elif SPOOLDIR_ULTRIX If the directory sys/ssssss exists, they are put in the directory sys/ssssss/C; otherwise, they are put in the directory sys/DEFAULT/C. - #endif #elif SPOOLDIR_SVR4 They are put in the directory sys/g, where sys is the system name and g is the grade. #endif #else SPOOLDIR_TAYLOR - They are named C.gqqqq, where g is the grade and qqqq is the sequence - number, and are placed in the directory ssssss/C. where ssssss is - the system name to transfer to or from. + They are named C.gqqqq, where g is the grade and qqqq is the + sequence number, and are placed in the directory ssssss/C. where + ssssss is the system name to transfer to or from. The sequence + number for a C. file is actually a long string; it is not based on + the sequence number file, but is generated via a process which + attempts to produce a unique string each time it is run. #endif Data files @@ -287,7 +289,7 @@ zsfind_file (zsimple, zsystem, bgrade) { size_t c; boolean ftruncated; - + /* D.LOCAL in D.LOCAL/, others in D./. If BSD43, D.LOCALX in D.LOCALX/. */ ftruncated = TRUE; @@ -336,7 +338,7 @@ zsfind_file (zsimple, zsystem, bgrade) char *zfree; const char *zdir; char *zret; - + /* D.LOCALX in D.LOCALX/, D.LOCAL in D.LOCAL/, others in D./. */ ftruncated = TRUE; if (strncmp (zsimple + 2, zSlocalname, strlen (zSlocalname)) == 0) @@ -380,7 +382,7 @@ zsfind_file (zsimple, zsystem, bgrade) zfree = NULL; zdir = "D."; } - + zret = zsappend4 ("sys", (fsultrix_has_spool (zsystem) ? zsystem diff --git a/gnu/libexec/uucp/libunix/srmdir.c b/gnu/libexec/uucp/libunix/srmdir.c index 7dcaa07..e143cdf 100644 --- a/gnu/libexec/uucp/libunix/srmdir.c +++ b/gnu/libexec/uucp/libunix/srmdir.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -69,7 +69,7 @@ fsysdep_rmdir (zdir) while (q != NULL) { struct sdirlist *qnext; - + if (rmdir (q->zdir) != 0) { ulog (LOG_ERROR, "rmdir (%s): %s", q->zdir, strerror (errno)); diff --git a/gnu/libexec/uucp/libunix/statsb.c b/gnu/libexec/uucp/libunix/statsb.c index a57d2a3..4fed437 100644 --- a/gnu/libexec/uucp/libunix/statsb.c +++ b/gnu/libexec/uucp/libunix/statsb.c @@ -17,16 +17,16 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" #if USE_RCS_ID -const char statsb_rcsid[] = "$Id: statsb.c,v 1.17 1994/04/10 22:06:10 ian Rel $"; +const char statsb_rcsid[] = "$Id: statsb.c,v 1.19 1995/06/21 19:20:39 ian Rel $"; #endif #include "uudefs.h" diff --git a/gnu/libexec/uucp/libunix/status.c b/gnu/libexec/uucp/libunix/status.c index a967085..66e1d385 100644 --- a/gnu/libexec/uucp/libunix/status.c +++ b/gnu/libexec/uucp/libunix/status.c @@ -1,7 +1,7 @@ /* status.c Routines to get and set the status for a system. - Copyright (C) 1991, 1992, 1993 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1995 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -31,6 +31,7 @@ #include "system.h" #include <errno.h> +#include <ctype.h> #if SPOOLDIR_HDB || SPOOLDIR_SVR4 @@ -104,6 +105,7 @@ fsysdep_get_status (qsys, qret, pfnone) qret->cretries = 0; qret->ilast = 0; qret->cwait = 0; + qret->zstring = NULL; if (pfnone != NULL) *pfnone = TRUE; ubuffree (zname); @@ -157,6 +159,33 @@ fsysdep_get_status (qsys, qret, pfnone) if (zend == znext) fbad = TRUE; + if (! fbad) + { + znext = zend; + while (isspace (BUCHAR (*znext))) + ++znext; + if (*znext == '\0') + qret->zstring = NULL; + else + { + if (*znext == '"') + ++znext; + qret->zstring = zbufcpy (znext); + zend = qret->zstring + strlen (qret->zstring); + while (zend != qret->zstring && *zend != ' ') + --zend; + if (*zend == '"' && zend != qret->zstring) + --zend; + if (zend != qret->zstring) + *zend = '\0'; + else + { + ubuffree (qret->zstring); + qret->zstring = NULL; + } + } + } + xfree ((pointer) zline); if (fbad) @@ -199,9 +228,16 @@ fsysdep_set_status (qsys, qset) istat = aiMapstatus[istat]; #endif /* MAP_STATUS */ - fprintf (e, "%d %d %ld %d %s %s\n", istat, qset->cretries, - qset->ilast, qset->cwait, azStatus[(int) qset->ttype], - qsys->uuconf_zname); + fprintf (e, "%d %d %ld %d ", istat, qset->cretries, qset->ilast, + qset->cwait); + +#if SPOOLDIR_SVR4 + fprintf (e, "\"%s\"", azStatus[(int) qset->ttype]); +#else + fprintf (e, "%s", azStatus[(int) qset->ttype]); +#endif + + fprintf (e, " %s\n", qsys->uuconf_zname); if (fclose (e) != 0) { ulog (LOG_ERROR, "fclose: %s", strerror (errno)); diff --git a/gnu/libexec/uucp/libunix/sync.c b/gnu/libexec/uucp/libunix/sync.c new file mode 100644 index 0000000..c346c58 --- /dev/null +++ b/gnu/libexec/uucp/libunix/sync.c @@ -0,0 +1,42 @@ +/* sync.c + Sync a file to disk, if FSYNC_ON_CLOSE is set. */ + +#include "uucp.h" + +#include "uudefs.h" +#include "sysdep.h" +#include "system.h" + +#include <errno.h> + +boolean +fsysdep_sync (e, zmsg) + openfile_t e; + const char *zmsg; +{ + int o; + +#if USE_STDIO + if (fflush (e) == EOF) + { + ulog (LOG_ERROR, "%s: fflush: %s", zmsg, strerror (errno)); + return FALSE; + } +#endif + +#if USE_STDIO + o = fileno (e); +#else + o = e; +#endif + +#if FSYNC_ON_CLOSE + if (fsync (o) < 0) + { + ulog (LOG_ERROR, "%s: fsync: %s", zmsg, strerror (errno)); + return FALSE; + } +#endif + + return TRUE; +} diff --git a/gnu/libexec/uucp/libunix/tcp.c b/gnu/libexec/uucp/libunix/tcp.c new file mode 100644 index 0000000..6ec39f2 --- /dev/null +++ b/gnu/libexec/uucp/libunix/tcp.c @@ -0,0 +1,444 @@ +/* tcp.c + Code to handle TCP connections. + + Copyright (C) 1991, 1992, 1993, 1995 Ian Lance Taylor + + This file is part of the Taylor UUCP package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The author of the program may be contacted at ian@airs.com or + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. + */ + +#include "uucp.h" + +#if USE_RCS_ID +const char tcp_rcsid[] = "$Id: tcp.c,v 1.5 1995/06/21 19:20:46 ian Rel $"; +#endif + +#if HAVE_TCP + +#include "uudefs.h" +#include "uuconf.h" +#include "sysdep.h" +#include "conn.h" +#include "system.h" + +#include <errno.h> + +#if HAVE_SYS_TYPES_TCP_H +#include <sys/types.tcp.h> +#endif +#include <sys/socket.h> +#include <netdb.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#if HAVE_FCNTL_H +#include <fcntl.h> +#else +#if HAVE_SYS_FILE_H +#include <sys/file.h> +#endif +#endif + +#ifndef FD_CLOEXEC +#define FD_CLOEXEC 1 +#endif + +/* This code handles TCP connections. It assumes a Berkeley socket + interface. */ + +/* The normal "uucp" port number. */ +#define IUUCP_PORT (540) + +/* Local functions. */ +static void utcp_free P((struct sconnection *qconn)); +static boolean ftcp_open P((struct sconnection *qconn, long ibaud, + boolean fwait)); +static boolean ftcp_close P((struct sconnection *qconn, + pointer puuconf, + struct uuconf_dialer *qdialer, + boolean fsuccess)); +static boolean ftcp_dial P((struct sconnection *qconn, pointer puuconf, + const struct uuconf_system *qsys, + const char *zphone, + struct uuconf_dialer *qdialer, + enum tdialerfound *ptdialer)); +static int itcp_port_number P((const char *zport)); + +/* The command table for a TCP connection. */ +static const struct sconncmds stcpcmds = +{ + utcp_free, + NULL, /* pflock */ + NULL, /* pfunlock */ + ftcp_open, + ftcp_close, + ftcp_dial, + fsysdep_conn_read, + fsysdep_conn_write, + fsysdep_conn_io, + NULL, /* pfbreak */ + NULL, /* pfset */ + NULL, /* pfcarrier */ + fsysdep_conn_chat, + NULL /* pibaud */ +}; + +/* Initialize a TCP connection. */ + +boolean +fsysdep_tcp_init (qconn) + struct sconnection *qconn; +{ + struct ssysdep_conn *q; + + q = (struct ssysdep_conn *) xmalloc (sizeof (struct ssysdep_conn)); + q->o = -1; + q->ord = -1; + q->owr = -1; + q->zdevice = NULL; + q->iflags = -1; + q->iwr_flags = -1; + q->fterminal = FALSE; + q->ftli = FALSE; + q->ibaud = 0; + + qconn->psysdep = (pointer) q; + qconn->qcmds = &stcpcmds; + return TRUE; +} + +/* Free a TCP connection. */ + +static void +utcp_free (qconn) + struct sconnection *qconn; +{ + xfree (qconn->psysdep); +} + +/* Open a TCP connection. If the fwait argument is TRUE, we are + running as a server. Otherwise we are just trying to reach another + system. */ + +static boolean +ftcp_open (qconn, ibaud, fwait) + struct sconnection *qconn; + long ibaud; + boolean fwait; +{ + struct ssysdep_conn *qsysdep; + struct sockaddr_in s; + const char *zport; + uid_t ieuid; + boolean fswap; + + ulog_device ("TCP"); + + qsysdep = (struct ssysdep_conn *) qconn->psysdep; + + qsysdep->o = socket (AF_INET, SOCK_STREAM, 0); + if (qsysdep->o < 0) + { + ulog (LOG_ERROR, "socket: %s", strerror (errno)); + return FALSE; + } + + if (fcntl (qsysdep->o, F_SETFD, + fcntl (qsysdep->o, F_GETFD, 0) | FD_CLOEXEC) < 0) + { + ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno)); + (void) close (qsysdep->o); + qsysdep->o = -1; + return FALSE; + } + + qsysdep->iflags = fcntl (qsysdep->o, F_GETFL, 0); + if (qsysdep->iflags < 0) + { + ulog (LOG_ERROR, "fcntl: %s", strerror (errno)); + (void) close (qsysdep->o); + qsysdep->o = -1; + return FALSE; + } + + /* We save our process ID in the qconn structure. This is checked + in ftcp_close. */ + qsysdep->ipid = getpid (); + + /* If we aren't waiting for a connection, we're done. */ + if (! fwait) + return TRUE; + + /* Run as a server and wait for a new connection. The code in + uucico.c has already detached us from our controlling terminal. + From this point on if the server gets an error we exit; we only + return if we have received a connection. It would be more robust + to respawn the server if it fails; someday. */ + bzero ((pointer) &s, sizeof s); + s.sin_family = AF_INET; + zport = qconn->qport->uuconf_u.uuconf_stcp.uuconf_zport; + s.sin_port = itcp_port_number (zport); + s.sin_addr.s_addr = htonl (INADDR_ANY); + + /* Swap to our real user ID when doing the bind call. This will + permit the server to use privileged TCP ports when invoked by + root. We only swap if our effective user ID is not root, so that + the program can also be made suid root in order to get privileged + ports when invoked by anybody. */ + fswap = geteuid () != 0; + if (fswap) + { + if (! fsuser_perms (&ieuid)) + { + (void) close (qsysdep->o); + qsysdep->o = -1; + return FALSE; + } + } + + if (bind (qsysdep->o, (struct sockaddr *) &s, sizeof s) < 0) + { + if (fswap) + (void) fsuucp_perms ((long) ieuid); + ulog (LOG_FATAL, "bind: %s", strerror (errno)); + } + + /* Now swap back to the uucp user ID. */ + if (fswap) + { + if (! fsuucp_perms ((long) ieuid)) + ulog (LOG_FATAL, "Could not swap back to UUCP user permissions"); + } + + if (listen (qsysdep->o, 5) < 0) + ulog (LOG_FATAL, "listen: %s", strerror (errno)); + + while (! FGOT_SIGNAL ()) + { + size_t clen; + int onew; + pid_t ipid; + + DEBUG_MESSAGE0 (DEBUG_PORT, + "ftcp_open: Waiting for connections"); + + clen = sizeof s; + onew = accept (qsysdep->o, (struct sockaddr *) &s, &clen); + if (onew < 0) + ulog (LOG_FATAL, "accept: %s", strerror (errno)); + + DEBUG_MESSAGE0 (DEBUG_PORT, + "ftcp_open: Got connection; forking"); + + ipid = ixsfork (); + if (ipid < 0) + ulog (LOG_FATAL, "fork: %s", strerror (errno)); + if (ipid == 0) + { + (void) close (qsysdep->o); + qsysdep->o = onew; + + /* Now we fork and let our parent die, so that we become + a child of init. This lets the main server code wait + for its child and then continue without accumulating + zombie children. */ + ipid = ixsfork (); + if (ipid < 0) + { + ulog (LOG_ERROR, "fork: %s", strerror (errno)); + _exit (EXIT_FAILURE); + } + + if (ipid != 0) + _exit (EXIT_SUCCESS); + + ulog_id (getpid ()); + + return TRUE; + } + + (void) close (onew); + + /* Now wait for the child. */ + (void) ixswait ((unsigned long) ipid, (const char *) NULL); + } + + /* We got a signal. */ + usysdep_exit (FALSE); + + /* Avoid compiler warnings. */ + return FALSE; +} + +/* Close the port. */ + +/*ARGSUSED*/ +static boolean +ftcp_close (qconn, puuconf, qdialer, fsuccess) + struct sconnection *qconn; + pointer puuconf; + struct uuconf_dialer *qdialer; + boolean fsuccess; +{ + struct ssysdep_conn *qsysdep; + boolean fret; + + qsysdep = (struct ssysdep_conn *) qconn->psysdep; + fret = TRUE; + if (qsysdep->o >= 0 && close (qsysdep->o) < 0) + { + ulog (LOG_ERROR, "close: %s", strerror (errno)); + fret = FALSE; + } + qsysdep->o = -1; + + /* If the current pid is not the one we used to open the port, then + we must have forked up above and we are now the child. In this + case, we are being called from within the fendless loop in + uucico.c. We return FALSE to force the loop to end and the child + to exit. This should be handled in a cleaner fashion. */ + if (qsysdep->ipid != getpid ()) + fret = FALSE; + + return fret; +} + +/* Dial out on a TCP port, so to speak: connect to a remote computer. */ + +/*ARGSUSED*/ +static boolean +ftcp_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialer) + struct sconnection *qconn; + pointer puuconf; + const struct uuconf_system *qsys; + const char *zphone; + struct uuconf_dialer *qdialer; + enum tdialerfound *ptdialer; +{ + struct ssysdep_conn *qsysdep; + const char *zhost; + struct hostent *q; + struct sockaddr_in s; + const char *zport; + char **pzdialer; + + qsysdep = (struct ssysdep_conn *) qconn->psysdep; + + *ptdialer = DIALERFOUND_FALSE; + + zhost = zphone; + if (zhost == NULL) + { + if (qsys == NULL) + { + ulog (LOG_ERROR, "No address for TCP connection"); + return FALSE; + } + zhost = qsys->uuconf_zname; + } + + errno = 0; + q = gethostbyname ((char *) zhost); + if (q != NULL) + { + s.sin_family = q->h_addrtype; + memcpy (&s.sin_addr.s_addr, q->h_addr, (size_t) q->h_length); + } + else + { + if (errno != 0) + { + ulog (LOG_ERROR, "gethostbyname (%s): %s", zhost, strerror (errno)); + return FALSE; + } + + s.sin_family = AF_INET; + s.sin_addr.s_addr = inet_addr ((char *) zhost); + if ((long) s.sin_addr.s_addr == (long) -1) + { + ulog (LOG_ERROR, "%s: unknown host name", zhost); + return FALSE; + } + } + + zport = qconn->qport->uuconf_u.uuconf_stcp.uuconf_zport; + s.sin_port = itcp_port_number (zport); + + if (connect (qsysdep->o, (struct sockaddr *) &s, sizeof s) < 0) + { + ulog (LOG_ERROR, "connect: %s", strerror (errno)); + return FALSE; + } + + /* Handle the dialer sequence, if any. */ + pzdialer = qconn->qport->uuconf_u.uuconf_stcp.uuconf_pzdialer; + if (pzdialer != NULL && *pzdialer != NULL) + { + if (! fconn_dial_sequence (qconn, puuconf, pzdialer, qsys, zphone, + qdialer, ptdialer)) + return FALSE; + } + + return TRUE; +} + +/* Get the port number given a name. The argument will almost always + be "uucp" so we cache that value. The return value is always in + network byte order. This returns -1 on error. */ + +static int +itcp_port_number (zname) + const char *zname; +{ + boolean fuucp; + static int iuucp; + int i; + char *zend; + struct servent *q; + + fuucp = strcmp (zname, "uucp") == 0; + if (fuucp && iuucp != 0) + return iuucp; + + /* Try it as a number first. */ + i = strtol ((char *) zname, &zend, 10); + if (i != 0 && *zend == '\0') + return htons (i); + + q = getservbyname ((char *) zname, (char *) "tcp"); + if (q == NULL) + { + /* We know that the "uucp" service should be 540, even if isn't + in /etc/services. */ + if (fuucp) + { + iuucp = htons (IUUCP_PORT); + return iuucp; + } + ulog (LOG_ERROR, "getservbyname (%s): %s", zname, strerror (errno)); + return -1; + } + + if (fuucp) + iuucp = q->s_port; + + return q->s_port; +} + +#endif /* HAVE_TCP */ diff --git a/gnu/libexec/uucp/libunix/tli.c b/gnu/libexec/uucp/libunix/tli.c new file mode 100644 index 0000000..3e546c8 --- /dev/null +++ b/gnu/libexec/uucp/libunix/tli.c @@ -0,0 +1,628 @@ +/* tli.c + Code to handle TLI connections. + + Copyright (C) 1992, 1993, 1994 Ian Lance Taylor + + This file is part of the Taylor UUCP package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The author of the program may be contacted at ian@airs.com or + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. + */ + +#include "uucp.h" + +#if USE_RCS_ID +const char tli_rcsid[] = "$Id: tli.c,v 1.4 1995/06/21 19:20:50 ian Rel $"; +#endif + +#if HAVE_TLI + +#include "sysdep.h" +#include "uudefs.h" +#include "uuconf.h" +#include "conn.h" +#include "system.h" + +#include <errno.h> + +#if HAVE_SYS_IOCTL_H +#include <sys/ioctl.h> +#endif + +#if HAVE_TIUSER_H +#include <tiuser.h> +#else +#if HAVE_XTI_H +#include <xti.h> +#else +#if HAVE_SYS_TLI_H +#include <sys/tli.h> +#endif +#endif +#endif + +#if HAVE_STROPTS_H +#include <stropts.h> +#endif + +#if HAVE_FCNTL_H +#include <fcntl.h> +#else +#if HAVE_SYS_FILE_H +#include <sys/file.h> +#endif +#endif + +#ifndef O_RDONLY +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 +#endif + +#ifndef FD_CLOEXEC +#define FD_CLOEXEC 1 +#endif + +/* The arguments to t_alloca have two different names. I want the + SVID ones, not the XPG3 ones. */ +#ifndef T_BIND +#define T_BIND T_BIND_STR +#endif +#ifndef T_CALL +#define T_CALL T_CALL_STR +#endif + +/* Hopefully these externs will not cause any trouble. This is how + they are shown in the SVID. */ +extern int t_errno; +extern char *t_errlist[]; +extern int t_nerr; + +#ifndef HAVE_TIUSER_H +#ifndef t_alloc +extern pointer t_alloc (); +#endif +#endif + +/* This code handles TLI connections. It's Unix specific. It's + largely based on code from Unix Network Programming, by W. Richard + Stevens. */ + +/* Local functions. */ +static const char *ztlierror P((void)); +static void utli_free P((struct sconnection *qconn)); +static boolean ftli_push P((struct sconnection *qconn)); +static boolean ftli_open P((struct sconnection *qconn, long ibaud, + boolean fwait)); +static boolean ftli_close P((struct sconnection *qconn, + pointer puuconf, + struct uuconf_dialer *qdialer, + boolean fsuccess)); +static boolean ftli_dial P((struct sconnection *qconn, pointer puuconf, + const struct uuconf_system *qsys, + const char *zphone, + struct uuconf_dialer *qdialer, + enum tdialerfound *ptdialer)); + +/* The command table for a TLI connection. */ +static const struct sconncmds stlicmds = +{ + utli_free, + NULL, /* pflock */ + NULL, /* pfunlock */ + ftli_open, + ftli_close, + ftli_dial, + fsysdep_conn_read, + fsysdep_conn_write, + fsysdep_conn_io, + NULL, /* pfbreak */ + NULL, /* pfset */ + NULL, /* pfcarrier */ + fsysdep_conn_chat, + NULL /* pibaud */ +}; + +/* Get a TLI error string. */ + +static const char * +ztlierror () +{ + if (t_errno == TSYSERR) + return strerror (errno); + if (t_errno < 0 || t_errno >= t_nerr) + return "Unknown TLI error"; + return t_errlist[t_errno]; +} + +/* Initialize a TLI connection. This may be called with qconn->qport + NULL, when opening standard input as a TLI connection. */ + +boolean +fsysdep_tli_init (qconn) + struct sconnection *qconn; +{ + struct ssysdep_conn *q; + + q = (struct ssysdep_conn *) xmalloc (sizeof (struct ssysdep_conn)); + q->o = -1; + q->ord = -1; + q->owr = -1; + q->zdevice = NULL; + q->iflags = -1; + q->iwr_flags = -1; + q->fterminal = FALSE; + q->ftli = TRUE; + q->ibaud = 0; + + qconn->psysdep = (pointer) q; + qconn->qcmds = &stlicmds; + return TRUE; +} + +/* Free a TLI connection. */ + +static void +utli_free (qconn) + struct sconnection *qconn; +{ + xfree (qconn->psysdep); +} + +/* Push all desired modules onto a TLI stream. If the user requests a + STREAMS connection without giving a list of modules, we just push + tirdwr. If the I_PUSH ioctl is not defined on this system, we just + ignore any list of modules. */ + +static boolean +ftli_push (qconn) + struct sconnection *qconn; +{ +#ifdef I_PUSH + + struct ssysdep_conn *qsysdep; + + qsysdep = (struct ssysdep_conn *) qconn->psysdep; + + if (qconn->qport->uuconf_u.uuconf_stli.uuconf_pzpush != NULL) + { + char **pz; + + for (pz = qconn->qport->uuconf_u.uuconf_stli.uuconf_pzpush; + *pz != NULL; + pz++) + { + if (ioctl (qsysdep->o, I_PUSH, *pz) < 0) + { + ulog (LOG_ERROR, "ioctl (I_PUSH, %s): %s", *pz, + strerror (errno)); + return FALSE; + } + } + } + else if (qconn->qport->uuconf_u.uuconf_stli.uuconf_fstream) + { + if (ioctl (qsysdep->o, I_PUSH, "tirdwr") < 0) + { + ulog (LOG_ERROR, "ioctl (I_PUSH, tirdwr): %s", + strerror (errno)); + return FALSE; + } + } + + /* If we have just put the connection into stream mode, we must turn + off the TLI flag to avoid using TLI calls on it. */ + if (qconn->qport->uuconf_u.uuconf_stli.uuconf_fstream) + qsysdep->ftli = FALSE; + +#endif /* defined (I_PUSH) */ + + return TRUE; +} + +/* Open a TLI connection. If the fwait argument is TRUE, we are + running as a server. Otherwise we are just trying to reach another + system. */ + +static boolean +ftli_open (qconn, ibaud, fwait) + struct sconnection *qconn; + long ibaud; + boolean fwait; +{ + struct ssysdep_conn *qsysdep; + const char *zdevice; + char *zfreedev; + const char *zservaddr; + char *zfreeaddr; + uid_t ieuid; + boolean fswap; + struct t_bind *qtbind; + struct t_call *qtcall; + + /* Unlike most other device types, we don't bother to call + ulog_device here, because fconn_open calls it with the name of + the port anyhow. */ + + qsysdep = (struct ssysdep_conn *) qconn->psysdep; + + zdevice = qconn->qport->uuconf_u.uuconf_stli.uuconf_zdevice; + if (zdevice == NULL) + zdevice = qconn->qport->uuconf_zname; + + zfreedev = NULL; + if (*zdevice != '/') + { + zfreedev = zbufalc (sizeof "/dev/" + strlen (zdevice)); + sprintf (zfreedev, "/dev/%s", zdevice); + zdevice = zfreedev; + } + + /* If we are acting as a server, swap to our real user ID before + calling t_open. This will permit the server to use privileged + TCP ports when invoked by root. We only swap if our effective + user ID is not root, so that the program can also be made suid + root in order to get privileged ports when invoked by anybody. */ + fswap = fwait && geteuid () != 0; + if (fswap) + { + if (! fsuser_perms (&ieuid)) + { + ubuffree (zfreedev); + return FALSE; + } + } + + qsysdep->o = t_open (zdevice, O_RDWR, (struct t_info *) NULL); + if (qsysdep->o < 0) + { + if (fswap) + (void) fsuucp_perms ((long) ieuid); + ulog (LOG_ERROR, "t_open (%s): %s", zdevice, ztlierror ()); + ubuffree (zfreedev); + return FALSE; + } + + if (fcntl (qsysdep->o, F_SETFD, + fcntl (qsysdep->o, F_GETFD, 0) | FD_CLOEXEC) < 0) + { + if (fswap) + (void) fsuucp_perms ((long) ieuid); + ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno)); + ubuffree (zfreedev); + (void) t_close (qsysdep->o); + qsysdep->o = -1; + return FALSE; + } + + qsysdep->iflags = fcntl (qsysdep->o, F_GETFL, 0); + if (qsysdep->iflags < 0) + { + if (fswap) + (void) fsuucp_perms ((long) ieuid); + ulog (LOG_ERROR, "fcntl: %s", strerror (errno)); + ubuffree (zfreedev); + (void) t_close (qsysdep->o); + qsysdep->o = -1; + return FALSE; + } + + /* We save our process ID in the qconn structure. This is checked + in ftli_close. */ + qsysdep->ipid = getpid (); + + /* If we aren't waiting for a connection, we can bind to any local + address, and then we're finished. */ + if (! fwait) + { + /* fswap is known to be FALSE here. */ + ubuffree (zfreedev); + if (t_bind (qsysdep->o, (struct t_bind *) NULL, + (struct t_bind *) NULL) < 0) + { + ulog (LOG_ERROR, "t_bind: %s", ztlierror ()); + (void) t_close (qsysdep->o); + qsysdep->o = -1; + return FALSE; + } + return TRUE; + } + + /* Run as a server and wait for a new connection. The code in + uucico.c has already detached us from our controlling terminal. + From this point on if the server gets an error we exit; we only + return if we have received a connection. It would be more robust + to respawn the server if it fails; someday. */ + qtbind = (struct t_bind *) t_alloc (qsysdep->o, T_BIND, T_ALL); + if (qtbind == NULL) + { + if (fswap) + (void) fsuucp_perms ((long) ieuid); + ulog (LOG_FATAL, "t_alloc (T_BIND): %s", ztlierror ()); + } + + zservaddr = qconn->qport->uuconf_u.uuconf_stli.uuconf_zservaddr; + if (zservaddr == NULL) + { + if (fswap) + (void) fsuucp_perms ((long) ieuid); + ulog (LOG_FATAL, "Can't run as TLI server; no server address"); + } + + zfreeaddr = zbufcpy (zservaddr); + qtbind->addr.len = cescape (zfreeaddr); + if (qtbind->addr.len > qtbind->addr.maxlen) + { + if (fswap) + (void) fsuucp_perms ((long) ieuid); + ulog (LOG_FATAL, "%s: TLI server address too long (max %d)", + zservaddr, qtbind->addr.maxlen); + } + memcpy (qtbind->addr.buf, zfreeaddr, qtbind->addr.len); + ubuffree (zfreeaddr); + + qtbind->qlen = 5; + + if (t_bind (qsysdep->o, qtbind, (struct t_bind *) NULL) < 0) + { + if (fswap) + (void) fsuucp_perms ((long) ieuid); + ulog (LOG_FATAL, "t_bind (%s): %s", zservaddr, ztlierror ()); + } + + if (fswap) + { + if (! fsuucp_perms ((long) ieuid)) + ulog (LOG_FATAL, "Could not swap back to UUCP user permissions"); + } + + (void) t_free ((pointer) qtbind, T_BIND); + + qtcall = (struct t_call *) t_alloc (qsysdep->o, T_CALL, T_ALL); + if (qtcall == NULL) + ulog (LOG_FATAL, "t_alloc (T_CALL): %s", ztlierror ()); + + while (! FGOT_SIGNAL ()) + { + int onew; + pid_t ipid; + + DEBUG_MESSAGE0 (DEBUG_PORT, + "ftli_open: Waiting for connections"); + + if (t_listen (qsysdep->o, qtcall) < 0) + ulog (LOG_FATAL, "t_listen: %s", ztlierror ()); + + onew = t_open (zdevice, O_RDWR, (struct t_info *) NULL); + if (onew < 0) + ulog (LOG_FATAL, "t_open (%s): %s", zdevice, ztlierror ()); + + if (fcntl (onew, F_SETFD, + fcntl (onew, F_GETFD, 0) | FD_CLOEXEC) < 0) + ulog (LOG_FATAL, "fcntl (FD_CLOEXEC): %s", strerror (errno)); + + if (t_bind (onew, (struct t_bind *) NULL, (struct t_bind *) NULL) < 0) + ulog (LOG_FATAL, "t_bind: %s", ztlierror ()); + + if (t_accept (qsysdep->o, onew, qtcall) < 0) + { + /* We may have received a disconnect. */ + if (t_errno != TLOOK) + ulog (LOG_FATAL, "t_accept: %s", ztlierror ()); + if (t_rcvdis (qsysdep->o, (struct t_discon *) NULL) < 0) + ulog (LOG_FATAL, "t_rcvdis: %s", ztlierror ()); + (void) t_close (onew); + continue; + } + + DEBUG_MESSAGE0 (DEBUG_PORT, + "ftli_open: Got connection; forking"); + + ipid = ixsfork (); + if (ipid < 0) + ulog (LOG_FATAL, "fork: %s", strerror (errno)); + if (ipid == 0) + { + ulog_close (); + + (void) t_close (qsysdep->o); + qsysdep->o = onew; + + /* Push any desired modules. */ + if (! ftli_push (qconn)) + _exit (EXIT_FAILURE); + + /* Now we fork and let our parent die, so that we become + a child of init. This lets the main server code wait + for its child and then continue without accumulating + zombie children. */ + ipid = ixsfork (); + if (ipid < 0) + { + ulog (LOG_ERROR, "fork: %s", strerror (errno)); + _exit (EXIT_FAILURE); + } + + if (ipid != 0) + _exit (EXIT_SUCCESS); + + ulog_id (getpid ()); + + return TRUE; + } + + (void) t_close (onew); + + /* Now wait for the child. */ + (void) ixswait ((unsigned long) ipid, (const char *) NULL); + } + + /* We got a signal. */ + usysdep_exit (FALSE); + + /* Avoid compiler warnings. */ + return FALSE; +} + +/* Close the port. */ + +/*ARGSUSED*/ +static boolean +ftli_close (qconn, puuconf, qdialer, fsuccess) + struct sconnection *qconn; + pointer puuconf; + struct uuconf_dialer *qdialer; + boolean fsuccess; +{ + struct ssysdep_conn *qsysdep; + boolean fret; + + qsysdep = (struct ssysdep_conn *) qconn->psysdep; + + fret = TRUE; + if (qsysdep->o >= 0) + { + if (qsysdep->ftli) + { + if (t_close (qsysdep->o) < 0) + { + ulog (LOG_ERROR, "t_close: %s", ztlierror ()); + fret = FALSE; + } + } + else + { + if (close (qsysdep->o) < 0) + { + ulog (LOG_ERROR, "close: %s", strerror (errno)); + fret = FALSE; + } + } + + qsysdep->o = -1; + } + + /* If the current pid is not the one we used to open the port, then + we must have forked up above and we are now the child. In this + case, we are being called from within the fendless loop in + uucico.c. We return FALSE to force the loop to end and the child + to exit. This should be handled in a cleaner fashion. */ + if (qsysdep->ipid != getpid ()) + fret = FALSE; + + return fret; +} + +/* Dial out on a TLI port, so to speak: connect to a remote computer. */ + +/*ARGSUSED*/ +static boolean +ftli_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialerfound) + struct sconnection *qconn; + pointer puuconf; + const struct uuconf_system *qsys; + const char *zphone; + struct uuconf_dialer *qdialer; + enum tdialerfound *ptdialerfound; +{ + struct ssysdep_conn *qsysdep; + char **pzdialer; + const char *zaddr; + struct t_call *qtcall; + char *zescape; + + qsysdep = (struct ssysdep_conn *) qconn->psysdep; + + *ptdialerfound = DIALERFOUND_FALSE; + + pzdialer = qconn->qport->uuconf_u.uuconf_stli.uuconf_pzdialer; + if (*pzdialer == NULL) + pzdialer = NULL; + + /* If the first dialer is "TLI" or "TLIS", we use the first token + (pzdialer[1]) as the address to connect to. */ + zaddr = zphone; + if (pzdialer != NULL + && (strcmp (pzdialer[0], "TLI") == 0 + || strcmp (pzdialer[0], "TLIS") == 0)) + { + if (pzdialer[1] == NULL) + ++pzdialer; + else + { + if (strcmp (pzdialer[1], "\\D") != 0 + && strcmp (pzdialer[1], "\\T") != 0) + zaddr = pzdialer[1]; + pzdialer += 2; + } + } + + if (zaddr == NULL) + { + ulog (LOG_ERROR, "No address for TLI connection"); + return FALSE; + } + + qtcall = (struct t_call *) t_alloc (qsysdep->o, T_CALL, T_ADDR); + if (qtcall == NULL) + { + ulog (LOG_ERROR, "t_alloc (T_CALL): %s", ztlierror ()); + return FALSE; + } + + zescape = zbufcpy (zaddr); + qtcall->addr.len = cescape (zescape); + if (qtcall->addr.len > qtcall->addr.maxlen) + { + ulog (LOG_ERROR, "%s: TLI address too long (max %d)", zaddr, + qtcall->addr.maxlen); + ubuffree (zescape); + return FALSE; + } + memcpy (qtcall->addr.buf, zescape, qtcall->addr.len); + ubuffree (zescape); + + if (t_connect (qsysdep->o, qtcall, (struct t_call *) NULL) < 0) + { + if (t_errno != TLOOK) + ulog (LOG_ERROR, "t_connect: %s", ztlierror ()); + else + { + if (t_rcvdis (qsysdep->o, (struct t_discon *) NULL) < 0) + ulog (LOG_ERROR, "t_rcvdis: %s", ztlierror ()); + else + ulog (LOG_ERROR, "Connection refused"); + } + return FALSE; + } + + /* We've connected to the remote. Push any desired modules. */ + if (! ftli_push (qconn)) + return FALSE; + + /* Handle the rest of the dialer sequence. */ + if (pzdialer != NULL && *pzdialer != NULL) + { + if (! fconn_dial_sequence (qconn, puuconf, pzdialer, qsys, zphone, + qdialer, ptdialerfound)) + return FALSE; + } + + return TRUE; +} + +#endif /* HAVE_TLI */ diff --git a/gnu/libexec/uucp/libunix/tmpfil.c b/gnu/libexec/uucp/libunix/tmpfil.c index b10e809..f2f5ba8 100644 --- a/gnu/libexec/uucp/libunix/tmpfil.c +++ b/gnu/libexec/uucp/libunix/tmpfil.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" diff --git a/gnu/libexec/uucp/libunix/uacces.c b/gnu/libexec/uucp/libunix/uacces.c index d99ead3..8f37a8e 100644 --- a/gnu/libexec/uucp/libunix/uacces.c +++ b/gnu/libexec/uucp/libunix/uacces.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" diff --git a/gnu/libexec/uucp/libunix/ufopen.c b/gnu/libexec/uucp/libunix/ufopen.c index 76ee1d1..d79d9a0 100644 --- a/gnu/libexec/uucp/libunix/ufopen.c +++ b/gnu/libexec/uucp/libunix/ufopen.c @@ -1,7 +1,7 @@ /* ufopen.c Open a file with the permissions of the invoking user. - Copyright (C) 1992 Ian Lance Taylor + Copyright (C) 1992, 1995 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -53,89 +53,6 @@ #define FD_CLOEXEC 1 #endif -/* Local functions. */ - -static boolean fsuser_perms P((uid_t *pieuid)); -static boolean fsuucp_perms P((long ieuid)); - -/* Switch to permissions of the invoking user. */ - -static boolean -fsuser_perms (pieuid) - uid_t *pieuid; -{ - uid_t ieuid, iuid; - - ieuid = geteuid (); - iuid = getuid (); - if (pieuid != NULL) - *pieuid = ieuid; - -#if HAVE_SETREUID - /* Swap the effective user id and the real user id. We can then - swap them back again when we want to return to the uucp user's - permissions. */ - if (setreuid (ieuid, iuid) < 0) - { - ulog (LOG_ERROR, "setreuid (%ld, %ld): %s", - (long) ieuid, (long) iuid, strerror (errno)); - return FALSE; - } -#else /* ! HAVE_SETREUID */ -#if HAVE_SAVED_SETUID - /* Set the effective user id to the real user id. Since the - effective user id is saved (it's the saved setuid) we will able - to set back to it later. If the real user id is root we will not - be able to switch back and forth, so don't even try. */ - if (iuid != 0) - { - if (setuid (iuid) < 0) - { - ulog (LOG_ERROR, "setuid (%ld): %s", (long) iuid, strerror (errno)); - return FALSE; - } - } -#else /* ! HAVE_SAVED_SETUID */ - /* There's no way to switch between real permissions and effective - permissions. Just try to open the file with the uucp - permissions. */ -#endif /* ! HAVE_SAVED_SETUID */ -#endif /* ! HAVE_SETREUID */ - - return TRUE; -} - -/* Restore the uucp permissions. */ - -/*ARGSUSED*/ -static boolean -fsuucp_perms (ieuid) - long ieuid; -{ -#if HAVE_SETREUID - /* Swap effective and real user id's back to what they were. */ - if (! fsuser_perms ((uid_t *) NULL)) - return FALSE; -#else /* ! HAVE_SETREUID */ -#if HAVE_SAVED_SETUID - /* Set ourselves back to our original effective user id. */ - if (setuid ((uid_t) ieuid) < 0) - { - ulog (LOG_ERROR, "setuid (%ld): %s", (long) ieuid, strerror (errno)); - /* Is this error message helpful or confusing? */ - if (errno == EPERM) - ulog (LOG_ERROR, - "Probably HAVE_SAVED_SETUID in policy.h should be set to 0"); - return FALSE; - } -#else /* ! HAVE_SAVED_SETUID */ - /* We didn't switch, no need to switch back. */ -#endif /* ! HAVE_SAVED_SETUID */ -#endif /* ! HAVE_SETREUID */ - - return TRUE; -} - /* Open a file with the permissions of the invoking user. Ignore the fbinary argument since Unix has no distinction between text and binary files. */ diff --git a/gnu/libexec/uucp/libunix/uid.c b/gnu/libexec/uucp/libunix/uid.c new file mode 100644 index 0000000..b93e2a9 --- /dev/null +++ b/gnu/libexec/uucp/libunix/uid.c @@ -0,0 +1,109 @@ +/* uid.c + Switch back and forth between UUCP and user permissions. + + Copyright (C) 1992, 1995 Ian Lance Taylor + + This file is part of the Taylor UUCP package. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The author of the program may be contacted at ian@airs.com or + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. + */ + +#include "uucp.h" + +#include "uudefs.h" +#include "sysdep.h" + +#include <errno.h> + +/* Switch to permissions of the invoking user. */ + +boolean +fsuser_perms (pieuid) + uid_t *pieuid; +{ + uid_t ieuid, iuid; + + ieuid = geteuid (); + iuid = getuid (); + if (pieuid != NULL) + *pieuid = ieuid; + +#if HAVE_SETREUID + /* Swap the effective user id and the real user id. We can then + swap them back again when we want to return to the uucp user's + permissions. */ + if (setreuid (ieuid, iuid) < 0) + { + ulog (LOG_ERROR, "setreuid (%ld, %ld): %s", + (long) ieuid, (long) iuid, strerror (errno)); + return FALSE; + } +#else /* ! HAVE_SETREUID */ +#if HAVE_SAVED_SETUID + /* Set the effective user id to the real user id. Since the + effective user id is saved (it's the saved setuid) we will able + to set back to it later. If the real user id is root we will not + be able to switch back and forth, so don't even try. */ + if (iuid != 0) + { + if (setuid (iuid) < 0) + { + ulog (LOG_ERROR, "setuid (%ld): %s", (long) iuid, strerror (errno)); + return FALSE; + } + } +#else /* ! HAVE_SAVED_SETUID */ + /* There's no way to switch between real permissions and effective + permissions. Just try to open the file with the uucp + permissions. */ +#endif /* ! HAVE_SAVED_SETUID */ +#endif /* ! HAVE_SETREUID */ + + return TRUE; +} + +/* Restore the uucp permissions. */ + +/*ARGSUSED*/ +boolean +fsuucp_perms (ieuid) + long ieuid; +{ +#if HAVE_SETREUID + /* Swap effective and real user id's back to what they were. */ + if (! fsuser_perms ((uid_t *) NULL)) + return FALSE; +#else /* ! HAVE_SETREUID */ +#if HAVE_SAVED_SETUID + /* Set ourselves back to our original effective user id. */ + if (setuid ((uid_t) ieuid) < 0) + { + ulog (LOG_ERROR, "setuid (%ld): %s", (long) ieuid, strerror (errno)); + /* Is this error message helpful or confusing? */ + if (errno == EPERM) + ulog (LOG_ERROR, + "Probably HAVE_SAVED_SETUID in policy.h should be set to 0"); + return FALSE; + } +#else /* ! HAVE_SAVED_SETUID */ + /* We didn't switch, no need to switch back. */ +#endif /* ! HAVE_SAVED_SETUID */ +#endif /* ! HAVE_SETREUID */ + + return TRUE; +} diff --git a/gnu/libexec/uucp/libunix/wldcrd.c b/gnu/libexec/uucp/libunix/wldcrd.c index 961ea31..1aa17fa 100644 --- a/gnu/libexec/uucp/libunix/wldcrd.c +++ b/gnu/libexec/uucp/libunix/wldcrd.c @@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" @@ -167,7 +167,7 @@ zsysdep_wildcard (zfile) zret = zbufcpy (sSglob.gl_pathv[iSglob]); ++iSglob; return zret; - + #else /* ! HAVE_GLOB */ char *zret; diff --git a/gnu/libexec/uucp/libunix/work.c b/gnu/libexec/uucp/libunix/work.c index 04a036c..4f380fb 100644 --- a/gnu/libexec/uucp/libunix/work.c +++ b/gnu/libexec/uucp/libunix/work.c @@ -1,7 +1,7 @@ /* work.c Routines to read command files. - Copyright (C) 1991, 1992, 1993 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1995 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -17,16 +17,16 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" #if USE_RCS_ID -const char work_rcsid[] = "$Id: work.c,v 1.2 1994/05/07 18:11:41 ache Exp $"; +const char work_rcsid[] = "$Id: work.c,v 1.20 1995/06/30 21:35:14 ian Rel $"; #endif #include "uudefs.h" @@ -189,7 +189,7 @@ fswork_file (zsystem, zfile, pbgrade) *pbgrade = zfile[2]; return (zfile[0] == 'C' && zfile[1] == '.' - && strlen (zfile) == 7); + && zfile[2] != '\0'); #endif /* SPOOLDIR_TAYLOR */ } @@ -426,13 +426,12 @@ fsysdep_get_work_init (qsys, bgrade) /* Get the next work entry for a system. This must parse the next line in the next work file. The type of command is set into - qcmd->bcmd; if there are no more commands we call - fsysdep_get_work_init to rescan, in case any came in since the last - call. If there are still no commands, qcmd->bcmd is set to 'H'. + qcmd->bcmd If there are no more commands, qcmd->bcmd is set to 'H'. Each field in the structure is set to point to a spot in an - malloced string. The only time we use the grade here is when - calling fsysdep_get_work_init to rescan. */ + malloced string. The grade argument is never used; it has been + used by fsysdep_get_work_init. */ +/*ARGSUSED*/ boolean fsysdep_get_work (qsys, bgrade, qcmd) const struct uuconf_system *qsys; @@ -471,18 +470,9 @@ fsysdep_get_work (qsys, bgrade, qcmd) { if (iSwork_file >= cSwork_files) { - /* Rescan the work directory. */ - if (! fsysdep_get_work_init (qsys, bgrade)) - { - ubuffree (zdir); - return FALSE; - } - if (iSwork_file >= cSwork_files) - { - qcmd->bcmd = 'H'; - ubuffree (zdir); - return TRUE; - } + qcmd->bcmd = 'H'; + ubuffree (zdir); + return TRUE; } if (zdir == NULL) @@ -506,7 +496,7 @@ fsysdep_get_work (qsys, bgrade, qcmd) } } while (e == NULL); - + qfile = (struct ssfile *) xmalloc (sizeof (struct ssfile)); callocated = CFILELINES; iline = 0; @@ -561,7 +551,7 @@ fsysdep_get_work (qsys, bgrade, qcmd) while (TRUE) { int iline; - + if (qSwork_file->cdid >= qSwork_file->clines) { /* We don't want to free qSwork_file here, since it must @@ -628,7 +618,7 @@ fsysdep_did_work (pseq) struct ssfile *qfile; struct ssline *qline; int i; - + qline = (struct ssline *) pseq; ubuffree (qline->zline); @@ -745,7 +735,7 @@ zsysdep_save_temp_file (pseq) ubuffree (zto); return "Could not move file to preservation directory"; } - + cwant = sizeof "File saved as\n\t/" + strlen (zSspooldir) + strlen (zto); if (cwant > cbuf) { @@ -787,11 +777,15 @@ bsgrade (pseq) zfile = ((struct ssline *) pseq)->qfile->zfile; +#if SPOOLDIR_TAYLOR + bgrade = *(strrchr (zfile, '/') + 3); +#else #if ! SPOOLDIR_SVR4 bgrade = zfile[strlen (zfile) - CSEQLEN - 1]; #else bgrade = *(strchr (zfile, '/') + 1); #endif +#endif return bgrade; } diff --git a/gnu/libexec/uucp/libunix/xqtfil.c b/gnu/libexec/uucp/libunix/xqtfil.c index 69e70db..7b1b141 100644 --- a/gnu/libexec/uucp/libunix/xqtfil.c +++ b/gnu/libexec/uucp/libunix/xqtfil.c @@ -1,7 +1,7 @@ /* xqtfil.c Routines to read execute files. - Copyright (C) 1991, 1992, 1993 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1995 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -17,16 +17,16 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" #if USE_RCS_ID -const char xqtfil_rcsid[] = "$Id: xqtfil.c,v 1.2 1994/05/07 18:11:42 ache Exp $"; +const char xqtfil_rcsid[] = "$Id: xqtfil.c,v 1.10 1995/07/19 04:18:37 ian Rel $"; #endif #include "uudefs.h" @@ -78,6 +78,7 @@ static DIR *qSxqt_topdir; #if ! SUBDIRS static const char *zSdir; #else /* SUBDIRS */ +static boolean fSone_dir; static char *zSdir; static DIR *qSxqt_dir; static char *zSsystem; @@ -89,9 +90,36 @@ static char *zSsystem; /*ARGSUSED*/ boolean -fsysdep_get_xqt_init () +fsysdep_get_xqt_init (zsystem) + const char *zsystem; { - usysdep_get_xqt_free (); + usysdep_get_xqt_free ((const char *) NULL); + +#if SUBDIRS + if (zsystem != NULL) + { +#if SPOOLDIR_HDB || SPOOLDIR_SVR4 + zSdir = zbufcpy (zsystem); +#endif +#if SPOOLDIR_ULTRIX + zSdir = zsappend3 ("sys", zsystem, "X."); +#endif +#if SPOOLDIR_TAYLOR + zSdir = zsysdep_in_dir (zsystem, "X."); +#endif + + qSxqt_dir = opendir ((char *) zSdir); + if (qSxqt_dir != NULL) + { + qSxqt_topdir = qSxqt_dir; + fSone_dir = TRUE; + zSsystem = zbufcpy (zsystem); + return TRUE; + } + } + + fSone_dir = FALSE; +#endif qSxqt_topdir = opendir ((char *) ZDIR); if (qSxqt_topdir == NULL) @@ -111,8 +139,10 @@ fsysdep_get_xqt_init () *pzsystem will be set to the system for which the execute file was created. */ +/*ARGSUSED*/ char * -zsysdep_get_xqt (pzsystem, pferr) +zsysdep_get_xqt (zsystem, pzsystem, pferr) + const char *zsystem; char **pzsystem; boolean *pferr; { @@ -220,20 +250,22 @@ zsysdep_get_xqt (pzsystem, pferr) #endif return zret; } - + /* If we've reached the end of the directory, then if we are using subdirectories loop around to read the next one, otherwise we are finished. */ if (q == NULL) { (void) closedir (qdir); + #if SUBDIRS qSxqt_dir = NULL; - continue; -#else + if (! fSone_dir) + continue; +#endif + qSxqt_topdir = NULL; return NULL; -#endif } } } @@ -243,7 +275,8 @@ zsysdep_get_xqt (pzsystem, pferr) /*ARGSUSED*/ void -usysdep_get_xqt_free () +usysdep_get_xqt_free (zsystem) + const char *zsystem; { if (qSxqt_topdir != NULL) { @@ -260,5 +293,6 @@ usysdep_get_xqt_free () zSdir = NULL; ubuffree (zSsystem); zSsystem = NULL; + fSone_dir = FALSE; #endif } diff --git a/gnu/libexec/uucp/libunix/xqtsub.c b/gnu/libexec/uucp/libunix/xqtsub.c index df84654..a2fd50a 100644 --- a/gnu/libexec/uucp/libunix/xqtsub.c +++ b/gnu/libexec/uucp/libunix/xqtsub.c @@ -1,7 +1,7 @@ /* xqtsub.c System dependent functions used only by uuxqt. - Copyright (C) 1991, 1992, 1993 Ian Lance Taylor + Copyright (C) 1991, 1992, 1993, 1995 Ian Lance Taylor This file is part of the Taylor UUCP package. @@ -17,16 +17,16 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. The author of the program may be contacted at ian@airs.com or - c/o Cygnus Support, Building 200, 1 Kendall Square, Cambridge, MA 02139. + c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144. */ #include "uucp.h" #if USE_RCS_ID -const char xqtsub_rcsid[] = "$Id: xqtsub.c,v 1.2 1994/05/07 18:11:43 ache Exp $"; +const char xqtsub_rcsid[] = "$Id: xqtsub.c,v 1.18 1995/06/21 20:21:14 ian Rel $"; #endif #include "uudefs.h" @@ -263,9 +263,9 @@ fsysdep_execute (qsys, zuser, pazargs, zfullcmd, zinput, zoutput, { ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno)); ferr = TRUE; - } + } } - + if (! ferr && zoutput != NULL) { aidescs[1] = creat ((char *) zoutput, IPRIVATE_FILE_MODE); @@ -280,7 +280,7 @@ fsysdep_execute (qsys, zuser, pazargs, zfullcmd, zinput, zoutput, { ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno)); ferr = TRUE; - } + } } if (! ferr) @@ -312,7 +312,7 @@ fsysdep_execute (qsys, zuser, pazargs, zfullcmd, zinput, zoutput, { ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno)); ferr = TRUE; - } + } } if (iseq == 0) @@ -545,7 +545,8 @@ fsysdep_lock_uuxqt_dir (iseq) } if (mkdir (zxqtdir, S_IRWXU) < 0 - && errno != EEXIST) + && errno != EEXIST + && errno != EISDIR) { ulog (LOG_ERROR, "mkdir (%s): %s", zxqtdir, strerror (errno)); return FALSE; @@ -658,7 +659,7 @@ fsysdep_move_uuxqt_files (cfiles, pzfrom, pzto, fto, iseq, pzinput) if (! fto) { const char *ztemp; - + ztemp = zfrom; zfrom = zto; zto = ztemp; @@ -682,7 +683,7 @@ fsysdep_move_uuxqt_files (cfiles, pzfrom, pzto, fto, iseq, pzinput) break; } - if (! fcopy_file (zfrom, zto, FALSE, FALSE)) + if (! fcopy_file (zfrom, zto, FALSE, FALSE, FALSE)) { ubuffree (zfree); break; |