Commit f25e4125 f25e4125ab2cce4c816bf4139811564a8604f30a by Sergey Poznyakoff

Added to the repository

1 parent bbd0617f
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 GNU Mailutils 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 General Public License
15 along with GNU Mailutils; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
18 /* This file implements an MH draftfile stream: a read-only stream used
19 to transparently pass MH draftfiles to the mailers. The only difference
20 between the usual RFC822 and MH draft is that the latter allows to use
21 a string of dashes to separate the headers from the body. */
22
23 #include <mh.h>
24 #include <mailutils/stream.h>
25
26 struct _mhdraft_stream {
27 stream_t stream; /* Actual stream */
28 size_t mark_offset; /* Offset of the header separator */
29 size_t mark_length; /* Length of the header separator (not counting the
30 newline) */
31 };
32
33 static int
34 _mhdraft_read (stream_t stream, char *optr, size_t osize,
35 off_t offset, size_t *nbytes)
36 {
37 struct _mhdraft_stream *s = stream_get_owner (stream);
38
39 if (offset < s->mark_offset)
40 {
41 if (offset + osize >= s->mark_offset)
42 osize = s->mark_offset - offset;
43 }
44 else
45 offset += s->mark_length;
46 return stream_read (s->stream, optr, osize, offset, nbytes);
47 }
48
49 static int
50 _mhdraft_readline (stream_t stream, char *optr, size_t osize,
51 off_t offset, size_t *nbytes)
52 {
53 struct _mhdraft_stream *s = stream_get_owner (stream);
54
55 if (offset < s->mark_offset)
56 {
57 if (offset + osize >= s->mark_offset)
58 {
59 int rc;
60 size_t n;
61 size_t rdsize = s->mark_offset - offset;
62 rc = stream_readline (s->stream, optr, rdsize, offset, &n);
63 if (rc == 0)
64 {
65 if (nbytes)
66 *nbytes = n;
67 }
68 return rc;
69 }
70 }
71 else
72 offset += s->mark_length;
73
74 return stream_readline (s->stream, optr, osize, offset, nbytes);
75 }
76
77 static int
78 _mhdraft_size (stream_t stream, off_t *psize)
79 {
80 struct _mhdraft_stream *s = stream_get_owner (stream);
81 int rc = stream_size (s->stream, psize);
82
83 if (rc == 0)
84 *psize -= s->mark_length;
85 return rc;
86 }
87
88 static int
89 _mhdraft_open (stream_t stream)
90 {
91 struct _mhdraft_stream *s = stream_get_owner (stream);
92 size_t offset, len;
93 char buffer[256];
94 int rc;
95
96 offset = 0;
97 while ((rc = stream_readline (s->stream, buffer, sizeof buffer,
98 offset, &len)) == 0
99 && len > 0)
100 {
101 if (_mh_delim (buffer))
102 {
103 s->mark_offset = offset;
104 s->mark_length = len - 1; /* do not count the terminating newline */
105 break;
106 }
107
108 offset += len;
109 }
110 return 0;
111 }
112
113 static int
114 _mhdraft_close (stream_t stream)
115 {
116 struct _mhdraft_stream *s = stream_get_owner (stream);
117 return stream_close (s->stream);
118 }
119
120 static void
121 _mhdraft_destroy (stream_t stream)
122 {
123 struct _mhdraft_stream *s = stream_get_owner (stream);
124 if (s->stream)
125 stream_destroy (&s->stream, stream_get_owner (s->stream));
126 free (s);
127 }
128
129 int
130 mhdraft_stream_create (stream_t *stream, stream_t src, int flags)
131 {
132 struct _mhdraft_stream *s;
133 int rc;
134
135 if (!flags)
136 flags = MU_STREAM_READ;
137 if (flags != MU_STREAM_READ)
138 return EINVAL;
139
140 s = calloc (1, sizeof (*s));
141 if (s == NULL)
142 return ENOMEM;
143
144 s->stream = src;
145
146 rc = stream_create (stream, flags|MU_STREAM_NO_CHECK, s);
147 if (rc)
148 {
149 free (s);
150 return rc;
151 }
152
153 stream_set_open (*stream, _mhdraft_open, s);
154 stream_set_close (*stream, _mhdraft_close, s);
155 stream_set_destroy (*stream, _mhdraft_destroy, s);
156 stream_set_readline (*stream, _mhdraft_readline, s);
157 stream_set_read (*stream, _mhdraft_read, s);
158 stream_set_size (*stream, _mhdraft_size, s);
159 return 0;
160 }
161
162