bb_askpass.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  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 <stdio.h>
  11. #include <string.h>
  12. #include <unistd.h>
  13. #include <fcntl.h>
  14. #include <signal.h>
  15. #include <termios.h>
  16. #include <sys/ioctl.h>
  17. #include "libbb.h"
  18. #define PWD_BUFFER_SIZE 256
  19. /* do nothing signal handler */
  20. static void askpass_timeout(int ATTRIBUTE_UNUSED ignore)
  21. {
  22. }
  23. char *bb_askpass(int timeout, const char * prompt)
  24. {
  25. char *ret;
  26. int i, size;
  27. struct sigaction sa;
  28. struct termios old, new;
  29. static char passwd[PWD_BUFFER_SIZE];
  30. tcgetattr(STDIN_FILENO, &old);
  31. tcflush(STDIN_FILENO, TCIFLUSH);
  32. size = sizeof(passwd);
  33. ret = passwd;
  34. memset(passwd, 0, size);
  35. fputs(prompt, stdout);
  36. fflush(stdout);
  37. tcgetattr(STDIN_FILENO, &new);
  38. new.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY);
  39. new.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP);
  40. tcsetattr(STDIN_FILENO, TCSANOW, &new);
  41. if (timeout) {
  42. sa.sa_flags = 0;
  43. sa.sa_handler = askpass_timeout;
  44. sigaction(SIGALRM, &sa, NULL);
  45. alarm(timeout);
  46. }
  47. if (read(STDIN_FILENO, passwd, size-1) <= 0) {
  48. ret = NULL;
  49. } else {
  50. for(i = 0; i < size && passwd[i]; i++) {
  51. if (passwd[i]== '\r' || passwd[i] == '\n') {
  52. passwd[i]= 0;
  53. break;
  54. }
  55. }
  56. }
  57. if (timeout) {
  58. alarm(0);
  59. }
  60. tcsetattr(STDIN_FILENO, TCSANOW, &old);
  61. fputs("\n", stdout);
  62. fflush(stdout);
  63. return ret;
  64. }