⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 5 页
字号:
        if ((offset < 0.0 ? -offset : offset) > x) maxoff = offset;        correction = 0.0;        if (operation == op_client || accepts >= count) {            if (action == action_display) {                format_time(text,100,offset,error,drift,drifterr);                printf("%s\n",text);            } else {                x = reset_clock(offset,error,1);                correction += x;                offset -= x;            }        } else            waiting = delay;        handle_saving(save_write,&total,&index,&cycle,record,&previous,&when,            &correction);/* Now correct the clock for a while, before getting another packet andupdating the statistics. */        while (when < previous+delay-waiting) {            do_nothing(waiting);            if (action == action_display)                when += waiting;            else {                correction += correct_drift(&when,&offset,drift);                handle_saving(save_write,&total,&index,&cycle,record,                    &previous,&when,&correction);            }        }continue1: ;    }}void run_client (char *hostnames[], int nhosts) {/* Get enough responses to do something with; or not, as the case may be.  Notethat it allows for half of the packets to be bad, so may make up to twice asmany attempts as specified by the -c value.  The deadline checking is merelyparanoia, to protect against broken signal handling - it cannot easily betriggered if the signal handling works. */    double history[COUNT_MAX], guesses[COUNT_MAX], offset, error, deadline,        a, b, x, y;    int accepts = 0, rejects = 0, flushes = 0, replicates = 0, cycle = 0, k;    unsigned char transmit[NTP_PACKET_MIN];    ntp_data data;    char text[100];    if (verbose > 2) {        format_time(text,50,0.0,-1.0,0.0,-1.0);        fprintf(stderr,"Started=%.6f %s\n",current_time(JAN_1970),text);    }    for (k = 0; k < nhosts; ++k) open_socket(k,hostnames[k],delay);    if (action != action_display) {        set_lock(1);        locked = 1;    }    attempts = 0;    deadline = current_time(JAN_1970)+delay;/* Listen to broadcast packets and select the best (i.e. earliest).  This willbe sensitive to a bad NTP broadcaster, but I believe such things are very rarein practice.  In any case, if you have one, it is probably the only one on yoursubnet, so you are knackered!  This allows up to ETHERNET_MAX replications perpacket, for systems with multiple addresses for receiving broadcasts; the onlyreason for a limit is to protect against broken NTP servers always returningthe same time. */    if (operation == op_listen) {        while (accepts < count) {            if (current_time(JAN_1970) > deadline)                fatal(0,"not enough valid broadcasts received in time",NULL);            flushes += flush_socket(0);            if (read_packet(0,&data,&x,&y)) {                if (++rejects > count)                    fatal(0,"too many bad or lost packets",NULL);                else                    continue;            } else {                a = data.transmit;                for (k = 0; k < accepts; ++k)                    if (a == history[k]) {                        if (++replicates > ETHERNET_MAX*count)                            fatal(0,"too many replicated packets",NULL);                        goto continue1;                    }                history[accepts] = a;                guesses[accepts++] = x;            }            if (verbose > 2)                fprintf(stderr,"Offset=%.6f disp=%.6f\n",x,dispersion);            else if (verbose > 1)                fprintf(stderr,"%s: offset=%.3f disp=%.3f\n",                    argv0,x,dispersion);/* Note that bubblesort IS a good method for this amount of data.  */            for (k = accepts-2; k >= 0; --k)                if (guesses[k] < guesses[k+1])                    break;                else {                    x = guesses[k];                    guesses[k] = guesses[k+1];                    guesses[k+1] = x;                }continue1:  ;        }        offset = guesses[0];        error = minerr+guesses[count <= 5 ? count-1 : 5]-offset;        if (verbose > 2)            fprintf(stderr,"accepts=%d rejects=%d flushes=%d replicates=%d\n",                accepts,rejects,flushes,replicates);/* Handle the client/server model.  It keeps a record of transmitted times,mainly out of paranoia. */    } else {        offset = 0.0;        error = NTP_INSANITY;        while (accepts < count && attempts < 2*count) {            if (current_time(JAN_1970) > deadline)                fatal(0,"not enough valid responses received in time",NULL);            make_packet(&data,NTP_CLIENT);            outgoing[attempts++] = data.transmit;            if (verbose > 2) {                fprintf(stderr,"Outgoing packet on socket %d:\n",cycle);                display_data(&data);            }            pack_ntp(transmit,NTP_PACKET_MIN,&data);            if (verbose > 2) display_packet(transmit,NTP_PACKET_MIN);            flushes += flush_socket(cycle);            write_socket(cycle,transmit,NTP_PACKET_MIN);            if (read_packet(cycle,&data,&x,&y)) {                if (++rejects > count)                    fatal(0,"too many bad or lost packets",NULL);                else                    continue;            } else                ++accepts;            if (++cycle >= nhosts) cycle = 0;/* Work out the most accurate time, and check that it isn't more accurate thanthe results warrant. */            if (verbose > 2)                fprintf(stderr,"Offset=%.6f+/-%.6f disp=%.6f\n",x,y,dispersion);            else if (verbose > 1)                fprintf(stderr,"%s: offset=%.3f+/-%.3f disp=%.3f\n",                    argv0,x,y,dispersion);            if ((a = x-offset) < 0.0) a = -a;            if (accepts <= 1) a = 0.0;            b = error+y;            if (y < error) {                offset = x;                error = y;            }            if (verbose > 2)                fprintf(stderr,"best=%.6f+/-%.6f\n",offset,error);            if (a > b) {                sprintf(text,"%d",cycle);                fatal(0,"inconsistent times got from NTP server on socket %s",                    text);            }            if (error <= minerr) break;        }        if (verbose > 2)            fprintf(stderr,"accepts=%d rejects=%d flushes=%d\n",                accepts,rejects,flushes);    }/* Tidy up the socket, issues diagnostics and perform the action. */    for (k = 0; k < nhosts; ++k) close_socket(k);    if (accepts == 0) fatal(0,"no acceptable packets received",NULL);    if (error > NTP_INSANITY)        fatal(0,"unable to get a reasonable time estimate",NULL);    if (verbose > 2)        fprintf(stderr,"Correction: %.6f +/- %.6f disp=%.6f\n",            offset,error,dispersion);    if (action == action_display) {        format_time(text,75,offset,error,0.0,-1.0);        printf("%s\n",text);    } else        (void)reset_clock(offset,error,0);    if (locked) set_lock(0);    if (verbose > 2) fprintf(stderr,"Stopped normally\n");    exit(EXIT_SUCCESS);}int main (int argc, char *argv[]) {/* This is the entry point and all that.  It decodes the arguments and callsone of the specialised routines to do the work. */    char *hostnames[MAX_SOCKETS], *savename = NULL;    int daemon = 0, nhosts = 0, help = 0, args = argc-1, k;    char c;    if (argv[0] == NULL || argv[0][0] == '\0')        argv0 = "sntp";    else if ((argv0 = strrchr(argv[0],'/')) != NULL)        ++argv0;    else        argv0 = argv[0];    setvbuf(stdout,NULL,_IOLBF,BUFSIZ);    setvbuf(stderr,NULL,_IOLBF,BUFSIZ);    if (INT_MAX < 2147483647) fatal(0,"sntp requires >= 32-bit ints",NULL);    if (DBL_EPSILON > 1.0e-13)        fatal(0,"sntp requires doubles with eps <= 1.0e-13",NULL);    for (k = 0; k < MAX_SOCKETS; ++k) hostnames[k] = NULL;/* Decode the arguments. */    while (argc > 1) {        k = 1;	if (strcmp(argv[1],"-4") == 0)	    preferred_family(PREF_FAM_INET);	else if (strcmp(argv[1],"-6") == 0)	    preferred_family(PREF_FAM_INET6);        else if (strcmp(argv[1],"-q") == 0 && action == 0)            action = action_query;        else if (strcmp(argv[1],"-r") == 0 && action == 0)            action = action_reset;        else if (strcmp(argv[1],"-a") == 0 && action == 0)            action = action_adjust;        else if (strcmp(argv[1],"-l") == 0 && lockname == NULL && argc > 2) {            lockname = argv[2];            k = 2;        } else if ((strcmp(argv[1],"-x") == 0) &&                daemon == 0) {            if (argc > 2 && sscanf(argv[2],"%d%c",&daemon,&c) == 1) {                if (daemon < 1 || daemon > 1440)                    fatal(0,"%s option value out of range",argv[1]);                k = 2;            } else                daemon = 300;        } else if (strcmp(argv[1],"-f") == 0 && savename == NULL && argc > 2) {            savename = argv[2];            k = 2;        } else if ((strcmp(argv[1],"--help") == 0 ||                    strcmp(argv[1],"-h") == 0 || strcmp(argv[1],"-?") == 0) &&                help == 0)            help = 1;        else if (strcmp(argv[1],"-v") == 0 && verbose == 0)            verbose = 1;        else if (strcmp(argv[1],"-V") == 0 && verbose == 0)            verbose = 2;        else if (strcmp(argv[1],"-W") == 0 && verbose == 0)            verbose = 3;        else if (strcmp(argv[1],"-e") == 0 && minerr == 0.0 && argc > 2) {            if (sscanf(argv[2],"%lf%c",&minerr,&c) != 1) syntax(1);            if (minerr <= 0.000999999 || minerr > 1.0)                fatal(0,"%s option value out of range","-e");            k = 2;        } else if (strcmp(argv[1],"-E") == 0 && maxerr == 0.0 && argc > 2) {            if (sscanf(argv[2],"%lf%c",&maxerr,&c) != 1) syntax(1);            if (maxerr < 1.0 || maxerr > 60.0)                fatal(0,"%s option value out of range","-E");            k = 2;        } else if (strcmp(argv[1],"-P") == 0 && prompt == 0.0 && argc > 2) {            if (strcmp(argv[2],"no") == 0)                prompt = (double)INT_MAX;            else {                if (sscanf(argv[2],"%lf%c",&prompt,&c) != 1) syntax(1);                if (prompt < 1.0 || prompt > 3600.0)                    fatal(0,"%s option value out of range","-p");            }            k = 2;        } else if (strcmp(argv[1],"-d") == 0 && delay == 0 && argc > 2) {            if (sscanf(argv[2],"%d%c",&delay,&c) != 1) syntax(1);            if (delay < 1 || delay > 3600)                fatal(0,"%s option value out of range","-d");            k = 2;        } else if (strcmp(argv[1],"-c") == 0 && count == 0 && argc > 2) {            if (sscanf(argv[2],"%d%c",&count,&c) != 1) syntax(1);            if (count < 1 || count > COUNT_MAX)                fatal(0,"%s option value out of range","-c");            k = 2;        } else            break;        argc -= k;        argv += k;    }/* Check the arguments for consistency and set the defaults. */    if (action == action_query) {        if (argc != 1 || minerr != 0.0 || maxerr != 0.0 || count != 0 ||                delay != 0 || daemon != 0 || prompt != 0.0 || lockname != NULL)            syntax(1);    } else {        if (argc < 1 || argc > MAX_SOCKETS || (daemon != 0 && delay != 0))            syntax(1);        if ((prompt || lockname != NULL) &&                action != action_reset && action != action_adjust)            syntax(1);        if (count > 0 && count < argc-1)            fatal(0,"-c value less than number of addresses",NULL);       if (argc > 1) {            operation = op_client;            for (k = 1; k < argc; ++k) {                if (argv[k][0] == '\0' || argv[k][0] == '-')                    fatal(0,"invalid Internet address '%s'",argv[k]);                hostnames[k-1] = argv[k];            }            nhosts = argc-1;        } else {            operation = op_listen;            nhosts = 0;        }        if (action == 0) action = action_display;        if (minerr <= 0.0) minerr = (operation == op_listen ? 0.5 : 0.1);        if (maxerr <= 0.0) maxerr = 5.0;        if (count == 0) count = (argc-1 < 5 ? 5 : argc-1);        if ((argc == 1 || (daemon != 0 && action != action_query)) && count < 5)            fatal(0,"at least 5 packets needed in this mode",NULL);        if ((action == action_reset || action == action_adjust) &&                lockname == NULL)            lockname = LOCKNAME;/* The '-x' option changes the implications of many other settings, though thisis not usually apparent to the caller.  Most of the time delays are to ensurethat stuck states terminate, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -