Add basic "fetch" and "imgstat" commands.
[gpxe.git] / src / hci / commands / image_cmd.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 <getopt.h>
22 #include <vsprintf.h>
23 #include <gpxe/image.h>
24 #include <gpxe/command.h>
25 #include <usr/fetch.h>
26 #include <usr/imgmgmt.h>
27
28 /** @file
29  *
30  * Image management commands
31  *
32  */
33
34 /**
35  * Print image description
36  *
37  */
38
39 /**
40  * "fetch"/"module"/"kernel" command syntax message
41  *
42  * @v argv              Argument list
43  */
44 static void fetch_syntax ( char **argv ) {
45         printf ( "Usage:\n"
46                  "  %s [-n|--name <name>] filename [arguments...]\n"
47                  "\n"
48                  "Fetch executable/loadable image\n",
49                  argv[0] );
50 }
51
52 /**
53  * The "fetch"/"module"/"kernel" command body
54  *
55  * @v argc              Argument count
56  * @v argv              Argument list
57  * @v name              Default name for image, or NULL
58  * @ret rc              Exit code
59  */
60 static int fetch_exec_name ( int argc, char **argv, const char *name ) {
61         static struct option longopts[] = {
62                 { "help", 0, NULL, 'h' },
63                 { "name", required_argument, NULL, 'n' },
64                 { NULL, 0, NULL, 0 },
65         };
66         struct image *image;
67         const char *filename;
68         char cmdline[ sizeof ( image->cmdline ) ];
69         size_t used = 0;
70         int c;
71         int rc;
72
73         /* Parse options */
74         while ( ( c = getopt_long ( argc, argv, "hn:",
75                                     longopts, NULL ) ) >= 0 ) {
76                 switch ( c ) {
77                 case 'n':
78                         /* Set image name */
79                         name = optarg;
80                         break;
81                 case 'h':
82                         /* Display help text */
83                 default:
84                         /* Unrecognised/invalid option */
85                         fetch_syntax ( argv );
86                         return 1;
87                 }
88         }
89
90         /* Need at least a filename remaining after the options */
91         if ( optind >= argc ) {
92                 fetch_syntax ( argv );
93                 return 1;
94         }
95         filename = argv[optind++];
96
97         /* Build command line */
98         while ( ( used < sizeof ( cmdline ) ) && ( optind < argc ) ) {
99                 used += snprintf ( &cmdline[used], sizeof ( cmdline ) - used,
100                                    " %s",  argv[optind++] );
101         }
102
103         /* Allocate and fill struct image */
104         image = malloc ( sizeof ( *image ) );
105         if ( ! image ) {
106                 printf ( "Out of memory\n" );
107                 return 1;
108         }
109         memset ( image, 0, sizeof ( *image ) );
110         if ( name )
111                 strncpy ( image->name, name, ( sizeof ( image->name ) - 1 ) );
112         if ( used )
113                 memcpy ( image->cmdline, cmdline, sizeof ( image->cmdline ) );
114
115         /* Fetch the file */
116         if ( ( rc = fetch ( image, filename ) ) != 0 ) {
117                 printf ( "Could not fetch %s: %s\n", filename,
118                          strerror ( rc ) );
119                 free ( image );
120                 return 1;
121         }
122
123         /* Register the image */
124         if ( ( rc = register_image ( image ) ) != 0 ) {
125                 printf ( "Could not register %s: %s\n", filename,
126                          strerror ( rc ) );
127                 free ( image );
128                 return 1;
129         }
130
131         imgstat ( image );
132         return 0;
133 }
134
135 /**
136  * The "fetch"/"module" command
137  *
138  * @v argc              Argument count
139  * @v argv              Argument list
140  * @ret rc              Exit code
141  */
142 static int fetch_exec ( int argc, char **argv ) {
143         return fetch_exec_name ( argc, argv, NULL );
144 }
145
146 /**
147  * The "kernel" command
148  *
149  * @v argc              Argument count
150  * @v argv              Argument list
151  * @ret rc              Exit code
152  */
153 static int kernel_exec ( int argc, char **argv ) {
154         return fetch_exec_name ( argc, argv, "kernel" );
155 }
156
157 /**
158  * "imgstat" command syntax message
159  *
160  * @v argv              Argument list
161  */
162 static void imgstat_syntax ( char **argv ) {
163         printf ( "Usage:\n"
164                  "  %s\n"
165                  "\n"
166                  "List executable/loadable images\n",
167                  argv[0] );
168 }
169
170 /**
171  * The "imgstat" command
172  *
173  * @v argc              Argument count
174  * @v argv              Argument list
175  * @ret rc              Exit code
176  */
177 static int imgstat_exec ( int argc __unused, char **argv __unused ) {
178         static struct option longopts[] = {
179                 { "help", 0, NULL, 'h' },
180                 { NULL, 0, NULL, 0 },
181         };
182         struct image *image;
183         int c;
184
185         /* Parse options */
186         while ( ( c = getopt_long ( argc, argv, "h", longopts, NULL ) ) >= 0 ){
187                 switch ( c ) {
188                 case 'h':
189                         /* Display help text */
190                 default:
191                         /* Unrecognised/invalid option */
192                         imgstat_syntax ( argv );
193                         return 1;
194                 }
195         }
196
197         /* Need at least a filename remaining after the options */
198         if ( optind != argc ) {
199                 imgstat_syntax ( argv );
200                 return 1;
201         }
202
203         /* Show status of all images */
204         for_each_image ( image ) {
205                 imgstat ( image );
206         }
207         return 0;
208 }
209
210 /** Image management commands */
211 struct command image_commands[] __command = {
212         {
213                 .name = "fetch",
214                 .exec = fetch_exec,
215         },
216         {
217                 .name = "module",
218                 .exec = fetch_exec, /* synonym for "fetch" */
219         },
220         {
221                 .name = "kernel",
222                 .exec = kernel_exec,
223         },
224         {
225                 .name = "imgstat",
226                 .exec = imgstat_exec,
227         },
228 };