1 /*
2 * Unreal Internet Relay Chat Daemon, src/s_debug.c
3 * Copyright (C) 1990 Jarkko Oikarinen and
4 * University of Oulu, Computing Center
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 1, or (at your option)
9 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21
22 #ifndef CLEAN_COMPILE
23 static char sccsid[] =
24 "@(#)s_debug.c 2.30 1/3/94 (C) 1988 University of Oulu, \
25 Computing Center and Jarkko Oikarinen";
26 #endif
27
28 #include "struct.h"
29 #include <string.h>
30 #include "proto.h"
31 /*
32 * Option string. Must be before #ifdef DEBUGMODE.
33 */
34 MODVAR char serveropts[] = {
35 #ifdef CHROOTDIR
36 'c',
37 #endif
38 #ifdef CMDLINE_CONFIG
39 'C',
40 #endif
41 #ifdef DEBUGMODE
42 'D',
43 #endif
44 #ifndef NO_FDLIST
45 'F',
46 #endif
47 /*
48 * Marks that the ircd is ``compiled as'' a hub.
49 * Now always defined as it's impossible to build unrealircd
50 * without hub support AFAIK. (#0003891) --binki
51 */
52 'h',
53 #ifdef SHOW_INVISIBLE_LUSERS
54 'i',
55 #endif
56 /* NOSPOOF is always compiled in now. --nenolod */
57 'n',
58 #ifdef VALLOC
59 'V',
60 #endif
61 #ifdef _WIN32
62 'W',
63 #endif
64 #ifdef USE_SYSLOG
65 'Y',
66 #endif
67 #ifdef INET6
68 '6',
69 #endif
70 #ifdef STRIPBADWORDS
71 'X',
72 #endif
73 #ifdef USE_SSL
74 'e',
75 #endif
76 #ifndef NO_OPEROVERRIDE
77 'O',
78 #endif
79 #ifndef OPEROVERRIDE_VERIFY
80 'o',
81 #endif
82 #ifdef ZIP_LINKS
83 'Z',
84 #endif
85 #ifdef EXTCMODE
86 'E',
87 #endif
88 '\0', /* Don't change those 3 nuls. -- Syzop */
89 '\0',
90 '\0'
91 };
92
93 char *extraflags = NULL;
94
95 #include "numeric.h"
96 #include "common.h"
97 #include "sys.h"
98 #include "whowas.h"
99 #include "hash.h"
100 #ifndef _WIN32
101 #include <sys/file.h>
102 #endif
103 #ifdef HPUX
104 #include <fcntl.h>
105 #endif
106 #if !defined(ULTRIX) && !defined(SGI) && \
107 !defined(__convex__) && !defined(_WIN32)
108 # include <sys/param.h>
109 #endif
110 #ifdef HPUX
111 # include <sys/syscall.h>
112 # define getrusage(a,b) syscall(SYS_GETRUSAGE, a, b)
113 #endif
114 #ifdef GETRUSAGE_2
115 # ifdef _SOLARIS
116 # include <sys/time.h>
117 # ifdef RUSAGEH
118 # include <sys/rusage.h>
119 # endif
120 # endif
121 # include <sys/resource.h>
122 #else
123 # ifdef TIMES_2
124 # include <sys/times.h>
125 # endif
126 #endif
127 #ifdef PCS
128 # include <time.h>
129 #endif
130 #ifdef HPUX
131 #include <unistd.h>
132 #endif
133 #include "h.h"
134
135 #ifndef ssize_t
136 #define ssize_t unsigned int
137 #endif
138
flag_add(char ch)139 void flag_add(char ch)
140 {
141 char *newextra;
142 if (extraflags)
143 {
144 char tmp[2] = { ch, 0 };
145 newextra = (char *)MyMalloc(strlen(extraflags) + 2);
146 strcpy(newextra, extraflags);
147 strcat(newextra, tmp);
148 MyFree(extraflags);
149 extraflags = newextra;
150 }
151 else
152 {
153 extraflags = malloc(2);
154 extraflags[0] = ch;
155 extraflags[1] = 0;
156 }
157 }
158
flag_del(char ch)159 void flag_del(char ch)
160 {
161 int newsz;
162 char *p, *op;
163 char *newflags;
164 newsz = 0;
165 p = extraflags;
166 for (newsz = 0, p = extraflags; *p; p++)
167 if (*p != ch)
168 newsz++;
169 newflags = MyMalloc(newsz + 1);
170 for (p = newflags, op = extraflags; (*op) && (newsz); newsz--, op++)
171 if (*op != ch)
172 *p++ = *op;
173 *p = '\0';
174 MyFree(extraflags);
175 extraflags = newflags;
176 }
177
178
179
180 #ifdef DEBUGMODE
181 #ifndef _WIN32
182 #define SET_ERRNO(x) errno = x
183 #else
184 #define SET_ERRNO(x) WSASetLastError(x)
185 #endif /* _WIN32 */
186
187 static char debugbuf[4096];
188
189 #ifndef USE_VARARGS
190 /*VARARGS2*/
debug(level,form,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10)191 void debug(level, form, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
192 int level;
193 char *form, *p1, *p2, *p3, *p4, *p5, *p6, *p7, *p8, *p9, *p10;
194 {
195 #else
196 void debug(int level, char *form, ...)
197 #endif
198 {
199 int err = ERRNO;
200
201 va_list vl;
202 va_start(vl, form);
203
204 if ((debuglevel >= 0) && (level <= debuglevel))
205 {
206 #ifndef USE_VARARGS
207 (void)ircsprintf(debugbuf, form, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
208 #else
209 (void)ircvsprintf(debugbuf, form, vl);
210 #if 0
211 # ifdef _WIN32
212 strcat(debugbuf,"\r\n");
213 # endif
214 #endif
215 #endif
216
217 #if 0
218 if (local[2])
219 {
220 local[2]->sendM++;
221 local[2]->sendB += strlen(debugbuf);
222 }
223 #endif
224 #ifndef _WIN32
225 (void)fprintf(stderr, "%s", debugbuf);
226 (void)fputc('\n', stderr);
227 #else
228 //# ifndef _WIN32GUI
229 // Cio_Puts(hCio, debugbuf, strlen(debugbuf));
230 //# else
231 strcat(debugbuf, "\r\n");
232 OutputDebugString(debugbuf);
233 //# endif
234 #endif
235 }
236 va_end(vl);
237 SET_ERRNO(err);
238 }
239
240 /*
241 * This is part of the STATS replies. There is no offical numeric for this
242 * since this isnt an official command, in much the same way as HASH isnt.
243 * It is also possible that some systems wont support this call or have
244 * different field names for "struct rusage".
245 * -avalon
246 */
247 void send_usage(aClient *cptr, char *nick)
248 {
249
250 #ifdef GETRUSAGE_2
251 struct rusage rus;
252 time_t secs, rup;
253 #ifdef hz
254 # define hzz hz
255 #else
256 # ifdef HZ
257 # define hzz HZ
258 # else
259 int hzz = 1;
260 # ifdef HPUX
261 hzz = (int)sysconf(_SC_CLK_TCK);
262 # endif
263 # endif
264 #endif
265
266 if (getrusage(RUSAGE_SELF, &rus) == -1)
267 {
268 sendto_one(cptr, ":%s NOTICE %s :Getruseage error: %s.",
269 me.name, nick, strerror(errno));
270 return;
271 }
272 secs = rus.ru_utime.tv_sec + rus.ru_stime.tv_sec;
273 rup = TStime() - me.since;
274 if (secs == 0)
275 secs = 1;
276
277 sendto_one(cptr,
278 ":%s %d %s :CPU Secs %ld:%ld User %ld:%ld System %ld:%ld",
279 me.name, RPL_STATSDEBUG, nick, secs / 60, secs % 60,
280 rus.ru_utime.tv_sec / 60, rus.ru_utime.tv_sec % 60,
281 rus.ru_stime.tv_sec / 60, rus.ru_stime.tv_sec % 60);
282 sendto_one(cptr, ":%s %d %s :RSS %ld ShMem %ld Data %ld Stack %ld",
283 me.name, RPL_STATSDEBUG, nick, rus.ru_maxrss,
284 rus.ru_ixrss / (rup * hzz), rus.ru_idrss / (rup * hzz),
285 rus.ru_isrss / (rup * hzz));
286 sendto_one(cptr, ":%s %d %s :Swaps %ld Reclaims %ld Faults %ld",
287 me.name, RPL_STATSDEBUG, nick, rus.ru_nswap,
288 rus.ru_minflt, rus.ru_majflt);
289 sendto_one(cptr, ":%s %d %s :Block in %ld out %ld",
290 me.name, RPL_STATSDEBUG, nick, rus.ru_inblock, rus.ru_oublock);
291 sendto_one(cptr, ":%s %d %s :Msg Rcv %ld Send %ld",
292 me.name, RPL_STATSDEBUG, nick, rus.ru_msgrcv, rus.ru_msgsnd);
293 sendto_one(cptr, ":%s %d %s :Signals %ld Context Vol. %ld Invol %ld",
294 me.name, RPL_STATSDEBUG, nick, rus.ru_nsignals,
295 rus.ru_nvcsw, rus.ru_nivcsw);
296 #else
297 # ifdef TIMES_2
298 struct tms tmsbuf;
299 time_t secs, mins;
300 int hzz = 1, ticpermin;
301 int umin, smin, usec, ssec;
302
303 # ifdef HPUX
304 hzz = sysconf(_SC_CLK_TCK);
305 # endif
306 ticpermin = hzz * 60;
307
308 umin = tmsbuf.tms_utime / ticpermin;
309 usec = (tmsbuf.tms_utime % ticpermin) / (float)hzz;
310 smin = tmsbuf.tms_stime / ticpermin;
311 ssec = (tmsbuf.tms_stime % ticpermin) / (float)hzz;
312 secs = usec + ssec;
313 mins = (secs / 60) + umin + smin;
314 secs %= hzz;
315
316 if (times(&tmsbuf) == -1)
317 {
318 sendto_one(cptr, ":%s %d %s :times(2) error: %s.",
319 me.name, RPL_STATSDEBUG, nick, STRERROR(ERRNO));
320 return;
321 }
322 secs = tmsbuf.tms_utime + tmsbuf.tms_stime;
323
324 sendto_one(cptr,
325 ":%s %d %s :CPU Secs %d:%d User %d:%d System %d:%d",
326 me.name, RPL_STATSDEBUG, nick, mins, secs, umin, usec, smin, ssec);
327 # endif
328 #endif
329 sendto_one(cptr, ":%s %d %s :Reads %d Writes %d",
330 me.name, RPL_STATSDEBUG, nick, readcalls, writecalls);
331 sendto_one(cptr, ":%s %d %s :DBUF alloc %d blocks %d",
332 me.name, RPL_STATSDEBUG, nick, dbufalloc, dbufblocks);
333 sendto_one(cptr,
334 ":%s %d %s :Writes: <0 %d 0 %d <16 %d <32 %d <64 %d",
335 me.name, RPL_STATSDEBUG, nick,
336 writeb[0], writeb[1], writeb[2], writeb[3], writeb[4]);
337 sendto_one(cptr,
338 ":%s %d %s :<128 %d <256 %d <512 %d <1024 %d >1024 %d",
339 me.name, RPL_STATSDEBUG, nick,
340 writeb[5], writeb[6], writeb[7], writeb[8], writeb[9]);
341 return;
342 }
343
344 int checkprotoflags(aClient *sptr, int flags, char *file, int line)
345 {
346 if (!MyConnect(sptr))
347 ircd_log(LOG_ERROR, "[Debug] [BUG] ERROR: %s:%d: IsToken(<%s>,%d) on remote client",
348 file, line, sptr->name, flags);
349 return (sptr->proto & flags) ? 1 : 0;
350 }
351 #endif
352