1/* sysdep.h -*- C -*-
2   The header file for the UNIX system dependent routines.
3
4   Copyright (C) 1991, 1992, 1993, 1995, 2002 Ian Lance Taylor
5
6   This file is part of the Taylor UUCP package.
7
8   This program is free software; you can redistribute it and/or
9   modify it under the terms of the GNU General Public License as
10   published by the Free Software Foundation; either version 2 of the
11   License, or (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16   General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
21
22   The author of the program may be contacted at ian@airs.com.
23   */
24
25#ifndef SYSDEP_H
26
27#define SYSDEP_H
28
29#if ANSI_C
30/* These structures are used in prototypes but are not defined in this
31   header file.  */
32struct uuconf_system;
33struct sconnection;
34#endif
35
36/* SCO, SVR4 and Sequent lockfiles are basically just like HDB
37   lockfiles.  */
38#if HAVE_SCO_LOCKFILES || HAVE_SVR4_LOCKFILES || HAVE_SEQUENT_LOCKFILES
39#undef HAVE_HDB_LOCKFILES
40#define HAVE_HDB_LOCKFILES 1
41#endif
42
43#if HAVE_BSD_TTY + HAVE_SYSV_TERMIO + HAVE_POSIX_TERMIOS != 1
44 #error Terminal driver define not set or duplicated
45#endif
46
47#if SPOOLDIR_V2 + SPOOLDIR_BSD42 + SPOOLDIR_BSD43 + SPOOLDIR_HDB + SPOOLDIR_ULTRIX + SPOOLDIR_SVR4 + SPOOLDIR_TAYLOR != 1
48 #error Spool directory define not set or duplicated
49#endif
50
51/* If setreuid is broken, don't use it.  */
52#if HAVE_BROKEN_SETREUID
53#undef HAVE_SETREUID
54#define HAVE_SETREUID 0
55#endif
56
57/* Get some standard types from the configuration header file.  */
58#ifdef PID_T
59typedef PID_T pid_t;
60#endif
61
62#ifdef UID_T
63typedef UID_T uid_t;
64#endif
65
66#ifdef GID_T
67typedef GID_T gid_t;
68#endif
69
70#ifdef OFF_T
71typedef OFF_T off_t;
72#endif
73
74/* On Unix, binary files are the same as text files.  */
75#define BINREAD "r"
76#define BINWRITE "w"
77
78/* If we have sigaction, we can force system calls to not be
79   restarted.  */
80#if HAVE_SIGACTION
81#undef HAVE_RESTARTABLE_SYSCALLS
82#define HAVE_RESTARTABLE_SYSCALLS 0
83#endif
84
85/* If we have sigvec, and we have HAVE_SIGVEC_SV_FLAGS, and
86   SV_INTERRUPT is defined, we can force system calls to not be
87   restarted (signal.h is included by uucp.h before this point, so
88   SV_INTERRUPT will be defined by now if it it ever is).  */
89#if HAVE_SIGVEC && HAVE_SIGVEC_SV_FLAGS
90#ifdef SV_INTERRUPT
91#undef HAVE_RESTARTABLE_SYSCALLS
92#define HAVE_RESTARTABLE_SYSCALLS 0
93#endif
94#endif
95
96/* If we were cross-configured, we will have a value of -1 for
97   HAVE_RESTARTABLE_SYSCALLS.  In this case, we try to guess what the
98   correct value should be.  Yuck.  If we have sigvec, but neither of
99   the above cases applied (which we know because they would have
100   changed HAVE_RESTARTABLE_SYSCALLS) then we are probably on 4.2BSD
101   and system calls are automatically restarted.  Otherwise, assume
102   that they are not.  */
103#if HAVE_RESTARTABLE_SYSCALLS == -1
104#undef HAVE_RESTARTABLE_SYSCALLS
105#if HAVE_SIGVEC
106#define HAVE_RESTARTABLE_SYSCALLS 1
107#else
108#define HAVE_RESTARTABLE_SYSCALLS 0
109#endif
110#endif /* HAVE_RESTARTABLE_SYSCALLS == -1 */
111
112/* We don't handle sigset in combination with restartable system
113   calls, so we check for it although this combination will never
114   happen.  */
115#if ! HAVE_SIGACTION && ! HAVE_SIGVEC && HAVE_SIGSET
116#if HAVE_RESTARTABLE_SYSCALLS
117#undef HAVE_SIGSET
118#define HAVE_SIGSET 0
119#endif
120#endif
121
122/* If we don't have restartable system calls, we can ignore
123   fsysdep_catch, usysdep_start_catch and usysdep_end_catch.
124   Otherwise fsysdep_catch has to do a setjmp.  */
125
126#if ! HAVE_RESTARTABLE_SYSCALLS
127
128#define fsysdep_catch() (TRUE)
129#define usysdep_start_catch()
130#define usysdep_end_catch()
131#define CATCH_PROTECT
132
133#else /* HAVE_RESTARTABLE_SYSCALLS */
134
135#if HAVE_SETRET && ! HAVE_SIGSETJMP
136#include <setret.h>
137#define setjmp setret
138#define longjmp longret
139#define jmp_buf ret_buf
140#else /* ! HAVE_SETRET || HAVE_SIGSETJMP */
141#include <setjmp.h>
142#if HAVE_SIGSETJMP
143#undef setjmp
144#undef longjmp
145#undef jmp_buf
146#define setjmp(s) sigsetjmp ((s), TRUE)
147#define longjmp siglongjmp
148#define jmp_buf sigjmp_buf
149#endif /* HAVE_SIGSETJMP */
150#endif /* ! HAVE_SETRET || HAVE_SIGSETJMP */
151
152extern volatile sig_atomic_t fSjmp;
153extern volatile jmp_buf sSjmp_buf;
154
155#define fsysdep_catch() (setjmp (sSjmp_buf) == 0)
156
157#define usysdep_start_catch() (fSjmp = TRUE)
158
159#define usysdep_end_catch() (fSjmp = FALSE)
160
161#define CATCH_PROTECT volatile
162
163#endif /* HAVE_RESTARTABLE_SYSCALLS */
164
165/* Get definitions for the terminal driver.  */
166
167#if HAVE_BSD_TTY
168#include <sgtty.h>
169struct sbsd_terminal
170{
171  struct sgttyb stty;
172  struct tchars stchars;
173  struct ltchars sltchars;
174};
175typedef struct sbsd_terminal sterminal;
176#define fgetterminfo(o, q) \
177  (ioctl ((o), TIOCGETP, &(q)->stty) == 0 \
178   && ioctl ((o), TIOCGETC, &(q)->stchars) == 0 \
179   && ioctl ((o), TIOCGLTC, &(q)->sltchars) == 0)
180#define fsetterminfo(o, q) \
181  (ioctl ((o), TIOCSETN, &(q)->stty) == 0 \
182   && ioctl ((o), TIOCSETC, &(q)->stchars) == 0 \
183   && ioctl ((o), TIOCSLTC, &(q)->sltchars) == 0)
184#define fsetterminfodrain(o, q) \
185  (ioctl ((o), TIOCSETP, &(q)->stty) == 0 \
186   && ioctl ((o), TIOCSETC, &(q)->stchars) == 0 \
187   && ioctl ((o), TIOCSLTC, &(q)->sltchars) == 0)
188#endif /* HAVE_BSD_TTY */
189
190#if HAVE_SYSV_TERMIO
191#include <termio.h>
192typedef struct termio sterminal;
193#define fgetterminfo(o, q) (ioctl ((o), TCGETA, (q)) == 0)
194#define fsetterminfo(o, q) (ioctl ((o), TCSETA, (q)) == 0)
195#define fsetterminfodrain(o, q) (ioctl ((o), TCSETAW, (q)) == 0)
196#endif /* HAVE_SYSV_TERMIO */
197
198#if HAVE_POSIX_TERMIOS
199#include <termios.h>
200typedef struct termios sterminal;
201#define fgetterminfo(o, q) (tcgetattr ((o), (q)) == 0)
202#define fsetterminfo(o, q) (tcsetattr ((o), TCSANOW, (q)) == 0)
203#define fsetterminfodrain(o, q) (tcsetattr ((o), TCSADRAIN, (q)) == 0)
204
205/* On some systems it is not possible to include both <sys/ioctl.h>
206   and <termios.h> in the same source files; I don't really know why.
207   On such systems, we pretend that we don't have <sys/ioctl.h>.  */
208#if ! HAVE_TERMIOS_AND_SYS_IOCTL_H
209#undef HAVE_SYS_IOCTL_H
210#define HAVE_SYS_IOCTL_H 0
211#endif
212
213#endif /* HAVE_POSIX_TERMIOS */
214
215/* The root directory (this is needed by the system independent stuff
216   as the default for local-send).  */
217#define ZROOTDIR "/"
218
219/* The name of the execution directory within the spool directory
220   (this is need by the system independent uuxqt.c).  */
221#define XQTDIR ".Xqtdir"
222
223/* The name of the directory in which we preserve file transfers that
224   failed.  */
225#define PRESERVEDIR ".Preserve"
226
227/* The name of the directory to which we move corrupt files.  */
228#define CORRUPTDIR ".Corrupt"
229
230/* The name of the directory to which we move failed execution files.  */
231#define FAILEDDIR ".Failed"
232
233/* The length of the sequence number used in a file name.  */
234#define CSEQLEN (4)
235
236/* Get some standard definitions.  Avoid including the files more than
237   once--some might have been included by uucp.h.  */
238#if USE_STDIO && HAVE_UNISTD_H
239#include <unistd.h>
240#endif
241#if ! USE_TYPES_H
242#include <sys/types.h>
243#endif
244#include <sys/stat.h>
245
246/* Get definitions for the file permission bits.  */
247
248#ifndef S_IRWXU
249#define S_IRWXU 0700
250#endif
251#ifndef S_IRUSR
252#define S_IRUSR 0400
253#endif
254#ifndef S_IWUSR
255#define S_IWUSR 0200
256#endif
257#ifndef S_IXUSR
258#define S_IXUSR 0100
259#endif
260
261#ifndef S_IRWXG
262#define S_IRWXG 0070
263#endif
264#ifndef S_IRGRP
265#define S_IRGRP 0040
266#endif
267#ifndef S_IWGRP
268#define S_IWGRP 0020
269#endif
270#ifndef S_IXGRP
271#define S_IXGRP 0010
272#endif
273
274#ifndef S_IRWXO
275#define S_IRWXO 0007
276#endif
277#ifndef S_IROTH
278#define S_IROTH 0004
279#endif
280#ifndef S_IWOTH
281#define S_IWOTH 0002
282#endif
283#ifndef S_IXOTH
284#define S_IXOTH 0001
285#endif
286
287#if STAT_MACROS_BROKEN
288#undef S_ISDIR
289#endif
290
291#ifndef S_ISDIR
292#ifdef S_IFDIR
293#define S_ISDIR(i) (((i) & S_IFMT) == S_IFDIR)
294#else /* ! defined (S_IFDIR) */
295#define S_ISDIR(i) (((i) & 0170000) == 040000)
296#endif /* ! defined (S_IFDIR) */
297#endif /* ! defined (S_ISDIR) */
298
299/* We need the access macros.  */
300#ifndef R_OK
301#define R_OK 4
302#define W_OK 2
303#define X_OK 1
304#define F_OK 0
305#endif /* ! defined (R_OK) */
306
307/* We create files with these modes (should this be configurable?).  */
308#define IPRIVATE_FILE_MODE (S_IRUSR | S_IWUSR)
309#define IPUBLIC_FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
310
311/* We create directories with this mode (should this be configurable?).  */
312#define IDIRECTORY_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
313#define IPUBLIC_DIRECTORY_MODE (S_IRWXU | S_IRWXG | S_IRWXO)
314
315#if ! HAVE_OPENDIR
316
317/* Define some structures to use if we don't have opendir, etc.  These
318   will only work if we have the old Unix filesystem, with a 2 byte
319   inode and a 14 byte filename.  */
320
321#include <sys/dir.h>
322
323struct dirent
324{
325  char d_name[DIRSIZ + 1];
326};
327
328typedef struct
329{
330  int o;
331  struct dirent s;
332} DIR;
333
334extern DIR *opendir P((const char *zdir));
335extern struct dirent *readdir P((DIR *));
336extern int closedir P((DIR *));
337
338#endif /* ! HAVE_OPENDIR */
339
340#if ! HAVE_FTW_H
341
342/* If there is no <ftw.h>, define the ftw constants.  */
343
344#define FTW_F (0)
345#define FTW_D (1)
346#define FTW_DNR (2)
347#define FTW_NS (3)
348
349#endif /* ! HAVE_FTW_H */
350
351/* This structure holds the system dependent information we keep for a
352   connection.  This is used by the TCP and TLI code.  */
353
354struct ssysdep_conn
355{
356  /* File descriptor.  */
357  int o;
358  /* File descriptor to read from (used by stdin and pipe port types).  */
359  int ord;
360  /* File descriptor to write to (used by stdin and pipe port types).  */
361  int owr;
362  /* Device name.  */
363  char *zdevice;
364  /* File status flags.  */
365  int iflags;
366  /* File status flags for write descriptor (-1 if not used).  */
367  int iwr_flags;
368  /* Hold the real descriptor when using a dialer device.  */
369  int ohold;
370  /* TRUE if this is a terminal and the remaining fields are valid.  */
371  boolean fterminal;
372  /* TRUE if this is a TLI descriptor.  */
373  boolean ftli;
374  /* Baud rate.  */
375  long ibaud;
376  /* Original terminal settings.  */
377  sterminal sorig;
378  /* Current terminal settings.  */
379  sterminal snew;
380  /* Process ID of currently executing pipe command, or parent process
381     of forked TCP or TLI server, or -1.  */
382  pid_t ipid;
383#if HAVE_COHERENT_LOCKFILES
384  /* On Coherent we need to hold on to the real port name which will
385     be used to enable the port.  Ick.  */
386  char *zenable;
387#endif
388};
389
390/* These functions do I/O and chat scripts to a port.  They are called
391   by the TCP and TLI routines.  */
392extern boolean fsysdep_conn_read P((struct sconnection *qconn,
393				    char *zbuf, size_t *pclen,
394				    size_t cmin, int ctimeout,
395				    boolean freport));
396extern boolean fsysdep_conn_write P((struct sconnection *qconn,
397				     const char *zbuf, size_t clen));
398extern boolean fsysdep_conn_io P((struct sconnection *qconn,
399				  const char *zwrite, size_t *pcwrite,
400				  char *zread, size_t *pcread));
401extern boolean fsysdep_conn_chat P((struct sconnection *qconn,
402				    char **pzprog));
403
404/* Set a signal handler.  */
405extern void usset_signal P((int isig, RETSIGTYPE (*pfn) P((int)),
406			    boolean fforce, boolean *pfignored));
407
408/* Default signal handler.  This sets the appropriate element of the
409   afSignal array.  If system calls are automatically restarted, it
410   may do a longjmp to an fsysdep_catch.  */
411extern RETSIGTYPE ussignal P((int isig));
412
413/* Try to fork, repeating several times.  */
414extern pid_t ixsfork P((void));
415
416/* Spawn a job.  Returns the process ID of the spawned job or -1 on
417   error.  The following macros may be passed in aidescs.  */
418
419/* Set descriptor to /dev/null.  */
420#define SPAWN_NULL (-1)
421/* Set element of aidescs to a pipe for caller to read from.  */
422#define SPAWN_READ_PIPE (-2)
423/* Set element of aidescs to a pipe for caller to write to.  */
424#define SPAWN_WRITE_PIPE (-3)
425
426extern pid_t ixsspawn P((const char **pazargs, int *aidescs,
427			 boolean fkeepuid, boolean fkeepenv,
428			 const char *zchdir, boolean fnosigs,
429			 boolean fshell, const char *zpath,
430			 const char *zuu_machine,
431			 const char *zuu_user));
432
433/* Do a form of popen using ixsspawn.  */
434extern FILE *espopen P((const char **pazargs, boolean frd,
435			pid_t *pipid));
436
437/* Wait for a particular process to finish, returning the exit status.
438   The process ID should be pid_t, but we can't put that in a
439   prototype.  */
440extern int ixswait P((unsigned long ipid, const char *zreport));
441
442/* Read from a connection using two file descriptors.  */
443extern boolean fsdouble_read P((struct sconnection *qconn, char *zbuf,
444				size_t *pclen, size_t cmin, int ctimeout,
445				boolean freport));
446
447/* Write to a connection using two file descriptors.  */
448extern boolean fsdouble_write P((struct sconnection *qconn,
449				 const char *zbuf, size_t clen));
450
451/* Run a chat program on a connection using two file descriptors.  */
452extern boolean fsdouble_chat P((struct sconnection *qconn,
453				char **pzprog));
454
455/* Find a spool file in the spool directory.  For a local file, the
456   bgrade argument is the grade of the file.  This is needed for
457   SPOOLDIR_SVR4.  */
458extern char *zsfind_file P((const char *zsimple, const char *zsystem,
459			    int bgrade));
460
461/* Return the grade given a sequence number.  */
462extern int bsgrade P((pointer pseq));
463
464/* Lock a string.  */
465extern boolean fsdo_lock P((const char *, boolean fspooldir,
466			    boolean *pferr));
467
468/* Unlock a string.  */
469extern boolean fsdo_unlock P((const char *, boolean fspooldir));
470
471/* Check access for a particular user name, or NULL to check access
472   for any user.  */
473extern boolean fsuser_access P((const struct stat *, int imode,
474				const char *zuser));
475
476/* Switch to the permissions of the invoking user.  This sets the
477   arguments to values to pass to fsuucp_perms.  */
478extern boolean fsuser_perms P((uid_t *, gid_t *));
479
480/* Switch back to the permissions of the UUCP user ID.  This should be
481   passed the values returned by fsuser_perms in its arguments.  */
482extern boolean fsuucp_perms P((long, long));
483
484/* Stick two directories and a file name together.  */
485extern char *zsappend3 P((const char *zdir1, const char *zdir2,
486			  const char *zfile));
487
488/* Stick three directories and a file name together.  */
489extern char *zsappend4 P((const char *zdir1, const char *zdir2,
490			  const char *zdir3, const char *zfile));
491
492/* Get a temporary file name.  */
493extern char *zstemp_file P((const struct uuconf_system *qsys));
494
495/* Get a command file name.  */
496extern char *zscmd_file P((const struct uuconf_system *qsys, int bgrade));
497
498/* Get a jobid from a system, a file name, and a grade.  */
499extern char *zsfile_to_jobid P((const struct uuconf_system *qsys,
500				const char *zfile,
501				int bgrade));
502
503/* Get a file name from a jobid.  This also returns the associated system
504   in *pzsystem and the grade in *pbgrade.  */
505extern char *zsjobid_to_file P((const char *zid, char **pzsystem,
506				char *pbgrade));
507
508/* See whether there is a spool directory for a system when using
509   SPOOLDIR_ULTRIX.  */
510extern boolean fsultrix_has_spool P((const char *zsystem));
511
512#if HAVE_COHERENT_LOCKFILES
513/* Lock a coherent tty.  */
514extern boolean lockttyexist P((const char *z));
515extern boolean fscoherent_disable_tty P((const char *zdevice,
516					 char **pzenable));
517#endif
518
519/* Some replacements for standard Unix functions.  */
520
521#if ! HAVE_DUP2
522extern int dup2 P((int oold, int onew));
523#endif
524
525#if ! HAVE_FTW
526extern int ftw P((const char *zdir,
527		  int (*pfn) P((const char *zfile,
528				const struct stat *qstat,
529				int iflag)),
530		  int cdescriptors));
531#endif
532
533#if ! HAVE_GETCWD && ! HAVE_GETWD
534extern char *getcwd P((char *zbuf, size_t cbuf));
535#endif
536
537#if ! HAVE_MKDIR
538extern int mkdir P((const char *zdir, int imode));
539#endif
540
541#if ! HAVE_RENAME
542extern int rename P((const char *zold, const char *znew));
543#endif
544
545#if ! HAVE_RMDIR
546extern int rmdir P((const char *zdir));
547#endif
548
549/* The working directory from which the program was run (this is set
550   by usysdep_initialize if called with INIT_GETCWD).  */
551extern char *zScwd;
552
553/* The spool directory name.  */
554extern const char *zSspooldir;
555
556/* The lock directory name.  */
557extern const char *zSlockdir;
558
559/* The local UUCP name (needed for some spool directory stuff).  */
560extern const char *zSlocalname;
561
562#endif /* ! defined (SYSDEP_H) */
563