home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
TELECOM
/
GNU_ATP_1_40.lzh
/
SRC
/
read.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-09-11
|
50KB
|
2,301 lines
/*
ATP QWK MAIL READER FOR READING AND REPLYING TO QWK MAIL PACKETS.
Copyright (C) 1992 Thomas McWilliams
Copyright (C) 1990 Rene Cougnenc
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or ( at your option )
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* Change Log: $Log: read.c,v $
* Revision 1.400 1992/11/28 09:54:05 root
* second release
*
* Revision 1.310 1992/07/08 23:15:14 root
* first release -- minor bug fix in read.c
*
* Revision 1.30 1992/07/05 15:36:19 root
* first release of ATP
*
* Revision 1.2 1992/04/19 12:50:02 root 1st semifunctional UNIX version.
*
*/
/* define prompts */
#define PRMT1 "%s [ %s ] > "
#define PRMT2 "%s [ %s ] > "
#define PRMTFR " From: "
#define PRMTTO " To: "
#define PRMTSB " Subject: "
#define PRMTSC " Security: "
#include <stdio.h>
#include <strings.h>
#include <time.h>
#include <types.h>
#include <modes.h>
#include "system.h"
#include "ansi.h"
#include "makemail.h"
#include "qlib.h"
#include "reader.h"
#include "readlib.h"
/* external function declarations */
char *getenv(); /* standard library */
void *malloc(); /* standard library */
void restore_term(); /* file: system.c */
void setup_term(); /* file: system.c */
char *tempnam(); /* file: system.c */
/* global function declarations */
int main();
/* static function declarations */
static void Purge();
static void scruter();
static int findtxt();
static char *findstr();
static int FindActive();
static void showterms();
static void ReadShell();
static void togltag();
static void Load();
static void Read();
static void chconf();
static void AutoJoin();
static void SaveMsg();
static void Help();
static void Tag();
static int ReadNext();
static void PutHeader();
static void PrintHeader();
static void Reply();
static int AddReply();
static void ListConf();
static void GoToNum();
static int SeekNum();
static void Display();
static void Welcome();
static void GetBbs();
/* end of static function declarations */
/* constant declarations */
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define NEXT 0
#define AGAIN 1
#define PREVIOUS 2
#define SCAN 3
#define FIND 4
#define KILL 5
#define NUKE 9
#define PRIVATE 13
#define RPT_MASK 0x03 /* lower 2 bits used for display mode repeat constant */
#ifndef SEP
#define SEP '/'
#endif
#ifndef SHELL
#define SHELL "SHELL"
#endif
/* global variables */
char *TagLine = NTAG; /* PCBoard style tagline */
char *FidoTag = FTAG; /* Fidonet style tagline */
char CurTag[256]; /* Tag line chosen... */
char UserTag[256]; /* Save run time defined tag-lines */
char OrigTag[256]; /* default tag from atprc config file */
static int dflag = TRUE; /* toggle for default and user defined tagline */
char HomePath[MAXPATHS]; /* Home directory 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... */
/* variables used by line editor */
char *luxptr; /* passed text to line editor for editing*/
/* variables set in configuration file */
int SCREENLINES = 25; /* default 25, changeable in config file */
int SaveConf = -1; /* save current conference */
long RbufSize = MYBUF;
char Editor[50]; /* Name of the standard text editor */
char Archiver[50];
char UnArchiver[50];
char qwklist[100]; /* command line for listing QWK packets */
char speller[100]; /* command line for invoking speller */
int autotag = TRUE; /* flag for random taglines */
int graphics = FALSE; /* flag for vt100 graphics mode */
int charset = CHR7BIT; /* which char set? 4 is dummy = undefnd.*/
int fido = FALSE; /* Flag for tagline style */
int ansi = TRUE; /* Flag true if ansi output is on */
/* variables used for reading, checking, writing, closing files */
struct MyIndex Index;
FILE *fidx = NULL, *fmsg = NULL; /* Index File and msg file, globals */
int FilesOpen = FALSE; /* Flag if these files are open */
int FirstDone = FALSE; /* Set if 1st message in conf is read */
static int newmail = TRUE; /* used by AutoJoin() */
int ActvCnt = 0; /* tracks number of active conferences */
int CurConf; /* Number of current Conference... */
long int TotMsg; /* Number of messages in conf */
byte *rbuf; /* Pointer to work buffer for messages */
int pmail = FALSE; /* Flag indicates if personal mail waiting */
int ReplyExist = 0; /* Flag 1 if there are replies to pack */
static int IsEmpty = TRUE; /* Flag false if a BBS is loaded */
int HeadLetter = 1; /* Flag 1 if automatic header is active */
static int caps = FALSE; /* Flag for reply ENTER mode */
/*--------------------------------------------------------------------------*/
/* for OS-9 */
#define MAXCMDS 7
static char *cmds[MAXCMDS] =
{ "del", "dir", "makdir", "deldir", "chd", "copy", "list" };
/*--------------------------------------------------------------------------*/
int main( argc, argv )
int argc;
char *argv[];
{
if( strlen( getenv( "PATH" ) ) > ( size_t ) MAXPATHS )
{
printf( "PATH environment too long: %d\n", (size_t) MAXPATHS );
exit( -1 );
};
setup_term();
MakeHomePath();
if( ReadConfig() )
return( -1 );
if( ( ConfName = malloc( sizeof(string16)*2 ) ) == NULL )
return( -1 );
Clean();
clear();
bblack();
Title();
cyan();
strcpy( CurBoard, txt[10] ); /* First default prompt.... */
strcpy( ConfName[0], txt[9] ); /* "empty" */
if( fido )
strcpy( CurTag, FidoTag ); /* setup the default TagLines */
else
strcpy( CurTag, TagLine );
strcat( CurTag, OrigTag );
if( ( rbuf = (byte *) malloc( MYBUF ) ) == NULL )
{
printf( "%s\n", txt[1] ); /* Not enough memory */
printf( "%lu bytes\n", MYBUF );
return( 0xFF );
}
if( argc == 2 )
GetBbs( argv[1] );
if( autotag )
ChooseTag();
printf( "%s\n", CurTag );
ReadShell();
free( rbuf );
if( FilesOpen )
{
fclose( fidx );
fclose( fmsg );
}
free( ConfName );
free( ConfNumbers );
free( ConfActive );
Clean();
restore_term();
return( 0 );
}
/*
* Main Shell
*/
static void ReadShell()
{
char prompt[80];
char *tmp = NULL;
char *ptr;
int i;
while( 1 )
{
topcat:
luxptr = NULL;
if( pmail && ( CurConf == findCindex( PERS_CONF ) ) )
sprintf( prompt, PRMT2, CurBoard, ConfName[CurConf] );
else
sprintf( prompt, PRMT1, CurBoard, ConfName[CurConf] );
tmp = readline( prompt );
printf( "\r %-75s \r", " " );
clear();
fflush( stdout );
StripDel( tmp );
StripSpaceL( tmp );
/* Internal shell commands */
for( i = 0; i < MAXCMDS; i++ )
{
if( !strnicmp( tmp, cmds[i], strlen( cmds[i] ) ) )
{
system( &tmp[0] );
goto topcat; /* break from loop and take it from the top! */
}
}
if( Numeric( tmp ) )
GoToNum( tmp );
else if( !strnicmp( tmp, "show ", 5 ) )
showterms();
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, "fido", 4 ) )
togltag();
else if( !strnicmp( tmp, "find ", 5 ) )
( void ) findtxt( tmp, FIND );
else if( !strnicmp( tmp, "help", 4 ) )
Help();
else if( !stricmp( tmp, "last" ) )
{
sprintf( prompt, "%ld", TotMsg );
GoToNum( prompt );
}
else if( !stricmp( tmp, "next" ) )
( void ) findtxt( tmp, NEXT );
else if( !strnicmp( tmp, "scan", 4 ) )
scruter();
else if( !strnicmp( tmp, "ql", 2 ) )
Qlist( qwklist );
else if( !strnicmp( ( char * ) tmp, "graph", 4 ) )
{
if( graphics )
{
graphics = FALSE;
printf( "\n\t\t +------------------------------+\n" );
printf( "\t\t | |\n" );
printf( "\t\t | vt100 graphics are now OFF |\n" );
printf( "\t\t | |\n" );
printf( "\t\t +------------------------------+\n\n" );
}
else
{
graphics = TRUE;
printf( "\n\016\t\t lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk\n" );
printf( "\t\t xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaax\n" );
printf( "\t\t xaa\017 vt100 graphics are now ON\016 ax\n" );
printf( "\t\t xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaax\n" );
printf( "\t\t mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj\n\n\017" );
}
}
else if( !strnicmp( tmp, "head", 4 ) )
{
blue();
high();
HeadLetter = HeadLetter ? 0 : 1;
printf( "%s ", txt[101] ); /* "Automatic H." */
printf( "%s\n", HeadLetter ? txt[85] : txt[86] ); /* "on" / "off" */
}
else if( !strnicmp( tmp, "news", 4 ) )
{
if( ansi )
{
sprintf( tmp, "%s%s%c%s", HomePath, CurBoard, SEP, NEWSG );
if( !access( tmp, S_IREAD ) )
{
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 ) )
{
if( ( !IsEmpty ) && ConfActive[CurConf] )
UpdateConf( UPDATE );
Load( tmp ); /* Load new mail */
}
else if( !strnicmp( tmp, "merde", 5 ) )
merde();/* Load new mail */
else if( !strnicmp( tmp, "rev", 3 ) )
{
if( ( !IsEmpty ) && ConfActive[CurConf] )
UpdateConf( UPDATE ); /* Save current conf pointer */
Read( tmp ); /* read existing mail */
}
else if( !strnicmp( tmp, "tag", 3 ) )
Tag( tmp ); /* change tagline */
else if( !stricmp( tmp, "reset" ) )
{
UpdateConf( RESET );
}
else if( tmp[0] == '\0' || tmp[1] == '\0' || tmp[1] == '\040' )
{
switch ( tmp[0] )
{
case '!':
if( tmp[1] )
{
system( ( char * ) &tmp[1] );
}
else
{
ptr = getenv( SHELL );
if( ptr )
system( ptr );
}
break;
case 'c':
case 'C':
if( CurConf == RCONF_IDX && FirstDone )
Reply( EDIT, tmp );
break;
case 'e':
case 'E':
if( CurConf == RCONF_IDX && tmp[1] == '\0' )
{
if( FirstDone )
Reply( EDIT, tmp );
}
else
{
Reply( ENTER, tmp );
}
break;
case 'j':
case 'J':
chconf( tmp );
break;
case 's':
case 'S':
SaveMsg( tmp );
break;
default:
break;
}
if( !tmp[1] || !tmp[0] )
switch( ( int ) tmp[0] )
{
case '?':
Help();
break;
case 'a':
case 'A':
if( FirstDone )
Display( 0 );
else
ReadNext( NEXT );
break;
case 'k':
case 'K':
if( CurConf == RCONF_IDX )
ReadNext( KILL );
break;
case 'm': /* toggle ANSI mode on/off */
case 'M':
ansi = ansi ? FALSE : TRUE;
yellow();
high();
printf( "%s %s .\n", txt[84], ansi ? txt[85] : txt[86] );
break;
case 'p':
case 'P':
if( CurConf == RCONF_IDX )
ReadNext( PRIVATE );
break;
case 'q':
case 'Q':
case 'g':
case 'G':
if( !IsEmpty )
UpdateConf( UPDATE ); /* Save current conf pointer */
if( FilesOpen )
{
fclose( fidx );
fclose( fmsg );
FilesOpen = FALSE;
}
if( ReplyExist )
{
red();
high();
/* Warning, you have */
printf( "%s\n%s %s.\n", txt[2], txt[3], CurBoard );
/* Replies,pack them ? */
sprintf( prompt,"%s", txt[4] );
if( YesNo( YES,prompt ) )
PackReply();
}
clear();
return;
case 'n':
case 'N':
AutoJoin();
break;
case 'r':
case 'R':
if( FirstDone && CurConf != RCONF_IDX )
Reply( REPLY, tmp );
break;
case '+':
case 0:
ReadNext( NEXT );
break;
case '-':
ReadNext( PREVIOUS );
break;
}
}
}
}
static void
togltag( /* void */ )
{ /* switch tagline styles */
fido = ( fido ? FALSE : TRUE );
Tag( "tag \177" );
}
static void
Load( name )
char *name;
{
char BbsName[50];
char tmp3[MAXPATHS];
char tmp2[MAXPATHS];
char tmp[MAXPATHS];
char OldDat[MAXPATHS];
char NewDat[MAXPATHS];
char prmbuf[80]; /* buffer for prompt passed to YesNo */
char *tptr;
int oldage;
int newage;
int i;
pmail = FALSE; /* reset global flag to indicate no personal mail yet */
if( ReplyExist )
{
red();
high();
/* Warning, you have Replies,pack them ? */
printf( "%s\n%s %s.\n", txt[2], txt[3], CurBoard );
sprintf( prmbuf,"%s", txt[4] );
if( YesNo( YES,prmbuf ) )
PackReply();
ReplyExist = FALSE;
}
BbsName[0] = '\0';
sscanf( name, "%s %s", tmp, BbsName );
if( !BbsName[0] )
{
red();
printf( "%s %s\n", txt[87], txt[88] ); /* "usage" " load.." */
return;
}
printf( "%s %s\n", txt[5], BbsName );
if( strstr( BbsName, ".qw" ) == NULL )
strcat( BbsName, ".qwk" );
sprintf( tmp, "%s%s", MailPath, BbsName );
/*
* Now that we've used BbsName to id the packet file strip any
* trailing digits so the board's subdir doesn't vary w/ packet #.
*/
tptr = BbsName;
i = -1;
while ( BbsName[++i] );
while ( BbsName[--i] != '.' );
BbsName[i] = '\0';
if( !Numeric( tptr ) )
while ( isdigit( BbsName[--i] ) )
BbsName[i] = '\0';
if( access( tmp, S_IREAD ) )
{
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 ! */
yellow();
high();
printf( "%s\n", txt[8] ); /* " Extracting Messages..." */
green();
fflush( stdout );
getcwd( tmp3, sizeof( tmp3 ) ); /* save current directory */
chdir( WorkPath ); /* change to work directory */
sprintf( tmp2, "%s %s", UnArchiver, tmp ); /* build unzip command line */
system( tmp2 ); /* execute unzip in work dir */
chdir( tmp3 ); /* restore current directory */
yellow();
sprintf( tmp3, "%s%c%s", WorkPath, SEP, CNTRL_FILE );
if( access( tmp3, S_IREAD | S_IWRITE ) )
{
printf( "Error: can't find control file: %s\n", tmp3 );
return;
}
sprintf( tmp2, "%s%s", HomePath, BbsName ); /* Access to a board subdir */
if( access( tmp2, S_IREAD ) )
makdir( tmp2, S_IFDIR, S_IREAD | S_IWRITE );
sprintf( OldDat, "%s%s%c%s", HomePath, BbsName, SEP, CNTRL_FILE );
sprintf( NewDat, "%s%c%s", WorkPath, SEP, CNTRL_FILE );
if( ( oldage = fileage( OldDat ) ) != 0 )
{
if( fileage( NewDat ) <= oldage )
{
red();
high();
/* "New packet older..." */
printf( "%s\n%s.\n", txt[2], txt[11] );
/* " Do you want to ... " */
sprintf( prmbuf , "%s...", txt[12] );
if( !YesNo( NO,prmbuf ) )
return;
}
}
strcpy( CurBoard, BbsName );
/* Create Index Files */
MkIndex( WorkPath, tmp2 );
Chk4Rep();
Chk4Cnf( tmp2 );
if( FilesOpen )
{
fclose( fidx );
fclose( fmsg );
FilesOpen = FALSE;
}
IsEmpty = FALSE;
newmail = TRUE;
caps = !fido;
if( pmail )
CurConf = findCindex( PERS_CONF );
else
CurConf = FindActive( LastConf );
if( CurConf < 0 )
CurConf = 0;
GetConf( CurConf );
}
/*
* Join a BBS without extracting new mail.
*/
static void
Read( name )
char *name;
{
char BbsName[50];
char tmp[MAXPATHS];
if( ReplyExist )
{
red();
printf( "%s\n%s %s.\n", txt[2], txt[3], CurBoard ); /* Warning, you have */
sprintf( tmp,"%s", txt[4] ); /* Replies, pack them? */
if( YesNo( YES,tmp ) )
PackReply();
ReplyExist = FALSE;
tmp[0] = '\0';
}
BbsName[0] = 0;
sscanf( name, "%s %s", tmp, BbsName );
if( !BbsName[0] )
{
red();
printf( "%s %s\n", txt[87], txt[89] ); /* "usage " "read..." */
return;
}
printf( "%s %s\n", txt[5], BbsName ); /* "Loading" */
sprintf( tmp, "%s%s%c%s", HomePath, BbsName, SEP, CNTRL_FILE );
if( access( tmp, S_IREAD | S_IWRITE ) )
{
printf( "%s : %s\n", txt[13], tmp ); /* "No bbs found " */
return;
}
sprintf( tmp, "%s%s", HomePath, BbsName );
if( ReadControl( tmp ) )
{
printf( "%s\n", txt[14] ); /* "Error in CONTROL.DAT." */
return;
}
strcpy( CurBoard, BbsName );
Chk4Rep();
Chk4Cnf( tmp );
if( FilesOpen )
{
fclose( fidx );
fclose( fmsg );
FilesOpen = FALSE;
}
ActvConf(); /* update boolean array of active/inactive flags */
IsEmpty = FALSE;
newmail = FALSE;
caps = !fido;
CurConf = FindActive( LastConf );
if( CurConf < 0 )
CurConf = 0;
GetConf( CurConf );
}
/*
* CHCONF : Change active conference.
*/
static void chconf( buf )
char *buf;
{
char Name[50];
char tmp[MAXPATHS];
int i;
unsigned int m;
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 );
if( ( i = findCindex( i ) ) > -1 )
strcpy( Name, ConfName[i] );
}
else
{ /* a name is given */
m = strlen( Name );
for( i = 0; i <= LastConf; i++ )
{
if( !stricmp( Name, ConfName[i] ) )
break;
}
if( i > LastConf )
{
for( i = 0; i <= LastConf; i++ )
{
if( !strnicmp( Name, ConfName[i], m ) )
break;
}
}
}
if( !stricmp( Name, "MAIN" ) )
i = 0; /* Special case for "main board" */
if( i > LastConf || i < 0 )
{
printf( "\n%s\n", txt[28] ); /* "Unknown conference" */
return;
}
sprintf( tmp, "%s%s%c%d.cnf", HomePath, CurBoard, SEP, ConfNumbers[i] );
if( access( tmp, S_IREAD | S_IWRITE ) )
{
red();
printf( "%s : %s %s\n", txt[6], tmp, ConfName[i] ); /* "No mail found" */
return;
}
UpdateConf( UPDATE ); /* Save current conf pointer */
if( GetConf( i ) == ERROR )
return;
blue();
high();
printf( "\n * %s %s %s. *\n\n", txt[29], ConfName[CurConf], txt[30] );
/* "Conference " "joined" */
}
/*
* Loads next valid conferences.
*/
#define ILR Index.LastRead
static void AutoJoin()
{
char tmp[MAXPATHS];
int i, j;
if( IsEmpty )
{
EmptyMsg();
return;
}
if( !ActvCnt )
{
chconf( "j MAIN\n" );
return;
}
i = CurConf;
j = ActvCnt;
while ( j-- )
{
i = FindActive( i );
sprintf( tmp, "j %d\n", ConfNumbers[i] );
chconf( tmp );
if( ILR < 1 || ILR != ( TotMsg - 1 ) || !newmail )
{
return;
}
else
printf( "\t%s.\n", txt[31] ); /* "No new mail" */
}
newmail = FALSE;
printf( "\n" );
}
#undef ILR
/*
* Save current message in text file ( append mode ).
*/
static void SaveMsg( str )
char *str;
{
char dummy[MAXPATHS];
char fname[MAXPATHS];
byte *ptr;
FILE *fp;
unsigned long i;
int apflag;
if( IsEmpty )
{
EmptyMsg();
return;
}
fname[0] = 0;
sscanf( str, "%s %s", dummy, fname );
if( !fname[0] )
{
high();
yellow();
ptr = (byte *) readline( txt[39] );
clear();
fflush( stdout );
fname[0] = '\0';
if( ptr != NULL )
strcpy( fname, (char *) ptr );
if( !fname[0] )
{
printf( "%s.\n", txt[40] ); /* "Aborted" */
return;
}
}
apflag = access( fname, S_IWRITE ) ? 1 : 0;
if( ( fp = fopen( fname, "a" ) ) == NULL )
{
red();
high();
printf( "%s %s\n", txt[51], fname ); /* "unable to open file" */
return;
}
PrintHeader( fp );
ptr = ( byte * ) ( rbuf + sizeof( struct MsgHeaderType ) );
i = 0;
while ( i < Index.Size )
{
if( *ptr != 0 )
{
if( charset == ISOLAT1 )
putc( codelu[ ( unsigned ) ( *ptr ) ] , fp );
else if( charset == CHR7BIT )
putc( code7bit[( unsigned ) ( *ptr ) ] , fp );
else
putc( *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.
*/
static void Help()
{
unsigned 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 k\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] );
#ifdef ENGLISH
printf( "\t review\t%s\n", hlp[17] );
#else
printf( "\t revois\t%s\n", hlp[17] );
#endif
printf( "\t files\t%s\n", hlp[18] );
printf( "\t tag help\t%s\n", hlp[19] );
printf( "\t head\t%s\n", hlp[22] );
printf( "\t scan\t%s\n", hlp[24] );
printf( "\t qlist\t%s\n", hlp[23] );
printf( "\n" );
}
/*
* Change Reader Signature :-)
*/
static void Tag( line )
char *line;
{
char dummy[50];
char tmp[256];
char tmp2[256];
int i,j;
tmp2[0] = tmp[0] = 0;
sscanf( line, "%s %s %s", dummy, tmp, tmp2 );
if( tmp2[0] == 0 && ( strnicmp( ( char * ) tmp, "list", 4 ) == 0 ) )
{ /* list taglines */
sprintf( tmp2, "%s%s", HomePath, TAGFILE );
printf( "%s\n", tmp2 );
if( !access( tmp2, S_IREAD ) )
{
tmp[0] = 0;
sprintf( tmp, "%s", HomePath );
tagview( tmp, TAGFILE );
}
printf( "\nDefault Tag : %s", OrigTag );
printf( "User defined: %s", UserTag );
printf( "\n" );
return;
}
if( tmp2[0] == 0 && Numeric( ( char * ) tmp ) )
{ /* try to get a tagline from the list */
i = atoi( ( char * ) tmp );
i = i < 0 ? -i : i;
TagSeek( i );
printf( "Current Tag now set to:" );
printf( "%s\n", CurTag );
return;
}
if( tmp2[0] == 0 && tmp[0] == '?' )
{ /* Print current tag */
printf( "Current TagLine is:" );
printf( "%s\n", CurTag );
return;
}
if( tmp2[0] == 0 && ( strnicmp( ( char * ) tmp, "rand", 4 ) == 0 ) )
{ /* select tag at random */
ChooseTag();
printf( "Current Tag now set to:" );
printf( "%s\n", CurTag );
return;
}
if( ( tmp2[0] == 0 && ( strnicmp( ( char * ) tmp, "help", 4 ) == 0 ) ) || line[3] == '\0' )
{ /* select tag help menu */
white();
high();
printf( "\n%s", taghlp[1] );
clear();
printf( "\n" );
for( j = 0; j < ( int ) strlen( taghlp[1] ); j++ )
putchar( '-' );
printf( "\n" );
high();
printf( "\t tag list\t%s\n", taghlp[2] );
printf( "\t tag ? \t%s\n", taghlp[3] );
printf( "\t tag `n' \t%s\n", taghlp[4] );
printf( "\t tag random\t%s\n", taghlp[5] );
printf( "\t tag swap\t%s\n", taghlp[6] );
printf( "\t tag auto\t%s\n", taghlp[7] );
printf( "\t tag \t%s\n", taghlp[8] );
printf( "\t tag help\t%s\n", taghlp[9] );
printf( "\t fido \t%s\n", taghlp[10] );
printf( "\n" );
printf( "Current TagLine is:" );
printf( "%s\n", CurTag );
return;
}
if( tmp2[0] == 0 && ( strnicmp( ( char * ) tmp, "auto", 4 ) == 0 ) )
{ /* toggle autotag line selection */
if( autotag )
{
autotag = FALSE;
printf( "\nautotag is OFF\n\n" );
}
else
{
autotag = TRUE;
printf( "\nautotag is ON\n" );
ChooseTag();
printf( "Current Tag now set to:" );
printf( "%s\n", CurTag );
}
return;
}
if( ( tmp2[0] == 0 ) && ( strnicmp( ( char * ) tmp, "swap", 4 ) == 0 ) )
{ /* restore standard tag */
dflag = dflag ? FALSE : TRUE;
if( fido )
strcpy( CurTag, FidoTag );
else
strcpy( CurTag, TagLine );
if( dflag )
strcat( CurTag, OrigTag );
else
strcat( CurTag, UserTag );
printf( "Current Tag now set to:" );
printf( "%s\n", CurTag );
return;
}
if( !stricmp( ( char * ) tmp, "fido" ) )
{
fido = ( fido ? FALSE : TRUE );
tmp[0] = '\177';
}
if( tmp[0] == '\177' )
{ /* toggle fido tag */
strcpy( ( char * ) tmp, ( char * ) CurTag );
if( fido )
{
line = ( char * ) tmp + strlen( TagLine ); /* point to start of tag message */
strcpy( CurTag, FidoTag );
}
else
{
line = ( char * ) tmp + strlen( FidoTag );
strcpy( CurTag, TagLine );
}
strcat( CurTag, line );
printf( "Current Tag now set to:" );
printf( "%s\n", CurTag );
return;
}
if( line[3] == '\040' )
{
line += 4; /* Change current tag to User defined Tag */
strcpy( UserTag, line );
strcat( UserTag, "\n" );
if( fido )
strcpy( CurTag, FidoTag );
else
strcpy( CurTag, TagLine );
strcat( CurTag, UserTag );
dflag = FALSE;
printf( "Tag is now set to :" );
printf( "%s\n", CurTag );
}
}
/*
* Print Next,previous or current message.
*/
static int
ReadNext( /* const int */ mode )
int mode;
{
byte tchar;
long here;
size_t nrecs;
if( mode < 0 || mode > 13 )
return( 0 );
if( IsEmpty )
{
EmptyMsg();
return( 0 );
}
if( !FilesOpen )
{
printf( "%s \n", txt[44] ); /* no mail in conf */
if( mode == SCAN )
return( 0 );
else
AutoJoin();
return( 0 );
}
/* if needed, seek to new record in conference index file */
if( mode == KILL || mode == NUKE || mode == PREVIOUS || mode == PRIVATE )
{
here = ftell( fidx ) - ( long ) ( ( mode & RPT_MASK ) * sizeof( struct MyIndex ) );
if( here < 0L )
{
printf( "%s\n", txt[15] ); /* "First message !" */
return( 0 );
}
if( fseek( fidx, here, SEEK_SET ) )
{
printf( "%s.\n", txt[16] ); /* "Seek error" */
return( 0 );
}
}
/* get new index information and check for end of conference */
if( fread( &( Index.LastRead ), 1, sizeof( struct MyIndex ), fidx )
!= sizeof( struct MyIndex ) )
{
printf( "%s\n", txt[17] ); /* "End of messages." */
if( mode == SCAN || mode == FIND )
return( 0 );
else
AutoJoin();
return( 0 );
}
/* use new index information to seek to new message in msg file */
if( fseek( fmsg, Index.Offset, SEEK_SET ) )
{
printf( "%s!\n", txt[16] ); /* "Seek Error" */
return( 0 );
}
fread( &tchar, 1, 1, fmsg ); /* read status into variable */
fseek( fmsg, Index.Offset, SEEK_SET ); /* re-seek */
if( mode == KILL || mode == NUKE )
{
tchar = tchar ^ 0x80; /* XOR status with 0x80 */
if( mode == NUKE ) tchar = tchar | 0x80;
fwrite( &tchar,1, 1,fmsg ); /* write back new status */
fflush( fmsg );
fseek( fmsg,Index.Offset, SEEK_SET ); /* re-seek */
}
if( mode == PRIVATE )
{
tchar = ( tchar == 0x2A ) ? 0x20 : 0x2A; /* XOR status with 0x80 */
fwrite( &tchar,1, 1,fmsg ); /* write back new status */
fflush( fmsg );
fseek( fmsg,Index.Offset, SEEK_SET ); /* re-seek */
}
nrecs = ( ( Index.Size / 128 ) + 1 ) /* Msg + Head */;
if( mode == SCAN )
{
fread( rbuf, 128, 1, fmsg );
PutHeader();
}
else
{
if( nrecs > ( RbufSize / 128 ) )
if( !reup( ( unsigned long ) ( nrecs+1 )*128L ) )
return( 0 );
if( fread( ( char * ) rbuf, 128, nrecs, fmsg ) != nrecs )
{
printf( "%s? \n", txt[18] ); /* Read Error */
return( 0 );
}
Display( mode );
}
return( 1 );
}
/*
* Prints the Qmail message header pointed by buf .
*/
static void
PutHeader( /* void */ )
{
struct MsgHeaderType Header;
/* const */ char */* const */ Space = "\t\t";
byte statu;
int i;
byte *pntr;
memcpy ( &Header.Status, rbuf, sizeof( struct MsgHeaderType ) );
pntr = ( byte * ) Header.MsgDate;
if( charset == ISOLAT1 )
{
for( i=0; i<88; i++ , pntr++ ) /* translate header info */
*pntr = codelu[ ( unsigned ) *pntr ];
}
else if( charset == CHR7BIT )
{
for( i=0; i<88; i++ , pntr++ ) /* translate header info */
*pntr = code7bit[ ( unsigned ) *pntr ];
}
/* check for lowercase letters in to/from fields */
caps = TRUE;
pntr = ( byte * ) ( Header.ForWhom );
for( i=0; i<50; i++ )
if( pntr[i] >= 'a' && pntr[i] <= 'z' )
caps = FALSE;
/* 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( UserName1, ( char * ) ( Header.ForWhom ), strlen( UserName1 ) )||
( !strnicmp( UserName2, ( char * ) ( Header.ForWhom ), strlen( UserName2 ) ) ) )
blink();
nprint( Header.ForWhom, 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( "%s", ConfName[findCindex( readCnum( ( byte * ) &( Header.BinConfN[0] ) ) )] );
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[%ld/%ld]", Index.MsgNum + 1, TotMsg ); /* 0 based, print 1 based. */
statu = Header.Status;
if( statu == '+' || statu == '*' || statu >= 0x80 )
{
printf( "\t\t" );
red();
high();
blink();
if( statu >= 0x80 )
printf( " %s%c", txt[105], BELL ); /* "KILLED MESSAGE" */
else
printf( " %s%c", txt[27], BELL ); /* "PRIVATE MESSAGE" */
}
printf( "\n\n" );
clear();
cyan();
}
/*
* Prints the Qmail message header in file fp.
*/
static void
PrintHeader( /* FILE * */ fp )
FILE *fp;
{
struct MsgHeaderType Header;
/* const */ char */* const */ Space = "\t\t";
int i;
byte *pntr;
memcpy ( &Header.Status, rbuf, sizeof( struct MsgHeaderType ) );
pntr = ( byte * ) Header.MsgDate;
if( charset == ISOLAT1 )
{
for( i=0; i<88; i++ , pntr++ ) /* translate header info */
*pntr = codelu[ ( unsigned ) *pntr ];
}
else if( charset == CHR7BIT )
{
for( i=0; i<88; i++ , pntr++ ) /* translate header info */
*pntr = code7bit[ ( unsigned ) *pntr ];
}
/* 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.ForWhom, 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 : " */
fprintf( fp, "%s", ( char * ) ( ConfName[findCindex( readCnum( ( byte * ) &( Header.BinConfN[0] ) ) )] ) );
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[%ld/%ld]", 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
* -------------------------------------------
*/
#define NulConf -1
#define unsave( x,y,z ) ( x = y , y = z )
static void
Reply( /* const int */ mode, /* const char * */ line )
int mode;
char *line;
{
int i , lowcase;
unsigned int j;
char *intmp;
char fname[MAXPATHS];
char tmp[MAXPATHS];
char dummy[MAXPATHS];
int reedit = FALSE;
struct MsgHeaderType *Header;
struct QmailRepType Qmail;
/* #ifdef USESYSTEM */
char cmd[MAXPATHS]; /* non-unix needs this */
/* #endif */
if( IsEmpty )
{
EmptyMsg();
return;
}
SaveConf = CurConf;
if( mode == ENTER )
{
if( ( sscanf( line, "%s %s", dummy, tmp ) ) == 2 )
{
if( Numeric( tmp ) )
{ /* find proper index for conference */
i = atoi( tmp );
i = findCindex( i );
}
else
{/* not numeric */
if( !strnicmp( tmp, "MAIN", 4 ) )
i = 0;
else
{ /* search for match in conf list */
j = strlen( tmp );
for( i = 0; i <= LastConf; i++ )
if( !strnicmp( tmp, ConfName[i], j ) )
break;
}
}
if( i < 0 || i > LastConf )
{/* index not found in previous step */
printf( "\n%s\n", txt[28] ); /* Unknown Conference */
unsave( CurConf, SaveConf, NulConf );
return;
}
CurConf = i; /* update Current conf. for our purposes */
}
if( CurConf == PCONF_IDX || CurConf == RCONF_IDX )
{
unsave( CurConf, SaveConf, NulConf );
return;
}
if( CurConf != SaveConf )
printf( "\n%s %d %s %s\n", txt[29], ConfNumbers[CurConf],
ConfName[CurConf], txt[30] );
}
Header = ( struct MsgHeaderType * ) rbuf;
if( ( SaveConf >= ( RCONF_IDX ) ) && mode != ENTER ) /* get actual conf. from header */
CurConf = findCindex( readCnum( ( byte * ) & ( Header->BinConfN[0] ) ) );
if( ( intmp = tempnam( WorkPath, "re" ) )!= NULL ) /* Temporary file */
strcpy ( fname, intmp );
else
sprintf( fname, "%s%c%s", WorkPath, SEP, "reply.tmp" );
l_edit: /* this is where we go if we need to re-edit msg. */
ResetHeader( &Qmail );
printf( "\n" );
/* get who the message is from */
morefr:
green();
strcpy ( dummy , UserName );
luxptr = dummy;
if( mode == EDIT )
{
scpy( dummy, ( char * ) ( Header->Author ), 25 );
}
/* if( strcmp( luxptr, UserName1 ) ) */
/* add_history( UserName1 ); */
lowcase = fido; /* True or False boolean valued */
if( mode == REPLY )
{
lowcase = FALSE;
intmp = ( char * ) Header->ForWhom;
for( i=0; i < 25; i++ )
if( intmp[i] >= 'a' && intmp[i] <= 'z' )
lowcase = TRUE;
}
if( mode == ENTER )
lowcase = !caps;
if( !lowcase ) /* PCBoard likes uppercase to/from field */
strupr( luxptr );
intmp = readline( PRMTFR );
strcpy( tmp, intmp );
luxptr = NULL;
StripDel( tmp );
if( strlen( tmp ) > ( unsigned ) 25 )
{
red();
printf( "%s\n", txt[34] ); /* "Entry too long ! 25 chars max */
goto morefr;
}
if( tmp[0] )
str2mem( ( char * ) Qmail.Author, tmp ); /* Right name in the from field */
else
{
blue();
printf( "%s.\n", txt[33] ); /* "message aborted" */
unsave( CurConf, SaveConf, NulConf );
return;
}
/* get who the message is being sent to */
moreto:
green();
luxptr = dummy;
if( mode == EDIT )
scpy( dummy, ( char * ) ( Header->ForWhom ), 25 );
else if( mode != ENTER )
scpy( dummy, ( char * ) ( Header->Author ), 25 );
else
strcpy( dummy, "All" );
/* PCBoard likes uppercase to/from field */
if( !fido || ( caps && ( mode == ENTER ) ) )
strupr( luxptr );
intmp = readline( PRMTTO );
/* PCBoard likes uppercase to/from field */
if( !fido || ( caps && ( mode == ENTER ) ) )
strupr( intmp );
strcpy( tmp, intmp );
luxptr = NULL;
StripDel( tmp );
if( strlen( tmp ) > ( unsigned ) 25 )
{
red();
printf( "%s\n", txt[34] ); /* "Entry too long ! 25 chars max */
goto moreto;
}
if( !stricmp( tmp, "N" ) || !tmp[0] )
{
blue();
printf( "%s.\n", txt[33] ); /* "message aborted" */
unsave( CurConf, SaveConf, NulConf );
return;
}
str2mem( ( char * ) ( Qmail.ForWhom ), ( char * ) tmp );
/* get subject of message */
moresub:
green();
if( mode != ENTER )
{
scpy( dummy, ( char * ) ( Header->Subject ), 25 );
luxptr = dummy;
}
intmp = readline( PRMTSB );
strcpy( tmp, intmp );
luxptr = NULL;
StripDel( tmp );
if( strlen( tmp ) > ( unsigned ) 25 )
{
red();
printf( "%s\n", txt[34] ); /* "Entry too long ! 25 chars max */
goto moresub;
}
if( !stricmp( tmp, "N" ) || !tmp[0] )
{
blue();
printf( "%s.\n", txt[33] ); /* "message aborted" */
unsave( CurConf, SaveConf, NulConf );
return;
}
str2mem( ( char * ) Qmail.Subject, ( char * ) tmp );
/* get security of message */
moresec:
green();
if( ( mode != ENTER ) &&
( Header->Status == '+' || Header->Status == '*' ) )
luxptr = "Receiver Only ( private )";
else
luxptr = "None ( public )";
intmp = readline( PRMTSC );
strcpy( tmp, intmp );
luxptr = NULL;
StripDel( tmp );
StripSpaceL( tmp );
if( tmp[0] )
{
strupr( tmp );
if( strlen( tmp ) > ( unsigned ) 25 )
{
red();
printf( "%s\n", txt[35] ); /* "Too long! R=...etc..." */
goto moresec;
}
if( tmp[0] == 'R'/* || !strnicmp( tmp,"priv", 4 ) */ )
Qmail.Status = ( char ) 0x2A;
else
Qmail.Status = ( char ) 0x20;
}
else
{
blue();
printf( "%s.\n", txt[33] ); /* "message aborted" */
unsave( CurConf, SaveConf, NulConf );
return;
}
sprintf( dummy, "%-7d", ConfNumbers[CurConf] );
str2mem( ( char * ) Qmail.ConfNum, dummy ); /* Msg goes to the current conference */
if( mode == EDIT && SaveConf == RCONF_IDX )
scpy( dummy, ( char * ) ( Header->RefMsg ), 7 );
else if( mode != ENTER )
scpy( dummy, ( char * ) ( Header->NumMsg ), 7 );
str2mem( ( char * ) Qmail.RefMsg, ( mode == ENTER ) ? "" : dummy );
if( mode == REPLY && reedit == FALSE )
QuoteMsg( fname );/* Quote original message... */
else if( mode == EDIT && reedit == FALSE )
StripTag( fname );
white();
/* "calling editor" */
printf( "\n%s\n", txt[38] );
sprintf( cmd,"%s %s", Editor, fname );
system ( cmd );
/* Here is where we ask if spelling needs checking */
if( speller[0] )
{
intmp = readline( "Check spelling [Y/n] ?" );
StripDel( intmp );
intmp[0] = tolower( intmp[0] );
if( intmp[0] != 'n' )
{
sprintf( cmd, "%s %s", speller, fname );
system( cmd );
}
} /* end of spelling code */
/* Here is where we ask if we want to save message */
Tag( "tag ?" );
printf( "Fido style tagline is %s.\n\n", fido ? "ON" : "OFF" );
printf( "select:\n\t`Save' to save reply.\n" );
printf( "\t`Edit' to re-edit reply.\n" );
printf( "\t`Fido' to toggle tagline style and save reply.\n" );
printf( "\t`Abort' to cancel reply.\n\n" );
intmp = readline( "Choose: Save, Edit, Fido, Abort [Save] ?" );
strcpy ( tmp, intmp );
StripDel( tmp );
tmp[0] = tolower( tmp[0] );
if( tmp[0] == 'e' )
{
reedit = TRUE;
goto l_edit; /* re-edit message */
}
if( tmp[0] != 's' && tmp[0] != '\0' && tmp[0] != 'f' )
{ /* abort reply */
printf( "\n\n%s\n", txt[33] );
unlink( fname );
unsave( CurConf, SaveConf, NulConf );
return;
}
if( tmp[0] == 'f' )
{
togltag();
}
if( !fido ) /* adjust header for fido or not */
for( i = 0; i < 50; i++ )
Qmail.ForWhom[i] = toupper( Qmail.ForWhom[i] );
if( AddReply( fname, (struct QmailRepType *) &(Qmail.Status) ) )
{
if( autotag )
ChooseTag();
if( SaveConf == RCONF_IDX )
{
CurConf = RCONF_IDX;
if( mode == EDIT )
ReadNext( NUKE );
TotMsg++;
sprintf( dummy,"%ld",TotMsg );
GoToNum ( dummy );
}
}
unsave( CurConf, SaveConf, NulConf );
return;
}
/*
* Add the reply to a Qmail reply.msg file.
*/
static int AddReply( fname, Qmail )
char *fname;
struct QmailRepType *Qmail;
{
if( !OpenRepFile( ADDREP ) )
return( FALSE );
if( KodeMessage( fname, Qmail ) )
return( FALSE );
ReplyExist = TRUE;
return( TRUE );
}
/*
* LIST CONF : Prints conferences numbers, names and status.
*/
static void ListConf()
{
#define pers -2
#define reps -1
unsigned line;
int i=0;
char tmp[MAXPATHS];
if( IsEmpty )
{
EmptyMsg();
return;
}
cls();
magenta();
high();
printf( "\r%s %s\n", txt[78], BoardName ); /* "Liste des conf. sur" */
clear();
red();
printf( "\r" );
for( i = 0; i < ( int ) ( strlen( txt[78] ) + strlen( BoardName ) + 1 ); i++ )
putchar( '-' );
putchar( '\n' );
for( i = pers, line = 0; i < RCONF_IDX; i++ )
{
line++;
if( line > SCREENLINES - 5 )
{
line = 0;
printf( "\n" );
if( !more( YES ) )
break;
cyan();
}
if( i == pers )
{ /* List personal conference first */
if( pmail )
blink();
i = PCONF_IDX;
}
if( i == reps ) /* List reply conference next */
i = RCONF_IDX;
sprintf( tmp, "%s%s%c%d.cnf", HomePath, CurBoard, SEP, ConfNumbers[i] );
red();
high();
printf( "\n\t\t%4d ", ConfNumbers[i] );
clear();
blue();
printf( "......... " );
magenta();
if( ( i == PCONF_IDX ) && pmail )
blink();
high();
printf( "%-15s ", ConfName[i] );
clear();
blue();
printf( "......... " );
if( ( i == PCONF_IDX ) && pmail )
blink();
high();
if( access( tmp, S_IREAD | S_IWRITE ) )
{
printf( "%s", txt[79] ); /* "Inactive" */
}
else
{
magenta();
printf( "%s", txt[80] ); /* "active" */
}
if( i == PCONF_IDX )
{
clear();
i = pers;
}
else if( i == RCONF_IDX )
i = reps;
}
clear();
printf( "\n\n" );
#undef reps
#undef pers
}
/*
* Goes to the msg number represented by the string. and print it.
* ( Internal count, not BBS numbers ! )
*/
static void GoToNum( /* const char * */ str )
char *str;
{
if( SeekNum( str ) )
Display( 0 );
}
/*
* Seek to specific message number
*
*/
static int
SeekNum( str )
char *str;
{
long int nb;
size_t nrecs; /* number of records to read */
if( IsEmpty )
{
EmptyMsg();
return( 0 );
}
nb = atol( str );
nb = nb - 1;
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( "%ld\n", TotMsg );
return( 0 );
}
if( fseek( fidx, ( nb * ( long ) sizeof( struct MyIndex ) ), SEEK_SET ) )
{
printf( "%s !\n", txt[16] ); /* "seek error" */
return( 0 );
}
if( fread( &Index.LastRead, 1, sizeof( struct MyIndex ), fidx )
!= sizeof( struct MyIndex ) )
{
printf( "%s\n", txt[17] ); /* "End of messages " */
return( 0 );
}
rewind( fmsg );
if( fseek( fmsg, Index.Offset, SEEK_SET ) )
{
printf( "%s !\n", txt[16] );
return( 0 );
}
nrecs = ( ( Index.Size / 128 ) + 1 ); /* same as ( Index.Size+128 )/128 ) */
if( ( fread( ( char * ) rbuf, 128, nrecs , fmsg ) ) != nrecs )
{
printf( "%s ? \n", txt[18] ); /* "read error" */
return( 0 );
}
rbuf[ ( Index.Size )+128 ] = '\0'; /* terminate buffer like a string */
return( 1 ); /* good seek */
}
/*
* DISPLAY : Prints the current message,stored in memory.
*/
static void
Display( mode )
int mode;
{
unsigned long i = 0;
int QuotedColor, line = 0, count = 0;
byte *ptr, *pt;
byte *linbuf;
if( IsEmpty )
{
EmptyMsg();
return;
}
cls();
PutHeader();
if( ( linbuf = ( byte * ) malloc( 400 ) ) == NULL )
{ /* local line buffer */
printf( "malloc() failed in read.c module Display()\n\n" );
return;
}
cyan();
ptr = rbuf + Index.Size + 127; /* strip off trailing junk */
while( *ptr == '\0' || *ptr == '\040' || *ptr == '\n' )
{
*ptr = '\0';
ptr--;
}
*( ++ptr ) = '\n';
ptr = ( rbuf + sizeof( struct MsgHeaderType ) );
i = 0;
line = QuotedColor = 0;
pt = linbuf;
*pt = 0;
while ( i < Index.Size )
{
/* Security for long lines */
if( count > ( int ) 79 )
*ptr = '\n';
/* Display a total line */
if( *ptr == '\n' )
{
count = 0;
*pt = 0;
line++;
pt = linbuf;
/* Process colors on quoted line */
if( IsQuoted( '>', pt ) )
{
while ( *pt != '>' )
putchar( *pt++ );
QuotedColor = 1;
red(); /* Quote char in red... */
putchar( *pt++ );
green(); /* Quoted line in green.. */
puts( ( char * ) pt );
cyan();
pt = linbuf;
}
else
{
if( QuotedColor )
{
cyan();
QuotedColor = 0;
}
puts( (char *) linbuf );
}
}
else if( *ptr )
{ /* Non 0 chars */
if( charset != CHRDOS )
{
if( vtspecial( *ptr ) && graphics )
{ /* use vt100 graphics codes */
*pt++ = '\016';
*pt++ = codevt[ ( unsigned ) ( *ptr ) ];
*pt = '\017';
}
else if( charset == ISOLAT1 )
*pt = codelu[ ( unsigned ) ( *ptr ) ]; /* use iso lookup table */
else
*pt = code7bit[ ( unsigned ) ( *ptr ) ];
}
else
*pt = *ptr;
pt++;
count++; /* Security for line length ... */
}
i++;
ptr++;
if( line > SCREENLINES - 8 )
{
line = 0;
if( mode == KILL || mode == NUKE || mode == PRIVATE )
break;
if( !more( YES ) )
break;
cyan();
}
}
free( linbuf );
FirstDone = TRUE;
printf( "\n" );
}
/*
* Welcome : Displays the welcome file.
*/
static void Welcome()
{
char tmp[MAXPATHS];
sprintf( tmp, "%s%s%c%s", HomePath, CurBoard, SEP, WELCOME );
if( !access( tmp, S_IREAD ) )
{
sprintf( tmp, "%s%s", HomePath, CurBoard );
view( tmp, WELCOME );
}
else
{
sprintf( tmp, "%s%s%c%s", HomePath, CurBoard, SEP, WELCOMEG ); /* ansi welcome */
if( !access( tmp, S_IREAD ) )
{
sprintf( tmp, "%s%s", HomePath, CurBoard );
view( tmp, WELCOMEG );
}
}
}
/*
* GETBBS : Called by main() with argv[1]. Looks for a new QWK packet, if
* older than message base, just loads the base.
*/
static void GetBbs( name )
char *name;
{
char tmp[MAXPATHS];
char packet[MAXPATHS];
char base[MAXPATHS];
strcpy( tmp, name );
if( strstr( name, ".qw" ) == NULL )
strcat( tmp, ".qwk" );
sprintf( packet, "%s%s", MailPath, tmp );
if( access( packet, S_IREAD ) )
{/* No new mail found */
printf( "%s\n", txt[31] ); /* "no new mail" */
Read( name );
return;
}
sprintf( base, "%s%s%c%s", HomePath, name, SEP, CNTRL_FILE );
if( access( base, S_IREAD ) )
{
printf( "%s. ", txt[45] ); /* New BBS in this base. */
sprintf( tmp, "load %s", name );
Load( tmp );
return;
}
if( fileage( packet ) <= fileage( base ) )
{
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 );
}
static void Purge()
{
int i;
char tmp[80];
char cnf[MAXPATHS];
char idx[MAXPATHS];
int size;
if( IsEmpty )
{
EmptyMsg();
return;
}
magenta();
high(); /* Selective erasing of conferences. */
printf( "\n%s\n", txt[102] ); /* Effacement sΘlectif des confΘrences */
clear();
red();
printf( "----------------------------------------\n\n" );
for( i = 0; i <= LastConf; i++ )
{
sprintf( cnf, "%s%s%c%d.cnf", HomePath, CurBoard, SEP, ConfNumbers[i] );
sprintf( idx, "%s%s%c%d.idx", HomePath, CurBoard, SEP, ConfNumbers[i] );
if( ( size = filesize( cnf ) ) == -1 )
continue; /* No such file */
onemore:
green();
high();
printf( "Conf. %d [ ", ConfNumbers[i] );
yellow();
printf( "%s", ConfName[i] );
green();
printf( " ] takes " );
yellow();
printf( "%ld", size );
green();
printf( " bytes. Delete ( 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;
if( FilesOpen )
{
fclose( fidx );
fclose( fmsg );
FilesOpen = FALSE;
FirstDone = FALSE;
}
}
ConfActive[i] = FALSE;
if( i == findCindex( PERS_CONF ) )
pmail = FALSE;
printf( "Conference %d is now empty.\n\n", ConfNumbers[i] );
ActvCnt--; /* one less active conference */
break;
default:
goto onemore;
}
}
if( !ConfActive[CurConf] )
AutoJoin();
}
/*
* scan through the message headers
*/
static void scruter()
{
int i, m;
m = SCREENLINES / 6;
do
{
cls();
for( i = 0; i < m; i++ )
if( !ReadNext( SCAN ) )
return;
}
while( more( YES ) );
return;
}
/*
* search conference for text string
*
*/
static int findtxt( fndargs, mode )
char *fndargs;
int mode;
{ /* valid modes are FIND & NEXT */
static char findbuf[256];
static long nm;
char *fndpt; /* not used but needed for future use */
char nmbuf[30];
if( mode == FIND )
{
strcpy( findbuf, fndargs );
nm = 1;
}
if( findbuf[5] == ( char ) 0 || nm > TotMsg || nm < 1 )
return( 0 ); /* nothing to do */
while( nm <= TotMsg )
{
sprintf( nmbuf,"%ld",nm );
nm++;
if( !SeekNum( nmbuf ) ) /* seek to next message in conference */
return( 0 );
rbuf[96] = '\0'; /* mark end of header search */
if( ( fndpt = findstr( ( byte * ) &rbuf[128], ( byte * ) &findbuf[5] ) ) != NULL ||
( fndpt = findstr( ( byte * ) &rbuf[21], ( byte * ) &findbuf[5] ) ) != NULL )
{
Display( 0 );
break;
}
}
return( 1 );
}
/* function to look for search string s2 in text string s1 */
static char *findstr( s1, s2 )
unsigned char *s1;
unsigned char *s2;
{
byte *p1, *p2;
p1 = s1;
p2 = s2;
/* while the end of string s1 has not been reached, */
while( *s1 )
{
/* while s2 matches within s1, */
/* look for search string s2 */
/* strip off lowercase if needed */
while ( ( isalpha( *p1 ) ? toupper( *p1 ) : *p1 ) ==
( isalpha( *p2 ) ? toupper( *p2 ) : *p2 ) )
{
/* advance string compare pointers */
p1++;
p2++;
/* if end of search string s2 is reached, */
/* return ptr to position in string s1 where s2 found */
if( !*p2 )
return( (char *) s1 );
/* if end of string s1 reached prematurely, */
/* return NULL indicating incomplete match */
if( !*p1 )
return( NULL );
}
/* if mismatch occurs, advance s1 string pointer */
/* and reset search string pointer s2 */
p1 = ++s1;
p2 = s2;
}
/* if end of string s1 reached, */
/* return NULL indicating string s2 not in s1 */
return( NULL );
}
/*
* Search array for next active conference, wrapping around
* to start if need be.
*/
static int FindActive( curcon )
int curcon;
{
int i;
for( i = curcon + 1; i <= LastConf; i++ )
{
if( ConfActive[i] )
return( i );
}
for( i = 0; i <= curcon; i++ )
{
if( ConfActive[i] )
return( i );
}
return( -1 );
}
static void showterms()
{
int i = 0;
while( terms[i] != NULL && i < 50 )
{
printf( "%s\n",terms[i] );
i++;
}
}