Update Red Hat Copyright Notices
[nbdkit.git] / plugins / iso / iso.c
blob6fc29b1a58b2a964de7ec6e8512c605963bee983
1 /* nbdkit
2 * Copyright Red Hat
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
33 #include <config.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <unistd.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
42 #include <nbdkit-plugin.h>
44 #include "cleanup.h"
45 #include "string-vector.h"
46 #include "utils.h"
48 /* List of directories parsed from the command line. */
49 static string_vector dirs = empty_vector;
51 /* xorriso or genisoimage or mkisofs program, picked at compile time,
52 * but can be overridden at run time.
54 static const char *isoprog = ISOPROG;
56 /* Extra parameters for isoprog. */
57 static const char *params = NULL;
59 /* The temporary ISO. */
60 static int fd = -1;
62 /* Construct the temporary ISO. */
63 static int
64 make_iso (void)
66 const char *tmpdir;
67 CLEANUP_FREE char *template = NULL;
68 CLEANUP_FREE char *command = NULL;
69 size_t command_len = 0;
70 FILE *fp;
71 size_t i;
72 int r;
74 /* Path for temporary file. */
75 tmpdir = getenv ("TMPDIR");
76 if (tmpdir == NULL)
77 tmpdir = LARGE_TMPDIR;
78 if (asprintf (&template, "%s/isoXXXXXX", tmpdir) == -1) {
79 nbdkit_error ("asprintf: %m");
80 return -1;
83 fd = mkstemp (template);
84 if (fd == -1) {
85 nbdkit_error ("mkstemp: %s: %m", template);
86 return -1;
88 unlink (template);
90 /* Construct the isoprog command. */
91 fp = open_memstream (&command, &command_len);
92 if (fp == NULL) {
93 nbdkit_error ("open_memstream: %m");
94 return -1;
97 shell_quote (isoprog, fp);
98 #if ISOPROG_IS_XORRISO
99 /* This is necessary to make xorriso command line parsing behave
100 * like mkisofs.
102 fprintf (fp, " -as mkisofs");
103 #endif
104 fprintf (fp, " -quiet");
105 if (params)
106 fprintf (fp, " %s", params);
107 for (i = 0; i < dirs.len; ++i) {
108 fputc (' ', fp);
109 shell_quote (dirs.ptr[i], fp);
111 /* Redirect output to the temporary file. */
112 fprintf (fp, " >&%d", fd);
114 if (fclose (fp) == EOF) {
115 nbdkit_error ("memstream failed: %m");
116 return -1;
119 /* Run the command. */
120 nbdkit_debug ("%s", command);
121 r = system (command);
122 if (exit_status_to_nbd_error (r, isoprog) == -1)
123 return -1;
125 return 0;
128 static void
129 iso_unload (void)
131 string_vector_empty (&dirs);
133 if (fd >= 0)
134 close (fd);
137 static int
138 iso_config (const char *key, const char *value)
140 char *dir;
142 if (strcmp (key, "dir") == 0) {
143 dir = nbdkit_realpath (value);
144 if (dir == NULL)
145 return -1;
147 if (string_vector_append (&dirs, dir) == -1) {
148 nbdkit_error ("realloc: %m");
149 free (dir);
150 return -1;
153 else if (strcmp (key, "params") == 0) {
154 params = value;
156 else if (strcmp (key, "prog") == 0) {
157 isoprog = value;
159 else {
160 nbdkit_error ("unknown parameter '%s'", key);
161 return -1;
164 return 0;
167 static int
168 iso_config_complete (void)
170 if (dirs.len == 0) {
171 nbdkit_error ("you must supply the dir=<DIRECTORY> parameter "
172 "after the plugin name on the command line");
173 return -1;
176 return 0;
179 #define iso_config_help \
180 "dir=<DIRECTORY> (required) The directory to serve.\n" \
181 "params='<PARAMS>' Extra parameters to pass.\n" \
182 "prog=<ISOPROG> The program used to make ISOs." \
184 static void
185 iso_dump_plugin (void)
187 printf ("iso_prog=%s\n", ISOPROG);
190 static int
191 iso_get_ready (void)
193 return make_iso ();
196 static void *
197 iso_open (int readonly)
199 return NBDKIT_HANDLE_NOT_NEEDED;
202 #define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
204 /* Get the file size. */
205 static int64_t
206 iso_get_size (void *handle)
208 struct stat statbuf;
210 if (fstat (fd, &statbuf) == -1) {
211 nbdkit_error ("fstat: %m");
212 return -1;
215 return statbuf.st_size;
218 /* Serves the same data over multiple connections. */
219 static int
220 iso_can_multi_conn (void *handle)
222 return 1;
225 static int
226 iso_can_cache (void *handle)
228 /* Let nbdkit call pread to populate the file system cache. */
229 return NBDKIT_CACHE_EMULATE;
232 /* Read data from the file. */
233 static int
234 iso_pread (void *handle, void *buf, uint32_t count, uint64_t offset)
236 while (count > 0) {
237 ssize_t r = pread (fd, buf, count, offset);
238 if (r == -1) {
239 nbdkit_error ("pread: %m");
240 return -1;
242 if (r == 0) {
243 nbdkit_error ("pread: unexpected end of file");
244 return -1;
246 buf += r;
247 count -= r;
248 offset += r;
251 return 0;
254 static struct nbdkit_plugin plugin = {
255 .name = "iso",
256 .longname = "nbdkit iso plugin",
257 .version = PACKAGE_VERSION,
258 .unload = iso_unload,
259 .config = iso_config,
260 .config_complete = iso_config_complete,
261 .config_help = iso_config_help,
262 .magic_config_key = "dir",
263 .dump_plugin = iso_dump_plugin,
264 .get_ready = iso_get_ready,
265 .open = iso_open,
266 .get_size = iso_get_size,
267 .can_multi_conn = iso_can_multi_conn,
268 .can_cache = iso_can_cache,
269 .pread = iso_pread,
270 .errno_is_preserved = 1,
273 NBDKIT_REGISTER_PLUGIN (plugin)