OPENAFS-SA-2018-003 rxgen: prevent unbounded input arrays
[openafs.git] / src / rxgen / rpc_parse.c
1 /* @(#)rpc_parse.c      1.1 87/11/04 3.9 RPCSRC */
2 /*
3  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
4  * unrestricted use provided that this legend is included on all tape
5  * media and as a part of the software program in whole or part.  Users
6  * may copy or modify Sun RPC without charge, but are not authorized
7  * to license or distribute it to anyone else except as part of a product or
8  * program developed by the user.
9  *
10  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13  *
14  * Sun RPC is provided with no support and without any obligation on the
15  * part of Sun Microsystems, Inc. to assist in its use, correction,
16  * modification or enhancement.
17  *
18  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20  * OR ANY PART THEREOF.
21  *
22  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23  * or profits or other special, indirect and consequential damages, even if
24  * Sun has been advised of the possibility of such damages.
25  *
26  * Sun Microsystems, Inc.
27  * 2550 Garcia Avenue
28  * Mountain View, California  94043
29  */
30
31 /*
32  * rpc_parse.c, Parser for the RPC protocol compiler
33  * Copyright (C) 1987 Sun Microsystems, Inc.
34  */
35 #include <afsconfig.h>
36 #include <afs/param.h>
37
38 #include <roken.h>
39
40 #include <ctype.h>
41
42 #include "rpc_scan.h"
43 #include "rpc_parse.h"
44 #include "rpc_util.h"
45
46 list *proc_defined[MAX_PACKAGES], *special_defined, *typedef_defined,
47     *uniondef_defined, *complex_defined;
48 char *SplitStart = NULL;
49 char *SplitEnd = NULL;
50 char *MasterPrefix = NULL;
51 char *ServerPrefix = "";
52 char *PackagePrefix[MAX_PACKAGES];
53 char *PackageStatIndex[MAX_PACKAGES];
54 int no_of_stat_funcs = 0;       /*
55                                  * current function number in client interface
56                                  * starts at 0
57                                  */
58 int no_of_stat_funcs_header[MAX_PACKAGES];      /*
59                                                  * Total number of functions in client
60                                                  * interface
61                                                  */
62 int no_of_opcodes[MAX_PACKAGES], master_no_of_opcodes = 0;
63 int lowest_opcode[MAX_PACKAGES], master_lowest_opcode = 99999;
64 int highest_opcode[MAX_PACKAGES], master_highest_opcode = 0;
65 int master_opcodenumber = 99999;
66 int opcodesnotallowed[MAX_PACKAGES];
67 int combinepackages = 0;
68 int PackageIndex = -1;
69 int PerProcCounter = 0;
70 int Multi_Init = 0;
71 int StatIndex = -1;
72
73 /*
74  * Character arrays to keep list of function names as we process the file
75  */
76
77 char function_list[MAX_PACKAGES]
78     [MAX_FUNCTIONS_PER_PACKAGE]
79     [MAX_FUNCTION_NAME_LEN];
80 int function_list_index;
81
82 /* static prototypes */
83 static void isdefined(definition * defp);
84 static void def_struct(definition * defp);
85 static void def_enum(definition * defp);
86 static void def_const(definition * defp);
87 static void def_union(definition * defp);
88 static void def_typedef(definition * defp);
89 static void get_declaration(declaration * dec, defkind dkind);
90 static void get_type(char **prefixp, char **typep, defkind dkind);
91 static void unsigned_dec(char **typep);
92 static void def_package(definition * defp);
93 static void def_prefix(definition * defp);
94 static void def_statindex(definition * defp);
95 static void def_startingopcode(definition * defp);
96 static void def_split(definition * defp);
97 static void customize_struct(definition * defp);
98 static char *structname(char *name);
99 static void def_special(declaration * dec, definition * defp);
100 static void check_proc(definition * defp, token * tokp, int noname);
101 static int InvalidConstant(char *name);
102 static int opcodenum_is_defined(int opcode_num);
103 static void analyze_ProcParams(definition * defp, token * tokp);
104 static void generate_code(definition * defp, int proc_split_flag,
105                           int multi_flag);
106 static void handle_split_proc(definition * defp, int multi_flag);
107 static void do_split(definition * defp, int direction, int *numofparams,
108                      defkind param_kind, int restore_flag);
109 static void hdle_param_tok(definition * defp, declaration * dec, token * tokp,
110                            defkind par_kind);
111 static void get1_param_type(definition * defp, declaration * dec,
112                             char **param_type);
113 static void get_param_type(definition * defp, declaration * dec,
114                            char **param_type, char **typename);
115 #ifdef undef
116 static void hndle_param_tail(definition * defp, declaration * dec,
117                              token * tokp, char *typename);
118 #endif
119 static void cs_Proc_CodeGeneration(definition * defp, int split_flag,
120                                    char *procheader);
121 static void cs_ProcName_setup(definition * defp, char *procheader,
122                               int split_flag);
123 static void cs_ProcParams_setup(definition * defp, int split_flag);
124 static void cs_ProcMarshallInParams_setup(definition * defp, int split_flag);
125 static void cs_ProcSendPacket_setup(definition * defp, int split_flag);
126 static void cs_ProcUnmarshallOutParams_setup(definition * defp);
127 static void cs_ProcTail_setup(definition * defp, int split_flag);
128 static void ucs_ProcName_setup(definition * defp, char *procheader,
129                               int split_flag);
130 static void ucs_ProcParams_setup(definition * defp, int split_flag);
131 static void ucs_ProcTail_setup(definition * defp, int split_flag);
132 static void ss_Proc_CodeGeneration(definition * defp);
133 static void ss_ProcName_setup(definition * defp);
134 static void ss_ProcParams_setup(definition * defp);
135 static void ss_ProcSpecial_setup(definition * defp);
136 static void ss_ProcUnmarshallInParams_setup(definition * defp);
137 static void ss_ProcCallRealProc_setup(definition * defp);
138 static void ss_ProcMarshallOutParams_setup(definition * defp);
139 static void ss_ProcTail_setup(definition * defp);
140 static int opcode_holes_exist(void);
141 static void er_ProcDeclExterns_setup(void);
142 static void er_ProcProcsArray_setup(void);
143 static void er_ProcMainBody_setup(void);
144 static void er_HeadofOldStyleProc_setup(void);
145 static void er_HeadofOldStyleProc_setup2(void);
146 static void er_BodyofOldStyleProc_setup(void);
147 static void er_BodyofOldStyleProc_setup2(void);
148 static void proc_er_case(definition * defp);
149 static void er_TailofOldStyleProc_setup(void);
150 static void er_TailofOldStyleProc_setup2(void);
151
152
153
154 /*
155  * return the next definition you see
156  */
157 definition *
158 get_definition(void)
159 {
160     definition *defp;
161     token tok;
162
163     defp = ALLOC(definition);
164     memset(defp, 0, sizeof(definition));
165     get_token(&tok);
166     switch (tok.kind) {
167     case TOK_STRUCT:
168         def_struct(defp);
169         break;
170     case TOK_UNION:
171         def_union(defp);
172         break;
173     case TOK_TYPEDEF:
174         def_typedef(defp);
175         break;
176     case TOK_ENUM:
177         def_enum(defp);
178         break;
179     case TOK_CONST:
180         def_const(defp);
181         break;
182     case TOK_EOF:
183         free(defp);
184         return NULL;
185     case TOK_PACKAGE:
186         def_package(defp);
187         break;
188     case TOK_PREFIX:
189         def_prefix(defp);
190         break;
191     case TOK_STATINDEX:
192         def_statindex(defp);
193         break;
194     case TOK_SPECIAL:
195         {
196             declaration dec;
197             def_special(&dec, defp);
198             break;
199         }
200     case TOK_STARTINGOPCODE:
201         def_startingopcode(defp);
202         break;
203     case TOK_CUSTOMIZED:
204         get_token(&tok);
205         def_struct(defp);
206         customize_struct(defp);
207         break;
208     case TOK_SPLITPREFIX:
209         def_split(defp);
210         break;
211     case TOK_PROC:
212         get_token(&tok);
213         if (tok.kind == TOK_LPAREN) {
214             unget_token(&tok);
215             check_proc(defp, &tok, 1);
216         } else
217             check_proc(defp, &tok, 0);
218         break;
219     case TOK_IDENT:
220         check_proc(defp, &tok, 0);
221         break;
222     case TOK_LPAREN:
223         unget_token(&tok);
224         check_proc(defp, &tok, 1);
225         break;
226     default:
227         error("definition keyword expected");
228     }
229     if (!IsRxgenToken(&tok)) {
230         scan(TOK_SEMICOLON, &tok);
231         isdefined(defp);
232     } else
233         pushed = 0;
234     return (defp);
235 }
236
237 static void
238 isdefined(definition * defp)
239 {
240     STOREVAL(&defined, defp);
241 }
242
243
244 static void
245 def_struct(definition * defp)
246 {
247     token tok;
248     declaration dec;
249     decl_list *decls;
250     decl_list **tailp;
251     int special = 0;
252
253     defp->def_kind = DEF_STRUCT;
254
255     scan(TOK_IDENT, &tok);
256     defp->def_name = tok.str;
257     scan(TOK_LBRACE, &tok);
258     tailp = &defp->def.st.decls;
259     do {
260         get_declaration(&dec, DEF_STRUCT);
261         /* If a structure contains an array, then we're going
262          * to need to be clever about freeing it */
263         if (dec.rel == REL_ARRAY) {
264            special = 1;
265         }
266         decls = ALLOC(decl_list);
267         decls->decl = dec;
268         *tailp = decls;
269         tailp = &decls->next;
270         scan(TOK_SEMICOLON, &tok);
271         peek(&tok);
272     } while (tok.kind != TOK_RBRACE);
273     get_token(&tok);
274     *tailp = NULL;
275
276     if (special)
277         STOREVAL(&complex_defined, defp);
278 }
279
280 static void
281 def_enum(definition * defp)
282 {
283     token tok;
284     enumval_list *elist;
285     enumval_list **tailp;
286
287     defp->def_kind = DEF_ENUM;
288     scan(TOK_IDENT, &tok);
289     defp->def_name = tok.str;
290     scan(TOK_LBRACE, &tok);
291     tailp = &defp->def.en.vals;
292     do {
293         scan(TOK_IDENT, &tok);
294         elist = ALLOC(enumval_list);
295         elist->name = tok.str;
296         elist->assignment = NULL;
297         scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
298         if (tok.kind == TOK_EQUAL) {
299             scan_num(&tok);
300             elist->assignment = tok.str;
301             scan2(TOK_COMMA, TOK_RBRACE, &tok);
302         }
303         *tailp = elist;
304         tailp = &elist->next;
305     } while (tok.kind != TOK_RBRACE);
306     *tailp = NULL;
307 }
308
309 static void
310 def_const(definition * defp)
311 {
312     token tok;
313
314     defp->def_kind = DEF_CONST;
315     scan(TOK_IDENT, &tok);
316     defp->def_name = tok.str;
317     scan(TOK_EQUAL, &tok);
318     scan2(TOK_IDENT, TOK_STRCONST, &tok);
319     defp->def.co = tok.str;
320 }
321
322 static void
323 def_union(definition * defp)
324 {
325     token tok;
326     declaration dec;
327     case_list *cases;
328     case_list **tailp;
329
330     defp->def_kind = DEF_UNION;
331     scan(TOK_IDENT, &tok);
332     defp->def_name = tok.str;
333     scan(TOK_SWITCH, &tok);
334     scan(TOK_LPAREN, &tok);
335     get_declaration(&dec, DEF_UNION);
336     defp->def.un.enum_decl = dec;
337     tailp = &defp->def.un.cases;
338     scan(TOK_RPAREN, &tok);
339     scan(TOK_LBRACE, &tok);
340     scan(TOK_CASE, &tok);
341     while (tok.kind == TOK_CASE) {
342         scan(TOK_IDENT, &tok);
343         cases = ALLOC(case_list);
344         cases->case_name = tok.str;
345         scan(TOK_COLON, &tok);
346         get_declaration(&dec, DEF_UNION);
347         cases->case_decl = dec;
348         *tailp = cases;
349         tailp = &cases->next;
350         scan(TOK_SEMICOLON, &tok);
351         scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
352     }
353     *tailp = NULL;
354     if (tok.kind == TOK_DEFAULT) {
355         scan(TOK_COLON, &tok);
356         get_declaration(&dec, DEF_UNION);
357         defp->def.un.default_decl = ALLOC(declaration);
358         *defp->def.un.default_decl = dec;
359         scan(TOK_SEMICOLON, &tok);
360         scan(TOK_RBRACE, &tok);
361     } else {
362         defp->def.un.default_decl = NULL;
363     }
364 }
365
366
367 static void
368 def_typedef(definition * defp)
369 {
370     declaration dec;
371
372     memset(&dec, 0, sizeof(dec));
373
374     defp->def_kind = DEF_TYPEDEF;
375     get_declaration(&dec, DEF_TYPEDEF);
376     defp->def_name = dec.name;
377     defp->def.ty.old_prefix = dec.prefix;
378     defp->def.ty.old_type = dec.type;
379     defp->def.ty.rel = dec.rel;
380     defp->def.ty.array_max = dec.array_max;
381 }
382
383
384 static void
385 get_declaration(declaration * dec, defkind dkind)
386 {
387     token tok;
388
389     get_type(&dec->prefix, &dec->type, dkind);
390     dec->rel = REL_ALIAS;
391     if (streq(dec->type, "void")) {
392         return;
393     }
394     scan2(TOK_STAR, TOK_IDENT, &tok);
395     if (tok.kind == TOK_STAR) {
396         dec->rel = REL_POINTER;
397         scan(TOK_IDENT, &tok);
398     }
399     dec->name = tok.str;
400     if (peekscan(TOK_LBRACKET, &tok)) {
401         if (dec->rel == REL_POINTER) {
402             error("no array-of-pointer declarations -- use typedef");
403         }
404         dec->rel = REL_VECTOR;
405         scan_num(&tok);
406         dec->array_max = tok.str;
407         scan(TOK_RBRACKET, &tok);
408     } else if (peekscan(TOK_LANGLE, &tok)) {
409         if (dec->rel == REL_POINTER) {
410             error("no array-of-pointer declarations -- use typedef");
411         }
412         dec->rel = REL_ARRAY;
413         if (peekscan(TOK_RANGLE, &tok)) {
414             if ((dkind == DEF_INPARAM) || (dkind == DEF_INOUTPARAM)) {
415                 error("input arrays must specify a max size");
416             }
417             dec->array_max = "~0u";     /* unspecified size, use max */
418         } else {
419             scan_num(&tok);
420             dec->array_max = tok.str;
421             scan(TOK_RANGLE, &tok);
422         }
423     }
424     if (streq(dec->type, "opaque")) {
425         if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
426             error("array declaration expected");
427         }
428     } else if (streq(dec->type, "string")) {
429         if (dec->rel != REL_ARRAY) {
430             error(" variable-length array declaration expected");
431         }
432     }
433 }
434
435
436 static void
437 get_type(char **prefixp, char **typep, defkind dkind)
438 {
439     token tok;
440
441     *prefixp = NULL;
442     get_token(&tok);
443     switch (tok.kind) {
444     case TOK_IDENT:
445         *typep = tok.str;
446         break;
447     case TOK_STRUCT:
448     case TOK_ENUM:
449     case TOK_UNION:
450         *prefixp = tok.str;
451         scan(TOK_IDENT, &tok);
452         *typep = tok.str;
453         break;
454     case TOK_UNSIGNED:
455         unsigned_dec(typep);
456         break;
457     case TOK_SHORT:
458         *typep = "short";
459         (void)peekscan(TOK_INT, &tok);
460         break;
461     case TOK_INT32:
462         *typep = "afs_int32";
463         (void)peekscan(TOK_INT, &tok);
464         break;
465     case TOK_VOID:
466         if (dkind != DEF_UNION) {
467             error("voids allowed only inside union definitions");
468         }
469         *typep = tok.str;
470         break;
471     case TOK_STRING:
472     case TOK_OPAQUE:
473     case TOK_CHAR:
474     case TOK_INT:
475     case TOK_FLOAT:
476     case TOK_DOUBLE:
477     case TOK_BOOL:
478     case TOK_AFSUUID:
479         *typep = tok.str;
480         break;
481     default:
482         error("expected type specifier");
483     }
484 }
485
486
487 static void
488 unsigned_dec(char **typep)
489 {
490     token tok;
491
492     peek(&tok);
493     switch (tok.kind) {
494     case TOK_CHAR:
495         get_token(&tok);
496         *typep = "u_char";
497         break;
498     case TOK_SHORT:
499         get_token(&tok);
500         *typep = "u_short";
501         (void)peekscan(TOK_INT, &tok);
502         break;
503     case TOK_INT32:
504         get_token(&tok);
505         *typep = "afs_uint32";
506         (void)peekscan(TOK_INT, &tok);
507         break;
508     case TOK_INT:
509         get_token(&tok);
510         *typep = "u_int";
511         break;
512     default:
513         *typep = "u_int";
514         break;
515     }
516 }
517
518
519 static void
520 def_package(definition * defp)
521 {
522     token tok;
523
524     defp->def_kind = DEF_PACKAGE;
525     scan(TOK_IDENT, &tok);
526     defp->def_name = tok.str;
527     no_of_stat_funcs = 0;
528
529     PackageIndex++;
530     if (PackageIndex >= MAX_PACKAGES)
531         error("Exceeded upper limit of package statements\n");
532
533     function_list_index = 0;
534     PackagePrefix[PackageIndex] = tok.str;
535     if (MasterPrefix == NULL)
536         MasterPrefix = tok.str;
537     no_of_opcodes[PackageIndex] = highest_opcode[PackageIndex] =
538         opcodesnotallowed[PackageIndex] = 0;
539     lowest_opcode[PackageIndex] = 99999;
540     proc_defined[PackageIndex] = NULL;
541     PackageStatIndex[PackageIndex] = NULL;
542 }
543
544 static void
545 def_prefix(definition * defp)
546 {
547     token tok;
548
549     defp->def_kind = DEF_PREFIX;
550     scan(TOK_IDENT, &tok);
551     defp->def_name = tok.str;
552     ServerPrefix = tok.str;
553 }
554
555 static void
556 def_statindex(definition * defp)
557 {
558     token tok;
559     char *name;
560
561     defp->def_kind = DEF_CONST;
562     scan_num(&tok);
563     if (PackageIndex < 0)
564         error("'statindex' command must follow 'package' command!\n");
565     if (PackageStatIndex[PackageIndex])
566         error("Cannot have more then one 'statindex' per package!\n");
567     if (InvalidConstant(tok.str))
568         error("Index in 'statindex' command must be a constant!");
569     name =
570         alloc(strlen(PackagePrefix[PackageIndex]) + strlen("STATINDEX") + 1);
571     strcpy(name, PackagePrefix[PackageIndex]);
572     strcat(name, "STATINDEX");
573     defp->def_name = name;
574     defp->def.co = tok.str;
575     PackageStatIndex[PackageIndex] = name;
576     StatIndex = atoi(tok.str);
577 }
578
579 static void
580 def_startingopcode(definition * defp)
581 {
582     token tok;
583
584     defp->def_kind = DEF_STARTINGOPCODE;
585     scan(TOK_IDENT, &tok);
586     defp->def_name = tok.str;
587     if (InvalidConstant(defp->def_name))
588         error("Opcode in 'startingopcode' command must be a constant!");
589     lowest_opcode[PackageIndex] = master_lowest_opcode = atoi(tok.str);
590     if (lowest_opcode[PackageIndex] < 0
591         || lowest_opcode[PackageIndex] > 99999)
592         error
593             ("startingopcode number is out of bounds (must be >= 0 < 100000)");
594     master_opcodenumber = lowest_opcode[PackageIndex];
595     opcodesnotallowed[PackageIndex] = 1;
596 }
597
598 static void
599 def_split(definition * defp)
600 {
601     token tok;
602
603     defp->def_kind = DEF_SPLITPREFIX;
604     do {
605         get_token(&tok);
606         switch (tok.kind) {
607         case TOK_IN:
608             scan(TOK_EQUAL, &tok);
609             scan(TOK_IDENT, &tok);
610             SplitStart = tok.str;
611             break;
612         case TOK_OUT:
613             scan(TOK_EQUAL, &tok);
614             scan(TOK_IDENT, &tok);
615             SplitEnd = tok.str;
616             break;
617         case TOK_SEMICOLON:
618             break;
619         default:
620             error("syntax error in the 'splitprefix' line");
621         }
622     } while (tok.kind != TOK_SEMICOLON);
623     if (!SplitStart && !SplitEnd)
624         error("At least one param should be passed to 'splitprefix' cmd");
625 }
626
627
628 static void
629 customize_struct(definition * defp)
630 {
631     decl_list *listp;
632     declaration *dec;
633     definition *defp1 = ALLOC(definition);
634     spec_list *specs, **tailp;
635
636     defp->def_kind = DEF_CUSTOMIZED;
637     defp1->def_kind = DEF_SPECIAL;
638     tailp = &defp1->def.sd.specs;
639     for (listp = defp->def.st.decls; listp; listp = listp->next) {
640         dec = &listp->decl;
641         if (streq(dec->type, "string") || (dec->rel == REL_POINTER)) {
642             specs = ALLOC(spec_list);
643             specs->sdef.string_name = dec->name;
644             specs->sdef.string_value = defp->def_name;
645             *tailp = specs;
646             tailp = &specs->next;
647         }
648     }
649     tailp = NULL;
650     STOREVAL(&special_defined, defp1);
651 }
652
653 static char *
654 structname(char *name)
655 {
656     static char namecontents[150];
657     char *pnt, *pnt1;
658
659     strcpy(namecontents, name);
660     pnt = namecontents;
661     if (!strncmp(pnt, "struct", 6))
662         pnt += 6;
663     while (isspace(*pnt))
664         pnt++;
665     pnt1 = pnt;
666     while (*pnt != ' ' && *pnt != '\0')
667         pnt++;
668     *pnt = '\0';
669     return pnt1;
670 }
671
672
673 static void
674 def_special(declaration * dec, definition * defp)
675 {
676     char *typename;
677     spec_list *specs, **tailp;
678     token tok;
679
680     defp->def_kind = DEF_SPECIAL;
681     get_type(&dec->prefix, &dec->type, DEF_SPECIAL);
682     dec->rel = REL_POINTER;
683     scan(TOK_IDENT, &tok);
684     tailp = &defp->def.sd.specs;
685     do {
686         specs = ALLOC(spec_list);
687         specs->sdef.string_name = tok.str;
688         get_param_type(defp, dec, &specs->sdef.string_value, &typename);
689         *tailp = specs;
690         tailp = &specs->next;
691         scan2(TOK_COMMA, TOK_SEMICOLON, &tok);
692         if (tok.kind == TOK_SEMICOLON)
693             break;
694         get_token(&tok);
695     } while (tok.kind == TOK_IDENT);
696     tailp = NULL;
697     STOREVAL(&special_defined, defp);
698 }
699
700
701 proc1_list *Proc_list, **Proc_listp;
702
703 static void
704 check_proc(definition * defp, token * tokp, int noname)
705 {
706     token tok;
707     int proc_split = 0;
708     int proc_multi = 0;
709
710     if (PackageIndex < 0)
711         error("Procedure must be in a package!\n");
712
713     tokp->kind = TOK_PROC;
714     defp->def_kind = DEF_PROC;
715     if (noname)
716         defp->pc.proc_name = "";
717     else
718         defp->pc.proc_name = tokp->str;
719     PerProcCounter = 0;
720     defp->pc.proc_prefix = alloc(strlen(PackagePrefix[PackageIndex]) + 1);
721     strcpy(defp->pc.proc_prefix, PackagePrefix[PackageIndex]);
722     scan2(TOK_LPAREN, TOK_IDENT, &tok);
723     defp->pc.proc_serverstub = NULL;
724     if (tok.kind == TOK_IDENT) {
725         defp->pc.proc_serverstub = tok.str;
726         scan(TOK_LPAREN, &tok);
727     }
728     analyze_ProcParams(defp, &tok);
729     defp->pc.proc_opcodenum = -1;
730     scan4(TOK_SPLIT, TOK_MULTI, TOK_EQUAL, TOK_SEMICOLON, &tok);
731     if (tok.kind == TOK_MULTI) {
732         proc_multi = 1;
733         defp->pc.multi_flag = 1;
734         scan2(TOK_EQUAL, TOK_SEMICOLON, &tok);
735     } else {
736         defp->pc.multi_flag = 0;
737     }
738     if (tok.kind == TOK_SPLIT) {
739         proc_split = 1;
740         defp->pc.split_flag = 1;
741         scan2(TOK_EQUAL, TOK_SEMICOLON, &tok);
742     } else {
743         defp->pc.split_flag = 0;
744     }
745     if (tok.kind == TOK_EQUAL) {
746         if (opcodesnotallowed[PackageIndex])
747             error("Opcode assignment isn't allowed here!");
748         scan_num(&tok);
749         if (InvalidConstant(tok.str))
750             error("Illegal Opcode assignment (Must be a constant opcode!)");
751         if (opcodenum_is_defined(atoi(tok.str)))
752             error("The opcode number is already used by a previous proc");
753         defp->pc.proc_opcodename = tok.str;
754         defp->pc.proc_opcodenum = atoi(tok.str);
755         if (defp->pc.proc_opcodenum < lowest_opcode[PackageIndex])
756             lowest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
757         if (defp->pc.proc_opcodenum < master_lowest_opcode)
758             master_lowest_opcode = defp->pc.proc_opcodenum;
759         if (defp->pc.proc_opcodenum > highest_opcode[PackageIndex])
760             highest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
761         if (defp->pc.proc_opcodenum > master_highest_opcode)
762             master_highest_opcode = defp->pc.proc_opcodenum;
763         scan(TOK_SEMICOLON, &tok);
764     } else {
765         if (master_opcodenumber == 99999)
766             master_opcodenumber = 0;
767         defp->pc.proc_opcodenum = master_opcodenumber++;
768         if (defp->pc.proc_opcodenum < lowest_opcode[PackageIndex])
769             lowest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
770         if (defp->pc.proc_opcodenum > highest_opcode[PackageIndex])
771             highest_opcode[PackageIndex] = defp->pc.proc_opcodenum;
772         if (defp->pc.proc_opcodenum > master_highest_opcode)
773             master_highest_opcode = defp->pc.proc_opcodenum;
774         opcodesnotallowed[PackageIndex] = 1;    /* force it */
775     }
776     no_of_opcodes[PackageIndex]++, master_no_of_opcodes++;
777     if (proc_multi) {
778         generate_code(defp, 0, 1);
779         if (Cflag || cflag) {
780             generate_code(defp, 1, 1);
781         }
782         generate_multi_macros(defp);
783     } else {
784         generate_code(defp, proc_split, 0);
785     }
786
787     if (function_list_index >= MAX_FUNCTIONS_PER_INTERFACE) {
788         error("too many functions in interface, "
789               "increase MAX_FUNCTIONS_PER_INTERFACE");
790     }
791     sprintf(function_list[PackageIndex][function_list_index], "%s%s%s",
792             prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
793
794     function_list_index++;
795     defp->statindex = no_of_stat_funcs;
796     no_of_stat_funcs_header[PackageIndex]++;
797     no_of_stat_funcs++;
798     *Proc_listp = NULL;
799 }
800
801
802 #define LEGALNUMS "0123456789"
803 static int
804 InvalidConstant(char *name)
805 {
806     char *map;
807     int slen;
808
809     map = LEGALNUMS;
810     slen = (int)strlen(name);
811     return (slen != strspn(name, map));
812 }
813
814 static int
815 opcodenum_is_defined(int opcode_num)
816 {
817     list *listp;
818     definition *defp;
819
820     for (listp = proc_defined[PackageIndex]; listp != NULL;
821          listp = listp->next) {
822         defp = (definition *) listp->val;
823         if (opcode_num == defp->pc.proc_opcodenum)
824             return 1;
825     }
826     return 0;
827 }
828
829
830 static void
831 analyze_ProcParams(definition * defp, token * tokp)
832 {
833     declaration dec;
834     decl_list *decls, **tailp;
835
836     Proc_listp = &defp->pc.plists;
837     tailp = &defp->def.st.decls;
838     do {
839         get_token(tokp);
840         Proc_list = ALLOC(proc1_list);
841         memset(Proc_list, 0, sizeof(proc1_list));
842         Proc_list->pl.param_flag = 0;
843         switch (tokp->kind) {
844         case TOK_IN:
845             hdle_param_tok(defp, &dec, tokp, DEF_INPARAM);
846             break;
847         case TOK_OUT:
848             hdle_param_tok(defp, &dec, tokp, DEF_OUTPARAM);
849             break;
850         case TOK_INOUT:
851             hdle_param_tok(defp, &dec, tokp, DEF_INOUTPARAM);
852             break;
853         case TOK_RPAREN:
854             break;
855         default:
856             unget_token(tokp);
857             hdle_param_tok(defp, &dec, tokp, DEF_NULL);
858             break;
859         }
860         *Proc_listp = Proc_list;
861         Proc_listp = &Proc_list->next;
862         decls = ALLOC(decl_list);
863         memset(decls, 0, sizeof(decl_list));
864         if (tokp->kind != TOK_RPAREN)
865             decls->decl = dec;
866         *tailp = decls;
867         tailp = &decls->next;
868     } while (tokp->kind != TOK_RPAREN);
869     *tailp = NULL;
870 }
871
872
873 static void
874 generate_code(definition * defp, int proc_split_flag, int multi_flag)
875 {
876     if (proc_split_flag)
877         handle_split_proc(defp, multi_flag);
878     else {
879         if (Cflag || cflag) {
880             cs_Proc_CodeGeneration(defp, 0, "");
881         }
882         if (Sflag || cflag)
883             ss_Proc_CodeGeneration(defp);
884     }
885     if (Sflag || (cflag && xflag && !proc_split_flag) || hflag)
886         STOREVAL(&proc_defined[PackageIndex], defp);
887 }
888
889
890 static void
891 handle_split_proc(definition * defp, int multi_flag)
892 {
893     char *startname = SplitStart, *endname = SplitEnd;
894     int numofparams = 0;
895
896     if (!startname)
897         startname = "Start";
898     if (!endname)
899         endname = "End";
900     if (Cflag || cflag) {
901         if (!cflag) {
902             do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 0);
903         }
904         cs_Proc_CodeGeneration(defp, 1, startname);
905         if (!cflag) {
906             do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 1);
907             do_split(defp, IN, &numofparams, DEF_INPARAM, 0);
908         }
909         cs_Proc_CodeGeneration(defp, (multi_flag ? 3 : 2), endname);
910         if (!cflag) {
911             do_split(defp, IN, &numofparams, DEF_INPARAM, 1);
912         }
913     }
914     if (Sflag || cflag)
915         ss_Proc_CodeGeneration(defp);
916 }
917
918
919 static void
920 do_split(definition * defp, int direction, int *numofparams,
921          defkind param_kind, int restore_flag)
922 {
923     proc1_list *plist;
924
925     if (restore_flag) {
926         defp->pc.paramtypes[direction] = *numofparams;
927         for (plist = defp->pc.plists; plist; plist = plist->next) {
928             if (plist->component_kind == DEF_NULL
929                 && plist->pl.param_kind == param_kind)
930                 plist->component_kind = DEF_PARAM;
931         }
932     } else {
933         *numofparams = defp->pc.paramtypes[direction];
934         defp->pc.paramtypes[direction] = 0;
935         for (plist = defp->pc.plists; plist; plist = plist->next) {
936             if (plist->component_kind == DEF_PARAM
937                 && plist->pl.param_kind == param_kind)
938                 plist->component_kind = DEF_NULL;
939         }
940     }
941 }
942
943
944 static void
945 hdle_param_tok(definition * defp, declaration * dec, token * tokp,
946                defkind par_kind)
947 {
948     static defkind last_param_kind = DEF_NULL;
949
950     if (par_kind == DEF_NULL)
951         Proc_list->pl.param_kind = last_param_kind;
952     else
953         Proc_list->pl.param_kind = par_kind;
954     last_param_kind = Proc_list->pl.param_kind;
955     defp->pc.paramtypes[(int)last_param_kind]++;
956     Proc_list->component_kind = DEF_PARAM;
957     Proc_list->code = alloc(250);
958     Proc_list->scode = alloc(250);
959     get_declaration(dec, par_kind);
960     Proc_list->pl.param_name = dec->name;
961     get1_param_type(defp, dec, &Proc_list->pl.param_type);
962     print_param(dec);
963     scan2(TOK_COMMA, TOK_RPAREN, tokp);
964     if (tokp->kind == TOK_COMMA)
965         peek(tokp);
966 }
967
968
969 static void
970 get1_param_type(definition * defp, declaration * dec, char **param_type)
971 {
972     char typecontents[100];
973
974     if (streq(dec->type, "string")) {
975         *param_type = "char *";
976     } else {
977         if (dec->prefix) {
978             strcpy(typecontents, dec->prefix);
979             strcat(typecontents, " ");
980             strcat(typecontents, dec->type);
981             strcat(typecontents, " *");
982         } else if (dec->rel == REL_POINTER) {
983             strcpy(typecontents, dec->type);
984             strcat(typecontents, " *");
985         } else
986             strcpy(typecontents, dec->type);
987         *param_type = alloc(100);
988         strcpy(*param_type, typecontents);
989     }
990 }
991
992
993 static void
994 get_param_type(definition * defp, declaration * dec, char **param_type,
995                char **typename)
996 {
997     char typecontents[100];
998
999     if (streq(dec->type, "string")) {
1000         *typename = "wrapstring";
1001         *param_type = "char *";
1002     } else {
1003         *typename = dec->type;
1004         if (dec->prefix) {
1005             strcpy(typecontents, dec->prefix);
1006             strcat(typecontents, " ");
1007             strcat(typecontents, dec->type);
1008             strcat(typecontents, " *");
1009             dec->rel = REL_POINTER;
1010         } else if (dec->rel == REL_POINTER) {
1011             strcpy(typecontents, dec->type);
1012             strcat(typecontents, " *");
1013         } else
1014             strcpy(typecontents, dec->type);
1015         *param_type = alloc(100);
1016         strcpy(*param_type, typecontents);
1017     }
1018 }
1019
1020
1021 #ifdef undef
1022 static void
1023 hndle_param_tail(definition * defp, declaration * dec, token * tokp,
1024                  char *typename)
1025 {
1026     char *amp;
1027
1028     if (dec->rel == REL_POINTER)
1029         Proc_list->pl.param_flag |= INDIRECT_PARAM;
1030     else
1031         Proc_list->pl.param_flag &= ~INDIRECT_PARAM;
1032     amp = "";
1033     if (!(Proc_list->pl.param_flag & INDIRECT_PARAM))
1034         amp = "&";
1035
1036     sprintf(Proc_list->code, "xdr_%s(&z_xdrs, %s%s)", typename, amp,
1037             Proc_list->pl.param_name);
1038     sprintf(Proc_list->scode, "xdr_%s(z_xdrs, &%s)", typename,
1039             Proc_list->pl.param_name);
1040     scan2(TOK_COMMA, TOK_RPAREN, tokp);
1041     if (tokp->kind == TOK_COMMA)
1042         peek(tokp);
1043 }
1044 #endif
1045
1046
1047 static void
1048 cs_Proc_CodeGeneration(definition * defp, int split_flag, char *procheader)
1049 {
1050     defp->can_fail = 0;
1051     cs_ProcName_setup(defp, procheader, split_flag);
1052     if (!cflag) {
1053         cs_ProcParams_setup(defp, split_flag);
1054         cs_ProcMarshallInParams_setup(defp, split_flag);
1055         if (split_flag != 1) {
1056             cs_ProcSendPacket_setup(defp, split_flag);
1057             cs_ProcUnmarshallOutParams_setup(defp);
1058         }
1059         cs_ProcTail_setup(defp, split_flag);
1060     }
1061
1062     if (!kflag && !split_flag && uflag) {
1063         ucs_ProcName_setup(defp, "ubik_", split_flag);
1064         if (!cflag) {
1065             ucs_ProcParams_setup(defp, split_flag);
1066             ucs_ProcTail_setup(defp, split_flag);
1067         }
1068     }
1069 }
1070
1071 static void
1072 cs_ProcName_setup(definition * defp, char *procheader, int split_flag)
1073 {
1074     proc1_list *plist;
1075     char *first_arg;
1076
1077     if (ansic_flag) {
1078         if (split_flag) {
1079             first_arg = "struct rx_call *z_call";
1080         } else {
1081             first_arg = "struct rx_connection *z_conn";
1082         }
1083     } else {
1084         if (split_flag) {
1085             first_arg = "z_call";
1086         } else {
1087             first_arg = "z_conn";
1088         }
1089     }
1090
1091     if (!cflag) {
1092         f_print(fout, "int %s%s%s%s(%s", procheader, prefix,
1093                 PackagePrefix[PackageIndex], defp->pc.proc_name, first_arg);
1094     }
1095     if ((strlen(procheader) + strlen(prefix) +
1096          strlen(PackagePrefix[PackageIndex]) + strlen(defp->pc.proc_name)) >=
1097         MAX_FUNCTION_NAME_LEN) {
1098         error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1099     }
1100     if (!cflag) {
1101         for (plist = defp->pc.plists; plist; plist = plist->next) {
1102             if (plist->component_kind == DEF_PARAM) {
1103                 f_print(fout, ",");
1104                 if (ansic_flag) {
1105                     if (plist->pl.param_kind == DEF_INPARAM &&
1106                         strcmp(plist->pl.param_type, "char *") == 0) {
1107                         f_print(fout, "const ");
1108                     }
1109                     if (plist->pl.param_flag & OUT_STRING) {
1110                         f_print(fout, "%s *%s", plist->pl.param_type,
1111                                 plist->pl.param_name);
1112                     } else {
1113                         f_print(fout, "%s %s", plist->pl.param_type,
1114                                 plist->pl.param_name);
1115                     }
1116                 } else {
1117                     f_print(fout, " %s", plist->pl.param_name);
1118                     plist->pl.param_flag &= ~PROCESSED_PARAM;
1119                 }
1120             }
1121         }
1122         f_print(fout, ")\n");
1123     }
1124 }
1125
1126 static void
1127 cs_ProcParams_setup(definition * defp, int split_flag)
1128 {
1129     proc1_list *plist, *plist1;
1130
1131     if (ansic_flag)
1132         return;
1133
1134     if (!split_flag)
1135         f_print(fout, "\tstruct rx_connection *z_conn;\n");
1136     if (split_flag) {
1137         f_print(fout, "\tstruct rx_call *z_call;\n");
1138     }
1139     for (plist = defp->pc.plists; plist; plist = plist->next) {
1140         if (plist->component_kind == DEF_PARAM
1141             && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1142             if (plist->pl.param_flag & OUT_STRING) {
1143                 f_print(fout, "\t%s *%s", plist->pl.param_type,
1144                         plist->pl.param_name);
1145             } else {
1146                 f_print(fout, "\t%s %s", plist->pl.param_type,
1147                         plist->pl.param_name);
1148             }
1149             plist->pl.param_flag |= PROCESSED_PARAM;
1150             for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1151                 if ((plist1->component_kind == DEF_PARAM)
1152                     && streq(plist->pl.param_type, plist1->pl.param_type)
1153                     && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1154                     char *star = "";
1155                     char *pntr = strchr(plist1->pl.param_type, '*');
1156                     if (pntr)
1157                         star = "*";
1158                     if (plist1->pl.param_flag & OUT_STRING) {
1159                         f_print(fout, ", *%s%s", star, plist1->pl.param_name);
1160                     } else {
1161                         f_print(fout, ", %s%s", star, plist1->pl.param_name);
1162                     }
1163                     plist1->pl.param_flag |= PROCESSED_PARAM;
1164                 }
1165             }
1166             f_print(fout, ";\n");
1167         }
1168     }
1169 }
1170
1171
1172 static void
1173 cs_ProcMarshallInParams_setup(definition * defp, int split_flag)
1174 {
1175     int noofparams, i = 0;
1176     proc1_list *plist;
1177     decl_list *dl;
1178     int noofallparams =
1179         defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT] +
1180         defp->pc.paramtypes[OUT];
1181
1182     f_print(fout, "{\n");
1183     if (!split_flag)
1184         f_print(fout, "\tstruct rx_call *z_call = rx_NewCall(z_conn);\n");
1185     if ((!split_flag) || (split_flag == 1)) {
1186         if (opcodesnotallowed[PackageIndex]) {
1187             f_print(fout, "\tstatic int z_op = %d;\n",
1188                     defp->pc.proc_opcodenum);
1189         } else {
1190             f_print(fout, "\tstatic int z_op = %s;\n",
1191                     defp->pc.proc_opcodename);
1192         }
1193     }
1194     f_print(fout, "\tint z_result;\n");
1195     if (!(split_flag > 1) || (noofallparams != 0)) {
1196         f_print(fout, "\tXDR z_xdrs;\n");
1197     }
1198
1199     if ((!split_flag) || (split_flag == 1)) {
1200         f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_ENCODE);\n");
1201         f_print(fout, "\n\t/* Marshal the arguments */\n");
1202         f_print(fout, "\tif ((!xdr_int(&z_xdrs, &z_op))");
1203         noofparams = defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT];
1204         for (plist = defp->pc.plists, dl = defp->def.st.decls; plist;
1205              plist = plist->next, dl = dl->next) {
1206             if (plist->component_kind == DEF_PARAM
1207                 && (plist->pl.param_kind == DEF_INPARAM
1208                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1209                 f_print(fout, "\n\t     || (!%s)", plist->code);
1210                 if (++i == noofparams) {
1211                     f_print(fout,
1212                             ") {\n\t\tz_result = RXGEN_CC_MARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1213                     defp->can_fail = 1;
1214                 }
1215             }
1216         }
1217         if (!i) {
1218             f_print(fout,
1219                     ") {\n\t\tz_result = RXGEN_CC_MARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1220             defp->can_fail = 1;
1221         }
1222     }
1223 }
1224
1225
1226 static void
1227 cs_ProcSendPacket_setup(definition * defp, int split_flag)
1228 {
1229     int noofoutparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1230
1231     if (noofoutparams) {
1232         f_print(fout, "\t/* Un-marshal the reply arguments */\n");
1233         if (split_flag) {
1234             f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
1235         } else {
1236             f_print(fout, "\tz_xdrs.x_op = XDR_DECODE;\n");
1237         }
1238     }
1239 }
1240
1241
1242 static void
1243 cs_ProcUnmarshallOutParams_setup(definition * defp)
1244 {
1245     int noofparams, i;
1246     proc1_list *plist;
1247     decl_list *dl;
1248
1249     noofparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1250     if (noofparams)
1251         for (plist = defp->pc.plists, dl = defp->def.st.decls, i = 0; plist;
1252              plist = plist->next, dl = dl->next) {
1253             if (plist->component_kind == DEF_PARAM
1254                 && (plist->pl.param_kind == DEF_OUTPARAM
1255                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1256                 if (!i) {
1257                     f_print(fout, "\tif ((!%s)", plist->code);
1258                 } else {
1259                     f_print(fout, "\n\t     || (!%s)", plist->code);
1260                 }
1261                 if (++i == noofparams) {
1262                     f_print(fout,
1263                             ") {\n\t\tz_result = RXGEN_CC_UNMARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1264                     defp->can_fail = 1;
1265                 }
1266             }
1267         }
1268 }
1269
1270
1271 static void
1272 cs_ProcTail_setup(definition * defp, int split_flag)
1273 {
1274     f_print(fout, "\tz_result = RXGEN_SUCCESS;\n");
1275     if (defp->can_fail) {
1276         f_print(fout, "fail:\n");
1277     }
1278     if (!split_flag) {
1279         f_print(fout, "\tz_result = rx_EndCall(z_call, z_result);\n");
1280     }
1281     if (xflag && split_flag != 1) {
1282         f_print(fout, "\tif (rx_enable_stats) {\n");
1283         if (PackageStatIndex[PackageIndex]) {
1284             f_print(fout,
1285                     "\t    rx_RecordCallStatistics(z_call, %s,\n",
1286                     PackageStatIndex[PackageIndex]);
1287         } else {
1288             f_print(fout,
1289                     "\t    rx_RecordCallStatistics(z_call, \n"
1290                     "\t\t(((afs_uint32)(ntohs(rx_ServiceIdOf(rx_ConnectionOf(z_call))) << 16)) |\n"
1291                     "\t\t((afs_uint32)ntohs(rx_PortOf(rx_PeerOf(rx_ConnectionOf(z_call)))))),\n");
1292         }
1293         f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, 1);\n",
1294                 no_of_stat_funcs, PackagePrefix[PackageIndex]);
1295         f_print(fout, "\t}\n\n");
1296     }
1297     f_print(fout, "\treturn z_result;\n}\n\n");
1298 }
1299
1300
1301 static void
1302 ss_Proc_CodeGeneration(definition * defp)
1303 {
1304     defp->can_fail = 0;
1305     ss_ProcName_setup(defp);
1306     if (!cflag) {
1307         ss_ProcParams_setup(defp);
1308         ss_ProcSpecial_setup(defp);
1309         ss_ProcUnmarshallInParams_setup(defp);
1310         ss_ProcCallRealProc_setup(defp);
1311         ss_ProcMarshallOutParams_setup(defp);
1312         ss_ProcTail_setup(defp);
1313     }
1314 }
1315
1316
1317 static void
1318 ss_ProcName_setup(definition * defp)
1319 {
1320     proc1_list *plist;
1321
1322     if ((strlen(prefix) + strlen(PackagePrefix[PackageIndex]) +
1323          strlen(defp->pc.proc_name)) >= MAX_FUNCTION_NAME_LEN) {
1324         error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1325     }
1326
1327     if (!cflag) {
1328         f_print(fout, "static afs_int32 _%s%s%s(", prefix,
1329                 PackagePrefix[PackageIndex], defp->pc.proc_name);
1330         f_print(fout, "struct rx_call *z_call, XDR *z_xdrs)\n{\n");
1331         f_print(fout, "\t" "afs_int32 z_result;\n");
1332
1333         for (plist = defp->pc.plists; plist; plist = plist->next)
1334             if (plist->component_kind == DEF_PARAM) {
1335                 plist->pl.param_flag &= ~(PROCESSED_PARAM);
1336                 plist->pl.string_name = NULL;
1337             }
1338     }
1339 }
1340
1341
1342 static void
1343 ss_ProcParams_setup(definition * defp)
1344 {
1345     proc1_list *plist, *plist1;
1346     list *listp;
1347     definition *defp1;
1348
1349     for (plist = defp->pc.plists; plist; plist = plist->next) {
1350         if ((plist->component_kind == DEF_PARAM)
1351             && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1352             if (plist->pl.param_flag & INDIRECT_PARAM) {
1353                 char pres = '\0', *pntr = strchr(plist->pl.param_type, '*');
1354                 if (pntr) {
1355                     --pntr;
1356                     pres = *pntr;
1357                     *pntr = (char)0;
1358                 }
1359                 f_print(fout, "\t%s %s", plist->pl.param_type,
1360                         plist->pl.param_name);
1361                 if (pntr)
1362                     *pntr = pres;
1363             } else if (strchr(plist->pl.param_type, '*') == 0) {
1364                 f_print(fout, "\t%s %s", plist->pl.param_type,
1365                         plist->pl.param_name);
1366             } else {
1367                 plist->pl.param_flag |= FREETHIS_PARAM;
1368                 f_print(fout, "\t%s %s=(%s)0", plist->pl.param_type,
1369                         plist->pl.param_name, plist->pl.param_type);
1370             }
1371             plist->pl.param_flag |= PROCESSED_PARAM;
1372             for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1373                 if ((plist1->component_kind == DEF_PARAM)
1374                     && streq(plist->pl.param_type, plist1->pl.param_type)
1375                     && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1376                     if (plist1->pl.param_flag & INDIRECT_PARAM) {
1377                         f_print(fout, ", %s", plist1->pl.param_name);
1378                     } else if (strchr(plist1->pl.param_type, '*') == 0) {
1379                         f_print(fout, ", %s", plist1->pl.param_name);
1380                     } else {
1381                         plist1->pl.param_flag |= FREETHIS_PARAM;
1382                         f_print(fout, ", *%s=(%s)0", plist1->pl.param_name,
1383                                 plist1->pl.param_type);
1384                     }
1385                     plist1->pl.param_flag |= PROCESSED_PARAM;
1386                 }
1387             }
1388             f_print(fout, ";\n");
1389         }
1390     }
1391     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1392         defp1 = (definition *) listp->val;
1393         for (plist = defp->pc.plists; plist; plist = plist->next) {
1394             if (plist->component_kind == DEF_PARAM
1395                 && (plist->pl.param_kind == DEF_OUTPARAM
1396                     || plist->pl.param_kind == DEF_INOUTPARAM)
1397                 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1398                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1399                     switch (defp1->pc.rel) {
1400                     case REL_ARRAY:
1401                     case REL_POINTER:
1402                     default:
1403                         break;
1404                     }
1405                 }
1406             }
1407         }
1408     }
1409     fprintf(fout, "\n");
1410 }
1411
1412
1413 static void
1414 ss_ProcSpecial_setup(definition * defp)
1415 {
1416     proc1_list *plist;
1417     definition *defp1;
1418     list *listp;
1419
1420     for (listp = special_defined; listp != NULL; listp = listp->next) {
1421         defp1 = (definition *) listp->val;
1422
1423         for (plist = defp->pc.plists; plist; plist = plist->next) {
1424             if (plist->component_kind == DEF_PARAM
1425                 && (plist->pl.param_kind == DEF_INPARAM
1426                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1427                 spec_list *spec = defp1->def.sd.specs;
1428                 char string[40];
1429                 strcpy(string, structname(spec->sdef.string_value));
1430                 if (streq(string, structname(plist->pl.param_type))) {
1431                     plist->pl.string_name = spec->sdef.string_name;
1432                     plist->pl.param_flag |= FREETHIS_PARAM;
1433                     fprintf(fout, "\n\t%s.%s = 0;", plist->pl.param_name,
1434                             spec->sdef.string_name);
1435                 }
1436             }
1437         }
1438     }
1439     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1440         defp1 = (definition *) listp->val;
1441         for (plist = defp->pc.plists; plist; plist = plist->next) {
1442             if (plist->component_kind == DEF_PARAM) {
1443                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1444                     plist->pl.param_flag |= FREETHIS_PARAM;
1445                     switch (defp1->pc.rel) {
1446                     case REL_ARRAY:
1447                         plist->pl.string_name = alloc(40);
1448                         if (brief_flag) {
1449                             f_print(fout, "\n\t%s.val = 0;",
1450                                     plist->pl.param_name);
1451                             f_print(fout, "\n\t%s.len = 0;",
1452                                     plist->pl.param_name);
1453                             s_print(plist->pl.string_name, "val");
1454                         } else {
1455                             f_print(fout, "\n\t%s.%s_val = 0;",
1456                                     plist->pl.param_name, defp1->def_name);
1457                             f_print(fout, "\n\t%s.%s_len = 0;",
1458                                     plist->pl.param_name, defp1->def_name);
1459                             s_print(plist->pl.string_name, "%s_val",
1460                                     defp1->def_name);
1461                         }
1462                         break;
1463                     case REL_POINTER:
1464                         f_print(fout, "\n\t%s = 0;", plist->pl.param_name);
1465                         plist->pl.string_name = NULL;
1466                         break;
1467                     default:
1468                         break;
1469                     }
1470                 }
1471             }
1472         }
1473     }
1474     for (listp = complex_defined; listp != NULL; listp = listp->next) {
1475         defp1 = (definition *) listp->val;
1476         for (plist = defp->pc.plists; plist; plist = plist->next) {
1477             if (plist->component_kind == DEF_PARAM) {
1478                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1479                     plist->pl.param_flag |= FREETHIS_PARAM;
1480                     fprintf(fout, "\n\tmemset(&%s, 0, sizeof(%s));",
1481                                  plist->pl.param_name, defp1->def_name);
1482                 }
1483             }
1484         }
1485     }
1486
1487     f_print(fout, "\n");
1488 }
1489
1490
1491 static void
1492 ss_ProcUnmarshallInParams_setup(definition * defp)
1493 {
1494     int noofparams, noofoutparams, i;
1495     proc1_list *plist;
1496
1497     noofparams = defp->pc.paramtypes[IN] + defp->pc.paramtypes[INOUT];
1498     noofoutparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1499     for (plist = defp->pc.plists, i = 0; plist; plist = plist->next) {
1500         if (plist->component_kind == DEF_PARAM
1501             && (plist->pl.param_kind == DEF_INPARAM
1502                 || plist->pl.param_kind == DEF_INOUTPARAM)) {
1503             if (!i) {
1504                 f_print(fout, "\n\tif ((!%s)",
1505                         (plist->scode ? plist->scode : plist->code));
1506             } else {
1507                 f_print(fout, "\n\t     || (!%s)",
1508                         (plist->scode ? plist->scode : plist->code));
1509             }
1510             if (++i == noofparams) {
1511                 if (!noofoutparams) {
1512                     f_print(fout, ") {\n");
1513                 } else {
1514                     f_print(fout, ") {\n");
1515                 }
1516                 f_print(fout,
1517                         "\t\tz_result = RXGEN_SS_UNMARSHAL;\n\t\tgoto fail;\n\t}\n\n");
1518                 defp->can_fail = 1;
1519             }
1520         }
1521     }
1522 }
1523
1524
1525 static void
1526 ss_ProcCallRealProc_setup(definition * defp)
1527 {
1528     extern char zflag;
1529     proc1_list *plist;
1530
1531     f_print(fout, "\tz_result = %s%s%s%s(z_call", prefix, ServerPrefix,
1532             PackagePrefix[PackageIndex], defp->pc.proc_name);
1533     for (plist = defp->pc.plists; plist; plist = plist->next) {
1534         if (plist->component_kind == DEF_PARAM) {
1535             if (plist->pl.param_flag & INDIRECT_PARAM) {
1536                 f_print(fout, ", &%s", plist->pl.param_name);
1537             } else {
1538                 if (plist->pl.param_flag & OUT_STRING) {
1539                     f_print(fout, ", &%s", plist->pl.param_name);
1540                 } else {
1541                     f_print(fout, ", %s", plist->pl.param_name);
1542                 }
1543             }
1544         }
1545     }
1546     f_print(fout, ");\n");
1547     if (zflag) {
1548         f_print(fout, "\tif (z_result)\n\t\treturn z_result;\n");
1549     }
1550 }
1551
1552
1553 static void
1554 ss_ProcMarshallOutParams_setup(definition * defp)
1555 {
1556     proc1_list *plist;
1557     int noofparams, i;
1558
1559     noofparams = defp->pc.paramtypes[INOUT] + defp->pc.paramtypes[OUT];
1560     if (noofparams)
1561         f_print(fout, "\tz_xdrs->x_op = XDR_ENCODE;\n");
1562     if (noofparams) {
1563         for (plist = defp->pc.plists, i = 0; plist; plist = plist->next) {
1564             if (plist->component_kind == DEF_PARAM
1565                 && (plist->pl.param_kind == DEF_OUTPARAM
1566                     || plist->pl.param_kind == DEF_INOUTPARAM)) {
1567                 if (!i) {
1568                     f_print(fout, "\tif ((!%s)",
1569                             (plist->scode ? plist->scode : plist->code));
1570                 } else {
1571                     f_print(fout, "\n\t     || (!%s)",
1572                             (plist->scode ? plist->scode : plist->code));
1573                 }
1574                 if (++i == noofparams) {
1575                     f_print(fout, ")\n\t\tz_result = RXGEN_SS_MARSHAL;\n");
1576                 }
1577             }
1578         }
1579     }
1580 }
1581
1582 static void
1583 ss_ProcTail_frees(char *xdrfunc, int *somefrees) {
1584     if (!*somefrees) {
1585         f_print(fout, "\tz_xdrs->x_op = XDR_FREE;\n");
1586         f_print(fout, "\tif ((!%s)", xdrfunc);
1587         *somefrees = 1;
1588     } else {
1589         f_print(fout, "\n\t    || (!%s)", xdrfunc);
1590     }
1591 }
1592
1593
1594 static void
1595 ss_ProcTail_setup(definition * defp)
1596 {
1597     proc1_list *plist;
1598     definition *defp1;
1599     list *listp;
1600     int somefrees = 0;
1601
1602     if (defp->can_fail) {
1603         f_print(fout, "fail:\n");
1604     }
1605
1606     for (plist = defp->pc.plists; plist; plist = plist->next) {
1607         if (plist->component_kind == DEF_PARAM
1608                 && (plist->pl.param_flag & FREETHIS_PARAM))
1609             ss_ProcTail_frees(plist->scode, &somefrees);
1610     }
1611
1612     for (listp = typedef_defined; listp != NULL; listp = listp->next) {
1613         defp1 = (definition *) listp->val;
1614         for (plist = defp->pc.plists; plist; plist = plist->next) {
1615             if (plist->component_kind == DEF_PARAM
1616                 && (plist->pl.param_kind == DEF_OUTPARAM
1617                     || plist->pl.param_kind == DEF_INOUTPARAM)
1618                 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1619                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1620                     switch (defp1->pc.rel) {
1621                     case REL_ARRAY:
1622                     case REL_POINTER:
1623                         ss_ProcTail_frees(plist->scode, &somefrees);
1624                         break;
1625                     default:
1626                         break;
1627                     }
1628                 }
1629             }
1630         }
1631     }
1632
1633     for (listp = uniondef_defined; listp != NULL; listp = listp->next) {
1634         defp1 = (definition *) listp->val;
1635         for (plist = defp->pc.plists; plist; plist = plist->next) {
1636             if (plist->component_kind == DEF_PARAM
1637                 && (plist->pl.param_kind == DEF_OUTPARAM
1638                     || plist->pl.param_kind == DEF_INOUTPARAM)
1639                 && !(plist->pl.param_flag & FREETHIS_PARAM)) {
1640                 if (streq(defp1->def_name, structname(plist->pl.param_type))) {
1641                     if (plist->pl.param_flag & INDIRECT_PARAM) {
1642                         ss_ProcTail_frees(plist->scode, &somefrees);
1643                     }
1644                 }
1645             }
1646         }
1647     }
1648
1649     if (somefrees) {
1650         f_print(fout, ")\n");
1651         f_print(fout, "\t\tz_result = RXGEN_SS_XDRFREE;\n\n");
1652     }
1653
1654     if (xflag) {
1655         f_print(fout, "\tif (rx_enable_stats) {\n");
1656         f_print(fout, "\t    rx_RecordCallStatistics(z_call,");
1657         if (PackageStatIndex[PackageIndex]) {
1658             f_print(fout, " %s,\n", PackageStatIndex[PackageIndex]);
1659         } else {
1660             f_print(fout,
1661                     "\n\t\t(((afs_uint32)(ntohs(rx_ServiceIdOf(rx_ConnectionOf(z_call))) << 16)) |\n"
1662                     "\t\t((afs_uint32)ntohs(rx_ServiceOf(rx_ConnectionOf(z_call))->servicePort))),\n");
1663         }
1664         f_print(fout, "\t\t%d, %sNO_OF_STAT_FUNCS, 0);\n",
1665                 no_of_stat_funcs, PackagePrefix[PackageIndex]);
1666         f_print(fout, "\t}\n\n");
1667     }
1668
1669     f_print(fout, "\treturn z_result;\n");
1670     f_print(fout, "}\n\n");
1671 }
1672
1673
1674 static void
1675 ucs_ProcName_setup(definition * defp, char *procheader, int split_flag)
1676 {
1677     proc1_list *plist;
1678
1679     if (!cflag) {
1680         if (ansic_flag) {
1681             f_print(fout, "int %s%s%s%s(struct ubik_client *aclient, afs_int32 aflags",
1682                           procheader, prefix, PackagePrefix[PackageIndex],
1683                           defp->pc.proc_name);
1684         } else {
1685             f_print(fout, "int %s%s%s%s(aclient, aflags", procheader, prefix,
1686                           PackagePrefix[PackageIndex], defp->pc.proc_name);
1687         }
1688     }
1689     if ((strlen(procheader) + strlen(prefix) +
1690          strlen(PackagePrefix[PackageIndex]) + strlen(defp->pc.proc_name)) >=
1691         MAX_FUNCTION_NAME_LEN) {
1692         error("function name is too long, increase MAX_FUNCTION_NAME_LEN");
1693     }
1694     if (!cflag) {
1695         for (plist = defp->pc.plists; plist; plist = plist->next) {
1696             if (plist->component_kind == DEF_PARAM) {
1697                 f_print(fout, ",");
1698                 if (ansic_flag) {
1699                     if (plist->pl.param_kind == DEF_INPARAM &&
1700                         strcmp(plist->pl.param_type, "char *") == 0) {
1701                         f_print(fout, "const ");
1702                     }
1703                     if (plist->pl.param_flag & OUT_STRING) {
1704                         f_print(fout, "%s *%s", plist->pl.param_type,
1705                                 plist->pl.param_name);
1706                     } else {
1707                         f_print(fout, "%s %s", plist->pl.param_type,
1708                                 plist->pl.param_name);
1709                     }
1710                 } else {
1711                     plist->pl.param_flag &= ~PROCESSED_PARAM;
1712                     f_print(fout, " %s", plist->pl.param_name);
1713                 }
1714             }
1715         }
1716         f_print(fout, ")\n");
1717     }
1718 }
1719
1720
1721 static void
1722 ucs_ProcParams_setup(definition * defp, int split_flag)
1723 {
1724     proc1_list *plist, *plist1;
1725
1726     if (ansic_flag)
1727         return;
1728
1729     f_print(fout, "\tstruct ubik_client *aclient;\n\tafs_int32 aflags;\n");
1730     for (plist = defp->pc.plists; plist; plist = plist->next) {
1731         if (plist->component_kind == DEF_PARAM
1732             && !(plist->pl.param_flag & PROCESSED_PARAM)) {
1733             if (plist->pl.param_flag & OUT_STRING) {
1734                 f_print(fout, "\t%s *%s", plist->pl.param_type,
1735                         plist->pl.param_name);
1736             } else {
1737                 f_print(fout, "\t%s %s", plist->pl.param_type,
1738                         plist->pl.param_name);
1739             }
1740             plist->pl.param_flag |= PROCESSED_PARAM;
1741             for (plist1 = defp->pc.plists; plist1; plist1 = plist1->next) {
1742                 if ((plist1->component_kind == DEF_PARAM)
1743                     && streq(plist->pl.param_type, plist1->pl.param_type)
1744                     && !(plist1->pl.param_flag & PROCESSED_PARAM)) {
1745                     char *star = "";
1746                     char *pntr = strchr(plist1->pl.param_type, '*');
1747                     if (pntr)
1748                         star = "*";
1749                     if (plist1->pl.param_flag & OUT_STRING) {
1750                         f_print(fout, ", *%s%s", star, plist1->pl.param_name);
1751                     } else {
1752                         f_print(fout, ", %s%s", star, plist1->pl.param_name);
1753                     }
1754                     plist1->pl.param_flag |= PROCESSED_PARAM;
1755                 }
1756             }
1757             f_print(fout, ";\n");
1758         }
1759     }
1760 }
1761
1762 static void
1763 ucs_ProcTail_setup(definition * defp, int split_flag)
1764 {
1765     proc1_list *plist;
1766
1767     f_print(fout, "{\tafs_int32 rcode, code, newHost, thisHost, i, _ucount;\n");
1768     f_print(fout, "\tint chaseCount, pass, needsync;\n");
1769 #if 0 /* goes with block below */
1770     f_print(fout, "\tint j, inlist;\n");
1771 #endif
1772     f_print(fout, "\tstruct rx_connection *tc;\n");
1773     f_print(fout, "\tstruct rx_peer *rxp;\n");
1774     f_print(fout, "\tshort origLevel;\n\n");
1775     f_print(fout, "\tif (!aclient)\n");
1776     f_print(fout, "\t\treturn UNOENT;\n");
1777     f_print(fout, "\tLOCK_UBIK_CLIENT(aclient);\n\n");
1778     f_print(fout, "\t restart:\n");
1779     f_print(fout, "\torigLevel = aclient->initializationState;\n");
1780     f_print(fout, "\trcode = UNOSERVERS;\n");
1781     f_print(fout, "\tchaseCount = needsync = 0;\n\n");
1782 #if 0 /* We should do some sort of caching algorithm for this, but I need to think about it - shadow 26 jun 06 */
1783     f_print(fout, "\tinlist = 0;\n");
1784     f_print(fout, "\tLOCK_UCLNT_CACHE;\n");
1785     f_print(fout, "\tfor (j = 0; ((j < SYNCCOUNT) && calls_needsync[j]); j++) {\n");
1786     f_print(fout, "\t\tif (calls_needsync[j] == (int *)%s%s%s) {\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1787     f_print(fout, "\t\t\tinlist = needsync = 1;\n");
1788     f_print(fout, "\t\t\tbreak;\n");
1789     f_print(fout, "\t\t}\n");
1790     f_print(fout, "\t}\n");
1791     f_print(fout, "\tUNLOCK_UCLNT_CACHE;\n");
1792 #endif
1793     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");
1794     f_print(fout, "\tfor (pass = 0; pass < 2; pass++) {  /*p */\n");
1795     f_print(fout, "\t\t/* For each entry in our servers list */\n");
1796     f_print(fout, "\t\tfor (_ucount = 0;; _ucount++) {     /*s */\n\n");
1797     f_print(fout, "\t\tif (needsync) {\n");
1798     f_print(fout, "\t\t\t/* Need a sync site. Lets try to quickly find it */\n");
1799     f_print(fout, "\t\t\tif (aclient->syncSite) {\n");
1800     f_print(fout, "\t\t\t\tnewHost = aclient->syncSite;        /* already in network order */\n");
1801     f_print(fout, "\t\t\t\taclient->syncSite = 0;      /* Will reset if it works */\n");
1802     f_print(fout, "\t\t\t} else if (aclient->conns[3]) {\n");
1803     f_print(fout, "\t\t\t\t/* If there are fewer than four db servers in a cell,\n");
1804     f_print(fout, "\t\t\t\t* there's no point in making the GetSyncSite call.\n");
1805     f_print(fout, "\t\t\t\t* At best, it's a wash. At worst, it results in more\n");
1806     f_print(fout, "\t\t\t\t* RPCs than you would otherwise make.\n");
1807     f_print(fout, "\t\t\t\t*/\n");
1808     f_print(fout, "\t\t\t\ttc = aclient->conns[_ucount];\n");
1809     f_print(fout, "\t\t\t\tif (tc && rx_ConnError(tc)) {\n");
1810     f_print(fout, "\t\t\t\t\taclient->conns[_ucount] = tc = ubik_RefreshConn(tc);\n");
1811     f_print(fout, "\t\t\t\t}\n");
1812     f_print(fout, "\t\t\t\tif (!tc)\n");
1813     f_print(fout, "\t\t\t\t\tbreak;\n");
1814     f_print(fout, "\t\t\t\tcode = VOTE_GetSyncSite(tc, &newHost);\n");
1815     f_print(fout, "\t\t\t\tif (aclient->initializationState != origLevel)\n");
1816     f_print(fout, "\t\t\t\t\tgoto restart;   /* somebody did a ubik_ClientInit */\n");
1817     f_print(fout, "\t\t\t\tif (code)\n");
1818     f_print(fout, "\t\t\t\t\tnewHost = 0;\n");
1819     f_print(fout, "\t\t\t\tnewHost = htonl(newHost);   /* convert to network order */\n");
1820     f_print(fout, "\t\t\t} else {\n");
1821     f_print(fout, "\t\t\t\tnewHost = 0;\n");
1822     f_print(fout, "\t\t\t}\n");
1823     f_print(fout, "\t\t\tif (newHost) {\n");
1824     f_print(fout, "\t\t\t\t/* position count at the appropriate slot in the client\n");
1825     f_print(fout, "\t\t\t\t* structure and retry. If we can't find in slot, we'll\n");
1826     f_print(fout, "\t\t\t\t* just continue through the whole list \n");
1827     f_print(fout, "\t\t\t\t*/\n");
1828     f_print(fout, "\t\t\t\tfor (i = 0; i < MAXSERVERS && aclient->conns[i]; i++) {\n");
1829     f_print(fout, "\t\t\t\t\trxp = rx_PeerOf(aclient->conns[i]);\n");
1830     f_print(fout, "\t\t\t\t\tthisHost = rx_HostOf(rxp);\n");
1831     f_print(fout, "\t\t\t\t\tif (!thisHost)\n");
1832     f_print(fout, "\t\t\t\t\t\tbreak;\n");
1833     f_print(fout, "\t\t\t\t\tif (thisHost == newHost) {\n");
1834     f_print(fout, "\t\t\t\t\t\tif (chaseCount++ > 2)\n");
1835     f_print(fout, "\t\t\t\t\t\t\tbreak;  /* avoid loop asking */\n");
1836     f_print(fout, "\t\t\t\t\t\t_ucount = i;  /* this index is the sync site */\n");
1837     f_print(fout, "\t\t\t\t\t\tbreak;\n");
1838     f_print(fout, "\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n");
1839     f_print(fout, "\t\t/*needsync */\n");
1840     f_print(fout, "\t\ttc = aclient->conns[_ucount];\n");
1841     f_print(fout, "\t\tif (tc && rx_ConnError(tc)) {\n");
1842     f_print(fout, "\t\t\taclient->conns[_ucount] = tc = ubik_RefreshConn(tc);\n");
1843     f_print(fout, "\t\t}\n");
1844     f_print(fout, "\t\tif (!tc)\n");
1845     f_print(fout, "\t\t\tbreak;\n\n");
1846     f_print(fout, "\t\tif ((pass == 0) && (aclient->states[_ucount] & CFLastFailed)) {\n");
1847     f_print(fout, "\t\t\tcontinue;       /* this guy's down */\n");
1848     f_print(fout, "\t\t}\n");
1849
1850     f_print(fout, "\t\trcode = %s%s%s(tc\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1851     for (plist = defp->pc.plists; plist; plist = plist->next) {
1852         if (plist->component_kind == DEF_PARAM) {
1853             plist->pl.param_flag &= ~PROCESSED_PARAM;
1854             f_print(fout, ", %s", plist->pl.param_name);
1855         }
1856     }
1857     f_print(fout, ");\n");
1858     f_print(fout, "\t\tif (aclient->initializationState != origLevel) {\n");
1859     f_print(fout, "\t\t\t/* somebody did a ubik_ClientInit */\n");
1860     f_print(fout, "\t\t\tif (rcode)\n");
1861     f_print(fout, "\t\t\t\tgoto restart;       /* call failed */\n");
1862     f_print(fout, "\t\t\telse\n");
1863     f_print(fout, "\t\t\t\tgoto done;  /* call suceeded */\n");
1864     f_print(fout, "\t\t}\n");
1865     f_print(fout, "\t\tif (rcode < 0) {    /* network errors */\n");
1866     f_print(fout, "\t\t\taclient->states[_ucount] |= CFLastFailed; /* Mark server down */\n");
1867     f_print(fout, "\t\t} else if (rcode == UNOTSYNC) {\n");
1868     f_print(fout, "\t\t\tneedsync = 1;\n");
1869     f_print(fout, "\t\t} else if (rcode != UNOQUORUM) {\n");
1870     f_print(fout, "\t\t\t/* either misc ubik code, or misc appl code, or success. */\n");
1871     f_print(fout, "\t\t\taclient->states[_ucount] &= ~CFLastFailed;        /* mark server up*/\n");
1872     f_print(fout, "\t\t\tgoto done;      /* all done */\n");
1873     f_print(fout, "\t\t}\n");
1874     f_print(fout, "\t\t}                       /*s */\n");
1875     f_print(fout, "\t}                           /*p */\n\n");
1876     f_print(fout, "\tdone:\n");
1877     f_print(fout, "\tif (needsync) {\n");
1878
1879 #if 0 /* We should do some sort of caching algorithm for this, but I need to think about it - shadow 26 jun 06 */
1880     f_print(fout, "\t\tif (!inlist) {          /* Remember proc call that needs sync site */\n");
1881     f_print(fout, "\t\t\tLOCK_UCLNT_CACHE;\n");
1882     f_print(fout, "\t\t\tcalls_needsync[synccount % SYNCCOUNT] = (int *)%s%s%s;\n", prefix, PackagePrefix[PackageIndex], defp->pc.proc_name);
1883     f_print(fout, "\t\t\tsynccount++;\n");
1884     f_print(fout, "\t\t\tUNLOCK_UCLNT_CACHE;\n");
1885     f_print(fout, "\t\t\tinlist = 1;\n");
1886     f_print(fout, "\t\t}\n");
1887 #endif
1888     f_print(fout, "\t\tif (!rcode) {           /* Remember the sync site - cmd successful */\n");
1889     f_print(fout, "\t\t\trxp = rx_PeerOf(aclient->conns[_ucount]);\n");
1890     f_print(fout, "\t\t\taclient->syncSite = rx_HostOf(rxp);\n");
1891     f_print(fout, "\t\t}\n");
1892     f_print(fout, "\t}\n");
1893     f_print(fout, "\tUNLOCK_UBIK_CLIENT(aclient);\n");
1894     f_print(fout, "\treturn rcode;\n}\n\n");
1895 }
1896
1897
1898 static int
1899 opcode_holes_exist(void)
1900 {
1901     int i;
1902
1903     for (i = lowest_opcode[PackageIndex]; i < highest_opcode[PackageIndex];
1904          i++) {
1905         if (!opcodenum_is_defined(i))
1906             return 1;
1907     }
1908     return 0;
1909 }
1910
1911
1912 void
1913 er_Proc_CodeGeneration(void)
1914 {
1915     int temp;
1916
1917     temp = PackageIndex;
1918     if (!combinepackages)
1919         PackageIndex = 0;
1920     for (; PackageIndex <= temp; PackageIndex++) {
1921         if (proc_defined[PackageIndex] == NULL)
1922             continue;
1923         if (combinepackages || opcode_holes_exist()) {
1924             er_HeadofOldStyleProc_setup();
1925             er_BodyofOldStyleProc_setup();
1926             er_TailofOldStyleProc_setup();
1927             er_HeadofOldStyleProc_setup2();
1928             er_BodyofOldStyleProc_setup2();
1929             er_TailofOldStyleProc_setup2();
1930         } else {
1931             er_ProcDeclExterns_setup();
1932             er_ProcProcsArray_setup();
1933             er_ProcMainBody_setup();
1934         }
1935     }
1936     PackageIndex = temp;
1937 }
1938
1939
1940 static void
1941 er_ProcDeclExterns_setup(void)
1942 {
1943     list *listp;
1944     definition *defp;
1945
1946     if ( !Sflag )
1947         return;
1948
1949     f_print(fout, "\n");
1950     for (listp = proc_defined[PackageIndex]; listp != NULL;
1951          listp = listp->next) {
1952         defp = (definition *) listp->val;
1953         if (defp->pc.proc_serverstub) {
1954             f_print(fout, "afs_int32 %s();\n", defp->pc.proc_serverstub);
1955         }
1956     }
1957 }
1958
1959
1960 static void
1961 er_ProcProcsArray_setup(void)
1962 {
1963     list *listp;
1964     definition *defp;
1965
1966     if ((listp = proc_defined[PackageIndex])) {
1967         defp = (definition *) listp->val;
1968         if ( cflag )  {
1969             f_print(fout, "\nstatic char *opnames%d[] = {\"%s%s\"",
1970                         PackageIndex, defp->pc.proc_prefix, defp->pc.proc_name);
1971         }
1972         else {
1973             if (defp->pc.proc_serverstub) {
1974                 f_print(fout, "\nstatic afs_int32 (*StubProcsArray%d[])() = {%s",
1975                         PackageIndex, defp->pc.proc_serverstub);
1976             } else {
1977                 f_print(fout,
1978                         "\nstatic afs_int32 (*StubProcsArray%d[])(struct rx_call *z_call, XDR *z_xdrs) = {_%s%s%s",
1979                         PackageIndex, prefix, defp->pc.proc_prefix,
1980                         ((definition *) listp->val)->pc.proc_name);
1981             }
1982         }
1983         listp = listp->next;
1984     }
1985     for (; listp != NULL; listp = listp->next) {
1986         defp = (definition *) listp->val;
1987         if ( cflag ) {
1988             f_print(fout, ", \"%s%s\"",defp->pc.proc_prefix,defp->pc.proc_name);
1989         }
1990         else {
1991             if (defp->pc.proc_serverstub) {
1992                 f_print(fout, ",%s", defp->pc.proc_serverstub);
1993             } else {
1994                 f_print(fout, ", _%s%s%s", prefix, defp->pc.proc_prefix,
1995                         defp->pc.proc_name);
1996             }
1997         }
1998     }
1999     f_print(fout, "};\n\n");
2000 }
2001
2002
2003 static void
2004 er_ProcMainBody_setup(void)
2005 {
2006     if ( cflag ) {
2007         f_print(fout, "char *%sTranslateOpCode(int op)\n{\n",
2008                 PackagePrefix[PackageIndex]);
2009         f_print(fout, "\tif (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\treturn NULL;\n",
2010                 PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
2011         f_print(fout, "\treturn opnames%d[op - %sLOWEST_OPCODE];\n}\n",
2012                 PackageIndex, PackagePrefix[PackageIndex]);
2013         f_print(fout, "struct %sstats *%sOpCodeStats(int op)\n{\n",
2014                 PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
2015         f_print(fout, "\tif (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\treturn NULL;\n",
2016                 PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
2017         f_print(fout, "\treturn NULL;/*%d %s*/\n}\n",
2018                 PackageIndex, PackagePrefix[PackageIndex]);
2019
2020         return;
2021     }
2022     f_print(fout, "int %s%sExecuteRequest(struct rx_call *z_call)\n",
2023             prefix, PackagePrefix[PackageIndex]);
2024     f_print(fout, "{\n\tint op;\n");
2025     f_print(fout, "\tXDR z_xdrs;\n");
2026     f_print(fout, "\t" "afs_int32 z_result;\n\n");
2027     f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
2028     f_print(fout,
2029             "\tif (!xdr_int(&z_xdrs, &op))\n\t\tz_result = RXGEN_DECODE;\n");
2030     f_print(fout,
2031             "\telse if (op < %sLOWEST_OPCODE || op > %sHIGHEST_OPCODE)\n\t\tz_result = RXGEN_OPCODE;\n",
2032             PackagePrefix[PackageIndex], PackagePrefix[PackageIndex]);
2033     f_print(fout,
2034             "\telse\n\t\tz_result = (*StubProcsArray%d[op - %sLOWEST_OPCODE])(z_call, &z_xdrs);\n",
2035             PackageIndex, PackagePrefix[PackageIndex]);
2036     f_print(fout, "\treturn hton_syserr_conv(z_result);\n}\n");
2037 }
2038
2039 static void
2040 er_HeadofOldStyleProc_setup2(void)
2041 {
2042     if ( cflag ) {
2043         f_print(fout, "int %sOpCodeIndex(int op)\n{\n", (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
2044         f_print(fout, "\tswitch (op) {\n");
2045     }
2046 }
2047
2048 static void
2049 er_HeadofOldStyleProc_setup(void)
2050 {
2051     if ( cflag ) {
2052         f_print(fout, "char *%sTranslateOpCode(int op)\n{\n",
2053             (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
2054     }
2055     else {
2056         f_print(fout,
2057                 "\nint %s%sExecuteRequest (struct rx_call *z_call)\n",
2058                 prefix,
2059                 (combinepackages ? MasterPrefix : PackagePrefix[PackageIndex]));
2060         f_print(fout, "{\n");
2061         f_print(fout, "\tint op;\n");
2062         f_print(fout, "\tXDR z_xdrs;\n");
2063         f_print(fout, "\t" "afs_int32 z_result;\n\n");
2064         f_print(fout, "\txdrrx_create(&z_xdrs, z_call, XDR_DECODE);\n");
2065         f_print(fout, "\tz_result = RXGEN_DECODE;\n");
2066         f_print(fout, "\tif (!xdr_int(&z_xdrs, &op)) goto fail;\n");
2067     }
2068     f_print(fout, "\tswitch (op) {\n");
2069 }
2070
2071 static void
2072 er_BodyofOldStyleProc_setup(void)
2073 {
2074     list *listp;
2075
2076     if (combinepackages) {
2077         int temp = PackageIndex;
2078         for (PackageIndex = 0; PackageIndex <= temp; PackageIndex++) {
2079             for (listp = proc_defined[PackageIndex]; listp != NULL;
2080                  listp = listp->next)
2081                 proc_er_case((definition *) listp->val);
2082         }
2083         PackageIndex = temp;
2084     } else {
2085         for (listp = proc_defined[PackageIndex]; listp != NULL;
2086              listp = listp->next)
2087             proc_er_case((definition *) listp->val);
2088     }
2089 }
2090
2091
2092 static void
2093 proc_er_case(definition * defp)
2094 {
2095     if ( cflag ) {
2096         f_print(fout, "\t\tcase %d:", defp->pc.proc_opcodenum);
2097         f_print(fout, "\treturn \"%s%s\";\n",
2098                 defp->pc.proc_prefix, defp->pc.proc_name);
2099         return;
2100     }
2101     if (opcodesnotallowed[PackageIndex]) {
2102         f_print(fout, "\t\tcase %d:\n", defp->pc.proc_opcodenum);
2103     } else {
2104         f_print(fout, "\t\tcase %s:\n", defp->pc.proc_opcodename);
2105     }
2106     if (defp->pc.proc_serverstub) {
2107         f_print(fout, "\t\t\tz_result = %s(z_call, &z_xdrs);\n",
2108                 defp->pc.proc_serverstub);
2109     } else {
2110         f_print(fout, "\t\t\tz_result = _%s%s%s(z_call, &z_xdrs);\n", prefix,
2111                 defp->pc.proc_prefix, defp->pc.proc_name);
2112     }
2113     f_print(fout, "\t\t\tbreak;\n");
2114 }
2115
2116 static void
2117 proc_op_case(definition * defp)
2118 {
2119     f_print(fout, "\t\tcase %d:", defp->pc.proc_opcodenum);
2120     f_print(fout, "\treturn %d;\n",
2121             defp->statindex);
2122 }
2123
2124 static void
2125 er_BodyofOldStyleProc_setup2(void)
2126 {
2127     list *listp;
2128
2129     if (!cflag)
2130         return;
2131     if (combinepackages) {
2132         int temp = PackageIndex;
2133         for (PackageIndex = 0; PackageIndex <= temp; PackageIndex++) {
2134             for (listp = proc_defined[PackageIndex]; listp != NULL;
2135                  listp = listp->next)
2136                 proc_op_case((definition *) listp->val);
2137         }
2138         PackageIndex = temp;
2139     } else {
2140         for (listp = proc_defined[PackageIndex]; listp != NULL;
2141              listp = listp->next)
2142             proc_op_case((definition *) listp->val);
2143     }
2144 }
2145
2146 static void
2147 er_TailofOldStyleProc_setup2(void)
2148 {
2149     if ( cflag ) {
2150         f_print(fout, "\t\tdefault:\n");
2151         f_print(fout, "\t\t\treturn -1;\n\t}\n}\n");
2152     }
2153 }
2154
2155 static void
2156 er_TailofOldStyleProc_setup(void)
2157 {
2158     f_print(fout, "\t\tdefault:\n");
2159     if ( cflag ) {
2160         f_print(fout, "\t\t\treturn NULL;\n\t}\n}\n");
2161         return;
2162     }
2163     f_print(fout, "\t\t\tz_result = RXGEN_OPCODE;\n");
2164     f_print(fout, "\t\t\tbreak;\n\t}\n");
2165     f_print(fout, "fail:\n");
2166     f_print(fout, "\treturn z_result;\n}\n");
2167 }
2168
2169 static void
2170 h_ProcMainBody_setup(void)
2171 {
2172     f_print(fout,"\nextern int %s%sExecuteRequest(struct rx_call *);\n",
2173             prefix, PackagePrefix[PackageIndex]);
2174 }
2175
2176 static void
2177 h_HeadofOldStyleProc_setup(void)
2178 {
2179     char *pprefix = (combinepackages ? MasterPrefix :
2180                      PackagePrefix[PackageIndex]);
2181     f_print(fout,"\nstruct %sstats{\n\tint statsver;\n};", pprefix);
2182     f_print(fout,"\nextern int %s%sExecuteRequest(struct rx_call *);\n",
2183             prefix, pprefix);
2184     f_print(fout,"\nextern int %sOpCodeIndex(int op);\n", PackagePrefix[PackageIndex]);
2185 }
2186
2187 void
2188 h_Proc_CodeGeneration(void)
2189 {
2190     int temp;
2191
2192     temp = PackageIndex;
2193     if (!combinepackages)
2194         PackageIndex = 0;
2195     for (; PackageIndex <= temp; PackageIndex++) {
2196         if (combinepackages || opcode_holes_exist()) {
2197             h_HeadofOldStyleProc_setup();
2198         } else {
2199             h_ProcMainBody_setup();
2200         }
2201     }
2202     PackageIndex = temp;
2203 }
2204
2205 static void
2206 proc_h_case(definition * defp)
2207 {
2208     f_print(fout, "#define opcode_%s%s \t((afs_uint64)((%uLL << 32) + %sOpCodeIndex(%u)))\n",
2209             defp->pc.proc_prefix, defp->pc.proc_name, StatIndex,
2210             defp->pc.proc_prefix, defp->pc.proc_opcodenum);
2211 }
2212
2213 void
2214 h_opcode_stats_pkg(char *pprefix, int lowest, int highest, int nops,
2215                   int statfuncs, char *ptype, list *proclist)
2216 {
2217     list *listp;
2218
2219     if (!pprefix)
2220         return;
2221
2222     f_print(fout,
2223             "\n/* Opcode-related useful stats for %spackage: %s */\n",
2224             ptype, pprefix);
2225     f_print(fout, "#define %sLOWEST_OPCODE   %d\n", pprefix, lowest);
2226     f_print(fout, "#define %sHIGHEST_OPCODE     %d\n", pprefix, highest);
2227     f_print(fout, "#define %sNUMBER_OPCODES     %d\n\n", pprefix, nops);
2228
2229     for (listp = proclist; listp != NULL;
2230          listp = listp->next)
2231         proc_h_case((definition *) listp->val);
2232
2233     if (xflag) {
2234         f_print(fout, "#define %sNO_OF_STAT_FUNCS\t%d\n\n",
2235                 pprefix, statfuncs);
2236         f_print(fout, "AFS_RXGEN_EXPORT\n");
2237         f_print(fout, "extern const char *%sfunction_names[];\n\n",
2238                 pprefix);
2239     }
2240 }
2241
2242 void
2243 h_opcode_stats(void)
2244 {
2245     if (combinepackages) {
2246         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]);
2247     } else {
2248         int i;
2249         for (i = 0; i <= PackageIndex; i++) {
2250             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]);
2251         }
2252     }
2253 }
2254
2255
2256 void
2257 generate_multi_macros(definition * defp)
2258 {
2259     char *startname = SplitStart, *endname = SplitEnd;
2260     proc1_list *plist;
2261     int numofparams;
2262     int first = 0;
2263
2264     if (!hflag)
2265         return;
2266     if (!Multi_Init) {
2267         Multi_Init = 1;
2268         f_print(fout, "\n#include <rx/rx_multi.h>");
2269     }
2270     f_print(fout, "\n#define multi_%s%s(", PackagePrefix[PackageIndex],
2271             defp->pc.proc_name);
2272     for (plist = defp->pc.plists; plist; plist = plist->next) {
2273         if (plist->component_kind == DEF_PARAM) {
2274             if (!first) {
2275                 first = 1;
2276                 f_print(fout, "%s", plist->pl.param_name);
2277             } else {
2278                 f_print(fout, ", %s", plist->pl.param_name);
2279             }
2280         }
2281     }
2282     f_print(fout, ") \\\n");
2283     if (!startname)
2284         startname = "Start";
2285     if (!endname)
2286         endname = "End";
2287     f_print(fout, "\tmulti_Body(%s%s%s(multi_call", startname,
2288             PackagePrefix[PackageIndex], defp->pc.proc_name);
2289     do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 0);
2290     for (plist = defp->pc.plists; plist; plist = plist->next) {
2291         if (plist->component_kind == DEF_PARAM)
2292             f_print(fout, ", %s", plist->pl.param_name);
2293     }
2294     do_split(defp, OUT, &numofparams, DEF_OUTPARAM, 1);
2295     f_print(fout, "), %s%s%s(multi_call", endname,
2296             PackagePrefix[PackageIndex], defp->pc.proc_name);
2297     do_split(defp, IN, &numofparams, DEF_INPARAM, 0);
2298     for (plist = defp->pc.plists; plist; plist = plist->next) {
2299         if (plist->component_kind == DEF_PARAM) {
2300             f_print(fout, ", %s", plist->pl.param_name);
2301         }
2302     }
2303     do_split(defp, IN, &numofparams, DEF_INPARAM, 1);
2304     f_print(fout, "))\n\n");
2305 }
2306
2307
2308 int
2309 IsRxgenToken(token * tokp)
2310 {
2311     if (tokp->kind == TOK_PACKAGE || tokp->kind == TOK_PREFIX
2312         || tokp->kind == TOK_SPECIAL || tokp->kind == TOK_STARTINGOPCODE
2313         || tokp->kind == TOK_SPLITPREFIX || tokp->kind == TOK_PROC
2314         || tokp->kind == TOK_STATINDEX)
2315         return 1;
2316     return 0;
2317 }
2318
2319 int
2320 IsRxgenDefinition(definition * def)
2321 {
2322     if (def->def_kind == DEF_PACKAGE || def->def_kind == DEF_PREFIX
2323         || def->def_kind == DEF_SPECIAL || def->def_kind == DEF_STARTINGOPCODE
2324         || def->def_kind == DEF_SPLITPREFIX || def->def_kind == DEF_PROC)
2325         return 1;
2326     return 0;
2327 }