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