Remove sunrpc compatibility
[openafs.git] / src / rxgen / rpc_parse.c
index 043f092..2a47fac 100644 (file)
@@ -6,54 +6,45 @@
  * 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.
- * 
+ *
  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- * 
+ *
  * Sun RPC is provided with no support and without any obligation on the
  * part of Sun Microsystems, Inc. to assist in its use, correction,
  * modification or enhancement.
- * 
+ *
  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  * OR ANY PART THEREOF.
- * 
+ *
  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  * or profits or other special, indirect and consequential damages, even if
  * Sun has been advised of the possibility of such damages.
- * 
+ *
  * Sun Microsystems, Inc.
  * 2550 Garcia Avenue
  * Mountain View, California  94043
  */
 
 /*
- * rpc_parse.c, Parser for the RPC protocol compiler 
+ * rpc_parse.c, Parser for the RPC protocol compiler
  * Copyright (C) 1987 Sun Microsystems, Inc.
  */
 #include <afsconfig.h>
 #include <afs/param.h>
 
-RCSID
-    ("$Header$");
+#include <roken.h>
 
-#include <stdlib.h>
-#include <stdio.h>
 #include <ctype.h>
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
+
 #include "rpc_scan.h"
 #include "rpc_parse.h"
 #include "rpc_util.h"
 
 list *proc_defined[MAX_PACKAGES], *special_defined, *typedef_defined,
-    *uniondef_defined;
+    *uniondef_defined, *complex_defined;
 char *SplitStart = NULL;
 char *SplitEnd = NULL;
 char *MasterPrefix = NULL;
@@ -77,6 +68,7 @@ int combinepackages = 0;
 int PackageIndex = -1;
 int PerProcCounter = 0;
 int Multi_Init = 0;
+int StatIndex = -1;
 
 /*
  * Character arrays to keep list of function names as we process the file
@@ -90,7 +82,6 @@ int function_list_index;
 /* static prototypes */
 static void isdefined(definition * defp);
 static void def_struct(definition * defp);
-static void def_program(definition * defp);
 static void def_enum(definition * defp);
 static void def_const(definition * defp);
 static void def_union(definition * defp);
@@ -134,22 +125,29 @@ static void cs_ProcMarshallInParams_setup(definition * defp, int split_flag);
 static void cs_ProcSendPacket_setup(definition * defp, int split_flag);
 static void cs_ProcUnmarshallOutParams_setup(definition * defp);
 static void cs_ProcTail_setup(definition * defp, int split_flag);
+static void ucs_ProcName_setup(definition * defp, char *procheader,
+                             int split_flag);
+static void ucs_ProcParams_setup(definition * defp, int split_flag);
+static void ucs_ProcTail_setup(definition * defp, int split_flag);
 static void ss_Proc_CodeGeneration(definition * defp);
 static void ss_ProcName_setup(definition * defp);
-static void ss_ProcParams_setup(definition * defp, int *somefrees);
-static void ss_ProcSpecial_setup(definition * defp, int *somefrees);
+static void ss_ProcParams_setup(definition * defp);
+static void ss_ProcSpecial_setup(definition * defp);
 static void ss_ProcUnmarshallInParams_setup(definition * defp);
 static void ss_ProcCallRealProc_setup(definition * defp);
 static void ss_ProcMarshallOutParams_setup(definition * defp);
-static void ss_ProcTail_setup(definition * defp, int somefrees);
+static void ss_ProcTail_setup(definition * defp);
 static int opcode_holes_exist(void);
 static void er_ProcDeclExterns_setup(void);
 static void er_ProcProcsArray_setup(void);
 static void er_ProcMainBody_setup(void);
 static void er_HeadofOldStyleProc_setup(void);
+static void er_HeadofOldStyleProc_setup2(void);
 static void er_BodyofOldStyleProc_setup(void);
+static void er_BodyofOldStyleProc_setup2(void);
 static void proc_er_case(definition * defp);
 static void er_TailofOldStyleProc_setup(void);
+static void er_TailofOldStyleProc_setup2(void);
 
 
 
@@ -163,7 +161,7 @@ get_definition(void)
     token tok;
 
     defp = ALLOC(definition);
-    memset((char *)defp, 0, sizeof(definition));
+    memset(defp, 0, sizeof(definition));
     get_token(&tok);
     switch (tok.kind) {
     case TOK_STRUCT:
@@ -178,15 +176,12 @@ get_definition(void)
     case TOK_ENUM:
        def_enum(defp);
        break;
-    case TOK_PROGRAM:
-       def_program(defp);
-       break;
     case TOK_CONST:
        def_const(defp);
        break;
     case TOK_EOF:
-       return (NULL);
-       break;
+       free(defp);
+       return NULL;
     case TOK_PACKAGE:
        def_package(defp);
        break;
@@ -253,6 +248,7 @@ def_struct(definition * defp)
     declaration dec;
     decl_list *decls;
     decl_list **tailp;
+    int special = 0;
 
     defp->def_kind = DEF_STRUCT;
 
@@ -262,6 +258,11 @@ def_struct(definition * defp)
     tailp = &defp->def.st.decls;
     do {
        get_declaration(&dec, DEF_STRUCT);
+       /* If a structure contains an array, then we're going
+        * to need to be clever about freeing it */
+       if (dec.rel == REL_ARRAY) {
+          special = 1;
+       }
        decls = ALLOC(decl_list);
        decls->decl = dec;
        *tailp = decls;
@@ -271,64 +272,9 @@ def_struct(definition * defp)
     } while (tok.kind != TOK_RBRACE);
     get_token(&tok);
     *tailp = NULL;
-}
 
-static void
-def_program(definition * defp)
-{
-    token tok;
-    version_list *vlist;
-    version_list **vtailp;
-    proc_list *plist;
-    proc_list **ptailp;
-
-    defp->def_kind = DEF_PROGRAM;
-    scan(TOK_IDENT, &tok);
-    defp->def_name = tok.str;
-    scan(TOK_LBRACE, &tok);
-    vtailp = &defp->def.pr.versions;
-    scan(TOK_VERSION, &tok);
-    do {
-       scan(TOK_IDENT, &tok);
-       vlist = ALLOC(version_list);
-       vlist->vers_name = tok.str;
-       scan(TOK_LBRACE, &tok);
-       ptailp = &vlist->procs;
-       do {
-           plist = ALLOC(proc_list);
-           get_type(&plist->res_prefix, &plist->res_type, DEF_PROGRAM);
-           if (streq(plist->res_type, "opaque")) {
-               error("illegal result type");
-           }
-           scan(TOK_IDENT, &tok);
-           plist->proc_name = tok.str;
-           scan(TOK_LPAREN, &tok);
-           get_type(&plist->arg_prefix, &plist->arg_type, DEF_PROGRAM);
-           if (streq(plist->arg_type, "opaque")) {
-               error("illegal argument type");
-           }
-           scan(TOK_RPAREN, &tok);
-           scan(TOK_EQUAL, &tok);
-           scan_num(&tok);
-           scan(TOK_SEMICOLON, &tok);
-           plist->proc_num = tok.str;
-           *ptailp = plist;
-           ptailp = &plist->next;
-           peek(&tok);
-       } while (tok.kind != TOK_RBRACE);
-       *vtailp = vlist;
-       vtailp = &vlist->next;
-       scan(TOK_RBRACE, &tok);
-       scan(TOK_EQUAL, &tok);
-       scan_num(&tok);
-       vlist->vers_num = tok.str;
-       scan(TOK_SEMICOLON, &tok);
-       scan2(TOK_VERSION, TOK_RBRACE, &tok);
-    } while (tok.kind == TOK_VERSION);
-    scan(TOK_EQUAL, &tok);
-    scan_num(&tok);
-    defp->def.pr.prog_num = tok.str;
-    *vtailp = NULL;
+    if (special)
+       STOREVAL(&complex_defined, defp);
 }
 
 static void
