usershell.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. /* setusershell(), getusershell(), endusershell() for uClibc.
  2. *
  3. * Copyright (C) 2010 Bernhard Reutner-Fischer <uclibc@uclibc.org>
  4. *
  5. * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB in
  6. * this tarball.
  7. */
  8. /* My manpage reads:
  9. * The getusershell() function returns the next line from the file
  10. * /etc/shells, opening the file if necessary. The line should contain
  11. * the pathname of a valid user shell. If /etc/shells does not exist
  12. * or is unreadable, getusershell() behaves as if /bin/sh and /bin/csh
  13. * were listed in the file.
  14. * The getusershell() function returns a NULL pointer on end-of-file.
  15. */
  16. #include <unistd.h>
  17. #include <stdlib.h>
  18. #include <paths.h>
  19. #include <string.h>
  20. #include "internal/parse_config.h"
  21. #if defined __USE_BSD || (defined __USE_XOPEN && !defined __USE_UNIX98)
  22. static const char * const defaultsh[] = { _PATH_BSHELL, _PATH_CSHELL, NULL};
  23. static char *shellb, **shells;
  24. static parser_t *shellp;
  25. void endusershell(void)
  26. {
  27. if (shellp) {
  28. shells = (char**) shellb;
  29. while (shells && *shells) {
  30. char*xxx = *shells++;
  31. free(xxx);
  32. }
  33. config_close(shellp);
  34. shellp = NULL;
  35. }
  36. free(shellb);
  37. shellb = NULL;
  38. shells = NULL;
  39. }
  40. libc_hidden_def(endusershell)
  41. void setusershell(void)
  42. {
  43. endusershell();
  44. shellp = config_open(_PATH_SHELLS);
  45. if (shellp == NULL)
  46. shells = (char **)defaultsh;
  47. else {
  48. char **shell = NULL;
  49. int pos = 0;
  50. while (config_read(shellp, &shell, 1, 1, "# \t", PARSE_NORMAL))
  51. {
  52. shellb = realloc(shellb, (pos + 2) * sizeof(char*));
  53. shells = (char**) shellb + pos++;
  54. *shells++ = strdup(*shell);
  55. *shells = NULL;
  56. }
  57. shells = (char **)shellb;
  58. }
  59. }
  60. libc_hidden_def(setusershell)
  61. char *getusershell(void)
  62. {
  63. char *sh;
  64. if (shells == NULL)
  65. setusershell();
  66. sh = *shells;
  67. if (sh)
  68. shells++;
  69. return sh;
  70. }
  71. #endif