int state_save(memfile_t *file) { stateheader_t header; block_t *block; int i; //clear the state info memset(&header,0,sizeof(stateheader_t)); //set the ident/version of the state header header.ident = ident; header.version = version; //calculate total data size for(i=0;blockinfo[i].type;i++) { blockinfo[i].size = 0; blockinfo[i].func(STATE_SIZE,(u8*)&blockinfo[i].size); if(blockinfo[i].size) { header.usize += blockinfo[i].size + 8; } } //write the state header writevar(header.ident,4); writevar(header.version,2); writevar(header.flags,2); writevar(header.usize,4); writevar(header.csize,4); writevar(header.crc32,4); //write each block for(i=0;blockinfo[i].type;i++) { if(blockinfo[i].size == 0) continue; printf("saving block '%4s' (%d bytes)\n",&blockinfo[i].type,blockinfo[i].size); block = block_create(blockinfo[i].type,blockinfo[i].size); blockinfo[i].func(STATE_SAVE,block->data); block_save(file,block); block_destroy(block); } return(0); }
/* * main - parse arguments and handle options */ int main( int argc, char *argv[] ) { int c; int errflg = 0; off_t tickadj_offset; off_t tick_offset; off_t dosync_offset; off_t noprintf_offset; int tickadj, ktickadj; /* HMS: Why isn't this u_long? */ int tick, ktick; /* HMS: Why isn't this u_long? */ int dosynctodr; int noprintf; int hz; int hz_int, hz_hundredths; int recommend_tickadj; long tmp; progname = argv[0]; while ((c = ntp_getopt(argc, argv, "a:Adkpqst:")) != EOF) { switch (c) { case 'a': writetickadj = atoi(ntp_optarg); if (writetickadj <= 0) { (void) fprintf(stderr, "%s: unlikely value for tickadj: %s\n", progname, ntp_optarg); errflg++; } #if defined SCO5_CLOCK if (writetickadj % HZ) { writetickadj = (writetickadj / HZ) * HZ; (void) fprintf(stderr, "tickadj truncated to: %d\n", writetickadj); } #endif /* SCO5_CLOCK */ break; case 'A': writeopttickadj = 1; break; case 'd': ++debug; break; case 'k': dokmem = 1; break; case 'p': setnoprintf = 1; break; case 'q': quiet = 1; break; case 's': unsetdosync = 1; break; case 't': writetick = atoi(ntp_optarg); if (writetick <= 0) { (void) fprintf(stderr, "%s: unlikely value for tick: %s\n", progname, ntp_optarg); errflg++; } break; default: errflg++; break; } } if (errflg || ntp_optind != argc) { (void) fprintf(stderr, "usage: %s [-Adkpqs] [-a newadj] [-t newtick]\n", progname); exit(2); } getoffsets(&tick_offset, &tickadj_offset, &dosync_offset, &noprintf_offset); if (debug) { (void) printf("tick offset = %lu\n", (unsigned long)tick_offset); (void) printf("tickadj offset = %lu\n", (unsigned long)tickadj_offset); (void) printf("dosynctodr offset = %lu\n", (unsigned long)dosync_offset); (void) printf("noprintf offset = %lu\n", (unsigned long)noprintf_offset); } if (writetick && (tick_offset == 0)) { (void) fprintf(stderr, "No tick kernel variable\n"); errflg++; } if (writeopttickadj && (tickadj_offset == 0)) { (void) fprintf(stderr, "No tickadj kernel variable\n"); errflg++; } if (unsetdosync && (dosync_offset == 0)) { (void) fprintf(stderr, "No dosynctodr kernel variable\n"); errflg++; } if (setnoprintf && (noprintf_offset == 0)) { (void) fprintf(stderr, "No noprintf kernel variable\n"); errflg++; } if (tick_offset != 0) { readvar(fd, tick_offset, &tick); #if defined(TICK_NANO) && defined(K_TICK_NAME) if (!quiet) (void) printf("KERNEL %s = %d nsec\n", K_TICK_NAME, tick); #endif /* TICK_NANO && K_TICK_NAME */ #ifdef TICK_NANO tick /= 1000; #endif } else { tick = 0; } if (tickadj_offset != 0) { readvar(fd, tickadj_offset, &tickadj); #ifdef SCO5_CLOCK /* scale from nsec/sec to usec/tick */ tickadj /= (1000L * HZ); #endif /*SCO5_CLOCK */ #if defined(TICKADJ_NANO) && defined(K_TICKADJ_NAME) if (!quiet) (void) printf("KERNEL %s = %d nsec\n", K_TICKADJ_NAME, tickadj); #endif /* TICKADJ_NANO && K_TICKADJ_NAME */ #ifdef TICKADJ_NANO tickadj += 999; tickadj /= 1000; #endif } else { tickadj = 0; } if (dosync_offset != 0) { readvar(fd, dosync_offset, &dosynctodr); } if (noprintf_offset != 0) { readvar(fd, noprintf_offset, &noprintf); } (void) close(fd); if (unsetdosync && dosync_offset == 0) { (void) fprintf(stderr, "%s: can't find %s in namelist\n", progname, #ifdef K_DOSYNCTODR_NAME K_DOSYNCTODR_NAME #else /* not K_DOSYNCTODR_NAME */ "dosynctodr" #endif /* not K_DOSYNCTODR_NAME */ ); exit(1); } hz = HZ; #if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) hz = (int) sysconf (_SC_CLK_TCK); #endif /* not HAVE_SYSCONF && _SC_CLK_TCK */ #ifdef OVERRIDE_HZ hz = DEFAULT_HZ; #endif ktick = tick; #ifdef PRESET_TICK tick = PRESET_TICK; #endif /* PRESET_TICK */ #ifdef TICKADJ_NANO tickadj /= 1000; if (tickadj == 0) tickadj = 1; #endif ktickadj = tickadj; #ifdef PRESET_TICKADJ tickadj = (PRESET_TICKADJ) ? PRESET_TICKADJ : 1; #endif /* PRESET_TICKADJ */ if (!quiet) { if (tick_offset != 0) { (void) printf("KERNEL tick = %d usec (from %s kernel variable)\n", ktick, #ifdef K_TICK_NAME K_TICK_NAME #else "<this can't happen>" #endif ); } #ifdef PRESET_TICK (void) printf("PRESET tick = %d usec\n", tick); #endif /* PRESET_TICK */ if (tickadj_offset != 0) { (void) printf("KERNEL tickadj = %d usec (from %s kernel variable)\n", ktickadj, #ifdef K_TICKADJ_NAME K_TICKADJ_NAME #else "<this can't happen>" #endif ); } #ifdef PRESET_TICKADJ (void) printf("PRESET tickadj = %d usec\n", tickadj); #endif /* PRESET_TICKADJ */ if (dosync_offset != 0) { (void) printf("dosynctodr is %s\n", dosynctodr ? "on" : "off"); } if (noprintf_offset != 0) { (void) printf("kernel level printf's: %s\n", noprintf ? "off" : "on"); } } if (tick <= 0) { (void) fprintf(stderr, "%s: the value of tick is silly!\n", progname); exit(1); } hz_int = (int)(1000000L / (long)tick); hz_hundredths = (int)((100000000L / (long)tick) - ((long)hz_int * 100L)); if (!quiet) { (void) printf("KERNEL hz = %d\n", hz); (void) printf("calculated hz = %d.%02d Hz\n", hz_int, hz_hundredths); } #if defined SCO5_CLOCK recommend_tickadj = 100; #else /* SCO5_CLOCK */ tmp = (long) tick * 500L; recommend_tickadj = (int)(tmp / 1000000L); if (tmp % 1000000L > 0) { recommend_tickadj++; } #ifdef MIN_REC_TICKADJ if (recommend_tickadj < MIN_REC_TICKADJ) { recommend_tickadj = MIN_REC_TICKADJ; } #endif /* MIN_REC_TICKADJ */ #endif /* SCO5_CLOCK */ if ((!quiet) && (tickadj_offset != 0)) { (void) printf("recommended value of tickadj = %d us\n", recommend_tickadj); } if ( writetickadj == 0 && !writeopttickadj && !unsetdosync && writetick == 0 && !setnoprintf) { exit(errflg ? 1 : 0); } if (writetickadj == 0 && writeopttickadj) { writetickadj = recommend_tickadj; } fd = openfile(file, O_WRONLY); if (setnoprintf && (noprintf_offset != 0)) { if (!quiet) { (void) fprintf(stderr, "setting noprintf: "); (void) fflush(stderr); } writevar(fd, noprintf_offset, 1); if (!quiet) { (void) fprintf(stderr, "done!\n"); } } if ((writetick > 0) && (tick_offset != 0)) { if (!quiet) { (void) fprintf(stderr, "writing tick, value %d: ", writetick); (void) fflush(stderr); } writevar(fd, tick_offset, writetick); if (!quiet) { (void) fprintf(stderr, "done!\n"); } } if ((writetickadj > 0) && (tickadj_offset != 0)) { if (!quiet) { (void) fprintf(stderr, "writing tickadj, value %d: ", writetickadj); (void) fflush(stderr); } #ifdef SCO5_CLOCK /* scale from usec/tick to nsec/sec */ writetickadj *= (1000L * HZ); #endif /* SCO5_CLOCK */ writevar(fd, tickadj_offset, writetickadj); if (!quiet) { (void) fprintf(stderr, "done!\n"); } } if (unsetdosync && (dosync_offset != 0)) { if (!quiet) { (void) fprintf(stderr, "zeroing dosynctodr: "); (void) fflush(stderr); } writevar(fd, dosync_offset, 0); if (!quiet) { (void) fprintf(stderr, "done!\n"); } } (void) close(fd); return(errflg ? 1 : 0); }