bin/60510: [PATCH]
Elmar Bartel
elmar at devsoft.com
Mon Dec 22 07:20:13 PST 2003
>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 at 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 at flash.net>
.br
Send bug reports or comments to the above address or to bug-less at gnu.org.
+
+.SH HACKED
+by Elmar Bartel (elmar at leo.org) based on
+an earlier hack of Kai-Uwe Rommel (rommel at 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;
+}
More information about the freebsd-bugs
mailing list