pxe_file.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007 #include <stdlib.h>
00008 #include <stdio.h>
00009 #include <errno.h>
00010 #include <byteswap.h>
00011 #include <gpxe/uaccess.h>
00012 #include <gpxe/posix_io.h>
00013 #include <gpxe/features.h>
00014 #include <pxe.h>
00015 #include <realmode.h>
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 FILE_LICENCE ( GPL2_OR_LATER );
00038
00039 FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 2 );
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 PXENV_EXIT_t pxenv_file_open ( struct s_PXENV_FILE_OPEN *file_open ) {
00053 userptr_t filename;
00054 size_t filename_len;
00055 int fd;
00056
00057 DBG ( "PXENV_FILE_OPEN" );
00058
00059
00060 filename = real_to_user ( file_open->FileName.segment,
00061 file_open->FileName.offset );
00062 filename_len = strlen_user ( filename, 0 );
00063 {
00064 char uri_string[ filename_len + 1 ];
00065
00066 copy_from_user ( uri_string, filename, 0,
00067 sizeof ( uri_string ) );
00068 DBG ( " %s", uri_string );
00069 fd = open ( uri_string );
00070 }
00071
00072 if ( fd < 0 ) {
00073 file_open->Status = PXENV_STATUS ( fd );
00074 return PXENV_EXIT_FAILURE;
00075 }
00076
00077 DBG ( " as file %d", fd );
00078
00079 file_open->FileHandle = fd;
00080 file_open->Status = PXENV_STATUS_SUCCESS;
00081 return PXENV_EXIT_SUCCESS;
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 PXENV_EXIT_t pxenv_file_close ( struct s_PXENV_FILE_CLOSE *file_close ) {
00095
00096 DBG ( "PXENV_FILE_CLOSE %d", file_close->FileHandle );
00097
00098 close ( file_close->FileHandle );
00099 file_close->Status = PXENV_STATUS_SUCCESS;
00100 return PXENV_EXIT_SUCCESS;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 PXENV_EXIT_t pxenv_file_select ( struct s_PXENV_FILE_SELECT *file_select ) {
00115 fd_set fdset;
00116 int ready;
00117
00118 DBG ( "PXENV_FILE_SELECT %d", file_select->FileHandle );
00119
00120 FD_ZERO ( &fdset );
00121 FD_SET ( file_select->FileHandle, &fdset );
00122 if ( ( ready = select ( &fdset, 0 ) ) < 0 ) {
00123 file_select->Status = PXENV_STATUS ( ready );
00124 return PXENV_EXIT_FAILURE;
00125 }
00126
00127 file_select->Ready = ( ready ? RDY_READ : 0 );
00128 file_select->Status = PXENV_STATUS_SUCCESS;
00129 return PXENV_EXIT_SUCCESS;
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 PXENV_EXIT_t pxenv_file_read ( struct s_PXENV_FILE_READ *file_read ) {
00147 userptr_t buffer;
00148 ssize_t len;
00149
00150 DBG ( "PXENV_FILE_READ %d to %04x:%04x+%04x", file_read->FileHandle,
00151 file_read->Buffer.segment, file_read->Buffer.offset,
00152 file_read->BufferSize );
00153
00154 buffer = real_to_user ( file_read->Buffer.segment,
00155 file_read->Buffer.offset );
00156 if ( ( len = read_user ( file_read->FileHandle, buffer, 0,
00157 file_read->BufferSize ) ) < 0 ) {
00158 file_read->Status = PXENV_STATUS ( len );
00159 return PXENV_EXIT_FAILURE;
00160 }
00161
00162 DBG ( " read %04zx", ( ( size_t ) len ) );
00163
00164 file_read->BufferSize = len;
00165 file_read->Status = PXENV_STATUS_SUCCESS;
00166 return PXENV_EXIT_SUCCESS;
00167 }
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 PXENV_EXIT_t pxenv_get_file_size ( struct s_PXENV_GET_FILE_SIZE
00180 *get_file_size ) {
00181 ssize_t filesize;
00182
00183 DBG ( "PXENV_GET_FILE_SIZE %d", get_file_size->FileHandle );
00184
00185 filesize = fsize ( get_file_size->FileHandle );
00186 if ( filesize < 0 ) {
00187 get_file_size->Status = PXENV_STATUS ( filesize );
00188 return PXENV_EXIT_FAILURE;
00189 }
00190
00191 DBG ( " is %zd", ( ( size_t ) filesize ) );
00192
00193 get_file_size->FileSize = filesize;
00194 get_file_size->Status = PXENV_STATUS_SUCCESS;
00195 return PXENV_EXIT_SUCCESS;
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) {
00209 userptr_t command;
00210 size_t command_len;
00211 int rc;
00212
00213 DBG ( "PXENV_FILE_EXEC" );
00214
00215
00216 command = real_to_user ( file_exec->Command.segment,
00217 file_exec->Command.offset );
00218 command_len = strlen_user ( command, 0 );
00219 {
00220 char command_string[ command_len + 1 ];
00221
00222 copy_from_user ( command_string, command, 0,
00223 sizeof ( command_string ) );
00224 DBG ( " %s", command_string );
00225
00226 if ( ( rc = system ( command_string ) ) != 0 ) {
00227 file_exec->Status = PXENV_STATUS ( rc );
00228 return PXENV_EXIT_FAILURE;
00229 }
00230 }
00231
00232 file_exec->Status = PXENV_STATUS_SUCCESS;
00233 return PXENV_EXIT_SUCCESS;
00234 }
00235
00236 segoff_t __data16 ( pxe_exit_hook ) = { 0, 0 };
00237 #define pxe_exit_hook __use_data16 ( pxe_exit_hook )
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253 PXENV_EXIT_t pxenv_file_api_check ( struct s_PXENV_FILE_API_CHECK *file_api_check ) {
00254 DBG ( "PXENV_FILE_API_CHECK" );
00255
00256 if ( file_api_check->Magic != 0x91d447b2 ) {
00257 file_api_check->Status = PXENV_STATUS_BAD_FUNC;
00258 return PXENV_EXIT_FAILURE;
00259 } else if ( file_api_check->Size <
00260 sizeof(struct s_PXENV_FILE_API_CHECK) ) {
00261 file_api_check->Status = PXENV_STATUS_OUT_OF_RESOURCES;
00262 return PXENV_EXIT_FAILURE;
00263 } else {
00264 file_api_check->Status = PXENV_STATUS_SUCCESS;
00265 file_api_check->Size = sizeof(struct s_PXENV_FILE_API_CHECK);
00266 file_api_check->Magic = 0xe9c17b20;
00267 file_api_check->Provider = 0x45585067;
00268 file_api_check->APIMask = 0x0000007f;
00269
00270 if ( pxe_exit_hook.segment | pxe_exit_hook.offset )
00271
00272 file_api_check->APIMask |= 0x00000080;
00273 file_api_check->Flags = 0;
00274 return PXENV_EXIT_SUCCESS;
00275 }
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 PXENV_EXIT_t pxenv_file_exit_hook ( struct s_PXENV_FILE_EXIT_HOOK
00290 *file_exit_hook ) {
00291 DBG ( "PXENV_FILE_EXIT_HOOK" );
00292
00293
00294 if ( pxe_exit_hook.segment | pxe_exit_hook.offset ) {
00295
00296 pxe_exit_hook.segment = file_exit_hook->Hook.segment;
00297 pxe_exit_hook.offset = file_exit_hook->Hook.offset;
00298 file_exit_hook->Status = PXENV_STATUS_SUCCESS;
00299 return PXENV_EXIT_SUCCESS;
00300 }
00301
00302 DBG ( " not NBP" );
00303 file_exit_hook->Status = PXENV_STATUS_UNSUPPORTED;
00304 return PXENV_EXIT_FAILURE;
00305 }
00306