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