Changeset 320

Show
Ignore:
Timestamp:
12/07/05 09:39:44
Author:
ben
Message:

Out of time - hopefully a working refactoring of readers and callbacks.

Armour has not been tested.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • openpgpsdk/trunk/examples/common.c

    r305 r320  
    55#include <assert.h> 
    66 
    7 static ops_parse_callback_return_t 
    8 callback(const ops_parser_content_t *content,void *arg_
     7static ops_parse_cb_return_t 
     8callback(const ops_parser_content_t *content,ops_parse_cb_info_t *cbinfo
    99    { 
    10     ops_secret_key_t **skey=arg_
     10    ops_secret_key_t **skey=ops_parse_cb_get_arg(cbinfo)
    1111 
    1212    if(content->tag == OPS_PTAG_CT_SECRET_KEY) 
     
    2222ops_secret_key_t *get_secret_key(const char *keyfile) 
    2323    { 
    24     ops_reader_fd_arg_t arg; 
    25     ops_parse_info_t parse_info; 
     24    ops_parse_info_t *pinfo; 
    2625    ops_secret_key_t *skey; 
     26    int fd; 
    2727 
    28     ops_parse_info_init(&parse_info); 
    29     parse_info.cb=callback; 
    30  
    31     arg.fd=open(keyfile,O_RDONLY); 
    32     assert(arg.fd >= 0); 
    33     parse_info.reader_arg=&arg; 
    34     parse_info.reader=ops_reader_fd; 
     28    pinfo=ops_parse_info_new(); 
    3529 
    3630    skey=NULL; 
    37     parse_info.cb_arg=&skey
     31    ops_parse_cb_set(pinfo,callback,&skey)
    3832 
    39     ops_parse(&parse_info); 
     33    fd=open(keyfile,O_RDONLY); 
     34    assert(fd >= 0); 
     35    ops_reader_set_fd(pinfo,fd); 
     36 
     37    ops_parse(pinfo); 
    4038 
    4139    return skey; 
  • openpgpsdk/trunk/examples/packet-dump.c

    r313 r320  
    313313    } 
    314314 
    315 static ops_parse_callback_return_t 
    316 callback(const ops_parser_content_t *content_,void *arg_
     315static ops_parse_cb_return_t callback(const ops_parser_content_t *content_, 
     316                                     ops_parse_cb_info_t *cbinfo
    317317    { 
    318318    const ops_parser_content_union_t *content=&content_->content; 
     
    320320    char *str; 
    321321 
    322     OPS_USED(arg_); 
     322    OPS_USED(cbinfo); 
    323323 
    324324    switch(content_->tag) 
     
    849849int main(int argc,char **argv) 
    850850    { 
    851     ops_parse_info_t parse_info; 
    852     ops_reader_fd_arg_t arg; 
     851    ops_parse_info_t *pinfo; 
    853852    ops_boolean_t armour=ops_false; 
    854853    int ret; 
     
    874873 
    875874 
    876     ops_parse_info_init(&parse_info); 
     875    pinfo=ops_parse_info_new(); 
    877876    //    ops_parse_packet_options(&opt,OPS_PTAG_SS_ALL,OPS_PARSE_RAW); 
    878     ops_parse_options(&parse_info,OPS_PTAG_SS_ALL,OPS_PARSE_PARSED); 
    879     parse_info.cb=callback; 
    880  
    881     arg.fd=0; 
    882     parse_info.reader_arg=&arg; 
    883     parse_info.reader=ops_reader_fd; 
     877    ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_PARSED); 
     878 
     879    ops_parse_cb_set(pinfo,callback,NULL); 
     880 
     881    ops_reader_set_fd(pinfo,0); 
    884882 
    885883    if(armour) 
    886         { 
    887         parse_info.armour_allow_no_gap=ops_true; 
    888         parse_info.armour_allow_headers_without_gap=ops_true; 
    889         ops_reader_push_dearmour(&parse_info); 
    890         } 
    891  
    892     ret=ops_parse(&parse_info); 
     884        ops_reader_push_dearmour(pinfo,ops_true,ops_true); 
     885 
     886    ret=ops_parse(pinfo); 
    893887    if (!ret) 
    894         { 
    895         print_errors(parse_info.errors); 
    896         } 
     888        ops_print_errors(ops_parse_info_get_errors(pinfo)); 
     889 
     890    ops_parse_info_delete(pinfo); 
    897891 
    898892    return 0; 
  • openpgpsdk/trunk/examples/verify.c

    r308 r320  
    1111int main(int argc,char **argv) 
    1212    { 
    13     ops_parse_info_t parse_info; 
     13    ops_parse_info_t *pinfo; 
    1414    ops_keyring_t keyring; 
    15     ops_reader_fd_arg_t arg; 
    1615    const char *target; 
     16    int fd; 
    1717 
    1818    if(argc != 2) 
     
    2727 
    2828    memset(&keyring,'\0',sizeof keyring); 
    29     ops_parse_info_init(&parse_info); 
    30     arg.fd=open(target,O_RDONLY); 
    31     if(arg.fd < 0) 
     29 
     30    pinfo=ops_parse_info_new(); 
     31 
     32    fd=open(target,O_RDONLY); 
     33    if(fd < 0) 
    3234        { 
    3335        perror(target); 
    3436        exit(2); 
    3537        } 
    36     parse_info.reader_arg=&arg; 
    37     parse_info.reader=ops_reader_fd; 
     38    ops_reader_set_fd(pinfo,fd); 
    3839 
    39     ops_parse_and_accumulate(&keyring,&parse_info); 
     40    ops_parse_and_accumulate(&keyring,pinfo); 
    4041 
    4142    ops_dump_keyring(&keyring); 
  • openpgpsdk/trunk/examples/verify2.c

    r318 r320  
    2626 
    2727// FIXME: should this be a part of the library? 
    28 static ops_parse_callback_return_t 
    29 callback(const ops_parser_content_t *content_,void *arg_
     28static ops_parse_cb_return_t 
     29callback(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo
    3030    { 
    3131    const ops_parser_content_union_t *content=&content_->content; 
    3232    const ops_key_data_t *signer; 
    3333 
    34     OPS_USED(arg_); 
     34    OPS_USED(cbinfo); 
    3535 
    3636    switch(content_->tag) 
     
    122122int main(int argc,char **argv) 
    123123    { 
    124     ops_parse_info_t parse_info; 
    125     ops_reader_fd_arg_t arg
     124    ops_parse_info_t *pinfo; 
     125    int fd
    126126    const char *keyfile; 
    127127    const char *verify; 
     
    153153 
    154154    memset(&keyring,'\0',sizeof keyring); 
    155     ops_parse_info_init(&parse_info); 
    156  
    157     arg.fd=open(keyfile,O_RDONLY); 
    158     if(arg.fd < 0) 
     155 
     156    pinfo=ops_parse_info_new(); 
     157 
     158    fd=open(keyfile,O_RDONLY); 
     159    if(fd < 0) 
    159160        { 
    160161        perror(keyfile); 
     
    162163        } 
    163164 
    164     parse_info.reader_arg=&arg; 
    165     parse_info.reader=ops_reader_fd; 
    166  
    167     ops_parse_and_accumulate(&keyring,&parse_info); 
    168  
    169     close(arg.fd); 
     165    ops_reader_set_fd(pinfo,fd); 
     166 
     167    ops_parse_and_accumulate(&keyring,pinfo); 
     168 
     169    close(fd); 
    170170 
    171171    if(verbose) 
    172172        ops_dump_keyring(&keyring); 
    173173 
    174     ops_parse_info_init(&parse_info); 
    175  
    176     arg.fd=open(verify,O_RDONLY); 
    177     if(arg.fd < 0) 
     174    ops_parse_info_delete(pinfo); 
     175    pinfo=ops_parse_info_new(); 
     176 
     177    fd=open(verify,O_RDONLY); 
     178    if(fd < 0) 
    178179        { 
    179180        perror(verify); 
     
    181182        } 
    182183 
    183     parse_info.reader_arg=&arg; 
    184     parse_info.reader=ops_reader_fd; 
    185  
    186     parse_info.cb=callback; 
     184    ops_reader_set_fd(pinfo,fd); 
     185 
     186    ops_parse_cb_set(pinfo,callback,NULL); 
    187187 
    188188    if(armour) 
    189         ops_reader_push_dearmour(&parse_info); 
    190  
    191     ops_parse(&parse_info); 
     189        ops_reader_push_dearmour(pinfo,ops_false,ops_false); 
     190 
     191    ops_parse(pinfo); 
    192192 
    193193    if(armour) 
    194         ops_reader_pop_dearmour(&parse_info); 
     194        ops_reader_pop_dearmour(pinfo); 
    195195 
    196196    if(signed_data) 
  • openpgpsdk/trunk/include/openpgpsdk/armour.h

    r314 r320  
    22#include "signature.h" 
    33 
    4 void ops_reader_push_dearmour(ops_parse_info_t *parse_info); 
     4void ops_reader_push_dearmour(ops_parse_info_t *parse_info, 
     5                              ops_boolean_t without_gap,ops_boolean_t no_gap); 
     6 
    57void ops_reader_pop_dearmour(ops_parse_info_t *parse_info); 
    68void ops_writer_push_dash_escaped(ops_create_info_t *info, 
  • openpgpsdk/trunk/include/openpgpsdk/errors.h

    r307 r320  
    4949char *ops_errcode(const ops_errcode_t errcode); 
    5050 
    51 void push_error(ops_error_t **errstack,ops_errcode_t errcode,int sys_errno, 
     51void ops_push_error(ops_error_t **errstack,ops_errcode_t errcode,int sys_errno, 
    5252                const char *file,int line,const char *comment,...); 
    53 void print_error(ops_error_t *err); 
    54 void print_errors(ops_error_t *errstack); 
     53void ops_print_error(ops_error_t *err); 
     54void ops_print_errors(ops_error_t *errstack); 
    5555 
    56 #define ops_system_error_1(err,code,syscall,fmt,arg)   do { push_error(err,OPS_E_SYSTEM_ERROR,errno,__FILE__,__LINE__,syscall); push_error(err,code,0,__FILE__,__LINE__,fmt,arg); } while(0) 
    57 #define ops_error_1(err,code,fmt,arg)  do { push_error(err,code,0,__FILE__,__LINE__,fmt,arg); } while(0) 
     56#define OPS_SYSTEM_ERROR_1(err,code,syscall,fmt,arg)   do { ops_push_error(err,OPS_E_SYSTEM_ERROR,errno,__FILE__,__LINE__,syscall); ops_push_error(err,code,0,__FILE__,__LINE__,fmt,arg); } while(0) 
     57#define OPS_ERROR_1(err,code,fmt,arg)  do { ops_push_error(err,code,0,__FILE__,__LINE__,fmt,arg); } while(0) 
    5858 
    5959#endif /* OPS_ERRORS */ 
  • openpgpsdk/trunk/include/openpgpsdk/packet-parse.h

    r287 r320  
    4242    OPS_RELEASE_MEMORY, 
    4343    OPS_KEEP_MEMORY 
    44     } ops_parse_callback_return_t; 
     44    } ops_parse_cb_return_t; 
    4545 
    46 typedef ops_parse_callback_return_t 
    47 ops_packet_parse_callback_t(const ops_parser_content_t *content,void *arg); 
     46typedef struct ops_parse_cb_info ops_parse_cb_info_t; 
    4847 
    49 struct ops_parse_info; 
    50 typedef ops_reader_ret_t ops_packet_reader_t(unsigned char *dest, 
    51                                              unsigned *plength, 
    52                                              ops_reader_flags_t flags, 
    53                                              struct ops_parse_info *parse_info); 
    54  
    55 /** \brief Structure to hold information about a packet parse. 
    56  * 
    57  *  This information includes options about the parse: 
    58  *  - whether the packet contents should be accumulated or not 
    59  *  - whether signature subpackets should be parsed or left raw 
    60  * 
    61  *  It contains options specific to the parsing of armoured data: 
    62  *  - whether headers are allowed in armoured data without a gap 
    63  *  - whether a blank line is allowed at the start of the armoured data 
    64  *   
    65  *  It also specifies : 
    66  *  - the callback function to use and its arguments 
    67  *  - the reader function to use and its arguments 
    68  * 
    69  *  It also contains information about the current state of the parse: 
    70  *  - offset from the beginning 
    71  *  - the accumulated data, if any 
    72  *  - the size of the buffer, and how much has been used 
    73  * 
    74  *  It has a linked list of errors. 
    75  */ 
    76  
    77 struct ops_parse_info 
    78     { 
    79     unsigned char ss_raw[256/8]; /*!< one bit per signature-subpacket type;  
    80                                     set to get raw data */ 
    81     unsigned char ss_parsed[256/8]; /*!< one bit per signature-subpacket type; 
    82                                        set to get parsed data */ 
    83  
    84     ops_packet_parse_callback_t *cb; /*!< the callback function to use when parsing */ 
    85     void *cb_arg; /*!< the args to pass to the callback function */ 
    86  
    87     ops_packet_reader_t *reader; /*!< the reader function to use to get the data to be parsed */ 
    88     void *reader_arg; /*!< the args to pass to the reader function */ 
    89     /* XXX: what do we do about offsets into compressed packets? */ 
    90     unsigned position; /*!< the offset from the beginning (with this reader) */ 
    91  
    92     unsigned accumulate:1;      /*!< set to accumulate packet data */ 
    93     unsigned char *accumulated; /*!< the accumulated data */ 
    94     unsigned asize;     /*!< size of the buffer */ 
    95     unsigned alength;   /*!< used buffer */ 
    96     unsigned armour_allow_headers_without_gap:1; /*!< allow headers in 
    97                                                   armoured data that 
    98                                                   are not separated 
    99                                                   from the data by a 
    100                                                   blank line */ 
    101     unsigned armour_allow_no_gap:1; /*!< allow no blank line at the 
    102                                        start of armoured data */ 
    103     ops_error_t * errors; 
    104     }; 
     48typedef ops_parse_cb_return_t 
     49ops_parse_cb_t(const ops_parser_content_t *content, 
     50               ops_parse_cb_info_t *cbinfo); 
    10551 
    10652typedef struct ops_parse_info ops_parse_info_t; 
     53typedef struct ops_reader_info ops_reader_info_t; 
     54 
     55typedef ops_reader_ret_t ops_reader_t(unsigned char *dest, 
     56                                      unsigned *plength, 
     57                                      ops_reader_flags_t flags, 
     58                                      ops_error_t **errors, 
     59                                      ops_reader_info_t *rinfo, 
     60                                      ops_parse_cb_info_t *cbinfo); 
     61typedef void ops_reader_destroyer_t(ops_reader_info_t *rinfo); 
     62 
     63ops_parse_info_t *ops_parse_info_new(void); 
     64void ops_parse_info_delete(ops_parse_info_t *pinfo); 
     65ops_error_t *ops_parse_info_get_errors(ops_parse_info_t *pinfo); 
     66 
     67void ops_parse_cb_set(ops_parse_info_t *pinfo,ops_parse_cb_t *cb,void *arg); 
     68void ops_parse_cb_push(ops_parse_info_t *pinfo,ops_parse_cb_t *cb,void *arg); 
     69void ops_reader_set(ops_parse_info_t *pinfo,ops_reader_t *reader,void *arg); 
     70void ops_reader_push(ops_parse_info_t *pinfo,ops_reader_t *reader,void *arg); 
     71 
     72void *ops_reader_get_arg(ops_reader_info_t *rinfo); 
     73void *ops_parse_cb_get_arg(ops_parse_cb_info_t *cbinfo); 
     74 
     75ops_parse_cb_return_t ops_parse_cb(const ops_parser_content_t *content, 
     76                                   ops_parse_cb_info_t *cbinfo); 
     77ops_parse_cb_return_t ops_parse_stacked_cb(const ops_parser_content_t *content, 
     78                                           ops_parse_cb_info_t *cbinfo); 
     79ops_reader_info_t *ops_parse_get_rinfo(ops_parse_info_t *pinfo); 
    10780 
    10881int ops_parse(ops_parse_info_t *parse_info); 
     
    12194    }; 
    12295 
    123 /** Initialise structure  
    124  */ 
    125 #define ops_parse_info_init(parse_info) memset(parse_info,'\0',sizeof *parse_info) 
    126  
    12796void ops_parse_options(ops_parse_info_t *parse_info,ops_content_tag_t tag, 
    12897                       ops_parse_type_t type); 
    12998 
    130 int ops_limited_read(unsigned char *dest,unsigned length, 
    131                      ops_region_t *region,ops_parse_info_t *parse_info); 
     99ops_boolean_t ops_limited_read(unsigned char *dest,unsigned length, 
     100                               ops_region_t *region,ops_error_t **errors, 
     101                               ops_reader_info_t *rinfo, 
     102                               ops_parse_cb_info_t *cbinfo); 
     103ops_boolean_t ops_stacked_limited_read(unsigned char *dest,unsigned length, 
     104                                       ops_region_t *region, 
     105                                       ops_error_t **errors, 
     106                                       ops_reader_info_t *rinfo, 
     107                                       ops_parse_cb_info_t *cbinfo); 
     108ops_reader_ret_t ops_stacked_read(unsigned char *dest,unsigned *length, 
     109                               ops_reader_flags_t flags, 
     110                               ops_error_t **errors, 
     111                               ops_reader_info_t *rinfo, 
     112                               ops_parse_cb_info_t *cbinfo); 
    132113 
    133114/* vim:set textwidth=120: */ 
  • openpgpsdk/trunk/include/openpgpsdk/util.h

    r307 r320  
    1313#define ops_true        1 
    1414 
    15 /** Arguments for reader_fd 
    16  */ 
    17 typedef struct 
    18     { 
    19     int fd; /*!< file descriptor */ 
    20     } ops_reader_fd_arg_t; 
    21  
    2215void hexdump(const unsigned char *src,size_t length); 
    23 ops_reader_ret_t ops_reader_fd(unsigned char *dest,unsigned *plength, 
    24                                ops_reader_flags_t flags,ops_parse_info_t *parse_info); 
     16void ops_reader_set_fd(ops_parse_info_t *pinfo,int fd); 
    2517 
    2618/* typesafe deconstification */ 
  • openpgpsdk/trunk/src/accumulate.c

    r317 r320  
    77#include <openpgpsdk/accumulate.h> 
    88#include "keyring_local.h" 
     9#include "parse_local.h" 
    910#include <openpgpsdk/signature.h> 
    1011#include <assert.h> 
     
    1415typedef struct 
    1516    { 
    16     ops_packet_parse_callback_t *cb; 
    17     void *cb_arg; 
    1817    ops_keyring_t *keyring; 
    1918    } accumulate_arg_t; 
     
    2221 * \ingroup Callbacks 
    2322 */ 
    24 static ops_parse_callback_return_t 
    25 accumulate_cb(const ops_parser_content_t *content_,void *arg_
     23static ops_parse_cb_return_t 
     24accumulate_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo
    2625    { 
    27     accumulate_arg_t *arg=arg_
     26    accumulate_arg_t *arg=ops_parse_cb_get_arg(cbinfo)
    2827    const ops_parser_content_union_t *content=&content_->content; 
    2928    ops_keyring_t *keyring=arg->keyring; 
     
    6867    // XXX: we now exclude so many things, we should either drop this or 
    6968    // do something to pass on copies of the stuff we keep 
    70     if(arg->cb) 
    71         return arg->cb(content_,arg->cb_arg); 
    72     return OPS_RELEASE_MEMORY; 
     69    return ops_parse_stacked_cb(content_,cbinfo); 
    7370    } 
    7471 
     
    8481*/ 
    8582 
    86 void ops_parse_and_accumulate(ops_keyring_t *keyring,ops_parse_info_t *parse_info) 
     83void ops_parse_and_accumulate(ops_keyring_t *keyring, 
     84                              ops_parse_info_t *parse_info) 
    8785    { 
    8886    accumulate_arg_t arg; 
    8987 
    90     assert(!parse_info->accumulate); 
     88    assert(!parse_info->rinfo.accumulate); 
    9189 
    9290    memset(&arg,'\0',sizeof arg); 
     
    9593    /* Kinda weird, but to do with counting, and we put it back after */ 
    9694    --keyring->nkeys; 
    97     arg.cb=parse_info->cb; 
    98     arg.cb_arg=parse_info->cb_arg; 
    9995 
    100     parse_info->cb=accumulate_cb; 
    101     parse_info->cb_arg=&arg; 
    102     parse_info->accumulate=1; 
     96    ops_parse_cb_push(parse_info,accumulate_cb,&arg); 
     97 
     98    parse_info->rinfo.accumulate=ops_true; 
     99 
    103100    ops_parse(parse_info); 
    104101    ++keyring->nkeys; 
  • openpgpsdk/trunk/src/armour.c

    r317 r320  
    1515typedef struct 
    1616    { 
    17     ops_packet_reader_t *reader; 
    18     void *reader_arg; 
    1917    enum 
    2018        { 
     
    2422        } state; 
    2523    ops_parse_info_t *parse_info; 
    26     ops_boolean_t seen_nl; 
    27     ops_boolean_t prev_nl; 
     24    ops_boolean_t seen_nl:1; 
     25    ops_boolean_t prev_nl:1; 
     26    ops_boolean_t allow_headers_without_gap:1; /*!< allow headers in 
     27                                                  armoured data that 
     28                                                  are not separated 
     29                                                  from the data by a 
     30                                                  blank line */ 
     31    ops_boolean_t allow_no_gap:1; /*!< allow no blank line at the 
     32                                       start of armoured data */ 
     33 
    2834    // base64 stuff 
    2935    unsigned buffered; 
     
    4349 
    4450// FIXME: move these to a common header 
    45 #define CB(t,pc)       do { (pc)->tag=(t); if(arg->parse_info->cb(pc,arg->parse_info->cb_arg) == OPS_RELEASE_MEMORY) ops_parser_content_free(pc); } while(0) 
    46 #define ERR(err)       do { content.content.error.error=err; content.tag=OPS_PARSER_ERROR; arg->parse_info->cb(&content,arg->parse_info->cb_arg); return OPS_R_EARLY_EOF; } while(0) 
     51#define CB(cbinfo,t,pc)        do { (pc)->tag=(t); if(ops_parse_cb((pc),(cbinfo)) == OPS_RELEASE_MEMORY) ops_parser_content_free(pc); } while(0) 
     52#define ERR(cbinfo,err)        do { content.content.error.error=err; content.tag=OPS_PARSER_ERROR; ops_parse_cb(&content,(cbinfo)); return OPS_R_EARLY_EOF; } while(0) 
    4753 
    4854static void push_back(dearmour_arg_t *arg,const unsigned char *buf, 
     
    5864    } 
    5965     
    60 static int read_char(dearmour_arg_t *arg,ops_boolean_t skip) 
     66static int read_char(dearmour_arg_t *arg,ops_error_t **errors, 
     67                     ops_reader_info_t *rinfo,ops_parse_cb_info_t *cbinfo, 
     68                     ops_boolean_t skip) 
    6169    { 
    6270    unsigned char c[1]; 
    63     ops_packet_reader_t *reader; 
    64     ops_reader_ret_t ret; 
    6571    unsigned length=1; 
    66  
    67     reader=arg->parse_info->reader; 
    68     arg->parse_info->reader=arg->reader; 
    69     arg->parse_info->reader_arg=arg->reader_arg; 
    7072 
    7173    do 
     
    8082                } 
    8183            } 
    82         else if((ret=arg->reader(c,&length,0,arg->reader_arg)) != OPS_R_OK) 
    83             { 
    84             arg->parse_info->reader=reader; 
    85             arg->parse_info->reader_arg=arg; 
    86  
     84        /* XXX: should ops_stacked_read exist? Shouldn't this be a limited_read? */ 
     85        else if(ops_stacked_read(c,&length,0,errors,rinfo,cbinfo) != OPS_R_OK) 
    8786            return -1; 
    88             } 
    8987        } 
    9088    while(skip && c[0] == '\r'); 
    91  
    92     arg->parse_info->reader=reader; 
    93     arg->parse_info->reader_arg=arg; 
    9489 
    9590    arg->prev_nl=arg->seen_nl; 
     
    9994    } 
    10095 
    101 static void flush(dearmour_arg_t *arg
     96static void flush(dearmour_arg_t *arg,ops_parse_cb_info_t *cbinfo
    10297    { 
    10398    ops_parser_content_t content; 
     
    108103    content.content.unarmoured_text.data=arg->unarmoured; 
    109104    content.content.unarmoured_text.length=arg->num_unarmoured; 
    110     CB(OPS_PTAG_CT_UNARMOURED_TEXT,&content); 
     105    CB(cbinfo,OPS_PTAG_CT_UNARMOURED_TEXT,&content); 
    111106    arg->num_unarmoured=0; 
    112107    } 
    113108 
    114 static int unarmoured_read_char(dearmour_arg_t *arg,ops_boolean_t skip) 
     109static int unarmoured_read_char(dearmour_arg_t *arg,ops_error_t **errors, 
     110                                ops_reader_info_t *rinfo, 
     111                                ops_parse_cb_info_t *cbinfo, 
     112                                ops_boolean_t skip) 
    115113    { 
    116114    int c; 
     
    118116    do 
    119117        { 
    120         c=read_char(arg,ops_false); 
     118        c=read_char(arg,errors,rinfo,cbinfo,ops_false); 
    121119        if(c < 0) 
    122120            return c; 
    123121        arg->unarmoured[arg->num_unarmoured++]=c; 
    124122        if(arg->num_unarmoured == sizeof arg->unarmoured) 
    125             flush(arg); 
     123            flush(arg,cbinfo); 
    126124        } 
    127125    while(skip && c == '\r'); 
     
    156154/* Note that this skips CRs so implementations always see just 
    157155   straight LFs as line terminators */ 
    158 static ops_reader_ret_t process_dash_escaped(dearmour_arg_t *arg) 
     156static ops_reader_ret_t process_dash_escaped(dearmour_arg_t *arg, 
     157                                             ops_error_t **errors, 
     158                                             ops_reader_info_t *rinfo, 
     159                                             ops_parse_cb_info_t *cbinfo) 
    159160    { 
    160161    ops_parser_content_t content; 
     
    176177            { 
    177178            free(hash); 
    178             ERR("Unknown hash algorithm"); 
     179            ERR(cbinfo,"Unknown hash algorithm"); 
    179180            } 
    180181        ops_hash_any(hash,alg); 
     
    191192        unsigned count; 
    192193 
    193         if((c=read_char(arg,ops_true)) < 0) 
     194        if((c=read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0) 
    194195            return OPS_R_EARLY_EOF; 
    195196        if(arg->prev_nl && c == '-') 
    196197            { 
    197             if((c=read_char(arg,ops_false)) < 0) 
     198            if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) 
    198199                return OPS_R_EARLY_EOF; 
    199200            if(c != ' ') 
     
    201202                /* then this had better be a trailer! */ 
    202203                if(c != '-') 
    203                     ERR("Bad dash-escaping"); 
     204                    ERR(cbinfo,"Bad dash-escaping"); 
    204205                for(count=2 ; count < 5 ; ++count) 
    205206                    { 
    206                     if((c=read_char(arg,ops_false)) < 0) 
     207                    if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) 
    207208                        return OPS_R_EARLY_EOF; 
    208209                    if(c != '-') 
    209                         ERR("Bad dash-escaping (2)"); 
     210                        ERR(cbinfo,"Bad dash-escaping (2)"); 
    210211                    } 
    211212                arg->state=AT_TRAILER_NAME; 
     
    213214                } 
    214215            /* otherwise we read the next character */ 
    215             if((c=read_char(arg,ops_false)) < 0) 
     216            if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) 
    216217                return OPS_R_EARLY_EOF; 
    217218            } 
     
    222223                hash->add(hash,(unsigned char *)"\r",1); 
    223224            hash->add(hash,body->data,body->length); 
    224             CB(OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY,&content); 
     225            CB(cbinfo,OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY,&content); 
    225226            body->length=0; 
    226227            } 
     
    229230        if(body->length == sizeof body->data) 
    230231            { 
    231             CB(OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY,&content); 
     232            CB(cbinfo,OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY,&content); 
    232233            body->length=0; 
    233234            } 
     
    239240 
    240241    trailer->hash=hash; 
    241     CB(OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER,&content2); 
     242    CB(cbinfo,OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER,&content2); 
    242243 
    243244    return OPS_R_OK; 
     
    255256    } 
    256257 
    257 static ops_reader_ret_t parse_headers(dearmour_arg_t *arg) 
     258static ops_reader_ret_t parse_headers(dearmour_arg_t *arg,ops_error_t **errors, 
     259                                      ops_reader_info_t *rinfo, 
     260                                      ops_parse_cb_info_t *cbinfo) 
    258261    { 
    259262    char *buf; 
     
    270273        int c; 
    271274 
    272         if((c=read_char(arg,ops_true)) < 0) 
     275        if((c=read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0) 
    273276            return OPS_R_EARLY_EOF; 
    274277 
     
    285288            s=strchr(buf,':'); 
    286289            if(!s) 
    287                 if(!first && !arg->parse_info->armour_allow_headers_without_gap) 
     290                if(!first && !arg->allow_headers_without_gap) 
    288291                    // then we have seriously malformed armour 
    289                     ERR("No colon in armour header"); 
     292                    ERR(cbinfo,"No colon in armour header"); 
    290293                else 
    291294                    { 
    292295                    if(first && 
    293                        !(arg->parse_info->armour_allow_headers_without_gap 
    294                          || arg->parse_info->armour_allow_no_gap)) 
    295                         ERR("No colon in armour header (2)"); 
     296                       !(arg->allow_headers_without_gap || arg->allow_no_gap)) 
     297                        ERR(cbinfo,"No colon in armour header (2)"); 
    296298                    // then we have a nasty armoured block with no 
    297299                    // headers, not even a blank line. 
     
    304306                *s='\0'; 
    305307                if(s[1] != ' ') 
    306                     ERR("No space in armour header"); 
     308                    ERR(cbinfo,"No space in armour header"); 
    307309                add_header(arg,buf,s+2); 
    308310                nbuf=0; 
     
    326328    } 
    327329 
    328 static ops_reader_ret_t read4(dearmour_arg_t *arg,int *pc,unsigned *pn, 
     330static ops_reader_ret_t read4(dearmour_arg_t *arg,ops_error_t **errors, 
     331                              ops_reader_info_t *rinfo, 
     332                              ops_parse_cb_info_t *cbinfo,int *pc,unsigned *pn, 
    329333                              unsigned long *pl) 
    330334    { 
     
    334338    for(n=0 ; n < 4 ; ++n) 
    335339        { 
    336         c=read_char(arg,ops_true); 
     340        c=read_char(arg,errors,rinfo,cbinfo,ops_true); 
    337341        if(c < 0) 
    338342            { 
     
    383387    } 
    384388 
    385 static ops_reader_ret_t decode64(dearmour_arg_t *arg) 
     389static ops_reader_ret_t decode64(dearmour_arg_t *arg,ops_error_t **errors, 
     390                                 ops_reader_info_t *rinfo, 
     391                                 ops_parse_cb_info_t *cbinfo) 
    386392    { 
    387393    unsigned n; 
     
    394400    assert(arg->buffered == 0); 
    395401 
    396     ret=read4(arg,&c,&n,&l); 
     402    ret=read4(arg,errors,rinfo,cbinfo,&c,&n,&l); 
    397403    if(ret != OPS_R_OK) 
    398         ERR("Badly formed base64"); 
     404        ERR(cbinfo,"Badly formed base64"); 
    399405 
    400406    if(n == 3) 
     
    411417        arg->eof64=ops_true; 
    412418        l >>= 4; 
    413         c=read_char(arg,ops_false); 
     419        c=read_char(arg,errors,rinfo,cbinfo,ops_false); 
    414420        if(c != '=') 
    415             ERR("Badly terminated base64"); 
     421            ERR(cbinfo,"Badly terminated base64"); 
    416422        } 
    417423    else if(n == 0) 
     
    431437        // then we saw padding 
    432438        assert(c == '='); 
    433         c=read_char(arg,ops_true); 
     439        c=read_char(arg,errors,rinfo,cbinfo,ops_true); 
    434440        if(c != '\n') 
    435             ERR("No newline at base64 end"); 
    436         c=read_char(arg,ops_false); 
     441            ERR(cbinfo,"No newline at base64 end"); 
     442        c=read_char(arg,errors,rinfo,cbinfo,ops_false); 
    437443        if(c != '=') 
    438             ERR("No checksum at base64 end"); 
     444            ERR(cbinfo,"No checksum at base64 end"); 
    439445        } 
    440446 
     
    442448        { 
    443449        // now we are at the checksum 
    444         ret=read4(arg,&c,&n,&arg->read_checksum); 
     450        ret=read4(arg,errors,rinfo,cbinfo,&c,&n,&arg->read_checksum); 
    445451        if(ret != OPS_R_OK || n != 4) 
    446             ERR("Error in checksum"); 
    447         c=read_char(arg,ops_true); 
     452            ERR(cbinfo,"Error in checksum"); 
     453        c=read_char(arg,errors,rinfo,cbinfo,ops_true); 
    448454        if(c != '\n') 
    449             ERR("Badly terminated checksum"); 
    450         c=read_char(arg,ops_false); 
     455            ERR(cbinfo,"Badly terminated checksum"); 
     456        c=read_char(arg,errors,rinfo,cbinfo,ops_false); 
    451457        if(c != '-') 
    452             ERR("Bad base64 trailer (2)"); 
     458            ERR(cbinfo,"Bad base64 trailer (2)"); 
    453459        } 
    454460 
     
    456462        { 
    457463        for(n=0 ; n < 4 ; ++n) 
    458             if(read_char(arg,ops_false) != '-') 
    459                 ERR("Bad base64 trailer"); 
     464            if(read_char(arg,errors,rinfo,cbinfo,ops_false) != '-') 
     465                ERR(cbinfo,"Bad base64 trailer"); 
    460466        arg->eof64=ops_true; 
    461467        } 
     
    473479 
    474480    if(arg->eof64 && arg->read_checksum != arg->checksum) 
    475         ERR("Checksum mismatch"); 
     481        ERR(cbinfo,"Checksum mismatch"); 
    476482 
    477483    return OPS_R_OK; 
     
    493499                                             unsigned *plength, 
    494500                                             ops_reader_flags_t flags, 
    495                                              ops_parse_info_t *parse_info) 
    496     { 
    497     dearmour_arg_t *arg=parse_info->reader_arg; 
    498     unsigned length=*plength; 
    499     ops_parser_content_t content; 
    500     ops_reader_ret_t ret; 
    501     ops_boolean_t first; 
    502  
    503     OPS_USED(flags); 
    504  
    505     if(arg->eof64 && !arg->buffered) 
    506         assert(arg->state == OUTSIDE_BLOCK || arg->state == AT_TRAILER_NAME); 
    507  
    508     while(length > 0) 
    509         { 
    510         unsigned count; 
    511         unsigned n; 
    512         char buf[1024]; 
    513         int c; 
    514  
    515         flush(arg); 
    516         switch(arg->state) 
    517             { 
    518         case OUTSIDE_BLOCK: 
    519             /* This code returns EOF rather than EARLY_EOF because if 
    520                we don't see a header line at all, then it is just an 
    521                EOF (and not a BLOCK_END) */ 
    522             while(!arg->seen_nl) 
    523                 if((c=unarmoured_read_char(arg,ops_true)) < 0) 
    524                     return OPS_R_EOF; 
    525  
    526             /* flush at this point so we definitely have room for the 
    527                header, and so we can easily erase it from the buffer */ 
    528             flush(arg); 
    529             /* Find and consume the 5 leading '-' */ 
    530             for(count=0 ; count < 5 ; ++count) 
    531                 { 
    532                 if((c=unarmoured_read_char(arg,ops_false)) < 0) 
    533                     return OPS_R_EOF; 
    534                 if(c != '-') 
    535                     goto reloop; 
    536                 } 
    537  
    538             /* Now find the block type */ 
    539             for(n=0 ; n < sizeof buf-1 ; ) 
    540                 { 
    541                 if((c=unarmoured_read_char(arg,ops_false)) < 0) 
    542                     return OPS_R_EOF; 
    543                 if(c == '-') 
    544                     goto got_minus; 
    545                 buf[n++]=c; 
    546                 } 
    547             /* then I guess this wasn't a proper header */ 
    548             break; 
    549  
    550         got_minus: 
    551             buf[n]='\0'; 
    552  
    553             /* Consume trailing '-' */ 
    554             for(count=1 ; count < 5 ; ++count) 
    555                 { 
    556                 if((c=unarmoured_read_char(arg,ops_false)) < 0) 
    557                     return OPS_R_EOF; 
    558                 if(c != '-') 
    559                     /* wasn't a header after all */ 
    560                     goto reloop; 
    561                 } 
    562  
    563             /* Consume final NL */ 
    564             if((c=unarmoured_read_char(arg,ops_true)) < 0) 
    565                 return OPS_R_EOF; 
    566             if(c != '\n') 
    567                 /* wasn't a header line after all */ 
    568                 break; 
    569  
    570             /* Now we've seen the header, scrub it from the buffer */ 
    571             arg->num_unarmoured=0; 
    572  
    573             /* But now we've seen a header line, then errors are 
    574                EARLY_EOF */ 
    575             if((ret=parse_headers(arg)) != OPS_R_OK) 
    576                 return OPS_R_EARLY_EOF; 
    577  
    578             if(!strcmp(buf,"BEGIN PGP SIGNED MESSAGE")) 
    579                 { 
    580                 ops_reader_ret_t ret; 
    581  
    582                 ops_dup_headers(&content.content.signed_cleartext_header.headers,&arg->headers); 
    583                 CB(OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER,&content); 
    584  
    585                 ret=process_dash_escaped(arg); 
    586                 if(ret != OPS_R_OK) 
    587                     return ret; 
    588                 } 
    589             else 
    590                 { 
    591                 content.content.armour_header.type=buf; 
    592                 content.content.armour_header.headers=arg->headers; 
    593                 memset(&arg->headers,'\0',sizeof arg->headers); 
    594                 CB(OPS_PTAG_CT_ARMOUR_HEADER,&content); 
    595                 base64(arg); 
    596                 } 
    597             break; 
    598  
    599         case BASE64: 
    600             first=ops_true; 
    601             while(length > 0) 
    602                 { 
    603                 if(!arg->buffered) 
    604                     { 
    605                     if(!arg->eof64) 
    606                         { 
    607                         ret=decode64(arg); 
    608                         if(ret != OPS_R_OK) 
    609                             return ret; 
    610                         } 
    611                     if(!arg->buffered) 
    612                         { 
    613                         assert(arg->eof64); 
    614                         if(first) 
    615                             { 
    616                             arg->state=AT_TRAILER_NAME; 
    617                             goto reloop; 
    618                             } 
    619                         return OPS_R_EARLY_EOF; 
    620                         } 
    621                     } 
    622                  
    623                 assert(arg->buffered); 
    624                 *dest=arg->buffer[--arg->buffered]; 
    625                 ++dest; 
    626                 --length; 
    627                 first=ops_false; 
    628                 } 
    629             if(arg->eof64 && !arg->buffered) 
    630                 arg->state=AT_TRAILER_NAME; 
    631             break; 
    632  
    633         case AT_TRAILER_NAME: 
    634             for(n=0 ; n < sizeof buf-1 ; ) 
    635                 { 
    636                 if((c=read_char(arg,ops_false)) < 0) 
    637                     return OPS_R_EARLY_EOF; 
    638                 if(c == '-') 
    639                     goto got_minus2; 
    640                 buf[n++]=c; 
    641                 } 
    642             /* then I guess this wasn't a proper trailer */ 
    643             ERR("Bad ASCII armour trailer"); 
    644             break; 
    645  
    646         got_minus2: 
    647             buf[n]='\0'; 
    648  
    649             /* Consume trailing '-' */ 
    650             for(count=1 ; count < 5 ; ++count) 
    651                 { 
    652                 if((c=read_char(arg,ops_false)) < 0) 
    653                     return OPS_R_EARLY_EOF; 
    654                 if(c != '-') 
    655                     /* wasn't a trailer after all */ 
    656                     ERR("Bad ASCII armour trailer (2)"); 
    657                 } 
    658  
    659             /* Consume final NL */ 
    660             if((c=read_char(arg,ops_true)) < 0) 
    661                 return OPS_R_EARLY_EOF; 
    662             if(c != '\n') 
    663                 /* wasn't a trailer line after all */ 
    664                 ERR("Bad ASCII armour trailer (3)"); 
    665  
    666             if(!strncmp(buf,"BEGIN ",6)) 
    667                 { 
    668                 if((ret=parse_headers(arg)) != OPS_R_OK) 
    669                     return ret; 
    670                 content.content.armour_header.type=buf; 
    671                 content.content.armour_header.headers=arg->headers; 
    672                 memset(&arg->headers,'\0',sizeof arg->headers); 
    673                 CB(OPS_PTAG_CT_ARMOUR_HEADER,&content); 
    674                 base64(arg); 
    675                 } 
    676             else 
    677                 { 
    678                 content.content.armour_trailer.type=buf; 
    679                 CB(OPS_PTAG_CT_ARMOUR_TRAILER,&content); 
     501                                             ops_error_t **errors, 
     502                                             ops_reader_info_t *rinfo, 
     503                                             ops_parse_cb_info_t *cbinfo) 
     504     { 
     505     dearmour_arg_t *arg=ops_reader_get_arg(rinfo); 
     506     unsigned length=*plength; 
     507     ops_parser_content_t content; 
     508     ops_reader_ret_t ret; 
     509     ops_boolean_t first; 
     510 
     511     OPS_USED(flags); 
     512 
     513     if(arg->eof64 && !arg->buffered) 
     514         assert(arg->state == OUTSIDE_BLOCK || arg->state == AT_TRAILER_NAME); 
     515 
     516     while(length > 0) 
     517         { 
     518         unsigned count; 
     519         unsigned n; 
     520         char buf[1024]; 
     521         int c; 
     522 
     523         flush(arg,cbinfo); 
     524         switch(arg->state) 
     525             { 
     526         case OUTSIDE_BLOCK: 
     527             /* This code returns EOF rather than EARLY_EOF because if 
     528                we don't see a header line at all, then it is just an 
     529                EOF (and not a BLOCK_END) */ 
     530             while(!arg->seen_nl) 
     531                 if((c=unarmoured_read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0) 
     532                     return OPS_R_EOF; 
     533 
     534             /* flush at this point so we definitely have room for the 
     535                header, and so we can easily erase it from the buffer */ 
     536             flush(arg,cbinfo); 
     537             /* Find and consume the 5 leading '-' */ 
     538             for(count=0 ; count < 5 ; ++count) 
     539                 { 
     540                 if((c=unarmoured_read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) 
     541                     return OPS_R_EOF; 
     542                 if(c != '-') 
     543                     goto reloop; 
     544                 } 
     545 
     546             /* Now find the block type */ 
     547             for(n=0 ; n < sizeof buf-1 ; ) 
     548                 { 
     549                 if((c=unarmoured_read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) 
     550                     return OPS_R_EOF; 
     551                 if(c == '-') 
     552                     goto got_minus; 
     553                 buf[n++]=c; 
     554                 } 
     555             /* then I guess this wasn't a proper header */ 
     556             break; 
     557 
     558         got_minus: 
     559             buf[n]='\0'; 
     560 
     561             /* Consume trailing '-' */ 
     562             for(count=1 ; count < 5 ; ++count) 
     563                 { 
     564                 if((c=unarmoured_read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) 
     565                     return OPS_R_EOF; 
     566                 if(c != '-') 
     567                     /* wasn't a header after all */ 
     568                     goto reloop; 
     569                 } 
     570 
     571             /* Consume final NL */ 
     572             if((c=unarmoured_read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0) 
     573                 return OPS_R_EOF; 
     574             if(c != '\n') 
     575                 /* wasn't a header line after all */ 
     576                 break; 
     577 
     578             /* Now we've seen the header, scrub it from the buffer */ 
     579             arg->num_unarmoured=0; 
     580 
     581             /* But now we've seen a header line, then errors are 
     582                EARLY_EOF */ 
     583             if((ret=parse_headers(arg,errors,rinfo,cbinfo)) != OPS_R_OK) 
     584                 return OPS_R_EARLY_EOF; 
     585 
     586             if(!strcmp(buf,"BEGIN PGP SIGNED MESSAGE")) 
     587                 { 
     588                 ops_reader_ret_t ret; 
     589 
     590                 ops_dup_headers(&content.content.signed_cleartext_header.headers,&arg->headers); 
     591                 CB(cbinfo,OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER,&content); 
     592 
     593                 ret=process_dash_escaped(arg,errors,rinfo,cbinfo); 
     594                 if(ret != OPS_R_OK) 
     595                     return ret; 
     596                 } 
     597             else 
     598                 { 
     599                 content.content.armour_header.type=buf; 
     600                 content.content.armour_header.headers=arg->headers; 
     601                 memset(&arg->headers,'\0',sizeof arg->headers); 
     602                 CB(cbinfo,OPS_PTAG_CT_ARMOUR_HEADER,&content); 
     603                 base64(arg); 
     604                 } 
     605             break; 
     606 
     607         case BASE64: 
     608             first=ops_true; 
     609             while(length > 0) 
     610                 { 
     611                 if(!arg->buffered) 
     612                     { 
     613                     if(!arg->eof64) 
     614                         { 
     615                         ret=decode64(arg,errors,rinfo,cbinfo); 
     616                         if(ret != OPS_R_OK) 
     617                             return ret; 
     618                         } 
     619                     if(!arg->buffered) 
     620                         { 
     621                         assert(arg->eof64); 
     622                         if(first) 
     623                             { 
     624                             arg->state=AT_TRAILER_NAME; 
     625                             goto reloop; 
     626                             } 
     627                         return OPS_R_EARLY_EOF; 
     628                         } 
     629                     } 
     630 
     631                 assert(arg->buffered); 
     632                 *dest=arg->buffer[--arg->buffered]; 
     633                 ++dest; 
     634                 --length; 
     635                 first=ops_false; 
     636                 } 
     637             if(arg->eof64 && !arg->buffered) 
     638                 arg->state=AT_TRAILER_NAME; 
     639             break; 
     640 
     641         case AT_TRAILER_NAME: 
     642             for(n=0 ; n < sizeof buf-1 ; ) 
     643                 { 
     644                 if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) 
     645                     return OPS_R_EARLY_EOF; 
     646                 if(c == '-') 
     647                     goto got_minus2; 
     648                 buf[n++]=c; 
     649                 } 
     650             /* then I guess this wasn't a proper trailer */ 
     651             ERR(cbinfo,"Bad ASCII armour trailer"); 
     652             break; 
     653 
     654         got_minus2: 
     655             buf[n]='\0'; 
     656 
     657             /* Consume trailing '-' */ 
     658             for(count=1 ; count < 5 ; ++count) 
     659                 { 
     660                 if((c=read_char(arg,errors,rinfo,cbinfo,ops_false)) < 0) 
     661                     return OPS_R_EARLY_EOF; 
     662                 if(c != '-') 
     663                     /* wasn't a trailer after all */ 
     664                     ERR(cbinfo,"Bad ASCII armour trailer (2)"); 
     665                 } 
     666 
     667             /* Consume final NL */ 
     668             if((c=read_char(arg,errors,rinfo,cbinfo,ops_true)) < 0) 
     669                 return OPS_R_EARLY_EOF; 
     670             if(c != '\n') 
     671                 /* wasn't a trailer line after all */ 
     672                 ERR(cbinfo,"Bad ASCII armour trailer (3)"); 
     673 
     674             if(!strncmp(buf,"BEGIN ",6)) 
     675                 { 
     676                 if((ret=parse_headers(arg,errors,rinfo,cbinfo)) != OPS_R_OK) 
     677                     return ret; 
     678                 content.content.armour_header.type=buf; 
     679                 content.content.armour_header.headers=arg->headers; 
     680                 memset(&arg->headers,'\0',sizeof arg->headers); 
     681                 CB(cbinfo,OPS_PTAG_CT_ARMOUR_HEADER,&content); 
     682                 base64(arg); 
     683                 } 
     684             else 
     685                 { 
     686                 content.content.armour_trailer.type=buf; 
     687                 CB(cbinfo,OPS_PTAG_CT_ARMOUR_TRAILER,&content); 
    680688                arg->state=OUTSIDE_BLOCK; 
    681689                } 
     
    689697    } 
    690698 
    691 void ops_reader_push_dearmour(ops_parse_info_t *parse_info) 
     699void ops_reader_push_dearmour(ops_parse_info_t *parse_info, 
     700                              ops_boolean_t without_gap,ops_boolean_t no_gap) 
    692701    { 
    693702    dearmour_arg_t *arg; 
    694703 
    695704    arg=ops_mallocz(sizeof *arg); 
    696  
    697     arg->reader_arg=parse_info->reader_arg; 
    698     arg->reader=parse_info->reader; 
    699     arg->parse_info=parse_info; 
    700705    arg->seen_nl=ops_true; 
    701  
    702     parse_info->reader=armoured_data_reader; 
    703     parse_info->reader_arg=arg; 
     706    arg->allow_headers_without_gap=without_gap; 
     707    arg->allow_no_gap=no_gap; 
     708 
     709    ops_reader_push(parse_info,armoured_data_reader,arg); 
    704710    } 
    705711 
    706712void ops_reader_pop_dearmour(ops_parse_info_t *parse_info) 
    707713    { 
    708     dearmour_arg_t *arg=parse_info->reader_arg; 
    709  
    710     parse_info->reader_arg=arg->reader_arg; 
    711     parse_info->reader=arg->reader; 
     714    dearmour_arg_t *arg=ops_reader_get_arg(ops_parse_get_rinfo(parse_info)); 
    712715 
    713716    free(arg); 
  • openpgpsdk/trunk/src/compress.c

    r282 r320  
    1111typedef struct 
    1212    { 
    13     ops_packet_reader_t *reader; 
    14     void *reader_arg; 
    15     ops_parse_info_t *parse_info; 
    1613    ops_region_t *region; 
    1714    unsigned char in[DECOMPRESS_BUFFER]; 
     
    2219    } decompress_arg_t; 
    2320 
    24 #define ERR(err)        do { content.content.error.error=err; content.tag=OPS_PARSER_ERROR; arg->parse_info->cb(&content,arg->parse_info->cb_arg); return OPS_R_EARLY_EOF; } while(0) 
     21#define ERR(err)        do { content.content.error.error=err; content.tag=OPS_PARSER_ERROR; ops_parse_cb(&content,cbinfo); return OPS_R_EARLY_EOF; } while(0) 
    2522 
    2623static ops_reader_ret_t compressed_data_reader(unsigned char *dest, 
    2724                                               unsigned *plength, 
    2825                                               ops_reader_flags_t flags, 
    29                                                ops_parse_info_t *parse_info) 
     26                                               ops_error_t **errors, 
     27                                               ops_reader_info_t *rinfo, 
     28                                               ops_parse_cb_info_t *cbinfo) 
    3029    { 
    31     decompress_arg_t *arg=parse_info->reader_arg
     30    decompress_arg_t *arg=ops_reader_get_arg(rinfo)
    3231    ops_parser_content_t content; 
    3332    unsigned length=*plength; 
     
    7170                    n=sizeof arg->in; 
    7271 
    73                 arg->parse_info->reader=arg->reader; 
    74                 arg->parse_info->reader_arg=arg->reader_arg; 
    75  
    76                 if(!ops_limited_read(arg->in,n,arg->region,arg->parse_info)) 
     72                if(!ops_stacked_limited_read(arg->in,n,arg->region, 
     73                                             errors,rinfo,cbinfo)) 
    7774                    return OPS_R_EARLY_EOF; 
    78  
    79                 arg->parse_info->reader=compressed_data_reader; 
    80                 arg->parse_info->reader_arg=arg; 
    8175 
    8276                arg->stream.next_in=arg->in; 
     
    125119    memset(&arg,'\0',sizeof arg); 
    126120 
    127     arg.reader_arg=parse_info->reader_arg; 
    128     arg.reader=parse_info->reader; 
     121 
    129122    arg.region=region; 
    130     arg.parse_info=parse_info; 
    131123 
    132124    arg.stream.next_in=Z_NULL; 
     
    144136        } 
    145137 
    146     parse_info->reader=compressed_data_reader; 
    147     parse_info->reader_arg=&arg; 
     138    ops_reader_push(parse_info,compressed_data_reader,&arg); 
    148139 
    149140    return ops_parse(parse_info); 
  • openpgpsdk/trunk/src/create.c

    r319 r320  
    567567    if(n == -1) 
    568568        { 
    569         ops_system_error_1(errors,OPS_E_W_WRITE_FAILED,"write", 
     569        OPS_SYSTEM_ERROR_1(errors,OPS_E_W_WRITE_FAILED,"write", 
    570570                           "file descriptor %d",arg->fd); 
    571571        return ops_false; 
     
    574574    if((unsigned)n != length) 
    575575        { 
    576         ops_error_1(errors,OPS_E_W_WRITE_TOO_SHORT, 
     576        OPS_ERROR_1(errors,OPS_E_W_WRITE_TOO_SHORT, 
    577577                    "file descriptor %d",arg->fd); 
    578578        return ops_false; 
  • openpgpsdk/trunk/src/errors.c

    r307 r320  
    5858 */ 
    5959 
    60 void push_error(ops_error_t **errstack,ops_errcode_t errcode,int sys_errno, 
     60void ops_push_error(ops_error_t **errstack,ops_errcode_t errcode,int sys_errno, 
    6161                const char *file,int line,const char *fmt,...) 
    6262    { 
     
    9191    } 
    9292 
    93 void print_error(ops_error_t *err) 
     93void ops_print_error(ops_error_t *err) 
    9494    { 
    9595    printf("%s:%d: ",err->file,err->line); 
    96     if (err->errcode==OPS_E_SYSTEM_ERROR) 
     96    if(err->errcode==OPS_E_SYSTEM_ERROR) 
    9797        printf("system error %d returned from %s()\n",err->sys_errno, 
    9898               err->comment); 
     
    101101    } 
    102102 
    103 void print_errors(ops_error_t *errstack) 
     103void ops_print_errors(ops_error_t *errstack) 
    104104    { 
    105105    ops_error_t *err; 
    106     for (err=errstack; err!=NULL; err=err->next) 
    107         print_error(err); 
     106 
     107    for(err=errstack ; err!=NULL ; err=err->next) 
     108        ops_print_error(err); 
    108109    } 
  • openpgpsdk/trunk/src/packet-parse.c

    r313 r320  
    22 * \brief Parser for OpenPGP packets 
    33 */ 
    4  
    54 
    65#include <openpgpsdk/packet.h> 
     
    98#include <openpgpsdk/compress.h> 
    109#include <openpgpsdk/errors.h> 
     10#include "parse_local.h" 
    1111 
    1212#include <assert.h> 
     
    3939        return 0; 
    4040 
    41     if (!ops_limited_read(data->contents, data->len,subregion,parse_info)) 
     41    if (!ops_limited_read(data->contents, data->len,subregion, 
     42                          &parse_info->errors,&parse_info->rinfo, 
     43                          &parse_info->cbinfo)) 
    4244        return 0; 
    4345     
     
    7072 */ 
    7173 
    72 static int read_unsigned_string(unsigned char **str, ops_region_t *subregion, ops_parse_info_t *parse_info) 
     74static int read_unsigned_string(unsigned char **str,ops_region_t *subregion, 
     75                                ops_parse_info_t *pinfo) 
    7376    { 
    7477    int len=0; 
     
    8083        return 0; 
    8184 
    82     if(len && !ops_limited_read(*str,len,subregion,parse_info)) 
     85    if(len && !ops_limited_read(*str,len,subregion,&pinfo->errors, 
     86                                &pinfo->rinfo,&pinfo->cbinfo)) 
    8387        return 0; 
    8488 
     
    102106 
    103107/*! \todo descr for CB macro */ 
    104 #define CB(t,pc)        do { (pc)->tag=(t); if(parse_info->cb(pc,parse_info->cb_arg) == OPS_RELEASE_MEMORY) ops_parser_content_free(pc); } while(0) 
     108#define CB(cbinfo,t,pc) do { (pc)->tag=(t); if((cbinfo)->cb(pc,(cbinfo)->arg) == OPS_RELEASE_MEMORY) ops_parser_content_free(pc); } while(0) 
     109#define CBP(info,t,pc) CB(&(info)->cbinfo,t,pc) 
    105110/*! macro to save typing */ 
    106111#define C               content.content 
    107 /*! macro to run CallBack function specifying a parser error has occurred */ 
    108 #define E               CB(OPS_PARSER_ERROR,&content); return 0 
    109112/*! set error code in content and run CallBack to handle error */ 
    110 #define ERRCODE(err)   do { C.errcode.errcode=err; CB(OPS_PARSER_ERRCODE,&content); } while(0) 
     113#define ERRCODE(cbinfo,err)    do { C.errcode.errcode=err; CB(cbinfo,OPS_PARSER_ERRCODE,&content); } while(0) 
    111114/*! set error text in content and run CallBack to handle error, then return */ 
    112 #define ERR(err)        do { C.error.error=err; E; } while(0) 
     115#define ERR(cbinfo,err) do { C.error.error=err; CB(cbinfo,OPS_PARSER_ERROR,&content); return ops_false; } while(0) 
     116#define ERRP(info,err)  do { C.error.error=err; CBP(info,OPS_PARSER_ERROR,&content); return ops_false; } while(0) 
    113117/*! set error text in content and run CallBack to handle warning, do not return */ 
    114118#define WARN(warn)      do { C.error.error=warn; CB(OPS_PARSER_ERROR,&content);; } while(0) 
     119#define WARNP(info,warn)        do { C.error.error=warn; CBP(info,OPS_PARSER_ERROR,&content); } while(0) 
    115120/*! \todo descr ERR1 macro */ 
    116 #define ERR1(fmt,x)    do { format_error(&content,(fmt),(x)); E; } while(0) 
     121#define ERR1P(info,fmt,x)      do { format_error(&content,(fmt),(x)); CBP(info,OPS_PARSER_ERROR,&content); return ops_false; } while(0) 
    117122 
    118123/* XXX: replace ops_ptag_t with something more appropriate for limiting 
     
    157162 */ 
    158163 
     164static ops_reader_ret_t sub_base_read(unsigned char *dest,unsigned *plength, 
     165                                      ops_reader_flags_t flags, 
     166                                      ops_error_t **errors, 
     167                                      ops_reader_info_t *rinfo, 
     168                                      ops_parse_cb_info_t *cbinfo) 
     169    { 
     170    ops_reader_ret_t ret=rinfo->reader(dest,plength,flags,errors,rinfo,cbinfo); 
     171 
     172    if(ret != OPS_R_OK && ret != OPS_R_PARTIAL_READ) 
     173        return ret; 
     174 
     175    if(rinfo->accumulate) 
     176        { 
     177        assert(rinfo->asize >= rinfo->alength); 
     178        if(rinfo->alength+*plength > rinfo->asize) 
     179            { 
     180            rinfo->asize=rinfo->asize*2+*plength; 
     181            rinfo->accumulated=realloc(rinfo->accumulated,rinfo->asize); 
     182            } 
     183        assert(rinfo->asize >= rinfo->alength+*plength); 
     184        memcpy(rinfo->accumulated+rinfo->alength,dest,*plength); 
     185        } 
     186    // we track length anyway, because it is used for packet offsets 
     187    rinfo->alength+=*plength; 
     188    // and also the position 
     189    rinfo->position+=*plength; 
     190 
     191    return ret; 
     192    } 
     193 
     194ops_reader_ret_t ops_stacked_read(unsigned char *dest,unsigned *length, 
     195                                  ops_reader_flags_t flags, 
     196                                  ops_error_t **errors, 
     197                                  ops_reader_info_t *rinfo, 
     198                                  ops_parse_cb_info_t *cbinfo) 
     199    { return sub_base_read(dest,length,flags,errors,rinfo->next,cbinfo); } 
     200 
    159201static ops_reader_ret_t base_read(unsigned char *dest,unsigned *plength, 
    160202                                  ops_reader_flags_t flags, 
    161                                   ops_parse_info_t *parse_info) 
    162     { 
    163     ops_reader_ret_t ret=parse_info->reader(dest,plength,flags,parse_info);  
    164     if(ret != OPS_R_OK && ret != OPS_R_PARTIAL_READ) 
    165         return ret; 
    166  
    167     if(parse_info->accumulate) 
    168         { 
    169         assert(parse_info->asize >= parse_info->alength); 
    170         if(parse_info->alength+*plength > parse_info->asize) 
    171             { 
    172             parse_info->asize=parse_info->asize*2+*plength; 
    173             parse_info->accumulated=realloc(parse_info->accumulated,parse_info->asize); 
    174             } 
    175         assert(parse_info->asize >= parse_info->alength+*plength); 
    176         memcpy(parse_info->accumulated+parse_info->alength,dest,*plength); 
    177         } 
    178     // we track length anyway, because it is used for packet offsets 
    179     parse_info->alength+=*plength; 
    180     // and also the position 
    181     parse_info->position+=*plength; 
    182  
    183     return ret; 
     203                                  ops_parse_info_t *info) 
     204    { 
     205    return sub_base_read(dest,plength,flags,&info->errors,&info->rinfo, 
     206                         &info->cbinfo); 
    184207    } 
    185208 
     
    236259 * \return              1 on success, 0 on error 
    237260 */ 
    238 int ops_limited_read(unsigned char *dest,unsigned length, 
    239                      ops_region_t *region,ops_parse_info_t *parse_info) 
     261ops_boolean_t ops_limited_read(unsigned char *dest,unsigned length, 
     262                               ops_region_t *region,ops_error_t **errors, 
     263                               ops_reader_info_t *rinfo, 
     264                               ops_parse_cb_info_t *cbinfo) 
    240265    { 
    241266    ops_parser_content_t content; 
     
    244269    if(!region->indeterminate && region->length_read+length > region->length) 
    245270        { 
    246         ERRCODE(OPS_E_P_NOT_ENOUGH_DATA); 
    247         return 0; 
    248         } 
    249  
    250     ret=base_read(dest,&length,region->indeterminate ? OPS_RETURN_LENGTH : 0, 
    251                   parse_info); 
     271        ERRCODE(cbinfo,OPS_E_P_NOT_ENOUGH_DATA); 
     272        return 0; 
     273        } 
     274 
     275    ret=sub_base_read(dest,&length, 
     276                      region->indeterminate ? OPS_RETURN_LENGTH : 0,errors, 
     277                      rinfo,cbinfo); 
    252278 
    253279    if(ret != OPS_R_OK && ret != OPS_R_PARTIAL_READ) 
    254280        { 
    255         ERRCODE(OPS_E_R_READ_FAILED); 
     281        ERRCODE(cbinfo,OPS_E_R_READ_FAILED); 
    256282        return 0; 
    257283        } 
     
    266292 
    267293    return 1; 
     294    } 
     295 
     296ops_boolean_t ops_stacked_limited_read(unsigned char *dest,unsigned length, 
     297                                       ops_region_t *region, 
     298                                       ops_error_t **errors, 
     299                                       ops_reader_info_t *rinfo, 
     300                                       ops_parse_cb_info_t *cbinfo) 
     301    { return ops_limited_read(dest,length,region,errors,rinfo->next,cbinfo); } 
     302 
     303static ops_boolean_t limited_read(unsigned char *dest,unsigned length, 
     304                                  ops_region_t *region,ops_parse_info_t *info) 
     305    { 
     306    return ops_limited_read(dest,length,region,&info->errors,&info->rinfo, 
     307                            &info->cbinfo); 
    268308    } 
    269309 
     
    287327        { 
    288328        int n=length%8192; 
    289         if(!ops_limited_read(buf,n,region,parse_info)) 
     329        if(!limited_read(buf,n,region,parse_info)) 
    290330            return 0; 
    291331        length-=n; 
     
    320360    assert(length <= 4); 
    321361    assert(sizeof(*dest) >= 4); 
    322     if(!ops_limited_read(c,length,region,parse_info)) 
     362    if(!limited_read(c,length,region,parse_info)) 
    323363        return 0; 
    324364 
     
    430470 
    431471    assert(length <= 8192); 
    432     if(!ops_limited_read(buf,length,region,parse_info)) 
     472    if(!limited_read(buf,length,region,parse_info)) 
    433473        return 0; 
    434474 
    435475    if((buf[0] >> nonzero) != 0 || !(buf[0]&(1 << (nonzero-1)))) 
    436         ERR("MPI format error");  /* XXX: Ben, one part of this constraint does not apply to encrypted MPIs the draft says. -- peter */ 
     476        ERRP(parse_info,"MPI format error");  /* XXX: Ben, one part of this constraint does not apply to encrypted MPIs the draft says. -- peter */ 
    437477 
    438478    *pbn=BN_bin2bn(buf,length,NULL); 
     
    496536    unsigned char c[1]; 
    497537 
    498     if(!ops_limited_read(c,1,region,parse_info)) 
     538    if(!limited_read(c,1,region,parse_info)) 
    499539        return 0; 
    500540    if(c[0] < 192) 
     
    507547        unsigned t=(c[0]-192) << 8; 
    508548 
    509         if(!ops_limited_read(c,1,region,parse_info)) 
     549        if(!limited_read(c,1,region,parse_info)) 
    510550            return 0; 
    511551        *length=t+c[0]+192; 
     
    741781    assert (region->length_read == 0);  /* We should not have read anything so far */ 
    742782 
    743     if(!ops_limited_read(c,1,region,parse_info)) 
     783    if(!limited_read(c,1,region,parse_info)) 
    744784        return 0; 
    745785    key->version=c[0]; 
    746786    if(key->version < 2 || key->version > 4) 
    747         ERR1("Bad public key version (0x%02x)",key->version); 
     787        ERR1P(parse_info,"Bad public key version (0x%02x)",key->version); 
    748788 
    749789    if(!limited_read_time(&key->creation_time,region,parse_info)) 
     
    755795        return 0; 
    756796 
    757     if(!ops_limited_read(c,1,region,parse_info)) 
     797    if(!limited_read(c,1,region,parse_info)) 
    758798        return 0; 
    759799 
     
    787827 
    788828    default: 
    789         ERR1("Unknown public key algorithm (%d)",key->algorithm); 
     829        ERR1P(parse_info,"Unknown public key algorithm (%d)",key->algorithm); 
    790830        } 
    791831 
     
    817857    // XXX: this test should be done for all packets, surely? 
    818858    if(region->length_read != region->length) 
    819         ERR1("Unconsumed data (%d)",region->length-region->length_read); 
    820  
    821     CB(tag,&content); 
     859        ERR1P(parse_info,"Unconsumed data (%d)", 
     860              region->length-region->length_read); 
     861 
     862    CBP(parse_info,tag,&content); 
    822863 
    823864    return 1; 
     
    868909        return 0; 
    869910 
    870     CB(OPS_PTAG_CT_USER_ATTRIBUTE,&content); 
     911    CBP(parse_info,OPS_PTAG_CT_USER_ATTRIBUTE,&content); 
    871912 
    872913    return 1; 
     
    905946    C.user_id.user_id=malloc(region->length+1);  /* XXX should we not like check malloc's return value? */ 
    906947 
    907     if(region->length && !ops_limited_read(C.user_id.user_id,region->length
    908                                           region,parse_info)) 
     948    if(region->length && !limited_read(C.user_id.user_id,region->length,region
     949                                       parse_info)) 
    909950        return 0; 
    910951 
    911952    C.user_id.user_id[region->length]='\0'; /* terminate the string */ 
    912953 
    913     CB(OPS_PTAG_CT_USER_ID,&content); 
     954    CBP(parse_info,OPS_PTAG_CT_USER_ID,&content); 
    914955 
    915956    return 1; 
     
    9861027 * \see RFC2440bis-12 5.2.2 
    9871028 */ 
    988 static int parse_v3_signature(ops_region_t *region,ops_parse_info_t *parse_info) 
     1029static int parse_v3_signature(ops_region_t *region, 
     1030                              ops_parse_info_t *parse_info) 
    9891031    { 
    9901032    unsigned char c[1]; 
     
    9941036 
    9951037    /* hash info length */ 
    996     if(!ops_limited_read(c,1,region,parse_info)) 
     1038    if(!limited_read(c,1,region,parse_info)) 
    9971039        return 0; 
    9981040    if(c[0] != 5) 
    999         ERR("bad hash info length"); 
    1000  
    1001     if(!ops_limited_read(c,1,region,parse_info)) 
     1041        ERRP(parse_info,"bad hash info length"); 
     1042 
     1043    if(!limited_read(c,1,region,parse_info)) 
    10021044        return 0; 
    10031045    C.signature.type=c[0]; 
     
    10081050    C.signature.creation_time_set=ops_true; 
    10091051 
    1010     if(!ops_limited_read(C.signature.signer_id,OPS_KEY_ID_SIZE,region,parse_info)) 
     1052    if(!limited_read(C.signature.signer_id,OPS_KEY_ID_SIZE,region,parse_info)) 
    10111053        return 0; 
    10121054    C.signature.signer_id_set=ops_true; 
    10131055 
    1014     if(!ops_limited_read(c,1,region,parse_info)) 
     1056    if(!limited_read(c,1,region,parse_info)) 
    10151057        return 0; 
    10161058    C.signature.key_algorithm=c[0]; 
    10171059    /* XXX: check algorithm */ 
    10181060 
    1019     if(!ops_limited_read(c,1,region,parse_info)) 
     1061    if(!limited_read(c,1,region,parse_info)) 
    10201062        return 0; 
    10211063    C.signature.hash_algorithm=c[0]; 
    10221064    /* XXX: check algorithm */ 
    10231065     
    1024     if(!ops_limited_read(C.signature.hash2,2,region,parse_info)) 
     1066    if(!limited_read(C.signature.hash2,2,region,parse_info)) 
    10251067        return 0; 
    10261068 
     
    10461088 
    10471089    default: 
    1048         ERR1("Bad signature key algorithm (%d)",C.signature.key_algorithm); 
     1090        ERR1P(parse_info,"Bad signature key algorithm (%d)",C.signature.key_algorithm); 
    10491091        } 
    10501092 
    10511093    if(region->length_read != region->length) 
    1052         ERR1("Unconsumed data (%d)",region->length-region->length_read); 
    1053  
    1054     CB(OPS_PTAG_CT_SIGNATURE,&content); 
     1094        ERR1P(parse_info,"Unconsumed data (%d)",region->length-region->length_read); 
     1095 
     1096    CBP(parse_info,OPS_PTAG_CT_SIGNATURE,&content); 
    10551097 
    10561098    return 1; 
     
    10891131 
    10901132    if(subregion.length > region->length) 
    1091         ERR("Subpacket too long"); 
    1092  
    1093     if(!ops_limited_read(c,1,&subregion,parse_info)) 
     1133        ERRP(parse_info,"Subpacket too long"); 
     1134 
     1135    if(!limited_read(c,1,&subregion,parse_info)) 
    10941136        return 0; 
    10951137 
     
    11061148        C.ss_raw.length=subregion.length-1; 
    11071149        C.ss_raw.raw=malloc(C.ss_raw.length); 
    1108         if(!ops_limited_read(C.ss_raw.raw,C.ss_raw.length,&subregion,parse_info)) 
    1109             return 0; 
    1110         CB(OPS_PTAG_RAW_SS,&content); 
     1150        if(!limited_read(C.ss_raw.raw,C.ss_raw.length,&subregion,parse_info)) 
     1151            return 0; 
     1152        CBP(parse_info,OPS_PTAG_RAW_SS,&content); 
    11111153        return 1; 
    11121154        } 
     
    11271169 
    11281170    case OPS_PTAG_SS_TRUST: 
    1129         if(!ops_limited_read(&C.ss_trust.level,1,&subregion,parse_info) 
    1130            || !ops_limited_read(&C.ss_trust.amount,1,&subregion,parse_info)) 
     1171        if(!limited_read(&C.ss_trust.level,1,&subregion,parse_info) 
     1172           || !limited_read(&C.ss_trust.amount,1,&subregion,parse_info)) 
    11311173            return 0; 
    11321174        break; 
    11331175 
    11341176    case OPS_PTAG_SS_REVOCABLE: 
    1135         if(!ops_limited_read(bool,1,&subregion,parse_info)) 
     1177        if(!limited_read(bool,1,&subregion,parse_info)) 
    11361178            return 0; 
    11371179        C.ss_revocable.revocable=!!bool; 
     
    11391181 
    11401182    case OPS_PTAG_SS_ISSUER_KEY_ID: 
    1141         if(!ops_limited_read(C.ss_issuer_key_id.key_id,OPS_KEY_ID_SIZE, 
     1183        if(!limited_read(C.ss_issuer_key_id.key_id,OPS_KEY_ID_SIZE, 
    11421184                             &subregion,parse_info)) 
    11431185            return 0; 
     
    11621204                                 
    11631205    case OPS_PTAG_SS_PRIMARY_USER_ID: 
    1164         if(!ops_limited_read (bool,1,&subregion,parse_info)) 
     1206        if(!limited_read (bool,1,&subregion,parse_info)) 
    11651207            return 0; 
    11661208        C.ss_primary_user_id.primary_user_id = !!bool; 
     
    12411283    case OPS_PTAG_SS_REVOCATION_REASON: 
    12421284        /* first byte is the machine-readable code */ 
    1243         if(!ops_limited_read(&C.ss_revocation_reason.code,1,&subregion,parse_info)) 
     1285        if(!limited_read(&C.ss_revocation_reason.code,1,&subregion,parse_info)) 
    12441286            return 0; 
    12451287 
     
    12511293    case OPS_PTAG_SS_REVOCATION_KEY: 
    12521294        /* octet 0 = class. Bit 0x80 must be set */ 
    1253         if(!ops_limited_read (&C.ss_revocation_key.class,1,&subregion,parse_info)) 
     1295        if(!limited_read (&C.ss_revocation_key.class,1,&subregion,parse_info)) 
    12541296            return 0; 
    12551297        if(!(C.ss_revocation_key.class&0x80)) 
     
    12611303  
    12621304        /* octet 1 = algid */ 
    1263         if(!ops_limited_read(&C.ss_revocation_key.algid,1,&subregion,parse_info)) 
     1305        if(!limited_read(&C.ss_revocation_key.algid,1,&subregion,parse_info)) 
    12641306            return 0; 
    12651307  
    12661308        /* octets 2-21 = fingerprint */ 
    1267         if(!ops_limited_read(&C.ss_revocation_key.fingerprint[0],20,&subregion, 
    1268                              parse_info)) 
     1309        if(!limited_read(&C.ss_revocation_key.fingerprint[0],20,&subregion, 
     1310                         parse_info)) 
    12691311            return 0; 
    12701312        break; 
     
    12721314    default: 
    12731315        if(parse_info->ss_parsed[t8]&t7) 
    1274             ERR1("Unknown signature subpacket type (%d)",c[0]&0x7f); 
     1316            ERR1P(parse_info,"Unknown signature subpacket type (%d)", 
     1317                  c[0]&0x7f); 
    12751318        read=ops_false; 
    12761319        break; 
     
    12811324        { 
    12821325        if(content.critical) 
    1283             ERR1("Critical signature subpacket ignored (%d)",c[0]&0x7f); 
     1326            ERR1P(parse_info,"Critical signature subpacket ignored (%d)", 
     1327                  c[0]&0x7f); 
    12841328        if(!read && !limited_skip(subregion.length-1,&subregion,parse_info)) 
    12851329            return 0; 
     
    12911335 
    12921336    if(read && subregion.length_read != subregion.length) 
    1293         ERR1("Unconsumed data (%d)", subregion.length-subregion.length_read); 
     1337        ERR1P(parse_info,"Unconsumed data (%d)", subregion.length-subregion.length_read); 
    12941338  
    1295     CB(content.tag,&content); 
     1339    CBP(parse_info,content.tag,&content); 
    12961340 
    12971341    return 1; 
     
    13611405 
    13621406    if(subregion.length > region->length) 
    1363         ERR("Subpacket set too long"); 
     1407        ERRP(parse_info,"Subpacket set too long"); 
    13641408 
    13651409    while(subregion.length_read < subregion.length) 
     
    13711415        if(!limited_skip(subregion.length-subregion.length_read,&subregion, 
    13721416                         parse_info)) 
    1373             ERR("Read failed while recovering from subpacket length mismatch"); 
    1374         ERR("Subpacket length mismatch"); 
     1417            ERRP(parse_info,"Read failed while recovering from subpacket length mismatch"); 
     1418        ERRP(parse_info,"Subpacket length mismatch"); 
    13751419        } 
    13761420 
     
    14011445    C.signature.v4_hashed_data_start=v4_hashed_data_start; 
    14021446 
    1403     if(!ops_limited_read(c,1,region,parse_info)) 
     1447    if(!limited_read(c,1,region,parse_info)) 
    14041448        return 0; 
    14051449    C.signature.type=c[0]; 
    14061450    /* XXX: check signature type */ 
    14071451 
    1408     if(!ops_limited_read(c,1,region,parse_info)) 
     1452    if(!limited_read(c,1,region,parse_info)) 
    14091453        return 0; 
    14101454    C.signature.key_algorithm=c[0]; 
    14111455    /* XXX: check algorithm */ 
    14121456 
    1413     if(!ops_limited_read(c,1,region,parse_info)) 
     1457    if(!limited_read(c,1,region,parse_info)) 
    14141458        return 0; 
    14151459    C.signature.hash_algorithm=c[0]; 
    14161460    /* XXX: check algorithm */ 
    14171461 
    1418     CB(OPS_PTAG_CT_SIGNATURE_HEADER,&content); 
     1462    CBP(parse_info,OPS_PTAG_CT_SIGNATURE_HEADER,&content); 
    14191463 
    14201464    if(!parse_signature_subpackets(&C.signature,region,parse_info)) 
    14211465        return 0; 
    1422     C.signature.v4_hashed_data_length=parse_info->alength 
     1466    C.signature.v4_hashed_data_length=parse_info->rinfo.alength 
    14231467        -C.signature.v4_hashed_data_start; 
    14241468 
     
    14261470        return 0; 
    14271471     
    1428     if(!ops_limited_read(C.signature.hash2,2,region,parse_info)) 
     1472    if(!limited_read(C.signature.hash2,2,region,parse_info)) 
    14291473        return 0; 
    14301474 
     
    14381482    case OPS_PKA_DSA: 
    14391483        if(!limited_read_mpi(&C.signature.signature.dsa.r,region,parse_info))  
    1440             ERR("Error reading DSA r field in signature"); 
     1484            ERRP(parse_info,"Error reading DSA r field in signature"); 
    14411485        if (!limited_read_mpi(&C.signature.signature.dsa.s,region,parse_info)) 
    1442             ERR("Error reading DSA s field in signature"); 
     1486            ERRP(parse_info,"Error reading DSA s field in signature"); 
    14431487        break; 
    14441488 
     
    14651509 
    14661510    default: 
    1467         ERR1("Bad v4 signature key algorithm (%d)",C.signature.key_algorithm); 
     1511        ERR1P(parse_info,"Bad v4 signature key algorithm (%d)", 
     1512              C.signature.key_algorithm); 
    14681513        } 
    14691514 
    14701515    if(region->length_read != region->length) 
    1471         ERR1("Unconsumed data (%d)",region->length-region->length_read); 
    1472  
    1473     CB(OPS_PTAG_CT_SIGNATURE_FOOTER,&content); 
     1516        ERR1P(parse_info,"Unconsumed data (%d)", 
     1517              region->length-region->length_read); 
     1518 
     1519    CBP(parse_info,OPS_PTAG_CT_SIGNATURE_FOOTER,&content); 
    14741520 
    14751521    return 1; 
     
    14971543    memset(&content,'\0',sizeof content); 
    14981544 
    1499     v4_hashed_data_start=parse_info->alength; 
    1500     if(!ops_limited_read(c,1,region,parse_info)) 
    1501         return 0; 
    1502  
    1503     /* XXX: More V2 issues!  - Ben*/ 
    1504     /* XXX: are there v2 signatures? - Peter */ 
     1545    v4_hashed_data_start=parse_info->rinfo.alength; 
     1546    if(!limited_read(c,1,region,parse_info)) 
     1547        return 0; 
     1548 
    15051549    if(c[0] == 2 || c[0] == 3) 
    15061550        return parse_v3_signature(region,parse_info); 
    15071551    else if(c[0] == 4) 
    15081552        return parse_v4_signature(region,parse_info,v4_hashed_data_start); 
    1509     ERR1("Bad signature version (%d)",c[0]); 
     1553    ERR1P(parse_info,"Bad signature version (%d)",c[0]); 
    15101554    } 
    15111555 
     
    15151559    ops_parser_content_t content; 
    15161560 
    1517     if(!ops_limited_read(c,1,region,parse_info)) 
     1561    if(!limited_read(c,1,region,parse_info)) 
    15181562        return 0; 
    15191563 
    15201564    C.compressed.type=c[0]; 
    15211565 
    1522     CB(OPS_PTAG_CT_COMPRESSED,&content); 
     1566    CBP(parse_info,OPS_PTAG_CT_COMPRESSED,&content); 
    15231567 
    15241568    /* The content of a compressed data packet is more OpenPGP packets 
     
    15331577    ops_parser_content_t content; 
    15341578 
    1535     if(!ops_limited_read(&C.one_pass_signature.version,1,region,parse_info)) 
     1579    if(!limited_read(&C.one_pass_signature.version,1,region,parse_info)) 
    15361580        return 0; 
    15371581    if(C.one_pass_signature.version != 3) 
    1538         ERR1("Bad one-pass signature version (%d)", 
     1582        ERR1P(parse_info,"Bad one-pass signature version (%d)", 
    15391583             C.one_pass_signature.version); 
    15401584 
    1541     if(!ops_limited_read(c,1,region,parse_info)) 
     1585    if(!limited_read(c,1,region,parse_info)) 
    15421586        return 0; 
    15431587    C.one_pass_signature.sig_type=c[0]; 
    15441588 
    1545     if(!ops_limited_read(c,1,region,parse_info)) 
     1589    if(!limited_read(c,1,region,parse_info)) 
    15461590        return 0; 
    15471591    C.one_pass_signature.hash_algorithm=c[0]; 
    15481592 
    1549     if(!ops_limited_read(c,1,region,parse_info)) 
     1593    if(!limited_read(c,1,region,parse_info)) 
    15501594        return 0; 
    15511595    C.one_pass_signature.key_algorithm=c[0]; 
    15521596 
    1553     if(!ops_limited_read(C.one_pass_signature.keyid, 
     1597    if(!limited_read(C.one_pass_signature.keyid, 
    15541598                         sizeof C.one_pass_signature.keyid,region,parse_info)) 
    15551599        return 0; 
    15561600 
    1557     if(!ops_limited_read(c,1,region,parse_info)) 
     1601    if(!limited_read(c,1,region,parse_info)) 
    15581602        return 0; 
    15591603    C.one_pass_signature.nested=!!c[0]; 
    15601604 
    1561     CB(OPS_PTAG_CT_ONE_PASS_SIGNATURE,&content); 
     1605    CBP(parse_info,OPS_PTAG_CT_ONE_PASS_SIGNATURE,&content); 
    15621606 
    15631607    return 1; 
     
    16031647            return 0; 
    16041648 
    1605     CB(OPS_PTAG_CT_TRUST, &content); 
     1649    CBP(parse_info,OPS_PTAG_CT_TRUST, &content); 
    16061650 
    16071651    return 1; 
     
    16131657    unsigned char c[1]; 
    16141658 
    1615     if(!ops_limited_read(c,1,region,parse_info)) 
     1659    if(!limited_read(c,1,region,parse_info)) 
    16161660        return 0; 
    16171661    C.literal_data_header.format=c[0]; 
    16181662 
    1619     if(!ops_limited_read(c,1,region,parse_info)) 
    1620         return 0; 
    1621     if(!ops_limited_read((unsigned char *)C.literal_data_header.filename,c[0],region,parse_info)) 
     1663    if(!limited_read(c,1,region,parse_info)) 
     1664        return 0; 
     1665    if(!limited_read((unsigned char *)C.literal_data_header.filename,c[0], 
     1666                     region,parse_info)) 
    16221667        return 0; 
    16231668    C.literal_data_header.filename[c[0]]='\0'; 
     
    16261671        return 0; 
    16271672 
    1628     CB(OPS_PTAG_CT_LITERAL_DATA_HEADER,&content); 
     1673    CBP(parse_info,OPS_PTAG_CT_LITERAL_DATA_HEADER,&content); 
    16291674 
    16301675    while(region->length_read < region->length) 
     
    16351680            l=sizeof C.literal_data_body.data; 
    16361681 
    1637         if(!ops_limited_read(C.literal_data_body.data,l,region,parse_info)) 
     1682        if(!limited_read(C.literal_data_body.data,l,region,parse_info)) 
    16381683            return 0; 
    16391684 
    16401685        C.literal_data_body.length=l; 
    16411686 
    1642         CB(OPS_PTAG_CT_LITERAL_DATA_BODY,&content); 
     1687        CBP(parse_info,OPS_PTAG_CT_LITERAL_DATA_BODY,&content); 
    16431688        } 
    16441689 
     
    16821727    if(!parse_public_key_data(&C.secret_key.public_key,region,parse_info)) 
    16831728        return 0; 
    1684     if(!ops_limited_read(c,1,region,parse_info)) 
     1729    if(!limited_read(c,1,region,parse_info)) 
    16851730        return 0; 
    16861731    C.secret_key.s2k_usage=c[0]; 
     
    17071752    // XXX: check the checksum 
    17081753 
    1709     CB(OPS_PTAG_CT_SECRET_KEY,&content); 
     1754    CBP(parse_info,OPS_PTAG_CT_SECRET_KEY,&content); 
    17101755 
    17111756    return 1; 
     
    17211766 * \param *pktlen       On return, will contain number of bytes in packet 
    17221767 * \return 1 on success, 0 on error, -1 on EOF */ 
    1723 static int ops_parse_one_packet(ops_parse_info_t *parse_info,unsigned long *pktlen) 
     1768static int ops_parse_one_packet(ops_parse_info_t *parse_info, 
     1769                                unsigned long *pktlen) 
    17241770    { 
    17251771    unsigned char ptag[1]; 
     
    17311777    ops_boolean_t indeterminate=ops_false; 
    17321778 
    1733     C.ptag.position=parse_info->position; 
     1779    C.ptag.position=parse_info->rinfo.position; 
    17341780 
    17351781    ret=base_read(ptag,&one,0,parse_info); 
     
    17431789        { 
    17441790        C.error.error="Format error (ptag bit not set)"; 
    1745         CB(OPS_PARSER_ERROR,&content); 
     1791        CBP(parse_info,OPS_PARSER_ERROR,&content); 
    17461792        return 0; 
    17471793        } 
     
    17841830        } 
    17851831 
    1786     CB(OPS_PARSER_PTAG,&content); 
     1832    CBP(parse_info,OPS_PARSER_PTAG,&content); 
    17871833 
    17881834    ops_init_subregion(&region,NULL); 
     
    18311877        format_error(&content,"Format error (unknown content tag %d)", 
    18321878                     C.ptag.content_tag); 
    1833         CB(OPS_PARSER_ERROR,&content); 
     1879        CBP(parse_info,OPS_PARSER_ERROR,&content); 
    18341880        r=0; 
    18351881        } 
     
    18461892            /* now throw it away */ 
    18471893            data_free(&remainder); 
    1848             WARN("Remainder of packet consumed and discarded."); 
     1894            WARNP(parse_info,"Remainder of packet consumed and discarded."); 
    18491895            } 
    18501896        else 
    1851             WARN("Problem consuming remainder of error packet."); 
     1897            WARNP(parse_info,"Problem consuming remainder of error packet."); 
    18521898        } 
    18531899 
    18541900    /* set pktlen */ 
    18551901 
    1856     *pktlen=parse_info->alength; 
     1902    *pktlen=parse_info->rinfo.alength; 
    18571903 
    18581904    /* do callback on entire packet, if desired */ 
    18591905 
    1860     if(parse_info->accumulate) 
    1861         { 
    1862         C.packet.length=parse_info->alength; 
    1863         C.packet.raw=parse_info->accumulated; 
    1864         parse_info->accumulated=NULL; 
    1865         parse_info->asize=0; 
    1866         CB(OPS_PARSER_PACKET_END,&content); 
    1867         } 
    1868     parse_info->alength=0; 
     1906    if(parse_info->rinfo.accumulate) 
     1907        { 
     1908        C.packet.length=parse_info->rinfo.alength; 
     1909        C.packet.raw=parse_info->rinfo.accumulated; 
     1910        parse_info->rinfo.accumulated=NULL; 
     1911        parse_info->rinfo.asize=0; 
     1912        CBP(parse_info,OPS_PARSER_PACKET_END,&content); 
     1913        } 
     1914    parse_info->rinfo.alength=0; 
    18691915         
    18701916    return r ? 1 : 0; 
     
    19081954    } 
    19091955 
     1956#if 0 
    19101957/** 
    19111958 * 
     
    19241971    /* can only handle ops_reader_fd for now */ 
    19251972 
    1926     if (parse_info->reader != ops_reader_fd) 
     1973    if (parse_info->rinfo.reader != ops_reader_fd) 
    19271974        { 
    19281975        fprintf(stderr,"ops_parse_errs: can only handle ops_reader_fd\n"); 
     
    19301977        } 
    19311978 
    1932     arg=parse_info->reader_arg; 
     1979    arg=parse_info->rinfo.arg; 
    19331980 
    19341981    /* store current state of accumulate flag */ 
    19351982 
    1936     orig_acc=parse_info->accumulate; 
     1983    orig_acc=parse_info->rinfo.accumulate; 
    19371984 
    19381985    /* set accumulate flag */ 
    19391986 
    1940     parse_info->accumulate=1; 
     1987    parse_info->rinfo.accumulate=1; 
    19411988 
    19421989    /* now parse each error in turn. */ 
     
    19632010 
    19642011    /* restore accumulate flag original value */ 
    1965     parse_info->accumulate=orig_acc; 
     2012    parse_info->rinfo.accumulate=orig_acc; 
    19662013 
    19672014    return 1; 
    19682015    } 
     2016#endif 
    19692017 
    19702018/** 
     
    20172065    } 
    20182066 
     2067ops_parse_info_t *ops_parse_info_new(void) 
     2068    { return ops_mallocz(sizeof(ops_parse_info_t)); } 
     2069 
     2070void ops_parse_info_delete(ops_parse_info_t *pinfo) 
     2071    { free(pinfo); } 
     2072 
     2073ops_reader_info_t *ops_parse_get_rinfo(ops_parse_info_t *pinfo) 
     2074    { return &pinfo->rinfo; } 
     2075 
     2076void ops_parse_cb_set(ops_parse_info_t *pinfo,ops_parse_cb_t *cb,void *arg) 
     2077    { 
     2078    pinfo->cbinfo.cb=cb; 
     2079    pinfo->cbinfo.arg=arg; 
     2080    } 
     2081 
     2082void ops_parse_cb_push(ops_parse_info_t *pinfo,ops_parse_cb_t *cb,void *arg) 
     2083    { 
     2084    ops_parse_cb_info_t *cbinfo=malloc(sizeof *cbinfo); 
     2085 
     2086    *cbinfo=pinfo->cbinfo; 
     2087    pinfo->cbinfo.next=cbinfo; 
     2088    ops_parse_cb_set(pinfo,cb,arg); 
     2089    } 
     2090 
     2091void *ops_parse_cb_get_arg(ops_parse_cb_info_t *cbinfo) 
     2092    { return cbinfo->arg; } 
     2093 
     2094ops_parse_cb_return_t ops_parse_cb(const ops_parser_content_t *content, 
     2095                                   ops_parse_cb_info_t *cbinfo) 
     2096    { return cbinfo->cb(content,cbinfo); } 
     2097 
     2098ops_parse_cb_return_t ops_parse_stacked_cb(const ops_parser_content_t *content, 
     2099                                           ops_parse_cb_info_t *cbinfo) 
     2100    { return ops_parse_cb(content,cbinfo->next); } 
     2101 
     2102void ops_reader_set(ops_parse_info_t *pinfo,ops_reader_t *reader,void *arg) 
     2103    { 
     2104    pinfo->rinfo.reader=reader; 
     2105    pinfo->rinfo.arg=arg; 
     2106    } 
     2107 
     2108void ops_reader_push(ops_parse_info_t *pinfo,ops_reader_t *reader,void *arg) 
     2109    { 
     2110    ops_reader_info_t *rinfo=malloc(sizeof *rinfo); 
     2111 
     2112    *rinfo=pinfo->rinfo; 
     2113    pinfo->rinfo.next=rinfo; 
     2114    ops_reader_set(pinfo,reader,arg); 
     2115    } 
     2116 
     2117void *ops_reader_get_arg(ops_reader_info_t *rinfo) 
     2118    { return rinfo->arg; } 
     2119 
     2120ops_error_t *ops_parse_info_get_errors(ops_parse_info_t *pinfo) 
     2121    { return pinfo->errors; } 
    20192122 
    20202123/* vim:set textwidth=120: */ 
  • openpgpsdk/trunk/src/util.c

    r312 r320  
    7979    } 
    8080 
     81/** Arguments for reader_fd 
     82 */ 
     83typedef struct 
     84    { 
     85    int fd; /*!< file descriptor */ 
     86    } reader_fd_arg_t; 
     87 
    8188/** 
    8289 * \ingroup Parse 
     
    103110 * \todo change arg_ to typesafe?  
    104111 */ 
    105 ops_reader_ret_t ops_reader_fd(unsigned char *dest,unsigned *plength, 
    106                                ops_reader_flags_t flags, 
    107                                ops_parse_info_t *parse_info) 
     112static ops_reader_ret_t reader_fd(unsigned char *dest,unsigned *plength, 
     113                                  ops_reader_flags_t flags, 
     114                                  ops_error_t **errors, 
     115                                  ops_reader_info_t *rinfo, 
     116                                  ops_parse_cb_info_t *cbinfo) 
    108117    { 
    109     ops_reader_fd_arg_t *arg=parse_info->reader_arg
     118    reader_fd_arg_t *arg=ops_reader_get_arg(rinfo)
    110119    int n=read(arg->fd,dest,*plength); 
     120 
     121    OPS_USED(cbinfo); 
    111122 
    112123    if(n == 0) 
     
    115126    if(n == -1) 
    116127        { 
    117         ops_system_error_1(&parse_info->errors,OPS_E_R_READ_FAILED,"read", 
     128        OPS_SYSTEM_ERROR_1(errors,OPS_E_R_READ_FAILED,"read", 
    118129                           "file descriptor %d",arg->fd); 
    119130        return OPS_R_ERROR; 
     
    129140        else 
    130141            { 
    131             ops_error_1(&parse_info->errors,OPS_E_R_EARLY_EOF, 
    132                                "file descriptor %d",arg->fd); 
     142            OPS_ERROR_1(errors,OPS_E_R_EARLY_EOF,"file descriptor %d",arg->fd); 
    133143            return OPS_R_EARLY_EOF; 
    134144            } 
     
    142152    } 
    143153 
     154void ops_reader_set_fd(ops_parse_info_t *pinfo,int fd) 
     155    { 
     156    reader_fd_arg_t *arg=malloc(sizeof *arg); 
     157 
     158    arg->fd=fd; 
     159    ops_reader_set(pinfo,reader_fd,arg); 
     160    } 
     161 
    144162void *ops_mallocz(size_t n) 
    145163    { 
  • openpgpsdk/trunk/src/validate.c

    r308 r320  
    77#include <string.h> 
    88 
    9 /* XXX: because we might well use this reader with different callbacks 
    10    it would make sense to split the arguments for callbacks, one for the reader 
    11    and one for the callback */ 
    129typedef struct 
    1310    { 
     
    2825static ops_reader_ret_t key_data_reader(unsigned char *dest,unsigned *plength, 
    2926                                        ops_reader_flags_t flags, 
    30                                         ops_parse_info_t *parse_info) 
     27                                        ops_error_t **errors, 
     28                                        ops_reader_info_t *rinfo, 
     29                                        ops_parse_cb_info_t *cbinfo) 
    3130    { 
    32     validate_reader_arg_t *arg=parse_info->reader_arg
     31    validate_reader_arg_t *arg=ops_reader_get_arg(rinfo)
    3332 
    3433    OPS_USED(flags); 
     34    OPS_USED(errors); 
     35    OPS_USED(cbinfo); 
    3536    if(arg->offset == arg->key->packets[arg->packet].length) 
    3637        { 
     
    5556 */ 
    5657 
    57 static ops_parse_callback_return_t 
    58 validate_cb(const ops_parser_content_t *content_,void *arg_
     58static ops_parse_cb_return_t 
     59validate_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo
    5960     { 
    6061     const ops_parser_content_union_t *content=&content_->content; 
    61      validate_cb_arg_t *arg=arg_
     62     validate_cb_arg_t *arg=ops_parse_cb_get_arg(cbinfo)
    6263     const ops_key_data_t *signer; 
    6364     ops_boolean_t valid; 
     
    137138                                    const ops_keyring_t *keyring) 
    138139    { 
    139     ops_parse_info_t parse_info; 
     140    ops_parse_info_t *pinfo; 
    140141    validate_cb_arg_t carg; 
    141142    validate_reader_arg_t rarg; 
     
    144145    memset(&carg,'\0',sizeof carg); 
    145146 
    146     ops_parse_info_init(&parse_info); 
     147    pinfo=ops_parse_info_new(); 
    147148    //    ops_parse_options(&opt,OPS_PTAG_CT_SIGNATURE,OPS_PARSE_PARSED); 
    148     parse_info.cb=validate_cb; 
    149     parse_info.reader=key_data_reader; 
    150149 
    151150    rarg.key=key; 
     
    156155    carg.rarg=&rarg; 
    157156 
    158     parse_info.cb_arg=&carg
    159     parse_info.reader_arg=&rarg
     157    ops_parse_cb_set(pinfo,validate_cb,&carg)
     158    ops_reader_set(pinfo,key_data_reader,&rarg)
    160159 
    161     ops_parse(&parse_info); 
     160    ops_parse(pinfo); 
    162161 
    163162    ops_public_key_free(&carg.pkey);