bb_askpass.c 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Ask for a password
  4. * I use a static buffer in this function. Plan accordingly.
  5. *
  6. * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
  7. *
  8. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  9. */
  10. #include <termios.h>
  11. #include "libbb.h"
  12. /* do nothing signal handler */
  13. static void askpass_timeout(int ATTRIBUTE_UNUSED ignore)
  14. {
  15. }
  16. char *bb_askpass(int timeout, const char *prompt)
  17. {
  18. /* Was static char[BIGNUM] */
  19. enum { sizeof_passwd = 128 };
  20. static char *passwd;
  21. char *ret;
  22. int i;
  23. struct sigaction sa, oldsa;
  24. struct termios tio, oldtio;
  25. if (!passwd)
  26. passwd = xmalloc(sizeof_passwd);
  27. memset(passwd, 0, sizeof_passwd);
  28. tcgetattr(STDIN_FILENO, &oldtio);
  29. tcflush(STDIN_FILENO, TCIFLUSH);
  30. tio = oldtio;
  31. tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);
  32. tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP);
  33. tcsetattr(STDIN_FILENO, TCSANOW, &tio);
  34. memset(&sa, 0, sizeof(sa));
  35. /* sa.sa_flags = 0; - no SA_RESTART! */
  36. /* SIGINT and SIGALRM will interrupt read below */
  37. sa.sa_handler = askpass_timeout;
  38. sigaction(SIGINT, &sa, &oldsa);
  39. if (timeout) {
  40. sigaction_set(SIGALRM, &sa);
  41. alarm(timeout);
  42. }
  43. fputs(prompt, stdout);
  44. fflush(stdout);
  45. ret = NULL;
  46. /* On timeout or Ctrl-C, read will hopefully be interrupted,
  47. * and we return NULL */
  48. if (read(STDIN_FILENO, passwd, sizeof_passwd - 1) > 0) {
  49. ret = passwd;
  50. i = 0;
  51. /* Last byte is guaranteed to be 0
  52. (read did not overwrite it) */
  53. do {
  54. if (passwd[i] == '\r' || passwd[i] == '\n')
  55. passwd[i] = '\0';
  56. } while (passwd[i++]);
  57. }
  58. if (timeout) {
  59. alarm(0);
  60. }
  61. sigaction_set(SIGINT, &oldsa);
  62. tcsetattr(STDIN_FILENO, TCSANOW, &oldtio);
  63. bb_putchar('\n');
  64. fflush(stdout);
  65. return ret;
  66. }