Date: Sun, 21 Aug 2005 13:14:40 GMT From: Victor Cruceru <soc-victor@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 82370 for review Message-ID: <200508211314.j7LDEeVD038848@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=82370 Change 82370 by soc-victor@soc-victor_82.76.158.176 on 2005/08/21 13:14:13 Finished the SNMP instrumentation for hrPrinterTable. Still need to test it using my dusty parallel printer... Affected files ... .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile#22 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c#9 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_diskstorage_tbl.c#8 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_network_tbl.c#4 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_printer_tbl.c#2 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.h#25 edit Differences ... ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile#22 (text+ko) ==== @@ -29,9 +29,12 @@ CONTRIB=${.CURDIR}/../../../../contrib/bsnmp MOD= hostres -SRCS= hostres_snmp.c hostres_scalars.c \ - hostres_storage_tbl.c hostres_fs_tbl.c \ - hostres_swrun_tbl.c hostres_swrunperf_tbl.c \ +SRCS= hostres_snmp.c \ + hostres_scalars.c \ + hostres_storage_tbl.c \ + hostres_fs_tbl.c \ + hostres_swrun_tbl.c\ + hostres_swrunperf_tbl.c \ hostres_device_tbl.c \ hostres_processor_tbl.c \ hostres_diskstorage_tbl.c \ ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c#9 (text+ko) ==== @@ -201,7 +201,7 @@ return (DS_DOWN); case DIS_ATTACHED: /* attach method called */ case DIS_BUSY: /* device is open */ - return (DR_RUNNING); + return (DS_RUNNING); default: return (DS_UNKNOWN); } ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_diskstorage_tbl.c#8 (text+ko) ==== @@ -312,7 +312,7 @@ entry->type = (struct asn_oid)OIDX_hrDeviceDiskStorage; entry->id = oid_zeroDotZero; /*unknown id - FIX ME*/ - entry->status = DR_RUNNING; + entry->status = DS_RUNNING; entry->errors = 0; /*FIX ME*/ snprintf(entry->descr, sizeof(entry->descr) - 1, "%s: <%s, ser. %s> ", @@ -531,7 +531,7 @@ entry->type = (struct asn_oid)OIDX_hrDeviceDiskStorage; entry->id = oid_zeroDotZero; /*unknown id - FIX ME*/ - entry->status = DR_RUNNING; + entry->status = DS_RUNNING; entry->errors = 0; /*FIX ME*/ snprintf(entry->descr, sizeof(entry->descr) - 1, "%s: Memory Disk ", @@ -639,7 +639,7 @@ entry->flags |= HR_DEVICE_IMMUTABLE; entry->type = (struct asn_oid)OIDX_hrDeviceDiskStorage; entry->id = oid_zeroDotZero; /*unknown id - FIX ME*/ - entry->status = DR_RUNNING; + entry->status = DS_RUNNING; entry->errors = 0; /*FIX ME*/ snprintf(entry->descr, sizeof(entry->descr) - 1, "%s: Disk Storage", ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_network_tbl.c#4 (text+ko) ==== @@ -323,7 +323,7 @@ dev_entry->flags |= HR_DEVICE_IMMUTABLE; dev_entry->type = (struct asn_oid)OIDX_hrDeviceNetwork; dev_entry->id = oid_zeroDotZero; /*unknown id - FIX ME*/ - dev_entry->status = DR_RUNNING; + dev_entry->status = DS_RUNNING; dev_entry->errors = 0; /*FIX ME*/ snprintf(dev_entry->descr, sizeof(dev_entry->descr) - 1, "%s: Network device", ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_printer_tbl.c#2 (text+ko) ==== @@ -77,6 +77,8 @@ #include <unistd.h> #include <assert.h> #include <paths.h> +#include <syslog.h> +#include <err.h> #define _PATH_PRINTCAP "/etc/printcap" #define _PATH_DEFDEVLP "/dev/lp" @@ -104,44 +106,26 @@ #define DEFUID 1 #define DEFTIMEOUT 120 - struct printer { +struct printer { char *printer; /* printer name */ int remote; /* true if RM points to a remote host */ int rp_matches_local; /* true if rp has same name as us */ - int tof; /* true if we are at top-of-form */ - /* ------------------------------------------------------ */ - char *acct_file; /* AF: accounting file */ - long baud_rate; /* BR: baud rate if lp is a tty */ - long conn_timeout; /* CT: TCP connection timeout */ - long daemon_user; /* DU: daemon user id -- XXX belongs ???? */ - char *form_feed; /* FF: form feed */ - long header_last; /* HL: print header last */ + char *log_file; /* LF: log file */ char *lock_file; /* LO: lock file */ char *lp; /* LP: device name or network address */ - long max_copies; /* MC: maximum number of copies allowed */ - long max_blocks; /* MX: maximum number of blocks to copy */ - long price100; /* PC: price per 100 units of output */ - long page_length; /* PL: page length */ - long page_width; /* PW: page width */ - long page_pwidth; /* PX: page width in pixels */ - long page_plength; /* PY: page length in pixels */ - long resend_copies; /* RC: resend copies to remote host */ - char *restrict_grp; /* RG: restricted group */ + char *remote_host; /* RM: remote machine name */ char *remote_queue; /* RP: remote printer name */ long restricted; /* RS: restricted to those with local accts */ long rw; /* RW: open LP for reading and writing */ - long short_banner; /* SB: short banner */ - long no_copies; /* SC: suppress multiple copies */ + char *spool_dir; /* SD: spool directory */ - long no_formfeed; /* SF: suppress FF on each print job */ - long no_header; /* SH: suppress header page */ + char *stat_recv; /* SR: statistics file, receiving jobs */ char *stat_send; /* SS: statistics file, sending jobs */ char *status_file; /* ST: status file name */ - char *trailer; /* TR: trailer string send when Q empties */ - char *mode_set; /* MS: mode set, a la stty */ + }; @@ -150,11 +134,11 @@ */ + static char *capdb_canonical_name(const char *_bp); static int capdb_getaltlog(char *_bp, const char *_shrt, const char *_lng); -static int capdb_getaltnum(char *_bp, const char *_shrt, - const char *_lng, long _dflt, long *_result); + static int capdb_getaltstr(char *_bp, const char *_shrt, const char *lng, const char *_dflt, char **_result); static int getprintcap_int(char *_bp, struct printer *_pp); @@ -173,6 +157,21 @@ const char *pcaperr(int error); +extern +struct hrDeviceTblEntry* +hrDeviceTblEntry_find_by_name(const char *dev_name); + + +extern +struct hrDeviceTblEntry * +hrDeviceTblEntry_find_by_index(int32_t idx); + + + +extern +void +hrDeviceTblEntry_delete_v( struct hrDeviceTblEntry* entry ); + /* * Read the printcap database for printer `printer' into the @@ -321,30 +320,16 @@ return PCAPERR_OSERR; #define CHK(x) do {if ((x) == PCAPERR_OSERR) return PCAPERR_OSERR;}while(0) - CHK(capdb_getaltstr(bp, "af", "acct.file", 0, &pp->acct_file)); - CHK(capdb_getaltnum(bp, "br", "tty.rate", 0, &pp->baud_rate)); - CHK(capdb_getaltnum(bp, "ct", "remote.timeout", DEFTIMEOUT, - &pp->conn_timeout)); - CHK(capdb_getaltnum(bp, "du", "daemon.user", DEFUID, - &pp->daemon_user)); - CHK(capdb_getaltstr(bp, "ff", "job.formfeed", DEFFF, &pp->form_feed)); + + + CHK(capdb_getaltstr(bp, "lf", "spool.log", _PATH_CONSOLE, &pp->log_file)); CHK(capdb_getaltstr(bp, "lo", "spool.lock", DEFLOCK, &pp->lock_file)); CHK(capdb_getaltstr(bp, "lp", "tty.device", _PATH_DEFDEVLP, &pp->lp)); - CHK(capdb_getaltnum(bp, "mc", "max.copies", DEFMAXCOPIES, - &pp->max_copies)); - CHK(capdb_getaltstr(bp, "ms", "tty.mode", 0, &pp->mode_set)); - CHK(capdb_getaltnum(bp, "mx", "max.blocks", DEFMX, &pp->max_blocks)); - CHK(capdb_getaltnum(bp, "pc", "acct.price", 0, &pp->price100)); - CHK(capdb_getaltnum(bp, "pl", "page.length", DEFLENGTH, - &pp->page_length)); - CHK(capdb_getaltnum(bp, "pw", "page.width", DEFWIDTH, - &pp->page_width)); - CHK(capdb_getaltnum(bp, "px", "page.pwidth", 0, &pp->page_pwidth)); - CHK(capdb_getaltnum(bp, "py", "page.plength", 0, &pp->page_plength)); - CHK(capdb_getaltstr(bp, "rg", "daemon.restrictgrp", 0, - &pp->restrict_grp)); + + + CHK(capdb_getaltstr(bp, "rm", "remote.host", 0, &pp->remote_host)); CHK(capdb_getaltstr(bp, "rp", "remote.queue", DEFLP, &pp->remote_queue)); @@ -354,17 +339,12 @@ CHK(capdb_getaltstr(bp, "ss", "stat.send", 0, &pp->stat_send)); CHK(capdb_getaltstr(bp, "st", "spool.status", DEFSTAT, &pp->status_file)); - CHK(capdb_getaltstr(bp, "tr", "job.trailer", 0, &pp->trailer)); - pp->resend_copies = capdb_getaltlog(bp, "rc", "remote.resend_copies"); pp->restricted = capdb_getaltlog(bp, "rs", "daemon.restricted"); - pp->short_banner = capdb_getaltlog(bp, "sb", "banner.short"); - pp->no_copies = capdb_getaltlog(bp, "sc", "job.no_copies"); - pp->no_formfeed = capdb_getaltlog(bp, "sf", "job.no_formfeed"); - pp->no_header = capdb_getaltlog(bp, "sh", "banner.disable"); - pp->header_last = capdb_getaltlog(bp, "hl", "banner.last"); + + pp->rw = capdb_getaltlog(bp, "rw", "tty.rw"); - pp->tof = !capdb_getaltlog(bp, "fo", "job.topofform"); + /* * Decide if the remote printer name matches the local printer name. @@ -431,20 +411,19 @@ #define cfree(x) do { if (x) free(x); } while(0) cfree(pp->printer); - cfree(pp->acct_file); - cfree(pp->form_feed); + + cfree(pp->log_file); cfree(pp->lock_file); cfree(pp->lp); - cfree(pp->restrict_grp); + cfree(pp->remote_host); cfree(pp->remote_queue); cfree(pp->spool_dir); cfree(pp->stat_recv); cfree(pp->stat_send); cfree(pp->status_file); - cfree(pp->trailer); - cfree(pp->mode_set); + init_printer(pp); } @@ -482,26 +461,8 @@ return PCAPERR_NOTFOUND; } -/* - * The same, only for integers. - */ -static int -capdb_getaltnum(char *bp, const char *shrt, const char *lng, long dflt, - long *result) -{ - int status; - status = cgetnum(bp, (char*)lng, result); - if (status >= 0) - return status; - status = cgetnum(bp, (char *)/*XXX*/shrt, result); - if (status >= 0) - return status; - *result = dflt; - return 0; -} - /* * Likewise for logical values. There's no need for a default parameter * because the default is always false. @@ -538,6 +499,218 @@ return retval; } + +static +struct hrPrinterTblEntry* +hrPrinterEntry_create( const struct hrDeviceTblEntry* devEntry) { + struct + hrPrinterTblEntry *entry = NULL; + + assert(devEntry != NULL); + if (devEntry == NULL) { + return NULL; + } + + if ((entry = malloc(sizeof(*entry))) == NULL) { + syslog(LOG_WARNING, "hrPrinterTable: %s: %m", __func__); + return (NULL); + } + memset(entry, 0, sizeof(*entry)); + entry->index = devEntry->index; + INSERT_OBJECT_INT(entry, &hrState_g.hr_printer_tbl); + return entry; + +} + +static +void +hrPrinterEntry_delete_v( struct hrPrinterTblEntry* entry ) { + assert(entry != NULL); + if (entry == NULL) { + return; + } + TAILQ_REMOVE(&hrState_g.hr_printer_tbl, entry, link); + free(entry); +} + + +static +struct hrPrinterTblEntry * +hrPrinterEntry_find_by_index(int32_t idx) { + + struct hrPrinterTblEntry *entry; + + TAILQ_FOREACH(entry, &hrState_g.hr_printer_tbl, link) + if (entry->index == idx) + return (entry); + return (NULL); +} + + +static +struct hrDeviceTblEntry* +hrDeviceTblEntry_create( const char* dev_name) { + struct + hrDeviceTblEntry *entry; + struct + deviceNameMapEntry *map = NULL; + + + assert(dev_name != NULL); + + if (dev_name == NULL) { + return (NULL); + } + + if (dev_name[0] == '\0') { + return (NULL); + } + + if ((entry = malloc(sizeof(*entry))) == NULL) { + syslog(LOG_WARNING, "hrPrinterTable: %s: %m", __func__); + return (NULL); + } + memset(entry, 0, sizeof(*entry)); + + + STAILQ_FOREACH(map, &hrState_g.device_name_map, link) + if (strcmp(map->name_key, dev_name) == 0) { + entry->index = map->hrIndex; + map->entry_p = entry; + break; + } + + if (map == NULL) { + /* new object - get a new index */ + if (hrState_g.next_hrDevice_index > INT_MAX) { + syslog(LOG_ERR, "%s: hrDeviceTable index wrap", __func__ ); + errx(1, "hrDeviceTable index wrap"); + } + + if ((map = malloc(sizeof(*map))) == NULL) { + syslog(LOG_ERR, "hrPrinterTable: %s: %m", __func__ ); + free(entry); + return (NULL); + } + map->hrIndex = hrState_g.next_hrDevice_index ++; + + memset(&map->name_key[0], 0, sizeof(map->name_key)); + strncpy(map->name_key, dev_name, sizeof(map->name_key) - 1); + + memset(&map->location_key[0], 0, sizeof(map->location_key)); + snprintf(map->location_key, sizeof(map->location_key) - 1, "printer:%s", dev_name); + + + map->entry_p = entry; + STAILQ_INSERT_TAIL(&hrState_g.device_name_map, map, link); + HR_DPRINTF((stderr, "%s at %s added into hrDeviceMap at index=%d\n ", + dev_name, + dev_name, map->hrIndex)); + } else { + HR_DPRINTF((stderr, "%s at %s exists in hrDeviceMap index=%d\n ", + dev_name, + dev_name, map->hrIndex)); + + } + + entry->index = map->hrIndex; + memset(&entry->name[0], 0, sizeof(entry->name)); + strncpy(entry->name, dev_name, sizeof(entry->name) - 1); + + memset(&entry->location[0], 0, sizeof(entry->location)); + snprintf(entry->location, sizeof(entry->location) - 1, "printer:%s", dev_name); + + INSERT_OBJECT_INT(entry, &hrState_g.hr_device_tbl); + + return entry; + +} + +static +void +handle_printer(struct printer *pp) { + struct hrDeviceTblEntry* dev_entry = NULL; + struct hrPrinterTblEntry* printer_entry = NULL; + + if (pp->rp_matches_local != 1) { + HR_DPRINTF((stderr, + "hrPrinterTable: skipped %s because it is not a local one\n", + pp->printer )); + return; + + } + dev_entry = hrDeviceTblEntry_find_by_name(pp->lp); + + if (dev_entry == NULL) { + HR_DPRINTF((stderr, + "hrPrinterTable: %s not in hrDeviceTable\n", + pp->lp )); + dev_entry = hrDeviceTblEntry_create(pp->lp); + if (dev_entry == NULL) { + return; + } + dev_entry->flags |= HR_DEVICE_IMMUTABLE; + dev_entry->type = (struct asn_oid)OIDX_hrDevicePrinter; + dev_entry->id = oid_zeroDotZero; /*unknown id - FIX ME*/ + dev_entry->status = DS_RUNNING; + dev_entry->errors = 0; /*FIX ME*/ + snprintf(dev_entry->descr, sizeof(dev_entry->descr) - 1, + "printer %s: %s ", + pp->printer , + pp->lp); + }else{ + HR_DPRINTF((stderr, + "hrPrinterTable: %s already in hrDeviceTable\n", + pp->lp )); + dev_entry->type = (struct asn_oid)OIDX_hrDevicePrinter; + dev_entry->flags |= HR_DEVICE_IMMUTABLE; + } + + /*Then check hrPrinterTable for this device*/ + printer_entry = hrPrinterEntry_find_by_index(dev_entry->index); + if (printer_entry == NULL) { + printer_entry = hrPrinterEntry_create(dev_entry); + } + assert(printer_entry != NULL); + printer_entry->flags |= HR_PRINTER_FOUND; + printer_entry->status = PS_UNKNOWN; + memset(printer_entry->detectedErrorState, 0, sizeof(printer_entry->detectedErrorState)); + + +} + +static +void +hrPrinter_get_OS_entries(void){ + int status, more; + struct printer myprinter, *pp = &myprinter; + + init_printer(pp); + more = firstprinter(pp, &status); + if (status) + goto errloop; + while (more) { + + do { + HR_DPRINTF((stderr, "*****>Got printer %s", pp->printer)); + + handle_printer(pp); + + more = nextprinter(pp, &status); +errloop: + if (status) + syslog(LOG_WARNING, + "hrPrinterTable: printcap entry for %s has errors, skipping", + pp->printer ? pp->printer : "<noname?>"); + } while (more && status); + } + + hrState_g.hr_printer_tick = this_tick; + hrState_g.hrPrinter_tbl_age = time(NULL); + +} + + /* * Init the things for hrPrinterTable */ @@ -545,6 +718,8 @@ hrState_g._printcapdb = (char**)malloc ( 2 * sizeof(char*) ); hrState_g._printcapdb[0] = strdup(_PATH_PRINTCAP); hrState_g._printcapdb[1] = NULL; + + hrPrinter_get_OS_entries(); } /* @@ -552,6 +727,16 @@ * It destroys the lists and frees any allocated heap memory */ void fini_hrPrinter_tbl_v(void) { + struct hrPrinterTblEntry *n1 = NULL, *n2 = NULL; + n1 = TAILQ_FIRST(&hrState_g.hr_printer_tbl); + while (n1 != NULL) { + n2 = TAILQ_NEXT(n1, link); + free(n1); + n1 = n2; + + } + TAILQ_INIT(&hrState_g.hr_printer_tbl); + if (hrState_g._printcapdb != NULL) { if (hrState_g._printcapdb[0] != NULL) { free(hrState_g._printcapdb[0]); @@ -568,15 +753,114 @@ void refresh_hrPrinter_tbl_v(void){ + struct hrPrinterTblEntry *entry = NULL, *entry_tmp = NULL; + + if ( this_tick <= hrState_g.hr_printer_tick) { + HR_DPRINTF((stderr, "%s: no refresh needed\n ",__func__)); + return; + } + + + + /*mark each entry as missing*/ + TAILQ_FOREACH(entry, &hrState_g.hr_printer_tbl, link) { + entry->flags &= ~HR_PRINTER_FOUND; + } + + + + hrPrinter_get_OS_entries(); + + /* + * Purge items that disappeared + */ + entry = TAILQ_FIRST(&hrState_g.hr_printer_tbl); + while (entry != NULL) { + entry_tmp = TAILQ_NEXT(entry, link); + if (!(entry->flags & HR_PRINTER_FOUND) ) { + struct hrDeviceTblEntry * dev_entry = NULL; + dev_entry = hrDeviceTblEntry_find_by_index(entry->index); + if (dev_entry != NULL) { + hrDeviceTblEntry_delete_v(dev_entry); + } + hrPrinterEntry_delete_v(entry); + } + entry = entry_tmp; + } + + hrState_g.hr_printer_tick = this_tick; + + hrState_g.hrPrinter_tbl_age = time(NULL); + + HR_DPRINTF((stderr, "%s: refresh DONE\n ",__func__)); + } int op_hrPrinterTable(struct snmp_context *ctx __unused, - struct snmp_value *value __unused, - u_int sub __unused, + struct snmp_value *value, + u_int sub, u_int iidx __unused, - enum snmp_op curr_op __unused) + enum snmp_op curr_op ) { - return (SNMP_ERR_NOSUCHNAME); + struct hrPrinterTblEntry *entry = NULL; + int ret = SNMP_ERR_NOERROR; + + if ( (time(NULL) - hrState_g.hrPrinter_tbl_age) > HR_PRINTER_TBL_REFRESH ) { + HR_DPRINTF((stderr, "%s: need refresh\n ",__func__)); + refresh_hrPrinter_tbl_v(); + } + + + switch (curr_op) { + + case SNMP_OP_GETNEXT: + if ((entry = NEXT_OBJECT_INT(&hrState_g.hr_printer_tbl, + &value->var, sub)) == NULL) { + return (SNMP_ERR_NOSUCHNAME); + } + value->var.len = sub + 1; + value->var.subs[sub] = entry->index; + break; + + case SNMP_OP_GET: + if (value->var.len - sub != 1) { + return (SNMP_ERR_NOSUCHNAME); + } + + if ((entry = + hrPrinterEntry_find_by_index(value->var.subs[sub])) + == NULL) { + return (SNMP_ERR_NOSUCHNAME); + } + break; + + case SNMP_OP_SET: + return (SNMP_ERR_NOT_WRITEABLE); + + case SNMP_OP_ROLLBACK: + case SNMP_OP_COMMIT: + assert(0); + return (SNMP_ERR_NOERROR); + } + + ret = SNMP_ERR_NOERROR; + switch (value->var.subs[sub - 1]) { + case LEAF_hrPrinterStatus: + value->v.integer = entry->status; + break; + case LEAF_hrPrinterDetectedErrorState: + ret = string_get(value, + entry->detectedErrorState, + sizeof(entry->detectedErrorState)); + break; + default: + assert(0); + ret = SNMP_ERR_NOSUCHNAME; + break; + + } + return (ret); + } ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.h#25 (text+ko) ==== @@ -311,6 +311,15 @@ TAILQ_HEAD(network_tbl, hrNetworkTblEntry); +enum PrinterStatus { + PS_OTHER = 1, + PS_UNKNOWN = 2, + PS_IDLE = 3, + PS_PRINTING = 4, + DS_WARMUP = 5 +}; + + /* * This structure is used to hold a SNMP table entry * for HOST-RESOURCES-MIB's hrPrinterTable @@ -318,7 +327,7 @@ struct hrPrinterTblEntry { int32_t index; - int32_t status; + int32_t status; /*values from PrinterStatus enum above*/ u_char detectedErrorState[2]; TAILQ_ENTRY(hrPrinterTblEntry) link; #define HR_PRINTER_FOUND 0x001 @@ -333,7 +342,7 @@ enum DeviceStatus { DS_UNKNOWN = 1, - DR_RUNNING = 2, + DS_RUNNING = 2, DS_WARNING = 3, DS_TESTING = 4, DS_DOWN = 5
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508211314.j7LDEeVD038848>