home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 3 Comm
/
03-Comm.zip
/
RDQWKSRC.ZIP
/
READ.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-15
|
33KB
|
1,455 lines
/*
╔══════════════════════════════════════════════════════════════════════════╗
║ ║
║ Test routines to read, in Qmail Format - R.Cougnenc 90 - ║
║ ║
║ Public Domain ║
║ ║
╟──────────────────────────────────────────────────────────────────────────╢
║ ║
║ These modules correspond to different tests at reading in ║
║ Qmail Format. They were never planned to be released as a ║
║ package. ║
║ ║
║ Source code is not beautified or optimised as they are work ║
║ files and are distributed as is. ║
║ ║
║ The program, even at it's rustic stage is fully fonctional, ║
║ as I use it regularly... ║
║ ║
║ Feel free to use any or all of these modules, if you can sort ║
║ it out! :-) ║
║ ║
╚══════════════════════════════════════════════════════════════════════════╝
*/
/*
Small Reader for Qmail format.
Using only tty mode and printf, this program should be compiled
on many systems with minor modifications.
Rene Cougnenc 1990
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef __TURBOC__
#include <alloc.h>
#else
#include <malloc.h>
#endif
#include "reader.h"
#include "qmail.h"
#include "ansi.h"
#include "read.h"
#include "readlib.h"
#include "makemail.h"
#define NEXT 1
#define AGAIN 0
#define PREVIOUS 2
char *TagLine = "\n---\n ■ AzerTyuioP 0.2 ■\n\n"; /* Reader Signature */
char CurTag[256]; /* Tag line chosen... */
char HomePath [MAXPATHS]; /* Home directory for exe file & root of msg dirs*/
char MailPath [MAXPATHS]; /* Where to look for new mail */
char ReplyPath [MAXPATHS]; /* Where to put replies */
char WorkPath [MAXPATHS]; /* Where to archive/unarchive mail . */
char CurBoard [50 ]; /* Name of the current board... */
int CurConf ; /* Name of the current Conference... */
int TotMsg ; /* Number of messages in conf */
int ReplyExist = 0 ; /* Flag 1 if there are replies to pack */
int ansi = 0 ; /* Flag 1 if ansi output is on */
int IsEmpty = 1 ; /* Flag 0 if a BBS is loaded */
int HeadLetter = 1 ; /* Flag 1 if automatic header is active */
char Editor [50 ]; /* Name of the standard text editor */
char Archiver [50 ];
char UnArchiver[50] ;
struct MyIndex Index ;
FILE *fidx,*fmsg ; /* Index File and msg file, globals */
int FilesOpen = 0 ; /* Flag if these files are open */
byte *rbuf ;
/* DOS internal commands. Will be called by system directly from shell. */
#define MAXCMDS 14
static char *cmds[MAXCMDS] = {"cd","chdir","copy","dir","del","era","md",
"mkdir","more","print","rd","rmdir","set",
"type"};
/*----------------------------------------------------------------------*/
main(argc,argv)
int argc;
char *argv[];
{
MakeHomePath(argv[0]);
if( ReadConfig() )
return (0xFF) ;
Clean();
clear();
bblack() ;
Title();
#if !__DISTRIB__
red();
printf("Perso ! Ne pas distribuer !\n\n");
/* ^^^^^^ = ? ^^^^^^^^^^^^^^^ = Do not distribute */
#endif
cyan();
strcpy(CurBoard,txt [ 10 ]); /* First default prompt.... */
strcpy(ConfName[0],txt[ 9 ]); /* "empty" */
strcpy(CurTag, TagLine ) ; /* default TagLine */
if( ( rbuf = (char *) malloc( MYBUF )) == NULL )
{
printf("%s\n",txt[ 1 ]); /* Not enough memory */
return (0xFF);
}
if( argc == 2 )
GetBbs( argv[1] );
ReadShell();
free( rbuf );
return( 0 );
}
/*
Main Shell
*/
void ReadShell()
{
char tmp[256];
char *ptr;
int i;
loop :
while( 1 )
{
if( ansi)
printf("%c[1;32m",27);
printf("%s [ %s ] > ",CurBoard,ConfName[CurConf]);
if( ansi)
printf("%c[0m",27);
gets(tmp);
for( i = 0 ; i < MAXCMDS; i++) /* Internal shell commands */
{
if( ! strnicmp(tmp,cmds[i],strlen(cmds[i] ) ) )
{
system( &tmp[0] );
goto loop ;
}
}
if( Numeric( tmp ) ) GoToNum( tmp );
else
if( ! strnicmp (tmp,"aide",4) ) help();
else
if( ! strnicmp (tmp,"cls",3) ) cls();
else
if( ! strnicmp (tmp,"clean",5) ) Purge();
else
if( ! strnicmp (tmp,"conf",4) ) ListConf();
else
if( ! strnicmp (tmp,"date",4) ) Date();
else
if( ! strnicmp (tmp,"help",4) ) help();
else
if( ! strnicmp (tmp,"head",4) )
{
#if __DISTRIB__
magenta(); high();
printf("%s",txt[ 95 ] ); /* "Unauthorized command" */
#else
blue(); high();
HeadLetter = HeadLetter ? 0 : 1 ;
printf("%s ",txt[101] ); /* "Automatic H." */
printf("%s\n", HeadLetter ? txt[85] : txt[86] ); /* "on" / "off" */
#endif
}
else
if( ! strnicmp (tmp,"news",4) )
{
if( ansi )
{
sprintf(tmp,"%s%s/%s",HomePath,CurBoard,NEWSG);
if(! access(tmp,0 ) )
{
sprintf(tmp,"%s%s",HomePath,CurBoard);
view(tmp,NEWSG);
continue ;
}
}
sprintf(tmp,"%s%s",HomePath,CurBoard);
view(tmp,NEWS);
}
else
if( ! strnicmp (tmp,"time",4) ) Date();
else
if( ! strnicmp (tmp,"welcome",4) ) Welcome();
else
if( ! strnicmp (tmp,"file",4) )
{
if( IsEmpty )
{
EmptyMsg();
continue ;
}
sprintf(tmp,"%s%s",HomePath,CurBoard);
view(tmp,NEWFILES);
}
else
if( ! strnicmp (tmp,"load",4) ) load(tmp); /* Load new mail */
else
if( ! strnicmp (tmp,"merde",5) ) merde(); /* Load new mail */
else
if( ! strnicmp (tmp,"read",4) ) Read(tmp); /* read existing mail */
else
if( ! strnicmp (tmp,"tag",3) ) Tag(tmp); /* read existing mail */
else
switch( (int) tmp[0] )
{
case '?' :
help();
break;
case '!' :
if( tmp[1] )
{
system(&tmp[1]);
}
else
{
ptr = getenv("COMSPEC");
system(ptr);
}
break;
case 'a' :
case 'A' :
Display();
break;
case 'e' :
case 'E' :
reply(ENTER);
break;
case 'j' :
case 'J' :
chconf(tmp);
break ;
case 'm' :
case 'M' :
ansi = ansi ? 0 : 1;
yellow(); high();
printf("%s %s .\n",txt[84], ansi ? txt[85] : txt[86]);
/* Mode ansi on / off */
break ;
case 'q' :
case 'Q' :
case 'g' :
case 'G' :
UpdateConf(); /* Save current conf pointer */
if( ReplyExist)
{
red(); high();
printf("%s\n%s %s.\n",txt[2],txt[3],CurBoard); /* Warning, you have */
printf("%s",txt[4]); /* Replies,pack them ?*/
if( YesNo(YES))
PackReply();
}
clear();
return ;
case 'n' :
case 'N' :
AutoJoin();
break;
case 'r' :
case 'R' :
reply(REPLY);
break;
case 's' :
case 'S' :
SaveMsg(tmp);
break;
case '+' :
case 0 :
ReadNext( NEXT );
break ;
case '-' :
ReadNext( PREVIOUS );
break ;
}
}
}
void load(name)
char *name ;
{
char BoardName[50];
char tmp2 [MAXPATHS];
char tmp [MAXPATHS];
char OldDat [MAXPATHS];
char NewDat [MAXPATHS];
struct stat Oldst;
struct stat Newst;
if( ReplyExist)
{
red();
high();
printf("%s\n%s %s.\n",txt[2],txt[3],CurBoard); /* Warning, you have */
printf("%s",txt[4]); /* Replies,pack them ?*/
if( YesNo(YES))
PackReply();
}
BoardName[0] = 0;
sscanf(name,"%s %s",tmp,BoardName);
if( ! BoardName[0] )
{
red();
printf("%s %s\n",txt[ 87 ], txt [ 88 ]); /* "usage" " load.." */
return;
}
printf("%s %s\n",txt[5],BoardName);
sprintf(tmp,"%s%s.qwk",MailPath,BoardName);
if( access(tmp,0 ) )
{
red();
printf ("%s : %s\n",txt[ 6 ],tmp); /* No mail found */
printf ("%s\n",txt[7]); /* Try the read command */
return ;
}
Clean(); /* Don't forget to clean work directory ! */
sprintf(tmp2,"%s %s %s %s %s %s? %s? %s ",
UnArchiver,tmp,CNTRL_FILE,MSG_FILE,NEWFILES,NEWS,WELCOME,WorkPath);
yellow();
high();
printf("%s\n",txt[8]); /* " Extracting Messages..." */
green();
system(tmp2);
yellow();
sprintf(tmp2,"%s%s",HomePath,BoardName); /* Access to a board subdir */
if( access(tmp2,0) )
mkdir(tmp2);
sprintf(OldDat,"%s%s/%s",HomePath,BoardName,CNTRL_FILE);
sprintf(NewDat,"%s/%s", WorkPath,CNTRL_FILE);
if(stat( OldDat,&Oldst) != -1 ) /* If exists an old control.dat */
{
stat( NewDat,&Newst );
if( Newst.st_mtime <= Oldst.st_mtime )
{
red();
high();
printf("%s\n%s.\n",txt[ 2 ], txt[ 11 ] ); /*"New packet older..."*/
printf("%s...",txt[ 12 ]); /*" Do you want to.." */
if( ! YesNo( NO ) )
return ;
}
}
strcpy(CurBoard,BoardName);
MkIndex(WorkPath,tmp2 ); /* Create Index Files */
IsEmpty = 0 ;
GetConf(0); /* load main board. */
}
/*
Join a BBS without extracting new mail.
*/
void Read(name)
char *name ;
{
char BoardName[50];
char tmp [MAXPATHS];
if( ReplyExist)
{
red();
printf("%s\n%s %s.\n",txt[2],txt[3],CurBoard); /* Warning, you have */
printf("%s",txt[4]); /* Replies,pack them ?*/
if( YesNo(YES))
PackReply();
}
BoardName[0] = 0;
sscanf(name,"%s %s",tmp,BoardName);
if( ! BoardName[0] )
{
red();
printf("%s %s\n",txt[ 87 ], txt [ 89 ]); /* "usage " "read..." */
return;
}
printf("%s %s\n",txt[ 5 ], BoardName); /* "Loading" */
sprintf(tmp,"%s%s",HomePath,BoardName);
if( access(tmp,0 ) )
{
printf ("%s : %s\n",txt[ 13 ] ,tmp); /* "No bbs found " */
return ;
}
if( ReadControl(tmp) )
{
printf("%s\n",txt[ 14 ] ); /* "Error in CONTROL.DAT." */
return ;
}
strcpy(CurBoard,BoardName);
IsEmpty = 0;
GetConf(0);
}
/*
CHCONF : Change active conference.
*/
void chconf(buf)
char *buf;
{
char Name[50];
char tmp [MAXPATHS];
int i ;
if( IsEmpty )
{
EmptyMsg();
return ;
}
Name[0] = 0;
sscanf(buf,"%s %s",tmp,Name);
if( ! Name[0] )
{
red();
printf("%s\n",txt[ 87]); /* "Usage" */
printf("\tj %s\n\t\t%s\n",txt[90],txt[91]); /*"Conf #" "or" */
printf("\tj %s\n",txt[92]); /*"conf name" */
printf("%s\n",txt[93]); /*"type conf to list..."*/
return;
}
if( Numeric( Name ) ) /* a number is given */
{
i = atoi(Name) ;
strcpy( Name,ConfName[i] );
}
else /* a name is given */
{
for( i = 0 ; i < MAXCONF ; i++ )
if( !stricmp(Name,ConfName[i] ))
break;
}
if( ! strnicmp(Name,"MAIN",4)) i = 0 ; /* Special case for "main board" */
if( i == MAXCONF )
{
red();
printf("%s\n",txt[ 28 ]); /* "Unknown conference" */
return ;
}
sprintf(tmp,"%s%s/%d.cnf",HomePath,CurBoard,i);
if( access(tmp,0 ) )
{
red();
printf ("%s : %s\n",txt[ 6 ],tmp); /* "No mail found" */
return ;
}
UpdateConf(); /* Save current conf pointer */
GetConf(i);
blue();
high();
printf("\n * %s %s %s. *\n\n",txt[29], ConfName[CurConf],txt[ 30 ]);
/* "Conference " "joined" */
}
/*
Loads next valid conferences.
*/
void AutoJoin()
{
static char *Default = "j 0\n";
char tmp[MAXPATHS];
int i;
if( IsEmpty )
{
EmptyMsg();
return ;
}
i = CurConf ;
while( i < MAXCONF )
{
i++ ;
sprintf(tmp,"%s%s/%d.cnf",HomePath,CurBoard,i);
if(! access (tmp,0 ) )
{
sprintf(tmp,"j %d\n",i );
chconf(tmp);
if( Index.LastRead == (TotMsg - 1) )
{
printf("\t%s.\n",txt[ 31 ]); /* "No new mail" */
continue;
}
return ;
}
}
chconf(Default); /* Default to Main Board. */
}
/*
Save current message in text file ( append mode ).
*/
void SaveMsg(str)
char *str;
{
char dummy [50];
char fname [MAXPATHS];
char *ptr ;
FILE *fp ;
int i,apflag ;
if( IsEmpty )
{
EmptyMsg();
return ;
}
fname[0] = 0 ;
sscanf(str,"%s %s",dummy,fname );
if( ! fname[0] )
{
high();
yellow();
printf("%s : ",txt[ 39 ]); /* "save message in file" */
clear();
fget(fname,12,stdin);
if( ! fname[0] )
{
printf("%s.\n",txt[ 40 ] ); /* "Aborted" */
return ;
}
}
apflag = access(fname,0) ? 1 : 0 ;
if( ( fp = fopen(fname,"a")) == NULL )
{
red();
high();
printf("%s %s\n",txt[ 51 ],fname ); /* "unable to open file" */
return ;
}
if( setvbuf(fp,NULL,_IOFBF,VBUF) )
printf("%sSavemsg()\n",txt[ 94 ]); /* "Setvbuf failed..." */
PrintHeader(fp);
ptr = (char *) (rbuf + sizeof(struct MsgHeaderType ) );
i = 0 ;
while (i < Index.Size)
{
if( *ptr != 0)
fputc( *ptr , fp ) ;
i++;
ptr++ ;
}
fprintf(fp,"\n");
blue();
high();
/*printf("Message %s",apflag ? "Saved in" : "Appended to");*/
printf("%s %s",txt[ 41], apflag ? txt[ 42 ] : txt[ 43 ]);
clear();
cyan();
printf(" %s\n",fname );
fclose(fp);
}
/*
Help message.
*/
void help()
{
int i;
white();
high();
printf("\n%s", hlp[1] );
clear();
printf("\n");
for( i = 0 ; i < strlen(hlp[1]) ; i++ )
putchar('-');
printf("\n");
high();
printf("\r\t q,g\t%s\n", hlp[ 2 ]);
printf("\t ?\t%s\n" , hlp[ 3 ]);
printf("\t !\t%s\n" , hlp[ 4 ]);
printf("\t +\t%s\n" , hlp[ 5 ]);
printf("\t -\t%s\n" , hlp[ 6 ]);
printf("\t a\t%s\n" , hlp[ 7 ]);
printf("\t e\t%s\n" , hlp[ 8 ]);
printf("\t j\t%s\n" , hlp[ 9 ]);
printf("\t m\t%s\n" , hlp[ 10 ]);
printf("\t n\t%s\n" , hlp[ 11 ]);
printf("\t r\t%s\n" , hlp[ 12 ]);
printf("\t s\t%s\n" , hlp[ 13 ]);
printf("\t conf\t%s\n" , hlp[ 14 ]);
printf("\t clean\t%s\n", hlp[ 15 ]);
printf("\t load\t%s\n" , hlp[ 16 ]);
printf("\t read\t%s\n" , hlp[ 17 ]);
printf("\t files\t%s\n", hlp[ 18 ]);
printf("\t tag\t%s\n" , hlp[ 19 ]);
printf("\t head\t%s\n" , hlp[ 22 ]);
printf("\t news\t%s\n" , hlp[ 20 ]);
printf("\t welcome\t%s\n" , hlp[ 21 ]);
printf("\n");
}
/*
Change Reader Signature :-)
*/
void Tag(line)
char *line ;
{
byte dummy[50];
byte tmp [256];
byte *ptr;
#if __DISTRIB__
magenta(); high();
printf("%s",txt[ 95 ] ); /* "Unauthorized command" */
return ;
#else
tmp[0] = 0 ;
sscanf(line,"%s %s",dummy,tmp);
if( ! tmp[0] ) /* restore standard tag */
{
clear();red();
strcpy(CurTag,TagLine);
printf("%s\n",txt[ 87 ]); /* "usage:" */
printf("\tTag < New Tag Line >.\n");
green();
printf("\r\tOriginal tag restored:");
cyan(); high();
printf("%s",CurTag);
return;
}
if( tmp[0] == '?' ) /* Print current tag */
{
ptr = CurTag ;
while( *ptr ) /* printable form... */
{
if (*ptr == 227 )
*ptr = '\n';
ptr++;
}
green();
printf("Current TagLine is :");
cyan(); high();
printf("%s",CurTag);
return ;
}
/* Change Tag */
strcpy(CurTag,"\n---\n");
strcat(CurTag,line + 4 );
strcat(CurTag,"\n\n");
ptr = CurTag ;
while( *ptr ) /* printable form... */
{
if (*ptr == 227 )
*ptr = '\n';
ptr++;
}
green();
printf("Tag is now set to :");
cyan(); high();
printf("%s",CurTag);
#endif
}
/*
Print Next,previous or current message.
*/
void ReadNext(mode)
int mode ;
{
int Head = sizeof( struct MsgHeaderType );
long here;
if( IsEmpty )
{
EmptyMsg();
return ;
}
if( mode == PREVIOUS )
{
here = ftell( fidx ) - (long )( 2 * sizeof(struct MyIndex) );
if( here < 0L )
{
printf("%s\n",txt[ 15 ]); /* "First message !" */
return ;
}
if( fseek( fidx, here , SEEK_SET ) )
{
printf("%s.\n",txt[16]); /* "Seek error" */
return ;
}
}
if( fread(&Index.LastRead,1,sizeof(struct MyIndex),fidx)
!= sizeof( struct MyIndex ) )
{
printf("%s\n",txt[ 17 ]); /* "End of messages." */
AutoJoin();
return ;
}
if( fseek(fmsg, Index.Offset, SEEK_SET ) )
{
printf("%s!\n",txt[ 16 ]); /* "Seek Error" */
return ;
}
if( (fread((char *)rbuf,1,Index.Size + Head,fmsg)) != Index.Size + Head )
{
printf("%s? \n",txt[ 18 ]); /* "Read error" */
return ;
}
Display();
}
/*
Prints the Qmail message header pointed by buf .
*/
void PutHeader()
{
struct MsgHeaderType *Header ;
static byte *Space = "\t\t\t";
Header = ( struct MsgHeaderType *) rbuf ;
/* printf("\nConf. : %d Read: %d Delete: %d",
Header->Conference,Header->Read,Header->Delete);*/
/* First line */
high();
green();
printf("\n%s",txt[ 19 ]); /* " From :" */
yellow();
nprint(Header->Author, 25); printf(Space);
green();
printf( "%s",txt[ 23]); /* "Number" */
yellow();
nprint(Header->NumMsg, 7);
/* Second line */
green();
printf("\n%s",txt[ 20 ]); /* "To:" */
red();
if( ! strnicmp(UserName, Header->ForWho,strlen(UserName ) ) )
blink();
nprint(Header->ForWho, 25); printf(Space);
clear(); green(); high();
printf( "%s",txt[24]); /* " Ref # " */
red();
nprint(Header->RefMsg, 7);
green();
printf("\n%s",txt[ 21 ]); /* "Subject" */
cyan();
nprint(Header->Subject, 25); printf(Space);
green();
printf( "%s",txt[ 25 ]); /* "Conf : " */
magenta();
/* printf("%d",Header->Conference);*/
printf("%s",ConfName[ Header->Conference ] );
green();
printf("\n%s",txt[ 22 ]); /* "date:" */
red();
nprint(Header->MsgDate, 8);
green();
printf( "%s",txt[ 26 ]); /* "time:" */
red();
nprint(Header->MsgTime, 5);
clear(); blue();
printf("\t[%d/%d]",Index.MsgNum +1 ,TotMsg); /* 0 based, print 1 based. */
if(Header->Status == '+' || Header->Status == '*')
{
printf("\t\t");
red(); high();
printf(" %s%c\n",txt[ 27 ],7); /* "PRIVATE MESSAGE" */
}
printf("\n\n");
clear();
cyan();
}
/*
Prints the Qmail message header in file fp.
*/
void PrintHeader(fp)
FILE *fp;
{
struct MsgHeaderType *Header ;
static byte *Space = "\t\t\t";
Header = ( struct MsgHeaderType *) rbuf ;
/* printf("\nConf. : %d Read: %d Delete: %d",
Header->Conference,Header->Read,Header->Delete);*/
/* First line */
fprintf(fp,"\n%s",txt[19]); /* "from:" */
nfprint(fp,Header->Author, 25); fprintf(fp,Space);
fprintf(fp, "%s",txt[23]); /* "number:" */
nfprint(fp,Header->NumMsg, 7);
/* Second line */
fprintf(fp,"\n%s",txt[ 20 ]); /* "to :" */
nfprint(fp,Header->ForWho, 25); fprintf(fp,Space);
fprintf(fp, "%s",txt[24]); /* "ref#" */
nfprint(fp,Header->RefMsg, 7);
fprintf(fp,"\n%s",txt[ 21 ] ); /* "subj." */
nfprint(fp,Header->Subject, 25); fprintf(fp,Space);
fprintf(fp, "%s",txt[ 25 ]); /* "Conf : " */
/* printf("%d",Header->Conference);*/
fprintf(fp,"%s",ConfName[ Header->Conference ] );
fprintf(fp,"\n%s",txt[ 22 ] ); /* "date :" */
nfprint(fp,Header->MsgDate, 8);
fprintf(fp, "%s",txt[ 26 ] ); /* "time:" */
nfprint(fp,Header->MsgTime, 5);
fprintf(fp,"\t[%d/%d]",Index.MsgNum +1, TotMsg ); /* 0 based, print 1 based. */
if(Header->Status == '+' || Header->Status == '*')
{
fprintf(fp,"\t\t");
fprintf(fp," %s\n",txt[ 27 ]); /* "PRIVATE MESSAGE" */
}
fprintf(fp,"\n\n");
}
/*
Reply to current message or enter a message
-------------------------------------------
*/
void reply(mode)
int mode ;
{
char fname [MAXPATHS];
char cmd [MAXPATHS];
char tmp [MAXPATHS];
char dummy [MAXPATHS];
struct MsgHeaderType *Header ;
struct QmailRepType Qmail ;
if( IsEmpty )
{
EmptyMsg();
return ;
}
Header = ( struct MsgHeaderType *) rbuf ;
sprintf(fname,"%s/$tmp.$$$" , WorkPath); /* Temporary file */
sprintf(cmd , "%s %s",Editor , fname ); /* Editor command */
ResetHeader( &Qmail );
blue();
high();
printf("\n%s\n\n",txt[ 32 ]); /* "Enter 'n' to abort entry..." */
moreto:
green();
scpy( dummy, Header->Author , 25 );
printf(" To [ %25s ] : ",(mode == REPLY ) ? dummy : "ALL");
white();
fget(tmp,50,stdin);
if( tmp[0] )
{
strupr(tmp);
if( ! strcmp(tmp,"N") )
{
blue();
printf("%s.\n",txt[ 33 ] ); /* "message aborted" */
return ;
}
if(strlen(tmp) > 25 )
{
red();
printf("%s\n",txt[ 34 ]); /* "Entry too long ! 25 chars max" */
goto moreto ;
}
str2mem( Qmail.ForWho,tmp );
}
else
str2mem( Qmail.ForWho,(mode == REPLY ) ? dummy : "ALL");
moresub:
green();
scpy( dummy, Header->Subject , 25 );
printf(" Subject [ %25s ] : ",(mode == REPLY ) ? dummy : "");
white();
fget(tmp,50,stdin);
if( ! strcmp(tmp,"N") || ! strcmp(tmp,"n") )
{
blue();
printf("%s.\n",txt[ 33 ] ); /* "message aborted" */
return ;
}
if( tmp[0] )
{
if(strlen(tmp) > 25 )
{
red();
printf("%s\n",txt[ 34 ]); /* "Entry too long ! 25 chars max" */
goto moresub ;
}
str2mem(Qmail.Subject,tmp );
}
else
str2mem(Qmail.Subject,(mode == REPLY ) ? dummy : "*" );
moresec:
green();
if( mode == REPLY )
printf(" Security [ %25s ] : ",
(Header->Status == '+') ? "R (private)" : "N (public )");
else
printf(" Security [ %25s ] : ", "N (public )");
white();
fget(tmp,50,stdin);
if( tmp[0] )
{
strupr(tmp);
if(strlen(tmp) > 2 )
{
red();
printf("%s\n",txt[ 35 ]); /* "Too long! R=...etc..." */
goto moresec ;
}
if( tmp[0] == 'R' )
{
Qmail.Status = 0x2A ;
Qmail.Unknown2 = 0x04 ;
green();
printf("%s.\n",txt[ 36 ]); /* "Receiver only" */
}
}
else /* Default selection */
if( Header->Status == '+' || Header->Status == '*')
{
Qmail.Status = 0x2A ;
Qmail.Unknown2 = 0x04 ;
green();
printf("%s.\n",txt[ 36 ]); /* "Receiver only" */
}
str2mem(Qmail.Author,UserName); /* Right name in the from field... */
sprintf (dummy,"%2d",CurConf );
str2mem(Qmail.ConfNum,dummy ); /* Msg goes to the current conference */
scpy( dummy, Header->NumMsg ,7);
str2mem(Qmail.RefMsg,(mode == REPLY ) ? dummy : "" );
if( mode == REPLY )
QuoteMsg(fname); /* Quote original message... */
printf("%s\n",txt[ 38 ]); /* "calling editor" */
system(cmd); /* Edit message.... */
AddReply(fname,(struct QmailRepType *) &Qmail.Status);
}
/*
Add the reply to a Qmail reply.msg file.
*/
void AddReply(fname,Qmail)
char *fname;
struct QmailRepType *Qmail;
{
OpenRepFile();
if( CodeMessage(fname,Qmail) )
return ;
ReplyExist = 1 ;
}
/*
LIST CONF : Prints conferences numbers,names, and status.
*/
void ListConf()
{
int i,line ;
char tmp[MAXPATHS];
if( IsEmpty )
{
EmptyMsg();
return ;
}
cls();
magenta(); high();
printf("\r\t\t\t%s %s\n",txt[78],BoardName); /* "Liste des conf. sur" */
clear(); red();
printf("\r\t\t\t");
for( i = 0 ; i < (strlen(txt[78]) + strlen(BoardName) + 1 ); i++)
putchar('-');
putchar('\n');
for( i = 0, line = 0 ; i <= LastConf ; i++ )
{
line++;
if( line > SCREENLINES - 5 )
{
line = 0 ;
printf("\n");
if( ! more(YES) )
break ;
cyan();
}
sprintf(tmp,"%s%s/%d.cnf",HomePath,CurBoard,i);
red(); high();
printf("\n\t\t%3d ",i);
clear(); blue();
printf("......... ");
magenta(); high();
printf("%10s ",ConfName[i] );
clear(); blue();
printf("......... ");
high();
if( access(tmp,0) )
{
printf("%s",txt[79]); /* "Inactive" */
}
else
{
magenta();
printf("%s",txt[80]); /* "active" */
}
}
clear();
printf("\n");
}
/*
Goes to the msg number represented by the string. and print it.
( Internal count, not BBS numbers ! )
*/
void GoToNum( str )
char *str ;
{
int nb ;
int Head = sizeof( struct MsgHeaderType );
if( IsEmpty )
{
EmptyMsg();
return ;
}
nb = atoi( str );
nb -- ;
if( nb < 0 || nb > TotMsg )
{
red();high();
printf("%s\n",txt[ 81 ]); /* "Number out of range ! " */
printf("%s " ,txt[ 82 ]); /* "Valid msgs are" */
magenta();
printf("1 ");
red();
printf("%s ",txt[ 83 ]); /* "to" */
magenta();
printf("%d\n",TotMsg);
return;
}
if( fseek( fidx,(long) nb * (long) sizeof(struct MyIndex ) , SEEK_SET ) )
{
printf("%s !\n",txt[ 16]); /* "seek error" */
return ;
}
if( fread(&Index.LastRead,1,sizeof(struct MyIndex),fidx)
!= sizeof( struct MyIndex ) )
{
printf("%s\n",txt[ 17 ]); /* "End of messages " */
}
if( fseek(fmsg, Index.Offset, SEEK_SET ) )
{
printf("%s !\n",txt[ 16 ]);
return ;
}
if( (fread((char *)rbuf,1,Index.Size + Head,fmsg)) != Index.Size + Head )
{
printf("%s ? \n",txt[ 18 ]); /* "read error" */
return ;
}
Display();
}
/*
DISPLAY : Prints the current message,stored in memory.
*/
void Display()
{
int line;
unsigned i;
register int count ;
int QuotedColor ;
char *ptr,*pt;
char tmp[MAXPATHS];
if( IsEmpty )
{
EmptyMsg();
return ;
}
cls();
PutHeader();
cyan();
line = 0;
i = 0 ;
count = 0;
ptr = (char *) (rbuf + sizeof(struct MsgHeaderType ) );
i = 0 ;
line = 0 ;
QuotedColor = 0 ;
pt = tmp ;
*pt = 0 ;
while (i < Index.Size)
{
if( count > MAXPATHS -1 ) /* Security for long lines */
*ptr = '\n' ;
if( *ptr == '\n' ) /* Display a total line */
{
count = 0 ;
*pt = 0 ;
line ++ ;
pt = tmp ;
if ( IsQuoted( '>',pt ) ) /* Process colors on quoted line */
{
while( *pt != '>' )
putchar(*pt++ );
QuotedColor = 1 ;
red(); /* Quote char in red... */
putchar(*pt++ );
green(); /* Quoted line in green.. */
puts(pt);
cyan();
pt = tmp ;
}
else
{
if( QuotedColor)
{
cyan();
QuotedColor = 0 ;
}
puts(tmp);
}
}
else
{
if( *ptr ) /* Non 0 chars */
{
*pt = *ptr ;
pt ++ ;
count ++ ; /* Security for line length ... */
}
}
i++;
ptr++ ;
if( line > SCREENLINES - 8 )
{
line = 0 ;
if( ! more(YES) )
break ;
cyan();
}
}
printf("\n");
}
/*
Welcome : Displays the welcome file.
*/
void Welcome(void)
{
char tmp[MAXPATHS];
if( ansi )
{
sprintf(tmp,"%s%s/%s",HomePath,CurBoard,WELCOMEG);
if(! access(tmp,0 ) )
{
sprintf(tmp,"%s%s",HomePath,CurBoard);
view(tmp,WELCOMEG);
return ;
}
}
sprintf(tmp,"%s%s/%s",HomePath,CurBoard,WELCOME);
if(! access(tmp,0 ) )
sprintf(tmp,"%s%s",HomePath,CurBoard);
view(tmp,WELCOME);
}
/*
GETBBS :
Called by main() with argv[1].
Looks for a new QWK packet, if older than message base,
just loads the base.
*/
void GetBbs( name )
char *name;
{
char tmp [MAXPATHS];
char packet [MAXPATHS];
char base [MAXPATHS];
struct stat Oldst;
struct stat Newst;
strcpy(tmp,name);
strcat(tmp,".qwk");
sprintf(packet,"%s%s",MailPath,tmp);
if( access(packet,0) ) /* No new mail found */
{
printf("%s\n",txt[31]); /* "no new mail" */
Read( name );
return ;
}
sprintf(base,"%s%s/%s",HomePath,name,CNTRL_FILE);
if( access(base,0 ) )
{
printf("%s. ",txt[45] ); /* New BBS in this base. */
sprintf(tmp,"load %s",name);
load(tmp);
return ;
}
stat( packet,&Newst);
stat( base ,&Oldst);
if( Newst.st_mtime <= Oldst.st_mtime )
{
blue(); high();
printf("%s. %s.\n",txt[ 46] , txt[ 47 ]);
sprintf(tmp,"read %s",name);
Read(tmp);
return ;
}
sprintf(tmp,"load %s",name);
load(tmp);
}
void Purge()
{
int i;
char tmp[80];
char cnf[MAXPATHS];
char idx[MAXPATHS];
struct stat st ;
if( IsEmpty )
{
EmptyMsg();
return ;
}
magenta();high();
printf("Effacement sélectif des conférences.\n");
/* Selective deleting of areas */
clear();
red();
printf("-------------------------------------\n\n");
for( i = 0 ; i < LastConf ; i++ )
{
sprintf(cnf,"%s%s/%d.cnf",HomePath,CurBoard,i);
sprintf(idx,"%s%s/%d.idx",HomePath,CurBoard,i);
if( stat(cnf,&st) == -1 )
continue; /* No such file */
onemore :
green();high();
printf("Conf. %d [ ",i);
yellow();
printf("%s",ConfName[i] );
green();
printf(" ] takes ");
yellow();
printf("%ld",st.st_size);
green();
printf(" bytes. Delete it (Y)es (N)o (S)top ? : ");
fget(tmp,5,stdin);
strupr(tmp);
switch( (int) tmp[0] )
{
case 'N' :
break ;
case 'S' :
return ;
case 'Y' :
case 'O' :
case 'J' :
if( unlink(cnf ) == - 1 )
printf("Unable to remove file %s\n",cnf);
if( unlink(idx ) == - 1 )
printf("Unable to remove file %s\n",idx);
blue();
if( i == CurConf )
{
Index.LastRead = 0 ;
Index.MsgNum = 0 ;
TotMsg = 0 ;
}
printf("Conference %d is now empty.\n\n",i);
if( i == CurConf )
{
Index.LastRead = 0 ;
Index.MsgNum = 0 ;
TotMsg = 0 ;
AutoJoin();
}
break ;
default:
goto onemore ;
}
}
}