home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xntp3.zip / util / tickadj.c < prev   
C/C++ Source or Header  |  1992-07-07  |  8KB  |  385 lines

  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. #include <stdio.h>
  9. #include <nlist.h>
  10. #include <sys/types.h>
  11. #include <sys/file.h>
  12. #include <sys/stat.h>
  13. #ifdef RS6000
  14. #undef hz
  15. #endif RS6000
  16.  
  17. #define    KMEM    "/dev/kmem"
  18. #define    STREQ(a, b)    (*(a) == *(b) && strcmp((a), (b)) == 0)
  19.  
  20. char *progname;
  21. int debug;
  22.  
  23. int dokmem = 1;
  24. int writetickadj = 0;
  25. int writeopttickadj = 0;
  26. int unsetdosync = 0;
  27. int writetick = 0;
  28. int quiet = 0;
  29. int setnoprintf = 0;
  30.  
  31. char *kmem = KMEM;
  32. char *kernel = 0;
  33.  
  34.  
  35. /*
  36.  * main - parse arguments and handle options
  37.  */
  38. main(argc, argv)
  39. int argc;
  40. char *argv[];
  41. {
  42.     int c;
  43.     int errflg = 0;
  44.     extern int optind;
  45.     extern char *optarg;
  46.     unsigned long tickadj_offset;
  47.     unsigned long tick_offset;
  48.     unsigned long dosync_offset;
  49.     unsigned long noprintf_offset;
  50.     int tickadj;
  51.     int tick;
  52.     int dosynctodr;
  53.     int noprintf;
  54.     int hz, hz_hundredths;
  55.     int recommend_tickadj;
  56.     long tmp;
  57.     char *file;
  58.     int fd;
  59.     int openfile();
  60.     char *getoffsets();
  61.     void readvar();
  62.     void writevar();
  63.  
  64.     progname = argv[0];
  65.     while ((c = getopt(argc, argv, "a:Adkqpst:")) != EOF)
  66.         switch (c) {
  67.         case 'd':
  68.             ++debug;
  69.             break;
  70.         case 'k':
  71.             dokmem = 1;
  72.             break;
  73.         case 'p':
  74. #ifdef sun
  75.             setnoprintf = 1;
  76. #else
  77.             (void) fprintf(stderr, "%s: Noprintf only supported on SUN systems- IGNORED\n", progname);
  78. #endif            
  79.             break;
  80.         case 'q':
  81.             quiet = 1;
  82.             break;
  83.         case 'a':
  84.             writetickadj = atoi(optarg);
  85.             if (writetickadj <= 0) {
  86.                 (void) fprintf(stderr,
  87.                     "%s: unlikely value for tickadj: %s\n",
  88.                     progname, optarg);
  89.                 errflg++;
  90.             }
  91.             break;
  92.         case 'A':
  93.             writeopttickadj = 1;
  94.             break;
  95.         case 's':
  96.             unsetdosync = 1;
  97.             break;
  98.         case 't':
  99.             writetick = atoi(optarg);
  100.             if (writetick <= 0) {
  101.                 (void) fprintf(stderr,
  102.                     "%s: unlikely value for tick: %s\n",
  103.                     progname, optarg);
  104.                 errflg++;
  105.             }
  106.             break;
  107.         default:
  108.             errflg++;
  109.             break;
  110.         }
  111.     if (errflg || optind != argc) {
  112.         (void) fprintf(stderr,
  113.             "usage: %s [-Aqsp] [-a newadj] [-t newtick]\n", progname);
  114.         exit(2);
  115.     }
  116.     kernel = getoffsets(kernel, &tick_offset,
  117.         &tickadj_offset, &dosync_offset, &noprintf_offset);
  118.     if (debug) {
  119.         (void) printf("tick offset = %lu\n", tick_offset);
  120.         (void) printf("tickadj offset = %lu\n", tickadj_offset);
  121.         (void) printf("dosynctodr offset = %lu\n", dosync_offset);
  122.         (void) printf("noprintf offset = %lu\n", noprintf_offset);
  123.     }
  124.  
  125.     if (dokmem)
  126.         file = kmem;
  127.     else
  128.         file = kernel;
  129.  
  130.     fd = openfile(file, O_RDONLY);
  131.     readvar(fd, tickadj_offset, &tickadj);
  132.     readvar(fd, tick_offset, &tick);
  133.     if (dosync_offset != 0)
  134.         readvar(fd, dosync_offset, &dosynctodr);
  135.     if (noprintf_offset != 0)
  136.         readvar(fd, noprintf_offset, &noprintf);
  137.     (void) close(fd);
  138.  
  139.     if (unsetdosync && dosync_offset == 0) {
  140.         (void) fprintf(stderr,
  141.             "%s: can't find _dosynctodr in namelist\n", progname);
  142.         exit(1);
  143.     }
  144.  
  145.     if (!quiet) {
  146.         if (dosync_offset == 0)
  147.             (void) printf("tick = %d us, tickadj = %d us\n",
  148.                  tick, tickadj);
  149.         else
  150.             (void) printf(
  151.                 "tick = %d us, tickadj = %d us, dosynctodr is %s\n",
  152.                  tick, tickadj, dosynctodr ? "on" : "off");
  153.         if (noprintf_offset != 0)
  154.             (void) printf("kernel level printf's: %s\n", noprintf ? "off" : "on");
  155.     }
  156.  
  157.     if (tick <= 0) {
  158.         (void) fprintf(stderr, "%s: the value of tick is silly!\n");
  159.         exit(1);
  160.     }
  161.  
  162.     hz = (int)(1000000L / (long)tick);
  163.     hz_hundredths = (int)((100000000L / (long)tick) - ((long)hz * 100L));
  164.     if (!quiet)
  165.         (void) printf("calculated hz = %d.%02d Hz\n", hz,
  166.             hz_hundredths);
  167.     tmp = (long) tick * 500L;
  168.     recommend_tickadj = (int)(tmp / 1000000L);
  169.     if (tmp % 1000000L > 0)
  170.         recommend_tickadj++;
  171.     if (!quiet)
  172.         (void) printf("recommended value of tickadj = %d us\n",
  173.             recommend_tickadj);
  174.     
  175.     if (writetickadj == 0 && !writeopttickadj &&
  176.         !unsetdosync && writetick == 0 && !setnoprintf)
  177.         exit(0);
  178.  
  179.     if (writetickadj == 0 && writeopttickadj)
  180.         writetickadj = recommend_tickadj;
  181.  
  182.     fd = openfile(file, O_WRONLY);
  183.  
  184.     if (setnoprintf && (noprintf_offset != 0)) {
  185.         if (!quiet) {
  186.             (void) fprintf(stderr, "setting noprintf: ");
  187.             (void) fflush(stderr);
  188.         }
  189.         writevar(fd, noprintf_offset, 1);
  190.         if (!quiet)
  191.             (void) fprintf(stderr, "done!\n");
  192.     }
  193.  
  194.     if (writetick > 0) {
  195.         if (!quiet) {
  196.             (void) fprintf(stderr, "writing tick, value %d: ",
  197.                 writetick);
  198.             (void) fflush(stderr);
  199.         }
  200.         writevar(fd, tick_offset, writetick);
  201.         if (!quiet)
  202.             (void) fprintf(stderr, "done!\n");
  203.     }
  204.     if (writetickadj > 0) {
  205.         if (!quiet) {
  206.             (void) fprintf(stderr, "writing tickadj, value %d: ",
  207.                 writetickadj);
  208.             (void) fflush(stderr);
  209.         }
  210.         writevar(fd, tickadj_offset, writetickadj);
  211.         if (!quiet)
  212.             (void) fprintf(stderr, "done!\n");
  213.     }
  214.     if (unsetdosync) {
  215.         if (!quiet) {
  216.             (void) fprintf(stderr, "zeroing dosynctodr: ");
  217.             (void) fflush(stderr);
  218.         }
  219.         writevar(fd, dosync_offset, 0);
  220.         if (!quiet)
  221.             (void) fprintf(stderr, "done!\n");
  222.     }
  223.     (void) close(fd);
  224.     exit(0);
  225. }
  226.  
  227. /*
  228.  * getoffsets - read the magic offsets from the specified file
  229.  */
  230. char *
  231. getoffsets(file, tick_off, tickadj_off, dosync_off, noprintf_off)
  232.     char *file;
  233.     unsigned long *tick_off;
  234.     unsigned long *tickadj_off;
  235.     unsigned long *dosync_off;
  236.     unsigned long *noprintf_off;
  237. {
  238.     char **kname;
  239.     int err = 0;
  240. #ifdef    NeXT
  241.     static struct nlist nl[] =
  242.     {    {{"_tickadj"}},
  243.         {{"_tick"}},
  244.         {{"_dosynctodr"}},
  245.         {{"_noprintf"}},
  246.         {{""}},
  247.     };
  248. #else
  249.     static struct nlist nl[] =
  250.     {    {"_tickadj"},
  251.         {"_tick"},
  252.         {"_dosynctodr"},
  253.         {"_noprintf"},
  254.         {""},
  255.     };
  256. #endif
  257.     static char *kernels[] = {
  258.         "/vmunix",
  259.         "/unix",
  260.         "/mach",
  261.         NULL
  262.     };
  263.     struct stat stbuf;
  264.  
  265. #define    K_TICKADJ    0
  266. #define    K_TICK        1
  267. #define    K_DOSYNC    2
  268. #define    K_NOPRINTF    3
  269.     for (kname = kernels; *kname != NULL; kname++) {
  270.         if (stat(*kname, &stbuf) == -1)
  271.             continue;
  272.         if (nlist(*kname, nl) >= 0)
  273.             break;
  274.     }
  275.     if (*kname == NULL) {
  276.         (void) fprintf(stderr,
  277.             "%s: nlist fails: can't find/read /vmunix or /unix\n",
  278.             progname);
  279.         exit(1);
  280.     }
  281.  
  282.     if (nl[K_TICKADJ].n_value == 0) {
  283.         (void) fprintf(stderr, "%s: namelist can't find `_tickadj'\n",
  284.             progname);
  285.         err++;
  286.     }
  287.     if (nl[K_TICK].n_value == 0) {
  288.         (void) fprintf(stderr, "%s: namelist can't find `_tick'\n",
  289.             progname);
  290.         err++;
  291.     }
  292. #ifdef sun
  293.     if (nl[K_NOPRINTF].n_value == 0) {
  294.         (void) fprintf(stderr, "%s: namelist can't find `_noprintf'\n",
  295.             progname);
  296.         err++;
  297.     }
  298. #endif
  299.     if (err)
  300.         exit(1);
  301.  
  302.     *tickadj_off = nl[K_TICKADJ].n_value;
  303.     *tick_off = nl[K_TICK].n_value;
  304.     *dosync_off = nl[K_DOSYNC].n_value;
  305.     *noprintf_off = nl[K_NOPRINTF].n_value;
  306.     return *kname;
  307. #undef K_TICKADJ
  308. #undef K_TICK
  309. #undef K_DOSYNC
  310. #undef K_NOPRINTF
  311. }
  312.  
  313.  
  314. /*
  315.  * openfile - open the file, check for errors
  316.  */
  317. int
  318. openfile(name, mode)
  319.     char *name;
  320.     int mode;
  321. {
  322.     int fd;
  323.  
  324.     fd = open(name, mode);
  325.     if (fd < 0) {
  326.         (void) fprintf(stderr, "%s: open %s: ", progname, name);
  327.         perror("");
  328.         exit(1);
  329.     }
  330.     return fd;
  331. }
  332.  
  333.  
  334. /*
  335.  * writevar - write a variable into the file
  336.  */
  337. void
  338. writevar(fd, off, var)
  339.     int fd;
  340.     unsigned long off;
  341.     int var;
  342. {
  343.     
  344.     if (lseek(fd, off, L_SET) == -1) {
  345.         (void) fprintf(stderr, "%s: lseek fails: ", progname);
  346.         perror("");
  347.         exit(1);
  348.     }
  349.     if (write(fd, (char *)&var, sizeof(int)) != sizeof(int)) {
  350.         (void) fprintf(stderr, "%s: write fails: ", progname);
  351.         perror("");
  352.         exit(1);
  353.     }
  354. }
  355.  
  356.  
  357. /*
  358.  * readvar - read a variable from the file
  359.  */
  360. void
  361. readvar(fd, off, var)
  362.     int fd;
  363.     unsigned long off;
  364.     int *var;
  365. {
  366.     int i;
  367.     
  368.     if (lseek(fd, off, L_SET) == -1) {
  369.         (void) fprintf(stderr, "%s: lseek fails: ", progname);
  370.         perror("");
  371.         exit(1);
  372.     }
  373.     i = read(fd, (char *)var, sizeof(int));
  374.     if (i < 0) {
  375.         (void) fprintf(stderr, "%s: read fails: ", progname);
  376.         perror("");
  377.         exit(1);
  378.     }
  379.     if (i != sizeof(int)) {
  380.         (void) fprintf(stderr, "%s: read expected %d, got %d\n",
  381.             progname, sizeof(int), i);
  382.         exit(1);
  383.     }
  384. }
  385.