tclMacEnv.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:13k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* 
  2.  * tclMacEnv.c --
  3.  *
  4.  * Implements the "environment" on a Macintosh.
  5.  *
  6.  * Copyright (c) 1995-1996 Sun Microsystems, Inc.
  7.  *
  8.  * See the file "license.terms" for information on usage and redistribution
  9.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  *
  11.  * RCS: @(#) $Id: tclMacEnv.c,v 1.2 1998/09/14 18:40:04 stanton Exp $
  12.  */
  13. #include <Gestalt.h>
  14. #include <Folders.h>
  15. #include <TextUtils.h>
  16. #include <Resources.h>
  17. #include <string.h>
  18. #include "tcl.h"
  19. #include "tclInt.h"
  20. #include "tclMacInt.h"
  21. #include "tclPort.h"
  22. #define kMaxEnvStringSize  255
  23. #define kMaxEnvVarSize  100
  24. #define kLoginnameTag  "LOGIN="
  25. #define kUsernameTag  "USER="
  26. #define kDefaultDirTag  "HOME="
  27. /* 
  28.  * The following specifies a text file where additional environment variables 
  29.  * can be set.  The file must reside in the preferences folder.  If the file 
  30.  * doesn't exist NO error will occur.  Commet out the difinition if you do 
  31.  * NOT want to use an environment variables file. 
  32.  */
  33. #define kPrefsFile   "Tcl Environment Variables"
  34. /* 
  35.  * The following specifies the Name of a 'STR#' resource in the application 
  36.  * where additional environment variables may be set.  If the resource doesn't
  37.  * exist no errors will occur.  Commet it out if you don't want it.
  38.  */
  39. #define REZ_ENV "pTcl Environment Variables"
  40. /* Globals */
  41. char **environ = NULL;
  42. /*
  43.  * Declarations for local procedures defined in this file:
  44.  */
  45. static char ** RezRCVariables _ANSI_ARGS_((void));
  46. static char ** FileRCVariables _ANSI_ARGS_((void));
  47. static char ** PathVariables _ANSI_ARGS_((void));
  48. static char ** SystemVariables _ANSI_ARGS_((void));
  49. static char * MakeFolderEnvVar _ANSI_ARGS_((char * prefixTag,
  50. long whichFolder));
  51. static char * GetUserName _ANSI_ARGS_((void));
  52. /*
  53.  *----------------------------------------------------------------------
  54.  *
  55.  * RezRCVariables --
  56.  *
  57.  *  Creates environment variables from the applications resource fork.
  58.  *  The function looks for the 'STR#' resource with the name defined
  59.  *  in the #define REZ_ENV.  If the define is not defined this code
  60.  *  will not be included.  If the resource doesn't exist or no strings
  61.  *  reside in the resource nothing will happen.
  62.  *
  63.  * Results:
  64.  * ptr to value on success, NULL if error.
  65.  *
  66.  * Side effects:
  67.  * Memory is allocated and returned to the caller.
  68.  *
  69.  *----------------------------------------------------------------------
  70.  */
  71. #ifdef REZ_ENV
  72. static char ** 
  73. RezRCVariables()
  74. {
  75.     Handle envStrs = NULL;
  76.     char** rezEnv = NULL;
  77.     short int numStrs;
  78.     envStrs = GetNamedResource('STR#', REZ_ENV);
  79.     if (envStrs == NULL) return NULL;
  80.     numStrs = *((short *) (*envStrs));
  81.     rezEnv = (char **) ckalloc((numStrs + 1) * sizeof(char *));
  82.     if (envStrs != NULL) {
  83. ResType theType;
  84. Str255 theName;
  85. short theID, index = 1;
  86. int i = 0;
  87. char* string;
  88. GetResInfo(envStrs, &theID, &theType, theName);
  89. for(;;) {
  90.     GetIndString(theName, theID, index++);
  91.     if (theName[0] == '') break;
  92.     string = (char *) ckalloc(theName[0] + 2);
  93.     strncpy(string, (char *) theName + 1, theName[0]);
  94.     string[theName[0]] = '';
  95.     rezEnv[i++] = string;
  96. }
  97. ReleaseResource(envStrs);
  98. rezEnv[i] = NULL;
  99. return rezEnv;
  100.     }
  101.     return NULL;
  102. }
  103. #endif
  104. /*
  105.  *----------------------------------------------------------------------
  106.  *
  107.  * FileRCVariables --
  108.  *
  109.  *  Creates environment variables from a file in the system preferences
  110.  *  folder.  The function looks for a file in the preferences folder 
  111.  *  a name defined in the #define kPrefsFile.  If the define is not 
  112.  *  defined this code will not be included.  If the resource doesn't exist or
  113.  *  no strings reside in the resource nothing will happen.
  114.  *
  115.  * Results:
  116.  * ptr to value on success, NULL if error.
  117.  *
  118.  * Side effects:
  119.  * Memory is allocated and returned to the caller.
  120.  *
  121.  *----------------------------------------------------------------------
  122.  */
  123. #ifdef kPrefsFile
  124. static char ** 
  125. FileRCVariables()
  126. {
  127.     char *prefsFolder = NULL;
  128.     char *tempPtr = NULL;
  129.     char **fileEnv = NULL;
  130.     FILE *thePrefsFile = NULL;
  131.     int i;
  132.     FSSpec prefDir;
  133.     OSErr err;
  134.     Handle theString = NULL;
  135.     Tcl_Channel chan;
  136.     int size;
  137.     Tcl_DString lineRead;
  138.     err = FSpFindFolder(kOnSystemDisk, kPreferencesFolderType, 
  139.     kDontCreateFolder, &prefDir);
  140.     if (err != noErr) {
  141. return NULL;
  142.     }
  143.     err = FSpPathFromLocation(&prefDir, &size, &theString);
  144.     if (err != noErr) {
  145. return NULL;
  146.     }
  147.     (void) Munger(theString, size, NULL, 0, kPrefsFile, strlen(kPrefsFile));
  148.     HLock(theString);
  149.     chan = Tcl_OpenFileChannel(NULL, *theString, "r", 0);
  150.     HUnlock(theString);
  151.     DisposeHandle(theString);
  152.     if (chan == NULL) {
  153. return NULL;
  154.     }
  155.     /*
  156.      * We found a env file.  Let start parsing it.
  157.      */
  158.     fileEnv = (char **) ckalloc((kMaxEnvVarSize + 1) * sizeof(char *));
  159.     i = 0;
  160.     Tcl_DStringInit(&lineRead);
  161.     while (Tcl_Gets(chan, &lineRead) != -1) {
  162. /*
  163.  * First strip off new line char
  164.  */
  165. if (lineRead.string[lineRead.length-1] == 'n') {
  166.     lineRead.string[lineRead.length-1] = '';
  167. }
  168. if (lineRead.string[0] == '' || lineRead.string[0] == '#') {
  169.     /*
  170.      * skip empty lines or commented lines
  171.      */
  172.     Tcl_DStringSetLength(&lineRead, 0);
  173.     continue;
  174. }
  175. tempPtr = (char *) ckalloc(lineRead.length + 1);
  176. strcpy(tempPtr, lineRead.string);
  177. fileEnv[i++] = tempPtr;
  178. Tcl_DStringSetLength(&lineRead, 0);
  179.     }
  180.     fileEnv[i] = NULL;
  181.     Tcl_Close(NULL, chan);
  182.     Tcl_DStringFree(&lineRead);
  183.     return fileEnv;
  184. }
  185. #endif
  186. /*
  187.  *----------------------------------------------------------------------
  188.  *
  189.  * MakeFolderEnvVar --
  190.  *
  191.  * This function creates "environment" variable by taking a prefix and
  192.  * appending a folder path to a directory.  The directory is specified
  193.  * by a integer value acceptable by the FindFolder function.
  194.  *
  195.  * Results:
  196.  * The function returns an *allocated* string.  If the folder doesn't
  197.  * exist the return string is still allocated and just contains the
  198.  * given prefix.
  199.  *
  200.  * Side effects:
  201.  * Memory is allocated and returned to the caller.
  202.  *
  203.  *----------------------------------------------------------------------
  204.  */
  205. static char * 
  206. MakeFolderEnvVar(
  207.     char * prefixTag, /* Prefix added before result. */
  208.     long whichFolder) /* Constant for FSpFindFolder. */
  209. {
  210.     char * thePath = NULL;
  211.     char * result = NULL;
  212.     OSErr theErr = noErr;
  213.     Handle theString = NULL;
  214.     FSSpec theFolder;
  215.     int size;
  216.     Tcl_DString pathStr;
  217.     Tcl_DString tagPathStr;
  218.     
  219.     Tcl_DStringInit(&pathStr);
  220.     theErr = FSpFindFolder(kOnSystemDisk, whichFolder, 
  221.     kDontCreateFolder, &theFolder);
  222.     if (theErr == noErr) {
  223. theErr = FSpPathFromLocation(&theFolder, &size, &theString);
  224. HLock(theString);
  225. tclPlatform = TCL_PLATFORM_MAC;
  226. Tcl_DStringAppend(&pathStr, *theString, -1);
  227. HUnlock(theString);
  228. DisposeHandle(theString);
  229. Tcl_DStringInit(&tagPathStr);
  230. Tcl_DStringAppend(&tagPathStr, prefixTag, strlen(prefixTag));
  231. Tcl_DStringAppend(&tagPathStr, pathStr.string, pathStr.length);
  232. Tcl_DStringFree(&pathStr);
  233. /*
  234.  * Make sure the path ends with a ':'
  235.  */
  236. if (tagPathStr.string[tagPathStr.length - 1] != ':') {
  237.     Tcl_DStringAppend(&tagPathStr, ":", 1);
  238. }
  239. /*
  240.  * Don't free tagPathStr - rather make sure it's allocated
  241.  * and return it as the result.
  242.  */
  243. if (tagPathStr.string == tagPathStr.staticSpace) {
  244.     result = (char *) ckalloc(tagPathStr.length + 1);
  245.     strcpy(result, tagPathStr.string);
  246. } else {
  247.     result = tagPathStr.string;
  248. }
  249.     } else {
  250. result = (char *) ckalloc(strlen(prefixTag) + 1);
  251. strcpy(result, prefixTag);
  252.     }
  253.     return result;
  254. }
  255. /*
  256.  *----------------------------------------------------------------------
  257.  *
  258.  * PathVariables --
  259.  *
  260.  *  Creates environment variables from the system call FSpFindFolder.
  261.  *  The function generates environment variables for many of the 
  262.  *  commonly used paths on the Macintosh.
  263.  *
  264.  * Results:
  265.  * ptr to value on success, NULL if error.
  266.  *
  267.  * Side effects:
  268.  * Memory is allocated and returned to the caller.
  269.  *
  270.  *----------------------------------------------------------------------
  271.  */
  272. static char ** 
  273. PathVariables()
  274. {
  275.     int i = 0;
  276.     char **sysEnv;
  277.     char *thePath = NULL;
  278.     
  279.     sysEnv = (char **) ckalloc((12) * sizeof(char *));
  280.     sysEnv[i++] = MakeFolderEnvVar("PREF_FOLDER=", kPreferencesFolderType);
  281.     sysEnv[i++] = MakeFolderEnvVar("SYS_FOLDER=", kSystemFolderType);
  282.     sysEnv[i++] = MakeFolderEnvVar("TEMP=", kTemporaryFolderType);
  283.     sysEnv[i++] = MakeFolderEnvVar("APPLE_M_FOLDER=", kAppleMenuFolderType);
  284.     sysEnv[i++] = MakeFolderEnvVar("CP_FOLDER=", kControlPanelFolderType);
  285.     sysEnv[i++] = MakeFolderEnvVar("DESK_FOLDER=", kDesktopFolderType);
  286.     sysEnv[i++] = MakeFolderEnvVar("EXT_FOLDER=", kExtensionFolderType);
  287.     sysEnv[i++] = MakeFolderEnvVar("PRINT_MON_FOLDER=",
  288.     kPrintMonitorDocsFolderType);
  289.     sysEnv[i++] = MakeFolderEnvVar("SHARED_TRASH_FOLDER=",
  290.     kWhereToEmptyTrashFolderType);
  291.     sysEnv[i++] = MakeFolderEnvVar("TRASH_FOLDER=", kTrashFolderType);
  292.     sysEnv[i++] = MakeFolderEnvVar("START_UP_FOLDER=", kStartupFolderType);
  293.     sysEnv[i++] = NULL;
  294.     return sysEnv;
  295. }
  296. /*
  297.  *----------------------------------------------------------------------
  298.  *
  299.  * SystemVariables --
  300.  *
  301.  *  Creates environment variables from various Mac system calls.
  302.  *
  303.  * Results:
  304.  * ptr to value on success, NULL if error.
  305.  *
  306.  * Side effects:
  307.  * Memory is allocated and returned to the caller.
  308.  *
  309.  *----------------------------------------------------------------------
  310.  */
  311. static char ** 
  312. SystemVariables()
  313. {
  314.     int i = 0;
  315.     char ** sysEnv;
  316.     char * thePath = NULL;
  317.     Handle theString = NULL;
  318.     FSSpec currentDir;
  319.     int size;
  320.     
  321.     sysEnv = (char **) ckalloc((4) * sizeof(char *));
  322.     /*
  323.      * Get user name from chooser.  It will be assigned to both
  324.      * the USER and LOGIN environment variables.
  325.      */
  326.     thePath = GetUserName();
  327.     if (thePath != NULL) {
  328. sysEnv[i] = (char *) ckalloc(strlen(kLoginnameTag) + strlen(thePath) + 1);
  329. strcpy(sysEnv[i], kLoginnameTag);
  330. strcpy(sysEnv[i]+strlen(kLoginnameTag), thePath);
  331. i++;
  332. sysEnv[i] = (char *) ckalloc(strlen(kUsernameTag) + strlen(thePath) + 1);
  333. strcpy(sysEnv[i], kUsernameTag);
  334. strcpy(sysEnv[i]+strlen(kUsernameTag), thePath);
  335. i++;
  336.     }
  337.     /*
  338.      * Get 'home' directory
  339.      */
  340. #ifdef kDefaultDirTag
  341.     FSpGetDefaultDir(&currentDir);
  342.     FSpPathFromLocation(&currentDir, &size, &theString);
  343.     HLock(theString);
  344.     sysEnv[i] = (char *) ckalloc(strlen(kDefaultDirTag) + size + 4);
  345.     strcpy(sysEnv[i], kDefaultDirTag);
  346.     strncpy(sysEnv[i]+strlen(kDefaultDirTag) , *theString, size);
  347.     if (sysEnv[i][strlen(kDefaultDirTag) + size - 1] != ':') {
  348. sysEnv[i][strlen(kDefaultDirTag) + size] = ':';
  349. sysEnv[i][strlen(kDefaultDirTag) + size + 1] = '';
  350.     } else {
  351. sysEnv[i][strlen(kDefaultDirTag) + size] = '';
  352.     }
  353.     HUnlock(theString);
  354.     DisposeHandle(theString);
  355.     i++;
  356. #endif
  357.     sysEnv[i++] = NULL;
  358.     return sysEnv;
  359. }
  360. /*
  361.  *----------------------------------------------------------------------
  362.  *
  363.  * TclMacCreateEnv --
  364.  *
  365.  * This function allocates and populates the global "environ"
  366.  * variable.  Entries are in traditional Unix format but variables
  367.  * are, hopefully, a bit more relevant for the Macintosh.
  368.  *
  369.  * Results:
  370.  * The number of elements in the newly created environ array.
  371.  *
  372.  * Side effects:
  373.  * Memory is allocated and pointed too by the environ variable.
  374.  *
  375.  *----------------------------------------------------------------------
  376.  */
  377. int
  378. TclMacCreateEnv()
  379. {
  380.     char ** sysEnv = NULL;
  381.     char ** pathEnv = NULL;
  382.     char ** fileEnv = NULL;
  383.     char ** rezEnv = NULL;
  384.     int count = 0;
  385.     int i, j;
  386.     sysEnv = SystemVariables();
  387.     if (sysEnv != NULL) {
  388. for (i = 0; sysEnv[i] != NULL; count++, i++) {
  389.     /* Empty Loop */
  390. }
  391.     }
  392.     pathEnv = PathVariables();
  393.     if (pathEnv != NULL) {
  394. for (i = 0; pathEnv[i] != NULL; count++, i++) {
  395.     /* Empty Loop */
  396. }
  397.     }
  398. #ifdef kPrefsFile
  399.     fileEnv = FileRCVariables();
  400.     if (fileEnv != NULL) {
  401. for (i = 0; fileEnv[i] != NULL; count++, i++) {
  402.     /* Empty Loop */
  403. }
  404.     }
  405. #endif
  406. #ifdef REZ_ENV
  407.     rezEnv = RezRCVariables();
  408.     if (rezEnv != NULL) {
  409. for (i = 0; rezEnv[i] != NULL; count++, i++) {
  410.     /* Empty Loop */
  411. }
  412.     }
  413. #endif
  414.     /*
  415.      * Create environ variable
  416.      */
  417.     environ = (char **) ckalloc((count + 1) * sizeof(char *));
  418.     j = 0;
  419.     if (sysEnv != NULL) {
  420. for (i = 0; sysEnv[i] != NULL;)
  421.     environ[j++] = sysEnv[i++];
  422. ckfree((char *) sysEnv);
  423.     }
  424.     if (pathEnv != NULL) {
  425. for (i = 0; pathEnv[i] != NULL;)
  426.     environ[j++] = pathEnv[i++];
  427. ckfree((char *) pathEnv);
  428.     }
  429. #ifdef kPrefsFile
  430.     if (fileEnv != NULL) {
  431. for (i = 0; fileEnv[i] != NULL;)
  432.     environ[j++] = fileEnv[i++];
  433. ckfree((char *) fileEnv);
  434.     }
  435. #endif
  436. #ifdef REZ_ENV
  437.     if (rezEnv != NULL) {
  438. for (i = 0; rezEnv[i] != NULL;)
  439.     environ[j++] = rezEnv[i++];
  440. ckfree((char *) rezEnv);
  441.     }
  442. #endif
  443.     environ[j] = NULL;
  444.     return j;
  445. }
  446. /*
  447.  *----------------------------------------------------------------------
  448.  *
  449.  * GetUserName --
  450.  *
  451.  * Get the user login name.
  452.  *
  453.  * Results:
  454.  *  ptr to static string, NULL if error.
  455.  *
  456.  * Side effects:
  457.  * None.
  458.  *
  459.  *----------------------------------------------------------------------
  460.  */
  461. static char *
  462. GetUserName()
  463. {
  464.     static char buf[33];
  465.     short refnum;
  466.     Handle h;
  467.     refnum = CurResFile();
  468.     UseResFile(0);
  469.     h = GetResource('STR ', -16096);
  470.     UseResFile(refnum);
  471.     if (h == NULL) {
  472. return NULL;
  473.     }
  474.     
  475.     HLock(h);
  476.     strncpy(buf, (*h)+1, **h);
  477.     buf[**h] = '';
  478.     HUnlock(h);
  479.     ReleaseResource(h);
  480.     return(buf[0] ? buf : NULL);
  481. }