コード例 #1
0
/*
 *  Loop forever handling clients as they come and go.
 *  Access to the framebuffer may be interleaved, if the user
 *  wants it that way.
 */
static void
main_loop(void)
{
    int	nopens = 0;
    int	ncloses = 0;

    while ( !fb_server_got_fb_free ) {
	long refresh_rate = 60000000; /* old default */
	fd_set infds;
	struct timeval tv;
	int	i;

	if (fb_server_fbp) {
	    if (fb_poll_rate(fb_server_fbp) > 0)
		refresh_rate = fb_poll_rate(fb_server_fbp);
	}

	infds = select_list;	/* struct copy */

	tv.tv_sec = 0L;
	tv.tv_usec = refresh_rate;
	if ((select( max_fd+1, &infds, (fd_set *)0, (fd_set *)0, (struct timeval *)&tv ) == 0)) {
	    /* Process fb events while waiting for client */
	    /*printf("select timeout waiting for client\n");*/
	    if (fb_server_fbp) {
		if (fb_poll(fb_server_fbp)) {
		    return;
		}
	    }
	    continue;
	}
	/* Handle any events from the framebuffer */
	if (fb_is_set_fd(fb_server_fbp, &infds)) {
	    fb_poll(fb_server_fbp);
	}

	/* Accept any new client connections */
	if (netfd > 0 && FD_ISSET(netfd, &infds)) {
	    new_client( pkg_getclient( netfd, fb_server_pkg_switch, comm_error, 0 ) );
	    nopens++;
	}

	/* Process arrivals from existing clients */
	/* First, pull the data out of the kernel buffers */
	for (i = MAX_CLIENTS-1; i >= 0; i--) {
	    if (clients[i] == NULL )  continue;
	    if (pkg_process( clients[i] ) < 0) {
		fprintf(stderr, "pkg_process error encountered (1)\n");
	    }
	    if (! FD_ISSET( clients[i]->pkc_fd, &infds )) continue;
	    if (pkg_suckin( clients[i] ) <= 0) {
		/* Probably EOF */
		drop_client( i );
		ncloses++;
		continue;
	    }
	}
	/* Second, process all the finished ones that we just got */
	for (i = MAX_CLIENTS-1; i >= 0; i--) {
	    if (clients[i] == NULL )  continue;
	    if (pkg_process( clients[i] ) < 0) {
		fprintf(stderr, "pkg_process error encountered (2)\n");
	    }
	}
	if (once_only && nopens > 1 && ncloses > 1)
	    return;
    }
}
コード例 #2
0
int
main(int argc, char **argv)
{
#define PORTSZ 32
    char	portname[PORTSZ];

    max_fd = 0;

    /* No disk files on remote machine */
    _fb_disk_enable = 0;
    memset((void *)clients, 0, sizeof(struct pkg_conn *) * MAX_CLIENTS);

#ifdef SIGALRM
    (void)signal( SIGPIPE, SIG_IGN );
    (void)signal( SIGALRM, sigalarm );
#endif
    /*alarm(1)*/

    FD_ZERO(&select_list);
    fb_server_select_list = &select_list;
    fb_server_max_fd = &max_fd;

#ifndef _WIN32
    /*
     * Inetd Daemon.
     * Check to see if we were invoked by /etc/inetd.  If so
     * we will have an open network socket on fd=0.  Become
     * a Transient PKG server if this is so.
     */
    netfd = 0;
    if ( is_socket(netfd) ) {
	init_syslog();
	new_client( pkg_transerver( fb_server_pkg_switch, comm_error ) );
	max_fd = 8;
	once_only = 1;
	main_loop();
	return 0;
    }
#endif

    /* for now, make them set a port_num, for usage message */
    if ( !get_args( argc, argv ) || !port_set ) {
	(void)fputs(usage, stderr);
	return 1;
    }

    /* Single-Frame-Buffer Server */
    if ( framebuffer != NULL ) {
	fb_server_retain_on_close = 1;	/* don't ever close the frame buffer */

	/* open a frame buffer */
	if ( (fb_server_fbp = fb_open(framebuffer, width, height)) == FB_NULL )
	    bu_exit(1, NULL);
	max_fd = fb_set_fd(fb_server_fbp, &select_list);

	/* check/default port */
	if ( port_set ) {
	    if ( port < 1024 )
		port += 5559;
	}
	snprintf(portname, PORTSZ, "%d", port);

	/*
	 * Hang an unending listen for PKG connections
	 */
	if ( (netfd = pkg_permserver(portname, 0, 0, comm_error)) < 0 )
	    bu_exit(-1, NULL);
	FD_SET(netfd, &select_list);
	V_MAX(max_fd, netfd);

	main_loop();
	return 0;
    }

#ifndef _WIN32
    /*
     * Stand-Alone Daemon
     */
    /* check/default port */
    if ( port_set ) {
	if ( port < 1024 )
	    port += 5559;
	sprintf(portname, "%d", port);
    } else {
	snprintf(portname, PORTSZ, "%s", "remotefb");
    }

    init_syslog();
    while ( (netfd = pkg_permserver(portname, 0, 0, comm_error)) < 0 ) {
	static int error_count=0;
	sleep(1);
	if (error_count++ < 60) {
	    continue;
	}
	comm_error("Unable to start the stand-alone framebuffer daemon after 60 seconds, giving up.");
	return 1;
    }

    while (1) {
	int fbstat;
	struct pkg_conn	*pcp;

	pcp = pkg_getclient( netfd, fb_server_pkg_switch, comm_error, 0 );
	if ( pcp == PKC_ERROR )
	    break;		/* continue is unlikely to work */

	if ( fork() == 0 )  {
	    /* 1st level child process */
	    (void)close(netfd);	/* Child is not listener */

	    /* Create 2nd level child process, "double detach" */
	    if ( fork() == 0 )  {
		/* 2nd level child -- start work! */
		new_client( pcp );
		once_only = 1;
		main_loop();
		return 0;
	    } else {
		/* 1st level child -- vanish */
		return 1;
	    }
	} else {
	    /* Parent: lingering server daemon */
	    pkg_close(pcp);	/* Daemon is not the server */
	    /* Collect status from 1st level child */
	    (void)wait( &fbstat );
	}
    }
#endif  /* _WIN32 */

    return 2;
}
コード例 #3
0
ファイル: server.c プロジェクト: cogitokat/brlcad
/**
 * start up a server that listens for a single client.
 */
