/************************************************************************/ /* 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 */ /************************************************************************/ /* variable index: in PMGRrDbCreate.h PKG_DBDIR also in bsd.port.mk PORTS_INSTALLED_DB PORT_DEPENDENCIES_DB */ #include <PMGRrDbCreate.h> typedef struct { DIR* dir; DIR* portDir; char* fileName; char* portDirName; unsigned int portDirNameLen; struct dirent* entry; } struc_pkg; int pkgDirEntryFilter( struc_pkg* ); int PMGRrDbCreate( void ) { FILE* portIPStream = NULL; FILE* portIStream = NULL; FILE* portStream = NULL; char id[] = "PMGRrDbCreate"; char* buffPtr = NULL; char* portBuffer = NULL; char* portDependency = NULL; char* portDependencyDir = NULL; char* portDir = NULL; char* portName = NULL; int errorCode = 0; int idx = 0; int portDependencyDirLen = 0; int portDependencyLen = 0; int portDirLen = 0; int portNameLen = 0; struc_pkg pkg; unsigned int size = 0; /* set pkg structure initial values */ MGmSetString( pkg.fileName, PKG_DBDIR ) if( errorCode ) { fprintf( stderr, "%s %s error: mSetString returned code 1\n", id, ver ); perror( "system message" ); return( 1 ); } if( !( portIStream = fopen( DATADIR PORTS_INSTALLED_DB, "w" ) ) ) { fprintf( stderr, "%s %s error: unable to open %s%s for write\n", id, ver, DATADIR, PORTS_INSTALLED_DB ); fprintf( stderr, "you must run this program as root and path %s must exist and be writable\n", DATADIR ); perror( "system message" ); return( 1 ); } if( !( portIPStream = fopen( DATADIR PORT_DEPENDENCIES_DB, "w" ) ) ) { fprintf( stderr, "%s %s error: unable to open %s%s for write\n", id, ver, DATADIR, PORT_DEPENDENCIES_DB ); fprintf( stderr, "you must run this program as root and path %s must exist and be writable\n", DATADIR ); perror( "system message" ); return( 1 ); } /********************************************************/ /* 1 Get the directory entries in /var/db/pkg */ /* 2 Filter out ".", ".." */ /* 3 Filter out any entry that is not a directory */ /* 3.1 This should be an effective work */ /* around for those who have portupgrade */ /* installed and therefore a "pkgdb.db" in */ /* their /var/db/pkg directory */ /********************************************************/ if( !( pkg.dir = opendir( pkg.fileName ) ) ) { fprintf( stderr, "%s %s error: could not open dir %s\n", id, ver, pkg.fileName ); perror( "system message" ); return( 1 ); } /* print /var/db/pkg directory entries */ while( ( pkg.entry = readdir( pkg.dir ) ) ) { pkg.portDirNameLen = strlen( pkg.fileName ) + strlen( pkg.entry->d_name ) + strlen( "/+CONTENTS" ) + 2; pkg.portDirName = ( char* )malloc( pkg.portDirNameLen ); strcpy( pkg.portDirName, pkg.fileName ); strcat( pkg.portDirName, "/" ); strcat( pkg.portDirName, pkg.entry->d_name ); if( pkgDirEntryFilter( &pkg ) ) { /* if entry matches filter then get next entry */ free( pkg.portDirName ); continue; } strcat( pkg.portDirName, "/+CONTENTS" ); if( !( portStream = fopen( pkg.portDirName, "r" ) ) ) { fprintf( stderr, "%s %s error: could not open %s\n", id, ver, pkg.portDirName ); perror( "system message" ); return( 1 ); } size = MGrFileSize( pkg.portDirName ); if( !( portBuffer = ( char* )malloc( size ) ) ) { fprintf( stderr, "%s %s error: could allocate %d bytes for %s buffer\n", id, ver, size, pkg.portDirName ); perror( "system message" ); return( 1 ); } fread( portBuffer, 1, size, portStream ); portBuffer[size+1] = 0; portName = strstr( portBuffer, "@name " ) + strlen( "@name " ); portNameLen = strstr( portName, "\n" ) - portName; portDir = strstr( portBuffer, "@comment ORIGIN:" ) + strlen( "@comment ORIGIN:" ); portDirLen = strstr( portDir, "\n" ) - portDir; portName[portNameLen] = 0; portDir[portDirLen] = 0; fprintf( portIStream, "%s%c%s%c\n", portName, NULL, portDir, NULL ); portName[portNameLen] = 10; portDir[portDirLen] = 10; /************************************************************************/ /* dependencies */ /************************************************************************/ buffPtr = portDir + portDirLen + 1; size = strlen( portBuffer ) - ( buffPtr - portBuffer ); portName[portNameLen] = 0; while( ( portDependency = strstr( buffPtr, "@pkgdep " ) ) ) { portDependency += strlen( "@pkgdep " ); portDependencyLen = strstr( portDependency, "\n" ) - portDependency; portDependency[portDependencyLen] = 0; buffPtr = portDependency + portDependencyLen + 1; portDependencyDir = strstr( buffPtr, "@comment DEPORIGIN:" ); portDependencyDir += strlen( "@comment DEPORIGIN:" ); portDependencyDirLen = strstr( portDependencyDir, "\n" ) - portDependencyDir; portDependencyDir[portDependencyDirLen] = 0; buffPtr = portDependencyDir + portDependencyDirLen + 1; if( portDependencyDir && portDependency ) { fprintf( portIPStream, "%s%c%s%c%s%c\n", portName, NULL, portDependency, NULL, portDependencyDir, NULL ); } else { fprintf( stderr, "%s %s error: error in dependency section\n", id, ver ); return( 1 ); } } /************************************************************************/ free( portBuffer ); free( pkg.portDirName ); idx++; } if( closedir( pkg.dir ) == -1 ) { fprintf( stderr, "%s %s error: could not close dir %s\n", id, ver, pkg.fileName ); perror( "system message" ); return( 1 ); } fflush( portIStream ); fflush( portIPStream ); fclose( portIStream ); fclose( portIPStream ); free( pkg.fileName ); return( 0 ); } /************************************************************************/ /* 1 Filter out ".", ".." */ /* 2 Filter out any entry that is not a dirctory */ /* 2.1 This should be an effective work around for */ /* those who have portupgrade installed and */ /* therefore a "pkgdb.db" in their /var/db/pkg */ /************************************************************************/ int pkgDirEntryFilter( struc_pkg* pkg ) { FILE* testStream = 0; /* filter #1 */ /* filter out . and .. entries */ if( strcmp( pkg->entry->d_name, "." ) == 0 || strcmp( pkg->entry->d_name, ".." ) == 0 ) { if( strlen( pkg->entry->d_name ) < 3 ) { return( 1 ); } } /* filter #2 */ /* make sure pkg->entry->d_name is a directory and not a file */ /* if it can be opened for append "a" then it is a file! */ if( ( testStream = fopen( pkg->portDirName, "a" ) ) ) { fclose( testStream ); return( 1 ); } return( 0 ); }