|
@@ -1,134 +1,74 @@
|
|
|
-
|
|
|
- * Copyright (c) 1985, 1993
|
|
|
- * The Regents of the University of California. All rights reserved.
|
|
|
+
|
|
|
*
|
|
|
- * Redistribution and use in source and binary forms, with or without
|
|
|
- * modification, are permitted provided that the following conditions
|
|
|
- * are met:
|
|
|
- * 1. Redistributions of source code must retain the above copyright
|
|
|
- * notice, this list of conditions and the following disclaimer.
|
|
|
- * 2. Redistributions in binary form must reproduce the above copyright
|
|
|
- * notice, this list of conditions and the following disclaimer in the
|
|
|
- * documentation and/or other materials provided with the distribution.
|
|
|
- * 4. Neither the name of the University nor the names of its contributors
|
|
|
- * may be used to endorse or promote products derived from this software
|
|
|
- * without specific prior written permission.
|
|
|
+ * Copyright (C) 2010 Bernhard Reutner-Fischer <uclibc@uclibc.org>
|
|
|
*
|
|
|
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
- * SUCH DAMAGE.
|
|
|
- *
|
|
|
- * This version has been hevily modified for use with uClibc
|
|
|
- * November 2002, Erik Andersen <andersen@codepoet.org>
|
|
|
+ * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in
|
|
|
+ * this tarball.
|
|
|
+ */
|
|
|
+
|
|
|
+ * The getusershell() function returns the next line from the file
|
|
|
+ * /etc/shells, opening the file if necessary. The line should contain
|
|
|
+ * the pathname of a valid user shell. If /etc/shells does not exist
|
|
|
+ * or is unreadable, getusershell() behaves as if /bin/sh and /bin/csh
|
|
|
+ * were listed in the file.
|
|
|
+ * The getusershell() function returns a NULL pointer on end-of-file.
|
|
|
*/
|
|
|
-
|
|
|
-#include <sys/param.h>
|
|
|
-#include <sys/file.h>
|
|
|
-#include <sys/stat.h>
|
|
|
-#include <stdio.h>
|
|
|
-#include <stdio_ext.h>
|
|
|
-#include <ctype.h>
|
|
|
-#include <stdlib.h>
|
|
|
#include <unistd.h>
|
|
|
+#include <stdlib.h>
|
|
|
#include <paths.h>
|
|
|
+#include <string.h>
|
|
|
+#include "internal/parse_config.h"
|
|
|
|
|
|
#if defined __USE_BSD || (defined __USE_XOPEN && !defined __USE_UNIX98)
|
|
|
|
|
|
-
|
|
|
- * Local shells should NOT be added here. They should be added in
|
|
|
- * /etc/shells.
|
|
|
- */
|
|
|
-
|
|
|
-static const char * const validsh[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
|
|
|
-static char **curshell, **shells, *strings;
|
|
|
-static char **initshells __P((void));
|
|
|
-
|
|
|
-
|
|
|
- * Get a list of shells from _PATH_SHELLS, if it exists.
|
|
|
- */
|
|
|
-char * getusershell(void)
|
|
|
-{
|
|
|
- char *ret;
|
|
|
-
|
|
|
- if (curshell == NULL)
|
|
|
- curshell = initshells();
|
|
|
- ret = *curshell;
|
|
|
- if (ret != NULL)
|
|
|
- curshell++;
|
|
|
- return (ret);
|
|
|
-}
|
|
|
-
|
|
|
-static void __free_initshell_memory(void)
|
|
|
-{
|
|
|
- free(shells);
|
|
|
- shells = NULL;
|
|
|
- free(strings);
|
|
|
- strings = NULL;
|
|
|
-}
|
|
|
+static const char * const defaultsh[] = { _PATH_BSHELL, _PATH_CSHELL, NULL};
|
|
|
+static char *shellb, **shells;
|
|
|
+static parser_t *shellp;
|
|
|
|
|
|
void endusershell(void)
|
|
|
{
|
|
|
- __free_initshell_memory();
|
|
|
- curshell = NULL;
|
|
|
+ if (shellp) {
|
|
|
+ shells = (char**) shellb;
|
|
|
+ while (shells && *shells) {
|
|
|
+ char*xxx = *shells++;
|
|
|
+ free(xxx);
|
|
|
+ }
|
|
|
+ config_close(shellp);
|
|
|
+ shellp = NULL;
|
|
|
+ }
|
|
|
+ free(shellb);
|
|
|
+ shellb = NULL;
|
|
|
+ shells = NULL;
|
|
|
}
|
|
|
-
|
|
|
void setusershell(void)
|
|
|
{
|
|
|
- curshell = initshells();
|
|
|
-}
|
|
|
+ endusershell();
|
|
|
+ shellp = config_open(_PATH_SHELLS);
|
|
|
+ if (shellp == NULL)
|
|
|
+ shells = (char **)defaultsh;
|
|
|
+ else {
|
|
|
+ char **shell = NULL;
|
|
|
+ int pos = 0;
|
|
|
|
|
|
-static char ** initshells(void)
|
|
|
-{
|
|
|
- register char **sp, *cp;
|
|
|
- register FILE *fp;
|
|
|
- struct stat statb;
|
|
|
- int flen;
|
|
|
+ while (config_read(shellp, &shell, 1, 1, "# \t", PARSE_NORMAL))
|
|
|
+ {
|
|
|
+ shellb = realloc(shellb, (pos + 2) * sizeof(char*));
|
|
|
+ shells = (char**) shellb + pos++;
|
|
|
+ *shells++ = strdup(*shell);
|
|
|
+ *shells = NULL;
|
|
|
|
|
|
- __free_initshell_memory();
|
|
|
-
|
|
|
- if ((fp = fopen(_PATH_SHELLS, "r")) == NULL)
|
|
|
- return (char **) validsh;
|
|
|
- if (fstat(fileno(fp), &statb) == -1) {
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
- if ((strings = malloc((unsigned)statb.st_size + 1)) == NULL) {
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
- if ((shells = calloc((unsigned)statb.st_size / 3, sizeof (char *))) == NULL) {
|
|
|
- goto cleanup;
|
|
|
- }
|
|
|
-
|
|
|
-#ifdef __UCLIBC_HAS_THREADS__
|
|
|
- __fsetlocking (fp, FSETLOCKING_BYCALLER);
|
|
|
-#endif
|
|
|
- sp = shells;
|
|
|
- cp = strings;
|
|
|
- flen = statb.st_size;
|
|
|
- while (fgets_unlocked(cp, flen - (cp - strings), fp) != NULL) {
|
|
|
- while (*cp != '#' && *cp != '/' && *cp != '\0')
|
|
|
- cp++;
|
|
|
- if (*cp == '#' || *cp == '\0')
|
|
|
- continue;
|
|
|
- *sp++ = cp;
|
|
|
- while (!isspace(*cp) && *cp != '#' && *cp != '\0')
|
|
|
- cp++;
|
|
|
- *cp++ = '\0';
|
|
|
- }
|
|
|
- *sp = NULL;
|
|
|
- fclose(fp);
|
|
|
- return (shells);
|
|
|
-
|
|
|
-cleanup:
|
|
|
- __free_initshell_memory();
|
|
|
- fclose(fp);
|
|
|
- return (char **) validsh;
|
|
|
+ }
|
|
|
+ shells = (char **)shellb;
|
|
|
+ }
|
|
|
+}
|
|
|
+char *getusershell(void)
|
|
|
+{
|
|
|
+ char *sh;
|
|
|
+ if (shells == NULL)
|
|
|
+ setusershell();
|
|
|
+ sh = *shells;
|
|
|
+ if (sh)
|
|
|
+ shells++;
|
|
|
+ return sh;
|
|
|
}
|
|
|
#endif
|