Annotation of embedaddon/ntp/util/tickadj.c, revision 1.1.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>