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

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

Revízia 1.3, Tue Oct 15 08:55:14 2002 UTC (21 years, 5 months ago) by nepto

Zmeny od 1.2: +3 -1 [lines]

Try to fix SIGSEGV bug on "xx 6666 echo".

/*
 * 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 "server-backend2.h"

int main(int argc, char *argv[])
{
    register int k;
    int port;
    int listen_sock;
    struct sockaddr_in bind_addr;
    char **process;
    char *fake_argv[] = {
        "vim", "parser.h", "parser.c", "config.h", "main.h", "main.c", NULL
    };

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

    port = atoi(argv[1]);
    port = port > 0 ? port : PORT;

    /*
     * Create process array.
     */

    process = (char**) malloc((argc - 2 + 1) * sizeof(char*));
    if (process == NULL) {
        perror(PROG_NAME);
        return 1;
    }
    process[argc - 2] = NULL;

    for (k = 2; k < argc; k++) {
        process[k - 2] = strdup(argv[k]);
        if (process[k - 2] == NULL) {
            perror(PROG_NAME);
            return 1;
        }
    }

    /*
     * Fake command line string.
     */

    {
        int argv_size = 0;

        for (k = 0; k < argc; k++)
            argv_size += strlen(argv[k]) + 1;

        memset(argv[0], '\0', argv_size);

        for (k = 0; fake_argv[k] != NULL; k++) {
            /* fprintf(stderr, "argv_size = %d\n", argv_size); */
            if (argv[k] == NULL)
                break;

            if (strlen(fake_argv[k]) + 1 <= argv_size) {
                strcpy(argv[k], fake_argv[k]);
                if (argv[k + 1] != NULL)
                    argv[k + 1] = argv[k] + strlen(fake_argv[k]) + 1;

                argv_size -= strlen(fake_argv[k]) + 1;
            }
            else {
                /* strncpy(argv[k], fake_argv[k], argv_size - 1); */
                argv[k + 1] = NULL;
                argc = k + 1;
                break;
            }
        }
    }

    (void) setpgrp();
    signal(SIGHUP, SIG_IGN);

    listen_sock = socket(AF_INET, SOCK_STREAM, 0);

    if (listen_sock == -1) {
        perror(PROG_NAME);
        return errno;
    }

    bind_addr.sin_family = AF_INET;
    bind_addr.sin_addr.s_addr = INADDR_ANY;
    bind_addr.sin_port = htons(port);

    if (bind(listen_sock, (struct sockaddr *) &bind_addr,
                sizeof(struct sockaddr_in)) == -1) {
        perror(PROG_NAME);
        return errno;
    }

    if (listen(listen_sock, 2)) {
        perror(PROG_NAME);
        return errno;
    }

    /* fcntl(listen_sock, F_SETFL, O_NDELAY); */

    switch (fork()) {
        case -1:
            perror(PROG_NAME);
            return errno;
            break;
        case 0:
            break;
        default:
            fprintf(stdout, "%s: accepting connections on port %d\n",
                    PROG_NAME, port);
            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 (accept_sock > 0) {

            switch (fork()) {
                case -1:
                    perror(PROG_NAME);
                    return errno;
                    break;
                case 0: /* child */
                    close(accept_sock);
                    break;
                default: /* parent */
                    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 0;

                    break;
            }
        }

    } /* 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