|
|
|
@ -153,17 +153,140 @@ static int process_message(GMimeMessage *message, const char *post_dir)
|
|
|
|
|
return cbinfo.count;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Find a sequence of bytes within a binary array. */
|
|
|
|
|
static int find_sequence(char * inbuf, int inlen, char * matchbuf, int matchlen)
|
|
|
|
|
{
|
|
|
|
|
int current;
|
|
|
|
|
int comp;
|
|
|
|
|
int found = 0;
|
|
|
|
|
|
|
|
|
|
for (current = 0; current < inlen-matchlen; current++, inbuf++) {
|
|
|
|
|
if (*inbuf == *matchbuf) {
|
|
|
|
|
found=1;
|
|
|
|
|
for (comp = 1; comp < matchlen; comp++) {
|
|
|
|
|
if (inbuf[comp] != matchbuf[comp]) {
|
|
|
|
|
found = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (found) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (found) {
|
|
|
|
|
return current;
|
|
|
|
|
} else {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The following is a work around to deal with how IE7 embeds the local file name
|
|
|
|
|
* within the Mime header using full WINDOWS file path with backslash directory delimiters.
|
|
|
|
|
* This section of code attempts to isolate the directory path and remove it
|
|
|
|
|
* from what is written into the output file. In addition, it changes
|
|
|
|
|
* esc chars (i.e. backslashes) to forward slashes.
|
|
|
|
|
* This function has two modes. The first to find a boundary marker. The
|
|
|
|
|
* second is to find the filename immediately after the boundary.
|
|
|
|
|
*/
|
|
|
|
|
static int readmimefile(FILE * fin, FILE * fout, char * boundary, int contentlen)
|
|
|
|
|
{
|
|
|
|
|
int find_filename = 0;
|
|
|
|
|
char buf[4096];
|
|
|
|
|
int marker;
|
|
|
|
|
int x;
|
|
|
|
|
int char_in_buf = 0;
|
|
|
|
|
int num_to_read;
|
|
|
|
|
int boundary_len;
|
|
|
|
|
char * path_end, * path_start, * filespec;
|
|
|
|
|
|
|
|
|
|
if (NULL == fin || NULL == fout || NULL == boundary || 0 >= contentlen) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
boundary_len = strlen(boundary);
|
|
|
|
|
while (0 < contentlen || 0 < char_in_buf) {
|
|
|
|
|
/* determine how much I will read into the buffer */
|
|
|
|
|
if (contentlen > sizeof(buf) - char_in_buf) {
|
|
|
|
|
num_to_read = sizeof(buf)- char_in_buf;
|
|
|
|
|
} else {
|
|
|
|
|
num_to_read = contentlen;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(0 < num_to_read) {
|
|
|
|
|
fread(&(buf[char_in_buf]), 1, num_to_read, fin);
|
|
|
|
|
contentlen -= num_to_read;
|
|
|
|
|
char_in_buf += num_to_read;
|
|
|
|
|
}
|
|
|
|
|
/* If I am looking for the filename spec */
|
|
|
|
|
if (find_filename) {
|
|
|
|
|
path_end = filespec = NULL;
|
|
|
|
|
x = strlen("filename=\"");
|
|
|
|
|
marker = find_sequence(buf, char_in_buf, "filename=\"", x );
|
|
|
|
|
if (0 <= marker) {
|
|
|
|
|
marker += x; /* Index beyond the filename marker */
|
|
|
|
|
path_start = &buf[marker];
|
|
|
|
|
for (path_end = path_start, x = 0; x < char_in_buf-marker; x++, path_end++) {
|
|
|
|
|
if ('\\' == *path_end) { /* convert backslashses to forward slashes */
|
|
|
|
|
*path_end = '/';
|
|
|
|
|
}
|
|
|
|
|
if ('\"' == *path_end) { /* If at the end of the file name spec */
|
|
|
|
|
*path_end = '\0'; /* temporarily null terminate the file spec for basename */
|
|
|
|
|
filespec = basename(path_start);
|
|
|
|
|
*path_end = '\"';
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (filespec) { /* If the file name path was found in the header */
|
|
|
|
|
fwrite(buf, 1, marker, fout);
|
|
|
|
|
x = (int)(path_end+1 - filespec);
|
|
|
|
|
fwrite(filespec, 1, x, fout);
|
|
|
|
|
x = (int)(path_end+1 - buf);
|
|
|
|
|
memmove(buf, &(buf[x]), char_in_buf-x);
|
|
|
|
|
char_in_buf -= x;
|
|
|
|
|
}
|
|
|
|
|
find_filename = 0;
|
|
|
|
|
} else { /* I am looking for the boundary marker */
|
|
|
|
|
marker = find_sequence(buf, char_in_buf, boundary, boundary_len);
|
|
|
|
|
if (0 > marker) {
|
|
|
|
|
if (char_in_buf < (boundary_len)) {
|
|
|
|
|
/*no possibility to find the boundary, write all you have */
|
|
|
|
|
fwrite(buf, 1, char_in_buf, fout);
|
|
|
|
|
char_in_buf = 0;
|
|
|
|
|
} else {
|
|
|
|
|
/* write all except for area where the boundary marker could be */
|
|
|
|
|
fwrite(buf, 1, char_in_buf -(boundary_len -1), fout);
|
|
|
|
|
x = char_in_buf -(boundary_len -1);
|
|
|
|
|
memmove(buf, &(buf[x]), char_in_buf-x);
|
|
|
|
|
char_in_buf = (boundary_len -1);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* write up through the boundary, then look for filename in the rest */
|
|
|
|
|
fwrite(buf, 1, marker + boundary_len, fout);
|
|
|
|
|
x = marker + boundary_len;
|
|
|
|
|
memmove(buf, &(buf[x]), char_in_buf-x);
|
|
|
|
|
char_in_buf -= marker + boundary_len;
|
|
|
|
|
find_filename =1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static struct ast_str *http_post_callback(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *vars, struct ast_variable *headers, int *status, char **title, int *contentlength)
|
|
|
|
|
{
|
|
|
|
|
struct ast_variable *var;
|
|
|
|
|
unsigned long ident = 0;
|
|
|
|
|
char buf[4096];
|
|
|
|
|
FILE *f;
|
|
|
|
|
size_t res;
|
|
|
|
|
int content_len = 0;
|
|
|
|
|
struct ast_str *post_dir;
|
|
|
|
|
GMimeMessage *message;
|
|
|
|
|
int message_count = 0;
|
|
|
|
|
char * boundary_marker = NULL;
|
|
|
|
|
|
|
|
|
|
if (!urih) {
|
|
|
|
|
return ast_http_error((*status = 400),
|
|
|
|
@ -213,17 +336,23 @@ static struct ast_str *http_post_callback(struct ast_tcptls_session_instance *se
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
ast_debug(1, "Got a Content-Length of %d\n", content_len);
|
|
|
|
|
} else if (!strcasecmp(var->name, "Content-Type")) {
|
|
|
|
|
boundary_marker = strstr(var->value, "boundary=");
|
|
|
|
|
if (boundary_marker) {
|
|
|
|
|
boundary_marker += strlen("boundary=");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(f, "\r\n");
|
|
|
|
|
|
|
|
|
|
for (res = sizeof(buf); content_len; content_len -= res) {
|
|
|
|
|
if (content_len < res) {
|
|
|
|
|
res = content_len;
|
|
|
|
|
if (0 > readmimefile(ser->f, f, boundary_marker, content_len)) {
|
|
|
|
|
if (option_debug) {
|
|
|
|
|
ast_log(LOG_DEBUG, "Cannot find boundary marker in POST request.\n");
|
|
|
|
|
}
|
|
|
|
|
fread(buf, 1, res, ser->f);
|
|
|
|
|
fwrite(buf, 1, res, f);
|
|
|
|
|
fclose(f);
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (fseek(f, SEEK_SET, 0)) {
|
|
|
|
|