File:  [Public] / Amaya / amaya / AHTURLTools.c
Revision 1.14: download - view: text, annotated - select for diffs
Thu Jan 23 08:08:12 1997 UTC (27 years, 4 months ago) by cvs
Branches: MAIN
CVS tags: THOT_2_0a, HEAD, AMAYA_0_95a
Fix bug of mailto.
Irene

/*
 *
 *  (c) COPYRIGHT MIT and INRIA, 1996.
 *  Please first read the full copyright statement in file COPYRIGHT.
 *
 */

/*
 * AHTURLTools.c: contains all the functions for testing, manipulating,
 * and normalizing URLs.
 *
 * Authors: J. Kahan, I. Vatton
 *
 */
 
/* Amaya includes  */
#define EXPORT extern
#include "amaya.h"


#include "init_f.h"
#include "AHTURLTools_f.h"

/*----------------------------------------------------------------------
  ExplodeURL 
  ----------------------------------------------------------------------*/

#ifdef __STDC__
void                ExplodeURL (char *url, char **proto, char **host, char **dir, char **file)
#else
void                ExplodeURL (url, proto, host, dir, file)
char               *url;
char              **proto;
char              **host;
char              **dir;
char              **file;

#endif
{
   char               *curr, *temp;

   if ((url == NULL) || (proto == NULL) || (host == NULL) ||
       (dir == NULL) || (file == NULL))
      return;

   /* initialize every pointer */
   *proto = *host = *dir = *file = NULL;

   /* skip any leading space */
   while ((*url == SPACE) || (*url == TAB))
      url++;
   curr = url;
   if (*curr == 0)
      goto finished;

   /* go to the end of the URL */
   while ((*curr != 0) && (*curr != SPACE) && (*curr != '\b') &&
	  (*curr != '\r') && (*curr != EOL))
      curr++;

   /* mark the end of the chain */
   *curr = EOS;
   curr--;
   if (curr <= url)
      goto finished;

   /* search the next DIR_SEP indicating the beginning of the file name */
   do
     curr--;
   while ((curr >= url) && (*curr != DIR_SEP));

   if (curr < url)
      goto finished;
   *file = curr + 1;

   /* mark the end of the dir */
   *curr = EOS;
   curr--;
   if (curr < url)
      goto finished;

   /* search for the "/" indicating the host name start */
   while ((curr > url) && ((*curr != DIR_SEP) || (*(curr + 1) != DIR_SEP)))
      curr--;

   /* if we found it, separate the host name from the directory */
   if ((*curr == DIR_SEP) && (*(curr + 1) == DIR_SEP))
     {
	*host = temp = curr + 2;
	while ((*temp != 0) && (*temp != DIR_SEP))
	   temp++;
	if (*temp == DIR_SEP)
	  {
	     *temp = EOS;
	     *dir = temp + 1;
	  }
     }
   else
     *dir = curr;

   if (curr <= url)
      goto finished;

   /* mark the end of the proto */
   *curr = EOS;
   curr--;
   if (curr < url)
      goto finished;

   if (*curr == ':')
     {
	*curr = EOS;
	curr--;
     }
   else
      goto finished;

   if (curr < url)
      goto finished;
   while ((curr > url) && (isalpha (*curr)))
      curr--;
   *proto = curr;

 finished:;

#ifdef AMAYA_DEBUG
   fprintf (stderr, "ExplodeURL(%s)\n\t", url);
   if (*proto)
      fprintf (stderr, "proto : %s, ", *proto);
   if (*host)
      fprintf (stderr, "host : %s, ", *host);
   if (*dir)
      fprintf (stderr, "dir : %s, ", *dir);
   if (*file)
      fprintf (stderr, "file : %s ", *file);
   fprintf (stderr, "\n");
#endif

}

/*----------------------------------------------------------------------
  IsHTMLName                                                         
  returns TRUE if path points to an HTML resource.
  ----------------------------------------------------------------------*/
