/* system.h Header file for system dependent stuff in the Taylor UUCP package. This file is not itself system dependent. Copyright (C) 1991, 1992, 1993, 1994, 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 SYSTEM_H #define SYSTEM_H #if ANSI_C /* These structures are used in prototypes but are not defined in this header file. */ struct tm; struct uuconf_system; struct uuconf_port; struct sconnection; struct sstatus; struct scmd; #endif /* Any function which returns an error should also report an error message, unless otherwise indicated. Any function that returns a char *, rather than a const char *, is returning a pointer to a buffer allocated by zbufalc which must be freed using ubuffree, unless otherwise indicated. */ /* The maximum length of a remote system name. */ extern size_t cSysdep_max_name_len; /* Initialize. If something goes wrong, this routine should just exit. The flag argument is 0, or a combination of any of the following flags. */ /* This program needs to know the current working directory. This is used because on Unix it can be expensive to determine the current working directory (some versions of getcwd fork a process), but in most cases we don't need to know it. However, we are going to chdir to the spool directory (unless INIT_CHDIR is set), so we have to get the cwd now if we are ever going to get it. Both uucp and uux use the function fsysdep_needs_cwd to determine whether they will need the current working directory, and pass the argument to usysdep_initialize appropriately. There's probably a cleaner way to handle this, but this will suffice for now. */ #define INIT_GETCWD (01) /* This program should not chdir to the spool directory. This may only make sense on Unix. It is set by cu. */ #define INIT_NOCHDIR (02) /* This program needs special access to the spool directories. That means, on Unix, this program is normally installed setuid. */ #define INIT_SUID (04) /* Do not close all open descriptors. This is not used by the UUCP code, but it is used by other programs which share some of the system dependent libraries. */ #define INIT_NOCLOSE (010) extern void usysdep_initialize P((pointer puuconf, int iflags)); /* Exit the program. The fsuccess argument indicates whether to return an indication of success or failure to the outer environment. This routine should not return. */ extern void usysdep_exit P((boolean fsuccess)); /* Called when a non-standard configuration file is being used, to avoid handing out privileged access. If it returns FALSE, default configuration file will be used. This is called before the usysdep_initialize function is called. */ extern boolean fsysdep_other_config P((const char *)); /* Detach from the controlling terminal. This probably only makes sense on Unix. It is called by uucico to try to get the modem port as a controlling terminal. It is also called by uucico before it starts up uuxqt, so that uuxqt will be a complete daemon. */ extern void usysdep_detach P((void)); /* Get the local node name if it is not specified in the configuration files. Returns NULL on error; otherwise the return value should point to a static buffer. */ extern const char *zsysdep_localname P((void)); /* Get the login name. This is used when uucico is started up with no arguments in slave mode, which causes it to assume that somebody has logged in. It also used by uucp and uux for recording the user name. This may not return NULL. The return value should point to a static buffer. */ extern const char *zsysdep_login_name P((void)); /* Set a signal handler for a signal. If the signal occurs, the appropriate element of afSignal should be set to the signal number (see the declaration of afSignal in uucp.h). This routine might be able to just use signal, but Unix requires more complex handling. This is called before usysdep_initialize. */ extern void usysdep_signal P((int isig)); /* Catch a signal. This is actually defined as a macro in the system dependent header file, and the prototype here just indicates how it should be called. It is called before a routine which must exit if a signal occurs, and is expected to set do a setjmp (which is why it must be a macro). It is actually only called in one place in the system independent code, before the call to read stdin in uux. This is needed to handle 4.2 BSD restartable system calls, which require a longjmp. On systems which don't need to do setjmp/longjmp around system calls, this can be redefined in sysdep.h to TRUE. It should return TRUE if the routine should proceed, or FALSE if a signal occurred. After having this return TRUE, usysdep_start_catch should be used to start catching the signal; this basically tells the signal handler that it's OK to do the longjmp, if fsysdep_catch did not already do so. */ #ifndef fsysdep_catch extern boolean fsysdep_catch P((void)); #endif /* Start catching a signal. This is called after fsysdep_catch to tell the signal handler to go ahead and do the longjmp. This may be implemented as a macro in sysdep.h. */ #ifndef usysdep_start_catch extern void usysdep_start_catch P((void)); #endif /* Stop catching a signal. This is called when it is no longer necessary for fsysdep_catch to handle signals. This may be implemented as a macro in sysdep.h. */ #ifndef usysdep_end_catch extern void usysdep_end_catch P((void)); #endif /* Link two files. On Unix this should attempt the link. If it succeeds it should return TRUE with *pfworked set to TRUE. If the link fails because it must go across a device, it should return TRUE with *pfworked set to FALSE. If the link fails for some other reason, it should log an error message and return FALSE. On a system which does not support links to files, this should just return TRUE with *pfworked set to FALSE. */ extern boolean fsysdep_link P((const char *zfrom, const char *zto, boolean *pfworked)); /* Get the port name. This is used when uucico is started up in slave mode to figure out which port was used to call in so that it can determine any appropriate protocol parameters. This may return NULL if the port cannot be determined, which will just mean that no protocol parameters are applied. The name returned should be the sort of name that would appear in the port file. This should set *pftcp_port to TRUE if it can determine that the port is a TCP connection rather than a normal serial port. The return value (if not NULL) should point to a static buffer. */ extern const char *zsysdep_port_name P((boolean *pftcp_port)); /* Expand a file name on the local system. On Unix, if the zfile argument begins with ~user/ it goes in that users home directory, and if it begins with ~/ it goes in the public directory (the public directory is passed to this routine, since each system may have its own public directory). Similar conventions may be desirable on other systems. This should always return an absolute path name, probably in the public directory. It should return NULL on error; otherwise the return value should be allocated using zbufcpy or zbufalc. If pfbadname is not NULL, then if the function returns NULL *pfbadname should be set to TRUE if the error is just that the file name is badly specified; *pfbadname should be set to FALSE for some sort of internal error. */ extern char *zsysdep_local_file P((const char *zname, const char *zpubdir, boolean *pfbadname)); /* Return whether a file name is in a directory, and check for read or write access. This should check whether zfile is within zdir (or is zdir itself). If it is not, it should return FALSE. If zfile is in zdir, then fcheck indicates whether further checking should be done. If fcheck is FALSE, no further checking is done. Otherwise, if freadable is TRUE the user zuser should have search access to all directories from zdir down to zfile and should have read access on zfile itself (if zfile does not exist, or is not a regular file, this function may return FALSE but does not have to). If freadable is FALSE, the user zuser should have search access to all directories from zdir down to zfile and should have write access on zfile (which may be a directory, or may not actually exist, which is acceptable). The zuser argument may be NULL, in which case the check should be made for any user, not just zuser. There is no way for this function to return error. */ extern boolean fsysdep_in_directory P((const char *zfile, const char *zdir, boolean fcheck, boolean freadable, const char *zuser)); /* Return TRUE if a file exists, FALSE otherwise. There is no way to return error. */ extern boolean fsysdep_file_exists P((const char *zfile)); /* Start up a program. If the ffork argument is true, this should spawn a new process and return. If the ffork argument is false, this may either return or not. The three string arguments may be catenated together to form the program to execute; I did it this way to make it easy to call execl(2), and because I never needed more than two arguments. The program will always be "uucico" or "uuxqt". The return value should be TRUE on success, FALSE on error. */ extern boolean fsysdep_run P((boolean ffork, const char *zprogram, const char *zarg1, const char *zarg2)); /* Send a mail message. This function will be passed an array of strings. All necessary newlines are already included; the strings should simply be concatenated together to form the mail message. It should return FALSE on error, although the return value is often ignored. */ extern boolean fsysdep_mail P((const char *zto, const char *zsubject, int cstrs, const char **paz)); /* Get the time in seconds since some epoch. The actual epoch is unimportant, so long as the time values are consistent across program executions and the value is never negative. If the pimicros argument is not NULL, it should be set to the number of microseconds (if this is not available, *pimicros should be set to zero). */ extern long ixsysdep_time P((long *pimicros)); /* Get the time in seconds and microseconds (millionths of a second) since some epoch. The actual epoch is not important, and it may change in between program invocations; this is provided because on Unix the times function may be used. If microseconds can not be determined, *pimicros can just be set to zero. */ extern long ixsysdep_process_time P((long *pimicros)); /* Parse the value returned by ixsysdep_time into a struct tm. I assume that this structure is defined in . This is basically just localtime, except that the ANSI function takes a time_t which may not be what is returned by ixsysdep_time. */ extern void usysdep_localtime P((long itime, struct tm *q)); /* Sleep for a number of seconds. */ extern void usysdep_sleep P((int cseconds)); /* Pause for half a second, or 1 second if subsecond sleeps are not possible. */ extern void usysdep_pause P((void)); /* Lock a remote system. This should return FALSE if the system is already locked (no error should be reported). */ extern boolean fsysdep_lock_system P((const struct uuconf_system *qsys)); /* Unlock a remote system. This should return FALSE on error (although the return value is generally ignored). */ extern boolean fsysdep_unlock_system P((const struct uuconf_system *qsys)); /* Get the conversation sequence number for a remote system, and increment it for next time. This should return -1 on error. */ extern long ixsysdep_get_sequence P((const struct uuconf_system *qsys)); /* Get the status of a remote system. This should return FALSE on error. Otherwise it should set *qret to the status. If no status information is available, this should set *qret to sensible values and return TRUE. If pfnone is not NULL, then it should be set to TRUE if no status information was available or FALSE otherwise. */ extern boolean fsysdep_get_status P((const struct uuconf_system *qsys, struct sstatus *qret, boolean *pfnone)); /* Set the status of a remote system. This should return FALSE on error. The system will be locked before this call is made. */ extern boolean fsysdep_set_status P((const struct uuconf_system *qsys, const struct sstatus *qset)); /* See whether a remote system is permitted to log in. This is just to support the remote.unknown shell script for HDB. The zscript argument is the script name, as return by uuconf_remote_unknown. The zsystem argument is the name given by the remote system. If the system is not permitted to log in, this function should log an error and return FALSE. */ extern boolean fsysdep_unknown_caller P((const char *zscript, const char *zsystem)); /* Check whether there is work for a remote system. It should return TRUE if there is work, FALSE otherwise; there is no way to indicate an error. */ extern boolean fsysdep_has_work P((const struct uuconf_system *qsys)); /* Initialize the work scan. This will be called before fsysdep_get_work. The bgrade argument is the minimum grade of execution files that should be considered (e.g. a bgrade of 'd' will allow all grades from 'A' to 'Z' and 'a' to 'd'). This function should return FALSE on error. */ extern boolean fsysdep_get_work_init P((const struct uuconf_system *qsys, int bgrade)); /* Get the next command to be executed for a remote system. The bgrade argument will be the same as for fsysdep_get_work_init; probably only one of these functions will use it, namely the function for which it is more convenient. This should return FALSE on error. The structure pointed to by qcmd should be filled in. The strings may point into a static buffer; they will be copied out if necessary. If there is no more work, this should set qcmd->bcmd to 'H' and return TRUE. This should set qcmd->pseq to something which can be passed to fsysdep_did_work to remove the job from the queue when it has been completed. This may set qcmd->bcmd to 'P' to represent a poll file; the main code will just pass the pseq element of such a structure to fsysdep_did_work if the system is called. */ extern boolean fsysdep_get_work P((const struct uuconf_system *qsys, int bgrade, struct scmd *qcmd)); /* Remove a job from the work queue. This must also remove the temporary file used for a send command, if there is one. It should return FALSE on error. */ extern boolean fsysdep_did_work P((pointer pseq)); /* Save the temporary file for a send command. This function should return a string that will be put into a mail message. On success this string should say something like ``The file has been saved as ...''. On failure it could say something like ``The file could not be saved because ...''. If there is no temporary file, or for some reason it's not appropriate to include a message, this function should just return NULL. This function is used when a file send fails for some reason, to make sure that we don't completely lost the file. */ extern const char *zsysdep_save_temp_file P((pointer pseq)); /* Save a file in a location used to hold corrupt files. This is called if a bad execution file is found by uuxqt. This should return the new name of the file (allocated by zbufalc), or NULL if the move failed (in which the original file should remain). */ extern char *zsysdep_save_corrupt_file P((const char *zfile)); /* Save a file in a location used to hold failed execution files. This is called if a uuxqt execution fails. This should return the new name of the file (allocated by zbufalc), or NULL if the move failed (in which case the original file should remain). */ extern char *zsysdep_save_failed_file P((const char *zfile)); /* Cleanup anything left over by fsysdep_get_work_init and fsysdep_get_work. This may be called even though fsysdep_get_work_init has not been. */ extern void usysdep_get_work_free P((const struct uuconf_system *qsys)); /* Add a base name to a file if it is a directory. If zfile names a directory, then return a string naming a file within the directory with the base file name of zname. This should return NULL on error. */ extern char *zsysdep_add_base P((const char *zfile, const char *zname)); /* Get a file name from the spool directory. This should return NULL on error. The pseq argument is TRUE if the file was found from searching the work directory; this is, unfortunately, needed to support SVR4 spool directories. */ extern char *zsysdep_spool_file_name P((const struct uuconf_system *qsys, const char *zfile, pointer pseq)); /* Make necessary directories. This should create all non-existent directories for a file. If the fpublic argument is TRUE, anybody should be permitted to create and remove files in the directory; otherwise anybody can list the directory, but only the UUCP system can create and remove files. It should return FALSE on error. */ extern boolean fsysdep_make_dirs P((const char *zfile, boolean fpublic)); /* Create a stdio file, setting appropriate protection. If the fpublic argument is TRUE, the file is made publically accessible; otherwise it is treated as a private data file. If the fappend argument is TRUE, the file is opened in append mode; otherwise any previously existing file of the same name is removed. If the fmkdirs argument is TRUE, then any necessary directories should also be created. On a system in which file protections are unimportant and the necessary directories exist, this may be implemented as fopen (zfile, fappend ? "a" : "w"); */ extern FILE *esysdep_fopen P((const char *zfile, boolean fpublic, boolean fappend, boolean fmkdirs)); /* Open a file, using the access permission of the user who invoked the program. The frd argument is TRUE if the file should be opened for reading, and the fbinary argument is TRUE if the file should be opened as a binary file (this is ignored on Unix, since there all files are binary files). This returns an openfile_t, not a FILE *. This is supposed to be able to open a file even if it can not be read by the uucp user. This is not possible on some older Unix systems. */ extern openfile_t esysdep_user_fopen P((const char *zfile, boolean frd, boolean fbinary)); /* Open a file to send to another system; the qsys argument is the system the file is being sent to. If fcheck is TRUE, it should make sure that the file is readable by zuser (if zuser is NULL the file must be readable by anybody). This is to eliminate a window between fsysdep_in_directory and esysdep_open_send. If an error occurs, it should return EFILECLOSED. */ extern openfile_t esysdep_open_send P((const struct uuconf_system *qsys, const char *zname, boolean fcheck, const char *zuser)); /* Return a temporary file name to receive into. This file will be opened by esysdep_open_receive. The qsys argument is the system the file is coming from, the zto argument is the name the file will have after it has been fully received, the ztemp argument, if it is not NULL, is from the command sent by the remote system, and the frestart argument is TRUE if the protocol and remote system permit file transfers to be restarted. The return value must be freed using ubuffree. The function should return NULL on error. */ extern char *zsysdep_receive_temp P((const struct uuconf_system *qsys, const char *zfile, const char *ztemp, boolean frestart)); /* Open a file to receive from another system. The zreceive argument is the return value of zsysdep_receive_temp with the same qsys, zfile and ztemp arguments. If the function can determine that this file has already been partially received, it should set *pcrestart to the number of bytes that have been received. If the file has not been partially received, *pcrestart should be set to -1. pcrestart will be passed in as NULL if file restart is not supported by the protocol or the remote system. The function should return EFILECLOSED on error. After the file is written, fsysdep_move_file will be called to move the file to its final destination, and to set the correct file mode. */ extern openfile_t esysdep_open_receive P((const struct uuconf_system *qsys, const char *zto, const char *ztemp, const char *zreceive, long *pcrestart)); /* Move a file. This is used to move a received file to its final location. The zto argument is the file to create. The zorig argument is the name of the file to move. If fmkdirs is TRUE, then any necessary directories are created; fpublic indicates whether they should be publically writeable or not. If fcheck is TRUE, this should make sure the directory is writeable by the user zuser (if zuser is NULL, then it must be writeable by any user); this is to avoid a window of vulnerability between fsysdep_in_directory and fsysdep_move_file. This function should return FALSE on error, in which case the zorig file should still exist. */ extern boolean fsysdep_move_file P((const char *zorig, const char *zto, boolean fmkdirs, boolean fpublic, boolean fcheck, const char *zuser)); /* Change the mode of a file. The imode argument is a Unix mode. This should return FALSE on error. */ extern boolean fsysdep_change_mode P((const char *zfile, unsigned int imode)); /* Truncate a file which we are receiving into. This may be done by closing the original file, removing it and reopening it. This should return FALSE on error. */ extern openfile_t esysdep_truncate P((openfile_t e, const char *zname)); /* Sync a file to disk. If this fails it should log an error using the zmsg parameter, and return FALSE. This is controlled by the FSYNC_ON_CLOSE macro in policy.h. */ extern boolean fsysdep_sync P((openfile_t e, const char *zmsg)); /* 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 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 the sending system never sees the acknowledgement. If these files involve an execution, the execution will happen twice, which will be bad. This function is called when a file is completely received. It is supposed to try and remember the reception, in case the connection is lost. It is passed the system, the file name to receive to, and the temporary file name from the sending system. It should return FALSE on error. */ extern boolean fsysdep_remember_reception P((const struct uuconf_system *qsys, const char *zto, const char *ztemp)); /* This function is called to see if a file has already been received successfully. It gets the same arguments as fsysdep_remember_reception. It should return TRUE if the file was already received, FALSE otherwise. There is no way to report error. */ extern boolean fsysdep_already_received P((const struct uuconf_system *qsys, const char *zto, const char *ztemp)); /* This function is called when it is no longer necessary to remember that a file has been received. This will be called when the protocol knows that the receive message has been acknowledged. It gets the same arguments as fsysdep_remember_reception. it should return FALSE on error. */ extern boolean fsysdep_forget_reception P((const struct uuconf_system *qsys, const char *zto, const char *ztemp)); /* Start expanding a wildcarded file name. This should return FALSE on error; otherwise subsequent calls to zsysdep_wildcard should return file names. */ extern boolean fsysdep_wildcard_start P((const char *zfile)); /* Get the next wildcard name. This should return NULL when there are no more names to return. The return value should be freed using ubuffree. The argument should be the same as that to fsysdep_wildcard_start. There is no way to return error. */ extern char *zsysdep_wildcard P((const char *zfile)); /* Finish getting wildcard names. This may be called before or after zsysdep_wildcard has returned NULL. It should return FALSE on error. */ extern boolean fsysdep_wildcard_end P((void)); /* Prepare to execute a bunch of file transfer requests. This should make an entry in the spool directory so that the next time uucico is started up it will transfer these files. The bgrade argument specifies the grade of the commands. The commands themselves are in the pascmds array, which has ccmds entries. The function should return NULL on error, or the jobid on success. The jobid is a string that may be printed or passed to fsysdep_kill_job and related functions, but is otherwise uninterpreted. */ extern char *zsysdep_spool_commands P((const struct uuconf_system *qsys, int bgrade, int ccmds, const struct scmd *pascmds)); /* Get a file name to use for a data file to be copied to another system. The ztname, zdname and zxname arguments will all either be NULL or point to an array of CFILE_NAME_LEN characters in length. The ztname array should be set to a temporary file name that could be passed to zsysdep_spool_file_name to retrieve the return value of this function; this will be appropriate for the temporary name in a send request. The zdname array should be set to a data file name that is appropriate for the spool directory of the other system; this will be appropriate for the name of the destination file in a send request of a data file for an execution of some sort. The zxname array should be set to an execute file name that is appropriate for the other system. The zlocalname argument is the name of the local system as seen by the remote system, the bgrade argument is the grade, and fxqt is TRUE if this file is going to become an execution file. This should return NULL on error. */ #define CFILE_NAME_LEN (15) extern char *zsysdep_data_file_name P((const struct uuconf_system *qsys, const char *zlocalname, int bgrade, boolean fxqt, char *ztname, char *zdname, char *zxname)); /* Get a name for a local execute file. This is used by uux for a local command with remote files. Returns NULL on error. */ extern char *zsysdep_xqt_file_name P((void)); /* Beginning getting execute files. To get a list of execute files, first fsysdep_get_xqt_init is called, then zsysdep_get_xqt is called several times until it returns NULL, then finally usysdep_get_xqt_free is called. If the zsystem argument is not NULL, it is the name of a system for which execution files are desired. */ extern boolean fsysdep_get_xqt_init P((const char *zsystem)); /* Get the next execute file. This should return NULL when finished (with *pferr set to FALSE). The zsystem argument should be the same string as that passed to fsysdep_get_xqt_init. On an error this should return NULL with *pferr set to TRUE. This should set *pzsystem to the name of the system for which the execute file was created; this is not guaranteed to match the zsystem argument--that must be double checked by the caller. Both the return value and *pzsystem should be freed using ubuffree. */ extern char *zsysdep_get_xqt P((const char *zsystem, char **pzsystem, boolean *pferr)); /* Clean up after getting execute files. The zsystem argument should be the same string as that passed to fsysdep_get_xqt_init. */ extern void usysdep_get_xqt_free P((const char *zsystem)); /* Get the absolute pathname of a command to execute. This is given the legal list of commands (which may be the special case "ALL") and the path. It must return an absolute pathname to the command. If it gets an error it should set *pferr to TRUE and return NULL; if the command is not found it should set *pferr to FALSE and return NULL. */ extern char *zsysdep_find_command P((const char *zcmd, char **pzcmds, char **pzpath, boolean *pferr)); /* Expand file names for uuxqt. This exists because uuxqt on Unix has to expand file names which begin with a ~. It does not want to expand any other type of file name, and it turns a double ~ into a single one without expanding. If this returns NULL, the file does not need to be changed; otherwise it returns a zbufalc'ed string. There is no way to report error. */ extern char *zsysdep_xqt_local_file P((const struct uuconf_system *qsys, const char *zfile)); #if ! ALLOW_FILENAME_ARGUMENTS /* Check an argument to an execution command to make sure that it doesn't refer to a file name that may not be accessed. This should check the argument to see if it is a filename. If it is, it should either reject it out of hand or it should call fin_directory_list on the file with both qsys->zremote_receive and qsys->zremote_send. If the file is rejected, it should log an error and return FALSE. Otherwise it should return TRUE. */ extern boolean fsysdep_xqt_check_file P((const struct uuconf_system *qsys, const char *zfile)); #endif /* ! ALLOW_FILENAME_ARGUMENTS */ /* Run an execute file. The arguments are: qsys -- system for which execute file was created zuser -- user who requested execution pazargs -- list of arguments to command (element 0 is command) zfullcmd -- command and arguments stuck together in one string zinput -- file name for standard input (may be NULL) zoutput -- file name for standard output (may be NULL) fshell -- if TRUE, use /bin/sh to execute file ilock -- return value of ixsysdep_lock_uuxqt pzerror -- set to name of standard error file pftemp -- set to TRUE if error is temporary, FALSE otherwise If fshell is TRUE, the command should be executed with /bin/sh (obviously, this can only really be done on Unix systems). If an error occurs this should return FALSE and set *pftemp appropriately. *pzerror should be freed using ubuffree. */ extern boolean fsysdep_execute P((const struct uuconf_system *qsys, const char *zuser, const char **pazargs, const char *zfullcmd, const char *zinput, const char *zoutput, boolean fshell, int ilock, char **pzerror, boolean *pftemp)); /* Lock for uuxqt execution. If the cmaxuuxqts argument is not zero, this should make sure that no more than cmaxuuxqts uuxqt processes are running at once. Also, only one uuxqt may execute a particular command (specified by the -c option) at a time. If zcmd is not NULL, it is a command that must be locked. This should return a nonnegative number which will be passed to other routines, including fsysdep_unlock_uuxqt, or -1 on error. */ extern int ixsysdep_lock_uuxqt P((const char *zcmd, int cmaxuuxqts)); /* Unlock a uuxqt process. This is passed the return value of ixsysdep_lock_uuxqt, as well as the arguments passed to ixsysdep_lock_uuxqt. It may return FALSE on error, but at present the return value is ignored. */ extern boolean fsysdep_unlock_uuxqt P((int iseq, const char *zcmd, int cmaxuuxqts)); /* See whether a particular uuxqt command is locked. This should return TRUE if the command is locked (because ixsysdep_lock_uuxqt was called with it as an argument), FALSE otherwise. There is no way to return error. */ extern boolean fsysdep_uuxqt_locked P((const char *zcmd)); /* Lock an execute file in order to execute it. This should return FALSE if the execute file is already locked. There is no way to return error. */ extern boolean fsysdep_lock_uuxqt_file P((const char *zfile)); /* Unlock an execute file. This should return FALSE on error. */ extern boolean fsysdep_unlock_uuxqt_file P((const char *zfile)); /* Lock the execution directory. The ilock argument is the return value of ixsysdep_lock_uuxqt. This should return FALSE if the directory is already locked. There is no way to return error. */ extern boolean fsysdep_lock_uuxqt_dir P((int ilock)); /* Remove all files in the execution directory, and unlock it. This should return FALSE on error. */ extern boolean fsysdep_unlock_uuxqt_dir P((int ilock)); /* Move files into or out of the execution directory. The code will already have checked that all the files exist. The elements in the pzfrom array will be complete filenames, and the elements in the pzto array will be either NULL (in which case the file should not be moved) or simple base names. If fto is TRUE, the files in pzfrom should be moved to pzto; otherwise, the files in pzto should be moved to pzfrom (this is used if a temporary failure occurs, in which case the execution will be retried later). If pzinput and *pzinput are not NULL, then it is the name of the standard input file; if it is the same as any element of pzfrom, then *pzinput should be set to the zbufcpy of the corresponding pzto value, if any. */ extern boolean fsysdep_move_uuxqt_files P((int cfiles, const char *const *pzfrom, const char *const *pzto, boolean fto, int ilock, char **pzinput)); /* Expand a file name on the local system, defaulting to the current directory. This is just like zsysdep_local_file, except that relative files are placed in the working directory the program started in rather than in the public directory. This should return NULL on error. */ extern char *zsysdep_local_file_cwd P((const char *zname, const char *zpubdir, boolean *pfbadname)); /* Add the working directory to a file name. The named file is actually on a remote system. If the file already has a directory, it should not be changed. This should return NULL on error. */ extern char *zsysdep_add_cwd P((const char *zfile)); /* See whether a file name will need the current working directory when zsysdep_local_file_cwd or zsysdep_add_cwd is called on it. This will be called before usysdep_initialize. It should just check whether the argument is an absolute path. See the comment above usysdep_initialize in this file for an explanation of why things are done this way. */ extern boolean fsysdep_needs_cwd P((const char *zfile)); /* Get the base name of a file. The file will be a local file name, and this function should return the base file name, ideally in a form which will make sense on most systems; it will be used if the destination of a uucp is a directory. */ extern char *zsysdep_base_name P((const char *zfile)); /* Return a filename within a directory. */ extern char *zsysdep_in_dir P((const char *zdir, const char *zfile)); /* Get the mode of a file. This should return a Unix style file mode. It should return 0 on error. */ extern unsigned int ixsysdep_file_mode P((const char *zfile)); /* See whether the user has access to a file. This is called by uucp and uux to prevent copying of a file which uucp can read but the user cannot. If access is denied, this should log an error message and return FALSE. */ extern boolean fsysdep_access P((const char *zfile)); /* See whether the daemon has access to a file. This is called by uucp and uux when a file is queued up for transfer without being copied into the spool directory. It is merely an early error check, as the daemon would of course discover the error itself when it tried the transfer. If access would be denied, this should log an error message and return FALSE. */ extern boolean fsysdep_daemon_access P((const char *zfile)); /* Translate a destination from system!user to a place in the public directory where uupick will get the file. On Unix this produces system!~/receive/user/localname, and that's probably what it has to produce on any other system as well. Returns NULL on a usage error, or otherwise returns string allocated by zbufcpy. */ extern char *zsysdep_uuto P((const char *zdest, const char *zlocalname)); /* Return TRUE if a pathname exists and is a directory. */ extern boolean fsysdep_directory P((const char *zpath)); /* Walk a directory tree. The zdir argument is the directory to walk. The pufn argument is a function to call on each regular file in the tree. The first argument to pufn should be the full filename; the second argument to pufn should be the filename relative to zdir; the third argument to pufn should be the pinfo argument to usysdep_walk_tree. The usysdep_walk_tree function should return FALSE on error. */ extern boolean usysdep_walk_tree P((const char *zdir, void (*pufn) P((const char *zfull, const char *zrelative, pointer pinfo)), pointer pinfo)); /* Return the jobid of a work file, given the sequence value. On error this should log an error and return NULL. The jobid is a string which may be printed out and read in and passed to fsysdep_kill_job, etc., but is not otherwise interpreted. */ extern char *zsysdep_jobid P((const struct uuconf_system *qsys, pointer pseq)); /* See whether the current user is privileged. Privileged users are permitted to kill jobs submitted by another user, and they are permitted to use the -u argument to uucico; other uses of this call may be added later. This should return TRUE if permission is granted, FALSE otherwise. */ extern boolean fsysdep_privileged P((void)); /* Kill a job, given the jobid. This should remove all associated files and in general eliminate the job completely. On error it should log an error message and return FALSE. */ extern boolean fsysdep_kill_job P((pointer puuconf, const char *zjobid)); /* Rejuvenate a job, given the jobid. If possible, this should update the time associated with the job such that it will not be eliminated by uustat -K or similar programs that check the creation time. This should affect the return value of ixsysdep_work_time. On error it should log an error message and return FALSE. */ extern boolean fsysdep_rejuvenate_job P((pointer puuconf, const char *zjobid)); /* Get the time a job was queued, given the sequence number. There is no way to indicate error. The return value must use the same epoch as ixsysdep_time. */ extern long ixsysdep_work_time P((const struct uuconf_system *qsys, pointer pseq)); /* Get the time a file was created. This is called by uustat on execution files. There is no way to indicate error. The return value must use the same epoch as ixsysdep_time. */ extern long ixsysdep_file_time P((const char *zfile)); /* Touch a file to make it appear as though it was created at the current time. This is called by uustat on execution files. On error this should log an error message and return FALSE. */ extern boolean fsysdep_touch_file P((const char *zfile)); /* Get the size in bytes of a file. If this file does not exist, this should not give an error message, but should return -1. If some other error occurs, this should return -2. */ extern long csysdep_size P((const char *zfile)); /* Return the amount of free space on the containing the given file name (the file may or may not exist). If the amount of free space cannot be determined, the function should return -1. */ extern long csysdep_bytes_free P((const char *zfile)); /* Start getting status information for all systems with available status information. There may be status information for unknown systems, which is why this series of functions is used. The phold argument is used to pass information around, to possibly avoid the use of static variables. On error this should log an error and return FALSE. */ extern boolean fsysdep_all_status_init P((pointer *phold)); /* Get status information for the next system. This should return the system name and fill in the qstat argument. The phold argument will be that set by fsysdep_all_status_init. On error this should log an error, set *pferr to TRUE, and return NULL. */ extern char *zsysdep_all_status P((pointer phold, boolean *pferr, struct sstatus *qstat)); /* Free up anything allocated by fsysdep_all_status_init and zsysdep_all_status. The phold argument is that set by fsysdep_all_status_init. */ extern void usysdep_all_status_free P((pointer phold)); /* Display the process status of all processes holding lock files. This is uustat -p. The return value is passed to usysdep_exit. */ extern boolean fsysdep_lock_status P((void)); /* Return TRUE if the user has legitimate access to the port. This is used by cu to control whether the user can open a port directly, rather than merely being able to dial out on it. Opening a port directly allows the modem to be reprogrammed. */ extern boolean fsysdep_port_access P((struct uuconf_port *qport)); /* Return whether the given port could be named by the given line. On Unix, the line argument would be something like "ttyd0", and this function should return TRUE if the named port is "/dev/ttyd0". */ extern boolean fsysdep_port_is_line P((struct uuconf_port *qport, const char *zline)); /* Set the terminal into raw mode. In this mode no input characters should be treated specially, and characters should be made available as they are typed. The original terminal mode should be saved, so that it can be restored by fsysdep_terminal_restore. If flocalecho is TRUE, then local echoing should still be done; otherwise echoing should be disabled. This function returns FALSE on error. */ extern boolean fsysdep_terminal_raw P((boolean flocalecho)); /* Restore the terminal back to the original setting, before fsysdep_terminal_raw was called. Returns FALSE on error. */ extern boolean fsysdep_terminal_restore P((void)); /* Read a line from the terminal. The fsysdep_terminal_raw function will have been called. This should print the zprompt argument (unless it is NULL) and return the line, allocated by zbufcpy, or NULL on error. */ extern char *zsysdep_terminal_line P((const char *zprompt)); /* Write a line to the terminal, ending with a newline. This is basically just puts (zline, stdout), except that the terminal will be in raw mode, so on ASCII Unix systems the line needs to end with \r\n. */ extern boolean fsysdep_terminal_puts P((const char *zline)); /* If faccept is TRUE, permit the user to generate signals from the terminal. If faccept is FALSE, turn signals off again. After fsysdep_terminal_raw is called, signals should be off. Return FALSE on error. */ extern boolean fsysdep_terminal_signals P((boolean faccept)); /* The cu program expects the system dependent code to handle the details of copying data from the communications port to the terminal. This should be set up by fsysdep_cu_init, and done while fsysdep_cu is called. It is permissible to do it on a continual basis (on Unix a subprocess handles it) so long as the copying can be stopped by the fsysdep_cu_copy function. The fsysdep_cu_init function does any system dependent initialization needed for this. */ extern boolean fsysdep_cu_init P((struct sconnection *qconn)); /* Copy all data from the communications port to the terminal, and all data from the terminal to the communications port. Keep this up until the escape character *zCuvar_escape is seen. Set *pbcmd to the character following the escape character; after the escape character, zlocalname should be printed, possibly after a delay. If two escape characters are entered in sequence, this function should send a single escape character to the port, and not return. Returns FALSE on error. */ extern boolean fsysdep_cu P((struct sconnection *qconn, char *pbcmd, const char *zlocalname)); /* If fcopy is TRUE, start copying data from the communications port to the terminal. If fcopy is FALSE, stop copying data. This function may be called several times during a cu session. It should return FALSE on error. */ extern boolean fsysdep_cu_copy P((boolean fcopy)); /* Stop copying data from the communications port to the terminal, and generally clean up after fsysdep_cu_init and fsysdep_cu. Returns FALSE on error. */ extern boolean fsysdep_cu_finish P((void)); /* Run a shell command. If zcmd is NULL, or *zcmd == '\0', just start up a shell. The second argument is one of the following values. This should return FALSE on error. */ enum tshell_cmd { /* Attach stdin and stdout to the terminal. */ SHELL_NORMAL, /* Attach stdout to the communications port, stdin to the terminal. */ SHELL_STDOUT_TO_PORT, /* Attach stdin to the communications port, stdout to the terminal. */ SHELL_STDIN_FROM_PORT, /* Attach both stdin and stdout to the communications port. */ SHELL_STDIO_ON_PORT }; extern boolean fsysdep_shell P((struct sconnection *qconn, const char *zcmd, enum tshell_cmd tcmd)); /* Change directory. If zdir is NULL, or *zdir == '\0', change to the user's home directory. Return FALSE on error. */ extern boolean fsysdep_chdir P((const char *zdir)); /* Suspend the current process. This is only expected to work on Unix versions that support SIGTSTP. In general, people can just shell out. */ extern boolean fsysdep_suspend P((void)); /* Start getting files for uupick. The zsystem argument may be NULL to get files from all systems, or it may specify a particular system. The zpubdir argument is the public directory to use. This returns FALSE on error. */ extern boolean fsysdep_uupick_init P((const char *zsystem, const char *zpubdir)); /* Get the next file for uupick. This returns the basic file name. It sets *pzfull to the full name, and *pzfrom to the name of the system which sent this file over; both should be freed using ubuffree. *pzfull should be passed to ubuffree after it is no longer needed. The zsystem and zpubdir arguments should be the same as the arguments to fsysdep_uupick_init. This returns NULL when all files been returned. */ extern char *zsysdep_uupick P((const char *zsystem, const char *zpubdir, char **pzfrom, char **pzfull)); /* Clean up after getting files for uupick. */ extern boolean fsysdep_uupick_free P((const char *zsystem, const char *zpubdir)); /* Translate a local file name for uupick. On Unix this is just like zsysdep_local_file_cwd except that a file beginning with ~/ is placed in the user's home directory rather than in the public directory. */ extern char *zsysdep_uupick_local_file P((const char *zfile, boolean *pfbadname)); /* Remove a directory and all the files in it. */ extern boolean fsysdep_rmdir P((const char *zdir)); #endif /* ! defined (SYSTEM_H) */