/*
* Amanda, The Advanced Maryland Automatic Network Disk Archiver
* Copyright (c) 1991-1999 University of Maryland at College Park
* Copyright (c) 2007-2012 Zmanda, Inc. All Rights Reserved.
* Copyright (c) 2013-2016 Carbonite, Inc. All Rights Reserved.
* All Rights Reserved.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of U.M. not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. U.M. makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
* BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Authors: the Amanda Development Team. Its members are listed in a
* file named AUTHORS, in the root directory of this distribution.
*/
/*
* $Id: amanda.h,v 1.131 2006/07/25 18:27:56 martinea Exp $
*
* the central header file included by all amanda sources
*/
#ifndef AMANDA_H
#define AMANDA_H
#ifdef HAVE_CONFIG_H
/* use a relative path here to avoid conflicting with Perl's config.h. */
#include "../config/config.h"
#endif
#include <glib.h>
#include <glib/gprintf.h>
#include "amflock.h"
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
/*
* Varargs/ellipsis handling: some broken systems DO NOT declare STDC_HEADERS,
* which means va_start behaves differently :/ So, use our own
*/
#ifdef STDC_HEADERS
#include <stdarg.h>
#define arglist_start(arg,hook_name) va_start(arg,hook_name)
#else /* !STDC_HEADERS */
#include <varargs.h>
#define arglist_start(arg,hook_name) va_start(arg)
#endif /* STDC_HEADERS */
#define arglist_val(arg,type) va_arg(arg,type)
#define arglist_end(arg) va_end(arg)
/*
* Force large file source even if configure guesses wrong.
*/
#ifndef _FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 64
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
/* gnulib creates this header locally if the system doesn't provide it,
* so it uses a local ("") include */
#include "stdint.h"
/*
* I would prefer that each Amanda module include only those system headers
* that are locally needed, but on most Unixes the system header files are not
* protected against multiple inclusion, so this can lead to problems.
*
* Also, some systems put key files in different places, so by including
* everything here the rest of the system is isolated from such things.
*/
/* from the autoconf documentation */
#ifdef HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# if HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
# if HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif
# if HAVE_NDIR_H
# include <ndir.h>
# endif
#endif
#ifdef ENABLE_NLS
# include <libintl.h>
# include <locale.h>
# define plural(String1, String2, Count) \
(((Count) == 1) ? (String1) : (String2))
#else
# define plural(String1, String2, Count) \
(((Count) == 1) ? (String1) : (String2))
# define setlocale(Which, Locale)
# define textdomain(Domain)
# define bindtextdomain(Package, Directory)
# define gettext(String) String
# define dgettext(Domain, String) String
# define dcgettext(Domain, String, Catagory) String
# define ngettext(String1, String2, Count) \
plural((String1), (String2), (Count))
# define dngettext(Domain, String1, String2, Count) \
plural((String1), (String2), (Count))
# define dcngettext(Domain, String1, String2, Count, Catagory) \
plural((String1), (String2), (Count))
#endif
#define T_(String) String
#ifndef SWIG /* TODO: make this go away */
#define _(String) dgettext("amanda", (String))
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifdef HAVE_GRP_H
# include <grp.h>
#endif
#if defined(USE_DB_H)
# include <db.h>
#else
#if defined(USE_DBM_H)
# include <dbm.h>
#else
#if defined(USE_GDBM_H)
# include <gdbm.h>
#else
#if defined(USE_NDBM_H)
# include <ndbm.h>
#endif
#endif
#endif
#endif
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#ifdef HAVE_LIBC_H
# include <libc.h>
#endif
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#ifdef HAVE_LIBGEN_H
# include <libgen.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#ifdef HAVE_SYSLOG_H
# include <syslog.h>
#endif
#ifdef HAVE_MATH_H
# include <math.h>
#endif
#ifdef HAVE_SYS_FILE_H
# include <sys/file.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#if defined(HAVE_SYS_IPC_H) && defined(HAVE_SYS_SHM_H)
# include <sys/ipc.h>
# include <sys/shm.h>
#else
# ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
# endif
#endif
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_SYS_UIO_H
# include <sys/uio.h>
#else
struct iovec {
void *iov_base;
int iov_len;
};
#endif
#ifdef HAVE_WAIT_H
# include <wait.h>
#endif
#ifdef HAVE_SYS_WAIT_H
# include <sys/wait.h>
#endif
#ifdef HAVE_STDARG_H
#include <stdarg.h>
#endif
#ifdef WAIT_USES_INT
typedef int amwait_t;
# ifndef WEXITSTATUS
# define WEXITSTATUS(stat_val) (*(unsigned*)&(stat_val) >> 8)
# endif
# ifndef WTERMSIG
# define WTERMSIG(stat_val) (*(unsigned*)&(stat_val) & 0x7F)
# endif
# ifndef WIFEXITED
# define WIFEXITED(stat_val) ((*(unsigned*)&(stat_val) & 255) == 0)
# endif
#else
# ifdef WAIT_USES_UNION
typedef union wait amwait_t;
# ifndef WEXITSTATUS
# define WEXITSTATUS(stat_val) (((amwait_t*)&(stat_val))->w_retcode)
# endif
# ifndef WTERMSIG
# define WTERMSIG(stat_val) (((amwait_t*)&(stat_val))->w_termsig)
# endif
# ifndef WIFEXITED
# define WIFEXITED(stat_val) (WTERMSIG(stat_val) == 0)
# endif
# else
typedef int amwait_t;
# ifndef WEXITSTATUS
# define WEXITSTATUS(stat_val) (*(unsigned*)&(stat_val) >> 8)
# endif
# ifndef WTERMSIG
# define WTERMSIG(stat_val) (*(unsigned*)&(stat_val) & 0x7F)
# endif
# ifndef WIFEXITED
# define WIFEXITED(stat_val) ((*(unsigned*)&(stat_val) & 255) == 0)
# endif
# endif
#endif
#ifndef WIFSIGNALED
# define WIFSIGNALED(stat_val) (WTERMSIG(stat_val) != 0)
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#if HAVE_EUIDACCESS
# define EUIDACCESS euidaccess
#elif HAVE_EACCESS
# define EUIDACCESS eaccess
#else
# define EUIDACCESS access
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#include <ctype.h>
#include <errno.h>
#include <pwd.h>
#include <signal.h>
#include <setjmp.h>
#include <stdio.h>
#include <sys/resource.h>
#include <sys/socket.h>
#ifdef WORKING_IPV6
#define INET6
#endif
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
#endif
#if !defined(HAVE_SIGACTION) && defined(HAVE_SIGVEC)
/* quick'n'dirty hack for NextStep31 */
# define sa_flags sv_flags
# define sa_handler sv_handler
# define sa_mask sv_mask
# define sigaction sigvec
# define sigemptyset(mask) /* no way to clear pending signals */
#endif
/*
* Most Unixen declare errno in <errno.h>, some don't. Some multithreaded
* systems have errno as a per-thread macro. So, we have to be careful.
*/
#ifndef errno
extern int errno;
#endif
/*
* Some older BSD systems don't have these FD_ macros, so if not, provide them.
*/
#if !defined(FD_SET) || defined(LINT) || defined(__lint)
# undef FD_SETSIZE
# define FD_SETSIZE (int)(sizeof(fd_set) * CHAR_BIT)
# undef FD_SET
# define FD_SET(n, p) (((fd_set *)(p))->fds_bits[(n)/WORD_BIT] |= (int)((1 << ((n) % WORD_BIT))))
# undef FD_CLR
# define FD_CLR(n, p) (((fd_set *)(p))->fds_bits[(n)/WORD_BIT] &= (int)(~(1 << ((n) % WORD_BIT))))
# undef FD_ISSET
# define FD_ISSET(n, p) (((fd_set *)(p))->fds_bits[(n)/WORD_BIT] & (1 << ((n) % WORD_BIT)))
# undef FD_ZERO
# define FD_ZERO(p) memset((p), 0, sizeof(*(p)))
#endif
#ifndef FD_COPY
# define FD_COPY(p, q) memcpy((q), (p), sizeof(*(p)))
#endif
/*
* Define MAX_HOSTNAME_LENGTH as the size of arrays to hold hostname's.
*/
#undef MAX_HOSTNAME_LENGTH
#define MAX_HOSTNAME_LENGTH 1025
/*
* If void is broken, substitute char.
*/
#ifdef BROKEN_VOID
# define void char
#endif
#define stringize(x) #x
#define stringconcat(x, y) x ## y
/* amanda #days calculation, with roundoff */
#define SECS_PER_DAY (24*60*60)
#define days_diff(a, b) (int)(((b) - (a) + SECS_PER_DAY/2) / SECS_PER_DAY)
/* Global constants. */
#ifndef AMANDA_SERVICE_NAME
#define AMANDA_SERVICE_NAME "amanda"
#endif
#define am_round(v,u) ((((v) + (u) - 1) / (u)) * (u))
#define am_floor(v,u) (((v) / (u)) * (u))
/* Holding disk block size. Do not even think about changint this! :-) */
#define DISK_BLOCK_KB 32
#define DISK_BLOCK_BYTES (DISK_BLOCK_KB * 1024)
/* Maximum length of tape label, plus one for null-terminator. */
#define MAX_TAPE_LABEL_LEN (10240)
#define MAX_TAPE_LABEL_BUF (MAX_TAPE_LABEL_LEN+1)
#define MAX_TAPE_LABEL_FMT "%10240s"
#include "sockaddr-util.h"
#include "debug.h"
#include "file.h"
/*@only@*/ /*@null@*/ char *debug_agets(const char *file, int line, FILE *f);
/*@only@*/ /*@null@*/ char *debug_areads(const char *file, int line, int fd);
#define agets(f) debug_agets(__FILE__,__LINE__,(f))
#define areads(f) debug_areads(__FILE__,__LINE__,(f))
/* return a "safe" version of the current environment; pass this to execle */
#define safe_env() safe_env_full(NULL)
/* like safe_env, but optionally add additional environment variables */
char ** safe_env_full(char **add);
void free_env(char **env);
time_t unctime(char *timestr);
/*
* amfree(ptr) -- if allocated, release space and set ptr to NULL.
*
* In general, this should be called instead of just free(), unless
* the very next source line sets the pointer to a new value.
*/
#define amfree(ptr) do { \
if((ptr) != NULL) { \
int e__errno = errno; \
free(ptr); \
(ptr) = NULL; \
errno = e__errno; \
(void)(ptr); /* Fix value never used warning at end of routines */ \
} \
} while (0)
#define strappend(s1,s2) do { \
char *t_t_t = (s1) ? g_strconcat(s1, s2, NULL) : g_strdup((s2)); \
amfree((s1)); \
(s1) = t_t_t; \
} while(0)
/*
* min/max. Don't do something like
*
* x = min(y++, z);
*
* because the increment will be duplicated.
*/
#undef min
#undef max
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
/*
* Utility bitmask manipulation macros.
*/
#define SET(t, f) ((t) |= (f))
#define CLR(t, f) ((t) &= ~((unsigned)(f)))
#define ISSET(t, f) ((t) & (f))
/*
* Utility string macros. All assume a variable holds the current
* character and the string pointer points to the next character to
* be processed. Typical setup is:
*
* s = buffer;
* ch = *s++;
* skip_whitespace(s, ch);
* ...
*
* If you advance the pointer "by hand" to skip over something, do
* it like this:
*
* s += some_amount;
* ch = s[-1];
*
* Note that ch has the character at the end of the just skipped field.
* It is often useful to terminate a string, make a copy, then restore
* the input like this:
*
* skip_whitespace(s, ch);
* fp = s-1; ## save the start
* skip_nonwhitespace(s, ch); ## find the end
* p[-1] = '\0'; ## temporary terminate
* field = g_strdup(fp); ## make a copy
* p[-1] = ch; ## restore the input
*
* The scanning macros are:
*
* skip_whitespace (ptr, var)
* -- skip whitespace, but stops at a newline
* skip_non_whitespace (ptr, var)
* -- skip non whitespace
* skip_non_whitespace_cs (ptr, var)
* -- skip non whitespace, stop at comment
* skip_integer (ptr, var)
* -- skip an integer field
* skip_line (ptr, var)
* -- skip just past the next newline
* strncmp_const (str, const_str)
* -- compare str to const_str, a string constant
* strncmp_const_skip (str, const_var, ptr, var)
* strncmp_const_skip_no_var(str, const_var, ptr)
* -- like strncmp_const, but skip the string if a match is
* found; this macro only tests for equality, discarding
* ordering information.
*
* where:
*
* ptr -- string pointer
* var -- current character
*
* These macros copy a non-whitespace field to a new buffer, and should
* only be used if dynamic allocation is impossible (fixed size buffers
* are asking for trouble):
*
* copy_string (ptr, var, field, len, fldptr)
* -- copy a non-whitespace field
* copy_string_cs (ptr, var, field, len, fldptr)
* -- copy a non-whitespace field, stop at comment
*
* where:
*
* ptr -- string pointer
* var -- current character
* field -- area to copy to
* len -- length of area (needs room for null byte)
* fldptr -- work pointer used in move
* if NULL on exit, the field was too small for the input
*/
#define STR_SIZE 4096 /* a generic string buffer size */
#define NUM_STR_SIZE 128 /* a generic number buffer size */
#define skip_whitespace(ptr,c) do { \
while((c) != '\n' && g_ascii_isspace((int)c)) (c) = *(ptr)++; \
} while(0)
#define skip_non_whitespace(ptr,c) do { \
while((c) != '\0' && !g_ascii_isspace((int)c)) (c) = *(ptr)++; \
} while(0)
#define skip_non_whitespace_cs(ptr,c) do { \
while((c) != '\0' && (c) != '#' && !g_ascii_isspace((int)c)) (c) = *(ptr)++;\
} while(0)
#define skip_non_integer(ptr,c) do { \
while((c) != '\0' && !isdigit(c)) (c) = *(ptr)++; \
} while(0)
#define skip_integer(ptr,c) do { \
if((c) == '+' || (c) == '-') (c) = *(ptr)++; \
while(isdigit(c)) (c) = *(ptr)++; \
} while(0)
#define skip_quoted_string(ptr, c) do { \
int iq = 0; \
while (((c) != '\0') && !((iq == 0) && g_ascii_isspace((int)c))) { \
if ((c) == '"') { \
iq = !iq; \
} else if ((c) == '\\') { \
if (*ptr) /* not last character */ \
(ptr)++; \
} \
(c) = *(ptr)++; \
} \
} while (0)
#define skip_quoted_line(ptr, c) do { \
int iq = 0; \
while((c) && !((iq == 0) && ((c) == '\n'))) { \
if ((c) == '"') \
iq = !iq; \
(c) = *(ptr)++; \
} \
if(c) \
(c) = *(ptr)++; \
} while(0)
#define skip_line(ptr,c) do { \
while((c) && (c) != '\n') \
(c) = *(ptr)++; \
if(c) \
(c) = *(ptr)++; \
} while(0)
#define copy_string(ptr,c,f,l,fp) do { \
(fp) = (f); \
while((c) != '\0' && !g_ascii_isspace((int)c)) { \
if((fp) >= (f) + (l) - 1) { \
*(fp) = '\0'; \
(fp) = NULL; \
(void)(fp); /* Fix value never used warning at end of routines */ \
break; \
} \
*(fp)++ = (c); \
(c) = *(ptr)++; \
} \
if(fp) \
*fp = '\0'; \
} while(0)
#define copy_string_cs(ptr,c,f,l,fp) do { \
(fp) = (f); \
while((c) != '\0' && (c) != '#' && !g_ascii_isspace((int)c)) { \
if((fp) >= (f) + (l) - 1) { \
*(fp) = '\0'; \
(fp) = NULL; \
break; \
} \
*(fp)++ = (c); \
(c) = *(ptr)++; \
} \
if(fp) *fp = '\0'; \
} while(0)
#define is_dot_or_dotdot(s) \
((s)[0] == '.' \
&& ((s)[1] == '\0' \
|| ((s)[1] == '.' && (s)[2] == '\0')))
#define strncmp_const(str, cnst) \
strncmp((str), (cnst), sizeof((cnst))-1)
/* (have to roll this up in an expression, so it can be used in if()) */
#define strncmp_const_skip(str, cnst, ptr, var) \
((g_str_has_prefix((str), (cnst)))? \
((ptr)+=sizeof((cnst))-1, (var)=(ptr)[-1], 0) \
:1)
/* (have to roll this up in an expression, so it can be used in if()) */
#define strncmp_const_skip_no_var(str, cnst, ptr) \
((g_str_has_prefix((str), (cnst)))? \
((ptr)+=sizeof((cnst))-1, 0) \
:1)
/* from old bsd-security.c */
extern int check_security(sockaddr_union *, char *, unsigned long, char **, char *);
/*
* Handle functions which are not always declared on all systems. This
* stops gcc -Wall and lint from complaining.
*/
/* AIX #defines accept, and provides a prototype for the alternate name */
#if !defined(HAVE_ACCEPT_DECL) && !defined(accept)
extern int accept(int s, struct sockaddr *addr, socklen_t_equiv *addrlen);
#endif
#ifndef HAVE_ATOF_DECL
extern double atof(const char *ptr);
#endif
#ifndef HAVE_BCOPY
# define bcopy(from,to,n) ((void)memmove((to), (from), (n)))
#else
# ifndef HAVE_BCOPY_DECL
extern void bcopy(const void *s1, void *s2, size_t n);
# endif
#endif
#ifndef HAVE_BIND_DECL
extern int bind(int s, const struct sockaddr *name, socklen_t_equiv namelen);
#endif
#ifndef HAVE_BZERO
#define bzero(s,n) ((void)memset((s),0,(n)))
#else
# ifndef HAVE_BZERO_DECL
extern void bzero(void *s, size_t n);
# endif
#endif
#ifndef HAVE_CLOSELOG_DECL
extern void closelog(void);
#endif
#ifndef HAVE_CONNECT_DECL
extern int connect(int s, struct sockaddr *name, socklen_t_equiv namelen);
#endif
#ifndef HAVE_FCLOSE_DECL
extern int fclose(FILE *stream);
#endif
#ifndef HAVE_FFLUSH_DECL
extern int fflush(FILE *stream);
#endif
#ifndef HAVE_FPRINTF_DECL
extern int fprintf(FILE *stream, const char *format, ...);
#endif
#ifndef HAVE_FPUTC_DECL
extern int fputc(int c, FILE *stream);
#endif
#ifndef HAVE_FPUTS_DECL
extern int fputs(const char *s, FILE *stream);
#endif
#ifndef HAVE_FREAD_DECL
extern size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
#endif
#ifndef HAVE_FSEEK_DECL
extern int fseek(FILE *stream, long offset, int ptrname);
#endif
#ifndef HAVE_FWRITE_DECL
extern size_t fwrite(const void *ptr, size_t size, size_t nitems,
FILE *stream);
#endif
#ifndef HAVE_GETHOSTNAME_DECL
extern int gethostname(char *name, int namelen);
#endif
#ifndef HAVE_GETOPT_DECL
extern char *optarg;
extern int getopt(int argc, char * const *argv, const char *optstring);
#endif
/* AIX #defines getpeername, and provides a prototype for the alternate name */
#if !defined(HAVE_GETPEERNAME_DECL) && !defined(getpeername)
extern int getpeername(int s, struct sockaddr *name, socklen_t_equiv *namelen);
#endif
/* AIX #defines getsockname, and provides a prototype for the alternate name */
#if !defined(HAVE_GETSOCKNAME_DECL) && !defined(getsockname)
extern int getsockname(int s, struct sockaddr *name, socklen_t_equiv *namelen);
#endif
#ifndef HAVE_GETSOCKOPT_DECL
extern int getsockopt(int s, int level, int optname, char *optval,
socklen_t_equiv *optlen);
#endif
#ifndef HAVE_INITGROUPS
# define initgroups(name,basegid) 0
#else
# ifndef HAVE_INITGROUPS_DECL
extern int initgroups(const char *name, gid_t basegid);
# endif
#endif
#ifndef HAVE_IOCTL_DECL
extern int ioctl(int fildes, int request, ...);
#endif
#ifndef isnormal
#ifndef HAVE_ISNORMAL
#define isnormal(f) (((f) < 0.0) || ((f) > 0.0))
#endif
#endif
#ifndef HAVE_LISTEN_DECL
extern int listen(int s, int backlog);
#endif
#ifndef HAVE_LSTAT_DECL
extern int lstat(const char *path, struct stat *buf);
#endif
#ifndef HAVE_MALLOC_DECL
extern void *malloc (size_t size);
#endif
#ifndef HAVE_MEMMOVE_DECL
#ifdef HAVE_MEMMOVE
extern void *memmove(void *to, const void *from, size_t n);
#else
extern char *memmove(char *to, /*const*/ char *from, size_t n);
#endif
#endif
#ifndef HAVE_MEMSET_DECL
extern void *memset(void *s, int c, size_t n);
#endif
#ifndef HAVE_MKTEMP_DECL
extern char *mktemp(char *template);
#endif
#ifndef HAVE_MKSTEMP_DECL
extern int mkstemp(char *template);
#endif
#ifndef HAVE_MKTIME_DECL
extern time_t mktime(struct tm *timeptr);
#endif
#ifndef HAVE_OPENLOG_DECL
#ifdef LOG_AUTH
extern void openlog(const char *ident, int logopt, int facility);
#else
extern void openlog(const char *ident, int logopt);
#endif
#endif
#ifndef HAVE_PCLOSE_DECL
extern int pclose(FILE *stream);
#endif
#ifndef HAVE_PERROR_DECL
extern void perror(const char *s);
#endif
#ifndef HAVE_PRINTF_DECL
extern int printf(const char *format, ...);
#endif
#ifndef HAVE_PUTS_DECL
extern int puts(const char *s);
#endif
#ifndef HAVE_REALLOC_DECL
extern void *realloc(void *ptr, size_t size);
#endif
/* AIX #defines recvfrom, and provides a prototype for the alternate name */
#if !defined(HAVE_RECVFROM_DECL) && !defined(recvfrom)
extern int recvfrom(int s, char *buf, int len, int flags,
struct sockaddr *from, socklen_t_equiv *fromlen);
#endif
#ifndef HAVE_REMOVE_DECL
extern int remove(const char *path);
#endif
#ifndef HAVE_RENAME_DECL
extern int rename(const char *old, const char *new);
#endif
#ifndef HAVE_REWIND_DECL
extern void rewind(FILE *stream);
#endif
#ifndef HAVE_RUSEROK_DECL
extern int ruserok(const char *rhost, int suser,
const char *ruser, const char *luser);
#endif
#ifndef HAVE_SELECT_DECL
extern int select(int nfds,
SELECT_ARG_TYPE *readfds,
SELECT_ARG_TYPE *writefds,
SELECT_ARG_TYPE *exceptfds,
struct timeval *timeout);
#endif
#ifndef HAVE_SENDTO_DECL
extern int sendto(int s, const char *msg, int len, int flags,
const struct sockaddr *to, int tolen);
#endif
#ifdef HAVE_SETRESGID
#define setegid(x) setresgid((gid_t)-1,(x),(gid_t)-1)
#ifndef HAVE_SETRESGID_DECL
extern int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
#endif
#else
#ifndef HAVE_SETEGID_DECL
extern int setegid(gid_t egid);
#endif
#endif
#ifdef HAVE_SETRESUID
#define seteuid(x) setresuid((uid_t)-1,(x),(uid_t)-1)
#ifndef HAVE_SETRESUID_DECL
extern int setresuid(uid_t ruid, uid_t euid, uid_t suid);
#endif
#else
#ifndef HAVE_SETEUID_DECL
extern int seteuid(uid_t euid);
#endif
#endif
#ifndef HAVE_SETPGID_DECL
#ifdef HAVE_SETPGID
extern int setpgid(pid_t pid, pid_t pgid);
#endif
#endif
#ifndef HAVE_SETPGRP_DECL
#ifdef SETPGRP_VOID
extern pid_t setpgrp(void);
#else
extern pid_t setpgrp(pid_t pgrp, pid_t pid);
#endif
#endif
#ifndef HAVE_SETSOCKOPT_DECL
extern int setsockopt(int s, int level, int optname,
const char *optval, int optlen);
#endif
#ifdef HAVE_SHMGET
#ifndef HAVE_SHMAT_DECL
extern void *shmat(int shmid, const SHM_ARG_TYPE *shmaddr, int shmflg);
#endif
#ifndef HAVE_SHMCTL_DECL
extern int shmctl(int shmid, int cmd, struct shmid_ds *buf);
#endif
#ifndef HAVE_SHMDT_DECL
extern int shmdt(SHM_ARG_TYPE *shaddr);
#endif
#ifndef HAVE_SHMGET_DECL
extern int shmget(key_t key, size_t size, int shmflg);
#endif
#endif
#ifndef HAVE_SNPRINTF_DECL
int snprintf(char *buf, size_t len, const char *format,...)
G_GNUC_PRINTF(3,4);
#endif
#ifndef HAVE_VSNPRINTF_DECL
int vsnprintf(char *buf, size_t len, const char *format, va_list ap);
#endif
#ifndef HAVE_SOCKET_DECL
extern int socket(int domain, int type, int protocol);
#endif
#ifndef HAVE_SOCKETPAIR_DECL
extern int socketpair(int domain, int type, int protocol, int sv[2]);
#endif
#ifndef HAVE_SSCANF_DECL
extern int sscanf(const char *s, const char *format, ...);
#endif
#ifndef HAVE_STRCASECMP_DECL
extern int strcasecmp(const char *s1, const char *s2);
#endif
#ifndef HAVE_STRERROR_DECL
extern char *strerror(int errnum);
#endif
#ifndef HAVE_STRFTIME_DECL
extern size_t strftime(char *s, size_t maxsize, const char *format,
const struct tm *timeptr);
#endif
#ifndef HAVE_STRNCASECMP_DECL
extern int strncasecmp(const char *s1, const char *s2, int n);
#endif
#ifndef HAVE_SYSLOG_DECL
extern void syslog(int priority, const char *logstring, ...)
G_GNUC_PRINTF(2,3);
#endif
#ifndef HAVE_SYSTEM_DECL
extern int system(const char *string);
#endif
#ifndef HAVE_TIME_DECL
extern time_t time(time_t *tloc);
#endif
#ifndef HAVE_TOLOWER_DECL
extern int tolower(int c);
#endif
#ifndef HAVE_TOUPPER_DECL
extern int toupper(int c);
#endif
#ifndef HAVE_UNGETC_DECL
extern int ungetc(int c, FILE *stream);
#endif
#ifndef HAVE_VFPRINTF_DECL
extern int vfprintf(FILE *stream, const char *format, va_list ap);
#endif
#ifndef HAVE_VPRINTF_DECL
extern int vprintf(const char *format, va_list ap);
#endif
/* these system headers are added by gnulib if they
* do not exist */
#include "netdb.h"
#include "arpa/inet.h"
/* gnulib-only includes */
#include "safe-read.h"
#include "full-read.h"
#include "full-write.h"
#if !defined(S_ISCHR) && defined(_S_IFCHR) && defined(_S_IFMT)
#define S_ISCHR(mode) (((mode) & _S_IFMT) == _S_IFCHR)
#endif
#if !defined(S_ISREG) && defined(_S_IFREG) && defined(_S_IFMT)
#define S_ISREG(mode) (((mode) & _S_IFMT) == _S_IFREG)
#endif
#ifndef HAVE_WAITPID
#ifdef HAVE_WAIT4
#define waitpid(pid,status,options) wait4(pid,status,options,0)
#else
extern pid_t waitpid(pid_t pid, amwait_t *stat_loc, int options);
#endif
#endif
#ifndef HAVE_WRITEV_DECL
extern ssize_t writev(int fd, const struct iovec *iov, int iovcnt);
#endif
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
#endif
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
#ifndef STDERR_FILENO
#define STDERR_FILENO 2
#endif
/* S_ISDIR is not defined on Nextstep */
#ifndef S_ISDIR
#if defined(_S_IFMT) && defined(_S_IFDIR)
#define S_ISDIR(mode) (((mode) & (_S_IFMT)) == (_S_IFDIR))
#else
#error Don t know how to define S_ISDIR
#endif
#endif
#if SIZEOF_SIZE_T == SIZEOF_INT
# define SIZE_T_ATOI (size_t)atoi
# ifndef SIZE_MAX
# define SIZE_MAX G_MAXUINT
# endif
#else
# define SIZE_T_ATOI (size_t)atol
# ifndef SIZE_MAX
# define SIZE_MAX ULONG_MAX
# endif
#endif
#if SIZEOF_SSIZE_T == SIZEOF_INT
# define SSIZE_T_ATOI (ssize_t)atoi
# ifndef SSIZE_MAX
# define SSIZE_MAX INT_MAX
# endif
# ifndef SSIZE_MIN
# define SSIZE_MIN INT_MIN
# endif
#else
# define SSIZE_T_ATOI (ssize_t)atol
# ifndef SSIZE_MAX
# define SSIZE_MAX LONG_MAX
# endif
# ifndef SSIZE_MIN
# define SSIZE_MIN LONG_MIN
# endif
#endif
#if SIZEOF_TIME_T == SIZEOF_INT
# define TIME_T_ATOI (time_t)atoi
# ifndef TIME_MAX
# define TIME_MAX G_MAXUINT
# endif
#else
# define TIME_T_ATOI (time_t)atol
# ifndef TIME_MAX
# define TIME_MAX ULONG_MAX
# endif
#endif
#if SIZEOF_OFF_T > SIZEOF_LONG
# ifdef HAVE_ATOLL
# define OFF_T_ATOI (off_t)atoll
# else
# define OFF_T_ATOI (off_t)atol
# endif
# ifdef HAVE_STRTOLL
# define OFF_T_STRTOL (off_t)strtoll
# else
# define OFF_T_STRTOL (off_t)strtol
# endif
#else
# if SIZEOF_OFF_T == SIZEOF_LONG
# define OFF_T_ATOI (off_t)atol
# define OFF_T_STRTOL (off_t)strtol
# else
# define OFF_T_ATOI (off_t)atoi
# define OFF_T_STRTOL (off_t)strtol
# endif
#endif
#define BIND_CYCLE_RETRIES 120 /* Total of 30 minutes */
#ifndef NI_MAXHOST
#define NI_MAXHOST 1025
#endif
typedef enum {
KENCRYPT_NONE, /* krb5 encryption not enabled */
KENCRYPT_WILL_DO, /* krb5 encryption will be enabled once amanda
protocol stream is closed */
KENCRYPT_YES /* krb5 encryption enabled on all stream */
} kencrypt_type;
#define DUMP_LEVELS 400
/* Constants to define the number of pre-opened pipes between amandad and
* its services */
/* If you change these, change them in perl/Amanda/Constants.pm.in.src, too */
#define DATA_FD_COUNT 4 /* number of general-use pipes */
#define DATA_FD_OFFSET 150 /* Don't change it */
#endif /* !AMANDA_H */