sockaddr's now require length (K. Sklower);
[unix-history] / usr / src / lib / libc / gen / getusershell.c
CommitLineData
4a76e37c
KM
1/*
2 * Copyright (c) 1985 Regents of the University of California.
73da8e88
KB
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
4a76e37c
KM
16 */
17
2ce81398 18#if defined(LIBC_SCCS) && !defined(lint)
73da8e88
KB
19static char sccsid[] = "@(#)getusershell.c 5.5 (Berkeley) %G%";
20#endif /* LIBC_SCCS and not lint */
4a76e37c
KM
21
22#include <sys/param.h>
23#include <sys/file.h>
24#include <sys/stat.h>
25#include <ctype.h>
26#include <stdio.h>
27
28#define SHELLS "/etc/shells"
29
30/*
31 * Do not add local shells here. They should be added in /etc/shells
32 */
33static char *okshells[] =
34 { "/bin/sh", "/bin/csh", 0 };
35
4a76e37c 36static char **shells, *strings;
25848be5 37static char **curshell = NULL;
4a76e37c
KM
38extern char **initshells();
39
40/*
41 * Get a list of shells from SHELLS, if it exists.
42 */
43char *
44getusershell()
45{
46 char *ret;
4a76e37c 47
25848be5
JB
48 if (curshell == NULL)
49 curshell = initshells();
50 ret = *curshell;
51 if (ret != NULL)
52 curshell++;
4a76e37c
KM
53 return (ret);
54}
55
56endusershell()
57{
58
59 if (shells != NULL)
60 free((char *)shells);
61 shells = NULL;
62 if (strings != NULL)
63 free(strings);
64 strings = NULL;
25848be5 65 curshell = NULL;
4a76e37c
KM
66}
67
68setusershell()
69{
70
25848be5 71 curshell = initshells();
4a76e37c
KM
72}
73
74static char **
75initshells()
76{
77 register char **sp, *cp;
78 register FILE *fp;
79 struct stat statb;
80 extern char *malloc(), *calloc();
81
4a76e37c
KM
82 if (shells != NULL)
83 free((char *)shells);
84 shells = NULL;
85 if (strings != NULL)
86 free(strings);
87 strings = NULL;
88 if ((fp = fopen(SHELLS, "r")) == (FILE *)0)
89 return(okshells);
90 if (fstat(fileno(fp), &statb) == -1) {
91 (void)fclose(fp);
92 return(okshells);
93 }
94 if ((strings = malloc((unsigned)statb.st_size)) == NULL) {
95 (void)fclose(fp);
96 return(okshells);
97 }
98 shells = (char **)calloc((unsigned)statb.st_size / 3, sizeof (char *));
99 if (shells == NULL) {
100 (void)fclose(fp);
101 free(strings);
102 strings = NULL;
103 return(okshells);
104 }
105 sp = shells;
106 cp = strings;
107 while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
25848be5 108 while (*cp != '#' && *cp != '/' && *cp != '\0')
4a76e37c 109 cp++;
25848be5 110 if (*cp == '#' || *cp == '\0')
4a76e37c
KM
111 continue;
112 *sp++ = cp;
113 while (!isspace(*cp) && *cp != '#' && *cp != '\0')
114 cp++;
115 *cp++ = '\0';
116 }
117 *sp = (char *)0;
118 (void)fclose(fp);
119 return (shells);
120}