2 * This file is part of the OpenPTS project.
4 * The Initial Developer of the Original Code is International
5 * Business Machines Corporation. Portions created by IBM
6 * Corporation are Copyright (C) 2010, 2011 International Business
7 * Machines Corporation. All Rights Reserved.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the Common Public License as published by
11 * IBM Corporation; either version 1 of the License, or (at your option)
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * Common Public License for more details.
19 * You should have received a copy of the Common Public License
20 * along with this program; if not, a copy can be viewed at
21 * http://www.opensource.org/licenses/cpl1.0.php.
26 * \brief logging functions
27 * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
29 * cleanup 2011-01-22 SM
30 * cleanup 2011-12-28 SM
32 * Verbose OUTPUT VERBOSE LOGGING
33 * Level (stdout) (stderr) (console/syslog/file)
34 * --------------------------------------------------
35 * 0 ON ERROR msg. ERROR/INFO
36 * 1 ON +verbose msg. ERROR/INFO
37 * 2 ON ERROR/INFO+DEBUG
38 * --------------------------------------------------
47 * logging.location=console|syslog|file
48 * logging.file=./ptsc.log
52 * 1. Commandline option (location/file must be given by conf)
58 * OUTPUT console/stderr
59 * VERBOSE console/stderr
60 * ASSERT console/stderr
62 * ERROR console|file|syslog
63 * INFO console|file|syslog
64 * TODO console|file|syslog
65 * DEBUG console|file|syslog
71 #include <stdlib.h> /* getenv */
72 #include <stdarg.h> /* va_ */
75 #include <sys/param.h>
82 #include <openpts_log.h>
84 #define SYSLOG_BUF_SIZE 1024
88 #ifndef DEFAULT_LOG_LOCATION
89 #define DEFAULT_LOG_LOCATION OPENPTS_LOG_FILE
91 #ifndef DEFAULT_LOG_FILE
92 #define DEFAULT_LOG_FILE "/var/adm/ras/openpts/log"
94 #define DEFAULT_LOG_FILE_PERM (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH)
95 #define DEFAULT_LOG_FILE_SIZE 0x100000
99 #define DEFAULT_LOG_LOCATION OPENPTS_LOG_FILE
100 #define DEFAULT_LOG_FILE "~/.openpts/openpts.log"
101 #define DEFAULT_LOG_FILE_PERM (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH)
102 #define DEFAULT_LOG_FILE_SIZE 0x100000
109 #include <nl_types.h>
114 /* external variables for logging macros */
118 /* global variables for this file */
119 static int logLocation = OPENPTS_LOG_UNDEFINED;
120 static char logFileName[256];
121 static FILE *logFile = NULL;
122 static int logFileFd = -1;
123 static int alreadyWarnedAboutLogFile = 0;
125 static int openLogFile(void);
126 static void addToLog(char* log_entry);
128 static char * command_name = NULL;
133 void initCatalog(void) {
135 (void) setlocale(LC_ALL, "");
137 catd = catopen(MF_OPENPTS, NL_CAT_LOCALE);
139 bindtextdomain(PACKAGE, LOCALEDIR);
148 static void expandLogFilePath(char *unexpandedPath) {
149 char *srcPtr = unexpandedPath;
150 char *destPtr = logFileName;
151 char *destEnd = destPtr + 255; /* leave space for '\0' */
152 char *homeDir = NULL;
155 while ((destPtr < destEnd) && ('\0' != srcPtr[0])) {
156 int destCharsWritten;
157 if ('~' == srcPtr[0]) {
158 int destSpaceLeft = destEnd - destPtr;
159 if (NULL == homeDir) {
160 homeDir = getenv("HOME");
161 homeDirLen = strlen(homeDir);
163 destCharsWritten = MIN(destSpaceLeft, homeDirLen);
164 memcpy(destPtr, homeDir, destCharsWritten);
166 destPtr[0] = srcPtr[0];
167 destCharsWritten = 1;
170 destPtr += destCharsWritten;
177 * set LogLocation by ENV
179 * export OPENPTS_LOG_FILE=/tmp/openpts.log
180 * export OPENPTS_LOG_CONSOLE=1
181 * export OPENPTS_LOG_SYSLOG=1
182 * export OPENPTS_DEBUG_MODE=0x01
184 void determineLogLocationByEnv(void) {
185 char *tempLogFileName = NULL;
186 char *tempDebugMode = NULL;
189 if (getenv("OPENPTS_LOG_SYSLOG") != NULL) {
190 logLocation = OPENPTS_LOG_SYSLOG;
191 } else if (getenv("OPENPTS_LOG_CONSOLE") != NULL) {
192 logLocation = OPENPTS_LOG_CONSOLE;
194 } else if ((tempLogFileName = getenv("OPENPTS_LOG_FILE")) != NULL) {
195 logLocation = OPENPTS_LOG_FILE;
196 } else if (getenv("OPENPTS_LOG_NULL") != NULL) {
197 logLocation = OPENPTS_LOG_NULL;
199 logLocation = DEFAULT_LOG_LOCATION;
200 tempLogFileName = DEFAULT_LOG_FILE;
203 if (logLocation == OPENPTS_LOG_FILE) {
204 expandLogFilePath(tempLogFileName);
207 /* debug mode => debugBits */
208 if ((tempDebugMode = getenv("OPENPTS_DEBUG_MODE")) != NULL) {
209 debugBits = (int) strtol(tempDebugMode,NULL,16);
210 DEBUG("DEBUG FLAG(0x%x) set by ENV\n", debugBits);
215 * Force custom log location by app itself
217 void setLogLocation(int ll, char *filename) {
220 if (ll == OPENPTS_LOG_FILE) {
221 if (logFileFd != -1) {
224 LOG(LOG_INFO, "Logfile changed from %s to %s\n", logFileName, filename);
225 oldlog=strdup(logFileName);
226 if (oldlog == NULL) {
227 LOG(LOG_ERR, "no memory");
232 expandLogFilePath(filename);
233 LOG(LOG_INFO, "Logfile changed from %s to %s\n", oldlog, logFileName);
236 if (filename != NULL) {
237 expandLogFilePath(filename);
239 expandLogFilePath(DEFAULT_LOG_FILE);
245 void setSyslogCommandName(char *name) {
250 * return loglocation in String (char*)
252 char *getLogLocationString() {
253 if (logLocation == OPENPTS_LOG_SYSLOG) {
255 } else if (logLocation == OPENPTS_LOG_CONSOLE) {
256 return "console(stderr)";
257 } else if (logLocation == OPENPTS_LOG_NULL) {
259 } else if (logLocation == OPENPTS_LOG_FILE) {
262 LOG(LOG_ERR, "logLocation %d\n", logLocation);
270 static void createLogEntry(
277 const char *priorities[1 + LOG_DEBUG] = {
287 /* number of chars written (not including '\0') */
288 int charsWritten = 0;
290 if (priority > LOG_DEBUG) {
291 charsWritten = snprintf(buf, bufLen, "[UNKNOWN (%d)] ", priority);
293 charsWritten = snprintf(buf, bufLen, "%s", priorities[priority]);
296 if ( charsWritten >= bufLen ) {
297 /* string was truncated */
301 charsWritten += vsnprintf(&buf[charsWritten], bufLen - charsWritten, format, list);
303 if ( charsWritten >= bufLen ) {
304 /* string was truncated */
308 if ( (charsWritten + 1) < bufLen ) {
309 buf[charsWritten] = '\n';
310 buf[++charsWritten] = '\0';
317 void writeLog(int priority, const char *format, ...) {
319 char *format2 = NULL;
321 va_start(list, format);
324 if (logLocation == OPENPTS_LOG_UNDEFINED) {
325 determineLogLocationByEnv();
329 if (logLocation == OPENPTS_LOG_NULL) {
330 /* disable logging */
336 len = strlen(format);
337 if (format[len - 1] == '\n') {
338 // format2 = malloc(len + 1); // +1 space
339 format2 = (char *) malloc(len);
340 if (format2 != NULL) {
341 memcpy(format2, format, len - 1);
342 format2[len - 1] = 0;
347 switch (logLocation) {
348 case OPENPTS_LOG_SYSLOG:
350 char buf[SYSLOG_BUF_SIZE];
352 /* ptsc -m (IF-M) -> syslog */
353 if (command_name == NULL) {
354 openlog("ptsc", LOG_NDELAY|LOG_PID, LOG_LOCAL5);
356 openlog(command_name, LOG_NDELAY|LOG_PID, LOG_LOCAL5);
359 /* vsyslog is not supported by some unix */
360 vsnprintf(buf, SYSLOG_BUF_SIZE, format, list);
362 /* priority is controlled by syslog conf */
363 /* for DEBUG, use OPENPTS_LOG_FILE */
364 syslog(priority, "%s", buf);
369 case OPENPTS_LOG_FILE:
371 if (openLogFile() == -1) {
372 if ( !alreadyWarnedAboutLogFile ) {
373 fprintf(stderr, NLS(MS_OPENPTS, OPENPTS_CANNOT_OPEN_LOGFILE,
374 "Unable to open logfile '%s'\n"), logFileName);
375 alreadyWarnedAboutLogFile = 1;
377 /* fall through to next case */
380 createLogEntry(priority, logEntry, 1024, format, list);
385 case OPENPTS_LOG_CONSOLE:
388 createLogEntry(priority, logEntry, 1024, format, list);
389 fprintf(stderr, "%s", logEntry);
397 va_start(list, format);
399 // if (getenv("PTSCD_DAEMON") != NULL) {
400 if (getenv("OPENPTS_SYSLOG") != NULL) {
401 /* daemon -> syslog */
402 openlog("ptsc", LOG_NDELAY|LOG_PID, LOG_LOCAL5);
404 // 2011-04-11 SM shows verbose messages
405 if (priority == LOG_DEBUG) priority = LOG_INFO;
407 // vsyslog is not supported by some unix
408 vsnprintf(buf, SYSLOG_BUF_SIZE, format, list);
409 syslog(priority, "%s", buf);
413 /* foregrond -> stdout */
414 if (priority == LOG_INFO) {
415 fprintf(stdout, "INFO:");
416 } else if (priority == LOG_ERR) {
417 fprintf(stdout, "ERROR:");
419 fprintf(stdout, "%d:", priority);
421 vfprintf(stdout, format, list);
422 fprintf(stdout, "\n");
428 if (format2 != NULL) free(format2);
433 static int openLogFile(void) {
434 if (logFileFd != -1) {
438 //logFileFd = open(logFileName, O_RDWR|O_CREAT|O_TRUNC, DEFAULT_LOG_FILE_PERM);
439 logFileFd = open(logFileName, O_WRONLY|O_CREAT|O_APPEND, DEFAULT_LOG_FILE_PERM);
443 static void addToLog(char* log_entry) {
444 /* Warnings are treated as errors so need this ugly code to build */
445 ssize_t n = write(logFileFd, log_entry, strlen(log_entry));