#ifndef _ATALK_LOGGER_H
#define _ATALK_LOGGER_H 1
+/*
+ * logger LOG Macro Usage
+ * ======================
+ *
+ * LOG(<logtype>, <loglevel>, "<string>"[, args]);
+ *
+ *
+ * logger API Setup
+ * ================
+ *
+ * Standard interface:
+ * -------------------
+ *
+ * setuplog(char *confstring)
+ * confstring = "<logtype> <loglevel> [<filename>]"
+ *
+ * Calling without <filename> configures basic logging to syslog. Specifying <filename>
+ * configures extended logging to <filename>.
+ *
+ * You can later disable logging by calling
+ *
+ * unsetuplog(char *confstring)
+ * confstring = "<logtype> [<any_string>]"
+ *
+ * Calling without <any_string> disables syslog logging, calling with <any_string>
+ * disables file logging.
+ *
+ * <logtype>:
+ * you can setup a default with "Default". Any other logtype used in LOG will then
+ * use the default if not setup itself. This is probabyl the only thing you may
+ * want to use.
+ *
+ * Example:
+ * setuplog("default log_debug /var/log/debug.log");
+ * See also libatalk/util/test/logger_test.c
+ *
+ * "Legacy" interface:
+ * -------------------
+ *
+ * Some netatalk daemons (31.3.2009.: e.g. atalkd, papd) may not be converted to
+ * use the new API and might still call
+ *
+ * syslog_setup(int loglevel, enum logtypes logtype, int display_options, int facility);
+ *
+ * directly. These daemons are therefore limited to syslog logging. Also their
+ * loglevel can't be changed at runtime.
+ *
+ *
+ * Note:
+ * dont get confused by log_init(). It only gets called if your app
+ * forgets to setup logging before calling LOG.
+ */
+
+
#include <limits.h>
#include <stdio.h>
-
-#include <atalk/boolean.h>
+#include <stdbool.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#define MAXLOGSIZE 512
+/* logger is used by pam modules */
+#ifndef UAM_MODULE_EXPORT
+#define UAM_MODULE_EXPORT
+#endif
enum loglevels {
- log_none = 0,
- log_severe = 10,
- log_error = 20,
- log_warning = 30,
- log_note = 40,
- log_info = 50,
- log_debug = 60,
- log_debug6 = 70,
- log_debug7 = 80,
- log_debug8 = 90,
- log_debug9 = 100,
- log_maxdebug = 110
+ log_none,
+ log_severe,
+ log_error,
+ log_warning,
+ log_note,
+ log_info,
+ log_debug,
+ log_debug6,
+ log_debug7,
+ log_debug8,
+ log_debug9,
+ log_maxdebug
};
-#define LOGLEVEL_STRING_IDENTIFIERS { \
- "LOG_NOTHING", \
- "LOG_SEVERE", \
- "LOG_ERROR", \
- "LOG_WARN", \
- "LOG_NOTE", \
- "LOG_INFO", \
- "LOG_DEBUG", \
- "LOG_DEBUG6", \
- "LOG_DEBUG7", \
- "LOG_DEBUG8", \
- "LOG_DEBUG9", \
- "LOG_MAXDEBUG"}
/* this is the enum specifying all availiable logtypes */
enum logtypes {
logtype_default,
- logtype_core,
logtype_logger,
logtype_cnid,
logtype_afpd,
- logtype_atalkd,
- logtype_papd,
+ logtype_dsi,
logtype_uams,
-
+ logtype_fce,
+ logtype_ad,
+ logtype_sl,
logtype_end_of_list_marker /* don't put any logtypes after this */
};
-/* these are the string identifiers corresponding to each logtype */
-#define LOGTYPE_STRING_IDENTIFIERS { \
- "Default", \
- "Core", \
- "Logger", \
- "CNID", \
- "AFPDaemon", \
- "ATalkDaemon", \
- "PAPDaemon", \
- "UAMSDaemon", \
- \
- "end_of_list_marker"} \
/* Display Option flags. */
/* redefine these so they can don't interfeer with syslog */
/* Main log config */
typedef struct {
- int inited; /* file log config initialized ? */
- int filelogging; /* Any level set to filelogging ? */
- /* Deactivates syslog logging */
- char processname[16];
- int syslog_opened; /* syslog opened ? */
- int facility; /* syslog facility to use */
- int syslog_display_options;
- int syslog_level; /* Log Level to send to syslog */
+ bool inited; /* file log config initialized ? */
+ bool syslog_opened; /* syslog opened ? */
+ bool console; /* if logging to console from a cli util */
+ char processname[16];
+ int syslog_facility;
+ int syslog_display_options;
} log_config_t;
/* This stores the config and options for one filelog type (e.g. logger, afpd etc.) */
typedef struct {
- int set; /* set individually ? yes: changing default
- * doesnt change it. no: it changes it.*/
- char *filename; /* Name of file */
- int fd; /* logfiles fd */
- int level; /* Log Level to put in this file */
- int display_options;
-} filelog_conf_t;
+ bool set; /* set individually ? yes: changing default
+ * doesnt change it. no: it changes it.*/
+ bool syslog; /* This type logs to syslog */
+ int fd; /* logfiles fd */
+ enum loglevels level; /* Log Level to put in this file */
+ int display_options;
+} logtype_conf_t;
+
/* =========================================================================
Global variables
- ========================================================================= */
+ ========================================================================= */
-#ifndef LOGGER_C
/* Make config accessible for LOG macro */
extern log_config_t log_config;
-extern filelog_conf_t file_configs[logtype_end_of_list_marker];
-/* These are used by the LOG macro to store __FILE__ and __LINE__ */
-extern char *log_src_filename;
-extern int log_src_linenumber;
-#endif
+extern UAM_MODULE_EXPORT logtype_conf_t type_configs[logtype_end_of_list_marker];
/* =========================================================================
Global function decarations
========================================================================= */
-/* */
-void log_init(void);
-
-/* Setup the level and type of log that will be logged for file loggging */
-bool log_setup(char *filename, enum loglevels loglevel, enum logtypes logtype);
-
-/* Setup the level and type of log that will be logged to syslog. */
-//void syslog_setup(enum loglevels loglevel);
-void syslog_setup(int loglevel, enum logtypes logtype,
- int display_options, int facility);
-
-/* void setuplog(char *logsource, char *logtype, char *loglevel, char *filename); */
-void setuplog(char *logtype, char *loglevel, char *filename);
+void setuplog(const char *loglevel, const char *logfile);
+void set_processname(const char *processname);
-/* finish up and close the logs */
-void log_close();
-
-/* This function sets up the ProcessName */
-void set_processname(char *processname);
+/* LOG macro func no.1: log the message to file */
+UAM_MODULE_EXPORT void make_log_entry(enum loglevels loglevel, enum logtypes logtype, const char *file, int line, char *message, ...);
/*
* How to write a LOG macro:
* We choose the verbose form in favor of the obfuscated ones, its easier
* to parse for human beings and facilitates expanding the macro for
* inline checks for debug levels.
- *
- * How to properly enclose multistatement macros:
- * http://en.wikipedia.org/wiki/C_macro#Multiple_statements
*/
-/* LOG macro func no.1: log the message to file */
-void make_log_entry(enum loglevels loglevel, enum logtypes logtype, char *message, ...);
+#define LOG_MAX log_info
-/* LOG macro func no.2: log the message to syslog */
-void make_syslog_entry(enum loglevels loglevel, enum logtypes logtype, char *message, ...);
+#ifdef NO_DEBUG
-/*
- Note:
- any configured file-logging deactivates syslog logging
- */
+#define LOG(log_level, type, ...) \
+ do { \
+ if (log_level <= LOG_MAX) \
+ if (log_level <= type_configs[type].level) \
+ make_log_entry((log_level), (type), __FILE__, __LINE__, __VA_ARGS__); \
+ } while(0)
+
+#else /* ! NO_DEBUG */
+
+#define LOG(log_level, type, ...) \
+ do { \
+ if (log_level <= type_configs[type].level) \
+ make_log_entry((log_level), (type), __FILE__, __LINE__, __VA_ARGS__); \
+ } while(0)
+
+#endif /* NO_DEBUG */
-#define LOG(a,b, ...) \
- do { \
- if ( ! log_config.inited) \
- log_init(); \
- if (file_configs[b].level >= a) \
- log_src_filename = __FILE__, \
- log_src_linenumber = __LINE__, \
- make_log_entry(a, b, __VA_ARGS__); \
- else if (( ! log_config.filelogging) && (log_config.syslog_level >= a)) \
- make_syslog_entry(a, b, __VA_ARGS__); \
- } while(0)
#endif /* _ATALK_LOGGER_H */