/* prot.h Protocol header file. Copyright (C) 1991, 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. The author of the program may be contacted at ian@airs.com or c/o AIRS, P.O. Box 520, Waltham, MA 02254. $Log: prot.h,v $ Revision 1.1.1.1 1993/03/21 09:45:37 cgd initial import of 386bsd-0.1 sources Revision 1.12 1992/03/13 22:59:25 ian Have breceive_char go through freceive_data Revision 1.11 1992/03/07 15:00:28 ian prot.h is never included more than once Revision 1.10 1992/02/08 03:54:18 ian Include only in , added 1992 copyright Revision 1.9 1992/01/18 22:48:53 ian Reworked sending of mail and general handling of failed transfers Revision 1.8 1991/12/31 19:43:13 ian Added 'e' protocol Revision 1.7 1991/11/15 21:00:59 ian Efficiency hacks for 'f' and 't' protocols Revision 1.6 1991/11/14 03:20:13 ian Added seven-bit and reliable commands to help when selecting protocols Revision 1.5 1991/11/12 18:25:33 ian Added 't' protocol Revision 1.4 1991/11/11 04:21:16 ian Added 'f' protocol Revision 1.3 1991/11/10 19:24:22 ian Added pffile protocol entry point for file level control Revision 1.2 1991/11/09 18:53:07 ian Reworked protocol interface Revision 1.1 1991/09/10 19:47:55 ian Initial revision */ /* The sprotocol structure holds information and functions for a specific protocol (e.g. the 'g' protocol). */ struct sprotocol { /* The name of the protocol (e.g. 'g'). */ char bname; /* Whether the protocol is full-duplex or not; a full-duplex protocol can transfer files in both directions at once. */ boolean ffullduplex; /* Reliability requirements, an or of RELIABLE_xxx defines from port.h. */ int ireliable; /* Protocol parameter commands. */ struct scmdtab *qcmds; /* A routine to start the protocol; the argument is whether the caller is the master or the slave. Returns TRUE if the protocol has been succesfully started, FALSE otherwise. */ boolean (*pfstart) P((boolean fmaster)); /* Shutdown the protocol. */ boolean (*pfshutdown) P((void)); /* Send a command to the other side. */ boolean (*pfsendcmd) P((const char *z)); /* Get buffer to space to fill with data. This should set *pcdata to the amount of data desired. */ char *(*pzgetspace) P((int *pcdata)); /* Send data to the other side. The first argument must be a return value of pzgetspace. */ boolean (*pfsenddata) P((char *z, int c)); /* Process received data in abPrecbuf, calling fgot_data as necessary. If fgot_data sets *pfexit, it should get passed back out. */ boolean (*pfprocess) P((boolean *pfexit)); /* Wait for data to come in and call fgot_data with it until fgot_data sets *pfexit. */ boolean (*pfwait) P((void)); /* Handle any file level actions that need to be taken. If fstart is TRUE, a file transfer is beginning. If fstart is FALSE a file transfer is ending, and *pfredo should be set to TRUE if the file transfer needs to be redone. If fstart and fsend are both TRUE, cbytes holds the size of the file or -1 if it is unknown. */ boolean (*pffile) P((boolean fstart, boolean fsend, boolean *pfredo, long cbytes)); }; /* Send a file. fmaster -- whether this job is the master e -- open file (send if fmaster, receive if ! fmaster) qcmd -- command to execute zmail -- user to notify on source system. ztosys -- system the file is being sent to fnew -- whether the system is running our code or not If this is called with fmaster TRUE, it is responsible for informing the slave that it wants to send a file; the slave will eventually call freceive_file. The file should then be transferred. When the transfer is complete, then if fmaster is TRUE and zmail is not NULL, mail should be sent to the user zmail; if fmaster is FALSE and qcmd->znotify is not NULL, mail should be sent to the user qcmd->znotify. After the file transfer is complete, the work queue entry should be removed by calling fsysdep_did_work (pseq). Most of the latter stuff is handled by fsent_file. */ extern boolean fsend_file P((boolean fmaster, openfile_t e, const struct scmd *qcmd, const char *zmail, const char *ztosys, boolean fnew)); /* Receive a file. fmaster -- whether this job is the master e -- open file (receive if fmaster, send if ! fmaster) qcmd -- command to execute zmail -- user to notify on destination system. zfromsys -- system the file is from fnew -- whether the system is running our code or not The field qcmd->znotify will not be meaningful. If this is called with fmaster TRUE, it is responsible for informing the slave that it wants to receive a file; the slave will eventually call pfsend. The file should then be transferred. When the transfer is complete, if fmaster is TRUE and zmail is not NULL, mail should be sent to the user zmail. After the file transfer is complete, the work queue entry should be removed by calling fsysdep_did_work (pseq). Most of the latter work is done by freceived_file. */ extern boolean freceive_file P((boolean fmaster, openfile_t e, const struct scmd *qcmd, const char *zmail, const char *zfromsys, boolean fnew)); /* Request a transfer. This is only called by the master. qcmd -- command (only pseq, zfrom, zto, zuser, zoptions valid) This function should tell the slave that the master wants to execute a transfer. The slave may queue up work to do. The return value is FALSE if some error occurred. This always does its work immediately, so it does not use qcmd->pseq. It sets *pfnever to TRUE if the request was denied. */ extern boolean fxcmd P((const struct scmd *qcmd, boolean *pfnever)); /* Confirm a transfer. This is only called by the slave. This is called after a transfer request has been received to confirm that it was successful. If it was not successful, pffail will be called with a first argument of 'X'. */ extern boolean fxcmd_confirm P((void)); /* Fail. This is called by the slave if it is unable to execute some request by the master. The argument bcmd is the request which failed ('S' or 'R'). The argument twhy indicates the reason. The return value is FALSE if some error occurred. */ extern boolean ftransfer_fail P((int bcmd, enum tfailure twhy)); /* Get a command from the master. The strings in the command argument are set to point into a static buffer. If fmaster is TRUE, this should not wait if there is no command pending; if fmaster is FALSE it should wait until a command is received. The field qcmd->pseq will be set to NULL. */ extern boolean fgetcmd P((boolean fmaster, struct scmd *qcmd)); /* Get a command string from the other system, where the nature of a command string is defined by the protocol. The return value is fragile, and must be saved if any other protocol related calls are made. */ extern const char *zgetcmd P((void)); /* Hangup. This is only called by the master, and indicates that the master is ready to relinquish control; after calling it, the master becomes the slave. If the original slave has no work to do, it confirms the hangup (the new slave will wind up getting a 'Y' command from fgetcmd). If the the original slave has work to do, it becomes the master (it also denies the hangup, but this is not seen outside the protocol code). The return value of fhangup is FALSE if some error occurred. */ extern boolean fhangup_request P((void)); /* Hangup reply. This is only called by the slave if the master has sent a hangup request. If fconfirm is TRUE, the slave is confirming the hangup, in which case the protocol should be shut down. If fconfirm is FALSE, the slave will become the master. The return value is FALSE if some error occurred. */ extern boolean fhangup_reply P((boolean fconfirm)); /* Handle data received by a protocol. This is called by the protocol specific routines as data comes in. The protocol specific routines may know that the data is destined for a command or a file, in which case they should pass fcmd and ffile appropriately. Otherwise they may both be passed as FALSE, in which case if a file recieve is in progress the data will be sent to the file, otherwise to a command. This will set *pfexit to TRUE if the file or command is finished. A file is finished when a zero length buffer is passed. A command is finished when a string containing a null byte is passed. This will return FALSE on error. */ extern boolean fgot_data P((const char *zdata, int cdata, boolean fcmd, boolean ffile, boolean *pfexit)); /* Send data to the other system. If the fread argument is TRUE, this will also receive data into the receive buffer abPrecbuf; fread is passed as TRUE if the protocol expects data to be coming back, to make sure the input buffer does not fill up. Returns FALSE on error. */ extern boolean fsend_data P((const char *zsend, int csend, boolean fdoread)); /* Receive data from the other system when there is no data to send. The cneed argument is the amount of data desired and the ctimeout argument is the timeout in seconds. This will set *pcrec to the amount of data received. It will return FALSE on error. If a timeout occurs, it will return TRUE with *pcrec set to zero. */ extern boolean freceive_data P((int cneed, int *pcrec, int ctimeout, boolean freport)); /* Protocol in use. */ extern const struct sprotocol *qProto; /* The size of the receive buffer. */ #define CRECBUFLEN (16384) /* Buffer to hold received data. */ extern char abPrecbuf[CRECBUFLEN]; /* Index of start of data in abPrecbuf. */ extern int iPrecstart; /* Index of end of data (first byte not included in data) in abPrecbuf. */ extern int iPrecend; /* Whether an unexpected shutdown is OK now; this is used to avoid giving a warning for systems that hang up in a hurry. */ extern boolean fPerror_ok; /* Prototypes for 'g' protocol functions. */ extern struct scmdtab asGproto_params[]; extern boolean fgstart P((boolean fmaster)); extern boolean fgshutdown P((void)); extern boolean fgsendcmd P((const char *z)); extern char *zggetspace P((int *pcdata)); extern boolean fgsenddata P((char *z, int c)); extern boolean fgprocess P((boolean *pfexit)); extern boolean fgwait P((void)); /* Prototypes for 'f' protocol functions. */ extern struct scmdtab asFproto_params[]; extern boolean ffstart P((boolean fmaster)); extern boolean ffshutdown P((void)); extern boolean ffsendcmd P((const char *z)); extern char *zfgetspace P((int *pcdata)); extern boolean ffsenddata P((char *z, int c)); extern boolean ffprocess P((boolean *pfexit)); extern boolean ffwait P((void)); extern boolean fffile P((boolean fstart, boolean fsend, boolean *pfredo, long cbytes)); /* Prototypes for 't' protocol functions. */ extern struct scmdtab asTproto_params[]; extern boolean ftstart P((boolean fmaster)); extern boolean ftshutdown P((void)); extern boolean ftsendcmd P((const char *z)); extern char *ztgetspace P((int *pcdata)); extern boolean ftsenddata P((char *z, int c)); extern boolean ftprocess P((boolean *pfexit)); extern boolean ftwait P((void)); extern boolean ftfile P((boolean fstart, boolean fsend, boolean *pfredo, long cbytes)); /* Prototypes for 'e' protocol functions. */ extern struct scmdtab asEproto_params[]; extern boolean festart P((boolean fmaster)); extern boolean feshutdown P((void)); extern boolean fesendcmd P((const char *z)); extern char *zegetspace P((int *pcdata)); extern boolean fesenddata P((char *z, int c)); extern boolean feprocess P((boolean *pfexit)); extern boolean fewait P((void)); extern boolean fefile P((boolean fstart, boolean fsend, boolean *pfredo, long cbytes));