/* ======================================================================== * Copyright 2008 Mark Crispin * ======================================================================== */ /* * Program: SSL standard I/O routines for server use * * Author: Mark Crispin * * Date: 22 September 1998 * Last Edited: 19 November 2008 * * Previous versions of this file were * * Copyright 1988-2006 University of Washington * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * */ /* Get character * Returns: character or EOF */ int PBIN (void) { if (!sslstdio) { int ret; do { clearerr (stdin); ret = getchar (); } while ((ret == EOF) && !feof (stdin) && ferror (stdin) && (errno == EINTR)); return ret; } if (!ssl_getdata (sslstdio->sslstream)) return EOF; /* one last byte available */ sslstdio->sslstream->ictr--; return (int) *(sslstdio->sslstream->iptr)++; } /* Get string * Accepts: destination string pointer * number of bytes available * Returns: destination string pointer or NIL if EOF */ char *PSIN (char *s,int n) { int i,c; if (start_tls) { /* doing a start TLS? */ ssl_server_init (start_tls);/* enter the mode */ start_tls = NIL; /* don't do this again */ } if (!sslstdio) { char *ret; do { clearerr (stdin); ret = fgets (s,n,stdin); } while (!ret && !feof (stdin) && ferror (stdin) && (errno == EINTR)); return ret; } for (i = c = 0, n-- ; (c != '\n') && (i < n); sslstdio->sslstream->ictr--) { if ((sslstdio->sslstream->ictr <= 0) && !ssl_getdata (sslstdio->sslstream)) return NIL; /* read error */ c = s[i++] = *(sslstdio->sslstream->iptr)++; } s[i] = '\0'; /* tie off string */ return s; } /* Get record * Accepts: destination string pointer * number of bytes to read * Returns: T if success, NIL otherwise */ long PSINR (char *s,unsigned long n) { unsigned long i; if (start_tls) { /* doing a start TLS? */ ssl_server_init (start_tls);/* enter the mode */ start_tls = NIL; /* don't do this again */ } if (sslstdio) return ssl_getbuffer (sslstdio->sslstream,n,s); /* non-SSL case */ while (n && ((i = fread (s,1,n,stdin)) || (errno == EINTR))) s += i,n -= i; return n ? NIL : LONGT; } /* Wait for stdin input * Accepts: timeout in seconds * Returns: T if have input on stdin, else NIL */ long INWAIT (long seconds) { return (sslstdio ? ssl_server_input_wait : server_input_wait) (seconds); } /* Put character * Accepts: character * Returns: character written or EOF */ int PBOUT (int c) { if (!sslstdio) return putchar (c); /* flush buffer if full */ if (!sslstdio->octr && PFLUSH ()) return EOF; sslstdio->octr--; /* count down one character */ *sslstdio->optr++ = c; /* write character */ return c; /* return that character */ } /* Put string * Accepts: destination string pointer * Returns: 0 or EOF if error */ int PSOUT (char *s) { if (!sslstdio) return fputs (s,stdout); while (*s) { /* flush buffer if full */ if (!sslstdio->octr && PFLUSH ()) return EOF; *sslstdio->optr++ = *s++; /* write one more character */ sslstdio->octr--; /* count down one character */ } return 0; /* success */ } /* Put record * Accepts: source sized text * Returns: 0 or EOF if error */ int PSOUTR (SIZEDTEXT *s) { unsigned char *t = s->data; unsigned long i = s->size; unsigned long j; if (sslstdio) while (i) { /* until request satisfied */ /* flush buffer if full */ if (!sslstdio->octr && PFLUSH ()) break; /* blat as big a chucnk as we can */ memcpy (sslstdio->optr,t,j = min (i,sslstdio->octr)); sslstdio->optr += j; /* account for chunk */ sslstdio->octr -= j; t += j; i -= j; } else while (i && ((j = fwrite (t,1,i,stdout)) || (errno == EINTR))) t += j,i -= j; return i ? EOF : NIL; } /* Flush output * Returns: 0 or EOF if error */ int PFLUSH (void) { if (!sslstdio) return fflush (stdout); /* force out buffer */ if (!ssl_sout (sslstdio->sslstream,sslstdio->obuf, SSLBUFLEN - sslstdio->octr)) return EOF; /* renew output buffer */ sslstdio->optr = sslstdio->obuf; sslstdio->octr = SSLBUFLEN; return 0; /* success */ }