view include/dcc_defs.h @ 3:b689077d4918

Ignore old patches
author Peter Gervai <grin@grin.hu>
date Tue, 10 Mar 2009 14:31:24 +0100
parents c7f6b056b673
children
line wrap: on
line source

/* Distributed Checksum Clearinghouse
 *
 * common definitions internal to client libraries and servers
 *
 * Copyright (c) 2008 by Rhyolite Software, LLC
 *
 * This agreement is not applicable to any entity which sells anti-spam
 * solutions to others or provides an anti-spam solution as part of a
 * security solution sold to other entities, or to a private network
 * which employs the DCC or uses data provided by operation of the DCC
 * but does not provide corresponding data to other users.
 *
 * Permission to use, copy, modify, and distribute this software without
 * changes for any purpose with or without fee is hereby granted, provided
 * that the above copyright notice and this permission notice appear in all
 * copies and any distributed versions or copies are either unchanged
 * or not called anything similar to "DCC" or "Distributed Checksum
 * Clearinghouse".
 *
 * Parties not eligible to receive a license under this agreement can
 * obtain a commercial license to use DCC by contacting Rhyolite Software
 * at sales@rhyolite.com.
 *
 * A commercial license would be for Distributed Checksum and Reputation
 * Clearinghouse software.  That software includes additional features.  This
 * free license for Distributed ChecksumClearinghouse Software does not in any
 * way grant permision to use Distributed Checksum and Reputation Clearinghouse
 * software
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND RHYOLITE SOFTWARE, LLC DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL RHYOLITE SOFTWARE, LLC
 * BE LIABLE FOR ANY SPECIAL, DIRECT, 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.
 *
 * Rhyolite Software DCC 1.3.103-1.309 $Revision$
 */

#ifndef DCC_DEFS_H
#define DCC_DEFS_H

#define DCC_VERSION "1.3.103"

#include "dcc_config.h"

/* work on WIN32 and any reasonable UNIX platform */
#ifdef UNIX
#include <stdarg.h>
#include <stdio.h>			/* for FreeBSD */
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
#undef EX_OK				/* IRIX defines EX_OK in unistd.h */
#include <limits.h>			/* for FreeBSD */
#include <netdb.h>
#include <netinet/in.h>
#include <sys/param.h>			/* for FreeBSD */
#include <sys/socket.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>
#else /* !UNIX or DCC_WIN32 */
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <winerror.h>
#include <limits.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <io.h>

typedef unsigned int	u_int32_t;
typedef signed int	int32_t;
typedef unsigned short	u_int16_t;
#endif /* !UNIX or DCC_WIN32 */

/* even some UNIX systems have ancient, unusable versions of sysexits.h */
#include "sendmail-sysexits.h"

/* use kludge file if asked */
#ifdef NEED_KLUDGE_H
#include "kludge.h"
#endif

#ifdef NEED_STRINGS_H
#include <strings.h>
#endif

#if !defined(DCC_HAVE_U_INT32_T)
#define u_int32_t uint32_t
#define u_int16_t uint16_t
#endif
#if !defined(DCC_HAVE_U_INT64_T)
#define u_int64_t uint64_t
#endif

#ifdef HAVE_GCC_ATTRIBUTES
#define UATTRIB __attribute__((unused))
#define PATTRIB(f,l) __attribute__((format (printf,f,l)))
#define NRATTRIB __attribute((__noreturn__))
#else
#define UATTRIB
#define PATTRIB(f,l)
#define NRATTRIB
#endif

#ifndef HAVE_GCC_INLINE
#define inline
#endif

typedef char DCC_PASSWD[32];
#define DCC_PASSWD_PAT "%.32s"

typedef char DCC_EMSG[120];

/* deal with ancient UNIX */
#ifndef STDIN_FILENO
#define STDIN_FILENO 0
#endif
#ifndef STDOUT_FILENO
#define STDOUT_FILENO 1
#endif
#ifndef STDERR_FILENO
#define STDERR_FILENO 2
#endif

