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>
62 #include "generator.h"
64 static char *unix_symbols
[] = {
66 "include ../../../config/Makefile.$(SYS_NAME)\n",
69 "#include <netdb.h>\n",
73 "LIBS = $(DESTDIR)lib/libafsrpc.so \\\n"
74 "\t$(DESTDIR)lib/afs/libcmd.a \\\n"
75 "\t$(DESTDIR)lib/afs/libafs_com_err.a \\\n"
76 "\t$(DESTDIR)lib/afs/util.a \n",
79 "LIBS = $(DESTDIR)lib/librxkad.a \\\n" "\t$(DESTDIR)lib/libdes.a \\\n"
80 "\t$(DESTDIR)lib/librx.a \\\n" "\t$(DESTDIR)lib/liblwp.a \\\n"
81 "\t$(DESTDIR)lib/afs/libcmd.a \\\n"
82 "\t$(DESTDIR)lib/afs/libafs_com_err.a \\\n"
83 "\t$(DESTDIR)lib/afs/util.a \\\n" "\t/usr/ucblib/libucb.a \n",
86 "\t@if [ ! -r DEST ] ; \\\n" "\tthen \\\n"
87 "\t\techo \"Must create DEST link by hand before building tests\"; \\\n"
88 "\t\texit 1; \\\n" "\tfi\n"
91 static char *nt_symbols
[] = {
93 "!INCLUDE ../../../config/NTMakefile.$(SYS_NAME)\n",
96 "#include <windows.h>\n",
100 "LIBS = $(DESTDIR)/lib/afsrpc.lib \\\n"
101 "\t$(DESTDIR)/lib/afs/afscmd.lib \\\n"
102 "\t$(DESTDIR)/lib/afs/afsafs_com_err.lib \\\n"
103 "\t$(DESTDIR)/lib/afs/afsutil.lib \\\n"
104 "\t$(DESTDIR)/lib/pthread.lib \\\n" "\t$(DESTDIR)/lib/afsreg.lib \\\n"
108 "LIBS = $(DESTDIR)/lib/afsrxkad.lib \\\n"
109 "\t$(DESTDIR)/lib/afsdes.lib \\\n" "\t$(DESTDIR)/lib/afsrx.lib \\\n"
110 "\t$(DESTDIR)/lib/afshcrypto.lib \\\n"
111 "\t$(DESTDIR)/lib/afslwp.lib \\\n"
112 "\t$(DESTDIR)/lib/afs/afscmd.lib \\\n"
113 "\t$(DESTDIR)/lib/afs/afsafs_com_err.lib \\\n"
114 "\t$(DESTDIR)/lib/afs/afsutil.lib \\\n"
115 "\t$(DESTDIR)/lib/afsreg.lib \n",
118 "!\tIF (!EXIST(DEST))\n"
119 "!\t\tERROR Must create DEST link by hand before building tests\n"
123 static char **platform
= nt_symbols
;
126 #define strdup(x) _strdup(x)
130 * 31 bit random number generator, we don't really care how random
131 * these numbers are, it is more important that identical rx files
132 * are generated no matter what platform the generator runs on
134 static unsigned long randVal
= 0x330E16;
141 static threadModel_t threadModel
= PTHREADS
;
146 randVal
= ((randVal
* 0xEECE66D) + 0xB) & 0xFFFFFFFF;
147 return ((double)(randVal
) / 4294967296.0);
151 * GetDescription writes a one line comment describing the parameters
152 * used in an rpc in the client program
155 GetDescription(rpcArgs
* argsP
)
160 bufP2
= calloc((MAX_TYP_STR
+ MAX_DIR_STR
+ ATTRIB_LEN
* ATTRIB_NO
)
161 * argsP
->argCount
+ 3, sizeof(char));
162 MEM_CHK(bufP2
, "GetDescription: out of mem bufP2\n");
164 for (i
= 0; i
< argsP
->argCount
; i
++) {
165 strcat(bufP2
, argsP
->argDescr
[i
].direction
);
166 strcat(bufP2
, argsP
->argDescr
[i
].type
);
172 * GetName -- get the name of the current server/instance
175 GetName(char *serverName
, int sign_no
)
177 /* itl file name 8.3 format */
180 bufP
= malloc(32 * sizeof(char));
181 MEM_CHK(bufP
, "GetName: bufP out of mem\n");
183 sprintf(bufP
, "%s%d", serverName
, sign_no
);
188 * OpenOutFile -- open a file in the output directory
191 OpenOutFile(char *outDir
, char *fileName
, char *tailStr
)
198 (char *)malloc(sizeof(char) *
199 (strlen(fileName
) + strlen(tailStr
) +
200 strlen(outDir
) + 2));
201 MEM_CHK(bufP
, "OpenOutFile : Out of mem -- bufP\n");
202 sprintf(bufP
, "%s/%s%s", outDir
, fileName
, tailStr
);
205 (char *)malloc(sizeof(char) *
206 (strlen(fileName
) + strlen(tailStr
) + 1));
207 MEM_CHK(bufP
, "OpenOutFile : Out of mem -- bufP\n");
208 sprintf(bufP
, "%s%s", fileName
, tailStr
);
210 fP
= fopen(bufP
, "w");
211 MEM_CHK(fP
, "main: Unable to open output file\n");
217 * WriteXGDecl -- write the declaration for a parameter
220 WriteXGDecl(arg_tuple
* arg
, FILE * xg_h
, int i
, int structFlag
, int lastFlag
)
223 if (!strcmp(arg
->type
, "varString")) {
224 fprintf(xg_h
, "\tchar a%d[STR_MAX];\n", i
);
226 fprintf(xg_h
, "\tdrpc_%s_t a%d;\n", arg
->type
, i
);
229 if (!strncmp(arg
->type
, "ar_", 2)) {
230 fprintf(xg_h
, "\t%s drpc_out_%s_t *a%d", arg
->direction
,
232 } else if (!strcmp(arg
->type
, "varString")) {
233 fprintf(xg_h
, "\t%s string a%d<STR_MAX>", arg
->direction
, i
);
234 } else if (!strcmp(arg
->direction
, "IN")) {
235 fprintf(xg_h
, "\t%s drpc_%s_t a%d", arg
->direction
, arg
->type
, i
);
237 fprintf(xg_h
, "\t%s drpc_%s_t *a%d", arg
->direction
, arg
->type
,
249 * WriteXG -- write the body of the xg interface
252 WriteXG(rpcArgs
* argsP
, FILE * xg_h
, char *serverName
, int sign_no
)
255 char *name
= GetName(serverName
, sign_no
);
258 * CASE 1: all arguments passed as parameters
261 fprintf(xg_h
, "\nproc %s(\n", name
);
263 /* declare each arg */
264 for (i
= 0; i
< argsP
->argCount
; i
++) {
265 WriteXGDecl(&argsP
->argDescr
[i
], xg_h
, i
, FALSE
,
266 (i
== argsP
->argCount
- 1));
269 /* Now pass the paramaters inside a structure */
270 fprintf(xg_h
, "\nstruct %s_t {\n", name
);
271 for (i
= 0; i
< argsP
->argCount
; i
++) {
272 WriteXGDecl(&argsP
->argDescr
[i
], xg_h
, i
, TRUE
,
273 (i
== argsP
->argCount
- 1));
275 fprintf(xg_h
, "} ;\n");
276 fprintf(xg_h
, "\nproc %s_s(\n", name
);
277 fprintf(xg_h
, "\tINOUT struct %s_t *s);\n", name
);
283 * GetRandStr -- get a random string
286 GetRandStr(int strLen
, char **ret
, int *rP
)
294 randI
= 'A' + ('Z' - 'A') * drand32();
295 sprintf(buf
, "%c", randI
);
304 * GetRandP -- sets a string to a random value of the data type
305 * inthe case of a char type, ret holds "%c" and ret2 holds '%c'
308 GetRandP(char *typ
, char **ret
, char **ret2
)
315 *ret
= calloc(MAX_RAND_LENGTH
+ 1, sizeof(char));
316 *ret2
= calloc(MAX_RAND_LENGTH
+ 1, sizeof(char));
318 if (strstr(typ
, "char")) {
319 GetRandStr(1, ret2
, &randI
);
321 strcpy(*ret2
, "'\\\\'");
322 else if (randI
== '\'')
323 strcpy(*ret2
, "'\\''");
325 sprintf(*ret
, "'%c'", randI
);
327 } else if (strstr(typ
, "short")) {
328 shI
= SHRT_MIN
+ (SHRT_MAX
- SHRT_MIN
) * drand32();
329 sprintf(*ret
, "%d", shI
);
331 } else if (strstr(typ
, "afs_int32")) {
332 randI
= INT_MIN
+ UINT_MAX
* drand32();
333 if (randI
< INT_MIN
|| randI
> INT_MAX
) {
334 fprintf(stderr
, "GetRandP: afs_int32 %d out of bounds\n", randI
);
337 sprintf(*ret
, "%d", randI
);
339 } else if (strstr(typ
, "float")) {
342 sprintf(*ret
, "%2.8e", f
);
345 } else if (strstr(typ
, "double")) {
347 sprintf(*ret
, "%2.16e", d1
);
350 } else if (strstr(typ
, "String")) {
351 strLen
= (MAX_RAND_LENGTH
- 2) * drand32();
352 GetRandStr(strLen
, ret
, &randI
);
359 * GenParamValues -- generate the parameter values for an rpc
362 GenParamValues(rpcArgs
* argsP
)
367 /* generate random values for each argument */
368 for (i
= 0; i
< argsP
->argCount
; i
++) {
370 argsP
->argDescr
[i
].vc_low
= 0;
371 argsP
->argDescr
[i
].vc_max
= IDL_FIX_ARRAY_SIZE
- 1;
372 argsP
->argDescr
[i
].vc_high
= IDL_FIX_ARRAY_SIZE
- 1;
373 argsP
->argDescr
[i
].ovc_low
= 0;
374 argsP
->argDescr
[i
].ovc_high
= IDL_FIX_ARRAY_SIZE
- 1;
376 if (!strncmp(argsP
->argDescr
[i
].type
, "ar_", 3)) {
377 typ
= argsP
->argDescr
[i
].type
+ 3;
378 for (j
= 0; j
< IDL_FIX_ARRAY_SIZE
; j
++) {
379 GetRandP(typ
, &argsP
->argDescr
[i
].inValue
[j
],
380 &argsP
->argDescr
[i
].inValue2
[j
]);
381 GetRandP(typ
, &argsP
->argDescr
[i
].outValue
[j
],
382 &argsP
->argDescr
[i
].outValue2
[j
]);
385 GetRandP(argsP
->argDescr
[i
].type
, &argsP
->argDescr
[i
].inValue
[0],
386 &argsP
->argDescr
[i
].inValue2
[0]);
387 GetRandP(argsP
->argDescr
[i
].type
, &argsP
->argDescr
[i
].outValue
[0],
388 &argsP
->argDescr
[i
].outValue2
[0]);
394 * WriteServC -- write the rpcs in the server file
397 WriteServC(rpcArgs
* argsP
, FILE * srv_h
, char *serverName
, int sign_no
)
402 name
= GetName(serverName
, sign_no
);
403 fprintf(srv_h
, "\nint A%s(struct rx_call *c,\n", name
);
405 /* declare each arg */
406 for (i
= 0; i
< argsP
->argCount
; i
++) {
408 if (!strcmp(argsP
->argDescr
[i
].type
, "varString")) {
409 if (!strcmp(argsP
->argDescr
[i
].direction
, "IN")) {
410 fprintf(srv_h
, "\tchar *a%d", i
);
412 fprintf(srv_h
, "\tchar **a%d", i
);
414 } else if (strncmp(argsP
->argDescr
[i
].type
, "ar_", 3)
415 && (!strcmp(argsP
->argDescr
[i
].direction
, "IN"))) {
416 fprintf(srv_h
, "\tdrpc_%s_t a%d", argsP
->argDescr
[i
].type
, i
);
418 if (!strncmp(argsP
->argDescr
[i
].type
, "ar_", 3)) {
419 fprintf(srv_h
, "\tdrpc_out_%s_t *a%d",
420 argsP
->argDescr
[i
].type
, i
);
422 fprintf(srv_h
, "\tdrpc_%s_t *a%d", argsP
->argDescr
[i
].type
,
426 if (i
< (argsP
->argCount
- 1)) {
427 fprintf(srv_h
, ",\n");
430 fputs(")\n{\n", srv_h
); /* balance the } */
431 fputs("\tint errFlag = 0;", srv_h
);
434 * check the in and inout parameters
436 for (i
= 0; i
< argsP
->argCount
; i
++) {
438 if (!strcmp(argsP
->argDescr
[i
].direction
, "IN")
439 || (!strcmp(argsP
->argDescr
[i
].direction
, "INOUT")
440 && !strcmp(argsP
->argDescr
[i
].type
, "varString"))) {
442 typ
= argsP
->argDescr
[i
].type
;
444 if (strstr(typ
, "String")) {
445 if (!strcmp(argsP
->argDescr
[i
].direction
, "INOUT")) {
446 fprintf(srv_h
, "\n\tCHECK%s((char *)*a%d, %s, \"%s\");",
447 typ
, i
, argsP
->argDescr
[i
].inValue
[0], name
);
449 fprintf(srv_h
, "\n\tCHECK%s((char *)a%d, %s, \"%s\");",
450 typ
, i
, argsP
->argDescr
[i
].inValue
[0], name
);
452 } else if (!strcmp(typ
, "afs_int32")) {
453 fprintf(srv_h
, "\n\tCHECK%s(a%d, %sL, \"%s\");", typ
, i
,
454 argsP
->argDescr
[i
].inValue
[0], name
);
456 if (!strncmp(typ
, "ar_", 3)) {
457 for (j
= 0; j
< IDL_FIX_ARRAY_SIZE
; j
++)
459 "\n\tCHECK%s(a%d->drpc_out_%s_t_val[%d], %s, \"%s\");",
460 (typ
+ 3), i
, typ
, j
,
461 argsP
->argDescr
[i
].inValue
[j
], name
);
463 fprintf(srv_h
, "\n\tCHECK%s(a%d, %s, \"%s\");", typ
, i
,
464 argsP
->argDescr
[i
].inValue
[0], name
);
467 } else if (!strcmp(argsP
->argDescr
[i
].direction
, "INOUT")) {
469 typ
= argsP
->argDescr
[i
].type
;
471 if (strstr(typ
, "String")) {
472 fprintf(srv_h
, "\n\tCHECK%s((char *)*a%d, %s, \"%s\");", typ
,
473 i
, argsP
->argDescr
[i
].inValue
[0], name
);
474 } else if (!strcmp(typ
, "afs_int32")) {
475 fprintf(srv_h
, "\n\tCHECK%s(*a%d, %sL, \"%s\");", typ
, i
,
476 argsP
->argDescr
[i
].inValue
[0], name
);
478 if (!strncmp(typ
, "ar_", 3)) {
479 for (j
= 0; j
< IDL_FIX_ARRAY_SIZE
; j
++)
481 "\n\tCHECK%s(a%d->drpc_out_%s_t_val[%d], %s, \"%s\");",
482 (typ
+ 3), i
, typ
, j
,
483 argsP
->argDescr
[i
].inValue
[j
], name
);
485 fprintf(srv_h
, "\n\tCHECK%s(*a%d, %s, \"%s\");", typ
, i
,
486 argsP
->argDescr
[i
].inValue
[0], name
);
493 * free up memory for dynamic input args
495 for (i
= 0; i
< argsP
->argCount
; i
++) {
496 if (!strncmp(argsP
->argDescr
[i
].type
, "ar_", 3)) {
497 typ
= argsP
->argDescr
[i
].type
;
498 if (!strcmp(argsP
->argDescr
[i
].direction
, "INOUT")) {
500 "\n\tif (a%d->drpc_out_%s_t_val) "
501 "free(a%d->drpc_out_%s_t_val);", i
, typ
, i
, typ
);
503 if (!strcmp(argsP
->argDescr
[i
].direction
, "INOUT")
504 || !strcmp(argsP
->argDescr
[i
].direction
, "OUT")) {
506 "\n\ta%d->drpc_out_%s_t_val = (%s *) "
507 "malloc(FIX_ARRAY_SIZE * sizeof(%s));", i
, typ
,
508 (typ
+ 3), (typ
+ 3));
509 fprintf(srv_h
, "\n\ta%d->drpc_out_%s_t_len = FIX_ARRAY_SIZE;",
516 * set the inout and out parameters
518 for (i
= 0; i
< argsP
->argCount
; i
++) {
520 if (!strcmp(argsP
->argDescr
[i
].direction
, "INOUT")
521 || !strcmp(argsP
->argDescr
[i
].direction
, "OUT")) {
523 typ
= argsP
->argDescr
[i
].type
;
525 if (!strncmp(typ
, "ar_", 3)) {
526 for (j
= 0; j
< IDL_FIX_ARRAY_SIZE
; j
++)
527 fprintf(srv_h
, "\n\ta%d->drpc_out_%s_t_val[%d] = %s;", i
,
528 typ
, j
, argsP
->argDescr
[i
].outValue
[j
]);
529 } else if (!strcmp(typ
, "afs_int32")) {
530 fprintf(srv_h
, "\n\t*a%d = %sL;", i
,
531 argsP
->argDescr
[i
].outValue
[0]);
532 } else if (!strcmp(typ
, "varString")) {
533 if (!strcmp(argsP
->argDescr
[i
].direction
, "OUT")) {
534 fprintf(srv_h
, "\n\t*a%d = malloc(STR_MAX);", i
);
536 fprintf(srv_h
, "\n\tstrcpy((char *)*a%d, %s);", i
,
537 argsP
->argDescr
[i
].outValue
[0]);
538 } else if (strstr(typ
, "String")) {
539 fprintf(srv_h
, "\n\t*a%d = (drpc_%s_t)rpc_ss_allocate(%d);",
540 i
, typ
, strlen(argsP
->argDescr
[i
].outValue
[0]) - 1);
541 fprintf(srv_h
, "\n\tstrcpy((char *)*a%d, %s);", i
,
542 argsP
->argDescr
[i
].outValue
[0]);
544 fprintf(srv_h
, "\n\t*a%d = %s;", i
,
545 argsP
->argDescr
[i
].outValue
[0]);
551 "\n\tif (errFlag) {" "\n\t\tprintf(\"%s: failed\\n\");"
552 "\n\t\tfflush(stdout);" "\n\t}" "\n\treturn errFlag;\n}\n", name
);
555 * second routine with arguments inside a structure
558 "\nint A%s_s(struct rx_call *c,\n\t%s_t *s)\n{"
559 "\n\tint errFlag = 0;", name
, name
);
562 * check the in and inout parameters
564 for (i
= 0; i
< argsP
->argCount
; i
++) {
566 if (!strcmp(argsP
->argDescr
[i
].direction
, "IN")
567 || (!strstr(argsP
->argDescr
[i
].type
, "String")
568 && !strcmp(argsP
->argDescr
[i
].direction
, "INOUT"))) {
570 typ
= argsP
->argDescr
[i
].type
;
572 if (!strncmp(typ
, "ar_", 3)) {
573 for (j
= 0; j
< IDL_FIX_ARRAY_SIZE
; j
++)
574 fprintf(srv_h
, "\n\tCHECK%s(s->a%d[%d], %s, \"%s_s\");",
575 (typ
+ 3), i
, j
, argsP
->argDescr
[i
].inValue
[j
],
577 } else if (strstr(typ
, "String")) {
578 fprintf(srv_h
, "\n\tCHECK%s((char *)s->a%d, %s, \"%s_s\");",
579 typ
, i
, argsP
->argDescr
[i
].inValue
[0], name
);
580 } else if (!strcmp(typ
, "afs_int32")) {
581 fprintf(srv_h
, "\n\tCHECK%s(s->a%d, %sL, \"%s_s\");", typ
, i
,
582 argsP
->argDescr
[i
].inValue
[0], name
);
584 fprintf(srv_h
, "\n\tCHECK%s(s->a%d, %s, \"%s_s\");", typ
, i
,
585 argsP
->argDescr
[i
].inValue
[0], name
);
591 * set the inout and out parameters
593 for (i
= 0; i
< argsP
->argCount
; i
++) {
595 if (!strcmp(argsP
->argDescr
[i
].direction
, "INOUT")
596 || !strcmp(argsP
->argDescr
[i
].direction
, "OUT")) {
598 typ
= argsP
->argDescr
[i
].type
;
600 if (!strncmp(typ
, "ar_", 3)) {
601 for (j
= 0; j
< IDL_FIX_ARRAY_SIZE
; j
++)
602 fprintf(srv_h
, "\n\ts->a%d[%d]= %s;", i
, j
,
603 argsP
->argDescr
[i
].outValue
[j
]);
604 } else if (!strcmp(typ
, "afs_int32")) {
605 fprintf(srv_h
, "\n\ts->a%d = %sL;", i
,
606 argsP
->argDescr
[i
].outValue
[0]);
607 } else if (!strcmp(typ
, "varString")) {
608 fprintf(srv_h
, "\n\tstrcpy((char *)s->a%d, %s);", i
,
609 argsP
->argDescr
[i
].outValue
[0]);
610 } else if (strstr(typ
, "String")) {
611 fprintf(srv_h
, "\n\ts->a%d = rpc_ss_allocate(%d);", i
,
612 strlen(argsP
->argDescr
[i
].outValue
[0]) - 1);
613 fprintf(srv_h
, "\n\tstrcpy((char *)s->a%d, %s);", i
,
614 argsP
->argDescr
[i
].outValue
[0]);
616 fprintf(srv_h
, "\n\ts->a%d = %s;", i
,
617 argsP
->argDescr
[i
].outValue
[0]);
623 "\n\tif (errFlag) {" "\n\t\tprintf(\"%s_s: failed\\n\");" "\n\t}"
624 "\n\tfflush(stdout);" "\n\treturn errFlag;\n}\n", name
);
631 * WriteMake - write the makefile for a particular client/server pair
634 WriteMake(char *serverName
, int srv_no
, FILE * mak_h
)
637 char *obj
= platform
[2];
639 sprintf(p
, "%s%d", serverName
, srv_no
);
640 fprintf(mak_h
, "%s", platform
[1]);
641 if (threadModel
== PTHREADS
) {
642 fprintf(mak_h
, "CFLAGS = -KPIC -g -mt -I$(DESTDIR)include\n" "%s",
646 fprintf(mak_h
, "CFLAGS = -g -I$(DESTDIR)include\n" "%s", platform
[7]
650 "\n\ntest: all\ntests: all\nall: %sClt %sSrv\n\n"
651 "%sClt: %s.cs.%s %s.xdr.%s %sClt.%s $(LIBS)\n", p
, p
, p
, p
, obj
,
653 if (platform
== nt_symbols
) {
654 fprintf(mak_h
, "\t$(EXECONLINK)\n\n");
657 "\t$(CC) $(CFLAGS) -o $@ %sClt.%s %s.cs.%s %s.xdr.%s "
658 "$(LIBS) $(XLIBS)\n\n", p
, obj
, p
, obj
, p
, obj
);
661 "%s.xdr.c: %s.xg\n\n" "%s.h %s.cs.c %s.ss.c: %s.xg\n"
662 "\t$(RXGEN) %s.xg\n" "\t%s %s.cs.c\n" "\t%s %s.ss.c\n\n", p
, p
, p
,
663 p
, p
, p
, p
, platform
[3], p
, platform
[3], p
);
664 fprintf(mak_h
, "%sSrv: %s.ss.%s %s.xdr.%s %sSrv.%s $(LIBS)\n", p
, p
, obj
,
667 if (platform
== nt_symbols
) {
668 fprintf(mak_h
, "\t$(EXECONLINK)\n\n");
671 "\t$(CC) $(CFLAGS) -o $@ %sSrv.o %s.ss.o %s.xdr.o "
672 "$(LIBS) $(XLIBS)\n\n", p
, p
, p
);
675 if (platform
== unix_symbols
) {
677 "clean:\n" "\t/bin/rm -f %sClt %s.h %s.cs.c %s.ss.c core "
679 "\t%sClt.o %s.cs.o %s.ss.o %s.xdr.c %s.xdr.o\n", p
, p
, p
, p
,
680 p
, p
, p
, p
, p
, p
, p
);
686 * WriteCltTrailer - finish writing client source
689 WriteCltTrailer(char *serverName
, int first
, int last
, FILE * itl_h
)
694 * Write out 1 function that calls all the manager functions
696 if (threadModel
== PTHREADS
) {
697 fprintf(itl_h
, "\n\nvoid *threadFunc(void *arg) {\n");
699 fprintf(itl_h
, "\n\nint threadFunc(int *arg) {\n");
703 "\tstruct rx_connection *conn;\n" "\tint error=0;\n\n"
704 "\tint i = (int) arg;\n\n");
707 "\tconn = rx_GetCachedConnection(serverAddr,serverPort,4,secClass,secIndex);\n");
709 fprintf(itl_h
, "\twhile(i--) {\n");
713 for (i
= first
; i
< last
; i
++) {
714 fprintf(itl_h
, "\t\tC_%s%d(conn);\n", serverName
, i
);
715 fprintf(itl_h
, "\t\tC_%s%d_s(conn);\n", serverName
, i
);
717 fprintf(itl_h
, "\t}\n");
719 fprintf(itl_h
, "\trx_ReleaseCachedConnection(conn);\n");
721 if (threadModel
== PTHREADS
) {
722 fprintf(itl_h
, "\treturn (void *) 0;\n");
725 "\tLWP_CALL(LWP_SignalProcess,(&done));\n" "\treturn 0;\n");
728 fprintf(itl_h
, "}\n");
731 "\n\nstatic void DoRun(struct cmd_syndesc *as, void *arock) {\n");
733 if (threadModel
== PTHREADS
) {
734 fprintf(itl_h
, "\tpthread_t *tid;\n");
736 fprintf(itl_h
, "\tPROCESS *tid;\n");
740 "\tint i,j;\n" "\tunsigned int numThreads=0,numIterations=0;\n"
741 "\tint errflg=0;\n" "\tstruct hostent *host=NULL;\n\n"
742 "\tnumThreads = atoi(as->parms[0].items->data);\n"
743 "\tnumIterations = atoi(as->parms[1].items->data);\n"
744 "\tsecType = atoi(as->parms[2].items->data);\n"
745 "\tencLevel = atoi(as->parms[3].items->data);\n"
746 "\tserverPort = htons(atoi(as->parms[4].items->data));\n"
747 "\tif ((host = hostutil_GetHostByName(as->parms[5].items->data))==0) {\n"
748 "\t\terrflg++;\n" "\t}\n" "\telse {\n"
749 "\t\tmemcpy((void *) &serverAddr, (const void *)host->h_addr, sizeof(serverAddr));\n"
750 "\t}\n" "\tif ((secType<1) || (secType>2)) errflg++;\n"
751 "\tif ((encLevel<0) || (encLevel>2)) errflg++;\n"
752 "\tif ((serverPort == 0) ||(numThreads == 0) ||(numIterations == 0)) errflg++;\n"
753 "\tif (errflg) {\n" "\t\tprintf(\"invalid argument\\n\");\n"
754 "\t\texit(1);\n" "\t}\n\n" "\tif(rx_Init(htons(0)) < 0) {\n"
755 "\t\texit(1);\n" "\t}\n\n" "\tswitch(secType) {\n" "\t\tcase 1:\n"
756 "\t\t\tsecIndex = 0;\n"
757 "\t\t\tsecClass = rxnull_NewClientSecurityObject();\n"
758 "\t\t\tbreak;\n" "\t\tcase 2:\n"
759 "\t\t\tif (GetTicket (&kvno, &Ksession, &ticketLen, ticket) == 0) {\n"
760 "\t\t\t\tsecIndex = 2;\n"
761 "\t\t\t\tsecClass = rxkad_NewClientSecurityObject(encLevel,\n"
762 "\t\t\t\t&Ksession, kvno, ticketLen, ticket);\n" "\t\t\t}\n"
763 "\t\t\tbreak;\n" "\t\tdefault:\n" "\t\t\tbreak;\n" "\t}\n"
764 "\tassert(secClass);\n\n");
765 if (threadModel
== PTHREADS
) {
767 "#if defined sun\n" "\tthr_setconcurrency(numThreads);\n"
768 "#endif\n" "\ttid = (pthread_t *) "
769 "malloc(numThreads*(sizeof(pthread_t)));\n");
772 "\ttid = malloc(numThreads*(sizeof(PROCESS *)));\n");
775 fprintf(itl_h
, "\tassert(tid);\n" "\tfor(j=0;j<numThreads;j++) {\n");
776 if (threadModel
== PTHREADS
) {
778 "\t\ti = pthread_create(&tid[j], (const pthread_attr_t *) 0,\n"
779 "\t\tthreadFunc, (void *) numIterations);\n"
780 "\t\tassert(i==0);\n");
783 "\t\tLWP_CALL(LWP_CreateProcess,(threadFunc, 10*4096, LWP_NORMAL_PRIORITY, numIterations, \"foo\", &tid[j]));\n");
786 fprintf(itl_h
, "\t}\n" "\tfor(j=0;j<numThreads;j++) {\n");
787 if (threadModel
== PTHREADS
) {
789 "\t\ti = pthread_join(tid[j], (void **) 0);\n"
790 "\t\tassert(i==0);\n");
792 fprintf(itl_h
, "\t\tLWP_CALL(LWP_WaitProcess,(&done));\n");
794 fprintf(itl_h
, "\t}\n" "\trx_Finalize();\n" "\tfree(tid);\n" "}\n");
797 * Write command syntax function
801 "static void SetupRunCmd(void) {\n" "\tstruct cmd_syndesc *ts;\n"
802 "\tts = cmd_CreateSyntax(NULL,DoRun, NULL, \"run the test client program\");\n"
803 "\tcmd_AddParm(ts, \"-threadCount\", CMD_SINGLE, CMD_REQUIRED, \"number of threads to spawn\");\n"
804 "\tcmd_AddParm(ts, \"-iterationCount\", CMD_SINGLE, CMD_REQUIRED, \"number of iterations to make over entire interface for each thread\");\n"
805 "\tcmd_AddParm(ts, \"-secType\", CMD_SINGLE, CMD_REQUIRED, \"security level to use (1 -> unauthenticated, 2 -> authenticated)\");\n"
806 "\tcmd_AddParm(ts, \"-encLevel\", CMD_SINGLE, CMD_REQUIRED, \"encryption level to use, (0-> rxkad_clear, 1 -> rxkad_auth, 2 -> rxkad_crypt)\");\n"
807 "\tcmd_AddParm(ts, \"-serverPort\", CMD_SINGLE, CMD_REQUIRED, \"port that server is using\");\n"
808 "\tcmd_AddParm(ts, \"-serverHost\", CMD_SINGLE, CMD_REQUIRED, \"host where server is running\");\n"
816 "int main (int argc, char *argv[]) {\n" "\tint code;\n\n"
817 "\tinitialize_CMD_error_table();\n" "\tSetupRunCmd();\n"
818 "\tcode = cmd_Dispatch(argc, argv);\n\n" "\treturn(code);\n"
824 * Create macros useful for checking input/output parameters
828 WriteTestMacros(FILE * f
)
831 "\n#define CHECKchar(x,y,z) if ((x)!=(y)) { printf(\"%%s: Got '%%c',"
832 "expected '%%c'\\n\", z, (char)x, (char)(y)); fflush(stdout); "
833 "errFlag = 1; } " "\n#define CHECKshort(x,y,z) if ((x)!=(y)) "
834 "{ printf(\"%%s: Got 0x%%04x, "
835 "expected 0x%%04x\\n\", z, x, y); fflush(stdout); "
836 "errFlag = 1; } " "\n#define CHECKint32(x,y,z) if ((x)!=(y)) "
837 "{ printf(\"%%s: Got 0x%%08x, "
838 "expected 0x%%08x\\n\", z, x, y); fflush(stdout); "
840 "\n#define CHECKfloat(x,y,z) if (((x)/(y)<.999999) "
841 "|| ((x)/(y)>1.000001)) "
842 "{ printf(\"%%s: Got %%2.8e, expected %%2.8e\\n\", z, x, y); "
843 "fflush(stdout); " "errFlag = 1; } "
844 "\n#define CHECKdouble(x,y,z) if (((x)/(y)<.999999999999999) || "
845 "((x)/(y)>1.000000000000001)) { printf(\"%%s: Got %%2.16e, "
846 "expected %%2.16e\\n\", z, x, y); fflush(stdout); errFlag = 1; }"
847 "\n#define CHECKvarString(x,y,z) if (strcmp((x),(y))) { printf(\"%%s: "
848 "Got \\\"%%s\\\", expected \\\"%%s\\\"\\n\", z, x, y); fflush(stdout); "
849 "errFlag = 1; } \n");
853 * WriteCltHeader - write the begining of the client code.
856 WriteCltHeader(char *serverName
, int srv_no
, FILE * itl_h
)
858 fprintf(itl_h
, "#include <stdio.h>\n");
859 if (threadModel
== PTHREADS
) {
860 fprintf(itl_h
, "#include <pthread.h>\n");
863 "%s" "#include <assert.h>\n" "#include <rx/rx.h>\n"
864 "#include <rx/rx_null.h>\n" "#include <rx/rxkad.h>\n"
865 "#include <afs/cmd.h>\n" "#include \"%s%d.h\"\n", platform
[4],
867 if (threadModel
== LWPS
) {
869 "\n\n#define LWP_CALL(fnName, params) \\\n" "{ \\\n"
870 "\tint rc; \\\n" "\trc = fnName params; \\\n"
871 "\tif (rc != LWP_SUCCESS) { \\\n"
872 "\t\tprintf(\"call to %%s failed with %%d\\n\", # fnName, rc); \\\n"
873 "\t\texit(1); \\\n" "\t} \\\n" "};\n\n" "char done;\n\n");
877 "struct ktc_encryptionKey serviceKey =\n"
878 "\t{0x45, 0xe3, 0x3d, 0x16, 0x29, 0x64, 0x8a, 0x8f};\n"
879 "long serviceKeyVersion = 7;\n"
880 "\nextern struct hostent *hostutil_GetHostByName();\n\n"
881 "static long GetTicket (long *versionP,\n"
882 "\tstruct ktc_encryptionKey *session,\n"
883 "\tint * ticketLenP, char *ticket)\n" "{\n" "\tlong code;\n"
884 "\tdes_init_random_number_generator (&serviceKey);\n"
885 "\tcode = des_random_key (session);\n"
886 "\tif (code) return code;\n" "\t*ticketLenP = 0;\n"
887 "\tcode = tkt_MakeTicket(ticket, ticketLenP, &serviceKey,\n"
888 "\t\t\"tclnt\", \"\", \"\",\n" "\t\t0, 0xffffffff, session, 0,\n"
889 "\t\t\"tsrvr\", \"\");\n" "\tif (code) return code;\n"
890 "\t*versionP = serviceKeyVersion;\n" "\treturn 0;\n" "}\n\n"
891 "static int secType,encLevel,serverPort,serverAddr;\n"
892 "struct rx_securityClass *secClass;\n" "int secIndex;\n"
893 "long kvno;\n" "char ticket[MAXKTCTICKETLEN];\n"
894 "int ticketLen;\n" "struct ktc_encryptionKey Ksession;\n\n");
895 WriteTestMacros(itl_h
);
900 * WriteCltInit -- write the initialization for each param
903 WriteCltInit(arg_tuple
* arg
, FILE * itl_h
, int i
, int structFlag
)
906 char *s
= (structFlag
) ? "s." : "";
908 if ((!strncmp(arg
->direction
, "IN", 2) || structFlag
)) {
909 if (!strncmp(arg
->type
, "varString", 9)) {
910 fprintf(itl_h
, "\tstrcpy(%sa%d, %s);\n", s
, i
, arg
->inValue
[0]);
911 } else if (!strncmp(arg
->type
, "ar_", 3)) {
914 "\t%sa%d.drpc_out_%s_t_len = FIX_ARRAY_SIZE;\n", s
, i
,
917 "\t%sa%d.drpc_out_%s_t_val = "
918 "malloc(FIX_ARRAY_SIZE * sizeof(%s));\n", s
, i
,
919 arg
->type
, (arg
->type
+ 3));
921 for (j
= 0; j
< IDL_FIX_ARRAY_SIZE
; j
++) {
923 fprintf(itl_h
, "\t%sa%d[%d] = %s;\n", s
, i
, j
,
926 fprintf(itl_h
, "\t%sa%d.drpc_out_%s_t_val[%d] = %s;\n", s
,
927 i
, arg
->type
, j
, arg
->inValue
[j
]);
931 fprintf(itl_h
, "\t%sa%d = %s;\n", s
, i
, arg
->inValue
[0]);
937 * WriteCltCall -- write each parameter for a call
940 WriteCltCall(arg_tuple
* arg
, FILE * itl_h
, int i
)
943 if (!strncmp(arg
->type
, "varString", 9)) {
944 if ((!strncmp(arg
->direction
, "OUT", 3))
945 || (!strncmp(arg
->direction
, "INOUT", 5))) {
946 fprintf(itl_h
, "&a%d_p", i
);
948 fprintf(itl_h
, "a%d_p", i
);
951 if ((!strncmp(arg
->direction
, "OUT", 3))
952 || (!strncmp(arg
->direction
, "INOUT", 5))
953 || (!strncmp(arg
->type
, "ar_", 3))) {
954 fprintf(itl_h
, "&a%d", i
);
956 fprintf(itl_h
, "a%d", i
);
962 * WriteCltDecl -- write the declaration for a parameter
965 WriteCltDecl(arg_tuple
* arg
, FILE * itl_h
, int i
)
968 if (!strncmp(arg
->type
, "ar_", 3)) {
969 if (!strncmp(arg
->direction
, "OUT", 3)) {
970 fprintf(itl_h
, "\tdrpc_out_%s_t a%d = {0,0};\n", arg
->type
, i
);
972 fprintf(itl_h
, "\tdrpc_out_%s_t a%d;\n", arg
->type
, i
);
974 } else if (!strncmp(arg
->type
, "varString", 9)) {
975 fprintf(itl_h
, "\tchar a%d[STR_MAX];\n", i
);
976 fprintf(itl_h
, "\tchar *a%d_p = a%d;\n", i
, i
);
978 fprintf(itl_h
, "\t%s a%d;\n", arg
->type
, i
);
984 * WriteClt -- write the rpcs in the client
987 WriteClt(rpcArgs
* argsP
, char *serverName
, int sign_no
, FILE * itl_h
)
989 char *name
, *name2
, *typ
;
992 name
= GetName(serverName
, sign_no
);
993 name2
= GetDescription(argsP
);
995 fprintf(itl_h
, "\n/* %s */\n\n", name2
);
997 fprintf(itl_h
, "\nvoid C_%s(struct rx_connection *conn) {\n", name
);
999 /* declare each arg */
1000 for (i
= 0; i
< argsP
->argCount
; i
++) {
1001 WriteCltDecl(&argsP
->argDescr
[i
], itl_h
, i
);
1003 fprintf(itl_h
, "\tint error;\n\tint errFlag;\n\n");
1005 /* initialize IN/INOUT args */
1006 for (i
= 0; i
< argsP
->argCount
; i
++) {
1007 WriteCltInit(&argsP
->argDescr
[i
], itl_h
, i
, FALSE
);
1010 /* call the server */
1011 fprintf(itl_h
, "\terror = A%s(conn, ", name
);
1014 for (i
= 0; i
< argsP
->argCount
; i
++) {
1015 WriteCltCall(&argsP
->argDescr
[i
], itl_h
, i
);
1016 fprintf(itl_h
, ((i
< (argsP
->argCount
- 1))) ? "," : ");\n");
1020 "\tif (error != 0) {\n"
1021 "\t\tprintf(\"C_%s failed %%d\\n\", error);\n"
1022 "\t\tfflush(stdout);\n" "\t\treturn;\n" "\t}\n", name
);
1025 * check the in and inout parameters
1027 for (i
= 0; i
< argsP
->argCount
; i
++) {
1029 if ((!strcmp(argsP
->argDescr
[i
].direction
, "OUT"))
1030 || (!strcmp(argsP
->argDescr
[i
].direction
, "INOUT"))) {
1032 typ
= argsP
->argDescr
[i
].type
;
1034 if (!strncmp(typ
, "ar_", 3)) {
1035 for (j
= 0; j
< IDL_FIX_ARRAY_SIZE
; j
++)
1037 "\n\tCHECK%s(a%d.drpc_out_%s_t_val[%d], %s, \"C_%s_s\");",
1038 (typ
+ 3), i
, typ
, j
,
1039 argsP
->argDescr
[i
].outValue
[j
], name
);
1040 } else if (strstr(typ
, "String")) {
1041 fprintf(itl_h
, "\n\tCHECK%s((char *)a%d, %s, \"C_%s_s\");",
1042 typ
, i
, argsP
->argDescr
[i
].outValue
[0], name
);
1043 } else if (!strcmp(typ
, "afs_int32")) {
1044 fprintf(itl_h
, "\n\tCHECK%s(a%d, %sL, \"C_%s_s\");", typ
, i
,
1045 argsP
->argDescr
[i
].outValue
[0], name
);
1047 fprintf(itl_h
, "\n\tCHECK%s(a%d, %s, \"C_%s_s\");", typ
, i
,
1048 argsP
->argDescr
[i
].outValue
[0], name
);
1054 * free up memory for dynamic input args
1056 for (i
= 0; i
< argsP
->argCount
; i
++) {
1057 if (!strncmp(argsP
->argDescr
[i
].type
, "ar_", 3)) {
1058 typ
= argsP
->argDescr
[i
].type
;
1060 "\n\tif (a%d.drpc_out_%s_t_val) "
1061 "free(a%d.drpc_out_%s_t_val);", i
, typ
, i
, typ
);
1066 fprintf(itl_h
, "\n}\n");
1069 * Call the structure oriented rpc interface
1072 fprintf(itl_h
, "\nvoid C_%s_s(struct rx_connection *conn) {\n", name
);
1073 fprintf(itl_h
, "\tstruct %s_t s;\n", name
);
1074 fprintf(itl_h
, "\tint error;\n\tint errFlag;\n\n");
1076 /* initialize IN/INOUT args */
1077 for (i
= 0; i
< argsP
->argCount
; i
++) {
1078 WriteCltInit(&argsP
->argDescr
[i
], itl_h
, i
, TRUE
);
1081 /* call the server */
1082 fprintf(itl_h
, "\terror = A%s_s(conn, &s);\n", name
);
1085 "\tif (error != 0) {\n"
1086 "\t\tprintf(\"C_%s_s failed %%d\\n\", error);\n"
1087 "\t\tfflush(stdout);\n" "\t\treturn;\n" "\t}\n", name
);
1090 * check the in and inout parameters
1092 for (i
= 0; i
< argsP
->argCount
; i
++) {
1094 if ((!strcmp(argsP
->argDescr
[i
].direction
, "OUT"))
1095 || (!strcmp(argsP
->argDescr
[i
].direction
, "INOUT"))) {
1097 typ
= argsP
->argDescr
[i
].type
;
1099 if (!strncmp(typ
, "ar_", 3)) {
1100 for (j
= 0; j
< IDL_FIX_ARRAY_SIZE
; j
++)
1101 fprintf(itl_h
, "\n\tCHECK%s(s.a%d[%d], %s, \"C_%s_s\");",
1102 (typ
+ 3), i
, j
, argsP
->argDescr
[i
].outValue
[j
],
1104 } else if (strstr(typ
, "String")) {
1105 fprintf(itl_h
, "\n\tCHECK%s((char *)s.a%d, %s, \"C_%s_s\");",
1106 typ
, i
, argsP
->argDescr
[i
].outValue
[0], name
);
1107 } else if (!strcmp(typ
, "afs_int32")) {
1108 fprintf(itl_h
, "\n\tCHECK%s(s.a%d, %sL, \"C_%s_s\");", typ
, i
,
1109 argsP
->argDescr
[i
].outValue
[0], name
);
1111 fprintf(itl_h
, "\n\tCHECK%s(s.a%d, %s, \"C_%s_s\");", typ
, i
,
1112 argsP
->argDescr
[i
].outValue
[0], name
);
1118 fprintf(itl_h
, "\n}\n");
1125 * WriteXGHeader -- fill in Header info in the xg file
1128 WriteXGHeader(char *serverName
, FILE * xg_h
, int srv_no
)
1131 /* create the interface header */
1134 "\n/* Do not edit this file -- it was created by a generator */\n"
1135 "\npackage A\n\n" "const STR_MAX = %d; \n"
1136 "const FIX_ARRAY_SIZE = %d; \n" "typedef char drpc_char_t; \n"
1137 "typedef short drpc_short_t; \n" "typedef long drpc_int32_t; \n"
1138 "typedef string drpc_varString_t<STR_MAX>; \n"
1139 "typedef drpc_char_t drpc_ar_char_t[FIX_ARRAY_SIZE]; \n"
1140 "typedef drpc_char_t drpc_out_ar_char_t<FIX_ARRAY_SIZE>; \n"
1141 "typedef drpc_short_t drpc_ar_short_t[FIX_ARRAY_SIZE]; \n"
1142 "typedef drpc_short_t drpc_out_ar_short_t<FIX_ARRAY_SIZE>; \n"
1143 "typedef drpc_int32_t drpc_ar_int32_t[FIX_ARRAY_SIZE]; \n"
1144 "typedef drpc_int32_t drpc_out_ar_int32_t<FIX_ARRAY_SIZE>; \n",
1145 IDL_STR_MAX
, IDL_FIX_ARRAY_SIZE
);
1149 * WriteServHeader -- fill in the Header info in the server file
1152 WriteServHeader(FILE * srv_h
, char *serverName
, int srv_no
)
1156 name
= GetName(serverName
, srv_no
);
1159 "\n/* Do not edit this file -- it's been created by a generator */\n\n"
1160 "%s\n" "#include <stdio.h>\n" "#include <string.h>\n"
1161 "#include <stdlib.h>\n" "#include <rx/rx.h>\n"
1162 "#include <rx/rx_null.h>\n" "#include <rx/rxkad.h>\n"
1163 "#include <afs/cmd.h>\n" "#include \"%s.h\"\n\n"
1164 "struct ktc_encryptionKey serviceKey =\n"
1165 "\t{0x45, 0xe3, 0x3d, 0x16, 0x29, 0x64, 0x8a, 0x8f};\n"
1166 "long serviceKeyVersion = 7;\n\n"
1167 "extern int AExecuteRequest();\n" "extern char *optarg;\n"
1168 "extern int optind, opterr, optopt;\n\n"
1169 "#define VERIFY(x,y) if (!(x)) { printf y ; exit(1); }\n"
1170 "#define CHECK(x) ASSERT(x)\n", platform
[4], name
);
1172 WriteTestMacros(srv_h
);
1177 * WriteServTrailer -- finish up the server file
1180 WriteServTrailer(FILE * srv_h
)
1184 "\nstatic long GetKey (char *rock, long kvno, struct ktc_encryptionKey *key) {\n"
1185 "\tmemcpy ((void *) key, (void *) &serviceKey, sizeof(*key));\n"
1186 "\treturn 0;\n" "}\n\n"
1187 "static void DoRun(struct cmd_syndesc *as, void *arock) {\n"
1188 "\tstruct rx_service *serv;\n"
1189 "\tstruct rx_securityClass *sc[3];\n\n"
1190 "\tint port=0, errflg=0;\n" "\tint lowThreads=4, highThreads=8;\n"
1191 "\tlowThreads = atoi(as->parms[0].items->data);\n"
1192 "\thighThreads = atoi(as->parms[1].items->data);\n"
1193 "\tport = atoi(as->parms[2].items->data);\n"
1194 "\tif (port == 0) errflg++;\n" "\tif (errflg) {\n"
1195 "\t\tprintf(\"invalid argument\\n\");\n" "\t\texit(1);\n" "\t}\n"
1196 "\trx_Init(htons(port));\n"
1197 "\tsc[0] = rxnull_NewServerSecurityObject();\n" "\tsc[1] = 0;\n"
1198 "\tsc[2] = rxkad_NewServerSecurityObject (rxkad_clear, 0, GetKey, 0);\n"
1199 "\tif (serv = rx_NewService(0,4,\"foo\",sc,3,AExecuteRequest)) {\n"
1200 "\t\trx_SetMinProcs(serv,lowThreads);\n"
1201 "\t\trx_SetMaxProcs(serv,highThreads);\n"
1202 "\t\trx_StartServer(1);\n" "\t}\n" "\texit(0);\n" "}\n\n"
1203 "static void SetupRunCmd(void) {\n" "\tstruct cmd_syndesc *ts;\n"
1204 "\tts = cmd_CreateSyntax(NULL,DoRun, NULL, \"run the test server program\");\n"
1205 "\tcmd_AddParm(ts, \"-lowThreadCount\", CMD_SINGLE, CMD_REQUIRED, \"minimum number of threads to spawn\");\n"
1206 "\tcmd_AddParm(ts, \"-highThreadCount\", CMD_SINGLE, CMD_REQUIRED, \"maximum number of threads to spawn\");\n"
1207 "\tcmd_AddParm(ts, \"-serverPort\", CMD_SINGLE, CMD_REQUIRED, \"port that server is using\");\n"
1208 "}\n" "int main(int argc, char **argv) {\n" "\tint code;\n"
1209 "\tinitialize_CMD_error_table();\n" "\tSetupRunCmd();\n"
1210 "\tcode = cmd_Dispatch(argc, argv);\n" "\treturn(code);\n" "}\n");
1214 * ProcessCmdLine -- processes the command line args
1217 ProcessCmdLine(int argc
, char **argv
, char **serverName
, char **ipFileName
,
1224 /* command line processing */
1225 while (--argc
> 0) {
1226 if ((*++argv
)[0] == '-') {
1227 switch ((*argv
)[1]) {
1230 case 'F': /* input table file */
1231 *ipFileName
= *++argv
;
1234 case 'h': /* display help */
1240 case 'L': /* use LWP threads */
1244 case 'S': /* serverName */
1245 *serverName
= *++argv
;
1246 /* need 8 char file name, and so truncate the server name */
1247 if ((int)strlen(*serverName
) > MAX_SERV_NAME
)
1248 *(*serverName
+ MAX_SERV_NAME
) = '\0';
1253 *outputDir
= *++argv
;
1258 if (strcmp(*++argv
, "NT"))
1259 platform
= unix_symbols
;
1273 FATAL("Please set server name using -s switch\n");
1278 main(int argc
, char **argv
)
1280 FILE *table_h
, *srv_h
, *xg_h
, *clt_h
, *mak_h
;
1283 char *name
, *ifName
;
1284 char *serverName
= NULL
;
1285 char *ipFileName
= NULL
;
1286 char *outputDir
= NULL
;
1287 int sign_no
= 0, start_no
, srv_no
;
1289 ProcessCmdLine(argc
, argv
, &serverName
, &ipFileName
, &outputDir
);
1291 /* open input file */
1292 table_h
= fopen(ipFileName
, "r");
1293 MEM_CHK(table_h
, "main: Unable to open input file\n");
1299 * open the first set of output files
1302 name
= GetName(serverName
, srv_no
);
1304 srv_h
= OpenOutFile(outputDir
, name
, "Srv.c");
1305 xg_h
= OpenOutFile(outputDir
, name
, ".xg");
1306 clt_h
= OpenOutFile(outputDir
, name
, "Clt.c");
1307 mak_h
= OpenOutFile(outputDir
, name
, ".mak");
1309 WriteXGHeader(serverName
, xg_h
, srv_no
);
1310 WriteServHeader(srv_h
, serverName
, srv_no
);
1311 WriteCltHeader(serverName
, srv_no
, clt_h
);
1312 WriteMake(serverName
, srv_no
, mak_h
);
1316 /* read the table */
1317 while (fscanf(table_h
, "%d", &(args
.argCount
)) != EOF
) {
1319 /* increment signature number 8.3 format-- only 10^7 dif sign */
1321 if (sign_no
> 1.0e+7)
1322 FATAL("Max no: of signatures overflow\n");
1324 /* allocate for the arg struct */
1326 (arg_tuple
*) calloc(args
.argCount
, sizeof(arg_tuple
));
1327 MEM_CHK(args
.argDescr
, "main: Out of memory -- args.argDescr\n");
1329 /* pick out the dirs and the types */
1330 for (i
= 0; i
< args
.argCount
; i
++) {
1332 (table_h
, " ( %s %s )", args
.argDescr
[i
].direction
,
1333 args
.argDescr
[i
].type
)) {
1334 FATAL("main: Incorrect input file format\n");
1339 * switch files when we hit TESTS_PER_FILE
1341 if (sign_no
- start_no
>= TESTS_PER_FILE
) {
1343 * Finish up the current files
1345 WriteServTrailer(srv_h
);
1346 WriteCltTrailer(serverName
, start_no
, sign_no
, clt_h
);
1353 * Open the next set of output files
1358 name
= GetName(serverName
, srv_no
);
1360 srv_h
= OpenOutFile(outputDir
, name
, "Srv.c");
1361 xg_h
= OpenOutFile(outputDir
, name
, ".xg");
1362 clt_h
= OpenOutFile(outputDir
, name
, "Clt.c");
1363 mak_h
= OpenOutFile(outputDir
, name
, ".mak");
1364 WriteXGHeader(serverName
, xg_h
, srv_no
);
1365 WriteServHeader(srv_h
, serverName
, srv_no
);
1366 WriteCltHeader(serverName
, srv_no
, clt_h
);
1367 WriteMake(serverName
, srv_no
, mak_h
);
1373 /* initialize parameter values */
1374 for (i
= 0; i
< args
.argCount
; i
++) {
1375 for (j
= 0; j
< IDL_FIX_ARRAY_SIZE
; j
++) {
1376 args
.argDescr
[i
].inValue
[j
] = NULL
;
1377 args
.argDescr
[i
].inValue2
[j
] = NULL
;
1378 args
.argDescr
[i
].outValue
[j
] = NULL
;
1379 args
.argDescr
[i
].outValue2
[j
] = NULL
;
1382 GenParamValues(&args
);
1384 /* write rpc desc into body of the interface */
1385 WriteXG(&args
, xg_h
, serverName
, sign_no
);
1387 /* write the rpc into the manager file */
1388 WriteServC(&args
, srv_h
, serverName
, sign_no
);
1390 /* write out ITL test */
1391 WriteClt(&args
, serverName
, sign_no
, clt_h
);
1393 /* free saved values */
1394 for (i
= 0; i
< args
.argCount
; i
++) {
1395 for (j
= 0; j
< IDL_FIX_ARRAY_SIZE
; j
++) {
1396 if (args
.argDescr
[i
].inValue
[j
])
1397 free(args
.argDescr
[i
].inValue
[j
]);
1398 if (args
.argDescr
[i
].inValue2
[j
])
1399 free(args
.argDescr
[i
].inValue2
[j
]);
1400 if (args
.argDescr
[i
].outValue
[j
])
1401 free(args
.argDescr
[i
].outValue
[j
]);
1402 if (args
.argDescr
[i
].outValue2
[j
])
1403 free(args
.argDescr
[i
].outValue2
[j
]);
1406 free(args
.argDescr
);
1409 WriteServTrailer(srv_h
);
1410 WriteCltTrailer(serverName
, start_no
, (sign_no
+ 1), clt_h
);
1420 * create 1 makefile that drives all the rest
1423 mak_h
= OpenOutFile(outputDir
, "Makefile", "");
1424 fprintf(mak_h
, "\ntest:all\ntests:all\nall:\n");
1425 fprintf(mak_h
, "%s", platform
[8]);
1426 for (i
= 1; i
<= srv_no
; i
++)
1427 fprintf(mak_h
, "\t%s %s%d.mak %s\n", platform
[0], serverName
, i
,
1429 fprintf(mak_h
, "\nclean:\n");
1430 for (i
= 1; i
<= srv_no
; i
++)
1431 fprintf(mak_h
, "\t%s %s%d.mak clean\n", platform
[0], serverName
, i
);