This is os-aix.c in view mode; [Download] [Up]
/* * Copyright (c) 1992 Michael A. Cooper. * This software may be freely distributed provided it is not sold for * profit and the author is credited appropriately. */ #ifndef lint static char *RCSid = "$Header: /src/common/usc/bin/sysinfo/RCS/os-aix.c,v 1.15 1992/12/12 23:48:04 mcooper Exp mcooper $"; #endif /* * $Log: os-aix.c,v $ * Revision 1.15 1992/12/12 23:48:04 mcooper * Call MkDevName() with correct number of parameters. * * Revision 1.14 1992/12/12 23:18:58 mcooper * Only print unknown VPD in Debug mode. * * Revision 1.13 1992/11/30 01:27:55 mcooper * Print unknown VPD info. * * Revision 1.12 1992/11/30 01:19:04 mcooper * Add support for looking up VPD from CuVPD. * * Revision 1.11 1992/11/24 01:57:19 mcooper * Change GetKernelVersionStr() to NOOP. * * Revision 1.11 1992/11/24 01:57:19 mcooper * Change GetKernelVersionStr() to NOOP. * * Revision 1.10 1992/11/24 00:54:19 mcooper * Fix buffer problem with GetDescript(). * * Revision 1.9 1992/11/24 00:51:07 mcooper * Make NLS catalog lookups more robust. * * Revision 1.8 1992/11/23 23:23:51 mcooper * Get amount of real memory from ODM CuAt. * * Revision 1.7 1992/11/23 22:53:02 mcooper * Get system model name from ODM CuAt. * * Revision 1.6 1992/11/21 04:32:38 mcooper * Add device support using ODM. * * Revision 1.5 1992/04/26 23:32:06 mcooper * Add Copyright notice * * Revision 1.4 1992/04/17 23:27:51 mcooper * Add support for ROM Version information (Sun only for now). * * Revision 1.3 1992/04/17 01:07:59 mcooper * More de-linting * * Revision 1.2 1992/04/15 02:04:16 mcooper * Change GetMemoryStr() to GetMemory(). * * Revision 1.1 1992/03/28 23:57:38 mcooper * Initial revision * */ /* * AIX specific functions */ #include <stdio.h> #include "system.h" #include "defs.h" #include "info-aix.h" #include <nl_types.h> #include <locale.h> /* * Get ODM Error string. */ static char *odmerror() { static char odmerrstr[BUFSIZ]; if (odm_err_msg(odmerrno, &odmerrstr) != 0) (void) sprintf(odmerrstr, "unknown ODM error %d", odmerrno); return(odmerrstr); } /* * Get the value of attribute 'Attr' with name 'Name' * from the Custom Attribute ODM. */ static char *GetAttrVal(Name, Attr) char *Name; char *Attr; { static struct CuAt CuAt; static char buff[BUFSIZ]; char *errstr = NULL; int ret; if (odm_initialize() == -1) { Error("ODM initialize failed: %s", odmerror()); return(-1); } (void) sprintf(buff, "attribute = '%s' and name = '%s'", Attr, Name); ret = (int) odm_get_obj(CuAt_CLASS, buff, &CuAt, ODM_FIRST); if (ret == -1) errstr = odmerror(); else if (ret == 0) errstr = "No entry found"; if (errstr) { if (Debug) Error("ODM get \"%s\" from \"%s\" failed: %s", buff, CuAt_CLASS[0].classname, errstr); return((char *) NULL); } return((CuAt.value[0]) ? CuAt.value : (char *) NULL); } /* * Get the PvDv ODM entry with the criteria 'Criteria'. */ static struct PdDv *GetPdDv(Criteria) char *Criteria; { static struct PdDv PdDv; char *errstr = NULL; int ret; if (odm_initialize() == -1) { Error("ODM initialize failed: %s", odmerror()); return((struct PdDv *) NULL); } ret = (int) odm_get_obj(PdDv_CLASS, Criteria, &PdDv, ODM_FIRST); if (ret == -1) errstr = odmerror(); else if (ret == 0) errstr = "No entry found"; if (errstr) { if (Debug) Error("ODM get \"%s\" from \"%s\" failed: %s", Criteria, PdDv_CLASS[0].classname, errstr); return((struct PdDv *) NULL); } return(&PdDv); } /* * Clean up a VPD string. Remove initial non alpha-numeric characters * as well as any trailing white space. */ static char *CleanVPD(string) char *string; { register char *cp, *end; while (string && *string && !isalnum(*string)) ++string; cp = end = &string[strlen(string) - 1]; while (cp && *cp && isspace(*cp)) --cp; if (cp != end) *(cp+1) = C_NULL; return(string); } /* * Find the VPD info entry for "string". Return a vpdinfo_t * entry for the matching entry and set it's "value" correctly. */ static vpdinfo_t *GetVPDinfo(string) char *string; { extern vpdinfo_t VPDinfo[]; static char buff[BUFSIZ]; static vpdinfo_t vpdinfo; register int i; for (i = 0; VPDinfo[i].code; ++i) { if (strncasecmp(string, VPDinfo[i].code, strlen(VPDinfo[i].code))) continue; vpdinfo.code = VPDinfo[i].code; vpdinfo.title = VPDinfo[i].title; /* * The "value" portion of "string" starts after the "code" portion. * CleanVPD() is harmful, so we need to pass it a private copy. */ (void) strcpy(buff, string + strlen(VPDinfo[i].code)); vpdinfo.value = CleanVPD(buff); return(&vpdinfo); } if (Debug) printf("Unknown VPD info \"%s\".\n", string); return((vpdinfo_t *) NULL); } /* * Given a VPD string "vpdstr", decode it into a list of strings. */ static char **DecodeVPD(vpdstr) char *vpdstr; { static char buff[BUFSIZ]; char *myvpdstr; register char *cp; vpdinfo_t *vpdinfo; char **list; int count; if (!vpdstr) return((char **) NULL); /* * Count number of fields and allocate list accordingly. */ for (count = 1; cp; cp = index(++cp, '*')); list = (char **) xcalloc(count + 1, sizeof(char *)); list[0] = NULL; /* strtok() is destructive */ myvpdstr = strdup(vpdstr); /* * Each field in "vpdstr" is seperated by a "*", followed by * the code for the field and it's value. Looks something like: * * *TM 19445*MF IBM */ for (count = 0, cp = strtok(myvpdstr, "*"); cp; cp = strtok((char *)NULL, "*")) { if (!(vpdinfo = GetVPDinfo(cp))) continue; (void) sprintf(buff, "%s is %s", vpdinfo->title, vpdinfo->value); list[count++] = strdup(buff); list[count] = (char *) NULL; } if (myvpdstr) (void) free(myvpdstr); return(list); } /* * Get and decode the Vital Product Data informatin for device "Name". */ static char **GetVPD(Name) char *Name; { static struct CuVPD cuvpd; static char buff[BUFSIZ]; int ret; if (odm_initialize() == -1) { Error("ODM initialize failed: %s", odmerror()); return((char *) NULL); } (void) sprintf(buff, "name=%s", Name); ret = (int) odm_get_obj(CuVPD_CLASS, buff, &cuvpd, ODM_FIRST); if (ret == -1) { if (Debug) Error("ODM get VPD object for \"%s\" failed: %s", Name, odmerror()); return((char **) NULL); } else if (ret == 0) { if (Debug) Error("No VPD information for \"%s\".", Name); return((char **) NULL); } if (Debug) printf("VPD: name = '%s' type = %d VPD = '%s'\n", cuvpd.name, cuvpd.vpd_type, cuvpd.vpd); return(DecodeVPD(cuvpd.vpd)); } /* * Get the system model name. */ extern char *GetModelName() { extern NAMETAB ModelTab[]; register char *val, *cp; register int i, type; if ((val = GetAttrVal(NN_SYS0, AT_MODELCODE)) == NULL) { if (Debug) Error("Cannot get \"%s\" for \"%s\" from ODM.", AT_MODELCODE, NN_SYS0); return((char *) NULL); } type = (int) strtol(val, NULL, 0); if (Debug) printf("System type = 0x%x\n", type); for (i = 0; ModelTab[i].name; ++i) if (type == ModelTab[i].value) return(ModelTab[i].name); if (Debug) Error("system model/type 0x%x is unknown.", type); return((char *) NULL); } /* * Get kernel version string. */ extern char *GetKernelVersionStr() { /* No such thing in AIX */ return((char *) NULL); } /* * Get amount of physical memory from the ODM CuAt data. */ extern char *GetMemory() { register char *val; register int amtval; static char buff[BUFSIZ]; if ((val = GetAttrVal(NN_SYS0, AT_REALMEM)) == NULL) { if (Debug) Error("Cannot get \"%s\" for \"%s\" from ODM.", AT_REALMEM, NN_SYS0); return((char *) NULL); } amtval = (int) strtol(val, NULL, 0); (void) sprintf(buff, "%d MB", DivRndUp(amtval, KBYTES)); return(buff); } /* * Get system serial number */ extern char *GetSerialNoStr() { /* No support */ return((char *) NULL); } /* * Get name of OS */ extern char *GetOSNameStr() { return(GetOSNameFromUname()); } /* * Get version of OS */ extern char *GetOSVersionStr() { return(GetOSVersionFromUname()); } /* * Get ROM Version */ extern char *GetRomVer() { /* No support */ return((char *) NULL); } /* * Take a device name, remove and then return the unit number. * e.g. Take "hdisk0", remove "0", and then return 0. */ static int GetUnit(Name) char *Name; { int unit; register char *cp; for (cp = Name; cp && *cp; ++cp) if (isdigit(*cp)) { unit = (int) atoi(cp); *cp = C_NULL; return(unit); } return(-1); } /* * Get the location information from CuDvPtr. */ static char *GetLocation(CuDvPtr) struct CuDv *CuDvPtr; { static char buff[BUFSIZ]; if (CuDvPtr->location[0]) { (void) sprintf(buff, "Location is %s", CuDvPtr->location); return(buff); } return((char *) NULL); } /* * Get Class information. */ static char *GetClassInfo(CuDvPtr) struct CuDv *CuDvPtr; { static char buff[BUFSIZ]; if (CuDvPtr->PdDvLn_Lvalue[0]) { (void) sprintf(buff, "Class/SubClass/Type is %s", CuDvPtr->PdDvLn_Lvalue); return(buff); } return((char *) NULL); } /* * Set the description informatin for Device. */ static void SetDescript(Device, CuDvPtr) DEVICE *Device; struct CuDv *CuDvPtr; { register char *cp; register char **cpp; char **vpdlist; char **list; char *loc = NULL, *class = NULL; register int listc; /* * Get the info to be composed */ loc = GetLocation(CuDvPtr); class = GetClassInfo(CuDvPtr); vpdlist = GetVPD(Device->dv_name); /* * Count the number of entries and allocate list accordingly */ for (listc = 0; vpdlist && vpdlist[listc]; ++listc); if (loc) ++listc; if (class) ++listc; list = (char **) xcalloc(listc + 1, sizeof(char *)); /* * Add the easy entries first */ listc = 0; if (loc) list[listc++] = strdup(loc); if (class) list[listc++] = strdup(class); /* * Add each VPD item */ for (cpp = vpdlist; cpp && *cpp; ++cpp) if (*cpp) list[listc++] = *cpp; if (vpdlist) (void) free(vpdlist); if (list && list[0]) Device->dv_desclist = list; } /* * Special routine to get memory information. */ extern DEVICE *ProbeMemory(Name, DevData, DevDataTab, CuDvPtr, PdDvPtr) /*ARGSUSED*/ char *Name; DEVDATA *DevData; DEVDATATAB *DevDataTab; struct CuDv *CuDvPtr; struct PdDv *PdDvPtr; { DEVICE *device; char *devname; char *cp; char buff[BUFSIZ]; if ((cp = GetAttrVal(Name, AT_SIZE)) == NULL) return((DEVICE *) NULL); device = NewDevice((DEVICE *) NULL); (void) sprintf(buff, "%s MB Memory Card", cp); device->dv_model = strdup(buff); device->dv_name = Name; device->dv_unit = DevData->dd_devunit; device->dv_master = MkMasterFromDevData(DevData); device->dv_type = DT_MEMORY; SetDescript(device, CuDvPtr); return(device); } /* * Get description information */ static char *GetDescript(CuDvPtr, PdDvPtr) struct CuDv *CuDvPtr; struct PdDv *PdDvPtr; { static char buff[BUFSIZ]; static char lastcat[BUFSIZ]; static nl_catd catd; char *msg = NULL; char *cp; if (!PdDvPtr->catalog[0]) return((char *) NULL); /* * Reuse open catalog if it's the same as the last time */ if ((int) catd <= 0 || !lastcat[0] || strcmp(PdDvPtr->catalog, lastcat)) { if ((int) catd > 0) (void) catclose(catd); if ((int) catd == 0) { /* * First time stuff. */ if (putenv(ENV_NLSPATH) != 0) if (Debug) Error("Cannot set environment $NLSPATH."); /* * If our LANG is "C", then set to our default in order to * avoid a bug in AIX that fails to find any catalogs in * this case. */ cp = getenv("LANG"); if (!cp || (cp && EQ(cp, "C"))) { (void) sprintf(buff, "LANG=%s", DEFAULT_LANG); if (putenv(strdup(buff)) != 0) if (Debug) Error("Cannot set environment %s.", buff); buff[0] = C_NULL; } (void) setlocale(LC_ALL, ""); } catd = catopen(PdDvPtr->catalog, 0); if ((int) catd <= 0) if (Debug) Error("Catalog open of \"%s\" failed: %s.", PdDvPtr->catalog, SYSERR); } /* * Retrieve the message from the catalog */ if ((int) catd > 0) { msg = catgets(catd, PdDvPtr->setno, PdDvPtr->msgno, buff); /* Save catalog name */ (void) strcpy(lastcat, PdDvPtr->catalog); } return((msg && *msg) ? msg : (char *) NULL); } /* * General routine to get device information from ODM. */ extern DEVICE *ProbeODM(DevData, TreePtr, CuDvPtr) /*ARGSUSED*/ DEVDATA *DevData; DEVICE **TreePtr; struct CuDv *CuDvPtr; { register DEVDATATAB *pddt; DEVICE *device; char *devname; char *desc; char *cp; static char buff[BUFSIZ]; struct PdDv *PdDvPtr; devname = MkDevName(DevData->dd_devname, DevData->dd_devunit, 0, 0); if (FindDeviceByName(devname, *TreePtr)) { if (Debug) printf("Device %s already exists.\n", devname); return((DEVICE *) NULL); } if (CuDvPtr->PdDvLn_Lvalue[0]) { (void) sprintf(buff, "uniquetype='%s'", CuDvPtr->PdDvLn_Lvalue); PdDvPtr = GetPdDv(buff); } else { if (Debug) Error("No PdDv link value for '%s'.", devname); return((char *) NULL); } /* * If we can't get the description for this device, then * use the device specific probe routine if one is defined. */ if ((desc = GetDescript(CuDvPtr, PdDvPtr)) == (char *) NULL) { if ((pddt = GetDevDataTab(DevData->dd_devname)) && pddt->ddt_probe) return((*pddt->ddt_probe)(devname, DevData, pddt, CuDvPtr, PdDvPtr)); else { if (Debug) Error("No description found for '%s'.", devname); return((DEVICE *) NULL); } } device = NewDevice((DEVICE *) NULL); device->dv_name = devname; device->dv_unit = DevData->dd_devunit; device->dv_master = MkMasterFromDevData(DevData); device->dv_type = DT_GENERIC; device->dv_model = strdup(desc); SetDescript(device, CuDvPtr); return(device); } /* * Build device tree by looking at the Object Database Manager (ODM) */ static int BuildODM(TreePtr) DEVICE **TreePtr; { static struct CuDv CuDv; extern struct Class CuDv_CLASS[]; static DEVDATA DevData; DEVICE *Dev; int op, ret; if (odm_initialize() == -1) { Error("ODM initialize failed: %s", odmerror()); return(-1); } for (op = ODM_FIRST; ; op = ODM_NEXT) { /* * Retrieve the object from ODM. */ ret = (int) odm_get_obj(CuDv_CLASS, (char *)NULL, &CuDv, op); if (ret == -1) { if (Debug) Error("ODM get object \"%s\" failed: %s", CuDv_CLASS[0].classname, odmerror()); return(-1); } else if (ret == 0) /* * We're done */ break; if (CuDv.status != AVAILABLE) { if (Debug) printf("Device \"%s\" is not available.\n", CuDv.name); continue; } /* * This should never happen */ if (CuDv.name[0] == C_NULL) continue; /* Make sure devdata is clean */ bzero(&DevData, sizeof(DEVDATA)); /* Set what we know */ DevData.dd_devname = strdup(CuDv.name); DevData.dd_devunit = GetUnit(DevData.dd_devname); if (CuDv.parent[0]) { DevData.dd_ctlrname = strdup(CuDv.parent); DevData.dd_ctlrunit = GetUnit(DevData.dd_ctlrname); } DevData.dd_flags |= DD_IS_ALIVE; if (Debug) printf("ODM: Found '%s' parent '%s' location '%s' uniq = '%s'\n", CuDv.name, CuDv.parent, CuDv.location, CuDv.PdDvLn_Lvalue); /* Probe and add device */ if (Dev = ProbeODM(&DevData, TreePtr, &CuDv)) AddDevice(Dev, TreePtr); } if (odm_terminate() != 0) if (Debug) Error("ODM Terminate did not succeed."); return(0); } /* * Build device tree using TreePtr. * Calls bus and method specific functions to * search for devices. */ extern int BuildDevicesAIX(TreePtr) DEVICE **TreePtr; { int Found = 1; if (BuildODM(TreePtr) == 0) Found = 0; return(Found); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.