home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Otherware
/
Otherware_1_SB_Development.iso
/
amiga
/
comms
/
network
/
amigaelm.lzh
/
f3.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-15
|
15KB
|
703 lines
#include "prefs.h"
#include <exec/types.h>
#include <exec/memory.h>
#include <libraries/dos.h>
#include <intuition/intuition.h>
#ifdef LATTICE
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/reqtools.h>
#endif
#include <libraries/reqtools.h>
#include <time.h>
Prototype void CreateHeader(FILE*,char*,char*);
Prototype BOOL SetFolderName(char *);
Prototype FILE *OpenHomeBox(void);
Prototype void CloseHomeBox(FILE *);
Prototype char *plural_s(int);
Prototype int plural_pix(int);
Prototype int send_off(char *,char *);
Prototype void append_sig(FILE *);
Prototype void append_elmheader(FILE *);
Prototype void set_options(void);
Prototype void outline(void);
Prototype void OpenTTY(void);
Prototype void Usage(void);
Prototype void DirectSend(char *,char *);
Prototype void copy_and_do_alias(FILE *,FILE *);
Prototype void copy_and_do_from(FILE *,FILE *);
Prototype void str_replace(char *,char *,char *);
Prototype void do_introduction(FILE *,char *,struct MailItem *);
Prototype void clean_exit(int);
Prototype void status_msg(char *, long);
Prototype char *parse_arpa_from(char *);
Prototype char lastch(char *);
char lastch(char *str)
{
int len;
len = strlen(str);
if (str && len)
return(str[len-1]);
else
return('\0');
}
void
CreateHeader(FILE* fp,char* To, char* Subject)
{
fprintf(fp,"To: %s\n",STR(To));
fprintf(fp,"Subject: %s\n",STR(Subject));
}
BOOL
SetFolderName(char *file)
{
char *foldername;
FILE *fp;
if (file && strlen(file) && (foldername=strdup(file))) {
/* IMHO it's not neccessary to lock the folder here */
if (fp=fopen(foldername,"r")) {
fclose(fp);
if (FolderName) free(FolderName);
FolderName = foldername;
return(TRUE);
}
free(foldername);
}
return(FALSE);
}
FILE *OpenHomeBox(void)
{
LockFile(FolderName);
return(fopen(FolderName,"r"));
}
void CloseHomeBox(FILE *folder)
{
fclose(folder);
UnLockFile(FolderName);
}
/* send_off schickt die Mail in file ab, wenn die Abfrage mit 'S' */
/* beantwortet wurde. Der Returnwert ist 1, wenn die Mail versandt */
/* 2, wenn noch mals editiert werden soll und 0 wenn abgebrochen werden */
/* soll */
int send_off(char *file,char *in_reply_to)
{
FILE *in,*out;
char c;
char String[MAX_LINELENGTH];
char *tfile;
BOOL display_header = TRUE;
/* complete header - begin */
if (tfile=malloc(strlen(file)+3)) { /* len + ".o" + null */
strcpy(tfile,file);
strcat(tfile,".o");
remove(tfile);
rename(file,tfile);
remove(file);
if (out=fopen(file,"w")) {
if (SendmailVersion==SM_FEULNER)
fprintf(out,"From: %s@%s%s (%s)\n",UserName,HostName,DomainName,RealName);
if (in_reply_to)
fprintf(out,"In-Reply-To: %s\n",in_reply_to);
if (WantReturn)
fprintf(out,"Return-Receipt-To: %s@%s%s\n",UserName,HostName,DomainName);
append_elmheader(out);
if (in=fopen(tfile,"r")) {
copy_and_do_alias(in,out);
copy_and_do_from(in,out);
fclose(in);
}
fclose(out);
remove(tfile);
}
}
/* complete header - end */
while (TRUE) {
if (display_header) {
sprintf(TBuffer,"\033[%d;1H\033[J",Win_Height-1);
outline();
putst("And now: \n");
putst_center("Choose e)dit message, s)end, S)end without signature, or f)orget.");
sprintf(TBuffer,"\033[%d;10H",Win_Height-1);
outline();
display_header = FALSE;
}
flush_input();
c=getch();
if (toupper(c)=='S') {
putst("Send");
if (c=='s') {
if (out=fopen(file,"a")) {
append_sig(out);
fclose(out);
}
}
else
putst(" (without signature)");
if (in=fopen(file,"r")) {
if (SentArchive) {
if (out=fopen(SentArchive,"a")) {
long t;
time(&t);
fprintf(out,"From %s (ARCHIVE)\n",UserName);
fprintf(out,"Date: %s",ctime(&t));
if (SendmailVersion!=SM_FEULNER)
fprintf(out,"From: %s@%s%s (%s)\n",UserName,HostName,DomainName,RealName);
copy_and_do_from(in,out);
fclose(out);
}
}
fclose(in);
}
if (SendmailVersion==SM_FEULNER)
sprintf(String,"sendmail <%s",file);
else if (SendmailVersion==SM_DILLON)
sprintf(String,"sendmail <%s -f %s -R \"%s\"",file,UserName,RealName);
else if (SendmailVersion==SM_OTHER)
sprintf(String,"sendmail <%s -f %s",file,UserName);
Execute(String,0L,0L);
return 1;
}
else if (c=='e') {
putst("Edit message");
editfile(file);
display_header = TRUE;
}
else if (c=='f') {
putst("Forget");
return 0;
}
}
}
void
copy_and_expand_alias(FILE *in, FILE *out, long start, long end)
{
char *buf,*ptr;
BOOL erstes = TRUE;
struct AliasItem *list,*l,*inner,*i;
if (buf = malloc(end-start+2)) {
fseek(in,start,0);
fread(buf,1,end-start+1,in);
buf[end-start+1] = '\0';
ptr = strchr(buf,':');
*ptr = '\0';
ptr++;
l = list = AdrsToAList(ptr);
if (list)
fprintf(out,"%s: ",buf);
while (l) {
/*printf("mal sehen: %s -> %s -> %s\n",l->alias,l->real,GetAlias(AliasList,l->alias));*/
i = inner = AdrsToAList(l->real?l->real:l->alias);
while (i) {
fprintf(out,"%s%s",erstes?"":",\n\t",i->real?i->real:i->alias);
erstes = FALSE;
i = i->next;
}
FreeAliasList(&inner);
l = l->next;
}
if (list)
fputc('\n',out);
FreeAliasList(&list);
if (erstes)
fprintf(stderr,"To: line is empty\n");
free(buf);
}
}
void
copy_and_do_alias(FILE *in,FILE *out)
{
char buf[MAX_LINELENGTH];
long pos,start,end;
buf[MAX_LINELENGTH-1]='\0'; /* 100% null-terminated */
while(getline(in,buf,&pos)) {
if (!strlen(buf)) { /* end of header, message body begins */
fputc('\n',out);
return;
}
else if (!strnicmp(buf,"To:",3) || !strnicmp(buf,"Cc:",3) || !strnicmp(buf,"Bcc:",4)) {
start = pos;
while(getline(in,buf,&pos) && (*buf==' ' || *buf=='\t'))
;
end = pos-1;
copy_and_expand_alias(in,out,start,end);
}
else
fprintf(out,"%s\n",buf);
}
}
void
copy_and_do_from(FILE *in,FILE *out)
{
char buf[MAX_LINELENGTH];
buf[MAX_LINELENGTH-1]='\0'; /* 100% null-terminated */
while(fgets(buf,MAX_LINELENGTH-1,in)) {
if (strncmp("From ",buf,5)==0)
fprintf(out,">%s",buf);
else
fputs(buf,out);
}
}
void
append_elmheader(FILE *file)
{
FILE *in;
char *headerfile;
if (headerfile = malloc(strlen(UULIB)+strlen(UserName)+strlen(ELM_HEADERS)+1)) {
strcpy(headerfile,UULIB);
strcat(headerfile,UserName);
strcat(headerfile,ELM_HEADERS);
if (!(in=fopen(headerfile,"r"))) {
strcpy(headerfile,UULIB);
strcat(headerfile,ELM_HEADERS);
in=fopen(headerfile,"r");
}
fprintf(file,"X-Mailer: //\\\\miga Electronic Mail (AmiElm %s)\n",VERSION);
if (in) {
char line[MAX_LINELENGTH];
line[MAX_LINELENGTH-1]='\0';
while(fgets(line,MAX_LINELENGTH-1,in))
if (strlen(line) && strchr(line,':'))
fputs(line,file);
fclose(in);
}
free(headerfile);
}
}
void
append_sig(FILE *file)
{
FILE *in;
char *sigfile;
if (sigfile = malloc(strlen(UULIB)+strlen(UserName)+strlen(SIGNATURE)+1)) {
strcpy(sigfile,UULIB);
strcat(sigfile,UserName);
strcat(sigfile,SIGNATURE);
if (!(in=fopen(sigfile,"r"))) {
strcpy(sigfile,UULIB);
strcat(sigfile,SIGNATURE);
in=fopen(sigfile,"r");
}
if (in) {
register int c;
while((c=getc(in))!=EOF)
putc(c,file);
fclose(in);
}
free(sigfile);
}
}
void
set_options(void)
{
char c;
BOOL Quit = FALSE;
while(!Quit) {
putst("\f \n\n"); /* extra space for character mapped console windows */
putst_center_bold("O p t i o n s");
putch('\n');
putst_center_bold("_______________");
putst("\033[8;1HWhich option do you want to change (toggle) ?\n");
putst(" (caution, changes are temporary!)\n\n\n");
putst(" (1) Handle Return-Receipt-To (");
if (ReturnReceipt)
putst("on)\n");
else
putst("off)\n");
putst(" (2) Handle Return-\033[1mView\033[m-To (");
if (ReturnView)
putst("on)\n");
else
putst("off)\n");
putst(" (3) Request Return-Receipt-To (");
if (WantReturn)
putst("on)\n");
else
putst("off)\n");
putst(" (4) Request Return-\033[1mView\033[m-To (");
if (WantReturn)
putst("on)\n");
else
putst("off)\n");
putst(" (5) Show full header (");
if (ShowHeader)
putst("on)\n");
else
putst("off)\n");
putst(" (6) Show signatures (");
if (ShowSig)
putst("on)\n");
else
putst("off)\n");
putst(" (7) Keep backups (");
if (KeepBackup)
putst("on)\n");
else
putst("off)\n");
putst("\n\n\n");
putst_center(" Choose 1-7, or any other key to return: ");
flush_input();
c=getch();
switch (c) {
case '1': ReturnReceipt = !ReturnReceipt; break;
case '2': ReturnView = !ReturnView; break;
case '3': WantReturn = !WantReturn; break;
case '4': WantView = !WantView; break;
case '5': ShowHeader = !ShowHeader; break;
case '6': ShowSig = !ShowSig; break;
case '7': KeepBackup = !KeepBackup; break;
default : Quit = TRUE; break;
}
}
}
/* Lowlevelroutinen zur Behandlung eines RAW-Fensters. Damit wird die
* Eingabepufferung der Standard-C Routinen umgangen; ausserdem koennen
* so die Cursortasten vom Programm aus abgefragt werden
*/
void
OpenTTY(void)
{
if (!open_intuition()) {
fprintf(stderr,"elm: cannot open tty\n");
clean_exit(103);
}
}
void
outline(void)
{
putst(TBuffer);
}
/* Die naechste Prozedur gibt eine kleine Bedienungsanleitung auf dem
* Bildschirm aus und verlaesst das Programm dann
*/
void
Usage(void)
{
printf("\033[1;33mAmiga Elm \033[0m%s ⌐ 1991-1992 Andreas M. Kirchwitz (amk@zikzak.in-berlin.de)\n",VERSION);
printf("(based on hwr-mail by Heiko W. Rupp, hwr@pilhuhn.ka.sub.org)\n");
printf("Usage: elm \033[3m[?|-v|-h|-?|-f] [<user>] [-s <subject>]\033[0m\n");
clean_exit(0);
}
void
DirectSend(char *To,char *Subject)
{
OpenTTY();
sendmail(To,Subject);
clean_exit(0);
}
char *
plural_s(int number)
{
return( (number==1)?"":"s" );
}
int
plural_pix(int number)
{
return( (number==1)?1:0 );
}
void
str_replace(char *workbuf, char *search, char *replace)
{
char *p;
if (replace && strlen(replace) && (p=strstr(workbuf,search))) {
char *s = p+strlen(search);
char *d = p;
while (*d++=*s++)
;
strins(p,replace);
}
}
void do_introduction(FILE *out, char *intro, struct MailItem *I)
{
int nnum;
char *str;
char *fname = NULL;
if (intro && strlen(intro)) {
if (I->FromName) {
fname=malloc(strlen(I->FromName)+1);
for(nnum=0;I->FromName[nnum]!='\0' && I->FromName[nnum]!=' ';nnum++)
fname[nnum]=I->FromName[nnum];
fname[nnum]='\0';
}
if (str=malloc(strlen(intro)+2*strlen(I->From)+strlen(I->MessageID)+strlen(I->Date)+1)) {
strcpy(str,intro);
str_replace(str,"$FIRSTNAME",fname);
if (I->FromName && strlen(I->FromName))
str_replace(str,"$NAME",I->FromName);
else
str_replace(str,"$NAME",I->From);
str_replace(str,"$MSGID",I->MessageID);
str_replace(str,"$DATE",I->Date);
fprintf(out,"%s\n\n",str);
}
}
}
void clean_exit(int err_code)
{
struct MailItem *del;
close_intuition();
if (MailTmp) remove(MailTmp);
UnLockFiles();
while(MailList) {
del = MailList;
MailList = MailList->next;
free(del);
}
FreeAliasList(&AliasList);
CloseReqToolsLib();
/*
aus unerfindlichen Gruenden produziert exit() Enforcer-Hits, wenn man
Elm startet, ein Reply macht, dies jedoch dann mit f)orget abbricht
und dann das Programm beendet
*/
exit(err_code);
}
void status_msg(char *msg, long delay_time)
{
int hpos;
if (intui_interface()) {
hpos = (Win_Width-strlen(msg))/2;
if (hpos<0)
hpos=0;
sprintf(TBuffer,"\033[%d;1H\033[J\033[%d;%dH[%.*s]",Win_Height,Win_Height,hpos-1,Win_Width-2,msg);
outline();
if (delay_time>0L)
Delay(delay_time);
}
else
fprintf(stderr,"elm: %s\n",msg);
}
char *parse_arpa_from(char *str)
{
/** try to parse the 'From:' line given... It can be in one of
two formats:
From: Dave Taylor <hpcnou!dat>
or From: hpcnou!dat (Dave Taylor)
Change 'newfrom' ONLY if sucessfully parsed this entry and
the resulting name is non-null!
**/
char *temp_buffer, *temp, *ret=NULL, *buffer;
register int i, j = 0, in_parens;
if (!(buffer=strdup(str)))
return(NULL);
removeCR(buffer); /* blow away '\n' char! */
buffer = delete_wspaces_begin(buffer);
delete_wspaces_end(buffer);
if (!(temp_buffer=malloc(strlen(buffer)+1))) {
free(buffer);
return(NULL);
}
temp = temp_buffer;
*temp = '\0';
if (lastch(buffer) == '>') {
/*
for (i=0; buffer[i] != '\0' && buffer[i] != '<' &&
buffer[i] != '('; i++)
*/
for (i=0; buffer[i] != '\0' && buffer[i] != '<'; i++)
temp[j++] = buffer[i];
temp[j] = '\0';
}
else if (lastch(buffer) == ')') {
in_parens = 1;
for (i=strlen(buffer)-2; i>=0 && buffer[i] != '\0' && buffer[i] != '<'; i--) {
switch(buffer[i]) {
case ')': in_parens++;
break;
case '(': in_parens--;
break;
}
if(!in_parens) break;
temp[j++] = buffer[i];
}
temp[j] = '\0';
strrev(temp);
}
/*
/* We want a REAL name... else NULL... */
temp = delete_wspaces_begin(temp);
delete_wspaces_end(temp);
/** if we have a null string at this point, we must just have a
From: line that contains an address only. At this point we
can have one of a few possibilities...
From: address
From: <address>
From: address ()
**/
j = 0;
if (strlen(temp) == 0) {
if (lastch(buffer) != '>') {
for (i=0; buffer[i] != '\0' && buffer[i] != '('; i++)
temp[j++] = buffer[i];
temp[j] = '\0';
}
else { /* get outta '<>' pair, please! */
for (i=strlen(buffer)-2;buffer[i] != '<' && buffer[i] != ':' && i>=0;i--)
temp[j++] = buffer[i];
temp[j] = '\0';
strrev(temp);
}
}
*/
temp = delete_wspaces_begin(temp);
delete_wspaces_end(temp);
if (strlen(temp) > 0) { /* mess with buffer... */
i = strlen(temp) - 1;
/* remove surrounding paired quotation marks */
if((temp[i] == '"') & (temp[0] == '"')) {
temp[i] = '\0';
temp++;
}
/* if anything is left, let's change 'from' value! */
if (strlen(temp) > 0)
ret = strdup(temp);
}
free(buffer);
free(temp_buffer);
return(ret);
}