home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / fingercl.zip / util.c < prev    next >
C/C++ Source or Header  |  1997-08-29  |  10KB  |  465 lines

  1. /* util.c -- Simple utility functions that everyone uses. */
  2.  
  3. /* Copyright (C) 1988, 1990, 1992  Free Software Foundation, Inc.
  4.  
  5.    This file is part of GNU Finger.
  6.  
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2, or (at your option)
  10.    any later version.
  11.  
  12.    This program is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with this program; if not, write to the Free Software
  19.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>
  24. #include <config.h>
  25. #include <general.h>
  26.  
  27. /* **************************************************************** */
  28. /*                                                                  */
  29. /*                      General Utility                             */
  30. /*                                                                  */
  31. /* **************************************************************** */
  32.  
  33. /* Array processing. */
  34.  
  35. /* Return the length of the null terminated array of pointers. */
  36. int
  37. array_len (array)
  38.      char **array;
  39. {
  40.   register int i;
  41.  
  42.   for (i = 0; array[i]; i++);
  43.   return (i);
  44. }
  45.  
  46. /* Free the contents of the null terminated array, and
  47.    then the array itself. */
  48. /*
  49. int
  50. free_array (array)
  51.      char **array;
  52. {
  53.   register int i;
  54.  
  55.   for (i = 0; array[i]; i++)
  56.     free (array[i]);
  57.  
  58.   free (array);
  59. }
  60. */
  61. /* Whoops, Unix doesn't have xstrnicmp.  String functions. */
  62.  
  63. #if defined (USG) || defined (hpux)
  64. #if !defined (index)
  65. char *
  66. index (string, ch)
  67.      char *string;
  68.      int ch;
  69. {
  70.   return ((char *)strchr (string, ch));
  71. }
  72. #endif
  73.  
  74. #if !defined (rindex)
  75. char *
  76. rindex (string, ch)
  77.      char *string;
  78.      int ch;
  79. {
  80.   return ((char *)strrchr (string, ch));
  81. }
  82. #endif
  83. #endif /* USG || hpux */
  84.  
  85.  
  86. /* Compare at most COUNT characters from string1 to string2.  Case
  87.    doesn't matter. */
  88. int
  89. xstrnicmp (string1, string2, count)
  90.   char *string1, *string2;
  91. {
  92.   register char ch1, ch2;
  93.  
  94.   while (count)
  95.     {
  96.       ch1 = *string1++;
  97.       ch2 = *string2++;
  98.  
  99.       if (to_upper(ch1) == to_upper(ch2))
  100.         count--;
  101.       else
  102.         break;
  103.     }
  104.   return (count);
  105. }
  106.  
  107.  
  108. /* xstrcmp (), but caseless. */
  109. int
  110. xstricmp (string1, string2)
  111.   char *string1, *string2;
  112. {
  113.   char ch1, ch2;
  114.  
  115.   while (*string1 && *string2)
  116.     {
  117.       ch1 = *string1++;
  118.       ch2 = *string2++;
  119.       if (to_upper(ch1) != to_upper(ch2))
  120.         return (1);
  121.     }
  122.   return (*string1 | *string2);
  123. }
  124.  
  125. /* Determine if s2 occurs in s1.  If so, return a pointer to the
  126.    match in s1.  The compare is case insensitive. */
  127. char *
  128. strindex (s1, s2)
  129.   register char *s1, *s2;
  130. {
  131.   register int i, l = strlen (s2);
  132.   register int len = strlen (s1);
  133.  
  134.   for (i = 0; (len - i) >= l; i++)
  135.     if (xstrnicmp (&s1[i], s2, l) == 0)
  136.       return (s1 + i);
  137.   return ((char *)NULL);
  138. }
  139.  
  140.  
  141. /* Match pattern string P against string S.
  142.    The special pattern characters are:
  143.  
  144.    " "    Matches both "." and " "
  145.  
  146.    Returns 1 on match, 0 if no match. */
  147.  
  148. #ifdef __GCC__
  149. inline
  150. #endif
  151.  
  152. static int
  153. matches_p (p, s)
  154.   char *p, *s;
  155. {
  156.   char ch1, ch2;
  157.  
  158.   while (*p && *s)
  159.     {
  160.       ch1 = *p++;
  161.       ch2 = *s++;
  162.  
  163.       if (ch1 == '.' && ch2 == ' ')
  164.         continue;
  165.  
  166.       if (to_upper(ch1) != to_upper(ch2))
  167.         return 0;
  168.     }
  169.  
  170.   /* Successful if end of pattern */
  171.   return !*p;
  172. }
  173.  
  174.  
  175. /* Determine if PATTERN matches USERNAME.  If so, return 1.  The
  176.    compare is case insensitive. */
  177. int
  178. matches_username (pattern, username)
  179.   char *pattern, *username;
  180. {
  181.   int i, patternlen = strlen (pattern);
  182.   int userlen = strlen (username);
  183.  
  184.   for (i = 0;  i <= userlen - patternlen; i++)
  185.     if (matches_p (pattern, username + i))
  186.       return 1;
  187.  
  188.   return 0;
  189. }
  190.  
  191.  
  192. /* Return a new string which is the concatenation of PATH and FILE. */
  193. char *
  194. path_concat (path, file)
  195.   char *path, *file;
  196. {
  197.   char *output = (char *) xmalloc (2 + strlen (path) + strlen (file));
  198.   register int i;
  199.  
  200.   strcpy (output, path);
  201.  
  202.   for (i = strlen (output) - 1; i > -1; i--)
  203.     if (output[i] != ' ')
  204.       break;
  205.  
  206.   output[i + 1] = '\0';
  207.  
  208.   if (output[0] && (output[strlen (output) - 1] != '/'))
  209.     strcat (output, "/");
  210.   strcat (output, file);
  211.   return (output);
  212. }
  213.  
  214. /* **************************************************************** */
  215. /*                                                                  */
  216. /*                      Generate Idle Time                          */
  217. /*                                                                  */
  218. /* **************************************************************** */
  219.  
  220. /* Number of seconds that, below which, the terminal is not idle. */
  221. long idle_time_threshold = 60;
  222.  
  223. /* Macro for appending possibly pluralized strings to time_buffer. */
  224. #define ADD_TIME(str,var)\
  225. {\
  226.   sprintf (time_buffer + strlen (time_buffer), str, var);\
  227.   if (var > 1) strcat (time_buffer, "s");\
  228.   strcat (time_buffer, ", ");\
  229. }
  230.  
  231. /* Return a static string which is the English representation of the
  232.    amount of idle time present in ITIME.  Note that ITIME is a long. */
  233. char *
  234. idle_time_string (itime)
  235.      long itime;
  236. {
  237.   int seconds, minutes, hours, days, weeks, months, years;
  238.   char time_buffer[128];
  239.  
  240.   time_buffer[0] = '\0';
  241.  
  242.   if (itime < idle_time_threshold)
  243.     return (NULL);
  244.  
  245.   hours = days = weeks = months = years = 0;
  246.  
  247.   seconds = itime % 60;
  248.   minutes = itime / 60;
  249.  
  250.   if (minutes >= 60)    { hours = minutes / 60; minutes %= 60; }
  251.   if (hours >= 24)      { days = hours / 24; hours %= 24; }
  252.   if (days  >= 7)       { weeks = days / 7; days %= 7; }
  253.   if (weeks >= 4)       { months = weeks / 4; weeks %= 4; }
  254.   if (months >= 12)     { years = months / 12; months %= 12; }
  255.  
  256.   {
  257.     if (years)  ADD_TIME ("%d year", years);
  258.     if (months) ADD_TIME ("%d month", months);
  259.     if (weeks)  ADD_TIME ("%d week", weeks);
  260.     if (days)   ADD_TIME ("%d day", days);
  261.   }
  262.  
  263.   sprintf (time_buffer + strlen (time_buffer), "%2d:%02d:%02d",
  264.            hours, minutes, seconds);
  265.  
  266.   return ((char *)strcpy
  267.           ((char *)xmalloc (1 + strlen (time_buffer)), time_buffer));
  268. }
  269.  
  270. static void
  271. memory_error_and_abort (what, nbytes)
  272.   char *what;
  273.   int nbytes;
  274. {
  275.   fprintf (stderr, "Fatal error: can't %s %d bytes.\n", what, nbytes);
  276.   abort ();
  277. }
  278.  
  279. void *
  280. xmalloc (nbytes)
  281.   int nbytes;
  282. {
  283.   char *temp = (char *)malloc (nbytes);
  284.  
  285.   if (!temp)
  286.     memory_error_and_abort ("alloc", nbytes);
  287.  
  288. #if 0
  289.   fprintf (stderr, "%lx: malloc\n", temp); /* DEBUG */
  290. #endif
  291.  
  292.   return ((void *)temp);
  293. }
  294.  
  295.  
  296. void *
  297. xrealloc (pointer, nbytes)
  298.      void *pointer;
  299.      int nbytes;
  300. {
  301.   char *temp;
  302.  
  303.   if (!pointer)
  304.     temp = (char *)xmalloc (nbytes);
  305.   else
  306.     temp = (char *)realloc (pointer, nbytes);
  307.  
  308.   if (!temp)
  309.     memory_error_and_abort (pointer ? "realloc" : "alloc", nbytes);
  310.  
  311.   return ((void *)temp);
  312. }
  313.  
  314. #include <pwd.h>
  315. /* Return the real person name of ENTRY. Make & stand for login name.
  316.    Returns pointer to static buffer. */
  317. char *
  318. pw_real_name (entry)
  319.   struct passwd *entry;
  320. {
  321.   static char *real_name_buffer = NULL;
  322.   char *t, *s, separator_char;
  323.   int nchars_expanded;
  324.  
  325.   t = entry->pw_gecos;
  326.  
  327.   while (*t && *t != ';' && *t != ',') t++;
  328.   separator_char = *t;
  329.   *t = '\0';
  330.  
  331.   /* Free old buffer */
  332.   if (real_name_buffer)
  333.     {
  334.       free (real_name_buffer);
  335.       real_name_buffer = NULL;
  336.     }
  337.  
  338.   /* Calculate size of resultant real-name string */
  339.   for (nchars_expanded = 0, s = entry->pw_gecos; *s; s++)
  340.     if (*s == '&')
  341.       nchars_expanded += strlen (entry->pw_name);
  342.     else
  343.       nchars_expanded++;
  344.  
  345.   /* Don't alloc one char */
  346.   if (!nchars_expanded)
  347.     return "";
  348.  
  349.   /* Allocate resultant string and create long name field. */
  350.   real_name_buffer = (char *)xmalloc (nchars_expanded + 1);
  351.  
  352.   for (t = entry->pw_gecos, s = real_name_buffer; *t; *t++)
  353.     if (*t == '&')
  354.       {
  355.         strcpy (s, entry->pw_name);
  356.         *s = (*s >= 'a' && *s <= 'z' ? *s - 32 : *s);
  357.         s += strlen (s);
  358.       }
  359.     else
  360.       *s++ = *t;
  361.  
  362.   *s = 0;
  363.  
  364.   /* Restore original entry */
  365.   *t = separator_char;
  366.  
  367.   return real_name_buffer;
  368. }
  369.  
  370.  
  371. /* Remove file name suffixes. Returns malloced string. */
  372. static char *
  373. strip_suffixes (s)
  374.   char *s;
  375. {
  376.   char *new, *s1, *d;
  377.  
  378.   for (s1 = s; *s1 && *s1 != '.'; s1++);
  379.  
  380.   new = (char *)malloc (s1 - s + 1);
  381.  
  382.   for (d = new; s < s1; *d++ = *s++);
  383.  
  384.   *d = 0;
  385.  
  386.   return new;
  387. }
  388.  
  389.  
  390. /* Return basename sans suffixes. Returns malloced string. */
  391. char *
  392. baseprefix (filename)
  393.   char *filename;
  394. {
  395.   char *s;
  396.  
  397.   for (s = filename + strlen (filename) - 1; s > filename; s--)
  398.     if (*s == '/')
  399.       return strip_suffixes (s + 1);
  400.  
  401.   return strip_suffixes (filename);
  402. }
  403.  
  404.  
  405. /* Return freshly allocated copy of S. */
  406. char *
  407. xstrdup (s)
  408.   char *s;
  409. {
  410.   char *tmp = xmalloc (strlen (s) + 1);
  411.  
  412.   strcpy (tmp, s);
  413.  
  414.   return tmp;
  415. }
  416.  
  417.  
  418. /* Test if string is name of console */
  419. int
  420. is_console (s)
  421.   char *s;
  422. {
  423.   int n = strlen (s);
  424.  
  425.   if (s[n-1] == '*')
  426.     n--;
  427.  
  428.   return (!xstrnicmp (s, "console", n)
  429.           || !strncmp (s, ":0", n)
  430.           || !strncmp (s, "hty", 3));
  431. }
  432.  
  433.  
  434. /* Strip domain part from name. Returns fresh string. */
  435. char *
  436. sans_domain (fqdn_or_host)
  437.   char *fqdn_or_host;
  438. {
  439.   char *tail, *hostpart;
  440.  
  441.   for (tail = fqdn_or_host; *tail && *tail != '.'; tail++);
  442.  
  443.   hostpart = xmalloc (tail - fqdn_or_host + 1);
  444.  
  445.   if (tail-fqdn_or_host)
  446.     strncpy (hostpart, fqdn_or_host, tail - fqdn_or_host);
  447.  
  448.   hostpart[tail - fqdn_or_host] = 0;
  449.  
  450.   return hostpart;
  451. }
  452.  
  453.  
  454. #undef free
  455. void
  456. xfree (blk)
  457.   void *blk;
  458. {
  459. #if 0
  460.   fprintf (stderr, "%lx: free\n", blk); /* DEBUG */
  461. #endif
  462.  
  463.   free (blk);
  464. }
  465.