diff options
author | Steve Bennett <steveb@workware.net.au> | 2010-01-24 10:26:24 +1000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2010-10-15 11:02:38 +1000 |
commit | 1df9b19429212012b245a88b08ab37caef564d1c (patch) | |
tree | e48d6153d5cde43723f2729d92e0b75d7e848ea1 /jim-syslog.c | |
parent | c4ec906079ac99fe52e8c4b27036ca0f2495848f (diff) | |
download | jimtcl-1df9b19429212012b245a88b08ab37caef564d1c.zip jimtcl-1df9b19429212012b245a88b08ab37caef564d1c.tar.gz jimtcl-1df9b19429212012b245a88b08ab37caef564d1c.tar.bz2 |
Implement some new features
Implement 'lreplace'
Implement 'string last'
Implement 'pid'
Implement 'info procs'
Implement 'info script'
Implement 'info patchlevel' as an alias for 'info version'
Implement syslog extensions for jim
Fix return code display in jim-interactive.c
Make jim more compatible if JIM_TCL_COMPAT is set
*: Use tcl_interactive rather than jim_interactive
*: Use auto_path rather than jim_libpath
Add "." to the lib search path, not "./"
Fix a couple of files with CRLF line endings
Diffstat (limited to 'jim-syslog.c')
-rw-r--r-- | jim-syslog.c | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/jim-syslog.c b/jim-syslog.c new file mode 100644 index 0000000..4a039ef --- /dev/null +++ b/jim-syslog.c @@ -0,0 +1,199 @@ +/* Syslog interface for tcl + * Copyright Victor Wagner <vitus@ice.ru> at + * http://www.ice.ru/~vitus/works/tcl.html#syslog + * + * Slightly modified by Steve Bennett <steveb@snapgear.com> + * Ported to Jim by Steve Bennett <steveb@workware.net.au> + */ +#include <jim.h> +#include <syslog.h> +#include <string.h> + +typedef struct { + int logOpened; + int facility; + int options; + char ident[32]; +} SyslogInfo; + +#ifndef LOG_AUTHPRIV +# define LOG_AUTHPRIV LOG_AUTH +#endif + +static const char *facilities[] = { + [LOG_AUTHPRIV] = "authpriv", + [LOG_CRON] = "cron", + [LOG_DAEMON] = "daemon", + [LOG_KERN] = "kernel", + [LOG_LPR] = "lpr", + [LOG_MAIL] = "mail", + [LOG_NEWS] = "news", + [LOG_SYSLOG] = "syslog", + [LOG_USER] = "user", + [LOG_UUCP] = "uucp", + [LOG_LOCAL0] = "local0", + [LOG_LOCAL1] = "local1", + [LOG_LOCAL2] = "local2", + [LOG_LOCAL3] = "local3", + [LOG_LOCAL4] = "local4", + [LOG_LOCAL5] = "local5", + [LOG_LOCAL6] = "local6", + [LOG_LOCAL7] = "local7", +}; + +static const char *priorities[] = { + [LOG_EMERG] = "emerg", + [LOG_ALERT] = "alert", + [LOG_CRIT] = "crit", + [LOG_ERR] = "err", + [LOG_ERR] = "error", + [LOG_WARNING] = "warning", + [LOG_NOTICE] = "notice", + [LOG_INFO] = "info", + [LOG_DEBUG] = "debug", +}; + +/** + * Find a matching name in the array of the given length. + * + * NULL entries are ignored. + * + * Returns the matching index if found, or -1 if not. + */ +static int find_by_name(const char *name, const char *array[], size_t len) +{ + int i; + for (i = 0; i < len; i++) { + if (array[i] && strcmp(array[i], name) == 0) { + return i; + } + } + return -1; +} + +/** + * Deletes the syslog command. + */ +static void Jim_SyslogCmdDelete(Jim_Interp *interp, void *privData) +{ + SyslogInfo *info=(SyslogInfo *)privData; + if (info->logOpened) { + closelog(); + } + Jim_Free(info); +} + +/* Syslog_Log - + * implements syslog tcl command. General format: syslog ?options? level text + * options -facility -ident -options + * + * syslog ?-facility cron|daemon|...? ?-ident string? ?-options int? ?debug|info|...? text + */ +int +Jim_SyslogCmd (Jim_Interp *interp, int argc, Jim_Obj *const *argv) +{ + int priority = LOG_INFO; + int i=1; + SyslogInfo *info = Jim_CmdPrivData(interp); + + if (argc <= 1) { +wrongargs: + Jim_WrongNumArgs(interp, 1, argv, "?-facility cron|daemon|...? ?-ident string? ?-options int? ?debug|info|...? message"); + return JIM_ERR; + } + while (i < argc-1) { + if (Jim_CompareStringImmediate(interp, argv[i], "-facility")) { + int entry = find_by_name(Jim_GetString(argv[i + 1], NULL), facilities, sizeof(facilities) / sizeof(*facilities)); + if (entry < 0) { + Jim_SetResultString(interp, "Unknown facility", -1); + return JIM_ERR; + } + if (info->facility != entry) { + info->facility = entry; + if (info->logOpened) { + closelog(); + info->logOpened=0; + } + } + } + else if (Jim_CompareStringImmediate(interp, argv[i], "-options")) { + long tmp; + if (Jim_GetLong(interp, argv[i+1], &tmp) == JIM_ERR) { + return JIM_ERR; + } + info->options = tmp; + if (info->logOpened) { + closelog(); + info->logOpened=0; + } + continue; + } + else if (Jim_CompareStringImmediate(interp, argv[i], "-ident")) { + strncpy(info->ident, Jim_GetString(argv[i+1], NULL), sizeof(info->ident)); + info->ident[sizeof(info->ident) - 1] = 0; + if (info->logOpened) { + closelog(); + info->logOpened=0; + } + } + else { + break; + } + i += 2; + } + + /* There should be either 0, 1 or 2 args left */ + if (i == argc) { + /* No args, but they have set some options, so OK */ + return JIM_OK; + } + + if (i<argc-1) { + priority = find_by_name(Jim_GetString(argv[i], NULL), priorities, sizeof(priorities) / sizeof(*priorities)); + if (priority < 0) { + Jim_SetResultString(interp, "Unknown priority", -1); + return JIM_ERR; + } + i++; + } + + if (i != argc - 1) { + goto wrongargs; + } + if (!info->logOpened) { + if (!info->ident[0]) { + Jim_Obj *argv0 = Jim_GetGlobalVariableStr(interp, "argv0", JIM_NONE); + if (argv0) { + strncpy(info->ident, Jim_GetString(argv0, NULL), sizeof(info->ident)); + } else { + strcpy(info->ident,"Tcl script"); + } + info->ident[sizeof(info->ident) - 1] = 0; + } + openlog(info->ident, info->options, info->facility); + info->logOpened=1; + } + syslog(priority, "%s", Jim_GetString(argv[i], NULL)); + + return JIM_OK; +} + +int Jim_syslogInit(Jim_Interp *interp) +{ + SyslogInfo *info; + + if (Jim_PackageProvide(interp, "syslog", "1.0", JIM_ERRMSG) != JIM_OK) { + return JIM_ERR; + } + + info = Jim_Alloc(sizeof(*info)); + + info->logOpened=0; + info->options=0; + info->facility=LOG_USER; + info->ident[0] = 0; + + Jim_CreateCommand(interp, "syslog", Jim_SyslogCmd, info, Jim_SyslogCmdDelete); + + return JIM_OK; +} |