/************************************************************************/ /* Copyright (C) 2004 Michael C. Shultz */ /* */ /* This program is free software; you can redistribute it and/or modify */ /* it under the terms of the GNU General Public License as published by */ /* the Free Software Foundation; either version 2 of the License, or (at*/ /* your option) any later version. */ /* */ /* This program is distributed in the hope that it will be useful, */ /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ /* GNU General Public License for more details. */ /* */ /* You should have received a copy of the GNU General Public License */ /* along with this program; if not, write to the Free Software */ /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA */ /* 02111-1307, USA. */ /* */ /* Michael C. Shultz */ /* ringworm@inbox.lv */ /* Box 3238 Landers, CA 92285 */ /************************************************************************/ /* (c/w)s2.1.1.1 build a cache database containing the name of each portname looked up, and the date, time and size of the Makefile. Get the available name of the installed port from the cache if the Makefile's time,date, size still match those in the cache. If they don't match update the cache record. The initial cache db should be created by an "ifFileExists command that returns false, then the cache db is touched. ( C/W) 2.1.1.2 When having to run make describe currently the output is sent to a temp file, then read from the temp file into a Buffer. Change this so that the Buffer is filled directly from popen'ing "make describe" instead of system( "make describe > tempfile" ). This will probably be just a minor speed up, but is a much better way to program. */ /* available = PMGRrMakeDescribe( portI.array[recIdxPortI][PORTNAME_F1] ); */ #include "PMGRrMakeDescribe.h" #define PORTDIR_F0 0 #define PORTNAME_F1 1 #define MAKEFILESIZE_F2 2 #define MAKEFILETIME_F4 4 #define CACHE_TMP_2_DB "mv"" "DATADIR"portCache.tmp "DATADIR PORTS_CACHE_DB /*globals */ MGsDb portCache; /* protos */ char* rGetFromMakeDescribe( char* ); int rPurgeCacheRecord( char*, char*, char*, char* ); MGsDb config_db; char config_db_file[] = DATADIR"configure.db"; char* PMGRrMakeDescribe( char* installedPortDir ) { FILE* cacheStream = NULL; FILE* cacheTempStream = NULL; char cachFileName[] = DATADIR PORTS_CACHE_DB; char id[] = "PMGRrMakeDescribe"; char* Buffer = NULL; char* Makefile = NULL; char* MakefileSize = NULL; char* MakefileSizeTemp = NULL; char* MakefileTime = NULL; char* MakefileTimeTemp = NULL; int cacheIdx = 0; int errorCode = 0; unsigned int MakefileSizeInt = 0; MGmDbArray( config_db, config_db_file, "r" ); if( !( MGrIfFileExist( cachFileName ) ) ) { fprintf( stdout, "%s message: Creating %s%s\n", id, DATADIR, PORTS_CACHE_DB ); fflush( stdout ); cacheStream = fopen( cachFileName, "w" ); /* 0 = dir 1 = available name 2 = makefile size 3 = makefile date 4 = makefile time */ fprintf( cacheStream, "%s%c%s%c%s%c%s%c%s%c\n", "dir", 0, "available name", 0, "makefile size", 0, "makefile date", 0, "makefile time", 0 ); fclose( cacheStream ); } /************************/ /* check cach db */ /************************/ MakefileSizeInt = strlen( PORTSDIR ) + strlen( installedPortDir ) + strlen( "/Makefile" ) + 1; Makefile = ( char* )malloc( MakefileSizeInt ); strncpy( Makefile, PORTSDIR, strlen(PORTSDIR)+1 ); strncat( Makefile, installedPortDir, strlen(installedPortDir)+1 ); strncat( Makefile, "/Makefile", strlen("/Makefile")+1 ); MakefileSizeTemp = MGrIntToString( MGrFileSize( Makefile ) ); MakefileSize = ( char* )malloc( strlen( MakefileSizeTemp ) + 1 ); MakefileTimeTemp = MGrIntToString( (int)MGrFileTime( Makefile ) ); MakefileTime = ( char* )malloc( strlen( MakefileTimeTemp ) + 1 ); strncpy( MakefileSize, MakefileSizeTemp, strlen(MakefileSizeTemp)+1 ); strncpy( MakefileTime, MakefileTimeTemp, strlen(MakefileTimeTemp)+1 ); MGmDbArray( portCache, cachFileName, "r+" ); if( errno ) { fprintf( stderr, "%s error: MGmDbArray returned with an error\n", id ); return( NULL ); } cacheIdx = 0; while( cacheIdx < portCache.recordQty ) { if( strcmp( installedPortDir, portCache.array[cacheIdx][PORTDIR_F0] ) == 0 ) { if( strcmp( MakefileSize, portCache.array[cacheIdx][MAKEFILESIZE_F2] ) == 0 ) { if( strcmp( MakefileTime, portCache.array[cacheIdx][MAKEFILETIME_F4] ) == 0 ) { Buffer = (char* )malloc( strlen( portCache.array[cacheIdx][PORTNAME_F1] ) + 1 ); strncpy( Buffer, portCache.array[cacheIdx][PORTNAME_F1], strlen(portCache.array[cacheIdx][PORTNAME_F1])+1 ); MGmDbArrayFree( portCache ); free( MakefileSize ); free( MakefileTime ); free( Makefile ); return( Buffer ); } else { /* if here then Makefile time is wrong */ errorCode = rPurgeCacheRecord( portCache.array[0][0], /* start of buffer */ portCache.array[cacheIdx][0], /* point in buffer just before current record */ portCache.array[cacheIdx+1][0], /* point just past current record */ portCache.buffer + portCache.eof ); /* end of buffer */ if( errorCode ) { return( NULL ); } cacheIdx = portCache.recordQty; } } else { /* if here, then there is a record, but the makefile size is wrong, for now this record will always be a cache miss, someday when I can do record updates, this should be fixed to insert the new port name int portCache.array[cacheIdx][PORTNAME_F1]. Probably I can to this easily with MGrInStringSwap */ /* I think merely removing the record from portCache.db will be sufficient, then let the cache miss section rewite a corrected record. */ errorCode = rPurgeCacheRecord( portCache.array[0][0], /* start of buffer */ portCache.array[cacheIdx][0], /* point in buffer just before current record */ portCache.array[cacheIdx+1][0], /* point just past current record */ portCache.buffer + portCache.eof ); /* end of buffer */ cacheIdx = portCache.recordQty; } } cacheIdx++; } fprintf( stdout, "(Cache miss)" ); fflush( stdout ); if( !( Buffer = rGetFromMakeDescribe( installedPortDir ) ) ) { fprintf( stderr, "%s error: rGetFromMakeDescribe returned NULL\n", id ); fflush( stderr ); free( Makefile ); free( MakefileSize ); free( MakefileTime ); MGmDbArrayFree(config_db); return( NULL ); } /************************/ /* cache miss */ /************************/ cacheTempStream = fopen( DATADIR"portCache.tmp", "w" ); fwrite( portCache.buffer, portCache.eof, 1, cacheTempStream ); fprintf( cacheTempStream, "%s%c%s%c%s%c%s%c%s%c\n", installedPortDir, 0, Buffer, 0, MakefileSize, 0, "makefile date", 0, MakefileTime, 0 ); fflush( cacheTempStream ); fclose( cacheTempStream ); MGmDbArrayFree( portCache ); system( CACHE_TMP_2_DB ); /************************/ free( MakefileSize ); free( Makefile ); MGmDbArrayFree(config_db); return( Buffer ); } char* rGetFromMakeDescribe( char* installedPortDir ) { FILE* tempStream = NULL; char id[] = "rGetFromMakeDescribe"; char* Buffer = NULL; char* currentPortMakefile = NULL; int idx = 0; int skip = 0; unsigned int BufferSize = 65000; unsigned int miscPtr = 0; Buffer = (char* )malloc( BufferSize ); Buffer[BufferSize] = 0; while( idx < config_db.recordQty ) { /* see if this port has anything special in config.db */ if( strnstr( installedPortDir, config_db.array[idx][0], strlen( installedPortDir ) ) != 0 ) { currentPortMakefile = ( char* )malloc( strlen( "( cd /usr/ports/" ) + strlen( installedPortDir ) + strlen( "; make " ) + strlen( config_db.array[idx][1] ) + strlen( " describe" ) + 1 ); strncpy( currentPortMakefile, "( cd /usr/ports/", strlen("( cd /usr/ports/")+1 ); strncat( currentPortMakefile, installedPortDir, strlen(installedPortDir)+1 ); strncat( currentPortMakefile, "; make ", strlen("; make ")+1 ); strncat( currentPortMakefile, config_db.array[idx][1], strlen(config_db.array[idx][1])+1 ); strncat( currentPortMakefile, " describe", strlen(" describe")+1 ); strncat( currentPortMakefile, " ) ", strlen(" ) ")+1 ); skip = 1; break; } idx++; } if( skip == 0 ) { /* set get portname for Makefile lookup from portI.db */ currentPortMakefile = ( char* )malloc( strlen( "( cd /usr/ports/" ) + strlen( installedPortDir ) + strlen( "; make describe )" ) + 1 ); strncpy( currentPortMakefile, "( cd /usr/ports/", strlen("( cd /usr/ports/")+1 ); strncat( currentPortMakefile, installedPortDir, strlen(installedPortDir)+1 ); strncat( currentPortMakefile, "; make describe )", strlen("; make describe )")+1 ); } tempStream = popen( currentPortMakefile, "r" ); if( ferror( tempStream ) ) { fprintf( stderr, "%s error: reading make describe into buffer\n", id ); perror( "system message" ); pclose( tempStream ); free( Buffer ); free( currentPortMakefile ); return( NULL ); } fread( Buffer, BufferSize, 1, tempStream ); pclose( tempStream ); free( currentPortMakefile ); miscPtr = 0; while( miscPtr < ( int )strlen( Buffer ) ) { if( Buffer[miscPtr] == '|' ) { Buffer[miscPtr] = 0; Buffer = realloc( Buffer, miscPtr + 1 ); miscPtr = ( int )strlen( Buffer ); } miscPtr++; } Buffer = ( char* )realloc( Buffer, strlen( Buffer ) + 1 ); return( Buffer ); } int rPurgeCacheRecord( char* ptrStart, char* ptrMid, char* ptrMidSkip, char* ptrEof ) { FILE* cacheTempStream = NULL; char cachFileName[] = DATADIR PORTS_CACHE_DB; char id[] = "PMGRrMakeDescribe.rPurgeCacheRecord"; /************************/ /* cache purge */ /************************/ cacheTempStream = fopen( DATADIR"portCache.tmp", "w" ); fwrite( ptrStart, (unsigned int)ptrMid - (unsigned int)ptrStart, 1, cacheTempStream ); fclose( cacheTempStream ); cacheTempStream = fopen( DATADIR"portCache.tmp", "a" ); fwrite( ptrMidSkip, (unsigned int)ptrEof - (unsigned int)ptrMidSkip, 1, cacheTempStream ); fclose( cacheTempStream ); fflush( cacheTempStream ); MGmDbArrayFree( portCache ); system( CACHE_TMP_2_DB ); MGmDbArray( portCache, cachFileName, "r+" ); if( errno ) { fprintf( stderr, "%s error: MGmDbArray returned with an error\n", id ); return( 1 ); } /************************/ return( 0 ); }