// part:headers(t) static int lcurl_mime_part_headers(lua_State *L){ lcurl_mime_part_t *p = lcurl_getmimepart(L); struct curl_slist *list; CURLcode ret; if(IS_FALSE(L, 2)){ list = NULL; } else{ list = lcurl_util_to_slist(L, 2); luaL_argcheck(L, list || IS_TABLE(L, 2), 2, "array or null expected"); } ret = curl_mime_headers(p->part, list, 1); if(ret != CURLE_OK){ if(list) curl_slist_free_all(list); return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, ret); } lua_settop(L, 1); return 1; }
/*********************************************************************** * * smtp_perform_mail() * * Sends an MAIL command to initiate the upload of a message. */ static CURLcode smtp_perform_mail(struct connectdata *conn) { char *from = NULL; char *auth = NULL; char *size = NULL; CURLcode result = CURLE_OK; struct Curl_easy *data = conn->data; /* Calculate the FROM parameter */ if(!data->set.str[STRING_MAIL_FROM]) /* Null reverse-path, RFC-5321, sect. 3.6.3 */ from = strdup("<>"); else if(data->set.str[STRING_MAIL_FROM][0] == '<') from = aprintf("%s", data->set.str[STRING_MAIL_FROM]); else from = aprintf("<%s>", data->set.str[STRING_MAIL_FROM]); if(!from) return CURLE_OUT_OF_MEMORY; /* Calculate the optional AUTH parameter */ if(data->set.str[STRING_MAIL_AUTH] && conn->proto.smtpc.sasl.authused) { if(data->set.str[STRING_MAIL_AUTH][0] != '\0') auth = aprintf("%s", data->set.str[STRING_MAIL_AUTH]); else /* Empty AUTH, RFC-2554, sect. 5 */ auth = strdup("<>"); if(!auth) { free(from); return CURLE_OUT_OF_MEMORY; } } /* Prepare the mime data if some. */ if(data->set.mimepost.kind != MIMEKIND_NONE) { /* Use the whole structure as data. */ data->set.mimepost.flags &= ~MIME_BODY_ONLY; /* Add external headers and mime version. */ curl_mime_headers(&data->set.mimepost, data->set.headers, 0); result = Curl_mime_prepare_headers(&data->set.mimepost, NULL, NULL, MIMESTRATEGY_MAIL); if(!result) if(!Curl_checkheaders(conn, "Mime-Version")) result = Curl_mime_add_header(&data->set.mimepost.curlheaders, "Mime-Version: 1.0"); /* Make sure we will read the entire mime structure. */ if(!result) result = Curl_mime_rewind(&data->set.mimepost); if(result) { free(from); free(auth); return result; } data->state.infilesize = Curl_mime_size(&data->set.mimepost); /* Read from mime structure. */ data->state.fread_func = (curl_read_callback) Curl_mime_read; data->state.in = (void *) &data->set.mimepost; } /* Calculate the optional SIZE parameter */ if(conn->proto.smtpc.size_supported && data->state.infilesize > 0) { size = aprintf("%" CURL_FORMAT_CURL_OFF_T, data->state.infilesize); if(!size) { free(from); free(auth); return CURLE_OUT_OF_MEMORY; } } /* Send the MAIL command */ if(!auth && !size) result = Curl_pp_sendf(&conn->proto.smtpc.pp, "MAIL FROM:%s", from); else if(auth && !size) result = Curl_pp_sendf(&conn->proto.smtpc.pp, "MAIL FROM:%s AUTH=%s", from, auth); else if(auth && size) result = Curl_pp_sendf(&conn->proto.smtpc.pp, "MAIL FROM:%s AUTH=%s SIZE=%s", from, auth, size); else result = Curl_pp_sendf(&conn->proto.smtpc.pp, "MAIL FROM:%s SIZE=%s", from, size); free(from); free(auth); free(size); if(!result) state(conn, SMTP_MAIL); return result; }
int main(void) { CURL *curl; CURLcode res = CURLE_OK; struct curl_slist *headers = NULL; struct curl_slist *recipients = NULL; struct curl_slist *slist = NULL; curl_mime *mime; curl_mime *alt; curl_mimepart *part; const char **cpp; curl = curl_easy_init(); if(curl) { /* This is the URL for your mailserver */ curl_easy_setopt(curl, CURLOPT_URL, "smtp://mail.example.com"); /* Note that this option isn't strictly required, omitting it will result * in libcurl sending the MAIL FROM command with empty sender data. All * autoresponses should have an empty reverse-path, and should be directed * to the address in the reverse-path which triggered them. Otherwise, * they could cause an endless loop. See RFC 5321 Section 4.5.5 for more * details. */ curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM); /* Add two recipients, in this particular case they correspond to the * To: and Cc: addressees in the header, but they could be any kind of * recipient. */ recipients = curl_slist_append(recipients, TO); recipients = curl_slist_append(recipients, CC); curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients); /* Build and set the message header list. */ for(cpp = headers_text; *cpp; cpp++) headers = curl_slist_append(headers, *cpp); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); /* Build the mime message. */ mime = curl_mime_init(curl); /* The inline part is an alternative proposing the html and the text versions of the e-mail. */ alt = curl_mime_init(curl); /* HTML message. */ part = curl_mime_addpart(alt); curl_mime_data(part, inline_html, CURL_ZERO_TERMINATED); curl_mime_type(part, "text/html"); /* Text message. */ part = curl_mime_addpart(alt); curl_mime_data(part, inline_text, CURL_ZERO_TERMINATED); /* Create the inline part. */ part = curl_mime_addpart(mime); curl_mime_subparts(part, alt); curl_mime_type(part, "multipart/alternative"); slist = curl_slist_append(NULL, "Content-Disposition: inline"); curl_mime_headers(part, slist, 1); /* Add the current source program as an attachment. */ part = curl_mime_addpart(mime); curl_mime_filedata(part, "smtp-mime.c"); curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime); /* Send the message */ res = curl_easy_perform(curl); /* Check for errors */ if(res != CURLE_OK) fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); /* Free lists. */ curl_slist_free_all(recipients); curl_slist_free_all(headers); /* curl won't send the QUIT command until you call cleanup, so you should * be able to re-use this connection for additional messages (setting * CURLOPT_MAIL_FROM and CURLOPT_MAIL_RCPT as required, and calling * curl_easy_perform() again. It may not be a good idea to keep the * connection open for a very long time though (more than a few minutes * may result in the server timing out the connection), and you do want to * clean up in the end. */ curl_easy_cleanup(curl); /* Free multipart message. */ curl_mime_free(mime); } return (int)res; }
static int lcurl_mime_part_assing_ext(lua_State *L, int part, int i){ #define UNSET_VALUE (const char*)-1 const char *mime_type = NULL, *mime_name = NULL, *mime_fname = NULL; int headers = 0; CURLcode ret; lcurl_mime_part_t *p = lcurl_getmimepart_at(L, part); if(IS_TABLE(L, i)) headers = i; else if (IS_OPTSTR(L, i)) { mime_type = IS_FALSE(L, i) ? UNSET_VALUE : lua_tostring(L, i); if(IS_TABLE(L, i+1)) headers = i+1; else if(IS_OPTSTR(L, i+1)){ mime_name = IS_FALSE(L, i+1) ? UNSET_VALUE : lua_tostring(L, i+1); if(IS_TABLE(L, i+2)) headers = i+2; else if(IS_OPTSTR(L, i+2)){ mime_fname = IS_FALSE(L, i+2) ? UNSET_VALUE : lua_tostring(L, i+2); if(IS_TABLE(L, i+3)) headers = i+3; else if(IS_FALSE(L, i+3)){ headers = -1; } } } } if(mime_type){ ret = curl_mime_type(p->part, mime_type == UNSET_VALUE ? NULL : mime_type); if(ret != CURLE_OK){ return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, ret); } } if(mime_name){ ret = curl_mime_name(p->part, mime_name == UNSET_VALUE ? NULL : mime_name); if(ret != CURLE_OK){ return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, ret); } } if(mime_fname){ ret = curl_mime_filename(p->part, mime_fname == UNSET_VALUE ? NULL : mime_fname); if(ret != CURLE_OK){ return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, ret); } } if(headers){ if(-1 == headers){ ret = curl_mime_headers(p->part, NULL, 0); if(ret != CURLE_OK){ return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, ret); } } else return lcurl_mime_part_assing_table(L, part, headers); } return 0; #undef UNSET_VALUE }