Commit 2cb65d61 2cb65d612d163e78e2427388bcb9ca150489fa86 by Sergey Poznyakoff

(ifile, ofile): Removed.

(istream, ostream): New streams.
(pop3d_setio,pop3d_init_tls_server): Rewritten using streams.
(pop3d_flush_output,pop3d_is_master): Likewise.
(pop3d_outf,pop3d_readline): Likewise.
(pop3d_deinit_tls_server): Removed.
(pop3d_bye): New function.
1 parent 2a0e6368
...@@ -17,11 +17,7 @@ ...@@ -17,11 +17,7 @@
17 17
18 #include "pop3d.h" 18 #include "pop3d.h"
19 19
20 static FILE *ifile; 20 static stream_t istream, ostream;
21 static FILE *ofile;
22 #ifdef WITH_TLS
23 static gnutls_session sfile;
24 #endif /* WITH_TLS */
25 21
26 /* Takes a string as input and returns either the remainder of the string 22 /* Takes a string as input and returns either the remainder of the string
27 after the first space, or a zero length string if no space */ 23 after the first space, or a zero length string if no space */
...@@ -137,79 +133,101 @@ pop3d_abquit (int reason) ...@@ -137,79 +133,101 @@ pop3d_abquit (int reason)
137 } 133 }
138 134
139 void 135 void
140 pop3d_setio (FILE * in, FILE * out) 136 pop3d_setio (FILE *in, FILE *out)
141 { 137 {
142 if (!in || !out) 138 if (!in || !out)
143 pop3d_abquit (ERR_NO_OFILE); 139 pop3d_abquit (ERR_NO_OFILE);
144 140
145 ifile = in; 141 if (stdio_stream_create (&istream, in, MU_STREAM_NO_CLOSE)
146 ofile = out; 142 || stdio_stream_create (&ostream, out, MU_STREAM_NO_CLOSE))
143 pop3d_abquit (ERR_NO_OFILE);
147 } 144 }
148 145
149 #ifdef WITH_TLS 146 #ifdef WITH_TLS
150
151 int 147 int
152 pop3d_init_tls_server () 148 pop3d_init_tls_server ()
153 { 149 {
154 sfile = 150 stream_t stream;
155 (gnutls_session) mu_init_tls_server (fileno (ifile), fileno (ofile)); 151 int in_fd;
156 if (!sfile) 152 int out_fd;
153 int rc;
154
155 if (stream_get_fd (istream, &in_fd)
156 || stream_get_fd (ostream, &out_fd))
157 return 0;
158 rc = tls_stream_create (&stream, in_fd, out_fd, 0);
159 if (rc)
157 return 0; 160 return 0;
161
162 if (stream_open (stream))
163 {
164 const char *p;
165 stream_strerror (stream, &p);
166 syslog (LOG_ERR, _("cannot open TLS stream: %s"), p);
167 return 0;
168 }
169
170 stream_destroy (&istream, stream_get_owner (istream));
171 stream_destroy (&ostream, stream_get_owner (ostream));
172 istream = ostream = stream;
158 return 1; 173 return 1;
159 } 174 }
175 #endif
160 176
161 void 177 void
162 pop3d_deinit_tls_server () 178 pop3d_bye ()
163 { 179 {
164 mu_deinit_tls_server (sfile); 180 if (istream == ostream)
165 } 181 {
166 182 stream_close (istream);
183 stream_destroy (&istream, stream_get_owner (istream));
184 }
185 /* There's no reason closing in/out streams otherwise */
186 #ifdef WITH_TLS
187 mu_deinit_tls_libs ();
167 #endif /* WITH_TLS */ 188 #endif /* WITH_TLS */
189 }
168 190
169 void 191 void
170 pop3d_flush_output () 192 pop3d_flush_output ()
171 { 193 {
172 fflush (ofile); 194 stream_flush (ostream);
173 } 195 }
174 196
175 int 197 int
176 pop3d_is_master () 198 pop3d_is_master ()
177 { 199 {
178 return ofile == NULL; 200 return ostream == NULL;
179 } 201 }
180 202
181 void 203 void
182 pop3d_outf (const char *fmt, ...) 204 pop3d_outf (const char *fmt, ...)
183 { 205 {
184 va_list ap; 206 va_list ap;
207 char *buf;
208 int rc;
209
185 va_start (ap, fmt); 210 va_start (ap, fmt);
211 vasprintf (&buf, fmt, ap);
212 va_end (ap);
213
214 if (!buf)
215 pop3d_abquit (ERR_NO_MEM);
216
186 if (daemon_param.transcript) 217 if (daemon_param.transcript)
187 { 218 syslog (LOG_DEBUG, "sent: %s", buf);
188 char *buf;
189 vasprintf (&buf, fmt, ap);
190 if (buf)
191 {
192 syslog (LOG_DEBUG, "sent: %s", buf);
193 free (buf);
194 }
195 }
196 219
197 #ifdef WITH_TLS 220 rc = stream_sequential_write (ostream, buf, strlen (buf));
198 if (tls_done) 221 free (buf);
222 if (rc)
199 { 223 {
200 char *buf; 224 const char *p;
201 vasprintf (&buf, fmt, ap);
202 if (buf)
203 {
204 gnutls_record_send (sfile, buf, strlen (buf));
205 free (buf);
206 }
207 }
208 else
209 #endif /* WITH_TLS */
210 vfprintf (ofile, fmt, ap);
211 225
212 va_end (ap); 226 if (stream_strerror (ostream, &p))
227 p = strerror (errno);
228 syslog (LOG_ERR, _("write failed: %s"), p);
229 pop3d_abquit (ERR_NO_OFILE);
230 }
213 } 231 }
214 232
215 233
...@@ -217,36 +235,26 @@ pop3d_outf (const char *fmt, ...) ...@@ -217,36 +235,26 @@ pop3d_outf (const char *fmt, ...)
217 char * 235 char *
218 pop3d_readline (char *buffer, size_t size) 236 pop3d_readline (char *buffer, size_t size)
219 { 237 {
220 char *ptr; 238 int rc;
221 239 size_t nbytes;
240
222 alarm (daemon_param.timeout); 241 alarm (daemon_param.timeout);
223 #ifdef WITH_TLS 242 rc = stream_sequential_readline (istream, buffer, size, &nbytes);
224 if (tls_done)
225 {
226 int rc = gnutls_record_recv (sfile, buffer, size - 1);
227 if (rc < 0)
228 {
229 syslog (LOG_ERR, _("TLS error on read: %s"),
230 gnutls_strerror (rc));
231 pop3d_abquit (ERR_TLS_IO);
232 }
233 else
234 buffer[rc] = 0;
235 ptr = buffer;
236 }
237 else
238 #endif /* WITH_TLS */
239 ptr = fgets (buffer, size, ifile);
240 alarm (0); 243 alarm (0);
241 244
242 /* We should probably check ferror() too, but if ptr is null we 245 if (rc)
243 are done anyway; if (!ptr && ferror(ifile)) */ 246 {
244 if (!ptr) 247 const char *p;
245 pop3d_abquit (ERR_NO_OFILE); 248
249 if (stream_strerror (ostream, &p))
250 p = strerror (errno);
251 syslog (LOG_ERR, _("write failed: %s"), p);
252 pop3d_abquit (ERR_NO_OFILE);
253 }
246 254
247 if (daemon_param.transcript) 255 if (daemon_param.transcript)
248 syslog (LOG_DEBUG, "recv: %s", ptr); 256 syslog (LOG_DEBUG, "recv: %s", buffer);
249 257
250 /* Caller should not free () this ... should we strdup() then? */ 258 /* Caller should not free () this ... should we strdup() then? */
251 return ptr; 259 return buffer;
252 } 260 }
......