⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 此dns服务器是在mydns基础上改写
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************************************	$Id: main.c,v 1.122 2005/12/08 17:45:56 bboy Exp $	Copyright (C) 2002-2005  Don Moore <bboy@bboy.net>	This program is free software; you can redistribute it and/or modify	it under the terms of the GNU General Public License as published by	the Free Software Foundation; either version 2 of the License, or	(at Your option) any later version.	This program is distributed in the hope that it will be useful,	but WITHOUT ANY WARRANTY; without even the implied warranty of	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the	GNU General Public License for more details.	You should have received a copy of the GNU General Public License	along with this program; if not, write to the Free Software	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA**************************************************************************************************/#include "named.h"QUEUE *Tasks;														/* Task queue */time_t current_time;												/* Current time */static int multicpu;												/* If multi-CPU, number of CPUs */static pid_t *pidlist;											/* List of related PIDs */static int is_master;											/* Is the current process the master? */static int got_sigusr1 = 0,			  got_sigusr2 = 0,			  got_sighup = 0,			  got_sigalrm = 0,									/* Signal flags */			  got_sigchld = 0;									/* Signal flags */static int shutting_down = 0;									/* Shutdown in progress? */int	run_as_root = 0;											/* Run as root user? */uint32_t answer_then_quit = 0;								/* Answer this many queries then quit */char	hostname[256];												/* Hostname of local machine */extern int *tcp4_fd, *udp4_fd;								/* Listening FD's (IPv4) */extern int num_tcp4_fd, num_udp4_fd;						/* Number of listening FD's (IPv4) */#if HAVE_IPV6extern int *tcp6_fd, *udp6_fd;								/* Listening FD's (IPv6) */extern int num_tcp6_fd, num_udp6_fd;						/* Number of listening FD's (IPv6) */#endifint	show_data_errors = 1;									/* Output data errors? */SERVERSTATUS Status;												/* Server status information */extern void create_listeners(void);extern void db_check_optional(void);extern int	opt_daemon;extern char	*opt_conf;extern uid_t perms_uid;extern gid_t perms_gid;/**************************************************************************************************	USAGE	Display program usage information.**************************************************************************************************/static voidusage(int status){	if (status != EXIT_SUCCESS)	{		fprintf(stderr, _("Try `%s --help' for more information."), progname);		fputs("\n", stderr);	}	else	{		printf(_("Usage: %s [OPTION]..."), progname);		puts("");		puts(_("Listen for and respond to Internet domain name queries."));		puts("");/*		puts("----------------------------------------------------------------------------78");  */		puts(_("  -b, --background        run as a daemon (move process into background)"));		puts(_("  -c, --conf=FILE         read config from FILE instead of the default"));		puts(_("      --create-tables     output table creation SQL and exit"));		puts(_("      --dump-config       output configuration and exit"));		printf("                          (%s: \"%s\")\n", _("default"), MYDNS_CONF);		puts("");		puts(_("  -D, --database=DB       database name to use"));		puts(_("  -h, --host=HOST         connect to database at HOST"));		puts(_("  -p, --password=PASS     password for database (or prompt from tty)"));		puts(_("  -u, --user=USER         username for database if not current user"));		puts("");#if DEBUG_ENABLED		puts(_("  -d, --debug             enable debug output"));#endif		puts(_("  -v, --verbose           be more verbose while running"));		puts(_("      --no-data-errors    don't output errors about bad data"));		puts(_("      --help              display this help and exit"));		puts(_("      --version           output version information and exit"));		puts("");		printf(_("The %s homepage is at %s\n"), PACKAGE_NAME, PACKAGE_HOMEPAGE);		puts("");		printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);	}	exit(status);}/*--- usage() -----------------------------------------------------------------------------------*//**************************************************************************************************	CMDLINE	Process command line options.**************************************************************************************************/static voidcmdline(int argc, char **argv){	char	*optstr;	int	want_dump_config = 0, optc, optindex;	struct option const longopts[] =	{		{"background",		no_argument,			NULL,	'b'},		{"conf",				required_argument,	NULL,	'c'},		{"create-tables",	no_argument,			NULL,	0},		{"dump-config",	no_argument,			NULL,	0},		{"database",		required_argument,	NULL,	'D'},		{"host",				required_argument,	NULL,	'h'},		{"password",		optional_argument,	NULL,	'p'},		{"user",				required_argument,	NULL,	'u'},		{"debug",			no_argument,			NULL,	'd'},		{"verbose",			no_argument,			NULL,	'v'},		{"help",				no_argument,			NULL,	0},		{"version",			no_argument,			NULL,	0},		{"quit-after",		required_argument,	NULL,	0}, /* Undocumented.. Useful when debugging */		{"run-as-root",	no_argument,			NULL,	0}, /* Undocumented.. */		{"no-data-errors",no_argument,			NULL,	0},		{NULL, 0, NULL, 0}	};	error_init(argv[0], LOG_DAEMON);							/* Init output/logging routines */	optstr = getoptstr(longopts);	while ((optc = getopt_long(argc, argv, optstr, longopts, &optindex)) != -1)	{		switch (optc)		{			case 0:				{					const char *opt = longopts[optindex].name;					if (!strcmp(opt, "version"))									/* --version */					{						printf("%s ("PACKAGE_NAME") "PACKAGE_VERSION" ("SQL_VERSION_STR")\n", progname);						puts("\n" PACKAGE_COPYRIGHT);						puts(_("This is free software; see the source for copying conditions.  There is NO"));						puts(_("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."));						exit(EXIT_SUCCESS);					}					else if (!strcmp(opt, "help"))								/* --help */						usage(EXIT_SUCCESS);					else if (!strcmp(opt, "dump-config"))						/* --dump-config */						want_dump_config++;					else if (!strcmp(opt, "create-tables"))					/* --create-tables */						db_output_create_tables();					else if (!strcmp(opt, "quit-after"))						/* --quit-after */						answer_then_quit = strtoul(optarg, (char **)NULL, 10);					else if (!strcmp(opt, "run-as-root"))						/* --run-as-root */						run_as_root = 1;					else if (!strcmp(opt, "no-data-errors"))					/* --no-data-errors */						show_data_errors = 0;				}				break;			case 'b':																	/* -b, --background */				opt_daemon = 1;				break;			case 'c':																	/* -c, --conf=FILE */				opt_conf = optarg;				break;			case 'd':																	/* -d, --debug */#if DEBUG_ENABLED				err_verbose = err_debug = 1;#endif				break;			case 'D':																	/* -D, --database=DB */				conf_set(&Conf, "database", optarg, 0);				break;			case 'h':																	/* -h, --host=HOST */				conf_set(&Conf, "db-host", optarg, 0);				break;			case 'p':																	/* -p, --password=PASS */				if (optarg)				{					conf_set(&Conf, "db-password", optarg, 0);					memset(optarg, 'X', strlen(optarg));				}				else					conf_set(&Conf, "db-password", passinput(_("Enter password")), 0);				break;			case 'u':																	/* -u, --user=USER */				conf_set(&Conf, "db-user", optarg, 0);				break;			case 'v':																	/* -v, --verbose */				err_verbose = 1;				break;			default:				usage(EXIT_FAILURE);		}	}	if (optind < argc)		fprintf(stderr, "%s: %s\n", progname, _("Extraneous command-line arguments ignored"));	load_config();	if (want_dump_config)	{		dump_config();		exit(EXIT_SUCCESS);	}	db_verify_tables();											/* Make sure tables are OK */	/* Random numbers are just for round robin and load balancing */	srand(time(NULL));}/*--- cmdline() ---------------------------------------------------------------------------------*//**************************************************************************************************	SET_SIGHANDLER**************************************************************************************************/typedef void (*sig_handler)(int);static voidset_sighandler(int sig, sig_handler h){	struct sigaction act;	sigemptyset(&act.sa_mask);	act.sa_flags = 0;	if (sig == SIGALRM)	{#ifdef SA_INTERRUPT		act.sa_flags |= SA_INTERRUPT;#endif	}	else	{#ifdef SA_RESTART		act.sa_flags |= SA_RESTART;#endif	}	act.sa_handler = h;	sigaction(sig, &act, 0);}/*--- set_sighandler() --------------------------------------------------------------------------*//**************************************************************************************************	BECOME_DAEMON**************************************************************************************************/static voidbecome_daemon(void){	int pid;	struct rlimit rl;	sql_close(sql);	if ((pid = fork()) < 0)		Err("fork");	if (pid)		_exit(EXIT_SUCCESS);	close(STDIN_FILENO);	close(STDOUT_FILENO);	close(STDERR_FILENO);	setsid();	if (getrlimit(RLIMIT_NOFILE, &rl) < 0)		Err("getrlimit");	rl.rlim_cur = rl.rlim_max;	setrlimit(RLIMIT_NOFILE, &rl);	if (getrlimit(RLIMIT_CORE, &rl) < 0)		Err("getrlimit");	rl.rlim_cur = rl.rlim_max;	setrlimit(RLIMIT_CORE, &rl);	db_connect();}/*--- become_daemon() ---------------------------------------------------------------------------*//**************************************************************************************************	CREATE_PIDFILE	Creates the PID file.**************************************************************************************************/static voidcreate_pidfile(void){	char *name = conf_get(&Conf, "pidfile", NULL);	FILE *fp;	if (!(fp = fopen(name, "w")))		Err("%s", name);	fprintf(fp, "%lu\n", (unsigned long)getpid());	fclose(fp);	/* Change ownership so we can delete it later */	chown(name, perms_uid, perms_gid);}/*--- create_pidfile() --------------------------------------------------------------------------*//**************************************************************************************************	SERVER_STATUS**************************************************************************************************/voidserver_status(void){	char buf[1024], *b = buf;	time_t uptime = time(NULL) - Status.start_time;	unsigned long requests = Status.udp_requests + Status.tcp_requests;	b += snprintf(b, sizeof(buf)-(b-buf), "%s ", hostname);	b += snprintf(b, sizeof(buf)-(b-buf), "%s %s (%lus) ", _("up"), strsecs(uptime), (unsigned long)uptime);	b += snprintf(b, sizeof(buf)-(b-buf), "%lu %s ", requests, _("questions"));	b += snprintf(b, sizeof(buf)-(b-buf), "(%.0f/s) ", requests ? AVG(requests, uptime) : 0.0);	b += snprintf(b, sizeof(buf)-(b-buf), "NOERROR=%u ", Status.results[DNS_RCODE_NOERROR]);	b += snprintf(b, sizeof(buf)-(b-buf), "SERVFAIL=%u ", Status.results[DNS_RCODE_SERVFAIL]);	b += snprintf(b, sizeof(buf)-(b-buf), "NXDOMAIN=%u ", Status.results[DNS_RCODE_NXDOMAIN]);	b += snprintf(b, sizeof(buf)-(b-buf), "NOTIMP=%u ", Status.results[DNS_RCODE_NOTIMP]);	b += snprintf(b, sizeof(buf)-(b-buf), "REFUSED=%u ", Status.results[DNS_RCODE_REFUSED]);	/* If the server is getting TCP queries, report on the percentage of TCP queries */	if (Status.tcp_requests)		b += snprintf(b, sizeof(buf)-(b-buf), "(%d%% TCP, %lu queries)",						  (int)PCT(requests, Status.tcp_requests), (unsigned long)Status.tcp_requests);	Notice("%s", buf);}/*--- server_status() ---------------------------------------------------------------------------*//**************************************************************************************************	SIGUSR1	Outputs server stats.**************************************************************************************************/voidsigusr1(int dummy){	if (is_master)	{		int n;		for (n = 0; n < multicpu - 1; n++)			kill(pidlist[n], SIGUSR1);	}	server_status();	got_sigusr1 = 0;}/*--- sigusr1() ---------------------------------------------------------------------------------*//**************************************************************************************************	SIGUSR2	Outputs cache stats.**************************************************************************************************/voidsigusr2(int dummy){	if (is_master)	{		int n;		for (n = 0; n < multicpu - 1; n++)			kill(pidlist[n], SIGUSR2);	}	cache_status(ZoneCache);#if USE_NEGATIVE_CACHE	cache_status(NegativeCache);#endif	cache_status(ReplyCache);	got_sigusr2 = 0;}/*--- sigusr2() ---------------------------------------------------------------------------------*//**************************************************************************************************	PERIODIC_TASK**************************************************************************************************/voidperiodic_task(int dummy){	alarm(ALARM_INTERVAL);	got_sigalrm = 0;}/*--- periodic_task() ---------------------------------------------------------------------------*//**************************************************************************************************	SIGHUP**************************************************************************************************/voidsighup(int dummy){	if (is_master)	{		int n;		for (n = 0; n < multicpu - 1; n++)			kill(pidlist[n], SIGHUP);	}	cache_empty(ZoneCache);#if USE_NEGATIVE_CACHE	cache_empty(NegativeCache);#endif	cache_empty(ReplyCache);	db_check_optional();	Notice(_("SIGHUP received: cache emptied, tables reloaded"));	got_sighup = 0;}/*--- sighup() ----------------------------------------------------------------------------------*//**************************************************************************************************	SIGNAL_HANDLER**************************************************************************************************/voidsignal_handler(int signo){	switch (signo)	{		case SIGHUP: got_sighup = 1; break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -