/* * Cleanup for http_xml_send_xmlrpc() */ static void http_xml_send_xmlrpc_cleanup(void *arg) { struct http_xml_send_xmlrpc_ctx *const ctx = arg; const struct structs_type *const xreq_type = &structs_type_xmlrpc_request; const struct structs_type *const xrep_type = &structs_type_xmlrpc_response; if (ctx->xreq != NULL) { structs_free(xreq_type, NULL, ctx->xreq); FREE(MEM_TYPE, ctx->xreq); } if (ctx->xrep != NULL) { structs_free(xrep_type, NULL, ctx->xrep); FREE(MEM_TYPE, ctx->xrep); } FREE(MEM_TYPE, ctx); }
int structs_fixedarray_decode(const struct structs_type *type, const u_char *code, size_t cmax, void *data, char *ebuf, size_t emax) { const struct structs_type *const etype = type->args[0].v; const u_int length = type->args[2].i; const u_int bitslen = NUM_BYTES(length); const u_char *bits; int clen = 0; u_int i; /* Make sure it's really a fixedarray type */ if (type->tclass != STRUCTS_TYPE_FIXEDARRAY) { errno = EINVAL; return (-1); } /* Get bits array */ if (cmax < bitslen) { strlcpy(ebuf, "encoded array is truncated", emax); errno = EINVAL; return (-1); } bits = code; code += bitslen; cmax -= bitslen; clen += bitslen; /* Decode elements */ for (i = 0; i < length; i++) { void *const edata = (char *)data + (i * etype->size); int eclen; /* If element not present, assign it the default value */ if ((bits[i / 8] & (1 << (i % 8))) == 0) { if (structs_init(etype, NULL, edata) == -1) goto fail; continue; } /* Decode element */ if ((eclen = (*etype->decode)(etype, code, cmax, edata, ebuf, emax)) == -1) goto fail; /* Go to next encoded element */ code += eclen; cmax -= eclen; clen += eclen; continue; /* Un-do work done so far */ fail: while (i-- > 0) { structs_free(etype, NULL, (char *)data + (i * etype->size)); } return (-1); } /* Done */ return (clen); }
int structs_fixedarray_encode(const struct structs_type *type, const char *mtype, struct structs_data *code, const void *data) { const struct structs_type *const etype = type->args[0].v; const u_int length = type->args[2].i; const u_int bitslen = NUM_BYTES(length); struct structs_data *ecodes; u_char *bits; void *delem; u_int tlen; int r = -1; u_int i; /* Make sure it's really a fixedarray type */ if (type->tclass != STRUCTS_TYPE_FIXEDARRAY) { errno = EINVAL; return (-1); } /* Get the default value for an element */ if ((delem = MALLOC(TYPED_MEM_TEMP, etype->size)) == NULL) return (-1); if (structs_init(etype, NULL, delem) == -1) goto fail1; /* Create bit array. Each bit indicates an element that is present. */ if ((bits = MALLOC(TYPED_MEM_TEMP, bitslen)) == NULL) goto fail2; memset(bits, 0, bitslen); tlen = bitslen; /* Create array of individual encodings, one per element */ if ((ecodes = MALLOC(TYPED_MEM_TEMP, length * sizeof(*ecodes))) == NULL) goto fail3; for (i = 0; i < length; i++) { const void *const elem = (char *)data + (i * etype->size); struct structs_data *const ecode = &ecodes[i]; /* Check for default value, leave out if same as */ if ((*etype->equal)(etype, elem, delem) == 1) { memset(ecode, 0, sizeof(*ecode)); continue; } bits[i / 8] |= (1 << (i % 8)); /* Encode element */ if ((*etype->encode)(etype, TYPED_MEM_TEMP, ecode, elem) == -1) goto fail4; tlen += ecode->length; } /* Allocate final encoded region */ if ((code->data = MALLOC(mtype, tlen)) == NULL) goto fail4; /* Copy bits array */ memcpy(code->data, bits, bitslen); code->length = bitslen; /* Copy encoded elements */ for (i = 0; i < length; i++) { struct structs_data *const ecode = &ecodes[i]; memcpy(code->data + code->length, ecode->data, ecode->length); code->length += ecode->length; } /* OK */ r = 0; /* Clean up and exit */ fail4: while (i-- > 0) FREE(TYPED_MEM_TEMP, ecodes[i].data); FREE(TYPED_MEM_TEMP, ecodes); fail3: FREE(TYPED_MEM_TEMP, bits); fail2: structs_free(etype, NULL, delem); fail1: FREE(TYPED_MEM_TEMP, delem); return (r); }
int structs_array_decode(const struct structs_type *type, const u_char *code, size_t cmax, void *data, char *ebuf, size_t emax) { const struct structs_type *const etype = type->args[0].v; const char *const mtype = type->args[1].v; struct structs_array *const ary = data; const u_char *bits; u_int32_t elength; u_int bitslen; int clen; u_int i; /* Make sure it's really an array type */ if (type->tclass != STRUCTS_TYPE_ARRAY) { errno = EINVAL; return (-1); } /* Get number of elements */ if (cmax < 4) goto truncated; memcpy(&elength, code, 4); ary->length = ntohl(elength); code += 4; cmax -= 4; clen = 4; /* Get bits array */ bitslen = NUM_BYTES(ary->length); if (cmax < bitslen) { truncated: strlcpy(ebuf, "encoded array is truncated", emax); errno = EINVAL; return (-1); } bits = code; code += bitslen; cmax -= bitslen; clen += bitslen; /* Allocate array elements */ if ((ary->elems = MALLOC(mtype, ary->length * etype->size)) == NULL) return (-1); /* Decode elements */ for (i = 0; i < ary->length; i++) { void *const edata = (char *)ary->elems + (i * etype->size); int eclen; /* If element not present, assign it the default value */ if ((bits[i / 8] & (1 << (i % 8))) == 0) { if (structs_init(etype, NULL, edata) == -1) goto fail; continue; } /* Decode element */ if ((eclen = (*etype->decode)(etype, code, cmax, edata, ebuf, emax)) == -1) goto fail; /* Go to next encoded element */ code += eclen; cmax -= eclen; clen += eclen; continue; /* Un-do work done so far */ fail: while (i-- > 0) { structs_free(etype, NULL, (char *)ary->elems + (i * etype->size)); } FREE(mtype, ary->elems); return (-1); } /* Done */ return (clen); }
ACPI_STATUS AcpiOsReleaseObject(ACPI_CACHE_T * Cache, void *Object) { structs_free(Object); return AE_OK; }
/* * Same as http_xml_send_xmlrpc() but with user-defined URL path. */ int http_xml_send_xmlrpc2(struct http_client *client, struct in_addr ip, u_int16_t port, int https, const char *username, const char *password, const char *urlpath, const char *methodName, u_int nparams, const struct structs_type **ptypes, const void **pdatas, const struct structs_type *rep_type, void *rep, struct xmlrpc_compact_fault *faultp, structs_xmllog_t *rlogger) { const struct structs_type *const xreq_type = &structs_type_xmlrpc_request; const struct structs_type *const xrep_type = &structs_type_xmlrpc_response; const struct structs_type *const ftype = &structs_type_xmlrpc_compact_fault; struct http_xml_send_xmlrpc_ctx *ctx; struct xmlrpc_compact_fault fault; char ebuf[128]; int ret = -1; int r; /* Get context */ if ((ctx = MALLOC(MEM_TYPE, sizeof(*ctx))) == NULL) { alogf(LOG_ERR, "%s: %m", "malloc"); return (-1); } memset(ctx, 0, sizeof(*ctx)); pthread_cleanup_push(http_xml_send_xmlrpc_cleanup, ctx); /* Build XML-RPC request and reply */ if ((ctx->xreq = structs_xmlrpc_build_request(MEM_TYPE, methodName, nparams, ptypes, pdatas)) == NULL) { alogf(LOG_ERR, "%s: %m", "structs_xmlrpc_build_request"); goto fail; } if ((ctx->xrep = MALLOC(MEM_TYPE, xrep_type->size)) == NULL) { alogf(LOG_ERR, "%s: %m", "malloc"); goto fail; } if (structs_init(xrep_type, NULL, ctx->xrep) == -1) { alogf(LOG_ERR, "%s: %m", "structs_init"); FREE(MEM_TYPE, ctx->xrep); ctx->xrep = NULL; goto fail; } #ifdef XML_RPC_DEBUG printf("%s: sending this XML-RPC request:\n", __FUNCTION__); (void)structs_xml_output(xreq_type, XML_RPC_REQUEST_TAG, NULL, ctx->xreq, stdout, NULL, 0); #endif /* Send request and get reply; note: we could get canceled here. */ r = http_xml_send(client, ip, port, https, urlpath, username, password, XML_RPC_REQUEST_TAG, NULL, xreq_type, ctx->xreq, STRUCTS_XML_FULL, XML_RPC_REPLY_TAG, NULL, NULL, xrep_type, ctx->xrep, 0, rlogger); #ifdef XML_RPC_DEBUG printf("%s: got this XML-RPC reply (error=%s):\n", __FUNCTION__, r == -1 ? strerror(errno) : "none"); (void)structs_xml_output(xrep_type, XML_RPC_REPLY_TAG, NULL, ctx->xrep, stdout, NULL, 0); #endif /* Check error */ if (r == -1) goto fail; /* Check for fault */ if (structs_init(ftype, NULL, &fault) == -1) { alogf(LOG_ERR, "%s: %m", "structs_init"); goto fail; } if (structs_xmlrpc2struct(xrep_type, ctx->xrep, "fault.value", ftype, &fault, NULL, NULL, 0) == 0) { if (faultp != NULL) *faultp = fault; else structs_free(ftype, NULL, &fault); ret = -2; /* -2 indicates fault */ goto fail; } structs_free(ftype, NULL, &fault); /* Extract response (if desired) */ if (rep != NULL) { if (rep_type != NULL) { /* return compact type */ if (structs_xmlrpc2struct(xrep_type, ctx->xrep, "params.0.value", rep_type, rep, NULL, ebuf, sizeof(ebuf)) == -1) { (*rlogger)(LOG_ERR, "error decoding XML-RPC" " response: %s", ebuf); goto fail; } } else { /* return exploded type */ if (structs_get(&structs_type_xmlrpc_value, "params.0.value", ctx->xrep, rep) == -1) { alogf(LOG_ERR, "structs_get: %m%s", ""); goto fail; } } } /* OK */ ret = 0; fail:; /* Done */ pthread_cleanup_pop(1); return (ret); }
void pmap_free(struct pmap *pmap) { assert(pmap != NULL && pmap != pmap_current()); free12k(pmap->l1s); structs_free(pmap); }