mirror of
https://github.com/bobbimanners/emailler.git
synced 2024-09-29 23:54:59 +00:00
Broke out MIME attachment functionality into a separate program (ATTACHER)
This commit is contained in:
parent
0b5150cf3b
commit
bdfa35db41
@ -45,7 +45,7 @@ TCP =\
|
||||
tweet65 \
|
||||
pop65-slow
|
||||
|
||||
bin: wget65.bin pop65.bin smtp65.bin email.bin rebuild.bin edit.bin
|
||||
bin: wget65.bin pop65.bin smtp65.bin email.bin rebuild.bin edit.bin attacher.bin
|
||||
|
||||
wget65.bin: w5100.c w5100_http.c linenoise.c
|
||||
wget65.bin: IP65LIB = ../ip65/ip65.lib
|
||||
@ -135,27 +135,29 @@ ip65.d64: prg
|
||||
|
||||
ip65.dsk: bin
|
||||
cp ../build/800k.po $@
|
||||
java -jar $(AC) -as $@ date65 < date65.bin
|
||||
java -jar $(AC) -p $@ date65.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -as $@ edit < edit.bin
|
||||
java -jar $(AC) -p $@ edit.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -as $@ email < email.bin
|
||||
java -jar $(AC) -p $@ email.cfg txt < email.cfg
|
||||
java -jar $(AC) -p $@ email.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -as $@ hfs65 < hfs65.bin
|
||||
java -jar $(AC) -p $@ hfs65.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -as $@ pop65 < pop65.bin
|
||||
java -jar $(AC) -p $@ pop65.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -as $@ rebuild < rebuild.bin
|
||||
java -jar $(AC) -p $@ rebuild.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -as $@ smtp65 < smtp65.bin
|
||||
java -jar $(AC) -p $@ smtp65.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -as $@ telnet65 < telnet65.bin
|
||||
java -jar $(AC) -as $@ tweet65 < tweet65.bin
|
||||
java -jar $(AC) -p $@ tweet65.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -p $@ tzone.txt txt < tzone.txt
|
||||
java -jar $(AC) -as $@ wget65 < wget65.bin
|
||||
java -jar $(AC) -p $@ wget65.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -as $@ attacher < attacher.bin
|
||||
java -jar $(AC) -p $@ attacher.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -as $@ date65 < date65.bin
|
||||
java -jar $(AC) -p $@ date65.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -as $@ edit < edit.bin
|
||||
java -jar $(AC) -p $@ edit.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -as $@ email < email.bin
|
||||
java -jar $(AC) -p $@ email.cfg txt < email.cfg
|
||||
java -jar $(AC) -p $@ email.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -as $@ hfs65 < hfs65.bin
|
||||
java -jar $(AC) -p $@ hfs65.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -as $@ pop65 < pop65.bin
|
||||
java -jar $(AC) -p $@ pop65.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -as $@ rebuild < rebuild.bin
|
||||
java -jar $(AC) -p $@ rebuild.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -as $@ smtp65 < smtp65.bin
|
||||
java -jar $(AC) -p $@ smtp65.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -as $@ telnet65 < telnet65.bin
|
||||
java -jar $(AC) -as $@ tweet65 < tweet65.bin
|
||||
java -jar $(AC) -p $@ tweet65.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
java -jar $(AC) -p $@ tzone.txt txt < tzone.txt
|
||||
java -jar $(AC) -as $@ wget65 < wget65.bin
|
||||
java -jar $(AC) -p $@ wget65.system sys < $(CC65)/apple2enh/util/loader.system
|
||||
|
||||
ip65.atr: com
|
||||
mkdir atr
|
||||
|
327
apps/attacher.c
Normal file
327
apps/attacher.c
Normal file
@ -0,0 +1,327 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Handle attaching files to outgoing messages
|
||||
// Bobbi July 2020
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <conio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "email_common.h"
|
||||
|
||||
#define BELL 0x07
|
||||
#define BACKSPACE 0x08
|
||||
#define RETURN 0x0d
|
||||
#define NORMAL 0x0e
|
||||
#define INVERSE 0x0f
|
||||
#define DELETE 0x7f
|
||||
|
||||
#define NETBUFSZ 1500
|
||||
#define LINEBUFSZ 1000 // According to RFC2822 Section 2.1.1 (998+CRLF)
|
||||
#define READSZ 1024 // Must be less than NETBUFSZ to fit in buf[]
|
||||
|
||||
static unsigned char buf[NETBUFSZ+1]; // One extra byte for null terminator
|
||||
static char linebuf[LINEBUFSZ];
|
||||
static char userentry[80];
|
||||
static uint8_t quit_to_email; // If 1, launch EMAIL.SYSTEM on quit
|
||||
static char filename[80];
|
||||
|
||||
#define ERR_NONFATAL 0
|
||||
#define ERR_FATAL 1
|
||||
|
||||
/*
|
||||
* Show error messages
|
||||
*/
|
||||
void error(uint8_t fatal, const char *fmt, ...) {
|
||||
va_list v;
|
||||
if (fatal) {
|
||||
videomode(VIDEOMODE_80COL);
|
||||
clrscr();
|
||||
printf("\n\n%cFATAL ERROR:%c\n\n", INVERSE, NORMAL);
|
||||
va_start(v, fmt);
|
||||
vprintf(fmt, v);
|
||||
va_end(v);
|
||||
printf("\n\n\n\n[Press Any Key To Quit]");
|
||||
cgetc();
|
||||
exit(1);
|
||||
} else {
|
||||
va_start(v, fmt);
|
||||
vprintf(fmt, v);
|
||||
va_end(v);
|
||||
printf(" - [Press Any Key]");
|
||||
cgetc();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Spinner while encoding attachments
|
||||
*/
|
||||
void spinner(uint32_t sz, uint8_t final) {
|
||||
static char chars[] = "|/-\\";
|
||||
static char buf[10] = "";
|
||||
static uint8_t i = 0;
|
||||
uint8_t j;
|
||||
for (j = 0; j < strlen(buf); ++j)
|
||||
putchar(BACKSPACE);
|
||||
if (final) {
|
||||
sprintf(buf, " [%lu]\n", sz);
|
||||
printf("%s", buf);
|
||||
strcpy(buf, "");
|
||||
}
|
||||
else {
|
||||
sprintf(buf, "%c %lu", chars[(i++) % 4], sz);
|
||||
printf("%s", buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read parms from EMAIL.CFG
|
||||
*/
|
||||
void readconfigfile(void) {
|
||||
FILE *fp = fopen("EMAIL.CFG", "r");
|
||||
if (!fp)
|
||||
error(ERR_FATAL, "Can't open config file EMAIL.CFG");
|
||||
fscanf(fp, "%s", cfg_server);
|
||||
fscanf(fp, "%s", cfg_user);
|
||||
fscanf(fp, "%s", cfg_pass);
|
||||
fscanf(fp, "%s", cfg_pop_delete);
|
||||
fscanf(fp, "%s", cfg_smtp_server);
|
||||
fscanf(fp, "%s", cfg_smtp_domain);
|
||||
fscanf(fp, "%s", cfg_instdir);
|
||||
fscanf(fp, "%s", cfg_emaildir);
|
||||
fscanf(fp, "%s", cfg_emailaddr);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a text file a line at a time leaving the line in linebuf[]
|
||||
* Returns number of chars in the line, or -1 if EOF.
|
||||
* Expects Apple ][ style line endings (CR) and does no conversion
|
||||
* fp - file to read from
|
||||
* reset - if 1 then just reset the buffer and return
|
||||
*/
|
||||
int16_t get_line(FILE *fp, uint8_t reset) {
|
||||
static uint16_t rd = 0; // Read
|
||||
static uint16_t wt = 0; // Write
|
||||
uint8_t found = 0;
|
||||
uint16_t j = 0;
|
||||
uint16_t i;
|
||||
if (reset) {
|
||||
rd = wt = 0;
|
||||
return 0;
|
||||
}
|
||||
while (1) {
|
||||
while (rd < wt) {
|
||||
linebuf[j++] = buf[rd++];
|
||||
if (linebuf[j - 1] == '\r') {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
linebuf[j] = '\0';
|
||||
if (rd == wt) // Empty buf
|
||||
rd = wt = 0;
|
||||
if (found) {
|
||||
return j;
|
||||
}
|
||||
if (feof(fp)) {
|
||||
return -1;
|
||||
}
|
||||
i = fread(&buf[wt], 1, READSZ - wt, fp);
|
||||
wt += i;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Base64 encode table
|
||||
*/
|
||||
static const char b64enc[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/*
|
||||
* Encode Base64 format
|
||||
* p - Pointer to source buffer
|
||||
* q - Pointer to destination buffer
|
||||
* len - Length of buffer to encode
|
||||
* Returns length of encoded data
|
||||
*/
|
||||
uint16_t encode_base64(char *p, char *q, uint16_t len) {
|
||||
uint16_t j = 0;
|
||||
uint16_t i, ii;
|
||||
for (i = 0; i < len / 3; ++i) {
|
||||
ii = 3 * i;
|
||||
q[j++] = b64enc[(p[ii] & 0xfc) >> 2];
|
||||
q[j++] = b64enc[((p[ii] & 0x03) << 4) | ((p[ii + 1] & 0xf0) >> 4)];
|
||||
q[j++] = b64enc[((p[ii + 1] & 0x0f) << 2) | ((p[ii + 2] & 0xc0) >> 6)];
|
||||
q[j++] = b64enc[(p[ii + 2] & 0x3f)];
|
||||
if (((i + 1) % 18) == 0)
|
||||
q[j++] = '\r';
|
||||
}
|
||||
ii += 3;
|
||||
i = len - ii; // Bytes remaining to encode
|
||||
switch (i) {
|
||||
case 1:
|
||||
q[j++] = b64enc[(p[ii] & 0xfc) >> 2];
|
||||
q[j++] = b64enc[(p[ii] & 0x03) << 4];
|
||||
q[j++] = '=';
|
||||
q[j++] = '=';
|
||||
break;
|
||||
case 2:
|
||||
q[j++] = b64enc[(p[ii] & 0xfc) >> 2];
|
||||
q[j++] = b64enc[((p[ii] & 0x03) << 4) | ((p[ii + 1] & 0xf0) >> 4)];
|
||||
q[j++] = b64enc[(p[ii + 1] & 0x0f) << 2];
|
||||
q[j++] = '=';
|
||||
break;
|
||||
}
|
||||
q[j] = '\0';
|
||||
return j;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prompt for a name, store it in userentry
|
||||
* Returns number of chars read.
|
||||
* prompt - Message to display before > prompt
|
||||
* is_file - if 1, restrict chars to those allowed in ProDOS filename
|
||||
* Returns number of chars read
|
||||
*/
|
||||
uint8_t prompt_for_name(char *prompt, uint8_t is_file) {
|
||||
uint16_t i;
|
||||
char c;
|
||||
printf("%s>", prompt);
|
||||
i = 0;
|
||||
while (1) {
|
||||
c = cgetc();
|
||||
if (is_file && !isalnum(c) &&
|
||||
(c != RETURN) && (c != BACKSPACE) && (c != DELETE) &&
|
||||
(c != '.') && (c != '/')) {
|
||||
putchar(BELL);
|
||||
continue;
|
||||
}
|
||||
switch (c) {
|
||||
case RETURN:
|
||||
goto done;
|
||||
case BACKSPACE:
|
||||
case DELETE:
|
||||
if (i > 0) {
|
||||
putchar(BACKSPACE);
|
||||
putchar(' ');
|
||||
putchar(BACKSPACE);
|
||||
--i;
|
||||
} else
|
||||
putchar(BELL);
|
||||
break;
|
||||
default:
|
||||
putchar(c);
|
||||
userentry[i++] = c;
|
||||
}
|
||||
if (i == 79)
|
||||
goto done;
|
||||
}
|
||||
done:
|
||||
userentry[i] = '\0';
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* Optionally attach files to outgoing email.
|
||||
* filename - Name of file containing email message
|
||||
*/
|
||||
void attach(char *fname) {
|
||||
FILE *fp, *fp2, *destfp;
|
||||
uint16_t chars, i, size;
|
||||
videomode(VIDEOMODE_80COL);
|
||||
printf("%c%s ATTACHER%c\n\n", 0x0f, PROGNAME, 0x0e);
|
||||
fp = fopen(fname, "rb+");
|
||||
if (!fp)
|
||||
error(ERR_FATAL, "Can't open %s", fname);
|
||||
sprintf(filename, "%s/OUTBOX/TMPFILE", cfg_emaildir);
|
||||
destfp = fopen(filename, "wb");
|
||||
if (!destfp)
|
||||
error(ERR_FATAL, "Can't open TMPFILE");
|
||||
|
||||
get_line(fp, 1); // Reset buffer
|
||||
printf("Copying email content ... "); // Space is for spinner to eat
|
||||
size = 0;
|
||||
while ((chars = get_line(fp, 0)) != -1) {
|
||||
size += chars;
|
||||
if (linebuf[0] == '\r')
|
||||
break;
|
||||
fputs(linebuf, destfp);
|
||||
spinner(size, 0);
|
||||
}
|
||||
fprintf(destfp, "MIME-Version: 1.0\r");
|
||||
fprintf(destfp, "Content-Type: multipart/mixed; boundary=a2forever\r\r");
|
||||
fprintf(destfp, "This is a multi-part message in MIME format.\r");
|
||||
fprintf(destfp, "--a2forever\r");
|
||||
fprintf(destfp, "Content-Type: text/plain; charset=US-ASCII\r");
|
||||
fprintf(destfp, "Content-Transfer-Encoding: 7bit\r\r");
|
||||
while ((chars = get_line(fp, 0)) != -1) {
|
||||
size += chars;
|
||||
fputs(linebuf, destfp);
|
||||
spinner(size, 0);
|
||||
}
|
||||
spinner(size, 1);
|
||||
|
||||
printf("\rEnter the filename or filenames to attach to the email.\n");
|
||||
printf("An empty entry means you are done attaching files.\n\n");
|
||||
while (prompt_for_name("File to attach", 1)) {
|
||||
fp2 = fopen(userentry, "rb");
|
||||
if (!fp2) {
|
||||
error(ERR_NONFATAL, "Can't open %s", userentry);
|
||||
continue;
|
||||
}
|
||||
fprintf(destfp, "\r--a2forever\r");
|
||||
fprintf(destfp, "Content-Type: application/octet-stream\r");
|
||||
fprintf(destfp, "Content-Transfer-Encoding: base64\r");
|
||||
// TODO: filename should be just the basename in the following line
|
||||
fprintf(destfp, "Content-Disposition: attachment; filename=%s;\r\r", userentry);
|
||||
printf("\r "); // Space is for spinner to eat
|
||||
size = 0;
|
||||
do {
|
||||
i = fread(buf, 1, 72 * 3 / 4 * 5, fp2); // Multiple of 72*3/4 bytes
|
||||
size += i;
|
||||
if (i == 0)
|
||||
break;
|
||||
i = encode_base64(buf, buf + READSZ / 2, i);
|
||||
i = fwrite(buf + READSZ / 2, 1, i, destfp);
|
||||
spinner(size, 0);
|
||||
} while (!feof(fp2));
|
||||
fclose(fp2);
|
||||
spinner(size, 1);
|
||||
}
|
||||
fprintf(destfp, "\r--a2forever--\r");
|
||||
fclose(fp);
|
||||
fclose(destfp);
|
||||
if (unlink(fname))
|
||||
error(ERR_FATAL, "Can't delete %s", fname);
|
||||
if (rename(filename, fname))
|
||||
error(ERR_FATAL, "Can't rename %s to %s", filename, fname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Load EMAIL.SYSTEM to $2000 and jump to it
|
||||
* (This code is in language card space so it can't possibly be trashed)
|
||||
*/
|
||||
#pragma code-name (push, "LC")
|
||||
void load_email(void) {
|
||||
revers(0);
|
||||
clrscr();
|
||||
exec("EMAIL.SYSTEM", NULL); // Assume it is in current directory
|
||||
}
|
||||
#pragma code-name (pop)
|
||||
|
||||
void main(int argc, char *argv[]) {
|
||||
readconfigfile();
|
||||
if (argc == 2) {
|
||||
quit_to_email = 1;
|
||||
attach(argv[1]);
|
||||
} else
|
||||
error(ERR_FATAL, "No email file specified");
|
||||
if (quit_to_email)
|
||||
load_email();
|
||||
}
|
||||
|
||||
|
18
apps/edit.c
18
apps/edit.c
@ -13,6 +13,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <conio.h>
|
||||
@ -40,9 +41,6 @@
|
||||
#define CLREOL 0x1d
|
||||
#define DELETE 0x7f
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
|
||||
#define BUFSZ (20 * 1024)
|
||||
char gapbuf[BUFSZ];
|
||||
char padding = 0; // To null terminate for strstr()
|
||||
@ -878,6 +876,18 @@ void load_email(void) {
|
||||
}
|
||||
#pragma code-name (pop)
|
||||
|
||||
/*
|
||||
* Load ATTACHER.SYSTEM to $2000 and jump to it
|
||||
* (This code is in language card space so it can't possibly be trashed)
|
||||
*/
|
||||
#pragma code-name (push, "LC")
|
||||
void load_attacher(void) {
|
||||
revers(0);
|
||||
clrscr();
|
||||
exec("ATTACHER.SYSTEM", filename); // Assume it is in current directory
|
||||
}
|
||||
#pragma code-name (pop)
|
||||
|
||||
/*
|
||||
* Save file to disk, handle user interface
|
||||
*/
|
||||
@ -1123,6 +1133,8 @@ int edit(char *fname) {
|
||||
if (modified)
|
||||
save();
|
||||
if (quit_to_email) {
|
||||
if (prompt_okay("Add attachments - "))
|
||||
load_attacher();
|
||||
if (prompt_okay("Quit to EMAIL - "))
|
||||
load_email();
|
||||
} else {
|
||||
|
101
apps/email.c
101
apps/email.c
@ -4,7 +4,6 @@
|
||||
// Bobbi June, July 2020
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
// - TODO: Feature to attach files to outgoing messages
|
||||
// - TODO: Get rid of all uses of malloc(). Don't need it.
|
||||
|
||||
#include <stdio.h>
|
||||
@ -604,51 +603,6 @@ uint16_t decode_base64(char *p) {
|
||||
return j;
|
||||
}
|
||||
|
||||
/*
|
||||
* Base64 encode table
|
||||
*/
|
||||
static const char b64enc[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/*
|
||||
* Encode Base64 format
|
||||
* p - Pointer to source buffer
|
||||
* q - Pointer to destination buffer
|
||||
* len - Length of buffer to encode
|
||||
* Returns length of encoded data
|
||||
*/
|
||||
uint16_t encode_base64(char *p, char *q, uint16_t len) {
|
||||
uint16_t j = 0;
|
||||
uint16_t i, ii;
|
||||
for (i = 0; i < len / 3; ++i) {
|
||||
ii = 3 * i;
|
||||
q[j++] = b64enc[(p[ii] & 0xfc) >> 2];
|
||||
q[j++] = b64enc[((p[ii] & 0x03) << 4) | ((p[ii + 1] & 0xf0) >> 4)];
|
||||
q[j++] = b64enc[((p[ii + 1] & 0x0f) << 2) | ((p[ii + 2] & 0xc0) >> 6)];
|
||||
q[j++] = b64enc[(p[ii + 2] & 0x3f)];
|
||||
if (((i + 1) % 18) == 0)
|
||||
q[j++] = '\r';
|
||||
}
|
||||
ii += 3;
|
||||
i = len - ii; // Bytes remaining to encode
|
||||
switch (i) {
|
||||
case 1:
|
||||
q[j++] = b64enc[(p[ii] & 0xfc) >> 2];
|
||||
q[j++] = b64enc[(p[ii] & 0x03) << 4];
|
||||
q[j++] = '=';
|
||||
q[j++] = '=';
|
||||
break;
|
||||
case 2:
|
||||
q[j++] = b64enc[(p[ii] & 0xfc) >> 2];
|
||||
q[j++] = b64enc[((p[ii] & 0x03) << 4) | ((p[ii + 1] & 0xf0) >> 4)];
|
||||
q[j++] = b64enc[(p[ii + 1] & 0x0f) << 2];
|
||||
q[j++] = '=';
|
||||
break;
|
||||
}
|
||||
q[j] = '\0';
|
||||
return j;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print line up to first '\r' or '\0'
|
||||
*/
|
||||
@ -1386,8 +1340,7 @@ uint8_t write_email_headers(FILE *fp1, FILE *fp2, struct emailhdrs *h,
|
||||
prompt_for_name("cc", 0);
|
||||
if (strlen(userentry) > 0)
|
||||
fprintf(fp2, "cc: %s\r", userentry);
|
||||
fprintf(fp2, "X-Mailer: %s - Apple II Forever!\r", PROGNAME);
|
||||
fprintf(fp2, "MIME-Version: 1.0\r\r");
|
||||
fprintf(fp2, "X-Mailer: %s - Apple II Forever!\r\r", PROGNAME);
|
||||
if (mode == 'R') {
|
||||
truncate_header(h->date, buf, 40);
|
||||
fprintf(fp2, "On %s, ", buf);
|
||||
@ -1617,47 +1570,6 @@ err:
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Optionally attach files to outgoing email.
|
||||
* Expects the name of the email file in filename[]
|
||||
*/
|
||||
void attach_files(void) {
|
||||
FILE *fp2;
|
||||
uint16_t i;
|
||||
if (prompt_okay("Attach file(s) - ")) {
|
||||
fp = fopen(filename, "ab");
|
||||
if (!fp) {
|
||||
error(ERR_NONFATAL, "Can't open %s", filename);
|
||||
return;
|
||||
}
|
||||
while (prompt_for_name("File to attach", 1)) {
|
||||
fp2 = fopen(userentry, "rb");
|
||||
if (!fp2) {
|
||||
error(ERR_NONFATAL, "Can't open %s", userentry);
|
||||
continue;
|
||||
}
|
||||
fprintf(fp, "--a2forever\r");
|
||||
fprintf(fp, "Content-Type: application/octet-stream\r");
|
||||
fprintf(fp, "Content-Transfer-Encoding: base64\r");
|
||||
// TODO: filename should be just the basename in the following line
|
||||
fprintf(fp, "Content-Disposition: attachment; filename=%s;\r\r", userentry);
|
||||
do {
|
||||
i = fread(buf, 1, 72 * 3 / 4 * 5, fp2); // Multiple of 72*3/4 bytes
|
||||
if (i == 0)
|
||||
break;
|
||||
//printf("Read %d bytes\n", i);
|
||||
i = encode_base64(buf, buf + READSZ / 2, i);
|
||||
//printf("Encoded to %d bytes\n", i);
|
||||
i = fwrite(buf + READSZ / 2, 1, i, fp);
|
||||
//printf("Wrote %d bytes\n", i);
|
||||
} while (!feof(fp2));
|
||||
fclose(fp2);
|
||||
}
|
||||
}
|
||||
fprintf(fp, "\r--a2forever--\r");
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a blank outgoing message and put it in OUTBOX.
|
||||
* OUTBOX is not a 'proper' mailbox (no EMAIL.DB)
|
||||
@ -1693,22 +1605,13 @@ void create_blank_outgoing() {
|
||||
prompt_for_name("cc", 0);
|
||||
if (strlen(userentry) > 0)
|
||||
fprintf(fp, "cc: %s\r", userentry);
|
||||
fprintf(fp, "X-Mailer: %s - Apple II Forever!\r", PROGNAME);
|
||||
fprintf(fp, "MIME-Version: 1.0\r");
|
||||
fprintf(fp, "Content-Type: multipart/mixed; boundary=a2forever\r\r");
|
||||
fprintf(fp, "This is a multi-part message in MIME format.\r");
|
||||
fprintf(fp, "--a2forever\r");
|
||||
fprintf(fp, "Content-Type: text/plain\r\r");
|
||||
fprintf(fp, "< insert email body here >\r");
|
||||
fprintf(fp, "X-Mailer: %s - Apple II Forever!\r\r", PROGNAME);
|
||||
fclose(fp);
|
||||
|
||||
// Update dest/NEXT.EMAIL, incrementing count by 1
|
||||
if (update_next_email("OUTBOX", num + 1))
|
||||
return;
|
||||
|
||||
sprintf(filename, "%s/OUTBOX/EMAIL.%u", cfg_emaildir, num);
|
||||
attach_files();
|
||||
|
||||
sprintf(filename, "Open %s/OUTBOX/EMAIL.%u in editor - ", cfg_emaildir, num);
|
||||
if (prompt_okay(filename)) {
|
||||
sprintf(filename, "%s/OUTBOX/EMAIL.%u", cfg_emaildir, num);
|
||||
|
@ -5,6 +5,6 @@ NODELETE
|
||||
192.168.10.2
|
||||
apple2.local
|
||||
/IP65
|
||||
/H1/EMAIL
|
||||
/DATA/EMAIL
|
||||
bobbi.8bit@gmail.com
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
// Bobbi June 2020
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
#define PROGNAME "emai//er v0.85"
|
||||
#define PROGNAME "emai//er v0.90"
|
||||
|
||||
// Configuration params from POP65.CFG
|
||||
char cfg_server[40]; // IP of POP3 server
|
||||
|
@ -456,8 +456,7 @@ void update_inbox(uint16_t nummsgs) {
|
||||
copyheader(hdrs.subject, linebuf + 9, 79);
|
||||
hdrs.subject[79] = '\0';
|
||||
}
|
||||
//if (linebuf[0] == '\r') {
|
||||
if (strlen(linebuf) < 10) {
|
||||
if (linebuf[0] == '\r') {
|
||||
headers = 0;
|
||||
hdrs.skipbytes = headerchars;
|
||||
}
|
||||
|
@ -10,15 +10,11 @@
|
||||
#include <conio.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <apple2_filetype.h>
|
||||
|
||||
typedef unsigned long uint32_t;
|
||||
typedef unsigned int uint16_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef int int16_t;
|
||||
#include "email_common.h"
|
||||
|
||||
#define NETBUFSZ 1500+4 // 4 extra bytes for overlap between packets
|
||||
|
Loading…
Reference in New Issue
Block a user