Subject: man pages again
To: None <current-users@NetBSD.ORG>
From: Julian Bean <jules@mailbox.co.uk>
List: current-users
Date: 03/09/1996 23:49:59
OK, I acted for once on my thought.  I was going to get ethernet support for my 
LC, but since someone broke the kernel source  I felt that was a sign, and I 
hacked this together.

Basically, the patch at the bottom of this file will change man such that if it 
has to format a page using any _build rule, it will try and work out what the 
corresponding cat directory is and save the formatted text there before 
displaying it.

It will only do this if run as root, since by default only root has write 
permissions to these directories.

I have several vague thoughts as to how sensible my way of coding it is - read 
the comments in the diff.

I would appreciate any comments of any kind.  If I ever get the my ethernet code 
working (which is my first priority), I might do some more work on the whole 
man/catman/man.conf system.  Does anyone have this project checked out?

Jules

P.S. Sorry about the long lines - you'd better check your mail reader hasn;t
wrapped them before applying any patches.

-----CUT HERE----
*** man.c.orig  Sat Mar  9 23:23:00 1996
--- man.c       Sat Mar  9 23:19:02 1996
***************
*** 542,547 ****
--- 542,654 ----
        (void)snprintf(cmd, sizeof(cmd), buf, *pathp);
        (void)system(cmd);
        (void)close(fd);
+ 
+       /*
+        *  If we are running as root, try to save a preformatted
+        *  version of the file.
+        *
+        *  This code isn't really integrated with our new, posh
+        *  man.conf format.  It is 'hacked' to assume that man
+        *  pages are stored in man<something> directories.  And
+        *  that the equivalent cat<something> directory exists.
+        *
+        *  It would be better if there were two man.conf directives,
+        *  _rawsubdir and _catsubdir, with *corresponding* directories
+        *  for unformatted and formatted versions of the pages.
+        *
+        *  Then, man could check to see if the unformatted version
+        *  is newer, and if so, format it, otherwise simply cat the
+        *  cached one.
+        *
+        *  Also, we're not supposed to be running as root. So maybe
+        *  it is not all that useful.  Since I personally do, I find
+        *  it so.
+        *
+        *  I am very tempted to suggest making man run suid (possibly
+        *  to a new user 'man') so that any user can 'cache'
+        *  manual pages.
+        *
+        *  Possibly it should delete the man?/ version of the file,
+        *  to save space, but then you couldn't troff it for output
+        *  to hard-copy.
+        *
+        *  This is mainly because groff is *very* slow on older machines,
+        *  like my macintosh LCIII.  And although NetBSD userland, by
+        *  by default, installs preformatted versions, most 3rd-party
+        *  stuff doesn't.  And of course we don't have a working catman.
+        *
+        *  Code added by Jules Bean (jules@mailbox.co.uk) 960309
+        */
+ 
+       if (geteuid() == 0) {
+               char catpath[100];
+               char *p;
+               int slcount=0;
+ 
+               strcpy(catpath,*pathp);
+ 
+               for(p=catpath+strlen(catpath);slcount<2;p--)
+                       if (*p =='/') slcount++;
+ 
+               p+=2;
+ 
+               /*
+                * p now points to the last directory component of the
+                * path, e.g. :
+                *
+                * catpath = "/usr/share/man/man1/tcsh.1"
+                *                           ^
+                *                           p
+                *
+                * We want to replace this with cat, and the suffix with 0
+                */
+ 
+               printf("Trailing component : %s\n",p);
+ 
+               if (strncmp(p,"man",3) == 0) { /* Good, it starts with man */
+                       
+                       /* So replace it with cat */
+                       memcpy(p,"cat",3); 
+ 
+                       /* Replace everything after the last . with 0 */
+                       p = strrchr(catpath,'.');
+                       strcpy(p+1,"0");
+ 
+                       /* Move the temp file across */
+                       sprintf(cmd,"mv %s %s",tpath,catpath);
+ 
+                       if (system(cmd) == 0)
+                       {
+                               /*
+                                * Good that worked.
+                                * Now change the path name used by the
+                                * auto-pager.
+                                * I don't know why strdup not strcpy, but that's
+                                * what it is below ;-)
+                                * Presumably this is free'd somewhere else,
+                                * or maybe we don't care about memory leaks
+                                * in a program which is about to terminate
+                                */
+ 
+                               *pathp = strdup(catpath); /* page newly formatted */
+                               return; /* drop out to auto-pager */
+                       } else { 
+                               /*
+                                * The system failed.  Don't know why. Error
+                                * checking could be cleverer here.
+                                * FS full is an obvious possibility. As is
+                                * a read-only man volume.
+                                */
+ 
+                               fprintf(stderr,"man: Cannot save newly formatted data as %s\n",catpath);
+                               /* 
+                                * And now drop through to default behaviour -
+                                * i.e. page the temporary file
+                                */
+                       }
+               }  
+       } 
+ 
        if ((*pathp = strdup(tpath)) == NULL) {
                warn(NULL);
                (void)cleanup();
----CUT HERE----