Beispiel #1
0
//  Send one APDU, transmit window owned memory.
//  data_len_ must be less than one TPDU.
size_t zmq::pgm_socket_t::send (unsigned char *data_, size_t data_len_)
{
    size_t nbytes = 0;
   
    const int status = pgm_send (sock, data_, data_len_, &nbytes);

    //  We have to write all data as one packet.
    if (nbytes > 0) {
        zmq_assert (status == PGM_IO_STATUS_NORMAL);
        zmq_assert (nbytes == data_len_);
    }
    else {
        zmq_assert (status == PGM_IO_STATUS_RATE_LIMITED ||
            status == PGM_IO_STATUS_WOULD_BLOCK);

        if (status == PGM_IO_STATUS_RATE_LIMITED)
            errno = ENOMEM;
        else
            errno = EBUSY;
    }

    //  Save return value.
    last_tx_status = status;

    return nbytes;
}
Beispiel #2
0
END_TEST

START_TEST (test_send_fail_001)
{
	guint8 buffer[ TEST_TXW_SQNS * TEST_MAX_TPDU ];
	const gsize apdu_length = 100;
	gsize bytes_written;
	fail_unless (PGM_IO_STATUS_ERROR == pgm_send (NULL, buffer, apdu_length, &bytes_written), "send not error");
}
Beispiel #3
0
END_TEST

