Logo Search packages:      
Sourcecode: maildrop version File versions  Download package

rfc2045appendurl.c

/*
** Copyright 2000 Double Precision, Inc.  See COPYING for
** distribution information.
*/

/*
** $Id: rfc2045appendurl.c,v 1.4 2003/03/07 00:47:31 mrsam Exp $
*/
#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)
                  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));
}

Generated by  Doxygen 1.6.0   Back to index