mirror of
https://github.com/GnoConsortium/gno.git
synced 2024-06-11 09:29:27 +00:00
This commit was manufactured by cvs2svn to create tag 'v1_0'.
This commit is contained in:
commit
4ecc6ce806
|
@ -1,209 +1,14 @@
|
|||
--------------------------------------------
|
||||
Name: manpack
|
||||
Version: 3.0
|
||||
Author: Devin Reade <gdr@myrias.com>
|
||||
Name: makewhatis
|
||||
Version: 1.0
|
||||
Author: Devin Reade <glyn@cs.ualberta.ca>
|
||||
Computer: Apple IIgs
|
||||
Requires: GNO v2.x
|
||||
Requires: Gno v2.x
|
||||
--------------------------------------------
|
||||
|
||||
===========
|
||||
Description:
|
||||
===========
|
||||
Description: Generates the whatis database for apropos(1) and whatis(1)
|
||||
See the man page for a detailed description.
|
||||
|
||||
Various programs for working with manual pages. This archive includes:
|
||||
|
||||
apropos v3.0 locate commands by keyword
|
||||
catman v1.0 format cat pages from man pages
|
||||
makewhatis v1.2 create the whatis database
|
||||
man v3.0 display reference manual pages
|
||||
whatis v3.0 locate commands by name
|
||||
|
||||
============
|
||||
Installation:
|
||||
============
|
||||
|
||||
Type at the command line `dmake install`. You may wish to first
|
||||
verify the destination directories in "Makefile.mk". By default
|
||||
these are:
|
||||
|
||||
BINDIR = /usr/bin (apropos, catman, man, and whatis)
|
||||
SBINDIR = /usr/sbin (makewhatis)
|
||||
MANDIR = /usr/man (all manual pages)
|
||||
|
||||
Ensure that all older versions of these programs are deleted.
|
||||
They may or may not be in the above directories.
|
||||
|
||||
==========
|
||||
Legalities:
|
||||
==========
|
||||
|
||||
These utilities are copyright 1995 by Devin Reade <gdr@myrias.com>.
|
||||
|
||||
They are provided as freeware, and may be distributed by Internet
|
||||
archive sites, online services such as GEnie, or BBSes provided that
|
||||
the archive remains intact. Permission is granted for distribution
|
||||
with GNO/ME and Orca provided credit for this work is given along
|
||||
with any other attributions.
|
||||
|
||||
Inclusion of these utilities in collections on disk, CD-ROM, or
|
||||
other portable media is permitted provided that only a nominal
|
||||
fee (not much more than the media cost) is charged. Contact the
|
||||
author regarding other commercial distributions.
|
||||
|
||||
Updates to these utilities may be distributed provided that the source
|
||||
and this README file are included. Please follow the coding style
|
||||
already in use and document your changes in this file.
|
||||
|
||||
=======
|
||||
CHANGES:
|
||||
=======
|
||||
|
||||
apropos, whatis
|
||||
|
||||
v3.0 (24 Jul 95)
|
||||
Complete rewrite from scratch by Devin Reade.
|
||||
|
||||
This version makes use of MANPATH in the same way
|
||||
as man(1) v3.0. Similarily, it will also search
|
||||
the 17/syscmnd Orca database.
|
||||
|
||||
In the previous version, the behavior of apropos was
|
||||
identical to that of whatis. This version has been
|
||||
fixed so that whatis is case sensitive and searches
|
||||
only the manual page names. The apropos search is
|
||||
case insensitive and searches the entire database
|
||||
entry.
|
||||
|
||||
v2.1 (1 Jul 92 ?)
|
||||
This version is by Mike Horwath and shipped with GNO v1.1.
|
||||
Although no version flags or resource forks where provided
|
||||
with this release, this release is designated as v2.1
|
||||
because it shipped with man(1) v2.1.
|
||||
|
||||
catman
|
||||
|
||||
v1.0 (24 Jul 95)
|
||||
Initial release. Written from scratch by Devin Reade.
|
||||
|
||||
makewhatis
|
||||
|
||||
v1.2 (24 Jul 95)
|
||||
Fixed bug where pages in "manl" ending in ".l" (that's
|
||||
"ell" in both cases) would be ignored.
|
||||
|
||||
Added recognition of files compressed with gzip.
|
||||
|
||||
File compression suffixes are now case sensitive.
|
||||
|
||||
If none of MANPATH, USRMAN, or MANDIR are defined,
|
||||
"/usr/man" will now be used.
|
||||
|
||||
Fixed a bug where the word SYNOPSIS appearing in the
|
||||
description would mangle the database entry.
|
||||
|
||||
Added a verbose-level-three flag (-v3), which is basically
|
||||
the old -v2 flag. The new -v2 is somewhat less verbose
|
||||
than it was.
|
||||
|
||||
v1.1 (29 May 94)
|
||||
Makewhatis will now ignore any man page starting with
|
||||
".so", in order to eliminate multiple files. The resultant
|
||||
blank lines in the whatis database have therefore been
|
||||
eliminated.
|
||||
|
||||
Changed -v flag to {-v1|-v2} for differing stages of verbosity.
|
||||
Only error output will be logged with the -l flag.
|
||||
|
||||
Manual page was updated, to include a correction to the -o
|
||||
flag usage and the modification to the -v flag. Descriptions
|
||||
of bugs unlikely to be fixed were added. Date and version
|
||||
were changed.
|
||||
|
||||
Fixed bug where input buffer wasn't properly terminated, and
|
||||
added checks for buffer overflows.
|
||||
|
||||
Makewhatis will now display all commands about which the
|
||||
manual page is written. For example, if foo.1 described
|
||||
both foo(1) and bar(1), and bar.1 was an .so (or .l) link
|
||||
to foo.1, then the database entry will have changed from
|
||||
|
||||
foo (1) - extract and add thingys
|
||||
foo, bar (1) - extract and add thingys
|
||||
|
||||
Makewhatis used to pick up the first NAME string in the file
|
||||
as a reference point. Now, any NAME is ignored in any line
|
||||
starting with .\" or .TH
|
||||
|
||||
Filename chapter numbers will now be correctly extracted
|
||||
regardless of the existence of .Z, .z, .F, or .f suffixes,
|
||||
or of the existence of '.' within the base file name.
|
||||
|
||||
Makewhatis is now linked with Soenke's gnulib for the
|
||||
getopt() function, rather than using the libc version.
|
||||
|
||||
Stack usage was reduced to 1k. Be aware, though, that a
|
||||
fair amount of global storage is used, including three 1k
|
||||
buffers.
|
||||
|
||||
v1.0 (15 May 94)
|
||||
Initial release. Written from scratch by Devin Reade.
|
||||
|
||||
man
|
||||
v3.0 (24 Jul 95)
|
||||
Complete rewrite from scratch by Devin Reade.
|
||||
|
||||
The -k, -t, -, -f, -M, and -T flags were added.
|
||||
|
||||
Man now supports the MANPATH environment variable which
|
||||
can be a list of paths delimited by either colons or
|
||||
spaces.
|
||||
|
||||
Added sections 3f, l, n, o, and p to searched subdirectories.
|
||||
|
||||
Added gzip(1) to compress(1) and freeze(1) as allowable
|
||||
source compressors.
|
||||
|
||||
Fixed bug with the .so source command; .so references
|
||||
should now (properly) appear as ".so man<section>/<filename>"
|
||||
instead of using the full pathname.
|
||||
|
||||
Updates to apropos v3.0 apply to man when invoked with
|
||||
the -k flag.
|
||||
|
||||
Preprocessing by eqn(1), refer(1), tbl(1), and vgrind(1)
|
||||
is not yet supported.
|
||||
|
||||
v2.1 (1 Jul 92 ?)
|
||||
Recognised environment variable USRMAN as well as MANDIR.
|
||||
|
||||
This version was also by Mike Horwath.
|
||||
|
||||
v2.0 (Date Unknown)
|
||||
This version is by Mike Horwath and shipped with GNO v1.1.
|
||||
|
||||
It made use of the environment variable MANDIR which had
|
||||
to be a single directory.
|
||||
|
||||
|
||||
=====
|
||||
TO DO:
|
||||
=====
|
||||
|
||||
Makewhatis is not very well integrated with the rest of the package;
|
||||
there is still duplication of definitions and functions in some files.
|
||||
|
||||
Man, catman, and makewhatis need to support preformatting for eqn(1),
|
||||
vgrind(1), et al.
|
||||
|
||||
Makewhatis' "verbose" output could be cleaner.
|
||||
|
||||
Performance analysis has not been done. No doubt some things could
|
||||
improve, including some string matching in util.c
|
||||
|
||||
If the stock getenv(3) function is used (as is done here), then the
|
||||
return value should be duplicated (via strdup) rather than just used.
|
||||
If the getenv function from the lenviron library is used, this is not
|
||||
a concern.
|
||||
|
||||
Perhaps an "X" version should be done for the Second Sight card. This
|
||||
will have to wait a while.
|
||||
Copy makewhatis to /usr/sbin and makewhatis.1 to $(USRMAN)/man1.
|
||||
Alternately, you can type "dmake install" from this directory.
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
.so man1/whatis.1
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995 by Devin Reade <gdr@myrias.com>. For distribution
|
||||
* information see the README file that is part of the manpack archive,
|
||||
* or contact the author, above.
|
||||
*/
|
||||
|
||||
segment "apropos___";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <libc.h>
|
||||
#include "util.h"
|
||||
#include "man.h"
|
||||
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
static char *versionstr = "3.0";
|
||||
static char *nothing = "nothing appropriate";
|
||||
|
||||
extern void begin_stack_check(void);
|
||||
extern int end_stack_check(void);
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
char *path;
|
||||
int i, matches1, matches2, matches3;
|
||||
short V_flag, M_flag, m_flag, n_flag, err_flag;
|
||||
|
||||
/* make sure Gno is running */
|
||||
if (needsgno()==0) {
|
||||
fprintf(stderr,"Requires Gno/ME\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
begin_stack_check();
|
||||
#endif
|
||||
|
||||
/* initialization */
|
||||
V_flag = M_flag = m_flag = n_flag = err_flag = 0;
|
||||
matches1 = matches2 = matches3 = 0;
|
||||
|
||||
/* parse command line and check usage */
|
||||
while((i = getopt(argc,argv,"M:m:nV")) != EOF) {
|
||||
switch(i) {
|
||||
case 'M':
|
||||
if (m_flag) err_flag++;
|
||||
M_flag++;
|
||||
path = optarg;
|
||||
break;
|
||||
case 'm':
|
||||
if (M_flag) err_flag++;
|
||||
m_flag++;
|
||||
path = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
n_flag++;
|
||||
break;
|
||||
case 'V':
|
||||
V_flag++;
|
||||
break;
|
||||
default:
|
||||
err_flag++;
|
||||
}
|
||||
}
|
||||
if (argc-optind < 1) err_flag++;
|
||||
if (err_flag || V_flag) {
|
||||
fprintf(stderr,"%s version %s by Devin Reade\n",
|
||||
basename(argv[0]),versionstr);
|
||||
}
|
||||
if (err_flag) {
|
||||
fprintf(stderr,
|
||||
"Usage: %s [[-M path] | [-m path]] [-nV] keyword [keyword ...]\n",
|
||||
basename(argv[0]));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* do the search */
|
||||
if (M_flag) {
|
||||
manpath = path;
|
||||
} else {
|
||||
manpath = getManpath();
|
||||
}
|
||||
matches1 = apropos(argc-optind, &argv[optind], MAN_K_MODE);
|
||||
if (!M_flag) free(manpath);
|
||||
if (m_flag) {
|
||||
manpath = path;
|
||||
matches2 = apropos(argc-optind, &argv[optind], MAN_K_MODE);
|
||||
}
|
||||
if (!n_flag) {
|
||||
matches3 = apropos(argc-optind, &argv[optind], ORCA_K_MODE);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
if (matches1>0) i+= matches1;
|
||||
if ( m_flag && matches2>0) i+=matches2;
|
||||
if (!n_flag && matches3>0) i+=matches3;
|
||||
|
||||
if (i==0) {
|
||||
fprintf(stderr,"%s: %s\n",basename(argv[0]),nothing);
|
||||
}
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
fprintf(stderr,"stack usage: %d bytes\n",end_stack_check());
|
||||
#endif
|
||||
|
||||
if ((matches1>=0) && (matches2>=0) && (matches3>=0) && i>0) return 0;
|
||||
return 1;
|
||||
}
|
|
@ -1,284 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995 by Devin Reade <gdr@myrias.com>. For distribution
|
||||
* information see the README file that is part of the manpack archive,
|
||||
* or contact the author, above.
|
||||
*/
|
||||
|
||||
segment "apropos2__";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include "util.h"
|
||||
#include "man.h"
|
||||
|
||||
/*
|
||||
* orcapadding -- return a suitable number of padding tabs based on the
|
||||
* length of the command
|
||||
*/
|
||||
|
||||
static char *orcapadding (char *command) {
|
||||
int i;
|
||||
static char *two ="\t\t";
|
||||
static char *one ="\t";
|
||||
static char *zero =" ";
|
||||
|
||||
i = strlen(command);
|
||||
if (i<8) return two;
|
||||
if (i<16) return one;
|
||||
return zero;
|
||||
}
|
||||
|
||||
/*
|
||||
* orcacomment -- return the start of the comment field in a line of
|
||||
* the Orca SYSCMND file. This _must_ be called before
|
||||
* orcacommand() is called on the same buffer, because
|
||||
* orcacommand() modifies the buffer.
|
||||
*/
|
||||
|
||||
static char *orcacomment (char *buffer) {
|
||||
char *p;
|
||||
static char *bad_line="malformed SYSCMND line\n";
|
||||
|
||||
p = buffer;
|
||||
|
||||
/* get past the command name */
|
||||
while ((*p != ' ') && (*p != '\t') && *p) p++;
|
||||
if (!*p) return bad_line;
|
||||
|
||||
/* get past space */
|
||||
while ((*p == ' ') || (*p == '\t') && *p) p++;
|
||||
if (!*p) return bad_line;
|
||||
|
||||
if (*p == '*') p++;
|
||||
switch (*p) {
|
||||
case 'U': /*FALLTHROUGH*/
|
||||
case 'u':
|
||||
p++;
|
||||
break;
|
||||
case 'C': /*FALLTHROUGH*/
|
||||
case 'L': /*FALLTHROUGH*/
|
||||
case 'c': /*FALLTHROUGH*/
|
||||
case 'l':
|
||||
p++;
|
||||
|
||||
/* get past space */
|
||||
while ((*p == ' ') || (*p == '\t') && *p) p++;
|
||||
if (!*p) return bad_line;
|
||||
|
||||
/* get past command or language number */
|
||||
while (isdigit(*p)) p++;
|
||||
|
||||
break;
|
||||
default:
|
||||
return bad_line;
|
||||
break;
|
||||
}
|
||||
|
||||
/* get past any remaining space */
|
||||
while ((*p == ' ') || (*p == '\t')) p++;
|
||||
if (!*p) return bad_line;
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* orcacommand -- returns the command name that starts the buffer.
|
||||
* This _must_ be called after orcacomment because it
|
||||
* modifies the buffer.
|
||||
*/
|
||||
|
||||
static char *orcacommand(char *buffer) {
|
||||
char *p;
|
||||
|
||||
p = buffer;
|
||||
while (*p && !isspace(*p)) p++;
|
||||
*p = '\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/*
|
||||
* apropos -- print matching lines from WHATIS database. Returns the
|
||||
* number of matching lines, or -1 on error.
|
||||
*
|
||||
* Argv is an array of argc strings, each of which is a keyword.
|
||||
* Apropos will print out any line that matches any of the
|
||||
* keywords in argv. The match algorithm depends on the value
|
||||
* of apropos_mode, which may be one of the following. For the
|
||||
* first three modes, global variable <manpath> must be set.
|
||||
*
|
||||
* MAN_K_MODE -- this is the one used by apropos(1). A
|
||||
* match is considered to be made if the keyword
|
||||
* appears anywhere in the WHATIS database line.
|
||||
* The match is case insensitive.
|
||||
*
|
||||
* MAN_F_MODE -- Any leading path component is stripped from
|
||||
* the keywords, and then a match is attempted
|
||||
* for any part of the WHATIS database line. The
|
||||
* match is case insensitive.
|
||||
*
|
||||
* WHATIS_MODE -- The WHATIS database line is parsed up to the
|
||||
* first occurance of a '(' character. If any
|
||||
* of the keywords are found, then the line is
|
||||
* printed. The search is case sensitive.
|
||||
*
|
||||
* ORCA_K_MODE -- Like MAN_K_MODE but instead of checking
|
||||
* the various WHATIS databases, it checks
|
||||
* 15/syscmnd.
|
||||
*
|
||||
* ORCA_W_MODE -- Like WHATIS_MODE but instead of checking
|
||||
* the various WHATIS databases, it checks
|
||||
* 15/syscmnd.
|
||||
*
|
||||
* WARNING: Use of the MAN_F_MODE may alter the contents of argv[].
|
||||
*/
|
||||
|
||||
int apropos(int argc, char **argv, int apropos_mode) {
|
||||
char **manpath_array;
|
||||
char *current_path, *p, *q, *r, *keyword;
|
||||
FILE *fp;
|
||||
char dirbrk;
|
||||
int i, j, matches;
|
||||
|
||||
#ifdef DEBUG
|
||||
assert ((apropos_mode == WHATIS_MODE) ||
|
||||
(apropos_mode == MAN_K_MODE) ||
|
||||
(apropos_mode == MAN_F_MODE) ||
|
||||
(apropos_mode == ORCA_K_MODE) ||
|
||||
(apropos_mode == ORCA_F_MODE) ||
|
||||
(apropos_mode == ORCA_W_MODE));
|
||||
#endif
|
||||
|
||||
matches = 0;
|
||||
|
||||
/*
|
||||
* if we're doing 'man -f', get the basename for all keywords
|
||||
*/
|
||||
if ((apropos_mode == MAN_F_MODE) || (apropos_mode == ORCA_F_MODE)) {
|
||||
for (i=0; i<argc; i++) {
|
||||
dirbrk = (strchr(argv[i],':')!=NULL) ? ':' : '/';
|
||||
if ((q = strrchr(argv[i],dirbrk)) != NULL) {
|
||||
q++;
|
||||
p = argv[i];
|
||||
do {
|
||||
*p = *q;
|
||||
p++; q++;
|
||||
} while (*q);
|
||||
*p = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((apropos_mode == ORCA_K_MODE) ||
|
||||
(apropos_mode == ORCA_W_MODE) ||
|
||||
(apropos_mode == ORCA_F_MODE)) {
|
||||
|
||||
/*
|
||||
* searching the Orca 15/syscmnd file
|
||||
*/
|
||||
|
||||
if ((fp = fopen(SYSCMND,"r")) == NULL) {
|
||||
fprintf(stderr,"couldn't open %s\n",SYSCMND);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* loop over lines in file */
|
||||
while ((q = fgets(linebuf,BUFFERSIZE,fp)) != NULL) {
|
||||
if (*linebuf == ';') continue;
|
||||
|
||||
/* loop over keywords */
|
||||
for(i=0; i<argc; i++) {
|
||||
keyword = argv[i];
|
||||
if ((apropos_mode == ORCA_K_MODE && ncstrstr(linebuf,keyword)) ||
|
||||
(apropos_mode == ORCA_F_MODE && strstr(linebuf,keyword)) ||
|
||||
(apropos_mode == ORCA_W_MODE &&
|
||||
!strncmp(linebuf,keyword,strlen(keyword)))) {
|
||||
r = orcacomment(linebuf);
|
||||
p = orcacommand(linebuf);
|
||||
q = orcapadding(p);
|
||||
printf("%s (Orca) %s- %s",p,q,r);
|
||||
matches++;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return matches;
|
||||
}
|
||||
|
||||
if ((manpath_array = makePathArray(manpath)) == NULL) return -1;
|
||||
|
||||
/*
|
||||
* loop over all the paths in MANPATH
|
||||
*/
|
||||
i=0;
|
||||
current_path = manpath_array[i];
|
||||
while (current_path) {
|
||||
|
||||
dirbrk = (strchr(current_path,':')!=NULL) ? ':' : '/';
|
||||
if (chdir(current_path) == -1) {
|
||||
fprintf(stderr,"%s: %s\n",current_path,strerror(errno));
|
||||
} else if ((fp=fopen(WHATIS,"r"))==NULL) {
|
||||
if (access(WHATIS,F_OK) == -1) {
|
||||
fprintf(stderr,"%s%c%s: %s\n",current_path,dirbrk,WHATIS,
|
||||
strerror(ENOENT));
|
||||
} else {
|
||||
fprintf(stderr,"error opening %s%c%s\n",current_path,dirbrk,
|
||||
WHATIS);
|
||||
}
|
||||
} else {
|
||||
/* read each line, looking for a match */
|
||||
for (;;) {
|
||||
q = fgets(linebuf,BUFFERSIZE,fp);
|
||||
if (q != NULL) {
|
||||
|
||||
/* search for a match to any keyword */
|
||||
for (j=0; j<argc; j++) {
|
||||
keyword = argv[j];
|
||||
switch (apropos_mode) {
|
||||
case MAN_F_MODE:
|
||||
if (strstr(linebuf,keyword)) {
|
||||
printf("%s",linebuf);
|
||||
matches++;
|
||||
}
|
||||
break;
|
||||
case MAN_K_MODE:
|
||||
if (ncstrstr(linebuf,keyword)) {
|
||||
printf("%s",linebuf);
|
||||
matches++;
|
||||
}
|
||||
break;
|
||||
case WHATIS_MODE:
|
||||
/* avoid unnecessary strcpy's */
|
||||
if (strstr(linebuf,keyword)==NULL) break;
|
||||
strcpy(linebuf2,linebuf);
|
||||
if ((p = strchr(linebuf2,'(')) != NULL) *p = '\0';
|
||||
if (strstr(linebuf2,keyword)) {
|
||||
printf("%s",linebuf);
|
||||
matches++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"internal error line %d of %s\n",
|
||||
__LINE__,__FILE__);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
} else if (ferror(fp)) {
|
||||
fprintf(stderr,"error reading %s database: %s\n",WHATIS,
|
||||
strerror(errno));
|
||||
break;
|
||||
} else break;
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
i++;
|
||||
current_path = manpath_array[i];
|
||||
} /* endwhile loop over directories */
|
||||
|
||||
return matches;
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
.\" Copyright (c) 1995 Devin Reade <gdr@myrias.com>. All rights reserved.
|
||||
.\"
|
||||
.TH CATMAN 8 "System Administration" "24 July 95" "Version 1.0"
|
||||
.SH NAME
|
||||
catman \- format cat pages from man pages
|
||||
.SH SYNOPSIS
|
||||
.BR catman
|
||||
[
|
||||
.B -pvV
|
||||
] [[
|
||||
.BI -M path
|
||||
] | [
|
||||
.BI -m path
|
||||
]] [
|
||||
.IR section " ..."
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.BR catman
|
||||
creates formatted versions of the on-line manual pages from their
|
||||
.BR nroff (1)
|
||||
or
|
||||
.BR aroff (1)
|
||||
source.
|
||||
Manual pages whose formatted versions are missing or out of date are
|
||||
regenerated.
|
||||
.LP
|
||||
If
|
||||
.IR section
|
||||
is specified, then
|
||||
.BR catman
|
||||
will only created formatted manual pages for the specified
|
||||
.IR section (s).
|
||||
.LP
|
||||
Manual pages that are
|
||||
.BR nroff (1)
|
||||
source and are compressed with either
|
||||
.BR compress (1),
|
||||
.BR freeze (1),
|
||||
or
|
||||
.BR gzip (1)
|
||||
are recognised provided that they have the suffixes
|
||||
.BR ".Z" ,
|
||||
.BR ".F" ,
|
||||
and
|
||||
.BR ".gz" ,
|
||||
respectively. Manual page names, including suffixes, are case sensitive.
|
||||
.LP
|
||||
Preformatted manual pages will be created in
|
||||
.BI cat ?
|
||||
only if that subdirectory exists.
|
||||
.SH OPTIONS
|
||||
.IP \fB-p\fP
|
||||
Display the commands that would have been executed, but do not actually
|
||||
execute them.
|
||||
.IP "\fB-M\fR \fIpath\fR"
|
||||
Set
|
||||
.I path
|
||||
to be the list of paths for which manual pages will be updated.
|
||||
If not set, the value of
|
||||
.BR MANPATH ,
|
||||
.BR USRMAN ,
|
||||
or
|
||||
.BR MANDIR
|
||||
will be used instead. Multiple directories may be specified by
|
||||
separating them either by colons or by spaces. In the latter case,
|
||||
be sure to quote
|
||||
.I path
|
||||
from the shell.
|
||||
.IP "\fB-m\fR \fIpath\fR"
|
||||
Append
|
||||
.I path
|
||||
on to the list of paths for which manual pages will be updated.
|
||||
.IP \fB-V\fR
|
||||
Display version information and exit.
|
||||
.IP \fB-v\fR
|
||||
Verbose. Show processing information.
|
||||
.SH BUGS
|
||||
Please report any bugs to Devin Reade, <gdr@myrias.ab.ca>.
|
||||
.SH SEE ALSO
|
||||
.BR apropos (1),
|
||||
.BR man (1),
|
||||
.BR whatis (1),
|
||||
.BR gzip (1),
|
||||
.BR compress (1),
|
||||
.BR freeze (1),
|
||||
.BR makewhatis (8).
|
||||
.SH WARNING
|
||||
.BR catman
|
||||
will unlink any out-of-date files in the
|
||||
.BI cat ?
|
||||
subdirectories. The files that would be unlinked are listed when
|
||||
.BR catman
|
||||
is invoked with the
|
||||
.BR -p
|
||||
option.
|
|
@ -1,356 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995 by Devin Reade <gdr@myrias.com>. For distribution
|
||||
* information see the README file that is part of the manpack archive,
|
||||
* or contact the author, above.
|
||||
*/
|
||||
|
||||
segment "catman____";
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <libc.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include "util.h"
|
||||
#include "man.h"
|
||||
|
||||
#define OVERFLOW_ABORT(line,file) { \
|
||||
fprintf(stderr,overflowMsg,line,file); \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
short v_flag, V_flag, M_flag, m_flag, p_flag, err_flag;
|
||||
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
static char *versionstr = "1.0";
|
||||
|
||||
/* This is of the form "man<section>" */
|
||||
char mandir[FILENAME_MAX];
|
||||
|
||||
/*
|
||||
* These are of the form
|
||||
* "(man|cat)<section>/<name>.<section>[.<compression_suffix>]"
|
||||
*/
|
||||
char manfile[FILENAME_MAX];
|
||||
char catfile[FILENAME_MAX];
|
||||
char catfile2[FILENAME_MAX];
|
||||
|
||||
char base[FILENAME_MAX];
|
||||
|
||||
static char *overflowMsg = "internal buffer overflow at line %d of %s\n";
|
||||
|
||||
extern void begin_stack_check(void);
|
||||
extern int end_stack_check(void);
|
||||
|
||||
/*
|
||||
* catman
|
||||
*
|
||||
* Pre: argv is an array of section numbers (character strings), possibly
|
||||
* empty.
|
||||
* argc is the number of entries in argv.
|
||||
* global variable <manpath> is a space- or colon-delimited list
|
||||
* of pathnames.
|
||||
*
|
||||
* Post: for each pathname in <manpath>, catman will preformat the manpages
|
||||
* within the man* subdirectories and place the result in the
|
||||
* corresponding cat* subdirectory. If section numbers are specified,
|
||||
* only those sections will be done.
|
||||
*
|
||||
* Returns 0 on success, 1 on failure.
|
||||
*/
|
||||
|
||||
int catman(int argc, char **argv) {
|
||||
|
||||
char **manpath_array; /* MANPATH components in array form */
|
||||
char *current_path; /* the current MANPATH component */
|
||||
int i; /* an index */
|
||||
int pathIndex; /* offset into manpath_array[] */
|
||||
int sectionIndex; /* offset into sections[] */
|
||||
DIR *manp, *catp; /* directory pointers */
|
||||
struct dirent *entp; /* current file entry in manp */
|
||||
char *sec; /* the current section "number" */
|
||||
int catfile_found; /* have we found a preformatted version */
|
||||
/* that's newer than the unformatted version? */
|
||||
fileType *ftype; /* the file type of the man page */
|
||||
struct stat statbuf1, statbuf2;
|
||||
char dirbrk;
|
||||
|
||||
/* create array of paths to search */
|
||||
if ((manpath_array = makePathArray(manpath)) == NULL) return 1;
|
||||
|
||||
/* loop over paths in MANPATH */
|
||||
pathIndex=0;
|
||||
current_path = manpath_array[pathIndex];
|
||||
while(current_path) {
|
||||
|
||||
dirbrk = (strchr(current_path,':')==NULL) ? '/' : ':';
|
||||
|
||||
/* go to the current path in MANPATH */
|
||||
if (v_flag) printf("cd %s\n",current_path);
|
||||
if (chdir(current_path) == -1) {
|
||||
pathIndex++;
|
||||
current_path = manpath_array[pathIndex];
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* loop over sections */
|
||||
for (sectionIndex=0; sections[sectionIndex].name!=NULL; sectionIndex++){
|
||||
|
||||
/*
|
||||
* if section number was specified and this isn't it, do
|
||||
* the next loop
|
||||
*/
|
||||
if (argc > 0) {
|
||||
sec = NULL;
|
||||
for (i=0; i<argc; i++) {
|
||||
if (!strcmp(argv[i],sections[sectionIndex].name)) {
|
||||
sec = argv[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sec == NULL) continue;
|
||||
} else sec = sections[sectionIndex].name;
|
||||
|
||||
#ifdef DEBUG
|
||||
assert(sec);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* we're going to update this section. Open the man? subdir
|
||||
*/
|
||||
|
||||
if (strlen(sec) + 3 >= FILENAME_MAX) {
|
||||
OVERFLOW_ABORT(__LINE__,__FILE__);
|
||||
}
|
||||
sprintf(mandir,"man%s",sec);
|
||||
if ((manp = opendir(mandir)) == NULL) continue;
|
||||
|
||||
/* make sure the cat? directory exists, but leave it closed */
|
||||
sprintf(catfile,"cat%s",sec);
|
||||
if ((catp = opendir(catfile)) == NULL) {
|
||||
closedir(manp);
|
||||
continue;
|
||||
} else {
|
||||
closedir(catp);
|
||||
}
|
||||
|
||||
/* loop over files in this section */
|
||||
while ((entp = readdir(manp)) != NULL) {
|
||||
|
||||
/* skip standard file entries */
|
||||
if (!strcmp(entp->d_name,".") || !strcmp(entp->d_name,"..")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* make the base the name of the man? entry excluding
|
||||
* any compression suffix
|
||||
*/
|
||||
strcpy(base,entp->d_name);
|
||||
for (i=0; compressArray[i].suffix != NULL; i++) {
|
||||
size_t len1, len2;
|
||||
|
||||
len1 = strlen(compressArray[i].suffix);
|
||||
len2 = strlen(base);
|
||||
if (!strcmp(compressArray[i].suffix,
|
||||
(char *)(base + len2 - len1))) {
|
||||
*(base + len2 - len1) = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* set manfile and catfile properly
|
||||
*/
|
||||
|
||||
sprintf(manfile,"man%s%c%s",sec,dirbrk,entp->d_name);
|
||||
sprintf(catfile,"cat%s%c%s",sec,dirbrk,base);
|
||||
|
||||
if (stat(manfile,&statbuf1) != 0) {
|
||||
fprintf(stderr,"stat on %s failed: %s: file skipped\n",
|
||||
manfile, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* search for an uncompressed file in the cat? directory,
|
||||
* unlinking any older files.
|
||||
*/
|
||||
catfile_found=0;
|
||||
if (stat(catfile,&statbuf2) == 0) {
|
||||
if (statbuf1.st_mtime <= statbuf2.st_mtime) {
|
||||
catfile_found++;
|
||||
} else {
|
||||
if (v_flag) printf("rm %s%c%s\n",current_path,dirbrk,catfile);
|
||||
if (!p_flag) unlink(catfile);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* search for any compressed files in the cat? directory,
|
||||
* unlinking any older files.
|
||||
*/
|
||||
for(i=0;compressArray[i].suffix != NULL; i++) {
|
||||
sprintf(catfile2,"cat%s%c%s%s",sec,dirbrk,base,
|
||||
compressArray[i].suffix);
|
||||
if (stat(catfile2,&statbuf2) == 0) {
|
||||
if ((!catfile_found) &&
|
||||
(statbuf1.st_mtime <= statbuf2.st_mtime)) {
|
||||
strcpy(catfile,catfile2);
|
||||
catfile_found++;
|
||||
} else {
|
||||
if (v_flag)
|
||||
printf("rm %s%c%s\n",current_path,dirbrk,catfile2);
|
||||
if (!p_flag) unlink(catfile2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (catfile_found) continue;
|
||||
|
||||
/*
|
||||
* If we got to this point, then we will be preformatting
|
||||
* the manual page. There is also no version of the man
|
||||
* page left in cat?.
|
||||
*/
|
||||
|
||||
sprintf(catfile,"cat%s%c%s",sec,dirbrk,base);
|
||||
i = getSuffixIndex(manfile);
|
||||
if (i >= 0) {
|
||||
if (strlen(compressArray[i].extractor) + strlen(manfile) +
|
||||
strlen(NROFF) + strlen(catfile) + 14 >= BUFFERSIZE) {
|
||||
OVERFLOW_ABORT(__LINE__,__FILE__);
|
||||
}
|
||||
sprintf(linebuf,"%s %s | %s -man - > %s",
|
||||
compressArray[i].extractor,manfile,NROFF,catfile);
|
||||
} else {
|
||||
|
||||
/* determine which roffer to use based on the file type */
|
||||
if ((ftype = getFileType(manfile)) == NULL) {
|
||||
fprintf(stderr,"getFileType failed for %s: %s\n",
|
||||
manfile,strerror(errno));
|
||||
continue;
|
||||
}
|
||||
if ((ftype->type == 0x50) && (ftype->auxtype == 0x8010)) {
|
||||
if (strlen(AROFF) + strlen(manfile) + strlen(catfile)
|
||||
>= BUFFERSIZE) {
|
||||
OVERFLOW_ABORT(__LINE__,__FILE__);
|
||||
}
|
||||
sprintf(linebuf,"%s %s > %s",AROFF,manfile,catfile);
|
||||
} else if ((ftype->type == TXT) || (ftype->type == BIN) ||
|
||||
(ftype->type == SRC) || (ftype->type == NON)) {
|
||||
if (strlen(NROFF) + strlen(manfile) + strlen(catfile)
|
||||
>= BUFFERSIZE) {
|
||||
OVERFLOW_ABORT(__LINE__,__FILE__);
|
||||
}
|
||||
sprintf(linebuf,"%s -man %s > %s",NROFF,manfile,catfile);
|
||||
} else {
|
||||
fprintf(stderr,"illegal file type for %s: file skipped\n",
|
||||
manfile);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (v_flag) printf("%s\n",linebuf);
|
||||
if (!p_flag) system(linebuf);
|
||||
} /* done looping over files */
|
||||
closedir(manp);
|
||||
} /* done looping over sections */
|
||||
|
||||
/* set up for the next component of MANPATH */
|
||||
pathIndex++;
|
||||
current_path = manpath_array[pathIndex];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
char *path;
|
||||
int i, result1, result2;
|
||||
|
||||
/* make sure Gno is running */
|
||||
if (needsgno()==0) {
|
||||
fprintf(stderr,"Requires Gno/ME\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
begin_stack_check();
|
||||
#endif
|
||||
|
||||
/* initialization */
|
||||
v_flag = V_flag = M_flag = m_flag = p_flag = err_flag = 0;
|
||||
result1 = result2 = 0;
|
||||
|
||||
/* parse command line and check usage */
|
||||
while((i = getopt(argc,argv,"M:m:pVv")) != EOF) {
|
||||
switch(i) {
|
||||
case 'M':
|
||||
if (m_flag) err_flag++;
|
||||
M_flag++;
|
||||
path = optarg;
|
||||
break;
|
||||
case 'm':
|
||||
if (M_flag) err_flag++;
|
||||
m_flag++;
|
||||
path = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
p_flag++;
|
||||
v_flag++;
|
||||
break;
|
||||
case 'V':
|
||||
V_flag++;
|
||||
break;
|
||||
case 'v':
|
||||
v_flag++;
|
||||
break;
|
||||
default:
|
||||
err_flag++;
|
||||
}
|
||||
}
|
||||
if (err_flag || V_flag) {
|
||||
fprintf(stderr,"%s version %s by Devin Reade\n",
|
||||
basename(argv[0]),versionstr);
|
||||
}
|
||||
if (err_flag) {
|
||||
fprintf(stderr,"Usage: %s [-pVv] [-M path] [-m path] [section ...]\n",
|
||||
basename(argv[0]));
|
||||
}
|
||||
if (err_flag || V_flag) return 1;
|
||||
|
||||
/* translate selected "sections" into something more understandable */
|
||||
for (i=optind; i<argc; i++) {
|
||||
if (!strcmp(argv[i],"local")) argv[i] = "l";
|
||||
if (!strcmp(argv[i],"new")) argv[i] = "n";
|
||||
if (!strcmp(argv[i],"old")) argv[i] = "o";
|
||||
if (!strcmp(argv[i],"public")) argv[i] = "p";
|
||||
}
|
||||
|
||||
/* do the search */
|
||||
if (M_flag) {
|
||||
manpath = path;
|
||||
} else {
|
||||
manpath = getManpath();
|
||||
}
|
||||
result1 = catman(argc-optind, &argv[optind]);
|
||||
if (!M_flag) free(manpath);
|
||||
if (m_flag) {
|
||||
manpath = path;
|
||||
result2 = catman(argc-optind, &argv[optind]);
|
||||
}
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
fprintf(stderr,"stack usage: %d bytes\n",end_stack_check());
|
||||
#endif
|
||||
|
||||
return (result1 || result2);
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995 by Devin Reade <gdr@myrias.com>. For distribution
|
||||
* information see the README file that is part of the manpack archive,
|
||||
* or contact the author, above.
|
||||
*/
|
||||
|
||||
segment "common____";
|
||||
|
||||
#include <types.h>
|
||||
#include <string.h>
|
||||
#include "man.h"
|
||||
|
||||
/*
|
||||
* getSuffixIndex
|
||||
*
|
||||
* return the index into compressArray of the appropriate
|
||||
* suffix/decompresser. If there is no match, return -1.
|
||||
*/
|
||||
|
||||
int getSuffixIndex(char *name) {
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
for (i=0; compressArray[i].suffix != NULL; i++) {
|
||||
p = strstr(name,compressArray[i].suffix);
|
||||
if (p && !*(p + strlen(compressArray[i].suffix))) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
Name: apropos
|
||||
Version: 3.0 (24 Jul 95)
|
||||
Author: Devin Reade.
|
||||
Contact: gdr@myrias.com
|
||||
Where: /usr/bin
|
||||
FTP: ftp.cco.caltech.edu, grind.isca.uiowa.edu
|
||||
|
||||
Locate commands by keyword. Bundled with catman, makewhatis,
|
||||
man, and whatis in the manpack30.shk archive.
|
||||
|
||||
Name: catman
|
||||
Version: 1.0 (24 Jul 95)
|
||||
Author: Devin Reade.
|
||||
Contact: gdr@myrias.com
|
||||
Where: /usr/sbin
|
||||
FTP: ftp.cco.caltech.edu, grind.isca.uiowa.edu
|
||||
|
||||
Preformat manual reference pages. Bundled with apropos, makewhatis,
|
||||
man, and whatis in the manpack30.shk archive.
|
||||
|
||||
Name: makewhatis
|
||||
Version: 1.2 (24 Jul 95)
|
||||
Author: Devin Reade.
|
||||
Contact: gdr@myrias.com
|
||||
Where: /usr/sbin
|
||||
FTP: ftp.cco.caltech.edu, grind.isca.uiowa.edu
|
||||
|
||||
Create the whatis database used by man(1), apropos(1), and whatis(1).
|
||||
Bundled with apropos, catman, man, and whatis in the manpack30.shk archive.
|
||||
|
||||
Name: man
|
||||
Version: 3.0 (24 Jul 95)
|
||||
Author: Devin Reade.
|
||||
Contact: gdr@myrias.com
|
||||
Where: /usr/bin
|
||||
FTP: ftp.cco.caltech.edu, grind.isca.uiowa.edu
|
||||
|
||||
Display manual reference pages. Bundled with apropos, catman,
|
||||
makewhatis, and whatis in the manpack30.shk archive.
|
||||
|
||||
Name: whatis
|
||||
Version: 3.0 (24 Jul 95)
|
||||
Author: Devin Reade.
|
||||
Contact: gdr@myrias.com
|
||||
Where: /usr/bin
|
||||
FTP: ftp.cco.caltech.edu, grind.isca.uiowa.edu
|
||||
|
||||
Locate commands by name. Bundled with apropos, catman,
|
||||
makewhatis, and man in the manpack30.shk archive.
|
||||
|
|
@ -1,38 +1,14 @@
|
|||
/*
|
||||
* Copyright 1995 by Devin Reade <gdr@myrias.com>. For distribution
|
||||
* information see the README file that is part of the manpack archive,
|
||||
* or contact the author, above.
|
||||
*/
|
||||
|
||||
segment "makewhatis";
|
||||
#ifdef __CCFRONT__
|
||||
#include <14:pragma.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "makewhatis.h"
|
||||
|
||||
#define NAME1 "NAME"
|
||||
#define NAME2 "N\bNA\bAM\bME\bE"
|
||||
#define NAME3 "N\bN\bN\bNA\bA\bA\bAM\bM\bM\bME\bE\bE\bE"
|
||||
#define SYNOPSIS1 "SYNOPSIS"
|
||||
#define SYNOPSIS2 "S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS"
|
||||
#define SYNOPSIS3 "S\bS\bS\bSY\bY\bY\bYN\bN\bN\bNO\bO\bO\bOP\bP\bP\bPS\bS\bS\bSI\bI\bI\bIS\bS\bS\bS"
|
||||
#define DESCRIPTION1 "DESCRIPTION"
|
||||
#define DESCRIPTION2 "D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN"
|
||||
#define DESCRIPTION3 "D\bD\bD\bDE\bE\bE\bES\bS\bS\bSC\bC\bC\bCR\bR\bR\bRI\bI\bI\bIP\bP\bP\bPT\bT\bT\bTI\bI\bI\bIO\bO\bO\bON\bN\bN\bN"
|
||||
|
||||
char buffer[BUFFERSIZE]; /* contains the command description */
|
||||
char titlebuf[BUFFERSIZE]; /* contains the command name */
|
||||
static char buffer2[BUFFERSIZE]; /* used for chars read from man page */
|
||||
|
||||
#ifdef TEST_FILLBUFFER
|
||||
short v_flag=2;
|
||||
# define output_fp stdout
|
||||
# define error_fp stderr
|
||||
#else
|
||||
extern FILE *output_fp; /* output file descriptor -- may be stdout */
|
||||
extern FILE *error_fp; /* error file descriptor -- may be stderr */
|
||||
#endif
|
||||
char buffer[BUFFERSIZE];
|
||||
static char buffer2[BUFFERSIZE];
|
||||
|
||||
/* void fillbuffer (char *filename);
|
||||
*
|
||||
|
@ -43,312 +19,101 @@ static char buffer2[BUFFERSIZE]; /* used for chars read from man page */
|
|||
*
|
||||
* 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. <titlebuf>
|
||||
* will contain all printable text starting with the first printable
|
||||
* non-whitespace character following "NAME" and ending with the
|
||||
* last printable character before the first '-' following "NAME".
|
||||
* "SYNOPSIS", or "DESCRIPTION", whichever comes first.
|
||||
*
|
||||
* If an error occurs, <buffer> will be an empty string (ie:
|
||||
* buffer[0] == '\0')
|
||||
*
|
||||
* Warning: This routine was written to be fast at the expense of code
|
||||
* size. It also has a lot of "special case"ing since it could
|
||||
* be fed nroff source, aroff'd output, or text files that may
|
||||
* include formatting control codes. If you're looking for some
|
||||
* nice neat code, you're not going to find it here.
|
||||
*/
|
||||
|
||||
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 */
|
||||
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 */
|
||||
char *p6; /* scratch */
|
||||
short found; /* some flags */
|
||||
short in_comment;
|
||||
char *p3; /* points to current char in buffer */
|
||||
short found; /* some flags */
|
||||
short in_comment;
|
||||
short in_format_BR;
|
||||
short in_format_f;
|
||||
short foo;
|
||||
|
||||
/*
|
||||
* Set p4 and p5 to the ends of buffer and titlebuf, respectively.
|
||||
* These are used for error checking, so that we don't overflow the
|
||||
* buffers. Using pointers will speed things up a bit at the cost
|
||||
* of four bytes of local storage. They are not global for the sake
|
||||
* of speed.
|
||||
*/
|
||||
|
||||
char *p4 = buffer + BUFFERSIZE;
|
||||
char *p5 = titlebuf + BUFFERSIZE;
|
||||
|
||||
/*
|
||||
/*
|
||||
* open the file
|
||||
*/
|
||||
|
||||
if ((fp = fopen(filename,"rb")) == NULL) {
|
||||
buffer[0] = '\0';
|
||||
if (v_flag) fprintf (error_fp,"Open failed for file \"%s\"\n",filename);
|
||||
buffer[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* see if it includes another man page
|
||||
*/
|
||||
if ((fgets(buffer2,4,fp) == NULL) || (strncmp(buffer2,".so",3)==0)) {
|
||||
buffer[0] = '\0';
|
||||
titlebuf[0] = '\0';
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
fseek(fp,0L,SEEK_SET);
|
||||
|
||||
/*
|
||||
* Make fp point to the first newline following NAME so that the
|
||||
* next block read will pick it up as the first character. This is
|
||||
* needed for the next section of code following this one.
|
||||
* 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(;;) {
|
||||
|
||||
/*
|
||||
* read in buffer2 in a line-oriented fashion at first so that we
|
||||
* can more easily ignore .\" and .TH lines
|
||||
*/
|
||||
|
||||
if (fgets(buffer2,BUFFERSIZE,fp)==NULL) {
|
||||
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';
|
||||
titlebuf[0] = '\0';
|
||||
fclose(fp);
|
||||
if (v_flag) fprintf (error_fp,
|
||||
"EOF or error on %s, NAME not found.\n",filename);
|
||||
return;
|
||||
}
|
||||
|
||||
/* ignore comment lines and any .TH line(s) */
|
||||
if ((strncmp(buffer2,".\\\"",3)==0) || (strncmp(buffer2,".TH",3)==0))
|
||||
continue;
|
||||
|
||||
/* check the various versions of "NAME" */
|
||||
if (strstr(buffer2,NAME1) != NULL) break;
|
||||
if (strstr(buffer2,NAME2) != NULL) break;
|
||||
if (strstr(buffer2,NAME3) != NULL) break;
|
||||
}
|
||||
|
||||
|
||||
/* we need the previous newline for the next algorithm to work */
|
||||
fseek(fp,-1L,SEEK_CUR);
|
||||
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.
|
||||
*
|
||||
* Also copy selected chars to titlebuf until the first '-' is found.
|
||||
*/
|
||||
|
||||
p3 = titlebuf;
|
||||
found = 0; /* set this when we find '-' */
|
||||
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 */
|
||||
foo = 0; /* haven't found the printable character after NAME */
|
||||
for(;;) {
|
||||
|
||||
/* read another block into buffer2. */
|
||||
|
||||
count = fread(buffer2,sizeof(char),BUFFERSIZE-1,fp);
|
||||
for(;;) {
|
||||
p2 = strchr(p1,'-');
|
||||
if (p2 != NULL) {
|
||||
p2++;
|
||||
break;
|
||||
}
|
||||
count = fread(buffer2,sizeof(char),BUFFERSIZE-1,fp);
|
||||
if (count == 0) {
|
||||
/* eof or error; empty buffer and titlebuf then return */
|
||||
buffer[0] = '\0';
|
||||
titlebuf[0] = '\0';
|
||||
fclose(fp);
|
||||
if (v_flag) fprintf (error_fp,
|
||||
"EOF or error on %s, command name not found.\n",filename);
|
||||
return;
|
||||
/*
|
||||
* eof or error, and we haven't found '-' yet ... return
|
||||
* an empty string
|
||||
*/
|
||||
buffer[0] = '\0';
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
buffer2[count] = '\0';
|
||||
buffer2[count] = '\0';
|
||||
p1 = buffer2;
|
||||
|
||||
/* mark the "end" of buffer2 with p2 */
|
||||
if ((p2 = strchr(p1,'-')) != 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 key words, p2
|
||||
* to either the end of the key words or the end of buffer2,
|
||||
* and p3 into the spot in titlebuf where the next character should
|
||||
* be put.
|
||||
*
|
||||
* Copy *p1 to *p3 while p1<p2 (not at end of titlebuf or key words),
|
||||
* 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;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* skip .BR-type formatting */
|
||||
if ((p1<p2) && (*p1=='\r') && (*(p1+1)=='.')) {
|
||||
p1++;
|
||||
while ((p1<p2) && !isspace(*p1)) p1++;
|
||||
if (p1==p2) in_format_BR = 1;
|
||||
else --p1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* skip whitespace if we haven't got the beginning of the
|
||||
* description yet.
|
||||
*/
|
||||
|
||||
#ifdef ISGRAPH_FIX
|
||||
if (isgraph(*p1) && (*p1!=' ')) foo=1;
|
||||
if (!foo) {
|
||||
while ((p1<p2) && !(isgraph(*p1) && (*p1!=' '))) p1++;
|
||||
if ((*p1=='.') && (*(p1-1)=='\r')) p1 -=2;
|
||||
else --p1;
|
||||
continue;
|
||||
}
|
||||
#else
|
||||
if (isgraph(*p1)) foo=1;
|
||||
if (!foo) {
|
||||
while ((p1<p2) && !isgraph(*p1)) p1++;
|
||||
if ((*p1=='.') && (*(p1-1)=='\r')) p1 -=2;
|
||||
else --p1;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* at this point, *p1 is either a control char or something that
|
||||
* we want in titlebuf, assuming that p1<p2.
|
||||
*/
|
||||
|
||||
if ((p1<p2) && !iscntrl(*p1)) {
|
||||
|
||||
/*
|
||||
* The conditional below means:
|
||||
* Copy it so that: 1. There is only one space between words; and
|
||||
* 2. The buffer doesn't begin with a space.
|
||||
*/
|
||||
|
||||
if ( !((p3>titlebuf) && (*p1 == ' ') && (*(p3-1) == ' ')) &&
|
||||
!((p3==titlebuf) && (*p3 == ' '))
|
||||
) {
|
||||
|
||||
/* don't let a space precede a comma */
|
||||
if ((*p1==',') && (*(p3-1)==' ')) {
|
||||
*(p3-1) = ',';
|
||||
continue;
|
||||
} else *p3++ = *p1;
|
||||
if (p3>=p5) { /* titlebuf overflow? */
|
||||
if (v_flag)
|
||||
fprintf(error_fp,"command name buffer overflow on %s\n",
|
||||
filename);
|
||||
buffer[0] = '\0';
|
||||
titlebuf[0] = '\0';
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found) { /* we've got all of the key words */
|
||||
p3--; /* p3 now points to last char, not terminator */
|
||||
if (*p3=='\\') p3--;
|
||||
while(isspace(*p3)) p3--;
|
||||
*(p3+1) = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
p1 = p2 + 1;
|
||||
#ifdef ISGRAPH_FIX
|
||||
while ( (p1 < buffer2 + BUFFERSIZE) &&!(isgraph(*p1) && (*p1 != ' '))) p1++;
|
||||
#else
|
||||
while ((p1 < buffer2 + BUFFERSIZE) && !isgraph(*p1)) p1++;
|
||||
#endif
|
||||
|
||||
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 */
|
||||
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,SYNOPSIS1)) != NULL) ||
|
||||
((p2 = strstr(p1,SYNOPSIS2)) != NULL) ||
|
||||
((p2 = strstr(p1,SYNOPSIS3)) != NULL) ||
|
||||
((p2 = strstr(p1,DESCRIPTION1)) != NULL) ||
|
||||
((p2 = strstr(p1,DESCRIPTION2)) != NULL) ||
|
||||
((p2 = strstr(p1,DESCRIPTION3)) != NULL)
|
||||
((p2 = strstr(p1,"SYNOPSIS")) != NULL) ||
|
||||
((p2 = strstr(p1,"DESCRIPTION")) != NULL)
|
||||
) {
|
||||
*p2 = '\0';
|
||||
/*
|
||||
* this conditional is to cover the wierd case of having the word
|
||||
* "SYNOPSIS" appearing in the description (or elsewhere), as
|
||||
* it does for the GNO Intro(1) man page. Blech. Only in
|
||||
* aroff source or a preformatted page would this matter.
|
||||
*/
|
||||
if (((p6 = strstr(p1,SYNOPSIS1)) != NULL) ||
|
||||
((p6 = strstr(p1,DESCRIPTION1)) != NULL)) {
|
||||
p2 = p6;
|
||||
}
|
||||
found = 1;
|
||||
found = 1;
|
||||
} else {
|
||||
p2 = buffer + count;
|
||||
p2 = buffer + count;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -357,17 +122,17 @@ void fillbuffer (char *filename) {
|
|||
*/
|
||||
|
||||
if (in_comment) {
|
||||
while((p1<p2) && (*p1 != '\r')) p1++;
|
||||
while((p1<p2) && (*p1 != '\r')) p1++;
|
||||
in_comment = 0;
|
||||
}
|
||||
|
||||
if (in_format_BR) {
|
||||
while ((p1<p2) && !isspace(*p1)) p1++;
|
||||
while ((p1<p2) && !isspace(*p1)) p1++;
|
||||
in_format_BR = 0;
|
||||
}
|
||||
|
||||
if (in_format_f) {
|
||||
p1 = p1 + 3 - in_format_f;
|
||||
p1 = p1 + 3 - in_format_f;
|
||||
in_format_f = 0;
|
||||
}
|
||||
|
||||
|
@ -383,26 +148,25 @@ void fillbuffer (char *filename) {
|
|||
|
||||
for (; p1<p2; p1++) {
|
||||
|
||||
/* skip .\" comments */
|
||||
/* skip .\" comments */
|
||||
if (strncmp(p1,"\r.\\\"",4) == 0) {
|
||||
while ((p1<p2) && (*p1!='\r')) p1++;
|
||||
while ((p1<p2) && (*p1!='\r')) p1++;
|
||||
if (p1==p2) in_comment = 1;
|
||||
}
|
||||
|
||||
/* skip .BR-type formatting */
|
||||
if ((p1<p2) && (*p1=='\r') && (*(p1+1)=='.')) {
|
||||
p1++;
|
||||
while ((p1<p2) && !isspace(*p1)) p1++;
|
||||
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;
|
||||
if ((p1<p2) && (*p1=='\\') && (*(p1+1)=='f')) {
|
||||
if ((p1 + 3) < p2) {
|
||||
p1 += 3;
|
||||
} else {
|
||||
in_format_f = p2 - p1;
|
||||
p1 = p2;
|
||||
in_format_f = p2 - p1;
|
||||
p1 = p2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -411,55 +175,30 @@ void fillbuffer (char *filename) {
|
|||
* we want in buffer, assuming that p1<p2.
|
||||
*/
|
||||
|
||||
if ((p1<p2) && !iscntrl(*p1)) {
|
||||
|
||||
/*
|
||||
* The conditional below means:
|
||||
* Copy it so that: 1. There is only one space between words; and
|
||||
* 2. The buffer doesn't begin with a space.
|
||||
*/
|
||||
|
||||
if ( !((p3>buffer) && (*p1 == ' ') && (*(p3-1) == ' ')) &&
|
||||
!((p3==buffer) && (*p3 == ' '))
|
||||
) {
|
||||
*p3++ = *p1;
|
||||
if (p3>=p4) { /* buffer overflow? */
|
||||
if (v_flag)
|
||||
fprintf(error_fp,"command description buffer overflow on %s\n",
|
||||
filename);
|
||||
buffer[0] = '\0';
|
||||
titlebuf[0] = '\0';
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((p1<p2) && !iscntrl(*p1)) *p3++ = *p1;
|
||||
}
|
||||
|
||||
if (found) { /* we've got the entire description */
|
||||
*p3 = '\0';
|
||||
break;
|
||||
|
||||
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);
|
||||
count = fread(buffer2,sizeof(char),BUFFERSIZE-1,fp);
|
||||
if (count == 0) {
|
||||
/* eof or error; terminate buffer and return */
|
||||
*p3 = '\0';
|
||||
fclose(fp);
|
||||
if (v_flag) fprintf (error_fp,
|
||||
"EOF or error on %s, description not found.\n",filename);
|
||||
return;
|
||||
*p3 = '\0';
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
buffer2[count] = '\0';
|
||||
p1 = buffer2;
|
||||
|
||||
}
|
||||
|
||||
p1 = buffer2;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* close the file
|
||||
*/
|
||||
|
@ -468,3 +207,26 @@ void fillbuffer (char *filename) {
|
|||
|
||||
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
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995 by Devin Reade <gdr@myrias.com>. For distribution
|
||||
* information see the README file that is part of the manpack archive,
|
||||
* or contact the author, above.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
#include "man.h"
|
||||
|
||||
/*
|
||||
* The compression suffixes and how to uncompress the files.
|
||||
* If you use ".l" (that's "ell") as a suffix, you will break the
|
||||
* algorithm for dereferencing aroff "links".
|
||||
*/
|
||||
|
||||
compressionType compressArray[] = {
|
||||
{ ".Z", "compress -cd" },
|
||||
{ ".F", "freeze -cd" },
|
||||
{ ".gz", "gzip -cd" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
char linebuf[BUFFERSIZE];
|
||||
char linebuf2[BUFFERSIZE];
|
||||
char *manpath;
|
||||
|
||||
Section sections[] = {
|
||||
{ "1", "1" },
|
||||
{ "2", "2" },
|
||||
{ "3", "3" },
|
||||
{ "3f", "3f" },
|
||||
{ "4", "4" },
|
||||
{ "5", "5" },
|
||||
{ "6", "6" },
|
||||
{ "7", "7" },
|
||||
{ "8", "8" },
|
||||
{ "new", "n" }, /* the words "new", "local", "public", */
|
||||
{ "local", "l" }, /* and "old" can be abbreviated on the */
|
||||
{ "public", "p" }, /* command line with "n", "l", "p", and */
|
||||
{ "old", "o" }, /* "o", respectively */
|
||||
{ NULL, NULL } /* MUST be NULL-terminated! */
|
||||
};
|
|
@ -1,70 +1,47 @@
|
|||
#
|
||||
# Makefile for the man package, for use with dmake(1).
|
||||
# Makefile for dmake(1)
|
||||
#
|
||||
|
||||
# Location for executables. They should normally be /usr/sbin and /usr/bin.
|
||||
# Location for executable. It should be /usr/sbin
|
||||
|
||||
SBINDIR = /usr/sbin
|
||||
BINDIR = /usr/bin
|
||||
BINDIR = /usr/sbin
|
||||
|
||||
# Location for man pages. Usually /usr/man.
|
||||
# Location for man pages.
|
||||
|
||||
MANDIR = /usr/man
|
||||
MANDIR = /usr/man
|
||||
|
||||
#
|
||||
# You should not have to change anything below this line
|
||||
#
|
||||
# Define: -DDEBUG to produce more debugging info and checks
|
||||
#
|
||||
# -DSTACK_CHECK to show stack usage. If you use this
|
||||
# one, ensure you add -l/usr/lib/stack to your LDLIBS.
|
||||
# Nothing past this point should have to be changed
|
||||
#
|
||||
|
||||
STACK = -s1270
|
||||
DEFINES =
|
||||
CFLAGS = $(DEFINES) $(STACK) -w -v -O -I/usr/include
|
||||
LDFLAGS = -v
|
||||
LDLIBS = -l/usr/lib/gnulib -l/usr/lib/stack
|
||||
CP = /bin/cp -f
|
||||
CFLAGS = -w -O -v
|
||||
OBJS = makewhatis.o fillbuffer.o process.o
|
||||
|
||||
makewhatis: $(OBJS)
|
||||
$(CC) $(OBJS) -o makewhatis
|
||||
|
||||
build: apropos catman makewhatis man whatis
|
||||
makewhatis.o: makewhatis.c makewhatis.h
|
||||
$(CC) -c $(CFLAGS) makewhatis.c
|
||||
|
||||
apropos: apropos.o apropos2.o util.o utilgs.o globals.o
|
||||
$(CC) $(LDFLAGS) $< $(LDLIBS) -o $@
|
||||
fillbuffer.o: fillbuffer.c makewhatis.h
|
||||
$(CC) -c $(CFLAGS) fillbuffer.c
|
||||
|
||||
catman: catman.o util.o utilgs.o globals.o common.o
|
||||
$(CC) $(LDFLAGS) $< $(LDLIBS) -o $@
|
||||
|
||||
makewhatis: makewhatis.o fillbuffer.o process.o
|
||||
$(CC) $(LDFLAGS) $< $(LDLIBS) -o $@
|
||||
|
||||
man: man.o man2.o apropos2.o util.o utilgs.o globals.o common.o
|
||||
$(CC) $(LDFLAGS) $< $(LDLIBS) -o $@
|
||||
|
||||
whatis: whatis.o apropos2.o util.o utilgs.o globals.o
|
||||
$(CC) $(LDFLAGS) $< $(LDLIBS) -o $@
|
||||
|
||||
clobber:
|
||||
$(RM) *.o *.root
|
||||
process.o: process.c makewhatis.h
|
||||
$(CC) -c $(CFLAGS) process.c
|
||||
|
||||
install:
|
||||
$(CP) apropos man whatis $(BINDIR)
|
||||
$(CP) catman makewhatis $(SBINDIR)
|
||||
$(CP) apropos.1 man.1 whatis.1 $(MANDIR)/man1
|
||||
$(CP) catman.8 makewhatis.8 $(MANDIR)/man8
|
||||
/bin/cp makewhatis $(BINDIR)
|
||||
/bin/cp makewhatis.1 $(MANDIR)/man1
|
||||
|
||||
# additional dependancies
|
||||
clean:
|
||||
/bin/cp -p rm $(OBJS)
|
||||
|
||||
apropos.o:: man.h util.h
|
||||
apropos2.o:: man.h util.h
|
||||
catman.o:: man.h util.h
|
||||
common.o:: man.h util.h
|
||||
fillbuffer.o:: makewhatis.h
|
||||
globals.o:: man.h
|
||||
makewhatis.o:: makewhatis.h
|
||||
man.o:: man.h util.h
|
||||
man2.o:: man.h util.h
|
||||
process.o:: makewhatis.h
|
||||
util.o:: util.h
|
||||
utilgs.o:: util.h
|
||||
whatis.o:: man.h util.h
|
||||
#
|
||||
# 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
|
||||
|
|
|
@ -1,303 +1,190 @@
|
|||
.TH MAKEWHATIS 8 "System Administration" "24 July 1995" "Version 1.2"
|
||||
.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
|
||||
[
|
||||
.B -c
|
||||
.I -c
|
||||
|
|
||||
.B -C
|
||||
.I -C
|
||||
] [
|
||||
.BI -f " outfile"
|
||||
.I -ovV
|
||||
] [
|
||||
.BI -l " logfile"
|
||||
.I "-f outfile"
|
||||
] [
|
||||
.BI -o " dbfile"
|
||||
.I "-l logfile"
|
||||
] [
|
||||
.BI -p " path"
|
||||
] [
|
||||
.BI -v " n"
|
||||
] [
|
||||
.B -V
|
||||
.I "-p path"
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.B makewhatis
|
||||
generates the whatis database for
|
||||
.BR apropos (1),
|
||||
.BR man (1),
|
||||
and
|
||||
.BR whatis (1).
|
||||
.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
|
||||
.B Makewhatis
|
||||
makes use of one of the environment variables
|
||||
.BR MANPATH ,
|
||||
.BR USRMAN ,
|
||||
or
|
||||
.BR MANDIR ,
|
||||
in the listed order of preference. It will use this
|
||||
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 either colons or spaces),
|
||||
then whatis databases will be generated
|
||||
in all of the specified paths. This may be overridden by the
|
||||
.BR -p
|
||||
flag.
|
||||
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,
|
||||
.BR makewhatis
|
||||
will generate its database from manual pages existing in the
|
||||
.IB manpath_component /man X
|
||||
subdirectories (where
|
||||
.I X
|
||||
is the section number)
|
||||
that are either
|
||||
.BR aroff
|
||||
or
|
||||
.BR nroff
|
||||
source files.
|
||||
However, since many GNO programmers are providing only preformatted
|
||||
text versions of their man pages, using the
|
||||
.I -c
|
||||
flag will cause
|
||||
.B makewhatis
|
||||
to also use manual pages in the
|
||||
.IB manpath_component /cat X
|
||||
subdirectories when building the database.
|
||||
If there is a corresponding manual page in both the
|
||||
.BI man X
|
||||
and
|
||||
.BI cat X
|
||||
subdirectory, then only the page in the
|
||||
.BI man X
|
||||
subdirectory will be used.
|
||||
.LP
|
||||
Manual pages which are
|
||||
.BR nroff
|
||||
source files in the
|
||||
.BI man X
|
||||
subdirectory, or are preformatted text in the
|
||||
.BI cat X
|
||||
subdirectory may be compressed by either
|
||||
.BR compress (1),
|
||||
.BR freeze (1),
|
||||
or
|
||||
.BR gzip (1),
|
||||
provided that the suffixes on the compressed file are
|
||||
.BR ".Z" ,
|
||||
.BR ".F" ,
|
||||
and
|
||||
.BR ".gz" ,
|
||||
respectively. The case of the suffix is significant.
|
||||
.BR Aroff
|
||||
source files
|
||||
.I "must not"
|
||||
be compressed by any method.
|
||||
.LP
|
||||
All
|
||||
.BR aroff
|
||||
link files are ignored. A file is assumed to be an
|
||||
.BR aroff
|
||||
link file if it ends in
|
||||
.B ".l"
|
||||
(dot lower-case ell) and is not within a
|
||||
.BR manl
|
||||
(man-ell) or a
|
||||
.BR catl
|
||||
(cat-ell) subdirectory.
|
||||
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 files
|
||||
be sorted after
|
||||
that the man pages are found. It is suggested that the database be sorted
|
||||
after
|
||||
.B makewhatis
|
||||
is finished. See
|
||||
.BR sort (1)
|
||||
or
|
||||
.BR msort (1) .
|
||||
.BR sort (1).
|
||||
.SH OPTIONS
|
||||
.IP "\fB\-c\fP"
|
||||
will check
|
||||
.BI cat X
|
||||
subdirectories as well as
|
||||
.BI man X
|
||||
subdirectories.
|
||||
.IP \fB\-C\fP
|
||||
.I -c
|
||||
will check man/catX sub-directories as well as man/manX
|
||||
.LP
|
||||
.I -C
|
||||
will check
|
||||
.I only
|
||||
.BI cat X
|
||||
subdirectories,
|
||||
.I not
|
||||
.BI man X
|
||||
subdirectories.
|
||||
.IP "\fB-f\fR \fIoutfile\fR"
|
||||
.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
|
||||
.IR outfile .
|
||||
Invoking
|
||||
.B -f
|
||||
without
|
||||
.B -v2
|
||||
produces no output.
|
||||
.IP "\fB-l\fR \fIlogfile\fR"
|
||||
will cause any error messages to be printed to
|
||||
.IR logfile .
|
||||
Invoking
|
||||
.B -l
|
||||
without either
|
||||
.B -v1
|
||||
or
|
||||
.B -v2
|
||||
produces no output.
|
||||
.IP "\fB-o\fR \fIdbfile\fR"
|
||||
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. While it is possible to
|
||||
use a full pathname for
|
||||
.IR dbfile ,
|
||||
this will result in that file being overwritten for each colon- or
|
||||
space-delimited entry in
|
||||
.BR MANPATH .
|
||||
.IP "\fB-p\fR \fIpath\fR"
|
||||
as the name for the generated whatis databases.
|
||||
.LP
|
||||
.I "-p path"
|
||||
overrides the environment variables
|
||||
.B MANPATH
|
||||
.I MANPATH
|
||||
et al for determining for which manual page hierarchies the databases must
|
||||
be generated.
|
||||
.IP "\fB-v\fR \fIn\fR"
|
||||
creates verbose status messages during execution. For
|
||||
.IR n =1
|
||||
only major error messages are printed out. For
|
||||
.IR n =2,
|
||||
the names of processed files are also printed. For
|
||||
.IR n =3,
|
||||
the output becomes very verbose with excessive status information, including
|
||||
listing any missing subdirectores.
|
||||
.IP \fB-V\fR
|
||||
.LP
|
||||
.I -v
|
||||
creates verbose status messages during execution.
|
||||
.LP
|
||||
.I -V
|
||||
will show version and usage information, then exit.
|
||||
.SH ENVIRONMENT
|
||||
.BR MANPATH
|
||||
\fIMANPATH\fR, \fIUSRMAN\fR, \fIMANDIR\fR:
|
||||
.br
|
||||
.BR USRMAN
|
||||
.br
|
||||
.BR MANDIR
|
||||
.RS
|
||||
Unless the
|
||||
.B -p
|
||||
.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. The search
|
||||
is done in the order shown. While
|
||||
determining where database files should be generated. While
|
||||
.B makewhatis
|
||||
will correctly handle
|
||||
.RB ` ~ '
|
||||
.I ~
|
||||
and
|
||||
.RB ` . '
|
||||
being part of these paths, it will not correctly handle
|
||||
.RB ` .. '.
|
||||
.sp 1
|
||||
Either colons or spaces can be used to delimit the individual paths.
|
||||
If the value of the selected environment variable contains no spaces
|
||||
nor
|
||||
.B /
|
||||
characters (such as
|
||||
.BR :usr:local:man ),
|
||||
it is assumed to be a single path, not a list of paths.
|
||||
.sp 1
|
||||
Although
|
||||
.B makewhatis
|
||||
allows
|
||||
.BR USRMAN
|
||||
and
|
||||
.BR MANDIR
|
||||
to be each a colon- or space-separated list of pathnames,
|
||||
it is recommended that for compatibility with
|
||||
.BR man
|
||||
(version 2.1 and earlier) these variables, if used, should be
|
||||
a single pathname.
|
||||
.RE
|
||||
.I .
|
||||
being part of these paths, it will not correctly handle \fI..\fR.
|
||||
.SH CAVEATS
|
||||
.B Makewhatis
|
||||
assumes that the programs
|
||||
.BR aroff ,
|
||||
.BR compress ,
|
||||
.BR freeze ,
|
||||
and
|
||||
.BR gzip
|
||||
are available to the executing shell via the
|
||||
.BR system (2)
|
||||
call.
|
||||
.BR Nroff
|
||||
is not used and need not be available.
|
||||
.LP
|
||||
Because
|
||||
.B makewhatis
|
||||
looks for the string
|
||||
.B NAME
|
||||
and one of
|
||||
.BR .SH ,
|
||||
.BR SYNOPSIS ,
|
||||
or
|
||||
.B DESCRIPTION
|
||||
.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 preformatted manual page
|
||||
.B NAME
|
||||
is underlined by repeated backspace-_ sequences, then the generated
|
||||
description for that particular man page is unpredictable,
|
||||
though usually blank. When parsing preformatted manual pages,
|
||||
.B makewhatis
|
||||
will understand the common double- and quadruple-boldfaced
|
||||
subheadings, provided
|
||||
that the backspace character (control-H) is used to achieve this effect.
|
||||
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
|
||||
.B NAME
|
||||
.I NAME
|
||||
to be in the format:
|
||||
.nf
|
||||
NAME
|
||||
\fIcommand_name\fR [...] - \fIbrief description\fR
|
||||
<command> - <brief description>
|
||||
.fi
|
||||
If this is not so (ignoring whitespace), then the output is unpredictable.
|
||||
.LP
|
||||
Man pages must be CR-delimited (ASCII 015, or control\-M).
|
||||
.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.
|
||||
.LP
|
||||
Any text appearing after
|
||||
.B NAME
|
||||
on the NAME header line will be ignored.
|
||||
.SH BUGS
|
||||
.B Makewhatis
|
||||
reads files in blocks of 1024 characters.
|
||||
If formatting information is split by the end
|
||||
of the input buffer, you may see formatting infomation such as
|
||||
.B .BR
|
||||
in the output. This was not fixed due to the overhead of having to
|
||||
check for such a condition.
|
||||
.LP
|
||||
Please report any additional bugs to Devin Reade, <gdr@myrias.com>.
|
||||
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/[share/]man/whatis -- the whatis database
|
||||
/usr/sbin/makewhatis -- whatis database generator
|
||||
man/whatis -- the whatis database
|
||||
.fi
|
||||
.SH SEE ALSO
|
||||
.BR apropos (1),
|
||||
.BR aroff (1),
|
||||
.BR catman (1),
|
||||
.BR compress (1),
|
||||
.BR freeze (1),
|
||||
.BR gzip (1),
|
||||
.BR man (1),
|
||||
.BR nroff (1),
|
||||
.BR whatis (1)
|
||||
.BR whatis (1),
|
||||
.SH AUTHOR
|
||||
Written by Devin Reade <glyn@cs.ualberta.ca> for the Apple IIgs and Gno.
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
/*
|
||||
* Copyright 1995 by Devin Reade <gdr@myrias.com>. For distribution
|
||||
* information see the README file that is part of the manpack archive,
|
||||
* or contact the author, above.
|
||||
*/
|
||||
|
||||
segment "makewhatis";
|
||||
#ifdef __CCFRONT__
|
||||
#include <14:pragma.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
|
@ -13,35 +9,28 @@ segment "makewhatis";
|
|||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include "getopt.h"
|
||||
#include <libc.h>
|
||||
|
||||
#include "makewhatis.h"
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
extern void begin_stack_check(void);
|
||||
extern int end_stack_check(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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{1|2|3} verbose
|
||||
* -V show version and usage info and exit
|
||||
* -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",
|
||||
"man1",
|
||||
"man2",
|
||||
"man3",
|
||||
"man3f",
|
||||
"man4",
|
||||
"man5",
|
||||
"man6",
|
||||
|
@ -49,30 +38,7 @@ char *man_subdir[] = {
|
|||
"man8",
|
||||
"mann",
|
||||
"manl",
|
||||
"manp",
|
||||
"mano",
|
||||
NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* 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",
|
||||
"cat3f",
|
||||
"cat4",
|
||||
"cat5",
|
||||
"cat6",
|
||||
"cat7",
|
||||
"cat8",
|
||||
"catn",
|
||||
"catl",
|
||||
"catp",
|
||||
"cato",
|
||||
NULL /* _must_ be NULL terminated! */
|
||||
NULL
|
||||
};
|
||||
|
||||
/* For the various command line flags */
|
||||
|
@ -82,10 +48,29 @@ 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 */
|
||||
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 */
|
||||
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;
|
||||
|
@ -93,15 +78,15 @@ 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 *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;
|
||||
|
@ -109,22 +94,18 @@ int main (int argc, char **argv) {
|
|||
|
||||
/* make sure Gno is running */
|
||||
if (needsgno()==0) {
|
||||
fprintf(stderr,"Requires Gno/ME\n");
|
||||
fprintf(stderr,"Requires Gno/ME\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
begin_stack_check();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* set the defaults
|
||||
*/
|
||||
|
||||
output_fp = stdout;
|
||||
error_fp = stderr;
|
||||
if (getwd(progdir) == NULL) {
|
||||
perror("getwd() failed");
|
||||
if (getwd(progdir) == NULL) {
|
||||
perror("getwd() failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -132,87 +113,86 @@ int main (int argc, char **argv) {
|
|||
* parse the command line
|
||||
*/
|
||||
|
||||
while((i = getopt(argc,argv,"cCf:l:o:p:v:V")) != EOF)
|
||||
switch(i) {
|
||||
while((i = getopt(argc,argv,"cCf:l:o:p:vV")) != EOF)
|
||||
switch(i) {
|
||||
case 'c':
|
||||
if (C_flag) errflag++;
|
||||
if (C_flag) errflag++;
|
||||
else c_flag++;
|
||||
break;
|
||||
case 'C':
|
||||
if (c_flag) errflag++;
|
||||
else C_flag++;
|
||||
if (c_flag) errflag++;
|
||||
else C_flag++;
|
||||
break;
|
||||
case 'f':
|
||||
output_fp = fopen (optarg,"w");
|
||||
output_fp = fopen (optarg,"w");
|
||||
if (output_fp == NULL) {
|
||||
fprintf(stderr,"Could not open output file %s; using stdout.\n",
|
||||
optarg);
|
||||
fprintf(stderr,"Could not open output file %s; using stdout.\n",
|
||||
optarg);
|
||||
output_fp = stdout;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case 'l':
|
||||
error_fp = fopen (optarg,"w");
|
||||
error_fp = fopen (optarg,"w");
|
||||
if (error_fp == NULL) {
|
||||
fprintf(stderr,"Could not open log file %s; using stderr.\n",
|
||||
optarg);
|
||||
fprintf(stderr,"Could not open log file %s; using stderr.\n",
|
||||
optarg);
|
||||
error_fp = stderr;
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
o_flag++;
|
||||
o_flag++;
|
||||
dbfile = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
p_flag++;
|
||||
p_flag++;
|
||||
p = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
v_flag = (short) atoi(optarg);
|
||||
if ((v_flag<1) && (v_flag>3)) errflag++;
|
||||
v_flag++;
|
||||
break;
|
||||
case 'V':
|
||||
fprintf(stderr,
|
||||
"%s --\n\tCreate the %s database.\n\tVersion %s by Devin Reade\n\n",
|
||||
fprintf(stderr,
|
||||
"%s -- Create the %s database.\n\tVersion %s by Devin Reade\n\n",
|
||||
argv[0],WHATIS,VERSIONSTRING);
|
||||
errflag++;
|
||||
break;
|
||||
default:
|
||||
errflag++;
|
||||
errflag++;
|
||||
break;
|
||||
}
|
||||
if (errflag) {
|
||||
fprintf(error_fp,
|
||||
"Usage:\n%s\t[-c|-C] [-f outfile] [-l logfile] [-o dbfile] [-p path]\n\
|
||||
\t\t[-v 1|2] [-V]\n\n\
|
||||
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 n\t\t<n>=1: Slightly verbose, only displaying major errors.\n\
|
||||
\t\t<n>=2: Verbose, displaying processed file names.\n\
|
||||
\t\t<n>=3: Very verbose, displaying more processing info.\n\
|
||||
-V\t\tShow version and usage information, then exit.\n",argv[0]);
|
||||
return -1;
|
||||
-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) p = DEFAULT_MANPATH;
|
||||
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,
|
||||
"malloc failed while making copy of \"%s\"\nAborted.\n",p);
|
||||
if (v_flag) fprintf(error_fp,"couldn't make copy of \"%s\"",p);
|
||||
return -1;
|
||||
}
|
||||
strcpy(manpath,p);
|
||||
|
@ -228,107 +208,100 @@ int main (int argc, char **argv) {
|
|||
path = strtok (manpath," ");
|
||||
while (path != NULL) {
|
||||
|
||||
if (access(path,F_OK)==0) {
|
||||
if (access(path,F_OK)==0) {
|
||||
|
||||
if (strcmp(path,".") == 0) {
|
||||
chdir(progdir);
|
||||
if (strcmp(path,".") == 0) {
|
||||
chdir(progdir);
|
||||
} else {
|
||||
chdir(path);
|
||||
chdir(path);
|
||||
}
|
||||
|
||||
/* open the whatis database file */
|
||||
if (!o_flag) dbfile = WHATIS;
|
||||
whatis_fp = fopen(dbfile,"w");
|
||||
/* 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\
|
||||
Aborted.\n",
|
||||
dbfile,path);
|
||||
exit(-1);
|
||||
}
|
||||
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) {
|
||||
if (!C_flag) for (i=0; man_subdir[i] != NULL; i++) {
|
||||
subdir = opendir(man_subdir[i]);
|
||||
if (subdir != NULL) {
|
||||
|
||||
/* print status */
|
||||
if (v_flag>=3) fprintf(output_fp,
|
||||
"Now working on directory %s\t%s ...\n",path,man_subdir[i]);
|
||||
/* 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]);
|
||||
chdir(man_subdir[i]);
|
||||
|
||||
/* loop over files within subdirectory */
|
||||
while ((file = readdir(subdir)) != NULL) {
|
||||
process (file->d_name,tmp_file,whatis_fp,&man_subdir[i][3]);
|
||||
}
|
||||
closedir(subdir);
|
||||
} else {
|
||||
if (v_flag>=3) fprintf(output_fp,
|
||||
"Could not access files in %s\t%s ...\n",path,man_subdir[i]);
|
||||
}
|
||||
chdir(path);
|
||||
}
|
||||
/* 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) {
|
||||
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>=3) fprintf(output_fp,
|
||||
"Now working on directory %s\t%s ...\n",path,cat_subdir[i]);
|
||||
/* 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]);
|
||||
chdir(cat_subdir[i]);
|
||||
|
||||
/* make filebuffer contain path to matching man* subdirectory */
|
||||
/* 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);
|
||||
/* 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,
|
||||
&man_subdir[i][3]);
|
||||
}
|
||||
closedir(subdir);
|
||||
} else {
|
||||
if (v_flag>=3) fprintf(output_fp,
|
||||
"Could not access files in %s\t%s ...\n",path,cat_subdir[i]);
|
||||
}
|
||||
chdir(path);
|
||||
}
|
||||
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);
|
||||
/* close the database */
|
||||
fclose(whatis_fp);
|
||||
|
||||
}
|
||||
/* get the next path in manpath */
|
||||
path = strtok (NULL," ");
|
||||
/* get the next path in manpath */
|
||||
path = strtok (NULL," ");
|
||||
}
|
||||
|
||||
|
||||
/* clean up and exit */
|
||||
unlink(tmp_file);
|
||||
unlink(tmp_file);
|
||||
if (output_fp != stdout) fclose(output_fp);
|
||||
if (error_fp != stderr) fclose(error_fp);
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
fprintf(stderr,"Makewhatis stack usage: %d bytes\n",end_stack_check());
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,27 +1,25 @@
|
|||
/*
|
||||
* Copyright 1995 by Devin Reade <gdr@myrias.com>. For distribution
|
||||
* information see the README file that is part of the manpack archive,
|
||||
* or contact the author, above.
|
||||
*/
|
||||
|
||||
#define VERSIONSTRING "1.2"
|
||||
#define ISGRAPH_FIX 1
|
||||
#define VERSIONSTRING "1.0"
|
||||
|
||||
/* The size of the IO buffers */
|
||||
#define BUFFERSIZE 1024
|
||||
#define BUFFERSIZE 1024
|
||||
|
||||
/* The default name for the whatis database */
|
||||
#define WHATIS "whatis"
|
||||
#define WHATIS "whatis"
|
||||
|
||||
/* The number of characters per tab in the whatis database */
|
||||
#define TABLENGTH 8
|
||||
#define TABLENGTH 8
|
||||
|
||||
#define DEFAULT_MANPATH "/usr/man"
|
||||
extern int chdir (const char *);
|
||||
extern int system (const char *);
|
||||
|
||||
extern int chdir (const char *);
|
||||
extern int system (const char *);
|
||||
|
||||
void fillbuffer (char *filename);
|
||||
void process (char *filename, char *tmp_file, FILE *whatis_fp, char *sec);
|
||||
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;
|
||||
|
|
|
@ -1,519 +0,0 @@
|
|||
.\" This man page copyright (c) 1980 Regents of the University of California.
|
||||
.\" All rights reserved. The Berkeley software License Agreement
|
||||
.\" specifies the terms and conditions for redistribution.
|
||||
.\"
|
||||
.\" While this manual page is based on one from UCB, the included
|
||||
.\" C source, makefile, and executables are copyright (c) 1995
|
||||
.\" by Devin Reade <gdr@myrias.com>. All rights reserved.
|
||||
.\"
|
||||
.TH MAN 1 "Commands and Applications" "24 July 95" "Version 3.0"
|
||||
.SH NAME
|
||||
man \- display reference manual pages; find reference pages by keyword
|
||||
.SH SYNOPSIS
|
||||
.B man
|
||||
.RB "[\|" \- "\|]"
|
||||
.RB "[\|" \-t "\|]"
|
||||
.RB "[\|" \-M
|
||||
.IR path "\|]"
|
||||
.RB "[\|" \-T
|
||||
.IR macro-package "\|]"
|
||||
.RI "[\|" section "\|] " title "
|
||||
.br
|
||||
.B man
|
||||
.RB "[\|" \-M
|
||||
.IR path "\|]"
|
||||
.B \-k
|
||||
.I keyword
|
||||
\&.\|.\|.
|
||||
.br
|
||||
.B man
|
||||
.RB "[\|" \-M
|
||||
.IR path "\|]"
|
||||
.B \-f
|
||||
.I filename
|
||||
\&.\|.\|.
|
||||
.SH DESCRIPTION
|
||||
.B man
|
||||
displays information from the reference manuals.
|
||||
It can display complete manual pages that you select by
|
||||
.IR title ,
|
||||
or one-line summaries selected either by
|
||||
.I keyword
|
||||
.RB ( \-k ),
|
||||
or by the name of an associated file
|
||||
.RB ( \-f ).
|
||||
.LP
|
||||
A
|
||||
.IR section ,
|
||||
when given, applies to the
|
||||
.I title
|
||||
that follows it on the command line.
|
||||
.B man
|
||||
looks in the indicated section of the manual for that
|
||||
.IR title .
|
||||
.I section
|
||||
is either a digit (perhaps followed by a single letter indicating
|
||||
the type of manual page), or one of the words
|
||||
.BR new ,
|
||||
.BR local ,
|
||||
.BR old ,
|
||||
or
|
||||
.BR public .
|
||||
The
|
||||
abbreviations
|
||||
.BR n ,
|
||||
.BR l ,
|
||||
.B o
|
||||
and
|
||||
.B p
|
||||
are also allowed.
|
||||
If
|
||||
.I section
|
||||
is omitted,
|
||||
.B man
|
||||
searches all reference sections
|
||||
(giving preference to commands over functions).
|
||||
If more than one manual page exists for the specified
|
||||
.IR title ,
|
||||
each page is displayed in the order in which it is found. The
|
||||
user is given the option of exiting after each page is displayed.
|
||||
If no manual page is located,
|
||||
.B man
|
||||
prints an error message.
|
||||
.LP
|
||||
The reference page sources are typically located in the
|
||||
.BR /usr/man/man?
|
||||
directories.
|
||||
If there are preformatted, up-to-date versions in
|
||||
corresponding
|
||||
.B cat?
|
||||
or
|
||||
.B fmt?
|
||||
directories,
|
||||
.B man
|
||||
simply displays or prints those versions.
|
||||
If the preformatted
|
||||
version of interest is out of date or missing,
|
||||
.B man
|
||||
reformats it prior to display.
|
||||
If directories for the
|
||||
preformatted versions are not provided,
|
||||
.B man
|
||||
reformats a page whenever it is requested.
|
||||
.LP
|
||||
If the standard output is not a terminal, or if the
|
||||
.RB ` \- '
|
||||
flag is given,
|
||||
.B man
|
||||
pipes its output through
|
||||
.BR cat (1V).
|
||||
Otherwise,
|
||||
.B man
|
||||
pipes its output through
|
||||
.BR more (1)
|
||||
to handle paging and underlining on the screen.
|
||||
.SH OPTIONS
|
||||
.IP \fB\-t\fP
|
||||
.B man
|
||||
arranges for the specified manual pages to be
|
||||
.BR troff ed
|
||||
to a suitable raster output device (see
|
||||
.BR troff (1)
|
||||
or
|
||||
.BR vtroff (1)).
|
||||
If both the
|
||||
.B \-
|
||||
and
|
||||
.B \-t
|
||||
flags are given,
|
||||
.B man
|
||||
updates the
|
||||
.BR troff ed
|
||||
versions of each named
|
||||
.I title
|
||||
(if necessary), but does not display them.
|
||||
.IP "\fB\-M\fP \fIpath\fP"
|
||||
Change the search path for manual pages.
|
||||
.I path
|
||||
is a colon- or space-separated list of directories that contain manual page
|
||||
directory subtrees.
|
||||
For example,
|
||||
.B /usr/man/u_man:/usr/man/a_man
|
||||
makes
|
||||
.B man
|
||||
search in the standard System V locations.
|
||||
The space delimiter is provided for compatibility with GS/OS's
|
||||
use of the colon as a pathname component delimiter. If the search
|
||||
path contains no spaces nor
|
||||
.B /
|
||||
characters (such as
|
||||
.BR :usr:local:man ),
|
||||
it is assumed to be a single path, not a list of paths.
|
||||
If spaces are used as delimiters, remember to quote
|
||||
.I path
|
||||
from the shell.
|
||||
Each directory in the
|
||||
.I path
|
||||
is assumed to contain subdirectories of the form
|
||||
.BR man[1-8l-p] .
|
||||
.IP "\fB\-T\fP \fImacro-package\fP"
|
||||
.B man
|
||||
uses
|
||||
.I macro-package
|
||||
rather than the standard
|
||||
.B \-man
|
||||
macros defined in
|
||||
.B /usr/lib/tmac/tmac.an
|
||||
for formatting manual pages.
|
||||
.IP "\fB\-k\fP \fIkeyword .\|.\|.\fP"
|
||||
.B man
|
||||
prints out one-line summaries from the
|
||||
.B whatis
|
||||
database (table of contents) that contain any of the given
|
||||
.IR keyword s.
|
||||
The
|
||||
.B whatis
|
||||
database is created using the
|
||||
.BR makewhatis (8)
|
||||
command.
|
||||
.IP "\fB\-f\fP \fIfilename .\|.\|.\fP"
|
||||
.B man
|
||||
attempts to locate manual pages related to any of the given
|
||||
.IR filename s.
|
||||
It strips the leading pathname components from each
|
||||
.IR filename ,
|
||||
and then prints one-line summaries containing the resulting
|
||||
basename or names.
|
||||
This option also uses the
|
||||
.B whatis
|
||||
database.
|
||||
.br
|
||||
.ne 7
|
||||
.SH "MANUAL PAGES"
|
||||
.LP
|
||||
Manual pages are either
|
||||
.BR nroff (1)/ troff (1)
|
||||
source files prepared with the
|
||||
.B \-man
|
||||
macro package, or
|
||||
.BR aroff (1)
|
||||
source files prepared with
|
||||
.B "Appleworks GS"
|
||||
(tm) or a compatible word processor.
|
||||
.SS "Referring to Other Manual Pages"
|
||||
Other manual pages can be referenced in one of two ways, depending on
|
||||
whether the target manual page is an
|
||||
.BR aroff
|
||||
or
|
||||
.BR nroff
|
||||
source file.
|
||||
.LP
|
||||
For
|
||||
.BR aroff
|
||||
source files, a "link" may be made by creating a file ending in
|
||||
.BR ".l"
|
||||
(that's a dot-ell). The file must contain a single line consisting
|
||||
of the pathname of the target
|
||||
.BR aroff
|
||||
source file.
|
||||
An intentional design limitation was made that disallows this form
|
||||
of "link" in the
|
||||
.BR manl
|
||||
(that's man-ell) subdirectory.
|
||||
.LP
|
||||
For
|
||||
.BR nroff
|
||||
source files, a "link" may be made by creating a file containing
|
||||
the
|
||||
.BR nroff
|
||||
source (\fB\.so\fP) command. This file should have the same suffix
|
||||
as the target
|
||||
.BR nroff
|
||||
source file.
|
||||
.B man
|
||||
does not itself do any processing of the source command.
|
||||
.LP
|
||||
With both types of "links" the pathname may be either a full- or
|
||||
partial-pathname. In the latter case, the pathname must be relative
|
||||
to the root of the manual page directory subtree.
|
||||
.LP
|
||||
.B man
|
||||
processes the indicated file in place of the current one.
|
||||
The reference must be expressed as
|
||||
a pathname relative to the root of
|
||||
the manual page directory subtree.
|
||||
.SS "Preprocessing Manual Pages"
|
||||
If the first line is a string of the form:
|
||||
.nf
|
||||
|
||||
\fB'\|\e"\0 \fR\fIX\fR
|
||||
|
||||
.fi
|
||||
where
|
||||
.I X
|
||||
is separated from the
|
||||
`\fB"\fP'
|
||||
by a single
|
||||
.SM SPACE
|
||||
and consists of any combination of characters in the following list,
|
||||
.B man
|
||||
pipes its input to
|
||||
.BR troff (1)
|
||||
or
|
||||
.BR nroff (1)
|
||||
through the corresponding preprocessors.
|
||||
.nf
|
||||
|
||||
\fBe\fP \fBeqn\fP(1), or \fBneqn\fP for \fBnroff\fP
|
||||
\fBr\fP \fBrefer\fP(1)
|
||||
\fBt\fP \fBtbl\fP(1)
|
||||
\fBv\fP \fBvgrind\fP(1)
|
||||
|
||||
.fi
|
||||
.LP
|
||||
If
|
||||
.B eqn
|
||||
or
|
||||
.B neqn
|
||||
is invoked,
|
||||
it will automatically read the file
|
||||
.B /usr/pub/eqnchar
|
||||
(see
|
||||
.BR eqnchar (7)).
|
||||
If
|
||||
.BR nroff (1)
|
||||
is invoked,
|
||||
.BR col (1V)
|
||||
is automatically used.
|
||||
.SH "COMPRESSED MANUAL PAGES"
|
||||
.B man
|
||||
allows its manual pages to be compressed by either
|
||||
.BR compress ,
|
||||
.BR freeze ,
|
||||
or
|
||||
.BR gzip ,
|
||||
in which case the manual page must have the suffix
|
||||
.BR .Z ,
|
||||
.BR .F ,
|
||||
or
|
||||
.BR .gz ,
|
||||
respectively. Note that the test for these suffixes is case sensitive
|
||||
and if the incorrect case is used then the compressed file will be passed
|
||||
to
|
||||
.B nroff
|
||||
with unpredictable results.
|
||||
.LP
|
||||
Compression may be used on files in either (or both) of the
|
||||
.BR man? " and " cat?
|
||||
subdirectories. Do not compress
|
||||
.BR aroff (1)
|
||||
source files since compressed files in the
|
||||
.BR man?
|
||||
subdirectory are always assumed to be
|
||||
.BR nroff (1)
|
||||
source.
|
||||
.SH ENVIRONMENT
|
||||
.IP \fBMANPATH\fP
|
||||
If set,
|
||||
its value overrides
|
||||
.B /usr/man
|
||||
as the default search path.
|
||||
(The
|
||||
.B \-M
|
||||
flag, in turn, overrides this value.)
|
||||
See the description of the
|
||||
.B \-M
|
||||
flag for syntax details.
|
||||
.IP \fBUSRMAN\fP
|
||||
If
|
||||
.B MANPATH
|
||||
is not set, then the value of
|
||||
.B USRMAN
|
||||
(if set) overrides
|
||||
.B /usr/man
|
||||
as the default search path.
|
||||
(The
|
||||
.B \-M
|
||||
flag, in turn, overrides this value.)
|
||||
See the description of the
|
||||
.B \-M
|
||||
flag for syntax details.
|
||||
.IP \fBMANDIR\fP
|
||||
If neither
|
||||
.B MANPATH
|
||||
nor
|
||||
.B USRMAN
|
||||
is set, then the value of
|
||||
.B MANDIR
|
||||
(if set) overrides
|
||||
.B /usr/man
|
||||
as the default search path.
|
||||
(The
|
||||
.B \-M
|
||||
flag, in turn, overrides this value.)
|
||||
See the description of the
|
||||
.B \-M
|
||||
flag for syntax details.
|
||||
.IP \fBPAGER\fP
|
||||
A program to use for interactively delivering
|
||||
.BR man 's
|
||||
output to the screen.
|
||||
If not set,
|
||||
.RB ` "/bin/more" '
|
||||
(see
|
||||
.BR more (1))
|
||||
is used.
|
||||
.IP \fBTCAT\fP
|
||||
The name of the program to use to display
|
||||
.BR troff ed
|
||||
manual pages.
|
||||
If not set,
|
||||
.RB ` "lpr \-t" '
|
||||
(see
|
||||
.BR lpr (1))
|
||||
is used.
|
||||
.IP \fBTROFF\fP
|
||||
The name of the formatter to use when the
|
||||
.B \-t
|
||||
flag is given.
|
||||
If not set,
|
||||
.RB ` "troff \-t" '
|
||||
is used.
|
||||
.SH FILES
|
||||
.B /usr/[share]/man
|
||||
.RS
|
||||
root of the standard manual page directory subtree
|
||||
.RE
|
||||
.sp
|
||||
.B /usr/[share]/man/man?/*
|
||||
.RS
|
||||
unformatted manual entries
|
||||
.RE
|
||||
.sp
|
||||
.B /usr/[share]/man/cat?/*
|
||||
.RS
|
||||
.BR nroff ed
|
||||
manual entries
|
||||
.RE
|
||||
.sp
|
||||
.B /usr/[share]/man/fmt?/*
|
||||
.RS
|
||||
.BR troff ed
|
||||
manual entries
|
||||
.RE
|
||||
.sp
|
||||
.B /usr/[share]/man/whatis
|
||||
.RS
|
||||
table of contents and keyword database
|
||||
.RE
|
||||
.sp
|
||||
.B /usr/[share]/lib/tmac/tmac.an
|
||||
.RS
|
||||
standard
|
||||
.B \-man
|
||||
macro package
|
||||
.RE
|
||||
.sp
|
||||
.B /usr/pub/eqnchar
|
||||
.SH "SEE ALSO"
|
||||
.BR apropos (1),
|
||||
.BR aroff (1),
|
||||
.BR cat (1V),
|
||||
.BR col (1V),
|
||||
.BR compress (1),
|
||||
.BR eqn (1),
|
||||
.BR freeze (1),
|
||||
.BR gzip (1),
|
||||
.BR less (1),
|
||||
.BR lpr (1),
|
||||
.BR more (1),
|
||||
.BR nroff (1),
|
||||
.BR refer (1),
|
||||
.BR tbl (1),
|
||||
.BR troff (1),
|
||||
.BR vgrind (1),
|
||||
.BR vtroff (1),
|
||||
.BR whatis (1),
|
||||
.BR whereis (1),
|
||||
.BR eqnchar (7),
|
||||
.BR man (7),
|
||||
.BR catman (8)
|
||||
.br
|
||||
.ne 5
|
||||
.SH NOTES
|
||||
.LP
|
||||
Because
|
||||
.B troff
|
||||
is not 8-bit clean,
|
||||
.B man
|
||||
has not been made 8-bit clean.
|
||||
.LP
|
||||
The
|
||||
.B \-f
|
||||
and
|
||||
.B \-k
|
||||
options use the
|
||||
.B whatis
|
||||
database, which is created by
|
||||
.BR makewhatis (8).
|
||||
.br
|
||||
.ne 4
|
||||
.LP
|
||||
Although this version of
|
||||
.B man
|
||||
allows
|
||||
.BR USRMAN " and " MANDIR
|
||||
to be each a colon- or space-separated list of pathnames, other versions
|
||||
of
|
||||
.B man
|
||||
treat the values of these environment variables as a single pathname.
|
||||
For compatibility reasons, the use of these two environment variables
|
||||
is discouraged; use
|
||||
.B MANPATH
|
||||
instead.
|
||||
.SH BUGS
|
||||
.LP
|
||||
The manual is supposed to be reproducible
|
||||
either on a phototypesetter or on an
|
||||
.SM ASCII
|
||||
terminal.
|
||||
However,
|
||||
on a terminal some information
|
||||
(indicated by font changes, for instance)
|
||||
is necessarily lost.
|
||||
.LP
|
||||
Some dumb terminals cannot process the vertical motions produced
|
||||
by the
|
||||
.B e
|
||||
.RB ( eqn (1))
|
||||
preprocessing flag.
|
||||
To prevent garbled output on these terminals,
|
||||
when you use
|
||||
.B e
|
||||
also use
|
||||
.BR t ,
|
||||
to invoke
|
||||
.BR col (1V)
|
||||
implicitly.
|
||||
This workaround has the disadvantage of eliminating superscripts and
|
||||
subscripts \(em even on those terminals that can display them.
|
||||
.SM CTRL-Q
|
||||
will clear a terminal that gets confused by
|
||||
.BR eqn (1)
|
||||
output.
|
||||
.LP
|
||||
The code which calls the
|
||||
.BR eqn (1),
|
||||
.BR refer (1),
|
||||
.BR tbl (1),
|
||||
and
|
||||
.BR vgrind (1)
|
||||
preprocessors is not yet implemented. Since these preprocessors do
|
||||
not as yet exist for GNO, this is not too much of a problem.
|
||||
.LP
|
||||
Please report any other bugs to Devin Reade, <gdr@myrias.com>.
|
||||
.SH HISTORY
|
||||
The GNO version of
|
||||
.BR man
|
||||
first appeared in GNO version 1.0 and was written by Mike Horwath.
|
||||
This version was rewritten from scratch by Devin Reade.
|
|
@ -1,154 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995 by Devin Reade <gdr@myrias.com>. For distribution
|
||||
* information see the README file that is part of the manpack archive,
|
||||
* or contact the author, above.
|
||||
*/
|
||||
|
||||
segment "man_______";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <libc.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <sgtty.h>
|
||||
#include <unistd.h>
|
||||
#include "util.h"
|
||||
#include "man.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
extern void begin_stack_check(void);
|
||||
extern int end_stack_check(void);
|
||||
#endif
|
||||
|
||||
char *macroPackage = "an"; /* default /usr/lib/tmac/tmac.an */
|
||||
char *versionStr = "Version 3.0 by Devin Reade";
|
||||
char *pager;
|
||||
char *troff;
|
||||
char *tcat;
|
||||
|
||||
static char *nothing = "nothing appropriate";
|
||||
|
||||
short f_flag, k_flag, M_flag, n_flag, t_flag, T_flag, V_flag;
|
||||
short hyphen_flag, err_flag;
|
||||
|
||||
static void usage(char *progname) {
|
||||
if (err_flag || V_flag) fprintf(stderr,"%s %s\n",progname,versionStr);
|
||||
if (err_flag) {
|
||||
fprintf(stderr,"Usage:\n\
|
||||
\t%s [-] [-nt] [-M path] [-T macro-package] [section] title ...\n\
|
||||
\t%s [-n] [-M path] -f filename ...\n\
|
||||
\t%s [-n] [-M path] -k keyword ...\n\n",progname,progname,progname);
|
||||
exit(1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
int i, result;
|
||||
char *p;
|
||||
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
/* make sure Gno is running */
|
||||
if (needsgno()==0) {
|
||||
fprintf(stderr,"Requires Gno/ME\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
begin_stack_check();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* initialization
|
||||
*/
|
||||
|
||||
f_flag = k_flag = M_flag = t_flag = T_flag = V_flag = 0;
|
||||
n_flag = hyphen_flag = err_flag = 0;
|
||||
|
||||
/*
|
||||
* parse the command line
|
||||
*/
|
||||
|
||||
while((i = getopt(argc,argv,"fkM:ntT:V-")) != EOF) {
|
||||
switch(i) {
|
||||
case 'f':
|
||||
f_flag++;
|
||||
if (k_flag || t_flag || T_flag || hyphen_flag) err_flag++;
|
||||
break;
|
||||
case 'k':
|
||||
k_flag++;
|
||||
if (f_flag || t_flag || T_flag || hyphen_flag) err_flag++;
|
||||
break;
|
||||
case 'M':
|
||||
M_flag++;
|
||||
manpath = Xstrdup(optarg,__LINE__,__FILE__);
|
||||
break;
|
||||
case 'n':
|
||||
n_flag++;
|
||||
break;
|
||||
case 't':
|
||||
t_flag++;
|
||||
if (k_flag || f_flag) err_flag++;
|
||||
break;
|
||||
case 'T':
|
||||
T_flag++;
|
||||
macroPackage = optarg;
|
||||
if (k_flag || f_flag) err_flag++;
|
||||
break;
|
||||
case 'V':
|
||||
V_flag++;
|
||||
break;
|
||||
default:
|
||||
err_flag++;
|
||||
}
|
||||
}
|
||||
/* take care of the '-' option, since getopt isn't smart enough */
|
||||
for (i=optind; i<argc; i++) {
|
||||
if (strcmp(argv[i],"-") == 0) {
|
||||
hyphen_flag++;
|
||||
if (k_flag || f_flag) err_flag++;
|
||||
--argc;
|
||||
for( ; i<argc; i++) {
|
||||
argv[i] = argv[i+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((argc == optind) || (!k_flag && !f_flag && (argc-optind > 3))) {
|
||||
err_flag++;
|
||||
}
|
||||
|
||||
usage(argv[0]);
|
||||
|
||||
/* if not already done, set the manpath */
|
||||
if (!M_flag) manpath = getManpath();
|
||||
|
||||
i = 0;
|
||||
if (k_flag || f_flag) {
|
||||
result = apropos(argc-optind, &argv[optind],
|
||||
((k_flag) ? MAN_K_MODE : MAN_F_MODE));
|
||||
if (!n_flag) {
|
||||
i = apropos(argc-optind, &argv[optind],
|
||||
((k_flag) ? ORCA_K_MODE : ORCA_F_MODE));
|
||||
}
|
||||
if (result<=0 && i<=0) {
|
||||
fprintf(stderr,"%s: %s\n",basename(argv[0]),nothing);
|
||||
}
|
||||
} else {
|
||||
if (!isatty(STDOUT_FILENO)) hyphen_flag++;
|
||||
result = man(argc-optind, &argv[optind]);
|
||||
}
|
||||
free(manpath);
|
||||
result = ((result == 0) && (i == 0)) ? 0 : 1;
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
fprintf(stderr,"stack usage: %d bytes\n",end_stack_check());
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995 by Devin Reade <gdr@myrias.com>. For distribution
|
||||
* information see the README file that is part of the manpack archive,
|
||||
* or contact the author, above.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Configuration info
|
||||
*/
|
||||
|
||||
#define WHATIS "whatis"
|
||||
#define PAGER "/bin/more"
|
||||
#define SYSCMND "15/syscmnd"
|
||||
|
||||
#define AROFF "aroff"
|
||||
#define NROFF "nroff"
|
||||
#define TROFF "troff -t"
|
||||
#define TCAT "lpr -t"
|
||||
#define CAT "cat"
|
||||
#define EQN "eqn"
|
||||
#define REFER "refer"
|
||||
#define TBL "tbl"
|
||||
#define VGRIND "vgrind"
|
||||
|
||||
#define NON 0x00
|
||||
#define TXT 0x04
|
||||
#define BIN 0x06
|
||||
#define SRC 0xB0
|
||||
|
||||
#define MAN_F_MODE 1
|
||||
#define MAN_K_MODE 2
|
||||
#define WHATIS_MODE 3
|
||||
#define ORCA_F_MODE 4
|
||||
#define ORCA_K_MODE 5
|
||||
#define ORCA_W_MODE 6
|
||||
|
||||
#define BUFFERSIZE 2048
|
||||
|
||||
typedef struct Section_tag {
|
||||
char *name; /* section name */
|
||||
char *suffix; /* directory suffix */
|
||||
} Section;
|
||||
|
||||
typedef struct {
|
||||
char *suffix;
|
||||
char *extractor;
|
||||
} compressionType;
|
||||
|
||||
/*
|
||||
* from globals.c
|
||||
*/
|
||||
|
||||
extern compressionType compressArray[];
|
||||
extern char linebuf[BUFFERSIZE];
|
||||
extern char linebuf2[BUFFERSIZE];
|
||||
|
||||
/*
|
||||
* from man.c
|
||||
*/
|
||||
|
||||
extern Section sections[];
|
||||
|
||||
extern char *manpath;
|
||||
extern char *pager;
|
||||
extern char *tcat;
|
||||
extern char *troff;
|
||||
extern char *macroPackage;
|
||||
|
||||
extern short hyphen_flag;
|
||||
extern short n_flag;
|
||||
extern short t_flag;
|
||||
|
||||
/*
|
||||
* from apropos2.c
|
||||
*/
|
||||
|
||||
int apropos(int argc, char **argv, int whole_line);
|
||||
|
||||
/*
|
||||
* from whatis2.c
|
||||
*/
|
||||
|
||||
int whatis(int argc, char **argv);
|
||||
|
||||
/*
|
||||
* from man2.c
|
||||
*/
|
||||
int man (int argc, char *argv[]);
|
||||
|
||||
|
||||
/*
|
||||
* from common.c
|
||||
*/
|
||||
|
||||
int getSuffixIndex(char *name);
|
|
@ -1,611 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995 by Devin Reade <gdr@myrias.com>. For distribution
|
||||
* information see the README file that is part of the manpack archive,
|
||||
* or contact the author, above.
|
||||
*/
|
||||
|
||||
segment "man2______";
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sgtty.h>
|
||||
#include "util.h"
|
||||
#include "man.h"
|
||||
|
||||
#define MAX(a,b) ((a) > (b)) ? (a) : (b)
|
||||
|
||||
static char **buildManList(char *suffix, char *name);
|
||||
static void display(char *list);
|
||||
static char *getBaseName (char *out, char *in);
|
||||
static void cleanManList(char **list);
|
||||
|
||||
/*
|
||||
* Pre: argc is the number of strings in argv. It should either be 1 or 2.
|
||||
* If DEBUG is defined, then any other value of argc will result in
|
||||
* a failed assert.
|
||||
*
|
||||
* argv is an array of strings. If argc==1, then argv[0] is presumed
|
||||
* to be the name of the man page. If argc==2, then argv[0] is
|
||||
* presumed to be a section number and argv[1] is the name of the
|
||||
* man page.
|
||||
*
|
||||
* globals:
|
||||
* manpath must be a malloc'd string. Either ':' or ' ' may
|
||||
* may be used as a directory delimiter.
|
||||
* macroPackage must be set to a static string.
|
||||
* t_flag must be in a defined state (either set or unset)
|
||||
* hyphen_flag must be in a defined state (either set or unset)
|
||||
*
|
||||
* Post: print the man page in whatever form it takes, acting as necessary
|
||||
* on the -, -M, and -T flags and section number.
|
||||
*/
|
||||
|
||||
int man(int argc, char *argv[]) {
|
||||
char **manpath_array, **manpagelist;
|
||||
char *sec, *name, *current_path;
|
||||
Section *section;
|
||||
int i, j, k, abort;
|
||||
short section_found, page_found;
|
||||
char dirbrk; /* path component separator. either ':' or '/' */
|
||||
char c, *p;
|
||||
struct sgttyb termMode;
|
||||
short oldMode;
|
||||
|
||||
/* initialization */
|
||||
abort = 0;
|
||||
section_found = 0;
|
||||
page_found = 0;
|
||||
if (t_flag) {
|
||||
if ((tcat = getenv("TCAT")) == NULL) {
|
||||
tcat = TCAT;
|
||||
} else tcat = Xstrdup(tcat,__LINE__,__FILE__);
|
||||
if ((troff = getenv("TROFF")) == NULL) {
|
||||
troff = TROFF;
|
||||
} else troff = Xstrdup(troff,__LINE__,__FILE__);
|
||||
}
|
||||
if (hyphen_flag) {
|
||||
pager = CAT;
|
||||
} else if ((pager = getenv("PAGER")) == NULL) {
|
||||
pager = PAGER;
|
||||
}
|
||||
|
||||
/* determine name and, if appropriate, sec */
|
||||
switch (argc) {
|
||||
case 1:
|
||||
sec = NULL;
|
||||
name = argv[0];
|
||||
break;
|
||||
case 2:
|
||||
sec = argv[0];
|
||||
/* special case some section abbreviations */
|
||||
if (!strcmp(sec,"l")) {
|
||||
sec = "local";
|
||||
} else if (!strcmp(sec,"n")) {
|
||||
sec = "new";
|
||||
} else if (!strcmp(sec,"o")) {
|
||||
sec = "old";
|
||||
} else if (!strcmp(sec,"p")) {
|
||||
sec = "public";
|
||||
}
|
||||
name = argv[1];
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,"internal error at line %d in file %s\n",__LINE__,
|
||||
__FILE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* create array of paths to search */
|
||||
if ((manpath_array = makePathArray(manpath)) == NULL) return 1;
|
||||
|
||||
/*
|
||||
* loop over all the paths in MANPATH
|
||||
*/
|
||||
i=0;
|
||||
current_path = manpath_array[i];
|
||||
while (!abort && current_path) {
|
||||
|
||||
dirbrk = (strchr(current_path,':')!=NULL) ? ':' : '/';
|
||||
|
||||
/* go to the current path in MANPATH */
|
||||
if (chdir(current_path) == -1) {
|
||||
i++;
|
||||
current_path = manpath_array[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
/* loop over sections */
|
||||
for (j=0; !abort && sections[j].name != NULL; j++) {
|
||||
|
||||
/*
|
||||
* if section number was specified and this isn't it, do
|
||||
* the next loop
|
||||
*/
|
||||
if (sec && (strcmp(sec,sections[j].name) ||
|
||||
(!isdigit(*sec) &&
|
||||
strncmp(sec,sections[j].name,strlen(sec))))) continue;
|
||||
section_found++;
|
||||
|
||||
/*
|
||||
* we're going to check this section. Get the pathnames
|
||||
* (relative to this directory) of the two files.
|
||||
*/
|
||||
|
||||
manpagelist = buildManList(sections[j].suffix,name);
|
||||
if (!manpagelist) continue;
|
||||
page_found++;
|
||||
|
||||
for (k=0; !abort && manpagelist[k]; k++) {
|
||||
display(manpagelist[k]);
|
||||
if (!hyphen_flag && !t_flag) {
|
||||
fprintf(stderr,
|
||||
"type q to quit, or any other key for next man page: ");
|
||||
c = getcharraw();
|
||||
if (c == '\0') {
|
||||
fprintf(stderr,"getcharraw failed line %d of %s: %s\n",
|
||||
__LINE__,__FILE__,strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
fputc('\n',stderr);
|
||||
/* evaluate result */
|
||||
if ((c == 'q') || (c == 'Q')) abort++;
|
||||
}
|
||||
}
|
||||
|
||||
cleanManList(manpagelist);
|
||||
|
||||
} /* done looping over sections */
|
||||
i++;
|
||||
current_path = manpath_array[i];
|
||||
|
||||
} /* done looping over paths */
|
||||
|
||||
i = 0; /* used here for the return code */
|
||||
if (sec) {
|
||||
if (!section_found) {
|
||||
fprintf(stderr,"there is no section %s in the manual\n",sec);
|
||||
i++;
|
||||
} else if (!page_found) {
|
||||
fprintf(stderr,"there is no %s in section %s\n",name,sec);
|
||||
i++;
|
||||
}
|
||||
} else if (!page_found) {
|
||||
fprintf(stderr,"there is no %s in the manual\n",name);
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
#define DIRBUF_LEN 10
|
||||
static const char *manstr="man";
|
||||
static const char *catstr="cat";
|
||||
|
||||
static char **buildManList(char *suffix, char *name) {
|
||||
static char buffer1[FILENAME_MAX];
|
||||
static char buffer2[FILENAME_MAX];
|
||||
DIR *directory;
|
||||
struct dirent *entry;
|
||||
char **list1, **list2, **list3;
|
||||
size_t len;
|
||||
int total1, total2, i, j, k;
|
||||
char *p, *fn;
|
||||
|
||||
/* initialization */
|
||||
list1 = list2 = list3 = NULL;
|
||||
total1 = total2 = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
/* sanity check on arguments */
|
||||
if(MAX(strlen(manstr),strlen(catstr)) + strlen(suffix) >= FILENAME_MAX) {
|
||||
fprintf(stderr,"internal error: buffer overflow at line %d of %s\n",
|
||||
__LINE__,__FILE__);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* look in man subdirectory
|
||||
*/
|
||||
strcpy(buffer1,manstr);
|
||||
strcat(buffer1,suffix);
|
||||
if ((directory = opendir(buffer1)) != NULL) {
|
||||
while ((entry = readdir(directory)) != (struct dirent *) NULL) {
|
||||
|
||||
/* skip if no match */
|
||||
len = strlen(name);
|
||||
if (strncmp(entry->d_name,name,len) ||
|
||||
(entry->d_name[len] != '.')) continue;
|
||||
|
||||
if (strlen(manstr) + strlen(suffix) + strlen(entry->d_name) +
|
||||
strlen(suffix) + 1 >= FILENAME_MAX) {
|
||||
fprintf(stderr,"internal error: buffer overflow at line %d of %s\n",
|
||||
__LINE__,__FILE__);
|
||||
}
|
||||
sprintf(buffer1,"%s%s:%s",manstr,suffix,entry->d_name);
|
||||
|
||||
/* look for "links" to aroff files. (what a kludge) */
|
||||
if ((buffer1[3] != 'l') &&
|
||||
(strcmp(".l",&buffer1[strlen(buffer1)-2])==0)) {
|
||||
FILE *linkptr;
|
||||
char *tp;
|
||||
|
||||
/* dereference the "link" */
|
||||
if ((linkptr = fopen(buffer1,"r")) == NULL) {
|
||||
fprintf(stderr,"couldn't open %s\n",buffer1);
|
||||
} else if (fgets(buffer2,FILENAME_MAX,linkptr)==NULL) {
|
||||
fprintf(stderr,"couldn't read %s\n",buffer1);
|
||||
} else {
|
||||
|
||||
/* drop trailing space and newline */
|
||||
tp = buffer2 + strlen(buffer2) -1;
|
||||
while ((tp>=buffer2) && (isspace(*tp) || *tp == '\n')) {
|
||||
*tp = '\0';
|
||||
tp--;
|
||||
}
|
||||
fclose(linkptr);
|
||||
|
||||
if (access(buffer2,R_OK) == 0) {
|
||||
list1 = addToStringArray(list1, buffer2);
|
||||
total1++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* not a .l "link"; a normal file */
|
||||
list1 = addToStringArray(list1, buffer1);
|
||||
total1++;
|
||||
}
|
||||
}
|
||||
closedir(directory);
|
||||
}
|
||||
|
||||
if (!t_flag) {
|
||||
/*
|
||||
* look in cat subdirectory
|
||||
*/
|
||||
strcpy(buffer1,catstr);
|
||||
strcat(buffer1,suffix);
|
||||
if ((directory = opendir(buffer1)) != NULL) {
|
||||
while ((entry = readdir(directory)) != (struct dirent *) NULL) {
|
||||
|
||||
/* skip if no match */
|
||||
len = strlen(name);
|
||||
if (strncmp(entry->d_name,name,len) ||
|
||||
(entry->d_name[len] != '.')) continue;
|
||||
|
||||
if (strlen(catstr) + strlen(suffix) + strlen(entry->d_name) +
|
||||
strlen(suffix) + 1 >= FILENAME_MAX) {
|
||||
fprintf(stderr,"internal error: buffer overflow at line %d of %s\n",
|
||||
__LINE__,__FILE__);
|
||||
}
|
||||
sprintf(buffer1,"%s%s:%s",catstr,suffix,entry->d_name);
|
||||
list2 = addToStringArray(list2, buffer1);
|
||||
total2++;
|
||||
}
|
||||
closedir(directory);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* eliminate files common to both lists
|
||||
*/
|
||||
len = strlen(suffix);
|
||||
for(i=0; i<total1; i++) {
|
||||
if (list1[i] == NULL) continue;
|
||||
for (j=0; j<total2; j++) {
|
||||
if (list2[j] == NULL) continue;
|
||||
|
||||
getBaseName(buffer1,list1[i]);
|
||||
getBaseName(buffer2,list2[j]);
|
||||
|
||||
#ifdef DEBUG
|
||||
if ((strlen(buffer1) < len + 5) ||
|
||||
(strlen(buffer2) < len + 5)) {
|
||||
fprintf(stderr,"internal error at line %d of %s\n",__LINE__,
|
||||
__FILE__);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
/* match after the respective "manXX/" and "catXX/" */
|
||||
if ( strcmp(&buffer1[len+4],&buffer2[len+4]) == 0 ) {
|
||||
|
||||
p = newerFile(list1[i],list2[j]);
|
||||
if (p == list1[i]) {
|
||||
free(list2[j]);
|
||||
list2[j] = NULL;
|
||||
} else if (p == list2[j]) {
|
||||
free(list1[i]);
|
||||
list1[i] = NULL;
|
||||
break;
|
||||
} else {
|
||||
fprintf(stderr,"internal error at line %d of %s\n\t%s\n\t%s\n",
|
||||
__LINE__,__FILE__,
|
||||
(list1[i]) ? list1[i] : "(NULL)",
|
||||
(list2[j]) ? list2[j] : "(NULL)");
|
||||
perror("newerFile failed");
|
||||
exit(1);
|
||||
}
|
||||
} /* endif */
|
||||
} /* endfor */
|
||||
} /* endfor */
|
||||
|
||||
/*
|
||||
* combine the two lists
|
||||
*/
|
||||
for (i=0;i<total1;i++) {
|
||||
if (list1[i] != NULL) {
|
||||
list3 = addToStringArray(list3, list1[i]);
|
||||
free(list1[i]);
|
||||
}
|
||||
}
|
||||
for (j=0;j<total2;j++) {
|
||||
if (list2[j] != NULL) {
|
||||
list3 = addToStringArray(list3, list2[j]);
|
||||
free(list2[j]);
|
||||
}
|
||||
}
|
||||
free(list1);
|
||||
free(list2);
|
||||
return list3;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* cleanManList
|
||||
*
|
||||
* Pre: list is a NULL-terminated array of strings, where the array
|
||||
* and each string in the array was allocated by malloc.
|
||||
*
|
||||
* Post: all malloc'd memory in list is free'd.
|
||||
*/
|
||||
|
||||
static void cleanManList(char **list) {
|
||||
int i;
|
||||
|
||||
for (i=0; list[i]; i++) {
|
||||
free(list[i]);
|
||||
}
|
||||
free (list);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* display
|
||||
*/
|
||||
|
||||
#define MANSUBDIR 0
|
||||
#define CATSUBDIR 1
|
||||
|
||||
#define FORMAT "Formatting manual page, please wait ..."
|
||||
#define DECOMP "Decompressing manual page, please wait ..."
|
||||
#define DECFOR "Decompressing and formatting manual page, please wait ..."
|
||||
#define OVERFLOW "Internal buffer overflow ... aborted."
|
||||
|
||||
static void display(char *file) {
|
||||
int icompress, isubdir;
|
||||
char *tmac;
|
||||
char *roffer;
|
||||
char *compressor;
|
||||
fileType *ft;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (file == NULL) {
|
||||
fprintf(stderr,"internal error line %d of %s\n",__LINE__,__FILE__);
|
||||
exit(1);
|
||||
}
|
||||
if (strlen(file) < 4) {
|
||||
fprintf(stderr,"internal error line %d of %s\n",__LINE__,__FILE__);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* determine which subdirectory this file is in
|
||||
*/
|
||||
if (strncmp(file,"cat",3) == 0) {
|
||||
isubdir = CATSUBDIR;
|
||||
} else {
|
||||
isubdir = MANSUBDIR;
|
||||
}
|
||||
|
||||
/*
|
||||
* if we're troffing a new file to fmt?, make sure the directory
|
||||
* exists
|
||||
*/
|
||||
if (t_flag && hyphen_flag) {
|
||||
char *p;
|
||||
struct stat sbuf;
|
||||
|
||||
/* ensure the fmt? directory exists */
|
||||
sprintf(linebuf,"fmt%s",&file[3]);
|
||||
if ((p = strchr(linebuf,':')) != NULL) {
|
||||
*p = '\0';
|
||||
#ifdef DEBUG
|
||||
} else if ((p = strchr(linebuf,'/')) == NULL) {
|
||||
fprintf(stderr,"internal error line %d of %s\n",__LINE__,
|
||||
__FILE__);
|
||||
exit(1);
|
||||
#endif
|
||||
} else *p = '\0';
|
||||
if (stat(linebuf,&sbuf) != 0) {
|
||||
fprintf(stderr,"couldn't stat %s: %s. %s skipped\n",
|
||||
linebuf,strerror(errno),file);
|
||||
return;
|
||||
} else if (!(sbuf.st_mode & S_IFDIR)) {
|
||||
fprintf(stderr,"cannot access %s: %s. %s skipped\n",
|
||||
linebuf,strerror(ENOTDIR),file);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* determine the type of compression used, if any
|
||||
*/
|
||||
icompress = getSuffixIndex(file);
|
||||
if (icompress >= 0) {
|
||||
compressor = compressArray[icompress].extractor;
|
||||
if (isubdir == MANSUBDIR) {
|
||||
|
||||
/*
|
||||
* compressed nroff source
|
||||
*/
|
||||
|
||||
if (t_flag && hyphen_flag) {
|
||||
if (strlen(compressor) + 2*strlen(file) + strlen(troff) +
|
||||
strlen(macroPackage) + strlen(tcat) + 12 > BUFFERSIZE) {
|
||||
fprintf(stderr,"%s\n",OVERFLOW);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(linebuf,"%s %s | %s -m%s - > fmt%s",
|
||||
compressor, file, troff, macroPackage, &file[3]);
|
||||
} else if (t_flag) {
|
||||
if (strlen(compressor) + strlen(file) + strlen(troff) +
|
||||
strlen(macroPackage) + strlen(tcat) + 12 > BUFFERSIZE) {
|
||||
fprintf(stderr,"%s\n",OVERFLOW);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(linebuf,"%s %s | %s -m%s - | %s",
|
||||
compressor, file, troff, macroPackage, tcat);
|
||||
} else {
|
||||
/* not troff, jes' plain old nroff */
|
||||
if (strlen(compressor) + strlen(file) + strlen(NROFF) +
|
||||
strlen(macroPackage) + strlen(pager) + 12 > BUFFERSIZE) {
|
||||
fprintf(stderr,"%s\n",OVERFLOW);
|
||||
exit(1);
|
||||
}
|
||||
if (!hyphen_flag) printf("%s\n",DECFOR);
|
||||
sprintf(linebuf,"%s %s | %s -m%s - | %s",
|
||||
compressor, file, NROFF, macroPackage, pager);
|
||||
}
|
||||
} else {
|
||||
|
||||
/*
|
||||
* compressed straight text
|
||||
*/
|
||||
|
||||
if (strlen(compressor)+strlen(file)+strlen(pager)+5 > BUFFERSIZE) {
|
||||
fprintf(stderr,"%s\n",OVERFLOW);
|
||||
exit(1);
|
||||
}
|
||||
if (!hyphen_flag) printf("%s\n",DECOMP);
|
||||
sprintf(linebuf,"%s %s | %s", compressor, file, pager);
|
||||
}
|
||||
} else {
|
||||
if (isubdir == MANSUBDIR) {
|
||||
|
||||
/*
|
||||
* Can be either aroff or nroff source. If it's nroff source,
|
||||
* it must either be a TXT, SRC, or BIN file
|
||||
*/
|
||||
|
||||
if (!hyphen_flag && !t_flag) printf("%s\n",FORMAT);
|
||||
if ((ft = getFileType(file)) == NULL) {
|
||||
perror(file);
|
||||
exit(1);
|
||||
}
|
||||
if ((ft->type == 0x50) || (ft->auxtype == 0x8010)) {
|
||||
|
||||
/*
|
||||
* AppleworksGS Word Processor format; use 'aroff'
|
||||
*/
|
||||
|
||||
if (t_flag) {
|
||||
fprintf(stderr,"cannot use troff on aroff source files\n");
|
||||
return;
|
||||
}
|
||||
if (strlen(AROFF)+strlen(file)+strlen(pager)+5 > BUFFERSIZE) {
|
||||
fprintf(stderr,"%s\n",OVERFLOW);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(linebuf,"%s %s | %s", AROFF, file, pager);
|
||||
|
||||
} else if ((ft->type == TXT) || (ft->type == BIN) ||
|
||||
(ft->type == SRC) || (ft->type == NON)) {
|
||||
|
||||
/*
|
||||
* TeXT, BINary, or SouRCe file; assume nroff source
|
||||
*/
|
||||
if (t_flag && hyphen_flag) {
|
||||
if (strlen(troff) + strlen(macroPackage) +
|
||||
2 * strlen(file) + 7 >= BUFFERSIZE) {
|
||||
fprintf(stderr,"%s\n",OVERFLOW);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(linebuf,"%s -m%s %s > fmt%s",
|
||||
troff, macroPackage, file, &file[3]);
|
||||
} else if (t_flag) {
|
||||
if (strlen(troff) + strlen(macroPackage) + strlen(file) +
|
||||
strlen(tcat) + 7 >= BUFFERSIZE) {
|
||||
fprintf(stderr,"%s\n",OVERFLOW);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(linebuf,"%s -m%s %s | %s",troff,macroPackage,file,tcat);
|
||||
} else {
|
||||
/* not troff, jes' plain old nroff */
|
||||
if (strlen(NROFF) + strlen(macroPackage) +
|
||||
strlen(file) + strlen(pager) + 8 >= BUFFERSIZE) {
|
||||
fprintf(stderr,"%s\n",OVERFLOW);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(linebuf,"%s -m%s %s | %s",NROFF,macroPackage,file,pager);
|
||||
}
|
||||
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"bad file type for %s\n\ttype = %x\n\taux = %lx\n",
|
||||
file,ft->type,ft->auxtype);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* assume straight text */
|
||||
if (strlen(CAT) + strlen(file) + strlen(pager) + 4 >= BUFFERSIZE){
|
||||
fprintf(stderr,"%s\n",OVERFLOW);
|
||||
exit(1);
|
||||
}
|
||||
sprintf(linebuf,"%s %s | %s", CAT, file, pager);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
fprintf(stderr,"DEBUG: BUFFER: %s\n",linebuf);
|
||||
#endif
|
||||
system(linebuf);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getBaseName -- copy the filename pointed to by <in> into the buffer
|
||||
* pointed to by <out>, dropping any compression suffix
|
||||
* that may be on the base name. The set of compression
|
||||
* suffixes is defined by the NULL-terminated compressArray[].
|
||||
*
|
||||
* It is the user's responsibility to ensure that the
|
||||
* buffer *out has been allocated with sufficient space
|
||||
* for the result.
|
||||
*
|
||||
* Returns a pointer to <out>.
|
||||
*/
|
||||
|
||||
static char *getBaseName (char *out, char *in) {
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
strcpy(out,in);
|
||||
if ((p = strrchr(out,'.')) != NULL) {
|
||||
for (i=0; compressArray[i].suffix; i++) {
|
||||
if (strcmp(p,compressArray[i].suffix)==0) {
|
||||
*p = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
|
@ -1,10 +1,6 @@
|
|||
/*
|
||||
* Copyright 1995 by Devin Reade <gdr@myrias.com>. For distribution
|
||||
* information see the README file that is part of the manpack archive,
|
||||
* or contact the author, above.
|
||||
*/
|
||||
|
||||
segment "makewhatis";
|
||||
#ifdef __CCFRONT__
|
||||
#include <14:pragma.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -16,178 +12,118 @@ segment "makewhatis";
|
|||
|
||||
#include "makewhatis.h"
|
||||
|
||||
/* These are the compression types */
|
||||
#define NO_COMPRESS 0
|
||||
#define Z_COMPRESS 1
|
||||
#define F_COMPRESS 2
|
||||
#define G_COMPRESS 3
|
||||
|
||||
#ifdef TEST_PROCESS
|
||||
short v_flag = 1;
|
||||
FILE *output_fp;
|
||||
FILE *error_fp;
|
||||
#else
|
||||
extern FILE *output_fp;
|
||||
extern FILE *error_fp;
|
||||
short v_flag = 1;
|
||||
#endif
|
||||
|
||||
extern GSString255Ptr __C2GSMALLOC (char *s);
|
||||
extern GSString255Ptr __C2GSMALLOC (char *s);
|
||||
extern char buffer[];
|
||||
extern char titlebuf[];
|
||||
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.
|
||||
* (sec> is the section "number". We really only care if it is
|
||||
* either "l" or "local" (because of aroff "links"), otherwise
|
||||
* it is ignored.
|
||||
* 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>.
|
||||
* appended to <whatis_fp>.
|
||||
*/
|
||||
|
||||
void process (char *filename, char *tmp_file, FILE *whatis_fp, char *sec) {
|
||||
void process (char *filename, char *tmp_file, FILE *whatis_fp) {
|
||||
|
||||
FileInfoRecGS info_record; /* used to get the file type */
|
||||
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 */
|
||||
short compression; /* the compression type (if nec) */
|
||||
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>=2) fprintf(output_fp,"Working on file %s/%s ...\n",sec,filename);
|
||||
if (v_flag) fprintf(output_fp,"Working on file %s ...\n",filename);
|
||||
|
||||
/*
|
||||
* get the file basename
|
||||
/*
|
||||
* 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);
|
||||
if (v_flag)
|
||||
fprintf(error_fp,"malloc failed when processing %s -- file skipped\n",
|
||||
filename);
|
||||
return;
|
||||
}
|
||||
strcpy(name,filename);
|
||||
|
||||
/*
|
||||
* check for a compression suffix like ".Z" or ".F"
|
||||
*/
|
||||
|
||||
p1 = name + strlen(name) -1; /* p1 points to last char of name */
|
||||
while ((p1>=name) && (*p1!='.')) p1--;
|
||||
if (p1<=name) { /* <= because we don't want a name beginning with '.' */
|
||||
if (v_flag)
|
||||
fprintf(error_fp,"%s has no suffix -- file skipped\n",
|
||||
filename);
|
||||
if ((suffix = strchr(name,'.')) == NULL) {
|
||||
if (v_flag)
|
||||
fprintf(error_fp,"%s has no suffix -- file skipped\n",
|
||||
filename);
|
||||
return;
|
||||
}
|
||||
if (strcmp(p1,".Z")==0) {
|
||||
compression = Z_COMPRESS;
|
||||
} else if (strcmp(p1,".F")==0) {
|
||||
compression = F_COMPRESS;
|
||||
} else if (strcmp(p1,".gz")==0) {
|
||||
compression = G_COMPRESS;
|
||||
} else compression = NO_COMPRESS;
|
||||
*p1 = '\0';
|
||||
|
||||
/*
|
||||
* define the suffix
|
||||
*/
|
||||
|
||||
if (compression == NO_COMPRESS) {
|
||||
suffix = p1 + 1;
|
||||
} else {
|
||||
while ((p1>=name) && (*p1!='.')) --p1;
|
||||
if (p1<=name) { /* <= because we don't want a name beginning with '.' */
|
||||
if (v_flag)
|
||||
fprintf(error_fp,"%s has deformed file name -- file skipped\n",
|
||||
filename);
|
||||
return;
|
||||
}
|
||||
*p1 = '\0';
|
||||
suffix = p1 + 1;
|
||||
}
|
||||
*suffix = '\0';
|
||||
suffix++;
|
||||
sufflen = strlen(suffix);
|
||||
|
||||
/*
|
||||
* find out the file type
|
||||
*/
|
||||
|
||||
if (compression == NO_COMPRESS) {
|
||||
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;
|
||||
}
|
||||
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 ((compression == NO_COMPRESS) &&
|
||||
(info_record.fileType == 0x50u) &&
|
||||
(info_record.auxType == 0x8010u)
|
||||
) {
|
||||
|
||||
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);
|
||||
if (v_flag>=3) fprintf(stderr,"%s\n",command_buf);
|
||||
sprintf(command_buf,"aroff -b %s >%s",filename,tmp_file);
|
||||
system(command_buf);
|
||||
fillbuffer(tmp_file);
|
||||
fillbuffer(tmp_file);
|
||||
|
||||
} else if (compression == Z_COMPRESS) {
|
||||
|
||||
} else if ( (toupper(*(suffix+sufflen-1))=='Z') &&
|
||||
(*(suffix+sufflen-2)=='.')) {
|
||||
|
||||
/* Compressed man page; uncompress it */
|
||||
sprintf(command_buf,"compress -cd %s > %s",filename,tmp_file);
|
||||
if (v_flag>=3) fprintf(stderr,"%s\n",command_buf);
|
||||
system(command_buf);
|
||||
fillbuffer(tmp_file);
|
||||
sprintf(command_buf,"compress -dc %s >%s",filename,tmp_file);
|
||||
system(command_buf);
|
||||
fillbuffer(tmp_file);
|
||||
|
||||
} else if (compression == F_COMPRESS) {
|
||||
|
||||
/* 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 -cd %s > %s",filename,tmp_file);
|
||||
if (v_flag>=3) fprintf(stderr,"%s\n",command_buf);
|
||||
system(command_buf);
|
||||
fillbuffer(tmp_file);
|
||||
sprintf(command_buf,"freeze -dc %s >%s",filename,tmp_file);
|
||||
system(command_buf);
|
||||
fillbuffer(tmp_file);
|
||||
|
||||
} else if (compression == G_COMPRESS) {
|
||||
|
||||
/* gzipped man page; zcat it */
|
||||
sprintf(command_buf,"gzip -cd %s > %s",filename,tmp_file);
|
||||
if (v_flag>=3) fprintf(stderr,"%s\n",command_buf);
|
||||
system(command_buf);
|
||||
fillbuffer(tmp_file);
|
||||
/* fix suffix for printout */
|
||||
sufflen -= 2;
|
||||
*(suffix + sufflen) = '\0';
|
||||
|
||||
} else if ((*suffix=='l') && (*(suffix+1)=='\0') &&
|
||||
strcmp("l",sec) && strcmp("local",sec)) {
|
||||
|
||||
/* It's a link to another man page; do nothing. */
|
||||
return;
|
||||
} 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 */
|
||||
if (v_flag>=3) fprintf(stderr,"assuming text file\n");
|
||||
fillbuffer(filename);
|
||||
}
|
||||
|
||||
/*
|
||||
* If there was an error, or it is an .so reference to another man
|
||||
* page, then return without writing anything to the database
|
||||
*/
|
||||
|
||||
if ((buffer[0] == '\0') || (titlebuf[0] == '\0')) {
|
||||
return;
|
||||
/* Assume that it's a text file */
|
||||
fillbuffer(filename);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -196,37 +132,33 @@ void process (char *filename, char *tmp_file, FILE *whatis_fp, char *sec) {
|
|||
* formatting.
|
||||
*/
|
||||
|
||||
p1 = buffer;
|
||||
p1 = buffer;
|
||||
while (isspace(*p1)) p1++;
|
||||
namelength = strlen(titlebuf) + strlen(suffix) + 4;
|
||||
namelength = strlen(name) + strlen(suffix) + 4;
|
||||
|
||||
if (namelength > (TABLENGTH * 3)) {
|
||||
fprintf(whatis_fp,"%s (%s) - %s\n", titlebuf, suffix, p1);
|
||||
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", titlebuf, suffix, p1);
|
||||
fprintf(whatis_fp,"%s (%s)\t- %s\n", name, suffix, p1);
|
||||
} else if (namelength > TABLENGTH ) {
|
||||
fprintf(whatis_fp,"%s (%s)\t\t- %s\n", titlebuf, suffix, p1);
|
||||
fprintf(whatis_fp,"%s (%s)\t\t- %s\n", name, suffix, p1);
|
||||
} else {
|
||||
fprintf(whatis_fp,"%s (%s)\t\t\t- %s\n", titlebuf, suffix, p1);
|
||||
fprintf(whatis_fp,"%s (%s)\t\t\t- %s\n", name, suffix, p1);
|
||||
}
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TEST_PROCESS
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
|
||||
output_fp = stdout;
|
||||
error_fp = stderr;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr,"Usage: %s <man_page_file_name>\n",argv[0]);
|
||||
if (argc != 2) {
|
||||
printf("Usage: %s <man_page_file_name>\n",argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
process (argv[1], ":tmp:garbage", stdout, "2");
|
||||
process (argv[1], ":tmp:garbage", stdout);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,386 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995 by Devin Reade <gdr@myrias.com>. For distribution
|
||||
* information see the README file that is part of the manpack archive,
|
||||
* or contact the author, above.
|
||||
*/
|
||||
|
||||
segment "util______";
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <sgtty.h>
|
||||
#include <fcntl.h>
|
||||
#include "util.h"
|
||||
|
||||
/*
|
||||
* getManpath -- return a malloc'd copy of the MANPATH. If MANPATH
|
||||
* isn't defined in the environment, then use USRMAN, then
|
||||
* MANDIR, then if all else fails, use the macro DEFAULT_MANPATH.
|
||||
* If an error occurs, print the cause via perror and exit.
|
||||
*/
|
||||
|
||||
char *getManpath(void) {
|
||||
char *manpath;
|
||||
|
||||
manpath = getenv("MANPATH");
|
||||
if (manpath == NULL) manpath = getenv("USRMAN");
|
||||
if (manpath == NULL) manpath = getenv("MANDIR");
|
||||
if (manpath == NULL) manpath = DEFAULT_MANPATH;
|
||||
|
||||
return Xstrdup(manpath,__LINE__,__FILE__);
|
||||
}
|
||||
|
||||
/*
|
||||
* Xstrdup - a safe strdup; it will handle error conditions and exit
|
||||
* one occurs
|
||||
*
|
||||
* line and file are arbitrary, but are expected to be the
|
||||
* values of __LINE__ and __FILE__ respectively.
|
||||
*/
|
||||
|
||||
char *Xstrdup(char *oldstr, int line, char *file) {
|
||||
char *newstr;
|
||||
|
||||
if ((newstr = malloc(strlen(oldstr)+1)) == NULL) {
|
||||
fprintf(stderr,"Xstrdup failed at line %d in file %s: %s\n",line,
|
||||
file,strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
strcpy(newstr,oldstr);
|
||||
return newstr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Xmalloc - a safe malloc; it will handle error conditions and exit
|
||||
* if one occurs.
|
||||
*
|
||||
* line and file are arbitrary, but are expected to be the
|
||||
* values of __LINE__ and __FILE__ respectively.
|
||||
*/
|
||||
|
||||
void *Xmalloc(size_t size, int line, char *file) {
|
||||
char *p;
|
||||
|
||||
if ((p = malloc(size)) == NULL) {
|
||||
fprintf(stderr,"Xmalloc failed at line %d in file %s: %s\n",line,
|
||||
file,strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
return ((void *) p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Xrealloc - a safe realloc; it will handle error conditions and exit
|
||||
* if one occurs.
|
||||
*
|
||||
* line and file are arbitrary, but are expected to be the
|
||||
* values of __LINE__ and __FILE__ respectively.
|
||||
*/
|
||||
|
||||
void *Xrealloc(void *oldptr, size_t size, int line, char *file) {
|
||||
char *p;
|
||||
|
||||
if ((p = realloc(oldptr, size)) == NULL) {
|
||||
fprintf(stderr,"Xrealloc failed at line %d in file %s: %s\n",line,
|
||||
file,strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
return ((void *) p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* addToStringArray -- add a string to a NULL-terminated array of strings.
|
||||
* If oldArray is NULL, then a new array is created,
|
||||
* otherwise oldArray is expanded.
|
||||
*
|
||||
* WARNING: | Because of the allocation scheme used, any oldArray
|
||||
* | passed to this routine _must_ be the return value
|
||||
* | of a previous call to this routine. This does not
|
||||
* | imply that only one array can be expanded by this
|
||||
* | routine (any number may be expanded).
|
||||
*
|
||||
* The value of macro SLOTS_QUANTUM defined below is
|
||||
* the number of array slots allocated at one time. The
|
||||
* size of the string array is always a multiple of this
|
||||
* value.
|
||||
*
|
||||
* Returns a pointer to an array that contains the old
|
||||
* strings with the new one appended. The array is
|
||||
* NULL-terminated.
|
||||
*/
|
||||
|
||||
#define SLOTS_QUANTUM 10
|
||||
|
||||
char **addToStringArray(char **oldArray, char *string) {
|
||||
|
||||
char **result;
|
||||
int slotsAlloced, slotsUsed;
|
||||
|
||||
if (oldArray == NULL) {
|
||||
|
||||
/*
|
||||
* This is a new array; do the brute force approach
|
||||
*/
|
||||
|
||||
result = Xmalloc(SLOTS_QUANTUM * sizeof(char *), __LINE__, __FILE__);
|
||||
result[0] = Xstrdup(string,__LINE__,__FILE__);
|
||||
result[1] = NULL;
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
* adding to and, if necessary, expanding an old array
|
||||
*/
|
||||
|
||||
/* determine slotsUsed and slotsAlloced */
|
||||
for (slotsUsed=0; oldArray[slotsUsed]; slotsUsed++);
|
||||
|
||||
if (slotsUsed % SLOTS_QUANTUM == SLOTS_QUANTUM-1) { /* space for NULL */
|
||||
slotsAlloced = slotsUsed+1;
|
||||
} else {
|
||||
slotsAlloced = ((slotsUsed / SLOTS_QUANTUM) + 1) * SLOTS_QUANTUM;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
assert(slotsUsed < slotsAlloced);
|
||||
#endif
|
||||
|
||||
/* expand number of slots if necessary */
|
||||
if (slotsUsed+1 < slotsAlloced) {
|
||||
/* there are enough slots; add it to this array */
|
||||
result = oldArray;
|
||||
} else {
|
||||
/* we need more slots; expand the array */
|
||||
slotsAlloced += SLOTS_QUANTUM;
|
||||
result = Xrealloc(oldArray, slotsAlloced * sizeof(char *),
|
||||
__LINE__, __FILE__);
|
||||
}
|
||||
|
||||
/* add the string to the array */
|
||||
result[slotsUsed++] = Xstrdup(string, __LINE__, __FILE__);
|
||||
result[slotsUsed] = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* makePathArray -- parse a path list and break it into a NULL-terminated
|
||||
* array of paths. The original path is left unchanged.
|
||||
*
|
||||
* The delimiter between paths may either be a ' ' or a ':'.
|
||||
* The delimiter is assumed to be a ':' if <path> contains
|
||||
* both '/' and ':' characters but no ' ' character,
|
||||
* otherwise the delimiter is assumed to be a ' '.
|
||||
*/
|
||||
|
||||
char **makePathArray(char *path) {
|
||||
|
||||
char *delim, *p, *q, **result;
|
||||
|
||||
/* set the delimiter */
|
||||
if ( strchr(path,' ')==NULL &&
|
||||
strchr(path,':') &&
|
||||
strchr(path,'/')) {
|
||||
delim = ":";
|
||||
} else {
|
||||
delim = " ";
|
||||
}
|
||||
|
||||
/* build the array */
|
||||
p = Xstrdup(path, __LINE__, __FILE__);
|
||||
q = strtok(p,delim);
|
||||
result = NULL;
|
||||
while (q) {
|
||||
result = addToStringArray(result, q);
|
||||
q = strtok(NULL,delim);
|
||||
}
|
||||
|
||||
free(p);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ncstrcmp -- A case insensitive ("no-case") strcmp
|
||||
*/
|
||||
|
||||
int ncstrcmp(char *a, char *b) {
|
||||
|
||||
while (*a && *b) {
|
||||
if (*a == *b) {
|
||||
a++; b++;
|
||||
continue;
|
||||
}
|
||||
return ((int) *b - *a);
|
||||
}
|
||||
if (!*a && !*b) return 0;
|
||||
return ((int) *b - *a);
|
||||
}
|
||||
|
||||
/*
|
||||
* ncstrncmp -- A case insensitive ("no-case") strncmp
|
||||
*/
|
||||
|
||||
int ncstrncmp (char *a, char *b, unsigned int count) {
|
||||
unsigned int i=0;
|
||||
|
||||
for (i=0; i<count; i++) {
|
||||
if (a[i] == b[i]) {
|
||||
if (!a[i]) break;
|
||||
else continue;
|
||||
}
|
||||
return ((int) b[i]-a[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ncstrstr -- A case insensitive ("no-case") strstr
|
||||
*
|
||||
* This is implemented using a convert-copy-to-single-case-
|
||||
* then-strstr hack.
|
||||
* It's speed could be increased by switching
|
||||
* to a Boyer-Moore scan algorithm anytime strlen(substr) > 5,
|
||||
* and using a straight-forward search for strlen(substr) <= 5.
|
||||
*/
|
||||
|
||||
char *ncstrstr(char *str, char *substr) {
|
||||
|
||||
char *strCopy, *substrCopy, *p;
|
||||
|
||||
strCopy = Xstrdup(str,__LINE__,__FILE__);
|
||||
substrCopy = Xstrdup(substr,__LINE__,__FILE__);
|
||||
|
||||
/* convert the strings */
|
||||
p = strCopy;
|
||||
while (*p) {
|
||||
*p = tolower(*p);
|
||||
p++;
|
||||
}
|
||||
p = substrCopy;
|
||||
while (*p) {
|
||||
*p = tolower(*p);
|
||||
p++;
|
||||
}
|
||||
|
||||
p = strstr(strCopy,substrCopy);
|
||||
free(strCopy);
|
||||
free(substrCopy);
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* newerFile -- Compares the "last modified" time of two paths.
|
||||
* Returns:
|
||||
* the name of the newer file if both files exist
|
||||
* the second file if both exist and have the same mod time
|
||||
* the name of the existing file if one file doesn't exist
|
||||
* NULL and sets errno if neither file exists or if there
|
||||
* is an error.
|
||||
*/
|
||||
|
||||
char *newerFile(char *path1, char *path2) {
|
||||
static struct stat record1, record2;
|
||||
int i,j;
|
||||
|
||||
/*
|
||||
* see if both, only one, or neither files exist
|
||||
*/
|
||||
|
||||
i = access(path1, F_OK);
|
||||
j = access(path2, F_OK);
|
||||
if (i==-1 && j==-1) {
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
} else if (i==-1) {
|
||||
return path2;
|
||||
} else if (j==-1) {
|
||||
return path1;
|
||||
}
|
||||
|
||||
/*
|
||||
* both files exist; stat them
|
||||
*/
|
||||
|
||||
if (stat(path1,&record1) != 0) return NULL;
|
||||
if (stat(path2,&record2) != 0) return NULL;
|
||||
|
||||
return (record1.st_mtime > record2.st_mtime) ? path1 : path2;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getcharraw() - return the next character from stdin without waiting
|
||||
* for a CR to be hit. Returns '\0' and sets errno
|
||||
* on an error.
|
||||
*/
|
||||
|
||||
#define FAILED_CHAR '\0';
|
||||
|
||||
char getcharraw(void) {
|
||||
short oldmode;
|
||||
struct sgttyb s;
|
||||
int count;
|
||||
char c;
|
||||
|
||||
/* obtain old terminal mode */
|
||||
if (gtty(STDIN_FILENO,&s) == -1) return FAILED_CHAR;
|
||||
oldmode = s.sg_flags;
|
||||
|
||||
/* set terminal to CBREAK and obtain keystroke */
|
||||
s.sg_flags |= CBREAK;
|
||||
if (stty(STDIN_FILENO,&s) == -1) return FAILED_CHAR;
|
||||
count = read (STDIN_FILENO, &c, 1);
|
||||
|
||||
/* reset old terminal mode */
|
||||
s.sg_flags = oldmode;
|
||||
if ((stty(STDIN_FILENO,&s) == -1) || (count == -1)) return FAILED_CHAR;
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
* basename -- return a pointer to the base filename (all leading
|
||||
* pathname components removed) of <path>. <path> _must_
|
||||
* point to a NULL-terminated string.
|
||||
*/
|
||||
|
||||
char *basename (char *path) {
|
||||
char *p, dirsep;
|
||||
|
||||
dirsep = (strchr(path,':')) ? ':' : '/';
|
||||
if ((p = strrchr(path,dirsep)) != NULL) {
|
||||
return p+1;
|
||||
} else {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dirname -- return a pointer to a string consisting of the directory
|
||||
* component of <path>. This returns a pointer to an internal
|
||||
* buffer, so the next call to dirname() will overwrite this
|
||||
* buffer. <path> must be a NULL-terminated string.
|
||||
*/
|
||||
|
||||
char *dirname (const char *path) {
|
||||
static char buffer[FILENAME_MAX];
|
||||
char *p, dirsep;
|
||||
|
||||
strcpy(buffer,path);
|
||||
|
||||
dirsep = (strchr(buffer,':')) ? ':' : '/';
|
||||
if ((p = strrchr(buffer,dirsep)) != NULL) {
|
||||
*p = '\0';
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995 by Devin Reade <gdr@myrias.com>. For distribution
|
||||
* information see the README file that is part of the manpack archive,
|
||||
* or contact the author, above.
|
||||
*/
|
||||
|
||||
/*
|
||||
* from util.c
|
||||
*/
|
||||
|
||||
#define DEFAULT_MANPATH "/usr/man"
|
||||
|
||||
char *getManpath(void);
|
||||
char *Xstrdup(char *oldstr, int line, char *file);
|
||||
void *Xmalloc(size_t size, int line, char *file);
|
||||
void *Xrealloc(void *oldptr, size_t size, int line, char *file);
|
||||
char **addToStringArray(char **oldArray, char *string);
|
||||
char **makePathArray(char *path);
|
||||
int ncstrcmp(char *a, char *b);
|
||||
int ncstrncmp (char *a, char *b, unsigned int count);
|
||||
char *ncstrstr(char *str, char *substr);
|
||||
char *newerFile(char *path1, char *path2);
|
||||
char getcharraw(void);
|
||||
char *basename (char *path);
|
||||
char *dirname (const char *path);
|
||||
|
||||
|
||||
/*
|
||||
* from utilgs.c
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned int type;
|
||||
unsigned long int auxtype;
|
||||
} fileType, fileTypePtr;
|
||||
|
||||
fileType *getFileType (char *file);
|
|
@ -1,179 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995 by Devin Reade <gdr@myrias.com>. For distribution
|
||||
* information see the README file that is part of the manpack archive,
|
||||
* or contact the author, above.
|
||||
*/
|
||||
|
||||
segment "utilgs____";
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <gsos.h>
|
||||
#include <orca.h>
|
||||
#include "util.h"
|
||||
|
||||
extern GSString255Ptr __C2GSMALLOC(char *);
|
||||
extern int _mapErr(int);
|
||||
|
||||
/*
|
||||
* access -- a replacement for the standard Gno one; this one will actually
|
||||
* return 0 when testing X_OK on a directory.
|
||||
*
|
||||
* This one still has a bug in it: If the file is a shell command or sys
|
||||
* file, then X_OK will return zero, but not if it is a shell script (as
|
||||
* with 'chtyp -lexec filename').
|
||||
*/
|
||||
|
||||
int access(char *name, int mode) {
|
||||
struct stat statbuf;
|
||||
int realmode=0;
|
||||
|
||||
if (stat(name,&statbuf) == -1) return -1;
|
||||
|
||||
/* check read permission */
|
||||
if ((mode & R_OK) && !(statbuf.st_mode & S_IREAD)) return -1;
|
||||
|
||||
/* check write permission */
|
||||
if ((mode & W_OK) && !(statbuf.st_mode & S_IWRITE)) return -1;
|
||||
|
||||
/*
|
||||
* Check execute mode. Assume directories have execute permission
|
||||
* for GS/OS.
|
||||
*/
|
||||
if (mode & X_OK) {
|
||||
if (statbuf.st_mode & (S_IFDIR | S_IEXEC)) return 0;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
return 0; /* file merely exists */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* chdir -- Replacement for the one normally shipping with Gno.
|
||||
* Returns -1 and sets errno on failure, instead of always
|
||||
* returning zero.
|
||||
*/
|
||||
|
||||
int chdir (const char *pathname) {
|
||||
|
||||
PrefixRecGS record;
|
||||
struct stat statbuf;
|
||||
int result;
|
||||
|
||||
errno = 0;
|
||||
if (stat(pathname,&statbuf) == -1) return -1;
|
||||
|
||||
/* verify that it's a directory */
|
||||
if (!(statbuf.st_mode & S_IFDIR)) {
|
||||
errno = ENOTDIR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* change directory */
|
||||
record.pCount = 2;
|
||||
record.prefixNum = 0; /* prefix 0 is the current directory */
|
||||
record.buffer.setPrefix = __C2GSMALLOC(pathname);
|
||||
if (record.buffer.setPrefix == (GSString255Ptr) NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
SetPrefixGS(&record);
|
||||
|
||||
/* verify success, clean up, and return */
|
||||
result = toolerror();
|
||||
free(record.buffer.setPrefix);
|
||||
if (result) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getFileType -- Get the file type and auxillary file type of a file.
|
||||
* On success it returns a pointer to an internal buffer
|
||||
* containing the file type and aux type. On failure
|
||||
* it returns NULL and sets errno.
|
||||
*/
|
||||
|
||||
fileType *getFileType (char *file) {
|
||||
|
||||
static FileInfoRecGS record;
|
||||
static fileType result;
|
||||
int i;
|
||||
|
||||
/* set the parameters */
|
||||
record.pCount = 4;
|
||||
if ((record.pathname = __C2GSMALLOC(file)) == NULL) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get the info */
|
||||
GetFileInfoGS(&record);
|
||||
|
||||
/* check for errors */
|
||||
i = toolerror();
|
||||
free(record.pathname);
|
||||
if (i) {
|
||||
errno = _mapErr(i);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* set the return value */
|
||||
result.type = record.fileType;
|
||||
result.auxtype = record.auxType;
|
||||
|
||||
return &result;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
#include <stdio.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *p;
|
||||
char buf[1024];
|
||||
int i;
|
||||
fileType *ft;
|
||||
|
||||
if (argc!=2) return -1;
|
||||
|
||||
ft = getFileType(argv[1]);
|
||||
if (ft == NULL) {
|
||||
perror(argv[1]);
|
||||
exit(1);
|
||||
} else {
|
||||
printf("type = %x\nauxtype = %lx\n",ft->type,ft->auxtype);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("F_OK: %d\n",access(argv[1],F_OK));
|
||||
printf("R_OK: %d\n",access(argv[1],R_OK));
|
||||
printf("W_OK: %d\n",access(argv[1],W_OK));
|
||||
printf("X_OK: %d\n",access(argv[1],X_OK));
|
||||
|
||||
if (getwd(buf) == NULL) {
|
||||
perror("getwd failed");
|
||||
exit(-1);
|
||||
}
|
||||
printf("old directory: %s\n",buf);
|
||||
|
||||
if ((i = chdir(argv[1])) !=0) perror ("chdir failed");
|
||||
printf("chdir returned %d\n",i);
|
||||
|
||||
if (getwd(buf) == NULL) {
|
||||
perror("getwd failed");
|
||||
exit(-1);
|
||||
}
|
||||
printf("new directory: %s\n",buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
|
@ -1,187 +0,0 @@
|
|||
.\" This man page is based on another man page copyright (c) 1980
|
||||
.\" by the Regents of the University of California.
|
||||
.\" All rights reserved. The Berkeley software License Agreement
|
||||
.\" specifies the terms and conditions for redistribution.
|
||||
.\"
|
||||
.\" While this manual page is based on one from UCB, the included
|
||||
.\" C source, makefile, and executables are copyright (c) 1995
|
||||
.\" by Devin Reade <gdr@myrias.com>. All rights reserved.
|
||||
.\"
|
||||
.TH WHATIS 1 "Commands and Applications" "24 July 95" "Version 3.0"
|
||||
.SH NAME
|
||||
whatis, apropos \- locate commands by name or keyword lookup
|
||||
.SH SYNOPSIS
|
||||
.BR apropos
|
||||
[[
|
||||
.BI \-M path
|
||||
] | [
|
||||
.BI \-m path
|
||||
]] [
|
||||
.BR -nV
|
||||
]
|
||||
.IR keyword " ..."
|
||||
.br
|
||||
.BR whatis
|
||||
[[
|
||||
.BI \-M path
|
||||
] | [
|
||||
.BI \-m path
|
||||
]] [
|
||||
.BR -nV
|
||||
]
|
||||
.IR keyword ...
|
||||
.SH DESCRIPTION
|
||||
.BR whatis
|
||||
shows the manual page title line for the specified
|
||||
.IR keyword (s),
|
||||
while
|
||||
.BR apropos
|
||||
shows which manual pages contain instances of any of the given
|
||||
.IR keyword (s)
|
||||
in their title line.
|
||||
Each word is considered separately and, for
|
||||
.BR apropos ,
|
||||
the case of letters is ignored.
|
||||
Words which are part of other words are considered; when looking for
|
||||
.IR compile ,
|
||||
.BR apropos
|
||||
will also list all instances of
|
||||
.IR compiler .
|
||||
.LP
|
||||
If a line output by either of these commands starts with
|
||||
.nf
|
||||
|
||||
\fIname\fR (\fIsection\fR) ...
|
||||
|
||||
.fi
|
||||
you can enter
|
||||
.BI man " section name"
|
||||
to get its documentation.
|
||||
.SH OPTIONS
|
||||
.IP "\fB\-M\fP \fIpath\fP"
|
||||
Override the list of standard directories
|
||||
.BR apropos
|
||||
or
|
||||
.BR whatis
|
||||
search for the
|
||||
.BR whatis
|
||||
database.
|
||||
The supplied
|
||||
.I path
|
||||
must be a colon\- or space\-delimited list of directories.
|
||||
This search path may also be set using the environment variable
|
||||
.BR MANPATH .
|
||||
The space delimiter is provided for compatibility with GS/OS's
|
||||
use of the colon as a pathname component delimiter. If the search
|
||||
path contains no spaces nor
|
||||
.B /
|
||||
characters (such as
|
||||
.BR :usr:local:man ),
|
||||
it is assumed to be a single path, not a list of paths.
|
||||
If spaces are used as delimiters, remember to quote them from the
|
||||
shell.
|
||||
.IP "\fB\-m\fP \fIpath\fP"
|
||||
Augment the list of standard directories
|
||||
.BR apropos
|
||||
or
|
||||
.BR whatis
|
||||
search for its database.
|
||||
The supplied
|
||||
.I path
|
||||
must be a colon\- or space\-delimited list of directories.
|
||||
These directories will be searched after the standard directories
|
||||
or the directories supplied by the
|
||||
.BR MANPATH
|
||||
environment variable are searched.
|
||||
If spaces are used as delimiters, remember to quote them from the
|
||||
shell.
|
||||
.IP \fB-n\fP
|
||||
Normally, in addition to searching the various
|
||||
.BR whatis
|
||||
databases,
|
||||
.BR apropos
|
||||
and
|
||||
.BR whatis
|
||||
will also search the Orca shell
|
||||
.BR 15/syscmnd
|
||||
file. Specifying the
|
||||
.BR -n
|
||||
flag will keep
|
||||
.BR apropos
|
||||
and
|
||||
.BR whatis
|
||||
from searching this file.
|
||||
.IP \fB-V\fP
|
||||
Show version information.
|
||||
.SH ENVIRONMENT
|
||||
.IP \fBMANPATH\fP
|
||||
If set,
|
||||
its value overrides
|
||||
.B /usr/man
|
||||
as the list of directories where
|
||||
.BR apropos
|
||||
and
|
||||
.BR whatis
|
||||
search for their databases.
|
||||
(The
|
||||
.B \-M
|
||||
flag, in turn, overrides this value.)
|
||||
See the description of the
|
||||
.B \-M
|
||||
flag for syntax details.
|
||||
.IP \fBUSRMAN\fP
|
||||
If
|
||||
.B MANPATH
|
||||
is not set, then the value of
|
||||
.B USRMAN
|
||||
(if set) overrides
|
||||
.B /usr/man
|
||||
as the list of directories where
|
||||
.BR apropos
|
||||
and
|
||||
.BR whatis
|
||||
search for their databases.
|
||||
(The
|
||||
.B \-M
|
||||
flag, in turn, overrides this value.)
|
||||
See the description of the
|
||||
.B \-M
|
||||
flag for syntax details.
|
||||
.IP \fBMANDIR\fP
|
||||
If neither
|
||||
.B MANPATH
|
||||
nor
|
||||
.B USRMAN
|
||||
is set, then the value of
|
||||
.B MANDIR
|
||||
(if set) overrides
|
||||
.B /usr/man
|
||||
as the list of directories where
|
||||
.BR apropos
|
||||
and
|
||||
.BR whatis
|
||||
search for their databases.
|
||||
(The
|
||||
.B \-M
|
||||
flag, in turn, overrides this value.)
|
||||
See the description of the
|
||||
.B \-M
|
||||
flag for syntax details.
|
||||
.SH FILES
|
||||
.\" .IP \fB/usr/\fR[\fBshare/\fR]\fBman/whatis\fR
|
||||
.BR /usr/ [ share/ ] man/whatis " \-"
|
||||
The
|
||||
.BR whatis (1)
|
||||
database.
|
||||
.SH BUGS
|
||||
Please report any bugs to Devin Reade, <gdr@myrias.ab.ca>.
|
||||
.SH SEE ALSO
|
||||
.BR man (1),
|
||||
.BR whereis (1),
|
||||
.BR catman (8),
|
||||
.BR makewhatis (8)
|
||||
.SH HISTORY
|
||||
The GNO version of
|
||||
.BR apropos
|
||||
first appeared in GNO version 1.0 and was written by Mike Horwath.
|
||||
This version was rewritten from scratch by Devin Reade.
|
|
@ -1,110 +0,0 @@
|
|||
/*
|
||||
* Copyright 1995 by Devin Reade <gdr@myrias.com>. For distribution
|
||||
* information see the README file that is part of the manpack archive,
|
||||
* or contact the author, above.
|
||||
*/
|
||||
|
||||
segment "apropos___";
|
||||
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <libc.h>
|
||||
#include "util.h"
|
||||
#include "man.h"
|
||||
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
static char *versionstr = "3.0";
|
||||
static char *nothing = "nothing appropriate";
|
||||
|
||||
extern void begin_stack_check(void);
|
||||
extern int end_stack_check(void);
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
char *path;
|
||||
int i, matches1, matches2, matches3;
|
||||
short V_flag, M_flag, m_flag, n_flag, err_flag;
|
||||
|
||||
/* make sure Gno is running */
|
||||
if (needsgno()==0) {
|
||||
fprintf(stderr,"Requires Gno/ME\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
begin_stack_check();
|
||||
#endif
|
||||
|
||||
/* initialization */
|
||||
V_flag = M_flag = m_flag = n_flag = err_flag = 0;
|
||||
matches1 = matches2 = matches3 = 0;
|
||||
|
||||
/* parse command line and check usage */
|
||||
while((i = getopt(argc,argv,"M:m:nV")) != EOF) {
|
||||
switch(i) {
|
||||
case 'M':
|
||||
if (m_flag) err_flag++;
|
||||
M_flag++;
|
||||
path = optarg;
|
||||
break;
|
||||
case 'm':
|
||||
if (M_flag) err_flag++;
|
||||
m_flag++;
|
||||
path = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
n_flag++;
|
||||
break;
|
||||
case 'V':
|
||||
V_flag++;
|
||||
break;
|
||||
default:
|
||||
err_flag++;
|
||||
}
|
||||
}
|
||||
if (argc-optind < 1) err_flag++;
|
||||
if (err_flag || V_flag) {
|
||||
fprintf(stderr,"%s version %s by Devin Reade\n",
|
||||
basename(argv[0]),versionstr);
|
||||
}
|
||||
if (err_flag) {
|
||||
fprintf(stderr,
|
||||
"Usage: %s [[-M path] | [-m path]] [-nV] keyword [keyword ...]\n",
|
||||
basename(argv[0]));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* do the search */
|
||||
if (M_flag) {
|
||||
manpath = path;
|
||||
} else {
|
||||
manpath = getManpath();
|
||||
}
|
||||
matches1 = apropos(argc-optind, &argv[optind], WHATIS_MODE);
|
||||
if (!M_flag) free(manpath);
|
||||
if (m_flag) {
|
||||
manpath = path;
|
||||
matches2 = apropos(argc-optind, &argv[optind], WHATIS_MODE);
|
||||
}
|
||||
if (!n_flag) {
|
||||
matches3 = apropos(argc-optind, &argv[optind], ORCA_W_MODE);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
if (matches1>0) i+= matches1;
|
||||
if ( m_flag && matches2>0) i+=matches2;
|
||||
if (!n_flag && matches3>0) i+=matches3;
|
||||
|
||||
if (i==0) {
|
||||
fprintf(stderr,"%s: %s\n",basename(argv[0]),nothing);
|
||||
}
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
fprintf(stderr,"stack usage: %d bytes\n",end_stack_check());
|
||||
#endif
|
||||
|
||||
if ((matches1>=0) && (matches2>=0) && (matches3>=0) && i>0) return 0;
|
||||
return 1;
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
whereis v1.1 (Gno)
|
||||
|
||||
============
|
||||
INSTALLATION
|
||||
============
|
||||
|
||||
If you have Gno and dmake, type "dmake install". Otherwise:
|
||||
|
||||
FILE: COPY TO:
|
||||
|
||||
Gno: Orca/whereis 17/whereis [if desired]
|
||||
Gno/whereis /usr/bin/whereis
|
||||
whereis.1 $(USRMAN)/man1/whereis.1
|
||||
|
||||
Orca: Orca/whereis 17/whereis
|
||||
whereis.cat 17/help/whereis
|
||||
|
||||
=====
|
||||
NOTES
|
||||
=====
|
||||
|
||||
Whereis is VERY dependant on pathnames.
|
||||
|
||||
This archive consist of both Orca shell and Gno versions. Both versions
|
||||
will work with both shells, the difference being that in the Gno version
|
||||
the leading "31" has been stripped from pathnames. (It is no longer needed
|
||||
because of namespace.)
|
||||
|
||||
I strongly recommend _not_ using the Gno version with the Orca shell unless
|
||||
you have actual partitions named "/usr", "/bin", "/etc", and so on, as you
|
||||
will get _many_ accesses to all online devices in this case.
|
||||
|
||||
A -V flag and rVersion resource have been added to show version information.
|
||||
|
||||
A -c flag has been added to provide case-insensitive searches.
|
||||
|
||||
The source is released because it is small, and you can change the pathnames
|
||||
if you wish.
|
||||
|
||||
=======
|
||||
HISTORY
|
||||
=======
|
||||
|
||||
v1.1: Rewritten to take advantage of Gno 2.x's namespace feature.
|
||||
Separate Gno and Orca versions created.
|
||||
Prototyped.
|
||||
Disabled references to the /man volume (both versions).
|
||||
Fixed up man page.
|
||||
Added -V flag to show version information.
|
||||
Added -c flag to force case-insensitive searches.
|
||||
Added "17" to list of directories to search for binaries.
|
||||
Added "17/help" to list of directories to search for man pages.
|
||||
|
||||
v1.0: Initial release.
|
||||
|
||||
=======
|
||||
AUTHORS
|
||||
=======
|
||||
|
||||
Author of the original original port from BSD to Gno is unknown. (Jawaid?)
|
||||
|
||||
v1.1 updated by G. Devin Reade <glyn@cs.ualberta.ca>
|
|
@ -1,39 +0,0 @@
|
|||
# Makefile.mk generated by makedmake (Gno) v1.1.1 for Dennis Vadura's dmake
|
||||
|
||||
BINDIR = 17
|
||||
MANDIR = /usr/man
|
||||
|
||||
# development flags
|
||||
# DEFINES += -DDEBUG -DCASEFLAG
|
||||
# CFLAGS += -w -s1023 -G25 $(DEFINES)
|
||||
# LDFLAGS +=
|
||||
# LDLIBS = /usr/lib/stack.a
|
||||
|
||||
# distribution flags
|
||||
DEFINES += -DCASEFLAG
|
||||
CFLAGS += -w -s1023 -O $(DEFINES)
|
||||
LDFLAGS +=
|
||||
LDLIBS =
|
||||
|
||||
all:
|
||||
echo Targets ...
|
||||
echo
|
||||
echo dmake install ... to copy executable file to $(BINDIR) and manual
|
||||
echo page to $(MANDIR)
|
||||
echo
|
||||
echo dmake whereis ... to compile source code. This should not be
|
||||
echo necessary.
|
||||
|
||||
whereis : whereis.o
|
||||
$(CC) $(LDFLAGS) -o whereis whereis.o $(LDLIBS)
|
||||
|
||||
whereis.o : whereis.c
|
||||
$(CC) $(CFLAGS) -c whereis.c
|
||||
|
||||
install :
|
||||
-$(RM) /usr/bin/whereis
|
||||
-$(RM) 17/whereis
|
||||
/bin/cp -f whereis $(BINDIR)
|
||||
/bin/cp -f whereis.1 $(MANDIR)/man1
|
||||
|
||||
.SILENT: all
|
|
@ -1,133 +0,0 @@
|
|||
.\" @(#)whereis.1 1.17 90/02/15 SMI; from UCB 4.2
|
||||
.TH WHEREIS 1 "Commands and Applications" "2 January 1994" "Orca/Gno Version 1.1"
|
||||
.SH NAME
|
||||
whereis \- locate the binary, source, and manual page files for a command
|
||||
.SH SYNOPSIS
|
||||
.B whereis
|
||||
[
|
||||
.B \-bcmsuV
|
||||
] [
|
||||
.B \-BMS
|
||||
.IR directory .\|.\|.
|
||||
.B \-f
|
||||
]
|
||||
\fIfilename\fP\|
|
||||
.SH DESCRIPTION
|
||||
.B whereis
|
||||
locates source/binary and manuals sections for specified
|
||||
files.
|
||||
The supplied names are first stripped of leading pathname components
|
||||
and any (single) trailing extension of the form
|
||||
.BR .ext ,
|
||||
for example,
|
||||
.BR .c .
|
||||
Prefixes of
|
||||
.B s.
|
||||
resulting from use of source code control are also dealt with.
|
||||
.B whereis
|
||||
then attempts to locate the desired program in
|
||||
a list of standard places:
|
||||
.RS
|
||||
.nf
|
||||
/bin
|
||||
/usr/bin
|
||||
/usr/sbin
|
||||
/usr/games
|
||||
/usr/include
|
||||
/usr/hosts
|
||||
/usr/local
|
||||
/usr/local/bin
|
||||
/etc
|
||||
/man (disabled)
|
||||
/usr/man
|
||||
/usr/src/bin
|
||||
/usr/src/etc
|
||||
17/
|
||||
17/help
|
||||
.fi
|
||||
.RE
|
||||
.SH OPTIONS
|
||||
.B \-b
|
||||
Search only for binaries.
|
||||
.LP
|
||||
.B \-c
|
||||
Make the search case\-insensitive.
|
||||
.LP
|
||||
.B \-f
|
||||
Terminate the last directory list and signals the start of file names,
|
||||
and
|
||||
.I must
|
||||
be used when any of the
|
||||
.BR \-B ,
|
||||
.BR \-M ,
|
||||
or
|
||||
.B \-S
|
||||
options are used.
|
||||
.LP
|
||||
.B \-m
|
||||
Search only for manual sections.
|
||||
.LP
|
||||
.B \-s
|
||||
Search only for sources.
|
||||
.LP
|
||||
.B \-u
|
||||
Search for unusual entries. A file is said to be unusual if it does
|
||||
not have one entry of each requested type. Therefore
|
||||
.B "whereis -m -u *"
|
||||
asks for those files in the current
|
||||
directory which have no documentation.
|
||||
.LP
|
||||
.B \-B
|
||||
Change or otherwise limit the places where
|
||||
.B whereis
|
||||
searches for binaries.
|
||||
.LP
|
||||
.B \-M
|
||||
Change or otherwise limit the places where
|
||||
.B whereis
|
||||
searches for
|
||||
manual sections.
|
||||
.LP
|
||||
.B \-S
|
||||
Change or otherwise limit the places where
|
||||
.B whereis
|
||||
searches for sources.
|
||||
.LP
|
||||
.B \-V
|
||||
Print version information.
|
||||
.SH EXAMPLE
|
||||
Find all files in
|
||||
.B /usr/bin
|
||||
which are not documented
|
||||
in
|
||||
.B /usr/share/man/man1
|
||||
with source in
|
||||
.BR /usr/src/cmd :
|
||||
.RS
|
||||
.nf
|
||||
|
||||
example% cd /usr/ucb
|
||||
example% whereis \-u \-M /usr/share/man/man1 \-S /usr/src/cmd \-f *
|
||||
.fi
|
||||
.RE
|
||||
.SH FILES
|
||||
.nf
|
||||
/usr/src/*
|
||||
/usr/{doc,man}/*
|
||||
/usr/{lib,bin,ucb,old,new,local}
|
||||
/etc
|
||||
.fi
|
||||
.SH SEE ALSO
|
||||
.BR chdir (2V)
|
||||
.SH BUGS
|
||||
Since
|
||||
.B whereis
|
||||
uses
|
||||
.BR chdir (2V)
|
||||
to run faster, pathnames given with the
|
||||
.BR \-M ,
|
||||
.BR \-S ,
|
||||
or
|
||||
.B \-B
|
||||
must be full; that is, they must begin with a
|
||||
.BR / .
|
|
@ -1,528 +0,0 @@
|
|||
#ifdef __CCFRONT__
|
||||
#include <14:pragma.h>
|
||||
#endif
|
||||
/*-
|
||||
* Copyright (c) 1980 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
char copyright[] =
|
||||
"@(#) Copyright (c) 1980 The Regents of the University of California.\n\
|
||||
All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)whereis.c 5.5 (Berkeley) 4/18/91";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <libc.h>
|
||||
|
||||
/*
|
||||
* Pointers that will correspond to the GNO_* or ORCA_* structs, below
|
||||
*/
|
||||
|
||||
static char **bindirs;
|
||||
static char **mandirs;
|
||||
static char **srcdirs;
|
||||
|
||||
/*
|
||||
* These are the directories to check when running under the Gno shell
|
||||
*/
|
||||
|
||||
static char *GNO_bindirs[] = {
|
||||
"/bin",
|
||||
"/usr/bin",
|
||||
"/usr/sbin",
|
||||
"/usr/games",
|
||||
"/usr/include",
|
||||
"/usr/hosts",
|
||||
"/usr/local",
|
||||
"/usr/local/bin",
|
||||
"17",
|
||||
"/etc",
|
||||
0
|
||||
};
|
||||
/* This needs to be redone - man pages live with sources */
|
||||
static char *GNO_mandirs[] = {
|
||||
|
||||
/*
|
||||
These are disabled since /man is not usually present; this eliminates
|
||||
a long series of accesses to the 3.5" drive.
|
||||
|
||||
"/man/man1",
|
||||
"/man/man2",
|
||||
"/man/man3",
|
||||
"/man/man4",
|
||||
"/man/man5",
|
||||
"/man/man6",
|
||||
"/man/man7",
|
||||
"/man/man8",
|
||||
"/man/cat1",
|
||||
"/man/cat2",
|
||||
"/man/cat3",
|
||||
"/man/cat4",
|
||||
"/man/cat5",
|
||||
"/man/cat6",
|
||||
"/man/cat7",
|
||||
"/man/cat8",
|
||||
*/
|
||||
|
||||
"/usr/man/cat1",
|
||||
"/usr/man/cat2",
|
||||
"/usr/man/cat3",
|
||||
"/usr/man/cat4",
|
||||
"/usr/man/cat5",
|
||||
"/usr/man/cat6",
|
||||
"/usr/man/cat7",
|
||||
"/usr/man/cat8",
|
||||
"/usr/man/man1",
|
||||
"/usr/man/man2",
|
||||
"/usr/man/man3",
|
||||
"/usr/man/man4",
|
||||
"/usr/man/man5",
|
||||
"/usr/man/man6",
|
||||
"/usr/man/man7",
|
||||
"/usr/man/man8",
|
||||
"17/help",
|
||||
0
|
||||
};
|
||||
static char *GNO_srcdirs[] = {
|
||||
"/usr/src/bin",
|
||||
"/usr/src/etc",
|
||||
/* still need libs */
|
||||
0
|
||||
};
|
||||
|
||||
/*
|
||||
* These are the directories to check when running under the Orca shell
|
||||
*/
|
||||
|
||||
static char *ORCA_bindirs[] = {
|
||||
"31/bin",
|
||||
"31/usr/bin",
|
||||
"31/usr/sbin",
|
||||
"31/usr/games",
|
||||
"31/usr/include",
|
||||
"31/usr/hosts",
|
||||
"31/usr/local",
|
||||
"31/usr/local/bin",
|
||||
"17",
|
||||
"31/etc",
|
||||
0
|
||||
};
|
||||
/* This needs to be redone - man pages live with sources */
|
||||
static char *ORCA_mandirs[] = {
|
||||
|
||||
/*
|
||||
These are disabled since /man is not usually present; this eliminates
|
||||
a long series of accesses to the 3.5" drive.
|
||||
|
||||
"31/man/man1",
|
||||
"31/man/man2",
|
||||
"31/man/man3",
|
||||
"31/man/man4",
|
||||
"31/man/man5",
|
||||
"31/man/man6",
|
||||
"31/man/man7",
|
||||
"31/man/man8",
|
||||
"31/man/cat1",
|
||||
"31/man/cat2",
|
||||
"31/man/cat3",
|
||||
"31/man/cat4",
|
||||
"31/man/cat5",
|
||||
"31/man/cat6",
|
||||
"31/man/cat7",
|
||||
"31/man/cat8",
|
||||
*/
|
||||
|
||||
"31/usr/man/cat1",
|
||||
"31/usr/man/cat2",
|
||||
"31/usr/man/cat3",
|
||||
"31/usr/man/cat4",
|
||||
"31/usr/man/cat5",
|
||||
"31/usr/man/cat6",
|
||||
"31/usr/man/cat7",
|
||||
"31/usr/man/cat8",
|
||||
"31/usr/man/man1",
|
||||
"31/usr/man/man2",
|
||||
"31/usr/man/man3",
|
||||
"31/usr/man/man4",
|
||||
"31/usr/man/man5",
|
||||
"31/usr/man/man6",
|
||||
"31/usr/man/man7",
|
||||
"31/usr/man/man8",
|
||||
"17/help",
|
||||
0
|
||||
};
|
||||
static char *ORCA_srcdirs[] = {
|
||||
"31/usr/src/bin",
|
||||
"31/usr/src/etc",
|
||||
/* still need libs */
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
#ifdef CASEFLAG
|
||||
int cflag = 0;
|
||||
#endif
|
||||
|
||||
char sflag = 1;
|
||||
char bflag = 1;
|
||||
char mflag = 1;
|
||||
char **Sflag;
|
||||
int Scnt;
|
||||
char **Bflag;
|
||||
int Bcnt;
|
||||
char **Mflag;
|
||||
int Mcnt;
|
||||
char uflag;
|
||||
|
||||
char *verstring = "whereis -- Apple IIgs Version 1.2";
|
||||
|
||||
void getlist (int *argcp, char ***argvp, char ***flagp, int *cntp);
|
||||
void zerof(void);
|
||||
void lookup (register char *cp);
|
||||
void looksrc (char *cp);
|
||||
void lookbin (char *cp);
|
||||
void lookman (char *cp);
|
||||
void findv (char **dirv, int dirc, char *cp);
|
||||
void find (char **dirs, char *cp);
|
||||
void findin (char *dir, char *cp);
|
||||
int itsit (register char *cp, register char *dp);
|
||||
|
||||
#ifdef DEBUG
|
||||
void begin_stack_check(void);
|
||||
int end_stack_check(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* whereis name
|
||||
* look for source, documentation and binaries
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
#ifdef DEBUG
|
||||
begin_stack_check();
|
||||
#endif
|
||||
|
||||
argc--, argv++;
|
||||
if (argc == 0) {
|
||||
usage:
|
||||
|
||||
#ifdef CASEFLAG
|
||||
fprintf(stderr, "whereis [ -sbmucV ] [ -SBM dir ... -f ] name...\n");
|
||||
#else /* not CASEFLAG */
|
||||
fprintf(stderr, "whereis [ -sbmuV ] [ -SBM dir ... -f ] name...\n");
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
if (getenv("CHECKSTACK"))
|
||||
printf("Stack Usage: %d\n",end_stack_check());
|
||||
#endif
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* select which directory structures we're going to use */
|
||||
if (needsgno()) {
|
||||
bindirs = GNO_bindirs;
|
||||
mandirs = GNO_mandirs;
|
||||
srcdirs = GNO_srcdirs;
|
||||
} else {
|
||||
bindirs = ORCA_bindirs;
|
||||
mandirs = ORCA_mandirs;
|
||||
srcdirs = ORCA_srcdirs;
|
||||
}
|
||||
|
||||
do
|
||||
if (argv[0][0] == '-') {
|
||||
register char *cp = argv[0] + 1;
|
||||
while (*cp) switch (*cp++) {
|
||||
|
||||
case 'f':
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
getlist(&argc, &argv, &Sflag, &Scnt);
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
getlist(&argc, &argv, &Bflag, &Bcnt);
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
getlist(&argc, &argv, &Mflag, &Mcnt);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
zerof();
|
||||
sflag++;
|
||||
continue;
|
||||
|
||||
case 'u':
|
||||
uflag++;
|
||||
continue;
|
||||
|
||||
case 'b':
|
||||
zerof();
|
||||
bflag++;
|
||||
continue;
|
||||
|
||||
case 'm':
|
||||
zerof();
|
||||
mflag++;
|
||||
continue;
|
||||
|
||||
#ifdef CASEFLAG
|
||||
case 'c':
|
||||
cflag++;
|
||||
continue;
|
||||
#endif /* not CASEFLAG */
|
||||
|
||||
case 'V':
|
||||
printf("%s\n",verstring);
|
||||
continue;
|
||||
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
argv++;
|
||||
} else
|
||||
lookup(*argv++);
|
||||
while (--argc > 0);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (getenv("CHECKSTACK"))
|
||||
printf("Stack Usage: %d\n",end_stack_check());
|
||||
#endif
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void getlist (int *argcp, char ***argvp, char ***flagp, int *cntp) {
|
||||
(*argvp)++;
|
||||
*flagp = *argvp;
|
||||
*cntp = 0;
|
||||
for ((*argcp)--; *argcp > 0 && (*argvp)[0][0] != '-'; (*argcp)--)
|
||||
(*cntp)++, (*argvp)++;
|
||||
(*argcp)++;
|
||||
(*argvp)--;
|
||||
}
|
||||
|
||||
|
||||
void zerof (void) {
|
||||
|
||||
if (sflag && bflag && mflag)
|
||||
sflag = bflag = mflag = 0;
|
||||
}
|
||||
|
||||
int count;
|
||||
int print;
|
||||
|
||||
|
||||
void lookup (register char *cp) {
|
||||
register char *dp;
|
||||
|
||||
for (dp = cp; *dp; dp++)
|
||||
continue;
|
||||
for (; dp > cp; dp--) {
|
||||
if (*dp == '.') {
|
||||
*dp = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (dp = cp; *dp; dp++)
|
||||
if (*dp == '/')
|
||||
cp = dp + 1;
|
||||
if (uflag) {
|
||||
print = 0;
|
||||
count = 0;
|
||||
} else
|
||||
print = 1;
|
||||
again:
|
||||
if (print)
|
||||
printf("%s:", cp);
|
||||
if (sflag) {
|
||||
looksrc(cp);
|
||||
if (uflag && print == 0 && count != 1) {
|
||||
print = 1;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
count = 0;
|
||||
if (bflag) {
|
||||
lookbin(cp);
|
||||
if (uflag && print == 0 && count != 1) {
|
||||
print = 1;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
count = 0;
|
||||
if (mflag) {
|
||||
lookman(cp);
|
||||
if (uflag && print == 0 && count != 1) {
|
||||
print = 1;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
if (print)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void looksrc (char *cp) {
|
||||
if (Sflag == 0) {
|
||||
find(srcdirs, cp);
|
||||
} else
|
||||
findv(Sflag, Scnt, cp);
|
||||
}
|
||||
|
||||
void lookbin (char *cp) {
|
||||
if (Bflag == 0)
|
||||
find(bindirs, cp);
|
||||
else
|
||||
findv(Bflag, Bcnt, cp);
|
||||
}
|
||||
|
||||
void lookman (char *cp) {
|
||||
if (Mflag == 0) {
|
||||
find(mandirs, cp);
|
||||
} else
|
||||
findv(Mflag, Mcnt, cp);
|
||||
}
|
||||
|
||||
void findv (char **dirv, int dirc, char *cp) {
|
||||
while (dirc > 0)
|
||||
findin(*dirv++, cp), dirc--;
|
||||
}
|
||||
|
||||
void find (char **dirs, char *cp) {
|
||||
while (*dirs)
|
||||
findin(*dirs++, cp);
|
||||
}
|
||||
|
||||
void findin (char *dir, char *cp) {
|
||||
DIR *dirp;
|
||||
struct dirent *dp;
|
||||
|
||||
dirp = opendir(dir);
|
||||
if (dirp == NULL)
|
||||
return;
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
if (itsit(cp, dp->d_name)) {
|
||||
count++;
|
||||
if (print)
|
||||
printf(" %s/%s", dir, dp->d_name);
|
||||
}
|
||||
}
|
||||
closedir(dirp);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CASEFLAG
|
||||
|
||||
int itsit (register char *cp, register char *dp) {
|
||||
register int i = strlen(dp);
|
||||
|
||||
if (cflag) {
|
||||
if ( (dp[0] == 's' || dp[0] == 'S') && dp[1] == '.' && itsit(cp, dp+2))
|
||||
return (1);
|
||||
while (*cp && *dp && (tolower(*cp) == tolower(*dp)))
|
||||
cp++, dp++, i--;
|
||||
if (*cp == 0 && *dp == 0)
|
||||
return (1);
|
||||
while (isdigit(*dp))
|
||||
dp++;
|
||||
if (*cp == 0 && *dp++ == '.') {
|
||||
--i;
|
||||
/* removed for GNO/ME, cause we want to look up compressed files also. */
|
||||
/* while (i > 0 && *dp)
|
||||
if (--i, *dp++ == '.')
|
||||
return (*dp++ == 'C' && *dp++ == 0);
|
||||
*/
|
||||
return (1);
|
||||
}
|
||||
} else {
|
||||
if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
|
||||
return (1);
|
||||
while (*cp && *dp && *cp == *dp)
|
||||
cp++, dp++, i--;
|
||||
if (*cp == 0 && *dp == 0)
|
||||
return (1);
|
||||
while (isdigit(*dp))
|
||||
dp++;
|
||||
if (*cp == 0 && *dp++ == '.') {
|
||||
--i;
|
||||
/* removed for GNO/ME, cause we want to look up compressed files also. */
|
||||
/* while (i > 0 && *dp)
|
||||
if (--i, *dp++ == '.')
|
||||
return (*dp++ == 'C' && *dp++ == 0);
|
||||
*/
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
#else /* not CASEFLAG */
|
||||
|
||||
int itsit (register char *cp, register char *dp) {
|
||||
register int i = strlen(dp);
|
||||
|
||||
if (dp[0] == 's' && dp[1] == '.' && itsit(cp, dp+2))
|
||||
return (1);
|
||||
while (*cp && *dp && *cp == *dp)
|
||||
cp++, dp++, i--;
|
||||
if (*cp == 0 && *dp == 0)
|
||||
return (1);
|
||||
while (isdigit(*dp))
|
||||
dp++;
|
||||
if (*cp == 0 && *dp++ == '.') {
|
||||
--i;
|
||||
/* removed for GNO/ME, cause we want to look up compressed files also. */
|
||||
/* while (i > 0 && *dp)
|
||||
if (--i, *dp++ == '.')
|
||||
return (*dp++ == 'C' && *dp++ == 0);*/
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,140 +0,0 @@
|
|||
$Id: README,v 1.2 1996/01/22 02:40:43 gdr Exp $
|
||||
|
||||
This is the README file for the describe package. This package is
|
||||
designated as version 1.0.2, and consists of the following utilities:
|
||||
|
||||
describe v1.0.2 - show database entries describing the current
|
||||
status of programs
|
||||
|
||||
descc v1.0.2 - the describe source compiler
|
||||
|
||||
descu v1.0.2 - the describe source updater
|
||||
|
||||
ABOUT DESCRIBE AND DESCC
|
||||
========================
|
||||
|
||||
This is yet another project I've been sitting on for a while, but have
|
||||
finally decided to release. The basic idea of the 'describe' package
|
||||
(the descc "compiler" and describe itself) is to provide a quick, easy
|
||||
way of accessing information related to the utilities which so many
|
||||
different people are releasing these days. The reason it sat around on
|
||||
my harddrive so long is I was having qualms about its designated role in
|
||||
life. I wasn't sure exactly what I wanted it to do. Well, I've decided
|
||||
to KISS for now: descc simply compiles the utility list, which I maintain,
|
||||
into a (very) simple "database" located in /usr/local/lib/
|
||||
[alternatively, the full path given in the environment variable DESCDB will be
|
||||
used, if it is set. sb]. The companion utility 'describe' is used to
|
||||
fetch information about a particular utility from this "database".
|
||||
|
||||
descc is fairly limited, as is the "database" format itself. Part of the
|
||||
KISS (or it wouldn't be out now) design philosophy ;). Usage is simple:
|
||||
when you get a new listing (I'll provide monthly updates), simply "descc
|
||||
<filename>" where <filename> is the name of the newly released update.
|
||||
descc will simply write over the old database and replace it with the
|
||||
new. (Note: No appendages are allowed by descc. See descu.)
|
||||
|
||||
As always, coments are appreciated. And, moreso than on other projects,
|
||||
I'd appreciate some comments about the direction I'm going in, suggestions
|
||||
as to where to take this, etc. I have a feeling that some fields in the
|
||||
format (eg, FTP:) are rather useless, and I'd like to know what you guys
|
||||
out there think.
|
||||
|
||||
James Brookes
|
||||
jamesb@ecst.csuchico.edu
|
||||
|
||||
ABOUT DESCU
|
||||
===========
|
||||
|
||||
I think describe and descc were really good ideas; they sure beat the
|
||||
text file list of Gno utilities that James used to keep. The one major
|
||||
shortfall I found was having to manually update the describe database
|
||||
source every time I wanted to include a new entry.
|
||||
|
||||
I therefore wrote descu, the describe updater, which is also rather
|
||||
limited due to following the KISS principle.
|
||||
|
||||
For completeness, I have also added the man pages describe.1, descc.8,
|
||||
and descu.8. I briefly pondered having a describe.5, but alas I was too
|
||||
lazy; you can find the file formats as part of descc.8.
|
||||
|
||||
Devin Reade
|
||||
gdr@myrias.ab.ca
|
||||
|
||||
INSTALLATION
|
||||
============
|
||||
|
||||
You can either type "dmake install", or do the following:
|
||||
|
||||
mkdir -p /usr/local/lib
|
||||
cp ./describe /usr/local/bin
|
||||
cp ./descc /usr/sbin
|
||||
cp ./descu /usr/sbin
|
||||
rm /usr/local/bin/descc
|
||||
|
||||
You will also want to do the following, which is NOT done by dmake's
|
||||
install target:
|
||||
|
||||
rehash
|
||||
descc ./describe.source
|
||||
|
||||
CHANGES
|
||||
=======
|
||||
|
||||
This details changes to the entire distribution.
|
||||
|
||||
v1.02 October 1995
|
||||
descc now circumvents a bug in ORCA/C's ftell() function.
|
||||
describe can now find entries that are not all lower-case.
|
||||
describe will now print the name of entries in the case
|
||||
they were entered into the database.
|
||||
descu now sorts the describe source file case-insensitive.
|
||||
describe and descc can now find the database in a path given
|
||||
by the environment variable DESCDB. If DESCDB is not set,
|
||||
/usr/local/lib/describe is used, as before.
|
||||
A new "Shell:" field has been added to the format of the database.
|
||||
|
||||
v1.01 May 1995
|
||||
Initial release for descu.
|
||||
Added -h and -v flags to describe and descc.
|
||||
Common defines and typedefs were extracted to desc.h.
|
||||
Descc now exits -1 on failure (vice 0).
|
||||
In descc, some more error checking and flushing were added. Also,
|
||||
mygets wasn't dereferencing one of its arguments properly.
|
||||
Allocated stack size was increased from 512 to 768 bytes.
|
||||
Describe and descc were modified not to be dependant on the size
|
||||
of integers.
|
||||
Ran source files through indent(1).
|
||||
|
||||
v1.0 Feb 1994
|
||||
Initial release for describe and descc.
|
||||
|
||||
AUTHORS
|
||||
=======
|
||||
|
||||
The original describe and descc utilities and the describe format were
|
||||
written by James Brookes <jamesb@ecst.csuchico.edu>.
|
||||
|
||||
The descu utility and v1.01 modifications to describe and descc were by
|
||||
Devin Reade <gdr@myrias.ab.ca>.
|
||||
|
||||
v1.02 modifications to describe, descc and descu were by Soenke Behrens
|
||||
<sbehrens@contech.demon.co.uk>.
|
||||
|
||||
LEGALESE
|
||||
========
|
||||
|
||||
The describe and descc utilities are copyright (c) 1994-1995 by James
|
||||
Brookes. The descu utility is copyright (c) 1995 by Devin Reade.
|
||||
|
||||
These programs may be freely copied provided that the archive, including
|
||||
source files and this README, remain intact. Modified versions of these
|
||||
programs may not be distributed without the permission of the respective
|
||||
authors.
|
||||
|
||||
Contact the respective authors for permission to include these programs on
|
||||
any commercial software collections. Permission is granted to Usenet sites
|
||||
and GEnie Information Services for inclusion in software archives.
|
||||
|
||||
The Apple IIGS executable files distributed with this archive contain
|
||||
material from the ORCA/C Run-Time Libraries, copyright 1987-1995 by
|
||||
Byte Works, Inc. Used with permission.
|
20
usr.orca.bin/describe/README.FIRST
Normal file
20
usr.orca.bin/describe/README.FIRST
Normal file
|
@ -0,0 +1,20 @@
|
|||
About Me
|
||||
~~~~~~~~~
|
||||
Um. Not much to say right now. I'll get back to this part later.
|
||||
|
||||
About My Source
|
||||
~~~~~~~~~~~~~~~
|
||||
I guess I used to feel a bit propriatary about it, but a couple of things
|
||||
have caused me to change my mind:
|
||||
|
||||
1) Losing over half of the eps source, may it rest in peace.
|
||||
2) Yes, people can profit by and sometimes even improve (gasp!) my
|
||||
source. And I'd be a grumpy old coot if I didn't let them.
|
||||
|
||||
So what this means is that most (not all) of my stuff will be released
|
||||
with full source from now henceforth. I only ask of you, the humble masses
|
||||
yearning to be free, please don't distribute modified versions of my programs
|
||||
without first contacting me. I think this is only fair.
|
||||
|
||||
James Brookes
|
||||
jamesb@ecst.csuchico.edu
|
|
@ -1,30 +0,0 @@
|
|||
#pragma optimize -1
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
char *basename (char *name) {
|
||||
char *p, brk;
|
||||
|
||||
/* checking for ':' is GS-specific */
|
||||
brk = (strchr(name,':')) ? ':' : '/';
|
||||
p = strrchr(name,brk);
|
||||
|
||||
return ((p) ? p+1 : name);
|
||||
}
|
||||
|
||||
|
||||
#ifdef SHELLCOMD
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr,"Usage: basename file_name\nVersion 1.0\n");
|
||||
return -1;
|
||||
}
|
||||
printf("%s\n",basename(argv[1]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* SHELLCOMD */
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* Header file for the describe package. This file is
|
||||
* used by describe(1), descc(8), and descu(8).
|
||||
*/
|
||||
|
||||
#define QUOTE_CHAR '#'
|
||||
#define DATABASE "/usr/local/lib/describe"
|
||||
|
||||
#define FIELD_LEN 9
|
||||
#define NAME_LEN 34
|
||||
#define MAX_LINE_LENGTH 81
|
||||
#define FIELD_COUNT 7 /* number of fields below, not including comments */
|
||||
|
||||
#define NAME "Name: "
|
||||
#define VERSION "Version: "
|
||||
#define SHELL "Shell: "
|
||||
#define AUTHOR "Author: "
|
||||
#define CONTACT "Contact: "
|
||||
#define WHERE "Where: "
|
||||
#define FTP "FTP: "
|
||||
|
||||
#define NAME_SHORT "Name:"
|
||||
#define VERSION_SHORT "Version:"
|
||||
#define SHELL_SHORT "Shell:"
|
||||
#define AUTHOR_SHORT "Author:"
|
||||
#define CONTACT_SHORT "Contact:"
|
||||
#define WHERE_SHORT "Where:"
|
||||
#define FTP_SHORT "FTP:"
|
||||
|
||||
#ifndef FALSE
|
||||
# define FALSE 0
|
||||
# define TRUE 1
|
||||
#endif
|
||||
|
||||
typedef short int2;
|
||||
typedef long int4;
|
||||
|
||||
typedef struct nameEntry_tag {
|
||||
char name[NAME_LEN];
|
||||
long int offset;
|
||||
} nameEntry;
|
||||
|
||||
typedef struct descEntryTag {
|
||||
char *name;
|
||||
char *data;
|
||||
} descEntry;
|
||||
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
/* extern int getopt_restart(void); */
|
||||
extern void begin_stack_check(void);
|
||||
extern int end_stack_check(void);
|
||||
extern char *basename(char *);
|
|
@ -1,97 +0,0 @@
|
|||
.TH DESCC 8 "System Administration" "7 May 1995" "Version 1.0.2"
|
||||
.SH NAME
|
||||
descc \- the describe(1) source compiler
|
||||
.SH SYNOPSIS
|
||||
.BR descc " [" -hV ]
|
||||
.I sourcefile
|
||||
.SH DESCRIPTION
|
||||
.BR descc
|
||||
compiles the describe source file
|
||||
.I sourcefile
|
||||
and saves the result to the system describe database.
|
||||
.SH OPTIONS
|
||||
.nf
|
||||
\fB-h\fR Show usage information.
|
||||
|
||||
\fB-V\fR Show version information.
|
||||
.fi
|
||||
.SH "FILE FORMATS"
|
||||
The describe source file consists of comments and records. A comment
|
||||
is any line starting with the
|
||||
.BR #
|
||||
character. Each record consists of eight fields. The first
|
||||
seven consist of one line of text and begin with the following identifiers:
|
||||
.nf
|
||||
|
||||
Name: (The name of the program.)
|
||||
Version: (The current version number.)
|
||||
Shell: (The shell(s) the program was written for.)
|
||||
Author: (The author or maintainer of the program.)
|
||||
Contact: (How to contact the Author, typically an
|
||||
email address.)
|
||||
Where: (Where the program should be installed.)
|
||||
FTP: (An ftp site from which the program may be
|
||||
obtained.)
|
||||
|
||||
.fi
|
||||
The last field consists of multiple lines of text. It should be
|
||||
a brief description of the program. The following is an example of
|
||||
a complete record:
|
||||
.nf
|
||||
|
||||
Name: describe
|
||||
Version: 1.0.2
|
||||
Shell: ORCA/Shell, GNO/ME
|
||||
Author: James Brookes
|
||||
Contact: jamesb@ecst.csuchico.edu
|
||||
Where: /usr/local/bin
|
||||
FTP: ftp.cco.caltech.edu
|
||||
|
||||
Print a multi-line description obtained from the compiled
|
||||
'describe' database; giving utility name, version, intended shell,
|
||||
author, author's contact, where the utility is, as well as where the
|
||||
utility can be FTPd from on the InterNet.
|
||||
|
||||
.fi
|
||||
.LP
|
||||
The describe database file consists of a
|
||||
.BR Header ,
|
||||
a set of
|
||||
.BR "Name Entries" ,
|
||||
and a set of
|
||||
.BR Records ,
|
||||
in the following format:
|
||||
.nf
|
||||
|
||||
Header
|
||||
2 bytes: Short Int, number of \fBName Entries\fR
|
||||
|
||||
Name Entries
|
||||
34 bytes: NULL-terminated string; name of the utility.
|
||||
4 bytes: Long Int, offset of the \fBrecord\fR in file.
|
||||
|
||||
Records
|
||||
8 variable-length NULL-terminated strings.
|
||||
|
||||
.fi
|
||||
.SH FILES
|
||||
/usr/local/lib/describe \- the system
|
||||
.B describe
|
||||
database. If the environment variable
|
||||
.B DESCDB
|
||||
is set, its value will be used instead.
|
||||
.SH ENVIRONMENT
|
||||
.IP DESCDB
|
||||
Full path to the system describe database. If
|
||||
.B DESCDB
|
||||
is set, its value is used instead of the default location
|
||||
/usr/local/lib/describe.
|
||||
|
||||
.SH AUTHOR
|
||||
James Brookes <jamesb@ecst.csuchico.edu>.
|
||||
.SH "SEE ALSO"
|
||||
.BR apropos (1),
|
||||
.BR describe (1),
|
||||
.BR man (1),
|
||||
.BR whatis (1),
|
||||
.BR descu (8).
|
|
@ -1,15 +1,15 @@
|
|||
#ifndef _ORCAC_
|
||||
#define _ORCAC_
|
||||
#endif
|
||||
|
||||
#ifdef _ORCAC_
|
||||
#pragma optimize -1
|
||||
#pragma stacksize 512
|
||||
#endif /* _ORCAC_ */
|
||||
|
||||
/* */
|
||||
/* descc - compile info file into describe database file */
|
||||
/* */
|
||||
/* v1.0.2 - One bug removed. Recompiled to accomodate new */
|
||||
/* SHELL line and DESCDB environment var */
|
||||
/* Soenke Behrens [Sun Oct 22 1995] */
|
||||
/* */
|
||||
/* v1.0.1 - Added -h and -V flags [Sat May 06 1995] */
|
||||
/* Extracted certain #defines to "desc.h" */
|
||||
/* Now uses getopt for command line parsing. */
|
||||
/* Fixed some potential bugs. */
|
||||
/* */
|
||||
/* v1.0.0 - James Brookes [Sat Oct 23 1993] */
|
||||
/* released [Thu Mar 31 1994] [!!!!!!!!!!!] */
|
||||
/* */
|
||||
|
@ -30,248 +30,202 @@
|
|||
/* */
|
||||
/* Records */
|
||||
/* */
|
||||
/* 8 variable-length Null-terminated strings. */
|
||||
/* 7 variable-length Null-terminated strings. */
|
||||
/* */
|
||||
|
||||
#pragma optimize 15
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
#include <assert.h>
|
||||
#include "desc.h"
|
||||
|
||||
#define _VERSION_ "v1.0.2"
|
||||
#pragma lint -1
|
||||
|
||||
/* prototypes */
|
||||
|
||||
void usage(char *callname);
|
||||
void version(char *callname);
|
||||
void puke(int error,int lines);
|
||||
int mygets(char *buffer, int2 *lines, FILE *FInPtr);
|
||||
int mygets(char *buffer, int *lines, FILE *FInPtr);
|
||||
|
||||
int Vflag;
|
||||
/* defines */
|
||||
|
||||
/* version - print it out */
|
||||
typedef struct nameEntry_tag
|
||||
|
||||
void version (char *callname) {
|
||||
Vflag++;
|
||||
fprintf(stderr,"%s version %s\n",callname,_VERSION_);
|
||||
return;
|
||||
}
|
||||
{
|
||||
char name[34];
|
||||
long int offset;
|
||||
}nameEntry;
|
||||
|
||||
#define _VERSION_ "v1.0.0"
|
||||
#define QUOTE_CHAR '#'
|
||||
#define OUTFILE "/usr/local/lib/describe"
|
||||
|
||||
#define FIELD_LEN 9
|
||||
|
||||
#define NAME "Name: "
|
||||
#define VERSION "Version: "
|
||||
#define AUTHOR "Author: "
|
||||
#define CONTACT "Contact: "
|
||||
#define WHERE "Where: "
|
||||
#define FTP "FTP: "
|
||||
|
||||
/* */
|
||||
/* usage - you know what to do */
|
||||
/* */
|
||||
|
||||
void usage (char *callname) {
|
||||
if (!Vflag) version(callname);
|
||||
fprintf(stderr,"usage: %s [-hV] <describe_sourcefile>\n",callname);
|
||||
exit(-1);
|
||||
}
|
||||
void usage (char *callname)
|
||||
|
||||
{
|
||||
fprintf(stderr,"%s %s\n",callname,_VERSION_);
|
||||
fprintf(stderr,"usage: %s <describe sourcefile>\n",callname);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* */
|
||||
/* puke - stdlib errors */
|
||||
/* */
|
||||
|
||||
void puke (int error,int lines) {
|
||||
fprintf(stderr,"\nError $%x in line %d of script\n",error,lines);
|
||||
fflush(stdout);
|
||||
exit(error);
|
||||
}
|
||||
void puke (int error,int lines)
|
||||
|
||||
{
|
||||
fprintf(stderr,"\nError $%x in line %d of script\n",error,lines);
|
||||
fflush(stdout);
|
||||
exit(error);
|
||||
}
|
||||
|
||||
/* */
|
||||
/* mygets - get a line (skipping commented lines) and increment line count */
|
||||
/* */
|
||||
|
||||
int mygets (char *buffer, int2 *lines, FILE *FInPtr) {
|
||||
char *p, c;
|
||||
int mygets (char *buffer, int *lines, FILE *FInPtr)
|
||||
|
||||
do {
|
||||
if (fgets(buffer,MAX_LINE_LENGTH,FInPtr)==NULL) {
|
||||
return(-1);
|
||||
}
|
||||
p = buffer + strlen(buffer) - 1; /* remove trailing \n */
|
||||
if (*p == '\n') {
|
||||
*p = '\0';
|
||||
} else {
|
||||
fprintf(stderr,"Line %d exceeds %d characters. Remainder ignored.\n",
|
||||
*lines,MAX_LINE_LENGTH-1);
|
||||
do {
|
||||
c = fgetc(FInPtr);
|
||||
} while ((c!='\n') && !feof(FInPtr));
|
||||
}
|
||||
(*lines)++;
|
||||
} while(buffer[0] == QUOTE_CHAR || buffer[0] == '\n');
|
||||
return(0);
|
||||
}
|
||||
{
|
||||
int i;
|
||||
|
||||
do
|
||||
|
||||
{
|
||||
if (fgets(buffer,80,FInPtr)==NULL)
|
||||
return(-1);
|
||||
buffer[strlen(buffer)-1] = '\0'; /* remove trailing \n */
|
||||
lines++;
|
||||
}
|
||||
|
||||
while(buffer[0] == QUOTE_CHAR || buffer[0] == '\n');
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* */
|
||||
/* Mainline */
|
||||
/* */
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
FILE *FInPtr, *FOutPtr;
|
||||
long int *record_locs, currLoc, endOfFile;
|
||||
char *buffer;
|
||||
int2 lines, namecount, i, j;
|
||||
nameEntry nameStruct;
|
||||
int c, errflag;
|
||||
char *db_path;
|
||||
int main (int argc, char **argv)
|
||||
|
||||
/* initialize globals */
|
||||
Vflag=0;
|
||||
errflag=0;
|
||||
#ifdef STACK_CHECK
|
||||
begin_stack_check();
|
||||
#endif
|
||||
{
|
||||
FILE *FInPtr, *FOutPtr;
|
||||
long int *record_locs, currLoc, endOfFile;
|
||||
char *tmpPtr, *buffer;
|
||||
int lines, namecount, c, i, j;
|
||||
nameEntry nameStruct;
|
||||
|
||||
assert(sizeof(int2)==2);
|
||||
assert(sizeof(int4)==4);
|
||||
if (argc != 2)
|
||||
usage(argv[0]);
|
||||
|
||||
/* Get database path: If DESCDB is set, use it,
|
||||
otherwise use DATABASE */
|
||||
/* open input and output files */
|
||||
|
||||
if (getenv("DESCDB") == 0)
|
||||
{
|
||||
if ((db_path = strdup(DATABASE)) == 0)
|
||||
{
|
||||
fprintf(stderr,"couldn't allocate path variable\n");
|
||||
exit (-1);
|
||||
}
|
||||
} else {
|
||||
if ((db_path = strdup(getenv("DESCDB"))) == 0)
|
||||
{
|
||||
fprintf(stderr,"couldn't allocate path variable\n");
|
||||
exit (-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* parse command line */
|
||||
while ((c = getopt(argc, argv, "hV")) != EOF) {
|
||||
switch (c) {
|
||||
case 'V':
|
||||
version(basename(argv[0]));
|
||||
break;
|
||||
case 'h': /*FALLTHROUGH*/
|
||||
default:
|
||||
errflag++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (errflag || (argc-optind != 1))
|
||||
{
|
||||
free (db_path);
|
||||
usage(basename(argv[0]));
|
||||
}
|
||||
buffer = (char *) malloc (81);
|
||||
if ((FInPtr = fopen(argv[1],"r")) == NULL)
|
||||
|
||||
{
|
||||
fprintf(stderr,"Error opening %s; exiting.\n",argv[1]);
|
||||
free(buffer);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* open input and output files */
|
||||
if ((FOutPtr = fopen(OUTFILE,"w+")) == NULL)
|
||||
|
||||
if ((buffer = malloc (MAX_LINE_LENGTH)) == NULL) {
|
||||
fprintf(stderr,"couldn't allocate line buffer\n");
|
||||
free (db_path);
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
if ((FInPtr = fopen(argv[argc-1],"r")) == NULL) {
|
||||
fprintf(stderr,"Error opening %s; exiting.\n",argv[argc-1]);
|
||||
free (db_path);
|
||||
free(buffer);
|
||||
exit(1);
|
||||
}
|
||||
{
|
||||
fprintf(stderr,"Error opening output file %s; exiting.\n",OUTFILE);
|
||||
free(buffer);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((FOutPtr = fopen(db_path,"wb+")) == NULL) {
|
||||
fprintf(stderr,"Error opening database file %s; exiting.\n",db_path);
|
||||
free (db_path);
|
||||
free(buffer);
|
||||
exit(1);
|
||||
}
|
||||
/* Compile array of names */
|
||||
|
||||
/* Compile array of names */
|
||||
lines = 0;
|
||||
namecount = 0;
|
||||
lines = 0;
|
||||
namecount = 0;
|
||||
fseek(FOutPtr,2,SEEK_CUR); /* space for # of array entries */
|
||||
|
||||
/* space for # of array entries */
|
||||
fwrite((void *)&namecount,sizeof(namecount),1,FOutPtr);
|
||||
while(mygets(buffer,&lines,FInPtr) != -1)
|
||||
|
||||
while(mygets(buffer,&lines,FInPtr) != -1) {
|
||||
if (!strncmp(buffer,NAME,FIELD_LEN)) { /* found a match */
|
||||
strncpy(nameStruct.name,&buffer[FIELD_LEN],NAME_LEN-1);
|
||||
nameStruct.name[NAME_LEN-1] = '\0';
|
||||
fwrite((void *)&nameStruct,sizeof(nameStruct),1,FOutPtr);
|
||||
namecount++;
|
||||
}
|
||||
}
|
||||
|
||||
if ((record_locs = malloc (namecount*sizeof(long int)))==NULL) {
|
||||
fprintf(stderr,"malloc of record_locs failed (%ld bytes); exiting\n",
|
||||
(long) namecount*sizeof(long int));
|
||||
exit(-1);
|
||||
}
|
||||
rewind(FInPtr);
|
||||
buffer[0] = '\0';
|
||||
lines = 0;
|
||||
fputc('\t',FOutPtr);
|
||||
/* Increment to first field */
|
||||
|
||||
while (strncmp(buffer,NAME,FIELD_LEN)) /* found a match! */
|
||||
mygets(buffer,&lines,FInPtr);
|
||||
|
||||
{ /* BUGBUG 22/10/95 Soenke Behrens */
|
||||
/* ORCA/C does not advance the file position indicator */
|
||||
/* correctly after above fputc(). This tries to remedy */
|
||||
/* the situation. Take out once library has been fixed */
|
||||
fprintf(FOutPtr,"Junk");
|
||||
fseek(FOutPtr,-4,SEEK_CUR);
|
||||
}
|
||||
|
||||
/* Write out records and keep track of their file offsets */
|
||||
for (i = 0; i < namecount; i++) {
|
||||
record_locs[i] = ftell(FOutPtr);
|
||||
|
||||
/* print out <Version>, <Shell>, <Author>, <Contact>, <Where>, <FTP> */
|
||||
for (j = 0; j < FIELD_COUNT-1; j++) {
|
||||
buffer[FIELD_LEN] = '\0';
|
||||
mygets(buffer,&lines,FInPtr);
|
||||
fprintf(FOutPtr,"%s\n",&buffer[FIELD_LEN]);
|
||||
}
|
||||
{
|
||||
if (!strncmp(buffer,NAME,FIELD_LEN)) /* found a match */
|
||||
|
||||
/* handle <description> field */
|
||||
for (;;) {
|
||||
if (mygets(buffer,&lines,FInPtr) == -1) break;
|
||||
if (!strncmp(buffer,NAME,FIELD_LEN)) break;
|
||||
fprintf(FOutPtr,"%s ",buffer);
|
||||
}
|
||||
fputc('\n',FOutPtr);
|
||||
}
|
||||
{
|
||||
tmpPtr = &buffer[FIELD_LEN];
|
||||
strcpy(nameStruct.name,tmpPtr);
|
||||
fwrite(&nameStruct,sizeof(nameStruct),1,FOutPtr);
|
||||
namecount++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
endOfFile = ftell(FOutPtr);
|
||||
fflush(FOutPtr); /*gdr 1*/
|
||||
rewind(FOutPtr);
|
||||
fwrite((void *)&namecount,sizeof(namecount),1,FOutPtr);
|
||||
fflush(FOutPtr); /*gdr 1*/
|
||||
record_locs = (long int *) malloc (namecount*sizeof(long int));
|
||||
rewind(FInPtr);
|
||||
buffer[0] = '\0';
|
||||
lines = 0;
|
||||
fprintf(FOutPtr,"\t");
|
||||
|
||||
/* Increment to first field */
|
||||
|
||||
/* time to go through the record_locs array and backpatch in */
|
||||
/* all the record locations. A little slower than necessary */
|
||||
/* perhaps, but it gets the job done. */
|
||||
while (strncmp(buffer,NAME,FIELD_LEN)) /* found a match! */
|
||||
mygets(buffer,&lines,FInPtr);
|
||||
|
||||
for (i = 0; i < namecount; i++) {
|
||||
fread(&nameStruct,sizeof(nameStruct),1,FOutPtr);
|
||||
fseek(FOutPtr,-(sizeof(nameStruct)),SEEK_CUR);
|
||||
nameStruct.offset = record_locs[i];
|
||||
fwrite((void *)&nameStruct,sizeof(nameStruct),(size_t) 1,FOutPtr);
|
||||
fflush(FOutPtr);
|
||||
}
|
||||
for (i = 0; i < namecount; i++)
|
||||
|
||||
fseek(FOutPtr,endOfFile,SEEK_SET);
|
||||
fclose(FOutPtr);
|
||||
free(db_path);
|
||||
free(record_locs);
|
||||
free(buffer);
|
||||
{
|
||||
record_locs[i] = ftell(FOutPtr);
|
||||
for (j = 0; j < 5; j++) /* parse additional info */
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
fprintf(stderr,"stack usage: %d bytes\n",end_stack_check());
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
mygets(buffer,&lines,FInPtr);
|
||||
tmpPtr = &buffer[FIELD_LEN];
|
||||
fprintf(FOutPtr,"%s\n",tmpPtr); /* print out fields */
|
||||
}
|
||||
|
||||
/* handle comment field */
|
||||
|
||||
while (1)
|
||||
|
||||
{
|
||||
if (mygets(buffer,&lines,FInPtr) == -1)
|
||||
break;
|
||||
if (!strncmp(buffer,NAME,FIELD_LEN)) /* until next field */
|
||||
break;
|
||||
fprintf(FOutPtr,"%s ",buffer);
|
||||
}
|
||||
|
||||
fprintf(FOutPtr,"\n");
|
||||
}
|
||||
|
||||
endOfFile = ftell(FOutPtr);
|
||||
rewind(FOutPtr);
|
||||
fwrite(&namecount,2,1,FOutPtr);
|
||||
|
||||
/* time to go through the record_locs array and backpatch in */
|
||||
/* all the record locations. A little slower than necessary */
|
||||
/* perhaps, but it gets the job done. */
|
||||
|
||||
for (i = 0; i < namecount; i++)
|
||||
|
||||
{
|
||||
currLoc = ftell(FOutPtr);
|
||||
fread(&nameStruct,sizeof(nameStruct),1,FOutPtr);
|
||||
fseek(FOutPtr,-(sizeof(nameEntry)),SEEK_CUR);
|
||||
nameStruct.offset = record_locs[i];
|
||||
fwrite(&nameStruct,sizeof(nameStruct),1,FOutPtr);
|
||||
}
|
||||
|
||||
fseek(FOutPtr,endOfFile,SEEK_SET);
|
||||
fclose(FOutPtr);
|
||||
free(record_locs);
|
||||
free(buffer);
|
||||
}
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
Name: descc
|
||||
Version: 1.0.2
|
||||
Shell: ORCA/Shell, GNO/ME
|
||||
Author: James Brookes
|
||||
Contact: jamesb@ecst.csuchico.edu
|
||||
Where: /usr/sbin
|
||||
FTP: ftp.cco.caltech.edu
|
||||
|
||||
Compile a source file into a 'describe' database file.
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
.TH DESCRIBE 1 "Commands and Applications" "7 May 1995" "Version 1.0.2"
|
||||
.SH NAME
|
||||
describe \- show information about a program
|
||||
.SH SYNOPSIS
|
||||
.BR describe " [" -hvV ]
|
||||
.I program
|
||||
.SH DESCRIPTION
|
||||
.BR describe
|
||||
will show current information about
|
||||
.IR program .
|
||||
This information includes:
|
||||
.nf
|
||||
|
||||
The name of the program;
|
||||
The program version number;
|
||||
The shell the program was written for;
|
||||
The author (or the person currently maintaining the program);
|
||||
Contact information for the author;
|
||||
Where the utility should be installed;
|
||||
An FTP site from which the program may be obtained, and;
|
||||
A brief description of the program.
|
||||
|
||||
.fi
|
||||
.LP
|
||||
.BR describe
|
||||
uses a database compiled by
|
||||
.BR descc (8).
|
||||
.SH OPTIONS
|
||||
.nf
|
||||
\fB-h\fR Show usage information.
|
||||
|
||||
\fB-v\fR Verbose debugging mode.
|
||||
|
||||
\fB-V\fR Show version information.
|
||||
.fi
|
||||
.SH FILES
|
||||
/usr/local/lib/describe \- the system
|
||||
.B describe
|
||||
database. If the environment variable
|
||||
.B DESCDB
|
||||
is set, its value will be used instead.
|
||||
.SH ENVIRONMENT
|
||||
.IP DESCDB
|
||||
Full path to the system describe database. If
|
||||
.B DESCDB
|
||||
is set, its value is used instead of the default location
|
||||
/usr/local/lib/describe.
|
||||
|
||||
.SH AUTHOR
|
||||
James Brookes <jamesb@ecst.csuchico.edu>.
|
||||
.SH "SEE ALSO"
|
||||
.BR apropos (1),
|
||||
.BR man (1),
|
||||
.BR whatis (1),
|
||||
.BR descc (8),
|
||||
.BR descu (8).
|
|
@ -1,22 +1,16 @@
|
|||
/*
|
||||
* describe(1) -- Copyright 1993-1995 James Brookes. See the README and
|
||||
* man page for details.
|
||||
*
|
||||
* We have to have this pragma in here; Orca/C's bit 5 optimization
|
||||
* (loop invariant removal) kills code somewhere in this file, resulting
|
||||
* in a system panic.
|
||||
*/
|
||||
|
||||
#pragma optimize 31
|
||||
#pragma optimize 15
|
||||
#pragma stacksize 512
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include "desc.h"
|
||||
|
||||
#define _VERSION_ "v1.0.2"
|
||||
#pragma lint -1
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
void begin_stack_check(void);
|
||||
int end_stack_check(void);
|
||||
#endif
|
||||
|
||||
/* prototypes */
|
||||
|
||||
|
@ -24,214 +18,188 @@ void usage(char *callname);
|
|||
void print_entry(FILE *FInPtr, long int index);
|
||||
void myprintf(char *string, int wordwrap_size);
|
||||
|
||||
int Vflag;
|
||||
/* defines */
|
||||
|
||||
void version (char *callname) {
|
||||
Vflag++;
|
||||
fprintf(stderr,"%s version %s\n",callname,_VERSION_);
|
||||
return;
|
||||
}
|
||||
typedef struct nameEntry_tag
|
||||
|
||||
void usage(char *callname) {
|
||||
if (!Vflag) version(callname);
|
||||
fprintf(stderr,"usage: %s [-hv] <utility_name>\n",callname);
|
||||
exit(-1);
|
||||
}
|
||||
{
|
||||
char name[34];
|
||||
long int offset;
|
||||
}nameEntry;
|
||||
|
||||
void myprintf(char *string, int wordwrap_size) {
|
||||
int length = 0;
|
||||
char *headString, *tailString;
|
||||
|
||||
headString = tailString = string;
|
||||
printf("\n");
|
||||
while (1) {
|
||||
tailString++; length++;
|
||||
if (*tailString == '\0') {
|
||||
printf("%s",headString);
|
||||
return;
|
||||
} else if (length == wordwrap_size) {
|
||||
while (*tailString != ' ')
|
||||
tailString--;
|
||||
*tailString = '\0';
|
||||
printf("%s\n",headString);
|
||||
headString = tailString+1;
|
||||
length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print_entry(FILE *FInPtr, long int index) {
|
||||
char *buffer;
|
||||
int i;
|
||||
|
||||
if ((buffer = (char *) malloc (1024)) == 0)
|
||||
{
|
||||
fprintf(stderr,"couldn't allocate buffer\n");
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
fseek(FInPtr,index,SEEK_SET);
|
||||
|
||||
printf("%s",VERSION);
|
||||
fgets(buffer,MAX_LINE_LENGTH,FInPtr);
|
||||
printf("%s",buffer);
|
||||
|
||||
printf("%s",SHELL);
|
||||
fgets(buffer,MAX_LINE_LENGTH,FInPtr);
|
||||
printf("%s",buffer);
|
||||
|
||||
printf("%s",AUTHOR);
|
||||
fgets(buffer,MAX_LINE_LENGTH,FInPtr);
|
||||
printf("%s",buffer);
|
||||
|
||||
printf("%s",CONTACT);
|
||||
fgets(buffer,MAX_LINE_LENGTH,FInPtr);
|
||||
printf("%s",buffer);
|
||||
|
||||
printf("%s",WHERE);
|
||||
fgets(buffer,MAX_LINE_LENGTH,FInPtr);
|
||||
printf("%s",buffer);
|
||||
|
||||
printf("%s",FTP);
|
||||
fgets(buffer,MAX_LINE_LENGTH,FInPtr);
|
||||
printf("%s",buffer);
|
||||
|
||||
fgets(buffer,1024,FInPtr);
|
||||
myprintf(buffer,75);
|
||||
|
||||
free(buffer);
|
||||
#ifdef STACK_CHECK
|
||||
printf("Stack: %d\n",end_stack_check());
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
FILE *FInPtr;
|
||||
char searchName[NAME_LEN];
|
||||
int2 verbose, numOfEntries, cmp, offset1, offset2, check, i;
|
||||
nameEntry nameStruct;
|
||||
int c, errflag;
|
||||
char *p, *tmp;
|
||||
char *db_path;
|
||||
#define _VERSION_ "v1.0"
|
||||
#define INFILE "/usr/local/lib/describe"
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
begin_stack_check();
|
||||
#endif
|
||||
|
||||
verbose = FALSE;
|
||||
Vflag = FALSE;
|
||||
errflag = FALSE;
|
||||
#define NAME "Name: "
|
||||
#define VERSION "Version: "
|
||||
#define AUTHOR "Author: "
|
||||
#define CONTACT "Contact: "
|
||||
#define WHERE "Where: "
|
||||
#define FTP "FTP: "
|
||||
|
||||
/* Get database path: If DESCDB is set, use it,
|
||||
otherwise use DATABASE */
|
||||
void usage(char *callname)
|
||||
|
||||
if (getenv("DESCDB") == 0)
|
||||
{
|
||||
if ((db_path = strdup(DATABASE)) == 0)
|
||||
{
|
||||
fprintf(stderr,"couldn't allocate path variable\n");
|
||||
exit (-1);
|
||||
}
|
||||
} else {
|
||||
if ((db_path = strdup(getenv("DESCDB"))) == 0)
|
||||
{
|
||||
fprintf(stderr,"couldn't allocate path variable\n");
|
||||
exit (-1);
|
||||
}
|
||||
}
|
||||
{
|
||||
fprintf(stderr,"Describe %s\n",_VERSION_);
|
||||
fprintf(stderr,"usage: %s -[v] <utilityname>\n",callname);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
while ((c = getopt(argc,argv,"hvV")) != EOF) {
|
||||
switch (c) {
|
||||
case 'v':
|
||||
verbose = TRUE;
|
||||
break;
|
||||
case 'V':
|
||||
version(basename(argv[0]));
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
errflag = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (errflag || (argc-optind != 1))
|
||||
{
|
||||
free (db_path);
|
||||
usage(basename(argv[0]));
|
||||
}
|
||||
void myprintf(char *string, int wordwrap_size)
|
||||
|
||||
{
|
||||
int length = 0;
|
||||
char *headString, *tailString;
|
||||
|
||||
headString = tailString = string;
|
||||
printf("\n");
|
||||
while (1)
|
||||
|
||||
if ((FInPtr = fopen(db_path,"rb")) == NULL) {
|
||||
perror("couldn't open database");
|
||||
free (db_path);
|
||||
exit(-1);
|
||||
}
|
||||
fread(&numOfEntries,2,1,FInPtr);
|
||||
offset1 = 0;
|
||||
offset2 = numOfEntries-1;
|
||||
{
|
||||
tailString++; length++;
|
||||
if (*tailString == '\0')
|
||||
|
||||
strcpy(searchName,argv[optind]);
|
||||
i=0;
|
||||
p = searchName;
|
||||
while (*p) {
|
||||
*p = tolower(*p);
|
||||
p++;
|
||||
}
|
||||
{
|
||||
printf("%s",headString);
|
||||
return;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
printf("Searching...\n");
|
||||
else if (length == wordwrap_size)
|
||||
|
||||
while (1) {
|
||||
check = ((offset2-offset1)/2) + offset1;
|
||||
fseek(FInPtr,2+(check*sizeof(nameEntry)),SEEK_SET);
|
||||
fread(&nameStruct,sizeof(nameEntry),1,FInPtr);
|
||||
{
|
||||
while (*tailString != ' ')
|
||||
tailString--;
|
||||
*tailString = '\0';
|
||||
printf("%s\n",headString);
|
||||
headString = tailString+1;
|
||||
length = 0;
|
||||
}
|
||||
|
||||
if((tmp = strdup(nameStruct.name)) == 0)
|
||||
{
|
||||
fprintf(stderr,"couldn't copy name string\n");
|
||||
free (db_path);
|
||||
exit (-1);
|
||||
}
|
||||
p = nameStruct.name;
|
||||
while (*p) {
|
||||
*p = tolower(*p);
|
||||
p++;
|
||||
}
|
||||
cmp = strcmp(nameStruct.name,searchName);
|
||||
|
||||
if (verbose)
|
||||
printf(" checked %s\n",tmp);
|
||||
|
||||
if (cmp > 0) { /* name bigger than searchName */
|
||||
offset2 = check-1;
|
||||
} else if (cmp < 0) { /* name smaller than searchName */
|
||||
offset1 = check+1;
|
||||
} else {
|
||||
if (verbose) {
|
||||
printf("Found entry %s!\n",tmp);
|
||||
#ifdef STACK_CHECK
|
||||
printf("Stack: %d\n",end_stack_check());
|
||||
#endif
|
||||
free (db_path);
|
||||
free (tmp);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
printf("%s%s\n",NAME,tmp);
|
||||
free (db_path);
|
||||
free (tmp);
|
||||
print_entry(FInPtr,nameStruct.offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (offset1 > offset2) {
|
||||
printf("Entry '%s' not found in describe database.\n",searchName);
|
||||
void print_entry(FILE *FInPtr, long int index)
|
||||
|
||||
{
|
||||
char *buffer;
|
||||
|
||||
buffer = (char *) malloc (1024);
|
||||
|
||||
fseek(FInPtr,index,SEEK_SET);
|
||||
|
||||
printf("%s",VERSION);
|
||||
fgets(buffer,80,FInPtr);
|
||||
printf("%s",buffer);
|
||||
|
||||
printf("%s",AUTHOR);
|
||||
fgets(buffer,80,FInPtr);
|
||||
printf("%s",buffer);
|
||||
|
||||
printf("%s",CONTACT);
|
||||
fgets(buffer,80,FInPtr);
|
||||
printf("%s",buffer);
|
||||
|
||||
printf("%s",WHERE);
|
||||
fgets(buffer,80,FInPtr);
|
||||
printf("%s",buffer);
|
||||
|
||||
printf("%s",FTP);
|
||||
fgets(buffer,80,FInPtr);
|
||||
printf("%s",buffer);
|
||||
|
||||
fgets(buffer,1024,FInPtr);
|
||||
myprintf(buffer,75);
|
||||
|
||||
free(buffer);
|
||||
#ifdef STACK_CHECK
|
||||
printf("Stack: %d\n",end_stack_check());
|
||||
printf("Stack: %d\n",end_stack_check());
|
||||
#endif
|
||||
free (db_path);
|
||||
free (tmp);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
|
||||
{
|
||||
FILE *FInPtr;
|
||||
char searchName[34];
|
||||
long int index;
|
||||
int verbose, argind, numOfEntries, cmp, offset1, offset2, check, i;
|
||||
nameEntry nameStruct;
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
begin_stack_check();
|
||||
#endif
|
||||
|
||||
verbose = FALSE;
|
||||
argind = 1;
|
||||
|
||||
if ((argc == 3) && (!strcmp(argv[1],"-v")))
|
||||
|
||||
{
|
||||
verbose = TRUE;
|
||||
argind++;
|
||||
}
|
||||
|
||||
else if (argc != 2)
|
||||
usage(argv[0]);
|
||||
|
||||
FInPtr = fopen(INFILE,"r");
|
||||
fread(&numOfEntries,2,1,FInPtr);
|
||||
offset1 = 0;
|
||||
offset2 = numOfEntries-1;
|
||||
|
||||
strcpy(searchName,argv[argind]);
|
||||
i=0;
|
||||
while(searchName[i] = tolower(searchName[i++]));
|
||||
|
||||
if (verbose)
|
||||
printf("Searching...\n");
|
||||
|
||||
while (1)
|
||||
|
||||
{
|
||||
check = ((offset2-offset1)/2) + offset1;
|
||||
fseek(FInPtr,2+(check*sizeof(nameEntry)),SEEK_SET);
|
||||
fread(&nameStruct,sizeof(nameEntry),1,FInPtr);
|
||||
|
||||
cmp = strcmp(nameStruct.name,searchName);
|
||||
|
||||
if (verbose)
|
||||
printf(" checked %s\n",nameStruct.name);
|
||||
|
||||
if (cmp > 0)
|
||||
offset2 = check-1;
|
||||
|
||||
else if (cmp < 0)
|
||||
offset1 = check+1;
|
||||
|
||||
else
|
||||
|
||||
{
|
||||
if (verbose)
|
||||
|
||||
{
|
||||
printf("Found entry %s!\n",searchName);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
printf("%s%s\n",NAME,searchName);
|
||||
print_entry(FInPtr,nameStruct.offset);
|
||||
}
|
||||
|
||||
if (offset1 > offset2)
|
||||
|
||||
{
|
||||
printf("Entry '%s' not found in describe database.\n",searchName);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
Name: describe
|
||||
Version: 1.0.2
|
||||
Shell: ORCA/Shell, GNO/ME
|
||||
Author: James Brookes
|
||||
Contact: jamesb@ecst.csuchico.edu
|
||||
Where: /usr/local/bin
|
||||
FTP: ftp.cco.caltech.edu
|
||||
|
||||
Print a multi-line description obtained from the compiled 'describe'
|
||||
database; giving utility name, version, intended shell, author, author's
|
||||
contact, where the utility is, as well as where the utility can be FTPd
|
||||
from on the InterNet.
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,58 +0,0 @@
|
|||
.TH DESCU 8 "System Administration" "7 May 1995" "Version 1.0.2"
|
||||
.SH NAME
|
||||
descu \- the describe(1) source updater
|
||||
.SH SYNOPSIS
|
||||
.BR descu " [" -hV ]
|
||||
.I sourcefile
|
||||
.I patchfile1
|
||||
[
|
||||
.IR patchfile2 " ..."
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.BR descu
|
||||
updates the describe source file
|
||||
.I sourcefile
|
||||
by applying the new and updated records from the \fIpatchfile\fRs
|
||||
and prints the result to standard output.
|
||||
.LP
|
||||
.IR Patchfile s
|
||||
are just one or more describe source entries as defined in
|
||||
.BR descc (8).
|
||||
(They have nothing to do with
|
||||
.BR patch (1).)
|
||||
.LP
|
||||
.IR Patchfile s
|
||||
are assumed to contain at most one entry (in all listed
|
||||
.IR patchfile s)
|
||||
for a given program, keyed on the
|
||||
.BR Name:
|
||||
field. If an entry in
|
||||
.IR patchfile
|
||||
is already in
|
||||
.IR sourcefile ,
|
||||
it replaces the original; otherwise the entry is appended. In both
|
||||
cases, the output is sorted lexicographically (ignoring case), based on
|
||||
the
|
||||
.BR Name:
|
||||
field.
|
||||
.LP
|
||||
.BR descu
|
||||
will create the file
|
||||
.B descu.rej
|
||||
in the current directory. This contains all records that were removed
|
||||
from
|
||||
.IR sourcefile .
|
||||
.SH OPTIONS
|
||||
.nf
|
||||
\fB-h\fR Show usage information.
|
||||
|
||||
\fB-V\fR Show version information.
|
||||
.fi
|
||||
.SH AUTHOR
|
||||
Devin Reade <gdr@myrias.ab.ca>
|
||||
.SH "SEE ALSO"
|
||||
.BR apropos (1),
|
||||
.BR describe (1),
|
||||
.BR man (1),
|
||||
.BR whatis (1),
|
||||
.BR descc (8).
|
|
@ -1,519 +0,0 @@
|
|||
/*
|
||||
* descu - describe(1) update utility for maintaining describe source files
|
||||
*
|
||||
* Usage: descu [-hV] sourcefile patchfile1 [patchfile2 ...]
|
||||
*
|
||||
* Options:
|
||||
* -h show usage information and exit.
|
||||
* -V show version information
|
||||
*
|
||||
* Copyright 1995 by Devin Reade for James Brookes' describe(1) utility.
|
||||
* See the included README file and man page for details.
|
||||
*
|
||||
* $Id: descu.c,v 1.2 1996/01/22 02:40:49 gdr Exp $
|
||||
*/
|
||||
|
||||
#pragma optimize -1
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include "desc.h"
|
||||
|
||||
#define _VERSION_ "v1.0.2"
|
||||
#define MAX_BUFFER 65534
|
||||
#define SLOTS_QUANTUM 20
|
||||
#define REJECT_FILE "descu.rej"
|
||||
|
||||
#ifndef __ORCAC__
|
||||
ssize_t read(int, void *, size_t);
|
||||
#endif
|
||||
char *strerror(int);
|
||||
void convert (char *);
|
||||
int my_stricmp (const char *cs, const char *ct);
|
||||
|
||||
char *versionStr = _VERSION_;
|
||||
static char *header=NULL; /* comments before the first describe entry */
|
||||
static char *trailer=NULL; /* comments after the last describe entry */
|
||||
|
||||
short oflag;
|
||||
short Vflag;
|
||||
short errflag;
|
||||
|
||||
descEntry **entryArray1=NULL;
|
||||
descEntry **entryArray2=NULL;
|
||||
int array1SlotsAlloced=0;
|
||||
int array2SlotsAlloced=0;
|
||||
int array1SlotsUsed=0;
|
||||
int array2SlotsUsed=0;
|
||||
|
||||
/*
|
||||
* inhale - read file into buffer
|
||||
*
|
||||
* Pre: <pathname> is the path name of the file to read in
|
||||
*
|
||||
* Post: returns a malloc'd NULL-terminated buffer containing the contents
|
||||
* of file <pathname>. On error, returns NULL and prints a suitable
|
||||
* message.
|
||||
*
|
||||
* On the Apple IIgs, CR's are also converted to LF's
|
||||
*/
|
||||
|
||||
char *inhale (char *pathname) {
|
||||
char *buffer;
|
||||
long bytecount, bytes_read;
|
||||
ssize_t i;
|
||||
int fd;
|
||||
|
||||
/* open the file */
|
||||
if ((fd = open(pathname,O_RDONLY))==-1) {
|
||||
fprintf(stderr,"inhale: open of %s failed: %s\n",
|
||||
pathname,strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* create the buffer */
|
||||
bytecount = lseek(fd,(off_t) 0,SEEK_END);
|
||||
if (bytecount > MAX_BUFFER) {
|
||||
fprintf(stderr,"descu internal error: cannot handle files greater"
|
||||
"than %d bytes\n due to a compiler bug. Sorry.\n",
|
||||
MAX_BUFFER);
|
||||
exit(-1);
|
||||
}
|
||||
lseek(fd,(off_t) 0, SEEK_SET);
|
||||
if ((buffer = malloc(bytecount+1))==NULL) {
|
||||
fprintf(stderr,"inhale: malloc of %ld-byte buffer failed for file %s:%s\n",
|
||||
bytecount+1,pathname,strerror(errno));
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* read file into the buffer */
|
||||
bytes_read=0;
|
||||
while (bytes_read < bytecount) {
|
||||
i = read(fd,&buffer[bytes_read],(size_t)bytecount-bytes_read);
|
||||
if (i==-1) {
|
||||
fprintf(stderr,"inhale: read failed on file %s:%s\n",
|
||||
pathname,strerror(errno));
|
||||
free(buffer);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
bytes_read += i;
|
||||
}
|
||||
|
||||
/* clean up and return buffer */
|
||||
close(fd);
|
||||
buffer[bytecount] = '\0';
|
||||
|
||||
#ifdef __ORCAC__
|
||||
/* convert CR to LF */
|
||||
{
|
||||
char *p;
|
||||
|
||||
for (p=buffer; *p ; p++) {
|
||||
if (*p == 0x0D) *p = 0x0A;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* extract_info -- take a string buffer containing the describe information
|
||||
* and return a malloc'd descEntry structure containing
|
||||
* pointers into the buffer of the various parts. Also
|
||||
* modifies the buffer so that there is a '\0' character
|
||||
* between the parts.
|
||||
*/
|
||||
|
||||
descEntry *extract_info(char *source) {
|
||||
|
||||
char *p;
|
||||
descEntry *entry;
|
||||
|
||||
if ((entry = malloc(sizeof(descEntry))) == NULL) {
|
||||
perror("add_entry: couldn't allocate new entry");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* extract out name */
|
||||
if (((entry->name = strstr(source,NAME_SHORT))==NULL) ||
|
||||
((p = strchr(source,'\n'))==NULL)) {
|
||||
fprintf(stderr,"bad or missing describe field: \"%s\"\n"
|
||||
"describe entry is:\n%s\n",NAME,source);
|
||||
free(entry);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* extract out data */
|
||||
entry->data = p+1;
|
||||
|
||||
/* terminate the name, dropping trailing space */
|
||||
do { --p; } while (isspace(*p));
|
||||
*(p+1) = '\0';
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* add_entry -- add entry to the descTable, even if it already exists.
|
||||
*/
|
||||
|
||||
void add_entry(descEntry *entry, int initial_buffer) {
|
||||
descEntry **e, ***array;
|
||||
int *slotsAlloced, *slotsUsed;
|
||||
|
||||
if (initial_buffer) {
|
||||
array = &entryArray1;
|
||||
slotsAlloced = &array1SlotsAlloced;
|
||||
slotsUsed = &array1SlotsUsed;
|
||||
} else {
|
||||
array = &entryArray2;
|
||||
slotsAlloced = &array2SlotsAlloced;
|
||||
slotsUsed = &array2SlotsUsed;
|
||||
}
|
||||
|
||||
/* grow array if necessary */
|
||||
if (*slotsAlloced == *slotsUsed) {
|
||||
*slotsAlloced += SLOTS_QUANTUM;
|
||||
if (*array) {
|
||||
e = realloc(*array,(*slotsAlloced) * sizeof(descEntry *));
|
||||
} else {
|
||||
e = malloc((*slotsAlloced) * sizeof(descEntry *));
|
||||
}
|
||||
if (e == NULL) {
|
||||
perror("couldn't grow describe array");
|
||||
exit(1);
|
||||
}
|
||||
*array = e;
|
||||
}
|
||||
|
||||
/* add in the entry */
|
||||
(*array)[*slotsUsed] = entry;
|
||||
(*slotsUsed)++;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* insert - insert all entries contained in buffer into the descTable.
|
||||
* If initial_buffer is non-zero, then use any comments preceeding
|
||||
* the first entry as the output file header, and any comments
|
||||
* following the last entry as the output file trailer. If
|
||||
* initial_buffer is zero, then the respective comment blocks are
|
||||
* ignored, effectively deleting them from the output.
|
||||
*/
|
||||
|
||||
void insert(char *buffer, int initial_buffer) {
|
||||
char *p, *q;
|
||||
descEntry *entry;
|
||||
|
||||
/* pull out the header (if nec) and init p */
|
||||
if (initial_buffer) header = buffer;
|
||||
p = strstr(buffer,NAME_SHORT);
|
||||
if(!p) return; /* buffer doesn't have any describe entries! */
|
||||
*(p-1)='\0';
|
||||
|
||||
/* add all but the last entry */
|
||||
while ((q=strstr(p+1,NAME_SHORT))!=NULL) {
|
||||
*(q-1)='\0';
|
||||
entry = extract_info(p);
|
||||
if (entry) add_entry(entry, initial_buffer);
|
||||
p=q;
|
||||
}
|
||||
|
||||
/* extract out the trailer and add the last entry */
|
||||
if ((q = strstr(p,"\n#"))==NULL) {
|
||||
if (initial_buffer) trailer="";
|
||||
} else {
|
||||
if (initial_buffer) trailer=q+1;
|
||||
*q = '\0';
|
||||
}
|
||||
|
||||
entry = extract_info(p);
|
||||
if (entry) add_entry(entry,initial_buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sortArray - do a heapsort on <array> consisting of <slotsUsed> elements.
|
||||
* The sort is based on the field array[i]->name, sorted
|
||||
* lexicographically ignoring case.
|
||||
*/
|
||||
|
||||
void sortArray(descEntry **array, int slotsUsed) {
|
||||
|
||||
int l, j, ir, i;
|
||||
descEntry *rra;
|
||||
|
||||
if (slotsUsed==1) return; /* no need to sort one element */
|
||||
--array; /* fudge since the algorithm was designed */
|
||||
/* for a unit-indexing */
|
||||
|
||||
l = (slotsUsed>>1) + 1;
|
||||
ir = slotsUsed;
|
||||
|
||||
/*
|
||||
* The index l will be decremented from its initial value down to 0 during
|
||||
* the heap creation phase. Once it reaches 0, the index ir will be
|
||||
* decremented from its initial value down to 0 during the heap selection
|
||||
* phase.
|
||||
*/
|
||||
for (;;) {
|
||||
if (l > 1) /* still in creation phase */
|
||||
rra = array[--l];
|
||||
else { /* in selection phase */
|
||||
rra= array[ir]; /* clear a space at the end of array */
|
||||
array[ir] = array[1]; /* retire the top of the heap into it */
|
||||
if (--ir == 1) { /* done with the last promotion */
|
||||
array[1] = rra;
|
||||
return;
|
||||
}
|
||||
}
|
||||
i = l; /* set up to sift down element rra to its proper place */
|
||||
j = l << 1;
|
||||
while (j<=ir) {
|
||||
if (j<ir && (my_stricmp(array[j]->name,array[j+1]->name)<0)) ++j;
|
||||
if (my_stricmp(rra->name,array[j]->name)<0) { /* demote rra */
|
||||
array[i] = array[j];
|
||||
i = j;
|
||||
j += i;
|
||||
} else j = ir + 1; /* this is rra's level; set j to terminate */
|
||||
} /* the sift-down */
|
||||
array[i] = rra;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* int my_stricmp (const char *cs, const char *ct);
|
||||
*
|
||||
* Compare the two strings cs and ct case-insensitive. Return
|
||||
* <0 if cs<ct, 0 if cs == ct, >0 if cs>ct.
|
||||
*
|
||||
*/
|
||||
|
||||
int my_stricmp (const char *cs, const char *ct)
|
||||
{
|
||||
char a, b;
|
||||
|
||||
while ((a = tolower(*cs)) && (b = tolower(*ct))) {
|
||||
if (a < b) return -1;
|
||||
if (a > b) return 1;
|
||||
cs++; ct++;
|
||||
}
|
||||
if (*cs == *ct) return 0;
|
||||
else if (*cs) return -1;
|
||||
else return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* ns_strcmp (no-space string compare) -- compare two strings, ignoring
|
||||
* a leading NAME_SHORT and whitespace, and ignoring trailing
|
||||
* whitespace.
|
||||
*
|
||||
* Returns zero if strings are equal, -1 if a<b, 1 if a>b.
|
||||
* The following are therefore equal:
|
||||
* "Name: test "
|
||||
* "Name: test "
|
||||
* The following are inequal:
|
||||
* "Name: one"
|
||||
* "Name: One"
|
||||
*/
|
||||
|
||||
int ns_strcmp (char *a, char *b) {
|
||||
char *p;
|
||||
size_t len;
|
||||
|
||||
/* strip NAME_SHORT and leading space */
|
||||
len = strlen(NAME_SHORT);
|
||||
a+=len;
|
||||
b+=len;
|
||||
while (isspace(*a)) a++;
|
||||
while (isspace(*b)) b++;
|
||||
|
||||
/* strip trailing space */
|
||||
p = a + strlen(a);
|
||||
do {
|
||||
--p;
|
||||
} while (isspace(*p));
|
||||
*(p+1) = '\0';
|
||||
|
||||
p = b + strlen(b);
|
||||
do {
|
||||
--p;
|
||||
} while (isspace(*p));
|
||||
*(p+1) = '\0';
|
||||
|
||||
/* do the string comparison */
|
||||
while (*a && *b) {
|
||||
if (*a < *b) return -1;
|
||||
if (*a > *b) return 1;
|
||||
a++; b++;
|
||||
}
|
||||
if (*a == *b) return 0;
|
||||
else if (*a) return -1;
|
||||
else return 1;
|
||||
}
|
||||
|
||||
|
||||
void version (char *progName) {
|
||||
fprintf(stderr,
|
||||
"%s version %s Copyright 1995 Devin Reade\n"
|
||||
"Freeware. See the manual page for copying restrictions.\n",
|
||||
progName,versionStr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Usage -- print usage info and exit
|
||||
*/
|
||||
|
||||
|
||||
void usage(char *progName) {
|
||||
|
||||
if (!Vflag || errflag) {
|
||||
fprintf(stderr,
|
||||
"%s -- describe(1) source update utility\n"
|
||||
"Usage: %s [-hV] sourcefile patchfile1 [patchfile2 ...]\n"
|
||||
"\t-h\tshow usage information\n"
|
||||
"\t-V\tshow version information\n\n",
|
||||
progName,progName);
|
||||
}
|
||||
version(progName);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* need I say it?
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
char *buffer;
|
||||
int i, j;
|
||||
FILE *outfp, *rejfp;
|
||||
int c;
|
||||
char *outputfile=NULL;
|
||||
int compare;
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
begin_stack_check();
|
||||
#endif
|
||||
|
||||
/* initialize */
|
||||
errflag=0;
|
||||
oflag=0;
|
||||
|
||||
/* parse command line */
|
||||
while ((c=getopt(argc,argv,"ho:V"))!=EOF) {
|
||||
switch (c) {
|
||||
case 'o':
|
||||
outputfile = optarg;
|
||||
oflag++;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
Vflag++;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
default:
|
||||
errflag++;
|
||||
}
|
||||
}
|
||||
|
||||
/* error and exit if necessary */
|
||||
if (errflag || (argc-optind<2)) usage(basename(argv[0]));
|
||||
|
||||
/* show version info */
|
||||
if (Vflag) version(basename(argv[0]));
|
||||
|
||||
/* open output (if nec) and reject file */
|
||||
if (oflag) {
|
||||
if ((outfp = fopen(outputfile,"w+"))==NULL) {
|
||||
perror("main: couldn't open output file");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
outfp = stdout;
|
||||
}
|
||||
if ((rejfp = fopen(REJECT_FILE,"w+"))==NULL) {
|
||||
perror("main: couldn't open rejects file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* read in original describe source file */
|
||||
buffer = inhale(argv[optind]);
|
||||
insert(buffer,1);
|
||||
|
||||
/* insert describe patch files */
|
||||
for (optind++; optind<argc; optind++) {
|
||||
buffer = inhale(argv[optind]);
|
||||
insert(buffer,0);
|
||||
}
|
||||
|
||||
/* sort the two arrays */
|
||||
sortArray(entryArray1,array1SlotsUsed);
|
||||
sortArray(entryArray2,array2SlotsUsed);
|
||||
|
||||
/*
|
||||
* merge the two arrays, printing out the result
|
||||
*/
|
||||
i=0; j=0;
|
||||
|
||||
/* print the header */
|
||||
fprintf(outfp,"%s\n",header);
|
||||
|
||||
/* first stage; merge while we have two arrays */
|
||||
while ((i<array1SlotsUsed) && (j<array2SlotsUsed)) {
|
||||
compare = ns_strcmp (entryArray1[i]->name, entryArray2[j]->name);
|
||||
if (compare < 0) {
|
||||
fprintf(outfp,"%s\n%s\n",entryArray1[i]->name,entryArray1[i]->data);
|
||||
i++;
|
||||
} else if (compare > 0) {
|
||||
fprintf(outfp,"%s\n%s\n",entryArray2[j]->name,entryArray2[j]->data);
|
||||
j++;
|
||||
} else {
|
||||
fprintf(rejfp,"%s\n%s\n",entryArray1[i]->name,entryArray1[i]->data);
|
||||
fprintf(outfp,"%s\n%s\n",entryArray2[j]->name,entryArray2[j]->data);
|
||||
i++; j++;
|
||||
}
|
||||
}
|
||||
|
||||
/* second stage; print out remaining list */
|
||||
while (i<array1SlotsUsed) {
|
||||
fprintf(outfp,"%s\n%s\n",entryArray1[i]->name,entryArray1[i]->data);
|
||||
i++;
|
||||
}
|
||||
while (j<array2SlotsUsed) {
|
||||
fprintf(outfp,"%s\n%s\n",entryArray2[j]->name,entryArray2[j]->data);
|
||||
j++;
|
||||
}
|
||||
|
||||
/* print the trailer */
|
||||
fprintf(outfp,"%s",trailer);
|
||||
|
||||
/* close the files and exit */
|
||||
fclose(rejfp);
|
||||
if (oflag) fclose(outfp);
|
||||
|
||||
#ifdef STACK_CHECK
|
||||
fprintf(stderr,"stack usage: %d bytes\n",end_stack_check());
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
Name: descu
|
||||
Version: 1.0.2
|
||||
Shell: ORCA/Shell, GNO/ME
|
||||
Author: Devin Reade
|
||||
Contact: gdr@myrias.ab.ca
|
||||
Where: /usr/sbin
|
||||
FTP: ftp.cco.caltech.edu
|
||||
|
||||
Update a 'describe' source file.
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
#
|
||||
# This is the makefile for the describe(1) package. It is for use
|
||||
# with dmake(1).
|
||||
#
|
||||
|
||||
# Use -DSTACK_CHECK in CFLAGS to show stack usage.
|
||||
|
||||
CFLAGS += -O -w -v -I/usr/include -s768
|
||||
LDFLAGS += -v
|
||||
LDLIBS += -l/usr/lib/lgetopt -l/usr/lib/stack
|
||||
BINDIR = /usr/local/bin
|
||||
SBINDIR = /usr/sbin
|
||||
MANDIR = /usr/man
|
||||
INSTALL = /bin/cp
|
||||
|
||||
build: describe descc descu
|
||||
|
||||
descc: descc.o basename.o descc.r
|
||||
@purge
|
||||
$(CC) $(LDFLAGS) $< -o $@ $(LDLIBS)
|
||||
copyfork descc.r descc
|
||||
|
||||
describe: describe.o basename.o describe.r
|
||||
@purge
|
||||
$(CC) $(LDFLAGS) $< -o $@ $(LDLIBS)
|
||||
copyfork describe.r describe
|
||||
|
||||
descu: descu.o basename.o descu.r
|
||||
@purge
|
||||
$(CC) $(LDFLAGS) $< -o $@ $(LDLIBS)
|
||||
copyfork descu.r descu
|
||||
|
||||
basename.o: basename.c
|
||||
$(CC) -c $(CFLAGS) basename.c
|
||||
|
||||
descc.o: descc.c desc.h
|
||||
$(CC) -c $(CFLAGS) descc.c
|
||||
|
||||
describe.o: describe.c desc.h
|
||||
$(CC) -c $(CFLAGS) describe.c
|
||||
|
||||
descu.o: descu.c desc.h
|
||||
$(CC) -c $(CFLAGS) descu.c
|
||||
|
||||
install:
|
||||
$(RM) -f /usr/local/bin/descc
|
||||
$(INSTALL) describe $(BINDIR)
|
||||
$(INSTALL) descc $(SBINDIR)
|
||||
$(INSTALL) descu $(SBINDIR)
|
||||
$(INSTALL) describe.1 $(MANDIR)/man1
|
||||
$(INSTALL) descc.8 $(MANDIR)/man8
|
||||
$(INSTALL) descu.8 $(MANDIR)/man8
|
31
usr.orca.bin/describe/readme
Normal file
31
usr.orca.bin/describe/readme
Normal file
|
@ -0,0 +1,31 @@
|
|||
About Describe
|
||||
~~~~~~~~~~~~~~
|
||||
First off: make sure the directory /usr/local/lib exists!!!
|
||||
|
||||
This is yet another project I've been sitting on for a while, but have
|
||||
finally decided to release. The basic idea of the 'describe' package
|
||||
(the descc "compiler" and describe itself) is to provide a quick, easy
|
||||
way of accessing information related to the utilities which so many
|
||||
different people are releasing these days. The reason it sat around on
|
||||
my harddrive so long is I was having qualms about its designated role in
|
||||
life. I wasn't sure exactly what I wanted it to do. Well, I've decided
|
||||
to KISS for now: descc simply compiles the utility list, which I maintain,
|
||||
into a (very) simple "database" located in /usr/local/lib/. The companion
|
||||
utility 'describe' is used to fetch information about a particular utility
|
||||
from this "database".
|
||||
|
||||
descc is fairly limited, as is the "database" format itself. Part of the
|
||||
KISS (or it wouldn't be out now) design philosophy ;). Usage is simple:
|
||||
when you get a new listing (I'll provide monthly updates), simply "descc
|
||||
<filename>" where <filename> is the name of the newly released update.
|
||||
descc will simply write over the old database and replace it with the
|
||||
new (note: no appendages allowed).
|
||||
|
||||
As always, coments are appreciated. And, moreso than on other projects,
|
||||
I'd appreciate some comments about the direction I'm going in, suggestions
|
||||
as to where to take this, etc. I have a feeling that some fields in the
|
||||
format (eg, FTP:) are rather useless, and I'd like to know what you guys
|
||||
out there think.
|
||||
|
||||
James Brookes
|
||||
jamesb@ecst.csuchico.edu
|
|
@ -1,63 +0,0 @@
|
|||
#
|
||||
# Makefile for udl
|
||||
# Copyright (c) 1993-1996 Soenke Behrens
|
||||
#
|
||||
# This makefile should be used with dmake.
|
||||
#
|
||||
# $Id: Makefile.gs,v 1.8 1996/01/22 01:01:30 gdr Exp $
|
||||
#
|
||||
|
||||
# Where do we put the binaries and man page?
|
||||
|
||||
BINDIR = /usr/local/bin
|
||||
MANDIR = /usr/local/man
|
||||
|
||||
# OS-dependant macros. See the README for an explanation of these.
|
||||
|
||||
DEFINES = -DGNO -D_POSIX_C_SOURCE -D_POSIX_SOURCE -DHAS_ATEXIT \
|
||||
-DOVERFLOW_CHECK
|
||||
|
||||
# Use optimization and a 2k stack.
|
||||
|
||||
CFLAGS = $(DEFINES) -O -w -s2048
|
||||
LDFLAGS = -s2048
|
||||
|
||||
# Depending on how you have your libraries set up, you may not need
|
||||
# this next line. In that case, just comment it out.
|
||||
|
||||
LDLIBS = -l/usr/lib/gnulib
|
||||
|
||||
#
|
||||
# You should not have to modify anything beyond this point
|
||||
#
|
||||
|
||||
OBJS = udl.o udluse.o common.o globals.o
|
||||
|
||||
udl: $(OBJS) udl.r help/udl
|
||||
$(CC) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@
|
||||
copyfork udl.r $@ -r
|
||||
|
||||
udl.o: udlgs.c common.h
|
||||
$(CC) -c $(CFLAGS) -o udl.o udlgs.c
|
||||
|
||||
install:
|
||||
cp -f udl $(BINDIR)
|
||||
cp -f udl.1 $(MANDIR)
|
||||
|
||||
help:
|
||||
mkdir $@
|
||||
|
||||
help/udl: udl.1 help
|
||||
nroff -man udl.1 > $@
|
||||
|
||||
clean:
|
||||
-$(RM) *.o *.root udl.r
|
||||
|
||||
clobber: clean
|
||||
-$(RM) -rf udl help
|
||||
|
||||
dist:
|
||||
@echo "Sorry, automatic packing not supported yet"
|
||||
|
||||
common.o:: common.h
|
||||
globals.o:: common.h
|
|
@ -1,94 +0,0 @@
|
|||
#
|
||||
# Makefile for udl
|
||||
# (c) 1993-1996 Soenke Behrens
|
||||
#
|
||||
# $Id: Makefile.unx,v 1.7 1996/01/22 01:01:31 gdr Exp $
|
||||
#
|
||||
|
||||
# $(CC) _must_ be an ANSI compiler.
|
||||
CC = cc
|
||||
BINDIR = /usr/local/bin
|
||||
MANDIR = /usr/local/man/man1
|
||||
INSTALL = /usr/bin/install
|
||||
|
||||
# These are arguments to $(INSTALL)
|
||||
MODE644 = -m 644
|
||||
MODE755 = -m 755
|
||||
OWNER_GROUP = -o bin -g sys
|
||||
|
||||
# You should not have to modify anything beyond this point
|
||||
##########################################################
|
||||
|
||||
#
|
||||
# OS-dependant macros. See the README for an explanation of these.
|
||||
#
|
||||
|
||||
DEFINES_AIX = -DBROKEN_REALLOC -D_POSIX_C_SOURCE -D_POSIX_SOURCE
|
||||
|
||||
DEFINES_Linux = -DREADDIR_RETURNS_DOT -D_POSIX_C_SOURCE -D_POSIX_SOURCE \
|
||||
-DHAS_ATEXIT
|
||||
|
||||
DEFINES_Solaris = -DREADDIR_RETURNS_DOT -D_POSIX_C_SOURCE -D_POSIX_SOURCE \
|
||||
-DBROKEN_DIRENT_STRUCT
|
||||
LDLIBS_Solaris = -lucb
|
||||
|
||||
DEFINES_SunOS = -DREADDIR_RETURNS_DOT -D_POSIX_C_SOURCE -D_POSIX_SOURCE \
|
||||
-DBROKEN_REALLOC
|
||||
|
||||
CFLAGS = $(DEFINES_$(OS)) -O
|
||||
LDFLAGS = $(LDFLAGS_$(OS)) -s
|
||||
LDLIBS = $(LDLIBS_$(OS))
|
||||
|
||||
OBJS = udl.o udluse.o common.o globals.o
|
||||
|
||||
build:
|
||||
@os_string=`uname -sr | tr ' ' '_'`; \
|
||||
case $$os_string in \
|
||||
SunOS_4*) os=SunOS;; \
|
||||
SunOS_5*) os=Solaris;; \
|
||||
AIX*) os=AIX;; \
|
||||
Linux*) os=Linux;; \
|
||||
*) echo "don't know about OS $$os_string"; \
|
||||
exit -1;; \
|
||||
esac; \
|
||||
$(MAKE) udl -f Makefile.unx OS=$$os
|
||||
|
||||
udl: $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o udl $(OBJS) $(LDLIBS)
|
||||
|
||||
udl.o: udlunix.c common.h
|
||||
$(CC) -c $(CFLAGS) -o udl.o udlunix.c
|
||||
|
||||
newudl.1: udl.1
|
||||
@echo "creating newudl.1"; \
|
||||
echo '/^.TH/ c\' > sed.script; \
|
||||
echo '.TH UDL 1 "15 January 1996" "Version 1.15"\
|
||||
"Commands and Applications"' >>sed.script; \
|
||||
sed -f sed.script <udl.1 >newudl.1; \
|
||||
rm -f sed.script
|
||||
|
||||
install: newudl.1 udl
|
||||
$(INSTALL) $(MODE755) $(OWNER_GROUP) udl $(BINDIR)
|
||||
$(INSTALL) $(MODE644) $(OWNER_GROUP) newudl.1 $(MANDIR)/udl.1
|
||||
rm -f newudl.1
|
||||
|
||||
clean:
|
||||
-rm -f *.o *~ core
|
||||
|
||||
clobber: clean
|
||||
-rm -rf udl newudl.1 help
|
||||
|
||||
dist: clobber
|
||||
@echo "creating archive"; \
|
||||
cwd=`pwd`; \
|
||||
parent=`dirname $$cwd`; \
|
||||
dir=`basename $$cwd`; \
|
||||
cd $$parent; \
|
||||
archive=$$dir.tar.Z; \
|
||||
if [ -f $$archive ]; then \
|
||||
echo "please move $$parent/$$archive out of the way, first"; \
|
||||
exit -1; \
|
||||
fi; \
|
||||
tar -cf - $$dir | compress > $$archive
|
||||
|
||||
udluse.o common.o globals.o:: common.h
|
|
@ -1,230 +0,0 @@
|
|||
=============================================================================
|
||||
udl - Convert EOL formats freely between MS-DOS (CR/LF), Unix/Amiga (LF),
|
||||
and Apple (CR).
|
||||
|
||||
(c) 1993-1996 Soenke Behrens, Devin Reade
|
||||
|
||||
Version 1.15: $Id: README,v 1.8 1996/01/22 01:01:32 gdr Exp $
|
||||
=============================================================================
|
||||
|
||||
Udl converts text files between CR, LF and CR/LF (Apple, Unix and MS-DOS).
|
||||
It is a very fast utility that ensures that the integrity of the file
|
||||
cannot be compromised during the translation. It is also much easier
|
||||
to use than tr(1).
|
||||
|
||||
=========
|
||||
Compiling:
|
||||
=========
|
||||
|
||||
There are two makefiles included:
|
||||
Makefile.gs - for use on the Apple IIgs running GNO
|
||||
Makefile.unx - for use with Unix systems.
|
||||
|
||||
Although udl on the IIgs can be run from either GNO or ORCA shells,
|
||||
it cannot be built with the standard ORCA installation due to a lack
|
||||
of additional libraries.
|
||||
|
||||
The IIgs distribution should contain a binary of udl, including a
|
||||
resource fork. Therefore, you should be able to skip straight to the
|
||||
section on installation. For those who must know, however, building the
|
||||
binaries under GNO should just be a matter of typing 'dmake -f Makefile.gs'.
|
||||
|
||||
If you are compiling on Unix operating systems that have been previously
|
||||
tested, you should be able to just type 'make -f Makefile.unx'. This
|
||||
will select the appropriate DEFINES for your system. For an explanation
|
||||
the various DEFINES, see the section below on "DEFINES Definitions".
|
||||
|
||||
Note that compilation of udl _requires_ an ANSI C compiler.
|
||||
|
||||
If you are compiling to a new system, add in another set of defines
|
||||
and let us know about them.
|
||||
|
||||
Note that udl.c assumes that getopt() is declared in <unistd.h> and that
|
||||
the function strdup() exists in <string.h>. You might have to change
|
||||
these includes if that's not the case. Ensure you use cpp conditional
|
||||
compilations to match your platform (and to avoid breaking the code for
|
||||
other platforms).
|
||||
|
||||
============
|
||||
Installation
|
||||
============
|
||||
|
||||
Apple IIgs with GNO
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
Type 'dmake install -f Makefile.gs'. By default this copies the binary
|
||||
into "/usr/local/bin" and the man page into "/usr/local/man/man1". (You
|
||||
_are_ using version 3.x of 'man', are you not? *blatent plug*) If you
|
||||
don't like these locations, either modify the BINDIR and MANDIR
|
||||
macros in the makefile or install the files by hand.
|
||||
|
||||
If you have describe(1) installed, you can update the udl(1) entry
|
||||
with the file "describe.udl". See the descu(8) and descc(8) man pages
|
||||
for details.
|
||||
|
||||
Apple IIgs with Orca/Shell
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Copy the following files to their respective destinations:
|
||||
|
||||
udl to 17
|
||||
help/udl to 17/help
|
||||
|
||||
Unix systems
|
||||
^^^^^^^^^^^^
|
||||
Type 'make -f Makefile.unx install'. By default the binary will
|
||||
go into /usr/local/bin and the man page into /usr/local/man/man1.
|
||||
This assumes root access. If this does not match your plans and/or
|
||||
access permissions, either copy the files by hand or change the
|
||||
BINDIR, MANDIR, and OWNER_GROUP macros in the makefile.
|
||||
|
||||
===================
|
||||
DEFINES Definitions
|
||||
===================
|
||||
|
||||
If you have problems compiling or are porting udl to a new operating
|
||||
system, define the following macros in the makefile as necessary.
|
||||
They should be used as the value of $(DEFINES_$(OS)) where $(OS) is
|
||||
your operating system as returned by `uname -sr | tr ' ' '_'`.
|
||||
|
||||
HAS_ATEXIT if your system has atexit()
|
||||
|
||||
_POSIX_C_SOURCE and _POSIX_SOURCE if your compiler is Posix compliant
|
||||
|
||||
READDIR_RETURNS_DOT if your direct readdir() function will return
|
||||
entries for "." and "..". SunOS 4.x and 5.x (Solaris) are known to
|
||||
do this.
|
||||
|
||||
BROKEN_REALLOC if your realloc() doesn't behave like malloc() when
|
||||
passed a NULL pointer as the first argument.
|
||||
|
||||
BROKEN_DIRENT_STRUCT if you find that the first two letters of
|
||||
filenames obtained during directory recursion (as shown when the
|
||||
"-v" flag is used) seem to be missing. Some installations of
|
||||
Solaris are known to do this.
|
||||
|
||||
GNO if you are compiling on the IIgs. This will allow for both
|
||||
':' and '/' as pathname separators.
|
||||
|
||||
OVERFLOW_CHECK Udl uses one recursive subroutine. Define this if
|
||||
you want to check for stack overflows for this routine (independent
|
||||
of any compiler flags). Strongly recommended.
|
||||
|
||||
CHECK_STACK if you want stack usage to be displayed (IIgs only).
|
||||
You will also have to specify -l/usr/lib/stack in LDFLAGS.
|
||||
|
||||
The following are the DEFINES values for tested operating systems:
|
||||
|
||||
APPLE IIGS: (use "dmake -f Makefile.gs")
|
||||
^^^^^^^^^^
|
||||
|
||||
ORCA/Shell and GNO/ME: (tested with occ)
|
||||
-DGNO -D_POSIX_C_SOURCE -D_POSIX_SOURCE -DHAS_ATEXIT
|
||||
-DOVERFLOW_CHECK
|
||||
|
||||
TESTED UNIX OS's: (use "make -f Makefile.unx")
|
||||
^^^^^^^^^^^^^^^^
|
||||
SunOS 4.x: (tested with gcc)
|
||||
-DREADDIR_RETURNS_DOT -DBROKEN_REALLOC
|
||||
-D_POSIX_C_SOURCE -D_POSIX_SOURCE
|
||||
|
||||
SunOS 5.x (Solaris): (tested with SUNWspro cc)
|
||||
-DREADDIR_RETURNS_DOT -DBROKEN_DIRENT_STRUCT
|
||||
-D_POSIX_C_SOURCE -D_POSIX_SOURCE
|
||||
|
||||
AIX 3.2: (tested with xlc)
|
||||
-DBROKEN_REALLOC -D_POSIX_C_SOURCE -D_POSIX_SOURCE
|
||||
|
||||
Linux 1.2.3: (tested with gcc)
|
||||
-DREADDIR_RETURNS_DOT -D_POSIX_C_SOURCE -D_POSIX_SOURCE
|
||||
-DHAS_ATEXIT
|
||||
|
||||
================
|
||||
Revision History:
|
||||
================
|
||||
|
||||
v1.01
|
||||
Tabs are left alone now. Also recognizes CR/LF (MeSsy-DOS).
|
||||
|
||||
v1.02
|
||||
Does no longer read in the complete file, instead creates a temp
|
||||
file in prefix 3/.
|
||||
|
||||
v1.03
|
||||
Fixed a bug, allocated not enough mem for strncpy.
|
||||
|
||||
v1.1
|
||||
Changed to use static GS/OS strings again. Made faster by factor
|
||||
5.8.
|
||||
|
||||
v1.11
|
||||
Cleaned the code up a bit, wrote a Makefile, all output by udl is
|
||||
prefixed with the name it was invoked with.
|
||||
|
||||
v1.12
|
||||
Sped up Apple <-> Unix conversion further (factor 1.5).
|
||||
|
||||
v1.12 (Unix)
|
||||
(December 1993)
|
||||
Modified source to produce a Unix version
|
||||
|
||||
v1.13
|
||||
(Updated by Devin Reade, November 1994)
|
||||
Added ability to recurse through directories (-R flag).
|
||||
Changed behavior to ignore binary files rather than exiting.
|
||||
Merged Unix and Apple IIgs versions.
|
||||
No message is printed out when a binary file (or, in the IIgs
|
||||
implementation, a non-TXT or non-SRC file) is encountered
|
||||
unless the -v option is specified.
|
||||
|
||||
v1.14
|
||||
(Soenke Behrens, Devin Reade, February 1995)
|
||||
udl creates a temporary file in the directory of the
|
||||
source file, not in /tmp. This reduces the likelihood of
|
||||
data loss in the event of a system crash or powerdown.
|
||||
udl now accepts something like "udl -R directory/" without
|
||||
affixing an extra '/' to "directory/".
|
||||
Fixed bug (via the BROKEN_DIRENT_STRUCT macro) that was causing
|
||||
filename-munging on Solaris. It seems that the sys/stat.h header
|
||||
file doesn't agree with the stat implementation.
|
||||
Modified Makefile.gs to properly write the new executable over
|
||||
the old resource fork for udl. The resource fork originates with
|
||||
the file udl.r.
|
||||
Added suggested defines to the README for various Unix platforms.
|
||||
Man page changes, including grammar and the deletion of a bug that
|
||||
no longer exists.
|
||||
Fixed bug where invoking 'udl -u directory' would attempt to
|
||||
deref a NULL pointer, causing either memory tromping (IIgs) or
|
||||
a core dump (Unix).
|
||||
Tested under SunOS 4.x, SunOS 5.x (Solaris), and AIX.
|
||||
|
||||
v1.15
|
||||
(Devin Reade, January 1996)
|
||||
Changed Makefile.unx to select what should be the proper
|
||||
defines automatically, based on the result of `uname -sr`.
|
||||
Added Linux defines.
|
||||
Changed references and definition of "mktemp" to "Mktemp". There
|
||||
is a discrepancy between the internal implementation and
|
||||
other common Unix versions.
|
||||
Added a section to this README on installation, and moved the
|
||||
description of the DEFINES from the makefiles to here.
|
||||
On the IIgs version, the resource fork is now created from a
|
||||
resource source file that is compiled, rather than using
|
||||
an interactive tool to create the resource fork.
|
||||
Changed source filenames to use the 8.3 format in anticipation of
|
||||
MS-DOS support. This does not affect the file names upon which
|
||||
udl operates.
|
||||
|
||||
=======
|
||||
Authors
|
||||
=======
|
||||
|
||||
Original code by Soenke Behrens <sbehrens@contech.demon.co.uk>
|
||||
with modifications and version-merging by Devin Reade <gdr@myrias.com>
|
||||
|
||||
==========
|
||||
Legalities:
|
||||
==========
|
||||
|
||||
This program contains material from the Orca/C Run-Time Libraries,
|
||||
copyright 1987-1996 by Byte Works, Inc. Used with permission.
|
||||
|
||||
=============================================================================
|
|
@ -1,928 +0,0 @@
|
|||
/*
|
||||
* udl - Convert EOL formats freely between MS-DOS (CR/LF), Unix/Amiga (LF),
|
||||
* and Apple (CR).
|
||||
*
|
||||
* Routines common to both the Unix and Apple IIgs versions.
|
||||
*
|
||||
* $Id: common.c,v 1.8 1996/01/22 01:01:32 gdr Exp $
|
||||
*
|
||||
* Copyright (c) 1993-1995 Soenke Behrens, Devin Reade
|
||||
*/
|
||||
|
||||
#ifdef GNO
|
||||
#pragma noroot
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
extern char *strdup(const char *);
|
||||
|
||||
/*
|
||||
* convert_gs() ... convert files to use CR as EOL
|
||||
*
|
||||
* Inputs:
|
||||
* FILE *infile File to read from
|
||||
* FILE *outfile File to write to
|
||||
*
|
||||
* Outputs:
|
||||
* None
|
||||
*/
|
||||
|
||||
void convert_gs(FILE *infile, FILE *outfile) {
|
||||
unsigned char a;
|
||||
unsigned char *in_bufpos;
|
||||
unsigned char *out_bufpos;
|
||||
unsigned char *in_bufend;
|
||||
unsigned char *out_bufend;
|
||||
size_t file_remain;
|
||||
|
||||
in_bufpos = in_buffer;
|
||||
out_bufpos = out_buffer;
|
||||
|
||||
(void) fseek(infile,0L,SEEK_END);
|
||||
file_remain = ftell(infile);
|
||||
rewind(infile);
|
||||
|
||||
in_bufend = in_buffer + my_fread(infile,BUFFERSIZE);
|
||||
out_bufend = out_buffer + BUFFERSIZE;
|
||||
|
||||
while (file_remain != 0) {
|
||||
a = *in_bufpos;
|
||||
in_bufpos++;
|
||||
|
||||
if (in_bufpos >= in_bufend) {
|
||||
file_remain -= in_bufend - in_buffer;
|
||||
in_bufend = in_buffer + my_fread(infile,BUFFERSIZE);
|
||||
in_bufpos = in_buffer;
|
||||
}
|
||||
/* a = fgetc (infile); */
|
||||
|
||||
if(a == '\n') {
|
||||
*out_bufpos = '\r';
|
||||
out_bufpos++;
|
||||
if (out_bufpos == out_bufend) {
|
||||
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
||||
out_bufpos = out_buffer;
|
||||
}
|
||||
/* fputc('\r',outfile); */
|
||||
} else if(a == '\r') {
|
||||
*out_bufpos = '\r';
|
||||
out_bufpos++;
|
||||
if (out_bufpos == out_bufend) {
|
||||
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
||||
out_bufpos = out_buffer;
|
||||
}
|
||||
/* fputc('\r',outfile); */
|
||||
|
||||
if (*in_bufpos == '\n' && file_remain != 0) {
|
||||
in_bufpos++;
|
||||
|
||||
if (in_bufpos >= in_bufend) {
|
||||
file_remain -= in_bufend - in_buffer;
|
||||
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
||||
in_bufpos = in_buffer;
|
||||
}
|
||||
}
|
||||
/* if ((a = fgetc (infile)) != '\n')
|
||||
ungetc (a,infile); */
|
||||
} else {
|
||||
*out_bufpos = a;
|
||||
out_bufpos++;
|
||||
if (out_bufpos == out_bufend) {
|
||||
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
||||
out_bufpos = out_buffer;
|
||||
}
|
||||
/* fputc(a,outfile); */
|
||||
}
|
||||
}
|
||||
/* Check for remainder in output buffer */
|
||||
if (out_bufpos != out_buffer)
|
||||
my_fwrite(out_buffer,outfile,out_bufpos - out_buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* convert_messy() ... convert files to use CR/LF as EOL
|
||||
*
|
||||
* Inputs:
|
||||
* FILE *infile File to read from
|
||||
* FILE *outfile File to write to
|
||||
*
|
||||
* Outputs:
|
||||
* None
|
||||
*/
|
||||
|
||||
void convert_messy (FILE *infile, FILE *outfile) {
|
||||
unsigned char a;
|
||||
unsigned char *in_bufpos;
|
||||
unsigned char *out_bufpos;
|
||||
unsigned char *in_bufend;
|
||||
unsigned char *out_bufend;
|
||||
size_t file_remain;
|
||||
|
||||
in_bufpos = in_buffer;
|
||||
out_bufpos = out_buffer;
|
||||
|
||||
(void) fseek(infile,0L,SEEK_END);
|
||||
file_remain = ftell(infile);
|
||||
rewind(infile);
|
||||
|
||||
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
||||
out_bufend = out_buffer + BUFFERSIZE;
|
||||
|
||||
while (file_remain != 0) {
|
||||
a = *in_bufpos;
|
||||
in_bufpos++;
|
||||
|
||||
if (in_bufpos >= in_bufend) {
|
||||
file_remain -= in_bufend - in_buffer;
|
||||
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
||||
in_bufpos = in_buffer;
|
||||
}
|
||||
/* a = fgetc (infile); */
|
||||
|
||||
if(a == '\n') {
|
||||
*out_bufpos = '\r';
|
||||
out_bufpos++;
|
||||
if (out_bufpos == out_bufend) {
|
||||
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
||||
out_bufpos = out_buffer;
|
||||
}
|
||||
/* fputc('\r',outfile); */
|
||||
|
||||
*out_bufpos = '\n';
|
||||
out_bufpos++;
|
||||
if (out_bufpos == out_bufend) {
|
||||
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
||||
out_bufpos = out_buffer;
|
||||
}
|
||||
/* fputc('\n',outfile); */
|
||||
} else if(a == '\r') {
|
||||
*out_bufpos = '\r';
|
||||
out_bufpos++;
|
||||
if (out_bufpos == out_bufend) {
|
||||
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
||||
out_bufpos = out_buffer;
|
||||
}
|
||||
/* fputc('\r',outfile); */
|
||||
|
||||
*out_bufpos = '\n';
|
||||
out_bufpos++;
|
||||
if (out_bufpos == out_bufend) {
|
||||
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
||||
out_bufpos = out_buffer;
|
||||
}
|
||||
/* fputc('\n',outfile); */
|
||||
|
||||
if (*in_bufpos == '\n' && file_remain != 0) {
|
||||
in_bufpos++;
|
||||
|
||||
if (in_bufpos >= in_bufend) {
|
||||
file_remain -= in_bufend - in_buffer;
|
||||
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
||||
in_bufpos = in_buffer;
|
||||
}
|
||||
}
|
||||
/* if ((a = fgetc (infile)) != '\n')
|
||||
ungetc (a,infile); */
|
||||
} else {
|
||||
*out_bufpos = a;
|
||||
out_bufpos++;
|
||||
if (out_bufpos == out_bufend) {
|
||||
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
||||
out_bufpos = out_buffer;
|
||||
}
|
||||
/* fputc(a,outfile); */
|
||||
}
|
||||
}
|
||||
/* Check for remained in output buffer */
|
||||
if (out_bufpos != out_buffer)
|
||||
my_fwrite(out_buffer,outfile,out_bufpos - out_buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* convert_tunix() ... convert files to use LF as EOL
|
||||
*
|
||||
* Inputs:
|
||||
* FILE *infile File to read from
|
||||
* FILE *outfile File to write to
|
||||
*
|
||||
* Outputs:
|
||||
* None
|
||||
*/
|
||||
|
||||
void convert_tunix (FILE *infile, FILE *outfile) {
|
||||
unsigned char a;
|
||||
unsigned char *in_bufpos;
|
||||
unsigned char *out_bufpos;
|
||||
unsigned char *in_bufend;
|
||||
unsigned char *out_bufend;
|
||||
size_t file_remain;
|
||||
|
||||
in_bufpos = in_buffer;
|
||||
out_bufpos = out_buffer;
|
||||
|
||||
(void) fseek(infile,0L,SEEK_END);
|
||||
file_remain = ftell(infile);
|
||||
rewind(infile);
|
||||
|
||||
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
||||
out_bufend = out_buffer + BUFFERSIZE;
|
||||
|
||||
while (file_remain != 0) {
|
||||
a = *in_bufpos;
|
||||
in_bufpos++;
|
||||
|
||||
if (in_bufpos >= in_bufend) {
|
||||
file_remain -= in_bufend - in_buffer;
|
||||
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
||||
in_bufpos = in_buffer;
|
||||
}
|
||||
/* a = fgetc (infile); */
|
||||
|
||||
if(a == '\r') {
|
||||
*out_bufpos = '\n';
|
||||
out_bufpos++;
|
||||
if (out_bufpos == out_bufend) {
|
||||
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
||||
out_bufpos = out_buffer;
|
||||
}
|
||||
/* fputc('\n',outfile); */
|
||||
|
||||
if (*in_bufpos == '\n' && file_remain != 0) {
|
||||
in_bufpos++;
|
||||
|
||||
if (in_bufpos >= in_bufend) {
|
||||
file_remain -= in_bufend - in_buffer;
|
||||
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
||||
in_bufpos = in_buffer;
|
||||
}
|
||||
}
|
||||
/* if ((a = fgetc (infile)) != '\n')
|
||||
ungetc (a,infile); */
|
||||
} else {
|
||||
*out_bufpos = a;
|
||||
out_bufpos++;
|
||||
if (out_bufpos == out_bufend) {
|
||||
my_fwrite(out_buffer,outfile,BUFFERSIZE);
|
||||
out_bufpos = out_buffer;
|
||||
}
|
||||
/* fputc(a,outfile); */
|
||||
}
|
||||
}
|
||||
/* Check for remainder in output buffer */
|
||||
if (out_bufpos != out_buffer)
|
||||
my_fwrite(out_buffer,outfile,out_bufpos - out_buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* convert_fast_gs() ... convert files to use CR as EOL
|
||||
* Do not care about differing EOL chars in the same file,
|
||||
* do not allow '\0' bytes, and replace in-vitro if possible.
|
||||
*
|
||||
* Inputs:
|
||||
* FILE *infile File to read from
|
||||
* FILE *outfile File to write to
|
||||
*
|
||||
* Outputs:
|
||||
* int FALSE if no conversion took place, TRUE otherwise
|
||||
*/
|
||||
|
||||
int convert_fast_gs(FILE *infile, FILE *outfile) {
|
||||
unsigned char a;
|
||||
unsigned char *in_bufpos;
|
||||
unsigned char *out_bufpos;
|
||||
unsigned char *in_bufend;
|
||||
unsigned char *out_bufend;
|
||||
size_t file_remain;
|
||||
enum file_format infile_type;
|
||||
|
||||
in_bufpos = in_buffer;
|
||||
out_bufpos = out_buffer;
|
||||
|
||||
(void) fseek(infile,0L,SEEK_END);
|
||||
file_remain = ftell(infile);
|
||||
rewind(infile);
|
||||
|
||||
in_bufend = in_buffer + my_fread(infile,BUFFERSIZE);
|
||||
out_bufend = out_buffer + BUFFERSIZE;
|
||||
*in_bufend = '\0';
|
||||
|
||||
infile_type = get_file_format (in_buffer);
|
||||
|
||||
switch (infile_type) {
|
||||
case apple:
|
||||
if (verbose)
|
||||
printf("%s: %s is already in Apple format, skipping.\n",
|
||||
program_name,current_file);
|
||||
return (FALSE);
|
||||
break;
|
||||
|
||||
case tunix:
|
||||
/* Replace "in-vitro", so out_buffer isn't used */
|
||||
while (file_remain != 0) {
|
||||
a = *in_bufpos;
|
||||
if (a == '\n')
|
||||
*in_bufpos++ = '\r';
|
||||
else if (a == '\0') { /* End of buffer reached */
|
||||
|
||||
/* Write changed buffer out */
|
||||
my_fwrite(in_buffer,outfile,in_bufend - in_buffer);
|
||||
|
||||
/* And reload it */
|
||||
file_remain -= in_bufend - in_buffer;
|
||||
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
||||
*in_bufend = '\0';
|
||||
in_bufpos = in_buffer;
|
||||
} else in_bufpos++;
|
||||
}
|
||||
return (TRUE);
|
||||
break;
|
||||
|
||||
case dos:
|
||||
/* This I couldn't speed up, so use the existing thing */
|
||||
convert_gs (infile, outfile);
|
||||
return (TRUE);
|
||||
break;
|
||||
|
||||
case binary:
|
||||
return (FALSE);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr,"%s: Fatal internal error\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
break;
|
||||
} /* switch */
|
||||
}
|
||||
|
||||
/*
|
||||
* convert_fast_messy() ... convert files to use CR/LF as EOL
|
||||
* Just check if it's already in DOS format.
|
||||
*
|
||||
* Inputs:
|
||||
* FILE *infile File to read from
|
||||
* FILE *outfile File to write to
|
||||
*
|
||||
* Outputs:
|
||||
* int FALSE if no conversion took place, TRUE otherwise
|
||||
*/
|
||||
|
||||
int convert_fast_messy (FILE *infile, FILE *outfile) {
|
||||
unsigned char *in_bufpos;
|
||||
unsigned char *out_bufpos;
|
||||
unsigned char *in_bufend;
|
||||
unsigned char *out_bufend;
|
||||
size_t file_remain;
|
||||
enum file_format infile_type;
|
||||
|
||||
in_bufpos = in_buffer;
|
||||
out_bufpos = out_buffer;
|
||||
|
||||
(void) fseek(infile,0L,SEEK_END);
|
||||
file_remain = ftell(infile);
|
||||
rewind(infile);
|
||||
|
||||
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
||||
out_bufend = out_buffer + BUFFERSIZE;
|
||||
*in_bufend = '\0';
|
||||
|
||||
infile_type = get_file_format (in_buffer);
|
||||
|
||||
switch (infile_type) {
|
||||
case dos:
|
||||
if (verbose)
|
||||
printf("%s: %s is already in MS-DOS format, skipping.\n",
|
||||
program_name,current_file);
|
||||
return (FALSE);
|
||||
break;
|
||||
|
||||
case tunix: /* drop through */
|
||||
case apple:
|
||||
/* Wasn't able to speed this up, call old routine */
|
||||
convert_messy (infile, outfile);
|
||||
return (TRUE);
|
||||
break;
|
||||
|
||||
case binary:
|
||||
return (FALSE);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr,"%s: Fatal internal error\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
break;
|
||||
} /* switch */
|
||||
}
|
||||
|
||||
/*
|
||||
* convert_fast_tunix() ... convert files to use LF as EOL
|
||||
* Do not care about differing EOL chars in the same file,
|
||||
* do not allow '\0' bytes, and replace in-vitro if possible.
|
||||
*
|
||||
* Inputs:
|
||||
* FILE *infile File to read from
|
||||
* FILE *outfile File to write to
|
||||
*
|
||||
* Outputs:
|
||||
* int FALSE if no conversion took place, TRUE otherwise
|
||||
*/
|
||||
|
||||
int convert_fast_tunix (FILE *infile, FILE *outfile) {
|
||||
unsigned char a;
|
||||
unsigned char *in_bufpos;
|
||||
unsigned char *out_bufpos;
|
||||
unsigned char *in_bufend;
|
||||
unsigned char *out_bufend;
|
||||
size_t file_remain;
|
||||
enum file_format infile_type;
|
||||
|
||||
in_bufpos = in_buffer;
|
||||
out_bufpos = out_buffer;
|
||||
|
||||
(void) fseek(infile,0L,SEEK_END);
|
||||
file_remain = ftell(infile);
|
||||
rewind(infile);
|
||||
|
||||
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
||||
out_bufend = out_buffer + BUFFERSIZE;
|
||||
*in_bufend = '\0';
|
||||
|
||||
infile_type = get_file_format (in_buffer);
|
||||
|
||||
switch (infile_type) {
|
||||
case tunix:
|
||||
if (verbose)
|
||||
printf("%s: %s is already in Unix format, skipping.\n",
|
||||
program_name,current_file);
|
||||
return (FALSE);
|
||||
break;
|
||||
|
||||
case apple:
|
||||
/* Replace "in-vitro", so out_buffer isn't used */
|
||||
while (file_remain != 0) {
|
||||
a = *in_bufpos;
|
||||
if (a == '\r')
|
||||
*in_bufpos++ = '\n';
|
||||
else if (a == '\0'){ /* End of buffer reached */
|
||||
|
||||
/* Write changed buffer out */
|
||||
my_fwrite(in_buffer,outfile,in_bufend - in_buffer);
|
||||
|
||||
/* And reload */
|
||||
file_remain -= in_bufend - in_buffer;
|
||||
in_bufend = in_buffer + my_fread(infile, BUFFERSIZE);
|
||||
*in_bufend = '\0';
|
||||
in_bufpos = in_buffer;
|
||||
} else in_bufpos++;
|
||||
}
|
||||
return (TRUE);
|
||||
break;
|
||||
|
||||
case dos:
|
||||
/* Couldn't speed it up, so use old routine */
|
||||
convert_tunix (infile, outfile);
|
||||
return (TRUE);
|
||||
break;
|
||||
|
||||
case binary:
|
||||
return (FALSE);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr,"%s: Fatal internal error\n", program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
break;
|
||||
} /* switch */
|
||||
}
|
||||
|
||||
/*
|
||||
* get_file_format() ... look at a buffer and find out what the EOL
|
||||
* character is. If no EOL character is found, print an error message
|
||||
* and exit.
|
||||
*
|
||||
* Inputs:
|
||||
* unsigned char *buffer Buffer to search through, terminated
|
||||
* by '\0'.
|
||||
*
|
||||
* Output:
|
||||
* enum file_format tunix, dos, apple, or binary
|
||||
*/
|
||||
|
||||
enum file_format get_file_format (unsigned char *buffer) {
|
||||
unsigned char c;
|
||||
enum file_format result = 0;
|
||||
|
||||
while ((c = *buffer++) != '\0') {
|
||||
if (c == '\n') {
|
||||
result = tunix;
|
||||
break;
|
||||
} else if (c == '\r') {
|
||||
if (*buffer == '\n')
|
||||
result = dos;
|
||||
else
|
||||
result = apple;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
if (verbose)
|
||||
printf("%s: No EOL found on the first %d bytes "
|
||||
"of %s. Might be a binary file. File skipped\n",
|
||||
program_name,BUFFERSIZE, current_file);
|
||||
result = binary;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* tryopen() ... try to open a file, exit if unsuccesful
|
||||
*
|
||||
* Inputs:
|
||||
* char *name Name of file to be opened
|
||||
* char *mode Mode string for fopen() call
|
||||
*
|
||||
* Output:
|
||||
* FILE * File identifier of successful fopen()
|
||||
*/
|
||||
|
||||
FILE *tryopen (char *name, char *mode) {
|
||||
FILE *tmp;
|
||||
|
||||
if ((tmp = fopen(name,mode)) == NULL) {
|
||||
fprintf(stderr,"%s: Unable to open file %s\n",program_name, name);
|
||||
exit (EXIT_FAILURE);
|
||||
} else
|
||||
return (tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* my_fread() ... read data into global buffer and exit if I fail
|
||||
*
|
||||
* Inputs:
|
||||
* FILE *infile File to read from
|
||||
* int howmuch Number of bytes to read
|
||||
*
|
||||
* Output:
|
||||
* int Number of bytes actually read
|
||||
*/
|
||||
|
||||
int my_fread(FILE *infile, int howmuch) {
|
||||
int result;
|
||||
|
||||
result = fread(in_buffer, 1, howmuch, infile);
|
||||
if (ferror(infile)) {
|
||||
fprintf(stderr,"%s: Error while reading data\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* my_fwrite() ... write data from global buffer to file
|
||||
*
|
||||
* Inputs:
|
||||
* unsigned char *buffer Buffer to write out
|
||||
* FILE *outfile File to write to
|
||||
* int howmuch Number of bytes to write
|
||||
*
|
||||
* Output:
|
||||
* None
|
||||
*/
|
||||
|
||||
void my_fwrite (unsigned char *buffer, FILE *outfile, int howmuch) {
|
||||
fwrite(buffer, 1, howmuch, outfile);
|
||||
if (ferror(outfile)) {
|
||||
fprintf(stderr,"%s: Error while writing data\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* cleanup() ... called in case of an exit(). Frees memory I allocated.
|
||||
*
|
||||
* Inputs:
|
||||
* None
|
||||
*
|
||||
* Output:
|
||||
* None
|
||||
*/
|
||||
|
||||
void cleanup (void) {
|
||||
char **p;
|
||||
|
||||
free (program_name);
|
||||
free (current_file);
|
||||
free (in_buffer);
|
||||
free (out_buffer);
|
||||
free (tempfile);
|
||||
if (pathList) {
|
||||
p = pathList;
|
||||
while(*p) free(*p++);
|
||||
free (pathList);
|
||||
}
|
||||
|
||||
if (tempfile)
|
||||
remove (tempfile);
|
||||
}
|
||||
|
||||
/*
|
||||
* usage() ... print out a usage string gotten from udluse.c
|
||||
*
|
||||
* Inputs:
|
||||
* None
|
||||
*
|
||||
* Outputs:
|
||||
* None
|
||||
*/
|
||||
|
||||
void usage (void) {
|
||||
extern char use1[]; /* from udluse.c */
|
||||
#ifdef GNO
|
||||
extern char use2[];
|
||||
#endif
|
||||
|
||||
fprintf(stderr,"%s",use1);
|
||||
#ifdef GNO
|
||||
if(!needsgno())
|
||||
fprintf(stderr,"%s",use2);
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* build_file_list() build the list of files to process
|
||||
*
|
||||
* Precondition:
|
||||
* file is the file name to be added to the pathList
|
||||
* recurse if non-zero, directories will be recursed
|
||||
*
|
||||
* Postcondition:
|
||||
* pathList will be a NULL-terminated array of strings. Each
|
||||
* string is a partial pathname (relative to rootdir) of a file
|
||||
* to convert.
|
||||
*
|
||||
* Note: This is a recursive routine that uses up (3 * sizeof(char *))
|
||||
* bytes of stack with each level of subdirectories.
|
||||
*/
|
||||
|
||||
|
||||
void build_file_list(char *file, short recurse) {
|
||||
char *thisdir;
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
|
||||
/* check for stack overflow */
|
||||
recursionDepth++;
|
||||
#ifdef OVERFLOW_CHECK
|
||||
if ((recursionDepth * BYTES_PER_DEPTH + BASESIZE) > STACKSIZE) {
|
||||
fprintf(stderr,"%s: Exceeded permitted nesting depth (%d levels)\n"
|
||||
"Aborted.\n",program_name,recursionDepth);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (stat(file,&tstat)!=0) {
|
||||
fprintf(stderr,"%s: Couldn't stat %s. File skipped\n",program_name,file);
|
||||
--recursionDepth;
|
||||
return;
|
||||
}
|
||||
|
||||
if (recurse && S_ISDIR(tstat.st_mode)) {
|
||||
char tstr[2];
|
||||
|
||||
/*
|
||||
* It is a directory. recurse through it.
|
||||
*/
|
||||
|
||||
/* save our state */
|
||||
tstr[0] = dirbrk;
|
||||
tstr[1] = '\0';
|
||||
if (*currentDirectory) {
|
||||
thisdir = strdup(currentDirectory);
|
||||
} else {
|
||||
thisdir = malloc(1);
|
||||
if (thisdir != NULL) *thisdir='\0';
|
||||
}
|
||||
if (thisdir == NULL) {
|
||||
perror("Couldn't duplicate current directory");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (*currentDirectory) strcat(currentDirectory,tstr);
|
||||
strcat(currentDirectory,file);
|
||||
if (currentDirectory[strlen(currentDirectory)-1] == dirbrk)
|
||||
currentDirectory[strlen(currentDirectory)-1] = '\0';
|
||||
|
||||
/* recurse */
|
||||
if ((dir = opendir(file)) == NULL) {
|
||||
fprintf(stderr,"%s: Couldn't open %s. Directory skipped.\n",
|
||||
program_name,currentDirectory);
|
||||
} else {
|
||||
if (chdir(file) !=0) {
|
||||
fprintf(stderr,"couldn't cd to %s\n",currentDirectory);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
#ifdef READDIR_RETURNS_DOT
|
||||
entry = readdir(dir); /* for "." */
|
||||
entry = readdir(dir); /* for ".." */
|
||||
#endif
|
||||
|
||||
while ((entry = readdir(dir))!=NULL) {
|
||||
/* ignore hidden files */
|
||||
#ifdef BROKEN_DIRENT_STRUCT
|
||||
if (*(entry->d_name)!='.') build_file_list((entry->d_name)-2,1);
|
||||
#else
|
||||
if (*(entry->d_name)!='.') build_file_list(entry->d_name,1);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (*thisdir) {
|
||||
if ((chdir(rootdir)!=0) || (chdir(thisdir)!=0)) {
|
||||
fprintf(stderr,"couldn't cd to %s\n",thisdir);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
} else {
|
||||
if (chdir(rootdir)!=0) {
|
||||
fprintf(stderr,"couldn't cd to calling directory\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* restore our state */
|
||||
strcpy(currentDirectory,thisdir);
|
||||
free(thisdir);
|
||||
|
||||
} else if (S_ISREG(tstat.st_mode)) {
|
||||
|
||||
/* It is a normal file. Add it to the pathList */
|
||||
add_to_pathList(currentDirectory, file);
|
||||
}
|
||||
|
||||
--recursionDepth;
|
||||
return;
|
||||
}
|
||||
|
||||
void add_to_pathList(char *thisdir, char *file) {
|
||||
char **p;
|
||||
|
||||
/* expand the pathList if necessary */
|
||||
if (pathSlotsUsed >= pathSlots) {
|
||||
pathSlots += PATHLIST_QUANTUM;
|
||||
#if BROKEN_REALLOC
|
||||
if ((pathList==NULL) &&
|
||||
((pathList = malloc((pathSlots+1) * sizeof(char *)))==NULL)) {
|
||||
fprintf(stderr,"%s: Couldn't expand pathList\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
} else {
|
||||
if ((p = realloc(pathList, (pathSlots+1) * sizeof(char *)))==NULL) {
|
||||
fprintf(stderr,"%s: Couldn't expand pathList\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
pathList = p;
|
||||
}
|
||||
#else
|
||||
if ((p = realloc(pathList,(pathSlots+1) * sizeof(char *)))==NULL) {
|
||||
fprintf(stderr,"%s: Couldn't expand pathList\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
} else pathList = p;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* add in the current directory and filename to the pathList */
|
||||
pathList[pathSlotsUsed] = malloc(strlen(thisdir)+strlen(file)+2);
|
||||
if (pathList[pathSlotsUsed] == NULL) {
|
||||
fprintf(stderr,"%s: Couldn't duplicate filename %s%c%s\n",program_name,
|
||||
thisdir,dirbrk,file);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (*thisdir) {
|
||||
sprintf(pathList[pathSlotsUsed],"%s%c%s",thisdir,dirbrk,file);
|
||||
} else {
|
||||
strcpy(pathList[pathSlotsUsed],file);
|
||||
}
|
||||
pathSlotsUsed++;
|
||||
pathList[pathSlotsUsed] = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mktemp() construct a unique file name
|
||||
*
|
||||
* This routine is slightly different than the Unix standard one,
|
||||
* thus the capitalization.
|
||||
*
|
||||
* Inputs:
|
||||
* base Template to construct the name upon. It should
|
||||
* be in the format "nameXXXXXX" where all "X" are replaced
|
||||
* in such a way that the resulting name is unique. There
|
||||
* should be at least one, at most 15 "X" in the base name.
|
||||
* base may contain a full or partial path.
|
||||
*
|
||||
* Outputs:
|
||||
* Mktemp() returns a pointer to a dynamically allocated string
|
||||
* containing a unique file name.
|
||||
*
|
||||
*/
|
||||
|
||||
char *Mktemp(const char *base)
|
||||
{
|
||||
static char id[16] = "AAAAAAAAAAAAAAA";
|
||||
char *p1,*p2,*st;
|
||||
|
||||
if ((st = malloc(strlen(base) + 1)) == NULL)
|
||||
{
|
||||
fprintf(stderr,"%s: memory allocation failure\n", program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
st = strcpy(st,base);
|
||||
|
||||
if (*st == '\0')
|
||||
{
|
||||
free (st);
|
||||
if ((st = strdup("TXXXXXXX")) == NULL)
|
||||
{
|
||||
fprintf(stderr,"%s: memory allocation failure\n", program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Replace all "X" with part of ID string */
|
||||
for(p1 = st + strlen(st) - 1,p2 = &id[14];
|
||||
p1 >= st && p2 >= id && *p1 == 'X';
|
||||
p1--,p2--)
|
||||
*p1 = *p2;
|
||||
|
||||
/* Update ID string to "count" one further */
|
||||
for(p1 = &id[14];p1 >= id;)
|
||||
if(*p1 == 'Z')
|
||||
{
|
||||
*p1 = 'A';
|
||||
p1--;
|
||||
} else {
|
||||
*p1 += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Make sure the file name does not already exist */
|
||||
#ifdef GNO
|
||||
if (needsgno() == TRUE) {
|
||||
#endif
|
||||
if (stat(st,&tstat) == 0)
|
||||
{
|
||||
free (st);
|
||||
st = Mktemp (base);
|
||||
}
|
||||
#ifdef GNO
|
||||
} else { /* ORCA/Shell doesn't like stat one little bit */
|
||||
FILE *fp;
|
||||
if ((fp = fopen(st,"r")) != NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
free (st);
|
||||
st = Mktemp (base);
|
||||
} else if ((fp = fopen(st,"a")) == NULL) {
|
||||
free(st);
|
||||
st = Mktemp (base);
|
||||
} else {
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
/* get_path() ... extract path from filename
|
||||
*
|
||||
* Inputs:
|
||||
* name A file name containing a full, partial or no path.
|
||||
*
|
||||
* Outputs:
|
||||
* Pointer to a string in static memory containing the path
|
||||
* to the given file, or an empty string if "name" contained
|
||||
* no path. The string can hold MAXPATHLEN characters.
|
||||
*/
|
||||
|
||||
char *get_path (const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
strcpy(filebuffer, name);
|
||||
|
||||
for (i = strlen(filebuffer) - 1; i > 0 && filebuffer[i] != dirbrk; i--)
|
||||
; /* empty loop to find end of path in name */
|
||||
|
||||
if (i != 0)
|
||||
++i;
|
||||
filebuffer[i] = '\0';
|
||||
return filebuffer;
|
||||
}
|
||||
|
||||
/* End Of File */
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* udl - Convert EOL formats freely between MS-DOS (CR/LF), Unix/Amiga (LF),
|
||||
* and Apple (CR).
|
||||
*
|
||||
* Header file for routines common to both the Unix and Apple IIgs versions.
|
||||
*
|
||||
* $Id: common.h,v 1.8 1996/01/22 01:01:33 gdr Exp $
|
||||
*
|
||||
* Copyright (c) 1993-1995 Soenke Behrens, Devin Reade
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#define BUFFERSIZE 0x2000
|
||||
#define PATHLIST_QUANTUM 20
|
||||
#define UDL_VERSION "Version 1.14"
|
||||
#define STACKSIZE 2048
|
||||
#define BYTES_PER_DEPTH 40
|
||||
#define BASESIZE 700
|
||||
|
||||
#ifndef FALSE
|
||||
# define FALSE 0
|
||||
# define TRUE !FALSE
|
||||
#endif
|
||||
|
||||
#ifndef EXIT_FAILURE
|
||||
# define EXIT_FAILURE 1
|
||||
# define EXIT_SUCCESS 0
|
||||
#endif
|
||||
|
||||
#ifdef HAS_ATEXIT
|
||||
# define EXIT(a) exit(a)
|
||||
#else
|
||||
# define EXIT(a) { cleanup(); exit(a); }
|
||||
#endif
|
||||
|
||||
enum file_format { tunix = 1, dos, apple, binary };
|
||||
|
||||
/* Since udl is so small, I dare to use some globals :) */
|
||||
extern char *program_name; /* How was udl invoked? */
|
||||
extern char *current_file; /* Name of current file */
|
||||
extern char *tempfile; /* Name of temporary file */
|
||||
extern unsigned char *in_buffer; /* My own buffering scheme instead of */
|
||||
extern unsigned char *out_buffer; /* setvbuf() */
|
||||
extern int verbose;
|
||||
extern char filebuffer[MAXPATHLEN]; /* a scratch buffer for file names */
|
||||
extern char currentDirectory[MAXPATHLEN];
|
||||
extern char rootdir[MAXPATHLEN]; /* the initial directory */
|
||||
extern struct stat tstat; /* temporary variable used to stat files */
|
||||
extern int pathSlotsUsed; /* number of used and available slots in pathList,*/
|
||||
extern int pathSlots; /* respectively. Both are initially zero. */
|
||||
extern char **pathList; /* the list of files to process, given relative */
|
||||
/* to the initial directory. Initially NULL, */
|
||||
/* and NULL terminated. */
|
||||
extern char dirbrk; /* the character used to separate parts of a path name */
|
||||
extern int recursionDepth; /* levels of subdirectories that we've traversed */
|
||||
extern int optind; /* part of getopt library */
|
||||
extern int opterr;
|
||||
|
||||
/* Prototypes of functions in common.c */
|
||||
|
||||
extern void convert_gs (FILE *infile, FILE *outfile);
|
||||
extern void convert_messy (FILE *infile, FILE *outfile);
|
||||
extern void convert_tunix (FILE *infile, FILE *outfile);
|
||||
extern int convert_fast_gs (FILE *infile, FILE *outfile);
|
||||
extern int convert_fast_messy (FILE *infile, FILE *outfile);
|
||||
extern int convert_fast_tunix (FILE *infile, FILE *outfile);
|
||||
extern enum file_format get_file_format (unsigned char *buffer);
|
||||
extern FILE *tryopen (char *file, char *mode);
|
||||
extern int my_fread (FILE *infile, int howmuch);
|
||||
extern void my_fwrite (unsigned char *buffer, FILE *outfile, int howmuch);
|
||||
extern void cleanup (void);
|
||||
extern void usage (void);
|
||||
extern void build_file_list(char *file, short recurse);
|
||||
extern void add_to_pathList(char *thisdir, char *file);
|
||||
extern char *get_path(const char *name);
|
||||
extern char *Mktemp(const char *base);
|
||||
extern int needsgno(void);
|
||||
|
||||
/* not strictly necessary, but it cuts down on warnings from gcc */
|
||||
#if defined(__GNUC__) || defined(_AIX)
|
||||
extern char *getwd(char *);
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
extern char getopt(int, char **, char *);
|
||||
#endif
|
||||
|
||||
/* End Of File */
|
|
@ -1,9 +0,0 @@
|
|||
Name: udl
|
||||
Version: 1.15
|
||||
Author: Soenke Behrens, Devin Reade
|
||||
Contact: sbehrens@contech.demon.co.uk, gdr@myrias.ab.ca
|
||||
Where: /usr/local/bin
|
||||
FTP: ftp.cco.caltech.edu, grind.isca.uiowa.edu
|
||||
|
||||
Converts text between the CR, LF and CR/LF forms. Also available for Unix
|
||||
machines, reasonably fast yet secure.
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* udl - Convert EOL formats freely between MS-DOS (CR/LF), Unix/Amiga (LF),
|
||||
* and Apple (CR).
|
||||
*
|
||||
* Contains definitions of global variables declared in common.h
|
||||
*
|
||||
* $Id: globals.c,v 1.5 1996/01/22 01:01:34 gdr Exp $
|
||||
*
|
||||
* Copyright (c) 1993-1995 Soenke Behrens, Devin Reade
|
||||
*/
|
||||
|
||||
#ifdef GNO
|
||||
#pragma noroot
|
||||
#endif
|
||||
|
||||
#include "common.h"
|
||||
|
||||
char *program_name; /* How was udl invoked? */
|
||||
char *current_file; /* Name of current file */
|
||||
char *tempfile; /* Name of temporary file */
|
||||
unsigned char *in_buffer; /* My own buffering scheme instead of */
|
||||
unsigned char *out_buffer; /* setvbuf() */
|
||||
int verbose;
|
||||
char filebuffer[MAXPATHLEN]; /* a scratch buffer for file names */
|
||||
char currentDirectory[MAXPATHLEN];
|
||||
char rootdir[MAXPATHLEN]; /* the initial directory */
|
||||
struct stat tstat; /* temporary variable used to stat files */
|
||||
int pathSlotsUsed; /* number of used and available slots in pathList,*/
|
||||
int pathSlots; /* respectively. Both are initially zero. */
|
||||
char **pathList; /* the list of files to process, given relative */
|
||||
/* to the initial directory. Initially NULL, */
|
||||
/* and NULL terminated. */
|
||||
char dirbrk; /* the character used to separate parts of a path name */
|
||||
int recursionDepth; /* levels of subdirectories that we've traversed */
|
||||
|
||||
/* End Of File */
|
|
@ -1,95 +0,0 @@
|
|||
.\" Copyright (c) 1993-1995 Soenke Behrens, Devin Reade
|
||||
.\" $Id: udl.1,v 1.8 1996/01/22 01:01:34 gdr Exp $
|
||||
.\"
|
||||
.TH UDL 1 "Commands and Applications" "21 January 1996" "Version 1.15"
|
||||
.SH NAME
|
||||
udl - convert text files between different architectures
|
||||
.SH SYNOPSIS
|
||||
.BR udl
|
||||
.BR -u | m | g
|
||||
[
|
||||
.B -Rvp
|
||||
]
|
||||
.I file1
|
||||
[
|
||||
.IR file2 " ..."
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.B udl
|
||||
converts files between different computer systems by changing the EOL
|
||||
(End-Of-Line) character.
|
||||
.PP
|
||||
On the Apple IIgs,
|
||||
.B udl
|
||||
will skip any file that is not of type TXT or SRC.
|
||||
No notice is given of this unless the
|
||||
.B -v
|
||||
flag is used.
|
||||
Since Unix file systems do not have file types
|
||||
.BR udl
|
||||
is limited in the types of checks which it can carry out,
|
||||
so the user must take care that
|
||||
it is not invoked on object files or the like. On both platforms, if
|
||||
.I file
|
||||
appears to be a binary file (that is, no EOL is
|
||||
found in the first part of the file) then
|
||||
.I file
|
||||
will be skipped.
|
||||
Again, no notice is given of this unless the
|
||||
.B -v
|
||||
flag is used.
|
||||
.PP
|
||||
During file conversion
|
||||
.B udl
|
||||
creates a temporary file in the same directory as the original file.
|
||||
The temporary file is close to or exactly the same size as the original
|
||||
file.
|
||||
.PP
|
||||
When running under Byteworks' ORCA shell, the Orca shell wildcards
|
||||
.BR =
|
||||
and
|
||||
.BR ?
|
||||
are properly expanded in file names.
|
||||
.SH OPTIONS
|
||||
.IP \fB\-u\fP
|
||||
Convert to use LF as EOL (Unix/Amiga).
|
||||
.IP \fB\-m\fP
|
||||
Convert to use CR/LF as EOL (MS-DOS).
|
||||
.IP \fB\-g\fP
|
||||
Convert to use CR as EOL (Apple).
|
||||
.IP \fB\-p\fP
|
||||
Be pedantic, only affects Unix<->Apple conversions, see below.
|
||||
.IP \fB\-R\fP
|
||||
Recurse through subdirectories.
|
||||
.IP \fB\-v\fP
|
||||
Be verbose, show the file udl is currently working on.
|
||||
.PP
|
||||
If you specify the
|
||||
.B -p
|
||||
switch,
|
||||
.B udl
|
||||
is pedantic while doing the conversion. This means: The input file may
|
||||
contain bytes with a value of zero (0), and the input file may contain
|
||||
different EOL characters (ie: MS-DOS and Unix style might be mixed in
|
||||
one file). For conversions to or from MS-DOS
|
||||
.B udl
|
||||
is always pedantic, so this only affects conversions from Unix to Apple
|
||||
or vice versa. Being pedantic slows udl down by a factor of 1.5.
|
||||
.SH LIMITATIONS
|
||||
When running under Gno on the Apple IIgs, there is a limit to the nesting
|
||||
depth when recusing on subdirectories. This is because the routine that
|
||||
is responsible for this behavior is itself recursive. The default 2k
|
||||
stack size will allow about 33 levels of nested directories, so this limit
|
||||
should not normally be a problem. If the limit is exceeded,
|
||||
.BR udl
|
||||
will exit with an error message before any files are changed, and before
|
||||
the stack actually overflows.
|
||||
.SH BUGS
|
||||
Bug reports should be directed to one of the two addresses below.
|
||||
.SH AUTHOR
|
||||
Soenke Behrens <sbehrens@contech.demon.co.uk> with contributions by
|
||||
Devin Reade <gdr@myrias.ab.ca>.
|
||||
.SH VERSION
|
||||
This is
|
||||
.B udl
|
||||
version 1.15.
|
|
@ -1,22 +0,0 @@
|
|||
#include "Types.Rez"
|
||||
|
||||
resource rVersion (0x1, purgeable1, nocrossbank) {
|
||||
{ 1, 1, 5, /* version 1.1.4 */
|
||||
release, /* development|alpha|beta|final|release */
|
||||
0 /* non-final release number */
|
||||
},
|
||||
verBritain,
|
||||
"udl",
|
||||
"Copyright 1993-1996,\n"
|
||||
"S" $"9A" "nke Behrens, Devin Reade"
|
||||
};
|
||||
|
||||
resource rComment (0x1) {
|
||||
"Text File Conversion Program\n"
|
||||
"Converts files between CR, CR/LF, and LF.\n"
|
||||
"(Apple, MS-DOS, and Unix)"
|
||||
};
|
||||
|
||||
resource rComment (0x2) {
|
||||
"Requires ORCA/Shell or GNO/ME"
|
||||
};
|
|
@ -1,417 +0,0 @@
|
|||
/*
|
||||
* udl - Convert EOL formats freely between MS-DOS (CR/LF), Unix/Amiga (LF),
|
||||
* and Apple (CR).
|
||||
*
|
||||
* Apple IIgs specific routines.
|
||||
*
|
||||
* $Id: udlgs.c,v 1.9 1996/02/04 01:34:29 gdr Exp $
|
||||
*
|
||||
* Copyright (c) 1993-1995 Soenke Behrens, Devin Reade
|
||||
*/
|
||||
|
||||
#include <orca.h>
|
||||
#include <shell.h>
|
||||
#include <gsos.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define QUITFLAG 0x4000 /* udl is restartable */
|
||||
#define DIRECTORY 0x0F
|
||||
|
||||
/*
|
||||
* Globals
|
||||
*/
|
||||
|
||||
int theType, theAuxType; /* Hold type of current file */
|
||||
Next_WildcardGSPB NextWild; /* for handling ORCA/Shell style wildcards */
|
||||
Init_WildcardGSPB InitWild;
|
||||
|
||||
extern pascal void SystemQuitFlags (unsigned);
|
||||
extern pascal void SystemQuitPath (GSString255Ptr);
|
||||
extern int needsgno(void);
|
||||
extern void begin_stack_check(void);
|
||||
extern int end_stack_check(void);
|
||||
|
||||
/*
|
||||
* Prototypes of functions in this file
|
||||
*/
|
||||
|
||||
extern int CheckGSOSType (char *name);
|
||||
extern void SetGSOSType (char *name, int type, int auxtype);
|
||||
extern int right_shell_version (void);
|
||||
|
||||
int main(int argc,char *argv[]) {
|
||||
FILE *infile, *outfile;
|
||||
int Tunix = FALSE;
|
||||
int Messy = FALSE;
|
||||
int GS = FALSE;
|
||||
int careful = FALSE;
|
||||
int converted;
|
||||
int c;
|
||||
static GSString255 gsp;
|
||||
static ResultBuf255 rsp;
|
||||
int R_flag = FALSE;
|
||||
char **p;
|
||||
|
||||
verbose = FALSE;
|
||||
recursionDepth = 0;
|
||||
program_name = NULL;
|
||||
tempfile = NULL;
|
||||
current_file = NULL;
|
||||
NextWild.pathName = NULL;
|
||||
in_buffer = out_buffer = NULL;
|
||||
pathSlotsUsed = 0;
|
||||
pathSlots = 0;
|
||||
pathList = NULL;
|
||||
*currentDirectory = '\0';
|
||||
recursionDepth=0;
|
||||
|
||||
#ifdef CHECK_STACK
|
||||
begin_stack_check();
|
||||
#endif
|
||||
|
||||
/* In case of exit(), free the mem I allocated */
|
||||
atexit (cleanup);
|
||||
|
||||
/* Make udl restartable */
|
||||
SystemQuitFlags (QUITFLAG);
|
||||
SystemQuitPath (NULL);
|
||||
|
||||
if (right_shell_version() == FALSE) {
|
||||
fprintf(stderr,"%s requires at least ORCA/Shell 2.0"
|
||||
" or GNO/ME 1.0\n", argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if ((program_name = strdup (argv[0])) == NULL) {
|
||||
fprintf(stderr,"%s: memory allocation failure\n",argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (argc < 3) {
|
||||
usage();
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Get and process arguments */
|
||||
|
||||
optind = 0;
|
||||
opterr = 1;
|
||||
while ((c = getopt (argc, argv, "pvugmR")) != EOF) {
|
||||
switch (c) {
|
||||
case 'v':
|
||||
verbose = TRUE;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
careful = TRUE;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
if (Tunix == TRUE || Messy == TRUE || GS == TRUE) {
|
||||
fprintf(stderr, "%s: You may not "
|
||||
"specify more than one conversion option\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
Tunix = TRUE;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (Tunix == TRUE || Messy == TRUE || GS == TRUE) {
|
||||
fprintf(stderr, "%s: You may not "
|
||||
"specify more than one conversion option\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
Messy = TRUE;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
if (Tunix == TRUE || Messy == TRUE || GS == TRUE) {
|
||||
fprintf(stderr, "%s: You may not "
|
||||
"specify more than one conversion option\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
GS = TRUE;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
R_flag++;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
usage();
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
default:
|
||||
fprintf (stderr, "%s: Internal getopt error\n", program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind == argc) { /* no files specified */
|
||||
usage();
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (Tunix == FALSE && GS == FALSE && Messy == FALSE) {
|
||||
fprintf(stderr,"%s: You have to specify a destination "
|
||||
"format.\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (verbose == TRUE) {
|
||||
printf ("%s version %s\n",program_name,UDL_VERSION);
|
||||
}
|
||||
|
||||
if ((in_buffer = malloc(BUFFERSIZE+1)) == NULL ||
|
||||
(out_buffer = malloc(BUFFERSIZE+1)) == NULL) {
|
||||
fprintf(stderr,"%s: Unable to buffer files\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Orca Shell: expand wildcards */
|
||||
if (!needsgno()) {
|
||||
NextWild.pCount = 1;
|
||||
InitWild.pCount = 2;
|
||||
rsp.bufSize = 259;
|
||||
NextWild.pathName = &rsp;
|
||||
InitWild.wFile = &gsp;
|
||||
if (R_flag) {
|
||||
InitWild.flags = 0x2000 | 0x1000;
|
||||
} else {
|
||||
InitWild.flags = 0;
|
||||
}
|
||||
|
||||
dirbrk = ':'; /* enforced by NextWildcardGS */
|
||||
|
||||
/* loop through all command line args */
|
||||
for (; optind < argc; optind++) {
|
||||
size_t i;
|
||||
int num_of_files;
|
||||
|
||||
i = strlen(argv[optind]);
|
||||
strncpy (gsp.text,argv[optind],i);
|
||||
gsp.length = i;
|
||||
InitWildcardGS (&InitWild);
|
||||
num_of_files = 0;
|
||||
|
||||
/* loop through all matches of wildcards */
|
||||
for (;;) {
|
||||
NextWildcardGS (&NextWild);
|
||||
if (toolerror()) {
|
||||
fprintf(stderr,"%s: Fatal internal error, "
|
||||
"exiting\n", program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* No further file found by NextWildcardGS */
|
||||
if(!rsp.bufString.length)
|
||||
break;
|
||||
|
||||
num_of_files++;
|
||||
|
||||
if((current_file = calloc(1,rsp.bufString.length + 1)) == NULL) {
|
||||
fprintf(stderr,"%s: memory allocation failure\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
strncpy(current_file, rsp.bufString.text,rsp.bufString.length);
|
||||
|
||||
add_to_pathList("",current_file);
|
||||
free(current_file);
|
||||
current_file = NULL;
|
||||
} /* for (;;) */
|
||||
|
||||
if (num_of_files == 0)
|
||||
fprintf(stderr,"%s: No files found that match %s\n",
|
||||
program_name,argv[optind]);
|
||||
} /* for (; optind < argc; optind++) */
|
||||
}
|
||||
/* gsh or other Gno shell */
|
||||
else {
|
||||
|
||||
/* save the directory we're in */
|
||||
if (getwd(rootdir)==NULL) {
|
||||
fprintf(stderr,"%s: Couldn't stat .\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (; optind<argc; optind++) {
|
||||
/* set the directory separator character. */
|
||||
dirbrk = (strchr(argv[optind],':')!=NULL) ? ':' : '/';
|
||||
build_file_list(argv[optind],R_flag);
|
||||
chdir(rootdir);
|
||||
*currentDirectory = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* files were all directories and no -R flag given */
|
||||
if (!pathList) {
|
||||
if (verbose) printf("%s: no files to process\n",program_name);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
p = pathList;
|
||||
while(*p) {
|
||||
current_file = *p;
|
||||
|
||||
if (CheckGSOSType (current_file) == FALSE) {
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
if (verbose == TRUE) {
|
||||
printf("%s: Working on %s\n",program_name,current_file);
|
||||
}
|
||||
|
||||
infile = tryopen(current_file,"rwb");
|
||||
tempfile = Mktemp(strcat(get_path(current_file), "udltmpXX"));
|
||||
outfile = tryopen(tempfile,"wb");
|
||||
|
||||
if (careful) {
|
||||
converted = TRUE; /* always */
|
||||
|
||||
if (GS)
|
||||
convert_gs(infile,outfile);
|
||||
else if (Tunix)
|
||||
convert_tunix(infile,outfile);
|
||||
else
|
||||
convert_messy(infile,outfile);
|
||||
} else {
|
||||
if (GS)
|
||||
converted = convert_fast_gs(infile,outfile);
|
||||
else if (Tunix)
|
||||
converted = convert_fast_tunix(infile,outfile);
|
||||
else
|
||||
converted = convert_fast_messy(infile,outfile);
|
||||
}
|
||||
|
||||
if (fclose (infile) == EOF || fclose (outfile) == EOF) {
|
||||
perror ("closing files");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (converted) { /* Temp file contains converted data */
|
||||
if (remove (current_file) != 0) {
|
||||
perror ("removing original file");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (rename (tempfile,current_file) != 0) {
|
||||
perror ("cannot rename temporary file");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
} else
|
||||
remove (tempfile);
|
||||
|
||||
free (tempfile); tempfile = NULL;
|
||||
SetGSOSType (current_file, theType, theAuxType);
|
||||
p++;
|
||||
} /* end while */
|
||||
|
||||
#ifdef CHECK_STACK
|
||||
fprintf(stderr,"stack usage: %d bytes\n",end_stack_check());
|
||||
#endif
|
||||
|
||||
return (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* CheckGSOSType() ... check if a file is of type TXT or SRC
|
||||
*
|
||||
* Inputs:
|
||||
* char *name Name of file to check
|
||||
*
|
||||
* Outputs:
|
||||
* int Boolean, TRUE if file type is TXT or SRC, FALSE otherwise
|
||||
*/
|
||||
|
||||
int CheckGSOSType(char *name) {
|
||||
#define TXT 0x04
|
||||
#define SRC 0xB0
|
||||
|
||||
static GSString255 gst;
|
||||
static FileInfoRecGS fir = {5};
|
||||
size_t i;
|
||||
|
||||
i = strlen (name);
|
||||
gst.length = i;
|
||||
strncpy(gst.text,name,i);
|
||||
fir.pathname = &gst;
|
||||
|
||||
GetFileInfoGS(&fir);
|
||||
|
||||
if (toolerror()) {
|
||||
fprintf (stderr,"%s: GS/OS error on %s: 0x%04X\n",
|
||||
program_name,name,toolerror());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if ((fir.fileType != TXT) && (fir.fileType != SRC)) {
|
||||
if (verbose && (fir.fileType != DIRECTORY))
|
||||
fprintf(stderr,"%s: %s is not of type TXT or "
|
||||
"SRC ... skipping\n",program_name,current_file);
|
||||
return (FALSE);
|
||||
} else {
|
||||
theType = fir.fileType;
|
||||
theAuxType = fir.auxType;
|
||||
return (TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* SetGSOSType() ... set file and auxtype of a file.
|
||||
*
|
||||
* Inputs:
|
||||
* char *name Name of file to be affected
|
||||
* int type File type it should be set to
|
||||
* int auxtype Auxiliary type it should be set to
|
||||
*
|
||||
* Outputs:
|
||||
* None
|
||||
*/
|
||||
|
||||
void SetGSOSType (char *name, int type, int auxtype) {
|
||||
static GSString255 gst;
|
||||
static FileInfoRecGS fir = {4, NULL, 0xE3};
|
||||
size_t i;
|
||||
|
||||
i = strlen (name);
|
||||
gst.length = i;
|
||||
strncpy(gst.text,name,i);
|
||||
fir.pathname = &gst;
|
||||
fir.fileType = type;
|
||||
fir.auxType = auxtype;
|
||||
|
||||
SetFileInfoGS(&fir);
|
||||
|
||||
if (toolerror()) {
|
||||
fprintf (stderr,"%s: GS/OS error on %s: 0x%04X\n",
|
||||
program_name,name,toolerror());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* right_shell_version() ... check if at least ORCA/Shell 2.0 or
|
||||
* GNO/ME 1.0 is active.
|
||||
*
|
||||
* Inputs:
|
||||
* None
|
||||
*
|
||||
* Output:
|
||||
* int Boolean, TRUE if shell is satisfactory, FALSE otherwise
|
||||
*/
|
||||
|
||||
int right_shell_version (void) {
|
||||
static VersionPB vpb;
|
||||
|
||||
VERSION(&vpb);
|
||||
|
||||
if (vpb.version[0] < '2' || strcmp (shellid(),"BYTEWRKS") != 0)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* End Of File */
|
|
@ -1,214 +0,0 @@
|
|||
/*
|
||||
* udl - Convert EOL formats freely between MS-DOS (CR/LF), Unix/Amiga (LF),
|
||||
* and Apple (CR).
|
||||
*
|
||||
* Unix specific routines.
|
||||
*
|
||||
* $Id: udlunix.c,v 1.8 1996/01/22 01:01:35 gdr Exp $
|
||||
*
|
||||
* Copyright (c) 1993-1995 Soenke Behrens, Devin Reade
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
extern char *strdup(const char *);
|
||||
|
||||
int main(int argc,char *argv[]) {
|
||||
FILE *infile, *outfile;
|
||||
char *p;
|
||||
int Tunix = FALSE;
|
||||
int Messy = FALSE;
|
||||
int GS = FALSE;
|
||||
int careful = FALSE;
|
||||
int converted;
|
||||
int c;
|
||||
int R_flag = FALSE;
|
||||
|
||||
verbose = FALSE;
|
||||
program_name = NULL;
|
||||
tempfile = NULL;
|
||||
current_file = NULL;
|
||||
in_buffer = out_buffer = NULL;
|
||||
pathSlotsUsed = 0;
|
||||
pathSlots = 0;
|
||||
pathList = NULL;
|
||||
*currentDirectory = '\0';
|
||||
recursionDepth=0;
|
||||
|
||||
/* In case of exit(), free the mem I allocated */
|
||||
#ifdef HAS_ATEXIT
|
||||
atexit (cleanup);
|
||||
#endif
|
||||
|
||||
if ((program_name = strdup (argv[0])) == NULL) {
|
||||
fprintf(stderr,"%s: memory allocation failure\n",argv[0]);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (argc < 3) {
|
||||
usage();
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Get and process arguments */
|
||||
|
||||
opterr = 1;
|
||||
while ((c = getopt (argc, argv, "pvugmR")) != EOF) {
|
||||
switch (c) {
|
||||
case 'v':
|
||||
verbose = TRUE;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
careful = TRUE;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
if (Tunix == TRUE || Messy == TRUE || GS == TRUE) {
|
||||
fprintf(stderr, "%s: You may not "
|
||||
"specify more than one conversion option\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
Tunix = TRUE;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (Tunix == TRUE || Messy == TRUE || GS == TRUE) {
|
||||
fprintf(stderr, "%s: You may not specify more than one "
|
||||
"conversion option\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
Messy = TRUE;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
if (Tunix == TRUE || Messy == TRUE || GS == TRUE) {
|
||||
fprintf(stderr, "%s: You may not specify more than one "
|
||||
"conversion option\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
GS = TRUE;
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
R_flag++;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
usage();
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
default:
|
||||
fprintf (stderr, "%s: Internal getopt error\n", program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* no files specified */
|
||||
if (optind == argc) {
|
||||
usage();
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (Tunix == FALSE && GS == FALSE && Messy == FALSE) {
|
||||
fprintf(stderr,"%s: You have to specify a destination "
|
||||
"format.\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (verbose == TRUE) {
|
||||
printf ("%s %s\n",program_name,UDL_VERSION);
|
||||
}
|
||||
|
||||
/* Now process the files I got */
|
||||
|
||||
if ((in_buffer = malloc(BUFFERSIZE+1)) == NULL ||
|
||||
(out_buffer = malloc(BUFFERSIZE+1)) == NULL) {
|
||||
fprintf(stderr,"%s: Unable to buffer files\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* save the directory we're in */
|
||||
if (getwd(rootdir)==NULL) {
|
||||
fprintf(stderr,"%s: Couldn't stat .\n",program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* set the directory separator character. */
|
||||
dirbrk = '/';
|
||||
|
||||
/* build the list of files to process */
|
||||
for (; optind<argc; optind++) {
|
||||
build_file_list(argv[optind],R_flag);
|
||||
chdir(rootdir);
|
||||
*currentDirectory = '\0';
|
||||
}
|
||||
|
||||
/* files were all directories and no -R flag given */
|
||||
if (!pathList) {
|
||||
if (verbose) printf("%s: no files to process\n",program_name);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
for (c=0; pathList[c]; c++) {
|
||||
if((current_file = strdup(pathList[c])) == NULL) {
|
||||
fprintf(stderr,"%s: memory allocation failure\n", program_name);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (verbose == TRUE) {
|
||||
printf("%s: Working on %s\n",program_name,
|
||||
current_file);
|
||||
}
|
||||
|
||||
infile = tryopen(current_file,"rwb");
|
||||
tempfile = Mktemp(strcat(get_path(current_file), "udltmpXX"));
|
||||
outfile = tryopen(tempfile,"wb");
|
||||
|
||||
if (careful) {
|
||||
converted = TRUE; /* always */
|
||||
|
||||
if (GS)
|
||||
convert_gs(infile,outfile);
|
||||
else if (Tunix)
|
||||
convert_tunix(infile,outfile);
|
||||
else
|
||||
convert_messy(infile,outfile);
|
||||
} else {
|
||||
if (GS)
|
||||
converted = convert_fast_gs(infile,outfile);
|
||||
else if (Tunix)
|
||||
converted = convert_fast_tunix(infile,outfile);
|
||||
else
|
||||
converted = convert_fast_messy(infile,outfile);
|
||||
}
|
||||
|
||||
if (fclose (infile) == EOF || fclose (outfile) == EOF) {
|
||||
perror ("closing files");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (converted) { /* Temp file contains converted data */
|
||||
if (remove (current_file) != 0) {
|
||||
perror ("removing original file");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (rename (tempfile,current_file) != 0) {
|
||||
perror ("cannot rename temporary file");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
} else
|
||||
remove (tempfile);
|
||||
|
||||
free (tempfile); tempfile = NULL;
|
||||
free(current_file);
|
||||
current_file = NULL;
|
||||
|
||||
} /* for (c=0; pathList[c]; c++) */
|
||||
|
||||
return (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* End Of File */
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* udl - Convert EOL formats freely between MS-DOS (CR/LF), Unix/Amiga (LF),
|
||||
* and Apple (CR).
|
||||
*
|
||||
* Usage strings.
|
||||
*
|
||||
* $Id: udluse.c,v 1.8 1996/01/22 01:01:36 gdr Exp $
|
||||
*
|
||||
* Copyright (c) 1993-1995 Soenke Behrens, Devin Reade
|
||||
*/
|
||||
|
||||
#ifdef GNO
|
||||
#pragma noroot
|
||||
#endif
|
||||
|
||||
char use1 [] =
|
||||
"udl 1.15 by Soenke Behrens, Devin Reade\n"
|
||||
"Usage: udl -u|g|m [-Rvp] file1 [file2 ...]\n\n"
|
||||
"Options:\n"
|
||||
" -u Convert file to use LF as EOL character.\n"
|
||||
" -g Convert file to use CR as EOL character.\n"
|
||||
" -m Convert file to use LF/CR as EOL character.\n"
|
||||
" -R Recurse through subdirectories.\n"
|
||||
" -p Be pedantic.\n"
|
||||
" -v Be verbose about it.\n\n"
|
||||
"udl creates a temporary file in the directory of the original file.\n"
|
||||
"The original file is overwritten after conversion.\n";
|
||||
|
||||
char use2 [] =
|
||||
"\nFiles may contain ORCA/Shell style wildcards.\n";
|
||||
|
||||
/* End Of File */
|
Loading…
Reference in New Issue
Block a user