[comp.sources.misc] v05i021: "man" client with trivial server

reggers@julian.uucp (Reg Quinton) (10/28/88)

Posting-number: Volume 5, Issue 21
Submitted-by: "Reg Quinton" <reggers@julian.uucp>
Archive-name: rman

Here's a posting for comp.sources.unix that others might find useful. If nothing
else the strategy is a sneaky one for building arbitrary client/server pairs.

We've implemented a simple "man/apropos" client for machines which don't have
the /usr/man directory. I'm sure this has been done a hundred times by others
but, for what it's worth, here's my way of doing it. Oh yes, this is a BSDism,
I don't know how you'd do the same thing under SysV.

[Given SVR4, that last comment is a non-sequitur.  ++bsa]

-----------------------cut, cut, blood, spurt. I wanted to be a lumber jack!
#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -s ./README`
then
echo "writing ./README"
cat > ./README << '\Rogue\Monster\'
There's no need to have manuals stored on every machine. Sources in this
directory are used to build a client man and apropos program which use the
man program on a server machine. This builds on the rcmd(3) call instead of
defining another service. Here's what you need to do.

a) on your client machines build and install the man program (see Makefile);
   and add an entry for "manhost" into your /etc/hosts and/or bind files.

b) on your server (ie. "manhost") machine add a user call "man" into your
   password file with home directory /usr/man (shell can be csh or sh). Clients
   not in /etc/hosts.equiv need to be added to /usr/man/.rhosts with lines of
   the form "<host-name> man".

c) although not required you can remove /usr/man on your clients, and chown
   -R man /usr/man on your server.

The names "manhost" and "man" are "#defines" in my code, you can use something
else if you like.

The client man program tells the rshd on manhost that a local user called "man"
wants the remote user called "man" to execute some man or apropos command. This
relies then on the rshd access control system.  Hosts in the server (ie manhost)
/etc/hosts.equiv file will be able to use the server without doing anything
else. Hosts not in manhost's /etc/hosts.equiv should have an entry put into
/usr/man/.rhosts for them (see rshd(8) for more details).

Reg Quinton <reggers@julian.uwo.ca>; 30-Sept-88
\Rogue\Monster\
else
  echo "will not over write ./README"
fi
if `test ! -s ./Makefile`
then
echo "writing ./Makefile"
cat > ./Makefile << '\Rogue\Monster\'
# $Author: reggers $
# $Date: 88/09/30 14:40:08 $
# $Header: Makefile,v 1.1 88/09/30 14:40:08 reggers Locked $
# $Locker: reggers $
# $Revision: 1.1 $
# $Source: /usrs/guru/reggers/rman/RCS/Makefile,v $
# $State: Exp $

BIN=/usr/local

man: rman.c Makefile
	cc -s -O -o man rman.c

install: man
	install -m 4555 -o root man ${BIN}
	-rm ${BIN}/apropos
	ln -s ${BIN}/man ${BIN}/apropos
	-rm /usr/ucb/man /usr/ucb/apropos
	@echo you might ... rm -rf /usr/man
\Rogue\Monster\
else
  echo "will not over write ./Makefile"
fi
if `test ! -s ./rman.c`
then
echo "writing ./rman.c"
cat > ./rman.c << '\Rogue\Monster\'
char *rcsversion=
"$Header: rman.c,v 1.3 88/10/03 11:58:23 reggers Exp $";

/*
 $Author: reggers $
 $Date: 88/10/03 11:58:23 $
 $Header: rman.c,v 1.3 88/10/03 11:58:23 reggers Exp $
 $Locker:  $
 $Revision: 1.3 $
 $Source: /usrs/guru/reggers/rman/RCS/rman.c,v $
 $State: Exp $

 This looks a lot like the rsh code (I'd bet) but we're only going to
 hit either man, or apropos, via the rsh sequence. And we're going to
 hit a particular user.
*/

#define	PAGER	"/usr/ucb/more"
#define	MANUSER	"man"
#define	MANHOST	"manhost"
#define	RSHPORT 514

#include	<stdio.h>
#include	<sysexits.h>
#include	<strings.h>

main(argc,argv)
int	argc;
char	*argv[];
{
	char	*cmd,*p,c;
	int	i,n,rem;

	if (p=rindex(argv[0],'/')) ++p;
	else	p= argv[0];

	cmd=(char *)malloc(n=(strlen(p)+1));	strcpy(cmd,p);

	if (strcmp(cmd,"man") && strcmp(cmd, "apropos"))
	{
		fprintf(stderr,"Usage: man topic\nor: apropos topic\n");
		exit(EX_USAGE);
	}

	for (i=1; argv[i]; i++)
	{
		cmd=(char *)realloc(cmd,n+=strlen(argv[i])+1);
		strcat(cmd," ");
		strcat(cmd,argv[i]);
	}

	p=MANHOST;

	if ((rem=rcmd(&p,RSHPORT,MANUSER,MANUSER,cmd,0)) < 0)
	{
		fprintf(stderr,"Oops... cannot connect to man server\n");
		exit(EX_UNAVAILABLE);
	}

	if (isatty(0) && isatty(1))
	{
		close(0);	dup(rem);
		execl(PAGER,PAGER,0);
		fprintf(stderr,"\"%s\" not found!\n",PAGER);
		exit(EX_UNAVAILABLE);
	}
    	while (read(rem,&c,1) == 1) fputc(c,stdout);
	exit(0);
}
\Rogue\Monster\
else
  echo "will not over write ./rman.c"
fi
echo "Finished archive 1 of 1"
exit