コード例 #1
0
void HostMatrixELL<ValueType>::Clear() {

  if (this->nnz_ > 0) {

    free_host(&this->mat_.val);
    free_host(&this->mat_.col);

    this->nrow_ = 0;
    this->ncol_ = 0;
    this->nnz_  = 0;

  }

}
コード例 #2
0
ファイル: host_matrix_coo.cpp プロジェクト: dcm3c/agros2d
void HostMatrixCOO<ValueType>::Clear() {

  if (this->get_nnz() > 0) {

    free_host(&this->mat_.row);
    free_host(&this->mat_.col);
    free_host(&this->mat_.val);

    this->nrow_ = 0;
    this->ncol_ = 0;
    this->nnz_  = 0;
  }

}
コード例 #3
0
ファイル: knownhost.c プロジェクト: infinitude-cn/cpp
/*
 * libssh2_knownhost_del
 *
 * Remove a host from the collection of known hosts.
 *
 */
LIBSSH2_API int
libssh2_knownhost_del(LIBSSH2_KNOWNHOSTS *hosts,
                      struct libssh2_knownhost *entry)
{
    struct known_host *node;

    /* check that this was retrieved the right way or get out */
    if(!entry || (entry->magic != KNOWNHOST_MAGIC))
        return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL,
                              "Invalid host information");

    /* get the internal node pointer */
    node = entry->node;

    /* unlink from the list of all hosts */
    _libssh2_list_remove(&node->node);

    /* clear the struct now since the memory in which it is allocated is
       about to be freed! */
    memset(entry, 0, sizeof(struct libssh2_knownhost));

    /* free all resources */
    free_host(hosts->session, node);

    return 0;
}
コード例 #4
0
ファイル: zeroconf.c プロジェクト: PascalGohl/distcc
/* Called when a resolve call completes */
static void resolve_reply(
        AvahiServiceResolver *UNUSED(r),
        AvahiIfIndex UNUSED(interface),
        AvahiProtocol UNUSED(protocol),
        AvahiResolverEvent event,
        const char *name,
        const char *UNUSED(type),
        const char *UNUSED(domain),
        const char *UNUSED(host_name),
        const AvahiAddress *a,
        uint16_t port,
        AvahiStringList *txt,
        AvahiLookupResultFlags UNUSED(flags),
        void *userdata) {

    struct host *h = userdata;

    switch (event) {

        case AVAHI_RESOLVER_FOUND: {
            AvahiStringList *i;

            /* Look for the number of CPUs in TXT RRs */
            for (i = txt; i; i = i->next) {
                char *key, *value;

                if (avahi_string_list_get_pair(i, &key, &value, NULL) < 0)
                    continue;

                if (!strcmp(key, "cpus"))
                    if ((h->n_cpus = atoi(value)) <= 0)
                        h->n_cpus = 1;

                avahi_free(key);
                avahi_free(value);
            }

            h->address = *a;
            h->port = port;

            avahi_service_resolver_free(h->resolver);
            h->resolver = NULL;

            /* Write modified hosts file */
            write_hosts(h->daemon_data);

            break;
        }

        case AVAHI_RESOLVER_FAILURE:

            rs_log_warning("Failed to resolve service '%s': %s\n", name,
                           avahi_strerror(avahi_client_errno(h->daemon_data->client)));

            free_host(h);
            break;
    }

}
コード例 #5
0
void MultiColored<OperatorType, VectorType, ValueType>::Clear(void) {

  LOG_DEBUG(this, "MultiColored::Clear()",
            this->build_);

  if (this->build_ == true) {

    delete this->preconditioner_ ;
    this->preconditioner_ = NULL;

    if (this->decomp_ == true) {

      for(int i=0; i<this->num_blocks_; ++i) {

        this->x_block_[i]->Clear();
        delete this->x_block_[i];

        this->diag_block_[i]->Clear();
        delete this->diag_block_[i];
        this->diag_solver_[i]->Clear();
        delete this->diag_solver_[i];

        for(int j=0; j<this->num_blocks_; ++j)
          delete this->preconditioner_block_[i][j];

        delete[] this->preconditioner_block_[i];
      }

      delete[] this->x_block_;
      delete[] this->diag_block_;
      delete[] this->diag_solver_;
      delete[] this->preconditioner_block_;
    }

    if (this->analyzer_op_ != this->op_)
      delete this->analyzer_op_;

    this->analyzer_op_ = NULL ;

    this->x_.Clear();

    this->permutation_.Clear();
    free_host(&this->block_sizes_);      
    this->num_blocks_ = 0 ;

    this->diag_.Clear();

    this->op_mat_format_ = false;
    this->precond_mat_format_ = CSR;

    this->decomp_ = true;

    this->build_ = false;

  }

}
コード例 #6
0
void HostVector<ValueType>::Clear(void) {

  if (this->size_ >0) {

    free_host(&this->vec_);

    this->size_ = 0 ;

  }

}
コード例 #7
0
ファイル: knownhost.c プロジェクト: alexmchale/turbosh
/*
 * libssh2_knownhost_free
 *
 * Free an entire collection of known hosts.
 *
 */
LIBSSH2_API void
libssh2_knownhost_free(LIBSSH2_KNOWNHOSTS *hosts)
{
    struct known_host *node;
    struct known_host *next;

    for(node = _libssh2_list_first(&hosts->head); node; node = next) {
        next = _libssh2_list_next(&node->node);
        free_host(hosts->session, node);
    }
    LIBSSH2_FREE(hosts->session, hosts);
}
コード例 #8
0
ファイル: zeroconf.c プロジェクト: PascalGohl/distcc
/* Remove hosts with duplicate service names from the host list.
 * Hosts with multiple IP addresses show up more than once, but
 * should all have the same service name: "distcc@hostname" */
static void remove_duplicate_services(struct daemon_data *d) {
    struct host *host1, *host2, *prev;
    assert(d);
    for (host1 = d->hosts; host1; host1 = host1->next) {
        assert(host1->service);
        for (host2 = host1->next, prev = host1; host2; host2 = prev->next) {
            assert(host2->service);
            if (!strcmp(host1->service, host2->service)) {
                prev->next = host2->next;
                free_host(host2);
            } else {
                prev = host2;
            }
        }
    }
}
コード例 #9
0
bool HostMatrixCOO<ValueType>::PermuteBackward(const BaseVector<int> &permutation) {

    assert(&permutation != NULL);

    // symmetric permutation only
    assert( (permutation.get_size() == this->nrow_) &&
            (permutation.get_size() == this->ncol_) );

    const HostVector<int> *cast_perm = dynamic_cast<const HostVector<int>*> (&permutation);
    assert(cast_perm != NULL);

    HostMatrixCOO<ValueType> src(this->local_backend_);
    src.AllocateCOO(this->nnz_, this->nrow_, this->ncol_);
    src.CopyFrom(*this);

    _set_omp_backend_threads(this->local_backend_, this->nnz_);

    // TODO
    // Is there a better way?
    int *pb = NULL;
    allocate_host(this->nrow_, &pb);

    #pragma omp parallel for
    for (int i=0; i<this->nrow_; ++i)
        pb [ cast_perm->vec_[i] ] = i;

    #pragma omp parallel for
    for (int i=0; i<this->nnz_; ++i) {

        this->mat_.row[i] = pb[src.mat_.row[i]];
        this->mat_.col[i] = pb[src.mat_.col[i]];

    }

    free_host(&pb);

    return true;

}
コード例 #10
0
ファイル: zeroconf.c プロジェクト: PascalGohl/distcc
/* Remove a service from the host list */
static void remove_service(struct daemon_data *d, AvahiIfIndex interface, AvahiProtocol protocol, const char *name, const char *domain) {
    struct host *h, *p = NULL;
    assert(d);

    for (h = d->hosts; h; h = h->next) {
        if (h->interface == interface &&
            h->protocol == protocol &&
            !strcmp(h->service, name) &&
            avahi_domain_equal(h->domain, domain)) {

            if (p)
                p->next = h->next;
            else
                d->hosts = h->next;

            free_host(h);

            break;
        } else
            p = h;
    }
}
コード例 #11
0
ファイル: knownhost.c プロジェクト: alexmchale/turbosh
/*
 * libssh2_knownhost_del
 *
 * Remove a host from the collection of known hosts.
 *
 */
LIBSSH2_API int
libssh2_knownhost_del(LIBSSH2_KNOWNHOSTS *hosts,
                      struct libssh2_knownhost *entry)
{
    struct known_host *node;
    if(!entry || (entry->magic != KNOWNHOST_MAGIC))
        /* check that this was retrieved the right way or get out */
        return LIBSSH2_ERROR_INVAL;

    /* get the internal node pointer */
    node = entry->node;

    /* unlink from the list of all hosts */
    _libssh2_list_remove(&node->node);

    /* free all resources */
    free_host(hosts->session, node);

    /* clear the struct now since this host entry has been removed! */
    memset(entry, 0, sizeof(struct libssh2_knownhost));

    return 0;
}
コード例 #12
0
ファイル: knownhost.c プロジェクト: alexmchale/turbosh
LIBSSH2_API int
libssh2_knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
                      const char *host, const char *salt,
                      const char *key, size_t keylen,
                      int typemask, struct libssh2_knownhost **store)
{
    struct known_host *entry =
        LIBSSH2_ALLOC(hosts->session, sizeof(struct known_host));
    size_t hostlen = strlen(host);
    int rc = LIBSSH2_ERROR_ALLOC;
    char *ptr;
    unsigned int ptrlen;

    if(!entry)
        return rc;

    if(!(typemask & LIBSSH2_KNOWNHOST_KEY_MASK))
        /* make sure we have a key type set */
        return LIBSSH2_ERROR_INVAL;

    memset(entry, 0, sizeof(struct known_host));

    entry->typemask = typemask;

    switch(entry->typemask  & LIBSSH2_KNOWNHOST_TYPE_MASK) {
    case LIBSSH2_KNOWNHOST_TYPE_PLAIN:
    case LIBSSH2_KNOWNHOST_TYPE_CUSTOM:
        entry->name = LIBSSH2_ALLOC(hosts->session, hostlen+1);
        if(!entry)
            goto error;
        memcpy(entry->name, host, hostlen+1);
        break;
    case LIBSSH2_KNOWNHOST_TYPE_SHA1:
        rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
                                   host, hostlen);
        if(rc)
            goto error;
        entry->name = ptr;
        entry->name_len = ptrlen;

        rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
                                   salt, strlen(salt));
        if(rc)
            goto error;
        entry->salt = ptr;
        entry->salt_len = ptrlen;
        break;
    default:
        rc = LIBSSH2_ERROR_METHOD_NOT_SUPPORTED;
        goto error;
    }

    if(typemask & LIBSSH2_KNOWNHOST_KEYENC_BASE64) {
        /* the provided key is base64 encoded already */
        if(!keylen)
            keylen = strlen(key);
        entry->key = LIBSSH2_ALLOC(hosts->session, keylen+1);
        if(!entry)
            goto error;
        memcpy(entry->key, key, keylen+1);
        entry->key[keylen]=0; /* force a terminating zero trailer */
    }
    else {
        /* key is raw, we base64 encode it and store it as such */
        size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen,
                                             &ptr);
        if(!nlen)
            goto error;

        entry->key = ptr;
    }

    /* add this new host to the big list of known hosts */
    _libssh2_list_add(&hosts->head, &entry->node);

    if(store)
        *store = knownhost_to_external(entry);

    return LIBSSH2_ERROR_NONE;
  error:
    free_host(hosts->session, entry);
    return rc;
}
コード例 #13
0
ファイル: knownhost.c プロジェクト: infinitude-cn/cpp
static int
knownhost_add(LIBSSH2_KNOWNHOSTS *hosts,
              const char *host, const char *salt,
              const char *key_type_name, size_t key_type_len,
              const char *key, size_t keylen,
              const char *comment, size_t commentlen,
              int typemask, struct libssh2_knownhost **store)
{
    struct known_host *entry;
    size_t hostlen = strlen(host);
    int rc;
    char *ptr;
    unsigned int ptrlen;

    /* make sure we have a key type set */
    if(!(typemask & LIBSSH2_KNOWNHOST_KEY_MASK))
        return _libssh2_error(hosts->session, LIBSSH2_ERROR_INVAL,
                              "No key type set");

    if(!(entry = LIBSSH2_CALLOC(hosts->session, sizeof(struct known_host))))
        return _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
                              "Unable to allocate memory for known host "
                              "entry");

    entry->typemask = typemask;

    switch(entry->typemask  & LIBSSH2_KNOWNHOST_TYPE_MASK) {
    case LIBSSH2_KNOWNHOST_TYPE_PLAIN:
    case LIBSSH2_KNOWNHOST_TYPE_CUSTOM:
        entry->name = LIBSSH2_ALLOC(hosts->session, hostlen+1);
        if(!entry->name) {
            rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
                                "Unable to allocate memory for host name");
            goto error;
        }
        memcpy(entry->name, host, hostlen+1);
        entry->name_len = hostlen;
        break;
    case LIBSSH2_KNOWNHOST_TYPE_SHA1:
        rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
                                   host, hostlen);
        if(rc)
            goto error;
        entry->name = ptr;
        entry->name_len = ptrlen;

        rc = libssh2_base64_decode(hosts->session, &ptr, &ptrlen,
                                   salt, strlen(salt));
        if(rc)
            goto error;
        entry->salt = ptr;
        entry->salt_len = ptrlen;
        break;
    default:
        rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
                            "Unknown host name type");
        goto error;
    }

    if(typemask & LIBSSH2_KNOWNHOST_KEYENC_BASE64) {
        /* the provided key is base64 encoded already */
        if(!keylen)
            keylen = strlen(key);
        entry->key = LIBSSH2_ALLOC(hosts->session, keylen+1);
        if(!entry->key) {
            rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
                                "Unable to allocate memory for key");
            goto error;
        }
        memcpy(entry->key, key, keylen+1);
        entry->key[keylen]=0; /* force a terminating zero trailer */
    }
    else {
        /* key is raw, we base64 encode it and store it as such */
        size_t nlen = _libssh2_base64_encode(hosts->session, key, keylen,
                                             &ptr);
        if(!nlen) {
            rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
                                "Unable to allocate memory for "
                                "base64-encoded key");
            goto error;
        }

        entry->key = ptr;
    }

    if (key_type_name && ((typemask & LIBSSH2_KNOWNHOST_KEY_MASK) ==
                          LIBSSH2_KNOWNHOST_KEY_UNKNOWN)) {
        entry->key_type_name = LIBSSH2_ALLOC(hosts->session, key_type_len+1);
        if (!entry->key_type_name) {
            rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
                                "Unable to allocate memory for key type");
            goto error;
        }
        memcpy(entry->key_type_name, key_type_name, key_type_len);
        entry->key_type_name[key_type_len]=0;
        entry->key_type_len = key_type_len;
    }

    if (comment) {
        entry->comment = LIBSSH2_ALLOC(hosts->session, commentlen+1);
        if(!entry->comment) {
            rc = _libssh2_error(hosts->session, LIBSSH2_ERROR_ALLOC,
                                "Unable to allocate memory for comment");
            goto error;
        }
        memcpy(entry->comment, comment, commentlen+1);
        entry->comment[commentlen]=0; /* force a terminating zero trailer */
        entry->comment_len = commentlen;
    }
    else {
        entry->comment = NULL;
    }

    /* add this new host to the big list of known hosts */
    _libssh2_list_add(&hosts->head, &entry->node);

    if(store)
        *store = knownhost_to_external(entry);

    return LIBSSH2_ERROR_NONE;
  error:
    free_host(hosts->session, entry);
    return rc;
}
コード例 #14
0
ファイル: mixed_precision.cpp プロジェクト: dcm3c/agros2d
void MixedPrecisionDC<OperatorTypeH, VectorTypeH, ValueTypeH, 
                      OperatorTypeL, VectorTypeL, ValueTypeL>::Build(void) {

  if (this->build_ == true)
    this->Clear();

  assert(this->build_ == false);
  this->build_ = true;

  assert(this->Solver_L_ != NULL);
  assert(this->op_ != NULL);

  this->op_h_ = this->op_;

  assert(this->op_->get_nrow() == this->op_->get_ncol());
  assert(this->op_->get_nrow() > 0);

  assert(this->op_l_ == NULL);
  this->op_l_ = new OperatorTypeL;
        
  this->r_l_.Allocate("r_l", this->op_l_->get_nrow());  
  this->r_h_.Allocate("r_h", this->op_h_->get_nrow());

  this->d_h_.Allocate("d_h", this->op_h_->get_nrow());
  this->d_l_.Allocate("d_l", this->op_h_->get_nrow());
  
  // TODO - ugly
  // copy the matrix

  // CSR H
  int *row_offset = NULL;
  int *col = NULL;
  ValueTypeH *val_h = NULL;

  // CSR L
  ValueTypeL *val_l = NULL;

  allocate_host(this->op_h_->get_nrow()+1, &row_offset);
  allocate_host(this->op_h_->get_nnz(),    &col);
  allocate_host(this->op_h_->get_nnz(),    &val_l);
  allocate_host(this->op_h_->get_nnz(),    &val_h);
  
  this->op_h_->CopyToCSR(row_offset, col, val_h);

  for (int i=0; i<this->op_h_->get_nnz(); ++i)
    val_l[i] = ValueTypeL( val_h[i] );
  
  this->op_l_->SetDataPtrCSR(&row_offset, &col, &val_l,
                             "Low prec Matrix", 
                             this->op_h_->get_nnz(),
                             this->op_h_->get_nrow(),
                             this->op_h_->get_ncol());
  
  // free only the h prec values
  free_host(&val_h);

  this->Solver_L_->SetOperator(*this->op_l_);
  this->Solver_L_->Build();

  this->op_l_->MoveToAccelerator();
  this->Solver_L_->MoveToAccelerator();
}
コード例 #15
0
void HostVector<ValueType>::Assemble(const int *ii, const ValueType *v,
                                     int size, const int n) {

  assert(ii != NULL);
  assert(v != NULL);
  assert(size > 0);
  assert(n >= 0);

  _set_omp_backend_threads(this->local_backend_, this->size_);
  const int nThreads = omp_get_max_threads();

  int N = n;

  if (N == 0) {

#pragma omp parallel for
    for (int i=0; i<size; ++i) {

      assert(ii[i] >= 0);

      int val = ii[i]+1;

      if (val > N) {
#pragma omp critical
{
        N = val;
}
      }

    }

    this->Clear();
    this->Allocate(N);

  }

  if (nThreads <= 2) {

    // serial
    for (int i=0; i<size; ++i)
      this->vec_[ ii[i] ] += v[i];

  } else {

    // parallel
    ValueType **v_red;

    v_red = (ValueType **) malloc(nThreads*sizeof(ValueType*));

    for (int k=0; k<nThreads; ++k) {

      v_red[k] = NULL;
      allocate_host(N, &v_red[k]);
      set_to_zero_host(N, v_red[k]);

    }

#pragma omp parallel
{
    const int me = omp_get_thread_num();
    const int istart = size*me/nThreads;
    const int iend = size*(me+1)/nThreads;

    for (int i = istart; i < iend; i++)
      v_red[me][ii[i]] += v[i];
}

#pragma omp parallel
{
    const int me = omp_get_thread_num();
    const int istart = N*me/nThreads;
    const int iend = N*(me+1)/nThreads;

    for (int i = istart; i < iend; ++i)
      for (int k=0; k<nThreads; ++k)
        this->vec_[i] += v_red[k][i];

}

    for (int k=0; k<nThreads; ++k)
      free_host(&v_red[k]);

    free(v_red);

  }

}
コード例 #16
0
void MultiColored<OperatorType, VectorType, ValueType>::Decompose_(void) {

  LOG_DEBUG(this, "MultiColored::Decompose_()",
            " * beging");

  if (this->decomp_ == true) {

    assert(this->num_blocks_ > 0);
    assert(this->block_sizes_ != NULL);

    int *offsets = NULL;
    allocate_host(this->num_blocks_+1, &offsets);    

    offsets[0] = 0 ;
    for(int i=0; i<this->num_blocks_; ++i)
      offsets[i+1] = this->block_sizes_[i];

    // sum up
    for(int i=0; i<this->num_blocks_; ++i)
      offsets[i+1] += offsets[i];

    this->diag_solver_ = new Solver<OperatorType, VectorType, ValueType>* [this->num_blocks_];

    this->preconditioner_block_ = new OperatorType** [this->num_blocks_]; 
    for (int i=0; i<this->num_blocks_; ++i) 
      this->preconditioner_block_[i] = new OperatorType* [this->num_blocks_];

    this->x_block_    = new VectorType* [this->num_blocks_];
    this->diag_block_ = new VectorType* [this->num_blocks_];

    for(int i=0; i<this->num_blocks_; ++i)
      for(int j=0; j<this->num_blocks_; ++j) {
        this->preconditioner_block_[i][j] = new LocalMatrix<ValueType>;
        this->preconditioner_block_[i][j]->CloneBackend( *this->op_ );
        
      }

    this->preconditioner_->ExtractSubMatrices(this->num_blocks_,
                                              this->num_blocks_,
                                              offsets,
                                              offsets,
                                              this->preconditioner_block_);

    free_host(&offsets);

    int x_offset = 0;
    for (int i=0; i<this->num_blocks_; ++i) {
      this->diag_block_[i] = new VectorType;
      this->diag_block_[i]->CloneBackend(*this->op_); // clone backend
      this->diag_block_[i]->Allocate("Diagonal preconditioners blocks",
                                     this->block_sizes_[i]);
      
      this->preconditioner_block_[i][i]->ExtractDiagonal(this->diag_block_[i]);

      
      this->x_block_[i] = new VectorType; // empty vector
      
      this->x_block_[i]->CloneBackend(*this->op_); // clone backend
      this->x_block_[i]->Allocate("MultiColored Preconditioner x_block_",
                                  this->block_sizes_[i]);
      
      
      x_offset += this->block_sizes_[i];

      Jacobi<OperatorType, VectorType, ValueType> *jacobi = new Jacobi<OperatorType, VectorType, ValueType>;
      jacobi->SetOperator(*this->preconditioner_block_[i][i]);
      jacobi->Build();
      
      this->diag_solver_[i] = jacobi;
      
      this->preconditioner_block_[i][i]->Clear();
    }
    
    // Clone the format 
    // e.g. the preconditioner block matrices will have the same format as this->op_
    if (this->op_mat_format_ == true)
      for(int i=0; i<this->num_blocks_; ++i)
        for(int j=0; j<this->num_blocks_; ++j)
          this->preconditioner_block_[i][j]->ConvertTo(this->precond_mat_format_);
  
  } else {

    this->diag_.CloneBackend(*this->op_);
    this->preconditioner_->ExtractDiagonal(&this->diag_);

  }

  this->x_.CloneBackend(*this->op_); 
  this->x_.Allocate("Permuted solution vector",
                    this->op_->get_nrow());

  LOG_DEBUG(this, "MultiColored::Decompose_()",
            " * end");

}
コード例 #17
0
ファイル: zeroconf.c プロジェクト: PascalGohl/distcc
/* The main function of the background daemon */
static int daemon_proc(const char *host_file, const char *lock_file, int n_slots) {
    int ret = 1;
    int lock_fd = -1;
    struct daemon_data d;
    time_t clip_time;
    int error;
    char machine[64], version[64], stype[128];

    rs_add_logger(rs_logger_syslog, RS_LOG_DEBUG, NULL, 0);

    /* Prepare daemon data structure */
    d.fd = -1;
    d.hosts = NULL;
    d.n_slots = n_slots;
    d.simple_poll = NULL;
    d.browser = NULL;
    d.client = NULL;
    clip_time = time(NULL);

    rs_log_info("Zeroconf daemon running.\n");

    /* Open daemon lock file and lock it */
    if ((lock_fd = open(lock_file, O_RDWR|O_CREAT, 0666)) < 0) {
        rs_log_crit("open('%s') failed: %s\n", lock_file, strerror(errno));
        goto finish;
    }

    if (generic_lock(lock_fd, 1, 1, 0) < 0) {
        /* lock failed, there's probably already another daemon running */
        goto finish;
    }

    /* Open host file */
    if ((d.fd = open(host_file, O_RDWR|O_CREAT, 0666)) < 0) {
        rs_log_crit("open('%s') failed: %s\n", host_file, strerror(errno));
        goto finish;
    }

    /* Clear host file */
    write_hosts(&d);

    if (!(d.simple_poll = avahi_simple_poll_new())) {
        rs_log_crit("Failed to create simple poll object.\n");
        goto finish;
    }

    if (!(d.client = avahi_client_new(
                  avahi_simple_poll_get(d.simple_poll),
                  0,
                  client_callback,
                  &d,
                  &error))) {
        rs_log_crit("Failed to create Avahi client object: %s\n", avahi_strerror(error));
        goto finish;
    }

    if (dcc_get_gcc_version(version, sizeof(version)) &&
        dcc_get_gcc_machine(machine, sizeof(machine))) {

        dcc_make_dnssd_subtype(stype, sizeof(stype), version, machine);
    } else {
        rs_log_warning("Warning, failed to get CC version and machine type.\n");

        strncpy(stype, DCC_DNS_SERVICE_TYPE, sizeof(stype));
        stype[sizeof(stype)-1] = 0;
    }

    rs_log_info("Browsing for '%s'.\n", stype);

    if (!(d.browser = avahi_service_browser_new(
                  d.client,
                  AVAHI_IF_UNSPEC,
                  AVAHI_PROTO_UNSPEC,
                  stype,
                  NULL,
                  0,
                  browse_reply,
                  &d))) {
        rs_log_crit("Failed to create service browser object: %s\n", avahi_strerror(avahi_client_errno(d.client)));
        goto finish;
    }

    /* Check whether the host file has been used recently */
    while (fd_last_used(d.fd, clip_time) <= MAX_IDLE_TIME) {

        /* Iterate the main loop for 5s */
        if (avahi_simple_poll_iterate(d.simple_poll, 5000) != 0) {
            rs_log_crit("Event loop exited abnormaly.\n");
            goto finish;
        }
    }

    /* Wer are idle */
    rs_log_info("Zeroconf daemon unused.\n");

    ret = 0;

finish:

    /* Cleanup */
    if (lock_fd >= 0) {
        generic_lock(lock_fd, 1, 0, 0);
        close(lock_fd);
    }

    if (d.fd >= 0)
        close(d.fd);

    while (d.hosts) {
        struct host *h = d.hosts;
        d.hosts = d.hosts->next;
        free_host(h);
    }

    if (d.client)
        avahi_client_free(d.client);

    if (d.simple_poll)
        avahi_simple_poll_free(d.simple_poll);

    rs_log_info("zeroconf daemon ended.\n");

    return ret;
}