.PHONY: all clean
.SUFFIXES: .c .o
-OBJS = main.o sanity.o version.o util.o query.o page.o sha512.o md5.o repo.o $(EXTOBJS)
+OBJS = main.o sanity.o version.o util.o query.o page.o sha512.o md5.o repo.o multipart.o $(EXTOBJS)
all: repoview.cgi
#include "rv_util.h"
#include "rv_db.h"
#include "rv_auth.h"
+#include "rv_multipart.h"
#include <stdlib.h>
#include <string.h>
postdata = malloc(1);
postdata[0] = 0;
int hasauth = 0;
+ int use_multi = 0;
char* type = getenv("CONTENT_TYPE");
if(type == NULL) {
type = rv_strdup("");
type[i] = 0;
i++;
bool found = false;
- rv_error_http();
+ char* bd = NULL;
for(; type[i] != 0; i++) {
if(type[i] != ' ' && type[i] != '\t') {
int j;
char* boundary = type + i;
- for(j = 0; boundary[j] != 0; j++){
- if(boundary[j] == '='){
+ for(j = 0; boundary[j] != 0; j++) {
+ if(boundary[j] == '=') {
boundary[j] = 0;
- printf("%s\n%s\n", boundary, boundary + j + 1);
- found = true;
+ if(strcmp(boundary, "boundary") == 0) {
+ bd = rv_strdup(boundary + j + 1);
+ found = true;
+ }
break;
}
}
}
}
if(!found) {
+ rv_error_http();
printf("Bad multipart/form-data. Parsing fail.");
goto freeall;
+ } else {
+ char* multipart = NULL;
+ unsigned long long length = 0;
+ char buffer[512];
+ while(1) {
+ int len = fread(buffer, 1, 512, stdin);
+ if(length > 0) {
+ char* old = multipart;
+ multipart = malloc(length + len);
+ int i;
+ for(i = 0; i < length; i++) {
+ multipart[i] = old[i];
+ }
+ free(old);
+ memcpy(multipart + length, buffer, len);
+ length += len;
+ } else {
+ length += len;
+ multipart = malloc(length);
+ memcpy(multipart, buffer, len);
+ }
+ if(feof(stdin)) break;
+ }
+ if(multipart != NULL) {
+ rv_parse_multipart(multipart, bd, length);
+ free(multipart);
+ }
}
+ if(bd != NULL) free(bd);
+ use_multi = 1;
break;
}
}
}
- rv_parse_query(postdata);
- rv_save_query('P');
+ if(use_multi == 0) {
+ rv_parse_query(postdata);
+ rv_save_query('P');
+ }
rv_init_auth();
hasauth = 1;
rv_process_page();
printf("Content-Type: text/html\r\n");
printf("\r\n");
rv_print_page();
- rv_load_query('P');
- rv_free_query();
+ if(use_multi == 0) {
+ rv_load_query('P');
+ rv_free_query();
+ }
freeall:
rv_load_query('Q');
rv_free_query();
rv_close_db();
+ rv_free_multipart();
if(hasauth) rv_free_auth();
free(type);
}
--- /dev/null
+/* $Id$ */
+
+#include "rv_multipart.h"
+
+#include "rv_util.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct multipart_entry** multipart_entries = NULL;
+
+void rv_free_multipart(void) {
+ if(multipart_entries == NULL) return;
+ int i;
+ for(i = 0; multipart_entries[i] != NULL; i++) {
+ free(multipart_entries[i]->name);
+ free(multipart_entries[i]->data);
+ free(multipart_entries[i]);
+ }
+ free(multipart_entries);
+}
+
+struct multipart_entry* rv_get_multipart(const char* name) {
+ if(multipart_entries == NULL) return NULL;
+ int i;
+ for(i = 0; multipart_entries[i] != NULL; i++) {
+ if(strcmp(multipart_entries[i]->name, name) == 0) {
+ return multipart_entries[i];
+ }
+ }
+ return NULL;
+}
+
+void rv_parse_multipart(unsigned char* buffer, char* boundary, unsigned long long length) {
+ unsigned long long i;
+ int incr = 0;
+ int phase = 0;
+ unsigned long long fstart = 0;
+ char* b = rv_strcat3("--", boundary, "\r");
+ char* eb = rv_strcat3("--", boundary, "--\r");
+ for(i = 0;; i++) {
+ if(i == length || buffer[i] == '\n') {
+ char* line = malloc(i - incr + 1);
+ memcpy(line, buffer + incr, i - incr);
+ line[i - incr] = 0;
+ if(line[0] == '\r' && phase == 0) {
+ phase = 1;
+ fstart = i + 1;
+ } else if(strcmp(b, line) == 0 || strcmp(eb, line) == 0) {
+ if(phase == 1) {
+ unsigned long long fend = i - strlen(line) - 2;
+ char* data = buffer + fstart;
+ unsigned long long datalen = fend - fstart;
+ }
+ phase = 0;
+ if(strcmp(eb, line) == 0) {
+ free(line);
+ break;
+ }
+ } else if(phase == 0) {
+ line[strlen(line) - 1] = 0;
+ fprintf(stderr, "%s\n", line);
+ }
+ free(line);
+ incr = i + 1;
+ if(i == length) break;
+ }
+ }
+ free(b);
+}
struct query_entry** qentries;
-struct query_entry** query;
-struct query_entry** postquery;
+struct query_entry** query = NULL;
+struct query_entry** postquery = NULL;
void rv_save_query(char c) {
if(c == 'Q') {
char* rv_get_query(const char* key) {
int i;
+ if(qentries == NULL) return NULL;
for(i = 0; qentries[i] != NULL; i++) {
if(strcmp(qentries[i]->key, key) == 0) {
return qentries[i]->value;
--- /dev/null
+/* $Id$ */
+
+#ifndef __RV_MULTIPART_H__
+#define __RV_MULTIPART_H__
+
+struct multipart_entry {
+ unsigned char* data;
+ char* name;
+ unsigned long long length;
+};
+
+void rv_parse_multipart(unsigned char* buffer, char* boundary, unsigned long long length);
+struct multipart_entry* rv_get_multipart(const char* name);
+void rv_free_multipart(void);
+
+#endif