diff include/dcc_defs.h @ 0:c7f6b056b673

First import of vendor version
author Peter Gervai <grin@grin.hu>
date Tue, 10 Mar 2009 13:49:58 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/dcc_defs.h	Tue Mar 10 13:49:58 2009 +0100
@@ -0,0 +1,786 @@
+/* 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 */