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

📄 log.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 3 页
字号:
	isc_dir_init(&dir);	result = isc_dir_open(&dir, dirname);	/*	 * Replace the file separator if it was taken out.	 */	if (basename != FILE_NAME(channel))		*(basename - 1) = sep;	/*	 * Return if the directory open failed.	 */	if (result != ISC_R_SUCCESS)		return (result);	while (isc_dir_read(&dir) == ISC_R_SUCCESS) {		if (dir.entry.length > basenamelen &&		    strncmp(dir.entry.name, basename, basenamelen) == 0 &&		    dir.entry.name[basenamelen] == '.') {			version = strtol(&dir.entry.name[basenamelen + 1],					 &digit_end, 10);			if (*digit_end == '\0' && version > greatest)				greatest = version;		}	}	isc_dir_close(&dir);	*greatestp = ++greatest;	return (ISC_R_SUCCESS);}static isc_result_troll_log(isc_logchannel_t *channel) {	int i, n, greatest;	char current[PATH_MAX + 1];	char new[PATH_MAX + 1];	const char *path;	isc_result_t result;	/*	 * Do nothing (not even excess version trimming) if ISC_LOG_ROLLNEVER	 * is specified.  Apparently complete external control over the log	 * files is desired.	 */	if (FILE_VERSIONS(channel) == ISC_LOG_ROLLNEVER)		return (ISC_R_SUCCESS);	path = FILE_NAME(channel);	/*	 * Set greatest_version to the greatest existing version	 * (not the maximum requested version).  This is 1 based even	 * though the file names are 0 based, so an oldest log of log.1	 * is a greatest_version of 2.	 */	result = greatest_version(channel, &greatest);	if (result != ISC_R_SUCCESS)		return (result);	/*	 * Now greatest should be set to the highest version number desired.	 * Since the highest number is one less than FILE_VERSIONS(channel)	 * when not doing infinite log rolling, greatest will need to be	 * decremented when it is equal to -- or greater than --	 * FILE_VERSIONS(channel).  When greatest is less than	 * FILE_VERSIONS(channel), it is already suitable for use as	 * the maximum version number.	 */	if (FILE_VERSIONS(channel) == ISC_LOG_ROLLINFINITE ||	    FILE_VERSIONS(channel) > greatest)		;		/* Do nothing. */	else		/*		 * When greatest is >= FILE_VERSIONS(channel), it needs to		 * be reduced until it is FILE_VERSIONS(channel) - 1.		 * Remove any excess logs on the way to that value.		 */		while (--greatest >= FILE_VERSIONS(channel)) {			n = snprintf(current, sizeof(current), "%s.%d",				     path, greatest);			if (n >= (int)sizeof(current) || n < 0)				result = ISC_R_NOSPACE;			else				result = isc_file_remove(current);			if (result != ISC_R_SUCCESS &&			    result != ISC_R_FILENOTFOUND)				syslog(LOG_ERR,				       "unable to remove log file '%s.%d': %s",				       path, greatest,				       isc_result_totext(result));		}	for (i = greatest; i > 0; i--) {		result = ISC_R_SUCCESS;		n = snprintf(current, sizeof(current), "%s.%d", path, i - 1);		if (n >= (int)sizeof(current) || n < 0)			result = ISC_R_NOSPACE;		if (result == ISC_R_SUCCESS) {			n = snprintf(new, sizeof(new), "%s.%d", path, i);			if (n >= (int)sizeof(new) || n < 0)				result = ISC_R_NOSPACE;		}		if (result == ISC_R_SUCCESS)			result = isc_file_rename(current, new);		if (result != ISC_R_SUCCESS &&		    result != ISC_R_FILENOTFOUND)			syslog(LOG_ERR,			       "unable to rename log file '%s.%d' to "			       "'%s.%d': %s", path, i - 1, path, i,			       isc_result_totext(result));	}	if (FILE_VERSIONS(channel) != 0) {		n = snprintf(new, sizeof(new), "%s.0", path);		if (n >= (int)sizeof(new) || n < 0)			result = ISC_R_NOSPACE;		else			result = isc_file_rename(path, new);		if (result != ISC_R_SUCCESS &&		    result != ISC_R_FILENOTFOUND)			syslog(LOG_ERR,			       "unable to rename log file '%s' to '%s.0': %s",			       path, path, isc_result_totext(result));	} else {		result = isc_file_remove(path);		if (result != ISC_R_SUCCESS &&		    result != ISC_R_FILENOTFOUND)			syslog(LOG_ERR, "unable to remove log file '%s': %s",			       path, isc_result_totext(result));	}	return (ISC_R_SUCCESS);}static isc_result_tisc_log_open(isc_logchannel_t *channel) {	struct stat statbuf;	isc_boolean_t regular_file;	isc_boolean_t roll = ISC_FALSE;	isc_result_t result = ISC_R_SUCCESS;	const char *path;	REQUIRE(channel->type == ISC_LOG_TOFILE);	REQUIRE(FILE_STREAM(channel) == NULL);	path = FILE_NAME(channel);	REQUIRE(path != NULL && *path != '\0');	/*	 * Determine type of file; only regular files will be	 * version renamed, and only if the base file exists	 * and either has no size limit or has reached its size limit.	 */	if (stat(path, &statbuf) == 0) {		regular_file = S_ISREG(statbuf.st_mode) ? ISC_TRUE : ISC_FALSE;		/* XXXDCL if not regular_file complain? */		if ((FILE_MAXSIZE(channel) == 0 &&		     FILE_VERSIONS(channel) != ISC_LOG_ROLLNEVER) ||		    (FILE_MAXSIZE(channel) > 0 &&		     statbuf.st_size >= FILE_MAXSIZE(channel)))			roll = regular_file;	} else if (errno == ENOENT)		regular_file = ISC_TRUE;	else		result = ISC_R_INVALIDFILE;	/*	 * Version control.	 */	if (result == ISC_R_SUCCESS && roll) {		if (FILE_VERSIONS(channel) == ISC_LOG_ROLLNEVER)			return (ISC_R_MAXSIZE);		result = roll_log(channel);		if (result != ISC_R_SUCCESS) {			if ((channel->flags & ISC_LOG_OPENERR) == 0) {				syslog(LOG_ERR,				       "isc_log_open: roll_log '%s' "				       "failed: %s",				       FILE_NAME(channel),				       isc_result_totext(result));				channel->flags |= ISC_LOG_OPENERR;			}			return (result);		}	}	result = isc_stdio_open(path, "a", &FILE_STREAM(channel));	return (result);}isc_boolean_tisc_log_wouldlog(isc_log_t *lctx, int level) {	/*	 * Try to avoid locking the mutex for messages which can't	 * possibly be logged to any channels -- primarily debugging	 * messages that the debug level is not high enough to print.	 *	 * If the level is (mathematically) less than or equal to the	 * highest_level, or if there is a dynamic channel and the level is	 * less than or equal to the debug level, the main loop must be	 * entered to see if the message should really be output.	 *	 * NOTE: this is UNLOCKED access to the logconfig.  However,	 * the worst thing that can happen is that a bad decision is made	 * about returning without logging, and that's not a big concern,	 * because that's a risk anyway if the logconfig is being	 * dynamically changed.	 */	if (lctx == NULL || lctx->logconfig == NULL)		return (ISC_FALSE);	return (ISC_TF(level <= lctx->logconfig->highest_level ||		       (lctx->logconfig->dynamic &&			level <= lctx->debug_level)));}static voidisc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,	     isc_logmodule_t *module, int level, isc_boolean_t write_once,	     isc_msgcat_t *msgcat, int msgset, int msg,	     const char *format, va_list args){	int syslog_level;	char time_string[64];	char level_string[24];	const char *iformat;	struct stat statbuf;	isc_boolean_t matched = ISC_FALSE;	isc_boolean_t printtime, printtag;	isc_boolean_t printcategory, printmodule, printlevel;	isc_logconfig_t *lcfg;	isc_logchannel_t *channel;	isc_logchannellist_t *category_channels;	isc_result_t result;	REQUIRE(lctx == NULL || VALID_CONTEXT(lctx));	REQUIRE(category != NULL);	REQUIRE(module != NULL);	REQUIRE(level != ISC_LOG_DYNAMIC);	REQUIRE(format != NULL);	/*	 * Programs can use libraries that use this logging code without	 * wanting to do any logging, thus the log context is allowed to	 * be non-existent.	 */	if (lctx == NULL)		return;	REQUIRE(category->id < lctx->category_count);	REQUIRE(module->id < lctx->module_count);	if (! isc_log_wouldlog(lctx, level))		return;	if (msgcat != NULL)		iformat = isc_msgcat_get(msgcat, msgset, msg, format);	else		iformat = format;	time_string[0]  = '\0';	level_string[0] = '\0';	LOCK(&lctx->lock);	lctx->buffer[0] = '\0';		lcfg = lctx->logconfig;	category_channels = ISC_LIST_HEAD(lcfg->channellists[category->id]);	/*	 * XXXDCL add duplicate filtering? (To not write multiple times to	 * the same source via various channels).	 */	do {		/*		 * If the channel list end was reached and a match was made,		 * everything is finished.		 */		if (category_channels == NULL && matched)			break;		if (category_channels == NULL && ! matched &&		    category_channels != ISC_LIST_HEAD(lcfg->channellists[0]))			/*			 * No category/module pair was explicitly configured.			 * Try the category named "default".			 */			category_channels =				ISC_LIST_HEAD(lcfg->channellists[0]);		if (category_channels == NULL && ! matched)			/*			 * No matching module was explicitly configured			 * for the category named "default".  Use the internal			 * default channel.			 */			category_channels = &default_channel;		if (category_channels->module != NULL &&		    category_channels->module != module) {			category_channels = ISC_LIST_NEXT(category_channels,							  link);			continue;		}		matched = ISC_TRUE;		channel = category_channels->channel;		category_channels = ISC_LIST_NEXT(category_channels, link);		if (((channel->flags & ISC_LOG_DEBUGONLY) != 0) &&		    lctx->debug_level == 0)			continue;		if (channel->level == ISC_LOG_DYNAMIC) {			if (lctx->debug_level < level)				continue;		} else if (channel->level < level)			continue;		if ((channel->flags & ISC_LOG_PRINTTIME) != 0 &&		    time_string[0] == '\0') {			isc_time_t isctime;						TIME_NOW(&isctime);			isc_time_formattimestamp(&isctime, time_string,						 sizeof(time_string));		}		if ((channel->flags & ISC_LOG_PRINTLEVEL) != 0 &&		    level_string[0] == '\0') {			if (level < ISC_LOG_CRITICAL)				snprintf(level_string, sizeof(level_string),					 isc_msgcat_get(isc_msgcat,						        ISC_MSGSET_LOG,						        ISC_MSG_LEVEL,						        "level %d: "),					 level);			else if (level > ISC_LOG_DYNAMIC)				snprintf(level_string, sizeof(level_string),					 "%s %d: ", log_level_strings[0],					 level);			else				snprintf(level_string, sizeof(level_string),					 "%s: ", log_level_strings[-level]);		}		/*		 * Only format the message once.		 */		if (lctx->buffer[0] == '\0') {			(void)vsnprintf(lctx->buffer, sizeof(lctx->buffer),					iformat, args);			/*			 * Check for duplicates.			 */			if (write_once) {				isc_logmessage_t *message, *new;				isc_time_t oldest;				isc_interval_t interval;				isc_interval_set(&interval,						 lcfg->duplicate_interval, 0);				/*				 * 'oldest' is the age of the oldest messages				 * which fall within the duplicate_interval				 * range.				 */				TIME_NOW(&oldest);				if (isc_time_subtract(&oldest, &interval, &oldest)				    != ISC_R_SUCCESS)					/*					 * Can't effectively do the checking					 * without having a valid time.					 */					message = NULL;				else					message =ISC_LIST_HEAD(lctx->messages);				while (message != NULL) {					if (isc_time_compare(&message->time,							     &oldest) < 0) {						/*						 * This message is older						 * than the duplicate_interval,						 * so it should be dropped from						 * the history.						 *						 * Setting the interval to be						 * to be longer will obviously						 * not cause the expired						 * message to spring back into						 * existence.						 */						new = ISC_LIST_NEXT(message,								    link);						ISC_LIST_UNLINK(lctx->messages,								message, link);						isc_mem_put(lctx->mctx,							message,							sizeof(*message) + 1 +							strlen(message->text));						message = new;						continue;					}					/*					 * This message is in the duplicate					 * filtering interval ...					 */					if (strcmp(lctx->buffer, message->text)					    == 0) {						/*						 * ... and it is a duplicate.						 * Unlock the mutex and						 * get the hell out of Dodge.						 */						UNLOCK(&lctx->lock);						return;					}					message = ISC_LIST_NEXT(message, link);				}				/*				 * It wasn't in the duplicate interval,				 * so add it to the message list.				 */				new = isc_mem_get(lctx->mctx,						  sizeof(isc_logmessage_t) +						  strlen(lctx->buffer) + 1);				if (new != NULL) {					/*					 * Put the text immediately after					 * the struct.  The strcpy is safe.					 */					new->text = (char *)(new + 1);					strcpy(new->text, lctx->buffer);					TIME_NOW(&new->time);					ISC_LIST_APPEND(lctx->messages,							new, link);				}			}		}		printtime     = ISC_TF((channel->flags & ISC_LOG_PRINTTIME)				       != 0);		printtag      = ISC_TF((channel->flags & ISC_LOG_PRINTTAG)				       != 0 && lcfg->tag != NULL);		printcategory = ISC_TF((channel->flags & ISC_LOG_PRINTCATEGORY)				       != 0);		printmodule   = ISC_TF((channel->flags & ISC_LOG_PRINTMODULE)				       != 0);		printlevel    = ISC_TF((channel->flags & ISC_LOG_PRINTLEVEL)				       != 0);		switch (channel->type) {		case ISC_LOG_TOFILE:			if (FILE_MAXREACHED(channel)) {				/*				 * If the file can be rolled, OR				 * If the file no longer exists, OR				 * If the file is less than the maximum size,				 *    (such as if it had been renamed and				 *     a new one touched, or it was truncated				 *     in place)				 * ... then close it to trigger reopening.				 */				if (FILE_VERSIONS(channel) !=				    ISC_LOG_ROLLNEVER ||				    (stat(FILE_NAME(channel), &statbuf) != 0 &&				     errno == ENOENT) ||				    statbuf.st_size < FILE_MAXSIZE(channel)) {					(void)fclose(FILE_STREAM(channel));					FILE_STREAM(channel) = NULL;					FILE_MAXREACHED(channel) = ISC_FALSE;				} else					/*					 * Eh, skip it.					 */					break;			}			if (FILE_STREAM(channel) == NULL) {				result = isc_log_open(channel);				if (result != ISC_R_SUCCESS &&				    result != ISC_R_MAXSIZE &&				    (channel->flags & ISC_LOG_OPENERR) == 0) {					syslog(LOG_ERR,					       "isc_log_open '%s' failed: %s",					       FILE_NAME(channel),					       isc_result_totext(result));					channel->flags |= ISC_LOG_OPENERR;				}				if (result != ISC_R_SUCCESS)					break;				channel->flags &= ~ISC_LOG_OPENERR;			}			/* FALLTHROUGH */		case ISC_LOG_TOFILEDESC:			fprintf(FILE_STREAM(channel), "%s%s%s%s%s%s%s%s%s%s\n",				printtime     ? time_string	: "",				printtime     ? " "		: "",				printtag      ? lcfg->tag	: "",				printtag      ? ": "		: "",				printcategory ? category->name	: "",				printcategory ? ": "		: "",				printmodule   ? (module != NULL ? module->name						 		: "no_module")					      			: "",				printmodule   ? ": "		: "",				printlevel    ? level_string	: "",				lctx->buffer);			fflush(FILE_STREAM(channel));			/*			 * If the file now exceeds its maximum size			 * threshold, note it so that it will not be logged			 * to any more.			 */			if (FILE_MAXSIZE(channel) > 0) {				INSIST(channel->type == ISC_LOG_TOFILE);				/* XXXDCL NT fstat/fileno */				/* XXXDCL complain if fstat fails? */				if (fstat(fileno(FILE_STREAM(channel)),					  &statbuf) >= 0 &&				    statbuf.st_size > FILE_MAXSIZE(channel))					FILE_MAXREACHED(channel) = ISC_TRUE;			}			break;		case ISC_LOG_TOSYSLOG:			if (level > 0)				syslog_level = LOG_DEBUG;			else if (level < ISC_LOG_CRITICAL)				syslog_level = LOG_CRIT;			else				syslog_level = syslog_map[-level];			(void)syslog(FACILITY(channel) | syslog_level,			       "%s%s%s%s%s%s%s%s%s",			       printtime     ? time_string	: "",			       printtag      ? lcfg->tag	: "",			       printtag      ? ": "		: "",			       printcategory ? category->name	: "",			       printcategory ? ": "		: "",			       printmodule   ? (module != NULL	? module->name						 		: "no_module")					      			: "",			       printmodule   ? ": "		: "",			       printlevel    ? level_string	: "",			       lctx->buffer);			break;		case ISC_LOG_TONULL:			break;		}	} while (1);	UNLOCK(&lctx->lock);}

⌨️ 快捷键说明

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