static void worker_gethostbyname(struct job_gethostbyname *job) { #if HAS_GETHOSTBYNAME_R == 5 int h_errno; job->ptr = gethostbyname_r(job->name, &job->entry, job->buffer, NETDB_BUFFER_SIZE, &h_errno); #elif HAS_GETHOSTBYNAME_R == 6 int h_errno; if (gethostbyname_r(job->name, &job->entry, job->buffer, NETDB_BUFFER_SIZE, &(job->ptr), &h_errno) != 0) job->ptr = NULL; #else job->ptr = gethostbyname(job->name); if (job->ptr) { job->ptr = hostent_dup(job->ptr); if (job->ptr) { job->entry = *job->ptr; } } #endif }
int gethostbyaddr_with_ares(const void *addr, int addrlen, int af, struct hostent *ret_h, char *buf, size_t &buflen, struct hostent **result, int *h_errnop) { int err = 0; if (!h_errnop) h_errnop = &err; cares_async_context ctx; ctx.called = false; ctx.errnop = h_errnop; ctx.ret = 0; ctx.result = result; ctx.buf = buf; ctx.buflen = &buflen; ares_channel c; ares_init(&c); ares_gethostbyaddr(c, addr, addrlen, af, [](void * arg, int status, int timeouts, struct hostent *hostent) { cares_async_context *ctx = (cares_async_context *)arg; ctx->called = true; if (status != ARES_SUCCESS) { *ctx->result = nullptr; switch (status) { case ARES_ENODATA: *ctx->errnop = NO_DATA; break; case ARES_EBADNAME: *ctx->errnop = NO_RECOVERY; break; case ARES_ENOTFOUND: default: *ctx->errnop = HOST_NOT_FOUND; break; } ctx->ret = -1; return ; } if (!hostent_dup(hostent, *ctx->result, ctx->buf, *ctx->buflen)) { *ctx->result = nullptr; *ctx->errnop = ENOEXEC; // 奇怪的错误码. ctx->ret = -1; return ; } *ctx->errnop = 0; ctx->ret = 0; }, &ctx); fd_set readers, writers; FD_ZERO(&readers); FD_ZERO(&writers); int nfds = ares_fds(c, &readers, &writers); if (nfds) { struct timeval tv, *tvp; tvp = ares_timeout(c, NULL, &tv); int count = select(nfds, &readers, &writers, NULL, tvp); if (count > 0) { ares_process(c, &readers, &writers); } } if (ctx.called) return ctx.ret; // No yet invoke callback. *result = nullptr; *h_errnop = HOST_NOT_FOUND; // TODO return -1; }
static exports get_exportlist(void) { static exports elist = NULL; struct exportnode *e, *ne; struct groupnode *g, *ng, *c, **cp; nfs_export *exp; int i; static unsigned int ecounter; unsigned int acounter; acounter = auth_reload(); if (elist && acounter == ecounter) return elist; ecounter = acounter; for (e = elist; e != NULL; e = ne) { ne = e->ex_next; for (g = e->ex_groups; g != NULL; g = ng) { ng = g->gr_next; xfree(g->gr_name); xfree(g); } xfree(e->ex_dir); xfree(e); } elist = NULL; for (i = 0; i < MCL_MAXTYPES; i++) { for (exp = exportlist[i].p_head; exp; exp = exp->m_next) { for (e = elist; e != NULL; e = e->ex_next) { if (!strcmp(exp->m_export.e_path, e->ex_dir)) break; } if (!e) { e = (struct exportnode *) xmalloc(sizeof(*e)); e->ex_next = elist; e->ex_groups = NULL; e->ex_dir = xstrdup(exp->m_export.e_path); elist = e; } /* We need to check if we should remove previous ones. */ if (i == MCL_ANONYMOUS && e->ex_groups) { for (g = e->ex_groups; g; g = ng) { ng = g->gr_next; xfree(g->gr_name); xfree(g); } e->ex_groups = NULL; continue; } if (i != MCL_FQDN && e->ex_groups) { struct hostent *hp; cp = &e->ex_groups; while ((c = *cp) != NULL) { if (client_gettype (c->gr_name) == MCL_FQDN && (hp = gethostbyname(c->gr_name))) { hp = hostent_dup (hp); if (client_check(exp->m_client, hp)) { *cp = c->gr_next; xfree(c->gr_name); xfree(c); xfree (hp); continue; } xfree (hp); } cp = &(c->gr_next); } } if (exp->m_export.e_hostname [0] != '\0') { for (g = e->ex_groups; g; g = g->gr_next) if (strcmp (exp->m_export.e_hostname, g->gr_name) == 0) break; if (g) continue; g = (struct groupnode *) xmalloc(sizeof(*g)); g->gr_name = xstrdup(exp->m_export.e_hostname); g->gr_next = e->ex_groups; e->ex_groups = g; } } } return elist; }