|
@@ -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
|
/**
|