示例#1
0
void
ph_end(struct pkg_conn *UNUSED(pc), char *UNUSED(buf))
{
    if (debug)  fprintf(stderr, "ph_end\n");
    pkg_close(pcsrv);
    bu_exit(0, NULL);
}
示例#2
0
void
ph_restart(struct pkg_conn *UNUSED(pc), char *buf)
{

    if (debug)fprintf(stderr, "ph_restart %s\n", buf);
    bu_log("Restarting\n");
    pkg_close(pcsrv);
    execlp("rtsrv", "rtsrv", control_host, tcp_port, (char *)0);
    perror("rtsrv");
    bu_exit(1, NULL);
}
void
drop_client(int sub)
{
    int fd;

    if ( clients[sub] == PKC_NULL )
	return;

    fd = clients[sub]->pkc_fd;

    FD_CLR( fd, &select_list );
    pkg_close( clients[sub] );
    clients[sub] = PKC_NULL;
}
示例#4
0
文件: fbserv.c 项目: cciechad/brlcad
/*
 *			D R O P _ C L I E N T
 */
void
drop_client(int sub)
{
    int fd = clients[sub]->pkc_fd;

    if ( clients[sub] == PKC_NULL )  return;

    FD_CLR( fd, &select_list );
    pkg_close( clients[sub] );
    clients[sub] = PKC_NULL;
#if 0
    (void)close( fd );			/* double-safety */
#endif
}
void
new_client(struct pkg_conn *pcp)
{
    int	i;

    if ( pcp == PKC_ERROR )
	return;

    for ( i = MAX_CLIENTS-1; i >= 0; i-- )  {
	if ( clients[i] != NULL )  continue;
	/* Found an available slot */
	clients[i] = pcp;
	FD_SET(pcp->pkc_fd, &select_list);
	V_MAX(max_fd, pcp->pkc_fd);
	setup_socket( pcp->pkc_fd );
	return;
    }
    fprintf(stderr, "fbserv: too many clients\n");
    pkg_close(pcp);
}
示例#6
0
int
main(int argc, char **argv)
{
    int	n;

    if (argc < 2)  {
	fprintf(stderr, "%s", srv_usage);
	return 1;
    }
    while (argv[1][0] == '-')  {
	if (BU_STR_EQUAL(argv[1], "-d"))  {
	    debug++;
	} else if (BU_STR_EQUAL(argv[1], "-x"))  {
	    sscanf(argv[2], "%x", (unsigned int *)&RTG.debug);
	    argc--; argv++;
	} else if (BU_STR_EQUAL(argv[1], "-X"))  {
	    sscanf(argv[2], "%x", (unsigned int *)&rdebug);
	    argc--; argv++;
	} else {
	    fprintf(stderr, "%s", srv_usage);
	    return 3;
	}
	argc--; argv++;
    }
    if (argc != 3 && argc != 4)  {
	fprintf(stderr, "%s", srv_usage);
	return 2;
    }

    control_host = argv[1];
    tcp_port = argv[2];

    /* Note that the LIBPKG error logger can not be
     * "bu_log", as that can cause bu_log to be entered recursively.
     * Given the special version of bu_log in use here,
     * that will result in a deadlock in bu_semaphore_acquire(res_syscall)!
     *  libpkg will default to stderr via pkg_errlog(), which is fine.
     */
    pcsrv = pkg_open(control_host, tcp_port, "tcp", "", "",
		      pkgswitch, NULL);
    if (pcsrv == PKC_ERROR)  {
	fprintf(stderr, "rtsrv: unable to contact %s, port %s\n",
		control_host, tcp_port);
	return 1;
    }

    if (argc == 4)  {
	/* Slip one command to dispatcher */
	(void)pkg_send(MSG_CMD, argv[3], strlen(argv[3])+1, pcsrv);

	/* Prevent chasing the package with an immediate TCP close */
	sleep(1);

	pkg_close(pcsrv);
	return 0;
    }

#ifdef SO_SNDBUF
    /* increase the default send buffer size to 32k since we're
     * sending pixels more than likely.
     */
    {
	int val = 32767;
	n = setsockopt(pcsrv->pkc_fd, SOL_SOCKET, SO_SNDBUF, (const void *)&val, sizeof(val));
	if (n < 0)  perror("setsockopt: SO_SNDBUF");
    }
#endif

    if (!debug)  {
	/* A fresh process */
	if (fork())
	    return 0;

	/* Go into our own process group */
	n = bu_process_id();

#ifdef HAVE_SETPGID
	if (setpgid(n, n) < 0)
	    perror("setpgid");
#else
	/* SysV uses setpgrp with no args and it can't fail,
	 * obsoleted by setpgid.
	 */
	setpgrp();
#endif

	/*
	 *  Unless controller process has specifically said
	 *  that this is an interactive session, e.g., for a demo,
	 *  drop to the lowest sensible priority.
	 */
	if (!interactive)  {
	    bu_nice_set(19);		/* lowest priority */
	}

	/* Close off the world */
	fclose(stdin);
	fclose(stdout);
	fclose(stderr);

	(void)close(0);
	(void)close(1);
	(void)close(2);

	/* For stdio & perror safety, reopen 0, 1, 2 */
	(void)open("/dev/null", 0);	/* to fd 0 */
	n = dup(0);			/* to fd 1 */
	if (n == -1)
	    perror("dup");
	n = dup(0);			/* to fd 2 */
	if (n == -1)
	    perror("dup");

#if defined(HAVE_SYS_IOCTL_H) && defined(TIOCNOTTY)
	n = open("/dev/tty", 2);
	if (n >= 0) {
	    (void)ioctl(n, TIOCNOTTY, 0);
	    (void)close(n);
	}
#endif
    }

    /* Send our version string */
    if (pkg_send(MSG_VERSION,
		   PROTOCOL_VERSION, strlen(PROTOCOL_VERSION)+1, pcsrv) < 0)  {
	fprintf(stderr, "pkg_send MSG_VERSION error\n");
	return 1;
    }
    if (debug)  fprintf(stderr, "PROTOCOL_VERSION='%s'\n", PROTOCOL_VERSION);

    /*
     *  Now that the fork() has been done, it is safe to initialize
     *  the parallel processing support.
     */

    avail_cpus = bu_avail_cpus();

    /* Need to set rtg_parallel non_zero here for RES_INIT to work */
    npsw = avail_cpus;
    if (npsw > 1)  {
	RTG.rtg_parallel = 1;
    } else
	RTG.rtg_parallel = 0;
    bu_semaphore_init(RT_SEM_LAST);

    bu_log("using %d of %d cpus\n",
	   npsw, avail_cpus);

    /*
     *  Initialize the non-parallel memory resource.
     *  The parallel guys are initialized after the rt_dirbuild().
     */
    rt_init_resource(&rt_uniresource, MAX_PSW, NULL);
    bn_rand_init(rt_uniresource.re_randptr, MAX_PSW);

    BU_LIST_INIT(&WorkHead);

    for (;;)  {
	struct pkg_queue	*lp;
	fd_set ifds;
	struct timeval tv;

	/* First, process any packages in library buffers */
	if (pkg_process(pcsrv) < 0)  {
	    bu_log("pkg_get error\n");
	    break;
	}

	/* Second, see if any input to read */
	FD_ZERO(&ifds);
	FD_SET(pcsrv->pkc_fd, &ifds);
	tv.tv_sec = BU_LIST_NON_EMPTY(&WorkHead) ? 0L : 9999L;
	tv.tv_usec = 0L;

	if (select(pcsrv->pkc_fd+1, &ifds, (fd_set *)0, (fd_set *)0,
		    &tv) != 0)  {
	    n = pkg_suckin(pcsrv);
	    if (n < 0)  {
		bu_log("pkg_suckin error\n");
		break;
	    } else if (n == 0)  {
		/* EOF detected */
		break;
	    } else {
		/* All is well */
	    }
	}

	/* Third, process any new packages in library buffers */
	if (pkg_process(pcsrv) < 0)  {
	    bu_log("pkg_get error\n");
	    break;
	}

	/* Finally, more work may have just arrived, check our list */
	if (BU_LIST_NON_EMPTY(&WorkHead))  {
	    lp = BU_LIST_FIRST(pkg_queue, &WorkHead);
	    BU_LIST_DEQUEUE(&lp->l);
	    switch (lp->type)  {
		case MSG_MATRIX:
		    ph_matrix((struct pkg_conn *)0, lp->buf);
		    break;
		case MSG_LINES:
		    ph_lines((struct pkg_conn *)0, lp->buf);
		    break;
		case MSG_OPTIONS:
		    ph_options((struct pkg_conn *)0, lp->buf);
		    break;
		case MSG_GETTREES:
		    ph_gettrees((struct pkg_conn *)0, lp->buf);
		    break;
		default:
		    bu_log("bad list element, type=%d\n", lp->type);
		    return 33;
	    }
	    BU_PUT(lp, struct pkg_queue);
	}
    }

    return 0;		/* bu_exit(0, NULL) */
}
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;
}
示例#8
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);
}