132 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
** Copyright 2000 Double Precision, Inc.  See COPYING for
 | 
						|
** distribution information.
 | 
						|
*/
 | 
						|
 | 
						|
/*
 | 
						|
** $Id$
 | 
						|
*/
 | 
						|
#if    HAVE_CONFIG_H
 | 
						|
#include       "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)
 | 
						|
			rfc2045_enomem();
 | 
						|
		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)
 | 
						|
	{
 | 
						|
		rfc2045_enomem();
 | 
						|
		return (0);
 | 
						|
	}
 | 
						|
 | 
						|
	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));
 | 
						|
}
 |