/* large apdu */
START_TEST (test_send_pass_002)
{
	pgm_sock_t* sock = generate_sock ();
	fail_if (NULL == sock, "generate_sock failed");
	sock->is_bound = TRUE;
	const gsize apdu_length = 16000;
	guint8 buffer[ apdu_length ];
	gsize bytes_written;
	fail_unless (PGM_IO_STATUS_NORMAL == pgm_send (sock, buffer, apdu_length, &bytes_written), "send not normal");
	fail_unless ((gssize)apdu_length == bytes_written, "send underrun");
}
Beispiel #4
0
//  Send one APDU, transmit window owned memory.
size_t zmq::pgm_socket_t::send (unsigned char *data_, size_t data_len_)
{
    size_t nbytes = 0;
   
    PGMIOStatus status = pgm_send (transport, data_, data_len_, &nbytes);

    if (nbytes != data_len_) {
        zmq_assert (status == PGM_IO_STATUS_RATE_LIMITED);
        zmq_assert (nbytes == 0);
    }
    
    // We have to write all data as one packet.
    if (nbytes > 0)
        zmq_assert ((ssize_t) nbytes == (ssize_t) data_len_);

    return nbytes;
}
Beispiel #5
0
int
main (
	int	argc,
	char   *argv[]
	)
{
	pgm_error_t* pgm_err = NULL;

	setlocale (LC_ALL, "");

	if (!pgm_init (&pgm_err)) {
		fprintf (stderr, "Unable to start PGM engine: %s\n", pgm_err->message);
		pgm_error_free (pgm_err);
		return EXIT_FAILURE;
	}

	pgm_sock_t*	sock = NULL;
	const char*	network = argv[1];
	int udp_encap_port = 7510;
	int xxx = 0;
	char buf[4196];
	memset(buf, 0, 4196);

	sock = create_sock(network, udp_encap_port);
	int p_status = pthread_create (&nak_thread, NULL, &nak_routine, sock);
	if ((sock != NULL) && (p_status == 0))
	{
	    do {
		sprintf(buf, "%d", xxx);
		const int status = pgm_send (sock, buf, 4196, NULL);
		if (PGM_IO_STATUS_NORMAL != status) {
		    fprintf (stderr, "pgm_send() failed.\n");
		}
		xxx ++;
		usleep(10*1000);
	    } while(1);
	}

/* cleanup */
	if (sock) {
		pgm_close (sock, TRUE);
		sock = NULL;
	}
	pgm_shutdown();
	return EXIT_SUCCESS;
}
Beispiel #6
0
int
main (
	int	argc,
	char   *argv[]
	)
{
	pgm_error_t* pgm_err = NULL;

	setlocale (LC_ALL, "");

	puts ("PGM daytime service");

	if (!pgm_init (&pgm_err)) {
		fprintf (stderr, "Unable to start PGM engine: %s\n", pgm_err->message);
		pgm_error_free (pgm_err);
		return EXIT_FAILURE;
	}

/* parse program arguments */
#ifdef _WIN32
	const char* binary_name = strrchr (argv[0], '\\');
#else
	const char* binary_name = strrchr (argv[0], '/');
#endif
	if (NULL == binary_name)	binary_name = argv[0];
	else				binary_name++;

	static struct option long_options[] = {
		{ "network",        required_argument, NULL, 'n' },
		{ "service",        required_argument, NULL, 's' },
		{ "port",           required_argument, NULL, 'p' },
		{ "speed-limit",    required_argument, NULL, 'r' },
		{ "enable-pgmcc",   no_argument,       NULL, 'c' },
		{ "enable-loop",    no_argument,       NULL, 'l' },
		{ "enable-fec",     required_argument, NULL, 'f' },
		{ "list",           no_argument,       NULL, 'i' },
		{ "help",           no_argument,       NULL, 'h' },
		{ NULL, 0, NULL, 0 }
	};

	int c;
	while ((c = getopt_long (argc, argv, "s:n:p:r:cf:N:K:P:lih", long_options, NULL)) != -1)
	{
		switch (c) {
		case 'n':	network = optarg; break;
		case 's':	port = atoi (optarg); break;
		case 'p':	udp_encap_port = atoi (optarg); break;
		case 'r':	max_rte = atoi (optarg); break;
		case 'c':	use_pgmcc = TRUE; break;
		case 'f':
			use_fec = TRUE;
			switch (optarg[0]) {
			case 'p':
			case 'P':
				proactive_packets = 1;
				break;
			case 'b':
			case 'B':
				proactive_packets = 1;
			case 'o':
			case 'O':
				use_ondemand_parity = TRUE;
				break;
			}
			break;
		case 'N':	rs_n = atoi (optarg); break;
		case 'K':	rs_k = atoi (optarg); break;
		case 'P':	proactive_packets = atoi (optarg); break;

		case 'l':	use_multicast_loop = TRUE; break;

		case 'i':
			pgm_if_print_all();
			return EXIT_SUCCESS;

		case 'h':
		case '?':
			usage (binary_name);
		}
	}

	if (use_fec && ( !rs_n || !rs_k )) {
		fprintf (stderr, "Invalid Reed-Solomon parameters RS(%d,%d).\n", rs_n, rs_k);
		usage (binary_name);
	}

/* setup signal handlers */
#ifdef SIGHUP
	signal (SIGHUP,  SIG_IGN);
#endif
#ifndef _WIN32
	int e = pipe (terminate_pipe);
	assert (0 == e);
	const int flags = fcntl (terminate_pipe[0], F_GETFL);
	fcntl (terminate_pipe[0], F_SETFL, flags | O_NONBLOCK);
	signal (SIGINT,  on_signal);
	signal (SIGTERM, on_signal);
#else
	terminateEvent = WSACreateEvent();
	SetConsoleCtrlHandler ((PHANDLER_ROUTINE)on_console_ctrl, TRUE);
	setvbuf (stdout, (char *) NULL, _IONBF, 0);
#endif /* !_WIN32 */

	if (!on_startup()) {
		fprintf (stderr, "Startup failed\n");
		return EXIT_FAILURE;
	}

/* service loop */
	do {
		time_t now;
		time (&now);
		const struct tm* time_ptr = localtime(&now);
#ifndef _WIN32
		char s[1024];
		const size_t slen = strftime (s, sizeof(s), TIME_FORMAT, time_ptr);
		const int status = pgm_send (sock, s, slen + 1, NULL);
#else
		char s[1024];
		const size_t slen = strftime (s, sizeof(s), TIME_FORMAT, time_ptr);
		wchar_t ws[1024];
		size_t wslen = MultiByteToWideChar (CP_ACP, 0, s, slen, ws, 1024);
		char us[1024];
		size_t uslen = WideCharToMultiByte (CP_UTF8, 0, ws, wslen + 1, us, sizeof(us), NULL, NULL);
		const int status = pgm_send (sock, us, uslen + 1, NULL);
#endif
	        if (PGM_IO_STATUS_NORMAL != status) {
			fprintf (stderr, "pgm_send() failed.\n");
		}
#ifndef _WIN32
		sleep (1);
#else
		Sleep (1 * 1000);
#endif
	} while (!is_terminated);

/* cleanup */
	puts ("Waiting for NAK thread.");
#ifndef _WIN32
	pthread_join (nak_thread, NULL);
	close (terminate_pipe[0]);
	close (terminate_pipe[1]);
#else
	WaitForSingleObject (nak_thread, INFINITE);
	CloseHandle (nak_thread);
	WSACloseEvent (terminateEvent);
#endif /* !_WIN32 */

	if (sock) {
		puts ("Closing PGM sock.");
		pgm_close (sock, TRUE);
		sock = NULL;
	}

	puts ("PGM engine shutdown.");
	pgm_shutdown();
	puts ("finished.");
	return EXIT_SUCCESS;
}
Beispiel #7
0
static int send_quote(void *data, void *data2) {
	struct msg *msg = (struct msg *)data;
	Quote *quote;
	int status;
	NOT_USED(data2);

	quote = (Quote *)msg->data;
	if (quote->thyquote.m_nLen == sizeof (THYQuote)) {
		if (get_logger_level() == __LOG_DEBUG) {
			time_t t = (time_t)quote->thyquote.m_nTime;
			char datestr[64];

			strftime(datestr, sizeof datestr, "%F %T", localtime(&t));
			xcb_log(XCB_LOG_DEBUG, "%s.%03d,%s,%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,"
				"%d,%.2f,%d,%d,%.2f,%d,%.2f,%d",
				datestr,
				quote->m_nMSec,
				quote->thyquote.m_cHYDM,
				quote->thyquote.m_cJYS,
				quote->thyquote.m_dZXJ,
				quote->thyquote.m_dJKP,
				quote->thyquote.m_dZGJ,
				quote->thyquote.m_dZDJ,
				quote->thyquote.m_dZSP,
				quote->thyquote.m_dJSP,
				quote->thyquote.m_dZJSJ,
				quote->thyquote.m_dJJSJ,
				quote->thyquote.m_nCJSL,
				quote->thyquote.m_dCJJE,
				quote->thyquote.m_nZCCL,
				quote->thyquote.m_nCCL,
				quote->thyquote.m_dMRJG1,
				quote->thyquote.m_nMRSL1,
				quote->thyquote.m_dMCJG1,
				quote->thyquote.m_nMCSL1);
		}
		/* for testing */
		dlist_rwlock_rdlock(monitors);
		if (dlist_length(monitors) > 0) {
			char res[512];
			dlist_iter_t iter = dlist_iter_new(monitors, DLIST_START_HEAD);
			dlist_node_t node;

			snprintf(res, sizeof res, "TX '%d,%s,%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,"
				"%d,%.2f,%d,%d,%.2f,%d,%.2f,%d'\r\n",
				quote->thyquote.m_nTime,
				quote->thyquote.m_cHYDM,
				quote->thyquote.m_cJYS,
				quote->thyquote.m_dZXJ,
				quote->thyquote.m_dJKP,
				quote->thyquote.m_dZGJ,
				quote->thyquote.m_dZDJ,
				quote->thyquote.m_dZSP,
				quote->thyquote.m_dJSP,
				quote->thyquote.m_dZJSJ,
				quote->thyquote.m_dJJSJ,
				quote->thyquote.m_nCJSL,
				quote->thyquote.m_dCJJE,
				quote->thyquote.m_nZCCL,
				quote->thyquote.m_nCCL,
				quote->thyquote.m_dMRJG1,
				quote->thyquote.m_nMRSL1,
				quote->thyquote.m_dMCJG1,
				quote->thyquote.m_nMCSL1);
			while ((node = dlist_next(iter))) {
				client c = (client)dlist_node_value(node);

				pthread_spin_lock(&c->lock);
				if (c->flags & CLIENT_CLOSE_ASAP) {
					pthread_spin_unlock(&c->lock);
					continue;
				}
				if (net_try_write(c->fd, res, strlen(res), 10, NET_NONBLOCK) == -1) {
					xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s",
						c, strerror(errno));
					if (++c->eagcount >= 10)
						client_free_async(c);
				} else if (c->eagcount)
					c->eagcount = 0;
				pthread_spin_unlock(&c->lock);
			}
			dlist_iter_free(&iter);
		}
		dlist_rwlock_unlock(monitors);
	}
	/* FIXME */
	if ((status = pgm_send(pgm_sender, msg->data, sizeof (Quote), NULL)) != PGM_IO_STATUS_NORMAL)
		xcb_log(XCB_LOG_WARNING, "Sending data failed");
	msg_decr(msg);
	return 0;
}
Beispiel #8
0
static int server_cron(event_loop el, unsigned long id, void *data) {
	dlist_iter_t iter;
	dlist_node_t node;
	NOT_USED(el);
	NOT_USED(id);
	NOT_USED(data);

	if (log_reload) {
		close_logger();
		if (init_logger("/var/log/xcb/xcb-dp2.log", __LOG_DEBUG) == 0) {
			const char *tmp;

			pthread_mutex_lock(&cfg_lock);
			if ((tmp = variable_retrieve(cfg, "general", "log_level"))) {
				if (!strcasecmp(tmp, "debug"))
					set_logger_level(__LOG_DEBUG);
				else if (!strcasecmp(tmp, "info"))
					set_logger_level(__LOG_INFO);
				else if (!strcasecmp(tmp, "notice"))
					set_logger_level(__LOG_NOTICE);
				else if (!strcasecmp(tmp, "warning"))
					set_logger_level(__LOG_WARNING);
			}
			pthread_mutex_unlock(&cfg_lock);
			log_reload = 0;
		}
		/* FIXME */
		if (addms)
			table_clear(times);
	}
	if (shut_down) {
		if (prepare_for_shutdown() == 0)
			exit(0);
		xcb_log(XCB_LOG_WARNING, "SIGTERM received, but errors trying to shutdown the server");
	}
	/* FIXME */
	iter = dlist_iter_new(clients_to_close, DLIST_START_HEAD);
	while ((node = dlist_next(iter))) {
		client c = (client)dlist_node_value(node);

		if (c->refcount == 0)
			client_free(c);
	}
	dlist_iter_free(&iter);
	/* FIXME */
	if (cronloops % 200 == 0) {
		char meme[] = "SU OT GNOLEB ERA ESAB RUOY LLA";
		int status;

		/* heartbeat */
		dlist_lock(clients);
		if (dlist_length(clients) > 0) {
			dstr res = dstr_new("HEARTBEAT|");
			dstr ip = getipv4();

			res = dstr_cat(res, ip);
			res = dstr_cat(res, "\r\n");
			iter = dlist_iter_new(clients, DLIST_START_HEAD);
			while ((node = dlist_next(iter))) {
				client c = (client)dlist_node_value(node);

				pthread_spin_lock(&c->lock);
				if (net_try_write(c->fd, res, dstr_length(res), 100, NET_NONBLOCK) == -1)
					xcb_log(XCB_LOG_WARNING, "Writing to client '%p': %s",
						c, strerror(errno));
				pthread_spin_unlock(&c->lock);
			}
			dlist_iter_free(&iter);
			dstr_free(ip);
			dstr_free(res);
		}
		dlist_unlock(clients);
		/* FIXME: trying to lower the high CPU load while idle */
		if ((status = pgm_send(pgm_sender, meme, sizeof meme, NULL)) != PGM_IO_STATUS_NORMAL)
			xcb_log(XCB_LOG_WARNING, "Communication test failed");
	}
	++cronloops;
	return 100;
}
Beispiel #9
0
int
main (
    int	argc,
    char   *argv[]
)
{
    pgm_error_t* pgm_err = NULL;

    setlocale (LC_ALL, "");

    /* pre-initialise PGM messages module to add hook for GLib logging */
    pgm_messages_init();
    log_init();
    if (!pgm_init (&pgm_err)) {
        g_error ("Unable to start PGM engine: %s", pgm_err->message);
        pgm_error_free (pgm_err);
        pgm_messages_shutdown();
        return EXIT_FAILURE;
    }

    /* parse program arguments */
    const char* binary_name = strrchr (argv[0], '/');
    int c;
    while ((c = getopt (argc, argv, "s:n:p:r:f:K:N:lih")) != -1)
    {
        switch (c) {
        case 'n':
            g_network = optarg;
            break;
        case 's':
            g_port = atoi (optarg);
            break;
        case 'p':
            g_udp_encap_port = atoi (optarg);
            break;
        case 'r':
            g_max_rte = atoi (optarg);
            break;

        case 'f':
            g_fec = TRUE;
            break;
        case 'K':
            g_k = atoi (optarg);
            break;
        case 'N':
            g_n = atoi (optarg);
            break;

        case 'l':
            g_multicast_loop = TRUE;
            break;

        case 'i':
            pgm_if_print_all();
            pgm_messages_shutdown();
            return EXIT_SUCCESS;

        case 'h':
        case '?':
            pgm_messages_shutdown();
            usage (binary_name);
        }
    }

    if (g_fec && ( !g_k || !g_n )) {
        pgm_messages_shutdown();
        g_error ("Invalid Reed-Solomon parameters RS(%d, %d).", g_n, g_k);
        usage (binary_name);
    }

    /* setup signal handlers */
    signal (SIGSEGV, on_sigsegv);
#ifdef SIGHUP
    signal (SIGHUP, SIG_IGN);
#endif

    if (create_pgm_socket())
    {
        while (optind < argc) {
            const int status = pgm_send (g_sock, argv[optind], strlen(argv[optind]) + 1, NULL);
            if (PGM_IO_STATUS_NORMAL != status) {
                g_warning ("pgm_send failed.");
            }
            optind++;
        }
    }

    /* cleanup */
    if (g_sock) {
        pgm_close (g_sock, TRUE);
        g_sock = NULL;
    }
    pgm_shutdown();
    pgm_messages_shutdown();
    return EXIT_SUCCESS;
}
Beispiel #10
0
int
main (
	int	argc,
	char   *argv[]
	)
{
	pgm_error_t* pgm_err = NULL;

	setlocale (LC_ALL, "");

	if (!pgm_init (&pgm_err)) {
		fprintf (stderr, "Unable to start PGM engine: %s\n", pgm_err->message);
		pgm_error_free (pgm_err);
		return EXIT_FAILURE;
	}

/* parse program arguments */
	const char* binary_name = strrchr (argv[0], '/');
	int c;
	while ((c = getopt (argc, argv, "s:n:p:r:f:K:N:lih")) != -1)
	{
		switch (c) {
		case 'n':	network = optarg; break;
		case 's':	port = atoi (optarg); break;
		case 'p':	udp_encap_port = atoi (optarg); break;
		case 'r':	max_rte = atoi (optarg); break;
		case 'f':	use_fec = TRUE; break;
		case 'K':	rs_k = atoi (optarg); break;
		case 'N':	rs_n = atoi (optarg); break;

		case 'l':	use_multicast_loop = TRUE; break;

		case 'i':
			pgm_if_print_all();
			return EXIT_SUCCESS;

		case 'h':
		case '?':
			usage (binary_name);
		}
	}

	if (use_fec && ( !rs_n || !rs_k )) {
		fprintf (stderr, "Invalid Reed-Solomon parameters RS(%d,%d).\n", rs_n, rs_k);
		usage (binary_name);
	}

	if (create_sock())
	{
		while (optind < argc) {
			const int status = pgm_send (sock, argv[optind], strlen (argv[optind]) + 1, NULL);
		        if (PGM_IO_STATUS_NORMAL != status) {
				fprintf (stderr, "pgm_send() failed.\n");
		        }
			optind++;
		}
	}

/* cleanup */
	if (sock) {
		pgm_close (sock, TRUE);
		sock = NULL;
	}
	pgm_shutdown();
	return EXIT_SUCCESS;
}
Beispiel #11
0
int main( int argc, char *argv[]) {
    int c = 0;
    int ret_val = 0;
    int port = 0;
    char network[128];
    char *file = NULL;
    char *iface = NULL;
    char *mcast_addr = NULL;
    int bfd = 0;
    network[0] = '\0';

#ifdef UDPTEST
    int sockfd = 0;
#else
    pgm_error_t* pgm_err = NULL;
    pgm_sock_t *pgm_sock;
    pthread_t nak_thread;
#endif

    while((c = getopt(argc, argv, ":hm:i:p:f:")) != -1) {
        switch (c) {
        case 'm':
            mcast_addr = optarg;
            break;
        case 'i':
            iface = optarg;
            break;
        case 'p':
            port = atoi(optarg);
            break;
        case 'h':
        case '?':
            print_usage();
            break;
        default:
            print_usage();
            break;
        }
    }

    if(optind != argc-1) {
        PRINT_ERR("Please provide the path to a file you want to send!");
        ret_val = -1;
        goto ret_error;
    } else {
        file = argv[optind];
    }

    if (iface) {
        char *ifaddr = pftp_inet_iftoa(iface);
        if (strlen(ifaddr) > 0) {
            strncat(network, ifaddr, 128);
            strncat(network, ";", 128);
        }
    }

    if (mcast_addr) {
        strncat(network, mcast_addr, 128);
    } else {
        strncat(network, PFTP_DEFAULT_MCAST_ADDR, 128);
    }

#ifdef UDPTEST
    struct sockaddr_in servaddr;

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = inet_addr(PFTP_DEFAULT_MCAST_ADDR);
    servaddr.sin_port = port ? htons(port) : htons(PFTP_UDP_PORT);
#else

    if (0 != pftp_create(1, network, port, &pgm_sock)) {
        ret_val = -1;
        goto ret_error;
    }

    int pgm_status;

    /* Start NAK receiver thread */
    m_run_receiver = 1;
    pthread_create(&nak_thread, NULL, nak_routine, (void*)pgm_sock);
#endif

    char buf[PGMBUF_SIZE];
    buf[0] = '\0';

    struct stat fstat;
    if (-1 == stat(file, &fstat)) {
        PRINT_ERR("Couldn't stat file: %s", strerror(errno));
        ret_val = -1;
        goto ret_error;
    }

    char *fname = strrchr(file, '/');
    if (!fname) {
        fname = file;
    } else {
        fname = fname+1;
    }

    memset(buf, 0, PGMBUF_SIZE);
    snprintf(buf, PGMBUF_SIZE, CMD_SEND_FILE" %ld %s", fstat.st_size, fname);
    PRINT_DBG("Sending file with command: %s", buf);

    size_t bytes_written;
    int bytes_read;

#ifdef UDPTEST
    bytes_written = sendto(sockfd, buf, strlen(buf)+1, 0, (struct sockaddr*)&servaddr, sizeof(servaddr));
    if (bytes_written != strlen(buf)+1) {
        PRINT_ERR("Couldn't send file transfer command! %s", strerror(errno));
        ret_val = -1;
        goto ret_error;
    }
#else
    pgm_status = pgm_status = pgm_send(pgm_sock, buf, strlen(buf)+1, &bytes_written);
    if (pgm_status != PGM_IO_STATUS_NORMAL) {
        PRINT_ERR("Couldn't send file transfer command!");
        ret_val = -1;
        goto ret_error;
    }
#endif

    bfd = open(file, O_RDONLY);
    if (bfd < 0) {
        PRINT_ERR("Couldn't open file for reading! %s", strerror(errno));
        ret_val = -1;
        goto ret_error;
    }

    int fds = 0;
    fd_set writefds;
    fd_set readfds;

    bytes_read = read(bfd, buf, PGMBUF_SIZE);
    while (bytes_read > 0) {

#ifdef UDPTEST

        bytes_written = sendto(sockfd, buf, bytes_read, 0, (struct sockaddr*)&servaddr, sizeof(servaddr));

#else
        struct timeval tv;
        pgm_status = pgm_send(pgm_sock, buf, bytes_read, &bytes_written);

        //PRINT_DBG("pgm_status: %d", pgm_status);

        switch (pgm_status) {

        case PGM_IO_STATUS_NORMAL :
        {
#endif
            if (bytes_written != bytes_read) {
                PRINT_ERR("Error sending file!");
                ret_val = -1;
                goto ret_error;
            }
            bytes_read = read(bfd, buf, PGMBUF_SIZE);

#ifdef UDPTEST
            struct timespec ts = {0, 35000};
            nanosleep(&ts, NULL);
#else
        } break;
        case PGM_IO_STATUS_TIMER_PENDING:
        {
            socklen_t optlen = sizeof(tv);
            pgm_getsockopt (pgm_sock, IPPROTO_PGM, PGM_TIME_REMAIN, &tv, &optlen);
            if (0 == (tv.tv_sec * 1000) + ((tv.tv_usec + 500) / 1000))
                break;
            goto block;
        }
        case PGM_IO_STATUS_RATE_LIMITED :
        {
            socklen_t optlen = sizeof(tv);
            pgm_getsockopt (pgm_sock, IPPROTO_PGM, PGM_RATE_REMAIN, &tv, &optlen);
            if (0 == (tv.tv_sec * 1000) + ((tv.tv_usec + 500) / 1000))
                break;
            /* No accidental fallthrough! */
        }
        case PGM_IO_STATUS_CONGESTION :
        case PGM_IO_STATUS_WOULD_BLOCK :
block:
        {
            FD_ZERO(&writefds);
            pgm_select_info(pgm_sock, NULL, &writefds, &fds);
            fds = select(fds, NULL, &writefds, NULL, pgm_status == PGM_IO_STATUS_WOULD_BLOCK ? NULL : &tv);
        } break;
        default:
            PRINT_ERR("Send error!");
            ret_val = -1;
            goto ret_error;
            break;
        }
#endif
    }

#ifndef UDPTEST
    pthread_mutex_lock(&m_pftp_mutex);
    m_run_receiver = 0;
    pthread_mutex_unlock(&m_pftp_mutex);
    pthread_join(nak_thread, NULL);
    pthread_mutex_destroy(&m_pftp_mutex);
#endif

    goto ret_good;

ret_error:
    PRINT_DBG("Exit error");
    goto ret;
ret_good:
    PRINT_DBG("Exit good");
ret:
    if (bfd > 0)
        close(bfd);
#ifdef UDPTEST
    if (sockfd > 0)
        close(sockfd);
#else
    if (pgm_sock) {
        pftp_stop(pgm_sock);
    }
#endif
    return ret_val;
}
Beispiel #12
0
int
main (
	int	argc,
	char   *argv[]
	)
{
	pgm_error_t* pgm_err = NULL;

	setlocale (LC_ALL, "");

	if (!pgm_init (&pgm_err)) {
		fprintf (stderr, "Unable to start PGM engine: %s\n", pgm_err->message);
		pgm_error_free (pgm_err);
		return EXIT_FAILURE;
	}

/* parse program arguments */
#ifdef _WIN32
	const char* binary_name = strrchr (argv[0], '\\');
#else
	const char* binary_name = strrchr (argv[0], '/');
#endif
	if (NULL == binary_name)	binary_name = argv[0];
	else				binary_name++;

	static struct option long_options[] = {
		{ "network",        required_argument, NULL, 'n' },
		{ "service",        required_argument, NULL, 's' },
		{ "port",           required_argument, NULL, 'p' },
		{ "speed-limit",    required_argument, NULL, 'r' },
		{ "enable-loop",    no_argument,       NULL, 'l' },
		{ "enable-fec",     required_argument, NULL, 'f' },
		{ "list",           no_argument,       NULL, 'i' },
		{ "help",           no_argument,       NULL, 'h' },
		{ NULL, 0, NULL, 0 }
	};

	int c;
	while ((c = getopt_long (argc, argv, "s:n:p:r:f:K:N:lih", long_options, NULL)) != -1)
	{
		switch (c) {
		case 'n':	network = optarg; break;
		case 's':	port = atoi (optarg); break;
		case 'p':	udp_encap_port = atoi (optarg); break;
		case 'r':	max_rte = atoi (optarg); break;
		case 'f':	use_fec = TRUE; break;
		case 'K':	rs_k = atoi (optarg); break;
		case 'N':	rs_n = atoi (optarg); break;

		case 'l':	use_multicast_loop = TRUE; break;

		case 'i':
			pgm_if_print_all();
			return EXIT_SUCCESS;

		case 'h':
		case '?':
			usage (binary_name);
		}
	}

	if (use_fec && ( !rs_n || !rs_k )) {
		fprintf (stderr, "Invalid Reed-Solomon parameters RS(%d,%d).\n", rs_n, rs_k);
		usage (binary_name);
	}

	if (create_sock())
	{
		while (optind < argc) {
			const int status = pgm_send (sock, argv[optind], strlen (argv[optind]) + 1, NULL);
		        if (PGM_IO_STATUS_NORMAL != status) {
				fprintf (stderr, "pgm_send() failed.\n");
		        }
			optind++;
		}
	}

/* cleanup */
	if (sock) {
		pgm_close (sock, TRUE);
		sock = NULL;
	}
	pgm_shutdown();
	return EXIT_SUCCESS;
}