From 3f58832474a4b270e136544016a401ef773ac065 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Thu, 17 Jan 2019 11:11:27 +0100 Subject: openpgp-ffi: New crate. - This creates a new crate, 'sequoia-openpgp-ffi', and moves a handful of functions from 'sequoia-ffi' to it. - The 'sequoia-ffi' crate is a superset of the 'sequoia-openpgp-ffi' crate. This is accomplished by some include! magic. - My first attempt involved having 'sequoia-ffi' depend on 'sequoia-openpgp-ffi', so that the former just re-exports the symbols. However, that turned out to be unreliable, and might be not what we want, because it could also duplicate parts of Rust's standard library. - Fixes #144. --- openpgp-ffi/examples/parser.c | 93 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 openpgp-ffi/examples/parser.c (limited to 'openpgp-ffi/examples/parser.c') diff --git a/openpgp-ffi/examples/parser.c b/openpgp-ffi/examples/parser.c new file mode 100644 index 00000000..81b097af --- /dev/null +++ b/openpgp-ffi/examples/parser.c @@ -0,0 +1,93 @@ +/* This example demonstrates how to use the packet parser from C. It + * also serves as a simple benchmark. */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +int +main (int argc, char **argv) +{ + struct stat st; + int fd; + uint8_t *b; + sq_status_t rc; + sq_error_t err; + sq_packet_parser_result_t ppr; + sq_packet_parser_t pp; + + if (argc != 2) + error (1, 0, "Usage: %s ", argv[0]); + + if (stat (argv[1], &st)) + error (1, errno, "%s", argv[1]); + + fd = open (argv[1], O_RDONLY); + if (fd == -1) + error (1, errno, "%s", argv[1]); + + b = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + close (fd); + if (b == MAP_FAILED) + error (1, errno, "mmap"); + + size_t n = 0; + time_t start = time (NULL); + time_t elapsed; + size_t tens_of_s = 0; + + ppr = sq_packet_parser_from_bytes (&err, b, st.st_size); + while (ppr && (pp = sq_packet_parser_result_packet_parser (ppr))) + { + // Get a reference to the packet that is currently being parsed. + sq_packet_t p = sq_packet_parser_packet (pp); + + if (sq_packet_tag(p) == SQ_TAG_LITERAL) + { + // Stream the packet here. + } + + // Finish parsing the current packet (returned in p), and read + // the header of the next packet (returned in ppr). + rc = sq_packet_parser_next (&err, pp, &p, &ppr); + if (rc) + error (1, 0, "sq_packet_parser_from_bytes: %s", + sq_error_string (err)); + + // We now own p. If we want, we can save it in some structure. + // This would be useful when collecting PKESK packets. Either + // way, we need to free it when we are done. + + n += 1; + + sq_packet_free (p); + + elapsed = time (NULL) - start; + if (elapsed % 10 == 0 && tens_of_s != elapsed / 10) + { + fprintf (stderr, + "Parsed %ld packets in %ld seconds, %.2f packets/s.\n", + n, elapsed, (double) n / (double) elapsed); + fflush (stderr); + tens_of_s = elapsed / 10; + } + } + if (ppr == NULL) + error (1, 0, "sq_packet_parser_from_bytes: %s", sq_error_string (err)); + + fprintf (stderr, "Parsed %ld packets in %ld seconds, %.2f packets/s.\n", + n, elapsed, (double) n / (double) elapsed); + + sq_packet_parser_result_free (ppr); + munmap (b, st.st_size); + return 0; +} -- cgit v1.2.3