/*
 * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );

/** @file
 *
 * Uniform Resource Identifiers
 *
 */

#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <libgen.h>
#include <ctype.h>
#include <ipxe/vsprintf.h>
#include <ipxe/params.h>
#include <ipxe/tcpip.h>
#include <ipxe/uri.h>

/**
 * Decode URI field
 *
 * @v encoded		Encoded field
 * @v buf		Data buffer
 * @v len		Length
 * @ret len		Length of data
 *
 * URI decoding can never increase the length of a string; we can
 * therefore safely decode in place.
 */
size_t uri_decode ( const char *encoded, void *buf, size_t len ) {
	uint8_t *out = buf;
	unsigned int count = 0;
	char hexbuf[3];
	char *hexbuf_end;
	char c;
	char decoded;
	unsigned int skip;

	/* Copy string, decoding escaped characters as necessary */
	while ( ( c = *(encoded++) ) ) {
		if ( c == '%' ) {
			snprintf ( hexbuf, sizeof ( hexbuf ), "%s", encoded );
			decoded = strtoul ( hexbuf, &hexbuf_end, 16 );
			skip = ( hexbuf_end - hexbuf );
			encoded += skip;
			if ( skip )
				c = decoded;
		}
		if ( count < len )
			out[count] = c;
		count++;
	}
	return count;
}

/**
 * Decode URI field in-place
 *
 * @v encoded		Encoded field, or NULL
 */
static void uri_decode_inplace ( char *encoded ) {
	char *decoded = encoded;
	size_t len;

	/* Do nothing if field is not present */
	if ( ! encoded )
		return;

	/* Decode field in place */
	len = uri_decode ( encoded, decoded, strlen ( encoded ) );

	/* Terminate decoded string */
	decoded[len] = '\0';
}

/**
 * Check if character should be escaped within a URI field
 *
 * @v c			Character
 * @v field		URI field index
 * @ret escaped		Character should be escaped
 */
static int uri_character_escaped ( char c, unsigned int field ) {

	/* Non-printing characters and whitespace should always be
	 * escaped, since they cannot sensibly be displayed as part of
	 * a coherent URL string.  (This test also catches control
	 * characters such as CR and LF, which could affect the
	 * operation of line-based protocols such as HTTP.)
	 *
	 * We should also escape characters which would alter the
	 * interpretation of the URL if not escaped, i.e. characters
	 * which have significance to the URL parser.  We should not
	 * blindly escape all such characters, because this would lead
	 * to some very strange-looking URLs (e.g. if we were to
	 * always escape '/' as "%2F" even within the URI path).
	 *
	 * We do not need to be perfect.  Our primary role is as a
	 * consumer of URIs rather than a producer; the main situation
	 * in which we produce a URI string is for display to a human
	 * user, who can probably tolerate some variance from the
	 * formal specification.  The only situation in which we
	 * currently produce a URI string to be consumed by a computer
	 * is when constructing an HTTP request URI, which contains
	 * only the path and query fields.
	 *
	 * We can therefore sacrifice some correctness for the sake of
	 * code size.  For example, colons within the URI host should
	 * be escaped unless they form part of an IPv6 literal
	 * address; doing this correctly would require the URI
	 * formatter to be aware of whether or not the URI host
	 * contained an IPv4 address, an IPv6 address, or a host name.
	 * We choose to simplify and never escape colons within the
	 * URI host field: in the event of a pathological hostname
	 * containing colons, this could potentially produce a URI
	 * string which could not be reparsed.
	 *
	 * After excluding non-printing characters, whitespace, and
	 * '%', the full set of characters with significance to the
	 * URL parser is "/#:@?".  We choose for each URI field which
	 * of these require escaping in our use cases.
	 *
	 * For the scheme field (equivalently, if field is zero), we
	 * escape anything that has significance not just for our URI
	 * parser but for any other URI parsers (e.g. HTTP query
	 * string parsers, which care about '=' and '&').
	 */
	static const char *escaped[URI_EPATH] = {
		/* Scheme or default: escape everything */
		[URI_SCHEME]	= "/#:@?=&",
		/* Opaque part: escape characters which would affect
		 * the reparsing of the URI, allowing everything else
		 * (e.g. ':', which will appear in iSCSI URIs).
		 */
		[URI_OPAQUE]	= "#",
		/* User name: escape everything */
		[URI_USER]	= "/#:@?",
		/* Password: escape everything */
		[URI_PASSWORD]	= "/#:@?",
		/* Host name: escape everything except ':', which may
		 * appear as part of an IPv6 literal address.
		 */
		[URI_HOST]	= "/#@?",
		/* Port number: escape everything */
		[URI_PORT]	= "/#:@?",
		/* Path: escape everything except '/', which usually
		 * appears within paths.
		 */
		[URI_PATH]	= "#:@?",
	};

	/* Always escape non-printing characters and whitespace */
	if ( ( ! isprint ( c ) ) || ( c == ' ' ) )
		return 1;

	/* Escape nothing else in already-escaped fields */
	if ( field >= URI_EPATH )
		return 0;

	/* Escape '%' and any field-specific characters */
	if ( ( c == '%' ) || strchr ( escaped[field], c ) )
		return 1;

	return 0;
}