#ifdef UNIX
#ifndef MAP_FAILED
#define MAP_FAILED ((void *)-1)
#endif
#ifdef HAVE_OLD_MSYNC
#define MSYNC(addr,len,flags) msync((void *)(addr),(len))
#else
#define MSYNC(addr,len,flags) msync((void *)(addr),(len),(flags))
#endif

#ifndef FD_CLOEXEC
#define FD_CLOEXEC 1
#endif

#define WIN32_SOC_CAST

typedef int SOCKET;
#define INVALID_SOCKET (-1)
#define SOCKET_ERROR (-1)
#define WSAAPI
#define closesocket close
#define ERROR_STR() ERROR_STR1(errno)
#define ERROR_STR1(e) strerror(e)
/* at least some filters including IPFW say EACCES on hits,
 * so treat EACCES like Unreachables */
#define UNREACHABLE_ERRORS() (errno == ECONNREFUSED		    \
			      || errno == EHOSTUNREACH		    \
			      || errno == ENETUNREACH		    \
			      || errno == EHOSTDOWN		    \
			      || errno == ENETDOWN		    \
			      || errno == EACCES)
#define DCC_SELECT_NERROR() (errno == EINTR || errno == EAGAIN)
/* EWOULDBLOCK and EAGAIN differ on HP-UX */
#define DCC_BLOCK_ERROR() (errno == EWOULDBLOCK || errno == EAGAIN)

/* PATH_MAX is an over generous 1024 on many UNIX varients,
 * but an incredible, ridiculous waste of 4096 on some Linux flavors.
 * Each of the hundreds of dccm and dccifd recipient structures contain
 * 2 paths.  Then there are the 8 paths in .dccw files.  So this matters . */
typedef char DCC_PATH[768];

#else /* !UNIX or DCC_WIN32 */
extern void win32_init(void);

#undef errno
#define errno WSAGetLastError()
#define h_errno WSAGetLastError()
#define ERROR_STR() ERROR_STR1(errno)
#define ERROR_STR1(e) ws_strerror(e)
const char *ws_strerror(int);
#define UNREACHABLE_ERRORS() ((errno) == WSAECONNREFUSED	\
			      || (errno) == WSAEHOSTUNREACH	\
			      || (errno) == WSAENETUNREACH	\
			      || (errno) == WSAEHOSTDOWN	\
			      || (errno) == WSAENETDOWN)
#define DCC_SELECT_NERROR() (errno == WSAEINTR)
#define DCC_BLOCK_ERROR() (errno == WSAEWOULDBLOCK || errno == WSAEINTR)
#define EADDRINUSE	WSAEADDRINUSE

typedef char DCC_PATH[MAX_PATH+1];

#define MAXHOSTNAMELEN   256

/* Microsoft sendto(), recvfrom() want char *buffers */
#define WIN32_SOC_CAST (char *)

/* some WIN32 versions lack snprintf() */
#define snprintf dcc_snprintf
extern int dcc_snprintf(char *, int, const char *, ...);
#define vsnprintf dcc_vsnprintf
extern int dcc_vsnprintf(char *, int, const char *, va_list);

extern char *optarg;
extern int optind, opterr, optopt;
extern int getopt(int, char * const [], const char *);

#define strcasecmp stricmp
#define strncasecmp strnicmp
extern int getpid(void);
#define usleep(us) Sleep((us+500)/1000)

#define LOG_ERR	    0
#define LOG_MAIL    0
#define LOG_NOTICE  0
#define LOG_PID	    0
extern void openlog(const char *, int, int);
extern void syslog(int, const char *, ...);
extern void closelog(void);

struct timezone {
    int     tz_minuteswest;		/* minutes west of Greenwich */
    int     tz_dsttime;			/* type of dst correction */
};
extern int gettimeofday(struct timeval *, struct timezone *);

#ifndef HAVE_PID_T
#undef pid_t
#define pid_t int
#endif

/* FlushViewOfFile() on Win98 sometimes returns 0 with GetLastError()==0 */
#define MSYNC(addr,len,flags) (FlushViewOfFile(addr,0), 0)

#define R_OK	04
#define W_OK	02
#ifndef S_ISDIR
#define S_ISDIR(mode) (mode & _S_IFDIR)
#endif

extern u_char win32_lock(HANDLE, DWORD);
extern u_char win32_unlock(HANDLE);

