From: turgd00@DMI.USherb.CA (DAVID TURGEON)
Subject: Small C program to CHAT with
Organization: Universite de Sherbrooke -- Dept. d'Informatique
Date: Fri, 20 Nov 1992 06:07:16 GMT

Here's a small program a friend made to monitor a port that enables 
Chat with anyone that can Telnet. (this is usefull when two people
are on different systems with no chat compability.


====== CUT HERE and Compile using 'cc' or something ============

/***********************************************************************
** cht.c -- quick and dirty internet chat program
**
*************************************************************************
** cht is a poorly written program that allows a person to telnet to the
** cht server,
** and send messages to the person running cht.
**
** The program waits for a TCP/IP connection to the specified port number
** (default is defined as PORTNUM), and when it gets a connection,
** it spawns 2 children. One child listens for data on the connection,
** and when it receives anything, it writes it to stdout, and the second
** child waits for input from stdin, and when it gets any, it writes it
** to the network.
**
** Currently, two commands (not case sensitive) are recognized (from the
**    network side only).
**   /bye closes the connection
**   /beep sends a beep to the terminal running cht, and prints "beep"
**
**
** As I said, this is a kludgey program, and can certainly be written more
** efficiently. Also, most of the network stuff was borrowed from
** another program, who's original purpose was to do remote tape
** tape copies from  a VMS system.
**
************************************************************************
** Also, feel free to modify, expand on, improve, or anything else you want
**    to do to this code.
**
** I take no responsibility for any use, or abuse of this software, and
**    I certainly do not guarantee it's usability -- if you don't
**    like it, don't use it.
**
*************************************************************************/
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/mtio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
 
#define PORTNUM 1227
#define MAXHOSTNAME 255
#define INBUFSIZ 1024
 
 
main(argc, argv)
    int     argc;
    char   *argv[];
{
    int     s, t, dummy = -1;
    int     port;
 
    if (argc == 2) {
        if (sscanf(argv[1], "%d", &port) != 1) {
            printf("Error - bad port number specified\n");
            exit(1);
        }
    } else
        port = PORTNUM;
    printf("Port = %d\n", port);
 
    if ((s = establish(port)) < 0) {    /* establish port */
        perror("establish");
        printf("s = %d\n", s);
        exit(1);
    }
 
    if ((t = get_connection(s)) == -1) {        /* wait for connection */
        perror("accept");
        exit(1);
    }
    printf("get_connection was completed!\n");
    got_connection(t);
    clean_up(t);
}
 
clean_up(t)
    int     t;
{
    int     rc;
    printf("Closing network\n");
    close(t);
}
 
getlines(t)
    int     t;
{
    int     siz = 0;
    int     i;
    char    buf[255];
    char    cmd[5];
 
    while(1) {
        siz = read_line(t, buf, sizeof(buf));
        for(i = 0; i < sizeof(cmd); i++)
            cmd[i] = toupper(buf[i]);
        if(!memcmp(cmd, "/BYE", 4))
            return(0);
        if(!memcmp(cmd, "/BEEP", 5)) {
            write(1, "\007\n-> *** Beep ***\n", 18);
            continue;
        }
        write(1, "\n-> ", 4);
        write(1, buf, siz);
    }
};
 
putlines(t)
    int     t;
{
    int     siz = 0;
    char    buf[255];
    char    user[255];
    int     user_l;
 
    sprintf(user, "%s> ", cuserid(NULL));
    user_l = strlen(user);
 
    while(1) {
        siz = read_line(0, buf, sizeof(buf));
        write(t, user, user_l);
        write(t, buf, siz);
    }
};
 
got_connection(t)
    int     t;
{
    int pid;
    char msg[255];
 
    sprintf(msg, "\015Welcome to the Cha Internet Message program!!\015\n");
 
    write(t, msg, strlen(msg));
 
    write(1, "\007", 1);
 
    if(fork() == 0) {   /* fork first child to read from net */
        getlines(t);    /*   (and write to local terminal) */
        clean_up(t);
    }
    else if(fork() == 0) { /* and the second to write to net */
        putlines(t);       /*   (and read from local terminal) */
    }
    else {
        wait();
    }
 
};
 
int read_line(s, buf, n)  /* reads until newline encountered */
    int s;
    char *buf;
    int n;
{
    char ch;
    int bcount = 0;
 
    while(bcount < n) {
        if(read(s, &ch, 1) != 1) {
            perror("read");
            abort();
        }
        buf[bcount++] = ch;
        if(ch == '\n') {
            buf[bcount++] = '\015';
            break;
        }
    }
    return(bcount);
}
 
int     establish(portnum)
    unsigned short portnum;
{
    char    myname[MAXHOSTNAME + 1];
    int     s;
    struct sockaddr_in sa;
    struct hostent *hp;
 
    bzero(&sa, sizeof(struct sockaddr_in));
    gethostname(myname, MAXHOSTNAME);
    printf("%s\n", myname);
    /* gethostbyname() doesn't work on WIN/TCP on the VAX */
 
/*
    hp = gethostbyname(myname);
    if(hp == NULL)
        return(-1);
    sa.sin_family = hp->h_addrtype;
*/
    sa.sin_family = AF_INET;
    sa.sin_port = htons(portnum);
    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket ");
        printf("socket failed - s = %d\n", s);
        return (-1);
    }
    printf("s = %d\n", s);
    if (bind(s, &sa, sizeof(sa)) < 0) {
        perror("bind ");
        close(s);
        return (-1);
    }
    printf("s = %d\n", s);
    listen(s, 3);
    printf("s = %d\n", s);
    return (s);
}
 
int     get_connection(s)
    int     s;
{
    struct sockaddr_in isa;
    int     i = sizeof(isa);
    int     t;
 
    if ((t = accept(s, &isa, &i)) < 0)
        return (-1);
    return (t);
};