home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / freeWAIS-sf-1.1 / ir / cutil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-08  |  27.1 KB  |  1,227 lines

  1.  
  2. /* Copyright (c) CNIDR (Work in progress) */
  3.  
  4. /* Wide AREA INFORMATION SERVER SOFTWARE    
  5.    No guarantees or restrictions.  See the readme file for the full standard
  6.    disclaimer.  
  7.   
  8.    3.26.90    Harry Morris, morris@think.com
  9.    4.11.90  HWM - generalized conditional includes (see c-dialect.h)
  10.    7/19/91  speed up substrcmp by ses@ccgr.technion.ac.il (Simon E Spero)
  11.  *
  12.  * $Log: cutil.c,v $
  13.  * Revision 1.21  1994/09/08  16:43:14  pfeifer
  14.  * removed dead code (was ifdef'ed AUTOCONF)
  15.  *
  16.  * Revision 1.20  1994/09/02  14:34:21  pfeifer
  17.  * fixed overlapping memory copies
  18.  *
  19.  * Revision 1.19  1994/08/08  07:31:52  pfeifer
  20.  * Moved wais_log_file_name and waislogfile to cutil.[ch]
  21.  *
  22.  * Revision 1.17  1994/06/13  10:40:39  pfeifer
  23.  * replaced strdup by function provided by Kent C Brodie
  24.  * <kcb@post.its.mcw.edu>
  25.  *
  26.  * Revision 1.16  1994/06/10  12:49:48  pfeifer
  27.  * typo
  28.  *
  29.  * Revision 1.15  1994/06/10  08:22:43  pfeifer
  30.  * bad typo
  31.  *
  32.  * Revision 1.14  1994/06/10  08:15:24  pfeifer
  33.  * added definition for strdup, wich is missing with solaris 2.3 ?
  34.  *
  35.  * Revision 1.13  1994/05/21  14:35:24  pfeifer
  36.  * initalize memory, in fs_realloc if it is really an malloc (should be
  37.  * obsolete :-( )
  38.  *
  39.  * Revision 1.12  1994/05/20  12:55:43  pfeifer
  40.  * beta
  41.  *
  42.  * Revision 1.11  1994/03/23  15:30:58  pfeifer
  43.  * fixed iso code
  44.  *
  45.  * Revision 1.10  1994/03/08  20:57:40  pfeifer
  46.  * Patchlevel 04
  47.  *
  48.  * Revision 1.9  1993/09/22  16:07:52  pfeifer
  49.  * Fixed word breaking for german ISO Umlaute and sz
  50.  *
  51.  * Revision 1.8  1993/07/16  12:10:19  huynh1
  52.  * Function generate_newline_for_boolean deleted!
  53.  *
  54.  * Revision 1.7  1993/07/14  09:52:38  huynh1
  55.  * keine "Anderung!
  56.  *
  57.  * Revision 1.6  1993/07/14  07:30:24  huynh1
  58.  * "Anderung in der Funktion generate_newline_for_boolean: Variable umbenannt: brackets = parentheses!
  59.  *
  60.  * Revision 1.5  1993/07/13  19:14:43  huynh1
  61.  * printf(".....") gel"oscht!
  62.  *
  63.  * Revision 1.4  1993/07/13  18:44:04  huynh1
  64.  * Keine "Anderung!
  65.  *
  66.  * Revision 1.3  1993/07/13  18:40:31  huynh1
  67.  * funktion generate_newline_for_boolean eingef"ugt!
  68.  *
  69.  * Revision 1.2  1993/02/16  14:59:21  freewais
  70.  * include stdargs.h or varargs.h based on whether compiler
  71.  * is ansi or non-ansi
  72.  *
  73.  * Revision 1.1  1993/02/16  14:53:14  freewais
  74.  * Initial revision
  75.  *
  76.  * Revision 1.24  92/03/28  19:53:39  jonathan
  77.  * Removed useless ifdef BSD in cprintf
  78.  * 
  79.  * Revision 1.23  92/03/07  19:44:39  jonathan
  80.  * ANSIfied arguments.
  81.  * 
  82.  * Revision 1.22  92/03/04  16:14:23  jonathan
  83.  * Added include <ctype.h> for isalnum.
  84.  * 
  85.  * Revision 1.21  92/02/21  11:03:15  jonathan
  86.  * Fixed $Log.
  87.  * 
  88.  * Revision 1.20  92/02/21  11:02:02  jonathan
  89.  * Added wais_log_level, RCSIdent
  90.  * 
  91.  * Revision 1.19  92/02/16  21:24:54  jonathan
  92.  * Added code for vprintf, if needed (like for old BSD).
  93.  * 
  94.  * Revision 1.18  92/02/12  14:33:26  morris
  95.  * made string_downcase not die when passed NULL
  96.  * 
  97.  * Revision 1.17  92/02/12  13:16:21  jonathan
  98.  * Added $Log so RCS will put the log message in the header
  99.  * 
  100.  *
  101. */
  102.  
  103. #ifndef lint
  104. static char *RCSid = "$Header: /usr/local/ls6/src+data/src/freeWAIS-sf/ir/RCS/cutil.c,v 1.21 1994/09/08 16:43:14 pfeifer Exp $";
  105. #endif
  106.  
  107. #define _C_C_util_
  108.  
  109. #include "cutil.h"
  110. #include "panic.h"
  111.  
  112. #include <ctype.h>
  113. /*----------------------------------------------------------------------*/
  114.  
  115. /* #define MEMORY_ACCOUNTING */
  116.  
  117. #ifdef MEMORY_ACCOUNTING
  118. #include "futil.h"
  119. #undef s_checkPtr
  120. #define s_checkPtr(ptr) fs_checkPtr(ptr)
  121. static FILE* memRecord = NULL;
  122. static void prepMemAcct _AP((void));
  123. static void 
  124. prepMemAcct()
  125. {
  126.   if (memRecord == NULL)
  127.     memRecord = s_fopen("MemoryAccounting","w");
  128. }
  129. static void flushMemAcct _AP((void));
  130. static void 
  131. flushMemAcct()
  132. {
  133.   fflush(memRecord);
  134. }
  135. #define tickles 0
  136. static char*     badPtr    = (char*)-1;
  137. static size_t    badSize    = -1;
  138. #endif /* def MEMORY_ACCOUNTING */
  139.  
  140. /*----------------------------------------------------------------------*/
  141.  
  142. void
  143. fs_checkPtr(ptr)
  144. void* ptr;
  145. /* If the ptr is NULL, give an error */
  146. #ifdef MEMORY_ACCOUNTING
  147. static char** ptrs = NULL;
  148. long i;
  149. static Boolean  doneSetup = false;
  150. if (doneSetup == false)
  151. {
  152. #ifdef THINK_C
  153. Debugger();
  154. #endif /* def THINK_C */
  155. doneSetup = true;
  156. }
  157. #endif /* def MEMORY_ACCOUNTING */
  158.  
  159.   if (ptr == NULL)
  160.     panic("checkPtr found a NULL pointer");
  161.  
  162. #ifdef MEMORY_ACCOUNTING
  163. /* look for specific ptr (useful when tracking un-freed memory) */
  164. if (ptr == badPtr) warn("checking found bad ptr"); 
  165. /* tickle a memory bug */
  166. if (ptrs == NULL && tickles > 0)
  167.   ptrs = (char**)malloc((size_t)tickles * sizeof(char*));
  168. for (i = 0; i < tickles; i++)
  169. { ptrs[i] = malloc((size_t)5);
  170. }
  171. for (i = 0; i < tickles; i++)
  172. { free(ptrs[i]);
  173. }
  174. #endif /* def MEMORY_ACCOUNTING */
  175.  
  176. }
  177.  
  178. /*----------------------------------------------------------------------*/
  179.  
  180. void*
  181. fs_malloc(size)
  182. size_t size;
  183. /* does safety checks and optional accounting */
  184.   register void* ptr = NULL;
  185.  
  186.   if(!size) return(NULL);
  187.  
  188. #ifdef THINK_C
  189.   ptr = (void*)NewPtr((long)size);
  190.   s_checkPtr(ptr);
  191.   memset(ptr,0,(size_t)size);    /* zero it */
  192. #else  
  193.   ptr = NULL;
  194.   ptr = (void*)calloc((size_t)size,(size_t)1);
  195.   s_checkPtr(ptr);
  196. #endif
  197.   
  198. #ifdef MEMORY_ACCOUNTING
  199.   /* look for specific size (useful when tracking un-freed memory) */
  200.   if (size == badSize)
  201.     warn("bad size in malloc");
  202.   
  203.   prepMemAcct();
  204.   fprintf(memRecord,"malloced %lu bytes at %lu\n",size,ptr);
  205.   flushMemAcct();
  206. #endif
  207.  
  208.   return(ptr);
  209. }
  210.  
  211. /*----------------------------------------------------------------------*/
  212.  
  213. void*
  214. fs_realloc(ptr,size)
  215. void* ptr;
  216. size_t size;
  217. /* does safety checks and optional accounting 
  218.    note - we don't know how big ptr's memory is, so we can't ensure
  219.    that any new memory allocated is NULLed!
  220.  */
  221.   register void* nptr = NULL;
  222.   
  223.   if (ptr == NULL) {        /* this is really a malloc */
  224.     nptr = s_malloc(size);      /* Initialize (up) */
  225.     if (nptr != NULL) bzero(nptr,size);
  226.     return(nptr);
  227.   }
  228. #ifdef THINK_C
  229.   nptr = NewPtr(size);        /* need to make a copy */ 
  230.   s_checkPtr(nptr);
  231.   BlockMove(ptr,nptr,size);    /* move the old contents into it */
  232.   DisposPtr(ptr);            /* get rid of the old ones */
  233. #else
  234.   nptr = (void*)realloc(ptr,size);
  235.   s_checkPtr(ptr);
  236. #endif  
  237.    
  238. #ifdef MEMORY_ACCOUNTING
  239.   /* look for specific size (useful when tracking un-freed memory) */
  240.   if (size == badSize) 
  241.     warn("bad size in realloc");
  242.   
  243.   prepMemAcct();
  244.   fprintf(memRecord,"realloced %lu bytes at %lu from %lu\n",size,nptr,ptr);
  245.   flushMemAcct();
  246. #endif
  247.  
  248.   return(nptr);
  249. }
  250.  
  251. /*----------------------------------------------------------------------*/
  252.  
  253. void
  254. fs_free(ptr)
  255. void* ptr;
  256. /* does safety checks and optional accounting */
  257. {
  258. #ifdef MEMORY_ACCOUNTING
  259.   prepMemAcct();
  260.   /* note that the sizeof a pointer is always 4.  If only we could find out
  261.      how much space that pointer was pointing to.  Oh well, this is a place
  262.      holder for now
  263.    */
  264.   fprintf(memRecord,"freed %lu bytes at %lu\n",(size_t)sizeof(ptr),ptr);
  265.   flushMemAcct();
  266.  
  267.   /* look for specific ptr (useful when tracking un-freed memory) */
  268.   if (ptr == badPtr) warn("bad ptr in free");
  269. #endif
  270.  
  271.   if (ptr != NULL)        /* some non-ansi compilers/os's cant handle freeing null */
  272.     {                /* if we knew the size of this block of memory, we could clear it - oh well */
  273. #ifdef THINK_C
  274.       DisposPtr(ptr);
  275. #else
  276.       free(ptr);
  277. #endif
  278.     }
  279. }
  280.  
  281. /*----------------------------------------------------------------------*/
  282.  
  283. char*
  284. s_strdup(s)
  285. char* s;
  286.  
  287. /* return a copy of s.  This is identical to the standard library routine
  288.    strdup(), except that it is safe.  If s == NULL or malloc fails, 
  289.    appropriate action is taken.
  290.  */
  291. {
  292.   unsigned long len;
  293.   char* copy = NULL;
  294.   
  295.   if (s == NULL)        /* saftey check to postpone stupid errors */
  296.     return(NULL);
  297.     
  298.   len = strlen(s);        /* length of string - terminator */
  299.   copy = (char*)s_malloc((size_t)(sizeof(char)*(len + 1)));
  300.   strncpy(copy,s,len + 1);
  301.   return(copy);
  302. }
  303.  
  304. /*----------------------------------------------------------------------*/
  305.  
  306. char*
  307. fs_strncat(dst,src,maxToAdd,maxTotal)
  308. char* dst;
  309.    char* src;
  310.    size_t maxToAdd;
  311.    size_t maxTotal;
  312.  
  313. /* like strncat, except the fourth argument limits the maximum total 
  314.    length of the resulting string
  315.  */
  316. {
  317.   size_t dstSize = strlen(dst);
  318.   size_t srcSize = strlen(src);
  319.   
  320.   if (dstSize + srcSize < maxTotal) /* use regular old strncat */
  321.     return(strncat(dst,src,maxToAdd));
  322.   else
  323.     { size_t truncateTo = maxTotal - dstSize - 1;
  324.       char   saveChar;
  325.       char*  result = NULL;
  326.  
  327.       saveChar = src[truncateTo];
  328.       src[truncateTo] = '\0';
  329.       result = strncat(dst,src,maxToAdd);
  330.       src[truncateTo] = saveChar;
  331.       return(result);
  332.     }
  333. }
  334.  
  335. /*----------------------------------------------------------------------*/
  336.  
  337. char*
  338. fs_strncpy(s1, s2, n)
  339.      char* s1;
  340.      char* s2;
  341.      long n;
  342. /* like strncpy except that it guarentees that the destination string ends with a NULL at position n.
  343.  */
  344. {
  345.   s1[n-1] = '\0';
  346.   return(strncpy(s1, s2, n - 1));
  347. }
  348.  
  349. /*----------------------------------------------------------------------*/
  350.  
  351. boolean 
  352. wordbreak_notalnum(ch)        /* dgg */
  353. long   ch;
  354. {   
  355.     return( !isalnum(ch));
  356. }
  357.  
  358. boolean 
  359. wordbreak_notgraph(ch)        /* dgg */
  360. long   ch;
  361. {   
  362.     return( !isgraph(ch));
  363. }
  364.  
  365. boolean wordbreak_user(c)
  366. long c;
  367. {
  368.   if ( (gDelimiters[0] != '\0') && (strchr(gDelimiters, (char) c) != NULL) )
  369.     return(IS_DELIMITER);  
  370.   else if (isgraph(c))
  371.     return(NOT_DELIMITER);
  372.   else
  373.     return(IS_DELIMITER);
  374. }
  375.  
  376. typedef boolean (boolfunc) _AP((long c));
  377.  
  378. char*
  379. strtokf(s1,isDelimiter)
  380. char* s1;
  381. boolfunc *isDelimiter; /* really *isDelimiter() */
  382.  
  383. /* This function is exactly like strtok, except that instead of passing a 
  384.    delimiter string, you pass a function that decides if a character is 
  385.    a delimiter or not, returning IS_DELIMITER or NOT_DELIMITER respecively.
  386.    Note that passing a NULL delimiter function will cause the last delimiter
  387.    to be used.
  388.  */
  389. {
  390.   static char* searchStr = NULL;
  391.   static boolfunc *delimiterFunc;
  392.   long i;
  393.   char* startTok = NULL;
  394.  
  395.   if (s1 != NULL)        /* passing s1 = NULL says use the last pos */
  396.     searchStr = s1;
  397.     
  398.   if (isDelimiter != NULL)
  399.     delimiterFunc = isDelimiter;
  400.    
  401.   if (searchStr == NULL || searchStr[0] == '\0')
  402.     return(NULL);        /* nothing left to search */
  403.     
  404.   if (delimiterFunc == NULL)
  405.     return(NULL);        /* no delimiter to search with */
  406.     
  407.   /* find the start of the next token */
  408.   for (i = 0; searchStr[i] != '\0'; i++)
  409.     { if ((*delimiterFunc)((long)searchStr[i]) == NOT_DELIMITER)
  410.     break;
  411.     }
  412.   
  413.   if (searchStr[i] == '\0') 
  414.     return(NULL);        /* read to end of search string */
  415.   else
  416.     startTok = searchStr + i;    /* remember the starting point for this token*/
  417.     
  418.   /* find the end of the next token */
  419.   for (; searchStr[i] != '\0'; i++)
  420.     { if ((*delimiterFunc)((long)searchStr[i]) == IS_DELIMITER)
  421.     break;
  422.     }
  423.    
  424.   /* if the end is a delimiter (and not just the end of the search string)
  425.      replace it with '\0', and put searchStr just beyond it, otherwise
  426.      put searchStr at the terminator. */
  427.   if (searchStr[i] != '\0')
  428.     { searchStr[i] = '\0';
  429.       searchStr = searchStr + i + 1;
  430.     }
  431.   else
  432.     searchStr = searchStr + i;
  433.    
  434.   return(startTok);
  435. }
  436.  
  437. /*----------------------------------------------------------------------*/
  438.  
  439. char*
  440. strtokf_isalnum(s1)
  441. char* s1;
  442.  
  443. /* 
  444.   This is a partially evaluated version of strtok_f
  445.  */
  446. {
  447.   static char* searchStr = NULL;
  448.   long i;
  449.   char* startTok = NULL;
  450.  
  451.   if (s1 != NULL)        /* passing s1 = NULL says use the last pos */
  452.     searchStr = s1;
  453.     
  454.    
  455.   if (searchStr == NULL || searchStr[0] == '\0')
  456.     return(NULL);        /* nothing left to search */
  457.     
  458.     
  459.   /* find the start of the next token */
  460.   for (i = 0; searchStr[i] != '\0'; i++)
  461.     { if (isalnum(searchStr[i]))
  462.     break;
  463.     }
  464.   
  465.   if (searchStr[i] == '\0') 
  466.     return(NULL);        /* read to end of search string */
  467.   else
  468.     startTok = searchStr + i;    /* remember the starting point for this token*/
  469.     
  470.   /* find the end of the next token */
  471.   for (; searchStr[i] != '\0'; i++)
  472.     { if (!isalnum(searchStr[i]))
  473.     break;
  474.     }
  475.    
  476.   /* if the end is a delimiter (and not just the end of the search string)
  477.      replace it with '\0', and put searchStr just beyond it, otherwise
  478.      put searchStr at the terminator. */
  479.   if (searchStr[i] != '\0')
  480.     { searchStr[i] = '\0';
  481.       searchStr = searchStr + i + 1;
  482.     }
  483.   else
  484.     searchStr = searchStr + i;
  485.    
  486.   return(startTok);
  487. }
  488.  
  489. /*----------------------------------------------------------------------*/
  490.  
  491. #ifdef ANSI_LIKE /* use ansi varargs */
  492.  
  493. long
  494. cprintf(boolean print, char* format, ...)
  495. /* just like printf, but only prints if the first argument = 1 */
  496. {
  497.   va_list ap;            /* the variable arguments */
  498.   if (print == 1)
  499.     { long res;
  500.       va_start(ap,format);    /* init ap */
  501.       res = vprintf(format,ap);    /* print the contents */
  502.       va_end(ap);        /* free ap */
  503.       return(res);
  504.     }
  505.   else
  506.     return(0);
  507. }
  508.  
  509. #else /* use k&r varargs */
  510.  
  511. long
  512. cprintf(va_alist)
  513. va_dcl
  514. /* just like printf, but only prints if the first argument = 1 */
  515. {
  516.   va_list ap;            /* the variable arguments */
  517.   boolean print;
  518.   long res;
  519.  
  520.   va_start(ap);            /* init ap */
  521.  
  522.   print = va_arg(ap,boolean);    /* get the condition */
  523.  
  524.   if (print == 1)
  525.     { char* format = va_arg(ap,char*); /* get the format */
  526.       res = vprintf(format,ap);    /* print the contents */
  527.     }
  528.   else
  529.     res = 0;
  530.  
  531.   va_end(ap);            /* free ap */
  532.  
  533.   return(res);
  534. }
  535.  
  536.   
  537. #endif
  538.  
  539. /* 
  540.    Define them here! Goes to libwais.a. So will be included in all
  541.    programs using wais.
  542. */
  543.  
  544. char* wais_log_file_name = NULL;
  545. FILE* waislogfile = NULL;
  546.  
  547. /* waislog - a new and improved logging facility.
  548.    first two arguments are important, the rest is text.
  549.  
  550.    arg1: priority.  If priority > log_level (some global), output this
  551.    message
  552.  
  553.    arg2: message code.  This is the kind of message (search, retrieval, etc). */
  554.  
  555. char *syslog_name = 0;
  556.   
  557. void
  558. #ifdef ANSI_LIKE
  559. waislog(long priority, long message, char *format, ...)
  560. #else
  561. waislog(va_alist)
  562. va_dcl
  563. #endif
  564.   {
  565.   va_list ap;
  566. #ifndef ANSI_LIKE
  567.   int priority, message;
  568.   char *format;
  569.   
  570.   va_start(ap);
  571.   priority = va_arg(ap, int);
  572.   message = va_arg(ap, int);
  573.   format = va_arg(ap, char *);
  574.   vwaislog(priority, message, format, ap);
  575.   va_end(ap);
  576. #else
  577.   va_start(ap, format);
  578.   vwaislog(priority, message, format, ap);
  579.   va_end(ap);
  580. #endif
  581.   }
  582.   
  583.   void
  584. #ifdef ANSI_LIKE /* use ansi varargs */
  585. vwaislog(long priority, long message, char* format, va_list ap)
  586. #else
  587. vwaislog(priority, message, format, ap)
  588. long priority, message;
  589. char *format;    
  590. va_list ap;
  591. #endif /* ANSI_LIKE */
  592.   /* just like printf, but prints to the waislogfile, with PID and time. */
  593.   {
  594.   static boolean in_vwaislog; /* to avoid reentrancy problems if */
  595.                   /* s_malloc fails and calls panic() */
  596.   
  597. #ifdef USE_SYSLOG
  598.   static boolean opened = 0;
  599. #endif
  600.   
  601.   in_vwaislog++;
  602.   
  603. #ifdef USE_SYSLOG
  604.   if (syslog_name && !opened) {
  605.     openlog(syslog_name, LOG_PID, LOG_WAIS);
  606.     opened = 1;
  607.   }
  608. #endif
  609.   
  610.   if(priority <= wais_log_level) {
  611.   
  612. #ifdef USE_SYSLOG
  613.     if (! opened) {
  614. #endif
  615.       if(waislogfile == NULL && wais_log_file_name != NULL)
  616.     waislogfile = fopen(wais_log_file_name, "a");
  617.   
  618.       if(waislogfile) {
  619.   
  620.     fprintf(waislogfile, "%d: %d: %s: %d: ", wais_pid, log_line++,
  621.         printable_time(), message);
  622.   
  623.     vfprintf(waislogfile, format,ap); /* print the contents */
  624.     fprintf(waislogfile, "\n");
  625.     fflush(waislogfile);
  626.       }
  627.  
  628.       if(waislogfile != NULL && waislogfile != stderr) {
  629.     fclose(waislogfile);
  630.     waislogfile = NULL;
  631.       }
  632. #ifdef USE_SYSLOG
  633.     }
  634.     else {
  635.       int log_priority;
  636.       char log_buf[512];
  637.       static int buffer_size;
  638.       static char *buffer;
  639.       char *use_buffer;
  640.       int format_size = strlen(format);
  641.  
  642.       /*
  643.        * All of this grungy code is to allow us to use s_malloc or
  644.        * s_realloc to allocate enough space for the message buffers,
  645.        * while at the same time not getting into an infinite loop if
  646.        * s_malloc or s_realloc fails and calls panic.
  647.        */
  648.   
  649.       if ((in_vwaislog > 1) || (format_size <= sizeof(log_buf) - 20)) {
  650.     use_buffer = log_buf;
  651.       }
  652.       else {
  653.     if (format_size + 20 > buffer_size) {
  654.       buffer_size = format_size + 20;
  655.       if (! buffer) {
  656.         buffer = s_malloc(buffer_size);
  657.       }
  658.       else {
  659.         buffer = s_realloc(buffer, buffer_size);
  660.       }
  661.     }
  662.     use_buffer = buffer;
  663.       }
  664.  
  665.       if (message < 0) {
  666.        /* Error message or warning */
  667.        if (priority >= 9) {
  668.         log_priority = LOG_NOTICE;
  669.        }
  670.        else if (priority >= 5) {
  671.         log_priority = LOG_WARNING;
  672.        }
  673.        else {
  674.         priority = LOG_ERR;
  675.        }
  676.       }
  677.       else {
  678.        switch (priority) {
  679.        case 1:
  680.        case 2:
  681.        case 3:
  682.         log_priority = LOG_NOTICE;
  683.         break;
  684.        case 4:
  685.        case 5:
  686.        case 6:
  687.         log_priority = LOG_INFO;
  688.         break;
  689.        default:
  690.         log_priority = LOG_DEBUG;
  691.         break;
  692.        }
  693.       }
  694.       
  695.       sprintf(use_buffer, "%d: %s", message, format);
  696.       vsyslog(log_priority, use_buffer, ap);
  697.       }
  698. #endif /* USE_SYSLOG */
  699.     }
  700.   
  701.   in_vwaislog--;
  702. }
  703.     
  704.   /*----------------------------------------------------------------------*/
  705.  
  706. void
  707. warn(message)
  708. char* message;
  709.  
  710. {
  711. #ifdef THINK_C
  712.   Debugger();
  713. #else
  714.   printf("%s\n<press return to continue>\n",message);
  715.   getchar();
  716. #endif
  717. }
  718.  
  719. /*----------------------------------------------------------------------*/
  720. boolean substrcmp(string1,string2)
  721. unsigned char *string1, *string2;
  722. {
  723.   /* compares the strings up until one of then ends.
  724.    * returns true if they are the same, false if not.
  725.    */
  726.   register unsigned char *a, *b;
  727.   
  728.   a = string1;
  729.   b = string2;
  730.   
  731.   while (*a && *b) 
  732.     if(*a++ != *b++) 
  733.       return false;
  734.   return true;
  735. }
  736.  
  737. /*----------------------------------------------------------------------*/
  738.  
  739. char *printable_time()
  740.   static char *string;
  741.   time_t tptr;
  742.   time(&tptr);
  743.   string = ctime(&tptr);
  744.   if(string){
  745.     if(string[strlen(string)-1] == '\n')
  746.       string[strlen(string)-1] = '\0';   
  747.     return(string+4);
  748.   }
  749.   else
  750.     return("Time Unknown");
  751. }
  752.  
  753. /*----------------------------------------------------------------------*/
  754.  
  755. char char_downcase(long_ch)
  756. unsigned long long_ch;
  757. {
  758.   unsigned char ch = long_ch & 0xFF; /* just want one byte */
  759.   /* when ansi is the way of the world, this can be tolower */
  760. #ifdef ISO
  761.   return(tolower(ch));
  762. #else
  763.   return (((ch >= 'A') && (ch <= 'Z')) ? (ch + 'a' -'A') : ch);
  764. #endif
  765. }
  766.  
  767. char *string_downcase(word)
  768. char *word;
  769. {
  770.   long i = 0;
  771.  
  772.   if (word == NULL)
  773.     return(NULL);
  774.  
  775.   while(word[i] != '\0')
  776.    { word[i] = char_downcase((unsigned long)word[i]);
  777.      i++;
  778.    }
  779.  
  780.   return(word);
  781. }
  782.  
  783. /*----------------------------------------------------------------------*/
  784.  
  785.  
  786. /* parsing arguments functions */
  787.  
  788. char *next_arg(argc,argv)
  789. int *argc;
  790. char ***argv;
  791.  
  792.      /* Returns NULL when it is out of arguments,
  793.         This side effects both argc and argv.  argc always contains the number
  794.     of arguments left.
  795.     The first returned is the command name. 
  796.     */
  797. {
  798.   if((*argc)-- > 0)
  799.     return(*((*argv)++));
  800.   else
  801.     return(NULL);
  802. }
  803.  
  804. #ifdef FIELDS /* tung, 5/94 */
  805. char *field_next_arg(argc, number_of_files, argv)
  806. int *argc;
  807. int *number_of_files;
  808. char ***argv;
  809.  
  810.      /* Returns NULL when it is out of arguments,
  811.         This side effects both argc and argv.  argc always contains the number
  812.     of arguments left.
  813.     The first returned is the command name. 
  814.     */
  815. {
  816.   if((*argc)-- > 0) {
  817.     ++(*number_of_files);
  818.     return(*((*argv) + (*number_of_files - 1)));
  819.   }
  820.   else
  821.     return(NULL);
  822. }
  823.  
  824. #endif
  825. /*----------------------------------------------------------------------*/
  826.  
  827. char *peek_arg(argc,argv)
  828. int *argc;
  829.     char ***argv;
  830.  
  831.      /* Returns the next argument without popping it.
  832.        Returns NULL when it is out of arguments.
  833.        */
  834. {
  835.   if((*argc) > 0)
  836.     return(**argv);
  837.   else
  838.     return(NULL);
  839. }
  840.  
  841. /*----------------------------------------------------------------------*/
  842.  
  843.  
  844. #ifdef THINK_C
  845. #include <EventMgr.h>
  846. #undef MAX_FILE_NAME_LEN 
  847. #ifdef WAIStation
  848. #include "CRetrievalApp.h"
  849. #endif /* def WAIStation */
  850. #endif /* def THINK_C */
  851.  
  852. void
  853. beFriendly()
  854. /* this routine is called during time intensive operations
  855.    on single processing machines (macs and DOS).  It gives
  856.    time to other processes
  857.  */
  858. #ifdef never
  859. #ifdef THINK_C
  860.    EventRecord      macEvent;    /* an event */
  861.  
  862.    static RgnHandle    mouseRgn = NULL; /* region for mouse moved events */
  863.    long                sleepTime;     /* max time between events */
  864.    
  865. #ifdef WAIStation
  866.    gApplication->FrobWaitCursor();
  867. #endif /* def WAIStation */
  868.    
  869.    if (mouseRgn == NULL)
  870.      mouseRgn = NewRgn(); /* do we need to set its value? */
  871.      
  872.    sleepTime = 5; /* arbitrary - a tech note recommends < 50 */
  873.    
  874.    WaitNextEvent(everyEvent,&macEvent,sleepTime,mouseRgn); 
  875. #endif /* def THINK_C */
  876. #endif
  877. }
  878.  
  879.  
  880. #if defined(BSD) || defined(BSD43)
  881. #define NEED_VPRINTF
  882. #endif
  883.  
  884. #ifdef NEED_VPRINTF
  885. /* Portable vsprintf  by Robert A. Larson <blarson@skat.usc.edu> */
  886.  
  887. /* Copyright 1989 Robert A. Larson.
  888.  * Distribution in any form is allowed as long as the author
  889.  * retains credit, changes are noted by their author and the
  890.  * copyright message remains intact.  This program comes as-is
  891.  * with no warentee of fitness for any purpouse.
  892.  *
  893.  * Thanks to Doug Gwen, Chris Torek, and others who helped clarify
  894.  * the ansi printf specs.
  895.  *
  896.  * Please send any bug fixes and improvments to blarson@skat.usc.edu .
  897.  * The use of goto is NOT a bug.
  898.  */
  899.  
  900. /* Feb    7, 1989        blarson        First usenet release */
  901.  
  902. /* This code implements the vsprintf function, without relying on
  903.  * the existance of _doprint or other system specific code.
  904.  *
  905.  * Define NOVOID if void * is not a supported type.
  906.  *
  907.  * Two compile options are available for efficency:
  908.  *    INTSPRINTF    should be defined if sprintf is int and returns
  909.  *            the number of chacters formated.
  910.  *    LONGINT        should be defined if sizeof(long) == sizeof(int)
  911.  *
  912.  *    They only make the code smaller and faster, they need not be
  913.  *    defined.
  914.  *
  915.  * UNSIGNEDSPECIAL should be defined if unsigned is treated differently
  916.  * than int in argument passing.  If this is definded, and LONGINT is not,
  917.  * the compiler must support the type unsingned long.
  918.  *
  919.  * Most quirks and bugs of the available sprintf fuction are duplicated,
  920.  * however * in the width and precision fields will work correctly
  921.  * even if sprintf does not support this, as will the n format.
  922.  *
  923.  * Bad format strings, or those with very long width and precision
  924.  * fields (including expanded * fields) will cause undesired results.
  925.  */
  926.  
  927. #ifdef OSK        /* os9/68k can take advantage of both */
  928. #define LONGINT
  929. #define INTSPRINTF
  930. #endif
  931.  
  932. /* This must be a typedef not a #define! */
  933. #ifdef NOVOID
  934. typedef char *pointer;
  935. #else
  936. typedef void *pointer;
  937. #endif
  938.  
  939. #ifdef    INTSPRINTF
  940. #define Sprintf(string,format,arg)    (sprintf((string),(format),(arg)))
  941. #else
  942. #define Sprintf(string,format,arg)    (\
  943.     sprintf((string),(format),(arg)),\
  944.     strlen(string)\
  945. )
  946. #endif
  947.  
  948. typedef int *intp;
  949.  
  950. int vsprintf(dest, format, args)
  951. char *dest;
  952. register char *format;
  953. va_list args;
  954. {
  955.     register char *dp = dest;
  956.     register char c;
  957.     register char *tp;
  958.     char tempfmt[64];
  959. #ifndef LONGINT
  960.     int longflag;
  961. #endif
  962.  
  963.     tempfmt[0] = '%';
  964.     while( (c = *format++) != 0) {
  965.     if(c=='%') {
  966.         tp = &tempfmt[1];
  967. #ifndef LONGINT
  968.         longflag = 0;
  969. #endif
  970. continue_format:
  971.         switch(c = *format++) {
  972.         case 's':
  973.             *tp++ = c;
  974.             *tp = '\0';
  975.             dp += Sprintf(dp, tempfmt, va_arg(args, char *));
  976.             break;
  977.         case 'u':
  978.         case 'x':
  979.         case 'o':
  980.         case 'X':
  981. #ifdef UNSIGNEDSPECIAL
  982.             *tp++ = c;
  983.             *tp = '\0';
  984. #ifndef LONGINT
  985.             if(longflag)
  986.             dp += Sprintf(dp, tempfmt, va_arg(args, unsigned long));
  987.             else
  988. #endif
  989.             dp += Sprintf(dp, tempfmt, va_arg(args, unsigned));
  990.             break;
  991. #endif
  992.         case 'd':
  993.         case 'c':
  994.         case 'i':
  995.             *tp++ = c;
  996.             *tp = '\0';
  997. #ifndef LONGINT
  998.             if(longflag)
  999.             dp += Sprintf(dp, tempfmt, va_arg(args, long));
  1000.             else
  1001. #endif
  1002.             dp += Sprintf(dp, tempfmt, va_arg(args, int));
  1003.             break;
  1004.         case 'f':
  1005.         case 'e':
  1006.         case 'E':
  1007.         case 'g':
  1008.         case 'G':
  1009.             *tp++ = c;
  1010.             *tp = '\0';
  1011.             dp += Sprintf(dp, tempfmt, va_arg(args, double));
  1012.             break;
  1013.         case 'p':
  1014.             *tp++ = c;
  1015.             *tp = '\0';
  1016.             dp += Sprintf(dp, tempfmt, va_arg(args, pointer));
  1017.             break;
  1018.         case '-':
  1019.         case '+':
  1020.         case '0':
  1021.         case '1':
  1022.         case '2':
  1023.         case '3':
  1024.         case '4':
  1025.         case '5':
  1026.         case '6':
  1027.         case '7':
  1028.         case '8':
  1029.         case '9':
  1030.         case '.':
  1031.         case ' ':
  1032.         case '#':
  1033.         case 'h':
  1034.             *tp++ = c;
  1035.             goto continue_format;
  1036.         case 'l':
  1037. #ifndef LONGINT
  1038.             longflag = 1;
  1039.             *tp++ = c;
  1040. #endif
  1041.             goto continue_format;
  1042.         case '*':
  1043.             tp += Sprintf(tp, "%d", va_arg(args, int));
  1044.             goto continue_format;
  1045.         case 'n':
  1046.             *va_arg(args, intp) = dp - dest;
  1047.             break;
  1048.         case '%':
  1049.         default:
  1050.             *dp++ = c;
  1051.             break;
  1052.         }
  1053.     } else *dp++ = c;
  1054.     }
  1055.     *dp = '\0';
  1056.     return dp - dest;
  1057. }
  1058.  
  1059.  
  1060. int vfprintf(dest, format, args)
  1061. FILE *dest;
  1062. register char *format;
  1063. va_list args;
  1064. {
  1065.     register char c;
  1066.     register char *tp;
  1067.     register int count = 0;
  1068.     char tempfmt[64];
  1069. #ifndef LONGINT
  1070.     int longflag;
  1071. #endif
  1072.  
  1073.     tempfmt[0] = '%';
  1074.     while(c = *format++) {
  1075.     if(c=='%') {
  1076.         tp = &tempfmt[1];
  1077. #ifndef LONGINT
  1078.         longflag = 0;
  1079. #endif
  1080. continue_format:
  1081.         switch(c = *format++) {
  1082.         case 's':
  1083.             *tp++ = c;
  1084.             *tp = '\0';
  1085.             count += fprintf(dest, tempfmt, va_arg(args, char *));
  1086.             break;
  1087.         case 'u':
  1088.         case 'x':
  1089.         case 'o':
  1090.         case 'X':
  1091. #ifdef UNSIGNEDSPECIAL
  1092.             *tp++ = c;
  1093.             *tp = '\0';
  1094. #ifndef LONGINT
  1095.             if(longflag)
  1096.             count += fprintf(dest, tempfmt, va_arg(args, unsigned long));
  1097.             else
  1098. #endif
  1099.             count += fprintf(dest, tempfmt, va_arg(args, unsigned));
  1100.             break;
  1101. #endif
  1102.         case 'd':
  1103.         case 'c':
  1104.         case 'i':
  1105.             *tp++ = c;
  1106.             *tp = '\0';
  1107. #ifndef LONGINT
  1108.             if(longflag)
  1109.             count += fprintf(dest, tempfmt, va_arg(args, long));
  1110.             else
  1111. #endif
  1112.             count += fprintf(dest, tempfmt, va_arg(args, int));
  1113.             break;
  1114.         case 'f':
  1115.         case 'e':
  1116.         case 'E':
  1117.         case 'g':
  1118.         case 'G':
  1119.             *tp++ = c;
  1120.             *tp = '\0';
  1121.             count += fprintf(dest, tempfmt, va_arg(args, double));
  1122.             break;
  1123.         case 'p':
  1124.             *tp++ = c;
  1125.             *tp = '\0';
  1126.             count += fprintf(dest, tempfmt, va_arg(args, pointer));
  1127.             break;
  1128.         case '-':
  1129.         case '+':
  1130.         case '0':
  1131.         case '1':
  1132.         case '2':
  1133.         case '3':
  1134.         case '4':
  1135.         case '5':
  1136.         case '6':
  1137.         case '7':
  1138.         case '8':
  1139.         case '9':
  1140.         case '.':
  1141.         case ' ':
  1142.         case '#':
  1143.         case 'h':
  1144.             *tp++ = c;
  1145.             goto continue_format;
  1146.         case 'l':
  1147. #ifndef LONGINT
  1148.             longflag = 1;
  1149.             *tp++ = c;
  1150. #endif
  1151.             goto continue_format;
  1152.         case '*':
  1153.             tp += Sprintf(tp, "%d", va_arg(args, int));
  1154.             goto continue_format;
  1155.         case 'n':
  1156.             *va_arg(args, intp) = count;
  1157.             break;
  1158.         case '%':
  1159.         default:
  1160.             putc(c, dest);
  1161.             count++;
  1162.             break;
  1163.         }
  1164.     } else {
  1165.         putc(c, dest);
  1166.         count++;
  1167.     }
  1168.     }
  1169.     return count;
  1170. }
  1171.  
  1172. vprintf(format, args)
  1173. char *format;
  1174. va_list args;
  1175. {
  1176.     return vfprintf(stdout, format, args);
  1177. }
  1178.  
  1179. #endif
  1180.  
  1181. #ifndef HAVE_STRDUP
  1182. char* strdup(s)
  1183. char* s;
  1184.  
  1185. /* return a copy of s.  This is identical to the standard library routine
  1186.    strdup(), except that it is safe.  If s == NULL or malloc fails, 
  1187.    appropriate action is taken.
  1188.  */
  1189. {
  1190.   unsigned long len;
  1191.   char* copy = NULL;
  1192.   
  1193.   if (s == NULL)        /* saftey check to postpone stupid errors */
  1194.     return(NULL);
  1195.     
  1196.   len = strlen(s);        /* length of string - terminator */
  1197.   copy = (char*)s_malloc((size_t)(sizeof(char)*(len + 1)));
  1198.   strncpy(copy,s,len + 1);
  1199.   return(copy);
  1200. }
  1201. #endif
  1202. /*----------------------------------------------------------------------*/
  1203.  
  1204. #ifdef NEED_MYBCOPY
  1205. void
  1206. mybcopy(b1, b2, length)
  1207.      char *b1, *b2;
  1208.      int length;
  1209. {
  1210.   int i;
  1211.   if (b1 > b2) {
  1212.     for (i=0;i<length;i++) {
  1213.       b2[i] = b1[i];
  1214.     }
  1215.   } else {
  1216.     for (i=length-1;i>=0;i--) {
  1217.       b2[i] = b1[i];
  1218.     }
  1219.   }
  1220. }
  1221. #endif /* NEED_MYBCOPY */
  1222.