#ifdef __STDC__
boolean             IsHTMLName (char *path)
#else  /* __STDC__ */
boolean             IsHTMLName (path)
char               *path;
#endif /* __STDC__ */
{
   char                temppath[MAX_LENGTH];
   char                suffix[MAX_LENGTH];
   char                nsuffix[MAX_LENGTH];
   int                 i;

   if (!path)
     return (FALSE);

   strcpy (temppath, path);
   ExtractSuffix (temppath, suffix);

   /* Normalize the suffix */
   i = 0;
   while (suffix[i] != EOS)
     {
       nsuffix[i] = TOLOWER (suffix[i]);
       i++;
     }
   nsuffix[i] = EOS;
   if ((strcmp (nsuffix, "html")) &&
       (strcmp (nsuffix, "htm")) &&
       (strcmp (nsuffix, "shtml")))
     return (FALSE);
   else if ((!strcmp (nsuffix, "gz")) ||
	    (!strcmp (nsuffix, "Z")))
     {
       /* take in account compressed files */
       ExtractSuffix (temppath, suffix);       
       /* Normalize the suffix */
       i = 0;
       while (suffix[i] != EOS)
	 {
	   nsuffix[i] = TOLOWER (suffix[i]);
	   i++;
	 }
       nsuffix[i] = EOS;
       if ((strcmp (nsuffix, "html")) &&
	   (strcmp (nsuffix, "htm")) &&
	   (strcmp (nsuffix, "shtml")))
	 return (FALSE);
       else
	 return (TRUE);
     }
   else
     return (TRUE);
}

/*----------------------------------------------------------------------
  IsImageName                                
  returns TRUE if path points to an image resource.
  ----------------------------------------------------------------------*/
#ifdef __STDC__
boolean             IsImageName (char *path)
#else  /* __STDC__ */
boolean             IsImageName (path)
char               *path;
#endif /* __STDC__ */
{
   char                temppath[MAX_LENGTH];
   char                suffix[MAX_LENGTH];
   char                nsuffix[MAX_LENGTH];
   int                 i;

   if (!path)
      return (FALSE);

   strcpy (temppath, path);
   ExtractSuffix (temppath, suffix);

   /* Normalize the suffix */
   i = 0;
   while (suffix[i] != EOS)
     {
       nsuffix[i] = TOLOWER (suffix[i]);
       i++;
     }
   nsuffix[i] = EOS;
   if ((strcmp (nsuffix, "gif")) && (strcmp (nsuffix, "xbm")) &&
       (strcmp (nsuffix, "xpm")) && (strcmp (nsuffix, "jpg")) &&
       (strcmp (nsuffix, "png")) && (strcmp (nsuffix, "au")))
      return (FALSE);
   return (TRUE);
}

/*----------------------------------------------------------------------
  IsTextName                                                         
  ----------------------------------------------------------------------*/
#ifdef __STDC__
boolean             IsTextName (char *path)
#else  /* __STDC__ */
boolean             IsTextName (path)
char               *path;

#endif /* __STDC__ */
{
   char                temppath[MAX_LENGTH];
   char                suffix[MAX_LENGTH];
   char                nsuffix[MAX_LENGTH];
   int                 i;

   if (!path)
     return (FALSE);

   strcpy (temppath, path);
   ExtractSuffix (temppath, suffix);

   /* Normalize the suffix */
   i = 0;
   while (suffix[i] != EOS)
     {
	nsuffix[i] = TOLOWER (suffix[i]);
	i++;
     }
   nsuffix[i] = EOS;

   if ((strcmp (nsuffix, "gif")) && (strcmp (nsuffix, "xbm")) &&
       (strcmp (nsuffix, "xpm")) && (strcmp (nsuffix, "jpg")) &&
       (strcmp (nsuffix, "pdf")) && (strcmp (nsuffix, "png")) &&
       (strcmp (nsuffix, "tgz")) && (strcmp (nsuffix, "xpg")) &&
       (strcmp (nsuffix, "xpd")) && (strcmp (nsuffix, "ps")) &&
       (strcmp (nsuffix, "au")))
      return (TRUE);
   else if ((!strcmp (nsuffix, "gz")) || (!strcmp (nsuffix, "Z")))
     {
       /* take in account compressed files */
       ExtractSuffix (temppath, suffix);       
       /* Normalize the suffix */
       i = 0;
       while (suffix[i] != EOS)
	 {
	   nsuffix[i] = TOLOWER (suffix[i]);
	   i++;
	 }
       nsuffix[i] = EOS;
       if ((!strcmp (nsuffix, "html")) ||
	   (!strcmp (nsuffix, "htm")) ||
	   (!strcmp (nsuffix, "shtml")))
	 return (TRUE);
       else
	 return (FALSE);
     }
   else
     return (FALSE);
}

/*----------------------------------------------------------------------
  IsHTTPPath                                     
  returns TRUE if path is in fact an http URL.
  ----------------------------------------------------------------------*/
