1/*
2 * rlcat - cat(1) using readline
3 *
4 * usage: rlcat
5 */
6
7/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
8
9   This file is part of the GNU Readline Library (Readline), a library for
10   reading lines of text with interactive input and history editing.
11
12   Readline is free software: you can redistribute it and/or modify
13   it under the terms of the GNU General Public License as published by
14   the Free Software Foundation, either version 3 of the License, or
15   (at your option) any later version.
16
17   Readline is distributed in the hope that it will be useful,
18   but WITHOUT ANY WARRANTY; without even the implied warranty of
19   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20   GNU General Public License for more details.
21
22   You should have received a copy of the GNU General Public License
23   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
24*/
25
26#if defined (HAVE_CONFIG_H)
27#  include <config.h>
28#endif
29
30#ifdef HAVE_UNISTD_H
31#  include <unistd.h>
32#endif
33
34#include <sys/types.h>
35#include "posixstat.h"
36
37#include <stdio.h>
38#include <ctype.h>
39#include <string.h>
40#include <errno.h>
41
42#ifdef HAVE_STDLIB_H
43#  include <stdlib.h>
44#else
45extern void exit();
46#endif
47
48#ifndef errno
49extern int errno;
50#endif
51
52#if defined (READLINE_LIBRARY)
53#  include "readline.h"
54#  include "history.h"
55#else
56#  include <readline/readline.h>
57#  include <readline/history.h>
58#endif
59
60extern int optind;
61extern char *optarg;
62
63static int stdcat();
64
65static char *progname;
66static int vflag;
67
68static void
69usage()
70{
71  fprintf (stderr, "%s: usage: %s [-vEVN] [filename]\n", progname, progname);
72}
73
74int
75main (argc, argv)
76     int argc;
77     char **argv;
78{
79  char *temp;
80  int opt, Vflag, Nflag;
81
82  progname = strrchr(argv[0], '/');
83  if (progname == 0)
84    progname = argv[0];
85  else
86    progname++;
87
88  vflag = Vflag = Nflag = 0;
89  while ((opt = getopt(argc, argv, "vEVN")) != EOF)
90    {
91      switch (opt)
92	{
93	case 'v':
94	  vflag = 1;
95	  break;
96	case 'V':
97	  Vflag = 1;
98	  break;
99	case 'E':
100	  Vflag = 0;
101	  break;
102	case 'N':
103	  Nflag = 1;
104	  break;
105	default:
106	  usage ();
107	  exit (2);
108	}
109    }
110
111  argc -= optind;
112  argv += optind;
113
114  if (isatty(0) == 0 || argc || Nflag)
115    return stdcat(argc, argv);
116
117  rl_variable_bind ("editing-mode", Vflag ? "vi" : "emacs");
118  while (temp = readline (""))
119    {
120      if (*temp)
121        add_history (temp);
122      printf ("%s\n", temp);
123    }
124
125  return (ferror (stdout));
126}
127
128static int
129fcopy(fp)
130     FILE *fp;
131{
132  int c;
133  char *x;
134
135  while ((c = getc(fp)) != EOF)
136    {
137      if (vflag && isascii ((unsigned char)c) && isprint((unsigned char)c) == 0)
138	{
139	  x = rl_untranslate_keyseq (c);
140	  if (fputs (x, stdout) != 0)
141	    return 1;
142	}
143      else if (putchar (c) == EOF)
144        return 1;
145    }
146  return (ferror (stdout));
147}
148
149int
150stdcat (argc, argv)
151     int argc;
152     char **argv;
153{
154  int  i, fd, r;
155  char *s;
156  FILE *fp;
157
158  if (argc == 0)
159    return (fcopy(stdin));
160
161  for (i = 0, r = 1; i < argc; i++)
162    {
163      if (*argv[i] == '-' && argv[i][1] == 0)
164	fp = stdin;
165      else
166	{
167	  fp = fopen (argv[i], "r");
168	  if (fp == 0)
169	    {
170	      fprintf (stderr, "%s: %s: cannot open: %s\n", progname, argv[i], strerror(errno));
171	      continue;
172	    }
173        }
174      r = fcopy (fp);
175      if (fp != stdin)
176	fclose(fp);
177    }
178  return r;
179}
180