/**
 * Encode URI field
 *
 * @v field		URI field index
 * @v raw		Raw data
 * @v raw_len		Length of raw data
 * @v buf		Buffer
 * @v len		Length of buffer
 * @ret len		Length of encoded string (excluding NUL)
 */
size_t uri_encode ( unsigned int field, const void *raw, size_t raw_len,
		    char *buf, ssize_t len ) {
	const uint8_t *raw_bytes = ( ( const uint8_t * ) raw );
	ssize_t remaining = len;
	size_t used;
	char c;

	/* Ensure encoded string is NUL-terminated even if empty */
	if ( len > 0 )
		buf[0] = '\0';

	/* Copy string, escaping as necessary */
	while ( raw_len-- ) {
		c = *(raw_bytes++);
		if ( uri_character_escaped ( c, field ) ) {
			used = ssnprintf ( buf, remaining, "%%%02X", c );
		} else {
			used = ssnprintf ( buf, remaining, "%c", c );
		}
		buf += used;
		remaining -= used;
	}

	return ( len - remaining );
}

/**
 * Encode URI field string
 *
 * @v field		URI field index
 * @v string		String
 * @v buf		Buffer
 * @v len		Length of buffer
 * @ret len		Length of encoded string (excluding NUL)
 */
size_t uri_encode_string ( unsigned int field, const char *string,
			   char *buf, ssize_t len ) {

	return uri_encode ( field, string, strlen ( string ), buf, len );
}

/**
 * Dump URI for debugging
 *
 * @v uri		URI
 */
static void uri_dump ( const struct uri *uri ) {

	if ( ! uri )
		return;
	if ( uri->scheme )
		DBGC ( uri, " scheme \"%s\"", uri->scheme );
	if ( uri->opaque )
		DBGC ( uri, " opaque \"%s\"", uri->opaque );
	if ( uri->user )
		DBGC ( uri, " user \"%s\"", uri->user );
	if ( uri->password )
		DBGC ( uri, " password \"%s\"", uri->password );
	if ( uri->host )
		DBGC ( uri, " host \"%s\"", uri->host );
	if ( uri->port )
		DBGC ( uri, " port \"%s\"", uri->port );
	if ( uri->path )
		DBGC ( uri, " path \"%s\"", uri->path );
	if ( uri->epath )
		DBGC ( uri, " epath \"%s\"", uri->epath );
	if ( uri->equery )
		DBGC ( uri, " equery \"%s\"", uri->equery );
	if ( uri->efragment )
		DBGC ( uri, " efragment \"%s\"", uri->efragment );
	if ( uri->params )
		DBGC ( uri, " params \"%s\"", uri->params->name );
}

/**
 * Free URI
 *
 * @v refcnt		Reference count
 */
static void uri_free ( struct refcnt *refcnt ) {
	struct uri *uri = container_of ( refcnt, struct uri, refcnt );

	params_put ( uri->params );
	free ( uri );
}

