mirror of
https://github.com/GnoConsortium/gno.git
synced 2024-12-21 07:30:05 +00:00
makewhatis version 1.0 (later to be incorporated in the manpack archive)
This commit is contained in:
parent
c89ef9549f
commit
39f4efc5b8
14
usr.bin/man/README
Normal file
14
usr.bin/man/README
Normal file
@ -0,0 +1,14 @@
|
||||
--------------------------------------------
|
||||
Name: makewhatis
|
||||
Version: 1.0
|
||||
Author: Devin Reade <glyn@cs.ualberta.ca>
|
||||
Computer: Apple IIgs
|
||||
Requires: Gno v2.x
|
||||
--------------------------------------------
|
||||
|
||||
Description: Generates the whatis database for apropos(1) and whatis(1)
|
||||
See the man page for a detailed description.
|
||||
|
||||
Installation:
|
||||
Copy makewhatis to /usr/sbin and makewhatis.1 to $(USRMAN)/man1.
|
||||
Alternately, you can type "dmake install" from this directory.
|
232
usr.bin/man/fillbuffer.c
Normal file
232
usr.bin/man/fillbuffer.c
Normal file
@ -0,0 +1,232 @@
|
||||
#ifdef __CCFRONT__
|
||||
#include <14:pragma.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "makewhatis.h"
|
||||
|
||||
char buffer[BUFFERSIZE];
|
||||
static char buffer2[BUFFERSIZE];
|
||||
|
||||
/* void fillbuffer (char *filename);
|
||||
*
|
||||
* Pre: <filename> is the name of the man page or temporary file
|
||||
* containing text. It may have nroff formatting information
|
||||
* or screen control codes, but must not be either a compressed
|
||||
* file nor an AWGS word processor file.
|
||||
*
|
||||
* Post: <buffer> will contain all the text, minus formatting and control
|
||||
* code, starting from the word "NAME" and ending with either ".SH".
|
||||
* "SYNOPSIS", or "DESCRIPTION", whichever comes first.
|
||||
*
|
||||
* If an error occurs, <buffer> will be an empty string (ie:
|
||||
* buffer[0] == '\0')
|
||||
*/
|
||||
|
||||
void fillbuffer (char *filename) {
|
||||
FILE *fp; /* FILE pointer for filename */
|
||||
int count; /* how many chars were read into buffer2 */
|
||||
char *p1; /* points to current char in buffer2 */
|
||||
char *p2; /* points to last char (of interest) in buffer2 */
|
||||
char *p3; /* points to current char in buffer */
|
||||
short found; /* some flags */
|
||||
short in_comment;
|
||||
short in_format_BR;
|
||||
short in_format_f;
|
||||
|
||||
/*
|
||||
* open the file
|
||||
*/
|
||||
|
||||
if ((fp = fopen(filename,"rb")) == NULL) {
|
||||
buffer[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make p1 point to spot in buffer2 where the first "NAME" occurs.
|
||||
* Note that if "NAME" is within a comment line (nroff source), it
|
||||
* will still be picked up.
|
||||
*/
|
||||
|
||||
for(;;) {
|
||||
count = fread(buffer2,sizeof(char),BUFFERSIZE-1,fp);
|
||||
if (count == 0) {
|
||||
/*
|
||||
* eof or error, and we haven't found "NAME" yet ... return
|
||||
* an empty string
|
||||
*/
|
||||
buffer[0] = '\0';
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
buffer2[count] = '\0';
|
||||
p1 = strstr(buffer2,"NAME");
|
||||
if (p1 != NULL) break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make p1 point to spot in buffer2 where there occurs the first
|
||||
* character following '-' which in turn follows "NAME".
|
||||
* Note that if "NAME" or '-' are within a comment line
|
||||
* (nroff source), it will still be picked up.
|
||||
*/
|
||||
|
||||
for(;;) {
|
||||
p2 = strchr(p1,'-');
|
||||
if (p2 != NULL) {
|
||||
p2++;
|
||||
break;
|
||||
}
|
||||
count = fread(buffer2,sizeof(char),BUFFERSIZE-1,fp);
|
||||
if (count == 0) {
|
||||
/*
|
||||
* eof or error, and we haven't found '-' yet ... return
|
||||
* an empty string
|
||||
*/
|
||||
buffer[0] = '\0';
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
buffer2[count] = '\0';
|
||||
p1 = buffer2;
|
||||
}
|
||||
p1 = p2;
|
||||
|
||||
/*
|
||||
* now copy selected chars to buffer until the next subheading is found
|
||||
*/
|
||||
|
||||
p3 = buffer;
|
||||
found = 0; /* set this when we find one of the above strings */
|
||||
in_format_BR = 0; /* in the middle of a .BR format */
|
||||
in_format_f = 0; /* in the middle of a \fI format */
|
||||
in_comment = 0; /* in the middle of a .\" comment */
|
||||
for(;;) {
|
||||
|
||||
/* mark the "end" of buffer2 with p2 */
|
||||
if ( ((p2 = strstr(p1,".SH")) != NULL) ||
|
||||
((p2 = strstr(p1,"SYNOPSIS")) != NULL) ||
|
||||
((p2 = strstr(p1,"DESCRIPTION")) != NULL)
|
||||
) {
|
||||
found = 1;
|
||||
} else {
|
||||
p2 = buffer + count;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is not our first iteration, dump any formatting information
|
||||
* or comments left over from the last interation.
|
||||
*/
|
||||
|
||||
if (in_comment) {
|
||||
while((p1<p2) && (*p1 != '\r')) p1++;
|
||||
in_comment = 0;
|
||||
}
|
||||
|
||||
if (in_format_BR) {
|
||||
while ((p1<p2) && !isspace(*p1)) p1++;
|
||||
in_format_BR = 0;
|
||||
}
|
||||
|
||||
if (in_format_f) {
|
||||
p1 = p1 + 3 - in_format_f;
|
||||
in_format_f = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* At this time, p1 points to the start of the description, p2
|
||||
* to either the end of the description or the end of buffer2,
|
||||
* and p3 into the spot in buffer where the next character should
|
||||
* be put.
|
||||
*
|
||||
* Copy *p1 to *p3 while p1<p2 (not at end of buffer or description),
|
||||
* skipping comments, formatting info, and control chars
|
||||
*/
|
||||
|
||||
for (; p1<p2; p1++) {
|
||||
|
||||
/* skip .\" comments */
|
||||
if (strncmp(p1,"\r.\\\"",4) == 0) {
|
||||
while ((p1<p2) && (*p1!='\r')) p1++;
|
||||
if (p1==p2) in_comment = 1;
|
||||
}
|
||||
|
||||
/* skip .BR-type formatting */
|
||||
if ((p1<p2) && (*p1=='\r') && (*(p1+1)=='.')) {
|
||||
while ((p1<p2) && !isspace(*p1)) p1++;
|
||||
if (p1==p2) in_format_BR = 1;
|
||||
}
|
||||
|
||||
/* skip \fI-type formatting */
|
||||
if ((p1<p2) && (*p1=='\\') && (*(p1+1)=='f')) {
|
||||
if ((p1 + 3) < p2) {
|
||||
p1 += 3;
|
||||
} else {
|
||||
in_format_f = p2 - p1;
|
||||
p1 = p2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* at this point, *p1 is either a control char or something that
|
||||
* we want in buffer, assuming that p1<p2.
|
||||
*/
|
||||
|
||||
if ((p1<p2) && !iscntrl(*p1)) *p3++ = *p1;
|
||||
}
|
||||
|
||||
if (found) { /* we've got the entire description */
|
||||
*p3 = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* We're part way through the description; read another block
|
||||
* into buffer2.
|
||||
*/
|
||||
|
||||
count = fread(buffer2,sizeof(char),BUFFERSIZE-1,fp);
|
||||
if (count == 0) {
|
||||
/* eof or error; terminate buffer and return */
|
||||
*p3 = '\0';
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
p1 = buffer2;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* close the file
|
||||
*/
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST_FILLBUFFER
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s <man_page_file_name>\n\n",argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fillbuffer(argv[1]);
|
||||
|
||||
if (strlen(buffer) == 0) {
|
||||
printf("buffer empty\n");
|
||||
} else {
|
||||
printf("main: buffer is %u chars long\n%s\n",strlen(buffer),buffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
47
usr.bin/man/makefile.mk
Normal file
47
usr.bin/man/makefile.mk
Normal file
@ -0,0 +1,47 @@
|
||||
#
|
||||
# Makefile for dmake(1)
|
||||
#
|
||||
|
||||
# Location for executable. It should be /usr/sbin
|
||||
|
||||
BINDIR = /usr/sbin
|
||||
|
||||
# Location for man pages.
|
||||
|
||||
MANDIR = /usr/man
|
||||
|
||||
#
|
||||
# Nothing past this point should have to be changed
|
||||
#
|
||||
|
||||
CFLAGS = -w -O -v
|
||||
OBJS = makewhatis.o fillbuffer.o process.o
|
||||
|
||||
makewhatis: $(OBJS)
|
||||
$(CC) $(OBJS) -o makewhatis
|
||||
|
||||
makewhatis.o: makewhatis.c makewhatis.h
|
||||
$(CC) -c $(CFLAGS) makewhatis.c
|
||||
|
||||
fillbuffer.o: fillbuffer.c makewhatis.h
|
||||
$(CC) -c $(CFLAGS) fillbuffer.c
|
||||
|
||||
process.o: process.c makewhatis.h
|
||||
$(CC) -c $(CFLAGS) process.c
|
||||
|
||||
install:
|
||||
/bin/cp makewhatis $(BINDIR)
|
||||
/bin/cp makewhatis.1 $(MANDIR)/man1
|
||||
|
||||
clean:
|
||||
/bin/cp -p rm $(OBJS)
|
||||
|
||||
#
|
||||
# These are just for debugging purposes
|
||||
#
|
||||
|
||||
fillbuffer: fillbuffer.c makewhatis.h
|
||||
$(CC) $(CFLAGS) -DTEST_FILLBUFFER -o fillbuffer fillbuffer.c
|
||||
|
||||
process: process.o fillbuffer.o
|
||||
$(CC) $(CFLAGS) process.o fillbuffer.o -o process
|
190
usr.bin/man/makewhatis.8
Normal file
190
usr.bin/man/makewhatis.8
Normal file
@ -0,0 +1,190 @@
|
||||
.TH MAKEWHATIS 1 "Commands and Applications" "15 May 1994" "Version 1.0"
|
||||
.SH NAME
|
||||
.B makewhatis
|
||||
\- generate the whatis database file
|
||||
.SH SYNOPSIS
|
||||
.B makewhatis
|
||||
[
|
||||
.I -c
|
||||
|
|
||||
.I -C
|
||||
] [
|
||||
.I -ovV
|
||||
] [
|
||||
.I "-f outfile"
|
||||
] [
|
||||
.I "-l logfile"
|
||||
] [
|
||||
.I "-p path"
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.B makewhatis
|
||||
generates the whatis database for
|
||||
.BR whatis "(1) and " apropos "(1)."
|
||||
This database is a text file containing line oriented records. Each record
|
||||
contains a man page name, the section number, and the brief description.
|
||||
.LP
|
||||
By default,
|
||||
.B makewhatis
|
||||
makes use of one of the environment variables \fIMANPATH\fR, \fIUSRMAN\fR,
|
||||
or \fIMANDIR\fR, in the listed order of preference. It will use this
|
||||
environment variable to determine for which manual pages the whatis
|
||||
database should be built. If the environment variable contains more than
|
||||
one path (delimited by spaces), then whatis databases will be generated
|
||||
in all of the specified paths.
|
||||
.LP
|
||||
The routines used are compatible with man pages in
|
||||
.BR nroff ,
|
||||
.BR aroff ,
|
||||
.BR compress ", or"
|
||||
.BR freeze
|
||||
format, as well as text versions of manual pages in the man/catX hierarchy.
|
||||
.B Makewhatis
|
||||
assumes that the suffixes \fI.Z\fR and \fI.F\fR are are appended to the
|
||||
chapter number on file names when those files are in
|
||||
.BR compress " or " freeze
|
||||
format, respectively. (For example, a compressed file would be expected
|
||||
to have a file name similar to
|
||||
.I foo.3.Z
|
||||
or \fIbar.3v.Z\fR.)
|
||||
Any files using the
|
||||
.I ".l"
|
||||
(ell) suffix are ignored. All suffix tests are case insensitive.
|
||||
.LP
|
||||
By default,
|
||||
.B makewhatis
|
||||
will only use files in the man/manX hierarchy in the creation of the
|
||||
database. However, since many Gno programmers are providing only text
|
||||
versions of their man pages, invoking
|
||||
.B makewhatis
|
||||
with the
|
||||
.I -c
|
||||
flag will add descriptions for all files in the man/catX hierarchy that
|
||||
don't have a counterpart in the man/manX hierarchy. This conditional
|
||||
eliminates the parsing of files in man/catX generated by
|
||||
.BR catman (1).
|
||||
.LP
|
||||
Note that the lines in the whatis database file are created in the order
|
||||
that the man pages are found. It is suggested that the database be sorted
|
||||
after
|
||||
.B makewhatis
|
||||
is finished. See
|
||||
.BR sort (1).
|
||||
.SH OPTIONS
|
||||
.I -c
|
||||
will check man/catX sub-directories as well as man/manX
|
||||
.LP
|
||||
.I -C
|
||||
will check
|
||||
.BR only
|
||||
man/catX sub-directories, not man/manX sub-directories.
|
||||
.LP
|
||||
.I "-f outfile"
|
||||
causes the
|
||||
.B makewhatis
|
||||
status output to be placed in \fIoutfile\fR.
|
||||
.LP
|
||||
.I "-l logfile"
|
||||
will cause any error messages to be printed to \fIlogfile\fR.
|
||||
.LP
|
||||
.I "-o dbfile"
|
||||
will make
|
||||
.B makewhatis
|
||||
use
|
||||
.I dbfile
|
||||
as the name for the generated whatis databases.
|
||||
.LP
|
||||
.I "-p path"
|
||||
overrides the environment variables
|
||||
.I MANPATH
|
||||
et al for determining for which manual page hierarchies the databases must
|
||||
be generated.
|
||||
.LP
|
||||
.I -v
|
||||
creates verbose status messages during execution.
|
||||
.LP
|
||||
.I -V
|
||||
will show version and usage information, then exit.
|
||||
.SH ENVIRONMENT
|
||||
\fIMANPATH\fR, \fIUSRMAN\fR, \fIMANDIR\fR:
|
||||
.br
|
||||
Unless the
|
||||
.I -p
|
||||
flag is used,
|
||||
.B makewhatis
|
||||
will use the first that it finds of these environment variables for
|
||||
determining where database files should be generated. While
|
||||
.B makewhatis
|
||||
will correctly handle
|
||||
.I ~
|
||||
and
|
||||
.I .
|
||||
being part of these paths, it will not correctly handle \fI..\fR.
|
||||
.SH CAVEATS
|
||||
Because
|
||||
.B makewhatis
|
||||
looks for the string
|
||||
.I NAME
|
||||
and one of \fI.SH\fR, \fISYNOPSIS\fR, or
|
||||
.I DESCRIPTION
|
||||
when processing files, it can be confused by missing fields or
|
||||
some methods of formatting. For example, if in a man/catX page
|
||||
.I NAME
|
||||
is boldfaced by repeated backspace characters as in \fIN^HNA^HAM^HME^HE\fR,
|
||||
then the generated description for that particular man page is unpredictable,
|
||||
though usually blank. For any diehards who like placing such information
|
||||
in their hand-coded man/catX pages, using a string similar to
|
||||
.I "NAME^H^H^H^HNAME"
|
||||
will create a proper description in the database file.
|
||||
.LP
|
||||
Similarily,
|
||||
.B makewhatis
|
||||
expects the subheading
|
||||
.I NAME
|
||||
to be in the format:
|
||||
.nf
|
||||
NAME
|
||||
<command> - <brief description>
|
||||
.fi
|
||||
If this is not so (ignoring whitespace), then the output is unpredictable.
|
||||
.LP
|
||||
Where unpredictable output has been mentioned above, this means that
|
||||
the description in the database file will either be blank or random
|
||||
text from the man page. It
|
||||
.I "does not"
|
||||
mean that system integrity or that the remainder of the database file
|
||||
has been affected.
|
||||
.SH BUGS
|
||||
If a man page describes multiple items and has a NAME subheading such as
|
||||
.nf
|
||||
|
||||
NAME
|
||||
item1, item2, item3 - This is the description.
|
||||
|
||||
.fi
|
||||
Then
|
||||
.B makewhatis
|
||||
should create a database record that reads:
|
||||
.nf
|
||||
|
||||
item1 (3), item2 (3), item3 (3) - This is the description.
|
||||
|
||||
.fi
|
||||
Instead, if item2.l and item3.l are links to item1.3, the created record reads
|
||||
.nf
|
||||
|
||||
item1 (3) - This is the description.
|
||||
|
||||
.fi
|
||||
.SH FILES
|
||||
.nf
|
||||
/usr/sbin/makewhatis -- whatis database generator
|
||||
man/whatis -- the whatis database
|
||||
.fi
|
||||
.SH SEE ALSO
|
||||
.BR apropos (1),
|
||||
.BR catman (1),
|
||||
.BR man (1),
|
||||
.BR whatis (1),
|
||||
.SH AUTHOR
|
||||
Written by Devin Reade <glyn@cs.ualberta.ca> for the Apple IIgs and Gno.
|
307
usr.bin/man/makewhatis.c
Normal file
307
usr.bin/man/makewhatis.c
Normal file
@ -0,0 +1,307 @@
|
||||
#ifdef __CCFRONT__
|
||||
#include <14:pragma.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <libc.h>
|
||||
|
||||
#include "makewhatis.h"
|
||||
|
||||
/*
|
||||
* Options:
|
||||
*
|
||||
* -c check cat* subdirectories as well
|
||||
* -C check _only_ cat* subdirectories, not man* subdirectories.
|
||||
* -f outfile force whatis status output to <outfile>
|
||||
* -l logfile log errors to <logfile>
|
||||
* -o dbfile force whatis database output to <dbfile>
|
||||
* -p path use the <path> rather than $MANPATH, $USRMAN, or $MANDIR
|
||||
* -s sort the whatis database by manual page name
|
||||
* -v verbose
|
||||
* -V show version and usage info and exit
|
||||
*/
|
||||
|
||||
char *man_subdir[] = {
|
||||
"man1",
|
||||
"man2",
|
||||
"man3",
|
||||
"man4",
|
||||
"man5",
|
||||
"man6",
|
||||
"man7",
|
||||
"man8",
|
||||
"mann",
|
||||
"manl",
|
||||
NULL
|
||||
};
|
||||
|
||||
/* For the various command line flags */
|
||||
|
||||
short c_flag = 0;
|
||||
short C_flag = 0;
|
||||
short o_flag = 0;
|
||||
short p_flag = 0;
|
||||
short v_flag = 0;
|
||||
short errflag = 0; /* This is set if there is a usage error or -V flag */
|
||||
|
||||
static char filebuffer[FILENAME_MAX]; /* used when traversing cat* pages */
|
||||
static char progdir[FILENAME_MAX]; /* the directory where makewhatis started */
|
||||
|
||||
/*
|
||||
* we include cat* since some Gno utility man pages aren't written in
|
||||
* either nroff or aroff source ... go figure.
|
||||
*/
|
||||
|
||||
char *cat_subdir[] = {
|
||||
"cat1",
|
||||
"cat2",
|
||||
"cat3",
|
||||
"cat4",
|
||||
"cat5",
|
||||
"cat6",
|
||||
"cat7",
|
||||
"cat8",
|
||||
"catn",
|
||||
"catl",
|
||||
NULL /* _must_ be NULL terminated! */
|
||||
};
|
||||
|
||||
FILE *output_fp;
|
||||
FILE *error_fp;
|
||||
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
|
||||
char *manpath; /* the location of the man pages */
|
||||
char *path; /* the current path; taken from manpath */
|
||||
char *p=NULL; /* a temporary pointer */
|
||||
struct dirent *file; /* the current file we have open */
|
||||
char tmp_file[L_tmpnam]; /* a scratch file */
|
||||
FILE *tmp_fp; /* pointer to tmp_file */
|
||||
FILE *whatis_fp; /* pointer to the current whatis database */
|
||||
DIR *subdir; /* the current man subdirectory -- eg: /usr/man/man3 */
|
||||
char *dbfile; /* non-default name of the whatis database */
|
||||
char *dirsep; /* the directory separator, either "/" or ":" */
|
||||
int i;
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
/* make sure Gno is running */
|
||||
if (needsgno()==0) {
|
||||
fprintf(stderr,"Requires Gno/ME\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* set the defaults
|
||||
*/
|
||||
|
||||
output_fp = stdout;
|
||||
error_fp = stderr;
|
||||
if (getwd(progdir) == NULL) {
|
||||
perror("getwd() failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* parse the command line
|
||||
*/
|
||||
|
||||
while((i = getopt(argc,argv,"cCf:l:o:p:vV")) != EOF)
|
||||
switch(i) {
|
||||
case 'c':
|
||||
if (C_flag) errflag++;
|
||||
else c_flag++;
|
||||
break;
|
||||
case 'C':
|
||||
if (c_flag) errflag++;
|
||||
else C_flag++;
|
||||
break;
|
||||
case 'f':
|
||||
output_fp = fopen (optarg,"w");
|
||||
if (output_fp == NULL) {
|
||||
fprintf(stderr,"Could not open output file %s; using stdout.\n",
|
||||
optarg);
|
||||
output_fp = stdout;
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
error_fp = fopen (optarg,"w");
|
||||
if (error_fp == NULL) {
|
||||
fprintf(stderr,"Could not open log file %s; using stderr.\n",
|
||||
optarg);
|
||||
error_fp = stderr;
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
o_flag++;
|
||||
dbfile = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
p_flag++;
|
||||
p = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
v_flag++;
|
||||
break;
|
||||
case 'V':
|
||||
fprintf(stderr,
|
||||
"%s -- Create the %s database.\n\tVersion %s by Devin Reade\n\n",
|
||||
argv[0],WHATIS,VERSIONSTRING);
|
||||
errflag++;
|
||||
break;
|
||||
default:
|
||||
errflag++;
|
||||
break;
|
||||
}
|
||||
if (errflag) {
|
||||
fprintf(error_fp,
|
||||
"Usage: %s [-c|-C] [-ovV] [-f outfile] [-l logfile] [-p path]\n\n\
|
||||
-c\t\tCheck catX subdirectories as well\n\
|
||||
-C\t\tCheck _only_ catX subdirectories, not manX subdirectories.\n\
|
||||
-f outfile\tForce whatis output to <outfile>.\n\
|
||||
-l logfile\tLog errors to <logfile>.\n\
|
||||
-o dbfile\tforce whatis database output to <dbfile>.\n\
|
||||
-p path\t\tUse the <path> rather than $MANPATH, $USRMAN, or $MANDIR.\n\
|
||||
-v\t\tVerbose.\n\
|
||||
-V\t\tShow version and usage information, then exit.\n",argv[0],WHATIS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* get the location of the man pages; p is already set if -p flag used
|
||||
*/
|
||||
|
||||
if (p == NULL) p = getenv("MANPATH");
|
||||
if (p == NULL) p = getenv("USRMAN");
|
||||
if (p == NULL) p = getenv("MANDIR");
|
||||
if (p == NULL) {
|
||||
fprintf(error_fp,"Location of man pages unknown. You must either define \
|
||||
environment variables\n$MANPATH, $USRMAN, or $MANDIR, or use the -p flag.\n\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* define the directory separator */
|
||||
dirsep = (strchr(p,':')==NULL) ? "/" : ":";
|
||||
|
||||
/* make a copy of the location */
|
||||
if ((manpath = malloc (strlen(p) + 1)) == NULL) {
|
||||
if (v_flag) fprintf(error_fp,"couldn't make copy of \"%s\"",p);
|
||||
return -1;
|
||||
}
|
||||
strcpy(manpath,p);
|
||||
|
||||
/* get the name of the temporary file */
|
||||
tmpnam (tmp_file);
|
||||
|
||||
/*
|
||||
* loop over all the paths in manpath. Don't use ':' as a delimiter since
|
||||
* the colon is a pathname separator under GS/OS.
|
||||
*/
|
||||
|
||||
path = strtok (manpath," ");
|
||||
while (path != NULL) {
|
||||
|
||||
if (access(path,F_OK)==0) {
|
||||
|
||||
if (strcmp(path,".") == 0) {
|
||||
chdir(progdir);
|
||||
} else {
|
||||
chdir(path);
|
||||
}
|
||||
|
||||
/* open the whatis database file */
|
||||
if (!o_flag) dbfile = WHATIS;
|
||||
whatis_fp = fopen(dbfile,"w");
|
||||
if (whatis_fp == NULL) {
|
||||
fprintf (error_fp,
|
||||
"Could not create whatis database file %s in directory %s.\n",
|
||||
dbfile,path);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* loop over the expected man* subdirectories within path
|
||||
*/
|
||||
|
||||
if (!C_flag) for (i=0; man_subdir[i] != NULL; i++) {
|
||||
subdir = opendir(man_subdir[i]);
|
||||
if (subdir != NULL) {
|
||||
|
||||
/* print status */
|
||||
if (v_flag) fprintf(output_fp,
|
||||
"Now working on directory %s\t%s ...\n",path,man_subdir[i]);
|
||||
|
||||
/* no need to error check because of opendir() */
|
||||
chdir(man_subdir[i]);
|
||||
|
||||
/* loop over files within subdirectory */
|
||||
while ((file = readdir(subdir)) != NULL) {
|
||||
process (file->d_name,tmp_file,whatis_fp);
|
||||
}
|
||||
closedir(subdir);
|
||||
} else {
|
||||
if (v_flag) fprintf(output_fp,
|
||||
"Could not access files in %s\t%s ...\n",path,man_subdir[i]);
|
||||
}
|
||||
chdir(path);
|
||||
}
|
||||
|
||||
/*
|
||||
* loop over the expected cat* subdirectories within path,
|
||||
* adding only those files without man* versions.
|
||||
*/
|
||||
|
||||
if (c_flag||C_flag) for (i=0; cat_subdir[i] != NULL; i++) {
|
||||
subdir = opendir(cat_subdir[i]);
|
||||
if (subdir != NULL) {
|
||||
|
||||
/* print status */
|
||||
if (v_flag) fprintf(output_fp,
|
||||
"Now working on directory %s\t%s ...\n",path,cat_subdir[i]);
|
||||
|
||||
/* no need to error check because of opendir() */
|
||||
chdir(cat_subdir[i]);
|
||||
|
||||
/* make filebuffer contain path to matching man* subdirectory */
|
||||
strcpy(filebuffer,path);
|
||||
strcat(filebuffer,dirsep);
|
||||
strcat(filebuffer,man_subdir[i]);
|
||||
strcat(filebuffer,dirsep);
|
||||
p = filebuffer + strlen(filebuffer); /* p points to '\0' */
|
||||
|
||||
/* loop over files that don't have a man* counterpart */
|
||||
while ((file = readdir(subdir)) != NULL) {
|
||||
strcpy(p,file->d_name);
|
||||
if (access(filebuffer,F_OK)!=0)
|
||||
process (file->d_name,tmp_file,whatis_fp);
|
||||
}
|
||||
closedir(subdir);
|
||||
} else {
|
||||
if (v_flag) fprintf(output_fp,
|
||||
"Could not access files in %s\t%s ...\n",path,cat_subdir[i]);
|
||||
}
|
||||
chdir(path);
|
||||
}
|
||||
|
||||
/* close the database */
|
||||
fclose(whatis_fp);
|
||||
|
||||
}
|
||||
/* get the next path in manpath */
|
||||
path = strtok (NULL," ");
|
||||
}
|
||||
|
||||
|
||||
/* clean up and exit */
|
||||
unlink(tmp_file);
|
||||
if (output_fp != stdout) fclose(output_fp);
|
||||
if (error_fp != stderr) fclose(error_fp);
|
||||
return 0;
|
||||
}
|
25
usr.bin/man/makewhatis.h
Normal file
25
usr.bin/man/makewhatis.h
Normal file
@ -0,0 +1,25 @@
|
||||
#define VERSIONSTRING "1.0"
|
||||
|
||||
/* The size of the IO buffers */
|
||||
#define BUFFERSIZE 1024
|
||||
|
||||
/* The default name for the whatis database */
|
||||
#define WHATIS "whatis"
|
||||
|
||||
/* The number of characters per tab in the whatis database */
|
||||
#define TABLENGTH 8
|
||||
|
||||
extern int chdir (const char *);
|
||||
extern int system (const char *);
|
||||
|
||||
void fillbuffer (char *filename);
|
||||
void process (char *filename, char *tmp_file, FILE *whatis_fp);
|
||||
|
||||
extern short c_flag;
|
||||
extern short C_flag;
|
||||
extern short f_flag;
|
||||
extern short l_flag;
|
||||
extern short O_flag;
|
||||
extern short p_flag;
|
||||
extern short v_flag;
|
||||
extern short errflag;
|
166
usr.bin/man/process.c
Normal file
166
usr.bin/man/process.c
Normal file
@ -0,0 +1,166 @@
|
||||
#ifdef __CCFRONT__
|
||||
#include <14:pragma.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <gsos.h>
|
||||
#include <orca.h>
|
||||
|
||||
#include "makewhatis.h"
|
||||
|
||||
#ifdef TEST_PROCESS
|
||||
short v_flag = 1;
|
||||
#endif
|
||||
|
||||
extern GSString255Ptr __C2GSMALLOC (char *s);
|
||||
extern char buffer[];
|
||||
extern FILE *output_fp;
|
||||
extern FILE *error_fp;
|
||||
|
||||
/*
|
||||
* void process (char *filename, char *tmp_file, FILE *whatis_fp);
|
||||
*
|
||||
* Pre: <filename> is the name of the file to add to the database.
|
||||
* <tmp_file> is the name for the temporary file. It has not been opened.
|
||||
* <whatis_fp> is a file pointer to the open whatis database file.
|
||||
*
|
||||
* Post: The name, section number, and description from the man page is
|
||||
* appended to <whatis_fp>.
|
||||
*/
|
||||
|
||||
void process (char *filename, char *tmp_file, FILE *whatis_fp) {
|
||||
|
||||
FileInfoRecGS info_record; /* used to get the file type */
|
||||
char *suffix; /* points to the start of the file suffix */
|
||||
static char command_buf[255]; /* used to call system(2) */
|
||||
char *p1; /* a scratch pointer */
|
||||
int namelength; /* length of 'name (section)' */
|
||||
char *name; /* points to the file basename */
|
||||
int sufflen; /* length of the filename suffix */
|
||||
|
||||
if (v_flag) fprintf(output_fp,"Working on file %s ...\n",filename);
|
||||
|
||||
/*
|
||||
* get the file basename and suffix
|
||||
*/
|
||||
|
||||
if ((name = malloc (strlen(filename)+1)) == NULL) {
|
||||
if (v_flag)
|
||||
fprintf(error_fp,"malloc failed when processing %s -- file skipped\n",
|
||||
filename);
|
||||
return;
|
||||
}
|
||||
strcpy(name,filename);
|
||||
if ((suffix = strchr(name,'.')) == NULL) {
|
||||
if (v_flag)
|
||||
fprintf(error_fp,"%s has no suffix -- file skipped\n",
|
||||
filename);
|
||||
return;
|
||||
}
|
||||
*suffix = '\0';
|
||||
suffix++;
|
||||
sufflen = strlen(suffix);
|
||||
|
||||
/*
|
||||
* find out the file type
|
||||
*/
|
||||
|
||||
info_record.pCount = 5;
|
||||
info_record.pathname = __C2GSMALLOC(filename);
|
||||
GetFileInfoGS(&info_record);
|
||||
if (toolerror()) {
|
||||
if (v_flag)
|
||||
fprintf(error_fp,"malloc failed when processing %s -- file skipped\n",
|
||||
filename);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process the file according to type: nroff, aroff, freeze, and compress.
|
||||
* The digested result is placed in buffer.
|
||||
*/
|
||||
|
||||
if ((info_record.fileType == 0x50u) && (info_record.auxType == 0x8010u)) {
|
||||
|
||||
/* is it an Appleworks GS word processor document? Use aroff */
|
||||
sprintf(command_buf,"aroff -b %s >%s",filename,tmp_file);
|
||||
system(command_buf);
|
||||
fillbuffer(tmp_file);
|
||||
|
||||
} else if ( (toupper(*(suffix+sufflen-1))=='Z') &&
|
||||
(*(suffix+sufflen-2)=='.')) {
|
||||
|
||||
/* Compressed man page; uncompress it */
|
||||
sprintf(command_buf,"compress -dc %s >%s",filename,tmp_file);
|
||||
system(command_buf);
|
||||
fillbuffer(tmp_file);
|
||||
|
||||
/* fix suffix for printout */
|
||||
sufflen -= 2;
|
||||
*(suffix + sufflen) = '\0';
|
||||
|
||||
} else if ( (toupper(*(suffix+sufflen-1))=='F') &&
|
||||
(*(suffix+sufflen-2)=='.')) {
|
||||
|
||||
/* Frozen man page; melt it */
|
||||
sprintf(command_buf,"freeze -dc %s >%s",filename,tmp_file);
|
||||
system(command_buf);
|
||||
fillbuffer(tmp_file);
|
||||
|
||||
/* fix suffix for printout */
|
||||
sufflen -= 2;
|
||||
*(suffix + sufflen) = '\0';
|
||||
|
||||
} else if ((toupper(*suffix)=='L') && (*(suffix+1)=='\0')) {
|
||||
|
||||
/* It's a link to another man page; do nothing. */
|
||||
return;
|
||||
|
||||
} else {
|
||||
|
||||
/* Assume that it's a text file */
|
||||
fillbuffer(filename);
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, buffer contains the line that we need to print to
|
||||
* whatis_fd. Strip off any leading spaces, then give it a nice
|
||||
* formatting.
|
||||
*/
|
||||
|
||||
p1 = buffer;
|
||||
while (isspace(*p1)) p1++;
|
||||
namelength = strlen(name) + strlen(suffix) + 4;
|
||||
|
||||
if (namelength > (TABLENGTH * 3)) {
|
||||
fprintf(whatis_fp,"%s (%s) - %s\n", name, suffix, p1);
|
||||
} else if (namelength > (TABLENGTH * 2)) {
|
||||
fprintf(whatis_fp,"%s (%s)\t- %s\n", name, suffix, p1);
|
||||
} else if (namelength > TABLENGTH ) {
|
||||
fprintf(whatis_fp,"%s (%s)\t\t- %s\n", name, suffix, p1);
|
||||
} else {
|
||||
fprintf(whatis_fp,"%s (%s)\t\t\t- %s\n", name, suffix, p1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef TEST_PROCESS
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s <man_page_file_name>\n",argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
process (argv[1], ":tmp:garbage", stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user