minor rewording, no fixes
[unix-history] / usr / src / usr.bin / more / main.c
CommitLineData
bfe13c81
KB
1/*
2 * Copyright (c) 1988 Mark Nudleman
3 * Copyright (c) 1988 Regents of the University of California.
4 * All rights reserved.
5 *
f15db449 6 * %sccs.include.redist.c%
bfe13c81
KB
7 */
8
9#ifndef lint
10char copyright[] =
11"@(#) Copyright (c) 1988 Mark Nudleman.\n\
12@(#) Copyright (c) 1988 Regents of the University of California.\n\
13 All rights reserved.\n";
14#endif /* not lint */
15
16#ifndef lint
f15db449 17static char sccsid[] = "@(#)main.c 5.13 (Berkeley) %G%";
bfe13c81
KB
18#endif /* not lint */
19
20/*
21 * Entry point, initialization, miscellaneous routines.
22 */
23
bc258617
KB
24#include <sys/types.h>
25#include <sys/file.h>
26#include <stdio.h>
27#include <less.h>
bfe13c81 28
bc258617
KB
29int ispipe;
30int new_file;
31int is_tty;
7a3f847f 32char *current_file, *previous_file, *current_name, *next_name;
bc258617
KB
33off_t prev_pos;
34int any_display;
35int scroll;
36int ac;
37char **av;
38int curr_ac;
39int quitting;
bfe13c81
KB
40
41extern int file;
bfe13c81
KB
42extern int cbufs;
43extern int errmsgs;
44
bc258617 45extern char *tagfile;
bfe13c81 46extern int tagoption;
bfe13c81 47
bfe13c81
KB
48/*
49 * Edit a new file.
50 * Filename "-" means standard input.
51 * No filename means the "current" file, from the command line.
52 */
bfe13c81
KB
53edit(filename)
54 register char *filename;
55{
bc258617 56 extern int errno;
bfe13c81
KB
57 register int f;
58 register char *m;
bc258617 59 off_t initial_pos, position();
bfe13c81 60 static int didpipe;
bc258617
KB
61 char message[100], *p;
62 char *rindex(), *strerror(), *save(), *bad_file();
bfe13c81
KB
63
64 initial_pos = NULL_POSITION;
bc258617
KB
65 if (filename == NULL || *filename == '\0') {
66 if (curr_ac >= ac) {
bfe13c81 67 error("No current file");
bc258617 68 return(0);
bfe13c81
KB
69 }
70 filename = save(av[curr_ac]);
bc258617
KB
71 }
72 else if (strcmp(filename, "#") == 0) {
73 if (*previous_file == '\0') {
bfe13c81 74 error("no previous file");
bc258617 75 return(0);
bfe13c81
KB
76 }
77 filename = save(previous_file);
78 initial_pos = prev_pos;
79 } else
80 filename = save(filename);
81
bc258617
KB
82 /* use standard input. */
83 if (!strcmp(filename, "-")) {
84 if (didpipe) {
bfe13c81 85 error("Can view standard input only once");
bc258617 86 return(0);
bfe13c81
KB
87 }
88 f = 0;
bc258617
KB
89 }
90 else if ((m = bad_file(filename, message, sizeof(message))) != NULL) {
bfe13c81
KB
91 error(m);
92 free(filename);
bc258617
KB
93 return(0);
94 }
95 else if ((f = open(filename, O_RDONLY, 0)) < 0) {
96 (void)sprintf(message, "%s: %s", filename, strerror(errno));
97 error(message);
bfe13c81 98 free(filename);
bc258617 99 return(0);
bfe13c81
KB
100 }
101
bc258617 102 if (isatty(f)) {
bfe13c81
KB
103 /*
104 * Not really necessary to call this an error,
105 * but if the control terminal (for commands)
106 * and the input file (for data) are the same,
107 * we get weird results at best.
108 */
109 error("Can't take input from a terminal");
110 if (f > 0)
bc258617
KB
111 (void)close(f);
112 (void)free(filename);
113 return(0);
bfe13c81
KB
114 }
115
bfe13c81
KB
116 /*
117 * We are now committed to using the new file.
118 * Close the current input file and set up to use the new one.
119 */
120 if (file > 0)
bc258617 121 (void)close(file);
bfe13c81
KB
122 new_file = 1;
123 if (previous_file != NULL)
124 free(previous_file);
125 previous_file = current_file;
126 current_file = filename;
38b11f7d 127 pos_clear();
bfe13c81
KB
128 prev_pos = position(TOP);
129 ispipe = (f == 0);
bc258617 130 if (ispipe) {
bfe13c81 131 didpipe = 1;
bc258617
KB
132 current_name = "stdin";
133 } else
134 current_name = (p = rindex(filename, '/')) ? p + 1 : filename;
7a3f847f
KB
135 if (curr_ac >= ac)
136 next_name = NULL;
137 else
138 next_name = av[curr_ac + 1];
bfe13c81
KB
139 file = f;
140 ch_init(cbufs, 0);
141 init_mark();
142
bc258617 143 if (is_tty) {
bfe13c81
KB
144 int no_display = !any_display;
145 any_display = 1;
bc258617 146 if (no_display && errmsgs > 0) {
bfe13c81
KB
147 /*
148 * We displayed some messages on error output
149 * (file descriptor 2; see error() function).
150 * Before erasing the screen contents,
151 * display the file name and wait for a keystroke.
152 */
153 error(filename);
154 }
155 /*
156 * Indicate there is nothing displayed yet.
157 */
bfe13c81
KB
158 if (initial_pos != NULL_POSITION)
159 jump_loc(initial_pos);
160 clr_linenum();
161 }
bc258617 162 return(1);
bfe13c81
KB
163}
164
165/*
166 * Edit the next file in the command line list.
167 */
bfe13c81
KB
168next_file(n)
169 int n;
170{
bc258617
KB
171 extern int quit_at_eof;
172 off_t position();
173
174 if (curr_ac + n >= ac) {
175 if (quit_at_eof || position(TOP) == NULL_POSITION)
bfe13c81
KB
176 quit();
177 error("No (N-th) next file");
bc258617
KB
178 }
179 else
180 (void)edit(av[curr_ac += n]);
bfe13c81
KB
181}
182
183/*
184 * Edit the previous file in the command line list.
185 */
bfe13c81
KB
186prev_file(n)
187 int n;
188{
189 if (curr_ac - n < 0)
190 error("No (N-th) previous file");
191 else
bc258617 192 (void)edit(av[curr_ac -= n]);
bfe13c81
KB
193}
194
195/*
12751432
KB
196 * copy a file directly to standard output; used if stdout is not a tty.
197 * the only processing is to squeeze multiple blank input lines.
bfe13c81 198 */
bc258617 199static
bfe13c81
KB
200cat_file()
201{
12751432
KB
202 extern int squeeze;
203 register int c, empty;
204
205 if (squeeze) {
206 empty = 0;
207 while ((c = ch_forw_get()) != EOI)
208 if (c != '\n') {
209 putchr(c);
210 empty = 0;
211 }
212 else if (empty < 2) {
213 putchr(c);
214 ++empty;
215 }
216 }
217 else while ((c = ch_forw_get()) != EOI)
bfe13c81
KB
218 putchr(c);
219 flush();
220}
221
bfe13c81
KB
222main(argc, argv)
223 int argc;
bc258617 224 char **argv;
bfe13c81 225{
bc258617
KB
226 int envargc, argcnt;
227 char *envargv[2], *getenv();
bfe13c81
KB
228
229 /*
bc258617 230 * Process command line arguments and MORE environment arguments.
bfe13c81
KB
231 * Command line arguments override environment arguments.
232 */
bc258617
KB
233 if (envargv[1] = getenv("MORE")) {
234 envargc = 2;
235 envargv[0] = "more";
236 envargv[2] = NULL;
237 (void)option(envargc, envargv);
238 }
239 argcnt = option(argc, argv);
240 argv += argcnt;
241 argc -= argcnt;
bfe13c81 242
bfe13c81
KB
243 /*
244 * Set up list of files to be examined.
245 */
246 ac = argc;
247 av = argv;
248 curr_ac = 0;
249
250 /*
251 * Set up terminal, etc.
252 */
253 is_tty = isatty(1);
bc258617 254 if (!is_tty) {
bfe13c81
KB
255 /*
256 * Output is not a tty.
257 * Just copy the input file(s) to output.
258 */
bc258617
KB
259 if (ac < 1) {
260 (void)edit("-");
bfe13c81 261 cat_file();
bc258617
KB
262 } else {
263 do {
264 (void)edit((char *)NULL);
bfe13c81
KB
265 if (file >= 0)
266 cat_file();
267 } while (++curr_ac < ac);
268 }
269 exit(0);
270 }
271
272 raw_mode(1);
273 get_term();
274 open_getchr();
275 init();
bfe13c81
KB
276 init_signals(1);
277
bc258617
KB
278 /* select the first file to examine. */
279 if (tagoption) {
bfe13c81 280 /*
bc258617
KB
281 * A -t option was given; edit the file selected by the
282 * "tags" search, and search for the proper line in the file.
bfe13c81 283 */
bc258617 284 if (!tagfile || !edit(tagfile) || tagsearch())
bfe13c81 285 quit();
bc258617
KB
286 }
287 else if (ac < 1)
288 (void)edit("-"); /* Standard input */
289 else {
bfe13c81
KB
290 /*
291 * Try all the files named as command arguments.
292 * We are simply looking for one which can be
293 * opened without error.
294 */
bc258617
KB
295 do {
296 (void)edit((char *)NULL);
bfe13c81
KB
297 } while (file < 0 && ++curr_ac < ac);
298 }
299
300 if (file >= 0)
301 commands();
302 quit();
303 /*NOTREACHED*/
304}
305
bfe13c81
KB
306/*
307 * Copy a string to a "safe" place
c48c82c8 308 * (that is, to a buffer allocated by malloc).
bfe13c81 309 */
bc258617 310char *
bfe13c81
KB
311save(s)
312 char *s;
313{
c48c82c8 314 char *p, *strcpy(), *malloc();
bfe13c81 315
c48c82c8 316 p = malloc((u_int)strlen(s)+1);
bfe13c81
KB
317 if (p == NULL)
318 {
319 error("cannot allocate memory");
320 quit();
321 }
c48c82c8 322 return(strcpy(p, s));
bfe13c81
KB
323}
324
325/*
326 * Exit the program.
327 */
bfe13c81
KB
328quit()
329{
330 /*
331 * Put cursor at bottom left corner, clear the line,
332 * reset the terminal modes, and exit.
333 */
334 quitting = 1;
bfe13c81
KB
335 lower_left();
336 clear_eol();
337 deinit();
338 flush();
339 raw_mode(0);
340 exit(0);
341}