Annotation of embedaddon/ntp/util/tickadj.c, revision 1.1
1.1 ! misho 1: /*
! 2: * tickadj - read, and possibly modify, the kernel `tick' and
! 3: * `tickadj' variables, as well as `dosynctodr'. Note that
! 4: * this operates on the running kernel only. I'd like to be
! 5: * able to read and write the binary as well, but haven't
! 6: * mastered this yet.
! 7: *
! 8: * HMS: The #includes here are different from those in xntpd/ntp_unixclock.c
! 9: * These seem "worse".
! 10: */
! 11:
! 12: #ifdef HAVE_CONFIG_H
! 13: # include <config.h>
! 14: #endif
! 15:
! 16: #include "ntp_types.h"
! 17: #include "l_stdlib.h"
! 18:
! 19: #include <stdio.h>
! 20: #ifdef HAVE_UNISTD_H
! 21: # include <unistd.h>
! 22: #endif /* HAVE_UNISTD_H */
! 23:
! 24: #ifdef HAVE___ADJTIMEX /* Linux */
! 25:
! 26: #include <sys/timex.h>
! 27: struct timex txc;
! 28:
! 29: #if 0
! 30: int
! 31: main(
! 32: int argc,
! 33: char *argv[]
! 34: )
! 35: {
! 36: int c, i;
! 37: int quiet = 0;
! 38: int errflg = 0;
! 39: char *progname;
! 40: extern int ntp_optind;
! 41: extern char *ntp_optarg;
! 42:
! 43: progname = argv[0];
! 44: if (argc==2 && argv[1][0] != '-') { /* old Linux format, for compatability */
! 45: if ((i = atoi(argv[1])) > 0) {
! 46: txc.time_tick = i;
! 47: txc.modes = ADJ_TIMETICK;
! 48: } else {
! 49: fprintf(stderr, "Silly value for tick: %s\n", argv[1]);
! 50: errflg++;
! 51: }
! 52: } else {
! 53: while ((c = ntp_getopt(argc, argv, "a:qt:")) != EOF) {
! 54: switch (c) {
! 55: case 'a':
! 56: if ((i=atoi(ntp_optarg)) > 0) {
! 57: txc.tickadj = i;
! 58: txc.modes |= ADJ_TICKADJ;
! 59: } else {
! 60: (void) fprintf(stderr,
! 61: "%s: unlikely value for tickadj: %s\n",
! 62: progname, ntp_optarg);
! 63: errflg++;
! 64: }
! 65: break;
! 66:
! 67: case 'q':
! 68: quiet = 1;
! 69: break;
! 70:
! 71: case 't':
! 72: if ((i=atoi(ntp_optarg)) > 0) {
! 73: txc.time_tick = i;
! 74: txc.modes |= ADJ_TIMETICK;
! 75: } else {
! 76: (void) fprintf(stderr,
! 77: "%s: unlikely value for tick: %s\n",
! 78: progname, ntp_optarg);
! 79: errflg++;
! 80: }
! 81: break;
! 82:
! 83: default:
! 84: fprintf(stderr,
! 85: "Usage: %s [tick_value]\n-or- %s [ -q ] [ -t tick ] [ -a tickadj ]\n",
! 86: progname, progname);
! 87: errflg++;
! 88: break;
! 89: }
! 90: }
! 91: }
! 92:
! 93: if (!errflg) {
! 94: if (__adjtimex(&txc) < 0)
! 95: perror("adjtimex");
! 96: else if (!quiet)
! 97: printf("tick = %ld\ntick_adj = %d\n",
! 98: txc.time_tick, txc.tickadj);
! 99: }
! 100:
! 101: exit(errflg ? 1 : 0);
! 102: }
! 103: #else
! 104: int
! 105: main(
! 106: int argc,
! 107: char *argv[]
! 108: )
! 109: {
! 110: if (argc > 2)
! 111: {
! 112: fprintf(stderr, "Usage: %s [tick_value]\n", argv[0]);
! 113: exit(-1);
! 114: }
! 115: else if (argc == 2)
! 116: {
! 117: #ifdef ADJ_TIMETICK
! 118: if ( (txc.time_tick = atoi(argv[1])) < 1 )
! 119: #else
! 120: if ( (txc.tick = atoi(argv[1])) < 1 )
! 121: #endif
! 122: {
! 123: fprintf(stderr, "Silly value for tick: %s\n", argv[1]);
! 124: exit(-1);
! 125: }
! 126: #ifdef ADJ_TIMETICK
! 127: txc.modes = ADJ_TIMETICK;
! 128: #else
! 129: #ifdef MOD_OFFSET
! 130: txc.modes = ADJ_TICK;
! 131: #else
! 132: txc.mode = ADJ_TICK;
! 133: #endif
! 134: #endif
! 135: }
! 136: else
! 137: {
! 138: #ifdef ADJ_TIMETICK
! 139: txc.modes = 0;
! 140: #else
! 141: #ifdef MOD_OFFSET
! 142: txc.modes = 0;
! 143: #else
! 144: txc.mode = 0;
! 145: #endif
! 146: #endif
! 147: }
! 148:
! 149: if (__adjtimex(&txc) < 0)
! 150: {
! 151: perror("adjtimex");
! 152: }
! 153: else
! 154: {
! 155: #ifdef ADJ_TIMETICK
! 156: printf("tick = %ld\ntick_adj = %ld\n", txc.time_tick, txc.tickadj);
! 157: #else
! 158: printf("tick = %ld\n", txc.tick);
! 159: #endif
! 160: }
! 161:
! 162: exit(0);
! 163: }
! 164: #endif
! 165:
! 166: #else /* not Linux... kmem tweaking: */
! 167:
! 168: #ifdef HAVE_SYS_FILE_H
! 169: # include <sys/file.h>
! 170: #endif
! 171: #include <sys/stat.h>
! 172:
! 173: #ifdef HAVE_SYS_PARAM_H
! 174: # include <sys/param.h>
! 175: #endif
! 176:
! 177: #ifdef NLIST_STRUCT
! 178: # include <nlist.h>
! 179: #else /* not NLIST_STRUCT */ /* was defined(SYS_AUX3) || defined(SYS_AUX2) */
! 180: # include <sys/resource.h>
! 181: # include <sys/file.h>
! 182: # include <a.out.h>
! 183: # ifdef HAVE_SYS_VAR_H
! 184: # include <sys/var.h>
! 185: # endif
! 186: #endif
! 187:
! 188: #include "ntp_stdlib.h"
! 189: #include "ntp_io.h"
! 190:
! 191: #ifdef hz /* Was: RS6000 */
! 192: # undef hz
! 193: #endif /* hz */
! 194:
! 195: #ifdef HAVE_KVM_OPEN
! 196: # include <kvm.h>
! 197: #endif
! 198:
! 199: #ifdef SYS_VXWORKS
! 200: /* vxWorks needs mode flag -casey*/
! 201: #define open(name, flags) open(name, flags, 0777)
! 202: #endif
! 203:
! 204: #ifndef L_SET /* Was: defined(SYS_PTX) || defined(SYS_IX86OSF1) */
! 205: # define L_SET SEEK_SET
! 206: #endif
! 207:
! 208: #ifndef HZ
! 209: # define HZ DEFAULT_HZ
! 210: #endif
! 211:
! 212: #define KMEM "/dev/kmem"
! 213: #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
! 214:
! 215: char *progname;
! 216: volatile int debug;
! 217:
! 218: int dokmem = 1;
! 219: int writetickadj = 0;
! 220: int writeopttickadj = 0;
! 221: int unsetdosync = 0;
! 222: int writetick = 0;
! 223: int quiet = 0;
! 224: int setnoprintf = 0;
! 225:
! 226: const char *kmem = KMEM;
! 227: const char *file = NULL;
! 228: int fd = -1;
! 229:
! 230: static void getoffsets (off_t *, off_t *, off_t *, off_t *);
! 231: static int openfile (const char *, int);
! 232: static void writevar (int, off_t, int);
! 233: static void readvar (int, off_t, int *);
! 234:
! 235: /*
! 236: * main - parse arguments and handle options
! 237: */
! 238: int
! 239: main(
! 240: int argc,
! 241: char *argv[]
! 242: )
! 243: {
! 244: int c;
! 245: int errflg = 0;
! 246: off_t tickadj_offset;
! 247: off_t tick_offset;
! 248: off_t dosync_offset;
! 249: off_t noprintf_offset;
! 250: int tickadj, ktickadj; /* HMS: Why isn't this u_long? */
! 251: int tick, ktick; /* HMS: Why isn't this u_long? */
! 252: int dosynctodr;
! 253: int noprintf;
! 254: int hz;
! 255: int hz_int, hz_hundredths;
! 256: int recommend_tickadj;
! 257: long tmp;
! 258:
! 259: progname = argv[0];
! 260: while ((c = ntp_getopt(argc, argv, "a:Adkpqst:")) != EOF)
! 261: {
! 262: switch (c)
! 263: {
! 264: case 'a':
! 265: writetickadj = atoi(ntp_optarg);
! 266: if (writetickadj <= 0)
! 267: {
! 268: (void) fprintf(stderr,
! 269: "%s: unlikely value for tickadj: %s\n",
! 270: progname, ntp_optarg);
! 271: errflg++;
! 272: }
! 273:
! 274: #if defined SCO5_CLOCK
! 275: if (writetickadj % HZ)
! 276: {
! 277: writetickadj = (writetickadj / HZ) * HZ;
! 278: (void) fprintf(stderr,
! 279: "tickadj truncated to: %d\n", writetickadj);
! 280: }
! 281: #endif /* SCO5_CLOCK */
! 282:
! 283: break;
! 284: case 'A':
! 285: writeopttickadj = 1;
! 286: break;
! 287: case 'd':
! 288: ++debug;
! 289: break;
! 290: case 'k':
! 291: dokmem = 1;
! 292: break;
! 293: case 'p':
! 294: setnoprintf = 1;
! 295: break;
! 296: case 'q':
! 297: quiet = 1;
! 298: break;
! 299: case 's':
! 300: unsetdosync = 1;
! 301: break;
! 302: case 't':
! 303: writetick = atoi(ntp_optarg);
! 304: if (writetick <= 0)
! 305: {
! 306: (void) fprintf(stderr,
! 307: "%s: unlikely value for tick: %s\n",
! 308: progname, ntp_optarg);
! 309: errflg++;
! 310: }
! 311: break;
! 312: default:
! 313: errflg++;
! 314: break;
! 315: }
! 316: }
! 317: if (errflg || ntp_optind != argc)
! 318: {
! 319: (void) fprintf(stderr,
! 320: "usage: %s [-Adkpqs] [-a newadj] [-t newtick]\n", progname);
! 321: exit(2);
! 322: }
! 323:
! 324: getoffsets(&tick_offset, &tickadj_offset, &dosync_offset, &noprintf_offset);
! 325:
! 326: if (debug)
! 327: {
! 328: (void) printf("tick offset = %lu\n", (unsigned long)tick_offset);
! 329: (void) printf("tickadj offset = %lu\n", (unsigned long)tickadj_offset);
! 330: (void) printf("dosynctodr offset = %lu\n", (unsigned long)dosync_offset);
! 331: (void) printf("noprintf offset = %lu\n", (unsigned long)noprintf_offset);
! 332: }
! 333:
! 334: if (writetick && (tick_offset == 0))
! 335: {
! 336: (void) fprintf(stderr,
! 337: "No tick kernel variable\n");
! 338: errflg++;
! 339: }
! 340:
! 341: if (writeopttickadj && (tickadj_offset == 0))
! 342: {
! 343: (void) fprintf(stderr,
! 344: "No tickadj kernel variable\n");
! 345: errflg++;
! 346: }
! 347:
! 348: if (unsetdosync && (dosync_offset == 0))
! 349: {
! 350: (void) fprintf(stderr,
! 351: "No dosynctodr kernel variable\n");
! 352: errflg++;
! 353: }
! 354:
! 355: if (setnoprintf && (noprintf_offset == 0))
! 356: {
! 357: (void) fprintf(stderr,
! 358: "No noprintf kernel variable\n");
! 359: errflg++;
! 360: }
! 361:
! 362: if (tick_offset != 0)
! 363: {
! 364: readvar(fd, tick_offset, &tick);
! 365: #if defined(TICK_NANO) && defined(K_TICK_NAME)
! 366: if (!quiet)
! 367: (void) printf("KERNEL %s = %d nsec\n", K_TICK_NAME, tick);
! 368: #endif /* TICK_NANO && K_TICK_NAME */
! 369:
! 370: #ifdef TICK_NANO
! 371: tick /= 1000;
! 372: #endif
! 373: }
! 374: else
! 375: {
! 376: tick = 0;
! 377: }
! 378:
! 379: if (tickadj_offset != 0)
! 380: {
! 381: readvar(fd, tickadj_offset, &tickadj);
! 382:
! 383: #ifdef SCO5_CLOCK
! 384: /* scale from nsec/sec to usec/tick */
! 385: tickadj /= (1000L * HZ);
! 386: #endif /*SCO5_CLOCK */
! 387:
! 388: #if defined(TICKADJ_NANO) && defined(K_TICKADJ_NAME)
! 389: if (!quiet)
! 390: (void) printf("KERNEL %s = %d nsec\n", K_TICKADJ_NAME, tickadj);
! 391: #endif /* TICKADJ_NANO && K_TICKADJ_NAME */
! 392:
! 393: #ifdef TICKADJ_NANO
! 394: tickadj += 999;
! 395: tickadj /= 1000;
! 396: #endif
! 397: }
! 398: else
! 399: {
! 400: tickadj = 0;
! 401: }
! 402:
! 403: if (dosync_offset != 0)
! 404: {
! 405: readvar(fd, dosync_offset, &dosynctodr);
! 406: }
! 407:
! 408: if (noprintf_offset != 0)
! 409: {
! 410: readvar(fd, noprintf_offset, &noprintf);
! 411: }
! 412:
! 413: (void) close(fd);
! 414:
! 415: if (unsetdosync && dosync_offset == 0)
! 416: {
! 417: (void) fprintf(stderr,
! 418: "%s: can't find %s in namelist\n",
! 419: progname,
! 420: #ifdef K_DOSYNCTODR_NAME
! 421: K_DOSYNCTODR_NAME
! 422: #else /* not K_DOSYNCTODR_NAME */
! 423: "dosynctodr"
! 424: #endif /* not K_DOSYNCTODR_NAME */
! 425: );
! 426: exit(1);
! 427: }
! 428:
! 429: hz = HZ;
! 430: #if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
! 431: hz = (int) sysconf (_SC_CLK_TCK);
! 432: #endif /* not HAVE_SYSCONF && _SC_CLK_TCK */
! 433: #ifdef OVERRIDE_HZ
! 434: hz = DEFAULT_HZ;
! 435: #endif
! 436: ktick = tick;
! 437: #ifdef PRESET_TICK
! 438: tick = PRESET_TICK;
! 439: #endif /* PRESET_TICK */
! 440: #ifdef TICKADJ_NANO
! 441: tickadj /= 1000;
! 442: if (tickadj == 0)
! 443: tickadj = 1;
! 444: #endif
! 445: ktickadj = tickadj;
! 446: #ifdef PRESET_TICKADJ
! 447: tickadj = (PRESET_TICKADJ) ? PRESET_TICKADJ : 1;
! 448: #endif /* PRESET_TICKADJ */
! 449:
! 450: if (!quiet)
! 451: {
! 452: if (tick_offset != 0)
! 453: {
! 454: (void) printf("KERNEL tick = %d usec (from %s kernel variable)\n",
! 455: ktick,
! 456: #ifdef K_TICK_NAME
! 457: K_TICK_NAME
! 458: #else
! 459: "<this can't happen>"
! 460: #endif
! 461: );
! 462: }
! 463: #ifdef PRESET_TICK
! 464: (void) printf("PRESET tick = %d usec\n", tick);
! 465: #endif /* PRESET_TICK */
! 466: if (tickadj_offset != 0)
! 467: {
! 468: (void) printf("KERNEL tickadj = %d usec (from %s kernel variable)\n",
! 469: ktickadj,
! 470: #ifdef K_TICKADJ_NAME
! 471: K_TICKADJ_NAME
! 472: #else
! 473: "<this can't happen>"
! 474: #endif
! 475: );
! 476: }
! 477: #ifdef PRESET_TICKADJ
! 478: (void) printf("PRESET tickadj = %d usec\n", tickadj);
! 479: #endif /* PRESET_TICKADJ */
! 480: if (dosync_offset != 0)
! 481: {
! 482: (void) printf("dosynctodr is %s\n", dosynctodr ? "on" : "off");
! 483: }
! 484: if (noprintf_offset != 0)
! 485: {
! 486: (void) printf("kernel level printf's: %s\n",
! 487: noprintf ? "off" : "on");
! 488: }
! 489: }
! 490:
! 491: if (tick <= 0)
! 492: {
! 493: (void) fprintf(stderr, "%s: the value of tick is silly!\n",
! 494: progname);
! 495: exit(1);
! 496: }
! 497:
! 498: hz_int = (int)(1000000L / (long)tick);
! 499: hz_hundredths = (int)((100000000L / (long)tick) - ((long)hz_int * 100L));
! 500: if (!quiet)
! 501: {
! 502: (void) printf("KERNEL hz = %d\n", hz);
! 503: (void) printf("calculated hz = %d.%02d Hz\n", hz_int,
! 504: hz_hundredths);
! 505: }
! 506:
! 507: #if defined SCO5_CLOCK
! 508: recommend_tickadj = 100;
! 509: #else /* SCO5_CLOCK */
! 510: tmp = (long) tick * 500L;
! 511: recommend_tickadj = (int)(tmp / 1000000L);
! 512: if (tmp % 1000000L > 0)
! 513: {
! 514: recommend_tickadj++;
! 515: }
! 516:
! 517: #ifdef MIN_REC_TICKADJ
! 518: if (recommend_tickadj < MIN_REC_TICKADJ)
! 519: {
! 520: recommend_tickadj = MIN_REC_TICKADJ;
! 521: }
! 522: #endif /* MIN_REC_TICKADJ */
! 523: #endif /* SCO5_CLOCK */
! 524:
! 525:
! 526: if ((!quiet) && (tickadj_offset != 0))
! 527: {
! 528: (void) printf("recommended value of tickadj = %d us\n",
! 529: recommend_tickadj);
! 530: }
! 531:
! 532: if ( writetickadj == 0
! 533: && !writeopttickadj
! 534: && !unsetdosync
! 535: && writetick == 0
! 536: && !setnoprintf)
! 537: {
! 538: exit(errflg ? 1 : 0);
! 539: }
! 540:
! 541: if (writetickadj == 0 && writeopttickadj)
! 542: {
! 543: writetickadj = recommend_tickadj;
! 544: }
! 545:
! 546: fd = openfile(file, O_WRONLY);
! 547:
! 548: if (setnoprintf && (noprintf_offset != 0))
! 549: {
! 550: if (!quiet)
! 551: {
! 552: (void) fprintf(stderr, "setting noprintf: ");
! 553: (void) fflush(stderr);
! 554: }
! 555: writevar(fd, noprintf_offset, 1);
! 556: if (!quiet)
! 557: {
! 558: (void) fprintf(stderr, "done!\n");
! 559: }
! 560: }
! 561:
! 562: if ((writetick > 0) && (tick_offset != 0))
! 563: {
! 564: if (!quiet)
! 565: {
! 566: (void) fprintf(stderr, "writing tick, value %d: ",
! 567: writetick);
! 568: (void) fflush(stderr);
! 569: }
! 570: writevar(fd, tick_offset, writetick);
! 571: if (!quiet)
! 572: {
! 573: (void) fprintf(stderr, "done!\n");
! 574: }
! 575: }
! 576:
! 577: if ((writetickadj > 0) && (tickadj_offset != 0))
! 578: {
! 579: if (!quiet)
! 580: {
! 581: (void) fprintf(stderr, "writing tickadj, value %d: ",
! 582: writetickadj);
! 583: (void) fflush(stderr);
! 584: }
! 585:
! 586: #ifdef SCO5_CLOCK
! 587: /* scale from usec/tick to nsec/sec */
! 588: writetickadj *= (1000L * HZ);
! 589: #endif /* SCO5_CLOCK */
! 590:
! 591: writevar(fd, tickadj_offset, writetickadj);
! 592: if (!quiet)
! 593: {
! 594: (void) fprintf(stderr, "done!\n");
! 595: }
! 596: }
! 597:
! 598: if (unsetdosync && (dosync_offset != 0))
! 599: {
! 600: if (!quiet)
! 601: {
! 602: (void) fprintf(stderr, "zeroing dosynctodr: ");
! 603: (void) fflush(stderr);
! 604: }
! 605: writevar(fd, dosync_offset, 0);
! 606: if (!quiet)
! 607: {
! 608: (void) fprintf(stderr, "done!\n");
! 609: }
! 610: }
! 611: (void) close(fd);
! 612: return(errflg ? 1 : 0);
! 613: }
! 614:
! 615: /*
! 616: * getoffsets - read the magic offsets from the specified file
! 617: */
! 618: static void
! 619: getoffsets(
! 620: off_t *tick_off,
! 621: off_t *tickadj_off,
! 622: off_t *dosync_off,
! 623: off_t *noprintf_off
! 624: )
! 625: {
! 626:
! 627: #ifndef NOKMEM
! 628: # ifndef HAVE_KVM_OPEN
! 629: const char **kname;
! 630: # endif
! 631: #endif
! 632:
! 633: #ifndef NOKMEM
! 634: # ifdef NLIST_NAME_UNION
! 635: # define NL_B {{
! 636: # define NL_E }}
! 637: # else
! 638: # define NL_B {
! 639: # define NL_E }
! 640: # endif
! 641: #endif
! 642:
! 643: #define K_FILLER_NAME "DavidLetterman"
! 644:
! 645: #ifdef NLIST_EXTRA_INDIRECTION
! 646: int i;
! 647: #endif
! 648:
! 649: #ifndef NOKMEM
! 650: static struct nlist nl[] =
! 651: {
! 652: NL_B
! 653: #ifdef K_TICKADJ_NAME
! 654: #define N_TICKADJ 0
! 655: K_TICKADJ_NAME
! 656: #else
! 657: K_FILLER_NAME
! 658: #endif
! 659: NL_E,
! 660: NL_B
! 661: #ifdef K_TICK_NAME
! 662: #define N_TICK 1
! 663: K_TICK_NAME
! 664: #else
! 665: K_FILLER_NAME
! 666: #endif
! 667: NL_E,
! 668: NL_B
! 669: #ifdef K_DOSYNCTODR_NAME
! 670: #define N_DOSYNC 2
! 671: K_DOSYNCTODR_NAME
! 672: #else
! 673: K_FILLER_NAME
! 674: #endif
! 675: NL_E,
! 676: NL_B
! 677: #ifdef K_NOPRINTF_NAME
! 678: #define N_NOPRINTF 3
! 679: K_NOPRINTF_NAME
! 680: #else
! 681: K_FILLER_NAME
! 682: #endif
! 683: NL_E,
! 684: NL_B "" NL_E,
! 685: };
! 686:
! 687: #ifndef HAVE_KVM_OPEN
! 688: static const char *kernels[] =
! 689: {
! 690: #ifdef HAVE_GETBOOTFILE
! 691: NULL, /* *** SEE BELOW! *** */
! 692: #endif
! 693: "/kernel/unix",
! 694: "/kernel",
! 695: "/vmunix",
! 696: "/unix",
! 697: "/mach",
! 698: "/hp-ux",
! 699: "/386bsd",
! 700: "/netbsd",
! 701: "/stand/vmunix",
! 702: "/bsd",
! 703: NULL
! 704: };
! 705: #endif /* not HAVE_KVM_OPEN */
! 706:
! 707: #ifdef HAVE_KVM_OPEN
! 708: /*
! 709: * Solaris > 2.5 doesn't have a kernel file. Use the kvm_* interface
! 710: * to read the kernel name list. -- stolcke 3/4/96
! 711: */
! 712: kvm_t *kvm_handle = kvm_open(NULL, NULL, NULL, O_RDONLY, progname);
! 713:
! 714: if (kvm_handle == NULL)
! 715: {
! 716: (void) fprintf(stderr,
! 717: "%s: kvm_open failed\n",
! 718: progname);
! 719: exit(1);
! 720: }
! 721: if (kvm_nlist(kvm_handle, nl) == -1)
! 722: {
! 723: (void) fprintf(stderr,
! 724: "%s: kvm_nlist failed\n",
! 725: progname);
! 726: exit(1);
! 727: }
! 728: kvm_close(kvm_handle);
! 729: #else /* not HAVE_KVM_OPEN */
! 730: #ifdef HAVE_GETBOOTFILE /* *** SEE HERE! *** */
! 731: if (kernels[0] == NULL)
! 732: {
! 733: char * cp = (char *)getbootfile();
! 734:
! 735: if (cp)
! 736: {
! 737: kernels[0] = cp;
! 738: }
! 739: else
! 740: {
! 741: kernels[0] = "/Placeholder";
! 742: }
! 743: }
! 744: #endif /* HAVE_GETBOOTFILE */
! 745: for (kname = kernels; *kname != NULL; kname++)
! 746: {
! 747: struct stat stbuf;
! 748:
! 749: if (stat(*kname, &stbuf) == -1)
! 750: {
! 751: continue;
! 752: }
! 753: if (nlist(*kname, nl) >= 0)
! 754: {
! 755: break;
! 756: }
! 757: else
! 758: {
! 759: (void) fprintf(stderr,
! 760: "%s: nlist didn't find needed symbols from <%s>: %s\n",
! 761: progname, *kname, strerror(errno));
! 762: }
! 763: }
! 764: if (*kname == NULL)
! 765: {
! 766: (void) fprintf(stderr,
! 767: "%s: Couldn't find the kernel\n",
! 768: progname);
! 769: exit(1);
! 770: }
! 771: #endif /* HAVE_KVM_OPEN */
! 772:
! 773: if (dokmem)
! 774: {
! 775: file = kmem;
! 776:
! 777: fd = openfile(file, O_RDONLY);
! 778: #ifdef NLIST_EXTRA_INDIRECTION
! 779: /*
! 780: * Go one more round of indirection.
! 781: */
! 782: for (i = 0; i < (sizeof(nl) / sizeof(struct nlist)); i++)
! 783: {
! 784: if ((nl[i].n_value) && (nl[i].n_sclass == 0x6b))
! 785: {
! 786: readvar(fd, nl[i].n_value, &nl[i].n_value);
! 787: }
! 788: }
! 789: #endif /* NLIST_EXTRA_INDIRECTION */
! 790: }
! 791: #endif /* not NOKMEM */
! 792:
! 793: *tickadj_off = 0;
! 794: *tick_off = 0;
! 795: *dosync_off = 0;
! 796: *noprintf_off = 0;
! 797:
! 798: #if defined(N_TICKADJ)
! 799: *tickadj_off = nl[N_TICKADJ].n_value;
! 800: #endif
! 801:
! 802: #if defined(N_TICK)
! 803: *tick_off = nl[N_TICK].n_value;
! 804: #endif
! 805:
! 806: #if defined(N_DOSYNC)
! 807: *dosync_off = nl[N_DOSYNC].n_value;
! 808: #endif
! 809:
! 810: #if defined(N_NOPRINTF)
! 811: *noprintf_off = nl[N_NOPRINTF].n_value;
! 812: #endif
! 813: return;
! 814: }
! 815:
! 816: #undef N_TICKADJ
! 817: #undef N_TICK
! 818: #undef N_DOSYNC
! 819: #undef N_NOPRINTF
! 820:
! 821:
! 822: /*
! 823: * openfile - open the file, check for errors
! 824: */
! 825: static int
! 826: openfile(
! 827: const char *name,
! 828: int mode
! 829: )
! 830: {
! 831: int ifd;
! 832:
! 833: ifd = open(name, mode);
! 834: if (ifd < 0)
! 835: {
! 836: (void) fprintf(stderr, "%s: open %s: ", progname, name);
! 837: perror("");
! 838: exit(1);
! 839: }
! 840: return ifd;
! 841: }
! 842:
! 843:
! 844: /*
! 845: * writevar - write a variable into the file
! 846: */
! 847: static void
! 848: writevar(
! 849: int ofd,
! 850: off_t off,
! 851: int var
! 852: )
! 853: {
! 854:
! 855: if (lseek(ofd, off, L_SET) == -1)
! 856: {
! 857: (void) fprintf(stderr, "%s: lseek fails: ", progname);
! 858: perror("");
! 859: exit(1);
! 860: }
! 861: if (write(ofd, (char *)&var, sizeof(int)) != sizeof(int))
! 862: {
! 863: (void) fprintf(stderr, "%s: write fails: ", progname);
! 864: perror("");
! 865: exit(1);
! 866: }
! 867: return;
! 868: }
! 869:
! 870:
! 871: /*
! 872: * readvar - read a variable from the file
! 873: */
! 874: static void
! 875: readvar(
! 876: int ifd,
! 877: off_t off,
! 878: int *var
! 879: )
! 880: {
! 881: int i;
! 882:
! 883: if (lseek(ifd, off, L_SET) == -1)
! 884: {
! 885: (void) fprintf(stderr, "%s: lseek fails: ", progname);
! 886: perror("");
! 887: exit(1);
! 888: }
! 889: i = read(ifd, (char *)var, sizeof(int));
! 890: if (i < 0)
! 891: {
! 892: (void) fprintf(stderr, "%s: read fails: ", progname);
! 893: perror("");
! 894: exit(1);
! 895: }
! 896: if (i != sizeof(int))
! 897: {
! 898: (void) fprintf(stderr, "%s: read expected %d, got %d\n",
! 899: progname, (int)sizeof(int), i);
! 900: exit(1);
! 901: }
! 902: return;
! 903: }
! 904: #endif /* not Linux */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>