nanohttp-common.c

Go to the documentation of this file.
00001 /******************************************************************
00002 *  $Id: nanohttp-common.c,v 1.38 2007/01/01 22:54:46 m0gg Exp $
00003 *
00004 * CSOAP Project:  A http client/server library in C
00005 * Copyright (C) 2003  Ferhat Ayaz
00006 *
00007 * This library is free software; you can redistribute it and/or
00008 * modify it under the terms of the GNU Library General Public
00009 * License as published by the Free Software Foundation; either
00010 * version 2 of the License, or (at your option) any later version.
00011 *
00012 * This library is distributed in the hope that it will be useful,
00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 * Library General Public License for more details.
00016 *
00017 * You should have received a copy of the GNU Library General Public
00018 * License along with this library; if not, write to the
00019 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00020 * Boston, MA  02111-1307, USA.
00021 *
00022 * Email: ayaz@jprogrammer.net
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     /* skip white space */
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 /* Content-type stuff */
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   /* 0: searching ';' 1: process key 2: process value */
00277 
00278 
00279   /* Create object */
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   /* TODO (#1#): encoding is always binary. implement also others! */
00388 /*  part->header = hpairnode_new(HEADER_CONTENT_TRANSFER_ENCODING, "binary", part->header);*/
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     /* TODO (#1#): get content-type from mime type list */
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)               /* should be used internally */
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   Free a mime message 
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 /* strtok_r() */
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   /* Scan leading delimiters.  */
00496   s += strspn(s, delim);
00497   if (*s == '\0')
00498     return NULL;
00499 
00500   /* Find the end of the token.  */
00501   token = s;
00502   s = strpbrk(token, delim);
00503   if (s == NULL)
00504     /* This token finishes the string.  */
00505     *save_ptr = strchr(token, '\0');
00506   else
00507   {
00508     /* Terminate the token and make *SAVE_PTR point past it.  */
00509     *s = '\0';
00510     *save_ptr = s + 1;
00511   }
00512   return token;
00513 }
00514 
00515 /* localtime_r() */
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

Generated on Thu Jan 25 23:36:02 2007 for csoap by  doxygen 1.4.6