| 
				
			 | 
			
			
				
				@@ -368,7 +368,7 @@ struct uri * parse_uri ( const char *uri_string ) { 
			 | 
		
		
	
		
			
			| 
				368
			 | 
			
				368
			 | 
			
			
				
				 		goto done; 
			 | 
		
		
	
		
			
			| 
				369
			 | 
			
				369
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				370
			 | 
			
				370
			 | 
			
			
				
				 	/* Identify net/absolute/relative path */ 
			 | 
		
		
	
		
			
			| 
				371
			 | 
			
				
			 | 
			
			
				
				-	if ( strncmp ( path, "//", 2 ) == 0 ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				371
			 | 
			
			
				
				+	if ( uri->scheme && ( strncmp ( path, "//", 2 ) == 0 ) ) { 
			 | 
		
		
	
		
			
			| 
				372
			 | 
			
				372
			 | 
			
			
				
				 		/* Net path.  If this is terminated by the first '/' 
			 | 
		
		
	
		
			
			| 
				373
			 | 
			
				373
			 | 
			
			
				
				 		 * of an absolute path, then we have no space for a 
			 | 
		
		
	
		
			
			| 
				374
			 | 
			
				374
			 | 
			
			
				
				 		 * terminator after the authority field, so shuffle 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -459,7 +459,6 @@ size_t format_uri ( const struct uri *uri, char *buf, size_t len ) { 
			 | 
		
		
	
		
			
			| 
				459
			 | 
			
				459
			 | 
			
			
				
				 		[URI_OPAQUE] = ':', 
			 | 
		
		
	
		
			
			| 
				460
			 | 
			
				460
			 | 
			
			
				
				 		[URI_PASSWORD] = ':', 
			 | 
		
		
	
		
			
			| 
				461
			 | 
			
				461
			 | 
			
			
				
				 		[URI_PORT] = ':', 
			 | 
		
		
	
		
			
			| 
				462
			 | 
			
				
			 | 
			
			
				
				-		[URI_PATH] = '/', 
			 | 
		
		
	
		
			
			| 
				463
			 | 
			
				462
			 | 
			
			
				
				 		[URI_QUERY] = '?', 
			 | 
		
		
	
		
			
			| 
				464
			 | 
			
				463
			 | 
			
			
				
				 		[URI_FRAGMENT] = '#', 
			 | 
		
		
	
		
			
			| 
				465
			 | 
			
				464
			 | 
			
			
				
				 	}; 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -486,8 +485,6 @@ size_t format_uri ( const struct uri *uri, char *buf, size_t len ) { 
			 | 
		
		
	
		
			
			| 
				486
			 | 
			
				485
			 | 
			
			
				
				 		prefix = prefixes[field]; 
			 | 
		
		
	
		
			
			| 
				487
			 | 
			
				486
			 | 
			
			
				
				 		if ( ( field == URI_HOST ) && ( uri->user != NULL ) ) 
			 | 
		
		
	
		
			
			| 
				488
			 | 
			
				487
			 | 
			
			
				
				 			prefix = '@'; 
			 | 
		
		
	
		
			
			| 
				489
			 | 
			
				
			 | 
			
			
				
				-		if ( ( field == URI_PATH ) && ( uri->path[0] == '/' ) ) 
			 | 
		
		
	
		
			
			| 
				490
			 | 
			
				
			 | 
			
			
				
				-			prefix = '\0'; 
			 | 
		
		
	
		
			
			| 
				491
			 | 
			
				488
			 | 
			
			
				
				 		if ( prefix ) { 
			 | 
		
		
	
		
			
			| 
				492
			 | 
			
				489
			 | 
			
			
				
				 			used += ssnprintf ( ( buf + used ), ( len - used ), 
			 | 
		
		
	
		
			
			| 
				493
			 | 
			
				490
			 | 
			
			
				
				 					    "%c", prefix ); 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -714,6 +711,55 @@ struct uri * resolve_uri ( const struct uri *base_uri, 
			 | 
		
		
	
		
			
			| 
				714
			 | 
			
				711
			 | 
			
			
				
				 	return new_uri; 
			 | 
		
		
	
		
			
			| 
				715
			 | 
			
				712
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				716
			 | 
			
				713
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				714
			 | 
			
			
				
				+/** 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				715
			 | 
			
			
				
				+ * Construct TFTP URI from server address and filename 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				716
			 | 
			
			
				
				+ * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				717
			 | 
			
			
				
				+ * @v sa_server		Server address 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				718
			 | 
			
			
				
				+ * @v filename		Filename 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				719
			 | 
			
			
				
				+ * @ret uri		URI, or NULL on failure 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				720
			 | 
			
			
				
				+ */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				721
			 | 
			
			
				
				+static struct uri * tftp_uri ( struct sockaddr *sa_server, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				722
			 | 
			
			
				
				+			       const char *filename ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				723
			 | 
			
			
				
				+	struct sockaddr_tcpip *st_server = 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				724
			 | 
			
			
				
				+		( ( struct sockaddr_tcpip * ) sa_server ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				725
			 | 
			
			
				
				+	char buf[ 6 /* "65535" + NUL */ ]; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				726
			 | 
			
			
				
				+	char *path; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				727
			 | 
			
			
				
				+	struct uri tmp; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				728
			 | 
			
			
				
				+	struct uri *uri = NULL; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				729
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				730
			 | 
			
			
				
				+	/* Initialise TFTP URI */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				731
			 | 
			
			
				
				+	memset ( &tmp, 0, sizeof ( tmp ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				732
			 | 
			
			
				
				+	tmp.scheme = "tftp"; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				733
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				734
			 | 
			
			
				
				+	/* Construct TFTP server address */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				735
			 | 
			
			
				
				+	tmp.host = sock_ntoa ( sa_server ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				736
			 | 
			
			
				
				+	if ( ! tmp.host ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				737
			 | 
			
			
				
				+		goto err_host; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				738
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				739
			 | 
			
			
				
				+	/* Construct TFTP server port, if applicable */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				740
			 | 
			
			
				
				+	if ( st_server->st_port ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				741
			 | 
			
			
				
				+		snprintf ( buf, sizeof ( buf ), "%d", 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				742
			 | 
			
			
				
				+			   ntohs ( st_server->st_port ) ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				743
			 | 
			
			
				
				+		tmp.port = buf; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				744
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				745
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				746
			 | 
			
			
				
				+	/* Construct TFTP path */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				747
			 | 
			
			
				
				+	if ( asprintf ( &path, "/%s", filename ) < 0 ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				748
			 | 
			
			
				
				+		goto err_path; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				749
			 | 
			
			
				
				+	tmp.path = path; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				750
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				751
			 | 
			
			
				
				+	/* Demangle URI */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				752
			 | 
			
			
				
				+	uri = uri_dup ( &tmp ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				753
			 | 
			
			
				
				+	if ( ! uri ) 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				754
			 | 
			
			
				
				+		goto err_uri; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				755
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				756
			 | 
			
			
				
				+ err_uri: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				757
			 | 
			
			
				
				+	free ( path ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				758
			 | 
			
			
				
				+ err_path: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				759
			 | 
			
			
				
				+ err_host: 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				760
			 | 
			
			
				
				+	return uri; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				761
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				762
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				717
			 | 
			
				763
			 | 
			
			
				
				 /** 
			 | 
		
		
	
		
			
			| 
				718
			 | 
			
				764
			 | 
			
			
				
				  * Construct URI from server address and filename 
			 | 
		
		
	
		
			
			| 
				719
			 | 
			
				765
			 | 
			
			
				
				  * 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -727,10 +773,6 @@ struct uri * resolve_uri ( const struct uri *base_uri, 
			 | 
		
		
	
		
			
			| 
				727
			 | 
			
				773
			 | 
			
			
				
				  * constructing a TFTP URI from the next-server and filename. 
			 | 
		
		
	
		
			
			| 
				728
			 | 
			
				774
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				729
			 | 
			
				775
			 | 
			
			
				
				 struct uri * pxe_uri ( struct sockaddr *sa_server, const char *filename ) { 
			 | 
		
		
	
		
			
			| 
				730
			 | 
			
				
			 | 
			
			
				
				-	char buf[ 6 /* "65535" + NUL */ ]; 
			 | 
		
		
	
		
			
			| 
				731
			 | 
			
				
			 | 
			
			
				
				-	struct sockaddr_tcpip *st_server = 
			 | 
		
		
	
		
			
			| 
				732
			 | 
			
				
			 | 
			
			
				
				-		( ( struct sockaddr_tcpip * ) sa_server ); 
			 | 
		
		
	
		
			
			| 
				733
			 | 
			
				
			 | 
			
			
				
				-	struct uri tmp; 
			 | 
		
		
	
		
			
			| 
				734
			 | 
			
				776
			 | 
			
			
				
				 	struct uri *uri; 
			 | 
		
		
	
		
			
			| 
				735
			 | 
			
				777
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				736
			 | 
			
				778
			 | 
			
			
				
				 	/* Fail if filename is empty */ 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -748,17 +790,5 @@ struct uri * pxe_uri ( struct sockaddr *sa_server, const char *filename ) { 
			 | 
		
		
	
		
			
			| 
				748
			 | 
			
				790
			 | 
			
			
				
				 	uri_put ( uri ); 
			 | 
		
		
	
		
			
			| 
				749
			 | 
			
				791
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				750
			 | 
			
				792
			 | 
			
			
				
				 	/* Otherwise, construct a TFTP URI directly */ 
			 | 
		
		
	
		
			
			| 
				751
			 | 
			
				
			 | 
			
			
				
				-	memset ( &tmp, 0, sizeof ( tmp ) ); 
			 | 
		
		
	
		
			
			| 
				752
			 | 
			
				
			 | 
			
			
				
				-	tmp.scheme = "tftp"; 
			 | 
		
		
	
		
			
			| 
				753
			 | 
			
				
			 | 
			
			
				
				-	tmp.host = sock_ntoa ( sa_server ); 
			 | 
		
		
	
		
			
			| 
				754
			 | 
			
				
			 | 
			
			
				
				-	if ( ! tmp.host ) 
			 | 
		
		
	
		
			
			| 
				755
			 | 
			
				
			 | 
			
			
				
				-		return NULL; 
			 | 
		
		
	
		
			
			| 
				756
			 | 
			
				
			 | 
			
			
				
				-	if ( st_server->st_port ) { 
			 | 
		
		
	
		
			
			| 
				757
			 | 
			
				
			 | 
			
			
				
				-		snprintf ( buf, sizeof ( buf ), "%d", 
			 | 
		
		
	
		
			
			| 
				758
			 | 
			
				
			 | 
			
			
				
				-			   ntohs ( st_server->st_port ) ); 
			 | 
		
		
	
		
			
			| 
				759
			 | 
			
				
			 | 
			
			
				
				-		tmp.port = buf; 
			 | 
		
		
	
		
			
			| 
				760
			 | 
			
				
			 | 
			
			
				
				-	} 
			 | 
		
		
	
		
			
			| 
				761
			 | 
			
				
			 | 
			
			
				
				-	tmp.path = filename; 
			 | 
		
		
	
		
			
			| 
				762
			 | 
			
				
			 | 
			
			
				
				-	uri = uri_dup ( &tmp ); 
			 | 
		
		
	
		
			
			| 
				763
			 | 
			
				
			 | 
			
			
				
				-	return uri; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				793
			 | 
			
			
				
				+	return tftp_uri ( sa_server, filename ); 
			 | 
		
		
	
		
			
			| 
				764
			 | 
			
				794
			 | 
			
			
				
				 } 
			 |