/** * @brief Parse a chunk of input into an array of IMAP arguments. * @see imap_parse_qstring(), imap_parse_literal(), imap_parse_array(), imap_parse_astring() * @note This function scans a string for an array of arguments, performing the following logic when a particular character is encountered: * " : Parse argument as quoted string with imap_parse_qstring(). * { : Parse argument as literal string with imap_parse_literal(). * ( or [ : Parse argument as array with imap_parse_astring(). * other : Defaults to parsing argument as atomic string with imap_parse_atomic(). * The supplied start and length pointers will be updated to reflect the input stream if the quoted string is parsed successfully. * @param start the address of a pointer to the start of the buffer to be parsed, that will be continually updated * to point to the next argument in the sequence during the parsing loop. * @param length a pointer to a size_t variable that contains the length of the string to be parsed, that will be continually updated * with the input stream position during the parsing loop. * @return -1 on parsing error or 1 on success. */ int_t imap_parse_arguments(connection_t *con, chr_t **start, size_t *length) { stringer_t *result = NULL; imap_arguments_t *array = NULL; while (*length && **start >= '!' && **start <= '~') { // Quoted strings. if (**start == '"') { if (imap_parse_qstring(&result, start, length) != 1) { return -1; } ar_append(&(con->imap.arguments), IMAP_ARGUMENT_TYPE_QSTRING, result); } // Literal strings. else if (**start == '{') { if (imap_parse_literal(con, &result, start, length) != 1) { return -1; } ar_append(&(con->imap.arguments), IMAP_ARGUMENT_TYPE_LITERAL, result); } // Parenthetical/blocked arrays. else if (**start == '(' || **start == '[') { if (imap_parse_array(0, con, &array, start, length) != 1) { if (array != NULL) { ar_free(array); } return -1; } ar_append(&(con->imap.arguments), IMAP_ARGUMENT_TYPE_ARRAY, array); array = NULL; } // Atomic strings. else if (**start >= '!' && **start <= '~') { if (imap_parse_astring(&result, start, length) != 1) { return -1; } ar_append(&(con->imap.arguments), IMAP_ARGUMENT_TYPE_ASTRING, result); } } return 1; }
/* This function frees all memory associated with the filesystem table. */ void fs_tab_free(void) { int n; if (fs_tab_used == 0) { return; } for (n = 0; n < fs_tab_used; n++) { free(fs_tab[n]->fstype); free(fs_tab[n]->name); free(fs_tab[n]->remote_name); } ar_free(fs_list); }
void imap_session_destroy(connection_t *con) { inx_cursor_t *cursor; meta_message_t *active; meta_user_wlock(con->imap.user); // If a folder was selected, clear the recent flag before closing the mailbox. if (con->imap.session_state == 1 && con->imap.user && con->imap.selected && !con->imap.read_only && (cursor = inx_cursor_alloc(con->imap.user->messages))) { while ((active = inx_cursor_value_next(cursor))) { if (active->foldernum == con->imap.selected && (active->status & MAIL_STATUS_RECENT) == MAIL_STATUS_RECENT) { active->status = (active->status | MAIL_STATUS_RECENT) ^ MAIL_STATUS_RECENT; } } inx_cursor_free(cursor); } meta_user_unlock(con->imap.user); // Is there a user session. if (con->imap.user) { if (con->imap.username) { meta_remove(con->imap.username, META_PROT_IMAP); } } st_cleanup(con->imap.username); st_cleanup(con->imap.tag); st_cleanup(con->imap.command); if (con->imap.arguments) { ar_free(con->imap.arguments); } mail_cache_reset(); return; }
/** * @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; }
/** * @brief Free a mail mime object and its underlying data, and recursively free its children parts. * @param mime a pointer to the mail mime object to be freed. * @return This function returns no value. */ void mail_mime_free(mail_mime_t *mime) { size_t increment, elements; if (!mime) { return; } if (mime->children) { elements = ar_length_get(mime->children); for (increment = 0; increment < elements; increment++) { mail_mime_free((mail_mime_t *)ar_field_ptr(mime->children, increment)); } ar_free(mime->children); } st_cleanup(mime->boundary); mm_free(mime); return; }
/** * @brief Parse a block of data into a mail mime object. * @note By parsing the specified mime part, this function fills in the content type and encoding of the resulting mail mime object. * If the message is multipart, the boundary string is determined and then used to split the body into children; * then each child part is passed to mail_mime_part() to be parsed likewise, recursively. * @param part a managed string containing the mime part data to be parsed. * @param recursion an incremented recursion level tracker for calling this function, to prevent an overflow from occurring. * @return NULL on failure or a pointer to a newly allocated and updated mail mime object parsed from the part data on success. */ mail_mime_t * mail_mime_part(stringer_t *part, uint32_t recursion) { array_t *holder; size_t elements, increment; mail_mime_t *result, *subpart; // Recursion limiter. if (recursion >= MAIL_MIME_RECURSION_LIMIT) { log_pedantic("Recursion limit hit."); return NULL; } if (st_empty(part)) { log_pedantic("Passed an empty placer_t."); return NULL; } if (!(result = mm_alloc(sizeof(mail_mime_t)))) { log_pedantic("Could not allocate %zu bytes for the MIME structure.", sizeof(mail_mime_t)); return NULL; } // Store the entire part, and figure out the length of the header. result->entire = pl_init(st_data_get(part), st_length_get(part)); result->header = mail_mime_header(part); // Check to make sure the header doesn't take up the entire part. if (st_length_get(&(result->header)) != st_length_get(part)) { result->body = pl_init(st_char_get(part) + st_length_get(&(result->header)), st_length_get(part) - st_length_get(&(result->header))); } // Determine the content type. result->type = mail_mime_type(result->header); result->encoding = mail_mime_encoding(result->header); // If were dealing with a multipart message, get the boundary. if ((result->type == MESSAGE_TYPE_MULTI_ALTERNATIVE || result->type == MESSAGE_TYPE_MULTI_MIXED || result->type == MESSAGE_TYPE_MULTI_RELATED || result->type == MESSAGE_TYPE_MULTI_RFC822 || result->type == MESSAGE_TYPE_MULTI_UNKOWN) && (result->boundary = mail_mime_boundary(result->header))) { // Get an array of message parts. if ((holder = mail_mime_split(result->body, result->boundary)) && (elements = ar_length_get(holder))) { if ((result->children = ar_alloc(elements))) { for (increment = 0; increment < elements; increment++) { if ((subpart = mail_mime_part(ar_field_st(holder, increment), recursion + 1))) { if (ar_append(&(result->children), ARRAY_TYPE_POINTER, subpart) != 1) { mail_mime_free(subpart); } } } } } if (holder) { ar_free(holder); } } return result; }
int main(void) { int i, N, L,method; double *inp; int p; double *phi; double *xpred, *amse; ar_object obj; p = 0; L = 5; phi = (double*)malloc(sizeof(double)* p); xpred = (double*)malloc(sizeof(double)* L); amse = (double*)malloc(sizeof(double)* L); FILE *ifp; double temp[2000]; ifp = fopen("seriesA.txt", "r"); i = 0; if (!ifp) { printf("Cannot Open File"); exit(100); } while (!feof(ifp)) { fscanf(ifp, "%lf \n", &temp[i]); i++; } N = i; inp = (double*)malloc(sizeof(double)* N); //wmean = mean(temp, N); for (i = 0; i < N; ++i) { inp[i] = temp[i]; //printf("%g \n",inp[i]); } method = 0; // method 0 - Yule Walker, Method 1 - Burg, Method 2, MLE (Box-Jenkins) obj = ar_init(method, N); ar_exec(obj, inp); ar_summary(obj); // Predict the next 5 values using the obtained ARIMA model ar_predict(obj, inp, L, xpred, amse); printf("\n"); printf("Predicted Values : "); for (i = 0; i < L; ++i) { printf("%g ", xpred[i]); } printf("\n"); printf("Standard Errors : "); for (i = 0; i < L; ++i) { printf("%g ", sqrt(amse[i])); } printf("\n"); ar_free(obj); //ar_estimate(inp, N, 2); free(inp); free(phi); free(xpred); free(amse); return 0; }
/** * @brief Create the data of an outbound smtp message that will be specified with the smtp DATA command. * @param attachments an optional inx holder containing a list of attachments to be included in the message. * @param from a managed string containing the email address sending the message. * @param to an inx holder containing a list of To: email recipients as managed strings. * @param cc an inx holder containing a list of 0 or more CC: recipients as managed strings. * @param bcc an inx holder containing a list of 0 or more BCC: recipients as managed strings. * @param subject a managed string containing the subject of the message. * @param body_plain an optional managed string containing the plain text body of the message. * @param body_html an optional managed string containing the html-formatted body of the message. * @return NULL on failure or a managed string containing the packaged outbound smtp message data on success. */ stringer_t * portal_smtp_create_data(inx_t *attachments, stringer_t *from, inx_t *to, inx_t *cc, inx_t *bcc, stringer_t *subject, stringer_t *body_plain, stringer_t *body_html) { inx_cursor_t *cursor = NULL; array_t *all_attachments = NULL; attachment_t *attachment; stringer_t *result = NULL, *boundary = NULL, *mime_data, *tmp; size_t nattached = 0; if (attachments && (!(cursor = inx_cursor_alloc(attachments)))) { log_pedantic("Unable to read message attachments."); return NULL; } else if (attachments) { while ((attachment = inx_cursor_value_next(cursor))) { // We are creating an array of all the attachment data. It needs to be ARRAY_TYPE_POINTER so deallocating the array doesn't free the underlying data. if (attachment->filedata && !ar_append(&all_attachments, ARRAY_TYPE_POINTER, attachment->filedata)) { log_pedantic("Unable to parse message attachments."); inx_cursor_free(cursor); if (all_attachments) ar_free(all_attachments); return NULL; } } if (all_attachments) { nattached = ar_length_get(all_attachments); } } if (!nattached) { if (cursor) { inx_cursor_free(cursor); } if (!(result = mail_mime_get_smtp_envelope(from, to, cc, bcc, subject, boundary, false))) { log_pedantic("Unable to generate smtp envelope for outbound mail."); return NULL; } } else { // TODO: This should really happen after encoding is performed, but the chances of a collision are still infinitesimal. // Now that we have all the attachment data in an array, we can generate a unique boundary string. if (!(boundary = mail_mime_generate_boundary(all_attachments))) { log_pedantic("Unable to generate boundary for MIME attachments."); inx_cursor_free(cursor); ar_free(all_attachments); return NULL; } ar_free(all_attachments); // Get the envelope for a message that has attachments. if (!(result = mail_mime_get_smtp_envelope(from, to, cc, bcc, subject, boundary, true))) { log_pedantic("Unable to generate smtp envelope for outbound mail."); inx_cursor_free(cursor); st_free(boundary); return NULL; } // Now that we have the envelope, the first content is the actual email body. if (!(tmp = st_merge("snsnsn", result, "--------------", boundary, "\r\nContent-Type: text-plain\r\nContent-Transfer-Encoding: 7bit\r\n\r\n", body_plain, "\r\n"))) { log_pedantic("Unable to pack message body into outbound message."); inx_cursor_free(cursor); st_free(boundary); return NULL; } st_free(result); result = tmp; // Now go through each attachment, encode it, and append it to the envelope. inx_cursor_reset(cursor); while ((attachment = inx_cursor_value_next(cursor))) { if (!(mime_data = mail_mime_encode_part(attachment->filedata, attachment->filename, boundary))) { log_pedantic("Unable to mime encode part for message attachment."); inx_cursor_free(cursor); st_free(boundary); return NULL; } tmp = st_merge("ss", result, mime_data); st_free(mime_data); st_free(result); if (!tmp) { log_pedantic("Unable to allocate space for portal smtp message."); inx_cursor_free(cursor); return NULL; } result = tmp; } inx_cursor_free(cursor); // One final boundary at the end. tmp = st_merge("snsn", result, "\r\n--------------", boundary, "--"); st_free(result); if (!tmp) { log_pedantic("Unable to allocate space for portal smtp message."); return NULL; } result = tmp; } return result; }
/** * @brief Parse an input line containing an IMAP command. * @note This function updates the protocol-specific IMAP structure with parsed values for the session's tag, command, and arguments fields. * Special handling is performed for any command that is preceded by a "UID" prefix. * @param con the IMAP client connection issuing the command. * @return 1 on success or < 0 on error. * -1: the tag could not be read. * -2: the IMAP command could not be read. * -3: the arguments to the IMAP command could not be read. */ int_t imap_command_parser(connection_t *con) { chr_t *holder; size_t length; if (!con) { log_pedantic("Invalid data was passed in for parsing."); return 0; } // Free the previous tag. st_cleanup(con->imap.tag); con->imap.tag = NULL; // Free the previous command. st_cleanup(con->imap.command); con->imap.command = NULL; // Free the previous arguments array. if (con->imap.arguments) { ar_free(con->imap.arguments); con->imap.arguments = NULL; } // Debug info. if (magma.log.imap) { imap_command_log_safe(&con->network.line); } // Get setup. holder = st_data_get(&(con->network.line)); length = st_length_get(&(con->network.line)); // Get the tag. if (imap_parse_astring(&(con->imap.tag), &holder, &length) != 1 || !con->imap.tag) { return -1; } // Get the command. if (imap_parse_astring(&(con->imap.command), &holder, &length) != 1 || !con->imap.command) { return -2; } // Check for the UID modifier. if (!st_cmp_ci_eq(con->imap.command, PLACER("UID", 3))) { con->imap.uid = 1; st_free(con->imap.command); con->imap.command = NULL; if (imap_parse_astring(&(con->imap.command), &holder, &length) != 1 || con->imap.command == NULL) { return -2; } } else if (con->imap.uid == 1) { con->imap.uid = 0; } // Now append the arguments to the array. if (imap_parse_arguments(con, &holder, &length) != 1) { return -3; } // Debug info. /*{ print_ar(0, con->imap.arguments); }*/ return 1; }
/** * @brief Extract the contents of an array argument and advance the position of the parser stream. * * @note This function expects as input a string beginning either with '(' or '['. * @param length a pointer to a size_t variable that contains the length of the string to be parsed, and that will be updated to reflect * the length of the remainder of the input string that follows the parsed literal string. * * @param recursion d * * @param con the client IMAP connection passing the array as input to the server. * @param array - * @param start - * @param length - * @return */ int_t imap_parse_array(int_t recursion, connection_t *con, imap_arguments_t **array, chr_t **start, size_t *length) { chr_t type; stringer_t *result = NULL; imap_arguments_t *inner = NULL; // Recursion limiter. if (recursion >= IMAP_ARRAY_RECURSION_LIMIT) { log_pedantic("Recursion limit hit."); return -1; } if (!*start || !*length) { log_pedantic("Could not parse NULL IMAP argument array."); return -1; } // Skip the opening parentheses. if (**start == '(') { type = ')'; (*start)++; (*length)--; } else if (**start == '[') { type = ']'; (*start)++; (*length)--; } else { return -1; } while (*length && **start != type && **start >= '!' && **start <= '~') { // Quoted strings. if (**start == '"') { if (imap_parse_qstring(&result, start, length) != 1) { return -1; } ar_append(array, IMAP_ARGUMENT_TYPE_QSTRING, result); } // Literal strings. else if (**start == '{') { if (imap_parse_literal(con, &result, start, length) != 1) { return -1; } ar_append(array, IMAP_ARGUMENT_TYPE_LITERAL, result); } // Parenthetical/blocked arrays. else if (**start == '(' || **start == '[') { if (imap_parse_array(recursion + 1, con, &inner, start, length) != 1) { if (inner) { ar_free(inner); } return -1; } ar_append(array, IMAP_ARGUMENT_TYPE_ARRAY, inner); inner = NULL; } // Nil strings. else if (**start >= '!' && **start <= '~') { if (imap_parse_nstring(&result, start, length, type) != 1) { return -1; } ar_append(array, IMAP_ARGUMENT_TYPE_NSTRING, result); } } // Parser error. if (**start != type) { return -1; } // Skip the closing token. if (length && **start == type) { (*start)++; (*length)--; } // Advance a space to the next argument. if (length && **start == ' ') { (*start)++; (*length)--; } return 1; }