]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[image] Add "imgextract" command for extracting archive images
authorMichael Brown <mcb30@ipxe.org>
Thu, 6 May 2021 12:11:31 +0000 (13:11 +0100)
committerMichael Brown <mcb30@ipxe.org>
Sat, 8 May 2021 14:34:19 +0000 (15:34 +0100)
Add the concept of extracting an image from an archive (which could be
a single-file archive such as a gzip-compressed file), along with an
"imgextract" command to expose this functionality to scripts.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/config/config.c
src/config/config_archive.c [new file with mode: 0644]
src/config/general.h
src/core/archive.c [new file with mode: 0644]
src/hci/commands/image_archive_cmd.c [new file with mode: 0644]
src/include/ipxe/errfile.h
src/include/ipxe/image.h
src/include/usr/imgarchive.h [new file with mode: 0644]
src/usr/imgarchive.c [new file with mode: 0644]

index 5e7a3ecfdb560c5a2db4f680ee7c4fbe27ae831c..dd1fceb923046586bfe63b7b1e380eddfe16cb97 100644 (file)
@@ -284,6 +284,9 @@ REQUIRE_OBJECT ( cert_cmd );
 #ifdef IMAGE_MEM_CMD
 REQUIRE_OBJECT ( image_mem_cmd );
 #endif
+#ifdef IMAGE_ARCHIVE_CMD
+REQUIRE_OBJECT ( image_archive_cmd );
+#endif
 
 /*
  * Drag in miscellaneous objects
diff --git a/src/config/config_archive.c b/src/config/config_archive.c
new file mode 100644 (file)
index 0000000..3644b5d
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <config/general.h>
+
+/** @file
+ *
+ * Archive image configuration
+ *
+ */
+
+PROVIDE_REQUIRING_SYMBOL();
index 9b21f127132994d968164924a9ec4d38bc697bf9..fd317be965b91b5ec28cc54e2ce25dd26623021b 100644 (file)
@@ -156,6 +156,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 //#define NTP_CMD              /* NTP commands */
 //#define CERT_CMD             /* Certificate management commands */
 //#define IMAGE_MEM_CMD                /* Read memory command */
+//#define IMAGE_ARCHIVE_CMD    /* Archive image management commands */
 
 /*
  * ROM-specific options
diff --git a/src/core/archive.c b/src/core/archive.c
new file mode 100644 (file)
index 0000000..cd024bd
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <string.h>
+#include <errno.h>
+#include <ipxe/image.h>
+
+/** @file
+ *
+ * Archive images
+ *
+ */
+
+/**
+ * Extract archive image
+ *
+ * @v image            Image
+ * @v name             Extracted image name
+ * @v extracted                Extracted image to fill in
+ * @ret rc             Return status code
+ */
+int image_extract ( struct image *image, const char *name,
+                   struct image **extracted ) {
+       char *dot;
+       int rc;
+
+       /* Check that this image can be used to extract an archive image */
+       if ( ! ( image->type && image->type->extract ) ) {
+               rc = -ENOTSUP;
+               goto err_unsupported;
+       }
+
+       /* Allocate new image */
+       *extracted = alloc_image ( image->uri );
+       if ( ! *extracted ) {
+               rc = -ENOMEM;
+               goto err_alloc;
+       }
+
+       /* Set image name */
+       if ( ( rc = image_set_name ( *extracted,
+                                    ( name ? name : image->name ) ) ) != 0 ) {
+               goto err_set_name;
+       }
+
+       /* Strip any archive or compression suffix from implicit name */
+       if ( ( ! name ) && ( (*extracted)->name ) &&
+            ( ( dot = strrchr ( (*extracted)->name, '.' ) ) != NULL ) ) {
+               *dot = '\0';
+       }
+
+       /* Try extracting archive image */
+       if ( ( rc = image->type->extract ( image, *extracted ) ) != 0 ) {
+               DBGC ( image, "IMAGE %s could not extract image: %s\n",
+                      image->name, strerror ( rc ) );
+               goto err_extract;
+       }
+
+       /* Register image */
+       if ( ( rc = register_image ( *extracted ) ) != 0 )
+               goto err_register;
+
+       /* Drop local reference to image */
+       image_put ( *extracted );
+
+       return 0;
+
+       unregister_image ( *extracted );
+ err_register:
+ err_extract:
+ err_set_name:
+       image_put ( *extracted );
+ err_alloc:
+ err_unsupported:
+       return rc;
+}
+
+/* Drag in objects via image_extract() */
+REQUIRING_SYMBOL ( image_extract );
+
+/* Drag in archive image formats */
+REQUIRE_OBJECT ( config_archive );
diff --git a/src/hci/commands/image_archive_cmd.c b/src/hci/commands/image_archive_cmd.c
new file mode 100644 (file)
index 0000000..a2212ae
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <getopt.h>
+#include <ipxe/command.h>
+#include <ipxe/parseopt.h>
+#include <usr/imgmgmt.h>
+#include <usr/imgarchive.h>
+
+/** @file
+ *
+ * Archive image commands
+ *
+ */
+
+/** "imgextract" options */
+struct imgextract_options {
+       /** Image name */
+       char *name;
+       /** Keep original image */
+       int keep;
+       /** Download timeout */
+       unsigned long timeout;
+};
+
+/** "imgextract" option list */
+static struct option_descriptor imgextract_opts[] = {
+       OPTION_DESC ( "name", 'n', required_argument,
+                     struct imgextract_options, name, parse_string ),
+       OPTION_DESC ( "keep", 'k', no_argument,
+                     struct imgextract_options, keep, parse_flag ),
+       OPTION_DESC ( "timeout", 't', required_argument,
+                     struct imgextract_options, timeout, parse_timeout ),
+};
+
+/** "imgextract" command descriptor */
+static struct command_descriptor imgextract_cmd =
+       COMMAND_DESC ( struct imgextract_options, imgextract_opts, 1, 1, NULL );
+
+/**
+ * The "imgextract" command
+ *
+ * @v argc             Argument count
+ * @v argv             Argument list
+ * @ret rc             Return status code
+ */
+static int imgextract_exec ( int argc, char **argv ) {
+       struct imgextract_options opts;
+       struct image *image;
+       int rc;
+
+       /* Parse options */
+       if ( ( rc = parse_options ( argc, argv, &imgextract_cmd,
+                                   &opts ) ) != 0 )
+               goto err_parse;
+
+       /* Acquire image */
+       if ( ( rc = imgacquire ( argv[optind], opts.timeout, &image ) ) != 0 )
+               goto err_acquire;
+
+       /* Extract archive image */
+       if ( ( rc = imgextract ( image, opts.name ) ) != 0 )
+               goto err_extract;
+
+       /* Success */
+       rc = 0;
+
+ err_extract:
+       /* Discard original image unless --keep was specified */
+       if ( ! opts.keep )
+               unregister_image ( image );
+ err_acquire:
+ err_parse:
+       return rc;
+}
+
+/** Archive image commands */
+struct command image_archive_commands[] __command = {
+       {
+               .name = "imgextract",
+               .exec = imgextract_exec,
+       },
+};
index e3bf9f565929d5e5d5942794152a908fe64df7e9..162e6b7b062ac6cf715544f875d8280d9d08dc77 100644 (file)
@@ -301,6 +301,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 #define ERRFILE_png                  ( ERRFILE_IMAGE | 0x00070000 )
 #define ERRFILE_der                  ( ERRFILE_IMAGE | 0x00080000 )
 #define ERRFILE_pem                  ( ERRFILE_IMAGE | 0x00090000 )
