Files
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

329 lines
8.6 KiB
C

static char sccsid[] = "@(#)07 1.4 src/bldenv/pkgtools/addvpd.c, pkgtools, bos41J, 9512A_all 3/16/95 09:50:14";
/*
* COMPONENT_NAME: PKGTOOLS
*
* FUNCTIONS: addToVpd
* fatal
* getChecksum
* initVpdPath
* usage
* warning
* xmalloc
*
* ORIGINS: 27
*
* IBM CONFIDENTIAL -- (IBM Confidential Restricted when
* combined with the aggregated modules for this product)
* SOURCE MATERIALS
*
* (C) COPYRIGHT International Business Machines Corp. 1992,1993
* All Rights Reserved
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
#include <swvpd.h>
#include <sys/param.h>
#include <errno.h>
#include <varargs.h>
#include "stanza.h"
#include "addvpd.h"
extern char * optarg;
/*-----------------------------------------------------------------------
| The addvpd command reads an input stanza file and adds an entry |
| to the vital products database (vpd) for each file entry in the |
| input file. |
-----------------------------------------------------------------------*/
main (int argc, char **argv)
{
int arg, rc=0;
char *stanzaFile, *lppname, *objDir;
char vpdPath[MAXPATHLEN];
char stanza[STANZASIZE];
char value[LENSIZE];
FILE *fp;
inv_t inv_entry;
short lpp_id=0;
objDir = NULL;
stanzaFile = NULL;
lppname = NULL;
while ( (arg = getopt (argc, argv, "d:f:l:")) != EOF )
{
switch (arg)
{
case 'd':
objDir = optarg;
break;
case 'f':
stanzaFile = optarg;
break;
case 'l':
lppname = optarg;
break;
case '?':
usage ();
}
}
/*---------------------------------------
| Verify command line parameters. |
---------------------------------------*/
if ( !strlen (stanzaFile) || !strlen (lppname) || !strlen (objDir) )
{
fprintf (stderr,Missing_Opt,COMMANDNAME);
usage ();
}
initVpdPath (objDir);
/*-------------------------------
| Get the lpp id from the vpd. |
-------------------------------*/
if (vpdreslpp_name(lppname,&lpp_id) != VPD_OK)
fatal (No_LPP_Id, lppname);
if ( (fp = fopen(stanzaFile, "r")) == NULL )
fatal (File_Open_Failed,stanzaFile,errno);
/*---------------------------------------------------------------
| Only add stanzas which contain "apply" on the class line to |
| the vpd. Inventory only entries do not contain apply and |
| should not be in the vpd. |
---------------------------------------------------------------*/
while ( (rc = readStanza (fp, stanza, STANZASIZE)) == 0 )
{
memset ((void *) &inv_entry, 0, sizeof inv_entry);
if ( !(rc = getEntry ("class",stanza,value)) && strlen (value) )
{
if ( !strstr (value, "apply") )
continue;
}
else
if ( rc == OVERFLOW )
fatal (Class_Overflow, stanza, LENSIZE);
else
fatal (No_Class, stanza);
addToVpd (&inv_entry, stanza, vpdPath, lpp_id);
}
if ( rc == OVERFLOW )
fatal (Stanza_Overflow, STANZASIZE, stanza);
exit (0);
}
void
usage ()
{
fprintf (stderr,Usage,COMMANDNAME);
exit (-1);
}
/*---------------------------------------------------------------
| Initialize and open the vpd with the location provided by |
| the -d parameter. |
---------------------------------------------------------------*/
void
initVpdPath ( char *objDir )
{
if (vpdremotepath(objDir) != VPD_OK)
fatal (VPD_Open_Failed);
else vpdremote();
}
/*-----------------------------------------------------------------------
| Fill in the inv_entry struct with size, checksum, link and symlink |
| information from the current stanza. If an entry already exists |
| for a file, display a warning message and do not do a addvpd. |
-----------------------------------------------------------------------*/
void
addToVpd (inv_t *inv_entry, char *stanza, char *vpdPath, short lpp_id)
{
char value[LENSIZE];
char *ptr;
long size, cksum;
int nameLen=0, rc=0;
inv_t get_entry;
memset ((void *) value, 0, LENSIZE);
inv_entry->lpp_id = lpp_id;
/*-------------------------------------------
| Get the file name from the stanza. |
-------------------------------------------*/
ptr = strchr (stanza, ':');
nameLen = ptr - stanza;
/*-------------------------------------------------------------------
| The following 128 is from the /usr/include/swvpd.h file. If |
| that value (size of loc0 in inventory struct) changes then so |
| should this. |
-------------------------------------------------------------------*/
strncpy (inv_entry->loc0, stanza, (nameLen < 128 ? nameLen: 128));
inv_entry->private = 0;
inv_entry->format = INV_FILE;
if ( !getEntry ("size",stanza,value) && strlen (value) )
{
if ( !strcmp(value, "VOLATILE") )
size = 0;
else
{
errno = 0;
if ( !(size = strtol (value, NULL, 10)) && errno )
fatal (No_Size, errno, stanza);
}
inv_entry->size = size;
}
else
/*-----------------------------------------------
| No size value in stanza. Default to 0. |
| This is the case for directory entries. |
-----------------------------------------------*/
inv_entry->size = 0;
if ( !(rc = getEntry ("type",stanza,value)) )
{
if ( !strcmp(value, "SYMLINK") )
inv_entry->file_type = 6;
}
if ( !(rc = getEntry ("links",stanza,value)) )
{
inv_entry->loc1 = xmalloc (strlen(value)+1);
strcpy (inv_entry->loc1, value);
}
if ( rc == OVERFLOW )
fatal (Link_Overflow, "LENSIZE", stanza);
if ( !(rc = getEntry ("target",stanza,value)) )
{
inv_entry->loc2 = xmalloc (strlen(value) + 1);
strcpy (inv_entry->loc2, value);
}
inv_entry->checksum = getChecksum (stanza, value);
get_entry = *inv_entry;
if ( vpdget (INVENTORY_TABLE, INV_LOC0, &get_entry) == VPD_OK )
warning (Entry_Exists, inv_entry->loc0);
else
if ( vpdadd (INVENTORY_TABLE, inv_entry) != VPD_OK )
warning (VPD_Add_Failed,inv_entry->loc0);
}
/*-----------------------------------------------------------------------
| getChecksum returns the integer checksum value for this stanza. |
| The format of a checksum attribute in the input file is |
| checksum = "11804 2 " |
| so we need to extract the 11804 and convert it to integer. |
| Directory entries do not have a checksum so default to 0. |
-----------------------------------------------------------------------*/
getChecksum (char *stanza, char *value)
{
int checksum=0;
char cksumDigits[LENSIZE];
char *ptr = value;
if ( !getEntry ("checksum",stanza,value) && strlen (value) )
{
if ( strcmp(value, "VOLATILE") )
{
/*-------------------------------------------
| Skip leading non digit (") character and |
| copy. |
-------------------------------------------*/
while ( !isdigit(*ptr) )
ptr++;
strcpy (cksumDigits, ptr);
/*---------------------------------------------------
| Save only numeric characters in cksumDigits. |
---------------------------------------------------*/
ptr = cksumDigits;
while ( isdigit(*ptr) )
ptr++;
*ptr = '\0';
errno = 0;
if ( !(checksum = strtol (cksumDigits, NULL, 10)) && errno )
fatal (No_Checksum, errno, stanza);
}
}
return (checksum);
}
/*---------------------------------------
| Malloc with error checking. |
---------------------------------------*/
char *
xmalloc (int len)
{
char *cp;
if (cp = malloc ((unsigned) len))
{
memset ((void *) cp, 0, len);
return (cp);
}
else
fatal (Malloc_Error, errno);
}
/*-----------------------------------------------------------------------
| fatal accepts a variable length argument list which is a message |
| format string and any arguments to the error message. The arguments |
| are combined and displayed to stderr and fatal exits with a -1. |
-----------------------------------------------------------------------*/
void
fatal (va_alist)
{
va_list ap;
char *msgFormat;
fprintf (stderr,"%s: FATAL ERROR:\n",COMMANDNAME);
va_start(ap);
msgFormat = va_arg(ap, char *);
vfprintf (stderr, msgFormat, ap);
va_end(ap);
fprintf (stderr,"\n\tTerminating.\n");
exit (-1);
}
/*-----------------------------------------------------------------------
| warning accepts a variable length argument list which is a message |
| format string and any arguments to the warning message. The |
| arguments are combined and displayed to stderr. |
-----------------------------------------------------------------------*/
void
warning (va_alist)
{
va_list ap;
char *msgFormat;
int argno = 0;
fprintf (stderr,"%s: WARNING:\n",COMMANDNAME);
va_start(ap);
msgFormat = va_arg(ap, char *);
vfprintf (stderr, msgFormat, ap);
va_end(ap);
}