home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / XGRP_000.SZH / CONFIG.C < prev    next >
C/C++ Source or Header  |  1991-08-21  |  26KB  |  782 lines

  1. #include "xgroup.h"
  2.  
  3.  
  4. /* variables visible only to this module */
  5.  
  6. #define GROUPIN         1
  7. #define GROUPOUT        2
  8. #define MSGDIR          3
  9. #define ARCHIVE         4
  10. #define UNARCHIVE       5
  11. #define GROUPR          6
  12. #define PACKSIZE        7
  13. #define GROUPHOLD       8
  14. #define XBBSOS2         9
  15. #define OUTBOUND        10
  16. #define INBOUND         11
  17. #define ROUTER          12
  18. #define ANADDRESS       13
  19. #define NETAREA         14
  20. #define ECHOR           15
  21. #define NOTINY          16
  22. #define PRIORITIES      17
  23. #define NOFORWARD       18
  24. #define NOLOCALFORWARD  19
  25. #define FORWARDFILES    20
  26. #define MAXIMUMDUPES    21
  27. #define NODUPES         22
  28. #define LOGFILE         23
  29. #define KEEPPATH        24
  30. #define KEEPSEENBYS     25
  31. #define KEEPDUPES       26
  32. #define TONAME          27
  33. #define KILLBADDATES    28
  34. #define MESSAGES        29
  35. #define KEEPNOFORWARDS  30
  36. #define ALLOWBADAREAS   31
  37.  
  38. struct __keywords__ {   /* Keyword lookup table structure */
  39.     char *keyword;
  40.     char tok;
  41. };
  42. typedef struct __keywords__ KEYWORD;
  43.  
  44. static KEYWORD table[]= {   /* config verb lookup table */
  45.       "groupin",GROUPIN,
  46.       "groupout",GROUPOUT,
  47.       "msgdir",MSGDIR,
  48.       "archive",ARCHIVE,
  49.       "unarchive",UNARCHIVE,
  50.       "group",GROUPR,
  51.       "packsize",PACKSIZE,
  52.       "grouphold",GROUPHOLD,
  53.       "xbbsos2",XBBSOS2,
  54.       "outbound",OUTBOUND,
  55.       "inbound",INBOUND,
  56.       "address",ANADDRESS,
  57.       "echo",ECHOR,
  58.       "notiny",NOTINY,
  59.       "priority",PRIORITIES,
  60.       "noforward",NOFORWARD,
  61.       "nolocalforward",NOLOCALFORWARD,
  62.       "forwardfiles",FORWARDFILES,
  63.       "netarea",NETAREA,
  64.       "maxdupes",MAXIMUMDUPES,
  65.       "nodupes",NODUPES,
  66.       "logfile",LOGFILE,
  67.       "route",ROUTER,
  68.       "keeppath",KEEPPATH,
  69.       "keepseenbys",KEEPSEENBYS,
  70.       "keepdupes",KEEPDUPES,
  71.       "toname",TONAME,
  72.       "killbaddates",KILLBADDATES,
  73.       "messages",MESSAGES,
  74.       "keepnoforwards",KEEPNOFORWARDS,
  75.       "allowbadareas",ALLOWBADAREAS,
  76.       NULL,0
  77. };
  78.  
  79. /* external global variables */
  80.  
  81. char machstate;
  82.  
  83. /* Global variables created in this module */
  84.  
  85. char     *groupin       = NULL;   /* groupmail inbound dir */
  86. char     *groupout      = NULL;   /* groupmail outbound dir */
  87. char     *grouphold     = NULL;   /* groupmail hold dir */
  88. char     *msgdir        = NULL;   /* xbbs msg dir */
  89. char     *outbound      = NULL;   /* bink-style outbound dir */
  90. char     *inbound       = NULL;   /* mailer's inbound dir */
  91. char     *archive       = NULL;   /* archiver spawn string */
  92. char     *unarchive     = NULL;   /* unarchiver spawn string */
  93. CONTROLS control;
  94. GROUP    *group         = NULL;   /* list of groups being processed */
  95. ADDR     *myaddr        = NULL;   /* our network address(es) */
  96. ECHOREC  *echos         = NULL;   /* 'normal' echos */
  97. ASSHOLE  *assholes      = NULL;   /* assholes, natch */
  98. ROUTE    *routes        = NULL;   /* route statements */
  99. TONAMES  *tonames       = NULL;   /* special to: fields */
  100. word     packsize       = 0;      /* size at which to begin compressing */
  101. word     netarea        = 0;      /* netmail area # */
  102. word     maxdupes       = MAXDUPES; /* max # dupe recs/echo area (8 bytes ea.) */
  103. char     *logfile       = NULL;   /* logfile filename */
  104. int      logfilehandle  = -1;     /* logfile handle */
  105. char     *putmsgs       = NULL;   /* where *.MSG files go */
  106.  
  107. /* functions visible only to this module */
  108.  
  109. static int    _fastcall look_up (char *s);
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116. int _fastcall config (char *configfile) {
  117.  
  118.     /* Reads configuration information from file.  Returns 0 (ok) or
  119.        -1 (fatal error, terminate with prejudice). */
  120.  
  121.     int     handle,token;
  122.     int     pri1,pri2;
  123.     struct __pid__ {
  124.         word pid;
  125.         word thread;
  126.         word parentpid;
  127.     } pid;
  128.     char    s[513],*p,*pp,wasplus,valid_types[] = "CHDNM";
  129.     GROUP   *ginfo = NULL,*glast = NULL;
  130.     ADDR    *ainfo = NULL,*alast = NULL,*ealast = NULL;
  131.     ECHOREC *einfo = NULL,*elast = NULL;
  132.     ROUTE   *rinfo = NULL,*rlast = NULL;
  133.     TONAMES *tinfo = NULL,*tlast = NULL;
  134.  
  135.  
  136.     if(!configfile || !*configfile) configfile = "XGROUP.CTL";
  137.     handle = sopen(configfile,O_RDONLY | O_BINARY,SH_DENYNO);
  138.     if(handle == -1) {
  139.         printf("\nCan't open configfile \"%s\"\n",configfile);
  140.         return -1;
  141.     }
  142.  
  143.     control.xbbsos2     = 0;
  144.     control.tinysbs     = 1;  /* fingers down the throat of echopol */
  145.     control.noforward   = 0;
  146.     control.nolocalfor  = 0;
  147.     control.forfiles    = 0;
  148.     control.nodupes     = 0;
  149.     control.keeppath    = 0;
  150.     control.keepsbs     = 0;
  151.     control.keepdupes   = 0;
  152.     control.delbaddate  = 0;
  153.     control.keepnoforwards = 0;
  154.     control.allowbadareas = 0;
  155.  
  156.     while(!eof(handle)) {
  157.         if(!fgetsx(s,512,handle)) break;    /* break if EOF */
  158.  
  159.         p = strchr(s,';');                  /* strip any comments */
  160.         if(p) *p = 0;
  161.         lstrip(s);
  162.         stripcr(s);
  163.         rstrip(s);
  164.         if(!*s) continue;                   /* blank line or comment */
  165.  
  166.         wasplus = (char)(s[strlen(s) - 1] == '+');
  167.  
  168.         p = skip_nonwhite(s);               /* isolate keyword */
  169.  
  170.         if(*p) {                            /* point p at any arg */
  171.             *p=0;
  172.             p++;
  173.             p = skip_white(p);
  174.         }
  175.  
  176.         /* now process keyword/arg combination */
  177.  
  178.         token = look_up(s);
  179.  
  180.         switch(token) {
  181.             case 0:
  182.                 printf("\nUnknown keyword \"%s\"\n",s);
  183.                 break;
  184.  
  185.             case PRIORITIES:
  186.                 if(!machstate) {
  187.                     printf("\nI can't adjust my priority under DOS.\n");
  188.                 }
  189.                 else {
  190.                     pri1 = atoi(p);
  191.                     if(pri1 < 1) pri1 = 1;
  192.                     if(pri1 > 3) pri1 = 3;
  193.                     p = skip_nonwhite(p);
  194.                     p = skip_white(p);
  195.                     pri2 = atoi(p);
  196.                     if(pri2 < 0) pri2 = 0;
  197.                     if(pri2 > 31) pri2 = 31;
  198.                     DosGetPID(&pid);
  199.                     if(!DosSetPrty(2,pri1,pri2,pid.thread)) {
  200.                         printf("\nMy priority set to %d,%d\n",pri1,pri2);
  201.                     }
  202.                     else {
  203.                         printf("\nCouldn't adjust my priority.\n");
  204.                     }
  205.                 }
  206.                 break;
  207.  
  208.             case ALLOWBADAREAS:
  209.                 control.allowbadareas = 1;
  210.                 break;
  211.  
  212.             case KILLBADDATES:
  213.                 control.delbaddate = 1;
  214.                 break;
  215.  
  216.             case KEEPDUPES:
  217.                 control.keepdupes = 1;
  218.                 break;
  219.  
  220.             case KEEPSEENBYS:
  221.                 control.keepsbs = 1;
  222.                 break;
  223.  
  224.             case KEEPNOFORWARDS:
  225.                 control.keepnoforwards = 1;
  226.                 break;
  227.  
  228.             case KEEPPATH:
  229.                 control.keeppath = 1;
  230.                 break;
  231.  
  232.             case LOGFILE:
  233.                 logfile = assign(logfile,p);
  234.                 break;
  235.  
  236.             case NODUPES:
  237.                 control.nodupes = 1;
  238.                 break;
  239.  
  240.             case MAXIMUMDUPES:
  241.                 maxdupes = atoi(p);
  242.                 if(maxdupes > 8150) maxdupes = 8150;
  243.                 break;
  244.  
  245.             case NOFORWARD:
  246.                 control.noforward = 1;
  247.                 break;
  248.  
  249.             case NOLOCALFORWARD:
  250.                 control.nolocalfor = 1;
  251.                 break;
  252.  
  253.             case FORWARDFILES:
  254.                 control.forfiles = 1;
  255.                 break;
  256.  
  257.             case NOTINY:
  258.                 control.tinysbs = 0;
  259.                 break;
  260.  
  261.             case MESSAGES:
  262.                 putmsgs = assign(putmsgs,strip_trail_bksl(p));
  263.                 break;
  264.  
  265.             case GROUPIN:
  266.                 groupin = assign(groupin,strip_trail_bksl(p));
  267.                 break;
  268.  
  269.             case GROUPOUT:
  270.                 groupout = assign(groupout,strip_trail_bksl(p));
  271.                 break;
  272.  
  273.             case GROUPHOLD:
  274.                 grouphold = assign(grouphold,strip_trail_bksl(p));
  275.                 break;
  276.  
  277.             case MSGDIR:
  278.                 msgdir = assign(msgdir,strip_trail_bksl(p));
  279.                 break;
  280.  
  281.             case ARCHIVE:
  282.                 archive = assign(archive,p);
  283.                 break;
  284.  
  285.             case UNARCHIVE:
  286.                 unarchive = assign(unarchive,p);
  287.                 break;
  288.  
  289.             case NETAREA:
  290.                 netarea = atoi(p);
  291.                 break;
  292.  
  293.             case TONAME:
  294.                 if(p && *p) p++;
  295.                 pp = to_delim(p,"\"");
  296.                 if(!*pp) {
  297. IncompleteTo:
  298.                     printf("\nIncomplete To: \"%s\" skipped\n",p);
  299.                     break;
  300.                 }
  301.                 *pp = 0;
  302.                 pp++;
  303.                                 pp = skip_white(pp);        /* point pp at keyword */
  304.                 if(!*pp) goto IncompleteTo;
  305.                 tinfo = (TONAMES *)malloc(sizeof(TONAMES));
  306.                 tinfo->prgname = NULL;
  307.                 tinfo->addr = NULL;
  308.                 tinfo->next = NULL;
  309.                 tinfo->msg = 0;
  310.                 tinfo->route = 0;
  311.                 tinfo->prog = 0;
  312.                 tinfo->reserved = 0;
  313.                 if(!tinfo) {
  314.                     goto OutOfMemory;
  315.                 }
  316.                 tinfo->to = strdup(p);
  317.                 if(!tinfo->to) {
  318.                     my_free(tinfo);
  319.                     goto OutOfMemory;
  320.                 }
  321.                 p = skip_nonwhite(pp);
  322.                 p = skip_white(p);
  323.                 if(!stricmp(pp,"ROUTE")) tinfo->route = 1;
  324.                 else if(!stricmp(pp,"MSG")) tinfo->msg = 1;
  325.                 else if(!stricmp(pp,"PROG")) tinfo->prog = 1;
  326.                 else {
  327. InvalidTo:
  328.                     my_free(tinfo->to);
  329.                     my_free(tinfo);
  330.                     printf("\nInvalid To: command \"%s\"--skipped\n",pp);
  331.                     break;
  332.                 }
  333.                 if(tinfo->route || tinfo->prog) {
  334.                     if(!*p) {
  335.                         my_free(tinfo->to);
  336.                         my_free(tinfo);
  337.                         goto IncompleteTo;
  338.                     }
  339.                     pp = skip_nonwhite(p);
  340.                     if(*pp) *pp = 0;
  341.                 }
  342.                 if(tinfo->route) {
  343.                     tinfo->addr = (ADDR *)malloc(sizeof(ADDR));
  344.                     if(!tinfo->addr) {
  345.                         my_free(tinfo->to);
  346.                         my_free(tinfo);
  347.                         goto OutOfMemory;
  348.                     }
  349.                     tinfo->addr->next = NULL;
  350.                     pp = p;
  351.                     if(parse_addr(&p,tinfo->addr,myaddr)) {
  352.                         my_free(tinfo->to);
  353.                         my_free(tinfo->addr);
  354.                         my_free(tinfo);
  355.                         printf("\nInvalid address \"%s\"--skipped\n",pp);
  356.                         break;
  357.                     }
  358.                 }
  359.                 else if(tinfo->prog) {
  360.                     tinfo->prgname = strdup(strupr(p));
  361.                     if(!tinfo->prgname) {
  362.                         my_free(tinfo->to);
  363.                         my_free(tinfo);
  364.                         goto OutOfMemory;
  365.                     }
  366.                 }
  367.  
  368.                 if(!tonames) {
  369.                     tonames = tinfo;
  370.                 }
  371.                 else {
  372.                     tlast->next = tinfo;
  373.                 }
  374.                 tinfo->next = NULL;
  375.                 tlast = tinfo;
  376.                 break;
  377.  
  378.             case GROUPR:
  379.                 pp = skip_nonwhite(p);
  380.                 if(!*pp) {
  381. Incomplete:
  382.                     printf("\nIncomplete group \"%s\" skipped\n",p);
  383.                     break;
  384.                 }
  385.                 *pp = 0;
  386.                 pp++;
  387.                 pp = skip_white(pp);  /* point pp at area # */
  388.                 if(!*pp) goto Incomplete;
  389.                 ginfo = (GROUP *)malloc(sizeof(GROUP));
  390.                 if(!ginfo) {
  391. OutOfMemory:
  392.                     printf("\nOut of memory\n");
  393.                     break;
  394.                 }
  395.                 ginfo->id = strdup(p);
  396.                 if(!ginfo->id) {
  397.                     my_free(ginfo);
  398.                     goto OutOfMemory;
  399.                 }
  400.                 ginfo->reserved = 0;
  401.                 ginfo->areano = atoi(pp);
  402.                 ginfo->password = NULL;
  403.                 ginfo->forwarded = ginfo->imported = ginfo->exported = 0;
  404.  
  405.                 pp = skip_nonwhite(pp);
  406.                 if(!*pp) {
  407.                     my_free(ginfo->id);
  408.                     my_free(ginfo);
  409.                     goto Incomplete;
  410.                 }
  411.                 *pp = 0;
  412.                 pp++;
  413.                 pp = skip_white(pp);  /* point pp at numdays */
  414.                 if(!*pp) {
  415.                     my_free(ginfo->id);
  416.                     my_free(ginfo);
  417.                     goto Incomplete;
  418.                 }
  419.                 ginfo->numdays = atoi(pp);
  420.  
  421.                 pp = skip_nonwhite(pp);
  422.                 if(!*pp) {
  423.                     my_free(ginfo->id);
  424.                     my_free(ginfo);
  425.                     goto Incomplete;
  426.                 }
  427.                 *pp = 0;
  428.                 pp++;
  429.                 pp = skip_white(pp);  /* point pp at address (or topstar option) */
  430.                 if(!*pp) {
  431.                     my_free(ginfo->id);
  432.                     my_free(ginfo);
  433.                     goto Incomplete;
  434.                 }
  435.                 if(*pp == '!') {    /* top star */
  436.                     ginfo->uplink = NULL;
  437.                     if(toupper(pp[1]) == 'F') ginfo->style = 2;
  438.                     else if(toupper(pp[1]) == 'P') ginfo->style = 1;
  439.                     else {
  440.                         ginfo->style = 0;
  441.                         if(toupper(pp[1]) != 'N') {
  442.                             printf("\nInvalid topstar option \"%c\" for group \"%s\"\n",
  443.                                    toupper(pp[1]),ginfo->id);
  444.                         }
  445.                     }
  446.                 }
  447.                 else {
  448.                     ginfo->style = 0;
  449.                     ginfo->uplink = (ADDR *)malloc(sizeof(ADDR));
  450.                     if(!ginfo->uplink) {
  451.                         my_free(ginfo->id);
  452.                         my_free(ginfo);
  453.                         goto OutOfMemory;
  454.                     }
  455.                     ginfo->uplink->next = NULL;
  456.                     if(parse_addr(&pp,ginfo->uplink,myaddr)) {
  457.                         printf("\nInvalid address info for group \"%s\"\n",ginfo->id);
  458.                         my_free(ginfo->id);
  459.                         my_free(ginfo->uplink);
  460.                         my_free(ginfo);
  461.                         break;
  462.                     }
  463.                 }
  464.                 pp = skip_nonwhite(pp);
  465.                 if(*pp) {
  466.                     *pp = 0;
  467.                     pp++;
  468.                     pp = skip_white(pp);  /* point pp at password */
  469.                     if(*pp) {
  470.                         ginfo->password = strdup(pp);
  471.                     }
  472.                 }
  473.  
  474.                 if(!group) {
  475.                     group = ginfo;
  476.                 }
  477.                 else {
  478.                     glast->next = ginfo;
  479.                 }
  480.                 ginfo->next = NULL;
  481.                 glast = ginfo;
  482.                 break;
  483.  
  484.             case PACKSIZE:
  485.                 packsize = atoi(p);
  486.                 if(packsize && packsize < 1024) packsize = 1024;
  487.                 break;
  488.  
  489.             case XBBSOS2:
  490.                 if(!machstate) {
  491.                     printf("\nI can't access long file names from DOS,\n"
  492.                            "therefore I can't support XBBS-OS/2 from DOS.\n");
  493.                     close(handle);
  494.                     return -1;
  495.                 }
  496.                 control.xbbsos2 = 1;
  497.                 break;
  498.  
  499.             case INBOUND:
  500.                 inbound = assign(inbound,p);
  501.                 break;
  502.  
  503.             case OUTBOUND:
  504.                 outbound = assign(outbound,strip_trail_bksl(p));
  505.                 break;
  506.  
  507.             case ROUTER:
  508.                 if(!machstate) {
  509.                     printf("\nI can't access long file names from DOS,\n"
  510.                            "therefore I can't route for XBBS-OS/2 from DOS.\n");
  511.                     break;
  512.                 }
  513.                 pp = skip_nonwhite(p);
  514.                 if(!*pp) {
  515. Incomplerte:
  516.                     printf("\nIncomplete route \"%s\" skipped\n",p);
  517.                     break;
  518.                 }
  519.                 *pp = 0;
  520.                 pp++;
  521.                 pp = skip_white(pp);    /* point pp at type */
  522.                 if(!*pp) goto Incomplerte;
  523.                 rinfo = (ROUTE *)malloc(sizeof(ROUTE));
  524.                 if(!rinfo) {
  525. OutOfMemoryR:
  526.                     printf("\nOut of memory\n");
  527.                     break;
  528.                 }
  529.                 rinfo->mask = strdup(p);
  530.                 rinfo->type = (char)toupper(*pp);
  531.                 if(!strchr(valid_types,rinfo->type)) {
  532.                     rinfo->type = 'H';
  533.                 }
  534.                 if(!rinfo->mask) {
  535.                     my_free(rinfo);
  536.                     goto OutOfMemoryR;
  537.                 }
  538.                 pp = skip_nonwhite(pp);
  539.                 if(!*pp) {
  540.                     my_free(rinfo->mask);
  541.                     my_free(rinfo);
  542.                     goto Incomplerte;
  543.                 }
  544.                 *pp = 0;
  545.                 pp++;
  546.                 pp = skip_white(pp);    /* point pp at address */
  547.                 if(!*pp) {
  548.                     my_free(rinfo->mask);
  549.                     my_free(rinfo);
  550.                     goto Incomplerte;
  551.                 }
  552.                 p = skip_nonwhite(pp);     /* point p at archive cmd */
  553.                 if(*p) {
  554.                     *p = 0;
  555.                     p++;
  556.                 }
  557.                 p = skip_white(p);
  558.                 if(!*p) {
  559.                     my_free(rinfo->mask);
  560.                     my_free(rinfo);
  561.                     goto Incomplerte;
  562.                 }
  563.                 rinfo->archive = strdup(p);
  564.                 if(!rinfo->archive) {
  565.                     my_free(rinfo->mask);
  566.                     my_free(rinfo);
  567.                     goto OutOfMemoryR;
  568.                 }
  569.                 if(!stricmp(pp,"SAME")) {
  570.                     rinfo->addr = NULL;
  571.                 }
  572.                 else {
  573.                     rinfo->addr = (ADDR *)malloc(sizeof(ADDR));
  574.                     if(!rinfo->addr) {
  575.                         my_free(rinfo->archive);
  576.                         my_free(rinfo->mask);
  577.                         my_free(rinfo);
  578.                         goto OutOfMemoryR;
  579.                     }
  580.                     rinfo->addr->next = NULL;
  581.                     if(parse_addr(&pp,rinfo->addr,myaddr)) {
  582.                         printf("\nInvalid address info for route \"%s\"\n",rinfo->mask);
  583.                         my_free(rinfo->archive);
  584.                         my_free(rinfo->mask);
  585.                         my_free(rinfo->addr);
  586.                         my_free(rinfo);
  587.                     }
  588.                 }
  589.                 if(!routes) {
  590.                     routes = rinfo;
  591.                 }
  592.                 else {
  593.                     rlast->next = rinfo;
  594.                 }
  595.                 rinfo->next = NULL;
  596.                 rlast = rinfo;
  597.                 break;
  598.  
  599.             case ECHOR:
  600.                 pp = skip_nonwhite(p);
  601.                 if(!*pp) {
  602. Incomplecho:
  603.                     printf("\nIncomplete echo \"%s\" skipped\n",p);
  604.                     break;
  605.                 }
  606.                 *pp = 0;
  607.                 pp++;
  608.                 pp = skip_white(pp);  /* point pp at area # */
  609.                 if(!*pp) goto Incomplecho;
  610.                 einfo = (ECHOREC *)malloc(sizeof(ECHOREC));
  611.                 if(!einfo) {
  612. OutOfMemoryE:
  613.                     printf("\nOut of memory\n");
  614.                     break;
  615.                 }
  616.                 einfo->forwarded = einfo->imported = einfo->exported = 0;
  617.                 einfo->password = NULL;
  618.                 einfo->tag = strdup(p);
  619.                 if(!einfo->tag) {
  620.                     my_free(einfo);
  621.                     goto OutOfMemoryE;
  622.                 }
  623.                 einfo->areano = atoi(pp);
  624.  
  625.                 pp = skip_nonwhite(pp);
  626.                 if(!*pp) {
  627.                     einfo->addr = NULL;
  628.                     goto SkipEchoAddr;
  629.                 }
  630.                 *pp = 0;
  631.                 pp++;
  632.                 pp = skip_white(pp);  /* point pp at addresses, if any */
  633.                 if(!*pp) {
  634.                     einfo->addr = NULL;
  635.                     goto SkipEchoAddr;
  636.                 }
  637.                 einfo->addr = (ADDR *)malloc(sizeof(ADDR));
  638.                 if(!einfo->addr) {
  639.                     my_free(einfo->tag);
  640.                     my_free(einfo);
  641.                     goto OutOfMemoryE;
  642.                 }
  643.                 einfo->addr->next = NULL;
  644.                 if(parse_addr(&pp,einfo->addr,myaddr)) {
  645.                     printf("\nInvalid address info for echo \"%s\"\n",einfo->tag);
  646.                     my_free(einfo->tag);
  647.                     my_free(einfo->addr);
  648.                     my_free(einfo);
  649.                     break;
  650.                 }
  651.  
  652.                 ealast = einfo->addr;
  653.  
  654. AnotherLine:
  655.  
  656.                 while(pp && *pp) {
  657.                     ainfo = (ADDR *)malloc(sizeof(ADDR));
  658.                     if(!ainfo) goto OutOfMemoryE;
  659.                     if(parse_addr(&pp,ainfo,einfo->addr)) {
  660.                        my_free(ainfo->domain);
  661.                        my_free(ainfo);
  662.                         break;
  663.                     }
  664.                     ealast->next = ainfo;
  665.                     ainfo->next = NULL;
  666.                     ealast = ainfo;
  667.                 }
  668.  
  669.                 if(wasplus) {
  670.                     if(fgetsx(s,1023,handle)) {
  671.                         pp = strchr(s,';');       /* strip any comments */
  672.                         if(pp) *pp = 0;
  673.                         lstrip(s);
  674.                         stripcr(s);
  675.                         rstrip(s);
  676.                         if(*s) {
  677.                             wasplus = (char)(s[strlen(s) - 1] == '+');
  678.                             pp = s;
  679.                             goto AnotherLine;
  680.                         }
  681.                     }
  682.                 }
  683.  
  684. SkipEchoAddr:
  685.  
  686.                 if(!echos) {
  687.                     echos = einfo;
  688.                 }
  689.                 else {
  690.                     elast->next = einfo;
  691.                 }
  692.                 einfo->next = NULL;
  693.                 elast = einfo;
  694.                 break;
  695.  
  696.             case ANADDRESS:
  697.                 ainfo = (ADDR *)malloc(sizeof(ADDR));
  698.                 if(!ainfo) {
  699. OutOfMemoryA:
  700.                     printf("\nOut of memory\n");
  701.                     break;
  702.                 }
  703.                 if(parse_addr(&p,ainfo,myaddr)) {
  704.                     printf("\nInvalid address skipped\n");
  705.                     my_free(ainfo->domain);
  706.                     my_free(ainfo);
  707.                     break;
  708.                 }
  709.                 if(!myaddr) {
  710.                     myaddr = ainfo;
  711.                 }
  712.                 else {
  713.                     alast->next = ainfo;
  714.                 }
  715.                 ainfo->next = NULL;
  716.                 alast = ainfo;
  717.                 while(p && *p) {
  718.                     ainfo = (ADDR *)malloc(sizeof(ADDR));
  719.                     if(!ainfo) goto OutOfMemoryA;
  720.                     if(parse_addr(&p,ainfo,myaddr)) {
  721.                         my_free(ainfo->domain);
  722.                         my_free(ainfo);
  723.                         break;
  724.                     }
  725.                     if(!myaddr) {
  726.                         myaddr = ainfo;
  727.                     }
  728.                     else {
  729.                         alast->next = ainfo;
  730.                     }
  731.                     ainfo->next = NULL;
  732.                     alast = ainfo;
  733.  
  734.                 }
  735.                 break;
  736.         }
  737.     }
  738.  
  739.     close(handle);
  740.  
  741.     if((group && (!groupin || !groupout)) || !msgdir || (!group && !echos) ||
  742.        !archive || !outbound || !inbound || !myaddr || !netarea) {
  743.         printf("\nFatal error:  \"%s\" missing vital info:\n",configfile);
  744.         if(group && !groupin)   printf("GROUPIN directory\n");
  745.         if(group && !groupout)  printf("GROUPOUT directory\n");
  746.         if(!msgdir)    printf("MSGDIR directory\n");
  747.         if(!echos && !group)     printf("GROUPs and/or ECHOs\n");
  748.         if(!archive)   printf("ARCHIVE command\n");
  749.         if(!unarchive) printf("UNARCHIVE command\n");
  750.         if(!outbound)  printf("OUTBOUND directory\n");
  751.         if(!inbound)   printf("INBOUND directory\n");
  752.         if(!myaddr)    printf("ADDRESS\n");
  753.         if(!netarea)   printf("NETAREA #\n");
  754.         return -1;
  755.     }
  756.  
  757.     if(logfile && *logfile) {
  758.         logfilehandle = sopen(logfile,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IWRITE | S_IREAD);
  759.         if(logfilehandle != -1) lseek(logfilehandle,0L,SEEK_END);
  760.     }
  761.  
  762.     if(!maxdupes) control.nodupes = 1;
  763.  
  764.     return 0;
  765. }
  766.  
  767.  
  768.  
  769. static int _fastcall look_up (char *s) {
  770.  
  771.     /* Look up a token's internal representation in the token table */
  772.  
  773.     register int i = 0;
  774.  
  775.  
  776.     while(table[i].keyword) {
  777.         if(!stricmp(table[i].keyword,s)) return (int)table[i].tok;
  778.         i++;
  779.     }
  780.     return 0; /* unknown command */
  781. }
  782.