+#define ERRFILE_archive                      ( ERRFILE_IMAGE | 0x000a0000 )
 
 #define ERRFILE_asn1                 ( ERRFILE_OTHER | 0x00000000 )
 #define ERRFILE_chap                 ( ERRFILE_OTHER | 0x00010000 )
index 046edf9a5bd11de584489c152bb5b2c1cc83cafe..c6e723dc69e85ccfa71a268becbcaf3e7a4df728 100644 (file)
@@ -113,6 +113,14 @@ struct image_type {
         */
        int ( * asn1 ) ( struct image *image, size_t offset,
                         struct asn1_cursor **cursor );
+       /**
+        * Extract archive image
+        *
+        * @v image             Image
+        * @v extracted         Extracted image
+        * @ret rc              Return status code
+        */
+       int ( * extract ) ( struct image *image, struct image *extracted );
 };
 
 /**
@@ -190,6 +198,8 @@ extern struct image * image_memory ( const char *name, userptr_t data,
 extern int image_pixbuf ( struct image *image, struct pixel_buffer **pixbuf );
 extern int image_asn1 ( struct image *image, size_t offset,
                        struct asn1_cursor **cursor );
+extern int image_extract ( struct image *image, const char *name,
+                          struct image **extracted );
 
 /**
  * Increment reference count on an image
diff --git a/src/include/usr/imgarchive.h b/src/include/usr/imgarchive.h
new file mode 100644 (file)
index 0000000..bf0c18f
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _USR_IMGARCHIVE_H
+#define _USR_IMGARCHIVE_H
+
+/** @file
+ *
+ * Archive image management
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <ipxe/image.h>
+
+extern int imgextract ( struct image *image, const char *name );
+
+#endif /* _USR_IMGARCHIVE_H */
diff --git a/src/usr/imgarchive.c b/src/usr/imgarchive.c
new file mode 100644 (file)
index 0000000..6849dd5
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
+
+#include <stdio.h>
+#include <ipxe/image.h>
+#include <usr/imgarchive.h>
+
+/** @file
+ *
+ * Archive image management
+ *
+ */
+
+/**
+ * Extract archive image
+ *
+ * @v image            Image
+ * @v name             Extracted image name (or NULL to use default)
+ * @ret rc             Return status code
+ */
+int imgextract ( struct image *image, const char *name ) {
+       struct image *extracted;
+       int rc;
+
+       /* Extract archive image */
+       if ( ( rc = image_extract ( image, name, &extracted ) ) != 0 ) {
+               printf ( "Could not extract image: %s\n", strerror ( rc ) );
+               return rc;
+       }
+
+       return 0;
+}