1 /*
2  * Copyright (c) 1996, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <process.h>
30 
31 /*
32  * This is a primitive bootstrapping utility for executing Java CGI
33  * programs, specifically Java RMI's CGI HTTP forwarding mechanism
34  *
35  * It executes the Java interpreter with options to define
36  * properties corresponding to the environment variables set by the
37  * CGI 1.0 specification and runs the target class.
38  *
39  * The following assumptions are made:
40  *     - the Java interpreter can be located by the system
41  *       PATH variable
42  *     - for RMI 1.1 prebeta release, the target class can be located
43  *       using the system CLASSPATH variable
44  */
45 
46 /* name of Java interpreter executable */
47 #define JAVA_NAME "java"
48 
49 /* name of Java class to execute with interpreter */
50 #define CLASS_NAME "sun.rmi.transport.proxy.CGIHandler"
51 
52 /* names of environment variables set in CGI 1.0 interface */
53 static char *var_names[] = {
54     "AUTH_TYPE",
55     "CONTENT_LENGTH",
56     "CONTENT_TYPE",
57     "GATEWAY_INTERFACE",
58     "HTTP_ACCEPT",
59     "PATH_INFO",
60     "PATH_TRANSLATED",
61     "QUERY_STRING",
62     "REMOTE_ADDR",
63     "REMOTE_HOST",
64     "REMOTE_IDENT",
65     "REMOTE_USER",
66     "REQUEST_METHOD",
67     "SCRIPT_NAME",
68     "SERVER_NAME",
69     "SERVER_PORT",
70     "SERVER_PROTOCOL",
71     "SERVER_SOFTWARE"
72 };
73 
74 #define NUM_VARS (sizeof(var_names) / sizeof(var_names[0]))
75 
76 /* file static functions */
77 static void server_error(char *);
78 
79 /*
80  * Program entry point: set up arguments and invoke Java interpreter.
81  */
82 int
main(int argc,char * argv[])83 main(
84     int     argc,
85     char   *argv[]
86 )
87 {
88     int     i;                  /* loop index variable */
89     char  **args;               /* array to store arguments to interpreter */
90     int     n = 0;              /* next index to fill in argument array */
91 
92     /* allocate space for argument list */
93     args = (char **)            /* allocate space for: */
94         malloc((1               /* executable name */
95                 + NUM_VARS      /* property definition for each variable */
96                 + 1             /* class name */
97                 + 1)            /* terminating NULL */
98                 * sizeof(*args));
99     if (args == NULL) {
100         server_error("memory allocation failure");
101         return 1;
102     }
103 
104     /* first argument: name of java interpreter */
105     args[n ++] = JAVA_NAME;
106 
107     /* next arguments: define CGI variables as properties to Java VM */
108     for (i = 0; i < NUM_VARS; ++ i) {
109         char *name = var_names[i];      /* name of variable */
110         char *value;                    /* value of variable */
111         char *buffer;                   /* buffer to store argument string */
112 
113         value = getenv(name);
114         if (value == NULL)              /* if variable undefined, */
115             value = "";                 /* use empty string */
116 
117         buffer = (char *)               /* allocate space for: */
118             malloc((2                   /* "-D" */
119                     + strlen(name)      /* variable name */
120                     + 2                 /* "=\"" */
121                     + strlen(value)     /* variable value */
122                     + 2)                /* "\"" and terminating '\0' */
123                     * sizeof(*buffer));
124         if (buffer == NULL) {
125             server_error("memory allocation failure");
126             return 1;
127         }
128 
129         /* construct property definition parameter */
130         sprintf(buffer, "-D%s=\"%s\"", name, value);
131 
132         args[n ++] = buffer;            /* add to argument list */
133     }
134 
135     /* last argument: name of class to execute */
136     args[n ++] = CLASS_NAME;
137 
138     args[n ++] = NULL;          /* terminate argument list */
139 
140     _execvp(JAVA_NAME, args);   /* execute java interpreter */
141 
142     /* if exec call returns, there was an error */
143     server_error("interpreter execution failure");
144     return 1;
145 }
146 
147 /*
148  * Return primitive error message to server because of some failure in
149  * this program.  (This could be embellished to an HTML formatted error
150  * message.)
151  */
152 static void
server_error(char * message)153 server_error(
154     char  *message
155 )
156 {
157     /*
158      * NOTE: CGI 1.0 spec uses "\n" (unlike "\r\n"
159      * for HTTP 1.0) for line termination
160      */
161     printf("Status: 500 Server Error: %s\n", message);
162     printf("Content-type: text/plain\n");
163     printf("\n");
164     printf("%s", message);
165 }
166