Date: Mon, 22 Dec 2003 16:15:30 +0100 (CET) From: Elmar Bartel <elmar@devsoft.com> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/60510: [PATCH] Message-ID: <20031222151530.414A2D77@hermes.devsoft.com> Resent-Message-ID: <200312221520.hBMFK8O3050683@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 60510 >Category: bin >Synopsis: [PATCH] >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Mon Dec 22 07:20:08 PST 2003 >Closed-Date: >Last-Modified: >Originator: Elmar Bartel >Release: FreeBSD 4.9-RELEASE i386 >Organization: leo.org >Environment: System: FreeBSD hermes.devsoft.com 4.9-RELEASE FreeBSD 4.9-RELEASE #0: Mon Dec 22 10:37:10 CET 2003 elmar@eldev.devsoft.com:/usr/src/sys/compile/ELDEV i386 >Description: The current version of less cannot deal with compressed files. The author of less proposes to use INPUT PREPROCESSOR. But hhis mechanism requires a complete decompression of the file even when only the first few lines will be looked at. So, most of the time this is simply waste of time and space. Instead the attached patch add's little code to recognize the type of compression and to read the decompressed content from a pipe. Some time ago I offered this patch to the original author, but he refused to accept it refering to its INPUT PREPROCESSOR feature. The given patch just extends the features of less and should not have any further impact. I'am using it for a long time now and I think its worth while, so I offer it to your project. >How-To-Repeat: >Fix: >Release-Note: >Audit-Trail: >Unformatted: >Patch: --- usr.bin/less/Makefile.orig Mon Dec 22 15:51:50 2003 +++ usr.bin/less/Makefile Mon Dec 22 15:22:24 2003 @@ -4,7 +4,7 @@ SRCS= main.c screen.c brac.c ch.c charset.c cmdbuf.c command.c decode.c \ edit.c filename.c forwback.c help.c ifile.c input.c jump.c line.c \ linenum.c lsystem.c mark.c optfunc.c option.c opttbl.c os.c output.c \ - position.c prompt.c search.c signal.c tags.c ttyin.c version.c + position.c prompt.c search.c signal.c tags.c ttyin.c version.c zfile.c DPADD= ${LIBTERMCAP} LDADD= -ltermcap LINKS= ${BINDIR}/less ${BINDIR}/more --- contrib/less/Makefile.in.orig Fri Jun 30 03:03:07 2000 +++ contrib/less/Makefile.in Mon Dec 22 15:12:17 2003 @@ -42,7 +42,7 @@ help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \ lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \ output.${O} position.${O} prompt.${O} search.${O} signal.${O} \ - tags.${O} ttyin.${O} version.${O} @REGEX_O@ + tags.${O} ttyin.${O} version.${O} zfile.${O} @REGEX_O@ all: less lesskey lessecho --- contrib/less/ch.c.orig Fri Jun 30 03:03:07 2000 +++ contrib/less/ch.c Mon Dec 22 15:12:17 2003 @@ -740,6 +740,8 @@ */ if (!(ch_flags & (CH_POPENED|CH_HELPFILE))) close(ch_file); + if (ch_flags & CH_COMPRESSED) + Zclose(ch_file); ch_file = -1; } else keepstate = TRUE; --- contrib/less/edit.c.orig Fri Jun 30 03:03:08 2000 +++ contrib/less/edit.c Mon Dec 22 15:12:17 2003 @@ -307,6 +307,16 @@ */ reedit_ifile(was_curr_ifile); return (1); + } else if ((answer=IsZfile(open_filename)) >= 0) + { + if ((f=Zopen(open_filename, answer)) < 0) + { + parg.p_string = errno_message(filename); + error("%s", &parg); + free(parg.p_string); + return (1); + } + chflags |= CH_COMPRESSED; } else if ((f = open(open_filename, OPEN_READ)) < 0) { /* --- contrib/less/less.h.orig Wed Jul 19 11:24:26 2000 +++ contrib/less/less.h Mon Dec 22 15:12:17 2003 @@ -388,6 +388,7 @@ #define CH_KEEPOPEN 002 #define CH_POPENED 004 #define CH_HELPFILE 010 +#define CH_COMPRESSED 020 #define ch_zero() ((POSITION)0) --- contrib/less/less.nro.orig Wed Jul 19 11:24:26 2000 +++ contrib/less/less.nro Mon Dec 22 15:25:33 2003 @@ -34,6 +34,22 @@ so with large input files it starts up faster than text editors like .I vi (1). +This version of +.I less +automagically detectets if a file (not stdin) is compressed via +.I bzip2 +(1), +.I gzip +(1), +.I compress +(1), +or +.I pack +(1) +and decompresses it before presenting the +contents of the file. This feature is implemented independent of the +.BR "INPUT PREPROCESSOR" s. +to conserve the fast startup even for compressed files. .I Less uses termcap (or terminfo on some systems), so it can run on a variety of terminals. @@ -1512,4 +1528,9 @@ Mark Nudelman <marknu@flash.net> .br Send bug reports or comments to the above address or to bug-less@gnu.org. + +.SH HACKED +by Elmar Bartel (elmar@leo.org) based on +an earlier hack of Kai-Uwe Rommel (rommel@leo.org)) +for less-177, to automatically detect compressed files. --- contrib/less/zfile.c.orig Mon Dec 22 15:12:17 2003 +++ contrib/less/zfile.c Mon Dec 22 15:12:17 2003 @@ -0,0 +1,83 @@ +#include <stdio.h> +#include <fcntl.h> +#include <signal.h> + +extern int errno; + +typedef struct { + unsigned char magic[2]; + char *cmd; + char *opt; +} CompressMethod; +static CompressMethod zTable[] = { + 0x1f, 0x9d, "compress", "-dc", + 0x1f, 0x1e, "gunzip", NULL, /* this is old packed Unix-Format, but + * pcat doesn't know stdin ... + * ... but gunzip does + */ + 0x1f, 0x8b, "gunzip", NULL, /* this is gzip itself */ + 0x42, 0x5a, "bzip2", "-d" /* this is bzip2 */ +}; +#define MethodCnt sizeof(zTable)/sizeof(CompressMethod) +static int pid[64]= { 0 }; + +int IsZfile(name) char *name; +{ + int Method, res, file; + unsigned char magic[2]; + + file = open(name, O_RDONLY); + res = read(file, magic, 2); + close(file); + if (res != 2) + return -1; + + for (Method=0; Method < MethodCnt; Method++) + if (zTable[Method].magic[0] == magic[0] && + zTable[Method].magic[1] == magic[1]) { + return Method; + } + return -1; +} + +int Zopen(open_file, Method) char *open_file; int Method; { + int p, ph[2], file; + + if (Method < 0 || Method >= MethodCnt) + return -1; + + if (pipe(ph)) + return -1; + + if ((p = fork()) == -1) + return -1; + + if (p == 0) { + if ((file = open(open_file, O_RDONLY)) == -1) + exit(1); + dup2(file, 0); + dup2(ph[1], 1); + dup2(ph[1], 2); + close(ph[1]); + close(ph[0]); + close(file); + if (execlp(zTable[Method].cmd, zTable[Method].cmd, + zTable[Method].opt, NULL) == -1) { + fprintf(stderr, + "cannot exec decompression command \"%s\": %s", + zTable[Method].cmd, strerror(errno)); + exit(1); + } + } + else + close(ph[1]); + pid[ph[0]] = p; + return ph[0]; +} + +void Zclose(handle) int handle; { + close(handle); + kill(pid[handle], SIGPIPE); + waitpid(pid[handle], NULL, 0); + return; +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20031222151530.414A2D77>