jabberd2
2.2.16
|
00001 /* 00002 * jabberd - Jabber Open Source Server 00003 * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, 00004 * Ryan Eatmon, Robert Norris 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA 00019 */ 00020 00021 #include "util.h" 00022 00023 #define MAX_LOG_LINE (1024) 00024 00025 #ifdef DEBUG 00026 static int debug_flag; 00027 static FILE *debug_log_target = 0; 00028 #endif 00029 00030 static const char *_log_level[] = 00031 { 00032 "emergency", 00033 "alert", 00034 "critical", 00035 "error", 00036 "warning", 00037 "notice", 00038 "info", 00039 "debug" 00040 }; 00041 00042 static log_facility_t _log_facilities[] = { 00043 { "local0", LOG_LOCAL0 }, 00044 { "local1", LOG_LOCAL1 }, 00045 { "local2", LOG_LOCAL2 }, 00046 { "local3", LOG_LOCAL3 }, 00047 { "local4", LOG_LOCAL4 }, 00048 { "local5", LOG_LOCAL5 }, 00049 { "local6", LOG_LOCAL6 }, 00050 { "local7", LOG_LOCAL7 }, 00051 { "log_user", LOG_USER }, 00052 { NULL, -1 } 00053 }; 00054 00055 static int _log_facility(const char *facility) { 00056 log_facility_t *lp; 00057 00058 if (facility == NULL) { 00059 return -1; 00060 } 00061 for (lp = _log_facilities; lp->facility; lp++) { 00062 if (!strcasecmp(lp->facility, facility)) { 00063 break; 00064 } 00065 } 00066 return lp->number; 00067 } 00068 00069 log_t log_new(log_type_t type, const char *ident, const char *facility) 00070 { 00071 log_t log; 00072 int fnum = 0; 00073 00074 log = (log_t) calloc(1, sizeof(struct log_st)); 00075 00076 log->type = type; 00077 00078 if(type == log_SYSLOG) { 00079 fnum = _log_facility(facility); 00080 if (fnum < 0) 00081 fnum = LOG_LOCAL7; 00082 openlog(ident, LOG_PID, fnum); 00083 return log; 00084 } 00085 00086 else if(type == log_STDOUT) { 00087 log->file = stdout; 00088 return log; 00089 } 00090 00091 log->file = fopen(ident, "a+"); 00092 if(log->file == NULL) 00093 { 00094 fprintf(stderr, 00095 "ERROR: couldn't open logfile: %s\n" 00096 " logging will go to stdout instead\n", strerror(errno)); 00097 log->type = log_STDOUT; 00098 log->file = stdout; 00099 } 00100 00101 return log; 00102 } 00103 00104 void log_write(log_t log, int level, const char *msgfmt, ...) 00105 { 00106 va_list ap; 00107 char *pos, message[MAX_LOG_LINE+1]; 00108 int sz, len; 00109 time_t t; 00110 00111 if(log && log->type == log_SYSLOG) { 00112 va_start(ap, msgfmt); 00113 #ifdef HAVE_VSYSLOG 00114 vsyslog(level, msgfmt, ap); 00115 #else 00116 len = vsnprintf(message, MAX_LOG_LINE, msgfmt, ap); 00117 if (len > MAX_LOG_LINE) 00118 message[MAX_LOG_LINE] = '\0'; 00119 else 00120 message[len] = '\0'; 00121 syslog(level, "%s", message); 00122 #endif 00123 va_end(ap); 00124 00125 #ifndef DEBUG 00126 return; 00127 #endif 00128 } 00129 00130 /* timestamp */ 00131 t = time(NULL); 00132 pos = ctime(&t); 00133 sz = strlen(pos); 00134 /* chop off the \n */ 00135 pos[sz-1]=' '; 00136 00137 /* insert the header */ 00138 len = snprintf(message, MAX_LOG_LINE, "%s[%s] ", pos, _log_level[level]); 00139 if (len > MAX_LOG_LINE) 00140 message[MAX_LOG_LINE] = '\0'; 00141 else 00142 message[len] = '\0'; 00143 00144 /* find the end and attach the rest of the msg */ 00145 for (pos = message; *pos != '\0'; pos++); /*empty statement */ 00146 sz = pos - message; 00147 va_start(ap, msgfmt); 00148 vsnprintf(pos, MAX_LOG_LINE - sz, msgfmt, ap); 00149 va_end(ap); 00150 #ifndef DEBUG 00151 if(log && log->type != log_SYSLOG) { 00152 #endif 00153 if(log && log->file) { 00154 fprintf(log->file,"%s", message); 00155 fprintf(log->file, "\n"); 00156 fflush(log->file); 00157 } 00158 #ifndef DEBUG 00159 } 00160 #endif 00161 00162 #ifdef DEBUG 00163 if (!debug_log_target) { 00164 debug_log_target = stderr; 00165 } 00166 /* If we are in debug mode we want everything copied to the stdout */ 00167 if ((log == 0) || (get_debug_flag() && log->type != log_STDOUT)) { 00168 fprintf(debug_log_target, "%s\n", message); 00169 fflush(debug_log_target); 00170 } 00171 #endif /*DEBUG*/ 00172 } 00173 00174 void log_free(log_t log) { 00175 if(log->type == log_SYSLOG) 00176 closelog(); 00177 else if(log->type == log_FILE) 00178 fclose(log->file); 00179 00180 free(log); 00181 } 00182 00183 #ifdef DEBUG 00184 00185 void debug_log(const char *file, int line, const char *msgfmt, ...) 00186 { 00187 va_list ap; 00188 char *pos, message[MAX_DEBUG]; 00189 int sz; 00190 time_t t; 00191 00192 if (!debug_log_target) { 00193 debug_log_target = stderr; 00194 } 00195 /* timestamp */ 00196 t = time(NULL); 00197 pos = ctime(&t); 00198 sz = strlen(pos); 00199 /* chop off the \n */ 00200 pos[sz-1]=' '; 00201 00202 /* insert the header */ 00203 snprintf(message, MAX_DEBUG, "%s%s:%d ", pos, file, line); 00204 00205 /* find the end and attach the rest of the msg */ 00206 for (pos = message; *pos != '\0'; pos++); /*empty statement */ 00207 sz = pos - message; 00208 va_start(ap, msgfmt); 00209 vsnprintf(pos, MAX_DEBUG - sz, msgfmt, ap); 00210 va_end(ap); 00211 fprintf(debug_log_target,"%s", message); 00212 fprintf(debug_log_target, "\n"); 00213 fflush(debug_log_target); 00214 } 00215 00216 int get_debug_flag(void) 00217 { 00218 return debug_flag; 00219 } 00220 00221 void set_debug_flag(int v) 00222 { 00223 debug_flag = v; 00224 } 00225 00226 int set_debug_log_from_config(config_t c) 00227 { 00228 return set_debug_file(config_get_one(c, "log.debug", 0)); 00229 }; 00230 00231 JABBERD2_API int set_debug_file(const char *filename) 00232 { 00233 // Close debug output file but not stderr 00234 if (debug_log_target != 0 && 00235 debug_log_target != stderr) 00236 { 00237 fprintf(debug_log_target, "Closing log\n"); 00238 fclose(debug_log_target); 00239 00240 debug_log_target = stderr; 00241 } 00242 00243 // Setup new log target 00244 if (filename) { 00245 log_debug(ZONE, "Openning debug log file %s", filename); 00246 debug_log_target = fopen(filename, "a+"); 00247 00248 if (debug_log_target) { 00249 log_debug(ZONE, "Staring debug log"); 00250 } else { 00251 debug_log_target = stderr; 00252 log_debug(ZONE, "Failed to open debug output file %s. Fallback to stderr", filename); 00253 } 00254 } else { 00255 // set stderr 00256 debug_log_target = stderr; 00257 } 00258 }; 00259 00260 #else /* DEBUG */ 00261 void debug_log(const char *file, int line, const char *msgfmt, ...) 00262 { } 00263 00264 void set_debug_flag(int v) 00265 { } 00266 #endif