/*
  (c) 1998 netEstate (http://www.netestate.de/, info@netestate.de),
Michael Brunnbauer & Markus Hendel, Gesellschaft fuer Netzwerkkommunikation bR
Am Bluetenanger 8, 80995 Muenchen, Germany

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "wwwlib.h"

void urlprint(FILE* fh,url u)
{
  if (defined(u.scheme))
    { 
      fputs("Scheme: ",fh);
      fputs(u.scheme,fh);
      fputs("\n",fh);
    };
  if (defined(u.scheme_specific))
    {
      fputs("Scheme-specific: ",fh);
      fputs(u.scheme_specific,fh);
      fputs("\n",fh);
    };
  if (defined(u.login))
    {
      fputs("Login: ",fh);
      fputs(u.login,fh);
      fputs("\n",fh);
    };
  if (defined(u.connection))
    {
      fputs("Connection: ",fh);
      fputs(u.connection,fh);
      fputs("\n",fh);
    };
  if (defined(u.path))
    {
      fputs("Path: ",fh);
      fputs(u.path,fh);
      fputs("\n",fh);
    };
  if (defined(u.user))
    {
      fputs("User: ",fh);
      fputs(u.user,fh);
      fputs("\n",fh);
    };
  if (defined(u.pw))
    {
      fputs("Pw: ",fh);
      fputs(u.pw,fh);
      fputs("\n",fh);
    };
  if (defined(u.host))
    {
      fputs("Host: ",fh);
      fputs(u.host,fh);
      fputs("\n",fh);
    };
  if (defined(u.port))
    {
      fputs("Port: ",fh);
      fputs(u.port,fh);
      fputs("\n",fh);
    };
  return;
};

url urlparse(char* text)
{
  url rueck;

  if (!strstr(text,":"))
    {
      /* not a valid url */
      return rueck;
    };

  /* get scheme */
  rueck.scheme=text;
  strstr(rueck.scheme,":")[0]=0;
  rueck.scheme.len=strlen(rueck.scheme);

  /* get scheme-specific part */
  rueck.scheme_specific=strstr(text,":")+1;
  text=rueck.scheme_specific;

  /* strip double / */
  if (strstr(text,"//")==text)
    {
      text+=2;
    }
  else
    {
      return rueck;
    };

  /* strip optional login info */
  if (strstr(text,"@"))
    {
      rueck.login=text;
      strstr(rueck.login,"@")[0]=0;
      rueck.login.len=strlen(rueck.login);
      text=strstr(text,"@")+1;
    };

  /* divide into connection and path */
  rueck.connection=text;
  if (strstr(text,"/"))
    {
      strstr(rueck.connection,"/")[0]=0;
      rueck.connection.len=strlen(rueck.connection);
      rueck.path=strstr(text,"/")+1;
    };

  /* divide connection */
  rueck.host=rueck.connection;
  if (strstr(rueck.connection,":"))
    {
      strstr(rueck.host,":")[0]=0;
      rueck.host.len=strlen(rueck.host);
      rueck.port=strstr(rueck.connection,":")+1;
    };

  /* divide login */
  if (defined(rueck.login))
    {
      rueck.user=rueck.login;
      if (strstr(rueck.login,":"))
	{
	  strstr(rueck.user,":")[0]=0;
	  rueck.user.len=strlen(rueck.user);
	  rueck.pw=strstr(rueck.login,":")+1;
	};
    };

  return rueck;
};

/* returncodes: 0 = EOF, 1 = OK, -1 = fehler */

int urlencode_parse(char** src,string& name,string& value)
{
  char buf[2];
  char hex[3];
  buf[1]=0;
  hex[2]=0;
  name="";value="";
  int c;

  /* read name */
  while ((**src)!='=')
    {
      switch (**src)
	{
	case 0:
	  {
	    log(LOG_ERROR,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
		"urlencode_parse: EOF while parsing name");
	    return -1 ;
	  };
	case '+':
	  {
	    name+=" ";
	    break;
	  };
	case '%':
	  {
            hex[0]=*(++(*src));
            if (!hex[0])
              {
                log(LOG_ERROR,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
                    "urlencode_parse: EOF after %");
                return -1;
              };
            hex[1]=*(++(*src));
            if (!hex[1])
	      {
		log(LOG_ERROR,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
		    "urlencode_parse: EOF after %");
		return -1;
	      };
	    if (sscanf(hex,"%x",&c)!=1)
	      {
		log(LOG_ERROR,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
		    "urlencode_parse: error with hex-character in name: %s",
		    (char*) hex);
		return -1;
	      };
	    buf[0]=(char) c;
	    name+=buf;
	    break;
	  };
	default:
	  {
	    buf[0]=**src;
	    name+=buf;
	    break;
	  };
	};
      (*src)++;
    };
  
  (*src)++;

  /* read value */
  while (**src && **src!='&')
    {
      switch (**src)
	{
        case '+':
          {
	    value+=" ";
	    break;
	  };
        case '%':
          {
            hex[0]=*(++(*src));
            if (!hex[0])
              {
                log(LOG_ERROR,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
                    "urlencode_parse: EOF after %");
                return -1;
              };
            hex[1]=*(++(*src));
            if (!hex[1])
              {
                log(LOG_ERROR,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
                    "urlencode_parse: EOF after %");
                return -1;
              };
            if (sscanf(hex,"%x",&c)!=1)
              {
                log(LOG_ERROR,__FILE__,__LINE__,ERROR_SYNTAX_ERROR,
                    "urlencode_parse: error with hex-character in value: %s",
                    (char*) hex);
                return -1;
              };
            buf[0]=(char) c;
            value+=buf;
            break;
          };
        default:
          {
	    buf[0]=**src;
	    value+=buf;
	    break;
          };
	};
      (*src)++;
    };

  if (**src=='&')
    {
      (*src)++;
      return 1;
    }
  else
    {
      return 0;
    };

  /* not reached */
  return 0;
}
