home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Unsorted BBS Collection
/
thegreatunsorted.tar
/
thegreatunsorted
/
programming
/
asm_programming
/
MJRDEVEL.ARC
/
ESGUTL.C
< prev
next >
Wrap
Text File
|
1989-03-20
|
39KB
|
1,361 lines
/***************************************************************************
* *
* ESGUTL.C *
* *
* Copyright (C) 1988,1989 GALACTICOMM, Inc. All Rights Reserved. *
* *
* E-Mail and SIG utilities and common-code segments. *
* *
* - T. Stryker 7/28/88 *
* *
***************************************************************************/
#include "stdio.h"
#include "ctype.h"
#include "majorbbs.h"
#include "usracc.h"
#include "btvstf.h"
#include "esigs.h"
#include "message.h"
#include "dosface.h"
#include "portable.h"
static
int reclen[]={ /* array of byte counts for download records */
0, /* NULL position for dnltyp[0] index */
0, /* ASCII download, no byte count needed */
128+4, /* XMODEM (128 byte blocks) */
128+5, /* XMODEM CRC (128 byte blocks) */
1024+5 /* YMODEM CRC (1K blocks) */
};
static
int blksiz[]={ /* array of byte counts for download blocks */
0, /* NULL position for dnltyp[0] index */
0, /* ASCII download, no byte count needed */
128, /* XMODEM (128 byte blocks) */
128, /* XMODEM CRC (128 byte blocks) */
1024 /* YMODEM CRC (1K blocks) */
};
#define ACK 6 /* ASCII controls chars used in XMODEM */
#define NAK 21
#define CCC 67 /* 'C' (rep's NAK) tells sender use CRC-16 */
#define SOH 1
#define STX 2 /* (rep's SOH) tells rcver 1024-byte block */
#define EOT 4
#define CAN 24
#define NAKSTG (esgptr->fxftyp == UPLTYPS+2 ? "\25" : "\103")
FILE *esgmb; /* esigs named-message file block ptr */
BTVFILE *esgbb; /* esigs btrieve message file block ptr */
BTVFILE *qscbb; /* esigs quickscan/config btrieve file ptr */
struct compos compos; /* concrete allocation of composite struct */
long filen; /* length of attachment found, from opnatt() */
int esgstt; /* current/new usrptr->substt hold register */
struct sigdat *sigdat, /* ram-resident SIG data tables base address */
*sdtptr; /* scratch ptr for scanning thru sigdat */
struct sofars *sfrptr; /* scratch ptr for scanning thru sofars */
struct qscfg *sopqsc, /* singular SYSOP/SIG-Op scratch area */
*qscfgs, /* base ptr to dynam allocated array */
*qscptr; /* ptr to current user's qscfgs entry */
struct usracc *sopusa; /* singular SYSOP/SIG-Op scratch acct */
char dftnlv[MAXSIG/2], /* default non-live SIG access bits */
dftliv[MAXSIG/2], /* default live SIG access bits */
maxnlv[MAXSIG/2]; /* maximum non-live SIG access bits */
char *accstg[]={"Zero","","Read","","Download","","Write","",
"Upload","","Co-Op","","SIG-Op","","SYSOP","<unassigned>"};
char uptmrs[64]; /* array of upload/download timers per usrnum*/
#define either(x,y) (esgptr->usigno == NOSIG ? (x) : (y)) /* E-Mail vs SIG */
#define MEMENU REPRMT
#define MSMENU (readac() >= OPAXES ? ORSPRMT : RSPRMT)
#define MMENU either(MEMENU,MSMENU)
#define HUH either(EMLHUH,SIGHUH)
iniesg() /* initialize email and sigs */
{
if (esgmb == NULL) {
esgmb=opnmsg("esigs.mcv");
dclvda(sizeof(struct esgusr));
qscbb=opnbtv("qscfg.dat",sizeof(struct qscfg));
esgbb=opnbtv("esigs.dat",sizeof(struct message));
emrtcy();
inieml();
inisig();
}
}
fireup() /* fire up status 3 input handling */
{
setmbk(esgmb);
setbtv(esgbb);
esgstt=usrptr->substt;
qscptr=&qscfgs[usrnum];
if (usrptr->flags&INJOIP) {
prompt(esgstt);
}
else if (esgstt == UPASC) {
usrptr->pfnacc=0;
return(1);
}
else if (usrptr->pfnacc > MAXPFN) {
byenow(MUCH2P);
}
else if (usrptr->pfnacc > WRNPFN && pfnlvl > 0) {
errmsg(RAUNCH);
}
else if (pfnlvl > 2) {
errmsg(PFNMSG);
}
else {
chkdft(esgptr->dftinp);
return(1);
}
return(0);
}
hdlesg() /* handle common email/sigs substates */
{
switch (esgstt) {
case DNLNOW:
case DWNAGN:
sdnldq();
break;
case ASCORX:
sascorx();
break;
case GOASC:
abodnl();
break;
case EDITING:
sediting();
break;
case ATTFIQ:
case UPLAGN:
sattfiq();
break;
case UPMODE:
case UPMSOP:
supmode();
break;
case SOPFSP:
ssopfsp();
break;
case UPASC:
supasc();
break;
case UPXMDM:
case GOXMDM:
case COMPLT:
prf("");
break;
default:
catastro("E/SIGS STATE ERROR (esgstt=%d)",esgstt);
}
}
dnload(whndun) /* download attachment, invoke arg when done */
int (*whndun)();
{
if (attfs() != NULL && filen >= 0) {
prfmsg(ATTMNT,ltoa(filen));
prompt(DNLNOW);
esgptr->whndun=whndun;
}
else {
prfmsg(ATTNF,ltoa(esgptr->msg.msgno));
cncall();
(*whndun)();
}
}
sdnldq() /* state: do you want to download file now? */
{
switch (cncyesno()) {
case 'Y':
prompt(ASCORX);
break;
case 'N':
(*esgptr->whndun)();
break;
default:
errmsg(YORN);
}
}
sascorx() /* state: ascii or xmodem flavor choice */
{
char c;
char *ostyle;
switch (c=cncchr()) {
case '?':
prohlp(ASCXHL);
return;
case '1':
if (cncchr() == 'C') {
btuxnf(usrnum,0,19);
}
cncall();
prompt(GOASC);
btuinj(usrnum,CYCLE);
ostyle=FOPRA;
btuech(usrnum,0);
break;
case '2':
case '3':
case '4':
cncall();
prompt(GOXMDM);
btutrg(usrnum,1);
esgptr->blknum=1;
esgptr->lstsiz=0;
esgptr->curpos=0L;
ostyle=FOPRB;
break;
default:
errmsg(HUH);
return;
}
esgptr->fxftyp=c-'0';
usrptr->flags|=NOINJO;
if ((esgptr->fp=fopen(attfs(),ostyle)) == NULL || filen < 0) {
dnloff();
clrprf();
esgstt=REFPN;
errmsg(ATTNF,ltoa(esgptr->msg.msgno));
}
}
dnloff() /* turn downloading process off */
{
if (esgptr->fxftyp > 0 && esgptr->fxftyp < UPLTYPS) {
esgptr->fxftyp=0;
btuoes(usrnum,0);
btutrg(usrnum,0);
echon();
btucli(usrnum);
usrptr->flags&=~(NOINJO+NOZAP);
rstrxf();
if (esgptr->fp != NULL) {
fclose(esgptr->fp);
esgptr->fp=NULL;
}
}
}
emrtcy() /* once-a-second real-time cycler */
{
for (usrnum=0 ; usrnum < nterms ; usrnum++) {
if (uptmrs[usrnum] != 0 && --uptmrs[usrnum] == 0) {
btuinj(usrnum,CYCLE);
}
}
rtkick(1,emrtcy);
}
emsthn() /* email/sigs status handler */
{
char ch;
int ibw;
setmbk(esgmb);
setbtv(esgbb);
qscptr=&qscfgs[usrnum];
esgstt=usrptr->substt;
switch (esgstt) {
case GOASC:
switch (status) {
case CYCLE:
btucli(usrnum);
if (btuoba(usrnum) < 1024) {
btuinj(usrnum,CYCLE);
break;
}
else if (fgets(prfbuf,1024,esgptr->fp) != NULL) {
prfbuf[strlen(prfbuf)-1]='\r';
outprf(usrnum);
btuinj(usrnum,CYCLE);
}
else {
btuoes(usrnum,1);
if (btuoba(usrnum) == OUTSIZ-1) {
btuinj(usrnum,OUTMT);
}
esgstt=COMPLT;
}
break;
default:
dfsthn();
}
break;
case GOXMDM:
switch (status) {
case INBLK:
btuict(usrnum,&ch);
switch (ch) {
case CCC:
if (esgptr->fxftyp == 2) {
esgptr->fxftyp=3;
}
case NAK:
esgptr->curpos-=esgptr->lstsiz;
if (fseek(esgptr->fp,esgptr->curpos,0) != 0) {
catastro("GOXMDM FSEEK ERROR");
}
esgptr->blknum-=1;
case ACK:
setmem(prfbuf+3,blksiz[esgptr->fxftyp],0);
if ((esgptr->lstsiz=fread(prfbuf+3,1,
blksiz[esgptr->fxftyp],esgptr->fp)) > 0) {
esgptr->blknum=((esgptr->blknum+1)&0xFF);
prfbuf[0]=(blksiz[esgptr->fxftyp] == 1024 ? STX : SOH);
prfbuf[1]=(char)(esgptr->blknum);
prfbuf[2]=(char)(esgptr->blknum^0xFF);
switch (esgptr->fxftyp) {
case 2:
prfbuf[131]=cksumv(prfbuf+3,128);
break;
case 3:
mkcrc(128);
break;
case 4:
mkcrc(1024);
break;
}
btuxct(usrnum,reclen[esgptr->fxftyp],prfbuf);
esgptr->curpos+=esgptr->lstsiz;
}
else {
prfbuf[0]=EOT;
btuxct(usrnum,1,prfbuf);
uptmrs[usrnum]=2;
esgstt=COMPLT;
}
break;
case CAN:
abodnl();
outprf(usrnum);
break;
}
break;
default:
dfsthn();
}
break;
case COMPLT:
switch (status) {
case CYCLE:
btuoes(usrnum,1);
setmem(prfbuf,10,EOT);
btuxct(usrnum,10,prfbuf);
break;
case OUTMT:
goodnl();
outprf(usrnum);
break;
default:
dfsthn();
}
break;
case UPXMDM:
switch (status) {
case CYCLE:
ibw=btuibw(usrnum);
if (esgptr->lstsiz == ibw) {
prfbuf[0]=0;
btuict(usrnum,prfbuf);
if (prfbuf[0] == EOT || prfbuf[0] == CAN) {
btubsz(usrnum,INPSIZ,OUTSIZ);
btuxct(usrnum,1,"\6"); /* ACK, done */
if (prfbuf[0] == CAN) {
donupl(0);
prompt(UPLAGN);
}
else {
donupl(1);
(*esgptr->whndun)();
}
outprf(usrnum);
break;
}
btuxct(usrnum,1,NAKSTG); /* NAK */
btucli(usrnum);
}
else {
esgptr->lstsiz=ibw;
}
uptmrs[usrnum]=3;
break;
case INBLK:
btuict(usrnum,prfbuf);
if (prfbuf[0] != SOH && prfbuf[0] != STX) {
break;
}
else if (prfbuf[1] == (char)((esgptr->blknum-1)&0xFF)
&& prfbuf[2] == (char)(((esgptr->blknum-1)^0xFF)&0xFF)) {
btuxct(usrnum,1,"\6"); /* ACK but ignore */
}
else if (prfbuf[1] == (char)(esgptr->blknum&0xFF)
&& prfbuf[2] == (char)((esgptr->blknum^0xFF)&0xFF)) {
if (cksmok()) {
btuxct(usrnum,1,"\6"); /* ACK and accept */
esgptr->blknum+=1;
fwrite(prfbuf+3,1,blksiz[esgptr->fxftyp-UPLTYPS],
esgptr->fp);
}
}
break;
default:
dfsthn();
}
break;
default:
if (status == CYCLE) {
cycmed();
}
else {
dfsthn();
}
}
usrptr->substt=esgstt;
}
abodnl() /* abort download */
{
btuclo(usrnum);
dnloff();
esgstt=DWNAGN;
errmsg(ABORTD);
}
goodnl() /* good download, finish up and go on */
{
sv.dwnlds+=1;
if (either(ednaud,sdnaud)) {
shocst(1,"%s D:%s",usaptr->userid,attfs());
}
dnloff();
prfmsg(COMPLT);
(*esgptr->whndun)();
}
mkcrc(len) /* make CRC from prfbuf record, len long */
int len;
{
int crc;
crc=ckscrc(prfbuf+3,len);
prfbuf[len+3]=(char)(crc>>8);
prfbuf[len+4]=(char)(crc&0xFF);
}
cksmok() /* check if record in prfbuf checksum is ok */
{
int typ,crc,len;
switch (typ=esgptr->fxftyp-UPLTYPS) {
case 2:
return(cksumv(prfbuf+3,128) == prfbuf[131]);
case 3:
case 4:
len=blksiz[typ];
crc=ckscrc(prfbuf+3,len);
return((char)(crc>>8) == prfbuf[len+3]
&& (char)(crc&0xFF) == prfbuf[len+4]);
}
return(0);
}
cksumv(stg,len) /* compute XMODEM checksum value */
char *stg;
int len;
{
int cks=0;
while (--len >= 0) {
cks+=*stg++;
}
return(cks&0xFF);
}
int ckscrc(stg,len) /* compute CRC value */
char *stg;
int len;
{
int crc,i;
crc=0;
while (--len >= 0) {
crc=crc^((int)*stg++<<8);
for (i=0 ; i < 8 ; i++) {
if (crc&0x8000) {
crc=(crc<<1)^0x1021;
}
else {
crc=crc<<1;
}
}
}
return(crc);
}
possat(rouptr) /* possibly begin attachment proceedings */
int (*rouptr)();
{
int sn;
if ((sn=findsig(esgptr->msg.to)) == NOSIG || rdautl(sn) >= ULAXES) {
prompt(ATTFIQ);
esgptr->whndun=rouptr;
}
else {
(*rouptr)();
}
}
sattfiq() /* state: attach file to this msg? */
{
switch (cncyesno()) {
case 'Y':
if (either(credok(nlveat,eattck),credsf(esgptr->sattck))) {
prompt((usrptr->flags&ISYSOP) ? UPMSOP : UPMODE);
}
break;
case 'N':
if (esgstt != ATTFIQ) {
prfmsg(NUPLD);
}
(*esgptr->whndun)();
break;
default:
errmsg(YORN);
}
}
supmode() /* state: what upload mode? */
{
char c;
char *ostyle;
switch (c=cncchr()) {
case '?':
prohlp(esgstt == UPMODE ? UPMODH : UPMSPH);
return;
case '1':
cncall();
prompt(UPASC);
btumil(usrnum,INPSIZ);
ostyle=FOPWA;
break;
case '2':
case '3':
case '4':
cncall();
prompt(UPXMDM);
uptmrs[usrnum]=2;
btubsz(usrnum,OUTSIZ,INPSIZ);
btutrg(usrnum,reclen[c-'0']);
esgptr->lstsiz=-1;
esgptr->blknum=1;
ostyle=FOPWB;
break;
case '5':
if (usrptr->flags&ISYSOP) {
prompt(SOPFSP);
return;
}
default:
errmsg(HUH);
return;
}
esgptr->fxftyp=c-'0'+UPLTYPS;
usrptr->flags|=NOINJO;
if ((esgptr->fp=fopen(attfs(),ostyle)) == NULL) {
uploff(0);
clrprf();
esgstt=UPLAGN;
errmsg(UPLFER);
}
}
ssopfsp() /* state: SYSOP file spec entry (opt 5) */
{
FILE *fp;
setmem(prfbuf,FSPSIZ,0);
strcpy(prfbuf,cncall());
if ((fp=fopen(prfbuf,FOPRA)) == NULL) {
esgstt=UPLAGN;
errmsg(SFSNXS);
}
else {
fclose(fp);
if ((fp=fopen(attfsd(),FOPWA)) == NULL) {
esgstt=UPLAGN;
errmsg(SOPFER);
}
else {
fwrite(prfbuf,1,FSPSIZ-1,fp);
fclose(fp);
esgptr->msg.flags|=INDRCT+FILATT+APPVED;
prfmsg(IATTAP);
(*esgptr->whndun)();
}
}
}
supasc() /* state: uploading ascii file */
{
cncall();
if (sameas(input,"OK")) {
uploff(1);
(*esgptr->whndun)();
}
else {
fprintf(esgptr->fp,"%s\n",input);
prf("");
}
}
uploff(keep) /* turn uploading off, keep or delete file */
int keep;
{
btumil(usrnum,DFTIMX);
if (esgptr->fxftyp > UPLTYPS) {
btubsz(usrnum,INPSIZ,OUTSIZ);
donupl(keep);
}
}
donupl(keep) /* done with upload, keep or delete file */
int keep;
{
int sn;
esgptr->fxftyp=0;
usrptr->flags&=~NOINJO;
btutrg(usrnum,0);
if (esgptr->fp != NULL) {
fclose(esgptr->fp);
esgptr->fp=NULL;
if (keep) {
if ((sn=findsig(esgptr->msg.to)) == NOSIG) {
esgptr->msg.flags|=FILATT+APPVED;
prfmsg(UPDONE);
}
else if (rdautl(sn) >= COAXES) {
esgptr->msg.flags|=FILATT+APPVED;
prfmsg(FILAVL);
}
else {
esgptr->msg.flags|=FILATT;
prfmsg(FILNVL);
}
sv.uplds+=1;
if (either(eupaud,supaud)) {
shocst(1,"%s U:%s",usaptr->userid,attfs());
}
}
else {
prfmsg(UPLCAN);
unlink(attfsd());
}
}
}
edimsg(clr,tpc,whndun) /* fire up editor, invoke whndun when done */
int clr,tpc,(*whndun)();
{
if (clr) {
mkmsgn();
esgptr->msg.flags=0;
}
bgnedt(clr,TXTSIZ,esgptr->msg.text,TPCSIZ,tpc ? esgptr->msg.topic : NULL);
esgptr->whndun=whndun;
esgstt=EDITING;
esgptr->dftinp='\0';
}
sediting() /* state: in the editor */
{
if (dunedt()) {
(*esgptr->whndun)();
}
else {
prf("");
}
}
uidxst(uid) /* does this User-ID exist? */
char *uid;
{
int retval;
setbtv(accbb);
retval=qeqbtv(uid,0);
setbtv(esgbb);
return(retval);
}
char *
attfsd() /* attachment filespec, "direct" only */
{
static char filespec[FSPSIZ];
char *fnp;
int fnplen;
strcpy(filespec,esgptr->msg.to[0] == SIGIDC ? esgptr->msg.to+1 : "email");
fnp=spr("\\%ld.att",esgptr->msg.msgno);
while ((fnplen=strlen(fnp)) >= 14) { /* ensures over 2 billion */
fnp[fnplen-2]=fnp[fnplen-1]; /* unique filenames */
fnp[fnplen-1]=fnp[1];
movmem(fnp+2,fnp+1,strlen(fnp+1));
}
strcat(filespec,fnp);
return(filespec);
}
char *
attfs() /* attachment filespec, net (may be indirect)*/
{
FILE *indrfp;
struct fndblk fb;
char *filespec;
filespec=attfsd();
if (esgptr->msg.flags&INDRCT) {
if ((indrfp=fopen(filespec,FOPRA)) == NULL) {
return(NULL);
}
if (fread(filespec,1,FSPSIZ-1,indrfp) != FSPSIZ-1) {
fclose(indrfp);
return(NULL);
}
fclose(indrfp);
}
if (fnd1st(&fb,filespec,0)) {
filen=fb.size;
}
else {
filen=-1L;
}
return(filespec);
}
findsig(name) /* find sig number, given name and access */
char *name;
{
return(findsigu(name,1));
}
findsigu(name,cond) /* find sig number utility, conditionally */
char *name;
int cond;
{
int retval;
for (retval=0,sdtptr=sigdat ; retval < nsigs ; retval++,sdtptr++) {
if (sameas(name,sdtptr->signam)) {
movmem(sdtptr->signam,name,UIDSIZ);
if (!cond) {
return(retval);
}
return(rdautl(retval) == NOAXES ? NOSIG : retval);
}
}
return(NOSIG);
}
addaux(newaux) /* add on to existing auxillary msg topic */
char *newaux;
{
char auxbuf[AXTSIZ*2];
strcpy(auxbuf,newaux);
if (strlen(esgptr->msg.auxtpc) != 0 && !(esgptr->msg.flags&ISSHDR)) {
strcat(auxbuf,", ");
strcat(auxbuf,esgptr->msg.auxtpc);
if (strlen(auxbuf) > AXTSIZ-1) {
auxbuf[AXTSIZ-2]='*';
auxbuf[AXTSIZ-1]='\0';
}
}
strcpy(esgptr->msg.auxtpc,auxbuf);
}
char *
formax(leader) /* form aux topic fragment, 15 chars max */
char *leader;
{
static char auxbuf[AXTSIZ/2+1],*ltoap;
strcpy(auxbuf,leader);
ltoap=ltoa(esgptr->msg.msgno);
strcpy(auxbuf+min(strlen(auxbuf),AXTSIZ/2-strlen(ltoap)-1),ltoap);
return(auxbuf);
}
mkmsgn() /* make msg number */
{
esgptr->msg.msgno=++sv.msgtot;
}
postit() /* post the msg built */
{
movmem(usaptr->userid,esgptr->msg.from,UIDSIZ);
esgptr->msg.crdate=today();
esgptr->msg.crtime=now();
esgptr->msg.nreply=0;
setbtv(esgbb);
insbtv(&esgptr->msg);
}
stdcnf() /* standard confirmation after posting */
{
prfmsg(WCONFM,ltoa(esgptr->msg.msgno));
pstpst(SWRITU,SNOTIFD);
}
pstpst(recip,sender) /* "post-posting" cleanup */
int recip,sender;
{
outprf(usrnum);
figin(1);
if (onsys(esgptr->msg.to)) {
prfmsg(recip,usaptr->userid);
if (injoth()) {
prfmsg(sender,esgptr->msg.to);
outprf(usrnum);
}
}
}
figin(addend) /* figure in the current msg to totals */
int addend;
{
if (esgptr->msg.to[0] == SIGIDC) {
sv.sigopn+=addend;
if (findsigu(esgptr->msg.to,0) == NOSIG) {
catastro("FIGIN: NO SIG!");
}
sdtptr->nmsgs+=addend;
switch (esgptr->msg.flags&(FILATT+APPVED)) {
case FILATT:
sdtptr->nw4app+=addend;
break;
case FILATT+APPVED:
sdtptr->nfiles+=addend;
break;
}
}
else {
sv.emlopn+=addend;
}
}
strtup(hlpmsn) /* start up a scan or list utility */
int hlpmsn;
{
long begin;
if (isdigit(morcnc())) {
begin=cnclon();
alomsg(esgptr->keynum,begin);
if (esgptr->msg.msgno != begin) {
prfmsg(MISS,ltoa(begin));
}
}
else {
switch (cncchr()) {
case '?':
prohlp(hlpmsn);
return(0);
case '.':
estabc();
break;
default:
errmsg(HUH);
return(0);
}
}
return(1);
}
estabc() /* establish current esigs.dat msg again */
{
gabbtv(&esgptr->msg,esgptr->fpos,esgptr->keynum);
}
estabn() /* establish position but don't load text */
{
gabbtv(NULL,esgptr->fpos,esgptr->keynum);
}
/* The following routine spits out the message summary lines like this:
#88888 04-JUN-88 14:03 From: Tiponeill To: Darkshade RRR ATT (32 replies)
Re: Hamburger Waffles in the Sunshine (Reply to #55555) */
sumams()
{
int flags,nr;
flags=esgptr->msg.flags;
if (flags&ISSHDR) {
prf("\r#%s SIG HEADER: %s SIG-Op: %s Created %s %02d:%02d\rSIG Topic: %s\r",
ltoa(esgptr->msg.msgno),
esgptr->msg.to,
esgptr->msg.from,
ncedat(esgptr->msg.crdate),
dthour(esgptr->msg.crtime),
dtmin(esgptr->msg.crtime),
esgptr->msg.topic);
}
else {
nr=esgptr->msg.nreply;
prf("\r#%s %s %02d:%02d From: %s To: %s %s%s%s\rRe: %s %s\r",
ltoa(esgptr->msg.msgno),
ncedat(esgptr->msg.crdate),
dthour(esgptr->msg.crtime),
dtmin(esgptr->msg.crtime),
esgptr->msg.from,
esgptr->msg.to,
(flags&RECREQ) && esgptr->msg.to[0] != SIGIDC ? " RRR" : "",
(flags&APPVED) ? " ATT" : "",
(nr == 0) ? "" : spr(" (%d repl%s)",nr,(nr == 1) ? "y" : "ies"),
esgptr->msg.topic,
axtstg());
}
}
char *
axtstg() /* auxillary topic string formatter */
{
return(esgptr->msg.auxtpc[0] == '\0' ? ""
: spr("(%s)",esgptr->msg.auxtpc));
}
sumnew() /* summarize new msg, set fpos, prompt */
{
esgptr->fpos=absbtv();
sumams();
prompt(either(SCOSCN,SCOSIG));
}
alomsg(keyno,msgno) /* acquire highest msg less than msgno, or? */
int keyno;
long msgno;
{
char *tffield;
tffield=either(usaptr->userid,sigdat[esgptr->usigno].signam);
movmem(tffield,compos.userid,UIDSIZ);
compos.msgno=msgno;
if (msgno == FIRSTM
|| !alebtv(&esgptr->msg,&compos,keyno)
|| !sameas(esgbb->key,compos.userid)) {
if (!agebtv(&esgptr->msg,&compos,keyno)
|| !sameas(esgbb->key,compos.userid)) {
return(0);
}
}
esgptr->fpos=absbtv();
esgptr->keynum=keyno;
return(1);
}
prompt(news) /* prompt user, set new state, default input */
int news;
{
int i,sn;
char *lstchp;
esgstt=news;
if (status != CRSTG || !morcnc() || (usrptr->flags&INJOIP)) {
sdtptr=&sigdat[esgptr->usigno];
switch (news) {
case EINFO:
prfmsg(news,emltck,eattck,rrrtck,emllif);
break;
case GOASC:
prfmsg(news,bbsttl,ncedat(today()),nctime(now()));
break;
case ERTFQ:
case ERFHLP:
case ERTHLP:
case STARTS:
case STARTL:
case RTSHLP:
case RTLHLP:
prfmsg(news,ltoa(esgptr->msg.msgno));
break;
case EDITING:
dunedt();
break;
case OPSTART:
if (usrptr->flags&ISYSOP) {
news=SYSTART;
}
case SSTART:
prfmsg(news,sdtptr->signam,sdtptr->descrp,sdtptr->nw4app);
break;
case SRKEY:
prfmsg(esgptr->keywds[0] == '\0' ? SRKEY : SRKYWD,esgptr->keywds);
break;
case SRCHNG:
if (!(esgptr->sflags&SCNQUI)) {
prfmsg(news,sdtptr->signam,esgptr->keywds);
break;
}
news=SRCHQS;
case SCANNG:
case LISTNG:
prfmsg(news,sdtptr->signam);
break;
case QUICKC:
prfmsg(news);
for (i=0 ; (sn=qsigno(i)) != NOSIG ; i++) {
prf(" %-9s ",sigdat[sn].signam);
}
prfmsg(QUICKC2);
break;
case QCKWDS:
prfmsg(news);
for (i=0 ; i < NQSKWG ; i++) {
prf(" %d. %s\r",i+1,qscptr->qskwds[i]);
}
prfmsg(QCKWDS2);
break;
case SIGCON:
case SIGCONH:
case SIG123H:
case SYS123H:
prfmsg(news,accstg[dftlvl(dftnlv)],
accstg[dftlvl(dftliv)],
accstg[dftlvl(maxnlv)]);
break;
case DELRUS:
sdtptr=&sigdat[esgptr->blknum];
prfmsg(news,sdtptr->signam,sdtptr->descrp,
sdtptr->nmsgs,sdtptr->nfiles);
break;
default:
prfmsg(news);
}
lstchp=prfptr-1;
if (!isspace(*lstchp)) {
esgptr->dftinp=*lstchp;
*(prfptr=lstchp)='\0';
}
else {
esgptr->dftinp='\0';
}
}
}
prohlp(news) /* prompt with help msg (don't change state) */
int news;
{
int xstt;
cncall();
xstt=esgstt;
prompt(news);
esgstt=xstt;
}
errmsg(msgnum,parm1,parm2) /* error msg, then re-prompt current state */
int msgnum;
long parm1,parm2;
{
prfmsg(msgnum,parm1,parm2);
outprf(usrnum);
cncall();
btucli(usrnum);
clrinp();
prompt(esgstt);
}
blwoff(msgnum,parm) /* blow off back to main e/s menu, with msg */
int msgnum;
long parm;
{
esgstt=MMENU;
errmsg(msgnum,parm);
}
xtext() /* transmit text of current msg to user */
{
char *cp;
int sn;
for (cp=esgptr->msg.text ; *cp != '\0' ; cp++) {
if (*cp == '\r' && isalpha(*(cp+1))) {
*cp='\n';
}
}
btuxmt(usrnum,esgptr->msg.text);
btuxmt(usrnum,"\r");
if ((sn=esgptr->usigno) != NOSIG && findqs(sn) < NSOFAR) {
if (esgptr->msg.msgno > sfrptr->msgno) {
sfrptr->msgno=esgptr->msg.msgno;
}
}
}
tovalid() /* check if proposed msg recipient is valid */
{
movmem(cncuid(),esgptr->msg.to,UIDSIZ);
return(validwr(esgptr->msg.to));
}
validwr(dest) /* ck if msg destination is ok, leave "to" be */
char *dest;
{
int signo,attach;
if ((signo=findsig(dest)) != NOSIG) {
attach=(esgptr->msg.flags&FILATT);
if (rdautl(signo) < (attach ? ULAXES : WRAXES)) {
errmsg(attach ? FWUNUP : FWUNWR,either("E-Mail","SIG"));
return(0);
}
return(1);
}
if (!uidxst(dest)) {
errmsg(FWUNXI,either("E-Mail","SIG"));
return(0);
}
return(1);
}
isalon() /* check if input is a "long", prep compos */
{
if (!isdigit(morcnc())) {
errmsg(HUH);
return(0);
}
compos.msgno=cnclon();
movmem(either(usaptr->userid,sigdat[esgptr->usigno].signam),
compos.userid,UIDSIZ);
return(1);
}
moddun() /* modify-msg done, update and go on */
{
estabn();
updbtv(&esgptr->msg);
prfmsg(WCONFM,ltoa(esgptr->msg.msgno));
prompt(MMENU);
}
fwdit(recip) /* forward current message to new recipient */
char *recip;
{
long tmno;
char oldnam[FSPSIZ];
strcpy(oldnam,attfsd());
movmem(recip,esgptr->msg.to,UIDSIZ);
addaux(spr("Fw by %s",usaptr->userid));
tmno=esgptr->msg.msgno;
mkmsgn();
if (esgptr->msg.flags&FILATT) {
rename(oldnam,attfsd());
dwfwdf();
}
insbtv(&esgptr->msg);
prfmsg(FWDCNF,ltoa(tmno),ltoa(esgptr->msg.msgno),esgptr->msg.to);
pstpst(SFWDDU,SNOTIFD);
}
dwfwdf() /* deal with forwarding of file */
{
int sn;
esgptr->msg.flags|=APPVED;
if ((sn=findsig(esgptr->msg.to)) != NOSIG) {
if (rdautl(sn) >= COAXES) {
prfmsg(FWDCAP);
}
else {
esgptr->msg.flags&=~APPVED;
prfmsg(FWDCNA);
}
}
}
delwck() /* delete msg, with sighdr and collision cks */
{
esgptr->fpos=absbtv();
if (esgptr->msg.flags&ISSHDR) {
blwoff(NDELHD);
}
else if (esgcfl()) {
blwoff(USING);
}
else {
delmsg();
prfmsg(OKGONE,ltoa(compos.msgno));
prompt(MMENU);
}
}
delmsg() /* delete msg and any direct attachment */
{
delbtv();
unlink(attfsd());
figin(-1);
}
esgmcu() /* email/sigs midnight cleanup */
{
int ctoday,age,smslif;
ctoday=cofdat(today());
setbtv(esgbb);
esgptr=((struct esgusr *)vdarea);
usrptr=user;
if (qlobtv(TONUM)) {
do {
gcrbtv(&esgptr->msg,TONUM);
age=ctoday-cofdat(esgptr->msg.crdate);
if (esgptr->msg.to[0] == SIGIDC) {
if (esgptr->msg.flags&ISSHDR) {
smslif=sigopt("message-lifetime:",siglif);
}
else if (smslif >= 0 && age > smslif) {
delmsg();
}
}
else if (emllif >= 0 && age > emllif) {
delmsg();
}
} while (qnxbtv());
}
}
char *
sigtpc(signo) /* sig topic (for use by teleconference) */
int signo;
{
if (signo <= 0 || signo >= nsigs) {
return("");
}
else {
return(sigdat[signo].descrp);
}
}
esgmod(whndun) /* email/sigs modify-msg utility */
int (*whndun)();
{
esgptr->fpos=absbtv();
if (esgcfl()) {
blwoff(USING);
}
else {
if (esgptr->msg.flags&ISSHDR) {
if (!sopmhd && !(usrptr->flags&ISYSOP)) {
blwoff(NOMODH);
return;
}
if (!morcnc()) {
prfmsg(EHDPFX,sigccr,siglif,sigtck,sattck);
outprf(usrnum);
}
}
edimsg(0,1,whndun);
}
}
esgcfl() /* email/sigs "conflict" (collision) detect */
{
long recpos;
struct esgusr *othesg;
recpos=esgptr->fpos;
for (othusn=0,othusp=user ; othusn < nterms ; othusn++,othusp++) {
if (othusn != usrnum
&& othusp->class > SUPIPG
&& (othusp->state == EMLSTT || othusp->state == SIGSTT)) {
switch (othusp->substt) {
case ESTART:
case REPRMT:
case SSTART:
case RSPRMT:
case OPSTART:
case ORSPRMT:
break;
default:
othesg=esgarr(othusn);
if (recpos == othesg->fpos
|| recpos == othesg->prethr) {
return(1);
}
}
}
}
return(0);
}
esghup() /* email/sigs hang-up-phone vector */
{
setmbk(esgmb);
if (usrptr->state == EMLSTT || usrptr->state == SIGSTT) {
uploff(0);
dnloff();
cpyoff();
clrprf();
}
qscptr=&qscfgs[usrnum];
if (qscptr->userid[0] != '\0') {
setbtv(qscbb);
geqbtv(NULL,usaptr->userid,0);
updbtv(qscptr);
setmem(qscptr,sizeof(struct qscfg),0);
}
}
credok(nlvflg,howmny) /* credits ok for this operation? */
int nlvflg;
int howmny;
{
if (nlvflg) {
return(1);
}
if (usrptr->class > FRELOA && usaptr->tckavl >= howmny) {
usaptr->tckavl-=howmny;
return(1);
}
if (howmny == 0) {
errmsg(NOTLIV,either("E-Mail","SIG"));
}
else {
errmsg(usrptr->class == FRELOA ? NOCREDS : NECREDS,
howmny,either("E-Mail","SIG"));
}
return(0);
}
credsf(howmny) /* credits sufficient for this operation? */
int howmny;
{
if (usaptr->tckavl >= howmny) {
usaptr->tckavl-=howmny;
return(1);
}
errmsg(usrptr->class == FRELOA ? NOCREDS : NECREDS,
howmny,either("E-Mail","SIG"));
return(0);
}