home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Devil's Doorknob BBS Capture (1996-2003)
/
devilsdoorknobbbscapture1996-2003.iso
/
WWIV2.ZIP
/
FIX.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-03
|
32KB
|
1,383 lines
/*****************************************************************************
WWIV Version 4
Copyright (C) 1988-1993 by Wayne Bell
Distribution of the source code for WWIV, in any form, modified or unmodified,
without PRIOR, WRITTEN APPROVAL by the author, is expressly prohibited.
Distribution of compiled versions of WWIV is limited to copies compiled BY
THE AUTHOR. Distribution of any copies of WWIV not compiled by the author
is expressly prohibited.
*****************************************************************************/
/*
* Possible future enhancements:
*
* duplicate users?
* modem stuff ok
* check for various .dat files existence
* decrement mail waiting
*/
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <sys\stat.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <alloc.h>
#define EXTENDED
#include "vardec.h"
#define OK " "
#define NOK "## "
#define QOK "?? "
int userfile=-1,configfile=-1,statusfile=-1;
statusrec status;
configrec syscfg;
char *thisuser;
char *thisuser_inact;
char cdir[81];
int num_dirs=0,num_subs=0;
directoryrec *directories;
subboardrec *subboards;
unsigned long max_qscan;
int sub_screwed[64];
int curlsub=-1,bchanged,nummsgs;
postrec *msgs;
messagerec *postm[64],*emailm;
char *emailmmm;
int numpostm[64],numemailm,num_type_0;
short gat[2048];
int gat_section;
int url;
smalrec *smallist,*new_smallist;
int cur_users;
int allow_changes=1,force_changes=0;
/****************************************************************************/
void read_user(unsigned int un)
{
long pos;
char s[80];
if (userfile==-1) {
sprintf(s,"%sUSER.LST",syscfg.datadir);
userfile=open(s,O_RDWR | O_BINARY);
if (userfile<0) {
*thisuser_inact=inact_deleted;
return;
}
}
pos=((long) url) * ((long) un);
if (filelength(userfile)<(pos+syscfg.userreclen)) {
*thisuser_inact=inact_deleted;
return;
}
lseek(userfile,pos,SEEK_SET);
read(userfile, thisuser, syscfg.userreclen);
}
/****************************************************************************/
void write_user(unsigned int un)
{
long pos;
char s[80];
if (userfile==-1) {
sprintf(s,"%sUSER.LST",syscfg.datadir);
userfile=open(s,O_RDWR | O_BINARY);
if (userfile<0) {
return;
}
}
pos=((long) url) * ((long) un);
if (filelength(userfile)<(pos+syscfg.userreclen)) {
return;
}
lseek(userfile,pos,SEEK_SET);
write(userfile, thisuser, syscfg.userreclen);
}
/****************************************************************************/
void close_user(void)
{
if (userfile!=-1) {
close(userfile);
userfile=-1;
}
}
/****************************************************************************/
void save_status(void)
{
char s[80];
sprintf(s,"%sSTATUS.DAT",syscfg.datadir);
statusfile=open(s,O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
write(statusfile, (void *)(&status), sizeof(statusrec));
close(statusfile);
statusfile=-1;
}
/****************************************************************************/
int exist(char *s)
{
int f;
f=open(s,O_RDONLY | O_BINARY);
close(f);
if (f>0)
return(1);
else
return(0);
}
/****************************************************************************/
void give_up(void)
{
printf("\n%sGiving up.\n",NOK);
exit(-1);
}
/****************************************************************************/
void oom(void *x)
{
if (!x) {
printf("%sOut of memory.\n",NOK);
give_up();
}
}
/****************************************************************************/
int yn(void)
{
char ch;
while (1) {
ch=getch();
if ((ch=='Y') || (ch=='y')) {
printf("Yes\n");
return(1);
}
if ((ch=='N') || (ch=='n') || (ch==13)) {
printf("No\n");
return(0);
}
}
}
/****************************************************************************/
void maybe_give_up(void)
{
printf("%sFuture expansion might try to fix this problem.\n",OK);
give_up();
}
/****************************************************************************/
int cdto(char *s)
{
char s1[81];
int i,db,st;
strcpy(s1,s);
i=strlen(s1)-1;
db=(s1[i]=='\\');
if (i==0)
db=0;
if ((i==2) && (s1[1]==':'))
db=0;
if (db)
s1[i]=0;
st=chdir(s1);
if (s[1]==':') {
i=setdisk(s[0]-'A');
if (i<=(s[0]-'A'))
st=1;
}
return(st);
}
/****************************************************************************/
void get_dir(char *s, int be)
{
strcpy(s,"X:\\");
s[0]='A'+getdisk();
getcurdir(0,&(s[3]));
if (be) {
if (s[strlen(s)-1]!='\\')
strcat(s,"\\");
}
}
/****************************************************************************/
int check_dir(char *dir, char *descr)
{
int st;
st=cdto(dir);
if (st)
printf("%sUnable to find dir '%s' for %s dir.\n",NOK,dir,descr);
cdto(cdir);
return(st);
}
/****************************************************************************/
void check_all_dirs(void)
{
int st=0,st1;
int i;
st |= check_dir(syscfg.msgsdir,"Messages");
st |= check_dir(syscfg.gfilesdir,"G-files");
st |= check_dir(syscfg.datadir,"Data");
st |= check_dir(syscfg.dloadsdir,"Default Dloads");
st |= check_dir(syscfg.tempdir,"Temp");
if (st) {
printf("%sOne of the critical system directories is not present or not set correctly.\n",NOK);
give_up();
}
for (i=0; i<num_dirs; i++) {
st1 = check_dir(directories[i].path,directories[i].name);
if (st1) {
st=1;
printf("%sEither create the dir, or use //DIREDIT to set it correctly.\n",NOK);
printf("%sThis program cannot fix this problem.\n",NOK);
}
}
}
/****************************************************************************/
int trashed_str(char *s, int ml, int lower)
{
int i,i1,st=0;
i1=strlen(s);
if (i1>ml)
st=1;
else
for (i=0; i<i1; i++) {
if (s[i]<32)
st=1;
if ((!lower) && (islower(s[i])))
st=1;
}
return(st);
}
/****************************************************************************/
int trashed_user()
{
if (trashed_str(thisuser,30,0))
return(1);
return(0);
}
void fix_user()
{
thisuser[30]=0;
}
/****************************************************************************/
void check_userlist(void)
{
long l;
int nu,check_trash=0,trashed_userlist=0,xxx;
url=syscfg.userreclen;
if (!url) {
url=700;
syscfg.userreclen=700;
}
read_user(1);
if (userfile<0) {
printf("%sNo userlist present.\n",NOK);
give_up();
}
l=filelength(userfile);
nu=(int) (l/((long)url)) - 1;
printf("%sFound %d user records... ",OK,nu);
if (nu>syscfg.maxusers) {
printf("Might be too many.\n");
check_trash=1;
} else
printf("Reasonable number.\n");
if (check_trash) {
read_user(nu);
if ((xxx=trashed_user())!=0) {
trashed_userlist=1;
printf("%sUserrec #%u appeares trashed (%d).\n",NOK,nu,xxx);
}
if (trashed_userlist) {
printf("%sUserlist appears screwed up.\n",NOK);
} else
printf("%sUserlist seems OK.\n",OK);
}
if (trashed_userlist) {
if (!allow_changes)
give_up();
printf("%sScanning for invalid user records...\n",OK);
while ((nu) && (trashed_user()))
read_user(--nu);
printf("%sAppears to be %u 'real' user records.\n",OK,nu);
if (!force_changes) {
printf("%sTruncate userlist to %u users? ",QOK,nu);
if (!yn())
trashed_userlist=0;
}
if (trashed_userlist) {
l=((long) nu) * ((long) syscfg.userreclen);
chsize(userfile,l);
}
}
}
/****************************************************************************/
void isr1(int un, char *name)
{
int cp,i;
char s[81];
smalrec sr;
cp=0;
while ((cp<cur_users) && (strcmp(name,(new_smallist[cp].name))>0))
++cp;
memmove(&(new_smallist[cp+1]),&(new_smallist[cp]),sizeof(smalrec)*(cur_users-cp));
strcpy(sr.name,name);
sr.number=un;
new_smallist[cp]=sr;
++cur_users;
}
/****************************************************************************/
void check_nameslist(void)
{
char s[81];
int st=0,i,i1,xxx;
unsigned int status_users,names_users;
printf("%sScanning NAMES.LST file...\n",OK);
sprintf(s,"%sNAMES.LST",syscfg.datadir);
i=open(s,O_RDONLY | O_BINARY);
if (i>0) {
if (filelength(i)) {
smallist=farmalloc(filelength(i));
oom(smallist);
read(i,smallist,(unsigned) filelength(i));
names_users=(unsigned int) (filelength(i)/sizeof(smalrec));
status_users=status.users;
} else
names_users=0;
close(i);
if (names_users!=status_users) {
status.users=names_users;
printf("%sstatus.users was wrong. ",NOK);
if (allow_changes) {
printf("Fixed it.\n");
save_status();
} else {
printf("Leaving it alone.\n");
}
}
} else {
names_users=0;
status.users=status.users;
printf("%s%s NOT FOUND.\n",NOK,s);
}
cur_users=0;
i1=filelength(userfile)/syscfg.userreclen-1;
new_smallist=farmalloc(((long)i1) * ((long)sizeof(smalrec)));
oom(new_smallist);
for (i=1; i<=i1; i++) {
read_user(i);
if ((*thisuser_inact & inact_deleted)==0) {
if ((xxx=trashed_user())!=0) {
printf("\n%s User #%d had trashed info (%d); patching.\n",NOK,i,xxx);
fix_user();
write_user(i);
}
isr1(i,thisuser);
}
if ((i % 10)==0)
printf("%s%d/%d\r",OK,i,i1);
}
printf("%s%d/%d\n",OK,i1,i1);
if (cur_users!=names_users) {
st=1;
printf("%sA different number of users was found (%d vs %d).\n",NOK,
cur_users,names_users);
} else {
for (i=0; i<names_users; i++) {
if (strcmp(smallist[i].name,new_smallist[i].name))
st=1;
if (smallist[i].number!=new_smallist[i].number)
st=1;
}
}
if (st) {
printf("%sThe new NAMES.LST file is different than the old one.\n",NOK);
if (allow_changes) {
status.users=cur_users;
i=open(s,O_RDWR | O_BINARY | O_TRUNC | O_CREAT, S_IREAD | S_IWRITE);
if (i<0) {
printf("%sCouldn't create %s.\n",NOK,s);
give_up();
}
write(i,(void *) (new_smallist), (sizeof(smalrec) * status.users));
close(i);
save_status();
printf("%sNAMES.LST file fixed.\n",OK);
} else {
printf("%sLeaving it alone, but it should be fixed. There is nothing bad that can\n",NOK);
printf("%shappen by fixing the NAMES.LST file.\n",NOK);
}
}
}
/****************************************************************************/
void iscan(int b)
{
int f;
char s[81];
curlsub=b;
bchanged=0;
nummsgs=0;
if (curlsub<0)
return;
sprintf(s,"%s%s.SUB",syscfg.datadir,subboards[curlsub].filename);
f=open(s,O_BINARY | O_RDWR);
if (f==-1) {
f=open(s,O_BINARY | O_RDWR | O_CREAT,S_IREAD | S_IWRITE);
msgs[0].owneruser=0;
write(f,(void *) (&msgs[0]),sizeof(postrec));
}
lseek(f,0L,SEEK_SET);
nummsgs=(read(f,(void *) (&msgs[0]),255*sizeof(postrec)) / sizeof(postrec))-1;
nummsgs=msgs[0].owneruser;
close(f);
}
/****************************************************************************/
void savebase(void)
{
int f;
char s[81];
if (bchanged==0)
return;
sprintf(s,"%s%s.SUB",syscfg.datadir,subboards[curlsub].filename);
f=open(s,O_BINARY | O_RDWR);
lseek(f,0L,SEEK_SET);
msgs[0].owneruser=nummsgs;
write(f,(void *) (&msgs[0]), ((nummsgs+1) * sizeof(postrec)));
close(f);
bchanged=0;
}
/****************************************************************************/
#define GATSECLEN (4096L+2048L*512L)
#define MSG_STARTING (((long)gat_section)*GATSECLEN + 4096)
void set_gat_section(int f, int section)
{
long l,l1;
int i;
if (gat_section!=section) {
l=filelength(f);
l1=((long)section)*GATSECLEN;
if (l<l1) {
chsize(f,l1);
l=l1;
}
lseek(f,l1,SEEK_SET);
if (l<(l1+4096)) {
for (i=0; i<2048; i++)
gat[i]=0;
write(f,(void *)gat, 4096);
} else {
read(f,(void *)gat, 4096);
}
gat_section=section;
}
}
/****************************************************************************/
void save_gat(int f)
{
long l;
l=((long)gat_section)*GATSECLEN;
lseek(f,l,SEEK_SET);
write(f,(void *)gat,4096);
}
/****************************************************************************/
void remove_link(messagerec *m1, char *aux)
{
messagerec m;
char s[81],s1[81];
int f;
long csec,nsec;
m=*m1;
strcpy(s,syscfg.msgsdir);
switch(m.storage_type) {
case 0:
case 1:
ltoa(m.stored_as,s1,16);
if (m.storage_type==1) {
strcat(s,aux);
strcat(s,"\\");
}
strcat(s,s1);
unlink(s);
break;
case 2:
f=open_file(aux);
set_gat_section(f,m.stored_as/2048);
csec=m.stored_as % 2048;
while ((csec>0) && (csec<2048)) {
nsec=(long) gat[csec];
gat[csec]=0;
csec=nsec;
}
save_gat(f);
close(f);
break;
default:
/* illegal storage type */
break;
}
}
/****************************************************************************/
void deletem(int mn)
{
int i;
if ((mn>0) && (mn<=nummsgs)) {
remove_link(&(msgs[mn].msg),(subboards[curlsub].filename));
for (i=mn; i<nummsgs; i++)
msgs[i]=msgs[i+1];
nummsgs--;
bchanged=1;
}
}
/****************************************************************************/
void delmail(int f, int loc)
{
mailrec m,m1;
userrec u;
int rm,i,t,otf;
char s[81];
sprintf(s,"%sEMAIL.DAT",syscfg.datadir);
f=open(s,O_RDWR | O_BINARY);
lseek(f,((long) loc) * ((long) sizeof(mailrec)), SEEK_SET);
read(f,(void *)&m,sizeof(mailrec));
rm=1;
if (m.status & status_multimail) {
t=filelength(f)/sizeof(mailrec);
otf=0;
for (i=0; i<t; i++)
if (i!=loc) {
lseek(f,((long)i)*((long)sizeof(mailrec)),SEEK_SET);
read(f,(void *)&m1,sizeof(mailrec));
if ((m.msg.stored_as==m1.msg.stored_as) && (m.msg.storage_type==m1.msg.storage_type) && (m1.daten!=0xffffffff))
otf=1;
}
if (otf)
rm=0;
}
close(f);
if (rm)
remove_link(&m.msg,"EMAIL");
if (m.tosys==0) {
#ifdef DEC_MAIL_WAITING
read_user(m.touser,&u);
if (u.waiting) {
--u.waiting;
write_user(m.touser,&u);
close_user();
}
#endif
}
f=open(s,O_RDWR | O_BINARY);
lseek(f,((long) loc) * ((long) sizeof(mailrec)), SEEK_SET);
m.touser=0;
m.tosys=0;
m.daten=0xffffffff;
m.msg.storage_type=0;
m.msg.stored_as=0xffffffff;
write(f,(void *)&m,sizeof(mailrec));
close(f);
}
/****************************************************************************/
void find_max_qscan(void)
{
int i,cs,r,t,f,any_screwed;
unsigned long maxthissub;
mailrec m;
char s[81];
for (i=0; i<64; i++)
sub_screwed[i]=0;
max_qscan=0L;
any_screwed=0;
num_type_0=0;
printf("%sScanning subboards...\n",OK);
for (cs=0; cs<num_subs; cs++) {
iscan(cs);
maxthissub=0L;
numpostm[cs]=nummsgs;
if (nummsgs) {
postm[cs]=farmalloc(nummsgs*sizeof(messagerec));
oom(postm[cs]);
for (i=1; i<=nummsgs; i++) {
postm[cs][i-1]=msgs[i].msg;
if (maxthissub>=msgs[i].qscan) {
sub_screwed[cs]=1;
any_screwed=1;
}
if (maxthissub<msgs[i].qscan)
maxthissub=msgs[i].qscan;
if (max_qscan<msgs[i].qscan)
max_qscan=msgs[i].qscan;
if (msgs[i].msg.storage_type<2) {
if (max_qscan<msgs[i].msg.stored_as)
max_qscan=msgs[i].msg.stored_as;
if (msgs[i].msg.storage_type==0)
++num_type_0;
}
}
if (sub_screwed[cs]) {
printf("%sSub '%s' has q-scan pointers screwed up.\n",NOK,subboards[cs].name);
}
}
}
printf("%sScanning EMAIL.DAT file...\n",OK);
sprintf(s,"%sEMAIL.DAT",syscfg.datadir);
f=open(s,O_BINARY | O_RDWR);
if (f!=-1) {
t=(int) (filelength(f)/sizeof(mailrec));
r=0;
numemailm=t;
emailm=farmalloc(t*sizeof(messagerec));
emailmmm=farmalloc(t);
if (t) {
oom(emailm);
oom(emailmmm);
}
while (r<t) {
lseek(f,(long)(sizeof(mailrec)) * (long)(r),SEEK_SET);
read(f,(void *)&m,sizeof(mailrec));
emailm[r]=m.msg;
emailmmm[r]=m.status;
if ((m.tosys!=0) || (m.touser!=0)) {
if (m.msg.storage_type<2)
if (max_qscan<m.msg.stored_as)
max_qscan=m.msg.stored_as;
if (m.msg.storage_type==0)
++num_type_0;
}
++r;
}
close(f);
}
max_qscan++;
if (max_qscan>status.qscanptr) {
printf("%sMax qscan pointer trashed (%ld vs %ld).\n",NOK,max_qscan,status.qscanptr);
status.qscanptr=max_qscan;
if (allow_changes) {
save_status();
printf("%sFixed.\n",OK);
} else
printf("%sLeaving as-is, but it should be fixed.\n",OK);
}
if ((allow_changes) && (any_screwed)) {
if (!force_changes) {
printf("%sFix up q-scan pointers? ",QOK);
if (!yn())
any_screwed=0;
}
if (any_screwed) {
for (cs=0; cs<num_subs; cs++) {
if (sub_screwed[cs]) {
printf("%sResetting q-scan ptrs for '%s'\n",OK,subboards[cs].name);
iscan(cs);
for (i=1; i<=nummsgs; i++) {
msgs[i].qscan=status.qscanptr++;
}
bchanged=1;
savebase();
}
}
save_status();
}
}
}
/****************************************************************************/
typedef struct {
long stored_as;
int subnum,msgnum;
} type_0;
/****************************************************************************/
char *describem(char *s, int subnum, int msgnum)
{
mailrec me;
postrec mp;
char s1[81];
int f;
if (subnum==-1) { /* email */
sprintf(s1,"%sEMAIL.DAT",syscfg.datadir);
f=open(s1,O_BINARY | O_RDWR);
lseek(f,(long)(sizeof(mailrec)) * (long)(msgnum),SEEK_SET);
read(f,(void *)&me,sizeof(mailrec));
close(f);
if (me.fromsys)
sprintf(s1,"user #%d @%d",me.fromuser,me.fromsys);
else
sprintf(s1,"user #%d",me.fromuser);
sprintf(s,"Mail from %s to ",s1);
if (me.tosys)
sprintf(s1,"user #%d @%d",me.touser,me.tosys);
else
sprintf(s1,"user #%d",me.touser);
strcat(s,s1);
sprintf(s1," '%.30s'",me.title);
strcat(s,s1);
} else {
iscan(subnum);
mp=msgs[msgnum];
if (mp.ownersys)
sprintf(s,"Post #%d on '%s' by user #%d @%d",
msgnum+1,
subboards[subnum].name,
mp.owneruser,
mp.ownersys);
else
sprintf(s,"Post #%d on '%s' by user #%d",
msgnum+1,
subboards[subnum].name,
mp.owneruser);
}
return(s);
}
/****************************************************************************/
void check_type_1(int num, messagerec *list, char *extra, int todesc)
{
char s[81],s1[81];
int i,i1,dup,ex;
char *already_done;
if (!num)
return;
sprintf(s,"%s%s\\",syscfg.msgsdir,extra);
already_done=farmalloc(num);
oom(already_done);
for (i=0; i<num; i++)
already_done[i]=0;
for (i=0; i<num; i++)
if ((list[i].storage_type==1) && (!already_done[i])) {
sprintf(s1,"%s%lX",s,list[i].stored_as);
ex=exist(s1);
dup=0;
if (!((todesc==-1) && (emailmmm[i] & status_multimail))) {
for (i1=i+1; i1<num; i1++)
if (list[i1].storage_type==1)
if (list[i1].stored_as==list[i].stored_as)
dup=1;
}
if (dup || (!ex)) {
if (!ex)
printf("%sFile not found: '%s'\n",NOK,s1);
if (dup)
printf("%sMessage file multiply referenced: '%s'\n",NOK,s1);
printf("%s for %s\n",NOK,describem(s1,todesc,i));
for (i1=i+1; i1<num; i1++)
if ((list[i1].storage_type==1) &&
(list[i1].stored_as==list[i].stored_as)) {
printf("%s for %s\n",NOK,describem(s1,todesc,i1));
already_done[i1]=1;
}
printf("%s No action taken.\n\n",NOK);
}
}
farfree(already_done);
}
/****************************************************************************/
int open_file(char *fn)
{
int f,i;
char s[81];
sprintf(s,"%s%s.DAT",syscfg.msgsdir,fn);
f=open(s,O_RDWR | O_BINARY);
if (f<0)
return(-1);
lseek(f,0L,SEEK_SET);
read(f,(void *)gat,4096);
gat_section=0;
return(f);
}
/****************************************************************************/
void check_type_2(int num, messagerec *list, char *extra, int todesc)
{
int f,i,i1,any,csec,csec1,any_dead,num_deadm,anything_done,numsec,high,sec;
char s[81];
int *deadm;
short *gati, *gatint;
if (!num)
return;
f=open_file(extra);
numsec=((int) (filelength(f)/GATSECLEN))+1;
high=numsec*2048;
gati=farmalloc(high*2);
gatint=farmalloc(high*2);
for (i=0; i<high; i++)
gati[i]=0;
for (i=0; i<numsec; i++) {
set_gat_section(f,i);
memcpy(gatint+2048*i, gat, 4096);
}
deadm=farmalloc(num*2);
oom(deadm);
any=0;
any_dead=0;
num_deadm=0;
anything_done=0;
for (i=0; i<num; i++)
if (list[i].storage_type==2) {
if (f<0) {
if (!any) {
any=1;
printf("%sType 2 data file not found: '%s%s.DAT'\n",
NOK,syscfg.msgsdir,extra);
}
deadm[num_deadm++]=i;
anything_done=1;
} else {
sec=(list[i].stored_as/2048)*2048;
csec=list[i].stored_as % 2048;
while ((csec>0) && (csec<2048)) {
if (gati[csec+sec]) {
if (!((todesc==-1) && (emailmmm[i] & status_multimail))) {
if (gati[csec+sec]!=-2)
gati[csec+sec]=-1;
++any_dead;
}
csec=-1;
} else {
if (!gatint[csec+sec]) {
gati[csec+sec]=-2;
++any_dead;
csec=-1;
} else {
gati[csec+sec]=i+1;
csec=gatint[csec+sec];
}
}
}
}
}
if (f<0) {
if (anything_done) {
printf("%sDunno what to do about that.\n",NOK);
}
farfree(gati);
farfree(deadm);
farfree(gatint);
close(f);
return;
}
if (any_dead) {
anything_done=1;
printf("%sErrors in '%s%s.DAT':\n",NOK,syscfg.msgsdir,extra);
for (i=0; i<num; i++)
if (list[i].storage_type==2) {
sec=(list[i].stored_as/2048)*2048;
csec=list[i].stored_as % 2048;
csec1=-1;
while ((csec>0) && (csec<2048)) {
if (gati[csec+sec]<0) {
printf("%s for %s\n",NOK,describem(s,todesc,i));
if (gati[csec+sec]==-1) {
printf("%s Collided on cluster #%d\n",NOK,csec+sec);
if (csec1==-1) {
printf("%s First cluster of message, removing.\n",NOK);
deadm[num_deadm++]=i;
} else {
gatint[csec1+sec]=-1;
printf("%s Truncating message.\n",NOK);
}
} else if (gati[csec+sec]==-2) {
printf("%s Pointed to unallocated cluster #%d\n",NOK,csec+sec);
if (csec1==-1) {
printf("%s First cluster of message, removing.\n",NOK);
deadm[num_deadm++]=i;
} else {
gatint[csec1+sec]=-1;
printf("%s Truncating message.\n",NOK);
}
} else {
printf("%s Unknown error.\n",NOK);
}
}
csec1=csec;
csec=gatint[csec+sec];
}
}
}
any_dead=0;
for (csec=0; csec<high; csec++)
if ((gatint[csec]) && (gati[csec]<=0)) {
gatint[csec]=0;
++any_dead;
}
if (any_dead) {
printf("%sLost clusters recovered from '%s%s.DAT': %d\n",
NOK,syscfg.msgsdir,extra,any_dead);
anything_done=1;
}
if (anything_done) {
i=force_changes;
if ((allow_changes) && (!i)) {
printf("%sWrite these changes to disk? ",QOK);
i=yn();
}
if (i) {
printf("%sUpdating '%s%s.DAT'.\n",OK,syscfg.msgsdir,extra);
for (i=0; i<numsec; i++) {
set_gat_section(f,i);
memcpy(gat, gatint+2048*i, 4096);
save_gat(f);
}
if (num_deadm) {
printf("%sRemoving messages with no text.\n",OK);
if (todesc!=-1) {
iscan(todesc);
for (i=0; i<num_deadm; i++)
deletem(deadm[i]-i+1);
savebase();
} else {
for (i=0; i<num_deadm; i++)
delmail(f,deadm[i]);
}
}
}
}
close(f);
farfree(deadm);
farfree(gati);
farfree(gatint);
}
/****************************************************************************/
void check_msg_consistency(void)
{
type_0 *x0;
int cs,i,i1,i2,cp,ex;
char s[81],s1[81];
/* check type 0 consistency */
if (num_type_0) {
printf("%sChecking type 0 message consistency.\n",OK);
x0=farmalloc(sizeof(type_0)*num_type_0);
oom(x0);
cp=0;
for (cs=0; cs<num_subs; cs++)
for (i=0; i<numpostm[cs]; i++)
if ((!postm[cs][i].storage_type) && (postm[cs][i].stored_as != -1)) {
x0[cp].stored_as=postm[cs][i].stored_as;
x0[cp].subnum=cs;
x0[cp].msgnum=i+1;
++cp;
}
for (cs=0; cs<numemailm; cs++)
if ((!emailm[cs].storage_type) && (emailm[cs].stored_as != -1)) {
x0[cp].stored_as=emailm[cs].stored_as;
x0[cp].subnum=-1;
x0[cp].msgnum=cs;
++cp;
}
for (i=0; i<cp; i++) {
if (x0[i].subnum!=-2) {
sprintf(s,"%s%lX",syscfg.msgsdir,x0[i].stored_as);
ex=exist(s);
i2=0;
for (i1=i+1; i1<cp; i1++)
if (x0[i].stored_as==x0[i1].stored_as)
i2=1;
if (i2 || (!ex)) {
if (!ex)
printf("%sFile not found: '%s'\n",NOK,s);
if (i2)
printf("%sMessage file multiply referenced: '%s'\n",NOK,s);
printf("%s for %s\n",NOK,describem(s1,x0[i].subnum,x0[i].msgnum));
for (i1=i+1; i1<cp; i1++)
if (x0[i].stored_as==x0[i1].stored_as) {
printf("%s for %s\n",NOK,describem(s1,x0[i1].subnum,x0[i1].msgnum));
x0[i1].subnum=-2;
}
printf("%s No action taken.\n\n",NOK);
}
}
}
farfree(x0);
}
/* check type 1 consistency */
printf("%sChecking type 1 message consistency.\n",OK);
check_type_1(numemailm,emailm,"EMAIL",-1);
for (cs=0; cs<num_subs; cs++) {
check_type_1(numpostm[cs],postm[cs],subboards[cs].filename,cs);
}
/* check type 2 consistency */
printf("%sChecking type 2 message consistency.\n",OK);
check_type_2(numemailm,emailm,"EMAIL",-1);
for (cs=0; cs<num_subs; cs++) {
check_type_2(numpostm[cs],postm[cs],subboards[cs].filename,cs);
}
}
/****************************************************************************/
void ck_size(char *fn, int f, long rl)
{
long l;
l=filelength(f);
if (l<rl) {
printf("%s%s too short (%ld<%ld).\n",NOK,fn,l,rl);
give_up();
}
if (l>rl) {
printf("%s%s too long (%ld>%ld).\n",NOK,fn,l,rl);
if (allow_changes)
printf("%sAttempting to continue.\n",NOK);
else
give_up();
}
}
/****************************************************************************/
void init(void)
{
char s[81];
int i;
strcpy(s,"CONFIG.DAT");
configfile=open(s,O_RDWR | O_BINARY);
if (configfile<0) {
printf("%s%s NOT FOUND.\n",NOK,s);
give_up();
}
ck_size(s,configfile,sizeof(configrec));
read(configfile,(void *) (&syscfg), sizeof(configrec));
close(configfile);
strcpy(cdir,"X:\\");
cdir[0]='A'+getdisk();
getcurdir(0,&(cdir[3]));
if (check_dir(syscfg.datadir,"Data")) {
printf("%sMust find data directory to continue.\n",NOK);
give_up();
}
if (!syscfg.userreclen)
syscfg.userreclen=700;
thisuser=(char *)farmalloc(syscfg.userreclen);
if (!thisuser) {
printf("%sCould not allocate %d bytes for userrec.\n",NOK,syscfg.userreclen);
give_up();
}
thisuser_inact=thisuser+syscfg.inactoffset;
sprintf(s,"%sSTATUS.DAT",syscfg.datadir);
statusfile=open(s,O_RDWR | O_BINARY);
if (statusfile<0) {
printf("%s%s NOT FOUND.\n",NOK,s);
if (allow_changes) {
printf("%sRe-creating STATUS.DAT file.\n",OK);
strcpy(status.date1,"00/00/00");
strcpy(status.date2,status.date1);
strcpy(status.date3,status.date1);
strcpy(status.log1,"000000.LOG");
strcpy(status.log2,status.log1);
strcpy(status.gfiledate,"00/00/00");
status.users=0;
status.callernum=65535;
status.callstoday=0;
status.msgposttoday=0;
status.emailtoday=0;
status.fbacktoday=0;
status.uptoday=0;
status.activetoday=0;
status.qscanptr=0L;
status.amsganon=0;
status.amsguser=0;
status.callernum1=0L;
status.net_edit_stuff=0;
status.wwiv_version=0;
status.net_version=0;
status.net_bias=0.001;
} else
give_up();
} else {
ck_size(s,statusfile,sizeof(statusrec));
read(statusfile,(void *)(&status), sizeof(statusrec));
close(statusfile);
}
sprintf(s,"%sDIRS.DAT",syscfg.datadir);
i=open(s,O_RDWR | O_BINARY);
if (i<0) {
printf("%s%s NOT FOUND.\n",NOK,s);
maybe_give_up();
} else {
directories=(directoryrec *)farmalloc(filelength(i));
if (!directories) {
printf("%sCouldn't allocate %ld bytes for %s.\n",NOK,filelength(i), s);
give_up();
}
num_dirs=(read(i,directories, (filelength(i))))/
sizeof(directoryrec);
close(i);
}
sprintf(s,"%sSUBS.DAT",syscfg.datadir);
i=open(s,O_RDWR | O_BINARY);
if (i<0) {
printf("%s%s NOT FOUND.\n",NOK,s);
maybe_give_up();
} else {
subboards=(subboardrec *)farmalloc(filelength(i));
if (!subboards) {
printf("%sCouldn't allocate %ld bytes for %s.\n",NOK,filelength(i),s);
give_up();
}
num_subs=(read(i, subboards, (filelength(i))))/
sizeof(subboardrec);
close(i);
}
msgs=farmalloc(255*sizeof(postrec));
oom(msgs);
}
/****************************************************************************/
void main(int argc, char *argv[])
{
int i;
char *ss;
for (i=1; i<argc; i++) {
ss=argv[i];
if ((*ss=='/') || (*ss=='-')) {
} else {
printf("%sUnknown argument: '%s'\n",NOK,ss);
}
}
printf("\n");
printf("Fix - Fix WWIV files.\n");
printf("\n");
if (getenv("BBS")) {
printf("Fix should only be run OUTSIDE the BBS.\n");
exit(-1);
}
init();
check_all_dirs();
check_userlist();
check_nameslist();
find_max_qscan();
check_msg_consistency();
}