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;
23 const char *mount_base(void)
25 return DEVICE_MOUNT_BASE;
28 char *join_paths(void *alloc_ctx, const char *a, const char *b)
32 full_path = talloc_array(alloc_ctx, char, strlen(a) + strlen(b) + 2);
35 if (b[0] != '/' && a[strlen(a) - 1] != '/')
36 strcat(full_path, "/");
43 static char *local_name(void *ctx)
47 tmp = tempnam(NULL, "pb-");
52 ret = talloc_strdup(ctx, tmp);
58 static void load_url_exit_cb(struct process *process)
60 struct load_url_async_data *url_data = process->data;
62 pb_log("The download client '%s' [pid %d] exited, rc %d\n",
63 process->path, process->pid, process->exit_status);
65 if (!url_data->status)
66 url_data->url_cb(url_data->ctx, &(url_data->status));
68 process_release(process);
72 * pb_load_nfs - Mounts the NFS export and returns the local file path.
74 * Returns the local file path in a talloc'ed character string on success,
77 static char *load_nfs(void *ctx, struct pb_url *url,
78 struct load_url_async_data *url_data)
82 struct process *process;
83 const char *argv[] = {
93 local = local_name(ctx);
98 result = pb_mkdir_recursive(local);
102 opts = talloc_strdup(NULL, "ro,nolock,nodiratime");
106 opts = talloc_asprintf_append(opts, ",port=%s", url->port);
109 process = process_create(ctx);
111 process->path = pb_system_apps.mount;
112 process->argv = argv;
113 process->exit_cb = load_url_exit_cb;
114 process->data = url_data;
116 result = process_run_async(process);
118 process_release(process);
120 result = process_run_simple_argv(ctx, argv);
128 local = talloc_asprintf_append(local, "/%s", url->path);
129 pb_log("%s: local '%s'\n", __func__, local);
134 pb_rmdir_recursive("/", local);
140 * pb_load_sftp - Loads a remote file via sftp and returns the local file path.
142 * Returns the local file path in a talloc'ed character string on success,
145 static char *load_sftp(void *ctx, struct pb_url *url,
146 struct load_url_async_data *url_data)
148 char *host_path, *local;
150 struct process *process;
151 const char *argv[] = {
158 local = local_name(ctx);
163 host_path = talloc_asprintf(local, "%s:%s", url->host, url->path);
167 process = process_create(ctx);
169 process->path = pb_system_apps.sftp;
170 process->argv = argv;
171 process->exit_cb = load_url_exit_cb;
172 process->data = url_data;
174 result = process_run_async(process);
176 process_release(process);
178 result = process_run_simple_argv(ctx, argv);
192 * pb_load_tftp - Loads a remote file via tftp and returns the local file path.
194 * Returns the local file path in a talloc'ed character string on success,
198 static char *load_tftp(void *ctx, struct pb_url *url,
199 struct load_url_async_data *url_data)
202 const char *argv[10];
205 struct process *process;
207 local = local_name(ctx);
212 /* first try busybox tftp args */
215 *p++ = pb_system_apps.tftp; /* 1 */
218 *p++ = local; /* 4 */
220 *p++ = url->path; /* 6 */
221 *p++ = url->host; /* 7 */
223 *p++ = url->port; /* 8 */
227 process = process_create(ctx);
229 process->path = pb_system_apps.tftp;
230 process->argv = argv;
231 process->exit_cb = load_url_exit_cb;
232 process->data = url_data;
234 result = process_run_async(process);
236 result = process_run_simple_argv(ctx, argv);
242 /* next try tftp-hpa args */
244 *p++ = pb_system_apps.tftp; /* 1 */
246 *p++ = "binary"; /* 3 */
247 *p++ = url->host; /* 4 */
249 *p++ = url->port; /* 5 */
251 *p++ = "get"; /* 7 */
252 *p++ = url->path; /* 8 */
253 *p++ = local; /* 9 */
254 *p++ = NULL; /* 10 */
257 process->argv = argv;
258 result = process_run_async(process);
260 process_release(process);
262 result = process_run_simple_argv(ctx, argv);
274 wget_no_check_certificate = 1,
278 * pb_load_wget - Loads a remote file via wget and returns the local file path.
280 * Returns the local file path in a talloc'ed character string on success,
284 static char *load_wget(void *ctx, struct pb_url *url, enum wget_flags flags,
285 struct load_url_async_data *url_data)
291 struct process *process;
293 local = local_name(ctx);
299 *p++ = pb_system_apps.wget; /* 1 */
301 *p++ = "--quiet"; /* 2 */
304 *p++ = local; /* 4 */
305 *p++ = url->full; /* 5 */
306 if (flags & wget_no_check_certificate)
307 *p++ = "--no-check-certificate"; /* 6 */
311 process = process_create(ctx);
313 process->path = pb_system_apps.wget;
314 process->argv = argv;
315 process->exit_cb = load_url_exit_cb;
316 process->data = url_data;
318 result = process_run_async(process);
320 process_release(process);
322 result = process_run_simple_argv(ctx, argv);
336 * load_url - Loads a (possibly) remote URL and returns the local file
338 * @ctx: The talloc context to associate with the returned string.
339 * @url: The remote file URL.
340 * @tempfile: An optional variable pointer to be set when a temporary local
342 * @url_cb: An optional callback pointer if the caller wants to load url
345 * Returns the local file path in a talloc'ed character string on success,
349 char *load_url_async(void *ctx, struct pb_url *url, unsigned int *tempfile,
350 load_url_callback url_cb)
354 struct load_url_async_data *url_data;
362 url_data = talloc_zero(ctx, struct load_url_async_data);
363 url_data->url_cb = url_cb;
365 url_data->status = 0;
368 switch (url->scheme) {
371 local = load_wget(ctx, url, 0, url_data);
375 local = load_wget(ctx, url, wget_no_check_certificate,
380 local = load_nfs(ctx, url, url_data);
384 local = load_sftp(ctx, url, url_data);
388 local = load_tftp(ctx, url, url_data);
392 local = talloc_strdup(ctx, url->full);
403 char *load_url(void *ctx, struct pb_url *url, unsigned int *tempfile)
405 return load_url_async(ctx, url, tempfile, NULL);