home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Otherware
/
Otherware_1_SB_Development.iso
/
amiga
/
comms
/
network
/
amigaelm.lzh
/
f2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-02-14
|
15KB
|
524 lines
#include "prefs.h"
#include <sys/types.h>
#include <sys/stat.h>
#ifdef LATTICE
#include <error.h>
#include <proto/dos.h>
#include <proto/exec.h>
#endif
#ifdef DICE
#include <errno.h>
#endif
static void ClearDirDisplay(int);
static void DisplayDirLine(int,int,struct MailItem *,int);
static void DisplayDirectory(int,int,int,int);
Prototype void NewDisplayDirectory(int,int,int,int,int);
Prototype void SaveFolder(BOOL,long,long);
Prototype void get_folder_data(long *,long *);
Prototype BOOL folder_changed(long,long);
Prototype struct MailItem *i_th(int);
extern int errno;
struct MailItem *i_th(int i)
{
struct MailItem *m = MailList;
while (--i)
m = m->next;
return(m);
}
void
SaveFolder(BOOL ask, long laenge, long datum)
{
long pos;
FILE *in,*keep,*store;
struct MailItem *I;
char Name[MAX_LINELENGTH];
char Text[MAX_LINELENGTH]; /* large enough for a single line? */
BOOL flags_written,folder_has_changed;
BOOL tmp_AlwaysKeep,tmp_AlwaysDelete;
int Number;
int to_delete,to_store,to_keep;
int save_num=1;
char buffer[80];
char TitleString[1024];
tmp_AlwaysKeep = AlwaysKeep;
tmp_AlwaysDelete = AlwaysDelete;
sprintf(Name,"%s.o",FolderName); /* name for backup */
LockFile(Name);
LockFile(FolderName);
if (folder_changed(laenge,datum)) {
status_msg("Folder has changed. Resynchronizing...",0L);
get_folder_data(&laenge,&datum);
if (!read_home_box() || !laenge || !datum) {
status_msg("Resync failed. Folder not saved.",200L);
clean_exit(5);
}
}
remove(Name); /* remove backup */
/* we need to know if there are none, or one, or more to delete/store */
for (I=MailList,to_delete=0,to_store=0; I; I=I->next) {
if (I->Status & DELETED)
to_delete++;
else if (I->Status & READ)
to_store++;
}
if (ask) {
if (to_delete) {
char chr;
sprintf(TBuffer,"\033[%d;%dH\033[JDelete message%s? (y/n) %c\b",
Win_Height-1,Win_Width-27+plural_pix(to_delete),
plural_s(to_delete),
tmp_AlwaysDelete?'y':'n');
outline();
do {
flush_input();
chr=getch();
if (chr=='\r')
chr=(tmp_AlwaysDelete?'y':'n');
} while (chr!='y' && chr!='n');
if (chr=='n') {
putst("No.");
tmp_AlwaysDelete = FALSE;
}
else {
tmp_AlwaysDelete = TRUE;
putst("Yes.");
}
Delay(25L); /* just a moment */
}
/*
* We need to determine if read messages
* are to be stored or kept.
* (unread messages are always kept)
*/
if (to_store) {
char chr;
sprintf(TBuffer,"\033[%d;%dH\033[JMove read message%s to \"received\" folder? (y/n) %c\b",
Win_Height-1,Win_Width-51+plural_pix(to_store),
plural_s(to_store),
tmp_AlwaysKeep?'n':'y');
outline();
do {
flush_input();
chr=getch();
if (chr=='\r')
chr=(tmp_AlwaysKeep?'n':'y');
} while (chr!='y' && chr!='n');
if (chr=='n') {
putst("No.");
tmp_AlwaysKeep = TRUE;
}
else {
tmp_AlwaysKeep = FALSE;
putst("Yes.");
}
Delay(25L); /* just a moment */
}
}
if (tmp_AlwaysKeep)
to_store = 0;
if (!tmp_AlwaysDelete)
to_delete = 0;
to_keep=MaxArticle-to_delete-to_store;
/*
* Formulate message as to number of keeps, stores, and deletes.
* This is only complex so that the message is good English.
*/
if (to_keep > 0) {
if (to_store > 0) {
if (to_delete > 0)
sprintf(buffer,
"Keeping %d message%s, storing %d, and deleting %d.",
to_keep, plural_s(to_keep), to_store, to_delete);
else
sprintf(buffer, "Keeping %d message%s and storing %d.",
to_keep, plural_s(to_keep), to_store);
} else {
if (to_delete > 0)
sprintf(buffer, "Keeping %d message%s and deleting %d.",
to_keep, plural_s(to_keep), to_delete);
else
sprintf(buffer, "Keeping %s.",
to_keep > 1 ? "all messages" : "message");
}
} else if (to_store > 0) {
if (to_delete > 0)
sprintf(buffer, "Storing %d message%s and deleting %d.",
to_store, plural_s(to_store), to_delete);
else
sprintf(buffer, "Storing %s.",
to_store > 1? "all messages" : "message");
} else {
if (to_delete > 0)
sprintf(buffer, "Deleting all messages.");
else
buffer[0] = '\0';
}
/* folder has changed? */
folder_has_changed = FALSE;
for (I=MailList; I; I=I->next) {
if (I->Status!=I->OldStatus)
folder_has_changed = TRUE;
}
if (folder_has_changed)
status_msg(buffer,0L);
else {
status_msg("Folder unchanged.",100L);
return;
}
/*
* Backups der Mailbox machen - auf diese Weise koennen geloeschte
* Mails von Hand wieder zurueckgeholt werden
*/
if (rename(FolderName,Name)) {
fprintf(stderr,"elm: cannot rename folder to backup\n");
UnLockFile(FolderName);
UnLockFile(Name);
return;
}
in=fopen(Name,"r");
keep=fopen(FolderName,"w");
if (tmp_AlwaysKeep) {
store=keep;
}
else {
store=fopen(ReceivedFolder,"a");
}
if ( !in || !keep || !store ) {
char exec[256];
fprintf(stderr,"elm: cannot open folder or backup\n");
sprintf(exec,"COPY %s.o %s",FolderName,FolderName);
Execute(exec,0L,0L);
UnLockFile(FolderName);
UnLockFile(Name);
return;
}
for (Number=MaxArticle;Number>0;Number--) {
FILE *out;
flags_written=FALSE;
if (ReverseSorting)
I=i_th(Number);
else
I=i_th(MaxArticle-Number+1);
/*
* Wenn die Mail nicht geloescht werden soll, dann die Mail
* versehen mit dem neuen Status in die Homebox zurueckschreiben
*/
out = ((I->Status & READ) && !tmp_AlwaysKeep)?store:keep;
if (!( (I->Status & DELETED) && tmp_AlwaysDelete )) {
long todo; /* bytes to do */
BOOL goon; /* go on saving */
sprintf(TitleString,"Processing %s, message: %d of %d",FolderName,save_num++,to_keep);
SetScreenTitle(TitleString);
fseek(in,I->ArtikelStart,0);
/* -------------------------------------------------------------------------- */
while((goon=getline(in,Text,&pos)) && (pos<I->TextStart)) {
if (!flags_written && !strncmp(Text,"X-Status:",9)) {
fprintf(out,"X-Status: O");
if (I->Status & READ) putc('R',out);
if (I->Status & LOGGED) putc('L',out);
if (I->Status & ANSWERED) putc('A',out);
if (I->Status & FORWARDED) putc('F',out);
if (I->Status & BOUNCED) putc('B',out);
putc('\n',out);
flags_written=TRUE;
}
else if (!flags_written && !strlen(Text)) {
fprintf(out,"X-Status: O");
if (I->Status & READ) putc('R',out);
if (I->Status & LOGGED) putc('L',out);
if (I->Status & ANSWERED) putc('A',out);
if (I->Status & FORWARDED) putc('F',out);
if (I->Status & BOUNCED) putc('B',out);
fprintf(out,"\n\n");
flags_written=TRUE;
}
else
fprintf(out,"%s\n",Text);
}
if (goon && pos<=I->ArtikelEnd) fprintf(out,"%s\n",Text);
/*
if (todo = I->ArtikelEnd-I->TextStart) {
*/
if (todo = I->ArtikelEnd-ftell(in)+1L) {
while(todo>0) {
long len = todo>FileBufferSize?FileBufferSize:todo;
todo -= len;
if (len=fread(FileBuffer,1L,len,in))
fwrite(FileBuffer,1L,len,out);
}
}
/*
while(getline(in,Text,&pos) && (pos<=I->ArtikelEnd)) {
if (pos<I->ArtikelEnd) {
/*
* Status-Zeile gefunden ? Dann in diese Zeile den neuen Status
* einschreiben.
*/
if ((!flags_written) && (strncmp(Text,"X-Status:",9)==0)) {
fprintf(out,"X-Status: O");
if (I->Status & READ) putc('R',out);
if (I->Status & LOGGED) putc('L',out);
if (I->Status & ANSWERED) putc('A',out);
if (I->Status & FORWARDED) putc('F',out);
if (I->Status & BOUNCED) putc('B',out);
putc('\n',out);
flags_written=TRUE;
}
/*
* Noch keine X-Status-Zeile und schon den Message-Body
* erreicht ? Wenn Status gesetzt ist, dann die X-Status-Zeile
* schreiben, danach die Body-Zeile
*/
else if ((!flags_written) && (pos<=I->TextStart) && (strlen(Text)==0)) {
fprintf(out,"X-Status: O");
if (I->Status & READ) putc('R',out);
if (I->Status & LOGGED) putc('L',out);
if (I->Status & ANSWERED) putc('A',out);
if (I->Status & FORWARDED) putc('F',out);
if (I->Status & BOUNCED) putc('B',out);
putc('\n',out);
flags_written=TRUE;
fprintf(out,"%s\n",Text);
}
else
fprintf(out,"%s\n",Text);
}
}
*/
/* -------------------------------------------------------------------------- */
}
}
fclose(in);
fclose(keep);
if (!tmp_AlwaysKeep) fclose(store);
UnLockFile(FolderName);
UnLockFile(Name);
if (!KeepBackup) remove(Name);
}
void
NewDisplayDirectory(int page,int MaxArt,int Akt,int Mode,int MsgPerPage)
{
static int LastAkt = -1;
static int LastPage = -1;
int hi;
int p20; /* page*MsgPerPage */
int f;
if (!MaxArt) return;
putst("\033[0 p"); /* cursor off */
p20=page*MsgPerPage;
if ( (p20+MsgPerPage) > MaxArt) /* Seite nur teilweise gefuellt */
hi=MaxArt; /* Dann nur bis MaxArticle dar- */
else /* stellen */
hi=p20+MsgPerPage;
if ((Mode==FULL) || (LastPage!=page)){ /* Seitenwechsel ? */
DisplayDirectory(page,hi,Akt,MsgPerPage);
LastPage=page; /* Aktuelle position und */
}
else { /* Modus update und gleiche Seite */
if ( (Akt< p20) || (Akt >p20+MsgPerPage))
DisplayDirectory(page,hi,Akt,MsgPerPage);
else {
f=(LastAkt-(p20))+1;
if(LastAkt>0) /* letzten Eintrag normal dar- */
DisplayDirLine(f,LastAkt,i_th(LastAkt),0); /* stellen */
f=(Akt-(p20))+1;
DisplayDirLine(f,Akt,i_th(Akt),1); /* Neue Position revers */
}
} /* Seite merken */
LastAkt=Akt; /* darstellen */
putst("\033[ p"); /* cursor on */
}
static void
ClearDirDisplay(int MsgPerPage)
{
register int line=2;
register int i;
for(i=0;i<MsgPerPage;i++) {
sprintf(TBuffer,"\033[%d;1H\033[K",line++);
outline();
}
}
static void
DisplayDirectory(int page,int hi,int Aktuell,int MsgPerPage)
{
register int j;
register int pos=2;
ClearDirDisplay(MsgPerPage);
for (j=(page*MsgPerPage);j<hi;j++) {
if (j==Aktuell-1)
DisplayDirLine(pos,j+1,i_th(j+1),1);
else
DisplayDirLine(pos,j+1,i_th(j+1),0);
pos++;
}
}
static void
DisplayDirLine(int Zeile,int Nummer,struct MailItem *I,int Mode)
{
char linenum[10];
char stat;
char *name = NULL;
sprintf(TBuffer,"\033[%d;1H ",Zeile); /* Goto line pos */
outline();
if (Mode==1) putst(REVERSE_ON);
sprintf(linenum,"(%ld)",I->Lines);
if (I->Status&DELETED)
stat='D';
else if (I->Status&READ)
stat=' ';
else if (I->Status&OLD)
stat='O';
else
stat='N';
if (I->FromName || !I->From) {
if (I->FromName && strcmp(RealName,I->FromName)) {
name = I->FromName;
}
else {
if (I->ToName) {
if (name=malloc(strlen(I->ToName)+4)) {
sprintf(name,"To %s",I->ToName);
}
}
else if (I->To) {
if (name=malloc(strlen(I->To)+4)) {
sprintf(name,"To %s",I->To);
}
}
}
}
else
name = I->From;
if (!name) name = "(none)";
sprintf(TBuffer,"%c%c%c%c%c%c %-3d %-6.6s %-20.20s %-6.6s %-*.*s",
(I->Status & LOGGED) ? 'L':' ',
stat,
(I->Urgent) ? 'U':' ',
(I->Status & ANSWERED) ? 'A':' ',
(I->Status & FORWARDED) ? 'F':' ',
(I->Status & BOUNCED) ? 'B':' ',
Nummer,
I->Date,
name,
linenum,
Win_Width-50,
Win_Width-50,
I->Subject?I->Subject:"(none)"
);
outline();
if (Mode==1) putst(PLAIN_TEXT);
}
void get_folder_data(long *laenge,long *datum)
{
struct stat s;
long try = 0L;
while(stat(FolderName,&s)) {
char msg[80];
if (errno!=EBUSY) { /* resource is busy? */
fprintf(stderr,"elm: error scanning folder, code %d\n",errno);
*laenge=0L;
*datum=0L;
return;
}
sprintf(msg,"Folder is busy. Stand by. Resynchronizing... try #%ld",++try);
status_msg(msg,0L);
Delay(100L);
}
*laenge=s.st_size;
*datum=s.st_mtime;
}
BOOL folder_changed(long laenge,long datum)
{
struct stat s;
long try = 0L;
while(stat(FolderName,&s)) {
char msg[80];
if (errno!=EBUSY) { /* resource is busy? */
fprintf(stderr,"elm: error scanning folder, code %d\n",errno);
return(TRUE);
}
sprintf(msg,"Folder is busy. Stand by. Resynchronizing... try #%ld",++try);
status_msg(msg,0L);
Delay(100L);
}
return (s.st_size!=laenge || s.st_mtime!=datum);
}