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

📄 pg.c

📁 Util-linux 软件包包含许多工具。其中比较重要的是加载、卸载、格式化、分区和管理硬盘驱动器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * pg  - A clone of the System V CRT paging utility. * *	Copyright (c) 2000-2001 Gunnar Ritter. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. [deleted] * 4. Neither the name of Gunnar Ritter nor the names of his contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY GUNNAR RITTER AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL GUNNAR RITTER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *//* Sccsid @(#)pg.c 1.44 (gritter) 2/8/02 - modified for util-linux *//* * #define _XOPEN_SOURCE  500L * * Adding this define gives us the correct prototypes for fseeko, ftello, * but (for some glibc versions) conflicting prototype for wcwidth. * So, avoid defining _XOPEN_SOURCE, and give prototypes for fseeko, ftello * by hand. */#include <sys/types.h>#include <sys/wait.h>#include <sys/stat.h>#ifndef	TIOCGWINSZ#include <sys/ioctl.h>#endif#include <sys/termios.h>#include <fcntl.h>#include <regex.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <limits.h>#include <ctype.h>#include <errno.h>#include <unistd.h>#include <signal.h>#include <setjmp.h>#include <locale.h>#include <nl_types.h>#include <libgen.h>#if NCH#include <ncurses.h>#else#include <curses.h>#endif#include <term.h>#include "nls.h"#include "widechar.h"#include "../defines.h"		/* for HAVE_fseeko */#define	READBUF		LINE_MAX	/* size of input buffer */#define CMDBUF		255		/* size of command buffer */#define	TABSIZE		8		/* spaces consumed by tab character *//* * Avoid the message "`var' might be clobbered by `longjmp' or `vfork'" */#define	CLOBBGRD(a)	(void)(&(a));#define	cuc(c)		((c) & 0377)enum { FORWARD = 1, BACKWARD = 2 };	/* search direction */enum { TOP, MIDDLE, BOTTOM };		/* position of matching line *//* * States for syntax-aware command line editor. */enum {	COUNT,	SIGN,	CMD_FIN,	SEARCH,	SEARCH_FIN,	ADDON_FIN,	STRING,	INVALID};/* * Current command */struct {	char cmdline[CMDBUF];	size_t cmdlen;	int count;	int key;	char pattern[CMDBUF];	char addon;} cmd;/* * Position of file arguments on argv[] to main() */struct {	int first;	int current;	int last;} files;void		(*oldint)(int);		/* old SIGINT handler */void		(*oldquit)(int);	/* old SIGQUIT handler */void		(*oldterm)(int);	/* old SIGTERM handler */char		*tty;			/* result of ttyname(1) */char		*progname;		/* program name */unsigned	ontty;			/* whether running on tty device */unsigned	exitstatus;		/* exit status */int		pagelen = 23;		/* lines on a single screen page */int		ttycols = 79;		/* screen columns (starting at 0) */struct termios	otio;			/* old termios settings */int		tinfostat = -1;		/* terminfo routines initialized */int		searchdisplay = TOP;	/* matching line position */regex_t		re;			/* regular expression to search for */int		remembered;		/* have a remembered search string */int		cflag;			/* clear screen before each page */int		eflag;			/* suppress (EOF) */int		fflag;			/* do not split lines */int		nflag;			/* no newline for commands required */int		rflag;			/* "restricted" pg */int		sflag;			/* use standout mode */char		*pstring = ":";		/* prompt string */char		*searchfor;		/* search pattern from argv[] */int		havepagelen;		/* page length is manually defined */long		startline;		/* start line from argv[] */int		nextfile = 1;		/* files to advance */jmp_buf		jmpenv;			/* jump from signal handlers */int		canjump;		/* jmpenv is valid */wchar_t		wbuf[READBUF];		/* used in several widechar routines */const char *copyright ="@(#)pg 1.44 2/8/02. Copyright (c) 2000-2001 Gunnar Ritter. ";const char *helpscreen = "All rights reserved.\n\-------------------------------------------------------\n\  h                       this screen\n\  q or Q                  quit program\n\  <newline>               next page\n\  f                       skip a page forward\n\  d or ^D                 next halfpage\n\  l                       next line\n\  $                       last page\n\  /regex/                 search forward for regex\n\  ?regex? or ^regex^      search backward for regex\n\  . or ^L                 redraw screen\n\  w or z                  set page size and go to next page\n\  s filename              save current file to filename\n\  !command                shell escape\n\  p                       go to previous file\n\  n                       go to next file\n\\n\Many commands accept preceding numbers, for example:\n\+1<newline> (next page); -1<newline> (previous page); 1<newline> (first page).\n\\n\See pg(1) for more information.\n\-------------------------------------------------------\n";#ifdef HAVE_fseeko#if defined (_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS) == 64  extern int fseeko64(FILE *f, off_t off, int whence);  extern off_t ftello64(FILE *f);  #define      my_fseeko       fseeko64  #define      my_ftello       ftello64#else  extern int fseeko(FILE *f, off_t off, int whence);  extern off_t ftello(FILE *f);  #define	my_fseeko	fseeko  #define	my_ftello	ftello#endif#else  static int my_fseeko(FILE *f, off_t off, int whence) {	return fseek(f, (long) off, whence);  }  static off_t my_ftello(FILE *f) {	return (off_t) ftell(f);  }#endif#ifdef USE_SIGSET	/* never defined *//* sigset and sigrelse are obsolete - use when POSIX stuff is unavailable */#define my_sigset	sigset#define my_sigrelse	sigrelse#elsestatic int my_sigrelse(int sig) {	sigset_t sigs;	if (sigemptyset(&sigs) || sigaddset(&sigs, sig))		return -1;	return sigprocmask(SIG_UNBLOCK, &sigs, NULL);}typedef void (*my_sighandler_t)(int);static my_sighandler_t my_sigset(int sig, my_sighandler_t disp) {	struct sigaction act, oact;	act.sa_handler = disp;	if (sigemptyset(&act.sa_mask))		return SIG_ERR;	act.sa_flags = 0;	if (sigaction(sig, &act, &oact))		return SIG_ERR;	if (my_sigrelse(sig))		return SIG_ERR;	return oact.sa_handler;}#endif/* * Quit pg. */static voidquit(int status){	exit(status < 0100 ? status : 077);}/* * Memory allocator including check. */static char *smalloc(size_t s){        char *m = (char *)malloc(s);        if (m == NULL) {                write(2, "Out of memory\n", 14);                quit(++exitstatus);        }        return m;}/* * Usage message and similar routines. */static voidusage(void){	fprintf(stderr, _("%s: Usage: %s [-number] [-p string] [-cefnrs] "			  "[+line] [+/pattern/] [files]\n"),			progname, progname);	quit(2);}static voidneedarg(char *s){	fprintf(stderr, _("%s: option requires an argument -- %s\n"),		progname, s);	usage();}static voidinvopt(char *s){	fprintf(stderr, _("%s: illegal option -- %s\n"), progname, s);	usage();}#ifdef ENABLE_WIDECHAR/* * A mbstowcs()-alike function that transparently handles invalid sequences. */static size_txmbstowcs(wchar_t *pwcs, const char *s, size_t nwcs){	size_t n = nwcs;	int c;	mbtowc(pwcs, NULL, MB_CUR_MAX);	while (*s && n) {		if ((c = mbtowc(pwcs, s, MB_CUR_MAX)) < 0) {			s++;			*pwcs = L'?';		} else			s += c;		pwcs++;		n--;	}	if (n)		*pwcs = L'\0';	mbtowc(pwcs, NULL, MB_CUR_MAX);	return nwcs - n;}#endif/* * Helper function for tputs(). */static intoutcap(int i){	char c = i;	return write(1, &c, 1);}/* * Write messages to terminal. */static voidmesg(char *message){	if (ontty == 0)		return;	if (*message != '\n' && sflag)		vidputs(A_STANDOUT, outcap);	write(1, message, strlen(message));	if (*message != '\n' && sflag)		vidputs(A_NORMAL, outcap);}/* * Get the window size. */static voidgetwinsize(void){	static int initialized, envlines, envcols, deflines, defcols;#ifdef	TIOCGWINSZ	struct winsize winsz;	int badioctl;#endif	char *p;	if (initialized == 0) {		if ((p = getenv("LINES")) != NULL && *p != '\0')			if ((envlines = atoi(p)) < 0)				envlines = 0;		if ((p = getenv("COLUMNS")) != NULL && *p != '\0')			if ((envcols = atoi(p)) < 0)				envcols = 0;		/* terminfo values. */		if (tinfostat != 1 || columns == 0)			defcols = 24;		else			defcols = columns;		if (tinfostat != 1 || lines == 0)			deflines = 80;		else			deflines = lines;		initialized = 1;	}#ifdef	TIOCGWINSZ	badioctl = ioctl(1, TIOCGWINSZ, &winsz);#endif	if (envcols)		ttycols = envcols - 1;#ifdef	TIOCGWINSZ	else if (!badioctl)		ttycols = winsz.ws_col - 1;#endif	else		ttycols = defcols - 1;	if (havepagelen == 0) {		if (envlines)			pagelen = envlines - 1;#ifdef	TIOCGWINSZ		else if (!badioctl)			pagelen = winsz.ws_row - 1;#endif		else			pagelen = deflines - 1;	}}/* * Message if skipping parts of files. */static voidskip(int direction){	if (direction > 0)		mesg(_("...skipping forward\n"));	else		mesg(_("...skipping backward\n"));}/* * Signal handler while reading from input file. */static voidsighandler(int signum){	if (canjump && (signum == SIGINT || signum == SIGQUIT))		longjmp(jmpenv, signum);	tcsetattr(1, TCSADRAIN, &otio);	quit(exitstatus);}/* * Check whether the requested file was specified on the command line. */static intcheckf(void){	if (files.current + nextfile >= files.last) {		mesg(_("No next file"));		return 1;	}	if (files.current + nextfile < files.first) {		mesg(_("No previous file"));		return 1;	}	return 0;}#ifdef ENABLE_WIDECHAR/* * Return the last character that will fit on the line at col columns * in case MB_CUR_MAX > 1. */static char *endline_for_mb(unsigned col, char *s){	unsigned pos = 0;	wchar_t *p = wbuf;	wchar_t *end;	size_t wl;	char *t = s;	if ((wl = xmbstowcs(wbuf, t, sizeof wbuf - 1)) == (size_t)-1)		return s + 1;	wbuf[wl] = L'\0';	while (*p != L'\0') {		switch (*p) {			/*			 * Cursor left.			 */		case L'\b':			if (pos > 0)				pos--;			break;			/*			 * No cursor movement.			 */		case L'\a':			break;			/*			 * Special.			 */		case L'\r':			pos = 0;			break;		case L'\n':			end = p + 1;			goto ended;			/*			 * Cursor right.			 */		case L'\t':			pos += TABSIZE - (pos % TABSIZE);			break;		default:			pos += wcwidth(*p);		}		if (pos > col) {			if (*p == L'\t')				p++;			else if (pos > col + 1)				/*				 * wcwidth() found a character that				 * has multiple columns. What happens				 * now? Assume the terminal will print				 * the entire character onto the next				 * row.				 */				p--;			if (*++p == L'\n')				p++;			end = p;			goto ended;		}		p++;	}	end = p; ended:	*end = L'\0';	p = wbuf;	if ((pos = wcstombs(NULL, p, READBUF)) == -1)		return s + 1;	return s + pos;}#endif/* * Return the last character that will fit on the line at col columns. */static char *endline(unsigned col, char *s){	unsigned pos = 0;	char *t = s;#ifdef ENABLE_WIDECHAR	if (MB_CUR_MAX > 1)		return endline_for_mb(col, s);#endif	while (*s != '\0') {		switch (*s) {			/*			 * Cursor left.			 */		case '\b':			if (pos > 0)				pos--;			break;			/*			 * No cursor movement.			 */		case '\a':			break;			/*			 * Special.			 */		case '\r':			pos = 0;			break;		case '\n':			t = s + 1;			goto cend;			/*			 * Cursor right.			 */		case '\t':			pos += TABSIZE - (pos % TABSIZE);			break;		default:			pos++;		}		if (pos > col) {			if (*s == '\t')				s++;			if (*++s == '\n')				s++;			t = s;			goto cend;		}		s++;	}	t = s; cend:	return t;}/* * Clear the current line on the terminal's screen. */static voidcline(void){	char *buf = (char *)smalloc(ttycols + 2);	memset(buf, ' ', ttycols + 2);	buf[0] = '\r';	buf[ttycols + 1] = '\r';	write(1, buf, ttycols + 2);	free(buf);}/* * Evaluate a command character's semantics. */static intgetstate(int c){	switch (c) {	case '1': case '2': case '3': case '4': case '5':	case '6': case '7': case '8': case '9': case '0':	case '\0':		return COUNT;	case '-': case '+':		return SIGN;	case 'l': case 'd': case '\004': case 'f': case 'z':	case '.': case '\014': case '$': case 'n': case 'p':	case 'w': case 'h': case 'q': case 'Q':		return CMD_FIN;	case '/': case '?': case '^':		return SEARCH;

⌨️ 快捷键说明

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