Back to index

courier  0.68.2
rfc2045appendurl.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 2000 Double Precision, Inc.  See COPYING for
00003 ** distribution information.
00004 */
00005 
00006 /*
00007 */
00008 #if    HAVE_CONFIG_H
00009 #include       "rfc2045_config.h"
00010 #endif
00011 #include       <stdlib.h>
00012 #include       <stdio.h>
00013 #include       <string.h>
00014 #if    HAVE_STRINGS_H
00015 #include       <strings.h>
00016 #endif
00017 #include      <ctype.h>
00018 #include      "rfc2045.h"
00019 
00020 extern void rfc2045_enomem();
00021 
00022 /*
00023 ** ---------------------------------------------------------------------
00024 ** Attempt to parse Content-Base: and Content-Location:, and return the
00025 ** "base" of all the relative URLs in the section.
00026 ** ---------------------------------------------------------------------
00027 */
00028 
00029 static void get_method_path(const char *p,
00030        const char **method,
00031        unsigned *methodl,
00032        const char **path)
00033 {
00034 unsigned      i;
00035 
00036        for (i=0; p && p[i]; i++)
00037        {
00038               if (p[i] == ':')
00039               {
00040                      *method=p;
00041                      *methodl= ++i;
00042                      *path=p+i;
00043                      return;
00044               }
00045 
00046               if (!isalpha( (int)(unsigned char)p[i]))
00047                      break;
00048        }
00049 
00050        *method=0;
00051        *methodl=0;
00052        *path=p;
00053 }
00054 
00055 char *rfc2045_append_url(const char *base, const char *loc)
00056 {
00057 const char *base_method;
00058 unsigned base_method_l;
00059 const char *base_path;
00060 
00061 const char *loc_method;
00062 unsigned loc_method_l;
00063 const char *loc_path;
00064 char *buf, *q;
00065 
00066        get_method_path(base, &base_method, &base_method_l, &base_path);
00067        get_method_path(loc, &loc_method, &loc_method_l, &loc_path);
00068 
00069        if (loc_method_l)
00070        {
00071               buf=malloc(strlen(loc)+1);
00072               if (!buf)
00073                      return NULL;
00074               else
00075                      strcpy(buf, loc);
00076               return (buf);
00077        }
00078 
00079        loc_method=base_method;
00080        loc_method_l=base_method_l;
00081 
00082        if (!base_path)      base_path="";
00083        if (!loc_path)       loc_path="";
00084 
00085        buf=malloc(loc_method_l + strlen(base_path)+strlen(loc_path) + 3);
00086 
00087        if (!buf)
00088        {
00089               return NULL;
00090        }
00091 
00092        if (loc_method_l)
00093               memcpy(buf, loc_method, loc_method_l);
00094        buf[loc_method_l]=0;
00095 
00096        q=buf + loc_method_l;
00097 
00098        strcat(strcpy(q, base_path), "/");
00099 
00100        if ( loc_path[0] == '/')
00101        {
00102        char *r;
00103 
00104               if (loc_path[1] == '/')
00105                      /* Location is absolute */
00106               {
00107                      *q=0;
00108               }
00109 
00110               /* Relative to top of base */
00111 
00112               else if ( q[0] == '/' && q[1] == '/' &&
00113                      (r=strchr(q+2, '/')) != 0)
00114               {
00115                      *r=0;
00116               }
00117               else
00118                      *q=0;  /* No sys in base, just start with / */
00119        }
00120 
00121        strcat(q, loc_path);
00122 
00123        return (buf);
00124 }
00125 
00126 char *rfc2045_content_base(struct rfc2045 *p)
00127 {
00128        return (rfc2045_append_url(p->content_base, p->content_location));
00129 }