home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / MXMS_160.LZH / FILE.C < prev    next >
C/C++ Source or Header  |  1991-06-26  |  52KB  |  1,634 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*    File.c      File i/o routines for MaxMail                             */
  4. /*                                                                          */
  5. /****************************************************************************/
  6.  
  7. #include "MaxMail.h"
  8.  
  9. struct msgupd_st *msgupd;
  10. struct msgupd_st *next;
  11. struct proto_st *proto1;
  12. struct repupl_st *upl1;
  13. struct packer_st *packer1;
  14. struct reparc_st *reparc1;
  15. struct stat fbuf;
  16. char fname[_MAX_PATH];
  17. char exec_ret;
  18. int comhandle = -1;
  19. int FirstArc = 1;
  20.  
  21. int Command = FALSE;
  22.  
  23. void _interrupt _far CheckWatch(void);
  24. void (_interrupt _far *OldTimer)(void);
  25.  
  26. static int Critseg,Critoffs;
  27.  
  28. char *packtemp;
  29. char *arccmndline;
  30.  
  31. /* Load up user message areas data into linked list */
  32.  
  33. int build_areas(int mode,int output)
  34. {
  35.    int keys,mask,x,anum;
  36.    int index,count;
  37.    word *bitp;
  38.    struct _aidx IDX;
  39.  
  40.    count = 0;
  41.    if (PackDone)
  42.       return(0);
  43.  
  44.    msgupd = MSGUPD_1;
  45.    USERCFG.totselareas = 0;
  46.    while (msgupd) {
  47.       next = msgupd->next;
  48.       free(msgupd);
  49.       msgupd = next;
  50.    }
  51.  
  52.  
  53.    MSGUPD_1 = NULL;        /* Set up linked list */
  54.    anum = 0;
  55.    index = sopen(PRM(aidx_name),O_BINARY | O_RDONLY,SH_DENYNO,S_IREAD);
  56.    if (index == -1)
  57.       aborterror(FILEOPEN,"Error opening Area index file");
  58.    keys = read(index,(char *)&IDX,sizeof(struct _aidx));
  59.    if(fseek(afile,IDX.offset,SEEK_SET) == 0) {
  60.       fread(&AREA,astrlen,1,afile);
  61.       if (output)
  62.          strout("\r\n");
  63.    }
  64.    else keys = FALSE;
  65.    while (keys == sizeof(struct _aidx)) {
  66.       bitp = &USERCFG.msgarea[anum / 16];
  67.       mask = 1;
  68.       for (x=0; x < (anum % 16); x++)
  69.          mask = mask << 1;
  70.       if (!AREA.msglock)         /* No locks for this area */
  71.          keys = TRUE;
  72.       else {        /* User must have same locks */
  73.          keys = AREA.msglock & LastUser.key;
  74.          if (keys != (int) AREA.msglock)
  75.             keys = FALSE;
  76.       }
  77.       if (isskiparea(anum))
  78.          keys = FALSE;         /* If Sysop set skip, don't build this area */
  79.       if (isForcearea(anum))         /* Force this area */
  80.          *bitp |= mask;        /* Force area to be turned on */
  81.       if (AREA.msgpath[0] && (LastUser.priv >= AREA.msgpriv) && keys) {
  82.          count++;        /* Possible areas count */
  83.          if (*bitp & mask) {        /* User has selected this area */
  84.             if(check_barareas(&AREA,mode)) {
  85.                totmsgareas++;
  86.                msgupd = (struct msgupd_st *) malloc(sizeof(struct msgupd_st));
  87.                if (msgupd == NULL)
  88.                   aborterror(BADALLOC,NULL);
  89.                if (MSGUPD_1 == NULL) 
  90.                   MSGUPD_1 = msgupd;        /* Link in top of pointer */
  91.                else MSGUPD_cur->next = msgupd;
  92.                msgupd->areano = anum;
  93.                msgupd->flags = 0;
  94.                msgupd->attribute = (word) AREA.attrib[UserClass];
  95.                strcpy(msgupd->msgpath,AREA.msgpath);
  96.                msgupd->update = FALSE;
  97.                switch (AREA.area_type) {
  98.                   case 0:        /* Fido 1.msg style */
  99.                      msgupd->himsg = find_fidohigh(AREA.msgpath);
  100.                      break;
  101.  
  102.                   default:
  103.                      msgupd->himsg = find_fidohigh(AREA.msgpath);
  104.                      break;
  105.                }
  106.                if (msgupd->himsg < 0  )
  107.                   msgupd->himsg = 0;
  108.                msgupd->areaindex = ftell(afile) - (long) astrlen;    /* Position */
  109.                msgupd->next = NULL;
  110.                msgupd->startmsg = 1;
  111.                msgupd->readmsgs = 0;
  112.                msgupd->msgcount = 0;
  113.                if (isForcearea(anum))
  114.                   msgupd->flags |= AREA_FORCED;
  115.                MSGUPD_cur = msgupd;
  116.                if (msgupd->himsg) {
  117.                   msgupd->startmsg = get_lastread(AREA.msgpath);
  118.                   if (msgupd->startmsg > msgupd->himsg) 
  119.                      msgupd->startmsg = msgupd->himsg;
  120.                   if (msgupd->startmsg < 1)
  121.                      msgupd->startmsg = 1;
  122.                   msgupd->msgcount = msgupd->himsg - msgupd->startmsg;
  123.                }
  124.                if (output) {
  125.                   sprintf(temp,"\rArea %d: ",anum);
  126.                   strncat(temp,AREA.msginfo,35);
  127.                   for (x = 45 - strlen(temp); x; x-- )
  128.                      strcat(temp," ");
  129.                   strout(temp);
  130.                }
  131.             }
  132.             else {        /* Deselect area */
  133.                mask ^= 0xffff;        /* Reverse mask */
  134.                *bitp &= mask;        /* Turn area off if barricaded rejected */
  135.             }
  136.          }
  137.          else {        /* User has area turned on, but it's no valid. Turn it off */
  138.             mask ^= 0xffff;        /* Reverse mask */
  139.             *bitp &= mask;        /* Turn area off if barricaded rejected */
  140.          }
  141.       }
  142.       else {        /* it's not a message area */
  143.          if (*bitp & mask) {        /* User has selected this area */
  144.             mask ^= 0xffff;        /* Reverse mask */
  145.             *bitp &= mask;        /* Turn area off if invalid */
  146.          }
  147.       }
  148.       anum++;
  149.       keys = read(index,(char *)&IDX,sizeof(struct _aidx));
  150.       if (keys == sizeof(struct _aidx)) {
  151.          if(fseek(afile,IDX.offset,SEEK_SET) == 0)
  152.             fread(&AREA,astrlen,1,afile);
  153.          else keys = FALSE;
  154.       }
  155.    }
  156.    if (output)
  157.       strout("\r\n");
  158.    close(index);
  159.    USERCFG.totselareas = totmsgareas;
  160.    USERCFG.totareas = count;
  161.    return(count);
  162. }
  163.  
  164. /* Scan message areas,build capture file */
  165.  
  166. int scan_msgs()
  167. {
  168.    int x,y,firsttime;
  169.    FILE *headfile;
  170.    FILE *statfile;
  171.    FILE *sfile;
  172.    struct msghead *MSGHD;
  173.  
  174.    if (MSGUPD_1 == NULL) {
  175.       setcolor(TextAttr[ATTN_TEXT]);
  176.       logit("User has no message areas selected",'!');
  177.       strout("\r\nYou have no valid message areas selected.");
  178.       strout("\r\nSelect [C] at menu prompt and change your configuration\r\n");
  179.       return(FALSE);
  180.    }
  181.  
  182.    if (PackDone)
  183.       return(FALSE);
  184.  
  185.    if (USERCFG.msgfrmt == 0) {
  186.       if (Task) {        /* Rename TxtFile to have tasknumber */
  187.          _splitpath(TxtFile,hdrive,hdir,temp,temp1);
  188.          temp[6] = 0;        /* Trim out 2 chars */
  189.          sprintf(TxtFile,"%s%02x%s",temp,Task,temp1);
  190.       }
  191.       if (tdir[0]) {
  192.          sprintf(temp1,"%s\\%s",tdir,TxtFile);
  193.          outfile = _fsopen(temp1,"w+",SH_DENYNO);
  194.       }
  195.       else outfile = _fsopen(TxtFile,"w+",SH_DENYNO);
  196.       if (outfile == NULL) {
  197.          sprintf(temp1,"Error creating %s",TxtFile);
  198.          aborterror(FILECREATE,temp1);
  199.       }
  200.    }
  201.    else {        /* QWK style */
  202.       if(openqwk()) {
  203.          sprintf(temp1,"Error creating QWK packet");
  204.          aborterror(FILECREATE,temp1);
  205.       }
  206.       statfile = NULL;
  207.       outfile = NULL;
  208.       SumFile[0] = 0;
  209.    }
  210.  
  211.    MSGHD = (struct msghead *) malloc(sizeof(struct msghead));
  212.    if (MSGHD == NULL)
  213.       aborterror(BADALLOC,NULL);
  214.    MSGHD->answers = NULL;
  215.    strcpy(MSGHD->ourname,LastUser.name);
  216.  
  217.    totmsgs = 0;
  218.    firsttime = TRUE;
  219.    msgupd = MSGUPD_1;
  220.    while (msgupd) {
  221.       fseek(afile,msgupd->areaindex,SEEK_SET);
  222.       fread(&AREA,astrlen,1,afile);
  223.       if (firsttime) {
  224.          if (USERCFG.msgfrmt == 0) {
  225.             fprintf(outfile,"\n MaxMail Version %.2f Custom message archive for %s\n",Version,USERCFG.name);
  226.             fprintf(outfile," ---> Messages were captured on %s\n",timestring());
  227.             if (MsgHdrFile[0]) {        /* Sysop wants to put in a message header file */
  228.                headfile = _fsopen(MsgHdrFile,"rt",SH_DENYNO);
  229.                if (headfile == NULL) 
  230.                   logit("Message Header file could not be opened.",'!');
  231.                else {
  232.                   fgets(temp,80,headfile);
  233.                   while (!feof(headfile)) {
  234.                      fputs(temp,outfile);
  235.                      fgets(temp,80,headfile);
  236.                   }
  237.                   fclose(headfile);
  238.                }
  239.             }
  240.             if (StatName[0]) {
  241.                if (Task) {
  242.                   sprintf(temp,".%x",Task);
  243.                   strcat(StatName,temp);
  244.                }
  245.                if (tdir[0]) {
  246.                   sprintf(temp,"%s\\%s",tdir,StatName);
  247.                   statfile = _fsopen(temp,"wt",SH_DENYNO);
  248.                }
  249.                else statfile = _fsopen(StatName,"wt",SH_DENYNO);
  250.             }
  251.             else statfile = NULL;
  252.             if (SumFile[0]) {
  253.                if (tdir[0]) {
  254.                   sprintf(temp,"%s\\%s",tdir,SumFile);
  255.                   unlink(temp);
  256.                }
  257.                else unlink(SumFile);
  258.             }
  259.          }
  260.          setcolor(TextAttr[STD_TEXT]);
  261.          strout("\r\n--------[ Grinding the sysop's disk now ]-----------------");
  262.          strout("\r\n                              Start    High   New     Your");
  263.          strout("\r\nMessage Area                    Msg     Msg   Msgs    Msgs");
  264.          strout("\r\n----------------------------------------------------------\r\n");
  265.          if (statfile != NULL && USERCFG.msgfrmt == 0) {
  266.             fprintf(statfile,"\n-----------------[ MaxMail Statistics ]-------------------");
  267.             fprintf(statfile,"\n                              Start    High   New     Your");
  268.             fprintf(statfile,"\nMessage Area                    Msg     Msg   Msgs    Msgs");
  269.             fprintf(statfile,"\n----------------------------------------------------------\n");
  270.          }
  271.          firsttime = FALSE;
  272.       }
  273.       msgupd->readmsgs = 0;
  274.       if (msgupd->msgcount > 0)     {    /* If there are messages in this area */
  275.          MSGHD->ourmail = 0;
  276.          if (MSGHD->answers != NULL)
  277.             free(MSGHD->answers);
  278.          MSGHD->answers = NULL;
  279.          x = load_area(msgupd,statfile,MSGHD);        /* Return lastread msgnum */
  280.          if (msg_update) {
  281.             msgupd->update = TRUE;
  282.             msgupd->readmsgs = x - msgupd->startmsg;        /* Establish last message read */
  283.          }
  284.          if (MSGHD->ourmail) {
  285.             setcolor(TextAttr[MENU_KEY]);
  286.             sprintf(temp,"      You have %d personal messages in this area.\r\n",MSGHD->ourmail);
  287.             strout(temp);
  288.             if (USERCFG.msgfrmt == 0 && statfile != NULL) {
  289.                fprintf(statfile,"      You have %d personal messages in this area. See messages: \n",MSGHD->ourmail);
  290.                y = 0;
  291.                fprintf(statfile,"      ");
  292.                setcolor(TextAttr[STD_TEXT]);
  293.                for (x = 0; x < (int) MSGHD->ourmail; x++) {
  294.                   if (x < (int) (MSGHD->ourmail - 1))
  295.                      fprintf(statfile,"%d,",MSGHD->answers[x]);
  296.                   else fprintf(statfile,"%d",MSGHD->answers[x]);
  297.                   if(++y > 20) {
  298.                      fprintf(statfile,"\n      ");
  299.                      y = 0;
  300.                   }
  301.                }
  302.                fprintf(statfile,"\n");
  303.             }
  304.          }
  305.       }
  306.       if ((unsigned) totmsgs >= MaxMsgs) {
  307.          setcolor(TextAttr[ATTN_TEXT]);
  308.          sprintf(temp1,"\r\nPoof! You've gobbled up the maximum # of messages (%d) for this run\r\n",totmsgs);
  309.          strout(temp1);
  310.          if (LogMode == VERBOSE)
  311.             logit("User has used up maximum messages for this run",'#');
  312.          break;
  313.       }
  314.       msgupd = msgupd->next;
  315.    }
  316.    setcolor(TextAttr[HILITE_TEXT]);
  317.    if (USERCFG.msgfrmt == 0) {
  318.       fprintf(outfile," \n\n ---> %d Total messages were captured <---\n",totmsgs);
  319.       fclose(outfile);
  320.       if (statfile != NULL) {
  321.          if (tdir[0]) {
  322.             sprintf(temp1,"%s\\%s",tdir,SumFile);
  323.             sfile = _fsopen(temp1,"rt",SH_DENYNO);
  324.          }
  325.          else sfile = _fsopen(SumFile,"rt",SH_DENYNO);
  326.          if (SumFile[0] && sfile != NULL) {
  327.             while (!feof(sfile)) {
  328.                if(fgets(temp1,80,sfile) != NULL)
  329.                   fputs(temp1,statfile);
  330.             }
  331.             fclose(sfile);
  332.          }
  333.          fclose(statfile);
  334.       }
  335.       if (SumFile[0]) {
  336.          if (tdir[0]) {
  337.             sprintf(temp,"%s\\%s",tdir,SumFile);
  338.             unlink(temp);
  339.          }
  340.          else unlink(SumFile);
  341.       }
  342.    }
  343.    else {        /* QWK format */
  344.       closeqwk();        /* Clean up things */
  345.    }
  346.    if (MSGHD->answers != NULL)
  347.       free(MSGHD->answers);
  348.    free(MSGHD);
  349.    return(TRUE);
  350. }
  351.  
  352. /* Scan individual message area,called from Scan_msgs(), get
  353.    message text and write to capture file, stats file */
  354.  
  355. int load_area(struct msgupd_st *msgupd,FILE *statfile,struct msghead *MSGHD)
  356. {
  357.    int x,y,msgcount,divisor,lastmsg;
  358.    int forward,fidoflags,msgtot,color;
  359.    FILE *sumfile = NULL;
  360.  
  361.    if (msgupd->himsg > 0) {
  362.       color = 0;        /* Activity divit color rotate */
  363.       lastmsg = msgupd->startmsg;
  364.       if (USERCFG.msgfrmt == 0) {
  365.          fprintf(outfile,"\n\n\n *************************************************************\n");
  366.          if (AREA.attrib[UserClass] & ECHOMAIL) 
  367.             sprintf(temp," ** Echomail Area %s - %s ",AREA.name,AREA.msginfo);
  368.          else sprintf(temp," ** Local/Public Area %s - %s ",AREA.name,AREA.msginfo);
  369.          while (strlen(temp) < 60)
  370.             strcat(temp," ");
  371.          strcat(temp,"**");
  372.          fprintf(outfile,"%s\n",temp);
  373.          fprintf(outfile," *************************************************************\n");
  374.       }
  375.       strncpy(temp1,AREA.msginfo,24);
  376.       temp1[24] = 0;
  377.       while (strlen(temp1) < 24)
  378.          strcat(temp1," ");
  379.       sprintf(temp,"[%03d] %s %04u    %04u   %04u     ",msgupd->areano,temp1,msgupd->startmsg,msgupd->himsg,msgupd->msgcount);
  380.       if (statfile != NULL)
  381.          fprintf(statfile,"[%03d] %s %04u    %04u   %04u    ",msgupd->areano,temp1,msgupd->startmsg,msgupd->himsg,msgupd->msgcount);
  382.       if (SumFile[0]) {
  383.          if (tdir[0]) {
  384.             sprintf(temp1,"%s\\%s",tdir,SumFile);
  385.             sumfile = _fsopen(temp1,"at",SH_DENYNO);
  386.          }
  387.          else sumfile = _fsopen(SumFile,"at",SH_DENYNO);
  388.          if (statfile != NULL) {
  389.             fprintf(sumfile,"\n\n************ Message Subject Summary ************************\n");
  390.             if (AREA.attrib[UserClass] & ECHOMAIL) 
  391.                sprintf(temp1,"** Echomail Area %s - %s ",AREA.name,AREA.msginfo);
  392.             else sprintf(temp1,"** Local/Public Area %s - %s ",AREA.name,AREA.msginfo);
  393.             while (strlen(temp1) < 59)
  394.                strcat(temp1," ");
  395.             strcat(temp1,"**");
  396.             fprintf(sumfile,"%s\n",temp1);
  397.             fprintf(sumfile,"*************************************************************\n");
  398.             fprintf(sumfile,"Msg#    From                                  Subject\n");
  399.             fprintf(sumfile,"-------------------------------------------------------------\n");
  400.          }
  401.          
  402.       }
  403.       setcolor(TextAttr[STD_TEXT]);
  404.       strout(temp);
  405.       msgcount = 0;
  406.       forward = 1;        /* Activity flag */
  407.  
  408.       fidoflags = 0;
  409.  
  410.       if (LastUser.priv < ASSTSYSOP && !(msgupd->attribute & NOPRIVATE)) 
  411.          fidoflags |= PRIVATE;
  412.  
  413. /* If non-echomail area, start at message #1 */
  414.  
  415.       if (!(AREA.attrib[UserClass] & ECHOMAIL) && msgupd->startmsg == 1) 
  416.          msgupd->startmsg = 0;
  417.  
  418.       msgtot = msgupd->himsg - msgupd->startmsg;  /* Total poss messages in area */
  419.       for (x=msgupd->startmsg+1; x <= (int) msgupd->himsg && ((unsigned) totmsgs < MaxMsgs); x++) {
  420.          if ((msgtot - msgcount) > 40)        /* Total messages in this area */
  421.             divisor = 2;
  422.          else divisor = 1;        /* Flip activity flag more */
  423.          MSGHD->subject[0] = 0;
  424.          switch (AREA.area_type) {
  425.             case 0:        /* Fido 1.msg style */
  426.                if (USERCFG.msgfrmt == 0) 
  427.                   y = file_fidomsg(x,fidoflags,outfile,msgupd,MSGHD);
  428.                else y = qwk_fidomsg(x,fidoflags,msgupd,MSGHD);
  429.                break;
  430.  
  431.             default:
  432.                if (USERCFG.msgfrmt == 0) 
  433.                   y = file_fidomsg(x,fidoflags,outfile,msgupd,MSGHD);
  434.                else y = qwk_fidomsg(x,fidoflags,msgupd,MSGHD);
  435.                break;
  436.          }
  437.  
  438.          if (y < 0) {        /* Some kind of error */
  439.             if (y == PVTMSG_ERR)         /* No real error, just a private msg */
  440.                continue;
  441.             else continue;        /* This is redundant for now! */
  442.          }
  443.          else {        /* A message was read */
  444.             lastmsg = y;
  445.             if (sumfile != NULL) {        /* Muck with the summary file */
  446.                sprintf(temp1,"%d",y);
  447.                while (strlen(temp1) < 8 )
  448.                   strcat(temp1," ");
  449.                fprintf(sumfile,"%s",temp1);
  450.                sprintf(temp1,"%s",MSGHD->from);
  451.                while (strlen(temp1) < 36 )
  452.                   strcat(temp1," ");
  453.                fprintf(sumfile,"%s  ",temp1);
  454.                strncpy(temp1,MSGHD->subject,34);
  455.                temp1[34] = 0;
  456.                fprintf(sumfile,"%s\n",temp1);
  457.             }
  458.             msgcount++;
  459.             totmsgs++;
  460.          }
  461.          if (!(msgcount % 10)) {        /* Show 10 count */
  462.             setcolor(TextAttr[HILITE_TEXT]);
  463.             sprintf(temp1,"  %4d",msgcount);
  464.             strout(temp1);
  465.             strout("\b\b\b\b\b\b");        /* Restore position to divit */
  466.          }
  467.          if (!(msgcount % divisor)) {        /* A little activity display logic */
  468.             setcolor(TextAttr[color]);
  469.             switch (forward) {
  470.                case 1:
  471.                   strout("\b|");
  472.                   forward++;
  473.                   break;
  474.  
  475.                case 2:
  476.                   strout("\b/");
  477.                   forward++;
  478.                   break;
  479.  
  480.                case 3:
  481.                   strout("\b-");
  482.                   forward++;
  483.                   break;
  484.  
  485.                case 4:
  486.                   strout("\b\\");
  487.                   forward = 1;
  488.                   break;
  489.             }
  490.             if (++color > (TOTALCOLORS - 1))
  491.                color = 0;        /* Restart */
  492.             if (color == ATTN_TEXT)
  493.                color++;
  494.          }
  495.          if (USERCFG.maxareamsgs != 0 && (USERCFG.msgfrmt == 1)) {
  496.             if((word) msgcount >= USERCFG.maxareamsgs) 
  497.                break;        /* We must stop here! */
  498.          }
  499.       }
  500.       if (!msgcount)    {    /* No messages in this area */
  501.          setcolor(TextAttr[ATTN_TEXT]);
  502.          strout("\bNew msgs are private!\r\n");    
  503.       }
  504.       else {
  505.          if (msgcount >= 3) 
  506.             strout("\b ");
  507.          sprintf(temp,"\b%04d              \r\n",msgcount);
  508.          setcolor(TextAttr[HILITE_TEXT]);
  509.          strout(temp);
  510.          if (statfile != NULL)
  511.             fprintf(statfile,"%04d\n",msgcount);
  512.       }
  513.    }
  514.    if (sumfile != NULL)
  515.       fclose(sumfile);
  516.    setcolor(TextAttr[STD_TEXT]);
  517.    return lastmsg;
  518. }
  519.  
  520. /* Pack user capture file & summary file into designated packer */
  521.  
  522. int Packit(void)
  523. {
  524.    int x,old;
  525.    FILE *new;
  526.    char *p,*p1;
  527.    struct find_t c_file;
  528.  
  529.    PackDone = FALSE;
  530.  
  531.    sprintf(temp1,"\r\n\r\nNow packing up %d messages\r\n",totmsgs);
  532.    setcolor(TextAttr[STD_TEXT]);
  533.    strout(temp1);
  534.    strout("Please wait while I call the packer program.....\r\n");
  535.    if (USERCFG.msgfrmt == 0) {
  536.       makearc(TxtFile);        /* Add Text file to archive */
  537.       if (StatName[0]) {
  538.          if (comhandle < 0) 
  539.             strout("Hang on! I am now adding the MSGSTATS file to the archive\r\n");
  540.          makearc(StatName);        /* Add stat file to archive */
  541.       }
  542. /* Include newfiles list option */
  543.       if ((USERCFG.flags & NEWFILES_INC) && NewFiles[0]) {
  544.          if (comhandle < 0) 
  545.             strout("Hang on! I am now adding the NEWFILES list to the archive. We're almost done..\r\n");
  546.          makearc(NewFiles);
  547.       }
  548.    }
  549.    else {        /* QWK format */
  550.       if ((USERCFG.flags & NEWFILES_INC) && NewFiles[0]) {
  551.          if (tdir[0])
  552.             sprintf(temp1,"%s\\",tdir);
  553.          if (QWKDir[0]) {
  554.             strcat(temp1,QWKDir);
  555.             strcat(temp1,"\\");
  556.          }
  557.          strcat(temp1,"NewFiles.dat");        /* Build full path */
  558.          if(copyfile(NewFiles,temp1))        /* Source to dest */
  559.             NewFiles[0] = 0;
  560.       }
  561.       copy2temp(QWKnews);        /* Copy all these files if they exist */
  562.       copy2temp(QWKbye);
  563.       copy2temp(QWKWelcome);
  564.  
  565.       if (!_dos_findfirst("blt-*.*",_A_NORMAL,&c_file)) {    /* copy the bulletins */
  566.          copy2temp(c_file.name);
  567.          while (!_dos_findnext(&c_file)) 
  568.             copy2temp(c_file.name);
  569.       }
  570.       makearc("*.*");
  571.    }
  572.  
  573.    if ((USERCFG.flags & NEWFILES_INC) && NewFiles[0])
  574.       logit("Adding NEWFILES list to user packet",'#');
  575.  
  576.    if (packer1->viewstring && comhandle < 0 && !IsLocal) {         /* Call up packer again, showing viewline */
  577.       setcolor(TextAttr[STD_TEXT]);
  578.       if (SwapMode)
  579.          sprintf(temp," /c %s",packer1->packexe);
  580.       else strcpy(temp," ");
  581.       strcpy(temp1,packer1->viewstring);
  582.       p = strtok(temp1,"%");        /* Up to 1st token */
  583.       strcat(temp,p);
  584.       strcat(temp," ");
  585.       p1 = strtok(NULL,"%");        /* Up to 2nd token */
  586.       if (tolower(p1[0]) == 'a')         /* Arcfile */
  587.          strcat(temp,ArcFile);
  588.       strcat(temp," ");
  589.       p1 = strtok(NULL,"\0");        /* Get rest of line */
  590.       if (p1) strcat(temp,p1);
  591.  
  592.       printf("Command line: %s %s\n",fname,temp);
  593.  
  594.       tempdir();
  595.  
  596.       old = dup(1);        /* old now refers to stdout */
  597.       if (!IsLocal) {
  598.          sprintf(temp1,"tmpmax%02x",Task);
  599.          new = _fsopen(temp1,"w+",SH_DENYWR);        /* Reroute stdout to file */
  600.          dup2(fileno(new),1);        /* Reroute stdout to file */
  601.       }
  602.  
  603. /* Execute the ARCHIVE viewing command */
  604.       if (SwapMode) {
  605.          sprintf(temp1,"Maxmal%02x.swp",Task);
  606.          x = swap(fname,temp,&exec_ret,temp1);
  607.       }
  608.       else {        /* We must do a DOS exec function */
  609.          strcpy(temp1,fname);
  610.          strcat(temp1," ");
  611.          strcat(temp1,temp);
  612.          x = system(temp1);
  613.          exec_ret = (char) x;
  614.       }
  615.  
  616.       if (!IsLocal) {
  617.          dup2(old,1);        /* Restore stdout */
  618.          fclose(new);
  619. /* Now display tmp file to user */
  620.          sprintf(temp1,"tmpmax%02x",Task);
  621.          show_file(temp1,FALSE);
  622.          unlink(temp1);
  623.       }
  624.       homedir();
  625.       check_carrier();
  626.    }
  627.  
  628.    sprintf(temp,"Packing up %d messages using %s",totmsgs,packer1->packexe);
  629.    logit(temp,'#');
  630.  
  631.    PackDone = TRUE;        /* Say yes, it's accepted */
  632.  
  633.    if (comhandle >= 0) {
  634.       close(comhandle);
  635.       comhandle = -1;
  636.    }
  637.  
  638.    if (USERCFG.msgfrmt == 1) {
  639.       tempdir();
  640.       sprintf(temp,"%s.qwk",BBSid);
  641.       rename(ArcFile,temp);
  642.       strcpy(ArcFile,temp);
  643.       homedir();
  644.    }
  645.  
  646.    tempdir();
  647.    stat(ArcFile,&fbuf);
  648.    homedir();
  649.    sprintf(temp,"%s is %lu bytes",ArcFile,fbuf.st_size);
  650.    logit(temp,'#');
  651.  
  652.    return(TRUE);
  653. }
  654.  
  655. /* Transmit user archive file, with designated protocol engine */
  656. int sendit(void)
  657. {
  658.    int x;
  659.    long calc;
  660.    char *p,*p1;
  661.    char portstr[3];
  662.  
  663.  
  664.    x = USERCFG.protocol;        /* Save current protocol type */
  665.    if (!x)
  666.       get_proto(FALSE);
  667.  
  668.    proto1 = get_curprotolnk();
  669.    USERCFG.protocol = (byte) x;
  670.  
  671.    _searchenv(proto1->protoexe,"PATH",fname);
  672.  
  673.    strcpy(temp1,proto1->protostring);
  674.    p = strtok(temp1,"%");        /* Up to 1st token */
  675.    strcpy(temp,p);
  676.    p1 = strtok(NULL,"%");        /* Up to 2nd token */
  677.  
  678. /* Parse protocol string and build command line */
  679.    while (*p1) {
  680.       switch (tolower(p1[0])) {
  681.          case 'a':
  682.             strcat(temp,ArcFile);
  683.             break;
  684.  
  685.          case 'p':
  686.             sprintf(portstr,"%d",prm.com_port + 1);        /* Com1 or com2 */
  687.             strcat(temp,portstr);
  688.             break;
  689.  
  690.          case 'b':
  691.             sprintf(portstr,"%d",LastUser.flag);        /* Baudrate */
  692.             strcat(temp,portstr);
  693.             break;
  694.  
  695.          default:
  696.             strcat(temp,p1);
  697.             break;
  698.       }
  699.       p1++;
  700.       if (*p1)
  701.          strcat(temp,p1);
  702.       strcat(temp," ");
  703.       p1 = strtok(NULL,"%");        /* Up to 2nd token */
  704.    }
  705.  
  706.  
  707.    tempdir();
  708.    stat(ArcFile,&fbuf);
  709.    homedir();
  710.  
  711.    setcolor(TextAttr[HILITE_TEXT]);
  712.    sprintf(temp1,"\r\nPacked message file (%s) is %lu bytes\r\n",ArcFile,fbuf.st_size);
  713.    strout(temp1);
  714.    calc = (long) get_kminute();
  715.    if (calc) {
  716.       calc = fbuf.st_size / calc;
  717.       if (calc <= 0)
  718.          calc = 1;
  719.    }
  720.    else calc = 1;
  721.  
  722.    if (!IsLocal) {
  723.       setcolor(TextAttr[HILITE_TEXT]);
  724.       sprintf(temp1,"It will take about %ld minute(s) to download\r\n",calc);
  725.       strout(temp1);
  726.    }
  727.    else Hangup = 0;
  728.    setcolor(TextAttr[PROMPT_TEXT]);
  729.  
  730.    if (!IsLocal) {
  731.       if (Hangup && !(USERCFG.flags & DLHANGUP)) {
  732.          strout("Are you sure you want to download it?\r\n");
  733.          strout("(Y)es,(N)o,(H)ang up after download [Y,n,h] -> ");
  734.       }
  735.       else {
  736.          if (!Hangup && (USERCFG.flags & DLHANGUP)) {
  737.             setcolor(TextAttr[ATTN_TEXT]);
  738.             strout("Sysop has turned OFF the hangup after download option.\r\n");
  739.             setcolor(TextAttr[PROMPT_TEXT]);
  740.          }
  741.          strout("Are you sure you want to download it? [Y,n] -> ");
  742.       }
  743.    }
  744.    else strout("Are you sure you want to keep this message packet? [Y,n] -> ");
  745.  
  746.    x = chrin();
  747.    if (isalpha(x))
  748.       x &= 0x00df;        /* Force upper case, toupper() has side effects */
  749.    chrout((char) x);
  750.    strout("\r\n");
  751.    if (x == '\r')
  752.       x = 'Y';
  753.  
  754.    if ( x == 'Y' || x == 'H') {
  755.       if (IsLocal) {
  756.          USERCFG.packcount++;
  757.          if (packer_del) {
  758.             setcolor(TextAttr[ATTN_TEXT]);
  759.             strout("\nUnfortunately, you did NOT specify /N switch so message packet\n");
  760.             strout("  will be deleted after exit!\n");
  761.             setcolor(TextAttr[STD_TEXT]);
  762.          }
  763.          else {
  764.             strout("\nMessage packet will remain on the local disk after exit.\n");
  765.             Exitcode = 7;
  766.          }
  767.          return TRUE;
  768.       }
  769.  
  770.       if (x == 'Y' && Hangup && !(USERCFG.flags & DLHANGUP))
  771.          Hangup = 0;
  772.  
  773.       if (x == 'H' && Hangup)
  774.          Hangup = 1;        /* User want's hangup */
  775.  
  776.       sprintf(temp1,"Transmit %s using %s",ArcFile,proto1->protoname);
  777.       logit(temp1,'=');
  778.  
  779.       sprintf(temp1,"Prepare to download %s using %s \r\n",ArcFile,proto1->protoname);
  780.       strout(temp1);
  781.       delay_s(2);        /* Make sure string is displayed to user */
  782.  
  783.       printf("Command line: %s %s\n",fname,temp);
  784.  
  785.    /* Execute the protocol engine */
  786.       FossilDeInit();        /* Remove fossil from us */
  787.  
  788.       tempdir();
  789.  
  790.       if((USERCFG.flags & DLHANGUP) && Hangup)
  791.          Hangup = 1;
  792.  
  793.       if (SwapMode) {
  794.          sprintf(temp1,"Maxmal%02x.swp",Task);
  795.          x = swap(fname,temp,&exec_ret,temp1);
  796.       }
  797.       else {        /* We must do a DOS exec function */
  798.          strcpy(temp1,fname);
  799.          strcat(temp1,temp);
  800.          x = system(temp1);
  801.          exec_ret = (char) x;
  802.       }
  803.  
  804.       homedir();
  805.       FossilInit();        /* Restart fossil for us */
  806.  
  807.       if (x || exec_ret) {
  808.          setcolor(TextAttr[ATTN_TEXT]);
  809.          strout("\r\n\r\nOh Oh! Xfer program had some kind of error\r\n");
  810.          sprintf(temp,"Xfer pgm error code: %d, swap error: %d",exec_ret,x);
  811.          logit(temp,'!');
  812.          if (Hangup == 1)
  813.             Hangup = 2;        /* Disable hangup */
  814.          return FALSE;        /* Allow user to retry transmission */
  815.       }
  816.       else {
  817.          USERCFG.dailycount += 1;
  818.          setcolor(TextAttr[HILITE_TEXT]);
  819.          strout("\r\nNo errors occured during transfer.\r\n");
  820.          USERCFG.packcount++;
  821.          return(TRUE);
  822.       }
  823.    }
  824.    else return FALSE;
  825. }
  826.  
  827. int repupload(void)
  828. {
  829.    int x;
  830.    char *p,*p1;
  831.    char portstr[3];
  832.    char tname[14];
  833.  
  834.    if (!IsLocal) {
  835.       x = USERCFG.protocol;        /* Save current protocol type */
  836.       get_proto(FALSE);        /* Force protocol question for uploads */
  837.       upl1 = get_curreplnk();
  838.       USERCFG.protocol = (byte) x;
  839.    }
  840.    else upl1 = REPUPL_1;
  841.  
  842.  
  843.    _searchenv(upl1->protoexe,"PATH",fname);
  844.  
  845.    sprintf(tname,"%s.rep",BBSid);
  846.  
  847.    strcpy(temp1,upl1->protostring);
  848.    p = strtok(temp1,"%");        /* Up to 1st token */
  849.    strcpy(temp,p);
  850.    p1 = strtok(NULL,"%");        /* Up to 2nd token */
  851.  
  852. /* Parse protocol string and build command line */
  853.    while (*p1) {
  854.       switch (tolower(p1[0])) {
  855.          case 'a':        /* Append full pathname of destination */
  856.             if (tdir[0]) 
  857.                strcat(temp,tdir);
  858.             else {
  859.                getcwd(fname,_MAX_PATH);
  860.                strcat(temp,fname);
  861.             }
  862.             strcat(temp,"\\");
  863.             if (QWKDir[0]) {
  864.                strcat(temp,QWKDir);
  865.                strcat(temp,"\\");
  866.             }
  867.             strcat(temp,tname);
  868.             break;
  869.  
  870.          case 'p':
  871.             sprintf(portstr,"%d",prm.com_port + 1);        /* Com1 or com2 */
  872.             strcat(temp,portstr);
  873.             break;
  874.  
  875.          case 'b':
  876.             sprintf(portstr,"%d",LastUser.flag);        /* Baudrate */
  877.             strcat(temp,portstr);
  878.             break;
  879.  
  880.          default:
  881.             strcat(temp,p1);
  882.             break;
  883.       }
  884.       p1++;
  885.       if (*p1)
  886.          strcat(temp,p1);
  887.       strcat(temp," ");
  888.       p1 = strtok(NULL,"%");        /* Up to 2nd token */
  889.    }
  890.  
  891.    sprintf(temp1,"\r\n%s file must be in either PkZip,LHARC or ARC format.\r\n",tname);
  892.    strout(temp1);
  893.    strout("Ready to upload REP packet? [Y,n] -> ");
  894.    x = chrin();
  895.    if (isalpha(x))
  896.       x &= 0x00df;        /* Force upper case, toupper() has side effects */
  897.    strout("\r\n");
  898.    if (x == 0x0d)
  899.       x = 'Y';
  900.  
  901.    if (x == 'Y') {
  902.       if (!IsLocal) {
  903.          sprintf(temp1,"Receiving %s packet using %s",tname,upl1->protoname);
  904.          logit(temp1,'=');
  905.          sprintf(temp1,"Prepare to upload %s file using %s \r\n",tname,upl1->protoname);
  906.          strout(temp1);
  907.       }
  908.       else {
  909.          sprintf(temp1,"\nSince you are in local mode here, enter full pathname for %s packet.\r\n",tname);
  910.          strout(temp1);
  911.          strout("And I will copy it over and process it. Include drive also.\r\n");
  912.          timeremain();
  913.          setcolor(TextAttr[PROMPT_TEXT]);
  914.          strout("--> ");
  915.          strin(temp1);
  916.          stripwhite(temp1);
  917.          if (temp1[0]) {
  918.             if(copy2temp(temp1))     {    /* Was it ok? */
  919.                setcolor(TextAttr[ATTN_TEXT]);
  920.                strout("\r\nInvalid filename given.\r\n");
  921.                return FALSE;
  922.             }
  923.             else {
  924.                sprintf(temp,"Receiving %s packet from local user",temp1);
  925.                logit(temp,'=');
  926.                strout("\nWould you like me to delete your REP packet now? ");
  927.                if (getyn(FALSE)) 
  928.                   unlink(temp1);
  929.                return TRUE;
  930.             }
  931.          }
  932.          else return FALSE;
  933.       }
  934.  
  935.       delay_s(2);        /* Make sure string is displayed to user */
  936.  
  937.       printf("Command line: %s %s\n",fname,temp);
  938.  
  939.    /* Execute the protocol engine */
  940.       FossilDeInit();        /* Remove fossil from us */
  941.  
  942.       tempdir();
  943.       if (SwapMode) {
  944.          sprintf(temp1,"Maxmal%02x.swp",Task);
  945.          x = swap(fname,temp,&exec_ret,temp1);
  946.       }
  947.       else {        /* We must do a DOS exec function */
  948.          strcpy(temp1,fname);
  949.          strcat(temp1,temp);
  950.          x = system(temp1);
  951.          exec_ret = (char) x;
  952.       }
  953.  
  954.       homedir();
  955.       FossilInit();        /* Restart fossil for us */
  956.  
  957.       if (x || exec_ret) {
  958.          setcolor(TextAttr[ATTN_TEXT]);
  959.          strout("\r\nOh Oh! Xfer program had some kind of error\r\n");
  960.          sprintf(temp,"Xfer pgm error code: %d, swap error: %d",exec_ret,x);
  961.          logit(temp,'!');
  962.          return(-1);
  963.       }
  964.       else {
  965.          setcolor(TextAttr[HILITE_TEXT]);
  966.          strout("\r\nNo errors occured during transfer.\r\n");
  967.          return(TRUE);
  968.       }
  969.    }
  970.    else return FALSE;
  971. }
  972.  
  973. unsigned get_msgcount(void)
  974. {
  975.    unsigned x;
  976.  
  977.    x = 0;
  978.    msgupd = MSGUPD_1;
  979.    USERCFG.totselareas = 0;        /* Re-do this while we are at it */
  980.    while (msgupd) {
  981.       USERCFG.totselareas++;
  982.       x += msgupd->msgcount;
  983.       msgupd = msgupd->next;
  984.    }
  985.    return x;
  986. }
  987.  
  988. void newuser_help(void)
  989. {
  990.    show_file(NewHelpFil,FALSE);
  991. }
  992.  
  993. /* Display file to user, allow optional escape from display */
  994.  
  995. int show_file(char *strng,int mode)
  996. {
  997.    FILE *newfile;
  998.    int linecount;
  999.    int esc;
  1000.    char ltemp[82];
  1001.    char *p;
  1002.  
  1003.    if (strng[0] == '\0')
  1004.       return(-1);        /* No help file */
  1005.  
  1006.    esc = FALSE;
  1007.    newfile = _fsopen(strng,"r",SH_DENYNO);        /* Open in read only, text mode */
  1008.    if (newfile == NULL) {
  1009.       sprintf(ltemp,"Error opening %s file for user.",strng);
  1010.       logit(ltemp,'!');
  1011.       return(-1);        /* Just skip it */
  1012.    }
  1013.  
  1014.    setcolor(TextAttr[VIEW_TEXT]);
  1015.    linecount = 0;
  1016.    while (!feof(newfile)) {
  1017.       if(fgets(ltemp,80,newfile)) {
  1018.          if (linecount > 21) {        /* Turn on more for paging */
  1019.             setcolor(7);        /* Basic black and white */
  1020.             if (mode) {
  1021.                strout("\r\nPress ESC to stop or any other key for more");
  1022.                if((chrinwait(1) & 0xff) == 0x1b) {        /* Just return */
  1023.                   esc = TRUE;
  1024.                   break;
  1025.                }
  1026.             }
  1027.             else {
  1028.                strout("\r\nPress any key for more");
  1029.                chrinwait(1);
  1030.             }
  1031.             cleareol();
  1032.             strout("\r\n");
  1033.             linecount = 0;
  1034.             setcolor(TextAttr[VIEW_TEXT]);
  1035.          }
  1036.          p = strtok(ltemp,"\n");
  1037.          if (p) 
  1038.             strout(p);
  1039.          cleareol();
  1040.          setcolor(7);        /* Basic black and white */
  1041.          strout("\r\n");
  1042.          setcolor(TextAttr[VIEW_TEXT]);
  1043.          linecount++;
  1044.       }
  1045.    }
  1046.    fclose(newfile);
  1047.    if (!esc) {
  1048.       setcolor(7);        /* Basic black and white */
  1049.       strout("\r\nPress any key to return");
  1050.       chrinwait(1);
  1051.    }
  1052.    cleareol();
  1053.    setcolor(TextAttr[STD_TEXT]);
  1054.    strout("\r\n");
  1055.    return(0);
  1056. }
  1057.  
  1058. /* If mode is TRUE, display message area */
  1059. struct msgupd_st *build1_area(int msgnum,int mode)
  1060. {
  1061.    int keys,mask,x,index;
  1062.    struct msgupd_st *this;
  1063.    struct _aidx IDX;
  1064.  
  1065.    if(is_selarea(msgnum))
  1066.       return NULL;
  1067.    index = sopen(PRM(aidx_name),O_BINARY | O_RDONLY,SH_DENYNO,S_IREAD);
  1068.    if (index == -1)
  1069.       aborterror(FILEOPEN,"Error opening Area index file");
  1070.    lseek(index,(long) (msgnum * sizeof(struct _aidx)),SEEK_SET);
  1071.    if(read(index,(char *)&IDX,sizeof(struct _aidx)) == 0) {
  1072.       close(index);
  1073.       return NULL;
  1074.    }
  1075.    if(fseek(afile,IDX.offset,SEEK_SET) != 0) {
  1076.       close(index);
  1077.       return NULL;
  1078.    }
  1079.    if(fread(&AREA,astrlen,1,afile) != 1) {
  1080.       close(index);
  1081.       return NULL;
  1082.    }
  1083.  
  1084.    mask = 1;
  1085.    for (x=0; x < (msgnum % 16); x++)
  1086.       mask = mask << 1;
  1087.    if (!AREA.msglock)         /* No locks for this area */
  1088.       keys = TRUE;
  1089.    else {        /* User must have same locks */
  1090.       keys = AREA.msglock & LastUser.key;
  1091.       if (keys != (int) AREA.msglock)
  1092.          keys = FALSE;
  1093.    }
  1094.    if (isskiparea(msgnum))
  1095.       keys = FALSE;         /* If Sysop set skip, don't build this area */
  1096.    else if(!check_barareas(&AREA,TRUE))
  1097.       keys = FALSE;
  1098.    if (AREA.msgpath[0] && (LastUser.priv >= AREA.msgpriv) && keys) {
  1099.       this = (struct msgupd_st *) malloc(sizeof(struct msgupd_st));
  1100.       if (this == NULL)
  1101.          aborterror(BADALLOC,NULL);
  1102.       this->areano = msgnum;
  1103.       strcpy(this->msgpath,AREA.msgpath);
  1104.       this->update = FALSE;
  1105.       switch (AREA.area_type) {
  1106.          case 0:        /* Fido 1.msg style */
  1107.             this->himsg = find_fidohigh(AREA.msgpath);
  1108.             break;
  1109.  
  1110.          default:
  1111.             this->himsg = find_fidohigh(AREA.msgpath);
  1112.             break;
  1113.       }
  1114.       this->areaindex = ftell(afile) - (long) astrlen;    /* Position */
  1115.       this->next = NULL;
  1116.       this->readmsgs = 0;
  1117.       this->flags = 0;
  1118.       if (isForcearea(msgnum))
  1119.          this->flags |= AREA_FORCED;
  1120.       this->attribute = (word) AREA.attrib[UserClass];
  1121.       if (mode) {
  1122.          sprintf(temp1,"\rArea %d: ",msgnum);
  1123.          strncat(temp1,AREA.msginfo,55);
  1124.          for (x = 65 - strlen(temp1); x; x-- )
  1125.             strcat(temp1," ");
  1126.          strout(temp1);
  1127.       }
  1128.       this->startmsg = get_lastread(AREA.msgpath);
  1129.       if (this->startmsg < 1)
  1130.          this->startmsg = 1;
  1131.       if (this->startmsg > this->himsg) 
  1132.          this->startmsg = this->himsg;
  1133.       this->msgcount = this->himsg - this->startmsg;
  1134.    }
  1135.    close(index);
  1136.    return this;
  1137. }
  1138.  
  1139.  
  1140.  
  1141. /* Test to see if selected area is barricaded, (Standard OPUS type)
  1142.    if so, get password from user and test to see if it is in file.
  1143.    If password is rejected UNmark area for user and return FALSE */
  1144.  
  1145. /* If MODE is true, this is a new selection. If mode is FALSE,
  1146.     check date on barricaded file, if date is newer than lastcall
  1147.     then process. If mode == -1, check but don't prompt */
  1148.  
  1149. /* Return TRUE if ok to access area, FALSE if not */
  1150. int check_barareas(struct _area *AREA,int mode)
  1151. {
  1152.    FILE *bfile;
  1153.    int count;
  1154.    char *p,*pp;
  1155.  
  1156.    if (AREA->msgbar[0] == 0)        /* No barricade file */
  1157.       return(TRUE);        /* No changes */
  1158.  
  1159.    if (mode == -1)        /* Don't prompt, just skip it */
  1160.       return(FALSE);        /* No changes */
  1161.  
  1162.    if(stat(AREA->msgbar,&fbuf) == 0 ) {        /* File does exist */
  1163.       if (!mode) {        /* Check the date on it */
  1164.          if (fbuf.st_mtime <= USERCFG.lasttime)        /* See if changed since last logon */
  1165.             return(TRUE);        /* No changes */
  1166.       }
  1167.       bfile = _fsopen(AREA->msgbar,"rt",SH_DENYNO);
  1168.       if (bfile == NULL)
  1169.          return(TRUE);
  1170.       p = getfline(bfile);        /* Fetch 1st line */
  1171.       if (p[0] == '!') {        /* This is an EXTENDED barricaded file. Ignore it? */
  1172.          fclose(bfile);
  1173.          return(ExtendOk);        /* Return what sysop configured for ext barr files */
  1174.       }
  1175.       
  1176. /* Okay, now inform the user this is a barricaded file */
  1177.       strncpy(temp1,AREA->msginfo,24);
  1178.       sprintf(temp,"\r\n   Message area: '%s' is a protected area\r\n",temp1);
  1179.       strout(temp);
  1180.       for (count=0; count < 3; count++ ) {        /* Try a password 3 times */
  1181.          strout("   Enter password -> ");
  1182.          strin(temp1);        /* Fetch it */
  1183.          if (!IsLocal)
  1184.             strout("\r\n");
  1185.          stripwhite(temp1);        /* Strip leading and traling space */
  1186.          while (p) {        /* Keep looping through barricaded file till you find it */
  1187.             pp = strtok(p," ");        /* Strip out the password */
  1188.             if (strcmpi(pp,temp1) == 0) {
  1189.                strout("        Password is ok, area is now selected!\r\n");
  1190.                fclose(bfile);
  1191.                return(TRUE);
  1192.             }
  1193.             p = getfline(bfile);        /* Fetch next line */
  1194.          }
  1195.          strout("        Password is rejected. Try again!\r\n");
  1196.          rewind(bfile);        /* Restart at top of barricaded file */
  1197.          p = getfline(bfile);        /* Fetch 1st line again */
  1198.       }
  1199.       fclose(bfile);
  1200.       return(FALSE);        /* Tried 3 times and failed */
  1201.    }
  1202.    else {
  1203.       fclose(bfile);
  1204.       return(TRUE);
  1205.    }
  1206. }
  1207.  
  1208. /* Fetch a line of text from a file. Return NULL if no more
  1209.     text lines. Assume file was opened in text mode. Strip any
  1210.     leading space in the line. */
  1211.  
  1212. char *getfline(FILE *tfile)
  1213. {
  1214.    static char fbuff[90];
  1215.    char *p;
  1216.  
  1217.    p = fgets(fbuff,89,tfile);
  1218.    if (p == NULL)
  1219.       return(NULL);
  1220.  
  1221.    while (*p && isspace(*p))
  1222.       p++;
  1223.    return(p);
  1224. }
  1225.  
  1226. void makearc(char *filename)
  1227. {
  1228.    char fext[5];
  1229.    char *p,*p1;
  1230.    int x,y,old,olderr;
  1231.    static int packertype=0;
  1232.    union REGS regs;
  1233.    struct SREGS sregs;
  1234.  
  1235.    if (IsLocal)
  1236.       ReDirect = FALSE;
  1237.  
  1238.    if (FirstArc) {
  1239.  
  1240.       regs.h.ah = 0x34;
  1241.       intdosx(®s,®s,&sregs);        /* Get the DOS busy flag */
  1242.       Critseg  =   sregs.es;
  1243.       Critoffs =   regs.x.bx;
  1244.  
  1245.       if (FirstArc == -1)  {
  1246.          free(packtemp);
  1247.          free(arccmndline);
  1248.       }
  1249.       packertype = USERCFG.packer;
  1250.       packtemp = (char *) malloc(91);
  1251.       if (packtemp == NULL)
  1252.          aborterror(BADALLOC,NULL);
  1253.       arccmndline = (char *) malloc(91);
  1254.       if (arccmndline == NULL)
  1255.          aborterror(BADALLOC,NULL);
  1256.    }
  1257.  
  1258.    if (!packertype) {    /* Must ask, but fix it so we only ask once */
  1259.       get_packer(FALSE);
  1260.       packertype = USERCFG.packer;
  1261.    }
  1262.  
  1263.    x = USERCFG.packer;
  1264.    USERCFG.packer = (byte) packertype;
  1265.    packer1 = get_curpacklnk();
  1266.    USERCFG.packer = (byte) x;
  1267.  
  1268.    if (FirstArc) {
  1269.       if (ReDirect) {
  1270.          if (prm.com_port <= 3) {        /* Can only redirect to com1,2,3 or 4 */
  1271.       /* Try Gateway device first */
  1272.             sprintf(packtemp,"GATE%d",prm.com_port+1);        /* Make com1,com2 etc */
  1273.             if ((comhandle = open(packtemp,O_RDWR,S_IWRITE)) >= 0) {
  1274.                _asm {
  1275.                   mov   ax,4400h        /* IOCTL device inquire */
  1276.                   mov   dx,comhandle
  1277.                   int   21h
  1278.                   mov   x,dx
  1279.                }
  1280.                if ((x & 0x0080) == 0) {        /* Device bit */
  1281.                   close(comhandle);
  1282.                   comhandle = -1;        /* Disable then if not device */
  1283.                }
  1284.             }
  1285.             else {        /* Nope, then try standard COM devices */
  1286.                sprintf(packtemp,"COM%d",prm.com_port+1);        /* Make com1 or com2 */
  1287.                if ((comhandle = open(packtemp,O_RDWR,S_IWRITE)) >= 0) {
  1288.                   _asm {
  1289.                      mov   ax,4400h  /* IOCTL device inquire */
  1290.                      mov   dx,comhandle
  1291.                      int   21h
  1292.                      mov   x,dx
  1293.                   }
  1294.                   if ((x & 0x0080) == 0) {        /* Device bit */
  1295.                      close(comhandle);
  1296.                      comhandle = -1;        /* Disable then if not device */
  1297.                   }
  1298.                }
  1299.             }
  1300.          }
  1301.       }
  1302.       _splitpath(packer1->packpname,packtemp,packtemp,fname,fext);
  1303.       x = strlen(fname);
  1304.       x = x <= 6 ? x : 6;
  1305.       strncpy(ArcFile,fname,x);
  1306.       ArcFile[x] = '\0';
  1307.  
  1308.       old =  USERCFG.packcount;
  1309.       while (old > 99) 
  1310.          old -= 100;
  1311.       sprintf(packtemp,"%02d",old);
  1312.       strcat(ArcFile,packtemp);
  1313.       strcat(ArcFile,fext);
  1314.  
  1315.       tempdir();
  1316.       while(stat(ArcFile,&fbuf) == 0 ) {     /* Uh oh. File exists! try next one */
  1317.          strncpy(ArcFile,fname,x);
  1318.          ArcFile[x] = '\0';
  1319.          sprintf(packtemp,"%02d",++old);
  1320.          strcat(ArcFile,packtemp);
  1321.          strcat(ArcFile,fext);
  1322.       }
  1323.  
  1324.       homedir();
  1325.  
  1326.       if (SwapMode) {        /* We must use command.com to exec if swapper is on */
  1327.          if (Command) {
  1328.             strcpy(fname,"C:\\command.com");        /* Look for it on boot first */
  1329.             if (!stat(fname,&fbuf)) {        /* Nope, so look in path */
  1330.                _searchenv("Command.com","PATH",fname);
  1331.                if (*fname == '\0') {
  1332.                   if (comhandle >= 0)
  1333.                      close(comhandle);
  1334.                   aborterror(BADEXEC,NULL);
  1335.                }
  1336.             }
  1337.          }
  1338.          else {
  1339.             _searchenv(packer1->packexe,"PATH",fname);
  1340.             if (*fname == '\0') {
  1341.                if (comhandle >= 0)
  1342.                   close(comhandle);
  1343.                logit("Error trying to locate packer program",'!');
  1344.                aborterror(BADEXEC,NULL);
  1345.             }
  1346.             strcpy(arccmndline," ");
  1347.          }
  1348.       }
  1349.       else {
  1350.          strcpy(fname,packer1->packexe);
  1351.          arccmndline[0] = 0;
  1352.       }
  1353.  
  1354.    /* All this junk to parse packer command line and build execute string */
  1355.       strcpy(packtemp,packer1->packstring);
  1356.       p = strtok(packtemp,"%");        /* Up to 1st token */
  1357.       strcat(arccmndline,p);
  1358.       strcat(arccmndline," ");
  1359.       p1 = strtok(NULL,"%");        /* Up to 2nd token */
  1360.       if (tolower(p1[0]) == 'a')     /* Arcfile */
  1361.          strcat(arccmndline,ArcFile);
  1362.       strcat(arccmndline," ");
  1363.    }
  1364.  
  1365.    printf("Command line: %s %s %s\n",fname,arccmndline,filename);
  1366.  
  1367. /* Prepare to execute the packer to arc up the file */
  1368.  
  1369.    tempdir();
  1370.    if (comhandle >= 0) {
  1371.       setcolor(TextAttr[VIEW_TEXT]);
  1372.       old = dup(1);        /* old now refers to stdout */
  1373.       olderr = dup(2);        /* olderr now refers to stderr */
  1374.       if(dup2(comhandle,1) != 0) /* Reroute stdout to com port */
  1375.          comhandle = -1;        /* Some kind of error */
  1376.       else dup2(comhandle,2); /* Reroute stderr to com port */
  1377.    }
  1378.  
  1379.    y = strlen(arccmndline);
  1380.    strcat(arccmndline,filename); /* incoming filename */
  1381.  
  1382. /* Here's the actual DOS exec */
  1383.  
  1384.    if (WatchDog) {
  1385.       OldTimer = _dos_getvect(0x1c);
  1386.       _dos_setvect(0x1c,CheckWatch);
  1387.    }
  1388.  
  1389.    if (SwapMode) {
  1390.       sprintf(packtemp,"Maxmal%02x.swp",Task);
  1391.       x = swap(fname,arccmndline,&exec_ret,packtemp);
  1392.    }
  1393.    else {
  1394.       strcpy(packtemp,fname);
  1395.       strcat(packtemp," ");
  1396.       strcat(packtemp,arccmndline);
  1397.       x = system(packtemp);
  1398.       exec_ret = (char) x;
  1399.    }
  1400.  
  1401.    if (WatchDog) {
  1402.       _dos_setvect(0x1c,OldTimer);
  1403.    }
  1404.  
  1405.    arccmndline[y] = 0;        /* Strip out filename */
  1406.  
  1407.    homedir();
  1408.  
  1409.    if (comhandle >= 0) {
  1410.       dup2(old,1);        /* Restore stdout */
  1411.       dup2(olderr,2);        /* Restore stderr */
  1412.       setcolor(TextAttr[STD_TEXT]);
  1413.    }
  1414.  
  1415.    check_carrier();
  1416.  
  1417.    if (x || exec_ret) {
  1418.       setcolor(TextAttr[ATTN_TEXT]);
  1419.       strout("\r\nOh Oh! Packer had some kind of error\r\n");
  1420.       strout("Shipping you back to Maximus!\r\n\r\n");
  1421.       sprintf(packtemp,"Packer error code: %d, swap error: %d",exec_ret,x);
  1422.       logit(packtemp,'!');
  1423.       if (comhandle >= 0)
  1424.          close(comhandle);
  1425.       aborterror(BADEXEC,"Error executing packer program");
  1426.    }
  1427.  
  1428.    if (FirstArc)
  1429.       FirstArc = FALSE;
  1430. }
  1431.  
  1432.  
  1433. int extractarc(char *name)
  1434. {
  1435.    char *p,*p1;
  1436.    int x,old,olderr;
  1437.    char *extractemp;
  1438.    char *cmndline;
  1439.    static char tname[13];
  1440.    static struct reparc_st *reparc1;
  1441.  
  1442.    if (IsLocal)
  1443.       ReDirect = FALSE;
  1444.  
  1445. /* We need to figure out what type of archive it is */
  1446.  
  1447.    strcpy(tname,name);
  1448.  
  1449.    extractemp = (char *) malloc(91);
  1450.    if (extractemp == NULL)
  1451.       aborterror(BADALLOC,NULL);
  1452.    cmndline = (char *) malloc(91);
  1453.    if (cmndline == NULL)
  1454.       aborterror(BADALLOC,NULL);
  1455.  
  1456.    x = sopen(tname,O_BINARY | O_RDONLY,SH_DENYNO,S_IREAD);
  1457.    if (x < 0)
  1458.       return -1;        /* Some kind of error */
  1459.  
  1460. /* Look at first few bytes */
  1461.    read(x,extractemp,10);        /* Read 10 bytes */
  1462.    strncpy(cmndline,extractemp,2);
  1463.    cmndline[2] = 0;
  1464.    if (strcmp(cmndline,"PK") == 0)         /* Is it ZIP? */
  1465.       reparc1 = ZIPREP;
  1466.    else {
  1467.       strncpy(cmndline,extractemp+2,3);
  1468.       cmndline[3] = 0;
  1469.       if (strcmp(cmndline,"-lh") == 0) /* Is it LHA? */
  1470.          reparc1 = LHAREP;
  1471.       else reparc1 = ARCREP;
  1472.    }
  1473.    close(x);
  1474.  
  1475.  
  1476.    if (ReDirect) {
  1477.       if (prm.com_port <= 3) {        /* Can only redirect to com1,2,3 or 4 */
  1478.    /* Try Gateway device first */
  1479.          sprintf(extractemp,"GATE%d",prm.com_port+1);        /* Make com1,com2 etc */
  1480.          if (comhandle == -1) {
  1481.             if ((comhandle = open(extractemp,O_RDWR,S_IWRITE)) >= 0) {
  1482.                _asm {
  1483.                   mov   ax,4400h        /* IOCTL device inquire */
  1484.                   mov   dx,comhandle
  1485.                   int   21h
  1486.                   mov   x,dx
  1487.                }
  1488.                if ((x & 0x0080) == 0) {        /* Device bit */
  1489.                   close(comhandle);
  1490.                   comhandle = -1;        /* Disable then if not device */
  1491.                }
  1492.             }
  1493.             else {        /* Nope, then try standard COM devices */
  1494.                sprintf(extractemp,"COM%d",prm.com_port+1);        /* Make com1 or com2 */
  1495.                if ((comhandle = open(extractemp,O_RDWR,S_IWRITE)) >= 0) {
  1496.                   _asm {
  1497.                      mov   ax,4400h  /* IOCTL device inquire */
  1498.                      mov   dx,comhandle
  1499.                      int   21h
  1500.                      mov   x,dx
  1501.                   }
  1502.                   if ((x & 0x0080) == 0) {        /* Device bit */
  1503.                      close(comhandle);
  1504.                      comhandle = -1;        /* Disable then if not device */
  1505.                   }
  1506.                }
  1507.             }
  1508.          }
  1509.       }
  1510.    }
  1511.  
  1512.    if (SwapMode) {        /* We must use command.com to exec if swapper is on */
  1513.       if (Command) {
  1514.          strcpy(fname,"C:\\command.com");        /* Look for it on boot first */
  1515.          if (!stat(extractemp,&fbuf)) {        /* Nope, so look in path */
  1516.             _searchenv("Command.com","PATH",fname);
  1517.             if (*fname == '\0') {
  1518.                if (comhandle >= 0)
  1519.                   close(comhandle);
  1520.                aborterror(BADEXEC,"No command.com");
  1521.             }
  1522.          }
  1523.          sprintf(cmndline," /c %s",reparc1->packexe);
  1524.       }
  1525.       else {
  1526.          _searchenv(reparc1->packexe,"PATH",fname);
  1527.          if (*fname == '\0') {
  1528.             if (comhandle >= 0)
  1529.                close(comhandle);
  1530.             aborterror(BADEXEC,NULL);
  1531.          }
  1532.          strcpy(cmndline," ");
  1533.       }
  1534.    }
  1535.    else {
  1536.       strcpy(fname,reparc1->packexe);
  1537.       cmndline[0] = 0;
  1538.    }
  1539.  
  1540. /* All this junk to parse packer command line and build execute string */
  1541.    strcpy(extractemp,reparc1->packstring);
  1542.    p = strtok(extractemp,"%");        /* Up to 1st token */
  1543.    strcat(cmndline,p);
  1544.    strcat(cmndline," ");
  1545.    p1 = strtok(NULL,"\r\n");
  1546.    if (tolower(p1[0]) == 'a') /* Arcfile name */
  1547.       strcat(cmndline,tname);
  1548.    strcat(cmndline," ");
  1549.  
  1550.    printf("Command line: %s %s\n",fname,cmndline);
  1551.  
  1552. /* Prepare to execute the packer to extract the file */
  1553.  
  1554.    if (comhandle >= 0) {
  1555.       setcolor(TextAttr[VIEW_TEXT]);
  1556.       old = dup(1);        /* old now refers to stdout */
  1557.       olderr = dup(2);        /* olderr now refers to stderr */
  1558.       if(dup2(comhandle,1) != 0) /* Reroute stdout to com port */
  1559.          comhandle = -1;        /* Some kind of error */
  1560.       else dup2(comhandle,2); /* Reroute stderr to com port */
  1561.    }
  1562.  
  1563.  
  1564. /* Here's the actual DOS exec */
  1565.  
  1566.    if (SwapMode) {
  1567.       sprintf(extractemp,"Maxmal%02x.swp",Task);
  1568.       x = swap(fname,cmndline,&exec_ret,extractemp);
  1569.    }
  1570.    else {
  1571.       strcpy(extractemp,fname);
  1572.       strcat(extractemp," ");
  1573.       strcat(extractemp,cmndline);
  1574.       x = system(extractemp);
  1575.       exec_ret = (char) x;
  1576.    }
  1577.  
  1578.    if (comhandle >= 0) {
  1579.       dup2(old,1);        /* Restore stdout */
  1580.       dup2(olderr,2);        /* Restore stderr */
  1581.    }
  1582.  
  1583.    check_carrier();
  1584.  
  1585.    old = 0;
  1586.  
  1587.    if (x || exec_ret) {
  1588.       setcolor(TextAttr[ATTN_TEXT]);
  1589.       strout("\r\nOh Oh! Packer had some kind of error\r\n");
  1590.       sprintf(extractemp,"Packer error code: %d, swap error: %d",exec_ret,x);
  1591.       logit(extractemp,'!');
  1592.       old = 1;
  1593.    }
  1594.    free(extractemp);
  1595.    free(cmndline);
  1596.    if (comhandle >= 0)
  1597.       setcolor(TextAttr[STD_TEXT]);
  1598.    return old;
  1599. }
  1600.  
  1601.  
  1602. #pragma check_stack( off )
  1603. #pragma check_pointer( off )
  1604. #pragma intrinsic( _enable, _disable )
  1605.  
  1606. void _interrupt _far CheckWatch(void)
  1607. {
  1608.    _asm {        /* Check carrier */
  1609.       mov   bx, OFFSET prm
  1610.       mov   dx,[bx]prm.com_port
  1611.       mov   ah,3        /* Get modem status */
  1612.       int   14h
  1613.       test  al,80h
  1614.       jnz   leave1        /* Everything's fine */
  1615.  
  1616.       push  es
  1617.       mov   ax,Critseg
  1618.       mov   es,ax
  1619.       mov   bx,Critoffs
  1620.       mov   ax,es:[bx]
  1621.       pop   es
  1622.       cmp   ax,0
  1623.       jnz   leave1
  1624.  
  1625.       mov   ax,4c01h        /* Force a drop out */
  1626.       int   21h
  1627.  
  1628.       leave1:
  1629.    }
  1630.  
  1631.    _chain_intr(OldTimer);
  1632. }
  1633.  
  1634.