/***** ** ** Module Header ******************************************************* ** ** ** ** Modules Revision 3.0 ** ** Providing a flexible user environment ** ** ** ** File: ModuleCmd_Whatis.c ** ** First Edition: 95/12/31 ** ** ** ** Authors: Jens Hamisch, jens@Strawberry.COM ** ** ** ** ModuleCmd_Apropos ** ** ** ** Notes: ** ** ** ** ************************************************************************ ** ****/ /** ** Copyright *********************************************************** ** ** ** ** Copyright 1991-1994 by John L. Furlan. ** ** see LICENSE.GPL, which must be provided, for details ** ** ** ** ************************************************************************ **/ static char Id[] = "@(#)$Id: ModuleCmd_Whatis.c,v 1.2 2001/06/09 09:48:46 rkowen Exp $"; static void *UseId[] = { &UseId, Id }; /** ************************************************************************ **/ /** HEADERS **/ /** ************************************************************************ **/ #include "modules_def.h" /** ************************************************************************ **/ /** LOCAL DATATYPES **/ /** ************************************************************************ **/ /** not applicable **/ /** ************************************************************************ **/ /** CONSTANTS **/ /** ************************************************************************ **/ /** not applicable **/ /** ************************************************************************ **/ /** MACROS **/ /** ************************************************************************ **/ #define WHATIS_SOME 0 #define WHATIS_ALL 1 /** ************************************************************************ **/ /** LOCAL DATA **/ /** ************************************************************************ **/ static char module_name[] = "ModuleCmd_Whatis.c"; /** File name of this module **/ #if WITH_DEBUGGING_MODULECMD static char _proc_ModuleCmd_Whatis[] = "ModuleCmd_Whatis"; static char _proc_ModuleCmd_Apropos[] = "ModuleCmd_Apropos"; #endif #if WITH_DEBUGGING_UTIL_1 static char _proc_whatis_dir[] = "whatis_dir"; static char _proc_read_cache[] = "read_cache"; static char _proc_apropos_cache[] = "apropos_cache"; #endif static char cache_name[] = APR_CACHE; /** ************************************************************************ **/ /** PROTOTYPES **/ /** ************************************************************************ **/ static int read_cache( int, char**, FILE*, int); static int whatis_dir( char*, int, char**, FILE*, int); static char *apropos_cache(void); /*++++ ** ** Function-Header ***************************************************** ** ** ** ** Function: ModuleCmd_Whatis ** ** ** ** Description: Display the passed modules 'whatis' information ** ** ** ** First Edition: 95/12/31 ** ** ** ** Parameters: Tcl_Interp *interp Attached Tcl Interp. ** ** int argc Number of arguments ** ** char *argv[] Argument list ** ** ** ** Result: int TCL_ERROR Failure ** ** TCL_OK Successfull operation ** ** ** ** Attached Globals: g_flags These are set up accordingly before ** ** this function is called in order to ** ** control everything ** ** g_current_module The module which is handled ** ** by the current command ** ** ** ** ************************************************************************ ** ++++*/ int ModuleCmd_Whatis( Tcl_Interp *interp, int argc, char *argv[]) { struct stat stats; Tcl_Interp *whatis_interp; Tcl_DString cmdbuf; int i, result = TCL_OK, done = 0; char modulefile[ MOD_BUFSIZE]; char modulename[ MOD_BUFSIZE]; char *modpath; /** Buffer for the contents of the **/ /** environment variable MODULEPATH **/ char **wptr; char *dirname; char *cache_file; /** Name of the cache file **/ FILE *cachefp = (FILE *) NULL; /** Cache file pointer **/ #if WITH_DEBUGGING_MODULECMD ErrorLogger( NO_ERR_START, LOC, _proc_ModuleCmd_Whatis, NULL); #endif /** ** Initialize the command buffer and set up the modules flag to ** 'whatisonly' **/ Tcl_DStringInit( &cmdbuf); g_flags |= M_WHATIS; /** ** Handle each passed module file. Create a Tcl interpreter for each ** module file to be handled and initialize it with custom module commands **/ if ( argc) { /** ** User provided a list of modules for ``whatis'' info **/ for(i=0; i **/ } /** ** Check whether a cache file exists then list all the ``whatis'' info ** Otherwise read all module files ... **/ cache_file = apropos_cache(); if( !sw_create && cache_file && !stat( cache_file, &stats)) { /** ** Open the cache file **/ if((FILE *) NULL == (cachefp = fopen( cache_file, "r"))) { if( OK != ErrorLogger( ERR_OPEN, LOC, cache_file, NULL)) return( TCL_ERROR); /** ---- EXIT (FAILURE) ---> **/ } else { /** ** Read the cache and close the file **/ result = read_cache( argc, argv, cachefp, WHATIS_ALL); if( EOF == fclose( cachefp)) if( OK != ErrorLogger( ERR_CLOSE, LOC, cache_file, NULL)) return( TCL_ERROR); /** ---- EXIT (FAILURE) ---> **/ done = 1; } } /** ** If we're not done now, we have to scan the files **/ if( !done) { /** ** Open the cache file if neccessary **/ if( sw_create && cache_file) { if((FILE *) NULL == (cachefp = fopen( cache_file, "w"))) if( OK != ErrorLogger( ERR_OPEN, LOC, cache_file, NULL)) return( TCL_ERROR); /** ---- EXIT (FAILURE) ---> **/ } /** ** Tokenize the module path string and check all dirs **/ for( dirname = strtok( modpath, ":"); dirname; dirname = strtok( NULL, ":") ) { if( !check_dir( dirname)) continue; whatis_dir( dirname, argc, argv, cachefp, WHATIS_ALL); } /** for **/ /** ** Close the cache file **/ if( cachefp) if( EOF == fclose( cachefp)) if( OK != ErrorLogger( ERR_CLOSE, LOC, cache_file, NULL)) return( TCL_ERROR); /** ---- EXIT (FAILURE) ---> **/ } } /** ** Leave the 'whatis only mode', free up what has been used and return **/ g_flags &= ~M_WHATIS; fprintf( stderr, "\n"); Tcl_DStringFree( &cmdbuf); /** ** Free up allocated resources **/ free( modpath); /** ** Return on success **/ #if WITH_DEBUGGING_MODULECMD ErrorLogger( NO_ERR_END, LOC, _proc_ModuleCmd_Whatis, NULL); #endif return( result); } /** End of 'ModuleCmd_Whatis' **/ /*++++ ** ** Function-Header ***************************************************** ** ** ** ** Function: ModuleCmd_Apropos ** ** ** ** Description: Scan the whatis database in order to find something ** ** matching the passed strings ** ** ** ** First Edition: 95/12/31 ** ** ** ** Parameters: Tcl_Interp *interp Attached Tcl Interp. ** ** int argc Number of arguments ** ** char *argv[] Argument list ** ** ** ** Result: int TCL_ERROR Failure ** ** TCL_OK Successfull operation ** ** ** ** Attached Globals: ** ** ** ** ************************************************************************ ** ++++*/ int ModuleCmd_Apropos( Tcl_Interp *interp, int argc, char *argv[]) { struct stat stats; char *dirname; char *modpath; /** Buffer for the contents of the **/ /** environment variable MODULEPATH **/ int i, done = 0; char *c; char *cache_file; /** Name of the cache file **/ FILE *cachefp = (FILE *) NULL; /** Cache file pointer **/ #if WITH_DEBUGGING_MODULECMD ErrorLogger( NO_ERR_START, LOC, _proc_ModuleCmd_Apropos, NULL); #endif /** ** Ignore case ... convert all arguments to lower case **/ if( sw_icase) { for( i=0; i **/ } /** ** Check whether there's a cache file. If it is, grep for the tokens ** in this file. Otherwise read all module files ... **/ cache_file = apropos_cache(); if( !sw_create && cache_file && !stat( cache_file, &stats)) { /** ** Open the cache file **/ if((FILE *) NULL == (cachefp = fopen( cache_file, "r"))) { if( OK != ErrorLogger( ERR_OPEN, LOC, cache_file, NULL)) return( TCL_ERROR); /** ---- EXIT (FAILURE) ---> **/ } else { /** ** Read the cache and close the file **/ read_cache( argc, argv, cachefp, WHATIS_SOME); if( EOF == fclose( cachefp)) if( OK != ErrorLogger( ERR_CLOSE, LOC, cache_file, NULL)) return( TCL_ERROR); /** ---- EXIT (FAILURE) ---> **/ done = 1; } } /** ** If we're not done now, we have to scan the files **/ if( !done) { /** ** Open the cache file if neccessary **/ if( sw_create && cache_file) { if((FILE *) NULL == (cachefp = fopen( cache_file, "w"))) if( OK != ErrorLogger( ERR_OPEN, LOC, cache_file, NULL)) return( TCL_ERROR); /** ---- EXIT (FAILURE) ---> **/ } /** ** Tokenize the module path string and check all dirs **/ for( dirname = strtok( modpath, ":"); dirname; dirname = strtok( NULL, ":") ) { if( !check_dir( dirname)) continue; whatis_dir( dirname, argc, argv, cachefp, WHATIS_SOME); } /** for **/ /** ** Close the cache file **/ if( cachefp) if( EOF == fclose( cachefp)) if( OK != ErrorLogger( ERR_CLOSE, LOC, cache_file, NULL)) return( TCL_ERROR); /** ---- EXIT (FAILURE) ---> **/ } /** ** Free up what has been allocated and exit from this procedure **/ free( modpath); #if WITH_DEBUGGING_MODULECMD ErrorLogger( NO_ERR_END, LOC, _proc_ModuleCmd_Apropos, NULL); #endif return( TCL_OK); } /** End of 'ModuleCmd_Apropos' **/ /*++++ ** ** Function-Header ***************************************************** ** ** ** ** Function: whatis_dir ** ** ** ** Description: Print all files beyond the passed directory ** ** ** ** First Edition: 91/10/23 ** ** ** ** Parameters: char *dir Directory to be scanned ** ** int argc Number of tokens ** ** char **argv List of tokens to check ** ** FILE *cfp Cache file pointer ** ** ** ** Result: int TCL_OK Successfull operation ** ** ** ** Attached Globals: g_flags These are set up accordingly before ** ** this function is called in order to ** ** control everything ** ** g_current_module The module which is handled ** ** by the current command ** ** ** ** ************************************************************************ ** ++++*/ static int whatis_dir( char *dir, int argc, char **argv, FILE *cfp, int whatis_list) { fi_ent *dirlst_head = NULL; /** Directory list base pointer **/ int count = 0; /** Number of elements in the top **/ /** level directory list **/ int tcount = 0; /** Total number of files to print **/ char **list; /** flat list of module files **/ int start = 0, i, k; int result = TCL_OK; Tcl_Interp *whatis_interp; Tcl_DString cmdbuf; char modulefile[ MOD_BUFSIZE]; char **wptr, *c; struct stat stats; #if WITH_DEBUGGING_UTIL_1 ErrorLogger( NO_ERR_START, LOC, _proc_whatis_dir, "dir='", dir, NULL); #endif /** ** Normal reading of the files **/ if( NULL == (dirlst_head = get_dir( dir, NULL, &count, &tcount))) if( OK != ErrorLogger( ERR_READDIR, LOC, dir, NULL)) return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ if( NULL == (list = (char**) malloc( tcount * sizeof( char**)))) if( OK != ErrorLogger( ERR_ALLOC, LOC, NULL)) return( TCL_ERROR); /** ------- EXIT (FAILURE) --------> **/ dirlst_to_list( list, dirlst_head, count, &start, NULL, NULL); /** ** Initialize the command buffer and set up the modules flag to 'whatislay ** only' **/ Tcl_DStringInit( &cmdbuf); g_flags |= M_WHATIS; /** ** Check all the files in the flat list for the passed tokens **/ for( i=0; i --> INSTPATH/etc/ ** / --> /RC_FILE ** / --> / **/ if( env = getenv( "MODULEWHATISCACHE")) { if((char *) NULL == (env_file = strrchr( env, '/'))) { env_file = env; env_path = instpath; } else { *env_file++ = '\0'; env_path = env; } if( !*env_file) env_file = cache_name; } else { env_path = instpath; env_file = cache_name; } /** ** Finaly we have to change INSTPATH -> INSTPATH/etc **/ if( env_path == instpath) { /* sprintf( buffer, "%s/etc/%s", env_path, env_file); */ strcpy( buffer, env_path); strcat( buffer, "/etc/"); strcat( buffer, env_file); } else { /* sprintf( buffer, "%s/%s", env_path, env_file); */ strcpy( buffer, env_path); strcat( buffer, "/"); strcat( buffer, env_file); } /** ** Return the name of the cache file **/ #if WITH_DEBUGGING_UTIL_1 ErrorLogger( NO_ERR_END, LOC, _proc_apropos_cache, NULL); #endif return( buffer); } /** End of 'apropos_cache' **/