📄 rfc822.c
字号:
tm.tm_mon = 1; else if (my_strncasematch ("mar", s)) tm.tm_mon = 2; else if (my_strncasematch ("apr", s)) tm.tm_mon = 3; else if (my_strncasematch ("may", s)) tm.tm_mon = 4; else if (my_strncasematch ("jun", s)) tm.tm_mon = 5; else if (my_strncasematch ("jul", s)) tm.tm_mon = 6; else if (my_strncasematch ("aug", s)) tm.tm_mon = 7; else if (my_strncasematch ("sep", s)) tm.tm_mon = 8; else if (my_strncasematch ("oct", s)) tm.tm_mon = 9; else if (my_strncasematch ("nov", s)) tm.tm_mon = 10; else if (my_strncasematch ("dec", s)) tm.tm_mon = 11; else goto error; while (!isspace (*s)) s++; while (*s && isspace (*s)) s++; if (!isdigit (*s)) goto error; /* Year */ tm.tm_year = atoi (s); if (tm.tm_year < 70) // < 50 according to RFC 2282 tm.tm_year += 100; else if (tm.tm_year >= 1900) tm.tm_year -= 1900; while (isdigit (*s)) s++; while (*s && isspace (*s)) s++; if (!*s) goto error; /* Hour */ tm.tm_hour = atoi (s); if (tm.tm_hour > 23) goto error; while (isdigit (*s)) s++; if (*s != ':') goto error; s++; /* Minute */ tm.tm_min = atoi (s); if (tm.tm_min > 59) goto error; while (isdigit (*s)) s++; /* Second */ if (*s == ':') { s++; tm.tm_sec = atoi (s); if (tm.tm_sec > 59) goto error; while (isdigit (*s)) s++; } else tm.tm_sec = 0; while (*s && isspace (*s)) s++; if (!*s) return mktime (&tm); /* Time Zone */ j = 0; if (*s == '-') j = -1; else if (*s == '+') j = 1; if (j) { s++; if (*s == '0') s++; i = atoi (s); i *= j; } else if (my_strncasematch ("ut", s)) // Universal Time i = 0; else if (my_strncasematch ("gmt", s)) // Greenwich Mean Time i = 0; else if (my_strncasematch ("utc", s)) // N Coordinated Universal Time i = 0; else if (my_strncasematch ("cet", s)) // N Central European Time i = 100; else if (my_strncasematch ("met", s)) // N Middle European Time i = 100; else if (my_strncasematch ("eet", s)) // N Eastern European Time i = 200; else if (my_strncasematch ("jst", s)) // N Japanese Standard Time i = 900; else if (my_strncasematch ("adt", s)) // N Atlantic Daylight Time i = -300; else if (my_strncasematch ("ast", s)) // N Atlantic Standard Time i = -400; else if (my_strncasematch ("edt", s)) // Eastern Daylight Time i = -400; else if (my_strncasematch ("est", s)) // Eastern Standard Time i = -500; else if (my_strncasematch ("cdt", s)) // Central Daylight Time i = -500; else if (my_strncasematch ("cst", s)) // Central Standard Time i = -600; else if (my_strncasematch ("mdt", s)) // Middle Daylight Time i = -600; else if (my_strncasematch ("mst", s)) // Middle Standard Time i = -700; else if (my_strncasematch ("pdt", s)) // Pacific Daylight Time i = -700; else if (my_strncasematch ("pst", s)) // Pacific Standard Time i = -800; else if (my_strncasematch ("ydt", s)) // N i = -800; else if (my_strncasematch ("yst", s)) // N i = -900; else if (my_strncasematch ("hdt", s)) // N i = -900; else if (my_strncasematch ("hst", s)) // N i = -1000; else if (my_strncasematch ("bdt", s)) // N Bering Daylight Time i = -1000; else if (my_strncasematch ("bst", s)) // N Bering Standard Time i = -1100; else if (my_strncasematch ("idt", s)) // N Israeli Daylight Time i = 300; else if (my_strncasematch ("nzst", s)) // N New Zealand Standard Time i = 1200; else { fprintf (stderr, "Warning: Unknown time zone: %s\n", s); return mktime (&tm); } tm.tm_hour += i / 100; tm.tm_min += i % 100; return mktime (&tm); error: fprintf (stderr, "Warning: Error parsing date: %s\n", date_string); return (time_t)-1;}/** * Create a new message. * * @param data message source data * @param length length of data in bytes * @param new_msg not really used now */static struct rfc822 *rfc822_create (char *data, int length, int new_msg) { const char *content_type, *content_transfer_encoding, *date_string; char *body_start; int body_len; struct rfc822 *result; struct line header, *x, *nx; result = my_malloc (sizeof(struct rfc822)); result->hdrs.to = NULL; result->hdrs.cc = NULL; result->hdrs.from = NULL; result->hdrs.subject = NULL; result->hdrs.message_id = NULL; result->hdrs.in_reply_to = NULL; result->hdrs.references = NULL; result->hdrs.from_address = NULL; result->hdrs.from_name = NULL; result->atts.next = result->atts.prev = &result->atts; if (split_and_splice_header (data, &header, &body_start) < 0) { fprintf (stderr, "Warning: Giving up on message with bad header\n"); free (result); return NULL; } /* Extract key headers */ content_type = NULL; content_transfer_encoding = NULL; for (x = header.next; x != &header; x = x->next) if (my_strncasematch ("to:", x->text) && !result->hdrs.to) result->hdrs.to = get_header_value (x->text); else if (my_strncasematch ("cc:", x->text) && !result->hdrs.cc) result->hdrs.cc = get_header_value (x->text); else if (my_strncasematch ("from:", x->text) && !result->hdrs.from) result->hdrs.from = get_header_value (x->text); else if (my_strncasematch ("subject:", x->text) && !result->hdrs.subject) result->hdrs.subject = get_header_value (x->text); else if (my_strncasematch ("content-type:", x->text) && !content_type) content_type = get_header_value (x->text); else if (my_strncasematch ("content-transfer-encoding:", x->text) && !content_transfer_encoding) content_transfer_encoding = get_header_value (x->text); else if (my_strncasematch ("date:", x->text)) { date_string = get_header_value (x->text); result->hdrs.date = parse_rfc822_date (date_string); } else if (my_strncasematch ("message-id:", x->text) && !result->hdrs.message_id) result->hdrs.message_id = get_header_value (x->text); else if (my_strncasematch ("in-reply-to:", x->text) && !result->hdrs.in_reply_to) result->hdrs.in_reply_to = get_header_value (x->text); else if (my_strncasematch ("references:", x->text) && !result->hdrs.references) result->hdrs.references = get_header_value (x->text); /* Process body */ body_len = length - (body_start - data); do_body (body_start, body_len, content_type, content_transfer_encoding, &result->atts); /* Free header memory */ for (x = header.next; x != &header; x = nx) { nx = x->next; free (x); } if (new_msg) result->data = data; else result->data = NULL; result->parts = NULL; return result;}/** * Create a new message. */struct rfc822 *rfc822_new (char *data) { int len; struct rfc822 *r; len = strlen (data); r = rfc822_create (data, len, 1); return r;}/** * Free memory used by message. * * @param msg message to free */voidrfc822_free (struct rfc822 *msg) { struct attachment *a, *na; text_part *tp, *next; for (a = msg->atts.next; a != &msg->atts; a = na) { na = a->next; if (a->ct == CT_MESSAGE_RFC822) rfc822_free (a->data.rfc822); else if (a->data.normal.charset) free (a->data.normal.charset); free (a); } if (msg->hdrs.from_name) free (msg->hdrs.from_name); if (msg->hdrs.from_address) free (msg->hdrs.from_address); if (msg->data) free (msg->data); for (tp = msg->parts; tp; tp = next) { next = tp->next; if (tp->text) free (tp->text); /*if (tp->charset) free (tp->charset);*/ free (tp); } free (msg);}/** * Get 'From:' header of message. */const char *rfc822_get_from (struct rfc822 *msg) { return msg->hdrs.from;}/** * Parse name and address from the 'From:' header. * Handles lines of forms 'Abcd Efgh <abcd@efgh.ij>' and * 'abcd@efgh.ij (Abcd Efgh)'. */static voidmake_from_namadd (struct rfc822 *msg) { const char *p, *q, *s; if (!msg->hdrs.from || msg->hdrs.from_address) return; p = msg->hdrs.from; while (*p && isspace (*p)) p++; if (!p) return; if ((s = strchr (p, '<'))) { // Abcd Efgh <abcd@efgh.ij> q = strchr (s, '>'); if (!q || q - s < 2) { msg->hdrs.from_address = my_strdup (p); return; } msg->hdrs.from_address = my_malloc ((q - s) * sizeof(char)); memcpy (msg->hdrs.from_address, s + 1, (q - s - 1) * sizeof(char)); msg->hdrs.from_address[q - s - 1] = '\0'; s--; while (p < s && isspace (*s)) s--; if (s == p) return; msg->hdrs.from_name = my_malloc ((s - p + 2) * sizeof(char)); memcpy (msg->hdrs.from_name, p, (s - p + 1) * sizeof(char)); msg->hdrs.from_name[s - p + 1] = '\0'; } else if ((s = strchr (p, '('))) { // abcd@efgh.ij (Abcd Efgh) q = strchr (s, ')'); if (!q || q - s < 1) { msg->hdrs.from_address = my_strdup (p); return; } msg->hdrs.from_name = my_malloc ((q - s) * sizeof(char)); memcpy (msg->hdrs.from_name, s + 1, (q - s - 1) * sizeof(char)); msg->hdrs.from_name[q - s - 1] = '\0'; s--; while (p < s && isspace (*s)) s--; if (s == p) return; msg->hdrs.from_address = my_malloc ((s - p + 2) * sizeof(char)); memcpy (msg->hdrs.from_address, p, (s - p + 1) * sizeof(char)); msg->hdrs.from_address[s - p + 1] = '\0'; } else { msg->hdrs.from_address = my_strdup (p); }}/** * Get name part of 'From:' header. */const char *rfc822_get_from_name (struct rfc822 *msg) { if (!msg->hdrs.from_name) make_from_namadd (msg); return msg->hdrs.from_name;}/** * Get address part of 'From:' header. */const char *rfc822_get_from_address (struct rfc822 *msg) { if (!msg->hdrs.from_address) make_from_namadd (msg); return msg->hdrs.from_address;}/** * Get 'To:' header of a message. */const char *rfc822_get_to (struct rfc822 *msg) { return msg->hdrs.to;}/** * Get 'Subject:' header of a message. */const char *rfc822_get_subject (struct rfc822 *msg) { return msg->hdrs.subject;}/** * Get time value from 'Date:' header of a message. */time_trfc822_get_date (struct rfc822 *msg) { return msg->hdrs.date;}/** * Get text parts from a message. */text_part *rfc822_get_parts (struct rfc822 *msg) { struct attachment *a; text_part *tp, *pt, *last_tp; if (msg->parts) return msg->parts; last_tp = NULL; for (a = msg->atts.next; a != &msg->atts; a = a->next) { tp = NULL; pt = NULL; switch (a->ct) { case CT_TEXT_HTML: break; case CT_TEXT_OTHER: break; case CT_TEXT_PLAIN: tp = my_malloc (sizeof(text_part)); tp->next = NULL; tp->text = my_malloc (a->data.normal.len + 1); memcpy (tp->text, a->data.normal.bytes, a->data.normal.len); tp->text[a->data.normal.len] = '\0'; tp->len = a->data.normal.len; tp->charset = a->data.normal.charset; pt = tp; break; case CT_MESSAGE_RFC822: // FIXME /*tp = rfc822_get_parts (a->data.rfc822); for (pt = tp; pt; pt = pt->next) if (!pt->next) break; */ break; case CT_OTHER: break; } if (tp) { if (last_tp) { last_tp->next = tp; last_tp = pt; } else { msg->parts = tp; last_tp = pt; } } } return msg->parts;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -