1#ifndef _ATALK_LOGGER_H 2#define _ATALK_LOGGER_H 1 3 4/* 5 * logger LOG Macro Usage 6 * ====================== 7 * 8 * LOG(<logtype>, <loglevel>, "<string>"[, args]); 9 * 10 * 11 * logger API Setup 12 * ================ 13 * 14 * Standard interface: 15 * ------------------- 16 * 17 * setuplog(char *confstring) 18 * confstring = "<logtype> <loglevel> [<filename>]" 19 * 20 * Calling without <filename> configures basic logging to syslog. Specifying <filename> 21 * configures extended logging to <filename>. 22 * 23 * You can later disable logging by calling 24 * 25 * unsetuplog(char *confstring) 26 * confstring = "<logtype> [<any_string>]" 27 * 28 * Calling without <any_string> disables syslog logging, calling with <any_string> 29 * disables file logging. 30 * 31 * <logtype>: 32 * you can setup a default with "Default". Any other logtype used in LOG will then 33 * use the default if not setup itself. This is probabyl the only thing you may 34 * want to use. 35 * 36 * Example: 37 * setuplog("default log_debug /var/log/debug.log"); 38 * See also libatalk/util/test/logger_test.c 39 * 40 * "Legacy" interface: 41 * ------------------- 42 * 43 * Some netatalk daemons (31.3.2009.: e.g. atalkd, papd) may not be converted to 44 * use the new API and might still call 45 * 46 * syslog_setup(int loglevel, enum logtypes logtype, int display_options, int facility); 47 * 48 * directly. These daemons are therefore limited to syslog logging. Also their 49 * loglevel can't be changed at runtime. 50 * 51 * 52 * Note: 53 * dont get confused by log_init(). It only gets called if your app 54 * forgets to setup logging before calling LOG. 55 */ 56 57 58#include <limits.h> 59#include <stdio.h> 60 61#include <atalk/boolean.h> 62 63#ifdef HAVE_CONFIG_H 64#include "config.h" 65#endif 66 67/* logger is used by pam modules */ 68#ifndef UAM_MODULE_EXPORT 69#define UAM_MODULE_EXPORT 70#endif 71 72enum loglevels { 73 log_none, 74 log_severe, 75 log_error, 76 log_warning, 77 log_note, 78 log_info, 79 log_debug, 80 log_debug6, 81 log_debug7, 82 log_debug8, 83 log_debug9, 84 log_maxdebug 85}; 86 87/* this is the enum specifying all availiable logtypes */ 88enum logtypes { 89 logtype_default, 90 logtype_logger, 91 logtype_cnid, 92 logtype_afpd, 93 logtype_dsi, 94 logtype_atalkd, 95 logtype_papd, 96 logtype_uams, 97 logtype_end_of_list_marker /* don't put any logtypes after this */ 98}; 99 100 101/* Display Option flags. */ 102/* redefine these so they can don't interfeer with syslog */ 103/* these can be used in standard logging too */ 104#define logoption_nsrcinfo 0x04 /* don't log source info */ 105/* the following do not work anymore, they're only provided in order to not 106 * break existing source code */ 107#define logoption_pid 0x01 /* log the pid with each message */ 108#define logoption_cons 0x02 /* log on the console if error logging */ 109#define logoption_ndelay 0x08 /* don't delay open */ 110#define logoption_perror 0x20 /* log to stderr as well */ 111#define logoption_nfile 0x40 /* ignore the file that called the log */ 112#define logoption_nline 0x80 /* ignore the line that called the log*/ 113 114/* facility codes */ 115/* redefine these so they can don't interfeer with syslog */ 116#define logfacility_user (1<<3) /* random user-level messages */ 117#define logfacility_mail (2<<3) /* mail system */ 118#define logfacility_daemon (3<<3) /* system daemons */ 119#define logfacility_auth (4<<3) /* security/authorization messages */ 120#define logfacility_syslog (5<<3) /* messages generated by syslogd */ 121#define logfacility_lpr (6<<3) /* line printer subsystem */ 122#define logfacility_authpriv (10<<3) /* security/auth messages (private) */ 123#define logfacility_ftp (11<<3) /* ftp daemon */ 124 125/* ========================================================================= 126 Structure definitions 127 ========================================================================= */ 128 129/* Main log config */ 130typedef struct { 131 bool inited; /* file log config initialized ? */ 132 bool syslog_opened; /* syslog opened ? */ 133 bool console; /* if logging to console from a cli util */ 134 char processname[16]; 135 int syslog_facility; 136 int syslog_display_options; 137} log_config_t; 138 139/* This stores the config and options for one filelog type (e.g. logger, afpd etc.) */ 140typedef struct { 141 bool set; /* set individually ? yes: changing default 142 * doesnt change it. no: it changes it.*/ 143 bool syslog; /* This type logs to syslog */ 144 int fd; /* logfiles fd */ 145 enum loglevels level; /* Log Level to put in this file */ 146 int display_options; 147} logtype_conf_t; 148 149 150/* ========================================================================= 151 Global variables 152 ========================================================================= */ 153 154/* Make config accessible for LOG macro */ 155extern log_config_t log_config; 156 157extern UAM_MODULE_EXPORT logtype_conf_t type_configs[logtype_end_of_list_marker]; 158 159/* ========================================================================= 160 Global function decarations 161 ========================================================================= */ 162 163/* */ 164void log_init(void); 165 166/* Setup the level and type of log that will be logged for file loggging */ 167void log_setup(const char *filename, enum loglevels loglevel, enum logtypes logtype); 168 169/* Setup the level and type of log that will be logged to syslog. */ 170void syslog_setup(int loglevel, enum logtypes logtype, 171 int display_options, int facility); 172 173/* This gets called e.g. from afpd.conf parsing code with a string like: */ 174/* "default log_maxdebug /var/log/afpd.log" */ 175void setuplog(const char *logstr); 176 177/* This gets called e.g. from afpd.conf parsing code with a string like: */ 178/* "default dummyname" */ 179void unsetuplog(const char *logstr); 180 181/* finish up and close the logs */ 182void log_close(void); 183 184/* This function sets up the ProcessName */ 185void set_processname(const char *processname); 186 187/* LOG macro func no.1: log the message to file */ 188UAM_MODULE_EXPORT void make_log_entry(enum loglevels loglevel, enum logtypes logtype, const char *file, int line, char *message, ...); 189 190/* 191 * How to write a LOG macro: 192 * http://c-faq.com/cpp/debugmacs.html 193 * 194 * We choose the verbose form in favor of the obfuscated ones, its easier 195 * to parse for human beings and facilitates expanding the macro for 196 * inline checks for debug levels. 197 * 198 * How to properly enclose multistatement macros: 199 * http://en.wikipedia.org/wiki/C_macro#Multiple_statements 200 */ 201 202#define LOG_MAX log_info 203 204#ifdef NO_DEBUG 205 206#define LOG(log_level, type, ...) \ 207 do { \ 208 if (log_level <= LOG_MAX) \ 209 if (log_level <= type_configs[type].level) \ 210 make_log_entry((log_level), (type), __FILE__, __LINE__, __VA_ARGS__); \ 211 } while(0) 212 213#else /* ! NO_DEBUG */ 214 215#define LOG(log_level, type, ...) \ 216 do { \ 217 if (log_level <= type_configs[type].level) \ 218 make_log_entry((log_level), (type), __FILE__, __LINE__, __VA_ARGS__); \ 219 } while(0) 220 221#endif /* NO_DEBUG */ 222 223#endif /* _ATALK_LOGGER_H */ 224