⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 more.c

📁 Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、分区和管理硬盘驱动器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 1980 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley.  The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. *//*** more.c - General purpose tty output filter and file perusal program****	by Eric Shienbrood, UC Berkeley****	modified by Geoff Peck, UCB to add underlining, single spacing**	modified by John Foderaro, UCB to add -c and MORE environment variable**	modified by Erik Troan <ewt@redhat.com> to be more posix and so compile**	  on linux/axp.**	modified by Kars de Jong <jongk@cs.utwente.nl> to use terminfo instead**	  of termcap.	1999-02-22 Arkadiusz Mi秌iewicz <misiek@pld.ORG.PL>	- added Native Language Support	1999-03-19 Arnaldo Carvalho de Melo <acme@conectiva.com.br>	- more nls translatable strings	1999-05-09 aeb - applied a RedHat patch (setjmp->sigsetjmp); without it	a second ^Z would fail.	1999-05-09 aeb - undone Kars' work, so that more works without	libcurses (and hence can be in /bin with libcurses being in /usr/lib	which may not be mounted). However, when termcap is not present curses	can still be used.*/#include <stdio.h>#include <string.h>#include <unistd.h>#include <stdlib.h>		/* for alloca() */#include <stdarg.h>		/* for va_start() etc */#include <sys/param.h>#include <ctype.h>#include <signal.h>#include <errno.h>#include <termios.h>#include <setjmp.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <sys/file.h>#include <sys/wait.h>#include <a.out.h>#include <locale.h>#include "xstrncpy.h"#include "nls.h"#include "widechar.h"#define _REGEX_RE_COMP#include <regex.h>#undef _REGEX_RE_COMP#define VI		"vi"	/* found on the user's path */#define Fopen(s,m)	(Currline = 0,file_pos=0,fopen(s,m))#define Ftell(f)	file_pos#define Fseek(f,off)	(file_pos=off,fseek(f,off,0))#define Getc(f)		(++file_pos, getc(f))#define Ungetc(c,f)	(--file_pos, ungetc(c,f))#define putcerr(c)	fputc(c, stderr)#define putserr(s)	fputs(s, stderr)#define putsout(s)	fputs(s, stdout)#define stty(fd,argp)  tcsetattr(fd,TCSANOW,argp)/* some function declarations */void initterm(void);void kill_line(void);void doclear(void);void cleareol(void);void clreos(void);void home(void);void error (char *mess);void do_shell (char *filename);int  colon (char *filename, int cmd, int nlines);int  expand (char **outbuf, char *inbuf);void argscan(char *s,char *argv0);void rdline (register FILE *f);void copy_file(register FILE *f);void search(char buf[], FILE *file, register int n);void skipf (register int nskip);void skiplns(register int n, register FILE *f);void screen (register FILE *f, register int num_lines);int  command (char *filename, register FILE *f);void erasep (register int col);void show (register char ch);void set_tty(void);void reset_tty(void);void ttyin (unsigned char buf[], register int nmax, char pchar);int  number(char *cmd);int  readch (void);int  get_line(register FILE *f, int *length);void prbuf (register char *s, register int n);void execute (char *filename, char *cmd, ...);FILE *checkf (char *, int *);#define TBUFSIZ	1024#define LINSIZ	256#define ctrl(letter)	(letter & 077)#define RUBOUT	'\177'#define ESC	'\033'#define QUIT	'\034'struct termios	otty, savetty0;long		file_pos, file_size;int		fnum, no_intty, no_tty, slow_tty;int		dum_opt, dlines;void		onquit(int), onsusp(int), chgwinsz(int), end_it(int);int		nscroll = 11;	/* Number of lines scrolled by 'd' */int		fold_opt = 1;	/* Fold long lines */int		stop_opt = 1;	/* Stop after form feeds */int		ssp_opt = 0;	/* Suppress white space */int		ul_opt = 1;	/* Underline as best we can */int		promptlen;int		Currline;	/* Line we are currently at */int		startup = 1;int		firstf = 1;int		notell = 1;int		docrterase = 0;int		docrtkill = 0;int		bad_so;	/* True if overwriting does not turn off standout */int		inwait, Pause, errors;int		within;	/* true if we are within a file,			false if we are between files */int		hard, dumb, noscroll, hardtabs, clreol, eatnl;int		catch_susp;	/* We should catch the SIGTSTP signal */char		**fnames;	/* The list of file names */int		nfiles;		/* Number of files left to process */char		*shell;		/* The name of the shell to use */int		shellp;		/* A previous shell command exists */sigjmp_buf	restore;char		Line[LINSIZ+2];	/* Line buffer */int		Lpp = 24;	/* lines per page */char		*Clear;		/* clear screen */char		*eraseln;	/* erase line */char		*Senter, *Sexit;/* enter and exit standout mode */char		*ULenter, *ULexit;	/* enter and exit underline mode */char		*chUL;		/* underline character */char		*chBS;		/* backspace character */char		*Home;		/* go to home */char		*cursorm;	/* cursor movement */char		cursorhome[40];	/* contains cursor movement to home */char		*EodClr;	/* clear rest of screen */int		Mcol = 80;	/* number of columns */int		Wrap = 1;	/* set if automargins */int		soglitch;	/* terminal has standout mode glitch */int		ulglitch;	/* terminal has underline mode glitch */int		pstate = 0;	/* current UL state */static int	magic(FILE *, char *);struct {    long chrctr, line;} context, screen_start;extern char	PC;		/* pad character */#ifndef HAVE_termcap#define USE_CURSES#endif#ifdef USE_CURSES#if NCH#include <ncurses.h>#else#include <curses.h>#endif#include <term.h>			/* include after <curses.h> */static voidmy_putstring(char *s) {	tputs (s, 1, putchar);		/* putp(s); */}static voidmy_setupterm(const char *term, int fildes, int *errret) {     setupterm(term, fildes, errret);}static intmy_tgetnum(char *s, char *ss) {     return tigetnum(ss);}static intmy_tgetflag(char *s, char *ss) {     return tigetflag(ss);}static char *my_tgetstr(char *s, char *ss) {     return tigetstr(ss);}static char *my_tgoto(const char *cap, int col, int row) {     return tparm(cap, col, row);}#else /* no CURSES */#include <termcap.h>char termbuffer[4096];char tcbuffer[4096];char *strbuf = termbuffer;static voidmy_putstring(char *s) {     tputs (s, 1, putchar);}static voidmy_setupterm(const char *term, int fildes, int *errret) {     *errret = tgetent(tcbuffer, term);}static intmy_tgetnum(char *s, char *ss) {     return tgetnum(s);}static intmy_tgetflag(char *s, char *ss) {     return tgetflag(s);}static char *my_tgetstr(char *s, char *ss) {     return tgetstr(s, &strbuf);}static char *my_tgoto(const char *cap, int col, int row) {     return tgoto(cap, col, row);}#endif /* USE_CURSES */static voididummy(int *kk) {}static voidFdummy(FILE **ff) {}static voidusage(char *s) {	char *p = strrchr(s, '/');	fprintf(stderr,		_("usage: %s [-dflpcsu] [+linenum | +/pattern] name1 name2 ...\n"),		p ? p + 1 : s);}int main(int argc, char **argv) {    FILE	*f;    char	*s;    char	*p;    int		ch;    int		left;    int		prnames = 0;    int		initopt = 0;    int		srchopt = 0;    int		clearit = 0;    int		initline = 0;    char	initbuf[80];    setlocale(LC_ALL, "");    bindtextdomain(PACKAGE, LOCALEDIR);    textdomain(PACKAGE);        /* avoid gcc complaints about register variables that       may be clobbered by a longjmp, by forcing our variables here       to be non-register */    Fdummy(&f); idummy(&left); idummy(&prnames);    idummy(&initopt); idummy(&srchopt); idummy(&initline);    nfiles = argc;    fnames = argv;    setlocale(LC_ALL, "");    initterm ();    nscroll = Lpp/2 - 1;    if (nscroll <= 0)	nscroll = 1;    if((s = getenv("MORE")) != NULL) argscan(s,argv[0]);    while (--nfiles > 0) {	if ((ch = (*++fnames)[0]) == '-') {	    argscan(*fnames+1,argv[0]);	}	else if (ch == '+') {	    s = *fnames;	    if (*++s == '/') {		srchopt++;		for (++s, p = initbuf; p < initbuf + 79 && *s != '\0';)		    *p++ = *s++;		*p = '\0';	    }	    else {		initopt++;		for (initline = 0; *s != '\0'; s++)		    if (isdigit (*s))			initline = initline*10 + *s -'0';		--initline;	    }	}	else break;    }    /* allow clreol only if Home and eraseln and EodClr strings are     *  defined, and in that case, make sure we are in noscroll mode     */    if(clreol)    {        if((Home == NULL) || (*Home == '\0') ||	   (eraseln == NULL) || (*eraseln == '\0') ||           (EodClr == NULL) || (*EodClr == '\0') )	      clreol = 0;	else noscroll = 1;    }    if (dlines == 0)	dlines = Lpp - (noscroll ? 1 : 2);    left = dlines;    if (nfiles > 1)	prnames++;    if (!no_intty && nfiles == 0) {	usage(argv[0]);	exit(1);    }    else	f = stdin;    if (!no_tty) {	signal(SIGQUIT, onquit);	signal(SIGINT, end_it);#ifdef SIGWINCH	signal(SIGWINCH, chgwinsz);#endif	if (signal (SIGTSTP, SIG_IGN) == SIG_DFL) {	    signal(SIGTSTP, onsusp);	    catch_susp++;	}	stty (fileno(stderr), &otty);    }    if (no_intty) {	if (no_tty)	    copy_file (stdin);	else {	    if ((ch = Getc (f)) == '\f')		doclear();	    else {		Ungetc (ch, f);		if (noscroll && (ch != EOF)) {		    if (clreol)			home ();		    else			doclear ();		}	    }	    if (srchopt)	    {		search (initbuf, stdin, 1);		if (noscroll)		    left--;	    }	    else if (initopt)		skiplns (initline, stdin);	    screen (stdin, left);	}	no_intty = 0;	prnames++;	firstf = 0;    }    while (fnum < nfiles) {	if ((f = checkf (fnames[fnum], &clearit)) != NULL) {	    context.line = context.chrctr = 0;	    Currline = 0;	    if (firstf) sigsetjmp (restore, 1);	    if (firstf) {		firstf = 0;		if (srchopt) {		    search (initbuf, f, 1);		    if (noscroll)			left--;		}		else if (initopt)		    skiplns (initline, f);	    }	    else if (fnum < nfiles && !no_tty) {		sigsetjmp (restore, 1);		left = command (fnames[fnum], f);	    }	    if (left != 0) {		if ((noscroll || clearit) && (file_size != LONG_MAX)) {		    if (clreol)			home ();		    else			doclear ();		}		if (prnames) {		    if (bad_so)			erasep (0);		    if (clreol)			cleareol ();		    putsout("::::::::::::::");		    if (promptlen > 14)			erasep (14);		    putchar('\n');		    if(clreol) cleareol();		    puts(fnames[fnum]);		    if(clreol) cleareol();		    puts("::::::::::::::");		    if (left > Lpp - 4)			left = Lpp - 4;		}		if (no_tty)		    copy_file (f);		else {		    within++;		    screen(f, left);		    within = 0;		}	    }	    sigsetjmp (restore, 1);	    fflush(stdout);	    fclose(f);	    screen_start.line = screen_start.chrctr = 0L;	    context.line = context.chrctr = 0L;	}	fnum++;	firstf = 0;    }    reset_tty ();    exit(0);}void argscan(char *s, char *argv0) {	int seen_num = 0;	while (*s != '\0') {		switch (*s) {		  case '0': case '1': case '2':		  case '3': case '4': case '5':		  case '6': case '7': case '8':		  case '9':			if (!seen_num) {				dlines = 0;				seen_num = 1;			}			dlines = dlines*10 + *s - '0';			break;		  case 'd':			dum_opt = 1;			break;		  case 'l':			stop_opt = 0;			break;		  case 'f':			fold_opt = 0;			break;		  case 'p':			noscroll++;			break;		  case 'c':			clreol++;			break;		  case 's':			ssp_opt = 1;			break;		  case 'u':			ul_opt = 0;			break;		  case '-': case ' ': case '\t':			break;		  default:			fprintf(stderr,				_("%s: unknown option \"-%c\"\n"), argv0, *s);			usage(argv0);			exit(1);			break;		}		s++;	}}/*** Check whether the file named by fs is an ASCII file which the user may** access.  If it is, return the opened file. Otherwise return NULL.*/FILE *checkf (fs, clearfirst)	register char *fs;	int *clearfirst;{	struct stat stbuf;	register FILE *f;	int c;	if (stat (fs, &stbuf) == -1) {		(void)fflush(stdout);		if (clreol)			cleareol ();		perror(fs);		return((FILE *)NULL);	}	if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {		printf(_("\n*** %s: directory ***\n\n"), fs);		return((FILE *)NULL);	}	if ((f = Fopen(fs, "r")) == NULL) {		(void)fflush(stdout);		perror(fs);		return((FILE *)NULL);	}	if (magic(f, fs))		return((FILE *)NULL);	c = Getc(f);	*clearfirst = (c == '\f');	Ungetc (c, f);	if ((file_size = stbuf.st_size) == 0)		file_size = LONG_MAX;	return(f);}/* * magic -- *	check for file magic numbers.  This code would best be shared with *	the file(1) program or, perhaps, more should not try and be so smart? */static intmagic(f, fs)	FILE *f;	char *fs;{	char twobytes[2];	/* don't try to look ahead if the input is unseekable */	if (fseek(f, 0L, SEEK_SET))		return(0);	if (fread(twobytes, 2, 1, f) == 1) {		switch(twobytes[0] + (twobytes[1]<<8)) {		case OMAGIC:	/* 0407 */		case NMAGIC:	/* 0410 */		case ZMAGIC:	/* 0413 */		case 0405:		case 0411:		case 0177545:		case 0x457f:		/* simple ELF detection */			printf(_("\n******** %s: Not a text file ********\n\n"), fs);			(void)fclose(f);			return(1);		}	}	(void)fseek(f, 0L, SEEK_SET);		/* rewind() not necessary */	return(0);}/*** Print out the contents of the file f, one screenful at a time.*/#define STOP -10void screen (register FILE *f, register int num_lines){    register int c;    register int nchars;    int length;			/* length of current line */    static int prev_len = 1;	/* length of previous line */    for (;;) {	while (num_lines > 0 && !Pause) {	    if ((nchars = get_line (f, &length)) == EOF)	    {		if (clreol)		    clreos();		return;	    }	    if (ssp_opt && length == 0 && prev_len == 0)		continue;	    prev_len = length;	    if (bad_so || ((Senter && *Senter == ' ') && (promptlen > 0)))		erasep (0);	    /* must clear before drawing line since tabs on some terminals	     * do not erase what they tab over.	     */	    if (clreol)		cleareol ();	    prbuf (Line, length);	    if (nchars < promptlen)		erasep (nchars);	/* erasep () sets promptlen to 0 */	    else promptlen = 0;	    /* is this needed?	     * if (clreol)	     *	cleareol();	* must clear again in case we wrapped *	     */	    if (nchars < Mcol || !fold_opt)		prbuf("\n", 1);	/* will turn off UL if necessary */	    if (nchars == STOP)		break;	    num_lines--;	}	if (pstate) {		my_putstring (ULexit);		pstate = 0;	}	fflush(stdout);	if ((c = Getc(f)) == EOF)	{	    if (clreol)		clreos ();	    return;	}	if (Pause && clreol)	    clreos ();	Ungetc (c, f);	sigsetjmp (restore, 1);	Pause = 0; startup = 0;	if ((num_lines = command (NULL, f)) == 0)	    return;	if (hard && promptlen > 0)		erasep (0);	if (noscroll && num_lines >= dlines)	{	    if (clreol)		home();	    else		doclear ();	}	screen_start.line = Currline;	screen_start.chrctr = Ftell (f);    }}/*** Come here if a quit signal is received*/void onquit(int dummy) {    signal(SIGQUIT, SIG_IGN);    if (!inwait) {	putchar ('\n');	if (!startup) {	    signal(SIGQUIT, onquit);	    siglongjmp (restore, 1);	}	else	    Pause++;    }    else if (!dum_opt && notell) {	promptlen += fprintf(stderr, _("[Use q or Q to quit]"));	notell = 0;    }    signal(SIGQUIT, onquit);}/*** Come here if a signal for a window size change is received*/#ifdef SIGWINCHvoid chgwinsz(int dummy) {    struct winsize win;    (void) signal(SIGWINCH, SIG_IGN);    if (ioctl(fileno(stdout), TIOCGWINSZ, &win) != -1) {	if (win.ws_row != 0) {	    Lpp = win.ws_row;	    nscroll = Lpp/2 - 1;	    if (nscroll <= 0)		nscroll = 1;	    dlines = Lpp - (noscroll ? 1 : 2);	}	if (win.ws_col != 0)	    Mcol = win.ws_col;    }    (void) signal(SIGWINCH, chgwinsz);}#endif/*** Clean up terminal state and exit. Also come here if interrupt signal received*/void end_it (int dummy) {    reset_tty ();    if (clreol) {	putchar ('\r');	clreos ();	fflush (stdout);    }    else if (!clreol && (promptlen > 0)) {	kill_line ();	fflush (stdout);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -