mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
Implement "more" and "less" commands in guestfish.
Use commands such as: more /etc/passwd less /etc/fstab These commands are specific to guestfish.
This commit is contained in:
1
TODO
1
TODO
@@ -156,7 +156,6 @@ Extra commands / functionality:
|
||||
fts(3) / ftw(3)
|
||||
|
||||
guestfish only:
|
||||
more/less (like cat, but pipes it through $PAGER)
|
||||
cat file | pipe-cmd should have a generic form? like
|
||||
'file | less' or 'file | sort'?
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@ guestfish_SOURCES = \
|
||||
fish.c \
|
||||
fish.h \
|
||||
glob.c \
|
||||
lcd.c
|
||||
lcd.c \
|
||||
more.c
|
||||
|
||||
guestfish_CFLAGS = \
|
||||
-I$(top_builddir)/src -Wall \
|
||||
|
||||
18
fish/edit.c
18
fish/edit.c
@@ -29,24 +29,6 @@
|
||||
|
||||
/* guestfish edit command, suggested by Ján Ondrej, implemented by RWMJ */
|
||||
|
||||
static int
|
||||
xwrite (int fd, const void *buf, size_t len)
|
||||
{
|
||||
int r;
|
||||
|
||||
while (len > 0) {
|
||||
r = write (fd, buf, len);
|
||||
if (r == -1) {
|
||||
perror ("write");
|
||||
return -1;
|
||||
}
|
||||
buf += r;
|
||||
len -= r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
load_file (const char *filename, int *len_r)
|
||||
{
|
||||
|
||||
36
fish/fish.c
36
fish/fish.c
@@ -724,6 +724,9 @@ issue_command (const char *cmd, char *argv[], const char *pipecmd)
|
||||
r = do_lcd (cmd, argc, argv);
|
||||
else if (strcasecmp (cmd, "glob") == 0)
|
||||
r = do_glob (cmd, argc, argv);
|
||||
else if (strcasecmp (cmd, "more") == 0 ||
|
||||
strcasecmp (cmd, "less") == 0)
|
||||
r = do_more (cmd, argc, argv);
|
||||
else
|
||||
r = run_action (cmd, argc, argv);
|
||||
|
||||
@@ -818,6 +821,21 @@ display_builtin_command (const char *cmd)
|
||||
" Glob runs <command> with wildcards expanded in any\n"
|
||||
" command args. Note that the command is run repeatedly\n"
|
||||
" once for each expanded argument.\n"));
|
||||
else if (strcasecmp (cmd, "more") == 0 ||
|
||||
strcasecmp (cmd, "less") == 0)
|
||||
printf (_("more - view a file in the pager\n"
|
||||
" more <filename>\n"
|
||||
"\n"
|
||||
" This is used to view a file in the pager.\n"
|
||||
"\n"
|
||||
" It is the equivalent of (and is implemented by)\n"
|
||||
" running \"cat\" and using the pager.\n"
|
||||
"\n"
|
||||
" Normally it uses $PAGER, but if you use the alias\n"
|
||||
" \"less\" then it always uses \"less\".\n"
|
||||
"\n"
|
||||
" NOTE: This will not work reliably for large files\n"
|
||||
" (> 2 MB) or binary files containing \\0 bytes.\n"));
|
||||
else if (strcasecmp (cmd, "help") == 0)
|
||||
printf (_("help - display a list of commands or help on a command\n"
|
||||
" help cmd\n"
|
||||
@@ -959,3 +977,21 @@ add_history_line (const char *line)
|
||||
nr_history_lines++;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
xwrite (int fd, const void *buf, size_t len)
|
||||
{
|
||||
int r;
|
||||
|
||||
while (len > 0) {
|
||||
r = write (fd, buf, len);
|
||||
if (r == -1) {
|
||||
perror ("write");
|
||||
return -1;
|
||||
}
|
||||
buf += r;
|
||||
len -= r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ extern void print_table (char * const * const argv);
|
||||
extern int launch (guestfs_h *);
|
||||
extern int is_true (const char *str);
|
||||
extern char **parse_string_list (const char *str);
|
||||
extern int xwrite (int fd, const void *buf, size_t len);
|
||||
|
||||
/* in cmds.c (auto-generated) */
|
||||
extern void list_commands (void);
|
||||
@@ -73,6 +74,9 @@ extern int do_lcd (const char *cmd, int argc, char *argv[]);
|
||||
/* in glob.c */
|
||||
extern int do_glob (const char *cmd, int argc, char *argv[]);
|
||||
|
||||
/* in more.c */
|
||||
extern int do_more (const char *cmd, int argc, char *argv[]);
|
||||
|
||||
/* This should just list all the built-in commands so they can
|
||||
* be added to the generated auto-completion code.
|
||||
*/
|
||||
@@ -83,6 +87,7 @@ extern int do_glob (const char *cmd, int argc, char *argv[]);
|
||||
"echo", \
|
||||
"edit", "vi", "emacs", \
|
||||
"lcd", \
|
||||
"glob"
|
||||
"glob", \
|
||||
"more", "less"
|
||||
|
||||
#endif /* FISH_H */
|
||||
|
||||
93
fish/more.c
Normal file
93
fish/more.c
Normal file
@@ -0,0 +1,93 @@
|
||||
/* guestfish - the filesystem interactive shell
|
||||
* Copyright (C) 2009 Red Hat Inc.
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "fish.h"
|
||||
|
||||
int
|
||||
do_more (const char *cmd, int argc, char *argv[])
|
||||
{
|
||||
char filename[] = "/tmp/guestfishXXXXXX";
|
||||
char buf[256];
|
||||
const char *pager;
|
||||
char *content;
|
||||
int r, fd;
|
||||
|
||||
if (argc != 1) {
|
||||
fprintf (stderr, _("use '%s filename' to page a file\n"), cmd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Choose a pager. */
|
||||
if (strcasecmp (cmd, "less") == 0)
|
||||
pager = "less";
|
||||
else {
|
||||
pager = getenv ("PAGER");
|
||||
if (pager == NULL)
|
||||
pager = "more";
|
||||
}
|
||||
|
||||
/* Download the file and write it to a temporary. */
|
||||
fd = mkstemp (filename);
|
||||
if (fd == -1) {
|
||||
perror ("mkstemp");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((content = guestfs_cat (g, argv[0])) == NULL) {
|
||||
close (fd);
|
||||
unlink (filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (xwrite (fd, content, strlen (content)) == -1) {
|
||||
close (fd);
|
||||
unlink (filename);
|
||||
free (content);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free (content);
|
||||
|
||||
if (close (fd) == -1) {
|
||||
perror (filename);
|
||||
unlink (filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* View it. */
|
||||
/* XXX Safe? */
|
||||
snprintf (buf, sizeof buf, "%s %s", pager, filename);
|
||||
|
||||
r = system (buf);
|
||||
unlink (filename);
|
||||
if (r != 0) {
|
||||
perror (buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user