extern void win32_unmap(HANDLE *, void *, const char *);
extern void *win32_map(DCC_EMSG, HANDLE *, const char *, int, int);
#endif /* !UNIX or DCC_WIN32 */


#ifndef HAVE_DAEMON
#define daemon dcc_daemon
extern int daemon(int, int);
#endif
extern void dcc_daemon_restart(const char *, void(*)(void));
extern void dcc_daemon_su(const char *);
extern void dcc_pidfile(DCC_PATH, const char *);

/* AIX is missing some prototypes or has them #ifdef'ed with strange switches */
#ifdef _AIX41
#include <sys/select.h>
typedef unsigned long long int uint64_t;
typedef unsigned int uint32_t;
typedef int int32_t;
typedef unsigned short uint16_t;

extern void openlog(const char *, int, int);
extern int snprintf(char *, int, const char *, ...);
extern int vsnprintf(char *, int, const char *, const char *, ...);
extern int seteuid(uid_t);
extern int flock(int, int);
#define	AF_LOCAL AF_UNIX
#endif /* _AIX41 */

#ifdef __hpux
#define seteuid(euid) setresuid(-1,euid,-1)
#define setegid(egid) setresgid(-1,egid,-1)
#endif /* __hpux */


#define DCC_MAXDOMAINLEN   256		/* limit host names; with \0 */

/* 4.4BSD sockets */
#ifdef HAVE_SA_LEN
#define DCC_SU_LEN(s) ((s)->sa.sa_len)
#else
#define DCC_SU_LEN(s) (((s)->sa.sa_family == AF_INET)	\
		       ? sizeof((s)->ipv4) : sizeof((s)->ipv6))
#endif
#ifdef HAVE_SOCKLEN_T
/* use #define to avoid problems with SOCKS prototypes */
#define DCC_SOCKLEN_T socklen_t
#else
#define DCC_SOCKLEN_T int
#endif
#if !defined(HAVE_AF_LOCAL) && !defined(AF_LOCAL)
#define AF_LOCAL AF_UNIX
#endif

/* these are needed even when IPV6 is available to handle old map file
 * formats in dcc_clnt.h */
struct dcc_in6_addr {
    u_int32_t dcc_s6_addr32[4];
};
struct dcc_sockaddr_in6 {
    u_char	sin6_len;
    u_char	sin6_family;
    u_int16_t	sin6_port;
    u_int32_t	sin6_flowinfo;
    struct dcc_in6_addr sin6_addr;
};
/* define in6_addr here after u_int32_t has been seen in sys/types.h */
#ifdef NO_IPV6
#undef in6_addr
#define in6_addr dcc_in6_addr		/* defend against lurking definitions */
#undef s6_addr32
#define s6_addr32 dcc_s6_addr32
#define sockaddr_in6 dcc_sockaddr_in6	/* defend against lurking definitions */
#endif /* NO_IPV6 */


#include "dcc_proto.h"


/* see if an address is in an IPv6 CIDR block */
#define DCC_IN_BLOCK(a,b,m) ((((a).s6_addr32[3] & (m).s6_addr32[3])	\
			      == (b).s6_addr32[3])			\
			     && (((a).s6_addr32[2] & (m).s6_addr32[2])	\
				 == (b).s6_addr32[2])			\
			     && (((a).s6_addr32[1] & (m).s6_addr32[1])	\
				 == (b).s6_addr32[1])			\
			     && (((a).s6_addr32[0] & (m).s6_addr32[0])	\
				 == (b).s6_addr32[0]))


/* puzzle out something for s6_addr32 */
#if !defined(s6_addr32) && defined(CONF_S6_ADDR32)
#define s6_addr32 CONF_S6_ADDR32
#endif

#ifdef NO_AF_INET6
#define AF_INET6 24
#endif

#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
#endif
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
#endif

#define MAXPORTNAMELEN	64

#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#endif

#define DCC_SU_EQ(a,b) ((a)->sa.sa_family == (b)->sa.sa_family		\
			&& (((a)->sa.sa_family == AF_INET)		\
			    ? ((a)->ipv4.sin_addr.s_addr		\
			       == (b)->ipv4.sin_addr.s_addr)		\
			    : !memcmp(&(a)->ipv6.sin6_addr,		\
				      &(b)->ipv6.sin6_addr,		\
				      sizeof((a)->ipv6.sin6_addr))))

