Here's looking at you, deadlock.
[privoxy.git] / errlog.c
1 const char errlog_rcs[] = "$Id: errlog.c,v 1.58 2007/10/28 19:04:21 fabiankeil Exp $";
2 /*********************************************************************
3  *
4  * File        :  $Source: /cvsroot/ijbswa/current/errlog.c,v $
5  *
6  * Purpose     :  Log errors to a designated destination in an elegant,
7  *                printf-like fashion.
8  *
9  * Copyright   :  Written by and Copyright (C) 2001-2007 the SourceForge
10  *                Privoxy team. http://www.privoxy.org/
11  *
12  *                Based on the Internet Junkbuster originally written
13  *                by and Copyright (C) 1997 Anonymous Coders and 
14  *                Junkbusters Corporation.  http://www.junkbusters.com
15  *
16  *                This program is free software; you can redistribute it 
17  *                and/or modify it under the terms of the GNU General
18  *                Public License as published by the Free Software
19  *                Foundation; either version 2 of the License, or (at
20  *                your option) any later version.
21  *
22  *                This program is distributed in the hope that it will
23  *                be useful, but WITHOUT ANY WARRANTY; without even the
24  *                implied warranty of MERCHANTABILITY or FITNESS FOR A
25  *                PARTICULAR PURPOSE.  See the GNU General Public
26  *                License for more details.
27  *
28  *                The GNU General Public License should be included with
29  *                this file.  If not, you can view it at
30  *                http://www.gnu.org/copyleft/gpl.html
31  *                or write to the Free Software Foundation, Inc., 59
32  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
33  *
34  * Revisions   :
35  *    $Log: errlog.c,v $
36  *    Revision 1.58  2007/10/28 19:04:21  fabiankeil
37  *    Don't mention daemon mode in "Logging disabled" message. Some
38  *    platforms call it differently and it's not really relevant anyway.
39  *
40  *    Revision 1.57  2007/10/27 13:02:26  fabiankeil
41  *    Relocate daemon-mode-related log messages to make sure
42  *    they aren't shown again in case of configuration reloads.
43  *
44  *    Revision 1.56  2007/10/14 14:26:56  fabiankeil
45  *    Remove the old log_error() version.
46  *
47  *    Revision 1.55  2007/10/14 14:12:41  fabiankeil
48  *    When in daemon mode, close stderr after the configuration file has been
49  *    parsed the first time. If logfile isn't set, stop logging. Fixes BR#897436.
50  *
51  *    Revision 1.54  2007/09/22 16:15:34  fabiankeil
52  *    - Let it compile with pcc.
53  *    - Move our includes below system includes to prevent macro conflicts.
54  *
55  *    Revision 1.53  2007/08/05 13:53:14  fabiankeil
56  *    #1763173 from Stefan Huehner: declare some more functions
57  *    static and use void instead of empty parameter lists.
58  *
59  *    Revision 1.52  2007/07/14 07:28:47  fabiankeil
60  *    Add translation function for JB_ERR_FOO codes.
61  *
62  *    Revision 1.51  2007/05/11 11:51:34  fabiankeil
63  *    Fix a type mismatch warning.
64  *
65  *    Revision 1.50  2007/04/11 10:55:44  fabiankeil
66  *    Enforce some assertions that could be triggered
67  *    on mingw32 and other systems where we use threads
68  *    but no locks.
69  *
70  *    Revision 1.49  2007/04/08 16:44:15  fabiankeil
71  *    We need <sys/time.h> for gettimeofday(), not <time.h>.
72  *
73  *    Revision 1.48  2007/03/31 13:33:28  fabiankeil
74  *    Add alternative log_error() with timestamps
75  *    that contain milliseconds and without using
76  *    strcpy(), strcat() or sprintf().
77  *
78  *    Revision 1.47  2006/11/28 15:25:15  fabiankeil
79  *    Only unlink the pidfile if it's actually used.
80  *
81  *    Revision 1.46  2006/11/13 19:05:51  fabiankeil
82  *    Make pthread mutex locking more generic. Instead of
83  *    checking for OSX and OpenBSD, check for FEATURE_PTHREAD
84  *    and use mutex locking unless there is an _r function
85  *    available. Better safe than sorry.
86  *
87  *    Fixes "./configure --disable-pthread" and should result
88  *    in less threading-related problems on pthread-using platforms,
89  *    but it still doesn't fix BR#1122404.
90  *
91  *    Revision 1.45  2006/08/21 11:15:54  david__schmidt
92  *    MS Visual C++ build updates
93  *
94  *    Revision 1.44  2006/08/18 16:03:16  david__schmidt
95  *    Tweak for OS/2 build happiness.
96  *
97  *    Revision 1.43  2006/08/03 02:46:41  david__schmidt
98  *    Incorporate Fabian Keil's patch work:
99  *    http://www.fabiankeil.de/sourcecode/privoxy/
100  *
101  *    Revision 1.42  2006/07/18 14:48:46  david__schmidt
102  *    Reorganizing the repository: swapping out what was HEAD (the old 3.1 branch)
103  *    with what was really the latest development (the v_3_0_branch branch)
104  *
105  *    Revision 1.40.2.4  2005/04/03 20:10:50  david__schmidt
106  *    Thanks to Jindrich Makovicka for a race condition fix for the log
107  *    file.  The race condition remains for non-pthread implementations.
108  *    Reference patch #1175720.
109  *
110  *    Revision 1.40.2.3  2003/03/07 03:41:04  david__schmidt
111  *    Wrapping all *_r functions (the non-_r versions of them) with mutex 
112  *    semaphores for OSX.  Hopefully this will take care of all of those pesky
113  *    crash reports.
114  *
115  *    Revision 1.40.2.2  2002/09/28 00:30:57  david__schmidt
116  *    Update error logging to give sane values for thread IDs on Mach kernels.
117  *    It's still a hack, but at least it looks farily normal.  We print the
118  *    absolute value of the first 4 bytes of the pthread_t modded with 1000.
119  *
120  *    Revision 1.40.2.1  2002/09/25 12:47:42  oes
121  *    Make log_error safe against NULL string arguments
122  *
123  *    Revision 1.40  2002/05/22 01:27:27  david__schmidt
124  *
125  *    Add os2_socket_strerr mirroring w32_socket_strerr.
126  *
127  *    Revision 1.39  2002/04/03 17:15:27  gliptak
128  *    zero padding thread ids in log
129  *
130  *    Revision 1.38  2002/03/31 17:18:59  jongfoster
131  *    Win32 only: Enabling STRICT to fix a VC++ compile warning.
132  *
133  *    Revision 1.37  2002/03/27 14:32:43  david__schmidt
134  *    More compiler warning message maintenance
135  *
136  *    Revision 1.36  2002/03/26 22:29:54  swa
137  *    we have a new homepage!
138  *
139  *    Revision 1.35  2002/03/24 15:23:33  jongfoster
140  *    Name changes
141  *
142  *    Revision 1.34  2002/03/24 13:25:43  swa
143  *    name change related issues
144  *
145  *    Revision 1.33  2002/03/13 00:27:04  jongfoster
146  *    Killing warnings
147  *
148  *    Revision 1.32  2002/03/07 03:46:17  oes
149  *    Fixed compiler warnings
150  *
151  *    Revision 1.31  2002/03/06 23:02:57  jongfoster
152  *    Removing tabs
153  *
154  *    Revision 1.30  2002/03/05 22:43:45  david__schmidt
155  *    - Better error reporting on OS/2
156  *    - Fix double-slash comment (oops)
157  *
158  *    Revision 1.29  2002/03/04 23:45:13  jongfoster
159  *    Printing thread ID if using Win32 native threads
160  *
161  *    Revision 1.28  2002/03/04 17:59:59  oes
162  *    Deleted deletePidFile(), cosmetics
163  *
164  *    Revision 1.27  2002/03/04 02:08:01  david__schmidt
165  *    Enable web editing of actions file on OS/2 (it had been broken all this time!)
166  *
167  *    Revision 1.26  2002/01/09 19:05:45  steudten
168  *    Fix big memory leak.
169  *
170  *    Revision 1.25  2002/01/09 14:32:08  oes
171  *    Added support for gmtime_r and localtime_r.
172  *
173  *    Revision 1.24  2001/12/30 14:07:32  steudten
174  *    - Add signal handling (unix)
175  *    - Add SIGHUP handler (unix)
176  *    - Add creation of pidfile (unix)
177  *    - Add action 'top' in rc file (RH)
178  *    - Add entry 'SIGNALS' to manpage
179  *    - Add exit message to logfile (unix)
180  *
181  *    Revision 1.23  2001/11/07 00:02:13  steudten
182  *    Add line number in error output for lineparsing for
183  *    actionsfile and configfile.
184  *    Special handling for CLF added.
185  *
186  *    Revision 1.22  2001/11/05 23:43:05  steudten
187  *    Add time+date to log files.
188  *
189  *    Revision 1.21  2001/10/25 03:40:47  david__schmidt
190  *    Change in porting tactics: OS/2's EMX porting layer doesn't allow multiple
191  *    threads to call select() simultaneously.  So, it's time to do a real, live,
192  *    native OS/2 port.  See defines for __EMX__ (the porting layer) vs. __OS2__
193  *    (native). Both versions will work, but using __OS2__ offers multi-threading.
194  *
195  *    Revision 1.20  2001/09/16 23:04:34  jongfoster
196  *    Fixing a warning
197  *
198  *    Revision 1.19  2001/09/13 20:08:06  jongfoster
199  *    Adding support for LOG_LEVEL_CGI
200  *
201  *    Revision 1.18  2001/09/10 11:27:24  oes
202  *    Declaration of w32_socket_strerr now conditional
203  *
204  *    Revision 1.17  2001/09/10 10:17:13  oes
205  *    Removed unused variable; Fixed sprintf format
206  *
207  *    Revision 1.16  2001/07/30 22:08:36  jongfoster
208  *    Tidying up #defines:
209  *    - All feature #defines are now of the form FEATURE_xxx
210  *    - Permanently turned off WIN_GUI_EDIT
211  *    - Permanently turned on WEBDAV and SPLIT_PROXY_ARGS
212  *
213  *    Revision 1.15  2001/07/29 17:41:10  jongfoster
214  *    Now prints thread ID for each message (pthreads only)
215  *
216  *    Revision 1.14  2001/07/19 19:03:48  haroon
217  *    - Added case for LOG_LEVEL_POPUPS
218  *
219  *    Revision 1.13  2001/07/13 13:58:58  oes
220  *     - Added case for LOG_LEVEL_DEANIMATE
221  *     - Removed all #ifdef PCRS
222  *
223  *    Revision 1.12  2001/06/09 10:55:28  jongfoster
224  *    Changing BUFSIZ ==> BUFFER_SIZE
225  *
226  *    Revision 1.11  2001/06/01 18:14:49  jongfoster
227  *    Changing the calls to strerr() to check HAVE_STRERR (which is defined
228  *    in config.h if appropriate) rather than the NO_STRERR macro.
229  *
230  *    Revision 1.10  2001/05/29 11:52:21  oes
231  *    Conditional compilation of w32_socket_error
232  *
233  *    Revision 1.9  2001/05/28 16:15:17  jongfoster
234  *    Improved reporting of errors under Win32.
235  *
236  *    Revision 1.8  2001/05/26 17:25:14  jongfoster
237  *    Added support for CLF (Common Log Format) and fixed LOG_LEVEL_LOG
238  *
239  *    Revision 1.7  2001/05/26 15:21:28  jongfoster
240  *    Activity animation in Win32 GUI now works even if debug==0
241  *
242  *    Revision 1.6  2001/05/25 21:55:08  jongfoster
243  *    Now cleans up properly on FATAL (removes taskbar icon etc)
244  *
245  *    Revision 1.5  2001/05/22 18:46:04  oes
246  *
247  *    - Enabled filtering banners by size rather than URL
248  *      by adding patterns that replace all standard banner
249  *      sizes with the "Junkbuster" gif to the re_filterfile
250  *
251  *    - Enabled filtering WebBugs by providing a pattern
252  *      which kills all 1x1 images
253  *
254  *    - Added support for PCRE_UNGREEDY behaviour to pcrs,
255  *      which is selected by the (nonstandard and therefore
256  *      capital) letter 'U' in the option string.
257  *      It causes the quantifiers to be ungreedy by default.
258  *      Appending a ? turns back to greedy (!).
259  *
260  *    - Added a new interceptor ijb-send-banner, which
261  *      sends back the "Junkbuster" gif. Without imagelist or
262  *      MSIE detection support, or if tinygif = 1, or the
263  *      URL isn't recognized as an imageurl, a lame HTML
264  *      explanation is sent instead.
265  *
266  *    - Added new feature, which permits blocking remote
267  *      script redirects and firing back a local redirect
268  *      to the browser.
269  *      The feature is conditionally compiled, i.e. it
270  *      can be disabled with --disable-fast-redirects,
271  *      plus it must be activated by a "fast-redirects"
272  *      line in the config file, has its own log level
273  *      and of course wants to be displayed by show-proxy-args
274  *      Note: Boy, all the #ifdefs in 1001 locations and
275  *      all the fumbling with configure.in and acconfig.h
276  *      were *way* more work than the feature itself :-(
277  *
278  *    - Because a generic redirect template was needed for
279  *      this, tinygif = 3 now uses the same.
280  *
281  *    - Moved GIFs, and other static HTTP response templates
282  *      to project.h
283  *
284  *    - Some minor fixes
285  *
286  *    - Removed some >400 CRs again (Jon, you really worked
287  *      a lot! ;-)
288  *
289  *    Revision 1.4  2001/05/21 19:32:54  jongfoster
290  *    Added another #ifdef _WIN_CONSOLE
291  *
292  *    Revision 1.3  2001/05/20 01:11:40  jongfoster
293  *    Added support for LOG_LEVEL_FATAL
294  *    Renamed LOG_LEVEL_FRC to LOG_LEVEL_FORCE,
295  *    and LOG_LEVEL_REF to LOG_LEVEL_RE_FILTER
296  *
297  *    Revision 1.2  2001/05/17 22:42:01  oes
298  *     - Cleaned CRLF's from the sources and related files
299  *     - Repaired logging for REF and FRC
300  *
301  *    Revision 1.1.1.1  2001/05/15 13:58:51  oes
302  *    Initial import of version 2.9.3 source tree
303  *
304  *
305  *********************************************************************/
306 \f
307
308 #include <stdlib.h>
309 #include <stdio.h>
310 #include <stdarg.h>
311 #include <string.h>
312
313 #include "config.h"
314 #include "miscutil.h"
315
316 /* For gettimeofday() */
317 #include <sys/time.h>
318
319 #if !defined(_WIN32) && !defined(__OS2__)
320 #include <unistd.h>
321 #endif /* !defined(_WIN32) && !defined(__OS2__) */
322
323 #include <errno.h>
324 #include <assert.h>
325
326 #ifdef _WIN32
327 #ifndef STRICT
328 #define STRICT
329 #endif
330 #include <windows.h>
331 #ifndef _WIN_CONSOLE
332 #include "w32log.h"
333 #endif /* ndef _WIN_CONSOLE */
334 #endif /* def _WIN32 */
335 #ifdef _MSC_VER
336 #define inline __inline
337 #endif /* def _MSC_VER */
338
339 #ifdef __OS2__
340 #include <sys/socket.h> /* For sock_errno */
341 #define INCL_DOS
342 #include <os2.h>
343 #endif
344
345 #include "errlog.h"
346 #include "project.h"
347 #include "jcc.h"
348
349 const char errlog_h_rcs[] = ERRLOG_H_VERSION;
350
351
352 /*
353  * LOG_LEVEL_FATAL cannot be turned off.  (There are
354  * some exceptional situations where we need to get a
355  * message to the user).
356  */
357 #define LOG_LEVEL_MINIMUM  LOG_LEVEL_FATAL
358
359 /* where to log (default: stderr) */
360 static FILE *logfp = NULL;
361
362 /* logging detail level.  */
363 int debug = (LOG_LEVEL_FATAL | LOG_LEVEL_ERROR | LOG_LEVEL_INFO);  
364
365 /* static functions */
366 static void fatal_error(const char * error_message);
367 #ifdef _WIN32
368 static char *w32_socket_strerr(int errcode, char *tmp_buf);
369 #endif
370 #ifdef __OS2__
371 static char *os2_socket_strerr(int errcode, char *tmp_buf);
372 #endif
373
374 #ifdef FEATURE_PTHREAD
375 static inline void lock_logfile(void)
376 {
377    pthread_mutex_lock(&log_mutex);
378 }
379 static inline void unlock_logfile(void)
380 {
381    pthread_mutex_unlock(&log_mutex);
382 }
383 static inline void lock_loginit(void)
384 {
385    pthread_mutex_lock(&log_init_mutex);
386 }
387 static inline void unlock_loginit(void)
388 {
389    pthread_mutex_unlock(&log_init_mutex);
390 }
391 #else /* ! FEATURE_PTHREAD */
392 /*
393  * FIXME we need a cross-platform locking mechanism.
394  * The locking/unlocking functions below should be 
395  * fleshed out for non-pthread implementations.
396  */ 
397 static inline void lock_logfile() {}
398 static inline void unlock_logfile() {}
399 static inline void lock_loginit() {}
400 static inline void unlock_loginit() {}
401 #endif
402
403 /*********************************************************************
404  *
405  * Function    :  fatal_error
406  *
407  * Description :  Displays a fatal error to standard error (or, on 
408  *                a WIN32 GUI, to a dialog box), and exits
409  *                JunkBuster with status code 1.
410  *
411  * Parameters  :
412  *          1  :  error_message = The error message to display.
413  *
414  * Returns     :  Does not return.
415  *
416  *********************************************************************/
417 static void fatal_error(const char * error_message)
418 {
419 #if defined(_WIN32) && !defined(_WIN_CONSOLE)
420    MessageBox(g_hwndLogFrame, error_message, "Privoxy Error", 
421       MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_SETFOREGROUND | MB_TOPMOST);  
422
423    /* Cleanup - remove taskbar icon etc. */
424    TermLogWindow();
425
426 #else /* if !defined(_WIN32) || defined(_WIN_CONSOLE) */
427    fputs(error_message, logfp);
428 #endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */
429
430 #if defined(unix)
431    if (pidfile)
432    {
433       unlink(pidfile);
434    }
435 #endif /* unix */
436
437    exit(1);
438 }
439
440
441 /*********************************************************************
442  *
443  * Function    :  show_version
444  *
445  * Description :  Logs the Privoxy version and the program name.
446  *
447  * Parameters  :
448  *          1  :  prog_name = The program name.
449  *
450  * Returns     :  Nothing.
451  *
452  *********************************************************************/
453 static void show_version(const char *prog_name)
454 {
455    log_error(LOG_LEVEL_INFO, "Privoxy version " VERSION);
456    if (prog_name != NULL)
457    {
458       log_error(LOG_LEVEL_INFO, "Program name: %s", prog_name);
459    }
460 }
461
462
463 /*********************************************************************
464  *
465  * Function    :  init_log_module
466  *
467  * Description :  Initializes the logging module to log to stderr.
468  *                Can only be called while stderr hasn't been closed
469  *                yet and is only supposed to be called once.
470  *
471  * Parameters  :
472  *          1  :  prog_name = The program name.
473  *
474  * Returns     :  Nothing.
475  *
476  *********************************************************************/
477 void init_log_module(const char *prog_name)
478 {
479    lock_logfile();
480    logfp = stderr;
481    unlock_logfile();
482    set_debug_level(debug);
483    show_version(prog_name);
484 }
485
486
487 /*********************************************************************
488  *
489  * Function    :  set_debug_level
490  *
491  * Description :  Sets the debug level to the provided value
492  *                plus LOG_LEVEL_MINIMUM.
493  *
494  *                XXX: we should only use the LOG_LEVEL_MINIMUM
495  *                until the frist time the configuration file has
496  *                been parsed.
497  *                
498  * Parameters  :  1: debug_level = The debug level to set.
499  *
500  * Returns     :  Nothing.
501  *
502  *********************************************************************/
503 void set_debug_level(int debug_level)
504 {
505    debug = debug_level | LOG_LEVEL_MINIMUM;
506 }
507
508
509 /*********************************************************************
510  *
511  * Function    :  disable_logging
512  *
513  * Description :  Disables logging.
514  *                
515  * Parameters  :  None.
516  *
517  * Returns     :  Nothing.
518  *
519  *********************************************************************/
520 void disable_logging(void)
521 {
522    lock_logfile();
523    if (logfp != NULL)
524    {
525       log_error(LOG_LEVEL_INFO, "No logfile configured. Logging disabled.");
526       fclose(logfp);
527       logfp = NULL;
528    }
529    unlock_logfile();
530 }
531
532
533 /*********************************************************************
534  *
535  * Function    :  init_error_log
536  *
537  * Description :  Initializes the logging module to log to a file.
538  *
539  *                XXX: should be renamed.
540  *
541  * Parameters  :
542  *          1  :  prog_name  = The program name.
543  *          2  :  logfname   = The logfile name, or NULL for stderr.
544  *          3  :  debuglevel = The debugging level.
545  *
546  * Returns     :  N/A
547  *
548  *********************************************************************/
549 void init_error_log(const char *prog_name, const char *logfname)
550 {
551    FILE *fp;
552
553    assert(NULL != logfname);
554
555    lock_loginit();
556
557    if (logfp == stderr)
558    {
559       log_error(LOG_LEVEL_INFO,
560          "Switching to daemon mode. Log messages will be written to: %s", logfname);
561    }
562    else if (logfp != NULL)
563    {
564       log_error(LOG_LEVEL_INFO, "(Re-)Open logfile \'%s\'", logfname ? logfname : "none");
565    }
566
567    /* set the designated log file */
568    fp = fopen(logfname, "a");
569    if (NULL == fp)
570    {
571       log_error(LOG_LEVEL_FATAL, "init_error_log(): can't open logfile: \'%s\'", logfname);
572    }
573
574    /* set logging to be completely unbuffered */
575    setbuf(fp, NULL);
576
577    lock_logfile();
578    if (logfp != NULL)
579    {
580       fclose(logfp);
581    }
582    logfp = fp;
583    unlock_logfile();
584
585    show_version(prog_name);
586
587    unlock_loginit();
588
589 } /* init_error_log */
590
591
592 /*********************************************************************
593  *
594  * Function    :  get_thread_id
595  *
596  * Description :  Returns a number that is different for each thread.
597  *
598  *                XXX: Should be moved elsewhere (miscutil.c?)
599  *                
600  * Parameters  :  None
601  *
602  * Returns     :  thread_id
603  *
604  *********************************************************************/
605 static long get_thread_id(void)
606 {
607    long this_thread = 1;  /* was: pthread_t this_thread;*/
608
609 #ifdef __OS2__
610    PTIB     ptib;
611    APIRET   ulrc; /* XXX: I have no clue what this does */
612 #endif /* __OS2__ */
613
614    /* FIXME get current thread id */
615 #ifdef FEATURE_PTHREAD
616    this_thread = (long)pthread_self();
617 #ifdef __MACH__
618    /*
619     * Mac OSX (and perhaps other Mach instances) doesn't have a debuggable
620     * value at the first 4 bytes of pthread_self()'s return value, a pthread_t.
621     * pthread_t is supposed to be opaque... but it's fairly random, though, so
622     * we make it mostly presentable.
623     */
624    this_thread = abs(this_thread % 1000);
625 #endif /* def __MACH__ */
626 #elif defined(_WIN32)
627    this_thread = GetCurrentThreadId();
628 #elif defined(__OS2__)
629    ulrc = DosGetInfoBlocks(&ptib, NULL);
630    if (ulrc == 0)
631      this_thread = ptib -> tib_ptib2 -> tib2_ultid;
632 #endif /* def FEATURE_PTHREAD */
633
634    return this_thread;
635 }
636
637
638 /*********************************************************************
639  *
640  * Function    :  get_log_timestamp
641  *
642  * Description :  Generates the time stamp for the log message prefix.
643  *
644  * Parameters  :
645  *          1  :  buffer = Storage buffer
646  *          2  :  buffer_size = Size of storage buffer
647  *
648  * Returns     :  Number of written characters or 0 for error.
649  *
650  *********************************************************************/
651 static inline size_t get_log_timestamp(char *buffer, size_t buffer_size)
652 {
653    size_t length;
654    time_t now; 
655    struct tm tm_now;
656    struct timeval tv_now; /* XXX: stupid name */
657    long msecs;
658    int msecs_length = 0;
659
660    gettimeofday(&tv_now, NULL);
661    msecs = tv_now.tv_usec / 1000;
662
663    time(&now);
664
665 #ifdef HAVE_LOCALTIME_R
666    tm_now = *localtime_r(&now, &tm_now);
667 #elif FEATURE_PTHREAD
668    pthread_mutex_lock(&localtime_mutex);
669    tm_now = *localtime(&now); 
670    pthread_mutex_unlock(&localtime_mutex);
671 #else
672    tm_now = *localtime(&now); 
673 #endif
674
675    length = strftime(buffer, buffer_size, "%b %d %H:%M:%S", &tm_now);
676    if (length > 0);
677    {
678       msecs_length = snprintf(buffer+length, buffer_size - length, ".%.3ld", msecs);               
679    }
680    if (msecs_length > 0)
681    {
682       length += (size_t)msecs_length;
683    }
684    else
685    {
686       length = 0;
687    }
688
689    return length;
690 }
691
692
693 /*********************************************************************
694  *
695  * Function    :  get_clf_timestamp
696  *
697  * Description :  Generates a Common Log Format time string.
698  *
699  * Parameters  :
700  *          1  :  buffer = Storage buffer
701  *          2  :  buffer_size = Size of storage buffer
702  *
703  * Returns     :  Number of written characters or 0 for error.
704  *
705  *********************************************************************/
706 static inline size_t get_clf_timestamp(char *buffer, size_t buffer_size)
707 {
708    /*
709     * Complex because not all OSs have tm_gmtoff or
710     * the %z field in strftime()
711     */
712    time_t now;
713    struct tm *tm_now; 
714    struct tm gmt;
715 #ifdef HAVE_LOCALTIME_R
716    struct tm dummy;
717 #endif
718    int days, hrs, mins;
719    size_t length;
720    int tz_length = 0;
721
722    time (&now); 
723 #ifdef HAVE_GMTIME_R
724    gmt = *gmtime_r(&now, &gmt);
725 #elif FEATURE_PTHREAD
726    pthread_mutex_lock(&gmtime_mutex);
727    gmt = *gmtime(&now);
728    pthread_mutex_unlock(&gmtime_mutex);
729 #else
730    gmt = *gmtime(&now);
731 #endif
732 #ifdef HAVE_LOCALTIME_R
733    tm_now = localtime_r(&now, &dummy);
734 #elif FEATURE_PTHREAD
735    pthread_mutex_lock(&localtime_mutex);
736    tm_now = localtime(&now); 
737    pthread_mutex_unlock(&localtime_mutex);
738 #else
739    tm_now = localtime(&now); 
740 #endif
741    days = tm_now->tm_yday - gmt.tm_yday; 
742    hrs = ((days < -1 ? 24 : 1 < days ? -24 : days * 24) + tm_now->tm_hour - gmt.tm_hour); 
743    mins = hrs * 60 + tm_now->tm_min - gmt.tm_min; 
744
745    length = strftime(buffer, buffer_size, "%d/%b/%Y:%H:%M:%S ", tm_now);
746
747    if (length > 0);
748    {
749       tz_length = snprintf(buffer+length, buffer_size-length,
750                      "%+03d%02d", mins / 60, abs(mins) % 60);
751    }
752    if (tz_length > 0)
753    {
754       length += (size_t)tz_length;
755    }
756    else
757    {
758       length = 0;
759    }
760
761    return length;
762 }
763
764
765 /*********************************************************************
766  *
767  * Function    :  get_log_level_string
768  *
769  * Description :  Translates a numerical loglevel into a string.
770  *
771  * Parameters  :  
772  *          1  :  loglevel = LOG_LEVEL_FOO
773  *
774  * Returns     :  Log level string.
775  *
776  *********************************************************************/
777 static inline const char *get_log_level_string(int loglevel)
778 {
779    char *log_level_string = NULL;
780
781    assert(0 < loglevel);
782
783    switch (loglevel)
784    {
785       case LOG_LEVEL_ERROR:
786          log_level_string = "Error";
787          break;
788       case LOG_LEVEL_FATAL:
789          log_level_string = "Fatal error";
790          break;
791       case LOG_LEVEL_GPC:
792          log_level_string = "Request";
793          break;
794       case LOG_LEVEL_CONNECT:
795          log_level_string = "Connect";
796          break;
797       case LOG_LEVEL_LOG:
798          log_level_string = "Writing";
799          break;
800       case LOG_LEVEL_HEADER:
801          log_level_string = "Header";
802          break;
803       case LOG_LEVEL_INFO:
804          log_level_string = "Info";
805          break;
806       case LOG_LEVEL_RE_FILTER:
807          log_level_string = "Re-Filter";
808          break;
809 #ifdef FEATURE_FORCE_LOAD
810       case LOG_LEVEL_FORCE:
811          log_level_string = "Force";
812          break;
813 #endif /* def FEATURE_FORCE_LOAD */
814 #ifdef FEATURE_FAST_REDIRECTS
815       case LOG_LEVEL_REDIRECTS:
816          log_level_string = "Redirect";
817          break;
818 #endif /* def FEATURE_FAST_REDIRECTS */
819       case LOG_LEVEL_DEANIMATE:
820          log_level_string = "Gif-Deanimate";
821          break;
822 #ifdef FEATURE_KILL_POPUPS
823       case LOG_LEVEL_POPUPS:
824          log_level_string = "Kill-Popups";
825          break;
826 #endif /* def FEATURE_KILL_POPUPS */
827       case LOG_LEVEL_CGI:
828          log_level_string = "CGI";
829          break;
830       default:
831          log_level_string = "Unknown log level";
832          break;
833    }
834    assert(NULL != log_level_string);
835
836    return log_level_string;
837 }
838
839
840 /*********************************************************************
841  *
842  * Function    :  log_error
843  *
844  * Description :  This is the error-reporting and logging function.
845  *
846  * Parameters  :
847  *          1  :  loglevel  = the type of message to be logged
848  *          2  :  fmt       = the main string we want logged, printf-like
849  *          3  :  ...       = arguments to be inserted in fmt (printf-like).
850  *
851  * Returns     :  N/A
852  *
853  *********************************************************************/
854 void log_error(int loglevel, const char *fmt, ...)
855 {
856    va_list ap;
857    char *outbuf = NULL;
858    static char *outbuf_save = NULL;
859    char tempbuf[BUFFER_SIZE];
860    size_t length = 0;
861    const char * src = fmt;
862    long thread_id;
863    char timestamp[30];
864    /*
865     * XXX: Make this a config option,
866     * why else do we allocate instead of using
867     * an array?
868     */
869    size_t log_buffer_size = BUFFER_SIZE;
870
871 #if defined(_WIN32) && !defined(_WIN_CONSOLE)
872    /*
873     * Irrespective of debug setting, a GET/POST/CONNECT makes
874     * the taskbar icon animate.  (There is an option to disable
875     * this but checking that is handled inside LogShowActivity()).
876     */
877    if (loglevel == LOG_LEVEL_GPC)
878    {
879       LogShowActivity();
880    }
881 #endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */
882
883    /*
884     * verify that the loglevel applies to current
885     * settings and that logging is enabled.
886     * Bail out otherwise.
887     */
888    if ((0 == (loglevel & debug)) || (logfp == NULL))
889    {
890       return;
891    }
892
893    thread_id = get_thread_id();
894    get_log_timestamp(timestamp, sizeof(timestamp));
895
896    /* protect the whole function because of the static buffer (outbuf) */
897    lock_logfile();
898
899    if (NULL == outbuf_save) 
900    {
901       outbuf_save = (char*)zalloc(log_buffer_size + 1); /* +1 for paranoia */
902       if (NULL == outbuf_save)
903       {
904          snprintf(tempbuf, sizeof(tempbuf),
905             "%s Privoxy(%08lx) Fatal error: log_error() failed to allocate buffer memory.\n"
906             "\nExiting.", timestamp, thread_id);
907          assert(NULL != logfp);
908          fputs(tempbuf, logfp);
909          unlock_logfile();
910          fatal_error(tempbuf); /* Exit */
911       }
912    }
913    outbuf = outbuf_save;
914
915    /*
916     * Memsetting the whole buffer to zero (in theory)
917     * makes things easier later on.
918     */
919    memset(outbuf, 0, log_buffer_size);
920
921    /* Add prefix for everything but Common Log Format messages */
922    if (loglevel != LOG_LEVEL_CLF)
923    {
924       length = (size_t)snprintf(outbuf, log_buffer_size, "%s Privoxy(%08lx) %s: ",
925                                 timestamp, thread_id, get_log_level_string(loglevel));
926    }
927
928    /* get ready to scan var. args. */
929    va_start(ap, fmt);
930
931    /* build formatted message from fmt and var-args */
932    while ((*src) && (length < log_buffer_size-2))
933    {
934       const char *sval = NULL; /* %N string  */
935       int ival;                /* %N string length or an error code */
936       unsigned uval;           /* %u value */
937       long lval;               /* %l value */
938       unsigned long ulval;     /* %ul value */
939       char ch;
940       const char *format_string = tempbuf;
941
942       ch = *src++;
943       if (ch != '%')
944       {
945          outbuf[length++] = ch;
946          /*
947           * XXX: Only necessary on platforms which don't use pthread
948           * mutexes (mingw32 for example), where multiple threads can
949           * write to the buffer at the same time.
950           */
951          outbuf[length] = '\0';
952          continue;
953       }
954       outbuf[length] = '\0';
955       ch = *src++;
956       switch (ch) {
957          case '%':
958             tempbuf[0] = '%';
959             tempbuf[1] = '\0';
960             break;
961          case 'd':
962             ival = va_arg( ap, int );
963             snprintf(tempbuf, sizeof(tempbuf), "%d", ival);
964             break;
965          case 'u':
966             uval = va_arg( ap, unsigned );
967             snprintf(tempbuf, sizeof(tempbuf), "%u", uval);
968             break;
969          case 'l':
970             /* this is a modifier that must be followed by u or d */
971             ch = *src++;
972             if (ch == 'd')
973             {
974                lval = va_arg( ap, long );
975                snprintf(tempbuf, sizeof(tempbuf), "%ld", lval);
976             }
977             else if (ch == 'u')
978             {
979                ulval = va_arg( ap, unsigned long );
980                snprintf(tempbuf, sizeof(tempbuf), "%lu", ulval);
981             }
982             else
983             {
984                snprintf(tempbuf, sizeof(tempbuf), "Bad format string: \"%s\"", fmt);
985                loglevel = LOG_LEVEL_FATAL;
986             }
987             break;
988          case 'c':
989             /*
990              * Note that char paramaters are converted to int, so we need to
991              * pass "int" to va_arg.  (See K&R, 2nd ed, section A7.3.2, page 202)
992              */
993             tempbuf[0] = (char) va_arg(ap, int);
994             tempbuf[1] = '\0';
995             break;
996          case 's':
997             format_string = va_arg(ap, char *);
998             if (format_string == NULL)
999             {
1000                format_string = "[null]";
1001             }
1002             break;
1003          case 'N':
1004             /*
1005              * Non-standard: Print a counted unterminated string.
1006              * Takes 2 parameters: int length, const char * string.
1007              */
1008             ival = va_arg(ap, int);
1009             sval = va_arg(ap, char *);
1010             if (sval == NULL)
1011             {
1012                format_string = "[null]";
1013             }
1014             else if (ival <= 0)
1015             {
1016                if (0 == ival)
1017                {
1018                   /* That's ok (but stupid) */
1019                   tempbuf[0] = '\0';
1020                }
1021                else
1022                {
1023                   /*
1024                    * That's not ok (and even more stupid)
1025                    */
1026                   assert(ival >= 0);
1027                   format_string = "[counted string lenght < 0]";
1028                }
1029             }
1030             else if (ival >= sizeof(tempbuf))
1031             {
1032                /*
1033                 * String is too long, copy as much as possible.
1034                 * It will be further truncated later.
1035                 */
1036                memcpy(tempbuf, sval, sizeof(tempbuf)-1);
1037                tempbuf[sizeof(tempbuf)-1] = '\0';
1038             }
1039             else
1040             {
1041                memcpy(tempbuf, sval, (size_t) ival);
1042                tempbuf[ival] = '\0';
1043             }
1044             break;
1045          case 'E':
1046             /* Non-standard: Print error code from errno */
1047 #ifdef _WIN32
1048             ival = WSAGetLastError();
1049             format_string = w32_socket_strerr(ival, tempbuf);
1050 #elif __OS2__
1051             ival = sock_errno();
1052             if (ival != 0)
1053             {
1054                format_string = os2_socket_strerr(ival, tempbuf);
1055             }
1056             else
1057             {
1058                ival = errno;
1059                format_string = strerror(ival);
1060             }
1061 #else /* ifndef _WIN32 */
1062             ival = errno; 
1063 #ifdef HAVE_STRERROR
1064             format_string = strerror(ival);
1065 #else /* ifndef HAVE_STRERROR */
1066             format_string = NULL;
1067 #endif /* ndef HAVE_STRERROR */
1068             if (sval == NULL)
1069             {
1070                snprintf(tempbuf, sizeof(tempbuf), "(errno = %d)", ival);
1071             }
1072 #endif /* ndef _WIN32 */
1073             break;
1074          case 'T':
1075             /* Non-standard: Print a Common Log File timestamp */
1076             get_clf_timestamp(tempbuf, sizeof(tempbuf));
1077             break;
1078          default:
1079             snprintf(tempbuf, sizeof(tempbuf), "Bad format string: \"%s\"", fmt);
1080             loglevel = LOG_LEVEL_FATAL;
1081             break;
1082       } /* switch( p ) */
1083
1084       assert(length < log_buffer_size);
1085       length += strlcpy(outbuf + length, format_string, log_buffer_size - length);
1086
1087       if (length >= log_buffer_size-2)
1088       {
1089          static char warning[] = "... [too long, truncated]";
1090
1091          length = log_buffer_size - sizeof(warning) - 1;
1092          length += strlcpy(outbuf + length, warning, log_buffer_size - length);
1093          assert(length < log_buffer_size);
1094
1095          break;
1096       }
1097    } /* for( p ... ) */
1098
1099    /* done with var. args */
1100    va_end(ap);
1101
1102    assert(length < log_buffer_size);
1103    length += strlcpy(outbuf + length, "\n", log_buffer_size - length);
1104
1105    /* Some sanity checks */
1106    if (!(length < log_buffer_size)
1107     || !(outbuf[log_buffer_size-1] == '\0')
1108     || !(outbuf[log_buffer_size] == '\0')
1109       )
1110    {
1111       /* Repeat as assertions */
1112       assert(length < log_buffer_size);
1113       assert(outbuf[log_buffer_size-1] == '\0');
1114       /*
1115        * outbuf's real size is log_buffer_size+1,
1116        * so while this looks like an off-by-one,
1117        * we're only checking our paranoia byte.
1118        */
1119       assert(outbuf[log_buffer_size] == '\0');
1120
1121       snprintf(outbuf, log_buffer_size,
1122          "%s Privoxy(%08lx) Fatal error: log_error()'s sanity checks failed. length: %d\n"
1123          "Exiting.", timestamp, thread_id, (int)length);
1124       loglevel = LOG_LEVEL_FATAL;
1125    }
1126
1127    assert(NULL != logfp);
1128
1129    if (loglevel == LOG_LEVEL_FATAL)
1130    {
1131       fatal_error(outbuf_save);
1132       /* Never get here */
1133    }
1134    fputs(outbuf_save, logfp);
1135
1136    unlock_logfile();
1137
1138 #if defined(_WIN32) && !defined(_WIN_CONSOLE)
1139    /* Write to display */
1140    LogPutString(outbuf_save);
1141 #endif /* defined(_WIN32) && !defined(_WIN_CONSOLE) */
1142
1143 }
1144
1145
1146 /*********************************************************************
1147  *
1148  * Function    :  jb_err_to_string
1149  *
1150  * Description :  Translates JB_ERR_FOO codes into strings.
1151  *
1152  *                XXX: the type of error codes is jb_err
1153  *                but the typedef'inition is currently not
1154  *                visible to all files that include errlog.h.
1155  *
1156  * Parameters  :
1157  *          1  :  error = a valid jb_err code
1158  *
1159  * Returns     :  A string with the jb_err translation
1160  *
1161  *********************************************************************/
1162 const char *jb_err_to_string(int error)
1163 {
1164    switch (error)
1165    {
1166       case JB_ERR_OK:
1167          return "Success, no error";
1168       case JB_ERR_MEMORY:
1169          return "Out of memory";
1170       case JB_ERR_CGI_PARAMS:
1171          return "Missing or corrupt CGI parameters";
1172       case JB_ERR_FILE:
1173          return "Error opening, reading or writing a file";
1174       case JB_ERR_PARSE:
1175          return "Parse error";
1176       case JB_ERR_MODIFIED:
1177          return "File has been modified outside of the CGI actions editor.";
1178       case JB_ERR_COMPRESS:
1179          return "(De)compression failure";
1180       default:
1181          assert(0);
1182          return "Unknown error";
1183    }
1184    assert(0);
1185    return "Internal error";
1186 }
1187
1188 #ifdef _WIN32
1189 /*********************************************************************
1190  *
1191  * Function    :  w32_socket_strerr
1192  *
1193  * Description :  Translate the return value from WSAGetLastError()
1194  *                into a string.
1195  *
1196  * Parameters  :
1197  *          1  :  errcode = The return value from WSAGetLastError().
1198  *          2  :  tmp_buf = A temporary buffer that might be used to
1199  *                          store the string.
1200  *
1201  * Returns     :  String representing the error code.  This may be
1202  *                a global string constant or a string stored in
1203  *                tmp_buf.
1204  *
1205  *********************************************************************/
1206 static char *w32_socket_strerr(int errcode, char *tmp_buf)
1207 {
1208 #define TEXT_FOR_ERROR(code,text) \
1209    if (errcode == code)           \
1210    {                              \
1211       return #code " - " text;    \
1212    }
1213
1214    TEXT_FOR_ERROR(WSAEACCES, "Permission denied")
1215    TEXT_FOR_ERROR(WSAEADDRINUSE, "Address already in use.")
1216    TEXT_FOR_ERROR(WSAEADDRNOTAVAIL, "Cannot assign requested address.");
1217    TEXT_FOR_ERROR(WSAEAFNOSUPPORT, "Address family not supported by protocol family.");
1218    TEXT_FOR_ERROR(WSAEALREADY, "Operation already in progress.");
1219    TEXT_FOR_ERROR(WSAECONNABORTED, "Software caused connection abort.");
1220    TEXT_FOR_ERROR(WSAECONNREFUSED, "Connection refused.");
1221    TEXT_FOR_ERROR(WSAECONNRESET, "Connection reset by peer.");
1222    TEXT_FOR_ERROR(WSAEDESTADDRREQ, "Destination address required.");
1223    TEXT_FOR_ERROR(WSAEFAULT, "Bad address.");
1224    TEXT_FOR_ERROR(WSAEHOSTDOWN, "Host is down.");
1225    TEXT_FOR_ERROR(WSAEHOSTUNREACH, "No route to host.");
1226    TEXT_FOR_ERROR(WSAEINPROGRESS, "Operation now in progress.");
1227    TEXT_FOR_ERROR(WSAEINTR, "Interrupted function call.");
1228    TEXT_FOR_ERROR(WSAEINVAL, "Invalid argument.");
1229    TEXT_FOR_ERROR(WSAEISCONN, "Socket is already connected.");
1230    TEXT_FOR_ERROR(WSAEMFILE, "Too many open sockets.");
1231    TEXT_FOR_ERROR(WSAEMSGSIZE, "Message too long.");
1232    TEXT_FOR_ERROR(WSAENETDOWN, "Network is down.");
1233    TEXT_FOR_ERROR(WSAENETRESET, "Network dropped connection on reset.");
1234    TEXT_FOR_ERROR(WSAENETUNREACH, "Network is unreachable.");
1235    TEXT_FOR_ERROR(WSAENOBUFS, "No buffer space available.");
1236    TEXT_FOR_ERROR(WSAENOPROTOOPT, "Bad protocol option.");
1237    TEXT_FOR_ERROR(WSAENOTCONN, "Socket is not connected.");
1238    TEXT_FOR_ERROR(WSAENOTSOCK, "Socket operation on non-socket.");
1239    TEXT_FOR_ERROR(WSAEOPNOTSUPP, "Operation not supported.");
1240    TEXT_FOR_ERROR(WSAEPFNOSUPPORT, "Protocol family not supported.");
1241    TEXT_FOR_ERROR(WSAEPROCLIM, "Too many processes.");
1242    TEXT_FOR_ERROR(WSAEPROTONOSUPPORT, "Protocol not supported.");
1243    TEXT_FOR_ERROR(WSAEPROTOTYPE, "Protocol wrong type for socket.");
1244    TEXT_FOR_ERROR(WSAESHUTDOWN, "Cannot send after socket shutdown.");
1245    TEXT_FOR_ERROR(WSAESOCKTNOSUPPORT, "Socket type not supported.");
1246    TEXT_FOR_ERROR(WSAETIMEDOUT, "Connection timed out.");
1247    TEXT_FOR_ERROR(WSAEWOULDBLOCK, "Resource temporarily unavailable.");
1248    TEXT_FOR_ERROR(WSAHOST_NOT_FOUND, "Host not found.");
1249    TEXT_FOR_ERROR(WSANOTINITIALISED, "Successful WSAStartup not yet performed.");
1250    TEXT_FOR_ERROR(WSANO_DATA, "Valid name, no data record of requested type.");
1251    TEXT_FOR_ERROR(WSANO_RECOVERY, "This is a non-recoverable error.");
1252    TEXT_FOR_ERROR(WSASYSNOTREADY, "Network subsystem is unavailable.");
1253    TEXT_FOR_ERROR(WSATRY_AGAIN, "Non-authoritative host not found.");
1254    TEXT_FOR_ERROR(WSAVERNOTSUPPORTED, "WINSOCK.DLL version out of range.");
1255    TEXT_FOR_ERROR(WSAEDISCON, "Graceful shutdown in progress.");
1256    /*
1257     * The following error codes are documented in the Microsoft WinSock
1258     * reference guide, but don't actually exist.
1259     *
1260     * TEXT_FOR_ERROR(WSA_INVALID_HANDLE, "Specified event object handle is invalid.");
1261     * TEXT_FOR_ERROR(WSA_INVALID_PARAMETER, "One or more parameters are invalid.");
1262     * TEXT_FOR_ERROR(WSAINVALIDPROCTABLE, "Invalid procedure table from service provider.");
1263     * TEXT_FOR_ERROR(WSAINVALIDPROVIDER, "Invalid service provider version number.");
1264     * TEXT_FOR_ERROR(WSA_IO_PENDING, "Overlapped operations will complete later.");
1265     * TEXT_FOR_ERROR(WSA_IO_INCOMPLETE, "Overlapped I/O event object not in signaled state.");
1266     * TEXT_FOR_ERROR(WSA_NOT_ENOUGH_MEMORY, "Insufficient memory available.");
1267     * TEXT_FOR_ERROR(WSAPROVIDERFAILEDINIT, "Unable to initialize a service provider.");
1268     * TEXT_FOR_ERROR(WSASYSCALLFAILURE, "System call failure.");
1269     * TEXT_FOR_ERROR(WSA_OPERATION_ABORTED, "Overlapped operation aborted.");
1270     */
1271
1272    sprintf(tmp_buf, "(error number %d)", errcode);
1273    return tmp_buf;
1274 }
1275 #endif /* def _WIN32 */
1276
1277
1278 #ifdef __OS2__
1279 /*********************************************************************
1280  *
1281  * Function    :  os2_socket_strerr
1282  *
1283  * Description :  Translate the return value from sock_errno()
1284  *                into a string.
1285  *
1286  * Parameters  :
1287  *          1  :  errcode = The return value from sock_errno().
1288  *          2  :  tmp_buf = A temporary buffer that might be used to
1289  *                          store the string.
1290  *
1291  * Returns     :  String representing the error code.  This may be
1292  *                a global string constant or a string stored in
1293  *                tmp_buf.
1294  *
1295  *********************************************************************/
1296 static char *os2_socket_strerr(int errcode, char *tmp_buf)
1297 {
1298 #define TEXT_FOR_ERROR(code,text) \
1299    if (errcode == code)           \
1300    {                              \
1301       return #code " - " text;    \
1302    }
1303
1304    TEXT_FOR_ERROR(SOCEPERM          , "Not owner.")
1305    TEXT_FOR_ERROR(SOCESRCH          , "No such process.")
1306    TEXT_FOR_ERROR(SOCEINTR          , "Interrupted system call.")
1307    TEXT_FOR_ERROR(SOCENXIO          , "No such device or address.")
1308    TEXT_FOR_ERROR(SOCEBADF          , "Bad file number.")
1309    TEXT_FOR_ERROR(SOCEACCES         , "Permission denied.")
1310    TEXT_FOR_ERROR(SOCEFAULT         , "Bad address.")
1311    TEXT_FOR_ERROR(SOCEINVAL         , "Invalid argument.")
1312    TEXT_FOR_ERROR(SOCEMFILE         , "Too many open files.")
1313    TEXT_FOR_ERROR(SOCEPIPE          , "Broken pipe.")
1314    TEXT_FOR_ERROR(SOCEWOULDBLOCK    , "Operation would block.")
1315    TEXT_FOR_ERROR(SOCEINPROGRESS    , "Operation now in progress.")
1316    TEXT_FOR_ERROR(SOCEALREADY       , "Operation already in progress.")
1317    TEXT_FOR_ERROR(SOCENOTSOCK       , "Socket operation on non-socket.")
1318    TEXT_FOR_ERROR(SOCEDESTADDRREQ   , "Destination address required.")
1319    TEXT_FOR_ERROR(SOCEMSGSIZE       , "Message too long.")
1320    TEXT_FOR_ERROR(SOCEPROTOTYPE     , "Protocol wrong type for socket.")
1321    TEXT_FOR_ERROR(SOCENOPROTOOPT    , "Protocol not available.")
1322    TEXT_FOR_ERROR(SOCEPROTONOSUPPORT, "Protocol not supported.")
1323    TEXT_FOR_ERROR(SOCESOCKTNOSUPPORT, "Socket type not supported.")
1324    TEXT_FOR_ERROR(SOCEOPNOTSUPP     , "Operation not supported.")
1325    TEXT_FOR_ERROR(SOCEPFNOSUPPORT   , "Protocol family not supported.")
1326    TEXT_FOR_ERROR(SOCEAFNOSUPPORT   , "Address family not supported by protocol family.")
1327    TEXT_FOR_ERROR(SOCEADDRINUSE     , "Address already in use.")
1328    TEXT_FOR_ERROR(SOCEADDRNOTAVAIL  , "Can't assign requested address.")
1329    TEXT_FOR_ERROR(SOCENETDOWN       , "Network is down.")
1330    TEXT_FOR_ERROR(SOCENETUNREACH    , "Network is unreachable.")
1331    TEXT_FOR_ERROR(SOCENETRESET      , "Network dropped connection on reset.")
1332    TEXT_FOR_ERROR(SOCECONNABORTED   , "Software caused connection abort.")
1333    TEXT_FOR_ERROR(SOCECONNRESET     , "Connection reset by peer.")
1334    TEXT_FOR_ERROR(SOCENOBUFS        , "No buffer space available.")
1335    TEXT_FOR_ERROR(SOCEISCONN        , "Socket is already connected.")
1336    TEXT_FOR_ERROR(SOCENOTCONN       , "Socket is not connected.")
1337    TEXT_FOR_ERROR(SOCESHUTDOWN      , "Can't send after socket shutdown.")
1338    TEXT_FOR_ERROR(SOCETOOMANYREFS   , "Too many references: can't splice.")
1339    TEXT_FOR_ERROR(SOCETIMEDOUT      , "Operation timed out.")
1340    TEXT_FOR_ERROR(SOCECONNREFUSED   , "Connection refused.")
1341    TEXT_FOR_ERROR(SOCELOOP          , "Too many levels of symbolic links.")
1342    TEXT_FOR_ERROR(SOCENAMETOOLONG   , "File name too long.")
1343    TEXT_FOR_ERROR(SOCEHOSTDOWN      , "Host is down.")
1344    TEXT_FOR_ERROR(SOCEHOSTUNREACH   , "No route to host.")
1345    TEXT_FOR_ERROR(SOCENOTEMPTY      , "Directory not empty.")
1346    TEXT_FOR_ERROR(SOCEOS2ERR        , "OS/2 Error.")
1347
1348    sprintf(tmp_buf, "(error number %d)", errcode);
1349    return tmp_buf;
1350 }
1351 #endif /* def __OS2__ */
1352
1353
1354 /*
1355   Local Variables:
1356   tab-width: 3
1357   end:
1358 */