summaryrefslogtreecommitdiffstats
path: root/include/inn
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 18:47:14 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 18:47:14 +0000
commit3eaf4237194e25804f221af93c269d3d97e2809d (patch)
treecdedf3fc954b0727b0b34aa9b0b211cc18f854eb /include/inn
downloadsmartcardauth-3eaf4237194e25804f221af93c269d3d97e2809d.tar.gz
smartcardauth-3eaf4237194e25804f221af93c269d3d97e2809d.zip
Added my SmartCard login/session lock/unlock utility
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/smartcardauth@1097604 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'include/inn')
-rw-r--r--include/inn/buffer.h48
-rw-r--r--include/inn/confparse.h78
-rw-r--r--include/inn/defines.h66
-rw-r--r--include/inn/hashtab.h60
-rw-r--r--include/inn/history.h110
-rw-r--r--include/inn/innconf.h211
-rw-r--r--include/inn/list.h51
-rw-r--r--include/inn/md5.h79
-rw-r--r--include/inn/messages.h99
-rw-r--r--include/inn/mmap.h33
-rw-r--r--include/inn/qio.h49
-rw-r--r--include/inn/sequence.h21
-rw-r--r--include/inn/timer.h38
-rw-r--r--include/inn/tst.h88
-rw-r--r--include/inn/vector.h87
-rw-r--r--include/inn/wire.h46
16 files changed, 1164 insertions, 0 deletions
diff --git a/include/inn/buffer.h b/include/inn/buffer.h
new file mode 100644
index 0000000..e9deb2b
--- /dev/null
+++ b/include/inn/buffer.h
@@ -0,0 +1,48 @@
+/* $Id: buffer.h 6295 2003-04-16 05:46:38Z rra $
+**
+** Counted, reusable memory buffer.
+**
+** A buffer is an allocated bit of memory with a known size and a separate
+** data length. It's intended to store strings and can be reused repeatedly
+** to minimize the number of memory allocations. Buffers increase in
+** increments of 1K.
+**
+** A buffer contains a notion of the data that's been used and the data
+** that's been left, used when the buffer is an I/O buffer where lots of data
+** is buffered and then slowly processed out of the buffer. The total length
+** of the data is used + left. If a buffer is just used to store some data,
+** used can be set to 0 and left stores the length of the data.
+*/
+
+#ifndef INN_BUFFER_H
+#define INN_BUFFER_H 1
+
+#include <inn/defines.h>
+
+struct buffer {
+ size_t size; /* Total allocated length. */
+ size_t used; /* Data already used. */
+ size_t left; /* Remaining unused data. */
+ char *data; /* Pointer to allocated memory. */
+};
+
+BEGIN_DECLS
+
+/* Allocate a new buffer and initialize its contents. */
+struct buffer *buffer_new(void);
+
+/* Resize a buffer to be at least as large as the provided size. */
+void buffer_resize(struct buffer *, size_t);
+
+/* Set the buffer contents, ignoring anything currently there. */
+void buffer_set(struct buffer *, const char *data, size_t length);
+
+/* Append data to the buffer. */
+void buffer_append(struct buffer *, const char *data, size_t length);
+
+/* Swap the contents of two buffers. */
+void buffer_swap(struct buffer *, struct buffer *);
+
+END_DECLS
+
+#endif /* INN_BUFFER_H */
diff --git a/include/inn/confparse.h b/include/inn/confparse.h
new file mode 100644
index 0000000..5c2aa1c
--- /dev/null
+++ b/include/inn/confparse.h
@@ -0,0 +1,78 @@
+/* $Id: confparse.h 5114 2002-02-18 01:17:24Z rra $
+**
+** Configuration file parsing interface.
+*/
+
+#ifndef INN_CONFPARSE_H
+#define INN_CONFPARSE_H 1
+
+#include <inn/defines.h>
+
+/* Avoid including <inn/vector.h> unless the client needs it. */
+struct vector;
+
+/* The opaque data type representing a configuration tree. */
+struct config_group;
+
+BEGIN_DECLS
+
+/* Parse the given file and build a configuration tree. This does purely
+ syntactic parsing; no semantic checking is done. After the file name, a
+ NULL-terminated list of const char * pointers should be given, naming the
+ top-level group types that the caller is interested in. If none are given
+ (if the second argument is NULL), the entire file is parsed. (This is
+ purely for efficiency reasons; if one doesn't care about speed, everything
+ will work the same if no types are given.)
+
+ Returns a config_group for the top-level group representing the entire
+ file. Generally one never wants to query parameters in this group;
+ instead, the client should then call config_find_group for the group type
+ of interest. Returns NULL on failure to read the file or on a parse
+ failure; errors are reported via warn. */
+struct config_group *config_parse_file(const char *filename, /* types */ ...);
+
+/* config_find_group returns the first group of the given type found in the
+ tree rooted at its argument. config_next_group returns the next group in
+ the tree of the same type as the given group (or NULL if none is found).
+ This can be used to do such things as enumerate all "peer" groups in a
+ configuration file. */
+struct config_group *config_find_group(struct config_group *,
+ const char *type);
+struct config_group *config_next_group(struct config_group *);
+
+/* Accessor functions for group information. */
+const char *config_group_type(struct config_group *);
+const char *config_group_tag(struct config_group *);
+
+/* Look up a parameter in a given config tree. The second argument is the
+ name of the parameter, and the result will be stored in the third argument
+ if the function returns true. If it returns false, the third argument is
+ unchanged and that parameter wasn't set (or was set to an invalid value for
+ the expected type). */
+bool config_param_boolean(struct config_group *, const char *, bool *);
+bool config_param_integer(struct config_group *, const char *, long *);
+bool config_param_real(struct config_group *, const char *, double *);
+bool config_param_string(struct config_group *, const char *, const char **);
+bool config_param_list(struct config_group *, const char *, struct vector *);
+
+/* Used for checking a configuration file, returns a vector of all parameters
+ set for the given config_group, including inherited ones. */
+struct vector *config_params(struct config_group *);
+
+/* Used for reporting semantic errors, config_error_param reports the given
+ error at a particular parameter in a config_group and config_error_group
+ reports an error at the definition of that group. The error is reported
+ using warn. */
+void config_error_group(struct config_group *, const char *format, ...);
+void config_error_param(struct config_group *, const char *key,
+ const char *format, ...);
+
+/* Free all space allocated by the tree rooted at config_group. One normally
+ never wants to do this. WARNING: This includes the storage allocated for
+ all strings returned by config_param_string and config_param_list for any
+ configuration groups in this tree. */
+void config_free(struct config_group *);
+
+END_DECLS
+
+#endif /* INN_CONFPARSE_H */
diff --git a/include/inn/defines.h b/include/inn/defines.h
new file mode 100644
index 0000000..74f4969
--- /dev/null
+++ b/include/inn/defines.h
@@ -0,0 +1,66 @@
+/* $Id: defines.h 6124 2003-01-14 06:03:29Z rra $
+**
+** Portable defines used by other INN header files.
+**
+** In order to make the libraries built by INN usable by other software,
+** INN needs to install several header files. Installing autoconf-
+** generated header files, however, is a bad idea, since the defines will
+** conflict with other software that uses autoconf.
+**
+** This header contains common definitions, such as internal typedefs and
+** macros, common to INN's header files but not based on autoconf probes.
+** As such, it's limited in what it can do; if compiling software against
+** INN's header files on a system not supporting basic ANSI C features
+** (such as const) or standard types (like size_t), the software may need
+** to duplicate the tests that INN itself performs, generate a config.h,
+** and make sure that config.h is included before any INN header files.
+*/
+
+#ifndef INN_DEFINES_H
+#define INN_DEFINES_H 1
+
+#include <inn/system.h>
+
+/* BEGIN_DECLS is used at the beginning of declarations so that C++
+ compilers don't mangle their names. END_DECLS is used at the end. */
+#undef BEGIN_DECLS
+#undef END_DECLS
+#ifdef __cplusplus
+# define BEGIN_DECLS extern "C" {
+# define END_DECLS }
+#else
+# define BEGIN_DECLS /* empty */
+# define END_DECLS /* empty */
+#endif
+
+/* __attribute__ is available in gcc 2.5 and later, but only with gcc 2.7
+ could you use the __format__ form of the attributes, which is what we use
+ (to avoid confusion with other macros). */
+#ifndef __attribute__
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
+# define __attribute__(spec) /* empty */
+# endif
+#endif
+
+/* Used for unused parameters to silence gcc warnings. */
+#define UNUSED __attribute__((__unused__))
+
+/* Make available the bool type. */
+#if INN_HAVE_STDBOOL_H
+# include <stdbool.h>
+#else
+# undef true
+# undef false
+# define true (1)
+# define false (0)
+# ifndef __cplusplus
+# define bool int
+# endif
+#endif /* INN_HAVE_STDBOOL_H */
+
+/* Tell Perl that we have a bool type. */
+#ifndef HAS_BOOL
+# define HAS_BOOL 1
+#endif
+
+#endif /* !INN_DEFINES_H */
diff --git a/include/inn/hashtab.h b/include/inn/hashtab.h
new file mode 100644
index 0000000..8d9f31e
--- /dev/null
+++ b/include/inn/hashtab.h
@@ -0,0 +1,60 @@
+/* $Id: hashtab.h 5944 2002-12-08 02:33:08Z rra $
+**
+** Generic hash table interface.
+**
+** Written by Russ Allbery <rra@stanford.edu>
+** This work is hereby placed in the public domain by its author.
+**
+** A hash table takes a hash function that acts on keys, a function to
+** extract the key from a data item stored in a hash, a function that takes
+** a key and a data item and returns true if the key matches, and a
+** function to be called on any data item being deleted from the hash.
+**
+** hash_create creates a hash and hash_free frees all the space allocated
+** by one. hash_insert, hash_replace, and hash_delete modify it, and
+** hash_lookup extracts values. hash_traverse can be used to walk the
+** hash, and hash_count returns the number of elements currently stored in
+** the hash. hash_searches, hash_collisions, and hash_expansions extract
+** performance and debugging statistics.
+*/
+
+#ifndef INN_HASHTAB_H
+#define INN_HASHTAB_H 1
+
+#include <inn/defines.h>
+
+BEGIN_DECLS
+
+/* The layout of this struct is entirely internal to the implementation. */
+struct hash;
+
+/* Data types for function pointers used by the hash table interface. */
+typedef unsigned long (*hash_func)(const void *);
+typedef const void * (*hash_key_func)(const void *);
+typedef bool (*hash_equal_func)(const void *, const void *);
+typedef void (*hash_delete_func)(void *);
+typedef void (*hash_traverse_func)(void *, void *);
+
+/* Generic hash table interface. */
+struct hash * hash_create(size_t, hash_func, hash_key_func,
+ hash_equal_func, hash_delete_func);
+void hash_free(struct hash *);
+void * hash_lookup(struct hash *, const void *key);
+bool hash_insert(struct hash *, const void *key, void *datum);
+bool hash_replace(struct hash *, const void *key, void *datum);
+bool hash_delete(struct hash *, const void *key);
+void hash_traverse(struct hash *, hash_traverse_func, void *);
+unsigned long hash_count(struct hash *);
+unsigned long hash_searches(struct hash *);
+unsigned long hash_collisions(struct hash *);
+unsigned long hash_expansions(struct hash *);
+
+/* Hash functions available for callers. */
+unsigned long hash_string(const void *);
+
+/* Functions useful for constructing new hashes. */
+unsigned long hash_lookup2(const char *, size_t, unsigned long partial);
+
+END_DECLS
+
+#endif /* INN_HASHTAB_H */
diff --git a/include/inn/history.h b/include/inn/history.h
new file mode 100644
index 0000000..48c6e25
--- /dev/null
+++ b/include/inn/history.h
@@ -0,0 +1,110 @@
+/* $Id: history.h 4916 2001-07-18 12:33:01Z alexk $
+**
+** Interface to history API
+*/
+
+#ifndef INN_HISTORY_H
+#define INN_HISTORY_H
+
+#include <inn/defines.h>
+
+BEGIN_DECLS
+
+/*
+** ensure appropriate scoping; we don't pull inn/storage.h as we
+** don't need; our caller then has the option
+*/
+struct history;
+struct token;
+
+/*
+** structure giving cache statistics returned from HISstats
+*/
+struct histstats {
+ /* number of positive hits */
+ int hitpos;
+ /* number of negative hits */
+ int hitneg;
+ /* number of misses (positive hit, but not in cache) */
+ int misses;
+ /* number of does not exists (negative hit, but not in cache) */
+ int dne;
+};
+
+
+/*
+** flags passed to HISopen
+*/
+
+/* open database read only */
+#define HIS_RDONLY (0)
+
+/* open database read/write */
+#define HIS_RDWR (1<<0)
+
+/* create on open */
+#define HIS_CREAT (1<<1)
+
+/* hint that the data should be kept on disk */
+#define HIS_ONDISK (1<<2)
+
+/* hint that the data should be kept in core */
+#define HIS_INCORE (1<<3)
+
+/* hint that the data should be kept mmap()ed */
+#define HIS_MMAP (1<<4)
+
+/*
+** values passed to HISctl
+*/
+enum {
+ /* (char **) get history path */
+ HISCTLG_PATH,
+
+ /* (char *) set history path */
+ HISCTLS_PATH,
+
+ /* (int) how many history writes may be outstanding */
+ HISCTLS_SYNCCOUNT,
+
+ /* (size_t) number of pairs for which the database should be sized */
+ HISCTLS_NPAIRS,
+
+ /* (bool) Ignore old database during expire */
+ HISCTLS_IGNOREOLD,
+
+ /* (time_t) interval, in s, between stats of the history database
+ * for * detecting a replacement, or 0 to disable (no checks);
+ * defaults {hisv6, taggedhash} */
+ HISCTLS_STATINTERVAL
+
+};
+
+struct history * HISopen(const char *, const char *, int);
+bool HISclose(struct history *);
+bool HISsync(struct history *);
+void HISsetcache(struct history *, size_t);
+bool HISlookup(struct history *, const char *, time_t *,
+ time_t *, time_t *, struct token *);
+bool HIScheck(struct history *, const char *);
+bool HISwrite(struct history *, const char *, time_t,
+ time_t, time_t, const struct token *);
+bool HISremember(struct history *, const char *, time_t);
+bool HISreplace(struct history *, const char *, time_t,
+ time_t, time_t, const struct token *);
+bool HISexpire(struct history *, const char *, const char *,
+ bool, void *, time_t,
+ bool (*)(void *, time_t, time_t, time_t,
+ struct token *));
+bool HISwalk(struct history *, const char *, void *,
+ bool (*)(void *, time_t, time_t, time_t,
+ const struct token *));
+struct histstats HISstats(struct history *);
+const char * HISerror(struct history *);
+bool HISctl(struct history *, int, void *);
+void HISlogclose(void);
+void HISlogto(const char *s);
+
+END_DECLS
+
+#endif
diff --git a/include/inn/innconf.h b/include/inn/innconf.h
new file mode 100644
index 0000000..8cd24d2
--- /dev/null
+++ b/include/inn/innconf.h
@@ -0,0 +1,211 @@
+/* $Id: innconf.h 7751 2008-04-06 14:35:40Z iulius $
+**
+** inn.conf parser interface.
+**
+** The interface to reading inn.conf configuration files and managing the
+** resulting innconf struct.
+*/
+
+#ifndef INN_INNCONF_H
+#define INN_INNCONF_H 1
+
+#include <inn/defines.h>
+#include <stdio.h>
+
+/*
+** This structure is organized in the same order as the variables contained
+** in it are mentioned in the inn.conf documentation, and broken down into
+** the same sections. Note that due to the implementation, only three types
+** of variables are permissible here: char *, bool, and long.
+*/
+struct innconf {
+ /* General Settings */
+ char *domain; /* Default domain of local host */
+ char *innflags; /* Flags to pass to innd on startup */
+ char *mailcmd; /* Command to send report/control type mail */
+ char *mta; /* MTA for mailing to moderators, innmail */
+ char *pathhost; /* Entry for the Path line */
+ char *server; /* Default server to connect to */
+
+ /* Feed Configuration */
+ long artcutoff; /* Max accepted article age */
+ char *bindaddress; /* Which interface IP to bind to */
+ char *bindaddress6; /* Which interface IPv6 to bind to */
+ bool dontrejectfiltered; /* Don't reject filtered article? */
+ long hiscachesize; /* Size of the history cache in kB */
+ bool ignorenewsgroups; /* Propagate cmsgs by affected group? */
+ bool immediatecancel; /* Immediately cancel timecaf messages? */
+ long linecountfuzz; /* Check linecount and reject if off by more */
+ long maxartsize; /* Reject articles bigger than this */
+ long maxconnections; /* Max number of incoming NNTP connections */
+ char *pathalias; /* Prepended Host for the Path line */
+ char *pathcluster; /* Appended Host for the Path line */
+ bool pgpverify; /* Verify control messages with pgpverify? */
+ long port; /* Which port innd should listen on */
+ bool refusecybercancels; /* Reject message IDs with "<cancel."? */
+ bool remembertrash; /* Put unwanted article IDs into history */
+ char *sourceaddress; /* Source IP for outgoing NNTP connections */
+ char *sourceaddress6; /* Source IPv6 for outgoing NNTP connections */
+ bool verifycancels; /* Verify cancels against article author */
+ bool wanttrash; /* Put unwanted articles in junk */
+ long wipcheck; /* How long to defer other copies of article */
+ long wipexpire; /* How long to keep pending article record */
+
+ /* History settings */
+ char *hismethod; /* Which history method to use */
+
+ /* Article Storage */
+ long cnfscheckfudgesize; /* Additional CNFS integrity checking */
+ bool enableoverview; /* Store overview info for articles? */
+ bool groupbaseexpiry; /* Do expiry by newsgroup? */
+ bool mergetogroups; /* Refile articles from to.* into to */
+ bool nfswriter; /* Use NFS writer functionality */
+ long overcachesize; /* fd size cache for tradindexed */
+ char *ovgrouppat; /* Newsgroups to store overview for */
+ char *ovmethod; /* Which overview method to use */
+ bool storeonxref; /* SMstore use Xref to detemine class? */
+ bool useoverchan; /* overchan write the overview, not innd? */
+ bool wireformat; /* Store tradspool artilces in wire format? */
+ bool xrefslave; /* Act as a slave of another server? */
+
+ /* Reading */
+ bool allownewnews; /* Allow use of the NEWNEWS command */
+ bool articlemmap; /* Use mmap to read articles? */
+ long clienttimeout; /* How long nnrpd can be inactive */
+ long initialtimeout; /* How long nnrpd waits for first command */
+ long msgidcachesize; /* Number of entries in the message ID cache */
+ bool nfsreader; /* Use NFS reader functionality */
+ long nfsreaderdelay; /* Delay applied to article arrival */
+ bool nnrpdcheckart; /* Check article existence before returning? */
+ char *nnrpdflags; /* Arguments to pass when spawning nnrpd */
+ long nnrpdloadlimit; /* Maximum getloadvg() we allow */
+ bool noreader; /* Refuse to fork nnrpd for readers? */
+ bool readerswhenstopped; /* Allow nnrpd when server is paused */
+ bool readertrack; /* Use the reader tracking system? */
+ bool tradindexedmmap; /* Whether to mmap for tradindexed */
+
+ /* Reading -- Keyword Support */
+ bool keywords; /* Generate keywords in overview? */
+ long keyartlimit; /* Max article size for keyword generation */
+ long keylimit; /* Max allocated space for keywords */
+ long keymaxwords; /* Max count of interesting works */
+
+ /* Posting */
+ bool addnntppostingdate; /* Add NNTP-Posting-Date: to posts */
+ bool addnntppostinghost; /* Add NNTP-Posting-Host: to posts */
+ bool checkincludedtext; /* Reject if too much included text */
+ char *complaints; /* Address for X-Complaints-To: */
+ char *fromhost; /* Host for the From: line */
+ long localmaxartsize; /* Max article size of local postings */
+ char *moderatormailer; /* Default host to mail moderated articles */
+ bool nnrpdauthsender; /* Add authenticated Sender: header? */
+ char *nnrpdposthost; /* Host postings should be forwarded to */
+ long nnrpdpostport; /* Port postings should be forwarded to */
+ char *organization; /* Data for the Organization: header */
+ bool spoolfirst; /* Spool all posted articles? */
+ bool strippostcc; /* Strip To:, Cc: and Bcc: from posts */
+
+ /* Posting -- Exponential Backoff */
+ bool backoffauth; /* Backoff by user, not IP address */
+ char *backoffdb; /* Directory for backoff databases */
+ long backoffk; /* Multiple for the sleep time */
+ long backoffpostfast; /* Upper time limit for fast posting */
+ long backoffpostslow; /* Lower time limit for slow posting */
+ long backofftrigger; /* Number of postings before triggered */
+
+ /* Monitoring */
+ bool doinnwatch; /* Start innwatch from rc.news? */
+ long innwatchbatchspace; /* Minimum free space in pathoutgoing */
+ long innwatchlibspace; /* Minimum free space in pathdb */
+ long innwatchloload; /* Load times 100 at which to restart */
+ long innwatchhiload; /* Load times 100 at which to throttle */
+ long innwatchpauseload; /* Load times 100 at which to pause */
+ long innwatchsleeptime; /* Seconds to wait between checks */
+ long innwatchspoolnodes; /* Minimum free inodes in patharticles */
+ long innwatchspoolspace; /* Minimum free space in patharticles */
+
+ /* Logging */
+ bool docnfsstat; /* Run cnfsstat in the background? */
+ bool logartsize; /* Log article sizes? */
+ bool logcancelcomm; /* Log ctlinnd cancel commands to syslog? */
+ long logcycles; /* How many old logs scanlogs should keep */
+ bool logipaddr; /* Log by host IP address? */
+ bool logsitename; /* Log outgoing site names? */
+ bool nnrpdoverstats; /* Log overview statistics? */
+ long nntpactsync; /* Checkpoint log after this many articles */
+ bool nntplinklog; /* Put storage token into the log? */
+ long status; /* Status file update interval */
+ long timer; /* Performance monitoring interval */
+ char *stathist; /* Filename for history profiler outputs */
+
+ /* System Tuning */
+ long badiocount; /* Failure count before dropping channel */
+ long blockbackoff; /* Multiplier for sleep in EAGAIN writes */
+ long chaninacttime; /* Wait before noticing inactive channels */
+ long chanretrytime; /* How long before channel restarts */
+ long icdsynccount; /* Articles between active & history updates */
+ long keepmmappedthreshold; /* Threshold for keeping mmap in buffindexed */
+ long maxforks; /* Give up after this many fork failure */
+ long nicekids; /* Child processes get niced to this */
+ long nicenewnews; /* If NEWNEWS command is used, nice to this */
+ long nicennrpd; /* nnrpd is niced to this */
+ long pauseretrytime; /* Seconds before seeing if pause is ended */
+ long peertimeout; /* How long peers can be inactive */
+ long rlimitnofile; /* File descriptor limit to set */
+ long maxcmdreadsize; /* max NNTP command read size used by innd */
+ long datamovethreshold; /* threshold no to extend buffer for ever */
+
+ /* Paths */
+ char *patharchive; /* Archived news. */
+ char *patharticles; /* Articles. */
+ char *pathbin; /* News binaries. */
+ char *pathcontrol; /* Path to control message handlers */
+ char *pathdb; /* News database files */
+ char *pathetc; /* News configuration files */
+ char *pathfilter; /* Filtering code */
+ char *pathhttp; /* HTML files */
+ char *pathincoming; /* Incoming spooled news */
+ char *pathlog; /* Log files */
+ char *pathnews; /* Home directory for news user */
+ char *pathoutgoing; /* Outgoing news batch files */
+ char *pathoverview; /* Overview infomation */
+ char *pathrun; /* Runtime state and sockets */
+ char *pathspool; /* Root of news spool hierarchy */
+ char *pathtmp; /* Temporary files for the news system */
+};
+
+/* The global innconf variable used in programs. */
+extern struct innconf *innconf;
+
+/* Used to request various types of quoting when printing out values. */
+enum innconf_quoting {
+ INNCONF_QUOTE_NONE,
+ INNCONF_QUOTE_SHELL,
+ INNCONF_QUOTE_PERL,
+ INNCONF_QUOTE_TCL
+};
+
+BEGIN_DECLS
+
+/* Parse the given file into innconf, using the default path if NULL. */
+bool innconf_read(const char *path);
+
+/* Free an innconf struct and all allocated memory for it. */
+void innconf_free(struct innconf *);
+
+/* Print a single value with appropriate quoting, return whether found. */
+bool innconf_print_value(FILE *, const char *key, enum innconf_quoting);
+
+/* Dump the entire configuration with appropriate quoting. */
+void innconf_dump(FILE *, enum innconf_quoting);
+
+/* Compare two instances of an innconf struct, for testing. */
+bool innconf_compare(struct innconf *, struct innconf *);
+
+/* Check the validity of an inn.conf file. Does innconf_read plus checking
+ for any unknown parameters that are set. */
+bool innconf_check(const char *path);
+
+END_DECLS
+
+#endif /* INN_INNCONF_H */
diff --git a/include/inn/list.h b/include/inn/list.h
new file mode 100644
index 0000000..99004e4
--- /dev/null
+++ b/include/inn/list.h
@@ -0,0 +1,51 @@
+/* $Id: list.h 6168 2003-01-21 06:27:32Z alexk $
+**
+*/
+
+#ifndef INN_LIST_H
+#define INN_LIST_H 1
+
+#include <inn/defines.h>
+
+struct node {
+ struct node *succ;
+ struct node *pred;
+};
+
+struct list {
+ struct node *head;
+ struct node *tail;
+ struct node *tailpred;
+};
+
+BEGIN_DECLS
+
+/* initialise a new list */
+void list_new(struct list *list);
+
+/* add a node to the head of the list */
+struct node *list_addhead(struct list *list, struct node *node);
+
+/* add a node to the tail of the list */
+struct node *list_addtail(struct list *list, struct node *node);
+
+/* return a pointer to the first node on the list */
+struct node *list_head(struct list *list);
+
+/* return a pointer to the last node on the list */
+struct node *list_tail(struct list *list);
+
+struct node *list_succ(struct node *node);
+struct node *list_pred(struct node *node);
+
+struct node *list_remhead(struct list *list);
+struct node *list_remove(struct node *node);
+struct node *list_remtail(struct list *list);
+struct node *list_insert(struct list *list, struct node *node,
+ struct node *pred);
+
+bool list_isempty(struct list *list);
+
+END_DECLS
+
+#endif /* INN_LIST_H */
diff --git a/include/inn/md5.h b/include/inn/md5.h
new file mode 100644
index 0000000..f0b1584
--- /dev/null
+++ b/include/inn/md5.h
@@ -0,0 +1,79 @@
+/* $Id: md5.h 4567 2001-02-24 08:10:16Z rra $
+**
+** RSA Data Security, Inc. MD5 Message-Digest Algorithm
+**
+** LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+** INCLUDING ALL IMPLIED WARRANTIES OF MER- CHANTABILITY AND FITNESS. IN
+** NO EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+** CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+** USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+** OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+** PERFORMANCE OF THIS SOFTWARE.
+**
+** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.
+**
+** License to copy and use this software is granted provided that it is
+** identified as the "RSA Data Security, Inc. MD5 Message-Digest
+** Algorithm" in all material mentioning or referencing this software or
+** this function.
+**
+** License is also granted to make and use derivative works provided that
+** such works are identified as "derived from the RSA Data Security,
+** Inc. MD5 Message-Digest Algorithm" in all material mentioning or
+** referencing the derived work.
+**
+** RSA Data Security, Inc. makes no representations concerning either the
+** merchantability of this software or the suitability of this software for
+** any particular purpose. It is provided "as is" without express or
+** implied warranty of any kind.
+**
+** These notices must be retained in any copies of any part of this
+** documentation and/or software.
+*/
+
+#ifndef INN_MD5_H
+#define INN_MD5_H 1
+
+#include <inn/defines.h>
+
+/* Make sure we have uint32_t. */
+#include <sys/types.h>
+#if INN_HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+
+/* SCO OpenServer gets int32_t from here. */
+#if INN_HAVE_SYS_BITYPES_H
+# include <sys/bitypes.h>
+#endif
+
+/* Bytes to process at once, defined by the algorithm. */
+#define MD5_CHUNKSIZE (1 << 6)
+#define MD5_CHUNKWORDS (MD5_CHUNKSIZE / sizeof(uint32_t))
+
+/* Length of the digest, defined by the algorithm. */
+#define MD5_DIGESTSIZE 16
+#define MD5_DIGESTWORDS (MD5_DIGESTSIZE / sizeof(uint32_t))
+
+BEGIN_DECLS
+
+/* Data structure for MD5 message-digest computation. */
+struct md5_context {
+ uint32_t count[2]; /* A 64-bit byte count. */
+ uint32_t buf[MD5_DIGESTWORDS]; /* Scratch buffer. */
+ union {
+ unsigned char byte[MD5_CHUNKSIZE]; /* Byte chunk buffer. */
+ uint32_t word[MD5_CHUNKWORDS]; /* Word chunk buffer. */
+ } in;
+ unsigned int datalen; /* Length of data in in. */
+ unsigned char digest[MD5_DIGESTSIZE]; /* Final digest. */
+};
+
+extern void md5_hash(const unsigned char *, size_t, unsigned char *);
+extern void md5_init(struct md5_context *);
+extern void md5_update(struct md5_context *, const unsigned char *, size_t);
+extern void md5_final(struct md5_context *);
+
+END_DECLS
+
+#endif /* !INN_MD5_H */
diff --git a/include/inn/messages.h b/include/inn/messages.h
new file mode 100644
index 0000000..22297fa
--- /dev/null
+++ b/include/inn/messages.h
@@ -0,0 +1,99 @@
+/* $Id: messages.h 5496 2002-06-07 13:59:06Z alexk $
+**
+** Logging, debugging, and error reporting functions.
+**
+** This collection of functions facilitate logging, debugging, and error
+** reporting in a flexible manner that can be used by libraries as well as by
+** programs. The functions are based around the idea of handlers, which take
+** a message and do something appropriate with it. The program can set the
+** appropriate handlers for all the message reporting functions, and then
+** library code can use them with impunity and know the right thing will
+** happen with the messages.
+*/
+
+#ifndef INN_MESSAGES_H
+#define INN_MESSAGES_H 1
+
+#include <inn/defines.h>
+#include <stdarg.h>
+
+BEGIN_DECLS
+
+/* These are the currently-supported types of traces. */
+enum message_trace {
+ TRACE_NETWORK, /* Network traffic. */
+ TRACE_PROGRAM, /* Stages of program execution. */
+ TRACE_ALL /* All traces; this must be last. */
+};
+
+/* The reporting functions. The ones prefaced by "sys" add a colon, a space,
+ and the results of strerror(errno) to the output and are intended for
+ reporting failures of system calls. */
+extern void trace(enum message_trace, const char *, ...)
+ __attribute__((__format__(printf, 2, 3)));
+extern void notice(const char *, ...)
+ __attribute__((__format__(printf, 1, 2)));
+extern void sysnotice(const char *, ...)
+ __attribute__((__format__(printf, 1, 2)));
+extern void warn(const char *, ...)
+ __attribute__((__format__(printf, 1, 2)));
+extern void syswarn(const char *, ...)
+ __attribute__((__format__(printf, 1, 2)));
+extern void die(const char *, ...)
+ __attribute__((__noreturn__, __format__(printf, 1, 2)));
+extern void sysdie(const char *, ...)
+ __attribute__((__noreturn__, __format__(printf, 1, 2)));
+
+/* Debug is handled specially, since we want to make the code disappear
+ completely unless we're built with -DDEBUG. We can only do that with
+ support for variadic macros, though; otherwise, the function just won't do
+ anything. */
+#if !defined(DEBUG) && (INN_HAVE_C99_VAMACROS || INN_HAVE_GNU_VAMACROS)
+# if INN_HAVE_C99_VAMACROS
+# define debug(format, ...) /* empty */
+# elif INN_HAVE_GNU_VAMACROS
+# define debug(format, args...) /* empty */
+# endif
+#else
+extern void debug(const char *, ...)
+ __attribute__((__format__(printf, 1, 2)));
+#endif
+
+/* Set the handlers for various message functions. All of these functions
+ take a count of the number of handlers and then function pointers for each
+ of those handlers. These functions are not thread-safe; they set global
+ variables. */
+extern void message_handlers_debug(int count, ...);
+extern void message_handlers_trace(int count, ...);
+extern void message_handlers_notice(int count, ...);
+extern void message_handlers_warn(int count, ...);
+extern void message_handlers_die(int count, ...);
+
+/* Enable or disable tracing for particular classes of messages. */
+extern void message_trace_enable(enum message_trace, bool);
+
+/* Some useful handlers, intended to be passed to message_handlers_*. All
+ handlers take the length of the formatted message, the format, a variadic
+ argument list, and the errno setting if any. */
+extern void message_log_stdout(int, const char *, va_list, int);
+extern void message_log_stderr(int, const char *, va_list, int);
+extern void message_log_syslog_debug(int, const char *, va_list, int);
+extern void message_log_syslog_info(int, const char *, va_list, int);
+extern void message_log_syslog_notice(int, const char *, va_list, int);
+extern void message_log_syslog_warning(int, const char *, va_list, int);
+extern void message_log_syslog_err(int, const char *, va_list, int);
+extern void message_log_syslog_crit(int, const char *, va_list, int);
+
+/* The type of a message handler. */
+typedef void (*message_handler_func)(int, const char *, va_list, int);
+
+/* If non-NULL, called before exit and its return value passed to exit. */
+extern int (*message_fatal_cleanup)(void);
+
+/* If non-NULL, prepended (followed by ": ") to all messages printed by either
+ message_log_stdout or message_log_stderr. */
+extern const char *message_program_name;
+
+END_DECLS
+
+#endif /* INN_MESSAGE_H */
diff --git a/include/inn/mmap.h b/include/inn/mmap.h
new file mode 100644
index 0000000..3769d51
--- /dev/null
+++ b/include/inn/mmap.h
@@ -0,0 +1,33 @@
+/* $Id: mmap.h 7598 2007-02-09 02:40:51Z eagle $
+**
+** MMap manipulation routines
+**
+** Written by Alex Kiernan (alex.kiernan@thus.net)
+**
+** These routines work with mmap()ed memory
+*/
+
+#ifndef INN_MMAP_H
+#define INN_MMAP_H 1
+
+#include <inn/defines.h>
+
+BEGIN_DECLS
+
+/* Figure out what page an address is in and flush those pages. This is the
+ internal function, which we wrap with a define below. */
+void inn__mapcntl(void *, size_t, int);
+
+/* Some platforms only support two arguments to msync. On those platforms,
+ make the third argument to mapcntl always be zero, getting rid of whatever
+ the caller tried to pass. This avoids undefined symbols for MS_ASYNC and
+ friends on platforms with two-argument msync functions. */
+#ifdef INN_HAVE_MSYNC_3_ARG
+# define inn_mapcntl inn__mapcntl
+#else
+# define inn_mapcntl(p, l, f) inn__mapcntl((p), (l), 0)
+#endif
+
+END_DECLS
+
+#endif /* INN_MMAP_H */
diff --git a/include/inn/qio.h b/include/inn/qio.h
new file mode 100644
index 0000000..132da6f
--- /dev/null
+++ b/include/inn/qio.h
@@ -0,0 +1,49 @@
+/* $Id: qio.h 3653 2000-07-29 02:57:50Z rra $
+**
+** Quick I/O package.
+**
+** The interface to the Quick I/O package, optimized for reading through
+** files line by line. This package uses internal buffering like stdio,
+** but is even more aggressive about its buffering.
+*/
+
+#ifndef INN_QIO_H
+#define INN_QIO_H 1
+
+#include <inn/defines.h>
+
+BEGIN_DECLS
+
+/*
+** State for a quick open file, equivalent to FILE for stdio. All callers
+** should treat this structure as opaque and instead use the functions and
+** macros defined below.
+*/
+enum QIOflag { QIO_ok, QIO_error, QIO_long };
+
+typedef struct {
+ int _fd;
+ size_t _length; /* Length of the current string. */
+ size_t _size; /* Size of the internal buffer. */
+ char * _buffer;
+ char * _start; /* Start of the unread data. */
+ char * _end; /* End of the available data. */
+ off_t _count; /* Number of bytes read so far. */
+ enum QIOflag _flag;
+} QIOSTATE;
+
+#define QIOerror(qp) ((qp)->_flag != QIO_ok)
+#define QIOtoolong(qp) ((qp)->_flag == QIO_long)
+#define QIOfileno(qp) ((qp)->_fd)
+#define QIOlength(qp) ((qp)->_length)
+#define QIOtell(qp) ((qp)->_count - ((qp)->_end - (qp)->_start))
+
+extern QIOSTATE * QIOopen(const char *name);
+extern QIOSTATE * QIOfdopen(int fd);
+extern char * QIOread(QIOSTATE *qp);
+extern void QIOclose(QIOSTATE *qp);
+extern int QIOrewind(QIOSTATE *qp);
+
+END_DECLS
+
+#endif /* !INN_QIO_H */
diff --git a/include/inn/sequence.h b/include/inn/sequence.h
new file mode 100644
index 0000000..d7bfa33
--- /dev/null
+++ b/include/inn/sequence.h
@@ -0,0 +1,21 @@
+/* $Id: sequence.h 4871 2001-07-09 08:09:58Z alexk $
+**
+** Sequence space arithmetic routines.
+**
+** This is a set of routines for implementing so called sequence
+** space arithmetic (typically used for DNS serial numbers). The
+** implementation here is taken from RFC 1982.
+*/
+
+#ifndef INN_SEQUENCE_H
+#define INN_SEQUENCE_H 1
+
+#include <inn/defines.h>
+
+BEGIN_DECLS
+
+int seq_lcompare(unsigned long, unsigned long);
+
+END_DECLS
+
+#endif /* INN_SEQUENCE_H */
diff --git a/include/inn/timer.h b/include/inn/timer.h
new file mode 100644
index 0000000..0cc611f
--- /dev/null
+++ b/include/inn/timer.h
@@ -0,0 +1,38 @@
+/* $Id: timer.h 6129 2003-01-19 00:39:49Z rra $
+**
+** Timer library interface.
+**
+** An interface to a simple profiling library. An application can declare
+** its intent to use n timers by calling TMRinit(n), and then start and
+** stop numbered timers with TMRstart and TMRstop. TMRsummary logs the
+** results to syslog given labels for each numbered timer.
+*/
+
+#ifndef INN_TIMER_H
+#define INN_TIMER_H
+
+#include <inn/defines.h>
+
+BEGIN_DECLS
+
+enum {
+ TMR_HISHAVE, /* Looking up ID in history (yes/no). */
+ TMR_HISGREP, /* Looking up ID in history (data). */
+ TMR_HISWRITE, /* Writing to history. */
+ TMR_HISSYNC, /* Syncing history to disk. */
+ TMR_APPLICATION /* Application numbering starts here. */
+};
+
+void TMRinit(unsigned int);
+void TMRstart(unsigned int);
+void TMRstop(unsigned int);
+void TMRsummary(const char *prefix, const char *const *labels);
+unsigned long TMRnow(void);
+void TMRfree(void);
+
+/* Return the current time as a double of seconds and fractional sections. */
+double TMRnow_double(void);
+
+END_DECLS
+
+#endif /* INN_TIMER_H */
diff --git a/include/inn/tst.h b/include/inn/tst.h
new file mode 100644
index 0000000..44bfff6
--- /dev/null
+++ b/include/inn/tst.h
@@ -0,0 +1,88 @@
+/* $Id: tst.h 6083 2002-12-27 07:24:36Z rra $
+**
+** Ternary search trie implementation.
+**
+** This implementation is based on the implementation by Peter A. Friend
+** (version 1.3), but has been assimilated into INN and modified to use INN
+** formatting conventions.
+**
+** Copyright (c) 2002, Peter A. Friend
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**
+** Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+**
+** Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+**
+** Neither the name of Peter A. Friend nor the names of its contributors may
+** be used to endorse or promote products derived from this software without
+** specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+** IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+** THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+** PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef INN_TST_H
+#define INN_TST_H 1
+
+#include <inn/defines.h>
+
+BEGIN_DECLS
+
+/* Constants used for return values and options. */
+enum tst_constants {
+ TST_OK,
+ TST_NULL_KEY,
+ TST_NULL_DATA,
+ TST_DUPLICATE_KEY,
+ TST_REPLACE
+};
+
+/* Opaque data type returned by and used by ternary search trie functions. */
+struct tst;
+
+/* Allocate a new ternary search trie. width is the number of nodes allocated
+ at a time and should be chosen carefully. One node is required for every
+ character in the tree. If you choose a value that is too small, your
+ application will spend too much time calling malloc and your node space
+ will be too spread out. Too large a value is just a waste of space. */
+struct tst *tst_init(int width);
+
+/* Insert a value into the tree. If the key already exists in the tree,
+ option determiens the behavior. If set to TST_REPLACE, the data for that
+ key is replaced with the new data value and the old value is returned in
+ exist_ptr. Otherwise, TST_DUPLICATE_KEY is returned. If key is zero
+ length, TST_NULL_KEY is returned. If data is NULL, TST_NULL_DATA is
+ returned. On success, TST_OK is returned.
+
+ The data argument may not be NULL. For a simple existence tree, use the
+ struct tst pointer as the data. */
+int tst_insert(struct tst *, const unsigned char *key, void *data, int option,
+ void **exist_ptr);
+
+/* Search for a key and return the associated data, or NULL if not found. */
+void *tst_search(struct tst *, const unsigned char *key);
+
+/* Delete the given key out of the trie, returning the data that it pointed
+ to. If the key was not found, returns NULL. */
+void *tst_delete(struct tst *, const unsigned char *key);
+
+/* Free the given ternary search trie and all resources it uses. */
+void tst_cleanup(struct tst *);
+
+#endif /* !INN_TST_H */
diff --git a/include/inn/vector.h b/include/inn/vector.h
new file mode 100644
index 0000000..ed63e32
--- /dev/null
+++ b/include/inn/vector.h
@@ -0,0 +1,87 @@
+/* $Id: vector.h 5450 2002-04-23 06:06:10Z rra $
+**
+** Vector handling (counted lists of char *'s).
+**
+** Written by Russ Allbery <rra@stanford.edu>
+** This work is hereby placed in the public domain by its author.
+**
+** A vector is a simple array of char *'s combined with a count. It's a
+** convenient way of managing a list of strings, as well as a reasonable
+** output data structure for functions that split up a string. There are
+** two basic types of vectors, regular vectors (in which case strings are
+** copied when put into a vector and freed when the vector is freed) and
+** cvectors or const vectors (where each pointer is a const char * to some
+** external string that isn't freed when the vector is freed).
+**
+** There are two interfaces here, one for vectors and one for cvectors,
+** with the basic operations being the same between the two.
+*/
+
+#ifndef INN_VECTOR_H
+#define INN_VECTOR_H 1
+
+#include <inn/defines.h>
+
+struct vector {
+ size_t count;
+ size_t allocated;
+ char **strings;
+};
+
+struct cvector {
+ size_t count;
+ size_t allocated;
+ const char **strings;
+};
+
+BEGIN_DECLS
+
+/* Create a new, empty vector. */
+struct vector *vector_new(void);
+struct cvector *cvector_new(void);
+
+/* Add a string to a vector. Resizes the vector if necessary. */
+void vector_add(struct vector *, const char *string);
+void cvector_add(struct cvector *, const char *string);
+
+/* Resize the array of strings to hold size entries. Saves reallocation work
+ in vector_add if it's known in advance how many entries there will be. */
+void vector_resize(struct vector *, size_t size);
+void cvector_resize(struct cvector *, size_t size);
+
+/* Reset the number of elements to zero, freeing all of the strings for a
+ regular vector, but not freeing the strings array (to cut down on memory
+ allocations if the vector will be reused). */
+void vector_clear(struct vector *);
+void cvector_clear(struct cvector *);
+
+/* Free the vector and all resources allocated for it. */
+void vector_free(struct vector *);
+void cvector_free(struct cvector *);
+
+/* Split functions build a vector from a string. vector_split splits on a
+ specified character, while vector_split_space splits on any sequence of
+ spaces or tabs (not any sequence of whitespace, as just spaces or tabs is
+ more useful for INN). The cvector versions destructively modify the
+ provided string in-place to insert nul characters between the strings. If
+ the vector argument is NULL, a new vector is allocated; otherwise, the
+ provided one is reused.
+
+ Empty strings will yield zero-length vectors. Adjacent delimiters are
+ treated as a single delimiter by *_split_space, but *not* by *_split, so
+ callers of *_split should be prepared for zero-length strings in the
+ vector. */
+struct vector *vector_split(const char *string, char sep, struct vector *);
+struct vector *vector_split_space(const char *string, struct vector *);
+struct cvector *cvector_split(char *string, char sep, struct cvector *);
+struct cvector *cvector_split_space(char *string, struct cvector *);
+
+/* Build a string from a vector by joining its components together with the
+ specified string as separator. Returns a newly allocated string; caller is
+ responsible for freeing. */
+char *vector_join(const struct vector *, const char *seperator);
+char *cvector_join(const struct cvector *, const char *separator);
+
+END_DECLS
+
+#endif /* INN_VECTOR_H */
diff --git a/include/inn/wire.h b/include/inn/wire.h
new file mode 100644
index 0000000..bafae0b
--- /dev/null
+++ b/include/inn/wire.h
@@ -0,0 +1,46 @@
+/* $Id: wire.h 6028 2002-12-24 05:10:39Z rra $
+**
+** Wire format article utilities.
+**
+** Originally written by Alex Kiernan (alex.kiernan@thus.net)
+**
+** These routines manipulate wire format articles; in particular, they should
+** be safe in the presence of embedded NULs and UTF-8 characters.
+*/
+
+#ifndef INN_WIRE_H
+#define INN_WIRE_H 1
+
+#include <inn/defines.h>
+
+BEGIN_DECLS
+
+/* Given a pointer to the start of an article, locate the first octet
+ of the body (which may be the octet beyond the end of the buffer if
+ your article is bodyless). */
+char *wire_findbody(const char *, size_t);
+
+/* Given a pointer into an article and a pointer to the end of the article,
+ find the start of the next line or return NULL if there are no more lines
+ remaining in the article. */
+char *wire_nextline(const char *, const char *end);
+
+/* Given a pointer to the start of an article and the name of a header, find
+ the beginning of the value of the given header (the returned pointer will
+ be after the name of the header and any initial whitespace). Headers whose
+ only content is whitespace are ignored. If the header isn't found, returns
+ NULL.
+
+ WARNING: This function does not comply with RFC 2822's idea of header
+ content, particularly in its skipping of initial whitespace. */
+char *wire_findheader(const char *article, size_t, const char *header);
+
+/* Given a pointer inside a header's value and a pointer to the end of the
+ article, returns a pointer to the end of the header value (the \n at the
+ end of the terminating \r\n with folding taken into account), or NULL if no
+ such terminator was found before the end of the article. */
+char *wire_endheader(const char *header, const char *end);
+
+END_DECLS
+
+#endif /* INN_WIRE_H */