/* zero port number if sa_family is AF_UNSPEC */
#define DCC_SU_PORT(su) ((su)->sa.sa_family == AF_INET			\
			 ? (su)->ipv4.sin_port				\
			 : (su)->sa.sa_family == AF_INET6		\
			 ? (su)->ipv6.sin6_port				\
			 : 0)

/* use IPv4 port number if sa_family is AF_UNSPEC */
#define DCC_SU_PORTP(su) ((su)->sa.sa_family == AF_INET6		\
			  ? &(su)->ipv6.sin6_port			\
			  : &(su)->ipv4.sin_port)

#define DCC_IN6_ADDR_V4MAPPED(ap) ((ap)->s6_addr32[0] == 0		\
				   && (ap)->s6_addr32[1] == 0		\
				   && (ap)->s6_addr32[2] == ntohl(0x0000ffff))

#define DCC_IN6_ADDR_V4COMPAT(ap) ((ap)->s6_addr32[0] == 0		\
				   && (ap)->s6_addr32[1] == 0		\
				   && (ap)->s6_addr32[2] == 0		\
				   && (ap)->s6_addr32[3] == 0		\
				   && (ap)->s6_addr32[3] == ntohl(1))



/* printf patterns for 64-bit values */
#ifdef HAVE_64BIT_LONG
#define LL_PAT	    "l"
#else
#define LL_PAT	    "ll"
#endif
#define	L_HPAT	    "%#"LL_PAT"x"
#define	L_HWPAT(w)  "%#"#w LL_PAT"x"	/* hex with specified width */
#define L_DPAT	    "%"LL_PAT"d"
#define L_DWPAT(w)  "%"#w LL_PAT"d"	/* decimal with specified width */

/* printf pattern for size_t and off_t */
#ifdef HAVE_BIG_FILES
#define OFF_HPAT    L_HPAT
#define OFF_DPAT    L_DPAT
#else
#define OFF_HPAT    "%#lx"
#define OFF_DPAT    "%ld"
#endif

#define DIM(_a)	    ((int)(sizeof(_a) / sizeof((_a)[0])))
#define LAST(_a)    (&(_a)[DIM(_a)-1])
/* abbreviation to silence common compiler warnings */
#define ISZ(_s)	    ((int)sizeof(_s))

#ifdef HAVE_STRLCPY
#define STRLCPY(d,s,lim) strlcpy(d,s,lim)
#else
#define STRLCPY(d,s,lim) ((lim)<=0 ? d		\
			  : ((d)[(lim)-1] = '\0', strncpy(d,s,(lim)-1)))
#endif
#define BUFCPY(d,s) STRLCPY(d,s,sizeof(d))
#ifdef HAVE_STRLCAT
#define STRLCAT(d,s,lim) strlcat(d,s,lim)
#else
#define STRLCAT(d,s,lim) dcc_strlcat(d,s,lim)
extern int dcc_strlcat(char *, const char *, int);
#endif

#define LITZ(_s)	((int)sizeof(_s)-1)
#define CLITCMP(b,_s)	strncasecmp(b, _s, LITZ(_s))
#define LITCMP(b,_s)	strncmp(b, _s, LITZ(_s))


#ifndef HAVE___PROGNAME
#define __progname dcc_progname
#endif

#undef max
#define max(a,b) ((a) > (b) ? (a) : (b))
#undef min
#define min(a,b) ((a) < (b) ? (a) : (b))

/* Is it time or has the local clock been changed?
 *	Is the clock after the target date or earlier than the original date? */
#define DCC_IS_TIME(now,tgt,lim) ((now) >= (tgt) || (now)+(lim) < (tgt))

#define DCC_ADJ_TIMER(now,tgt,lim,new_lim) {				\
	if (*(tgt) > (now)+(new_lim))					\
		*(tgt) = (now)+(new_lim);				\
	*(lim) = (new_lim);						\
}

