home *** CD-ROM | disk | FTP | other *** search
/ The Devil's Doorknob BBS Capture (1996-2003) / devilsdoorknobbbscapture1996-2003.iso / W / WWIVSOR.ZIP / FIX.C < prev    next >
C/C++ Source or Header  |  1995-04-27  |  34KB  |  1,442 lines

  1. /*****************************************************************************
  2.  
  3.                 WWIV Version 4
  4.                     Copyright (C) 1988-1995 by Wayne Bell
  5.  
  6. Distribution of the source code for WWIV, in any form, modified or unmodified,
  7. without PRIOR, WRITTEN APPROVAL by the author, is expressly prohibited.
  8. Distribution of compiled versions of WWIV is limited to copies compiled BY
  9. THE AUTHOR.  Distribution of any copies of WWIV not compiled by the author
  10. is expressly prohibited.
  11.  
  12.  
  13. *****************************************************************************/
  14.  
  15.  
  16.  
  17. /*
  18.  * Possible future enhancements:
  19.  *
  20.  * duplicate users?
  21.  * modem stuff ok
  22.  * check for various .dat files existence
  23.  * decrement mail waiting
  24.  */
  25.  
  26.  
  27.  
  28. #pragma warn -par
  29. void sysoplog(char *s) {}
  30. void giveup_timeslice(void) {}
  31. void read_status(void) {}
  32. #pragma warn +par
  33.  
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <io.h>
  37. #include <sys\stat.h>
  38. #include <string.h>
  39. #include <ctype.h>
  40. #include <fcntl.h>
  41. #include <alloc.h>
  42.  
  43. #ifdef __OS2__
  44. #define huge
  45. #endif /* __OS2__ */
  46.  
  47. #define EXTENDED
  48. #include "vardec.h"
  49. #include "share.h"
  50. #include "share.c"
  51.  
  52. #define OK  "   "
  53. #define NOK "## "
  54. #define QOK "?? "
  55.  
  56. void fix_user(void);
  57. int trashed_user(void);
  58. int open_file(char *fn);
  59. void remove_link(messagerec *m1, char *aux);
  60.  
  61. int userfile=-1,configfile=-1,statusfile=-1;
  62. int force_yes=0,no_usercheck=0;
  63. statusrec status;
  64. configrec syscfg;
  65. char *thisuser;
  66. char *thisuser_inact;
  67. char cdir[81];
  68. int num_dirs=0,num_subs=0;
  69. directoryrec *directories;
  70. subboardrec *subboards;
  71. unsigned long max_qscan;
  72. int curlsub=-1,nummsgs;
  73. short gat[2048];
  74. int gat_section;
  75. int url;
  76. int debuglevel=0;
  77. int incom=0;                                     /* keep share.c happy */
  78. int subchg=0;
  79. messagerec *emailm;
  80. char *emailmmm;
  81. int numemailm,num_type_0;
  82.  
  83. smalrec *smallist,*new_smallist;
  84. int cur_users;
  85.  
  86.  
  87. extern unsigned int wwiv_num_version;
  88. #define NOT_BBS 0
  89. #define malloca(x) bbsmalloc(x)
  90. #define MAX_TO_CACHE 163
  91. #include "subacc.c"
  92.  
  93.  
  94. int allow_changes=1,force_changes=0;
  95.  
  96. /****************************************************************************/
  97.  
  98. void read_user(unsigned int un)
  99. {
  100.   long pos;
  101.   char s[80];
  102.  
  103.   if (userfile==-1) {
  104.     sprintf(s,"%sUSER.LST",syscfg.datadir);
  105.     userfile=sh_open1(s,O_RDWR | O_BINARY);
  106.     if (userfile<0) {
  107.       *thisuser_inact=inact_deleted;
  108.       return;
  109.     }
  110.   }
  111.  
  112.   pos=((long) url) * ((long) un);
  113.   if (filelength(userfile)<(pos+syscfg.userreclen)) {
  114.     *thisuser_inact=inact_deleted;
  115.     return;
  116.   }
  117.  
  118.   lseek(userfile,pos,SEEK_SET);
  119.   read(userfile, thisuser, syscfg.userreclen);
  120. }
  121.  
  122. /****************************************************************************/
  123.  
  124. void write_user(unsigned int un)
  125. {
  126.   long pos;
  127.   char s[80];
  128.  
  129.   if (userfile==-1) {
  130.     sprintf(s,"%sUSER.LST",syscfg.datadir);
  131.     userfile=sh_open1(s,O_RDWR | O_BINARY);
  132.     if (userfile<0) {
  133.       return;
  134.     }
  135.   }
  136.  
  137.   pos=((long) url) * ((long) un);
  138.   if (filelength(userfile)<(pos+syscfg.userreclen)) {
  139.     return;
  140.   }
  141.  
  142.   lseek(userfile,pos,SEEK_SET);
  143.   write(userfile, thisuser, syscfg.userreclen);
  144. }
  145.  
  146. /****************************************************************************/
  147.  
  148.  
  149. void close_user(void)
  150. {
  151.   if (userfile!=-1) {
  152.     sh_close(userfile);
  153.     userfile=-1;
  154.   }
  155. }
  156.  
  157. /****************************************************************************/
  158.  
  159. void save_status(void)
  160. {
  161.   char s[80];
  162.  
  163.   sprintf(s,"%sSTATUS.DAT",syscfg.datadir);
  164.   statusfile=sh_open(s,O_RDWR | O_BINARY | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
  165.   write(statusfile, (void *)(&status), sizeof(statusrec));
  166.   sh_close(statusfile);
  167.   statusfile=-1;
  168. }
  169.  
  170. /****************************************************************************/
  171.  
  172. int exist(char *s)
  173. {
  174.   int f;
  175.  
  176.   f=sh_open1(s,O_RDONLY | O_BINARY);
  177.   sh_close(f);
  178.   if (f>0)
  179.     return(1);
  180.   else
  181.     return(0);
  182. }
  183.  
  184. /****************************************************************************/
  185.  
  186. void give_up(void)
  187. {
  188.   printf("\n%sGiving up.\n",NOK);
  189.   exit(-1);
  190. }
  191.  
  192.  
  193. /****************************************************************************/
  194.  
  195. void oom(void *x, char *where, long l)
  196. {
  197.   if (!x) {
  198.     printf("%sOut of memory for %s (%ld bytes).\n",NOK, where, l);
  199.     give_up();
  200.   }
  201. }
  202.  
  203. /****************************************************************************/
  204.  
  205. int yn(void)
  206. {
  207.   char ch;
  208.  
  209.   if (force_yes) {
  210.     printf("Yes\n");
  211.     return(1);
  212.   }
  213.  
  214.   while (1) {
  215.     ch=getch();
  216.     if ((ch=='Y') || (ch=='y')) {
  217.       printf("Yes\n");
  218.       return(1);
  219.     }
  220.     if ((ch=='N') || (ch=='n') || (ch==13)) {
  221.       printf("No\n");
  222.       return(0);
  223.     }
  224.   }
  225. }
  226.  
  227.  
  228. /****************************************************************************/
  229.  
  230. void maybe_give_up(void)
  231. {
  232.   printf("%sFuture expansion might try to fix this problem.\n",OK);
  233.   give_up();
  234. }
  235.  
  236. /****************************************************************************/
  237.  
  238. int mdto(char *s)
  239. {
  240.   char s1[81];
  241.   int i,db,st;
  242.  
  243.   strcpy(s1,s);
  244.   i=strlen(s1)-1;
  245.   db=(s1[i]=='\\');
  246.   if (i==0)
  247.     db=0;
  248.   if ((i==2) && (s1[1]==':'))
  249.     db=0;
  250.   if (db)
  251.     s1[i]=0;
  252.   st=mkdir(s1);
  253.   if (s[1]==':') {
  254.     i=setdisk(s[0]-'A');
  255.     if (i<=(s[0]-'A'))
  256.       st=1;
  257.   }
  258.   return(st);
  259. }
  260.  
  261.  
  262. int cdto(char *s)
  263. {
  264.   char s1[81];
  265.   int i,db,st;
  266.  
  267.   strcpy(s1,s);
  268.   i=strlen(s1)-1;
  269.   db=(s1[i]=='\\');
  270.   if (i==0)
  271.     db=0;
  272.   if ((i==2) && (s1[1]==':'))
  273.     db=0;
  274.   if (db)
  275.     s1[i]=0;
  276.   st=chdir(s1);
  277.   if (s[1]==':') {
  278.     i=setdisk(s[0]-'A');
  279.     if (i<=(s[0]-'A'))
  280.       st=1;
  281.   }
  282.   return(st);
  283. }
  284.  
  285. /****************************************************************************/
  286.  
  287.  
  288. void get_dir(char *s, int be)
  289. {
  290.   strcpy(s,"X:\\");
  291.   s[0]='A'+getdisk();
  292.   getcurdir(0,&(s[3]));
  293.   if (be) {
  294.     if (s[strlen(s)-1]!='\\')
  295.       strcat(s,"\\");
  296.   }
  297. }
  298.  
  299.  
  300. /****************************************************************************/
  301.  
  302. int check_dir(char *dir, char *descr)
  303. {
  304.   int st;
  305.  
  306.   st=cdto(dir);
  307.   if (st) {
  308.     printf("\n%sUnable to find dir '%s' \n   for %s dir, \n   CREATE it (y/N)? ",
  309.       NOK,dir,descr);
  310.     if(yn()) {
  311.       st=mdto(dir);
  312.       if (st)
  313.         printf("%sUnable to create dir '%s' for %s dir.\n",NOK,dir,descr);
  314.     } else {
  315.  
  316.     }
  317.   }
  318.   cdto(cdir);
  319.   return(st);
  320. }
  321.  
  322. /****************************************************************************/
  323.  
  324.  
  325. void check_all_dirs(void)
  326. {
  327.   int st=0,st1;
  328.   int i;
  329.  
  330.   st |= check_dir(syscfg.msgsdir,"Messages");
  331.   st |= check_dir(syscfg.gfilesdir,"G-files");
  332.   st |= check_dir(syscfg.datadir,"Data");
  333.   st |= check_dir(syscfg.dloadsdir,"Default Dloads");
  334.   st |= check_dir(syscfg.tempdir,"Temp");
  335.  
  336.   if (st) {
  337.     printf("%sOne of the critical system directories is not present or not set correctly.\n",NOK);
  338.     give_up();
  339.   }
  340.  
  341.   for (i=0; i<num_dirs; i++) {
  342.     if (!(directories[i].mask & mask_cdrom)) {
  343.       st1 = check_dir(directories[i].path,directories[i].name);
  344.       if (st1) {
  345.         st=1;
  346.         printf("%sEither create the dir, or use //DIREDIT to set it correctly.\n",NOK);
  347.         printf("%sThis program cannot fix this problem.\n",NOK);
  348.       }
  349.     }
  350.   }
  351. }
  352.  
  353.  
  354.  
  355. /****************************************************************************/
  356.  
  357. int trashed_str(char *s, int ml, int lower)
  358. {
  359.   int i,i1,st=0;
  360.  
  361.   i1=strlen(s);
  362.   if (i1>ml)
  363.     st=1;
  364.   else
  365.     for (i=0; i<i1; i++) {
  366.       if (s[i]<32)
  367.         st=1;
  368.       if ((!lower) && (islower(s[i])))
  369.         st=1;
  370.     }
  371.   return(st);
  372. }
  373.  
  374. /****************************************************************************/
  375.  
  376.  
  377. int trashed_user()
  378. {
  379.   if (trashed_str(thisuser,30,0))
  380.     return(1);
  381.  
  382.   return(0);
  383. }
  384.  
  385. void fix_user()
  386. {
  387.   thisuser[30]=0;
  388. }
  389.  
  390.  
  391. /****************************************************************************/
  392.  
  393.  
  394. void check_userlist(void)
  395. {
  396.   long l;
  397.   int nu,check_trash=0,trashed_userlist=0,xxx;
  398.  
  399.   url=syscfg.userreclen;
  400.   if (!url) {
  401.     url=700;
  402.     syscfg.userreclen=700;
  403.   }
  404.  
  405.   read_user(1);
  406.   if (userfile<0) {
  407.     printf("%sNo userlist present.\n",NOK);
  408.     give_up();
  409.   }
  410.  
  411.   l=filelength(userfile);
  412.   nu=(int) (l/((long)url)) - 1;
  413.  
  414.   printf("%sFound %d user records... ",OK,nu);
  415.  
  416.   if (nu>syscfg.maxusers) {
  417.     printf("Might be too many.\n");
  418.     check_trash=1;
  419.   } else
  420.     printf("Reasonable number.\n");
  421.  
  422.   if (check_trash) {
  423.     read_user(nu);
  424.     if ((xxx=trashed_user())!=0) {
  425.       trashed_userlist=1;
  426.       printf("%sUserrec #%u appeares trashed (%d).\n",NOK,nu,xxx);
  427.     }
  428.  
  429.     if (trashed_userlist) {
  430.       printf("%sUserlist appears screwed up.\n",NOK);
  431.     } else
  432.       printf("%sUserlist seems OK.\n",OK);
  433.   }
  434.  
  435.   if (trashed_userlist) {
  436.     if (!allow_changes)
  437.       give_up();
  438.  
  439.     printf("%sScanning for invalid user records...\n",OK);
  440.  
  441.     while ((nu) && (trashed_user()))
  442.       read_user(--nu);
  443.  
  444.     printf("%sAppears to be %u 'real' user records.\n",OK,nu);
  445.  
  446.     if (!force_changes) {
  447.       printf("%sTruncate userlist to %u users? ",QOK,nu);
  448.       if (!yn())
  449.         trashed_userlist=0;
  450.     }
  451.  
  452.     if (trashed_userlist) {
  453.       l=((long) nu) * ((long) syscfg.userreclen);
  454.       chsize(userfile,l);
  455.     }
  456.   }
  457. }
  458.  
  459.  
  460. /****************************************************************************/
  461.  
  462. void isr1(int un, char *name)
  463. {
  464.   int cp;
  465.   smalrec sr;
  466.  
  467.   cp=0;
  468.   while ((cp<cur_users) && (strcmp(name,(new_smallist[cp].name))>0))
  469.     ++cp;
  470.   memmove(&(new_smallist[cp+1]),&(new_smallist[cp]),sizeof(smalrec)*(cur_users-cp));
  471.   strcpy(sr.name,name);
  472.   sr.number=un;
  473.   new_smallist[cp]=sr;
  474.   ++cur_users;
  475. }
  476.  
  477. /****************************************************************************/
  478.  
  479.  
  480. void check_nameslist(void)
  481. {
  482.   char s[81];
  483.   int st=0,i,i1,i2,xxx;
  484.   unsigned int status_users,names_users;
  485.  
  486.   printf("%sScanning NAMES.LST file...\n",OK);
  487.   sprintf(s,"%sNAMES.LST",syscfg.datadir);
  488.   i=sh_open1(s,O_RDONLY | O_BINARY);
  489.   if (i>0) {
  490.     if (filelength(i)) {
  491.       smallist=(smalrec *)bbsmalloc(filelength(i)+1);
  492.       oom(smallist, "smallist", filelength(i));
  493.       read(i,smallist,(unsigned) filelength(i));
  494.       names_users=(unsigned int) (filelength(i)/sizeof(smalrec));
  495.       status_users=status.users;
  496.     } else
  497.       names_users=0;
  498.     sh_close(i);
  499.  
  500.     if (names_users!=status_users) {
  501.       status.users=names_users;
  502.       printf("%sstatus.users was wrong.  ",NOK);
  503.       if (allow_changes) {
  504.         printf("Fixed it.\n");
  505.         save_status();
  506.       } else {
  507.         printf("Leaving it alone.\n");
  508.       }
  509.     }
  510.   } else {
  511.     names_users=0;
  512.     status.users=status.users;
  513.     printf("%s%s NOT FOUND.\n",NOK,s);
  514.   }
  515.  
  516.   cur_users=0;
  517.  
  518.   i1=filelength(userfile)/syscfg.userreclen-1;
  519.  
  520.   new_smallist=(smalrec *)bbsmalloc(((long)i1+1) * ((long)sizeof(smalrec)));
  521.   oom(new_smallist,"new_smallist",((long)i1) * ((long)sizeof(smalrec)));
  522.  
  523.   for (i=1; i<=i1; i++) {
  524.     read_user(i);
  525.     if ((*thisuser_inact & inact_deleted)==0) {
  526.       if ((xxx=trashed_user())!=0) {
  527. #ifdef NOT_WORTH_IT
  528.         printf("\n%s User #%d had trashed info (%d); patching.\n",NOK,i,xxx);
  529.         fix_user();
  530.         write_user(i);
  531. #else
  532.         i2=xxx;
  533.         xxx=i2;
  534. #endif
  535.       }
  536.       isr1(i,thisuser);
  537.     }
  538.     if ((i % 10)==0)
  539.       printf("%s%d/%d\r",OK,i,i1);
  540.   }
  541.   printf("%s%d/%d\n",OK,i1,i1);
  542.  
  543.   if (cur_users!=names_users) {
  544.     st=1;
  545.     printf("%sA different number of users was found (%d vs %d).\n",NOK,
  546.         cur_users,names_users);
  547.  
  548.   } else {
  549.     for (i=0; i<names_users; i++) {
  550.       if (strcmp(smallist[i].name,new_smallist[i].name))
  551.         st=1;
  552.       if (smallist[i].number!=new_smallist[i].number)
  553.         st=1;
  554.     }
  555.   }
  556.   if (st) {
  557.     printf("%sThe new NAMES.LST file is different than the old one.\n",NOK);
  558.     if (allow_changes) {
  559.       status.users=cur_users;
  560.       i=sh_open(s,O_RDWR | O_BINARY | O_TRUNC | O_CREAT, S_IREAD | S_IWRITE);
  561.       if (i<0) {
  562.         printf("%sCouldn't create %s.\n",NOK,s);
  563.         give_up();
  564.       }
  565.       write(i,(void *) (new_smallist), (sizeof(smalrec) * status.users));
  566.       sh_close(i);
  567.  
  568.       save_status();
  569.       printf("%sNAMES.LST file fixed.\n",OK);
  570.     } else {
  571.       printf("%sLeaving it alone, but it should be fixed.  There is nothing bad that can\n",NOK);
  572.       printf("%shappen by fixing the NAMES.LST file.\n",NOK);
  573.     }
  574.   }
  575.   if (smallist) {
  576.     bbsfree(smallist);
  577.     smallist=NULL;
  578.   }
  579.   if (new_smallist) {
  580.     bbsfree(new_smallist);
  581.     new_smallist=NULL;
  582.   }
  583. }
  584.  
  585. /****************************************************************************/
  586.  
  587. #define GATSECLEN (4096L+2048L*512L)
  588. #define MSG_STARTING (((long)gat_section)*GATSECLEN + 4096)
  589.  
  590.  
  591. void set_gat_section(int f, int section)
  592. {
  593.   long l,l1;
  594.   int i;
  595.  
  596.   if (gat_section!=section) {
  597.     l=filelength(f);
  598.     l1=((long)section)*GATSECLEN;
  599.     if (l<l1) {
  600.       chsize(f,l1);
  601.       l=l1;
  602.     }
  603.     lseek(f,l1,SEEK_SET);
  604.     if (l<(l1+4096)) {
  605.       for (i=0; i<2048; i++)
  606.         gat[i]=0;
  607.       write(f,(void *)gat, 4096);
  608.     } else {
  609.       read(f,(void *)gat, 4096);
  610.     }
  611.     gat_section=section;
  612.   }
  613. }
  614.  
  615. /****************************************************************************/
  616.  
  617.  
  618. void save_gat(int f)
  619. {
  620.   long l;
  621.  
  622.   l=((long)gat_section)*GATSECLEN;
  623.   lseek(f,l,SEEK_SET);
  624.   write(f,(void *)gat,4096);
  625. }
  626.  
  627. /****************************************************************************/
  628.  
  629.  
  630.  
  631. void remove_link(messagerec *m1, char *aux)
  632. {
  633.   messagerec m;
  634.   char s[81],s1[81];
  635.   int f;
  636.   long csec,nsec;
  637.  
  638.   m=*m1;
  639.   strcpy(s,syscfg.msgsdir);
  640.   switch(m.storage_type) {
  641.     case 0:
  642.     case 1:
  643.       ltoa(m.stored_as,s1,16);
  644.       if (m.storage_type==1) {
  645.         strcat(s,aux);
  646.         strcat(s,"\\");
  647.       }
  648.       strcat(s,s1);
  649.       unlink(s);
  650.       break;
  651.     case 2:
  652.       f=open_file(aux);
  653.       if (f>=0) {
  654.         set_gat_section(f,(int) (m.stored_as/2048));
  655.         csec=m.stored_as % 2048;
  656.         while ((csec>0) && (csec<2048)) {
  657.           nsec=(long) gat[csec];
  658.           gat[csec]=0;
  659.           csec=nsec;
  660.         }
  661.         save_gat(f);
  662.         sh_close(f);
  663.       }
  664.       break;
  665.     default:
  666.       /* illegal storage type */
  667.       break;
  668.   }
  669. }
  670.  
  671. /****************************************************************************/
  672.  
  673.  
  674. void delmail(int f, int loc)
  675. {
  676.   mailrec m,m1;
  677.   int rm,i,t,otf;
  678.   char s[81];
  679.  
  680.   sprintf(s,"%sEMAIL.DAT",syscfg.datadir);
  681.   f=sh_open1(s,O_RDWR | O_BINARY);
  682.  
  683.  
  684.   lseek(f,((long) loc) * ((long) sizeof(mailrec)), SEEK_SET);
  685.   read(f,(void *)&m,sizeof(mailrec));
  686.  
  687.   rm=1;
  688.   if (m.status & status_multimail) {
  689.     t=filelength(f)/sizeof(mailrec);
  690.     otf=0;
  691.     for (i=0; i<t; i++)
  692.       if (i!=loc) {
  693.         lseek(f,((long)i)*((long)sizeof(mailrec)),SEEK_SET);
  694.         read(f,(void *)&m1,sizeof(mailrec));
  695.         if ((m.msg.stored_as==m1.msg.stored_as) && (m.msg.storage_type==m1.msg.storage_type) && (m1.daten!=0xffffffff))
  696.           otf=1;
  697.       }
  698.     if (otf)
  699.       rm=0;
  700.   }
  701.  
  702.   sh_close(f);
  703.   if (rm)
  704.     remove_link(&m.msg,"EMAIL");
  705.  
  706.   if (m.tosys==0) {
  707. #ifdef DEC_MAIL_WAITING
  708.     read_user(m.touser,&u);
  709.     if (u.waiting) {
  710.       --u.waiting;
  711.       write_user(m.touser,&u);
  712.       close_user();
  713.     }
  714. #endif
  715.   }
  716.  
  717.   f=sh_open1(s,O_RDWR | O_BINARY);
  718.   lseek(f,((long) loc) * ((long) sizeof(mailrec)), SEEK_SET);
  719.   m.touser=0;
  720.   m.tosys=0;
  721.   m.daten=0xffffffff;
  722.   m.msg.storage_type=0;
  723.   m.msg.stored_as=0xffffffff;
  724.   write(f,(void *)&m,sizeof(mailrec));
  725.   sh_close(f);
  726. }
  727.  
  728. /****************************************************************************/
  729.  
  730. void find_max_qscan(void)
  731. {
  732.   int i,cs,r,t,f,any_screwed, here_screwed;
  733.   unsigned long maxthissub;
  734.   mailrec m;
  735.   char s[81];
  736.   postrec *p;
  737.  
  738.   max_qscan=0L;
  739.   any_screwed=0;
  740.   num_type_0=0;
  741.  
  742.   printf("%sScanning subboards...\n",OK);
  743.  
  744.   for (cs=0; cs<num_subs; cs++) {
  745.     iscan1(cs,0);
  746.     open_sub(0);
  747.     maxthissub=0L;
  748.     here_screwed=0;
  749.     if (nummsgs) {
  750.       for (i=1; i<=nummsgs; i++) {
  751.         p=get_post(i);
  752.         if (maxthissub>=p->qscan) {
  753.           any_screwed=1;
  754.           here_screwed=1;
  755.         }
  756.         if (maxthissub<p->qscan)
  757.           maxthissub=p->qscan;
  758.         if (max_qscan<p->qscan)
  759.           max_qscan=p->qscan;
  760.         if (p->msg.storage_type<2) {
  761.           /* if (max_qscan<p->msg.stored_as)
  762.             max_qscan=p->msg.stored_as; */
  763.           if (p->msg.storage_type==0)
  764.             ++num_type_0;
  765.         }
  766.       }
  767.       if (here_screwed) {
  768.         printf("%sSub '%s' has q-scan pointers screwed up.\n",NOK,subboards[cs].name);
  769.       }
  770.     }
  771.     close_sub();
  772.   }
  773.  
  774.   printf("%sScanning EMAIL.DAT file...\n",OK);
  775.  
  776.   sprintf(s,"%sEMAIL.DAT",syscfg.datadir);
  777.   f=sh_open1(s,O_BINARY | O_RDWR);
  778.   if (f!=-1) {
  779.     t=(int) (filelength(f)/sizeof(mailrec));
  780.     r=0;
  781.     numemailm=t;
  782.     emailm=(messagerec *)bbsmalloc((t+1)*sizeof(messagerec));
  783.     emailmmm=(char *)bbsmalloc(t+1);
  784.     if (t) {
  785.       oom(emailm,"emailm",t*sizeof(messagerec));
  786.       oom(emailmmm,"emailmmm",t);
  787.     }
  788.     while (r<t) {
  789.       lseek(f,(long)(sizeof(mailrec)) * (long)(r),SEEK_SET);
  790.       read(f,(void *)&m,sizeof(mailrec));
  791.       emailm[r]=m.msg;
  792.       emailmmm[r]=m.status;
  793.       if ((m.tosys!=0) || (m.touser!=0)) {
  794.         if (m.msg.storage_type<2)
  795.           /* if (max_qscan<m.msg.stored_as)
  796.             max_qscan=m.msg.stored_as; */
  797.         if (m.msg.storage_type==0)
  798.           ++num_type_0;
  799.       }
  800.       ++r;
  801.     }
  802.     sh_close(f);
  803.   }
  804.   max_qscan++;
  805.   if (max_qscan>status.qscanptr) {
  806.     printf("%sMax qscan pointer trashed (%lu vs %lu).\n",NOK,max_qscan,status.qscanptr);
  807.     status.qscanptr=max_qscan;
  808.     if (allow_changes) {
  809.       save_status();
  810.       printf("%sFixed.\n",OK);
  811.     } else
  812.       printf("%sLeaving as-is, but it should be fixed.\n",OK);
  813.   }
  814.  
  815.   if (max_qscan>=0x80000000) {
  816.     printf("%sMax qscan pointer indicates qscan troubles (too big).\n", NOK);
  817.     any_screwed=1;
  818.   }
  819.  
  820.   if ((allow_changes) && (any_screwed)) {
  821.     if (!force_changes) {
  822.       printf("%sReset all qscan pointers on BBS? ",QOK);
  823.       if (!yn())
  824.         any_screwed=0;
  825.     }
  826.     if (any_screwed) {
  827.       printf("%sResetting qscan pointers... do //resetqscan from mainmenu also.\n",OK);
  828.       max_qscan=1;
  829.       status.qscanptr=max_qscan;
  830.       for (cs=0; cs<num_subs; cs++) {
  831.         if (iscan1(cs,0)) {
  832.           open_sub(1);
  833.           for (i=1; i<=nummsgs; i++) {
  834.             p=get_post(i);
  835.             if (p) {
  836.               p->qscan=status.qscanptr++;
  837.               write_post(i,p);
  838.             }
  839.           }
  840.           close_sub();
  841.         }
  842.       }
  843.       save_status();
  844.     }
  845.   }
  846. }
  847.  
  848.  
  849. /****************************************************************************/
  850.  
  851.  
  852. typedef struct {
  853.   long    stored_as;
  854.   int     subnum,msgnum;
  855. } type_0;
  856.  
  857.  
  858. /****************************************************************************/
  859.  
  860.  
  861. char *describem(char *s, int subnum, int msgnum)
  862. {
  863.   mailrec me;
  864.   postrec *mp;
  865.   char s1[81];
  866.   int f;
  867.  
  868.   if (subnum==-1) { /* email */
  869.     sprintf(s1,"%sEMAIL.DAT",syscfg.datadir);
  870.     f=sh_open1(s1,O_BINARY | O_RDWR);
  871.     lseek(f,(long)(sizeof(mailrec)) * (long)(msgnum),SEEK_SET);
  872.     read(f,(void *)&me,sizeof(mailrec));
  873.     sh_close(f);
  874.  
  875.     if (me.fromsys)
  876.       sprintf(s1,"user #%d @%d",me.fromuser,me.fromsys);
  877.     else
  878.       sprintf(s1,"user #%d",me.fromuser);
  879.  
  880.     sprintf(s,"Mail from %s to ",s1);
  881.  
  882.     if (me.tosys)
  883.       sprintf(s1,"user #%d @%d",me.touser,me.tosys);
  884.     else
  885.       sprintf(s1,"user #%d",me.touser);
  886.  
  887.     strcat(s,s1);
  888.  
  889.     sprintf(s1," '%.30s'",me.title);
  890.     strcat(s,s1);
  891.  
  892.   } else {
  893.     iscan1(subnum,0);
  894.     mp=get_post(msgnum);
  895.     if (mp) {
  896.       if (mp->ownersys)
  897.         sprintf(s,"Post #%d on '%s' by user #%d @%d",
  898.             msgnum+1,
  899.             subboards[subnum].name,
  900.             mp->owneruser,
  901.             mp->ownersys);
  902.       else
  903.         sprintf(s,"Post #%d on '%s' by user #%d",
  904.             msgnum+1,
  905.             subboards[subnum].name,
  906.             mp->owneruser);
  907.     } else {
  908.       sprintf(s, "Unreadable (?) post #%d on '%s'",
  909.             msgnum+1, subboards[subnum].name);
  910.     }
  911.   }
  912.   return(s);
  913. }
  914.  
  915.  
  916. /****************************************************************************/
  917.  
  918.  
  919. void check_type_1(int num, messagerec *list, char *extra, int todesc)
  920. {
  921.   char s[81],s1[81];
  922.   int i,i1,dup,ex;
  923.   char *already_done;
  924.  
  925.   if (!num)
  926.     return;
  927.  
  928.   sprintf(s,"%s%s\\",syscfg.msgsdir,extra);
  929.   already_done=(char *)bbsmalloc(num);
  930.   sprintf(s1,"already_done(%s)",extra);
  931.   oom(already_done,s1,num);
  932.  
  933.   for (i=0; i<num; i++)
  934.     already_done[i]=0;
  935.  
  936.   for (i=0; i<num; i++)
  937.     if ((list[i].storage_type==1) && (!already_done[i])) {
  938.       sprintf(s1,"%s%lX",s,list[i].stored_as);
  939.       ex=exist(s1);
  940.       dup=0;
  941.       if (!((todesc==-1) && (emailmmm[i] & status_multimail))) {
  942.         for (i1=i+1; i1<num; i1++)
  943.           if (list[i1].storage_type==1)
  944.             if (list[i1].stored_as==list[i].stored_as)
  945.               dup=1;
  946.       }
  947.       if (dup || (!ex)) {
  948.         if (!ex)
  949.           printf("%sFile not found: '%s'\n",NOK,s1);
  950.         if (dup)
  951.           printf("%sMessage file multiply referenced: '%s'\n",NOK,s1);
  952.         printf("%s  for %s\n",NOK,describem(s1,todesc,i));
  953.  
  954.         for (i1=i+1; i1<num; i1++)
  955.           if ((list[i1].storage_type==1) &&
  956.               (list[i1].stored_as==list[i].stored_as)) {
  957.             printf("%s  for %s\n",NOK,describem(s1,todesc,i1));
  958.             already_done[i1]=1;
  959.           }
  960.         printf("%s  No action taken.\n\n",NOK);
  961.       }
  962.     }
  963.   bbsfree(already_done);
  964. }
  965.  
  966. /****************************************************************************/
  967.  
  968.  
  969. int open_file(char *fn)
  970. {
  971.   int f;
  972.   char s[81];
  973.  
  974.   sprintf(s,"%s%s.DAT",syscfg.msgsdir,fn);
  975.   f=sh_open1(s,O_RDWR | O_BINARY);
  976.   if (f<0)
  977.     return(-1);
  978.  
  979.   lseek(f,0L,SEEK_SET);
  980.   read(f,(void *)gat,4096);
  981.   gat_section=0;
  982.   return(f);
  983. }
  984.  
  985.  
  986. /****************************************************************************/
  987.  
  988.  
  989. void check_type_2(int num, messagerec *list, char *extra, int todesc)
  990. {
  991.   int f,i,any,csec,csec1,any_dead,num_deadm,anything_done,numsec,sec;
  992.   char s[81];
  993.   int *deadm;
  994.   short huge *gati, huge *gatint;
  995.   long high;
  996.  
  997.   if (!num)
  998.     return;
  999.  
  1000.   f=open_file(extra);
  1001.   numsec=((int) (filelength(f)/GATSECLEN))+1;
  1002.   high=((long)numsec)*2048;
  1003.  
  1004.   gati=(short *)bbsmalloc(high*2+1);
  1005.   sprintf(s,"gati(%s)",extra);
  1006.   oom((void *)gati,s,high*2);
  1007.   gatint=(short *)bbsmalloc(high*2+1);
  1008.   sprintf(s,"gatint(%s)",extra);
  1009.   oom((void *)gatint,s,high*2);
  1010.  
  1011.  
  1012.   for (i=0; i<high; i++)
  1013.     gati[i]=0;
  1014.  
  1015.   for (i=0; i<numsec; i++) {
  1016.     set_gat_section(f,i);
  1017.     memcpy((char *) (gatint+2048*i), gat, 4096);
  1018.   }
  1019.  
  1020.   deadm=(int *)bbsmalloc(num*2);
  1021.   sprintf(s,"deadm(%s)",extra);
  1022.   oom(deadm,s,num*2);
  1023.  
  1024.   any=0;
  1025.   any_dead=0;
  1026.   num_deadm=0;
  1027.   anything_done=0;
  1028.  
  1029.   for (i=0; i<num; i++)
  1030.     if (list[i].storage_type==2) {
  1031.       if (f<0) {
  1032.         if (!any) {
  1033.           any=1;
  1034.           printf("%sType 2 data file not found: '%s%s.DAT'\n",
  1035.                 NOK,syscfg.msgsdir,extra);
  1036.         }
  1037.         deadm[num_deadm++]=i;
  1038.         anything_done=1;
  1039.       } else {
  1040.         sec=(list[i].stored_as/2048)*2048;
  1041.         csec=list[i].stored_as % 2048;
  1042.         while ((csec>0) && (csec<2048)) {
  1043.           if (gati[csec+sec]) {
  1044.             if (!((todesc==-1) && (emailmmm[i] & status_multimail))) {
  1045.               if (gati[csec+sec]!=-2)
  1046.                 gati[csec+sec]=-1;
  1047.               ++any_dead;
  1048.             }
  1049.             csec=-1;
  1050.           } else {
  1051.             if (!gatint[csec+sec]) {
  1052.               gati[csec+sec]=-2;
  1053.               ++any_dead;
  1054.               csec=-1;
  1055.             } else {
  1056.               gati[csec+sec]=i+1;
  1057.               csec=gatint[csec+sec];
  1058.             }
  1059.           }
  1060.         }
  1061.       }
  1062.     }
  1063.  
  1064.   if (f<0) {
  1065.     if (anything_done) {
  1066.  
  1067.       printf("%sDunno what to do about that.\n",NOK);
  1068.  
  1069.     }
  1070.     bbsfree((void *)gati);
  1071.     bbsfree((void *)deadm);
  1072.     bbsfree((void *)gatint);
  1073.     sh_close(f);
  1074.     return;
  1075.   }
  1076.  
  1077.   if (any_dead) {
  1078.     anything_done=1;
  1079.     printf("%sErrors in '%s%s.DAT':\n",NOK,syscfg.msgsdir,extra);
  1080.     for (i=0; i<num; i++)
  1081.       if (list[i].storage_type==2) {
  1082.         sec=(list[i].stored_as/2048)*2048;
  1083.         csec=list[i].stored_as % 2048;
  1084.         csec1=-1;
  1085.         while ((csec>0) && (csec<2048)) {
  1086.           if (gati[csec+sec]<0) {
  1087.             printf("%s  for %s\n",NOK,describem(s,todesc,i));
  1088.             if (gati[csec+sec]==-1) {
  1089.               printf("%s    Collided on cluster #%d\n",NOK,csec+sec);
  1090.               if (csec1==-1) {
  1091.                 printf("%s    First cluster of message, removing.\n",NOK);
  1092.                 deadm[num_deadm++]=i;
  1093.               } else {
  1094.                 gatint[csec1+sec]=-1;
  1095.                 printf("%s    Truncating message.\n",NOK);
  1096.               }
  1097.             } else if (gati[csec+sec]==-2) {
  1098.               printf("%s    Pointed to unallocated cluster #%d\n",NOK,csec+sec);
  1099.               if (csec1==-1) {
  1100.                 printf("%s    First cluster of message, removing.\n",NOK);
  1101.                 deadm[num_deadm++]=i;
  1102.               } else {
  1103.                 gatint[csec1+sec]=-1;
  1104.                 printf("%s    Truncating message.\n",NOK);
  1105.               }
  1106.             } else {
  1107.               printf("%s    Unknown error.\n",NOK);
  1108.             }
  1109.           }
  1110.           csec1=csec;
  1111.           csec=gatint[csec+sec];
  1112.         }
  1113.       }
  1114.  
  1115.   }
  1116.  
  1117.   any_dead=0;
  1118.   for (csec=0; csec<numsec; csec++)
  1119.     if ((gatint[csec]) && (gati[csec]<=0)) {
  1120.       gatint[csec]=0;
  1121.       ++any_dead;
  1122.     }
  1123.   if (any_dead) {
  1124.     printf("%sLost clusters recovered from '%s%s.DAT': %d\n",
  1125.           NOK,syscfg.msgsdir,extra,any_dead);
  1126.     anything_done=1;
  1127.   }
  1128.  
  1129.   if (anything_done) {
  1130.     i=force_changes;
  1131.     if ((allow_changes) && (!i)) {
  1132.       printf("%sWrite these changes to disk? ",QOK);
  1133.       i=yn();
  1134.     }
  1135.  
  1136.  
  1137.     if (i) {
  1138.       printf("%sUpdating '%s%s.DAT'.\n",OK,syscfg.msgsdir,extra);
  1139.       for (i=0; i<numsec; i++) {
  1140.         set_gat_section(f,i);
  1141.         memcpy(gat, (char *) (gatint+2048*i), 4096);
  1142.         save_gat(f);
  1143.       }
  1144.       if (num_deadm) {
  1145.         printf("%sRemoving messages with no text.\n",OK);
  1146.         if (todesc!=-1) {
  1147.           iscan1(todesc,0);
  1148.  
  1149.           for (i=0; i<num_deadm; i++)
  1150.             delete(deadm[i]-i+1);
  1151.  
  1152.         } else {
  1153.           for (i=0; i<num_deadm; i++)
  1154.             delmail(f,deadm[i]);
  1155.  
  1156.         }
  1157.       }
  1158.     }
  1159.   }
  1160.   sh_close(f);
  1161.   bbsfree((void *)deadm);
  1162.   bbsfree((void *)gati);
  1163.   bbsfree((void *)gatint);
  1164. }
  1165.  
  1166.  
  1167. /****************************************************************************/
  1168.  
  1169.  
  1170. void check_msg_consistency(void)
  1171. {
  1172.   type_0 *x0;
  1173.   int cs,i,i1,i2,cp,ex;
  1174.   char s[81],s1[81];
  1175.   postrec *p;
  1176.   messagerec *pm;
  1177.  
  1178.   /* check type 0 consistency */
  1179.  
  1180.   if (num_type_0) {
  1181.     printf("%sChecking type 0 message consistency.\n",OK);
  1182.     x0=(type_0 *)bbsmalloc(sizeof(type_0)*num_type_0);
  1183.     oom(x0,"x0",sizeof(type_0)*num_type_0);
  1184.     cp=0;
  1185.     for (cs=0; cs<num_subs; cs++) {
  1186.       iscan1(cs, 0);
  1187.       open_sub(0);
  1188.       for (i=1; i<=nummsgs; i++) {
  1189.         p=get_post(i);
  1190.         if ((p->msg.storage_type==0) && (p->msg.stored_as!=(unsigned long)-1)) {
  1191.           x0[cp].stored_as=p->msg.stored_as;
  1192.           x0[cp].subnum=cs;
  1193.           x0[cp].msgnum=i+1;
  1194.           ++cp;
  1195.         }
  1196.       }
  1197.       close_sub();
  1198.     }
  1199.     for (cs=0; cs<numemailm; cs++)
  1200.       if ((!emailm[cs].storage_type) && (emailm[cs].stored_as != (unsigned long)-1)) {
  1201.         x0[cp].stored_as=emailm[cs].stored_as;
  1202.         x0[cp].subnum=-1;
  1203.         x0[cp].msgnum=cs;
  1204.         ++cp;
  1205.       }
  1206.  
  1207.     for (i=0; i<cp; i++) {
  1208.       if (x0[i].subnum!=-2) {
  1209.         sprintf(s,"%s%lX",syscfg.msgsdir,x0[i].stored_as);
  1210.         ex=exist(s);
  1211.  
  1212.         i2=0;
  1213.  
  1214.         for (i1=i+1; i1<cp; i1++)
  1215.           if (x0[i].stored_as==x0[i1].stored_as)
  1216.             i2=1;
  1217.  
  1218.         if (i2 || (!ex)) {
  1219.           if (!ex)
  1220.             printf("%sFile not found: '%s'\n",NOK,s);
  1221.           if (i2)
  1222.             printf("%sMessage file multiply referenced: '%s'\n",NOK,s);
  1223.           printf("%s  for %s\n",NOK,describem(s1,x0[i].subnum,x0[i].msgnum));
  1224.           for (i1=i+1; i1<cp; i1++)
  1225.             if (x0[i].stored_as==x0[i1].stored_as) {
  1226.               printf("%s  for %s\n",NOK,describem(s1,x0[i1].subnum,x0[i1].msgnum));
  1227.               x0[i1].subnum=-2;
  1228.             }
  1229.           printf("%s  No action taken.\n\n",NOK);
  1230.         }
  1231.       }
  1232.     }
  1233.  
  1234.     bbsfree(x0);
  1235.   }
  1236.  
  1237.   /* check type 1&2 consistency */
  1238.  
  1239.   printf("%sChecking type 1&2 message consistency.\n",OK);
  1240.   check_type_1(numemailm,emailm,"EMAIL",-1);
  1241.   check_type_2(numemailm,emailm,"EMAIL",-1);
  1242.   for (cs=0; cs<num_subs; cs++) {
  1243.     iscan1(cs, 0);
  1244.     if (nummsgs) {
  1245.       pm=(messagerec *)bbsmalloc(nummsgs*sizeof(messagerec));
  1246.       open_sub(1);
  1247.       sprintf(s,"pm(%s)",subboards[cs].filename);
  1248.       oom(pm,s,nummsgs*sizeof(messagerec));
  1249.       for (i=1; i<=nummsgs; i++) {
  1250.         pm[i-1]=get_post(i)->msg;
  1251.       }
  1252.       check_type_1(nummsgs,pm,subboards[cs].filename,cs);
  1253.       check_type_2(nummsgs,pm,subboards[cs].filename,cs);
  1254.       close_sub();
  1255.       bbsfree(pm);
  1256.     }
  1257.   }
  1258. }
  1259.  
  1260.  
  1261. /****************************************************************************/
  1262.  
  1263.  
  1264. void ck_size(char *fn, int f, long rl)
  1265. {
  1266.   long l;
  1267.  
  1268.   l=filelength(f);
  1269.   if (l<rl) {
  1270.     printf("%s%s too short (%ld<%ld).\n",NOK,fn,l,rl);
  1271.     give_up();
  1272.   }
  1273.  
  1274.   if (l>rl) {
  1275.     printf("%s%s too long (%ld>%ld).\n",NOK,fn,l,rl);
  1276.     if (allow_changes)
  1277.       printf("%sAttempting to continue.\n",NOK);
  1278.     else
  1279.       give_up();
  1280.   }
  1281. }
  1282.  
  1283. /****************************************************************************/
  1284.  
  1285. void init(void)
  1286. {
  1287.   char s[81];
  1288.   int i;
  1289.  
  1290.   strcpy(s,"CONFIG.DAT");
  1291.   configfile=sh_open1(s,O_RDWR | O_BINARY);
  1292.   if (configfile<0) {
  1293.     printf("%s%s NOT FOUND.\n",NOK,s);
  1294.     give_up();
  1295.   }
  1296.  
  1297.   ck_size(s,configfile,sizeof(configrec));
  1298.  
  1299.   read(configfile,(void *) (&syscfg), sizeof(configrec));
  1300.   sh_close(configfile);
  1301.  
  1302.   strcpy(cdir,"X:\\");
  1303.   cdir[0]='A'+getdisk();
  1304.   getcurdir(0,&(cdir[3]));
  1305.  
  1306.   if (check_dir(syscfg.datadir,"Data")) {
  1307.     printf("%sMust find data directory to continue.\n",NOK);
  1308.     give_up();
  1309.   }
  1310.  
  1311.   if (!syscfg.userreclen)
  1312.     syscfg.userreclen=700;
  1313.  
  1314.   thisuser=(char *)bbsmalloc(syscfg.userreclen+1);
  1315.   if (!thisuser) {
  1316.     printf("%sCould not allocate %d bytes for userrec.\n",NOK,syscfg.userreclen);
  1317.     give_up();
  1318.   }
  1319.   thisuser_inact=thisuser+syscfg.inactoffset;
  1320.  
  1321.   sprintf(s,"%sSTATUS.DAT",syscfg.datadir);
  1322.   statusfile=sh_open1(s,O_RDWR | O_BINARY);
  1323.   if (statusfile<0) {
  1324.     printf("%s%s NOT FOUND.\n",NOK,s);
  1325.     if (allow_changes) {
  1326.       printf("%sRe-creating STATUS.DAT file.\n",OK);
  1327.       strcpy(status.date1,"00/00/00");
  1328.       strcpy(status.date2,status.date1);
  1329.       strcpy(status.date3,status.date1);
  1330.       strcpy(status.log1,"000000.LOG");
  1331.       strcpy(status.log2,status.log1);
  1332.       strcpy(status.gfiledate,"00/00/00");
  1333.       status.users=0;
  1334.       status.callernum=65535;
  1335.       status.callstoday=0;
  1336.       status.msgposttoday=0;
  1337.       status.localposts=0;
  1338.       status.emailtoday=0;
  1339.       status.fbacktoday=0;
  1340.       status.uptoday=0;
  1341.       status.activetoday=0;
  1342.       status.qscanptr=0L;
  1343.       status.amsganon=0;
  1344.       status.amsguser=0;
  1345.       status.callernum1=0L;
  1346.       status.net_edit_stuff=0;
  1347.       status.wwiv_version=0;
  1348.       status.net_version=0;
  1349.       status.net_bias=0.001;
  1350.     } else
  1351.       give_up();
  1352.   } else {
  1353.  
  1354.     ck_size(s,statusfile,sizeof(statusrec));
  1355.     read(statusfile,(void *)(&status), sizeof(statusrec));
  1356.     sh_close(statusfile);
  1357.  
  1358.     if (status.wwiv_version > wwiv_num_version) {
  1359.       printf("%sYou need a newer version of fix (this is for %d, you need %d)\n",
  1360.             NOK, wwiv_num_version, status.wwiv_version);
  1361.       give_up();
  1362.     }
  1363.  
  1364.   }
  1365.  
  1366.  
  1367.   sprintf(s,"%sDIRS.DAT",syscfg.datadir);
  1368.   i=sh_open1(s,O_RDWR | O_BINARY);
  1369.   if (i<0) {
  1370.     printf("%s%s NOT FOUND.\n",NOK,s);
  1371.     maybe_give_up();
  1372.   } else {
  1373.     directories=(directoryrec *)bbsmalloc(filelength(i)+1);
  1374.     if (!directories) {
  1375.       printf("%sCouldn't allocate %ld bytes for %s.\n",NOK,filelength(i), s);
  1376.       give_up();
  1377.     }
  1378.     num_dirs=(read(i,directories, (filelength(i))))/
  1379.               sizeof(directoryrec);
  1380.     sh_close(i);
  1381.   }
  1382.  
  1383.   sprintf(s,"%sSUBS.DAT",syscfg.datadir);
  1384.   i=sh_open1(s,O_RDWR | O_BINARY);
  1385.   if (i<0) {
  1386.     printf("%s%s NOT FOUND.\n",NOK,s);
  1387.     maybe_give_up();
  1388.   } else {
  1389.     subboards=(subboardrec *)bbsmalloc(filelength(i)+1);
  1390.     if (!subboards) {
  1391.       printf("%sCouldn't allocate %ld bytes for %s.\n",NOK,filelength(i),s);
  1392.       give_up();
  1393.     }
  1394.     num_subs=(read(i, subboards, (filelength(i))))/
  1395.              sizeof(subboardrec);
  1396.     sh_close(i);
  1397.  
  1398.   }
  1399. }
  1400.  
  1401. /****************************************************************************/
  1402.  
  1403.  
  1404. void main(int argc, char *argv[])
  1405. {
  1406.   int i;
  1407.   char *ss;
  1408.  
  1409.   for (i=1; i<argc; i++) {
  1410.     ss=argv[i];
  1411.     if ((*ss=='/') || (*ss=='-')) {
  1412.       switch(toupper(ss[1])) {
  1413.         case 'Y': force_yes=1; break;
  1414.         case 'U': no_usercheck=1; break;
  1415.       }
  1416.     } else {
  1417.       printf("%sUnknown argument: '%s'\n",NOK,ss);
  1418.     }
  1419.   }
  1420.  
  1421.   printf("\n");
  1422.   printf("Fix - Fix WWIV files.\n");
  1423.   printf("\n");
  1424.  
  1425.   if (getenv("BBS")) {
  1426.     printf("Fix should only be run OUTSIDE the BBS.\n");
  1427.     exit(-1);
  1428.   }
  1429.  
  1430.   init();
  1431.  
  1432.   check_all_dirs();
  1433.   check_userlist();
  1434.   if (!no_usercheck)
  1435.     check_nameslist();
  1436.   find_max_qscan();
  1437.   check_msg_consistency();
  1438.  
  1439. }
  1440.  
  1441.  
  1442.