Root/src/main.c

1
2#include <stdio.h> // for fprintf
3#include <stdlib.h> // for getenv
4#include <unistd.h> // for access
5
6
7typedef int bool;
8#define FALSE 0
9#define TRUE 1
10
11#define LENGTH_OF(a) ( sizeof(a) / sizeof(a[0]) )
12
13
14#define ANY_SECTION 0
15
16
17// This is for different forms that man page file names can take such as:
18// + time.2
19// + time.2.gz
20//
21typedef struct
22{
23  char *name_template;
24  char *emitter;
25}
26Form;
27
28
29int main( int argc, char **argv)
30{
31  // Parse the command-line
32  if ( argc < 2 || 3 < argc)
33  {
34    fprintf( stderr, "Use: %s [section] page\n", argv[0]);
35    return 1;
36  }
37
38  int section;
39  char *page;
40
41  if ( 2 == argc)
42  {
43    page = argv[ 1];
44    section = ANY_SECTION;
45  }
46  else {
47    section = atoi( argv[1]);
48    page = argv[ 2];
49  }
50
51  // Parse the MANPATH
52  char *man_path_s = getenv("MANPATH");
53  if ( ! man_path_s)
54    man_path_s = "/usr/share/man";
55  #define MAX_MAN_PATH_ITEMS 32
56  char *man_path_item[ MAX_MAN_PATH_ITEMS];
57  int man_path_items = 0;
58  // Split the colon separated MANPATH in to discrete strings
59  char *cursor = man_path_s;
60  bool fresh_item = TRUE;
61  while( *cursor != '\0')
62  {
63    if ( fresh_item)
64    {
65      if ( man_path_items < MAX_MAN_PATH_ITEMS)
66        man_path_item[ man_path_items++] = cursor;
67      fresh_item = FALSE;
68    }
69    if ( ':' == *cursor)
70    {
71      *cursor = '\0';
72      fresh_item = TRUE;
73    }
74    cursor += 1;
75  }
76
77  // Go through every item on MANPATH
78  int mpi;
79  for ( mpi = 0; mpi < man_path_items; ++ mpi)
80  {
81    char *man_dir = man_path_item[ mpi];
82
83    // Go through sections 1..9 or just the specified section
84    int min_s = ANY_SECTION == section ? 1 : section;
85    int max_s = ANY_SECTION == section ? 9 : section;
86    int s;
87    for ( s = min_s; s <= max_s; ++ s)
88    {
89      // If the named man page exists in this (MANPATH item, section) then
90      // display it
91      char path_to_file[ 256];
92      Form form[] = {
93        {"%s/man%i/%s.%i", emitter:"cat"},
94        {"%s/man%i/%s.%i.gz", emitter:"zcat"},
95      };
96      char cmd[ 512] = {'\0'};
97      int i;
98      for ( i = 0; i < LENGTH_OF(form); ++ i)
99      {
100        Form f = form[ i];
101
102        snprintf( path_to_file, sizeof(path_to_file), f.name_template, man_dir, s, page, s);
103        if ( ! access( path_to_file, R_OK))
104        {
105          snprintf( cmd, sizeof(cmd), "%s %s | mandoc | less", f.emitter, path_to_file);
106          break;
107        }
108      }
109
110      if ( cmd[0] != '\0')
111      {
112        system( cmd);
113        return 0;
114      }
115    }
116  }
117
118  fprintf( stderr, "No manual entry for %s\n", page);
119  return 1;
120}
121
122

Archive Download this file

Branches:
master



interactive