]> git.ipfire.org Git - thirdparty/squid.git/blame - src/tools.cc
Initial revision
[thirdparty/squid.git] / src / tools.cc
CommitLineData
090089c4 1static char rcsid[] = "$Id: tools.cc,v 1.1 1996/02/22 06:23:56 wessels Exp $";
2/*
3 **********************************************************************
4 * Copyright (c) 1994, 1995. All rights reserved.
5 *
6 * The Harvest software was developed by the Internet Research Task
7 * Force Research Group on Resource Discovery (IRTF-RD):
8 *
9 * Mic Bowman of Transarc Corporation.
10 * Peter Danzig of the University of Southern California.
11 * Darren R. Hardy of the University of Colorado at Boulder.
12 * Udi Manber of the University of Arizona.
13 * Michael F. Schwartz of the University of Colorado at Boulder.
14 * Duane Wessels of the University of Colorado at Boulder.
15 *
16 * This copyright notice applies to software in the Harvest
17 * ``src/'' directory only. Users should consult the individual
18 * copyright notices in the ``components/'' subdirectories for
19 * copyright information about other software bundled with the
20 * Harvest source code distribution.
21 *
22 * TERMS OF USE
23 *
24 * The Harvest software may be used and re-distributed without
25 * charge, provided that the software origin and research team are
26 * cited in any use of the system. Most commonly this is
27 * accomplished by including a link to the Harvest Home Page
28 * (http://harvest.cs.colorado.edu/) from the query page of any
29 * Broker you deploy, as well as in the query result pages. These
30 * links are generated automatically by the standard Broker
31 * software distribution.
32 *
33 * The Harvest software is provided ``as is'', without express or
34 * implied warranty, and with no support nor obligation to assist
35 * in its use, correction, modification or enhancement. We assume
36 * no liability with respect to the infringement of copyrights,
37 * trade secrets, or any patents, and are not responsible for
38 * consequential damages. Proper use of the Harvest software is
39 * entirely the responsibility of the user.
40 *
41 * DERIVATIVE WORKS
42 *
43 * Users may make derivative works from the Harvest software, subject
44 * to the following constraints:
45 *
46 * - You must include the above copyright notice and these
47 * accompanying paragraphs in all forms of derivative works,
48 * and any documentation and other materials related to such
49 * distribution and use acknowledge that the software was
50 * developed at the above institutions.
51 *
52 * - You must notify IRTF-RD regarding your distribution of
53 * the derivative work.
54 *
55 * - You must clearly notify users that your are distributing
56 * a modified version and not the original Harvest software.
57 *
58 * - Any derivative product is also subject to these copyright
59 * and use restrictions.
60 *
61 * Note that the Harvest software is NOT in the public domain. We
62 * retain copyright, as specified above.
63 *
64 * HISTORY OF FREE SOFTWARE STATUS
65 *
66 * Originally we required sites to license the software in cases
67 * where they were going to build commercial products/services
68 * around Harvest. In June 1995 we changed this policy. We now
69 * allow people to use the core Harvest software (the code found in
70 * the Harvest ``src/'' directory) for free. We made this change
71 * in the interest of encouraging the widest possible deployment of
72 * the technology. The Harvest software is really a reference
73 * implementation of a set of protocols and formats, some of which
74 * we intend to standardize. We encourage commercial
75 * re-implementations of code complying to this set of standards.
76 *
77 *
78 */
79#include "config.h"
80#include <stdio.h>
81#include <stdlib.h>
82#include <string.h>
83#include <signal.h>
84#include <unistd.h> /* for sysconf() stuff */
85#include <malloc.h>
86#include <syslog.h>
87#include <sys/time.h>
88#include <sys/resource.h>
89#include <sys/wait.h>
90#include <sys/param.h> /* has NOFILE */
91#include <sys/types.h>
92
93#include "debug.h"
94#include "cache_cf.h"
95#include "autoconf.h"
96#include "ftp.h" /* sig_child() needs to know FTP threads */
97
98
99void death(), deathb(), neighbors_rotate_log(), stat_rotate_log();
100void mail_warranty(), print_warranty(), _db_rotate_log();
101int do_mallinfo = 0; /* don't do mallinfo() unless this gets set */
102int PrintRusage _PARAMS((void (*)(), FILE *));
103
104extern ftpget_thread *FtpgetThread;
105extern int catch_signals; /* main.c */
106extern int storeWriteCleanLog _PARAMS((void));
107
108/*-------------------------------------------------------------------------
109--
110-- death, deathb
111--
112-- Function: These functions catch and report fatal system violations.
113--
114-- Inputs: None.
115--
116-- Output: None.
117--
118-- Comments: None.
119--
120--------------------------------------------------------------------------*/
121void death()
122{
123 fprintf(stderr, "FATAL: Received Segment Violation...dying.\n");
124 signal(SIGSEGV, SIG_DFL);
125 signal(SIGBUS, SIG_DFL);
126 storeWriteCleanLog();
127 PrintRusage(NULL, stderr);
128 print_warranty();
129 abort();
130}
131
132
133void deathb()
134{
135 fprintf(stderr, "FATAL: Received bus error...dying.\n");
136 signal(SIGSEGV, SIG_DFL);
137 signal(SIGBUS, SIG_DFL);
138 signal(SIGBUS, SIG_DFL);
139 storeWriteCleanLog();
140 PrintRusage(NULL, stderr);
141 print_warranty();
142 abort();
143}
144
145#define DEAD_MSG "\
146The Harvest Cache (version %s) died.\n\
147\n\
148You've encountered a fatal error in the Harvest Cache version %s.\n\
149If a core file was created (possibly in the swap directory),\n\
150please execute 'gdb cached core' or 'dbx cached core', then type 'where',\n\
151and report the trace back to harvest-dvl@cs.colorado.edu.\n\
152\n\
153Thanks!\n"
154
155static char *dead_msg()
156{
157 static char msg[1024];
158 sprintf(msg, DEAD_MSG, HARVEST_VERSION, HARVEST_VERSION);
159 return msg;
160}
161
162void mail_warranty()
163{
164 FILE *fp;
165 static char filename[256];
166 static char command[256];
167
168 sprintf(filename, "/tmp/mailin%d", (int) getpid());
169 fp = fopen(filename, "w");
170 if (fp != NULL) {
171 fprintf(fp, "From: cached\n");
172 fprintf(fp, "To: %s\n", getAdminEmail());
173 fprintf(fp, "Subject: %s\n", dead_msg());
174 fclose(fp);
175
176 sprintf(command, "mail %s < %s", getAdminEmail(), filename);
177
178 system(command);
179 unlink(filename);
180 }
181}
182
183void print_warranty()
184{
185 if (getAdminEmail())
186 mail_warranty();
187 else
188 puts(dead_msg());
189}
190
191void rotate_logs(sig)
192 int sig;
193{
194 debug(1, "rotate_logs: SIGHUP received.\n");
195
196 storeWriteCleanLog();
197 neighbors_rotate_log();
198 stat_rotate_log();
199 _db_rotate_log();
200#if defined(_HARVEST_SYSV_SIGNALS_)
201 signal(sig, rotate_logs);
202#endif
203}
204
205void shut_down(sig)
206 int sig;
207{
208 debug(1, "Shutting down...\n");
209 storeWriteCleanLog();
210 PrintRusage(NULL, stderr);
211 debug(0, "Harvest Cache (Version %s): Exiting due to signal %d.\n",
212 HARVEST_VERSION, sig);
213 exit(1);
214}
215
216void fatal_common(message)
217 char *message;
218{
219 if (syslog_enable)
220 syslog(LOG_ALERT, message);
221 fprintf(stderr, "FATAL: %s\n", message);
222 fprintf(stderr, "Harvest Cache (Version %s): Terminated abnormally.\n",
223 HARVEST_VERSION);
224 fflush(stderr);
225 PrintRusage(NULL, stderr);
226 if (debug_log != stderr) {
227 debug(0, "FATAL: %s\n", message);
228 debug(0, "Harvest Cache (Version %s): Terminated abnormally.\n",
229 HARVEST_VERSION);
230 }
231}
232
233/* fatal */
234void fatal(message)
235 char *message;
236{
237 fatal_common(message);
238 exit(1);
239}
240
241/* fatal with dumping core */
242void fatal_dump(message)
243 char *message;
244{
245 if (message)
246 fatal_common(message);
247 if (catch_signals)
248 storeWriteCleanLog();
249 abort();
250}
251
252
253void dumpMallocStats(f)
254 FILE *f;
255{
256#if USE_MALLINFO
257 struct mallinfo mp;
258
259 if (!do_mallinfo)
260 return;
261
262 mp = mallinfo();
263
264 fprintf(f, "Malloc Instrumentation via mallinfo(): \n");
265 fprintf(f, " total space in arena %d\n", mp.arena);
266 fprintf(f, " number of ordinary blocks %d\n", mp.ordblks);
267 fprintf(f, " number of small blocks %d\n", mp.smblks);
268 fprintf(f, " number of holding blocks %d\n", mp.hblks);
269 fprintf(f, " space in holding block headers %d\n", mp.hblkhd);
270 fprintf(f, " space in small blocks in use %d\n", mp.usmblks);
271 fprintf(f, " space in free blocks %d\n", mp.fsmblks);
272 fprintf(f, " space in ordinary blocks in use %d\n", mp.uordblks);
273 fprintf(f, " space in free ordinary blocks %d\n", mp.fordblks);
274 fprintf(f, " cost of enabling keep option %d\n", mp.keepcost);
275#if LNG_MALLINFO
276 fprintf(f, " max size of small blocks %d\n", mp.mxfast);
277 fprintf(f, " number of small blocks in a holding block %d\n",
278 mp.nlblks);
279 fprintf(f, " small block rounding factor %d\n", mp.grain);
280 fprintf(f, " space (including overhead) allocated in ord. blks %d\n",
281 mp.uordbytes);
282 fprintf(f, " number of ordinary blocks allocated %d\n",
283 mp.allocated);
284 fprintf(f, " bytes used in maintaining the free tree %d\n",
285 mp.treeoverhead);
286#endif /* LNG_MALLINFO */
287
288#if PRINT_MMAP
289 mallocmap();
290#endif /* PRINT_MMAP */
291#endif /* USE_MALLINFO */
292}
293
294int PrintRusage(f, lf)
295 void (*f) ();
296 FILE *lf;
297{
298#if defined(HAVE_RUSAGE) && defined(RUSAGE_SELF)
299 struct rusage rusage;
300
301 getrusage(RUSAGE_SELF, &rusage);
302 fprintf(lf, "CPU Usage: user %d sys %d\nMemory Usage: rss %d KB\n",
303 rusage.ru_utime.tv_sec, rusage.ru_stime.tv_sec,
304 rusage.ru_maxrss * getpagesize() / 1000);
305 fprintf(lf, "Page faults with physical i/o: %d\n",
306 rusage.ru_majflt);
307
308#endif
309 dumpMallocStats(lf);
310 if (f)
311 f(0);
312 return 0;
313}
314
315int getHeapSize()
316{
317#if USE_MALLINFO
318 struct mallinfo mp;
319
320 mp = mallinfo();
321
322 return (mp.arena);
323#else
324 return (0);
325#endif
326}
327
328void sig_child(sig)
329 int sig;
330{
331 int status;
332 int pid;
333 ftpget_thread *t = NULL;
334
335 if ((pid = waitpid(0, &status, WNOHANG)) > 0) {
336 debug(3, "sig_child: Ate pid %d\n", pid);
337 for (t = FtpgetThread; t; t = t->next) {
338 debug(5, "sig_child: checking pid=%d state=%d\n",
339 t->pid, t->state);
340 if (t->pid == pid && t->state == FTPGET_THREAD_RUNNING) {
341 debug(5, "sig_child: GOT IT!\n");
342 t->state = FTPGET_THREAD_WAITED;
343 t->status = status;
344 t->wait_retval = pid;
345 break;
346 }
347 }
348 }
349#if defined(_HARVEST_SYSV_SIGNALS_)
350 signal(sig, sig_child);
351#endif
352}
353
354#define MAX_ZOMBIES_TO_KILL 20
355void kill_zombie()
356{
357 int status;
358 int i = 0;
359 int pid;
360
361 while ((pid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) {
362 debug(3, "kill_zombie: Ate pid %d\n", pid);
363 if (++i > MAX_ZOMBIES_TO_KILL)
364 break;
365 }
366}
367
368/*
369 * getMaxFD - returns the file descriptor table size
370 */
371int getMaxFD()
372{
373 static int i = -1;
374
375 if (i == -1) {
376#if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX)
377 i = sysconf(_SC_OPEN_MAX); /* prefered method */
378#elif defined(HAVE_GETDTABLESIZE)
379 i = getdtablesize(); /* the BSD way */
380#elif defined(OPEN_MAX)
381 i = OPEN_MAX;
382#elif defined(NOFILE)
383 i = NOFILE;
384#elif defined(_NFILE)
385 i = _NFILE;
386#else
387 i = 64; /* 64 is a safe default */
388#endif
389 debug(10, "getMaxFD set MaxFD at %d\n", i);
390 }
391 return (i);
392}