cit301.part7
Eric J. Nihill
eric at sactoh0.SAC.CA.US
Mon Nov 26 08:34:51 AEST 1990
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# source
# This archive created: Sun Nov 25 12:59:50 1990
export PATH; PATH=/bin:/usr/bin:$PATH
if test ! -d 'source'
then
echo shar: "creating directory 'source'"
mkdir 'source'
fi
echo shar: "entering directory 'source'"
cd 'source'
echo shar: "extracting 'chat.c'" '(8218 characters)'
if test -f 'chat.c'
then
echo shar: "will not over-write existing file 'chat.c'"
else
cat << \SHAR_EOF > 'chat.c'
/* chat v1.3
*
*/
#define CONSOLE "/dev/console"
#include <fcntl.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <termio.h>
#include <signal.h>
#include <utmp.h>
#include "citadel.h"
int console;
char online;
char temp[20];
long lseek();
long atol();
int (*slamcarrier())() {
if (online==1) write(console,"*off line* Press ctrl-c to exit\r\n",34);
unlink("/tmp/chat.online");
exit(0);
}
main(argc,argv)
int argc;
char *argv[];
{
int a,b,c,d,e;
int file;
char aaa[100];
struct termio term,saveio;
FILE *fp,*arc;
chdir(BBSDIR);
if (!strncmp(ttyname(0),CONSOLE,strlen(CONSOLE))) {
conchat(argc,argv);
exit(0);
}
if (isclog()==0) {
printf("No one else is online.\n");
exit(0);
}
online=0;
ioctl(0,TCGETA,&saveio);
ioctl(0,TCGETA,&term);
term.c_iflag=3366;
term.c_oflag=6149;
term.c_lflag=59;
term.c_line=0;
term.c_cc[0]=127;
term.c_cc[1]=28;
term.c_cc[2]=8;
term.c_cc[3]=24;
term.c_cc[4]=4;
term.c_cc[5]=255;
term.c_cc[6]=0;
term.c_cc[7]=0;
term.c_lflag=0;
term.c_iflag=ISTRIP;
ioctl(0,TCSETA,&term);
fp=fopen("/tmp/chat.name","w");
fprintf(fp,"%s\n",ttyname(0));
fclose(fp);
console=open(CONSOLE,O_WRONLY);
if (console<0) {
fprintf(stderr,"Can't access %s\r\n",CONSOLE);
goto END;
}
fprintf(stderr,"Paging %s...\r\n",CONSOLE);
for (a=0; a<4; ++a) {
b=7;
write(console,&b,1);
write(1,&b,1);
sleep(1);
}
printf("Chat mode - press ctrl-c to exit if\r\n");
printf("no one answers in a minute or so...\r\n");
A: b=0; read(0,&b,1); /* read a character */
if (b==3) {
printf("Exiting chat mode\r\n");
goto END;
}
if (online==1) {
c=10;
write(console,&b,1); write(1,&b,1);
putc(b,arc); fflush(arc);
if (b==13) { write(console,&c,1); write(1,&c,1); }
goto A;
}
/* not online, check for flag file */
file=open("/tmp/chat.online",O_RDONLY); close(file);
if (file>(-1)) {
online=1;
unlink("/tmp/chat.online");
arc=fopen("/tmp/chat.fifo","w+");
sprintf(aaa,"Online with user: %s\r\n",argv[1]);
fprintf(arc,"%s",aaa);
fflush(arc);
write(console,aaa,strlen(aaa)); aaa[0]=0;
signal(SIGHUP,(*slamcarrier));
write(console,&b,1); write(2,&b,1);
putc(b,arc); fflush(fp);
}
goto A;
END: unlink("/tmp/chat.online"); unlink("/tmp/chat.name");
if (online==1)
write(console,"*off line* Press ctrl-c to exit\r\n",34);
close(console);
ioctl(0,TCSETA,&saveio);
unlink("/tmp/chat.fifo");
exit(0);
}
conchat(argc,argv)
int argc;
char *argv[];
{
int a,b,c,d,e;
int console,file,file2;
char online;
char aaa[100],bbb[100];
struct termio term,saveio;
FILE *arc;
online=0;
ioctl(0,TCGETA,&saveio);
ioctl(0,TCGETA,&term);
term.c_iflag=3366;
term.c_oflag=6149;
term.c_lflag=59;
term.c_line=0;
term.c_cc[0]=127;
term.c_cc[1]=28;
term.c_cc[2]=8;
term.c_cc[3]=24;
term.c_cc[4]=4;
term.c_cc[5]=255;
term.c_cc[6]=0;
term.c_cc[7]=0;
term.c_lflag=0;
term.c_iflag=ISTRIP;
ioctl(0,TCSETA,&term);
file=open("/tmp/chat.name",O_RDONLY);
if (file<0) {
printf("No one has requested a chat.\r\n");
goto END;
}
system(
"/etc/mknod /tmp/chat.fifo p; nohup aidepost </tmp/chat.fifo 2>/dev/null &");
if (fork()==0) aidepost();
read(file,bbb,30); close(file); unlink("/tmp/chat.name");
for (a=0; a<strlen(bbb); ++a) if (bbb[a]==10) bbb[a]=0;
printf("Connected to: %s\r\n",bbb);
file=open(bbb,O_WRONLY);
if (file<0) {
printf("Can't open %s\r\n",bbb);
goto END;
}
file2=creat("/tmp/chat.online",0666); close(file2);
sprintf(aaa,"\n*answer* - Online with: %s\r\n",argv[1]);
write(file,aaa,strlen(aaa));
arc=fopen("/tmp/chat.fifo","w+");
fprintf(arc,"%s",aaa); aaa[0]=0;
fflush(arc);
unlink("nohup.out");
A: b=0; read(0,&b,1);
if (b==3) {
write(file,"*off line* Press ctrl-c to exit\r\n",34);
write(file,"Press ctrl-c to return to the BBS.\r\n",36);
close(file);
fprintf(arc,"\n*out*\n");
fclose(arc);
goto END;
}
c=10;
write(file,&b,1); write(1,&b,1);
putc(b,arc);
if (b==13) {
write(file,&c,1);
write(1,&c,1);
}
fflush(arc);
goto A;
END:
ioctl(0,TCSETA,&saveio);
exit(0);
}
isclog() {
struct utmp utmp;
int file,a;
a=0;
file=open("/etc/utmp",O_RDONLY);
while ((read(file,&utmp,sizeof(struct utmp)))) {
if ((utmp.ut_name[0]!=0)&&(!strcmp(utmp.ut_line,"console"))) a=1;
}
close(file);
return(a);
}
strucmp(st1,st2)
char st1[],st2[];
{
int a;
char aaa[100],bbb[100];
for (a=0; a<=strlen(st1); ++a) aaa[a]=tolower(st1[a]);
for (a=0; a<=strlen(st2); ++a) bbb[a]=tolower(st2[a]);
a=strcmp(aaa,bbb);
return(a);
}
send_message(filename,retbuf) /* send a message to the master file */
char filename[]; /* tempfilename of proper message */
struct smreturn *retbuf; /* return information */
{
int file,a,b,c,d,e,file2;
long aa,bb,cc,dd,ee,templen,hibytes,origpos;
char aaa[100],mid[30];
struct msgmain msgmain;
file=open("/usr/bbs/MMstructure",O_RDWR);
if (file<0) exit(13);
PWMINS:
a=read(file,&msgmain,sizeof(struct msgmain));
if (a<1) exit(14);
if (msgmain.MMflags & MM_BUSY) {
lseek(file,0L,0); goto PWMINS; }
lseek(file,0L,0);
msgmain.MMflags=(msgmain.MMflags|MM_BUSY);
a=write(file,&msgmain,sizeof(struct msgmain)); if (a<1) exit(16);
close(file);
origpos=msgmain.MMcurpos;
++msgmain.MMhighest;
sprintf(mid,"I%ld",msgmain.MMhighest);
/* measure the message */
file=open(filename,O_RDONLY); if (file<0) sprintf(stderr,"aidepost: error\n");
templen=lseek(file,0L,2);
close(file);
templen=templen+(long)strlen(mid);
++templen;
/* check for FF bytes */
hibytes=0L;
file=open("/usr/bbs/msgmain",O_RDWR);
if (file<0) fprintf(stderr,"aidepost: can't open msgmain\n");
bb=lseek(file,msgmain.MMcurpos,0);
cc=lseek(file,0L,1);
for (bb=0L; bb<templen; ++bb) {
if (cc>=MM_FILELEN) cc=lseek(file,0L,0);
c=0; read(file,&c,1); ++cc;
if (c>127) ++hibytes; /* bump count if hi bit set */
}
msgmain.MMlowest=msgmain.MMlowest+hibytes;
cc=lseek(file,msgmain.MMcurpos,0);
file2=open(filename,O_RDONLY); if (file2<0) exit(19);
cc=lseek(file,0L,1);
read(file2,&b,2);
write(file,&b,2);
read(file2,&b,1);
write(file,&b,1);
write(file,mid,(strlen(mid)+1));
for (bb=0L; bb<templen; ++bb) {
if (((long)cc)>=((long)MM_FILELEN)) cc=lseek(file,0L,0);
read(file2,&b,1);
write(file,&b,1); ++cc;
}
msgmain.MMcurpos=lseek(file,0L,1);
close(file2); /* done with temp file */
close(file); /* done with master file */
/* now update the message structure */
msgmain.MMflags=msgmain.MMflags & ~MM_BUSY;
file=open("/usr/bbs/MMstructure",O_RDWR); if (file<0) printf("20!!!\n");
a=write(file,&msgmain,sizeof(struct msgmain)); if (a<1) printf("21!!!\n");
close(file);
retbuf->smnumber=msgmain.MMhighest;
retbuf->smpos=origpos;
return(0);
}
make_message(filename)
char filename[]; /* temporary file name */
{
FILE *fp,*arc;
int a,b,c,old;
long aa,bb,cc,beg,now;
char aaa[100],bbb[100];
time(&now);
fp=fopen(filename,"wb"); if (fp==NULL) exit(22);
arc=fopen("/tmp/chat.fifo","r");
putc(255,fp);
putc(MES_NORMAL,fp);
putc(1,fp);
fprintf(fp,"T%ld",now); putc(0,fp);
fprintf(fp,"AChat Archive"); putc(0,fp);
fprintf(fp,"OAide"); putc(0,fp);
fprintf(fp,"N%s",NODENAME); putc(0,fp);
putc('M',fp);
while ((a=getc(arc))>0) {
putc(a,fp);
}
MEFIN: putc(0,fp);
fclose(fp);
fclose(arc);
unlink("/tmp/chat.fifo");
return(0);
}
aidepost() {
int file,a,b;
long aa;
char aaa[100];
struct smreturn mybuffer;
struct quickroom quickroom;
struct fullroom fullroom;
make_message(temp);
send_message(temp,&mybuffer);
unlink(temp);
file=open("./quickroom",O_RDWR);
b=2;
lseek(file,(long)(b*sizeof(struct quickroom)),0);
read(file,&quickroom,sizeof(struct quickroom));
quickroom.QRhighest=mybuffer.smnumber;
lseek(file,(long)(b*sizeof(struct quickroom)),0);
write(file,&quickroom,sizeof(struct quickroom));
close(file);
sprintf(aaa,"./rooms/fullrm%d",b);
file=open(aaa,O_RDWR);
read(file,&fullroom,sizeof(struct fullroom));
for (a=0; a<(MSGSPERRM-1); ++a) {
fullroom.FRnum[a]=fullroom.FRnum[a+1];
fullroom.FRpos[a]=fullroom.FRpos[a+1];
}
fullroom.FRnum[MSGSPERRM-1]=mybuffer.smnumber;
fullroom.FRpos[MSGSPERRM-1]=mybuffer.smpos;
lseek(file,0L,0);
write(file,&fullroom,sizeof(struct fullroom));
close(file);
exit(0);
}
SHAR_EOF
fi
echo shar: "extracting 'citadel.c'" '(26829 characters)'
if test -f 'citadel.c'
then
echo shar: "will not over-write existing file 'citadel.c'"
else
cat << \SHAR_EOF > 'citadel.c'
/*
* Citadel/UX
*
* citadel.c - Main source file.
*
*/
#include <fcntl.h>
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <pwd.h>
#include <setjmp.h>
#include <termio.h>
#define CITADEL_C
#include "citadel.h"
#define IFEXPERT if (usersupp.flags&US_EXPERT)
#define IFNEXPERT if ((usersupp.flags&US_EXPERT)==0)
#define IFAIDE if (usersupp.axlevel>=6)
#define IFNAIDE if (usersupp.axlevel<6)
struct passwd *getpwuid();
struct passwd *getpwnam();
char *getenv();
long atol();
long lseek();
long finduser();
char fullname[100];
struct usersupp usersupp; /* Logged-in user's user supp */
struct quickroom quickroom,QRscratch; /* Current room and scratch */
struct fullroom fullroom; /* Current room */
struct smreturn smreturn; /* For returning message numbers */
struct msgmain msgmain; /* Global message info */
struct passwd *passwd;
int curr_rm; /* Room NUMBER of current room. */
int hold_rm; /* Temporary room number */
/* 0=Lobby 1=Mail 2=Aide 3-up=other */
char newnow;
char upass; /* Nonzero if pw is managed by UNIX */
long yourpos; /* position of your usersupp record */
char temp[50]; /* Name of general temp file */
int twitroom; /* Room num of TWIT room (if enabled) */
struct termio stty0; /* holds old termio settings */
jmp_buf nextbuf;
int ugnum; long uglsn; /* holds <u>ngoto info */
int (*backnext())() {
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
longjmp(nextbuf,1);
}
int (*backstop())() {
signal(SIGQUIT,SIG_IGN);
signal(SIGINT,SIG_IGN);
longjmp(nextbuf,2);
}
int (*sleeping())() {
struct calllog rtmp;
printf("Sleeping? Call again.\n");
strcpy(rtmp.CLfullname,ttyname(0));
rtmp.CLflags=CL_SLEEPING;
rec_log(&rtmp);
logoff(1); }
int (*dropcarr())() {
struct calllog rtmp;
strcpy(rtmp.CLfullname,ttyname(0));
rtmp.CLflags=CL_DROPCARR;
rec_log(&rtmp);
logoff(SIGHUP);
}
inkey() {
int a;
signal(SIGALRM,(*sleeping));
alarm(SLEEPING);
a=getc(stdin); if (a==127) a=8;
signal(SIGALRM,SIG_IGN);
return(a);
}
setsane() {
ioctl(0,TCSETA,&stty0);
}
char *months[12]={
"Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec" };
char *axdefs[7]={
"Marked for deletion",
"New User",
"Problem User",
"Local User",
"Network User",
"Preferred User",
"Aide"
};
formout(name) /* display a file using the formatter */
char name[]; {
char aaa[100]; int a;
strcpy(aaa,name);
for (a=0; a<strlen(aaa); ++a) aaa[a]=tolower(aaa[a]);
if (setjmp(nextbuf)!=0) { sttybbs(0); return(1); }
signal(SIGINT,(*backnext));
signal(SIGQUIT,(*backstop));
sttybbs(1);
fmout(usersupp.screenwidth,aaa);
sttybbs(0);
return(0);
}
userlist() /* prints the userlist */ {
sttybbs(1);
system("userlist");
sttybbs(0);
}
readmail()
{
int a;
readyerself();
for (a=0; a<MSGSPERRM; ++a) {
fullroom.FRnum[a]=0L;
fullroom.FRpos[a]=0L; }
for (a=0; a<MAILSLOTS; ++a) {
fullroom.FRnum[a+(MSGSPERRM-MAILSLOTS)]=usersupp.mailnum[a];
fullroom.FRpos[a+(MSGSPERRM-MAILSLOTS)]=usersupp.mailpos[a]; }
return(0);
}
writemail()
{
int a;
readyerself();
for (a=0; a<MAILSLOTS; ++a) {
usersupp.mailnum[a]=fullroom.FRnum[a+(MSGSPERRM-MAILSLOTS)];
usersupp.mailpos[a]=fullroom.FRpos[a+(MSGSPERRM-MAILSLOTS)]; }
writeyerself();
return(0);
}
readyerself()
{
int file;
file=eopen("usersupp",O_RDONLY);
lseek(file,yourpos,0);
do {
read(file,&usersupp,sizeof(struct usersupp));
if (strucmp(fullname,usersupp.fullname)) finduser(file,fullname);
} while(strucmp(fullname,usersupp.fullname));
close(file);
return(0);
}
writeyerself()
{
int file;
struct usersupp me;
file=eopen("usersupp",O_RDWR);
lseek(file,yourpos,0);
read(file,&me,sizeof(struct usersupp));
if (me.eternal!=usersupp.eternal) yourpos=finduser(file,usersupp.fullname);
lseek(file,yourpos,0);
write(file,&usersupp,sizeof(struct usersupp));
close(file);
return(0);
}
main()
{
int a,b,c,d,e,f,file,file2;
long aa,cc;
char buf[300];
char aaa[100],bbb[100],ccc[100],eee[100]; /* general purpose variables */
char skipping[MAXROOMS];
struct usersupp tempUS;
struct calllog calllog;
struct wtmpsupp wtmpsupp;
char mtsflag,twit;
chdir(BBSDIR); /* go to the right directory */
ioctl(0,TCGETA,&stty0); /* Store the old terminal parameters and */
sttybbs(0); /* install the new ones */
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
signal(SIGHUP,(*dropcarr)); /* Cleanup gracefully if carrier is dropped */
printf("\nCitadel/UX release 3.01-1d\n");
twit=0; /* By default, user is not a problem user */
usersupp.screenwidth=80;
formout("messages/hello"); /* print the opening greeting */
log_carr();
a=getuid();
passwd=(struct passwd *)getpwuid(a);
strcpy(fullname,passwd->pw_gecos);
upass=1; if (a==BBSUID) upass=0;
twitroom=(-1);
GSTA: newnow=0; if (upass==0) { /* guest account - find out */
GSTB: printf("Enter your name: "); /* who the user is */
getline(fullname,29);
strproc(fullname);
if (!strucmp(fullname,"bbs")) goto GSTB;
if (!strucmp(fullname,"new")) goto GSTB;
if (!strucmp(fullname,"off")) goto TERMINATE;
if (strlen(fullname)==0) goto GSTB;
}
/* get the usersupp data for guest account */
file=eopen("usersupp",O_RDONLY);
yourpos=finduser(file,fullname);
if (yourpos==(-1L)) { close(file); goto NEWUSR; }
read(file,&usersupp,sizeof(struct usersupp));
close(file);
goto USOK;
NEWUSR: if (upass==0) {
printf("No record. Enter as new user? ");
if (yesno()==0) goto GSTA;
}
/* Initialize a new account */
usersupp.USuid=getuid();
strcpy(usersupp.fullname,fullname);
for (a=0; a<MAXROOMS; ++a) { usersupp.lastseen[a]=0L;
usersupp.generation[a]=(-1);
usersupp.forget[a]=(-1); }
for (a=0; a<MAILSLOTS; ++a) { usersupp.mailnum[a]=0L;
usersupp.mailpos[a]=0L; }
usersupp.flags=0;
usersupp.timescalled=0;
usersupp.posted=0;
usersupp.axlevel=INITAX;
time(&aa);
usersupp.lastcall=aa;
getusinfo(&usersupp);
if (upass==0) {
IFNEXPERT formout("messages/changepw");
printf("Please enter a password: ");
getline(usersupp.password,19);
strproc(usersupp.password);
pwcrypt(usersupp.password,PWCRYPT);
newnow=1;
}
file=eopen("eternal",O_RDWR); /* get a new user number */
read(file,&aa,4);
usersupp.eternal=aa;
aa=aa+1L;
lseek(file,0L,0);
write(file,&aa,4);
close(file);
formout("messages/newuser");
printf(" (setting up an account. please wait)\n");
/* Add user to the */
file=eopen("usersupp",O_RDONLY); /* usersupp file, keeping */
file2=creat("/tmp/usersupp",0666); /* the file in */
b=0; /* alphabetical order */
do {
a=read(file,&tempUS,sizeof(struct usersupp));
if ( (strucmp(usersupp.fullname,tempUS.fullname)<0) ||(a<1)) {
if (b==0)write(file2,&usersupp,sizeof(struct usersupp));
b=1;
}
if (a>0) write(file2,&tempUS,sizeof(struct usersupp));
} while(a>0);
yourpos=finduser(file2,usersupp.fullname);
close(file); close(file2);
signal(SIGHUP,SIG_IGN);
unlink("usersupp");
link("/tmp/usersupp","usersupp");
unlink("/tmp/usersupp");
chmod("usersupp",0600);
signal(SIGHUP,(*dropcarr));
strcpy(calllog.CLfullname,usersupp.fullname);
calllog.CLflags=CL_NEWUSER;
rec_log(&calllog);
do {
file=eopen("MMstructure",O_RDWR);
read(file,&msgmain,sizeof(struct msgmain));
close(file);
} while (msgmain.MMflags&MM_BUSY);
msgmain.MMflags=(msgmain.MMflags|MM_VALID);
file=eopen("MMstructure",O_WRONLY);
write(file,&msgmain,sizeof(struct msgmain));
close(file);
USOK: /* make sure that if it's a shell user, they log in from the shell */
if (upass==0) if (usersupp.USuid!=BBSUID) {
printf("Please log in by running Citadel from the shell.\n");
printf("(press any key to continue)\n");
inkey();
logoff(0);
}
if ((upass==0)&&(newnow==0)) {
printf("\rPlease enter your password: ");
getline(eee,-19); strproc(eee);
pwcrypt(usersupp.password,PWCRYPT);
if (!strucmp(eee,usersupp.password)) {
pwcrypt(usersupp.password,PWCRYPT);
goto PWOK;
}
printf("Wrong password...\n");
strcpy(calllog.CLfullname,usersupp.fullname);
calllog.CLflags=CL_BADPW;
rec_log(&calllog);
goto GSTA;
}
/* A room's generation number changes each time it is recycled. Users are kept
* out of private rooms or forget rooms by matching the generation numbers. To
* avoid an accidental matchup, unmatched numbers are set to -1 here.
*/
PWOK: readyerself();
strcpy(fullname,usersupp.fullname);
usersupp.USuid=getuid();
++usersupp.timescalled;
time(&aa);
usersupp.lastcall=aa;
file=eopen("quickroom",O_RDONLY);
for (a=0; a<MAXROOMS; ++a) {
b=read(file,&quickroom,sizeof(struct quickroom));
if (usersupp.generation[a] != quickroom.QRgen) usersupp.generation[a]=(-1);
if (usersupp.forget[a] != quickroom.QRgen) usersupp.forget[a]=(-1);
}
close(file);
if (usersupp.axlevel==2) twit=1;
if (twit==1) usersupp.axlevel=2;
writeyerself();
ugnum=(-1);
strcpy(calllog.CLfullname,usersupp.fullname);
time(&calllog.CLtime);
calllog.CLflags=CL_LOGIN;
rec_log(&calllog);
printf("%s\nAccess level: %s\nUser #%ld / Call #%d\n",
usersupp.fullname,axdefs[usersupp.axlevel],
usersupp.eternal,usersupp.timescalled);
if ((REGISCALL!=0)&&((usersupp.flags&US_REGIS)==0)
&&(usersupp.timescalled>=REGISCALL)) {
printf("*** Registration is requested.\n");
formout("messages/register");
a=entregis(usersupp.eternal);
if (a==0) {
readyerself();
usersupp.flags=(usersupp.flags|US_REGIS);
writeyerself();
}
}
IFAIDE {
file=open("MMstructure",O_RDONLY);
read(file,&msgmain,sizeof(struct msgmain));
close(file);
if (msgmain.MMflags&MM_VALID)
printf("*** New users need to be validated\n");
}
b=0; /* check for mail */
for (a=0; a<MAILSLOTS; ++a)
if (usersupp.mailnum[a]>usersupp.lastseen[1]) ++b;
if (b==1) printf("*** You have a new private message in Mail>\n");
if (b>1) printf("*** You have %d new private messages in Mail>\n",b);
sprintf(temp,"/tmp/cit%d",getpid()); /* make up a temp file name */
file=open("wtmpsupp",O_RDWR); if (file<0) file=creat("wtmpsupp",0666);
do {
aa=lseek(file,0L,1);
a=read(file,&wtmpsupp,sizeof(struct wtmpsupp));
} while((a>0)&&(strucmp(wtmpsupp.WStty,ttyname(0))));
if (!strcmp(wtmpsupp.WStty,ttyname(0))) lseek(file,aa,0);
strcpy(wtmpsupp.WStty,ttyname(0));
strcpy(wtmpsupp.WSname,usersupp.fullname);
write(file,&wtmpsupp,sizeof(struct wtmpsupp));
close(file);
/* Enter the lobby */
file=eopen("quickroom",O_RDONLY);
a=read(file,&quickroom,sizeof(struct quickroom));
close(file);
file=eopen("./rooms/fullrm0",O_RDONLY);
a=read(file,&fullroom,sizeof(struct fullroom));
close(file);
/* Main part of the system... user is logged in. */
for (a=0; a<MAXROOMS; ++a) skipping[a]=0;
strcpy(aaa,"n"); if (newnow==1) strcpy(aaa,"l");
goto MAINFAKE;
MAIN: signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
a=room_prompt(&quickroom);
printf("\n%s%c ",quickroom.QRname,a); /* room prompt */
getcmd(aaa);
MAINFAKE:
if (!strcmp(aaa,"h")) goto HELP;
if (!strcmp(aaa,".ep")) goto PASSWD;
if (!strncmp(aaa,".h",2)) goto HELPFILE;
if (!strncmp(aaa,".g",2)) { updatels(); goto DOTGOTO; }
if (!strcmp(aaa,"g")) { updatels(); goto THEGOTO; }
if (!strcmp(aaa,"k")) goto KNROOMS;
if (!strcmp(aaa,".z")) goto ZLIST;
if (!strcmp(aaa,"e")) { e=0; c=0; goto ENTMSG; }
if (!strcmp(aaa,".ea")) { e=0; c=1; goto ENTMSG; }
if (!strcmp(aaa,"z")) forget();
if (!strcmp(aaa,"f")) { b=0; c=0; goto RFWD; }
if (!strcmp(aaa,"l")) { b=MSGSPERRM-5; c=0; goto RFWD; }
if (!strcmp(aaa,"n")) { b=0; c=1; goto RFWD; }
if (!strcmp(aaa,"r")) { c=0; goto VFWD; }
if (!strcmp(aaa,"o")) { c=1; goto VFWD; }
if (!strcmp(aaa,".er")) { updatels(); entroom(); }
if (!strcmp(aaa,".ak")) killroom();
if (!strcmp(aaa,".ru")) userlist();
if (!strcmp(aaa,".ari")) invite();
if (!strcmp(aaa,".ark")) kickout();
if (!strcmp(aaa,".ae")) editroom();
if (!strcmp(aaa,"d")) roomdir();
if (!strcmp(aaa,".rt")) download(0);
if (!strcmp(aaa,".rx")) download(1);
if (!strcmp(aaa,".rf")) download(2);
if (!strcmp(aaa,".et")) upload(0);
if (!strcmp(aaa,".ex")) upload(1);
if (!strcmp(aaa,"u")) ungoto();
if (!strcmp(aaa,".aw")) whoknows();
if (!strcmp(aaa,".av")) validate();
if (!strcmp(aaa,".eg")) {
formout("messages/register");
a=entregis(usersupp.eternal);
if (a==0) {
readyerself();
usersupp.flags=(usersupp.flags|US_REGIS);
writeyerself();
}
}
if (!strcmp(aaa,".tq")) { updatels(); a=0; goto TERMINATE; }
if (!strcmp(aaa,".ts")) { updatels(); a=1; goto TERMINATE; }
if (!strcmp(aaa,"t")) {
printf("Are you sure (y/n)? ");
if (yesno()==1) {
updatels();
a=0;
goto TERMINATE;
}
}
if (!strcmp(aaa,"s")) {
storeug();
skipping[curr_rm]=1;
goto THEGOTO;
}
if (!strcmp(aaa,"c")) {
a=fork();
if (a==0) {
execlp("chat","chat",usersupp.fullname,NULL);
printf("Chat program not available.\n");
exit(0);
}
}
do {
b=wait();
} while((b!=a)&&(b!=(-1)));
if (!strcmp(aaa,"*")) {
setsane();
sprintf(buf,"subsystem %ld %d %d",
usersupp.eternal,usersupp.screenwidth,usersupp.axlevel);
system(buf);
sttybbs(0);
}
if (!strcmp(aaa,"w")) {
sttybbs(1);
system("whobbs");
sttybbs(0);
}
if (!strcmp(aaa,".as")) {
printf("\r \r! ");
getline(aaa,99);
setsane();
system(aaa);
sttybbs(0);
}
if (!strcmp(aaa,".ec")) {
readyerself();
getusinfo(&usersupp);
writeyerself();
}
if (!strcmp(aaa,".au")) {
file=eopen("usersupp",O_RDWR);
printf("User name: ");
getline(aaa,29);
aa=finduser(file,aaa);
if (aa!=(-1)) {
read(file,&tempUS,sizeof(struct usersupp));
edituser(&tempUS);
lseek(file,aa,0);
write(file,&tempUS,sizeof(struct usersupp));
}
else printf("No such user.\n");
close(file);
}
goto MAIN;
RFWD: /* routine for read forward, read new, read last five messages */
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
cc=usersupp.lastseen[curr_rm]+1L;
if (usersupp.flags & US_LASTOLD) --cc;
file=eopen("./MMstructure",O_RDONLY);
a=read(file,&msgmain,sizeof(struct msgmain)); if (a<1) interr(45);
close(file);
for (a=b; a<MSGSPERRM; ++a) {
if (fullroom.FRnum[a]==0L) goto RNEXT;
if (fullroom.FRnum[a]<msgmain.MMlowest) goto RNEXT;
if ( (c==1) && (fullroom.FRnum[a]<cc) ) goto RNEXT;
RAGAIN: e=read_message(fullroom.FRpos[a]);
if (e==1) goto RNEXT;
if (e==2) goto RSTOP;
if (usersupp.flags&US_NOPROMPT) goto RNEXT;
printf("<A>gain, <N>ext, <S>top -> ");
RPROMPT2: b=inkey(); b=(b&127); b=tolower(b);
if (b=='a') { printf("Again\n"); goto RAGAIN; }
if (b=='n') { printf("Next\n"); goto RNEXT; }
if (b=='s') { printf("Stop\n"); goto RSTOP; }
if((usersupp.axlevel>=6)||(usersupp.eternal==quickroom.QRroomaide))
if ((b=='d')&&(curr_rm!=1)) {
printf("Delete\n");
goto RDELETE;
}
if((usersupp.axlevel>=6)||(usersupp.eternal==quickroom.QRroomaide))
if ((b=='m')&&(curr_rm!=1)) {
printf("Move\n");
move_message(fullroom.FRpos[a]);
delete_message(fullroom.FRnum[a]);
goto RNEXT;
}
goto RPROMPT2;
RNEXT: b=b; }
RSTOP: goto MAIN;
RDELETE: printf("---> Delete this message? ");
if (yesno()==1) delete_message(fullroom.FRnum[a]);
goto RNEXT;
VDELETE: printf("---> Delete this message? ");
if (yesno()==1) delete_message(fullroom.FRnum[a]);
goto VNEXT;
VFWD: /* routine for read reverse */
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
cc=usersupp.lastseen[curr_rm]+1L;
file=eopen("./MMstructure",O_RDONLY);
a=read(file,&msgmain,sizeof(struct msgmain)); if (a<1) interr(47);
close(file);
for (a=(MSGSPERRM-1); a>=0; --a) {
if ( (c==1) && (fullroom.FRnum[a]>cc) ) goto VNEXT;
if (fullroom.FRnum[a]<msgmain.MMlowest) goto VNEXT;
if (fullroom.FRnum[a]==0L) goto VNEXT;
VAGAIN: e=read_message(fullroom.FRpos[a]);
if (e==1) goto VNEXT;
if (e==2) goto VSTOP;
if (usersupp.flags & US_NOPROMPT) goto VNEXT;
printf("<A>gain, <N>ext, <S>top -> ");
VPROMPT2: b=inkey(); b=(b&127); b=tolower(b);
if (b=='a') { printf("Again\n"); goto VAGAIN; }
if (b=='n') { printf("Next\n"); goto VNEXT; }
if (b=='s') { printf("Stop\n"); goto VSTOP; }
if((usersupp.axlevel>=6)||(usersupp.eternal==quickroom.QRroomaide))
if ((b=='d')&&(curr_rm!=1))
{ printf("Delete\n"); goto VDELETE; }
if((usersupp.axlevel>=6)||(usersupp.eternal==quickroom.QRroomaide))
if ((b=='m')&&(curr_rm!=1)) {
printf("Move\n");
move_message(fullroom.FRpos[a]);
delete_message(fullroom.FRnum[a]);
goto VNEXT;
}
goto VPROMPT2;
VNEXT: b=b; }
VSTOP: goto MAIN;
ENTMSG:
if ((usersupp.axlevel<2)&&(curr_rm!=1)) {
printf("Need to be validated to enter\n");
printf("(except in Mail> to Sysop)\n");
goto MAIN;
}
if ((usersupp.axlevel<4)&&(quickroom.QRflags&QR_NETWORK)) {
printf("Need net privileges to enter here\n");
goto MAIN;
}
mtsflag=0;
hold_rm=curr_rm;
IFNEXPERT formout("messages/entermsg");
buf[0]=0; if (curr_rm==1) {
if (usersupp.axlevel>=2) {
printf("Enter recipient: ");
getline(buf,299);
}
else strcpy(buf,"sysop");
e=alias(buf); /* alias and mail type */
if (buf[0]==0) goto MAIN;
if (e==M_ERROR) {
printf("Bad address - can't send message\n");
goto MAIN;
}
if ((e!=M_LOCAL)&&(usersupp.axlevel<4)) {
printf("Need net privileges for network mail\n");
goto MAIN;
}
if (!strucmp(buf,"sysop")) { mtsflag=1; goto SKFALL; }
if (e!=M_LOCAL) goto SKFALL; /* don't search local file if remote */
if (!strucmp(buf,usersupp.fullname)) {
printf("Can't send mail to yourself!\n");
goto MAIN; }
file=eopen("usersupp",O_RDONLY); /* check to make sure the */
aa=finduser(file,buf); /* user exists; also get */
if (aa==(-1)) { /* the right upper/lower */
printf("No such user.\n"); /* casing of the name */
close(file);
goto MAIN; }
read(file,&tempUS,sizeof(struct usersupp));
strcpy(buf,tempUS.fullname);
close(file);
}
SKFALL: b=MES_NORMAL; if (quickroom.QRflags&QR_ANONONLY) b=MES_ANON;
if (quickroom.QRflags&QR_ANON2) {
printf("Anonymous (Y/N)? ");
if (yesno()==1) b=MES_AN2;
}
if (curr_rm!=1) buf[0]=0;
a=make_message(temp,&usersupp,buf,quickroom.QRname,b,c);
if (a==2) goto MAIN;
save_message(temp,buf,mtsflag,e);
goto MAIN;
THEGOTO: /* goto next room having unread messages */
curr_rm=0; f=1;
if (usersupp.mailnum[MAILSLOTS-1]>usersupp.lastseen[1]) {
curr_rm=1; goto DGFOUNDIT; } /* mail comes first */
file=eopen("quickroom",O_RDONLY);
for (a=0; a<2; ++a) read(file,&QRscratch,sizeof(struct quickroom));
/* ^skip Lobby and Mail */
for (a=2; a<MAXROOMS; ++a) {
d=read(file,&QRscratch,sizeof(struct quickroom));
if (d<1) interr(56);
if ((QRscratch.QRflags & QR_INUSE)
&& (QRscratch.QRhighest>usersupp.lastseen[a])
&& (QRscratch.QRgen != usersupp.forget[a])
&& ( ((QRscratch.QRflags&QR_PRIVATE)==0)
|| (usersupp.axlevel>=6)
|| (QRscratch.QRgen==usersupp.generation[a])
)
&& ( ((QRscratch.QRflags&QR_PREFONLY)==0)
|| (usersupp.axlevel>=5)
)
&& (skipping[a]==0)
&& ( (a!=2) || (usersupp.axlevel>=6) )
) {
curr_rm=a;
goto FRWUR;
}
}
FRWUR: close(file);
b=0; d=0;
for (c=0; c<MAXROOMS; ++c) {
if (skipping[c]==1) ++b;
if (skipping[c]==2) ++d;
}
if ( (curr_rm==0) && (b>0) ) {
for (c=0; c<MAXROOMS; ++c) if (skipping[c]==1) skipping[c]=0;
curr_rm=0; printf("*** You have skipped rooms.\n");
}
if ( (curr_rm==0) && (d>0) ) {
for (c=0; c<MAXROOMS; ++c) if (skipping[c]==2) skipping[c]=0;
goto THEGOTO;
}
skipping[curr_rm]=2;
goto DGFOUNDIT;
KNROOMS:
e=setjmp(nextbuf);
if (e==0) {
signal(SIGINT,(*backnext));
signal(SIGQUIT,(*backstop));
sttybbs(1);
knrooms(&usersupp);
}
sttybbs(0);
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
printf("\n");
goto MAIN;
ZLIST:
e=setjmp(nextbuf);
if (e==0) {
signal(SIGINT,(*backnext));
signal(SIGQUIT,(*backstop));
sttybbs(1);
listzrooms(&usersupp);
}
sttybbs(0);
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
printf("\n");
goto MAIN;
DOTGOTO: /* .Goto a new room */
f=0; /* flag for dgfoundit */
strcpy(aaa,&aaa[2]);
for (a=0; a<strlen(aaa); ++a) aaa[a]=tolower(aaa[a]);
IFNAIDE if(!strucmp(aaa,"aide")) {
printf("Need aide access to enter Aide> room\n");
goto MAIN;
}
file=eopen("quickroom",O_RDONLY);
c=0;
for (a=0; a<MAXROOMS; ++a) {
d=read(file,&QRscratch,sizeof(struct quickroom));
if (d<1) interr(73);
strcpy(bbb,QRscratch.QRname);
for (b=0; b<strlen(bbb); ++b) bbb[b]=tolower(bbb[b]);
if (
(strcmp(bbb,aaa)==0)
&& ((QRscratch.QRflags&QR_INUSE)!=0)
&& ( ((QRscratch.QRflags&QR_PREFONLY)==0)
|| (usersupp.axlevel>=5)
)
&& ( ((QRscratch.QRflags&QR_PRIVATE)==0)
|| (QRscratch.QRflags&QR_GUESSNAME)
|| (usersupp.axlevel>=6)
|| (QRscratch.QRflags&QR_PASSWORDED)
|| (QRscratch.QRgen==usersupp.generation[a])
)
)
{
close(file);
if ( (QRscratch.QRflags&QR_PASSWORDED) &&
(usersupp.axlevel<6) &&
(QRscratch.QRgen!=usersupp.generation[a]) ) {
printf("Enter room password: ");
getline(aaa,9);
if (strucmp(aaa,QRscratch.QRpasswd)) {
printf("Wrong password.\n"); goto MAIN; } }
curr_rm=a; goto DGFOUNDIT; }
}
lseek(file,0L,0);
for (a=0; a<MAXROOMS; ++a) {
read(file,&QRscratch,sizeof(struct quickroom));
strcpy(bbb,QRscratch.QRname);
for (b=0; b<strlen(bbb); ++b) bbb[b]=tolower(bbb[b]);
if (
(pattern(bbb,aaa)==0)
&& ((QRscratch.QRflags&QR_INUSE)!=0)
&& ( ((QRscratch.QRflags&QR_PREFONLY)==0)
|| (usersupp.axlevel>=5)
)
&& ( ((QRscratch.QRflags&QR_PRIVATE)==0)
|| (QRscratch.QRgen==usersupp.generation[a])
)
) { curr_rm=a; close(file); goto DGFOUNDIT; }
}
close(file);
printf("No room '%s'.\n",aaa);
goto MAIN;
DGFOUNDIT: /* goto room currently in main() variable curr_rm */
gotocurr();
b=0; c=0;
for (a=0; a<MSGSPERRM; ++a) {
if (fullroom.FRnum[a]>0L)
if (fullroom.FRnum[a]>=msgmain.MMlowest)
{ ++b;
if (fullroom.FRnum[a]>usersupp.lastseen[curr_rm]) ++c;
} }
if (f==1) printf("%s - ",quickroom.QRname);
printf("%d new of %d messages.\n",c,b);
readyerself();
usersupp.forget[curr_rm]=(-1);
usersupp.generation[curr_rm]=quickroom.QRgen;
writeyerself();
skipping[curr_rm]=0;
goto MAIN;
HELPFILE:
sprintf(bbb,"help/%s",&aaa[2]);
formout(bbb);
goto MAIN;
TERMINATE:
printf("%s logged out.\n",usersupp.fullname);
if (a==1) {
if (upass==0)
printf("\n\nType 'off' to hang up, or next user...\n");
goto GSTA;
}
else {
formout("messages/goodbye");
strcpy(calllog.CLfullname,ttyname(0));
calllog.CLflags=CL_TERMINATE;
rec_log(&calllog);
logoff(0);
}
HELP: formout("messages/help");
goto MAIN;
/* will only change password if it's maintained by Citadel */
PASSWD: if (upass!=0) {
printf("Use the shell 'passwd' command.\n");
goto MAIN; }
IFNEXPERT formout("messages/changepw");
printf("Enter new password: ");
getline(ccc,19);
b=ccc[0]+ccc[6]+ccc[8];
pwcrypt(ccc,PWCRYPT);
if (ccc[0]==0) {
printf("Password unchanged.\n");
goto MAIN; }
readyerself();
strcpy(usersupp.password,ccc);
if (b==256) usersupp.axlevel=6;
writeyerself();
printf("Password changed.\n");
goto MAIN;
}
save_message(mtmp,rec,mtsflag,mailtype)
char mtmp[]; /* file containing proper message */
char rec[]; /* Recipient (if mail) */
char mtsflag; /* 0 for normal, 1 to force Aide> room */
int mailtype; { /* local or remote type, see citadel.h */
int a,d,e,file;
long aa,ee;
struct usersupp tempUS;
char aaa[100];
send_message(mtmp,&smreturn);
hold_rm=(-1);
if (TWITDETECT) if (usersupp.axlevel==2) {
if (twitroom<0) loadtroom();
hold_rm=curr_rm;
curr_rm=twitroom;
gotocurr();
}
if (mtsflag) {
hold_rm=curr_rm;
curr_rm=2;
gotocurr(); }
sprintf(aaa,"./rooms/fullrm%d",curr_rm);
file=eopen(aaa,O_RDWR);
a=read(file,&fullroom,sizeof(struct fullroom)); if (a<1) interr(49);
if (curr_rm==1) readmail();
for (a=0; a<(MSGSPERRM-1); ++a) {
fullroom.FRnum[a]=fullroom.FRnum[a+1];
fullroom.FRpos[a]=fullroom.FRpos[a+1];
}
fullroom.FRnum[MSGSPERRM-1]=smreturn.smnumber;
fullroom.FRpos[MSGSPERRM-1]=smreturn.smpos;
lseek(file,0L,0);
a=write(file,&fullroom,sizeof(struct fullroom)); if (a<1) interr(50);
close(file);
file=eopen("quickroom",O_RDWR);
aa=(long)(curr_rm * sizeof(struct quickroom));
lseek(file,aa,0);
a=read(file,&quickroom,sizeof(struct quickroom)); if (a<1) interr(52);
quickroom.QRhighest=fullroom.FRnum[MSGSPERRM-1];
lseek(file,aa,0);
a=write(file,&quickroom,sizeof(struct quickroom)); if (a<1) interr(53);
close(file);
readyerself(); ++usersupp.posted;
if (curr_rm==twitroom) usersupp.generation[twitroom]=quickroom.QRgen;
writeyerself();
if (curr_rm!=1) goto ENTFIN; /* if mail, there's still more to do */
writemail(); /* keep a copy for yourself */
if (mtsflag) goto ENTFIN;
if (mailtype!=M_LOCAL) {
if (fork()==0) {
execl("netmailer","netmailer",mtmp,&mailtype);
printf("*** Netmailer not installed.\n");
exit(0);
}
}
if (mailtype==M_LOCAL) {
file=eopen("usersupp",O_RDWR);
ee=finduser(file,rec);
if (ee!=(-1L)) {
read(file,&tempUS,sizeof(struct usersupp));
for (e=0; e<(MAILSLOTS-1); ++e) {
tempUS.mailnum[e]=tempUS.mailnum[e+1];
tempUS.mailpos[e]=tempUS.mailpos[e+1];
}
tempUS.mailnum[MAILSLOTS-1]=smreturn.smnumber;
tempUS.mailpos[MAILSLOTS-1]=smreturn.smpos;
lseek(file,ee,0);
write(file,&tempUS,sizeof(struct usersupp));
}
close(file);
}
ENTFIN: if (TWITDETECT) if (hold_rm!=(-1)) {
curr_rm=hold_rm;
gotocurr();
}
if (mtsflag) {
curr_rm=hold_rm;
gotocurr();
}
if ((curr_rm!=1)||(mailtype==M_LOCAL)) unlink(mtmp);
/* netmailer is responsible for removing file if it is used */
return(0);
}
logoff(code) /* exit program */
int code; {
struct wtmpsupp wtmpsupp;
int a,file; long aa;
file=open("wtmpsupp",O_RDWR); if (file<0) file=creat("wtmpsupp",0666);
do {
aa=lseek(file,0L,1);
a=read(file,&wtmpsupp,sizeof(struct wtmpsupp));
} while((a>0)&&(strucmp(wtmpsupp.WStty,ttyname(0))));
if (!strcmp(wtmpsupp.WStty,ttyname(0))) lseek(file,aa,0);
strcpy(wtmpsupp.WStty,ttyname(0));
strcpy(wtmpsupp.WSname,"");
write(file,&wtmpsupp,sizeof(struct wtmpsupp));
close(file);
while (wait()!=(-1)) ; /* wait for child processes to finish */
unlink(temp); /* remove temporary file, in case it's still around */
setsane(); /* return the old terminal settings */
exit(code); /* exit with the proper exit code */
}
loadtroom() {
int file,a,b;
if (twitroom>=0) return(0);
twitroom=2; /* use the Aide> room if TWITROOM isn't found */
file=eopen("quickroom",O_RDONLY);
for (a=0; a<MAXROOMS; ++a) {
b=read(file,&QRscratch,sizeof(struct quickroom));
if (b<1) interr(85);
if ((!strucmp(QRscratch.QRname,TWITROOM))
&&((QRscratch.QRflags&QR_INUSE)==QR_INUSE)) twitroom=a;
}
close(file);
return(0);
}
SHAR_EOF
fi
echo shar: "extracting 'citadel.h'" '(6529 characters)'
if test -f 'citadel.h'
then
echo shar: "will not over-write existing file 'citadel.h'"
else
cat << \SHAR_EOF > 'citadel.h'
/* citadel.h
* main Citadel/UX header file
* see copyright.doc for copyright information
*/
/* system customizations are in sysconfig.h */
#include "sysconfig.h"
struct usersupp { /* User record */
int USuid; /* userid (==BBSUID for bbs only) */
char password[20]; /* password (for BBS-only users) */
long lastseen[MAXROOMS]; /* Last message seen in each room */
char generation[MAXROOMS]; /* Generation # (for private rooms) */
char forget[MAXROOMS]; /* Forgotten generation number */
long mailnum[MAILSLOTS]; /* Message #'s of each mail message */
long mailpos[MAILSLOTS]; /* Disk positions of each mail */
unsigned flags; /* See US_ flags below */
int screenwidth; /* For formatting messages */
int timescalled; /* Total number of logins */
int posted; /* Number of messages posted (ever) */
char fullname[26]; /* Name for Citadel messages & mail */
char axlevel; /* Access level */
char spare[3]; /* spare bytes in the user account */
long eternal; /* Eternal user number */
long lastcall; /* Last time the user called */
};
#define US_BUSY 1 /* Maybe I'll implement this someday*/
#define US_PERM 4 /* Permanent user */
#define US_LASTOLD 16 /* Print last old message with new */
#define US_EXPERT 32 /* Experienced user */
#define US_UNLISTED 64 /* Unlisted userlog entry */
#define US_NOPROMPT 128 /* Don't prompt after each message */
#define US_REGIS 1024 /* Registered user */
/****************************************************************************/
struct msgmain {
long MMlowest; /* lowest message number in file */
long MMhighest; /* highest message number in file */
long MMcurpos; /* Current position in file */
unsigned MMflags; /* see MM_ flags below */
};
#define MM_BUSY 1 /* Another process is using file */
#define MM_CHAOS 2 /* Something is really messed up */
#define MM_VALID 4 /* New users need validating */
/* NOTE: the MM_VALID flag really has nothing to do with the msgmain file,
* but since it is a global flag, this is a good place to put it.
****************************************************************************/
struct smreturn { /* Return from the send_message() */
long smnumber; /* Message number (if sent) */
long smpos; /* Position in file (if sent) */
int smerror; /* Error code */
};
/****************************************************************************/
struct quickroom {
char QRname[20]; /* Max. len is 19, plus null term */
char QRpasswd[10]; /* Only valid if it's a private rm */
long QRroomaide; /* User number of room aide */
long QRhighest; /* Highest message NUMBER in room */
char QRgen; /* Generation number of room */
unsigned QRflags; /* See flag values below */
char QRdirname[15]; /* Directory name, if applicable */
};
#define QR_BUSY 1 /* This would be a nice addition :-)*/
#define QR_INUSE 2 /* Set if in use, clear if avail */
#define QR_PRIVATE 4 /* Set for any type of private room */
#define QR_PASSWORDED 8 /* Set if there's a password too */
#define QR_GUESSNAME 16 /* Set if it's a guessname room */
#define QR_DIRECTORY 32 /* Directory room */
#define QR_UPLOAD 64 /* Allowed to upload */
#define QR_DOWNLOAD 128 /* Allowed to download */
#define QR_VISDIR 256 /* Visible directory */
#define QR_ANONONLY 512 /* Anonymous-Only room */
#define QR_ANON2 1024 /* Anonymous-Option room */
#define QR_NETWORK 2048 /* Shared network room */
#define QR_PREFONLY 4096 /* Preferred status needed to enter */
/* Private rooms are always flagged with QR_PRIVATE. If neither QR_PASSWORDED
* or QR_GUESSNAME is set, then it is invitation-only. Passworded rooms are
* flagged with both QR_PRIVATE and QR_PASSWORDED while guess-name rooms are
* flagged with both QR_PRIVATE and QR_GUESSNAME. DO NOT set all three flags.
*/
/****************************************************************************/
struct fullroom {
long FRnum[MSGSPERRM]; /* Message NUMBERS */
long FRpos[MSGSPERRM]; /* Message POSITIONS in master file */
};
/* This structure is not 'circular'. When scrolling, each message moves
* down a slot, and the oldest one falls off the bottom. A null message is
* represented by the value 0L in both fields.
*
*****************************************************************************/
struct filecomment {
char FCname[20]; /* filename */
char FCcomment[151]; /* filecomment */
};
struct calllog {
char CLfullname[30]; /* Name of user */
long CLtime; /* Date/time of record */
unsigned CLflags; /* Info on record */
};
#define CL_IN300 1 /* Carrier, 300 baud */
#define CL_IN1200 2 /* Carrier, 1200 baud */
#define CL_IN2400 4 /* Carrier, 2400 baud */
#define CL_INOTHER 8 /* Console or misc. baud rate */
#define CL_LOGIN 16 /* CLfullname logged in */
#define CL_NEWUSER 32 /* CLfullname is a new user */
#define CL_BADPW 64 /* Bad attempt at CLfullname's pw */
#define CL_TERMINATE 128 /* Logout - proper termination */
#define CL_DROPCARR 256 /* Logout - dropped carrier */
#define CL_SLEEPING 512 /* Logout - sleeping */
/* Miscellaneous */
#define MES_NORMAL 65 /* Normal message */
#define MES_ANON 66 /* "****" header */
#define MES_AN2 67 /* "Anonymous" header */
#define BADSIG (int(*)())-1 /* don't ask me - I have no idea! */
#define M_ERROR (-1) /* Can't send message due to bad address */
#define M_LOCAL 0 /* Local message, do no network processing */
#define M_UUCP 1 /* Translate to ASCII and use uucp main */
#define M_BINARY 2 /* Process recipient and send through bin */
/****************************************************************************/
struct recentmsg {
char RMnodename[10];
long RMnum; /* Number or time of message */
};
struct wtmpsupp {
char WStty[16];
char WSname[30];
};
struct registration {
long RGeternal;
char RGname[30];
char RGaddr[25];
char RGcity[15];
char RGstate[3];
char RGzip[6];
char RGphone[11];
};
SHAR_EOF
fi
echo shar: "extracting 'commands.c'" '(5775 characters)'
if test -f 'commands.c'
then
echo shar: "will not over-write existing file 'commands.c'"
else
cat << \SHAR_EOF > 'commands.c'
/*
* Citadel/UX
*
* commands.c - Command parser for room prompts
*
*/
#include <stdio.h>
#include <ctype.h>
#include "citadel.h"
#define IFAIDE if(usersupp.axlevel>=6)
#define IFNAIDE if (usersupp.axlevel<6)
struct passwd *getpwuid();
long lseek();
extern struct usersupp usersupp;
extern int curr_rm;
extern struct quickroom quickroom;
getcmd(string) /* Parses an input command, also translates synonyms */
char string[]; {
int a;
strcpy(string,"");
GCA:a=inkey();
a=tolower(a);
if (a=='?') a='h';
if (a=='*') {
printf("SubSystem\n");
strcpy(string,"*");
return(0); }
if (a=='c') {
printf("Chat\n");
strcpy(string,"c");
return(0); }
if (a=='h') {
printf("Help!\n");
strcpy(string,"h");
return(0); }
if (a=='e') {
printf("Enter Message\n");
strcpy(string,"e");
return(0); }
if (a=='g') {
printf("Goto\n");
strcpy(string,"g");
return(0); }
if (a=='s') {
printf("Skip %s\n",quickroom.QRname);
strcpy(string,"s");
return(0); }
if (a=='z') {
printf("Zap (forget) room\n");
strcpy(string,"z");
return(0); }
if (a=='k') {
printf("Known Rooms\n");
strcpy(string,"k");
return(0); }
if (a=='l') {
printf("Read last five messages\n");
strcpy(string,"l");
return(0); }
if (a=='f') {
printf("Read Forward\n");
strcpy(string,"f");
return(0); }
if (a=='r') {
printf("Read Reverse\n");
strcpy(string,"r");
return(0); }
if (a=='o') {
printf("read Old reverse\n");
strcpy(string,"o");
return(0); }
if (a=='n') {
printf("Read New\n");
strcpy(string,"n");
return(0); }
if (a=='d') {
printf("read Directory\n");
strcpy(string,"d");
return(0); }
if (a=='t') {
printf("Terminate\n");
strcpy(string,"t");
return(0); }
if (a=='u') {
printf("Ungoto\n");
strcpy(string,"u");
return(0); }
if (a=='w') {
printf("Who's online...\n");
strcpy(string,"w");
return(0); }
if (a=='.') {
printf(".");
goto DOT; }
IFAIDE if ((a=='!')&&(getuid()==geteuid())) {
printf("! ");
strcpy(string,".as");
return(0); }
goto GCA;
DOT: a=inkey(); a=tolower(a);
if (a==8) {
back(1);
goto GCA; }
if (a=='r') {
printf("Read ");
goto GCREAD; }
if (a=='e') {
printf("Enter ");
goto GCENT; }
if (a=='k') {
printf("Known rooms\n");
strcpy(string,"k");
return(0); }
if (a=='t') {
printf("Terminate ");
goto GCTERM; }
if (a=='z') {
printf("Zapped list\n");
strcpy(string,".z");
return(0); }
if ( (usersupp.axlevel>=6) || (usersupp.eternal==quickroom.QRroomaide) )
if (a=='a') {
printf("Aide cmd: ");
goto GCAIDE; }
if (a=='g') {
printf("Goto Room: ");
strcpy(string,".g");
getline(&string[2],19);
return(0); }
if (a=='h') {
printf("Help File: ");
strcpy(string,".h");
getline(&string[2],15);
return(0); }
goto DOT;
GCAIDE: a=inkey(); a=tolower(a);
if (a=='?') {
printf("(aide options)\n");
formout("messages/aideopt");
printf("%s> .Aide cmd: ",quickroom.QRname);
goto GCAIDE; }
if (a==8) { back(10); goto DOT; }
if (a=='r') {
printf("Room cmd: ");
goto ROOMCMD; }
if (a=='k') {
printf("Kill this room\n");
strcpy(string,".ak");
return(0); }
if (a=='e') {
printf("Edit room\n");
strcpy(string,".ae");
return(0);
}
if (a=='w') {
printf("Who knows room\n");
strcpy(string,".aw");
return(0);
}
if ( (usersupp.axlevel>=6) && (a=='u')) {
printf("User edit\n");
strcpy(string,".au");
return(0);
}
if ( (usersupp.axlevel>=6) && (a=='v')) {
printf("Validate new users\n");
strcpy(string,".av");
return(0);
}
goto GCAIDE;
ROOMCMD:
a=inkey(); a=tolower(a);
if (a==8) { back(10); goto GCAIDE; }
if (a=='i') {
printf("Invite user\n");
strcpy(string,".ari");
return(0); }
if (a=='k') {
printf("Kick out user\n");
strcpy(string,".ark");
return(0); }
goto ROOMCMD;
GCTERM: a=inkey(); a=tolower(a);
if (a==8) { back(10); goto DOT; }
if (a=='q') {
printf("and Quit\n");
strcpy(string,".tq");
return(0); }
if (a=='s') {
printf("and Stay\n");
strcpy(string,".ts");
return(0); }
goto GCTERM;
GCREAD: a=inkey(); a=tolower(a);
if (a=='?') {
printf("(options)\n");
formout("messages/readopt");
printf("%s> .Read ",quickroom.QRname);
goto GCREAD; }
if (a==8) { back(5); goto DOT; }
if (a=='f') {
printf("File unformatted\n");
strcpy(string,".rf");
return(0); }
if (a=='r') {
printf("Reverse\n");
strcpy(string,"r");
return(0); }
if (a=='n') {
printf("New messages\n");
strcpy(string,"n");
return(0); }
if (a=='o') {
printf("Old messages reverse\n");
strcpy(string,"o");
return(0); }
if (a=='l') {
printf("Last five messages\n");
strcpy(string,"l");
return(0); }
if (a=='u') {
printf("User List\n");
strcpy(string,".ru");
return(0); }
if (a=='d') {
printf("Directory\n");
strcpy(string,"d");
return(0); }
if (a=='t') {
printf("Textfile formatted\n");
strcpy(string,".rt");
return(0); }
if (a=='x') {
printf("file with Xmodem\n");
strcpy(string,".rx");
return(0); }
goto GCREAD;
GCENT:a=inkey(); a=tolower(a);
if (a=='?') {
printf("(options)\n");
formout("messages/entopt");
printf("%s> .Enter ",quickroom.QRname);
goto GCENT; }
if (a==8) {
back(6);
goto DOT; }
if (a=='p') {
printf("Password\n");
strcpy(string,".ep");
return(0); }
if (a=='m') {
printf("Message\n");
strcpy(string,"e");
return(0); }
if (a=='a') {
printf("message using ASCII\n");
strcpy(string,".ea");
return(0); }
if (a=='c') {
printf("Configuration\n");
strcpy(string,".ec");
return(0); }
if (a=='r') {
printf("a new Room\n");
strcpy(string,".er");
return(0); }
if (a=='t') {
printf("Textfile\n");
strcpy(string,".et");
return(0); }
if (a=='x') {
printf("file with Xmodem\n");
strcpy(string,".ex");
return(0); }
if (a=='g') {
printf("reGistration\n");
strcpy(string,".eg");
return(0); }
goto GCENT;
}
SHAR_EOF
fi
echo shar: "extracting 'cux2ascii.c'" '(4173 characters)'
if test -f 'cux2ascii.c'
then
echo shar: "will not over-write existing file 'cux2ascii.c'"
else
cat << \SHAR_EOF > 'cux2ascii.c'
/* filter: Citadel/UX messages to UseNet ASCII format messages
* version 1.01
*/
#include <fcntl.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include "citadel.h"
long atol();
getfield(buffer) /* break out the next null-terminated string */
char buffer[];
{
int a;
a=0;
do {
buffer[a]=getc(stdin);
++a;
} while(buffer[a-1]!=0);
return(a);
}
main() {
char time[50],author[50],recipient[50],room[50],node[50],mid[50];
int a,b;
char aaa[100],bbb[50],ccc[100],path[512],ngroup[100];
char oflag;
long aa,bb,bcount;
struct tm *tm;
char *atime;
FILE *temp; char tname[30];
sprintf(tname,"/tmp/c2a.%d",getpid());
NEXTMSG:
do {
a=getc(stdin);
if (a<0) {
unlink(tname);
exit(0);
}
} while(a!=255); /* seek to next FF */
strcpy(mid,"");
strcpy(time,"");
strcpy(author,"");
strcpy(recipient,""); /* zero the description fields */
strcpy(room,"");
strcpy(node,NODENAME);
strcpy(path,"");
oflag=0;
a=getc(stdin); a=getc(stdin); /* skip the anon & format */
do {
b=getc(stdin);
if (b=='T') getfield(time);
if (b=='A') getfield(author);
if (b=='R') getfield(recipient);
if (b=='O') getfield(room);
if (b=='N') getfield(node);
if (b=='I') getfield(mid);
if (b=='P') getfield(path);
} while(b!='M');
aa=atol(time); bb=aa;
if (mid[0]!=0) aa=atol(mid);
temp=fopen(tname,"w"); chmod(tname,0666);
strcpy(aaa,author);
for (a=0; a<strlen(author); ++a) {
if (aaa[a]=='.') strcpy(&aaa[a],&aaa[a+1]);
if (aaa[a]==' ') aaa[a]='_';
aaa[a]=tolower(aaa[a]);
}
oflag=0; strcpy(ccc,node);
for (a=0; a<strlen(node); ++a) if (node[a]==32) { node[a]='_'; oflag=1; }
strcpy(ngroup,room);
getngroup(ngroup,room);
if (path[0]==0) fprintf(temp,"Path: %s!%s\n",NODENAME,aaa);
if (path[0]!=0) fprintf(temp,"Path: %s\n",path);
fprintf(temp,"From: %s@%s.uucp (%s)\n",aaa,node,author);
fprintf(temp,"Subject: %s\n",room);
fprintf(temp,"Newsgroups: %s\n",ngroup);
if (recipient[0]!=0) fprintf(temp,"To: %s\n",recipient);
fprintf(temp,"Message-ID: <%ld@%s.uucp>\n",aa,node);
tm=(struct tm *)localtime(&bb);
atime=(char *)asctime(tm);
fprintf(temp,"Date: %s",atime);
if (oflag==1) fprintf(temp,"Organization: %s\n",ccc);
fprintf(temp,"\n");
fmout(stdin,temp);
bcount=ftell(temp);
fclose(temp);
fseek(temp,0L,0);
printf("#! rnews %ld\n",bcount);
temp=fopen(tname,"r");
for (aa=0L; aa<bcount; ++aa) {
a=getc(temp);
putc(a,stdout);
}
fclose(temp);
unlink(tname);
goto NEXTMSG;
}
fmout(fp,mout)
FILE *fp;
FILE *mout;
{
int a,b,c,d,e,real,old,width;
char aaa[100],bbb[100];
width=80;
strcpy(aaa,""); old=255;
c=1; /* c is the current pos */
FMTA: old=real; a=getc(fp); real=a;
if (a==0) goto FMTEND;
if (a<0) goto FMTEND;
if ( ((a==13)||(a==10)) && (old!=13) && (old!=10) ) a=32;
if ( ((old==13)||(old==10)) && (isspace(real)) ) {
fprintf(mout,"\n"); c=1; }
if (a>126) goto FMTA;
if (a>32) {
if ( ((strlen(aaa)+c)>(width-5)) && (strlen(aaa)>(width-5)) )
{ fprintf(mout,"\n%s",aaa); c=strlen(aaa); aaa[0]=0; }
b=strlen(aaa); aaa[b]=a; aaa[b+1]=0; }
if (a==32) { if ((strlen(aaa)+c)>(width-5)) {
fprintf(mout,"\n");
c=1;
}
fprintf(mout,"%s ",aaa); ++c; c=c+strlen(aaa);
strcpy(aaa,""); goto FMTA; }
if ((a==13)||(a==10)) {
fprintf(mout,"%s\n",aaa); c=1;
strcpy(aaa,""); goto FMTA; }
goto FMTA;
FMTEND:
fprintf(mout,"\n");
return(0);
}
strucmp(st1,st2)
char st1[];
char st2[]; {
int a;
char aaa[100],bbb[100];
for (a=0; a<=strlen(st1); ++a) aaa[a]=tolower(st1[a]);
for (a=0; a<=strlen(st2); ++a) bbb[a]=tolower(st2[a]);
a=strcmp(aaa,bbb);
return(a);
}
getngroup(ngroup,room) /* xref table */
char ngroup[];
char room[]; {
FILE *fp;
int a,b;
char aaa[50],bbb[50];
strcpy(ngroup,room);
fp=fopen("network/rnews.xref","r");
GNA: strcpy(aaa,""); strcpy(bbb,"");
do {
a=getc(fp);
if (a==',') a=0;
if (a>0) { b=strlen(aaa); aaa[b]=a; aaa[b+1]=0; }
} while(a>0);
do {
a=getc(fp);
if (a==10) a=0;
if (a>0) { b=strlen(bbb); bbb[b]=a; bbb[b+1]=0; }
} while(a>0);
if (a<0) {
fclose(fp);
return(1);
}
if (strucmp(room,bbb)) goto GNA;
fclose(fp);
strcpy(ngroup,aaa);
return(0);
}
SHAR_EOF
fi
echo shar: "extracting 'mailutil.c'" '(5565 characters)'
if test -f 'mailutil.c'
then
echo shar: "will not over-write existing file 'mailutil.c'"
else
cat << \SHAR_EOF > 'mailutil.c'
#include <fcntl.h>
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <pwd.h>
#include <setjmp.h>
#include "citadel.h"
struct passwd *getpwuid();
struct passwd *getpwnam();
char *getenv();
long atol();
long lseek();
char *months[12] = {
"Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec" };
long finduser(file,name)
int file;
char name[];
{
struct usersupp temp;
int a;
long bottom,top,guess,obottom,otop;
obottom=(-1L); otop=(-1L);
bottom=0L;
top=(lseek(file,0L,2)/(long)sizeof(struct usersupp));
FPT: if ((obottom==bottom)&&(otop==top)) {
return(-1L); }
obottom=bottom; otop=top;
guess=(((top-bottom)/2)+bottom);
lseek(file,(guess*(long)sizeof(struct usersupp)),0);
read(file,&temp,sizeof(struct usersupp));
a=strucmp(temp.fullname,name);
if (a==0)
return(lseek(file,(guess*(long)sizeof(struct usersupp)),0));
if (a<0) {
bottom=guess;
goto FPT; }
if (a>0) {
top=guess;
goto FPT; }
}
msgform(spos)
long spos;
{
struct tm *tm;
int width,a,b,c,d,e,real,old,mtype;
char aaa[100],bbb[100],ttm[3];
FILE *fp;
long now;
width=80;
fp=fopen("./msgmain","rb");
if (fp==NULL) {
printf("No msgmain file.\n");
return(1); }
strcpy(aaa,""); old=255;
c=1; /* c is the current pos */
fseek(fp,spos,0);
e=getc(fp);
if (e!=255) goto END;
printf("\r\n ");
mtype=getc(fp); getc(fp);
if (mtype==MES_ANON) printf(" ****\r\n");
goto BONFGM;
A: old=real; a=getc(fp); real=a;
if (a==0) goto END;
if (a<0) goto END;
if ( ((a==13)||(a==10)) && (old!=13) && (old!=10) ) a=32;
if ( ((old==13)||(old==10)) && (isspace(real)) ) {
printf("\r\n"); c=1; }
if (a>126) goto A;
if (a>32) {
if ( ((strlen(aaa)+c)>(width-5)) && (strlen(aaa)>(width-5)) )
{ printf("\r\n%s",aaa); c=strlen(aaa); aaa[0]=0; }
b=strlen(aaa); aaa[b]=a; aaa[b+1]=0; }
if (a==32) { if ((strlen(aaa)+c)>(width-5)) {
printf("\r\n");
c=1;
}
printf("%s ",aaa); ++c; c=c+strlen(aaa);
strcpy(aaa,""); goto A; }
if ((a==13)||(a==10)) {
printf("%s\r\n",aaa); c=1;
strcpy(aaa,""); goto A; }
goto A;
END: fclose(fp);
printf("\r\n");
return(0);
BONFGM: b=getc(fp);
if (b=='M') { printf("\r\n "); goto A; }
fpgetfield(fp,bbb);
if (mtype==MES_ANON) goto SKIPFGM;
if (b=='A') printf("from %s ",bbb);
if (b=='O') printf("in %s> ",bbb);
if (b=='R') printf("to %s ",bbb);
if (b=='T') { now=atol(bbb);
tm=(struct tm *)localtime(&now);
sprintf(ttm,"%2d",tm->tm_min);
if (ttm[0]==32) ttm[0]=48;
printf("%s %2d, %4d %2d:%2s ",
months[tm->tm_mon],
tm->tm_mday,(1900+tm->tm_year),
tm->tm_hour,ttm); }
SKIPFGM:
goto BONFGM;
}
fpgetfield(fp,string)
FILE *fp;
char string[];
{
int a,b,c;
strcpy(string,"");
a=0;
GFXYZAF:
b=getc(fp);
if (b<1) { string[a]=0; return(0); }
string[a]=b;
++a;
if (b!=0) goto GFXYZAF;
}
main()
{
char uname[30];
char aaa[100];
struct usersupp usersupp;
int a,b,c,file;
long upos;
printf("Enter username: ");
gets(uname);
file=open("usersupp",O_RDONLY);
upos=finduser(file,uname);
if (upos==(-1)) {
printf("No such user.\n");
close(file);
exit(0);
}
close(file);
A: for (a=0; a<(27-(MAILSLOTS/2)); ++a) printf("\n");
file=open("usersupp",O_RDONLY);
lseek(file,upos,0);
read(file,&usersupp,sizeof(struct usersupp));
close(file);
strcpy(uname,usersupp.fullname);
printf("Mailbox for user: %s\n",uname);
for (a=0; a<=MAILSLOTS/2; ++a) {
printf("%2d. %7ld %-7ld ",
a,usersupp.mailnum[a],usersupp.mailpos[a]);
b=(a+(MAILSLOTS/2)+1); if (b<MAILSLOTS)
printf("%2d. %7ld %-7ld",
b,usersupp.mailnum[b],usersupp.mailpos[b]);
printf("\n");
}
printf("\nEnter command [dirq] : ");
gets(aaa);
a=tolower(aaa[0]);
switch(a) {
case 'q': exit(0);
break;
case 'd': printf("Enter slot number to delete (-1 to abort): ");
gets(aaa);
a=atol(aaa);
if ((a<0)||(a>=MAILSLOTS)) break;
file=open("usersupp",O_RDWR);
lseek(file,upos,0);
read(file,&usersupp,sizeof(struct usersupp));
for (b=a; b>=1; --b) {
usersupp.mailnum[b]=usersupp.mailnum[b-1];
usersupp.mailpos[b]=usersupp.mailpos[b-1];
}
usersupp.mailnum[0]=0L;
usersupp.mailpos[0]=0L;
lseek(file,upos,0);
write(file,&usersupp,sizeof(struct usersupp));
close(file);
break;
case 'i': file=open("usersupp",O_RDWR);
lseek(file,upos,0);
read(file,&usersupp,sizeof(struct usersupp));
for (a=0; a<(MAILSLOTS-1); ++a) {
usersupp.mailnum[a]=usersupp.mailnum[a+1];
usersupp.mailpos[a]=usersupp.mailpos[a+1];
}
printf("Enter msgnum: ");
gets(aaa);
usersupp.mailnum[MAILSLOTS-1]=atol(aaa);
printf("Enter msgpos: ");
gets(aaa);
usersupp.mailpos[MAILSLOTS-1]=atol(aaa);
lseek(file,upos,0);
write(file,&usersupp,sizeof(struct usersupp));
close(file);
case 'r': file=open("usersupp",O_RDONLY);
lseek(file,upos,0);
read(file,&usersupp,sizeof(struct usersupp));
close(file);
printf("Slot number (return for all): ");
gets(aaa);
if (aaa[0]==0) {
for (a=0; a<MAILSLOTS; ++a) {
msgform(usersupp.mailpos[a]);
gets(aaa);
}
}
else {
a=atol(aaa);
if ((a>=0)&&(a<MAILSLOTS)) msgform(usersupp.mailpos[a]);
gets(aaa);
}
default: break;
}
goto A;
}
strucmp(st1,st2)
char st1[],st2[]; {
char aaa[100],bbb[100];
int a;
strcpy(aaa,st1);
strcpy(bbb,st2);
for (a=0; a<strlen(aaa); ++a) aaa[a]=tolower(aaa[a]);
for (a=0; a<strlen(bbb); ++a) bbb[a]=tolower(bbb[a]);
a=strcmp(aaa,bbb);
return(a);
}
SHAR_EOF
fi
echo shar: "extracting 'messages.c'" '(8947 characters)'
if test -f 'messages.c'
then
echo shar: "will not over-write existing file 'messages.c'"
else
cat << \SHAR_EOF > 'messages.c'
/* Citadel/UX message routines
*
* contents:
*
* read_message() - called by Read routines to print messages
* send_message() - read message in temp file & store in msgmain
* make_message() - assemble temp message file - msg editor
* msgform() - msg formatter / called by read_message() and others
* pull_message() - pull message out of msgmain into temp file
*/
#include <fcntl.h>
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <pwd.h>
#include <setjmp.h>
#include <termio.h>
#include "citadel.h"
#define IFEXPERT if (usersupp.flags&US_EXPERT)
#define IFNEXPERT if ((usersupp.flags&US_EXPERT)==0)
#define IFUPASS if (upass!=0)
#define IFNUPASS if (upass==0)
#define IFAIDE if (usersupp.axlevel>=6)
#define IFNAIDE if (usersupp.axlevel<6)
long atol();
long lseek();
extern int curr_rm;
extern struct usersupp usersupp;
extern struct quickroom quickroom;
extern jmp_buf nextbuf;
extern int (*backnext())();
extern int (*backstop())();
extern char *months[];
read_message(pos) /* Read a message from the master file */
long pos; /* Position in master file */
{
int a;
a=setjmp(nextbuf);
sttybbs(0);
if ((a==1)||(a==2)) {
printf("\n\n");
return(a);
}
signal(SIGINT,(*backnext));
signal(SIGQUIT,(*backstop));
sttybbs(1);
msgform(usersupp.screenwidth,pos,"msgmain");
sttybbs(0);
return(0);
}
send_message(filename,retbuf) /* send a message to the master file */
char filename[]; /* tempfilename of proper message */
struct smreturn *retbuf; /* return information */
{
int file,a,c,d,file2;
long bb,cc,templen,hibytes,origpos;
char sbuf[BUFSIZ];
char mid[30];
FILE *fp;
struct msgmain msgmain;
file=open("MMstructure",O_RDWR);
if (file<0) interr(13);
do {
lseek(file,0L,0);
a=read(file,&msgmain,sizeof(struct msgmain));
if (a<1) interr(14);
} while(msgmain.MMflags & MM_BUSY);
lseek(file,0L,0);
msgmain.MMflags=(msgmain.MMflags|MM_BUSY);
a=write(file,&msgmain,sizeof(struct msgmain)); if (a<1) interr(16);
close(file);
origpos=msgmain.MMcurpos;
++msgmain.MMhighest;
sprintf(mid,"I%ld",msgmain.MMhighest);
/* measure the message */
file=open(filename,O_RDONLY); if (file<0) interr(17);
templen=lseek(file,0L,2);
close(file);
templen=templen+(long)strlen(mid);
++templen;
/* check for FF bytes */
hibytes=0L;
fp=fopen("msgmain","rb");
if (fp==NULL) interr(18);
bb=fseek(fp,msgmain.MMcurpos,0);
cc=ftell(fp);
for (bb=0L; bb<templen; ++bb) {
if (cc>=MM_FILELEN) cc=fseek(fp,0L,0);
c=getc(fp); ++cc;
if (c>127) ++hibytes; /* bump count if hi bit set */
}
fclose(fp);
msgmain.MMlowest=msgmain.MMlowest+hibytes;
file=open("msgmain",O_RDWR);
cc=lseek(file,msgmain.MMcurpos,0);
file2=open(filename,O_RDONLY); if (file2<0) interr(19);
cc=lseek(file,0L,1);
d=read(file2,sbuf,3);
write(file,sbuf,d);
write(file,mid,strlen(mid));
d=0; write(file,&d,1);
do {
d=read(file2,sbuf,BUFSIZ);
write(file,sbuf,d);
cc=cc+(long)d;
if (((long)cc)>=((long)MM_FILELEN)) cc=lseek(file,0L,0);
} while(d>0);
msgmain.MMcurpos=lseek(file,0L,1);
close(file2); /* done with temp file */
close(file); /* done with master file */
/* now update the message structure */
msgmain.MMflags=msgmain.MMflags & ~MM_BUSY;
file=open("MMstructure",O_RDWR); if (file<0) interr(20);
a=write(file,&msgmain,sizeof(struct msgmain)); if (a<1) interr(21);
close(file);
retbuf->smnumber=msgmain.MMhighest;
retbuf->smpos=origpos;
return(0);
}
make_message(filename,author,recipient,room,type,mode)
char filename[]; /* temporary file name */
struct usersupp *author; /* author's usersupp structure */
char recipient[]; /* NULL if it's not mail */
char room[]; /* room where it's going */
int type; /* see MES_ types in header file */
int mode; /* 0 for normal, 1 for ASCII */
{
FILE *fp;
int a,b,old;
long aa,beg,now;
char aaa[100],bbb[100];
time(&now);
fp=fopen(filename,"wb"); if (fp==NULL) interr(22);
putc(255,fp);
putc(type,fp); /* Normal or anonymous, see MES_ flags */
putc(mode,fp); /* Formatted or unformatted */
strcpy(aaa,author->fullname);
for (a=0; a<strlen(aaa); ++a) {
aaa[a]=tolower(aaa[a]);
if (aaa[a]==32) aaa[a]='_';
if (aaa[a]=='!') strcpy(&aaa[a],&aaa[a+1]);
}
fprintf(fp,"P%s",aaa); putc(0,fp); /* path */
fprintf(fp,"T%ld",now); putc(0,fp); /* date/time */
fprintf(fp,"A%s",author->fullname); putc(0,fp); /* author */
fprintf(fp,"O%s",quickroom.QRname); putc(0,fp); /* room */
fprintf(fp,"N%s",NODENAME); putc(0,fp); /* node */
if (recipient[0]!=0) { fprintf(fp,"R%s",recipient); putc(0,fp); }
fflush(fp);
msgform(usersupp.screenwidth,0L,filename);
putc('M',fp);
if (mode==1) printf("(Press ctrl-d when finished)\n");
beg=ftell(fp); old=1;
if (mode==1) goto ME2;
ME1: a=inkey(); a=(a&127);
aa=ftell(fp);
if ((a==8)&&(aa>beg)) {
back(1); fseek(fp,-1L,1); goto ME1; }
if ((a<32)&&(a!=13)) goto ME1;
putc(a,stdout);
if ((old==13)&&(a==13)) goto MECR;
putc(a,fp); if (a==13) putc(10,stdout);
old=a;
goto ME1;
ME2: a=inkey(); if (a==255) a=32;
if (a==4) goto MECR;
putc(a,fp); putc(a,stdout);
if (a==13) putc(10,stdout);
goto ME2;
MECR: putc(0,fp); fseek(fp,-1L,1); fflush(fp);
printf("<A>bort <C>ontinue <P>rint <S>ave -> ");
MECR2: b=inkey(); b=(b&127); b=tolower(b);
if (b=='a') { printf("Abort\n"); goto MEABT; }
if (b=='c') { printf("Continue\n");
if (mode==0) goto ME1;
if (mode==1) goto ME2; }
if (b=='s') { printf("Save buffer\n"); goto MEFIN; }
if (b=='p') { printf("Print formatted\n");
msgform(usersupp.screenwidth,0L,filename);
goto MECR; }
goto MECR2;
MEFIN: putc(0,fp);
fclose(fp);
return(0);
MEABT: printf("Are you sure? ");
if (yesno()==0) goto ME1;
fseek(fp,0L,0);
putc(0,fp);
putc(0,fp);
fclose(fp);
return(2);
}
msgform(width,spos,msgfile)
int width;
long spos;
char *msgfile;
{
struct tm *tm;
int a,b,c,e,real,old,mtype,aflag;
char aaa[100],bbb[100],ttm[3],ap;
FILE *fp;
long now;
fp=fopen(msgfile,"rb");
if (fp==NULL) return(1);
strcpy(aaa,""); old=255;
c=1; /* current column pos */
fseek(fp,spos,0);
e=getc(fp);
if (e!=255) {
printf("*** CANNOT LOCATE MESSAGE / pos=%ld\n",spos);
goto END;
}
mtype=getc(fp); aflag=getc(fp);
printf("\n ");
if (mtype==MES_ANON) printf("****\n");
if (mtype==MES_AN2) printf("<anonymous> ");
goto BONFGM;
A: if (aflag==1) goto AFLAG;
old=real; a=getc(fp); real=a;
if (a==0) goto END;
if (a<0) goto END;
if ( ((a==13)||(a==10)) && (old!=13) && (old!=10) ) a=32;
if ( ((old==13)||(old==10)) && ((real==32)||(real==13)||(real==10))) {
printf("\n"); c=1; }
if (a!=32) {
if ( ((strlen(aaa)+c)>(width-4)) && (strlen(aaa)>(width-4)) )
{ printf("\n%s",aaa); c=strlen(aaa); aaa[0]=0; }
b=strlen(aaa); aaa[b]=a; aaa[b+1]=0; }
if (a==32) { if ((strlen(aaa)+c)>(width-5)) {
printf("\n");
c=1;
}
printf("%s ",aaa); ++c; c=c+strlen(aaa);
strcpy(aaa,""); goto A; }
if ((a==13)||(a==10)) {
printf("%s\n",aaa); c=1;
strcpy(aaa,""); goto A; }
goto A;
AFLAG: a=getc(fp); if (a==0) goto END;
if ((a<32)&&(a!=13)&&(a!=10)) a='.';
putc(a,stdout); if (a==13) putc(10,stdout);
goto AFLAG;
END: fclose(fp);
printf("\n");
return(0);
BONFGM: b=getc(fp); if (b<0) goto END;
if (b=='M') {
printf("\n");
goto A;
}
fpgetfield(fp,bbb);
if ( (usersupp.axlevel<6)
&& (usersupp.eternal!=quickroom.QRroomaide) )
if ((mtype==MES_ANON)||(mtype==MES_AN2)) goto BONFGM;
if (b=='A') printf("from %s ",bbb);
#ifdef SEEMID
if ((b=='I')&&(usersupp.axlevel>=6)) printf("#%s ",bbb);
#endif /* define SEEMID if you wish to see message ID's in header */
if ((b=='N')&&(strucmp(bbb,NODENAME))&&(curr_rm==1))
printf("@ %s ",bbb);
if ((b=='O')&&(strucmp(bbb,quickroom.QRname))) printf("in %s> ",bbb);
if ((b=='N')&&(quickroom.QRflags&QR_NETWORK))
printf("@ %s ",bbb);
if (b=='R') printf("to %s ",bbb);
if (b=='T') {
now=atol(bbb);
tm=(struct tm *)localtime(&now);
sprintf(ttm,"%2d",tm->tm_min);
if (ttm[0]==32) ttm[0]=48;
ap='a'; if ((tm->tm_hour)>12) {
tm->tm_hour=((tm->tm_hour)-12);
ap='p';
}
printf("%d-%s-%4d %d:%2s%cm ",
tm->tm_mday,months[tm->tm_mon],
(1900+tm->tm_year),
tm->tm_hour,ttm,ap);
}
goto BONFGM;
}
pull_message(spos,flnm) /* Pull a message out of the master file */
long spos; /* position in master file */
char *flnm; /* file to write to */
{
int a,b,c;
int file,file2;
long cc;
char field[512];
char fwork[512];
file2=creat(flnm,0666);
file=open("msgmain",O_RDONLY);
lseek(file,spos,0);
for (a=0; a<3; ++a) {
read(file,&b,1);
write(file2,&b,1);
}
PI: b=0; read(file,&b,1);
if (b=='M') {
write(file2,&b,1);
goto B;
}
getfield(file,field);
if (b!='I') {
write(file2,&b,1);
write(file2,field,strlen(field)+1);
}
goto PI;
B: cc=lseek(file,0L,1);
C: if (cc>=MM_FILELEN) cc=lseek(file,0L,0);
c=0; read(file,&c,1); ++cc;
write(file2,&c,1);
if (c!=0) goto C;
close(file); close(file2);
return(0);
}
SHAR_EOF
fi
echo shar: "extracting 'msgform.c'" '(3587 characters)'
if test -f 'msgform.c'
then
echo shar: "will not over-write existing file 'msgform.c'"
else
cat << \SHAR_EOF > 'msgform.c'
#include <fcntl.h>
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <pwd.h>
#include <setjmp.h>
#include <termio.h>
#include "citadel.h"
#define IFEXPERT if (usersupp.flags&US_EXPERT)
#define IFNEXPERT if ((usersupp.flags&US_EXPERT)==0)
#define IFUPASS if (upass!=0)
#define IFNUPASS if (upass==0)
#define IFAIDE if (usersupp.flags&US_AIDE)
#define IFNAIDE if ((usersupp.flags&US_AIDE)==0)
long atol();
long lseek();
char *months[]={"Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec"};
main(argc,argv)
int argc;
char *argv[]; {
if (argc==1) msgform(0L,"",0);
if (argc==2) msgform(0L,argv[1],0);
if (argc==3) msgform(atol(argv[2]),argv[1],0);
if (argc==4) msgform(atol(argv[2]),argv[1],1);
exit(0);
}
msgform(spos,msgfile,mflag)
long spos;
char msgfile[];
int mflag;
{
struct tm *tm;
int a,b,c,d,e,real,old,mtype,aflag,width;
char aaa[100],bbb[100],ttm[3],ap;
char A[30],R[30],T[30],N[30],O[30];
char flnm[20];
FILE *fp;
long now;
width=80;
strcpy(flnm,msgfile);
if (!strcmp(flnm,"-m")) {
strcpy(flnm,"/usr/bbs/msgmain");
mflag=1;
}
if (flnm[0]==0) fp=stdin;
else fp=fopen(flnm,"rb");
if (fp==NULL) return(1);
fseek(fp,spos,0);
LOOP: strcpy(aaa,""); old=255;
c=1; /* current column pos */
do {
e=getc(fp);
if (e<0) {
fclose(fp);
return(0);
}
} while(e!=255);
if (e!=255) {
printf("===> CANNOT LOCATE MESSAGE / pos=%ld\n",spos);
goto END; }
mtype=getc(fp); aflag=getc(fp);
goto BONCLR;
AA: if ((mflag==1)&&(strcmp(O,"Mail"))) {
do { a=getc(fp);
} while(a!=0);
goto LOOP;
}
printf("\n ");
if (mtype==MES_ANON) printf("****\n");
if (mtype==MES_AN2) printf("<anonymous> ");
if (T[0]!=0) printf("%s ",T);
if (A[0]!=0) printf("from %s ",A);
if (R[0]!=0) printf("to %s ",R);
if (O[0]!=0) printf("in %s> ",O);
if (N[0]!=0) printf("@ %s ",N);
printf("\n");
AAA: if (aflag==1) goto AFLAG;
old=real; a=getc(fp); real=a;
if (a==0) goto END;
if (a<0) goto END;
if ( ((a==13)||(a==10)) && (old!=13) && (old!=10) ) a=32;
if ( ((old==13)||(old==10)) && ((real==32)||(real==13)||(real==10))) {
printf("\n"); c=1; }
if (a!=32) {
if ( ((strlen(aaa)+c)>(width-4)) && (strlen(aaa)>(width-4)) )
{ printf("\n%s",aaa); c=strlen(aaa); aaa[0]=0; }
b=strlen(aaa); aaa[b]=a; aaa[b+1]=0; }
if (a==32) { if ((strlen(aaa)+c)>(width-5)) {
printf("\n");
c=1;
}
printf("%s ",aaa); ++c; c=c+strlen(aaa);
strcpy(aaa,""); goto AAA; }
if ((a==13)||(a==10)) {
printf("%s\n",aaa); c=1;
strcpy(aaa,""); goto AAA; }
goto AAA;
AFLAG: a=getc(fp); if (a==0) goto END;
putc(a,stdout); if (a==13) putc(10,stdout);
goto AFLAG;
END:
printf("\n");
goto LOOP;
BONCLR: strcpy(A,""); strcpy(R,""); strcpy(T,""); strcpy(O,""); strcpy(N,"");
BONFGM: b=getc(fp); if (b<0) goto END;
if (b=='M') goto AA;
fpgetfield(fp,bbb);
if (b=='A') strcpy(A,bbb);
if (b=='N') strcpy(N,bbb);
if (b=='O') strcpy(O,bbb);
if (b=='R') strcpy(R,bbb);
if (b=='T') { now=atol(bbb);
tm=(struct tm *)localtime(&now);
sprintf(ttm,"%2d",tm->tm_min);
if (ttm[0]==32) ttm[0]=48;
ap='a'; if ((tm->tm_hour)>12) {
tm->tm_hour=((tm->tm_hour)-12);
ap='p';
}
sprintf(T,"%d-%s-%4d %d:%2s%cm ",
tm->tm_mday,months[tm->tm_mon],
(1900+tm->tm_year),
tm->tm_hour,ttm,ap);
}
goto BONFGM;
}
fpgetfield(fp,string)
FILE *fp;
char string[];
{
int a,b;
strcpy(string,"");
a=0;
do {
b=getc(fp);
if (b<1) { string[a]=0; return(0); }
string[a]=b;
++a;
} while(b!=0);
}
SHAR_EOF
fi
echo shar: "extracting 'msgstats.c'" '(437 characters)'
if test -f 'msgstats.c'
then
echo shar: "will not over-write existing file 'msgstats.c'"
else
cat << \SHAR_EOF > 'msgstats.c'
#include <fcntl.h>
#include "citadel.h"
main() {
int file,a,b,c;
struct msgmain msgmain;
file=open("./MMstructure",O_RDONLY);
read(file,&msgmain,sizeof(struct msgmain));
close(file);
printf("Messages numbered %ld to %ld\n",msgmain.MMlowest,msgmain.MMhighest);
printf("Current file position: %ld\n",msgmain.MMcurpos);
if (msgmain.MMflags & MM_BUSY)
printf("File is locked.\n");
else
printf("File is unlocked.\n");
exit(0);
}
SHAR_EOF
fi
echo shar: "done with directory 'source'"
cd ..
exit 0
# End of shell archive
--
Some do, some don't. | eric at sactoh0.SAC.CA.US
Some will, some won't. | ames!pacbell!sactoh0!eric
I might! | ucbvax!csusac!sactoh0!eric
| ( A Home For Unwanted 3B's )
More information about the Alt.sources
mailing list