root/openpgpsdk/trunk/src/util.c

Revision 371 (checked in by ben, 7 years ago)

Make sure dmalloc happens last.

Line 
1 /** \file 
2  */
3
4 #include <openpgpsdk/util.h>
5 #include <openpgpsdk/packet-parse.h>
6 #include <openpgpsdk/crypto.h>
7 #include <openpgpsdk/create.h>
8 #include <openpgpsdk/errors.h>
9 #include <stdio.h>
10 #include <assert.h>
11 #include <unistd.h>
12 #include <string.h>
13
14 #include <openpgpsdk/final.h>
15
16 /**
17  * Searches the given map for the given type.
18  * Returns a human-readable descriptive string if found,
19  * returns NULL if not found
20  *
21  * It is the responsibility of the calling function to handle the
22  * error case sensibly (i.e. don't just print out the return string.
23  *
24  */
25 static char *str_from_map_or_null(int type, ops_map_t *map)
26     {
27     ops_map_t *row;
28
29     for ( row=map; row->string != NULL; row++ )
30         if (row->type == type)
31             return row->string;
32     return NULL;
33     }
34
35 /**
36  * \ingroup Utils
37  *
38  * Searches the given map for the given type.
39  * Returns a readable string if found, "Unknown" if not.
40  */
41
42 char *ops_str_from_map(int type, ops_map_t *map)
43     {
44     char *str;
45     str=str_from_map_or_null(type,map);
46     if (str)
47         return(str);
48     else
49         return("Unknown");
50     }
51
52 void hexdump(const unsigned char *src,size_t length)
53     {
54     while(length--)
55         printf("%02X",*src++);
56     }
57
58 /**
59  * \ingroup Utils
60  *
61  * Initialise OpenPGP:SDK. This <b>must</b> be called before any other
62  * OpenPGP:SDK function is used.
63  */
64
65 void ops_init(void)
66     {
67     ops_crypto_init();
68     }
69
70 /**
71  * \ingroup Utils
72  *
73  * Close down OpenPGP:SDK, release any resources under the control of
74  * the library. No OpenPGP:SDK function other than ops_init() should
75  * be called after this function.
76  */
77
78 void ops_finish(void)
79     {
80     ops_crypto_finish();
81     }
82
83 /** Arguments for reader_fd
84  */
85 typedef struct
86     {
87     int fd; /*!< file descriptor */
88     } reader_fd_arg_t;
89
90 /**
91  * \ingroup Parse
92  *
93  * ops_reader_fd() attempts to read up to "plength" bytes from the file
94  * descriptor in "parse_info" into the buffer starting at "dest" using the
95  * rules contained in "flags"
96  *
97  * \param       dest    Pointer to previously allocated buffer
98  * \param       plength Number of bytes to try to read
99  * \param       flags   Rules about reading to use
100  * \param       parse_info      Gets cast to ops_reader_fd_arg_t
101  *
102  * \return      OPS_R_EOF       if no bytes were read
103  * \return      OPS_R_PARTIAL_READ      if not enough bytes were read, and OPS_RETURN_LENGTH is set in "flags"
104  * \return      OPS_R_EARLY_EOF if not enough bytes were read, and OPS_RETURN_LENGTH was not set in "flags"
105  * \return      OPS_R_OK        if expected length was read
106  * \return      OPS_R_ERROR     if cannot read
107  *
108  * OPS_R_EARLY_EOF and OPS_R_ERROR push errors on the stack
109  *
110  * \sa enum opt_reader_ret_t
111  *
112  * \todo change arg_ to typesafe?
113  */
114 static ops_reader_ret_t reader_fd(unsigned char *dest,unsigned *plength,
115                                   ops_reader_flags_t flags,
116                                   ops_error_t **errors,
117                                   ops_reader_info_t *rinfo,
118                                   ops_parse_cb_info_t *cbinfo)
119     {
120     reader_fd_arg_t *arg=ops_reader_get_arg(rinfo);
121     int n=read(arg->fd,dest,*plength);
122
123     OPS_USED(cbinfo);
124
125     if(n == 0)
126         return OPS_R_EOF;
127
128     if(n == -1)
129         {
130         OPS_SYSTEM_ERROR_1(errors,OPS_E_R_READ_FAILED,"read",
131                            "file descriptor %d",arg->fd);
132         return OPS_R_ERROR;
133         }
134
135     if((unsigned)n != *plength)
136         {
137         if(flags&OPS_RETURN_LENGTH)
138             {
139             *plength=n;
140             return OPS_R_PARTIAL_READ;
141             }
142         else
143             {
144             OPS_ERROR_1(errors,OPS_E_R_EARLY_EOF,"file descriptor %d",arg->fd);
145             return OPS_R_EARLY_EOF;
146             }
147         }
148 #if 0
149     printf("[read 0x%x: ",length);
150     hexdump(dest,length);
151     putchar(']');
152 #endif
153     return OPS_R_OK;
154     }
155
156 void ops_reader_set_fd(ops_parse_info_t *pinfo,int fd)
157     {
158     reader_fd_arg_t *arg=malloc(sizeof *arg);
159
160     arg->fd=fd;
161     ops_reader_set(pinfo,reader_fd,arg);
162     }
163
164 typedef struct
165     {
166     const unsigned char *buffer;
167     size_t length;
168     size_t offset;
169     } reader_mem_arg_t;
170
171 static ops_reader_ret_t reader_mem(unsigned char *dest,unsigned *plength,
172                                    ops_reader_flags_t flags,
173                                    ops_error_t **errors,
174                                    ops_reader_info_t *rinfo,
175                                    ops_parse_cb_info_t *cbinfo)
176     {
177     reader_mem_arg_t *arg=ops_reader_get_arg(rinfo);
178     unsigned n;
179
180     OPS_USED(cbinfo);
181
182     if(arg->offset+*plength > arg->length)
183         n=arg->length-arg->offset;
184     else
185         n=*plength;
186
187     if(n == 0)
188         return OPS_R_EOF;
189
190     memcpy(dest,arg->buffer+arg->offset,n);
191     arg->offset+=n;
192
193     if(n != *plength)
194         {
195         if(flags&OPS_RETURN_LENGTH)
196             {
197             *plength=n;
198             return OPS_R_PARTIAL_READ;
199             }
200         else
201             {
202             OPS_ERROR(errors,OPS_E_R_EARLY_EOF,"memory block");
203             return OPS_R_EARLY_EOF;
204             }
205         }
206
207     return OPS_R_OK;
208     }
209
210 // Note that its the caller's responsibility to ensure buffer continues to
211 // exist
212 void ops_reader_set_memory(ops_parse_info_t *pinfo,const void *buffer,
213                            size_t length)
214     {
215     reader_mem_arg_t *arg=malloc(sizeof *arg);
216
217     arg->buffer=buffer;
218     arg->length=length;
219     ops_reader_set(pinfo,reader_mem,arg);
220     }
221
222 void *ops_mallocz(size_t n)
223     {
224     void *m=malloc(n);
225
226     memset(m,'\0',n);
227
228     return m;
229     }
230
231 typedef struct
232     {
233     unsigned short sum;
234     } sum16_arg_t;
235
236 static ops_reader_ret_t sum16_reader(unsigned char *dest,
237                                     unsigned *plength,
238                                     ops_reader_flags_t flags,
239                                     ops_error_t **errors,
240                                     ops_reader_info_t *rinfo,
241                                     ops_parse_cb_info_t *cbinfo)
242     {
243     sum16_arg_t *arg=ops_reader_get_arg(rinfo);
244     ops_reader_ret_t ret=ops_stacked_read(dest,plength,flags,errors,rinfo,
245                                           cbinfo);
246     unsigned n;
247
248     for(n=0 ; n < *plength ; ++n)
249         arg->sum=(arg->sum+dest[n])&0xffff;
250
251     return ret;
252     }
253
254 void ops_reader_push_sum16(ops_parse_info_t *pinfo)
255     {
256     sum16_arg_t *arg=ops_mallocz(sizeof *arg);
257
258     ops_reader_push(pinfo,sum16_reader,arg);
259     }
260
261 unsigned short ops_reader_pop_sum16(ops_parse_info_t *pinfo)
262     {
263     sum16_arg_t *arg=ops_reader_get_arg(ops_parse_get_rinfo(pinfo));
264     unsigned short sum=arg->sum;
265
266     ops_reader_pop(pinfo);
267     free(arg);
268
269     return sum;
270     }
Note: See TracBrowser for help on using the browser.