66cff1d624c1f288cc9cfdb805ab280376f2d9b7
[debian/amanda] / common-src / amanda.h
1 /*
2  * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3  * Copyright (c) 1991-1999 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.123 2006/03/03 15:05:15 vectro 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_LIMITS_H
148 #include <limits.h>
149 #endif
150
151 #ifdef HAVE_SYS_PARAM_H
152 #  include <sys/param.h>
153 #endif
154
155 #if defined(HAVE_SYS_IPC_H) && defined(HAVE_SYS_SHM_H)
156 #  include <sys/ipc.h>
157 #  include <sys/shm.h>
158 #else
159 #  ifdef HAVE_SYS_MMAN_H
160 #    include <sys/mman.h>
161 #  endif
162 #endif
163
164 #ifdef HAVE_SYS_SELECT_H
165 #  include <sys/select.h>
166 #endif
167
168 #ifdef HAVE_SYS_STAT_H
169 #  include <sys/stat.h>
170 #endif
171
172 #ifdef HAVE_SYS_UIO_H
173 #  include <sys/uio.h>
174 #else
175 struct iovec {
176     void *iov_base;
177     int iov_len;
178 };
179 #endif
180
181 #ifdef HAVE_WAIT_H
182 #  include <wait.h>
183 #endif
184
185 #ifdef HAVE_SYS_WAIT_H
186 #  include <sys/wait.h>
187 #endif
188
189 #ifdef WAIT_USES_INT
190   typedef int amwait_t;
191 # ifndef WEXITSTATUS
192 #  define WEXITSTATUS(stat_val) (*(unsigned*)&(stat_val) >> 8)
193 # endif
194 # ifndef WTERMSIG
195 #  define WTERMSIG(stat_val) (*(unsigned*)&(stat_val) & 0x7F)
196 # endif
197 # ifndef WIFEXITED
198 #  define WIFEXITED(stat_val) ((*(unsigned*)&(stat_val) & 255) == 0)
199 # endif
200 #else
201 # ifdef WAIT_USES_UNION
202    typedef union wait amwait_t;
203 #  ifndef WEXITSTATUS
204 #  define WEXITSTATUS(stat_val) (((amwait_t*)&(stat_val))->w_retcode)
205 #  endif
206 #  ifndef WTERMSIG
207 #   define WTERMSIG(stat_val) (((amwait_t*)&(stat_val))->w_termsig)
208 #  endif
209 #  ifndef WIFEXITED
210 #   define WIFEXITED(stat_val) (WTERMSIG(stat_val) == 0)
211 #  endif
212 # else
213    typedef int amwait_t;
214 #  ifndef WEXITSTATUS
215 #   define WEXITSTATUS(stat_val) (*(unsigned*)&(stat_val) >> 8)
216 #  endif
217 #  ifndef WTERMSIG
218 #   define WTERMSIG(stat_val) (*(unsigned*)&(stat_val) & 0x7F)
219 #  endif
220 #  ifndef WIFEXITED
221 #   define WIFEXITED(stat_val) ((*(unsigned*)&(stat_val) & 255) == 0)
222 #  endif
223 # endif
224 #endif
225
226 #ifndef WIFSIGNALED
227 # define WIFSIGNALED(stat_val)  (WTERMSIG(stat_val) != 0)
228 #endif
229
230 #ifdef HAVE_UNISTD_H
231 #  include <unistd.h>
232 #endif
233
234 #include <ctype.h>
235 #include <errno.h>
236 #include <netinet/in.h>
237 #include <pwd.h>
238 #include <signal.h>
239 #include <setjmp.h>
240 #include <stdio.h>
241 #include <sys/resource.h>
242 #include <sys/socket.h>
243
244 #if !defined(CONFIGURE_TEST)
245 #  include "amanda-int.h"
246 #endif
247
248 #ifdef HAVE_ARPA_INET_H
249 #include <arpa/inet.h>
250 #endif
251
252 /*
253  * The dbmalloc package comes from:
254  *
255  *  http://www.clark.net/pub/dickey/dbmalloc/dbmalloc.tar.gz
256  *
257  * or
258  *
259  *  ftp://gatekeeper.dec.com/pub/usenet/comp.sources.misc/volume32/dbmalloc/
260  *
261  * The following functions are sprinkled through the code, but are
262  * disabled unless USE_DBMALLOC is defined:
263  *
264  *  malloc_enter(char *) -- stack trace for malloc reports
265  *  malloc_leave(char *) -- stack trace for malloc reports
266  *  malloc_mark(void *) -- mark an area as never to be free-d
267  *  malloc_chain_check(void) -- check the malloc area now
268  *  malloc_dump(int fd) -- report the malloc contents to a file descriptor
269  *  malloc_list(int fd, ulong a, ulong b) -- report memory activated since
270  *      history stamp a that is still active as of stamp b (leak check)
271  *  malloc_inuse(ulong *h) -- create history stamp h and return the amount
272  *      of memory currently in use.
273  */
274
275 #ifdef USE_DBMALLOC
276 #include "dbmalloc.h"
277 #else
278 #define malloc_enter(func)
279 #define malloc_leave(func)
280 #define malloc_mark(ptr)
281 #define malloc_chain_check()
282 #define malloc_dump(fd)
283 #define malloc_list(a,b,c)
284 #define malloc_inuse(hist)              (*(hist) = 0, 0)
285 #define dbmalloc_caller_loc(x,y)        (x)
286 #endif
287
288 #if !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC)
289 /* quick'n'dirty hack for NextStep31 */
290 #  define sa_flags sv_flags
291 #  define sa_handler sv_handler
292 #  define sa_mask sv_mask
293 #  define sigaction sigvec
294 #  define sigemptyset(mask) /* no way to clear pending signals */
295 #endif
296
297 /*
298  * Most Unixen declare errno in <errno.h>, some don't.  Some multithreaded
299  * systems have errno as a per-thread macro.  So, we have to be careful.
300  */
301 #ifndef errno
302 extern int errno;
303 #endif
304
305
306 /*
307  * Some older BSD systems don't have these FD_ macros, so if not, provide them.
308  */
309 #ifndef FD_SET
310 #  define FD_SETSIZE      (sizeof(fd_set) * 8)
311 #  define FD_SET(n, p)    (((fd_set *) (p))->fds_bits[0] |= (1 << ((n) % 32)))
312 #  define FD_CLR(n, p)    (((fd_set *) (p))->fds_bits[0] &= ~(1 << ((n) % 32)))
313 #  define FD_ISSET(n, p)  (((fd_set *) (p))->fds_bits[0] & (1 << ((n) % 32)))
314 #  define FD_ZERO(p)      memset((p), 0, sizeof(*(p)))
315 #endif
316
317 #ifndef FD_COPY
318 #  define FD_COPY(p, q)   memcpy((q), (p), sizeof(fd_set))
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  * Macros to allow code to adapt to both ANSI and class C environments.
337  *
338  * P(): prototype argument macro - removes arguments from prototypes in
339  *      class C environments
340  * stringize(): turn a bare word or words into a quoted string
341  * stringconcat(): turn two quoted strings into one
342  */
343 #if STDC_HEADERS
344 #  define P(parms)      parms
345 #  define stringize(x) #x
346 #  define stringconcat(x, y) x ## y
347 #else
348 #  define P(parms)      ()
349 #  define stringize(x) "x"
350 #  define stringconcat(x, y) x/**/y
351 #endif
352
353 /*
354  * So that we can use GNUC attributes (such as to get -Wall warnings
355  * for printf-like functions).  Only do this in gcc 2.7 or later ...
356  * it may work on earlier stuff, but why chance it.
357  */
358 #if !defined(__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < 7
359 #define __attribute__(__x)
360 #endif
361
362 /*
363  * assertions, but call error() instead of abort 
364  */
365 #ifndef ASSERTIONS
366
367 #define assert(exp) ((void)0)
368
369 #else   /* ASSERTIONS */
370
371 #define assert(exp)     do {                                            \
372     if (!(exp)) {                                                       \
373         onerror(abort);                                                 \
374         error("assert: %s false, file %s, line %d",                     \
375            stringize(exp), __FILE__, __LINE__);                         \
376     }                                                                   \
377 } while (0)
378
379 #endif  /* ASSERTIONS */
380
381 /*
382  * print debug output, else compile to nothing.
383  */
384
385 #ifdef DEBUG_CODE                                                       /* { */
386 #   define dbopen()     debug_open()
387 #   define dbreopen(a,b) debug_reopen(a,b)
388 #   define dbclose()    debug_close()
389 #   define dbprintf(p)  (debug? (debug_printf p, 0) : 0)
390 #   define dbfd()       debug_fd()
391 #   define dbfp()       debug_fp()
392 #   define dbfn()       debug_fn()
393
394 extern void debug_open P((void));
395 extern void debug_reopen P((char *file, char *notation));
396 extern void debug_close P((void));
397 extern void debug_printf P((const char *format, ...))
398     __attribute__ ((format (printf, 1, 2)));
399 extern int  debug_fd P((void));
400 extern FILE *  debug_fp P((void));
401 extern char *  debug_fn P((void));
402 extern void set_debug_prefix_pid P((pid_t));
403 extern char *debug_prefix P((char *));
404 extern char *debug_prefix_time P((char *));
405 #else                                                                   /* }{ */
406 #   define dbopen()
407 #   define dbreopen(a,b)
408 #   define dbclose()
409 #   define dbprintf(p)
410 #   define dbfd()       (-1)
411 #   define dbfp()       NULL
412 #   define dbfn()       NULL
413 #   define set_debug_prefix_pid(x)
414 #   define debug_prefix(x) get_pname()
415 #   define debug_prefix_time(x) get_pname()
416 #endif                                                                  /* } */
417
418 /* amanda #days calculation, with roundoff */
419
420 #define SECS_PER_DAY    (24*60*60)
421 #define days_diff(a, b) (((b) - (a) + SECS_PER_DAY/2) / SECS_PER_DAY)
422
423 /* Global constants.  */
424 #ifndef AMANDA_SERVICE_NAME
425 #define AMANDA_SERVICE_NAME "amanda"
426 #endif
427 #ifndef KAMANDA_SERVICE_NAME
428 #define KAMANDA_SERVICE_NAME "kamanda"
429 #endif
430 #ifndef SERVICE_SUFFIX
431 #define SERVICE_SUFFIX ""
432 #endif
433 #ifndef AMANDA_SERVICE_DEFAULT
434 #define AMANDA_SERVICE_DEFAULT  10080
435 #endif
436 #ifndef KAMANDA_SERVICE_DEFAULT
437 #define KAMANDA_SERVICE_DEFAULT 10081
438 #endif
439
440 #define am_round(v,u)   ((((v) + (u) - 1) / (u)) * (u))
441 #define am_floor(v,u)   (((v) / (u)) * (u))
442
443 /* Holding disk block size.  Do not even think about changint this!  :-) */
444 #define DISK_BLOCK_KB           32
445 #define DISK_BLOCK_BYTES        (DISK_BLOCK_KB * 1024)
446
447 /* Maximum size of a tape block */
448 /* MAX_TAPE_BLOCK_KB is defined in config.h */
449 /* by configure --with-maxtapeblocksize     */
450 #define MAX_TAPE_BLOCK_BYTES (MAX_TAPE_BLOCK_KB*1024)
451
452 /* Maximum length of tape label, plus one for null-terminator. */
453 #define MAX_TAPE_LABEL_LEN (10240)
454 #define MAX_TAPE_LABEL_BUF (MAX_TAPE_LABEL_LEN+1)
455
456 /* Define miscellaneous amanda functions.  */
457 #define ERR_INTERACTIVE 1
458 #define ERR_SYSLOG      2
459 #define ERR_AMANDALOG   4
460
461 extern void   set_logerror P((void (*f)(char *)));
462 extern void   set_pname P((char *pname));
463 extern char  *get_pname P((void));
464 extern int    erroutput_type;
465 extern void   error     P((const char *format, ...))
466     __attribute__ ((format (printf, 1, 2), noreturn));
467 extern void   errordump P((const char *format, ...))
468     __attribute__ ((format (printf, 1, 2), noreturn));
469 extern int    onerror         P((void (*errf)(void)));
470
471 extern void *debug_alloc P((const char *c, int l, size_t size));
472 extern void *debug_newalloc P((const char *c, int l, void *old, size_t size));
473 extern char *debug_stralloc P((const char *c, int l, const char *str));
474 extern char *debug_newstralloc P((const char *c, int l, char *oldstr,
475     const char *newstr));
476 extern const char *debug_caller_loc P((const char *file, int line));
477 extern int debug_alloc_push P((char *file, int line));
478 extern void debug_alloc_pop P((void));
479
480 #define alloc(s)                debug_alloc(__FILE__, __LINE__, (s))
481 #define newalloc(p,s)           debug_newalloc(__FILE__, __LINE__, (p), (s))
482 #define stralloc(s)             debug_stralloc(__FILE__, __LINE__, (s))
483 #define newstralloc(p,s)        debug_newstralloc(__FILE__, __LINE__, (p), (s))
484
485 /*
486  * Voodoo time.  We want to be able to mark these calls with the source
487  * line, but CPP does not handle variable argument lists so we cannot
488  * do what we did above (e.g. for alloc()).
489  *
490  * What we do is call a function to save the file and line number
491  * and have it return "false".  That triggers the "?" operator to
492  * the right side of the ":" which is a call to the debug version of
493  * vstralloc/newvstralloc but without parameters.  The compiler gets
494  * those from the next input tokens:
495  *
496  *  xx = vstralloc(a,b,NULL);
497  *
498  * becomes:
499  *
500  *  xx = debug_alloc_push(__FILE__,__LINE__)?0:debug_vstralloc(a,b,NULL);
501  *
502  * This works as long as vstralloc/newvstralloc are not part of anything
503  * very complicated.  Assignment is fine, as is an argument to another
504  * function (but you should not do that because it creates a memory leak).
505  * This will not work in arithmetic or comparison, but it is unlikely
506  * they are used like that.
507  *
508  *  xx = vstralloc(a,b,NULL);                   OK
509  *  return vstralloc(j,k,NULL);                 OK
510  *  sub(a, vstralloc(g,h,NULL), z);             OK, but a leak
511  *  if(vstralloc(s,t,NULL) == NULL) { ...       NO, but unneeded
512  *  xx = vstralloc(x,y,NULL) + 13;              NO, but why do it?
513  */
514
515 #define vstralloc debug_alloc_push(__FILE__,__LINE__)?0:debug_vstralloc
516 #define newvstralloc debug_alloc_push(__FILE__,__LINE__)?0:debug_newvstralloc
517
518 extern char  *debug_vstralloc       P((const char *str, ...));
519 extern char  *debug_newvstralloc    P((char *oldstr, const char *newstr, ...));
520
521 #define stralloc2(s1,s2)      vstralloc((s1),(s2),NULL)
522 #define newstralloc2(p,s1,s2) newvstralloc((p),(s1),(s2),NULL)
523
524 /* Usage: vstrextend(foo, "bar, "baz", NULL). Extends the existing 
525  * string, or allocates a brand new one. */
526 extern char *vstrextend P((char **oldstr, ...));
527
528 extern char  *debug_agets   P((const char *c, int l, FILE *file));
529 extern char  *debug_areads  P((const char *c, int l, int fd));
530 #define agets(f)              debug_agets(__FILE__,__LINE__,(f))
531 #define areads(f)             debug_areads(__FILE__,__LINE__,(f))
532
533 extern int debug_amtable_alloc P((const char *file,
534                                   int line,
535                                   void **table,
536                                   int *current,
537                                   size_t elsize,
538                                   int count,
539                                   int bump,
540                                   void (*init_func)(void *)));
541 #define amtable_alloc(t,c,s,n,b,f) debug_amtable_alloc(__FILE__,      \
542                                                      __LINE__,        \
543                                                      (t),             \
544                                                      (c),             \
545                                                      (s),             \
546                                                      (n),             \
547                                                      (b),             \
548                                                      (f))
549
550 extern void amtable_free      P((void **table, int *current));
551
552 extern uid_t  client_uid;
553 extern gid_t  client_gid;
554 extern void   safe_fd         P((int fd_start, int fd_count));
555 extern void   safe_cd         P((void));
556 extern void   save_core       P((void));
557 extern char **safe_env        P((void));
558 extern char  *validate_regexp P((char *regex));
559 extern char  *validate_glob   P((char *glob));
560 extern char  *clean_regex     P((char *regex));
561 extern int    match           P((char *regex, char *str));
562 extern int    match_glob      P((char *glob, char *str));
563 extern char  *glob_to_regex   P((char *glob));
564 extern int    match_tar       P((char *glob, char *str));
565 extern char  *tar_to_regex    P((char *glob));
566 extern int    match_host      P((char *glob, char *host));
567 extern int    match_disk      P((char *glob, char *disk));
568 extern int    match_datestamp P((char *dateexp, char *datestamp));
569 extern int    match_level     P((char *levelexp, char *level));
570 extern time_t unctime         P((char *timestr));
571 extern ssize_t  areads_dataready  P((int fd));
572 extern void     areads_relbuf     P((int fd));
573
574 /*
575  * amfree(ptr) -- if allocated, release space and set ptr to NULL.
576  *
577  * In general, this should be called instead of just free(), unless
578  * the very next source line sets the pointer to a new value.
579  */
580
581 #define amfree(ptr) do {                                                \
582     if(ptr) {                                                           \
583         int e__errno = errno;                                           \
584         free(ptr);                                                      \
585         (ptr) = NULL;                                                   \
586         errno = e__errno;                                               \
587     }                                                                   \
588 } while(0)
589
590 #define strappend(s1,s2) do {                                           \
591     char *t_t_t = (s1) ? stralloc2((s1),(s2)) : stralloc((s2));         \
592     amfree((s1));                                                       \
593     (s1) = t_t_t;                                                       \
594 } while(0)
595
596 /*
597  * "Safe" close macros.  Close the object then set it to a value that
598  * will cause an error if referenced.
599  *
600  * aclose(fd) -- close a file descriptor and set it to -1.
601  * afclose(f) -- close a stdio file and set it to NULL.
602  * apclose(p) -- close a stdio pipe file and set it to NULL.
603  *
604  * Note: be careful not to do the following:
605  *
606  *  for(fd = low; fd < high; fd++) {
607  *      aclose(fd);
608  *  }
609  *
610  * Since aclose() sets the argument to -1, this will loop forever.
611  * Just copy fd to a temp variable and use that with aclose().
612  *
613  * Aclose() interacts with areads() to inform it to release any buffer
614  * it has outstanding on the file descriptor.
615  */
616
617 #define aclose(fd) do {                                                 \
618     if((fd) >= 0) {                                                     \
619         close(fd);                                                      \
620         areads_relbuf(fd);                                              \
621     }                                                                   \
622     (fd) = -1;                                                          \
623 } while(0)
624
625 #define afclose(f) do {                                                 \
626     if((f) != NULL) {                                                   \
627         fclose(f);                                                      \
628     }                                                                   \
629     (f) = NULL;                                                         \
630 } while(0)
631
632 #define apclose(p) do {                                                 \
633     if((p) != NULL) {                                                   \
634         pclose(p);                                                      \
635     }                                                                   \
636     (p) = NULL;                                                         \
637 } while(0)
638
639 /*
640  * Return the number of elements in an array.
641  */
642 #define am_countof(a)   (sizeof(a) / sizeof((a)[0]))
643
644 /*
645  * min/max.  Don't do something like
646  *
647  *    x = min(y++, z);
648  *
649  * because the increment will be duplicated.
650  */
651 #undef min
652 #undef max
653 #define min(a, b)       ((a) < (b) ? (a) : (b))
654 #define max(a, b)       ((a) > (b) ? (a) : (b))
655
656 /*
657  * Utility bitmask manipulation macros.
658  */
659 #define SET(t, f)       ((t) |= (f))
660 #define CLR(t, f)       ((t) &= ~((unsigned)(f)))
661 #define ISSET(t, f)     ((t) & (f))
662
663 /*
664  * Utility string macros.  All assume a variable holds the current
665  * character and the string pointer points to the next character to
666  * be processed.  Typical setup is:
667  *
668  *  s = buffer;
669  *  ch = *s++;
670  *  skip_whitespace(s, ch);
671  *  ...
672  *
673  * If you advance the pointer "by hand" to skip over something, do
674  * it like this:
675  *
676  *  s += some_amount;
677  *  ch = s[-1];
678  *
679  * Note that ch has the character at the end of the just skipped field.
680  * It is often useful to terminate a string, make a copy, then restore
681  * the input like this:
682  *
683  *  skip_whitespace(s, ch);
684  *  fp = s-1;                   ## save the start
685  *  skip_nonwhitespace(s, ch);  ## find the end
686  *  p[-1] = '\0';               ## temporary terminate
687  *  field = stralloc(fp);       ## make a copy
688  *  p[-1] = ch;                 ## restore the input
689  *
690  * The scanning macros are:
691  *
692  *  skip_whitespace (ptr, var)
693  *    -- skip whitespace, but stops at a newline
694  *  skip_non_whitespace (ptr, var)
695  *    -- skip non whitespace
696  *  skip_non_whitespace_cs (ptr, var)
697  *    -- skip non whitespace, stop at comment
698  *  skip_integer (ptr, var)
699  *    -- skip an integer field
700  *  skip_line (ptr, var)
701  *    -- skip just past the next newline
702  *
703  * where:
704  *
705  *  ptr -- string pointer
706  *  var -- current character
707  *
708  * These macros copy a non-whitespace field to a new buffer, and should
709  * only be used if dynamic allocation is impossible (fixed size buffers
710  * are asking for trouble):
711  *
712  *  copy_string (ptr, var, field, len, fldptr)
713  *    -- copy a non-whitespace field
714  *  copy_string_cs (ptr, var, field, len, fldptr)
715  *    -- copy a non-whitespace field, stop at comment
716  *
717  * where:
718  *
719  *  ptr -- string pointer
720  *  var -- current character
721  *  field -- area to copy to
722  *  len -- length of area (needs room for null byte)
723  *  fldptr -- work pointer used in move
724  *            if NULL on exit, the field was too small for the input
725  */
726
727 #define STR_SIZE        4096            /* a generic string buffer size */
728 #define NUM_STR_SIZE    32              /* a generic number buffer size */
729
730 #define skip_whitespace(ptr,c) do {                                     \
731     while((c) != '\n' && isspace(c)) (c) = *(ptr)++;                    \
732 } while(0)
733
734 #define skip_non_whitespace(ptr,c) do {                                 \
735     while((c) != '\0' && !isspace(c)) (c) = *(ptr)++;                   \
736 } while(0)
737
738 #define skip_non_whitespace_cs(ptr,c) do {                              \
739     while((c) != '\0' && (c) != '#' && !isspace(c)) (c) = *(ptr)++;     \
740 } while(0)
741
742 #define skip_non_integer(ptr,c) do {                                    \
743     while((c) != '\0' && !isdigit(c)) (c) = *(ptr)++;                   \
744 } while(0)
745
746 #define skip_integer(ptr,c) do {                                        \
747     if((c) == '+' || (c) == '-') (c) = *(ptr)++;                        \
748     while(isdigit(c)) (c) = *(ptr)++;                                   \
749 } while(0)
750
751 #define skip_line(ptr,c) do {                                           \
752     while((c) && (c) != '\n') (c) = *(ptr)++;                           \
753     if(c) (c) = *(ptr)++;                                               \
754 } while(0)
755
756 #define copy_string(ptr,c,f,l,fp) do {                                  \
757     (fp) = (f);                                                         \
758     while((c) != '\0' && !isspace(c)) {                                 \
759         if((fp) >= (f) + (l) - 1) {                                     \
760             *(fp) = '\0';                                               \
761             (fp) = NULL;                                                \
762             break;                                                      \
763         }                                                               \
764         *(fp)++ = (c);                                                  \
765         (c) = *(ptr)++;                                                 \
766     }                                                                   \
767     if(fp) *fp = '\0';                                                  \
768 } while(0)
769
770 #define copy_string_cs(ptr,c,f,l,fp) do {                               \
771     (fp) = (f);                                                         \
772     while((c) != '\0' && (c) != '#' && !isspace(c)) {                   \
773         if((fp) >= (f) + (l) - 1) {                                     \
774             *(fp) = '\0';                                               \
775             (fp) = NULL;                                                \
776             break;                                                      \
777         }                                                               \
778         *(fp)++ = (c);                                                  \
779         (c) = *(ptr)++;                                                 \
780     }                                                                   \
781     if(fp) *fp = '\0';                                                  \
782 } while(0)
783
784 #define is_dot_or_dotdot(s)                                             \
785     ((s)[0] == '.'                                                      \
786      && ((s)[1] == '\0'                                                 \
787          || ((s)[1] == '.' && (s)[2] == '\0')))
788
789 /* from amflock.c */
790 extern int    amflock   P((int fd, char *resource));
791 extern int    amroflock P((int fd, char *resource));
792 extern int    amfunlock P((int fd, char *resource));
793
794 /* from file.c */
795 extern int    mkpdir    P((char *file, int mode, uid_t uid, gid_t gid));
796 extern int    rmpdir    P((char *file, char *topdir));
797 extern char  *sanitise_filename P((char *inp));
798
799 /* from bsd-security.c */
800 extern char  *check_user_ruserok     P((const char *host,
801                                         struct passwd *pwd,
802                                         const char *user));
803 extern char  *check_user_amandahosts P((const char *host,
804                                         struct passwd *pwd,
805                                         const char *user));
806
807 extern int debug;
808 extern int check_security P((struct sockaddr_in *, char *, unsigned long,
809                              char **));
810
811
812 /*
813  * Handle functions which are not always declared on all systems.  This
814  * stops gcc -Wall and lint from complaining.
815  */
816
817 /* AIX #defines accept, and provides a prototype for the alternate name */
818 #if !defined(HAVE_ACCEPT_DECL) && !defined(accept)
819 extern int accept P((int s, struct sockaddr *addr, int *addrlen));
820 #endif
821
822 #ifndef HAVE_ATOF_DECL
823 extern double atof P((const char *ptr));
824 #endif
825
826 #ifndef HAVE_BCOPY
827 # define bcopy(from,to,n) ((void)memmove((to), (from), (n)))
828 #else
829 # ifndef HAVE_BCOPY_DECL
830 extern void bcopy P((const void *s1, void *s2, size_t n));
831 # endif
832 #endif
833
834 #ifndef HAVE_BIND_DECL
835 extern int bind P((int s, const struct sockaddr *name, int namelen));
836 #endif
837
838 #ifndef HAVE_BZERO
839 #define bzero(s,n) ((void)memset((s),0,(n)))
840 #else
841 # ifndef HAVE_BZERO_DECL
842 extern void bzero P((void *s, size_t n));
843 # endif
844 #endif
845
846 #ifndef HAVE_CLOSELOG_DECL
847 extern void closelog P((void));
848 #endif
849
850 #ifndef HAVE_CONNECT_DECL
851 extern int connect P((int s, struct sockaddr *name, int namelen));
852 #endif
853
854 #if !defined(TEXTDB) && !defined(HAVE_DBM_OPEN_DECL)
855 #undef   DBM_INSERT
856 #define  DBM_INSERT  0
857
858 #undef   DBM_REPLACE
859 #define  DBM_REPLACE 1
860
861     typedef struct {
862         int dummy[10];
863     } DBM;
864
865 #ifndef HAVE_STRUCT_DATUM
866     typedef struct {
867         char    *dptr;
868         int     dsize;
869     } datum;
870 #endif
871
872     extern DBM   *dbm_open     P((char *file, int flags, int mode));
873     extern void   dbm_close    P((DBM *db));
874     extern datum  dbm_fetch    P((DBM *db, datum key));
875     extern datum  dbm_firstkey P((DBM *db));
876     extern datum  dbm_nextkey  P((DBM *db));
877     extern int    dbm_delete   P((DBM *db, datum key));
878     extern int    dbm_store    P((DBM *db, datum key, datum content, int flg));
879 #endif
880
881 #ifndef HAVE_FCLOSE_DECL
882 extern int fclose P((FILE *stream));
883 #endif
884
885 #ifndef HAVE_FFLUSH_DECL
886 extern int fflush P((FILE *stream));
887 #endif
888
889 #ifndef HAVE_FPRINTF_DECL
890 extern int fprintf P((FILE *stream, const char *format, ...));
891 #endif
892
893 #ifndef HAVE_FPUTC_DECL
894 extern int fputc P((int c, FILE *stream));
895 #endif
896
897 #ifndef HAVE_FPUTS_DECL
898 extern int fputs P((const char *s, FILE *stream));
899 #endif
900
901 #ifndef HAVE_FREAD_DECL
902 extern size_t fread P((void *ptr, size_t size, size_t nitems, FILE *stream));
903 #endif
904
905 #ifndef HAVE_FSEEK_DECL
906 extern int fseek P((FILE *stream, long offset, int ptrname));
907 #endif
908
909 #ifndef HAVE_FWRITE_DECL
910 extern size_t fwrite P((const void *ptr, size_t size, size_t nitems,
911                         FILE *stream));
912 #endif
913
914 #ifndef HAVE_GETHOSTNAME_DECL
915 extern int gethostname P((char *name, int namelen));
916 #endif
917
918 #ifndef HAVE_GETOPT_DECL
919 extern char *optarg;
920 extern int getopt P((int argc, char * const *argv, const char *optstring));
921 #endif
922
923 /* AIX #defines getpeername, and provides a prototype for the alternate name */
924 #if !defined(HAVE_GETPEERNAME_DECL) && !defined(getpeername)
925 extern int getpeername P((int s, struct sockaddr *name, int *namelen));
926 #endif
927
928 /* AIX #defines getsockname, and provides a prototype for the alternate name */
929 #if !defined(HAVE_GETSOCKNAME_DECL) && !defined(getsockname)
930 extern int getsockname P((int s, struct sockaddr *name, int *namelen));
931 #endif
932
933 #ifndef HAVE_GETSOCKOPT_DECL
934 extern int getsockopt P((int s, int level, int optname, char *optval,
935                          int *optlen));
936 #endif
937
938 #ifndef HAVE_GETTIMEOFDAY_DECL
939 # ifdef HAVE_TWO_ARG_GETTIMEOFDAY
940 extern int gettimeofday P((struct timeval *tp, struct timezone *tzp));
941 # else
942 extern int gettimeofday P((struct timeval *tp));
943 # endif
944 #endif
945
946 #ifndef HAVE_INITGROUPS
947 # define initgroups(name,basegid) 0
948 #else
949 # ifndef HAVE_INITGROUPS_DECL
950 extern int initgroups P((const char *name, gid_t basegid));
951 # endif
952 #endif
953
954 #ifndef HAVE_IOCTL_DECL
955 extern int ioctl P((int fildes, int request, ...));
956 #endif
957
958 #ifndef HAVE_LISTEN_DECL
959 extern int listen P((int s, int backlog));
960 #endif
961
962 #ifndef HAVE_LSTAT_DECL
963 extern int lstat P((const char *path, struct stat *buf));
964 #endif
965
966 #ifndef HAVE_MALLOC_DECL
967 extern void *malloc P((size_t size));
968 #endif
969
970 #ifndef HAVE_MEMMOVE_DECL
971 #ifdef HAVE_MEMMOVE
972 extern void *memmove P((void *to, const void *from, size_t n));
973 #else
974 extern char *memmove P((char *to, /*const*/ char *from, size_t n));
975 #endif
976 #endif
977
978 #ifndef HAVE_MEMSET_DECL
979 extern void *memset P((void *s, int c, size_t n));
980 #endif
981
982 #ifndef HAVE_MKTEMP_DECL
983 extern char *mktemp P((char *template));
984 #endif
985
986 #ifndef HAVE_MKSTEMP_DECL
987 extern int mkstemp P((char *template));
988 #endif
989
990 #ifndef HAVE_MKTIME_DECL
991 extern time_t mktime P((struct tm *timeptr));
992 #endif
993
994 #ifndef HAVE_OPENLOG_DECL
995 #ifdef LOG_AUTH
996 extern void openlog P((const char *ident, int logopt, int facility));
997 #else
998 extern void openlog P((const char *ident, int logopt));
999 #endif
1000 #endif
1001
1002 #ifndef HAVE_PCLOSE_DECL
1003 extern int pclose P((FILE *stream));
1004 #endif
1005
1006 #ifndef HAVE_PERROR_DECL
1007 extern void perror P((const char *s));
1008 #endif
1009
1010 #ifndef HAVE_PRINTF_DECL
1011 extern int printf P((const char *format, ...));
1012 #endif
1013
1014 #ifndef HAVE_PUTS_DECL
1015 extern int puts P((const char *s));
1016 #endif
1017
1018 #ifndef HAVE_REALLOC_DECL
1019 extern void *realloc P((void *ptr, size_t size));
1020 #endif
1021
1022 /* AIX #defines recvfrom, and provides a prototype for the alternate name */
1023 #if !defined(HAVE_RECVFROM_DECL) && !defined(recvfrom)
1024 extern int recvfrom P((int s, char *buf, int len, int flags,
1025                        struct sockaddr *from, int *fromlen));
1026 #endif
1027
1028 #ifndef HAVE_REMOVE_DECL
1029 extern int remove P((const char *path));
1030 #endif
1031
1032 #ifndef HAVE_RENAME_DECL
1033 extern int rename P((const char *old, const char *new));
1034 #endif
1035
1036 #ifndef HAVE_REWIND_DECL
1037 extern void rewind P((FILE *stream));
1038 #endif
1039
1040 #ifndef HAVE_RUSEROK_DECL
1041 extern int ruserok P((const char *rhost, int suser,
1042                       const char *ruser, const char *luser));
1043 #endif
1044
1045 #ifndef HAVE_SELECT_DECL
1046 extern int select P((int nfds,
1047                      SELECT_ARG_TYPE *readfds,
1048                      SELECT_ARG_TYPE *writefds,
1049                      SELECT_ARG_TYPE *exceptfds,
1050                      struct timeval *timeout));
1051 #endif
1052
1053 #ifndef HAVE_SENDTO_DECL
1054 extern int sendto P((int s, const char *msg, int len, int flags,
1055                      const struct sockaddr *to, int tolen));
1056 #endif
1057
1058 #ifdef HAVE_SETRESGID
1059 #define setegid(x)      setresgid(-1,(x),-1)
1060 #ifndef HAVE_SETRESGID_DECL
1061 extern int setresgid P((gid_t rgid, gid_t egid, gid_t sgid));
1062 #endif
1063 #else
1064 #ifndef HAVE_SETEGID_DECL
1065 extern int setegid P((gid_t egid));
1066 #endif
1067 #endif
1068
1069 #ifdef HAVE_SETRESUID
1070 #define seteuid(x)      setresuid(-1,(x),-1)
1071 #ifndef HAVE_SETRESUID_DECL
1072 extern int setresuid P((uid_t ruid, uid_t euid, uid_t suid));
1073 #endif
1074 #else
1075 #ifndef HAVE_SETEUID_DECL
1076 extern int seteuid P((uid_t euid));
1077 #endif
1078 #endif
1079
1080 #ifndef HAVE_SETPGID_DECL
1081 #ifdef HAVE_SETPGID
1082 extern int setpgid P((int pid, int pgid));
1083 #endif
1084 #endif
1085
1086 #ifndef HAVE_SETPGRP_DECL
1087 #ifdef SETPGRP_VOID
1088 extern pid_t setpgrp P((void));
1089 #else
1090 extern pid_t setpgrp P((int pgrp, int pid));
1091 #endif
1092 #endif
1093
1094 #ifndef HAVE_SETSOCKOPT_DECL
1095 extern int setsockopt P((int s, int level, int optname,
1096                          const char *optval, int optlen));
1097 #endif
1098
1099 #ifdef HAVE_SHMGET
1100 #ifndef HAVE_SHMAT_DECL
1101 extern void *shmat P((int shmid, const SHM_ARG_TYPE *shmaddr, int shmflg));
1102 #endif
1103
1104 #ifndef HAVE_SHMCTL_DECL
1105 extern int shmctl P((int shmid, int cmd, struct shmid_ds *buf));
1106 #endif
1107
1108 #ifndef HAVE_SHMDT_DECL
1109 extern int shmdt P((SHM_ARG_TYPE *shaddr));
1110 #endif
1111
1112 #ifndef HAVE_SHMGET_DECL
1113 extern int shmget P((key_t key, size_t size, int shmflg));
1114 #endif
1115 #endif
1116
1117 #ifndef HAVE_SNPRINTF_DECL
1118 #include "arglist.h"
1119 int snprintf  P((char *buf, size_t len, const char *format,...))
1120                     __attribute__((format(printf,3,4)));
1121 #endif
1122 #ifndef HAVE_VSNPRINTF_DECL
1123 #include "arglist.h"
1124 int vsnprintf P((char *buf, size_t len, const char *format, va_list ap));
1125 #endif
1126
1127 #ifndef HAVE_SOCKET_DECL
1128 extern int socket P((int domain, int type, int protocol));
1129 #endif
1130
1131 #ifndef HAVE_SOCKETPAIR_DECL
1132 extern int socketpair P((int domain, int type, int protocol, int sv[2]));
1133 #endif
1134
1135 #ifndef HAVE_SSCANF_DECL
1136 extern int sscanf P((const char *s, const char *format, ...));
1137 #endif
1138
1139 #ifndef HAVE_STRCASECMP_DECL
1140 extern int strcasecmp P((const char *s1, const char *s2));
1141 #endif
1142
1143 #ifndef HAVE_STRERROR_DECL
1144 extern char *strerror P((int errnum));
1145 #endif
1146
1147 #ifndef HAVE_STRFTIME_DECL
1148 extern size_t strftime P((char *s, size_t maxsize, const char *format,
1149                           const struct tm *timeptr));
1150 #endif
1151
1152 #ifndef HAVE_STRNCASECMP_DECL
1153 extern int strncasecmp P((const char *s1, const char *s2, int n));
1154 #endif
1155
1156 #ifndef HAVE_SYSLOG_DECL
1157 extern void syslog P((int priority, const char *logstring, ...))
1158     __attribute__ ((format (printf, 2, 3)));
1159 #endif
1160
1161 #ifndef HAVE_SYSTEM_DECL
1162 extern int system P((const char *string));
1163 #endif
1164
1165 #ifndef HAVE_TIME_DECL
1166 extern time_t time P((time_t *tloc));
1167 #endif
1168
1169 #ifndef HAVE_TOLOWER_DECL
1170 extern int tolower P((int c));
1171 #endif
1172
1173 #ifndef HAVE_TOUPPER_DECL
1174 extern int toupper P((int c));
1175 #endif
1176
1177 #ifndef HAVE_UNGETC_DECL
1178 extern int ungetc P((int c, FILE *stream));
1179 #endif
1180
1181 #ifndef HAVE_VFPRINTF_DECL
1182 #include "arglist.h"
1183 extern int vfprintf P((FILE *stream, const char *format, va_list ap));
1184 #endif
1185
1186 #ifndef HAVE_VPRINTF_DECL
1187 #include "arglist.h"
1188 extern int vprintf P((const char *format, va_list ap));
1189 #endif
1190
1191 #if !defined(S_ISCHR) && defined(_S_IFCHR) && defined(_S_IFMT)
1192 #define S_ISCHR(mode) (((mode) & _S_IFMT) == _S_IFCHR)
1193 #endif
1194
1195 #if !defined(S_ISREG) && defined(_S_IFREG) && defined(_S_IFMT)
1196 #define S_ISREG(mode) (((mode) & _S_IFMT) == _S_IFREG)
1197 #endif
1198
1199 #ifndef HAVE_WAITPID
1200 #ifdef HAVE_WAIT4
1201 #define waitpid(pid,status,options) wait4(pid,status,options,0)
1202 #else
1203 extern pid_t waitpid P((pid_t pid, amwait_t *stat_loc, int options));
1204 #endif
1205 #endif
1206
1207 #ifndef HAVE_WRITEV_DECL
1208 extern ssize_t writev P((int fd, const struct iovec *iov, int iovcnt));
1209 #endif
1210
1211 #ifndef STDIN_FILENO
1212 #define STDIN_FILENO 0
1213 #endif
1214
1215 #ifndef STDOUT_FILENO
1216 #define STDOUT_FILENO 1
1217 #endif
1218
1219 #ifndef STDERR_FILENO
1220 #define STDERR_FILENO 2
1221 #endif
1222
1223 /* S_ISDIR is not defined on Nextstep */
1224 #ifndef S_ISDIR
1225 #if defined(_S_IFMT) && defined(_S_IFDIR)
1226 #define S_ISDIR(mode)   (((mode) & (_S_IFMT)) == (_S_IFDIR))
1227 #else
1228 error: Don t know how to define S_ISDIR
1229 #endif
1230 #endif
1231
1232 #if SIZEOF_OFF_T > SIZEOF_LONG
1233 #  define        OFF_T_FMT       LL_FMT
1234 #else
1235 #  define        OFF_T_FMT       "%ld"
1236 #endif
1237
1238 #if SIZEOF_LONG == 8
1239    typedef long am64_t;
1240 #  ifdef LONG_MAX
1241 #    define AM64_MAX LONG_MAX
1242 #  else
1243 #    define AM64_MAX 9223372036854775807L
1244 #  endif
1245 #  ifdef LONG_MIN
1246 #    define AM64_MIN LONG_MIN
1247 #  else
1248 #    define AM64_MIN -9223372036854775807L -1L
1249 #  endif
1250 #  define AM64_FMT "%ld"
1251 #else
1252 #if SIZEOF_LONG_LONG == 8
1253    typedef long long am64_t;
1254 #  ifdef LONG_LONG_MAX
1255 #    define AM64_MAX LONG_LONG_MAX
1256 #  else
1257 #    define AM64_MAX 9223372036854775807LL
1258 #  endif
1259 #  ifdef LONG_LONG_MIN
1260 #    define AM64_MIN LONG_LONG_MIN
1261 #  else
1262 #    define AM64_MIN -9223372036854775807LL -1LL
1263 #  endif
1264 #  define AM64_FMT LL_FMT
1265 #else
1266 #if SIZEOF_INTMAX_T == 8
1267    typedef intmax_t am64_t;
1268 #  ifdef INTMAX_MAX
1269 #    define AM64_MAX INTMAX_MAX
1270 #  else
1271 #    define AM64_MAX 9223372036854775807LL
1272 #  endif
1273 #  ifdef INTMAX_MIN
1274 #    define AM64_MIN INTMAX_MIN
1275 #  else
1276 #    define AM64_MIN -9223372036854775807LL -1LL
1277 #  endif
1278 #  define AM64_FMT LL_FMT
1279 #else
1280 #if SIZEOF_OFF_T == 8
1281    typedef off_t am64_t;
1282 #  ifdef OFF_MAX
1283 #    define AM64_MAX OFF_MAX
1284 #  else
1285 #    define AM64_MAX 9223372036854775807LL
1286 #  endif
1287 #  ifdef OFF_MIN
1288 #    define AM64_MIN OFF_MIN
1289 #  else
1290 #    define AM64_MIN -9223372036854775807LL -1LL
1291 #  endif
1292 #  define AM64_FMT OFF_T_FMT
1293 #else  /* no 64 bits tyupe found, use long. */
1294    typedef long am64_t;
1295 #  ifdef LONG_MAX
1296 #    define AM64_MAX LONG_MAX
1297 #  else
1298 #    define AM64_MAX 2147483647
1299 #  endif
1300 #  ifdef LONG_MIN
1301 #    define AM64_MIN LONG_MIN
1302 #  else
1303 #    define AM64_MIN -2147483647 -1
1304 #  endif
1305 #  define AM64_FMT "%ld"
1306 #endif
1307 #endif
1308 #endif
1309 #endif
1310
1311 #endif  /* !AMANDA_H */