17 #define _POSIX_C_SOURCE 200809L 158 const size_t BUFSZ_INCREMENT = 512;
168 size_t bytes_read_loop;
169 if((new_buf =
realloc(read_buf, bufsz + BUFSZ_INCREMENT)) == NULL){
174 bufsz += BUFSZ_INCREMENT;
176 bytes_read_loop = fread(&read_buf[bufsz - BUFSZ_INCREMENT],
181 *bytes_read += bytes_read_loop;
187 }
while(!feof(stream));
202 const char *
const email){
204 size_t new_address_list_sz;
209 new_address_list_sz)) == NULL){
215 strncpy(new_address->
email, email,
sizeof(new_address->
email));
216 new_address->
email[
sizeof(new_address->
email) - 1] =
'\0';
271 const char *
const filename,
272 const char *
const path){
274 size_t new_attachment_list_sz;
276 if(filename == NULL || path == NULL){
277 errx(1,
"must provide attachment with valid name:path");
283 new_attachment_list_sz)) == NULL){
284 err(1,
"realloc: attachment list");
289 strncpy(new_attachment->
name, filename,
sizeof(new_attachment->
name));
290 new_attachment->
name[
sizeof(new_attachment->
name) - 1] =
'\0';
292 strncpy(new_attachment->
path, path,
sizeof(new_attachment->
path));
293 new_attachment->
path[
sizeof(new_attachment->
path) - 1] =
'\0';
304 const char *
const attach_arg){
305 char *attach_arg_dup;
309 if((attach_arg_dup = strdup(attach_arg)) == NULL){
310 err(1,
"strdup: %s", attach_arg);
313 filename = strtok(attach_arg_dup,
":");
314 filepath = strtok(NULL,
":");
318 free(attach_arg_dup);
331 const char *
const option){
339 if((optdup = strdup(option)) == NULL){
340 err(1,
"strdup: option: %s", option);
343 if((opt_key = strtok(optdup,
"=")) == NULL){
344 errx(1,
"strtok: %s", optdup);
347 opt_value = strtok(NULL,
"=");
349 if(strcmp(opt_key,
"smtp-security") == 0){
350 if(strcmp(opt_value,
"none") == 0){
354 else if(strcmp(opt_value,
"tls") == 0){
357 else if(strcmp(opt_value,
"starttls") == 0){
365 else if(strcmp(opt_key,
"smtp-auth") == 0){
366 if(strcmp(opt_value,
"none") == 0){
369 else if(strcmp(opt_value,
"plain") == 0){
372 else if(strcmp(opt_value,
"login") == 0){
376 else if(strcmp(opt_value,
"cram-md5") == 0){
384 else if(strcmp(opt_key,
"smtp-flag") == 0){
385 if(strcmp(opt_value,
"debug") == 0){
388 else if(strcmp(opt_value,
"no-cert-verify") == 0){
395 else if(strcmp(opt_key,
"smtp-server") == 0){
396 if((mailx->
server = strdup(opt_value)) == NULL){
400 else if(strcmp(opt_key,
"smtp-port") == 0){
401 if((mailx->
port = strdup(opt_value)) == NULL){
405 else if(strcmp(opt_key,
"smtp-user") == 0){
406 if((mailx->
user = strdup(opt_value)) == NULL){
410 else if(strcmp(opt_key,
"smtp-pass") == 0){
411 if((mailx->
pass = strdup(opt_value)) == NULL){
415 else if(strcmp(opt_key,
"smtp-from") == 0){
416 if((mailx->
from = strdup(opt_value)) == NULL){
427 errx(1,
"invalid argument: %s", option);
440 memset(mailx, 0,
sizeof(*mailx));
498 int main(
int argc,
char *argv[]){
505 while((rc = getopt(argc, argv,
"a:s:S:")) != -1){
524 errx(1,
"must provide at least one email destination address");
527 if(mailx.
from == NULL){
528 errx(1,
"must provide a FROM address");
532 if((mailx.
server = strdup(
"localhost")) == NULL){
537 if(mailx.
port == NULL){
538 if((mailx.
port = strdup(
"25")) == NULL){
543 puts(
"Reading email body from stdin");
545 err(1,
"failed to read email body from stdin");
550 for(i = 0; i < argc; i++){
enum smtp_status_code smtp_close(struct smtp *smtp)
const char * smtp_status_code_errstr(enum smtp_status_code status_code)
enum smtp_connection_security connection_security
enum smtp_status_code smtp_header_add(struct smtp *const smtp, const char *const key, const char *const value)
enum smtp_authentication_method auth_method
static void mailx_parse_smtp_option(struct mailx *const mailx, const char *const option)
enum smtp_status_code smtp_mail(struct smtp *const smtp, const char *const body)
enum smtp_status_code smtp_attachment_add_path(struct smtp *const smtp, const char *const name, const char *const path)
static void mailx_address_append(struct mailx *const mailx, enum smtp_address_type address_type, const char *const email)
struct mailx_attachment * attachment_list
static void mailx_free(const struct mailx *const mailx)
enum smtp_address_type address_type
static void mailx_init_default_values(struct mailx *const mailx)
smtp_authentication_method
static void mailx_append_attachment_arg(struct mailx *const mailx, const char *const attach_arg)
enum smtp_flag smtp_flags
static void mailx_send(struct mailx *const mailx)
enum smtp_status_code smtp_address_add(struct smtp *const smtp, enum smtp_address_type type, const char *const email, const char *const name)
static char * smtp_ffile_get_contents(FILE *stream, size_t *bytes_read)
static void mailx_append_attachment(struct mailx *const mailx, const char *const filename, const char *const path)
struct mailx_address * address_list
enum smtp_status_code smtp_auth(struct smtp *const smtp, enum smtp_authentication_method auth_method, const char *const user, const char *const pass)
int main(int argc, char *argv[])
enum smtp_status_code smtp_open(const char *const server, const char *const port, enum smtp_connection_security connection_security, enum smtp_flag flags, const char *const cafile, struct smtp **smtp)