@@ -423,6 +369,8 @@ def_typedef(definition * defp)
 {
     declaration dec;
 
+    memset(&dec, 0, sizeof(dec));
+
     defp->def_kind = DEF_TYPEDEF;
     get_declaration(&dec, DEF_TYPEDEF);
     defp->def_name = dec.name;
@@ -463,7 +411,7 @@ get_declaration(declaration * dec, defkind dkind)
        }
        dec->rel = REL_ARRAY;
        if (peekscan(TOK_RANGLE, &tok)) {
-           dec->array_max = "~0";      /* unspecified size, use max */
+           dec->array_max = "~0u";     /* unspecified size, use max */
        } else {
            scan_num(&tok);
            dec->array_max = tok.str;
@@ -512,8 +460,8 @@ get_type(char **prefixp, char **typep, defkind dkind)
        (void)peekscan(TOK_INT, &tok);
        break;
     case TOK_VOID:
-       if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
-           error("voids allowed only inside union and program definitions");
+       if (dkind != DEF_UNION) {
+           error("voids allowed only inside union definitions");
        }
        *typep = tok.str;
        break;
@@ -574,8 +522,11 @@ def_package(definition * defp)
     scan(TOK_IDENT, &tok);
     defp->def_name = tok.str;
     no_of_stat_funcs = 0;
-    if (PackageIndex++ >= MAX_PACKAGES)
+
+    PackageIndex++;
+    if (PackageIndex >= MAX_PACKAGES)
        error("Exceeded upper limit of package statements\n");
+
     function_list_index = 0;
     PackagePrefix[PackageIndex] = tok.str;
     if (MasterPrefix == NULL)
@@ -619,6 +570,7 @@ def_statindex(definition * defp)
     defp->def_name = name;
     defp->def.co = tok.str;
     PackageStatIndex[PackageIndex] = name;
+    StatIndex = atoi(tok.str);
 }
 
 static void
@@ -837,6 +789,7 @@ check_proc(definition * defp, token * tokp, int noname)
            prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
 
     function_list_index++;
+    defp->statindex = no_of_stat_funcs;
     no_of_stat_funcs_header[PackageIndex]++;
     no_of_stat_funcs++;
     *Proc_listp = NULL;
@@ -882,7 +835,7 @@ analyze_ProcParams(definition * defp, token * tokp)
     do {
        get_token(tokp);
        Proc_list = ALLOC(proc1_list);
-       memset((char *)Proc_list, 0, sizeof(proc1_list));
+       memset(Proc_list, 0, sizeof(proc1_list));
        Proc_list->pl.param_flag = 0;
        switch (tokp->kind) {
        case TOK_IN:
@@ -904,7 +857,7 @@ analyze_ProcParams(definition * defp, token * tokp)
        *Proc_listp = Proc_list;
        Proc_listp = &Proc_list->next;
        decls = ALLOC(decl_list);
-       memset((char *)decls, 0, sizeof(decl_list));
+       memset(decls, 0, sizeof(decl_list));
     if (tokp->kind != TOK_RPAREN)
         decls->decl = dec;
        *tailp = decls;
@@ -926,7 +879,7 @@ generate_code(definition * defp, int proc_split_flag, int multi_flag)
        if (Sflag || cflag)
            ss_Proc_CodeGeneration(defp);
     }
-    if (Sflag)
+    if (Sflag || (cflag && xflag && !proc_split_flag) || hflag)
        STOREVAL(&proc_defined[PackageIndex], defp);
 }
 
@@ -935,7 +888,7 @@ static void
 handle_split_proc(definition * defp, int multi_flag)
 {
     char *startname = SplitStart, *endname = SplitEnd;
-    int numofparams;
+    int numofparams = 0;
 
     if (!startname)
        startname = "Start";
@@ -1102,22 +1055,39 @@ cs_Proc_CodeGeneration(definition * defp, int split_flag, char *procheader)
        }
        cs_ProcTail_setup(defp, split_flag);
     }
-}
 