/**
 * Parse URI
 *
 * @v uri_string	URI as a string
 * @ret uri		URI
 *
 * Splits a URI into its component parts.  The return URI structure is
 * dynamically allocated and must eventually be freed by calling
 * uri_put().
 */
struct uri * parse_uri ( const char *uri_string ) {
	struct uri *uri;
	struct parameters *params;
	char *raw;
	char *tmp;
	char *path;
	char *epath;
	char *authority;
	size_t raw_len;
	unsigned int field;

	/* Allocate space for URI struct and two copies of the string */
	raw_len = ( strlen ( uri_string ) + 1 /* NUL */ );
	uri = zalloc ( sizeof ( *uri ) + ( 2 * raw_len ) );
	if ( ! uri )
		return NULL;
	ref_init ( &uri->refcnt, uri_free );
	raw = ( ( ( void * ) uri ) + sizeof ( *uri ) );
	path = ( raw + raw_len );

	/* Copy in the raw string */
	memcpy ( raw, uri_string, raw_len );

	/* Identify the parameter list, if present */
	if ( ( tmp = strstr ( raw, "##params" ) ) ) {
		*tmp = '\0';
		tmp += 8 /* "##params" */;
		params = find_parameters ( *tmp ? ( tmp + 1 ) : NULL );
		if ( params ) {
			uri->params = claim_parameters ( params );
		} else {
			/* Ignore non-existent submission blocks */
		}
	}

	/* Chop off the fragment, if it exists */
	if ( ( tmp = strchr ( raw, '#' ) ) ) {
		*(tmp++) = '\0';
		uri->efragment = tmp;
	}

	/* Identify absolute URIs */
	epath = raw;
	for ( tmp = raw ; ; tmp++ ) {
		/* Possible scheme character (for our URI schemes) */
		if ( isalpha ( *tmp ) || ( *tmp == '-' ) || ( *tmp == '_' ) )
			continue;
		/* Invalid scheme character or NUL: is a relative URI */
		if ( *tmp != ':' )
			break;
		/* Absolute URI: identify hierarchical/opaque */
		uri->scheme = raw;
		*(tmp++) = '\0';
		if ( *tmp == '/' ) {
			/* Absolute URI with hierarchical part */
			epath = tmp;
		} else {
			/* Absolute URI with opaque part */
			uri->opaque = tmp;
			epath = NULL;
		}
		break;
	}

	/* If we don't have a path (i.e. we have an absolute URI with
	 * an opaque portion, we're already finished processing
	 */
	if ( ! epath )
		goto done;

	/* Chop off the query, if it exists */
	if ( ( tmp = strchr ( epath, '?' ) ) ) {
		*(tmp++) = '\0';
		uri->equery = tmp;
	}

	/* If we have no path remaining, then we're already finished
	 * processing.
	 */
	if ( ! epath[0] )
		goto done;

	/* Identify net/absolute/relative path */
	if ( uri->scheme && ( strncmp ( epath, "//", 2 ) == 0 ) ) {
		/* Net path.  If this is terminated by the first '/'
		 * of an absolute path, then we have no space for a
		 * terminator after the authority field, so shuffle
		 * the authority down by one byte, overwriting one of
		 * the two slashes.
		 */
		authority = ( epath + 2 );
		if ( ( tmp = strchr ( authority, '/' ) ) ) {
			/* Shuffle down */
			uri->epath = tmp;
			memmove ( ( authority - 1 ), authority,
				  ( tmp - authority ) );
			authority--;
			*(--tmp) = '\0';
		}
	} else {
		/* Absolute/relative path */
		uri->epath = epath;
		authority = NULL;
	}

	/* Create copy of path for decoding */
	if ( uri->epath ) {
		strcpy ( path, uri->epath );
		uri->path = path;
	}

	/* If we don't have an authority (i.e. we have a non-net
	 * path), we're already finished processing
	 */
	if ( ! authority )
		goto done;

	/* Split authority into user[:password] and host[:port] portions */
	if ( ( tmp = strchr ( authority, '@' ) ) ) {
		/* Has user[:password] */
		*(tmp++) = '\0';
		uri->host = tmp;
		uri->user = authority;
		if ( ( tmp = strchr ( authority, ':' ) ) ) {
			/* Has password */
			*(tmp++) = '\0';
			uri->password = tmp;
		}
	} else {
		/* No user:password */
		uri->host = authority;
	}

