Commit 594d8574 594d8574f36387da2ac1bc819d2193f999f73cfe by Alain Magloire

* mailbox2/stream.c: stream_read() and stream_write()

	change prototype to be void * instead of char *.
	* mailbox2/bstream.c: Adjust bstream_{read,write} to the
	new prototypes.
	* mailbox2/pop3/pop3_stream.c: Likewised.
	* mailbox2/Makefile.am: New file.
	* mailbox2/pop3/Makefile.am: New file.
	* mailbox2/mstream.c: Mapfile stream Implementation.
	* mailbox2/fstream.c: File stream implementation.
	* mailbox2/include/mailutils/sys/fstream.h: New file.
	* mailbox2/include/mailutils/sys/mstream.h: New file.
	* mailbox2/tcp.c: rename to tcpstream.c.
	* mailbox2/include/mailutils/sys/tcp.h: Rename to tcpstream.h
1 parent 2ca6f6be
1 # Use automake to process this file -*-Makefile-*-
2
3 AUTOMAKE_OPTIONS = ../lib/ansi2knr
4
5 #INCLUDES = -I${top_srcdir}/include
6 INCLUDES = -I${top_srcdir}/mailbox2/include
7
8 SUBDIRS = include pop3 mbox
9
10
11 lib_LTLIBRARIES = libmailbox.la
12
13 libmailbox_la_SOURCES = \
14 bstream.c \
15 fstream.c \
16 iterator.c \
17 md5-rsa.c \
18 mstream.c \
19 stream.c \
20 tcp.c
...@@ -118,7 +118,7 @@ _bs_close (stream_t stream) ...@@ -118,7 +118,7 @@ _bs_close (stream_t stream)
118 networking. Lots of code between POP and IMAP can be share this way. 118 networking. Lots of code between POP and IMAP can be share this way.
119 The buffering is on the read only, the writes fall through. */ 119 The buffering is on the read only, the writes fall through. */
120 static int 120 static int
121 _bs_read (stream_t stream, char *buf, size_t count, size_t *pnread) 121 _bs_read (stream_t stream, void *buf, size_t count, size_t *pnread)
122 { 122 {
123 int status = 0; 123 int status = 0;
124 struct _bs *bs = (struct _bs *)stream; 124 struct _bs *bs = (struct _bs *)stream;
...@@ -138,6 +138,7 @@ _bs_read (stream_t stream, char *buf, size_t count, size_t *pnread) ...@@ -138,6 +138,7 @@ _bs_read (stream_t stream, char *buf, size_t count, size_t *pnread)
138 else 138 else
139 { 139 {
140 size_t residue = count; 140 size_t residue = count;
141 char *p = buf;
141 int r; 142 int r;
142 143
143 monitor_lock (bs->lock); 144 monitor_lock (bs->lock);
...@@ -151,12 +152,12 @@ _bs_read (stream_t stream, char *buf, size_t count, size_t *pnread) ...@@ -151,12 +152,12 @@ _bs_read (stream_t stream, char *buf, size_t count, size_t *pnread)
151 /* Drain our buffer first. */ 152 /* Drain our buffer first. */
152 if (bs->rbuffer.count > 0) 153 if (bs->rbuffer.count > 0)
153 { 154 {
154 memcpy(buf, bs->rbuffer.ptr, bs->rbuffer.count); 155 memcpy(p, bs->rbuffer.ptr, bs->rbuffer.count);
155 residue -= bs->rbuffer.count; 156 residue -= bs->rbuffer.count;
156 buf += bs->rbuffer.count; 157 p += bs->rbuffer.count;
157 } 158 }
158 bs->rbuffer.count = 0; /* Signal we will need to refill. */ 159 bs->rbuffer.count = 0; /* Signal we will need to refill. */
159 status = stream_read (bs->stream, buf, residue, &r); 160 status = stream_read (bs->stream, p, residue, &r);
160 residue -= r; 161 residue -= r;
161 if (pnread) 162 if (pnread)
162 *pnread = count - residue; 163 *pnread = count - residue;
...@@ -172,10 +173,10 @@ _bs_read (stream_t stream, char *buf, size_t count, size_t *pnread) ...@@ -172,10 +173,10 @@ _bs_read (stream_t stream, char *buf, size_t count, size_t *pnread)
172 /* Drain the buffer, if we have less then requested. */ 173 /* Drain the buffer, if we have less then requested. */
173 while (residue > (size_t)(r = bs->rbuffer.count)) 174 while (residue > (size_t)(r = bs->rbuffer.count))
174 { 175 {
175 (void)memcpy (buf, bs->rbuffer.ptr, (size_t)r); 176 (void)memcpy (p, bs->rbuffer.ptr, (size_t)r);
176 bs->rbuffer.ptr += r; 177 bs->rbuffer.ptr += r;
177 /* bs->rbuffer.count = 0 ... done in refill */ 178 /* bs->rbuffer.count = 0 ... done in refill */
178 buf += r; 179 p += r;
179 residue -= r; 180 residue -= r;
180 status = refill (bs); 181 status = refill (bs);
181 /* Did we reach the end. */ 182 /* Did we reach the end. */
...@@ -192,7 +193,7 @@ _bs_read (stream_t stream, char *buf, size_t count, size_t *pnread) ...@@ -192,7 +193,7 @@ _bs_read (stream_t stream, char *buf, size_t count, size_t *pnread)
192 } 193 }
193 if (!done) 194 if (!done)
194 { 195 {
195 memcpy(buf, bs->rbuffer.ptr, residue); 196 memcpy(p, bs->rbuffer.ptr, residue);
196 bs->rbuffer.count -= residue; 197 bs->rbuffer.count -= residue;
197 bs->rbuffer.ptr += residue; 198 bs->rbuffer.ptr += residue;
198 if (pnread) 199 if (pnread)
...@@ -290,23 +291,24 @@ _bs_readline (stream_t stream, char *buf, size_t count, size_t *pnread) ...@@ -290,23 +291,24 @@ _bs_readline (stream_t stream, char *buf, size_t count, size_t *pnread)
290 } 291 }
291 292
292 static int 293 static int
293 _bs_write (stream_t stream, const char *buf, size_t count, size_t *pnwrite) 294 _bs_write (stream_t stream, const void *buf, size_t count, size_t *pnwrite)
294 { 295 {
295 struct _bs *bs = (struct _bs *)stream; 296 struct _bs *bs = (struct _bs *)stream;
296 int err = 0; 297 int err = 0;
297 size_t nwriten = 0; 298 size_t nwriten = 0;
298 size_t total = 0; 299 size_t total = 0;
299 int nleft = count; 300 int nleft = count;
301 const char *p = buf;
300 302
301 /* First try to send it all. */ 303 /* First try to send it all. */
302 while (nleft > 0) 304 while (nleft > 0)
303 { 305 {
304 err = stream_write (bs->stream, buf, nleft, &nwriten); 306 err = stream_write (bs->stream, p, nleft, &nwriten);
305 if (err != 0 || nwriten == 0) 307 if (err != 0 || nwriten == 0)
306 break; 308 break;
307 nleft -= nwriten; 309 nleft -= nwriten;
308 total += nwriten; 310 total += nwriten;
309 buf += nwriten; 311 p += nwriten;
310 } 312 }
311 if (pnwrite) 313 if (pnwrite)
312 *pnwrite = total; 314 *pnwrite = total;
......
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Library Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31
32 #include <mailutils/sys/fstream.h>
33 #include <mailutils/error.h>
34
35
36 static int
37 _fs_add_ref (stream_t stream)
38 {
39 struct _fs *fs = (struct _fs *)stream;
40 int status;
41 monitor_lock (fs->lock);
42 status = ++fs->ref;
43 monitor_unlock (fs->lock);
44 return status;
45 }
46
47 static int
48 _fs_destroy (stream_t stream)
49 {
50 struct _fs *fs = (struct _fs *)stream;
51 if (fs->file)
52 fclose (fs->file);
53 monitor_destroy (fs->lock);
54 free (fs);
55 return 0;
56 }
57
58 static int
59 _fs_release (stream_t stream)
60 {
61 int status;
62 struct _fs *fs = (struct _fs *)stream;
63 monitor_lock (fs->lock);
64 status = --fs->ref;
65 if (status <= 0)
66 {
67 monitor_unlock (fs->lock);
68 _fs_destroy (stream);
69 return 0;
70 }
71 monitor_unlock (fs->lock);
72 return status;
73 }
74
75 static int
76 _fs_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
77 {
78 struct _fs *fs = (struct _fs *)stream;
79 size_t n;
80 int err = 0;
81
82 if (fs->file)
83 {
84 n = fread (optr, 1, osize, fs->file);
85 if (n == 0)
86 {
87 if (ferror(fs->file))
88 err = MU_ERROR_IO;
89 }
90 }
91
92 if (nbytes)
93 *nbytes = n;
94 return err;
95 }
96
97 static int
98 _fs_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
99 {
100 struct _fs *fs = (struct _fs *)stream;
101 size_t n = 0;
102 int err = 0;
103
104 if (fs->file)
105 {
106 if (fgets (optr, osize, fs->file) != NULL)
107 {
108 n = strlen (optr);
109 }
110 else
111 {
112 if (ferror (fs->file))
113 err = MU_ERROR_IO;
114 }
115 }
116
117 if (nbytes)
118 *nbytes = n;
119 return err;
120 }
121
122 static int
123 _fs_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes)
124 {
125 struct _fs *fs = (struct _fs *)stream;
126 size_t n;
127 int err = 0;
128
129 if (fs->file)
130 {
131 n = fwrite (iptr, 1, isize, fs->file);
132 if (n != isize)
133 {
134 if (feof (fs->file) == 0)
135 err = MU_ERROR_IO;
136 clearerr(fs->file);
137 n = 0;
138 }
139 }
140
141 if (nbytes)
142 *nbytes = n;
143 return err;
144 }
145
146 static int
147 _fs_truncate (stream_t stream, off_t len)
148 {
149 struct _fs *fs = (struct _fs *)stream;
150 if (fs->file && ftruncate (fileno(fs->file), len) != 0)
151 return MU_ERROR_IO;
152 return 0;
153 }
154
155 static int
156 _fs_get_size (stream_t stream, off_t *psize)
157 {
158 struct _fs *fs = (struct _fs *)stream;
159 struct stat stbuf;
160 stbuf.st_size = 0;
161 if (fs->file)
162 {
163 fflush (fs->file);
164 if (fstat(fileno(fs->file), &stbuf) == -1)
165 return errno;
166 }
167 if (psize)
168 *psize = stbuf.st_size;
169 return 0;
170 }
171
172 static int
173 _fs_flush (stream_t stream)
174 {
175 struct _fs *fs = (struct _fs *)stream;
176 if (fs->file)
177 return fflush (fs->file);
178 return 0;
179 }
180
181 static int
182 _fs_get_fd (stream_t stream, int *pfd)
183 {
184 struct _fs *fs = (struct _fs *)stream;
185 int status = 0;
186 if (pfd)
187 {
188 if (fs->file)
189 *pfd = fileno (fs->file);
190 else
191 status = MU_ERROR_INVALID_PARAMETER;
192 }
193 return status;
194 }
195
196 static int
197 _fs_seek (stream_t stream, off_t off, enum stream_whence whence)
198 {
199 struct _fs *fs = (struct _fs *)stream;
200 int err = 0;
201 if (fs->file)
202 {
203 errno = MU_ERROR_INVALID_PARAMETER;
204 if (whence == MU_STREAM_WHENCE_SET)
205 err = fseek (fs->file, off, SEEK_SET);
206 else if (whence == MU_STREAM_WHENCE_CUR)
207 err = fseek (fs->file, off, SEEK_CUR);
208 else if (whence == MU_STREAM_WHENCE_END)
209 err = fseek (fs->file, off, SEEK_END);
210 else
211 err = MU_ERROR_INVALID_PARAMETER;
212 if (err != 0)
213 err = errno;
214 }
215 return err;
216 }
217
218 static int
219 _fs_tell (stream_t stream, off_t *off)
220 {
221 struct _fs *fs = (struct _fs *)stream;
222 if (off == NULL)
223 return MU_ERROR_INVALID_PARAMETER;
224 *off = (fs->file) ? ftell (fs->file) : 0;
225 return 0;
226 }
227
228 static int
229 _fs_get_flags (stream_t stream, int *flags)
230 {
231 struct _fs *fs = (struct _fs *)stream;
232 if (flags == NULL)
233 return MU_ERROR_INVALID_PARAMETER;
234 *flags = fs->flags;
235 return 0;
236 }
237
238 static int
239 _fs_get_state (stream_t stream, enum stream_state *state)
240 {
241 (void)stream;
242 if (state == NULL)
243 return MU_ERROR_INVALID_PARAMETER;
244 *state = MU_STREAM_NO_STATE;
245 return 0;
246 }
247
248 static int
249 _fs_close (stream_t stream)
250 {
251 struct _fs *fs = (struct _fs *)stream;
252 int err = 0;
253 if (fs->file)
254 {
255 if (fclose (fs->file) != 0)
256 err = errno;
257 fs->file = NULL;
258 }
259 return err;
260 }
261
262 static int
263 _fs_open (stream_t stream, const char *filename, int port, int flags)
264 {
265 struct _fs *fs = (struct _fs *)stream;
266 int flg;
267 int fd;
268 const char *mode;
269
270 (void)port; /* Ignored. */
271
272 if (fs->file)
273 {
274 fclose (fs->file);
275 fs->file = NULL;
276 }
277
278 /* Map the flags to the system equivalent. */
279 if (flags & MU_STREAM_WRITE && flags & MU_STREAM_READ)
280 return EINVAL;
281 else if (flags & MU_STREAM_WRITE)
282 flg = O_WRONLY;
283 else if (flags & MU_STREAM_RDWR)
284 flg = O_RDWR;
285 else /* default */
286 flg = O_RDONLY;
287
288 /* Local folders should not block it is local disk ???
289 We simply ignore the O_NONBLOCK flag
290 But take care of the APPEND. */
291 if (flags & MU_STREAM_APPEND)
292 flg |= O_APPEND;
293
294 /* Handle CREAT with care, not to follow symlinks. */
295 if (flags & MU_STREAM_CREAT)
296 {
297 /* First see if the file already exists. */
298 fd = open(filename, flg);
299 if (fd == -1)
300 {
301 /* Oops bail out. */
302 if (errno != ENOENT)
303 return errno;
304 /* Race condition here when creating the file ??. */
305 fd = open(filename, flg|O_CREAT|O_EXCL, 0600);
306 if (fd < 0)
307 return errno;
308 }
309 }
310 else
311 {
312 fd = open (filename, flg);
313 if (fd < 0)
314 return errno;
315 }
316
317 /* We have to make sure that We did not open
318 a symlink. From Casper D. in bugtraq. */
319 if ((flg & MU_STREAM_CREAT) ||
320 (flg & MU_STREAM_RDWR) ||
321 (flg & MU_STREAM_WRITE))
322 {
323 struct stat fdbuf, filebuf;
324
325 /* The next two stats should never fail. */
326 if (fstat(fd, &fdbuf) == -1)
327 return errno;
328 if (lstat(filename, &filebuf) == -1)
329 return errno;
330
331 /* Now check that: file and fd reference the same file,
332 file only has one link, file is plain file. */
333 if (fdbuf.st_dev != filebuf.st_dev
334 || fdbuf.st_ino != filebuf.st_ino
335 || fdbuf.st_nlink != 1
336 || filebuf.st_nlink != 1
337 || (fdbuf.st_mode & S_IFMT) != S_IFREG)
338 {
339 mu_error ("%s must be a plain file with one link\n", filename);
340 close (fd);
341 return EINVAL;
342 }
343 }
344 /* We use FILE * object. */
345 if (flags & MU_STREAM_APPEND)
346 mode = "a";
347 else if (flags & MU_STREAM_RDWR)
348 mode = "r+b";
349 else if (flags & MU_STREAM_WRITE)
350 mode = "wb";
351 else /* Default readonly. */
352 mode = "rb";
353
354 fs->file = fdopen (fd, mode);
355 if (fs->file == NULL)
356 {
357 int ret = errno;
358 free (fs);
359 return ret;
360 }
361 fs->flags = flags;
362 return 0;
363 }
364
365 static struct _stream_vtable _fs_vtable =
366 {
367 _fs_add_ref,
368 _fs_release,
369 _fs_destroy,
370
371 _fs_open,
372 _fs_close,
373
374 _fs_read,
375 _fs_readline,
376 _fs_write,
377
378 _fs_seek,
379 _fs_tell,
380
381 _fs_get_size,
382 _fs_truncate,
383 _fs_flush,
384
385 _fs_get_fd,
386 _fs_get_flags,
387 _fs_get_state
388 };
389
390 int
391 stream_file_create (stream_t *pstream)
392 {
393 struct _fs *fs;
394
395 if (pstream == NULL)
396 return MU_ERROR_INVALID_PARAMETER;
397
398 fs = calloc (1, sizeof *fs);
399 if (fs == NULL)
400 return MU_ERROR_NO_MEMORY ;
401
402 fs->base.vtable = &_fs_vtable;
403 fs->ref = 1;
404 fs->file = NULL;
405 fs->flags = 0;
406 *pstream = &fs->base;
407 return 0;
408 }
...@@ -34,9 +34,23 @@ extern int mbox_uidnext __P ((mbox_t, unsigned long)); ...@@ -34,9 +34,23 @@ extern int mbox_uidnext __P ((mbox_t, unsigned long));
34 extern int mbox_open __P ((mbox_t, const char *, int)); 34 extern int mbox_open __P ((mbox_t, const char *, int));
35 extern int mbox_close __P ((mbox_t)); 35 extern int mbox_close __P ((mbox_t));
36 36
37 extern int mbox_get_message __P ((mbox_t, unsigned int, message_t *)); 37 extern int mbox_get_envelope __P ((mbox_t, unsigned int, envelope_t *));
38 extern int mbox_set_envelope __P ((mbox_t, unsigned int, envelope_t));
38 39
39 extern int mbox_get_size __P ((mbox_t, unsigned long *)); 40 extern int mbox_get_header __P ((mbox_t, unsigned int, stream_t *));
41 extern int mbox_set_header __P ((mbox_t, unsigned int, stream_t));
42 extern int mbox_header_size __P ((mbox_t, unsigned int, size_t *));
43 extern int mbox_hdr_get_value __P ((mbox_t, unsigned int, char *, size_t, size_t *));
44 extern int mbox_hdr_set_value __P ((mbox_t, unsigned int, char *, size_t, int));
45
46 extern int mbox_get_body __P ((mbox_t, unsigned int, stream_t *));
47 extern int mbox_set_body __P ((mbox_t, unsigned int, stream_t));
48 extern int mbox_body_size __P ((mbox_t, unsigned int, size_t *));
49
50 extern int mbox_get_flags __P ((mbox_t, unsigned int, int *));
51 extern int mbox_set_flags __P ((mbox_t, unsigned int, int));
52
53 extern int mbox_size __P ((mbox_t, unsigned long *));
40 54
41 extern int mbox_save_attributes __P ((mbox_t)); 55 extern int mbox_save_attributes __P ((mbox_t));
42 extern int mbox_expunge __P ((mbox_t)); 56 extern int mbox_expunge __P ((mbox_t));
......
...@@ -53,9 +53,9 @@ extern int stream_destroy __P ((stream_t)); ...@@ -53,9 +53,9 @@ extern int stream_destroy __P ((stream_t));
53 extern int stream_open __P ((stream_t, const char *, int, int)); 53 extern int stream_open __P ((stream_t, const char *, int, int));
54 extern int stream_close __P ((stream_t)); 54 extern int stream_close __P ((stream_t));
55 55
56 extern int stream_read __P ((stream_t, char *, size_t, size_t *)); 56 extern int stream_read __P ((stream_t, void *, size_t, size_t *));
57 extern int stream_readline __P ((stream_t, char *, size_t, size_t *)); 57 extern int stream_readline __P ((stream_t, char *, size_t, size_t *));
58 extern int stream_write __P ((stream_t, const char *, size_t, size_t*)); 58 extern int stream_write __P ((stream_t, const void *, size_t, size_t*));
59 59
60 extern int stream_seek __P ((stream_t, off_t, enum stream_whence)); 60 extern int stream_seek __P ((stream_t, off_t, enum stream_whence));
61 extern int stream_tell __P ((stream_t, off_t *)); 61 extern int stream_tell __P ((stream_t, off_t *));
......
...@@ -15,8 +15,8 @@ ...@@ -15,8 +15,8 @@
15 along with this program; if not, write to the Free Software 15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17 17
18 #ifndef MAILUTILS_SYS_TCP_H 18 #ifndef MAILUTILS_SYS_BSTREAM_H
19 #define MAILUTILS_SYS_TCP_H 19 #define MAILUTILS_SYS_BSTREAM_H
20 20
21 #include <mailutils/sys/stream.h> 21 #include <mailutils/sys/stream.h>
22 #include <mailutils/monitor.h> 22 #include <mailutils/monitor.h>
...@@ -39,4 +39,4 @@ struct _bs ...@@ -39,4 +39,4 @@ struct _bs
39 monitor_t lock; 39 monitor_t lock;
40 }; 40 };
41 41
42 #endif /* _MAILUTILS_SYS_TCP_H */ 42 #endif /* _MAILUTILS_SYS_BSTREAM_H */
......
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Library General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifndef MAILUTILS_SYS_FSTREAM_H
19 #define MAILUTILS_SYS_FSTREAM_H
20
21 #include <mailutils/sys/stream.h>
22 #include <mailutils/monitor.h>
23
24 struct _fs
25 {
26 struct _stream base;
27 int ref;
28 int flags;
29 FILE *file;
30 monitor_t lock;
31 };
32
33 #endif /* _MAILUTILS_SYS_FSTREAM_H */
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Library General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifndef MAILUTILS_SYS_MSTREAM_H
19 #define MAILUTILS_SYS_MSTREAM_H
20
21 #include <mailutils/sys/stream.h>
22 #include <mailutils/monitor.h>
23
24 struct _ms
25 {
26 struct _stream base;
27 int ref;
28 int fd;
29 int flags;
30 int mflags;
31 char *ptr;
32 size_t size;
33 off_t offset;
34 monitor_t lock;
35 };
36
37 #endif /* _MAILUTILS_SYS_MSTREAM_H */
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
23 #include <mailutils/pop3.h> 23 #include <mailutils/pop3.h>
24 #include <mailutils/sys/stream.h> 24 #include <mailutils/sys/stream.h>
25 #include <mailutils/sys/iterator.h> 25 #include <mailutils/sys/iterator.h>
26 #include <mailutils/monitor.h>
26 #include <mailutils/error.h> 27 #include <mailutils/error.h>
27 28
28 #ifdef DMALLOC 29 #ifdef DMALLOC
...@@ -59,6 +60,7 @@ struct p_iterator ...@@ -59,6 +60,7 @@ struct p_iterator
59 unsigned int ref; 60 unsigned int ref;
60 int done; 61 int done;
61 void *item; 62 void *item;
63 monitor_t lock;
62 }; 64 };
63 65
64 struct p_stream 66 struct p_stream
...@@ -67,6 +69,7 @@ struct p_stream ...@@ -67,6 +69,7 @@ struct p_stream
67 pop3_t pop3; 69 pop3_t pop3;
68 unsigned ref; 70 unsigned ref;
69 int done; 71 int done;
72 monitor_t lock;
70 }; 73 };
71 74
72 struct work_buf 75 struct work_buf
...@@ -99,10 +102,12 @@ struct _pop3 ...@@ -99,10 +102,12 @@ struct _pop3
99 102
100 enum pop3_state state; 103 enum pop3_state state;
101 stream_t stream; /* TCP Connection. */ 104 stream_t stream; /* TCP Connection. */
105 monitor_t lock;
102 }; 106 };
103 107
104 extern int pop3_iterator_create __P ((pop3_t, iterator_t *)); 108 extern int pop3_iterator_create __P ((pop3_t, iterator_t *));
105 extern int pop3_stream_create __P ((pop3_t, stream_t *)); 109 extern int pop3_stream_create __P ((pop3_t, stream_t *));
110 extern void pop3_cleanup __P ((void *));
106 111
107 /* Check for non recoverable error. */ 112 /* Check for non recoverable error. */
108 #define POP3_CHECK_EAGAIN(pop3, status) \ 113 #define POP3_CHECK_EAGAIN(pop3, status) \
......
...@@ -32,9 +32,9 @@ struct _stream_vtable ...@@ -32,9 +32,9 @@ struct _stream_vtable
32 int (*open) __P ((stream_t, const char *, int, int)); 32 int (*open) __P ((stream_t, const char *, int, int));
33 int (*close) __P ((stream_t)); 33 int (*close) __P ((stream_t));
34 34
35 int (*read) __P ((stream_t, char *, size_t, size_t *)); 35 int (*read) __P ((stream_t, void *, size_t, size_t *));
36 int (*readline) __P ((stream_t, char *, size_t, size_t *)); 36 int (*readline) __P ((stream_t, char *, size_t, size_t *));
37 int (*write) __P ((stream_t, const char *, size_t, size_t *)); 37 int (*write) __P ((stream_t, const void *, size_t, size_t *));
38 38
39 int (*seek) __P ((stream_t, off_t, enum stream_whence)); 39 int (*seek) __P ((stream_t, off_t, enum stream_whence));
40 int (*tell) __P ((stream_t, off_t *)); 40 int (*tell) __P ((stream_t, off_t *));
......
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Library Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 #ifdef HAVE_CONFIG_H
19 # include <config.h>
20 #endif
21
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31
32 #include <mailutils/sys/mstream.h>
33 #include <mailutils/error.h>
34
35 #ifdef _POSIX_MAPPED_FILES
36 #include <sys/mman.h>
37
38 #ifndef MAP_FAILED
39 # define MAP_FAILED (void*)-1
40 #endif
41
42 static int
43 _ms_add_ref (stream_t stream)
44 {
45 int status;
46 struct _ms *ms = (struct _ms *)stream;
47 monitor_lock (ms->lock);
48 status = ++ms->ref;
49 monitor_unlock (ms->lock);
50 return status;
51 }
52
53 static int
54 _ms_destroy (stream_t stream)
55 {
56 struct _ms *ms = (struct _ms *)stream;
57
58 if (ms->ptr != MAP_FAILED)
59 {
60 if (ms->ptr)
61 munmap (ms->ptr, ms->size);
62 if (ms->fd != -1)
63 close (ms->fd);
64 monitor_destroy (ms->lock);
65 }
66 free (ms);
67 return 0;
68 }
69
70 static int
71 _ms_release (stream_t stream)
72 {
73 int status;
74 struct _ms *ms = (struct _ms *)stream;
75 monitor_lock (ms->lock);
76 status = --ms->ref;
77 if (status <= 0)
78 {
79 monitor_unlock (ms->lock);
80 _ms_destroy (stream);
81 return 0;
82 }
83 monitor_unlock (ms->lock);
84 return status;
85 }
86
87 static int
88 _ms_read (stream_t stream, void *optr, size_t osize, size_t *nbytes)
89 {
90 struct _ms *ms = (struct _ms *)stream;
91 size_t n = 0;
92
93 monitor_lock (ms->lock);
94 if (ms->ptr != MAP_FAILED && ms->ptr)
95 {
96 if (ms->offset < (off_t)ms->size)
97 {
98 n = ((ms->offset + osize) > ms->size) ?
99 ms->size - ms->offset : osize;
100 memcpy (optr, ms->ptr + ms->offset, n);
101 ms->offset += n;
102 }
103 }
104 monitor_unlock (ms->lock);
105
106 if (nbytes)
107 *nbytes = n;
108 return 0;
109 }
110
111 static int
112 _ms_readline (stream_t stream, char *optr, size_t osize, size_t *nbytes)
113 {
114 struct _ms *ms = (struct _ms *)stream;
115 size_t n = 0;
116
117 monitor_lock (ms->lock);
118 if (ms->ptr != MAP_FAILED && ms->ptr)
119 {
120 if (ms->offset < (off_t)ms->size)
121 {
122 /* Save space for the null byte. */
123 char *nl;
124 osize--;
125 nl = memchr (ms->ptr + ms->offset, '\n', ms->size - ms->offset);
126 n = (nl) ? nl - (ms->ptr + ms->offset) + 1 : ms->size - ms->offset;
127 n = (n > osize) ? osize : n;
128 memcpy (optr, ms->ptr + ms->offset, n);
129 optr[n] = '\0';
130 ms->offset += n;
131 }
132 }
133 monitor_unlock (ms->lock);
134
135 if (nbytes)
136 *nbytes = n;
137 return 0;
138 }
139
140 static int
141 _ms_write (stream_t stream, const void *iptr, size_t isize, size_t *nbytes)
142 {
143 struct _ms *ms = (struct _ms *)stream;
144 int err = 0;
145 size_t n = 0;
146
147 monitor_lock (ms->lock);
148 if (ms->mflags & PROT_WRITE)
149 {
150 /* Bigger we have to remmap. */
151 if (ms->size < (ms->offset + isize))
152 {
153 if (ms->ptr != MAP_FAILED && munmap (ms->ptr, ms->size) == 0)
154 {
155 ms->ptr = MAP_FAILED;
156 if (ftruncate (ms->fd, ms->offset + isize) == 0)
157 {
158 ms->ptr = mmap (0, ms->offset + isize, ms->mflags,
159 MAP_SHARED, ms->fd, 0);
160 if (ms->ptr != MAP_FAILED)
161 ms->size = ms->offset + isize;
162 }
163 }
164 }
165
166 if (ms->ptr != MAP_FAILED)
167 {
168 if (isize > 0)
169 memcpy (ms->ptr + ms->offset, iptr, isize);
170 ms->offset += isize;
171 n = isize;
172 }
173 else
174 err = MU_ERROR_IO;
175 }
176 else
177 err = MU_ERROR_IO;
178 monitor_unlock (ms->lock);
179
180 if (nbytes)
181 *nbytes = n;
182 return err;
183 }
184
185 static int
186 _ms_truncate (stream_t stream, off_t len)
187 {
188 struct _ms *ms = (struct _ms *)stream;
189 int err = 0;
190
191 monitor_lock (ms->lock);
192 if (ms->ptr != MAP_FAILED)
193 {
194 /* Remap. */
195 if (ms->ptr && munmap (ms->ptr, ms->size) == 0)
196 {
197 if (ftruncate (ms->fd, len) == 0)
198 {
199 ms->ptr = (len) ?
200 mmap (0, len, ms->mflags, MAP_SHARED, ms->fd, 0) : NULL;
201 if (ms->ptr != MAP_FAILED)
202 {
203 ms->size = len;
204 }
205 else
206 err = errno;
207 }
208 else
209 err = errno;
210 }
211 }
212 monitor_unlock (ms->lock);
213 return err;
214 }
215
216 static int
217 _ms_get_size (stream_t stream, off_t *psize)
218 {
219 struct _ms *ms = (struct _ms *)stream;
220 struct stat stbuf;
221 int err = 0;
222
223 monitor_lock (ms->lock);
224 stbuf.st_size = 0;
225 if (ms->ptr != MAP_FAILED)
226 {
227 if (ms->ptr)
228 msync (ms->ptr, ms->size, MS_SYNC);
229
230 if (fstat(ms->fd, &stbuf) == 0)
231 {
232 /* Remap. */
233 if (ms->size != (size_t)stbuf.st_size)
234 {
235 if (ms->ptr && munmap (ms->ptr, ms->size) == 0)
236 {
237 if (ms->size)
238 {
239 ms->ptr = mmap (0, ms->size, ms->mflags , MAP_SHARED,
240 ms->fd, 0);
241 if (ms->ptr != MAP_FAILED)
242 ms->size = stbuf.st_size;
243 else
244 err = errno;
245 }
246 else
247 ms->ptr = NULL;
248 }
249 else
250 err = errno;
251 }
252 }
253 }
254 monitor_unlock (ms->lock);
255 if (psize)
256 *psize = stbuf.st_size;
257 return err;
258 }
259
260 static int
261 _ms_flush (stream_t stream)
262 {
263 int err = 0;
264 struct _ms *ms = (struct _ms *)stream;
265 monitor_lock (ms->lock);
266 if (ms->ptr != MAP_FAILED && ms->ptr != NULL)
267 err = msync (ms->ptr, ms->size, MS_SYNC);
268 monitor_unlock (ms->lock);
269 return 0;
270 }
271
272 static int
273 _ms_get_fd (stream_t stream, int *pfd)
274 {
275 struct _ms *ms = (struct _ms *)stream;
276 if (pfd)
277 *pfd = ms->fd;
278 return 0;
279 }
280
281 static int
282 _ms_get_flags (stream_t stream, int *flags)
283 {
284 struct _ms *ms = (struct _ms *)stream;
285 if (flags == NULL)
286 return MU_ERROR_INVALID_PARAMETER;
287 *flags = ms->flags;
288 return 0;
289 }
290
291 static int
292 _ms_get_state (stream_t stream, enum stream_state *state)
293 {
294 (void)stream;
295 if (state == NULL)
296 return MU_ERROR_INVALID_PARAMETER;
297 *state = MU_STREAM_NO_STATE;
298 return 0;
299 }
300
301 static int
302 _ms_seek (stream_t stream, off_t off, enum stream_whence whence)
303 {
304 struct _ms *ms = (struct _ms *)stream;
305 off_t noff = ms->offset;
306 int err = 0;
307 if (whence == MU_STREAM_WHENCE_SET)
308 noff = off;
309 else if (whence == MU_STREAM_WHENCE_CUR)
310 noff += off;
311 else if (whence == MU_STREAM_WHENCE_END)
312 noff = ms->size + off;
313 else
314 noff = -1; /* error. */
315 if (noff >= 0)
316 {
317 if (noff > ms->offset)
318 _ms_truncate (stream, noff);
319 ms->offset = noff;
320 }
321 else
322 err = MU_ERROR_INVALID_PARAMETER;
323 return err;
324 }
325
326 static int
327 _ms_tell (stream_t stream, off_t *off)
328 {
329 struct _ms *ms = (struct _ms *)stream;
330 if (off == NULL)
331 return MU_ERROR_INVALID_PARAMETER;
332 *off = ms->offset;
333 return 0;
334 }
335
336 static int
337 _ms_close (stream_t stream)
338 {
339 struct _ms *ms = (struct _ms *)stream;
340 int err = 0;
341 monitor_lock (ms->lock);
342 if (ms->ptr != MAP_FAILED)
343 {
344 if (ms->ptr && munmap (ms->ptr, ms->size) != 0)
345 err = errno;
346 ms->ptr = MAP_FAILED;
347 }
348 if (ms->fd != -1)
349 if (close (ms->fd) != 0)
350 err = errno;
351 ms->fd = -1;
352 monitor_unlock (ms->lock);
353 return err;
354 }
355
356 static int
357 _ms_open (stream_t stream, const char *filename, int port, int flags)
358 {
359 struct _ms *ms = (struct _ms *)stream;
360 int mflag, flg;
361 struct stat st;
362
363 (void)port; /* Ignored. */
364
365 /* Close any previous file. */
366 if (ms->ptr != MAP_FAILED)
367 {
368 if (ms->ptr)
369 munmap (ms->ptr, ms->size);
370 ms->ptr = MAP_FAILED;
371 }
372 if (ms->fd != -1)
373 {
374 close (ms->fd);
375 ms->fd = -1;
376 }
377 /* Map the flags to the system equivalent */
378 if ((flags & MU_STREAM_WRITE) && (flags & MU_STREAM_READ))
379 return EINVAL;
380 else if (flags & MU_STREAM_WRITE)
381 {
382 mflag = PROT_WRITE;
383 flg = O_WRONLY;
384 }
385 else if (flags & MU_STREAM_RDWR)
386 {
387 mflag = PROT_READ | PROT_WRITE;
388 flg = O_RDWR;
389 }
390 else if (flags & MU_STREAM_CREAT)
391 return ENOSYS;
392 else /* default */
393 {
394 mflag = PROT_READ;
395 flg = O_RDONLY;
396 }
397
398 ms->fd = open (filename, flg);
399 if (ms->fd < 0)
400 return errno;
401 if (fstat (ms->fd, &st) != 0)
402 {
403 int err = errno;
404 close (ms->fd);
405 return err;
406 }
407 ms->size = st.st_size;
408 if (ms->size)
409 {
410 ms->ptr = mmap (0, ms->size, mflag , MAP_SHARED, ms->fd, 0);
411 if (ms->ptr == MAP_FAILED)
412 {
413 int err = errno;
414 close (ms->fd);
415 ms->ptr = MAP_FAILED;
416 return err;
417 }
418 }
419 else
420 ms->ptr = NULL;
421 ms->mflags = mflag;
422 ms->flags = flags;
423 return 0;
424 }
425
426 static struct _stream_vtable _ms_vtable =
427 {
428 _ms_add_ref,
429 _ms_release,
430 _ms_destroy,
431
432 _ms_open,
433 _ms_close,
434
435 _ms_read,
436 _ms_readline,
437 _ms_write,
438
439 _ms_seek,
440 _ms_tell,
441
442 _ms_get_size,
443 _ms_truncate,
444 _ms_flush,
445
446 _ms_get_fd,
447 _ms_get_flags,
448 _ms_get_state,
449 };
450
451 #endif /* _POSIX_MAPPED_FILES */
452
453 int
454 stream_mapfile_create (stream_t *pstream)
455 {
456 #ifndef _POSIX_MAPPED_FILES
457 return ENOSYS;
458 #else
459 struct _ms *ms;
460
461 if (pstream == NULL)
462 return MU_ERROR_INVALID_PARAMETER;
463
464 ms = calloc (1, sizeof *ms);
465 if (ms == NULL)
466 return MU_ERROR_NO_MEMORY;
467
468 ms->base.vtable = &_ms_vtable;
469 ms->ref = 1;
470 ms->fd = -1;
471 ms->offset = -1;
472 ms->flags = 0;
473 ms->mflags = 0;
474 *pstream = &ms->base;
475
476 return 0;
477 #endif /* _POSIX_MAPPED_FILES */
478 }
1 # Use automake to process this file -*-Makefile-*-
2
3 AUTOMAKE_OPTIONS = ../lib/ansi2knr
4
5 #INCLUDES = -I${top_srcdir}/include
6 INCLUDES = -I${top_srcdir}/mailbox2/include
7
8 lib_LTLIBRARIES = libpop3.la
9
10 libmailbox_la_SOURCES = \
11 pop3_apop.c \
12 pop3_capa.c \
13 pop3_cleanup.c \
14 pop3_connect.c \
15 pop3_create.c \
16 pop3_dele.c \
17 pop3_destroy.c \
18 pop3_disconnect.c \
19 pop3_iterator.c \
20 pop3_list.c \
21 pop3_lista.c \
22 pop3_noop.c \
23 pop3_pass.c \
24 pop3_quit.c \
25 pop3_readline.c \
26 pop3_response.c \
27 pop3_retr.c \
28 pop3_rset.c \
29 pop3_sendline.c \
30 pop3_stat.c \
31 pop3_stream.c \
32 pop3_timeout.c \
33 pop3_top.c \
34 pop3_uidl.c \
35 pop3_uidla.c \
36 pop3_user.c
...@@ -49,10 +49,10 @@ pop3_get_stream (pop3_t pop3, stream_t *pstream) ...@@ -49,10 +49,10 @@ pop3_get_stream (pop3_t pop3, stream_t *pstream)
49 if (pop3->stream == NULL) 49 if (pop3->stream == NULL)
50 { 50 {
51 stream_t stream = NULL; 51 stream_t stream = NULL;
52 int status = stream_tcp_create (&stream)); 52 int status = stream_tcp_create (&stream);
53 if (status) 53 if (status)
54 return status; 54 return status;
55 stream_buffer_create (&(pop3->stream), stream, 1024); */ 55 stream_buffer_create (&(pop3->stream), stream, 1024);
56 } 56 }
57 *pstream = pop3->stream; 57 *pstream = pop3->stream;
58 return 0; 58 return 0;
...@@ -66,9 +66,9 @@ static int p_destroy __P ((stream_t)); ...@@ -66,9 +66,9 @@ static int p_destroy __P ((stream_t));
66 static int p_open __P ((stream_t, const char *, int, int)); 66 static int p_open __P ((stream_t, const char *, int, int));
67 static int p_close __P ((stream_t)); 67 static int p_close __P ((stream_t));
68 68
69 static int p_read __P ((stream_t, char *, size_t, size_t *)); 69 static int p_read __P ((stream_t, void *, size_t, size_t *));
70 static int p_readline __P ((stream_t, char *, size_t, size_t *)); 70 static int p_readline __P ((stream_t, char *, size_t, size_t *));
71 static int p_write __P ((stream_t, const char *, size_t, size_t *)); 71 static int p_write __P ((stream_t, const void *, size_t, size_t *));
72 72
73 static int p_seek __P ((stream_t, off_t, enum stream_whence)); 73 static int p_seek __P ((stream_t, off_t, enum stream_whence));
74 static int p_tell __P ((stream_t, off_t *)); 74 static int p_tell __P ((stream_t, off_t *));
...@@ -191,11 +191,12 @@ p_close (stream_t stream) ...@@ -191,11 +191,12 @@ p_close (stream_t stream)
191 } 191 }
192 192
193 static int 193 static int
194 p_read (stream_t stream, char *buf, size_t buflen, size_t *pn) 194 p_read (stream_t stream, void *buf, size_t buflen, size_t *pn)
195 { 195 {
196 struct p_stream *p_stream = (struct p_stream *)stream; 196 struct p_stream *p_stream = (struct p_stream *)stream;
197 size_t n = 0; 197 size_t n = 0;
198 int status = 0; 198 int status = 0;
199 char *p = buf;
199 if (p_stream) 200 if (p_stream)
200 { 201 {
201 monitor_lock (p_stream->lock); 202 monitor_lock (p_stream->lock);
...@@ -208,17 +209,17 @@ p_read (stream_t stream, char *buf, size_t buflen, size_t *pn) ...@@ -208,17 +209,17 @@ p_read (stream_t stream, char *buf, size_t buflen, size_t *pn)
208 /* The pop3_readline () function will always read one less to 209 /* The pop3_readline () function will always read one less to
209 be able to terminate the buffer, this will cause serious grief 210 be able to terminate the buffer, this will cause serious grief
210 for stream_read() where it is legitimate to have a buffer of 211 for stream_read() where it is legitimate to have a buffer of
211 1 char. So we must catch here or change the behavoiour of 212 1 char. So we must catch it here or change the behaviour of
212 XXX_readline. */ 213 XXX_readline. */
213 if (buflen == 1) 214 if (buflen == 1)
214 { 215 {
215 char buffer[2]; 216 char buffer[2];
216 *buffer = '\0'; 217 *buffer = '\0';
217 status = pop3_readline (p_stream->pop3, buffer, 2, &nread); 218 status = pop3_readline (p_stream->pop3, buffer, 2, &nread);
218 *buf = *buffer; 219 *p = *buffer;
219 } 220 }
220 else 221 else
221 status = pop3_readline (p_stream->pop3, buf, buflen, &nread); 222 status = pop3_readline (p_stream->pop3, p, buflen, &nread);
222 223
223 if (status != 0) 224 if (status != 0)
224 break; 225 break;
...@@ -230,7 +231,7 @@ p_read (stream_t stream, char *buf, size_t buflen, size_t *pn) ...@@ -230,7 +231,7 @@ p_read (stream_t stream, char *buf, size_t buflen, size_t *pn)
230 } 231 }
231 n += nread; 232 n += nread;
232 buflen -= nread; 233 buflen -= nread;
233 buf += nread; 234 p += nread;
234 } 235 }
235 while (buflen > 0); 236 while (buflen > 0);
236 } 237 }
...@@ -267,7 +268,7 @@ p_readline (stream_t stream, char *buf, size_t buflen, size_t *pn) ...@@ -267,7 +268,7 @@ p_readline (stream_t stream, char *buf, size_t buflen, size_t *pn)
267 } 268 }
268 269
269 static int 270 static int
270 p_write (stream_t stream, const char *buf, size_t buflen, size_t *pn) 271 p_write (stream_t stream, const void *buf, size_t buflen, size_t *pn)
271 { 272 {
272 struct p_stream *p_stream = (struct p_stream *)stream; 273 struct p_stream *p_stream = (struct p_stream *)stream;
273 return stream_write (p_stream->pop3->stream, buf, buflen, pn); 274 return stream_write (p_stream->pop3->stream, buf, buflen, pn);
......
...@@ -125,7 +125,7 @@ main (int argc, char **argv) ...@@ -125,7 +125,7 @@ main (int argc, char **argv)
125 for ( ; done == 0; ) 125 for ( ; done == 0; )
126 { 126 {
127 127
128 line = readline ("pop3> "); 128 line = readline ((char *)"pop3> ");
129 129
130 if (!line) 130 if (!line)
131 break; 131 break;
......
...@@ -69,7 +69,7 @@ int ...@@ -69,7 +69,7 @@ int
69 } 69 }
70 70
71 int 71 int
72 (stream_read) (stream_t stream, char *buf, size_t buflen, size_t *n) 72 (stream_read) (stream_t stream, void *buf, size_t buflen, size_t *n)
73 { 73 {
74 if (stream == NULL || stream->vtable == NULL 74 if (stream == NULL || stream->vtable == NULL
75 || stream->vtable->read == NULL) 75 || stream->vtable->read == NULL)
...@@ -87,7 +87,7 @@ int ...@@ -87,7 +87,7 @@ int
87 } 87 }
88 88
89 int 89 int
90 (stream_write) (stream_t stream, const char *buf, size_t buflen, size_t *n) 90 (stream_write) (stream_t stream, const void *buf, size_t buflen, size_t *n)
91 { 91 {
92 if (stream == NULL || stream->vtable == NULL 92 if (stream == NULL || stream->vtable == NULL
93 || stream->vtable->write == NULL) 93 || stream->vtable->write == NULL)
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
24 #include <errno.h> 24 #include <errno.h>
25 #include <netdb.h> 25 #include <netdb.h>
26 #include <fcntl.h> 26 #include <fcntl.h>
27 //#define __USE_BSD
28 #include <string.h> 27 #include <string.h>
29 #include <strings.h> 28 #include <strings.h>
30 #include <sys/types.h> 29 #include <sys/types.h>
...@@ -33,7 +32,7 @@ ...@@ -33,7 +32,7 @@
33 #include <arpa/inet.h> 32 #include <arpa/inet.h>
34 #include <unistd.h> 33 #include <unistd.h>
35 34
36 #include <mailutils/sys/tcp.h> 35 #include <mailutils/sys/tcpstream.h>
37 #include <mailutils/error.h> 36 #include <mailutils/error.h>
38 37
39 /* On solaris inet_addr() return -1. */ 38 /* On solaris inet_addr() return -1. */
...@@ -226,7 +225,7 @@ _tcp_get_fd (stream_t stream, int *fd) ...@@ -226,7 +225,7 @@ _tcp_get_fd (stream_t stream, int *fd)
226 } 225 }
227 226
228 static int 227 static int
229 _tcp_read (stream_t stream, char *buf, size_t buf_size, size_t *br) 228 _tcp_read (stream_t stream, void *buf, size_t buf_size, size_t *br)
230 { 229 {
231 struct _tcp_instance *tcp = (struct _tcp_instance *)stream; 230 struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
232 int bytes; 231 int bytes;
...@@ -282,7 +281,7 @@ _tcp_readline (stream_t stream, char *buf, size_t buf_size, size_t *br) ...@@ -282,7 +281,7 @@ _tcp_readline (stream_t stream, char *buf, size_t buf_size, size_t *br)
282 } 281 }
283 282
284 static int 283 static int
285 _tcp_write (stream_t stream, const char *buf, size_t buf_size, size_t *bw) 284 _tcp_write (stream_t stream, const void *buf, size_t buf_size, size_t *bw)
286 { 285 {
287 struct _tcp_instance *tcp = (struct _tcp_instance *)stream; 286 struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
288 int bytes; 287 int bytes;
...@@ -339,6 +338,8 @@ static int ...@@ -339,6 +338,8 @@ static int
339 _tcp_get_flags (stream_t stream, int *flags) 338 _tcp_get_flags (stream_t stream, int *flags)
340 { 339 {
341 struct _tcp_instance *tcp = (struct _tcp_instance *)stream; 340 struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
341 if (flags == NULL)
342 return MU_ERROR_INVALID_PARAMETER;
342 *flags = tcp->flags; 343 *flags = tcp->flags;
343 return 0; 344 return 0;
344 } 345 }
...@@ -347,6 +348,8 @@ static int ...@@ -347,6 +348,8 @@ static int
347 _tcp_get_state (stream_t stream, enum stream_state *state) 348 _tcp_get_state (stream_t stream, enum stream_state *state)
348 { 349 {
349 struct _tcp_instance *tcp = (struct _tcp_instance *)stream; 350 struct _tcp_instance *tcp = (struct _tcp_instance *)stream;
351 if (state == NULL)
352 return MU_ERROR_INVALID_PARAMETER;
350 *state = tcp->state; 353 *state = tcp->state;
351 return 0; 354 return 0;
352 } 355 }
...@@ -381,6 +384,9 @@ stream_tcp_create (stream_t *pstream) ...@@ -381,6 +384,9 @@ stream_tcp_create (stream_t *pstream)
381 { 384 {
382 struct _tcp_instance *tcp; 385 struct _tcp_instance *tcp;
383 386
387 if (pstream == NULL)
388 return MU_ERROR_INVALID_PARAMETER;
389
384 tcp = calloc (1, sizeof *tcp); 390 tcp = calloc (1, sizeof *tcp);
385 if (tcp == NULL) 391 if (tcp == NULL)
386 return MU_ERROR_NO_MEMORY; 392 return MU_ERROR_NO_MEMORY;
......