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>