mail: Detect terminal input, end of file, better argument parsing.
* If the input is a terminal rather than a file or pipe, only then look for the single period on a line as end of text. Also look for end of file as an end of the text, so that piped in text works. * Parse multiple e-mail addresses properly, adding a comma between them (a space doesn't work). Also allow mixing of "to" e-mail addresses and command line switches, previously all "to" addresses had to be at the end. * Fewer blank lines in the output, make it look nicer, remove things like a redundant display of the body text before text was read. Also no output text when just piping in a message. * Avoid buffer overrun by using fgets instead of gets. * Use stderr for text the user likely doesn't want to save, and for prompts that would be invisible if stdout was redirected to a file. Signed-off-by: Augustin Cavalier <[email protected]>
This commit is contained in:
committed by
Augustin Cavalier
parent
f1b2a12f3b
commit
f765016ffd
+45
-36
@@ -6,17 +6,18 @@
|
|||||||
* Santiago (Jacques) Lema
|
* Santiago (Jacques) Lema
|
||||||
* Jérôme Duval, [email protected]
|
* Jérôme Duval, [email protected]
|
||||||
* Augustin Cavalier, <waddlesplash>
|
* Augustin Cavalier, <waddlesplash>
|
||||||
|
* Alexander G. M. Smith <[email protected]>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <Application.h>
|
|
||||||
#include <String.h>
|
|
||||||
#include <E-mail.h>
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <Application.h>
|
||||||
|
#include <E-mail.h>
|
||||||
|
#include <String.h>
|
||||||
|
|
||||||
#define APP_SIG "application/x-vnd.Haiku-mail_utils-mail"
|
#define APP_SIG "application/x-vnd.Haiku-mail_utils-mail"
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
@@ -28,17 +29,15 @@ int main(int argc, char* argv[])
|
|||||||
fprintf(stdout,"This program can only send mail, not read it.\n");
|
fprintf(stdout,"This program can only send mail, not read it.\n");
|
||||||
fprintf(stdout,"usage: %s [-v] [-s subject] [-c cc-addr] "
|
fprintf(stdout,"usage: %s [-v] [-s subject] [-c cc-addr] "
|
||||||
"[-b bcc-addr] to-addr ...\n", argv[0]);
|
"[-b bcc-addr] to-addr ...\n", argv[0]);
|
||||||
fflush(stdout);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *subject = "No title";
|
char *subject = "No subject";
|
||||||
char *cc = "";
|
char *cc = "";
|
||||||
char *bcc = "";
|
char *bcc = "";
|
||||||
BString to = "";
|
BString to;
|
||||||
BString body = "";
|
bool verbose = false;
|
||||||
|
|
||||||
bool verbose =false;
|
|
||||||
// Parse arguments
|
// Parse arguments
|
||||||
for (int i = 1; i < argc; i++) {
|
for (int i = 1; i < argc; i++) {
|
||||||
if (strcmp(argv[i], "-v") == 0)
|
if (strcmp(argv[i], "-v") == 0)
|
||||||
@@ -53,51 +52,60 @@ int main(int argc, char* argv[])
|
|||||||
bcc = argv[i+1];
|
bcc = argv[i+1];
|
||||||
i++;
|
i++;
|
||||||
} else {
|
} else {
|
||||||
|
if (to.Length() > 0)
|
||||||
|
to.Append(", ");
|
||||||
to.Append(argv[i]);
|
to.Append(argv[i]);
|
||||||
if (i < argc - 1)
|
}
|
||||||
to.Append(" ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
fprintf(stdout, "\n");
|
fprintf(stdout, "\n");
|
||||||
fprintf(stdout, "To:\t<%s> \n", to.String());
|
fprintf(stdout, "To:\t%s\n", to.String());
|
||||||
fprintf(stdout, "Cc:\t<%s> \n", cc);
|
fprintf(stdout, "Cc:\t%s\n", cc);
|
||||||
fprintf(stdout, "Bcc:\t<%s> \n", bcc);
|
fprintf(stdout, "Bcc:\t%s\n", bcc);
|
||||||
fprintf(stdout, "Subj:\t<%s> \n", subject);
|
fprintf(stdout, "Subj:\t%s\n", subject);
|
||||||
fprintf(stdout, "Body:\t<%s> \n", body.String());
|
fprintf(stdout, "\n");
|
||||||
fprintf(stdout, "\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if recipients are valid
|
// Check if recipients are valid
|
||||||
if (strcmp(to.String(), "") == 0 &&
|
if (strcmp(to.String(), "") == 0 &&
|
||||||
strcmp(cc, "") == 0 &&
|
strcmp(cc, "") == 0 &&
|
||||||
strcmp(bcc, "") == 0) {
|
strcmp(bcc, "") == 0) {
|
||||||
|
|
||||||
fprintf(stdout, "[Error]: You must specify at least one recipient "
|
fprintf(stderr, "[Error]: You must specify at least one recipient "
|
||||||
"in to, cc or bcc fields.\n");
|
"in to, cc or bcc fields.\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read each line until we get a single dot "." on a line
|
bool isTerminal = isatty(STDIN_FILENO) != 0;
|
||||||
|
if (isTerminal) {
|
||||||
|
fprintf(stderr, "Now type your message.\n"
|
||||||
|
"Type '.' alone on a line to end your text and send it.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
BString body;
|
||||||
char line[32768] = "";
|
char line[32768] = "";
|
||||||
|
|
||||||
printf("Now type your message.\nType '.' alone on a line to send it.\n");
|
// Read each line and collect the body text until we get an end of text
|
||||||
|
// marker. That's a single dot "." on a line typed in by the user,
|
||||||
|
// or end of file when reading a file.
|
||||||
do {
|
do {
|
||||||
gets(line);
|
if (fgets(line, sizeof(line), stdin) == NULL) {
|
||||||
|
// End of file or an error happened, just send collected body text.
|
||||||
if (strcmp(line, ".") != 0) {
|
break;
|
||||||
body.Append(line).Append("\n");
|
|
||||||
}
|
}
|
||||||
// fprintf(stdout,"Line: %s \n",line);
|
|
||||||
} while (strcmp(line, ".") != 0);
|
|
||||||
|
|
||||||
|
if (isTerminal && strcmp(line, ".\n") == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
body.Append(line);
|
||||||
|
} while (true);
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
fprintf(stdout, "\nBody:\n%s\n", body.String());
|
fprintf(stdout, "\nBody:\n%s\n", body.String());
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
fprintf(stdout, "\nSending E-mail...\n");
|
fprintf(stderr, "Sending E-mail...\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
BMailMessage mail;
|
BMailMessage mail;
|
||||||
@@ -105,14 +113,15 @@ int main(int argc, char* argv[])
|
|||||||
mail.AddHeaderField(B_MAIL_CC, cc);
|
mail.AddHeaderField(B_MAIL_CC, cc);
|
||||||
mail.AddHeaderField(B_MAIL_BCC, bcc);
|
mail.AddHeaderField(B_MAIL_BCC, bcc);
|
||||||
mail.AddHeaderField(B_MAIL_SUBJECT, subject);
|
mail.AddHeaderField(B_MAIL_SUBJECT, subject);
|
||||||
mail.AddContent(body.String(), strlen(body.String()));
|
mail.AddContent(body.String(), body.Length());
|
||||||
status_t result = mail.Send();
|
status_t result = mail.Send();
|
||||||
|
|
||||||
if (result == B_OK) {
|
if (result == B_OK) {
|
||||||
fprintf(stdout, "\nMessage was sent successfully.\n");
|
if (verbose)
|
||||||
|
fprintf(stderr, "Message was sent successfully.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stdout, "Message failed to send: %s", strerror(result));
|
fprintf(stderr, "Message failed to send: %s\n", strerror(result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user