void
run_server(int port) {
    struct pkg_conn *client;
    int netfd;
    char portname[MAX_DIGITS + 1] = {0};
    /* int pkg_result  = 0; */
    char *buffer, *msgbuffer;
    long bytes = 0;
    FILE *fp;

    /** our server callbacks for each message type */
    struct pkg_switch callbacks[] = {
	{MSG_HELO, server_helo, "HELO", NULL},
	{MSG_DATA, server_data, "DATA", NULL},
	{MSG_CIAO, server_ciao, "CIAO", NULL},
	{0, 0, (char *)0, (void*)0}
    };

    validate_port(port);

    /* start up the server on the given port */
    snprintf(portname, MAX_DIGITS, "%d", port);
    netfd = pkg_permserver(portname, "tcp", 0, 0);
    if (netfd < 0) {
	bu_bomb("Unable to start the server");
    }

    /* listen for a good client indefinitely.  this is a simple
     * handshake that waits for a HELO message from the client.  if it
     * doesn't get one, the server continues to wait.
     */
    do {
	client = pkg_getclient(netfd, callbacks, NULL, 0);
	if (client == PKC_NULL) {
	    bu_log("Connection seems to be busy, waiting...\n");
	    sleep(10);
	    continue;
	} else if (client == PKC_ERROR) {
	    bu_log("Fatal error accepting client connection.\n");
	    pkg_close(client);
	    client = PKC_NULL;
	    continue;
	}

	/* got a connection, process it */
	msgbuffer = pkg_bwaitfor (MSG_HELO, client);
	if (msgbuffer == NULL) {
	    bu_log("Failed to process the client connection, still waiting\n");
	    pkg_close(client);
	    client = PKC_NULL;
	} else {
	    bu_log("msgbuffer: %s\n", msgbuffer);
	    /* validate magic header that client should have sent */
	    if (!BU_STR_EQUAL(msgbuffer, MAGIC_ID)) {
		bu_log("Bizarre corruption, received a HELO without at matching MAGIC ID!\n");
		pkg_close(client);
		client = PKC_NULL;
	    }
	}
    } while (client == PKC_NULL);

    /* have client, will send file */
    fp = fopen("lempar.c", "rb");
    buffer = (char *)bu_calloc(2048, 1, "buffer allocation");

    if (fp == NULL) {
	bu_log("Unable to open lempar.c\n");
	bu_bomb("Unable to read file\n");
    }

    /* send the file data to the server */
    while (!feof(fp) && !ferror(fp)) {
	bytes = fread(buffer, 1, 2048, fp);
	bu_log("Read %ld bytes from lempar.c\n", bytes);

	if (bytes > 0) {
	    bytes = pkg_send(MSG_DATA, buffer, (size_t)bytes, client);
	    if (bytes < 0) {
		pkg_close(client);
		bu_log("Unable to successfully send data");
		bu_free(buffer, "buffer release");
		return;
	    }
	}
    }

    /* Tell the client we're done */
    bytes = pkg_send(MSG_CIAO, "DONE", 5, client);
    if (bytes < 0) {
	bu_log("Connection to client seems faulty.\n");
    }

    /* Confirm the client is done */
    buffer = pkg_bwaitfor (MSG_CIAO , client);
    bu_log("buffer: %s\n", buffer);

    /* shut down the server, one-time use */
    pkg_close(client);
}