static char sccsid[] = "@(#)83 1.46 src/bldenv/pkgtools/adeinv.c, pkgtools, bos41J, 9516A_all 4/18/95 12:06:36"; /* * COMPONENT_NAME: PKGTOOLS * * FUNCTIONS: * checkSize * chktype * getDirectoryName * getInstDirs * getyp * main * openoutfiles * permTable * printLine * printMode * print_links * proclst * readlp * tableread * writeInvTcb * * * 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 #include #include #include #include #include "ade.h" #include "adeinventory.h" #include "acfList.h" void openoutfiles(char *, char *, char *, char *, char *, char *, char *); int readlp(char *, char *); void printLine (char *, int); void getDirectoryName (char *, char *, char); void getInstDirs (int, int); void print_links (InsEntry *, int); void printMode (InsEntry *, int); char *getyp(InsEntry *); /* *---------------------------------------------------- * External variable accessed in this module. *---------------------------------------------------- */ extern char *optarg; /* For cmdline option processing */ extern char **verbose_msgs ; /* Ptr to verbose message set */ extern char **default_msgs ; /* Ptr to default (short) msg set */ extern int errno; /* *----------------------------------------------------- * Global data available to other modules in adeinv. *----------------------------------------------------- */ char **msgArray ; /* Ptr to msg set to use */ char *commandName = NULL; /* *----------------------------------------------------- * Module level data. Some of this data could * reside inside main, but to allow error messages * access the information, it is at module level. *----------------------------------------------------- */ static char insfilename[MAXPATHLEN+1]; static char tablename[MAXPATHLEN+1]; /* *===================================================== * Function : Main * Purpose : *===================================================== */ main(int ac,char **av) { char lppFileName[MAXPATHLEN+1]; char lppOption[LPPNAMELEN+1]; char lppname[LPPNAMELEN+1]; char tcbFile[MAXPATHLEN+1]; /* Output file */ char invFile[MAXPATHLEN+1]; /* Output file */ char applyFile[MAXPATHLEN+1]; /* Output file */ char sizeFile[MAXPATHLEN+1]; /* Output file */ char xrefFile[MAXPATHLEN+1]; /* Output file */ char *outputDirectory; int rFlag=0,sFlag=0,DFlag=0,lFlag=0, updtFlag=0; int YFlag=0, bootFlag=0; int aFlag=0 ; int arg,i; FILE *insl_ptr; InsEntry insentry; int rc=ADE_SUCCESS; char *vrmf = NULL; msgArray = (char**)&default_msgs ; /* default messages @ 1st */ bzero (insfilename,MAXPATHLEN+1); bzero (lppFileName,MAXPATHLEN+1); bzero (lppname,LPPNAMELEN+1); outputDirectory = NULL; commandName = getCommandName( av[0] ); acfInit() ; while (( arg = getopt (ac, av, "a:d:t:s:i:l:rDLu:U:vY")) != EOF) { switch (arg) { case 'a': if (acfLoadFile(optarg) == ADE_ERROR) { /* *--------------------------------------------- * Inform user of error and give a usage * before aborting. *--------------------------------------------- */ inserror(msgArray[ACFloadError], optarg) ; usage() ; } aFlag++ ; break ; case 's': sFlag++; i = 0; shipPaths[i++] = strtok(optarg,":"); while ((shipPaths[i++] = strtok(NULL,":")) != (char *)NULL); num_paths = --i; break; case 'i': strcpy(insfilename,optarg); break; case 't': strcpy(tablename,optarg); permtable++; break; case 'l': strcpy (lppname, optarg); break; case 'u': strcpy (lppFileName, optarg); bootFlag=readlp(lppFileName,lppOption); break; case 'r': rFlag++; break; case 'D': DFlag++; break; case 'L': lFlag++; break; case 'U': updtFlag++; initHashTable(); vrmf = optarg; break; case 'd': outputDirectory = optarg; break; case 'v': msgArray = (char**)&verbose_msgs ; break ; case 'Y': YFlag++; break; case '?': usage(); break; } } /*------------------------------------------------------------------- | Verify that all required flags were provided on command line. | -------------------------------------------------------------------*/ if ( !sFlag || !insfilename[0] || !lppFileName[0] || !lppname[0] ) usage(); if ( rFlag && DFlag ) usage(); getInstDirs(rFlag,DFlag); dirList = listNew(); listInit (dirList); openoutfiles(lppOption, tcbFile, invFile, applyFile, sizeFile, xrefFile, outputDirectory); /*----------------------------------------------------------- * Don't write an xref file if this is for an update (vrmf * contains a string) or if processing the root part. * The xref file is written during usr processing. *----------------------------------------------------------- */ if ( strlen(vrmf) || rFlag ) { fclose (opxref_ptr); opxref_ptr = NULL; } if ( permtable ) { perm_ptr=fopen(tablename,"r"); if ( !perm_ptr ) { warning (msgArray[CantOpenTableFile], tablename); permtable=0; } } /*------------------------------------------------------------------- | Read each inslist entry and write to apply list, inventory file, | | tcb file ,size file and xref file . If -r flag specified, only | | process root files, which have a lower case type. | -------------------------------------------------------------------*/ fprintf (stderr,"\n"); insl_ptr = openFile(insfilename, "r"); while ( (i=readList (insl_ptr, &insentry, lFlag)) != EOF ) { if ( !i && opxref_ptr && !isaLink (insentry.type) ) fprintf(opxref_ptr,".%s %s\n", insentry.object_name,lppOption); if ( rFlag && isupper((int)insentry.type) ) continue; if ( !i ) rc |= proclst(&insentry, lppOption, lppname, rFlag, lFlag, updtFlag, vrmf, YFlag, aFlag); else rc |= i; } getInSize(lppOption, rFlag, DFlag, lppname, outputDirectory); /*----------------------------------------------------------- | Be sure tcb file is flushed before calling outSize. | | It will do a stat on the tcb file. | -----------------------------------------------------------*/ fflush (optcb_ptr); outSize(updtFlag, tcbFile, lppOption, bootFlag, rFlag); if (updtFlag) { if (acfWriteACF(TRUE) == ADE_ERROR) { inserror(msgArray[lppacfError]) ; rc |= ADE_ERROR ; } } fclose(opinv_ptr); fclose(opal_ptr); fclose(opsize_ptr); fclose(optcb_ptr); fclose(opxref_ptr); rc |= checkSize (invFile); rc |= checkSize (applyFile); rc |= checkSize (tcbFile); rc |= checkSize (sizeFile); exit(rc); } /*----------------------------------------------------------------------- | Open the inventory, tcb, size, and apply list files for this lpp | | option. | -----------------------------------------------------------------------*/ void openoutfiles (char *lppOption, char *tcbFile, char *invFile, char *applyFile, char *sizeFile, char *xrefFile, char *outDir) { int dirFlag = 0; if ( strlen(outDir) ) dirFlag++; if ( dirFlag ) { strcpy (invFile,outDir); strcat (invFile, "/"); strcat (invFile, lppOption); } else strcpy(invFile,lppOption); strcat(invFile,".inventory"); opinv_ptr = openFile(invFile,"w"); if ( dirFlag ) { strcpy (applyFile,outDir); strcat (applyFile, "/"); strcat (applyFile, lppOption); } else strcpy(applyFile,lppOption); strcat(applyFile,".al"); opal_ptr = openFile(applyFile,"w"); if ( dirFlag ) { strcpy (sizeFile,outDir); strcat (sizeFile, "/"); strcat (sizeFile, lppOption); } else strcpy(sizeFile,lppOption); strcat(sizeFile,".size"); opsize_ptr = openFile(sizeFile,"w"); if ( dirFlag ) { strcpy (tcbFile,outDir); strcat (tcbFile, "/"); strcat (tcbFile, lppOption); } else strcpy(tcbFile,lppOption); strcat(tcbFile,".tcb"); optcb_ptr = openFile(tcbFile,"w"); if ( dirFlag ) { strcpy (xrefFile,outDir); strcat (xrefFile, "/"); strcat (xrefFile, lppOption); } else strcpy(xrefFile,lppOption); strcat(xrefFile,".xref"); if ( strlen (xrefFile) ) opxref_ptr = openFile(xrefFile,"w"); else opxref_ptr = NULL; } /*--------------------------------------------------------------- | NAME: proclst | | DESCRIPTION: Main processing function for each inslist entry. | This function drives the generation of the output files | based on the inslist entry and command line parameters. | | PRE CONDITIONS: Command line checking has been performed. | insentry contains the inslist data from a syntactically valid | inslist file entry. | | POST CONDITIONS: The entry is written to the apply list, | inventory and tcb files as applicable. The size structures | are updated for each entry. | | PARAMETERS: insentry - pointer to inslist entry structure | lppOption - current option or fileset name | rFlag - set if -r flag was used on command line for | root processing | lFlag - set if -L flag was used on command line for | writing links to apply list | updtFlag - set if -U option was used on command line for | update mode | vrmf - set to current version.release.mod.fix level if | update mode was specified | YFlag - set if adeinv should ignore entries not found | in ship trees and continue processing | aFlag - set if the -a option was used to specify a user- | provided lpp.acf file | | NOTES: | | DATA STRUCTURES: insentry - structure containing inslist entry | data for an entry in the inslist file. | | RETURNS: 0 for success | non-zero for error -----------------------------------------------------------------*/ proclst(InsEntry *insentry, char *lppOption, char *lppname, int rFlag, int lFlag, int updtFlag, char *vrmf, int YFlag, int aFlag) { Fileinfo fileinfo; char cksum[512]; int tcb_sw=0; off_t filesize; char DirName[MAXPATHLEN+1]; int rc = 0; int i = 0; /*--------------------------------------------------------------- | Write a tcb file if the tcbflag is set or if the file is | SUID or SGID. ----------------------------------------------------------------*/ if ( (insentry->tcbflag == 'Y') || (insentry->mode & S_ISUID) || (insentry->mode & S_ISGID) ) tcb_sw++; fileinfo.file_fd = 0; if ( !chktype(insentry) && ((insentry->type != 'd') && (insentry->type != 'D')) ) { strcpy(fileinfo.filename, insentry->object_name); if (findfile(fileinfo.filename, shipPaths, num_paths, fileinfo.ship_name, &fileinfo.f_st.st, cksum) != 0) { warning(msgArray[FileNotFound], fileinfo.filename) ; bzero (cksum, 512); fileinfo.f_st.st.st_size=0; if ( YFlag ) return (0); else return (1); } } filesize=fileinfo.f_st.st.st_size; /* *----------------------------------------------------------------- * If no -r flag (processing usr part), all lower case object * names should be preceded by /usr/lpp//inst_root before * any entries are written to the output files. * If -U flag is set (vrmf is not 0 length), then we want to * change the path to include the vrmf_level and option in the * pathname, /usr/lpp//