distTLI/udpserver.c
///////////////////////////////////////////////////////////////////////////////
// Filename: udpserver.c
///////////////////////////////////////////////////////////////////////////////
// Purpose: show how to use UDP (this file: udp server) (TLI version)
//          uses udpclient(.c) as UDP client
///////////////////////////////////////////////////////////////////////////////
// History:
// ========
//
// Date     Time     Name      Description   
// -------- -------- --------  ------------------------------------------------
// 96/02/26 14:17:40 muellerg: created
//
///////////////////////////////////////////////////////////////////////////////
// Feature test switches ///////////////////////////// Feature test switches //
    /* NONE */
// System headers /////////////////////////////////////////// System headers //
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#ifndef sun
#include <strings.h>
#endif
#include <unistd.h>
#include <tiuser.h> 
#include <sys/types.h>
#include <sys/socket.h>
// #include <sys/in.h>              
#ifdef sun
// O_RDWR
#include <sys/fcntl.h>
#endif
// Local headers ///////////////////////////////////////////// Local headers //
#include "../common.h"
// Macros /////////////////////////////////////////////////////////// Macros //
    /* NONE */
// File scope objects /////////////////////////////////// File scope objects //
    /* NONE */
// External variables, functions, and classes ///////////// External objects //
    /* NONE */
// Signal catching functions ///////////////////// Signal catching functions //
    /* NONE */
// Structures, unions, and class definitions /////////////////// Definitions //
    /* NONE */
// Functions and class implementation /// Functions and class implementation //
/*
 * Read the contents of the TLI descriptor and write each line back to
 * the sender.
 */
void do_it(int tfd)
{
    int n, flags;
    char line[MAXLINE];
    struct t_unitdata   *udataptr;
    // Allocate memory for the t_unitdata structure and the address field
    // in that structure.  This allows any size of address to be handled
    // by this function.
    udataptr = (struct t_unitdata *) t_alloc(tfd, T_UNITDATA, T_ADDR);
    if (udataptr == NULL)
        error.system("server: t_alloc error for T_UNITDATA");
    while(true)
    {
        // Read a message from the TLI descriptor and send it back
        // to whomever sent it.
        udataptr->opt.maxlen   = 0;     // don't care about options 
        udataptr->opt.len      = 0;
        udataptr->udata.maxlen = MAXLINE;
        udataptr->udata.len    = MAXLINE;
        udataptr->udata.buf    = line;
        if (t_rcvudata(tfd, udataptr, &flags) < 0)
            error.system("server: t_rcvudata() error");
        if (t_sndudata(tfd, udataptr) < 0)
            error.system("server: t_sndudata() error");
    }
}
// Main /////////////////////////////////////////////////////////////// Main //
/*
 * Example of server using the UDP protocol.
 *
 * paramteters:
 *
 *   argv[1]: port number to bind() & listen() to 
 */
int
main(int argc, char *argv[])
{
    error.set_program_name(argv[0]);    
    if(argc!=2)
    {
        cerr << "Usage: " << argv[0] << " port" << endl;
        exit(EXIT_FAILURE);
    }
    int tfd;
    struct sockaddr_in serv_addr;
    struct t_bind req;
    int portnumber = -1;
    // get port number
    portnumber = atoi(argv[1]);
    if(portnumber <1)
    {
        cerr << "illegal port number" << endl;
        exit(EXIT_FAILURE);
    }
    // Open a UDP endpoint.
    if ( (tfd = t_open(DEV_UDP, O_RDWR, (struct t_info *) 0)) < 0)
    {
        error.warning("server: can't t_open %s", DEV_UDP);
        exit(EXIT_FAILURE);
    }
    // Bind our local address so that the client can send to us.
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family      = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port        = htons(portnumber);
    req.addr.maxlen = sizeof(serv_addr);
    req.addr.len    = sizeof(serv_addr);
    req.addr.buf    = (char *) &serv_addr;
    req.qlen        = 5;
    if (t_bind(tfd, &req, (struct t_bind *) 0) < 0)
        error.system("server: can't t_bind local address");
    do_it(tfd);     // do it all 
        /* NOTREACHED */
    return(EXIT_SUCCESS);
}