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