~ubuntu-branches/debian/experimental/linux-tools/experimental

« back to all changes in this revision

Viewing changes to drivers/staging/usbip/userspace/src/usbipd.c

  • Committer: Package Import Robot
  • Author(s): Ben Hutchings
  • Date: 2014-02-02 16:57:49 UTC
  • mfrom: (1.1.10) (0.1.21 sid)
  • Revision ID: package-import@ubuntu.com-20140202165749-tw94o9t1t0a8txk6
Tags: 3.13-1~exp2
Merge changes from sid up to 3.12.6-3

Show diffs side-by-side

added added

removed removed

Lines of Context:
56
56
 
57
57
static const char usbipd_help_string[] =
58
58
        "usage: usbipd [options]\n"
 
59
        "\n"
 
60
        "       -4, --ipv4\n"
 
61
        "               Bind to IPv4. Default is both.\n"
 
62
        "\n"
 
63
        "       -6, --ipv6\n"
 
64
        "               Bind to IPv6. Default is both.\n"
 
65
        "\n"
59
66
        "       -D, --daemon\n"
60
67
        "               Run as a daemon process.\n"
61
68
        "\n"
354
361
        snprintf(buf, buf_size, "%s:%s", hbuf, sbuf);
355
362
}
356
363
 
357
 
static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[])
 
364
static int listen_all_addrinfo(struct addrinfo *ai_head, int sockfdlist[],
 
365
                             int maxsockfd)
358
366
{
359
367
        struct addrinfo *ai;
360
368
        int ret, nsockfd = 0;
361
369
        const size_t ai_buf_size = NI_MAXHOST + NI_MAXSERV + 2;
362
370
        char ai_buf[ai_buf_size];
363
371
 
364
 
        for (ai = ai_head; ai && nsockfd < MAXSOCKFD; ai = ai->ai_next) {
 
372
        for (ai = ai_head; ai && nsockfd < maxsockfd; ai = ai->ai_next) {
365
373
                int sock;
366
374
                addrinfo_to_text(ai, ai_buf, ai_buf_size);
367
375
                dbg("opening %s", ai_buf);
374
382
 
375
383
                usbip_net_set_reuseaddr(sock);
376
384
                usbip_net_set_nodelay(sock);
 
385
                /* We use seperate sockets for IPv4 and IPv6
 
386
                 * (see do_standalone_mode()) */
 
387
                usbip_net_set_v6only(sock);
377
388
 
378
389
                if (sock >= FD_SETSIZE) {
379
390
                        err("FD_SETSIZE: %s: sock=%d, max=%d",
402
413
                sockfdlist[nsockfd++] = sock;
403
414
        }
404
415
 
405
 
        if (nsockfd == 0)
406
 
                return -1;
407
 
 
408
 
        dbg("listening on %d address%s", nsockfd, (nsockfd == 1) ? "" : "es");
409
 
 
410
416
        return nsockfd;
411
417
}
412
418
 
473
479
        }
474
480
}
475
481
 
476
 
static int do_standalone_mode(int daemonize)
 
482
static int do_standalone_mode(int daemonize, int ipv4, int ipv6)
477
483
{
478
484
        struct addrinfo *ai_head;
479
485
        int sockfdlist[MAXSOCKFD];
480
 
        int nsockfd;
 
486
        int nsockfd, family;
481
487
        int i, terminate;
482
488
        struct pollfd *fds;
483
489
        struct timespec timeout;
501
507
        set_signal();
502
508
        write_pid_file();
503
509
 
504
 
        ai_head = do_getaddrinfo(NULL, PF_UNSPEC);
 
510
        info("starting " PROGNAME " (%s)", usbip_version_string);
 
511
 
 
512
        /*
 
513
         * To suppress warnings on systems with bindv6only disabled
 
514
         * (default), we use seperate sockets for IPv6 and IPv4 and set
 
515
         * IPV6_V6ONLY on the IPv6 sockets.
 
516
         */
 
517
        if (ipv4 && ipv6)
 
518
                family = AF_UNSPEC;
 
519
        else if (ipv4)
 
520
                family = AF_INET;
 
521
        else
 
522
                family = AF_INET6;
 
523
 
 
524
        ai_head = do_getaddrinfo(NULL, family);
505
525
        if (!ai_head) {
506
526
                usbip_host_driver_close();
507
527
                return -1;
508
528
        }
509
 
 
510
 
        info("starting " PROGNAME " (%s)", usbip_version_string);
511
 
 
512
 
        nsockfd = listen_all_addrinfo(ai_head, sockfdlist);
 
529
        nsockfd = listen_all_addrinfo(ai_head, sockfdlist,
 
530
                sizeof(sockfdlist) / sizeof(*sockfdlist));
 
531
        freeaddrinfo(ai_head);
513
532
        if (nsockfd <= 0) {
514
533
                err("failed to open a listening socket");
515
 
                freeaddrinfo(ai_head);
516
534
                usbip_host_driver_close();
517
535
                return -1;
518
536
        }
 
537
 
 
538
        dbg("listening on %d address%s", nsockfd, (nsockfd == 1) ? "" : "es");
 
539
 
519
540
        fds = calloc(nsockfd, sizeof(struct pollfd));
520
541
        for (i = 0; i < nsockfd; i++) {
521
542
                fds[i].fd = sockfdlist[i];
551
572
 
552
573
        info("shutting down " PROGNAME);
553
574
        free(fds);
554
 
        freeaddrinfo(ai_head);
555
575
        usbip_host_driver_close();
556
576
 
557
577
        return 0;
560
580
int main(int argc, char *argv[])
561
581
{
562
582
        static const struct option longopts[] = {
 
583
                { "ipv4",     no_argument,       NULL, '4' },
 
584
                { "ipv6",     no_argument,       NULL, '6' },
 
585
                { "daemon",   no_argument,       NULL, 'D' },
563
586
                { "daemon",   no_argument,       NULL, 'D' },
564
587
                { "debug",    no_argument,       NULL, 'd' },
565
588
                { "pid",      optional_argument, NULL, 'P' },
576
599
        } cmd;
577
600
 
578
601
        int daemonize = 0;
 
602
        int ipv4 = 0, ipv6 = 0;
579
603
        int opt, rc = -1;
580
604
        pid_file = NULL;
581
605
 
587
611
 
588
612
        cmd = cmd_standalone_mode;
589
613
        for (;;) {
590
 
                opt = getopt_long(argc, argv, "DdP::t:hv", longopts, NULL);
 
614
                opt = getopt_long(argc, argv, "46DdP::t:hv", longopts, NULL);
591
615
 
592
616
                if (opt == -1)
593
617
                        break;
594
618
 
595
619
                switch (opt) {
 
620
                case '4':
 
621
                        ipv4 = 1;
 
622
                        break;
 
623
                case '6':
 
624
                        ipv6 = 1;
 
625
                        break;
596
626
                case 'D':
597
627
                        daemonize = 1;
598
628
                        break;
618
648
                }
619
649
        }
620
650
 
 
651
        if (!ipv4 && !ipv6)
 
652
                ipv4 = ipv6 = 1;
 
653
 
621
654
        switch (cmd) {
622
655
        case cmd_standalone_mode:
623
 
                rc = do_standalone_mode(daemonize);
 
656
                rc = do_standalone_mode(daemonize, ipv4, ipv6);
624
657
                remove_pid_file();
625
658
                break;
626
659
        case cmd_version: