home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / MXMS_160.LZH / CONFIG.C next >
C/C++ Source or Header  |  1991-06-23  |  42KB  |  1,307 lines

  1. /****************************************************************************/
  2. /*                                                                          */
  3. /*    Config.c    User configuration routines for Maxmail                   */
  4. /*                                                                          */
  5. /****************************************************************************/
  6.  
  7. #include "MaxMail.h"
  8.  
  9. int _FAR_ _cdecl inp(unsigned);
  10. int _FAR_ _cdecl outp(unsigned, int);
  11.  
  12. int msgnum,handle,areas_sel;
  13. int Usercount;
  14. char msgstr[81];
  15. struct user_cfg uscfg;
  16. struct msgupd_st *msgupd;
  17. struct msgupd_st *prev;
  18.  
  19. #define TIMERMODE 182        /* code to put timer in right mode */
  20. #define FREQSCALE 1190000L    /* basic time frequency in hertz   */
  21. #define TIMESCALE 1230L        /* number of counts in 0.1 second  */
  22. #define T_MODEPORT 67        /* port controls timer mode        */
  23. #define FREQPORT   66        /* port controls tone frequency    */
  24. #define BEEPPORT   97        /* port controls speaker           */
  25. #define ON         79        /* signal to turn speaker on       */
  26.  
  27. void configmenu(void)
  28. {
  29.    int choice = TRUE;
  30.    char resp;
  31.    int good,x;
  32.    struct packer_st *pack1;
  33.    struct proto_st  *proto1;
  34.  
  35.    do
  36.    {
  37.       clearscreen();
  38.       proto1 = get_curprotolnk();
  39.       pack1 = get_curpacklnk();
  40.       setcolor(TextAttr[STD_TEXT]);
  41.       strout("\r\nMaxMail configuration menu\r\n");
  42.       strout("----------------------------------------------------\r\n");
  43.       setcolor(TextAttr[MENU_KEY]);
  44.       strout("[A]dd message areas\r\n");
  45.       if (USERCFG.totselareas) {
  46.          setcolor(TextAttr[MENU_KEY]);
  47.          strout("[D]elete message areas\r\n");
  48.          strout("[E]rase all current selected message areas\r\n");
  49.       }
  50.       setcolor(TextAttr[MENU_KEY]);
  51.       strout("[H]ang up after download            :");
  52.       setcolor(TextAttr[HILITE_TEXT]);
  53.       if (USERCFG.flags & DLHANGUP)
  54.          strout(" Always, if sysop has it enabled\r\n");
  55.       else strout(" Ask every time\r\n");
  56.       setcolor(TextAttr[MENU_KEY]);
  57.       strout("[L]ist message areas                :");
  58.       setcolor(TextAttr[HILITE_TEXT]);
  59.       if (USERCFG.totselareas)
  60.          sprintf(temp," Currently, %d selected\r\n",USERCFG.totselareas);
  61.       else strcpy(temp," No message areas are currently selected\r\n");
  62.       strout(temp);
  63.       setcolor(TextAttr[MENU_KEY]);
  64.       strout("[M]essage style                     :");
  65.       setcolor(TextAttr[HILITE_TEXT]);
  66.       if (USERCFG.msgfrmt == 1)
  67.          strout(" QWK\r\n");
  68.       else strout(" Standard Text\r\n");
  69.       setcolor(TextAttr[MENU_KEY]);
  70.       strout("[N]ewfiles list included            :");
  71.       setcolor(TextAttr[HILITE_TEXT]);
  72.       if (USERCFG.flags & NEWFILES_INC)
  73.          strout(" Yes\r\n");
  74.       else strout(" No\r\n");
  75.       setcolor(TextAttr[MENU_KEY]);
  76.       strout("[P]acking method                    :");
  77.       setcolor(TextAttr[HILITE_TEXT]);
  78.       if (USERCFG.packer)
  79.          sprintf(temp," %s\r\n",pack1->packname);
  80.       else strcpy(temp," NONE, always ask.\r\n");
  81.       setcolor(TextAttr[HILITE_TEXT]);
  82.       strout(temp);
  83.       if (USERCFG.msgfrmt == 1) {
  84.          setcolor(TextAttr[MENU_KEY]);
  85.          strout("[T]otal messages packed per area    :");
  86.          setcolor(TextAttr[HILITE_TEXT]);
  87.          if (USERCFG.maxareamsgs == 0)
  88.             strout(" ALL\r\n");
  89.          else {
  90.             sprintf(temp," %u\r\n",USERCFG.maxareamsgs);
  91.             strout(temp);
  92.          }
  93.       }
  94.       setcolor(TextAttr[MENU_KEY]);
  95.       strout("[X]fer protocol                     :");
  96.       if (USERCFG.protocol)
  97.          sprintf(temp," %s\r\n",proto1->protoname);
  98.       else strcpy(temp," NONE, always ask.\r\n");
  99.       setcolor(TextAttr[HILITE_TEXT]);
  100.       strout(temp);
  101.       strout("\r\n");
  102.       setcolor(TextAttr[STD_TEXT]);
  103.       strout("[Q]uit to main menu\r\n");
  104.       good = FALSE;
  105.       strout("\r\n");
  106.       while (!good) {
  107.          timeremain();
  108.          setcolor(TextAttr[PROMPT_TEXT]);
  109.          strout("Choice --> ");
  110.          ChatOk = TRUE;
  111.          x = chrin();
  112.          ChatOk = FALSE;
  113.          resp = (char) x;
  114.          if(resp == '\r')
  115.             resp = '0';
  116.          good = TRUE;
  117.          chrout(resp);
  118.          strout("\r\n");
  119.          setcolor(TextAttr[STD_TEXT]);
  120.          switch (toupper((int) resp)) {
  121.             case 'A':        /* add message areas */
  122.                add_msgareas();
  123.                break;
  124.  
  125.             case 'D':        /* delete message areas */
  126.                if (USERCFG.totselareas) 
  127.                   del_msgareas();
  128.                break;
  129.  
  130.             case 'E':        /* Erase all current message areas */
  131.                if (!USERCFG.totselareas)
  132.                   break;
  133.                setcolor(TextAttr[HILITE_TEXT]);
  134.                strout("\r\nAre you sure you wish to erase ALL your currently select message areas?\r\n");
  135.                if (getyn(TRUE)) {
  136.                   memset(&USERCFG.msgarea,0,64);        /* Clear out table */
  137.                   USERCFG.totselareas = 0;
  138.                   msgupd = MSGUPD_1;
  139.                   while (msgupd) {
  140.                      prev = msgupd->next;
  141.                      free(msgupd);
  142.                      msgupd = prev;
  143.                   }
  144.                   MSGUPD_1 = NULL;
  145.                }
  146.                break;
  147.  
  148.             case 'H':        /* Toggle hangup after download */
  149.                USERCFG.flags ^= DLHANGUP;
  150.                break;
  151.  
  152.             case 'L':        /* List msg areas */
  153.                strout("\r\nCurrently selected areas:\r\n\r\n");
  154.                show_areas(FALSE);
  155.                presskey();
  156.                break;
  157.  
  158.             case 'M':        /* Change message format */
  159.                get_msgtype();
  160.                break;
  161.  
  162.             case 'N':        /* Get newfiles type */
  163.                USERCFG.flags ^= NEWFILES_INC;
  164.                break;
  165.  
  166.             case 'P':        /* change packer type */
  167.                get_packer(TRUE);
  168.                break;
  169.  
  170.             case 'Q':
  171.                choice = FALSE;
  172.                break;
  173.  
  174.             case 'T':
  175.                if (USERCFG.msgfrmt == 1) 
  176.                   get_totperarea();
  177.                break;
  178.  
  179.             case 'X':        /* Change download protocol */
  180.                get_proto(TRUE);
  181.                break;
  182.  
  183.             case '!':
  184.             case '0':        /* Redisplay */
  185.                break;
  186.          }
  187.       }
  188.    }
  189.    while (choice);
  190.  
  191.    x = USRCFG_UPD;
  192.    x ^= 0xffff;
  193.    USERCFG.flags &= x;        /* Turn off update flags */
  194.    x = USRCFG_FUPD;
  195.    x ^= 0xffff;
  196.    USERCFG.flags &= x;        /* Turn off forced update flags */
  197. }
  198.  
  199. void getconfig(void)
  200. {
  201.    areas_sel = FALSE;
  202.  
  203.     /* Now ask user to set up message areas to read */
  204.    if (USERCFG.flags & USRCFG_MSGUPD  && !newuser) {
  205.       setcolor(TextAttr[ATTN_TEXT]);
  206.       strout("\r\nSysop has changed available message areas. You are required to redo\r\n");
  207.       strout("your areas selection again,sorry.");
  208.       presskey();
  209.       memset(&USERCFG.msgarea,0,64);        /* Clear out table */
  210.       USERCFG.totselareas = 0;
  211.       msgupd = MSGUPD_1;
  212.       while (msgupd) {
  213.          prev = msgupd->next;
  214.          free(msgupd);
  215.          msgupd = prev;
  216.       }
  217.       MSGUPD_1 = NULL;
  218.       MarkForce();
  219.       add_msgareas();
  220.    }
  221.  
  222.    if (newuser) {
  223.       MarkForce();
  224.       add_msgareas();
  225.       get_msgtype();
  226.       if (USERCFG.msgfrmt == 1) 
  227.          get_totperarea();
  228.       get_packer(TRUE);
  229.       get_proto(TRUE);
  230.    }
  231.    else if (USERCFG.flags & USRCFG_FUPD) {
  232.       setcolor(TextAttr[ATTN_TEXT]);
  233.       strout("\r\nSorry, but the Sysop needs you to re-do your configuration again.");
  234.       presskey();
  235.       memset(&USERCFG.msgarea,0,64);        /* Clear out table */
  236.       USERCFG.totselareas = 0;
  237.       msgupd = MSGUPD_1;
  238.       while (msgupd) {
  239.          prev = msgupd->next;
  240.          free(msgupd);
  241.          msgupd = prev;
  242.       }
  243.       MSGUPD_1 = NULL;
  244.       MarkForce();
  245.       configmenu();
  246.    }
  247. }
  248.  
  249. void list_config()
  250. {
  251.    struct packer_st *pack1;
  252.    struct proto_st  *proto1;
  253.  
  254.    strout("\r\nYour current MaxMail configuration\r\n");
  255.    strout("-------------------------------------------------------\r\n");
  256.  
  257.    strout("Message areas selected:\r\n");
  258.    show_areas(FALSE);
  259.    proto1 = get_curprotolnk();
  260.    pack1 = get_curpacklnk();
  261.  
  262.    strout("-------------------------------------------------------\r\n");
  263.    if (USERCFG.msgfrmt == 1) 
  264.       strout("Message Format: QWK");
  265.    else strout("Message Format: Standard text");
  266.    if (USERCFG.maxareamsgs) {
  267.       sprintf(temp,"\r\nYou will pack up a maximum of %u messages per area",USERCFG.maxareamsgs);
  268.       strout(temp);
  269.    }
  270.    else strout("\r\nYou will pack up ALL new messages in each area, if possible");
  271.    if (USERCFG.flags & NEWFILES_INC)
  272.       strout("\r\nYou are including a newfiles listing in your mail packet");
  273.    if (USERCFG.protocol)
  274.       sprintf(temp,"\r\nDefault protocol: %s\r\n",proto1->protoname);
  275.    else strcpy(temp,"\r\nDefault protocol: NONE, always ask.\r\n");
  276.    strout(temp);
  277.    if (USERCFG.packer)
  278.       sprintf(temp,"Default packer: %s\r\n",pack1->packname);
  279.    else strcpy(temp,"Default packer: NONE, always ask.\r\n");
  280.    strout(temp);
  281.    if (USERCFG.flags & DLHANGUP) {
  282.       strcpy(temp,"You have turned on automatic Hangup after download\r\n");
  283.       strout(temp);
  284.    }
  285.    strout("-------------------------------------------------------\r\n");
  286.    presskey();
  287. }
  288.  
  289. int new_user(int filenum)
  290. {
  291.    int x,y;
  292.  
  293.    x = 0;
  294.    USERCFG.flags |= USRCFG_UPD;        /* Force the user to update his configuration */
  295.  
  296. /* Seek to start of file and count records */
  297.    if(lseek(filenum,0L,SEEK_SET) >= 0L)     {    /* Rewind to begginning */
  298.       y = read(filenum,(char *) &uscfg,sizeof(struct user_cfg));
  299.       while (y == sizeof(struct user_cfg)) {
  300.          x++;        /* Simple count */
  301.          y = read(filenum,(char *) &uscfg,sizeof(struct user_cfg));
  302.       }
  303.    }
  304.    return(x);
  305. }
  306.  
  307. void update_usercfg(int filenum)
  308. {
  309.    lseek(filenum,(long) (UserCfgnum * sizeof(struct user_cfg)),SEEK_SET);        /* Append to tail of file */
  310.    write(filenum,(struct user_cfg *) &USERCFG,sizeof(struct user_cfg));
  311. }
  312.  
  313. /* Convert message number to bitmap location and turn it on */
  314. void msgmark(int num)
  315. {
  316.    word *bitp;
  317.    int x,mask;
  318.  
  319.    if (isskiparea(num))
  320.       return;
  321.    
  322.    bitp = &USERCFG.msgarea[num / 16];        /* Point to proper slot, 16 bits per slot */
  323.    mask = 1;
  324.    for (x=0; x < (num % 16); x++)
  325.       mask = mask << 1;
  326.    *bitp = *bitp | mask;        /* Turn it on */
  327.    areas_sel = TRUE;
  328.    return;
  329. }
  330.  
  331. /* Convert message number to bitmap location and turn it off */
  332. void msgunmark(int num)
  333. {
  334.    word *bitp;
  335.    int x,mask;
  336.    
  337.    bitp = &USERCFG.msgarea[num / 16];        /* Point to proper slot, 16 bits per slot */
  338.    mask = 1;
  339.    for (x=0; x < (num % 16); x++)
  340.       mask = mask << 1;
  341.    mask ^= 0xffff;
  342.    *bitp = *bitp & mask;        /* Turn it off */
  343.    return;
  344. }
  345.  
  346.  
  347. int screen_areas(int flag)
  348. {
  349.    int  x,keys,col;
  350.    int  msgpos,anum,index;
  351.    int  areas;
  352.    struct _aidx IDX;
  353.  
  354.    index = sopen(PRM(aidx_name),O_BINARY | O_RDONLY,SH_DENYNO,S_IREAD);
  355.    if (index == -1)
  356.       aborterror(FILEOPEN,"Error opening Area index file");
  357.    keys = read(index,(char *)&IDX,sizeof(struct _aidx));
  358.    fseek(afile,IDX.offset,SEEK_SET);
  359.    fread(&AREA,astrlen,1,afile);
  360.    areas = 0;
  361.    anum = 0;
  362.    while (keys) {
  363.       msgpos = 0;
  364.       col = 0;
  365.       while (keys && (msgpos < 20)) {
  366.          keys = AREA.msglock;
  367.          if (!keys)         /* No locks for this area */
  368.             keys = TRUE;
  369.          else {        /* User must have same locks */
  370.             keys = AREA.msglock & LastUser.key;
  371.             if (keys != (int) AREA.msglock)
  372.                keys = FALSE;
  373.          }
  374.          x = atoi(AREA.name);        /* Get Message area */
  375.          if (isskiparea(anum))
  376.             keys = FALSE;         /* If Sysop set skip, don't show this area */
  377.          if (AREA.msgpath[0] && (LastUser.priv >= AREA.msgpriv) && keys ) {
  378.             if (flag) {        /* If true show areas we don't already have selected */
  379.                if (is_selarea(anum)) {        /* We already have this area */
  380.                   keys = read(index,(char *)&IDX,sizeof(struct _aidx));
  381.                   fseek(afile,IDX.offset,SEEK_SET);
  382.                   fread(&AREA,astrlen,1,afile);
  383.                   anum++;
  384.                   continue;
  385.                }
  386.             }
  387.             areas++;
  388.             if (!col) {     /* 1st column */
  389.                strncpy(temp,AREA.msginfo,20);
  390.                temp[20] = 0;
  391.                sprintf(msgstr,"[%d] %s",anum,temp);
  392.                x = strlen(msgstr);
  393.                while (x++ < 26) 
  394.                   strcat(msgstr," ");        /* Pad it for formatting */
  395.             }
  396.             else {        /* 2nd or 3rd column */
  397.                strncpy(temp1,AREA.msginfo,20);
  398.                temp1[20] = 0;
  399.                sprintf(temp,"[%d] %s",anum,temp1);
  400.                x = strlen(temp);
  401.                while (x++ < 26) 
  402.                   strcat(temp," ");        /* Pad it for formatting */
  403.                strcat(msgstr,temp);
  404.                if (col == 2) {
  405.                   strcat(msgstr,"\r\n");
  406.                   setcolor(TextAttr[STD_TEXT]);
  407.                   strout(msgstr);
  408.                   msgpos++;        /* Another row is spit out */
  409.                   col = -1;
  410.                }
  411.             }
  412.             col++;
  413.          }
  414.          keys = read(index,(char *)&IDX,sizeof(struct _aidx));
  415.          fseek(afile,IDX.offset,SEEK_SET);
  416.          fread(&AREA,astrlen,1,afile);        /* Read next area */
  417.          anum++;
  418.       }
  419.       if (col) {        /* Some message areas left */
  420.          setcolor(TextAttr[STD_TEXT]);
  421.          strcat(msgstr,"\r\n");
  422.          strout(msgstr);
  423.       }
  424.       if (keys) {        /* More areas than a pageful */
  425.          setcolor(TextAttr[PROMPT_TEXT]);
  426.          strout("\r\nMore areas?  ");
  427.          if (getyn(FALSE)) {
  428.             strout("\r\n");
  429.             continue;
  430.          }
  431.          else break;
  432.       }
  433.       else break;
  434.    }
  435.    close(index);
  436.    setcolor(TextAttr[STD_TEXT]);
  437.    return areas;
  438. }
  439.  
  440. void get_proto(int flag)
  441. {
  442.    byte x;
  443.    char *p;
  444.  
  445.    setcolor(TextAttr[HILITE_TEXT]);
  446.    strout("\r\n\r\nEnter default protocol to use\r\n");
  447.    strout("-----------------------------\r\n");
  448.    setcolor(TextAttr[MENU_KEY]);
  449.    display_protos();
  450.    if (flag)
  451.       strout("[0] Always ask\r\n");
  452.    while (1) {
  453.       timeremain();
  454.       setcolor(TextAttr[PROMPT_TEXT]);
  455.       strout("--> ");
  456.       strin(msgstr);
  457.       if (!IsLocal)
  458.          strout("\r\n");
  459.       p = strtok(msgstr," \r");
  460.       if (!(isdigit(*p)) && p != NULL) {
  461.          setcolor(TextAttr[ATTN_TEXT]);
  462.          strout("You must enter digits only!\r\n");
  463.          continue;
  464.       }
  465.       x = (byte) atoi(p);
  466.       if ((int) x <= totprotocols) {
  467.          if (flag)         /* Allow 0(Always Ask) */
  468.             break;
  469.          if (!flag && x != 0)
  470.             break;
  471.       }
  472.    }
  473.    USERCFG.protocol = x;
  474.  
  475.    USERCFG.totprotos = totprotocols;
  476. }
  477.  
  478. void get_packer(int flag)
  479. {
  480.    byte x;
  481.    char *p;
  482.  
  483.    x = 0;
  484.    setcolor(TextAttr[HILITE_TEXT]);
  485.    strout("\r\n\r\nEnter packing method you wish to use\r\n");
  486.    strout("------------------------------------\r\n");
  487.    setcolor(TextAttr[MENU_KEY]);
  488.    display_packers();
  489.    if (flag)
  490.       strout("[0] Always ask\r\n");
  491.    while (1) {
  492.       timeremain();
  493.       setcolor(TextAttr[PROMPT_TEXT]);
  494.       strout("--> ");
  495.       strin(msgstr);
  496.       if (!IsLocal)
  497.          strout("\r\n");
  498.       p = strtok(msgstr," \r");
  499.       if (!(isdigit(*p)) && p != NULL) {
  500.          setcolor(TextAttr[ATTN_TEXT]);
  501.          strout("You must enter digits only!\r\n");
  502.          continue;
  503.       }
  504.       x = (byte) atoi(p);
  505.       if ((int) x <= totpackers ) {
  506.          if (flag)         /* Allow 0(Always Ask) */
  507.             break;
  508.          if (!flag && x != 0) 
  509.             break;
  510.       }
  511.    }
  512.  
  513.    if (USERCFG.packer != x && PackDone) {
  514.       PackDone = FALSE;
  515.       erase_arc();
  516.       msgupd = MSGUPD_1;
  517.       while (msgupd) {
  518.          msgupd->update = FALSE;
  519.          msgupd = msgupd->next;
  520.       }
  521.    }
  522.    USERCFG.packer = x;
  523.    USERCFG.totpackers = totpackers;
  524. }
  525.  
  526. int reset_config(word flag)
  527. {
  528.    int x;
  529.    long pos;
  530.  
  531.    Usercount = 0;
  532.    x = sopen(CfgFile,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IWRITE);
  533.    if (x == -1) {
  534.       strout("\r\nError opening config file! Try later.\r\n");
  535.       return(FALSE);
  536.    }
  537.    logit("Sysop is reseting all current users",'#');
  538.    lseek(x,0L,SEEK_SET);        /* Rewind to begginning */
  539.    read(x,(char *) &uscfg,sizeof(struct user_cfg));
  540.    while (!eof(x)) {
  541.       pos = tell(x) - (long) sizeof(struct user_cfg);    /* Get position */
  542.       if (uscfg.name[0]) {
  543.          Usercount++;
  544.          uscfg.flags |= flag;
  545.          lseek(x,pos,SEEK_SET);     /* Rewind back to this record */
  546.          write(x,(struct user_cfg *) &uscfg,sizeof(struct user_cfg));
  547.       }
  548.       read(x,(char *) &uscfg,sizeof(struct user_cfg)); /* Next record */
  549.    }
  550.    close(x);
  551.    return(TRUE);
  552. }
  553.  
  554. int delete_users(void)
  555. {
  556.    int x,User;
  557.    char *p1;
  558.    struct user_cfg USCFG;
  559.  
  560.    if (test_task()) {
  561.       setcolor(TextAttr[ATTN_TEXT]);
  562.       strout("\r\nSorry, but someone else is using MaxMail currently. Try later!\r\n");
  563.    }
  564.    setcolor(TextAttr[STD_TEXT]);
  565.    strout("Enter user's name ---> ");
  566.    strin(temp);
  567.    if (!IsLocal)
  568.       strout("\r\n");
  569.    p1 = strtok(temp,"\t\r\n");
  570.    if (p1) {
  571.       if (strcmpi(p1,LastUser.name) == 0) {
  572.          setcolor(TextAttr[ATTN_TEXT]);
  573.          strout("Whoah there pardner! You can't delete yourself!\r\n");
  574.          return FALSE;
  575.       }
  576.       x = sopen(CfgFile,O_RDWR | O_BINARY | O_CREAT,SH_DENYNO,S_IWRITE);
  577.       if (x == -1)
  578.          aborterror(FILEOPEN,"Error opening/creating User config file");
  579.       User = find_config(x,p1,&USCFG);
  580.       if (User < 0) {
  581.          setcolor(TextAttr[ATTN_TEXT]);
  582.          strout("Sorry but that user name does not exist.\r\n");
  583.       }
  584.       else {
  585.          strout("User is now being deleted.\r\n");
  586.          sprintf(temp1,"Sysop is deleting user: %s",p1);
  587.          logit(temp1,'#');
  588.          memset(USCFG.name,0,36);        /* Delete */
  589.          lseek(x,(long) User * sizeof(struct user_cfg),SEEK_SET);
  590.          write(x,(struct user_cfg *) &USCFG,sizeof(struct user_cfg));
  591.       }
  592.       close(x);
  593.    }
  594.    return(TRUE);
  595. }
  596.  
  597. void user_stats()
  598. {
  599.    int x,row,handle,y;
  600.    byte z;
  601.    struct tm  *newtime;
  602.    char ttemp[40];
  603.    char *month;
  604.    char *day;
  605.    struct packer_st *packer1;
  606.    struct proto_st *proto1;
  607.  
  608.    setcolor(TextAttr[STD_TEXT]);
  609.    if (!Usercount) {        /* We have to count the active users */
  610.       EmptyRecs = 0;
  611.       handle = sopen(CfgFile,O_RDWR | O_BINARY,SH_DENYNO,S_IREAD);
  612.       if (handle == -1) {
  613.          setcolor(TextAttr[ATTN_TEXT]);
  614.          strout("\r\nError opening config file! Try later.\r\n");
  615.          return;
  616.       }
  617.       y = read(handle,(char *) &uscfg,sizeof(struct user_cfg));
  618.       while (y == sizeof(struct user_cfg)) {
  619.          if (uscfg.name[0])
  620.             Usercount++;
  621.          else{
  622.             EmptyRecs++;
  623.          }
  624.          y = read(handle,(char *) &uscfg,sizeof(struct user_cfg));
  625.       }
  626.       lseek(handle,0L,SEEK_SET);        /* Rewind file */
  627.    }
  628.    else {
  629.       handle = sopen(CfgFile,O_RDWR | O_BINARY,SH_DENYNO,S_IREAD);
  630.       if (handle == -1) {
  631.          strout("\r\nError opening config file! Try later.\r\n");
  632.          return;
  633.       }
  634.    }
  635.    sprintf(temp,"\r\nCurrently, there are %d active users for MaxMail.\r\n",Usercount);
  636.    setcolor(TextAttr[HILITE_TEXT]);
  637.    strout(temp);
  638.    if (EmptyRecs) {
  639.       sprintf(temp,"There are %d empty records in the user file. Use the Pack function to clean.\r\n",EmptyRecs);
  640.       strout(temp);
  641.    }
  642.  
  643. /* Read all the users and display pertinent data */
  644.  
  645.    y = read(handle,(char *) &uscfg,sizeof(struct user_cfg));
  646.    while (y == sizeof(struct user_cfg)) {
  647.       setcolor(TextAttr[STD_TEXT]);
  648.       strout("__________________________________________________________________________\r\n");
  649.       strout("User Name          Lasttime  Frmt Calls Packs  Packer  Protocol  Flags\r\n");
  650.       strout("--------------------------------------------------------------------------\r\n");
  651.       row = 3;
  652.       setcolor(TextAttr[HILITE_TEXT]);
  653.       while (row < 23 && y == sizeof(struct user_cfg)) {
  654.          while (uscfg.name[0] == 0 && y == sizeof(struct user_cfg)) 
  655.             y = read(handle,(char *) &uscfg,sizeof(struct user_cfg));
  656.          if (y != sizeof(struct user_cfg)) 
  657.             break;
  658.          strncpy(temp,uscfg.name,15);
  659.          temp[15] = 0;
  660.          while (strlen(temp) < 18)
  661.             strcat(temp," ");
  662.          newtime = localtime(&uscfg.lasttime);
  663.          strcpy(ttemp,asctime(newtime));
  664.          strtok(ttemp," ");               /* Strip Day of week */
  665.          month = strtok(NULL," ");
  666.          day = strtok(NULL," ");
  667.          if (uscfg.calls < uscfg.packcount)
  668.             uscfg.calls = uscfg.packcount;
  669.          if (!uscfg.calls)
  670.             uscfg.calls = 1;
  671.          sprintf(temp1," %s %s    ",month,day);
  672.          strcat(temp,temp1);
  673.          if (uscfg.msgfrmt == 0)
  674.             strcat(temp,"STD");
  675.          else strcat(temp,"QWK");
  676.          sprintf(temp1,"  %5d %5d  ",uscfg.calls,uscfg.packcount);
  677.          strcat(temp,temp1);
  678.          z = USERCFG.packer;
  679.          USERCFG.packer = uscfg.packer;     /* Temporary fix */
  680.          packer1 = get_curpacklnk();
  681.          USERCFG.packer = z;
  682.          if (packer1 == NULL)
  683.             strcat(temp,"None  ");
  684.          else {
  685.             strcpy(temp1,packer1->packname);
  686.             day = strtok(temp1," ");         /* Get 1st name only */
  687.             while (strlen(day) < 6)
  688.                strcat(day," ");
  689.             strcat(temp,day);
  690.          }
  691.          uscfg.packer = (byte) x;
  692.          strcat(temp,"  ");
  693.          z = USERCFG.protocol;
  694.          USERCFG.protocol = uscfg.protocol;     /* Temporary fix */
  695.          proto1 = get_curprotolnk();
  696.          USERCFG.protocol = z;
  697.          if (proto1 == NULL)
  698.             strcat(temp,"None  ");
  699.          else {
  700.             strcpy(temp1,proto1->protoname);
  701.             day = strtok(temp1," ");         /* Get 1st name only */
  702.             strcat(temp,day);
  703.          }
  704.          uscfg.protocol = (byte) x;
  705.          strcat(temp,"    ");
  706.       /* Tack on flags */
  707.          if (uscfg.flags & LASTREAD_UPD)
  708.             strcat(temp,"L");
  709.          if (uscfg.flags & USRCFG_UPD)
  710.             strcat(temp,"U");
  711.          if (uscfg.flags & USRCFG_FUPD)
  712.             strcat(temp,"F");
  713.          if (uscfg.flags & USRCFG_MSGUPD)
  714.             strcat(temp,"M");
  715.          if (uscfg.flags & NEWFILES_INC)
  716.             strcat(temp,"N");
  717.          if (uscfg.flags & DLHANGUP)
  718.             strcat(temp,"H");
  719.          temp[79] = 0;
  720.          strcat(temp,"\r\n");
  721.          strout(temp);
  722.          row++;
  723.          y = read(handle,(char *) &uscfg,sizeof(struct user_cfg));
  724.       }
  725.       if (y == sizeof(struct user_cfg)) {        /* Still more records */
  726.          strout("\r\nPress ESC to stop or any other key for more");
  727.          x = chrin();
  728.          strout("\r\n");
  729.          if (x == 0x1b) 
  730.             break;
  731.       }
  732.       else break;
  733.    }
  734.    close(handle);
  735.    if (x != 0x1b) {
  736.       presskey();
  737.    }
  738. }
  739.  
  740. void del_msgareas(void)
  741. {
  742.    char *p;
  743.    int x;
  744.  
  745.    setcolor(TextAttr[STD_TEXT]);
  746.    strout("\r\nYour currently selected message areas\r\n");
  747.    strout("-----------------------------------------\r\n");
  748.    setcolor(TextAttr[HILITE_TEXT]);
  749.    show_areas(FALSE);
  750.    setcolor(TextAttr[STD_TEXT]);
  751.    strout("\r\nEnter message area(s) you wish to delete (Use comma or space to sep)\r\n");
  752.    timeremain();
  753.    setcolor(TextAttr[PROMPT_TEXT]);
  754.    strout("--> ");
  755.    strin(msgstr);
  756.    strout("\r\n");
  757.    p = strtok(msgstr," ,\0");
  758.    while (p) {
  759.       if (isdigit(*p)) {
  760.          msgnum = atoi(p);
  761.          x = is_selarea(msgnum);
  762.          if(x && !(isForcearea(x))) {
  763.             USERCFG.totselareas--;
  764.             msgunmark(msgnum);        /* Delete it */
  765.             x--;
  766.             msgupd = MSGUPD_1;
  767.             if (!x)
  768.                MSGUPD_1 = msgupd->next;
  769.             else {
  770.                while (x) {
  771.                   prev = msgupd;
  772.                   msgupd = msgupd->next;
  773.                   x--;
  774.                }
  775.                prev->next = msgupd->next;        /* Skip current one */
  776.             }
  777.             free(msgupd);
  778.             if (PackDone) {
  779.                logit("User is deleting message areas",'#');
  780.                erase_arc();
  781.                while (msgupd) {
  782.                   msgupd->update = FALSE;
  783.                   msgupd = msgupd->next;
  784.                }
  785.                PackDone = FALSE;
  786.             }
  787.          }
  788.          else if(isForcearea(x)){
  789.             sprintf(temp,"\r\nSorry, but Sysop wants you to pack area #%03d",x);
  790.             setcolor(TextAttr[ATTN_TEXT]);
  791.             strout(temp);
  792.             presskey();
  793.          }
  794.       }
  795.       p = strtok(NULL," ,\0");
  796.    }
  797.    strout("\r\n");
  798. }
  799.  
  800. void add_msgareas(void)
  801. {
  802.    char *p;
  803.    struct msgupd_st *new;
  804.    int first;
  805.  
  806.    first = TRUE;
  807.    setcolor(TextAttr[HILITE_TEXT]);
  808.    if (USERCFG.totselareas) {
  809.       strout("\r\nYour currently selected message areas\r\n");
  810.       strout("-----------------------------------------\r\n");
  811.       setcolor(TextAttr[MENU_KEY]);
  812.       show_areas(FALSE);
  813.       setcolor(TextAttr[HILITE_TEXT]);
  814.       strout("\r\nOther message areas available\r\n");
  815.    }
  816.    else strout("\r\nMessage areas available\r\n");
  817.    strout("-----------------------------------------\r\n");
  818.    setcolor(TextAttr[MENU_KEY]);
  819.    if(screen_areas(TRUE)) {
  820.       setcolor(TextAttr[HILITE_TEXT]);
  821.       strout("\r\nEnter message area(s) you wish to add (Use comma or space to sep)\r\n");
  822.       timeremain();
  823.       setcolor(TextAttr[PROMPT_TEXT]);
  824.       strout("--> ");
  825.       strin(msgstr);
  826.       strout("\r\n");
  827.       p = strtok(msgstr," ,\0");
  828.       while (p) {
  829.          if (isdigit(*p)) {
  830.             msgnum = atoi(p);
  831.             if(!is_selarea(msgnum)) {
  832.                msgupd = MSGUPD_1;
  833.                if (first) {
  834.                   setcolor(TextAttr[STD_TEXT]);
  835.                   strout("\r\nHang on, I'm scanning the new message areas you selected.....\r\n");
  836.                   first = FALSE;
  837.                }
  838.                new = build1_area(msgnum,TRUE);
  839.                if (new) {
  840.                   if (MSGUPD_1 == NULL) 
  841.                      MSGUPD_1 = new;
  842.                   else {        /* Attach it to the end */
  843.                      prev = msgupd;
  844.                      while (msgupd) {
  845.                         prev = msgupd;
  846.                         msgupd = msgupd->next;
  847.                      }
  848.                      prev->next = new;
  849.                   }
  850.                   msgmark(msgnum);        /* Add it */
  851.                   new->next = NULL;
  852.                   new->update = FALSE;
  853.                   if (PackDone) {
  854.                      logit("User is adding new message areas",'#');
  855.                      erase_arc();
  856.                      msgupd = MSGUPD_1;
  857.                      while (msgupd) {
  858.                         msgupd->update = FALSE;
  859.                         msgupd = msgupd->next;
  860.                      }
  861.                      PackDone = FALSE;
  862.                   }
  863.                }
  864.             }
  865.          }
  866.          p = strtok(NULL," ,\0");
  867.       }
  868.       strout("\r\n");
  869.    }
  870.    else {
  871.       setcolor(TextAttr[ATTN_TEXT]);
  872.       strout("Sorry, you have no other areas you can add at this time.\r\n");
  873.    }
  874.    get_msgcount();        /* Just re-do totselareas */
  875. }
  876.  
  877. void edit_msgptrs(void)
  878. {
  879.    char *p1;
  880.    char resp;
  881.    int firsttime;
  882.    int good = TRUE;
  883.    int doupdate = FALSE;
  884.    int rows,x;
  885.  
  886.    while (good) {
  887.       firsttime = TRUE;
  888.       msgupd = MSGUPD_1;
  889.       while (msgupd) {
  890.          setcolor(TextAttr[STD_TEXT]);
  891.          strout("\r\n---------------------------------------------------");
  892.          strout("\r\nCurrently selected            Start    High   New  ");
  893.          strout("\r\nMessage Areas                   Msg     Msg   Msgs ");
  894.          strout("\r\n---------------------------------------------------\r\n");
  895.          rows = 0;
  896.          while (msgupd && rows < 17) {
  897.             fseek(afile,msgupd->areaindex,SEEK_SET);
  898.             fread(&AREA,astrlen,1,afile);
  899.             strncpy(temp1,AREA.msginfo,24);
  900.             temp1[24] = 0;
  901.             while (strlen(temp1) < 24)
  902.                strcat(temp1," ");
  903.             sprintf(temp,"[%03d] %s %04d    %04d   %04d\r\n",msgupd->areano,temp1,msgupd->startmsg,msgupd->himsg,msgupd->msgcount);      
  904.             strout(temp);
  905.             msgupd = msgupd->next;
  906.             rows++;
  907.             firsttime = FALSE;
  908.          }
  909.          if(msgupd) {        /* Still some more, so page it */
  910.             strout("\r\nPress ESC to stop or any other key for more");
  911.             x = chrin();
  912.             strout("\r\n");
  913.             if (x == 0x1b)
  914.                msgupd = NULL;        /* Force a stop */
  915.          }
  916.       }
  917.       if (firsttime) {
  918.          setcolor(TextAttr[ATTN_TEXT]);
  919.          strout("\r\nYou have no currently selected message areas\r\n");
  920.          return;
  921.       }
  922.       else {
  923.          setcolor(TextAttr[STD_TEXT]);
  924.          strout("---------------------------------------------------\r\n");
  925.          setcolor(TextAttr[HILITE_TEXT]);
  926.          strout("\r\nEnter message area # you wish to change ...\r\n");
  927.          strout("Or type 'Q' to exit back to main menu\r\n\r\n");
  928.          timeremain();
  929.          setcolor(TextAttr[PROMPT_TEXT]);
  930.          strout("Message area to change --> ");
  931.          strin(temp);
  932.          if (*temp == '\r')
  933.             break;
  934.          stripwhite(temp);        /* Trim off spaces */
  935.          if (temp) {
  936.             p1 = strtok(temp," \t\r\n");
  937.             if (p1) resp = (char) toupper(*p1);
  938.             else break;        /* No answer, default */
  939.          }
  940.          else break;
  941.          if (resp == 'Q') 
  942.             break;
  943.          else {        /* Parse out message area */
  944.             msgupd = find_area(atoi(p1));
  945.             if (isdigit(resp) && msgupd) {
  946.                setcolor(TextAttr[HILITE_TEXT]);
  947.                strout("\r\n                              Start    High   New  ");
  948.                strout("\r\nMessage Area                    Msg     Msg   Msgs \r\n");
  949.                strout("---------------------------------------------------\r\n");
  950.                fseek(afile,msgupd->areaindex,SEEK_SET);
  951.                fread(&AREA,astrlen,1,afile);
  952.                strncpy(temp1,AREA.msginfo,24);
  953.                temp1[24] = 0;
  954.                while (strlen(temp1) < 24)
  955.                   strcat(temp1," ");
  956.                sprintf(temp,"[%03d] %s %04d    %04d   %04d\r\n",
  957.                   msgupd->areano,temp1,msgupd->startmsg,msgupd->himsg,msgupd->msgcount);      
  958.                strout(temp);
  959.                strout("\r\n");
  960.                timeremain();
  961.                setcolor(TextAttr[PROMPT_TEXT]);
  962.                strout("Start message # --> ");
  963.                strin(temp);
  964.                if (!IsLocal)
  965.                   strout("\r\n");
  966.                p1 = strtok(temp," \t\r\n");
  967.                if (p1) {
  968.                   firsttime = atoi(p1);
  969.                   if (isdigit(*p1) && (firsttime != (int) msgupd->startmsg)) {
  970.                      firsttime = firsttime >= 1 ? firsttime : 1;
  971.                      firsttime = firsttime <= (int) msgupd->himsg ? firsttime : (int) msgupd->himsg;
  972.                      msgupd->startmsg = firsttime;
  973.                      msgupd->msgcount = msgupd->himsg - msgupd->startmsg;
  974.                      if (msgupd->msgcount < 0)
  975.                         msgupd->msgcount = 0;
  976.                      doupdate = TRUE;
  977.                      msgupd->readmsgs = 0;
  978.                      if (PackDone) {
  979.                         logit("User is resetting message area pointers",'#');
  980.                         PackDone = FALSE;
  981.                         erase_arc();
  982.                      }
  983.                      else if (msg_update)
  984.                         msgupd->update = TRUE;
  985.                   }
  986.                }
  987.             }
  988.          }
  989.       }
  990.    }
  991.    if (doupdate)
  992.       update_msgs();
  993.    setcolor(TextAttr[STD_TEXT]);
  994. }
  995.  
  996. /* Delete users who are no longer active on Maximus user file */
  997.  
  998. void kill_oldusers(void)
  999. {
  1000.    int handl1,handl2;
  1001.    int x,y;
  1002.    long pos;
  1003.  
  1004.    if (test_task()) {
  1005.       setcolor(TextAttr[ATTN_TEXT]);
  1006.       strout("\r\nSorry, but someone else is using MaxMail currently. Try later!\r\n");
  1007.    }
  1008.  
  1009.    handl1 = sopen(CfgFile,O_RDWR | O_BINARY,SH_DENYWR,S_IWRITE);
  1010.    if (handl1 == -1) {
  1011.       setcolor(TextAttr[ATTN_TEXT]);
  1012.       strout("\r\nCan't write to user file");
  1013.       aborterror(FILEOPEN,"Error opening User config file");
  1014.    }
  1015.  
  1016.    handl2 = sopen(PRM(user_file),O_RDWR | O_BINARY,SH_DENYNO,S_IREAD);
  1017.    if (handl1 == -1) {
  1018.       setcolor(TextAttr[ATTN_TEXT]);
  1019.       strout("\r\nCan't open User.bbs file\r\n");
  1020.       close(handl1);
  1021.    }
  1022.    y = read(handl1,(char *) &uscfg,sizeof(struct user_cfg));
  1023.    x = 0;
  1024.    while (y == sizeof(struct user_cfg)) {
  1025.       if (uscfg.name[0]) {
  1026.          if (!find_realuser(uscfg.name,handl2)) {
  1027.             memset(uscfg.name,0,36);        /* Null out name */
  1028.             pos = tell(handl1) - (long) sizeof(struct user_cfg);    /* Get position */
  1029.             lseek(handl1,pos,SEEK_SET);     /* Rewind back to this record */
  1030.             write(handl1,(struct user_cfg *) &uscfg,sizeof(struct user_cfg));
  1031.             x++;
  1032.             strout(".");
  1033.          }
  1034.          else strout("*");
  1035.       }
  1036.       else strout("E");
  1037.       y = read(handl1,(char *) &uscfg,sizeof(struct user_cfg));
  1038.    }
  1039.    strout("\r\n");
  1040.    close(handl1);
  1041.    close(handl2);
  1042.    if (x) {
  1043.       setcolor(TextAttr[HILITE_TEXT]);
  1044.       sprintf(temp,"Sysop has deleted %d users from config file",x);
  1045.       strout(temp);
  1046.       strout(".\r\n");
  1047.       logit(temp,'#');
  1048.    }
  1049.    else {
  1050.       setcolor(TextAttr[ATTN_TEXT]);
  1051.       strout("No users are inactive at this time.\r\n");
  1052.    }
  1053.    setcolor(TextAttr[STD_TEXT]);
  1054. }
  1055.  
  1056. /* See if another MaxMail user is currently active */
  1057. int test_task(void)
  1058. {
  1059.    struct find_t c_file;
  1060.    int x;
  1061.  
  1062.    sprintf(temp,"MxMlAct.%03x",Task);        /* Create a task id */
  1063.    unlink(temp);        /* Delete our own task file */
  1064.  
  1065.    if (_dos_findfirst("MxMlAct.*",_A_NORMAL,&c_file) == 0) { /* Uh oh. Someone else is using MaxMail! */
  1066.       x = sopen(temp,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IWRITE);
  1067.       close(x);        /* Re-Create task file */
  1068.       return(TRUE);
  1069.    }
  1070.    x = sopen(temp,O_RDWR | O_BINARY | O_CREAT,SH_DENYWR,S_IWRITE);
  1071.    close(x);        /* Re-Create task file */
  1072.    return(FALSE);
  1073. }
  1074.  
  1075. void examine_user(void)
  1076. {
  1077.    int x,y,User,mask,bitloop,areas;
  1078.    int handl1,index;
  1079.    int col,line,anum;
  1080.    char *p1;
  1081.    word *bitp;
  1082.    struct _aidx IDX;
  1083.  
  1084.    setcolor(TextAttr[STD_TEXT]);
  1085.    strout("Enter user's name ---> ");
  1086.    strin(temp);
  1087.    if (!IsLocal)
  1088.       strout("\r\n");
  1089.    p1 = strtok(temp,"\t\r\n");
  1090.    if (p1) {
  1091.       handl1 = sopen(CfgFile,O_RDWR | O_BINARY | O_CREAT,SH_DENYNO,S_IREAD);
  1092.       if (handl1 == -1)
  1093.          aborterror(FILEOPEN,"Error opening User config file");
  1094.       User = find_config(handl1,p1,&uscfg);
  1095.       if (User < 0) {
  1096.          setcolor(TextAttr[ATTN_TEXT]);
  1097.          strout("Sorry but that user name does not exist.\r\n");
  1098.       }
  1099.       else {        /* Display possible message areas */
  1100.          col = 0;
  1101.          line = 0;
  1102.          areas = 0;
  1103.          index = sopen(PRM(aidx_name),O_BINARY | O_RDONLY,SH_DENYNO,S_IREAD);
  1104.          if (index == -1)
  1105.             aborterror(FILEOPEN,"Error opening Area index file");
  1106.          setcolor(TextAttr[STD_TEXT]);
  1107.          for (bitloop=0; bitloop < 64; bitloop++ ) {
  1108.             bitp = &uscfg.msgarea[bitloop];
  1109.             mask = 1;
  1110.             for (x=0; x < 16; x++) {        /* Bitmask loop */
  1111.                if (*bitp & mask) {        /* User selected area */
  1112.                   anum = (bitloop * 16) + x;
  1113.                   lseek(index,(long) (anum * sizeof(struct _aidx)),SEEK_SET);
  1114.                   read(index,(char *)&IDX,sizeof(struct _aidx));
  1115.                   fseek(afile,IDX.offset,SEEK_SET);
  1116.                   y = fread(&AREA,astrlen,1,afile);
  1117.                   if (AREA.msginfo[0]){
  1118.                      areas++;
  1119.                      if (!areas) {        /* First time */
  1120.                         strout("\r\nUser message areas: \r\n");
  1121.                         strout("-------------------\r\n");
  1122.                         rewind(afile);        /* Rewind AREA file */
  1123.                      }
  1124.                      if (!col) {     /* 1st column */
  1125.                         strncpy(temp,AREA.msginfo,20);
  1126.                         temp[20] = 0;
  1127.                         sprintf(msgstr,"[%d] %s",anum,temp);
  1128.                         y = strlen(msgstr);
  1129.                         while (y++ < 26) 
  1130.                            strcat(msgstr," ");        /* Pad it for formatting */
  1131.                      }
  1132.                      else {        /* 2nd or 3rd column */
  1133.                         strncpy(temp1,AREA.msginfo,20);
  1134.                         temp1[20] = 0;
  1135.                         sprintf(temp,"[%d] %s",anum,temp1);
  1136.                         y = strlen(temp);
  1137.                         while (y++ < 26) 
  1138.                            strcat(temp," ");        /* Pad it for formatting */
  1139.                         strcat(msgstr,temp);
  1140.                         if (col == 2) {
  1141.                            strcat(msgstr,"\r\n");
  1142.                            strout(msgstr);
  1143.                            line++;        /* Another row is spit out */
  1144.                            if (line > 23) {
  1145.                               presskey();
  1146.                               line = 0;
  1147.                            }
  1148.                            col = -1;
  1149.                         }
  1150.                      }
  1151.                      col++;
  1152.                   }
  1153.                }
  1154.                mask = mask << 1;
  1155.             }
  1156.          }
  1157.          if (col) {
  1158.             strcat(msgstr,"\r\n");
  1159.             strout(msgstr);
  1160.          }
  1161.          close(index);
  1162.          if (areas) {
  1163.             sprintf(temp,"\r\nTotal areas selected: %d \r\n",areas);
  1164.             strout(temp);
  1165.          }
  1166.       }
  1167.       close(handl1);
  1168.    }
  1169. }
  1170.  
  1171.  
  1172. /* Generate a tone of given frequency and length, time is in 10ths of seconds */
  1173. void tone (int freq, int time)
  1174. {
  1175.  
  1176.    int  hibyte, lowbyte, port;
  1177.    long divisor;
  1178.  
  1179.    divisor = FREQSCALE / freq;    /* scale freq to timer units  */
  1180.    lowbyte = (int) (divisor % 256); /* break integer into         */
  1181.    hibyte  = (int) (divisor >> 8);        /*  two bytes                 */
  1182.  
  1183.    outp (T_MODEPORT, TIMERMODE);    /* prepare timer for input    */
  1184.    outp (FREQPORT, lowbyte);    /* set low byte of timer reg  */
  1185.    outp (FREQPORT, hibyte); /* set high byte of timer reg */
  1186.  
  1187.    port = inp(BEEPPORT);        /* save port setting          */
  1188.    outp (BEEPPORT, ON);        /* turn speaker on            */
  1189.    delay_ms(time);
  1190.    outp (BEEPPORT, port);        /* turn speaker off, restore  */
  1191.                 /*  original setting          */
  1192. }
  1193.  
  1194.  
  1195. void get_msgtype(void)
  1196. {
  1197.    int x;
  1198.    unsigned oldfrmt;
  1199.  
  1200.    do
  1201.    {
  1202.       setcolor(TextAttr[HILITE_TEXT]);
  1203.       strout("Enter message format you wish to use\r\n");
  1204.       strout("------------------------------------\r\n");
  1205.       strout("[0]Standard Text      [1]QWK packets\r\n");
  1206.       timeremain();
  1207.       setcolor(TextAttr[PROMPT_TEXT]);
  1208.       strout("--> ");
  1209.       x = chrin();
  1210.       if (x == '\r')
  1211.          x = '0';
  1212.       else if (!(isdigit(x))) {
  1213.          setcolor(TextAttr[ATTN_TEXT]);
  1214.          strout("\r\nYou must enter digits only!\r\n");
  1215.          continue;
  1216.       }
  1217.       setcolor(TextAttr[STD_TEXT]);
  1218.       sprintf(temp,"%c\r\n",x);
  1219.       strout(temp);
  1220.    }
  1221.    while (x != '1' && x != '0' );
  1222.    oldfrmt = USERCFG.msgfrmt;
  1223.    USERCFG.msgfrmt = x - 0x30;
  1224.    if (USERCFG.msgfrmt == 1)
  1225.       qwkinit();
  1226.  
  1227.    if (oldfrmt != USERCFG.msgfrmt && PackDone)
  1228.       erase_arc();
  1229. }
  1230.  
  1231. void get_nfiles(void)
  1232. {
  1233.    int x;
  1234.  
  1235.    setcolor(TextAttr[HILITE_TEXT]);
  1236.    strout("\r\nDo you wish to include a newfiles list\r\n");
  1237.    strout("  in your packet?\r\n");
  1238.    if (getyn(TRUE))
  1239.       USERCFG.flags |= NEWFILES_INC;
  1240.    else {
  1241.       x = NEWFILES_INC ^ 0xffff;
  1242.       USERCFG.flags &= x;        /* Turn it off */
  1243.    }
  1244. }
  1245.  
  1246. void get_totperarea(void)
  1247. {
  1248.  
  1249.    if(USERCFG.msgfrmt == 1) {        /* This is only needed for QWK */
  1250.       while (1) {
  1251.          setcolor(TextAttr[HILITE_TEXT]);
  1252.          strout("\r\nEnter maximum # of messages you want to pack in each area\r\n");
  1253.          timeremain();
  1254.          setcolor(TextAttr[PROMPT_TEXT]);
  1255.          strout(" or enter a '0' for full pack per area --> ");
  1256.          strin(msgstr);
  1257.          if (!IsLocal)
  1258.             strout("\r\n");
  1259.          setcolor(TextAttr[STD_TEXT]);
  1260.          stripwhite(msgstr);
  1261.          if (!(isdigit(msgstr[0])) && msgstr[0]) {
  1262.             setcolor(TextAttr[ATTN_TEXT]);
  1263.             strout("You must enter digits only!\r\n");
  1264.             continue;
  1265.          }
  1266.          switch (msgstr[0]) {
  1267.             case 0:
  1268.                USERCFG.maxareamsgs = 0;
  1269.                break;
  1270.  
  1271.             default:
  1272.                if (isdigit(msgstr[0]))
  1273.                   USERCFG.maxareamsgs = (word) (atoi(msgstr));
  1274.                else USERCFG.maxareamsgs = 0;
  1275.          }
  1276.          break;
  1277.       }
  1278.    }
  1279. }
  1280.  
  1281. /* Get a yes/no anser from user. Return TRUE for yes,FALSE for no.
  1282.    If flag is true add timeremain key */
  1283.  
  1284. int getyn(int flag)
  1285. {
  1286.    int x;
  1287.  
  1288.    if (flag) 
  1289.       timeremain();
  1290.    setcolor(TextAttr[PROMPT_TEXT]);
  1291.    strout("[y,N] ");
  1292.    x = chrin();
  1293.    chrout((char) x);
  1294.    strout("\r\n");
  1295.    if (toupper(x) == 'Y')
  1296.       return TRUE;
  1297.    else return FALSE;
  1298. }
  1299.  
  1300.  
  1301. void presskey(void)
  1302. {
  1303.    strout("\r\nPress any key");
  1304.    chrin();
  1305.    strout("\r\n");
  1306. }
  1307.