	/* Split host into host[:port] */
	if ( ( tmp = strrchr ( uri->host, ':' ) ) &&
	     ( uri->host[ strlen ( uri->host ) - 1 ] != ']' ) ) {
		*(tmp++) = '\0';
		uri->port = tmp;
	}

 done:
	/* Decode fields in-place */
	for ( field = 0 ; field < URI_EPATH ; field++ )
		uri_decode_inplace ( ( char * ) uri_field ( uri, field ) );

	DBGC ( uri, "URI parsed \"%s\" to", uri_string );
	uri_dump ( uri );
	DBGC ( uri, "\n" );

	return uri;
}

/**
 * Get port from URI
 *
 * @v uri		URI, or NULL
 * @v default_port	Default port to use if none specified in URI
 * @ret port		Port
 */
unsigned int uri_port ( const struct uri *uri, unsigned int default_port ) {

	if ( ( ! uri ) || ( ! uri->port ) )
		return default_port;

	return ( strtoul ( uri->port, NULL, 0 ) );
}

/**
 * Format URI
 *
 * @v uri		URI
 * @v buf		Buffer to fill with URI string
 * @v size		Size of buffer
 * @ret len		Length of URI string
 */
size_t format_uri ( const struct uri *uri, char *buf, size_t len ) {
	static const char prefixes[URI_FIELDS] = {
		[URI_PASSWORD] = ':',
		[URI_PORT] = ':',
		[URI_EQUERY] = '?',
		[URI_EFRAGMENT] = '#',
	};
	char prefix;
	size_t used = 0;
	unsigned int field;

	/* Ensure buffer is NUL-terminated */
	if ( len )
		buf[0] = '\0';

	/* Special-case NULL URI */
	if ( ! uri )
		return 0;

	/* Generate fields */
	for ( field = 0 ; field < URI_FIELDS ; field++ ) {

		/* Skip non-existent fields */
		if ( ! uri_field ( uri, field ) )
			continue;

		/* Skip path field if encoded path is present */
		if ( ( field == URI_PATH ) && uri->epath )
			continue;

		/* Prefix this field, if applicable */
		prefix = prefixes[field];
		if ( ( field == URI_HOST ) && ( uri->user != NULL ) )
			prefix = '@';
		if ( prefix ) {
			used += ssnprintf ( ( buf + used ), ( len - used ),
					    "%c", prefix );
		}

		/* Encode this field */
		used += uri_encode_string ( field, uri_field ( uri, field ),
					    ( buf + used ), ( len - used ) );

		/* Suffix this field, if applicable */
		if ( field == URI_SCHEME ) {
			used += ssnprintf ( ( buf + used ), ( len - used ),
					    ":%s", ( uri->host ? "//" : "" ) );
		}
	}

	if ( len ) {
		DBGC ( uri, "URI formatted" );
		uri_dump ( uri );
		DBGC ( uri, " to \"%s%s\"\n", buf,
		       ( ( used > len ) ? "<TRUNCATED>" : "" ) );
	}

	return used;
}

/**
 * Format URI
 *
 * @v uri		URI
 * @ret string		URI string, or NULL on failure
 *
 * The caller is responsible for eventually freeing the allocated
 * memory.
 */
char * format_uri_alloc ( const struct uri *uri ) {
	size_t len;
	char *string;

	len = ( format_uri ( uri, NULL, 0 ) + 1 /* NUL */ );
	string = malloc ( len );
	if ( string )
		format_uri ( uri, string, len );
	return string;
}

/**
 * Copy URI fields
 *
 * @v src		Source URI
 * @v dest		Destination URI, or NULL to calculate length
 * @ret len		Length of raw URI
 */
