Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 1 Jun 2001 17:34:15 +0200 (MEST)
From:      Jean-Luc.Richier@imag.fr
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   misc/27816: rpcgen dos not generate correct TI-RPC server code
Message-ID:  <200106011534.f51FYFo02634@lagavulin.imag.fr>

next in thread | raw e-mail | index | archive | help

>Number:         27816
>Category:       misc
>Synopsis:       rpcgen -b generates server code which does not compile
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jun 01 08:40:02 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Jean-Luc Richier
>Release:        FreeBSD 5.0-CURRENT i386
>Organization:
IMAG
>Environment:
System: FreeBSD lagavulin.imag.fr 5.0-CURRENT FreeBSD 5.0-CURRENT #1: Wed May 30 20:25:18 MEST 2001 richier@lagavulin.imag.fr:/altroot1a/usr/obj/usr/src/sys/GENERIC i386


>Description:
	FreeBSD5.0-current uses know TI-RPC rpc library. Therefore rpcgen
	should generate TI-RPC code.
	But currently rpcgen generate protmap code by default, and the code
	for servers generated for TI-RPC (rpcgen -b) does not compile,
	for it reference TLI transport functions and not socket transport.

>How-To-Repeat:
	take a rpcsvc file, compile it:
	% cp /usr/include/rpcsvc/rnusers.x .
	% rpcgen -b rnusers.x 
	% cc -o serv rnusers_svc.c 
rnusers_svc.c: In function `closedown':
rnusers_svc.c:58: storage size of `tinfo' isn't known
rnusers_svc.c:60: `T_CLTS' undeclared (first use in this function)
rnusers_svc.c:60: (Each undeclared identifier is reported only once
rnusers_svc.c:60: for each function it appears in.)
rnusers_svc.c: In function `main':
rnusers_svc.c:271: `FMNAMESZ' undeclared (first use in this function)
rnusers_svc.c:271: size of array `mname' has non-integer type
rnusers_svc.c:273: `I_LOOK' undeclared (first use in this function)
rnusers_svc.c:290: `T_DATAXFER' undeclared (first use in this function)
rnusers_svc.c:293: `I_POP' undeclared (first use in this function)
rnusers_svc.c:293: `I_PUSH' undeclared (first use in this function)

>Fix:
Below is a patch to generate correct code.
Some remarks
1/ I kept the old TI-transport code, and added an internal flag
   tirpc_socket (with no option to clear it) to control the generation.
2/ I reversed the -b flag: now TI-RPC is the default.
3/ Even if on many systems option -I (inetd support) is always on,
   I modified rpcgen to generate different code with option -I or
   without (simpler code). So explicit -I is needed for inetd support.
   This choice can be argued.
4/ There are a few corrections in rpcgen.1 and usage function to conform
   to the code.
5/ I kept a support for ``transport monitors'' and the NLSPROVIDER env
   variable, even if the use is not clear in non TLI stream based systems.

*** usr.bin/rpcgen/rpc_main.c.DIST	Sat Apr 14 06:48:36 2001
--- usr.bin/rpcgen/rpc_main.c	Fri Jun  1 17:13:20 2001
***************
*** 124,130 ****

int nonfatalerrors;	/* errors */
#if defined(__FreeBSD__) || defined(__NetBSD__)
! int inetdflag = 0;	/* Support for inetd  is now the default */
  #else
  int inetdflag;	/* Support for inetd  is now the default */
  #endif
--- 124,131 ----
  
  int nonfatalerrors;	/* errors */
  #if defined(__FreeBSD__) || defined(__NetBSD__)
! int inetdflag = 0;
! int tirpc_socket = 1;	/* TI-RPC on socket, no TLI library */
  #else
  int inetdflag;	/* Support for inetd  is now the default */
  #endif
***************
*** 152,162 ****
  int Cflag = 0;		/* ANSI C syntax */
  int CCflag = 0;		/* C++ files */
  static int allfiles;   /* generate all files */
- #if defined(__FreeBSD__) || defined(__NetBSD__)
- int tirpcflag = 0;    /* generating code for tirpc, by default */
- #else
  int tirpcflag = 1;    /* generating code for tirpc, by default */
- #endif
  xdrfunc *xdrfunc_head = NULL; /* xdr function list */
  xdrfunc *xdrfunc_tail = NULL; /* xdr function list */
  pid_t childpid;
