Imported Upstream version 2.4.5p1
[debian/amanda] / common-src / amanda.h
1 /*
2  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3  * Copyright (c) 1991-1998 University of Maryland at College Park
4  * All Rights Reserved.
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of U.M. not be used in advertising or
11  * publicity pertaining to distribution of the software without specific,
12  * written prior permission.  U.M. makes no representations about the
13  * suitability of this software for any purpose.  It is provided "as is"
14  * without express or implied warranty.
15  *
16  * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Authors: the Amanda Development Team.  Its members are listed in a
24  * file named AUTHORS, in the root directory of this distribution.
25  */
26 /*
27  * $Id: amanda.h,v 1.66.2.7.4.5.2.12.2.6 2005/09/20 21:31:52 jrjackson Exp $
28  *
29  * the central header file included by all amanda sources
30  */
31 #ifndef AMANDA_H
32 #define AMANDA_H
33
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37
38 /*
39  * I would prefer that each Amanda module include only those system headers
40  * that are locally needed, but on most Unixes the system header files are not
41  * protected against multiple inclusion, so this can lead to problems.
42  *
43  * Also, some systems put key files in different places, so by including 
44  * everything here the rest of the system is isolated from such things.
45  */
46 #ifdef HAVE_ALLOCA_H
47 #  include <alloca.h>
48 #endif
49
50 #if 0
51 /* an explanation for this is available in the CHANGES file for
52    amanda-2.4.0b5 */
53 #ifdef HAVE_ASM_BYTEORDER_H
54 #  include <asm/byteorder.h>
55 #endif
56 #endif
57
58 #ifdef HAVE_SYS_TYPES_H
59 #  include <sys/types.h>
60 #endif
61
62 /* from the autoconf documentation */
63 #ifdef HAVE_DIRENT_H
64 #  include <dirent.h>
65 #  define NAMLEN(dirent) strlen((dirent)->d_name)
66 #else
67 #  define dirent direct
68 #  define NAMLEN(dirent) (dirent)->d_namlen
69 #  if HAVE_SYS_NDIR_H
70 #    include <sys/ndir.h>
71 #  endif
72 #  if HAVE_SYS_DIR_H
73 #    include <sys/dir.h>
74 #  endif
75 #  if HAVE_NDIR_H
76 #    include <ndir.h>
77 #  endif
78 #endif
79
80 #ifdef HAVE_FCNTL_H
81 #  include <fcntl.h>
82 #endif
83
84 #ifdef HAVE_GRP_H
85 #  include <grp.h>
86 #endif
87
88 #if defined(USE_DB_H)
89 #  include <db.h>
90 #else
91 #if defined(USE_DBM_H)
92 #  include <dbm.h>
93 #else
94 #if defined(USE_GDBM_H)
95 #  include <gdbm.h>
96 #else
97 #if defined(USE_NDBM_H)
98 #  include <ndbm.h>
99 #endif
100 #endif
101 #endif
102 #endif
103
104 #ifdef HAVE_NETDB_H
105 #  include <netdb.h>
106 #endif
107
108 #ifdef TIME_WITH_SYS_TIME
109 #  include <sys/time.h>
110 #  include <time.h>
111 #else
112 #  ifdef HAVE_SYS_TIME_H
113 #    include <sys/time.h>
114 #  else
115 #    include <time.h>
116 #  endif
117 #endif
118
119 #ifdef HAVE_LIBC_H
120 #  include <libc.h>
121 #endif
122
123 #ifdef HAVE_STDLIB_H
124 #  include <stdlib.h>
125 #endif
126
127 #ifdef HAVE_STRING_H
128 #  include <string.h>
129 #endif
130
131 #ifdef HAVE_STRINGS_H
132 #  include <strings.h>
133 #endif
134
135 #ifdef HAVE_SYSLOG_H
136 #  include <syslog.h>
137 #endif
138
139 #ifdef HAVE_SYS_FILE_H
140 #  include <sys/file.h>
141 #endif
142
143 #ifdef HAVE_SYS_IOCTL_H
144 #  include <sys/ioctl.h>
145 #endif
146
147 #ifdef HAVE_SYS_PARAM_H
148 #  include <sys/param.h>
149 #endif
150
151 #if defined(HAVE_SYS_IPC_H) && defined(HAVE_SYS_SHM_H)
152 #  include <sys/ipc.h>
153 #  include <sys/shm.h>
154 #else
155 #  ifdef HAVE_SYS_MMAN_H
156 #    include <sys/mman.h>
157 #  endif
158 #endif
159
160 #ifdef HAVE_SYS_SELECT_H
161 #  include <sys/select.h>
162 #endif
163
164 #ifdef HAVE_SYS_STAT_H
165 #  include <sys/stat.h>
166 #endif
167
168 #ifdef HAVE_WAIT_H
169 #  include <wait.h>
170 #endif
171
172 #ifdef HAVE_SYS_WAIT_H
173 #  include <sys/wait.h>
174 #endif
175
176 #ifdef WAIT_USES_INT
177   typedef int amwait_t;
178 # ifndef WEXITSTATUS
179 #  define WEXITSTATUS(stat_val) (*(unsigned*)&(stat_val) >> 8)
180 # endif
181 # ifndef WTERMSIG
182 #  define WTERMSIG(stat_val) (*(unsigned*)&(stat_val) & 0x7F)
183 # endif
184 # ifndef WIFEXITED
185 #  define WIFEXITED(stat_val) ((*(unsigned*)&(stat_val) & 255) == 0)
186 # endif
187 #else
188 # ifdef WAIT_USES_UNION
189    typedef union wait amwait_t;
190 #  ifndef WEXITSTATUS
191 #  define WEXITSTATUS(stat_val) (((amwait_t*)&(stat_val))->w_retcode)
192 #  endif
193 #  ifndef WTERMSIG
194 #   define WTERMSIG(stat_val) (((amwait_t*)&(stat_val))->w_termsig)
195 #  endif
196 #  ifndef WIFEXITED
197 #   define WIFEXITED(stat_val) (WTERMSIG(stat_val) == 0)
198 #  endif
199 # else
200    typedef int amwait_t;
201 #  ifndef WEXITSTATUS
202 #   define WEXITSTATUS(stat_val) (*(unsigned*)&(stat_val) >> 8)
203 #  endif
204 #  ifndef WTERMSIG
205 #   define WTERMSIG(stat_val) (*(unsigned*)&(stat_val) & 0x7F)
206 #  endif
207 #  ifndef WIFEXITED
208 #   define WIFEXITED(stat_val) ((*(unsigned*)&(stat_val) & 255) == 0)
209 #  endif
210 # endif
211 #endif
212
213 #ifdef HAVE_UNISTD_H
214 #  include <unistd.h>
215 #endif
216
217 /*
218  * At present, the kerberos routines require atexit(), or equivilent.  If 
219  * you're not using kerberos, you don't need it at all.  If you just null
220  * out the definition, you'll end up with ticket files hanging around in
221  * /tmp.
222  */
223 #if defined(KRB4_SECURITY)
224 #   if !defined(HAVE_ATEXIT) 
225 #      if defined(HAVE_ON_EXIT)
226 #          define atexit(func) on_exit(func, 0)
227 #      else
228 #          define atexit(func) (you must to resolve lack of atexit in amanda.h)
229 #      endif
230 #   endif
231 #endif
232
233 #include <ctype.h>
234 #include <errno.h>
235 #include <netinet/in.h>
236 #include <pwd.h>
237 #include <signal.h>
238 #include <setjmp.h>
239 #include <stdio.h>
240 #include <sys/resource.h>
241 #include <sys/socket.h>
242
243 #if !defined(CONFIGURE_TEST)
244 #  include "amanda-int.h"
245 #endif
246
247 #ifdef HAVE_ARPA_INET_H
248 #include <arpa/inet.h>
249 #endif
250
251 #ifdef KRB4_SECURITY
252 #  include <des.h>
253 #  include <krb.h>
254 #endif
255
256 /*
257  * The dbmalloc package comes from:
258  *
259  *  http://www.clark.net/pub/dickey/dbmalloc/dbmalloc.tar.gz
260  *
261  * or
262  *
263  *  ftp://gatekeeper.dec.com/pub/usenet/comp.sources.misc/volume32/dbmalloc/
264  *
265  * The following functions are sprinkled through the code, but are
266  * disabled unless USE_DBMALLOC is defined:
267  *
268  *  malloc_enter(char *) -- stack trace for malloc reports
269  *  malloc_leave(char *) -- stack trace for malloc reports
270  *  malloc_mark(void *) -- mark an area as never to be free-d
271  *  malloc_chain_check(void) -- check the malloc area now
272  *  malloc_dump(int fd) -- report the malloc contents to a file descriptor
273  *  malloc_list(int fd, ulong a, ulong b) -- report memory activated since
274  *      history stamp a that is still active as of stamp b (leak check)
275  *  malloc_inuse(ulong *h) -- create history stamp h and return the amount
276  *      of memory currently in use.
277  */
278
279 #ifdef USE_DBMALLOC
280 #include "dbmalloc.h"
281 #else
282 #define malloc_enter(func)
283 #define malloc_leave(func)
284 #define malloc_mark(ptr)
285 #define malloc_chain_check()
286 #define malloc_dump(fd)
287 #define malloc_list(a,b,c)
288 #define malloc_inuse(hist)              (*(hist) = 0, 0)
289 #define dbmalloc_caller_loc(x,y)        (x)
290 #endif
291
292 #if !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC)
293 /* quick'n'dirty hack for NextStep31 */
294 #  define sa_flags sv_flags
295 #  define sa_handler sv_handler
296 #  define sa_mask sv_mask
297 #  define sigaction sigvec
298 #  define sigemptyset(mask) /* no way to clear pending signals */
299 #endif
300
301 /*
302  * Most Unixen declare errno in <errno.h>, some don't.  Some multithreaded
303  * systems have errno as a per-thread macro.  So, we have to be careful.
304  */
305 #ifndef errno
306 extern int errno;
307 #endif
308
309
310 /*
311  * Some older BSD systems don't have these FD_ macros, so if not, provide them.
312  */
313 #ifndef FD_SET
314 #  define FD_SETSIZE      (sizeof(fd_set) * 8)
315 #  define FD_SET(n, p)    (((fd_set *) (p))->fds_bits[0] |= (1 << ((n) % 32)))
316 #  define FD_CLR(n, p)    (((fd_set *) (p))->fds_bits[0] &= ~(1 << ((n) % 32)))
317 #  define FD_ISSET(n, p)  (((fd_set *) (p))->fds_bits[0] & (1 << ((n) % 32)))
318 #  define FD_ZERO(p)      memset((p), 0, sizeof(*(p)))
319 #endif
320
321
322 /*
323  * Define MAX_HOSTNAME_LENGTH as the size of arrays to hold hostname's.
324  */
325 #undef  MAX_HOSTNAME_LENGTH
326 #define MAX_HOSTNAME_LENGTH 1025
327
328 /*
329  * If void is broken, substitute char.
330  */
331 #ifdef BROKEN_VOID
332 #  define void char
333 #endif
334
335 /*
336  * define prototype macro so that prototypes can be declared in both ANSI
337  * and classic C environments.
338  */
339 #if STDC_HEADERS
340 #  define P(parms)      parms
341 #  define stringize(x) #x
342 #else
343 #  define P(parms)      ()
344 #  define stringize(x) "x"
345 #endif
346
347 /*
348  * So that we can use GNUC attributes (such as to get -Wall warnings
349  * for printf-like functions).  Only do this in gcc 2.7 or later ...
350  * it may work on earlier stuff, but why chance it.
351  */
352 #if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 7
353 #define __attribute__(__x)
354 #endif
355
356 /*
357  * assertions, but call error() instead of abort 
358  */
359 #ifndef ASSERTIONS
360
361 #define assert(exp) ((void)0)
362
363 #else   /* ASSERTIONS */
364
365 #define assert(exp) {if(!(exp)) error("assert: %s false, file %s, line %d", \
366                                    stringize(exp), __FILE__, __LINE__);}
367
368 #endif  /* ASSERTIONS */
369
370 /*
371  * print debug output, else compile to nothing.
372  */
373
374 #ifdef DEBUG_CODE                                                       /* { */
375 #   define dbopen()     debug_open()
376 #   define dbreopen(a,b) debug_reopen(a,b)
377 #   define dbclose()    debug_close()
378 #   define dbprintf(p)  (debug? (debug_printf p, 0) : 0)
379 #   define dbfd()       debug_fd()
380 #   define dbfp()       debug_fp()
381 #   define dbfn()       debug_fn()
382
383 extern void debug_open P((void));
384 extern void debug_reopen P((char *file, char *notation));
385 extern void debug_close P((void));
386 extern void debug_printf P((char *format, ...))
387     __attribute__ ((format (printf, 1, 2)));
388 extern int  debug_fd P((void));
389 extern FILE *  debug_fp P((void));
390 extern char *  debug_fn P((void));
391 extern void set_debug_prefix_pid P((pid_t));
392 extern char *debug_prefix P((char *));
393 extern char *debug_prefix_time P((char *));
394 #else                                                                   /* }{ */
395 #   define dbopen()
396 #   define dbreopen(a,b)
397 #   define dbclose()
398 #   define dbprintf(p)
399 #   define dbfd()       (-1)
400 #   define dbfp()       NULL
401 #   define dbfn()       NULL
402 #   define set_debug_prefix_pid(x)
403 #   define debug_prefix(x) get_pname()
404 #   define debug_prefix_time(x) get_pname()
405 #endif                                                                  /* } */
406
407 /* amanda #days calculation, with roundoff */
408
409 #define SECS_PER_DAY    (24*60*60)
410 #define days_diff(a, b) (((b) - (a) + SECS_PER_DAY/2) / SECS_PER_DAY)
411
412 /* Global constants.  */
413 #ifndef AMANDA_SERVICE_NAME
414 #define AMANDA_SERVICE_NAME "amanda"
415 #endif
416 #ifndef KAMANDA_SERVICE_NAME
417 #define KAMANDA_SERVICE_NAME "kamanda"
418 #endif
419 #ifndef SERVICE_SUFFIX
420 #define SERVICE_SUFFIX ""
421 #endif
422 #ifndef AMANDA_SERVICE_DEFAULT
423 #define AMANDA_SERVICE_DEFAULT  10080
424 #endif
425 #ifndef KAMANDA_SERVICE_DEFAULT
426 #define KAMANDA_SERVICE_DEFAULT 10081
427 #endif
428
429 #define am_round(v,u)   ((((v) + (u) - 1) / (u)) * (u))
430 #define am_floor(v,u)   (((v) / (u)) * (u))
431
432 /* Holding disk block size.  Do not even think about changing this!  :-) */
433 #define DISK_BLOCK_KB           32
434 #define DISK_BLOCK_BYTES        (DISK_BLOCK_KB * 1024)
435
436 /* Maximum size of a tape block */
437 /* MAX_TAPE_BLOCK_KB is defined in config.h */
438 /* by configure --with-maxtapeblocksize     */
439 #define MAX_TAPE_BLOCK_BYTES (MAX_TAPE_BLOCK_KB*1024)
440
441 /* Define miscellaneous amanda functions.  */
442 #define ERR_INTERACTIVE 1
443 #define ERR_SYSLOG      2
444 #define ERR_AMANDALOG   4
445
446 /* For static buffer manager [alloc.c:sbuf_man()] */
447 #define SBUF_MAGIC 42
448 #define SBUF_DEF(name, len) static SBUF2_DEF(len) name = {SBUF_MAGIC, len, -1}
449 #define SBUF2_DEF(len)          \
450     struct {                    \
451         int magic;              \
452         int max, cur;           \
453         void *bufp[len];        \
454     }
455
456 extern void   set_logerror P((void (*f)(char *)));
457 extern void   set_pname P((char *pname));
458 extern char  *get_pname P((void));
459 extern int    erroutput_type;
460 extern void   error     P((char *format, ...))
461     __attribute__ ((format (printf, 1, 2)));
462 extern void   errordump P((char *format, ...))
463     __attribute__ ((format (printf, 1, 2)));
464 extern int    onerror         P((void (*errf)(void)));
465
466 extern void  *debug_alloc           P((char *c, int l, size_t size));
467 extern void  *debug_newalloc        P((char *c, int l, void *old, size_t size));
468 extern char  *debug_stralloc        P((char *c, int l, const char *str));
469 extern char  *debug_newstralloc     P((char *c, int l, char *oldstr, const char *newstr));
470 extern char  *debug_caller_loc      P((char *file, int line));
471
472 extern int   debug_alloc_push       P((char *file, int line));
473 extern void  debug_alloc_pop        P((void));
474
475 #define alloc(s)                debug_alloc(__FILE__, __LINE__, (s))
476 #define newalloc(p,s)           debug_newalloc(__FILE__, __LINE__, (p), (s))
477 #define stralloc(s)             debug_stralloc(__FILE__, __LINE__, (s))
478 #define newstralloc(p,s)        debug_newstralloc(__FILE__, __LINE__, (p), (s))
479
480 /*
481  * Voodoo time.  We want to be able to mark these calls with the source
482  * line, but CPP does not handle variable argument lists so we cannot
483  * do what we did above (e.g. for alloc()).
484  *
485  * What we do is call a function to save the file and line number
486  * and have it return "false".  That triggers the "?" operator to
487  * the right side of the ":" which is a call to the debug version of
488  * vstralloc/newvstralloc but without parameters.  The compiler gets
489  * those from the next input tokens:
490  *
491  *  xx = vstralloc(a,b,NULL);
492  *
493  * becomes:
494  *
495  *  xx = debug_alloc_push(__FILE__,__LINE__)?0:debug_vstralloc(a,b,NULL);
496  *
497  * This works as long as vstralloc/newvstralloc are not part of anything
498  * very complicated.  Assignment is fine, as is an argument to another
499  * function (but you should not do that because it creates a memory leak).
500  * This will not work in arithmetic or comparison, but it is unlikely
501  * they are used like that.
502  *
503  *  xx = vstralloc(a,b,NULL);                   OK
504  *  return vstralloc(j,k,NULL);                 OK
505  *  sub(a, vstralloc(g,h,NULL), z);             OK, but a leak
506  *  if(vstralloc(s,t,NULL) == NULL) { ...       NO, but unneeded
507  *  xx = vstralloc(x,y,NULL) + 13;              NO, but why do it?
508  */
509
510 #define vstralloc debug_alloc_push(__FILE__,__LINE__)?0:debug_vstralloc
511 #define newvstralloc debug_alloc_push(__FILE__,__LINE__)?0:debug_newvstralloc
512
513 extern char  *debug_vstralloc       P((const char *str, ...));
514 extern char  *debug_newvstralloc    P((char *oldstr, const char *newstr, ...));
515
516 #define stralloc2(s1,s2)      vstralloc((s1),(s2),NULL)
517 #define newstralloc2(p,s1,s2) newvstralloc((p),(s1),(s2),NULL)
518
519 extern char  *debug_agets     P((char *c, int l, FILE *file));
520 extern char  *debug_areads    P((char *c, int l, int fd));
521 #define agets(f)              debug_agets(__FILE__,__LINE__,(f))
522 #define areads(f)             debug_areads(__FILE__,__LINE__,(f))
523
524 extern int debug_amtable_alloc P((char *file,
525                                   int line,
526                                   void **table,
527                                   int *current,
528                                   size_t elsize,
529                                   int count,
530                                   int bump,
531                                   void (*init_func)(void *)));
532 #define amtable_alloc(t,c,s,n,b,f) debug_amtable_alloc(__FILE__,        \
533                                                        __LINE__,        \
534                                                        (t),             \
535                                                        (c),             \
536                                                        (s),             \
537                                                        (n),             \
538                                                        (b),             \
539                                                        (f))
540 extern void amtable_free      P((void **table, int *current));
541
542 extern void  *sbuf_man        P((void *bufs, void *ptr));
543 extern uid_t  client_uid;
544 extern gid_t  client_gid;
545 extern void   safe_cd         P((void));
546 extern void   safe_fd         P((int fd_start, int fd_count));
547 extern void   save_core       P((void));
548 extern char **safe_env        P((void));
549 extern char  *validate_regexp P((char *regex));
550 extern char  *validate_glob   P((char *glob));
551 extern char  *clean_regex     P((char *regex));
552 extern int    match           P((char *regex, char *str));
553 extern int    match_glob      P((char *glob, char *str));
554 extern char  *glob_to_regex   P((char *glob));
555 extern int    match_tar       P((char *glob, char *str));
556 extern char  *tar_to_regex    P((char *glob));
557 extern int    match_host      P((char *glob, char *host));
558 extern int    match_disk      P((char *glob, char *disk));
559 extern int    match_datestamp P((char *dateexp, char *datestamp));
560 extern time_t unctime         P((char *timestr));
561 extern ssize_t  areads_dataready  P((int fd));
562 extern void     areads_relbuf     P((int fd));
563
564 /*
565  * amfree(ptr) -- if allocated, release space and set ptr to NULL.
566  *
567  * In general, this should be called instead of just free(), unless
568  * the very next source line sets the pointer to a new value.
569  */
570
571 #define amfree(ptr) do {                                                \
572     if(ptr) {                                                           \
573         int e__errno = errno;                                           \
574         free(ptr);                                                      \
575         (ptr) = NULL;                                                   \
576         errno = e__errno;                                               \
577     }                                                                   \
578 } while(0)
579
580 #define strappend(s1,s2) do {                                           \
581     char *t_t_t = (s1) ? stralloc2((s1),(s2)) : stralloc((s2));         \
582     amfree((s1));                                                       \
583     (s1) = t_t_t;                                                       \
584 } while(0)
585
586 /*
587  * "Safe" close macros.  Close the object then set it to a value that
588  * will cause an error if referenced.
589  *
590  * aclose(fd) -- close a file descriptor and set it to -1.
591  * afclose(f) -- close a stdio file and set it to NULL.
592  * apclose(p) -- close a stdio pipe file and set it to NULL.
593  *
594  * Note: be careful not to do the following:
595  *
596  *  for(fd = low; fd < high; fd++) {
597  *      aclose(fd);
598  *  }
599  *
600  * Since aclose() sets the argument to -1, this will loop forever.
601  * Just copy fd to a temp variable and use that with aclose().
602  *
603  * Aclose() interacts with areads() to inform it to release any buffer
604  * it has outstanding on the file descriptor.
605  */
606
607 #define aclose(fd) do {                                                 \
608     if((fd) >= 0) {                                                     \
609         close(fd);                                                      \
610         areads_relbuf(fd);                                              \
611     }                                                                   \
612     (fd) = -1;                                                          \
613 } while(0)
614
615 #define afclose(f) do {                                                 \
616     if((f) != NULL) {                                                   \
617         fclose(f);                                                      \
618     }                                                                   \
619     (f) = NULL;                                                         \
620 } while(0)
621
622 #define apclose(p) do {                                                 \
623     if((p) != NULL) {                                                   \
624         pclose(p);                                                      \
625     }                                                                   \
626     (p) = NULL;                                                         \
627 } while(0)
628
629 /*
630  * Return the number of elements in an array.
631  */
632 #define am_countof(a)        (sizeof(a) / sizeof((a)[0]))
633
634 /*
635  * min/max.  Don't do something like
636  *
637  *    x = min(y++, z);
638  *
639  * because the increment will be duplicated.
640  */
641 #undef min
642 #undef max
643 #define min(a, b)       ((a) < (b) ? (a) : (b))
644 #define max(a, b)       ((a) > (b) ? (a) : (b))
645
646 /*
647  * Utility string macros.  All assume a variable holds the current
648  * character and the string pointer points to the next character to
649  * be processed.  Typical setup is:
650  *
651  *  s = buffer;
652  *  ch = *s++;
653  *  skip_whitespace(s, ch);
654  *  ...
655  *
656  * If you advance the pointer "by hand" to skip over something, do
657  * it like this:
658  *
659  *  s += some_amount;
660  *  ch = s[-1];
661  *
662  * Note that ch has the character at the end of the just skipped field.
663  * It is often useful to terminate a string, make a copy, then restore
664  * the input like this:
665  *
666  *  skip_whitespace(s, ch);
667  *  fp = s-1;                   ## save the start
668  *  skip_nonwhitespace(s, ch);  ## find the end
669  *  p[-1] = '\0';               ## temporary terminate
670  *  field = stralloc(fp);       ## make a copy
671  *  p[-1] = ch;                 ## restore the input
672  *
673  * The scanning macros are:
674  *
675  *  skip_whitespace (ptr, var)
676  *    -- skip whitespace, but stops at a newline
677  *  skip_non_whitespace (ptr, var)
678  *    -- skip non whitespace
679  *  skip_non_whitespace_cs (ptr, var)
680  *    -- skip non whitespace, stop at comment
681  *  skip_integer (ptr, var)
682  *    -- skip an integer field
683  *  skip_line (ptr, var)
684  *    -- skip just past the next newline
685  *
686  * where:
687  *
688  *  ptr -- string pointer
689  *  var -- current character
690  *
691  * These macros copy a non-whitespace field to a new buffer, and should
692  * only be used if dynamic allocation is impossible (fixed size buffers
693  * are asking for trouble):
694  *
695  *  copy_string (ptr, var, field, len, fldptr)
696  *    -- copy a non-whitespace field
697  *  copy_string_cs (ptr, var, field, len, fldptr)
698  *    -- copy a non-whitespace field, stop at comment
699  *
700  * where:
701  *
702  *  ptr -- string pointer
703  *  var -- current character
704  *  field -- area to copy to
705  *  len -- length of area (needs room for null byte)
706  *  fldptr -- work pointer used in move
707  *            if NULL on exit, the field was too small for the input
708  */
709
710 #define STR_SIZE        1024            /* a generic string buffer size */
711 #define NUM_STR_SIZE    32              /* a generic number buffer size */
712
713 #define skip_whitespace(ptr,c) do {                                     \
714     while((c) != '\n' && isspace(c)) (c) = *(ptr)++;                    \
715 } while(0)
716
717 #define skip_non_whitespace(ptr,c) do {                                 \
718     while((c) != '\0' && !isspace(c)) (c) = *(ptr)++;                   \
719 } while(0)
720
721 #define skip_non_whitespace_cs(ptr,c) do {                              \
722     while((c) != '\0' && (c) != '#' && !isspace(c)) (c) = *(ptr)++;     \
723 } while(0)
724
725 #define skip_non_integer(ptr,c) do {                                    \
726     while((c) != '\0' && !isdigit(c)) (c) = *(ptr)++;                   \
727 } while(0)
728
729 #define skip_integer(ptr,c) do {                                        \
730     if((c) == '+' || (c) == '-') (c) = *(ptr)++;                        \
731     while(isdigit(c)) (c) = *(ptr)++;                                   \
732 } while(0)
733
734 #define skip_line(ptr,c) do {                                           \
735     while((c) && (c) != '\n') (c) = *(ptr)++;                           \
736     if(c) (c) = *(ptr)++;                                               \
737 } while(0)
738
739 #define copy_string(ptr,c,f,l,fp) do {                                  \
740     (fp) = (f);                                                         \
741     while((c) != '\0' && !isspace(c)) {                                 \
742         if((fp) >= (f) + (l) - 1) {                                     \
743             *(fp) = '\0';                                               \
744             (fp) = NULL;                                                \
745             break;                                                      \
746         }                                                               \
747         *(fp)++ = (c);                                                  \
748         (c) = *(ptr)++;                                                 \
749     }                                                                   \
750     if(fp) *fp = '\0';                                                  \
751 } while(0)
752
753 #define copy_string_cs(ptr,c,f,l,fp) do {                               \
754     (fp) = (f);                                                         \
755     while((c) != '\0' && (c) != '#' && !isspace(c)) {                   \
756         if((fp) >= (f) + (l) - 1) {                                     \
757             *(fp) = '\0';                                               \
758             (fp) = NULL;                                                \
759             break;                                                      \
760         }                                                               \
761         *(fp)++ = (c);                                                  \
762         (c) = *(ptr)++;                                                 \
763     }                                                                   \
764     if(fp) *fp = '\0';                                                  \
765 } while(0)
766
767 #define is_dot_or_dotdot(s)                                             \
768     ((s)[0] == '.'                                                      \
769      && ((s)[1] == '\0'                                                 \
770          || ((s)[1] == '.' && (s)[2] == '\0')))
771
772 /* from amflock.c */
773 extern int    amflock   P((int fd, char *resource));
774 extern int    amroflock P((int fd, char *resource));
775 extern int    amfunlock P((int fd, char *resource));
776
777 /* from file.c */
778 extern int    mkpdir    P((char *file, int mode, uid_t uid, gid_t gid));
779 extern int    rmpdir    P((char *file, char *topdir));
780 extern char  *sanitise_filename P((char *inp));
781
782 extern int debug;
783 extern char *version_info[];
784
785 /* from security.c */
786 extern int security_ok P((struct sockaddr_in *addr,
787                           char *str, uint32_t cksum, char **errstr));
788 extern char *get_bsd_security P((void));
789
790 /*
791  * Handle functions which are not always declared on all systems.  This
792  * stops gcc -Wall and lint from complaining.
793  */
794
795 /* AIX #defines accept, and provides a prototype for the alternate name */
796 #if !defined(HAVE_ACCEPT_DECL) && !defined(accept)
797 extern int accept P((int s, struct sockaddr *addr, int *addrlen));
798 #endif
799
800 #ifndef HAVE_ATOF_DECL
801 extern double atof P((const char *ptr));
802 #endif
803
804 #ifndef HAVE_BCOPY
805 # define bcopy(from,to,n) ((void)memmove((to), (from), (n)))
806 #else
807 # ifndef HAVE_BCOPY_DECL
808 extern void bcopy P((const void *s1, void *s2, size_t n));
809 # endif
810 #endif
811
812 #ifndef HAVE_BIND_DECL
813 extern int bind P((int s, const struct sockaddr *name, int namelen));
814 #endif
815
816 #ifndef HAVE_BZERO
817 #define bzero(s,n) ((void)memset((s),0,(n)))
818 #else
819 # ifndef HAVE_BZERO_DECL
820 extern void bzero P((void *s, size_t n));
821 # endif
822 #endif
823
824 #ifndef HAVE_CLOSELOG_DECL
825 extern void closelog P((void));
826 #endif
827
828 #ifndef HAVE_CONNECT_DECL
829 extern int connect P((int s, struct sockaddr *name, int namelen));
830 #endif
831
832 #if !defined(TEXTDB) && !defined(HAVE_DBM_OPEN_DECL)
833 #undef   DBM_INSERT
834 #define  DBM_INSERT  0
835
836 #undef   DBM_REPLACE
837 #define  DBM_REPLACE 1
838
839     typedef struct {
840         int dummy[10];
841     } DBM;
842
843 #ifndef HAVE_STRUCT_DATUM
844     typedef struct {
845         char    *dptr;
846         int     dsize;
847     } datum;
848 #endif
849
850     extern DBM   *dbm_open     P((char *file, int flags, int mode));
851     extern void   dbm_close    P((DBM *db));
852     extern datum  dbm_fetch    P((DBM *db, datum key));
853     extern datum  dbm_firstkey P((DBM *db));
854     extern datum  dbm_nextkey  P((DBM *db));
855     extern int    dbm_delete   P((DBM *db, datum key));
856     extern int    dbm_store    P((DBM *db, datum key, datum content, int flg));
857 #endif
858
859 #ifndef HAVE_FCLOSE_DECL
860 extern int fclose P((FILE *stream));
861 #endif
862
863 #ifndef HAVE_FFLUSH_DECL
864 extern int fflush P((FILE *stream));
865 #endif
866
867 #ifndef HAVE_FPRINTF_DECL
868 extern int fprintf P((FILE *stream, const char *format, ...));
869 #endif
870
871 #ifndef HAVE_FPUTC_DECL
872 extern int fputc P((int c, FILE *stream));
873 #endif
874
875 #ifndef HAVE_FPUTS_DECL
876 extern int fputs P((const char *s, FILE *stream));
877 #endif
878
879 #ifndef HAVE_FREAD_DECL
880 extern size_t fread P((void *ptr, size_t size, size_t nitems, FILE *stream));
881 #endif
882
883 #ifndef HAVE_FSEEK_DECL
884 extern int fseek P((FILE *stream, long offset, int ptrname));
885 #endif
886
887 #ifndef HAVE_FWRITE_DECL
888 extern size_t fwrite P((const void *ptr, size_t size, size_t nitems,
889                         FILE *stream));
890 #endif
891
892 #ifndef HAVE_GETHOSTNAME_DECL
893 extern int gethostname P((char *name, int namelen));
894 #endif
895
896 #ifndef HAVE_GETOPT_DECL
897 extern char *optarg;
898 extern int getopt P((int argc, char * const *argv, const char *optstring));
899 #endif
900
901 /* AIX #defines getpeername, and provides a prototype for the alternate name */
902 #if !defined(HAVE_GETPEERNAME_DECL) && !defined(getpeername)
903 extern int getpeername P((int s, struct sockaddr *name, int *namelen));
904 #endif
905
906 /* AIX #defines getsockname, and provides a prototype for the alternate name */
907 #if !defined(HAVE_GETSOCKNAME_DECL) && !defined(getsockname)
908 extern int getsockname P((int s, struct sockaddr *name, int *namelen));
909 #endif
910
911 #ifndef HAVE_GETSOCKOPT_DECL
912 extern int getsockopt P((int s, int level, int optname, char *optval,
913                          int *optlen));
914 #endif
915
916 #ifndef HAVE_GETTIMEOFDAY_DECL
917 # ifdef HAVE_TWO_ARG_GETTIMEOFDAY
918 extern int gettimeofday P((struct timeval *tp, struct timezone *tzp));
919 # else
920 extern int gettimeofday P((struct timeval *tp));
921 # endif
922 #endif
923
924 #ifndef HAVE_INITGROUPS
925 # define initgroups(name,basegid) 0
926 #else
927 # ifndef HAVE_INITGROUPS_DECL
928 /* modification by BIS@BBN 5/20/2003:
929  * In some Unix systems, basegid is defined as a gid_t; in others
930  * it is defined as an int.  On Mac OS X, there is a "pre-compiled"
931  * unistd.h which causes the gcc -E command in the ICE_CHECK_DECL
932  * autoconf macro to not succeed.  Thus, on Mac OS X, configure thinks
933  * we don't have this declaration when we actually do.  Since Mac OS X
934  * defines basegid as an int, this declaration causes a compilation
935  * failure.  The path of least resistance for fixing this problem
936  * is to just change the basegid declaration from gid_t to int, since
937  * other (but not all) UNIX flavors also defined basegid as an int.
938 extern int initgroups P((const char *name, gid_t basegid));
939  */
940 extern int initgroups P((const char *name, int basegid));
941 # endif
942 #endif
943
944 #ifndef HAVE_IOCTL_DECL
945 extern int ioctl P((int fildes, int request, ...));
946 #endif
947
948 #ifndef HAVE_LISTEN_DECL
949 extern int listen P((int s, int backlog));
950 #endif
951
952 #ifndef HAVE_LSTAT_DECL
953 extern int lstat P((const char *path, struct stat *buf));
954 #endif
955
956 #ifndef HAVE_MALLOC_DECL
957 extern void *malloc P((size_t size));
958 #endif
959
960 #ifndef HAVE_MEMMOVE_DECL
961 #ifdef HAVE_MEMMOVE
962 extern void *memmove P((void *to, const void *from, size_t n));
963 #else
964 extern char *memmove P((char *to, /*const*/ char *from, size_t n));
965 #endif
966 #endif
967
968 #ifndef HAVE_MEMSET_DECL
969 extern void *memset P((void *s, int c, size_t n));
970 #endif
971
972 #ifndef HAVE_MKTEMP_DECL
973 extern char *mktemp P((char *template));
974 #endif
975
976 #ifndef HAVE_MKTIME_DECL
977 extern time_t mktime P((struct tm *timeptr));
978 #endif
979
980 #ifndef HAVE_OPENLOG_DECL
981 #ifdef LOG_AUTH
982 extern void openlog P((const char *ident, int logopt, int facility));
983 #else
984 extern void openlog P((const char *ident, int logopt));
985 #endif
986 #endif
987
988 #ifndef HAVE_PCLOSE_DECL
989 extern int pclose P((FILE *stream));
990 #endif
991
992 #ifndef HAVE_PERROR_DECL
993 extern void perror P((const char *s));
994 #endif
995
996 #ifndef HAVE_PRINTF_DECL
997 extern int printf P((const char *format, ...));
998 #endif
999
1000 #ifndef HAVE_PUTS_DECL
1001 extern int puts P((const char *s));
1002 #endif
1003
1004 #ifndef HAVE_REALLOC_DECL
1005 extern void *realloc P((void *ptr, size_t size));
1006 #endif
1007
1008 /* AIX #defines recvfrom, and provides a prototype for the alternate name */
1009 #if !defined(HAVE_RECVFROM_DECL) && !defined(recvfrom)
1010 extern int recvfrom P((int s, char *buf, int len, int flags,
1011                        struct sockaddr *from, int *fromlen));
1012 #endif
1013
1014 #ifndef HAVE_REMOVE_DECL
1015 extern int remove P((const char *path));
1016 #endif
1017
1018 #ifndef HAVE_RENAME_DECL
1019 extern int rename P((const char *old, const char *new));
1020 #endif
1021
1022 #ifndef HAVE_REWIND_DECL
1023 extern void rewind P((FILE *stream));
1024 #endif
1025
1026 #ifndef HAVE_RUSEROK_DECL
1027 extern int ruserok P((const char *rhost, int suser,
1028                       const char *ruser, const char *luser));
1029 #endif
1030
1031 #ifndef HAVE_SELECT_DECL
1032 extern int select P((int nfds,
1033                      SELECT_ARG_TYPE *readfds,
1034                      SELECT_ARG_TYPE *writefds,
1035                      SELECT_ARG_TYPE *exceptfds,
1036                      struct timeval *timeout));
1037 #endif
1038
1039 #ifndef HAVE_SENDTO_DECL
1040 extern int sendto P((int s, const char *msg, int len, int flags,
1041                      const struct sockaddr *to, int tolen));
1042 #endif
1043
1044 #ifdef HAVE_SETRESGID
1045 #define setegid(x)      setresgid(-1,(x),-1)
1046 #ifndef HAVE_SETRESGID_DECL
1047 extern int setresgid P((gid_t rgid, gid_t egid, gid_t sgid));
1048 #endif
1049 #else
1050 #ifndef HAVE_SETEGID_DECL
1051 extern int setegid P((gid_t egid));
1052 #endif
1053 #endif
1054
1055 #ifdef HAVE_SETRESUID
1056 #define seteuid(x)      setresuid(-1,(x),-1)
1057 #ifndef HAVE_SETRESUID_DECL
1058 extern int setresuid P((uid_t ruid, uid_t euid, uid_t suid));
1059 #endif
1060 #else
1061 #ifndef HAVE_SETEUID_DECL
1062 extern int seteuid P((uid_t euid));
1063 #endif
1064 #endif
1065
1066 #ifndef HAVE_SETPGID_DECL
1067 #ifdef HAVE_SETPGID
1068 extern int setpgid P((int pid, int pgid));
1069 #endif
1070 #endif
1071
1072 #ifndef HAVE_SETPGRP_DECL
1073 #ifdef SETPGRP_VOID
1074 extern pid_t setpgrp P((void));
1075 #else
1076 extern pid_t setpgrp P((int pgrp, int pid));
1077 #endif
1078 #endif
1079
1080 #ifndef HAVE_SETSOCKOPT_DECL
1081 extern int setsockopt P((int s, int level, int optname,
1082                          const char *optval, int optlen));
1083 #endif
1084
1085 #ifdef HAVE_SHMGET
1086 #ifndef HAVE_SHMAT_DECL
1087 extern void *shmat P((int shmid, const SHM_ARG_TYPE *shmaddr, int shmflg));
1088 #endif
1089
1090 #ifndef HAVE_SHMCTL_DECL
1091 extern int shmctl P((int shmid, int cmd, struct shmid_ds *buf));
1092 #endif
1093
1094 #ifndef HAVE_SHMDT_DECL
1095 extern int shmdt P((SHM_ARG_TYPE *shaddr));
1096 #endif
1097
1098 #ifndef HAVE_SHMGET_DECL
1099 extern int shmget P((key_t key, size_t size, int shmflg));
1100 #endif
1101 #endif
1102
1103 #if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF)
1104 #define ap_snprintf     snprintf
1105 #define ap_vsnprintf    vsnprintf
1106 #endif
1107 #ifndef HAVE_SNPRINTF_DECL
1108 #include "arglist.h"
1109 int ap_snprintf  P((char *buf, size_t len, const char *format,...))
1110                     __attribute__((format(printf,3,4)));
1111 #endif
1112 #ifndef HAVE_VSNPRINTF_DECL
1113 #include "arglist.h"
1114 int ap_vsnprintf P((char *buf, size_t len, const char *format, va_list ap));
1115 #endif
1116
1117 #ifndef HAVE_SOCKET_DECL
1118 extern int socket P((int domain, int type, int protocol));
1119 #endif
1120
1121 #ifndef HAVE_SOCKETPAIR_DECL
1122 extern int socketpair P((int domain, int type, int protocol, int sv[2]));
1123 #endif
1124
1125 #ifndef HAVE_SSCANF_DECL
1126 extern int sscanf P((const char *s, const char *format, ...));
1127 #endif
1128
1129 #ifndef HAVE_STRCASECMP_DECL
1130 extern int strcasecmp P((const char *s1, const char *s2));
1131 #endif
1132
1133 #ifndef HAVE_STRERROR_DECL
1134 extern char *strerror P((int errnum));
1135 #endif
1136
1137 #ifndef HAVE_STRFTIME_DECL
1138 extern size_t strftime P((char *s, size_t maxsize, const char *format,
1139                           const struct tm *timeptr));
1140 #endif
1141
1142 #ifndef HAVE_STRNCASECMP_DECL
1143 extern int strncasecmp P((const char *s1, const char *s2, int n));
1144 #endif
1145
1146 #ifndef HAVE_SYSLOG_DECL
1147 extern void syslog P((int priority, const char *logstring, ...))
1148     __attribute__ ((format (printf, 2, 3)));
1149 #endif
1150
1151 #ifndef HAVE_SYSTEM_DECL
1152 extern int system P((const char *string));
1153 #endif
1154
1155 #ifndef HAVE_TIME_DECL
1156 extern time_t time P((time_t *tloc));
1157 #endif
1158
1159 #ifndef HAVE_TOLOWER_DECL
1160 extern int tolower P((int c));
1161 #endif
1162
1163 #ifndef HAVE_TOUPPER_DECL
1164 extern int toupper P((int c));
1165 #endif
1166
1167 #ifndef HAVE_UNGETC_DECL
1168 extern int ungetc P((int c, FILE *stream));
1169 #endif
1170
1171 #ifndef HAVE_VFPRINTF_DECL
1172 #include "arglist.h"
1173 extern int vfprintf P((FILE *stream, const char *format, va_list ap));
1174 #endif
1175
1176 #ifndef HAVE_VPRINTF_DECL
1177 #include "arglist.h"
1178 extern int vprintf P((const char *format, va_list ap));
1179 #endif
1180
1181 #if !defined(S_ISCHR) && defined(_S_IFCHR) && defined(_S_IFMT)
1182 #define S_ISCHR(mode) (((mode) & _S_IFMT) == _S_IFCHR)
1183 #endif
1184
1185 #if !defined(S_ISREG) && defined(_S_IFREG) && defined(_S_IFMT)
1186 #define S_ISREG(mode) (((mode) & _S_IFMT) == _S_IFREG)
1187 #endif
1188
1189 #ifndef HAVE_WAITPID
1190 #ifdef HAVE_WAIT4
1191 #define waitpid(pid,status,options) wait4(pid,status,options,0)
1192 #else
1193 extern pid_t waitpid P((pid_t pid, amwait_t *stat_loc, int options));
1194 #endif
1195 #endif
1196
1197 #ifndef STDIN_FILENO
1198 #define STDIN_FILENO 0
1199 #endif
1200
1201 #ifndef STDOUT_FILENO
1202 #define STDOUT_FILENO 1
1203 #endif
1204
1205 #ifndef STDERR_FILENO
1206 #define STDERR_FILENO 2
1207 #endif
1208
1209 /* S_ISDIR is not defined on Nextstep */
1210 #ifndef S_ISDIR
1211 #if defined(_S_IFMT) && defined(_S_IFDIR)
1212 #define S_ISDIR(mode)   (((mode) & (_S_IFMT)) == (_S_IFDIR))
1213 #else
1214 error: Don t know how to define S_ISDIR
1215 #endif
1216 #endif
1217
1218 #endif  /* !AMANDA_H */