#ifdef __STDC__
boolean             IsHTTPPath (char *path)
#else  /* __STDC__ */
boolean             IsHTTPPath (path)
char               *path;
#endif /* __STDC__ */
{
   if (!path)
      return FALSE;

   if (strncmp (path, "http:", 5) != 0)
      return FALSE;
   return TRUE;
}

/*----------------------------------------------------------------------
  IsWithParameters                           
  returns TRUE if url has a concatenated query string.
  ----------------------------------------------------------------------*/
#ifdef __STDC__
boolean             IsWithParameters (char *url)
#else  /* __STDC__ */
boolean             IsWithParameters (url)
char               *url;
#endif /* __STDC__ */
{
   int                 i;

   if ((!url) || (url[0] == EOS))
      return FALSE;

   i = strlen (url) - 1;
   while (i > 0 && url[i--] != '?')
      if (i < 0)
	 return FALSE;

   /* There is a parameter */
   return TRUE;
}

/*----------------------------------------------------------------------
  IsW3Path                                           
  returns TRUE if path is in fact a URL.
  ----------------------------------------------------------------------*/
#ifdef __STDC__
boolean             IsW3Path (char *path)
#else  /* __STDC__ */
boolean             IsW3Path (path)
char               *path;
#endif /* __STDC__ */
{
   if ((strncmp (path, "http:", 5)) && (strncmp (path, "ftp:", 4)) &&
       (strncmp (path, "telnet:", 7)) && (strncmp (path, "wais:", 5)) &&
       (strncmp (path, "news:", 5)) && (strncmp (path, "gopher:", 7)) &&
       (strncmp (path, "mailto:", 7)) && (strncmp (path, "archie:", 7)))
      return FALSE;
   return TRUE;
}

/*----------------------------------------------------------------------
  IsValidProtocol                                                    
  returns true if the url protocol is supported by Amaya.
  ----------------------------------------------------------------------*/
#ifdef __STDC__
boolean             IsValidProtocol (char *url)
#else  /* __STDC__ */
boolean             IsValidProtocol (url)
char               *url;
#endif /* __STDC__ */
{
   if (!strncmp (url, "http:", 5)
      /***|| !strncmp (path, "ftp:", 4)
      || !strncmp (path, "news:", 5)***/ )
      return (TRUE);
   else
      return (FALSE);
}

/*----------------------------------------------------------------------
   NormalizeURL
   normalizes orgName according to a base associated with doc, and
   following the standard URL format rules.
   The function returns the new complete and normalized URL 
   or file name path (newName) and the name of the document (docName).        
   N.B. If the function can't find out what's the docName, it assigns
   the name "noname.html".
  ----------------------------------------------------------------------*/
