This only works if the file isn't a symbolic link or in a directory that
is a symbolic link. The symbolic links are in the inventory.loc2 field
but since it's a vchar field you can't scan on it. So you wouldn't be
able to find /bin/ksh since /bin is a symbolic link to /usr/bin, or
/etc/ifconfig since it's a symbolic link to /usr/sbin/ifconfig, but you
can find /usr/bin/ksh and /usr/sbin/ifconfig.
Joe Seigh
the best way to find the LPP a file belongs to is
# odmget -q "loc0 = filename" inventory
get the number for the lpp_id and use it below
# odmget -q "lpp_id = number" lpp
for example:
# odmget -q "loc0 = /etc/motd" inventory
inventory:
lpp_id = 1
private = 0
file_type = 0
format = 1
loc0 = "/etc/motd"
loc1 = ""
loc2 = ""
size = 0
checksum = 0
# odmget -q "lpp_id = 1" lpp
lpp:
name = "bos.obj"
size = 0
state = 5
cp_flag = 19
group = ""
magic_letter = "I"
ver = 3
rel = 2
mod = 0
fix = 0
ptf = ""
description = "The Base Operating System"
lpp_id = 1
you could write a program to do this if you had a header file for the
software inventory vpd structures, but IBM doesn't supply one with the
AIX ditribution.
-------------------------------------------------------------------------------
Eric Siebert UNIX Systems Programmer Any opinions expressed are mine and
University of Chicago - NTCS are not necessarily shared by my
e-si...@uchicago.edu employer.
Joe Seigh
A couple of people have posted comprehensive methods of doing this, but
a shortcut that often works is
lslpp -cf all | grep -w <filename> | awk -F: '{print $2 "\t" $3}'
Michael Wojcik
Communications Product Group, Micro Focus Ltd.
Department of English, Miami University
Well, "lslpp -f" works very nicely. If you'd hit PF6 in smit to see the
actual command being executed, you'd have some idea of what manual
page to read, and therefore found that the lpp subsystem has _lots_
of options.
Otherwise, the _easiest_ (sorry, Eric :-) way to search is to
cd /usr/lpp
grep <filename_of_interest> */*.al
Each LPP directory contains an inventory file that you can search.
________________________________________________________________________
Gary R. Hook | "Yes, John, but when Pirates of
AIX Application Enabling | the Caribbean breaks down, the
IBM Corporation, Southlake, Texas | pirates don't eat the tourists."
The above opinions are all mine. | - the lawyer in "Jurassic Park"
I use the following script:
======================================================================
#!/bin/ksh
#
# shell script to tell you which "lpp" contains a particular file or directory
# syntax: whichlpp [path1] [path2] [path3] ... [pathN]
#
# All the spaces below are VERY important....
#
# Parentheses - ()
# Square brackets - []
# Curly brackets - {}
# Double quote - "
# Single quote - '
# Back single quote - `
# Forward slash - /
# Back slash - \
#
# For more information, see InfoExplorer and odmget, inventory, and lpp.
# -Mickey Coggins,
# with TONS of help from the *amazing* Stephan Langenfeld
ODMDIR=/usr/lib/objrepos
for FILENAME ; do
if [[ `basename $FILENAME` != $FILENAME ]] ; then
stanza=`odmget -q"loc0 = $FILENAME" inventory`
if [[ -z "$stanza" ]] ; then
echo "Couldn't find "$FILENAME" with an exact search."
echo "Try entering simply "\"`basename $FILENAME`\"
fi
else
stanza=`odmget -q"loc0 like */$FILENAME" inventory`
fi
stanza=`echo $stanza` # converts all newlines to spaces
# do it while some chars to process
while (( ${#stanza} > 1 )) ; do
# get right part of string,
# which is the last stanza in the list
tmpstanza=${stanza##*inventory:}
lpp_ids=${tmpstanza#*lpp_id = }
lpp_ids=${lpp_ids%% *}
names0=${tmpstanza#*loc0 = \"}
names0=${names0%%\"*}
names1=${tmpstanza#*loc1 = \"}
names1=${names1%%\"*}
names2=${tmpstanza#*loc2 = \"}
names2=${names2%%\"*}
for id in $lpp_ids ; do
name=`odmget -q"lpp_id = $id" lpp | grep name`
name=${name#*name = \"}
name=${name%%\"*}
echo lppname: $name
echo -n "location: $names0"
if [[ x$names1 != x ]] ; then
echo -n " hard links: $names1"
fi
if [[ x$names2 != x ]] ; then
echo -n " soft links: $names2"
fi
echo
done
# chop off the last entry in the list
stanza=${stanza%inventory:*}
done
done
:-) okay, easy but time consuming! . . . after Joe answered my
question about getting to the the SVPD ODM classes without source by
using odm_mount_class (guess i should've RTFM'ed. sorry! and thanks
Joe!), its pretty easy to whip up some code like:
/* lppwhence - so i have a penchant for the word "whence"
could probably use some cleaning up . . .
Eric Siebert
compile with
# cc -o lppwhence lppwhence.c -lodm
*/
#include <stdio.h>
#include <stdarg.h>
#include <swvpd.h>
#include <odmi.h>
#include <limits.h>
#include <errno.h>
void err_exit(const char *fmt, ...)
{
va_list p_args;
va_start(p_args, fmt);
vfprintf(stderr, fmt, p_args);
va_end(p_args);
exit(1);
}
void odmerr_exit()
{
char estr[256];
if (-1 == odm_err_msg(odmerrno, &estr))
err_exit("Unknown ODM error");
else
err_exit(estr);
}
short get_lpp_id(char *lstr)
{
CLASS_SYMBOL cl_inventory;
struct inventory *i_rec1;
struct inventory *i_rec2;
char q_str[MAX_INV_LOC0 + 10];
if (-1 == odm_set_path("/etc/objrepos"))
odmerr_exit();
if (-1 == (cl_inventory = odm_mount_class("inventory")))
odmerr_exit();
if (-1 == odm_open_class(cl_inventory))
odmerr_exit();
sprintf(q_str, "loc0 = %s", lstr);
if (-1 == (i_rec1 = odm_get_obj(cl_inventory, q_str, NULL, ODM_FIRST)))
odmerr_exit();
if (-1 == odm_close_class(cl_inventory))
odmerr_exit();
if (i_rec1 != NULL)
return(i_rec1->lpp_id);
if (-1 == odm_set_path("/usr/lib/objrepos"))
odmerr_exit();
if (-1 == (cl_inventory = odm_mount_class("inventory")))
odmerr_exit();
if (-1 == odm_open_class(cl_inventory))
odmerr_exit();
if (-1 == (i_rec2 = odm_get_obj(cl_inventory, q_str, NULL, ODM_FIRST)))
odmerr_exit();
odm_close_class(cl_inventory);
if (i_rec2 == NULL)
return(-1);
return(i_rec2->lpp_id);
}
void print_lpp_name(short lppid)
{
CLASS_SYMBOL cl_lpp;
struct lpp *l_rec1;
struct lpp *l_rec2;
char q_str[MAX_INV_LOC0 + 10];
if (-1 == odm_set_path("/etc/objrepos"))
odmerr_exit();
if (-1 == odm_open_class(cl_lpp))
odmerr_exit();
if (-1 == (cl_lpp = odm_mount_class("lpp")))
odmerr_exit();
sprintf(q_str, "lpp_id = %d", lppid);
if (-1 == (l_rec1 = odm_get_obj(cl_lpp, q_str, NULL, ODM_FIRST)))
odmerr_exit();
if (-1 == odm_close_class(cl_lpp))
odmerr_exit();
if (l_rec1 != NULL)
{
printf("%s\n", l_rec1->name);
return;
}
if (-1 == odm_set_path("/usr/lib/objrepos"))
odmerr_exit();
if (-1 == (cl_lpp = odm_mount_class("lpp")))
odmerr_exit();
if (-1 == odm_open_class(cl_lpp))
odmerr_exit();
if (-1 == (l_rec2 = odm_get_obj(cl_lpp, q_str, NULL, ODM_FIRST)))
odmerr_exit();
odm_close_class(cl_lpp);
if (l_rec2 != NULL)
printf("%s\n", l_rec2->name);
}
main(int argc, char *argv[])
{
char pbuf[PATH_MAX];
if (argc < 2)
err_exit("Usage: lppwhence filename\n");
/* see if its a link - only goes one deep */
if (-1 != readlink(argv[1], pbuf, PATH_MAX))
printf("following link to %s\n", pbuf);
else
{
if (EINVAL == errno)
strncpy(pbuf, argv[1], strlen(argv[1]));
else
err_exit("error reading link for %s (errno %d)\n", argv[1], errno);
}
odm_initialize();
print_lpp_name(get_lpp_id(pbuf));
odm_terminate();
jim
In article <34fer8$d...@sun2.ruf.uni-freiburg.de>
borr...@ibm1.ruf.uni-freiburg.de (H.G.Borrmann) writes:
> I use the following script:
> ======================================================================
> #!/bin/ksh
> #
> # shell script to tell you which "lpp" contains a particular file or
directory
> # syntax: whichlpp [path1] [path2] [path3] ... [pathN]
> #
> # All the spaces below are VERY important....
> #
> # Parentheses - ()
> # Square brackets - []
> # Curly brackets - {}
> # Double quote - "
> # Single quote - '
> # Back single quote - `
> # Forward slash - /
> # Back slash - \
> #
> # For more information, see InfoExplorer and odmget, inventory, and lpp.
> # -Mickey Coggins,
> # with TONS of help from the *amazing* Stephan Langenfeld
>
> ODMDIR=/usr/lib/objrepos
Add the loop here:
for odmdir in /usr/lib/objrepos /etc/objrepos /usr/share/lib/objrepos; do
ODMDIR=$odmdir
.....
done
Now if you do a (for example) "whichlpp spool" you should see a little more
information.
--
Jim Salter FirePower Systems, Inc.
jsa...@firepower.com (415) 462-3077