564 lines
16 KiB
C
564 lines
16 KiB
C
/* sysh.unx -*- C -*-
|
||
The header file for the UNIX system dependent routines.
|
||
|
||
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.
|
||
*/
|
||
|
||
#ifndef SYSH_UNX_H
|
||
|
||
#define SYSH_UNX_H
|
||
|
||
#if ANSI_C
|
||
/* These structures are used in prototypes but are not defined in this
|
||
header file. */
|
||
struct uuconf_system;
|
||
struct sconnection;
|
||
#endif
|
||
|
||
/* SCO, SVR4 and Sequent lockfiles are basically just like HDB
|
||
lockfiles. */
|
||
#if HAVE_SCO_LOCKFILES || HAVE_SVR4_LOCKFILES || HAVE_SEQUENT_LOCKFILES
|
||
#undef HAVE_HDB_LOCKFILES
|
||
#define HAVE_HDB_LOCKFILES 1
|
||
#endif
|
||
|
||
#if HAVE_BSD_TTY + HAVE_SYSV_TERMIO + HAVE_POSIX_TERMIOS != 1
|
||
#error Terminal driver define not set or duplicated
|
||
#endif
|
||
|
||
#if SPOOLDIR_V2 + SPOOLDIR_BSD42 + SPOOLDIR_BSD43 + SPOOLDIR_HDB + SPOOLDIR_ULTRIX + SPOOLDIR_SVR4 + SPOOLDIR_TAYLOR != 1
|
||
#error Spool directory define not set or duplicated
|
||
#endif
|
||
|
||
/* If setreuid is broken, don't use it. */
|
||
#if HAVE_BROKEN_SETREUID
|
||
#undef HAVE_SETREUID
|
||
#define HAVE_SETREUID 0
|
||
#endif
|
||
|
||
/* Get some standard types from the configuration header file. */
|
||
#ifdef PID_T
|
||
typedef PID_T pid_t;
|
||
#endif
|
||
|
||
#ifdef UID_T
|
||
typedef UID_T uid_t;
|
||
#endif
|
||
|
||
#ifdef GID_T
|
||
typedef GID_T gid_t;
|
||
#endif
|
||
|
||
#ifdef OFF_T
|
||
typedef OFF_T off_t;
|
||
#endif
|
||
|
||
/* On Unix, binary files are the same as text files. */
|
||
#define BINREAD "r"
|
||
#define BINWRITE "w"
|
||
|
||
/* If we have sigaction, we can force system calls to not be
|
||
restarted. */
|
||
#if HAVE_SIGACTION
|
||
#undef HAVE_RESTARTABLE_SYSCALLS
|
||
#define HAVE_RESTARTABLE_SYSCALLS 0
|
||
#endif
|
||
|
||
/* If we have sigvec, and we have HAVE_SIGVEC_SV_FLAGS, and
|
||
SV_INTERRUPT is defined, we can force system calls to not be
|
||
restarted (signal.h is included by uucp.h before this point, so
|
||
SV_INTERRUPT will be defined by now if it it ever is). */
|
||
#if HAVE_SIGVEC && HAVE_SIGVEC_SV_FLAGS
|
||
#ifdef SV_INTERRUPT
|
||
#undef HAVE_RESTARTABLE_SYSCALLS
|
||
#define HAVE_RESTARTABLE_SYSCALLS 0
|
||
#endif
|
||
#endif
|
||
|
||
/* If we were cross-configured, we will have a value of -1 for
|
||
HAVE_RESTARTABLE_SYSCALLS. In this case, we try to guess what the
|
||
correct value should be. Yuck. If we have sigvec, but neither of
|
||
the above cases applied (which we know because they would have
|
||
changed HAVE_RESTARTABLE_SYSCALLS) then we are probably on 4.2BSD
|
||
and system calls are automatically restarted. Otherwise, assume
|
||
that they are not. */
|
||
#if HAVE_RESTARTABLE_SYSCALLS == -1
|
||
#undef HAVE_RESTARTABLE_SYSCALLS
|
||
#if HAVE_SIGVEC
|
||
#define HAVE_RESTARTABLE_SYSCALLS 1
|
||
#else
|
||
#define HAVE_RESTARTABLE_SYSCALLS 0
|
||
#endif
|
||
#endif /* HAVE_RESTARTABLE_SYSCALLS == -1 */
|
||
|
||
/* We don't handle sigset in combination with restartable system
|
||
calls, so we check for it although this combination will never
|
||
happen. */
|
||
#if ! HAVE_SIGACTION && ! HAVE_SIGVEC && HAVE_SIGSET
|
||
#if HAVE_RESTARTABLE_SYSCALLS
|
||
#undef HAVE_SIGSET
|
||
#define HAVE_SIGSET 0
|
||
#endif
|
||
#endif
|
||
|
||
/* If we don't have restartable system calls, we can ignore
|
||
fsysdep_catch, usysdep_start_catch and usysdep_end_catch.
|
||
Otherwise fsysdep_catch has to do a setjmp. */
|
||
|
||
#if ! HAVE_RESTARTABLE_SYSCALLS
|
||
|
||
#define fsysdep_catch() (TRUE)
|
||
#define usysdep_start_catch()
|
||
#define usysdep_end_catch()
|
||
#define CATCH_PROTECT
|
||
|
||
#else /* HAVE_RESTARTABLE_SYSCALLS */
|
||
|
||
#if HAVE_SETRET && ! HAVE_SIGSETJMP
|
||
#include <setret.h>
|
||
#define setjmp setret
|
||
#define longjmp longret
|
||
#define jmp_buf ret_buf
|
||
#else /* ! HAVE_SETRET || HAVE_SIGSETJMP */
|
||
#include <setjmp.h>
|
||
#if HAVE_SIGSETJMP
|
||
#undef setjmp
|
||
#undef longjmp
|
||
#undef jmp_buf
|
||
#define setjmp(s) sigsetjmp ((s), TRUE)
|
||
#define longjmp siglongjmp
|
||
#define jmp_buf sigjmp_buf
|
||
#endif /* HAVE_SIGSETJMP */
|
||
#endif /* ! HAVE_SETRET || HAVE_SIGSETJMP */
|
||
|
||
extern volatile sig_atomic_t fSjmp;
|
||
extern volatile jmp_buf sSjmp_buf;
|
||
|
||
#define fsysdep_catch() (setjmp (sSjmp_buf) == 0)
|
||
|
||
#define usysdep_start_catch() (fSjmp = TRUE)
|
||
|
||
#define usysdep_end_catch() (fSjmp = FALSE)
|
||
|
||
#define CATCH_PROTECT volatile
|
||
|
||
#endif /* HAVE_RESTARTABLE_SYSCALLS */
|
||
|
||
/* Get definitions for the terminal driver. */
|
||
|
||
#if HAVE_BSD_TTY
|
||
#include <sgtty.h>
|
||
struct sbsd_terminal
|
||
{
|
||
struct sgttyb stty;
|
||
struct tchars stchars;
|
||
struct ltchars sltchars;
|
||
};
|
||
typedef struct sbsd_terminal sterminal;
|
||
#define fgetterminfo(o, q) \
|
||
(ioctl ((o), TIOCGETP, &(q)->stty) == 0 \
|
||
&& ioctl ((o), TIOCGETC, &(q)->stchars) == 0 \
|
||
&& ioctl ((o), TIOCGLTC, &(q)->sltchars) == 0)
|
||
#define fsetterminfo(o, q) \
|
||
(ioctl ((o), TIOCSETN, &(q)->stty) == 0 \
|
||
&& ioctl ((o), TIOCSETC, &(q)->stchars) == 0 \
|
||
&& ioctl ((o), TIOCSLTC, &(q)->sltchars) == 0)
|
||
#define fsetterminfodrain(o, q) \
|
||
(ioctl ((o), TIOCSETP, &(q)->stty) == 0 \
|
||
&& ioctl ((o), TIOCSETC, &(q)->stchars) == 0 \
|
||
&& ioctl ((o), TIOCSLTC, &(q)->sltchars) == 0)
|
||
#endif /* HAVE_BSD_TTY */
|
||
|
||
#if HAVE_SYSV_TERMIO
|
||
#include <termio.h>
|
||
typedef struct termio sterminal;
|
||
#define fgetterminfo(o, q) (ioctl ((o), TCGETA, (q)) == 0)
|
||
#define fsetterminfo(o, q) (ioctl ((o), TCSETA, (q)) == 0)
|
||
#define fsetterminfodrain(o, q) (ioctl ((o), TCSETAW, (q)) == 0)
|
||
#endif /* HAVE_SYSV_TERMIO */
|
||
|
||
#if HAVE_POSIX_TERMIOS
|
||
#include <termios.h>
|
||
typedef struct termios sterminal;
|
||
#define fgetterminfo(o, q) (tcgetattr ((o), (q)) == 0)
|
||
#define fsetterminfo(o, q) (tcsetattr ((o), TCSANOW, (q)) == 0)
|
||
#define fsetterminfodrain(o, q) (tcsetattr ((o), TCSADRAIN, (q)) == 0)
|
||
|
||
/* On some systems it is not possible to include both <sys/ioctl.h>
|
||
and <termios.h> in the same source files; I don't really know why.
|
||
On such systems, we pretend that we don't have <sys/ioctl.h>. */
|
||
#if ! HAVE_TERMIOS_AND_SYS_IOCTL_H
|
||
#undef HAVE_SYS_IOCTL_H
|
||
#define HAVE_SYS_IOCTL_H 0
|
||
#endif
|
||
|
||
#endif /* HAVE_POSIX_TERMIOS */
|
||
|
||
/* The root directory (this is needed by the system independent stuff
|
||
as the default for local-send). */
|
||
#define ZROOTDIR "/"
|
||
|
||
/* The name of the execution directory within the spool directory
|
||
(this is need by the system independent uuxqt.c). */
|
||
#define XQTDIR ".Xqtdir"
|
||
|
||
/* The name of the directory in which we preserve file transfers that
|
||
failed. */
|
||
#define PRESERVEDIR ".Preserve"
|
||
|
||
/* The name of the directory to which we move corrupt files. */
|
||
#define CORRUPTDIR ".Corrupt"
|
||
|
||
/* The name of the directory to which we move failed execution files. */
|
||
#define FAILEDDIR ".Failed"
|
||
|
||
/* The length of the sequence number used in a file name. */
|
||
#define CSEQLEN (4)
|
||
|
||
/* Get some standard definitions. Avoid including the files more than
|
||
once--some might have been included by uucp.h. */
|
||
#if USE_STDIO && HAVE_UNISTD_H
|
||
#include <unistd.h>
|
||
#endif
|
||
#if ! USE_TYPES_H
|
||
#include <sys/types.h>
|
||
#endif
|
||
#include <sys/stat.h>
|
||
|
||
/* Get definitions for the file permission bits. */
|
||
|
||
#ifndef S_IRWXU
|
||
#define S_IRWXU 0700
|
||
#endif
|
||
#ifndef S_IRUSR
|
||
#define S_IRUSR 0400
|
||
#endif
|
||
#ifndef S_IWUSR
|
||
#define S_IWUSR 0200
|
||
#endif
|
||
#ifndef S_IXUSR
|
||
#define S_IXUSR 0100
|
||
#endif
|
||
|
||
#ifndef S_IRWXG
|
||
#define S_IRWXG 0070
|
||
#endif
|
||
#ifndef S_IRGRP
|
||
#define S_IRGRP 0040
|
||
#endif
|
||
#ifndef S_IWGRP
|
||
#define S_IWGRP 0020
|
||
#endif
|
||
#ifndef S_IXGRP
|
||
#define S_IXGRP 0010
|
||
#endif
|
||
|
||
#ifndef S_IRWXO
|
||
#define S_IRWXO 0007
|
||
#endif
|
||
#ifndef S_IROTH
|
||
#define S_IROTH 0004
|
||
#endif
|
||
#ifndef S_IWOTH
|
||
#define S_IWOTH 0002
|
||
#endif
|
||
#ifndef S_IXOTH
|
||
#define S_IXOTH 0001
|
||
#endif
|
||
|
||
#if STAT_MACROS_BROKEN
|
||
#undef S_ISDIR
|
||
#endif
|
||
|
||
#ifndef S_ISDIR
|
||
#ifdef S_IFDIR
|
||
#define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR)
|
||
#else /* ! defined (S_IFDIR) */
|
||
#define S_ISDIR(i) (((i) & 0170000) == 040000)
|
||
#endif /* ! defined (S_IFDIR) */
|
||
#endif /* ! defined (S_ISDIR) */
|
||
|
||
/* We need the access macros. */
|
||
#ifndef R_OK
|
||
#define R_OK 4
|
||
#define W_OK 2
|
||
#define X_OK 1
|
||
#define F_OK 0
|
||
#endif /* ! defined (R_OK) */
|
||
|
||
/* We create files with these modes (should this be configurable?). */
|
||
#define IPRIVATE_FILE_MODE (S_IRUSR | S_IWUSR)
|
||
#define IPUBLIC_FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
|
||
|
||
/* We create directories with this mode (should this be configurable?). */
|
||
#define IDIRECTORY_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
|
||
#define IPUBLIC_DIRECTORY_MODE (S_IRWXU | S_IRWXG | S_IRWXO)
|
||
|
||
#if ! HAVE_OPENDIR
|
||
|
||
/* Define some structures to use if we don't have opendir, etc. These
|
||
will only work if we have the old Unix filesystem, with a 2 byte
|
||
inode and a 14 byte filename. */
|
||
|
||
#include <sys/dir.h>
|
||
|
||
struct dirent
|
||
{
|
||
char d_name[DIRSIZ + 1];
|
||
};
|
||
|
||
typedef struct
|
||
{
|
||
int o;
|
||
struct dirent s;
|
||
} DIR;
|
||
|
||
extern DIR *opendir P((const char *zdir));
|
||
extern struct dirent *readdir P((DIR *));
|
||
extern int closedir P((DIR *));
|
||
|
||
#endif /* ! HAVE_OPENDIR */
|
||
|
||
#if ! HAVE_FTW_H
|
||
|
||
/* If there is no <ftw.h>, define the ftw constants. */
|
||
|
||
#define FTW_F (0)
|
||
#define FTW_D (1)
|
||
#define FTW_DNR (2)
|
||
#define FTW_NS (3)
|
||
|
||
#endif /* ! HAVE_FTW_H */
|
||
|
||
/* This structure holds the system dependent information we keep for a
|
||
connection. This is used by the TCP and TLI code. */
|
||
|
||
struct ssysdep_conn
|
||
{
|
||
/* File descriptor. */
|
||
int o;
|
||
/* File descriptor to read from (used by stdin and pipe port types). */
|
||
int ord;
|
||
/* File descriptor to write to (used by stdin and pipe port types). */
|
||
int owr;
|
||
/* Device name. */
|
||
char *zdevice;
|
||
/* File status flags. */
|
||
int iflags;
|
||
/* File status flags for write descriptor (-1 if not used). */
|
||
int iwr_flags;
|
||
/* Hold the real descriptor when using a dialer device. */
|
||
int ohold;
|
||
/* TRUE if this is a terminal and the remaining fields are valid. */
|
||
boolean fterminal;
|
||
/* TRUE if this is a TLI descriptor. */
|
||
boolean ftli;
|
||
/* Baud rate. */
|
||
long ibaud;
|
||
/* Original terminal settings. */
|
||
sterminal sorig;
|
||
/* Current terminal settings. */
|
||
sterminal snew;
|
||
/* Process ID of currently executing pipe command, or parent process
|
||
of forked TCP or TLI server, or -1. */
|
||
pid_t ipid;
|
||
#if HAVE_COHERENT_LOCKFILES
|
||
/* On Coherent we need to hold on to the real port name which will
|
||
be used to enable the port. Ick. */
|
||
char *zenable;
|
||
#endif
|
||
};
|
||
|
||
/* These functions do I/O and chat scripts to a port. They are called
|
||
by the TCP and TLI routines. */
|
||
extern boolean fsysdep_conn_read P((struct sconnection *qconn,
|
||
char *zbuf, size_t *pclen,
|
||
size_t cmin, int ctimeout,
|
||
boolean freport));
|
||
extern boolean fsysdep_conn_write P((struct sconnection *qconn,
|
||
const char *zbuf, size_t clen));
|
||
extern boolean fsysdep_conn_io P((struct sconnection *qconn,
|
||
const char *zwrite, size_t *pcwrite,
|
||
char *zread, size_t *pcread));
|
||
extern boolean fsysdep_conn_chat P((struct sconnection *qconn,
|
||
char **pzprog));
|
||
|
||
/* Set a signal handler. */
|
||
extern void usset_signal P((int isig, RETSIGTYPE (*pfn) P((int)),
|
||
boolean fforce, boolean *pfignored));
|
||
|
||
/* Default signal handler. This sets the appropriate element of the
|
||
afSignal array. If system calls are automatically restarted, it
|
||
may do a longjmp to an fsysdep_catch. */
|
||
extern RETSIGTYPE ussignal P((int isig));
|
||
|
||
/* Try to fork, repeating several times. */
|
||
extern pid_t ixsfork P((void));
|
||
|
||
/* Spawn a job. Returns the process ID of the spawned job or -1 on
|
||
error. The following macros may be passed in aidescs. */
|
||
|
||
/* Set descriptor to /dev/null. */
|
||
#define SPAWN_NULL (-1)
|
||
/* Set element of aidescs to a pipe for caller to read from. */
|
||
#define SPAWN_READ_PIPE (-2)
|
||
/* Set element of aidescs to a pipe for caller to write to. */
|
||
#define SPAWN_WRITE_PIPE (-3)
|
||
|
||
extern pid_t ixsspawn P((const char **pazargs, int *aidescs,
|
||
boolean fkeepuid, boolean fkeepenv,
|
||
const char *zchdir, boolean fnosigs,
|
||
boolean fshell, const char *zpath,
|
||
const char *zuu_machine,
|
||
const char *zuu_user));
|
||
|
||
/* Do a form of popen using ixsspawn. */
|
||
extern FILE *espopen P((const char **pazargs, boolean frd,
|
||
pid_t *pipid));
|
||
|
||
/* Wait for a particular process to finish, returning the exit status.
|
||
The process ID should be pid_t, but we can't put that in a
|
||
prototype. */
|
||
extern int ixswait P((unsigned long ipid, const char *zreport));
|
||
|
||
/* Read from a connection using two file descriptors. */
|
||
extern boolean fsdouble_read P((struct sconnection *qconn, char *zbuf,
|
||
size_t *pclen, size_t cmin, int ctimeout,
|
||
boolean freport));
|
||
|
||
/* Write to a connection using two file descriptors. */
|
||
extern boolean fsdouble_write P((struct sconnection *qconn,
|
||
const char *zbuf, size_t clen));
|
||
|
||
/* Run a chat program on a connection using two file descriptors. */
|
||
extern boolean fsdouble_chat P((struct sconnection *qconn,
|
||
char **pzprog));
|
||
|
||
/* Find a spool file in the spool directory. For a local file, the
|
||
bgrade argument is the grade of the file. This is needed for
|
||
SPOOLDIR_SVR4. */
|
||
extern char *zsfind_file P((const char *zsimple, const char *zsystem,
|
||
int bgrade));
|
||
|
||
/* Return the grade given a sequence number. */
|
||
extern int bsgrade P((pointer pseq));
|
||
|
||
/* Lock a string. */
|
||
extern boolean fsdo_lock P((const char *, boolean fspooldir,
|
||
boolean *pferr));
|
||
|
||
/* Unlock a string. */
|
||
extern boolean fsdo_unlock P((const char *, boolean fspooldir));
|
||
|
||
/* Check access for a particular user name, or NULL to check access
|
||
for any user. */
|
||
extern boolean fsuser_access P((const struct stat *, int imode,
|
||
const char *zuser));
|
||
|
||
/* Switch to the permissions of the invoking user. This sets the
|
||
argument to a value to pass to fsuucp_perms. */
|
||
extern boolean fsuser_perms P((uid_t *));
|
||
|
||
/* Switch back to the permissions of the UUCP user ID. This should be
|
||
passed the value returned by fsuser_perms in its argument. */
|
||
extern boolean fsuucp_perms P((long));
|
||
|
||
/* Stick two directories and a file name together. */
|
||
extern char *zsappend3 P((const char *zdir1, const char *zdir2,
|
||
const char *zfile));
|
||
|
||
/* Stick three directories and a file name together. */
|
||
extern char *zsappend4 P((const char *zdir1, const char *zdir2,
|
||
const char *zdir3, const char *zfile));
|
||
|
||
/* Get a temporary file name. */
|
||
extern char *zstemp_file P((const struct uuconf_system *qsys));
|
||
|
||
/* Get a command file name. */
|
||
extern char *zscmd_file P((const struct uuconf_system *qsys, int bgrade));
|
||
|
||
/* Get a jobid from a system, a file name, and a grade. */
|
||
extern char *zsfile_to_jobid P((const struct uuconf_system *qsys,
|
||
const char *zfile,
|
||
int bgrade));
|
||
|
||
/* Get a file name from a jobid. This also returns the associated system
|
||
in *pzsystem and the grade in *pbgrade. */
|
||
extern char *zsjobid_to_file P((const char *zid, char **pzsystem,
|
||
char *pbgrade));
|
||
|
||
/* See whether there is a spool directory for a system when using
|
||
SPOOLDIR_ULTRIX. */
|
||
extern boolean fsultrix_has_spool P((const char *zsystem));
|
||
|
||
#if HAVE_COHERENT_LOCKFILES
|
||
/* Lock a coherent tty. */
|
||
extern boolean lockttyexist P((const char *z));
|
||
extern boolean fscoherent_disable_tty P((const char *zdevice,
|
||
char **pzenable));
|
||
#endif
|
||
|
||
/* Some replacements for standard Unix functions. */
|
||
|
||
#if ! HAVE_DUP2
|
||
extern int dup2 P((int oold, int onew));
|
||
#endif
|
||
|
||
#if ! HAVE_FTW
|
||
extern int ftw P((const char *zdir,
|
||
int (*pfn) P((const char *zfile,
|
||
struct stat *qstat,
|
||
int iflag)),
|
||
int cdescriptors));
|
||
#endif
|
||
|
||
#if ! HAVE_GETCWD && ! HAVE_GETWD
|
||
extern char *getcwd P((char *zbuf, size_t cbuf));
|
||
#endif
|
||
|
||
#if ! HAVE_MKDIR
|
||
extern int mkdir P((const char *zdir, int imode));
|
||
#endif
|
||
|
||
#if ! HAVE_RENAME
|
||
extern int rename P((const char *zold, const char *znew));
|
||
#endif
|
||
|
||
#if ! HAVE_RMDIR
|
||
extern int rmdir P((const char *zdir));
|
||
#endif
|
||
|
||
/* The working directory from which the program was run (this is set
|
||
by usysdep_initialize if called with INIT_GETCWD). */
|
||
extern char *zScwd;
|
||
|
||
/* The spool directory name. */
|
||
extern const char *zSspooldir;
|
||
|
||
/* The lock directory name. */
|
||
extern const char *zSlockdir;
|
||
|
||
/* The local UUCP name (needed for some spool directory stuff). */
|
||
extern const char *zSlocalname;
|
||
|
||
#endif /* ! defined (SYSH_UNX_H) */
|