--- 153,159 ----
***************
*** 1174,1184 ****
  					 *  generating backward compatible
  					 *  code
  					 */
- #if defined(__FreeBSD__) || defined(__NetBSD__)
- 					tirpcflag = 1;
- #else
  					tirpcflag = 0;
- #endif
  					break;
  
  				case 'I':
--- 1171,1177 ----
***************
*** 1265,1277 ****
  	cmd->makefileflag = flag['M'];
  
  	if (tirpcflag) {
! 		pmflag = inetdflag ? 0 : 1;
! 		/* pmflag or inetdflag is always TRUE */
  		if ((inetdflag && cmd->nflag)) {
  			/* netid not allowed with inetdflag */
  			warnx("cannot use netid flag with inetd flag");
  			return (0);
  		}
  	} else {		/* 4.1 mode */
  		pmflag = 0;	/* set pmflag only in tirpcmode */
  #if !defined(__FreeBSD__) && !defined(__NetBSD__)
--- 1258,1270 ----
  	cmd->makefileflag = flag['M'];
  
  	if (tirpcflag) {
! 		pmflag = inetdflag;	/* generate pm/inetd code */
  		if ((inetdflag && cmd->nflag)) {
  			/* netid not allowed with inetdflag */
  			warnx("cannot use netid flag with inetd flag");
  			return (0);
  		}
+ 		inetdflag = 0;	/* inetdflag only for the case tirpc==0 */
  	} else {		/* 4.1 mode */
  		pmflag = 0;	/* set pmflag only in tirpcmode */
  #if !defined(__FreeBSD__) && !defined(__NetBSD__)
***************
*** 1329,1360 ****
  	f_print(stderr, "options:\n");
  	f_print(stderr, "-a\t\tgenerate all files, including samples\n");
  	f_print(stderr, "-b\t\tbackward compatibility mode (generates code\
! for SunOS 4.X)\n");
  	f_print(stderr, "-c\t\tgenerate XDR routines\n");
  	f_print(stderr, "-C\t\tANSI C mode\n");
  	f_print(stderr, "-Dname[=value]\tdefine a symbol (same as #define)\n");
  	f_print(stderr, "-h\t\tgenerate header file\n");
  	f_print(stderr, "-i size\t\tsize at which to start generating\
! inline code\n");
! 	f_print(stderr, "-I\t\tgenerate code for inetd support in server\
! (for SunOS 4.X)\n");
  	f_print(stderr, "-K seconds\tserver exits after K seconds of\
! inactivity\n");
  	f_print(stderr, "-l\t\tgenerate client side stubs\n");
  	f_print(stderr, "-L\t\tserver errors will be printed to syslog\n");
  	f_print(stderr, "-m\t\tgenerate server side stubs\n");
  	f_print(stderr, "-M\t\tgenerate MT-safe code\n");
  	f_print(stderr, "-n netid\tgenerate server code that supports\
! named netid\n");
  	f_print(stderr, "-N\t\tsupports multiple arguments and\
! call-by-value\n");
  	f_print(stderr, "-o outfile\tname of the output file\n");
  	f_print(stderr, "-s nettype\tgenerate server code that supports named\
! nettype\n");
  	f_print(stderr, "-Sc\t\tgenerate sample client code that uses remote\
! procedures\n");
  	f_print(stderr, "-Ss\t\tgenerate sample server code that defines\
! remote procedures\n");
  	f_print(stderr, "-Sm \t\tgenerate makefile template \n");
  
  	f_print(stderr, "-t\t\tgenerate RPC dispatch table\n");
--- 1322,1352 ----
  	f_print(stderr, "options:\n");
  	f_print(stderr, "-a\t\tgenerate all files, including samples\n");
  	f_print(stderr, "-b\t\tbackward compatibility mode (generates code\
!  for SunOS 4.X)\n");
  	f_print(stderr, "-c\t\tgenerate XDR routines\n");
  	f_print(stderr, "-C\t\tANSI C mode\n");
  	f_print(stderr, "-Dname[=value]\tdefine a symbol (same as #define)\n");
  	f_print(stderr, "-h\t\tgenerate header file\n");
  	f_print(stderr, "-i size\t\tsize at which to start generating\
!  inline code\n");
! 	f_print(stderr, "-I\t\tgenerate code for inetd support in server\n");
  	f_print(stderr, "-K seconds\tserver exits after K seconds of\
!  inactivity\n");
  	f_print(stderr, "-l\t\tgenerate client side stubs\n");
  	f_print(stderr, "-L\t\tserver errors will be printed to syslog\n");
  	f_print(stderr, "-m\t\tgenerate server side stubs\n");
  	f_print(stderr, "-M\t\tgenerate MT-safe code\n");
  	f_print(stderr, "-n netid\tgenerate server code that supports\
!  named netid\n");
  	f_print(stderr, "-N\t\tsupports multiple arguments and\
!  call-by-value\n");
  	f_print(stderr, "-o outfile\tname of the output file\n");
  	f_print(stderr, "-s nettype\tgenerate server code that supports named\
!  nettype\n");
  	f_print(stderr, "-Sc\t\tgenerate sample client code that uses remote\
!  procedures\n");
  	f_print(stderr, "-Ss\t\tgenerate sample server code that defines\
!  remote procedures\n");
  	f_print(stderr, "-Sm \t\tgenerate makefile template \n");
  
  	f_print(stderr, "-t\t\tgenerate RPC dispatch table\n");
*** usr.bin/rpcgen/rpc_svcout.c.DIST	Mon Mar 19 15:52:21 2001
--- usr.bin/rpcgen/rpc_svcout.c	Mon May 14 18:20:55 2001
***************
*** 44,49 ****
--- 44,51 ----
  #include "rpc_parse.h"
  #include "rpc_util.h"
  
+ extern int tirpc_socket;
+ 
  static char RQSTP[] = "rqstp";
  static char TRANSP[] = "transp";
  static char ARG[] = "argument";
***************
*** 107,113 ****
  		var_type = (nomain? "extern" : "static");
  		f_print(fout, "%s int _rpcpmstart;", var_type);
  		f_print(fout, "\t\t/* Started by a port monitor ? */\n");
! 		if (!tirpcflag) {
  			f_print(fout, "%s int _rpcfdtype;", var_type);
  			f_print(fout, "\n\t\t /* Whether Stream or \
  Datagram ? */\n");
--- 109,115 ----
  		var_type = (nomain? "extern" : "static");
  		f_print(fout, "%s int _rpcpmstart;", var_type);
  		f_print(fout, "\t\t/* Started by a port monitor ? */\n");
! 		if (!tirpcflag || tirpc_socket) {
  			f_print(fout, "%s int _rpcfdtype;", var_type);
  			f_print(fout, "\n\t\t /* Whether Stream or \
  Datagram ? */\n");
***************
*** 154,168 ****
  			}
  			f_print(fout, "\tpid_t pid;\n");
  			f_print(fout, "\tint i;\n");
! 			f_print(fout, "\tchar mname[FMNAMESZ + 1];\n\n");
  
  			if (mtflag & timerflag)
  				f_print(fout, "\tmutex_init(&_svcstate_lock, USYNC_THREAD, NULL);\n");
  
! 			write_pm_most(infile, netflag);
! 			f_print(fout, "\telse {\n");
! 			write_rpc_svc_fg(infile, "\t\t");
! 			f_print(fout, "\t}\n");
  		} else {
  			f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
  			f_print(fout, "\n");
--- 156,179 ----
  			}
  			f_print(fout, "\tpid_t pid;\n");
  			f_print(fout, "\tint i;\n");
! 			if (pmflag) {
! 				if (tirpc_socket) {
! 					f_print(fout, "\tstruct sockaddr_storage saddr;\n");
! 					f_print(fout, "\tint asize = sizeof (saddr);\n\n");
! 				} else
! 					f_print(fout, "\tchar mname[FMNAMESZ + 1];\n\n");
! 			}
  
  			if (mtflag & timerflag)
  				f_print(fout, "\tmutex_init(&_svcstate_lock, USYNC_THREAD, NULL);\n");
  
! 			if (pmflag) {
! 				write_pm_most(infile, netflag);
! 				f_print(fout, "\telse {\n");
! 				write_rpc_svc_fg(infile, "\t\t");
! 				f_print(fout, "\t}\n");
! 			} else
! 				write_rpc_svc_fg(infile, "\t");
  		} else {
  			f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
  			f_print(fout, "\n");
***************
*** 170,176 ****
  		}
  	}
  
