7 #include <talloc/talloc.h>
8 #include <system/system.h>
9 #include <process/process.h>
15 #define DEVICE_MOUNT_BASE (LOCAL_STATE_DIR "/petitboot/mnt")
17 struct load_url_async_data {
18 load_url_callback url_cb;
22 const char *mount_base(void)
24 return DEVICE_MOUNT_BASE;
27 char *join_paths(void *alloc_ctx, const char *a, const char *b)
31 full_path = talloc_array(alloc_ctx, char, strlen(a) + strlen(b) + 2);
34 if (b[0] != '/' && a[strlen(a) - 1] != '/')
35 strcat(full_path, "/");
42 static char *local_name(void *ctx)
46 tmp = tempnam(NULL, "pb-");
51 ret = talloc_strdup(ctx, tmp);
57 static void load_url_exit_cb(struct process *process)
59 struct load_url_async_data *url_data = process->data;
61 pb_log("The download client '%s' [pid %d] exited, rc %d\n",
62 process->path, process->pid, process->exit_status);
64 url_data->url_cb(url_data->ctx, process->exit_status);
66 process_release(process);
70 * pb_load_nfs - Mounts the NFS export and returns the local file path.
72 * Returns the local file path in a talloc'ed character string on success,
75 static char *load_nfs(void *ctx, struct pb_url *url,
76 struct load_url_async_data *url_data)
80 struct process *process;
81 const char *argv[] = {
91 local = local_name(ctx);
96 result = pb_mkdir_recursive(local);
100 opts = talloc_strdup(NULL, "ro,nolock,nodiratime");
104 opts = talloc_asprintf_append(opts, ",port=%s", url->port);
107 process = process_create(ctx);
109 process->path = pb_system_apps.mount;
110 process->argv = argv;
111 process->exit_cb = load_url_exit_cb;
112 process->data = url_data;
114 result = process_run_async(process);
116 process_release(process);
118 result = process_run_simple_argv(ctx, argv);
126 local = talloc_asprintf_append(local, "/%s", url->path);
127 pb_log("%s: local '%s'\n", __func__, local);
132 pb_rmdir_recursive("/", local);
138 * pb_load_sftp - Loads a remote file via sftp and returns the local file path.
140 * Returns the local file path in a talloc'ed character string on success,
143 static char *load_sftp(void *ctx, struct pb_url *url,
144 struct load_url_async_data *url_data)
146 char *host_path, *local;
148 struct process *process;
149 const char *argv[] = {
156 local = local_name(ctx);
161 host_path = talloc_asprintf(local, "%s:%s", url->host, url->path);
165 process = process_create(ctx);
167 process->path = pb_system_apps.sftp;
168 process->argv = argv;
169 process->exit_cb = load_url_exit_cb;
170 process->data = url_data;
172 result = process_run_async(process);
174 process_release(process);
176 result = process_run_simple_argv(ctx, argv);
190 * pb_load_tftp - Loads a remote file via tftp and returns the local file path.
192 * Returns the local file path in a talloc'ed character string on success,
196 static char *load_tftp(void *ctx, struct pb_url *url,
197 struct load_url_async_data *url_data)
200 const char *argv[10];
203 struct process *process;
205 local = local_name(ctx);
210 /* first try busybox tftp args */
213 *p++ = pb_system_apps.tftp; /* 1 */
216 *p++ = local; /* 4 */
218 *p++ = url->path; /* 6 */
219 *p++ = url->host; /* 7 */
221 *p++ = url->port; /* 8 */
225 process = process_create(ctx);
227 process->path = pb_system_apps.tftp;
228 process->argv = argv;
229 process->exit_cb = load_url_exit_cb;
230 process->data = url_data;
232 result = process_run_async(process);
234 result = process_run_simple_argv(ctx, argv);
240 /* next try tftp-hpa args */
242 *p++ = pb_system_apps.tftp; /* 1 */
244 *p++ = "binary"; /* 3 */
245 *p++ = url->host; /* 4 */
247 *p++ = url->port; /* 5 */
249 *p++ = "get"; /* 7 */
250 *p++ = url->path; /* 8 */
251 *p++ = local; /* 9 */
252 *p++ = NULL; /* 10 */
255 process->argv = argv;
256 result = process_run_async(process);
258 process_release(process);
260 result = process_run_simple_argv(ctx, argv);
272 wget_no_check_certificate = 1,
276 * pb_load_wget - Loads a remote file via wget and returns the local file path.
278 * Returns the local file path in a talloc'ed character string on success,
282 static char *load_wget(void *ctx, struct pb_url *url, enum wget_flags flags,
283 struct load_url_async_data *url_data)
289 struct process *process;
291 local = local_name(ctx);
297 *p++ = pb_system_apps.wget; /* 1 */
299 *p++ = "--quiet"; /* 2 */
302 *p++ = local; /* 4 */
303 *p++ = url->full; /* 5 */
304 if (flags & wget_no_check_certificate)
305 *p++ = "--no-check-certificate"; /* 6 */
309 process = process_create(ctx);
311 process->path = pb_system_apps.wget;
312 process->argv = argv;
313 process->exit_cb = load_url_exit_cb;
314 process->data = url_data;
316 result = process_run_async(process);
318 process_release(process);
320 result = process_run_simple_argv(ctx, argv);
334 * load_url - Loads a (possibly) remote URL and returns the local file
336 * @ctx: The talloc context to associate with the returned string.
337 * @url: The remote file URL.
338 * @tempfile: An optional variable pointer to be set when a temporary local
340 * @url_cb: An optional callback pointer if the caller wants to load url
343 * Returns the local file path in a talloc'ed character string on success,
347 char *load_url_async(void *ctx, struct pb_url *url, unsigned int *tempfile,
348 load_url_callback url_cb)
352 struct load_url_async_data *url_data;
360 url_data = talloc_zero(ctx, struct load_url_async_data);
361 url_data->url_cb = url_cb;
365 switch (url->scheme) {
368 local = load_wget(ctx, url, 0, url_data);
372 local = load_wget(ctx, url, wget_no_check_certificate,
377 local = load_nfs(ctx, url, url_data);
381 local = load_sftp(ctx, url, url_data);
385 local = load_tftp(ctx, url, url_data);
389 local = talloc_strdup(ctx, url->full);
400 char *load_url(void *ctx, struct pb_url *url, unsigned int *tempfile)
402 return load_url_async(ctx, url, tempfile, NULL);