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

Contents of /trunk/w32gpgme/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 24 - (show annotations)
Sat Oct 8 10:43:08 2005 UTC (19 years, 4 months ago) by twoaday
File MIME type: text/plain
File size: 5796 byte(s)
Bug fixes to correct some problems introduced by
the MyGPGME to GPGME port.

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26