From owner-freebsd-bugs@FreeBSD.ORG Sat Feb 16 11:50:02 2008 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3456816A421 for ; Sat, 16 Feb 2008 11:50:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 2A91613C467 for ; Sat, 16 Feb 2008 11:50:02 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.2/8.14.2) with ESMTP id m1GBo1iq000528 for ; Sat, 16 Feb 2008 11:50:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.2/8.14.1/Submit) id m1GBo1NY000527; Sat, 16 Feb 2008 11:50:01 GMT (envelope-from gnats) Resent-Date: Sat, 16 Feb 2008 11:50:01 GMT Resent-Message-Id: <200802161150.m1GBo1NY000527@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Ighighi Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7F41316A418 for ; Sat, 16 Feb 2008 11:45:26 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id 848EE13C457 for ; Sat, 16 Feb 2008 11:45:26 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.2/8.14.2) with ESMTP id m1GBh35Z003779 for ; Sat, 16 Feb 2008 11:43:03 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.2/8.14.1/Submit) id m1GBh2id003778; Sat, 16 Feb 2008 11:43:02 GMT (envelope-from nobody) Message-Id: <200802161143.m1GBh2id003778@www.freebsd.org> Date: Sat, 16 Feb 2008 11:43:02 GMT From: Ighighi To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: bin/120730: [patch] man(1): support for running on local files, also for bzip2(1) compressed manpages X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Feb 2008 11:50:02 -0000 >Number: 120730 >Category: bin >Synopsis: [patch] man(1): support for running on local files, also for bzip2(1) compressed manpages >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: Sat Feb 16 11:50:01 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Ighighi >Release: 6.3-STABLE >Organization: >Environment: FreeBSD orion.nebula.mil 6.3-STABLE FreeBSD 6.3-STABLE #0: Fri Feb 15 12:35:41 VET 2008 root@orion:/usr/obj/usr/src/sys/CUSTOM i386 >Description: This is a merge from 2 previous PR's: http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/116702 http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/103007 I combined them both so to have an unique diff in case one of them is merged, to keep the same line numbers. Also, they're now easier to implement since FreeBSD 6.2 / 7 because BSD gunzip(1) supports bzip2(1) archives as well. About running man(1) on local files: it has long been in the TODO file and I think it's a feature that comes in handy to both developers and users alike when creating and browsing manpages... The semantics are simple: if the argument contains a directory separator ('/'), then open that file and forget about $MANPATH. To open a manpage in the current directory, all the user has to do is use "./". If this patch is eventually merged, I could add the relevant notes to man(1) myself. This patch to man(1) adds support support for bzip2-compressed manpages. Useful in multi-boot/custom environments, letting you read those Linux manpages compressed with bzip2. >How-To-Repeat: >Fix: Patch attached with submission follows: --- src/gnu/usr.bin/man/lib/util.c.orig 1999-05-13 11:59:27.000000000 -0400 +++ src/gnu/usr.bin/man/lib/util.c 2008-02-14 05:58:49.944858771 -0430 @@ -120,6 +120,24 @@ is_directory (path) } /* + * Is path a regular file? + */ +int +is_file (path) + char *path; +{ + struct stat sb; + register int status; + + status = stat (path, &sb); + + if (status != 0) + return -1; + + return ((sb.st_mode & S_IFREG) == S_IFREG); +} + +/* * Attempt a system () call. Return 1 for success and 0 for failure * (handy for counting successes :-). */ --- src/gnu/usr.bin/man/man/man.c.orig 2007-09-27 23:53:06.000000000 -0400 +++ src/gnu/usr.bin/man/man/man.c 2008-02-14 05:59:18.027587722 -0430 @@ -29,6 +29,7 @@ static const char rcsid[] = #ifdef __FreeBSD__ #include #include +#include #endif #include #include @@ -69,6 +70,7 @@ extern char *sprintf (); extern char **glob_filename (); extern int is_newer (); extern int is_directory (); +extern int is_file (); extern int do_system_command (); char *prognam; @@ -85,6 +87,7 @@ static int apropos; static int whatis; static int findall; static int print_where; +static char *ultimate_source (); #ifdef __FreeBSD__ static char *locale, *locale_opts, *locale_nroff, *locale_codeset; @@ -201,10 +204,17 @@ main (argc, argv) } else { - status = man (nextarg); + if (strchr(nextarg, '/') != NULL && is_file(nextarg) == 1) { + char *dir = dirname(nextarg); + char *srcfile = ultimate_source(nextarg, dir); + format_and_display(dirname(srcfile), srcfile, NULL); + } + else { + status = man (nextarg); - if (status == 0) - gripe_not_found (nextarg, longsec); + if (status == 0) + gripe_not_found (nextarg, longsec); + } } } return (status==0); /* status==1 --> exit(0), @@ -807,7 +817,7 @@ get_expander (file) return YCAT; #endif /* YCAT */ #ifdef ZCAT - if (*end == 'Z' || !strcmp(end, "gz")) + if (*end == 'Z' || !strcmp(end, "gz") || !strcmp(end, "bz2")) return ZCAT; #endif /* ZCAT */ return NULL; @@ -1391,14 +1401,21 @@ format_and_display (path, man_file, cat_ if (access (man_file, R_OK) != 0) return 0; - if (troff) + if (troff || cat_file == NULL) { roff_command = make_roff_command (man_file); if (roff_command == NULL) return 0; - else + else if (cat_file != NULL) snprintf (command, sizeof(command), "(cd %s ; %s)", path, roff_command); - + else + { + if (strchr(man_file, '/') != NULL) + snprintf (command, sizeof(command), "%s | %s", roff_command, pager); + else + snprintf (command, sizeof(command), "(cd %s ; %s | %s)", path, + roff_command, pager); + } found = do_system_command (command); } else --- src/gnu/usr.bin/man/TODO.orig 1993-07-07 19:06:59.000000000 -0400 +++ src/gnu/usr.bin/man/TODO 2008-02-14 05:58:49.950858975 -0430 @@ -105,8 +105,6 @@ XX I've been using your man(1) package file names used by Motif. Maybe there's a better way to handle this? -15. Add ability to run man on a local file - 16. Handle per-tree tmac macros XX Allow user-definable section search order via -S or $MANSECT. >Release-Note: >Audit-Trail: >Unformatted: