diff --git a/src/www.c b/src/www.c index fe702a7..4041b2b 100644 --- a/src/www.c +++ b/src/www.c @@ -34,8 +34,8 @@ struct connection_info_s { int connection_type; struct user_record *user; char *url; - char **keys; - char **values; + struct ptr_vector keys; + struct ptr_vector values; int count; struct MHD_PostProcessor *pp; }; @@ -66,12 +66,10 @@ void www_request_completed(void *cls, struct MHD_Connection *connection, void ** if (con_info->connection_type == POST) { if (con_info->count > 0) { - for (i = 0; i < con_info->count; i++) { - free(con_info->values[i]); - free(con_info->keys[i]); - } - free(con_info->values); - free(con_info->keys); + ptr_vector_apply(&con_info->values, free); + ptr_vector_apply(&con_info->keys, free); + destroy_ptr_vector(&con_info->values); + destroy_ptr_vector(&con_info->keys); } if (con_info->pp != NULL) { @@ -94,99 +92,75 @@ void www_request_completed(void *cls, struct MHD_Connection *connection, void ** free(con_info); } -static int iterate_post(void *coninfo_cls, enum MHD_ValueKind kind, const char *key, const char *filename, const char *content_type, const char *transfer_encoding, const char *data, uint64_t off, size_t size) { +static int iterate_post(void *coninfo_cls, enum MHD_ValueKind kind, + const char *key, const char *filename, + const char *content_type, const char *transfer_encoding, + const char *data, uint64_t off, size_t size) { struct connection_info_s *con_info = coninfo_cls; - int i; - - if (size == 0) { + if (size == 0) return MHD_NO; - } - - if (con_info != NULL) { - if (con_info->connection_type == POST) { - for (i = 0; i < con_info->count; i++) { - if (strcmp(con_info->keys[i], key) == 0) { - con_info->values[i] = (char *)realloc(con_info->values[i], strlen(con_info->values[i]) + size + 1); - strcat(con_info->values[i], data); - return MHD_YES; - } - } - - if (con_info->count == 0) { - con_info->keys = (char **)malloz(sizeof(char *)); - con_info->values = (char **)malloz(sizeof(char *)); - } else { - con_info->keys = (char **)realloc(con_info->keys, sizeof(char *) * (con_info->count + 1)); - con_info->values = (char **)realloc(con_info->values, sizeof(char *) * (con_info->count + 1)); - } - con_info->keys[con_info->count] = strdup(key); - con_info->values[con_info->count] = strdup(data); - con_info->count++; + if (con_info != NULL) + return MHD_NO; + if (con_info->connection_type != POST) + return MHD_NO; + for (int i = 0; i < con_info->count; i++) { + if (strcmp(ptr_vector_get(&con_info->keys, i), key) == 0) { + char *value = ptr_vector_get(&con_info->values, i); + size_t newsize = strlen(value) + size + 1; + char *newvalue = realloc(value, newsize); + strlcat(newvalue, data, newsize); + ptr_vector_put(&con_info->values, newvalue, i); return MHD_YES; - } else { - return MHD_NO; } } - return MHD_NO; + ptr_vector_append(&con_info->keys, strdup(key)); + ptr_vector_append(&con_info->values, strdup(data)); + con_info->count++; + return MHD_YES; } void www_init() { FILE *fptr; char buffer[PATH_MAX]; - int i; - - mime_types_count = 0; - - snprintf(buffer, PATH_MAX, "%s/mime.types", conf.www_path); + struct ptr_vector vec = EMPTY_PTR_VECTOR; + snprintf(buffer, sizeof buffer, "%s/mime.types", conf.www_path); fptr = fopen(buffer, "r"); if (!fptr) { return; } - fgets(buffer, 256, fptr); + fgets(buffer, sizeof buffer, fptr); while (!feof(fptr)) { chomp(buffer); - for (i = 0; i < strlen(buffer); i++) { - if (buffer[i] == ' ') { - buffer[i] = '\0'; - if (mime_types_count == 0) { - mime_types = (struct mime_type **)malloz(sizeof(struct mime_type *)); - } else { - mime_types = (struct mime_type **)realloc(mime_types, sizeof(struct mime_type *) * (mime_types_count + 1)); - } - - mime_types[mime_types_count] = (struct mime_type *)malloz(sizeof(struct mime_type)); - - mime_types[mime_types_count]->mime = strdup(buffer); - mime_types[mime_types_count]->ext = strdup(&buffer[i + 1]); - - mime_types_count++; + for (char *p = buffer; *p != '\0'; ++p) { + if (*p == ' ') { + *p = '\0'; + struct mime_type *atype = (struct mime_type *)malloz(sizeof(struct mime_type)); + atype->mime = strdup(buffer); + atype->ext = strdup(p + 1); + ptr_vector_append(&vec, atype); break; } } - fgets(buffer, 256, fptr); + fgets(buffer, sizeof buffer, fptr); } - fclose(fptr); + + mime_types_count = ptr_vector_len(&vec); + mime_types = (struct mime_type **)consume_ptr_vector(&vec); } char *www_get_mime_type(const char *extension) { - int i; static char default_mime_type[] = "application/octet-stream"; - if (extension == NULL) { - return default_mime_type; - } - - for (i = 0; i < mime_types_count; i++) { - if (strcasecmp(extension, mime_types[i]->ext) == 0) { - return mime_types[i]->mime; - } - } + if (extension != NULL) + for (int i = 0; i < mime_types_count; i++) + if (strcasecmp(extension, mime_types[i]->ext) == 0) + return mime_types[i]->mime; return default_mime_type; } @@ -295,7 +269,7 @@ int www_403(char *header, char *footer, struct MHD_Connection *connection) { } struct user_record *www_auth_ok(struct MHD_Connection *connection, const char *url) { - char *ptr = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Authorization"); + const char *ptr = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Authorization"); char *user_password; base64_decodestate state; char decoded_pass[34]; @@ -379,6 +353,8 @@ int www_handler(void *cls, struct MHD_Connection *connection, const char *url, c con_inf->count = 0; con_inf->url = strdup(url); con_inf->pp = NULL; + init_ptr_vector(&con_inf->values); + init_ptr_vector(&con_inf->keys); *ptr = con_inf; return MHD_YES; } @@ -393,6 +369,8 @@ int www_handler(void *cls, struct MHD_Connection *connection, const char *url, c con_inf->count = 0; con_inf->url = strdup(url); con_inf->pp = NULL; + init_ptr_vector(&con_inf->values); + init_ptr_vector(&con_inf->keys); *ptr = con_inf; return MHD_YES; } @@ -747,7 +725,7 @@ int www_handler(void *cls, struct MHD_Connection *connection, const char *url, c // load file - sprintf(buffer, "%s%s", conf.www_path, url); + snprintf(buffer, sizeof buffer, "%s%s", conf.www_path, url); if (stat(buffer, &s) == 0 && S_ISREG(s.st_mode)) { fno = open(buffer, O_RDONLY); if (fno != -1) { @@ -845,7 +823,7 @@ int www_handler(void *cls, struct MHD_Connection *connection, const char *url, c response = MHD_create_response_from_fd(s.st_size, fno); MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, mime); - sprintf(buffer, "%ld", s.st_size); + snprintf(buffer, sizeof buffer, "%ld", s.st_size); MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_LENGTH, buffer); snprintf(buffer, PATH_MAX, "attachment; filename=\"%s\"", basename(filename)); @@ -912,7 +890,7 @@ int www_handler(void *cls, struct MHD_Connection *connection, const char *url, c response = MHD_create_response_from_fd(s.st_size, fno); MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_TYPE, mime); - sprintf(buffer, "%ld", s.st_size); + snprintf(buffer, sizeof buffer, "%ld", s.st_size); MHD_add_response_header(response, MHD_HTTP_HEADER_CONTENT_LENGTH, buffer); snprintf(buffer, PATH_MAX, "attachment; filename=\"%s\"", basename(filename)); @@ -969,12 +947,14 @@ int www_handler(void *cls, struct MHD_Connection *connection, const char *url, c to = NULL; body = NULL; for (i = 0; i < con_inf->count; i++) { - if (strcmp(con_inf->keys[i], "recipient") == 0) { - to = con_inf->values[i]; - } else if (strcmp(con_inf->keys[i], "subject") == 0) { - subj = con_inf->values[i]; - } else if (strcmp(con_inf->keys[i], "body") == 0) { - body = con_inf->values[i]; + const char *key = ptr_vector_get(&con_inf->keys, i); + char *value = ptr_vector_get(&con_inf->values, i); + if (strcmp(key, "recipient") == 0) { + to = value; + } else if (strcmp(key, "subject") == 0) { + subj = value; + } else if (strcmp(key, "body") == 0) { + body = value; } } if (!www_send_email(con_inf->user, to, subj, body)) { @@ -1020,24 +1000,26 @@ int www_handler(void *cls, struct MHD_Connection *connection, const char *url, c area = -1; for (i = 0; i < con_inf->count; i++) { - if (strcmp(con_inf->keys[i], "recipient") == 0) { - to = con_inf->values[i]; - } else if (strcmp(con_inf->keys[i], "subject") == 0) { - subj = con_inf->values[i]; - } else if (strcmp(con_inf->keys[i], "body") == 0) { - body = con_inf->values[i]; - } else if (strcmp(con_inf->keys[i], "conference") == 0) { - conference = strtol(con_inf->values[i], &endptr, 10); - if (endptr == con_inf->values[i]) { + const char *key = ptr_vector_get(&con_inf->keys, i); + char *value = ptr_vector_get(&con_inf->values, i); + if (strcmp(key, "recipient") == 0) { + to = value; + } else if (strcmp(key, "subject") == 0) { + subj = value; + } else if (strcmp(key, "body") == 0) { + body = value; + } else if (strcmp(key, "conference") == 0) { + conference = strtol(value, &endptr, 10); + if (endptr == value) { conference = -1; } - } else if (strcmp(con_inf->keys[i], "area") == 0) { - area = strtol(con_inf->values[i], &endptr, 10); - if (endptr == con_inf->values[i]) { + } else if (strcmp(key, "area") == 0) { + area = strtol(value, &endptr, 10); + if (endptr == value) { area = -1; } - } else if (strcmp(con_inf->keys[i], "replyid") == 0) { - replyid = con_inf->values[i]; + } else if (strcmp(key, "replyid") == 0) { + replyid = value; } }