getpass.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /* ============================================================================
  2. * Copyright (C) 1998 - 2002, Daniel Stenberg, <[email protected]>, et al.
  3. *
  4. * Redistribution and use are freely permitted provided that:
  5. *
  6. * 1) This header remain in tact.
  7. * 2) The prototypes for getpass and getpass_r are not changed from:
  8. * char *getpass(const char *prompt)
  9. * char *getpass_r(const char *prompt, char* buffer, int buflen)
  10. * 3) This source code is not used outside of this(getpass.c) file.
  11. * 4) Any changes to this(getpass.c) source code are made publicly available.
  12. *
  13. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  14. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  15. * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  16. * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  17. * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  18. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  19. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  20. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  21. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  22. * POSSIBILITY OF SUCH DAMAGE.
  23. * ============================================================================
  24. *
  25. * $Id$
  26. *
  27. * The spirit of this license is to allow use of this source code in any
  28. * project be it open or closed but still encourage the use of the open,
  29. * library based equivilents.
  30. *
  31. * Author(s):
  32. * Angus Mackay <[email protected]>
  33. *
  34. * Contributor(s):
  35. * Daniel Stenberg <[email protected]>
  36. */
  37. #include "setup.h" /* setup.h is required for read() prototype */
  38. #ifndef HAVE_GETPASS_R
  39. #ifndef WIN32
  40. #ifdef VMS
  41. #include <stdio.h>
  42. #include <string.h>
  43. #include descrip
  44. #include starlet
  45. #include iodef
  46. #include iosbdef
  47. char *getpass_r(const char *prompt, char *buffer, size_t buflen)
  48. {
  49. long sts;
  50. short chan;
  51. struct _iosb iosb;
  52. $DESCRIPTOR(ttdesc, "TT");
  53. buffer[0]='\0';
  54. if ((sts = sys$assign(&ttdesc, &chan,0,0)) & 1) {
  55. if (((sts = sys$qiow(0, chan, IO$_READPROMPT | IO$M_NOECHO, &iosb, 0, 0, buffer, buflen, 0, 0, prompt, strlen(prompt))) & 1) && (iosb.iosb$w_status&1)) {
  56. buffer[iosb.iosb$w_bcnt] = '\0';
  57. }
  58. sts = sys$dassgn(chan);
  59. }
  60. return buffer; /* we always return success */
  61. }
  62. #else /* VMS */
  63. #ifdef HAVE_TERMIOS_H
  64. # if !defined(HAVE_TCGETATTR) && !defined(HAVE_TCSETATTR)
  65. # undef HAVE_TERMIOS_H
  66. # endif
  67. #endif
  68. #ifndef RETSIGTYPE
  69. # define RETSIGTYPE void
  70. #endif
  71. #ifdef HAVE_UNISTD_H
  72. #include <unistd.h>
  73. #endif
  74. #include <stdio.h>
  75. #include <signal.h>
  76. #ifdef HAVE_TERMIOS_H
  77. # include <termios.h>
  78. #else
  79. # ifdef HAVE_TERMIO_H
  80. # include <termio.h>
  81. # else
  82. # endif
  83. #endif
  84. /* The last #include file should be: */
  85. #ifdef MALLOCDEBUG
  86. #include "memdebug.h"
  87. #endif
  88. char *getpass_r(const char *prompt, char *buffer, size_t buflen)
  89. {
  90. FILE *infp;
  91. char infp_fclose = 0;
  92. FILE *outfp;
  93. RETSIGTYPE (*sigint)();
  94. #ifndef __EMX__
  95. RETSIGTYPE (*sigtstp)();
  96. #endif
  97. size_t bytes_read;
  98. int infd;
  99. int outfd;
  100. #ifdef HAVE_TERMIOS_H
  101. struct termios orig;
  102. struct termios noecho;
  103. #else
  104. # ifdef HAVE_TERMIO_H
  105. struct termio orig;
  106. struct termio noecho;
  107. # else
  108. # endif
  109. #endif
  110. sigint = signal(SIGINT, SIG_IGN);
  111. /* 20000318 mgs
  112. * this is needed by the emx system, SIGTSTP is not a supported signal */
  113. #ifndef __EMX__
  114. sigtstp = signal(SIGTSTP, SIG_IGN);
  115. #endif
  116. infp=fopen("/dev/tty", "r");
  117. if( NULL == infp )
  118. infp = stdin;
  119. else
  120. infp_fclose = 1;
  121. outfp = stderr;
  122. infd = fileno(infp);
  123. outfd = fileno(outfp);
  124. /* dissable echo */
  125. #ifdef HAVE_TERMIOS_H
  126. tcgetattr(outfd, &orig);
  127. noecho = orig;
  128. noecho.c_lflag &= ~ECHO;
  129. tcsetattr(outfd, TCSANOW, &noecho);
  130. #else
  131. # ifdef HAVE_TERMIO_H
  132. ioctl(outfd, TCGETA, &orig);
  133. noecho = orig;
  134. noecho.c_lflag &= ~ECHO;
  135. ioctl(outfd, TCSETA, &noecho);
  136. # else
  137. # endif
  138. #endif
  139. fputs(prompt, outfp);
  140. fflush(outfp);
  141. bytes_read=read(infd, buffer, buflen);
  142. buffer[bytes_read > 0 ? (bytes_read -1) : 0] = '\0';
  143. /* print a new line if needed */
  144. #ifdef HAVE_TERMIOS_H
  145. fputs("\n", outfp);
  146. #else
  147. # ifdef HAVE_TERMIO_H
  148. fputs("\n", outfp);
  149. # else
  150. # endif
  151. #endif
  152. /*
  153. * reset term charectaristics, use TCSAFLUSH incase the
  154. * user types more than buflen
  155. */
  156. #ifdef HAVE_TERMIOS_H
  157. tcsetattr(outfd, TCSAFLUSH, &orig);
  158. #else
  159. # ifdef HAVE_TERMIO_H
  160. ioctl(outfd, TCSETA, &orig);
  161. # else
  162. # endif
  163. #endif
  164. signal(SIGINT, sigint);
  165. #ifndef __EMX__
  166. signal(SIGTSTP, sigtstp);
  167. #endif
  168. if(infp_fclose)
  169. fclose(infp);
  170. return buffer; /* we always return success */
  171. }
  172. #endif /* VMS */
  173. #else /* WIN32 */
  174. #include <stdio.h>
  175. #include <conio.h>
  176. char *getpass_r(const char *prompt, char *buffer, int buflen)
  177. {
  178. int i;
  179. printf("%s", prompt);
  180. for(i=0; i<buflen; i++) {
  181. buffer[i] = getch();
  182. if ( buffer[i] == '\r' ) {
  183. buffer[i] = 0;
  184. break;
  185. }
  186. }
  187. /* if user didn't hit ENTER, terminate buffer */
  188. if (i==buflen)
  189. buffer[buflen-1]=0;
  190. return buffer; /* we always return success */
  191. }
  192. #endif
  193. #endif /* ifndef HAVE_GETPASS_R */
  194. #if 0
  195. /* for consistensy, here's the old-style function: */
  196. char *getpass(const char *prompt)
  197. {
  198. static char buf[256];
  199. return getpass_r(prompt, buf, sizeof(buf));
  200. }
  201. #endif
  202. /*
  203. * local variables:
  204. * eval: (load-file "../curl-mode.el")
  205. * end:
  206. * vim600: fdm=marker
  207. * vim: et sw=2 ts=2 sts=2 tw=78
  208. */