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

Annotation of /trunk/Src/wptGPGMEData.cpp

Parent Directory Parent Directory | Revision Log Revision Log


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


1 twoaday 133 /* wptGPGMEData.cpp - WinPT specifc data extensions
2 twoaday 200 * Copyright (C) 2001-2006 Timo Schulz
3 twoaday 133 *
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 twoaday 121 #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 twoaday 271 #include "wptTypes.h"
33 twoaday 121
34 twoaday 271 /* Default buffer size */
35     #define BUFSIZE 128
36 twoaday 200
37 twoaday 271
38 twoaday 121 /* 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 twoaday 271 char buf[BUFSIZE+1];
137 twoaday 121
138     if (!*r_dh)
139     return gpg_error (GPG_ERR_INV_ARG);
140     gpgme_data_new (&dh);
141 twoaday 271 while (gpg_data_readline (*r_dh, buf, DIM (buf)-1)) {
142 twoaday 121 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 twoaday 200 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 twoaday 121 /* 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 twoaday 271 char line[BUFSIZE+32];
181 twoaday 121 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 twoaday 271 while (gpg_data_readline (sig, line, BUFSIZE) > 0) {
190 twoaday 121 if (!strncmp (line, "-----BEGIN PGP SIGNED MESSAGE", 29) ||
191 twoaday 200 is_armor_header (line))
192 twoaday 121 continue;
193     if (strlen (line) <= 2)
194     break; /* parsed all headers, now we reached the body */
195     }
196 twoaday 200
197     /* We just support 1 nesting level. */
198 twoaday 271 while (gpg_data_readline (sig, line, BUFSIZE) > 0 ) {
199 twoaday 247 if (!strncmp (line, "-----BEGIN PGP SIGNATURE", 24))
200 twoaday 121 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 twoaday 144
271    
272 twoaday 226
273 twoaday 144 /* Write a single byte to data object @hd. */
274     void
275     gpg_data_putc (gpgme_data_t hd, int c)
276     {
277 twoaday 162 BYTE ch[2];
278 twoaday 144
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