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
108 #include <nl_types.h>
113 /* external variables for logging macros */
117 /* global variables for this file */
118 static int logLocation = OPENPTS_LOG_UNDEFINED;
119 static char logFileName[256];
120 static FILE *logFile = NULL;
121 static int logFileFd = -1;
122 static int alreadyWarnedAboutLogFile = 0;
124 static int openLogFile(void);
125 static void addToLog(char* log_entry);
127 static char * command_name = NULL;
132 void initCatalog(void) {
134 (void) setlocale(LC_ALL, "");
136 catd = catopen(MF_OPENPTS, NL_CAT_LOCALE);
138 bindtextdomain(PACKAGE, LOCALEDIR);
147 static void expandLogFilePath(char *unexpandedPath) {
148 char *srcPtr = unexpandedPath;
149 char *destPtr = logFileName;
150 char *destEnd = destPtr + 255; /* leave space for '\0' */
151 char *homeDir = NULL;
154 while ((destPtr < destEnd) && ('\0' != srcPtr[0])) {
155 int destCharsWritten;
156 if ('~' == srcPtr[0]) {
157 int destSpaceLeft = destEnd - destPtr;
158 if (NULL == homeDir) {
159 homeDir = getenv("HOME");
160 homeDirLen = strlen(homeDir);
162 destCharsWritten = MIN(destSpaceLeft, homeDirLen);
163 memcpy(destPtr, homeDir, destCharsWritten);
165 destPtr[0] = srcPtr[0];
166 destCharsWritten = 1;
169 destPtr += destCharsWritten;
176 * set LogLocation by ENV
178 * export OPENPTS_LOG_FILE=/tmp/openpts.log
179 * export OPENPTS_LOG_CONSOLE=1
180 * export OPENPTS_LOG_SYSLOG=1
181 * export OPENPTS_DEBUG_MODE=0x01
183 void determineLogLocationByEnv(void) {
184 char *tempLogFileName = NULL;
185 char *tempDebugMode = NULL;
190 if (getenv("OPENPTS_LOG_SYSLOG") != NULL) {
191 logLocation = OPENPTS_LOG_SYSLOG;
192 } else if (getenv("OPENPTS_LOG_CONSOLE") != NULL) {
193 logLocation = OPENPTS_LOG_CONSOLE;
195 } else if ((tempLogFileName = getenv("OPENPTS_LOG_FILE")) != NULL) {
196 logLocation = OPENPTS_LOG_FILE;
197 } else if (getenv("OPENPTS_LOG_NULL") != NULL) {
198 logLocation = OPENPTS_LOG_NULL;
200 logLocation = DEFAULT_LOG_LOCATION;
201 tempLogFileName = DEFAULT_LOG_FILE;
204 if (logLocation == OPENPTS_LOG_FILE) {
205 expandLogFilePath(tempLogFileName);
208 /* debug mode => debugBits */
209 if ((tempDebugMode = getenv("OPENPTS_DEBUG_MODE")) != NULL) {
210 debugBits = (int) strtol(tempDebugMode,NULL,16);
211 DEBUG("DEBUG FLAG(0x%x) set by ENV\n", debugBits);
216 * Force custom log location by app itself
218 void setLogLocation(int ll, char *filename) {
221 if (ll == OPENPTS_LOG_FILE) {
222 expandLogFilePath(filename);
226 void setSyslogCommandName(char *name) {
231 * return loglocation in String (char*)
233 char *getLogLocationString() {
234 if (logLocation == OPENPTS_LOG_SYSLOG) {
236 } else if (logLocation == OPENPTS_LOG_CONSOLE) {
237 return "console(stderr)";
238 } else if (logLocation == OPENPTS_LOG_NULL) {
240 } else if (logLocation == OPENPTS_LOG_FILE) {
243 ERROR("logLocation %d\n", logLocation);
251 static void createLogEntry(
258 const char *priorities[1 + LOG_DEBUG] = {
268 /* number of chars written (not including '\0') */
269 int charsWritten = 0;
271 if (priority > LOG_DEBUG) {
272 charsWritten = snprintf(buf, bufLen, "[UNKNOWN (%d)] ", priority);
274 charsWritten = snprintf(buf, bufLen, "%s", priorities[priority]);
277 if ( charsWritten >= bufLen ) {
278 /* string was truncated */
282 charsWritten += vsnprintf(&buf[charsWritten], bufLen - charsWritten, format, list);
284 if ( charsWritten >= bufLen ) {
285 /* string was truncated */
289 if ( (charsWritten + 1) < bufLen ) {
290 buf[charsWritten] = '\n';
291 buf[++charsWritten] = '\0';
298 void writeLog(int priority, const char *format, ...) {
300 char *format2 = NULL;
302 // char buf[SYSLOG_BUF_SIZE];
303 va_start(list, format);
306 if (logLocation == OPENPTS_LOG_UNDEFINED) {
307 determineLogLocationByEnv();
308 // fprintf(stderr, "logLocation == OPENPTS_LOG_UNDEFINED\n");
312 if (logLocation == OPENPTS_LOG_NULL) {
318 len = strlen(format);
319 if (format[len - 1] == '\n') {
320 // format2 = malloc(len + 1); // +1 space
321 format2 = (char *) malloc(len);
322 if (format2 != NULL) {
323 memcpy(format2, format, len - 1);
324 format2[len - 1] = 0;
329 switch (logLocation) {
330 case OPENPTS_LOG_SYSLOG:
332 char buf[SYSLOG_BUF_SIZE];
334 /* ptsc -m (IF-M) -> syslog */
335 if (command_name == NULL) {
336 openlog("ptsc", LOG_NDELAY|LOG_PID, LOG_LOCAL5);
338 openlog(command_name, LOG_NDELAY|LOG_PID, LOG_LOCAL5);
341 /* vsyslog is not supported by some unix */
342 vsnprintf(buf, SYSLOG_BUF_SIZE, format, list);
344 /* priority is controlled by syslog conf */
345 /* for DEBUG, use OPENPTS_LOG_FILE */
346 syslog(priority, "%s", buf);
351 case OPENPTS_LOG_FILE:
353 if (openLogFile() == -1) {
354 if ( !alreadyWarnedAboutLogFile ) {
355 fprintf(stderr, NLS(MS_OPENPTS, OPENPTS_CANNOT_OPEN_LOGFILE,
356 "Unable to open logfile '%s'\n"), logFileName);
357 alreadyWarnedAboutLogFile = 1;
359 /* fall through to next case */
362 createLogEntry(priority, logEntry, 1024, format, list);
367 case OPENPTS_LOG_CONSOLE:
370 createLogEntry(priority, logEntry, 1024, format, list);
371 fprintf(stderr, "%s", logEntry);
379 va_start(list, format);
381 // if (getenv("PTSCD_DAEMON") != NULL) {
382 if (getenv("OPENPTS_SYSLOG") != NULL) {
383 /* daemon -> syslog */
384 openlog("ptsc", LOG_NDELAY|LOG_PID, LOG_LOCAL5);
386 // 2011-04-11 SM shows verbose messages
387 if (priority == LOG_DEBUG) priority = LOG_INFO;
389 // vsyslog is not supported by some unix
390 vsnprintf(buf, SYSLOG_BUF_SIZE, format, list);
391 syslog(priority, "%s", buf);
395 /* foregrond -> stdout */
396 if (priority == LOG_INFO) {
397 fprintf(stdout, "INFO:");
398 } else if (priority == LOG_ERR) {
399 fprintf(stdout, "ERROR:");
401 fprintf(stdout, "%d:", priority);
403 vfprintf(stdout, format, list);
404 fprintf(stdout, "\n");
410 if (format2 != NULL) free(format2);
415 static int openLogFile(void) {
416 if (logFileFd != -1) {
420 //logFileFd = open(logFileName, O_RDWR|O_CREAT|O_TRUNC, DEFAULT_LOG_FILE_PERM);
421 logFileFd = open(logFileName, O_WRONLY|O_CREAT|O_APPEND, DEFAULT_LOG_FILE_PERM);
425 static void addToLog(char* log_entry) {
426 /* Warnings are treated as errors so need this ugly code to build */
427 ssize_t n = write(logFileFd, log_entry, strlen(log_entry));