]> git.ozlabs.org Git - ccan/blobdiff - ccan/rfc822/rfc822.h
rfc822: new module.
[ccan] / ccan / rfc822 / rfc822.h
diff --git a/ccan/rfc822/rfc822.h b/ccan/rfc822/rfc822.h
new file mode 100644 (file)
index 0000000..2beae41
--- /dev/null
@@ -0,0 +1,171 @@
+/* Licensed under LGPLv2.1+ - see LICENSE file for details */
+#ifndef CCAN_RFC822_H_
+#define CCAN_RFC822_H_
+
+#include <stdlib.h>
+
+#include <ccan/bytestring/bytestring.h>
+
+/* #define CCAN_RFC822_DEBUG 1 */
+
+struct rfc822_header;
+struct rfc822_msg;
+
+/**
+ * rfc822_set_allocation_failure_handler - set function to call on allocation
+ *                                        failure
+ * @h: failure handler function pointer
+ *
+ * Normally functions in this module abort() on allocation failure for
+ * simplicity.  You can change this behaviour by calling this function
+ * to set an alternative callback for allocation failures.  The
+ * callback is called with a string describing where the failure
+ * occurred, which can be used to log a more useful error message.
+ *
+ * Example:
+ *     static void my_handler(const char *str)
+ *     {
+ *             fprintf(stderr, "Allocation failure: %s\n", str);
+ *             exit(1);
+ *     }
+ *
+ *     static void do_rfc822_stuff(void *buf, size_t len)
+ *     {
+ *             rfc822_set_allocation_failure_handler(&my_handler);
+ *             rfc822_start(NULL, buf, len);
+ *     }
+ */
+void rfc822_set_allocation_failure_handler(void (*h)(const char *));
+
+
+static inline bool rfc822_iswsp(char c)
+{
+       return (c == ' ') || (c == '\t');
+}
+
+/**
+ * rfc822_check - check validity of an rfc822_msg context
+ * @msg: message to validate
+ *
+ * This debugging function checks the validity of the internal data
+ * structures in an active rfc822_msg context.  If @abortstr is
+ * non-NULL, that will be printed in a diagnostic if the state is
+ * inconsistent, and the function will abort.  If the state of the
+ * structure is valid it returns it unchanged.
+ *
+ * Returns the list head if the list is consistent, NULL if not (it
+ * can never return NULL if @abortstr is set).
+ */
+struct rfc822_msg *rfc822_check(const struct rfc822_msg *msg,
+                               const char *abortstr);
+
+/**
+ * rfc822_start - start parsing a new rfc822 message
+ * @ctx: talloc context to make allocations in
+ * @p: pointer to a buffer containing the message text
+ * @len: length of the message text
+ *
+ * This function creates a new rfc822_msg context for parsing an
+ * rfc822 message, initialized based on the message text given by the
+ * pointer.
+ */
+struct rfc822_msg *rfc822_start(const void *ctx, const char *p, size_t len);
+
+/**
+ * rfc822_free - free an rfc822 message
+ * @msg: message to free
+ *
+ * Frees an rfc822_msg context, including all subsiduary data
+ * structures.
+ */
+void rfc822_free(struct rfc822_msg *msg);
+
+/**
+ * rfc822_first_header - retrieve the first header of an rfc822 message
+ * @msg: message
+ *
+ * Finds the first header field of @msg and returns a struct
+ * rfc822_header pointer representing it.
+ */
+#define rfc822_first_header(msg) (rfc822_next_header((msg), NULL))
+
+/**
+ * rfc822_next_header - retrieve the next header of an rfc822 message
+ * @msg: message
+ * @hdr: current header field
+ *
+ * Finds the header field of @msg which immediately follows @hdr and
+ * returns a struct rfc822_header pointer for it.  If @hdr is NULL,
+ * returns the first header in the message.
+ */
+struct rfc822_header *rfc822_next_header(struct rfc822_msg *msg,
+                                        struct rfc822_header *hdr);
+
+#define rfc822_for_each_header(msg, hdr) \
+       for ((hdr) = rfc822_first_header((msg)); \
+            (hdr);                                     \
+            (hdr) = rfc822_next_header((msg), (hdr)))
+
+/**
+ * rfc822_body - retrieve the body of an rfc822 message
+ * @msg: message
+ *
+ * Finds the body of @msg and returns a bytestring containing its
+ * contents.
+ */
+struct bytestring rfc822_body(struct rfc822_msg *msg);
+
+enum rfc822_header_errors {
+       RFC822_HDR_NO_COLON = 1,
+       RFC822_HDR_BAD_NAME = 2,
+};
+
+enum rfc822_header_errors rfc822_header_errors(struct rfc822_msg *msg,
+                                              struct rfc822_header *hdr);
+
+/**
+ * rfc822_header_raw_content - retrieve the raw content of an rfc822 header
+ * @hdr: a header handle
+ *
+ * This returns a bytestring containing the complete contents (name
+ * and value) of @hdr.  This will work even if the header is badly
+ * formatted and cannot otherwise be parsed.
+ */
+struct bytestring rfc822_header_raw_content(struct rfc822_msg *msg,
+                                           struct rfc822_header *hdr);
+
+
+/**
+ * rfc822_header_raw_name - retrieve the name of an rfc822 header
+ * @hdr: a header handle
+ *
+ * This returns a bytestring containing the header name of @hdr.  This
+ * could include any invalid characters, in the case of a badly
+ * formatted header.
+ */
+struct bytestring rfc822_header_raw_name(struct rfc822_msg *msg,
+                                        struct rfc822_header *hdr);
+
+/**
+ * rfc822_header_raw_value - retrieve the unprocessed value of an rfc822 header
+ * @hdr: a header handle
+ *
+ * This returns a bytestring containing the complete contents of
+ * @hdr's value.  This includes the terminating and any internal
+ * (folded) newlines.
+ */
+struct bytestring rfc822_header_raw_value(struct rfc822_msg *msg,
+                                         struct rfc822_header *hdr);
+
+/**
+ * rfc822_header_unfolded_value - retrieve the unfolded value of an rfc822 header
+ * @hdr: a header handle
+ *
+ * This returns a bytestring containing the unfolded contents of
+ * @hdr's value.  That is, the header value with any internal and the
+ * terminating newline removed.
+ */
+struct bytestring rfc822_header_unfolded_value(struct rfc822_msg *msg,
+                                              struct rfc822_header *hdr);
+
+#endif /* CCAN_RFC822_H_ */