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 }