static size_t uri_copy_fields ( const struct uri *src, struct uri *dest ) {
	size_t len = sizeof ( *dest );
	char *out = ( ( void * ) dest + len );
	unsigned int field;
	size_t field_len;

	/* Copy existent fields */
	for ( field = 0 ; field < URI_FIELDS ; field++ ) {

		/* Skip non-existent fields */
		if ( ! uri_field ( src, field ) )
			continue;

		/* Calculate field length */
		field_len = ( strlen ( uri_field ( src, field ) )
			      + 1 /* NUL */ );
		len += field_len;

		/* Copy field, if applicable */
		if ( dest ) {
			memcpy ( out, uri_field ( src, field ), field_len );
			uri_field ( dest, field ) = out;
			out += field_len;
		}
	}
	return len;
}

/**
 * Duplicate URI
 *
 * @v uri		URI
 * @ret uri		Duplicate URI
 *
 * Creates a modifiable copy of a URI.
 */
struct uri * uri_dup ( const struct uri *uri ) {
	struct uri *dup;
	size_t len;

	/* Allocate new URI */
	len = uri_copy_fields ( uri, NULL );
	dup = zalloc ( len );
	if ( ! dup )
		return NULL;
	ref_init ( &dup->refcnt, uri_free );

	/* Copy fields */
	uri_copy_fields ( uri, dup );

	/* Copy parameters */
	dup->params = params_get ( uri->params );

	DBGC ( uri, "URI duplicated" );
	uri_dump ( uri );
	DBGC ( uri, "\n" );

	return dup;
}

/**
 * Resolve base+relative path
 *
 * @v base_uri		Base path
 * @v relative_uri	Relative path
 * @ret resolved_uri	Resolved path, or NULL on failure
 *
 * Takes a base path (e.g. "/var/lib/tftpboot/vmlinuz" and a relative
 * path (e.g. "initrd.gz") and produces a new path
 * (e.g. "/var/lib/tftpboot/initrd.gz").  Note that any non-directory
 * portion of the base path will automatically be stripped; this
 * matches the semantics used when resolving the path component of
 * URIs.
 */
char * resolve_path ( const char *base_path,
		      const char *relative_path ) {
	char *base_copy;
	char *base_tmp;
	char *resolved;

	/* If relative path is absolute, just re-use it */
	if ( relative_path[0] == '/' )
		return strdup ( relative_path );

	/* Create modifiable copy of path for dirname() */
	base_copy = strdup ( base_path );
	if ( ! base_copy )
		return NULL;

	/* Strip filename portion of base path */
	base_tmp = dirname ( base_copy );

	/* Process "./" and "../" elements */
	while ( *relative_path == '.' ) {
		relative_path++;
		if ( *relative_path == 0 ) {
			/* Do nothing */
		} else if ( *relative_path == '/' ) {
			relative_path++;
		} else if ( *relative_path == '.' ) {
			relative_path++;
			if ( *relative_path == 0 ) {
				base_tmp = dirname ( base_tmp );
			} else if ( *relative_path == '/' ) {
				base_tmp = dirname ( base_tmp );
				relative_path++;
			} else {
				relative_path -= 2;
				break;
			}
		} else {
			relative_path--;
			break;
		}
	}

	/* Create and return new path */
	if ( asprintf ( &resolved, "%s%s%s", base_tmp,
			( ( base_tmp[ strlen ( base_tmp ) - 1 ] == '/' ) ?
			  "" : "/" ), relative_path ) < 0 )
		resolved = NULL;
	free ( base_copy );
	return resolved;
}

/**
 * Resolve base+relative URI
 *
 * @v base_uri		Base URI, or NULL
 * @v relative_uri	Relative URI
 * @ret resolved_uri	Resolved URI, or NULL on failure
 *
 * Takes a base URI (e.g. "http://ipxe.org/kernels/vmlinuz" and a
 * relative URI (e.g. "../initrds/initrd.gz") and produces a new URI
 * (e.g. "http://ipxe.org/initrds/initrd.gz").
 */
