/* The difference between this function, and pr_cmd_alloc(), is that this * allocates the cmd_rec directly from the given pool, whereas pr_cmd_alloc() * will allocate a subpool from the given pool, and allocate its cmd_rec * from the subpool. This means that pr_cmd_alloc()'s cmd_rec's can be * subsequently destroyed easily; this function's cmd_rec's will be destroyed * when the given pool is destroyed. */ static cmd_rec *make_cmd(pool *cp, int argc, ...) { va_list args; cmd_rec *c; pool *sub_pool; c = pcalloc(cp, sizeof(cmd_rec)); c->argc = argc; c->stash_index = -1; if (argc) { register unsigned int i; c->argv = pcalloc(cp, sizeof(void *) * (argc + 1)); va_start(args, argc); for (i = 0; i < argc; i++) { c->argv[i] = (void *) va_arg(args, char *); } va_end(args); c->argv[argc] = NULL; } /* Make sure we provide pool and tmp_pool for the consumers. */ sub_pool = make_sub_pool(cp); c->pool = c->tmp_pool = sub_pool; return c; }
pr_buffer_t *pr_netio_buffer_alloc(pr_netio_stream_t *nstrm) { size_t bufsz; pr_buffer_t *pbuf = NULL; if (nstrm == NULL) { errno = EINVAL; return NULL; } pbuf = pcalloc(nstrm->strm_pool, sizeof(pr_buffer_t)); /* Allocate a buffer. */ bufsz = pr_config_get_server_xfer_bufsz(nstrm->strm_mode); pbuf->buf = pcalloc(nstrm->strm_pool, bufsz); pbuf->buflen = bufsz; /* Position the offset at the start of the buffer, and set the * remaining bytes value accordingly. */ pbuf->current = pbuf->buf; pbuf->remaining = bufsz; /* Add this buffer to the given stream. */ nstrm->strm_buf = pbuf; return pbuf; }
PCPOINT * pc_point_make(const PCSCHEMA *s) { size_t sz; PCPOINT *pt; if ( ! s ) { pcerror("null schema passed into pc_point_make"); return NULL; } /* Width of the data area */ sz = s->size; if ( ! sz ) { pcerror("invalid size calculation in pc_point_make"); return NULL; } /* Make our own data area */ pt = pcalloc(sizeof(PCPOINT)); pt->data = pcalloc(sz); /* Set up basic info */ pt->schema = s; pt->readonly = PC_FALSE; return pt; };
PCPOINT * pc_point_from_double_array(const PCSCHEMA *s, double *array, uint32_t nelems) { int i; PCPOINT *pt; if ( ! s ) { pcerror("null schema passed into pc_point_from_double_array"); return NULL; } if ( s->ndims != nelems ) { pcerror("number of elements in schema and array differ in pc_point_from_double_array"); return NULL; } /* Reference the external data */ pt = pcalloc(sizeof(PCPOINT)); pt->data = pcalloc(s->size); pt->schema = s; pt->readonly = PC_FALSE; for ( i = 0; i < nelems; i++ ) { if ( PC_FAILURE == pc_point_set_double_by_index(pt, i, array[i]) ) { pcerror("failed to write value into dimension %d in pc_point_from_double_array", i); return NULL; } } return pt; }
char *pr_utf8_encode(pool *p, const char *in, size_t inlen, size_t *outlen) { #ifdef HAVE_ICONV_H size_t inbuflen, outbuflen; char *inbuf, outbuf[PR_TUNABLE_PATH_MAX*2], *res; if (!p || !in || !outlen) { errno = EINVAL; return NULL; } if (encode_conv == (iconv_t) -1) { errno = EPERM; return NULL; } inbuf = pcalloc(p, inlen); memcpy(inbuf, in, inlen); inbuflen = inlen; outbuflen = sizeof(outbuf); if (utf8_convert(encode_conv, inbuf, &inbuflen, outbuf, &outbuflen) < 0) return NULL; *outlen = sizeof(outbuf) - outbuflen; res = pcalloc(p, *outlen); memcpy(res, outbuf, *outlen); return res; #else pr_trace_msg("utf8", 1, "missing iconv support, no UTF8 encoding possible"); return pstrdup(p, in); #endif /* !HAVE_ICONV_H */ }
PCPATCH_DIMENSIONAL * pc_patch_dimensional_compress(const PCPATCH_DIMENSIONAL *pdl, PCDIMSTATS *pds) { int i; int ndims = pdl->schema->ndims; PCPATCH_DIMENSIONAL *pdl_compressed; assert(pdl); assert(pdl->schema); if ( ! pds ) pds = pc_dimstats_make(pdl->schema); /* Still sampling, update stats */ if ( pds->total_points < PCDIMSTATS_MIN_SAMPLE ) pc_dimstats_update(pds, pdl); pdl_compressed = pcalloc(sizeof(PCPATCH_DIMENSIONAL)); memcpy(pdl_compressed, pdl, sizeof(PCPATCH_DIMENSIONAL)); pdl_compressed->bytes = pcalloc(ndims*sizeof(PCBYTES)); /* Compress each dimension as dictated by stats */ for ( i = 0; i < ndims; i++ ) { pdl_compressed->bytes[i] = pc_bytes_encode(pdl->bytes[i], pds->stats[i].recommended_compression); } return pdl_compressed; }
/* * _build_data: both cmd_select and cmd_procedure potentially * return data to mod_sql; this function builds a modret to return * that data. This is Postgres specific; other backends may choose * to do things differently. */ static modret_t *_build_data(cmd_rec *cmd, db_conn_t *conn) { PGresult *result = NULL; sql_data_t *sd = NULL; char **data = NULL; int index = 0; int field = 0; int row =0; if (!conn) return PR_ERROR_MSG(cmd, MOD_SQL_POSTGRES_VERSION, "badly formed request"); result = conn->result; sd = (sql_data_t *) pcalloc(cmd->tmp_pool, sizeof(sql_data_t)); sd->rnum = (unsigned long) PQntuples(result); sd->fnum = (unsigned long) PQnfields(result); data = (char **) pcalloc(cmd->tmp_pool, sizeof(char *) * ((sd->rnum * sd->fnum) + 1)); for (row = 0; row < sd->rnum; row++) { for (field = 0; field < sd->fnum; field++) { data[index++] = pstrdup(cmd->tmp_pool, PQgetvalue(result, row, field)); } } data[index] = NULL; sd->data = data; return mod_create_data( cmd, (void *) sd ); }
void *new_obj(pool_t *mpool, size_t sz) { pool_t *mp = mpool; obj_t *ob = NULL; if (mp == NULL) { mp = pool_create(G_MPOOL_SIZE); if (mp == NULL) { return NULL; } ob = (obj_t *)pcalloc(mp, sz); if (ob == NULL) { pool_destroy(mp); return NULL; } ob->new_mp_flag = 1; } else { ob = pcalloc(mp, sz); if (ob == NULL) { return NULL; } ob->new_mp_flag = 0; } ob->mpool = mp; return ob; }
int parse_cgi(epoll_cgi_t *cgi) { list_buffer *cgi_data, *send; buffer *b; char *p; int count; buffer *header, *out, *tmp; cgi_data = cgi->cgi_data; if(cgi_data == NULL || cgi_data->b == NULL || cgi_data->b->ptr == NULL || cgi_data->b->size == 0) return 0; b = cgi_data->b; send = (list_buffer *) pcalloc(cgi->con->p, sizeof(list_buffer)); header = (buffer *) pcalloc(cgi->con->p, sizeof(buffer)); cgi->con->out->status_code = HTTP_OK; p = strstr(b->ptr,"\n\n"); if(p != NULL && (p-b->ptr) < b->size) { buffer_n_to_lower(b, (p-b->ptr)+1); header->ptr = b->ptr; header->size = (p-b->ptr) + 2; tmp = (buffer *) pcalloc(cgi->con->p, sizeof(buffer)); buffer_find_str(header, tmp, "content-type:"); if(tmp->ptr == NULL) { send_bad_gateway(cgi->con->fd); return 1; } p = tmp->ptr + tmp->size; while(*p == ' ') p++; tmp->ptr = p; p = strchr(p, '\n'); count = p - tmp->ptr ; if(*(p-1) != '\r' ) count++; tmp->size = count; cgi->con->out->content_type = buffer_create_size(cgi->con->p, count); cgi->con->out->content_type->size = count; strncpy(cgi->con->out->content_type->ptr, tmp->ptr, count -1); cgi->con->out->content_type->ptr[count-1] = 0; out = (buffer *)pcalloc(cgi->con->p, sizeof(buffer)); out->ptr = header->ptr + header->size; out->size = b->size - header->size; send->b = out; send->next = cgi_data->next; cgi->out = send; } }
static bytebuffer_t * bytebuffer_new(void) { bytebuffer_t *bb = pcalloc(sizeof(bytebuffer_t)); bb->sz = 1024; bb->buf = pcalloc(bb->sz*sizeof(uint8_t)); bb->ptr = bb->buf; }
PCBITMAP * pc_bitmap_new(uint32_t npoints) { PCBITMAP *map = pcalloc(sizeof(PCBITMAP)); map->map = pcalloc(sizeof(uint8_t)*npoints); map->npoints = npoints; map->nset = 0; return map; }
PCPOINTLIST * pc_pointlist_make(uint32_t npoints) { PCPOINTLIST *pl = pcalloc(sizeof(PCPOINTLIST)); pl->points = pcalloc(sizeof(PCPOINT*) * npoints); pl->maxpoints = npoints; pl->npoints = 0; pl->mem = NULL; return pl; }
PCPATCH_DIMENSIONAL * pc_patch_dimensional_clone(const PCPATCH_DIMENSIONAL *patch) { PCPATCH_DIMENSIONAL *pdl = pcalloc(sizeof(PCPATCH_DIMENSIONAL)); memcpy(pdl, patch, sizeof(PCPATCH_DIMENSIONAL)); pdl->bytes = pcalloc(patch->schema->ndims * sizeof(PCBYTES)); pdl->npoints = 0; pdl->stats = NULL; return pdl; }
PCPOINTLIST * pc_pointlist_make(uint32_t npoints) { PCPOINTLIST *pl = pcalloc(sizeof(PCPOINTLIST)); pl->points = pcalloc(sizeof(PCPOINT*) * npoints); pl->maxpoints = npoints; pl->npoints = 0; pl->readonly = PC_FALSE; return pl; }
static PCSCHEMA* pc_schema_new(uint32_t ndims) { PCSCHEMA *pcs = pcalloc(sizeof(PCSCHEMA)); pcs->dims = pcalloc(sizeof(PCDIMENSION*) * ndims); pcs->namehash = create_string_hashtable(); pcs->ndims = ndims; pcs->x_position = -1; pcs->y_position = -1; return pcs; }
char *pr_encode_str(pool *p, const char *in, size_t inlen, size_t *outlen) { #ifdef HAVE_ICONV size_t inbuflen, outbuflen, outbufsz; char *inbuf, outbuf[PR_TUNABLE_PATH_MAX*2], *res; if (p == NULL || in == NULL || outlen == NULL) { errno = EINVAL; return NULL; } /* If the local charset matches the remote charset, then there's no point * in converting; the charsets are the same. Indeed, on some libiconv * implementations, attempting to convert between the same charsets results * in a tightly spinning CPU (see Bug#3272). */ if (local_charset != NULL && encoding != NULL && strcasecmp(local_charset, encoding) == 0) { return pstrdup(p, in); } if (encode_conv == (iconv_t) -1) { pr_trace_msg(trace_channel, 1, "invalid encoding conversion handle, " "unable to encode string"); return pstrdup(p, in); } inbuf = pcalloc(p, inlen); memcpy(inbuf, in, inlen); inbuflen = inlen; outbuflen = sizeof(outbuf); if (str_convert(encode_conv, inbuf, &inbuflen, outbuf, &outbuflen) < 0) return NULL; *outlen = sizeof(outbuf) - outbuflen; /* We allocate one byte more, for a terminating NUL. */ outbufsz = sizeof(outbuf) - outbuflen + 1; res = pcalloc(p, outbufsz); memcpy(res, outbuf, *outlen); return res; #else pr_trace_msg(trace_channel, 1, "missing iconv support, no %s encoding possible", encoding); return pstrdup(p, in); #endif /* !HAVE_ICONV */ }
void run_accept(struct server* server) { static int one = 1; struct timeval timeout; timeout.tv_sec = 60; timeout.tv_usec = 0; struct pollfd spfd; spfd.events = POLLIN; spfd.revents = 0; spfd.fd = server->fd; while (1) { struct mempool* pool = mempool_new(); struct connection* conn = pcalloc(pool, sizeof(struct connection)); conn->pool = pool; conn->addrlen = sizeof(struct sockaddr_in6); conn->managed_conn = pcalloc(conn->pool, sizeof(struct netmgr_connection)); conn->managed_conn->pool = conn->pool; conn->managed_conn->extra = conn; conn->compression_state = -1; conn->server = server; buffer_init(&conn->managed_conn->read_buffer, conn->pool); buffer_init(&conn->managed_conn->write_buffer, conn->pool); if (poll(&spfd, 1, -1) < 0) { printf("Error while polling server: %s\n", strerror(errno)); pfree(pool); continue; } if ((spfd.revents ^ POLLIN) != 0) { printf("Error after polling server: %i (poll revents)!\n", spfd.revents); pfree(pool); break; } spfd.revents = 0; int fd = accept(server->fd, (struct sockaddr*) &conn->addr, &conn->addrlen); if (fd < 0) { if (errno == EAGAIN) continue; printf("Error while accepting client: %s\n", strerror(errno)); pfree(pool); continue; } conn->managed_conn->fd = fd; if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, sizeof(timeout))) printf("Setting recv timeout failed! %s\n", strerror(errno)); if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, sizeof(timeout))) printf("Setting send timeout failed! %s\n", strerror(errno)); if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void *) &one, sizeof(one))) printf("Setting TCP_NODELAY failed! %s\n", strerror(errno)); if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK) < 0) { printf("Setting O_NONBLOCK failed! %s, this error cannot be recovered, closing client.\n", strerror(errno)); close(fd); continue; } queue_push(server->prepared_connections, conn); } pthread_cancel (pthread_self()); }
PCPATCH * pc_patch_uncompressed_from_wkb(const PCSCHEMA *s, const uint8_t *wkb, size_t wkbsize) { /* byte: endianness (1 = NDR, 0 = XDR) uint32: pcid (key to POINTCLOUD_SCHEMAS) uint32: compression (0 = no compression, 1 = dimensional, 2 = lazperf) uint32: npoints pcpoint[]: data (interpret relative to pcid) */ static size_t hdrsz = 1+4+4+4; /* endian + pcid + compression + npoints */ PCPATCH_UNCOMPRESSED *patch; uint8_t *data; uint8_t swap_endian = (wkb[0] != machine_endian()); uint32_t npoints; if ( wkb_get_compression(wkb) != PC_NONE ) { pcerror("%s: call with wkb that is not uncompressed", __func__); return NULL; } npoints = wkb_get_npoints(wkb); if ( (wkbsize - hdrsz) != (s->size * npoints) ) { pcerror("%s: wkb size and expected data size do not match", __func__); return NULL; } if ( swap_endian ) { data = uncompressed_bytes_flip_endian(wkb+hdrsz, s, npoints); } else { data = pcalloc(npoints * s->size); memcpy(data, wkb+hdrsz, npoints*s->size); } patch = pcalloc(sizeof(PCPATCH_UNCOMPRESSED)); patch->type = PC_NONE; patch->readonly = PC_FALSE; patch->schema = s; patch->npoints = npoints; patch->maxpoints = npoints; patch->datasize = (wkbsize - hdrsz); patch->data = data; patch->stats = NULL; return (PCPATCH*)patch; }
static PCPATCH * pc_patch_dimensional_deserialize(const SERIALIZED_PATCH *serpatch, const PCSCHEMA *schema) { // typedef struct // { // uint32_t size; // uint32_t pcid; // uint32_t compression; // uint32_t npoints; // double xmin, xmax, ymin, ymax; // data: // pcpoint[3] pcstats(min, max, avg) // pcbytes[ndims]; // } // SERIALIZED_PATCH; PCPATCH_DIMENSIONAL *patch; int i; const uint8_t *buf; int ndims = schema->ndims; int npoints = serpatch->npoints; size_t stats_size = pc_stats_size(schema); // 3 pcpoints worth of stats /* Reference the external data */ patch = pcalloc(sizeof(PCPATCH_DIMENSIONAL)); /* Set up basic info */ patch->type = serpatch->compression; patch->schema = schema; patch->readonly = true; patch->npoints = npoints; patch->bounds = serpatch->bounds; /* Point into the stats area */ patch->stats = pc_patch_stats_deserialize(schema, serpatch->data); /* Set up dimensions */ patch->bytes = pcalloc(ndims * sizeof(PCBYTES)); buf = serpatch->data + stats_size; for ( i = 0; i < ndims; i++ ) { PCBYTES *pcb = &(patch->bytes[i]); PCDIMENSION *dim = schema->dims[i]; pc_bytes_deserialize(buf, dim, pcb, true /*readonly*/, false /*flipendian*/); pcb->npoints = npoints; buf += pc_bytes_serialized_size(pcb); } return (PCPATCH*)patch; }
PCPATCH * pc_patch_ght_from_wkb(const PCSCHEMA *schema, const uint8_t *wkb, size_t wkbsize) { #ifndef HAVE_LIBGHT pcerror("%s: libght support is not enabled", __func__); return NULL; #else /* byte: endianness (1 = NDR, 0 = XDR) uint32: pcid (key to POINTCLOUD_SCHEMAS) uint32: compression (0 = no compression, 1 = dimensional, 2 = GHT) uint32: npoints uint32: ghtsize uint8[]: ghtbuffer */ static size_t hdrsz = 1+4+4+4; /* endian + pcid + compression + npoints */ PCPATCH_GHT *patch; uint8_t swap_endian = (wkb[0] != machine_endian()); uint32_t npoints; size_t ghtsize; const uint8_t *buf; if ( wkb_get_compression(wkb) != PC_GHT ) { pcerror("%s: call with wkb that is not GHT compressed", __func__); return NULL; } npoints = wkb_get_npoints(wkb); patch = pcalloc(sizeof(PCPATCH_GHT)); patch->type = PC_GHT; patch->readonly = PC_FALSE; patch->schema = schema; patch->npoints = npoints; /* Start on the GHT */ buf = wkb+hdrsz; ghtsize = wkb_get_int32(buf, swap_endian); buf += 4; /* Move to start of GHT buffer */ /* Copy in the tree buffer */ patch->ght = pcalloc(ghtsize); patch->ghtsize = ghtsize; memcpy(patch->ght, buf, ghtsize); return (PCPATCH*)patch; #endif }
/* * Instantiate a new PCDOUBLESTATS for calculation, and set up * initial values for min/max/sum */ static PCDOUBLESTATS * pc_dstats_new(int ndims) { int i; PCDOUBLESTATS *stats = pcalloc(sizeof(PCDOUBLESTATS)); stats->dims = pcalloc(sizeof(PCDOUBLESTAT)*ndims); for ( i = 0; i < ndims; i++ ) { stats->dims[i].min = DBL_MAX; stats->dims[i].max = -1 * DBL_MAX; stats->dims[i].sum = 0; } stats->npoints = 0; return stats; }
char *sftp_utf8_decode_str(pool *p, const char *str) { #if defined(PR_USE_NLS) && defined(HAVE_ICONV_H) size_t inlen, inbuflen, outlen, outbuflen; char *inbuf, outbuf[PR_TUNABLE_PATH_MAX*2], *res = NULL; if (p == NULL || str == NULL) { errno = EINVAL; return NULL; } if (decode_conv == (iconv_t) -1) { pr_trace_msg("sftp", 1, "decoding conversion handle is invalid, unable to " "decode UTF8 string"); return (char *) str; } /* If the local charset matches the remote charset (i.e. local_charset is * "UTF-8"), then there's no point in converting; the charsets are the * same. Indeed, on some libiconv implementations, attempting to * convert between the same charsets results in a tightly spinning CPU * (see Bug#3272). */ if (strncasecmp(local_charset, "UTF-8", 6) == 0) { return (char *) str; } inlen = strlen(str) + 1; inbuf = pcalloc(p, inlen); memcpy(inbuf, str, inlen); inbuflen = inlen; outbuflen = sizeof(outbuf); if (utf8_convert(decode_conv, inbuf, &inbuflen, outbuf, &outbuflen) < 0) { pr_trace_msg("sftp", 1, "error decoding string: %s", strerror(errno)); return (char *) str; } outlen = sizeof(outbuf) - outbuflen; res = pcalloc(p, outlen); memcpy(res, outbuf, outlen); return res; #else return pstrdup(p, str); #endif /* !PR_USE_NLS && !HAVE_ICONV_H */ }
static pr_ctrls_t *ctrls_new(void) { pr_ctrls_t *ctrl = NULL; /* Check for a free ctrl first */ if (ctrls_free_list) { /* Take one from the top */ ctrl = ctrls_free_list; ctrls_free_list = ctrls_free_list->ctrls_next; if (ctrls_free_list) ctrls_free_list->ctrls_prev = NULL; } else { /* Have to allocate a new one. */ ctrl = (pr_ctrls_t *) pcalloc(ctrls_pool, sizeof(pr_ctrls_t)); /* It's important that a new ctrl object have the retval initialized * to 1; this tells the Controls layer that it is "pending", not yet * handled. */ ctrl->ctrls_cb_retval = 1; } return ctrl; }
uint8_t * pc_patch_uncompressed_to_wkb(const PCPATCH_UNCOMPRESSED *patch, size_t *wkbsize) { /* byte: endianness (1 = NDR, 0 = XDR) uint32: pcid (key to POINTCLOUD_SCHEMAS) uint32: compression (0 = no compression, 1 = dimensional, 2 = GHT) uint32: npoints uchar[]: data (interpret relative to pcid) */ char endian = machine_endian(); /* endian + pcid + compression + npoints + datasize */ size_t size = 1 + 4 + 4 + 4 + patch->datasize; uint8_t *wkb = pcalloc(size); uint32_t compression = patch->type; uint32_t npoints = patch->npoints; uint32_t pcid = patch->schema->pcid; wkb[0] = endian; /* Write endian flag */ memcpy(wkb + 1, &pcid, 4); /* Write PCID */ memcpy(wkb + 5, &compression, 4); /* Write compression */ memcpy(wkb + 9, &npoints, 4); /* Write npoints */ memcpy(wkb + 13, patch->data, patch->datasize); /* Write data */ if ( wkbsize ) *wkbsize = size; return wkb; }
static void test_patch_union() { int i; int npts = 20; PCPOINTLIST *pl1; PCPATCH *pu; PCPATCH **palist; pl1 = pc_pointlist_make(npts); for ( i = 0; i < npts; i++ ) { PCPOINT *pt = pc_point_make(simpleschema); pc_point_set_double_by_name(pt, "x", i*2.0); pc_point_set_double_by_name(pt, "y", i*1.9); pc_point_set_double_by_name(pt, "Z", i*0.34); pc_point_set_double_by_name(pt, "intensity", 10); pc_pointlist_add_point(pl1, pt); } palist = pcalloc(2*sizeof(PCPATCH*)); palist[0] = (PCPATCH*)pc_patch_dimensional_from_pointlist(pl1); palist[1] = (PCPATCH*)pc_patch_uncompressed_from_pointlist(pl1); pu = pc_patch_from_patchlist(palist, 2); CU_ASSERT_EQUAL(pu->npoints, 2*npts); pc_pointlist_free(pl1); pc_patch_free(pu); pc_patch_free(palist[0]); pc_patch_free(palist[1]); pcfree(palist); }
/* * cmd_identify: returns API information and an identification string for * the backend handler. mod_sql will call this at initialization and * display the identification string. The API version information is * used by mod_sql to identify available command handlers. * * Inputs: * None. The cmd->tmp_pool can be used to construct the return data, but * do not depend on any other portion of the cmd_rec to be useful in any way. * * Returns: * A sql_data_t of *exactly* this form: * sql_data_t->rnum = 1; * sql_data_t->fnum = 2; * sql_data_t->data[0] = "identification string" * sql_data_t->data[0] = "API version" * * Notes: * See mod_sql.h for currently accepted APIs. */ MODRET cmd_identify(cmd_rec * cmd) { sql_data_t *sd = NULL; _sql_check_cmd(cmd, "cmd_identify"); sd = (sql_data_t *) pcalloc(cmd->tmp_pool, sizeof(sql_data_t)); sd->data = (char **) pcalloc(cmd->tmp_pool, sizeof(char *) * 2); sd->rnum = 1; sd->fnum = 2; sd->data[0] = MOD_SQL_POSTGRES_VERSION; sd->data[1] = MOD_SQL_API_V1; return mod_create_data(cmd, (void *) sd); }
/* * cmd_escapestring: certain strings sent to a database should be properly * escaped -- for instance, quotes need to be escaped to insure that * a query string is properly formatted. cmd_escapestring does whatever * is necessary to escape the special characters in a string. * * Inputs: * cmd->argv[0]: connection name * cmd->argv[1]: string to escape * * Returns: * this command CANNOT fail. The return string is null-terminated and * stored in the data field of the modret_t structure. * * Notes: * Different languages may escape different characters in different ways. * A backend should handle this correctly, where possible. If there is * no client library function to do the string conversion, it is strongly * recommended that the backend module writer do whatever is necessry (read * the database documentation and figure it out) to do the conversion * themselves in this function. * * A backend MUST supply a working escapestring implementation. Simply * copying the data from argv[0] into the data field of the modret allows * for possible SQL injection attacks when this backend is used. */ MODRET cmd_escapestring(cmd_rec * cmd) { conn_entry_t *entry = NULL; db_conn_t *conn = NULL; modret_t *cmr = NULL; char *unescaped = NULL; char *escaped = NULL; cmd_rec *close_cmd; size_t unescaped_len = 0; #ifdef HAVE_POSTGRES_PQESCAPESTRINGCONN int pgerr = 0; #endif sql_log(DEBUG_FUNC, "%s", "entering \tpostgres cmd_escapestring"); _sql_check_cmd(cmd, "cmd_escapestring"); if (cmd->argc != 2) { sql_log(DEBUG_FUNC, "%s", "exiting \tpostgres cmd_escapestring"); return PR_ERROR_MSG(cmd, MOD_SQL_POSTGRES_VERSION, "badly formed request"); } /* get the named connection */ entry = _sql_get_connection(cmd->argv[0]); if (!entry) { sql_log(DEBUG_FUNC, "%s", "exiting \tpostgres cmd_escapestring"); return PR_ERROR_MSG(cmd, MOD_SQL_POSTGRES_VERSION, "unknown named connection"); } conn = (db_conn_t *) entry->data; /* Make sure the connection is open. */ cmr = cmd_open(cmd); if (MODRET_ERROR(cmr)) { sql_log(DEBUG_FUNC, "%s", "exiting \tpostgres cmd_escapestring"); return cmr; } unescaped = cmd->argv[1]; unescaped_len = strlen(unescaped); escaped = (char *) pcalloc(cmd->tmp_pool, sizeof(char) * (unescaped_len * 2) + 1); #ifdef HAVE_POSTGRES_PQESCAPESTRINGCONN PQescapeStringConn(conn->postgres, escaped, unescaped, unescaped_len, &pgerr); if (pgerr != 0) { sql_log(DEBUG_FUNC, "%s", "exiting \tpostgres cmd_escapestring"); return _build_error(cmd, conn); } #else PQescapeString(escaped, unescaped, unescaped_len); #endif close_cmd = _sql_make_cmd(cmd->tmp_pool, 1, entry->name); cmd_close(close_cmd); SQL_FREE_CMD(close_cmd); sql_log(DEBUG_FUNC, "%s", "exiting \tpostgres cmd_escapestring"); return mod_create_data(cmd, (void *) escaped); }
static int copy_symlink(pool *p, const char *src_path, const char *dst_path) { char *link_path = pcalloc(p, PR_TUNABLE_BUFFER_SIZE); int len; len = pr_fsio_readlink(src_path, link_path, PR_TUNABLE_BUFFER_SIZE-1); if (len < 0) { int xerrno = errno; pr_log_pri(PR_LOG_WARNING, MOD_COPY_VERSION ": error reading link '%s': %s", src_path, strerror(xerrno)); errno = xerrno; return -1; } link_path[len] = '\0'; if (pr_fsio_symlink(link_path, dst_path) < 0) { int xerrno = errno; pr_log_pri(PR_LOG_WARNING, MOD_COPY_VERSION ": error symlinking '%s' to '%s': %s", link_path, dst_path, strerror(xerrno)); errno = xerrno; return -1; } return 0; }
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; }
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; }