ec0653316e75bd3f0c0489bc906c3fcab8c2202b
[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.131 2006/07/25 18:27:56 martinea 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 /* use a relative path here to avoid conflicting with Perl's config.h. */
36 #include "../config/config.h"
37 #endif
38
39 #include <glib.h>
40 #include <glib/gprintf.h>
41
42 #include "amflock.h"
43
44 /*
45  * Force large file source even if configure guesses wrong.
46  */
47 #ifndef _LARGE_FILE_SOURCE
48 #define _LARGE_FILES 1
49 #endif
50
51 #ifndef _LARGEFILE64_SOURCE
52 #define _LARGEFILE64_SOURCE 1
53 #endif
54
55 #ifndef  _FILE_OFFSET_BITS
56 #define _FILE_OFFSET_BITS 64
57 #endif
58
59 #ifdef HAVE_SYS_TYPES_H
60 #  include <sys/types.h>
61 #endif
62
63 /* gnulib creates this header locally if the system doesn't provide it */
64 #include <stdint.h>
65
66 /*
67  * I would prefer that each Amanda module include only those system headers
68  * that are locally needed, but on most Unixes the system header files are not
69  * protected against multiple inclusion, so this can lead to problems.
70  *
71  * Also, some systems put key files in different places, so by including 
72  * everything here the rest of the system is isolated from such things.
73  */
74
75 /* from the autoconf documentation */
76 #ifdef HAVE_DIRENT_H
77 #  include <dirent.h>
78 #  define NAMLEN(dirent) strlen((dirent)->d_name)
79 #else
80 #  define dirent direct
81 #  define NAMLEN(dirent) (dirent)->d_namlen
82 #  if HAVE_SYS_NDIR_H
83 #    include <sys/ndir.h>
84 #  endif
85 #  if HAVE_SYS_DIR_H
86 #    include <sys/dir.h>
87 #  endif
88 #  if HAVE_NDIR_H
89 #    include <ndir.h>
90 #  endif
91 #endif
92
93 #ifdef ENABLE_NLS
94 #  include <libintl.h>
95 #  include <locale.h>
96 #  define  plural(String1, String2, Count)                              \
97                 (((Count) == 1) ? (String1) : (String2))
98 #else
99 #  define plural(String1, String2, Count)                               \
100                 (((Count) == 1) ? (String1) : (String2))
101 #  define setlocale(Which, Locale)
102 #  define textdomain(Domain)
103 #  define bindtextdomain(Package, Directory)
104 #  define gettext(String)                       String
105 #  define dgettext(Domain, String)              String
106 #  define dcgettext(Domain, String, Catagory)   String
107 #  define ngettext(String1, String2, Count)                             \
108                 plural((String1), (String2), (Count))
109 #  define dngettext(Domain, String1, String2, Count)                    \
110                 plural((String1), (String2), (Count))
111 #  define dcngettext(Domain, String1, String2, Count, Catagory)         \
112                 plural((String1), (String2), (Count))
113 #endif
114 #define T_(String)                      String
115 #ifndef SWIG /* TODO: make this go away */
116 #define _(String)                       dgettext("amanda", (String))
117 #endif
118
119 #ifdef HAVE_FCNTL_H
120 #  include <fcntl.h>
121 #endif
122
123 #ifdef HAVE_GRP_H
124 #  include <grp.h>
125 #endif
126
127 #if defined(USE_DB_H)
128 #  include <db.h>
129 #else
130 #if defined(USE_DBM_H)
131 #  include <dbm.h>
132 #else
133 #if defined(USE_GDBM_H)
134 #  include <gdbm.h>
135 #else
136 #if defined(USE_NDBM_H)
137 #  include <ndbm.h>
138 #endif
139 #endif
140 #endif
141 #endif
142
143 #ifdef HAVE_NETDB_H
144 #  include <netdb.h>
145 #endif
146
147 #ifdef TIME_WITH_SYS_TIME
148 #  include <sys/time.h>
149 #  include <time.h>
150 #else
151 #  ifdef HAVE_SYS_TIME_H
152 #    include <sys/time.h>
153 #  else
154 #    include <time.h>
155 #  endif
156 #endif
157
158 #ifdef HAVE_LIBC_H
159 #  include <libc.h>
160 #endif
161
162 #ifdef HAVE_STDLIB_H
163 #  include <stdlib.h>
164 #endif
165
166 #ifdef HAVE_LIBGEN_H
167 #  include <libgen.h>
168 #endif
169
170 #ifdef HAVE_STRING_H
171 #  include <string.h>
172 #endif
173
174 #ifdef HAVE_STRINGS_H
175 #  include <strings.h>
176 #endif
177
178 #ifdef HAVE_SYSLOG_H
179 #  include <syslog.h>
180 #endif
181
182 #ifdef HAVE_MATH_H
183 #  include <math.h>
184 #endif
185
186 #ifdef HAVE_SYS_FILE_H
187 #  include <sys/file.h>
188 #endif
189
190 #ifdef HAVE_SYS_IOCTL_H
191 #  include <sys/ioctl.h>
192 #endif
193
194 #ifdef HAVE_LIMITS_H
195 #include <limits.h>
196 #endif
197
198 #ifdef HAVE_SYS_PARAM_H
199 #  include <sys/param.h>
200 #endif
201
202 #if defined(HAVE_SYS_IPC_H) && defined(HAVE_SYS_SHM_H)
203 #  include <sys/ipc.h>
204 #  include <sys/shm.h>
205 #else
206 #  ifdef HAVE_SYS_MMAN_H
207 #    include <sys/mman.h>
208 #  endif
209 #endif
210
211 #ifdef HAVE_SYS_SELECT_H
212 #  include <sys/select.h>
213 #endif
214
215 #ifdef HAVE_SYS_STAT_H
216 #  include <sys/stat.h>
217 #endif
218
219 #ifdef HAVE_SYS_UIO_H
220 #  include <sys/uio.h>
221 #else
222 struct iovec {
223     void *iov_base;
224     int iov_len;
225 };
226 #endif
227
228 #ifdef HAVE_WAIT_H
229 #  include <wait.h>
230 #endif
231
232 #ifdef HAVE_SYS_WAIT_H
233 #  include <sys/wait.h>
234 #endif
235
236 #ifdef HAVE_STDARG_H
237 #include <stdarg.h>
238 #endif
239
240 #ifdef WAIT_USES_INT
241   typedef int amwait_t;
242 # ifndef WEXITSTATUS
243 #  define WEXITSTATUS(stat_val) (*(unsigned*)&(stat_val) >> 8)
244 # endif
245 # ifndef WTERMSIG
246 #  define WTERMSIG(stat_val) (*(unsigned*)&(stat_val) & 0x7F)
247 # endif
248 # ifndef WIFEXITED
249 #  define WIFEXITED(stat_val) ((*(unsigned*)&(stat_val) & 255) == 0)
250 # endif
251 #else
252 # ifdef WAIT_USES_UNION
253    typedef union wait amwait_t;
254 #  ifndef WEXITSTATUS
255 #  define WEXITSTATUS(stat_val) (((amwait_t*)&(stat_val))->w_retcode)
256 #  endif
257 #  ifndef WTERMSIG
258 #   define WTERMSIG(stat_val) (((amwait_t*)&(stat_val))->w_termsig)
259 #  endif
260 #  ifndef WIFEXITED
261 #   define WIFEXITED(stat_val) (WTERMSIG(stat_val) == 0)
262 #  endif
263 # else
264    typedef int amwait_t;
265 #  ifndef WEXITSTATUS
266 #   define WEXITSTATUS(stat_val) (*(unsigned*)&(stat_val) >> 8)
267 #  endif
268 #  ifndef WTERMSIG
269 #   define WTERMSIG(stat_val) (*(unsigned*)&(stat_val) & 0x7F)
270 #  endif
271 #  ifndef WIFEXITED
272 #   define WIFEXITED(stat_val) ((*(unsigned*)&(stat_val) & 255) == 0)
273 #  endif
274 # endif
275 #endif
276
277 #ifndef WIFSIGNALED
278 # define WIFSIGNALED(stat_val)  (WTERMSIG(stat_val) != 0)
279 #endif
280
281 #ifdef HAVE_UNISTD_H
282 #  include <unistd.h>
283 #endif
284
285 #ifdef HAVE_NETINET_IN_H
286 #  include <netinet/in.h>
287 #endif
288
289 #include <ctype.h>
290 #include <errno.h>
291 #include <pwd.h>
292 #include <signal.h>
293 #include <setjmp.h>
294 #include <stdio.h>
295 #include <sys/resource.h>
296 #include <sys/socket.h>
297
298 #ifdef HAVE_ARPA_INET_H
299 #include <arpa/inet.h>
300 #endif
301
302 #ifdef WORKING_IPV6
303 #define INET6
304 #endif
305
306 #ifndef INET_ADDRSTRLEN
307 #define INET_ADDRSTRLEN 16
308 #endif
309
310 #if !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC)
311 /* quick'n'dirty hack for NextStep31 */
312 #  define sa_flags sv_flags
313 #  define sa_handler sv_handler
314 #  define sa_mask sv_mask
315 #  define sigaction sigvec
316 #  define sigemptyset(mask) /* no way to clear pending signals */
317 #endif
318
319 /*
320  * Most Unixen declare errno in <errno.h>, some don't.  Some multithreaded
321  * systems have errno as a per-thread macro.  So, we have to be careful.
322  */
323 #ifndef errno
324 extern int errno;
325 #endif
326
327 /*
328  * Some compilers have int for type of sizeof() some use size_t.
329  * size_t is the one we want...
330  */
331 #define SIZEOF(x)       (size_t)sizeof(x)
332
333
334 /*
335  * Some older BSD systems don't have these FD_ macros, so if not, provide them.
336  */
337 #if !defined(FD_SET) || defined(LINT) || defined(__lint)
338 #  undef FD_SETSIZE
339 #  define FD_SETSIZE      (int)(SIZEOF(fd_set) * CHAR_BIT)
340
341 #  undef FD_SET
342 #  define FD_SET(n, p)    (((fd_set *)(p))->fds_bits[(n)/WORD_BIT] |= (int)((1 << ((n) % WORD_BIT))))
343
344 #  undef FD_CLR
345 #  define FD_CLR(n, p)    (((fd_set *)(p))->fds_bits[(n)/WORD_BIT] &= (int)(~(1 << ((n) % WORD_BIT))))
346
347 #  undef FD_ISSET
348 #  define FD_ISSET(n, p)  (((fd_set *)(p))->fds_bits[(n)/WORD_BIT] & (1 << ((n) % WORD_BIT)))
349
350 #  undef FD_ZERO
351 #  define FD_ZERO(p)      memset((p), 0, SIZEOF(*(p)))
352 #endif
353
354 #ifndef FD_COPY
355 #  define FD_COPY(p, q)   memcpy((q), (p), SIZEOF(*(p)))
356 #endif
357
358
359 /*
360  * Define MAX_HOSTNAME_LENGTH as the size of arrays to hold hostname's.
361  */
362 #undef  MAX_HOSTNAME_LENGTH
363 #define MAX_HOSTNAME_LENGTH 1025
364
365 /*
366  * If void is broken, substitute char.
367  */
368 #ifdef BROKEN_VOID
369 #  define void char
370 #endif
371
372 #define stringize(x) #x
373 #define stringconcat(x, y) x ## y
374
375 /* amanda #days calculation, with roundoff */
376
377 #define SECS_PER_DAY    (24*60*60)
378 #define days_diff(a, b) (int)(((b) - (a) + SECS_PER_DAY/2) / SECS_PER_DAY)
379
380 /* Global constants.  */
381 #ifndef AMANDA_SERVICE_NAME
382 #define AMANDA_SERVICE_NAME "amanda"
383 #endif
384 #ifndef KAMANDA_SERVICE_NAME
385 #define KAMANDA_SERVICE_NAME "kamanda"
386 #endif
387 #ifndef SERVICE_SUFFIX
388 #define SERVICE_SUFFIX ""
389 #endif
390 #ifndef AMANDA_SERVICE_DEFAULT
391 #define AMANDA_SERVICE_DEFAULT  ((in_port_t)10080)
392 #endif
393 #ifndef KAMANDA_SERVICE_DEFAULT
394 #define KAMANDA_SERVICE_DEFAULT ((in_port_t)10081)
395 #endif
396
397 #define am_round(v,u)   ((((v) + (u) - 1) / (u)) * (u))
398 #define am_floor(v,u)   (((v) / (u)) * (u))
399
400 /* Holding disk block size.  Do not even think about changint this!  :-) */
401 #define DISK_BLOCK_KB           32
402 #define DISK_BLOCK_BYTES        (DISK_BLOCK_KB * 1024)
403
404 /* Maximum length of tape label, plus one for null-terminator. */
405 #define MAX_TAPE_LABEL_LEN (10240)
406 #define MAX_TAPE_LABEL_BUF (MAX_TAPE_LABEL_LEN+1)
407 #define MAX_TAPE_LABEL_FMT "%10240s"
408
409 /* Unfortunately, the system-level sockaddr_storage definition can lead to
410  * C aliasing errors (where the optimizer doesn't notice that two operations
411  * affect the same datum).  We define our own similar type as a union.
412  */
413 typedef union sockaddr_union {
414     struct sockaddr         sa;
415     struct sockaddr_in      sin;
416 #ifdef WORKING_IPV6
417     struct sockaddr_in6     sin6;
418 #endif
419 #ifdef HAVE_SOCKADDR_STORAGE
420     struct sockaddr_storage ss; /* not used; just here to make the union full-size */
421 #endif
422 } sockaddr_union;
423
424 #include "debug.h"
425 #include "file.h"
426
427 void *debug_alloc(const char *file, int line, size_t size);
428 void *debug_newalloc(const char *file, int line, void *old, size_t size);
429 char *debug_stralloc(const char *file, int line, const char *str);
430 char *debug_newstralloc(const char *file, int line,
431                 char *oldstr, const char *newstr);
432 char *debug_vstralloc(const char *file, int line, const char *str, ...);
433 char *debug_newvstralloc(const char *file, int line,
434                 char *oldstr, const char *str, ...);
435 char *debug_vstrallocf(const char *file, int line, const char *fmt,
436                 ...) G_GNUC_PRINTF(3, 4);
437 char *debug_newvstrallocf(const char *file, int line, char *oldstr,
438                 const char *fmt, ...) G_GNUC_PRINTF(4, 5);
439
440 /* Usage: vstrextend(foo, "bar, "baz", NULL). Extends the existing 
441  * string, or allocates a brand new one. */
442 char *debug_vstrextend(const char *file, int line, char **oldstr, ...);
443
444 #define alloc(s)                debug_alloc(__FILE__, __LINE__, (s))
445 #define newalloc(p,s)           debug_newalloc(__FILE__, __LINE__, (p), (s))
446 #define stralloc(s)             debug_stralloc(__FILE__, __LINE__, (s))
447 #define newstralloc(p,s)        debug_newstralloc(__FILE__, __LINE__, (p), (s))
448 #define vstralloc(...)          debug_vstralloc(__FILE__,__LINE__,__VA_ARGS__)
449 #define newvstralloc(...)       debug_newvstralloc(__FILE__,__LINE__,__VA_ARGS__)
450 #define vstrallocf(...)         debug_vstrallocf(__FILE__,__LINE__,__VA_ARGS__)
451 #define newvstrallocf(...)      debug_newvstrallocf(__FILE__,__LINE__,__VA_ARGS__)
452 #define vstrextend(...)         debug_vstrextend(__FILE__,__LINE__,__VA_ARGS__)
453
454 #define stralloc2(s1,s2)        vstralloc((s1),(s2),NULL)
455 #define newstralloc2(p,s1,s2)   newvstralloc((p),(s1),(s2),NULL)
456
457 #define vstrallocf(...)         debug_vstrallocf(__FILE__,__LINE__,__VA_ARGS__)
458
459 /*@only@*/ /*@null@*/ char *debug_agets(const char *file, int line, FILE *f);
460 /*@only@*/ /*@null@*/ char *debug_areads(const char *file, int line, int fd);
461 #define agets(f)              debug_agets(__FILE__,__LINE__,(f))
462 #define areads(f)             debug_areads(__FILE__,__LINE__,(f))
463
464 extern int debug_amtable_alloc(const char *file,
465                                   int line,
466                                   void **table,
467                                   size_t *current,
468                                   size_t elsize,
469                                   size_t count,
470                                   int bump,
471                                   void (*init_func)(void *));
472
473 #define amtable_alloc(t,c,s,n,b,f) debug_amtable_alloc(__FILE__,      \
474                                                      __LINE__,        \
475                                                      (t),             \
476                                                      (c),             \
477                                                      (s),             \
478                                                      (n),             \
479                                                      (b),             \
480                                                      (f))
481
482 extern void amtable_free(void **, size_t *);
483
484 char ** safe_env(void);
485 char *  validate_regexp(const char *regex);
486 char *  validate_glob(const char *glob);
487 char *  clean_regex(const char *regex);
488 int     match(const char *regex, const char *str);
489 int     match_no_newline(const char *regex, const char *str);
490 int     match_glob(const char *glob, const char *str);
491 char *  glob_to_regex(const char *glob);
492 int     match_tar(const char *glob, const char *str);
493 char *  tar_to_regex(const char *glob);
494 int     match_host(const char *glob, const char *host);
495 int     match_disk(const char *glob, const char *disk);
496 int     match_datestamp(const char *dateexp, const char *datestamp);
497 int     match_level(const char *levelexp, const char *level);
498 time_t  unctime(char *timestr);
499
500 /*
501  * amfree(ptr) -- if allocated, release space and set ptr to NULL.
502  *
503  * In general, this should be called instead of just free(), unless
504  * the very next source line sets the pointer to a new value.
505  */
506
507 #define amfree(ptr) do {                                                \
508     if((ptr) != NULL) {                                                 \
509         int e__errno = errno;                                           \
510         free(ptr);                                                      \
511         (ptr) = NULL;                                                   \
512         errno = e__errno;                                               \
513         (void)(ptr);  /* Fix value never used warning at end of routines */ \
514     }                                                                   \
515 } while (0)
516
517 #define strappend(s1,s2) do {                                           \
518     char *t_t_t = (s1) ? stralloc2((s1),(s2)) : stralloc((s2));         \
519     amfree((s1));                                                       \
520     (s1) = t_t_t;                                                       \
521 } while(0)
522
523 /*
524  * Return the number of elements in an array.
525  */
526 #define am_countof(a)   (int)(SIZEOF(a) / SIZEOF((a)[0]))
527
528 /*
529  * min/max.  Don't do something like
530  *
531  *    x = min(y++, z);
532  *
533  * because the increment will be duplicated.
534  */
535 #undef min
536 #undef max
537 #define min(a, b)       ((a) < (b) ? (a) : (b))
538 #define max(a, b)       ((a) > (b) ? (a) : (b))
539
540 /*
541  * Utility bitmask manipulation macros.
542  */
543 #define SET(t, f)       ((t) |= (f))
544 #define CLR(t, f)       ((t) &= ~((unsigned)(f)))
545 #define ISSET(t, f)     ((t) & (f))
546
547 /*
548  * Utility string macros.  All assume a variable holds the current
549  * character and the string pointer points to the next character to
550  * be processed.  Typical setup is:
551  *
552  *  s = buffer;
553  *  ch = *s++;
554  *  skip_whitespace(s, ch);
555  *  ...
556  *
557  * If you advance the pointer "by hand" to skip over something, do
558  * it like this:
559  *
560  *  s += some_amount;
561  *  ch = s[-1];
562  *
563  * Note that ch has the character at the end of the just skipped field.
564  * It is often useful to terminate a string, make a copy, then restore
565  * the input like this:
566  *
567  *  skip_whitespace(s, ch);
568  *  fp = s-1;                   ## save the start
569  *  skip_nonwhitespace(s, ch);  ## find the end
570  *  p[-1] = '\0';               ## temporary terminate
571  *  field = stralloc(fp);       ## make a copy
572  *  p[-1] = ch;                 ## restore the input
573  *
574  * The scanning macros are:
575  *
576  *  skip_whitespace (ptr, var)
577  *    -- skip whitespace, but stops at a newline
578  *  skip_non_whitespace (ptr, var)
579  *    -- skip non whitespace
580  *  skip_non_whitespace_cs (ptr, var)
581  *    -- skip non whitespace, stop at comment
582  *  skip_integer (ptr, var)
583  *    -- skip an integer field
584  *  skip_line (ptr, var)
585  *    -- skip just past the next newline
586  *  strncmp_const (str, const_str)
587  *    -- compare str to const_str, a string constant
588  *  strncmp_const_skip (str, const_var, ptr, var)
589  *    -- like strncmp_const, but skip the string if a match is
590  *       found; this macro only tests for equality, discarding
591  *       ordering information.
592  *
593  * where:
594  *
595  *  ptr -- string pointer
596  *  var -- current character
597  *
598  * These macros copy a non-whitespace field to a new buffer, and should
599  * only be used if dynamic allocation is impossible (fixed size buffers
600  * are asking for trouble):
601  *
602  *  copy_string (ptr, var, field, len, fldptr)
603  *    -- copy a non-whitespace field
604  *  copy_string_cs (ptr, var, field, len, fldptr)
605  *    -- copy a non-whitespace field, stop at comment
606  *
607  * where:
608  *
609  *  ptr -- string pointer
610  *  var -- current character
611  *  field -- area to copy to
612  *  len -- length of area (needs room for null byte)
613  *  fldptr -- work pointer used in move
614  *            if NULL on exit, the field was too small for the input
615  */
616
617 #define STR_SIZE        4096            /* a generic string buffer size */
618 #define NUM_STR_SIZE    128             /* a generic number buffer size */
619
620 #define skip_whitespace(ptr,c) do {                                     \
621     while((c) != '\n' && g_ascii_isspace((int)c)) (c) = *(ptr)++;               \
622 } while(0)
623
624 #define skip_non_whitespace(ptr,c) do {                                 \
625     while((c) != '\0' && !g_ascii_isspace((int)c)) (c) = *(ptr)++;              \
626 } while(0)
627
628 #define skip_non_whitespace_cs(ptr,c) do {                              \
629     while((c) != '\0' && (c) != '#' && !g_ascii_isspace((int)c)) (c) = *(ptr)++;\
630 } while(0)
631
632 #define skip_non_integer(ptr,c) do {                                    \
633     while((c) != '\0' && !isdigit(c)) (c) = *(ptr)++;                   \
634 } while(0)
635
636 #define skip_integer(ptr,c) do {                                        \
637     if((c) == '+' || (c) == '-') (c) = *(ptr)++;                        \
638     while(isdigit(c)) (c) = *(ptr)++;                                   \
639 } while(0)
640
641 #define skip_quoted_string(ptr, c) do {                                 \
642     int iq = 0;                                                         \
643     while (((c) != '\0') && !((iq == 0) && g_ascii_isspace((int)c))) {          \
644         if ((c) == '"') {                                               \
645             iq = !iq;                                                   \
646         } else if ((c) == '\\') {                                       \
647             if (*ptr)   /* not last character */                        \
648                 (ptr)++;                                                \
649         }                                                               \
650         (c) = *(ptr)++;                                                 \
651     }                                                                   \
652 } while (0)
653
654 #define skip_quoted_line(ptr, c) do {                                   \
655     int iq = 0;                                                         \
656     while((c) && !((iq == 0) && ((c) == '\n'))) {                       \
657         if ((c) == '"')                                                 \
658             iq = !iq;                                                   \
659         (c) = *(ptr)++;                                                 \
660     }                                                                   \
661     if(c)                                                               \
662         (c) = *(ptr)++;                                                 \
663 } while(0)
664
665 #define skip_line(ptr,c) do {                                           \
666     while((c) && (c) != '\n')                                           \
667         (c) = *(ptr)++;                                                 \
668     if(c)                                                               \
669         (c) = *(ptr)++;                                                 \
670 } while(0)
671
672 #define copy_string(ptr,c,f,l,fp) do {                                  \
673     (fp) = (f);                                                         \
674     while((c) != '\0' && !g_ascii_isspace((int)c)) {                            \
675         if((fp) >= (f) + (l) - 1) {                                     \
676             *(fp) = '\0';                                               \
677             (fp) = NULL;                                                \
678             (void)(fp);  /* Fix value never used warning at end of routines */ \
679             break;                                                      \
680         }                                                               \
681         *(fp)++ = (c);                                                  \
682         (c) = *(ptr)++;                                                 \
683     }                                                                   \
684     if(fp)                                                              \
685         *fp = '\0';                                                     \
686 } while(0)
687
688 #define copy_string_cs(ptr,c,f,l,fp) do {                               \
689     (fp) = (f);                                                         \
690     while((c) != '\0' && (c) != '#' && !g_ascii_isspace((int)c)) {              \
691         if((fp) >= (f) + (l) - 1) {                                     \
692             *(fp) = '\0';                                               \
693             (fp) = NULL;                                                \
694             break;                                                      \
695         }                                                               \
696         *(fp)++ = (c);                                                  \
697         (c) = *(ptr)++;                                                 \
698     }                                                                   \
699     if(fp) *fp = '\0';                                                  \
700 } while(0)
701
702 #define is_dot_or_dotdot(s)                                             \
703     ((s)[0] == '.'                                                      \
704      && ((s)[1] == '\0'                                                 \
705          || ((s)[1] == '.' && (s)[2] == '\0')))
706
707 #define strncmp_const(str, cnst)                                        \
708         strncmp((str), (cnst), sizeof((cnst))-1)
709
710 /* (have to roll this up in an expression, so it can be used in if()) */
711 #define strncmp_const_skip(str, cnst, ptr, var)                         \
712         ((strncmp((str), (cnst), sizeof((cnst))-1) == 0)?               \
713                  ((ptr)+=sizeof((cnst))-1, (var)=(ptr)[-1], 0)          \
714                 :1)
715
716 /* from old bsd-security.c */
717 extern int debug;
718 extern int check_security(sockaddr_union *, char *, unsigned long, char **);
719
720 /*
721  * Handle functions which are not always declared on all systems.  This
722  * stops gcc -Wall and lint from complaining.
723  */
724
725 /* AIX #defines accept, and provides a prototype for the alternate name */
726 #if !defined(HAVE_ACCEPT_DECL) && !defined(accept)
727 extern int accept(int s, struct sockaddr *addr, socklen_t_equiv *addrlen);
728 #endif
729
730 #ifndef HAVE_ATOF_DECL
731 extern double atof(const char *ptr);
732 #endif
733
734 #ifndef HAVE_BCOPY
735 # define bcopy(from,to,n) ((void)memmove((to), (from), (n)))
736 #else
737 # ifndef HAVE_BCOPY_DECL
738 extern void bcopy(const void *s1, void *s2, size_t n);
739 # endif
740 #endif
741
742 #ifndef HAVE_BIND_DECL
743 extern int bind(int s, const struct sockaddr *name, socklen_t_equiv namelen);
744 #endif
745
746 #ifndef HAVE_BZERO
747 #define bzero(s,n) ((void)memset((s),0,(n)))
748 #else
749 # ifndef HAVE_BZERO_DECL
750 extern void bzero(void *s, size_t n);
751 # endif
752 #endif
753
754 #ifndef HAVE_CLOSELOG_DECL
755 extern void closelog(void);
756 #endif
757
758 #ifndef HAVE_CONNECT_DECL
759 extern int connect(int s, struct sockaddr *name, socklen_t_equiv namelen);
760 #endif
761
762 #ifndef HAVE_FCLOSE_DECL
763 extern int fclose(FILE *stream);
764 #endif
765
766 #ifndef HAVE_FFLUSH_DECL
767 extern int fflush(FILE *stream);
768 #endif
769
770 #ifndef HAVE_FPRINTF_DECL
771 extern int fprintf(FILE *stream, const char *format, ...);
772 #endif
773
774 #ifndef HAVE_FPUTC_DECL
775 extern int fputc(int c, FILE *stream);
776 #endif
777
778 #ifndef HAVE_FPUTS_DECL
779 extern int fputs(const char *s, FILE *stream);
780 #endif
781
782 #ifndef HAVE_FREAD_DECL
783 extern size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
784 #endif
785
786 #ifndef HAVE_FSEEK_DECL
787 extern int fseek(FILE *stream, long offset, int ptrname);
788 #endif
789
790 #ifndef HAVE_FWRITE_DECL
791 extern size_t fwrite(const void *ptr, size_t size, size_t nitems,
792                         FILE *stream);
793 #endif
794
795 #ifndef HAVE_GETHOSTNAME_DECL
796 extern int gethostname(char *name, int namelen);
797 #endif
798
799 #ifndef HAVE_GETOPT_DECL
800 extern char *optarg;
801 extern int getopt(int argc, char * const *argv, const char *optstring);
802 #endif
803
804 /* AIX #defines getpeername, and provides a prototype for the alternate name */
805 #if !defined(HAVE_GETPEERNAME_DECL) && !defined(getpeername)
806 extern int getpeername(int s, struct sockaddr *name, socklen_t_equiv *namelen);
807 #endif
808
809 /* AIX #defines getsockname, and provides a prototype for the alternate name */
810 #if !defined(HAVE_GETSOCKNAME_DECL) && !defined(getsockname)
811 extern int getsockname(int s, struct sockaddr *name, socklen_t_equiv *namelen);
812 #endif
813
814 #ifndef HAVE_GETSOCKOPT_DECL
815 extern int getsockopt(int s, int level, int optname, char *optval,
816                          socklen_t_equiv *optlen);
817 #endif
818
819 #ifndef HAVE_INITGROUPS
820 # define initgroups(name,basegid) 0
821 #else
822 # ifndef HAVE_INITGROUPS_DECL
823 extern int initgroups(const char *name, gid_t basegid);
824 # endif
825 #endif
826
827 #ifndef HAVE_IOCTL_DECL
828 extern int ioctl(int fildes, int request, ...);
829 #endif
830
831 #ifndef isnormal
832 #ifndef HAVE_ISNORMAL
833 #define isnormal(f) (((f) < 0.0) || ((f) > 0.0))
834 #endif
835 #endif
836
837 #ifndef HAVE_LISTEN_DECL
838 extern int listen(int s, int backlog);
839 #endif
840
841 #ifndef HAVE_LSTAT_DECL
842 extern int lstat(const char *path, struct stat *buf);
843 #endif
844
845 #ifndef HAVE_MALLOC_DECL
846 extern void *malloc (size_t size);
847 #endif
848
849 #ifndef HAVE_MEMMOVE_DECL
850 #ifdef HAVE_MEMMOVE
851 extern void *memmove(void *to, const void *from, size_t n);
852 #else
853 extern char *memmove(char *to, /*const*/ char *from, size_t n);
854 #endif
855 #endif
856
857 #ifndef HAVE_MEMSET_DECL
858 extern void *memset(void *s, int c, size_t n);
859 #endif
860
861 #ifndef HAVE_MKTEMP_DECL
862 extern char *mktemp(char *template);
863 #endif
864
865 #ifndef HAVE_MKSTEMP_DECL
866 extern int mkstemp(char *template);
867 #endif
868
869 #ifndef HAVE_MKTIME_DECL
870 extern time_t mktime(struct tm *timeptr);
871 #endif
872
873 #ifndef HAVE_OPENLOG_DECL
874 #ifdef LOG_AUTH
875 extern void openlog(const char *ident, int logopt, int facility);
876 #else
877 extern void openlog(const char *ident, int logopt);
878 #endif
879 #endif
880
881 #ifndef HAVE_PCLOSE_DECL
882 extern int pclose(FILE *stream);
883 #endif
884
885 #ifndef HAVE_PERROR_DECL
886 extern void perror(const char *s);
887 #endif
888
889 #ifndef HAVE_PRINTF_DECL
890 extern int printf(const char *format, ...);
891 #endif
892
893 #ifndef HAVE_PUTS_DECL
894 extern int puts(const char *s);
895 #endif
896
897 #ifndef HAVE_REALLOC_DECL
898 extern void *realloc(void *ptr, size_t size);
899 #endif
900
901 /* AIX #defines recvfrom, and provides a prototype for the alternate name */
902 #if !defined(HAVE_RECVFROM_DECL) && !defined(recvfrom)
903 extern int recvfrom(int s, char *buf, int len, int flags,
904                        struct sockaddr *from, socklen_t_equiv *fromlen);
905 #endif
906
907 #ifndef HAVE_REMOVE_DECL
908 extern int remove(const char *path);
909 #endif
910
911 #ifndef HAVE_RENAME_DECL
912 extern int rename(const char *old, const char *new);
913 #endif
914
915 #ifndef HAVE_REWIND_DECL
916 extern void rewind(FILE *stream);
917 #endif
918
919 #ifndef HAVE_RUSEROK_DECL
920 extern int ruserok(const char *rhost, int suser,
921                       const char *ruser, const char *luser);
922 #endif
923
924 #ifndef HAVE_SELECT_DECL
925 extern int select(int nfds,
926                      SELECT_ARG_TYPE *readfds,
927                      SELECT_ARG_TYPE *writefds,
928                      SELECT_ARG_TYPE *exceptfds,
929                      struct timeval *timeout);
930 #endif
931
932 #ifndef HAVE_SENDTO_DECL
933 extern int sendto(int s, const char *msg, int len, int flags,
934                      const struct sockaddr *to, int tolen);
935 #endif
936
937 #ifdef HAVE_SETRESGID
938 #define setegid(x)      setresgid((gid_t)-1,(x),(gid_t)-1)
939 #ifndef HAVE_SETRESGID_DECL
940 extern int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
941 #endif
942 #else
943 #ifndef HAVE_SETEGID_DECL
944 extern int setegid(gid_t egid);
945 #endif
946 #endif
947
948 #ifdef HAVE_SETRESUID
949 #define seteuid(x)      setresuid((uid_t)-1,(x),(uid_t)-1)
950 #ifndef HAVE_SETRESUID_DECL
951 extern int setresuid(uid_t ruid, uid_t euid, uid_t suid);
952 #endif
953 #else
954 #ifndef HAVE_SETEUID_DECL
955 extern int seteuid(uid_t euid);
956 #endif
957 #endif
958
959 #ifndef HAVE_SETPGID_DECL
960 #ifdef HAVE_SETPGID
961 extern int setpgid(pid_t pid, pid_t pgid);
962 #endif
963 #endif
964
965 #ifndef HAVE_SETPGRP_DECL
966 #ifdef SETPGRP_VOID
967 extern pid_t setpgrp(void);
968 #else
969 extern pid_t setpgrp(pid_t pgrp, pid_t pid);
970 #endif
971 #endif
972
973 #ifndef HAVE_SETSOCKOPT_DECL
974 extern int setsockopt(int s, int level, int optname,
975                          const char *optval, int optlen);
976 #endif
977
978 #ifdef HAVE_SHMGET
979 #ifndef HAVE_SHMAT_DECL
980 extern void *shmat(int shmid, const SHM_ARG_TYPE *shmaddr, int shmflg);
981 #endif
982
983 #ifndef HAVE_SHMCTL_DECL
984 extern int shmctl(int shmid, int cmd, struct shmid_ds *buf);
985 #endif
986
987 #ifndef HAVE_SHMDT_DECL
988 extern int shmdt(SHM_ARG_TYPE *shaddr);
989 #endif
990
991 #ifndef HAVE_SHMGET_DECL
992 extern int shmget(key_t key, size_t size, int shmflg);
993 #endif
994 #endif
995
996 #ifndef HAVE_SNPRINTF_DECL
997 #include "arglist.h"
998 int snprintf(char *buf, size_t len, const char *format,...)
999      G_GNUC_PRINTF(3,4);
1000 #endif
1001 #ifndef HAVE_VSNPRINTF_DECL
1002 #include "arglist.h"
1003 int vsnprintf(char *buf, size_t len, const char *format, va_list ap);
1004 #endif
1005
1006 #ifndef HAVE_SOCKET_DECL
1007 extern int socket(int domain, int type, int protocol);
1008 #endif
1009
1010 #ifndef HAVE_SOCKETPAIR_DECL
1011 extern int socketpair(int domain, int type, int protocol, int sv[2]);
1012 #endif
1013
1014 #ifndef HAVE_SSCANF_DECL
1015 extern int sscanf(const char *s, const char *format, ...);
1016 #endif
1017
1018 #ifndef HAVE_STRCASECMP_DECL
1019 extern int strcasecmp(const char *s1, const char *s2);
1020 #endif
1021
1022 #ifndef HAVE_STRERROR_DECL
1023 extern char *strerror(int errnum);
1024 #endif
1025
1026 #ifndef HAVE_STRFTIME_DECL
1027 extern size_t strftime(char *s, size_t maxsize, const char *format,
1028                           const struct tm *timeptr);
1029 #endif
1030
1031 #ifndef HAVE_STRNCASECMP_DECL
1032 extern int strncasecmp(const char *s1, const char *s2, int n);
1033 #endif
1034
1035 #ifndef HAVE_SYSLOG_DECL
1036 extern void syslog(int priority, const char *logstring, ...)
1037      G_GNUC_PRINTF(2,3);
1038 #endif
1039
1040 #ifndef HAVE_SYSTEM_DECL
1041 extern int system(const char *string);
1042 #endif
1043
1044 #ifndef HAVE_TIME_DECL
1045 extern time_t time(time_t *tloc);
1046 #endif
1047
1048 #ifndef HAVE_TOLOWER_DECL
1049 extern int tolower(int c);
1050 #endif
1051
1052 #ifndef HAVE_TOUPPER_DECL
1053 extern int toupper(int c);
1054 #endif
1055
1056 #ifndef HAVE_UNGETC_DECL
1057 extern int ungetc(int c, FILE *stream);
1058 #endif
1059
1060 #ifndef HAVE_VFPRINTF_DECL
1061 #include "arglist.h"
1062 extern int vfprintf(FILE *stream, const char *format, va_list ap);
1063 #endif
1064
1065 #ifndef HAVE_VPRINTF_DECL
1066 #include "arglist.h"
1067 extern int vprintf(const char *format, va_list ap);
1068 #endif
1069
1070 /* gnulib-only includes (hence "" instead of <>) */
1071 #include "getaddrinfo.h"
1072 #include "inet_ntop.h"
1073 #include "safe-read.h"
1074 #include "full-read.h"
1075 #include "full-write.h"
1076
1077 #if !defined(S_ISCHR) && defined(_S_IFCHR) && defined(_S_IFMT)
1078 #define S_ISCHR(mode) (((mode) & _S_IFMT) == _S_IFCHR)
1079 #endif
1080
1081 #if !defined(S_ISREG) && defined(_S_IFREG) && defined(_S_IFMT)
1082 #define S_ISREG(mode) (((mode) & _S_IFMT) == _S_IFREG)
1083 #endif
1084
1085 #ifndef HAVE_WAITPID
1086 #ifdef HAVE_WAIT4
1087 #define waitpid(pid,status,options) wait4(pid,status,options,0)
1088 #else
1089 extern pid_t waitpid(pid_t pid, amwait_t *stat_loc, int options);
1090 #endif
1091 #endif
1092
1093 #ifndef HAVE_WRITEV_DECL
1094 extern ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
1095 #endif
1096
1097 #ifndef STDIN_FILENO
1098 #define STDIN_FILENO 0
1099 #endif
1100
1101 #ifndef STDOUT_FILENO
1102 #define STDOUT_FILENO 1
1103 #endif
1104
1105 #ifndef STDERR_FILENO
1106 #define STDERR_FILENO 2
1107 #endif
1108
1109 /* S_ISDIR is not defined on Nextstep */
1110 #ifndef S_ISDIR
1111 #if defined(_S_IFMT) && defined(_S_IFDIR)
1112 #define S_ISDIR(mode)   (((mode) & (_S_IFMT)) == (_S_IFDIR))
1113 #else
1114 #error Don t know how to define S_ISDIR
1115 #endif
1116 #endif
1117
1118 #if SIZEOF_SIZE_T == SIZEOF_INT
1119 #  define        SIZE_T_ATOI    (size_t)atoi
1120 #  ifndef SIZE_MAX
1121 #    define      SIZE_MAX       G_MAXUINT
1122 #  endif
1123 #else
1124 #  define        SIZE_T_ATOI    (size_t)atol
1125 #  ifndef SIZE_MAX
1126 #    define      SIZE_MAX       ULONG_MAX
1127 #  endif
1128 #endif
1129
1130 #if SIZEOF_SSIZE_T == SIZEOF_INT
1131 #  define        SSIZE_T_ATOI   (ssize_t)atoi
1132 #  ifndef SSIZE_MAX
1133 #    define      SSIZE_MAX      INT_MAX
1134 #  endif
1135 #  ifndef SSIZE_MIN
1136 #    define      SSIZE_MIN      INT_MIN
1137 #  endif
1138 #else
1139 #  define        SSIZE_T_ATOI   (ssize_t)atol
1140 #  ifndef SSIZE_MAX
1141 #    define      SSIZE_MAX      LONG_MAX
1142 #  endif
1143 #  ifndef SSIZE_MIN
1144 #    define      SSIZE_MIN      LONG_MIN
1145 #  endif
1146 #endif
1147
1148 #if SIZEOF_TIME_T == SIZEOF_INT
1149 #  define        TIME_T_ATOI    (time_t)atoi
1150 #  ifndef TIME_MAX
1151 #    define      TIME_MAX       G_MAXUINT
1152 #  endif
1153 #else
1154 #  define        TIME_T_ATOI    (time_t)atol
1155 #  ifndef TIME_MAX
1156 #    define      TIME_MAX       ULONG_MAX
1157 #  endif
1158 #endif
1159
1160 #if SIZEOF_OFF_T > SIZEOF_LONG
1161 #  ifdef HAVE_ATOLL
1162 #    define        OFF_T_ATOI    (off_t)atoll
1163 #  else
1164 #    define        OFF_T_ATOI    (off_t)atol
1165 #  endif
1166 #  ifdef HAVE_STRTOLL
1167 #    define        OFF_T_STRTOL  (off_t)strtoll
1168 #  else
1169 #    define        OFF_T_STRTOL  (off_t)strtol
1170 #  endif
1171 #else
1172 #  if SIZEOF_OFF_T == SIZEOF_LONG
1173 #    define        OFF_T_ATOI    (off_t)atol
1174 #    define        OFF_T_STRTOL  (off_t)strtol
1175 #  else
1176 #    define        OFF_T_ATOI    (off_t)atoi
1177 #    define        OFF_T_STRTOL  (off_t)strtol
1178 #  endif
1179 #endif
1180
1181
1182 #define BIND_CYCLE_RETRIES      120             /* Total of 30 minutes */
1183
1184 #define MAX_DUMPERS 63
1185
1186 #ifndef NI_MAXHOST
1187 #define NI_MAXHOST 1025
1188 #endif
1189
1190 typedef enum {
1191     KENCRYPT_NONE,      /* krb5 encryption not enabled */
1192     KENCRYPT_WILL_DO,   /* krb5 encryption will be enabled once amanda
1193                            protocol stream is closed */
1194     KENCRYPT_YES        /* krb5 encryption enabled on all stream */
1195 } kencrypt_type;
1196
1197 #endif  /* !AMANDA_H */