From 7db36a90600fbb3ab6a5d6ce9b97c954b76891e4 Mon Sep 17 00:00:00 2001
From: Harsh Prateek Bora <harsh@linux.vnet.ibm.com>
Date: Fri, 5 Oct 2012 14:56:41 +0530
Subject: [PATCH] lsvpd: device listing using location code

Earlier, this support was introduced for lscfg.
This patch enables lsvpd to support device listing using location code as well.

---
 src/output/lsvpd.cpp |  429 +++++++++++++++++++++++++++-----------------------
 1 files changed, 233 insertions(+), 196 deletions(-)

Index: lsvpd-1.7.0/src/output/lsvpd.cpp
===================================================================
--- lsvpd-1.7.0.orig/src/output/lsvpd.cpp
+++ lsvpd-1.7.0/src/output/lsvpd.cpp
@@ -53,7 +53,7 @@ extern int optind, opterr, optopt;
 
 bool markedVpd = false;
 bool debug = false;
-string serial = "", machineType = "", path = "", devType = "";
+string serial = "", machineType = "", path = "", devType = "", devName = "";
 
 void printUsage( )
 {
@@ -66,6 +66,7 @@ void printUsage( )
 	cout << "sbin/lsvpd [options]" << endl;
 	cout << "options: " << endl;
 	cout << " --help,       -h     print this usage message" << endl;
+	cout << " --list=DEV,   -lDEV  print info about given device (location code, AIX name)." << endl;
 	cout << " --debug,      -D     print extra information about devices (sysfs locations, etc)" << endl;
 	cout << " --version,    -v     print the version of vpd tools" << endl;
 	cout << " --mark,       -m     Mark VPD as global or partition-private." << endl;
@@ -80,9 +81,25 @@ void printVersion( )
 	cout << "lsvpd " << VPD_VERSION << endl;
 }
 
