Xoxa-c  0.3.1
Normalizer/Parser for XML
 All Data Structures Files Functions Variables Typedefs Enumerations Pages
xoxa.h
Go to the documentation of this file.
1 /* xoxa.h.prefix ... */
2 /* This file is part of the Xoxa library: https://bitbucket.org/nxg/xoxa
3  * Copyright 2013, 2014, Norman Gray <http://nxg.me.uk>.
4  * It is distributed under the terms of the BSD 2-clause Licence;
5  * see the file LICENCE for details.
6  */
7 
104 /* util_types.h ... */
105 #ifndef UTIL_TYPES_H_READ
106 #define UTIL_TYPES_H_READ 1
107 
108 // This header contains types which are used in util.h, and which are
109 // also used in xml_expat.h, which util.h includes. Separate them out
110 // here to avoid an import loop.
111 
112 #include <stdlib.h>
113 #include <stdint.h>
114 
115 typedef uint8_t byte;
116 
117 typedef struct {
118  size_t nwritten;
119  size_t len;
120  byte* buf;
121 } Buf;
122 
123 #endif /* UTIL_TYPES_H_READ */
124 /* pgp_types.h ... */
125 #ifndef PGP_TYPES_H_READ
126 #define PGP_TYPES_H_READ 1
127 
128 #include <sys/select.h>
129 
130 //#include "util_types.h"
131 
132 // This header contains types which are used in pgp.h, and which are
133 // also used in xml_expat.h, which pgp.h includes. Separate them out
134 // here to avoid an import loop.
135 
136 #if XOXA_PRIVATE_INTERFACE
137 // A channel for communicating with the subprocess. Note that the
138 // Channel is a read or write channel _from the point of view of the
139 // parent process_ rather than the child.
140 //
141 // Creating a writing channel (non-zero argument to new_channel)
142 // creates a Buf within the channel; creating a reading channel does
143 // not, and one must be added to the channel subsequently.
144 typedef struct {
145  int fd[2]; // fd[0]=read end; fd[1]=write end
146  Buf* buf; // the content to be written, or into which the pipe will be read
147  ssize_t nwritten; // negative if this channel is to be read from
148 } Channel;
149 #define CHANNEL_FOR_WRITING_P(ch) ((ch)->nwritten >= 0)
150 // Retrieve the FD associated with this Channel; this will be open for
151 // reading (respectively writing) if the Channel is a read (write) one.
152 #define CHANNEL_GET_FD(ch) (CHANNEL_FOR_WRITING_P(ch) ? (ch)->fd[1] : (ch)->fd[0])
153 // Get the _other_ FD, which is the FD associated with the other
154 // end of the Channel's pipe, in the child.
155 #define CHANNEL_GET_CHILD_FD(ch) (CHANNEL_FOR_WRITING_P(ch) ? (ch)->fd[0] : (ch)->fd[1])
156 
157 typedef struct process_manager_s {
158  int in; // the write end of a pipe, which goes to the subprocess stdin
159  char nchan; // the number of extra channels (including the subprocess stdout/stderr)
160  Channel** ch; // the other channels
161  pid_t child; // the PID of the subprocess
162  fd_set readable; // a mask of the readable channels
163 } ProcessManager;
164 #endif /* XOXA_PRIVATE_INTERFACE */
165 
167 typedef enum { good_sig, bad_sig, unknown } GPGResult;
168 
175 typedef struct gpg_result_s {
179  union {
181  struct {
183  char* keyid;
185  char* username;
186  } goodsig;
188  struct {
190  char* keyid;
192  char* username;
193  } badsig;
194  } detail;
196  const char* stderr; // content of GPG stderr, or NULL if unavailable
198 
199 
200 #endif /* PGP_TYPES_H_READ */
201 /* xml_expat.h ... */
202 #ifndef XML_EXPAT_H
203 #define XML_EXPAT_H 1
204 
205 #include <stdio.h>
206 #include <stdint.h>
207 #include <setjmp.h>
208 
209 #include <expat.h>
210 
211 //#include "util_types.h"
212 //#include "pgp_types.h"
213 
214 struct ParserState_s;
218 typedef struct ParserState_s ParserState;
219 
220 
221 
232 typedef void (*output_callback_t)(const byte* bytes, size_t len, void* data);
233 
242 typedef void (*output_callback_end_t)(ParserState*, void* data);
243 
246  void* data,
247  const char* label);
248 
250  output_callback_end_t cb_end);
251 
252 // public interface
253 
264 typedef uint8_t ParserFlags;
265 // the flag values are only for communication with the xoxa_parser_flags function
266 #define XOXA_REPORT_ALL 1<<0
267 // the following three occupy two bits; XOXA_CHATTER also acts as a mask for these
268 #define XOXA_QUIET 1<<1
269 #define XOXA_FEEDBACK 2<<1
270 #define XOXA_CHATTER 3<<1
271 #if XOXA_PRIVATE_INTERFACE
272 #define SHOWING_MESSAGES(PS_P) ((PS_P)->flags.verbosity > 0)
273 #define SHOWING_CHATTER(PS_P) ((PS_P)->flags.verbosity > 1)
274 #endif
275 
276 #define INPUT_SOURCE_STRING 0
277 #define INPUT_SOURCE_FILE 1
278 typedef struct {
279  char type; // INPUT_SOURCE_*
280  const char* basename; // the filename, in the case of in.f
281  union {
282  const char* buffer;
283  FILE* f;
284  } in;
285 } InputSource;
286 
287 struct callback_frame_s {
289  output_callback_end_t f_end;
290  unsigned int startdepth;
291  void* data;
292  const char* label; // a printable label for this frame
293  struct callback_frame_s* down;
294 };
295 typedef struct callback_frame_s callback_frame_t;
296 #define VALID_CALLBACK_FRAME(FRAME) ((FRAME)->f != NULL)
297 
298 
305  XML_Parser parser;
306  InputSource *src;
307  callback_frame_t* callback;
308  // element_depth is incremented at the start of any element,
309  // and decremented at its end
310  unsigned int element_depth;
311  Buf* B;
312  Buf* text;
313  char text_skipping_whitespace; // values of this are private to xml_expat.c
314  struct {
315  unsigned int report_all : 1;
316  unsigned int verbosity : 2; // values 0, 1, 2
317 #define XOXA_DIGEST_TYPE_NONE 0
318 #define XOXA_DIGEST_TYPE_MD 1
319 #define XOXA_DIGEST_TYPE_PGP 2
320  // also indicates whether pgp or digest is used in union 'd' below
321  unsigned int digest_type : 2;
322  } flags;
323  union {
324  struct {
325  void* ctx;
326  byte* bytes;
327  unsigned int len;
328  } digest;
329  SignatureDetail pgp; // if parser_flags & XOXA_DIGEST_IS_PGP_
330  } d;
331  // following three are filled in from a <?signature?> PI
332  const char* signature_armor;
333  const char* signature_xpath;
334  const char* signature_algorithm;
335  output_callback_t signature_callback;
336  void* signature_callback_data;
337  jmp_buf* error_jmp_buf;
338  char* error_message; // NULL if no error
339 
340  // The following extra_* functions are so that we can insert the
341  // Xoxa handlers in between the caller and the underlying Expat
342  // handlers, and so implement the Expat interface transparently.
343  // Each Xoxa handler is written so that it calls the corresponding
344  // extra_* handler as well.
345  XML_StartElementHandler extra_StartElementHandler;
346  XML_EndElementHandler extra_EndElementHandler;
347  XML_CharacterDataHandler extra_CharacterDataHandler;
348  XML_ProcessingInstructionHandler extra_ProcessingInstructionHandler;
349  XML_StartCdataSectionHandler extra_StartCdataSectionHandler;
350  XML_EndCdataSectionHandler extra_EndCdataSectionHandler;
351  XML_StartNamespaceDeclHandler extra_StartNamespaceDeclHandler;
352  XML_EndNamespaceDeclHandler extra_EndNamespaceDeclHandler;
353  XML_XmlDeclHandler extra_XmlDeclHandler;
354  XML_SkippedEntityHandler extra_SkippedEntityHandler;
355  void* extra_UserData;
356 };
357 
358 #if XOXA_PRIVATE_INTERFACE
359 ParserState* xoxa_make_new_parserstate_(InputSource* src,
360  XML_Parser parser,
361  ParserState* copy_of);
362 
363 // assertions for checking the ParserState structure.
364 // P->src may be NULL, if we're planning to use the GetBuffer
365 // mechanism to read the content, rather than xoxa_parse_*.
366 #define PARSERSTATE_OK_TEST_(P) \
367  ((P) != NULL \
368  && (P)->parser != NULL \
369  && (P)->B != NULL \
370  && (P)->text != NULL)
371 #define OK_PARSERSTATE(P) do { \
372  assert(PARSERSTATE_OK_TEST_(P)); \
373  } while (0)
374 
375 // Allocate and fail on any memory errors
376 #define MALLOC(var, Type) if ((var = (Type*)malloc(sizeof(Type))) == NULL) { \
377  fatal("Can't allocate space for " # Type); \
378  }
379 
380 #endif /* XOXA_PRIVATE_INTERFACE */
381 
382 ParserState* xoxa_new_parser(InputSource*);
385 
386 int xoxa_parse(ParserState*);
387 void xoxa_signature_fd(ParserState*, int);
388 byte* xoxa_get_digest(ParserState*, size_t*);
390 
391 void xoxa_null_callback(const byte* buf, size_t len, void* data);
392 void xoxa_default_callback(const byte* buf, size_t len, void* data);
393 
394 const char* xoxa_error_message(ParserState*);
395 
396 InputSource* xoxa_new_input_source_from_string(const char* xmlcontent);
397 InputSource* xoxa_new_input_source_from_filename(const char* filename);
398 InputSource* xoxa_new_input_source_from_fd(const int fd);
399 
400 const char* xoxa_parser_library_ident(void);
401 
402 #endif /* XML_EXPAT_H */
403 /* util.h ... */
404 #ifndef READ_UTIL_H
405 #define READ_UTIL_H 1
406 
407 //#include "util_types.h"
408 //#include "xml_expat.h"
409 
410 
411 const char* xoxa_version_string(void);
412 
413 #ifdef XOXA_PRIVATE_INTERFACE
414 
415 #include <setjmp.h>
416 
417 void fatal(const char* fmt, ...);
418 void warning(const char* fmt, ...);
419 void xoxa_set_error_message_(ParserState*, int abandon_parse_p, const char* fmt, ...);
420 void xoxa_abandon_parse_(ParserState*);
421 void xoxa_jmp_set_(ParserState*, jmp_buf*);
422 void xoxa_jmp_clear_(ParserState*);
423 int isxmlspace(const byte* p);
424 
425 byte* copystring(const byte* s);
426 
427 Buf* bufinit(void);
428 Buf* bufinit_with(const byte*);
429 Buf* bufprintf(Buf* B, const char* fmt, ...);
430 Buf* bufchar(Buf* B, byte c);
431 Buf* bufstrcpy(Buf* dst, const byte* src);
432 Buf* bufstrncpy(Buf* dst, const byte* src, const size_t len);
433 Buf* bufcrop(Buf* B);
434 byte* bufstring(Buf* B);
435 byte* bufstring_copy(Buf* B);
436 void bufreset(Buf* B);
437 size_t buflength(Buf*);
438 void buffree(Buf*);
439 
440 int bufstrcmp(const byte* b1, const byte* b2);
441 
442 #endif /* XOXA_PRIVATE_INTERFACE */
443 
444 #endif /* READ_UTIL_H */
445 /* digest.h ... */
446 #ifndef READ_DIGEST_H
447 #define READ_DIGEST_H 1
448 
449 //#include "xml_expat.h"
450 
451 // xoxa_parse_for_digest is implemented in digest.c
452 // xoxa_digest_{initialize,finalize} are implemented in digest_???.c
453 
486  const char* digest_name);
487 
507  const char* digest_name);
508 
516 
521 const char* xoxa_digest_library_ident(void);
522 
523 #endif /* READ_DIGEST_H */
524 /* pgp.h ... */
525 #ifndef PGP_H_LOADED
526 #define PGP_H_LOADED 1
527 
528 // The functions and structs in this header file are visible outside this module,
529 // but they are not part of the Xoxa public interface.
530 
531 //#include "util_types.h"
532 //#include "pgp_types.h"
533 //#include "xml_expat.h"
534 
535 #if XOXA_PRIVATE_INTERFACE
536 
537 #define CHANNEL_WRITE 1
538 #define CHANNEL_READ 0
539 Channel* new_channel(char writing_p); // call with non-zero to create a writing channel
540 void channel_free(Channel*);
541 int channel_add_buffer(Channel* ch, Buf* b); // can only be called with a writing channel
542 void subprocess_free(ProcessManager* pm);
543 int subprocess_send(ProcessManager* pm, const char* buf, size_t buflen);
544 ProcessManager* new_subprocess(char** cmd, ...);
545 ProcessManager* pgp_verify_detached(Channel* signature, Channel* status_info);
546 SignatureDetail* gpg_signature_init(SignatureDetail*);
547 SignatureDetail* gpg_parse_status(Channel* chatter, SignatureDetail* detail);
548 #endif /* XOXA_PRIVATE_INTERFACE */
549 
553 
554 // Name for the algorithm
555 //#define PGP_ALGORITHM_NAME "http://ns.nxg.me.uk/xoxa/algo#openpgp"
556 #define PGP_ALGORITHM_NAME "pgp"
557 
558 #endif /* PGP_H_LOADED */