+    if (!kflag && !split_flag && uflag) {
+       ucs_ProcName_setup(defp, "ubik_", split_flag);
+       if (!cflag) {
+           ucs_ProcParams_setup(defp, split_flag);
+           ucs_ProcTail_setup(defp, split_flag);
+       }
+    }
+}
 
 static void
 cs_ProcName_setup(definition * defp, char *procheader, int split_flag)
 {
     proc1_list *plist;
+    char *first_arg;
 
-    if (!cflag) {
+    if (ansic_flag) {
        if (split_flag) {
-           f_print(fout, "int %s%s%s%s(z_call", procheader, prefix,
-                   PackagePrefix[PackageIndex], defp->pc.proc_name);
+           first_arg = "struct rx_call *z_call";
        } else {
-           f_print(fout, "int %s%s%s%s(z_conn", procheader, prefix,
-                   PackagePrefix[PackageIndex], defp->pc.proc_name);
+           first_arg = "struct rx_connection *z_conn";
        }
+    } else {
+       if (split_flag) {
+           first_arg = "z_call";
+       } else {
+           first_arg = "z_conn";
+       }
+    }
+
+    if (!cflag) {
+       f_print(fout, "int %s%s%s%s(%s", procheader, prefix,
+               PackagePrefix[PackageIndex], defp->pc.proc_name, first_arg);
     }
     if ((strlen(procheader) + strlen(prefix) +
         strlen(PackagePrefix[PackageIndex]) + strlen(defp->pc.proc_name)) >=
@@ -1127,24 +1097,41 @@ cs_ProcName_setup(definition * defp, char *procheader, int split_flag)
     if (!cflag) {
        for (plist = defp->pc.plists; plist; plist = plist->next) {
            if (plist->component_kind == DEF_PARAM) {
-               plist->pl.param_flag &= ~PROCESSED_PARAM;
-               f_print(fout, ", %s", plist->pl.param_name);
+               f_print(fout, ",");
+               if (ansic_flag) {
+                   if (plist->pl.param_kind == DEF_INPARAM &&
+                       strcmp(plist->pl.param_type, "char *") == 0) {
+                       f_print(fout, "const ");
+                   }
+                   if (plist->pl.param_flag & OUT_STRING) {
+                       f_print(fout, "%s *%s", plist->pl.param_type,
+                               plist->pl.param_name);
+                   } else {
+                       f_print(fout, "%s %s", plist->pl.param_type,
+                               plist->pl.param_name);
+                   }
+               } else {
+                   f_print(fout, " %s", plist->pl.param_name);
+                   plist->pl.param_flag &= ~PROCESSED_PARAM;
+               }
            }
        }
        f_print(fout, ")\n");
     }
 }
 
-
 static void
 cs_ProcParams_setup(definition * defp, int split_flag)
 {
     proc1_list *plist, *plist1;
 
+    if (ansic_flag)
+       return;
+
     if (!split_flag)
-       f_print(fout, "\tregister struct rx_connection *z_conn;\n");
+       f_print(fout, "\tstruct rx_connection *z_conn;\n");
     if (split_flag) {
-       f_print(fout, "\tregister struct rx_call *z_call;\n");
+       f_print(fout, "\tstruct rx_call *z_call;\n");
     }
     for (plist = defp->pc.plists; plist; plist = plist->next) {
        if (plist->component_kind == DEF_PARAM
@@ -1205,12 +1192,6 @@ cs_ProcMarshallInParams_setup(definition * defp, int split_flag)
     if (!(split_flag > 1) || (noofallparams != 0)) {
        f_print(fout, "\tXDR z_xdrs;\n");
     }
-    /*
-     * Print out client side stat gathering call
-     */
-    if (xflag && split_flag != 1) {
-       f_print(fout, "\tstruct clock __QUEUE, __EXEC;\n");
-    }
 
     if ((!split_flag) || (split_flag == 1)) {
        f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_ENCODE);\n");
@@ -1296,39 +1277,18 @@ cs_ProcTail_setup(definition * defp, int split_flag)
     }
     if (xflag && split_flag != 1) {
        f_print(fout, "\tif (rx_enable_stats) {\n");
-       f_print(fout, "\t    clock_GetTime(&__EXEC);\n");
-       f_print(fout, "\t    clock_Sub(&__EXEC, &z_call->startTime);\n");
-       f_print(fout, "\t    __QUEUE = z_call->startTime;\n");
-       f_print(fout, "\t    clock_Sub(&__QUEUE, &z_call->queueTime);\n");
        if (PackageStatIndex[PackageIndex]) {
-           if (!split_flag) {
-               f_print(fout,
-                       "\t    rx_IncrementTimeAndCount(z_conn->peer, %s,\n",
-                       PackageStatIndex[PackageIndex]);
-           } else {
-               f_print(fout,
-                       "\t    rx_IncrementTimeAndCount(z_call->conn->peer, %s,\n",
-                       PackageStatIndex[PackageIndex]);
-           }
+           f_print(fout,
+                   "\t    rx_RecordCallStatistics(z_call, %s,\n",
+                   PackageStatIndex[PackageIndex]);
        } else {
-           if (!split_flag) {
-               f_print(fout,
-                       "\t    rx_IncrementTimeAndCount(z_conn->peer,\n"
-                       "\t\t(((afs_uint32)(ntohs(z_conn->serviceId) << 16)) \n"
-                       "\t\t| ((afs_uint32)ntohs(z_conn->peer->port))),\n");
-           } else {
-               f_print(fout,
-                       "\t    rx_IncrementTimeAndCount(z_call->conn->peer,\n"
-                       "\t\t(((afs_uint32)(ntohs(z_call->conn->serviceId) << 16)) |\n"
-                       "\t\t((afs_uint32)ntohs(z_call->conn->peer->port))),\n");
-           }
-       }
-       if (xflag) {
-           f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, &__QUEUE, &__EXEC,\n",
-                   no_of_stat_funcs, PackagePrefix[PackageIndex]);
            f_print(fout,
-                   "\t\t&z_call->bytesSent, &z_call->bytesRcvd, 1);\n");
+                   "\t    rx_RecordCallStatistics(z_call, \n"
+                   "\t\t(((afs_uint32)(ntohs(rx_ServiceIdOf(rx_ConnectionOf(z_call))) << 16)) |\n"
+                   "\t\t((afs_uint32)ntohs(rx_PortOf(rx_PeerOf(rx_ConnectionOf(z_call)))))),\n");
        }
+       f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, 1);\n",
+               no_of_stat_funcs, PackagePrefix[PackageIndex]);
        f_print(fout, "\t}\n\n");
     }
     f_print(fout, "\treturn z_result;\n}\n\n");
@@ -1338,17 +1298,15 @@ cs_ProcTail_setup(definition * defp, int split_flag)
 static void
 ss_Proc_CodeGeneration(definition * defp)
 {
-    int somefrees = 0;
-
     defp->can_fail = 0;
     ss_ProcName_setup(defp);
     if (!cflag) {
-       ss_ProcParams_setup(defp, &somefrees);
-       ss_ProcSpecial_setup(defp, &somefrees);
+       ss_ProcParams_setup(defp);
+       ss_ProcSpecial_setup(defp);
        ss_ProcUnmarshallInParams_setup(defp);
        ss_ProcCallRealProc_setup(defp);
        ss_ProcMarshallOutParams_setup(defp);
-       ss_ProcTail_setup(defp, somefrees);
+       ss_ProcTail_setup(defp);
     }
 }
 
@@ -1368,9 +1326,6 @@ ss_ProcName_setup(definition * defp)
                PackagePrefix[PackageIndex], defp->pc.proc_name);
        f_print(fout, "struct rx_call *z_call, XDR *z_xdrs)\n{\n");
        f_print(fout, "\t" "afs_int32 z_result;\n");
-       if (xflag) {
-           f_print(fout, "\tstruct clock __QUEUE, __EXEC;\n");
-       }
 
        for (plist = defp->pc.plists; plist; plist = plist->next)
            if (plist->component_kind == DEF_PARAM) {
@@ -1382,7 +1337,7 @@ ss_ProcName_setup(definition * defp)
 
 
 static void
-ss_ProcParams_setup(definition * defp, int *somefrees)
+ss_ProcParams_setup(definition * defp)
 {
     proc1_list *plist, *plist1;
     list *listp;
@@ -1400,13 +1355,13 @@ ss_ProcParams_setup(definition * defp, int *somefrees)
                }
                f_print(fout, "\t%s %s", plist->pl.param_type,
                        plist->pl.param_name);
-               *pntr = pres;
+               if (pntr)
+                   *pntr = pres;
            } else if (strchr(plist->pl.param_type, '*') == 0) {
                f_print(fout, "\t%s %s", plist->pl.param_type,
                        plist->pl.param_name);
            } else {
                plist->pl.param_flag |= FREETHIS_PARAM;
-               *somefrees = 1;
                f_print(fout, "\t%s %s=(%s)0", plist->pl.param_type,
                        plist->pl.param_name, plist->pl.param_type);
            }
@@ -1421,7 +1376,6 @@ ss_ProcParams_setup(definition * defp, int *somefrees)
                        f_print(fout, ", %s", plist1->pl.param_name);
                    } else {
                        plist1->pl.param_flag |= FREETHIS_PARAM;
-                       *somefrees = 1;
                        f_print(fout, ", *%s=(%s)0", plist1->pl.param_name,
                                plist1->pl.param_type);
                    }
@@ -1442,6 +1396,7 @@ ss_ProcParams_setup(definition * defp, int *somefrees)
                    switch (defp1->pc.rel) {
                    case REL_ARRAY:
                    case REL_POINTER:
+                   default:
                        break;
                    }
                }
@@ -1453,7 +1408,7 @@ ss_ProcParams_setup(definition * defp, int *somefrees)
 
 
 static void
