41 |
int |
int |
42 |
mail_send (int argc, char **argv) |
mail_send (int argc, char **argv) |
43 |
{ |
{ |
44 |
struct send_environ env; |
compose_env_t env; |
45 |
int status; |
int status; |
46 |
|
|
47 |
env.to = env.cc = env.bcc = env.subj = NULL; |
compose_init (&env); |
|
env.outfiles = NULL; env.nfiles = 0; |
|
48 |
|
|
49 |
if (argc < 2) |
if (argc < 2) |
50 |
env.to = ml_readline ((char *)"To: "); |
compose_header_set (&env, MU_HEADER_TO, ml_readline ((char *)"To: "), |
51 |
|
COMPOSE_REPLACE); |
52 |
else |
else |
53 |
{ |
{ |
54 |
while (--argc) |
while (--argc) |
66 |
} |
} |
67 |
else |
else |
68 |
{ |
{ |
69 |
if (env.to) |
compose_header_set (&env, MU_HEADER_TO, p, |
70 |
util_strcat(&env.to, ","); |
COMPOSE_SINGLE_LINE); |
|
util_strcat(&env.to, p); |
|
71 |
free (p); |
free (p); |
72 |
} |
} |
73 |
} |
} |
74 |
} |
} |
75 |
|
|
76 |
if (util_getenv (NULL, "askcc", Mail_env_boolean, 0) == 0) |
if (util_getenv (NULL, "askcc", Mail_env_boolean, 0) == 0) |
77 |
env.cc = ml_readline ((char *)"Cc: "); |
compose_header_set (&env, MU_HEADER_CC, |
78 |
|
ml_readline ((char *)"Cc: "), |
79 |
|
COMPOSE_REPLACE); |
80 |
if (util_getenv (NULL, "askbcc", Mail_env_boolean, 0) == 0) |
if (util_getenv (NULL, "askbcc", Mail_env_boolean, 0) == 0) |
81 |
env.bcc = ml_readline ((char *)"Bcc: "); |
compose_header_set (&env, MU_HEADER_BCC, |
82 |
|
ml_readline ((char *)"Bcc: "), |
83 |
|
COMPOSE_REPLACE); |
84 |
|
|
85 |
if (util_getenv (NULL, "asksub", Mail_env_boolean, 0) == 0) |
if (util_getenv (NULL, "asksub", Mail_env_boolean, 0) == 0) |
86 |
env.subj = ml_readline ((char *)"Subject: "); |
compose_header_set (&env, MU_HEADER_SUBJECT, |
87 |
|
ml_readline ((char *)"Subject: "), |
88 |
|
COMPOSE_REPLACE); |
89 |
else |
else |
90 |
{ |
{ |
91 |
env.subj = NULL; |
char *p; |
92 |
util_getenv (&env.subj, "subject", Mail_env_string, 0); |
if (util_getenv (&p, "subject", Mail_env_string, 0) == 0) |
93 |
|
compose_header_set (&env, MU_HEADER_SUBJECT, |
94 |
|
p, |
95 |
|
COMPOSE_REPLACE); |
96 |
} |
} |
97 |
|
|
98 |
status = mail_send0 (&env, isupper(argv[0][0])); |
status = mail_send0 (&env, isupper(argv[0][0])); |
99 |
free_env_headers (&env); |
compose_destroy (&env); |
100 |
return status; |
return status; |
101 |
} |
} |
102 |
|
|
103 |
|
void |
104 |
|
compose_init (compose_env_t *env) |
105 |
|
{ |
106 |
|
memset (env, 0, sizeof (*env)); |
107 |
|
} |
108 |
|
|
109 |
|
int |
110 |
|
compose_header_set (compose_env_t *env, char *name, char *value, |
111 |
|
int mode) |
112 |
|
{ |
113 |
|
int status; |
114 |
|
char *old_value; |
115 |
|
|
116 |
|
if (!env->header |
117 |
|
&& (status = header_create (&env->header, NULL, 0, NULL)) != 0) |
118 |
|
{ |
119 |
|
util_error ("can't create header: %s", mu_errstring (status)); |
120 |
|
return status; |
121 |
|
} |
122 |
|
|
123 |
|
switch (mode) |
124 |
|
{ |
125 |
|
case COMPOSE_REPLACE: |
126 |
|
case COMPOSE_APPEND: |
127 |
|
status = header_set_value (env->header, name, value, mode); |
128 |
|
break; |
129 |
|
|
130 |
|
case COMPOSE_SINGLE_LINE: |
131 |
|
if (header_aget_value (env->header, name, &old_value) == 0 |
132 |
|
&& old_value[0]) |
133 |
|
{ |
134 |
|
char *new_value = NULL; |
135 |
|
|
136 |
|
asprintf (&new_value, "%s,%s", old_value, value); |
137 |
|
status = header_set_value (env->header, name, new_value, 1); |
138 |
|
free (new_value); |
139 |
|
} |
140 |
|
else |
141 |
|
status = header_set_value (env->header, name, value, 1); |
142 |
|
} |
143 |
|
|
144 |
|
return status; |
145 |
|
} |
146 |
|
|
147 |
|
char * |
148 |
|
compose_header_get (compose_env_t *env, char *name, char *defval) |
149 |
|
{ |
150 |
|
char *p; |
151 |
|
|
152 |
|
if (header_aget_value (env->header, name, &p)) |
153 |
|
p = defval; |
154 |
|
return p; |
155 |
|
} |
156 |
|
|
157 |
void |
void |
158 |
free_env_headers (struct send_environ *env) |
compose_destroy (compose_env_t *env) |
159 |
{ |
{ |
160 |
if (env->to) |
header_destroy (&env->header, NULL); |
|
free (env->to); |
|
|
if (env->cc) |
|
|
free (env->cc); |
|
|
if (env->bcc) |
|
|
free (env->bcc); |
|
|
if (env->subj) |
|
|
free (env->subj); |
|
161 |
if (env->outfiles) |
if (env->outfiles) |
162 |
{ |
{ |
163 |
int i; |
int i; |
184 |
*/ |
*/ |
185 |
|
|
186 |
int |
int |
187 |
mail_send0 (struct send_environ *env, int save_to) |
mail_send0 (compose_env_t *env, int save_to) |
188 |
{ |
{ |
189 |
int done = 0; |
int done = 0; |
190 |
int fd; |
int fd; |
276 |
entry = util_find_entry (mail_escape_table, argv[0]); |
entry = util_find_entry (mail_escape_table, argv[0]); |
277 |
|
|
278 |
if (entry.escfunc) |
if (entry.escfunc) |
279 |
{ |
status = (*entry.escfunc)(argc, argv, env); |
|
status = (*entry.escfunc)(argc, argv, env); |
|
|
} |
|
280 |
else |
else |
281 |
util_error ("Unknown escape %s", argv[0]); |
util_error ("Unknown escape %s", argv[0]); |
282 |
} |
} |
295 |
free (buf); |
free (buf); |
296 |
} |
} |
297 |
|
|
298 |
/* If interrupted dumpt the file to dead.letter. */ |
/* If interrupted dump the file to dead.letter. */ |
299 |
if (int_cnt) |
if (int_cnt) |
300 |
{ |
{ |
301 |
if (util_getenv (NULL, "save", Mail_env_boolean, 0) == 0) |
if (util_getenv (NULL, "save", Mail_env_boolean, 0) == 0) |
328 |
return 1; |
return 1; |
329 |
} |
} |
330 |
|
|
331 |
fclose (env->file); /*FIXME: freopen would be better*/ |
fclose (env->file); /* FIXME: freopen would be better */ |
332 |
|
|
333 |
file = fopen (filename, "r"); |
file = fopen (filename, "r"); |
334 |
if (file != NULL) |
if (file != NULL) |
335 |
{ |
{ |
336 |
mailer_t mailer; |
mailer_t mailer; |
337 |
message_t msg = NULL; |
message_t msg = NULL; |
338 |
|
|
339 |
message_create (&msg, NULL); |
message_create (&msg, NULL); |
340 |
|
|
341 |
/* Fill the header. */ |
/* Fill the header */ |
342 |
{ |
header_set_value (env->header, "X-Mailer", argp_program_version, 1); |
343 |
header_t header = NULL; |
message_set_header (msg, env->header, NULL); |
|
message_get_header (msg, &header); |
|
|
if (env->to && *env->to != '\0') |
|
|
header_set_value (header, MU_HEADER_TO, strdup (env->to), 0); |
|
|
if (env->cc && *env->cc != '\0') |
|
|
header_set_value (header, MU_HEADER_CC, strdup (env->cc), 0); |
|
|
if (env->bcc && *env->bcc != '\0') |
|
|
header_set_value (header, MU_HEADER_BCC , strdup (env->bcc), 0); |
|
|
if (env->subj && *env->subj != '\0') |
|
|
header_set_value (header, MU_HEADER_SUBJECT, strdup (env->subj), 1); |
|
|
header_set_value (header, "X-Mailer", strdup(argp_program_version), 1); |
|
|
} |
|
344 |
|
|
345 |
/* Fill the body. */ |
/* Fill the body. */ |
346 |
{ |
{ |
369 |
/* Save outgoing message */ |
/* Save outgoing message */ |
370 |
if (save_to) |
if (save_to) |
371 |
{ |
{ |
372 |
savefile = strdup (env->to); |
savefile = compose_header_get (env, MU_HEADER_TO, NULL); |
373 |
if (savefile) |
if (savefile) |
374 |
{ |
{ |
375 |
char *p = strchr (savefile, '@'); |
char *p = strchr (savefile, '@'); |
414 |
} |
} |
415 |
|
|
416 |
/* Do we need to Send the message on the wire? */ |
/* Do we need to Send the message on the wire? */ |
417 |
if ((env->to && *env->to != '\0') |
if (compose_header_get (env, "to", NULL) |
418 |
|| (env->cc && *env->cc != '\0') |
|| compose_header_get (env, "cc", NULL) |
419 |
|| (env->bcc && *env->bcc != '\0')) |
|| compose_header_get (env, "bcc", NULL)) |
420 |
{ |
{ |
421 |
char *sendmail; |
char *sendmail; |
422 |
if (util_getenv (&sendmail, "sendmail", Mail_env_string, 0) == 0) |
if (util_getenv (&sendmail, "sendmail", Mail_env_string, 0) == 0) |