home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / LO241SRV.ZIP / general.c < prev    next >
Text File  |  1998-08-01  |  42KB  |  1,441 lines

  1.  
  2. // LoraBBS Version 2.41 Free Edition
  3. // Copyright (C) 1987-98 Marco Maccaferri
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 2 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19. #include <stdio.h>
  20. #include <dos.h>
  21. #include <io.h>
  22. #include <share.h>
  23. #include <alloc.h>
  24. #include <fcntl.h>
  25. #include <string.h>
  26. #include <time.h>
  27. #include <ctype.h>
  28. #include <stdlib.h>
  29. #include <sys\stat.h>
  30.  
  31. #include <cxl\cxlvid.h>
  32. #include <cxl\cxlwin.h>
  33. #include <cxl\cxlstr.h>
  34.  
  35. #include "lsetup.h"
  36. #include "sched.h"
  37. #include "msgapi.h"
  38. #include "externs.h"
  39. #include "prototyp.h"
  40. #include "zmodem.h"
  41. #include "msgapi.h"
  42.  
  43. void display_cpu (void);
  44.  
  45. static void is_4dos (void);
  46. static void compilation_data(void);
  47.  
  48. #define MAX_INDEX    200
  49.  
  50. void software_version (char *arguments)
  51. {
  52.    unsigned char i;
  53.    unsigned pp;
  54.    float t, u;
  55.    struct diskfree_t df;
  56.  
  57.    cls ();
  58.  
  59.    change_attr (LMAGENTA|_BLACK);
  60.    m_print ("%s - The Computer-Based Information System\n", VERSION);
  61.    m_print ("CopyRight (c) 1989-96 by Marco Maccaferri. All Rights Reserved.\n");
  62. #ifdef __OCC__
  63.    m_print ("CopyRight (c) 1995 Old Colorado City Communications. All Rights Reserved.\n");
  64. #endif
  65.  
  66.    change_attr (LCYAN|_BLACK);
  67.    m_print ("\nJanus revision 0.31 - (C) Copyright 1987-90, Bit Bucket Software Co.\n");
  68.    m_print ("MsgAPI - Copyright 1990, 1991 by Scott J. Dudley.  All rights reserved.\n");
  69.    m_print ("BlueWave Offline Mail System. Copyright 1990-94 by Cutting Edge Computing\n");
  70.  
  71.    compilation_data ();
  72.  
  73.    activation_key ();
  74.    if (registered)
  75.       m_print ("Registered to: %s\n               %s\n\n", config->sysop, config->system_name);
  76.  
  77.    change_attr(WHITE|_BLACK);
  78.    m_print(bbstxt[B_COMPUTER]);
  79.    m_print(bbstxt[B_TYPE_GENERIC]);
  80.  
  81.    m_print (bbstxt[B_OS_OS2], _osmajor / 10, _osminor);
  82.    m_print (bbstxt[B_ONE_CR]);
  83.    m_print (bbstxt[B_ONE_CR]);
  84.  
  85.    if (strstr (arguments, "/NDSK") == NULL) {
  86.       if (!_dos_getdiskfree (3, &df)) {
  87.      t = (float)df.total_clusters * df.bytes_per_sector * df.sectors_per_cluster / 1048576L;
  88.      u = (float)df.avail_clusters * df.bytes_per_sector * df.sectors_per_cluster / 1048576L;
  89.      pp = (unsigned )(u * 100 / t);
  90.          m_print (bbstxt[B_GENERAL_FREE1], u, t, pp);
  91.       }
  92.  
  93.       for (i = 4; i <= 26; i++) {
  94.          if (!_dos_getdiskfree (i, &df)) {
  95.             t = (float)df.total_clusters * df.bytes_per_sector * df.sectors_per_cluster / 1048576L;
  96.             u = (float)df.avail_clusters * df.bytes_per_sector * df.sectors_per_cluster / 1048576L;
  97.             pp = (unsigned )(u * 100 / t);
  98.             m_print (bbstxt[B_GENERAL_FREE2], i + 64, u, t, pp);
  99.          }
  100.       }
  101.    }
  102.  
  103.    m_print (bbstxt[B_ONE_CR]);
  104.  
  105.    press_enter ();
  106. }
  107.  
  108. void is_4dos()
  109. {
  110. }
  111.  
  112. void display_area_list(type, flag, sig)   /* flag == 1, Normale due colonne */
  113. int type, flag, sig;                      /* flag == 2, Normale una colonna */
  114. {                                         /* flag == 3, Anche nomi, una colonna */
  115.    int fd, fdi, i, pari, area, linea, nsys, nm;
  116.    char stringa[80], filename[50], dir[80], first;
  117.    struct _sys tsys;
  118.    struct _sys_idx sysidx[10];
  119.  
  120.    memset (&tsys, 0, sizeof (struct _sys));
  121.  
  122.    if (!type)
  123.        return;
  124.  
  125.    first = 1;
  126.  
  127.    if (sig == -1) {
  128.       if (type == 1)
  129.          read_system_file ("MGROUP");
  130.       else if (type == 2)
  131.          read_system_file ("FGROUP");
  132.  
  133.       do {
  134.          m_print (bbstxt[B_GROUP_LIST]);
  135.          chars_input (stringa, 4, INPUT_FIELD);
  136.          if ( (sig = atoi (stringa)) == 0)
  137.             return;
  138.       } while (sig < 0);
  139.  
  140.       if (type == 1)
  141.          usr.msg_sig = sig;
  142.       else if (type == 2)
  143.          usr.file_sig = sig;
  144.    }
  145.  
  146.    if (type == 1) {
  147.       sprintf(filename,"%sSYSMSG.DAT", config->sys_path);
  148.       area = usr.msg;
  149.    }
  150.    else if (type == 2) {
  151.       sprintf(filename,"%sSYSFILE.DAT", config->sys_path);
  152.       area = usr.files;
  153.    }
  154.    else
  155.       return;
  156.  
  157.    fd = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD);
  158.    if (fd == -1)
  159.       return;
  160.  
  161.    if (type == 1) {
  162.       sprintf(filename,"%sSYSMSG.IDX", config->sys_path);
  163.       area = usr.msg;
  164.    }
  165.    else if (type == 2) {
  166.       sprintf(filename,"%sSYSFILE.IDX", config->sys_path);
  167.       area = usr.files;
  168.    }
  169.  
  170.    fdi = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD);
  171.    if (fdi == -1) {
  172.       close (fd);
  173.       return;
  174.    }
  175.  
  176.    do {
  177.       if (!get_command_word (stringa, 12)) {
  178.          if (type == 1)
  179.             m_print(bbstxt[B_SELECT_AREAS],bbstxt[B_MESSAGE]);
  180.          else if (type == 2)
  181.             m_print(bbstxt[B_SELECT_AREAS],bbstxt[B_FILE]);
  182.          input(stringa, 12);
  183.          if (!CARRIER || time_remain() <= 0) {
  184.             close (fdi);
  185.             return;
  186.          }
  187.       }
  188.  
  189.       if (!stringa[0] && first) {
  190.          first = 0;
  191.          stringa[0] = area_change_key[2];
  192.       }
  193.  
  194.       if (stringa[0] == area_change_key[2] || (!stringa[0] && !area)) {
  195.          cls();
  196.          m_print(bbstxt[B_AREAS_TITLE], (type == 1) ? bbstxt[B_MESSAGE] : bbstxt[B_FILE]);
  197.  
  198.          first = 0;
  199.          pari = 0;
  200.          linea = 4;
  201.          nm = 0;
  202.          lseek(fdi, 0L, SEEK_SET);
  203.  
  204.          do {
  205.             nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  206.             nsys /= sizeof (struct _sys_idx);
  207.  
  208.             for (i=0; i < nsys; i++, nm++) {
  209.                if (usr.priv < sysidx[i].priv || (usr.flags & sysidx[i].flags) != sysidx[i].flags)
  210.                   continue;
  211.  
  212.                if (sig) {
  213.                   if (sysidx[i].sig != sig)
  214.                      continue;
  215.                }
  216.  
  217.                if (type == 1) {
  218.                   if (read_system_file ("MSGAREA"))
  219.                      break;
  220.  
  221.                   lseek(fd, (long)nm * SIZEOF_MSGAREA, SEEK_SET);
  222.                   read(fd, (char *)&tsys.msg_name, SIZEOF_MSGAREA);
  223.  
  224.                   if (sig || tsys.msg_restricted) {
  225.                      if (tsys.msg_sig != sig)
  226.                         continue;
  227.                   }
  228.  
  229.                   if (flag == 1) {
  230.                      strcpy (dir, tsys.msg_name);
  231.                      dir[31] = '\0';
  232.  
  233.                      sprintf (stringa, "ì%3d ... %-31s ", sysidx[i].area, dir);
  234.  
  235.                      if (pari) {
  236.                         m_print ("%s\n", strtrim (stringa));
  237.                         pari = 0;
  238.                         if (!(linea = more_question(linea)))
  239.                            break;
  240.                      }
  241.                      else {
  242.                         m_print (stringa);
  243.                         pari = 1;
  244.                      }
  245.                   }
  246.                   else if (flag == 2) {
  247.                      m_print("ì%3d ... %s\n", sysidx[i].area, tsys.msg_name);
  248.                      if (!(linea = more_question(linea)))
  249.                         break;
  250.                   }
  251.                   else if (flag == 3) {
  252.                      m_print("ì%3d ...  %-12s %s\n", sysidx[i].area, sysidx[i].key, tsys.msg_name);
  253.                      if (!(linea = more_question(linea)))
  254.                         break;
  255.                   }
  256.                   else if (flag == 4) {
  257.                      if (!sysidx[i].key[0])
  258.                         sprintf (sysidx[i].key, "%d", sysidx[i].area);
  259.                      m_print("ì%-12s ... %s\n", sysidx[i].key, tsys.msg_name);
  260.                      if (!(linea = more_question(linea)))
  261.                         break;
  262.                   }
  263.                }
  264.                else if (type == 2) {
  265.                   if (read_system_file ("FILEAREA"))
  266.                      break;
  267.  
  268.                   lseek(fd, (long)nm * SIZEOF_FILEAREA, SEEK_SET);
  269.                   read(fd, (char *)&tsys.file_name, SIZEOF_FILEAREA);
  270.  
  271.                   if (sig || tsys.file_restricted) {
  272.                      if (tsys.file_sig != sig)
  273.                         continue;
  274.                   }
  275.  
  276.                   if (flag == 1) {
  277.                      strcpy (dir, tsys.file_name);
  278.                      dir[31] = '\0';
  279.  
  280.                      sprintf (stringa, "ì%3d ... %-31s ", sysidx[i].area, dir);
  281.  
  282.                      if (pari) {
  283.                         m_print ("%s\n", strtrim (stringa));
  284.                         pari = 0;
  285.                         if (!(linea = more_question(linea)))
  286.                            break;
  287.                      }
  288.                      else {
  289.                         m_print (stringa);
  290.                         pari = 1;
  291.                      }
  292.                   }
  293.                   else if (flag == 2) {
  294.                      m_print("ì%3d ... %s\n", sysidx[i].area, tsys.file_name);
  295.                      if (!(linea = more_question(linea)))
  296.                         break;
  297.                   }
  298.                   else if (flag == 3) {
  299.                      m_print("ì%3d ...  %-12s %s\n", sysidx[i].area, sysidx[i].key, tsys.file_name);
  300.                      if (!(linea = more_question(linea)))
  301.                         break;
  302.                   }
  303.                   else if (flag == 4) {
  304.                      if (!sysidx[i].key[0])
  305.                         sprintf (sysidx[i].key, "%d", sysidx[i].area);
  306.                      m_print("ì%-12s ... %s\n", sysidx[i].key, tsys.file_name);
  307.                      if (!(linea = more_question(linea)))
  308.                         break;
  309.                   }
  310.                }
  311.             }
  312.          } while (linea && nsys == 10);
  313.  
  314.          if (pari)
  315.             m_print(bbstxt[B_ONE_CR]);
  316.          area = -1;
  317.       }
  318.       else if (stringa[0] == area_change_key[1]) {
  319.          lseek(fdi, 0L, SEEK_SET);
  320.  
  321.          do {
  322.             nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  323.             nsys /= sizeof (struct _sys_idx);
  324.  
  325.             for (i=0; i < nsys; i++)
  326.                if (sysidx[i].area == area)
  327.                   break;
  328.          } while (i == nsys && nsys == 10);
  329.  
  330.          if (i == nsys)
  331.             continue;
  332.  
  333.          for (;;) {
  334.             i++;
  335.             if (i >= nsys) {
  336.                i = 0;
  337.                nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  338.                if (nsys == 0) {
  339.                   lseek(fdi, 0L, SEEK_SET);
  340.                   nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  341.                }
  342.                nsys /= sizeof (struct _sys_idx);
  343.                i = 0;
  344.             }
  345.             if (sig) {
  346.                if (sysidx[i].sig != sig)
  347.                   continue;
  348.             }
  349.             if (sysidx[i].area == area)
  350.                break;
  351.             if (usr.priv >= sysidx[i].priv && (usr.flags & sysidx[i].flags) == sysidx[i].flags)
  352.                break;
  353.          }
  354.  
  355.          area = sysidx[i].area;
  356.       }
  357.       else if (stringa[0] == area_change_key[0]) {
  358.          lseek(fdi, 0L, SEEK_SET);
  359.  
  360.          do {
  361.             nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  362.             nsys /= sizeof (struct _sys_idx);
  363.  
  364.             for (i=0; i < nsys; i++)
  365.                if (sysidx[i].area == area)
  366.                   break;
  367.          } while (i == nsys && nsys == 10);
  368.  
  369.          if (i == nsys)
  370.             continue;
  371.  
  372.          for (;;) {
  373.             i--;
  374.             if (i < 0) {
  375.                if (lseek(fdi, tell(fdi) - (10L + (long)nsys) * sizeof (struct _sys_idx), SEEK_SET) == -1L)
  376.                   lseek(fdi, (long)nsys * sizeof (struct _sys_idx), SEEK_END);
  377.  
  378.                nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  379.                nsys /= sizeof (struct _sys_idx);
  380.                i = nsys - 1;
  381.                if (i < 0)
  382.                   break;
  383.             }
  384.             if (sig) {
  385.                if (sysidx[i].sig != sig)
  386.                   continue;
  387.             }
  388.             if (sysidx[i].area == area)
  389.                break;
  390.             if (usr.priv >= sysidx[i].priv && (usr.flags & sysidx[i].flags) == sysidx[i].flags)
  391.                break;
  392.          }
  393.  
  394.          area = sysidx[i].area;
  395.       }
  396.       else if (strlen(stringa) < 1 && read_system (usr.msg, type)) {
  397.          close (fdi);
  398.          close (fd);
  399.          return;
  400.       }
  401.       else {
  402.          lseek(fdi, 0L, SEEK_SET);
  403.          area = atoi(stringa);
  404.          if (area < 1) {
  405.             area = -1;
  406.             do {
  407.                nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  408.                nsys /= sizeof (struct _sys_idx);
  409.  
  410.                for(i=0;i<nsys;i++) {
  411.                   if (usr.priv < sysidx[i].priv || (usr.flags & sysidx[i].flags) != sysidx[i].flags)
  412.                      continue;
  413.                   if (sig) {
  414.                      if (sysidx[i].sig != sig)
  415.                         continue;
  416.                   }
  417.                   if (!stricmp(strbtrim (stringa), strbtrim (sysidx[i].key))) {
  418.                      area = sysidx[i].area;
  419.                      break;
  420.                   }
  421.                }
  422.             } while (i == nsys && nsys == 10);
  423.          }
  424.          else {
  425.             do {
  426.                nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  427.                nsys /= sizeof (struct _sys_idx);
  428.  
  429.                for(i=0;i<nsys;i++) {
  430.                   if (usr.priv < sysidx[i].priv || (usr.flags & sysidx[i].flags) != sysidx[i].flags)
  431.                      continue;
  432.                   if (sig) {
  433.                      if (sysidx[i].sig != sig)
  434.                         continue;
  435.                   }
  436.                   if (sysidx[i].area == area)
  437.                      break;
  438.                }
  439.             } while (i == nsys && nsys == 10);
  440.  
  441.             if (i == nsys)
  442.                area = -1;
  443.          }
  444.       }
  445.    } while (area == -1 || !read_system(area, type));
  446.  
  447.    close (fdi);
  448.    close (fd);
  449.  
  450.    if (type == 1) {
  451.       status_line(msgtxt[M_BBS_EXIT], area, sys.msg_name);
  452.       usr.msg = area;
  453.    }
  454.    else if (type == 2) {
  455.       status_line(msgtxt[M_BBS_SPAWN], area, sys.file_name);
  456.       usr.files = area;
  457.    }
  458. }
  459.  
  460. void display_new_area_list (sig)
  461. int sig;
  462. {
  463.    int fd, fdi, i, pari, area, linea, nsys, nm, first;
  464.    char stringa[13], filename[50];
  465.    struct _sys_idx sysidx[10];
  466.  
  467.    first = 1;
  468.  
  469.    sprintf(filename,"%sSYSMSG.DAT", config->sys_path);
  470.    fd = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD);
  471.    if (fd == -1)
  472.       return;
  473.  
  474.    sprintf(filename,"%sSYSMSG.IDX", config->sys_path);
  475.    area = usr.msg;
  476.    fdi = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD);
  477.    if (fdi == -1) {
  478.       close (fd);
  479.       return;
  480.    }
  481.  
  482.    do {
  483.       if (!get_command_word (stringa, 12)) {
  484.          m_print(bbstxt[B_SELECT_AREAS],bbstxt[B_MESSAGE]);
  485.          input(stringa, 12);
  486.          if (!CARRIER || time_remain() <= 0) {
  487.             close (fdi);
  488.             return;
  489.          }
  490.       }
  491.  
  492.       if (!stringa[0] && first) {
  493.          first = 0;
  494.          stringa[0] = area_change_key[2];
  495.       }
  496.  
  497.       if (stringa[0] == area_change_key[2] || (!stringa[0] && !area)) {
  498.          cls();
  499.          m_print(bbstxt[B_AREAS_TITLE], bbstxt[B_MESSAGE]);
  500.  
  501.          first = 0;
  502.          pari = 0;
  503.          linea = 4;
  504.          nm = 0;
  505.          lseek(fdi, 0L, SEEK_SET);
  506.  
  507.          do {
  508.             nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  509.             nsys /= sizeof (struct _sys_idx);
  510.  
  511.             for (i=0; i < nsys; i++, nm++) {
  512.                if (usr.priv < sysidx[i].priv || (usr.flags & sysidx[i].flags) != sysidx[i].flags)
  513.                   continue;
  514.                if (sig) {
  515.                   if (sysidx[i].sig != sig)
  516.                      continue;
  517.                }
  518.  
  519.                lseek(fd, (long)nm * SIZEOF_MSGAREA, SEEK_SET);
  520.                read(fd, (char *)&sys.msg_name, SIZEOF_MSGAREA);
  521.  
  522.                if (sig) {
  523.                   if (sys.msg_sig != sig)
  524.                      continue;
  525.                }
  526.  
  527.                if (sys.quick_board || sys.gold_board)
  528.                   quick_scan_message_base (sys.quick_board, sys.gold_board, sys.msg_num, 0);
  529.                else if (sys.pip_board)
  530.                   pip_scan_message_base (sys.msg_num, 0);
  531.                else if (sys.squish)
  532.                   squish_scan_message_base (sys.msg_num, sys.msg_path, 0);
  533.                else
  534.                   scan_message_base(sys.msg_num, 0);
  535.  
  536.                if (last_msg > lastread) {
  537.                   m_print("ì%3d ...  %s\n",sysidx[i].area,sys.msg_name);
  538.  
  539.                   if (!(linea = more_question(linea)))
  540.                      break;
  541.                }
  542.             }
  543.          } while (linea && nsys == 10);
  544.  
  545.          if (pari)
  546.             m_print(bbstxt[B_ONE_CR]);
  547.          area = -1;
  548.       }
  549.       else if (stringa[0] == area_change_key[1]) {
  550.          lseek(fdi, 0L, SEEK_SET);
  551.  
  552.          do {
  553.             nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  554.             nsys /= sizeof (struct _sys_idx);
  555.  
  556.             for (i=0; i < nsys; i++)
  557.                if (sysidx[i].area == area)
  558.                   break;
  559.          } while (i == nsys && nsys == 10);
  560.  
  561.          if (i == nsys)
  562.             continue;
  563.  
  564.          do {
  565.             i++;
  566.             if (i >= nsys) {
  567.                i = 0;
  568.                nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  569.                if (nsys == 0) {
  570.                   lseek(fdi, 0L, SEEK_SET);
  571.                   nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  572.                }
  573.                nsys /= sizeof (struct _sys_idx);
  574.             }
  575.             if (sysidx[i].area == area)
  576.                break;
  577.          } while (usr.priv < sysidx[i].priv || (usr.flags & sysidx[i].flags) != sysidx[i].flags);
  578.  
  579.          area = sysidx[i].area;
  580.       }
  581.       else if (stringa[0] == area_change_key[0]) {
  582.          lseek(fdi, 0L, SEEK_SET);
  583.  
  584.          do {
  585.             nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  586.             nsys /= sizeof (struct _sys_idx);
  587.  
  588.             for (i=0; i < nsys; i++)
  589.                if (sysidx[i].area == area)
  590.                   break;
  591.          } while (i == nsys && nsys == 10);
  592.  
  593.          if (i == nsys)
  594.             continue;
  595.  
  596.          do {
  597.             i--;
  598.             if (i < 0) {
  599.                if (lseek(fdi, tell(fdi) - (10L + (long)nsys) * sizeof (struct _sys_idx), SEEK_SET) == -1L)
  600.                   lseek(fdi, (long)nsys * sizeof (struct _sys_idx), SEEK_END);
  601.  
  602.                nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  603.                nsys /= sizeof (struct _sys_idx);
  604.                i = nsys - 1;
  605.                if (i < 0)
  606.                   break;
  607.             }
  608.             if (sysidx[i].area == area)
  609.                break;
  610.          } while (usr.priv < sysidx[i].priv || (usr.flags & sysidx[i].flags) != sysidx[i].flags);
  611.  
  612.          area = sysidx[i].area;
  613.       }
  614.       else if (strlen(stringa) < 1 && read_system (usr.msg, 1)) {
  615.          close (fdi);
  616.          close (fd);
  617.          return;
  618.       }
  619.       else {
  620.          lseek(fdi, 0L, SEEK_SET);
  621.          area = atoi(stringa);
  622.          if (area < 1) {
  623.             area = -1;
  624.             do {
  625.                nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  626.                nsys /= sizeof (struct _sys_idx);
  627.  
  628.                for(i=0;i<nsys;i++) {
  629.                   if (usr.priv < sysidx[i].priv || (usr.flags & sysidx[i].flags) != sysidx[i].flags)
  630.                      continue;
  631.                   if (sig) {
  632.                      if (sysidx[i].sig != sig)
  633.                         continue;
  634.                   }
  635.                   if (!stricmp(strbtrim (stringa), strbtrim (sysidx[i].key))) {
  636.                      area = sysidx[i].area;
  637.                      break;
  638.                   }
  639.                }
  640.             } while (i == nsys && nsys == 10);
  641.          }
  642.          else {
  643.             do {
  644.                nsys = read(fdi, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  645.                nsys /= sizeof (struct _sys_idx);
  646.  
  647.                for(i=0;i<nsys;i++) {
  648.                   if (usr.priv < sysidx[i].priv || (usr.flags & sysidx[i].flags) != sysidx[i].flags)
  649.                      continue;
  650.                   if (sig) {
  651.                      if (sysidx[i].sig != sig)
  652.                         continue;
  653.                   }
  654.                   if (sysidx[i].area == area)
  655.                      break;
  656.                }
  657.             } while (i == nsys && nsys == 10);
  658.  
  659.             if (i == nsys)
  660.                area = -1;
  661.          }
  662.       }
  663.    } while (area == -1 || !read_system(area, 1));
  664.  
  665.    close (fdi);
  666.    close (fd);
  667.  
  668.    status_line(msgtxt[M_BBS_EXIT], area, sys.msg_name);
  669.    usr.msg = area;
  670. }
  671.  
  672. int read_system (int s, int type)
  673. {
  674.    int fd, nsys, i, mn = 0;
  675.    char filename[50];
  676.    struct _sys_idx sysidx[10];
  677.    struct _sys tsys;
  678.     MSG *ptr;
  679.     offline_reader =  0;
  680.  
  681.     if (type != 1 && type != 2)
  682.         return (0);
  683.  
  684.     if (sq_ptr != NULL) {
  685.         MsgCloseArea (sq_ptr);
  686.         sq_ptr = NULL;
  687.     }
  688.  
  689.     if (type == 1)
  690.         sprintf(filename,"%sSYSMSG.IDX", config->sys_path);
  691.     else if (type == 2)
  692.         sprintf(filename,"%sSYSFILE.IDX", config->sys_path);
  693.  
  694.     fd = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD);
  695.     if (fd == -1)
  696.         return (0);
  697.  
  698.     do {
  699.         nsys = read(fd, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  700.         nsys /= sizeof (struct _sys_idx);
  701.         for (i = 0; i < nsys; i++, mn++) {
  702.             if (sysidx[i].area == s)
  703.                 break;
  704.         }
  705.     } while (i == nsys && nsys == 10);
  706.  
  707.     close (fd);
  708.  
  709.     if (i == nsys)
  710.         return (0);
  711. //   if (usr.name[0] && (sysidx[i].priv > usr.priv || (usr.flags & sysidx[i].flags) != sysidx[i].flags))
  712. //      return (0);
  713.  
  714.    i = mn;
  715.  
  716.    if (type == 1) {
  717.       sprintf(filename,SYSMSG_PATH, config->sys_path);
  718.       fd = sh_open (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD);
  719.       if (fd == -1)
  720.          return (0);
  721.       lseek (fd, (long)i * SIZEOF_MSGAREA, SEEK_SET);
  722.       read(fd, (char *)&tsys.msg_name, SIZEOF_MSGAREA);
  723.  
  724.       if (usr.priv < tsys.msg_priv) {
  725.          close(fd);
  726.          return (0);
  727.       }
  728.       if ((usr.flags & tsys.msg_flags) != tsys.msg_flags) {
  729.          close(fd);
  730.          return (0);
  731.       }
  732.  
  733.       lseek (fd, (long)i * SIZEOF_MSGAREA, SEEK_SET);
  734.       read(fd, (char *)&sys.msg_name, SIZEOF_MSGAREA);
  735.       close (fd);
  736. //      memcpy (&sys, &tsys, SIZEOF_MSGAREA);
  737.  
  738.       if (sys.pip_board) {
  739.          sprintf(filename, "%sMPTR%04x.PIP", pip_msgpath, sys.pip_board);
  740.          fd = cshopen(filename, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  741.          if (fd == -1)
  742.             return (0);
  743.          close(fd);
  744.  
  745.             sprintf(filename, "%sMPKT%04x.PIP", pip_msgpath, sys.pip_board);
  746.          fd = shopen(filename, O_RDONLY|O_BINARY);
  747.          if (fd == -1) {
  748.             fd = cshopen(filename, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  749.             if (fd == -1)
  750.                return (0);
  751.             filename[0] = filename[1] = '\0';
  752.             write (fd, filename, 2);
  753.          }
  754.          close (fd);
  755.       }
  756.       else if (sys.quick_board) {
  757.          sprintf (filename, "%sMSG*.BBS", fido_msgpath);
  758.          if (!dexists (filename))
  759.             return (0);
  760.       }
  761.       else if (sys.gold_board) {
  762.          sprintf (filename, "%sMSG*.DAT", fido_msgpath);
  763.          if (!dexists (filename))
  764.             return (0);
  765.       }
  766.         else if (sys.squish) {
  767.             ptr = MsgOpenArea (sys.msg_path, MSGAREA_CRIFNEC, MSGTYPE_SQUISH);
  768.             if (ptr == NULL)
  769.                 return (0);
  770.             MsgCloseArea (ptr);
  771.       }
  772.       else {
  773.          sys.msg_path[strlen (sys.msg_path) - 1] = '\0';
  774.          if (!dexists (sys.msg_path))
  775.             return (0);
  776.          sys.msg_path[strlen (sys.msg_path)] = '\\';
  777.       }
  778.     }
  779.    else if (type == 2) {
  780.       sprintf(filename,"%sSYSFILE.DAT", config->sys_path);
  781.       while ((fd = sopen (filename, SH_DENYNONE, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE)) == -1)
  782.          ;
  783.       lseek (fd, (long)i * SIZEOF_FILEAREA, SEEK_SET);
  784.       read(fd, (char *)&tsys.file_name, SIZEOF_FILEAREA);
  785.  
  786.       if (caller && usr.name[0]) {
  787.          if (usr.priv < tsys.file_priv) {
  788.             close(fd);
  789.             return (0);
  790.          }
  791.          if ((usr.flags & tsys.file_flags) != tsys.file_flags) {
  792.             close(fd);
  793.             return (0);
  794.          }
  795.       }
  796.  
  797.       lseek (fd, (long)i * SIZEOF_FILEAREA, SEEK_SET);
  798.       read(fd, (char *)&sys.file_name, SIZEOF_FILEAREA);
  799.       close(fd);
  800. //      memcpy (&sys.file_name, &tsys.file_name, SIZEOF_FILEAREA);
  801.  
  802.       sys.filepath[strlen (sys.filepath) - 1] = '\0';
  803.       if (!dexists (sys.filepath)) {
  804.          sys.filepath[0] = '\0';
  805.          return (0);
  806.       }
  807.       sys.filepath[strlen (sys.filepath)] = '\\';
  808.    }
  809.  
  810.    return (1);
  811. }
  812.  
  813. int read_system2 (s, type, tsys)
  814. int s, type;
  815. struct _sys *tsys;
  816. {
  817.    int fd, nsys, i, mn=0;
  818.    char filename[50];
  819.     struct _sys_idx sysidx[10];
  820.     offline_reader =0;
  821.  
  822.     if (type != 1 && type != 2)
  823.         return (0);
  824.  
  825.     if (sq_ptr != NULL) {
  826.         MsgCloseArea (sq_ptr);
  827.         sq_ptr = NULL;
  828.     }
  829.  
  830.     if (type == 1)
  831.         sprintf(filename,"%sSYSMSG.IDX", config->sys_path);
  832.     else if (type == 2)
  833.         sprintf(filename,"%sSYSFILE.IDX", config->sys_path);
  834.  
  835.     fd = cshopen(filename, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  836.     if (fd == -1)
  837.         return (0);
  838.  
  839.     do {
  840.         nsys = read(fd, (char *)&sysidx, sizeof(struct _sys_idx) * 10);
  841.         nsys /= sizeof (struct _sys_idx);
  842.         for (i=0; i < nsys; i++, mn++) {
  843.             if (sysidx[i].area == s)
  844.                 break;
  845.         }
  846.     } while (i == nsys && nsys == 10);
  847.  
  848.     close (fd);
  849.  
  850.     if (i == nsys || sysidx[i].priv > usr.priv || (usr.flags & sysidx[i].flags) != sysidx[i].flags)
  851.         return (0);
  852.  
  853.     i = mn;
  854.  
  855.    if (type == 1) {
  856.       sprintf(filename,SYSMSG_PATH, config->sys_path);
  857.       fd = cshopen(filename, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  858.       if (fd == -1)
  859.          return (0);
  860.       lseek (fd, (long)i * SIZEOF_MSGAREA, SEEK_SET);
  861.       read(fd, (char *)&tsys->msg_name, SIZEOF_MSGAREA);
  862.       close(fd);
  863.    }
  864.    else if (type == 2) {
  865.       sprintf(filename,"%sSYSFILE.DAT", config->sys_path);
  866.       fd = cshopen(filename, O_RDWR|O_BINARY|O_CREAT, S_IREAD|S_IWRITE);
  867.       if (fd == -1)
  868.          return (0);
  869.       lseek (fd, (long)i * SIZEOF_FILEAREA, SEEK_SET);
  870.       read(fd, (char *)&tsys->file_name, SIZEOF_FILEAREA);
  871.       close(fd);
  872.    }
  873.  
  874.    return (1);
  875. }
  876.  
  877. void user_list(args)
  878. char *args;
  879. {
  880.    char stringa[40], linea[80], *p, handle, swap, vote, filebox;
  881.    int fd, line, act, nn, day, mont, year;
  882.    int mdays[] = {31,28,31,30,31,30,31,31,30,31,30,31};
  883.    long days, now;
  884.    struct _usr tempusr;
  885.  
  886.    nopause = 0;
  887.     line = 3;
  888.    act = 0;
  889.    nn = 0;
  890.    filebox = vote = handle = swap = 0;
  891.  
  892.    cls();
  893.  
  894.    change_attr(YELLOW|_BLACK);
  895.    if ((p=strstr (args,"/H")) != NULL)
  896.       handle = 1;
  897.    if ((p=strstr (args,"/F")) != NULL)
  898.       filebox = 1;
  899.    if ((p=strstr (args,"/V")) != NULL)
  900.       vote = 1;
  901.    if ((p=strstr (args,"/S")) != NULL)
  902.       swap = 1;
  903.    if ((p=strstr (args,"/L")) != NULL) {
  904.       act = 1;
  905.       if (p[2] == '=')
  906.          nn = atoi(&p[3]);
  907.       else {
  908.          if (!get_command_word (stringa, 5)) {
  909.             m_print(bbstxt[B_MIN_DAYS_LIST]);
  910.             input(stringa,5);
  911.          }
  912.          if (stringa[0] == '\0')
  913.             nn = 15;
  914.          nn = atoi(stringa);
  915.       }
  916.       data (stringa);
  917.       sscanf(stringa, "%2d %3s %2d", &day, linea, &year);
  918.       linea[3] = '\0';
  919.       for (mont = 0; mont < 12; mont++) {
  920.             if ((!stricmp(mtext[mont], linea)) || (!stricmp(mesi[mont], linea)))
  921.             break;
  922.       }
  923.       now = (long)year*365;
  924.       for (line=0;line<mont;line++)
  925.          now += mdays[line];
  926.       now += day;
  927.    }
  928.    else if ((p=strstr (args,"/T")) != NULL) {
  929.       act = 2;
  930.       if (p[2] == '=')
  931.          nn = atoi(&p[3]);
  932.       else {
  933.          if (!get_command_word (stringa, 5)) {
  934.             m_print(bbstxt[B_MIN_CALLS_LIST]);
  935.             input(stringa,5);
  936.          }
  937.          if (stringa[0] == '\0')
  938.             nn = 10;
  939.          nn = atoi(stringa);
  940.       }
  941.    }
  942.    else {
  943.       if (!get_command_word (stringa, 35)) {
  944.          m_print(bbstxt[B_ENTER_USERNAME]);
  945.          input(stringa,35);
  946.       }
  947.       act = 0;
  948.    }
  949.  
  950.    strupr(stringa);
  951.  
  952.    cls();
  953.     change_attr(YELLOW|_BLACK);
  954.    m_print(bbstxt[B_USERLIST_TITLE]);
  955.    m_print(bbstxt[B_USERLIST_UNDERLINE]);
  956.  
  957.    sprintf(linea, "%s.BBS", config->user_file);
  958.    fd=shopen(linea,O_RDONLY|O_BINARY);
  959.  
  960.    while(read(fd,(char *)&tempusr,sizeof(struct _usr)) == sizeof (struct _usr)) {
  961.       if (tempusr.usrhidden || tempusr.deleted || !tempusr.name[0])
  962.          continue;
  963.  
  964.       if (filebox && !tempusr.havebox)
  965.          continue;
  966.  
  967.       if (vote && tempusr.priv != vote_priv)
  968.          continue;
  969.  
  970.       if (handle)
  971.          strcpy (tempusr.name, tempusr.handle);
  972.  
  973.       if (act == 0) {
  974.          strupr(tempusr.name);
  975.  
  976.          if (strstr(tempusr.name,stringa) == NULL)
  977.             continue;
  978.  
  979.          fancy_str(tempusr.name);
  980.       }
  981.       else if (act == 1) {
  982.          sscanf(tempusr.ldate, "%2d %3s %2d", &day, linea, &year);
  983.          linea[3] = '\0';
  984.          for (mont = 0; mont < 12; mont++) {
  985.             if ((!stricmp(mtext[mont], linea)) || (!stricmp(mesi[mont], linea)))
  986.                     break;
  987.          }
  988.          days = (long)year*365;
  989.          for (line=0;line<mont;line++)
  990.             days += mdays[line];
  991.          days += day;
  992.          if ((int)(now-days) > nn)
  993.             continue;
  994.       }
  995.       else if (act == 2) {
  996.          if (tempusr.times < (long)nn)
  997.             continue;
  998.       }
  999.  
  1000.       if (swap) {
  1001.          strcpy (linea, tempusr.name);
  1002.          p = strchr (linea, '\0');
  1003.          while (*p != ' ' && p != linea)
  1004.             p--;
  1005.          if (p != linea)
  1006.             *p++ = '\0';
  1007.          strcpy (tempusr.name, p);
  1008.          strcat (tempusr.name, " ");
  1009.          strcat (tempusr.name, linea);
  1010.       }
  1011.  
  1012.       m_print(bbstxt[B_USERLIST_FORMAT], tempusr.name, tempusr.city, tempusr.ldate, tempusr.times, tempusr.n_dnld, tempusr.n_upld);
  1013.       if (!(line=more_question(line)))
  1014.          break;
  1015.    }
  1016.  
  1017.    close(fd);
  1018.    m_print(bbstxt[B_ONE_CR]);
  1019.  
  1020.    if (line)
  1021.       press_enter();
  1022. }
  1023.  
  1024. int logoff_procedure()
  1025. {
  1026.    read_system_file("LOGOFF");
  1027.  
  1028.    if (!local_mode && !terminal && CARRIER)
  1029.       timer (2);
  1030.  
  1031.    return (1);
  1032. }
  1033.  
  1034. void update_user (void)
  1035. {
  1036.    int online, fd, i, m, fflag, posit;
  1037.    char filename[80];
  1038.    long prev, crc;
  1039.    struct _useron useron;
  1040.    struct _usridx usridx[MAX_INDEX];
  1041.  
  1042.    if (!local_mode)
  1043.       FLUSH_OUTPUT ();
  1044.  
  1045.    sprintf (filename, USERON_NAME, config->sys_path);
  1046.    if ((fd = sh_open (filename, SH_DENYNONE, O_RDWR|O_BINARY, S_IREAD|S_IWRITE)) != -1) {
  1047.       for (;;) {
  1048.          prev = tell (fd);
  1049.  
  1050.          if (read (fd, (char *)&useron, sizeof (struct _useron)) != sizeof (struct _useron))
  1051.             break;
  1052.  
  1053.          if (useron.line == line_offset) {
  1054.             lseek (fd, prev, SEEK_SET);
  1055.             memset ((char *)&useron, 0, sizeof (struct _useron));
  1056.             write (fd, (char *)&useron, sizeof (struct _useron));
  1057.             break;
  1058.          }
  1059.       }
  1060.  
  1061.       close (fd);
  1062.    }
  1063.  
  1064.    if (usr.name[0] && usr.city[0] && usr.pwd[0]) {
  1065.       fflag = 0;
  1066.       posit = 0;
  1067.  
  1068.       crc = crc_name (usr.name);
  1069.  
  1070.       sprintf (filename, "%s.IDX", config->user_file);
  1071.       fd = sh_open (filename, SH_DENYWR, O_RDWR|O_BINARY, S_IREAD|S_IWRITE);
  1072.  
  1073.       do {
  1074.          i = read (fd, (char *)&usridx, sizeof (struct _usridx) * MAX_INDEX);
  1075.          m = i / sizeof (struct _usridx);
  1076.  
  1077.          for (i = 0; i < m; i++)
  1078.             if (usridx[i].id == crc) {
  1079.                m = 0;
  1080.                posit += i;
  1081.                fflag = 1;
  1082.                break;
  1083.             }
  1084.  
  1085.             if (!fflag)
  1086.             posit += m;
  1087.       } while (m == MAX_INDEX && !fflag);
  1088.  
  1089.       close (fd);
  1090.  
  1091.       if (!fflag)
  1092.          status_line ("!Can't update %s", usr.name);
  1093.       else {
  1094.          online = (int)((time (NULL) - start_time) / 60);
  1095.          usr.time += online;
  1096.          if (lorainfo.logindate[0])
  1097.             strcpy (usr.ldate, lorainfo.logindate);
  1098.  
  1099.          sprintf (filename, "%s.BBS", config->user_file);
  1100.          fd = sh_open (filename, SH_DENYWR, O_RDWR|O_BINARY, S_IREAD|S_IWRITE);
  1101.          lseek (fd, (long)posit * sizeof (struct _usr), SEEK_SET);
  1102.          write (fd, (char *)&usr, sizeof (struct _usr));
  1103.          close (fd);
  1104.  
  1105.          set_last_caller ();
  1106.       }
  1107.  
  1108.       online = (int)((time (NULL) - start_time) / 60);
  1109.       status_line("+%s off-line. Calls=%ld, Len=%d, Today=%d", usr.name, usr.times, online, usr.time);
  1110.       sysinfo.today.humanconnects += time (NULL) - start_time;
  1111.       sysinfo.week.humanconnects += time (NULL) - start_time;
  1112.       sysinfo.month.humanconnects += time (NULL) - start_time;
  1113.       sysinfo.year.humanconnects += time (NULL) - start_time;
  1114.    }
  1115.  
  1116.    memset (usr.name, 0, 36);
  1117. }
  1118.  
  1119. void space (int s)
  1120. {
  1121.    int i;
  1122.  
  1123.    for (i = 0; i < s; i++) {
  1124.       if (!local_mode)
  1125.          BUFFER_BYTE (' ');
  1126.       if (snooping)
  1127.          wputc (' ');
  1128.    }
  1129.  
  1130.    if (!local_mode)
  1131.       UNBUFFER_BYTES ();
  1132. }
  1133.  
  1134. static void compilation_data (void)
  1135. {
  1136.   #define COMPILER      "Borland C"
  1137.   #define COMPVERMAJ    1
  1138.   #define COMPVERMIN    50
  1139.  
  1140.   m_print (bbstxt[B_COMPILER], __DATE__, __TIME__, COMPILER, COMPVERMAJ, COMPVERMIN);
  1141. }
  1142.  
  1143. void show_lastcallers (char *args)
  1144. {
  1145.    int fd, i, line;
  1146.    char linea[82], filename[80];
  1147.    struct _lastcall lc;
  1148.  
  1149.    sprintf(filename, "%sLASTCALL.BBS", config->sys_path);
  1150.    fd = shopen(filename, O_RDONLY|O_BINARY);
  1151.  
  1152.    memset((char *)&lc, 0, sizeof(struct _lastcall));
  1153.  
  1154.    cls();
  1155.    sprintf(linea,bbstxt[B_TODAY_CALLERS], system_name);
  1156.    i = (80 - strlen(linea)) / 2;
  1157.    space(i);
  1158.    change_attr(WHITE|_BLACK);
  1159.    m_print("%s\n",linea);
  1160.    change_attr(LRED|_BLACK);
  1161.    strnset(linea, '-', strlen(linea));
  1162.    i = (80 - strlen(linea)) / 2;
  1163.    space(i);
  1164.    m_print("%s\n\n",linea);
  1165.    change_attr(LGREEN|_BLACK);
  1166.    m_print(bbstxt[B_CALLERS_HEADER]);
  1167.    change_attr(GREEN|_BLACK);
  1168.    m_print("-------------------------------------------------------------------------------\n");
  1169.  
  1170.    line = 5;
  1171.    i = atoi(args);
  1172.  
  1173.    while (read(fd, (char *)&lc, sizeof(struct _lastcall)) == sizeof(struct _lastcall)) {
  1174.       if (i && lc.line != i)
  1175.          continue;
  1176.  
  1177.       change_attr(LCYAN|_BLACK);
  1178.       sprintf(linea,"%-20.20s ", lc.name);
  1179.       m_print(linea);
  1180.       change_attr(WHITE|_BLACK);
  1181.       m_print("%2d    ", lc.line);
  1182.       m_print("%6lu ", (long)lc.baud * 100L);
  1183.       m_print("    %s ", lc.logon);
  1184.       m_print("  %s ", lc.logoff);
  1185.       m_print(" %5d  ", lc.times);
  1186.       change_attr(YELLOW|_BLACK);
  1187.       sprintf(linea," %s", lc.city);
  1188.       linea[19] = '\0';
  1189.       m_print("%s\n",linea);
  1190.  
  1191.       if (!(line = more_question(line)) || !CARRIER)
  1192.          break;
  1193.    }
  1194.  
  1195.    close(fd);
  1196.    m_print (bbstxt[B_ONE_CR]);
  1197.  
  1198.    if (line)
  1199.       press_enter ();
  1200. }
  1201.  
  1202. void bulletin_menu (args)
  1203. char *args;
  1204. {
  1205.    int max_input;
  1206.    char stringa[10], *p, *a, filename[80];
  1207.  
  1208.    p = args;
  1209.    while ((a=strchr(p,':')) != NULL || (a=strchr(p,'\\')) != NULL)
  1210.       p = a+1;
  1211.  
  1212.    max_input = 8 - strlen(p);
  1213.  
  1214.    for (;;) {
  1215.       if (!get_command_word (stringa, max_input)) {
  1216.          if (!read_file (args))
  1217.             return;
  1218.          input (stringa, max_input);
  1219.          if (!stringa[0] || !CARRIER || time_remain() <= 0)
  1220.             return;
  1221.       }
  1222.  
  1223.       strcpy (filename, args);
  1224.       strcat (filename, stringa);
  1225.       read_file (filename);
  1226.       press_enter ();
  1227.    }
  1228. }
  1229.  
  1230. void message_to_next_caller ()
  1231. {
  1232.    FILE *fp;
  1233.    int i;
  1234.    char filename[80];
  1235.    long t;
  1236.    struct tm *tim;
  1237.  
  1238.    line_editor (0);
  1239.  
  1240.    m_print(bbstxt[B_DATABASE]);
  1241.    if (yesno_question (DEF_YES) == DEF_NO) {
  1242.       free_message_array ();
  1243.       return;
  1244.    }
  1245.  
  1246.    sprintf(filename,"%sNEXT%d.BBS",config->sys_path,line_offset);
  1247.    fp = fopen(filename,"wb");
  1248.    if (fp == NULL) {
  1249.       free_message_array ();
  1250.       return;
  1251.    }
  1252.  
  1253.    memset((char *)&msg,0,sizeof(struct _msg));
  1254.    msg.attr = MSGLOCAL;
  1255.  
  1256.    msg.dest_net=config->alias[sys.use_alias].net;
  1257.    msg.dest=config->alias[sys.use_alias].node;
  1258.    strcpy (msg.from, usr.name);
  1259.    strcpy (msg.subj, "Logout comment");
  1260.    data(msg.date);
  1261.    msg.up=0;
  1262.    msg_fzone=config->alias[sys.use_alias].zone;
  1263.    msg.orig=config->alias[sys.use_alias].node;
  1264.    msg.orig_net=config->alias[sys.use_alias].net;
  1265.    time(&t);
  1266.    tim=localtime(&t);
  1267.    msg.date_written.date=(tim->tm_year-80)*512+(tim->tm_mon+1)*32+tim->tm_mday;
  1268.    msg.date_written.time=tim->tm_hour*2048+tim->tm_min*32+tim->tm_sec/2;
  1269.    msg.date_arrived.date=msg.date_written.date;
  1270.    msg.date_arrived.time=msg.date_written.time;
  1271.  
  1272.    fwrite((char *)&msg,sizeof(struct _msg),1,fp);
  1273.  
  1274.    i = 0;
  1275.    while (messaggio[i] != NULL) {
  1276.       if (messaggio[i][strlen(messaggio[i])-1] == '\r')
  1277.          fprintf(fp,"%s\n", messaggio[i++]);
  1278.       else
  1279.          fprintf(fp,"%s\r\n", messaggio[i++]);
  1280.    }
  1281.  
  1282.    fclose (fp);
  1283.    free_message_array ();
  1284.  
  1285.    status_line(":Write message to next caller");
  1286. }
  1287.  
  1288. void read_comment ()
  1289. {
  1290.    FILE *fp;
  1291.    int line = 1;
  1292.    char filename[130];
  1293.    struct _msg msgt;
  1294.  
  1295.    sprintf(filename,"%sNEXT%d.BBS",config->sys_path,line_offset);
  1296.    fp = fopen(filename,"rb");
  1297.    if (fp == NULL)
  1298.       return;
  1299.  
  1300.    fread((char *)&msgt,sizeof(struct _msg),1,fp);
  1301.    strcpy (msgt.to, usr.name);
  1302.  
  1303.    cls ();
  1304.    line = msg_attrib(&msgt, 0, line, 0);
  1305.    m_print(bbstxt[B_ONE_CR]);
  1306.    change_attr(LGREY|_BLACK);
  1307.  
  1308.    while (fgets(filename,128,fp) != NULL) {
  1309.       while (strlen (filename) > 0 && (filename[strlen (filename) - 1] == 0x0D || filename[strlen (filename) - 1] == 0x0A))
  1310.          filename[strlen (filename) -1] = '\0';
  1311.       m_print ("%s\n", filename);
  1312.       if (!(line=more_question(line)) || !CARRIER)
  1313.          break;
  1314.    }
  1315.  
  1316.    fclose(fp);
  1317.  
  1318.    UNBUFFER_BYTES ();
  1319.    FLUSH_OUTPUT();
  1320.  
  1321.    if (line) {
  1322.       m_print (bbstxt[B_ONE_CR]);
  1323.       press_enter ();
  1324.    }
  1325.  
  1326.    sprintf(filename,"%sNEXT%d.BBS",config->sys_path,line_offset);
  1327.    unlink (filename);
  1328. }
  1329.  
  1330. #define IsBis(y) (!(y % 4) && ((y % 100) || !(y % 400)))
  1331.  
  1332. void display_usage ()
  1333. {
  1334.    int i, y_axis[15], z, m, dd, mm, aa, month[13];
  1335.    long total, tempo, day_now;
  1336.    struct tm *tim;
  1337.  
  1338.    month[1] = 31;
  1339.    month[2] = 28;
  1340.    month[3] = 31;
  1341.    month[4] = 30;
  1342.    month[5] = 31;
  1343.    month[6] = 30;
  1344.    month[7] = 31;
  1345.    month[8] = 31;
  1346.    month[9] = 30;
  1347.    month[10] = 31;
  1348.    month[11] = 30;
  1349.    month[12] = 31;
  1350.  
  1351.    tempo = time (&tempo);
  1352.    tim = localtime (&tempo);
  1353.  
  1354.    total = 365 * tim->tm_year;
  1355.    if (IsBis (tim->tm_year))
  1356.       month[2] = 29;
  1357.    else
  1358.       month[2] = 28;
  1359.    for (i = 1; i < (tim->tm_mon + 1); i++)
  1360.       total += month[i];
  1361.    total += tim->tm_mday;
  1362.    total *= 60;
  1363.  
  1364.    sscanf (linestat.startdate, "%2d-%2d-%2d", &mm, &dd, &aa);
  1365.  
  1366.    day_now = 365 * aa;
  1367.    if (IsBis (aa))
  1368.       month[2] = 29;
  1369.    else
  1370.       month[2] = 28;
  1371.    for (i = 1; i < mm; i++)
  1372.       day_now += month[i];
  1373.    day_now += dd;
  1374.    day_now *= 60;
  1375.  
  1376.    total -= day_now;
  1377.    total += 60;
  1378.  
  1379.    for (i = 0; i < 15; i++)
  1380.       y_axis[i] = 0;
  1381.  
  1382.    if (total > 0)
  1383.       for (i = 0; i < 24; i++)
  1384.       {
  1385.          m = (int)((linestat.busyperhour[i] * 100L) / total);
  1386.          if (m > y_axis[14])
  1387.             y_axis[14] = m;
  1388.       }
  1389.  
  1390.    m = y_axis[14] / 15;
  1391.  
  1392.    for (i = 13; i >= 0; i--)
  1393.       y_axis[i] = y_axis[i+1] - m;
  1394.  
  1395.    cls ();
  1396.    m_print (bbstxt[B_PERCENTAGE], linestat.startdate, tim->tm_mon+1, tim->tm_mday, tim->tm_year % 100, line_offset);
  1397.  
  1398.    for (i = 14; i >= 0; i--) {
  1399.       m_print (bbstxt[B_PERCY], y_axis[i]);
  1400.       for (z = 0; z < 24; z++) {
  1401.          if (total > 0)
  1402.             m = (int)((linestat.busyperhour[z] * 100L) / total);
  1403.          else
  1404.             m = -1;
  1405.          if (m >= y_axis[i] && m > 0)
  1406.             m_print ("██ ");
  1407.          else
  1408.             m_print ("   ");
  1409.       }
  1410.  
  1411.       m_print (bbstxt[B_ONE_CR]);
  1412.    }
  1413.  
  1414.    m_print (bbstxt[B_PERCX1]);
  1415.    m_print (bbstxt[B_PERCX2]);
  1416.  
  1417.    press_enter ();
  1418. }
  1419.  
  1420. void time_statistics ()
  1421. {
  1422.    long t, this_call;
  1423.    struct tm *tim;
  1424.  
  1425.    this_call = (long)((time(&t) - start_time));
  1426.    tim = localtime (&t);
  1427.  
  1428.    m_print (bbstxt[B_TSTATS_1], tim->tm_hour, tim->tm_min);
  1429.    m_print (bbstxt[B_TSTATS_2], tim->tm_mday, mtext[tim->tm_mon], tim->tm_year);
  1430.                                                                                 
  1431.    m_print (bbstxt[B_TSTATS_3], (int)(this_call/60), (int)(this_call % 60));
  1432.  
  1433.    this_call += usr.time * 60;
  1434.    m_print (bbstxt[B_TSTATS_4], (int)(this_call/60), (int)(this_call % 60));
  1435.    m_print (bbstxt[B_TSTATS_5], time_remain ());
  1436.    m_print (bbstxt[B_TSTATS_6], config->class[usr_class].max_call);
  1437.  
  1438.    press_enter ();
  1439. }
  1440.  
  1441.