[Info-vax] Non-portable code
Marc Van Dyck
marc.vandyck at brutele.be
Thu Jan 7 13:34:05 EST 2010
Jan-Erik Söderholm formulated on mercredi :
>
> Just so it's fully understood...
>
> Why not simply use ANALYZE/IMAGE ?
> What extra does your Pascal program give ?
This program is used to get the version of layered products, tools,
etc,
that are installed on our systems. It uses a reference file (idea
copied
from a layered product named Polycenter System Census that briefly
existed about 15 years ago) associating an executable image for each
of the layered products or tool we are using. The program is integrated
in DCL, you just type, for example "$ version acms" and it will return
a line "ACMS ACMS V5.1", getting the information from
the
executable associated to ACMS (in this case ACMSBOOT.EXE) in the
reference file. Wildcarding is supported, so typing "$ version *" will
return the version of all products installed on the system. We use it
for our configuration management : the lists for each system are
assembled in an excel file to provide comparisons possibilities, and
we also load the same info in the configuration database of HP
Openview Service Desk. I also added a /SYMBOL qualifier, so that you
could type "$ version acms /symbol=acms_ident" way before ANAL/IMAGE
had it. Now this is buried everywhere in our management procedures and
it is far easier for me to continue maintaining it (not counting the
fun of doing it) rather than make changes everywhere...
Here is the modified code that allows me to call it from Pascal. The
modifications mainly consisted in removing all printing, transforming
the main program into a function, returning SS*_NORMAL if ok or the
error code otherwise, and passing parameters via [class_s] descriptors.
Had to play a little bit with null-terminated strings to make fopen
work as expected...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ssdef.h>
#include <elfdef.h>
#include <descrip.h>
static void decode_note_entries (char *section, int size) ;
static const char magic_plus[] = {
EHDR$K_ELFMAG0, EHDR$K_ELFMAG1, EHDR$K_ELFMAG2, EHDR$K_ELFMAG3,
EHDR$K_ELFCLASS64, EHDR$K_ELFDATA2LSB } ;
#define MAX_STR_LEN 255
static char img_id[MAX_STR_LEN + 1];
static char image[MAX_STR_LEN + 1];
int get_id(struct dsc$descriptor_s *image_desc, struct dsc$descriptor_s
*img_id_desc) {
FILE *fd ;
ELF64_EHDR the_elf_header ;
ELF64_SHDR *sh = NULL ;
char *section = NULL ;
int i ;
if (image_desc->dsc$w_length > MAX_STR_LEN) {
return SS$_BADPARAM;
}
memset(image, 0, MAX_STR_LEN);
memcpy(image, image_desc->dsc$a_pointer,
image_desc->dsc$w_length);
fd = fopen (image, "rb") ;
if (!fd) {
return vaxc$errno;
}
if (fseek(fd, 0, SEEK_SET)!=0) {
return vaxc$errno;
}
if (fread(&the_elf_header, sizeof the_elf_header, 1, fd)!=1) {
return vaxc$errno;
}
if (0!=strncmp((char*)&the_elf_header.ehdr$t_e_ident, magic_plus,
sizeof magic_plus-1)) {
fclose (fd) ;
return SS$_BADIMGHDR;
}
sh = (ELF64_SHDR*) malloc (sizeof *sh
*the_elf_header.ehdr$w_e_shnum) ;
if (fseek(fd, the_elf_header.ehdr$q_e_shoff, SEEK_SET)!=0) {
return vaxc$errno;
}
if (fread(sh, sizeof *sh*the_elf_header.ehdr$w_e_shnum, 1, fd)!=1)
{
return vaxc$errno;
}
for (i=1; i<the_elf_header.ehdr$w_e_shnum; i++)
if (sh[i].shdr$l_sh_type==SHDR$K_SHT_NOTE) {
section = malloc (sh[i].shdr$q_sh_size) ;
if (fseek(fd, sh[i].shdr$q_sh_offset, SEEK_SET)!=0) {
return vaxc$errno;
}
if (fread(section, sh[i].shdr$q_sh_size, 1, fd)!=1) {
return vaxc$errno;
}
decode_note_entries (section, sh[i].shdr$q_sh_size) ;
break ;
}
if (strlen(img_id) > img_id_desc->dsc$w_length) {
return SS$_BADPARAM;
}
strncpy(img_id_desc->dsc$a_pointer, img_id, strlen(img_id));
img_id_desc->dsc$w_length = strlen(img_id);
fclose(fd)!=0;
return SS$_NORMAL;
}
static void decode_note_entries (char *section, int size) {
ELF64_NHDR *nh ;
for (nh = (ELF64_NHDR*)section ; (char*)nh-section<size ;
nh=(ELF64_NHDR*)((char*)nh+sizeof(ELF64_NHDR)+((nh->nhdr$q_nh_namesz+7)&~7)+((nh->nhdr$q_nh_descsz+7)&~7)))
{
if (nh->nhdr$q_nh_descsz>0) {
if (nh->nhdr$q_nh_type == NHDR$K_NT_VMS_IMGID) {
strncpy(img_id,
(char*)nh+sizeof(ELF64_NHDR)+((nh->nhdr$q_nh_namesz+7)&~7),
MAX_STR_LEN);
}
}
}
}
--
Marc Van Dyck
More information about the Info-vax
mailing list