iPXE
image.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 * You can also choose to distribute this program under the terms of
20 * the Unmodified Binary Distribution Licence (as given in the file
21 * COPYING.UBDL), provided that you have satisfied its requirements.
22 */
23
24FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25FILE_SECBOOT ( PERMITTED );
26
27#include <stddef.h>
28#include <string.h>
29#include <stdlib.h>
30#include <stdio.h>
31#include <ctype.h>
32#include <errno.h>
33#include <assert.h>
34#include <libgen.h>
35#include <syslog.h>
36#include <ipxe/list.h>
37#include <ipxe/uaccess.h>
38#include <ipxe/umalloc.h>
39#include <ipxe/uri.h>
40#include <ipxe/image.h>
41
42/** @file
43 *
44 * Executable images
45 *
46 */
47
48/* Disambiguate the various error causes */
49#define EACCES_UNTRUSTED \
50 __einfo_error ( EINFO_EACCES_UNTRUSTED )
51#define EINFO_EACCES_UNTRUSTED \
52 __einfo_uniqify ( EINFO_EACCES, 0x01, "Untrusted image" )
53#define EACCES_PERMANENT \
54 __einfo_error ( EINFO_EACCES_PERMANENT )
55#define EINFO_EACCES_PERMANENT \
56 __einfo_uniqify ( EINFO_EACCES, 0x02, "Trust requirement is permanent" )
57
58/** List of registered images */
60
61/** Image selected for execution */
63 .name = "SELECTED",
64};
65
66/** Currently-executing image */
68 .name = "CURRENT",
69};
70
71/** Current image trust requirement */
73
74/** Prevent changes to image trust requirement */
76
77/** Empty image terminating NUL */
78const char empty_image_data[] = { '\0' };
79
80/**
81 * Free executable image
82 *
83 * @v refcnt Reference counter
84 *
85 * Image consumers must call image_put() rather than calling
86 * free_image() directly. This function is exposed for use only by
87 * static images.
88 */
89void free_image ( struct refcnt *refcnt ) {
90 struct image *image = container_of ( refcnt, struct image, refcnt );
91 struct image_tag *tag;
92
93 /* Sanity check: free_image() should not be called directly on
94 * dynamically allocated images.
95 */
96 assert ( refcnt->count < 0 );
97 DBGC ( image, "IMAGE %s freed\n", image->name );
98
99 /* Clear any tag weak references */
101 if ( tag->image == image )
102 tag->image = NULL;
103 }
104
105 /* Free dynamic allocations used by both static and dynamic images */
106 free ( image->cmdline );
107 uri_put ( image->uri );
109
110 /* Free image name, if dynamically allocated */
111 if ( ! ( image->flags & IMAGE_STATIC_NAME ) )
112 free ( image->name );
113
114 /* Free image data and image itself, if dynamically allocated */
115 if ( ! ( image->flags & IMAGE_STATIC ) ) {
116 image_set_len ( image, 0 );
117 free ( image );
118 }
119}
120
121/**
122 * Allocate executable image
123 *
124 * @v uri URI, or NULL
125 * @ret image Executable image
126 */
127struct image * alloc_image ( struct uri *uri ) {
128 struct image *image;
129 int rc;
130
131 /* Allocate image */
132 image = zalloc ( sizeof ( *image ) );
133 if ( ! image )
134 goto err_alloc;
135
136 /* Initialise image */
138 if ( uri && ( ( rc = image_set_uri ( image, uri ) ) != 0 ) )
139 goto err_set_uri;
141
142 return image;
143
144 err_set_uri:
145 image_put ( image );
146 err_alloc:
147 return NULL;
148}
149
150/**
151 * Set image URI
152 *
153 * @v image Image
154 * @v uri New image URI
155 * @ret rc Return status code
156 */
157int image_set_uri ( struct image *image, struct uri *uri ) {
158 const char *name;
159 int rc;
160
161 /* Set name, if image does not already have one */
162 if ( ! ( image->name && image->name[0] ) ) {
163 name = ( uri->path ? uri->path : uri->opaque );
164 if ( name ) {
165 name = basename ( ( char * ) name );
166 if ( ( rc = image_set_name ( image, name ) ) != 0 )
167 return rc;
168 }
169 }
170
171 /* Update image URI */
172 uri_put ( image->uri );
173 image->uri = uri_get ( uri );
174
175 return 0;
176}
177
178/**
179 * Set image name
180 *
181 * @v image Image
182 * @v name New image name
183 * @ret rc Return status code
184 */
185int image_set_name ( struct image *image, const char *name ) {
186 char *name_copy;
187
188 /* Duplicate name */
189 name_copy = strdup ( name );
190 if ( ! name_copy )
191 return -ENOMEM;
192
193 /* Free existing name, if not statically allocated */
194 if ( ! ( image->flags & IMAGE_STATIC_NAME ) )
195 free ( image->name );
196
197 /* Replace existing name */
198 image->name = name_copy;
200
201 return 0;
202}
203
204/**
205 * Strip dot suffix from image name, if present
206 *
207 * @v image Image
208 * @ret sep Position of old dot separator, or NULL
209 */
210char * image_strip_suffix ( struct image *image ) {
211 char *dot;
212
213 /* Locate and strip suffix, if present */
214 if ( image->name &&
215 ( ( dot = strrchr ( image->name, '.' ) ) != NULL ) ) {
216 *dot = '\0';
217 return dot;
218 }
219
220 return NULL;
221}
222
223/**
224 * Set image command line
225 *
226 * @v image Image
227 * @v cmdline New image command line, or NULL
228 * @ret rc Return status code
229 */
230int image_set_cmdline ( struct image *image, const char *cmdline ) {
231
232 free ( image->cmdline );
233 image->cmdline = NULL;
234 if ( cmdline ) {
236 if ( ! image->cmdline )
237 return -ENOMEM;
238 }
239 return 0;
240}
241
242/**
243 * Set image length
244 *
245 * @v image Image
246 * @v len Length of image data
247 * @ret rc Return status code
248 */
249int image_set_len ( struct image *image, size_t len ) {
250 size_t alloc_len;
251 void *data;
252 void *new;
253 char *nul;
254
255 /* Refuse to reallocate static images */
256 if ( image->flags & IMAGE_STATIC )
257 return -ENOTTY;
258
259 /* Calculate allocation length (including a terminating NUL) */
260 alloc_len = ( len ? ( len + 1 ) : 0 );
261 if ( alloc_len < len )
262 return -ERANGE;
263
264 /* (Re)allocate image data */
265 data = image->rwdata;
266 if ( data == empty_image_data )
267 data = NULL;
268 new = urealloc ( data, alloc_len );
269 if ( ! new )
270 return -ENOMEM;
271 image->data = ( len ? new : empty_image_data );
272 image->len = len;
273
274 /* Add terminating NUL (if not the empty image) */
275 if ( len ) {
276 nul = ( image->rwdata + len );
277 *nul = '\0';
278 }
279
280 return 0;
281}
282
283/**
284 * Set image data
285 *
286 * @v image Image
287 * @v data Image data
288 * @v len Length of image data
289 * @ret rc Return status code
290 */
291int image_set_data ( struct image *image, const void *data, size_t len ) {
292 int rc;
293
294 /* Set image length */
295 if ( ( rc = image_set_len ( image, len ) ) != 0 )
296 return rc;
297
298 /* Copy in new image data */
299 memcpy ( image->rwdata, data, len );
300
301 return 0;
302}
303
304/**
305 * Determine image type
306 *
307 * @v image Executable image
308 * @ret rc Return status code
309 */
310static int image_probe ( struct image *image ) {
311 struct image_type *type;
312 int rc;
313
314 /* Try each type in turn */
316 if ( ( rc = type->probe ( image ) ) == 0 ) {
317 image->type = type;
318 DBGC ( image, "IMAGE %s is %s\n",
319 image->name, type->name );
320 return 0;
321 }
322 DBGC ( image, "IMAGE %s is not %s: %s\n", image->name,
323 type->name, strerror ( rc ) );
324 }
325
326 DBGC ( image, "IMAGE %s format not recognised\n", image->name );
327 return -ENOTSUP;
328}
329
330/**
331 * Register executable image
332 *
333 * @v image Executable image
334 * @ret rc Return status code
335 */
336int register_image ( struct image *image ) {
337 static unsigned int imgindex = 0;
338 char name[8]; /* "imgXXXX" */
339 int rc;
340
341 /* Sanity checks */
342 if ( image->flags & IMAGE_STATIC ) {
343 assert ( ( image->name == NULL ) ||
345 assert ( image->cmdline == NULL );
346 }
347
348 /* Create image name if it doesn't already have one */
349 if ( ! image->name ) {
350 snprintf ( name, sizeof ( name ), "img%d", imgindex++ );
351 if ( ( rc = image_set_name ( image, name ) ) != 0 )
352 return rc;
353 }
354
355 /* Check for terminating NUL (required for text-based images) */
356 if ( ! image->data ) {
357 DBGC ( image, "IMAGE %s has no data\n", image->name );
358 return -EINVAL;
359 }
360 if ( image->text[image->len] != '\0' ) {
361 DBGC ( image, "IMAGE %s missing terminating NUL\n",
362 image->name );
363 return -EINVAL;
364 }
365
366 /* Add to image list */
367 image_get ( image );
370 DBGC ( image, "IMAGE %s at [%lx,%lx) registered\n",
371 image->name, virt_to_phys ( image->data ),
372 ( virt_to_phys ( image->data ) + image->len ) );
373
374 /* Try to detect image type, if applicable. Ignore failures,
375 * since we expect to handle some unrecognised images
376 * (e.g. kernel initrds, multiboot modules, random files
377 * provided via our EFI virtual filesystem, etc).
378 */
379 if ( ! image->type )
380 image_probe ( image );
381
382 return 0;
383}
384
385/**
386 * Unregister executable image
387 *
388 * @v image Executable image
389 */
390void unregister_image ( struct image *image ) {
391
392 /* Do nothing unless image is registered */
393 if ( ! ( image->flags & IMAGE_REGISTERED ) )
394 return;
395
396 DBGC ( image, "IMAGE %s unregistered\n", image->name );
397 list_del ( &image->list );
399 image_put ( image );
400}
401
402/**
403 * Find image by name
404 *
405 * @v name Image name
406 * @ret image Executable image, or NULL
407 */
408struct image * find_image ( const char *name ) {
409 struct image *image;
410
412 if ( strcmp ( image->name, name ) == 0 )
413 return image;
414 }
415
416 return NULL;
417}
418
419/**
420 * Find image by tag
421 *
422 * @v tag Image tag
423 * @ret image Executable image, or NULL
424 */
425struct image * find_image_tag ( struct image_tag *tag ) {
426 struct image *image;
427
429 if ( tag->image == image )
430 return image;
431 }
432
433 return NULL;
434}
435
436/**
437 * Execute image
438 *
439 * @v image Executable image
440 * @ret rc Return status code
441 *
442 * The image must already be registered. Note that executing an image
443 * may cause it to unregister itself. The caller must therefore
444 * assume that the image pointer becomes invalid.
445 */
446int image_exec ( struct image *image ) {
447 struct image *saved_current_image;
448 struct image *replacement = NULL;
449 struct uri *old_cwuri;
450 int rc;
451
452 /* Sanity check */
454
455 /* Switch current working directory to be that of the image
456 * itself, if applicable
457 */
458 old_cwuri = uri_get ( cwuri );
459 if ( image->uri )
460 churi ( image->uri );
461
462 /* Set as currently running image */
463 saved_current_image = image_tag ( image, &current_image );
464
465 /* Take out a temporary reference to the image, so that it
466 * does not get freed when temporarily unregistered.
467 */
468 image_get ( image );
469
470 /* Check that this image can be executed */
471 if ( ! ( image->type && image->type->exec ) ) {
472 rc = -ENOEXEC;
473 goto err;
474 }
475
476 /* Check that image is trusted (if applicable) */
478 DBGC ( image, "IMAGE %s is not trusted\n", image->name );
480 goto err;
481 }
482
483 /* Record boot attempt */
484 syslog ( LOG_NOTICE, "Executing \"%s\"\n", image->name );
485
486 /* Temporarily unregister the image during its execution */
488
489 /* Try executing the image */
490 if ( ( rc = image->type->exec ( image ) ) != 0 ) {
491 DBGC ( image, "IMAGE %s could not execute: %s\n",
492 image->name, strerror ( rc ) );
493 /* Do not return yet; we still have clean-up to do */
494 }
495
496 /* Record result of boot attempt */
497 if ( rc == 0 ) {
498 syslog ( LOG_NOTICE, "Execution of \"%s\" completed\n",
499 image->name );
500 } else {
501 syslog ( LOG_ERR, "Execution of \"%s\" failed: %s\n",
502 image->name, strerror ( rc ) );
503 }
504
505 /* Re-register image (unless due to be replaced) */
506 if ( ! image->replacement )
508
509 /* Pick up replacement image before we drop the original
510 * image's temporary reference. The replacement image must
511 * already be registered, so we don't need to hold a temporary
512 * reference (which would complicate the tail-recursion).
513 */
515 if ( replacement )
517
518 /* Clear any recorded replacement image */
521
522 err:
523 /* Unregister image if applicable */
526
527 /* Debug message for tail-recursion. Placed here because the
528 * image_put() may end up freeing the image.
529 */
530 if ( replacement ) {
531 DBGC ( image, "IMAGE %s replacing self with IMAGE %s\n",
532 image->name, replacement->name );
533 }
534
535 /* Drop temporary reference to the original image */
536 image_put ( image );
537
538 /* Restore previous currently-running image */
539 image_tag ( saved_current_image, &current_image );
540
541 /* Reset current working directory */
542 churi ( old_cwuri );
543 uri_put ( old_cwuri );
544
545 /* Tail-recurse into replacement image, if one exists */
546 if ( replacement )
547 return image_exec ( replacement );
548
549 return rc;
550}
551
552/**
553 * Set replacement image
554 *
555 * @v replacement Replacement image
556 * @ret rc Return status code
557 *
558 * The replacement image must already be registered, and must remain
559 * registered until the currently-executing image returns.
560 */
562 struct image *image = current_image.image;
563 int rc;
564
565 /* Sanity check */
567
568 /* Fail unless there is a currently-executing image */
569 if ( ! image ) {
570 rc = -ENOTTY;
571 DBGC ( replacement, "IMAGE %s cannot replace non-existent "
572 "image: %s\n", replacement->name, strerror ( rc ) );
573 return rc;
574 }
575
576 /* Check that the replacement image can be executed */
577 if ( ! ( replacement->type && replacement->type->exec ) )
578 return -ENOEXEC;
579
580 /* Clear any existing replacement */
582
583 /* Set replacement */
585 DBGC ( image, "IMAGE %s will replace self with IMAGE %s\n",
586 image->name, replacement->name );
587
588 return 0;
589}
590
591/**
592 * Select image for execution
593 *
594 * @v image Executable image
595 * @ret rc Return status code
596 */
597int image_select ( struct image *image ) {
598
599 /* Check that this image can be executed */
600 if ( ! ( image->type && image->type->exec ) )
601 return -ENOEXEC;
602
603 /* Mark image as selected */
605
606 return 0;
607}
608
609/**
610 * Change image trust requirement
611 *
612 * @v require_trusted Require trusted images
613 * @v permanent Make trust requirement permanent
614 * @ret rc Return status code
615 */
616int image_set_trust ( int require_trusted, int permanent ) {
617
618 /* Update trust requirement, if permitted to do so */
620 require_trusted_images = require_trusted;
622 }
623
624 /* Fail if we attempted to change the trust requirement but
625 * were not permitted to do so.
626 */
627 if ( require_trusted_images != require_trusted )
628 return -EACCES_PERMANENT;
629
630 return 0;
631}
632
633/**
634 * Create registered image from block of memory
635 *
636 * @v name Name
637 * @v data Image data
638 * @v len Length
639 * @ret image Image, or NULL on error
640 */
641struct image * image_memory ( const char *name, const void *data,
642 size_t len ) {
643 struct image *image;
644 int rc;
645
646 /* Allocate image */
647 image = alloc_image ( NULL );
648 if ( ! image ) {
649 rc = -ENOMEM;
650 goto err_alloc_image;
651 }
652
653 /* Set name */
654 if ( ( rc = image_set_name ( image, name ) ) != 0 )
655 goto err_set_name;
656
657 /* Set data */
658 if ( ( rc = image_set_data ( image, data, len ) ) != 0 )
659 goto err_set_data;
660
661 /* Register image */
662 if ( ( rc = register_image ( image ) ) != 0 )
663 goto err_register;
664
665 /* Drop local reference to image */
666 image_put ( image );
667
668 return image;
669
670 err_register:
671 err_set_data:
672 err_set_name:
673 image_put ( image );
674 err_alloc_image:
675 return NULL;
676}
677
678/**
679 * Find argument within image command line
680 *
681 * @v image Image
682 * @v key Argument search key (including trailing delimiter)
683 * @ret value Argument value, or NULL if not found
684 */
685const char * image_argument ( struct image *image, const char *key ) {
686 const char *cmdline = image->cmdline;
687 const char *search;
688 const char *match;
689 const char *next;
690
691 /* Find argument */
692 for ( search = cmdline ; search ; search = next ) {
693
694 /* Find next occurrence, if any */
695 match = strstr ( search, key );
696 if ( ! match )
697 break;
698 next = ( match + strlen ( key ) );
699
700 /* Check preceding delimiter, if any */
701 if ( ( match == cmdline ) || isspace ( match[-1] ) )
702 return next;
703 }
704
705 return NULL;
706}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
union @162305117151260234136356364136041353210355154177 key
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
Assertions.
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
const char * name
Definition ath9k_hw.c:1986
char * basename(char *path)
Return base name from path.
Definition basename.c:43
int isspace(int character)
Check to see if character is a space.
Definition ctype.c:42
Character types.
void churi(struct uri *uri)
Change working URI.
Definition cwuri.c:46
struct uri * cwuri
Current working URI.
Definition cwuri.c:39
uint32_t next
Next descriptor address.
Definition dwmac.h:11
ring len
Length.
Definition dwmac.h:226
uint64_t tag
Identity tag.
Definition edd.h:1
const char * replacement
Definition editstring.h:54
uint32_t type
Operating system type.
Definition ena.h:1
uint8_t data[48]
Additional event data.
Definition ena.h:11
Error codes.
#define DBGC(...)
Definition compiler.h:530
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:921
#define EINVAL
Invalid argument.
Definition errno.h:472
#define ENOEXEC
Exec format error.
Definition errno.h:563
#define ENOMEM
Not enough space.
Definition errno.h:578
#define ENOTSUP
Operation not supported.
Definition errno.h:633
#define ERANGE
Result too large.
Definition errno.h:683
#define ENOTTY
Inappropriate I/O control operation.
Definition errno.h:638
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:951
#define LOG_ERR
Error: error conditions.
Definition syslog.h:36
#define LOG_NOTICE
Notice: normal but significant conditions.
Definition syslog.h:42
static int require_trusted_images_permanent
Prevent changes to image trust requirement.
Definition image.c:75
const char empty_image_data[]
Empty image terminating NUL.
Definition image.c:78
struct image * alloc_image(struct uri *uri)
Allocate executable image.
Definition image.c:127
#define EACCES_UNTRUSTED
Definition image.c:49
struct image * find_image(const char *name)
Find image by name.
Definition image.c:408
struct list_head images
List of registered images.
Definition image.c:59
char * image_strip_suffix(struct image *image)
Strip dot suffix from image name, if present.
Definition image.c:210
void unregister_image(struct image *image)
Unregister executable image.
Definition image.c:390
void free_image(struct refcnt *refcnt)
Free executable image.
Definition image.c:89
int image_exec(struct image *image)
Execute image.
Definition image.c:446
#define EACCES_PERMANENT
Definition image.c:53
int image_set_data(struct image *image, const void *data, size_t len)
Set image data.
Definition image.c:291
static int require_trusted_images
Current image trust requirement.
Definition image.c:72
struct image * find_image_tag(struct image_tag *tag)
Find image by tag.
Definition image.c:425
int image_set_uri(struct image *image, struct uri *uri)
Set image URI.
Definition image.c:157
int register_image(struct image *image)
Register executable image.
Definition image.c:336
int image_set_cmdline(struct image *image, const char *cmdline)
Set image command line.
Definition image.c:230
int image_replace(struct image *replacement)
Set replacement image.
Definition image.c:561
int image_set_name(struct image *image, const char *name)
Set image name.
Definition image.c:185
struct image * image_memory(const char *name, const void *data, size_t len)
Create registered image from block of memory.
Definition image.c:641
static int image_probe(struct image *image)
Determine image type.
Definition image.c:310
const char * image_argument(struct image *image, const char *key)
Find argument within image command line.
Definition image.c:685
int image_set_len(struct image *image, size_t len)
Set image length.
Definition image.c:249
int image_select(struct image *image)
Select image for execution.
Definition image.c:597
int image_set_trust(int require_trusted, int permanent)
Change image trust requirement.
Definition image.c:616
Executable images.
static struct image * image_get(struct image *image)
Increment reference count on an image.
Definition image.h:248
struct image_tag current_image
#define IMAGE_STATIC_NAME
Image name is statically allocated.
Definition image.h:99
#define IMAGE_REGISTERED
Image is registered.
Definition image.h:84
#define IMAGE_TRUSTED
Image is trusted.
Definition image.h:87
static struct image * image_tag(struct image *image, struct image_tag *tag)
Tag image.
Definition image.h:305
static void image_put(struct image *image)
Decrement reference count on an image.
Definition image.h:258
#define IMAGE_TAGS
Image tag table.
Definition image.h:188
#define IMAGE_STATIC
Image is statically allocated.
Definition image.h:96
#define for_each_image(image)
Iterate over all registered images.
Definition image.h:199
#define __image_tag
An image tag.
Definition image.h:191
struct image_tag selected_image
#define IMAGE_AUTO_UNREGISTER
Image will be automatically unregistered after execution.
Definition image.h:90
#define IMAGE_TYPES
Executable image type table.
Definition image.h:174
User memory allocation.
void * urealloc(void *ptr, size_t new_size)
Reallocate external memory.
String functions.
void * memcpy(void *dest, const void *src, size_t len) __nonnull
Access to external ("user") memory.
Linked lists.
#define LIST_HEAD_INIT(list)
Initialise a static list head.
Definition list.h:31
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition list.h:94
#define list_del(list)
Delete an entry from a list.
Definition list.h:120
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:718
uint32_t cmdline
Definition multiboot.h:4
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
int strcmp(const char *first, const char *second)
Compare strings.
Definition string.c:174
char * strdup(const char *src)
Duplicate string.
Definition string.c:425
char * strstr(const char *haystack, const char *needle)
Find substring.
Definition string.c:324
char * strrchr(const char *src, int character)
Find rightmost character within a string.
Definition string.c:304
size_t strlen(const char *src)
Get length of string.
Definition string.c:244
An image tag.
Definition image.h:180
An executable image type.
Definition image.h:102
int(* exec)(struct image *image)
Execute image.
Definition image.h:120
An executable image.
Definition image.h:24
unsigned int flags
Flags.
Definition image.h:40
struct image * replacement
Replacement image.
Definition image.h:80
struct refcnt refcnt
Reference count.
Definition image.h:26
struct image_type * type
Image type, if known.
Definition image.h:66
const void * data
Read-only data.
Definition image.h:51
char * name
Name.
Definition image.h:38
size_t len
Length of raw file image.
Definition image.h:63
struct list_head list
List of registered images.
Definition image.h:29
struct uri * uri
URI of image.
Definition image.h:32
char * cmdline
Command line to pass to image.
Definition image.h:43
const char * text
Read-only text (guaranteed to be NUL terminated).
Definition image.h:60
void * rwdata
Writable data.
Definition image.h:53
A doubly-linked list entry (or list head).
Definition list.h:19
A reference counter.
Definition refcnt.h:27
int count
Current reference count.
Definition refcnt.h:33
A Uniform Resource Identifier.
Definition uri.h:65
const char * path
Path (after URI decoding).
Definition uri.h:81
const char * opaque
Opaque part.
Definition uri.h:71
System logger.
#define syslog(priority, fmt,...)
Write message to system log.
Definition syslog.h:94
#define for_each_table_entry(pointer, table)
Iterate through all entries within a linker table.
Definition tables.h:386
Uniform Resource Identifiers.
static struct uri * uri_get(struct uri *uri)
Increment URI reference count.
Definition uri.h:195
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition uri.h:206
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383