Platon Technologies
neprihlásený Prihlásiť Registrácia
SlovakEnglish
open source software development oslavujeme 10 rokov vývoja otvoreného softvéru! Piatok, 29. marec 2024

Súbor: [Platon] / libplaton / utils / server-backend / server-backend-fast.c (stiahnutie)

Revízia 1.1, Wed Oct 16 21:04:54 2002 UTC (21 years, 5 months ago) by nepto

Interactive communication implemented. Use -i switch.
Code split into several parts and redunand added into utils.c file.
server-backend2.[ch] removed, server-backed-fast.c added, they both use
  the same header server-backend.h file.
README added with description and compilation notes.

/*
 * server_backend.c - network server socketing backend
 *
 * (c) 2001 Ondrej Jombik <nepto@pobox.sk>
 *
 * History
 * - 19/9/2001 - initial release
 * - 20/9/2001 - minor bugfixes
 *             - waitpid() used as substitute of wait()
 * - 24/9/2001 - fork() after accept() change (parent <-> child)
 *             - fnctl() removed
 *
 * TODO
 * - write debug infomations to STDERR
 * - ability to enter fake command on command line
 */

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

/* wait() */
#include <sys/wait.h>

/* struct timeval */
#include <sys/time.h>

/* signal() */
#include <signal.h>

#include "utils.h"
#include "server-backend.h"

int main(int argc, char *argv[])
{
    register int cur_arg;
    int port, f_interactive = 0;
    int listen_sock;
    char **process;

    if (argc < 3) {
        fprintf(stderr, "Usage:\n"
                "  %s <port> <process> <arg1> ... <argN>\n"
                "  %s -i <port>\n",
                PROG_NAME, PROG_NAME);
        return 1;
    }

    cur_arg = 1;
    if (! strcmp(argv[cur_arg], "-i")) {
        f_interactive = 1;
        cur_arg++;
    }

    port = get_port(argv[cur_arg]);
    cur_arg++;

    if (f_interactive && 0) {
        process = NULL;
    } else {
        if ((process = create_process_array(argc, argv, cur_arg)) == NULL) {
            perror(PROG_NAME);
            return 32;
        }
    }

    fake_command_line(argc, argv);

    if ((listen_sock = bind_to_port(port)) == -1) {
        perror(PROG_NAME);
        return 16;
    }

    if (1) {
        (void) setpgrp();
        signal(SIGHUP, SIG_IGN);
    }

    if (0)
        fcntl(listen_sock,F_SETFL,O_NDELAY);

    switch (f_interactive ? 1 : fork()) {
        case -1:
            perror(PROG_NAME);
            return errno;
            break;
        case 0:
            break;
        default:
            fprintf(stderr, "%s: accepting connections on port %d\n",
                    PROG_NAME, port);
            if (f_interactive)
                fprintf(stderr, "%s: interactive mode enabled,"
                        " waiting for first client\n", PROG_NAME);
            else
                return 0;
            break;
    }

    while (1) {
        struct sockaddr_in acc_addr;
        unsigned int size;
        int accept_sock;

        sleep(1);

        size        = sizeof(struct sockaddr_in);
        accept_sock = accept(listen_sock, (struct sockaddr*) &acc_addr, &size);

        if (accept_sock < 0) {
            perror(PROG_NAME);
            return errno;
        }

        if (f_interactive) {
            fprintf(stderr, "%s: new client connected from %s\n",
                    PROG_NAME, (char*)inet_ntoa(acc_addr.sin_addr));
            fprintf(stderr, "%s: you can now communicate via socket no. %d\n",
                    PROG_NAME, accept_sock);
        }

        if (accept_sock > 0) {

            switch (f_interactive ? 1 : fork()) {
                case -1:
                    perror(PROG_NAME);
                    return errno;
                    break;
                case 0: /* child */
                    close(accept_sock);
                    break;
                default: /* parent */
                    if (! f_interactive) {
                        dup2(accept_sock, 0);
                        dup2(accept_sock, 1);
                        dup2(accept_sock, 2);
                        close(listen_sock);
                        close(accept_sock);
                        execvp(process[0], process);
                        write(accept_sock, "execlp() failure\n\r", 18);
                        return 8;
                    }

                    if (do_interactive(accept_sock) < 0) {
                        perror(PROG_NAME);
                        return 8;
                    }
                    return 0;
            }
        }

    } /* while (1) */

    return 0;
}


Platon Group <platon@platon.sk> http://platon.sk/
Copyright © 2002-2006 Platon Group
Stránka používa redakčný systém Metafox
Na začiatok