From 4b5bd45caa1ddd157e54197578b0b4f6a17d05bb Mon Sep 17 00:00:00 2001 From: Neil Stockbridge Date: Wed, 18 May 2011 16:15:03 +1200 Subject: [PATCH] The source files are now under revision control --- Makefile | 9 ++++ src/Makefile | 34 +++++++++++++++ src/main.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 Makefile create mode 100644 src/Makefile create mode 100644 src/main.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..505e758 --- /dev/null +++ b/Makefile @@ -0,0 +1,9 @@ + +#.SILENT: + +all: + $(MAKE) -C src/ + +clean: + $(MAKE) -C src/ clean + diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..8f52ed5 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,34 @@ + +PROJECT = man +#DEBUG = -g + +CC = gcc + +ifndef CFLAGS +CFLAGS = -Os -Wall $(DEBUG) -DDEBUG +endif + +ifndef STRIP +STRIP=strip +endif + +PARTS = main.o + +.c.o: + $(RM) $@ +# $(CC) -MM $(CFLAGS) $*.c + $(CC) -c $(CFLAGS) $*.c + +.SILENT: + +# Targets... + +all: $(PROJECT) + +$(PROJECT): $(PARTS) + $(CC) $(LDFLAGS) $(LIBS) $(DEBUG) -o $(PROJECT) $(PARTS) + $(STRIP) $(PROJECT) + +clean: + rm -f *.o $(PROJECT) + diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..feec08c --- /dev/null +++ b/src/main.c @@ -0,0 +1,121 @@ + +#include // for fprintf +#include // for getenv +#include // for access + + +typedef int bool; +#define FALSE 0 +#define TRUE 1 + +#define LENGTH_OF(a) ( sizeof(a) / sizeof(a[0]) ) + + +#define ANY_SECTION 0 + + +// This is for different forms that man page file names can take such as: +// + time.2 +// + time.2.gz +// +typedef struct +{ + char *name_template; + char *emitter; +} +Form; + + +int main( int argc, char **argv) +{ + // Parse the command-line + if ( argc < 2 || 3 < argc) + { + fprintf( stderr, "Use: %s [section] page\n", argv[0]); + return 1; + } + + int section; + char *page; + + if ( 2 == argc) + { + page = argv[ 1]; + section = ANY_SECTION; + } + else { + section = atoi( argv[1]); + page = argv[ 2]; + } + + // Parse the MANPATH + char *man_path_s = getenv("MANPATH"); + if ( ! man_path_s) + man_path_s = "/usr/share/man"; + #define MAX_MAN_PATH_ITEMS 32 + char *man_path_item[ MAX_MAN_PATH_ITEMS]; + int man_path_items = 0; + // Split the colon separated MANPATH in to discrete strings + char *cursor = man_path_s; + bool fresh_item = TRUE; + while( *cursor != '\0') + { + if ( fresh_item) + { + if ( man_path_items < MAX_MAN_PATH_ITEMS) + man_path_item[ man_path_items++] = cursor; + fresh_item = FALSE; + } + if ( ':' == *cursor) + { + *cursor = '\0'; + fresh_item = TRUE; + } + cursor += 1; + } + + // Go through every item on MANPATH + int mpi; + for ( mpi = 0; mpi < man_path_items; ++ mpi) + { + char *man_dir = man_path_item[ mpi]; + + // Go through sections 1..9 or just the specified section + int min_s = ANY_SECTION == section ? 1 : section; + int max_s = ANY_SECTION == section ? 9 : section; + int s; + for ( s = min_s; s <= max_s; ++ s) + { + // If the named man page exists in this (MANPATH item, section) then + // display it + char path_to_file[ 256]; + Form form[] = { + {"%s/man%i/%s.%i", emitter:"cat"}, + {"%s/man%i/%s.%i.gz", emitter:"zcat"}, + }; + char cmd[ 512] = {'\0'}; + int i; + for ( i = 0; i < LENGTH_OF(form); ++ i) + { + Form f = form[ i]; + + snprintf( path_to_file, sizeof(path_to_file), f.name_template, man_dir, s, page, s); + if ( ! access( path_to_file, R_OK)) + { + snprintf( cmd, sizeof(cmd), "%s %s | mandoc | less", f.emitter, path_to_file); + break; + } + } + + if ( cmd[0] != '\0') + { + system( cmd); + return 0; + } + } + } + + fprintf( stderr, "No manual entry for %s\n", page); + return 1; +} +