[mod.sources] v06i098: Sun RPC Source

sources-request@mirror.UUCP (08/08/86)

Submitted by: cca!SUN.COM!marks (Mark Stein)
Mod.sources: Volume 6, Issue 98
Archive-name: rpc2/Part10

[  All I have done is verify that this unpacks properly.  --r$  ]

Sun RPC source (part 10 of 11).  This software package contains code
and documentation for Revision 3.0 of the Sun Remote Procedure Call
library.  In addition, a beta version of the XDR/RPC protocol compiler
is included.  Comments about this latest release may be mailed to
sun!rpc or rpc@sun.com.

Sun RPC is a product of Sun Microsystems, Inc. and is provided for
unrestricted use provided that this legend is included on all tape
media and as a part of the software program in whole or part.  Users
may copy or modify Sun RPC without charge, but are not authorized to
license or distribute it to anyone else except as part of a product or
program developed by the user.

- - - - - - - - - C U T - H E R E - - - - - - - - - - - - - - - - - -
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
#	rpc/rpcgen/Makefile
#	rpc/rpcgen/README
#	rpc/rpcgen/rpc_cout.c
#	rpc/rpcgen/rpc_hout.c
#	rpc/rpcgen/rpc_main.c
#	rpc/rpcgen/rpc_parse.c
#	rpc/rpcgen/rpc_parse.h
#	rpc/rpcgen/rpc_scan.c
#	rpc/rpcgen/rpc_scan.h
#	rpc/rpcgen/rpc_svcout.c
# This archive created: Mon Jul 14 16:55:46 1986
export PATH; PATH=/bin:/usr/bin:$PATH
for d in rpc rpc/doc rpc/rpclib rpc/tools rpc/toys rpc/rpclib/profiled rpc/rpcgen rpc/rpcgen/test
do
	if test ! -d $d
	then
		echo "shar: Making directory $d"
		mkdir $d
		chmod 755 $d
	fi
done
echo shar: "extracting 'rpc/rpcgen/Makefile'" '(956 characters)'
if test -f 'rpc/rpcgen/Makefile'
then
	echo shar: "will not over-write existing file 'rpc/rpcgen/Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/Makefile'
X#
X#	@(#)Makefile 1.1 86/03/26 (C) 1986 SMI
X#
X# Makefile for rpc protocol compiler
X# Copyright (C) 1986, Sun Microsystems, Inc.
X#
XOBJS= rpc_main.o rpc_hout.o rpc_cout.o rpc_parse.o rpc_scan.o rpc_util.o \
X	rpc_svcout.o
XSRCS= rpc_main.c rpc_hout.c rpc_cout.c rpc_parse.c rpc_scan.c rpc_util.c \
X	rpc_svcout.c
XHDRS= rpc_util.h rpc_parse.h rpc_scan.h
X
X# XDR_UPDATE used when rpc library used is pre-3.2
XXDR_UPDATE = xdr_update.o
XGOAL=rpcgen
XCFLAGS = -O
XDESTDIR=
X
Xall: $(GOAL) $(XDR_UPDATE)
X
X$(GOAL): $(OBJS) 
X	cc $(CFLAGS) $(OBJS) -o $@
X
Xinstall: $(GOAL)
X	install -s rpcgen $(DESTDIR)/usr/bin
X	
X
X$(GOAL).lint: $(SRCS) $(HDRS)
X	lint $(SRCS) > $@
X
Xclean:
X	rm -f $(GOAL) $(OBJS) $(XDR_UPDATE)
X
Xrpc_util.c: rpc_util.h rpc_scan.h
Xrpc_scan.c: rpc_util.h rpc_scan.h
Xrpc_parse.c: rpc_util.h rpc_scan.h rpc_parse.h
Xrpc_cout.c: rpc_util.h rpc_parse.h
Xrpc_hout.c: rpc_util.h rpc_parse.h
Xrpc_svcout.c: rpc_util.h rpc_parse.h
Xrpc_main.c: rpc_util.h rpc_parse.h rpc_scan.h
X
SHAR_EOF
if test 956 -ne "`wc -c < 'rpc/rpcgen/Makefile'`"
then
	echo shar: "error transmitting 'rpc/rpcgen/Makefile'" '(should have been 956 characters)'
fi
chmod 664 'rpc/rpcgen/Makefile'
fi
echo shar: "extracting 'rpc/rpcgen/README'" '(901 characters)'
if test -f 'rpc/rpcgen/README'
then
	echo shar: "will not over-write existing file 'rpc/rpcgen/README'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/README'
