1 /*
2  *  Window Maker miscelaneous function library
3  *
4  *  Copyright (c) 1997-2003 Alfredo K. Kojima
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
19  *  MA 02110-1301, USA.
20  */
21 
22 #include "wconfig.h"
23 
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 
30 #include <WUtil.h>
31 #include <WINGsP.h>
32 
33 #ifdef HAVE_SYSLOG_H
34 #include <syslog.h>
35 
36 static Bool syslog_initialized = False;
37 
38 
syslog_open(const char * prog_name)39 static void syslog_open(const char *prog_name)
40 {
41 	int options;
42 
43 	if (!prog_name)
44 		prog_name = "WINGs";
45 
46 	options = LOG_PID;
47 	openlog(prog_name, options, LOG_DAEMON);
48 	syslog_initialized = True;
49 }
50 
syslog_message(int prio,const char * prog_name,const char * msg)51 static void syslog_message(int prio, const char *prog_name, const char *msg)
52 {
53 	if (!syslog_initialized)
54 		syslog_open(prog_name);
55 
56 	//jump over the program name cause syslog is already displaying it
57 	syslog(prio, "%s", msg + strlen(prog_name));
58 }
59 
w_syslog_close(void)60 void w_syslog_close(void)
61 {
62 	if (syslog_initialized) {
63 		closelog();
64 		syslog_initialized = False;
65 	}
66 }
67 #endif
68 
__wmessage(const char * func,const char * file,int line,int type,const char * msg,...)69 void __wmessage(const char *func, const char *file, int line, int type, const char *msg, ...)
70 {
71 	va_list args;
72 	char *buf;
73 	static int linemax = 0;
74 	int truncated = 0;
75 #ifdef HAVE_SYSLOG
76 	int syslog_priority = LOG_INFO;
77 #endif
78 
79 	if (linemax == 0) {
80 #ifdef HAVE_SYSCONF
81 		linemax = sysconf(_SC_LINE_MAX);
82 		if (linemax == -1) {
83 			/* I'd like to know of this ever fires */
84 			fprintf(stderr, "%s %d: sysconf(_SC_LINE_MAX) returned error\n",
85 				__FILE__, __LINE__);
86 			linemax = 512;
87 		}
88 #else /* !HAVE_SYSCONF */
89 		fprintf(stderr, "%s %d: Your system does not have sysconf(3); "
90 			"let wmaker-dev@windowmaker.org know.\n", __FILE__, __LINE__);
91 		linemax = 512;
92 #endif /* HAVE_SYSCONF */
93 	}
94 
95 	buf = wmalloc(linemax);
96 
97 	fflush(stdout);
98 
99 	/* message format: <wings_progname>(function(file:line): <type?>: <message>"\n" */
100 	strncat(buf, _WINGS_progname ? _WINGS_progname : "WINGs", linemax - 1);
101 	snprintf(buf + strlen(buf), linemax - strlen(buf), "(%s(%s:%d))", func, file, line);
102 	strncat(buf, ": ", linemax - 1 - strlen(buf));
103 
104 	switch (type) {
105 		case WMESSAGE_TYPE_FATAL:
106 			strncat(buf, _("fatal: "), linemax - 1 - strlen(buf));
107 #ifdef HAVE_SYSLOG
108 			syslog_priority = LOG_CRIT;
109 #endif
110 		break;
111 		case WMESSAGE_TYPE_ERROR:
112 			strncat(buf, _("error: "), linemax - 1 - strlen(buf));
113 #ifdef HAVE_SYSLOG
114 			syslog_priority = LOG_ERR;
115 #endif
116 		break;
117 		case WMESSAGE_TYPE_WARNING:
118 			strncat(buf, _("warning: "), linemax - 1 - strlen(buf));
119 #ifdef HAVE_SYSLOG
120 			syslog_priority = LOG_WARNING;
121 #endif
122 		break;
123 		case WMESSAGE_TYPE_MESSAGE:
124 			/* FALLTHROUGH */
125 		default:	/* should not happen, but doesn't hurt either */
126 		break;
127 	}
128 
129 	va_start(args, msg);
130 	if (vsnprintf(buf + strlen(buf), linemax - strlen(buf), msg, args) >= linemax - strlen(buf))
131 		truncated = 1;
132 
133 	va_end(args);
134 
135 	fputs(buf, stderr);
136 #ifdef HAVE_SYSLOG
137 	syslog_message(syslog_priority, _WINGS_progname ? _WINGS_progname : "WINGs", buf);
138 #endif
139 
140 	if (truncated)
141 		fputs("*** message truncated ***", stderr);
142 
143 	fputs("\n", stderr);
144 
145 	wfree(buf);
146 }
147 
148