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

Annotation of /trunk/MyGPGME/data.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Mon Jan 31 11:02:21 2005 UTC (20 years, 1 month ago) by twoaday
File MIME type: text/plain
File size: 26612 byte(s)
WinPT initial checkin.


1 twoaday 2 /* data.c
2     * Copyright (C) 2000-2003 Werner Koch (dd9jn), g10 Code GmbH
3     * Copyright (C) 2001-2004 Timo Schulz
4     *
5     * This file is part of MyGPGME.
6     *
7     * MyGPGME is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 2 of the License, or
10     * (at your option) any later version.
11     *
12     * MyGPGME is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20     */
21    
22     #include <stdio.h>
23     #include <stdlib.h>
24     #include <string.h>
25     #include <assert.h>
26     #include <errno.h>
27     #include <sys/types.h>
28     #include <sys/stat.h>
29     #include <process.h>
30     #include <io.h>
31     #include <windows.h>
32    
33     #include "util.h"
34     #include "context.h"
35     #include "ops.h"
36    
37     #define ALLOC_CHUNK 1024
38     #define MAX_FILESIZE 16777216
39    
40     static char pgm_string[128] = "OpenPrivacy";
41    
42    
43     /**
44     * gpgme_data_new:
45     * @r_dh: returns the new data object
46     *
47     * Create a new data object without any content.
48     *
49     * Return value: An error value or 0 on success
50     **/
51     gpgme_error_t
52     gpgme_data_new (gpgme_data_t * r_dh)
53     {
54     gpgme_data_t dh;
55    
56     if (!r_dh)
57     return mk_error (Invalid_Value);
58     *r_dh = NULL;
59     dh = calloc (1, sizeof *dh);
60     if (!dh)
61     return mk_error (Out_Of_Core);
62     dh->mode = GPGME_DATA_MODE_INOUT;
63     *r_dh = dh;
64     return 0;
65     } /* gpgme_data_new */
66    
67    
68     /**
69     * gpgme_data_new_from_mem:
70     * @r_dh: Returns a new data object.
71     * @buffer: Initialize with this.
72     * @size: Size of the buffer
73     * @copy: Flag wether a copy of the buffer should be used.
74     *
75     * Create a new data object and initialize with data
76     * from the memory. A @copy with value %TRUE creates a copy of the
77     * memory, a value of %FALSE uses the original memory of @buffer and the
78     * caller has to make sure that this buffer is valid until gpgme_release_data()
79     * is called.
80     *
81     * Return value:
82     **/
83     gpgme_error_t
84     gpgme_data_new_from_mem (gpgme_data_t * r_dh,
85     const char * buffer, size_t size, int copy)
86     {
87     gpgme_data_t dh;
88     gpgme_error_t err;
89     char * p;
90    
91     if (!r_dh || !buffer)
92     return mk_error (Invalid_Value);
93     *r_dh = NULL;
94     err = gpgme_data_new (&dh);
95     if (err)
96     return err;
97     dh->len = size;
98     if (copy) {
99     p = dh->private_buffer = malloc (size? size : 1);
100     if (!p) {
101     gpgme_data_release (dh);
102     return mk_error (Out_Of_Core);
103     }
104     dh->private_len = size;
105     memcpy (dh->private_buffer, buffer, size);
106     dh->data = dh->private_buffer;
107     dh->writepos = size;
108     }
109     else
110     dh->data = buffer;
111     dh->type = GPGME_DATA_TYPE_MEM;
112     *r_dh = dh;
113     return 0;
114     }
115    
116    
117     gpgme_error_t
118     gpgme_data_new_with_read_cb (gpgme_data_t *r_dh,
119     int (*read_cb)(void*,char *,size_t,size_t*),
120     void *read_cb_value)
121     {
122     gpgme_data_t dh;
123     gpgme_error_t err;
124    
125     if (!r_dh || !read_cb)
126     return mk_error (Invalid_Value);
127     *r_dh = NULL;
128     err = gpgme_data_new (&dh);
129     if (err)
130     return err;
131     dh->type = GPGME_DATA_TYPE_CB;
132     dh->mode = GPGME_DATA_MODE_OUT;
133     dh->read_cb = read_cb;
134     dh->read_cb_value = read_cb_value;
135    
136     *r_dh = dh;
137     return 0;
138     }
139    
140     /**
141     * gpgme_data_new_from_file:
142     * @r_dh: returns the new data object
143     * @fname: filename
144     *
145     * Create a new data object and initialize it with the content of
146     * the file @file. If @copy is %True the file is immediately read in
147     * adn closed. @copy of %False is not yet supportted.
148     *
149     * Return value: An error code or 0 on success. If the error code is
150     * %GPGME_File_Error, the OS error code is held in %errno.
151     **/
152     gpgme_error_t
153     gpgme_data_new_from_file (gpgme_data_t * r_dh, const char * fname)
154     {
155     gpgme_data_t dh;
156     gpgme_error_t err;
157     struct stat st;
158     FILE *fp;
159    
160     if (!r_dh)
161     return mk_error (Invalid_Value);
162     *r_dh = NULL;
163     if (!fname)
164     return mk_error (Invalid_Value);
165    
166     err = gpgme_data_new (&dh);
167     if (err)
168     return err;
169    
170     fp = my_fopen (fname, "rb");
171     if (!fp) {
172     int save_errno = errno;
173     gpgme_data_release (dh);
174     errno = save_errno;
175     return mk_error (File_Error);
176     }
177    
178     if (fstat (fileno (fp), &st)) {
179     int save_errno = errno;
180     fclose (fp);
181     gpgme_data_release (dh);
182     errno = save_errno;
183     return mk_error (File_Error);
184     }
185    
186     /* Check to disallow to load large files */
187     if (st.st_size > MAX_FILESIZE) {
188     fclose (fp);
189     gpgme_data_release (dh);
190     return mk_error (General_Error);
191     }
192     dh->private_buffer = malloc (st.st_size? st.st_size : 1);
193     if (!dh->private_buffer) {
194     fclose (fp);
195     gpgme_data_release (dh);
196     return mk_error (Out_Of_Core);
197     }
198     dh->private_len = st.st_size;
199    
200     if (fread (dh->private_buffer, dh->private_len, 1, fp) != 1) {
201     int save_errno = errno;
202     fclose (fp);
203     gpgme_data_release (dh);
204     errno = save_errno;
205     return mk_error (File_Error);
206     }
207     fclose (fp);
208    
209     dh->len = dh->private_len;
210     dh->data = dh->private_buffer;
211     dh->writepos = dh->len;
212     dh->type = GPGME_DATA_TYPE_MEM;
213    
214     *r_dh = dh;
215     return 0;
216     }
217    
218    
219     gpgme_error_t
220     gpgme_data_new_from_filepart (gpgme_data_t *r_dh, const char *fname, FILE *fp,
221     long offset, ulong length)
222     {
223     gpgme_data_t dh;
224     gpgme_error_t err;
225    
226     if (!r_dh)
227     return mk_error (Invalid_Value);
228     *r_dh = NULL;
229     if ( fname && fp ) /* these are mutual exclusive */
230     return mk_error (Invalid_Value);
231     if (!fname && !fp)
232     return mk_error (Invalid_Value);
233     if (!length)
234     return mk_error (Invalid_Value);
235    
236     err = gpgme_data_new ( &dh );
237     if (err)
238     return err;
239    
240     if (!fp) {
241     fp = my_fopen (fname, "rb");
242     if (!fp) {
243     int save_errno = errno;
244     gpgme_data_release (dh);
245     errno = save_errno;
246     return mk_error (File_Error);
247     }
248     }
249    
250     if ( fseek ( fp, offset, SEEK_SET) ) {
251     int save_errno = errno;
252     if (fname)
253     fclose (fp);
254     gpgme_data_release (dh);
255     errno = save_errno;
256     return mk_error (File_Error);
257     }
258    
259    
260     dh->private_buffer = malloc ( length? length : 1 );
261     if( !dh->private_buffer ) {
262     if( fname )
263     fclose( fp );
264     gpgme_data_release (dh);
265     return mk_error (Out_Of_Core);
266     }
267     dh->private_len = length;
268    
269     if ( fread ( dh->private_buffer, dh->private_len, 1, fp ) != 1 ) {
270     int save_errno = errno;
271     if (fname)
272     fclose (fp);
273     gpgme_data_release (dh);
274     errno = save_errno;
275     return mk_error (File_Error);
276     }
277    
278     if (fname)
279     fclose (fp);
280    
281     dh->len = dh->private_len;
282     dh->data = dh->private_buffer;
283     dh->writepos = dh->len;
284     dh->type = GPGME_DATA_TYPE_MEM;
285    
286     *r_dh = dh;
287     return 0;
288     }
289    
290    
291     /**
292     * gpgme_data_release:
293     * @dh: Data object
294     *
295     * Release the data object @dh. @dh may be NULL in which case nothing
296     * happens.
297     **/
298     void
299     gpgme_data_release (gpgme_data_t dh)
300     {
301     if (dh) {
302     safe_free (dh->private_buffer);
303     safe_free (dh);
304     }
305     } /* gpgme_data_release */
306    
307    
308     char *
309     _gpgme_data_release_and_return_string (gpgme_data_t dh)
310     {
311     char *val = NULL;
312    
313     if (!dh)
314     return val;
315    
316     if (!_gpgme_data_append (dh, "", 1)) { /* append EOS */
317     val = dh->private_buffer;
318     if (!val && dh->data) {
319     val = malloc (dh->len);
320     if (val)
321     memcpy (val, dh->data, dh->len);
322     }
323     }
324     safe_free (dh);
325     return val;
326     }
327    
328    
329     /**
330     * gpgme_data_release_and_get_mem:
331     * @dh: the data object
332     * @r_len: returns the length of the memory
333     *
334     * Release the data object @dh and return its content and the length
335     * of that content. The caller has to free this data. @dh maybe NULL
336     * in which case NULL is returned. If there is not enough memory for
337     * allocating the return value, NULL is returned and the object is
338     * released.
339     *
340     * Return value: a pointer to an allocated buffer of length @r_len.
341     **/
342     char *
343     gpgme_data_release_and_get_mem (gpgme_data_t dh, size_t *r_len)
344     {
345     char *val = NULL;
346    
347     if (r_len)
348     *r_len = 0;
349     if (dh) {
350     size_t len = dh->len;
351     val = dh->private_buffer;
352     if ( !val && dh->data ) {
353     val = malloc (len);
354     if ( val )
355     memcpy (val, dh->data, len);
356     }
357     safe_free (dh);
358     if (val && r_len)
359     *r_len = len;
360     }
361     return val;
362     }
363    
364    
365     /**
366     * gpgme_data_get_type:
367     * @dh: the data object
368     *
369     * Get the type of the data object.
370     * Data types are prefixed with %GPGME_DATA_TYPE_
371     *
372     * Return value: the data type
373     **/
374     gpgme_data_type_t
375     gpgme_data_get_type ( gpgme_data_t dh )
376     {
377     if ( !dh || (!dh->data && !dh->read_cb))
378     return GPGME_DATA_TYPE_NONE;
379    
380     return dh->type;
381     }
382    
383     void
384     _gpgme_data_set_mode( gpgme_data_t dh, gpgme_data_mode_t mode )
385     {
386     assert( dh );
387     dh->mode = mode;
388     }
389    
390    
391     gpgme_data_mode_t
392     _gpgme_data_get_mode( gpgme_data_t dh )
393     {
394     assert( dh );
395     return dh->mode;
396     }
397    
398     /**
399     * gpgme_data_rewind:
400     * @dh: the data object
401     *
402     * Prepare the data object in a way, that a gpgme_data_read() does start
403     * at the beginning of the data. This has to be done for all types
404     * of data objects.
405     *
406     * Return value: An error code or 0 on success
407     **/
408     gpgme_error_t
409     gpgme_data_rewind ( gpgme_data_t dh )
410     {
411     if ( !dh )
412     return mk_error (Invalid_Value);
413    
414     if ( dh->type == GPGME_DATA_TYPE_NONE
415     || dh->type == GPGME_DATA_TYPE_MEM ) {
416     dh->readpos = 0;
417     }
418     else if (dh->type == GPGME_DATA_TYPE_CB) {
419     dh->len = dh->readpos = 0;
420     dh->read_cb_eof = 0;
421     /* FIXME: do a special call to the read function to trigger a rewind
422     there */
423     }
424     else
425     return mk_error (General_Error);
426     return 0;
427     }
428    
429     /**
430     * gpgme_data_read:
431     * @dh: the data object
432     * @buffer: A buffer
433     * @length: The length of that bufer
434     * @nread: Returns the number of bytes actually read.
435     *
436     * Copy data from the current read position (which may be set by
437     * gpgme_data_rewind()) to the supplied @buffer, max. @length bytes
438     * are copied and the actual number of bytes are returned in @nread.
439     * If there are no more bytes available %GPGME_EOF is returned and @nread
440     * is set to 0.
441     *
442     * Return value: An errorcode or 0 on success, EOF is indcated by the
443     * error code GPGME_EOF.
444     **/
445     gpgme_error_t
446     gpgme_data_read ( gpgme_data_t dh, char *buffer, size_t length, size_t *nread )
447     {
448     size_t nbytes;
449    
450     if ( !dh )
451     return mk_error (Invalid_Value);
452     if (dh->type == GPGME_DATA_TYPE_MEM ) {
453     nbytes = dh->len - dh->readpos;
454     if ( !nbytes ) {
455     *nread = 0;
456     return mk_error(EOF);
457     }
458     if (nbytes > length)
459     nbytes = length;
460     memcpy ( buffer, dh->data + dh->readpos, nbytes );
461     *nread = nbytes;
462     dh->readpos += nbytes;
463     }
464     else if (dh->type == GPGME_DATA_TYPE_CB) {
465     nbytes = dh->len - dh->readpos;
466     if ( nbytes ) {
467     /* we have unread data - return this */
468     if (nbytes > length)
469     nbytes = length;
470     memcpy ( buffer, dh->data + dh->readpos, nbytes );
471     *nread = nbytes;
472     dh->readpos += nbytes;
473     }
474     else { /* get the data from the callback */
475     if (!dh->read_cb || dh->read_cb_eof) {
476     *nread = 0;
477     return mk_error (EOF);
478     }
479     if (dh->read_cb (dh->read_cb_value, buffer, length, nread )) {
480     *nread = 0;
481     dh->read_cb_eof = 1;
482     return mk_error (EOF);
483     }
484     }
485     }
486     else
487     return mk_error (General_Error);
488     return 0;
489     }
490    
491    
492     gpgme_error_t
493     _gpgme_data_eof( gpgme_data_t dh )
494     {
495     if( !dh )
496     return mk_error( Invalid_Value );
497     if( dh->type == GPGME_DATA_TYPE_MEM ) {
498     size_t nbytes = dh->len - dh->readpos;
499     if( !nbytes )
500     return mk_error( EOF );
501     }
502     return 0;
503     }
504    
505    
506     gpgme_error_t
507     _gpgme_data_unread (gpgme_data_t dh, const char *buffer, size_t length )
508     {
509     if( !dh )
510     return mk_error (Invalid_Value);
511     if( dh->type == GPGME_DATA_TYPE_MEM ) {
512     /* check that we don't unread more than we have yet read */
513     if( dh->readpos < length )
514     return mk_error( Invalid_Value );
515     /* No need to use the buffer for this data type */
516     dh->readpos -= length;
517     }
518     else {
519     return mk_error( General_Error );
520     }
521     return 0;
522     }
523    
524    
525     /*
526     * This function does make sense when we know that it contains no nil chars.
527     */
528     char *
529     _gpgme_data_get_as_string ( gpgme_data_t dh )
530     {
531     char *val = NULL;
532    
533     if (dh) {
534     val = malloc ( dh->len+1 );
535     if ( val ) {
536     memcpy ( val, dh->data, dh->len );
537     val[dh->len] = 0;
538     }
539     }
540     return val;
541     }
542    
543    
544     /**
545     * gpgme_data_write:
546     * @dh: the context
547     * @buffer: data to be written to the data object
548     * @length: length o this data
549     *
550     * Write the content of @buffer to the data object @dh at the current write
551     * position.
552     *
553     * Return value: 0 on succress or an errorcode
554     **/
555     gpgme_error_t
556     gpgme_data_write (gpgme_data_t dh, const char *buffer, size_t length)
557     {
558     if (!dh || !buffer)
559     return mk_error (Invalid_Value);
560    
561     return _gpgme_data_append (dh, buffer, length );
562     }
563    
564    
565     gpgme_error_t
566     _gpgme_data_append ( gpgme_data_t dh, const char *buffer, size_t length )
567     {
568     assert (dh);
569    
570     if ( dh->type == GPGME_DATA_TYPE_NONE ) {
571     /* convert it to a mem data type */
572     assert (!dh->private_buffer);
573     dh->type = GPGME_DATA_TYPE_MEM;
574     dh->private_len = length < ALLOC_CHUNK? ALLOC_CHUNK : length;
575     dh->private_buffer = malloc ( dh->private_len );
576     if( !dh->private_buffer ) {
577     dh->private_len = 0;
578     return mk_error (Out_Of_Core);
579     }
580     dh->writepos = 0;
581     dh->data = dh->private_buffer;
582     }
583     else if ( dh->type != GPGME_DATA_TYPE_MEM )
584     return mk_error (Invalid_Type);
585    
586     if ( dh->mode != GPGME_DATA_MODE_INOUT
587     && dh->mode != GPGME_DATA_MODE_IN )
588     return mk_error (Invalid_Mode);
589    
590     if ( !dh->private_buffer ) {
591     /* we have to copy it now */
592     assert (dh->data);
593     dh->private_len = dh->len+length;
594     if (dh->private_len < ALLOC_CHUNK)
595     dh->private_len = ALLOC_CHUNK;
596     dh->private_buffer = malloc ( dh->private_len );
597     if (!dh->private_buffer) {
598     dh->private_len = 0;
599     return mk_error (Out_Of_Core);
600     }
601     memcpy ( dh->private_buffer, dh->data, dh->len );
602     dh->writepos = dh->len;
603     dh->data = dh->private_buffer;
604     }
605    
606     /* allocate more memory if needed */
607     if ( dh->writepos + length > dh->private_len ) {
608     char *p;
609     size_t newlen = dh->private_len
610     + (dh->len < ALLOC_CHUNK? ALLOC_CHUNK : length);
611     p = realloc ( dh->private_buffer, newlen );
612     if ( !p )
613     return mk_error (Out_Of_Core);
614     dh->private_buffer = p;
615     dh->private_len = newlen;
616     dh->data = dh->private_buffer;
617     assert ( !(dh->writepos + length > dh->private_len) );
618     }
619    
620     memcpy ( dh->private_buffer + dh->writepos, buffer, length );
621     dh->writepos += length;
622     dh->len += length;
623    
624     return 0;
625     }
626    
627     gpgme_error_t
628     _gpgme_data_append_string ( gpgme_data_t dh, const char *s )
629     {
630     return _gpgme_data_append ( dh, s, s? strlen(s):0 );
631     }
632    
633    
634     gpgme_error_t
635     _gpgme_data_read_from_tmpfile( gpgme_data_t dh )
636     {
637     FILE *fp;
638     size_t n;
639     unsigned char buf[512];
640    
641     gpgme_data_rewind( dh );
642     fp = fopen( _gpgme_get_tmpfile(0), "rb" );
643     if( fp == NULL )
644     return mk_error( File_Error );
645     while( !feof(fp) ) {
646     memset(buf, 0, sizeof buf );
647     n = fread(buf, 1, sizeof buf - 1, fp );
648     if( n > 0 )
649     gpgme_data_write( dh, buf, n );
650     }
651     fclose( fp );
652     return 0;
653     } /* _gpgme_data_read_from_tmpfile */
654    
655    
656     gpgme_error_t
657     _gpgme_data_write_to_tmpfile( gpgme_data_t dh )
658     {
659     FILE *fp;
660     char *p;
661    
662     gpgme_data_rewind( dh );
663     fp = fopen( _gpgme_get_tmpfile(1), "wb" );
664     if( fp == NULL )
665     return mk_error( File_Error );
666     p = _gpgme_data_get_as_string( dh );
667     if( p ) {
668     fwrite( p, 1, strlen( p ), fp );
669     safe_free( p );
670     }
671     fclose( fp );
672     return 0;
673     } /* _gpgme_data_write_to_tmpfile */
674    
675     char*
676     gpgme_data_get_as_string( gpgme_data_t dh )
677     {
678     return _gpgme_data_get_as_string( dh );
679     } /* gpgme_data_get_as_string */
680    
681     char*
682     gpgme_data_release_and_return_string( gpgme_data_t dh )
683     {
684     return _gpgme_data_release_and_return_string( dh );
685     } /* gpgme_data_release_and_return_string */
686    
687     gpgme_error_t
688     gpgme_data_release_and_set_file( gpgme_data_t dh, const char *fname )
689     {
690     char *p = NULL;
691     FILE *fp;
692    
693     fp = my_fopen( fname, "wb" );
694     if( fp == NULL )
695     return mk_error( File_Error );
696    
697     p = _gpgme_data_release_and_return_string( dh );
698     if( p ) {
699     fwrite( p, 1, strlen( p ), fp );
700     fflush( fp );
701     safe_free( p );
702     }
703     fclose( fp );
704    
705     return 0;
706     } /* gpgme_data_release_and_set_file */
707    
708    
709     size_t
710     gpgme_data_readline( gpgme_data_t dh, char * line, size_t nbytes )
711     {
712     char ch = 0;
713     size_t nread = 0, pos = 0;
714    
715     if( !dh )
716     return 0;
717    
718     memset( line, 0, nbytes );
719     while( !gpgme_data_read( dh, &ch, 1, &nread ) ) {
720     if( !nread )
721     break;
722     if( ch == '\n' ) {
723     line[pos++] = ch;
724     line[pos++] = '\0';
725     break;
726     }
727     line[pos++] = ch;
728     if( pos > nbytes ) {
729     line[pos++] = '\0';
730     break;
731     }
732     }
733    
734     return pos;
735     } /* gpgme_data_readline */
736    
737    
738     static char*
739     wrap_lines_soft( char *buf, int wraplen )
740     {
741     char *curpos, *lastspc, *lastbrk;
742    
743     for( curpos = lastspc = lastbrk = buf; *curpos; curpos++ ) {
744     if( *curpos == ' ' )
745     lastspc = curpos;
746     else {
747     if( *curpos == '\n' ) {
748     lastbrk = curpos;
749     lastspc = lastbrk;
750     }
751     }
752     if( (curpos - lastbrk) >= wraplen ) {
753     *lastspc = '\n';
754     lastbrk = lastspc;
755     }
756     }
757    
758     return buf;
759     } /* wrap_lines_soft */
760    
761     static char*
762     wrap_lines( char *buf, size_t bufsize, size_t wraplen )
763     {
764     char *soft, *hard, *p;
765     size_t pos = 0, size = 0;
766    
767     soft = wrap_lines_soft( buf, wraplen );
768     if( !soft )
769     return NULL;
770     hard = malloc (bufsize + (bufsize/10));
771     if( !hard )
772     return NULL;
773     strcpy (hard, soft);
774     while( soft ) {
775     p = strchr( soft, '\n' );
776     if( p == NULL )
777     break;
778     pos = p - soft + 1;
779     if( soft[pos-2] != '\r' ) {
780     memcpy( hard + size, soft, pos-1 );
781     size += (pos-1);
782     memcpy( hard + size, "\r\n", 2 );
783     size += 2;
784     }
785     else {
786     memcpy( hard+size, soft, pos );
787     size += pos;
788     }
789     soft += pos;
790     }
791    
792     memcpy( hard + size, "\0", 1 );
793     return hard;
794     } /* wrap_lines */
795    
796    
797     int
798     gpgme_data_wrap_lines( gpgme_data_t *r_dh, size_t wraplen )
799     {
800     gpgme_error_t err = 0;
801     gpgme_data_t mdh;
802     char *raw, *p;
803     size_t nlen;
804    
805     err = gpgme_data_new( &mdh );
806     if( err )
807     return err;
808    
809     raw = _gpgme_data_get_as_string( *r_dh );
810     if( !raw ) {
811     gpgme_data_release( mdh );
812     return mk_error( General_Error );
813     }
814     nlen = strlen( raw );
815     if( !strchr( raw, '\n' ) && nlen < wraplen ) {
816     gpgme_data_release( mdh );
817     safe_free( raw );
818     return 0;
819     }
820    
821     p = wrap_lines( raw, nlen, wraplen );
822     if( p )
823     _gpgme_data_append_string( mdh, p );
824     gpgme_data_release( *r_dh );
825     *r_dh = mdh;
826     safe_free( raw );
827     safe_free( p );
828     return 0;
829     } /* gpgme_data_wrap_lines */
830    
831    
832     gpgme_error_t
833     gpgme_data_mail_quote (gpgme_data_t *r_dh)
834     {
835     gpgme_data_t dh;
836     char buf[128];
837    
838     if (!*r_dh)
839     return mk_error (Invalid_Value);
840     gpgme_data_new (&dh);
841     while (gpgme_data_readline (*r_dh, buf, 127)) {
842     gpgme_data_write (dh, "> ", 2);
843     gpgme_data_write (dh, buf, strlen (buf));
844     }
845     gpgme_data_release (*r_dh);
846     *r_dh = dh;
847     return 0;
848     }
849    
850    
851     gpgme_error_t
852     gpgme_data_extract_plaintext( gpgme_data_t sig, gpgme_data_t *r_plain )
853     {
854     gpgme_data_t plain;
855     gpgme_error_t err;
856     char line[128+32];
857     int pos = 0;
858     int sig_begin = 0;
859    
860     err = gpgme_data_new( &plain );
861     if( err ) {
862     if( r_plain )
863     *r_plain = NULL;
864     return err;
865     }
866    
867     while( gpgme_data_readline( sig, line, 128 ) ) {
868     if( !strncmp( line, "-----BEGIN PGP SIGNED MESSAGE", 29 )
869     || !strncmp( line, "Version:", 8 )
870     || !strncmp( line, "Comment:", 8 )
871     || !strncmp( line, "Charset:", 8 )
872     || !strncmp( line, "Hash:", 5 )
873     || !strncmp (line, "MessageID", 9))
874     continue;
875     if( strlen( line ) <= 2 )
876     break; /* parsed all headers, now we reached the body */
877     }
878     /* fixme: handle multi dash escaped sequences! */
879     while( gpgme_data_readline( sig, line, 128 ) ) {
880     if( !strncmp( line, "-----BEGIN PGP SIGNATURE", 24 ) )
881     break; /* end of plaintext */
882     if( !strncmp( line, "- -", 3 ) )
883     pos = 2;
884     _gpgme_data_append_string( plain, line + pos );
885     pos = 0;
886     }
887     if( r_plain )
888     *r_plain = plain;
889     else
890     gpgme_data_release( plain );
891     return err;
892     } /* gpgme_data_extract_plaintext */
893    
894    
895     gpgme_error_t
896     gpgme_data_change_version( gpgme_data_t *r_dh )
897     {
898     gpgme_error_t err = 0;
899     gpgme_data_t mdh;
900     char line[128+32];
901    
902     err = gpgme_data_new( &mdh );
903     if( err ) {
904     if( r_dh )
905     *r_dh = NULL;
906     return err;
907     }
908     while( gpgme_data_readline( *r_dh, line, 128 ) ) {
909     if( strlen( line ) > 14
910     && !strncmp( line, "Version: GnuPG", 14 )
911     && !strstr( line, pgm_string ) ) {
912     line[strlen( line ) - 2] = '\0';
913     strcat( line, " - " );
914     strcat( line, pgm_string );
915     strcat( line, "\r\n" );
916     }
917     _gpgme_data_append_string( mdh, line );
918     }
919     gpgme_data_release( *r_dh );
920     if( r_dh )
921     *r_dh = mdh;
922     else
923     gpgme_data_release( mdh );
924     return err;
925     } /* gpgme_data_change_version */
926    
927    
928     /* Convert two hexadecimal digits from STR to the value they
929     represent. Returns -1 if one of the characters is not a
930     hexadecimal digit. */
931     static int
932     _gpgme_hextobyte (const unsigned char *str)
933     {
934     int val = 0;
935     int i;
936    
937     #define NROFHEXDIGITS 2
938     for (i = 0; i < NROFHEXDIGITS; i++) {
939     if (*str >= '0' && *str <= '9')
940     val += *str - '0';
941     else if (*str >= 'A' && *str <= 'F')
942     val += 10 + *str - 'A';
943     else if (*str >= 'a' && *str <= 'f')
944     val += 10 + *str - 'a';
945     else
946     return -1;
947     if (i < NROFHEXDIGITS - 1)
948     val *= 16;
949     str++;
950     }
951     return val;
952     }
953    
954    
955     /* Decode the C formatted string SRC and store the result in the
956     buffer *DESTP which is LEN bytes long. If LEN is zero, then a
957     large enough buffer is allocated with malloc and *DESTP is set to
958     the result. Currently, LEN is only used to specify if allocation
959     is desired or not, the caller is expected to make sure that *DESTP
960     is large enough if LEN is not zero. */
961     gpgme_error_t
962     _gpgme_decode_c_string (const char *src, char **destp, size_t len)
963     {
964     char *dest;
965    
966     /* Set up the destination buffer. */
967     if (len)
968     {
969     if (len < strlen (src) + 1)
970     return GPGME_General_Error;
971    
972     dest = *destp;
973     }
974     else
975     {
976     /* The converted string will never be larger than the original
977     string. */
978     dest = malloc (strlen (src) + 1);
979     if (!dest)
980     return GPGME_Out_Of_Core;
981     *destp = dest;
982     }
983    
984     /* Convert the string. */
985     while (*src)
986     {
987     if (*src != '\\')
988     {
989     *(dest++) = *(src++);
990     continue;
991     }
992    
993     switch (src[1])
994     {
995     #define DECODE_ONE(match,result) \
996     case match: \
997     src += 2; \
998     *(dest++) = result; \
999     break;
1000    
1001     DECODE_ONE ('\'', '\'');
1002     DECODE_ONE ('\"', '\"');
1003     DECODE_ONE ('\?', '\?');
1004     DECODE_ONE ('\\', '\\');
1005     DECODE_ONE ('a', '\a');
1006     DECODE_ONE ('b', '\b');
1007     DECODE_ONE ('f', '\f');
1008     DECODE_ONE ('n', '\n');
1009     DECODE_ONE ('r', '\r');
1010     DECODE_ONE ('t', '\t');
1011     DECODE_ONE ('v', '\v');
1012    
1013     case 'x':
1014     {
1015     int val = _gpgme_hextobyte (&src[2]);
1016    
1017     if (val == -1)
1018     {
1019     /* Should not happen. */
1020     *(dest++) = *(src++);
1021     *(dest++) = *(src++);
1022     if (*src)
1023     *(dest++) = *(src++);
1024     if (*src)
1025     *(dest++) = *(src++);
1026     }
1027     else
1028     {
1029     if (!val)
1030     {
1031     /* A binary zero is not representable in a C
1032     string. */
1033     *(dest++) = '\\';
1034     *(dest++) = '0';
1035     }
1036     else
1037     *((unsigned char *) dest++) = val;
1038     src += 4;
1039     }
1040     }
1041    
1042     default:
1043     {
1044     /* Should not happen. */
1045     *(dest++) = *(src++);
1046     *(dest++) = *(src++);
1047     }
1048     }
1049     }
1050     *(dest++) = 0;
1051    
1052     return 0;
1053     }
1054    
1055    
1056     void
1057     gpgme_set_pgm_string (const char * name)
1058     {
1059     if (!name || !*name)
1060     return;
1061     memset (pgm_string, 0, sizeof pgm_string);
1062     strncpy (pgm_string, name, sizeof pgm_string-1);
1063     } /* gpgme_set_pgm_string */

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26