+bool contains( const vector<DataItem*>& vec, const string& val )
+{
+        vector<DataItem*>::const_iterator i, end;
+
+        for( i = vec.begin( ), end = vec.end( ); i != end; ++i )
+        {
+                const string name = (*i)->getValue( );
+                if( name == val )
+                        return true;
+        }
+
+        return false;
+}
+
 void printVPD( Component* root )
 {
 
+	bool devFound = false;
+
 	if( debug )
 	{
 		vector<string> children = root->getChildren( );
@@ -126,147 +143,158 @@ void printVPD( Component* root )
 		!= string::npos ) && ( bn.find( "pci@" ) == string::npos &&
 		bn.find( "isa@" ) == string::npos ) )
 	{
-		cout << "*" << root->getFeatureCodeAC( ) << " ";
-		if( root->getFeatureCode( ) != "" )
-			cout << root->getFeatureCode( );
-		else
+		if( devName != "" )
 		{
-			if( markedVpd )
-				cout << "********";
-			else
-				cout << "????????";
+			if ( (root->getPhysicalLocation() == devName) ||
+			     contains(root->getAIXNames(), devName) ) {
+				devFound = true;
+			}
+
 		}
-		cout << endl;
 
-		if( root->getDescription( ) != "" )
+		if ( devName == "" || (devName != "" && devFound == true ) )
 		{
-			cout << "*" << root->getDescriptionAC( ) << " " <<
-				root->getDescription( );
-			string val = string( root->getCD( ) );
-
-			if( val != "" )
+			cout << "*" << root->getFeatureCodeAC( ) << " ";
+			if( root->getFeatureCode( ) != "" )
+				cout << root->getFeatureCode( );
+			else
 			{
-				char s1, s2;
-				s1 = val[ 0 ];
-				s2 = val[ 1 ];
-				val[ 0 ] = val[ 2 ];
-				val[ 1 ] = val[ 3 ];
-				val[ 2 ] = s1;
-				val[ 3 ] = s2;
-
-				s1 = val[ 4 ];
-				s2 = val[ 5 ];
-				val[ 4 ] = val[ 6 ];
-				val[ 5 ] = val[ 7 ];
-				val[ 6 ] = s1;
-				val[ 7 ] = s2;
-
-				cout << " (" << val << ")";
+				if( markedVpd )
+					cout << "********";
+				else
+					cout << "????????";
 			}
 			cout << endl;
-		}
 
-		if( root->getRecordType( ) != "" )
-			cout << "*" << root->getRecordTypeAC( )<< " " <<
-				root->getRecordType( ) << endl;
-		/*AX*/
-		vector<DataItem*>::const_iterator j, stop;
-		for( j = root->getAIXNames( ).begin( ),
-			stop = root->getAIXNames( ).end( ); j != stop; ++j )
-		{
-			cout << "*" << (*j)->getAC( ) << " " << (*j)->getValue( ) << endl;
-		}
+			if( root->getDescription( ) != "" )
+			{
+				cout << "*" << root->getDescriptionAC( ) << " " <<
+					root->getDescription( );
+				string val = string( root->getCD( ) );
+
+				if( val != "" )
+				{
+					char s1, s2;
+					s1 = val[ 0 ];
+					s2 = val[ 1 ];
+					val[ 0 ] = val[ 2 ];
+					val[ 1 ] = val[ 3 ];
+					val[ 2 ] = s1;
+					val[ 3 ] = s2;
+
+					s1 = val[ 4 ];
+					s2 = val[ 5 ];
+					val[ 4 ] = val[ 6 ];
+					val[ 5 ] = val[ 7 ];
+					val[ 6 ] = s1;
+					val[ 7 ] = s2;
+
+					cout << " (" << val << ")";
+				}
+				cout << endl;
+			}
 
-		/*MF*/
-		if( root->getManufacturer( ) != "" )
-			cout << "*" << root->getManufacturerAC( ) << " " <<
-				root->getManufacturer( ) << endl;
-		/*TM*/
-		if( root->getModel( ) != "" )
-			cout << "*" << root->getModelAC( ) << " " <<
-				root->getModel( ) << endl;
-		/* SE */
-		if( root->getMachineSerial( ) != "" )
-			cout << "*" << root->getMachineSerialAC() << " " <<
-				root->getMachineSerial( ) << endl;
-		/*CD*/
-		if( root->getCD( ) != "" )
-			cout << "*" << root->getCDAC( ) << " " << root->getCD( ) << endl;
-		/*NA*/
-		if( root->getNetAddr( ) != "" )
-			cout << "*" << root->getNetAddrAC( ) << " " <<
-				root->getNetAddr( ) << endl;
-		/*FN*/
-		if( root->getFRU( ) != "" )
-			cout << "*" << root->getFRUAC( ) << " " << root->getFRU( ) <<
-				endl;
-		/*RM*/
-		if( root->getFirmwareVersion( ) != "" )
-			cout << "*" << root->getFirmwareVersionAC( ) << " "
-				<< root->getFirmwareVersion( ) << endl;
-		/*MN*/
-		if( root->getManufacturerID( ) != "" )
-			cout << "*" << root->getManufacturerIDAC( ) << " " <<
-				root->getManufacturerID( ) << endl;
-		/*RL*/
-		if( root->getFirmwareLevel( ) != "" )
-			cout << "*" << root->getFirmwareLevelAC( ) << " "
-				<< root->getFirmwareLevel( ) << endl;
-		/*SN*/
-		if( root->getSerialNumber( ) != "" )
-			cout << "*" << root->getSerialNumberAC( ) << " " <<
-				root->getSerialNumber( ) << endl;
-		/*EC*/
-		if( root->getEngChange( ) != "" )
-			cout << "*" << root->getEngChangeAC( ) << " " <<
-				root->getEngChange( ) << endl;
-		/*PN*/
-		if( root->getPartNumber( ) != "" )
-			cout << "*" << root->getPartNumberAC( ) << " " <<
-				root->getPartNumber( ) << endl;
-		/*N5*/
-		if( root->getn5( ) != "" )
-			cout << "*" << root->getn5AC( ) << " " <<
-				root->getn5( ) << endl;
-		/*N6*/
-		if( root->getn6( ) != "" )
-			cout << "*" << root->getn6AC( ) << " " <<
-				root->getn6( ) << endl;
+			if( root->getRecordType( ) != "" )
+				cout << "*" << root->getRecordTypeAC( )<< " " <<
+					root->getRecordType( ) << endl;
+			/*AX*/
+			vector<DataItem*>::const_iterator j, stop;
+			for( j = root->getAIXNames( ).begin( ),
+				stop = root->getAIXNames( ).end( ); j != stop; ++j )
+			{
+				cout << "*" << (*j)->getAC( ) << " " << (*j)->getValue( ) << endl;
+			}
 
-		for( j = root->getDeviceSpecific( ).begin( ),
-			stop = root->getDeviceSpecific( ).end( );
-			j != stop; ++j )
-		{
+			/*MF*/
+			if( root->getManufacturer( ) != "" )
+				cout << "*" << root->getManufacturerAC( ) << " " <<
+					root->getManufacturer( ) << endl;
+			/*TM*/
+			if( root->getModel( ) != "" )
+				cout << "*" << root->getModelAC( ) << " " <<
+					root->getModel( ) << endl;
+			/* SE */
+			if( root->getMachineSerial( ) != "" )
+				cout << "*" << root->getMachineSerialAC() << " " <<
+					root->getMachineSerial( ) << endl;
+			/*CD*/
+			if( root->getCD( ) != "" )
+				cout << "*" << root->getCDAC( ) << " " << root->getCD( ) << endl;
+			/*NA*/
+			if( root->getNetAddr( ) != "" )
+				cout << "*" << root->getNetAddrAC( ) << " " <<
+					root->getNetAddr( ) << endl;
+			/*FN*/
+			if( root->getFRU( ) != "" )
+				cout << "*" << root->getFRUAC( ) << " " << root->getFRU( ) <<
+					endl;
+			/*RM*/
+			if( root->getFirmwareVersion( ) != "" )
+				cout << "*" << root->getFirmwareVersionAC( ) << " "
+					<< root->getFirmwareVersion( ) << endl;
+			/*MN*/
+			if( root->getManufacturerID( ) != "" )
+				cout << "*" << root->getManufacturerIDAC( ) << " " <<
+					root->getManufacturerID( ) << endl;
+			/*RL*/
+			if( root->getFirmwareLevel( ) != "" )
+				cout << "*" << root->getFirmwareLevelAC( ) << " "
+					<< root->getFirmwareLevel( ) << endl;
+			/*SN*/
+			if( root->getSerialNumber( ) != "" )
+				cout << "*" << root->getSerialNumberAC( ) << " " <<
+					root->getSerialNumber( ) << endl;
+			/*EC*/
+			if( root->getEngChange( ) != "" )
+				cout << "*" << root->getEngChangeAC( ) << " " <<
+					root->getEngChange( ) << endl;
+			/*PN*/
+			if( root->getPartNumber( ) != "" )
+				cout << "*" << root->getPartNumberAC( ) << " " <<
+					root->getPartNumber( ) << endl;
+			/*N5*/
+			if( root->getn5( ) != "" )
+				cout << "*" << root->getn5AC( ) << " " <<
+					root->getn5( ) << endl;
+			/*N6*/
+			if( root->getn6( ) != "" )
+				cout << "*" << root->getn6AC( ) << " " <<
+					root->getn6( ) << endl;
+
+			for( j = root->getDeviceSpecific( ).begin( ),
+				stop = root->getDeviceSpecific( ).end( );
+				j != stop; ++j )
+			{
 
-			if (!(*j)->getAC().compare("SZ")) {
-				/* Accounts for AIX lsvpd output, which uses key
-				 * 'Size' rather than 'SZ'.  BZ 54756 */
-				cout << "*Size " << (*j)->getValue( ) << endl;
+				if (!(*j)->getAC().compare("SZ")) {
+					/* Accounts for AIX lsvpd output, which uses key
+					 * 'Size' rather than 'SZ'.  BZ 54756 */
+					cout << "*Size " << (*j)->getValue( ) << endl;
+				}
+				else
+					cout << "*" << (*j)->getAC( ) << " " << (*j)->getValue( ) << endl;
 			}
-			else
-				cout << "*" << (*j)->getAC( ) << " " << (*j)->getValue( ) << endl;
-		}
 
-		if( root->getMicroCodeImage( ) != "" )
-			cout << "*" << root->getMicroCodeImageAC( ) << " " <<
-				root->getMicroCodeImage( ) << endl;
+			if( root->getMicroCodeImage( ) != "" )
+				cout << "*" << root->getMicroCodeImageAC( ) << " " <<
+					root->getMicroCodeImage( ) << endl;
+
+			for( j = root->getUserData( ).begin( ),
+				stop = root->getUserData( ).end( );
+				j != stop; ++j )
+			{
+				cout << "*" << (*j)->getAC( ) << " " << (*j)->getValue( ) << endl;
+			}
 
-		for( j = root->getUserData( ).begin( ),
-			stop = root->getUserData( ).end( );
-			j != stop; ++j )
-		{
-			cout << "*" << (*j)->getAC( ) << " " << (*j)->getValue( ) << endl;
+			if( root->getPhysicalLocation( ) != "" )
+				cout << "*" << root->getPhysicalLocationAC( ) << " " <<
+					root->getPhysicalLocation( ) << endl;
+
+			if( root->getKeywordVersion( ) != "" )
+				cout << "*" << root->getKeywordVersionAC( ) << " " <<
+					root->getKeywordVersion( ) << endl;
 		}
-
-		if( root->getPhysicalLocation( ) != "" )
-			cout << "*" << root->getPhysicalLocationAC( ) << " " <<
-				root->getPhysicalLocation( ) << endl;
-
-		if( root->getKeywordVersion( ) != "" )
-			cout << "*" << root->getKeywordVersionAC( ) << " " <<
-				root->getKeywordVersion( ) << endl;
 	}
-
 	if( debug )
 		cout << " ------------------------- " << endl;
 
@@ -281,84 +309,87 @@ void printVPD( Component* root )
 
 void printVPD( System* root )
 {
-	/* bpeters: Where did this come from?  Seems sketchy. */
-	cout << "*VC 5.0" << endl;
+	if( devName == "" )
+	{
+		/* bpeters: Where did this come from?  Seems sketchy. */
+		cout << "*VC 5.0" << endl;
 
-	devType = root->getArch( );
+		devType = root->getArch( );
 
-	if( debug )
-	{
-		cout << "ID: " << root->getID( ) << endl;
-		cout << "Device Tree Node: " << root->getDevTreeNode( ) << endl;
-		vector<string>::const_iterator i, end;
-		cout << "Children: " << endl;
-		for( i = root->getChildren( ).begin( ), end = root->getChildren( ).end( );
-			i != end; ++i )
+		if( debug )
 		{
-			cout << *(i) << endl;
+			cout << "ID: " << root->getID( ) << endl;
+			cout << "Device Tree Node: " << root->getDevTreeNode( ) << endl;
+			vector<string>::const_iterator i, end;
+			cout << "Children: " << endl;
+			for( i = root->getChildren( ).begin( ), end = root->getChildren( ).end( );
+				i != end; ++i )
+			{
+				cout << *(i) << endl;
+			}
 		}
-	}
 
-	if( machineType != "" )
-		cout << "*" << root->getMachineTypeAC( ) << " " <<
-			machineType << endl;
-	else if( root->getMachineType( ) != "" )
-		cout << "*" << root->getMachineTypeAC( ) << " " <<
-			root->getMachineType( ) << endl;
-
-	if( serial != "" )
-		cout << "*" << root->getSerial1AC( ) << " " << serial << endl;
-	else if( root->getSerial1( ) != "" )
-		cout << "*" << root->getSerial1AC( ) << " " <<
-			root->getSerial1( ) << endl;
-
-	if( serial != "" )
-		cout << "*" << root->getProcessorIDAC( ) << " " << serial << endl;
-	else if( root->getProcessorID( ) != "" )
-		cout << "*" << root->getProcessorIDAC( ) << " " <<
-			root->getProcessorID( ) << endl;
+		if( machineType != "" )
+			cout << "*" << root->getMachineTypeAC( ) << " " <<
+				machineType << endl;
+		else if( root->getMachineType( ) != "" )
+			cout << "*" << root->getMachineTypeAC( ) << " " <<
+				root->getMachineType( ) << endl;
+
+		if( serial != "" )
+			cout << "*" << root->getSerial1AC( ) << " " << serial << endl;
+		else if( root->getSerial1( ) != "" )
+			cout << "*" << root->getSerial1AC( ) << " " <<
+				root->getSerial1( ) << endl;
+
+		if( serial != "" )
+			cout << "*" << root->getProcessorIDAC( ) << " " << serial << endl;
+		else if( root->getProcessorID( ) != "" )
+			cout << "*" << root->getProcessorIDAC( ) << " " <<
+				root->getProcessorID( ) << endl;
 
-	if( root->getOS( ) != "" )
-		cout << "*" << root->getOSAC( ) << " " << root->getOS( ) << endl;
+		if( root->getOS( ) != "" )
+			cout << "*" << root->getOSAC( ) << " " << root->getOS( ) << endl;
 
-	if( root->getSerial2( ) != "" )
-	{
-		cout << "*" << root->getFeatureCodeAC( ) << " ";
-		if( root->getFeatureCode( ) != "" )
-			cout << root->getFeatureCode( );
-		else
+		if( root->getSerial2( ) != "" )
 		{
-			if( markedVpd )
-				cout << "********";
+			cout << "*" << root->getFeatureCodeAC( ) << " ";
+			if( root->getFeatureCode( ) != "" )
+				cout << root->getFeatureCode( );
 			else
-				cout << "????????";
-		}
-		cout << endl;
+			{
+				if( markedVpd )
+					cout << "********";
+				else
+					cout << "????????";
+			}
+			cout << endl;
 
-		cout << "*" << root->getDescriptionAC( ) << " " <<
-			root->getDescription( ) << endl;
-		cout << "*" << root->getRecordTypeAC( ) << " " <<
-			root->getRecordType( ) << endl;
-		cout << "*" << root->getFlagFieldAC( ) << " " <<
-			root->getFlagField( ) << endl;
-		cout << "*" << root->getBrandAC( ) << " " <<
-			root->getBrand( ) << endl;
-		cout << "*" << root->getLocationAC( ) << " " <<
-			root->getLocation( ) << endl;
-		cout << "*" << root->getSerial2AC( ) << " " <<
-			root->getSerial2( ) << endl;
-		cout << "*" << root->getMachineModelAC( ) << " " <<
-			root->getMachineModel( ) << endl;
-		cout << "*" << root->getSUIDAC( ) << " " << root->getSUID( ) << endl;
-		cout << "*" << root->getKeywordVerAC( ) << " " <<
-			root->getKeywordVer( ) << endl;
-	}
+			cout << "*" << root->getDescriptionAC( ) << " " <<
+				root->getDescription( ) << endl;
+			cout << "*" << root->getRecordTypeAC( ) << " " <<
+				root->getRecordType( ) << endl;
+			cout << "*" << root->getFlagFieldAC( ) << " " <<
+				root->getFlagField( ) << endl;
+			cout << "*" << root->getBrandAC( ) << " " <<
+				root->getBrand( ) << endl;
+			cout << "*" << root->getLocationAC( ) << " " <<
+				root->getLocation( ) << endl;
+			cout << "*" << root->getSerial2AC( ) << " " <<
+				root->getSerial2( ) << endl;
+			cout << "*" << root->getMachineModelAC( ) << " " <<
+				root->getMachineModel( ) << endl;
+			cout << "*" << root->getSUIDAC( ) << " " << root->getSUID( ) << endl;
+			cout << "*" << root->getKeywordVerAC( ) << " " <<
+				root->getKeywordVer( ) << endl;
+		}
 
-	vector<DataItem*>::const_iterator j, stop;
-	for( j = root->getDeviceSpecific( ).begin( ), stop = root->getDeviceSpecific( ).end( );
-		j != stop; ++j )
-	{
-		cout << "*" << (*j)->getAC( ) << " " << (*j)->getValue( ) << endl;
+		vector<DataItem*>::const_iterator j, stop;
+		for( j = root->getDeviceSpecific( ).begin( ), stop = root->getDeviceSpecific( ).end( );
+			j != stop; ++j )
+		{
+			cout << "*" << (*j)->getAC( ) << " " << (*j)->getValue( ) << endl;
+		}
 	}
 
 	const vector<Component*> children = root->getLeaves( );
@@ -371,7 +402,7 @@ void printVPD( System* root )
 
 int main( int argc, char** argv )
 {
-	char opts [] = "hDvms::t::z:";
+	char opts [] = "hDvms::t::z:l:";
 	bool done = false;
 	bool compressed = false;
 	System * root = NULL;
@@ -387,6 +418,7 @@ int main( int argc, char** argv )
 		{ "type", 2, 0, 't' },
 		{ "path", 1, 0, 'p' },
 		{ "zip", 1, 0, 'z' },
+		{ "list", 1, 0, 'l' },
 		{ "debug", 0, 0, 'D' },
 		{ 0, 0, 0, 0 }
 	};
@@ -428,6 +460,11 @@ int main( int argc, char** argv )
 				compressed = true;
 				break;
 
+                        case 'l':
+				if ( optarg != NULL )
+					devName = optarg;
+				break;
+
 			case 'D':
 				debug = true;
 				break;
