|
1 /********************************************************************* |
|
2 * RPC for the Windows NT Operating System |
|
3 * 1993 by Martin F. Gergeleit |
|
4 * Users may use, copy or modify Sun RPC for the Windows NT Operating |
|
5 * System according to the Sun copyright below. |
|
6 * |
|
7 * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO |
|
8 * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE |
|
9 * USE OF. USE ENTIRELY AT YOUR OWN RISK!!! |
|
10 *********************************************************************/ |
|
11 |
|
12 /* @(#)rpc_main.c 2.2 88/08/01 4.0 RPCSRC */ |
|
13 /* |
|
14 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for |
|
15 * unrestricted use provided that this legend is included on all tape |
|
16 * media and as a part of the software program in whole or part. Users |
|
17 * may copy or modify Sun RPC without charge, but are not authorized |
|
18 * to license or distribute it to anyone else except as part of a product or |
|
19 * program developed by the user. |
|
20 * |
|
21 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE |
|
22 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR |
|
23 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. |
|
24 * |
|
25 * Sun RPC is provided with no support and without any obligation on the |
|
26 * part of Sun Microsystems, Inc. to assist in its use, correction, |
|
27 * modification or enhancement. |
|
28 * |
|
29 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE |
|
30 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC |
|
31 * OR ANY PART THEREOF. |
|
32 * |
|
33 * In no event will Sun Microsystems, Inc. be liable for any lost revenue |
|
34 * or profits or other special, indirect and consequential damages, even if |
|
35 * Sun has been advised of the possibility of such damages. |
|
36 * |
|
37 * Sun Microsystems, Inc. |
|
38 * 2550 Garcia Avenue |
|
39 * Mountain View, California 94043 |
|
40 */ |
|
41 //#ifndef lint |
|
42 //static char sccsid[] = "@(#)rpc_main.c 1.7 87/06/24 (C) 1987 SMI"; |
|
43 //#endif |
|
44 |
|
45 /* |
|
46 * rpc_main.c, Top level of the RPC protocol compiler. |
|
47 * Copyright (C) 1987, Sun Microsystems, Inc. |
|
48 */ |
|
49 |
|
50 #include <stdio.h> |
|
51 #include <assert.h> |
|
52 #include <stdlib.h> |
|
53 #include <string.h> |
|
54 #include <ctype.h> |
|
55 #include "rpc_util.h" |
|
56 #include "rpc_pars.h" |
|
57 #include "rpc_scan.h" |
|
58 |
|
59 #ifdef WIN32 |
|
60 #include <direct.h> |
|
61 #include <process.h> |
|
62 #include <io.h> |
|
63 #include <fcntl.h> |
|
64 #else |
|
65 #include <unistd.h> |
|
66 #include <sys/file.h> |
|
67 #endif |
|
68 |
|
69 #include "ae_component_rpc.h" |
|
70 |
|
71 #define EXTEND 1 /* alias for TRUE */ |
|
72 |
|
73 static char *cmdname; |
|
74 #ifdef WIN32 |
|
75 #ifdef __BORLANDC__ |
|
76 static char CPP[] = "cpp32"; |
|
77 static char CPPFLAGS[] = "-C -P- -oCON"; |
|
78 #else |
|
79 static char CPP[] = "cl"; |
|
80 static char CPPFLAGS[] = "/C /EP /nologo"; |
|
81 #endif |
|
82 #else |
|
83 static char CPP[] = "/usr/bin/cpp"; |
|
84 static char CPPFLAGS[] = "-C"; |
|
85 #endif |
|
86 static char *allv[] = { |
|
87 "rpcgen", "-s", "udp", "-s", "tcp", |
|
88 }; |
|
89 static int allc = sizeof(allv)/sizeof(allv[0]); |
|
90 |
|
91 |
|
92 /* prototypes */ |
|
93 extern void crash(); |
|
94 static void do_registers( int argc, char *argv[] ); |
|
95 struct commandline command_line; |
|
96 |
|
97 |
|
98 /* |
|
99 * add extension to filename |
|
100 */ |
|
101 char * |
|
102 extendfile(file, ext) |
|
103 char *file; |
|
104 char *ext; |
|
105 { |
|
106 #ifdef WIN32 |
|
107 int i; |
|
108 #endif |
|
109 char *res; |
|
110 char *p; |
|
111 |
|
112 res = alloc(strlen(file) + strlen(ext) + 1); |
|
113 if (res == NULL) { |
|
114 abort(); |
|
115 } |
|
116 #ifdef WIN32 |
|
117 p = NULL; |
|
118 for (i = 0; file[i] != '\0'; i++) |
|
119 if (file[i] == '.') |
|
120 p = &file[i]; |
|
121 #else |
|
122 p = rindex(file, '.'); |
|
123 #endif |
|
124 if (p == NULL) { |
|
125 p = file + strlen(file); |
|
126 } |
|
127 (void) strcpy(res, file); |
|
128 (void) strcpy(res + (p - file), ext); |
|
129 return (res); |
|
130 } |
|
131 |
|
132 /* |
|
133 * Open output file with given extension |
|
134 */ |
|
135 void |
|
136 open_output(infile, outfile) |
|
137 char *infile; |
|
138 char *outfile; |
|
139 { |
|
140 char *ptr; |
|
141 char buff[1024]; |
|
142 |
|
143 // check that some file is specified |
|
144 if (outfile == NULL) { |
|
145 fout = stdout; |
|
146 return; |
|
147 } |
|
148 |
|
149 // set the buffer with the specified output path |
|
150 strcpy( buff, command_line.outfile ); |
|
151 |
|
152 // only copy the filename itself |
|
153 ptr = strrchr( outfile, '\\' ); |
|
154 if( ptr == NULL ) { |
|
155 ptr = strrchr( outfile, '/' ); |
|
156 if( ptr == NULL ) { |
|
157 ptr = outfile - 1; |
|
158 } |
|
159 } |
|
160 ptr++; |
|
161 strcat( buff, ptr ); |
|
162 |
|
163 // check that we are not going to overwrite the input file |
|
164 if (infile != NULL && streq(buff, infile)) { |
|
165 f_print(stderr, "%s: output would overwrite %s\n", cmdname, infile); |
|
166 crash(); |
|
167 } |
|
168 |
|
169 // fprintf( stderr, "INFO: opening output file %s\n", buff ); |
|
170 |
|
171 // open the output file |
|
172 fout = fopen(buff, "w"); |
|
173 if (fout == NULL) { |
|
174 f_print(stderr, "%s: unable to open output file.", cmdname); |
|
175 perror(buff); |
|
176 crash(); |
|
177 } |
|
178 record_open(buff); |
|
179 } |
|
180 |
|
181 /* |
|
182 * Open input file with given define for C-preprocessor |
|
183 */ |
|
184 void |
|
185 open_input(infile, define) |
|
186 char *infile; |
|
187 char *define; |
|
188 { |
|
189 #ifdef WIN32 |
|
190 #ifdef __BORLANDC__ |
|
191 #define _P_WAIT P_WAIT |
|
192 #define _spawnlp spawnlp |
|
193 #endif |
|
194 int old; |
|
195 int pd[2]; |
|
196 |
|
197 infilename = (infile == NULL) ? "<stdin>" : infile; |
|
198 _pipe(pd, 0xffff, O_TEXT); |
|
199 |
|
200 old = dup(1); |
|
201 (void) dup2(pd[1], 1); |
|
202 |
|
203 if (_spawnlp(_P_WAIT, CPP, CPP, CPPFLAGS, |
|
204 define, infile, NULL) < 0) { |
|
205 f_print(stderr, "%s: unable to open ", cmdname); |
|
206 perror(CPP); |
|
207 crash(); |
|
208 } |
|
209 |
|
210 (void) dup2(old, 1); |
|
211 |
|
212 (void) close(pd[1]); |
|
213 fin = fdopen(pd[0], "r"); |
|
214 if (fin == NULL) { |
|
215 f_print(stderr, "%s: ", cmdname); |
|
216 perror(infilename); |
|
217 crash(); |
|
218 } |
|
219 #else |
|
220 int pd[2]; |
|
221 |
|
222 infilename = (infile == NULL) ? "<stdin>" : infile; |
|
223 (void) pipe(pd); |
|
224 switch (fork()) { |
|
225 case 0: |
|
226 (void) close(1); |
|
227 (void) dup2(pd[1], 1); |
|
228 (void) close(pd[0]); |
|
229 execl(CPP, CPP, CPPFLAGS, define, infile, NULL); |
|
230 perror("execl"); |
|
231 exit(1); |
|
232 case -1: |
|
233 perror("fork"); |
|
234 exit(1); |
|
235 } |
|
236 (void) close(pd[1]); |
|
237 fin = fdopen(pd[0], "r"); |
|
238 if (fin == NULL) { |
|
239 f_print(stderr, "%s: ", cmdname); |
|
240 perror(infilename); |
|
241 crash(); |
|
242 } |
|
243 #endif |
|
244 } |
|
245 |
|
246 /* |
|
247 * Compile into an XDR routine output file |
|
248 */ |
|
249 static void |
|
250 c_output(infile, define, extend, outfile) |
|
251 char *infile; |
|
252 char *define; |
|
253 int extend; |
|
254 char *outfile; |
|
255 { |
|
256 definition *def; |
|
257 char *include; |
|
258 char *outfilename; |
|
259 long tell; |
|
260 |
|
261 open_input(infile, define); |
|
262 outfilename = extend ? extendfile(infile, outfile) : outfile; |
|
263 open_output(infile, outfilename); |
|
264 f_print(fout, "#include <rpc/rpc.h>\n"); |
|
265 if (infile && (include = extendfile(infile, ".h"))) { |
|
266 f_print(fout, "#include \"%s\"\n", include); |
|
267 free(include); |
|
268 } |
|
269 tell = ftell(fout); |
|
270 while ((def = get_definition())) { |
|
271 emit(def); |
|
272 } |
|
273 if (extend && tell == ftell(fout)) { |
|
274 (void) unlink(outfilename); |
|
275 } |
|
276 } |
|
277 |
|
278 /* |
|
279 * Compile into an XDR header file |
|
280 */ |
|
281 static void |
|
282 h_output(infile, define, extend, outfile) |
|
283 char *infile; |
|
284 char *define; |
|
285 int extend; |
|
286 char *outfile; |
|
287 { |
|
288 definition *def; |
|
289 char *outfilename; |
|
290 long tell; |
|
291 char nbuff[256]; |
|
292 |
|
293 open_input(infile, define); |
|
294 outfilename = extend ? extendfile(infile, outfile) : outfile; |
|
295 open_output(infile, outfilename); |
|
296 tell = ftell(fout); |
|
297 |
|
298 // AE -- do proper #ifdef |
|
299 { |
|
300 char *ptr; |
|
301 int slen; |
|
302 int i; |
|
303 |
|
304 // get a pointer to the filename |
|
305 ptr = strrchr( outfilename, '\\' ); |
|
306 ptr = ((ptr == NULL) ? outfilename : ptr+1); |
|
307 |
|
308 // now copy the filename |
|
309 slen = strlen(ptr); |
|
310 assert( slen < 256 ); |
|
311 memcpy( nbuff, ptr, slen ); |
|
312 nbuff[slen] = 0; |
|
313 |
|
314 // make everything upper case |
|
315 for( i = 0; i < slen; i++ ) { |
|
316 nbuff[i] = toupper( nbuff[i] ); |
|
317 } |
|
318 assert( nbuff[slen-2] == '.' ); |
|
319 nbuff[slen-2] = '_'; |
|
320 |
|
321 // now print the ifdef |
|
322 f_print( fout, "#ifndef __%s__\n", nbuff ); |
|
323 f_print( fout, "#define __%s__\n", nbuff ); |
|
324 } |
|
325 |
|
326 |
|
327 /*** The following line was added, ***/ |
|
328 /*** 31.03.92, Detlef Schwellenbach ***/ |
|
329 |
|
330 f_print(fout, "#include <rpc/types.h>\n"); |
|
331 |
|
332 // AE -- include this for the CLIENT type |
|
333 { |
|
334 f_print(fout, "#include <rpc/rpc.h>\n\n"); |
|
335 } |
|
336 |
|
337 while ((def = get_definition())) { |
|
338 print_datadef(def); |
|
339 } |
|
340 if (extend && tell == ftell(fout)) { |
|
341 (void) unlink(outfilename); |
|
342 } |
|
343 |
|
344 // AE -- end the #def |
|
345 f_print(fout, "#endif /* __%s__ */\n", nbuff ); |
|
346 } |
|
347 |
|
348 /* |
|
349 * Compile into an RPC service |
|
350 */ |
|
351 static void |
|
352 s_output(argc, argv, infile, define, extend, outfile, nomain) |
|
353 int argc; |
|
354 char *argv[]; |
|
355 char *infile; |
|
356 char *define; |
|
357 int extend; |
|
358 char *outfile; |
|
359 int nomain; |
|
360 { |
|
361 char *include; |
|
362 definition *def; |
|
363 int foundprogram; |
|
364 char *outfilename; |
|
365 |
|
366 open_input(infile, define); |
|
367 outfilename = extend ? extendfile(infile, outfile) : outfile; |
|
368 open_output(infile, outfilename); |
|
369 f_print(fout, "#include <stdio.h>\n"); |
|
370 f_print(fout, "#include <rpc/rpc.h>\n"); |
|
371 f_print(fout, "#ifdef WIN32\n"); |
|
372 f_print(fout, "#include <rpc/PMAP_CLN.H>\n"); |
|
373 f_print(fout, "#else\n"); |
|
374 f_print(fout, "#include <rpc/pmap_clnt.h>\n"); |
|
375 f_print(fout, "#endif\n"); |
|
376 if (infile && (include = extendfile(infile, ".h"))) { |
|
377 f_print(fout, "#include \"%s\"\n", include); |
|
378 free(include); |
|
379 } |
|
380 foundprogram = 0; |
|
381 while ((def = get_definition())) { |
|
382 foundprogram |= (def->def_kind == DEF_PROGRAM); |
|
383 } |
|
384 if (extend && !foundprogram) { |
|
385 (void) unlink(outfilename); |
|
386 return; |
|
387 } |
|
388 if (nomain) { |
|
389 write_programs((char *)NULL); |
|
390 } else { |
|
391 write_most(); |
|
392 do_registers(argc, argv); |
|
393 write_rest(); |
|
394 write_programs("static"); |
|
395 } |
|
396 } |
|
397 |
|
398 static void |
|
399 l_output(infile, define, extend, outfile) |
|
400 char *infile; |
|
401 char *define; |
|
402 int extend; |
|
403 char *outfile; |
|
404 { |
|
405 char *include; |
|
406 definition *def; |
|
407 int foundprogram; |
|
408 char *outfilename; |
|
409 |
|
410 open_input(infile, define); |
|
411 outfilename = extend ? extendfile(infile, outfile) : outfile; |
|
412 open_output(infile, outfilename); |
|
413 f_print(fout, "#include <rpc/rpc.h>\n"); |
|
414 if (infile && (include = extendfile(infile, ".h"))) { |
|
415 f_print(fout, "#include \"%s\"\n", include); |
|
416 free(include); |
|
417 } |
|
418 foundprogram = 0; |
|
419 while ((def = get_definition())) { |
|
420 foundprogram |= (def->def_kind == DEF_PROGRAM); |
|
421 } |
|
422 if (extend && !foundprogram) { |
|
423 (void) unlink(outfilename); |
|
424 return; |
|
425 } |
|
426 write_stubs(); |
|
427 } |
|
428 |
|
429 /* |
|
430 * Perform registrations for service output |
|
431 */ |
|
432 static void |
|
433 do_registers(argc, argv) |
|
434 int argc; |
|
435 char *argv[]; |
|
436 { |
|
437 int i; |
|
438 |
|
439 for (i = 1; i < argc; i++) { |
|
440 if (streq(argv[i], "-s")) { |
|
441 write_register(argv[i + 1]); |
|
442 i++; |
|
443 } |
|
444 } |
|
445 } |
|
446 |
|
447 /* |
|
448 * Parse command line arguments |
|
449 */ |
|
450 static int parseargs( int argc, char *argv[], struct commandline *cmd ) |
|
451 { |
|
452 int i, err; |
|
453 char *opt; |
|
454 |
|
455 // check params |
|
456 assert( argv != NULL ); |
|
457 assert( cmd != NULL ); |
|
458 |
|
459 // clear the cmd struct |
|
460 memset( cmd, 0, sizeof(*cmd) ); |
|
461 |
|
462 // if we don't have at least one extra param (the filename) then exit |
|
463 if( argc < 2 ) { |
|
464 return 0; |
|
465 } |
|
466 |
|
467 // now parse each token |
|
468 for( i = 1; i < argc; i++ ) { |
|
469 |
|
470 // if the first char is not '-' then this is the filename and we should break |
|
471 if( argv[i][0] != '-' ) { |
|
472 break; |
|
473 } |
|
474 |
|
475 // get a pointer to the option |
|
476 opt = &(argv[i][1]); |
|
477 |
|
478 // now look for a match |
|
479 if( strcmp(opt,"client") == 0 ) { |
|
480 cmd->client_flag = 1; |
|
481 } else if( strcmp(opt,"server") == 0 ) { |
|
482 cmd->server_flag = 1; |
|
483 } else if( strcmp(opt,"component_base") == 0 ) { |
|
484 cmd->component_base_flag = 1; |
|
485 } else if( strcmp(opt,"component_mod_service_manager") == 0 ) { |
|
486 cmd->component_mod_service_manager = 1; |
|
487 } else if( strcmp(opt,"component_mod_component_impl") == 0 ) { |
|
488 cmd->component_mod_component_impl = 1; |
|
489 } else if( strcmp(opt,"wrapstring") == 0 ) { |
|
490 cmd->wrapstring_flag = 1; |
|
491 } else if( strcmp(opt,"header") == 0 ) { |
|
492 cmd->header = 1; |
|
493 } else if( opt[0] == 't' ) { |
|
494 opt++; |
|
495 ae_set_trace( atoi(opt) ); |
|
496 } else if( strncmp(opt,"o:",2) == 0 ) { |
|
497 opt = &(argv[i][3]); |
|
498 strcpy( cmd->outfile, opt ); |
|
499 } else if( strncmp(opt,"p:",2) == 0 ) { |
|
500 opt = &(argv[i][3]); |
|
501 err = chdir( opt ); |
|
502 if( err != 0 ) { |
|
503 fprintf( stderr, "WARNING: couldn't change to the specified path.\n" ); |
|
504 return 0; |
|
505 } |
|
506 // fprintf( stderr, "INFO: changing directory to %s.\n", opt ); |
|
507 } else { |
|
508 fprintf( stderr, "WARNING: unknown option '-%s'\n", opt ); |
|
509 } |
|
510 } |
|
511 |
|
512 // now read in the filename |
|
513 if( i == argc ) { |
|
514 fprintf( stderr, "WARNING: no filename specified.\n" ); |
|
515 return 0; |
|
516 } |
|
517 cmd->infile = argv[i]; |
|
518 |
|
519 // done |
|
520 return 1; |
|
521 } |
|
522 |
|
523 |
|
524 int |
|
525 main(argc, argv) |
|
526 int argc; |
|
527 char *argv[]; |
|
528 |
|
529 { |
|
530 // parse the command line |
|
531 if (!parseargs(argc, argv, &command_line)) { |
|
532 fprintf( stderr, "usage: %s [-header | -client | -server | -component_base | -component_mod_service_manager | -component_mod_component_impl | -w | -t#] interface_file\n", argv[0] ); |
|
533 fprintf( stderr, "\tt0 - Component stubs.\n" ); |
|
534 fprintf( stderr, "\tt2 - Service manager.\n" ); |
|
535 fprintf( stderr, "\tt4 - Component instance.\n" ); |
|
536 fprintf( stderr, "\tt6 - Client stub.\n" ); |
|
537 exit(1); |
|
538 } |
|
539 |
|
540 // print the header if appropriate |
|
541 if( command_line.client_flag || command_line.server_flag || command_line.header ) { |
|
542 h_output(command_line.infile, "-DRPC_HDR", EXTEND, ".h"); |
|
543 reinitialize(); |
|
544 } |
|
545 |
|
546 // output the xdr file if appropriate |
|
547 if( command_line.client_flag || command_line.server_flag ) { |
|
548 c_output(command_line.infile, "-DRPC_XDR", EXTEND, "_xdr.c"); |
|
549 reinitialize(); |
|
550 } |
|
551 |
|
552 // output the client files |
|
553 if( command_line.client_flag ) { |
|
554 l_output(command_line.infile, "-DRPC_CLNT", EXTEND, "_clnt.c"); |
|
555 reinitialize(); |
|
556 if( command_line.component_base_flag ) { |
|
557 ae_output_rpc_file( command_line.infile, ".h", TYPE_CLIENT_H ); |
|
558 reinitialize(); |
|
559 ae_output_rpc_file( command_line.infile, ".cpp", TYPE_CLIENT_C ); |
|
560 reinitialize(); |
|
561 } |
|
562 } |
|
563 |
|
564 // output the server files |
|
565 if( command_line.server_flag ) { |
|
566 s_output(allc, allv, command_line.infile, "-DRPC_SVC", EXTEND, "_svc.c", 0); |
|
567 reinitialize(); |
|
568 if( command_line.component_base_flag ) { |
|
569 ae_output_rpc_file( command_line.infile, "_svc_stub_impl.cpp", TYPE_SVC_STUB_IMPL ); |
|
570 reinitialize(); |
|
571 } |
|
572 if( command_line.component_mod_service_manager ) { |
|
573 ae_output_rpc_file( command_line.infile, ".cpp", TYPE_SVC_MGR_C ); |
|
574 reinitialize(); |
|
575 ae_output_rpc_file( command_line.infile, ".h", TYPE_SVC_MGR_H ); |
|
576 reinitialize(); |
|
577 } |
|
578 if( command_line.component_mod_component_impl ) { |
|
579 ae_output_rpc_file( command_line.infile, ".h", TYPE_INST_H ); |
|
580 reinitialize(); |
|
581 ae_output_rpc_file( command_line.infile, ".cpp", TYPE_INST_C ); |
|
582 reinitialize(); |
|
583 } |
|
584 } |
|
585 |
|
586 exit(0); |
|
587 } |