bb_askpass.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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;
  24. struct termios old, new;
  25. if (!passwd)
  26. passwd = xmalloc(sizeof_passwd);
  27. memset(passwd, 0, sizeof_passwd);
  28. tcgetattr(STDIN_FILENO, &old);
  29. tcflush(STDIN_FILENO, TCIFLUSH);
  30. fputs(prompt, stdout);
  31. fflush(stdout);
  32. tcgetattr(STDIN_FILENO, &new);
  33. new.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);
  34. new.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP);
  35. tcsetattr(STDIN_FILENO, TCSANOW, &new);
  36. if (timeout) {
  37. sa.sa_flags = 0;
  38. sa.sa_handler = askpass_timeout;
  39. sigaction(SIGALRM, &sa, NULL);
  40. alarm(timeout);
  41. }
  42. ret = NULL;
  43. /* On timeout, read will hopefully be interrupted by SIGALRM,
  44. * and we return NULL */
  45. if (read(STDIN_FILENO, passwd, sizeof_passwd-1) > 0) {
  46. ret = passwd;
  47. i = 0;
  48. /* Last byte is guaranteed to be 0
  49. (read did not overwrite it) */
  50. do {
  51. if (passwd[i] == '\r' || passwd[i] == '\n')
  52. passwd[i] = '\0';
  53. } while (passwd[i++]);
  54. }
  55. if (timeout) {
  56. alarm(0);
  57. }
  58. tcsetattr(STDIN_FILENO, TCSANOW, &old);
  59. putchar('\n');
  60. fflush(stdout);
  61. return ret;
  62. }