home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / bbs / gnu / shellutils-1.9.4-src.lha / src / amiga / shellutils-1.9.4 / lib / getusershell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-22  |  4.6 KB  |  212 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. #if defined (CONFIG_BROKETS)
  22. /* We use <config.h> instead of "config.h" so that a compilation
  23.    using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
  24.    (which it would do because it found this file in $srcdir).  */
  25. #include <config.h>
  26. #else
  27. #include "config.h"
  28. #endif
  29. #endif
  30.  
  31. #ifndef SHELLS_FILE
  32. /* File containing a list of nonrestricted shells, one per line. */
  33. #define SHELLS_FILE "/etc/shells"
  34. #endif
  35.  
  36. #include <stdio.h>
  37. #include <ctype.h>
  38.  
  39. #ifdef STDC_HEADERS
  40. #include <stdlib.h>
  41. #else
  42. char *malloc ();
  43. char *realloc ();
  44. #endif
  45.  
  46. char *xstrdup ();
  47.  
  48. static int readname ();
  49.  
  50. /* List of shells to use if the shells file is missing. */
  51. static char const* const default_shells[] =
  52. {
  53.   "/bin/sh", "/bin/ksh", "/bin/bash", NULL
  54. };
  55.  
  56. /* Index of the next shell in `default_shells' to return.
  57.    0 means we are not using `default_shells'. */
  58. static int default_index = 0;
  59.  
  60. /* Input stream from the shells file. */
  61. static FILE *shellstream = NULL;
  62.  
  63. /* Line of input from the shells file. */
  64. static char *line = NULL;
  65.  
  66. /* Number of bytes allocated for `line'. */
  67. static int line_size = 0;
  68.  
  69. /* Return an entry from the shells file, ignoring comment lines.
  70.    If the file doesn't exist, use the list in DEFAULT_SHELLS (above).
  71.    In any case, the returned string is in memory allocated through malloc.
  72.    Return NULL if there are no more entries.  */
  73.  
  74. char *
  75. getusershell ()
  76. {
  77.   if (default_index > 0)
  78.     {
  79.       if (default_shells[default_index])
  80.     /* Not at the end of the list yet.  */
  81.     return xstrdup (default_shells[default_index++]);
  82.       return NULL;
  83.     }
  84.  
  85.   if (shellstream == NULL)
  86.     {
  87.       shellstream = fopen (SHELLS_FILE, "r");
  88.       if (shellstream == NULL)
  89.     {
  90.       /* No shells file.  Use the default list.  */
  91.       default_index = 1;
  92.       return xstrdup (default_shells[0]);
  93.     }
  94.     }
  95.  
  96.   while (readname (&line, &line_size, shellstream))
  97.     {
  98.       if (*line != '#')
  99.     return line;
  100.     }
  101.   return NULL;            /* End of file. */
  102. }
  103.  
  104. /* Rewind the shells file. */
  105.  
  106. void
  107. setusershell ()
  108. {
  109.   default_index = 0;
  110.   if (shellstream == NULL)
  111.     shellstream = fopen (SHELLS_FILE, "r");
  112.   else
  113.     fseek (shellstream, 0L, 0);
  114. }
  115.  
  116. /* Close the shells file. */
  117.  
  118. void
  119. endusershell ()
  120. {
  121.   if (shellstream)
  122.     {
  123.       fclose (shellstream);
  124.       shellstream = NULL;
  125.     }
  126. }
  127.  
  128. /* Allocate N bytes of memory dynamically, with error checking.  */
  129.  
  130. static char *
  131. xmalloc (n)
  132.      unsigned n;
  133. {
  134.   char *p;
  135.  
  136.   p = malloc (n);
  137.   if (p == 0)
  138.     {
  139.       fprintf (stderr, "virtual memory exhausted\n");
  140.       exit (1);
  141.     }
  142.   return p;
  143. }
  144.  
  145. /* Reallocate space P to size N, with error checking.  */
  146.  
  147. static char *
  148. xrealloc (p, n)
  149.      char *p;
  150.      unsigned n;
  151. {
  152.   p = realloc (p, n);
  153.   if (p == 0)
  154.     {
  155.       fprintf (stderr, "virtual memory exhausted\n");
  156.       exit (1);
  157.     }
  158.   return p;
  159. }
  160.  
  161. /* Read a line from STREAM, removing any newline at the end.
  162.    Place the result in *NAME, which is malloc'd
  163.    and/or realloc'd as necessary and can start out NULL,
  164.    and whose size is passed and returned in *SIZE.
  165.  
  166.    Return the number of characters placed in *NAME
  167.    if some nonempty sequence was found, otherwise 0.  */
  168.  
  169. static int
  170. readname (name, size, stream)
  171.      char **name;
  172.      int *size;
  173.      FILE *stream;
  174. {
  175.   int c;
  176.   int name_index = 0;
  177.  
  178.   if (*name == NULL)
  179.     {
  180.       *size = 10;
  181.       *name = (char *) xmalloc (*size);
  182.     }
  183.  
  184.   /* Skip blank space.  */
  185.   while ((c = getc (stream)) != EOF && isspace (c))
  186.     /* Do nothing. */ ;
  187.   
  188.   while (c != EOF && !isspace (c))
  189.     {
  190.       (*name)[name_index++] = c;
  191.       while (name_index >= *size)
  192.     {
  193.       *size *= 2;
  194.       *name = (char *) xrealloc (*name, *size);
  195.     }
  196.       c = getc (stream);
  197.     }
  198.   (*name)[name_index] = '\0';
  199.   return name_index;
  200. }
  201.  
  202. #ifdef TEST
  203. main ()
  204. {
  205.   char *s;
  206.  
  207.   while (s = getusershell ())
  208.     puts (s);
  209.   exit (0);
  210. }
  211. #endif
  212.