cat.c 4.07 KB
Newer Older
1 2
/* cat.c - command to show the contents of a file  */
/*
3
 *  GRUB  --  GRand Unified Bootloader
4
 *  Copyright (C) 2003,2005,2007,2008  Free Software Foundation, Inc.
5
 *
6
 *  GRUB is free software: you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation, either version 3 of the License, or
9 10
 *  (at your option) any later version.
 *
11
 *  GRUB is distributed in the hope that it will be useful,
12 13 14 15 16
 *  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
17
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
18 19
 */

20 21 22 23 24
#include <grub/dl.h>
#include <grub/file.h>
#include <grub/disk.h>
#include <grub/term.h>
#include <grub/misc.h>
25
#include <grub/extcmd.h>
26
#include <grub/i18n.h>
27
#include <grub/charset.h>
28

29 30
GRUB_MOD_LICENSE ("GPLv3+");

31 32 33 34 35
static const struct grub_arg_option options[] =
  {
    {"dos", -1, 0, N_("Accept DOS-style CR/NL line endings."), 0, 0},
    {0, 0, 0, 0, 0, 0}
  };
36

37
static grub_err_t
BVK Chaitanya's avatar
BVK Chaitanya committed
38
grub_cmd_cat (grub_extcmd_context_t ctxt, int argc, char **args)
39
{
BVK Chaitanya's avatar
BVK Chaitanya committed
40
  struct grub_arg_list *state = ctxt->state;
41
  int dos = 0;
42
  grub_file_t file;
43
  unsigned char buf[GRUB_DISK_SECTOR_SIZE];
44
  grub_ssize_t size;
45
  int key = GRUB_TERM_NO_KEY;
46 47 48 49 50 51
  grub_uint32_t code = 0;
  int count = 0;
  unsigned char utbuf[GRUB_MAX_UTF8_PER_CODEPOINT + 1];
  int utcount = 0;
  int is_0d = 0;
  int j;
52

53 54 55
  if (state[0].set)
    dos = 1;

56
  if (argc != 1)
57
    return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
58

59
  file = grub_file_open (args[0]);
60
  if (! file)
61
    return grub_errno;
62

63 64
  while ((size = grub_file_read (file, buf, sizeof (buf))) > 0
	 && key != GRUB_TERM_ESC)
65 66
    {
      int i;
67

68 69
      for (i = 0; i < size; i++)
	{
70
	  utbuf[utcount++] = buf[i];
71

72
	  if (is_0d && buf[i] != '\n')
73
	    {
74 75 76
	      grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
	      grub_printf ("<%x>", (int) '\r');
	      grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
77
	    }
78 79 80 81

	  is_0d = 0;

	  if (!grub_utf8_process (buf[i], &code, &count))
82
	    {
83
	      grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
84 85 86 87 88 89 90 91 92 93 94 95 96
	      for (j = 0; j < utcount - 1; j++)
		grub_printf ("<%x>", (unsigned int) utbuf[j]);
	      code = 0;
	      count = 0;
	      if (utcount == 1 || !grub_utf8_process (buf[i], &code, &count))
		{
		  grub_printf ("<%x>", (unsigned int) buf[i]);
		  code = 0;
		  count = 0;
		  utcount = 0;
		  grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
		  continue;
		}
97
	      grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
98
	      utcount = 1;
99
	    }
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
	  if (count)
	    continue;

	  if ((code >= 0xa1 || grub_isprint (code)
	       || grub_isspace (code)) && code != '\r')
	    {
	      grub_printf ("%C", code);
	      count = 0; 
	      code = 0;
	      utcount = 0;
	      continue;
	    }

	  if (dos && code == '\r')
	    {
	      is_0d = 1;
	      count = 0; 
	      code = 0;
	      utcount = 0;
	      continue;
	    }

	  grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
	  for (j = 0; j < utcount; j++)
	    grub_printf ("<%x>", (unsigned int) utbuf[j]);
	  grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
	  count = 0; 
	  code = 0;
	  utcount = 0;
129
	}
130

131 132 133
      do
	key = grub_getkey_noblock ();
      while (key != GRUB_TERM_ESC && key != GRUB_TERM_NO_KEY);
134 135
    }

136 137 138 139 140 141 142
  if (is_0d)
    {
      grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
      grub_printf ("<%x>", (unsigned int) '\r');
      grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
    }

143 144 145 146 147 148 149
  if (utcount)
    {
      grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT);
      for (j = 0; j < utcount; j++)
	grub_printf ("<%x>", (unsigned int) utbuf[j]);
      grub_setcolorstate (GRUB_TERM_COLOR_STANDARD);
    }
150

151
  grub_xputs ("\n");
152 153
  grub_refresh ();
  grub_file_close (file);
154

155 156 157
  return 0;
}

158
static grub_extcmd_t cmd;
159

160
GRUB_MOD_INIT(cat)
161
{
162
  cmd = grub_register_extcmd ("cat", grub_cmd_cat, 0,
163 164
			      N_("FILE"), N_("Show the contents of a file."),
			      options);
165 166
}

167
GRUB_MOD_FINI(cat)
168
{
169
  grub_unregister_extcmd (cmd);
170
}