static void lcurl_mime_part_remove_subparts(lua_State *L, lcurl_mime_part_t *p, int free_it){ lcurl_mime_t *sub = lcurl_mime_part_get_subparts(L, p); if(sub){ assert(LUA_NOREF != p->subpart_ref); /* detach `subpart` mime from current mime part */ /* if set `sub->parent = NULL` then gc for mime will try free curl_mime_free. */ luaL_unref(L, LCURL_LUA_REGISTRY, p->subpart_ref); p->subpart_ref = LUA_NOREF; if(p->part && free_it){ curl_mime_subparts(p->part, NULL); } /* seems curl_mime_subparts(h, NULL) free asubparts. so we have to invalidate all reference to all nested objects (part/mime). NOTE. All resources already feed. So just need set all pointers to NULL and free all Lua resources (like references and storages) */ { lcurl_mime_part_t *ptr; /* reset all parts*/ for(ptr = sub->parts; ptr; ptr=ptr->next){ lcurl_mime_part_remove_subparts(L, p, 0); } lcurl_mime_reset(L, sub); } } }
// part:subparts(mime[, type[, name]][, headers]) static int lcurl_mime_part_subparts(lua_State *L){ lcurl_mime_part_t *p = lcurl_getmimepart(L); lcurl_mime_t *mime = lcurl_getmime_at(L, 2); CURLcode ret; /* we can attach mime to only one part */ if(mime->parent){ return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, CURLE_BAD_FUNCTION_ARGUMENT); } /* if we already have one subpart then libcurl free it so we can not use any references to it */ lcurl_mime_part_remove_subparts(L, p, 1); ret = curl_mime_subparts(p->part, mime->mime); if(ret != CURLE_OK){ return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, ret); } lua_pushvalue(L, 2); p->subpart_ref = luaL_ref(L, LCURL_LUA_REGISTRY); mime->parent = p; if (lua_gettop(L) > 2){ int res = lcurl_mime_part_assing_ext(L, 1, 3); if (res) return res; } lua_settop(L, 1); return 1; }
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; }