summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'net-mail/ezmlm-idx/files/get_header.c')
-rw-r--r--net-mail/ezmlm-idx/files/get_header.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/net-mail/ezmlm-idx/files/get_header.c b/net-mail/ezmlm-idx/files/get_header.c
new file mode 100644
index 000000000000..38b0bf3fd427
--- /dev/null
+++ b/net-mail/ezmlm-idx/files/get_header.c
@@ -0,0 +1,113 @@
+#include "substdio.h"
+#include "seek.h"
+#include "get_header.h"
+#include "stralloc.h"
+#include "errtxt.h"
+#include "strerr.h"
+
+#define FATAL "get_header: fatal: "
+
+static stralloc line = {0};
+
+static void die_nomem()
+{
+ strerr_die2x(111,FATAL,ERR_NOMEM);
+}
+
+/**
+ * This function assumes that input is at the begining of the file;
+ * and it returns input to that state when the function has completed.
+ * The return is 0 if the header was not found, and 1 otherwise. If
+ * found, the header will be stored in the value stralloc struct.
+ */
+int get_header(input, name, value)
+substdio *input;
+char *name;
+stralloc *value;
+{
+ int match = 0;
+ int found_start = 0;
+ unsigned int len;
+ char *cp;
+
+ for (;;) {
+ if (getln(input, &line, &match, '\n') == -1)
+ strerr_die2sys(111, FATAL,ERR_READ_INPUT);
+ if (!match) break;
+ if (line.len == 1) break;
+ cp = line.s ; len = line.len;
+ if (found_start) {
+ if ((*cp == ' ' || *cp == '\t')) {
+ if (!stralloc_catb(value, cp, len - 1)) die_nomem();
+ } else {
+ break;
+ }
+ } else {
+ if (case_startb(cp,len,"from:")) {
+ if (!stralloc_copyb(value, cp, len - 1)) die_nomem();
+ found_start = 1;
+ }
+ }
+ }
+
+ if (seek_begin(input->fd) == -1)
+ strerr_die2sys(111,FATAL,ERR_SEEK_INPUT);
+
+ return found_start;
+}
+
+/**
+ * This function makes the same assumptions about input as get_header :
+ * it should be at the begining of the file, and once done, seek will
+ * be used to return it there. The return value is an e-mail address if
+ * one can be found, or null otherwise. No attempt is made to validate
+ * the email address, and the work done for parsing it is relatively
+ * simplistic; it will handle the following forms as shown:
+ *
+ * username@domain => username@domain
+ * "Name <username@domain>" => username@domain
+ * username1@domain, username2@domain => username1@domain
+ * username1@domain, "Name <username2@domain>" => username2@domain
+ *
+ * If junk is present in the From: header, this will return that. This
+ * function may not be appropriate if a valid e-mail address is required.
+ */
+char *get_from(input)
+substdio *input;
+{
+ stralloc from_header = {0};
+ int from_complete = 0, i;
+ char *from_addr = (char *) 0;
+
+ if (!get_header(input, "from:", &from_header))
+ return (char *) 0;
+
+ /* issub uses a char *, and stralloc structures aren't null
+ * terminated -- they're ... 'Z' terminated ...
+ * but the stuff in from_header is a copy anyway ... we'll modify it so
+ * we don't have to do strcpy or somesuch.
+ */
+ for (i = strlen("from:") ; i < from_header.len ; ++i) {
+ if (*(from_header.s + i) == '<') {
+ from_addr = from_header.s + (i + 1);
+ } else if (from_addr && *(from_header.s + i) == '>') {
+ from_complete = 1;
+ *(from_header.s+i) = '\0'; /* null terminate so from_addr is valid */
+ break;
+ }
+ }
+ if (!from_complete) { /* <...> not found ... assume a simpler format */
+ for(i = strlen("from:") ; i < from_header.len ; ++i) {
+ if (!from_addr && *(from_header.s + i) != ' ') {
+ from_addr = from_header.s + i;
+ } else if (from_addr && isspace(*(from_header.s + i)) ||
+ *(from_header.s + i) == ',') {
+ break;
+ }
+ }
+ *(from_header.s + i) = '\0'; /* this is safe even if i == from_header.len */
+ /* because strallocs have an extra char */
+ }
+ return from_addr;
+}
+