00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef HAVE_CONFIG_H
00025 #include <config.h>
00026 #endif
00027
00028 #ifdef HAVE_STDIO_H
00029 #include <stdio.h>
00030 #endif
00031
00032 #ifdef HAVE_STDLIB_H
00033 #include <stdlib.h>
00034 #endif
00035
00036 #ifdef HAVE_STDARG_H
00037 #include <stdarg.h>
00038 #endif
00039
00040 #ifdef HAVE_STRING_H
00041 #include <string.h>
00042 #endif
00043
00044 #ifdef HAVE_ERRNO_H
00045 #include <errno.h>
00046 #endif
00047
00048 #ifdef HAVE_CTYPE_H
00049 #include <ctype.h>
00050 #endif
00051
00052 #ifdef HAVE_PTHREAD_H
00053 #include <pthread.h>
00054 #endif
00055
00056 #include "nanohttp-logging.h"
00057 #include "nanohttp-error.h"
00058 #include "nanohttp-common.h"
00059
00060 hpair_t *
00061 hpairnode_new(const char *key, const char *value, hpair_t * next)
00062 {
00063 hpair_t *pair;
00064
00065 log_verbose3("new pair ('%s','%s')", SAVE_STR(key), SAVE_STR(value));
00066 if (!(pair = (hpair_t *) malloc(sizeof(hpair_t))))
00067 {
00068 log_error2("malloc failed (%s)", strerror(errno));
00069 return NULL;
00070 }
00071
00072 if (key != NULL)
00073 {
00074 pair->key = strdup(key);
00075 }
00076 else
00077 {
00078 pair->key = NULL;
00079 }
00080
00081 if (value != NULL)
00082 {
00083 pair->value = strdup(value);
00084 }
00085 else
00086 {
00087 pair->value = NULL;
00088 }
00089
00090 pair->next = next;
00091
00092 return pair;
00093 }
00094
00095 hpair_t *
00096 hpairnode_parse(const char *str, const char *delim, hpair_t * next)
00097 {
00098 hpair_t *pair;
00099 char *key, *value;
00100
00101 pair = (hpair_t *) malloc(sizeof(hpair_t));
00102 pair->key = "";
00103 pair->value = "";
00104 pair->next = next;
00105
00106 key = strtok_r((char *) str, delim, &value);
00107
00108 if (key != NULL)
00109 {
00110 pair->key = strdup(key);
00111 }
00112 if (value != NULL)
00113 {
00114
00115 for (; *value == ' '; value++) ;
00116
00117 pair->value = strdup(value);
00118 }
00119 return pair;
00120 }
00121
00122 hpair_t *
00123 hpairnode_copy(const hpair_t * src)
00124 {
00125 hpair_t *pair;
00126
00127 if (src == NULL)
00128 return NULL;
00129
00130 pair = hpairnode_new(src->key, src->value, NULL);
00131 return pair;
00132 }
00133
00134 hpair_t *
00135 hpairnode_copy_deep(const hpair_t * src)
00136 {
00137 hpair_t *pair, *result, *next;
00138
00139 if (src == NULL)
00140 return NULL;
00141
00142 result = hpairnode_copy(src);
00143
00144 next = src->next;
00145 pair = result;
00146
00147 while (next != NULL)
00148 {
00149 pair->next = hpairnode_copy(next);
00150 pair = pair->next;
00151 next = next->next;
00152 }
00153
00154 return result;
00155 }
00156
00157 void
00158 hpairnode_dump(const hpair_t * pair)
00159 {
00160 if (pair == NULL)
00161 {
00162 log_verbose1("(NULL)[]");
00163 return;
00164 }
00165 log_verbose5("(%p)['%s','%s','%p']", pair,
00166 SAVE_STR(pair->key), SAVE_STR(pair->value), pair->next);
00167
00168 return;
00169 }
00170
00171 void
00172 hpairnode_dump_deep(const hpair_t * pairs)
00173 {
00174 const hpair_t *p;
00175
00176 log_verbose1("-- BEGIN dump_deep hpair_t --");
00177 for (p = pairs; p != NULL; p = p->next)
00178 {
00179 hpairnode_dump(p);
00180 }
00181 log_verbose1("-- END dump_deep hpair_t --\n");
00182
00183 return;
00184 }
00185
00186 void
00187 hpairnode_free(hpair_t * pair)
00188 {
00189 if (pair == NULL)
00190 return;
00191
00192 if (pair->key)
00193 free(pair->key);
00194
00195 if (pair->value)
00196 free(pair->value);
00197
00198 free(pair);
00199
00200 return;
00201 }
00202
00203
00204 void
00205 hpairnode_free_deep(hpair_t * pair)
00206 {
00207 hpair_t *tmp;
00208
00209 while (pair != NULL)
00210 {
00211 tmp = pair->next;
00212 hpairnode_free(pair);
00213 pair = tmp;
00214 }
00215
00216 return;
00217 }
00218
00219 char *
00220 hpairnode_get_ignore_case(hpair_t * pair, const char *key)
00221 {
00222 if (key == NULL)
00223 {
00224 log_error1("key is NULL");
00225 return NULL;
00226 }
00227
00228 while (pair != NULL)
00229 {
00230 if (pair->key != NULL)
00231 {
00232 if (!strcasecmp(pair->key, key))
00233 {
00234 return pair->value;
00235 }
00236 }
00237 pair = pair->next;
00238 }
00239
00240 return NULL;
00241 }
00242
00243 char *
00244 hpairnode_get(hpair_t * pair, const char *key)
00245 {
00246 if (key == NULL)
00247 {
00248 log_error1("key is NULL");
00249 return NULL;
00250 }
00251 while (pair != NULL)
00252 {
00253 if (pair->key != NULL)
00254 {
00255 if (!strcmp(pair->key, key))
00256 {
00257 return pair->value;
00258 }
00259 }
00260 pair = pair->next;
00261 }
00262
00263 return NULL;
00264 }
00265
00266
00267
00268 content_type_t *
00269 content_type_new(const char *content_type_str)
00270 {
00271 hpair_t *pair = NULL, *last = NULL;
00272 content_type_t *ct;
00273 char ch, key[256], value[256];
00274 int inQuote = 0, i = 0, c = 0, begin = 0, len;
00275 int mode = 0;
00276
00277
00278
00279
00280 ct = (content_type_t *) malloc(sizeof(content_type_t));
00281 ct->params = NULL;
00282
00283 len = strlen(content_type_str);
00284 while (i <= len)
00285 {
00286 if (i != len)
00287 ch = content_type_str[i++];
00288 else
00289 {
00290 ch = ' ';
00291 i++;
00292 }
00293
00294 switch (mode)
00295 {
00296 case 0:
00297
00298 if (ch == ';')
00299 {
00300 ct->type[c] = '\0';
00301 c = 0;
00302 mode = 1;
00303 }
00304 else if (ch != ' ' && ch != '\t' && ch != '\r')
00305 ct->type[c++] = ch;
00306 break;
00307
00308 case 1:
00309
00310 if (ch == '=')
00311 {
00312 key[c] = '\0';
00313 c = 0;
00314 mode = 2;
00315 }
00316 else if (ch != ' ' && ch != '\t' && ch != '\r')
00317 key[c++] = ch;
00318 break;
00319
00320 case 2:
00321
00322 if (ch != ' ')
00323 begin = 1;
00324
00325 if ((ch == ' ' || ch == ';') && !inQuote && begin)
00326 {
00327 value[c] = '\0';
00328
00329 pair = hpairnode_new(key, value, NULL);
00330 if (ct->params == NULL)
00331 ct->params = pair;
00332 else
00333 last->next = pair;
00334 last = pair;
00335
00336 c = 0;
00337 begin = 0;
00338 mode = 1;
00339 }
00340 else if (ch == '"')
00341 inQuote = !inQuote;
00342 else if (begin && ch != '\r')
00343 value[c++] = ch;
00344
00345 break;
00346
00347 }
00348 }
00349
00350 return ct;
00351 }
00352
00353 void
00354 content_type_free(content_type_t * ct)
00355 {
00356 if (!ct)
00357 return;
00358
00359 hpairnode_free_deep(ct->params);
00360 free(ct);
00361
00362 return;
00363 }
00364
00365 struct part_t *
00366 part_new(const char *id, const char *filename, const char *content_type, const char *transfer_encoding, struct part_t * next)
00367 {
00368 struct part_t *part;
00369
00370 if (!(part = (struct part_t *) malloc(sizeof(struct part_t))))
00371 {
00372 log_error2("malloc failed (%s)", strerror(errno));
00373 return NULL;
00374 }
00375
00376 part->header = NULL;
00377 part->next = next;
00378 part->deleteOnExit = 0;
00379 strcpy(part->id, id);
00380 strcpy(part->filename, filename);
00381 if (content_type)
00382 strcpy(part->content_type, content_type);
00383 else
00384 part->content_type[0] = '\0';
00385
00386 part->header = hpairnode_new(HEADER_CONTENT_ID, id, part->header);
00387
00388
00389
00390 strcpy(part->transfer_encoding,
00391 transfer_encoding ? transfer_encoding : "binary");
00392
00393 if (content_type)
00394 {
00395 part->header =
00396 hpairnode_new(HEADER_CONTENT_TYPE, content_type, part->header);
00397 }
00398 else
00399 {
00400
00401 }
00402
00403 return part;
00404 }
00405
00406 void
00407 part_free(struct part_t * part)
00408 {
00409 if (part == NULL)
00410 return;
00411
00412 if (part->deleteOnExit)
00413 {
00414 remove(part->filename);
00415 }
00416
00417 hpairnode_free_deep(part->header);
00418
00419 free(part);
00420 }
00421
00422 struct attachments_t *
00423 attachments_new(void)
00424 {
00425 struct attachments_t *attachments;
00426
00427 if (!(attachments = (struct attachments_t *) malloc(sizeof(struct attachments_t))))
00428 {
00429 log_error2("malloc failed (%s)", strerror(errno));
00430 return NULL;
00431 }
00432
00433 attachments->parts = NULL;
00434 attachments->last = NULL;
00435 attachments->root_part = NULL;
00436
00437 return attachments;
00438 }
00439
00440 void
00441 attachments_add_part(struct attachments_t *attachments, struct part_t *part)
00442 {
00443 if (!attachments)
00444 return;
00445
00446 if (attachments->last)
00447 attachments->last->next = part;
00448 else
00449 attachments->parts = part;
00450
00451 attachments->last = part;
00452
00453 return;
00454 }
00455
00456
00457
00458
00459 void
00460 attachments_free(struct attachments_t *message)
00461 {
00462 struct part_t *tmp, *part;
00463
00464 if (!message)
00465 return;
00466
00467 part = message->parts;
00468 while (part)
00469 {
00470 tmp = part->next;
00471 part_free(part);
00472 part = tmp;
00473 }
00474
00475 if (message->root_part)
00476 part_free(message->root_part);
00477
00478 free(message);
00479
00480 return;
00481 }
00482
00483
00484 #ifdef WIN32
00485
00486
00487 char *
00488 strtok_r(char *s, const char *delim, char **save_ptr)
00489 {
00490 char *token;
00491
00492 if (s == NULL)
00493 s = *save_ptr;
00494
00495
00496 s += strspn(s, delim);
00497 if (*s == '\0')
00498 return NULL;
00499
00500
00501 token = s;
00502 s = strpbrk(token, delim);
00503 if (s == NULL)
00504
00505 *save_ptr = strchr(token, '\0');
00506 else
00507 {
00508
00509 *s = '\0';
00510 *save_ptr = s + 1;
00511 }
00512 return token;
00513 }
00514
00515
00516 struct tm *
00517 localtime_r(const time_t * const timep, struct tm *p_tm)
00518 {
00519 static struct tm *tmp;
00520 tmp = localtime(timep);
00521 if (tmp)
00522 {
00523 memcpy(p_tm, tmp, sizeof(struct tm));
00524 tmp = p_tm;
00525 }
00526 return tmp;
00527 }
00528
00529 #endif