home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD2.bin / bbs / gnu / sh-utils-1.12-src.lha / sh-utils-1.12 / lib / getusershell.c < prev    next >
C/C++ Source or Header  |  1994-11-12  |  4KB  |  205 lines

  1. /* getusershell.c -- Return names of valid user shells.
  2.    Copyright (C) 1991 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /* Written by David MacKenzie <djm@gnu.ai.mit.edu> */
  19.  
  20. #ifdef HAVE_CONFIG_H
  21. #include <config.h>
  22. #endif
  23.  
  24. #ifndef SHELLS_FILE
  25. /* File containing a list of nonrestricted shells, one per line. */
  26. #define SHELLS_FILE "/etc/shells"
  27. #endif
  28.  
  29. #include <stdio.h>
  30. #include <ctype.h>
  31.  
  32. #ifdef STDC_HEADERS
  33. #include <stdlib.h>
  34. #else
  35. char *malloc ();
  36. char *realloc ();
  37. #endif
  38.  
  39. char *xstrdup ();
  40.  
  41. static int readname ();
  42.  
  43. /* List of shells to use if the shells file is missing. */
  44. static char const* const default_shells[] =
  45. {
  46.   "/bin/sh", "/bin/ksh", "/bin/bash", NULL
  47. };
  48.  
  49. /* Index of the next shell in `default_shells' to return.
  50.    0 means we are not using `default_shells'. */
  51. static int default_index = 0;
  52.  
  53. /* Input stream from the shells file. */
  54. static FILE *shellstream = NULL;
  55.  
  56. /* Line of input from the shells file. */
  57. static char *line = NULL;
  58.  
  59. /* Number of bytes allocated for `line'. */
  60. static int line_size = 0;
  61.  
  62. /* Return an entry from the shells file, ignoring comment lines.
  63.    If the file doesn't exist, use the list in DEFAULT_SHELLS (above).
  64.    In any case, the returned string is in memory allocated through malloc.
  65.    Return NULL if there are no more entries.  */
  66.  
  67. char *
  68. getusershell ()
  69. {
  70.   if (default_index > 0)
  71.     {
  72.       if (default_shells[default_index])
  73.     /* Not at the end of the list yet.  */
  74.     return xstrdup (default_shells[default_index++]);
  75.       return NULL;
  76.     }
  77.  
  78.   if (shellstream == NULL)
  79.     {
  80.       shellstream = fopen (SHELLS_FILE, "r");
  81.       if (shellstream == NULL)
  82.     {
  83.       /* No shells file.  Use the default list.  */
  84.       default_index = 1;
  85.       return xstrdup (default_shells[0]);
  86.     }
  87.     }
  88.  
  89.   while (readname (&line, &line_size, shellstream))
  90.     {
  91.       if (*line != '#')
  92.     return line;
  93.     }
  94.   return NULL;            /* End of file. */
  95. }
  96.  
  97. /* Rewind the shells file. */
  98.  
  99. void
  100. setusershell ()
  101. {
  102.   default_index = 0;
  103.   if (shellstream == NULL)
  104.     shellstream = fopen (SHELLS_FILE, "r");
  105.   else
  106.     fseek (shellstream, 0L, 0);
  107. }
  108.  
  109. /* Close the shells file. */
  110.  
  111. void
  112. endusershell ()
  113. {
  114.   if (shellstream)
  115.     {
  116.       fclose (shellstream);
  117.       shellstream = NULL;
  118.     }
  119. }
  120.  
  121. /* Allocate N bytes of memory dynamically, with error checking.  */
  122.  
  123. static char *
  124. xmalloc (n)
  125.      unsigned n;
  126. {
  127.   char *p;
  128.  
  129.   p = malloc (n);
  130.   if (p == 0)
  131.     {
  132.       fprintf (stderr, "virtual memory exhausted\n");
  133.       exit (1);
  134.     }
  135.   return p;
  136. }
  137.  
  138. /* Reallocate space P to size N, with error checking.  */
  139.  
  140. static char *
  141. xrealloc (p, n)
  142.      char *p;
  143.      unsigned n;
  144. {
  145.   p = realloc (p, n);
  146.   if (p == 0)
  147.     {
  148.       fprintf (stderr, "virtual memory exhausted\n");
  149.       exit (1);
  150.     }
  151.   return p;
  152. }
  153.  
  154. /* Read a line from STREAM, removing any newline at the end.
  155.    Place the result in *NAME, which is malloc'd
  156.    and/or realloc'd as necessary and can start out NULL,
  157.    and whose size is passed and returned in *SIZE.
  158.  
  159.    Return the number of characters placed in *NAME
  160.    if some nonempty sequence was found, otherwise 0.  */
  161.  
  162. static int
  163. readname (name, size, stream)
  164.      char **name;
  165.      int *size;
  166.      FILE *stream;
  167. {
  168.   int c;
  169.   int name_index = 0;
  170.  
  171.   if (*name == NULL)
  172.     {
  173.       *size = 10;
  174.       *name = (char *) xmalloc (*size);
  175.     }
  176.  
  177.   /* Skip blank space.  */
  178.   while ((c = getc (stream)) != EOF && isspace (c))
  179.     /* Do nothing. */ ;
  180.   
  181.   while (c != EOF && !isspace (c))
  182.     {
  183.       (*name)[name_index++] = c;
  184.       while (name_index >= *size)
  185.     {
  186.       *size *= 2;
  187.       *name = (char *) xrealloc (*name, *size);
  188.     }
  189.       c = getc (stream);
  190.     }
  191.   (*name)[name_index] = '\0';
  192.   return name_index;
  193. }
  194.  
  195. #ifdef TEST
  196. main ()
  197. {
  198.   char *s;
  199.  
  200.   while (s = getusershell ())
  201.     puts (s);
  202.   exit (0);
  203. }
  204. #endif
  205.