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

📄 log.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
字号:
/* FreeTDS - Library of routines accessing Sybase and Microsoft databases * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns * Copyright (C) 2006 Frediano Ziglio * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#if HAVE_CONFIG_H#include <config.h>#endif /* HAVE_CONFIG_H */#include <stdarg.h>#if TIME_WITH_SYS_TIME# if HAVE_SYS_TIME_H#  include <sys/time.h>#endif# include <time.h>#else# if HAVE_SYS_TIME_H#  include <sys/time.h># else#  include <time.h># endif#endif#include <assert.h>#include <ctype.h>#include <limits.h>#include <stdio.h>#if HAVE_STDLIB_H#include <stdlib.h>#endif /* HAVE_STDLIB_H */#if HAVE_STRING_H#include <string.h>#endif /* HAVE_STRING_H */#if HAVE_UNISTD_H#include <unistd.h>#endif /* HAVE_UNISTD_H */#ifdef WIN32#include <process.h>#endif#include "tds.h"#include "tds_checks.h"#include "tdsthread.h"#ifdef DMALLOC#include <dmalloc.h>#endifTDS_RCSID(var, "$Id: log.c,v 1.4 2007/11/12 22:17:28 jklowden Exp $");/* for now all messages go to the log */int tds_debug_flags = TDS_DBGFLAG_ALLLVL | TDS_DBGFLAG_SOURCE;int tds_g_append_mode = 0;static char *g_dump_filename = NULL;static int write_dump = 0;	/* is TDS stream debug log turned on? */static FILE *g_dumpfile = NULL;	/* file pointer for dump log          */static TDS_MUTEX_DECLARE(g_dump_mutex);static FILE* tdsdump_append(void);#ifdef TDS_ATTRIBUTE_DESTRUCTORstatic void __attribute__((destructor))tds_util_deinit(void){	tdsdump_close();}#endif/** * Temporarily turn off logging. */voidtdsdump_off(void){	TDS_MUTEX_LOCK(&g_dump_mutex);	write_dump = 0;	TDS_MUTEX_UNLOCK(&g_dump_mutex);}				/* tdsdump_off()  *//** * Turn logging back on.  You must call tdsdump_open() before calling this routine. */voidtdsdump_on(void){	TDS_MUTEX_LOCK(&g_dump_mutex);	write_dump = 1;	TDS_MUTEX_UNLOCK(&g_dump_mutex);}				/* tdsdump_on()  *//** * This creates and truncates a human readable dump file for the TDS * traffic.  The name of the file is specified by the filename * parameter.  If that is given as NULL or an empty string, * any existing log file will be closed. * * \return  true if the file was opened, false if it couldn't be opened. */inttdsdump_open(const char *filename){	int result;		/* really should be a boolean, not an int */	TDS_MUTEX_LOCK(&g_dump_mutex);	/* same append file */	if (tds_g_append_mode && filename != NULL && g_dump_filename != NULL && strcmp(filename, g_dump_filename) == 0) {		TDS_MUTEX_UNLOCK(&g_dump_mutex);		return 1;	}	/* free old one */	if (g_dumpfile != NULL && g_dumpfile != stdout && g_dumpfile != stderr)		fclose(g_dumpfile);	g_dumpfile = NULL;	if (g_dump_filename)		TDS_ZERO_FREE(g_dump_filename);	/* required to close just log ?? */	if (filename == NULL || filename[0] == '\0') {		TDS_MUTEX_UNLOCK(&g_dump_mutex);		return 1;	}	result = 1;	if (tds_g_append_mode) {		g_dump_filename = strdup(filename);		/* if mutex are available do not reopen file every time */#ifdef TDS_HAVE_PTHREAD_MUTEX		g_dumpfile = tdsdump_append();#endif	} else if (!strcmp(filename, "stdout")) {		g_dumpfile = stdout;	} else if (!strcmp(filename, "stderr")) {		g_dumpfile = stderr;	} else if (NULL == (g_dumpfile = fopen(filename, "w"))) {		result = 0;	}	if (result)		write_dump = 1;	TDS_MUTEX_UNLOCK(&g_dump_mutex);	if (result) {		char today[64];		struct tm *tm;#ifdef HAVE_LOCALTIME_R		struct tm res;#endif		time_t t;		time(&t);#ifdef HAVE_LOCALTIME_R#if HAVE_FUNC_LOCALTIME_R_TM		tm = localtime_r(&t, &res);#elif HAVE_FUNC_LOCALTIME_R_INT		tm = NULL;		if (!localtime_r(&t, &res))			tm = &res;#else#error One should be defined#endif#else		tm = localtime(&t);#endif		strftime(today, sizeof(today), "%Y-%m-%d %H:%M:%S", tm);		tdsdump_log(TDS_DBG_INFO1, "Starting log file for FreeTDS %s\n"			    "\ton %s with debug flags 0x%x.\n", VERSION, today, tds_debug_flags);	}	return result;}				/* tdsdump_open()  */static FILE*tdsdump_append(void){	if (!g_dump_filename)		return NULL;	if (!strcmp(g_dump_filename, "stdout")) {		return stdout;	} else if (!strcmp(g_dump_filename, "stderr")) {		return stderr;	}	return fopen(g_dump_filename, "a");}/** * Close the TDS dump log file. */voidtdsdump_close(void){	TDS_MUTEX_LOCK(&g_dump_mutex);	write_dump = 0;	if (g_dumpfile != NULL && g_dumpfile != stdout && g_dumpfile != stderr)		fclose(g_dumpfile);	g_dumpfile = NULL;	if (g_dump_filename)		TDS_ZERO_FREE(g_dump_filename);	TDS_MUTEX_UNLOCK(&g_dump_mutex);}				/* tdsdump_close()  */static voidtdsdump_start(FILE *file, const char *fname, int line){	char buf[128], *pbuf;	int started = 0;	/* write always time before log */	if (tds_debug_flags & TDS_DBGFLAG_TIME) {		fputs(tds_timestamp_str(buf, 127), file);		started = 1;	}	pbuf = buf;	if (tds_debug_flags & TDS_DBGFLAG_PID) {		if (started)			*pbuf++ = ' ';		pbuf += sprintf(pbuf, "%d", (int) getpid());		started = 1;	}	if ((tds_debug_flags & TDS_DBGFLAG_SOURCE) && fname && line) {		const char *p;		p = strrchr(fname, '/');		if (p)			fname = p + 1;		p = strrchr(fname, '\\');		if (p)			fname = p + 1;		if (started)			pbuf += sprintf(pbuf, " (%s:%d)", fname, line);		else			pbuf += sprintf(pbuf, "%s:%d", fname, line);		started = 1;	}	if (started)		*pbuf++ = ':';	*pbuf = 0;	fputs(buf, file);}/** * Dump the contents of data into the log file in a human readable format. * \param msg      message to print before dump * \param buf      buffer to dump * \param length   number of bytes in the buffer */voidtdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, const void *buf, int length){	int i;	int j;#define BYTES_PER_LINE 16	const unsigned char *data = (const unsigned char *) buf;	const int debug_lvl = level_line & 15;	const int line = level_line >> 4;	char line_buf[BYTES_PER_LINE * 8 + 16], *p;	FILE *dumpfile;	if (((tds_debug_flags >> debug_lvl) & 1) == 0 || !write_dump)		return;	if (!g_dumpfile && !g_dump_filename)		return;	TDS_MUTEX_LOCK(&g_dump_mutex);	dumpfile = g_dumpfile;#ifdef TDS_HAVE_PTHREAD_MUTEX	if (tds_g_append_mode && dumpfile == NULL)		dumpfile = g_dumpfile = tdsdump_append();#else	if (tds_g_append_mode)		dumpfile = tdsdump_append();#endif	if (dumpfile == NULL) {		TDS_MUTEX_UNLOCK(&g_dump_mutex);		return;	}	tdsdump_start(dumpfile, file, line);	fprintf(dumpfile, "%s\n", msg);	for (i = 0; i < length; i += BYTES_PER_LINE) {		p = line_buf;		/*		 * print the offset as a 4 digit hex number		 */		p += sprintf(p, "%04x", i);		/*		 * print each byte in hex		 */		for (j = 0; j < BYTES_PER_LINE; j++) {			if (j == BYTES_PER_LINE / 2)				*p++ = '-';			else				*p++ = ' ';			if (j + i >= length)				p += sprintf(p, "  ");			else				p += sprintf(p, "%02x", data[i + j]);		}		/*		 * skip over to the ascii dump column		 */		p += sprintf(p, " |");		/*		 * print each byte in ascii		 */		for (j = i; j < length && (j - i) < BYTES_PER_LINE; j++) {			if (j - i == BYTES_PER_LINE / 2)				*p++ = ' ';			p += sprintf(p, "%c", (isprint(data[j])) ? data[j] : '.');		}		strcpy(p, "|\n");		fputs(line_buf, dumpfile);	}	fputs("\n", dumpfile);	fflush(dumpfile);#ifndef TDS_HAVE_PTHREAD_MUTEX	if (tds_g_append_mode) {		if (dumpfile != stdout && dumpfile != stderr)			fclose(dumpfile);	}#endif	TDS_MUTEX_UNLOCK(&g_dump_mutex);}				/* tdsdump_dump_buf()  *//** * This function write a message to the debug log.   * \param file name of the log file * \param level_line kind of detail to be included * \param fmt       printf-like format string */voidtdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...){	const int debug_lvl = level_line & 15;	const int line = level_line >> 4;	va_list ap;	FILE *dumpfile;	if (((tds_debug_flags >> debug_lvl) & 1) == 0 || !write_dump)		return;	if (!g_dumpfile && !g_dump_filename)		return;	TDS_MUTEX_LOCK(&g_dump_mutex);	dumpfile = g_dumpfile;#ifdef TDS_HAVE_PTHREAD_MUTEX	if (tds_g_append_mode && dumpfile == NULL)		dumpfile = g_dumpfile = tdsdump_append();#else	if (tds_g_append_mode)		dumpfile = tdsdump_append();#endif		if (dumpfile == NULL) { 		TDS_MUTEX_UNLOCK(&g_dump_mutex);		return;	}	tdsdump_start(dumpfile, file, line);	va_start(ap, fmt);	vfprintf(dumpfile, fmt, ap);	va_end(ap);	fflush(dumpfile);#ifndef TDS_HAVE_PTHREAD_MUTEX	if (tds_g_append_mode) {		if (dumpfile != stdout && dumpfile != stderr)			fclose(dumpfile);	}#endif	TDS_MUTEX_UNLOCK(&g_dump_mutex);}				/* tdsdump_log()  */

⌨️ 快捷键说明

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