#define FOREVER_SECS	1000
#define FOREVER_US	(FOREVER_SECS*DCC_US)
#define us2tv(tvp,us)	((tvp)->tv_sec = (us) / DCC_US,			\
			  (tvp)->tv_usec = (us) % DCC_US)
extern time_t tv_diff2us(const struct timeval *, const struct timeval *);
extern void tv_add(struct timeval *,
		   const struct timeval *, const struct timeval *);
extern void tv_add_us(struct timeval *, time_t);

/* prefer gmtime_r even where we don't really care */
#ifdef HAVE_GMTIME_R
#define DCC_GMTIME_R(src,tgt) gmtime_r(src,tgt)
#else
#define DCC_GMTIME_R(src,tgt) memcpy(tgt,gmtime(src),sizeof(struct tm))
#endif

#define DCC_WHITESPACE " \t\n\r"

/* ctype() is now a slow mess that does not give constant results on all
 * systems */
#define DCC_IS_WHITE(c) ((c) == ' ' || (c) == '\t' || (c) == '\r' || (c)== '\n')
#define DCC_IS_UPPER(c) ((c) >= 'A' && (c) <= 'Z')
#define DCC_IS_LOWER(c) ((c) >= 'a' && (c) <= 'z')
#define DCC_TO_LOWER(c) (DCC_IS_UPPER(c) ? ((c) + ('a'-'A')) : (c))
#define DCC_TO_UPPER(c) (DCC_IS_LOWER(c) ? ((c) - ('a'-'A')) : (c))

typedef union {
    struct sockaddr sa;
    struct sockaddr_in ipv4;
    struct sockaddr_in6 ipv6;
} DCC_SOCKU;

/* we cannot always use DCC_SOCKU because sizeof(sockaddr_in6) is not defined
 * on systems without IPv6 and when they do get IPv6, the native sockaddr_in
 * often differs in size from the work-around version in the DCC source */
typedef struct {
    union {
	struct in_addr v4;
	struct in6_addr v6;
    } u;
    u_int16_t	port;
    u_char	family;
} DCC_IP;

#ifdef HAVE_RSENDTO
extern int Rconnect(int, const struct sockaddr *, DCC_SOCKLEN_T);
extern ssize_t Rsend(int, const void *, size_t, int);
extern ssize_t Rsendto(int, const void *, size_t, int,
		       const struct sockaddr *, size_t);
extern ssize_t Rrecv(int, void *, size_t, int);
extern ssize_t Rrecvfrom(int, void *, size_t, int,
			 struct sockaddr *, DCC_SOCKLEN_T *);
extern struct hostent *Rgethostbyname(const char *);
#else
#define Rconnect    connect
#define Rsend	    send
#define Rsendto	    sendto
#define Rrecv	    recv
#define Rrecvfrom   recvfrom
#define Rgethostbyname gethostbyname
#endif

/* use very old fashioned gethostbyname() if we are not doing any IPv6 */
#ifdef NO_IPV6
#undef HAVE_GETIPNODEBYNAME
#undef HAVE_GETADDRINFO
#endif

#if !defined(HAVE_GETIPNODEBYNAME) || !defined(HAVE_FREEHOSTENT) || !defined(HAVE_GETIPNODEBYADDR)
#undef HAVE_GETIPNODEBYNAME
#endif

#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_FREEADDRINFO) || !defined(HAVE_GAI_STRERROR) || !defined(HAVE_GETNAMEINFO)
#undef HAVE_GETADDRINFO
#endif

/* prefer getaddrinfo() for IPv6 resolution */
#if defined(HAVE_GETADDRINFO)
#define USE_GETADDRINFO
#undef HAVE_GETIPNODEBYNAME
#endif
#ifdef HAVE_GETIPNODEBYNAME
#define USE_GETIPNODEBYNAME
#undef HAVE_GETADDRINFO
#endif

#undef DCC_HSTRERROR
#ifdef UNIX
#ifdef USE_GETADDRINFO
#define DCC_HSTRERROR(e) gai_strerror(e)
#endif
#if !defined(DCC_HSTRERROR) && defined(HAVE_HSTRERROR)
#define DCC_HSTRERROR(e) hstrerror(e)
#endif
#ifndef DCC_HSTRERROR
#define DCC_HSTRERROR(e) dcc_hstrerror(e)
#endif
#else /* !UNIX or DCC_WIN32 */
#define DCC_HSTRERROR(e) ws_strerror(e)
#endif /* !UNIX or DCC_WIN32 */