#ifdef __STDC__
void                NormalizeURL (char *orgName, Document doc, char *newName, char *docName)
#else  /* __STDC__ */
void                NormalizeURL (orgName, doc, newName, docName)
char               *orgName;
Document            doc;
char               *newName;
char               *docName;
#endif /* __STDC__ */
{
   char                basename[MAX_LENGTH];
   char                tempname[MAX_LENGTH];
   int                 i;
   char               *ptr;
   char               *basename_ptr;
   int                 basename_flag;
   Element             el;
   ElementType         elType;
   AttributeType       attrType;
   Attribute           attrHREF;
   int                 length;

   /* Fix up orgName, by erasing leading and trailing white space */
   if (!newName || !docName)
      return;
   ptr = orgName;
   while (*ptr == ' ' && *ptr++ != EOS) ;
   strcpy (tempname, ptr);
   ptr = strchr (tempname, ' ');
   if (ptr)
      *ptr = EOS;

   if (IsW3Path (tempname))
     /* the name is complete */
     strcpy (newName, tempname);
   else
     {
       if (doc)
	 {
	   /* take into account the BASE element. */
	   length = MAX_LENGTH;
	   /* get the root element    */
	   el = TtaGetMainRoot (doc);
	   
	   /* search the BASE element */
	   elType.ElSSchema = TtaGetDocumentSSchema (doc);
	   elType.ElTypeNum = HTML_EL_BASE;
	   el = TtaSearchTypedElement (elType, SearchInTree, el);
	   if (el)
	     {
	       /* 
	       ** The document has a BASE element 
	       ** Get the HREF attribute of the BASE Element 
	       */
	       attrType.AttrSSchema = elType.ElSSchema;
	       attrType.AttrTypeNum = HTML_ATTR_HREF_;
	       attrHREF = TtaGetAttribute (el, attrType);
	       if (attrHREF)
		 {
		   /* Use the base path of the document */
		   TtaGiveTextAttributeValue (attrHREF, basename, &length);
		   /* base and orgName have to be separated by a DIR_SEP */
		   if (basename[strlen (basename) - 1] != DIR_SEP)
		     {
		       if (IsHTMLName (basename))
			 {
			   /* remove the document name from basename */
			   length = strlen (basename) - 1;
			   while (basename[length] != DIR_SEP)
			     basename[length--] = EOS;
			 }
		       else if (tempname[0] != DIR_SEP)
			 strcat (basename, DIR_STR);
		     }
		 }
	       else
		 basename[0] = EOS;
	     }
	   else
	     basename[0] = EOS;
	 }
       else
	 basename[0] = EOS;
       
       if (basename[0] == EOS)
	 {
	   /* there is no BASE element in that document. */
	   if (DocumentURLs[(int) doc])
	     {
	       basename_ptr = HTParse (DocumentURLs[(int) doc], "", PARSE_ALL);
	       basename_flag = TRUE;
	     }
	   else
	     {
	       basename_ptr = "";
	       basename_flag = FALSE;
	     }
	 }
       else
	 {
	   basename_ptr = HTParse (basename, "", PARSE_ALL);
	   basename_flag = TRUE;
	 }
       
       ptr = HTParse (tempname, basename_ptr, PARSE_ALL);
       if (basename_flag)
	 HT_FREE (basename_ptr);
       if (ptr)
	 {
	   ptr = HTSimplify (&ptr);
	   strcpy (newName, ptr);
	   HT_FREE (ptr);
	 }
       else
	 newName[0] = EOS;
     }

   i = strlen (newName) - 1;
   if (i > 0)
     {
       /* search now the document name */
       ptr = strrchr (newName, DIR_SEP);
       if (ptr)
	 ptr++;
       if (ptr && *ptr != EOS)
	 strcpy (docName, ptr);
       else
	 /* the docname was not comprised inside the URL, so let's */
	 /* assign a "noname.html" name :) */
	 strcpy (docName, "noname.html");
       
	/* remove DIR_SEP at the end of complete path */
	if (newName[i] == DIR_SEP)
	   newName[i] = EOS;
     }
}

/*----------------------------------------------------------------------
  IsSameHost                                                         
  ----------------------------------------------------------------------*/
#ifdef __STDC__
boolean             IsSameHost (char *url1, char *url2)
#else  /* __STDC__ */
boolean             IsSameHost (url1, url2)
char               *path;
#endif /* __STDC__ */
{
   char               *basename_ptr1, *basename_ptr2;
   boolean             result;

   basename_ptr1 = HTParse (url1, "", PARSE_ACCESS | PARSE_HOST | PARSE_PUNCTUATION);
   basename_ptr2 = HTParse (url2, "", PARSE_ACCESS | PARSE_HOST | PARSE_PUNCTUATION);

   if (strcmp (basename_ptr1, basename_ptr2))
      result = FALSE;
   else
      result = TRUE;

   HT_FREE (basename_ptr1);
   HT_FREE (basename_ptr2);

   return (result);
}


/*----------------------------------------------------------------------
  AHTMakeRelativeURL                                                
  converts url into a relative url to base_url.
  If succesful, returns the new URL, otherwise, it returns NULL.
  The caller has to free the new URL.
  ----------------------------------------------------------------------*/
#ifdef __STDC__
char               *AHTMakeRelativeName (char *url, char *base_url)
#else  /* __STDC__ */
char               *AHTMakeRelativeName (url, base_url)
char                url;
char                base_url;

#endif /* __STDC__ */
{
   char               *base_ptr, *url_ptr;
   char               *result;

   /* verify if we are in the same host */

   base_ptr = HTParse (base_url, "", PARSE_ACCESS | PARSE_HOST | PARSE_PUNCTUATION);
   url_ptr = HTParse (url, "", PARSE_ACCESS | PARSE_HOST | PARSE_PUNCTUATION);

   if (!strcmp (base_ptr, url_ptr))
     {
	HT_FREE (base_ptr);
	HT_FREE (url_ptr);

	/* Normalize the URLs */

	base_ptr = HTParse (base_url, "", PARSE_ALL);
	url_ptr = HTParse (url, "", PARSE_ALL);

	/* Use libwww to make relative name */

	result = HTRelative (url_ptr, base_ptr);
	HT_FREE (base_ptr);
	HT_FREE (url_ptr);
     }
   else
      result = (char *) NULL;

   return (result);
}




Webmaster