utils.c (3057B)
1 /* This work is in the public domain. See COPYING file for details. */ 2 3 extern int header_sent; 4 5 #include <errno.h> 6 #include <stdarg.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 11 #include "utils.h" 12 13 void 14 fatal(const char *fmt, ...) 15 { 16 va_list ap; 17 18 if (!header_sent) { 19 puts("Content-Type: text/html\r"); 20 puts("Status: 200 OK\r"); 21 puts("\r"); 22 header_sent = TRUE; 23 } 24 25 fputs("ERROR: ", stdout); 26 va_start(ap, fmt); 27 vfprintf(stdout, fmt, ap); 28 va_end(ap); 29 30 if (fmt[0] && fmt[strlen(fmt)-1] == ':') { 31 fprintf(stdout, " %s\n", strerror(errno)); 32 } else { 33 fprintf(stdout, "\n"); 34 } 35 36 exit(1); 37 } 38 39 void * 40 emalloc(size_t size) 41 { 42 void *p; 43 if ((p = malloc(size)) == NULL) 44 fatal("malloc:"); 45 return p; 46 } 47 48 void * 49 ecalloc(size_t nmemb, size_t size) 50 { 51 void *p; 52 if ((p = calloc(nmemb, size)) == NULL) 53 fatal("calloc:"); 54 return p; 55 } 56 57 void * 58 erealloc(void *ptr, size_t size) 59 { 60 void *p; 61 if ((p = realloc(ptr, size)) == NULL) 62 fatal("realloc:"); 63 return p; 64 } 65 66 char * 67 read_file(const char *name) 68 { 69 char *content; 70 long size; 71 FILE *file; 72 73 file = fopen(name, "rb"); 74 if (file == NULL) 75 goto err; 76 if (fseek(file, 0, SEEK_END) != 0) 77 goto err; 78 if ((size = ftell(file)) == -1) 79 goto err; 80 if (fseek(file, 0, SEEK_SET) != 0) 81 goto err; 82 if ((content = malloc((size + 1) * sizeof(char))) == NULL) 83 goto err; 84 if (fread(content, sizeof(char), size, file) != (size_t)size) 85 goto err; 86 fclose(file); 87 (content)[size] = '\0'; 88 return content; 89 err: 90 fatal("%s:", name); 91 return NULL; 92 } 93 94 void 95 parse_html_str(char *str) 96 { 97 char *x, *y, tmp; 98 99 x = y = str; 100 while (*y != '\0') { 101 if (*y == '%') { 102 if (*(y+1) == '\0' || *(y+2) == '\0') 103 fatal("parse_html_str: hex char missing"); 104 tmp = *(y+3); 105 *(y+3) = '\0'; 106 *x = strtol(y+1, NULL, 16); 107 if (*x != 13) /* ignore carriage return */ 108 x++; 109 *(y+3) = tmp; 110 y+=3; 111 } else { 112 if (*y == '+') 113 *y = ' '; 114 *x++ = *y++; 115 } 116 } 117 *x = '\0'; 118 } 119 120 struct input_list * 121 input_list_new(char *url) 122 { 123 struct input_list *head, *tail; 124 char *name, *value; 125 int done; 126 127 head = tail = NULL; 128 done = FALSE; 129 130 if ((url = strchr(url, '?')) == NULL) 131 return NULL; 132 *url++ = '\0'; 133 134 while (!done) { 135 name = url; 136 if ((url = strchr(url, '&')) == NULL) 137 done = TRUE; 138 else 139 *url++ = '\0'; 140 141 if ((value = strchr(name, '=')) == NULL) 142 fatal("parse_url: %s: no value", name); 143 *value++ = '\0'; 144 145 if (head == NULL) { 146 head = tail = ecalloc(1, sizeof(*tail)); 147 } else { 148 tail->next = ecalloc(1, sizeof(*tail)); 149 tail = tail->next; 150 } 151 parse_html_str(name); 152 parse_html_str(value); 153 tail->name = strlen(name) == 0 ? NULL : name; 154 tail->value = strlen(value) == 0 ? NULL : value; 155 } 156 return head; 157 } 158 159 void 160 input_list_free(struct input_list *list) 161 { 162 struct input_list *it, *itn; 163 for (it = list; it != NULL;) { 164 itn = it->next; 165 free(it); 166 it = itn; 167 } 168 } 169 170 char * 171 input_list_find(struct input_list *list, char *name) 172 { 173 struct input_list *it; 174 for (it = list; it != NULL; it = it->next) { 175 if (strcmp(name, it->name) == 0) 176 return it->value; 177 } 178 return NULL; 179 }