home *** CD-ROM | disk | FTP | other *** search
- Subject: v24i059: Purdue shell turbo charger and manual installer, Part03/06
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: 6e30599b ca2f7cca 2ab41a55 d3a10a38
-
- Submitted-by: Kevin Braunsdorf <ksb@cc.purdue.edu>
- Posting-number: Volume 24, Issue 59
- Archive-name: pucc-mk/part03
-
- #!/bin/sh
- # This is part 03 of pucc-1c
- # ============= mkcat/genwhatis.c ==============
- if test ! -d 'mkcat'; then
- echo 'x - creating directory mkcat'
- mkdir 'mkcat'
- fi
- if test -f 'mkcat/genwhatis.c' -a X"$1" != X"-c"; then
- echo 'x - skipping mkcat/genwhatis.c (File already exists)'
- else
- echo 'x - extracting mkcat/genwhatis.c (Text)'
- sed 's/^X//' << 'Purdue' > 'mkcat/genwhatis.c' &&
- /*
- X * Copyright 1990 Purdue Research Foundation, West Lafayette, Indiana
- X * 47907. All rights reserved.
- X *
- X * Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
- X *
- X * This software is not subject to any license of the American Telephone
- X * and Telegraph Company or the Regents of the University of California.
- X *
- X * Permission is granted to anyone to use this software for any purpose on
- X * any computer system, and to alter it and redistribute it freely, subject
- X * to the following restrictions:
- X *
- X * 1. Neither the authors nor Purdue University are responsible for any
- X * consequences of the use of this software.
- X *
- X * 2. The origin of this software must not be misrepresented, either by
- X * explicit claim or by omission. Credit to the authors and Purdue
- X * University must appear in documentation and sources.
- X *
- X * 3. Altered versions must be plainly marked as such, and must not be
- X * misrepresented as being the original software.
- X *
- X * 4. This notice may not be removed or altered.
- X */
- X
- /* $Id: genwhatis.c,v 3.3 90/08/31 12:45:46 ksb Exp $
- X *
- X * genwhatis -- update the whatis database
- X */
- #include "machine.h"
- X
- #include <stdio.h>
- #include <ctype.h>
- #include <math.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/file.h>
- #include <sys/param.h>
- #include <fcntl.h>
- #if defined(SYSV)
- #include <ndir.h>
- #else
- #include <sys/dir.h>
- #endif
- #include <sys/stat.h>
- X
- #if !defined(MAXPATHLEN)
- #define MAXPATHLEN 1024
- #endif
- X
- #include "main.h"
- #include "pt.h"
- #include "genwhatis.h"
- #include "mkcat.h"
- X
- extern char *sys_errlist[];
- #define strerror(Me) sys_errlist[Me]
- extern char *strrchr(), *strcpy();
- X
- X
- extern char *malloc(), *realloc(), *calloc();
- extern char *mktemp(), *strcat(), *strcpy();
- extern int errno;
- extern int strlen();
- X
- static char acLockExt[] = /* lock extender on db */
- X ".lock";
- X
- /*
- X * compare to whatis entries (the lowest left in each really) (ksb)
- X */
- static int
- wucmp(pWULeft, pWURight)
- register WHATIS *pWULeft, *pWURight;
- {
- X register int i;
- X
- X i = pWULeft->ppclist[0][0] - pWURight->ppclist[0][0];
- X if (i != 0)
- X return i;
- X i = strcmp(pWULeft->ppclist[0], pWURight->ppclist[0]);
- X if (i != 0)
- X return i;
- X i = pWULeft->isection - pWURight->isection;
- X if (i != 0)
- X return i;
- X return strcmp(pWULeft->pcext, pWURight->pcext);
- }
- X
- /*
- X * remove the first whatis entry in a queue (ksb)
- X */
- static void
- wudequeue(pWU)
- WHATIS *pWU;
- {
- X if (0 == pWU->ilen) {
- X fprintf(stderr, "%s: internal error\n", progname);
- X exit(20);
- X }
- X pWU->ilen -= 1;
- X pWU->ppclist += 1;
- }
- X
- /*
- X * pull the lowest string off the queues (ksb)
- X */
- static WHATIS *
- wufindmin(iLen, pWUWhats)
- int iLen;
- WHATIS *pWUWhats;
- {
- X register WHATIS *pWULow;
- X register int i, cp;
- X
- X pWULow = (WHATIS *)0;
- X for (i = 0; i < iLen; ++i) {
- X /* spent or error page -- ignore it now
- X */
- X if (0 == pWUWhats[i].ilen)
- X continue;
- X if ((WHATIS *)0 == pWULow) {
- X pWULow = & pWUWhats[i];
- X continue;
- X }
- X /* this first case can happen if we were given two
- X * copies of the same page to update... *sigh*
- X */
- X if (0 == (cp = wucmp(& pWUWhats[i], pWULow))) {
- X wudequeue(& pWUWhats[i]);
- X } else if (cp < 0) {
- X pWULow = & pWUWhats[i];
- X }
- X }
- X return pWULow;
- }
- X
- /*
- X * output a whatis entry (ksb)
- X */
- static void
- wudump(fp, pWU)
- FILE *fp;
- WHATIS *pWU;
- {
- X fprintf(fp, "%s (%s)\t- %s\n", pWU->ppclist[0], pWU->pcext, pWU->pcsummary);
- }
- X
- /*
- X * read a whatis record from a file, cannot be longer than 1024 (ksb)
- X * characters
- X */
- static WHATIS *
- nextwu(fp)
- register FILE *fp;
- {
- X static WHATIS WURet;
- X static char *apcFake[2];
- X static char acLine[1024];
- X register char *pcLine;
- X
- X if (feof(fp) || (char *)0 == (pcLine = fgets(acLine, 1024, fp))) {
- X return (WHATIS *)0;
- X }
- X
- X /* we do not copy bogus entries that the old makewhatis program
- X * would generate... " (5) -devices - UUCP ...."
- X * (for L-devices)
- X */
- X while (isspace(*pcLine))
- X ++pcLine;
- X apcFake[0] = pcLine;
- X while (! isspace(*pcLine) && '\000' != *pcLine)
- X ++pcLine;
- X
- X do {
- X *pcLine++ = '\000';
- X } while (isspace(*pcLine));
- X
- X /* should have "(Xn) - <stuff>" now */
- X if ('('/*)*/ != *pcLine)
- X return nextwu(fp);
- X while ('\b' == pcLine[1] && '(' == pcLine[2]) /*)*/
- X pcLine += 2;
- X ++pcLine;
- X WURet.isection = atoi(pcLine);
- X WURet.pcext = pcLine;
- X while (/*(*/ ')' != *pcLine && '\000' != *pcLine)
- X ++pcLine;
- X if (')' != *pcLine)
- X return nextwu(fp);
- X *pcLine++ = '\000';
- X
- X while ('-' != *pcLine && '\000' != *pcLine)
- X ++pcLine;
- X if ('-' != *pcLine)
- X return nextwu(fp);
- X
- X do {
- X ++pcLine;
- X } while (isspace(*pcLine) && '\000' != *pcLine);
- X WURet.pcsummary = pcLine;
- X
- X if ((char *)0 != (pcLine = strrchr(pcLine, '\n'))) {
- X *pcLine = '\000';
- X }
- X
- X WURet.ppclist = & apcFake[0];
- X WURet.ilen = 1;
- X
- X return & WURet;
- }
- X
- /*
- X * update the whatis database, use install (of course) (ksb)
- X * we flock the whatis database so two people can run this at
- X * about the same time...
- X *
- X * Take Old Del Add
- X * ~ n n n
- X * Old y n n
- X * ~ n y n
- X * ~ y y n
- X * Add n n y
- X * Add y n y
- X * Add n y y
- X * Add y y y
- X */
- int
- MergeWhatis(fpOldWhatis, iLenNew, pWUWhatsNew, iLenDel, pWUWhatsGone, fpNewWhatis)
- FILE *fpOldWhatis, *fpNewWhatis;
- int iLenNew, iLenDel;
- WHATIS *pWUWhatsNew, *pWUWhatsGone;
- {
- X register WHATIS *pWUAdd, *pWUDel, *pWUOld;
- X register int i, a;
- X
- X pWUOld = nextwu(fpOldWhatis);
- X pWUAdd = wufindmin(iLenNew, pWUWhatsNew);
- X pWUDel = wufindmin(iLenDel, pWUWhatsGone);
- X while ((WHATIS *)0 != pWUOld) {
- X while ((WHATIS *)0 != pWUAdd && (i = wucmp(pWUAdd, pWUOld)) < 0) {
- X wudump(fpNewWhatis, pWUAdd);
- X wudequeue(pWUAdd);
- X pWUAdd = wufindmin(iLenNew, pWUWhatsNew);
- X }
- X while ((WHATIS *)0 != pWUDel && (a = wucmp(pWUDel, pWUOld)) < 0) {
- X wudequeue(pWUDel);
- X pWUDel = wufindmin(iLenDel, pWUWhatsGone);
- X }
- X if ((WHATIS *)0 != pWUAdd && 0 == i) {
- X wudump(fpNewWhatis, pWUAdd);
- X wudequeue(pWUAdd);
- X pWUAdd = wufindmin(iLenNew, pWUWhatsNew);
- X } else if ((WHATIS *)0 != pWUDel && 0 == a) {
- X wudequeue(pWUDel);
- X pWUDel = wufindmin(iLenDel, pWUWhatsGone);
- X } else {
- X wudump(fpNewWhatis, pWUOld);
- X }
- X pWUOld = nextwu(fpOldWhatis);
- X }
- X while ((WHATIS *)0 != pWUAdd) {
- X wudump(fpNewWhatis, pWUAdd);
- X wudequeue(pWUAdd);
- X pWUAdd = wufindmin(iLenNew, pWUWhatsNew);
- X }
- X return 0;
- }
- X
- /*
- X * modify the whatis database (add or delete lines)
- X */
- int
- ModWhatis(iLenAdd, pWUAdd, iLenDel, pWUDel)
- int iLenAdd, iLenDel;
- WHATIS *pWUAdd, *pWUDel;
- {
- X register FILE *fpWhat, *fpNew;
- X register int i;
- X auto int fdLock; /* for a flock */
- X auto char *pcNew, *pcEnd;
- X auto char acNew[MAXPATHLEN+1];
- X auto char acDest[MAXPATHLEN+1];
- X auto char acCmd[4*MAXPATHLEN+200];
- #define PDELAY 2 /* sleep between peeks at the lock */
- #define MAXLOOP 30 /* wait 60 seconds for another update */
- X
- X if ('/' == pcWhatis[0] || ('.' == pcWhatis[0] && '/' == pcWhatis[1])) {
- X sprintf(acDest, "%s", pcWhatis);
- X } else {
- X sprintf(acDest, "%s/%s", pcRoot, pcWhatis);
- X }
- X pcEnd = acDest+strlen(acDest);
- X (void)strcpy(pcEnd, acLockExt);
- X if (fExec) {
- X for (i = 0; i < MAXLOOP; ++i) {
- X fdLock = open(acDest, O_EXCL|O_CREAT|O_WRONLY, 0660);
- X if (-1 == fdLock && EEXIST == errno) {
- X if (0 == i) {
- X fprintf(stderr, "%s: contending for database\n", progname);
- X (void)fflush(stderr);
- X }
- X sleep(PDELAY);
- X continue;
- X }
- X if (-1 == fdLock) {
- X fprintf(stderr, "%s: open: %s: %s\n", progname, acDest, strerror(errno));
- X exit(1);
- X }
- X (void)close(fdLock);
- X break;
- X }
- X if (MAXLOOP == i) {
- X fprintf(stderr, "%s: ignoring lock file\n", progname);
- X } else if (fVerbose) {
- X fprintf(fpOut, "%s: locked %s\n", progname, acDest);
- X }
- X }
- X *pcEnd = '\000';
- X
- X if (NULL == (fpWhat = fopen(acDest, "r"))) {
- X fprintf(stderr, "%s: fopen: %s: %s\n", progname, acDest, strerror(errno));
- X if (NULL == (fpWhat = fopen("/dev/null", "r"))) {
- X fprintf(stderr, "%s: fopen: /dev/null: %s\n", progname, strerror(errno));
- X exit(1);
- X }
- X }
- X
- X (void)strcpy(acNew, "/usr/tmp/mkwhatXXXXXX");
- X if ((char *)0 == (pcNew = mktemp(acNew))) {
- X fprintf(stderr, "%s: mktemp: no temp file\n", progname);
- X exit(1);
- X }
- X if (NULL == (fpNew = fopen(pcNew, "w"))) {
- X fprintf(stderr, "%s: fopen: %s: %s\n", progname, pcNew, strerror(errno));
- X exit(1);
- X }
- X
- X i = MergeWhatis(fpWhat, iLenAdd, pWUAdd, iLenDel, pWUDel, fpNew);
- X (void)fclose(fpWhat);
- X (void)fclose(fpNew);
- X if (0 != i) {
- X return 1;
- X }
- X
- X (void) sprintf(acCmd, "cmp -s %s %s || INSTALL=\"%s\" install", acDest, pcNew, fVerbose ? "-v" : "");
- X if ((char *)0 != apcModes[WHATISOWNER]) {
- X (void)strcat(acCmd, " -o");
- X (void)strcat(acCmd, apcModes[WHATISOWNER]);
- X }
- X if ((char *)0 != apcModes[WHATISGROUP]) {
- X (void)strcat(acCmd, " -g");
- X (void)strcat(acCmd, apcModes[WHATISGROUP]);
- X }
- X if ((char *)0 != apcModes[WHATISMODE]) {
- X (void)strcat(acCmd, " -m");
- X (void)strcat(acCmd, apcModes[WHATISMODE]);
- X }
- X (void)strcat(acCmd, " ");
- X (void)strcat(acCmd, pcNew);
- X (void)strcat(acCmd, " ");
- X (void)strcat(acCmd, acDest);
- X
- X if (fVerbose) {
- X fprintf(fpOut, "%s: %s\n", progname, acCmd);
- X }
- X (void)fflush(stdout);
- X if (fExec && 0 != system(acCmd)) {
- X return 1;
- X }
- X if (fVerbose) {
- X fprintf(fpOut, "%s: rm -f %s\n", progname, pcNew);
- X }
- X if (fExec) {
- X (void) unlink(pcNew);
- X }
- X *pcEnd = acLockExt[0];
- X if (fExec) {
- X if (-1 == unlink(acDest)) {
- X fprintf(stderr, "%s: unlink: %s: %s\n", progname, acDest, strerror(errno));
- X } else if (fVerbose) {
- X fprintf(fpOut, "%s: unlocked %s\n", progname, acDest);
- X }
- X }
- X
- X return 0;
- }
- X
- /*
- X * make a new whatis database from all the cat info (ksb)
- X */
- int
- NewWhatis(n, ppWU, piCounts)
- int n;
- WHATIS **ppWU;
- int *piCounts;
- {
- X register WHATIS **ppWUNew;
- X register FILE *fpNew;
- X register int i, f;
- X auto int fdLock; /* for a create lock */
- X auto char *pcNew, *pcEnd;
- X auto char acNew[MAXPATHLEN+1];
- X auto char acDest[MAXPATHLEN+1];
- X auto char acCmd[4*MAXPATHLEN+200];
- X
- X fprintf(fpOut, "%s: %d sections ready for whatis\n", progname, n);
- X
- X if ('/' == pcWhatis[0] || ('.' == pcWhatis[0] && '/' == pcWhatis[1])) {
- X sprintf(acDest, "%s", pcWhatis);
- X } else {
- X sprintf(acDest, "%s/%s", pcRoot, pcWhatis);
- X }
- X pcEnd = acDest+strlen(acDest);
- X (void)strcpy(pcEnd, acLockExt);
- X if (fExec) {
- X for (i = 0; i < MAXLOOP; ++i) {
- X fdLock = open(acDest, O_EXCL|O_CREAT|O_WRONLY, 0660);
- X if (-1 == fdLock && EEXIST == errno) {
- X if (0 == i) {
- X fprintf(stderr, "%s: contending for database\n", progname);
- X (void)fflush(stderr);
- X }
- X sleep(PDELAY);
- X continue;
- X }
- X if (-1 == fdLock) {
- X fprintf(stderr, "%s: open: %s: %s\n", progname, acDest, strerror(errno));
- X exit(1);
- X }
- X (void)close(fdLock);
- X break;
- X }
- X if (MAXLOOP == i) {
- X fprintf(stderr, "%s: ignoring lock file\n", progname);
- X } else if (fVerbose) {
- X fprintf(fpOut, "%s: locked %s\n", progname, acDest);
- X }
- X }
- X *pcEnd = '\000';
- X
- X (void)strcpy(acNew, "/usr/tmp/mkwhatXXXXXX");
- X if ((char *)0 == (pcNew = mktemp(acNew))) {
- X fprintf(stderr, "%s: mktemp: no temp file\n", progname);
- X return 0;
- X }
- X if (NULL == (fpNew = fopen(pcNew, "w"))) {
- X fprintf(stderr, "%s: fopen: %s: %s\n", progname, pcNew, strerror(errno));
- X return 0;
- X }
- X
- X if (0 == (ppWUNew = (WHATIS **)malloc((unsigned)n*sizeof(WHATIS *)))) {
- X fprintf(stderr, acNoMem, progname);
- X return 0;
- X }
- X for (i = 0; i < n; ++i) {
- X ppWUNew[i] = wufindmin(piCounts[i], ppWU[i]);
- X }
- X for (;;) {
- X f = -1;
- X for (i = 0; i < n; ++i) {
- X if ((WHATIS *)0 == ppWUNew[i]) {
- X continue;
- X }
- X if (f == -1 || wucmp(ppWUNew[f], ppWUNew[i]) > 0) {
- X f = i;
- X }
- X }
- X if (f == -1)
- X break;
- X wudump(fpNew, ppWUNew[f]);
- X wudequeue(ppWUNew[f]);
- X ppWUNew[f] = wufindmin(piCounts[f], ppWU[f]);
- X }
- X (void)fclose(fpNew);
- X
- X (void) sprintf(acCmd, "cmp -s %s %s || INSTALL=\"%s\" install", acDest, pcNew, fVerbose ? "-v" : "");
- X if ((char *)0 != apcModes[WHATISOWNER]) {
- X (void)strcat(acCmd, " -o");
- X (void)strcat(acCmd, apcModes[WHATISOWNER]);
- X }
- X if ((char *)0 != apcModes[WHATISGROUP]) {
- X (void)strcat(acCmd, " -g");
- X (void)strcat(acCmd, apcModes[WHATISGROUP]);
- X }
- X if ((char *)0 != apcModes[WHATISMODE]) {
- X (void)strcat(acCmd, " -m");
- X (void)strcat(acCmd, apcModes[WHATISMODE]);
- X }
- X (void)strcat(acCmd, " ");
- X (void)strcat(acCmd, pcNew);
- X (void)strcat(acCmd, " ");
- X (void)strcat(acCmd, acDest);
- X if (fVerbose) {
- X fprintf(fpOut, "%s: %s\n", progname, acCmd);
- X }
- X (void)fflush(stdout);
- X if (fExec && 0 != system(acCmd)) {
- X return 1;
- X }
- X if (fVerbose) {
- X fprintf(fpOut, "%s: rm -f %s\n", progname, pcNew);
- X }
- X if (fExec) {
- X (void) unlink(pcNew);
- X }
- X *pcEnd = acLockExt[0];
- X if (fExec) {
- X if (-1 == unlink(acDest)) {
- X fprintf(stderr, "%s: unlink: %s: %s\n", progname, acDest, strerror(errno));
- X } else if (fVerbose) {
- X fprintf(fpOut, "%s: unlocked %s\n", progname, acDest);
- X }
- X }
- X
- X return 0;
- }
- X
- /*
- X * routine for qsort(3) (ksb)
- X */
- int
- mysort(ppcLeft, ppcRight)
- char **ppcLeft, **ppcRight;
- {
- X return strcmp(*ppcLeft, *ppcRight);
- }
- X
- /*
- X * read the whatis info out of a formatted manual page (ksb)
- X * this allows us to understand what should be installed
- X * or removed from the cat dirs and whatis info...
- X *
- X * return non-zero on error
- X */
- int
- WUGrok(fpFmt, pPTPage, pWU)
- FILE *fpFmt; /* file to read stuff out of (in) */
- PATH *pPTPage; /* raw page (in) */
- WHATIS *pWU; /* whatis entries to fill in (out) */
- {
- X extern char *strsave();
- X auto char acBase[MAXPATHLEN+1];
- X auto char acSection[MAXPATHLEN+1];
- X auto char acHeader[MAXPATHLEN+1];
- X auto char **ppcLinks, *pcAlso, *pcSummary, *pcHSection;
- X auto int iLen;
- X
- X pWU->ilen = 0;
- X (void)strcpy(acBase, PTBase(pPTPage));
- X (void)strcpy(acSection, PTExt(pPTPage));
- X
- X /* rdlinks leaves LN_PAD (char *)0's for us - how nice
- X */
- X if (0 != rdlinks(fpFmt, PTFull(pPTPage), & ppcLinks, & iLen, & pcAlso, acHeader)) {
- X return 1;
- X }
- X pcSummary = ppcLinks[--iLen]; /* summary is last line */
- X
- X if (!SplitHead(acHeader, & pcHSection)) {
- X fprintf(fpOut, "%s: `%s\' has a malformed header line\n", progname, PTLocal(pPTPage));
- X return 1;
- X }
- X if (0 == strcasecmp(acSection, "man")) {
- X if (!isdigit(*pcHSection)) {
- X fprintf(fpOut, "%s: `%s\' header extender `%s\' not numeric\n", progname, PTLocal(pPTPage), pcHSection);
- X }
- X (void)strcpy(acSection, pcHSection);
- X } else if (0 != strcasecmp(acSection, pcHSection)) {
- X fprintf(fpOut, "%s: `%s\' doesn\'t match its header extender `%s\' (not fatal)\n", progname, PTLocal(pPTPage), pcHSection);
- X }
- X
- X /* here we should search the alias list for the one in the header
- X * (acHeader) and shift our weight to that one
- X */
- X if (0 != strcasecmp(acBase, acHeader)) {
- X register int i;
- X for (i = 0; i < iLen; ++i) {
- X if (0 != strcasecmp(ppcLinks[i], acHeader)) {
- X continue;
- X }
- X (void)strcpy(acBase, ppcLinks[i]);
- X break;
- X }
- X if (i == iLen) {
- X fprintf(fpOut, "%s: `%s.%s\' doesn\'t match its header name `%s\' (not fatal)\n", progname, acBase, acSection, acHeader);
- X ppcLinks[iLen++] = acHeader;
- X }
- X }
- X
- X /* put on man name */
- X ppcLinks[iLen++] = pWU->pcbase = strsave(acBase);
- X ppcLinks[iLen] = (char *)0;
- X qsort((char *)ppcLinks, iLen, sizeof(char *), mysort);
- X uniq(ppcLinks, & iLen);
- X
- X /* for the big whatis update at the end we save these
- X * (note we saved the base name already)
- X */
- X pWU->isection = atoi(acSection);
- X pWU->ilen = iLen;
- X pWU->ppclist = ppcLinks;
- X pWU->pcsummary = pcSummary;
- X pWU->pcext = strsave(acSection);
- X pWU->pcalso = pcAlso;
- X
- X return 0;
- }
- X
- /*
- X * remove the links that are in both pWUCool and pWUOld from pWUOld (ksb)
- X * This keeps us from removing a link, then putting it back
- X * return the number of links in common
- X */
- int
- WUStrike(pWUOld, pWUCool)
- WHATIS *pWUOld, *pWUCool;
- {
- X register int cnt, i, j, c;
- X
- X cnt = 0;
- X for (j = i = 0; j < pWUCool->ilen; ++j) {
- X while (i < pWUOld->ilen &&
- X 0 < (c = strcmp(pWUCool->ppclist[j], pWUOld->ppclist[i]))) {
- X ++i;
- X }
- X if (i == pWUOld->ilen)
- X break;
- X if (0 != c) {
- X continue;
- X }
- X c = i;
- X do {
- X pWUOld->ppclist[c] = pWUOld->ppclist[c+1];
- X } while (++c < pWUOld->ilen);
- X --pWUOld->ilen;
- X ++cnt;
- X }
- X return cnt;
- }
- Purdue
- chmod 0444 mkcat/genwhatis.c ||
- echo 'restore of mkcat/genwhatis.c failed'
- Wc_c="`wc -c < 'mkcat/genwhatis.c'`"
- test 15821 -eq "$Wc_c" ||
- echo 'mkcat/genwhatis.c: original size 15821, current size' "$Wc_c"
- fi
- # ============= mkcat/format.c ==============
- if test -f 'mkcat/format.c' -a X"$1" != X"-c"; then
- echo 'x - skipping mkcat/format.c (File already exists)'
- else
- echo 'x - extracting mkcat/format.c (Text)'
- sed 's/^X//' << 'Purdue' > 'mkcat/format.c' &&
- /*
- X * Copyright 1990 Purdue Research Foundation, West Lafayette, Indiana
- X * 47907. All rights reserved.
- X *
- X * Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
- X *
- X * This software is not subject to any license of the American Telephone
- X * and Telegraph Company or the Regents of the University of California.
- X *
- X * Permission is granted to anyone to use this software for any purpose on
- X * any computer system, and to alter it and redistribute it freely, subject
- X * to the following restrictions:
- X *
- X * 1. Neither the authors nor Purdue University are responsible for any
- X * consequences of the use of this software.
- X *
- X * 2. The origin of this software must not be misrepresented, either by
- X * explicit claim or by omission. Credit to the authors and Purdue
- X * University must appear in documentation and sources.
- X *
- X * 3. Altered versions must be plainly marked as such, and must not be
- X * misrepresented as being the original software.
- X *
- X * 4. This notice may not be removed or altered.
- X */
- X
- /* $Id: format.c,v 3.4 90/10/23 16:43:43 ksb Exp $
- X *
- X * format - make a cat (formatted) page from a man page
- X */
- #include "machine.h"
- X
- #include <stdio.h>
- #include <ctype.h>
- #include <math.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/file.h>
- #include <sys/param.h>
- #include <fcntl.h>
- #if defined(SYSV)
- #include <ndir.h>
- #else
- #include <sys/dir.h>
- #endif
- #include <sys/stat.h>
- X
- #if !defined(MAXPATHLEN)
- #define MAXPATHLEN 1024
- #endif
- X
- #include "main.h"
- #include "pt.h"
- #include "genwhatis.h"
- #include "readman.h"
- #include "scan.h"
- #include "mkcat.h"
- X
- extern FILE *popen();
- extern int errno;
- extern char *sys_errlist[];
- #define strerror(Me) sys_errlist[Me]
- extern char *strrchr(), *strcpy(), *strchr(), *strcat();
- extern char *malloc(), *mktemp();
- X
- #if !defined(F_OK)
- #define F_OK 0
- #endif
- X
- X
- char acRoot[] = /* root of the formatted tree */
- X "/usr/man";
- char acCat[] = /* cat dir basename */
- X "cat";
- char acWhatis[] = /* whatis database to updtae */
- X "whatis";
- char acTemp[] = /* a temp file with some space */
- X "/usr/tmp/mkcatXXXXXX";
- X
- char acDotZ[] = /* compresses extender */
- X ".Z";
- X
- X
- /*
- X * warn of multiple manual pages, one name foo.1l, one foo.1 or (ksb)
- X * some such (only for the name provided)
- X */
- void
- WarnMulti(iSection, ppcBase, pcSection)
- int iSection;
- char **ppcBase, *pcSection;
- {
- X auto char acDir[MAXPATHLEN+1];
- X register DIR *pDIRCat;
- X register struct direct *pEnt;
- X register char *pcFile, **ppcTemp;
- X register char *pcHack;
- X
- X if ('/' == pcCat[0] || ('.' == pcCat[0] && '/' == pcCat[1]))
- X (void)sprintf(acDir, "%s%d", pcCat, iSection);
- X else
- X (void)sprintf(acDir, "%s/%s%d", pcRoot, pcCat, iSection);
- X if ((DIR *)0 == (pDIRCat = opendir(acDir))) {
- X fprintf(stderr, "%s: opendir: %s: %s\n", progname, acDir, strerror(errno));
- X exit(1);
- X }
- X
- X while ((struct direct *)0 != (pEnt = readdir(pDIRCat))) {
- X pcFile = pEnt->d_name;
- X if ((char *)0 == (pcHack = strrchr(pcFile, '.'))) {
- X /* ignore short files... or dirs */
- X continue;
- X }
- X
- X /* ignore compress suffix on installed pages */
- X if (0 == strcmp(acDotZ, pcHack)) {
- X *pcHack = '\000';
- X /* d_namlen is now wrong... do we care? */
- X if ((char *)0 == (pcHack = strrchr(pcFile, '.'))) {
- X continue;
- X }
- X }
- X *pcHack++ = '\000';
- X
- X /* ignore intro pages, `.', and `..'
- X */
- X if ('.' == pcFile[0] && ('\000' == pcFile[1] ||
- X ('.' == pcFile[1] && '\000' == pcFile[2])) ||
- X 0 == IsOKBase(pcFile)) {
- X continue;
- X }
- X
- X /* go through the (sorted!) list of names
- X * quit on match with bad extender, or no more to check
- X * (too bad the directory is not sorted here)
- X */
- X for (ppcTemp = ppcBase; (char *)0 != *ppcTemp; ++ppcTemp) {
- X register int cp;
- X cp = strcmp(pcFile, *ppcTemp);
- X if (0 < cp)
- X continue;
- X if (0 > cp)
- X break;
- X if (ExtConflict(pcHack, pcSection)) {
- X fprintf(fpOut, "%s: %s.%s and %s.%s both live in %s\n", progname, pcFile, pcHack, pcFile, pcSection, acDir);
- X }
- X }
- X }
- X (void)closedir(pDIRCat);
- }
- X
- X
- /*
- X * sort -u, kinda (ksb)
- X */
- uniq(ppcVec, piLen)
- char **ppcVec;
- int *piLen;
- {
- X register char **ppcFrom, **ppcList;
- X
- X ppcList = ppcVec;
- X if ((char *)0 == ppcList[0])
- X return;
- X for (ppcFrom = ppcList+1; (char *)0 != *ppcFrom; ++ppcFrom) {
- X if (0 != strcmp(*ppcFrom, *ppcList))
- X *++ppcList = *ppcFrom;
- X else
- X --*piLen;
- X }
- X ppcList[1] = (char *)0;
- }
- X
- /*
- X * split off the two parts of BAR(1) (ksb)
- X * ^^^ ^
- X * (also handles missformatted bold open parens)
- X */
- int
- SplitHead(pcHeader, ppcOpen)
- char *pcHeader, **ppcOpen;
- {
- X register char *pcTemp, *pcClose, *pcOpen;
- X register int retval = 1;
- X
- X for (pcTemp = pcHeader; '\000' != *pcTemp; ++pcTemp) {
- X if (isupper(*pcTemp)) {
- X *pcTemp = tolower(*pcTemp);
- X }
- X }
- X
- X if ((char *)0 != (pcOpen = strchr(pcHeader, '(') /*)*/)) {
- X while ('\b' == pcOpen[1] && '('/*)*/ == pcOpen[2])
- X pcOpen += 2;
- X *pcOpen++ = '\000';
- X if ((char *)0 != (pcClose = strchr(pcOpen, ')'))) {
- X *pcClose = '\000';
- X } else {
- X retval = 0;
- X }
- X } else {
- X retval = 0;
- X }
- X *ppcOpen = pcOpen;
- X return retval;
- }
- X
- X
- /*
- X * format the given page with the given macro package (ksb)
- X * put it in the named file
- X */
- static int
- MkFmt(pPTPage, pcTemp)
- PATH *pPTPage; /* raw page (in) */
- char *pcTemp; /* temp name to build it in (in) */
- {
- X auto char acCmd[MAXPATHLEN*2+sizeof(acTemp)+400];
- X auto FILE *fpFake;
- X
- #if !defined(R_OK)
- #define R_OK 4
- #endif
- X if (0 != access(PTFull(pPTPage), R_OK)) {
- X fprintf(stderr, "%s: access: %s: %s\n", progname, PTFull(pPTPage), strerror(errno));
- X return 1;
- X }
- X
- X (void)sprintf(acCmd, "MK=\"%s\" mk -m%s %s >%s", fVerbose ? "" : "-s", (char *)0 != pcMkToken ? pcMkToken : "Mkcat", PTFull(pPTPage), pcTemp);
- X
- X if (fVerbose) {
- X fprintf(fpOut, "%s: %s\n", progname, acCmd);
- X }
- X (void)fflush(fpOut);
- X (void)fflush(stderr);
- X
- X if (fExec)
- X return 0 != system(acCmd);
- X
- X if (NULL == (fpFake = fopen(pcTemp, "w"))) {
- X fprintf(stderr, "%s: fopen: %s: %s\n", progname, pcTemp, strerror(errno));
- X return 1;
- X }
- X (void)fprintf(fpFake, "%s(", PTBase(pPTPage));
- X (void)fprintf(fpFake, "%s) Fake man page\n\n%s\n", PTExt(pPTPage), acMark);
- X (void)fprintf(fpFake, "\t%s - a dry run line\n\nfaked for your protection\n", PTBase(pPTPage));
- X (void)fclose(fpFake);
- X return 0;
- }
- X
- /*
- X * update an installed manual page, remove the old one and install new (ksb)
- X *
- X * format it, all whatis lines to DEL or ADD list
- X * install the page
- X * remove or build links
- X * let caller update whatis as a group
- X *
- X * #1 why we remove an old page, if we replace all its links
- X * in this case we have an old page called `OLD(1)' which
- X * has a NAME section `old, new, other - things'. The new page
- X * has changed the names around (it happens) to call the page
- X * `NEW(1)' with a NAME section `new, old, other -- things' or
- X * we have added a new name `BETTER(1)' and kept all the old NAMES
- X * ... in all cases we can remove the old page becasue we superceed
- X * it!
- X * If we do not cover *all* the old links we tell the user to run
- X * rmcat on the `base' manual page or remove the collisions.
- X * An example? cd(1) and sh(1). If you run mkcat on cd(1) it will
- X * tell you to remove sh(1) or remove the name `cd' in sh(1)!
- X * *** As it should! ***
- X */
- int
- ModFmt(pPTPage, pWU, pWUDel)
- PATH *pPTPage;
- WHATIS *pWU, *pWUDel;
- {
- X auto FILE *fpFmt;
- X auto char acDest[MAXPATHLEN+1];
- X auto char acTName[sizeof(acTemp)+sizeof(acDotZ)+1];
- X auto char acCmd[MAXPATHLEN+sizeof(acTemp)+1000+400];
- X auto int fWasThere;
- X auto PATH PTDel;
- X auto struct stat stDest;
- X
- X if (! PTHasExt(pPTPage)) {
- X fprintf(fpOut, "%s: `%s\' no manual section extender\n", progname, PTFull(pPTPage));
- X return 1;
- X }
- X
- X if (! isdigit(*PTExt(pPTPage)) && 0 != strcasecmp("man", PTExt(pPTPage))) {
- X fprintf(stderr, "%s: `%s\' missing section number in extender\n", progname, PTFull(pPTPage));
- X return 1;
- X }
- X
- X
- X /* make a formatted page in a temp space and read the link info
- X */
- X (void)strcpy(acTName, acTemp);
- X if ((char *)0 == mktemp(acTName)) {
- X return 1;
- X }
- X if (fFormat) {
- X /* MkFmt will fake a formatted copy if we are running under
- X * -n, clever, eh?
- X */
- X if (0 != MkFmt(pPTPage, acTName)) {
- X return 1;
- X }
- X } else {
- X if (PTIsComp(pPTPage)) {
- X (void)sprintf(acCmd, "zcat %s >%s", PTFull(pPTPage), acTName);
- X } else {
- X (void)sprintf(acCmd, "cp %s %s", PTFull(pPTPage), acTName);
- X }
- X if (fVerbose) {
- X (void)printf("%s: %s\n", progname, acCmd);
- X }
- X if (0 != system(acCmd)) {
- X fprintf(stderr, "%s: cp failed\n", progname);
- X return 1;
- X }
- X }
- X if (NULL == (fpFmt = fopen(acTName, "r"))) {
- X fprintf(stderr, "%s: fopen: %s: %s\n", progname, PTFull(pPTPage), strerror(errno));
- X return 1;
- X }
- X if (0 != WUGrok(fpFmt, pPTPage, pWU)) {
- X (void)fclose(fpFmt);
- X return 1;
- X }
- X (void)fclose(fpFmt);
- X
- X if (0 != strcmp(pWU->pcbase, PTBase(pPTPage))) {
- X fprintf(fpOut, "%s: `%s\' should be named `%s.%s\' (repaired)\n", progname, PTFull(pPTPage), pWU->pcbase, pWU->pcext);
- X }
- X
- X if ('/' == pcCat[0] || ('.' == pcCat[0] && '/' == pcCat[1])) {
- X (void)sprintf(acDest, "%s%d/%s.%s%s", pcCat, pWU->isection, pWU->pcbase, pWU->pcext, fCompress ? acDotZ : "");
- X } else {
- X (void)sprintf(acDest, "%s/%s%d/%s.%s%s", pcRoot, pcCat, pWU->isection, pWU->pcbase, pWU->pcext, fCompress ? acDotZ : "");
- X }
- X PTInit(&PTDel, acDest);
- X
- X /* if an old one exists read it for links
- X * (no error if there is not one, might be a new file)
- X */
- X pWUDel->ilen = 0;
- X fWasThere = (-1 != LSTAT(acDest, &stDest));
- X if (fWasThere) {
- X register int r = 0;
- X if (PTIsComp(&PTDel)) {
- X (void)sprintf(acCmd, "exec zcat %s", acDest);
- X if (NULL != (fpFmt = popen(acCmd, "r"))) {
- X r = WUGrok(fpFmt, &PTDel, pWUDel);
- X }
- X (void)pclose(fpFmt);
- X } else {
- X if (NULL != (fpFmt = fopen(acDest, "r"))) {
- X r = WUGrok(fpFmt, &PTDel, pWUDel);
- X }
- X (void)fclose(fpFmt);
- X }
- X if (0 != r) {
- X printf("%s: %s: don\'t grok old man page\n", progname, acDest);
- X fWasThere = 0;
- X }
- X }
- X if (fDelete && !fWasThere) {
- X /* no page to remove, fail */
- X return 1;
- X }
- X
- X (void)sprintf(acCmd, "INSTALL=\"%s\" install%s", fVerbose ? "-v" : "", fDelete ? " -R" : "");
- X if ((char *)0 != apcModes[PAGEOWNER]) {
- X (void)strcat(acCmd, " -o");
- X (void)strcat(acCmd, apcModes[PAGEOWNER]);
- X }
- X if ((char *)0 != apcModes[PAGEGROUP]) {
- X (void)strcat(acCmd, " -g");
- X (void)strcat(acCmd, apcModes[PAGEGROUP]);
- X }
- X if ((char *)0 != apcModes[PAGEMODE]) {
- X (void)strcat(acCmd, " -m");
- X (void)strcat(acCmd, apcModes[PAGEMODE]);
- X }
- X
- X if (fDelete) {
- X if (0 != strcmp(pWUDel->pcbase, pWU->pcbase) || 0 != strcmp(pWUDel->pcext, pWU->pcext)) {
- X (void)printf("%s: `%s.%s\' doesn't match `%s.%s\'\n", progname, pWU->pcbase, pWU->pcext, pWUDel->pcbase, pWUDel->pcext);
- X (void)printf("%s: use `%s -Dv -f %s\' to remove page\n", progname, progname, acDest);
- X return 1;
- X }
- X ModLinks(&PTDel, pWUDel, (struct direct **)0, 0, &stDest, 1);
- X (void)WUStrike(pWU, pWUDel);
- X } else {
- X if (-1 == access(PTDir(&PTDel), F_OK)) {
- X MakeDir(PTDir(&PTDel), DIROWNER, DIRGROUP, DIRMODE);
- X }
- X /* remove common links from pWUDel, remove non-common
- X * from catdirs (links are not common if extender is
- X * different!)
- X */
- X if (fWasThere && 0 == strcmp(pWUDel->pcbase, pWU->pcbase)) {
- X if (0 == strcmp(pWUDel->pcext, pWU->pcext)) {
- X (void)WUStrike(pWUDel, pWU);
- X }
- X switch (stDest.st_mode & S_IFMT) {
- X case S_IFREG:
- X ModLinks(&PTDel, pWUDel, (struct direct **)0, 0, &stDest, 1);
- X break;
- #if HAVE_SLINKS
- X case S_IFLNK:
- X fprintf(stderr, "%s: run -L before installing `%s\'\n", progname, acDest);
- X return 1;
- #endif
- X default:
- X fprintf(stderr, "%s: %s: not a plain file or link\n", progname, acDest);
- X break;
- X }
- X }
- X
- X WarnMulti(pWU->isection, pWU->ppclist, pWU->pcext);
- X
- X /* compress the temp file if it needs it
- X */
- X if (fCompress) {
- X auto char acDoComp[MAXPATHLEN+100];
- X (void)sprintf(acDoComp, "exec compress -f %s", acTName);
- X if (0 != system(acDoComp)) {
- X fprintf(stderr, "%s: system: `%s\' failed\n", progname, acDoComp);
- X return 1;
- X }
- X if (-1 == access(acTName, F_OK)) {
- X (void)strcat(acTName, acDotZ);
- X if (-1 == access(acTName, R_OK)) {
- X fprintf(stderr, "%s: compress lost my file, `%s\'\n", progname, acTName);
- X return 1;
- X }
- X }
- X }
- X
- X (void)strcat(acCmd, " ");
- X (void)strcat(acCmd, acTName);
- X }
- X
- X (void)strcat(acCmd, " ");
- X (void)strcat(acCmd, acDest);
- X
- X if (fVerbose) {
- X fprintf(fpOut, "%s: %s\n", progname, acCmd);
- X }
- X (void)fflush(stdout);
- X if (fExec && 0 != system(acCmd)) {
- X return 1;
- X }
- X
- X /* now we have to put in the new links if needed
- X */
- X if (!fDelete) {
- X ModLinks(&PTDel, pWU, (struct direct **)0, 0, fWasThere ? &stDest : (struct stat *)0, 0);
- X }
- X
- X /* install removed the temp file for us (unless the user set -c)
- X * in any event we try to unlink it, just in case install bombed
- X */
- X if (fVerbose) {
- X printf("%s: rm -f %s\n", progname, acTName);
- X }
- X (void)unlink(acTName);
- X
- X return 0;
- }
- Purdue
- chmod 0444 mkcat/format.c ||
- echo 'restore of mkcat/format.c failed'
- Wc_c="`wc -c < 'mkcat/format.c'`"
- test 12839 -eq "$Wc_c" ||
- echo 'mkcat/format.c: original size 12839, current size' "$Wc_c"
- fi
- # ============= mk/setenv.c ==============
- if test ! -d 'mk'; then
- echo 'x - creating directory mk'
- mkdir 'mk'
- fi
- if test -f 'mk/setenv.c' -a X"$1" != X"-c"; then
- echo 'x - skipping mk/setenv.c (File already exists)'
- else
- echo 'x - extracting mk/setenv.c (Text)'
- sed 's/^X//' << 'Purdue' > 'mk/setenv.c' &&
- #include <stdio.h>
- #include "machine.h"
- X
- #define nil ((char *)0)
- extern char *strcpy(), *strcat();
- X
- /*
- X * set an environment variable (ksb)
- X * for unsetenv call with pchValue set to nil
- X *
- X * This routine modifies the global "environ" and will
- X * build a new list if it must grow (it doesn't free the old one
- X * since it may not have been malloc'd) It will overwrite the
- X * old value if the new one will fit, else is mallocs one large enough.
- X *
- X * returns nothing (an int)
- X */
- int
- setenv(pchName, pchValue)
- char *pchName, *pchValue;
- {
- X extern char **environ, *calloc(), *malloc();
- X extern int strlen();
- X register char **ppch, *pch;
- X register int len, nv;
- X
- X nv = 0;
- X len = strlen(pchName);
- X for (ppch = environ; nil != (pch = *ppch); ++ppch) {
- X if (0 == strncmp(pch, pchName, len) && '=' == pch[len]) {
- X break;
- X }
- X ++nv;
- X }
- X
- X if (nil == pchValue) {
- X if (nil == pch) {
- X return ;
- X }
- X while (nil != (ppch[0] = ppch[1])) {
- X ++ppch;
- X }
- X return ;
- X }
- X
- X if (nil == pch) {
- X ++nv;
- X ppch = (char **)calloc(nv+1, sizeof(char *));
- X while (nv) {
- X --nv;
- X ppch[nv+1] = environ[nv];
- X }
- X environ = ppch;
- X }
- X
- X len += strlen(pchValue) + 1;
- X if (nil == pch || strlen(pch) < len)
- X pch = malloc(len+1);
- X strcpy(pch, pchName);
- X strcat(pch, "=");
- X strcat(pch, pchValue);
- X *ppch = pch;
- }
- Purdue
- chmod 0444 mk/setenv.c ||
- echo 'restore of mk/setenv.c failed'
- Wc_c="`wc -c < 'mk/setenv.c'`"
- test 1292 -eq "$Wc_c" ||
- echo 'mk/setenv.c: original size 1292, current size' "$Wc_c"
- fi
- # ============= mk-lib/m-clean ==============
- if test ! -d 'mk-lib'; then
- echo 'x - creating directory mk-lib'
- mkdir 'mk-lib'
- fi
- if test -f 'mk-lib/m-clean' -a X"$1" != X"-c"; then
- echo 'x - skipping mk-lib/m-clean (File already exists)'
- else
- echo 'x - extracting mk-lib/m-clean (Text)'
- sed 's/^X//' << 'Purdue' > 'mk-lib/m-clean' &&
- # the Clean target removes the junk generated by the other targets (ksb)
- X
- $Clean(*): ${rm-rm} -f %P.o
- $Clean(*): ${rm-rm} -f %P
- $Clean(*): ${make-make} %s clean
- $Clean(*): ${make-make} clean
- Purdue
- chmod 0444 mk-lib/m-clean ||
- echo 'restore of mk-lib/m-clean failed'
- Wc_c="`wc -c < 'mk-lib/m-clean'`"
- test 191 -eq "$Wc_c" ||
- echo 'mk-lib/m-clean: original size 191, current size' "$Wc_c"
- fi
- # ============= mkcat/readman.c ==============
- if test -f 'mkcat/readman.c' -a X"$1" != X"-c"; then
- echo 'x - skipping mkcat/readman.c (File already exists)'
- else
- echo 'x - extracting mkcat/readman.c (Text)'
- sed 's/^X//' << 'Purdue' > 'mkcat/readman.c' &&
- /*
- X * $Id: readman.c,v 3.4 90/11/28 09:44:05 ksb Exp $
- X *
- X * Copyright 1990 Purdue Research Foundation, West Lafayette, Indiana
- X * 47907. All rights reserved.
- X *
- X * Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
- X *
- X * This software is not subject to any license of the American Telephone
- X * and Telegraph Company or the Regents of the University of California.
- X *
- X * Permission is granted to anyone to use this software for any purpose on
- X * any computer system, and to alter it and redistribute it freely, subject
- X * to the following restrictions:
- X *
- X * 1. Neither the authors nor Purdue University are responsible for any
- X * consequences of the use of this software.
- X *
- X * 2. The origin of this software must not be misrepresented, either by
- X * explicit claim or by omission. Credit to the authors and Purdue
- X * University must appear in documentation and sources.
- X *
- X * 3. Altered versions must be plainly marked as such, and must not be
- X * misrepresented as being the original software.
- X *
- X * 4. This notice may not be removed or altered.
- X */
- X
- /*
- X * routines to read a manual page and extract useful facts (ksb)
- X * $Compile: ${cc-cc} ${cc_debug--g} -DTEST %f -o %F
- X */
- #include "machine.h"
- #include <stdio.h>
- #include <ctype.h>
- X
- #include "main.h"
- #include "readman.h"
- #include "mkcat.h"
- X
- extern char *malloc(), *realloc(), *calloc(), *strrchr();
- extern char *strcat(), *strcpy();
- extern int strlen(), errno;
- extern char *sys_errlist[];
- #define strerror(Me) (sys_errlist[Me])
- X
- static char *apcFmts[] = {
- X "normal",
- X "bold",
- X "underline",
- X "bold & underlined",
- X "overstruck",
- X "bold & overstruck",
- X "underline & overstruck",
- X "bold & underlined & overstruck",
- X (char *)0
- };
- X
- char acMark[] = /* the line following this mark */
- X "NAME";
- char acAlso[] = /* the pages we refer to follow this line */
- X "SEE ALSO";
- char acNoMem[] = /* message for out of mem */
- X "%s: out of memory\n";
- X
- # if 0
- /* someday this will tell the user about unknown section names
- X */
- static char *apcHeaders[] = {
- X "AUTHOR",
- X "AUTHORS",
- X "AVAILABILITY",
- X "BUGS",
- X "CAVEATS",
- X "COMMANDS",
- X "COPYRIGHT",
- X "DESCRIPTION",
- X "DIAGNOSTICS",
- X "ENVIRONMENT",
- X "ENVIRONMENT VARIABLES",
- X "EXAMPLES",
- X "EXIT CODES",
- X "FILES",
- X "FUNCTIONS",
- X "HINTS",
- X "INITIALIZATION",
- X "LIMITATIONS",
- X "NAME",
- X "NOTES",
- X "OPTIONS",
- X "RETURN VALUES",
- X "ROUTINES",
- X "SEE ALSO",
- X "SUMMARY",
- X "SYNOPSIS",
- X "USAGE",
- X "VARIABLES",
- X (char *)0
- };
- #endif
- X
- /*
- X * save a string in malloced memory (ksb)
- X */
- char *
- strsave(pc)
- char *pc;
- {
- X register char *pcRet;
- X
- X if ((char *)0 == (pcRet = malloc((unsigned)strlen(pc)+1))) {
- X fprintf(stderr, acNoMem, progname);
- X exit(1);
- X }
- X return strcpy(pcRet, pc);
- }
- X
- /*
- X * strip nroff nonsense of a string (ksb)
- X */
- int
- StripFmt(pcBuf)
- char *pcBuf;
- {
- X register int fmt = FMT_NORMAL;
- X register char *pcScan;
- X
- X for (pcScan = pcBuf; '\000' != *pcScan; ++pcScan) {
- X if ('\b' == pcScan[1]) {
- X if ('_' == pcScan[0]) {
- X fmt |= FMT_UNDERLINE;
- X } else if (pcScan[0] == pcScan[2]) {
- X fmt |= FMT_BOLD;
- X } else {
- X fmt |= FMT_OVERSTRIKE;
- X }
- X ++pcScan;
- X continue;
- X }
- X *pcBuf++ = *pcScan;
- X }
- X *pcBuf = '\000';
- X return fmt;
- }
- X
- /*
- X * compare a mark and a word which might be bold or something (ksb)
- X */
- static int
- markcmp(pcLine, pcMark, mLen)
- char *pcLine, *pcMark;
- int mLen;
- {
- X register int i;
- X
- X for (i = 0; i < mLen; ++i) {
- X while ('\000' != pcLine[0] && '\b' == pcLine[1]) {
- X pcLine += 2;
- X }
- X if (*pcLine != *pcMark)
- X return *pcLine - *pcMark;
- X ++pcLine, ++pcMark;
- X }
- X return 0;
- }
- X
- /*
- X * Build the names of the symbolic links the (soon to be installed) (ksb)
- X * manual page.
- X * *we must* leave LN_PAD (char *)0's on the end of the vector
- X * (one will be replaced be the basename before we sort -u them)
- X * We will also find the header name:
- X * MKCAT(8) .... ....
- X * ^^^^^^^^
- X * and save it, if pcHeader points to a buffer of about BUFSIZ.
- X */
- int
- rdlinks(fpFmt, pcSrc, pppcVec, piLen, ppcAlso, pcHeader)
- register FILE
- X *fpFmt; /* input file to read */
- char *pcSrc, /* name to call it (for user) */
- X ***pppcVec, /* place to store list of names */
- X **ppcAlso, /* place to put see alsos */
- X *pcHeader; /* place to store header name */
- int *piLen; /* number of links */
- {
- X auto char *pcBuf, *pcAlsoLine;
- X register char *pcLine, *pcNewLine, **ppcLinks, **ppcMode;
- X register int i;
- X register char ch;
- #define MODE_HEADER 0
- #define MODE_SCAN 1
- #define MODE_LINK 2
- #define MODE_LINK2 3
- #define MODE_BODY 4
- #define MODE_ALSO 5
- #define MISSING_PAREN 1
- X auto int iLen, iMode, iMissing, fHasDash;
- X auto char acLine[BUFSIZ];
- X extern char *strchr();
- X
- X pcBuf = (char *)0;
- X pcAlsoLine = (char *)0;
- X iMode = MODE_HEADER;
- X iMissing = 0;
- X while ((char *)0 != (pcLine = fgets(acLine, BUFSIZ, fpFmt))) {
- X while (isspace(*pcLine) && '\000' != *pcLine) {
- X ++pcLine;
- X }
- #if 0
- X printf("%s: %s", MODE_HEADER == iMode ? "header" : MODE_SCAN == iMode ? "scanner" : "links" , pcLine);
- #endif
- X if (MODE_HEADER == iMode) {
- X register char *pcClose;
- X
- X if ((char *)0 == (pcClose = strchr(pcLine, /*(*/')'))) {
- X if (0 == markcmp(pcLine, acMark, sizeof(acMark)-1)) {
- X (void)fprintf(fpOut, "%s: %s: bad header line or %s line before header\n", progname, pcSrc, acMark);
- X return 1;
- X }
- X if (strlen(pcLine) > 2) {
- X iMissing |= MISSING_PAREN;
- X }
- X continue;
- X }
- X *++pcClose = '\000';
- X if ((char *)0 != pcHeader) {
- X (void)strcpy(pcHeader, pcLine);
- X }
- X iMode = MODE_SCAN;
- X continue;
- X }
- X if (MODE_SCAN == iMode) {
- X if (0 == markcmp(pcLine, acMark, sizeof(acMark)-1)) {
- X iMode = MODE_LINK;
- X ppcMode = &pcBuf;
- X }
- X continue;
- X }
- X if (MODE_BODY == iMode) {
- X if (0 == markcmp(pcLine, acAlso, sizeof(acAlso)-1)) {
- X iMode = MODE_ALSO;
- X ppcMode = &pcAlsoLine;
- X }
- X continue;
- X }
- X if ((char *)0 != (pcNewLine = strrchr(pcLine, '\n'))) {
- X do {
- X *pcNewLine = '\000';
- X } while (pcNewLine != pcLine && (--pcNewLine, isspace(*pcNewLine)));
- X }
- X if ('\000' == *pcLine) {
- X if (MODE_ALSO == iMode || (char **)0 == ppcAlso)
- X break;
- X iMode = MODE_BODY;
- X continue;
- X }
- X
- X /* does the input line have the magic dash?
- X */
- X if (MODE_ALSO != iMode) {
- X register char *pcHack;
- X
- X pcHack = pcLine;
- X while ((char *)0 != (pcHack = strchr(pcHack, '-'))) {
- X if ((pcHack == pcLine || isspace(pcHack[-1])) &&
- X ('\000' == pcHack[1] || isspace(pcHack[1]))) {
- X break;
- X }
- X ++pcHack;
- X }
- X fHasDash = ((char *)0 != pcHack);
- X } else {
- X fHasDash = 0;
- X }
- X if ((char *)0 == (*ppcMode)) {
- X iLen = strlen(pcLine)+1;
- X (*ppcMode) = malloc((unsigned)iLen+1);
- X if ((char *)0 == (*ppcMode)) {
- X fprintf(stderr, acNoMem, progname);
- X exit(1);
- X }
- X (void)strcpy((*ppcMode), pcLine);
- X } else {
- X register int temp;
- X
- X if (MODE_LINK2 == iMode && fHasDash) {
- X fprintf(fpOut, "%s: %s: too many whatis entries at `%s\'\n", progname, pcSrc, pcLine);
- X break;
- X }
- X temp = strlen(pcLine)+1; /* put in a space */
- X (*ppcMode) = realloc((char *)(*ppcMode), (unsigned) iLen+temp+8);
- X if ((char *)0 == (*ppcMode)) {
- X fprintf(stderr, acNoMem, progname);
- X exit(1);
- X }
- X /* join lines that are hyphenated
- X * we know iLen is >2 we assume it is >>2
- X */
- X if ('-' == (*ppcMode)[iLen-2] && !isspace((*ppcMode)[iLen-3])) {
- X --iLen, --temp;
- X (void)strcpy(& (*ppcMode)[iLen-1], pcLine);
- X } else {
- X (*ppcMode)[iLen-1] = ' ';
- X (void)strcpy(& (*ppcMode)[iLen], pcLine);
- X }
- X iLen += temp;
- X }
- X if (fHasDash) {
- X iMode = MODE_LINK2;
- X }
- X }
- X
- X if ((char *)0 == pcBuf) {
- X if (iMissing & MISSING_PAREN) {
- X (void)fprintf(fpOut, "%s: %s: header line missing parenthesis?\n", progname, pcSrc);
- X } else {
- X fprintf(fpOut, "%s: `%s\' has no %s line\n", progname, pcSrc, acMark);
- X }
- X return 1;
- X }
- X
- X /* here we have something like "foo, bar, wham - meta words"
- X * we need to build a vector "foo", "bar", "wham", "meta words"
- X */
- X ch = '^';
- X iLen = 0;
- X for (pcLine = pcBuf; '\000' != *pcLine; ++pcLine) {
- X if (isspace(ch) && '-' == pcLine[0] && isspace(pcLine[1])) {
- X ++iLen;
- X break;
- X }
- X if (',' == *pcLine || (0 == iLen && ':' == *pcLine)) {
- X ++iLen;
- X }
- X ch = *pcLine;
- X }
- X if ('\000' == *pcLine || 0 == iLen) {
- X if ((char *)0 != pcBuf)
- X (void) free(pcBuf);
- X fprintf(fpOut, "%s: `%s\' has a bad %s line (too short)?\n", progname, pcSrc, acMark);
- X return 1;
- X }
- X ++iLen;
- X ppcLinks = (char **)calloc((unsigned) iLen+LN_PAD, sizeof(char *));
- X if ((char **)0 == ppcLinks) {
- X fprintf(stderr, acNoMem, progname);
- X exit(1);
- X }
- X iLen = 1;
- X ppcLinks[0] = pcBuf;
- X ch = '^';
- X for (pcLine = pcBuf; '\000' != *pcLine; ++pcLine) {
- X if (! (isspace(ch) && '-' == pcLine[0] && isspace(pcLine[1])) &&
- X ',' != *pcLine && !(iLen == 1 && ':' == *pcLine)) {
- X ch = *pcLine;
- X continue;
- X }
- X ch = *pcLine;
- X pcNewLine = pcLine;
- X while (pcNewLine > pcBuf && (--pcNewLine, isspace(*pcNewLine)))
- X *pcNewLine = '\000';
- X do {
- X *pcLine++ = '\000';
- X } while (isspace(*pcLine));
- X ppcLinks[iLen++] = pcLine;
- X if ('-' == ch) {
- X break;
- X }
- X }
- X
- X /* search links for poor names, and warn.
- X */
- X for (i = 0; i < iLen-1; ++i) {
- X register char *pcTemp;
- X register int fmt;
- X
- X pcTemp = ppcLinks[i];
- X fmt = StripFmt(pcTemp);
- X if (FMT_NORMAL != fmt) {
- X fprintf(fpOut, "%s: link `%s\' should not be %s\n", progname, pcTemp, apcFmts[fmt]);
- X }
- X while ('\000' != *pcTemp && !isspace(*pcTemp)) {
- X ++pcTemp;
- X }
- X if ('\000' != *pcTemp) {
- X register int j;
- X fprintf(fpOut, "%s: warning link `%s\' has a space in it (skipped)\n", progname, ppcLinks[i]);
- X --iLen;
- X for (j = i; j < iLen; ++j)
- X ppcLinks[j] = ppcLinks[j+1];
- X --i;
- X continue;
- X }
- X while ((char *)0 != (pcTemp = strrchr(ppcLinks[i], '/'))) {
- X /* eat trailing slash, paranoid */
- X if ('\000' == pcTemp[1]) {
- X *pcTemp = '\000';
- X continue;
- X }
- X ++pcTemp;
- X fprintf(fpOut, "%s: link `%s\' has a `/\' in it, changed to `%s\'\n", progname, ppcLinks[i], pcTemp);
- X ppcLinks[i] = pcTemp;
- X break;
- X }
- X }
- X
- X (void)StripFmt(ppcLinks[iLen-1]);
- X ch = '^';
- X for (pcLine = pcBuf = ppcLinks[iLen-1]; '\000' != *pcLine; ++pcLine) {
- X if (isspace(*pcLine)) {
- X ch = ' ';
- X continue;
- X }
- X if (' ' == ch) {
- X *pcBuf++ = ' ';
- X ch = 'W';
- X }
- X *pcBuf++ = *pcLine;
- X }
- X *pcBuf = '\000';
- X
- X ppcLinks[iLen] = (char *)0;
- X ppcLinks[iLen+1] = (char *)0;
- X *pppcVec = ppcLinks;
- X *piLen = iLen;
- X if ((char **)0 != ppcAlso) {
- X *ppcAlso = pcAlsoLine;
- X }
- X return 0;
- }
- X
- #if TEST
- char *progname = "test";
- X
- int
- main(argc, argv)
- int argc;
- char **argv;
- {
- X register int i, j;
- X auto int iCnt, iFailed;
- X auto char **ppcLinks, acHeader[1000], *pcAlso;
- X auto FILE *fpIn;
- X
- X for (iFailed = 0, i = 1; i < argc; ++i) {
- X if ('-' == argv[i][0] && '\000' == argv[i][1]) {
- X fpIn = stdin;
- X } else if (NULL == (fpIn = fopen(argv[i], "r"))) {
- X fprintf(stderr, "%s: fopen: %s: %s\n", progname, argv[i], strerror(errno));
- X ++iFailed;
- X continue;
- X }
- X if (rdlinks(fpIn, argv[i], &ppcLinks, &iCnt, &pcAlso, acHeader)) {
- X printf("rdlinks fails for %s\n", argv[i]);
- X (void)fclose(fpIn);
- X ++iFailed;
- X continue;
- X }
- X if (fpIn == stdin)
- X clearerr(stdin);
- X else
- X (void)fclose(fpIn);
- X (void)printf("page %s: header `%s\', links %d\n", argv[i], acHeader, iCnt);
- X (void)printf("summary: `%s\'\n", ppcLinks[--iCnt]);
- X for (j = 0; j < iCnt; ++j) {
- X (void)printf("\t`%s\'\n", ppcLinks[j]);
- X }
- X if ((char *)0 != pcAlso) {
- X printf("see also:\n\t%s\n", pcAlso);
- X }
- X }
- X exit(iFailed);
- }
- #endif
- Purdue
- chmod 0444 mkcat/readman.c ||
- echo 'restore of mkcat/readman.c failed'
- Wc_c="`wc -c < 'mkcat/readman.c'`"
- test 11371 -eq "$Wc_c" ||
- echo 'mkcat/readman.c: original size 11371, current size' "$Wc_c"
- fi
- # ============= mk/mk.1l ==============
- if test -f 'mk/mk.1l' -a X"$1" != X"-c"; then
- echo 'x - skipping mk/mk.1l (File already exists)'
- else
- echo 'x - extracting mk/mk.1l (Text)'
- sed 's/^X//' << 'Purdue' > 'mk/mk.1l' &&
- .TH MK 1L LOCAL
- .SH NAME
- mk \- detect and execute shell commands in files
- .SH SYNOPSIS
- .B mk
- [
- .B \-AVachinsv
- ] [
- .BI \-D defn
- ] [
- .BI \-U undef
- ] [
- .BI \-d submarker
- ] [
- .BI \-e template
- ] [
- .BI \-l lines
- ] [
- .BI \-m marker
- ] [
- .BI \-t templates
- ] [
- .I file
- ]
- .SH DESCRIPTION
- .I Mk
- is a utility for detecting and executing shell commands within files.
- It searches through the first
- .I \fIlines\fP
- (default 99) of named files,
- looking for a \fImarker\fP (default \*(lqCompile\*(rq).
- When the marker is located, the portion of the line on which it appears,
- after the colon and up to a NEWLINE (or an occurrence of two sequential
- unescaped dollar signs (``$$'')), is executed by issuing it to
- .IR sh (1).
- .PP
- Normally, when the named files contain source language statements,
- the commands are contained in lines that appear as comments to
- the language processor.
- This is merely a convention, however, and is not a
- .I mk
- requirement.
- .PP
- .I Mk
- depends on the shell to do general parameter and
- variable expansion.
- However,
- .I mk
- does do some
- .IR printf (3)\-like
- string substitution.
- These substitutions produce the file name in alternate forms.
- The unlisted upper case letters below (DPQUX) each produce
- the same expansion as the lower case version, but abort the
- expansion if the string would be empty.
- They begin with a percent sign (`%'):
- .sp \n()Pu
- .RS
- .TS
- l l.
- %f the full name of the \fIfile\fP specified on the \fImk\fP command line
- %r the RCS revision file for the specified \fIfile\fP
- %d the directory part of the specified \fIfile\fP
- %p the prefix portion of the specified \fIfile\fP
- %q\fIc\fP the prefix portion of \fIfile\fP upto \fIc\fP
- %u\fIc\fP the extension on \fIfile\fP after \fIc\fP
- %x the extension on the specified \fIfile\fP, if any
- %y the file type (f,d,b,c,l,s,p) as in \fIfind\fP(1)
- %F the base name of the \fIfile\fP, no prefix
- %R the RCS revision \fIfile\fP for the base name for the specified file
- %Y\fIc\fP the file type of \fIfile\fP must be \fIc\fP or abort
- %~ the root of the default templates directory
- %% a literal percent sign
- .TE
- .RE
- .PP
- The values of \fImk\fP's command line options may be substituted, using
- percent escapes.
- Each of the options, \-\fBa\fP/\fBA\fP, \-\fBc\fP, \-\fBi\fP, \-\fBn\fP and
- \-\fBv\fP/\fBs\fP, may be substituted via a percent escape that begins with the
- option letter \- e. g., ``%c'' expands to ``\-c'' only if the \-\fBc\fP option
- was specified in the call to \fImk\fP.
- The upper case forms of these options suppress the leading dash.
- Other command line parameters are available as listed below.
- .sp \n()Pu
- .RS
- .TS
- l l.
- %b the full path with which \fImk\fP was invoked
- %e expands to the ``\-e \fItemplate\fP'' option, if given
- %l expands to ``\-l \fIlines\fP'', if one was given
- %m the \fImarker\fP we are searching for
- %o the single letter switches supplied to \fImk\fP
- %s the \fIsubmarker\fP we are searching for
- %t expands to the ``\-t \fItemplates\fP'' option, if given
- %B the last component of the path with which \fImk\fP was invoked
- %E expands to the \fItemplate\fP option, if given
- %L expands to the \fIlines\fP option, if given
- %M the \fImarker\fP we are searching for in lower case
- %O the single letter switches supplied to \fImk\fP, no leading dash
- %S the \fIsubmarker\fP we are searching for in lower case
- %T expands to the \fItemplates\fP option, if given
- .TE
- .RE
- .PP
- If a percent escape fails to find the indicated data \- e. g., no
- .I submarker
- was specified \- it will silently cause the marked line being expanded to be
- rejected.
- .PP
- All C\-like backslash (`\e') escape sequences are substituted.
- These substitutions accommodate commands that require characters some
- language processors might not allow in comments.
- .PP
- .I Mk
- will also allow a resource limit to be set for each directive.
- Here are the resources that can be limited:
- .sp \n()Pu
- .RS
- .TS
- l l l.
- Resource Description Warning Signal
- _
- clock wall clock seconds (done by \fImk\fP itself) SIGALRM
- core core dump size in bytes no warning signal
- cpu number of CPU seconds SIGXCPU
- data data size in bytes no warning signal
- fsize file size of any output file in bytes SIGXFSZ
- rss resident pages in bytes no warning signal
- stack stack size in bytes SIGSEGV
- .TE
- .RE
- .PP
- These resources may be specified after the complete marker and submarker.
- They are separated by commas from each other and the marker/submarker.
- Two values may follow each resource name, separated from the
- name by an equal sign (`=') \- a warning \fIlimit\fP and
- an absolute \fImaximum\fP.
- The
- .I limit
- and
- .I maximum
- must be separated by a slash (`/').
- If only one value is specified, it is considered to be both the
- .I limit
- and the \fImaximum\fP.
- .PP
- When the directive's process reaches the \fIlimit\fP, it is
- sent the indicated warning signal.
- When the process reaches the \fImaximum\fP, it is sent a SIGKILL
- signal.
- When the
- .I clock
- values are the same,
- .I mk
- waits two seconds before sending the SIGKILL.
- .PP
- For example,
- .sp \n()Pu
- .RS
- C $Run,cpu=300/360,core=0: %F 1 1000
- .RE
- .sp \n()Pu
- would send to
- .I sh
- for execution (that's the meaning of the ``Run'' marker) the base name of
- the file (effected with the ``%F'' substitution).
- The base name executable would be supplied with the arguments ``1 1000''.
- The CPU time limit would be 300 and the CPU time maximum, 360.
- The maximum core dump size would be 0 bytes.
- .PP
- The exit status of the
- .I mk
- command is the count of the number of directives that exited non\-zero.
- If a command is known (or intended) to fail then the expected exit code,
- preceded by an equal sign (`='), may be specified after its marker
- (``Fail'' in the following example).
- .sp \n()Pu
- .RS
- # $Fail=1: %F "bad args"
- .RE
- .sp \n()Pu
- When an exit code is specified, any other exit code will be treated
- as a failure.
- The special exit code `*' can be used to force
- a command to always exit successfully.
- Any exit code except the specified one will be considered a successful exit
- if the specified code is prefixed with a tilde (`~').
- In the following example, any nonzero exit code that ``%F'' issues will cause
- .I mk
- to issue a zero code:
- .sp \n()Pu
- .RS
- # $NonZero=~0: %F "nonzero args"
- .RE
- .sp \n()Pu
- .PP
- The full form of an
- .I mk
- directive is
- .sp \n()Pu
- .RS
- \fB$\fP \fImarker\fP[\fB(\fP\fIsubmarker\fP\fB)\fP] [\fB=\fP[\fB~\fP]\fIexit\-status\fP] [\fB,\fP\fIresource\fP\fB=\fP[\fIlimit\fP][\fB/\fP\fImaximum\fP]] \fB:\fP \fIcommand\fP [ \fB$$\fP ]
- .RE
- .sp \n()Pu
- where the
- .I resource
- may be repeated to name and set multiple resource limits.
- .PP
- If no
- .I marker
- line can be found in the first \fIlines\fP (default 99)
- of the file, a standard template file name is formed using the
- \fB\-t\fItemplates\fR arguments.
- The
- .I templates
- string is subjected to \fImk\fP's file name substitutions (see above).
- .I Mk
- then searches the file whose name emerges from that substitution for
- \fImarkers\fP.
- The special marker ``*'' matches, and is a match for, any marker
- or submarker.
- .SH OPTIONS
- Note that options and arguments may be intermixed on the command line
- to change the behavior of
- .I mk
- on a per file basis \- e. g., ``mk \-s foo.c \-v \-ddebug bar.c''.
- .TP
- .B \-A
- Find all the marked lines that match the specified \fImarker\fP
- and \fIsubmarker\fP, stop processing at the first command that is
- successful.
- .TP
- .BI \-D defn
- Give a definition for an environment variable.
- The definition must have the form \fIident\fP\fB=\fP\fIvalue\fP.
- .TP
- .BI \-U undef
- Remove a definition for the environment variable \fIundef\fP.
- .TP
- .B \-a
- Find all the marked lines that match the specified \fImarker\fP
- and \fIsubmarker\fP.
- .TP
- .B \-c
- Confirm the action before running it.
- This will allow the user to see the command before it is executed.
- A response of `y' or `Y' will cause the command to be run.
- .TP
- .BI \-d submarker
- Look for the string \*(lq$\fImarker\fP(\fIsubmarker\fP):\*(rq in file.
- White space is ignored.
- A command line including \*(lq\-d debug\*(rq would match
- \*(lq$\fImarker\fP(debug):\*(rq.
- Submarkers in the file are ignored (do not take part in matching)
- if no submarker is specified.
- The \fIsubmarker\fP \*(lq*\*(rq matches all submarkers in the file.
- .TP
- .BI \-e template
- This \fItemplate\fP will be searched before the file at hand.
- This allows \fImk\fP to trap character special files with the %y macro.
- .TP
- .B \-h
- Print a help message.
- .TP
- .B \-i
- Ignore case when looking for \fImarker\fP and \fIsubmarker\fP.
- .TP
- .B \-l lines
- Search
- .I lines
- lines rather than the default 99 for compilation markers.
- .TP
- .B \-m marker
- Look for the string \*(rq\fB$\fP\fImarker\fP\fB:\fP\*(rq
- as the delimiter for the compilation directive.
- The default \fImarker\fP string is \*(lqCompile\*(rq.
- Note that \fImarker\fP does not include either the leading dollar\-sign (`$')
- or the trailing colon (`:').
- The \fImarker\fP \*(lq*\*(rq matches all markers in the file.
- .TP
- .B \-n
- Do not execute the located commands.
- This flag specifies that the resulting command(s) should not be executed,
- but only printed on the standard output.
- .TP
- .B \-s
- Be silent.
- Executed commands are not output.
- .TP
- .BI \-t templates
- The
- .I templates
- string produces a file name that will be searched for a
- .I marker
- line if no
- .I marker
- line is found in the file named on the
- .I mk
- call.
- The percent escapes described above are all available for substitution
- in this string, so that the template can be based on the extender of the
- file being processed.
- The default
- \fItemplates\f string is ``/usr/local/lib/mk/def_%x''.
- More than one template option my be specified.
- .I Mk
- searches for all of them in the order they are given.
- .TP
- .B \-v
- Be verbose.
- This is the opposite of \-\fBs\fP (above), and is implied by
- the \-\fBn\fP option (above).
- .TP
- .B \-V
- Be extra verbose.
- Used only to debug \fImk\fP, or output the default templates configuration.
- .SH EXAMPLES
- .I Mk
- is most commonly used to produce input for the shell.
- The following lines might occur in a C program source file:
- .sp \n()Pu
- .RS
- .nf
- /*
- X * $Compile: ${cc\-cc} ${CFLAGS\-\-O} \-o %F \-DFOO=1 %f
- X * $Compile(debug): ${cc\-cc} ${CFLAGS\-\-g} \-o %F \-DDEBUG %f
- X * $Run: %F /tmp/test
- X * $Fail=1: %F /etc/passwd
- X * $Limit,cpu=100,clock=600,fsize=10000: %F /tmp/test2
- X */
- .fi
- .RE
- .sp \n()Pu
- If the file were called \*(lqfoo.c\*(rq, \fImk\fP,
- invoked as
- .sp \n()Pu
- .RS
- mk foo.c
- .RE
- .sp \n()Pu
- would send
- .I sh
- the command:
- .sp \n()Pu
- .RS
- cc \-O \-o foo \-DFOO=1 foo.c
- .RE
- .sp \n()Pu
- With an invocation like
- .sp \n()Pu
- .RS
- mk \-ddebug foo.c
- .RE
- .sp \n()Pu
- the command
- .sp \n()Pu
- .RS
- cc \-g \-o foo \-DDEBUG foo.c
- .RE
- .sp \n()Pu
- would be sent to \fIsh\fP.
- .PP
- \fIMk\fP will output the default templates option if only \-\fBV\fP is
- set:
- .RS
- .nf
- mk: $Id: mk.1l,v 4.2 90/11/28 16:29:54 ksb Exp $
- mk: %~ `/usr/local/lib/mk'
- mk: -e `%~/type-%y:%~/pre-%x:%~/comma-%U,'
- mk: -t `%~/file-%F:%~/dot-%x:%~/m-%M'
- .fi
- .RE
- .SH SEE ALSO
- sh(1),
- setrlimit(2),
- valid(1L).
- .SH AUTHORS
- S. McGeady, Intel, Inc., mcg@mipon2.intel.com
- .sp 1
- Kevin Braunsdorf, Purdue University Computing Center (ksb@cc.purdue.edu)
- Purdue
- chmod 0444 mk/mk.1l ||
- echo 'restore of mk/mk.1l failed'
- Wc_c="`wc -c < 'mk/mk.1l'`"
- test 10944 -eq "$Wc_c" ||
- echo 'mk/mk.1l: original size 10944, current size' "$Wc_c"
- fi
- true || echo 'restore of mkcat/pt.c failed'
- echo End of part 3, continue with part 4
- exit 0
-
- exit 0 # Just in case...
-