home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / prog / c / afixsrc.lha / areafix.c next >
C/C++ Source or Header  |  1990-05-23  |  38KB  |  1,658 lines

  1. /*======================================================================*/
  2. /* AreaFix 1.00 by Russel Miranda                    */
  3. /*======================================================================*/
  4.  
  5. #include <AreaFix.h>
  6.  
  7. void main(int argc, char *argv[])
  8. {
  9.     struct msg *header;    /* I found that all the variables I    */
  10.     char *msgname;        /* needed wouldn't fit nicely onto the    */
  11.     char *line;        /* stack, so I made pointers to all of    */
  12.     short high;        /* them, and allocated the space later.    */
  13.     char *temp;        
  14.     char *cmds;        
  15.     char *in;        
  16.     char *out;        
  17.     char *pass;        
  18.     char *message;        
  19.     char *configname="PARAGON:AreaFix.CFG";
  20.     int index,count,processed=0,dots,searchbase=0;
  21.     int fwdlvl=0;
  22.     char rescan=FALSE,remove=FALSE,firstline=FALSE;
  23.     char query=FALSE,listareas=FALSE,change=FALSE;
  24.     struct area *found=NULL;
  25.     struct address *newadr;
  26.     struct address *orignode;
  27.     FILE *fptr;
  28.     
  29.     printf(    "%-15s v%-5s - by Russel Miranda\n------------------------------------------\n",prgname,version);
  30.         
  31.     if((argc>1)&&(argv[1][0]=='?'))
  32.     {
  33.         printf(
  34.         "Usage:\n"
  35.         "\n"
  36.         "1.> AreaFix [-c<filename>] [-f]\n\n"
  37.         "-c<filename> - specifies an alternate config file.\n"
  38.         "-f           - forces the generation of a new Areas.CTL file.\n\n"
  39.         "ParCon must be active before this can be run.\n\n");
  40.         exit(0);
  41.     }
  42.     
  43.     for(index=1;index<argc;index++)
  44.     {
  45.         if(argv[index][0]=='-')
  46.         {
  47.             switch(toupper(argv[index][1]))
  48.             {
  49.                 case 'C':
  50.                     configname=&argv[index][2];
  51.                     break;
  52.                 case 'F':
  53.                     change=TRUE;
  54.                     break;
  55.             }
  56.         }
  57.     }
  58.     
  59.     mytask=FindTask(0L);            /* Rename the task for    */
  60.     oldname=mytask->tc_Node.ln_Name;    /* the brief period of    */
  61.     mytask->tc_Node.ln_Name = prgname;        /* time I'm here!    */
  62.     
  63.     StartLink();            /* For info on this, see the    */
  64.     bbspath=bbsconfig->defpath;    /* header "ParConLnk.h"        */
  65.     
  66.     printf("Working...");
  67.     
  68.     /* This way is much better than putting a 256 character string    */
  69.     /* onto the stack.                        */
  70.     
  71.     line=(char *)calloc(256,sizeof(char));
  72.     filename=(char *)calloc(256,sizeof(char));
  73.     if(!(filename && line))
  74.     {
  75.         printf("Error allocating memory.\n");
  76.         EXit(10);
  77.     }
  78.     
  79.     lprintf("    %s v%s by Russel Miranda\n",prgname,version);
  80.     TimeStr(line);
  81.     lprintf("*-- Session started @ %s\n",line);
  82.     
  83.     newadr=(struct address *)calloc(1,sizeof(struct address));
  84.     orignode=(struct address *)calloc(1,sizeof(struct address));
  85.     header=(struct msg *)calloc(1,sizeof(struct msg));
  86.     msgname=(char *)calloc(256,sizeof(char));
  87.     in=(char *)calloc(256,sizeof(char));
  88.     out=(char *)calloc(256,sizeof(char));
  89.     pass=(char *)calloc(256,sizeof(char));
  90.     message=(char *)calloc(256,sizeof(char));
  91.         
  92.     if(!(newadr && orignode && header && msgname && in && out && pass && message))
  93.         NoMem();
  94.     
  95.     /* Setup the default input and output files.            */
  96.     
  97.     sprintf(in,"%sAreas.CTL",bbspath);
  98.     sprintf(out,"%sAreas.CTL",bbspath);
  99.     
  100.     /* Read the config file.                    */
  101.     
  102.     ReadCfg(configname,in,out,&fwdlvl,&searchbase);
  103.     
  104.     /* Read the highpoint file.                      */
  105.     
  106.     high=GetHiMk((short)searchbase);
  107.     
  108.     /* Read the AREAS.CTL file, and build a list of areas and the    */
  109.     /* systems they are connected to.                */
  110.     
  111.     InputAreas(&change,in);
  112.     
  113.     /* Check the QUE file to find out if anyone is waiting for an    */
  114.     /* echo whose request we've forwarded... If so, build the list.    */
  115.     
  116.     BuildReqLst();
  117.     
  118.     /* Scan for messages to AreaFix, and if any are found, process    */
  119.     /* them immediately!                        */
  120.     
  121.     lprintf("|   Scanning messages in area %d...\n",searchbase+1);
  122.     
  123.     for(count=high+1;count<=bbsconfig->himsgno[searchbase];count++)
  124.     {
  125.         sprintf(msgname,"%s%d.%d",bbsconfig->msgpath[searchbase],count,searchbase+1);
  126. #ifdef DEBUG
  127.         printf("Checking message: %s\r",msgname);
  128. #endif
  129.         if(fptr=fopen(msgname,"rb"))
  130.         {
  131. #ifdef DEBUG
  132.             printf("\nOpened, checking...\r");
  133. #endif
  134.             fread((char *)header,sizeof(struct msg)-2,1,fptr);
  135.             if(AliasMatch(header->touser))
  136.             {
  137. #ifdef DEBUG
  138.                 printf("\nHas my name on it...\n");
  139.                 printf("Destination Address: (%d/%d)\n",header->desnet,header->desnode);
  140. #endif
  141.                 /* Process the message.            */
  142.                 
  143.                 if((header->desnet!=bbsconfig->net)||(header->desnode!=bbsconfig->node))
  144.                     continue;
  145.                 
  146. #ifdef DEBUG
  147.                 printf("It's for me!\n");
  148. #endif
  149.                 
  150.                 orignode->zone=0;
  151.                 orignode->net=header->orignet;
  152.                 orignode->node=header->orignode;
  153.                 
  154.                 lprintf("| * Processing message #%d from (%d/%d):\n",count,orignode->net,orignode->node);
  155.                 
  156.                 replymsg=MessageOpen(orignode,header->fromuser,prgname,searchbase,"Auto Reply",message);
  157.                 
  158.                 listareas=FALSE;
  159.                 rescan=FALSE;
  160.                 query=FALSE;
  161.                 
  162.                 processed++;
  163.                 
  164.                 if(cmds=strchr(header->subject,' '))
  165.                 {
  166.                     *cmds=0;
  167.                     cmds++;
  168.                     cmds=stpblk(cmds);
  169.                 }
  170.                 
  171.                 if(!PassMatch(orignode,header->subject))
  172.                 {
  173.                     fprintf(replymsg,"Invalid password.\r\n");
  174.                     MessageClose(replymsg,searchbase,message);
  175.                     lprintf("| : Invalid password: \"%s\"\n",header->subject);
  176.                     lprintf("| * Message processing aborted.\n");
  177.                     continue;
  178.                 }
  179.                 
  180.                 while((*cmds)&&(cmds))
  181.                 {
  182.                     if(cmds[0]=='-')
  183.                     {
  184.                         if(!strnicmp(cmds,"-L",2))
  185.                         {
  186.                             lprintf("| | Echo list requested.\n");
  187.                             listareas=TRUE;
  188.                             if(cmds=strchr(cmds,' '))
  189.                                 cmds=stpblk(cmds);
  190.                             continue;
  191.                         }
  192.                         if(!strnicmp(cmds,"-R",2))
  193.                         {
  194.                             lprintf("| | Requested rescan.\n");
  195.                             rescan=TRUE;
  196.                             if(cmds=strchr(cmds,' '))
  197.                                 cmds=stpblk(cmds);
  198.                             continue;
  199.                         }
  200.                         if(!strnicmp(cmds,"-Q",2))
  201.                         {
  202.                             lprintf("| | Query list requested.\n");
  203.                             query=TRUE;
  204.                             if(cmds=strchr(cmds,' '))
  205.                                 cmds=stpblk(cmds);
  206.                             continue;
  207.                         }
  208.                     }
  209.                     if(cmds=strchr(cmds,' '))
  210.                         cmds=stpblk(cmds);
  211.                     lprintf("| < Invalid subject line command.\r\n");
  212.                 }
  213.                 
  214.                 firstline=TRUE;
  215.                 while(GetLine(fptr,line))
  216.                 {
  217.                     if(line[0]==0x01)
  218.                         continue;
  219.                     strupr(line);
  220.                     temp=line;
  221.                     if(!strncmp(temp,"---",3))
  222.                         break;
  223.                     if(firstline)
  224.                     {
  225.                         fprintf(replymsg,"                 Changes in EchoMail Topology\r\n\r\n");
  226.                         fprintf(replymsg,"AREA:                            STATUS:\r\n");
  227.                         fprintf(replymsg,"-------------------------------  -------------------------------\r\n");
  228.                         firstline=FALSE;
  229.                     }
  230.                     if(temp[0]=='-')
  231.                     {
  232.                         temp++;
  233.                         remove=TRUE;
  234.                     }
  235.                     else
  236.                         remove=FALSE;
  237.                     fprintf(replymsg,"%s ",line);
  238.                     for(dots=strlen(line);dots<=29;dots++)
  239.                         fputc('.',replymsg);
  240.                     fprintf(replymsg,"  ");
  241.                     if(found=FindAreaT(temp))
  242.                     {
  243.                         if(remove)
  244.                         {
  245.                             lprintf("| | Attempting to disconnect from area \"%s\": ",temp);
  246.                             if(RemoveNode(found,orignode))
  247.                             {
  248.                                 fprintf(replymsg,"Deleted.\r\n");
  249.                                 lprintf("Disconnected.\n");
  250.                                 change=TRUE;
  251.                             }
  252.                             else
  253.                             {
  254.                                 fprintf(replymsg,"Not previously connected.\r\n");
  255.                                 lprintf("Not connected.\r\n");
  256.                             }
  257.                         }
  258.                         else
  259.                         {
  260.                             lprintf("| | Attempting to add area \"%s\": ",temp);
  261.                             if(!FindNode(found,orignode))
  262.                             {
  263.                                 if(GoodLevel(orignode,temp))
  264.                                 {
  265.                                     NodeAdd(found,orignode);
  266.                                     fprintf(replymsg,"Added area");
  267.                                     lprintf("Added");
  268.                                     change=TRUE;
  269.                                     if(rescan)
  270.                                     {
  271.                                         ReScan(found);
  272.                                         fprintf(replymsg," and rescanned");
  273.                                         lprintf(" and rescanned");
  274.                                     }
  275.                                     fprintf(replymsg,".\r\n");
  276.                                     lprintf(".\n");
  277.                                 }
  278.                                 else
  279.                                 {
  280.                                     fprintf(replymsg,"Security too low.\r\n");
  281.                                     lprintf("Insufficient security.\n");
  282.                                 }
  283.                             }
  284.                             else
  285.                             {
  286.                                 fprintf(replymsg,"Previously connected");
  287.                                 lprintf("Previously connected");
  288.                                 if(rescan)
  289.                                 {
  290.                                     fprintf(replymsg,", rescanning\r\n");
  291.                                     lprintf(", rescanning\n");
  292.                                     ReScan(found);
  293.                                 }
  294.                                 fprintf(replymsg,".\r\n");
  295.                                 lprintf(".\n");
  296.                             }
  297.                         }
  298.                     }
  299.                     else
  300.                     {
  301.                         if(!remove)
  302.                         {
  303.                             if(AvailFrom(newadr,temp,pass))
  304.                             {
  305.                                 if(SecLevel(orignode)>=fwdlvl)
  306.                                 {
  307.                                     if(AddReq(temp,newadr,orignode))
  308.                                         AddFwd(line,newadr,pass);
  309.                                     fprintf(replymsg,"Forwarded request.\r\n");
  310.                                     lprintf("| | Attempting to add area \"%s\": Forwarded request to (%d/%d).\n",temp,newadr->net,newadr->node);
  311.                                 }
  312.                                 else
  313.                                 {
  314.                                     fprintf(replymsg,"Not Available.\r\n");
  315.                                     lprintf("| + Attempting to forward request for area \"%s\": Insufficient security.\n",temp);
  316.                                 }
  317.                             }
  318.                             else
  319.                             {
  320.                                 fprintf(replymsg,"Not available.\r\n");
  321.                                 lprintf("| + Attempting to add area \"%s\": Tag not found/available.\n",temp);
  322.                             }
  323.                         }
  324.                         else
  325.                         {
  326.                             fprintf(replymsg,"Not connected.\n");
  327.                             lprintf("| + Attempting to remove \"%s\": Not connected.\n",temp);
  328.                         }
  329.                     }
  330.                 }
  331.                 
  332.                 ActiveAreas(replymsg,orignode);
  333.                 if(query)
  334.                     AvailAreas(replymsg,orignode);
  335.                 MessageClose(replymsg,searchbase,message);
  336.                 if(listareas)
  337.                 {
  338.                     lprintf("| | Attempting to send AvailAreas.TXT\n");
  339.                     List(orignode,searchbase);
  340.                 }
  341.                 lprintf("| * Processing complete.\n");
  342.             }
  343.             fclose(fptr);
  344.         }
  345.     }
  346.     
  347.     /* Save the high marks again.                    */
  348.     
  349.     SaveHiMk((short)searchbase,bbsconfig->himsgno[searchbase]);
  350.     
  351.     lprintf("|   Scanning complete.  %d messages processed.\n",processed);
  352.     
  353.     /* If someone sent out a request (or maybe several) that I had    */
  354.     /* to forward, now is a good time to send them.            */
  355.     
  356.     SendFwd(searchbase);
  357.     
  358.     /* Check to see if any of the echos we've been waiting for are    */
  359.     /* here yet...                            */
  360.     
  361.     ProcQue(&change,searchbase);
  362.     
  363.     /* Save the ones that aren't in yet...                */
  364.     
  365.     SaveQue();
  366.     
  367.     /* We don't need ParCon anymore, sever the link.        */
  368.     
  369.     EndLink();
  370.     
  371.     /* If anything changed, save the AREAS.CTL file...        */
  372.     
  373.     if(change)
  374.     {
  375.         OutputAreas(out);
  376.         lprintf("|   New \"%s\" created.\n",out);
  377.     }
  378.     
  379.     TimeStr(line);
  380.     lprintf("*-- Session ended @ %s\n",line);
  381.     printf("Done.\nTotal messages processed: %d\n",processed);
  382.     EXit(0);
  383. }
  384.  
  385. /*-                                       -*\
  386.  * GetLine() - A nice little function I slapped together for reading a    *
  387.  *    line from a config file or a message, it will only return lines    *
  388.  *    that have something in them, and will discard the text after a    *
  389.  *    semicolon.  Pass over the file pointer, and the address of a    *
  390.  *    string 256 characters in length, and it will fill it with the    *
  391.  *    line from the file.  Returns a 1 if it was sucessful, returns    *
  392. \*-    a 0 if it hit the end of the file.                   -*/
  393.  
  394. int GetLine(FILE *fptr,char *str)
  395. {
  396.     char *strptr;
  397.     unsigned char count;
  398.     unsigned char len;
  399.     
  400.     do
  401.     {
  402.         if(!fgets(str,255,fptr))
  403.             return 0;
  404.         if(str[strlen(str)-1]=='\n')
  405.             str[strlen(str)-1]=0;
  406.         strptr=stpblk(str);
  407.         len=strlen(strptr);
  408.         for(count=0;count<len;count++)
  409.         {
  410.             if(strptr[count]==';')
  411.             {
  412.                 strptr[count]=0;
  413.                 break;
  414.             }
  415.         }
  416.         len=strlen(strptr);
  417.         for(count=len-1;((count>=0)&&(isspace(strptr[count])));count--)
  418.             strptr[count]=0;
  419.     } while(!strlen(strptr));
  420.     return 1;
  421. }
  422. /*-                                       -*\
  423.  * AreaAdd - adds an area to the area list                *
  424. \*-                                       -*/
  425.  
  426. struct area *AreaAdd(short number)
  427. {
  428.     struct area *new;
  429.     
  430.     if(!(new=(struct area *)calloc(1,sizeof(struct area))))
  431.         EXit(10);
  432.     
  433.     new->areanum=number;
  434.     strcpy(new->areatag,bbsconfig->tagname[number-1]);
  435.     
  436.     if(!first)
  437.         first=new;
  438.     else
  439.         last->next=new;
  440.     last=new;
  441.     return new;
  442. }
  443.  
  444. /*-                                       -*\
  445.  * NodeAdd() - adds a node to the node list hanging off of an area list    *
  446. \*-                                       -*/
  447.  
  448. void NodeAdd(struct area *to,struct address *add)
  449. {
  450.     struct address *new;
  451.     
  452.     if(!(new=(struct address *)calloc(1,sizeof(struct address))))
  453.         EXit(10);
  454.     new->zone=(add->zone);
  455.     new->net=(add->net);
  456.     new->node=(add->node);
  457.     
  458.     if(!(to->firstnode))
  459.         to->firstnode=new;
  460.     else
  461.         to->lastnode->nextnode=new;
  462.     to->lastnode=new;
  463. }
  464.  
  465. /*-                                       -*\
  466.  * OutputAreas() - writes the Areas.CTL file                *
  467. \*-                                       -*/
  468.  
  469. void OutputAreas(char *outfile)
  470. {
  471.     struct address *curadd;
  472.     struct area *cur=first;
  473.     FILE *fptr;
  474.     
  475.     if(!(fptr=fopen(outfile,"w")))
  476.     {
  477.         printf("Error writing output file: \"%s\"\n",outfile);
  478.         lprintf("| E Error writing output file: \"%s\"\n",outfile);
  479.         return;
  480.     }
  481.     fprintf(fptr,"; Areas.CTL - created by %-15s v%-5s\n",prgname,version);
  482.     fprintf(fptr,";             By Russel Miranda\n");
  483.     fprintf(fptr,";             Another utilility for Paragon BBS\n");
  484.     fprintf(fptr,";\n");
  485.     while(cur)
  486.     {
  487.         fprintf(fptr,";---Tag Name: %s\n",cur->areatag);
  488.         fprintf(fptr,"AREA %d\n",cur->areanum);
  489.         curadd=cur->firstnode;
  490.         while(curadd)
  491.         {
  492.             fprintf(fptr,"%d/%d\n",curadd->net,curadd->node);
  493.             curadd=curadd->nextnode;
  494.         }
  495.         cur=cur->next;
  496.     }
  497.     fclose(fptr);
  498. }
  499.  
  500. /*-                                       -*\
  501.  * FindAreaT() - Returns a pointer to the area with tag <match>        *
  502. \*-                                       -*/
  503.  
  504. struct area *FindAreaT(char *match)
  505. {
  506.     register struct area *cur=first;
  507.     
  508.     while(cur)
  509.     {
  510.         if(!stricmp(cur->areatag,match))
  511.             return cur;
  512.         cur=cur->next;
  513.     }
  514.     return NULL;
  515. }
  516.  
  517. /*-                                       -*\
  518.  * RemoveNode() - Removes a system's address from the list attached to    *
  519. \*    the area pointed to by <from>.                    */
  520.  
  521. int RemoveNode(struct area *from,struct address *adr)
  522. {
  523.     register struct address *prev,*cur;
  524.     prev=NULL;
  525.     cur=from->firstnode;
  526.     while(cur)
  527.     {
  528.         if(!cmpnode(cur,adr))
  529.         {
  530.             if(!prev)
  531.                 from->firstnode=cur->nextnode;
  532.             else
  533.                 prev->nextnode=cur->nextnode;
  534.             free(cur);
  535.             return 1;
  536.         }
  537.         prev=cur;
  538.         cur=cur->nextnode;
  539.     }
  540.     return 0;
  541. }
  542.  
  543. /*-                                       -*\
  544.  * FindNode() - Looks for the system pointed to by <match> in the list    *
  545. \*-    attached to the area pointed to by <where>.               -*/
  546.  
  547. struct address *FindNode(struct area *where,struct address *match)
  548. {
  549.     register struct address *curadr=where->firstnode;
  550.     
  551.     while(curadr)
  552.     {
  553.         if(!cmpnode(curadr,match))
  554.             return curadr;
  555.         curadr=curadr->nextnode;
  556.     }
  557.     return NULL;
  558. }
  559.  
  560. /*-                                       -*\
  561.  * cmpnode() - Compares two addresses, returns a 0 if they are the same    *
  562. \*-    or a 1 if they are different                       -*/
  563.  
  564. int cmpnode(struct address *one,struct address *two)
  565. {
  566.     if(one->net!=two->net)
  567.         return 1;
  568.     if(one->node!=two->node)
  569.         return 1;
  570.     return 0;
  571. }
  572.  
  573. /*-                                       -*\
  574.  * AvailAreas() - Outputs a query list for <adr> into the file <file>    *
  575. \*-                                       -*/
  576.  
  577. void AvailAreas(FILE *file,struct address *adr)
  578. {
  579.     struct area *cur=first;
  580.     char stat;
  581.     
  582.     fprintf(file,"\r\nAreas available to (%d/%d) from (%d/%d):\r\n",adr->net,adr->node,bbsconfig->net,bbsconfig->node);
  583.     while(cur)
  584.     {
  585.         if(FindNode(cur,adr))
  586.         {
  587.             stat='*';
  588.         }
  589.         else
  590.         {
  591.             if(GoodLevel(adr,cur->areatag))
  592.             {
  593.                 stat=' ';
  594.             }
  595.             else
  596.             {
  597.                 cur=cur->next;
  598.                 continue;
  599.             }
  600.         }
  601.         if(strnicmp(bbsconfig->msgname[cur->areanum-1],"NEW_",4))
  602.             fprintf(file," %c %-16s - %s\r\n",stat,cur->areatag,bbsconfig->msgname[cur->areanum-1]);
  603.         else
  604.             fprintf(file," %c %-16s - <New Area>\r\n",stat,cur->areatag);
  605.         cur=cur->next;
  606.     }
  607.     fprintf(file,"\r\nNote: '*' denotes area you are connected to.\r\n");
  608. }
  609.  
  610. /*-                                       -*\
  611.  * ActiveAreas() - Outputs a list of areas that <adr> is connected to    *
  612. \*-                                       -*/
  613.  
  614. void ActiveAreas(FILE *file,struct address *adr)
  615. {
  616.     register struct area *cur=first;
  617.     int total=0;
  618.     char feed;
  619.     
  620.     fprintf(file,"\r\nActive areas on (%d/%d):\r\n",adr->net,adr->node);
  621.     while(cur)
  622.     {
  623.         if(FindNode(cur,adr))
  624.         {
  625.             if(!cmpnode(cur->firstnode,adr))
  626.                 feed='*';
  627.             else
  628.                 feed=' ';
  629.             fprintf(file," %c %s\r\n",feed,cur->areatag);
  630.             total++;
  631.         }
  632.         cur=cur->next;
  633.     }
  634.     if(!total)
  635.         fprintf(file,"\r\nNone\r\n");
  636.     else
  637.         fprintf(file,"\r\nTotal: %d\r\n",total);
  638.     fprintf(file,"Note: '*' indicates you are the feed for this echo.\r\n");
  639. }
  640.  
  641. /*-                                       -*\
  642.  * MessageOpen() - Opens a private message to <to> on <dest> with the    *
  643.  *    subject <subject>.  You must keep track of the name, which is    *
  644. \*-    placed into the string you point to with <MsgName>.           -*/
  645.  
  646. FILE *MessageOpen(struct address *dest,char *to,char *from,int area,char *subject,char *MsgName)
  647. {
  648.     struct msg msgheader={0};
  649.     FILE *msgptr;
  650.     static char number;
  651.     number++;
  652.     sprintf(filename,"%s%x%d-Tmp.AFX",bbsconfig->msgpath[area],mytask,number);
  653.     strcpy(MsgName,filename);
  654.     if(!(msgptr=fopen(filename,"w")))
  655.     {
  656.         printf("Error opening message.\n");
  657.         lprintf("| E Error opening message.\n");
  658.         EXit(10);
  659.     }
  660.     TimeStr(msgheader.datetime);
  661.     strcpy(msgheader.fromuser,from);
  662.     strcpy(msgheader.touser,to);
  663.     strcpy(msgheader.subject,subject);
  664.     msgheader.desnode=dest->node;
  665.     msgheader.desnet=dest->net;
  666.     msgheader.orignode=bbsconfig->node;
  667.     msgheader.orignet=bbsconfig->net;
  668.     msgheader.private=1;
  669.     msgheader.fileupreq=1;
  670.     fwrite((char *)&msgheader,sizeof(struct msg)-2,1,msgptr);
  671.     return msgptr;
  672. }
  673.  
  674. /*-                                       -*\
  675.  * MessageClose() - closes the message <file> (in <area>) with the    *
  676. \*-    name <MsgName>.  Turns this temp file into a new message.      -*/
  677.  
  678. void MessageClose(FILE *file,int area,char *MsgName)
  679. {
  680.     int msgnum;
  681.     
  682.     fprintf(file,"\r\n\r\n--- %s v%s\r\n",prgname,version);
  683.     fclose(file);
  684.     Own(area);
  685.     msgnum=++bbsconfig->himsgno[area];
  686.     bbsconfig->lomsgno[area]++;
  687.     DisOwn(area);
  688.     sprintf(filename,"%s%d.%d",bbsconfig->msgpath[area],msgnum,area+1);
  689.     rename(MsgName,filename);
  690.     sprintf(filename,"%s%d.%d",bbsconfig->msgpath[area],msgnum-(bbsconfig->msgno[area]+1),area+1);
  691.     remove(filename);
  692. }
  693.  
  694. /*-                                       -*\
  695.  * AliasAdd() - Adds an alias to the list of acceptable names        *
  696. \*-                                       -*/
  697.  
  698. void AliasAdd(char *addition)
  699. {
  700.     struct alias *new;
  701.     
  702.     if(!(new=calloc(1,sizeof(struct alias))))
  703.         NoMem();
  704.     strcpy(new->name,addition);
  705.     if(!falias)
  706.         falias=new;
  707.     else
  708.         lalias->nextalias=new;
  709.     lalias=new;
  710. }
  711.  
  712. /*-                                       -*\
  713.  * PassAdd() - Adds a password to the list of passwords for the system    *
  714. \*-    pointed to by <add>, and gives this system security <level>.   -*/
  715.  
  716. void PassAdd(struct address *add,char *text,short level)
  717. {
  718.     struct pass *new;
  719.     
  720.     if(!(new=calloc(1,sizeof(struct pass))))
  721.         NoMem();
  722.     strcpy(new->pass,text);
  723.     new->level=level;
  724.     new->adr=*add;
  725.     if(!fpass)
  726.         fpass=new;
  727.     else
  728.         lpass->nextpass=new;
  729.     lpass=new;
  730. }
  731.  
  732. /*-                                       -*\
  733.  * PassMatch() - Checks to see if <password> matches the password set    *
  734. \*-    up for system <where>.                           -*/
  735.  
  736. int PassMatch(struct address *where,char *password)
  737. {
  738.     register struct pass *cur=fpass;
  739.     
  740.     while(cur)
  741.     {
  742.         if(!cmpnode(where,&cur->adr))
  743.         {
  744.             if(!stricmp(cur->pass,password))
  745.                 return 1;
  746.             return 0;
  747.         }
  748.         cur=cur->nextpass;
  749.     }
  750.     return 0;
  751. }
  752.  
  753. /*-                                       -*\
  754.  * AliasMatch() - Checks to see if <match> is an acceptable name for    *
  755. \*-    a message addressed to AreaFix.                       -*/
  756.  
  757. int AliasMatch(char *match)
  758. {
  759.     register struct alias *cur=falias;
  760.     
  761.     while(cur)
  762.     {
  763.         if(!stricmp(match,cur->name))
  764.             return 1;
  765.         cur=cur->nextalias;
  766.     }
  767.     return 0;
  768. }
  769.  
  770. /*-                                       -*\
  771.  * ProtAdd() - Adds a protection level for the echo <tag>        *
  772. \*-                                       -*/
  773.  
  774. void ProtAdd(char *tag,short level)
  775. {
  776.     struct protect *new;
  777.     
  778.     if(!(new=calloc(1,sizeof(struct protect))))
  779.         NoMem();
  780.     strcpy(new->tag,tag);
  781.     new->level=level;
  782.     if(!fprot)
  783.         fprot=new;
  784.     else
  785.         lprot->nextprot=new;
  786.     lprot=new;
  787. }
  788.  
  789. /*-                                       -*\
  790.  * FindProt - Finds the protection level for the echo area <tag>.    *
  791. \*-                                       -*/
  792.  
  793. int FindProt(char *tag)
  794. {
  795.     register struct protect *cur=fprot;
  796.     
  797.     while(cur)
  798.     {
  799.         if(!stricmp(tag,cur->tag))
  800.             return (long)(cur->level);
  801.         cur=cur->nextprot;
  802.     }
  803.     return 0;
  804. }
  805.  
  806. /*-                                       -*\
  807.  * SecLevel() - Returns the security level for the system <where>.    *
  808. \*-                                       -*/
  809.  
  810. int SecLevel(struct address *where)
  811. {
  812.     register struct pass *cur=fpass;
  813.     
  814.     while(cur)
  815.     {
  816.         if(!cmpnode(&cur->adr,where))
  817.             return (long)(cur->level);
  818.         cur=cur->nextpass;
  819.     }
  820.     return 0;
  821. }
  822.  
  823. /*-                                       -*\
  824.  * GoodLevel() - Checks to see if <where> has enough security to add    *
  825. \*-    the echo <tag>.                               -*/
  826.  
  827. int GoodLevel(struct address *where,char *tag)
  828. {
  829.     short area,node;
  830.     
  831.     node=SecLevel(where);
  832.     area=FindProt(tag);
  833.     
  834.     if(node>=area)
  835.         return 1;
  836.     return 0;
  837. }
  838.  
  839. /*-                                       -*\
  840.  * SyntaxEr() - reports a syntax error in the parsing of a text file.    *
  841. \*-                                       -*/
  842.  
  843. void SyntaxEr(char *err)
  844. {
  845.     lprintf("| < Syntax error in AreaFix.CFG: %s\n",err);
  846.     printf("Syntax error in AreaFix.CFG:\n\"%s\"\n",err);
  847.     printf("Skipping entry.\n");
  848. }
  849.  
  850. /*-                                       -*\
  851.  * lprintf() - prints line out to log file.                *
  852. \*-                                       -*/
  853.  
  854. void lprintf(char *fmt, ...)
  855. {
  856.     va_list ap;
  857.     char *p,*sval;
  858.     int ival;
  859.     FILE *log;
  860.     
  861.     sprintf(filename,"%sAreaFix.LOG",bbspath);
  862.     if(!(log=fopen(filename,"a")))
  863.     {
  864.         printf("Error opening logfile!\n");
  865.         printf("Aborting!!!\n");
  866.         EXit(10);
  867.     }
  868.     
  869.     va_start(ap, fmt);
  870.     for(p = fmt; *p; p++)
  871.     {
  872.         if(*p != '%')
  873.         {
  874.             fputc(*p,log);
  875.             continue;
  876.         }
  877.         switch(*++p)
  878.         {
  879.             case 'd':
  880.                 ival=va_arg(ap,int);
  881.                 fprintf(log,"%d",ival);
  882.                 break;
  883.             case 's':
  884.                 for(sval=va_arg(ap,char *); *sval; sval++)
  885.                     fputc(*sval,log);
  886.                 break;
  887.             default:
  888.                 fputc(*p,log);
  889.                 break;
  890.         }
  891.     }
  892.     fclose(log);
  893.     va_end(ap);
  894. }
  895.  
  896. /*-                                       -*\
  897.  * TimeStr() - places the standard time string for messages into <str>    *
  898. \*-                                       -*/
  899.  
  900. void TimeStr(char *str)
  901. {
  902.     unsigned long t;
  903.     char work[26];
  904.     
  905.     time(&t);
  906.     strcpy(work,ctime(&t));
  907.     
  908.     work[7]=0;
  909.     work[10]=0;
  910.     work[19]=0;
  911.     work[24]=0;
  912.     sprintf(str,"%s %s %s %s",&work[8],&work[4],&work[22],&work[11]);
  913. }
  914.  
  915. /*-                                       -*\
  916.  * ReScan() - Forces <Area> to be rescanned.                *
  917. \*-                                       -*/
  918.  
  919. void ReScan(struct area *Area)
  920. {
  921.     bbsconfig->himsgsent[Area->areanum-1]=bbsconfig->lomsgno[Area->areanum-1];
  922. }
  923.  
  924. /*-                                       -*\
  925.  * List() - Sends the file AvailAreas.TXT to <dest> in a message.    *
  926. \*-                                       -*/
  927.  
  928. void List(struct address *dest,int area)
  929. {
  930.     FILE *listmsg;
  931.     FILE *source;
  932.     int ret;
  933.     char tmpname[256];
  934.     
  935.     if(!(listmsg=MessageOpen(dest,"Sysop",prgname,area,"Available areas list",tmpname)))
  936.     {
  937.         lprintf("| < No list sent.\n");
  938.         return;
  939.     }
  940.     sprintf(filename,"%sAvailAreas.TXT",bbspath);
  941.     if(!(source=fopen(filename,"r")))
  942.     {
  943.         MessageClose(listmsg,area,tmpname);
  944.         lprintf("| < AvailAreas.TXT could not be opened.\n");
  945.         return;
  946.     }
  947.     while((ret=fgetc(source))!=EOF)
  948.     {
  949.         switch(ret)
  950.         {
  951.             case '\n':
  952.                 fputc('\r',listmsg);
  953.             default:
  954.                 fputc(ret,listmsg);
  955.         }
  956.     }
  957.     fclose(source);
  958.     MessageClose(listmsg,area,tmpname);
  959. }
  960.  
  961. /*-                                       -*\
  962.  * EXit() - Sets the task name to the old name, and then exits        *
  963. \*-                                       -*/
  964.  
  965. void EXit(int level)
  966. {
  967.     mytask->tc_Node.ln_Name = oldname;
  968.     exit(level);
  969. }
  970.  
  971. /*-                                       -*\
  972.  * validarea() - checks to see if <number> is an OK echomail base    *
  973. \*-                                       -*/
  974.  
  975. int validarea(int number)
  976. {
  977.     if(strlen(bbsconfig->tagname[number-1])<2)
  978.         return 0;
  979.     if(strlen(bbsconfig->msgname[number-1])<2)
  980.         return 0;
  981.     if(bbsconfig->msglevel[number-1]>15)
  982.         return 0;
  983.     return 1;
  984. }
  985.  
  986. /*-                                       -*\
  987.  * NoMem() - When AreaFix can't allocate memory, it notes it in the log    *
  988. \*-    and exits.                               -*/
  989.  
  990. void NoMem(void)
  991. {
  992.     printf("Error allocating memory.\n");
  993.     lprintf("| E Error allocating memory.\n");
  994.     lprintf("*-- Operation aborted.\n");
  995.     EXit(10);
  996. }
  997.  
  998. /*-                                       -*\
  999.  * AddFwd() - Adds forward request for sending out later.        *
  1000. \*-                                       -*/
  1001.  
  1002. void AddFwd(char *tag,struct address *from,char *pswd)
  1003. {
  1004.     struct fwdsys *curFS=firstFS;
  1005.     
  1006.     while(curFS)
  1007.     {
  1008.         if(!cmpnode(&curFS->adr,from))
  1009.         {
  1010.             AddFwdArea(curFS,tag);
  1011.             return;
  1012.         }
  1013.         curFS=curFS->next;
  1014.     }
  1015.     if(curFS=calloc(1,sizeof(struct fwdsys)))
  1016.     {
  1017.         if(firstFS)
  1018.             lastFS->next=curFS;
  1019.         else
  1020.             firstFS=curFS;
  1021.         lastFS=curFS;
  1022.         lastFS->next=NULL;
  1023.         curFS->adr=*from;
  1024.         strcpy(curFS->password,pswd);
  1025.         AddFwdArea(curFS,tag);
  1026.         return;
  1027.     }
  1028.     NoMem();
  1029. }
  1030.  
  1031. /*-                                       -*\
  1032.  * AddFwdArea() - Adds area to list of areas being requested from a    *
  1033. \*-    system.                                   -*/
  1034.  
  1035. void AddFwdArea(struct fwdsys *system,char *tag)
  1036. {
  1037.     struct fwdarea *newfwd;
  1038.     
  1039.     if(newfwd=calloc(1,sizeof(struct fwdarea)))
  1040.     {
  1041.         if(system->firstarea)
  1042.             system->lastarea->next=newfwd;
  1043.         else
  1044.             system->firstarea=newfwd;
  1045.         system->lastarea=newfwd;
  1046.         system->lastarea->next=NULL;
  1047.         strcpy(newfwd->tag,tag);
  1048.         return;
  1049.     }
  1050.     NoMem();
  1051. }
  1052.  
  1053. /*-                                       -*\
  1054.  * SendFwd() - Sends out all the requests that are to be forwarded.    *
  1055. \*-                                       -*/
  1056.  
  1057. void SendFwd(int area)
  1058. {
  1059.     FILE *file;
  1060.     char tmpname[256];
  1061.     struct fwdsys *curFS=firstFS;
  1062.     struct fwdarea *curFA;
  1063.     
  1064.     while(curFS)
  1065.     {
  1066.         file=MessageOpen(&curFS->adr,"Areafix","(Auto request) Areafix",area,curFS->password,tmpname);
  1067.         {
  1068.             curFA=curFS->firstarea;
  1069.             while(curFA)
  1070.             {
  1071.                 fprintf(file,"%s\r\n",curFA->tag);
  1072.                 curFA=curFA->next;
  1073.             }
  1074.             MessageClose(file,area,tmpname);
  1075.         }
  1076.         curFS=curFS->next;
  1077.     }
  1078. }
  1079.  
  1080. /*-                                       -*\
  1081.  * AvailFrom() - finds if area <tag> is available for requesting, and    *
  1082. \*-    if so, from where, and what is the password for that system.   -*/
  1083.  
  1084. int AvailFrom(struct address *where,char *tag,char *pass)
  1085. {
  1086.     char buffer[256];
  1087.     char *pswd;
  1088.     char *node;
  1089.     char *net;
  1090.     FILE *file;
  1091.     
  1092.     sprintf(filename,"%sEchoReq.LST",bbspath);
  1093.     if(file=fopen(filename,"r"))
  1094.     {
  1095.         while(GetLine(file,buffer))
  1096.         {
  1097.             if(!strnicmp(buffer,"#SYSTEM",7))
  1098.             {
  1099.                 net=stpblk(&buffer[7]);
  1100.                 node=strchr(net,'/');
  1101.                 pswd=strchr(node,' ');
  1102.                 pswd++;
  1103.                 if((*net)&&(node))
  1104.                 {
  1105.                     *node=0;
  1106.                     node++;
  1107.                     where->net=atoi(net);
  1108.                     where->node=atoi(node);
  1109.                 }
  1110.                 strcpy(pass,pswd);
  1111.                 continue;
  1112.             }
  1113.             if(where->net)
  1114.             {
  1115.                 if(!stricmp(buffer,tag))
  1116.                 {
  1117.                     fclose(file);
  1118.                     return 1;
  1119.                 }
  1120.             }
  1121.         }
  1122.     }
  1123.     return 0;
  1124. }
  1125.  
  1126. /*-                                       -*\
  1127.  * BuildReqLst() - Reads in the current QUE file, and builds the list    *
  1128. \*-    of requests in memory.                           -*/
  1129.  
  1130. void BuildReqLst(void)
  1131. {
  1132.     char buffer[256];
  1133.     char *token;
  1134.     char *endtoken;
  1135.     char *nodeptr;
  1136.     FILE *file;
  1137.     struct request *area;
  1138.     int net,node;
  1139.     
  1140.     sprintf(filename,"%sAreaFix.QUE",bbspath);
  1141.     if(file=fopen(filename,"r"))
  1142.     {
  1143.         while(GetLine(file,buffer))
  1144.         {
  1145.             endtoken=strchr(buffer,' ');
  1146.             if(endtoken)
  1147.             {
  1148.                 *endtoken=0;
  1149.                 token=endtoken;
  1150.                 area=AddQueArea(buffer);
  1151.                 do
  1152.                 {
  1153.                     token++;
  1154.                     token=stpblk(token);
  1155.                     endtoken=strchr(token,' ');
  1156.                     if(endtoken)
  1157.                         *endtoken=0;
  1158.                     nodeptr=strchr(token,'/');
  1159.                     *nodeptr=0;
  1160.                     nodeptr++;
  1161.                     net=atoi(token);
  1162.                     node=atoi(nodeptr);
  1163.                     AddQue(area,net,node);
  1164.                     token=endtoken;
  1165.                 } while(endtoken);
  1166.             }
  1167.         }
  1168.         fclose(file);
  1169.     }
  1170. }
  1171.  
  1172. /*-                                       -*\
  1173.  * AddQue() - Adds a request for the area described by <to>        *
  1174. \*-                                       -*/
  1175.  
  1176. void AddQue(struct request *to, int net, int node)
  1177. {
  1178.     struct address *newadr;
  1179.     
  1180.     if(newadr=calloc(1,sizeof(struct address)))
  1181.     {
  1182.         newadr->net=(short)net;
  1183.         newadr->node=(short)node;
  1184.         if(to->firstadr)
  1185.             to->lastadr->nextnode=newadr;
  1186.         else
  1187.             to->firstadr=newadr;
  1188.         to->lastadr=newadr;
  1189.         to->lastadr->nextnode=NULL;
  1190.         return;
  1191.     }
  1192.     NoMem();
  1193. }
  1194.  
  1195. /*-                                       -*\
  1196.  * AddQueArea() - Adds new que area for <tag>.                *
  1197. \*-                                       -*/
  1198.  
  1199. struct request *AddQueArea(char *tag)
  1200. {
  1201.     struct request *newreq;
  1202.     if(newreq=calloc(1,sizeof(struct request)))
  1203.     {
  1204.         if(firstreq)
  1205.             lastreq->next=newreq;
  1206.         else
  1207.             firstreq=newreq;
  1208.         lastreq=newreq;
  1209.         lastreq->next=NULL;
  1210.         strcpy(newreq->tag,tag);
  1211.         return newreq;
  1212.     }
  1213.     NoMem();
  1214. }
  1215.  
  1216. /*-                                       -*\
  1217.  * AddReq() - Handles adding a system to the que, for the echo named    *
  1218.  *    <tag>, from the system <source>.  Will add address on end if    *
  1219. \*-    previously requested by another, or will create new line.      -*/
  1220.  
  1221. int AddReq(char *tag, struct address *source, struct address *dest)
  1222. {
  1223.     struct request *curR=firstreq;
  1224.     struct request *newreq;
  1225.     
  1226.     while(curR)
  1227.     {
  1228.         if(!stricmp(curR->tag,tag))
  1229.         {
  1230.             AddQue(curR,dest->net,dest->node);
  1231.             return 0;
  1232.         }
  1233.         curR=curR->next;
  1234.     }
  1235.     newreq=AddQueArea(tag);
  1236.     AddQue(newreq,source->net,source->node);
  1237.     AddQue(newreq,dest->net,dest->node);
  1238.     return 1;
  1239. }
  1240.     
  1241. /*-                                       -*\
  1242.  * ProcQue() - Processes que, and adds lines to AREAS.CTL if an area    *
  1243.  *    that was previously requested is found.  (usually because it    *
  1244. \*-    created by MailProc)                           -*/
  1245.  
  1246. void ProcQue(char *change,int search)
  1247. {
  1248.     struct area *cur;
  1249.     struct request *curR=firstreq;
  1250.     struct request *prevR=NULL;
  1251.     int count,cnt;
  1252.     struct address *curA,*tempA;
  1253.     FILE *notify;
  1254.     char tempnme[256];
  1255.     
  1256.     if(curR)
  1257.     {
  1258.         lprintf("| * Processing request que:\n");
  1259.         
  1260.         while(curR)
  1261.         {
  1262.             for(count=0;count<MAXMSGBASE;count++)
  1263.             {
  1264.                 if(!stricmp(curR->tag,bbsconfig->tagname[count]))
  1265.                     break;
  1266.             }
  1267.             if(count!=MAXMSGBASE)
  1268.             {
  1269.                 *change=TRUE;
  1270.                 if(!(cur=FindAreaT(curR->tag)))
  1271.                     cur=AreaAdd((short)(count+1));
  1272.                 curA=curR->firstadr;
  1273.                 while(curA)
  1274.                 {
  1275.                     if(!FindNode(cur,curA))
  1276.                     {
  1277.                         lprintf("| | Added system (%d/%d) to echo \"%s\"\n",curA->net,curA->node,curR->tag);
  1278.                         NodeAdd(cur,curA);
  1279.                         notify=MessageOpen(curA,"Sysop",prgname,search,"Previously requested areas",tempnme);
  1280.                         fprintf(notify,"The following previously requested area is now available.\r\n");
  1281.                         fprintf(notify,"-------------------------------  -------------------------------\r\n");
  1282.                         fprintf(notify,"%s ",curR->tag);
  1283.                         for(cnt=strlen(curR->tag);cnt<=29;cnt++)
  1284.                             fputc('.',notify);
  1285.                         fprintf(notify,"  Added area.\r\n");
  1286.                         MessageClose(notify,search,tempnme);
  1287.                     }
  1288.                     tempA=curA;
  1289.                     curA=curA->nextnode;
  1290.                     free(tempA);
  1291.                 }
  1292.                 if(prevR)
  1293.                 {
  1294.                     prevR->next=curR->next;
  1295.                     free(curR);
  1296.                     curR=prevR->next;
  1297.                     continue;
  1298.                 }
  1299.                 else
  1300.                 {
  1301.                     firstreq=curR->next;
  1302.                     free(curR);
  1303.                     curR=firstreq;
  1304.                     continue;
  1305.                 }
  1306.                 break;
  1307.             }
  1308.             prevR=curR;
  1309.             curR=curR->next;
  1310.         }
  1311.         lprintf("| * Finished processing request que.\n");
  1312.     }
  1313. }
  1314.  
  1315. /*-                                       -*\
  1316.  * SaveQue() - Saves the AreaFix.QUE file, if there are any que entries    *
  1317. \*-    that have not been removed.                       -*/
  1318.  
  1319. void SaveQue(void)
  1320. {
  1321.     struct request *curR=firstreq;
  1322.     struct address *curA;
  1323.     FILE *file;
  1324.     
  1325.     sprintf(filename,"%sAreaFix.QUE",bbspath);
  1326.     if(firstreq)
  1327.     {
  1328.         if(file=fopen(filename,"w"))
  1329.         {
  1330.             while(curR)
  1331.             {
  1332.                 fprintf(file,"%s",curR->tag);
  1333.                 curA=curR->firstadr;
  1334.                 while(curA)
  1335.                 {
  1336.                     fprintf(file," %d/%d",curA->net,curA->node);
  1337.                     curA=curA->nextnode;
  1338.                 }
  1339.                 fprintf(file,"\n");
  1340.                 curR=curR->next;
  1341.             }
  1342.             fclose(file);
  1343.         }
  1344.         return;
  1345.     }
  1346.     remove(filename);
  1347. }
  1348.  
  1349. /*-                                       -*\
  1350.  * InputAreas() - Reads the areas.ctl file, and builds the list of echo *
  1351. \*-    areas & the systems they are connected to.               -*/
  1352.  
  1353. void InputAreas(char *change,char *in)
  1354. {
  1355.     FILE *fptr;
  1356.     char buffer[256];
  1357.     char *temp,*node;
  1358.     short number;
  1359.     struct area *cur;
  1360.     struct address newadr;
  1361.     
  1362.     if(fptr=fopen(in,"r"))
  1363.     {
  1364.         while(GetLine(fptr,buffer))
  1365.         {
  1366.             if(!strnicmp(buffer,"AREA",4))
  1367.             {
  1368.                 temp=stpblk(&buffer[4]);
  1369.                 number=(short)atoi(temp);
  1370.                 if(!validarea(number))
  1371.                 {
  1372.                     cur=NULL;
  1373.                     lprintf("| < Area %d is not a valid EchoMail message base. Skipped.\n",number);
  1374.                     printf("Area %d is not a valid EchoMail message base.\n",number);
  1375.                     *change=TRUE;
  1376.                     continue;
  1377.                 }
  1378.                 cur=AreaAdd(number);
  1379.                 continue;
  1380.             }
  1381.             if(!cur)
  1382.             {
  1383.                 printf("\n");
  1384.                 lprintf("| < No valid area specified for address (%s). Skipped entry.\n",buffer);
  1385.                 printf("No valid area specified for address \"%s\".  Skipped.\n",buffer);
  1386.                 *change=TRUE;
  1387.                 continue;
  1388.             }
  1389.             node=strchr(buffer,'/');
  1390.             *node=0;
  1391.             node++;
  1392.             newadr.net=atoi(buffer);
  1393.             newadr.node=atoi(node);
  1394.             newadr.zone=0;
  1395.             NodeAdd(cur,&newadr);
  1396.         }
  1397.         fclose(fptr);
  1398.     }
  1399.     else
  1400.     {
  1401.         printf("Error!\n");
  1402.         lprintf("| E Error opening areas file \"%s\".\n",in);
  1403.         lprintf("*-- Operation aborted.\n");
  1404.         EXit(10);
  1405.     }
  1406. }
  1407.  
  1408. /*-                                       -*\
  1409.  * ReadCfg() - Reads the config file, and builds the alias, protection,    *
  1410.  *    and password lists - along with setting the search base and    *
  1411.  *    protection on forwarding.                    *
  1412. \*-                                       -*/
  1413.  
  1414. void ReadCfg(char *cfgname, char *in, char *out, int *forward, int *search)
  1415. {
  1416.     char buffer[256];
  1417.     char *temp,*level,*net,*node,*passwd;
  1418.     FILE *fptr;
  1419.     struct address newadr;
  1420.     
  1421.     if(fptr=fopen(cfgname,"r"))
  1422.     {
  1423.         AliasAdd("Areafix");
  1424.         while(GetLine(fptr,buffer))
  1425.         {
  1426.             if(!strnicmp(buffer,"ALIAS",5))
  1427.             {
  1428.                 temp=stpblk(&buffer[5]);
  1429.                 if(!strlen(temp))
  1430.                 {
  1431.                     lprintf("| < Missing alias name in AreaFix.CFG: %s\n",buffer);
  1432.                     printf("Missing alias name in AreaFix.CFG:\n\"%s\"\n",buffer);
  1433.                     printf("Skipping entry.\n");
  1434.                     continue;
  1435.                 }
  1436.                 AliasAdd(temp);
  1437.                 continue;
  1438.             }
  1439.             if(!strnicmp(buffer,"PROTECT",7))
  1440.             {
  1441.                 temp=stpblk(&buffer[7]);
  1442.                 if(!strlen(temp))
  1443.                 {
  1444.                     SyntaxEr(buffer);
  1445.                     continue;
  1446.                 }
  1447.                 if(!(level=strchr(temp,' ')))
  1448.                 {
  1449.                     SyntaxEr(buffer);
  1450.                     continue;
  1451.                 }
  1452.                 *level=0;
  1453.                 level++;
  1454.                 level=stpblk(level);
  1455.                 if(!strlen(level))
  1456.                 {
  1457.                     SyntaxEr(buffer);
  1458.                     continue;
  1459.                 }
  1460.                 ProtAdd(temp,(short)atoi(level));
  1461.             }
  1462.             if(!strnicmp(buffer,"PASS",4))
  1463.             {
  1464.                 net=stpblk(&buffer[4]);
  1465.                 if(!(node=strchr(net,'/')))
  1466.                 {
  1467.                     SyntaxEr(buffer);
  1468.                     continue;
  1469.                 }
  1470.                 *node=0;
  1471.                 node++;
  1472.                 if(!(passwd=strchr(node,' ')))
  1473.                 {
  1474.                     SyntaxEr(buffer);
  1475.                     continue;
  1476.                 }
  1477.                 *passwd=0;
  1478.                 passwd++;
  1479.                 if(!(level=strchr(passwd,' ')))
  1480.                 {
  1481.                     SyntaxEr(buffer);
  1482.                     continue;
  1483.                 }
  1484.                 *level=0;
  1485.                 level++;
  1486.                 newadr.net=atoi(net);
  1487.                 newadr.node=atoi(node);
  1488.                 newadr.zone=0;
  1489.                 PassAdd(&newadr,passwd,(short)atoi(level));
  1490.                 continue;
  1491.             }
  1492.             if(!strnicmp(buffer,"INPUT",5))
  1493.             {
  1494.                 temp=stpblk(&buffer[5]);
  1495.                 strcpy(in,temp);
  1496.                 continue;
  1497.             }
  1498.             if(!strnicmp(buffer,"OUTPUT",6))
  1499.             {
  1500.                 temp=stpblk(&buffer[6]);
  1501.                 strcpy(out,temp);
  1502.                 continue;
  1503.             }
  1504.             if(!strnicmp(buffer,"FORWARD",7))
  1505.             {
  1506.                 temp=stpblk(&buffer[7]);
  1507.                 *forward=atoi(temp);
  1508.                 continue;
  1509.             }
  1510.             if(!strnicmp(buffer,"SEARCH",6))
  1511.             {
  1512.                 temp=stpblk(&buffer[6]);
  1513.                 *search=atoi(temp)-1;
  1514.                 if((*search<0)||(*search>=MAXMSGBASE))
  1515.                 {
  1516.                     lprintf("| E Search base is out of range.\n");
  1517.                     lprintf("*-- Operation aborted.\n");
  1518.                     printf("Search base is out of range.\n");
  1519.                     EXit(10);
  1520.                 }
  1521.                 if(bbsconfig->msglevel[*search]>16)
  1522.                 {
  1523.                     lprintf("| E Search base access level out of range.\n");
  1524.                     lprintf("*-- Operation aborted.\n");
  1525.                     printf("Search base access level is out of range.\n");
  1526.                     EXit(10);
  1527.                 }
  1528.                 if(bbsconfig->basetype[*search]!=2)
  1529.                 {
  1530.                     lprintf("| E Search base is not of type NetMail.\n");
  1531.                     lprintf("*-- Operation aborted.\n");
  1532.                     printf("Search base is not of type NetMail.\n");
  1533.                     EXit(10);
  1534.                 }
  1535.                 if(stricmp(bbsconfig->tagname[*search],"MATRIX"))
  1536.                 {
  1537.                     lprintf("| E Search base has incorrect tag name.\n");
  1538.                     lprintf("*-- Operation aborted.\n");
  1539.                     printf("Search base has incorrect tag name.\n");
  1540.                     EXit(10);
  1541.                 }
  1542.                 continue;
  1543.             }
  1544.         }
  1545.         if(!(*search))
  1546.         {
  1547.             lprintf("| E Search base not defined.\n");
  1548.             lprintf("*-- Operation aborted.\n");
  1549.             printf("Search base not defined.\n");
  1550.             EXit(10);
  1551.         }
  1552.         fclose(fptr);
  1553.     }
  1554.     else
  1555.     {
  1556.         lprintf("| E Error reading %s\n",cfgname);
  1557.         lprintf("*-- Operation aborted.\n");
  1558.         printf("Error reading %s\n",cfgname);
  1559.         EXit(10);
  1560.     }
  1561. }
  1562.  
  1563. /*-                                       -*\
  1564.  * GetHiMk() - Gets the "High Water Mark" for a certain message base.    *
  1565.  *    This is typically the last message AreaFix read from this base,    *
  1566.  *    unless the search base area is not the same area as the last    *
  1567.  *    time, in which case it returns the lowest message number in    *
  1568. \*-    that base.                               -*/
  1569.  
  1570. short GetHiMk(short search)
  1571. {
  1572.     FILE *fptr;
  1573.     struct himark hmk;
  1574.     short highpt;
  1575.     
  1576.     sprintf(filename,"%sAreaFix.HPT",bbspath);
  1577.     if(fptr=fopen(filename,"r"))
  1578.     {
  1579.         fread((void *)&hmk,sizeof(struct himark),1,fptr);
  1580.         if(!strncmp(hmk.version,hiptver,strlen(hiptver)))
  1581.         {
  1582.             fclose(fptr);
  1583.             if(hmk.basenumber==search)
  1584.             {
  1585.                 return hmk.highmsg;
  1586.             }
  1587.             else
  1588.             {
  1589.                 lprintf("| < High-watermark is for area %d - Discarding & scanning from beginning.\n",hmk.basenumber+1);
  1590.                 return bbsconfig->lomsgno[search];
  1591.             }
  1592.         }
  1593.         lprintf("| < Old version HiMark, updating to v%s\n",version);
  1594.         fseek(fptr,(search*sizeof(short)),0);
  1595.         fread((void *)&highpt,sizeof(short),1,fptr);
  1596.         fclose(fptr);
  1597.         return highpt;
  1598.     }
  1599.     else
  1600.     {
  1601.         lprintf("| < AreaFix.HPT couldn't be opened.  Scanning from beginning.\n");
  1602.         printf("\nHighpoint file couldn't be opened!\n");
  1603.         printf("Assuming low message is highpoint of previous scan.\n");
  1604.         return bbsconfig->lomsgno[search];
  1605.     }
  1606. }
  1607.  
  1608. /*-                                       -*\
  1609.  * SaveHiMk() - Saves the "High Water Mark" for the search base, along    *
  1610.  *    with the number of the search base, and the version of the    *
  1611. \*-    mark, just incase I someday decide to store more in there.     -*/
  1612.  
  1613. void SaveHiMk(short search,short point)
  1614. {
  1615.     struct himark hpt;
  1616.     FILE *fptr;
  1617.     
  1618.     sprintf(filename,"%sAreaFix.HPT",bbspath);
  1619.     if(fptr=fopen(filename,"w"))
  1620.     {
  1621.         hpt.basenumber=search;
  1622.         hpt.highmsg=point;
  1623.         strcpy(hpt.version,hiptver);
  1624.         fwrite((char *)&hpt,sizeof(struct himark),1,fptr);
  1625.         fclose(fptr);
  1626.     }
  1627.     else
  1628.     {
  1629.         printf("Error saving highpoint info.\n");
  1630.         lprintf("| < Error saving AreaFix.HPT\n");
  1631.     }
  1632. }
  1633.  
  1634.  
  1635. /*----------------------------------------------------------------------*
  1636.  * The End.  This program was fun to write... I had never used lists    *
  1637.  * like I did in this one, and I'd like to once again thank Thomas E.    *
  1638.  * Cotton III for sitting down one day and explaining dynamic QUE's to    *
  1639.  * me... this is an offspring of that hour at work one boring day...    *
  1640.  *----------------------------------------------------------------------*
  1641.  * If you have any questions about this source, contact me on my BBS     *
  1642.  * The Enterprise BBS (717) 588-7636, or on the Paragon Support BBS,    *
  1643.  * The Inner Circle   (508) 393-3875.  I'm usually happy to hear from    *
  1644.  * other programmers and to help them out if they need it.  On the    *
  1645.  * other hand, if you see something that should definately be fixed,    *
  1646.  * or can suggest something better for some part, I'll gladly hear your    *
  1647.  * suggestions.  This source is NOT public domain... but you can use it    *
  1648.  * or any part of it you want in any program you wish, as long as:    *
  1649.  *                                    *
  1650.  * 1) You give me credit, where it's due.  Nothing fancy...        *
  1651.  * 2) You tell me you used it, and (optional) send me a copy of the    *
  1652.  *    finished program.                            *
  1653.  *                                    *
  1654.  * I'm just curious as to what it gets used for, and (heheheh) greedy    *
  1655.  * because I want all the latest PD, ShareWare and FreeWare programs    *
  1656.  * that come out...  I can't help it!                    *
  1657.  *----------------------------------------------------------------------*/
  1658.