| 
				
			 | 
			
			
				
				@@ -109,23 +109,39 @@ static void ftp_done ( struct ftp_request *ftp, int rc ) { 
			 | 
		
		
	
		
			
			| 
				109
			 | 
			
				109
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				110
			 | 
			
				110
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				111
			 | 
			
				111
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				112
			 | 
			
			
				
				+/** An FTP control channel string */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				113
			 | 
			
			
				
				+struct ftp_control_string { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				114
			 | 
			
			
				
				+	/** Literal portion */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				115
			 | 
			
			
				
				+	const char *literal; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				116
			 | 
			
			
				
				+	/** Variable portion 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				117
			 | 
			
			
				
				+	 * 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				118
			 | 
			
			
				
				+	 * @v ftp	FTP request 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				119
			 | 
			
			
				
				+	 * @ret string	Variable portion of string 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				120
			 | 
			
			
				
				+	 */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				121
			 | 
			
			
				
				+	const char * ( *variable ) ( struct ftp_request *ftp ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				122
			 | 
			
			
				
				+}; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				123
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				112
			 | 
			
				124
			 | 
			
			
				
				 /** 
			 | 
		
		
	
		
			
			| 
				113
			 | 
			
				
			 | 
			
			
				
				- * FTP control channel strings 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				125
			 | 
			
			
				
				+ * Retrieve FTP pathname 
			 | 
		
		
	
		
			
			| 
				114
			 | 
			
				126
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				115
			 | 
			
				
			 | 
			
			
				
				- * These are used as printf() format strings.  Since only one of them 
			 | 
		
		
	
		
			
			| 
				116
			 | 
			
				
			 | 
			
			
				
				- * (RETR) takes an argument, we always supply that argument to the 
			 | 
		
		
	
		
			
			| 
				117
			 | 
			
				
			 | 
			
			
				
				- * snprintf() call. 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				127
			 | 
			
			
				
				+ * @v ftp		FTP request 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				128
			 | 
			
			
				
				+ * @ret path		FTP pathname 
			 | 
		
		
	
		
			
			| 
				118
			 | 
			
				129
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				119
			 | 
			
				
			 | 
			
			
				
				-static const char * ftp_strings[] = { 
			 | 
		
		
	
		
			
			| 
				120
			 | 
			
				
			 | 
			
			
				
				-	[FTP_CONNECT]	= NULL, 
			 | 
		
		
	
		
			
			| 
				121
			 | 
			
				
			 | 
			
			
				
				-	[FTP_USER]	= "USER anonymous\r\n", 
			 | 
		
		
	
		
			
			| 
				122
			 | 
			
				
			 | 
			
			
				
				-	[FTP_PASS]	= "PASS etherboot@etherboot.org\r\n", 
			 | 
		
		
	
		
			
			| 
				123
			 | 
			
				
			 | 
			
			
				
				-	[FTP_TYPE]	= "TYPE I\r\n", 
			 | 
		
		
	
		
			
			| 
				124
			 | 
			
				
			 | 
			
			
				
				-	[FTP_PASV]	= "PASV\r\n", 
			 | 
		
		
	
		
			
			| 
				125
			 | 
			
				
			 | 
			
			
				
				-	[FTP_RETR]	= "RETR %s\r\n", 
			 | 
		
		
	
		
			
			| 
				126
			 | 
			
				
			 | 
			
			
				
				-	[FTP_WAIT]	= NULL, 
			 | 
		
		
	
		
			
			| 
				127
			 | 
			
				
			 | 
			
			
				
				-	[FTP_QUIT]	= "QUIT\r\n", 
			 | 
		
		
	
		
			
			| 
				128
			 | 
			
				
			 | 
			
			
				
				-	[FTP_DONE]	= NULL, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				130
			 | 
			
			
				
				+static const char * ftp_uri_path ( struct ftp_request *ftp ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				131
			 | 
			
			
				
				+	return ftp->uri->path; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				132
			 | 
			
			
				
				+} 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				133
			 | 
			
			
				
				+ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				134
			 | 
			
			
				
				+/** FTP control channel strings */ 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				135
			 | 
			
			
				
				+static struct ftp_control_string ftp_strings[] = { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				136
			 | 
			
			
				
				+	[FTP_CONNECT]	= { NULL, NULL }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				137
			 | 
			
			
				
				+	[FTP_USER]	= { "USER anonymous", NULL }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				138
			 | 
			
			
				
				+	[FTP_PASS]	= { "PASS etherboot@etherboot.org", NULL }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				139
			 | 
			
			
				
				+	[FTP_TYPE]	= { "TYPE I", NULL }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				140
			 | 
			
			
				
				+	[FTP_PASV]	= { "PASV", NULL }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				141
			 | 
			
			
				
				+	[FTP_RETR]	= { "RETR ", ftp_uri_path }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				142
			 | 
			
			
				
				+	[FTP_WAIT]	= { NULL, NULL }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				143
			 | 
			
			
				
				+	[FTP_QUIT]	= { "QUIT", NULL }, 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				144
			 | 
			
			
				
				+	[FTP_DONE]	= { NULL, NULL }, 
			 | 
		
		
	
		
			
			| 
				129
			 | 
			
				145
			 | 
			
			
				
				 }; 
			 | 
		
		
	
		
			
			| 
				130
			 | 
			
				146
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				131
			 | 
			
				147
			 | 
			
			
				
				 /** 
			 | 
		
		
	
	
		
			
			| 
				
			 | 
			
			
				
				@@ -178,18 +194,23 @@ static void ftp_parse_value ( char **text, uint8_t *value, size_t len ) { 
			 | 
		
		
	
		
			
			| 
				178
			 | 
			
				194
			 | 
			
			
				
				  * 
			 | 
		
		
	
		
			
			| 
				179
			 | 
			
				195
			 | 
			
			
				
				  */ 
			 | 
		
		
	
		
			
			| 
				180
			 | 
			
				196
			 | 
			
			
				
				 static void ftp_next_state ( struct ftp_request *ftp ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				197
			 | 
			
			
				
				+	struct ftp_control_string *ftp_string; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				198
			 | 
			
			
				
				+	const char *literal; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				199
			 | 
			
			
				
				+	const char *variable; 
			 | 
		
		
	
		
			
			| 
				181
			 | 
			
				200
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				182
			 | 
			
				201
			 | 
			
			
				
				 	/* Move to next state */ 
			 | 
		
		
	
		
			
			| 
				183
			 | 
			
				202
			 | 
			
			
				
				 	if ( ftp->state < FTP_DONE ) 
			 | 
		
		
	
		
			
			| 
				184
			 | 
			
				203
			 | 
			
			
				
				 		ftp->state++; 
			 | 
		
		
	
		
			
			| 
				185
			 | 
			
				204
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				186
			 | 
			
				205
			 | 
			
			
				
				 	/* Send control string if needed */ 
			 | 
		
		
	
		
			
			| 
				187
			 | 
			
				
			 | 
			
			
				
				-	if ( ftp_strings[ftp->state] != NULL ) { 
			 | 
		
		
	
		
			
			| 
				188
			 | 
			
				
			 | 
			
			
				
				-		DBGC ( ftp, "FTP %p sending ", ftp ); 
			 | 
		
		
	
		
			
			| 
				189
			 | 
			
				
			 | 
			
			
				
				-		DBGC ( ftp, ftp_strings[ftp->state], ftp->uri->path ); 
			 | 
		
		
	
		
			
			| 
				190
			 | 
			
				
			 | 
			
			
				
				-		xfer_printf ( &ftp->control, ftp_strings[ftp->state], 
			 | 
		
		
	
		
			
			| 
				191
			 | 
			
				
			 | 
			
			
				
				-			      ftp->uri->path ); 
			 | 
		
		
	
		
			
			| 
				192
			 | 
			
				
			 | 
			
			
				
				-	}	 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				206
			 | 
			
			
				
				+	ftp_string = &ftp_strings[ftp->state]; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				207
			 | 
			
			
				
				+	literal = ftp_string->literal; 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				208
			 | 
			
			
				
				+	variable = ( ftp_string->variable ? 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				209
			 | 
			
			
				
				+		     ftp_string->variable ( ftp ) : "" ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				210
			 | 
			
			
				
				+	if ( literal ) { 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				211
			 | 
			
			
				
				+		DBGC ( ftp, "FTP %p sending %s%s\n", ftp, literal, variable ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				212
			 | 
			
			
				
				+		xfer_printf ( &ftp->control, "%s%s\r\n", literal, variable ); 
			 | 
		
		
	
		
			
			| 
				
			 | 
			
				213
			 | 
			
			
				
				+	} 
			 | 
		
		
	
		
			
			| 
				193
			 | 
			
				214
			 | 
			
			
				
				 } 
			 | 
		
		
	
		
			
			| 
				194
			 | 
			
				215
			 | 
			
			
				
				  
			 | 
		
		
	
		
			
			| 
				195
			 | 
			
				216
			 | 
			
			
				
				 /** 
			 |