1 /**************************************************************************************************
2 	$Id: mydnsutil.h,v 1.68 2005/04/28 18:43:46 bboy Exp $
3 
4 	mydnsutil.h: Support library for the MyDNS package.
5 
6 	Copyright (C) 2002-2005  Don Moore <bboy@bboy.net>
7 
8 	This program is free software; you can redistribute it and/or modify
9 	it under the terms of the GNU General Public License as published by
10 	the Free Software Foundation; either version 2 of the License, or
11 	(at Your option) any later version.
12 
13 	This program is distributed in the hope that it will be useful,
14 	but WITHOUT ANY WARRANTY; without even the implied warranty of
15 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 	GNU General Public License for more details.
17 
18 	You should have received a copy of the GNU General Public License
19 	along with this program; if not, write to the Free Software
20 	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 **************************************************************************************************/
22 
23 #ifndef MYDNSUTIL_H
24 #define MYDNSUTIL_H
25 
26 #define _GNU_SOURCE
27 
28 #include <config.h>
29 
30 /* <unistd.h> should be included before any preprocessor test
31    of _POSIX_VERSION.  */
32 #ifdef HAVE_UNISTD_H
33 #	include <unistd.h>
34 #endif /* HAVE_UNISTD_H */
35 
36 #ifdef HAVE_INTTYPES_H
37 #	include <inttypes.h>
38 #endif
39 
40 #include <stdio.h>
41 #include <sys/types.h>
42 
43 #ifdef HAVE_LIMITS_H
44 #	include <limits.h>
45 #endif
46 
47 #ifdef HAVE_STDARG_H
48 #	include <stdarg.h>
49 #endif
50 
51 #include <ctype.h>
52 #include <syslog.h>
53 
54 #ifdef HAVE_LOCALE_H
55 #	include <locale.h>
56 #endif
57 
58 #ifndef HAVE_SETLOCALE
59 #	define setlocale(category,locale) /* empty */
60 #endif
61 
62 /* For gettext (NLS).  */
63 #include "gettext.h"
64 #define _(String) gettext(String)
65 #define N_(String) (String)
66 
67 #ifdef STDC_HEADERS
68 #	define getopt system_getopt
69 #	include <stdlib.h>
70 #	undef getopt
71 #else
72 extern char *getenv ();
73 #endif
74 
75 #include <getopt.h>
76 
77 /* Don't use bcopy!  Use memmove if source and destination may overlap,
78    memcpy otherwise.  */
79 #ifdef HAVE_STRING_H
80 # if !STDC_HEADERS && HAVE_MEMORY_H
81 #  include <memory.h>
82 # endif
83 # include <string.h>
84 #else
85 # include <strings.h>
86 char *memchr ();
87 #endif
88 
89 #if HAVE_SIGNAL_H
90 #	include <signal.h>
91 #endif
92 
93 #if HAVE_TERMIOS_H
94 #	include <termios.h>
95 #endif
96 
97 #include <errno.h>
98 #ifndef errno
99 extern int errno;
100 #endif
101 #ifdef VMS
102 #include <perror.h>
103 #endif
104 
105 #ifndef HAVE_DECL_STRERROR
106 extern char *strerror ();
107 #endif
108 
109 #ifndef HAVE_DECL_STRCASECMP
110 extern int strcasecmp ();
111 #endif
112 
113 #ifndef HAVE_DECL_STRNCASECMP
114 extern int strncasecmp ();
115 #endif
116 
117 #ifndef HAVE_DECL_STRCOLL
118 extern int strcoll ();
119 #endif
120 
121 #include <sys/stat.h>
122 #ifdef STAT_MACROS_BROKEN
123 # undef S_ISDIR
124 #endif
125 #if !defined(S_ISDIR) && defined(S_IFDIR)
126 # define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
127 #endif
128 
129 #ifdef HAVE_SYS_FILE_H
130 #include <sys/file.h>
131 #endif /* HAVE_SYS_FILE_H */
132 
133 #ifndef O_RDONLY
134 /* Since <fcntl.h> is POSIX, prefer that to <sys/fcntl.h>.
135    This also avoids some useless warnings on (at least) Linux.  */
136 #ifdef HAVE_FCNTL_H
137 #include <fcntl.h>
138 #else /* not HAVE_FCNTL_H */
139 #ifdef HAVE_SYS_FCNTL_H
140 #include <sys/fcntl.h>
141 #endif /* not HAVE_SYS_FCNTL_H */
142 #endif /* not HAVE_FCNTL_H */
143 #endif /* not O_RDONLY */
144 
145 #ifdef HAVE_SYS_SOCKET_H
146 #	include <sys/socket.h>
147 #endif
148 
149 #ifdef HAVE_NETINET_IN_H
150 #	include <netinet/in.h>
151 #endif
152 
153 #ifdef HAVE_ARPA_INET_H
154 #	include <arpa/inet.h>
155 #endif
156 
157 #if HAVE_SYS_SOCKIO_H
158 #  include <sys/sockio.h>
159 #endif
160 
161 #if USE_PGSQL
162 #	include <libpq-fe.h>
163 #       include <pgtypes_timestamp.h>
164 
165 #ifdef PGSQL_VERSION
166 #	define  SQL_VERSION_STR	"PostgreSQL " PGSQL_VERSION
167 #else		/* !PGSQL_VERSION */
168 #	if HAVE_PGCONFIG
169 #		include <pg_config.h>
170 #	endif	/* HAVE_PGCONFIG */
171 #		ifdef PG_VERSION
172 #			define  SQL_VERSION_STR	"PostgreSQL " PG_VERSION
173 #		else
174 #			define  SQL_VERSION_STR	"PostgreSQL"
175 #		endif
176 #endif	/* !PGSQL_VERSION */
177 #else		/* !USE_PGSQL (MySQL) */
178 #	include <mysql.h>
179 #	include <errmsg.h>
180 #	define  SQL_VERSION_STR	"MySQL " MYSQL_SERVER_VERSION
181 #endif	/* !USE_PGSQL */
182 
183 
184 /* MS-DOS and similar non-Posix systems have some peculiarities:
185     - they distinguish between binary and text files;
186     - they use both `/' and `\\' as directory separator in file names;
187     - they can have a drive letter X: prepended to a file name;
188     - they have a separate root directory on each drive;
189     - their filesystems are case-insensitive;
190     - directories in environment variables (like INFOPATH) are separated
191         by `;' rather than `:';
192     - text files can have their lines ended either with \n or with \r\n pairs;
193 
194    These are all parameterized here except the last, which is
195    handled by the source code as appropriate (mostly, in info/).  */
196 #ifndef O_BINARY
197 # ifdef _O_BINARY
198 #  define O_BINARY _O_BINARY
199 # else
200 #  define O_BINARY 0
201 # endif
202 #endif /* O_BINARY */
203 
204 #if O_BINARY
205 # include <io.h>
206 # ifdef __MSDOS__
207 #  include <limits.h>
208 #  ifdef __DJGPP__
209 #   define HAVE_LONG_FILENAMES(dir)  (pathconf (dir, _PC_NAME_MAX) > 12)
210 #   define NULL_DEVICE	"/dev/null"
211 #  else  /* !__DJGPP__ */
212 #   define HAVE_LONG_FILENAMES(dir)  (0)
213 #   define NULL_DEVICE	"NUL"
214 #  endif /* !__DJGPP__ */
215 #  define SET_SCREEN_SIZE_HELPER terminal_prep_terminal()
216 #  define DEFAULT_INFO_PRINT_COMMAND ">PRN"
217 # else   /* !__MSDOS__ */
218 #  define setmode(f,m)  _setmode(f,m)
219 #  define HAVE_LONG_FILENAMES(dir)   (1)
220 #  define NULL_DEVICE	"NUL"
221 # endif  /* !__MSDOS__ */
222 # define SET_BINARY(f)  do {if (!isatty(f)) setmode(f,O_BINARY);} while(0)
223 # define FOPEN_RBIN	"rb"
224 # define FOPEN_WBIN	"wb"
225 # define IS_SLASH(c)	((c) == '/' || (c) == '\\')
226 # define HAVE_DRIVE(n)	((n)[0] && (n)[1] == ':')
227 # define IS_ABSOLUTE(n)	(IS_SLASH((n)[0]) || ((n)[0] && (n)[1] == ':'))
228 # define FILENAME_CMP	strcasecmp
229 # define FILENAME_CMPN	strncasecmp
230 # define PATH_SEP	";"
231 # define STRIP_DOT_EXE	1
232 # define DEFAULT_TMPDIR	"c:/"
233 # define PIPE_USE_FORK	0
234 #else  /* not O_BINARY */
235 # define SET_BINARY(f)	(void)0
236 # define FOPEN_RBIN	"r"
237 # define FOPEN_WBIN	"w"
238 # define IS_SLASH(c)	((c) == '/')
239 # define HAVE_DRIVE(n)	(0)
240 # define IS_ABSOLUTE(n)	((n)[0] == '/')
241 # define FILENAME_CMP	strcmp
242 # define FILENAME_CMPN	strncmp
243 # define HAVE_LONG_FILENAMES(dir)   (1)
244 # define PATH_SEP	":"
245 # define STRIP_DOT_EXE	0
246 # ifdef VMS
247 #  define DEFAULT_TMPDIR "sys$scratch:"
248 # else
249 #  define DEFAULT_TMPDIR "/tmp/"
250 # endif
251 # define NULL_DEVICE	"/dev/null"
252 # define PIPE_USE_FORK	1
253 #endif /* not O_BINARY */
254 
255 #if HAVE_TIME_H
256 #	include <time.h>
257 #endif
258 #if HAVE_SYS_TIME_H
259 #	include <sys/time.h>
260 #endif
261 
262 #if HAVE_PWD_H
263 #	include <pwd.h>
264 #endif
265 
266 #if HAVE_POLL_H
267 #	include <poll.h>
268 #else
269 # if HAVE_SYS_SELECT_H
270 #	include <sys/select.h>
271 # endif
272 
273 struct pollfd {
274   int		fd;		/* file descriptor */
275   short		events;		/* requested events */
276   short		revents;	/* returned events */
277 };
278 
279 #endif
280 /* Cope with OS's that do not declare some of these */
281 /* Input/Output values */
282 #ifndef POLLIN
283 #define POLLIN		0x0001
284 #endif
285 #ifndef POLLPRI
286 #define POLLPRI		0x0002
287 #endif
288 #ifndef POLLOUT
289 #define POLLOUT		0x0004
290 #endif
291 #ifndef POLLMSG
292 #define POLLMSG		0x0400
293 #endif
294 #ifndef POLLREMOVE
295 #define POLLREMOVE	0x1000
296 #endif
297 #ifndef POLLRDHUP
298 #define POLLRDHUP	0x2000
299 #endif
300 /* Output values */
301 #ifndef POLLERR
302 #define POLLERR		0x0008
303 #endif
304 #ifndef POLLHUP
305 #define POLLHUP		0x0010
306 #endif
307 #ifndef POLLNVAL
308 #define POLLNVAL	0x0020
309 #endif
310 
311 #ifndef HAVE_UCHAR
312 typedef unsigned char uchar;
313 #endif
314 
315 #ifndef HAVE_UINT
316 typedef unsigned int uint;
317 #endif
318 
319 #ifndef HAVE_UINT8_T
320 typedef unsigned char uint8_t;
321 #endif
322 
323 #ifndef HAVE_UINT16_T
324 typedef unsigned short uint16_t;
325 #endif
326 
327 #ifndef HAVE_UINT32_T
328 typedef unsigned int uint32_t;
329 #endif
330 
331 
332 /* Placing this after a function prototype indicates to the compiler that the function takes a
333    variable number of arguments in printf(3) format.  If this is used, the compiler will check
334    to make sure your variables match the format string, just like it would with printf(3) and
335    friends.  You shouldn't use this if it's possible to pass NULL as the fmtarg, since the
336    the compiler will issue a warning about a NULL format string. */
337 /* GNU only... */
338 #define  __printflike(fmtarg, firstvararg) \
339             __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
340 
341 /* Macro for pluralizing words in printf() statements.  If 'n' is 1, evaluates to "", otherwise
342    evaluates to "s".  i.e. printf("%d number%s found.", num, S(num)); */
343 #define  S(n)  ((n == 1) ? "" : "s")
344 
345 /* Evaluates to the number of items in the specified array. */
346 #define  NUM_ENTRIES(Array) (sizeof Array / sizeof *(Array))
347 
348 /* Macro to return the last char in a string */
349 #define	LASTCHAR(s)	((s)[strlen((s))-1])
350 
351 
352 /* Macro to determine an average.  "t" is the total, and "c" is the number of elements. */
353 #define  AVG(t,c)    (double)(((double)c > 0.0) ? (double)((double)t / (double)c) : 0.0)
354 
355 /* Macro to determine a percentage.  "t" is the total, "c" is the count. i.e. PCT(100,65)
356 	evaluates as (double)65.0. */
357 #define  PCT(t,c)    (double)(((double)t > 0.0) ? (double)((double)c / (double)t) * 100.0 : 0.0)
358 
359 /* Returns 1 for "[Yy](es)", "[Tt](rue)", "1", "[Aa]ctive", or "(o)[Nn]" */
360 #define  GETBOOL(str)   \
361 	((str) && ((str)[0] == 'Y' || (str)[0] == 'y' || (str)[0] == 'T' || (str)[0] == 't' || \
362 	 (str)[0] == '1' || (str)[1] == 'n' || (str)[1] == 'N' || (str)[0] == 'A'))
363 
364 /* These characters might cause problems in SQL queries; they should be escaped (or the data
365 	rejected, which is probably always appropriate for DNS data */
366 #define	SQL_BADCHAR(c)		(((c) == '\n' || (c) == '\r' || (c) == '\\' || (c) == '\'' || (c) == '"'))
367 
368 
369 #ifndef  __STRING
370 #  define   __STRING(x) "x"
371 #endif
372 #if (!defined (__GNUC__) || __GNUC__ < 2 || __GNUC_MINOR__ < (defined (__cplusplus) ? 6 : 4))
373 #  define   __FUNCTION_NAME   ((const char *)0)
374 #else
375 #  define   __FUNCTION_NAME   __PRETTY_FUNCTION__
376 #endif
377 
378 #ifndef MAX
379 #define MAX(__N__, __M__) (((__N__) > (__M__))?(__N__):(__M__))
380 #endif
381 #ifndef MIN
382 #define MIN(__N__, __M__) (((__N__) < (__M__))?(__N__):(__M__))
383 #endif
384 
385 /* cidr.c */
386 extern int in_cidr(char *cidr, struct in_addr ip);
387 
388 
389 /*
390 **  conf.c
391 **  Routines to load the configuration file
392 */
393 /* Generic structure for holding name/value pairs */
394 typedef struct _conflist {
395   const char	*name;		/* Name of option */
396   char		*value;		/* Value for this option */
397   const char	*desc;		/* Description of this option */
398   const char	*altname;	/* Alternate name for this option */
399   int		defaulted;	/* This variable was defaulted; not actually in config file */
400   struct _conflist *next;
401 } CONF;
402 
403 #define	CONF_FS_CHAR	'\034'
404 #define	CONF_FS_STR		"\034"
405 
406 extern void		conf_clobber(CONF **, const char *, const char *);
407 extern void		conf_set(CONF **, const char *, const char *, int);
408 extern const char	*conf_get(CONF **, const char *, int *);
409 extern void		conf_load(CONF **, const char *);
410 
411 #define MEMMAN 1
412 
413 #if MEMMAN == 0
414 #define __ALLOCATE__(SIZE, THING, COUNT, ARENA) calloc(COUNT, SIZE)
415 #define __REALLOCATE__(OBJECT, SIZE, THING, COUNT, ARENA) realloc(OBJECT, (COUNT)*(SIZE))
416 #define __RELEASE__(OBJECT, COUNT, ARENA)  if ((OBJECT)) free((OBJECT)), (OBJECT) = NULL
417 #define STRDUP(__STRING__) strdup(__STRING__)
418 #define STRNDUP(__STRING__, __LENGTH__) strndup(__STRING__, __LENGTH__)
419 #define ASPRINTF asprintf
420 #define VASPRINTF vasprintf
421 #else
422 #define __ALLOCATE__(SIZE, THING, COUNT, ARENA)	\
423   _mydns_allocate(SIZE, COUNT, ARENA, "##THING##", __FILE__, __LINE__)
424 #define __REALLOCATE__(OBJECT, SIZE, THING, COUNT, ARENA) \
425   _mydns_reallocate((void*)(OBJECT), SIZE, COUNT, ARENA, "##THING##", __FILE__, __LINE__)
426 #define __RELEASE__(OBJECT, COUNT, ARENA) \
427   _mydns_release((void*)(OBJECT), COUNT, ARENA, __FILE__, __LINE__), (OBJECT) = NULL
428 
429 #define STRDUP(__STRING__)		_mydns_strdup(__STRING__, ARENA_GLOBAL, __FILE__, __LINE__)
430 #define STRNDUP(__STRING__, __LENGTH__) _mydns_strndup(__STRING__, __LENGTH__, ARENA_GLOBAL, __FILE__, __LINE__)
431 #define ASPRINTF			_mydns_asprintf
432 #define VASPRINTF			_mydns_vasprintf
433 
434 #endif
435 
436 /*
437 **  memoryman.c
438 **  Memory management functions.
439 */
440 typedef enum _arena_t {
441   ARENA_GLOBAL		= 0,
442   ARENA_LOCAL		= 1,
443   ARENA_SHARED0		= 2,
444 } arena_t;
445 
446 extern int	_mydns_asprintf(char **strp, const char *fmt, ...);
447 extern int	_mydns_vasprintf(char **strp, const char *fmt, va_list ap);
448 extern char *	_mydns_strdup(const char *, arena_t, const char *, int);
449 extern char *	_mydns_strndup(const char *, size_t, arena_t, const char *, int);
450 extern void *	_mydns_allocate(size_t, size_t, arena_t, const char *, const char *, int);
451 extern void *	_mydns_reallocate(void *, size_t, size_t, arena_t, const char *, const char *, int);
452 extern void	_mydns_release(void *, size_t, arena_t, const char *, int);
453 
454 #define ALLOCATE_GLOBAL(SIZE, THING) \
455   __ALLOCATE__(SIZE, THING, 1, ARENA_GLOBAL)
456 #define ALLOCATE_LOCAL(SIZE, THING) \
457   __ALLOCATE__(SIZE, THING, 1, ARENA_LOCAL)
458 #define ALLOCATE_SHARED(SIZE, THING, POOL) \
459   __ALLOCATE__(SIZE, THING, 1, ARENA_SHARED##POOL)
460 
461 #define ALLOCATE_N_GLOBAL(COUNT, SIZE, THING) \
462   __ALLOCATE__(SIZE, THING, COUNT, ARENA_GLOBAL)
463 #define ALLOCATE_N_LOCAL(COUNT, SIZE, THING) \
464   __ALLOCATE__(SIZE, THING, COUNT, ARENA_LOCAL)
465 #define ALLOCATE_N_SHARED(COUNT, SIZE, THING, POOL) \
466   __ALLOCATE__(SIZE, THING, COUNT, ARENA_SHARED##POOL)
467 
468 #define ALLOCATE(SIZE, THING) \
469   ALLOCATE_GLOBAL(SIZE, THING)
470 #define ALLOCATE_N(COUNT, SIZE, THING)	\
471   ALLOCATE_N_GLOBAL(COUNT, SIZE, THING)
472 
473 #define REALLOCATE_GLOBAL(OBJECT, SIZE, THING) \
474   __REALLOCATE__(OBJECT, SIZE, THING, 1, ARENA_GLOBAL)
475 #define REALLOCATE_LOCAL(OBJECT, SIZE, THING) \
476   __REALLOCATE__(OBJECT, SIZE, THING, 1, ARENA_LOCAL)
477 #define REALLOCATE_SHARED(OBJECT, SIZE, THING, POOL) \
478   __REALLOCATE__(OBJECT, SIZE, THING, 1, ARENA_SHARED##POOL)
479 
480 #define REALLOCATE(OBJECT, SIZE, THING)	\
481   REALLOCATE_GLOBAL(OBJECT, SIZE, THING)
482 
483 #define RELEASE_GLOBAL(OBJECT) \
484   __RELEASE__(OBJECT, 1, ARENA_GLOBAL)
485 #define RELEASE_LOCAL(OBJECT) \
486   __RELEASE__(OBJECT, 1, ARENA_LOCAL)
487 #define RELEASE_SHARED(OBJECT, POOL) \
488   __RELEASE__(OBJECT, 1, ARENA_SHARED##POOL)
489 
490 #define RELEASE(OBJECT)	\
491   RELEASE_GLOBAL(OBJECT)
492 
493 /* Convert str to unsigned int */
494 #define atou(s) (uint32_t)strtoul(s, (char **)NULL, 10)
495 
496 extern CONF	*Conf;				/* Config file data */
497 
498 /*
499 **  error.c
500 **  Error reporting functions.
501 */
502 extern const char	*progname;			/* The name of this program */
503 extern int		err_verbose;			/* Should ERR_VERBOSE output anything? */
504 #if DEBUG_ENABLED
505 extern int		err_debug;			/* Should ERR_DEBUG output anything? */
506 #endif
507 extern FILE		*err_file;			/* Output to this file */
508 
509 extern void		error_reinit(void);
510 extern void		error_init(const char *argv0, int facility);
511 #if DEBUG_ENABLED
512 extern void		Debug(const char *, ...) __printflike(1,2);
513 extern void		DebugX(const char *, int, const char *, ...) __printflike(3,4);
514 #endif
515 extern void		Verbose(const char *, ...) __printflike(1,2);
516 extern void		Notice(const char *, ...) __printflike(1,2);
517 extern int		Warn(const char *, ...) __printflike(1,2);
518 extern int		Warnx(const char *, ...) __printflike(1,2);
519 extern void		Err(const char *, ...) __printflike(1,2);
520 extern void		Errx(const char *, ...) __printflike(1,2);
521 extern void		Out_Of_Memory(void);
522 
523 #if USE_PGSQL
524 extern int		WarnSQL(PGconn *, const char *, ...) __printflike(2,3);
525 extern void		ErrSQL(PGconn *, const char *, ...) __printflike(2,3);
526 #else
527 extern int		WarnSQL(MYSQL *, const char *, ...) __printflike(2,3);
528 extern void		ErrSQL(MYSQL *, const char *, ...) __printflike(2,3);
529 #endif
530 
531 #if !HAVE_DECL_STRSEP
532 extern char		*strsep(char **stringp, const char *delim);
533 #endif
534 
535 #if !HAVE_INET_PTON
536 extern int		inet_pton(int, const char *, void *);
537 #endif
538 
539 #if !HAVE_INET_NTOP
540 extern const char *sql_errmsg(MYSQL *);
541 *inet_ntop(int, const void *, char *, unsigned int);
542 #endif
543 
544 
545 /* getoptstr.c */
546 extern char		*getoptstr(struct option const longopts[]);
547 
548 
549 /* ip.c */
550 extern void		_sockclose(int, const char*, int);
551 #define			sockclose(fd)	_sockclose((fd), __FILE__, __LINE__), (fd) = -1
552 extern const char	*ipaddr(int, void *);
553 #if HAVE_IPV6
554 extern int		is_ipv6(char *);
555 #endif
556 
557 
558 /* passinput.c */
559 extern char		*passinput(const char *prompt);
560 
561 /* string.c */
562 extern char		*strtrimlead(char *), *strtrimtrail(char *), *strtrim(char *);
563 extern char		*strtoupper(char *), *strtolower(char *);
564 extern char		*strsecs(time_t);
565 extern char		*strdcat(char **, const char *);
566 extern int		sdprintf(char **, const char *, ...) __printflike(2,3);
567 extern size_t		human_file_size(const char *);
568 
569 /* strsep_quotes.c */
570 extern char		*strsep_quotes(char **, char *, size_t);
571 extern int		strsep_quotes2(char **, char **);
572 
573 /* wildcard.c */
574 extern int		wildcard_valid(char *p);
575 extern int		wildcard_match(register char *, register char *);
576 
577 #endif /* MYDNSUTIL_H */
578 
579 /* vi:set ts=3: */
580