#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <gpxe/xfer.h>
#include <gpxe/open.h>
#include <gpxe/job.h>
#include <gpxe/uaccess.h>
#include <gpxe/umalloc.h>
#include <gpxe/image.h>
#include <gpxe/downloader.h>
Go to the source code of this file.
Data Structures | |
| struct | downloader |
| A downloader. More... | |
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| static void | downloader_free (struct refcnt *refcnt) |
| Free downloader object. | |
| static void | downloader_finished (struct downloader *downloader, int rc) |
| Terminate download. | |
| static int | downloader_ensure_size (struct downloader *downloader, size_t len) |
| Ensure that download buffer is large enough for the specified size. | |
| static void | downloader_job_kill (struct job_interface *job) |
| Handle kill() event received via job control interface. | |
| static void | downloader_job_progress (struct job_interface *job, struct job_progress *progress) |
| Report progress of download job. | |
| static int | downloader_xfer_deliver_iob (struct xfer_interface *xfer, struct io_buffer *iobuf, struct xfer_metadata *meta) |
| Handle deliver_raw() event received via data transfer interface. | |
| static void | downloader_xfer_close (struct xfer_interface *xfer, int rc) |
| Handle close() event received via data transfer interface. | |
| int | create_downloader (struct job_interface *job, struct image *image, int(*register_image)(struct image *image), int type,...) |
| Instantiate a downloader. | |
Variables | |
| static struct job_interface_operations | downloader_job_operations |
| Downloader job control interface operations. | |
| static struct xfer_interface_operations | downloader_xfer_operations |
| Downloader data transfer interface operations. | |
Definition in file downloader.c.
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| static void downloader_free | ( | struct refcnt * | refcnt | ) | [static] |
Free downloader object.
| refcnt | Downloader reference counter |
Definition at line 61 of file downloader.c.
References container_of, free(), downloader::image, and image_put().
Referenced by create_downloader().
00061 { 00062 struct downloader *downloader = 00063 container_of ( refcnt, struct downloader, refcnt ); 00064 00065 image_put ( downloader->image ); 00066 free ( downloader ); 00067 }
| static void downloader_finished | ( | struct downloader * | downloader, | |
| int | rc | |||
| ) | [static] |
Terminate download.
| downloader | Downloader | |
| rc | Reason for termination |
Definition at line 75 of file downloader.c.
References downloader::job, job_done(), job_nullify(), downloader::xfer, and xfer_close().
Referenced by create_downloader(), downloader_job_kill(), and downloader_xfer_close().
00075 { 00076 00077 /* Block further incoming messages */ 00078 job_nullify ( &downloader->job ); 00079 xfer_nullify ( &downloader->xfer ); 00080 00081 /* Free resources and close interfaces */ 00082 xfer_close ( &downloader->xfer, rc ); 00083 job_done ( &downloader->job, rc ); 00084 }
| static int downloader_ensure_size | ( | struct downloader * | downloader, | |
| size_t | len | |||
| ) | [static] |
Ensure that download buffer is large enough for the specified size.
| downloader | Downloader | |
| len | Required minimum size |
| rc | Return status code |
Definition at line 93 of file downloader.c.
References image::data, DBGC, ENOBUFS, downloader::image, image::len, and urealloc().
Referenced by downloader_xfer_deliver_iob().
00094 { 00095 userptr_t new_buffer; 00096 00097 /* If buffer is already large enough, do nothing */ 00098 if ( len <= downloader->image->len ) 00099 return 0; 00100 00101 DBGC ( downloader, "Downloader %p extending to %zd bytes\n", 00102 downloader, len ); 00103 00104 /* Extend buffer */ 00105 new_buffer = urealloc ( downloader->image->data, len ); 00106 if ( ! new_buffer ) { 00107 DBGC ( downloader, "Downloader %p could not extend buffer to " 00108 "%zd bytes\n", downloader, len ); 00109 return -ENOBUFS; 00110 } 00111 downloader->image->data = new_buffer; 00112 downloader->image->len = len; 00113 00114 return 0; 00115 }
| static void downloader_job_kill | ( | struct job_interface * | job | ) | [static] |
Handle kill() event received via job control interface.
| job | Downloader job control interface |
Definition at line 128 of file downloader.c.
References container_of, downloader_finished(), and ECANCELED.
00128 { 00129 struct downloader *downloader = 00130 container_of ( job, struct downloader, job ); 00131 00132 /* Terminate download */ 00133 downloader_finished ( downloader, -ECANCELED ); 00134 }
| static void downloader_job_progress | ( | struct job_interface * | job, | |
| struct job_progress * | progress | |||
| ) | [static] |
Report progress of download job.
| job | Downloader job control interface | |
| progress | Progress report to fill in |
Definition at line 142 of file downloader.c.
References job_progress::completed, container_of, downloader::image, image::len, downloader::pos, and job_progress::total.
00143 { 00144 struct downloader *downloader = 00145 container_of ( job, struct downloader, job ); 00146 00147 /* This is not entirely accurate, since downloaded data may 00148 * arrive out of order (e.g. with multicast protocols), but 00149 * it's a reasonable first approximation. 00150 */ 00151 progress->completed = downloader->pos; 00152 progress->total = downloader->image->len; 00153 }
| static int downloader_xfer_deliver_iob | ( | struct xfer_interface * | xfer, | |
| struct io_buffer * | iobuf, | |||
| struct xfer_metadata * | meta | |||
| ) | [static] |
Handle deliver_raw() event received via data transfer interface.
| xfer | Downloader data transfer interface | |
| iobuf | Datagram I/O buffer | |
| meta | Data transfer metadata |
| rc | Return status code |
Definition at line 176 of file downloader.c.
References container_of, copy_to_user(), io_buffer::data, image::data, downloader_ensure_size(), free_iob(), downloader::image, iob_len(), max, xfer_metadata::offset, downloader::pos, SEEK_CUR, and xfer_metadata::whence.
00178 { 00179 struct downloader *downloader = 00180 container_of ( xfer, struct downloader, xfer ); 00181 size_t len; 00182 size_t max; 00183 int rc; 00184 00185 /* Calculate new buffer position */ 00186 if ( meta->whence != SEEK_CUR ) 00187 downloader->pos = 0; 00188 downloader->pos += meta->offset; 00189 00190 /* Ensure that we have enough buffer space for this data */ 00191 len = iob_len ( iobuf ); 00192 max = ( downloader->pos + len ); 00193 if ( ( rc = downloader_ensure_size ( downloader, max ) ) != 0 ) 00194 goto done; 00195 00196 /* Copy data to buffer */ 00197 copy_to_user ( downloader->image->data, downloader->pos, 00198 iobuf->data, len ); 00199 00200 /* Update current buffer position */ 00201 downloader->pos += len; 00202 00203 done: 00204 free_iob ( iobuf ); 00205 return rc; 00206 }
| static void downloader_xfer_close | ( | struct xfer_interface * | xfer, | |
| int | rc | |||
| ) | [static] |
Handle close() event received via data transfer interface.
| xfer | Downloader data transfer interface | |
| rc | Reason for close |
Definition at line 214 of file downloader.c.
References container_of, downloader_finished(), downloader::image, and downloader::register_image.
00214 { 00215 struct downloader *downloader = 00216 container_of ( xfer, struct downloader, xfer ); 00217 00218 /* Register image if download was successful */ 00219 if ( rc == 0 ) 00220 rc = downloader->register_image ( downloader->image ); 00221 00222 /* Terminate download */ 00223 downloader_finished ( downloader, rc ); 00224 }
| int create_downloader | ( | struct job_interface * | job, | |
| struct image * | image, | |||
| int(*)(struct image *image) | register_image, | |||
| int | type, | |||
| ... | ||||
| ) |
Instantiate a downloader.
| job | Job control interface | |
| image | Image to fill with downloaded file | |
| register_image | Image registration routine | |
| type | Location type to pass to xfer_open() | |
| ... | Remaining arguments to pass to xfer_open() |
| rc | Return status code |
register_image() will be called.
Definition at line 256 of file downloader.c.
References downloader_finished(), downloader_free(), ENOMEM, refcnt::free, downloader::image, image_get(), downloader::job, job_init(), job_plug_plug(), ref_put(), downloader::refcnt, register_image(), downloader::register_image, va_end, va_start, downloader::xfer, xfer_init(), xfer_vopen(), and zalloc().
Referenced by imgfetch().
00258 { 00259 struct downloader *downloader; 00260 va_list args; 00261 int rc; 00262 00263 /* Allocate and initialise structure */ 00264 downloader = zalloc ( sizeof ( *downloader ) ); 00265 if ( ! downloader ) 00266 return -ENOMEM; 00267 downloader->refcnt.free = downloader_free; 00268 job_init ( &downloader->job, &downloader_job_operations, 00269 &downloader->refcnt ); 00270 xfer_init ( &downloader->xfer, &downloader_xfer_operations, 00271 &downloader->refcnt ); 00272 downloader->image = image_get ( image ); 00273 downloader->register_image = register_image; 00274 va_start ( args, type ); 00275 00276 /* Instantiate child objects and attach to our interfaces */ 00277 if ( ( rc = xfer_vopen ( &downloader->xfer, type, args ) ) != 0 ) 00278 goto err; 00279 00280 /* Attach parent interface, mortalise self, and return */ 00281 job_plug_plug ( &downloader->job, job ); 00282 ref_put ( &downloader->refcnt ); 00283 va_end ( args ); 00284 return 0; 00285 00286 err: 00287 downloader_finished ( downloader, rc ); 00288 ref_put ( &downloader->refcnt ); 00289 va_end ( args ); 00290 return rc; 00291 }
struct job_interface_operations downloader_job_operations [static] |
Initial value:
{
.done = ignore_job_done,
.kill = downloader_job_kill,
.progress = downloader_job_progress,
}
Definition at line 156 of file downloader.c.
struct xfer_interface_operations downloader_xfer_operations [static] |
Initial value:
{
.close = downloader_xfer_close,
.vredirect = xfer_vreopen,
.window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob,
.deliver_iob = downloader_xfer_deliver_iob,
.deliver_raw = xfer_deliver_as_iob,
}
Definition at line 227 of file downloader.c.
1.5.7.1