#ifndef HAVE_POLL
#undef USE_POLL
#endif

#define LOGBUF_SIZE	(DCC_MAXDOMAINLEN*2)

extern int dcc_ex_code;			/* not thread safe */
extern void dcc_pemsg(int, DCC_EMSG, const char *, ...) PATTRIB(3,4);
extern void dcc_vpemsg(int, DCC_EMSG, const char *, va_list);
#define DCC_FNM_LNO_PAT " in line %d of %s"
typedef struct {
	char b[sizeof(DCC_PATH)+sizeof(DCC_FNM_LNO_PAT)+8];
} DCC_FNM_LNO_BUF;
extern const char *fnm_lno(DCC_FNM_LNO_BUF *, const char *, int);


#define DCC_MAX_HDR_LINE    78		/* by RFC 2822 */
#define DCC_MAX_XHDR_LEN    240		/* largest possible X-DCC header */
typedef struct {
    u_int	start_len;		/* length of start up to ':' */
    u_int	used;			/* bytes of buffer used */
    int		col;			/* current column */
    char	buf[DCC_MAX_XHDR_LEN];
} DCC_HEADER_BUF;

#define DCC_MAP_NM_DEF	    "map"


#ifndef HAVE_PTHREADS
#undef HAVE_HELPERS
#else
#define HAVE_HELPERS 1
#endif


typedef void(*LOG_WRITE_FNC)(void *context, const char *buf, u_int buflen);

extern void dcc_sign(const char *, int, void *, u_int);
extern u_char dcc_ck_signature(const char *, int, const void *, u_int);

extern DCC_PATH dcc_homedir;
extern u_char fnm2rel(DCC_PATH, const char *, const char *);
extern void fnm2rel_good(DCC_PATH, const char *, const char *);
extern u_char fnm2abs(DCC_PATH, const char *, const char *);
extern const char *fnm2abs_err(DCC_PATH, const char *);
extern const char *path2fnm(const char *);
extern u_char dcc_cdhome(DCC_EMSG, const char *, u_char);

extern uid_t dcc_real_uid, dcc_effective_uid;
extern gid_t dcc_real_gid, dcc_effective_gid;
extern void dcc_get_priv(void);
extern u_char dcc_get_priv_home(const char *);
extern void dcc_rel_priv(void);
extern void dcc_init_priv(void);
extern u_char dcc_ck_private(DCC_EMSG, struct stat *, const char *, int);
extern int dcc_lock_open(DCC_EMSG, const char *, int, u_char, int, u_char *);
# define DCC_LOCK_OPEN_NOWAIT	0x1	/* don't wait to get lock */
# define DCC_LOCK_OPEN_NOLOCK	0x2	/* already locked */
# define DCC_LOCK_OPEN_SHARE	0x4
#define DCC_LOCK_ALL_FILE   (-1)
extern u_char dcc_unlock_fd(DCC_EMSG, int, int, const char *, const char *);
extern u_char dcc_exlock_fd(DCC_EMSG, int, int, int,
			    const char *, const char *);
extern u_char dcc_set_mtime(DCC_EMSG, const char *, int,
			    const struct timeval *);

extern DCC_PATH dcc_main_logdir;
extern void tmp_path_init(const char *, const char *);
#define	DCC_TMP_LOG_PREFIX "/tmp."	/* must be the same length */
#define	DCC_FIN_LOG_PREFIX "/msg."
#define DCC_MKSTEMP_LEN 6		/* characters added by dcc_mkstemp() */
#define DCC_MKSTEMP_LEN_STR "6"
extern int dcc_mkstemp(DCC_EMSG, char *, int, char *, int,
		       const char *, const char *, const char *, u_char, int);
