/[winpt]/trunk/Src/wptGPGMEData.cpp
ViewVC logotype

Contents of /trunk/Src/wptGPGMEData.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 271 - (show annotations)
Sun Nov 5 08:57:45 2006 UTC (18 years, 3 months ago) by twoaday
File size: 6450 byte(s)


1 /* wptGPGMEData.cpp - WinPT specifc data extensions
2 * Copyright (C) 2001-2006 Timo Schulz
3 *
4 * This file is part of WinPT.
5 *
6 * WinPT is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * WinPT is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with WinPT; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <windows.h>
25 #include <malloc.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <gpgme.h>
29
30 #include "wptUtil.h"
31 #include "wptGPG.h"
32 #include "wptTypes.h"
33
34 /* Default buffer size */
35 #define BUFSIZE 128
36
37
38 /* Implement a word based line break. @inp is the input buffer
39 and @wraplen is the maximal line length.
40 Return value: the wrapped buffer on success. */
41 char*
42 wrap_lines (char *inp, size_t inlen, size_t wraplen, size_t *r_len)
43 {
44 char *out;
45 char *p, *inp_ptr;
46 int end_is_le=0, add_le=0;
47 size_t n;
48
49 inp[inlen] = 0;
50 if (inp[inlen-2] == '\r' && inp[inlen-1] == '\n')
51 end_is_le = 1;
52 out = (char *)calloc (1, 4*inlen/3+2+1);
53 if (!out)
54 return NULL;
55 n = 0;
56 inp_ptr = inp;
57 while ((p = strsep (&inp_ptr, " \n"))) {
58 if (strlen (p) == 0) {
59 strcat (out, " ");
60 n++;
61 continue;
62 }
63 /* if we find an existing \r\n pair, we generate a break
64 at the given position and reset the counter. */
65 if (p[strlen (p)-1] == '\r') {
66 p[strlen (p)-1]=0;
67 add_le=1;
68 }
69 else
70 add_le=0;
71 if (n + strlen (p) > wraplen) {
72 strcat (out, "\r\n");
73 n = 0;
74 }
75 else if (n > 0 || add_le) {
76 strcat (out, " ");
77 n++;
78 }
79
80 n += strlen (p);
81 strcat (out, p);
82 if (add_le) {
83 strcat (out, "\r\n");
84 n = 0;
85 }
86 }
87 if (end_is_le)
88 strcat (out, "\r\n");
89 *r_len = strlen (out);
90 return out;
91 }
92
93
94 /* Wrap the lines of @r_dh with a line length of @wraplen.
95 @r_dh will be released and on success it contains the
96 handle to the wrapped data.
97 Return value: 0 on success. */
98 gpgme_error_t
99 gpg_data_wrap_lines (gpgme_data_t *r_dh, size_t wraplen)
100 {
101 gpgme_error_t err;
102 gpgme_data_t mdh;
103 char *raw = NULL;
104 char *p = NULL;
105 size_t nlen;
106
107 err = gpgme_data_new (&mdh);
108 if (err)
109 return err;
110
111 raw = gpgme_data_release_and_get_mem (*r_dh, &nlen);
112 if (!raw) {
113 gpgme_data_release (mdh);
114 return gpg_error (GPG_ERR_INV_ARG);
115 }
116
117 p = wrap_lines (raw, nlen, wraplen, &nlen);
118 if (p) {
119 gpgme_data_write (mdh, p, nlen);
120 gpgme_data_rewind (mdh);
121 free (p);
122 }
123 gpgme_free (raw);
124 *r_dh = mdh;
125 return 0;
126 }
127
128
129 /* Prepend '> ' to each line into @r_dh. On success @r_dh
130 contains a handle to the quoted data.
131 Return value: 0 on success. */
132 gpgme_error_t
133 gpg_data_mail_quote (gpgme_data_t *r_dh)
134 {
135 gpgme_data_t dh;
136 char buf[BUFSIZE+1];
137
138 if (!*r_dh)
139 return gpg_error (GPG_ERR_INV_ARG);
140 gpgme_data_new (&dh);
141 while (gpg_data_readline (*r_dh, buf, DIM (buf)-1)) {
142 gpgme_data_write (dh, "> ", 2);
143 gpgme_data_write (dh, buf, strlen (buf));
144 }
145 gpgme_data_release (*r_dh);
146 *r_dh = dh;
147 return 0;
148 }
149
150
151 static int
152 is_armor_header (const char *line)
153 {
154 const char *header[] = {
155 "Version:",
156 "Comment:",
157 "Charset:",
158 "Hash:",
159 "MessageID",
160 NULL
161 };
162 int i;
163
164 for (i=0; header[i] != NULL; i++) {
165 if (!strncmp (line, header[i], strlen (header[i])))
166 return -1;
167 }
168 return 0;
169 }
170
171
172 /* Extract the plaintext data from the escaped data object @sig.
173 The plaintxt is stored in @r_plain.
174 Return value: 0 on success. */
175 gpgme_error_t
176 gpg_data_extract_plaintext (gpgme_data_t sig, gpgme_data_t *r_plain)
177 {
178 gpgme_data_t plain;
179 gpgme_error_t err;
180 char line[BUFSIZE+32];
181 int pos = 0;
182
183 if (r_plain)
184 *r_plain = NULL;
185 err = gpgme_data_new (&plain);
186 if (err)
187 return err;
188
189 while (gpg_data_readline (sig, line, BUFSIZE) > 0) {
190 if (!strncmp (line, "-----BEGIN PGP SIGNED MESSAGE", 29) ||
191 is_armor_header (line))
192 continue;
193 if (strlen (line) <= 2)
194 break; /* parsed all headers, now we reached the body */
195 }
196
197 /* We just support 1 nesting level. */
198 while (gpg_data_readline (sig, line, BUFSIZE) > 0 ) {
199 if (!strncmp (line, "-----BEGIN PGP SIGNATURE", 24))
200 break; /* end of plaintext */
201 if (!strncmp (line, "- -", 3))
202 pos = 2;
203 gpgme_data_write (plain, line+pos, strlen (line+pos));
204 pos = 0;
205 }
206 gpgme_data_write (plain, "", 1);
207 if (r_plain)
208 *r_plain = plain;
209 else
210 gpgme_data_release (plain);
211 return err;
212 }
213
214
215 /* Release the data in @dh and store the contents in the file @fname.
216 Return value: 0 on success. */
217 gpgme_error_t
218 gpg_data_release_and_set_file (gpgme_data_t dh, const char *fname)
219 {
220 char *p = NULL;
221 FILE *fp;
222 size_t n;
223
224 fp = fopen (fname, "wb");
225 if (fp == NULL)
226 return gpg_error (GPG_ERR_ENOENT);
227
228 p = gpgme_data_release_and_get_mem (dh, &n);
229 if (p) {
230 fwrite (p, 1, n, fp);
231 fflush (fp);
232 memset (p, 0xFF, n);
233 gpgme_free (p);
234 }
235 fclose (fp);
236 return 0;
237 }
238
239
240 /* Try to read a line, terminated by \n from the given
241 gpgme data object @dh into @line.
242 Return value: numbers of chars read. */
243 size_t
244 gpg_data_readline (gpgme_data_t dh, char *line, size_t nbytes)
245 {
246 char ch = 0;
247 int nread = 0, pos = 0;
248
249 if (!dh)
250 return 0;
251
252 memset (line, 0, nbytes);
253 while ((nread=gpgme_data_read (dh, &ch, 1)) > 0) {
254 if (!nread)
255 break;
256 if (ch == '\n') {
257 line[pos++] = ch;
258 line[pos++] = '\0';
259 break;
260 }
261 line[pos++] = ch;
262 if (pos > (int)nbytes) {
263 line[pos++] = '\0';
264 break;
265 }
266 }
267
268 return pos;
269 }
270
271
272
273 /* Write a single byte to data object @hd. */
274 void
275 gpg_data_putc (gpgme_data_t hd, int c)
276 {
277 BYTE ch[2];
278
279 ch[0] = (BYTE)c;
280 ch[1] = '\0';
281 gpgme_data_write (hd, ch, 1);
282 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26