Blame misc/getusershell.c

Packit Service 82fcde
/*
Packit Service 82fcde
 * Copyright (c) 1985, 1993
Packit Service 82fcde
 *	The Regents of the University of California.  All rights reserved.
Packit Service 82fcde
 *
Packit Service 82fcde
 * Redistribution and use in source and binary forms, with or without
Packit Service 82fcde
 * modification, are permitted provided that the following conditions
Packit Service 82fcde
 * are met:
Packit Service 82fcde
 * 1. Redistributions of source code must retain the above copyright
Packit Service 82fcde
 *    notice, this list of conditions and the following disclaimer.
Packit Service 82fcde
 * 2. Redistributions in binary form must reproduce the above copyright
Packit Service 82fcde
 *    notice, this list of conditions and the following disclaimer in the
Packit Service 82fcde
 *    documentation and/or other materials provided with the distribution.
Packit Service 82fcde
 * 4. Neither the name of the University nor the names of its contributors
Packit Service 82fcde
 *    may be used to endorse or promote products derived from this software
Packit Service 82fcde
 *    without specific prior written permission.
Packit Service 82fcde
 *
Packit Service 82fcde
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
Packit Service 82fcde
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
Packit Service 82fcde
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
Packit Service 82fcde
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
Packit Service 82fcde
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
Packit Service 82fcde
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
Packit Service 82fcde
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
Packit Service 82fcde
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
Packit Service 82fcde
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
Packit Service 82fcde
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
Packit Service 82fcde
 * SUCH DAMAGE.
Packit Service 82fcde
 */
Packit Service 82fcde
Packit Service 82fcde
#if defined(LIBC_SCCS) && !defined(lint)
Packit Service 82fcde
static char sccsid[] = "@(#)getusershell.c	8.1 (Berkeley) 6/4/93";
Packit Service 82fcde
#endif /* LIBC_SCCS and not lint */
Packit Service 82fcde
Packit Service 82fcde
#include <sys/param.h>
Packit Service 82fcde
#include <sys/file.h>
Packit Service 82fcde
#include <sys/stat.h>
Packit Service 82fcde
#include <stdio.h>
Packit Service 82fcde
#include <stdio_ext.h>
Packit Service 82fcde
#include <ctype.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <unistd.h>
Packit Service 82fcde
#include <paths.h>
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Local shells should NOT be added here.  They should be added in
Packit Service 82fcde
 * /etc/shells.
Packit Service 82fcde
 */
Packit Service 82fcde
Packit Service 82fcde
/* NB: we do not initialize okshells here.  The initialization needs
Packit Service 82fcde
   relocations.  These interfaces are used so rarely that this is not
Packit Service 82fcde
   justified.  Instead explicitly initialize the array when it is
Packit Service 82fcde
   used.  */
Packit Service 82fcde
#if 0
Packit Service 82fcde
static const char *const okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
Packit Service 82fcde
#else
Packit Service 82fcde
static const char *okshells[3];
Packit Service 82fcde
#endif
Packit Service 82fcde
static char **curshell, **shells, *strings;
Packit Service 82fcde
static char **initshells (void) __THROW;
Packit Service 82fcde
Packit Service 82fcde
/*
Packit Service 82fcde
 * Get a list of shells from _PATH_SHELLS, if it exists.
Packit Service 82fcde
 */
Packit Service 82fcde
char *
Packit Service 82fcde
getusershell (void)
Packit Service 82fcde
{
Packit Service 82fcde
	char *ret;
Packit Service 82fcde
Packit Service 82fcde
	if (curshell == NULL)
Packit Service 82fcde
		curshell = initshells();
Packit Service 82fcde
	ret = *curshell;
Packit Service 82fcde
	if (ret != NULL)
Packit Service 82fcde
		curshell++;
Packit Service 82fcde
	return (ret);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
endusershell (void)
Packit Service 82fcde
{
Packit Service 82fcde
Packit Service 82fcde
	free(shells);
Packit Service 82fcde
	shells = NULL;
Packit Service 82fcde
	free(strings);
Packit Service 82fcde
	strings = NULL;
Packit Service 82fcde
	curshell = NULL;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
setusershell (void)
Packit Service 82fcde
{
Packit Service 82fcde
Packit Service 82fcde
	curshell = initshells();
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
static char **
Packit Service 82fcde
initshells (void)
Packit Service 82fcde
{
Packit Service 82fcde
	char **sp, *cp;
Packit Service 82fcde
	FILE *fp;
Packit Service 82fcde
	struct stat64 statb;
Packit Service 82fcde
	size_t flen;
Packit Service 82fcde
Packit Service 82fcde
	free(shells);
Packit Service 82fcde
	shells = NULL;
Packit Service 82fcde
	free(strings);
Packit Service 82fcde
	strings = NULL;
Packit Service 82fcde
	if ((fp = fopen(_PATH_SHELLS, "rce")) == NULL)
Packit Service 82fcde
		goto init_okshells_noclose;
Packit Service 82fcde
	if (fstat64(fileno(fp), &statb) == -1) {
Packit Service 82fcde
	init_okshells:
Packit Service 82fcde
		(void)fclose(fp);
Packit Service 82fcde
	init_okshells_noclose:
Packit Service 82fcde
		okshells[0] = _PATH_BSHELL;
Packit Service 82fcde
		okshells[1] = _PATH_CSHELL;
Packit Service 82fcde
		return (char **) okshells;
Packit Service 82fcde
	}
Packit Service 82fcde
	if (statb.st_size > ~(size_t)0 / sizeof (char *) * 3)
Packit Service 82fcde
		goto init_okshells;
Packit Service 82fcde
	flen = statb.st_size + 3;
Packit Service 82fcde
	if ((strings = malloc(flen)) == NULL)
Packit Service 82fcde
		goto init_okshells;
Packit Service 82fcde
	shells = malloc(statb.st_size / 3 * sizeof (char *));
Packit Service 82fcde
	if (shells == NULL) {
Packit Service 82fcde
		free(strings);
Packit Service 82fcde
		strings = NULL;
Packit Service 82fcde
		goto init_okshells;
Packit Service 82fcde
	}
Packit Service 82fcde
	sp = shells;
Packit Service 82fcde
	cp = strings;
Packit Service 82fcde
	while (fgets_unlocked(cp, flen - (cp - strings), fp) != NULL) {
Packit Service 82fcde
		while (*cp != '#' && *cp != '/' && *cp != '\0')
Packit Service 82fcde
			cp++;
Packit Service 82fcde
		if (*cp == '#' || *cp == '\0' || cp[1] == '\0')
Packit Service 82fcde
			continue;
Packit Service 82fcde
		*sp++ = cp;
Packit Service 82fcde
		while (!isspace(*cp) && *cp != '#' && *cp != '\0')
Packit Service 82fcde
			cp++;
Packit Service 82fcde
		*cp++ = '\0';
Packit Service 82fcde
	}
Packit Service 82fcde
	*sp = NULL;
Packit Service 82fcde
	(void)fclose(fp);
Packit Service 82fcde
	return (shells);
Packit Service 82fcde
}