mirror of
https://github.com/bobbimanners/emailler.git
synced 2024-11-18 21:07:03 +00:00
EMAIL: Allow attachment filename / path to be manually overriden when saving
This commit is contained in:
parent
e0d1bdac82
commit
9d1364f83b
97
apps/email.c
97
apps/email.c
@ -756,24 +756,45 @@ uint8_t word_wrap_line(FILE *fp, char **s, uint8_t cols, char mode) {
|
|||||||
return (*s ? 1 : 0); // Caller should invoke again
|
return (*s ? 1 : 0); // Caller should invoke again
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t prompt_for_name(char *, uint8_t); // Forward declaration
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OK to d/l attachment?
|
* OK to d/l attachment?
|
||||||
*/
|
*/
|
||||||
char prompt_okay_attachment(char *filename) {
|
char prompt_okay_attachment(char *filename) {
|
||||||
char c;
|
char c;
|
||||||
printf("Okay to download %s? (y/n) >", filename);
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
printf("ProDOS filename: %s\n", filename);
|
||||||
|
printf("%c A)ccept | S)kip | R)ename%c\n", INVERSE, NORMAL);
|
||||||
c = cgetc();
|
c = cgetc();
|
||||||
if ((c == 'y') || (c == 'Y') || (c == 'n') || (c == 'N'))
|
switch (c) {
|
||||||
|
case 'A':
|
||||||
|
case 'a':
|
||||||
|
return 1;
|
||||||
break;
|
break;
|
||||||
putchar(BELL);
|
case 'S':
|
||||||
|
case 's':
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
case 'r':
|
||||||
|
c = wherey();
|
||||||
|
if (prompt_for_name("Save As", 2) == 255) {
|
||||||
|
gotoxy(0, c);
|
||||||
|
break; // ESC pressed
|
||||||
|
}
|
||||||
|
if (strlen(userentry) > 0) {
|
||||||
|
if (userentry[0] == '/')
|
||||||
|
strcpy(filename, userentry);
|
||||||
|
else
|
||||||
|
snprintf(filename, 80, "%s/ATTACHMENTS/%s", cfg_emaildir, userentry);
|
||||||
|
}
|
||||||
|
gotoxy(0, c);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
putchar(BELL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
putchar(RETURN); // Go to col 0
|
|
||||||
putchar(CURUP);
|
|
||||||
putchar(CLRLINE);
|
|
||||||
if ((c == 'y') || (c == 'Y'))
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -792,6 +813,10 @@ void sanitize_filename(char *s) {
|
|||||||
}
|
}
|
||||||
if (isalnum(c) || c == '.' || c == '/')
|
if (isalnum(c) || c == '.' || c == '/')
|
||||||
s[j++] = c;
|
s[j++] = c;
|
||||||
|
if (j == 15) {
|
||||||
|
s[j] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -890,8 +915,9 @@ void email_pager(struct emailhdrs *h) {
|
|||||||
FILE *sbackfp = NULL;
|
FILE *sbackfp = NULL;
|
||||||
const int8_t *b = b64dec - 43;
|
const int8_t *b = b64dec - 43;
|
||||||
FILE *attachfp;
|
FILE *attachfp;
|
||||||
uint16_t linecount, chars;
|
uint16_t linecount, chars, skipbytes;
|
||||||
uint8_t mime_enc, mime_binary, mime_hasfile, eof, screennum, maxscreennum;
|
uint8_t mime_enc, mime_binary, mime_hasfile, eof,
|
||||||
|
screennum, maxscreennum, attnum;
|
||||||
char c, *readp, *writep;
|
char c, *readp, *writep;
|
||||||
clrscr2();
|
clrscr2();
|
||||||
snprintf(filename, 80, "%s/%s/EMAIL.%u", cfg_emaildir, curr_mbox, h->emailnum);
|
snprintf(filename, 80, "%s/%s/EMAIL.%u", cfg_emaildir, curr_mbox, h->emailnum);
|
||||||
@ -913,6 +939,7 @@ restart:
|
|||||||
mime_enc = ENC_7BIT;
|
mime_enc = ENC_7BIT;
|
||||||
mime_binary = 0;
|
mime_binary = 0;
|
||||||
mime_hasfile = 0;
|
mime_hasfile = 0;
|
||||||
|
attnum = 0;
|
||||||
if (sbackfp)
|
if (sbackfp)
|
||||||
fclose(sbackfp);
|
fclose(sbackfp);
|
||||||
_filetype = PRODOS_T_BIN;
|
_filetype = PRODOS_T_BIN;
|
||||||
@ -938,6 +965,13 @@ restart:
|
|||||||
fputs("\nSubject: ", stdout);
|
fputs("\nSubject: ", stdout);
|
||||||
printfield(h->subject, 0, 70);
|
printfield(h->subject, 0, 70);
|
||||||
fputs("\n\n", stdout);
|
fputs("\n\n", stdout);
|
||||||
|
|
||||||
|
// We do not need all the email headers for the summary screen right now.
|
||||||
|
// Freeing them can release up to nearly 8KB. The caller rebuilds the
|
||||||
|
// summary info by calling read_email_db().
|
||||||
|
skipbytes = h->skipbytes;
|
||||||
|
free_headers_list();
|
||||||
|
|
||||||
get_line(fp, 1, linebuf, &pos); // Reset buffer
|
get_line(fp, 1, linebuf, &pos); // Reset buffer
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!readp)
|
if (!readp)
|
||||||
@ -987,21 +1021,29 @@ restart:
|
|||||||
}
|
}
|
||||||
} else if (strstr(writep, "filename=")) {
|
} else if (strstr(writep, "filename=")) {
|
||||||
mime_hasfile = 1;
|
mime_hasfile = 1;
|
||||||
snprintf(filename, 80, "%s/ATTACHMENTS/%s",
|
snprintf(filename, 80, "%s", strstr(writep, "filename=") + 9);
|
||||||
cfg_emaildir, strstr(writep, "filename=") + 9);
|
printf("%cAttachment %u %c\n",
|
||||||
|
INVERSE, ++attnum, NORMAL);
|
||||||
|
printf(" MIME filename: %s", filename);
|
||||||
sanitize_filename(filename);
|
sanitize_filename(filename);
|
||||||
|
snprintf(userentry, 80, "%s/ATTACHMENTS/%s",
|
||||||
|
cfg_emaildir, filename);
|
||||||
|
strcpy(filename, userentry);
|
||||||
|
prompt_dl:
|
||||||
if (prompt_okay_attachment(filename)) {
|
if (prompt_okay_attachment(filename)) {
|
||||||
printf("** Attachment -> %s ", filename);
|
printf("*** Attachment -> %s ", filename);
|
||||||
attachfp = fopen(filename, "wb");
|
attachfp = fopen(filename, "wb");
|
||||||
if (!attachfp)
|
if (!attachfp) {
|
||||||
printf("\n** Can't open %s ", filename);
|
printf("\n*** Can't open %s %d\n", filename, errno);
|
||||||
|
goto prompt_dl;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
attachfp = NULL;
|
attachfp = NULL;
|
||||||
} else if ((mime == 3) && (!strncmp(writep, "\r", 1))) {
|
} else if ((mime == 3) && (!strncmp(writep, "\r", 1))) {
|
||||||
mime = 4;
|
mime = 4;
|
||||||
if (!attachfp && mime_hasfile) {
|
if (!attachfp && mime_hasfile) {
|
||||||
mime_enc = ENC_SKIP; // Skip over MIME parts user chose to skip
|
mime_enc = ENC_SKIP; // Skip over MIME parts user chose to skip
|
||||||
printf("** Skipping %s ", filename);
|
printf("*** Skipping %s ", filename);
|
||||||
} else if (!attachfp && mime_binary) {
|
} else if (!attachfp && mime_binary) {
|
||||||
mime_enc = ENC_SKIP; // Skip over binary MIME parts with no filename
|
mime_enc = ENC_SKIP; // Skip over binary MIME parts with no filename
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@ -1060,7 +1102,7 @@ restart:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
endscreen:
|
endscreen:
|
||||||
if ((*cursorrow == 22) || eof) {
|
if (!mime_hasfile && ((*cursorrow == 22) || eof)) {
|
||||||
printf("\n%c[%07lu] %s | B)ack | T)op | H)drs | M)IME | Q)uit%c",
|
printf("\n%c[%07lu] %s | B)ack | T)op | H)drs | M)IME | Q)uit%c",
|
||||||
INVERSE,
|
INVERSE,
|
||||||
pos,
|
pos,
|
||||||
@ -1098,7 +1140,7 @@ retry:
|
|||||||
case 'T':
|
case 'T':
|
||||||
case 't':
|
case 't':
|
||||||
mime = 0;
|
mime = 0;
|
||||||
pos = h->skipbytes;
|
pos = skipbytes;
|
||||||
fseek(fp, pos, SEEK_SET);
|
fseek(fp, pos, SEEK_SET);
|
||||||
goto restart;
|
goto restart;
|
||||||
break;
|
break;
|
||||||
@ -1132,7 +1174,7 @@ retry:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (linebuf[0] != '\r');
|
} while (linebuf[0] != '\r');
|
||||||
pos = h->skipbytes;
|
pos = skipbytes;
|
||||||
fseek(fp, pos, SEEK_SET);
|
fseek(fp, pos, SEEK_SET);
|
||||||
goto restart;
|
goto restart;
|
||||||
case 'Q':
|
case 'Q':
|
||||||
@ -1369,6 +1411,7 @@ uint8_t parse_from_addr(char *p, char *q) {
|
|||||||
* Returns number of chars read.
|
* Returns number of chars read.
|
||||||
* prompt - Message to display before > prompt
|
* prompt - Message to display before > prompt
|
||||||
* is_file - if 1, restrict chars to those allowed in ProDOS filename
|
* is_file - if 1, restrict chars to those allowed in ProDOS filename
|
||||||
|
* if 2, restrict chars to those allowed in ProDOS path
|
||||||
* Returns number of chars read, or 255 if ESC pressed
|
* Returns number of chars read, or 255 if ESC pressed
|
||||||
*/
|
*/
|
||||||
uint8_t prompt_for_name(char *prompt, uint8_t is_file) {
|
uint8_t prompt_for_name(char *prompt, uint8_t is_file) {
|
||||||
@ -1379,8 +1422,12 @@ uint8_t prompt_for_name(char *prompt, uint8_t is_file) {
|
|||||||
i = 0;
|
i = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
c = cgetc();
|
c = cgetc();
|
||||||
if (is_file && !isalnum(c) && (c != RETURN) && (c != BACKSPACE) &&
|
if ((is_file > 0) && !isalnum(c) && (c != RETURN) && (c != BACKSPACE) &&
|
||||||
(c != DELETE) && (c != ESC) && (c != '.')) {
|
(c != DELETE) && (c != ESC) && (c != '.') && (c != '/')) {
|
||||||
|
putchar(BELL);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((is_file == 1) && (c == '/')) {
|
||||||
putchar(BELL);
|
putchar(BELL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1962,6 +2009,7 @@ void keyboard_hdlr(void) {
|
|||||||
h->status = 'R'; // Mark email read
|
h->status = 'R'; // Mark email read
|
||||||
write_updated_headers(h, get_db_index());
|
write_updated_headers(h, get_db_index());
|
||||||
email_pager(h);
|
email_pager(h);
|
||||||
|
read_email_db(first_msg, 0, 0); // email_pager() deletes the headers
|
||||||
email_summary();
|
email_summary();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2097,6 +2145,11 @@ void main(void) {
|
|||||||
error(ERR_FATAL, "Need 80 cols");
|
error(ERR_FATAL, "Need 80 cols");
|
||||||
if ((*pp & 0x30) != 0x30)
|
if ((*pp & 0x30) != 0x30)
|
||||||
error(ERR_FATAL, "Need 128K");
|
error(ERR_FATAL, "Need 128K");
|
||||||
|
|
||||||
|
// Clear system bit map
|
||||||
|
for (pp = (uint8_t*)0xbf58; pp <= (uint8_t*)0xbf6f; ++pp)
|
||||||
|
*pp = 0;
|
||||||
|
|
||||||
videomode(VIDEOMODE_80COL);
|
videomode(VIDEOMODE_80COL);
|
||||||
readconfigfile();
|
readconfigfile();
|
||||||
reverse = 0;
|
reverse = 0;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define PROGNAME "emai//er v1.05"
|
#define PROGNAME "emai//er v1.06"
|
||||||
|
|
||||||
// Configuration params from EMAIL.CFG
|
// Configuration params from EMAIL.CFG
|
||||||
char cfg_server[40]; // IP of POP3 server
|
char cfg_server[40]; // IP of POP3 server
|
||||||
|
Loading…
Reference in New Issue
Block a user