home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1935 / chat.c next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  8.9 KB  |  414 lines

  1. /*
  2.  
  3. chat
  4. Written by D'Arcy J.M. Cain
  5. All rights reserved
  6.  
  7. This is the front end to the chatter program.  It is run by any number
  8. of users who wish to communicate conference style with each other.  The
  9. chatter program serves each user.
  10.  
  11. Permission is hereby granted to freely copy and redistribute this
  12. software, provided that the author is clearly credited in all
  13. copies and derivations.  This software is provided ``As Is'' and
  14. without any express or implied warranties.
  15.  
  16. */
  17.  
  18. #include    <stdio.h>
  19. #include    <stdlib.h>
  20. #include    <string.h>
  21. #include    <curses.h>
  22. #include    <signal.h>
  23. #include    <process.h>
  24. #include    <getopt.h>
  25. #include    <ctype.h>
  26. #include    <errno.h>
  27. #include    "chat.h"
  28.  
  29. char chat_rcsid[] = "$Id: chat.c,v 1.1 90/08/19 19:03:22 darcy Exp $";
  30.  
  31. #ifndef    NO_CHG_NAME
  32. static char    *options = "hn:f:";
  33. #else
  34. static char    *options = "hf:";
  35. #endif
  36.  
  37. static FILE        *cap_file = NULL;
  38. static WINDOW    *disp, *inp;
  39.  
  40. #ifdef    HALFDELAY_BROKEN
  41. int        chat_suspended = 0;
  42. #endif
  43.  
  44. void    cleanup(void)        /* come here on just about any signal */
  45. {
  46.     while (chk_q())                    /* clean up your own mess */
  47.         ;
  48.  
  49.     if (cap_file != NULL)
  50.         fclose(cap_file);
  51.  
  52.     chc_send("x");
  53.  
  54.     mvwprintw(inp, 1, 1, "%-77s", "    So long...   It's been nice chatting");
  55.     wrefresh(disp);                    /* display any leftovers */
  56.     wrefresh(inp);                    /* display polite message */
  57.  
  58.     delwin(disp);
  59.     delwin(inp);
  60.     endwin();
  61.     ch_close();
  62.     exit(0);
  63. }
  64.  
  65. void    disp_str(char *str)    /* add latest string to list just above box */
  66. {
  67.     scroll(disp);                /* make room for it first */
  68.     mvwprintw(disp, LINES - 5, 0, "%s", str);
  69.  
  70.     if (cap_file != NULL)        /* save to file if it is open */
  71.         fprintf(cap_file, "%s\n", str);
  72. }
  73.  
  74. static int    need_to_refresh = 0;
  75.  
  76. int        chk_q(void)
  77. {
  78.     char    msgbuf[256];
  79.  
  80.     if (ch_get(msgbuf))
  81.     {
  82.         disp_str(msgbuf);            /*let user know what chatter has to say */
  83.  
  84.         if (*msgbuf == 'e')            /* is chatter telling us to get lost? */
  85.         {
  86.             wrefresh(disp);            /* display anything pending */
  87.             cleanup();                /* take the Big Sleep */
  88.         }
  89.  
  90.         need_to_refresh = -1;
  91.         return(1);                    /* let caller know */
  92.     }
  93.  
  94.     return(0);                        /* nothing happened */
  95. }
  96.  
  97. #ifndef    NO_SH_ESC
  98. static void    run_command(char *s)
  99. {
  100.     int        status, pid, w, tty;
  101.     void    (*istat)(), (*qstat)();
  102.  
  103.     if ((tty = open("/dev/tty", 2)) == -1)
  104.     {
  105.         fprintf(stderr, "Can't open /dev/tty\n");
  106.         return;
  107.     }
  108.  
  109.     if ((pid = fork()) == 0)
  110.     {
  111.         close(0); dup(tty);
  112.         close(1); dup(tty);
  113.         close(1); dup(tty);
  114.         close(tty);
  115.         execlp("sh", "sh", (*s ? "-c" : NULL), s, NULL);
  116.         exit(0);        /* note:  We don't care about failure here */
  117.     }
  118.  
  119.     close(tty);
  120.     istat = signal(SIGINT, SIG_IGN);
  121.     qstat = signal(SIGQUIT, SIG_IGN);
  122.  
  123.     while ((w = wait(&status)) != pid)
  124.         if ((w == -1) && (errno != EINTR))
  125.             break;
  126.  
  127.     signal(SIGINT, istat);
  128.     signal(SIGQUIT, qstat);
  129. }
  130. #endif
  131.  
  132. void    help(void)
  133. {
  134.     WINDOW    *w;
  135.     int        k;
  136.     static char *help_msg[] = {
  137.         "CHAT - multi user conference utility",
  138.         "Written by D'Arcy J.M. Cain (darcy@druid.uucp)",
  139.         "Copyright 1990 - All rights reserved",
  140.         "$Revision: 1.1 $\b " + 1,
  141.         "",
  142.         "chat commands consist of a slash (/) followed by a command",
  143.         "   ?     this Help screen",
  144. #ifndef    NO_SH_ESC
  145.         "   !     shell Escape",
  146. #endif
  147.         "   c     Change channel i.e: \"/c3\" - change to channel 3",
  148.         "         Note: \"/c*\" will change to first empty channel",
  149.         "   h     Same as ?",
  150. #ifndef    NO_CHG_NAME
  151.         "   n     change Name to following string",
  152. #endif
  153.         "   r     Redraw screen",
  154. #ifndef    NO_SHOW_USERS
  155.         "   s     Show current users using chat",
  156. #endif
  157.         "   x     eXit from chat",
  158.         "",
  159.         "                       Hit a key to continue ..."
  160.     };
  161. #define    HELP_SZ    (sizeof(help_msg)/sizeof(char *))    
  162.  
  163.     w = newwin(HELP_SZ + 3, 71, 1, 3);    /* get a new window */
  164.     box(w, 0, 0);                        /* and box it */
  165.  
  166.     for (k = 0; k < HELP_SZ; k++)        /*  display the help screen */
  167.         mvwprintw(w, k + 1, 3, "%s", help_msg[k]);
  168.  
  169.     wrefresh(w);        /* show the screen */
  170.  
  171.     while (wgetch(w) == ERR)
  172.         ;                /* wait for keystroke */
  173.  
  174.     delwin(w);            /* clear the window */
  175.     touchwin(disp);        /* update display window */
  176.     wrefresh(disp);        /* get everything back in sync */
  177.     wrefresh(inp);
  178. }
  179.  
  180. int        main(int argc, char **argv)
  181. {
  182.     int        c;
  183.     char    entry[512], *ptr = NULL, *ptr1, msgbuf[256];
  184.  
  185.     if ((ptr1 = ch_init()) != NULL)
  186.     {
  187.         perror(ptr1);
  188.         return(1);
  189.     }
  190.  
  191.     /* curses stuff */
  192.     initscr();
  193.     nonl();
  194.     noecho();
  195.     cbreak();
  196. #ifndef    HALFDELAY_BROKEN
  197.     halfdelay(20);
  198. #endif
  199.  
  200.     /* make sure we always exit through cleanup */
  201.     signal(SIGINT, cleanup);
  202.     signal(SIGABRT, cleanup);
  203.     signal(SIGQUIT, cleanup);
  204.     signal(SIGKILL, cleanup);
  205.     signal(SIGTERM, cleanup);
  206.  
  207.     disp = newwin(LINES - 4, COLS, 0, 0);    /* conversation window */
  208.     idlok(disp, TRUE);
  209.     scrollok(disp, TRUE);
  210.  
  211.     inp = newwin(3, COLS, LINES - 4, 0);    /* input window */
  212.     box(inp, 0, 0);
  213.  
  214.     mvwprintw(inp, 1, 1, "-> ");            /* prompt string */
  215.  
  216.     while ((c = getopt(argc, argv, options)) != -1)
  217.     {
  218.         switch (c)
  219.         {
  220.             case '?':
  221.             default:
  222.                 sprintf(entry, "%s: Invalid option %c", argv[0], c);
  223.                 disp_str(entry);
  224.  
  225.             case 'h':
  226.                 sprintf(entry,
  227. #ifndef    NO_CHG_NAME
  228.                     "Usage: %s [-h] [-c channel] [-n name] [-f file]",
  229. #else
  230.                     "Usage: %s [-h] [-c channel] [-f file]",
  231. #endif
  232.                     argv[0]);
  233.                 disp_str(entry);
  234.                 cleanup();
  235.                 break;
  236.  
  237. #ifndef    NO_CHG_NAME
  238.             case 'n':
  239.                 ptr = optarg;
  240.                 break;
  241. #endif
  242.  
  243.             case 'f':
  244.                 if ((cap_file = fopen(optarg, "a")) == NULL)
  245.                 {
  246.                     sprintf(entry, "Can't open log file: %s", SYS_ERRLIST);
  247.                     cleanup();
  248.                 }
  249.                 break;
  250.         }
  251.     }
  252.     
  253.     disp_str("chat - multi user conferencing utility");    /* signon string */
  254.     disp_str("Written by D'Arcy J.M. Cain");
  255.     disp_str("Copyright 1990 by D'Arcy J.M. Cain - All rights reserved");
  256.     disp_str("$Revision: 1.1 $\b " + 1);
  257.     disp_str("");
  258.  
  259.     /* open chat link */
  260.     ch_init();
  261.     sprintf(entry, "o%s", (ptr == NULL) ? cuserid(NULL) : ptr);
  262.     chc_send(entry);
  263.     sleep(1);                                /* messages are not FIFO     */
  264.  
  265.     disp_str("Enter /h or /? for help");
  266.     disp_str("");
  267.     wrefresh(disp);
  268.  
  269.     ptr = entry;
  270.     chc_send("s");                            /* get list of current users */
  271.  
  272.     for (;;)                    /* loop till the cows come home */
  273.     {
  274.         while (chk_q())
  275.             ;
  276.  
  277.         if (need_to_refresh)
  278.             wrefresh(disp);        /* refresh display if necessary*/
  279.  
  280.         wrefresh(inp);            /* refresh this to place cursor */
  281.  
  282.         if ((c = wgetch(inp)) != ERR);    /* if got a character (not timed out) */
  283.         {
  284.             if (c == 4)
  285.                 cleanup();    /* end of session ? */
  286.  
  287.             if (c == '\r')    /* end of line ? */
  288.             {
  289.                 *ptr = 0;                    
  290.  
  291.                 if (*entry == '/')        /* command? */
  292.                 {
  293.                     switch (entry[1])
  294.                     {
  295.                         case '?':        /* request for help */
  296.                         case 'h':
  297.                             help();
  298.                             break;
  299.  
  300. #ifndef    NO_SH_ESC
  301.                         case '!':        /* shell escape */
  302.                             ptr = entry + 2;
  303.                             while (isspace(*ptr))
  304.                                 ptr++;
  305.  
  306. #ifdef    HALFDELAY_BROKEN
  307.                             chat_suspended = 1;
  308. #endif
  309.                             endwin();
  310.                             run_command(ptr);
  311.                             printf("\n[Press 'Enter' to continue ...]");
  312.  
  313.                             while (gets(entry) == NULL)
  314.                                 ;
  315.  
  316.                             doupdate();
  317. #ifdef    HALFDELAY_BROKEN
  318.                             chat_suspended = 0;
  319. #endif
  320.                             break;
  321. #endif
  322.  
  323.                         case 'l':        /* redraw screen */
  324.                         case 'r':
  325.                             clearok(disp, TRUE);    /* update display window */
  326.                             clearok(inp, TRUE);        /* update input window */
  327.                             wrefresh(disp);            /* redraw both windows */
  328.                             wrefresh(inp);
  329.                             clearok(disp, FALSE);    /* reset display window */
  330.                             clearok(inp, FALSE);    /* reset input window */
  331.                             break;
  332.  
  333. #ifndef    NO_CHG_NAME
  334.                         case 'n':        /* these are passed to chatter */
  335. #endif
  336. #ifndef    NO_SHOW_USERS
  337.                         case 's':
  338. #endif
  339.                         case 'c':
  340.                             ptr = entry + 2;
  341.                             while (isspace(*ptr))
  342.                                 ptr++;
  343.                             sprintf(msgbuf, "%c%s", entry[1], ptr);
  344.                             chc_send(msgbuf);
  345.                             break;
  346.  
  347.                         case 'x':        /* exit from chat */
  348.                         case 'q':        /* for Dennis Breckenridge :-) */
  349.                             cleanup();
  350.                             break;
  351.  
  352.                         default:
  353.                             beep();
  354.                     }
  355.                 }
  356.                 else if (*entry)        /* else send it if not blank */
  357.                 {
  358.                     sprintf(msgbuf, "m%s", entry);
  359.                     chc_send(msgbuf);
  360.                 }
  361.  
  362.                 ptr = entry;    /* reset input box */
  363.                 mvwprintw(inp, 1, 1, "%77s", "");
  364.                 mvwprintw(inp, 1, 1, "-> ");
  365.             }
  366.             else if (c == '\b')    /* take care of backspaces */
  367.             {
  368.                 if (ptr != entry)
  369.                 {
  370.                     wprintw(inp, "\b \b");
  371.                     ptr--;
  372.                 }
  373.             }
  374.             else if (c == '\t')    /* expand tabs */
  375.             {
  376.                 ptr1 = ptr + 8 - ((ptr - entry) % 8);
  377.                 while (ptr != ptr1)
  378.                 {
  379.                     *(ptr++) = ' ';
  380.                     waddch(inp, ' ');
  381.                 }
  382.             }
  383.             else if ((c >= ' ') && (c < 0x7f))    /* otherwise if printable */
  384.             {
  385.                 if ((ptr - entry) > 62)            /* time for word wrap? */
  386.                 {
  387.                     *(ptr++) = c;                /* don't lose latest char */
  388.                     *ptr = 0;                    /* terminate string */
  389.  
  390.                     while (!isspace(*ptr))        /* find latest space */
  391.                     {
  392.                         if (--ptr == entry)        /* special case - no spaces */
  393.                         {
  394.                             ptr += strlen(entry);
  395.                             *(ptr + 2) = 0;
  396.                             break;
  397.                         }
  398.                     }
  399.  
  400.                     *(ptr++) = 0;                /* change space to zero */
  401.                     sprintf(msgbuf, "m%s", entry);
  402.                     chc_send(msgbuf);
  403.                     strcpy(entry, ptr);            /* change string to leftover */
  404.                     ptr = entry + strlen(entry);
  405.                     mvwprintw(inp, 1, 1, "%77s", "");    /* clear input box */
  406.                     mvwprintw(inp, 1, 1, "-> %s", entry);    /* print string */
  407.                 }
  408.                 else
  409.                     waddch(inp, (*(ptr++) = c));        /* print character */
  410.             }
  411.         }
  412.     }
  413. }
  414.