-ss_ProcSpecial_setup(definition * defp, int *somefrees)
+ss_ProcSpecial_setup(definition * defp)
 {
     proc1_list *plist;
     definition *defp1;
@@ -1461,6 +1416,7 @@ ss_ProcSpecial_setup(definition * defp, int *somefrees)
 
     for (listp = special_defined; listp != NULL; listp = listp->next) {
        defp1 = (definition *) listp->val;
+
        for (plist = defp->pc.plists; plist; plist = plist->next) {
            if (plist->component_kind == DEF_PARAM
                && (plist->pl.param_kind == DEF_INPARAM
@@ -1471,41 +1427,60 @@ ss_ProcSpecial_setup(definition * defp, int *somefrees)
                if (streq(string, structname(plist->pl.param_type))) {
                    plist->pl.string_name = spec->sdef.string_name;
                    plist->pl.param_flag |= FREETHIS_PARAM;
-                   *somefrees = 1;
                    fprintf(fout, "\n\t%s.%s = 0;", plist->pl.param_name,
                            spec->sdef.string_name);
                }
            }
        }
     }
-    if (!*somefrees)
-       fprintf(fout, "\n");
     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
        defp1 = (definition *) listp->val;
        for (plist = defp->pc.plists; plist; plist = plist->next) {
            if (plist->component_kind == DEF_PARAM) {
                if (streq(defp1->def_name, structname(plist->pl.param_type))) {
                    plist->pl.param_flag |= FREETHIS_PARAM;
-                   *somefrees = 1;
                    switch (defp1->pc.rel) {
                    case REL_ARRAY:
-                       f_print(fout, "\n\t%s.%s_val = 0;",
-                               plist->pl.param_name, defp1->def_name);
-                       f_print(fout, "\n\t%s.%s_len = 0;",
-                               plist->pl.param_name, defp1->def_name);
                        plist->pl.string_name = alloc(40);
-                       s_print(plist->pl.string_name, "%s_val",
-                               defp1->def_name);
+                       if (brief_flag) {
+                           f_print(fout, "\n\t%s.val = 0;",
+                                   plist->pl.param_name);
+                           f_print(fout, "\n\t%s.len = 0;",
+                                   plist->pl.param_name);
+                           s_print(plist->pl.string_name, "val");
+                       } else {
+                           f_print(fout, "\n\t%s.%s_val = 0;",
+                                   plist->pl.param_name, defp1->def_name);
+                           f_print(fout, "\n\t%s.%s_len = 0;",
+                                   plist->pl.param_name, defp1->def_name);
+                           s_print(plist->pl.string_name, "%s_val",
+                                   defp1->def_name);
+                       }
                        break;
                    case REL_POINTER:
                        f_print(fout, "\n\t%s = 0;", plist->pl.param_name);
                        plist->pl.string_name = NULL;
                        break;
+                   default:
+                       break;
                    }
                }
            }
        }
     }
+    for (listp = complex_defined; listp != NULL; listp = listp->next) {
+       defp1 = (definition *) listp->val;
+       for (plist = defp->pc.plists; plist; plist = plist->next) {
+           if (plist->component_kind == DEF_PARAM) {
+               if (streq(defp1->def_name, structname(plist->pl.param_type))) {
+                   plist->pl.param_flag |= FREETHIS_PARAM;
+                   fprintf(fout, "\n\tmemset(&%s, 0, sizeof(%s));",
+                                plist->pl.param_name, defp1->def_name);
+               }
+           }
+       }
+    }
+
     f_print(fout, "\n");
 }
 
@@ -1601,36 +1576,36 @@ ss_ProcMarshallOutParams_setup(definition * defp)
     }
 }
 
+static void
+ss_ProcTail_frees(char *xdrfunc, int *somefrees) {
+    if (!*somefrees) {
+       f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
+        f_print(fout, "\tif ((!%s)", xdrfunc);
+       *somefrees = 1;
+    } else {
+       f_print(fout, "\n\t    || (!%s)", xdrfunc);
+    }
+}
+
 
 static void
-ss_ProcTail_setup(definition * defp, int somefrees)
+ss_ProcTail_setup(definition * defp)
 {
     proc1_list *plist;
     definition *defp1;
     list *listp;
-    int firsttime = 0;
+    int somefrees = 0;
 
     if (defp->can_fail) {
        f_print(fout, "fail:\n");
     }
+
     for (plist = defp->pc.plists; plist; plist = plist->next) {
        if (plist->component_kind == DEF_PARAM
-           && (plist->pl.param_flag & FREETHIS_PARAM))
-           somefrees = 1;
-    }
-    if (somefrees)
-       f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
-    for (plist = defp->pc.plists; plist; plist = plist->next) {
-       if (plist->component_kind == DEF_PARAM
-           && (plist->pl.param_flag & FREETHIS_PARAM)) {
-           char *dot = "", *extens = "";
-           if (plist->pl.string_name) {
-               dot = ".";
-               extens = plist->pl.string_name;
-           }
-           f_print(fout, "\tif (!%s) goto fail1;\n", plist->scode);
-       }
+               && (plist->pl.param_flag & FREETHIS_PARAM))
+           ss_ProcTail_frees(plist->scode, &somefrees);
     }
+
     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
        defp1 = (definition *) listp->val;
        for (plist = defp->pc.plists; plist; plist = plist->next) {
@@ -1642,19 +1617,16 @@ ss_ProcTail_setup(definition * defp, int somefrees)
                    switch (defp1->pc.rel) {
                    case REL_ARRAY:
                    case REL_POINTER:
-                       if (!somefrees && !firsttime) {
-                           firsttime = 1;
-                           f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
-                       }
-                       somefrees = 1;
-                       f_print(fout, "\tif (!%s) goto fail1;\n",
-                               plist->scode);
+                       ss_ProcTail_frees(plist->scode, &somefrees);
+                       break;
+                   default:
                        break;
                    }
                }
            }
        }
     }
+
     for (listp = uniondef_defined; listp != NULL; listp = listp->next) {
        defp1 = (definition *) listp->val;
        for (plist = defp->pc.plists; plist; plist = plist->next) {
@@ -1664,69 +1636,259 @@ ss_ProcTail_setup(definition * defp, int somefrees)
                && !(plist->pl.param_flag & FREETHIS_PARAM)) {
                if (streq(defp1->def_name, structname(plist->pl.param_type))) {
                    if (plist->pl.param_flag & INDIRECT_PARAM) {
-                       if (!somefrees && !firsttime) {
-                           firsttime = 1;
-                           f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
-                       }
-                       somefrees = 1;
-                       f_print(fout, "\tif (!%s) goto fail1;\n",
-                               plist->scode);
+                       ss_ProcTail_frees(plist->scode, &somefrees);
                    }
                }
            }
        }
     }
 
+    if (somefrees) {
+       f_print(fout, ")\n");
+       f_print(fout, "\t\tz_result = RXGEN_SS_XDRFREE;\n\n");
+    }
+
     if (xflag) {
        f_print(fout, "\tif (rx_enable_stats) {\n");
-       f_print(fout, "\t    clock_GetTime(&__EXEC);\n");
-       f_print(fout, "\t    clock_Sub(&__EXEC, &z_call->startTime);\n");
-       f_print(fout, "\t    __QUEUE = z_call->startTime;\n");
-       f_print(fout, "\t    clock_Sub(&__QUEUE, &z_call->queueTime);\n");
-       f_print(fout, "\t    rx_IncrementTimeAndCount(z_call->conn->peer,");
+       f_print(fout, "\t    rx_RecordCallStatistics(z_call,");
        if (PackageStatIndex[PackageIndex]) {
            f_print(fout, " %s,\n", PackageStatIndex[PackageIndex]);
        } else {
            f_print(fout,
-                   "\n\t\t(((afs_uint32)(ntohs(z_call->conn->serviceId) << 16)) |\n"
-                   "\t\t((afs_uint32)ntohs(z_call->conn->service->servicePort))),\n");
+                   "\n\t\t(((afs_uint32)(ntohs(rx_ServiceIdOf(rx_ConnectionOf(z_call))) << 16)) |\n"
+                   "\t\t((afs_uint32)ntohs(rx_ServiceOf(rx_ConnectionOf(z_call))->servicePort))),\n");
        }
