convert a single to multiuser.. in c++ program

Discussion in 'C++' started by OZ, Feb 8, 2004.

  1. OZ

    OZ Guest

    the serproxy claim itself a multi-thread proxy thing.

    I have sent email to write the original writer and there is no replay after
    3 weeks. my configuration and setting are good.

    http://www.lspace.nildram.co.uk/freeware.html

    I installed it in rh 9.0

    I found it is single user only.
    do any one know how to change the single program in c program into a
    multi-user?

    /*
    * main.c
    *
    * main module for serproxy
    *
    * (C)1999 Stefano Busti
    *
    */


    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    #if defined(__UNIX__)
    # include <unistd.h>
    # include <fcntl.h>
    # include <sys/time.h>
    #elif defined(__WIN32__)
    # include <windows.h>
    # include <io.h>
    #endif

    #include "sio.h"
    #include "sock.h"
    #include "pipe.h"
    #include "thread.h"
    #include "vlist.h"
    #include "cfglib.h"
    #include "config.h"
    #include "error.h"

    int readcfg(void);
    void cleanup(void);
    int waitclients(void);
    thr_startfunc_t serve_pipe(void *data);
    void debug(void);

    #if defined(__UNIX__)
    char cfgfile[] = "/etc/serproxy.cfg";
    #elif defined(__WIN32__)
    char cfgfile[] = "serproxy.cfg";
    #endif

    cfg_s cfg;
    vlist_s pipes;

    int main(int argc, char **argv)
    {
    if (sock_start())
    return -1;
    vlist_init(&pipes, pipe_destroy);
    cfg_init(&cfg, 0);
    atexit(cleanup);
    readcfg();
    #ifdef DEBUG
    debug();
    #endif
    waitclients();

    return 0;
    }

    void cleanup(void)
    {
    cfg_cleanup(&cfg);
    vlist_cleanup(&pipes);
    sock_finish();
    }

    int readcfg(void)
    {
    char ports[BUFSIZ], *p;
    int port;
    pipe_s *pipe;
    cfg_s local;
    serialinfo_s sinfo;
    char *parity;

    /* Read the global config settings */
    cfg_fromfile(&cfg, cfgfile);

    /* Read the comm port list */
    if (cfg_readbuf(cfgfile, "comm_ports", ports, sizeof(ports)) == NULL)
    errend("Couldn't find 'comm_ports' entry in config file '%s'", cfgfile);

    vlist_clear(&pipes);

    /* Parse the comm ports list */
    p = strtok(ports, ",");
    while (p)
    {
    if (sscanf(p, "%d", &port) > 0)
    {
    pipe = malloc(sizeof(pipe_s));
    //pipe_init(pipe);
    if (pipe == NULL)
    perrend("malloc(pipe_s)");

    cfg_init(&local, port);

    /* Copy global settings to those for current pipe */
    cfg_assign(&local, &cfg);

    /* Set the comm port */
    local.ints[CFG_IPORT].val = port;

    /* Load this pipe's config */
    cfg_fromfile(&local, cfgfile);

    /* Try initializing the pipe */
    if (pipe_init(pipe, local.ints[CFG_INETPORT].val))
    perrend("pipe_init");

    /* Copy over the rest of the pipe's config */
    pipe->timeout = local.ints[CFG_ITIMEOUT].val;
    sinfo.port = port;
    sinfo.baud = local.ints[CFG_IBAUD].val;
    sinfo.stopbits = local.ints[CFG_ISTOP].val;
    sinfo.databits = local.ints[CFG_IDATA].val;

    parity = local.strs[CFG_SPARITY].val;

    if (strcmp(parity, "none") == 0)
    {
    sinfo.parity = SIO_PARITY_NONE;
    }
    else if (strcmp(parity, "even") == 0)
    {
    sinfo.parity = SIO_PARITY_EVEN;
    }
    else if (strcmp(parity, "odd") == 0)
    {
    sinfo.parity = SIO_PARITY_ODD;
    }
    else
    {
    errend("Unknown parity string '%s'", parity);
    }

    if (sio_setinfo(&pipe->sio, &sinfo))
    errend("Unable to configure comm port %d", port);

    /* Finally add the pipe to the pipes list */
    vlist_add(&pipes, pipes.tail, pipe);

    cfg_cleanup(&local);
    }

    p = strtok(NULL, ",");
    }

    /* Clean up local cfg struct */
    cfg_cleanup(&local);

    return 0;
    }

    int waitclients(void)
    {
    int fd_max;
    fd_set fds;
    vlist_i *it;
    pipe_s *pit, *newpipe;
    tcpsock_s *newsock;
    thr_t thread;

    fd_max = 0;
    FD_ZERO(&fds);

    /* Set all sockets to listen */
    for (it = pipes.head; it; it = it->next)
    {
    pit = (pipe_s *)it->data;

    if (tcp_listen(&pit->sock))
    perror("waitclients() - tcp_listen()");
    }

    printf("Serproxy - (C)1999 Stefano Busti - Waiting for clients\n");

    while (1)
    {
    /* Iterate through the pipe list */
    for (it = pipes.head; it; it = it->next)
    {
    pit = (pipe_s *)it->data;

    /* Monitor socket fd of each */
    FD_SET(pit->sock.fd, &fds);

    /* Track max fd */
    if (pit->sock.fd > fd_max)
    fd_max = pit->sock.fd;
    }

    /* Wait for a read ( == accept() in this case) */
    if (select(fd_max + 1, &fds, NULL, NULL, NULL) == -1)
    perrend("waitclients() - select()");


    /* Find which sockets are involved */
    for (it = pipes.head; it; it = it->next)
    {
    pit = (pipe_s *)it->data;

    if (FD_ISSET(pit->sock.fd, &fds))
    {
    /* Create a new pipe struct for the new thread */
    newpipe = malloc(sizeof(pipe_s));
    if (!newpipe)
    perrend("waitclients() - malloc(pipe_s)");

    newpipe->sio = pit->sio;

    /* Try to open serial port */
    if (sio_open(&newpipe->sio))
    {
    tcp_refuse(&pit->sock);
    error("Failed to open comm port - connection refused");
    free(newpipe);
    continue;
    }

    /* Accept the connection */
    newsock = tcp_accept(&pit->sock);

    /* All ok? */
    if (newsock)
    {
    newpipe->sock = *newsock;
    free(newsock);

    newpipe->timeout = pit->timeout;
    newpipe->mutex = pit->mutex;

    /* Create the server thread */
    if (thr_create(&thread, 1, serve_pipe, newpipe))
    {
    error("Feck - thread creation failed");
    free(newpipe);
    }
    else
    {
    fprintf(stderr, "Server thread launched\n");
    }
    }
    else
    {
    perror("waitclients() - accept()");
    free(newpipe);
    }
    }
    }
    }
    return 0;
    }

    /* Main routine for the server threads */
    thr_startfunc_t serve_pipe(void *data)
    {
    char sio_buf[BUFSIZ], sock_buf[BUFSIZ];
    int fd_max, sio_fd, sock_fd;
    int sio_count, sock_count;
    int res, port;
    fd_set rfds, wfds;
    pipe_s *pipe = (pipe_s *)data;
    #if defined(__UNIX__)
    struct timeval tv = {pipe->timeout, 0};
    struct timeval *ptv = &tv;
    #elif defined(__WIN32__)
    struct timeval tv = {0,10000};
    struct timeval *ptv = &tv;
    DWORD msecs = 0, timeout = pipe->timeout * 1000;
    #endif

    port = pipe->sio.info.port;

    /* Only proceed if we can lock the mutex */
    if (thr_mutex_trylock(pipe->mutex))
    {
    error("server(%d) - resource is locked", port);
    }
    else
    {

    sio_count = 0;
    sock_count = 0;
    sio_fd = pipe->sio.fd;
    sock_fd = pipe->sock.fd;
    #if defined(__UNIX__)
    fd_max = sio_fd > sock_fd ? sio_fd : sock_fd;
    #elif defined(__WIN32__)
    fd_max = sock_fd;
    msecs = GetTickCount();
    #endif
    fprintf(stderr, "server(%d) - thread started\n", port);

    while (1)
    {
    FD_ZERO(&rfds);
    FD_ZERO(&wfds);

    #if defined(__UNIX__)
    /* Always ask for read notification to check for EOF */
    FD_SET(sio_fd, &rfds);
    /* Only ask for write notification if we have something to write */
    if (sock_count > 0)
    FD_SET(sio_fd, &wfds);

    /* Reset timeout values */
    tv.tv_sec = pipe->timeout;
    tv.tv_usec = 0;

    #endif
    /* Always ask for read notification to check for EOF */
    FD_SET(sock_fd, &rfds);
    /* Only ask for write notification if we have something to write */
    if (sio_count > 0)
    FD_SET(sock_fd, &wfds);

    //DBG_MSG2("server(%d) waiting for events", port);

    /* Wait for read/write events */
    res = select(fd_max + 1, &rfds, &wfds, NULL, ptv);
    if (res == -1)
    {
    perror2("server(%d) - select()", port);
    break;
    }
    #if defined(__UNIX__)

    /* Use the select result for timeout detection */
    if (res == 0)
    {
    fprintf(stderr, "server(%d) - timed out\n", port);
    break;
    }

    /* Input from serial port? */
    if (FD_ISSET(sio_fd, &rfds))
    #elif defined(__WIN32__)

    if (1)
    #endif
    {
    /* Only read input if buffer is empty */
    if (sio_count == 0)
    {
    sio_count = sio_read(&pipe->sio, sio_buf, sizeof(sio_buf));
    if (sio_count <= 0)
    {
    if (sio_count == 0)
    {
    #if defined(__UNIX__)
    fprintf(stderr, "server(%d) - EOF from sio\n", port);
    break;
    #endif
    }
    else
    {
    perror2("server(%d) - read(sio)", port);
    break;
    }
    }
    else
    {
    DBG_MSG3("server(%d) - read %d bytes from sio", port, sio_count);
    }
    }
    }

    /* Write to socket possible? */
    if (FD_ISSET(sock_fd, &wfds))
    {
    if (sio_count > 0)
    {
    if ((res = tcp_write(&pipe->sock, sio_buf, sio_count)) < 0)
    {
    perror2("server(%d) - write(sock)", port);
    break;
    }
    DBG_MSG3("server(%d) - Wrote %d bytes to sock", port, res);
    sio_count -= res;
    }
    }


    /* Input from socket? */
    if (FD_ISSET(sock_fd, &rfds))
    {
    /* Only read input if buffer is empty */
    if (sock_count == 0)
    {
    sock_count = tcp_read(&pipe->sock, sock_buf, sizeof(sock_buf));
    if (sock_count <= 0)
    {
    if (sock_count == 0)
    {
    fprintf(stderr, "server(%d) - EOF from sock\n", port);
    break;
    }
    else
    {
    perror2("server(%d) - read(sock)", port);
    break;
    }
    }
    DBG_MSG3("server(%d) - read %d bytes from sock", port, sock_count);
    }
    }

    #if defined(__UNIX__)
    /* Write to serial port possible? */
    if (FD_ISSET(sio_fd, &wfds))
    #elif defined(__WIN32__)

    /* No socket IO performed? */
    if ((!FD_ISSET(sock_fd, &rfds)) && (!FD_ISSET(sock_fd, &wfds)))
    {
    /* Break on a time out */
    if (GetTickCount() - msecs > timeout)
    {
    fprintf(stderr, "server(%d) - timed out\n", port);
    break;
    }
    }
    else
    {
    msecs = GetTickCount();
    }

    if (1)
    #endif
    {
    if (sock_count > 0)
    {
    if ((res = sio_write(&pipe->sio, sock_buf, sock_count)) < 0)
    {
    perror2("server(%d) - write(sio)", port);
    break;
    }
    DBG_MSG3("server(%d) - wrote %d bytes to sio", port, res);
    sock_count -= res;
    }
    }

    }

    /* Unlock our mutex */
    thr_mutex_unlock(pipe->mutex);
    }

    fprintf(stderr, "server(%d) exiting\n", port);

    /* Clean up - don't call pipe_cleanup() as that would nuke our mutex */
    sio_cleanup(&pipe->sio);
    tcp_cleanup(&pipe->sock);


    free(pipe);

    thr_exit((thr_exitcode_t)0);

    return (thr_exitcode_t)0;
    }

    void debug(void)
    {
    vlist_i *it;
    pipe_s *pit;
    int i = 1;

    fprintf(stderr, "pipes:\n\n");
    vlist_debug(&pipes, stderr);

    for (it = pipes.head; it; it = it->next)
    {
    pit = (pipe_s *)it->data;

    fprintf(stderr, "sio[%d]:\n\n", i);
    sio_debug(&pit->sio, stderr);

    fprintf(stderr, "sock[%d]:\n\n", i);
    tcp_debug(&pit->sock, stderr);

    i++;
    }
    }


    --
    mcu development team
    http://arm.web7days.com
     
    OZ, Feb 8, 2004
    #1
    1. Advertising

  2. OZ

    Aggro Guest

    OZ wrote:

    > the serproxy claim itself a multi-thread proxy thing.


    This group is for standard C++ language only. The standard C++ does not
    contain things that are in your program and therefore your question is
    off topic here.

    Please don't multipost.

    Please read groups faq before posting.
     
    Aggro, Feb 8, 2004
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bhavin Patel

    How to write multiuser application?

    Bhavin Patel, Jun 3, 2004, in forum: Perl
    Replies:
    1
    Views:
    752
    Jim Gibson
    Jun 3, 2004
  2. Tangent

    Multiuser issue

    Tangent, Nov 11, 2003, in forum: ASP .Net
    Replies:
    3
    Views:
    395
    Tangent
    Nov 11, 2003
  3. Manuel Arroba
    Replies:
    5
    Views:
    438
    John Saunders
    Jun 8, 2004
  4. Michael A. Covington

    Setting up Eclipse in a multiuser environment

    Michael A. Covington, Feb 5, 2004, in forum: Java
    Replies:
    1
    Views:
    1,405
    Neil Campbell
    Feb 5, 2004
  5. OZ
    Replies:
    5
    Views:
    464
Loading...

Share This Page