getpass.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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. /* VMS does not work because of warnings on icc */
  53. /* $DESCRIPTOR(ttdesc, "TT");
  54. buffer[0]='\0';
  55. if ((sts = sys$assign(&ttdesc, &chan,0,0)) & 1) {
  56. 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)) {
  57. buffer[iosb.iosb$w_bcnt] = '\0';
  58. }
  59. sts = sys$dassgn(chan);
  60. }
  61. */
  62. return buffer; /* we always return success */
  63. }
  64. #else /* VMS */
  65. #ifdef HAVE_TERMIOS_H
  66. # if !defined(HAVE_TCGETATTR) && !defined(HAVE_TCSETATTR)
  67. # undef HAVE_TERMIOS_H
  68. # endif
  69. #endif
  70. #ifndef RETSIGTYPE
  71. # define RETSIGTYPE void
  72. #endif
  73. #ifdef HAVE_UNISTD_H
  74. #include <unistd.h>
  75. #endif
  76. #include <stdio.h>
  77. #include <signal.h>
  78. #ifdef HAVE_TERMIOS_H
  79. # include <termios.h>
  80. #else
  81. # ifdef HAVE_TERMIO_H
  82. # include <termio.h>
  83. # else
  84. # endif
  85. #endif
  86. /* The last #include file should be: */
  87. #ifdef MALLOCDEBUG
  88. #include "memdebug.h"
  89. #endif
  90. char *getpass_r(const char *prompt, char *buffer, size_t buflen)
  91. {
  92. FILE *infp;
  93. char infp_fclose = 0;
  94. FILE *outfp;
  95. RETSIGTYPE (*sigint)();
  96. #ifndef __EMX__
  97. RETSIGTYPE (*sigtstp)();
  98. #endif
  99. size_t bytes_read;
  100. int infd;
  101. int outfd;
  102. #ifdef HAVE_TERMIOS_H
  103. struct termios orig;
  104. struct termios noecho;
  105. #else
  106. # ifdef HAVE_TERMIO_H
  107. struct termio orig;
  108. struct termio noecho;
  109. # else
  110. # endif
  111. #endif
  112. sigint = signal(SIGINT, SIG_IGN);
  113. /* 20000318 mgs
  114. * this is needed by the emx system, SIGTSTP is not a supported signal */
  115. #ifndef __EMX__
  116. sigtstp = signal(SIGTSTP, SIG_IGN);
  117. #endif
  118. infp=fopen("/dev/tty", "r");
  119. if( NULL == infp )
  120. infp = stdin;
  121. else
  122. infp_fclose = 1;
  123. outfp = stderr;
  124. infd = fileno(infp);
  125. outfd = fileno(outfp);
  126. /* dissable echo */
  127. #ifdef HAVE_TERMIOS_H
  128. tcgetattr(outfd, &orig);
  129. noecho = orig;
  130. noecho.c_lflag &= ~ECHO;
  131. tcsetattr(outfd, TCSANOW, &noecho);
  132. #else
  133. # ifdef HAVE_TERMIO_H
  134. ioctl(outfd, TCGETA, &orig);
  135. noecho = orig;
  136. noecho.c_lflag &= ~ECHO;
  137. ioctl(outfd, TCSETA, &noecho);
  138. # else
  139. # endif
  140. #endif
  141. fputs(prompt, outfp);
  142. fflush(outfp);
  143. bytes_read=read(infd, buffer, buflen);
  144. buffer[bytes_read > 0 ? (bytes_read -1) : 0] = '\0';
  145. /* print a new line if needed */
  146. #ifdef HAVE_TERMIOS_H
  147. fputs("\n", outfp);
  148. #else
  149. # ifdef HAVE_TERMIO_H
  150. fputs("\n", outfp);
  151. # else
  152. # endif
  153. #endif
  154. /*
  155. * reset term charectaristics, use TCSAFLUSH incase the
  156. * user types more than buflen
  157. */
  158. #ifdef HAVE_TERMIOS_H
  159. tcsetattr(outfd, TCSAFLUSH, &orig);
  160. #else
  161. # ifdef HAVE_TERMIO_H
  162. ioctl(outfd, TCSETA, &orig);
  163. # else
  164. # endif
  165. #endif
  166. signal(SIGINT, sigint);
  167. #ifndef __EMX__
  168. signal(SIGTSTP, sigtstp);
  169. #endif
  170. if(infp_fclose)
  171. fclose(infp);
  172. return buffer; /* we always return success */
  173. }
  174. #endif /* VMS */
  175. #else /* WIN32 */
  176. #include <stdio.h>
  177. #include <conio.h>
  178. char *getpass_r(const char *prompt, char *buffer, int buflen)
  179. {
  180. int i;
  181. printf("%s", prompt);
  182. for(i=0; i<buflen; i++) {
  183. buffer[i] = (char)getch();
  184. if ( buffer[i] == '\r' ) {
  185. buffer[i] = 0;
  186. break;
  187. }
  188. }
  189. /* if user didn't hit ENTER, terminate buffer */
  190. if (i==buflen)
  191. buffer[buflen-1]=0;
  192. return buffer; /* we always return success */
  193. }
  194. #endif
  195. #endif /* ifndef HAVE_GETPASS_R */
  196. #if 0
  197. /* for consistensy, here's the old-style function: */
  198. char *getpass(const char *prompt)
  199. {
  200. static char buf[256];
  201. return getpass_r(prompt, buf, sizeof(buf));
  202. }
  203. #endif
  204. /*
  205. * local variables:
  206. * eval: (load-file "../curl-mode.el")
  207. * end:
  208. * vim600: fdm=marker
  209. * vim: et sw=2 ts=2 sts=2 tw=78
  210. */