extern u_char dcc_main_logdir_init(DCC_EMSG, const char *);
typedef enum {				/* type of log subdirector */
    LOG_MODE_FLAT,			/*	logdir/ */
    LOG_MODE_DAY,			/*	logdir/ddd/ */
    LOG_MODE_HOUR,			/*	logdir/ddd/hh/ */
    LOG_MODE_MINUTE			/*	logdir/ddd/hh/mm/ */
} LOG_MODE;
extern int dcc_log_open(DCC_EMSG, DCC_PATH, char *, int,
			const char *, const char *, const char *, LOG_MODE);
extern int dcc_main_log_open(DCC_EMSG, DCC_PATH log_path, char *, int);
extern u_char dcc_log_keep(DCC_EMSG, char *);
extern u_char dcc_log_close(DCC_EMSG, const char *, int,
			    const struct timeval *);
#define DCC_LOG_DATE_PAT "VERSION: 3\nDATE: %s"
#define DCC_LOG_DATE_FMT "%x %X %Z"
#define DCC_LOG_MSG_SEP "\n### end of message body ########################\n"
#define DCC_LOG_TRN_MSG0 "### log truncated ######################"
#define DCC_LOG_TRN_MSG "\n"DCC_LOG_TRN_MSG0"\n"
#define DCC_LOG_TRN_MSG_CR "\r\n"DCC_LOG_TRN_MSG0"\r\n"
typedef struct {
    int	    len;
    char    buf[500];
} EARLY_LOG;
extern int dcc_vearly_log(EARLY_LOG *, const char *, va_list);
extern const char *optopt2str(int);


#define DCC_US	(1000*1000)

extern const struct tm *dcc_localtime(time_t, struct tm *);
#ifndef HAVE_LOCALTIME_R
extern void dcc_localtime_lock(void);
extern void dcc_localtime_unlock(void);
#endif
const char *dcc_time2str(char *, size_t, const char *, time_t);
#ifdef HAVE_TIMEGM
#define DCC_TIMEGM(tm) timegm(tm)
#else
#ifdef HAVE_ALTZONE
#define DCC_TIMEGM(tm) ((tm)->tm_isdst=-1, mktime(tm) - altzone)
#else
#define DCC_TIMEGM(tm) ((tm)->tm_isdst=-1, mktime(tm))
#endif
#endif

extern int dcc_get_secs(const char *, const char **, int, int, int);
#define DCC_MAX_SECS 0x7fffffff
extern u_int dcc_get_port(DCC_EMSG, const char *, u_int, const char *, int);
#define DCC_GET_PORT_INVALID    0x10000
extern u_char dcc_host_locked;
#define MAX_DCC_HOSTADDRS 20
extern DCC_SOCKU dcc_hostaddrs[MAX_DCC_HOSTADDRS];
extern char dcc_host_canonname[DCC_MAXDOMAINLEN];
extern DCC_SOCKU *dcc_hostaddrs_end;
extern void dcc_host_lock(void);
extern void dcc_host_unlock(void);
extern u_char dcc_get_host(const char *, u_char, int *);
extern u_char dcc_get_host_SOCKS(const char *, u_char, int *);
extern const char *dcc_hstrerror(int);
extern DCC_SOCKU *dcc_mk_su(DCC_SOCKU *, int, const void *, u_short);
extern u_char dcc_str2ip(DCC_SOCKU *, const char *);
extern void dcc_bits2mask(struct in6_addr *, int);
extern int dcc_str2cidr(DCC_EMSG, struct in6_addr *, struct in6_addr *,
			u_char *, const char *, const char *, int);
extern int dcc_udp_bind(DCC_EMSG, SOCKET *, const DCC_SOCKU *, int *);
extern DCC_CLNT_ID dcc_get_id(DCC_EMSG, const char *, const char *, int);
extern const char *dcc_get_srvr_id(DCC_EMSG, DCC_SRVR_ID *,
				   const char *, const char *,
				   const char *, int);
extern const char *dcc_parse_word(DCC_EMSG, char *, int,
				  const char *, const char *,
				  const char *, int);
extern const char *parse_passwd(DCC_EMSG, DCC_PASSWD, const char *,
				const char *, const char *, int);
extern u_char dcc_ck_word_comma(const char **, const char *);

