2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 * generator.c -- phase 2 of the generator.
13 * takes a file, which has a list of signature as input,
14 * and outputs the client, server, .xg, and makefiles
15 * This file is normally created by running tableGen.c,
16 * but theoretically could be generated by a human.
18 * Format of the signatures : no_of_args list_of_arg_signs
19 * arg_sign : (dir type)
22 * This program is used to generate client/server pairs that
23 * make and verify random rpcs. It can be used to generate
24 * both pthread and lwp versions of the client and server.
25 * It was designed to verify that the new pthread rx library
26 * was functioning correctly.
28 * The key to understanding how this program works is to realize
29 * that all the data necessary to generate the client/server
30 * code is generated first, in char string format.
31 * For example, if you are generating 10 rpc's, the input and
32 * output values of all the parameters are generated - and
33 * stored as strings. This allows you to write out the values
34 * as the client and server are created without having to worry
35 * about data type conversion.
37 * In addition, these strings (along with other information) are
38 * stored in a structure that is iterated over many times during
39 * the construction of the client and server.
41 * Often this iteration takes the form of:
42 * for (i=0; i < argsP->argCount; i++)
44 * It may be possible to eliminate some of these iterations for
45 * efficiency sake, but this was not done - allowing an easier
48 * The bulk of this code was lifted from the delight project.
52 #include <afsconfig.h>
53 #include <afs/param.h>
64 #include "generator.h"
66 static char *unix_symbols[] = {
68 "include ../../../config/Makefile.$(SYS_NAME)\n",
71 "#include <netdb.h>\n",
75 "LIBS = $(DESTDIR)lib/libafsrpc.so \\\n"
76 "\t$(DESTDIR)lib/afs/libcmd.a \\\n"
77 "\t$(DESTDIR)lib/afs/libafs_com_err.a \\\n"
78 "\t$(DESTDIR)lib/afs/util.a \n",
81 "LIBS = $(DESTDIR)lib/librxkad.a \\\n" "\t$(DESTDIR)lib/libdes.a \\\n"
82 "\t$(DESTDIR)lib/librx.a \\\n" "\t$(DESTDIR)lib/liblwp.a \\\n"
83 "\t$(DESTDIR)lib/afs/libcmd.a \\\n"
84 "\t$(DESTDIR)lib/afs/libafs_com_err.a \\\n"
85 "\t$(DESTDIR)lib/afs/util.a \\\n" "\t/usr/ucblib/libucb.a \n",
88 "\t@if [ ! -r DEST ] ; \\\n" "\tthen \\\n"
89 "\t\techo \"Must create DEST link by hand before building tests\"; \\\n"
90 "\t\texit 1; \\\n" "\tfi\n"
93 static char *nt_symbols[] = {
95 "!INCLUDE ../../../config/NTMakefile.$(SYS_NAME)\n",
98 "#include <windows.h>\n",
102 "LIBS = $(DESTDIR)/lib/afsrpc.lib \\\n"
103 "\t$(DESTDIR)/lib/afs/afscmd.lib \\\n"
104 "\t$(DESTDIR)/lib/afs/afsafs_com_err.lib \\\n"
105 "\t$(DESTDIR)/lib/afs/afsutil.lib \\\n"
106 "\t$(DESTDIR)/lib/pthread.lib \\\n" "\t$(DESTDIR)/lib/afsreg.lib \\\n"
110 "LIBS = $(DESTDIR)/lib/afsrxkad.lib \\\n"
111 "\t$(DESTDIR)/lib/afsdes.lib \\\n" "\t$(DESTDIR)/lib/afsrx.lib \\\n"
112 "\t$(DESTDIR)/lib/afslwp.lib \\\n"
113 "\t$(DESTDIR)/lib/afs/afscmd.lib \\\n"
114 "\t$(DESTDIR)/lib/afs/afsafs_com_err.lib \\\n"
115 "\t$(DESTDIR)/lib/afs/afsutil.lib \\\n"
116 "\t$(DESTDIR)/lib/afsreg.lib \n",
119 "!\tIF (!EXIST(DEST))\n"
120 "!\t\tERROR Must create DEST link by hand before building tests\n"
124 static char **platform = nt_symbols;
127 #define strdup(x) _strdup(x)
131 * 31 bit random number generator, we don't really care how random
132 * these numbers are, it is more important that identical rx files
133 * are generated no matter what platform the generator runs on
135 static unsigned long randVal = 0x330E16;
142 static threadModel_t threadModel = PTHREADS;
147 randVal = ((randVal * 0xEECE66D) + 0xB) & 0xFFFFFFFF;
148 return ((double)(randVal) / 4294967296.0);
152 * GetDescription writes a one line comment describing the parameters
153 * used in an rpc in the client program
156 GetDescription(rpcArgs * argsP)
162 (char *)calloc((MAX_TYP_STR + MAX_DIR_STR + ATTRIB_LEN * ATTRIB_NO)
163 * argsP->argCount + 3, sizeof(char));
164 MEM_CHK(bufP2, "GetDescription: out of mem bufP2\n");
166 for (i = 0; i < argsP->argCount; i++) {
167 strcat(bufP2, argsP->argDescr[i].direction);
168 strcat(bufP2, argsP->argDescr[i].type);
174 * GetName -- get the name of the current server/instance
177 GetName(char *serverName, int sign_no)
179 /* itl file name 8.3 format */
182 bufP = (char *)malloc(32 * sizeof(char));
183 MEM_CHK(bufP, "GetName: bufP out of mem\n");
185 sprintf(bufP, "%s%d", serverName, sign_no);
190 * OpenOutFile -- open a file in the output directory
193 OpenOutFile(char *outDir, char *fileName, char *tailStr)
200 (char *)malloc(sizeof(char) *
201 (strlen(fileName) + strlen(tailStr) +
202 strlen(outDir) + 2));
203 MEM_CHK(bufP, "OpenOutFile : Out of mem -- bufP\n");
204 sprintf(bufP, "%s/%s%s", outDir, fileName, tailStr);
207 (char *)malloc(sizeof(char) *
208 (strlen(fileName) + strlen(tailStr) + 1));
209 MEM_CHK(bufP, "OpenOutFile : Out of mem -- bufP\n");
210 sprintf(bufP, "%s%s", fileName, tailStr);
212 fP = fopen(bufP, "w");
213 MEM_CHK(fP, "main: Unable to open output file\n");
219 * WriteXGDecl -- write the declaration for a parameter
222 WriteXGDecl(arg_tuple * arg, FILE * xg_h, int i, int structFlag, int lastFlag)
225 if (!strcmp(arg->type, "varString")) {
226 fprintf(xg_h, "\tchar a%d[STR_MAX];\n", i);
228 fprintf(xg_h, "\tdrpc_%s_t a%d;\n", arg->type, i);
231 if (!strncmp(arg->type, "ar_", 2)) {
232 fprintf(xg_h, "\t%s drpc_out_%s_t *a%d", arg->direction,
234 } else if (!strcmp(arg->type, "varString")) {
235 fprintf(xg_h, "\t%s string a%d<STR_MAX>", arg->direction, i);
236 } else if (!strcmp(arg->direction, "IN")) {
237 fprintf(xg_h, "\t%s drpc_%s_t a%d", arg->direction, arg->type, i);
239 fprintf(xg_h, "\t%s drpc_%s_t *a%d", arg->direction, arg->type,
251 * WriteXG -- write the body of the xg interface
254 WriteXG(rpcArgs * argsP, FILE * xg_h, char *serverName, int sign_no)
257 char *name = GetName(serverName, sign_no);
260 * CASE 1: all arguments passed as parameters
263 fprintf(xg_h, "\nproc %s(\n", name);
265 /* declare each arg */
266 for (i = 0; i < argsP->argCount; i++) {
267 WriteXGDecl(&argsP->argDescr[i], xg_h, i, FALSE,
268 (i == argsP->argCount - 1));
271 /* Now pass the paramaters inside a structure */
272 fprintf(xg_h, "\nstruct %s_t {\n", name);
273 for (i = 0; i < argsP->argCount; i++) {
274 WriteXGDecl(&argsP->argDescr[i], xg_h, i, TRUE,
275 (i == argsP->argCount - 1));
277 fprintf(xg_h, "} ;\n");
278 fprintf(xg_h, "\nproc %s_s(\n", name);
279 fprintf(xg_h, "\tINOUT struct %s_t *s);\n", name);
285 * GetRandStr -- get a random string
288 GetRandStr(int strLen, char **ret, int *rP)
296 randI = 'A' + ('Z' - 'A') * drand32();
297 sprintf(buf, "%c", randI);
306 * GetRandP -- sets a string to a random value of the data type
307 * inthe case of a char type, ret holds "%c" and ret2 holds '%c'
310 GetRandP(char *typ, char **ret, char **ret2)
317 *ret = (char *)calloc(MAX_RAND_LENGTH + 1, sizeof(char));
318 *ret2 = (char *)calloc(MAX_RAND_LENGTH + 1, sizeof(char));
320 if (strstr(typ, "char")) {
321 GetRandStr(1, ret2, &randI);
323 strcpy(*ret2, "'\\\\'");
324 else if (randI == '\'')
325 strcpy(*ret2, "'\\''");
327 sprintf(*ret, "'%c'", randI);
329 } else if (strstr(typ, "short")) {
330 shI = SHRT_MIN + (SHRT_MAX - SHRT_MIN) * drand32();
331 sprintf(*ret, "%d", shI);
333 } else if (strstr(typ, "afs_int32")) {
334 randI = INT_MIN + UINT_MAX * drand32();
335 if (randI < INT_MIN || randI > INT_MAX) {
336 fprintf(stderr, "GetRandP: afs_int32 %d out of bounds\n", randI);
339 sprintf(*ret, "%d", randI);
341 } else if (strstr(typ, "float")) {
344 sprintf(*ret, "%2.8e", f);
347 } else if (strstr(typ, "double")) {
349 sprintf(*ret, "%2.16e", d1);
352 } else if (strstr(typ, "String")) {
353 strLen = (MAX_RAND_LENGTH - 2) * drand32();
354 GetRandStr(strLen, ret, &randI);
361 * GenParamValues -- generate the parameter values for an rpc
364 GenParamValues(rpcArgs * argsP)
369 /* generate random values for each argument */
370 for (i = 0; i < argsP->argCount; i++) {
372 argsP->argDescr[i].vc_low = 0;
373 argsP->argDescr[i].vc_max = IDL_FIX_ARRAY_SIZE - 1;
374 argsP->argDescr[i].vc_high = IDL_FIX_ARRAY_SIZE - 1;
375 argsP->argDescr[i].ovc_low = 0;
376 argsP->argDescr[i].ovc_high = IDL_FIX_ARRAY_SIZE - 1;
378 if (!strncmp(argsP->argDescr[i].type, "ar_", 3)) {
379 typ = argsP->argDescr[i].type + 3;
380 for (j = 0; j < IDL_FIX_ARRAY_SIZE; j++) {
381 GetRandP(typ, &argsP->argDescr[i].inValue[j],
382 &argsP->argDescr[i].inValue2[j]);
383 GetRandP(typ, &argsP->argDescr[i].outValue[j],
384 &argsP->argDescr[i].outValue2[j]);
387 GetRandP(argsP->argDescr[i].type, &argsP->argDescr[i].inValue[0],
388 &argsP->argDescr[i].inValue2[0]);
389 GetRandP(argsP->argDescr[i].type, &argsP->argDescr[i].outValue[0],
390 &argsP->argDescr[i].outValue2[0]);
396 * WriteServC -- write the rpcs in the server file
399 WriteServC(rpcArgs * argsP, FILE * srv_h, char *serverName, int sign_no)
404 name = GetName(serverName, sign_no);
405 fprintf(srv_h, "\nint A%s(struct rx_call *c,\n", name);
407 /* declare each arg */
408 for (i = 0; i < argsP->argCount; i++) {
410 if (!strcmp(argsP->argDescr[i].type, "varString")) {
411 if (!strcmp(argsP->argDescr[i].direction, "IN")) {
412 fprintf(srv_h, "\tchar *a%d", i);
414 fprintf(srv_h, "\tchar **a%d", i);
416 } else if (strncmp(argsP->argDescr[i].type, "ar_", 3)
417 && (!strcmp(argsP->argDescr[i].direction, "IN"))) {
418 fprintf(srv_h, "\tdrpc_%s_t a%d", argsP->argDescr[i].type, i);
420 if (!strncmp(argsP->argDescr[i].type, "ar_", 3)) {
421 fprintf(srv_h, "\tdrpc_out_%s_t *a%d",
422 argsP->argDescr[i].type, i);
424 fprintf(srv_h, "\tdrpc_%s_t *a%d", argsP->argDescr[i].type,
428 if (i < (argsP->argCount - 1)) {
429 fprintf(srv_h, ",\n");
432 fputs(")\n{\n", srv_h); /* balance the } */
433 fputs("\tint errFlag = 0;", srv_h);
436 * check the in and inout parameters
438 for (i = 0; i < argsP->argCount; i++) {
440 if (!strcmp(argsP->argDescr[i].direction, "IN")
441 || (!strcmp(argsP->argDescr[i].direction, "INOUT")
442 && !strcmp(argsP->argDescr[i].type, "varString"))) {
444 typ = argsP->argDescr[i].type;
446 if (strstr(typ, "String")) {
447 if (!strcmp(argsP->argDescr[i].direction, "INOUT")) {
448 fprintf(srv_h, "\n\tCHECK%s((char *)*a%d, %s, \"%s\");",
449 typ, i, argsP->argDescr[i].inValue[0], name);
451 fprintf(srv_h, "\n\tCHECK%s((char *)a%d, %s, \"%s\");",
452 typ, i, argsP->argDescr[i].inValue[0], name);
454 } else if (!strcmp(typ, "afs_int32")) {
455 fprintf(srv_h, "\n\tCHECK%s(a%d, %sL, \"%s\");", typ, i,
456 argsP->argDescr[i].inValue[0], name);
458 if (!strncmp(typ, "ar_", 3)) {
459 for (j = 0; j < IDL_FIX_ARRAY_SIZE; j++)
461 "\n\tCHECK%s(a%d->drpc_out_%s_t_val[%d], %s, \"%s\");",
462 (typ + 3), i, typ, j,
463 argsP->argDescr[i].inValue[j], name);
465 fprintf(srv_h, "\n\tCHECK%s(a%d, %s, \"%s\");", typ, i,
466 argsP->argDescr[i].inValue[0], name);
469 } else if (!strcmp(argsP->argDescr[i].direction, "INOUT")) {
471 typ = argsP->argDescr[i].type;
473 if (strstr(typ, "String")) {
474 fprintf(srv_h, "\n\tCHECK%s((char *)*a%d, %s, \"%s\");", typ,
475 i, argsP->argDescr[i].inValue[0], name);
476 } else if (!strcmp(typ, "afs_int32")) {
477 fprintf(srv_h, "\n\tCHECK%s(*a%d, %sL, \"%s\");", typ, i,
478 argsP->argDescr[i].inValue[0], name);
480 if (!strncmp(typ, "ar_", 3)) {
481 for (j = 0; j < IDL_FIX_ARRAY_SIZE; j++)
483 "\n\tCHECK%s(a%d->drpc_out_%s_t_val[%d], %s, \"%s\");",
484 (typ + 3), i, typ, j,
485 argsP->argDescr[i].inValue[j], name);
487 fprintf(srv_h, "\n\tCHECK%s(*a%d, %s, \"%s\");", typ, i,
488 argsP->argDescr[i].inValue[0], name);
495 * free up memory for dynamic input args
497 for (i = 0; i < argsP->argCount; i++) {
498 if (!strncmp(argsP->argDescr[i].type, "ar_", 3)) {
499 typ = argsP->argDescr[i].type;
500 if (!strcmp(argsP->argDescr[i].direction, "INOUT")) {
502 "\n\tif (a%d->drpc_out_%s_t_val) "
503 "free(a%d->drpc_out_%s_t_val);", i, typ, i, typ);
505 if (!strcmp(argsP->argDescr[i].direction, "INOUT")
506 || !strcmp(argsP->argDescr[i].direction, "OUT")) {
508 "\n\ta%d->drpc_out_%s_t_val = (%s *) "
509 "malloc(FIX_ARRAY_SIZE * sizeof(%s));", i, typ,
510 (typ + 3), (typ + 3));
511 fprintf(srv_h, "\n\ta%d->drpc_out_%s_t_len = FIX_ARRAY_SIZE;",
518 * set the inout and out parameters
520 for (i = 0; i < argsP->argCount; i++) {
522 if (!strcmp(argsP->argDescr[i].direction, "INOUT")
523 || !strcmp(argsP->argDescr[i].direction, "OUT")) {
525 typ = argsP->argDescr[i].type;
527 if (!strncmp(typ, "ar_", 3)) {
528 for (j = 0; j < IDL_FIX_ARRAY_SIZE; j++)
529 fprintf(srv_h, "\n\ta%d->drpc_out_%s_t_val[%d] = %s;", i,
530 typ, j, argsP->argDescr[i].outValue[j]);
531 } else if (!strcmp(typ, "afs_int32")) {
532 fprintf(srv_h, "\n\t*a%d = %sL;", i,
533 argsP->argDescr[i].outValue[0]);
534 } else if (!strcmp(typ, "varString")) {
535 if (!strcmp(argsP->argDescr[i].direction, "OUT")) {
536 fprintf(srv_h, "\n\t*a%d = (char *) malloc(STR_MAX);", i);
538 fprintf(srv_h, "\n\tstrcpy((char *)*a%d, %s);", i,
539 argsP->argDescr[i].outValue[0]);
540 } else if (strstr(typ, "String")) {
541 fprintf(srv_h, "\n\t*a%d = (drpc_%s_t)rpc_ss_allocate(%d);",
542 i, typ, strlen(argsP->argDescr[i].outValue[0]) - 1);
543 fprintf(srv_h, "\n\tstrcpy((char *)*a%d, %s);", i,
544 argsP->argDescr[i].outValue[0]);
546 fprintf(srv_h, "\n\t*a%d = %s;", i,
547 argsP->argDescr[i].outValue[0]);
553 "\n\tif (errFlag) {" "\n\t\tprintf(\"%s: failed\\n\");"
554 "\n\t\tfflush(stdout);" "\n\t}" "\n\treturn errFlag;\n}\n", name);
557 * second routine with arguments inside a structure
560 "\nint A%s_s(struct rx_call *c,\n\t%s_t *s)\n{"
561 "\n\tint errFlag = 0;", name, name);
564 * check the in and inout parameters
566 for (i = 0; i < argsP->argCount; i++) {
568 if (!strcmp(argsP->argDescr[i].direction, "IN")
569 || (!strstr(argsP->argDescr[i].type, "String")
570 && !strcmp(argsP->argDescr[i].direction, "INOUT"))) {
572 typ = argsP->argDescr[i].type;
574 if (!strncmp(typ, "ar_", 3)) {
575 for (j = 0; j < IDL_FIX_ARRAY_SIZE; j++)
576 fprintf(srv_h, "\n\tCHECK%s(s->a%d[%d], %s, \"%s_s\");",
577 (typ + 3), i, j, argsP->argDescr[i].inValue[j],
579 } else if (strstr(typ, "String")) {
580 fprintf(srv_h, "\n\tCHECK%s((char *)s->a%d, %s, \"%s_s\");",
581 typ, i, argsP->argDescr[i].inValue[0], name);
582 } else if (!strcmp(typ, "afs_int32")) {
583 fprintf(srv_h, "\n\tCHECK%s(s->a%d, %sL, \"%s_s\");", typ, i,
584 argsP->argDescr[i].inValue[0], name);
586 fprintf(srv_h, "\n\tCHECK%s(s->a%d, %s, \"%s_s\");", typ, i,
587 argsP->argDescr[i].inValue[0], name);
593 * set the inout and out parameters
595 for (i = 0; i < argsP->argCount; i++) {
597 if (!strcmp(argsP->argDescr[i].direction, "INOUT")
598 || !strcmp(argsP->argDescr[i].direction, "OUT")) {
600 typ = argsP->argDescr[i].type;
602 if (!strncmp(typ, "ar_", 3)) {
603 for (j = 0; j < IDL_FIX_ARRAY_SIZE; j++)
604 fprintf(srv_h, "\n\ts->a%d[%d]= %s;", i, j,
605 argsP->argDescr[i].outValue[j]);
606 } else if (!strcmp(typ, "afs_int32")) {
607 fprintf(srv_h, "\n\ts->a%d = %sL;", i,
608 argsP->argDescr[i].outValue[0]);
609 } else if (!strcmp(typ, "varString")) {
610 fprintf(srv_h, "\n\tstrcpy((char *)s->a%d, %s);", i,
611 argsP->argDescr[i].outValue[0]);
612 } else if (strstr(typ, "String")) {
613 fprintf(srv_h, "\n\ts->a%d = rpc_ss_allocate(%d);", i,
614 strlen(argsP->argDescr[i].outValue[0]) - 1);
615 fprintf(srv_h, "\n\tstrcpy((char *)s->a%d, %s);", i,
616 argsP->argDescr[i].outValue[0]);
618 fprintf(srv_h, "\n\ts->a%d = %s;", i,
619 argsP->argDescr[i].outValue[0]);
625 "\n\tif (errFlag) {" "\n\t\tprintf(\"%s_s: failed\\n\");" "\n\t}"
626 "\n\tfflush(stdout);" "\n\treturn errFlag;\n}\n", name);
633 * WriteMake - write the makefile for a particular client/server pair
636 WriteMake(char *serverName, int srv_no, FILE * mak_h)
639 char *obj = platform[2];
641 sprintf(p, "%s%d", serverName, srv_no);
642 fprintf(mak_h, "%s", platform[1]);
643 if (threadModel == PTHREADS) {
644 fprintf(mak_h, "CFLAGS = -KPIC -g -mt -I$(DESTDIR)include\n" "%s",
648 fprintf(mak_h, "CFLAGS = -g -I$(DESTDIR)include\n" "%s", platform[7]
652 "\n\ntest: all\ntests: all\nall: %sClt %sSrv\n\n"
653 "%sClt: %s.cs.%s %s.xdr.%s %sClt.%s $(LIBS)\n", p, p, p, p, obj,
655 if (platform == nt_symbols) {
656 fprintf(mak_h, "\t$(EXECONLINK)\n\n");
659 "\t$(CC) $(CFLAGS) -o $@ %sClt.%s %s.cs.%s %s.xdr.%s "
660 "$(LIBS) $(XLIBS)\n\n", p, obj, p, obj, p, obj);
663 "%s.xdr.c: %s.xg\n\n" "%s.h %s.cs.c %s.ss.c: %s.xg\n"
664 "\t$(RXGEN) %s.xg\n" "\t%s %s.cs.c\n" "\t%s %s.ss.c\n\n", p, p, p,
665 p, p, p, p, platform[3], p, platform[3], p);
666 fprintf(mak_h, "%sSrv: %s.ss.%s %s.xdr.%s %sSrv.%s $(LIBS)\n", p, p, obj,
669 if (platform == nt_symbols) {
670 fprintf(mak_h, "\t$(EXECONLINK)\n\n");
673 "\t$(CC) $(CFLAGS) -o $@ %sSrv.o %s.ss.o %s.xdr.o "
674 "$(LIBS) $(XLIBS)\n\n", p, p, p);
677 if (platform == unix_symbols) {
679 "clean:\n" "\t/bin/rm -f %sClt %s.h %s.cs.c %s.ss.c core "
681 "\t%sClt.o %s.cs.o %s.ss.o %s.xdr.c %s.xdr.o\n", p, p, p, p,
682 p, p, p, p, p, p, p);
688 * WriteCltTrailer - finish writing client source
691 WriteCltTrailer(char *serverName, int first, int last, FILE * itl_h)
696 * Write out 1 function that calls all the manager functions
698 if (threadModel == PTHREADS) {
699 fprintf(itl_h, "\n\nvoid *threadFunc(void *arg) {\n");
701 fprintf(itl_h, "\n\nint threadFunc(int *arg) {\n");
705 "\tstruct rx_connection *conn;\n" "\tint error=0;\n\n"
706 "\tint i = (int) arg;\n\n");
709 "\tconn = rx_GetCachedConnection(serverAddr,serverPort,4,secClass,secIndex);\n");
711 fprintf(itl_h, "\twhile(i--) {\n");
715 for (i = first; i < last; i++) {
716 fprintf(itl_h, "\t\tC_%s%d(conn);\n", serverName, i);
717 fprintf(itl_h, "\t\tC_%s%d_s(conn);\n", serverName, i);
719 fprintf(itl_h, "\t}\n");
721 fprintf(itl_h, "\trx_ReleaseCachedConnection(conn);\n");
723 if (threadModel == PTHREADS) {
724 fprintf(itl_h, "\treturn (void *) 0;\n");
727 "\tLWP_CALL(LWP_SignalProcess,(&done));\n" "\treturn 0;\n");
730 fprintf(itl_h, "}\n");
733 "\n\nstatic void DoRun(struct cmd_syndesc *as, void *arock) {\n");
735 if (threadModel == PTHREADS) {
736 fprintf(itl_h, "\tpthread_t *tid;\n");
738 fprintf(itl_h, "\tPROCESS *tid;\n");
742 "\tint i,j;\n" "\tunsigned int numThreads=0,numIterations=0;\n"
743 "\tint errflg=0;\n" "\tstruct hostent *host=NULL;\n\n"
744 "\tnumThreads = atoi(as->parms[0].items->data);\n"
745 "\tnumIterations = atoi(as->parms[1].items->data);\n"
746 "\tsecType = atoi(as->parms[2].items->data);\n"
747 "\tencLevel = atoi(as->parms[3].items->data);\n"
748 "\tserverPort = htons(atoi(as->parms[4].items->data));\n"
749 "\tif ((host = hostutil_GetHostByName(as->parms[5].items->data))==0) {\n"
750 "\t\terrflg++;\n" "\t}\n" "\telse {\n"
751 "\t\tmemcpy((void *) &serverAddr, (const void *)host->h_addr, sizeof(serverAddr));\n"
752 "\t}\n" "\tif ((secType<1) || (secType>2)) errflg++;\n"
753 "\tif ((encLevel<0) || (encLevel>2)) errflg++;\n"
754 "\tif ((serverPort == 0) ||(numThreads == 0) ||(numIterations == 0)) errflg++;\n"
755 "\tif (errflg) {\n" "\t\tprintf(\"invalid argument\\n\");\n"
756 "\t\texit(1);\n" "\t}\n\n" "\tif(rx_Init(htons(0)) < 0) {\n"
757 "\t\texit(1);\n" "\t}\n\n" "\tswitch(secType) {\n" "\t\tcase 1:\n"
758 "\t\t\tsecIndex = 0;\n"
759 "\t\t\tsecClass = rxnull_NewClientSecurityObject();\n"
760 "\t\t\tbreak;\n" "\t\tcase 2:\n"
761 "\t\t\tif (GetTicket (&kvno, &Ksession, &ticketLen, ticket) == 0) {\n"
762 "\t\t\t\tsecIndex = 2;\n"
763 "\t\t\t\tsecClass = rxkad_NewClientSecurityObject(encLevel,\n"
764 "\t\t\t\t&Ksession, kvno, ticketLen, ticket);\n" "\t\t\t}\n"
765 "\t\t\tbreak;\n" "\t\tdefault:\n" "\t\t\tbreak;\n" "\t}\n"
766 "\tassert(secClass);\n\n");
767 if (threadModel == PTHREADS) {
769 "#if defined sun\n" "\tthr_setconcurrency(numThreads);\n"
770 "#endif\n" "\ttid = (pthread_t *) "
771 "malloc(numThreads*(sizeof(pthread_t)));\n");
774 "\ttid = (PROCESS *) malloc(numThreads*(sizeof(PROCESS *)));\n");
777 fprintf(itl_h, "\tassert(tid);\n" "\tfor(j=0;j<numThreads;j++) {\n");
778 if (threadModel == PTHREADS) {
780 "\t\ti = pthread_create(&tid[j], (const pthread_attr_t *) 0,\n"
781 "\t\tthreadFunc, (void *) numIterations);\n"
782 "\t\tassert(i==0);\n");
785 "\t\tLWP_CALL(LWP_CreateProcess,(threadFunc, 10*4096, LWP_NORMAL_PRIORITY, numIterations, \"foo\", &tid[j]));\n");
788 fprintf(itl_h, "\t}\n" "\tfor(j=0;j<numThreads;j++) {\n");
789 if (threadModel == PTHREADS) {
791 "\t\ti = pthread_join(tid[j], (void **) 0);\n"
792 "\t\tassert(i==0);\n");
794 fprintf(itl_h, "\t\tLWP_CALL(LWP_WaitProcess,(&done));\n");
796 fprintf(itl_h, "\t}\n" "\trx_Finalize();\n" "\tfree(tid);\n" "}\n");
799 * Write command syntax function
803 "static void SetupRunCmd(void) {\n" "\tstruct cmd_syndesc *ts;\n"
804 "\tts = cmd_CreateSyntax(NULL,DoRun, NULL, \"run the test client program\");\n"
805 "\tcmd_AddParm(ts, \"-threadCount\", CMD_SINGLE, CMD_REQUIRED, \"number of threads to spawn\");\n"
806 "\tcmd_AddParm(ts, \"-iterationCount\", CMD_SINGLE, CMD_REQUIRED, \"number of iterations to make over entire interface for each thread\");\n"
807 "\tcmd_AddParm(ts, \"-secType\", CMD_SINGLE, CMD_REQUIRED, \"security level to use (1 -> unauthenticated, 2 -> authenticated)\");\n"
808 "\tcmd_AddParm(ts, \"-encLevel\", CMD_SINGLE, CMD_REQUIRED, \"encryption level to use, (0-> rxkad_clear, 1 -> rxkad_auth, 2 -> rxkad_crypt)\");\n"
809 "\tcmd_AddParm(ts, \"-serverPort\", CMD_SINGLE, CMD_REQUIRED, \"port that server is using\");\n"
810 "\tcmd_AddParm(ts, \"-serverHost\", CMD_SINGLE, CMD_REQUIRED, \"host where server is running\");\n"
818 "int main (int argc, char *argv[]) {\n" "\tint code;\n\n"
819 "\tinitialize_CMD_error_table();\n" "\tSetupRunCmd();\n"
820 "\tcode = cmd_Dispatch(argc, argv);\n\n" "\treturn(code);\n"
826 * Create macros useful for checking input/output parameters
830 WriteTestMacros(FILE * f)
833 "\n#define CHECKchar(x,y,z) if ((x)!=(y)) { printf(\"%%s: Got '%%c',"
834 "expected '%%c'\\n\", z, (char)x, (char)(y)); fflush(stdout); "
835 "errFlag = 1; } " "\n#define CHECKshort(x,y,z) if ((x)!=(y)) "
836 "{ printf(\"%%s: Got 0x%%04x, "
837 "expected 0x%%04x\\n\", z, x, y); fflush(stdout); "
838 "errFlag = 1; } " "\n#define CHECKint32(x,y,z) if ((x)!=(y)) "
839 "{ printf(\"%%s: Got 0x%%08x, "
840 "expected 0x%%08x\\n\", z, x, y); fflush(stdout); "
842 "\n#define CHECKfloat(x,y,z) if (((x)/(y)<.999999) "
843 "|| ((x)/(y)>1.000001)) "
844 "{ printf(\"%%s: Got %%2.8e, expected %%2.8e\\n\", z, x, y); "
845 "fflush(stdout); " "errFlag = 1; } "
846 "\n#define CHECKdouble(x,y,z) if (((x)/(y)<.999999999999999) || "
847 "((x)/(y)>1.000000000000001)) { printf(\"%%s: Got %%2.16e, "
848 "expected %%2.16e\\n\", z, x, y); fflush(stdout); errFlag = 1; }"
849 "\n#define CHECKvarString(x,y,z) if (strcmp((x),(y))) { printf(\"%%s: "
850 "Got \\\"%%s\\\", expected \\\"%%s\\\"\\n\", z, x, y); fflush(stdout); "
851 "errFlag = 1; } \n");
855 * WriteCltHeader - write the begining of the client code.
858 WriteCltHeader(char *serverName, int srv_no, FILE * itl_h)
860 fprintf(itl_h, "#include <stdio.h>\n");
861 if (threadModel == PTHREADS) {
862 fprintf(itl_h, "#include <pthread.h>\n");
865 "%s" "#include <assert.h>\n" "#include <rx/rx.h>\n"
866 "#include <rx/rx_null.h>\n" "#include <rx/rxkad.h>\n"
867 "#include <afs/cmd.h>\n" "#include \"%s%d.h\"\n", platform[4],
869 if (threadModel == LWPS) {
871 "\n\n#define LWP_CALL(fnName, params) \\\n" "{ \\\n"
872 "\tint rc; \\\n" "\trc = fnName params; \\\n"
873 "\tif (rc != LWP_SUCCESS) { \\\n"
874 "\t\tprintf(\"call to %%s failed with %%d\\n\", # fnName, rc); \\\n"
875 "\t\texit(1); \\\n" "\t} \\\n" "};\n\n" "char done;\n\n");
879 "struct ktc_encryptionKey serviceKey =\n"
880 "\t{0x45, 0xe3, 0x3d, 0x16, 0x29, 0x64, 0x8a, 0x8f};\n"
881 "long serviceKeyVersion = 7;\n"
882 "\nextern struct hostent *hostutil_GetHostByName();\n\n"
883 "static long GetTicket (long *versionP,\n"
884 "\tstruct ktc_encryptionKey *session,\n"
885 "\tint * ticketLenP, char *ticket)\n" "{\n" "\tlong code;\n"
886 "\tdes_init_random_number_generator (&serviceKey);\n"
887 "\tcode = des_random_key (session);\n"
888 "\tif (code) return code;\n" "\t*ticketLenP = 0;\n"
889 "\tcode = tkt_MakeTicket(ticket, ticketLenP, &serviceKey,\n"
890 "\t\t\"tclnt\", \"\", \"\",\n" "\t\t0, 0xffffffff, session, 0,\n"
891 "\t\t\"tsrvr\", \"\");\n" "\tif (code) return code;\n"
892 "\t*versionP = serviceKeyVersion;\n" "\treturn 0;\n" "}\n\n"
893 "static int secType,encLevel,serverPort,serverAddr;\n"
894 "struct rx_securityClass *secClass;\n" "int secIndex;\n"
895 "long kvno;\n" "char ticket[MAXKTCTICKETLEN];\n"
896 "int ticketLen;\n" "struct ktc_encryptionKey Ksession;\n\n");
897 WriteTestMacros(itl_h);
902 * WriteCltInit -- write the initialization for each param
905 WriteCltInit(arg_tuple * arg, FILE * itl_h, int i, int structFlag)
908 char *s = (structFlag) ? "s." : "";
910 if ((!strncmp(arg->direction, "IN", 2) || structFlag)) {
911 if (!strncmp(arg->type, "varString", 9)) {
912 fprintf(itl_h, "\tstrcpy(%sa%d, %s);\n", s, i, arg->inValue[0]);
913 } else if (!strncmp(arg->type, "ar_", 3)) {
916 "\t%sa%d.drpc_out_%s_t_len = FIX_ARRAY_SIZE;\n", s, i,
919 "\t%sa%d.drpc_out_%s_t_val = "
920 "(%s *) malloc(FIX_ARRAY_SIZE * sizeof(%s));\n", s, i,
921 arg->type, (arg->type + 3), (arg->type + 3));
923 for (j = 0; j < IDL_FIX_ARRAY_SIZE; j++) {
925 fprintf(itl_h, "\t%sa%d[%d] = %s;\n", s, i, j,
928 fprintf(itl_h, "\t%sa%d.drpc_out_%s_t_val[%d] = %s;\n", s,
929 i, arg->type, j, arg->inValue[j]);
933 fprintf(itl_h, "\t%sa%d = %s;\n", s, i, arg->inValue[0]);
939 * WriteCltCall -- write each parameter for a call
942 WriteCltCall(arg_tuple * arg, FILE * itl_h, int i)
945 if (!strncmp(arg->type, "varString", 9)) {
946 if ((!strncmp(arg->direction, "OUT", 3))
947 || (!strncmp(arg->direction, "INOUT", 5))) {
948 fprintf(itl_h, "&a%d_p", i);
950 fprintf(itl_h, "a%d_p", i);
953 if ((!strncmp(arg->direction, "OUT", 3))
954 || (!strncmp(arg->direction, "INOUT", 5))
955 || (!strncmp(arg->type, "ar_", 3))) {
956 fprintf(itl_h, "&a%d", i);
958 fprintf(itl_h, "a%d", i);
964 * WriteCltDecl -- write the declaration for a parameter
967 WriteCltDecl(arg_tuple * arg, FILE * itl_h, int i)
970 if (!strncmp(arg->type, "ar_", 3)) {
971 if (!strncmp(arg->direction, "OUT", 3)) {
972 fprintf(itl_h, "\tdrpc_out_%s_t a%d = {0,0};\n", arg->type, i);
974 fprintf(itl_h, "\tdrpc_out_%s_t a%d;\n", arg->type, i);
976 } else if (!strncmp(arg->type, "varString", 9)) {
977 fprintf(itl_h, "\tchar a%d[STR_MAX];\n", i);
978 fprintf(itl_h, "\tchar *a%d_p = a%d;\n", i, i);
980 fprintf(itl_h, "\t%s a%d;\n", arg->type, i);
986 * WriteClt -- write the rpcs in the client
989 WriteClt(rpcArgs * argsP, char *serverName, int sign_no, FILE * itl_h)
991 char *name, *name2, *typ;
994 name = GetName(serverName, sign_no);
995 name2 = GetDescription(argsP);
997 fprintf(itl_h, "\n/* %s */\n\n", name2);
999 fprintf(itl_h, "\nvoid C_%s(struct rx_connection *conn) {\n", name);
1001 /* declare each arg */
1002 for (i = 0; i < argsP->argCount; i++) {
1003 WriteCltDecl(&argsP->argDescr[i], itl_h, i);
1005 fprintf(itl_h, "\tint error;\n\tint errFlag;\n\n");
1007 /* initialize IN/INOUT args */
1008 for (i = 0; i < argsP->argCount; i++) {
1009 WriteCltInit(&argsP->argDescr[i], itl_h, i, FALSE);
1012 /* call the server */
1013 fprintf(itl_h, "\terror = A%s(conn, ", name);
1016 for (i = 0; i < argsP->argCount; i++) {
1017 WriteCltCall(&argsP->argDescr[i], itl_h, i);
1018 fprintf(itl_h, ((i < (argsP->argCount - 1))) ? "," : ");\n");
1022 "\tif (error != 0) {\n"
1023 "\t\tprintf(\"C_%s failed %%d\\n\", error);\n"
1024 "\t\tfflush(stdout);\n" "\t\treturn;\n" "\t}\n", name);
1027 * check the in and inout parameters
1029 for (i = 0; i < argsP->argCount; i++) {
1031 if ((!strcmp(argsP->argDescr[i].direction, "OUT"))
1032 || (!strcmp(argsP->argDescr[i].direction, "INOUT"))) {
1034 typ = argsP->argDescr[i].type;
1036 if (!strncmp(typ, "ar_", 3)) {
1037 for (j = 0; j < IDL_FIX_ARRAY_SIZE; j++)
1039 "\n\tCHECK%s(a%d.drpc_out_%s_t_val[%d], %s, \"C_%s_s\");",
1040 (typ + 3), i, typ, j,
1041 argsP->argDescr[i].outValue[j], name);
1042 } else if (strstr(typ, "String")) {
1043 fprintf(itl_h, "\n\tCHECK%s((char *)a%d, %s, \"C_%s_s\");",
1044 typ, i, argsP->argDescr[i].outValue[0], name);
1045 } else if (!strcmp(typ, "afs_int32")) {
1046 fprintf(itl_h, "\n\tCHECK%s(a%d, %sL, \"C_%s_s\");", typ, i,
1047 argsP->argDescr[i].outValue[0], name);
1049 fprintf(itl_h, "\n\tCHECK%s(a%d, %s, \"C_%s_s\");", typ, i,
1050 argsP->argDescr[i].outValue[0], name);
1056 * free up memory for dynamic input args
1058 for (i = 0; i < argsP->argCount; i++) {
1059 if (!strncmp(argsP->argDescr[i].type, "ar_", 3)) {
1060 typ = argsP->argDescr[i].type;
1062 "\n\tif (a%d.drpc_out_%s_t_val) "
1063 "free(a%d.drpc_out_%s_t_val);", i, typ, i, typ);
1068 fprintf(itl_h, "\n}\n");
1071 * Call the structure oriented rpc interface
1074 fprintf(itl_h, "\nvoid C_%s_s(struct rx_connection *conn) {\n", name);
1075 fprintf(itl_h, "\tstruct %s_t s;\n", name);
1076 fprintf(itl_h, "\tint error;\n\tint errFlag;\n\n");
1078 /* initialize IN/INOUT args */
1079 for (i = 0; i < argsP->argCount; i++) {
1080 WriteCltInit(&argsP->argDescr[i], itl_h, i, TRUE);
1083 /* call the server */
1084 fprintf(itl_h, "\terror = A%s_s(conn, &s);\n", name);
1087 "\tif (error != 0) {\n"
1088 "\t\tprintf(\"C_%s_s failed %%d\\n\", error);\n"
1089 "\t\tfflush(stdout);\n" "\t\treturn;\n" "\t}\n", name);
1092 * check the in and inout parameters
1094 for (i = 0; i < argsP->argCount; i++) {
1096 if ((!strcmp(argsP->argDescr[i].direction, "OUT"))
1097 || (!strcmp(argsP->argDescr[i].direction, "INOUT"))) {
1099 typ = argsP->argDescr[i].type;
1101 if (!strncmp(typ, "ar_", 3)) {
1102 for (j = 0; j < IDL_FIX_ARRAY_SIZE; j++)
1103 fprintf(itl_h, "\n\tCHECK%s(s.a%d[%d], %s, \"C_%s_s\");",
1104 (typ + 3), i, j, argsP->argDescr[i].outValue[j],
1106 } else if (strstr(typ, "String")) {
1107 fprintf(itl_h, "\n\tCHECK%s((char *)s.a%d, %s, \"C_%s_s\");",
1108 typ, i, argsP->argDescr[i].outValue[0], name);
1109 } else if (!strcmp(typ, "afs_int32")) {
1110 fprintf(itl_h, "\n\tCHECK%s(s.a%d, %sL, \"C_%s_s\");", typ, i,
1111 argsP->argDescr[i].outValue[0], name);
1113 fprintf(itl_h, "\n\tCHECK%s(s.a%d, %s, \"C_%s_s\");", typ, i,
1114 argsP->argDescr[i].outValue[0], name);
1120 fprintf(itl_h, "\n}\n");
1127 * WriteXGHeader -- fill in Header info in the xg file
1130 WriteXGHeader(char *serverName, FILE * xg_h, int srv_no)
1133 /* create the interface header */
1136 "\n/* Do not edit this file -- it was created by a generator */\n"
1137 "\npackage A\n\n" "const STR_MAX = %d; \n"
1138 "const FIX_ARRAY_SIZE = %d; \n" "typedef char drpc_char_t; \n"
1139 "typedef short drpc_short_t; \n" "typedef long drpc_int32_t; \n"
1140 "typedef string drpc_varString_t<STR_MAX>; \n"
1141 "typedef drpc_char_t drpc_ar_char_t[FIX_ARRAY_SIZE]; \n"
1142 "typedef drpc_char_t drpc_out_ar_char_t<FIX_ARRAY_SIZE>; \n"
1143 "typedef drpc_short_t drpc_ar_short_t[FIX_ARRAY_SIZE]; \n"
1144 "typedef drpc_short_t drpc_out_ar_short_t<FIX_ARRAY_SIZE>; \n"
1145 "typedef drpc_int32_t drpc_ar_int32_t[FIX_ARRAY_SIZE]; \n"
1146 "typedef drpc_int32_t drpc_out_ar_int32_t<FIX_ARRAY_SIZE>; \n",
1147 IDL_STR_MAX, IDL_FIX_ARRAY_SIZE);
1151 * WriteServHeader -- fill in the Header info in the server file
1154 WriteServHeader(FILE * srv_h, char *serverName, int srv_no)
1158 name = GetName(serverName, srv_no);
1161 "\n/* Do not edit this file -- it's been created by a generator */\n\n"
1162 "%s\n" "#include <stdio.h>\n" "#include <string.h>\n"
1163 "#include <stdlib.h>\n" "#include <rx/rx.h>\n"
1164 "#include <rx/rx_null.h>\n" "#include <rx/rxkad.h>\n"
1165 "#include <afs/cmd.h>\n" "#include \"%s.h\"\n\n"
1166 "struct ktc_encryptionKey serviceKey =\n"
1167 "\t{0x45, 0xe3, 0x3d, 0x16, 0x29, 0x64, 0x8a, 0x8f};\n"
1168 "long serviceKeyVersion = 7;\n\n"
1169 "extern int AExecuteRequest();\n" "extern char *optarg;\n"
1170 "extern int optind, opterr, optopt;\n\n"
1171 "#define VERIFY(x,y) if (!(x)) { printf y ; exit(1); }\n"
1172 "#define CHECK(x) ASSERT(x)\n", platform[4], name);
1174 WriteTestMacros(srv_h);
1179 * WriteServTrailer -- finish up the server file
1182 WriteServTrailer(FILE * srv_h)
1186 "\nstatic long GetKey (char *rock, long kvno, struct ktc_encryptionKey *key) {\n"
1187 "\tmemcpy ((void *) key, (void *) &serviceKey, sizeof(*key));\n"
1188 "\treturn 0;\n" "}\n\n"
1189 "static void DoRun(struct cmd_syndesc *as, void *arock) {\n"
1190 "\tstruct rx_service *serv;\n"
1191 "\tstruct rx_securityClass *sc[3];\n\n"
1192 "\tint port=0, errflg=0;\n" "\tint lowThreads=4, highThreads=8;\n"
1193 "\tlowThreads = atoi(as->parms[0].items->data);\n"
1194 "\thighThreads = atoi(as->parms[1].items->data);\n"
1195 "\tport = atoi(as->parms[2].items->data);\n"
1196 "\tif (port == 0) errflg++;\n" "\tif (errflg) {\n"
1197 "\t\tprintf(\"invalid argument\\n\");\n" "\t\texit(1);\n" "\t}\n"
1198 "\trx_Init(htons(port));\n"
1199 "\tsc[0] = rxnull_NewServerSecurityObject();\n" "\tsc[1] = 0;\n"
1200 "\tsc[2] = rxkad_NewServerSecurityObject (rxkad_clear, 0, GetKey, 0);\n"
1201 "\tif (serv = rx_NewService(0,4,\"foo\",sc,3,AExecuteRequest)) {\n"
1202 "\t\trx_SetMinProcs(serv,lowThreads);\n"
1203 "\t\trx_SetMaxProcs(serv,highThreads);\n"
1204 "\t\trx_StartServer(1);\n" "\t}\n" "\texit(0);\n" "}\n\n"
1205 "static void SetupRunCmd(void) {\n" "\tstruct cmd_syndesc *ts;\n"
1206 "\tts = cmd_CreateSyntax(NULL,DoRun, NULL, \"run the test server program\");\n"
1207 "\tcmd_AddParm(ts, \"-lowThreadCount\", CMD_SINGLE, CMD_REQUIRED, \"minimum number of threads to spawn\");\n"
1208 "\tcmd_AddParm(ts, \"-highThreadCount\", CMD_SINGLE, CMD_REQUIRED, \"maximum number of threads to spawn\");\n"
1209 "\tcmd_AddParm(ts, \"-serverPort\", CMD_SINGLE, CMD_REQUIRED, \"port that server is using\");\n"
1210 "}\n" "int main(int argc, char **argv) {\n" "\tint code;\n"
1211 "\tinitialize_CMD_error_table();\n" "\tSetupRunCmd();\n"
1212 "\tcode = cmd_Dispatch(argc, argv);\n" "\treturn(code);\n" "}\n");
1216 * ProcessCmdLine -- processes the command line args
1219 ProcessCmdLine(int argc, char **argv, char **serverName, char **ipFileName,
1226 /* command line processing */
1227 while (--argc > 0) {
1228 if ((*++argv)[0] == '-') {
1229 switch ((*argv)[1]) {
1232 case 'F': /* input table file */
1233 *ipFileName = *++argv;
1236 case 'h': /* display help */
1242 case 'L': /* use LWP threads */
1246 case 'S': /* serverName */
1247 *serverName = *++argv;
1248 /* need 8 char file name, and so truncate the server name */
1249 if ((int)strlen(*serverName) > MAX_SERV_NAME)
1250 *(*serverName + MAX_SERV_NAME) = '\0';
1255 *outputDir = *++argv;
1260 if (strcmp(*++argv, "NT"))
1261 platform = unix_symbols;
1275 FATAL("Please set server name using -s switch\n");
1280 main(int argc, char **argv)
1282 FILE *table_h, *srv_h, *xg_h, *clt_h, *mak_h;
1285 char *name, *ifName;
1286 char *serverName = NULL;
1287 char *ipFileName = NULL;
1288 char *outputDir = NULL;
1289 int sign_no = 0, start_no, srv_no;
1291 ProcessCmdLine(argc, argv, &serverName, &ipFileName, &outputDir);
1293 /* open input file */
1294 table_h = fopen(ipFileName, "r");
1295 MEM_CHK(table_h, "main: Unable to open input file\n");
1301 * open the first set of output files
1304 name = GetName(serverName, srv_no);
1306 srv_h = OpenOutFile(outputDir, name, "Srv.c");
1307 xg_h = OpenOutFile(outputDir, name, ".xg");
1308 clt_h = OpenOutFile(outputDir, name, "Clt.c");
1309 mak_h = OpenOutFile(outputDir, name, ".mak");
1311 WriteXGHeader(serverName, xg_h, srv_no);
1312 WriteServHeader(srv_h, serverName, srv_no);
1313 WriteCltHeader(serverName, srv_no, clt_h);
1314 WriteMake(serverName, srv_no, mak_h);
1318 /* read the table */
1319 while (fscanf(table_h, "%d", &(args.argCount)) != EOF) {
1321 /* increment signature number 8.3 format-- only 10^7 dif sign */
1323 if (sign_no > 1.0e+7)
1324 FATAL("Max no: of signatures overflow\n");
1326 /* allocate for the arg struct */
1328 (arg_tuple *) calloc(args.argCount, sizeof(arg_tuple));
1329 MEM_CHK(args.argDescr, "main: Out of memory -- args.argDescr\n");
1331 /* pick out the dirs and the types */
1332 for (i = 0; i < args.argCount; i++) {
1334 (table_h, " ( %s %s )", args.argDescr[i].direction,
1335 args.argDescr[i].type)) {
1336 FATAL("main: Incorrect input file format\n");
1341 * switch files when we hit TESTS_PER_FILE
1343 if (sign_no - start_no >= TESTS_PER_FILE) {
1345 * Finish up the current files
1347 WriteServTrailer(srv_h);
1348 WriteCltTrailer(serverName, start_no, sign_no, clt_h);
1355 * Open the next set of output files
1360 name = GetName(serverName, srv_no);
1362 srv_h = OpenOutFile(outputDir, name, "Srv.c");
1363 xg_h = OpenOutFile(outputDir, name, ".xg");
1364 clt_h = OpenOutFile(outputDir, name, "Clt.c");
1365 mak_h = OpenOutFile(outputDir, name, ".mak");
1366 WriteXGHeader(serverName, xg_h, srv_no);
1367 WriteServHeader(srv_h, serverName, srv_no);
1368 WriteCltHeader(serverName, srv_no, clt_h);
1369 WriteMake(serverName, srv_no, mak_h);
1375 /* initialize parameter values */
1376 for (i = 0; i < args.argCount; i++) {
1377 for (j = 0; j < IDL_FIX_ARRAY_SIZE; j++) {
1378 args.argDescr[i].inValue[j] = NULL;
1379 args.argDescr[i].inValue2[j] = NULL;
1380 args.argDescr[i].outValue[j] = NULL;
1381 args.argDescr[i].outValue2[j] = NULL;
1384 GenParamValues(&args);
1386 /* write rpc desc into body of the interface */
1387 WriteXG(&args, xg_h, serverName, sign_no);
1389 /* write the rpc into the manager file */
1390 WriteServC(&args, srv_h, serverName, sign_no);
1392 /* write out ITL test */
1393 WriteClt(&args, serverName, sign_no, clt_h);
1395 /* free saved values */
1396 for (i = 0; i < args.argCount; i++) {
1397 for (j = 0; j < IDL_FIX_ARRAY_SIZE; j++) {
1398 if (args.argDescr[i].inValue[j])
1399 free(args.argDescr[i].inValue[j]);
1400 if (args.argDescr[i].inValue2[j])
1401 free(args.argDescr[i].inValue2[j]);
1402 if (args.argDescr[i].outValue[j])
1403 free(args.argDescr[i].outValue[j]);
1404 if (args.argDescr[i].outValue2[j])
1405 free(args.argDescr[i].outValue2[j]);
1408 free(args.argDescr);
1411 WriteServTrailer(srv_h);
1412 WriteCltTrailer(serverName, start_no, (sign_no + 1), clt_h);
1422 * create 1 makefile that drives all the rest
1425 mak_h = OpenOutFile(outputDir, "Makefile", "");
1426 fprintf(mak_h, "\ntest:all\ntests:all\nall:\n");
1427 fprintf(mak_h, "%s", platform[8]);
1428 for (i = 1; i <= srv_no; i++)
1429 fprintf(mak_h, "\t%s %s%d.mak %s\n", platform[0], serverName, i,
1431 fprintf(mak_h, "\nclean:\n");
1432 for (i = 1; i <= srv_no; i++)
1433 fprintf(mak_h, "\t%s %s%d.mak clean\n", platform[0], serverName, i);