downloader.c File Reference

Image downloader. More...

#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.


Detailed Description

Image downloader.

Definition in file downloader.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER   ) 

static void downloader_free ( struct refcnt refcnt  )  [static]

Free downloader object.

Parameters:
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.

Parameters:
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.

Parameters:
downloader Downloader
len Required minimum size
Return values:
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.

Parameters:
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.

Parameters:
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.

Parameters:
xfer Downloader data transfer interface
iobuf Datagram I/O buffer
meta Data transfer metadata
Return values:
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.

Parameters:
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.

Parameters:
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()
Return values:
rc Return status code
Instantiates a downloader object to download the specified URI into the specified image object. If the download is successful, the image registration routine 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 }


Variable Documentation

Initial value:

 {
        .done           = ignore_job_done,
        .kill           = downloader_job_kill,
        .progress       = downloader_job_progress,
}
Downloader job control interface operations.

Definition at line 156 of file downloader.c.

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,
}
Downloader data transfer interface operations.

Definition at line 227 of file downloader.c.


Generated on Tue Apr 6 20:01:14 2010 for gPXE by  doxygen 1.5.7.1