File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / util / tickadj.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 1 month ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

    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>