1 /* uudefs.h
2    Miscellaneous definitions for the UUCP package.
3 
4    Copyright (C) 1991, 1992, 1993, 1995, 2002 Ian Lance Taylor
5 
6    This file is part of the Taylor UUCP package.
7 
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2 of the
11    License, or (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
21 
22    The author of the program may be contacted at ian@airs.com.
23    */
24 
25 #if ANSI_C
26 /* These structures are used in prototypes but are not defined in this
27    header file.  */
28 struct uuconf_system;
29 struct uuconf_timespan;
30 #endif
31 
32 /* The tlog enumeration holds the different types of logging.  */
33 enum tlog
34 {
35   /* Normal log entry.  */
36   LOG_NORMAL,
37   /* Error log entry.  */
38   LOG_ERROR,
39   /* Fatal log entry.  */
40   LOG_FATAL
41 #if DEBUG > 1
42     ,
43   /* Debugging log entry.  */
44   LOG_DEBUG,
45   /* Start debugging log entry.  */
46   LOG_DEBUG_START,
47   /* Continue debugging log entry.  */
48   LOG_DEBUG_CONTINUE,
49   /* End debugging log entry.  */
50   LOG_DEBUG_END
51 #endif
52 };
53 
54 /* The tstatus_type enumeration holds the kinds of status information
55    we put in the status file.  The order of entries here corresponds
56    to the order of entries in the azStatus array.  */
57 enum tstatus_type
58 {
59   /* Conversation complete.  */
60   STATUS_COMPLETE,
61   /* Port unavailable.  */
62   STATUS_PORT_FAILED,
63   /* Dial failed.  */
64   STATUS_DIAL_FAILED,
65   /* Login failed.  */
66   STATUS_LOGIN_FAILED,
67   /* Handshake failed.  */
68   STATUS_HANDSHAKE_FAILED,
69   /* Failed after logging in.  */
70   STATUS_FAILED,
71   /* Talking to remote system.  */
72   STATUS_TALKING,
73   /* Wrong time to call.  */
74   STATUS_WRONG_TIME,
75   /* Number of status values.  */
76   STATUS_VALUES
77 };
78 
79 /* An array to convert status entries to strings.  If more status entries
80    are added, this array must be extended.  */
81 extern const char *azStatus[];
82 
83 /* The sstatus structure holds the contents of a system status file.  */
84 struct sstatus
85 {
86   /* Current status of conversation.  */
87   enum tstatus_type ttype;
88   /* Number of failed retries.  */
89   int cretries;
90   /* Time of last call in seconds since epoch (determined by
91      ixsysdep_time).  */
92   long ilast;
93   /* Number of seconds until a retry is permitted.  */
94   int cwait;
95   /* String in status file.  Only used when reading status file, not
96      when writing.  May be NULL.  Should be freed with ubuffree.  */
97   char *zstring;
98 };
99 
100 /* How long we have to wait for the next call, given the number of retries
101    we have already made.  This should probably be configurable.  */
102 #define CRETRY_WAIT(c) ((c) * 10 * 60)
103 
104 /* The scmd structure holds a complete UUCP command.  */
105 struct scmd
106 {
107   /* Command ('S' for send, 'R' for receive, 'X' for execute, 'E' for
108      simple execution, 'H' for hangup, 'Y' for hangup confirm, 'N' for
109      hangup deny).  */
110   char bcmd;
111   /* Grade of the command ('\0' if from remote system).  */
112   char bgrade;
113   /* Sequence handle for fsysdep_did_work.  */
114   pointer pseq;
115   /* File name to transfer from.  */
116   const char *zfrom;
117   /* File name to transfer to.  */
118   const char *zto;
119   /* User who requested transfer.  */
120   const char *zuser;
121   /* Options.  */
122   const char *zoptions;
123   /* Temporary file name ('S' and 'E').  */
124   const char *ztemp;
125   /* Mode to give newly created file ('S' and 'E').  */
126   unsigned int imode;
127   /* User to notify on remote system (optional; 'S' and 'E').  */
128   const char *znotify;
129   /* File size (-1 if not supplied) ('S', 'E' and 'R').  */
130   long cbytes;
131   /* Command to execute ('E').  */
132   const char *zcmd;
133   /* Position to restart from ('R').  */
134   long ipos;
135 };
136 
137 #if DEBUG > 1
138 
139 /* We allow independent control over several different types of
140    debugging output, using a bit string with individual bits dedicated
141    to particular debugging types.  */
142 
143 /* The bit string is stored in iDebug.  */
144 extern int iDebug;
145 
146 /* Debug abnormal events.  */
147 #define DEBUG_ABNORMAL (01)
148 /* Debug chat scripts.  */
149 #define DEBUG_CHAT (02)
150 /* Debug initial handshake.  */
151 #define DEBUG_HANDSHAKE (04)
152 /* Debug UUCP protocol.  */
153 #define DEBUG_UUCP_PROTO (010)
154 /* Debug protocols.  */
155 #define DEBUG_PROTO (020)
156 /* Debug port actions.  */
157 #define DEBUG_PORT (040)
158 /* Debug configuration files.  */
159 #define DEBUG_CONFIG (0100)
160 /* Debug spool directory actions.  */
161 #define DEBUG_SPOOLDIR (0200)
162 /* Debug executions.  */
163 #define DEBUG_EXECUTE (0400)
164 /* Debug incoming data.  */
165 #define DEBUG_INCOMING (01000)
166 /* Debug outgoing data.  */
167 #define DEBUG_OUTGOING (02000)
168 
169 /* Maximum possible value for iDebug.  */
170 #define DEBUG_MAX (03777)
171 
172 /* Intializer for array of debug names.  The index of the name in the
173    array is the corresponding bit position in iDebug.  We only check
174    for prefixes, so these names only need to be long enough to
175    distinguish each name from every other.  The last entry must be
176    NULL.  The string "all" is also recognized to turn on all
177    debugging.  */
178 #define DEBUG_NAMES \
179   { "a", "ch", "h", "u", "pr", "po", "co", "s", "e", "i", "o", NULL }
180 
181 /* The prefix to use to turn off all debugging.  */
182 #define DEBUG_NONE "n"
183 
184 /* Check whether a particular type of debugging is being done.  */
185 #define FDEBUGGING(i) ((iDebug & (i)) != 0)
186 
187 /* These macros are used to output debugging information.  I use
188    several different macros depending on the number of arguments
189    because no macro can take a variable number of arguments and I
190    don't want to use double parentheses.  */
191 #define DEBUG_MESSAGE0(i, z) \
192   do { if (FDEBUGGING (i)) ulog (LOG_DEBUG, (z)); } while (0)
193 #define DEBUG_MESSAGE1(i, z, a1) \
194   do { if (FDEBUGGING (i)) ulog (LOG_DEBUG, (z), (a1)); } while (0)
195 #define DEBUG_MESSAGE2(i, z, a1, a2) \
196   do { if (FDEBUGGING (i)) ulog (LOG_DEBUG, (z), (a1), (a2)); } while (0)
197 #define DEBUG_MESSAGE3(i, z, a1, a2, a3) \
198   do \
199     { \
200       if (FDEBUGGING (i)) \
201 	ulog (LOG_DEBUG, (z), (a1), (a2), (a3)); \
202     } \
203   while (0)
204 #define DEBUG_MESSAGE4(i, z, a1, a2, a3, a4) \
205   do \
206     { \
207       if (FDEBUGGING (i)) \
208 	ulog (LOG_DEBUG, (z), (a1), (a2), (a3), (a4)); \
209     } \
210   while (0)
211 
212 #else /* DEBUG <= 1 */
213 
214 /* If debugging information is not being compiled, provide versions of
215    the debugging macros which just disappear.  */
216 #define DEBUG_MESSAGE0(i, z)
217 #define DEBUG_MESSAGE1(i, z, a1)
218 #define DEBUG_MESSAGE2(i, z, a1, a2)
219 #define DEBUG_MESSAGE3(i, z, a1, a2, a3)
220 #define DEBUG_MESSAGE4(i, z, a1, a2, a3, a4)
221 
222 #endif /* DEBUG <= 1 */
223 
224 /* Functions.  */
225 
226 /* Given an unknown system name, return information for an unknown
227    system.  If unknown systems are not permitted, this returns FALSE.
228    Otherwise, it translates the name as necessary for the spool
229    directory, and fills in *qsys.  */
230 extern boolean funknown_system P((pointer puuconf, const char *zsystem,
231 				  struct uuconf_system *qsys));
232 
233 /* See whether a file belongs in the spool directory.  */
234 extern boolean fspool_file P((const char *zfile));
235 
236 /* See if the current time matches a time span.  If not, return FALSE.
237    Otherwise, return TRUE and set *pival and *pcretry to the values
238    from the matching element of the span.  */
239 extern boolean ftimespan_match P((const struct uuconf_timespan *qspan,
240 				  long *pival, int *pcretry));
241 
242 /* Remove all occurrences of the local system name followed by an
243    exclamation point from the start of the argument.  Return the
244    possibly shortened argument.  */
245 extern char *zremove_local_sys P((struct uuconf_system *qlocalsys,
246 				  char *z));
247 
248 /* Determine the maximum size that may ever be transferred, given a
249    timesize span.  If there are any time gaps larger than 1 hour not
250    described by the timesize span, this returns -1.  Otherwise it
251    returns the largest size that may be transferred at some time.  */
252 extern long cmax_size_ever P((const struct uuconf_timespan *qtimesize));
253 
254 /* Send mail about a file transfer.  */
255 extern boolean fmail_transfer P((boolean fok, const char *zuser,
256 				 const char *zmail, const char *zwhy,
257 				 const char *zfrom, const char *zfromsys,
258 				 const char *zto, const char *ztosys,
259 				 const char *zsaved));
260 
261 /* See whether a file is in one of a list of directories.  The zpubdir
262    argument is used to pass the directory names to zsysdep_local_file.
263    If fcheck is FALSE, this does not check accessibility.  Otherwise,
264    if freadable is TRUE, the user zuser must have read access to the
265    file and all appropriate directories; if freadable is FALSE zuser
266    must have write access to the appropriate directories.  The zuser
267    argument may be NULL, in which case all users must have the
268    appropriate access (this is used for a remote request).  */
269 extern boolean fin_directory_list P((const char *zfile,
270 				     char **pzdirs,
271 				     const char *zpubdir,
272 				     boolean fcheck,
273 				     boolean freadable,
274 				     const char *zuser));
275 
276 /* Parse a command string.  */
277 extern boolean fparse_cmd P((char *zcmd, struct scmd *qcmd));
278 
279 /* Return whether a command needs quoting.  */
280 extern boolean fcmd_needs_quotes P((const struct scmd *qcmd));
281 
282 /* Quote the strings in a command, creating a new command.  */
283 extern void uquote_cmd P((const struct scmd *qorig, struct scmd *qnew));
284 
285 /* Free a command structure created by uquote_cmd.  */
286 extern void ufree_quoted_cmd P((struct scmd *qcmd));
287 
288 /* Backslash qoute a string, returning a newly allocated string.  If
289    fbackslashonly, only quote backslashes.  Otherwise, quote
290    backslashes and all nonprinting characters.  */
291 extern char *zquote_cmd_string P((const char *zorig, boolean fbackslashonly));
292 
293 /* Make a log entry.  */
294 #ifdef __GNUC__
295 #define GNUC_VERSION __GNUC__
296 #else
297 #define GNUC_VERSION 0
298 #endif
299 
300 #if ANSI_C && HAVE_VFPRINTF
301 extern void ulog P((enum tlog ttype, const char *zfmt, ...))
302 #if GNUC_VERSION > 1
303 #ifdef __printf0like
304      __printf0like (2, 3)
305 #else
306      __attribute__ ((format (printf, 2, 3)))
307 #endif
308 #endif
309      ;
310 #else
311 extern void ulog ();
312 #endif
313 
314 #undef GNUC_VERSION
315 
316 /* Report an error returned by one of the uuconf routines.  */
317 extern void ulog_uuconf P((enum tlog ttype, pointer puuconf,
318 			   int iuuconf));
319 
320 /* Set the function to call if a fatal error occurs.  */
321 extern void ulog_fatal_fn P((void (*pfn) P((void))));
322 
323 /* If ffile is TRUE, send log entries to the log file rather than to
324    stderr.  */
325 extern void ulog_to_file P((pointer puuconf, boolean ffile));
326 
327 /* Set the ID number used by the logging functions.  */
328 extern void ulog_id P((int iid));
329 
330 /* Set the system name used by the logging functions.  */
331 extern void ulog_system P((const char *zsystem));
332 
333 /* Set the system and user name used by the logging functions.  */
334 extern void ulog_user P((const char *zuser));
335 
336 /* Set the device name used by the logging functions.  */
337 extern void ulog_device P((const char *zdevice));
338 
339 /* Close the log file.  */
340 extern void ulog_close P((void));
341 
342 /* Make an entry in the statistics file.  */
343 extern void ustats P((boolean fsucceeded, const char *zuser,
344 		      const char *zsystem, boolean fsent,
345 		      long cbytes, long csecs, long cmicros,
346 		      boolean fcaller));
347 
348 /* Close the statistics file.  */
349 extern void ustats_close P((void));
350 
351 #if DEBUG > 1
352 /* A debugging routine to output a buffer.  This outputs zhdr, the
353    buffer length clen, and the contents of the buffer in quotation
354    marks.  */
355 extern void udebug_buffer P((const char *zhdr, const char *zbuf,
356 			     size_t clen));
357 
358 /* A debugging routine to make a readable version of a character.
359    This takes a buffer at least 5 bytes long, and returns the length
360    of the string it put into it (not counting the null byte).  */
361 extern size_t cdebug_char P((char *z, int ichar));
362 
363 /* Parse a debugging option string.  This can either be a number or a
364    comma separated list of debugging names.  This returns a value for
365    iDebug.  */
366 extern int idebug_parse P((const char *));
367 
368 #endif /* DEBUG <= 1 */
369 
370 /* Copy one file to another.  */
371 extern boolean fcopy_file P((const char *zfrom, const char *zto,
372 			     boolean fpublic, boolean fmkdirs,
373 			     boolean fsignals));
374 
375 /* Copy an open file to another.  */
376 extern boolean fcopy_open_file P((openfile_t efrom, const char *zto,
377 				  boolean fpublic, boolean fmkdirs,
378 				  boolean fsignals));
379 
380 /* Translate escape sequences in a buffer, leaving the result in the
381    same buffer and returning the length.  */
382 extern size_t cescape P((char *zbuf));
383 
384 /* Get a buffer to hold a string of a given size.  The buffer should
385    be freed with ubuffree.  */
386 extern char *zbufalc P((size_t csize));
387 
388 /* Call zbufalc to allocate a buffer and copy a string into it.  */
389 extern char *zbufcpy P((const char *z));
390 
391 /* Free up a buffer returned by zbufalc or zbufcpy.  */
392 extern void ubuffree P((char *z));
393 
394 /* Allocate memory without fail.  */
395 extern pointer xmalloc P((size_t));
396 
397 /* Realloc memory without fail.  */
398 extern pointer xrealloc P((pointer, size_t));
399 
400 /* Free memory (accepts NULL pointers, which some libraries erroneously
401    do not).  */
402 extern void xfree P((pointer));
403 
404 /* Global variables.  */
405 
406 /* The name of the program being run.  Set from argv[0].  */
407 extern const char *zProgram;
408 
409 /* When a signal occurs, the signal handlers sets the appropriate
410    element of the arrays afSignal and afLog_signal to TRUE.  The
411    afSignal array is used to check whether a signal occurred.  The
412    afLog_signal array tells ulog to log the signal; ulog will clear
413    the element after logging it, which means that if a signal comes in
414    at just the right moment it will not be logged.  It will always be
415    recorded in afSignal, though.  At the moment we handle 5 signals:
416    SIGHUP, SIGINT, SIGQUIT, SIGTERM and SIGPIPE (the Unix code also
417    handles SIGALRM).  If we want to handle more, the afSignal array
418    must be extended; I see little point to handling any of the other
419    ANSI C or POSIX signals, as they are either unlikely to occur
420    (SIGABRT, SIGUSR1) or nearly impossible to handle cleanly (SIGILL,
421    SIGSEGV).  SIGHUP is only logged if fLog_sighup is TRUE.  */
422 #define INDEXSIG_SIGHUP (0)
423 #define INDEXSIG_SIGINT (1)
424 #define INDEXSIG_SIGQUIT (2)
425 #define INDEXSIG_SIGTERM (3)
426 #define INDEXSIG_SIGPIPE (4)
427 #define INDEXSIG_COUNT (5)
428 
429 extern volatile sig_atomic_t afSignal[INDEXSIG_COUNT];
430 extern volatile sig_atomic_t afLog_signal[INDEXSIG_COUNT];
431 extern boolean fLog_sighup;
432 
433 /* The names of the signals to use in error messages, as an
434    initializer for an array.  */
435 #define INDEXSIG_NAMES \
436   { "hangup", "interrupt", "quit", "termination", "SIGPIPE" }
437 
438 /* Check to see whether we've received a signal.  It would be nice if
439    we could use a single variable for this, but we sometimes want to
440    clear our knowledge of a signal and that would cause race
441    conditions (clearing a single element of the array is not a race
442    assuming that we don't care about a particular signal, even if it
443    occurs after we've examined the array).  */
444 #define FGOT_SIGNAL() \
445   (afSignal[INDEXSIG_SIGHUP] || afSignal[INDEXSIG_SIGINT] \
446    || afSignal[INDEXSIG_SIGQUIT] || afSignal[INDEXSIG_SIGTERM] \
447    || afSignal[INDEXSIG_SIGPIPE])
448 
449 /* If we get a SIGINT in uucico, we continue the current communication
450    session but don't start any new ones.  This macros checks for any
451    signal other than SIGINT, which means we should get out
452    immediately.  */
453 #define FGOT_QUIT_SIGNAL() \
454   (afSignal[INDEXSIG_SIGHUP] || afSignal[INDEXSIG_SIGQUIT] \
455    || afSignal[INDEXSIG_SIGTERM] || afSignal[INDEXSIG_SIGPIPE])
456 
457 /* Device name to log.  This is set by fconn_open.  It may be NULL.  */
458 extern char *zLdevice;
459 
460 /* If not NULL, ulog calls this function before outputting anything.
461    This is used to support cu.  */
462 extern void (*pfLstart) P((void));
463 
464 /* If not NULL, ulog calls this function after outputting everything.
465    This is used to support cu.  */
466 extern void (*pfLend) P((void));
467