Let ifmgmt.c take care of calling efree(), since it's the once which
[people/dverkamp/gpxe.git] / src / usr / imgmgmt.c
1 /*
2  * Copyright (C) 2007 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., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 #include <stdint.h>
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <vsprintf.h>
23 #include <gpxe/image.h>
24 #include <gpxe/emalloc.h>
25 #include <usr/fetch.h>
26 #include <usr/imgmgmt.h>
27
28 /** @file
29  *
30  * Image management
31  *
32  */
33
34 /**
35  * Fetch an image
36  *
37  * @v filename          Filename for image
38  * @v name              Name for image, or NULL
39  * @ret new_image       Newly created image
40  * @ret rc              Return status code
41  */
42 int imgfetch ( const char *filename, const char *name,
43                struct image **new_image ) {
44         struct image *image;
45         int rc;
46
47         /* Allocate new image */
48         image = malloc ( sizeof ( *image ) );
49         if ( ! image )
50                 return -ENOMEM;
51         memset ( image, 0, sizeof ( *image ) );
52
53         /* Fill in image name */
54         if ( name )
55                 strncpy ( image->name, name, ( sizeof ( image->name ) - 1 ) );
56
57         /* Fetch the file */
58         if ( ( rc = fetch ( filename, &image->data, &image->len ) ) != 0 )
59                 goto err;
60
61         /* Register the image */
62         if ( ( rc = register_image ( image ) ) != 0 )
63                 goto err;
64
65         *new_image = image;
66         return 0;
67
68  err:
69         efree ( image->data );
70         free ( image );
71         return rc;
72 }
73
74 /**
75  * Load an image
76  *
77  * @v image             Image
78  * @ret rc              Return status code
79  */
80 int imgload ( struct image *image ) {
81         int rc;
82
83         /* Try to load image */
84         if ( ( rc = image_autoload ( image ) ) != 0 )
85                 return rc;
86
87         /* If we succeed, move the image to the start of the list */
88         promote_image ( image );
89
90         return 0;
91 }
92
93 /**
94  * Execute an image
95  *
96  * @v image             Image
97  * @ret rc              Return status code
98  */
99 int imgexec ( struct image *image ) {
100         return image_exec ( image );
101 }
102
103 /**
104  * Identify the first loaded image
105  *
106  * @ret image           Image, or NULL
107  */
108 struct image * imgautoselect ( void ) {
109         struct image *image;
110
111         for_each_image ( image ) {
112                 if ( image->flags & IMAGE_LOADED )
113                         return image;
114         }
115
116         return NULL;
117 }
118
119 /**
120  * Display status of an image
121  *
122  * @v image             Executable/loadable image
123  */
124 void imgstat ( struct image *image ) {
125         printf ( "%s: %zd bytes", image->name, image->len );
126         if ( image->type )
127                 printf ( " [%s]", image->type->name );
128         if ( image->flags & IMAGE_LOADED )
129                 printf ( " [LOADED]" );
130         if ( image->cmdline[0] )
131                 printf ( " \"%s\"", image->cmdline );
132         printf ( "\n" );
133 }
134
135 /**
136  * Free an image
137  *
138  * @v image             Executable/loadable image
139  */
140 void imgfree ( struct image *image ) {
141         unregister_image ( image );
142         efree ( image->data );
143         free ( image );
144 }