summaryrefslogtreecommitdiffstats
path: root/rfc2045/rfc2045appendurl.c
diff options
context:
space:
mode:
authorSam Varshavchik2013-08-19 16:39:41 -0400
committerSam Varshavchik2013-08-25 14:43:51 -0400
commit9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch)
tree7a81a04cb51efb078ee350859a64be2ebc6b8813 /rfc2045/rfc2045appendurl.c
parenta9520698b770168d1f33d6301463bb70a19655ec (diff)
downloadcourier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2
Initial checkin
Imported from subversion report, converted to git. Updated all paths in scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'rfc2045/rfc2045appendurl.c')
-rw-r--r--rfc2045/rfc2045appendurl.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/rfc2045/rfc2045appendurl.c b/rfc2045/rfc2045appendurl.c
new file mode 100644
index 0000000..2f2ce6c
--- /dev/null
+++ b/rfc2045/rfc2045appendurl.c
@@ -0,0 +1,129 @@
+/*
+** Copyright 2000 Double Precision, Inc. See COPYING for
+** distribution information.
+*/
+
+/*
+*/
+#if HAVE_CONFIG_H
+#include "rfc2045_config.h"
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#if HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#include <ctype.h>
+#include "rfc2045.h"
+
+extern void rfc2045_enomem();
+
+/*
+** ---------------------------------------------------------------------
+** Attempt to parse Content-Base: and Content-Location:, and return the
+** "base" of all the relative URLs in the section.
+** ---------------------------------------------------------------------
+*/
+
+static void get_method_path(const char *p,
+ const char **method,
+ unsigned *methodl,
+ const char **path)
+{
+unsigned i;
+
+ for (i=0; p && p[i]; i++)
+ {
+ if (p[i] == ':')
+ {
+ *method=p;
+ *methodl= ++i;
+ *path=p+i;
+ return;
+ }
+
+ if (!isalpha( (int)(unsigned char)p[i]))
+ break;
+ }
+
+ *method=0;
+ *methodl=0;
+ *path=p;
+}
+
+char *rfc2045_append_url(const char *base, const char *loc)
+{
+const char *base_method;
+unsigned base_method_l;
+const char *base_path;
+
+const char *loc_method;
+unsigned loc_method_l;
+const char *loc_path;
+char *buf, *q;
+
+ get_method_path(base, &base_method, &base_method_l, &base_path);
+ get_method_path(loc, &loc_method, &loc_method_l, &loc_path);
+
+ if (loc_method_l)
+ {
+ buf=malloc(strlen(loc)+1);
+ if (!buf)
+ return NULL;
+ else
+ strcpy(buf, loc);
+ return (buf);
+ }
+
+ loc_method=base_method;
+ loc_method_l=base_method_l;
+
+ if (!base_path) base_path="";
+ if (!loc_path) loc_path="";
+
+ buf=malloc(loc_method_l + strlen(base_path)+strlen(loc_path) + 3);
+
+ if (!buf)
+ {
+ return NULL;
+ }
+
+ if (loc_method_l)
+ memcpy(buf, loc_method, loc_method_l);
+ buf[loc_method_l]=0;
+
+ q=buf + loc_method_l;
+
+ strcat(strcpy(q, base_path), "/");
+
+ if ( loc_path[0] == '/')
+ {
+ char *r;
+
+ if (loc_path[1] == '/')
+ /* Location is absolute */
+ {
+ *q=0;
+ }
+
+ /* Relative to top of base */
+
+ else if ( q[0] == '/' && q[1] == '/' &&
+ (r=strchr(q+2, '/')) != 0)
+ {
+ *r=0;
+ }
+ else
+ *q=0; /* No sys in base, just start with / */
+ }
+
+ strcat(q, loc_path);
+
+ return (buf);
+}
+
+char *rfc2045_content_base(struct rfc2045 *p)
+{
+ return (rfc2045_append_url(p->content_base, p->content_location));
+}