-       f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, &__QUEUE, &__EXEC,\n",
+       f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, 0);\n",
                no_of_stat_funcs, PackagePrefix[PackageIndex]);
-       f_print(fout, "\t\t&z_call->bytesSent, &z_call->bytesRcvd, 0);\n");
        f_print(fout, "\t}\n\n");
     }
 
     f_print(fout, "\treturn z_result;\n");
-    if (somefrees) {
-       f_print(fout, "fail1:\n");
-
-       if (xflag) {
-           f_print(fout, "\tif (rx_enable_stats) {\n");
-           f_print(fout, "\t    clock_GetTime(&__EXEC);\n");
-           f_print(fout, "\t    clock_Sub(&__EXEC, &z_call->startTime);\n");
-           f_print(fout, "\t    __QUEUE = z_call->startTime;\n");
-           f_print(fout, "\t    clock_Sub(&__QUEUE, &z_call->queueTime);\n");
-           f_print(fout,
-                   "\t    rx_IncrementTimeAndCount(z_call->conn->peer,");
-           if (PackageStatIndex[PackageIndex]) {
-               f_print(fout, " %s,\n", PackageStatIndex[PackageIndex]);
+    f_print(fout, "}\n\n");
+}
+
+
+static void
+ucs_ProcName_setup(definition * defp, char *procheader, int split_flag)
+{
+    proc1_list *plist;
+
+    if (!cflag) {
+       if (ansic_flag) {
+           f_print(fout, "int %s%s%s%s(struct ubik_client *aclient, afs_int32 aflags",
+                         procheader, prefix, PackagePrefix[PackageIndex],
+                         defp->pc.proc_name);
+       } else {
+           f_print(fout, "int %s%s%s%s(aclient, aflags", procheader, prefix,
+                         PackagePrefix[PackageIndex], defp->pc.proc_name);
+       }
+    }
+    if ((strlen(procheader) + strlen(prefix) +
+        strlen(PackagePrefix[PackageIndex]) + strlen(defp->pc.proc_name)) >=
+       MAX_FUNCTION_NAME_LEN) {
+       error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
+    }
+    if (!cflag) {
+       for (plist = defp->pc.plists; plist; plist = plist->next) {
+           if (plist->component_kind == DEF_PARAM) {
+               f_print(fout, ",");
+               if (ansic_flag) {
+                   if (plist->pl.param_kind == DEF_INPARAM &&
+                       strcmp(plist->pl.param_type, "char *") == 0) {
+                       f_print(fout, "const ");
+                   }
+                   if (plist->pl.param_flag & OUT_STRING) {
+                       f_print(fout, "%s *%s", plist->pl.param_type,
+                               plist->pl.param_name);
+                   } else {
+                       f_print(fout, "%s %s", plist->pl.param_type,
+                               plist->pl.param_name);
+                   }
+               } else {
+                   plist->pl.param_flag &= ~PROCESSED_PARAM;
+                   f_print(fout, " %s", plist->pl.param_name);
+               }
+           }
+       }
+       f_print(fout, ")\n");
+    }
+}
+
+
+static void
+ucs_ProcParams_setup(definition * defp, int split_flag)
+{
+    proc1_list *plist, *plist1;
+
+    if (ansic_flag)
+       return;
+
+    f_print(fout, "\tstruct ubik_client *aclient;\n\tafs_int32 aflags;\n");
+    for (plist = defp->pc.plists; plist; plist = plist->next) {
+       if (plist->component_kind == DEF_PARAM
+           && !(plist->pl.param_flag & PROCESSED_PARAM)) {
+           if (plist->pl.param_flag & OUT_STRING) {
+               f_print(fout, "\t%s *%s", plist->pl.param_type,
+                       plist->pl.param_name);
            } else {
-               f_print(fout,
-                       "\n\t\t(((afs_uint32)(ntohs(z_call->conn->serviceId) << 16)) |\n"
-                       "\t\t((afs_uint32)ntohs(z_call->conn->service->servicePort))),\n");
+               f_print(fout, "\t%s %s", plist->pl.param_type,
+                       plist->pl.param_name);
            }
-           f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, &__QUEUE, &__EXEC,\n",
-                   no_of_stat_funcs, PackagePrefix[PackageIndex]);
-           f_print(fout,
-                   "\t\t&z_call->bytesSent, &z_call->bytesRcvd, 0);\n");
-           f_print(fout, "\t}\n\n");
+           plist->pl.param_flag |= PROCESSED_PARAM;
+           for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
+               if ((plist1->component_kind == DEF_PARAM)
+                   && streq(plist->pl.param_type, plist1->pl.param_type)
+                   && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
+                   char *star = "";
+                   char *pntr = strchr(plist1->pl.param_type, '*');
+                   if (pntr)
+                       star = "*";
+                   if (plist1->pl.param_flag & OUT_STRING) {
+                       f_print(fout, ", *%s%s", star, plist1->pl.param_name);
+                   } else {
+                       f_print(fout, ", %s%s", star, plist1->pl.param_name);
+                   }
+                   plist1->pl.param_flag |= PROCESSED_PARAM;
+               }
+           }
+           f_print(fout, ";\n");
        }
+    }
+}
 
