home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / SATAN11.ZIP / SRC / RPCGEN / RPC_MAIN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-08  |  9.5 KB  |  446 lines

  1. /* @(#)rpc_main.c    2.2 88/08/01 4.0 RPCSRC */
  2. /*
  3.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  4.  * unrestricted use provided that this legend is included on all tape
  5.  * media and as a part of the software program in whole or part.  Users
  6.  * may copy or modify Sun RPC without charge, but are not authorized
  7.  * to license or distribute it to anyone else except as part of a product or
  8.  * program developed by the user.
  9.  * 
  10.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  11.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  12.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  13.  * 
  14.  * Sun RPC is provided with no support and without any obligation on the
  15.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  16.  * modification or enhancement.
  17.  * 
  18.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  19.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  20.  * OR ANY PART THEREOF.
  21.  * 
  22.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  23.  * or profits or other special, indirect and consequential damages, even if
  24.  * Sun has been advised of the possibility of such damages.
  25.  * 
  26.  * Sun Microsystems, Inc.
  27.  * 2550 Garcia Avenue
  28.  * Mountain View, California  94043
  29.  */
  30. #ifndef lint
  31. static char sccsid[] = "@(#)rpc_main.c 1.7 87/06/24 (C) 1987 SMI";
  32. #endif
  33.  
  34. /*
  35.  * rpc_main.c, Top level of the RPC protocol compiler. 
  36.  * Copyright (C) 1987, Sun Microsystems, Inc. 
  37.  */
  38.  
  39. #include <stdio.h>
  40. #include <string.h>
  41. #include <stdlib.h>
  42. #include <unistd.h>
  43. #include <sys/file.h>
  44. #include "rpc_util.h"
  45. #include "rpc_parse.h"
  46. #include "rpc_scan.h"
  47.  
  48. #define EXTEND    1        /* alias for TRUE */
  49.  
  50. struct commandline {
  51.     int cflag;
  52.     int hflag;
  53.     int lflag;
  54.     int sflag;
  55.     int mflag;
  56.     char *infile;
  57.     char *outfile;
  58. };
  59.  
  60. static char *cmdname;
  61. static char CPP[] = "cc";
  62. #define CPPFLAGS "-C", "-E"
  63. static char *allv[] = {
  64.     "rpcgen", "-s", "udp", "-s", "tcp",
  65. };
  66. static int allc = sizeof(allv)/sizeof(allv[0]);
  67.  
  68. static c_output();
  69. static h_output();
  70. static s_output();
  71. static l_output();
  72. static do_registers();
  73. static parseargs();
  74.  
  75. main(argc, argv)
  76.     int argc;
  77.     char *argv[];
  78.  
  79. {
  80.     struct commandline cmd;
  81.  
  82.     if (!parseargs(argc, argv, &cmd)) {
  83.         f_print(stderr,
  84.             "usage: %s infile\n", cmdname);
  85.         f_print(stderr,
  86.             "       %s [-c | -h | -l | -m] [-o outfile] [infile]\n",
  87.             cmdname);
  88.         f_print(stderr,
  89.             "       %s [-s udp|tcp]* [-o outfile] [infile]\n",
  90.             cmdname);
  91.         exit(1);
  92.     }
  93.     if (cmd.cflag) {
  94.         c_output(cmd.infile, "-DRPC_XDR", !EXTEND, cmd.outfile);
  95.     } else if (cmd.hflag) {
  96.         h_output(cmd.infile, "-DRPC_HDR", !EXTEND, cmd.outfile);
  97.     } else if (cmd.lflag) {
  98.         l_output(cmd.infile, "-DRPC_CLNT", !EXTEND, cmd.outfile);
  99.     } else if (cmd.sflag || cmd.mflag) {
  100.         s_output(argc, argv, cmd.infile, "-DRPC_SVC", !EXTEND,
  101.              cmd.outfile, cmd.mflag);
  102.     } else {
  103.         c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c");
  104.         reinitialize();
  105.         h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h");
  106.         reinitialize();
  107.         l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c");
  108.         reinitialize();
  109.         s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND,
  110.              "_svc.c", cmd.mflag);
  111.     }
  112.     exit(0);
  113. }
  114.  
  115. /*
  116.  * add extension to filename 
  117.  */
  118. static char *
  119. extendfile(file, ext)
  120.     char *file;
  121.     char *ext;
  122. {
  123.     char *res;
  124.     char *p;
  125.  
  126.     res = alloc(strlen(file) + strlen(ext) + 1);
  127.     if (res == NULL) {
  128.         abort();
  129.     }
  130.     p = strchr(file, '.');
  131.     if (p == NULL) {
  132.         p = file + strlen(file);
  133.     }
  134.     (void) strcpy(res, file);
  135.     (void) strcpy(res + (p - file), ext);
  136.     return (res);
  137. }
  138.  
  139. /*
  140.  * Open output file with given extension 
  141.  */
  142. static
  143. open_output(infile, outfile)
  144.     char *infile;
  145.     char *outfile;
  146. {
  147.     if (outfile == NULL) {
  148.         fout = stdout;
  149.         return;
  150.     }
  151.     if (infile != NULL && streq(outfile, infile)) {
  152.         f_print(stderr, "%s: output would overwrite %s\n", cmdname,
  153.             infile);
  154.         crash();
  155.     }
  156.     fout = fopen(outfile, "w");
  157.     if (fout == NULL) {
  158.         f_print(stderr, "%s: unable to open ", cmdname);
  159.         perror(outfile);
  160.         crash();
  161.     }
  162.     record_open(outfile);
  163. }
  164.  
  165. /*
  166.  * Open input file with given define for C-preprocessor 
  167.  */
  168. static
  169. open_input(infile, define)
  170.     char *infile;
  171.     char *define;
  172. {
  173.     int pd[2];
  174.  
  175.     infilename = (infile == NULL) ? "<stdin>" : infile;
  176.     (void) pipe(pd);
  177.     switch (fork()) {
  178.     case 0:
  179.         (void) close(1);
  180.         (void) dup2(pd[1], 1);
  181.         (void) close(pd[0]);
  182.         execlp(CPP, CPP, CPPFLAGS, define, infile, NULL);
  183.         perror("execlp");
  184.         exit(1);
  185.     case -1:
  186.         perror("fork");
  187.         exit(1);
  188.     }
  189.     (void) close(pd[1]);
  190.     fin = fdopen(pd[0], "r");
  191.     if (fin == NULL) {
  192.         f_print(stderr, "%s: ", cmdname);
  193.         perror(infilename);
  194.         crash();
  195.     }
  196. }
  197.  
  198. /*
  199.  * Compile into an XDR routine output file
  200.  */
  201. static
  202. c_output(infile, define, extend, outfile)
  203.     char *infile;
  204.     char *define;
  205.     int extend;
  206.     char *outfile;
  207. {
  208.     definition *def;
  209.     char *include;
  210.     char *outfilename;
  211.     long tell;
  212.  
  213.     open_input(infile, define);    
  214.     outfilename = extend ? extendfile(infile, outfile) : outfile;
  215.     open_output(infile, outfilename);
  216.     f_print(fout, "#include <sys/time.h>\n");
  217.     f_print(fout, "#include <rpc/rpc.h>\n");
  218.     if (infile && (include = extendfile(infile, ".h"))) {
  219.         f_print(fout, "#include \"%s\"\n", include);
  220.         free(include);
  221.     }
  222.     tell = ftell(fout);
  223.     while (def = get_definition()) {
  224.         emit(def);
  225.     }
  226.     if (extend && tell == ftell(fout)) {
  227.         (void) unlink(outfilename);
  228.     }
  229. }
  230.  
  231. /*
  232.  * Compile into an XDR header file
  233.  */
  234. static
  235. h_output(infile, define, extend, outfile)
  236.     char *infile;
  237.     char *define;
  238.     int extend;
  239.     char *outfile;
  240. {
  241.     definition *def;
  242.     char *outfilename;
  243.     long tell;
  244.  
  245.     open_input(infile, define);
  246.     outfilename =  extend ? extendfile(infile, outfile) : outfile;
  247.     open_output(infile, outfilename);
  248.     tell = ftell(fout);
  249.     while (def = get_definition()) {
  250.         print_datadef(def);
  251.     }
  252.     if (extend && tell == ftell(fout)) {
  253.         (void) unlink(outfilename);
  254.     }
  255. }
  256.  
  257. /*
  258.  * Compile into an RPC service
  259.  */
  260. static
  261. s_output(argc, argv, infile, define, extend, outfile, nomain)
  262.     int argc;
  263.     char *argv[];
  264.     char *infile;
  265.     char *define;
  266.     int extend;
  267.     char *outfile;
  268.     int nomain;
  269. {
  270.     char *include;
  271.     definition *def;
  272.     int foundprogram;
  273.     char *outfilename;
  274.  
  275.     open_input(infile, define);
  276.     outfilename = extend ? extendfile(infile, outfile) : outfile;
  277.     open_output(infile, outfilename);
  278.     f_print(fout, "#include <stdio.h>\n");
  279.     f_print(fout, "#include <sys/time.h>\n");
  280.     f_print(fout, "#include <rpc/rpc.h>\n");
  281.     if (infile && (include = extendfile(infile, ".h"))) {
  282.         f_print(fout, "#include \"%s\"\n", include);
  283.         free(include);
  284.     }
  285.     foundprogram = 0;
  286.     while (def = get_definition()) {
  287.         foundprogram |= (def->def_kind == DEF_PROGRAM);
  288.     }
  289.     if (extend && !foundprogram) {
  290.         (void) unlink(outfilename);
  291.         return;
  292.     }
  293.     if (nomain) {
  294.         write_programs((char *)NULL);
  295.     } else {
  296.         write_most();
  297.         do_registers(argc, argv);
  298.         write_rest();
  299.         write_programs("static");
  300.     }
  301. }
  302.  
  303. static
  304. l_output(infile, define, extend, outfile)
  305.     char *infile;
  306.     char *define;
  307.     int extend;
  308.     char *outfile;
  309. {
  310.     char *include;
  311.     definition *def;
  312.     int foundprogram;
  313.     char *outfilename;
  314.  
  315.     open_input(infile, define);
  316.     outfilename = extend ? extendfile(infile, outfile) : outfile;
  317.     open_output(infile, outfilename);
  318.     f_print(fout, "#include <sys/time.h>\n");
  319.     f_print(fout, "#include <rpc/rpc.h>\n");
  320.     if (infile && (include = extendfile(infile, ".h"))) {
  321.         f_print(fout, "#include \"%s\"\n", include);
  322.         free(include);
  323.     }
  324.     foundprogram = 0;
  325.     while (def = get_definition()) {
  326.         foundprogram |= (def->def_kind == DEF_PROGRAM);
  327.     }
  328.     if (extend && !foundprogram) {
  329.         (void) unlink(outfilename);
  330.         return;
  331.     }
  332.     write_stubs();
  333. }
  334.  
  335. /*
  336.  * Perform registrations for service output 
  337.  */
  338. static
  339. do_registers(argc, argv)
  340.     int argc;
  341.     char *argv[];
  342.  
  343. {
  344.     int i;
  345.  
  346.     for (i = 1; i < argc; i++) {
  347.         if (streq(argv[i], "-s")) {
  348.             write_register(argv[i + 1]);
  349.             i++;
  350.         }
  351.     }
  352. }
  353.  
  354. /*
  355.  * Parse command line arguments 
  356.  */
  357. static
  358. parseargs(argc, argv, cmd)
  359.     int argc;
  360.     char *argv[];
  361.     struct commandline *cmd;
  362.  
  363. {
  364.     int i;
  365.     int j;
  366.     char c;
  367.     char flag[(1 << 8 * sizeof(char))];
  368.     int nflags;
  369.  
  370.     cmdname = argv[0];
  371.     cmd->infile = cmd->outfile = NULL;
  372.     if (argc < 2) {
  373.         return (0);
  374.     }
  375.     flag['c'] = 0;
  376.     flag['h'] = 0;
  377.     flag['s'] = 0;
  378.     flag['o'] = 0;
  379.     flag['l'] = 0;
  380.     flag['m'] = 0;
  381.     for (i = 1; i < argc; i++) {
  382.         if (argv[i][0] != '-') {
  383.             if (cmd->infile) {
  384.                 return (0);
  385.             }
  386.             cmd->infile = argv[i];
  387.         } else {
  388.             for (j = 1; argv[i][j] != 0; j++) {
  389.                 c = argv[i][j];
  390.                 switch (c) {
  391.                 case 'c':
  392.                 case 'h':
  393.                 case 'l':
  394.                 case 'm':
  395.                     if (flag[c]) {
  396.                         return (0);
  397.                     }
  398.                     flag[c] = 1;
  399.                     break;
  400.                 case 'o':
  401.                 case 's':
  402.                     if (argv[i][j - 1] != '-' || 
  403.                         argv[i][j + 1] != 0) {
  404.                         return (0);
  405.                     }
  406.                     flag[c] = 1;
  407.                     if (++i == argc) {
  408.                         return (0);
  409.                     }
  410.                     if (c == 's') {
  411.                         if (!streq(argv[i], "udp") &&
  412.                             !streq(argv[i], "tcp")) {
  413.                             return (0);
  414.                         }
  415.                     } else if (c == 'o') {
  416.                         if (cmd->outfile) {
  417.                             return (0);
  418.                         }
  419.                         cmd->outfile = argv[i];
  420.                     }
  421.                     goto nextarg;
  422.  
  423.                 default:
  424.                     return (0);
  425.                 }
  426.             }
  427.     nextarg:
  428.             ;
  429.         }
  430.     }
  431.     cmd->cflag = flag['c'];
  432.     cmd->hflag = flag['h'];
  433.     cmd->sflag = flag['s'];
  434.     cmd->lflag = flag['l'];
  435.     cmd->mflag = flag['m'];
  436.     nflags = cmd->cflag + cmd->hflag + cmd->sflag + cmd->lflag + cmd->mflag;
  437.     if (nflags == 0) {
  438.         if (cmd->outfile != NULL || cmd->infile == NULL) {
  439.             return (0);
  440.         }
  441.     } else if (nflags > 1) {
  442.         return (0);
  443.     }
  444.     return (1);
  445. }
  446.