BSD 4_3_Net_2 release
[unix-history] / usr / src / contrib / isode / snmp / unixd.c
CommitLineData
b62cce74
C
1/* unixd.c - daemon for UNIX MIB */
2
3#ifndef lint
4static char *rcsid = "$Header: /f/osi/snmp/RCS/unixd.c,v 7.13 91/03/09 11:57:58 mrose Exp $";
5#endif
6
7/*
8 * $Header: /f/osi/snmp/RCS/unixd.c,v 7.13 91/03/09 11:57:58 mrose Exp $
9 *
10 * Contributed by NYSERNet Inc. This work was partially supported by the
11 * U.S. Defense Advanced Research Projects Agency and the Rome Air Development
12 * Center of the U.S. Air Force Systems Command under contract number
13 * F30602-88-C-0016.
14 *
15 *
16 * $Log: unixd.c,v $
17 * Revision 7.13 91/03/09 11:57:58 mrose
18 * update
19 *
20 * Revision 7.12 91/02/22 09:44:55 mrose
21 * Interim 6.8
22 *
23 * Revision 7.11 91/01/11 15:35:40 mrose
24 * sets
25 *
26 * Revision 7.10 91/01/08 12:48:55 mrose
27 * update
28 *
29 * Revision 7.9 90/12/18 10:14:22 mrose
30 * update
31 *
32 * Revision 7.8 90/10/17 11:57:41 mrose
33 * sync
34 *
35 * Revision 7.7 90/07/09 14:49:48 mrose
36 * sync
37 *
38 * Revision 7.6 90/03/06 13:51:01 mrose
39 * jch
40 *
41 * Revision 7.5 90/02/23 17:48:05 mrose
42 * update
43 *
44 * Revision 7.4 90/02/19 15:54:09 mrose
45 * touch-up
46 *
47 * Revision 7.3 90/02/19 15:39:08 mrose
48 * one more time
49 *
50 * Revision 7.2 90/02/17 17:19:01 mrose
51 * touch-up
52 *
53 * Revision 7.1 90/02/17 10:42:20 mrose
54 * touch-up
55 *
56 * Revision 7.0 90/02/17 10:36:48 mrose
57 * *** empty log message ***
58 *
59 */
60
61/*
62 * NOTICE
63 *
64 * Acquisition, use, and distribution of this module and related
65 * materials are subject to the restrictions of a license agreement.
66 * Consult the Preface in the User's Manual for the full terms of
67 * this agreement.
68 *
69 */
70
71
72#include <errno.h>
73#include <signal.h>
74#include <stdio.h>
75#include <varargs.h>
76#include "smux.h"
77#include "objects.h"
78#include <sys/ioctl.h>
79#ifdef BSD42
80#include <sys/file.h>
81#endif
82#ifdef SYS5
83#include <fcntl.h>
84#endif
85#include "tailor.h"
86
87/* \f DATA */
88
89int debug = 0;
90static int nbits = FD_SETSIZE;
91
92static LLog _pgm_log = {
93 "unixd.log", NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE,
94 LLOG_FATAL, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK
95};
96static LLog *pgm_log = &_pgm_log;
97
98static char *myname = "unixd";
99
100
101static int smux_fd = NOTOK;
102static int rock_and_roll = 0;
103static int dont_bother_anymore = 0;
104
105static OID subtree = NULLOID;
106static struct smuxEntry *se = NULL;
107
108
109static fd_set ifds;
110static fd_set ofds;
111
112
113void adios (), advise ();
114
115/* \f MAIN */
116
117/* ARGSUSED */
118
119main (argc, argv, envp)
120int argc;
121char **argv,
122 **envp;
123{
124 int nfds;
125
126 arginit (argv);
127 envinit ();
128
129 FD_ZERO (&ifds);
130 FD_ZERO (&ofds);
131 nfds = 0;
132
133/* set fd's for other purposes here... */
134
135 for (;;) {
136 int n,
137 secs;
138 fd_set rfds,
139 wfds;
140
141 secs = NOTOK;
142
143 rfds = ifds; /* struct copy */
144 wfds = ofds; /* .. */
145
146 if (smux_fd == NOTOK && !dont_bother_anymore)
147 secs = 5 * 60L;
148 else
149 if (rock_and_roll)
150 FD_SET (smux_fd, &rfds);
151 else
152 FD_SET (smux_fd, &wfds);
153 if (smux_fd >= nfds)
154 nfds = smux_fd + 1;
155
156 if ((n = xselect (nfds, &rfds, &wfds, NULLFD, secs)) == NOTOK)
157 adios ("failed", "xselect");
158
159/* check fd's for other purposes here... */
160
161 if (smux_fd == NOTOK && !dont_bother_anymore) {
162 if (n == 0) {
163 if ((smux_fd = smux_init (debug)) == NOTOK)
164 advise (LLOG_EXCEPTIONS, NULLCP, "smux_init: %s [%s]",
165 smux_error (smux_errno), smux_info);
166 else
167 rock_and_roll = 0;
168 }
169 }
170 else
171 if (rock_and_roll) {
172 if (FD_ISSET (smux_fd, &rfds))
173 doit_smux ();
174 }
175 else
176 if (FD_ISSET (smux_fd, &wfds))
177 start_smux ();
178 }
179}
180
181/* \f MISCELLANY */
182
183static arginit (vec)
184char **vec;
185{
186 register char *ap;
187
188 if (myname = rindex (*vec, '/'))
189 myname++;
190 if (myname == NULL || *myname == NULL)
191 myname = *vec;
192 if (strncmp (myname, "smux.", 5) == 0 && myname[5] != NULL)
193 myname += 5;
194
195 isodetailor (myname, 0);
196 ll_hdinit (pgm_log, myname);
197
198 for (vec++; ap = *vec; vec++) {
199 if (*ap == '-')
200 switch (*++ap) {
201 case 'd':
202 debug++;
203 continue;
204
205 default:
206 adios (NULLCP, "-%s: unknown switch", ap);
207 }
208
209 adios (NULLCP, "usage: %s [switches]", myname);
210 }
211
212
213}
214
215/* \f */
216
217static envinit () {
218 int i,
219 sd;
220 char file[BUFSIZ];
221 FILE *fp;
222
223 nbits = getdtablesize ();
224
225 if (debug == 0 && !(debug = isatty (2))) {
226 for (i = 0; i < 5; i++) {
227 switch (fork ()) {
228 case NOTOK:
229 sleep (5);
230 continue;
231
232 case OK:
233 break;
234
235 default:
236 _exit (0);
237 }
238 break;
239 }
240
241 (void) chdir ("/");
242
243 if ((sd = open ("/dev/null", O_RDWR)) == NOTOK)
244 adios ("/dev/null", "unable to read");
245 if (sd != 0)
246 (void) dup2 (sd, 0), (void) close (sd);
247 (void) dup2 (0, 1);
248 (void) dup2 (0, 2);
249
250#ifdef SETSID
251 if (setsid () == NOTOK)
252 advise (LLOG_EXCEPTIONS, "failed", "setsid");
253#endif
254#ifdef TIOCNOTTY
255 if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) {
256 (void) ioctl (sd, TIOCNOTTY, NULLCP);
257 (void) close (sd);
258 }
259#else
260#ifdef SYS5
261 (void) setpgrp ();
262 (void) signal (SIGINT, SIG_IGN);
263 (void) signal (SIGQUIT, SIG_IGN);
264#endif
265#endif
266 }
267 else
268 ll_dbinit (pgm_log, myname);
269
270#ifndef sun /* damn YP... */
271 for (sd = 3; sd < nbits; sd++)
272 if (pgm_log -> ll_fd != sd)
273 (void) close (sd);
274#endif
275
276 (void) signal (SIGPIPE, SIG_IGN);
277
278 ll_hdinit (pgm_log, myname);
279
280 mibinit ();
281
282 (void) sprintf (file, "/etc/%s.pid", myname);
283 if (fp = fopen (file, "w")) {
284 (void) fprintf (fp, "%d\n", getpid ());
285 (void) fclose (fp);
286 }
287
288 advise (LLOG_NOTICE, NULLCP, "starting");
289}
290
291/* \f MIB */
292
293#include <nlist.h>
294
295static int kd;
296static int quantum = 0;
297static int lastq = -1;
298
299static struct nlist nl[] = {
300#define N_MBSTAT 0
301 { "_mbstat" },
302
303 NULL
304};
305
306
307static mibinit () {
308 OT ot;
309 register struct nlist *nz;
310
311 if ((se = getsmuxEntrybyname ("unixd")) == NULL)
312 adios (NULLCP, "no SMUX entry for \"%s\"", "unixd");
313
314 if (readobjects ("unixd.defs") == NOTOK)
315 adios (NULLCP, "readobjects: %s", PY_pepy);
316
317 if ((ot = text2obj ("mbuf")) == NULL)
318 adios (NULLCP, "text2obj (\"%s\") fails", "mbuf");
319 subtree = ot -> ot_name;
320
321 if (nlist ("/vmunix", nl) == NOTOK)
322 adios ("/vmunix", "unable to nlist");
323 for (nz = nl; nz -> n_name; nz++)
324 if (nz -> n_value == 0)
325 advise (LLOG_EXCEPTIONS, NULLCP, "\"%s\" not in /vmunix (warning)",
326 nz -> n_name);
327
328 if ((kd = open ("/dev/kmem", O_RDONLY)) == NOTOK)
329 adios ("/vmunix", "unable to read");
330
331 init_unix (); /* UNIX-specific enterprise */
332
333 if ((smux_fd = smux_init (debug)) == NOTOK)
334 advise (LLOG_EXCEPTIONS, NULLCP, "smux_init: %s [%s]",
335 smux_error (smux_errno), smux_info);
336 else
337 rock_and_roll = 0;
338}
339
340/* \f */
341
342static start_smux () {
343 if (smux_simple_open (&se -> se_identity, "SMUX UNIX daemon",
344 se -> se_password, strlen (se -> se_password))
345 == NOTOK) {
346 if (smux_errno == inProgress)
347 return;
348
349 advise (LLOG_EXCEPTIONS, NULLCP, "smux_simple_open: %s [%s]",
350 smux_error (smux_errno), smux_info);
351losing: ;
352 smux_fd = NOTOK;
353 return;
354 }
355 advise (LLOG_NOTICE, NULLCP, "SMUX open: %s \"%s\"",
356 oid2ode (&se -> se_identity), se -> se_name);
357 rock_and_roll = 1;
358
359 if (smux_register (subtree, -1, readOnly) == NOTOK) {
360 advise (LLOG_EXCEPTIONS, NULLCP, "smux_register: %s [%s]",
361 smux_error (smux_errno), smux_info);
362 goto losing;
363 }
364 advise (LLOG_NOTICE, NULLCP, "SMUX register: readOnly %s in=%d",
365 oid2ode (subtree), -1);
366}
367
368/* \f */
369
370static doit_smux () {
371 struct type_SNMP_SMUX__PDUs *event;
372
373 if (smux_wait (&event, NOTOK) == NOTOK) {
374 if (smux_errno == inProgress)
375 return;
376
377 advise (LLOG_EXCEPTIONS, NULLCP, "smux_wait: %s [%s]",
378 smux_error (smux_errno), smux_info);
379losing: ;
380 smux_fd = NOTOK;
381 return;
382 }
383
384 switch (event -> offset) {
385 case type_SNMP_SMUX__PDUs_registerResponse:
386 {
387 struct type_SNMP_RRspPDU *rsp = event -> un.registerResponse;
388
389 if (rsp -> parm == int_SNMP_RRspPDU_failure) {
390 advise (LLOG_NOTICE, NULLCP,
391 "SMUX registration of %s failed",
392 oid2ode (subtree));
393 dont_bother_anymore = 1;
394 (void) smux_close (goingDown);
395 goto losing;
396 }
397 else
398 advise (LLOG_NOTICE, NULLCP,
399 "SMUX register: readOnly %s out=%d",
400 oid2ode (subtree), rsp -> parm);
401 }
402 if (smux_trap (int_SNMP_generic__trap_coldStart,
403 0, (struct type_SNMP_VarBindList *) 0) == NOTOK) {
404 advise (LLOG_EXCEPTIONS, NULLCP, "smux_trap: %s [%s]",
405 smux_error (smux_errno), smux_info);
406 goto losing;
407 }
408 break;
409
410 case type_SNMP_SMUX__PDUs_get__request:
411 case type_SNMP_SMUX__PDUs_get__next__request:
412 get_smux (event -> un.get__request, event -> offset);
413 break;
414
415 case type_SNMP_SMUX__PDUs_close:
416 advise (LLOG_NOTICE, NULLCP, "SMUX close: %s",
417 smux_error (event -> un.close -> parm));
418 goto losing;
419
420 case type_SNMP_SMUX__PDUs_simple:
421 case type_SNMP_SMUX__PDUs_registerRequest:
422 case type_SNMP_SMUX__PDUs_get__response:
423 case type_SNMP_SMUX__PDUs_trap:
424 advise (LLOG_EXCEPTIONS, NULLCP, "unexpectedOperation: %d",
425 event -> offset);
426 (void) smux_close (protocolError);
427 goto losing;
428
429 case type_SNMP_SMUX__PDUs_set__request:
430 case type_SNMP_SMUX__PDUs_commitOrRollback:
431 set_smux (event);
432 break;
433
434 default:
435 advise (LLOG_EXCEPTIONS, NULLCP, "badOperation: %d",
436 event -> offset);
437 (void) smux_close (protocolError);
438 goto losing;
439 }
440}
441
442/* \f */
443
444static get_smux (pdu, offset)
445register struct type_SNMP_GetRequest__PDU *pdu;
446int offset;
447{
448 int idx,
449 status;
450 object_instance ois;
451 register struct type_SNMP_VarBindList *vp;
452
453 quantum = pdu -> request__id;
454 idx = 0;
455 for (vp = pdu -> variable__bindings; vp; vp = vp -> next) {
456 register OI oi;
457 register OT ot;
458 register struct type_SNMP_VarBind *v = vp -> VarBind;
459
460 idx++;
461
462 if (offset == type_SNMP_SMUX__PDUs_get__next__request) {
463 if ((oi = name2inst (v -> name)) == NULLOI
464 && (oi = next2inst (v -> name)) == NULLOI)
465 goto no_name;
466
467 if ((ot = oi -> oi_type) -> ot_getfnx == NULLIFP)
468 goto get_next;
469 }
470 else
471 if ((oi = name2inst (v -> name)) == NULLOI
472 || (ot = oi -> oi_type) -> ot_getfnx == NULLIFP) {
473no_name: ;
474 pdu -> error__status = int_SNMP_error__status_noSuchName;
475 goto out;
476 }
477
478try_again: ;
479 switch (ot -> ot_access) {
480 case OT_NONE:
481 if (offset == type_SNMP_SMUX__PDUs_get__next__request)
482 goto get_next;
483 goto no_name;
484
485 case OT_RDONLY:
486 if (offset == type_SNMP_SMUX__PDUs_set__request) {
487 pdu -> error__status = int_SNMP_error__status_noSuchName;
488 goto out;
489 }
490 break;
491
492 case OT_RDWRITE:
493 break;
494 }
495
496 switch (status = (*ot -> ot_getfnx) (oi, v, offset)) {
497 case NOTOK: /* get-next wants a bump */
498get_next: ;
499 oi = &ois;
500 for (;;) {
501 if ((ot = ot -> ot_next) == NULLOT) {
502 pdu -> error__status =
503 int_SNMP_error__status_noSuchName;
504 goto out;
505 }
506 oi -> oi_name = (oi -> oi_type = ot) -> ot_name;
507 if (ot -> ot_getfnx)
508 goto try_again;
509 }
510
511 case int_SNMP_error__status_noError:
512 break;
513
514 default:
515 pdu -> error__status = status;
516 goto out;
517 }
518 }
519 idx = 0;
520
521out: ;
522 pdu -> error__index = idx;
523
524 if (smux_response (pdu) == NOTOK) {
525 advise (LLOG_EXCEPTIONS, NULLCP, "smux_response: %s [%s]",
526 smux_error (smux_errno), smux_info);
527 smux_fd = NOTOK;
528 }
529}
530
531/* \f */
532
533static set_smux (event)
534struct type_SNMP_SMUX__PDUs *event;
535{
536 switch (event -> offset) {
537 case type_SNMP_SMUX__PDUs_set__request:
538 {
539 register struct type_SNMP_GetRequest__PDU *pdu =
540 event -> un.get__response;
541
542 pdu -> error__status = int_SNMP_error__status_noSuchName;
543 pdu -> error__index = pdu -> variable__bindings ? 1 : 0;
544
545 if (smux_response (pdu) == NOTOK) {
546 advise (LLOG_EXCEPTIONS, NULLCP, "smux_response: %s [%s]",
547 smux_error (smux_errno), smux_info);
548 smux_fd = NOTOK;
549 }
550 }
551 break;
552
553 case type_SNMP_SMUX__PDUs_commitOrRollback:
554 {
555 struct type_SNMP_SOutPDU *cor = event -> un.commitOrRollback;
556
557 if (cor -> parm == int_SNMP_SOutPDU_commit) {
558 /* "should not happen" */
559 (void) smux_close (protocolError);
560 smux_fd = NOTOK;
561 }
562 }
563 break;
564 }
565}
566
567/* \f UNIX */
568
569#ifdef BSD44
570#include <sys/param.h>
571#endif
572#include <sys/mbuf.h>
573
574/* \f */
575
576static struct mbstat mbstat;
577
578/* \f */
579
580#define mbufS 0
581#define mbufClusters 1
582#define mbufFreeClusters 2
583#define mbufDrops 3
584#ifdef BSD44
585#define mbufWaits 4
586#define mbufDrains 5
587#endif
588#if !defined(BSD43) && !defined(BSD44)
589#define mbufFrees 6
590#endif
591
592
593static int o_mbuf (oi, v, offset)
594OI oi;
595register struct type_SNMP_VarBind *v;
596int offset;
597{
598 int ifvar;
599 register struct mbstat *m = &mbstat;
600 register OID oid = oi -> oi_name;
601 register OT ot = oi -> oi_type;
602
603 ifvar = (int) ot -> ot_info;
604 switch (offset) {
605 case type_SNMP_SMUX__PDUs_get__request:
606 if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1
607 || oid -> oid_elements[oid -> oid_nelem - 1] != 0)
608 return int_SNMP_error__status_noSuchName;
609 break;
610
611 case type_SNMP_SMUX__PDUs_get__next__request:
612 if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
613 OID new;
614
615 if ((new = oid_extend (oid, 1)) == NULLOID)
616 return NOTOK;
617 new -> oid_elements[new -> oid_nelem - 1] = 0;
618
619 if (v -> name)
620 free_SNMP_ObjectName (v -> name);
621 v -> name = new;
622 }
623 else
624 return NOTOK;
625 break;
626
627 default:
628 return int_SNMP_error__status_genErr;
629 }
630
631 if (quantum != lastq) {
632 lastq = quantum;
633
634 if (getkmem (nl + N_MBSTAT, (caddr_t) m, sizeof *m) == NOTOK)
635 return (offset == type_SNMP_PDUs_get__next__request ? NOTOK
636 : int_SNMP_error__status_genErr);
637 }
638
639 switch (ifvar) {
640 case mbufS:
641 return o_integer (oi, v, m -> m_mbufs);
642
643 case mbufClusters:
644 return o_integer (oi, v, m -> m_clusters);
645
646 case mbufFreeClusters:
647 return o_integer (oi, v, m -> m_clfree);
648
649 case mbufDrops:
650 return o_integer (oi, v, m -> m_drops);
651
652#ifdef mbufWaits
653 case mbufWaits:
654 return o_integer (oi, v, m -> m_wait);
655#endif
656
657#ifdef mbufDrains
658 case mbufDrains:
659 return o_integer (oi, v, m -> m_drain);
660#endif
661
662#ifdef mbufFrees
663 case mbufFrees:
664 return o_integer (oi, v, m -> m_mbfree);
665#endif
666
667 default:
668 return int_SNMP_error__status_noSuchName;
669 }
670}
671
672/* \f */
673
674#define mbufType 0
675#define mbufAllocates 1
676
677
678static int o_mbufType (oi, v, offset)
679OI oi;
680register struct type_SNMP_VarBind *v;
681int offset;
682{
683 int ifnum,
684 ifvar;
685 register struct mbstat *m = &mbstat;
686 register OID oid = oi -> oi_name;
687 register OT ot = oi -> oi_type;
688
689 ifvar = (int) ot -> ot_info;
690 switch (offset) {
691 case type_SNMP_SMUX__PDUs_get__request:
692 if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1)
693 return int_SNMP_error__status_noSuchName;
694 if ((ifnum = oid -> oid_elements[oid -> oid_nelem - 1])
695 >= sizeof m -> m_mtypes / sizeof m -> m_mtypes[0])
696 return int_SNMP_error__status_noSuchName;
697 break;
698
699 case type_SNMP_SMUX__PDUs_get__next__request:
700again: ;
701 if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
702 OID new;
703
704 ifnum = 0;
705
706 if ((new = oid_extend (oid, 1)) == NULLOID)
707 return NOTOK;
708 new -> oid_elements[new -> oid_nelem - 1] = ifnum;
709
710 if (v -> name)
711 free_SNMP_ObjectName (v -> name);
712 v -> name = new;
713
714 oid = new; /* for hack... */
715 }
716 else {
717 int i = ot -> ot_name -> oid_nelem;
718
719 if ((ifnum = oid -> oid_elements[i] + 1)
720 >= sizeof m -> m_mtypes / sizeof m -> m_mtypes[0])
721 return NOTOK;
722
723 oid -> oid_elements[i] = ifnum;
724 oid -> oid_nelem = i + 1;
725 }
726 break;
727
728 default:
729 return int_SNMP_error__status_genErr;
730 }
731
732 if (quantum != lastq) {
733 lastq = quantum;
734
735 if (getkmem (nl + N_MBSTAT, (caddr_t) m, sizeof *m) == NOTOK)
736 return (offset == type_SNMP_PDUs_get__next__request ? NOTOK
737 : int_SNMP_error__status_genErr);
738 }
739
740/* hack to compress table size... */
741 if (offset == type_SNMP_SMUX__PDUs_get__next__request
742 && m -> m_mtypes[ifnum] == 0)
743 goto again;
744
745 switch (ifvar) {
746 case mbufType:
747 return o_integer (oi, v, ifnum);
748
749 case mbufAllocates:
750 return o_integer (oi, v, m -> m_mtypes[ifnum]);
751
752 default:
753 return int_SNMP_error__status_noSuchName;
754 }
755}
756
757/* \f */
758
759init_unix () {
760 register OT ot;
761
762 if (ot = text2obj ("mbufS"))
763 ot -> ot_getfnx = o_mbuf,
764 ot -> ot_info = (caddr_t) mbufS;
765 if (ot = text2obj ("mbufClusters"))
766 ot -> ot_getfnx = o_mbuf,
767 ot -> ot_info = (caddr_t) mbufClusters;
768 if (ot = text2obj ("mbufFreeClusters"))
769 ot -> ot_getfnx = o_mbuf,
770 ot -> ot_info = (caddr_t) mbufFreeClusters;
771 if (ot = text2obj ("mbufDrops"))
772 ot -> ot_getfnx = o_mbuf,
773 ot -> ot_info = (caddr_t) mbufDrops;
774#ifdef mbufWaits
775 if (ot = text2obj ("mbufWaits"))
776 ot -> ot_getfnx = o_mbuf,
777 ot -> ot_info = (caddr_t) mbufWaits;
778#endif
779#ifdef mbufDrains
780 if (ot = text2obj ("mbufDrains"))
781 ot -> ot_getfnx = o_mbuf,
782 ot -> ot_info = (caddr_t) mbufDrains;
783#endif
784#ifdef mbufFrees
785 if (ot = text2obj ("mbufFrees"))
786 ot -> ot_getfnx = o_mbuf,
787 ot -> ot_info = (caddr_t) mbufFrees;
788#endif
789 if (ot = text2obj ("mbufType"))
790 ot -> ot_getfnx = o_mbufType,
791 ot -> ot_info = (caddr_t) mbufType;
792 if (ot = text2obj ("mbufAllocates"))
793 ot -> ot_getfnx = o_mbufType,
794 ot -> ot_info = (caddr_t) mbufAllocates;
795}
796
797/* \f */
798
799int getkmem (n, buffer, cc)
800struct nlist *n;
801caddr_t buffer;
802int cc;
803{
804 if (n -> n_value == 0) {
805 advise (LLOG_EXCEPTIONS, NULLCP, "\"%s\" not in /vmunix", n -> n_name);
806 return NOTOK;
807 }
808 if (lseek (kd, (long) n -> n_value, L_SET) == NOTOK) {
809 advise (LLOG_EXCEPTIONS, "failed", "lseek of 0x%x for \"%s\" in kmem",
810 (long) n -> n_value, n -> n_name);
811 return NOTOK;
812 }
813 if (read (kd, buffer, cc) != cc) {
814 advise (LLOG_EXCEPTIONS, "failed", "read of \"%s\" from kmem",
815 n -> n_name);
816 return NOTOK;
817 }
818
819 return OK;
820}
821
822/* \f ERRORS */
823
824#ifndef lint
825void adios (va_alist)
826va_dcl
827{
828 va_list ap;
829
830 va_start (ap);
831
832 _ll_log (pgm_log, LLOG_FATAL, ap);
833
834 va_end (ap);
835
836 _exit (1);
837}
838#else
839/* VARARGS */
840
841void adios (what, fmt)
842char *what,
843 *fmt;
844{
845 adios (what, fmt);
846}
847#endif
848
849
850#ifndef lint
851void advise (va_alist)
852va_dcl
853{
854 int code;
855 va_list ap;
856
857 va_start (ap);
858
859 code = va_arg (ap, int);
860
861 _ll_log (pgm_log, code, ap);
862
863 va_end (ap);
864}
865#else
866/* VARARGS */
867
868void advise (code, what, fmt)
869char *what,
870 *fmt;
871int code;
872{
873 advise (code, what, fmt);
874}
875#endif