struct uri * resolve_uri ( const struct uri *base_uri,
			   struct uri *relative_uri ) {
	struct uri tmp_uri;
	char *tmp_epath = NULL;
	char *tmp_path = NULL;
	struct uri *new_uri;

	/* If relative URI is absolute, just re-use it */
	if ( uri_is_absolute ( relative_uri ) || ( ! base_uri ) )
		return uri_get ( relative_uri );

	/* Mangle URI */
	memcpy ( &tmp_uri, base_uri, sizeof ( tmp_uri ) );
	if ( relative_uri->epath ) {
		tmp_epath = resolve_path ( ( base_uri->epath ?
					     base_uri->epath : "/" ),
					   relative_uri->epath );
		if ( ! tmp_epath )
			goto err_epath;
		tmp_path = strdup ( tmp_epath );
		if ( ! tmp_path )
			goto err_path;
		uri_decode_inplace ( tmp_path );
		tmp_uri.epath = tmp_epath;
		tmp_uri.path = tmp_path;
		tmp_uri.equery = relative_uri->equery;
		tmp_uri.efragment = relative_uri->efragment;
		tmp_uri.params = relative_uri->params;
	} else if ( relative_uri->equery ) {
		tmp_uri.equery = relative_uri->equery;
		tmp_uri.efragment = relative_uri->efragment;
		tmp_uri.params = relative_uri->params;
	} else if ( relative_uri->efragment ) {
		tmp_uri.efragment = relative_uri->efragment;
		tmp_uri.params = relative_uri->params;
	} else if ( relative_uri->params ) {
		tmp_uri.params = relative_uri->params;
	}

	/* Create demangled URI */
	new_uri = uri_dup ( &tmp_uri );
	free ( tmp_path );
	free ( tmp_epath );
	return new_uri;

	free ( tmp_path );
 err_path:
	free ( tmp_epath );
 err_epath:
	return NULL;
}

/**
 * Construct TFTP URI from server address and filename
 *
 * @v sa_server		Server address
 * @v filename		Filename
 * @ret uri		URI, or NULL on failure
 */
static struct uri * tftp_uri ( struct sockaddr *sa_server,
			       const char *filename ) {
	struct sockaddr_tcpip *st_server =
		( ( struct sockaddr_tcpip * ) sa_server );
	char buf[ 6 /* "65535" + NUL */ ];
	char *path;
	struct uri tmp;
	struct uri *uri = NULL;

	/* Initialise TFTP URI */
	memset ( &tmp, 0, sizeof ( tmp ) );
	tmp.scheme = "tftp";

	/* Construct TFTP server address */
	tmp.host = sock_ntoa ( sa_server );
	if ( ! tmp.host )
		goto err_host;

	/* Construct TFTP server port, if applicable */
	if ( st_server->st_port ) {
		snprintf ( buf, sizeof ( buf ), "%d",
			   ntohs ( st_server->st_port ) );
		tmp.port = buf;
	}

	/* Construct TFTP path */
	if ( asprintf ( &path, "/%s", filename ) < 0 )
		goto err_path;
	tmp.path = path;
	tmp.epath = path;

	/* Demangle URI */
	uri = uri_dup ( &tmp );
	if ( ! uri )
		goto err_uri;

 err_uri:
	free ( path );
 err_path:
 err_host:
	return uri;
}

/**
 * Construct URI from server address and filename
 *
 * @v sa_server		Server address
 * @v filename		Filename
 * @ret uri		URI, or NULL on failure
 *
 * PXE TFTP filenames specified via the DHCP next-server field often
 * contain characters such as ':' or '#' which would confuse the
 * generic URI parser.  We provide a mechanism for directly
 * constructing a TFTP URI from the next-server and filename.
 */
struct uri * pxe_uri ( struct sockaddr *sa_server, const char *filename ) {
	struct uri *uri;

	/* Fail if filename is empty */
	if ( ! ( filename && filename[0] ) )
		return NULL;

	/* If filename is a hierarchical absolute URI, then use that
	 * URI.  (We accept only hierarchical absolute URIs, since PXE
	 * filenames sometimes start with DOS drive letters such as
	 * "C:\", which get misinterpreted as opaque absolute URIs.)
	 */
	uri = parse_uri ( filename );
	if ( uri && uri_is_absolute ( uri ) && ( ! uri->opaque ) )
		return uri;
	uri_put ( uri );

	/* Otherwise, construct a TFTP URI directly */
	return tftp_uri ( sa_server, filename );
}
