/* * This removes all the bindings for the given objects. */ void cleanCDKObjectBindings (EObjectType cdktype, void *object) { CDKOBJS *obj = bindableObject (&cdktype, object); if (obj != 0 && obj->bindingList != 0) { unsigned x; for (x = 0; x < obj->bindingCount; x++) { (obj)->bindingList[x].bindFunction = 0; (obj)->bindingList[x].bindData = 0; } freeAndNull ((obj)->bindingList); } }
/****************************************************************************** * * _DtEnvCleanCacheSlot() * * Free up all memory associated with a cache slot for a targetHost. */ static void _DtEnvCleanCacheSlot( cacheForTargetHost *targetCache ) { int i; freeAndNull( targetCache->remoteHost ); targetCache->cacheHit = 1; freeAndNull( targetCache->mapListStr ); for ( i = 0; i < targetCache->mapListCnt; i++ ) { freeAndNull( targetCache->mapList[i] ); freeAndNull( targetCache->mapListDetails[i].localEnvVarCopy ); freeAndNull( targetCache->mapListDetails[i].mappedEnvVarPtr ); /* do not free .localEnvVarPtr - belongs to environ */ } freeAndNull( targetCache->mapList ); targetCache->mapListCnt = 0; }
/****************************************************************************** * * _DtEnvMapIt() * * Fill out a map cache for a single environment variable. */ static void _DtEnvMapIt( char *envVar, cachedEnvVar *envVarCache, char *targetHost) { char *separator, *tmpPtr, *tmpPtr2, swapout, *netpath; char *prePend, *postPend, *newPrePend; char **pathList; int availPathListSize, pathListCount, availEnvStrSize, len, tmpi, i; int considerMapping; _Xstrtokparams strtok_buf; /* * Information Layout: * * localEnvVarPtr = ptr to original "PATH=/users/foo:/users/bar" * localEnvVarCopy = copy of original "/users/foo:/users/bar" * mappedEnvVarPtr = mapped "PATH=/nfs/.../users/foo:/nfs/.../users/bar" */ if ( (envVarCache->localEnvVarPtr = getenv( envVar )) ) { envVarCache->localEnvVarCopy = strdup( envVarCache->localEnvVarPtr ); /* sneak back past "NAME=" portion. */ envVarCache->localEnvVarPtr -= strlen( envVar ) + 1; } else { /* * Nothing to map. Punt. */ envVarCache->localEnvVarCopy = (char *) NULL; envVarCache->localEnvVarPtr = (char *) NULL; return; } #ifdef _DTENV_SUPPORT_COMMA_SEPARATED /* * Pick between colon-separated and comma-separated host-qualified * mapping code. */ if ( !strcmp(envVar, "DTDATABASESEARCHPATH") ) { /* * comma-separated and host-qualified mapping. */ separator = ","; } else { /* * colon-separated mapping. */ separator = ":"; } #else separator = ":"; #endif /* _DTENV_SUPPORT_COMMA_SEPARATED */ /* * Break path list into elements */ availPathListSize = MALLOC_BUMP_SIZE; pathListCount = 0; pathList = (char **) malloc( sizeof(char *) * availPathListSize ); /* * Break up path list into an array of path elements. */ tmpPtr = strdup( envVarCache->localEnvVarCopy ); /* work copy */ while (1) { if (!pathListCount) tmpPtr2 = _XStrtok( tmpPtr, separator, strtok_buf ); else tmpPtr2 = _XStrtok( (char *) NULL, separator, strtok_buf ); if (tmpPtr2) { pathListCount++; if (pathListCount > availPathListSize) { availPathListSize += MALLOC_BUMP_SIZE; pathList = (char **) realloc( (char *) pathList, sizeof(char *) * availPathListSize ); } pathList[pathListCount-1] = strdup( tmpPtr2 ); } else { break; } } free( tmpPtr ); /* * Setup new "NAME=....." string. */ availEnvStrSize = strlen( envVar ) + 64; envVarCache->mappedEnvVarPtr = (char *) calloc( availEnvStrSize, sizeof(char) ); strcpy( envVarCache->mappedEnvVarPtr, envVar ); strcat( envVarCache->mappedEnvVarPtr, "=" ); /* * Start mapping each path element. */ for ( i = 0; i < pathListCount; i++ ) { prePend = pathList[i]; postPend = (char *) NULL; newPrePend = (char *) NULL; /* * Assume we need to map this path element. */ considerMapping = 1; #ifdef _DTENV_SUPPORT_COMMA_SEPARATED if ( !strcmp( separator, "," ) ) { if ( DtStrchr(prePend, ':' ) ) { /* * Host qualified elements in a comma separated list * will NOT be mapped. */ considerMapping = 0; } } #endif /* _DTENV_SUPPORT_COMMA_SEPARATED */ if (considerMapping) { /* * Tear apart and check for so called substitution characters. */ if (( tmpPtr = DtStrchr(prePend, '%') )) { /* * Temporarly shorten path up to substitution character. */ swapout = *tmpPtr; *tmpPtr = '\0'; /* * Move the dividing point back to a directory element. */ tmpPtr2 = DtStrrchr( prePend, '/' ); /* * Restore the send half of the string. */ *tmpPtr = swapout; if (tmpPtr2) { /* * Can do a split around the "/". * * Will have "<prePath>/" and "/<postPath>". */ postPend = strdup( tmpPtr2 ); *(tmpPtr2 + mblen(tmpPtr2, MB_CUR_MAX)) = '\0'; } } #ifdef DTENV_PERF_HOOK { int tpi; extern unsigned long stopwatch_tt_file_netfile; extern int stopwatch_repeat_rate; struct timeval start, stop; struct timezone junk; gettimeofday( &start, &junk ); for ( tpi = 0; tpi < stopwatch_repeat_rate-1; tpi++ ) { netpath = _DtEnv_tt_file_netfile( prePend ); if ( tt_ptr_error(netpath) == TT_OK ) ttfreeAndNull( netpath ); } netpath = _DtEnv_tt_file_netfile( prePend ); gettimeofday( &stop, &junk ); if (start.tv_usec > stop.tv_usec) { stop.tv_usec += 1000000; stop.tv_sec--; } stopwatch_tt_file_netfile += (stop.tv_usec - start.tv_usec); stopwatch_tt_file_netfile += (stop.tv_sec - start.tv_sec) * 1000000; } #else netpath = _DtEnv_tt_file_netfile( prePend ); #endif /* DTENV_PERF_HOOK */ if ( tt_ptr_error(netpath) != TT_OK ) { newPrePend = (char *) NULL; } else { #ifdef DTENV_PERF_HOOK { int tpi; extern unsigned long stopwatch_tt_netfile_file; extern int stopwatch_repeat_rate; struct timeval start, stop; struct timezone junk; gettimeofday( &start, &junk ); for ( tpi = 0; tpi < stopwatch_repeat_rate-1; tpi++ ) { newPrePend = _DtEnv_tt_host_netfile_file (targetHost, netpath); if ( tt_ptr_error(newPrePend) == TT_OK ) ttfreeAndNull( newPrePend ); } newPrePend = _DtEnv_tt_host_netfile_file (targetHost, netpath); gettimeofday( &stop, &junk ); if (start.tv_usec > stop.tv_usec) { stop.tv_usec += 1000000; stop.tv_sec--; } stopwatch_tt_netfile_file += (stop.tv_usec - start.tv_usec); stopwatch_tt_netfile_file += (stop.tv_sec - start.tv_sec) * 1000000; } #else newPrePend = _DtEnv_tt_host_netfile_file (targetHost, netpath); #endif /* DTENV_PERF_HOOK */ if ( tt_ptr_error(newPrePend) != TT_OK ) { newPrePend = (char *) NULL; } ttfreeAndNull( netpath ); } } /* * Calculate length of the new path element to the new path list. */ tmpi = strlen(envVarCache->mappedEnvVarPtr)+1; /* current list + ... */ if ( i != 0 ) tmpi += 1; /* separator */ if (newPrePend) tmpi += strlen(newPrePend); /* new prePend or ... */ else tmpi += strlen(prePend); /* ... old prePend */ if (postPend) tmpi += strlen(postPend); /* new postPend */ if ( tmpi > availEnvStrSize ) { /* * Grow new mappedEnvVar space. */ availEnvStrSize = tmpi + 64; envVarCache->mappedEnvVarPtr = (char *) realloc( (char *) envVarCache->mappedEnvVarPtr, availEnvStrSize ); } /* * Add the new path element. */ if ( i != 0 ) strcat( envVarCache->mappedEnvVarPtr, separator ); if (newPrePend) strcat( envVarCache->mappedEnvVarPtr, newPrePend ); else strcat( envVarCache->mappedEnvVarPtr, prePend ); if (postPend) strcat( envVarCache->mappedEnvVarPtr, postPend ); freeAndNull( prePend ); /* aka pathList[i] */ ttfreeAndNull( newPrePend ); freeAndNull( postPend ); } freeAndNull( pathList ); }
char *_DtEnv_tt_host_netfile_file( const char *host, const char *filename) { static int first_time = 1; static int fragListAvail = CACHE_FILEFRAG_SIZE_START; static int fragListCnt = 0; static cachedNetfileFrag *fragList; static int cacheGen = 0; static int hitIdxStart = 0; char *newfile; int hitval, hitIdx, i; cachedNetfileFrag *tmpCffP; char *tmpStr; int newCount = fragListCnt; _DtSvcProcessLock(); if (first_time) { fragList = (cachedNetfileFrag *) calloc( fragListAvail, sizeof(cachedNetfileFrag) ); first_time = 0; } /* * Take care of the obvious. */ if (!filename) { _DtSvcProcessUnlock(); return( (char *) NULL ); } if (!host) { /* * Return a tt_free-able un-mapped copy. */ tmpStr = tt_malloc( strlen(filename) + 1 ); strcpy( tmpStr, filename ); _DtSvcProcessUnlock(); return(tmpStr); } /* * Look for existing answer in cache. * * While at it, also look for least used entry just in case. */ if (fragListCnt) hitIdxStart = (hitIdxStart + 7) % fragListCnt; else hitIdxStart = 0; hitIdx = hitIdxStart; hitval = fragList[hitIdx].cacheHit; tmpCffP = fragList; /* walk rather than index */ for ( i = 0; i < fragListCnt; i++ ) { if (tmpCffP->cacheHit && !strcmp( filename, tmpCffP->pathFragOrig ) ) { if (!strcmp( host, tmpCffP->targetHost ) ) { break; } } /* * Save index of least used entry */ if (tmpCffP->cacheHit < hitval) { hitIdx = i; hitval = tmpCffP->cacheHit; } tmpCffP++; } /* * Decide what was found. */ if ( i != fragListCnt ) { /* * Found a cached entry. */ hitIdx = i; if ( fragList[hitIdx].cacheHit++ > CACHE_FILEFRAG_REMAP_AFTER ) { /* * This looks like an old entry, so re-compute it. */ freeAndNull( fragList[hitIdx].targetHost ); freeAndNull( fragList[hitIdx].pathFragOrig ); ttfreeAndNull( fragList[hitIdx].pathFragMapped ); fragList[hitIdx].cacheHit = 0; /* 0 means remap below */ } } else { /* * Did not find a cache entry, so scrounge around for * a new entry. */ if ( fragListCnt < fragListAvail ) { /* * Use next already-malloc'ed cacheEntry. */ hitIdx = fragListCnt; newCount = fragListCnt + 1; } else if ( fragListCnt < CACHE_FILEFRAG_SIZE_MAX ) { /* * Can grow fragList[] */ fragListAvail += CACHE_FILEFRAG_SIZE_BUMP; fragList = (cachedNetfileFrag *) realloc( (char *) fragList, sizeof(cachedNetfileFrag) * fragListAvail); /* * Zero out new memory. */ memset( fragList + (fragListAvail-CACHE_FILEFRAG_SIZE_BUMP), 0, CACHE_FILEFRAG_SIZE_BUMP*sizeof(cachedNetfileFrag) ); hitIdx = fragListCnt; newCount = fragListCnt + 1; } else { /* * Last resort - bump out the least used entry. */ freeAndNull( fragList[hitIdx].targetHost ); freeAndNull( fragList[hitIdx].pathFragOrig ); ttfreeAndNull( fragList[hitIdx].pathFragMapped ); /* * Since the cache is 100% full, ocassionally reset * everyone's cacheHit rate so entries that were only * popular long ago don't get locked in. */ if ( cacheGen++ > CACHE_FILEFRAG_RESET_PRI ) { cacheGen = 0; tmpCffP = fragList; for ( i = 0; i < fragListCnt; i++ ) { tmpCffP->cacheHit = 1; tmpCffP++; } } } fragList[hitIdx].cacheHit = 0; /* 0 means remap below */ } if ( ! fragList[hitIdx].cacheHit ) { /* * Need to perform mapping. */ newfile = tt_host_netfile_file( host, filename ); #ifdef _DTENV_SUPPORT_MAPERROR_CACHING fragList[hitIdx].targetHost = strdup ( host ); fragList[hitIdx].pathFragOrig = strdup( filename ); fragList[hitIdx].cacheHit = 1; fragList[hitIdx].pathFragMapped = newfile; fragListCnt = newCount; #else if ( tt_ptr_error(newfile) == TT_OK ) { fragList[hitIdx].targetHost = strdup ( host ); fragList[hitIdx].pathFragOrig = strdup( filename ); fragList[hitIdx].cacheHit = 1; fragList[hitIdx].pathFragMapped = newfile; /* * Only change the count if we are successful in adding * a new entry. */ fragListCnt = newCount; } else { /* * Don't cache errors. Leave this cache slot empty * and it will be rediscovered and used in the future. */ fragList[hitIdx].cacheHit = 0; /* * Do not change the fragListCount since we are not saving * error entries. */ } #endif /* _DTENV_SUPPORT_MAPERROR_CACHING */ } /* * Dig out answer and return it. */ #ifdef _DTENV_SUPPORT_MAPERROR_CACHING if ( tt_ptr_error(newfile) == TT_OK ) #else if ( fragList[hitIdx].cacheHit ) #endif /* _DTENV_SUPPORT_MAPERROR_CACHING */ { /* * Return a tt_free-able copy of the answer. */ tmpStr = tt_malloc( strlen(fragList[hitIdx].pathFragMapped) + 1 ); strcpy( tmpStr, fragList[hitIdx].pathFragMapped ); _DtSvcProcessUnlock(); return(tmpStr); } else { /* * See XXX comment. * * Since newfile is an error code, return as is. */ _DtSvcProcessUnlock(); return(newfile); } }