XThis directory contains the source for the RPC protocol compiler
X`rpcgen.'   Rpcgen allows you to specify the protocol and data types
Xused for an RPC service in a concise format, and will automatically
Xgenerate the various stock components required to make a server for
Xthat service.  See rpcgen.1 for usage information.
X
XThe `test' directory contains an example of how rpcgen might be used.
X
XThis software is from the Sun Microsystems 3.2Beta software release and
Xis made available subject to the same conditions as the Remote
XProcedure Call library.  Please send comments and bug reports to
Xsun!rpc or rpc@sun.com.
X
X./xdr_update.c contains two xdr routines which have been added in
X3.2 (and which rpcgen uses).  This file may either be loaded with the
Xserver being built (as in the `test' directory), or may be added to the
Xrpc library.  These routines will be part of the next rpc library
Xrelease.
SHAR_EOF
if test 901 -ne "`wc -c < 'rpc/rpcgen/README'`"
then
	echo shar: "error transmitting 'rpc/rpcgen/README'" '(should have been 901 characters)'
fi
chmod 664 'rpc/rpcgen/README'
fi
echo shar: "extracting 'rpc/rpcgen/rpc_cout.c'" '(7980 characters)'
if test -f 'rpc/rpcgen/rpc_cout.c'
then
	echo shar: "will not over-write existing file 'rpc/rpcgen/rpc_cout.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/rpc_cout.c'
X#ifndef lint
Xstatic char	sccsid[] = "@(#)rpc_cout.c 1.1 86/03/26 (C) 1986 SMI";
X#endif
X
X/*
X * rpc_cout.c, XDR routine outputter for the RPC protocol compiler
X * Copyright (C) 1986, Sun Microsystems, Inc.
X */
X#include <stdio.h>
X#include <strings.h>
X#include "rpc_util.h"
X#include "rpc_parse.h"
X
X#define SPECIALDEF 1	/* special if definition created by compiler */
X#define NORMALDEF 0		/* normal if definition created by human */
X
X
X/*
X * Emit the C-routine for the given definition
X */
Xvoid
Xemit(def)
X	definition *def;
X{
X	do_emit(def,NORMALDEF);
X}
X
X
X
Xstatic
Xdo_emit(def,special)
X	definition *def;
X	int special;
X{
X
X	if (def->def_kind == DEF_PROGRAM) {
X		return;
X	}
X	if (isprinted(def->def_name)) {
X		return;
X	}
X	print_undefineds(def);
X	print_header(def,special);
X	switch (def->def_kind) {
X	case DEF_UNION:
X		emit_union(def);
X		break;
X	case DEF_ARRAY:
X		emit_array(def);
X		break;
X	case DEF_ENUM:
X		emit_enum(def);
X		break;
X	case DEF_STRUCT:	
X		emit_struct(def);
X		break;	
X	case DEF_TYPEDEF:
X		emit_typedef(def);
X		break;
X	}
X	print_trailer();
X}
X
Xstatic
Xfindtype(def,type)
X	definition *def;
X	char *type;
X{
X	if (def->def_kind == DEF_PROGRAM) {
X		return(0);
X	} else {
X		return(streq(def->def_name,type));
X	}
X}
X
Xstatic
Xundefined(type)
X	char *type;
X{
X	definition *def;
X
X	def = (definition *) FINDVAL(defined,type,findtype);
X	return(def == NULL);
X}
X
Xstatic	
Xisprinted(name)
X	char *name;
X{
X	char *find;
X
X	find = (char *) FINDVAL(printed,name,streq);
X	if (find) {
X		return(1);
X	}
X	STOREVAL(&printed, name);
X	return(0);
X}
X
X
X
Xstatic char *
Xformat_funcname(decp)
X	declaration *decp;
X{
X	char buf[256];
X	char *p;
X
X	switch (decp->rel) {
X	case REL_POINTER:
X		sprintf(buf,"%s_ptr",decp->type);
X		break;
X	case REL_VECTOR:
X		if (streq(decp->type,"string") && decp->array_max == NULL) {
X			sprintf(buf,"wrapstring");
X		} else {
X			sprintf(buf,"%s_%s",decp->type,decp->array_max);
X		}
X		break;
X	case REL_ALIAS:
X		sprintf(buf,"%s",decp->type);
X		break;
X	}
X	p = alloc(strlen(buf) + 1);
X	strcpy(p,buf);
X	return(p);
X}
X
X
X
X
Xstatic 
Xprint_undefineds(def)
X	definition *def;
X{
X	case_list *cl;
X	declaration *dflt;
X
X	if (def->def_kind != DEF_UNION) {
X		return;
X	}
X	for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
X		if (cl->case_decl.rel != REL_ALIAS) {
X			emit_new(&cl->case_decl);
X		}
X	}
X	dflt = def->def.un.default_decl;
X	if (dflt) {
X		if (dflt->rel != REL_ALIAS) {
X			emit_new(dflt);
X		}
X	}
X}
X
X
Xstatic	
Xemit_new(dec)
X	declaration *dec;
X{
X	definition *def;
X
X	if (dec->rel == REL_VECTOR && streq(dec->type,"string") && 
X			dec->array_max == NULL) {
X		return;
X	}
X	def = ALLOC(definition);
X	def->def_kind = DEF_TYPEDEF;
X	def->def_name = format_funcname(dec);
X	def->def.ty.old_prefix = dec->prefix;
X	def->def.ty.old_type = dec->type;
X	def->def.ty.rel = dec->rel;
X	def->def.ty.array_max = dec->array_max;
X	do_emit(def, SPECIALDEF);
X}
X
Xstatic
Xprint_header(def,special)
X	definition *def;	
X	int special;
X{
X	space();	
X	if (special) {
X		fprintf(fout,"static ");
X	}
X	fprintf(fout,"bool_t\n");
X	fprintf(fout,"xdr_%s(xdrs,objp)\n",def->def_name);
X	fprintf(fout,"\tXDR *xdrs;\n");
X	if (special) {
X		if (streq(def->def.ty.old_type,"string")) {
X			fprintf(fout,"\tchar *");	
X		} else if (streq(def->def.ty.old_type,"opaque")) {
X			fprintf(fout,"\tchar *");
X		} else if (streq(def->def.ty.old_type,"bool")) {
X			fprintf(fout,"\tbool_t *");
X		} else {
X			fprintf(fout,"\t%s *",def->def.ty.old_type);
X		}
X	} else {
X		fprintf(fout,"\t%s ",def->def_name);
X	}
X	if (def->def_kind != DEF_TYPEDEF  ||
X			! isvectordef(def->def.ty.old_type,def->def.ty.rel)) {
X		fprintf(fout,"*");
X	}
X	fprintf(fout,"objp;\n");
X	fprintf(fout,"{\n");
X}
X
Xstatic
Xtypedefed(def,type)
X	definition *def;
X	char *type;
X{
X	if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
X		return(0);
X	} else {
X		return (streq(def->def_name,type));
X	}
X}
X
Xstatic
Xisvectordef(type,rel)
X	char *type;
X	relation rel;	
X{
X	definition *def;
X
X	for (;;) {
X		switch (rel) {
X		case REL_VECTOR:
X			return(! streq(type,"string"));
X		case REL_POINTER:
X			return(0);
X		case REL_ALIAS:	
X			def = (definition *) FINDVAL(defined,type,typedefed);
X			if (def == NULL) {
X				return(0);
X			}
X			type = def->def.ty.old_type;
X			rel = def->def.ty.rel;
X		}
X	}
X}
X	
Xstatic
Xprint_trailer()
X{
X	fprintf(fout,"\treturn(TRUE);\n");
X	fprintf(fout,"}\n");
X	space();
X}
X
Xstatic
Xprint_ifopen(name)
X	char *name;
X{
X	fprintf(fout,"\tif (! xdr_%s(xdrs",name);
X}
X
X
Xstatic
Xprint_ifarg(arg)
X	char *arg;
X{
X	fprintf(fout,", %s",arg);
X}
X
X
Xstatic
Xprint_ifsizeof(prefix,type)
X	char *prefix;
X	char *type;
X{
X	if (streq(type,"bool")) {
X		fprintf(fout,", sizeof(bool_t), xdr_bool");
X	} else {
X		fprintf(fout,", sizeof(");
X		if (undefined(type) && prefix) {
X			fprintf(fout,"%s ",prefix);
X		}
X		fprintf(fout,"%s), xdr_%s",type,type);
X	}
X}
X
Xstatic
Xprint_ifclose()
X{
X	fprintf(fout,")) {\n");
X	fprintf(fout,"\t\treturn(FALSE);\n");
X	fprintf(fout,"\t}\n");
X}
X
Xstatic
Xspace()
X{
X	fprintf(fout,"\n\n");
X}
X
Xstatic
Xprint_ifstat(prefix,type,rel,amax,name)
X	char *prefix;
X	char *type;
X	relation rel;
X	char *amax;
X	char *name;
X{
X	char *alt = NULL;
X
X	switch (rel) {
X	case REL_POINTER:
X		print_ifopen("pointer");
X		print_ifarg("(char *) ");
X		fprintf(fout,name);
X		print_ifsizeof(prefix,type);
X		break;
X	case REL_VECTOR:
X		if (streq(type,"string")) {
X			if (amax) {
X				alt = "string";
X			} else {
X				alt = "wrapstring";	
X			}
X		} else if (streq(type,"opaque")) {
X			alt = "opaque";
X		}
X		if (alt) {
X			print_ifopen(alt);
X			print_ifarg(name);
X		} else {
X			print_ifopen("vector");
X			print_ifarg("(char *) ");
X			fprintf(fout,name);
X		}
X		if (amax) {
X			print_ifarg(amax);
X		}
X		if (! alt) {
X			print_ifsizeof(prefix,type);
X		}
X		break;
X	case REL_ALIAS:
X		print_ifopen(type);
X		print_ifarg(name);
X		break;
X	}
X	print_ifclose();
X}
X
X
X/*ARGSUSED*/
Xstatic
Xemit_enum(def)
X	definition *def;
X{
X	print_ifopen("enum");
X	print_ifarg("(enum_t *) objp");
X	print_ifclose();
X}
X
X
Xstatic
Xemit_array(def)
X	definition *def;
X{
X	array_def *ad = &def->def.ar;
X	char *prefix = ad->array_prefix;
X	char *type = ad->array_type;
X	int bytes;
X
X	bytes = streq(type,"opaque");
X	print_ifopen(bytes ? "bytes" : "array");
X	print_ifarg("&objp->");
X	fprintf(fout,ad->array_name);
X	print_ifarg("(char *) &objp->");
X	fprintf(fout,ad->len_name);
X	print_ifarg(ad->array_max);
X	if (! bytes) {
X		print_ifsizeof(prefix,type);
X	}
X	print_ifclose();
X}
X
X
X
Xstatic
Xprint_funcname(decp)
X	declaration *decp;
X{
X	char *buf;
X
X	buf = format_funcname(decp);
X	fprintf(fout,buf);
X	free(buf);
X}
X
X
X	
Xstatic
Xemit_union(def)
X	definition *def;
X{
X	declaration *dflt;
X	
X
X	print_tags(def);
X	print_ifopen("union");
X	print_ifarg("(enum_t *) &objp->");
X	fprintf(fout,def->def.un.enum_decl.name);
X	print_ifarg("(char *) &objp->");
X	fprintf(fout,"%s",def->def_name);
X	print_ifarg("choices");
X	dflt = def->def.un.default_decl;
X	if (dflt) {
X		print_ifarg("xdr_");
X		print_funcname(dflt);
X	} else {
X		print_ifarg("NULL");
X	}
X	print_ifclose();
X}
X
X
X
Xstatic
Xprint_tags(def)
X	definition *def;
X{
X	case_list *cl;
X
X	fprintf(fout,"\tstatic struct xdr_discrim choices[] = {\n",def->def_name);
X	for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
X		fprintf(fout,"\t\t{ (int) %s, xdr_",cl->case_name);
X		print_funcname(&cl->case_decl);
X		fprintf(fout," },\n");
X	}
X	fprintf(fout,"\t\t{ __dontcare__, NULL }\n");
X	fprintf(fout,"\t};\n");
X	fprintf(fout,"\n");	
X}
X
X
Xstatic
Xemit_struct(def)
X	definition *def;
X{
X	decl_list *dl;
X
X	for (dl = def->def.st.decls; dl != NULL; dl = dl->next) {
X		print_stat(&dl->decl);
X	}
X}
X
X
X
X		
Xstatic
Xemit_typedef(def)
X	definition *def;
X{
X	char *prefix = def->def.ty.old_prefix;
X	char *type = def->def.ty.old_type;
X	char *amax = def->def.ty.array_max;
X	relation rel = def->def.ty.rel;
X
X	print_ifstat(prefix,type,rel,amax,"objp");
X}
X
X
X
X
X
Xstatic
Xprint_stat(dec) 
X	declaration *dec;
X{
X	char *prefix = dec->prefix;
X	char *type = dec->type;
X	char *amax = dec->array_max;
X	relation rel = dec->rel;
X	char name[256];
X
X	if (isvectordef(type,rel)) {
X		sprintf(name,"objp->%s",dec->name);
X	} else {
X		sprintf(name,"&objp->%s",dec->name);
X	}
X	print_ifstat(prefix,type,rel,amax,name);
X}
SHAR_EOF
if test 7980 -ne "`wc -c < 'rpc/rpcgen/rpc_cout.c'`"
then
	echo shar: "error transmitting 'rpc/rpcgen/rpc_cout.c'" '(should have been 7980 characters)'
fi
chmod 444 'rpc/rpcgen/rpc_cout.c'
fi
echo shar: "extracting 'rpc/rpcgen/rpc_hout.c'" '(5658 characters)'
if test -f 'rpc/rpcgen/rpc_hout.c'
then
	echo shar: "will not over-write existing file 'rpc/rpcgen/rpc_hout.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/rpc_hout.c'
X#ifndef lint 
Xstatic char sccsid[] = "@(#)rpc_hout.c 1.1 86/03/26 (C) 1986 SMI";
X#endif
X 
X/*
X * rpc_hout.c, Header file outputter for the RPC protocol compiler
X * Copyright (C) 1986, Sun Microsystems, Inc.
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include "rpc_util.h"
X#include "rpc_parse.h"
X
X
X/*
X * Print the C-version of an xdr definition
X */
Xvoid
Xprint_datadef(def)
X	definition *def;
X{
X	
X	fprintf(fout,"\n");
X	switch (def->def_kind) {
X	case DEF_STRUCT:
X		pstructdef(def);
X		break;
X	case DEF_UNION:
X		puniondef(def);
X		break;
X	case DEF_ARRAY:
X		parraydef(def);
X		break;
X	case DEF_ENUM:
X		penumdef(def);
X		break;
X	case DEF_TYPEDEF:
X		ptypedef(def);
X		break;
X	case DEF_PROGRAM:
X		pprogramdef(def);
X		break;
X	}
X	fprintf(fout,"\n");
X}
X
X/*
X * Declare all of the functions that were written
X */
Xvoid
Xprint_funcdefs()
X{
X	list *l;
X	definition *def;
X
X	for (l = defined; l != NULL; l = l->next) {
X		def = (definition *) l->val;
X		if (def->def_kind != DEF_PROGRAM) {
X			fprintf(fout,"bool_t xdr_%s();\n",def->def_name);
X		}
X	}
X}
X
Xstatic
Xpstructdef(def)
X	definition *def;
X{
X	decl_list *l;
X	char *name = def->def_name;
X
X	fprintf(fout,"struct %s {\n",name);
X	for (l = def->def.st.decls; l != NULL; l = l->next) {
X		pdeclaration(name,&l->decl,1);
X	}
X	fprintf(fout,"};\n");
X	fprintf(fout,"typedef struct %s %s;\n",name,name);
X}
X
Xstatic
Xpuniondef(def)
X	definition *def;
X{
X	case_list *l;
X	char *name = def->def_name;
X	declaration *decl;
X
X	fprintf(fout,"struct %s {\n",name);
X	decl = &def->def.un.enum_decl;
X	fprintf(fout,"\t%s %s;\n",decl->type,decl->name);
X	fprintf(fout,"\tunion {\n");
X	for (l = def->def.un.cases; l != NULL; l = l->next) {
X		pdeclaration(name,&l->case_decl,2);
X	}
X	decl = def->def.un.default_decl;
X	if (decl && ! streq(decl->type,"void")) {
X		pdeclaration(name,decl,2);
X	}
X	fprintf(fout,"\t} %s;\n",name);
X	fprintf(fout,"};\n");
X	fprintf(fout,"typedef struct %s %s;\n",name,name);
X}
X
X
X
Xstatic
Xpdefine(name,num)
X	char *name;
X	char *num;	
X{
X	
X	fprintf(fout,"#define %s %s\n",name,num);
X}
X
Xstatic
Xdprinted(stop,start)
X	proc_list *stop;
X	version_list *start;
X{
X	version_list *vers;
X	proc_list *proc;
X
X	for (vers = start; vers != NULL; vers = vers->next) {
X		for (proc = vers->procs; proc != NULL; proc = proc->next) {
X			if (proc == stop) {
X				return(0);
X			} else if (streq(proc->proc_name,stop->proc_name)) {
X				return(1);
X			}
X		}
X	}
X	abort();	
X	/* NOTREACHED */
X}
X	
X	
Xstatic
Xpprogramdef(def)
X	definition *def;
X{
X	version_list *vers;
X	proc_list *proc;
X
X	pdefine(def->def_name,def->def.pr.prog_num);
X	for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
X		pdefine(vers->vers_name,vers->vers_num);
X		for (proc = vers->procs; proc != NULL; proc = proc->next) {
X			if (! dprinted(proc,def->def.pr.versions)) {
X				pdefine(proc->proc_name,proc->proc_num);
X			}
X		}
X	}
X}
X
X
Xstatic
Xpenumdef(def)
X	definition *def;
X{
X	char *name = def->def_name;
X	enumval_list *l;
X	char *last = NULL;
X	int count = 0;
X
X	fprintf(fout,"enum %s {\n",name);
X	for (l = def->def.en.vals; l != NULL; l = l->next) {
X		fprintf(fout,"\t%s",l->name);
X		if (l->assignment) {
X			fprintf(fout," = %s",l->assignment);
X			last = l->assignment;
X			count = 1;
X		} else {
X			if (last == NULL) {
X				fprintf(fout," = %d",count++);
X			} else {
X				fprintf(fout," = %s + %d",last,count++);
X			}
X		}	
X		fprintf(fout,",\n");
X	}
X	fprintf(fout,"};\n");
X	fprintf(fout,"typedef enum %s %s;\n",name,name);
X}
X
Xstatic
Xparraydef(def)
X	definition *def;
X{
X	char *name = def->def_name;
X	char *atype = def->def.ar.array_type;
X	char *aname = def->def.ar.array_name;
X
X	fprintf(fout,"struct %s {\n",name);
X	fprintf(fout,"\tu_int %s;\n",def->def.ar.len_name);
X	if (streq(atype,"opaque")) {
X		atype = "char";
X	}
X	fprintf(fout,"\t%s *%s;\n",atype,aname);
X	fprintf(fout,"};\n");
X	fprintf(fout,"typedef struct %s %s;\n",name,name);
X}
X	
X
Xstatic
Xptypedef(def)
X	definition *def;
X{
X	char *name = def->def_name;
X	char *old = def->def.ty.old_type;
X	char *prefix = def->def.ty.old_prefix;
X	relation rel = def->def.ty.rel;
X
X	if (! streq(name,old)) {
X		if (streq(old,"string")) {
X			old = "char";
X			rel = REL_POINTER;
X		} else if (streq(old,"opaque")) {
X			old = "char";
X		} else if (streq(old,"bool")) {
X			old = "bool_t";
X		}	
X		fprintf(fout,"typedef ");
X		if (undefined2(old,name) && prefix) {
X			fprintf(fout,"%s ",prefix);
X		}
X		fprintf(fout,"%s ",old);
X		if (rel == REL_POINTER) {
X			fprintf(fout,"*");
X		}
X		fprintf(fout,name);
X		if (rel == REL_VECTOR) {
X			fprintf(fout,"[%s]",def->def.ty.array_max);
X		}
X		fprintf(fout,";\n");
X	}
X}
X
Xstatic
Xpdeclaration(name,dec,tab)
X	char *name;
X	declaration *dec;
X	int tab;
X{	
X	if (streq(dec->type,"void")) {
X		return;
X	}
X	while (tab--) {	
X		fprintf(fout,"\t");
X	}
X	if (streq(dec->type,name) && ! dec->prefix) {
X		fprintf(fout,"struct ");
X	}
X	if (streq(dec->type,"string")) {
X		fprintf(fout,"char *%s",dec->name);
X	} else {
X		if (streq(dec->type,"bool")) {
X			fprintf(fout,"bool_t ");
X		} else if (streq(dec->type,"opaque")) {
X			fprintf(fout,"char ");
X		} else {
X			if (dec->prefix) {
X				if (streq(dec->prefix,"enum")) {
X					fprintf(fout,"enum ");
X				} else {
X					fprintf(fout,"struct ");
X				}
X			}
X			fprintf(fout,"%s ",dec->type);
X		}
X		if (dec->rel == REL_POINTER) {
X			fprintf(fout,"*");
X		}
X		fprintf(fout,dec->name);
X		if (dec->rel == REL_VECTOR) {
X			fprintf(fout,"[%s]",dec->array_max);
X		}
X	}
X	fprintf(fout,";\n");
X}
X
X
X
Xstatic
Xundefined2(type,stop)
X	char *type;
X	char *stop;
X{
X	list *l;
X	definition *def;
X
X	for (l = defined; l != NULL; l = l->next) {
X		def = (definition *) l->val;
X		if (def->def_kind != DEF_PROGRAM) {
X			if (streq(def->def_name,stop)) {
X				return(1);
X			} else if (streq(def->def_name,type)) {
X				return(0);
X			}
X		}
X	}
X	return(1);
X}
SHAR_EOF
if test 5658 -ne "`wc -c < 'rpc/rpcgen/rpc_hout.c'`"
then
	echo shar: "error transmitting 'rpc/rpcgen/rpc_hout.c'" '(should have been 5658 characters)'
fi
chmod 444 'rpc/rpcgen/rpc_hout.c'
fi
echo shar: "extracting 'rpc/rpcgen/rpc_main.c'" '(4370 characters)'
if test -f 'rpc/rpcgen/rpc_main.c'
then
	echo shar: "will not over-write existing file 'rpc/rpcgen/rpc_main.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/rpc_main.c'
X#ifndef lint 
Xstatic char sccsid[] = "@(#)rpc_main.c 1.2 86/04/30 (C) 1986 SMI";
X#endif
X 
X/*
X * rpc_main.c, Top level of the RPC protocol compiler.
X *
X * Copyright (C) 1986, Sun Microsystems, Inc.
X */
X
X#include <stdio.h>
X#include <strings.h>
X#include <sys/file.h>
X#include "rpc_util.h"
X#include "rpc_parse.h"
X#include "rpc_scan.h"
X
Xstatic cflag;
Xstatic hflag;
Xstatic sflag;
Xstatic char *cmdname;
X
Xmain(argc,argv)
X    int argc;
X    char *argv[];
X{
X
X	cmdname = argv[0];
X	if (! parseargs(argc,argv)) {
X		fprintf(stderr,
X			"usage: %s infile\n",cmdname);
X		fprintf(stderr,
X			"       %s [-c | -h] [-o outfile] [infile]\n",cmdname);
X		fprintf(stderr,
X			"       %s [-s udp|tcp]* [-o outfile] [infile]\n",
X			cmdname);
X		exit(1);
X	}
X	if (cflag) {
X		open_input(infile);
X		open_output(outfile,(char*)NULL);
X		c_output();
X	} else if (hflag) {
X		open_input(infile);
X		open_output(outfile,(char*)NULL);
X		h_output();
X	} else if (sflag) {
X		open_input(infile);
X		open_output(outfile,(char*)NULL);
X		s_output(argc,argv);
X	} else {
X		open_input(infile);
X		open_output(infile,".c");
X		c_output();	
X		outfile2 = outfile;
X		reinitialize();
X		open_input(infile);	
X		open_output(infile,".h");
X		h_output();	
X	}
X}
X
Xchar *
Xextend(file,ext)
X	char *file;
X	char *ext;
X{
X	char *res;
X	char *p;
X
X	res = alloc(strlen(file) + strlen(ext) + 1);
X	if (res == NULL) {
X		abort();	
X	}
X	p = rindex(file,'.');
X	if (p == NULL) {
X		return(NULL);
X	}
X	strcpy(res,file);
X	strcpy(res + (p - file),ext);
X	return(res);
X}
X
X	
Xopen_output(file,ext)
X	char *file;
X	char *ext;
X{
X
X	if (file == NULL) {
X		fout = stdout;
X		return;
X	}
X	if (ext != NULL) {
X		if (! (outfile = extend(file, ext))) {
X			fprintf(stderr,"%s: %s has no extension\n",cmdname,file);
X			crash();	
X		}
X	} else {
X		outfile = file;
X	}
X	if (infile != NULL && streq(outfile,infile)) {
X		fprintf(stderr,"%s: output would overwrite %s\n",cmdname,infile);
X		outfile = NULL;
X		crash();
X	}
X	fout = fopen(outfile,"w");	
X	if (fout == NULL) {
X		fprintf(stderr,"%s: unable to open ",cmdname);
X		perror(outfile);
X		crash();	
X	}
X}
X
Xopen_input(file)
X	char *file;
X{
X	if (file == NULL) {
X		fin = stdin;
X		return;
X	}
X	infile = file;
X	fin = fopen(infile,"r");
X	if (fin == NULL) {
X		fprintf(stderr,"%s: unable to open ",cmdname);
X		perror(infile);
X		crash();	
X	}
X}
X
X
Xc_output()
X{
X	definition *def;
X	char *include;	
X
X	fprintf(fout,"#include <rpc/rpc.h>\n");
X	if (infile && (include = extend(infile,".h"))) {
X		fprintf(fout,"#include \"%s\"\n",include);
X		free(include);
X	}
X	scanprint(OFF);
X	while (def = get_definition()) {
X		emit(def);
X	}
X}
X
Xh_output()
X{
X	definition *def;
X
X	scanprint(ON);	
X	while (def = get_definition()) {
X		print_datadef(def);
X	}
X	print_funcdefs();
X}
X
Xs_output(argc,argv)
X	int argc;
X	char *argv[];
X{
X	char *include;	
X
X	scanprint(OFF);
X	fprintf(fout,"#include <stdio.h>\n");
X	fprintf(fout,"#include <rpc/rpc.h>\n");
X	if (infile && (include = extend(infile,".h"))) {
X		fprintf(fout,"#include \"%s\"\n",include);
X		free(include);
X	}
X	while (get_definition()) 
X		;
X	write_most();
X	do_registers(argc,argv);	
X	write_rest();
X}
X
X
Xdo_registers(argc,argv)
X	int argc;
X	char *argv[];
X{
X	int i;
X
X	for (i = 1; i < argc; i++) {
X		if (streq(argv[i],"-s")) {
X			write_register(argv[i+1]);
X			i++;
X		}
X	}
X}
X
Xstatic
Xparseargs(argc,argv)
X	int argc;
X	char *argv[];
X{
X	int i;
X	int j;
X	char c;
X	char flag[(1 << 8*sizeof(char))];
X
X	if (argc < 2) {
X		return(0);
X	}
X
X	flag['c'] = 0;
X	flag['h'] = 0;
X	flag['s'] = 0;
X	flag['o'] = 0;
X	for (i = 1; i < argc; i++) {
X		if (argv[i][0] != '-') {
X			if (infile) {
X				return(0);
X			}
X			infile = argv[i];
X		} else {
X			for (j = 1; argv[i][j] != 0; j++) {
X				switch (c = argv[i][j]) {
X				case 'c':	
X				case 'h':
X					if (flag[c]) {
X						return(0);
X					}
X					flag[c] = 1;	
X					break;
X				case 'o':	
X				case 's':
X					if (argv[i][j-1] != '-' || argv[i][j+1] != 0) {
X						return(0);
X					}
X					flag[c] = 1;
X					if (++i == argc) {
X						return(0);
X					}
X					if (c == 's') {
X						if (! streq(argv[i],"udp") &&
X								! streq(argv[i],"tcp")) {
X							return(0);
X						}
X					} else if (c == 'o') {
X						if (outfile) {
X							return(0);
X						}
X						outfile = argv[i];
X					}
X					goto nextarg;	
X	
X				default:
X					return(0);
X				}
X			}
X		nextarg:
X			;
X		}
X	}
X	cflag = flag['c'];
X	hflag = flag['h'];
X	sflag = flag['s'];
X	if (! cflag && ! hflag && !sflag && (infile == NULL || outfile != NULL)) {
X		return(0);
X	}
X	return(1);
X}
X		
SHAR_EOF
if test 4370 -ne "`wc -c < 'rpc/rpcgen/rpc_main.c'`"
then
	echo shar: "error transmitting 'rpc/rpcgen/rpc_main.c'" '(should have been 4370 characters)'
fi
chmod 444 'rpc/rpcgen/rpc_main.c'
fi
echo shar: "extracting 'rpc/rpcgen/rpc_parse.c'" '(8096 characters)'
if test -f 'rpc/rpcgen/rpc_parse.c'
then
	echo shar: "will not over-write existing file 'rpc/rpcgen/rpc_parse.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/rpc_parse.c'
X#ifndef lint 
Xstatic char sccsid[] = "@(#)rpc_parse.c 1.1 86/03/26 (C) 1986 SMI";
X#endif
X
X/* 
X * rpc_parse.c, Parser for the RPC protocol compiler
X * Copyright (C) 1986 Sun Microsystems, Inc.
X */
X
X#include <stdio.h> 
X#include "rpc_util.h"
X#include "rpc_scan.h"
X#include "rpc_parse.h"
X
X/*
X * return the next definition you see
X */
Xdefinition *
Xget_definition()
X{
X	definition *defp;
X	token tok;
X
X
X	defp = ALLOC(definition);
X	get_token(&tok);
X	switch (tok.kind) {
X	case TOK_STRUCT:
X		def_struct(defp);
X		break;
X	case TOK_UNION:
X		def_union(defp);
X		break;
X	case TOK_TYPEDEF:
X		def_typedef(defp);
X		break;
X	case TOK_ARRAY:
X		def_array(defp);
X		break;
X	case TOK_ENUM:
X		def_enum(defp);
X		break;
X	case TOK_PROGRAM:
X		def_program(defp);	
X		break;
X	case TOK_EOF:
X		return(NULL);	
X		break;
X	default:
X		error("definition keyword expected");
X	}
X	scan(TOK_SEMICOLON,&tok);
X	isdefined(defp);
X	return(defp);
X}
X
Xstatic 
Xisdefined(defp)
X	definition *defp;
X{
X	STOREVAL(&defined,defp); 
X}
X
X
Xstatic
Xdef_struct(defp)
X	definition *defp;
X{
X	token tok;
X	declaration dec;
X	decl_list *decls;
X	decl_list **tailp;
X
X	defp->def_kind = DEF_STRUCT;
X
X	scan(TOK_IDENT,&tok);
X	defp->def_name = tok.str;
X	scan(TOK_LBRACE,&tok);
X	tailp = &defp->def.st.decls;
X	do {
X		get_declaration(&dec,DEF_STRUCT);
X		decls = ALLOC(decl_list);
X		decls->decl = dec;
X		*tailp = decls;
X		tailp = &decls->next;
X		scan(TOK_SEMICOLON,&tok);
X		peek(&tok);	
X	} while (tok.kind != TOK_RBRACE);
X	get_token(&tok);	
X	*tailp = NULL;	
X}
X
Xstatic
Xdef_program(defp)
X	definition *defp;
X{
X	token tok;
X	version_list *vlist;
X	version_list **vtailp;
X	proc_list *plist;
X	proc_list **ptailp;
X	
X	defp->def_kind = DEF_PROGRAM;
X	scan(TOK_IDENT,&tok);
X	defp->def_name = tok.str;
X	scan(TOK_LBRACE,&tok);
X	vtailp = &defp->def.pr.versions;
X	scan(TOK_VERSION,&tok);
X	do {
X		scan(TOK_IDENT,&tok);
X		vlist = ALLOC(version_list);
X		vlist->vers_name = tok.str;
X		scan(TOK_LBRACE,&tok);
X		ptailp = &vlist->procs;
X		do {
X			plist = ALLOC(proc_list);
X			get_type(&plist->res_prefix,&plist->res_type,DEF_PROGRAM);
X			if (streq(plist->res_type,"string") || 
X					streq(plist->res_type,"opaque")) {
X				error("illegal result type");
X			}
X			scan(TOK_IDENT,&tok);
X			plist->proc_name = tok.str;
X			scan(TOK_LPAREN,&tok);
X			get_type(&plist->arg_prefix,&plist->arg_type,DEF_PROGRAM);
X			if (streq(plist->arg_type,"string") || 
X					streq(plist->arg_type,"opaque")) {
X				error("illegal argument type");
X			}
X			scan(TOK_RPAREN,&tok);
X			scan(TOK_EQUAL,&tok);
X			scan_num(&tok);
X			scan(TOK_SEMICOLON,&tok);
X			plist->proc_num = tok.str;
X			*ptailp = plist;
X			ptailp = &plist->next;
X			peek(&tok);
X		} while (tok.kind != TOK_RBRACE);
X		*vtailp = vlist;
X		vtailp = &vlist->next;
X		scan(TOK_RBRACE,&tok);
X		scan(TOK_EQUAL,&tok);
X		scan_num(&tok);
X		vlist->vers_num = tok.str;
X		scan(TOK_SEMICOLON,&tok);
X		scan2(TOK_VERSION,TOK_RBRACE,&tok);
X	} while (tok.kind == TOK_VERSION);
X	scan(TOK_EQUAL, &tok);
X	scan_num(&tok);
X	defp->def.pr.prog_num = tok.str;
X	*vtailp = NULL;
X}
X	
Xstatic	
Xdef_enum(defp)
X	definition *defp;
X{
X	token tok;
X	enumval_list *elist;
X	enumval_list **tailp;
X
X	defp->def_kind = DEF_ENUM;
X	scan(TOK_IDENT,&tok);
X	defp->def_name = tok.str;
X	scan(TOK_LBRACE,&tok);
X	tailp = &defp->def.en.vals;
X	do {
X		scan(TOK_IDENT,&tok);
X		elist = ALLOC(enumval_list);
X		elist->name = tok.str;
X		elist->assignment = NULL;
X		scan3(TOK_COMMA,TOK_RBRACE,TOK_EQUAL,&tok);	
X		if (tok.kind == TOK_EQUAL) {
X			scan_num(&tok);
X			elist->assignment = tok.str;
X			scan2(TOK_COMMA,TOK_RBRACE,&tok);
X		}
X		*tailp = elist;
X		tailp = &elist->next;
X	} while (tok.kind != TOK_RBRACE);
X	*tailp = NULL;
X}
X	
Xstatic
Xdef_array(defp)
X	definition *defp;
X{
X	token tok;
X	declaration dec;
X
X	defp->def_kind = DEF_ARRAY;
X	scan(TOK_IDENT,&tok);
X	defp->def_name = tok.str;
X	scan(TOK_LBRACE,&tok);
X	get_declaration(&dec,DEF_ARRAY);
X	if (! streq(dec.type,"u_int")) {
X		error("array length must be of type unsigned");
X	}
X	if (dec.rel != REL_ALIAS) {
X		error("array length may not be pointer or vector");
X	}
X	scan(TOK_SEMICOLON,&tok);
X	defp->def.ar.len_name = dec.name;
X	get_declaration(&dec,DEF_ARRAY);
X	if (dec.rel != REL_VECTOR) {
X		error("expected array declaration");
X	}
X	if (streq(dec.type,"string")) {
X		error("string declarations don't make sense here");
X	}
X	scan(TOK_SEMICOLON,&tok);
X	defp->def.ar.array_prefix = dec.prefix;
X	defp->def.ar.array_type = dec.type;
X	defp->def.ar.array_name = dec.name;
X	defp->def.ar.array_max = dec.array_max;
X	scan(TOK_RBRACE,&tok);
X}
X
X
X
Xstatic
Xdef_union(defp)
X	definition *defp;
X{ 
X	token tok;
X	declaration dec;
X	case_list *cases;
X	case_list **tailp;
X
X	defp->def_kind = DEF_UNION;
X	scan(TOK_IDENT,&tok);
X	defp->def_name = tok.str;
X	scan(TOK_SWITCH,&tok);
X	scan(TOK_LPAREN,&tok);
X	get_declaration(&dec,DEF_UNION);
X	defp->def.un.enum_decl = dec;
X	tailp = &defp->def.un.cases;
X	scan(TOK_RPAREN,&tok);
X	scan(TOK_LBRACE,&tok);
X	scan(TOK_CASE, &tok);
X	while (tok.kind == TOK_CASE) {
X		scan(TOK_IDENT,&tok);
X		cases = ALLOC(case_list);
X		cases->case_name = tok.str;
X		scan(TOK_COLON,&tok);
X		get_declaration(&dec,DEF_UNION);
X		cases->case_decl = dec;
X		*tailp = cases;
X		tailp = &cases->next;
X		scan(TOK_SEMICOLON,&tok);
X		scan3(TOK_CASE,TOK_DEFAULT,TOK_RBRACE,&tok);
X	}
X	*tailp = NULL;
X	if (tok.kind == TOK_DEFAULT) {
X		scan(TOK_COLON,&tok);
X		get_declaration(&dec,DEF_UNION);
X		defp->def.un.default_decl =  ALLOC(declaration);
X		*defp->def.un.default_decl = dec;
X		scan(TOK_SEMICOLON,&tok);
X		scan(TOK_RBRACE,&tok);
X	}
X}
X
X
Xstatic
Xdef_typedef(defp)
X	definition *defp;
X{ 
X	declaration dec;
X
X	defp->def_kind = DEF_TYPEDEF;
X	get_declaration(&dec,DEF_TYPEDEF);
X	defp->def_name = dec.name;
X	defp->def.ty.old_prefix = dec.prefix;
X	defp->def.ty.old_type = dec.type;
X	defp->def.ty.rel = dec.rel;
X	defp->def.ty.array_max = dec.array_max;
X}
X
X
Xstatic
Xget_declaration(dec,dkind)
X	declaration *dec;
X	defkind dkind;
X{
X	token tok;
X
X	get_type(&dec->prefix,&dec->type,dkind);
X	dec->rel = REL_ALIAS;
X	scan2(TOK_STAR,TOK_IDENT,&tok);
X	if (tok.kind == TOK_STAR) {
X		dec->rel = REL_POINTER;
X		scan(TOK_IDENT,&tok);
X	}
X	dec->name = tok.str; 
X	if (peekscan(TOK_LBRACKET,&tok)) {
X		if (dec->rel == REL_POINTER) {
X			error("no array-of-pointer declarations -- use typedef");
X		}
X		dec->rel = REL_VECTOR;
X		if (streq(dec->type,"string") && peekscan(TOK_RBRACKET,&tok)) {
X			dec->array_max = NULL; 	/* means unspecified */
X		} else {	
X			dec->rel = REL_VECTOR;
X			scan_num(&tok);	
X			dec->array_max = tok.str;
X			scan(TOK_RBRACKET,&tok);
X		}
X	}
X	if (streq(dec->type,"opaque") || streq(dec->type,"string")) {
X		if (dec->rel != REL_VECTOR) {
X			error("vector declaration expected");
X		}
X	} else if (streq(dec->type,"void")) {
X		if (dec->rel != REL_ALIAS) {
X			error("no vector-of-void or pointer-to-void declarations");
X		}
X	}
X}
X
X
Xstatic
Xget_type(prefixp,typep, dkind)
X	char **prefixp;
X	char **typep;
X	defkind dkind;
X{
X	token tok;
X
X	*prefixp = NULL; 
X	get_token(&tok);
X	switch (tok.kind) {
X	case TOK_IDENT:
X		*typep = tok.str;
X		break;
X	case TOK_STRUCT:
X	case TOK_ENUM:
X	case TOK_ARRAY:
X	case TOK_UNION:
X		*prefixp = tok.str;
X		scan(TOK_IDENT,&tok);	
X		*typep = tok.str;
X		break;
X	case TOK_UNSIGNED:
X		unsigned_dec(typep);
X		break;
X	case TOK_SHORT:
X		*typep = "short"; 
X		(void) peekscan(TOK_INT,&tok);
X		break;
X	case TOK_LONG:
X		*typep = "long"; 
X		(void) peekscan(TOK_INT,&tok);
X		break;
X	case TOK_VOID:
X		if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
X			error("voids allowed only inside union and program definitions");
X		}
X		*typep = tok.str;
X		break;
X	case TOK_STRING:
X	case TOK_OPAQUE:
X	case TOK_CHAR:
X	case TOK_INT:
X	case TOK_FLOAT:
X	case TOK_DOUBLE:
X	case TOK_BOOL:
X		*typep = tok.str;
X		break;	
X	default:
X		error("expected type specifier");
X	}
X}
X
X
Xstatic
Xunsigned_dec(typep)
X	char **typep;
X{
X	token tok;
X
X	peek(&tok);
X	switch (tok.kind) {
X	case TOK_CHAR:
X		get_token(&tok);
X		*typep = "u_char";
X		break;
X	case TOK_SHORT:
X		get_token(&tok);
X		*typep = "u_short";
X		(void) peekscan(TOK_INT,&tok);
X		break;
X	case TOK_LONG:
X		get_token(&tok);
X		*typep = "u_long";
X		(void) peekscan(TOK_INT,&tok);
X		break;
X	case TOK_INT:
X		get_token(&tok);
X		*typep = "u_int";
X		break;
X	default:
X		*typep = "u_int";
X		break;
X	}
X}
SHAR_EOF
if test 8096 -ne "`wc -c < 'rpc/rpcgen/rpc_parse.c'`"
then
	echo shar: "error transmitting 'rpc/rpcgen/rpc_parse.c'" '(should have been 8096 characters)'
fi
chmod 444 'rpc/rpcgen/rpc_parse.c'
fi
echo shar: "extracting 'rpc/rpcgen/rpc_parse.h'" '(2141 characters)'
if test -f 'rpc/rpcgen/rpc_parse.h'
then
	echo shar: "will not over-write existing file 'rpc/rpcgen/rpc_parse.h'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/rpc_parse.h'
X/* @(#)rpc_parse.h 1.1 86/03/26 (C) 1986 SMI */
X
X/*
X * rpc_parse.h, Definitions for the RPCL parser 
X * Copyright (C) 1986, Sun Microsystems, Inc.
X */
X
Xenum defkind {
X	DEF_ARRAY,
X	DEF_STRUCT,
X	DEF_UNION,
X	DEF_ENUM,
X	DEF_TYPEDEF,
X	DEF_PROGRAM
X};
Xtypedef enum defkind defkind;
X
Xstruct array_def {
X	char *len_name;
X	char *array_name;
X	char *array_prefix;
X	char *array_type;
X	char *array_max;	
X};
Xtypedef struct array_def array_def;
X
Xenum relation {
X	REL_VECTOR,
X	REL_POINTER,
X	REL_ALIAS,
X};
Xtypedef enum relation relation;
X
Xstruct typedef_def {
X	char *old_prefix;
X	char *old_type;
X	relation rel;
X	char *array_max;
X};
Xtypedef struct typedef_def typedef_def;
X
X
Xstruct enumval_list {
X	char *name;
X	char *assignment;
X	struct enumval_list *next;
X};
Xtypedef struct enumval_list enumval_list;
X
Xstruct enum_def {
X	enumval_list *vals;
X};
Xtypedef struct enum_def enum_def;
X
X
Xstruct declaration {
X	char *prefix;
X	char *type;
X	char *name;
X	relation rel;
X	char *array_max;
X};
Xtypedef struct declaration declaration;
X
X
Xstruct decl_list {
X	declaration decl;
X	struct decl_list *next;
X};
Xtypedef struct decl_list decl_list;
X
Xstruct struct_def {
X	decl_list *decls;
X};
Xtypedef struct struct_def struct_def;
X
X
Xstruct case_list {
X	char *case_name;
X	declaration case_decl;
X	struct case_list *next;
X};
Xtypedef struct case_list case_list;
X
Xstruct union_def {
X	declaration enum_decl;
X	case_list *cases;
X	declaration *default_decl;
X};
Xtypedef struct union_def union_def;
X
X
X
Xstruct proc_list {
X	char *proc_name;
X	char *proc_num;
X	char *arg_type;
X	char *arg_prefix;
X	char *res_type;
X	char *res_prefix;
X	struct proc_list *next;
X};
Xtypedef struct proc_list proc_list;
X
X
Xstruct version_list {
X	char *vers_name;
X	char *vers_num;	
X	proc_list *procs;
X	struct version_list *next;
X};
Xtypedef struct version_list version_list;
X
Xstruct program_def {	
X	char *prog_num;
X	version_list *versions;
X};
Xtypedef struct program_def program_def;
X
Xstruct definition {
X	char *def_name;
X	defkind def_kind;
X	union {
X		array_def ar;
X		struct_def st;
X		union_def un;
X		enum_def en;
X		typedef_def ty;
X		program_def pr;
X	} def;
X};
Xtypedef struct definition definition;
X
Xdefinition *get_definition();
SHAR_EOF
if test 2141 -ne "`wc -c < 'rpc/rpcgen/rpc_parse.h'`"
then
	echo shar: "error transmitting 'rpc/rpcgen/rpc_parse.h'" '(should have been 2141 characters)'
fi
chmod 444 'rpc/rpcgen/rpc_parse.h'
fi
echo shar: "extracting 'rpc/rpcgen/rpc_scan.c'" '(5877 characters)'
if test -f 'rpc/rpcgen/rpc_scan.c'
then
	echo shar: "will not over-write existing file 'rpc/rpcgen/rpc_scan.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/rpc_scan.c'
X#ifndef lint 
Xstatic char sccsid[] = "@(#)rpc_scan.c 1.1 86/03/26 (C) 1986 SMI";
X#endif
X 
X/*
X * rpc_scan.c, Scanner for the RPC protocol compiler
X * Copyright (C) 1986, Sun Microsystems, Inc.
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <strings.h>
X#include "rpc_scan.h"
X#include "rpc_util.h"
X
X#define commentstart(p)	(*(p) == '/' && *((p) + 1) == '*')
X#define commentend(p)	(*(p) == '*' && *((p) + 1) == '/') 
X
Xstatic int pushed = 0;			/* is a token pushed */
Xstatic token lasttok;			/* last token, if pushed */
Xstatic int scan_print;			/* print out directives? */
X
X/*
X * turn printing on or off
X */
Xvoid
Xscanprint(sw) 
X	int sw; 
X{
X	scan_print = sw;
X}
X
X
X/*
X * scan expecting 1 given token
X */
Xvoid
Xscan(expect,tokp)
X	tok_kind expect;
X	token *tokp;
X{
X	get_token(tokp);
X	if (tokp->kind != expect) {
X		expected1(expect);
X	}
X}
X
X/*
X * scan expecting 2 given tokens
X */
Xvoid
Xscan2(expect1,expect2,tokp)
X	tok_kind expect1;
X	tok_kind expect2;
X	token *tokp;
X{
X	get_token(tokp);
X	if (tokp->kind != expect1 && tokp->kind != expect2) {
X		expected2(expect1,expect2);
X	}
X}
X
X/*
X * scan expecting 3 given token
X */
Xvoid
Xscan3(expect1,expect2,expect3,tokp)
X	tok_kind expect1;
X	tok_kind expect2;
X	tok_kind expect3;
X	token *tokp;
X{
X	get_token(tokp);
X	if (tokp->kind != expect1 && tokp->kind != expect2 
X			&& tokp->kind != expect3) {
X		expected3(expect1,expect2,expect3);
X	}
X}
X
X
X/*
X * scan expecting a constant, possibly symbolic
X */
Xvoid
Xscan_num(tokp)
X	token *tokp;
X{
X	get_token(tokp);
X	switch (tokp->kind) {
X	case TOK_CONST:	
X	case TOK_IDENT:
X		break;	
X	default:
X		error("constant or identifier expected");
X	}
X}
X
X
X/*
X * Peek at the next token
X */
Xvoid
Xpeek(tokp)
X	token *tokp;
X{
X	get_token(tokp);
X	unget_token(tokp);
X}
X
X
X/*
X * Peek at the next token and
X * scan it if it matches what you expect
X */
Xint
Xpeekscan(expect,tokp)
X	tok_kind expect;
X	token *tokp;
X{
X	peek(tokp);
X	if (tokp->kind == expect) {
X		get_token(tokp);
X		return(1);
X	}
X	return(0);
X}
X
X
X
X/*
X * Get the next token, printing out any directive that
X * are encountered.
X */
Xvoid
Xget_token(tokp)
X	token *tokp;
X{
X
X	if (pushed) {
X		pushed = 0;
X		*tokp = lasttok;
X		return;
X	}
X	for (;;) {	
X		if (*where == 0) {
X			if (! fgets(curline,MAXLINESIZE,fin)) {
X				tokp->kind = TOK_EOF;
X				*where = 0;
X				return;
X			}
X			where = curline;
X			linenum++;
X		} else if (isspace(*where)) {
X			whitespace();
X		} else if (commentstart(where)) {
X			decomment();
X		} else if (directive(where)) {
X			printdirective(where);
X			*where = 0;
X		} else {
X			break;
X		}
X	}
X	/* 
X	 * 'where' is not whitespace, comment, or directive
X	 * Must be a token!
X	 */
X	switch (*where) {
X	case ':':	tokp->kind = TOK_COLON; where++; break;	
X	case ';':	tokp->kind = TOK_SEMICOLON; where++; break;
X	case ',':	tokp->kind = TOK_COMMA; where++; break;
X	case '=':	tokp->kind = TOK_EQUAL; where++; break;
X	case '*':	tokp->kind = TOK_STAR; where++; break;
X	case '[':	tokp->kind = TOK_LBRACKET; where++; break;
X	case ']':	tokp->kind = TOK_RBRACKET; where++; break;
X	case '{':	tokp->kind = TOK_LBRACE; where++; break;
X	case '}':	tokp->kind = TOK_RBRACE; where++; break;
X	case '(':	tokp->kind = TOK_LPAREN; where++; break;
X	case ')':	tokp->kind = TOK_RPAREN; where++; break;
X
X	case '0': 	 
X	case '1': 
X	case '2':
X	case '3':
X	case '4':
X	case '5':
X	case '6':
X	case '7':
X	case '8':
X	case '9':
X		tokp->kind = TOK_CONST; 
X		findconst(&where,&tokp->str);
X		break;
X
X
X	default:
X		if ( ! (isalpha(*where) || *where == '_')) {
X			char buf[100];
X			char *p;
X
X			sprintf(buf,"illegal character in file: ");
X			p = buf + strlen(buf);
X			if (isprint(*where)) {
X				sprintf(p,"%c",*where);	
X			} else {
X				sprintf(p,"%d",*where);
X			}
X			error(buf);
X		}
X		findkind(&where,tokp);
X		break;
X	}
X}
X
X
X
Xstatic
Xunget_token(tokp)
X	token *tokp;
X{
X	lasttok = *tokp;
X	pushed = 1;
X}
X
X
Xstatic
Xfindconst(str,val)
X	char **str;
X	char **val;
X{
X	char *p;
X	int size;
X
X	p = *str;
X	do {
X		*p++;
X	} while (isdigit(*p));
X	size = p - *str;
X	*val = alloc(size + 1);
X	strncpy(*val,*str,size);
X	(*val)[size] = 0;
X	*str = p;
X}
X
X
X
Xstatic token symbols[] = {
X	{ TOK_UNION,	"union" },
X	{ TOK_SWITCH,	"switch" }, 
X	{ TOK_CASE,	"case" },
X	{ TOK_DEFAULT,	"default" },
X	{ TOK_STRUCT,		"struct" },
X	{ TOK_TYPEDEF,	"typedef" },
X	{ TOK_ENUM,	"enum" },
X	{ TOK_ARRAY,	"array" },
X	{ TOK_OPAQUE,	"opaque" },
X	{ TOK_BOOL,	"bool" },
X	{ TOK_VOID,	"void" },
X	{ TOK_CHAR,	"char" },
X	{ TOK_INT,	"int" },
X	{ TOK_UNSIGNED,	"unsigned" },
X	{ TOK_SHORT,	"short" },
X	{ TOK_LONG,	"long" },
X	{ TOK_FLOAT,	"float" },
X	{ TOK_DOUBLE,	"double" },
X	{ TOK_STRING,	"string" },
X	{ TOK_PROGRAM,	"program" },
X	{ TOK_VERSION,	"version" },
X	{ TOK_EOF,	"??????"},
X};
X
X
Xstatic
Xfindkind(mark,tokp)
X	char **mark;
X	token *tokp;
X{
X
X	int len;
X	token *s;
X	char *str;
X
X	str = *mark;
X	for (s = symbols; s->kind != TOK_EOF; s++) {
X		len = strlen(s->str);
X		if (strncmp(str,s->str,len) == 0) {
X			if (!isalnum(str[len]) && str[len] != '_') {
X				tokp->kind = s->kind;
X				tokp->str = s->str;
X				*mark = str + len;
X				return;	
X			}
X		}
X	}
X	tokp->kind = TOK_IDENT;
X	for (len = 0; isalnum(str[len]) || str[len] == '_'; len++)
X		;
X	tokp->str = alloc(len+1);
X	strncpy(tokp->str,str,len);
X	tokp->str[len] = 0;
X	*mark = str + len;
X}
X
Xstatic
Xwhitespace()
X{
X	while (isspace(*where))
X		where++;
X}
X
Xstatic
Xdecomment()
X{
X	for (where += 2; ! commentend(where) ; where++) {
X		if (*where == 0) {
X			if (! fgets(curline,MAXLINESIZE,fin)) {
X				error("unterminated comment");
X			}
X			linenum++;
X			where = curline - 1;
X		}
X	}
X	where += 2;
X}
X
X
Xstatic
Xdirective(line)
X	char *line;
X{
X	return(line == curline && *line == '#');
X}
X 
Xstatic
Xprintdirective(line)
X	char *line;
X{
X	char *s;
X
X	for (s = line + strlen(line) - 1; s >= line; s--) {
X		if (commentend(s)) {
X			break;	
X		} else if (commentstart(s)) {
X			where = s;
X			*where++ = '\n';
X			*where = 0;	
X			if (scan_print) {
X				fprintf(fout,line);
X			}
X			decomment();
X			return;
X		} 
X	}
X	if (scan_print) {
X		fprintf(fout,line);
X	}
X}				
SHAR_EOF
if test 5877 -ne "`wc -c < 'rpc/rpcgen/rpc_scan.c'`"
then
	echo shar: "error transmitting 'rpc/rpcgen/rpc_scan.c'" '(should have been 5877 characters)'
fi
chmod 444 'rpc/rpcgen/rpc_scan.c'
fi
echo shar: "extracting 'rpc/rpcgen/rpc_scan.h'" '(914 characters)'
if test -f 'rpc/rpcgen/rpc_scan.h'
then
	echo shar: "will not over-write existing file 'rpc/rpcgen/rpc_scan.h'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/rpc_scan.h'
X/* @(#)rpc_scan.h 1.1 86/03/26 (C) 1986 SMI */
X
X/*
X * rpc_scan.h, Definitions for the RPCL scanner
X * Copyright (C) 1986, Sun Microsystems, Inc.
X */
X
X/*
X * kinds of tokens
X */
Xenum tok_kind {
X	TOK_IDENT,
X	TOK_CONST,
X	TOK_LPAREN,
X	TOK_RPAREN,
X	TOK_LBRACE,
X	TOK_RBRACE,
X	TOK_LBRACKET,
X	TOK_RBRACKET,
X	TOK_STAR,
X	TOK_COMMA,
X	TOK_EQUAL,
X	TOK_COLON,
X	TOK_SEMICOLON,
X	TOK_STRUCT,
X	TOK_UNION,
X	TOK_SWITCH,
X	TOK_CASE,
X	TOK_DEFAULT,
X	TOK_ENUM,
X	TOK_ARRAY,
X	TOK_TYPEDEF,
X	TOK_INT,
X	TOK_SHORT,
X	TOK_LONG,
X	TOK_UNSIGNED,
X	TOK_FLOAT,
X	TOK_DOUBLE,
X	TOK_OPAQUE,
X	TOK_CHAR,
X	TOK_STRING,
X	TOK_BOOL,
X	TOK_VOID,
X	TOK_PROGRAM,
X	TOK_VERSION,
X	TOK_EOF
X};
Xtypedef enum tok_kind tok_kind;
X
X/*
X * a token
X */
Xstruct token {
X	tok_kind kind;
X	char *str;
X};
Xtypedef struct token token;
X
X
X/*
X * routine interface
X */
Xvoid scanprint();	
Xvoid scan();
Xvoid scan2();
Xvoid scan3();
Xvoid scan_num();
Xvoid peek();
Xint  peekscan();
Xvoid get_token();
X
SHAR_EOF
if test 914 -ne "`wc -c < 'rpc/rpcgen/rpc_scan.h'`"
then
	echo shar: "error transmitting 'rpc/rpcgen/rpc_scan.h'" '(should have been 914 characters)'
fi
chmod 444 'rpc/rpcgen/rpc_scan.h'
fi
echo shar: "extracting 'rpc/rpcgen/rpc_svcout.c'" '(5764 characters)'
if test -f 'rpc/rpcgen/rpc_svcout.c'
then
	echo shar: "will not over-write existing file 'rpc/rpcgen/rpc_svcout.c'"
else
sed 's/^X//' << \SHAR_EOF > 'rpc/rpcgen/rpc_svcout.c'
X#ifndef lint 
Xstatic char sccsid[] = "@(#)rpc_svcout.c 1.1 86/03/26 (C) 1986 SMI";
X#endif
X
X/*
X * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
X * Copyright (C) 1986, Sun Microsytsems, Inc.
X */
X#include <stdio.h>
X#include <strings.h>
X#include "rpc_parse.h"
X#include "rpc_util.h"
X
Xstatic char RQSTP[] = "rqstp";
Xstatic char TRANSP[] = "transp";
Xstatic char ARG[] = "argument";
Xstatic char RESULT[] = "result";
Xstatic char ROUTINE[] = "local";
X
X
X/*
X * write most of the service, that is,
X * everything but the registrations.
X */
Xvoid
Xwrite_most()
X{
X	list *l;
X	definition *def;
X	version_list *vp;
X
X
X	for (l = defined; l != NULL; l = l->next) {
X		def = (definition *) l->val;
X		if (def->def_kind == DEF_PROGRAM) {
X			write_program(def);
X		}
X	}
X	fprintf(fout,"\n\n");
X	fprintf(fout,"main()\n");
X	fprintf(fout,"{\n");
X	fprintf(fout,"\tSVCXPRT *%s;\n",TRANSP);
X	fprintf(fout,"\n");
X	for (l = defined; l != NULL; l = l->next) {
X		def = (definition *) l->val;
X		if (def->def_kind != DEF_PROGRAM) {	
X			continue;
X		}
X		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
X			 fprintf(fout,"\tpmap_unset(%s, %s);\n",def->def_name,vp->vers_name);
X		}
X	}
X}
X
X
X/*
X * write a registration for the given transport
X */
Xvoid
Xwrite_register(transp)
X	char *transp;
X{
X	list *l;
X	definition *def;
X	version_list *vp;
X
X	fprintf(fout,"\n");
X	fprintf(fout,"\t%s = svc%s_create(RPC_ANYSOCK",TRANSP,transp);
X	if (streq(transp,"tcp")) {
X		fprintf(fout,", 0, 0");
X	}
X	fprintf(fout,");\n");
X	fprintf(fout,"\tif (%s == NULL) {\n",TRANSP);
X	fprintf(fout,"\t\tfprintf(stderr,\"cannot create %s service.\\n\");\n",transp);
X	fprintf(fout,"\t\texit(1);\n");
X	fprintf(fout,"\t}\n");
X
X	for (l = defined; l != NULL; l = l->next) {
X		def = (definition *) l->val;
X		if (def->def_kind != DEF_PROGRAM) {	
X			continue;
X		}
X		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
X			fprintf(fout,
X				"\tif (! svc_register(%s, %s, %s, ",
X				TRANSP,def->def_name,vp->vers_name);
X			pvname(def->def_name,vp->vers_num);
X			fprintf(fout,", IPPROTO_%s)) {\n",
X				streq(transp,"udp") ? "UDP" : "TCP");
X	 		fprintf(fout,
X				"\t\tfprintf(stderr,\"unable to register (%s, %s, %s).\\n\");\n",
X				def->def_name,vp->vers_name, transp);
X			fprintf(fout,"\t\texit(1);\n");
X			fprintf(fout,"\t}\n");
X		}
X	}
X}
X
X
X/*
X * write the rest of the service
X */
Xvoid
Xwrite_rest()
X{
X	fprintf(fout,"\tsvc_run();\n");
X	fprintf(fout,"\tfprintf(stderr,\"svc_run returned\\n\");\n");
X	fprintf(fout,"\texit(1);\n");
X	fprintf(fout,"}\n");
X}
X
X
X
Xstatic
Xwrite_program(def)
X	definition *def;
X{
X	version_list *vp;
X	proc_list *proc;
X	int filled;
X
X	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
X		fprintf(fout,"\n");
X		fprintf(fout,"static void\n");
X		pvname(def->def_name, vp->vers_num);
X		fprintf(fout,"(%s, %s)\n",RQSTP,TRANSP);
X		fprintf(fout,"	struct svc_req *%s;\n",RQSTP);
X		fprintf(fout,"	SVCXPRT *%s;\n",TRANSP);
X		fprintf(fout,"{\n");
X
X		filled = 0;	
X		fprintf(fout,"\tunion {\n");
X		for (proc = vp->procs; proc != NULL; proc = proc->next) {
X			if (streq(proc->arg_type,"void")) {
X				continue;
X			}
X			filled = 1;
X			fprintf(fout,"\t\t");	
X			if (proc->arg_prefix) {
X				if (streq(proc->arg_prefix,"enum")) {
X					fprintf(fout,"enum ");
X				} else {
X					fprintf(fout,"struct ");
X				}
X			}
X			fprintf(fout,"%s ",proc->arg_type);
X			pvname(proc->proc_name,vp->vers_num);
X			fprintf(fout,"_arg;\n");
X		}
X		if (! filled) {
X			fprintf(fout,"\t\tint fill;\n");
X		}
X		fprintf(fout,"\t} %s;\n",ARG);
X		fprintf(fout,"\tchar *%s;\n",RESULT);
X		fprintf(fout,"\tbool_t (*xdr_%s)(), (*xdr_%s)();\n",ARG,RESULT);
X		fprintf(fout,"\tchar *(*%s)();\n",ROUTINE);
X		for (proc = vp->procs; proc != NULL; proc = proc->next) {
X			fprintf(fout,"\textern ");
X			if (proc->res_prefix) {
X				fprintf(fout,"%s ",proc->res_prefix);
X			}
X			fprintf(fout,"%s *",proc->res_type);
X			pvname(proc->proc_name,vp->vers_num);
X			fprintf(fout,"();\n");
X		}
X		fprintf(fout,"\n");
X		fprintf(fout,"\tswitch (%s->rq_proc) {\n",RQSTP);
X
X		fprintf(fout,"\tcase NULLPROC:\n");
X		fprintf(fout,"\t\tsvc_sendreply(%s, xdr_void, NULL);\n",TRANSP);
X		fprintf(fout,"\t\treturn;\n\n");
X
X		for (proc = vp->procs; proc != NULL; proc = proc->next) {
X			fprintf(fout,"\tcase %s:\n",proc->proc_name);
X			fprintf(fout,"\t\txdr_%s = xdr_%s;\n",ARG,proc->arg_type);
X			fprintf(fout,"\t\txdr_%s = xdr_%s;\n",RESULT,proc->res_type);
X			fprintf(fout,"\t\t%s = (char *(*)()) ",ROUTINE);
X			pvname(proc->proc_name,vp->vers_num);
X			fprintf(fout,";\n");
X			fprintf(fout,"\t\tbreak;\n\n");
X		}
X		fprintf(fout,"\tdefault:\n");
X		printerr("noproc",TRANSP);
X		fprintf(fout,"\t\treturn;\n");
X		fprintf(fout,"\t}\n");
X
X		fprintf(fout,"\tbzero(&%s, sizeof(%s));\n",ARG,ARG);
X		printif("getargs",TRANSP,"&",ARG);
X		printerr("decode",TRANSP);
X		fprintf(fout,"\t\treturn;\n");
X		fprintf(fout,"\t}\n");
X
X		fprintf(fout,"\t%s = (*%s)(&%s);\n",RESULT,ROUTINE,ARG);
X		printif("sendreply",TRANSP,"",RESULT);
X		printerr("systemerr",TRANSP);
X		fprintf(fout,"\t}\n");
X
X		printif("freeargs",TRANSP,"&",ARG);
X		fprintf(fout,"\t\tfprintf(stderr,\"unable to free arguments\\n\");\n");
X		fprintf(fout,"\t\texit(1);\n");
X		fprintf(fout,"\t}\n");
X
X		fprintf(fout,"}\n\n");
X	}
X}
X	
Xstatic
Xprinterr(err,transp)
X	char *err;
X	char *transp;
X{
X	fprintf(fout,"\t\tsvcerr_%s(%s);\n",err,transp);
X}
X
Xstatic
Xprintif(proc,transp,prefix,arg)
X	char *proc;
X	char *transp;
X	char *prefix;
X	char *arg;
X{
X	fprintf(fout,"\tif (! svc_%s(%s, xdr_%s, %s%s)) {\n",
X		proc,transp,arg,prefix,arg);
X}
X
Xstatic char *
Xlocase(str)
X	char *str;
X{
X	char c;
X	static char buf[100];
X	char *p = buf;
X
X	while (c = *str++) {
X		*p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
X	}
X	*p = 0;
X	return(buf);
X}
X
X
Xstatic
Xpvname(pname,vnum)
X	char *pname;
X	char *vnum;
X{
X	fprintf(fout,"%s_%s",locase(pname),vnum);
X}
X
SHAR_EOF
if test 5764 -ne "`wc -c < 'rpc/rpcgen/rpc_svcout.c'`"
then
	echo shar: "error transmitting 'rpc/rpcgen/rpc_svcout.c'" '(should have been 5764 characters)'
fi
chmod 444 'rpc/rpcgen/rpc_svcout.c'
fi
exit 0
#	End of shell archive