bool_t check_encoding_zbase32(void) { stringer_t *zb32, *binary; byte_t buffer[ZBASE32_CHECK_SIZE]; for (uint64_t i = 0; status() && i < ZBASE32_CHECK_ITERATIONS; i++) { // Fill the buffer with random data and convert the buffer to hex. if (rand_write(PLACER(buffer, ZBASE32_CHECK_SIZE)) != ZBASE32_CHECK_SIZE) { return false; } else if (!(zb32 = zbase32_encode(PLACER(buffer, ZBASE32_CHECK_SIZE)))) { return false; } //log_pedantic("zb32 = %.*s", st_length_int(zb32), st_char_get(zb32)); // Convert the buffer back to binary and compare it with the original array. if (!(binary = zbase32_decode(zb32))) { st_free(zb32); return false; } else if (st_cmp_cs_eq(binary, PLACER(buffer, ZBASE32_CHECK_SIZE))) { st_free(binary); st_free(zb32); return false; } st_free(binary); st_free(zb32); } return true; }
static bool reopen_input_file(int i,progress_info *proginfo) { unsigned char *header; if (!open_input_stream(files[i])) { prog_error(proginfo); st_warning("could not reopen input file: [%s]",files[i]->filename); return FALSE; } if (NULL == (header = malloc(files[i]->header_size * sizeof(unsigned char)))) { prog_error(proginfo); st_warning("could not allocate %d-byte WAVE header",files[i]->header_size); return FALSE; } if (read_n_bytes(files[i]->input,header,files[i]->header_size,NULL) != files[i]->header_size) { prog_error(proginfo); st_warning("error while reading %d-byte WAVE header",files[i]->header_size); st_free(header); return FALSE; } st_free(header); return TRUE; }
/** * @brief Decompress data using the bzip engine. * @param compressed a pointer to the head of the compressed data. * @return NULL on failure, or a managed string containing the uncompressed data on success. */ stringer_t * decompress_bzip(compress_t *compressed) { int ret; void *bptr; uint64_t hash, rlen, blen; stringer_t *result = NULL; compress_head_t *head; if (!(head = (compress_head_t *)compressed)) { log_info("Invalid compression header. {compress_head = NULL}"); return NULL; } else if (head->engine != COMPRESS_ENGINE_BZIP) { log_info("The buffer passed in was not compressed using the BZIP engine. {engine = %hhu}", head->engine); return NULL; } else if (!(bptr = compress_body_data(compressed)) || !(blen = head->length.compressed) || !(rlen = head->length.original) || head->hash.compressed != (hash = hash_adler32(bptr, blen))) { log_info("The compressed has been corrupted. {expected = %lu / input = %lu}", head->hash.compressed, hash); return NULL; } else if (!(result = st_alloc(head->length.original + 1))) { log_info("Could not allocate a block of %lu bytes for the uncompressed data.", head->length.original); return NULL; } else if ((ret = BZ2_bzBuffToBuffDecompress_d(st_data_get(result), (unsigned int *)&rlen, bptr, blen, 0, 0)) != BZ_OK) { log_info("Unable to decompress the buffer. {BZ2_bzBuffToBuffDecompress = %i}", ret); st_free(result); return NULL; } else if (head->length.original != rlen || head->hash.original != (hash = hash_adler32(st_data_get(result), rlen))) { log_info("The uncompressed data is corrupted. {input = %lu != %lu / hash = %lu != %lu}", head->length.original, rlen, head->hash.original, hash); st_free(result); return NULL; } st_length_set(result, rlen); return result; }
bool_t check_string_dupe(char *type, uint32_t check) { size_t len; stringer_t *s, *d; if (!(s = st_alloc(check, st_length_int(constant)))) { return false; } len = snprintf(st_char_get(s), st_length_int(constant) + 1, "%.*s", st_length_int(constant), st_char_get(constant)); if (check & MAPPED_T || check & MANAGED_T) { st_length_set(s, len); } if (!(d = st_dupe(s))) { st_free(s); return false; } log_print("%28.28s = %.*s", type, st_length_int(d), st_char_get(d)); if (memcmp(st_char_get(d), st_char_get(s), st_length_get(s))) { st_free(s); st_free(d); return false; } st_free(s); st_free(d); return true; }
bool_t check_string_dupe(uint32_t check) { size_t len; stringer_t *s, *d; if (!(s = st_alloc_opts(check, st_length_int(string_check_constant)))) { return false; } len = snprintf(st_char_get(s), st_length_int(string_check_constant) + 1, "%.*s", st_length_int(string_check_constant), st_char_get(string_check_constant)); if ((check & MAPPED_T) || (check & MANAGED_T)) { st_length_set(s, len); } if (!(d = st_dupe(s))) { st_free(s); return false; } if (memcmp(st_char_get(d), st_char_get(s), st_length_get(s))) { st_free(s); st_free(d); return false; } st_free(s); st_free(d); return true; }
bool_t check_encoding_qp(void) { stringer_t *qp, *binary; byte_t buffer[QP_CHECK_SIZE]; for (uint64_t i = 0; status() && i < QP_CHECK_ITERATIONS; i++) { // Fill the buffer with random data and convert the buffer to hex. if (rand_write(PLACER(buffer, QP_CHECK_SIZE)) != QP_CHECK_SIZE) { return false; } else if (!(qp = qp_encode(PLACER(buffer, QP_CHECK_SIZE)))) { return false; } //log_pedantic("qp = %.*s", st_length_int(qp), st_char_get(qp)); // Convert the buffer back to binary and compare it with the original array. if (!(binary = qp_decode(qp))) { st_free(qp); return false; } else if (st_cmp_cs_eq(binary, PLACER(buffer, QP_CHECK_SIZE))) { st_free(binary); st_free(qp); return false; } st_free(binary); st_free(qp); } return true; }
void st_input_destroy (st_input *input) { st_assert (input != NULL); st_free (input->text); st_free (input); }
/** * @brief Get the subtype of the Content-Type header value from a mime header. * @note For example in the case of a Content-Type of 'text/plain', "plain" would be the subtype. * @param header a placer pointing to the mime header to be parsed. * @return a managed string containing the content subtype of the header, with "plain" as the default. */ stringer_t * mail_mime_type_sub(placer_t header) { chr_t *stream; stringer_t *line, *result; size_t remaining, characters = 0; if (!(line = mail_header_fetch_cleaned(&header, PLACER("Content-Type", 12)))) { return st_import("plain", 5); } stream = st_char_get(line); remaining = st_length_get(line); // Advance past any garbage. while (remaining && (*stream == '\n' || *stream == '\r' || *stream == ' ' || *stream == '\t' || *stream == '"')) { stream++; remaining--; } // Count how many characters are in the group. Based on RFC4288, section 4.2. while (remaining && ((*stream >= 'a' && *stream <= 'z') || (*stream >= 'A' && *stream <= 'Z') || (*stream >= '0' && *stream <= '9') || *stream == '!' || *stream == '#' || *stream == '$' || *stream == '&' || *stream == '.' || *stream == '+' || *stream == '-' || *stream == '^' || *stream == '_')) { stream++; remaining--; } // Make sure we got something back. Use a default value of plain. if (!remaining || *stream != '/') { st_free(line); return st_import("plain", 5); } // Advance past the separator. stream++; remaining--; // Count how many characters are in the subtype. Based on RFC4288, section 4.2. while (remaining != 0 && ((*stream >= 'a' && *stream <= 'z') || (*stream >= 'A' && *stream <= 'Z') || (*stream >= '0' && *stream <= '9') || *stream == '!' || *stream == '#' || *stream == '$' || *stream == '&' || *stream == '.' || *stream == '+' || *stream == '-' || *stream == '^' || *stream == '_')) { stream++; remaining--; characters++; } // Make sure we got something back. Use a default value of text. if (!characters) { st_free(line); return st_import("plain", 5); } result = st_import(stream - characters, characters); st_free(line); return result; }
// Check that we can't specify a length greater than the available buffer. bool_t check_string_logic(uint32_t check) { stringer_t *s; if (!(s = st_alloc(check, 128)) || st_length_set(s, st_avail_get(s) * 2) != st_avail_get(s)) { if (s) st_free(s); return false; } st_free(s); return true; }
// QUESTION: Why are we using managed strings here? It makes no sense, especially since we have expectations as to where they point. // QUESTION: And why even have message? It seems like we could make do with just having part. size_t mail_discover_insertion_point(stringer_t *message, stringer_t *part, int_t type) { chr_t *stream; size_t length; stringer_t *tag; // If the message is not HTML, return the end of the part as the insertion point. if (type != MESSAGE_TYPE_HTML) { return st_char_get(part) - st_char_get(message) + st_length_get(part); } // Get setup. length = st_length_get(part); stream = st_data_get(part) + length - 1; while (length) { // Reverse until we find a character that is not whitespace. while (length && (*stream == ' ' || *stream == '\r' || *stream == '\n' || *stream == '\t')) { length--; stream--; } if (!(tag = mail_extract_tag(stream, length))) { return (st_char_get(part) - st_char_get(message)) + length; } // What tag is it? if (st_cmp_ci_eq(tag, PLACER("</body>", 7)) != 0 && st_cmp_ci_eq(tag, PLACER("</html>", 7)) != 0) { st_free(tag); return (st_char_get(part) - st_char_get(message)) + length; } st_free(tag); // Advance past this tag. while (length && *stream != '<') { length--; stream--; } if (length && *stream == '<') { length--; stream--; } } return (st_char_get(part) - st_char_get(message)) + length; }
char * st_input_next_chunk (st_input *input) { char *chunk_filtered, *chunk = NULL; st_uint start; start = st_input_index (input); while (st_input_look_ahead (input, 1) != ST_INPUT_EOF) { if (st_input_look_ahead (input, 1) != '!') { st_input_consume (input); continue; } /* skip past doubled bangs */ if (st_input_look_ahead (input, 1) == '!' && st_input_look_ahead (input, 2) == '!') { st_input_consume (input); st_input_consume (input); continue; } chunk = st_input_range (input, start, st_input_index (input)); chunk_filtered = filter_double_bangs (chunk); st_input_consume (input); st_free (chunk); return chunk_filtered; } return NULL; }
/** * @brief Allocates an output string of appropriate size with specified opts for hex decoding of input * @param input Input stringer to be decoded. * @return NULL on failure, otherwise allocated stringer with decoded data. */ stringer_t * hex_decode_opts(stringer_t *input, uint32_t opts) { stringer_t *result = NULL; size_t insize; if(st_empty(input)) { log_pedantic("Empty stringer was passed in."); } if(!opts) { log_pedantic("Invalid stringer options were passed in."); goto error; } insize = st_length_get(input); if(!(result = st_alloc_opts(opts, (insize % 2) ? ((insize + 1) / 2) : (insize / 2) ))) { log_error("Failed to allocate memory for hex-encoded output."); goto error; } if(result != hex_decode_st(input, result)) { log_error("Failed to encode data."); goto cleanup_result; } return result; cleanup_result: st_free(result); error: return NULL; }
/** * @brief Accept a username for POP3 authentication. * @note This command is only allowed for sessions which have not yet been authenticated. * If the username has already been supplied pre-authentication, the old value will be overwritten with the new one. * @param con the POP3 client connection issuing the command. * @brief This function returns no value. */ void pop_user(connection_t *con) { stringer_t *username, *clean; if (con->pop.session_state != 0) { pop_invalid(con); return; } // If they didn't pass in a valid username. if (!(username = pop_user_parse(con)) || !(clean = credential_address(username))) { con_write_bl(con, "-ERR Invalid USER command.\r\n", 28); st_cleanup(username); return; } // Check for a previously provided value and free it. st_cleanup(con->pop.username); st_free(username); // Store the value we were given. Until authentication, this will be the fully qualified username. con->pop.username = clean; // Tell the client everything worked. con_write_bl(con, "+OK Username accepted.\r\n", 24); return; }
/** * @brief Insert a spam signature training link into a plain text message part. * @see mail_discover_insertion_point() * @param server the server object of the web server where the teacher application is hosted. * @param message a managed string containing the message body to be parsed. * @param part a managed string (placer) containing the part of the message where the signature should be inserted. * @param signum the spam signature number referenced by the teacher url. * @param sigkey the spam signature key for client verification in the teacher app. * @param disposition if 0, the message disposition is "innocent"; otherwise, the disposition specifies "spam". * @param type the encoding type of the message (MESSAGE_TYPE_HTML or other). * @param encoding if MESSAGE_ENCODING_QUOTED_PRINTABLE, set the encoding type to qp. * @return NULL on failure or a managed string containing the message with the inserted signature training link on success. */ stringer_t * mail_insert_chunk_text(server_t *server, stringer_t *message, stringer_t *part, uint64_t signum, uint64_t sigkey, int_t disposition, int_t type, int_t encoding) { size_t point; stringer_t *pretext; stringer_t *posttext; stringer_t *result; stringer_t *signature; if (st_empty(part)) { return NULL; } // Start at the end of the chunk and search for where to insert the signature. if (!(signature = mail_build_signature(server, type, encoding, signum, sigkey, disposition))) { return NULL; } // Figure out the insertion point_t and create the new message. point = mail_discover_insertion_point(message, part, type); pretext = PLACER(st_char_get(message), point); posttext = PLACER(st_char_get(message) + point, st_length_get(message) - point); result = st_merge("sss", pretext, signature, posttext); st_free(signature); if (!result) { log_pedantic("Unable to merge the strings together."); } return result; }
bool_t check_bitwise_simple(void) { stringer_t *a, *b, *outcome, *check; unsigned char a_buf[] = {0x00, 0xFF, 0x88, 0x44, 0x22}; unsigned char b_buf[] = {0x11, 0x33, 0xF0, 0x0F, 0x3C}; unsigned char xor_buf[] = {0x11, 0xCC, 0x78, 0x4B, 0x1E}; unsigned char and_buf[] = {0x00, 0x33, 0x80, 0x04, 0x20}; unsigned char or_buf[] = {0x11, 0xFF, 0xF8, 0x4F, 0x3E}; unsigned char nota_buf[] = {0xFF, 0x00, 0x77, 0xBB, 0xDD}; a = PLACER(a_buf, 5); b = PLACER(b_buf, 5); check = PLACER(xor_buf, 5); if(!(outcome = st_xor(a, b, NULL)) || st_cmp_cs_eq(outcome, check)) { st_cleanup(outcome); return false; } check = PLACER(and_buf, 5); st_free(outcome); if(!(outcome = st_and(a, b, NULL)) || st_cmp_cs_eq(outcome, check)) { st_cleanup(outcome); return false; } check = PLACER(or_buf, 5); st_free(outcome); if(!(outcome = st_or(a, b, NULL)) || st_cmp_cs_eq(outcome, check)) { st_cleanup(outcome); return false; } check = PLACER(nota_buf, 5); st_free(outcome); if(!(outcome = st_not(a, NULL)) || st_cmp_cs_eq(outcome,check)) { st_cleanup(outcome); return false; } st_free(outcome); return true; }
END_TEST START_TEST(test_folder_exists__nonexistent) { stringer_t *nonex = mkstringer("/nonexistent"); ck_assert_int_eq(-1, folder_exists(nonex, false)); ck_assert_int_eq(-1, folder_exists(nonex, true)); st_free(nonex); }
void st_close (ddb_dsp_context_t *_src) { ddb_soundtouch_t *st = (ddb_soundtouch_t *)_src; if (st->st) { st_free (st->st); } free (st); }
END_TEST START_TEST(test_folder_exists__nested) { stringer_t *deepdir = mkstringer("/tmp/deeply/nested/dir"); ck_assert_int_eq(-1, folder_exists(deepdir, false)); ck_assert_int_eq(-1, folder_exists(deepdir, true)); st_free(deepdir); }
bool_t check_string_import(void) { stringer_t *s; if (!(s = st_import(st_data_get(string_check_constant), st_length_int(string_check_constant)))) { return false; } if (memcmp(st_char_get(s), st_char_get(string_check_constant), st_length_get(string_check_constant))) { st_free(s); return false; } st_free(s); return true; }
/** * @brief Derive an organizational signet from the corresponding private key structures. */ prime_org_signet_t * org_signet_generate(prime_org_key_t *org) { prime_org_signet_t *signet = NULL; stringer_t *signing = NULL, *encryption = NULL, *cryptographic = MANAGEDBUF(69); // Ensure the org structure contains the necessary private keys. if (!org || !org->encryption || !org->signing || org->signing->type != ED25519_PRIV) { return NULL; } else if (!(signet = mm_alloc(sizeof(prime_org_signet_t)))) { return NULL; } // Store the public singing, and encryption keys. else if (!(signing = ed25519_public_get(org->signing, NULL)) || !(encryption = secp256k1_public_get(org->encryption, NULL))) { log_pedantic("PRIME organizational signet generation failed, the public keys could not be derived from the provided private keys."); org_signet_free(signet); st_cleanup(signing); return NULL; } // Generate a serialized signet with the cryptographic fields. else if (st_write(cryptographic, prime_field_write(PRIME_ORG_SIGNET, 1, ED25519_KEY_PUB_LEN, signing, MANAGEDBUF(34)), prime_field_write(PRIME_ORG_SIGNET, 3, SECP256K1_KEY_PUB_LEN, encryption, MANAGEDBUF(35))) != 69) { log_pedantic("PRIME organizational signet generation failed, the serialized cryptographic signet could not be derived."); org_signet_free(signet); st_free(encryption); st_free(signing); return NULL; } // Generate a signature using the serialized cryptographic fields. else if (!(signet->signature = ed25519_sign(org->signing, cryptographic, NULL))) { log_pedantic("PRIME organizational signet generation failed, the cryptographic signet signature could not be derived."); org_signet_free(signet); st_free(encryption); st_free(signing); return NULL; } // Finally, convert the serialized public keys into usable structures. else if (!(signet->signing = ed25519_public_set(signing)) || !(signet->encryption = secp256k1_public_set(encryption))) { log_pedantic("PRIME organizational signet generation failed, the serialized public keys could not be parsed."); org_signet_free(signet); st_free(encryption); st_free(signing); return NULL; } // We no longer need the serialized public keys. st_free(encryption); st_free(signing); return signet; }
/** * @brief Free all loaded magma configuration options. * @note First all magma config keys will be freed, then the cache servers, relay servers, and magma servers. * @return This function returns no value. */ void config_free(void) { for (uint64_t i = 0; i < sizeof(magma_keys) / sizeof(magma_keys_t); i++) { switch (magma_keys[i].norm.type) { case (M_TYPE_BLOCK): if (*((void **)(magma_keys[i].store))) { mm_free(*((void **)(magma_keys[i].store))); } break; case (M_TYPE_NULLER): if (*((char **)(magma_keys[i].store))) { ns_free(*((char **)(magma_keys[i].store))); } break; case (M_TYPE_STRINGER): // Intercept the blacklist config key. if (!st_cmp_cs_eq(NULLER(magma_keys[i].name), PLACER("magma.smtp.blacklist", 20))) { for (uint32_t j = 0; j < magma.smtp.blacklists.count; j++) { st_free(magma.smtp.blacklists.domain[j]); } } else if (*((stringer_t **)(magma_keys[i].store))) { st_free(*((stringer_t **)(magma_keys[i].store))); } break; default: #ifdef MAGMA_PEDANTIC if (magma_keys[i].norm.type != M_TYPE_BOOLEAN && magma_keys[i].norm.type != M_TYPE_DOUBLE && magma_keys[i].norm.type != M_TYPE_FLOAT && magma_keys[i].norm.type != M_TYPE_INT16 && magma_keys[i].norm.type != M_TYPE_INT32 && magma_keys[i].norm.type != M_TYPE_INT64 && magma_keys[i].norm.type != M_TYPE_INT8 && magma_keys[i].norm.type != M_TYPE_UINT8 && magma_keys[i].norm.type != M_TYPE_UINT16 && magma_keys[i].norm.type != M_TYPE_UINT32 && magma_keys[i].norm.type != M_TYPE_UINT64 && magma_keys[i].norm.type != M_TYPE_ENUM) { log_pedantic("Unexpected type. {type = %s = %u}", type(magma_keys[i].norm.type), magma_keys[i].norm.type); } #endif break; } } cache_free(); relay_free(); servers_free(); return; }
void st_asn1_free_context(st_asn1_context* pContext) { if ((pContext == NULL) || (*pContext == NULL)) return; if (((unsigned char*)*pContext)[0]) st_free(*pContext); *pContext = NULL; }
/** * @brief Generate a MIME boundary string that is unique to a collection of content. * @param parts a pointer to an array of managed strings containing the MIME children data to be separated by the boundary. * @return NULL on failure, or a pointer to a managed string containing the generated boundary on success. */ stringer_t * mail_mime_generate_boundary (array_t *parts) { stringer_t *result, *cmp; chr_t *ptr; size_t blen = 16; int_t rnd; if (!parts) { log_pedantic("Cannot generate mime boundary with empty input data."); return NULL; } if (!(result = st_alloc(blen))) { log_error("Unable to allocate space for boundary string."); return NULL; } // Keep generating boundary strings until one of them is unique... we don't expect collisions to happen that often. while (1) { srand(rand_get_uint64()); ptr = st_char_get (result); // Generate blen's worth of random bytes, each being either a random digit or lowercase letter. for (size_t i = 0; i < blen; i++) { rnd = rand(); if (rnd % 2) { *ptr++ = '0' + (rnd % 10); } else { *ptr ++ = 'a' + (rnd % 26); } } st_length_set(result, blen); // Now make sure it's not found in any of the parts. for (size_t i = 0; i < ar_length_get(parts); i++) { if (!(cmp = (stringer_t *) ar_field_ptr(parts, i))) { log_pedantic("Could not generate mime boundary for null content."); st_free(result); return NULL; } if (st_search_ci(cmp, result, NULL)) { continue; } } // If we made it this far, the boundary string was not found in any of the supplied content. break; } return result; }
void req_free(HTTPRequest *req) { if (req->headers) { st_free(req->headers); } if (req->request_str) WOFREE(req->request_str); if (req->content) WOFREE(req->content); WOFREE(req); }
/* * This function cleans up all the lists and dictionaries created while parsing the config. */ static void freeWOXMLEdits(WOXMLEdits *config) { int i; for (i=0; i<wolist_count(config->new_apps); i++) st_free(wolist_elementAt(config->new_apps, i)); wolist_dealloc(config->new_apps); for (i=0; i<wolist_count(config->new_app_instances); i++) { int j; list *instances = wolist_elementAt(config->new_app_instances, i); for (j=0; j<wolist_count(instances); j++) st_free(wolist_elementAt(instances, j)); wolist_dealloc(instances); } wolist_dealloc(config->new_app_instances); }
END_TEST START_TEST(test_folder_exists__tmpdir) { stringer_t *tmpdir = mkstringer("/tmp/check_host_folder.d"); ck_assert_int_eq(-1, folder_exists(tmpdir, false)); ck_assert_int_eq(1, folder_exists(tmpdir, true)); rmdir(st_data_get(tmpdir)); st_free(tmpdir); }
/** * @brief Encode a MIME part for a provided block of data (file attachment) with the specified filename. * @note This function will look up the media type based on the supplied filename, and use that media type as a determination * of whether the content is to be encoded as either quoted-printable or base64. * @param data a pointer to a managed string containing the body of the data to be encoded. * @param filename a pointer to a managed string containing the filename of the attachment for which the data was provided. * @param boundary a pointer to a managed string containing the boundary that will be used to separate the individual MIME parts. * @return NULL on failure, or a pointer to a managed string containing the file attachment encoded as a MIME part on success. */ stringer_t * mail_mime_encode_part(stringer_t *data, stringer_t *filename, stringer_t *boundary) { stringer_t *result, *encoded; media_type_t *mtype; chr_t *fstart, *extptr = NULL, *ctype; size_t flen; if (!data) { return NULL; } // First get the extension of the filename so we can look up the media type. if (!st_empty_out(filename, (uchr_t **)&fstart, &flen)) { extptr = fstart + flen + 1; while (extptr >= fstart) { if (*extptr == '.') { break; } extptr--; } if (extptr < fstart) { extptr = NULL; } } mtype = mail_mime_get_media_type (extptr); if (mtype->bin) { encoded = base64_encode(data, NULL); ctype = "base64"; } else { encoded = qp_encode(data); ctype = "quoted-printable"; } if (!encoded) { log_pedantic("Unable to encode MIME part data."); return NULL; } // What we return is: boundary/CRLF, Content-Type/CRLF, Content-Transfer-Encoding/CRLF, Content-Disposition/CRLF, data/CRLF if (!(result = st_merge("nsnnnnnnnsns", "--------------", boundary, "\r\n", "Content-Type: ", mtype->name, ";\r\n", "Content-Transfer-Encoding: ", ctype, "\r\nContent-Disposition: attachment; filename=\"", filename, "\"\r\n\r\n", encoded))) { log_pedantic("Unable to generate MIME part data."); return NULL; } st_free(encoded); return result; }
bool_t check_string_import(void) { stringer_t *s; if (!(s = st_import(st_data_get(constant), st_length_int(constant)))) { return false; } log_print("%28.28s = %.*s", "duplicate", st_length_int(s), st_char_get(s)); if (memcmp(st_char_get(s), st_char_get(constant), st_length_get(constant))) { st_free(s); return false; } st_free(s); return true; }
/** * @brief Get an array of the key/value pairs of parameters passed to the value of the mime Content-Type header. * @note The parameters of the Content-Type header value will be examined, and each found parameter will result in the addition of * TWO managed strings to the returned array: the first containing the parameter key name, and the second with the parameter value. * @param header a placer pointing to the mime header to be parsed. * @return NULL on failure, or on success, an array of managed strings structured as the key name followed by the value of each parameter * passed in the Content-Type header. */ array_t * mail_mime_type_parameters(placer_t header) { array_t *output; stringer_t *key, *holder; placer_t parameter; unsigned increment, tokens; if (!(holder = mail_header_fetch_cleaned(&header, PLACER("Content-Type", 12)))) { return NULL; } if ((tokens = tok_get_count_st(holder, ';')) <= 1) { st_free(holder); return NULL; } // Allocate an array. if (!(output = ar_alloc((tokens - 1) * 2))) { st_free(holder); return NULL; } for (increment = 1; increment < tokens; increment++) { tok_get_st(holder, ';', increment, ¶meter); if ((key = mail_mime_type_parameters_key(¶meter))) { upper_st(key); ar_append(&output, ARRAY_TYPE_STRINGER, key); ar_append(&output, ARRAY_TYPE_STRINGER, mail_mime_type_parameters_value(¶meter)); } } st_free(holder); if (!ar_length_get(output)) { ar_free(output); return NULL; } return output; }
// Note that we need 1 extra byte for the 0x04 prefix taken from proposed RFC for adding EdDSA to the OpenPGP schema. // https://tools.ietf.org/id/draft-koch-eddsa-for-openpgp.txt void org_signet_free(prime_org_signet_t *org) { if (org) { if (org->signing) ed25519_free(org->signing); if (org->encryption) secp256k1_free(org->encryption); if (org->signature) st_free(org->signature); mm_free(org); } return; }