extern void dcc_ipv4toipv6(struct in6_addr *, const struct in_addr);
extern u_char dcc_ipv6toipv4(struct in_addr *, const struct in6_addr *);
extern void dcc_su2ip(DCC_IP *, const DCC_SOCKU *);
extern u_char dcc_ipv6sutoipv4(DCC_SOCKU *, const DCC_SOCKU *);
extern u_char dcc_ipv4sutoipv6(DCC_SOCKU *, const DCC_SOCKU *);

const char *dcc_trim_ffff(const char *);
#define DCC_SU2STR_SIZE (INET6_ADDRSTRLEN+1+6+1)
extern const char *dcc_ipv4tostr(char *, int, const struct in_addr *);
extern const char *dcc_ipv6tostr(char *, int, const struct in6_addr *);
extern const char *dcc_ipv6tostr2(char *, int, const struct in6_addr *);
const char *dcc_ip2str(char *, int, const DCC_IP *);
extern const char *dcc_su2str(char *, int, const DCC_SOCKU *);
extern const char *dcc_su2str2(char *, int, const DCC_SOCKU *);
extern const char *dcc_su2str3(char *, int, const DCC_SOCKU *, u_short);
extern const char *dcc_su2str_err(const DCC_SOCKU *);
extern const char * dcc_host_portname(char *, int, const char *, const char *);
extern const char *dcc_su2name(char *, int, const DCC_SOCKU *);

extern void clean_stdio(void);
extern u_char dcc_no_syslog;
extern int dcc_error_priority, dcc_trace_priority;
extern u_char dcc_parse_log_opt(const char *);
extern void dcc_syslog_init(u_char, const char *, const char *);
extern DCC_PATH dcc_progname;
extern int dcc_progname_len;
extern void dcc_vfatal_msg(const char *, va_list);
extern int dcc_verror_msg(const char *, va_list);
extern void dcc_error_msg(const char *, ...) PATTRIB(1,2);
extern void dcc_vtrace_msg(const char *, va_list);
extern void dcc_trace_msg(const char *, ...) PATTRIB(1,2);
extern u_char trace_quiet;
extern void quiet_trace_msg(const char *p, ...) PATTRIB(1,2);
#ifndef HAVE_VSYSLOG
#define vsyslog dcc_vsyslog
extern void vsyslog(int, const char *, va_list);
#endif

extern void NRATTRIB dcc_logbad(int, const char *, ...) PATTRIB(2,3);
#define DCC_ASSERT(c) ((c) ? 0 : dcc_logbad(EX_SOFTWARE, #c))

extern const char *id2str(char *, u_int, DCC_CLNT_ID);
extern char *dcc_ck2str(char *, u_int, DCC_CK_TYPES, const DCC_SUM, u_int32_t);
#define DCC_CK2STR_LEN (sizeof(DCC_SUM)*2+sizeof(DCC_SUM)/4+1)
extern const char *dcc_ck2str_err(DCC_CK_TYPES, const DCC_SUM, u_int32_t);
extern char *dcc_tgts2str(char *, u_int, DCC_TGTS, u_char);
extern char *dcc_thold2str(char *, u_int, DCC_CK_TYPES, DCC_TGTS);
extern char *dcc_type2str(char *, u_int, DCC_CK_TYPES,
			  const char *, u_char, u_char);
extern const char *dcc_type2str_err(DCC_CK_TYPES,
				    const char *, u_char, u_char);
#define SET_ALL_THOLDS	(DCC_CK_TYPE_LAST+1)
#define SET_CMN_THOLDS	(SET_ALL_THOLDS+1)
extern DCC_CK_TYPES dcc_str2type_del(const char *, int);
extern DCC_CK_TYPES dcc_str2type_db(const char *, int);
extern DCC_CK_TYPES dcc_str2type_thold(const char *, int);
extern DCC_CK_TYPES dcc_str2type_wf(const char *, int);
extern DCC_TGTS dcc_str2cnt(const char *);

extern const char *dcc_aop2str(char *, int, DCC_AOPS, u_int32_t);
extern const char *dcc_hdr_op2str(char *, int, const DCC_HDR *);
#define DCC_OPBUF 32


#endif /* DCC_DEFS_H */