/[winpt]/trunk/w32gpgme/data.c
ViewVC logotype

Annotation of /trunk/w32gpgme/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 25 - (hide annotations)
Wed Oct 12 10:04:26 2005 UTC (19 years, 4 months ago) by twoaday
File MIME type: text/plain
File size: 5820 byte(s)
First testing phase finished.
Provide bug fixes for a lot of (minor) problems.

1 twoaday 25 #include <windows.h>
2 twoaday 23 #include <malloc.h>
3     #include <string.h>
4     #include <stdio.h>
5     #include <errno.h>
6    
7     #include "w32gpgme.h"
8    
9    
10    
11     /* Soft line wrapping. */
12     static char*
13 twoaday 25 wrap_lines_soft (char *buf, int buflen, int wraplen)
14 twoaday 23 {
15     char *curpos, *lastspc, *lastbrk;
16    
17 twoaday 25 for (curpos = lastspc = lastbrk = buf; *curpos; curpos++) {
18     if (buflen-- < 1)
19     break;
20     if (*curpos == ' ')
21 twoaday 23 lastspc = curpos;
22     else {
23 twoaday 25 if (*curpos == '\n') {
24 twoaday 23 lastbrk = curpos;
25     lastspc = lastbrk;
26     }
27     }
28 twoaday 25 if ((curpos - lastbrk) >= wraplen) {
29 twoaday 23 *lastspc = '\n';
30     lastbrk = lastspc;
31     }
32     }
33     return buf;
34     }
35    
36    
37     static char*
38 twoaday 25 wrap_lines (char *buf, size_t bufsize, size_t wraplen, size_t *r_len)
39 twoaday 23 {
40 twoaday 25 char *soft, *buffer;
41     gpgme_data_t in, out;
42     int n;
43    
44     soft = wrap_lines_soft (buf, bufsize, wraplen);
45     if (!soft)
46 twoaday 23 return NULL;
47 twoaday 25 buffer = calloc (1, wraplen+4);
48     gpgme_data_new_from_mem (&in, soft, bufsize, 1);
49     gpgme_data_new (&out);
50    
51     while ((n=gpg_data_readline (in, buffer, wraplen+3)) > 0) {
52     if (buffer[n-1] == 0 && buffer[n-2] == 0x0a)
53     n -= 2;
54     gpgme_data_write (out, buffer, n);
55     gpgme_data_write (out, "\r\n", 2);
56 twoaday 23 }
57 twoaday 25 gpgme_data_write (out, "", 1);
58     free (buffer);
59     gpgme_data_release (in);
60     return gpgme_data_release_and_get_mem (out, r_len);
61 twoaday 23 }
62    
63    
64     /* Wrap the lines of @r_dh with a line length of @wraplen.
65     @r_dh will be released and on success it contains the
66     handle to the wrapped data.
67     Return value: 0 on success. */
68     gpgme_error_t
69     gpg_data_wrap_lines (gpgme_data_t *r_dh, size_t wraplen)
70     {
71 twoaday 25 gpgme_error_t err;
72 twoaday 23 gpgme_data_t mdh;
73 twoaday 25 char *raw = NULL;
74     char *p = NULL;
75 twoaday 23 size_t nlen;
76    
77 twoaday 25 err = gpgme_data_new (&mdh);
78     if (err)
79 twoaday 23 return err;
80    
81 twoaday 25 raw = gpgme_data_release_and_get_mem (*r_dh, &nlen);
82     if (!raw) {
83     gpgme_data_release (mdh);
84     return gpg_error (GPG_ERR_INV_ARG);
85 twoaday 23 }
86 twoaday 25 if (!memchr (raw, '\n', nlen) && nlen < wraplen) {
87     /* Restore old data and rewind. */
88     gpgme_data_write (mdh, raw, nlen);
89     gpgme_data_rewind (mdh);
90     *r_dh = mdh;
91     free (raw); /* XXX: gpgme_free (raw); */
92 twoaday 23 return 0;
93     }
94    
95 twoaday 25 p = wrap_lines (raw, nlen, wraplen, &nlen);
96     if (p) {
97     gpgme_data_write (mdh, p, nlen);
98     free (p);
99 twoaday 23 }
100 twoaday 25 gpgme_data_rewind (mdh);
101 twoaday 23 *r_dh = mdh;
102     if (raw)
103 twoaday 25 free (raw); /* XXX: gpgme_free (raw); */
104 twoaday 23 return 0;
105     }
106    
107    
108     /* Prepend '> ' to each line into @r_dh. On success @r_dh
109     contains a handle to the quoted data.
110     Return value: 0 on success. */
111     gpgme_error_t
112     gpg_data_mail_quote (gpgme_data_t *r_dh)
113     {
114     gpgme_data_t dh;
115     char buf[128];
116    
117     if (!*r_dh)
118 twoaday 25 return gpg_error (GPG_ERR_INV_ARG);
119 twoaday 23 gpgme_data_new (&dh);
120     while (gpg_data_readline (*r_dh, buf, 127)) {
121     gpgme_data_write (dh, "> ", 2);
122     gpgme_data_write (dh, buf, strlen (buf));
123     }
124     gpgme_data_release (*r_dh);
125     *r_dh = dh;
126     return 0;
127     }
128    
129     /* Extract the plaintext data from the escaped data object @sig.
130     The plaintxt is stored in @r_plain.
131     Return value: 0 on success. */
132     gpgme_error_t
133 twoaday 25 gpg_data_extract_plaintext (gpgme_data_t sig, gpgme_data_t *r_plain)
134 twoaday 23 {
135     gpgme_data_t plain;
136     gpgme_error_t err;
137     char line[128+32];
138     int pos = 0;
139     int sig_begin = 0;
140    
141 twoaday 25 if (r_plain)
142     *r_plain = NULL;
143     err = gpgme_data_new (&plain);
144     if (err)
145 twoaday 23 return err;
146    
147 twoaday 25 while (gpg_data_readline (sig, line, 128) > 0) {
148     if (!strncmp (line, "-----BEGIN PGP SIGNED MESSAGE", 29) ||
149     !strncmp (line, "Version:", 8) ||
150     !strncmp (line, "Comment:", 8) ||
151     !strncmp (line, "Charset:", 8) ||
152     !strncmp (line, "Hash:", 5) ||
153     !strncmp (line, "MessageID", 9))
154 twoaday 23 continue;
155 twoaday 25 if (strlen (line) <= 2)
156 twoaday 23 break; /* parsed all headers, now we reached the body */
157     }
158 twoaday 25 /* XXX handle multi dash escaped sequences */
159     while (gpg_data_readline (sig, line, 128) > 0 ) {
160     if (!strncmp( line, "-----BEGIN PGP SIGNATURE", 24))
161 twoaday 23 break; /* end of plaintext */
162 twoaday 25 if (!strncmp (line, "- -", 3))
163 twoaday 23 pos = 2;
164     gpgme_data_write (plain, line+pos, strlen (line+pos));
165     pos = 0;
166     }
167     gpgme_data_write (plain, "", 1);
168 twoaday 25 if (r_plain)
169 twoaday 23 *r_plain = plain;
170     else
171 twoaday 25 gpgme_data_release (plain);
172 twoaday 23 return err;
173 twoaday 24 }
174 twoaday 23
175    
176 twoaday 24 /* Release the data in @dh and store the contents in the file @fname.
177     Return value: 0 on success. */
178 twoaday 23 gpgme_error_t
179     gpg_data_release_and_set_file (gpgme_data_t dh, const char *fname)
180     {
181     char *p = NULL;
182     FILE *fp;
183     size_t n;
184    
185     fp = fopen (fname, "wb");
186     if (fp == NULL)
187     return gpg_err_code_from_errno (errno);
188    
189     p = gpgme_data_release_and_get_mem (dh, &n);
190     if (p) {
191 twoaday 24 fwrite (p, 1, n, fp);
192 twoaday 23 fflush (fp);
193 twoaday 24 memset (p, 0xFF, n);
194 twoaday 25 free (p); /* XXX: gpgme_free (p); */
195 twoaday 23 }
196     fclose (fp);
197     return 0;
198 twoaday 24 }
199    
200    
201     /* Try to read a line, terminated by \n from the given
202     gpgme data object @dh into @line.
203     Return value: numbers of chars read. */
204     size_t
205     gpg_data_readline (gpgme_data_t dh, char *line, size_t nbytes)
206     {
207     char ch = 0;
208     int nread = 0, pos = 0;
209    
210     if (!dh)
211     return 0;
212    
213     memset (line, 0, nbytes);
214     while ((nread=gpgme_data_read (dh, &ch, 1)) > 0) {
215     if (!nread)
216     break;
217     if (ch == '\n') {
218     line[pos++] = ch;
219     line[pos++] = '\0';
220     break;
221     }
222     line[pos++] = ch;
223     if (pos > (int)nbytes) {
224     line[pos++] = '\0';
225     break;
226     }
227     }
228    
229     return pos;
230     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26