Path: utzoo!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!munnari.oz.au!basser!usage!ccadfa!csadfa!wkt From: wkt@csadfa.cs.adfa.oz.au (Warren Toomey) Newsgroups: comp.os.minix Subject: man(1) - a more Unix-like version Message-ID: <829@ccadfa.adfa.oz.au> Date: 19 Dec 89 08:31:12 GMT Sender: news@ccadfa.adfa.oz.au Lines: 366 Yet another man(1) program - this one keeps man files a la Unix. ------------------------- cut here ----------------------------- #!/bin/sh # to extract, remove the header and type "sh filename" if `test ! -s ./README` then echo "writing ./README" cat > ./README << '\Rogue\Monster\' Here is yet another implementation of man(1); this one knows only about files with man macros, and files without. Each manual is in a separate file, and they are kept in cat1 ... cat8, man1 ... man8 directories just like Unix. You'll need to build a `whatis' file too! And before I go, here's my implementation of apropos & whatis: alias apropos 'grep "$1" /usr/man/whatis' alias whatis 'grep "^$1" /usr/man/whatis' Does help if you have Clam :-) Finally, with regards to Andy's 1.5 manuals posting, either break them up into separate files & put them in to /usr/man/cat1, or wait a bit. I LaTeX'd all the 1.3 manuals by hand & I will try to knock up a LaTeX -> nroff converter for the manuals I created. Merry Christmas to you all! Warren Toomey - wkt@csadfa.oz.au@munnari.oz.au[@uunet] \Rogue\Monster\ else echo "will not over write ./README" fi if `test ! -s ./man.c` then echo "writing ./man.c" cat > ./man.c << '\Rogue\Monster\' #include #include #include /* Man - find, nroff & display online manuals * * Written by Warren Toomey. Dec, 1989. * You may freely copy or give away this source as * long as this notice remains intact. * */ /* Things to do: if stdout != tty, don't page (I think?) */ #define EPAGE "PAGER=" /* Pager environment variable name */ #define EMAN "MANPATH=" /* Man path environment variable name */ #define PAGER "/usr/local/bin/less" /* Default pager */ #define MANPATH "/usr/man" /* Default man directory */ #define WHATIS "whatis" /* Whatis file */ #define NROFF "nroff -man" /* Nroff for manuals */ int fgetarg(stream,cbuf) /* Get next arg from file into cbuf, */ FILE *stream; /* returning the character that */ char *cbuf; /* terminated it. Cbuf returns NULL */ { /* if no arg. EOF is returned if no */ int ch; /* args left in file. */ int i; i=0; cbuf[i]=NULL; while (((ch=fgetc(stream))==' ') || (ch=='\t') || (ch=='\n')) if (ch=='\n') return(ch); /* Bypass leading */ /* whitespace */ if (feof(stream)) return(EOF); cbuf[i++]=ch; while (((ch=fgetc(stream))!=' ') && (ch!='\t') && (ch!='\n')) cbuf[i++]=ch; /* Get the argument */ cbuf[i]=NULL; return(ch); } char *getenval(envp,var) /* Return the variable value from envp */ char *envp[],*var; { int i; char *value; for (i=0;envp[i]!=NULL;i++) if (!strncmp(envp[i],var,strlen(var))) { value = envp[i] + strlen(var); return(value); } return(NULL); } int fsize(path,siz) /* Return the size of a file in bytes */ char *path; /* or an error if cannot stat it */ int *siz; { struct stat buf; int i=0; if (i=stat(path,&buf)) return(i); *siz= buf.st_size; return(0); } cutstring(s1,ary) /* Cut string of fields into separate */ char *s1, *ary[]; /* fields. Separator is space, tab or : */ { int i=0; ary[0]=s1; /* Set first field */ while (*s1) { if ((*s1==' ') || (*s1=='\t') || (*s1==':')) { *s1=NULL; ary[++i]= s1+1; } s1++; } } char msearch(mp,title) /* Find the section of the manual where */ char *mp, *title; /* the requested title is in */ { char whatis[100], word[100], ch=1; int size; FILE *zin; sprintf(whatis,"%s/%s",mp,WHATIS); /* find `whatis' */ if (fsize(whatis,&size)!=0) return('0'); /* Use size to search */ /* linearly or binarily */ if ((zin=fopen(whatis,"r"))==NULL) return('0'); while (ch!=EOF) /* search for title */ { ch=fgetarg(zin,word); if (!strcmp(word,title)) { while ((ch=fgetc(zin)!='(')); /* Find the digit */ ch=fgetc(zin); fclose(zin); return(ch); } /* else skip rest of line */ else while ((ch!=EOF) && (ch!='\n')) ch=fgetarg(zin,word); } return('0'); } usage() { fprintf(stderr,"Usage: man [section] title\n"); exit(0); } main(argc,argv,envp) int argc; char *argv[], *envp[]; { int i,size; char *pager, *manpath, sect, usersect; char *mandir[100]; char cmd[200]; if ((argc<2) || (argc>3)) usage(); usersect='0'; if (argc==3) { usersect=argv[1][0]; /* Get any section */ if ((usersect<'1') || (usersect>'8')) usage(); } pager=getenval(envp,EPAGE); /* Set up pager path */ if (pager==NULL) pager= PAGER; manpath=getenval(envp,EMAN); /* Set up manual path */ if (manpath==NULL) manpath= MANPATH; cutstring(manpath,mandir); /* Split man path */ for (i=0;mandir[i]!=NULL;i++) /* For every manual directory */ { /* find an entry */ sect=msearch(mandir[i],argv[argc-1]); /* If one exists */ if ((sect!='0') && ((usersect=='0') || (usersect==sect))) { sprintf(cmd,"%s/cat%c/%s.%c", /* Check cat entry */ mandir[i],sect,argv[argc-1],sect); if (fsize(cmd,&size)) /* If none, nroff */ { /* a new one */ fprintf(stderr,"Reformatting page. Please wait...\n"); sprintf(cmd,"%s %s/man%c/%s.%c | %s",NROFF, mandir[i], sect,argv[argc-1],sect,pager); system(cmd); exit(0); } else /* just page the cat file */ { sprintf(cmd,"%s %s/cat%c/%s.%c",pager, mandir[i], sect,argv[argc-1],sect); system(cmd); exit(0); } } } printf("No manual on %s\n",argv[argc-1]); exit(1); } \Rogue\Monster\ else echo "will not over write ./man.c" fi if `test ! -s ./man.1` then echo "writing ./man.1" cat > ./man.1 << '\Rogue\Monster\' .TH man 1 .SH NAME man \- find & format online manuals .SH SYNTAX man [section] title .SH DESCRIPTION .B Man finds an online manual of the given title, formats it (if necessary), and displays it on the screen. If the title occurs in several sections of the online manuals, the section argument specifies which section. .PP .B Man looks in the users environment for two variables, .B MANPATH and .B PAGER. The first holds a list of directories where manuals are kept; directories should be absolute and be separated by spaces, tabs, or colons. It can be set up from shell like .PP $ MANPATH="/usr/man /usr/local/man" ; export MANPATH .PP If no .B MANPATH variable is found, .B man defaults to .I /usr/man. .PP The .B PAGER variable indicates which pager should be used to display the manual. If none is found, .B man defaults to .I /usr/local/bin/less. .PP .B Man searches through the .I whatis file in each of the directories in .B MANPATH for an appropriate manual. This file is described in .I whatis(5). .B Man then looks for the manual in a .I catx directory; if it is there, .B man directly displays it with the pager. Otherwise, .B nroff is used to format the manual from the .I manx directory, and the output is passed to the pager. .PP If no manual is found in .I whatis, or the manual does not exist etc., .B man will give an error message and fail. .SH FILES /usr/man \- usual directory for manuals /usr/man/whatis \- file which lists all the manuals /usr/man/catx \- directories of pre-nroffed manuals /usr/man/manx \- directories of non-nroffed manuals .SH SEE ALSO nroff(1), less(1), whatis(5) \Rogue\Monster\ else echo "will not over write ./man.1" fi if `test ! -s ./whatis.5` then echo "writing ./whatis.5" cat > ./whatis.5 << '\Rogue\Monster\' .TH whatis 5 .SH NAME whatis \- list the available online manuals .SH SYNTAX /usr/man/whatis .SH DESCRIPTION .B Whatis contains a list of all the available online manuals in the manual directory, and which section each manual is in. Each line in the file contains .PP + the name of manual .PP + the section it is in [in parentheses] .PP + a short description about the manual .PP The manual name must contain no whitespace, and have no leading whitespace. The section consists of open parenthesis, single digit (plus optional single uppercase letter \- to indicate subtype), close parenthesis, and is separated from the name and description by whitespace. The description of the manual is ignored, and can be anything, but must not contain carriage returns. .SH EXAMPLE .TP 8 whatis (5) \- the entry for this manual .TP 8 man (1) \- an entry for the manual program .TP 8 man (7) \- an entry for the manual macros .TP 8 less (1L) \- the less pager, which is not standard .SH SEE ALSO man(1), nroff(1) \Rogue\Monster\ else echo "will not over write ./whatis.5" fi echo "Finished archive 1 of 1" exit Warren Toomey VK2XWT, electric guitar licker. Deep in the bowels of ADFA Comp Science. Canberra. ACT. 2600. Email: wkt@csadfa.oz.au `Worth the money but not the risk -CC'