Пример #1
0
static int mdns_external_avahi_register(char *apname, int port) {
    char mdns_port[6];
    sprintf(mdns_port, "%d", config.port);

    char *argv[] = {
        NULL, apname, "_raop._tcp", mdns_port, MDNS_RECORD, NULL
    };

    argv[0] = "avahi-publish-service";
    int pid = fork_execvp(argv[0], argv);
    if (pid >= 0) {
        mdns_pid = pid;
        return 0;
    }
    else
        debug(1, "Calling %s failed, trying next method", argv[0]);

    argv[0] = "mDNSPublish";
    pid = fork_execvp(argv[0], argv);
    if (pid >= 0)
    {
        mdns_pid = pid;
        return 0;
    }
    else
        warn("Calling %s failed !", argv[0]);
    
    // If we reach here, both execvp calls failed.
    return -1;
}
static int mdns_external_dns_sd_register(char *apname, int port) {
  char mdns_port[6];
  sprintf(mdns_port, "%d", config.port);

  char *argvwithoutmetadata[] = {NULL, apname, config.regtype, mdns_port,
                                 MDNS_RECORD_WITHOUT_METADATA, NULL};

#ifdef CONFIG_METADATA
  char *argvwithmetadata[] = {NULL, apname, config.regtype, mdns_port, MDNS_RECORD_WITH_METADATA,
                              NULL};
#endif

  char **argv;
#ifdef CONFIG_METADATA
  if (config.metadata_enabled)
    argv = argvwithmetadata;
  else
#endif

    argv = argvwithoutmetadata;

  int pid = fork_execvp(argv[0], argv);
  if (pid >= 0) {
    mdns_pid = pid;
    return 0;
  } else
    warn("Calling %s failed !", argv[0]);

  return -1;
}
static int mdns_external_avahi_register(char *apname, int port) {
  char mdns_port[6];
  sprintf(mdns_port, "%d", config.port);

  char *argvwithoutmetadata[] = {NULL, apname, config.regtype, mdns_port,
                                 MDNS_RECORD_WITHOUT_METADATA, NULL};
#ifdef CONFIG_METADATA
  char *argvwithmetadata[] = {NULL, apname, config.regtype, mdns_port, MDNS_RECORD_WITH_METADATA,
                              NULL};
#endif
  char **argv;

#ifdef CONFIG_METADATA
  if (config.metadata_enabled)
    argv = argvwithmetadata;
  else
#endif
    argv = argvwithoutmetadata;

  argv[0] = "avahi-publish-service";
  int pid = fork_execvp(argv[0], argv);
  if (pid >= 0) {
    mdns_pid = pid;
    return 0;
  } else
    warn("Calling %s failed !", argv[0]);

  argv[0] = "mDNSPublish";
  pid = fork_execvp(argv[0], argv);
  if (pid >= 0) {
    mdns_pid = pid;
    return 0;
  } else
    warn("Calling %s failed !", argv[0]);

  // If we reach here, both execvp calls failed.
  return -1;
}
Пример #4
0
int
fork_execlp(const char *file, ...) {
  const char *argv[1024];
  unsigned int i;
  va_list args;
 
  va_start (args, file);
 
  i = 0;
  do
    argv[i] = va_arg (args, const char *);
  while (argv[i++] != NULL);
 
  va_end (args);
 
  return fork_execvp (file, (char **) argv);
}
Пример #5
0
static int mdns_external_dns_sd_register(char *apname, int port) {
    char mdns_port[6];
    sprintf(mdns_port, "%d", config.port);

    char *argv[] = {"dns-sd", "-R", apname, "_raop._tcp", ".",
                        mdns_port, MDNS_RECORD, NULL};

    int pid = fork_execvp(argv[0], argv);
    if (pid >= 0)
    {
        mdns_pid = pid;
        return 0;
    }
    else
        warn("Calling %s failed !", argv[0]);

    return -1;
}
Пример #6
0
int run_receiver(UDR_Options * udr_options) {

    int orig_ppid = getppid();

    UDT::startup();

    addrinfo hints;
    addrinfo* res;

    set_verbosity(udr_options->verbose);

    memset(&hints, 0, sizeof(struct addrinfo));

    hints.ai_flags = AI_PASSIVE;
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;

    char receiver_port[NI_MAXSERV];
    UDTSOCKET serv;

    bool bad_port = false;

    for(int port_num = udr_options->start_port; port_num < udr_options->end_port; port_num++) {
        bad_port = false;
        snprintf(receiver_port, sizeof(receiver_port), "%d", port_num);

        if (0 != getaddrinfo(NULL, receiver_port, &hints, &res)) {
            bad_port = true;
        }
        else {
            serv = UDT::socket(res->ai_family, res->ai_socktype, res->ai_protocol);
            if (UDT::ERROR == UDT::bind(serv, res->ai_addr, res->ai_addrlen)) {
                bad_port = true;
            }
        }

        freeaddrinfo(res);

        if(!bad_port)
            break;
    }

    if(bad_port){
        fprintf(stderr, "[udr receiver] ERROR: could not bind to any port in range %d - %d\n", udr_options->start_port, udr_options->end_port);
        return 0;
    }

    unsigned char rand_pp[PASSPHRASE_SIZE];

    if (!RAND_bytes((unsigned char *) rand_pp, PASSPHRASE_SIZE)) {
        fprintf(stderr, "Couldn't generate random key: %ld\n", ERR_get_error());
        exit(EXIT_FAILURE);
    }

    //stdout port number and password -- to send back to the client
    printf("%s ", receiver_port);

    for(int i = 0; i < PASSPHRASE_SIZE; i++) {
        printf("%02x", rand_pp[i]);
    }
    printf(" \n");
    fflush(stdout);

    verbose_print("[udr receiver] server is ready at port %s\n", receiver_port);

    if (UDT::ERROR == UDT::listen(serv, 10)) {
        cerr << "[udr receiver] listen: " << UDT::getlasterror().getErrorMessage() << endl;
        return 0;
    }

    sockaddr_storage clientaddr;
    int addrlen = sizeof(clientaddr);

    UDTSOCKET recver;

    if (UDT::INVALID_SOCK == (recver = UDT::accept(serv, (sockaddr*)&clientaddr, &addrlen))) {
        fprintf(stderr, "[udr receiver] accept: %s\n", UDT::getlasterror().getErrorMessage());
        return 0;
    }

    char clienthost[NI_MAXHOST];
    char clientservice[NI_MAXSERV];
    getnameinfo((sockaddr *)&clientaddr, addrlen, clienthost, sizeof(clienthost), clientservice, sizeof(clientservice), NI_NUMERICHOST|NI_NUMERICSERV);


    string cmd_str = udt_recv_string(recver);
    const char * cmd = cmd_str.c_str();

    //perhaps want to at least check that starts with rsync?
    if(strncmp(cmd, "rsync ", 5) != 0){
        exit(1);
    }

    char * rsync_cmd;
    if(udr_options->server_connect){
        verbose_print("[udr receiver] server connect mode\n");

        rsync_cmd = (char *)malloc(100);

        if(strlen(udr_options->server_config) > 0){
            sprintf(rsync_cmd, "%s%s %s", "rsync --config=", udr_options->server_config, " --server --daemon .");
        }
        else{
            strcpy(rsync_cmd, "rsync --server --daemon .");
        }
    }
    else{
        rsync_cmd = (char *)malloc(strlen(cmd) + 1);
        strcpy(rsync_cmd, cmd);
    }

    verbose_print("[udr receiver] rsync cmd: %s\n", rsync_cmd);

    char ** sh_cmd = (char **)malloc(sizeof(char *) * 4);
    sh_cmd[0] = udr_options->shell_program;
    sh_cmd[1] = "-c";
    sh_cmd[2] = rsync_cmd;
    sh_cmd[3] = NULL;

    //now fork and exec the rsync on the remote side using sh (so that wildcards will be expanded properly)
    int child_to_parent, parent_to_child;

    int rsync_pid = fork_execvp(udr_options->shell_program, sh_cmd, &parent_to_child, &child_to_parent);

    //now if we're in server mode need to drop privileges if specified
    if(udr_options->rsync_gid > 0){
        setgid(udr_options->rsync_gid);
    }
    if(udr_options->rsync_uid > 0){
        setuid(udr_options->rsync_uid);
    }

    verbose_print("[udr receiver] rsync pid: %d\n", rsync_pid);

    struct thread_data recv_to_udt;
    recv_to_udt.udt_socket = &recver;
    recv_to_udt.fd = child_to_parent; //stdout of rsync server process
    recv_to_udt.id = 2;
    recv_to_udt.is_complete = false;

    struct thread_data udt_to_recv;
    udt_to_recv.udt_socket = &recver;
    udt_to_recv.fd = parent_to_child; //stdin of rsync server process
    udt_to_recv.id = 3;
    udt_to_recv.is_complete = false;

    if(udr_options->encryption){
        crypto encrypt(EVP_ENCRYPT, PASSPHRASE_SIZE, rand_pp,
            udr_options->encryption_type);
        crypto decrypt(EVP_DECRYPT, PASSPHRASE_SIZE, rand_pp,
            udr_options->encryption_type);
        recv_to_udt.crypt = &encrypt;
        udt_to_recv.crypt = &decrypt;
    }
    else{
        recv_to_udt.crypt = NULL;
        udt_to_recv.crypt = NULL;
    }

    pthread_t recv_to_udt_thread;
    pthread_create(&recv_to_udt_thread, NULL, handle_to_udt, (void *)&recv_to_udt);

    pthread_t udt_to_recv_thread;
    pthread_create(&udt_to_recv_thread, NULL, udt_to_handle, (void*)&udt_to_recv);

    verbose_print("[udr receiver] waiting to join on recv_to_udt_thread\n");
    verbose_print("[udr receiver] ppid %d pid %d\n", getppid(), getpid());

    //going to poll if the ppid changes then we know it's exited and then we exit all of our threads and exit as well
    //also going to check if either thread is complete, if one is then the other should also be killed
    //bit of a hack to deal with the pthreads
    while(true){
        if(getppid() != orig_ppid){
            pthread_kill(recv_to_udt_thread, SIGUSR1);
            pthread_kill(udt_to_recv_thread, SIGUSR1);
            break;
        }
        if(recv_to_udt.is_complete && udt_to_recv.is_complete){
            verbose_print("[udr receiver] both threads are complete: recv_to_udt.is_complete %d udt_to_recv.is_complete %d\n", recv_to_udt.is_complete, udt_to_recv.is_complete);
            break;
        }
        else if(recv_to_udt.is_complete){
            verbose_print("[udr receiver] recv_to_udt is complete: recv_to_udt.is_complete %d udt_to_recv.is_complete %d\n", recv_to_udt.is_complete, udt_to_recv.is_complete);
            break;
        }
        else if(udt_to_recv.is_complete){
            verbose_print("[udr receiver] udt_to_recv is complete: recv_to_udt.is_complete %d udt_to_recv.is_complete %d\n", recv_to_udt.is_complete, udt_to_recv.is_complete);
            break;
        }

        sleep(ppid_poll);
    }

    verbose_print("[udr receiver] Trying to close recver\n");
    UDT::close(recver);

    verbose_print("[udr receiver] Closed recver\n");

    UDT::close(serv);

    verbose_print("[udr receiver] Closed serv\n");

    UDT::cleanup();

    verbose_print("[udr receiver] UDT cleaned up\n");

    return 0;
}