int run_edit (const char *cmd, size_t argc, char *argv[]) { const char *editor; CLEANUP_FREE char *remotefilename = NULL; int r; if (argc != 1) { fprintf (stderr, _("use '%s filename' to edit a file\n"), cmd); return -1; } /* Choose an editor. */ if (STRCASEEQ (cmd, "vi")) editor = "vi"; else if (STRCASEEQ (cmd, "emacs")) editor = "emacs -nw"; else editor = NULL; /* use $EDITOR */ /* Handle 'win:...' prefix. */ remotefilename = win_prefix (argv[0]); if (remotefilename == NULL) return -1; r = edit_file_editor (g, remotefilename, editor, NULL, 0 /* not verbose */); return r == -1 ? -1 : 0; }
int run_copy_out (const char *cmd, size_t argc, char *argv[]) { if (argc < 2) { fprintf (stderr, _("use 'copy-out <remote> [<remote>...] <localdir>' to copy files out of the image\n")); return -1; } /* Local directory is always the last arg. */ const char *local = argv[argc-1]; const int nr_remotes = argc-1; /* Download each remote one at a time using copy-out. */ int i, r; for (i = 0; i < nr_remotes; ++i) { CLEANUP_FREE char *remote = NULL; /* Allow win:... prefix on remotes. */ remote = win_prefix (argv[i]); if (remote == NULL) return -1; r = guestfs_copy_out (g, remote, local); if (r == -1) return -1; } return 0; }
int run_copy_in (const char *cmd, size_t argc, char *argv[]) { CLEANUP_FREE char *remote = NULL; if (argc < 2) { fprintf (stderr, _("use 'copy-in <local> [<local>...] <remotedir>' to copy files into the image\n")); return -1; } /* Remote directory is always the last arg. * Allow "win:" prefix on remote. */ remote = win_prefix (argv[argc-1]); if (remote == NULL) return -1; const int nr_locals = argc-1; /* Upload each local one at a time using copy-in. */ int i; for (i = 0; i < nr_locals; ++i) { int r = guestfs_copy_in (g, argv[i], remote); if (r == -1) return -1; } return 0; }
int run_copy_in (const char *cmd, size_t argc, char *argv[]) { if (argc < 2) { fprintf (stderr, _("use 'copy-in <local> [<local>...] <remotedir>' to copy files into the image\n")); return -1; } /* Remote directory is always the last arg. */ char *remote = argv[argc-1]; /* Allow win: prefix on remote. */ remote = win_prefix (remote); if (remote == NULL) return -1; int nr_locals = argc-1; int remote_is_dir = guestfs_is_dir (g, remote); if (remote_is_dir == -1) { free (remote); return -1; } if (!remote_is_dir) { fprintf (stderr, _("copy-in: target '%s' is not a directory\n"), remote); free (remote); return -1; } /* Upload each local one at a time using tar-in. */ int i; for (i = 0; i < nr_locals; ++i) { struct fd_pid fdpid = make_tar_from_local (argv[i]); if (fdpid.fd == -1) { free (remote); return -1; } char fdbuf[64]; snprintf (fdbuf, sizeof fdbuf, "/dev/fd/%d", fdpid.fd); int r = guestfs_tar_in (g, fdbuf, remote); if (close (fdpid.fd) == -1) { perror ("close (tar-from-local subprocess)"); r = -1; } int status; if (waitpid (fdpid.pid, &status, 0) == -1) { perror ("wait (tar-from-local subprocess)"); free (remote); return -1; } if (!(WIFEXITED (status) && WEXITSTATUS (status) == 0)) { free (remote); return -1; } if (r == -1) { free (remote); return -1; } } free (remote); return 0; }
int run_copy_out (const char *cmd, size_t argc, char *argv[]) { if (argc < 2) { fprintf (stderr, _("use 'copy-out <remote> [<remote>...] <localdir>' to copy files out of the image\n")); return -1; } /* Local directory is always the last arg. */ const char *local = argv[argc-1]; int nr_remotes = argc-1; struct stat statbuf; if (stat (local, &statbuf) == -1 || ! (S_ISDIR (statbuf.st_mode))) { fprintf (stderr, _("copy-out: target '%s' is not a directory\n"), local); return -1; } /* Download each remote one at a time using tar-out. */ int i, r; for (i = 0; i < nr_remotes; ++i) { char *remote = argv[i]; /* Allow win:... prefix on remotes. */ remote = win_prefix (remote); if (remote == NULL) return -1; /* If the remote is a file, download it. If it's a directory, * create the directory in local first before using tar-out. */ r = guestfs_is_file (g, remote); if (r == -1) { free (remote); return -1; } if (r == 1) { /* is file */ char buf[PATH_MAX]; const char *basename; if (split_path (buf, sizeof buf, remote, NULL, &basename) == -1) { free (remote); return -1; } char filename[PATH_MAX]; snprintf (filename, sizeof filename, "%s/%s", local, basename); if (guestfs_download (g, remote, filename) == -1) { free (remote); return -1; } } else { /* not a regular file */ r = guestfs_is_dir (g, remote); if (r == -1) { free (remote); return -1; } if (r == 0) { fprintf (stderr, _("copy-out: '%s' is not a file or directory\n"), remote); free (remote); return -1; } char buf[PATH_MAX]; const char *basename; if (split_path (buf, sizeof buf, remote, NULL, &basename) == -1) { free (remote); return -1; } struct fd_pid fdpid = make_tar_output (local, basename); if (fdpid.fd == -1) { free (remote); return -1; } char fdbuf[64]; snprintf (fdbuf, sizeof fdbuf, "/dev/fd/%d", fdpid.fd); int r = guestfs_tar_out (g, remote, fdbuf); if (close (fdpid.fd) == -1) { perror ("close (tar-output subprocess)"); free (remote); r = -1; } int status; if (waitpid (fdpid.pid, &status, 0) == -1) { perror ("wait (tar-output subprocess)"); free (remote); return -1; } if (!(WIFEXITED (status) && WEXITSTATUS (status) == 0)) { free (remote); return -1; } if (r == -1) { free (remote); return -1; } } free (remote); } return 0; }
int run_edit (const char *cmd, size_t argc, char *argv[]) { CLEANUP_FREE char *tmpdir = guestfs_get_tmpdir (g); CLEANUP_UNLINK_FREE char *filename = NULL; char buf[256]; const char *editor; CLEANUP_FREE char *remotefilename = NULL, *newname = NULL; struct stat oldstat, newstat; int r, fd; if (argc != 1) { fprintf (stderr, _("use '%s filename' to edit a file\n"), cmd); return -1; } /* Choose an editor. */ if (STRCASEEQ (cmd, "vi")) editor = "vi"; else if (STRCASEEQ (cmd, "emacs")) editor = "emacs -nw"; else { editor = getenv ("EDITOR"); if (editor == NULL) editor = "vi"; /* could be cruel here and choose ed(1) */ } /* Handle 'win:...' prefix. */ remotefilename = win_prefix (argv[0]); if (remotefilename == NULL) return -1; /* Download the file and write it to a temporary. */ if (asprintf (&filename, "%s/guestfishXXXXXX", tmpdir) == -1) { perror ("asprintf"); return -1; } fd = mkstemp (filename); if (fd == -1) { perror ("mkstemp"); return -1; } snprintf (buf, sizeof buf, "/dev/fd/%d", fd); if (guestfs_download (g, remotefilename, buf) == -1) { close (fd); return -1; } if (close (fd) == -1) { perror (filename); return -1; } /* Get the old stat. */ if (stat (filename, &oldstat) == -1) { perror (filename); return -1; } /* Edit it. */ /* XXX Safe? */ snprintf (buf, sizeof buf, "%s %s", editor, filename); r = system (buf); if (r != 0) { perror (buf); return -1; } /* Get the new stat. */ if (stat (filename, &newstat) == -1) { perror (filename); return -1; } /* Changed? */ if (oldstat.st_ctime == newstat.st_ctime && oldstat.st_size == newstat.st_size) return 0; /* Upload to a new file in the same directory, so if it fails we * don't end up with a partially written file. Give the new file * a completely random name so we have only a tiny chance of * overwriting some existing file. */ newname = generate_random_name (remotefilename); if (!newname) return -1; /* Write new content. */ if (guestfs_upload (g, filename, newname) == -1) return -1; /* Set the permissions, UID, GID and SELinux context of the new * file to match the old file (RHBZ#788641). */ if (guestfs_copy_attributes (g, remotefilename, newname, GUESTFS_COPY_ATTRIBUTES_ALL, 1, -1) == -1) return -1; if (guestfs_mv (g, newname, remotefilename) == -1) return -1; return 0; }
int run_more (const char *cmd, size_t argc, char *argv[]) { CLEANUP_FREE char *tmpdir = guestfs_get_tmpdir (g); CLEANUP_UNLINK_FREE char *filename = NULL; char buf[256]; CLEANUP_FREE char *remote = NULL; const char *pager; int r, fd; if (argc != 1) { fprintf (stderr, _("use '%s filename' to page a file\n"), cmd); return -1; } /* Choose a pager. */ if (STRCASEEQ (cmd, "less")) pager = "less"; else { pager = getenv ("PAGER"); if (pager == NULL) pager = "more"; } /* Allow win:... prefix on remote. */ remote = win_prefix (argv[0]); if (remote == NULL) return -1; /* Download the file and write it to a temporary. */ if (asprintf (&filename, "%s/guestfishXXXXXX", tmpdir) == -1) { perror ("asprintf"); return -1; } fd = mkstemp (filename); if (fd == -1) { perror ("mkstemp"); return -1; } snprintf (buf, sizeof buf, "/dev/fd/%d", fd); if (guestfs_download (g, remote, buf) == -1) { close (fd); return -1; } if (close (fd) == -1) { perror (filename); return -1; } /* View it. */ /* XXX Safe? */ snprintf (buf, sizeof buf, "%s %s", pager, filename); r = system (buf); if (r != 0) { perror (buf); return -1; } return 0; }
int run_more (const char *cmd, size_t argc, char *argv[]) { TMP_TEMPLATE_ON_STACK (filename); char buf[256]; char *remote; const char *pager; int r, fd; if (argc != 1) { fprintf (stderr, _("use '%s filename' to page a file\n"), cmd); return -1; } /* Choose a pager. */ if (STRCASEEQ (cmd, "less")) pager = "less"; else { pager = getenv ("PAGER"); if (pager == NULL) pager = "more"; } remote = argv[0]; /* Allow win:... prefix on remote. */ remote = win_prefix (remote); if (remote == NULL) return -1; /* Download the file and write it to a temporary. */ fd = mkstemp (filename); if (fd == -1) { perror ("mkstemp"); free (remote); return -1; } snprintf (buf, sizeof buf, "/dev/fd/%d", fd); if (guestfs_download (g, remote, buf) == -1) { close (fd); unlink (filename); free (remote); return -1; } if (close (fd) == -1) { perror (filename); unlink (filename); free (remote); return -1; } /* View it. */ /* XXX Safe? */ snprintf (buf, sizeof buf, "%s %s", pager, filename); r = system (buf); unlink (filename); if (r != 0) { perror (buf); free (remote); return -1; } free (remote); return 0; }
int run_display (const char *cmd, size_t argc, char *argv[]) { TMP_TEMPLATE_ON_STACK (filename); char *remote; const char *display; char buf[256]; int r, fd; if (argc != 1) { fprintf (stderr, _("display filename\n")); return -1; } /* Choose a display command. */ display = getenv ("GUESTFISH_DISPLAY_IMAGE"); if (display == NULL) display = "display"; remote = argv[0]; /* Allow win:... prefix on remote. */ remote = win_prefix (remote); if (remote == NULL) return -1; /* Download the file and write it to a temporary. */ fd = mkstemp (filename); if (fd == -1) { perror ("mkstemp"); free (remote); return -1; } snprintf (buf, sizeof buf, "/dev/fd/%d", fd); if (guestfs_download (g, remote, buf) == -1) { close (fd); unlink (filename); free (remote); return -1; } if (close (fd) == -1) { perror (filename); unlink (filename); free (remote); return -1; } /* View it. */ snprintf (buf, sizeof buf, "%s %s", display, filename); r = system (buf); unlink (filename); if (r != 0) { perror (buf); free (remote); return -1; } free (remote); return 0; }
int run_display (const char *cmd, size_t argc, char *argv[]) { CLEANUP_FREE char *tmpdir = guestfs_get_tmpdir (g), *filename = NULL; CLEANUP_FREE char *remote = NULL; const char *display; char buf[256]; int r, fd; if (argc != 1) { fprintf (stderr, _("display filename\n")); return -1; } /* Choose a display command. */ display = getenv ("GUESTFISH_DISPLAY_IMAGE"); if (display == NULL) display = "display"; /* Allow win:... prefix on remote. */ remote = win_prefix (argv[0]); if (remote == NULL) return -1; /* Download the file and write it to a temporary. */ if (asprintf (&filename, "%s/guestfishXXXXXX", tmpdir) == -1) { perror ("asprintf"); return -1; } fd = mkstemp (filename); if (fd == -1) { perror ("mkstemp"); return -1; } snprintf (buf, sizeof buf, "/dev/fd/%d", fd); if (guestfs_download (g, remote, buf) == -1) { close (fd); unlink (filename); return -1; } if (close (fd) == -1) { perror (filename); unlink (filename); return -1; } /* View it. */ snprintf (buf, sizeof buf, "%s %s", display, filename); r = system (buf); unlink (filename); if (r != 0) { perror (buf); return -1; } return 0; }