17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * Copyright (c) 1985 Regents of the University of California.
37c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement
47c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution.
57c478bd9Sstevel@tonic-gate */
67c478bd9Sstevel@tonic-gate
7*5d54f3d8Smuffin #pragma ident "%Z%%M% %I% %E% SMI"
8*5d54f3d8Smuffin
97c478bd9Sstevel@tonic-gate #include <sys/param.h>
107c478bd9Sstevel@tonic-gate #include <sys/file.h>
117c478bd9Sstevel@tonic-gate #include <sys/stat.h>
127c478bd9Sstevel@tonic-gate #include <ctype.h>
137c478bd9Sstevel@tonic-gate #include <stdio.h>
14*5d54f3d8Smuffin #include <malloc.h>
157c478bd9Sstevel@tonic-gate
167c478bd9Sstevel@tonic-gate #define SHELLS "/etc/shells"
177c478bd9Sstevel@tonic-gate
187c478bd9Sstevel@tonic-gate /*
197c478bd9Sstevel@tonic-gate * Do not add local shells here. They should be added in /etc/shells
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate static char *okshells[] =
227c478bd9Sstevel@tonic-gate { "/bin/sh", "/bin/csh", "/usr/bin/sh", "/usr/bin/csh", 0 };
237c478bd9Sstevel@tonic-gate
247c478bd9Sstevel@tonic-gate static char **shells, *strings;
257c478bd9Sstevel@tonic-gate static char **curshell;
26*5d54f3d8Smuffin
27*5d54f3d8Smuffin static char **initshells(void);
287c478bd9Sstevel@tonic-gate
297c478bd9Sstevel@tonic-gate /*
307c478bd9Sstevel@tonic-gate * Get a list of shells from SHELLS, if it exists.
317c478bd9Sstevel@tonic-gate */
327c478bd9Sstevel@tonic-gate char *
getusershell(void)33*5d54f3d8Smuffin getusershell(void)
347c478bd9Sstevel@tonic-gate {
357c478bd9Sstevel@tonic-gate char *ret;
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate if (curshell == NULL)
387c478bd9Sstevel@tonic-gate curshell = initshells();
397c478bd9Sstevel@tonic-gate ret = *curshell;
407c478bd9Sstevel@tonic-gate if (ret != NULL)
417c478bd9Sstevel@tonic-gate curshell++;
427c478bd9Sstevel@tonic-gate return (ret);
437c478bd9Sstevel@tonic-gate }
447c478bd9Sstevel@tonic-gate
45*5d54f3d8Smuffin void
endusershell(void)46*5d54f3d8Smuffin endusershell(void)
477c478bd9Sstevel@tonic-gate {
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate if (shells != NULL)
507c478bd9Sstevel@tonic-gate free((char *)shells);
517c478bd9Sstevel@tonic-gate shells = NULL;
527c478bd9Sstevel@tonic-gate if (strings != NULL)
537c478bd9Sstevel@tonic-gate free(strings);
547c478bd9Sstevel@tonic-gate strings = NULL;
557c478bd9Sstevel@tonic-gate curshell = NULL;
567c478bd9Sstevel@tonic-gate }
577c478bd9Sstevel@tonic-gate
58*5d54f3d8Smuffin void
setusershell(void)59*5d54f3d8Smuffin setusershell(void)
607c478bd9Sstevel@tonic-gate {
617c478bd9Sstevel@tonic-gate
627c478bd9Sstevel@tonic-gate curshell = initshells();
637c478bd9Sstevel@tonic-gate }
647c478bd9Sstevel@tonic-gate
657c478bd9Sstevel@tonic-gate static char **
initshells(void)66*5d54f3d8Smuffin initshells(void)
677c478bd9Sstevel@tonic-gate {
68*5d54f3d8Smuffin char **sp, *cp;
69*5d54f3d8Smuffin FILE *fp;
707c478bd9Sstevel@tonic-gate struct stat statb;
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate if (shells != NULL)
737c478bd9Sstevel@tonic-gate free((char *)shells);
747c478bd9Sstevel@tonic-gate shells = NULL;
757c478bd9Sstevel@tonic-gate if (strings != NULL)
767c478bd9Sstevel@tonic-gate free(strings);
777c478bd9Sstevel@tonic-gate strings = NULL;
787c478bd9Sstevel@tonic-gate if ((fp = fopen(SHELLS, "r")) == (FILE *)0)
797c478bd9Sstevel@tonic-gate return (okshells);
807c478bd9Sstevel@tonic-gate if (fstat(fileno(fp), &statb) == -1) {
817c478bd9Sstevel@tonic-gate (void)fclose(fp);
827c478bd9Sstevel@tonic-gate return (okshells);
837c478bd9Sstevel@tonic-gate }
847c478bd9Sstevel@tonic-gate if ((strings = malloc((unsigned)statb.st_size + 1)) == NULL) {
857c478bd9Sstevel@tonic-gate (void)fclose(fp);
867c478bd9Sstevel@tonic-gate return (okshells);
877c478bd9Sstevel@tonic-gate }
887c478bd9Sstevel@tonic-gate shells = (char **)calloc((unsigned)statb.st_size / 3, sizeof (char *));
897c478bd9Sstevel@tonic-gate if (shells == NULL) {
907c478bd9Sstevel@tonic-gate (void)fclose(fp);
917c478bd9Sstevel@tonic-gate free(strings);
927c478bd9Sstevel@tonic-gate strings = NULL;
937c478bd9Sstevel@tonic-gate return (okshells);
947c478bd9Sstevel@tonic-gate }
957c478bd9Sstevel@tonic-gate sp = shells;
967c478bd9Sstevel@tonic-gate cp = strings;
977c478bd9Sstevel@tonic-gate while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
987c478bd9Sstevel@tonic-gate while (*cp != '#' && *cp != '/' && *cp != '\0')
997c478bd9Sstevel@tonic-gate cp++;
1007c478bd9Sstevel@tonic-gate if (*cp == '#' || *cp == '\0')
1017c478bd9Sstevel@tonic-gate continue;
1027c478bd9Sstevel@tonic-gate *sp++ = cp;
1037c478bd9Sstevel@tonic-gate while (!isspace(*cp) && *cp != '#' && *cp != '\0')
1047c478bd9Sstevel@tonic-gate cp++;
1057c478bd9Sstevel@tonic-gate *cp++ = '\0';
1067c478bd9Sstevel@tonic-gate }
1077c478bd9Sstevel@tonic-gate *sp = (char *)0;
1087c478bd9Sstevel@tonic-gate (void)fclose(fp);
1097c478bd9Sstevel@tonic-gate return (shells);
1107c478bd9Sstevel@tonic-gate }
111