void schedule(void (*f)(void*,void*,void*,void*),int nloops, void *a1, void *a2, void *a3, void *a4) { pool *p, *sub_pool; sched_t *s; if (scheds == NULL) { p = make_sub_pool(permanent_pool); pr_pool_tag(p, "Schedules Pool"); scheds = xaset_create(p, NULL); } else { p = scheds->pool; } sub_pool = make_sub_pool(p); pr_pool_tag(sub_pool, "schedule pool"); s = pcalloc(sub_pool, sizeof(sched_t)); s->pool = sub_pool; s->f = f; s->a1 = a1; s->a2 = a2; s->a3 = a3; s->a4 = a4; s->loops = nloops; xaset_insert(scheds, (xasetmember_t *) s); }
void schedule(void (*cb)(void *, void *, void *, void *), int nloops, void *arg1, void *arg2, void *arg3, void *arg4) { pool *p, *sub_pool; sched_t *s; if (cb == NULL || nloops < 0) { return; } if (scheds == NULL) { p = make_sub_pool(permanent_pool); pr_pool_tag(p, "Schedules Pool"); scheds = xaset_create(p, NULL); } else { p = scheds->pool; } sub_pool = make_sub_pool(p); pr_pool_tag(sub_pool, "schedule pool"); s = pcalloc(sub_pool, sizeof(sched_t)); s->pool = sub_pool; s->cb = cb; s->arg1 = arg1; s->arg2 = arg2; s->arg3 = arg3; s->arg4 = arg4; s->nloops = nloops; xaset_insert(scheds, (xasetmember_t *) s); }
pr_regex_t *pr_regexp_alloc(module *m) { pr_regex_t *pre = NULL; pool *re_pool = NULL; /* If no regex-tracking list has been allocated, create one. Register a * cleanup handler for this pool, to free up the data in the list. */ if (regexp_pool == NULL) { regexp_pool = make_sub_pool(permanent_pool); pr_pool_tag(regexp_pool, "Regexp Pool"); regexp_list = make_array(regexp_pool, 0, sizeof(pr_regex_t *)); } re_pool = pr_pool_create_sz(regexp_pool, 128); pr_pool_tag(re_pool, "regexp pool"); pre = pcalloc(re_pool, sizeof(pr_regex_t)); pre->regex_pool = re_pool; pre->m = m; /* Add this pointer to the array. */ *((pr_regex_t **) push_array(regexp_list)) = pre; return pre; }
int child_add(pid_t pid, int fd) { pool *p; pr_child_t *ch; /* If no child-tracking list has been allocated, create one. */ if (!child_pool) { child_pool = make_sub_pool(permanent_pool); pr_pool_tag(child_pool, "Child Pool"); } if (!child_list) child_list = xaset_create(make_sub_pool(child_pool), NULL); p = make_sub_pool(child_pool); pr_pool_tag(p, "child session pool"); ch = pcalloc(p, sizeof(pr_child_t)); ch->ch_pool = p; ch->ch_pid = pid; time(&ch->ch_when); ch->ch_pipefd = fd; ch->ch_dead = FALSE; xaset_insert(child_list, (xasetmember_t *) ch); child_listlen++; return 0; }
void init_pools(void) { if (permanent_pool == NULL) { permanent_pool = make_sub_pool(NULL); } pr_pool_tag(permanent_pool, "permanent_pool"); }
modret_t *pr_module_call(module *m, modret_t *(*func)(cmd_rec *), cmd_rec *cmd) { modret_t *res; module *prev_module = curr_module; if (m == NULL || func == NULL || cmd == NULL) { errno = EINVAL; return NULL; } if (!cmd->tmp_pool) { cmd->tmp_pool = make_sub_pool(cmd->pool); pr_pool_tag(cmd->tmp_pool, "Module call tmp_pool"); } curr_module = m; res = func(cmd); curr_module = prev_module; /* Note that we don't clear the pool here because the function may * return data which resides in this pool. */ return res; }
int vroot_fsio_stat(pr_fs_t *fs, const char *stat_path, struct stat *st) { int res, xerrno; char vpath[PR_TUNABLE_PATH_MAX + 1], *path = NULL; pool *tmp_pool = NULL; if (session.curr_phase == LOG_CMD || session.curr_phase == LOG_CMD_ERR || (session.sf_flags & SF_ABORT) || vroot_path_have_base() == FALSE) { /* NOTE: once stackable FS modules are supported, have this fall through * to the next module in the stack. */ return stat(stat_path, st); } tmp_pool = make_sub_pool(session.pool); pr_pool_tag(tmp_pool, "VRoot FSIO stat pool"); path = vroot_realpath(tmp_pool, stat_path, 0); if (vroot_path_lookup(NULL, vpath, sizeof(vpath)-1, path, 0, NULL) < 0) { xerrno = errno; destroy_pool(tmp_pool); errno = xerrno; return -1; } res = stat(vpath, st); xerrno = errno; destroy_pool(tmp_pool); errno = xerrno; return res; }
static void log_failure_event(const char *event_name, int flags) { int res; char *msg = NULL; size_t msg_len = 0; pool *p; p = make_sub_pool(log_failure_pool); pr_pool_tag(p, "FailureLog Message Pool"); res = log_failure_fmt_msg(p, log_failure_fmt, event_name, &msg, &msg_len, flags); if (res < 0) { pr_trace_msg(trace_channel, 2, "error formatting message: %s", strerror(errno)); } else { res = write(log_failure_fd, msg, msg_len); while (res < 0) { int xerrno = errno; if (xerrno == EINTR) { pr_signals_handle(); res = write(log_failure_fd, msg, msg_len); continue; } pr_trace_msg(trace_channel, 2, "error writing message to FailureLog: %s", strerror(xerrno)); break; } } destroy_pool(p); }
int proxy_db_init(pool *p) { const char *version; if (p == NULL) { errno = EINVAL; return -1; } if (db_pool != NULL) { return 0; } /* Check that the SQLite headers used match the version of the SQLite * library used. * * For now, we only log if there is a difference. */ version = sqlite3_libversion(); if (strcmp(version, SQLITE_VERSION) != 0) { (void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION, "compiled using SQLite version '%s' headers, but linked to " "SQLite version '%s' library", SQLITE_VERSION, version); } pr_trace_msg(trace_channel, 9, "using SQLite %s", version); db_pool = make_sub_pool(p); pr_pool_tag(db_pool, "Proxy Database Pool"); return 0; }
int pr_class_open(pool *p, const char *name) { pr_class_t *cls; pool *cls_pool; if (!p || !name) { errno = EINVAL; return -1; } /* Allocate a sub pool from the given pool, from which a new Class will * be allocated. */ cls_pool = make_sub_pool(p); pr_pool_tag(cls_pool, "<Class> Pool"); cls = pcalloc(cls_pool, sizeof(pr_class_t)); cls->cls_pool = cls_pool; cls->cls_name = pstrdup(cls->cls_pool, name); cls->cls_satisfy = PR_CLASS_SATISFY_ANY; /* Change the configuration context type. */ main_server->config_type = CONF_CLASS; curr_cls = cls; return 0; }
static int mcache_init(void) { const char *version; memcache_pool = make_sub_pool(permanent_pool); pr_pool_tag(memcache_pool, MOD_MEMCACHE_VERSION); memcache_server_lists = make_array(memcache_pool, 2, sizeof(memcached_server_st **)); memcache_init(); pr_event_register(&memcache_module, "core.restart", mcache_restart_ev, NULL); version = memcached_lib_version(); if (strcmp(version, LIBMEMCACHED_VERSION_STRING) != 0) { pr_log_pri(PR_LOG_INFO, MOD_MEMCACHE_VERSION ": compiled using libmemcached-%s headers, but linked to " "libmemcached-%s library", LIBMEMCACHED_VERSION_STRING, version); } else { pr_log_debug(DEBUG2, MOD_MEMCACHE_VERSION ": using libmemcached-%s", version); } return 0; }
static int dynmasq_init(void) { #if defined(PR_SHARED_MODULE) pr_event_register(&dynmasq_module, "core.module-unload", dynmasq_mod_unload_ev, NULL); #endif /* !PR_SHARED_MODULE */ pr_event_register(&dynmasq_module, "core.postparse", dynmasq_postparse_ev, NULL); pr_event_register(&dynmasq_module, "core.restart", dynmasq_restart_ev, NULL); #ifdef PR_USE_CTRLS if (pr_ctrls_register(&dynmasq_module, "dynmasq", "mod_dynmasq controls", dynmasq_handle_dynmasq) < 0) { pr_log_pri(PR_LOG_NOTICE, MOD_DYNMASQ_VERSION ": error registering 'dynmasq' control: %s", strerror(errno)); } else { register unsigned int i; dynmasq_act_pool = make_sub_pool(permanent_pool); pr_pool_tag(dynmasq_act_pool, "DynMasq Controls Pool"); for (i = 0; dynmasq_acttab[i].act_action; i++) { dynmasq_acttab[i].act_acl = palloc(dynmasq_act_pool, sizeof(ctrls_acl_t)); pr_ctrls_init_acl(dynmasq_acttab[i].act_acl); } } #endif /* PR_USE_CTRLS */ return 0; }
int pr_ctrls_add_arg(pr_ctrls_t *ctrl, char *ctrls_arg) { /* Sanity checks */ if (!ctrl || !ctrls_arg) { errno = EINVAL; return -1; } /* Make sure the pr_ctrls_t has a temporary pool, from which the args will * be allocated. */ if (!ctrl->ctrls_tmp_pool) { ctrl->ctrls_tmp_pool = make_sub_pool(ctrls_pool); pr_pool_tag(ctrl->ctrls_tmp_pool, "ctrls tmp pool"); } if (!ctrl->ctrls_cb_args) ctrl->ctrls_cb_args = make_array(ctrl->ctrls_tmp_pool, 0, sizeof(char *)); /* Add the given argument */ *((char **) push_array(ctrl->ctrls_cb_args)) = pstrdup(ctrl->ctrls_tmp_pool, ctrls_arg); return 0; }
int pr_ctrls_add_response(pr_ctrls_t *ctrl, char *fmt, ...) { char buf[PR_TUNABLE_BUFFER_SIZE] = {'\0'}; va_list resp; /* Sanity check */ if (!ctrl || !fmt) { errno = EINVAL; return -1; } /* Make sure the pr_ctrls_t has a temporary pool, from which the responses * will be allocated */ if (!ctrl->ctrls_tmp_pool) { ctrl->ctrls_tmp_pool = make_sub_pool(ctrls_pool); pr_pool_tag(ctrl->ctrls_tmp_pool, "ctrls tmp pool"); } if (!ctrl->ctrls_cb_resps) ctrl->ctrls_cb_resps = make_array(ctrl->ctrls_tmp_pool, 0, sizeof(char *)); /* Affix the message */ va_start(resp, fmt); vsnprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), fmt, resp); va_end(resp); buf[sizeof(buf) - 1] = '\0'; /* add the given response */ *((char **) push_array(ctrl->ctrls_cb_resps)) = pstrdup(ctrl->ctrls_tmp_pool, buf); return 0; }
int pr_ctrls_copy_args(pr_ctrls_t *src_ctrl, pr_ctrls_t *dst_ctrl) { /* Sanity checks */ if (!src_ctrl || !dst_ctrl) { errno = EINVAL; return -1; } /* If source ctrl has no ctrls_cb_args member, there's nothing to be * done. */ if (!src_ctrl->ctrls_cb_args) return 0; /* Make sure the pr_ctrls_t has a temporary pool, from which the args will * be allocated. */ if (!dst_ctrl->ctrls_tmp_pool) { dst_ctrl->ctrls_tmp_pool = make_sub_pool(ctrls_pool); pr_pool_tag(dst_ctrl->ctrls_tmp_pool, "ctrls tmp pool"); } /* Overwrite any existing dst_ctrl->ctrls_cb_args. This is OK, as * the ctrl will be reset (cleared) once it has been processed. */ dst_ctrl->ctrls_cb_args = copy_array(dst_ctrl->ctrls_tmp_pool, src_ctrl->ctrls_cb_args); return 0; }
static void create_main_server(void) { pool *main_pool; main_pool = make_sub_pool(permanent_pool); pr_pool_tag(main_pool, "testsuite#main_server pool"); server_list = xaset_create(main_pool, NULL); main_server = (server_rec *) pcalloc(main_pool, sizeof(server_rec)); xaset_insert(server_list, (xasetmember_t *) main_server); main_server->pool = main_pool; main_server->conf = xaset_create(main_pool, NULL); main_server->set = server_list; main_server->sid = 1; main_server->notes = pr_table_nalloc(main_pool, 0, 8); /* TCP KeepAlive is enabled by default, with the system defaults. */ main_server->tcp_keepalive = palloc(main_server->pool, sizeof(struct tcp_keepalive)); main_server->tcp_keepalive->keepalive_enabled = TRUE; main_server->tcp_keepalive->keepalive_idle = -1; main_server->tcp_keepalive->keepalive_count = -1; main_server->tcp_keepalive->keepalive_intvl = -1; main_server->ServerName = "Test Server"; main_server->ServerPort = 21; }
struct proxy_session *proxy_session_alloc(pool *p) { pool *sess_pool; struct proxy_session *proxy_sess; sess_pool = make_sub_pool(p); pr_pool_tag(sess_pool, "Proxy Session pool"); proxy_sess = pcalloc(sess_pool, sizeof(struct proxy_session)); proxy_sess->pool = sess_pool; /* This will be configured by the ProxySourceAddress directive, if present. */ proxy_sess->src_addr = NULL; /* This will be configured by the ProxyDataTransferPolicy directive, if * present. */ proxy_sess->dataxfer_policy = PROXY_SESS_DATA_TRANSFER_POLICY_DEFAULT; /* Fill in the defaults for the session members. */ proxy_sess->connect_timeout = -1; proxy_sess->connect_timerno = -1; proxy_sess->linger_timeout = -1; return proxy_sess; }
static void dynmasq_restart_ev(const void *event_data, void *user_data) { #ifdef PR_USE_CTRLS register unsigned int i; #endif /* PR_USE_CTRLS */ if (dynmasq_timer_id != -1) { pr_timer_remove(dynmasq_timer_id, &dynmasq_module); dynmasq_timer_id = -1; } #ifdef PR_USE_CTRLS if (dynmasq_act_pool) { destroy_pool(dynmasq_act_pool); dynmasq_act_pool = NULL; } dynmasq_act_pool = make_sub_pool(permanent_pool); pr_pool_tag(dynmasq_act_pool, "DynMasq Controls Pool"); /* Re-create the controls ACLs. */ for (i = 0; dynmasq_acttab[i].act_action; i++) { dynmasq_acttab[i].act_acl = palloc(dynmasq_act_pool, sizeof(ctrls_acl_t)); pr_ctrls_init_acl(dynmasq_acttab[i].act_acl); } #endif /* PR_USE_CTRLS */ }
int pr_parser_prepare(pool *p, xaset_t **parsed_servers) { if (p == NULL) { if (parser_pool == NULL) { parser_pool = make_sub_pool(permanent_pool); pr_pool_tag(parser_pool, "Parser Pool"); } p = parser_pool; } if (parsed_servers == NULL) { parser_server_list = &server_list; } else { parser_server_list = parsed_servers; } parser_servstack = make_array(p, 1, sizeof(server_rec *)); parser_curr_server = (server_rec **) push_array(parser_servstack); *parser_curr_server = main_server; parser_confstack = make_array(p, 10, sizeof(config_rec *)); parser_curr_config = (config_rec **) push_array(parser_confstack); *parser_curr_config = NULL; return 0; }
server_rec *pr_parser_server_ctxt_open(const char *addrstr) { server_rec *s; pool *p; p = make_sub_pool(permanent_pool); pr_pool_tag(p, "<VirtualHost> Pool"); s = (server_rec *) pcalloc(p, sizeof(server_rec)); s->pool = p; s->config_type = CONF_VIRTUAL; s->sid = ++parser_sid; s->notes = pr_table_nalloc(p, 0, 8); /* TCP KeepAlive is enabled by default, with the system defaults. */ s->tcp_keepalive = palloc(s->pool, sizeof(struct tcp_keepalive)); s->tcp_keepalive->keepalive_enabled = TRUE; s->tcp_keepalive->keepalive_idle = -1; s->tcp_keepalive->keepalive_count = -1; s->tcp_keepalive->keepalive_intvl = -1; /* Have to make sure it ends up on the end of the chain, otherwise * main_server becomes useless. */ xaset_insert_end(*parser_server_list, (xasetmember_t *) s); s->set = *parser_server_list; if (addrstr) { s->ServerAddress = pstrdup(s->pool, addrstr); } /* Default server port */ s->ServerPort = pr_inet_getservport(s->pool, "ftp", "tcp"); (void) pr_parser_server_ctxt_push(s); return s; }
pr_netio_t *pr_alloc_netio2(pool *parent_pool, module *owner) { pr_netio_t *netio = NULL; pool *netio_pool = NULL; if (parent_pool == NULL) { errno = EINVAL; return NULL; } netio_pool = make_sub_pool(parent_pool); /* If this is the daemon process, we are allocating a sub-pool from the * permanent_pool. You might wonder why the daemon process needs netio * objects. It doesn't, really -- but it's for use by all of the session * processes that will be forked. They will be able to reuse the memory * already allocated for the main ctrl/data/other netios, as is. * * This being the case, we should label the sub-pool accordingly. */ if (mpid == getpid()) { pr_pool_tag(netio_pool, "Shared Netio Pool"); } else { pr_pool_tag(netio_pool, "netio pool"); } netio = pcalloc(netio_pool, sizeof(pr_netio_t)); netio->pool = netio_pool; netio->owner = owner; if (owner != NULL) { netio->owner_name = pstrdup(netio_pool, owner->name); } /* Set the default NetIO handlers to the core handlers. */ netio->abort = core_netio_abort_cb; netio->close = core_netio_close_cb; netio->open = core_netio_open_cb; netio->poll = core_netio_poll_cb; netio->postopen = core_netio_postopen_cb; netio->read = core_netio_read_cb; netio->reopen = core_netio_reopen_cb; netio->shutdown = core_netio_shutdown_cb; netio->write = core_netio_write_cb; return netio; }
static void counter_restart_ev(const void *event_data, void *user_data) { if (counter_pool) { destroy_pool(counter_pool); } counter_pool = make_sub_pool(permanent_pool); pr_pool_tag(counter_pool, MOD_COUNTER_VERSION); }
int sftp_service_init(void) { if (service_pool == NULL) { service_pool = make_sub_pool(sftp_pool); pr_pool_tag(service_pool, "Service Pool"); } return 0; }
static int dso_init(void) { #ifdef PR_USE_CTRLS register unsigned int i = 0; #endif /* PR_USE_CTRLS */ /* Allocate the pool for this module's use. */ dso_pool = make_sub_pool(permanent_pool); pr_pool_tag(dso_pool, MOD_DSO_VERSION); lt_dlpreload_default(lt_preloaded_symbols); /* Initialize libltdl. */ if (lt_dlinit() < 0) { pr_log_pri(PR_LOG_ERR, MOD_DSO_VERSION ": error initializing libltdl: %s", lt_dlerror()); return -1; } /* Explicitly set the search path used for opening modules. */ if (lt_dlsetsearchpath(dso_module_path) < 0) { pr_log_pri(PR_LOG_ERR, MOD_DSO_VERSION ": error setting module path: %s", lt_dlerror()); return -1; } #ifdef PR_USE_CTRLS /* Register ctrls handlers. */ for (i = 0; dso_acttab[i].act_action; i++) { pool *sub_pool = make_sub_pool(dso_pool); /* Allocate and initialize the ACL for this control. */ dso_acttab[i].act_acl = pcalloc(sub_pool, sizeof(ctrls_acl_t)); dso_acttab[i].act_acl->acl_pool = sub_pool; pr_ctrls_init_acl(dso_acttab[i].act_acl); if (pr_ctrls_register(&dso_module, dso_acttab[i].act_action, dso_acttab[i].act_desc, dso_acttab[i].act_cb) < 0) pr_log_pri(PR_LOG_INFO, MOD_DSO_VERSION ": error registering '%s' control: %s", dso_acttab[i].act_action, strerror(errno)); } #endif /* PR_USE_CTRLS */ /* Ideally, we'd call register a listener for the 'core.exit' event * and call lt_dlexit() there, politely freeing up any resources allocated * by the ltdl library. However, it's possible that other modules, later in * the dispatch cycles, may need to use pointers to memory in shared modules * that would become invalid by such finalization. So we skip it, for now. * * If there was a way to schedule this handler, to happen after all other * exit handlers, that'd be best. */ pr_event_register(&dso_module, "core.restart", dso_restart_ev, NULL); return 0; }
static ctrls_action_t *ctrls_action_new(void) { ctrls_action_t *act = NULL; pool *sub_pool = make_sub_pool(ctrls_pool); pr_pool_tag(sub_pool, "ctrls action subpool"); act = pcalloc(sub_pool, sizeof(ctrls_action_t)); act->pool = sub_pool; return act; }
static void log_failure_restart_ev(const void *event_data, void *user_data) { destroy_pool(log_failure_pool); log_failure_fields = NULL; log_failure_pool = make_sub_pool(permanent_pool); pr_pool_tag(log_failure_pool, MOD_LOG_FAILURE_VERSION); if (log_failure_mkfields(log_failure_pool) < 0) { pr_trace_msg(trace_channel, 3, "error creating fields table: %s", strerror(errno)); } }
int pr_ipbind_create(server_rec *server, pr_netaddr_t *addr, unsigned int port) { pr_ipbind_t *ipbind = NULL; register unsigned int i = 0; if (server == NULL|| addr == NULL) { errno = EINVAL; return -1; } i = ipbind_hash_addr(addr); /* Make sure the address is not already in use */ for (ipbind = ipbind_table[i]; ipbind; ipbind = ipbind->ib_next) { if (pr_netaddr_cmp(ipbind->ib_addr, addr) == 0 && ipbind->ib_port == port) { /* An ipbind already exists for this IP address */ pr_log_pri(PR_LOG_WARNING, "notice: '%s' (%s:%u) already bound to '%s'", server->ServerName, pr_netaddr_get_ipstr(addr), port, ipbind->ib_server->ServerName); errno = EADDRINUSE; return -1; } } if (!binding_pool) { binding_pool = make_sub_pool(permanent_pool); pr_pool_tag(binding_pool, "Bindings Pool"); } ipbind = pcalloc(server->pool, sizeof(pr_ipbind_t)); ipbind->ib_server = server; ipbind->ib_addr = addr; ipbind->ib_port = port; ipbind->ib_namebinds = NULL; ipbind->ib_isdefault = FALSE; ipbind->ib_islocalhost = FALSE; ipbind->ib_isactive = FALSE; pr_trace_msg(trace_channel, 8, "created IP binding for %s#%u, server %p", pr_netaddr_get_ipstr(ipbind->ib_addr), ipbind->ib_port, ipbind->ib_server); /* Add the ipbind to the table. */ if (ipbind_table[i]) { ipbind->ib_next = ipbind_table[i]; } ipbind_table[i] = ipbind; return 0; }
int vroot_fsio_readlink(pr_fs_t *fs, const char *readlink_path, char *buf, size_t bufsz) { int res, xerrno; char vpath[PR_TUNABLE_PATH_MAX + 1], *path = NULL, *alias_path = NULL; pool *tmp_pool = NULL; if (session.curr_phase == LOG_CMD || session.curr_phase == LOG_CMD_ERR || (session.sf_flags & SF_ABORT) || vroot_path_have_base() == FALSE) { /* NOTE: once stackable FS modules are supported, have this fall through * to the next module in the stack. */ return readlink(readlink_path, buf, bufsz); } /* In order to find any VRootAlias paths, we need to use the full path. * However, if we do NOT find any VRootAlias, then we do NOT want to use * the full path. */ tmp_pool = make_sub_pool(session.pool); pr_pool_tag(tmp_pool, "VRoot FSIO readlink pool"); path = vroot_realpath(tmp_pool, readlink_path, VROOT_REALPATH_FL_ABS_PATH); if (vroot_path_lookup(tmp_pool, vpath, sizeof(vpath)-1, path, 0, &alias_path) < 0) { xerrno = errno; destroy_pool(tmp_pool); errno = xerrno; return -1; } if (alias_path == NULL) { if (vroot_path_lookup(NULL, vpath, sizeof(vpath)-1, readlink_path, 0, NULL) < 0) { xerrno = errno; destroy_pool(tmp_pool); errno = xerrno; return -1; } } res = readlink(vpath, buf, bufsz); xerrno = errno; destroy_pool(tmp_pool); errno = xerrno; return res; }
int var_init(void) { if (!var_pool) { var_pool = make_sub_pool(permanent_pool); pr_pool_tag(var_pool, "Variables Pool"); } if (!var_tab) var_tab = pr_table_alloc(var_pool, 0); return 0; }
/* Copy a connection structure, also creates a sub pool for the new * connection. */ conn_t *pr_inet_copy_conn(pool *p, conn_t *c) { conn_t *res = NULL; pool *sub_pool = NULL; if (p == NULL || c == NULL) { errno = EINVAL; return NULL; } sub_pool = make_sub_pool(p); pr_pool_tag(sub_pool, "inet_copy_conn pool"); res = (conn_t *) pcalloc(sub_pool, sizeof(conn_t)); memcpy(res, c, sizeof(conn_t)); res->pool = sub_pool; res->instrm = res->outstrm = NULL; if (c->local_addr) { res->local_addr = pr_netaddr_alloc(res->pool); if (pr_netaddr_set_family(res->local_addr, pr_netaddr_get_family(c->local_addr)) < 0) { destroy_pool(res->pool); return NULL; } pr_netaddr_set_sockaddr(res->local_addr, pr_netaddr_get_sockaddr(c->local_addr)); } if (c->remote_addr) { res->remote_addr = pr_netaddr_alloc(res->pool); if (pr_netaddr_set_family(res->remote_addr, pr_netaddr_get_family(c->remote_addr)) < 0) { destroy_pool(res->pool); return NULL; } pr_netaddr_set_sockaddr(res->remote_addr, pr_netaddr_get_sockaddr(c->remote_addr)); } if (c->remote_name) { res->remote_name = pstrdup(res->pool, c->remote_name); } register_cleanup(res->pool, (void *) res, conn_cleanup_cb, conn_cleanup_cb); return res; }