00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 FILE_LICENCE ( GPL2_OR_LATER );
00020
00021 #include <string.h>
00022 #include <stdio.h>
00023 #include <errno.h>
00024 #include <gpxe/xfer.h>
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 static struct xfer_metadata dummy_metadata;
00039
00040
00041
00042
00043
00044
00045
00046 void xfer_close ( struct xfer_interface *xfer, int rc ) {
00047 struct xfer_interface *dest = xfer_get_dest ( xfer );
00048 struct xfer_interface_operations *op = xfer->op;
00049
00050 DBGC ( xfer, "XFER %p->%p close\n", xfer, dest );
00051
00052 xfer_unplug ( xfer );
00053 xfer_nullify ( xfer );
00054 dest->op->close ( dest, rc );
00055 xfer->op = op;
00056 xfer_put ( dest );
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 int xfer_vredirect ( struct xfer_interface *xfer, int type, va_list args ) {
00068 struct xfer_interface *dest = xfer_get_dest ( xfer );
00069 int rc;
00070
00071 DBGC ( xfer, "XFER %p->%p redirect\n", xfer, dest );
00072
00073 rc = dest->op->vredirect ( dest, type, args );
00074
00075 if ( rc != 0 ) {
00076 DBGC ( xfer, "XFER %p<-%p redirect: %s\n", xfer, dest,
00077 strerror ( rc ) );
00078 }
00079 xfer_put ( dest );
00080 return rc;
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 int xfer_redirect ( struct xfer_interface *xfer, int type, ... ) {
00092 va_list args;
00093 int rc;
00094
00095 va_start ( args, type );
00096 rc = xfer_vredirect ( xfer, type, args );
00097 va_end ( args );
00098 return rc;
00099 }
00100
00101
00102
00103
00104
00105
00106
00107 size_t xfer_window ( struct xfer_interface *xfer ) {
00108 struct xfer_interface *dest = xfer_get_dest ( xfer );
00109 size_t len;
00110
00111 len = dest->op->window ( dest );
00112
00113 xfer_put ( dest );
00114 return len;
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124 struct io_buffer * xfer_alloc_iob ( struct xfer_interface *xfer, size_t len ) {
00125 struct xfer_interface *dest = xfer_get_dest ( xfer );
00126 struct io_buffer *iobuf;
00127
00128 DBGC ( xfer, "XFER %p->%p alloc_iob %zd\n", xfer, dest, len );
00129
00130 iobuf = dest->op->alloc_iob ( dest, len );
00131
00132 if ( ! iobuf ) {
00133 DBGC ( xfer, "XFER %p<-%p alloc_iob failed\n", xfer, dest );
00134 }
00135 xfer_put ( dest );
00136 return iobuf;
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 int xfer_deliver_iob_meta ( struct xfer_interface *xfer,
00148 struct io_buffer *iobuf,
00149 struct xfer_metadata *meta ) {
00150 struct xfer_interface *dest = xfer_get_dest ( xfer );
00151 int rc;
00152
00153 DBGC ( xfer, "XFER %p->%p deliver_iob %zd\n", xfer, dest,
00154 iob_len ( iobuf ) );
00155
00156 rc = dest->op->deliver_iob ( dest, iobuf, meta );
00157
00158 if ( rc != 0 ) {
00159 DBGC ( xfer, "XFER %p<-%p deliver_iob: %s\n", xfer, dest,
00160 strerror ( rc ) );
00161 }
00162 xfer_put ( dest );
00163 return rc;
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173 int xfer_deliver_iob ( struct xfer_interface *xfer,
00174 struct io_buffer *iobuf ) {
00175 return xfer_deliver_iob_meta ( xfer, iobuf, &dummy_metadata );
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185 int xfer_deliver_raw ( struct xfer_interface *xfer,
00186 const void *data, size_t len ) {
00187 struct xfer_interface *dest = xfer_get_dest ( xfer );
00188 int rc;
00189
00190 DBGC ( xfer, "XFER %p->%p deliver_raw %p+%zd\n", xfer, dest,
00191 data, len );
00192
00193 rc = dest->op->deliver_raw ( dest, data, len );
00194
00195 if ( rc != 0 ) {
00196 DBGC ( xfer, "XFER %p<-%p deliver_raw: %s\n", xfer, dest,
00197 strerror ( rc ) );
00198 }
00199 xfer_put ( dest );
00200 return rc;
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 int xfer_vprintf ( struct xfer_interface *xfer, const char *format,
00212 va_list args ) {
00213 size_t len;
00214 va_list args_tmp;
00215
00216 va_copy ( args_tmp, args );
00217 len = vsnprintf ( NULL, 0, format, args );
00218 {
00219 char buf[len + 1];
00220 vsnprintf ( buf, sizeof ( buf ), format, args_tmp );
00221 va_end ( args_tmp );
00222 return xfer_deliver_raw ( xfer, buf, len );
00223 }
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 int xfer_printf ( struct xfer_interface *xfer, const char *format, ... ) {
00235 va_list args;
00236 int rc;
00237
00238 va_start ( args, format );
00239 rc = xfer_vprintf ( xfer, format, args );
00240 va_end ( args );
00241 return rc;
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 int xfer_seek ( struct xfer_interface *xfer, off_t offset, int whence ) {
00253 struct io_buffer *iobuf;
00254 struct xfer_metadata meta = {
00255 .offset = offset,
00256 .whence = whence,
00257 };
00258
00259 DBGC ( xfer, "XFER %p seek %s+%ld\n", xfer,
00260 whence_text ( whence ), offset );
00261
00262
00263 iobuf = xfer_alloc_iob ( xfer, 0 );
00264 if ( ! iobuf )
00265 return -ENOMEM;
00266 return xfer_deliver_iob_meta ( xfer, iobuf, &meta );
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 void ignore_xfer_close ( struct xfer_interface *xfer __unused,
00285 int rc __unused ) {
00286
00287 }
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 int ignore_xfer_vredirect ( struct xfer_interface *xfer __unused,
00298 int type __unused, va_list args __unused ) {
00299 return 0;
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 size_t unlimited_xfer_window ( struct xfer_interface *xfer __unused ) {
00312 return ~( ( size_t ) 0 );
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 size_t no_xfer_window ( struct xfer_interface *xfer __unused ) {
00325 return 0;
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335 struct io_buffer *
00336 default_xfer_alloc_iob ( struct xfer_interface *xfer __unused, size_t len ) {
00337 return alloc_iob ( len );
00338 }
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351 int xfer_deliver_as_raw ( struct xfer_interface *xfer,
00352 struct io_buffer *iobuf,
00353 struct xfer_metadata *meta __unused ) {
00354 int rc;
00355
00356 rc = xfer->op->deliver_raw ( xfer, iobuf->data, iob_len ( iobuf ) );
00357 free_iob ( iobuf );
00358 return rc;
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 int xfer_deliver_as_iob ( struct xfer_interface *xfer,
00373 const void *data, size_t len ) {
00374 struct io_buffer *iobuf;
00375
00376 iobuf = xfer->op->alloc_iob ( xfer, len );
00377 if ( ! iobuf )
00378 return -ENOMEM;
00379
00380 memcpy ( iob_put ( iobuf, len ), data, len );
00381 return xfer->op->deliver_iob ( xfer, iobuf, &dummy_metadata );
00382 }
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 int ignore_xfer_deliver_raw ( struct xfer_interface *xfer,
00393 const void *data __unused, size_t len ) {
00394 DBGC ( xfer, "XFER %p %zd bytes delivered %s\n", xfer, len,
00395 ( ( xfer == &null_xfer ) ?
00396 "before connection" : "after termination" ) );
00397 return 0;
00398 }
00399
00400
00401 struct xfer_interface_operations null_xfer_ops = {
00402 .close = ignore_xfer_close,
00403 .vredirect = ignore_xfer_vredirect,
00404 .window = unlimited_xfer_window,
00405 .alloc_iob = default_xfer_alloc_iob,
00406 .deliver_iob = xfer_deliver_as_raw,
00407 .deliver_raw = ignore_xfer_deliver_raw,
00408 };
00409
00410
00411
00412
00413
00414
00415
00416
00417 struct xfer_interface null_xfer = XFER_INIT ( &null_xfer_ops );