! 	if (logflag && !inetdflag) {
  		open_log_file(infile, "\t");
  	}
  }
--- 181,187 ----
  		}
  	}
  
! 	if (logflag && !inetdflag && !pmflag) {
  		open_log_file(infile, "\t");
  	}
  }
***************
*** 802,808 ****
  	f_print(fout, "\t\textern fd_set svc_fdset;\n");
  	f_print(fout, "\t\tstatic int size;\n");
  	f_print(fout, "\t\tint i, openfd;\n");
! 	if (tirpcflag && pmflag) {
  		f_print(fout, "\t\tstruct t_info tinfo;\n\n");
  		f_print(fout,
  			"\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n");
--- 813,819 ----
  	f_print(fout, "\t\textern fd_set svc_fdset;\n");
  	f_print(fout, "\t\tstatic int size;\n");
  	f_print(fout, "\t\tint i, openfd;\n");
! 	if (!tirpc_socket && (tirpcflag && pmflag)) {
  		f_print(fout, "\t\tstruct t_info tinfo;\n\n");
  		f_print(fout,
  			"\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n");
***************
*** 856,864 ****
  	definition *def;
  	version_list *vp;
  
! 	f_print(fout, "\tif (!ioctl(0, I_LOOK, mname) &&\n");
! 	f_print(fout, "\t\t(!strcmp(mname, \"sockmod\") ||");
! 	f_print(fout, " !strcmp(mname, \"timod\"))) {\n");
  	f_print(fout, "\t\tchar *netid;\n");
  	if (!netflag) {	/* Not included by -n option */
  		f_print(fout, "\t\tstruct netconfig *nconf = NULL;\n");
--- 867,881 ----
  	definition *def;
  	version_list *vp;
  
! 	if (tirpc_socket) {
! 		f_print(fout,
! 		"\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
! 		f_print(fout, "\t\tint ssize = sizeof (int);\n");
! 	} else {
! 		f_print(fout, "\tif (!ioctl(0, I_LOOK, mname) &&\n");
! 		f_print(fout, "\t\t(!strcmp(mname, \"sockmod\") ||");
! 		f_print(fout, " !strcmp(mname, \"timod\"))) {\n");
! 	}
  	f_print(fout, "\t\tchar *netid;\n");
  	if (!netflag) {	/* Not included by -n option */
  		f_print(fout, "\t\tstruct netconfig *nconf = NULL;\n");
***************
*** 871,876 ****
--- 888,901 ----
   *  f_print(fout, "\t\textern char *getenv();\n");
   */
  	f_print(fout, "\n");
+ 	if (tirpc_socket) {
+ 		f_print(fout, "\t\tif (saddr.ss_family != AF_INET &&\n");
+ 		f_print(fout, "\t\t    saddr.ss_family != AF_INET6)\n");
+ 		f_print(fout, "\t\t\texit(1);\n");
+ 		f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n");
+ 		f_print(fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
+ 		f_print(fout, "\t\t\texit(1);\n");
+ 	}
  	f_print(fout, "\t\t_rpcpmstart = 1;\n");
  	open_log_file(infile, "\t\t");
  	f_print(fout, "\n\t\tif ((netid = \
***************
*** 885,907 ****
  	f_print(fout, "\t\t\tif ((nconf = getnetconfigent(netid)) == NULL)\n");
  	sprintf(_errbuf, "cannot get transport info");
  	print_err_message("\t\t\t\t");
! 	if (timerflag)
! 		f_print(fout, "\n\t\t\tpmclose = \
  (t_getstate(0) != T_DATAXFER);\n");
  	f_print(fout, "\t\t}\n");
  	/*
  	 * A kludgy support for inetd services. Inetd only works with
  	 * sockmod, and RPC works only with timod, hence all this jugglery
  	 */
! 	f_print(fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n");
! 	f_print(fout,
! 		"\t\t\tif (ioctl(0, I_POP, 0) || \
  ioctl(0, I_PUSH, \"timod\")) {\n");
! 	sprintf(_errbuf, "could not get the right module");
! 	print_err_message("\t\t\t\t");
! 	f_print(fout, "\t\t\t\texit(1);\n");
! 	f_print(fout, "\t\t\t}\n");
! 	f_print(fout, "\t\t}\n");
  	f_print(fout,
  		"\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) \
  == NULL) {\n",
--- 910,938 ----
  	f_print(fout, "\t\t\tif ((nconf = getnetconfigent(netid)) == NULL)\n");
  	sprintf(_errbuf, "cannot get transport info");
  	print_err_message("\t\t\t\t");
! 	if (timerflag) {
! 		if (tirpc_socket)
! 			f_print(fout, "\n\t\t\tpmclose = 1;\t/* XXX */\n");
! 		else
! 			f_print(fout, "\n\t\t\tpmclose = \
  (t_getstate(0) != T_DATAXFER);\n");
+ 	}
  	f_print(fout, "\t\t}\n");
  	/*
  	 * A kludgy support for inetd services. Inetd only works with
  	 * sockmod, and RPC works only with timod, hence all this jugglery
  	 */
! 	if (!tirpc_socket) {
! 		f_print(fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n");
! 		f_print(fout,
! 			"\t\t\tif (ioctl(0, I_POP, 0) || \
  ioctl(0, I_PUSH, \"timod\")) {\n");
! 		sprintf(_errbuf, "could not get the right module");
! 		print_err_message("\t\t\t\t");
! 		f_print(fout, "\t\t\t\texit(1);\n");
! 		f_print(fout, "\t\t\t}\n");
! 		f_print(fout, "\t\t}\n");
! 	}
  	f_print(fout,
  		"\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) \
  == NULL) {\n",
***************
*** 991,1000 ****
  		f_print(fout, "%s\t(void) close(i);\n", sp);
  		f_print(fout, "%s}\n", sp);
  	}
! 	if (!logflag)
  		open_log_file(infile, sp);
  	f_print(fout, "#endif\n");
! 	if (logflag)
  		open_log_file(infile, sp);
  }
  
--- 1022,1031 ----
  		f_print(fout, "%s\t(void) close(i);\n", sp);
  		f_print(fout, "%s}\n", sp);
  	}
! 	if (!logflag && (!tirpcflag || pmflag))
  		open_log_file(infile, sp);
  	f_print(fout, "#endif\n");
! 	if (logflag && (!tirpcflag || pmflag))
  		open_log_file(infile, sp);
  }
  
*** usr.bin/rpcgen/rpcgen.1.DIST	Sat Apr 14 06:48:36 2001
--- usr.bin/rpcgen/rpcgen.1	Fri Jun  1 16:58:08 2001
***************
*** 108,114 ****
  and the sample makefile to
  .Pa makefile.proto . 
  .Pp
! The server created can be started both by the port monitors
  (for example,
  .Xr inetd 8 )
  or by itself.
--- 108,117 ----
  and the sample makefile to
  .Pa makefile.proto . 
  .Pp
! If option
! .Fl I
! is set,
! the server created can be started both by the port monitors
  (for example,
  .Xr inetd 8 )
  or by itself.
***************
*** 117,125 ****
  the file descriptor
  .Em 0
  was passed.
! The name of the transport must be specified
  by setting up the environment variable
! .Ev PM_TRANSPORT .
  When the server generated by
  .Nm
  is executed,
--- 120,128 ----
  the file descriptor
  .Em 0
  was passed.
! The name of the transport may be specified
  by setting up the environment variable
! .Ev NLSPROVIDER .
  When the server generated by
  .Nm
  is executed,
***************
*** 247,260 ****
  code for older versions
  of the operating system.
  .Pp
- Note: in
- .Fx ,
- this compatibility flag is turned on by
- default since
- .Fx
- supports only the older
- .Tn ONC RPC
- library.
  .It Fl c
  Compile into
  .Tn XDR
--- 250,255 ----
***************
*** 324,335 ****
  servers 
  are always logged with
  .Xr syslog 3 .
! .\" .IP
! .\" Note:
! .\" this option is supported for backward compatibility only.
! .\" By default,
! .\" .B rpcgen
! .\" generates servers that can be invoked through portmonitors.
  .Pp
  .It Fl K Ar seconds
  By default, services created using
--- 319,330 ----
  servers 
  are always logged with
  .Xr syslog 3 .
! .Pp
! Note:
! Contrary to some systems, in
! .Fx
! this option is needed to generate 
! servers that can be invoked through portmonitors and inetd.
  .Pp
  .It Fl K Ar seconds
  By default, services created using

>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200106011534.f51FYFo02634>