10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * Copyright (c) 1985 Regents of the University of California.
30Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement
40Sstevel@tonic-gate * specifies the terms and conditions for redistribution.
50Sstevel@tonic-gate */
60Sstevel@tonic-gate
7*722Smuffin #pragma ident "%Z%%M% %I% %E% SMI"
8*722Smuffin
90Sstevel@tonic-gate #include <sys/param.h>
100Sstevel@tonic-gate #include <sys/file.h>
110Sstevel@tonic-gate #include <sys/stat.h>
120Sstevel@tonic-gate #include <ctype.h>
130Sstevel@tonic-gate #include <stdio.h>
14*722Smuffin #include <malloc.h>
150Sstevel@tonic-gate
160Sstevel@tonic-gate #define SHELLS "/etc/shells"
170Sstevel@tonic-gate
180Sstevel@tonic-gate /*
190Sstevel@tonic-gate * Do not add local shells here. They should be added in /etc/shells
200Sstevel@tonic-gate */
210Sstevel@tonic-gate static char *okshells[] =
220Sstevel@tonic-gate { "/bin/sh", "/bin/csh", "/usr/bin/sh", "/usr/bin/csh", 0 };
230Sstevel@tonic-gate
240Sstevel@tonic-gate static char **shells, *strings;
250Sstevel@tonic-gate static char **curshell;
26*722Smuffin
27*722Smuffin static char **initshells(void);
280Sstevel@tonic-gate
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate * Get a list of shells from SHELLS, if it exists.
310Sstevel@tonic-gate */
320Sstevel@tonic-gate char *
getusershell(void)33*722Smuffin getusershell(void)
340Sstevel@tonic-gate {
350Sstevel@tonic-gate char *ret;
360Sstevel@tonic-gate
370Sstevel@tonic-gate if (curshell == NULL)
380Sstevel@tonic-gate curshell = initshells();
390Sstevel@tonic-gate ret = *curshell;
400Sstevel@tonic-gate if (ret != NULL)
410Sstevel@tonic-gate curshell++;
420Sstevel@tonic-gate return (ret);
430Sstevel@tonic-gate }
440Sstevel@tonic-gate
45*722Smuffin void
endusershell(void)46*722Smuffin endusershell(void)
470Sstevel@tonic-gate {
480Sstevel@tonic-gate
490Sstevel@tonic-gate if (shells != NULL)
500Sstevel@tonic-gate free((char *)shells);
510Sstevel@tonic-gate shells = NULL;
520Sstevel@tonic-gate if (strings != NULL)
530Sstevel@tonic-gate free(strings);
540Sstevel@tonic-gate strings = NULL;
550Sstevel@tonic-gate curshell = NULL;
560Sstevel@tonic-gate }
570Sstevel@tonic-gate
58*722Smuffin void
setusershell(void)59*722Smuffin setusershell(void)
600Sstevel@tonic-gate {
610Sstevel@tonic-gate
620Sstevel@tonic-gate curshell = initshells();
630Sstevel@tonic-gate }
640Sstevel@tonic-gate
650Sstevel@tonic-gate static char **
initshells(void)66*722Smuffin initshells(void)
670Sstevel@tonic-gate {
68*722Smuffin char **sp, *cp;
69*722Smuffin FILE *fp;
700Sstevel@tonic-gate struct stat statb;
710Sstevel@tonic-gate
720Sstevel@tonic-gate if (shells != NULL)
730Sstevel@tonic-gate free((char *)shells);
740Sstevel@tonic-gate shells = NULL;
750Sstevel@tonic-gate if (strings != NULL)
760Sstevel@tonic-gate free(strings);
770Sstevel@tonic-gate strings = NULL;
780Sstevel@tonic-gate if ((fp = fopen(SHELLS, "r")) == (FILE *)0)
79*722Smuffin return (okshells);
800Sstevel@tonic-gate if (fstat(fileno(fp), &statb) == -1) {
810Sstevel@tonic-gate (void)fclose(fp);
82*722Smuffin return (okshells);
830Sstevel@tonic-gate }
840Sstevel@tonic-gate if ((strings = malloc((unsigned)statb.st_size + 1)) == NULL) {
850Sstevel@tonic-gate (void)fclose(fp);
86*722Smuffin return (okshells);
870Sstevel@tonic-gate }
880Sstevel@tonic-gate shells = (char **)calloc((unsigned)statb.st_size / 3, sizeof (char *));
890Sstevel@tonic-gate if (shells == NULL) {
900Sstevel@tonic-gate (void)fclose(fp);
910Sstevel@tonic-gate free(strings);
920Sstevel@tonic-gate strings = NULL;
93*722Smuffin return (okshells);
940Sstevel@tonic-gate }
950Sstevel@tonic-gate sp = shells;
960Sstevel@tonic-gate cp = strings;
970Sstevel@tonic-gate while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
980Sstevel@tonic-gate while (*cp != '#' && *cp != '/' && *cp != '\0')
990Sstevel@tonic-gate cp++;
1000Sstevel@tonic-gate if (*cp == '#' || *cp == '\0')
1010Sstevel@tonic-gate continue;
1020Sstevel@tonic-gate *sp++ = cp;
1030Sstevel@tonic-gate while (!isspace(*cp) && *cp != '#' && *cp != '\0')
1040Sstevel@tonic-gate cp++;
1050Sstevel@tonic-gate *cp++ = '\0';
1060Sstevel@tonic-gate }
1070Sstevel@tonic-gate *sp = (char *)0;
1080Sstevel@tonic-gate (void)fclose(fp);
1090Sstevel@tonic-gate return (shells);
1100Sstevel@tonic-gate }
111