getpass.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /* ============================================================================
  2. * Copyright (C) 1998 Angus Mackay. All rights reserved;
  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. /* no perror? make an fprintf! */
  89. #ifndef HAVE_PERROR
  90. # define perror(x) fprintf(stderr, "Error in: %s\n", x)
  91. #endif
  92. char *getpass_r(const char *prompt, char *buffer, size_t buflen)
  93. {
  94. FILE *infp;
  95. FILE *outfp;
  96. RETSIGTYPE (*sigint)();
  97. #ifndef __EMX__
  98. RETSIGTYPE (*sigtstp)();
  99. #endif
  100. size_t bytes_read;
  101. int infd;
  102. int outfd;
  103. #ifdef HAVE_TERMIOS_H
  104. struct termios orig;
  105. struct termios noecho;
  106. #else
  107. # ifdef HAVE_TERMIO_H
  108. struct termio orig;
  109. struct termio noecho;
  110. # else
  111. # endif
  112. #endif
  113. sigint = signal(SIGINT, SIG_IGN);
  114. /* 20000318 mgs
  115. * this is needed by the emx system, SIGTSTP is not a supported signal */
  116. #ifndef __EMX__
  117. sigtstp = signal(SIGTSTP, SIG_IGN);
  118. #endif
  119. if( (infp=fopen("/dev/tty", "r")) == NULL )
  120. {
  121. infp = stdin;
  122. }
  123. if( (outfp=fopen("/dev/tty", "w")) == NULL )
  124. {
  125. outfp = stderr;
  126. }
  127. infd = fileno(infp);
  128. outfd = fileno(outfp);
  129. /* dissable echo */
  130. #ifdef HAVE_TERMIOS_H
  131. if(tcgetattr(outfd, &orig) != 0)
  132. {
  133. ; /*perror("tcgetattr");*/
  134. }
  135. noecho = orig;
  136. noecho.c_lflag &= ~ECHO;
  137. if(tcsetattr(outfd, TCSANOW, &noecho) != 0)
  138. {
  139. ; /*perror("tcgetattr");*/
  140. }
  141. #else
  142. # ifdef HAVE_TERMIO_H
  143. if(ioctl(outfd, TCGETA, &orig) != 0)
  144. {
  145. ; /*perror("ioctl");*/
  146. }
  147. noecho = orig;
  148. noecho.c_lflag &= ~ECHO;
  149. if(ioctl(outfd, TCSETA, &noecho) != 0)
  150. {
  151. ; /*perror("ioctl");*/
  152. }
  153. # else
  154. # endif
  155. #endif
  156. fputs(prompt, outfp);
  157. fflush(outfp);
  158. bytes_read=read(infd, buffer, buflen);
  159. buffer[bytes_read > 0 ? (bytes_read -1) : 0] = '\0';
  160. /* print a new line if needed */
  161. #ifdef HAVE_TERMIOS_H
  162. fputs("\n", outfp);
  163. #else
  164. # ifdef HAVE_TERMIO_H
  165. fputs("\n", outfp);
  166. # else
  167. # endif
  168. #endif
  169. /*
  170. * reset term charectaristics, use TCSAFLUSH incase the
  171. * user types more than buflen
  172. */
  173. #ifdef HAVE_TERMIOS_H
  174. if(tcsetattr(outfd, TCSAFLUSH, &orig) != 0)
  175. {
  176. ; /*perror("tcgetattr");*/
  177. }
  178. #else
  179. # ifdef HAVE_TERMIO_H
  180. if(ioctl(outfd, TCSETA, &orig) != 0)
  181. {
  182. ; /*perror("ioctl");*/
  183. }
  184. # else
  185. # endif
  186. #endif
  187. signal(SIGINT, sigint);
  188. #ifndef __EMX__
  189. signal(SIGTSTP, sigtstp);
  190. #endif
  191. return buffer; /* we always return success */
  192. }
  193. #endif /* VMS */
  194. #else /* WIN32 */
  195. #include <stdio.h>
  196. #include <conio.h>
  197. char *getpass_r(const char *prompt, char *buffer, int buflen)
  198. {
  199. int i;
  200. printf("%s", prompt);
  201. for(i=0; i<buflen; i++) {
  202. buffer[i] = getch();
  203. if ( buffer[i] == '\r' ) {
  204. buffer[i] = 0;
  205. break;
  206. }
  207. }
  208. /* if user didn't hit ENTER, terminate buffer */
  209. if (i==buflen)
  210. buffer[buflen-1]=0;
  211. return buffer; /* we always return success */
  212. }
  213. #endif
  214. #endif /* ifndef HAVE_GETPASS_R */
  215. #if 0
  216. /* for consistensy, here's the old-style function: */
  217. char *getpass(const char *prompt)
  218. {
  219. static char buf[256];
  220. return getpass_r(prompt, buf, sizeof(buf));
  221. }
  222. #endif
  223. /*
  224. * local variables:
  225. * eval: (load-file "../curl-mode.el")
  226. * end:
  227. * vim600: fdm=marker
  228. * vim: et sw=2 ts=2 sts=2 tw=78
  229. */