home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / LO241SRV.ZIP / chat.c < prev    next >
Text File  |  1998-08-01  |  22KB  |  872 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 <stdlib.h>
  21. #include <ctype.h>
  22. #include <string.h>
  23. #include <io.h>
  24. #include <share.h>
  25. #include <fcntl.h>
  26. #include <dos.h>
  27. #include <time.h>
  28. #include <sys/stat.h>
  29.  
  30. #define INCL_DOSPROCESS
  31. #include <os2.h>
  32.  
  33. #include <cxl\cxlvid.h>
  34. #include <cxl\cxlwin.h>
  35. #include <cxl\cxlstr.h>
  36.  
  37. #include "lsetup.h"
  38. #include "sched.h"
  39. #include "msgapi.h"
  40. #include "externs.h"
  41. #include "prototyp.h"
  42.  
  43. void VioUpdate (void);
  44. static int cb_online_users(int, int, int);
  45. static void chat_wrap (char *, int);
  46. static void cb_send_message (char *, int);
  47.  
  48. void online_users(int flag, int use_alias)
  49. {
  50.    int fd, i, line;
  51.    char linea[128];
  52.    struct _useron useron;
  53.  
  54.    cls();
  55.    sprintf(linea,bbstxt[B_ONLINE_USERS], system_name);
  56.    i = (80 - strlen(linea)) / 2;
  57.    space(i);
  58.    change_attr(WHITE|_BLACK);
  59.    m_print("%s\n",linea);
  60.    change_attr(LRED|_BLACK);
  61.    strnset(linea, '-', strlen(linea));
  62.    i = (80 - strlen(linea)) / 2;
  63.    space(i);
  64.    m_print("%s\n\n",linea);
  65.    m_print(bbstxt[B_ONLINE_HEADER]);
  66.    m_print(bbstxt[B_ONLINE_UNDERLINE]);
  67.  
  68.    line = 5;
  69.    sprintf(linea,USERON_NAME, config->sys_path);
  70.    fd = shopen(linea, O_RDONLY|O_BINARY);
  71.  
  72.    while (read(fd, (char *)&useron, sizeof (struct _useron)) == sizeof (struct _useron)) {
  73.       if (useron.donotdisturb || useron.line_status == 0)
  74.          continue;
  75.  
  76.       useron.city[21] = '\0';
  77.  
  78.       if (use_alias)
  79.          sprintf (linea, " %-25.25s  %4d  %6lu  %-14.14s  %s\n", useron.alias, useron.line, useron.baud, useron.status, useron.city);
  80.       else
  81.          sprintf (linea, " %-25.25s  %4d  %6lu  %-14.14s  %s\n", useron.name, useron.line, useron.baud, useron.status, useron.city);
  82.       m_print (linea);
  83.  
  84.       if (!(line = more_question (line)) || !CARRIER)
  85.          break;
  86.    }
  87.  
  88.    close(fd);
  89.    m_print(bbstxt[B_ONE_CR]);
  90.  
  91.    if (flag && CARRIER)
  92.       press_enter ();
  93. }
  94.  
  95. void send_online_message (int use_alias)
  96. {
  97.    FILE *fp;
  98.    int fd, ul;
  99.    char linea[80], filename[80];
  100.    struct _useron useron;
  101.  
  102.    if (!get_command_word (linea, 4)) {
  103.       online_users(0, use_alias);
  104.  
  105.       change_attr(CYAN|_BLACK);
  106.       m_print(bbstxt[B_SELECT_USER]);
  107.       input(linea, 4);
  108.    }
  109.  
  110.    if (!strlen(linea) || atoi(linea) <= 0 || !CARRIER)
  111.       return;
  112.  
  113.    ul = atoi(linea) - 1;
  114.    change_attr(LRED|_BLACK);
  115.  
  116.    sprintf(filename, USERON_NAME, config->sys_path);
  117.    fd = shopen(filename, O_RDONLY|O_BINARY);
  118.    lseek (fd, (long)ul * sizeof(struct _useron), SEEK_SET);
  119.  
  120.    if (read(fd, (char *)&useron, sizeof(struct _useron)) != sizeof(struct _useron) || useron.donotdisturb || !useron.name[0]) {
  121.       m_print(bbstxt[B_INVALID_LINE]);
  122.       close (fd);
  123.       return;
  124.    }
  125.  
  126.    close (fd);
  127.    strltrim (cmd_string);
  128.  
  129.    if (!cmd_string[0]) {
  130.       if (use_alias)
  131.          m_print(bbstxt[B_MESSAGE_FOR], useron.alias);
  132.       else
  133.          m_print(bbstxt[B_MESSAGE_FOR], useron.name);
  134.       change_attr(WHITE|_BLACK);
  135.       m_print(":");
  136.       input(linea, 77);
  137.       if (!strlen(linea) || !CARRIER)
  138.          return;
  139.    }
  140.    else {
  141.       cmd_string[77] = '0';
  142.       strcpy (linea, cmd_string);
  143.       cmd_string[0] = '\0';
  144.    }
  145.  
  146.    change_attr(CYAN|_BLACK);
  147.    m_print(bbstxt[B_PROCESSING]);
  148.  
  149.    sprintf (filename, ONLINE_MSGNAME, ipc_path, ul+1);
  150.    if ((fp = sh_fopen (filename, "at", SH_DENYWR)) != NULL) {
  151.       fprintf (fp, bbstxt[B_IPC_HEADER]);
  152.       fprintf (fp, bbstxt[B_IPC_FROM], usr.name, line_offset);
  153.       fprintf (fp, bbstxt[B_IPC_MESSAGE], linea);
  154.       fprintf (fp, "\001");
  155.       fclose (fp);
  156.    }
  157.  
  158.    m_print (bbstxt[B_MESSAGE_SENT]);
  159.    press_enter ();
  160. }
  161.  
  162. void set_mailon (zz, ne, no, po, location)
  163. int zz, ne, no, po;
  164. char *location;
  165. {
  166.    char string[80];
  167.  
  168.    memset ((char *)&usr, 0, sizeof (struct _usr));
  169.    sprintf (string, "%d:%d/%d.%d", zz, ne, no, po);
  170.    strcpy (usr.name, string);
  171.    strcpy (string, location);
  172.    if (strlen (string) > 25)
  173.       string[25] = '\0';
  174.    strcpy (usr.city, string);
  175.    usr.quiet = 1;
  176.    data (usr.ldate);
  177.    set_useron_record (NOCHANGE, 0, 0);
  178. }
  179.  
  180. void reset_mailon (void)
  181. {
  182.    int fd;
  183.    char filename[80];
  184.    long prev;
  185.    struct _useron useron;
  186.  
  187.    set_last_caller ();
  188.  
  189.    sprintf (filename, USERON_NAME, config->sys_path);
  190.    fd = shopen (filename, O_RDWR|O_BINARY);
  191.  
  192.    while (fd != -1) {
  193.       prev = tell (fd);
  194.  
  195.       if (read (fd, (char *)&useron, sizeof(struct _useron)) != sizeof(struct _useron))
  196.          break;
  197.  
  198.       if (useron.line == line_offset) {
  199.          lseek(fd,prev,SEEK_SET);
  200.          memset((char *)&useron, 0, sizeof(struct _useron));
  201.          write (fd, (char *)&useron, sizeof(struct _useron));
  202.          break;
  203.       }
  204.    }
  205.  
  206.    close(fd);
  207. }
  208.  
  209. void set_useron_record (int sta, int toggle, int cb)
  210. {
  211.    int fd, i;
  212.    char filename[80], *p;
  213.    static char first = 1;
  214.    long prev;
  215.    struct _useron useron;
  216.  
  217.    sprintf (filename, USERON_NAME, config->sys_path);
  218.    fd = cshopen (filename, O_CREAT|O_RDWR|O_BINARY,S_IREAD|S_IWRITE);
  219.  
  220.    memset ((char *)&useron, 0, sizeof(struct _useron));
  221.  
  222.    if (lseek (fd, (line_offset-1) * (long)sizeof(struct _useron), SEEK_SET) == -1) {
  223.       for (i = 0; i < line_offset; i++) {
  224.          prev = tell (fd);
  225.          if (read (fd, (char *)&useron, sizeof (struct _useron)) != sizeof (struct _useron))
  226.             write (fd, (char *)&useron, sizeof (struct _useron));
  227.       }
  228.    }
  229.    else {
  230.       prev = tell (fd);
  231.       read (fd, (char *)&useron, sizeof (struct _useron));
  232.    }
  233.  
  234.    if (first) {
  235.       first = 0;
  236.       useron.donotdisturb = usr.quiet;
  237.    }
  238.  
  239.    strcpy (useron.name, usr.name);
  240.    strcpy (useron.city, usr.city);
  241.    useron.line = (short)line_offset;
  242.    useron.baud = local_mode ? 0 : rate;
  243.  
  244.    if (sta != NOCHANGE) {
  245.       useron.line_status = (short)sta;
  246.       user_status = (char)sta;
  247.  
  248.       switch (sta) {
  249.          case WFC:
  250.             p = "Idle";
  251.             strcpy (useron.name, "Waiting for Call");
  252.             break;
  253.          case LOGIN:
  254.             p = "Login";
  255.             break;
  256.          case BROWSING:
  257.             p = "Browsing";
  258.             break;
  259.          case UPLDNLD:
  260.             p = "Up/Downl";
  261.             break;
  262.          case READWRITE:
  263.             p = "R/Write";
  264.             break;
  265.          case DOOR:
  266.             p = "Ext.Door";
  267.             break;
  268.          case CHATTING:
  269.             p = "CB Chat";
  270.             break;
  271.          case QUESTIONAIRE:
  272.             p = "New user";
  273.             break;
  274.          case QWKDOOR:
  275.             p = "QWK Door";
  276.             break;
  277.          default:
  278.             p = "???";
  279.             break;
  280.       }
  281.  
  282.       strcpy (useron.status, p);
  283.    }
  284.  
  285.    if (toggle)
  286.       useron.donotdisturb ^= 1;
  287.  
  288.    useron.cb_channel = (short)cb;
  289.  
  290.    lseek (fd, prev, SEEK_SET);
  291.    write (fd, (char *)&useron, sizeof (struct _useron));
  292.    close (fd);
  293. }
  294.  
  295. int check_multilogon(user_name)
  296. char *user_name;
  297. {
  298.    int fd, rc = 0;
  299.    char filename[80];
  300.    struct _useron useron;
  301.  
  302.    sprintf (filename, USERON_NAME, config->sys_path);
  303.    fd = shopen (filename, O_RDONLY|O_BINARY);
  304.  
  305.    while (read (fd, (char *)&useron, sizeof(struct _useron)) == sizeof(struct _useron))
  306.       if (!strcmp (useron.name, user_name) && useron.line != line_offset) {
  307.          rc = 1;
  308.          break;
  309.       }
  310.  
  311.    close (fd);
  312.  
  313.    return (rc);
  314. }
  315.  
  316. void cb_who_is_where (flag)
  317. int flag;
  318. {
  319.    int i, line;
  320.  
  321.    line = 0;
  322.  
  323.    for (i = 1; i <= 40; i++)
  324.    {
  325.       if (!(line=cb_online_users (2, i, line)))
  326.          break;
  327.    }
  328.  
  329.    if (flag && CARRIER && line)
  330.       press_enter();
  331. }
  332.  
  333. static int cb_online_users(flag, cb_num, line)
  334. int flag, cb_num;
  335. {
  336.         int fd, i, first;
  337.         char linea[82];
  338.         struct _useron useron;
  339.  
  340.         if (flag != 2)
  341.                 cls();
  342.         first = 1;
  343.  
  344.         line += 5;
  345.         sprintf (linea, USERON_NAME, config->sys_path);
  346.         fd = shopen (linea, O_RDONLY|O_BINARY);
  347.  
  348.         while (read (fd, (char *)&useron, sizeof(struct _useron)) == sizeof(struct _useron)) {
  349.                 if (!useron.name[0] || useron.cb_channel != cb_num)
  350.                         continue;
  351.  
  352.                 if (first) {
  353.                         sprintf(linea,bbstxt[B_CALLERS_ON_CHANNEL], cb_num);
  354.                         i = (80 - strlen(linea)) / 2;
  355.                         space(i);
  356.                         change_attr(WHITE|_BLACK);
  357.                         m_print("%s\n",linea);
  358.                         if (!(line = more_question(line)) || !CARRIER)
  359.                                 break;
  360.                         change_attr(LRED|_BLACK);
  361.                         strnset(linea, '-', strlen(linea));
  362.                         i = (80 - strlen(linea)) / 2;
  363.                         space(i);
  364.                         m_print("%s\n\n",linea);
  365.                         if (!(line = more_question(line)) || !CARRIER)
  366.                                 break;
  367.                         m_print(bbstxt[B_CHANNEL_HEADER]);
  368.                         if (!(line = more_question(line)) || !CARRIER)
  369.                                 break;
  370.                         m_print(bbstxt[B_CHANNEL_UNDERLINE]);
  371.                         if (!(line = more_question(line)) || !CARRIER)
  372.                                 break;
  373.  
  374.                         first = 0;
  375.                 }
  376.  
  377.                 change_attr(LCYAN|_BLACK);
  378.                 sprintf(linea,"%-30.30s ", useron.name);
  379.                 m_print(linea);
  380.                 change_attr(WHITE|_BLACK);
  381.                 m_print("%2d    ", useron.line);
  382.                 m_print("  %5u   ", useron.baud);
  383.                 change_attr(YELLOW|_BLACK);
  384.                 sprintf(linea,"%s\n", useron.city);
  385.                 linea[24] = '\0';
  386.                 m_print(linea);
  387.  
  388.                 if (!(line = more_question(line)) || !CARRIER)
  389.                         break;
  390.         }
  391.  
  392.         close(fd);
  393.  
  394.         if (!first)
  395.                 m_print("\n");
  396.  
  397.         if (flag == 1 && CARRIER && line)
  398.                 press_enter();
  399.  
  400.         return (line);
  401. }
  402.  
  403.  
  404. void cb_chat (void)
  405. {
  406.    int fd2, ul, cb_num, endrun, i;
  407.    char linea[80], filename[100], wrp[80];
  408.    long cb_time;
  409.  
  410.    endrun = 0;
  411.    cb_num = 1;
  412.    set_useron_record (CHATTING, 0, cb_num);
  413.    wrp[0] = '\0';
  414.  
  415.    cls ();
  416.    status_line ("+Entering the CB-Chat system");
  417.  
  418.    cb_online_users (0, cb_num, 0);
  419.    m_print (bbstxt[B_CB_CHAT_HELP1]);
  420.    m_print (bbstxt[B_CB_CHAT_HELP2]);
  421.  
  422.    sprintf (filename, "\n\n%s  joins the conversation.\n\n", usr.name);
  423.    cb_send_message (filename, cb_num);
  424.  
  425.    change_attr (LGREEN|_BLACK);
  426.    sprintf (linea, "\n[%-15.15s]: ", usr.name);
  427.    m_print (linea);
  428.  
  429.    cb_time = timerset (100);
  430.  
  431.    do {
  432.       i = local_mode ? local_kbd : PEEKBYTE ();
  433.  
  434.       if (time_remain () <= 0) {
  435.          change_attr (LRED|_BLACK);
  436.          m_print (bbstxt[B_TIMEOUT]);
  437.          terminating_call ();
  438.          return;
  439.       }
  440.  
  441.       if (wrp[0])
  442.          i = 0;
  443.  
  444.       if (i != -1) {
  445.          change_attr( (int)color_chat (line_offset) );
  446.          inp_wrap(linea, wrp, 60);
  447.  
  448.          if (linea[0] && linea[0] != '/') {
  449.             sprintf(filename, "è[%-15.15s]: %c%s\n", usr.name, color_chat (line_offset), linea);
  450.             cb_send_message (filename, cb_num);
  451.             cb_time = timerset(50);
  452.          }
  453.          else if (linea[0] == '/') {
  454.             switch (toupper(linea[1])) {
  455.                case 'C':
  456.                   ul = atoi(&linea[2]);
  457.                   if (ul >= 1 && ul <= 40) {
  458.                      if (cb_num != ul) {
  459.                         sprintf(filename, "\n\n%s  leaves the conversation.\n\n", usr.name);
  460.                         cb_send_message (filename, cb_num);
  461.                         sprintf(filename, "\n\n%s  joins the conversation.\n\n", usr.name);
  462.                         cb_send_message (filename, ul);
  463.                      }
  464.                      cb_num = ul;
  465.                      set_useron_record(CHATTING, 0, cb_num);
  466.                      status_line("#CB-Chat Channel %d", cb_num);
  467.                      cb_online_users(1, cb_num, 0);
  468.                   }
  469.                   break;
  470.                case 'H':
  471.                   read_system_file("CB_HELP");
  472.                   break;
  473.                case 'Q':
  474.                   endrun = 1;
  475.                   sprintf(filename, "\n\n%s  leaves the conversation.\n\n", usr.name);
  476.                   cb_send_message (filename, cb_num);
  477.                   break;
  478.                case 'W':
  479.                   cb_online_users(1, cb_num, 0);
  480.                   m_print( "\n");
  481.                   break;
  482.                case 'A':
  483.                   cb_who_is_where (0);
  484.                   m_print( "\n");
  485.                   break;
  486.             }
  487.          }
  488.  
  489.          if (!endrun) {
  490.             change_attr(LGREEN|_BLACK);
  491.             sprintf(linea, "[%-15.15s]: ", usr.name);
  492.             m_print( linea);
  493.          }
  494.       }
  495.  
  496.       if (timeup (cb_time)) {
  497.          sprintf (filename, CBSIM_NAME, ipc_path, line_offset);
  498.          fd2 = cshopen (filename, O_RDONLY|O_BINARY, S_IREAD|S_IWRITE);
  499.          if (fd2 != -1) {
  500.             if (filelength (fd2) > 0L) {
  501.                close (fd2);
  502.                m_print ("\r");
  503.                if (read_file (filename))
  504.                   unlink (filename);
  505.  
  506.                change_attr (LGREEN|_BLACK);
  507.                sprintf (linea, "[%-15.15s]: ", usr.name);
  508.                m_print (linea);
  509.             }
  510.          }
  511.  
  512.          cb_time = timerset (100);
  513.       }
  514.       else
  515.          time_release ();
  516.    } while (!endrun && CARRIER);
  517.  
  518.    if (CARRIER) {
  519.       set_useron_record (BROWSING, 0, 0);
  520.       status_line ("+Leaving the CB-Chat system");
  521.    }
  522. }
  523.  
  524. static void cb_send_message (message, cb_num)
  525. char *message;
  526. int cb_num;
  527. {
  528.    int fd, fd2;
  529.    char filename [80];
  530.    long cb_time;
  531.    struct _useron useron;
  532.  
  533.    sprintf(filename,USERON_NAME, config->sys_path);
  534.    fd = shopen(filename, O_RDONLY|O_BINARY);
  535.  
  536.    while (read(fd, (char *)&useron, sizeof(struct _useron)) == sizeof(struct _useron)) {
  537.       if (!useron.name[0] || useron.cb_channel != cb_num)
  538.          continue;
  539.       if (useron.line == line_offset)
  540.          continue;
  541.  
  542.       sprintf(filename, CBSIM_NAME, ipc_path, useron.line);
  543.       cb_time = timerset (100);
  544.       do {
  545.          fd2 = sopen(filename, O_CREAT|O_WRONLY|O_APPEND|O_BINARY, SH_DENYRW, S_IREAD|S_IWRITE);
  546.          if (fd2 != -1)
  547.             write (fd2, message, strlen (message));
  548.       } while (!timeup (cb_time) && fd2 == -1);
  549.  
  550.       if (fd2 == -1)
  551.          status_line ("!CB-CHAT: Locking problems");
  552.       else
  553.          close (fd2);
  554.    }
  555.  
  556.    close(fd);
  557. }
  558.  
  559. unsigned char color_chat (task)
  560. int task;
  561. {
  562.    switch (task % 7)
  563.    {
  564.       case 1:
  565.          return (15);
  566.       case 2:
  567.          return (11);
  568.       case 3:
  569.          return (12);
  570.       case 4:
  571.          return (13);
  572.       case 5:
  573.          return (15);
  574.       case 6:
  575.          return (9);
  576.    }
  577.  
  578.    return (15);
  579. }
  580.  
  581. void yelling_at_sysop (char *arguments)
  582. {
  583.    FILE *fp;
  584.    int i, wh, secs = 0;
  585.    char linea[128], s1[20], s2[20], s3[20], *p;
  586.    long maxt;
  587.    struct dosdate_t dosdate;
  588.    struct time dostime;
  589.      
  590.    _dos_getdate (&dosdate);
  591.  
  592.    if (config->page_start[dosdate.dayofweek] || config->page_end[dosdate.dayofweek]) {
  593.       gettime (&dostime);
  594.       i = dostime.ti_hour * 60 + dostime.ti_min;
  595.  
  596.       if (i < config->page_start[dosdate.dayofweek] || i > config->page_end[dosdate.dayofweek]) {
  597.          read_system_file ("NOTAVAIL");
  598.          return;
  599.       }
  600.    }
  601.    else {
  602.       read_system_file ("NOTAVAIL");
  603.       return;
  604.    }
  605.  
  606.    if ((p = stristr (arguments, "/A=\"")) != NULL) {
  607.       strcpy (linea, &p[4]);
  608.       p = strtok (linea, "\"");
  609.       m_print (p);
  610.    }
  611.    else
  612.       m_print (bbstxt[B_YELLING]);
  613.  
  614.    hidecur ();
  615.  
  616.    wh = wopen (10, 23, 15, 55, 1, LCYAN|_BLUE, LCYAN|_BLUE);
  617.    wactiv (wh);
  618.    wtitle ("╡ Sysop Page ╞", TCENTER, LCYAN|_BLUE);
  619.  
  620.    wcenters (1, LCYAN|_BLUE, "[C] To break in for a chat");
  621.    wcenters (2, LCYAN|_BLUE, "[A] To terminate the page ");
  622.  
  623.    if ((p = stristr (arguments, "/T=")) != NULL)
  624.       secs = atoi (&p[3]);
  625.  
  626.    if (!secs)
  627.       maxt = -1L;
  628.    else
  629.       maxt = timerset (secs * 100);
  630.  
  631.    if ((p = stristr (arguments, "/F=")) != NULL) {
  632.       strcpy (linea, &p[3]);
  633.       p = strtok (linea, " ");
  634.    }
  635.    else
  636.       p = "PAGE.DAT";
  637.  
  638.    if ((fp = fopen (p, "rt")) != NULL) {
  639.       for (;;) {
  640.          if (maxt != -1L && timeup (maxt))
  641.             break;
  642.  
  643.          if (fgets(linea, 127, fp) == NULL) {
  644.             if (maxt == -1L)
  645.                break;
  646.             rewind (fp);
  647.             if (fgets(linea, 127, fp) == NULL)
  648.                break;
  649.          }
  650.  
  651.          linea[strlen(linea)-1] = '\0';
  652.          if (!strlen(linea) || linea[0] == ';' || linea[0] == '%')
  653.             continue;
  654.  
  655.          sscanf(linea,"%s %s %s",s1, s2, s3);
  656.  
  657.          if (!stricmp (s1, "TONE")) {
  658.         if (!usr.nerd)
  659.            DosBeep (atol (s2), atol (s3) * 10);
  660.         else
  661.            DosSleep (atol (s3) * 100);
  662.         time_release ();
  663.         if ( toupper(local_kbd) == 'C') {
  664.            wclose();
  665.            wactiv (mainview);
  666.            fclose (fp);
  667.            sysop_chatting ();
  668.            return;
  669.         }
  670.         if ( toupper(local_kbd) == 'A')
  671.            break;
  672.      }
  673.      else if (!stricmp (s1, "WAIT")) {
  674.         DosSleep (atol (s2) * 10);
  675.         time_release ();
  676.         if ( toupper(local_kbd) == 'C') {
  677.            wclose();
  678.            wactiv (mainview);
  679.            fclose (fp);
  680.            sysop_chatting ();
  681.            return;
  682.         }
  683.         if ( toupper(local_kbd) == 'A')
  684.            break;
  685.      }
  686.  
  687.      if ( toupper(local_kbd) == 'A') {
  688.         local_kbd = -1;
  689.         break;
  690.      }
  691.       }
  692.  
  693.       fclose (fp);
  694.    }
  695.  
  696.    wclose();
  697.    wactiv (mainview);
  698.  
  699.    if (snooping)
  700.       showcur ();
  701.  
  702.    read_system_file ("PAGED");
  703. }
  704.  
  705.  
  706. void sysop_chatting ()
  707. {
  708.    char wrp[80];
  709.    long start_write;
  710.  
  711.    showcur ();
  712.  
  713.    lorainfo.wants_chat = 0;
  714.    if (function_active == 1)
  715.       f1_status();
  716.  
  717.    if (local_mode) {
  718.       sysop_error ();
  719.       return;
  720.    }
  721.  
  722.    local_kbd = -1;
  723.    start_write = time(NULL);
  724.  
  725.    status_line ("+Sysop entered chat mode");
  726.    if (!read_system_file ("STARTCHT"))
  727.       m_print(bbstxt[B_BREAKING_CHAT]);
  728.  
  729.    wrp[0]='\0';
  730.  
  731.    while (local_kbd != 0x1B) {
  732.       chat_wrap(wrp, 79);
  733.       if (!CARRIER)
  734.          return;
  735.    }
  736.  
  737.    status_line ("+Chat mode ended");
  738.    if (!read_system_file ("ENDCHT"))
  739.       m_print(bbstxt[B_CHAT_END]);
  740.    local_kbd = -1;
  741.    local_mode = 0;
  742.  
  743.    allowed += (int)((time(NULL)-start_write)/60);
  744.    usr.chat_minutes = (short)((time(NULL)-start_write)/60);
  745. }
  746.  
  747. static void chat_wrap(wrp, width)
  748. char *wrp;
  749. int width;
  750. {
  751.    static char color = YELLOW|_BLACK;
  752.    unsigned char c, s[80];
  753.    int z, i, m;
  754.  
  755.    strcpy (s, wrp);
  756.    z = strlen (wrp);
  757.  
  758.    m_print ("%c%s", color, wrp);
  759.  
  760.    while (z < width) {
  761.       UNBUFFER_BYTES ();
  762.       VioUpdate ();
  763.  
  764.       while (PEEKBYTE () == -1 && local_kbd == -1) {
  765.          if (!CARRIER)
  766.             return;
  767.          time_release ();
  768.       }
  769.  
  770.       if (PEEKBYTE () != -1) {
  771.          c = (unsigned char )TIMED_READ (1);
  772.          if (color != (CYAN + _BLACK)) {
  773.             color = CYAN|_BLACK;
  774.             change_attr (color);
  775.          }
  776.       }
  777.       else if (local_kbd != -1) {
  778.          c = (char)local_kbd;
  779.          if (c == 0x1B)
  780.             return;
  781.          local_kbd = -1;
  782.          if (color != (YELLOW + _BLACK)) {
  783.             color = YELLOW|_BLACK;
  784.             change_attr (color);
  785.          }
  786.       }
  787.  
  788.       if (c == 0x0D && z == 0) {
  789.          m_print ("\n");
  790.          s[0] = '\0';
  791.          wrp[0] = '\0';
  792.          return;
  793.       }
  794.  
  795.       if ((c == 0x08 || c == 0x7F) && (z > 0)) {
  796.          s[--z] = '\0';
  797.          SENDBYTE ('\b');
  798.          SENDBYTE (' ');
  799.          SENDBYTE ('\b');
  800.          if (snooping)
  801.             wputs ("\b \b");
  802.       }
  803.  
  804.       if (c < 20 && c != 0x0D && c != 0x7F)
  805.          continue;
  806.  
  807.       s[z++] = c;
  808.  
  809.       if (c == 0x0D) {
  810.          m_print ("\n");
  811.          s[z] = '\0';
  812.          wrp[0] = '\0';
  813.          return;
  814.       }
  815.  
  816.       SENDBYTE (c);
  817.       if (snooping)
  818.          wputc (c);
  819.    }
  820.  
  821.    s[z] = '\0';
  822.  
  823.    while (z > 0 && s[z] != ' ')
  824.       z--;
  825.  
  826.    m = 0;
  827.  
  828.    if (z != 0) {
  829.       for (i = z + 1; i <= width; i++) {
  830.          SENDBYTE (0x08);
  831.          wrp[m++] = s[i];
  832.          if (snooping)
  833.             wputs ("\b");
  834.          s[i] = '\0';
  835.       }
  836.  
  837.       space (width - z);
  838.    }
  839.  
  840.    wrp[m] = '\0';
  841.    m_print ("\n");
  842. }
  843.  
  844. void broadcast_message (message)
  845. char *message;
  846. {
  847.    int fd, fd2;
  848.    char filename[80];
  849.    struct _useron useron;
  850.    long cb_time;
  851.  
  852.    sprintf(filename, USERON_NAME, config->sys_path);
  853.    fd = shopen(filename, O_RDONLY|O_BINARY);
  854.  
  855.    while (read(fd, (char *)&useron, sizeof(struct _useron)) == sizeof(struct _useron)) {
  856.       if (!useron.name[0] || useron.donotdisturb)
  857.          continue;
  858.       if (useron.line == line_offset)
  859.          continue;
  860.  
  861.       sprintf(filename, ONLINE_MSGNAME, ipc_path, useron.line);
  862.       cb_time = timerset (100);
  863.       do {
  864.          fd2 = sopen(filename, O_CREAT|O_WRONLY|O_APPEND|O_BINARY, SH_DENYRW, S_IREAD|S_IWRITE);
  865.          if (fd2 != -1)
  866.              write (fd2, message, strlen (message));
  867.       } while (!timeup (cb_time) && fd2 == -1);
  868.    }
  869.  
  870.    close(fd);
  871. }
  872.