-       f_print(fout, "\treturn RXGEN_SS_XDRFREE;\n}\n\n");
-    } else {
-       f_print(fout, "}\n\n");
+static void
+ucs_ProcTail_setup(definition * defp, int split_flag)
+{
+    proc1_list *plist;
+
+    f_print(fout, "{\tafs_int32 rcode, code, newHost, thisHost, i, _ucount;\n");
+    f_print(fout, "\tint chaseCount, pass, needsync;\n");
+#if 0 /* goes with block below */
+    f_print(fout, "\tint j, inlist;\n");
+#endif
+    f_print(fout, "\tstruct rx_connection *tc;\n");
+    f_print(fout, "\tstruct rx_peer *rxp;\n");
+    f_print(fout, "\tshort origLevel;\n\n");
+    f_print(fout, "\tif (!aclient)\n");
+    f_print(fout, "\t\treturn UNOENT;\n");
+    f_print(fout, "\tLOCK_UBIK_CLIENT(aclient);\n\n");
+    f_print(fout, "\t restart:\n");
+    f_print(fout, "\torigLevel = aclient->initializationState;\n");
+    f_print(fout, "\trcode = UNOSERVERS;\n");
+    f_print(fout, "\tchaseCount = needsync = 0;\n\n");
+#if 0 /* We should do some sort of caching algorithm for this, but I need to think about it - shadow 26 jun 06 */
+    f_print(fout, "\tinlist = 0;\n");
+    f_print(fout, "\tLOCK_UCLNT_CACHE;\n");
+    f_print(fout, "\tfor (j = 0; ((j < SYNCCOUNT) && calls_needsync[j]); j++) {\n");
+    f_print(fout, "\t\tif (calls_needsync[j] == (int *)%s%s%s) {\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
+    f_print(fout, "\t\t\tinlist = needsync = 1;\n");
+    f_print(fout, "\t\t\tbreak;\n");
+    f_print(fout, "\t\t}\n");
+    f_print(fout, "\t}\n");
+    f_print(fout, "\tUNLOCK_UCLNT_CACHE;\n");
+#endif
+    f_print(fout, "\t/* \n\t* First  pass, we try all servers that are up.\n\t* Second pass, we try all servers.\n\t*/\n");
+    f_print(fout, "\tfor (pass = 0; pass < 2; pass++) {  /*p */\n");
+    f_print(fout, "\t\t/* For each entry in our servers list */\n");
+    f_print(fout, "\t\tfor (_ucount = 0;; _ucount++) {     /*s */\n\n");
+    f_print(fout, "\t\tif (needsync) {\n");
+    f_print(fout, "\t\t\t/* Need a sync site. Lets try to quickly find it */\n");
+    f_print(fout, "\t\t\tif (aclient->syncSite) {\n");
+    f_print(fout, "\t\t\t\tnewHost = aclient->syncSite;        /* already in network order */\n");
+    f_print(fout, "\t\t\t\taclient->syncSite = 0;      /* Will reset if it works */\n");
+    f_print(fout, "\t\t\t} else if (aclient->conns[3]) {\n");
+    f_print(fout, "\t\t\t\t/* If there are fewer than four db servers in a cell,\n");
+    f_print(fout, "\t\t\t\t* there's no point in making the GetSyncSite call.\n");
+    f_print(fout, "\t\t\t\t* At best, it's a wash. At worst, it results in more\n");
+    f_print(fout, "\t\t\t\t* RPCs than you would otherwise make.\n");
+    f_print(fout, "\t\t\t\t*/\n");
+    f_print(fout, "\t\t\t\ttc = aclient->conns[_ucount];\n");
+    f_print(fout, "\t\t\t\tif (tc && rx_ConnError(tc)) {\n");
+    f_print(fout, "\t\t\t\t\taclient->conns[_ucount] = tc = ubik_RefreshConn(tc);\n");
+    f_print(fout, "\t\t\t\t}\n");
+    f_print(fout, "\t\t\t\tif (!tc)\n");
+    f_print(fout, "\t\t\t\t\tbreak;\n");
+    f_print(fout, "\t\t\t\tcode = VOTE_GetSyncSite(tc, &newHost);\n");
+    f_print(fout, "\t\t\t\tif (aclient->initializationState != origLevel)\n");
+    f_print(fout, "\t\t\t\t\tgoto restart;   /* somebody did a ubik_ClientInit */\n");
+    f_print(fout, "\t\t\t\tif (code)\n");
+    f_print(fout, "\t\t\t\t\tnewHost = 0;\n");
+    f_print(fout, "\t\t\t\tnewHost = htonl(newHost);   /* convert to network order */\n");
+    f_print(fout, "\t\t\t} else {\n");
+    f_print(fout, "\t\t\t\tnewHost = 0;\n");
+    f_print(fout, "\t\t\t}\n");
+    f_print(fout, "\t\t\tif (newHost) {\n");
+    f_print(fout, "\t\t\t\t/* position count at the appropriate slot in the client\n");
+    f_print(fout, "\t\t\t\t* structure and retry. If we can't find in slot, we'll\n");
+    f_print(fout, "\t\t\t\t* just continue through the whole list \n");
+    f_print(fout, "\t\t\t\t*/\n");
+    f_print(fout, "\t\t\t\tfor (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {\n");
+    f_print(fout, "\t\t\t\t\trxp = rx_PeerOf(aclient->conns[i]);\n");
+    f_print(fout, "\t\t\t\t\tthisHost = rx_HostOf(rxp);\n");
+    f_print(fout, "\t\t\t\t\tif (!thisHost)\n");
+    f_print(fout, "\t\t\t\t\t\tbreak;\n");
+    f_print(fout, "\t\t\t\t\tif (thisHost == newHost) {\n");
+    f_print(fout, "\t\t\t\t\t\tif (chaseCount++ > 2)\n");
+    f_print(fout, "\t\t\t\t\t\t\tbreak;  /* avoid loop asking */\n");
+    f_print(fout, "\t\t\t\t\t\t_ucount = i;  /* this index is the sync site */\n");
+    f_print(fout, "\t\t\t\t\t\tbreak;\n");
+    f_print(fout, "\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n");
+    f_print(fout, "\t\t/*needsync */\n");
+    f_print(fout, "\t\ttc = aclient->conns[_ucount];\n");
+    f_print(fout, "\t\tif (tc && rx_ConnError(tc)) {\n");
+    f_print(fout, "\t\t\taclient->conns[_ucount] = tc = ubik_RefreshConn(tc);\n");
+    f_print(fout, "\t\t}\n");
+    f_print(fout, "\t\tif (!tc)\n");
+    f_print(fout, "\t\t\tbreak;\n\n");
+    f_print(fout, "\t\tif ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {\n");
+    f_print(fout, "\t\t\tcontinue;       /* this guy's down */\n");
+    f_print(fout, "\t\t}\n");
+
+    f_print(fout, "\t\trcode = %s%s%s(tc\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
+    for (plist = defp->pc.plists; plist; plist = plist->next) {
+       if (plist->component_kind == DEF_PARAM) {
+           plist->pl.param_flag &= ~PROCESSED_PARAM;
+           f_print(fout, ", %s", plist->pl.param_name);
+       }
     }
+    f_print(fout, ");\n");
+    f_print(fout, "\t\tif (aclient->initializationState != origLevel) {\n");
+    f_print(fout, "\t\t\t/* somebody did a ubik_ClientInit */\n");
+    f_print(fout, "\t\t\tif (rcode)\n");
+    f_print(fout, "\t\t\t\tgoto restart;       /* call failed */\n");
+    f_print(fout, "\t\t\telse\n");
+    f_print(fout, "\t\t\t\tgoto done;  /* call suceeded */\n");
+    f_print(fout, "\t\t}\n");
+    f_print(fout, "\t\tif (rcode < 0) {    /* network errors */\n");
+    f_print(fout, "\t\t\taclient->states[_ucount] |= CFLastFailed; /* Mark server down */\n");
+    f_print(fout, "\t\t} else if (rcode == UNOTSYNC) {\n");
+    f_print(fout, "\t\t\tneedsync = 1;\n");
+    f_print(fout, "\t\t} else if (rcode != UNOQUORUM) {\n");
+    f_print(fout, "\t\t\t/* either misc ubik code, or misc appl code, or success. */\n");
+    f_print(fout, "\t\t\taclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/\n");
+    f_print(fout, "\t\t\tgoto done;      /* all done */\n");
+    f_print(fout, "\t\t}\n");
+    f_print(fout, "\t\t}                       /*s */\n");
+    f_print(fout, "\t}                           /*p */\n\n");
+    f_print(fout, "\tdone:\n");
+    f_print(fout, "\tif (needsync) {\n");
+
+#if 0 /* We should do some sort of caching algorithm for this, but I need to think about it - shadow 26 jun 06 */
+    f_print(fout, "\t\tif (!inlist) {          /* Remember proc call that needs sync site */\n");
+    f_print(fout, "\t\t\tLOCK_UCLNT_CACHE;\n");
+    f_print(fout, "\t\t\tcalls_needsync[synccount % SYNCCOUNT] = (int *)%s%s%s;\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
+    f_print(fout, "\t\t\tsynccount++;\n");
+    f_print(fout, "\t\t\tUNLOCK_UCLNT_CACHE;\n");
+    f_print(fout, "\t\t\tinlist = 1;\n");
+    f_print(fout, "\t\t}\n");
+#endif
+    f_print(fout, "\t\tif (!rcode) {           /* Remember the sync site - cmd successful */\n");
+    f_print(fout, "\t\t\trxp = rx_PeerOf(aclient->conns[_ucount]);\n");
+    f_print(fout, "\t\t\taclient->syncSite = rx_HostOf(rxp);\n");
+    f_print(fout, "\t\t}\n");
+    f_print(fout, "\t}\n");
+    f_print(fout, "\tUNLOCK_UBIK_CLIENT(aclient);\n");
+    f_print(fout, "\treturn rcode;\n}\n\n");
 }
 
 
@@ -1759,6 +1921,9 @@ er_Proc_CodeGeneration(void)
            er_HeadofOldStyleProc_setup();
            er_BodyofOldStyleProc_setup();
            er_TailofOldStyleProc_setup();
+           er_HeadofOldStyleProc_setup2();
+           er_BodyofOldStyleProc_setup2();
+           er_TailofOldStyleProc_setup2();
        } else {
            er_ProcDeclExterns_setup();
            er_ProcProcsArray_setup();
@@ -1775,6 +1940,9 @@ er_ProcDeclExterns_setup(void)
     list *listp;
     definition *defp;
 
+    if ( !Sflag )
+       return;
+
     f_print(fout, "\n");
     for (listp = proc_defined[PackageIndex]; listp != NULL;
         listp = listp->next) {
@@ -1794,25 +1962,35 @@ er_ProcProcsArray_setup(void)
 
     if ((listp = proc_defined[PackageIndex])) {
        defp = (definition *) listp->val;
-       if (defp->pc.proc_serverstub) {
-           f_print(fout, "\nstatic afs_int32 (*StubProcsArray%d[])() = {%s",
-                   PackageIndex, defp->pc.proc_serverstub);
-       } else {
-           f_print(fout,
-                   "\nstatic afs_int32 (*StubProcsArray%d[])(struct rx_call *z_call, XDR *z_xdrs) = {_%s%s%s",
-                   PackageIndex, prefix, defp->pc.proc_prefix,
-                   ((definition *) listp->val)->pc.proc_name);
-           defp = (definition *) listp->val;
+       if ( cflag )  {
+           f_print(fout, "\nstatic char *opnames%d[] = {\"%s%s\"",
+                       PackageIndex, defp->pc.proc_prefix, defp->pc.proc_name);
+       }
+       else {
+           if (defp->pc.proc_serverstub) {
+               f_print(fout, "\nstatic afs_int32 (*StubProcsArray%d[])() = {%s",
+                       PackageIndex, defp->pc.proc_serverstub);
+           } else {
+               f_print(fout,
+                       "\nstatic afs_int32 (*StubProcsArray%d[])(struct rx_call *z_call, XDR *z_xdrs) = {_%s%s%s",
+                       PackageIndex, prefix, defp->pc.proc_prefix,
+                       ((definition *) listp->val)->pc.proc_name);
+           }
        }
        listp = listp->next;
     }
     for (; listp != NULL; listp = listp->next) {
        defp = (definition *) listp->val;
-       if (defp->pc.proc_serverstub) {
-           f_print(fout, ",%s", defp->pc.proc_serverstub);
-       } else {
-           f_print(fout, ", _%s%s%s", prefix, defp->pc.proc_prefix,
-                   defp->pc.proc_name);
+       if ( cflag ) {
+           f_print(fout, ", \"%s%s\"",defp->pc.proc_prefix,defp->pc.proc_name);
+       }
+       else {
+           if (defp->pc.proc_serverstub) {
+               f_print(fout, ",%s", defp->pc.proc_serverstub);
+           } else {
+               f_print(fout, ", _%s%s%s", prefix, defp->pc.proc_prefix,
+                       defp->pc.proc_name);
+           }
        }
     }
     f_print(fout, "};\n\n");
@@ -1822,7 +2000,23 @@ er_ProcProcsArray_setup(void)
 static void
 er_ProcMainBody_setup(void)
 {
-    f_print(fout, "int %s%sExecuteRequest(register struct rx_call *z_call)\n",
+    if ( cflag ) {
+       f_print(fout, "char *%sTranslateOpCode(int op)\n{\n",
+               PackagePrefix[PackageIndex]);
+       f_print(fout, "\tif (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\treturn NULL;\n",
+               PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
+       f_print(fout, "\treturn opnames%d[op - %sLOWEST_OPCODE];\n}\n",
+               PackageIndex, PackagePrefix[PackageIndex]);
+       f_print(fout, "struct %sstats *%sOpCodeStats(int op)\n{\n",
+               PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
+       f_print(fout, "\tif (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\treturn NULL;\n",
+               PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
+       f_print(fout, "\treturn NULL;/*%d %s*/\n}\n",
+               PackageIndex, PackagePrefix[PackageIndex]);
+
+       return;
+    }
+    f_print(fout, "int %s%sExecuteRequest(struct rx_call *z_call)\n",
            prefix, PackagePrefix[PackageIndex]);
     f_print(fout, "{\n\tint op;\n");
     f_print(fout, "\tXDR z_xdrs;\n");
@@ -1839,21 +2033,35 @@ er_ProcMainBody_setup(void)
     f_print(fout, "\treturn hton_syserr_conv(z_result);\n}\n");
 }
 
+static void
+er_HeadofOldStyleProc_setup2(void)
+{
+    if ( cflag ) {
+       f_print(fout, "int %sOpCodeIndex(int op)\n{\n", (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
+        f_print(fout, "\tswitch (op) {\n");
+    }
+}
 
 static void
 er_HeadofOldStyleProc_setup(void)
 {
-    f_print(fout,
-           "\nint %s%sExecuteRequest (register struct rx_call *z_call)\n",
-           prefix,
+    if ( cflag ) {
+       f_print(fout, "char *%sTranslateOpCode(int op)\n{\n",
            (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
-    f_print(fout, "{\n");
-    f_print(fout, "\tint op;\n");
-    f_print(fout, "\tXDR z_xdrs;\n");
-    f_print(fout, "\t" "afs_int32 z_result;\n\n");
-    f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
-    f_print(fout, "\tz_result = RXGEN_DECODE;\n");
-    f_print(fout, "\tif (!xdr_int(&z_xdrs, &op)) goto fail;\n");
+    }
+    else {
+       f_print(fout,
+               "\nint %s%sExecuteRequest (struct rx_call *z_call)\n",
+               prefix,
+               (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
+       f_print(fout, "{\n");
+       f_print(fout, "\tint op;\n");
+       f_print(fout, "\tXDR z_xdrs;\n");
+       f_print(fout, "\t" "afs_int32 z_result;\n\n");
+       f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
+       f_print(fout, "\tz_result = RXGEN_DECODE;\n");
+       f_print(fout, "\tif (!xdr_int(&z_xdrs, &op)) goto fail;\n");
+    }
     f_print(fout, "\tswitch (op) {\n");
 }
 
@@ -1881,6 +2089,12 @@ er_BodyofOldStyleProc_setup(void)
 static void
 proc_er_case(definition * defp)
 {
+    if ( cflag ) {
+       f_print(fout, "\t\tcase %d:", defp->pc.proc_opcodenum);
+       f_print(fout, "\treturn \"%s%s\";\n",
+               defp->pc.proc_prefix, defp->pc.proc_name);
+       return;
+    }
     if (opcodesnotallowed[PackageIndex]) {
        f_print(fout, "\t\tcase %d:\n", defp->pc.proc_opcodenum);
     } else {
@@ -1896,57 +2110,141 @@ proc_er_case(definition * defp)
     f_print(fout, "\t\t\tbreak;\n");
 }
 
+static void
+proc_op_case(definition * defp)
+{
+    f_print(fout, "\t\tcase %d:", defp->pc.proc_opcodenum);
+    f_print(fout, "\treturn %d;\n",
+           defp->statindex);
+}
+
+static void
+er_BodyofOldStyleProc_setup2(void)
+{
+    list *listp;
+
+    if (!cflag)
+       return;
+    if (combinepackages) {
+       int temp = PackageIndex;
+       for (PackageIndex = 0; PackageIndex <= temp; PackageIndex++) {
+           for (listp = proc_defined[PackageIndex]; listp != NULL;
+                listp = listp->next)
+               proc_op_case((definition *) listp->val);
+       }
+       PackageIndex = temp;
+    } else {
+       for (listp = proc_defined[PackageIndex]; listp != NULL;
+            listp = listp->next)
+           proc_op_case((definition *) listp->val);
+    }
+}
+
+static void
+er_TailofOldStyleProc_setup2(void)
+{
+    if ( cflag ) {
+       f_print(fout, "\t\tdefault:\n");
+       f_print(fout, "\t\t\treturn -1;\n\t}\n}\n");
+    }
+}
 
 static void
 er_TailofOldStyleProc_setup(void)
 {
     f_print(fout, "\t\tdefault:\n");
+    if ( cflag ) {
+       f_print(fout, "\t\t\treturn NULL;\n\t}\n}\n");
+       return;
+    }
     f_print(fout, "\t\t\tz_result = RXGEN_OPCODE;\n");
     f_print(fout, "\t\t\tbreak;\n\t}\n");
     f_print(fout, "fail:\n");
     f_print(fout, "\treturn z_result;\n}\n");
 }
 
+static void
+h_ProcMainBody_setup(void)
+{
+    f_print(fout,"\nextern int %s%sExecuteRequest(struct rx_call *);\n",
+           prefix, PackagePrefix[PackageIndex]);
+}
+
+static void
+h_HeadofOldStyleProc_setup(void)
+{
+    char *pprefix = (combinepackages ? MasterPrefix :
+                    PackagePrefix[PackageIndex]);
+    f_print(fout,"\nstruct %sstats{\n\tint statsver;\n};", pprefix);
+    f_print(fout,"\nextern int %s%sExecuteRequest(struct rx_call *);\n",
+           prefix, pprefix);
+    f_print(fout,"\nextern int %sOpCodeIndex(int op);\n", PackagePrefix[PackageIndex]);
+}
+
+void
+h_Proc_CodeGeneration(void)
+{
+    int temp;
+
+    temp = PackageIndex;
+    if (!combinepackages)
+        PackageIndex = 0;
+    for (; PackageIndex <= temp; PackageIndex++) {
+       if (combinepackages || opcode_holes_exist()) {
+           h_HeadofOldStyleProc_setup();
+       } else {
+            h_ProcMainBody_setup();
+       }
+    }
+    PackageIndex = temp;
+}
+
+static void
+proc_h_case(definition * defp)
+{
+    f_print(fout, "#define opcode_%s%s \t((afs_uint64)((%uLL << 32) + %sOpCodeIndex(%u)))\n",
+           defp->pc.proc_prefix, defp->pc.proc_name, StatIndex,
+           defp->pc.proc_prefix, defp->pc.proc_opcodenum);
+}
+
+void
+h_opcode_stats_pkg(char *pprefix, int lowest, int highest, int nops,
+                 int statfuncs, char *ptype, list *proclist)
+{
+    list *listp;
+
+    if (!pprefix)
+       return;
+
+    f_print(fout,
+            "\n/* Opcode-related useful stats for %spackage: %s */\n",
+            ptype, pprefix);
+    f_print(fout, "#define %sLOWEST_OPCODE   %d\n", pprefix, lowest);
+    f_print(fout, "#define %sHIGHEST_OPCODE     %d\n", pprefix, highest);
+    f_print(fout, "#define %sNUMBER_OPCODES     %d\n\n", pprefix, nops);
+
+    for (listp = proclist; listp != NULL;
+         listp = listp->next)
+        proc_h_case((definition *) listp->val);
+
+    if (xflag) {
+        f_print(fout, "#define %sNO_OF_STAT_FUNCS\t%d\n\n",
+                pprefix, statfuncs);
+        f_print(fout, "AFS_RXGEN_EXPORT\n");
+        f_print(fout, "extern const char *%sfunction_names[];\n\n",
+                pprefix);
+    }
+}
 
 void
 h_opcode_stats(void)
 {
     if (combinepackages) {
-       f_print(fout,
-               "\n/* Opcode-related useful stats for Master package: %s */\n",
-               MasterPrefix);
-       f_print(fout, "#define %sLOWEST_OPCODE   %d\n", MasterPrefix,
-               master_lowest_opcode);
-       f_print(fout, "#define %sHIGHEST_OPCODE %d\n", MasterPrefix,
-               master_highest_opcode);
-       f_print(fout, "#define %sNUMBER_OPCODES %d\n\n", MasterPrefix,
-               master_no_of_opcodes);
-       if (xflag) {
-           f_print(fout, "#define %sNO_OF_STAT_FUNCS\t%d\n\n", MasterPrefix,
-                   no_of_stat_funcs_header[0]);
-           f_print(fout, "AFS_RXGEN_EXPORT\n");
-           f_print(fout, "extern const char *%sfunction_names[];\n\n",
-                   MasterPrefix);
-       }
+       h_opcode_stats_pkg(MasterPrefix, master_lowest_opcode, master_highest_opcode, master_no_of_opcodes, no_of_stat_funcs_header[0], "Master ", proc_defined[0]);
     } else {
        int i;
        for (i = 0; i <= PackageIndex; i++) {
-           f_print(fout,
-                   "\n/* Opcode-related useful stats for package: %s */\n",
-                   PackagePrefix[i]);
-           f_print(fout, "#define %sLOWEST_OPCODE   %d\n", PackagePrefix[i],
-                   lowest_opcode[i]);
-           f_print(fout, "#define %sHIGHEST_OPCODE     %d\n",
-                   PackagePrefix[i], highest_opcode[i]);
-           f_print(fout, "#define %sNUMBER_OPCODES     %d\n\n",
-                   PackagePrefix[i], no_of_opcodes[i]);
-           if (xflag) {
-               f_print(fout, "#define %sNO_OF_STAT_FUNCS\t%d\n\n",
-                       PackagePrefix[i], no_of_stat_funcs_header[i]);
-               f_print(fout, "AFS_RXGEN_EXPORT\n");
-               f_print(fout, "extern const char *%sfunction_names[];\n\n",
-                       PackagePrefix[i]);
-           }
+           h_opcode_stats_pkg(PackagePrefix[i], lowest_opcode[i], highest_opcode[i], no_of_opcodes[i], no_of_stat_funcs_header[i], "", proc_defined[i]);
        }
     }
 }