/************************************************************************/ /* 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 */ /************************************************************************/ #include <pmStatus.h> #define PORTNAME_F0 0 /* works for portI and portIP */ #define PORTDIR_F1 1 #define DEPENDANCYNAME_F1 1 #define DEPENDANCYDIR_F2 2 #define MATCH 0 void catch_SIGSEGV( int ); char id[] = "pmStatus"; int main( ) { FILE* portOODStream =NULL; MGsDb portI; MGsDb portIP; char modeReadOny[] = "r"; char portIFileName[] = DATADIR PORTS_INSTALLED_DB; char portIPFileName[] = DATADIR PORT_DEPENDENCIES_DB; char portOODFileName[] = DATADIR PORTS_OLD_DB; char* available = NULL; char* portOODbuffer = NULL; char* systemCommand; int miscPtr = 0; unsigned int portOODsize2 = 0; int recIdxPortI = 0; int recIdxPortIP = 0; int skip = 0; /* handle seg faults */ /* signal(SIGSEGV, catch_SIGSEGV ); */ /*......................................................*/ /* create portI.db and portIP.db */ /*......................................................*/ if( PMGRrDbCreate() ) { fprintf( stderr, "%s %s error: PMGRrDbCreate returned with an error\n", id, ver ); return( 1 ); } /****************************************/ /* MGmDbArray: */ /* b = dbase structure name */ /* c = dbase file name string */ /* d = open mode string */ /****************************************/ MGmDbArray( portI, portIFileName, modeReadOny ); if( errno ) { fprintf( stderr, "%s %s error: MGmDbArray returned with an error\n", id, ver ); return( 1 ); } MGmDbArray( portIP, portIPFileName, modeReadOny ); if( errno ) { fprintf( stderr, "%s %s error: MGmDbArray returned with an error\n", id, ver ); return( 1 ); } recIdxPortI = 0; portOODStream = fopen( portOODFileName, "w" ); /* loop thru installed ports db */ while( recIdxPortI < portI.recordQty ) { /* PMGRrMakeDescribe returns the version of the available port from "cd /usr/ports/; make describe" */ available = PMGRrMakeDescribe( portI.array[recIdxPortI][PORTDIR_F1] ); /* compare installed port name with name from "make describe" */ if( ( strcmp( portI.array[recIdxPortI][0], available ) ) < 0 ) { fprintf( stdout, "have:%-25s status: OLD available:%-25s %-25s\n", portI.array[recIdxPortI][0], available, portI.array[recIdxPortI][PORTDIR_F1] ); fflush( stdout ); fprintf( portOODStream, "%s%c%s%cOLD%c%s%c\n", portI.array[recIdxPortI][PORTDIR_F1], 0, portI.array[recIdxPortI][0], 0, 0, available, 0 ); fflush( portOODStream ); } if( ( strcmp( portI.array[recIdxPortI][0], available ) ) > 0 ) { /* remove ports that have been deleted from or moved in the ports collection */ /* added 0.1.7 20040804 */ if( strlen(available) == 0 ) { fprintf( stdout, "removing: %s, \n\t it is no longer in the ports collection, \n\t see /usr/ports/MOVED for possible explanation\n", portI.array[recIdxPortI][0] ); systemCommand = ( char* )malloc( strlen( "( pkg_delete -f )" ) + strlen( portI.array[recIdxPortI][0] ) + 1 ); strncpy( systemCommand, "pkg_delete -f ",strlen("pkg_delete -f ")+1 ); strncat( systemCommand, portI.array[recIdxPortI][0], strlen(portI.array[recIdxPortI][0])+1 ); fprintf( stdout, "%s\n", systemCommand ); system( systemCommand ); free( systemCommand ); } fprintf( stdout, "have:%-25s status: OLD requires downgrade! available:%-25s %-25s\n", portI.array[recIdxPortI][0], available, portI.array[recIdxPortI][PORTDIR_F1] ); fprintf( portOODStream, "%s%c%s%cERR%c%s%c\n", portI.array[recIdxPortI][PORTDIR_F1], 0, portI.array[recIdxPortI][0], 0, 0, available, 0 ); fflush( stdout ); fflush( portOODStream ); } if( ( strcmp( portI.array[recIdxPortI][0], available ) ) == 0 ) { /* fprintf( stdout, "have:%-25s status: up to date:%-25s %-25s\n", portI.array[recIdxPortI][0], available, portI.array[recIdxPortI][PORTDIR_F1] ); fflush( stdout ); */ fprintf( stdout, "have:%-25s status: CURRENT: %-25s\n", portI.array[recIdxPortI][0], portI.array[recIdxPortI][PORTDIR_F1] ); } free( available ); recIdxPortI++; } fclose( portOODStream ); /****************************************/ /* parent port check */ /****************************************/ recIdxPortIP = 0; while( recIdxPortIP < portIP.recordQty ) { recIdxPortI = 0; /* while parent port not in portI */ while( ( recIdxPortI < portI.recordQty ) && ( strcmp( portI.array[recIdxPortI][0], portIP.array[recIdxPortIP][1] ) != 0 ) ) { recIdxPortI++; } if( recIdxPortI != portI.recordQty ) /* if recIdxPortI == portI.recordQty then parent port name */ { /* not in portIP */ recIdxPortIP++; continue; /* contilue = return to While statement */ } /***************************************/ /* was dependancy port ever installed? */ /***************************************/ recIdxPortI = 0; skip = 0; /* search all of portI's paths for the path pointed to in portIP */ while( ( recIdxPortI < portI.recordQty ) && ( strcmp( portI.array[recIdxPortI][PORTDIR_F1], portIP.array[recIdxPortIP][DEPENDANCYDIR_F2] ) != 0 ) ) { recIdxPortI++; } /************************************************************************/ /* handle switch from XFree86 to Xorg or other cases where */ /* dependency ports have changed names by ignoring them rather than */ /* trying to reinstall the original dependency port */ /************************************************************************/ if( strncmp( portIP.array[recIdxPortIP][DEPENDANCYNAME_F1], "XFree86", 4 ) == MATCH || strncmp( portIP.array[recIdxPortIP][DEPENDANCYNAME_F1], "Xorg", 4 ) == MATCH || strncmp( portIP.array[recIdxPortIP][DEPENDANCYNAME_F1], "imake", 4 ) == MATCH ) { /* fprintf( stdout, "%-25s ignoring reason: X dependency %-25s\n", portI.array[recIdxPortI-1][PORTNAME_F0], portIP.array[recIdxPortIP][DEPENDANCYNAME_F1] ); fflush( stdout ); */ skip = 1; } /* if recIdxPortI == portI.recordQty then dependancy never installed! */ if( recIdxPortI == portI.recordQty && skip == 0 ) { fprintf( stdout, "%-25s dependancy port %s %s not installed!\n", portIP.array[recIdxPortIP][PORTNAME_F0], portIP.array[recIdxPortIP][DEPENDANCYNAME_F1], portIP.array[recIdxPortIP][DEPENDANCYDIR_F2] ); portOODStream = fopen( portOODFileName, "a" ); fprintf( portOODStream, "%s%c%s%cMISSING%c%s%c\n", portIP.array[recIdxPortIP][DEPENDANCYDIR_F2], 0, portIP.array[recIdxPortIP][DEPENDANCYNAME_F1], 0, 0, portIP.array[recIdxPortIP][PORTNAME_F0], 0 ); fflush( portOODStream ); skip = 1; } /********************/ /* find IP port in I */ recIdxPortI = 0; while( recIdxPortI < portI.recordQty && skip == 0) { if( ( strcmp( portI.array[recIdxPortI][0], portIP.array[recIdxPortIP][0] ) == 0 ) ) { portOODStream = fopen( portOODFileName, "r+" ); portOODsize2 = MGrFileSize( portOODFileName ); if( portOODsize2 == 0 ) { portOODsize2 = 1; } portOODbuffer = ( char* )malloc( portOODsize2 ); if( portOODbuffer == NULL ) { printf( "pmStatus error allocating %d bytes for portOODbuffer\n", portOODsize2 ); exit(100); } /* printf("portOODsize2 = %d\n", portOODsize2 ); */ fread( portOODbuffer, portOODsize2, 1, portOODStream ); miscPtr = 0; while( miscPtr < portOODsize2 ) { if( portOODbuffer[miscPtr] == 0 ) { portOODbuffer[miscPtr] = TAB; } miscPtr++; } if( strstr( portOODbuffer, portI.array[recIdxPortI][PORTDIR_F1] ) == 0 ) { fprintf( stdout, "have:%-25s status built with OLD dependency port :%-25s\n", portI.array[recIdxPortI][0], /* portI[0] = name */ portIP.array[recIdxPortIP][1] ); /* portIP[1] = depency name */ fflush( stdout ); fprintf( portOODStream, "%s%c%s%cPARENTOOD%c%s%c\n", portI.array[recIdxPortI][PORTDIR_F1], 0, /* portI[1] = path */ portI.array[recIdxPortI][0], 0, 0, portIP.array[recIdxPortIP][1], 0 ); fflush( portOODStream ); } miscPtr = 0; while( miscPtr < portOODsize2 ) { if( portOODbuffer[miscPtr] == TAB ) { portOODbuffer[miscPtr] = 0; } miscPtr++; } fclose( portOODStream ); free( portOODbuffer ); } recIdxPortI++; } recIdxPortIP++; } /****************************************/ fprintf( stderr, "status report finished\n" ); fflush( stderr ); MGmDbArrayFree( portI ); MGmDbArrayFree( portIP ); exit( 0 ); } /******************/ /* signal handler */ /******************/ void catch_SIGSEGV( int signalID ) { sigset_t mask_set; /* used to set a signal masking set. */ sigset_t old_set; /* used to store the old mask set. */ /* re-set the signal handler again to catch_SIGSEGV, for next time */ signal( SIGSEGV, catch_SIGSEGV ); /* mask any further signals while we're inside the handler. */ sigfillset(&mask_set); sigprocmask(SIG_SETMASK, &mask_set, &old_set); if( signalID == SIGSEGV ) { /* reset the cache */ system( CACHE_RESET ); fprintf( stderr, "%s %s warning: segment fault, resetting cache\n", id, ver ); /* see sysexits(3) for codes */ exit( EX_TEMPFAIL ); } }