/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	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.

**********************************************************************/



#include	<string.h>
#include	<stdlib.h>
#include	"memory_debug.h"
#include	"utils.h"
#include	"gbparam.h"

int
xx_get_url2(
	URL *	ret,
	L_CHAR * url,
	char * __file,int __line)
{
L_CHAR * buf;
L_CHAR * div;
L_CHAR * host;
L_CHAR *dir;
L_CHAR ch;
int p,len;
int er;
L_CHAR nq;
L_CHAR * nq_str;
int i;
L_CHAR * f;

	nq = 0;
	nq_str = 0;
	er = 0;
	zero_url(ret);
	buf = xx_ll_copy_str(url,__file,__line);

	for ( i = 0 ; buf[i] ; i ++ ) {
		switch ( buf[i] ) {
		case '?':
			nq = '?';
			buf[i] = 0;
			nq_str = &buf[i+1];
			break;
		case '#':
			nq = '#';
			buf[i] = 0;
			nq_str = &buf[i+1];
			break;
		default:
			continue;
		}
		break;
	}

	len = l_strlen(buf);
	div = xx_nl_copy_str(std_cm,"://",__file,__line);
	for ( p = 0 ; p < len-3 ; p ++ )
		if ( memcmp(div,&buf[p],3*sizeof(L_CHAR)) == 0 ) {
			d_f_ree(div);
			goto match;
		}
	d_f_ree(div);
	ret->proto = 0;
	ret->server = 0;
	ret->port = 0;
	dir = buf;
	goto dir_res;
match:
	buf[p] = 0;
	ret->proto = xx_ll_copy_str(buf,__file,__line);
	p += 3;
	host = &buf[p];
	for ( ; buf[p] && buf[p] != ':' && buf[p] != '/' ; p ++ );
	ch = buf[p];
	if ( (&buf[p]) == host ) {
		ret->server = 0;
		switch ( ch ) {
		case ':':
			er = -1;
			goto end;
		case '/':
			ret->port = 0;
			buf[p] = '/';
			dir = &buf[p];
			goto dir_res;
		case 0:
			ret->port = 0;
			ret->db = xx_nl_copy_str(std_cm,"/",__file,__line);
			ret->resource = 0;
			goto end;
		}
	}
	buf[p] = 0;
	ret->server = xx_ll_copy_str(host,__file,__line);
	switch ( ch ) {
	case 0:
		ret->port = 0;
		ret->db = xx_nl_copy_str(std_cm,"/",__file,__line);
		ret->resource = 0;
		goto end;
	case ':':
		p ++;
		break;
	case '/':
		ret->port = 0;
		buf[p] = '/';
		dir = &buf[p];
		goto dir_res;
	}
/* port: */
	ret->port = 0;
	for ( ; '0' <= buf[p] && buf[p] <= '9' ; p ++ )
		ret->port = ret->port*10 + buf[p] - '0';
	switch ( buf[p] ) {
	case 0:
		ret->db = xx_nl_copy_str(std_cm,"/",__file,__line);
		ret->resource = 0;
		goto end;
	case '/':
		dir = &buf[p];
		goto dir_res;
	default:
		er = -1;
		goto end;
	}
dir_res:
	p = len = l_strlen(dir)-1;
	for ( ; p >= 0 ; p -- )
		if ( dir[p] == '/' )
			goto res;
	ret->db = 0;
	ret->resource = xx_ll_copy_str(dir,__file,__line);
	goto end;
res:
	if ( len == p ) {
		ret->resource = 0;
		ret->db = xx_ll_copy_str(dir,__file,__line);
	}
	else {
		ret->resource = xx_ll_copy_str(&dir[p+1],__file,__line);
		dir[p+1] = 0;
		ret->db = xx_ll_copy_str(dir,__file,__line);
	}
end:
	if ( ret->port == 0 && ret->proto ) {
		ret->port = get_wkp(ret->proto);
		if ( ret->port < 0 )
			ret->port = 0;
	}
	switch ( nq ) {
	case '#':
		ret->name = xx_ll_copy_str(nq_str,__file,__line);
		break;
	case '?':
		ret->query = xx_ll_copy_str(nq_str,__file,__line);
		break;
	}
	if ( ret->db && ret->db[0] == '/' && ret->db[1] == '@' ) {
		ret->agent = xx_ll_copy_str(&ret->db[2],__file,__line);
		for ( i = 0 ; ret->agent[i] && ret->agent[i] != '/' ; i ++ );
		nq = ret->agent[i];
		ret->agent[i] = 0;
		f = ret->db;
		if ( nq == 0 )
			ret->db = xx_nl_copy_str(std_cm,"/",__file,__line);
		else	ret->db = xx_ll_copy_str(&ret->db[i+2],__file,__line);
		d_f_ree(f);
	}
	d_f_ree(buf);
	return er;
}

