1/* system.h
2   Header file for system dependent stuff in the Taylor UUCP package.
3   This file is not itself system dependent.
4
5   Copyright (C) 1991, 1992, 1993, 1994, 1995, 2002 Ian Lance Taylor
6
7   This file is part of the Taylor UUCP package.
8
9   This program is free software; you can redistribute it and/or
10   modify it under the terms of the GNU General Public License as
11   published by the Free Software Foundation; either version 2 of the
12   License, or (at your option) any later version.
13
14   This program is distributed in the hope that it will be useful, but
15   WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   General Public License for more details.
18
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
22
23   The author of the program may be contacted at ian@airs.com.
24   */
25
26#ifndef SYSTEM_H
27
28#define SYSTEM_H
29
30#if ANSI_C
31/* These structures are used in prototypes but are not defined in this
32   header file.  */
33struct tm;
34struct uuconf_system;
35struct uuconf_port;
36struct sconnection;
37struct sstatus;
38struct scmd;
39#endif
40
41/* Any function which returns an error should also report an error
42   message, unless otherwise indicated.
43
44   Any function that returns a char *, rather than a const char *, is
45   returning a pointer to a buffer allocated by zbufalc which must be
46   freed using ubuffree, unless otherwise indicated.  */
47
48/* The maximum length of a remote system name.  */
49extern size_t cSysdep_max_name_len;
50
51/* Initialize.  If something goes wrong, this routine should just
52   exit.  The flag argument is 0, or a combination of any of the
53   following flags.  */
54
55/* This program needs to know the current working directory.  This is
56   used because on Unix it can be expensive to determine the current
57   working directory (some versions of getcwd fork a process), but in
58   most cases we don't need to know it.  However, we are going to
59   chdir to the spool directory (unless INIT_CHDIR is set), so we have
60   to get the cwd now if we are ever going to get it.  Both uucp and
61   uux use the function fsysdep_needs_cwd to determine whether they
62   will need the current working directory, and pass the argument to
63   usysdep_initialize appropriately.  There's probably a cleaner way
64   to handle this, but this will suffice for now.  */
65#define INIT_GETCWD (01)
66
67/* This program should not chdir to the spool directory.  This may
68   only make sense on Unix.  It is set by cu.  */
69#define INIT_NOCHDIR (02)
70
71/* This program needs special access to the spool directories.  That
72   means, on Unix, this program is normally installed setuid.  */
73#define INIT_SUID (04)
74
75/* Do not close all open descriptors.  This is not used by the UUCP
76   code, but it is used by other programs which share some of the
77   system dependent libraries.  */
78#define INIT_NOCLOSE (010)
79
80extern void usysdep_initialize P((pointer puuconf, int iflags));
81
82/* Exit the program.  The fsuccess argument indicates whether to
83   return an indication of success or failure to the outer
84   environment.  This routine should not return.  */
85extern void usysdep_exit P((boolean fsuccess));
86
87/* Called when a non-standard configuration file is being used, to
88   avoid handing out privileged access.  If it returns FALSE, default
89   configuration file will be used.  This is called before the
90   usysdep_initialize function is called.  */
91extern boolean fsysdep_other_config P((const char *));
92
93/* Detach from the controlling terminal.  This probably only makes
94   sense on Unix.  It is called by uucico to try to get the modem port
95   as a controlling terminal.  It is also called by uucico before it
96   starts up uuxqt, so that uuxqt will be a complete daemon.  */
97extern void usysdep_detach P((void));
98
99/* Get the local node name if it is not specified in the configuration
100   files.  Returns NULL on error; otherwise the return value should
101   point to a static buffer.  */
102extern const char *zsysdep_localname P((void));
103
104/* Get the login name.  This is used when uucico is started up with no
105   arguments in slave mode, which causes it to assume that somebody
106   has logged in.  It also used by uucp and uux for recording the user
107   name.  This may not return NULL.  The return value should point to
108   a static buffer.  */
109extern const char *zsysdep_login_name P((void));
110
111/* Set a signal handler for a signal.  If the signal occurs, the
112   appropriate element of afSignal should be set to the signal number
113   (see the declaration of afSignal in uucp.h).  This routine might be
114   able to just use signal, but Unix requires more complex handling.
115   This is called before usysdep_initialize.  */
116extern void usysdep_signal P((int isig));
117
118/* Catch a signal.  This is actually defined as a macro in the system
119   dependent header file, and the prototype here just indicates how it
120   should be called.  It is called before a routine which must exit if
121   a signal occurs, and is expected to set do a setjmp (which is why
122   it must be a macro).  It is actually only called in one place in
123   the system independent code, before the call to read stdin in uux.
124   This is needed to handle 4.2 BSD restartable system calls, which
125   require a longjmp.  On systems which don't need to do
126   setjmp/longjmp around system calls, this can be redefined in
127   sysdep.h to TRUE.  It should return TRUE if the routine should
128   proceed, or FALSE if a signal occurred.  After having this return
129   TRUE, usysdep_start_catch should be used to start catching the
130   signal; this basically tells the signal handler that it's OK to do
131   the longjmp, if fsysdep_catch did not already do so.  */
132#ifndef fsysdep_catch
133extern boolean fsysdep_catch P((void));
134#endif
135
136/* Start catching a signal.  This is called after fsysdep_catch to
137   tell the signal handler to go ahead and do the longjmp.  This may
138   be implemented as a macro in sysdep.h.  */
139#ifndef usysdep_start_catch
140extern void usysdep_start_catch P((void));
141#endif
142
143/* Stop catching a signal.  This is called when it is no longer
144   necessary for fsysdep_catch to handle signals.  This may be
145   implemented as a macro in sysdep.h.  */
146#ifndef usysdep_end_catch
147extern void usysdep_end_catch P((void));
148#endif
149
150/* Link two files.  On Unix this should attempt the link.  If it
151   succeeds it should return TRUE with *pfworked set to TRUE.  If the
152   link fails because it must go across a device, it should return
153   TRUE with *pfworked set to FALSE.  If the link fails for some other
154   reason, it should log an error message and return FALSE.  On a
155   system which does not support links to files, this should just
156   return TRUE with *pfworked set to FALSE.  */
157extern boolean fsysdep_link P((const char *zfrom, const char *zto,
158			       boolean *pfworked));
159
160/* Get the port name.  This is used when uucico is started up in slave
161   mode to figure out which port was used to call in so that it can
162   determine any appropriate protocol parameters.  This may return
163   NULL if the port cannot be determined, which will just mean that no
164   protocol parameters are applied.  The name returned should be the
165   sort of name that would appear in the port file.  This should set
166   *pftcp_port to TRUE if it can determine that the port is a TCP
167   connection rather than a normal serial port.  The return value (if
168   not NULL) should point to a static buffer.  */
169extern const char *zsysdep_port_name P((boolean *pftcp_port));
170
171/* Expand a file name on the local system.  On Unix, if the zfile
172   argument begins with ~user/ it goes in that users home directory,
173   and if it begins with ~/ it goes in the public directory (the
174   public directory is passed to this routine, since each system may
175   have its own public directory).  Similar conventions may be
176   desirable on other systems.  This should always return an absolute
177   path name, probably in the public directory.  It should return NULL
178   on error; otherwise the return value should be allocated using
179   zbufcpy or zbufalc.  If pfbadname is not NULL, then if the function
180   returns NULL *pfbadname should be set to TRUE if the error is just
181   that the file name is badly specified; *pfbadname should be set to
182   FALSE for some sort of internal error.  */
183extern char *zsysdep_local_file P((const char *zname,
184				   const char *zpubdir,
185				   boolean *pfbadname));
186
187/* Return whether a file name is in a directory, and check for read or
188   write access.  This should check whether zfile is within zdir (or
189   is zdir itself).  If it is not, it should return FALSE.  If zfile
190   is in zdir, then fcheck indicates whether further checking should
191   be done.  If fcheck is FALSE, no further checking is done.
192   Otherwise, if freadable is TRUE the user zuser should have search
193   access to all directories from zdir down to zfile and should have
194   read access on zfile itself (if zfile does not exist, or is not a
195   regular file, this function may return FALSE but does not have to).
196   If freadable is FALSE, the user zuser should have search access to
197   all directories from zdir down to zfile and should have write
198   access on zfile (which may be a directory, or may not actually
199   exist, which is acceptable).  The zuser argument may be NULL, in
200   which case the check should be made for any user, not just zuser.
201   There is no way for this function to return error.  */
202extern boolean fsysdep_in_directory P((const char *zfile,
203				       const char *zdir,
204				       boolean fcheck,
205				       boolean freadable,
206				       const char *zuser));
207
208/* Return TRUE if a file exists, FALSE otherwise.  There is no way to
209   return error.  */
210extern boolean fsysdep_file_exists P((const char *zfile));
211
212/* Start up a program.  If the ffork argument is true, this should
213   spawn a new process and return.  If the ffork argument is false,
214   this may either return or not.  The three string arguments may be
215   catenated together to form the program to execute; I did it this
216   way to make it easy to call execl(2), and because I never needed
217   more than two arguments.  The program will always be "uucico" or
218   "uuxqt".  The return value should be TRUE on success, FALSE on
219   error.  */
220extern boolean fsysdep_run P((boolean ffork, const char *zprogram,
221			      const char *zarg1, const char *zarg2));
222
223/* Send a mail message.  This function will be passed an array of
224   strings.  All necessary newlines are already included; the strings
225   should simply be concatenated together to form the mail message.
226   It should return FALSE on error, although the return value is often
227   ignored.  */
228extern boolean fsysdep_mail P((const char *zto, const char *zsubject,
229			       int cstrs, const char **paz));
230
231/* Get the time in seconds since some epoch.  The actual epoch is
232   unimportant, so long as the time values are consistent across
233   program executions and the value is never negative.  If the
234   pimicros argument is not NULL, it should be set to the number of
235   microseconds (if this is not available, *pimicros should be set to
236   zero).  */
237extern long ixsysdep_time P((long *pimicros));
238
239/* Get the time in seconds and microseconds (millionths of a second)
240   since some epoch.  The actual epoch is not important, and it may
241   change in between program invocations; this is provided because on
242   Unix the times function may be used.  If microseconds can not be
243   determined, *pimicros can just be set to zero.  */
244extern long ixsysdep_process_time P((long *pimicros));
245
246/* Parse the value returned by ixsysdep_time into a struct tm.  I
247   assume that this structure is defined in <time.h>.  This is
248   basically just localtime, except that the ANSI function takes a
249   time_t which may not be what is returned by ixsysdep_time.  */
250extern void usysdep_localtime P((long itime, struct tm *q));
251
252/* Sleep for a number of seconds.  */
253extern void usysdep_sleep P((int cseconds));
254
255/* Pause for half a second, or 1 second if subsecond sleeps are not
256   possible.  */
257extern void usysdep_pause P((void));
258
259/* Lock a remote system.  This should return FALSE if the system is
260   already locked (no error should be reported).  */
261extern boolean fsysdep_lock_system P((const struct uuconf_system *qsys));
262
263/* Unlock a remote system.  This should return FALSE on error
264   (although the return value is generally ignored).  */
265extern boolean fsysdep_unlock_system P((const struct uuconf_system *qsys));
266
267/* Get the conversation sequence number for a remote system, and
268   increment it for next time.  This should return -1 on error.  */
269extern long ixsysdep_get_sequence P((const struct uuconf_system *qsys));
270
271/* Get the status of a remote system.  This should return FALSE on
272   error.  Otherwise it should set *qret to the status.  If no status
273   information is available, this should set *qret to sensible values
274   and return TRUE.  If pfnone is not NULL, then it should be set to
275   TRUE if no status information was available or FALSE otherwise.  */
276extern boolean fsysdep_get_status P((const struct uuconf_system *qsys,
277				     struct sstatus *qret,
278				     boolean *pfnone));
279
280/* Set the status of a remote system.  This should return FALSE on
281   error.  The system will be locked before this call is made.  */
282extern boolean fsysdep_set_status P((const struct uuconf_system *qsys,
283				     const struct sstatus *qset));
284
285/* See whether a remote system is permitted to log in.  This is just
286   to support the remote.unknown shell script for HDB.  The zscript
287   argument is the script name, as return by uuconf_remote_unknown.
288   The zsystem argument is the name given by the remote system.  If
289   the system is not permitted to log in, this function should log an
290   error and return FALSE.  */
291extern boolean fsysdep_unknown_caller P((const char *zscript,
292					 const char *zsystem));
293
294/* Check whether there is work for a remote system.  It should return
295   TRUE if there is work, FALSE otherwise; there is no way to indicate
296   an error.  */
297extern boolean fsysdep_has_work P((const struct uuconf_system *qsys));
298
299/* Initialize the work scan.  This will be called before
300   fsysdep_get_work.  The bgrade argument is the minimum grade of
301   execution files that should be considered (e.g. a bgrade of 'd'
302   will allow all grades from 'A' to 'Z' and 'a' to 'd').  The cmax
303   argument is the maximum number of items to return in calls to
304   fsysdep_get_work; a value of 0 means there is no limit.  This
305   function should return FALSE on error.  */
306extern boolean fsysdep_get_work_init P((const struct uuconf_system *qsys,
307					int bgrade, unsigned int cmax));
308
309/* Get the next command to be executed for a remote system.  The
310   bgrade and cmax arguments will be the same as for
311   fsysdep_get_work_init; probably only one of these functions will
312   use them, namely the function for which it is more convenient.
313   This should return FALSE on error.  The structure pointed to by
314   qcmd should be filled in.  The strings may point into a static
315   buffer; they will be copied out if necessary.  If there is no more
316   work, this should set qcmd->bcmd to 'H' and return TRUE.  This
317   should set qcmd->pseq to something which can be passed to
318   fsysdep_did_work to remove the job from the queue when it has been
319   completed.  This may set qcmd->bcmd to 'P' to represent a poll
320   file; the main code will just pass the pseq element of such a
321   structure to fsysdep_did_work if the system is called.  */
322extern boolean fsysdep_get_work P((const struct uuconf_system *qsys,
323				   int bgrade, unsigned int cmax,
324				   struct scmd *qcmd));
325
326/* Remove a job from the work queue.  This must also remove the
327   temporary file used for a send command, if there is one.  It should
328   return FALSE on error.  */
329extern boolean fsysdep_did_work P((pointer pseq));
330
331/* Save the temporary file for a send command.  This function should
332   return a string that will be put into a mail message.  On success
333   this string should say something like ``The file has been saved as
334   ...''.  On failure it could say something like ``The file could not
335   be saved because ...''.  If there is no temporary file, or for some
336   reason it's not appropriate to include a message, this function
337   should just return NULL.  This function is used when a file send
338   fails for some reason, to make sure that we don't completely lost
339   the file.  */
340extern const char *zsysdep_save_temp_file P((pointer pseq));
341
342/* Save a file in a location used to hold corrupt files.  This is
343   called if a bad execution file is found by uuxqt.  This should
344   return the new name of the file (allocated by zbufalc), or NULL if
345   the move failed (in which the original file should remain).  */
346extern char *zsysdep_save_corrupt_file P((const char *zfile));
347
348/* Save a file in a location used to hold failed execution files.
349   This is called if a uuxqt execution fails.  This should return the
350   new name of the file (allocated by zbufalc), or NULL if the move
351   failed (in which case the original file should remain).  */
352extern char *zsysdep_save_failed_file P((const char *zfile));
353
354/* Cleanup anything left over by fsysdep_get_work_init and
355   fsysdep_get_work.  This may be called even though
356   fsysdep_get_work_init has not been.  */
357extern void usysdep_get_work_free P((const struct uuconf_system *qsys));
358
359/* Add a base name to a file if it is a directory.  If zfile names a
360   directory, then return a string naming a file within the directory
361   with the base file name of zname.  This should return NULL on
362   error.  */
363extern char *zsysdep_add_base P((const char *zfile,
364				 const char *zname));
365
366/* Get a file name from the spool directory.  This should return NULL
367   on error.  The pseq argument is TRUE if the file was found from
368   searching the work directory; this is, unfortunately, needed to
369   support SVR4 spool directories.  */
370extern char *zsysdep_spool_file_name P((const struct uuconf_system *qsys,
371					const char *zfile,
372					pointer pseq));
373
374/* Make necessary directories.  This should create all non-existent
375   directories for a file.  If the fpublic argument is TRUE, anybody
376   should be permitted to create and remove files in the directory;
377   otherwise anybody can list the directory, but only the UUCP system
378   can create and remove files.  It should return FALSE on error.  */
379extern boolean fsysdep_make_dirs P((const char *zfile, boolean fpublic));
380
381/* Create a stdio file, setting appropriate protection.  If the
382   fpublic argument is TRUE, the file is made publically accessible;
383   otherwise it is treated as a private data file.  If the fappend
384   argument is TRUE, the file is opened in append mode; otherwise any
385   previously existing file of the same name is removed.  If the
386   fmkdirs argument is TRUE, then any necessary directories should
387   also be created.  On a system in which file protections are
388   unimportant and the necessary directories exist, this may be
389   implemented as
390
391   fopen (zfile, fappend ? "a" : "w");
392
393   */
394extern FILE *esysdep_fopen P((const char *zfile, boolean fpublic,
395			      boolean fappend, boolean fmkdirs));
396
397/* Open a file, using the access permission of the user who invoked
398   the program.  The frd argument is TRUE if the file should be opened
399   for reading, and the fbinary argument is TRUE if the file should be
400   opened as a binary file (this is ignored on Unix, since there all
401   files are binary files).  This returns an openfile_t, not a FILE *.
402   This is supposed to be able to open a file even if it can not be
403   read by the uucp user.  This is not possible on some older Unix
404   systems.  */
405extern openfile_t esysdep_user_fopen P((const char *zfile,
406					boolean frd, boolean fbinary));
407
408/* Open a file to send to another system; the qsys argument is the
409   system the file is being sent to.  If fcheck is TRUE, it should
410   make sure that the file is readable by zuser (if zuser is NULL the
411   file must be readable by anybody).  This is to eliminate a window
412   between fsysdep_in_directory and esysdep_open_send.  If an error
413   occurs, it should return EFILECLOSED.  */
414extern openfile_t esysdep_open_send P((const struct uuconf_system *qsys,
415				       const char *zname,
416				       boolean fcheck,
417				       const char *zuser));
418
419/* Return a temporary file name to receive into.  This file will be
420   opened by esysdep_open_receive.  The qsys argument is the system
421   the file is coming from, the zto argument is the name the file will
422   have after it has been fully received, the ztemp argument, if it is
423   not NULL, is from the command sent by the remote system, and the
424   frestart argument is TRUE if the protocol and remote system permit
425   file transfers to be restarted.  The return value must be freed
426   using ubuffree.  The function should return NULL on error.  */
427extern char *zsysdep_receive_temp P((const struct uuconf_system *qsys,
428				     const char *zfile,
429				     const char *ztemp,
430				     boolean frestart));
431
432/* Open a file to receive from another system.  The zreceive argument
433   is the return value of zsysdep_receive_temp with the same qsys,
434   zfile and ztemp arguments.  If the function can determine that this
435   file has already been partially received, it should set *pcrestart
436   to the number of bytes that have been received.  If the file has
437   not been partially received, *pcrestart should be set to -1.
438   pcrestart will be passed in as NULL if file restart is not
439   supported by the protocol or the remote system.  The function
440   should return EFILECLOSED on error.  After the file is written,
441   fsysdep_move_file will be called to move the file to its final
442   destination, and to set the correct file mode.  */
443extern openfile_t esysdep_open_receive P((const struct uuconf_system *qsys,
444					  const char *zto,
445					  const char *ztemp,
446					  const char *zreceive,
447					  long *pcrestart));
448
449/* Move a file.  This is used to move a received file to its final
450   location.  The zto argument is the file to create.  The zorig
451   argument is the name of the file to move.  If fmkdirs is TRUE, then
452   any necessary directories are created; fpublic indicates whether
453   they should be publically writeable or not.  If fcheck is TRUE,
454   this should make sure the directory is writeable by the user zuser
455   (if zuser is NULL, then it must be writeable by any user); this is
456   to avoid a window of vulnerability between fsysdep_in_directory and
457   fsysdep_move_file.  This function should return FALSE on error, in
458   which case the zorig file should still exist.  */
459extern boolean fsysdep_move_file P((const char *zorig, const char *zto,
460				    boolean fmkdirs, boolean fpublic,
461				    boolean fcheck, const char *zuser));
462
463/* Change the mode of a file.  The imode argument is a Unix mode.
464   This should return FALSE on error.  */
465extern boolean fsysdep_change_mode P((const char *zfile,
466				      unsigned int imode));
467
468/* Truncate a file which we are receiving into.  This may be done by
469   closing the original file, removing it and reopening it.  This
470   should return FALSE on error.  */
471extern openfile_t esysdep_truncate P((openfile_t e, const char *zname));
472
473/* Sync a file to disk.  If this fails it should log an error using
474   the zmsg parameter, and return FALSE.  This is controlled by the
475   FSYNC_ON_CLOSE macro in policy.h.  */
476extern boolean fsysdep_sync P((openfile_t e, const char *zmsg));
477
478/* It is possible for the acknowledgement of a received file to be
479   lost.  The sending system will then now know that the file was
480   correctly received, and will send it again.  This can be a problem
481   particularly with protocols which support channels, since they may
482   send several small files in a single window, all of which may be
483   received correctly although the sending system never sees the
484   acknowledgement.  If these files involve an execution, the
485   execution will happen twice, which will be bad.
486
487   This function is called when a file is completely received.  It is
488   supposed to try and remember the reception, in case the connection
489   is lost.  It is passed the system, the file name to receive to, and
490   the temporary file name from the sending system.  It should return
491   FALSE on error.  */
492extern boolean fsysdep_remember_reception P((const struct uuconf_system *qsys,
493					     const char *zto,
494					     const char *ztemp));
495
496/* This function is called to see if a file has already been received
497   successfully.  It gets the same arguments as
498   fsysdep_remember_reception.  It should return TRUE if the file was
499   already received, FALSE otherwise.  There is no way to report
500   error.  */
501extern boolean fsysdep_already_received P((const struct uuconf_system *qsys,
502					   const char *zto,
503					   const char *ztemp));
504
505/* This function is called when it is no longer necessary to remember
506   that a file has been received.  This will be called when the
507   protocol knows that the receive message has been acknowledged.  It
508   gets the same arguments as fsysdep_remember_reception.  it should
509   return FALSE on error.  */
510extern boolean fsysdep_forget_reception P((const struct uuconf_system *qsys,
511					   const char *zto,
512					   const char *ztemp));
513
514/* Start expanding a wildcarded file name.  This should return FALSE
515   on error; otherwise subsequent calls to zsysdep_wildcard should
516   return file names.  */
517extern boolean fsysdep_wildcard_start P((const char *zfile));
518
519/* Get the next wildcard name.  This should return NULL when there are
520   no more names to return.  The return value should be freed using
521   ubuffree.  The argument should be the same as that to
522   fsysdep_wildcard_start.  There is no way to return error.  */
523extern char *zsysdep_wildcard P((const char *zfile));
524
525/* Finish getting wildcard names.  This may be called before or after
526   zsysdep_wildcard has returned NULL.  It should return FALSE on
527   error.  */
528extern boolean fsysdep_wildcard_end P((void));
529
530/* Prepare to execute a bunch of file transfer requests.  This should
531   make an entry in the spool directory so that the next time uucico
532   is started up it will transfer these files.  The bgrade argument
533   specifies the grade of the commands.  The commands themselves are
534   in the pascmds array, which has ccmds entries.  The function should
535   return NULL on error, or the jobid on success.  The jobid is a
536   string that may be printed or passed to fsysdep_kill_job and
537   related functions, but is otherwise uninterpreted.  If pftemp is
538   not NULL, then on an error return, *pftemp will be TRUE for a
539   temporary error, FALSE for a permanent error.  */
540extern char *zsysdep_spool_commands P((const struct uuconf_system *qsys,
541				       int bgrade, int ccmds,
542				       const struct scmd *pascmds,
543				       boolean *pftemp));
544
545/* Get a file name to use for a data file to be copied to another
546   system.  The ztname, zdname and zxname arguments will all either be
547   NULL or point to an array of CFILE_NAME_LEN characters in length.
548   The ztname array should be set to a temporary file name that could
549   be passed to zsysdep_spool_file_name to retrieve the return value
550   of this function; this will be appropriate for the temporary name
551   in a send request.  The zdname array should be set to a data file
552   name that is appropriate for the spool directory of the other
553   system; this will be appropriate for the name of the destination
554   file in a send request of a data file for an execution of some
555   sort.  The zxname array should be set to an execute file name that
556   is appropriate for the other system.  The zlocalname argument is
557   the name of the local system as seen by the remote system, the
558   bgrade argument is the grade, and fxqt is TRUE if this file is
559   going to become an execution file.  This should return NULL on
560   error.  */
561#define CFILE_NAME_LEN (15)
562
563extern char *zsysdep_data_file_name P((const struct uuconf_system *qsys,
564				       const char *zlocalname,
565				       int bgrade, boolean fxqt,
566				       char *ztname, char *zdname,
567				       char *zxname));
568
569/* Get a name for a local execute file.  This is used by uux for a
570   local command with remote files.  Returns NULL on error.  */
571extern char *zsysdep_xqt_file_name P((void));
572
573/* Beginning getting execute files.  To get a list of execute files,
574   first fsysdep_get_xqt_init is called, then zsysdep_get_xqt is
575   called several times until it returns NULL, then finally
576   usysdep_get_xqt_free is called.  If the zsystem argument is not
577   NULL, it is the name of a system for which execution files are
578   desired.  */
579extern boolean fsysdep_get_xqt_init P((const char *zsystem));
580
581/* Get the next execute file.  This should return NULL when finished
582   (with *pferr set to FALSE).  The zsystem argument should be the
583   same string as that passed to fsysdep_get_xqt_init.  On an error
584   this should return NULL with *pferr set to TRUE.  This should set
585   *pzsystem to the name of the system for which the execute file was
586   created; this is not guaranteed to match the zsystem argument--that
587   must be double checked by the caller.  Both the return value and
588   *pzsystem should be freed using ubuffree.  */
589extern char *zsysdep_get_xqt P((const char *zsystem, char **pzsystem,
590				boolean *pferr));
591
592/* Clean up after getting execute files.  The zsystem argument should
593   be the same string as that passed to fsysdep_get_xqt_init.  */
594extern void usysdep_get_xqt_free P((const char *zsystem));
595
596/* Get the absolute pathname of a command to execute.  This is given
597   the legal list of commands (which may be the special case "ALL")
598   and the path.  It must return an absolute pathname to the command.
599   If it gets an error it should set *pferr to TRUE and return NULL;
600   if the command is not found it should set *pferr to FALSE and
601   return NULL.  */
602extern char *zsysdep_find_command P((const char *zcmd, char **pzcmds,
603				     char **pzpath, boolean *pferr));
604
605/* Expand file names for uuxqt.  This exists because uuxqt on Unix has
606   to expand file names which begin with a ~.  It does not want to
607   expand any other type of file name, and it turns a double ~ into a
608   single one without expanding.  If this returns NULL, the file does
609   not need to be changed; otherwise it returns a zbufalc'ed string.
610   There is no way to report error.  */
611extern char *zsysdep_xqt_local_file P((const struct uuconf_system *qsys,
612				       const char *zfile));
613
614#if ! ALLOW_FILENAME_ARGUMENTS
615/* Check an argument to an execution command to make sure that it
616   doesn't refer to a file name that may not be accessed.  This should
617   check the argument to see if it is a filename.  If it is, it should
618   either reject it out of hand or it should call fin_directory_list
619   on the file with both qsys->zremote_receive and qsys->zremote_send.
620   If the file is rejected, it should log an error and return FALSE.
621   Otherwise it should return TRUE.  */
622extern boolean fsysdep_xqt_check_file P((const struct uuconf_system *qsys,
623					 const char *zfile));
624#endif /* ! ALLOW_FILENAME_ARGUMENTS */
625
626/* Run an execute file.  The arguments are:
627
628   qsys -- system for which execute file was created
629   zuser -- user who requested execution
630   pazargs -- list of arguments to command (element 0 is command)
631   zfullcmd -- command and arguments stuck together in one string
632   zinput -- file name for standard input (may be NULL)
633   zoutput -- file name for standard output (may be NULL)
634   fshell -- if TRUE, use /bin/sh to execute file
635   ilock -- return value of ixsysdep_lock_uuxqt
636   pzerror -- set to name of standard error file
637   pftemp -- set to TRUE if error is temporary, FALSE otherwise
638
639   If fshell is TRUE, the command should be executed with /bin/sh
640   (obviously, this can only really be done on Unix systems).  If an
641   error occurs this should return FALSE and set *pftemp
642   appropriately.  *pzerror should be freed using ubuffree.  */
643extern boolean fsysdep_execute P((const struct uuconf_system *qsys,
644				  const char *zuser,
645				  const char **pazargs,
646				  const char *zfullcmd,
647				  const char *zinput,
648				  const char *zoutput,
649				  const char *zchdir,
650				  boolean fshell,
651				  int ilock,
652				  char **pzerror,
653				  boolean *pftemp));
654
655/* Lock for uuxqt execution.  If the cmaxuuxqts argument is not zero,
656   this should make sure that no more than cmaxuuxqts uuxqt processes
657   are running at once.  Also, only one uuxqt may execute a particular
658   command (specified by the -c option) at a time.  If zcmd is not
659   NULL, it is a command that must be locked.  This should return a
660   nonnegative number which will be passed to other routines,
661   including fsysdep_unlock_uuxqt, or -1 on error.  */
662extern int ixsysdep_lock_uuxqt P((const char *zcmd,
663				  int cmaxuuxqts));
664
665/* Unlock a uuxqt process.  This is passed the return value of
666   ixsysdep_lock_uuxqt, as well as the arguments passed to
667   ixsysdep_lock_uuxqt.  It may return FALSE on error, but at present
668   the return value is ignored.  */
669extern boolean fsysdep_unlock_uuxqt P((int iseq, const char *zcmd,
670				       int cmaxuuxqts));
671
672/* See whether a particular uuxqt command is locked.  This should
673   return TRUE if the command is locked (because ixsysdep_lock_uuxqt
674   was called with it as an argument), FALSE otherwise.  There is no
675   way to return error.  */
676extern boolean fsysdep_uuxqt_locked P((const char *zcmd));
677
678/* Lock an execute file in order to execute it.  This should return
679   FALSE if the execute file is already locked.  There is no way to
680   return error.  */
681extern boolean fsysdep_lock_uuxqt_file P((const char *zfile));
682
683/* Unlock an execute file.  This should return FALSE on error.  */
684extern boolean fsysdep_unlock_uuxqt_file P((const char *zfile));
685
686/* Lock the execution directory.  The ilock argument is the return
687   value of ixsysdep_lock_uuxqt.  This should return FALSE if the
688   directory is already locked.  There is no way to return error.  */
689extern boolean fsysdep_lock_uuxqt_dir P((int ilock));
690
691/* Remove all files in the execution directory, and unlock it.  This
692   should return FALSE on error.  */
693extern boolean fsysdep_unlock_uuxqt_dir P((int ilock));
694
695/* Copy files into the execution directory indicated by ilock.  The
696   code will already have checked that all the files exist.  The
697   copying may be done using the link system call.  The elements in
698   the pzfrom array will be complete filenames.  The elements in the
699   pzto array will be either NULL (in which case the file should not
700   be copied) or simple base names.  If pzinput and *pzinput are not
701   NULL, then *pzinput is the name of the standard input file; if it
702   is the same as any element of pzfrom, then *pzinput will be set to
703   the zbufcpy of the full path for the corresponding pzto value, if
704   any.  */
705extern boolean fsysdep_copy_uuxqt_files P((int cfiles,
706					   const char *const *pzfrom,
707					   const char *const *pzto,
708					   int ilock,
709					   char **pzinput));
710
711/* Expand a file name on the local system, defaulting to the current
712   directory.  This is just like zsysdep_local_file, except that
713   relative files are placed in the working directory the program
714   started in rather than in the public directory.  This should return
715   NULL on error.  */
716extern char *zsysdep_local_file_cwd P((const char *zname,
717				       const char *zpubdir,
718				       boolean *pfbadname));
719
720/* Add the working directory to a file name.  The named file is
721   actually on a remote system.  If the file already has a directory,
722   it should not be changed.  This should return NULL on error.  */
723extern char *zsysdep_add_cwd P((const char *zfile));
724
725/* See whether a file name will need the current working directory
726   when zsysdep_local_file_cwd or zsysdep_add_cwd is called on it.
727   This will be called before usysdep_initialize.  It should just
728   check whether the argument is an absolute path.  See the comment
729   above usysdep_initialize in this file for an explanation of why
730   things are done this way.  */
731extern boolean fsysdep_needs_cwd P((const char *zfile));
732
733/* Get the base name of a file.  The file will be a local file name,
734   and this function should return the base file name, ideally in a
735   form which will make sense on most systems; it will be used if the
736   destination of a uucp is a directory.  */
737extern char *zsysdep_base_name P((const char *zfile));
738
739/* Return a filename within a directory.  */
740extern char *zsysdep_in_dir P((const char *zdir, const char *zfile));
741
742/* Get the mode of a file.  This should return a Unix style file mode.
743   It should return 0 on error.  */
744extern unsigned int ixsysdep_file_mode P((const char *zfile));
745
746/* Get the mode of a file using the permissions of the user who
747   invoked the program.  This should return a Unix style file mode.
748   It should return 0 on error.  */
749extern unsigned int ixsysdep_user_file_mode P((const char *zfile));
750
751/* See whether the user has access to a file.  This is called by uucp
752   and uux to prevent copying of a file which uucp can read but the
753   user cannot.  If access is denied, this should log an error message
754   and return FALSE.  */
755extern boolean fsysdep_access P((const char *zfile));
756
757/* See whether the daemon has access to a file.  This is called by
758   uucp and uux when a file is queued up for transfer without being
759   copied into the spool directory.  It is merely an early error
760   check, as the daemon would of course discover the error itself when
761   it tried the transfer.  If access would be denied, this should log
762   an error message and return FALSE.  */
763extern boolean fsysdep_daemon_access P((const char *zfile));
764
765/* Translate a destination from system!user to a place in the public
766   directory where uupick will get the file.  On Unix this produces
767   system!~/receive/user/localname, and that's probably what it has to
768   produce on any other system as well.  Returns NULL on a usage
769   error, or otherwise returns string allocated by zbufcpy.  */
770extern char *zsysdep_uuto P((const char *zdest,
771			     const char *zlocalname));
772
773/* Return TRUE if a pathname exists and is a directory.  */
774extern boolean fsysdep_directory P((const char *zpath));
775
776/* Walk a directory tree.  The zdir argument is the directory to walk.
777   The pufn argument is a function to call on each regular file in the
778   tree.  The first argument to pufn should be the full filename; the
779   second argument to pufn should be the filename relative to zdir;
780   the third argument to pufn should be the pinfo argument to
781   usysdep_walk_tree.  The usysdep_walk_tree function should return
782   FALSE on error.  */
783extern boolean usysdep_walk_tree P((const char *zdir,
784				    void (*pufn) P((const char *zfull,
785						    const char *zrelative,
786						    pointer pinfo)),
787				    pointer pinfo));
788
789/* Return the jobid of a work file, given the sequence value.  On
790   error this should log an error and return NULL.  The jobid is a
791   string which may be printed out and read in and passed to
792   fsysdep_kill_job, etc., but is not otherwise interpreted.  */
793extern char *zsysdep_jobid P((const struct uuconf_system *qsys,
794			      pointer pseq));
795
796/* See whether the current user is privileged.  Privileged users are
797   permitted to kill jobs submitted by another user, and they are
798   permitted to use the -u argument to uucico; other uses of this call
799   may be added later.  This should return TRUE if permission is
800   granted, FALSE otherwise.  */
801extern boolean fsysdep_privileged P((void));
802
803/* Kill a job, given the jobid.  This should remove all associated
804   files and in general eliminate the job completely.  On error it
805   should log an error message and return FALSE.  */
806extern boolean fsysdep_kill_job P((pointer puuconf,
807				   const char *zjobid));
808
809/* Rejuvenate a job, given the jobid.  If possible, this should update
810   the time associated with the job such that it will not be
811   eliminated by uustat -K or similar programs that check the creation
812   time.  This should affect the return value of ixsysdep_work_time.
813   On error it should log an error message and return FALSE.  */
814extern boolean fsysdep_rejuvenate_job P((pointer puuconf,
815					 const char *zjobid));
816
817/* Get the time a job was queued, given the sequence number.  There is
818   no way to indicate error.  The return value must use the same epoch
819   as ixsysdep_time.  */
820extern long ixsysdep_work_time P((const struct uuconf_system *qsys,
821				  pointer pseq));
822
823/* Get the time a file was created.  This is called by uustat on
824   execution files.  There is no way to indicate error.  The return
825   value must use the same epoch as ixsysdep_time.  */
826extern long ixsysdep_file_time P((const char *zfile));
827
828/* Touch a file to make it appear as though it was created at the
829   current time.  This is called by uustat on execution files.  On
830   error this should log an error message and return FALSE.  */
831extern boolean fsysdep_touch_file P((const char *zfile));
832
833/* Get the size in bytes of a file.  If this file does not exist, this
834   should not give an error message, but should return -1.  If some
835   other error occurs, this should return -2.  */
836extern long csysdep_size P((const char *zfile));
837
838/* Return the amount of free space on the containing the given file
839   name (the file may or may not exist).  If the amount of free space
840   cannot be determined, the function should return -1.  */
841extern long csysdep_bytes_free P((const char *zfile));
842
843/* Start getting status information for all systems with available
844   status information.  There may be status information for unknown
845   systems, which is why this series of functions is used.  The phold
846   argument is used to pass information around, to possibly avoid the
847   use of static variables.  On error this should log an error and
848   return FALSE.  */
849extern boolean fsysdep_all_status_init P((pointer *phold));
850
851/* Get status information for the next system.  This should return the
852   system name and fill in the qstat argument.  The phold argument
853   will be that set by fsysdep_all_status_init.  On error this should
854   log an error, set *pferr to TRUE, and return NULL.  */
855extern char *zsysdep_all_status P((pointer phold, boolean *pferr,
856				   struct sstatus *qstat));
857
858/* Free up anything allocated by fsysdep_all_status_init and
859   zsysdep_all_status.  The phold argument is that set by
860   fsysdep_all_status_init.  */
861extern void usysdep_all_status_free P((pointer phold));
862
863/* Display the process status of all processes holding lock files.
864   This is uustat -p.  The return value is passed to usysdep_exit.  */
865extern boolean fsysdep_lock_status P((void));
866
867/* Return TRUE if the user has legitimate access to the port.  This is
868   used by cu to control whether the user can open a port directly,
869   rather than merely being able to dial out on it.  Opening a port
870   directly allows the modem to be reprogrammed.  */
871extern boolean fsysdep_port_access P((struct uuconf_port *qport));
872
873/* Return whether the given port could be named by the given line.  On
874   Unix, the line argument would be something like "ttyd0", and this
875   function should return TRUE if the named port is "/dev/ttyd0".  */
876extern boolean fsysdep_port_is_line P((struct uuconf_port *qport,
877				       const char *zline));
878
879/* Set the terminal into raw mode.  In this mode no input characters
880   should be treated specially, and characters should be made
881   available as they are typed.  The original terminal mode should be
882   saved, so that it can be restored by fsysdep_terminal_restore.  If
883   flocalecho is TRUE, then local echoing should still be done;
884   otherwise echoing should be disabled.  This function returns FALSE
885   on error.  */
886extern boolean fsysdep_terminal_raw P((boolean flocalecho));
887
888/* Restore the terminal back to the original setting, before
889   fsysdep_terminal_raw was called.  Returns FALSE on error.  */
890extern boolean fsysdep_terminal_restore P((void));
891
892/* Read a line from the terminal.  The fsysdep_terminal_raw function
893   will have been called.  This should print the zprompt argument
894   (unless it is NULL) and return the line, allocated by zbufcpy, or
895   NULL on error.  */
896extern char *zsysdep_terminal_line P((const char *zprompt));
897
898/* Write a line to the terminal, ending with a newline.  This is
899   basically just puts (zline, stdout), except that the terminal will
900   be in raw mode, so on ASCII Unix systems the line needs to end with
901   \r\n.  */
902extern boolean fsysdep_terminal_puts P((const char *zline));
903
904/* If faccept is TRUE, permit the user to generate signals from the
905   terminal.  If faccept is FALSE, turn signals off again.  After
906   fsysdep_terminal_raw is called, signals should be off.  Return
907   FALSE on error.  */
908extern boolean fsysdep_terminal_signals P((boolean faccept));
909
910/* The cu program expects the system dependent code to handle the
911   details of copying data from the communications port to the
912   terminal.  This should be set up by fsysdep_cu_init, and done while
913   fsysdep_cu is called.  It is permissible to do it on a continual
914   basis (on Unix a subprocess handles it) so long as the copying can
915   be stopped by the fsysdep_cu_copy function.
916
917   The fsysdep_cu_init function does any system dependent
918   initialization needed for this.  */
919extern boolean fsysdep_cu_init P((struct sconnection *qconn));
920
921/* Copy all data from the communications port to the terminal, and all
922   data from the terminal to the communications port.  Keep this up
923   until the escape character *zCuvar_escape is seen.  Set *pbcmd to
924   the character following the escape character; after the escape
925   character, zlocalname should be printed, possibly after a delay.
926   If two escape characters are entered in sequence, this function
927   should send a single escape character to the port, and not return.
928   Returns FALSE on error.  */
929extern boolean fsysdep_cu P((struct sconnection *qconn,
930			     char *pbcmd,
931			     const char *zlocalname));
932
933/* If fcopy is TRUE, start copying data from the communications port
934   to the terminal.  If fcopy is FALSE, stop copying data.  This
935   function may be called several times during a cu session.  It
936   should return FALSE on error.  */
937extern boolean fsysdep_cu_copy P((boolean fcopy));
938
939/* Stop copying data from the communications port to the terminal, and
940   generally clean up after fsysdep_cu_init and fsysdep_cu.  Returns
941   FALSE on error.  */
942extern boolean fsysdep_cu_finish P((void));
943
944/* Run a shell command.  If zcmd is NULL, or *zcmd == '\0', just
945   start up a shell.  The second argument is one of the following
946   values.  This should return FALSE on error.  */
947enum tshell_cmd
948{
949  /* Attach stdin and stdout to the terminal.  */
950  SHELL_NORMAL,
951  /* Attach stdout to the communications port, stdin to the terminal.  */
952  SHELL_STDOUT_TO_PORT,
953  /* Attach stdin to the communications port, stdout to the terminal.  */
954  SHELL_STDIN_FROM_PORT,
955  /* Attach both stdin and stdout to the communications port.  */
956  SHELL_STDIO_ON_PORT
957};
958
959extern boolean fsysdep_shell P((struct sconnection *qconn,
960				const char *zcmd,
961				enum tshell_cmd tcmd));
962
963/* Change directory.  If zdir is NULL, or *zdir == '\0', change to the
964   user's home directory.  Return FALSE on error.  */
965extern boolean fsysdep_chdir P((const char *zdir));
966
967/* Suspend the current process.  This is only expected to work on Unix
968   versions that support SIGTSTP.  In general, people can just shell
969   out.  */
970extern boolean fsysdep_suspend P((void));
971
972/* Start getting files for uupick.  The zsystem argument may be NULL
973   to get files from all systems, or it may specify a particular
974   system.  The zpubdir argument is the public directory to use.  This
975   returns FALSE on error.  */
976extern boolean fsysdep_uupick_init P((const char *zsystem,
977				      const char *zpubdir));
978
979/* Get the next file for uupick.  This returns the basic file name.
980   It sets *pzfull to the full name, and *pzfrom to the name of the
981   system which sent this file over; both should be freed using
982   ubuffree.  *pzfull should be passed to ubuffree after it is no
983   longer needed.  The zsystem and zpubdir arguments should be the
984   same as the arguments to fsysdep_uupick_init.  This returns NULL
985   when all files been returned.  */
986extern char *zsysdep_uupick P((const char *zsystem, const char *zpubdir,
987			       char **pzfrom, char **pzfull));
988
989/* Clean up after getting files for uupick.  */
990extern boolean fsysdep_uupick_free P((const char *zsystem,
991				      const char *zpubdir));
992
993/* Translate a local file name for uupick.  On Unix this is just like
994   zsysdep_local_file_cwd except that a file beginning with ~/ is
995   placed in the user's home directory rather than in the public
996   directory.  */
997extern char *zsysdep_uupick_local_file P((const char *zfile,
998					  boolean *pfbadname));
999
1000/* Remove a directory and all the files in it.  */
1001extern boolean fsysdep_rmdir P((const char *zdir));
1002
1003#endif /* ! defined (SYSTEM_H) */
1004