/* known header field types */ enum { HEADER_FROM = 0, HEADER_REPLY_TO, HEADER_TO, HEADER_CC, HEADER_BCC, HEADER_SUBJECT, HEADER_DATE, HEADER_MESSAGE_ID, HEADER_UNKNOWN }; static GList * local_message_get_header(GMimeMessage *message, const char *field) { struct raw_header *h; GList * gret = NULL; if (field == NULL) return NULL; h = GMIME_OBJECT(message)->headers->headers; while (h) { if (h->value && !g_strncasecmp(field, h->name, strlen(field))) { gret = g_list_prepend(gret, g_strdup(h->value)); if (gmime_debug) warn("Looking for %s => %s\n", field, h->value); } h = h->next; } return gret; } /** * g_mime_message_set_date_from_string: Set the message sent-date * @message: MIME Message * @string: A string of date * * Set the sent-date on a MIME Message. **/ static void local_mime_message_set_date_from_string (GMimeMessage *message, const gchar *string) { time_t date; int offset = 0; date = g_mime_utils_header_decode_date (string, &offset); g_mime_message_set_date (message, date, offset); } /* different declarations for different types of set and get functions */ typedef const char *(*GetFunc) (GMimeMessage *message); typedef InternetAddressList *(*GetRcptFunc) (GMimeMessage *message, const char *type ); typedef GList *(*GetListFunc) (GMimeMessage *message, const char *type ); typedef void (*SetFunc) (GMimeMessage *message, const char *value); typedef void (*SetListFunc) (GMimeMessage *message, const char *field, const char *value); /** different types of functions * * FUNC_CHARPTR * - function with no arguments * - get returns char* * * FUNC_IA (from Internet Address) * - function with additional "field" argument from the fieldfunc table, * - get returns Glist* * * FUNC_LIST * - function with additional "field" argument (given arbitrary header field name) * - get returns Glist* **/ enum { FUNC_CHARPTR = 0, FUNC_CHARFREEPTR, FUNC_IA, FUNC_LIST }; /** * fieldfunc struct: structure of MIME fields and corresponding get and set * functions. **/ static struct { char * name; GetFunc func; GetRcptFunc rcptfunc; GetListFunc getlistfunc; SetFunc setfunc; SetListFunc setlfunc; gint functype; } fieldfunc[] = { { "From", g_mime_message_get_sender, NULL, NULL, g_mime_message_set_sender, NULL, FUNC_CHARPTR }, { "Reply-To", g_mime_message_get_reply_to, NULL, NULL, g_mime_message_set_reply_to, NULL, FUNC_CHARPTR }, { "To", NULL, g_mime_message_get_recipients, NULL, NULL, g_mime_message_add_recipients_from_string, FUNC_IA }, { "Cc", NULL, g_mime_message_get_recipients, NULL, NULL, g_mime_message_add_recipients_from_string, FUNC_IA }, { "Bcc", NULL, g_mime_message_get_recipients, NULL, NULL, g_mime_message_add_recipients_from_string, FUNC_IA }, { "Subject", g_mime_message_get_subject, NULL, NULL, g_mime_message_set_subject, NULL, FUNC_CHARPTR }, { "Date", g_mime_message_get_date_string, NULL, NULL, local_mime_message_set_date_from_string, NULL, FUNC_CHARFREEPTR }, { "Message-Id",g_mime_message_get_message_id, NULL, NULL, g_mime_message_set_message_id, NULL, FUNC_CHARPTR }, { NULL, NULL, NULL, local_message_get_header, NULL, g_mime_message_add_header, FUNC_LIST } }; /** * message_set_header: set header of any type excluding special (Content- and MIME-Version:) **/ static void message_set_header(GMimeMessage *message, const char *field, const char *value) { gint i; if (gmime_debug) warn("message_set_header(msg=0x%x, '%s' => '%s')\n", message, field, value); if (!g_strcasecmp (field, "MIME-Version:") || !g_strncasecmp (field, "Content-", 8)) { warn ("Could not set special header: \"%s\"", field); return; } for (i=0; i<=HEADER_UNKNOWN; ++i) { if (!fieldfunc[i].name || !g_strncasecmp(field, fieldfunc[i].name, strlen(fieldfunc[i].name))) { switch (fieldfunc[i].functype) { case FUNC_CHARPTR: (*(fieldfunc[i].setfunc))(message, value); break; case FUNC_IA: (*(fieldfunc[i].setlfunc))(message, fieldfunc[i].name, value); break; case FUNC_LIST: (*(fieldfunc[i].setlfunc))(message, field, value); break; default: break; } break; } } } /** * message_get_header: returns the list of 'any header' values * (except of unsupported yet Content- and MIME-Version special headers) * * You should free the GList list by yourself. **/ static GList * message_get_header(GMimeMessage *message, const char *field) { gint i; char * ret = NULL; GList * gret = NULL; for (i=0; i<=HEADER_UNKNOWN; ++i) { if (!fieldfunc[i].name || !g_strncasecmp(field, fieldfunc[i].name, strlen(fieldfunc[i].name))) { if (gmime_debug) warn("message_get_header(%s) = %d", field, fieldfunc[i].functype); switch (fieldfunc[i].functype) { case FUNC_CHARFREEPTR: ret = (char *)(*(fieldfunc[i].func))(message); break; case FUNC_CHARPTR: ret = (char *)(*(fieldfunc[i].func))(message); break; case FUNC_IA: { InternetAddressList *ia_list = NULL, *ia; ia_list = (*(fieldfunc[i].rcptfunc))(message, field); gret = g_list_alloc(); ia = ia_list; while (ia && ia->address) { char *ia_string; ia_string = internet_address_to_string((InternetAddress *)ia->address, FALSE); gret = g_list_append(gret, ia_string); ia = ia->next; } } break; case FUNC_LIST: gret = (*(fieldfunc[i].getlistfunc))(message, field); break; default: break; } break; } } if (gmime_debug) warn("message_get_header(%s) = 0x%x/%s ret=%s", field, gret, gret ? (char *)(gret->data) : "", ret); if (gret == NULL && ret != NULL) gret = g_list_prepend(gret, g_strdup(ret)); if (fieldfunc[i].functype == FUNC_CHARFREEPTR && ret) g_free(ret); return gret; }