#include "cbf_file.h"
Go to the source code of this file.
Functions | |
int | cbf_mime_temp (cbf_node *column, unsigned int row) |
int | cbf_nblen (const char *line, int *nblen) |
int | cbf_read_mime (cbf_file *infile, cbf_file *outfile, size_t *size, long *id, char *old_digest, char *new_digest) |
int | cbf_parse_mimeheader (cbf_file *file, int *encoding, size_t *size, long *id, char *digest, unsigned int *compression, int *bits, int *sign) |
int cbf_mime_temp | ( | cbf_node * | column, |
unsigned int | row | ||
) |
Definition at line 167 of file cbf_read_mime.c.
References bits(), CBF_ASCII, cbf_delete_fileconnection(), cbf_failnez, CBF_FORMAT, cbf_get_bintext(), cbf_get_fileposition(), cbf_is_base64digest(), cbf_is_mimebinary(), cbf_onfailnez, cbf_open_temporary(), cbf_read_mime(), cbf_set_bintext(), cbf_set_fileposition(), CBF_TOKEN_TMP_BIN, cbf_node_struct::context, MSG_DIGEST, and cbf_file::read_headers.
Referenced by cbf_binary_parameters(), cbf_check_digest(), cbf_get_binary(), and cbf_write_value().
{ cbf_file *file; cbf_file *temp_file; long start, temp_start; size_t size; int id, bits, sign, type, checked_digest; unsigned int compression; char old_digest [25], *new_digest, digest [25]; /* Check the value */ if (!cbf_is_mimebinary (column, row)) return CBF_ASCII; /* Parse it */ size = 0; cbf_failnez (cbf_get_bintext (column, row, &type, &id, &file, &start, &size, &checked_digest, old_digest, &bits, &sign, &compression)) /* Position the file at the start of the mime section */ cbf_failnez (cbf_set_fileposition (file, start, SEEK_SET)) /* Get the temporary file */ cbf_failnez (cbf_open_temporary (column->context, &temp_file)) /* Move to the end of the temporary file */ cbf_onfailnez (cbf_set_fileposition (temp_file, 0, SEEK_END), cbf_delete_fileconnection (&temp_file)) /* Get the starting location */ cbf_onfailnez (cbf_get_fileposition (temp_file, &temp_start), cbf_delete_fileconnection (&temp_file)) /* Calculate a new digest if necessary */ if (cbf_is_base64digest (old_digest) && (file->read_headers & MSG_DIGEST) && !checked_digest) new_digest = digest; else new_digest = NULL; /* Decode the binary data to the temporary file */ cbf_onfailnez (cbf_read_mime (file, temp_file, NULL, NULL, old_digest, new_digest), cbf_delete_fileconnection (&temp_file)) /* Check the digest */ if (new_digest) if (strcmp (old_digest, new_digest) == 0) checked_digest = 1; else return CBF_FORMAT | cbf_delete_fileconnection (&temp_file); /* Replace the connection */ cbf_onfailnez (cbf_set_bintext (column, row, CBF_TOKEN_TMP_BIN, id, temp_file, temp_start, size, checked_digest, old_digest, bits, sign, compression), cbf_delete_fileconnection (&temp_file)) /* Success */ return 0; }
int cbf_nblen | ( | const char * | line, |
int * | nblen | ||
) |
Definition at line 375 of file cbf_read_mime.c.
Referenced by cbf_lex(), and cbf_parse_mimeheader().
{ register char *myline; register int mylen; *nblen = mylen = 0; if (!(myline = (char *)line)) return 1; for (; *myline; myline++) if (!isspace (*myline)) mylen = myline-(char *)line+1; *nblen = mylen; return 0; }
int cbf_parse_mimeheader | ( | cbf_file * | file, |
int * | encoding, | ||
size_t * | size, | ||
long * | id, | ||
char * | digest, | ||
unsigned int * | compression, | ||
int * | bits, | ||
int * | sign | ||
) |
Definition at line 516 of file cbf_read_mime.c.
References CBF_BYTE_OFFSET, CBF_CANONICAL, cbf_cistrncmp(), cbf_failnez, CBF_FORMAT, cbf_is_blank(), cbf_nblen(), CBF_NONE, CBF_PACKED, CBF_PREDICTOR, cbf_read_line(), cbf_skip_whitespace(), cbf_compress_nodestruct::count, ENC_BASE10, ENC_BASE16, ENC_BASE64, ENC_BASE8, ENC_NONE, and ENC_QP.
Referenced by cbf_lex(), and cbf_read_mime().
{ static const char *value [] = { "Content-Type:", /* State 0 */ "Content-Transfer-Encoding:", /* State 1 */ "X-Binary-Size:", /* State 2 */ "X-Binary-ID:", /* State 3 */ "X-Binary-Element-Type:", /* State 4 */ "Content-MD5:" /* State 5 */ }; const char *line, *c; int state, continuation, item, line_count, fresh_line, quote, text_bits, count, failure, nblen; /* Defaults */ if (encoding) *encoding = 0; if (size) *size = 0; if (id) *id = 0; if (digest) *digest = '\0'; if (compression) *compression = CBF_NONE; if (bits) *bits = 0; if (sign) *sign = -1; /* Read the file line by line */ state = -1; line_count = 0; fresh_line = 0; nblen = 1; while (nblen) { if (!fresh_line) cbf_failnez (cbf_read_line (file, &line)) cbf_nblen(line, &nblen); fresh_line = 0; line_count++; /* Check for premature terminations */ if ( (line[0] == ';') || ( cbf_cistrncmp(line,"--CIF-BINARY-FORMAT-SECTION--",29) == 0 ) ) return CBF_FORMAT; /* Check for a header continuation line */ continuation = line [0] == ' ' || line [0] == '\t'; /* Check for a new item */ if (continuation) item = 0; else { for (c = line; *c != ':' && *c > 32 && *c < 127; c++); item = c != line && *c == ':'; } /* Check for the end of the header */ if (line_count > 1 && cbf_is_blank (line)) return 0; /* Check for valid header-ness of line */ if (!item && (line_count == 1 || !continuation)) return CBF_FORMAT; /* Look for the entries we are interested in */ c = line; if (item) for (state = 5; state > -1; state--) if (cbf_cistrncmp (line, value [state], strlen (value [state])) == 0) { c = line + strlen (value [state]); break; } /* Skip past comments and whitespace */ cbf_failnez (cbf_skip_whitespace (file, &line, &c, &fresh_line)) /* Get the value */ switch (state) { case 0: /* Content */ if (cbf_cistrncmp (c, "application/", 12) != 0 && cbf_cistrncmp (c, "image/", 6) != 0 && cbf_cistrncmp (c, "text/", 5) != 0 && cbf_cistrncmp (c, "audio/", 6) != 0 && cbf_cistrncmp (c, "video/", 6) != 0) return CBF_FORMAT; while (*c) { /* Skip to the end of the section (a semicolon) */ while (*c) if (*c == '\"') { c++; while (*c) if (*c == '\"') { c++; break; } else { if (*c == '\\') c++; if (*c) c++; } } else if (*c == '(') cbf_failnez (cbf_skip_whitespace (file, &line, &c, &fresh_line)) else if (*c == ';') { c++; break; } else c++; /* We are at the end of the section or the end of the item */ cbf_failnez (cbf_skip_whitespace (file, &line, &c, &fresh_line)) if (cbf_cistrncmp (c, "conversions", 11) == 0) { c += 11; cbf_failnez (cbf_skip_whitespace (file, &line, &c, &fresh_line)) if (*c == '=') { c++; cbf_failnez (cbf_skip_whitespace (file, &line, &c, &fresh_line)) if (compression) { quote = 0; if (*c == '\"') quote = 1; *compression = CBF_NONE; if (cbf_cistrncmp (c + quote, "x-cbf_packed", 12) == 0) *compression = CBF_PACKED; if (cbf_cistrncmp (c + quote, "x-cbf_canonical", 15) == 0) *compression = CBF_CANONICAL; if (cbf_cistrncmp (c + quote, "x-cbf_byte_offset", 17) == 0) *compression = CBF_BYTE_OFFSET; if (cbf_cistrncmp (c + quote, "x-cbf_predictor", 15) == 0) *compression = CBF_PREDICTOR; } } } } state = -1; break; case 1: /* Binary encoding */ if (encoding) { failure = 1; quote = 0; if (*c == '\"') quote = 1; if (cbf_cistrncmp (c+quote, "Quoted-Printable", 16) == 0) if (isspace (c [16]) || c [16] == '(' || (quote && c [16] == '\"')) { failure = 0; *encoding = ENC_QP; } if (cbf_cistrncmp (c+quote, "Base64", 6) == 0) if (isspace (c [6]) || c [6] == '(' || (quote && c [16] == '\"')) { failure = 0; *encoding = ENC_BASE64; } if (cbf_cistrncmp (c+quote, "X-Base8", 7) == 0) if (isspace (c [7]) || c [7] == '(' || (quote && c [16] == '\"')) { failure = 0; *encoding = ENC_BASE8; } if (cbf_cistrncmp (c+quote, "X-Base10", 8) == 0) if (isspace (c [8]) || c [8] == '(' || (quote && c [16] == '\"')) { failure = 0; *encoding = ENC_BASE10; } if (cbf_cistrncmp (c+quote, "X-Base16", 8) == 0) if (isspace (c [8]) || c [8] == '(' || (quote && c [16] == '\"')) { failure = 0; *encoding = ENC_BASE16; } if (cbf_cistrncmp (c+quote, "7bit", 4) == 0 || cbf_cistrncmp (c+quote, "8bit", 4) == 0) if (isspace (c [4]) || c [4] == '(' || (quote && c [16] == '\"')) { failure = 0; *encoding = ENC_NONE; } if (cbf_cistrncmp (c+quote, "Binary", 6) == 0) if (isspace (c [6]) || c [6] == '(' || (quote && c [16] == '\"')) { failure = 0; *encoding = ENC_NONE; } } if (failure) return CBF_FORMAT; break; case 2: /* Binary size */ if (size) *size = atol (c); break; case 3: /* Binary ID */ if (id) *id = atol (c); break; case 4: /* Binary element type (signed/unsigned ?-bit integer) */ failure = 3; while (*c) { quote = 0; cbf_failnez (cbf_skip_whitespace (file, &line, &c, &fresh_line)) if (*c == '\"') { if (quote) break; c++; quote++; } if (failure == 3) { if (cbf_cistrncmp (c, "signed", 6) == 0) { c += 6; if (sign) *sign = 1; failure --; } if (cbf_cistrncmp (c, "unsigned", 8) == 0) { c += 8; if (sign) *sign = 0; failure --; } } if (failure == 2) { count = 0; sscanf (c, "%d-%n", &text_bits, &count); if (cbf_cistrncmp (c+count, "bit", 3 ) == 0) if (count && text_bits > 0 && text_bits <= 64) { c += count; if (bits) *bits = text_bits; failure --; } } if (failure == 1) { if (cbf_cistrncmp (c, "integer", 7 ) == 0) failure--; } if (*c) c++; } if (failure) return CBF_FORMAT; break; case 5: /* Message digest */ if (digest) { strncpy (digest, c, 24); digest [24] = '\0'; } break; } } /* Success */ return 0; }
int cbf_read_mime | ( | cbf_file * | infile, |
cbf_file * | outfile, | ||
size_t * | size, | ||
long * | id, | ||
char * | old_digest, | ||
char * | new_digest | ||
) |
Definition at line 272 of file cbf_read_mime.c.
References cbf_failnez, cbf_flush_bits(), CBF_FORMAT, cbf_frombase64(), cbf_frombasex(), cbf_fromqp(), cbf_parse_mimeheader(), cbf_reset_bits(), ENC_BASE10, ENC_BASE16, ENC_BASE64, ENC_BASE8, and ENC_QP.
Referenced by cbf_mime_temp().
{ int encoding; size_t file_size; unsigned int compression; /* Read the header */ encoding = 0; file_size = 0; cbf_failnez (cbf_parse_mimeheader (infile, &encoding, &file_size, id, old_digest, &compression, NULL, NULL)) if (file_size <= 0) return CBF_FORMAT; /* Discard any bits in the buffers */ cbf_failnez (cbf_reset_bits (outfile)) /* Decode the binary data */ switch (encoding) { case ENC_QP: cbf_failnez (cbf_fromqp (infile, outfile, file_size, NULL, new_digest)) break; case ENC_BASE64: cbf_failnez (cbf_frombase64 (infile, outfile, file_size, NULL, new_digest)) break; case ENC_BASE8: case ENC_BASE10: case ENC_BASE16: cbf_failnez (cbf_frombasex (infile, outfile, file_size, NULL, new_digest)) break; default: return CBF_FORMAT; } /* Flush the buffers */ cbf_failnez (cbf_flush_bits (outfile)) /* Size (excluding the encoding) */ if (size) *size = file_size; /* Success */ return 0; }