1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include "tcl.h"
32 #include "nfstcl4.h"
33
34 /* This variable is used to keep the path from argv[0] to find tclprocs. */
35 static char *buffer;
36
37 /*
38 * The following variable is a special hack that is needed in order for
39 * Sun shared libraries to be used for Tcl.
40 */
41
42 extern int main();
43 extern void nfs_initialize();
44
45 int *tclDummyMainPtr = (int *)main;
46 Tcl_Interp *interp;
47
48 /*
49 * -----------------------------------------------------------------
50 *
51 * main --
52 *
53 * This is the main program for the application.
54 *
55 * Results:
56 * None: Tcl_Main never returns here, so this procedure never
57 * returns either.
58 *
59 * Side effects:
60 * Whatever the application does.
61 *
62 * -----------------------------------------------------------------
63 */
64
65 int
66 main(argc, argv)
67 int argc; /* Number of command-line arguments. */
68 char **argv; /* Values of command-line arguments. */
69 {
70 extern char *optarg;
71 extern int optind,
72 optopt,
73 opterr;
74 char *tmp_ptr;
75 int c,
76 Vflg = 0,
77 errflg = 0;
78
79 opterr = 0;
80
81 #ifdef TCL_TEST
82 /*
83 * Pass the build time location of the tcl library
84 * (to find init.tcl)
85 */
86 Tcl_Obj *path;
87 path = Tcl_NewStringObj(TCL_BUILDTIME_LIBRARY, -1);
88 TclSetLibraryPath(Tcl_NewListObj(1, &path));
89
90 #endif
91
92 #ifdef TCL_XT_TEST
93 XtToolkitInitialize();
94 #endif
95
96 /* search for flags */
97 while ((c = getopt(argc, argv, "V")) != EOF)
98 switch (c) {
99 case 'V':
100 Vflg++;
101 break;
102 case '?':
103 errflg++;
104 break;
105 default:
106 break;
107 }
108
109 if (errflg) {
110 fprintf(stderr, "usage: %s [-V]\n", argv[0]);
111 exit(1);
112 }
113
114 if (Vflg)
115 #ifdef NFSH_VERS
116 printf("%s version %s\n", argv[0], NFSH_VERS);
117 #else
118 printf("%s version unknown.\n", argv[0]);
119 #endif
120
121 /* check for path information on argv[0], if so, use it for tclprocs */
122 #undef DEBUG_BUFFER
123 #ifdef DEBUG_BUFFER
124 printf("argv[0] = <%s>\n", argv[0]);
125 #endif /* DEBUG_BUFFER */
126 if (strchr(argv[0], '/') != NULL) {
127 /* store argv[0] path */
128 buffer = malloc(strlen(argv[0]) + 255);
129 strcpy(buffer, argv[0]);
130 tmp_ptr = strrchr(buffer, '/');
131 if (tmp_ptr == NULL)
132 buffer = NULL;
133 else {
134 ++tmp_ptr;
135 *tmp_ptr = '\0';
136 }
137 #ifdef DEBUG_BUFFER
138 printf("buffer = <%s>\n", buffer);
139 #endif /* DEBUG_BUFFER */
140 } else
141 buffer = NULL;
142
143 Tcl_Main(argc, argv, Tcl_AppInit);
144 return (0); /* Needed only to prevent compiler warning. */
145 }
146
147
148 /*
149 * -----------------------------------------------------------------
150 *
151 * Tcl_AppInit --
152 *
153 * This procedure performs application-specific initialization.
154 * Most applications, especially those that incorporate additional
155 * packages, will have their own version of this procedure.
156 *
157 * Results:
158 * Returns a standard Tcl completion code, and leaves an error
159 * message in the interp's result if an error occurs.
160 *
161 * Side effects:
162 * Depends on the startup script.
163 *
164 * -----------------------------------------------------------------
165 */
166
167 int
168 Tcl_AppInit(interp)
169 Tcl_Interp *interp; /* Interpreter for application. */
170 {
171 char *default_procs = "tclprocs";
172 char nfshvers[10];
173 int i;
174
175 if (Tcl_Init(interp) == TCL_ERROR) {
176 return (TCL_ERROR);
177 }
178
179 #ifdef TCL_TEST
180 #ifdef TCL_XT_TEST
181 if (Tclxttest_Init(interp) == TCL_ERROR) {
182 return (TCL_ERROR);
183 }
184 #endif
185 if (Tcltest_Init(interp) == TCL_ERROR) {
186 return (TCL_ERROR);
187 }
188
189 Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init,
190 (Tcl_PackageInitProc *) NULL);
191
192 if (TclObjTest_Init(interp) == TCL_ERROR) {
193 return (TCL_ERROR);
194 }
195
196 #ifdef TCL_THREADS
197 if (TclThread_Init(interp) == TCL_ERROR) {
198 return (TCL_ERROR);
199 }
200 #endif
201 if (Procbodytest_Init(interp) == TCL_ERROR) {
202 return (TCL_ERROR);
203 }
204
205 Tcl_StaticPackage(interp, "procbodytest", Procbodytest_Init,
206 Procbodytest_SafeInit);
207
208 #endif /* TCL_TEST */
209
210 /*
211 * Call the init procedures for included packages.
212 * Each call should look like this:
213 *
214 * if (Mod_Init(interp) == TCL_ERROR) {
215 * return (TCL_ERROR);
216 * }
217 *
218 * where "Mod" is the name of the module.
219 */
220
221 /*
222 * Call Tcl_CreateCommand for application-specific commands, if
223 * they weren't already created by the init procedures called above.
224 */
225
226 nfs_initialize(interp);
227
228 /*
229 * Specify a user-specific startup file to invoke if the
230 * application is run interactively. Typically the
231 * startup file is "~/.apprc" where "app" is the name of
232 * the application. If this line is deleted then no
233 * user-specific startup file will be run under any
234 * conditions.
235 */
236
237 Tcl_SetVar(interp, "tcl_rcFileName", "~/.tclshrc", TCL_GLOBAL_ONLY);
238
239 #ifdef NFSH_VERS
240 /*
241 * set the variable "nfsh_version" for the version number
242 * of the tool. It's value is defined by NFSH_VERS at
243 * compile time. If it is not set, "Unknown" will be printed.
244 */
245 sprintf(nfshvers, "%s", NFSH_VERS);
246 Tcl_SetVar(interp, "nfsh_version", nfshvers, TCL_GLOBAL_ONLY);
247 #else
248 Tcl_SetVar(interp, "nfsh_version", "Unknown", TCL_GLOBAL_ONLY);
249 #endif
250
251 /* check for path information stored in buffer. */
252 /* If so, use it for tclprocs. */
253 if (buffer == NULL) {
254 /* look under PATH */
255 #ifdef DEBUG_BUFFER
256 printf("default_procs = <%s>\n", default_procs);
257 #endif /* DEBUG_BUFFER */
258 if ((default_procs = find_file(default_procs, "PATH", ":"))
259 == NULL) {
260 interp->result = "cannot read [tclprocs].";
261 return (TCL_ERROR);
262 }
263 } else { /* use argv[0] path and append default_procs */
264 strcat(buffer, default_procs);
265 default_procs = buffer;
266 #ifdef DEBUG_BUFFER
267 printf("default_procs = <%s>\n", default_procs);
268 #endif /* DEBUG_BUFFER */
269 }
270
271 if (Tcl_EvalFile(interp, default_procs) == TCL_ERROR) {
272 interp->result = "unable to load [tclprocs].";
273 return (TCL_ERROR);
274 }
275
276 /* clear buffer */
277 if (buffer != NULL)
278 free(buffer);
279
280 return (TCL_OK);
281 }