~ubuntu-branches/debian/squeeze/ntp/squeeze-201010051545

« back to all changes in this revision

Viewing changes to ntpdc/ntpdc.c

  • Committer: Bazaar Package Importer
  • Author(s): Matt Zimmerman
  • Date: 2004-10-11 16:10:27 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20041011161027-icyjbji8ujym633o
Tags: 1:4.2.0a-10ubuntu2
Use ntp.ubuntulinux.org instead of pool.ntp.org

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
#include "ntp_select.h"
9
9
#include "ntp_io.h"
10
10
#include "ntp_stdlib.h"
 
11
/* Don't include ISC's version of IPv6 variables and structures */
 
12
#define ISC_IPV6_H 1
 
13
#include "isc/net.h"
 
14
#include "isc/result.h"
11
15
 
12
16
#include <ctype.h>
13
17
#include <signal.h>
20
24
# define closesocket close
21
25
#endif /* SYS_WINNT */
22
26
 
23
 
#ifdef HAVE_LIBREADLINE
 
27
#if defined(HAVE_LIBREADLINE) || defined (HAVE_LIBEDIT)
24
28
# include <readline/readline.h>
25
29
# include <readline/history.h>
26
 
#endif /* HAVE_LIBREADLINE */
 
30
#endif /* HAVE_LIBREADLINE || HAVE_LIBEDIT */
27
31
 
28
32
#ifdef SYS_VXWORKS
29
33
/* vxWorks needs mode flag -casey*/
45
49
static  u_long  info_auth_keyid;
46
50
 
47
51
/*
48
 
 * Type of key md5 or des
 
52
 * Type of key md5
49
53
 */
50
 
#define KEY_TYPE_DES    3
51
54
#define KEY_TYPE_MD5    4
52
55
 
53
 
static  int info_auth_keytype = KEY_TYPE_MD5;   /* MD5*/
 
56
static  int info_auth_keytype = KEY_TYPE_MD5;   /* MD5 */
54
57
u_long  current_time;           /* needed by authkeys; not used */
55
58
 
56
59
int             ntpdcmain       P((int, char **));
60
63
static  int     openhost        P((const char *));
61
64
static  int     sendpkt         P((char *, int));
62
65
static  void    growpktdata     P((void));
63
 
static  int     getresponse     P((int, int, int *, int *, char **));
 
66
static  int     getresponse     P((int, int, int *, int *, char **, int));
64
67
static  int     sendrequest     P((int, int, int, int, int, char *));
65
68
static  void    getcmds         P((void));
66
69
static  RETSIGTYPE abortcmd     P((int));
68
71
static  void    tokenize        P((const char *, char **, int *));
69
72
static  int     findcmd         P((char *, struct xcmd *, struct xcmd *, struct xcmd **));
70
73
static  int     getarg          P((char *, int, arg_v *));
71
 
static  int     getnetnum       P((const char *, u_int32 *, char *));
 
74
static  int     getnetnum       P((const char *, struct sockaddr_storage *, char *, int));
72
75
static  void    help            P((struct parse *, FILE *));
73
76
#ifdef QSORT_USES_VOID_P
74
77
static  int     helpsort        P((const void *, const void *));
108
111
        { "delay",      my_delay,       { OPT|INT, NO, NO, NO },
109
112
          { "msec", "", "", "" },
110
113
          "set the delay added to encryption time stamps" },
111
 
        { "host",       host,           { OPT|NTP_STR, NO, NO, NO },
112
 
          { "hostname", "", "", "" },
 
114
        { "host",       host,           { OPT|NTP_STR, OPT|NTP_STR, NO, NO },
 
115
          { "-4|-6", "hostname", "", "" },
113
116
          "specify the host whose NTP server we talk to" },
114
117
        { "passwd",     passwd,         { OPT|NTP_STR, NO, NO, NO },
115
118
          { "", "", "", "" },
151
154
#define MAXCMDS         100             /* maximum commands on cmd line */
152
155
#define MAXHOSTS        200             /* maximum hosts on cmd line */
153
156
#define MAXLINE         512             /* maximum line length */
154
 
#define MAXTOKENS       (1+MAXARGS+2)   /* maximum number of usable tokens */
 
157
#define MAXTOKENS       (1+1+MAXARGS+2) /* maximum number of usable tokens */
 
158
                                        /* command + -4|-6 + MAXARGS + */
 
159
                                        /* redirection */
155
160
 
156
161
/*
157
162
 * Some variables used and manipulated locally
160
165
static  struct timeval tvsout = { DEFSTIMEOUT, 0 };     /* secondary time out */
161
166
static  l_fp delay_time;                                /* delay time */
162
167
static  char currenthost[LENHOSTNAME];                  /* current host name */
163
 
static  struct sockaddr_in hostaddr = { 0 };            /* host address */
164
 
static  int showhostnames = 1;                          /* show host names by default */
 
168
int showhostnames = 1;                                  /* show host names by default */
165
169
 
166
 
static  int sockfd;                                     /* fd socket is openned on */
 
170
static  int ai_fam_templ;                               /* address family */
 
171
static  int ai_fam_default;                             /* default address family */
 
172
static  SOCKET sockfd;                                  /* fd socket is opened on */
167
173
static  int havehost = 0;                               /* set to 1 when host open */
168
 
struct servent *server_entry = NULL;            /* server entry for ntp */
 
174
int s_port = 0;
169
175
 
170
176
#if defined (SYS_WINNT) || defined (SYS_VXWORKS)
171
177
char password[9];
172
178
#endif /* SYS_WINNT || SYS_VXWORKS */
173
179
 
174
180
#ifdef SYS_WINNT
175
 
WORD wVersionRequested;
176
 
WSADATA wsaData;
177
181
DWORD NumberOfBytesWritten;
178
182
 
179
183
HANDLE  TimerThreadHandle = NULL;       /* 1998/06/03 - Used in ntplib/machines.c */
192
196
static  int pktdatasize;
193
197
 
194
198
/*
 
199
 * These are used to help the magic with old and new versions of ntpd.
 
200
 */
 
201
int impl_ver = IMPL_XNTPD;
 
202
static int req_pkt_size = REQ_LEN_NOMAC;
 
203
 
 
204
/*
195
205
 * For commands typed on the command line (with the -c option)
196
206
 */
197
207
static  int numcmds = 0;
263
273
    showhostnames = 0;              /* show host names by default */
264
274
    ntp_optind = 0;
265
275
    ntp_optarg = 0;
266
 
    server_entry = NULL;            /* server entry for ntp */
267
276
    havehost = 0;                   /* set to 1 when host open */
268
277
    numcmds = 0;
269
278
    numhosts = 0;
292
301
        taskPrioritySet(taskIdSelf(), 100 );
293
302
#endif
294
303
 
 
304
#ifdef SYS_WINNT
 
305
        if (!Win32InitSockets())
 
306
        {
 
307
                fprintf(stderr, "No useable winsock.dll:");
 
308
                exit(1);
 
309
        }
 
310
#endif /* SYS_WINNT */
 
311
 
 
312
        /* Check to see if we have IPv6. Otherwise force the -4 flag */
 
313
        if (isc_net_probeipv6() != ISC_R_SUCCESS) {
 
314
                ai_fam_default = AF_INET;
 
315
        }
 
316
 
295
317
        progname = argv[0];
296
 
        while ((c = ntp_getopt(argc, argv, "c:dilnps")) != EOF)
 
318
        ai_fam_templ = ai_fam_default;
 
319
        while ((c = ntp_getopt(argc, argv, "46c:dilnps")) != EOF)
297
320
            switch (c) {
 
321
                case '4':
 
322
                    ai_fam_templ = AF_INET;
 
323
                    break;
 
324
                case '6':
 
325
                    ai_fam_templ = AF_INET6;
 
326
                    break;
298
327
                case 'c':
299
328
                    ADDCMD(ntp_optarg);
300
329
                    break;
322
351
            }
323
352
        if (errflg) {
324
353
                (void) fprintf(stderr,
325
 
                               "usage: %s [-dilnps] [-c cmd] host ...\n",
 
354
                               "usage: %s [-46dilnps] [-c cmd] host ...\n",
326
355
                               progname);
327
356
                exit(2);
328
357
        }
353
382
        }
354
383
        pktdatasize = INITDATASIZE;
355
384
 
356
 
#ifdef SYS_WINNT
357
 
        wVersionRequested = MAKEWORD(1,1);
358
 
        if (WSAStartup(wVersionRequested, &wsaData)) {
359
 
                fprintf(stderr, "No useable winsock.dll");
360
 
                exit(1);
361
 
        }
362
 
#endif /* SYS_WINNT */
363
 
 
364
385
        if (numcmds == 0) {
365
386
                (void) openhost(chosts[0]);
366
387
                getcmds();
392
413
        const char *hname
393
414
        )
394
415
{
395
 
        u_int32 netnum;
396
416
        char temphost[LENHOSTNAME];
397
 
 
398
 
        if (server_entry == NULL) {
399
 
                server_entry = getservbyname("ntp", "udp");
400
 
                if (server_entry == NULL) {
401
 
#ifdef VMS /* UCX getservbyname() doesn't work [yet], but we do know better */
402
 
                        server_entry = (struct servent *)
403
 
                                malloc(sizeof(struct servent));
404
 
                        server_entry->s_port = htons(NTP_PORT);
405
 
#else
406
 
                        (void) fprintf(stderr, "%s: ntp/udp: unknown service\n",
407
 
                                       progname);
408
 
                        exit(1);
409
 
#endif /* VMS & UCX */
410
 
                }
411
 
                if (debug > 2)
412
 
                    printf("Got ntp/udp service entry\n");
413
 
        }
414
 
 
415
 
        if (!getnetnum(hname, &netnum, temphost))
416
 
            return 0;
417
 
        
 
417
        int a_info, i;
 
418
        struct addrinfo hints, *ai = NULL;
 
419
        register const char *cp;
 
420
        char name[LENHOSTNAME];
 
421
        char service[5];
 
422
 
 
423
        /*
 
424
         * We need to get by the [] if they were entered 
 
425
         */
 
426
        
 
427
        cp = hname;
 
428
        
 
429
        if (*cp == '[') {
 
430
                cp++;   
 
431
                for(i = 0; *cp != ']'; cp++, i++)
 
432
                        name[i] = *cp;  
 
433
                name[i] = '\0';
 
434
                hname = name;
 
435
        }       
 
436
 
 
437
        /*
 
438
         * First try to resolve it as an ip address and if that fails,
 
439
         * do a fullblown (dns) lookup. That way we only use the dns
 
440
         * when it is needed and work around some implementations that
 
441
         * will return an "IPv4-mapped IPv6 address" address if you
 
442
         * give it an IPv4 address to lookup.
 
443
         */
 
444
        strcpy(service, "ntp");
 
445
        memset((char *)&hints, 0, sizeof(struct addrinfo));
 
446
        hints.ai_family = ai_fam_templ;
 
447
        hints.ai_protocol = IPPROTO_UDP;
 
448
        hints.ai_socktype = SOCK_DGRAM;
 
449
        hints.ai_flags = AI_NUMERICHOST;
 
450
 
 
451
        a_info = getaddrinfo(hname, service, &hints, &ai);
 
452
        if (a_info == EAI_NONAME || a_info == EAI_NODATA) {
 
453
                hints.ai_flags = AI_CANONNAME;
 
454
#ifdef AI_ADDRCONFIG
 
455
                hints.ai_flags |= AI_ADDRCONFIG;
 
456
#endif
 
457
                a_info = getaddrinfo(hname, service, &hints, &ai);      
 
458
        }
 
459
        /* Some older implementations don't like AI_ADDRCONFIG. */
 
460
        if (a_info == EAI_BADFLAGS) {
 
461
                hints.ai_flags = AI_CANONNAME;
 
462
                a_info = getaddrinfo(hname, service, &hints, &ai);      
 
463
        }
 
464
        if (a_info != 0) {
 
465
                (void) fprintf(stderr, "%s\n", gai_strerror(a_info));
 
466
                return 0;
 
467
        }
 
468
 
 
469
        if (ai->ai_canonname == NULL) {
 
470
                strncpy(temphost, stoa((struct sockaddr_storage *)ai->ai_addr),
 
471
                    LENHOSTNAME);
 
472
                temphost[LENHOSTNAME-1] = '\0';
 
473
        } else {
 
474
                strncpy(temphost, ai->ai_canonname, LENHOSTNAME);
 
475
                temphost[LENHOSTNAME-1] = '\0';
 
476
        }
 
477
 
418
478
        if (debug > 2)
419
479
            printf("Opening host %s\n", temphost);
420
480
 
425
485
                havehost = 0;
426
486
        }
427
487
        (void) strcpy(currenthost, temphost);
428
 
 
429
 
        hostaddr.sin_family = AF_INET;
430
 
#ifndef SYS_VXWORKS
431
 
        hostaddr.sin_port = server_entry->s_port;
432
 
#else
433
 
        hostaddr.sin_port = htons(SERVER_PORT_NUM);
434
 
#endif
435
 
        hostaddr.sin_addr.s_addr = netnum;
 
488
        
 
489
        /* port maps to the same in both families */
 
490
        s_port = ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port; 
 
491
#ifdef SYS_VXWORKS
 
492
        ((struct sockaddr_in6 *)&hostaddr)->sin6_port = htons(SERVER_PORT_NUM);
 
493
        if (ai->ai_family == AF_INET)
 
494
                *(struct sockaddr_in *)&hostaddr= 
 
495
                        *((struct sockaddr_in *)ai->ai_addr);
 
496
        else 
 
497
                *(struct sockaddr_in6 *)&hostaddr= 
 
498
                        *((struct sockaddr_in6 *)ai->ai_addr);
 
499
#endif /* SYS_VXWORKS */
436
500
 
437
501
#ifdef SYS_WINNT
438
502
        {
439
503
                int optionValue = SO_SYNCHRONOUS_NONALERT;
440
504
                int err;
 
505
 
441
506
                err = setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&optionValue, sizeof(optionValue));
442
507
                if (err != NO_ERROR) {
443
508
                        (void) fprintf(stderr, "cannot open nonoverlapped sockets\n");
444
509
                        exit(1);
445
510
                }
446
511
        }
447
 
 
448
 
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 
512
 
 
513
        sockfd = socket(ai->ai_family, SOCK_DGRAM, 0);
449
514
        if (sockfd == INVALID_SOCKET) {
450
515
                error("socket", "", "");
451
516
                exit(-1);
452
517
        }
453
518
#else
454
 
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 
519
        sockfd = socket(ai->ai_family, SOCK_DGRAM, 0);
455
520
        if (sockfd == -1)
456
521
            error("socket", "", "");
457
522
#endif /* SYS_WINNT */
469
534
# endif
470
535
#endif
471
536
 
472
 
        if (connect(sockfd, (struct sockaddr *)&hostaddr,
 
537
#ifdef SYS_VXWORKS
 
538
        if (connect(sockfd, (struct sockaddr *)&hostaddr, 
473
539
                    sizeof(hostaddr)) == -1)
 
540
#else
 
541
        if (connect(sockfd, (struct sockaddr *)ai->ai_addr,
 
542
                    ai->ai_addrlen) == -1)
 
543
#endif /* SYS_VXWORKS */
474
544
            error("connect", "", "");
475
 
        
 
545
        if (a_info)
 
546
                freeaddrinfo(ai);
476
547
        havehost = 1;
 
548
        req_pkt_size = REQ_LEN_NOMAC;
 
549
        impl_ver = IMPL_XNTPD;
477
550
        return 1;
478
551
}
479
552
 
521
594
        int reqcode,
522
595
        int *ritems,
523
596
        int *rsize,
524
 
        char **rdata
 
597
        char **rdata,
 
598
        int esize
525
599
        )
526
600
{
527
601
        struct resp_pkt rpkt;
528
602
        struct timeval tvo;
529
603
        int items;
 
604
        int i;
530
605
        int size;
531
606
        int datasize;
532
607
        char *datap;
 
608
        char *tmp_data;
533
609
        char haveseq[MAXSEQ+1];
534
610
        int firstpkt;
535
611
        int lastseq;
537
613
        int seq;
538
614
        fd_set fds;
539
615
        int n;
 
616
        int pad;
540
617
 
541
618
        /*
542
619
         * This is pretty tricky.  We may get between 1 and many packets
660
737
                return (int)INFO_ERR(rpkt.err_nitems);
661
738
        }
662
739
 
663
 
 
664
740
        /*
665
741
         * Collect items and size.  Make sure they make sense.
666
742
         */
667
743
        items = INFO_NITEMS(rpkt.err_nitems);
668
744
        size = INFO_ITEMSIZE(rpkt.mbz_itemsize);
669
 
 
 
745
        if (esize > size)
 
746
                pad = esize - size;
 
747
        else 
 
748
                pad = 0;
670
749
        if ((datasize = items*size) > (n-RESP_HEADER_SIZE)) {
671
750
                if (debug)
672
751
                    printf(
679
758
         * If this isn't our first packet, make sure the size matches
680
759
         * the other ones.
681
760
         */
682
 
        if (!firstpkt && size != *rsize) {
 
761
        if (!firstpkt && esize != *rsize) {
683
762
                if (debug)
684
763
                    printf("Received itemsize %d, previous %d\n",
685
764
                           size, *rsize);
686
765
                goto again;
687
766
        }
688
 
 
689
767
        /*
690
 
         * If we've received this before, toss it
 
768
         * If we've received this before, +toss it
691
769
         */
692
770
        seq = INFO_SEQ(rpkt.auth_seq);
693
771
        if (haveseq[seq]) {
711
789
        /*
712
790
         * So far, so good.  Copy this data into the output array.
713
791
         */
714
 
        if ((datap + datasize) > (pktdata + pktdatasize)) {
 
792
        if ((datap + datasize + (pad * items)) > (pktdata + pktdatasize)) {
715
793
                int offset = datap - pktdata;
716
794
                growpktdata();
717
795
                *rdata = pktdata; /* might have been realloced ! */
718
796
                datap = pktdata + offset;
719
797
        }
720
 
        memmove(datap, (char *)rpkt.data, (unsigned)datasize);
721
 
        datap += datasize;
 
798
        /* 
 
799
         * We now move the pointer along according to size and number of
 
800
         * items.  This is so we can play nice with older implementations
 
801
         */
 
802
 
 
803
        tmp_data = (char *)rpkt.data;
 
804
        for(i = 0; i <items; i++){
 
805
                memmove(datap, tmp_data, (unsigned)size);
 
806
                tmp_data += size;
 
807
                memset(datap + size, 0, pad);
 
808
                datap += size + pad;
 
809
        }
 
810
 
722
811
        if (firstpkt) {
723
812
                firstpkt = 0;
724
 
                *rsize = size;
 
813
                *rsize = size + pad;
725
814
        }
726
815
        *ritems += items;
727
816
 
770
859
 
771
860
        if (!auth) {
772
861
                qpkt.auth_seq = AUTH_SEQ(0, 0);
773
 
                return sendpkt((char *)&qpkt, REQ_LEN_NOMAC);
 
862
                return sendpkt((char *)&qpkt, req_pkt_size);
774
863
        } else {
775
864
                l_fp ts;
776
865
                int maclen = 0;
777
866
                const char *pass = "\0";
 
867
                struct req_pkt_tail *qpktail;
 
868
 
 
869
                qpktail = (struct req_pkt_tail *)((char *)&qpkt + req_pkt_size
 
870
                    + MAX_MAC_LEN - sizeof(struct req_pkt_tail));
778
871
 
779
872
                if (info_auth_keyid == 0) {
780
873
                        maclen = getkeyid("Keyid: ");
786
879
                        info_auth_keyid = maclen;
787
880
                }
788
881
                if (!authistrusted(info_auth_keyid)) {
789
 
                        pass = getpass((info_auth_keytype == KEY_TYPE_DES)
790
 
                            ? "DES Password: " : "MD5 Password: ");
 
882
                        pass = getpass("MD5 Password: ");
791
883
                        if (*pass == '\0') {
792
884
                                (void) fprintf(stderr,
793
885
                                    "Invalid password\n");
797
889
                authusekey(info_auth_keyid, info_auth_keytype, (const u_char *)pass);
798
890
                authtrust(info_auth_keyid, 1);
799
891
                qpkt.auth_seq = AUTH_SEQ(1, 0);
800
 
                qpkt.keyid = htonl(info_auth_keyid);
 
892
                qpktail->keyid = htonl(info_auth_keyid);
801
893
                get_systime(&ts);
802
894
                L_ADD(&ts, &delay_time);
803
 
                HTONL_FP(&ts, &qpkt.tstamp);
 
895
                HTONL_FP(&ts, &qpktail->tstamp);
804
896
                maclen = authencrypt(info_auth_keyid, (u_int32 *)&qpkt,
805
 
                    REQ_LEN_NOMAC);
 
897
                    req_pkt_size);
806
898
                if (maclen == 0) {  
807
899
                        (void) fprintf(stderr, "Key not found\n");
808
900
                        return (1);
809
901
                }
810
 
                return sendpkt((char *)&qpkt, (int)(REQ_LEN_NOMAC + maclen));
 
902
                return sendpkt((char *)&qpkt, (int)(req_pkt_size + maclen));
811
903
        }
812
904
        /*NOTREACHED*/
813
905
}
827
919
        int *ritems,
828
920
        int *rsize,
829
921
        char **rdata,
830
 
        int quiet_mask
 
922
        int quiet_mask,
 
923
        int esize
831
924
        )
832
925
{
833
926
        int res;
846
939
        /*
847
940
         * Poll the socket and clear out any pending data
848
941
         */
 
942
again:
849
943
        do {
850
944
                tvzero.tv_sec = tvzero.tv_usec = 0;
851
945
                FD_ZERO(&fds);
871
965
        /*
872
966
         * Get the response.  If we got a standard error, print a message
873
967
         */
874
 
        res = getresponse(implcode, reqcode, ritems, rsize, rdata);
 
968
        res = getresponse(implcode, reqcode, ritems, rsize, rdata, esize);
 
969
 
 
970
        /*
 
971
         * Try to be compatible with older implementations of ntpd.
 
972
         */
 
973
        if (res == INFO_ERR_FMT && req_pkt_size != 48) {
 
974
                int oldsize;
 
975
 
 
976
                oldsize = req_pkt_size;
 
977
 
 
978
                switch(req_pkt_size) {
 
979
                case REQ_LEN_NOMAC:
 
980
                        req_pkt_size = 160;
 
981
                        break;
 
982
                case 160:
 
983
                        req_pkt_size = 48;
 
984
                        break;
 
985
                }
 
986
                if (impl_ver == IMPL_XNTPD) {
 
987
                        fprintf(stderr,
 
988
                            "***Warning changing to older implementation\n");
 
989
                        return INFO_ERR_IMPL;
 
990
                }
 
991
 
 
992
                fprintf(stderr,
 
993
                    "***Warning changing the request packet size from %d to %d\n",
 
994
                    oldsize, req_pkt_size);
 
995
                goto again;
 
996
        }
875
997
 
876
998
        /* log error message if not told to be quiet */
877
999
        if ((res > 0) && (((1 << res) & quiet_mask) == 0)) {
878
1000
                switch(res) {
879
1001
                    case INFO_ERR_IMPL:
 
1002
                        /* Give us a chance to try the older implementation. */
 
1003
                        if (implcode == IMPL_XNTPD)
 
1004
                                break;
880
1005
                        (void) fprintf(stderr,
881
1006
                                       "***Server implementation incompatable with our own\n");
882
1007
                        break;
918
1043
static void
919
1044
getcmds(void)
920
1045
{
921
 
#ifdef HAVE_LIBREADLINE
 
1046
#if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT)
922
1047
        char *line;
923
1048
 
924
1049
        for (;;) {
927
1052
                docmd(line);
928
1053
                free(line);
929
1054
        }
930
 
#else /* not HAVE_LIBREADLINE */
 
1055
#else /* not (HAVE_LIBREADLINE || HAVE_LIBEDIT) */
931
1056
        char line[MAXLINE];
932
1057
 
933
1058
        for (;;) {
944
1069
 
945
1070
                docmd(line);
946
1071
        }
947
 
#endif /* not HAVE_LIBREADLINE */
 
1072
#endif /* not HAVE_LIBREADLINE || HAVE_LIBEDIT */
948
1073
}
949
1074
 
950
1075
 
 
1076
#ifndef SYS_WINNT /* Under NT cannot handle SIGINT, WIN32 spawns a handler */
951
1077
/*
952
1078
 * abortcmd - catch interrupts and abort the current command
953
1079
 */
963
1089
        (void) fflush(stderr);
964
1090
        if (jump) longjmp(interrupt_buf, 1);
965
1091
}
966
 
 
 
1092
#endif /* SYS_WINNT */
967
1093
 
968
1094
/*
969
1095
 * docmd - decode the command line and execute a command
976
1102
        char *tokens[1+MAXARGS+2];
977
1103
        struct parse pcmd;
978
1104
        int ntok;
979
 
        static int i;
 
1105
        int i, ti;
 
1106
        int rval;
980
1107
        struct xcmd *xcmd;
981
1108
 
 
1109
        ai_fam_templ = ai_fam_default;
982
1110
        /*
983
1111
         * Tokenize the command line.  If nothing on it, return.
984
1112
         */
1006
1134
         */
1007
1135
        pcmd.keyword = tokens[0];
1008
1136
        pcmd.nargs = 0;
1009
 
        for (i = 0; i < MAXARGS && xcmd->arg[i] != NO; i++) {
1010
 
                if ((i+1) >= ntok) {
 
1137
        ti = 1;
 
1138
        for (i = 0; i < MAXARGS && xcmd->arg[i] != NO;) {
 
1139
                if ((i+ti) >= ntok) {
1011
1140
                        if (!(xcmd->arg[i] & OPT)) {
1012
1141
                                printusage(xcmd, stderr);
1013
1142
                                return;
1014
1143
                        }
1015
1144
                        break;
1016
1145
                }
1017
 
                if ((xcmd->arg[i] & OPT) && (*tokens[i+1] == '>'))
1018
 
                    break;
1019
 
                if (!getarg(tokens[i+1], (int)xcmd->arg[i], &pcmd.argval[i]))
1020
 
                    return;
 
1146
                if ((xcmd->arg[i] & OPT) && (*tokens[i+ti] == '>'))
 
1147
                        break;
 
1148
                rval = getarg(tokens[i+ti], (int)xcmd->arg[i], &pcmd.argval[i]);
 
1149
                if (rval == -1) {
 
1150
                        ti++;
 
1151
                        continue;
 
1152
                }
 
1153
                if (rval == 0)
 
1154
                        return;
1021
1155
                pcmd.nargs++;
 
1156
                i++;
1022
1157
        }
1023
1158
 
1024
 
        i++;
 
1159
        i += ti;
1025
1160
        if (i < ntok && *tokens[i] == '>') {
1026
1161
                char *fname;
1027
1162
 
1040
1175
                        perror("");
1041
1176
                        return;
1042
1177
                }
1043
 
                i = 1;          /* flag we need a close */
1044
1178
        } else {
1045
1179
                current_output = stdout;
1046
 
                i = 0;          /* flag no close */
1047
1180
        }
1048
1181
 
1049
1182
        if (interactive && setjmp(interrupt_buf)) {
1052
1185
                jump = 1;
1053
1186
                (xcmd->handler)(&pcmd, current_output);
1054
1187
                jump = 0;
1055
 
                if (i) (void) fclose(current_output);
 
1188
                if (current_output != stdout)
 
1189
                        (void) fclose(current_output);
 
1190
                current_output = NULL;
1056
1191
        }
1057
1192
}
1058
1193
 
1156
1291
}
1157
1292
 
1158
1293
 
1159
 
                                /*
 
1294
/*
1160
1295
 * getarg - interpret an argument token
 
1296
 *
 
1297
 * return:       0 - failure
 
1298
 *               1 - success
 
1299
 *              -1 - skip to next token
1161
1300
 */
1162
1301
static int
1163
1302
getarg(
1175
1314
                argp->string = str;
1176
1315
                break;
1177
1316
            case ADD:
1178
 
                if (!getnetnum(str, &(argp->netnum), (char *)0)) {
 
1317
                if (!strcmp("-6", str)) {
 
1318
                        ai_fam_templ = AF_INET6;
 
1319
                        return -1;
 
1320
                } else if (!strcmp("-4", str)) {
 
1321
                        ai_fam_templ = AF_INET;
 
1322
                        return -1;
 
1323
                }
 
1324
                if (!getnetnum(str, &(argp->netnum), (char *)0, 0)) {
1179
1325
                        return 0;
1180
1326
                }
1181
1327
                break;
1209
1355
                        argp->ival = -argp->ival;
1210
1356
                }
1211
1357
                break;
 
1358
            case IP_VERSION:
 
1359
                if (!strcmp("-6", str))
 
1360
                        argp->ival = 6 ;
 
1361
                else if (!strcmp("-4", str))
 
1362
                        argp->ival = 4 ;
 
1363
                else {
 
1364
                        (void) fprintf(stderr,
 
1365
                            "***Version must be either 4 or 6\n");
 
1366
                        return 0;
 
1367
                }
 
1368
                break;
1212
1369
        }
1213
1370
 
1214
1371
        return 1;
1222
1379
static int
1223
1380
getnetnum(
1224
1381
        const char *hname,
1225
 
        u_int32 *num,
1226
 
        char *fullhost
 
1382
        struct sockaddr_storage *num,
 
1383
        char *fullhost,
 
1384
        int af
1227
1385
        )
1228
1386
{
1229
 
        struct hostent *hp;
 
1387
        int sockaddr_len;
 
1388
        struct addrinfo hints, *ai = NULL;
1230
1389
 
 
1390
        sockaddr_len = (af == AF_INET)
 
1391
                           ? sizeof(struct sockaddr_in)
 
1392
                           : sizeof(struct sockaddr_in6);
 
1393
        memset((char *)&hints, 0, sizeof(struct addrinfo));
 
1394
        hints.ai_flags = AI_CANONNAME;
 
1395
#ifdef AI_ADDRCONFIG
 
1396
        hints.ai_flags |= AI_ADDRCONFIG;
 
1397
#endif
 
1398
        
 
1399
        /* decodenetnum only works with addresses */
1231
1400
        if (decodenetnum(hname, num)) {
1232
1401
                if (fullhost != 0) {
1233
 
                        (void) sprintf(fullhost,
1234
 
                                       "%u.%u.%u.%u", (u_int)((htonl(*num)>>24)&0xff),
1235
 
                                       (u_int)((htonl(*num)>>16)&0xff), (u_int)((htonl(*num)>>8)&0xff),
1236
 
                                       (u_int)(htonl(*num)&0xff));
 
1402
                        getnameinfo((struct sockaddr *)num, sockaddr_len, 
 
1403
                                    fullhost, sizeof(fullhost), NULL, 0, 
 
1404
                                    NI_NUMERICHOST); 
1237
1405
                }
1238
1406
                return 1;
1239
 
        } else if ((hp = gethostbyname(hname)) != 0) {
1240
 
                memmove((char *)num, hp->h_addr, sizeof(u_int32));
 
1407
        } else if (getaddrinfo(hname, "ntp", &hints, &ai) == 0) {
 
1408
                memmove((char *)num, ai->ai_addr, ai->ai_addrlen);
1241
1409
                if (fullhost != 0)
1242
 
                    (void) strcpy(fullhost, hp->h_name);
 
1410
                        (void) strcpy(fullhost, ai->ai_canonname);
1243
1411
                return 1;
1244
1412
        } else {
1245
1413
                (void) fprintf(stderr, "***Can't find host %s\n", hname);
1254
1422
 */
1255
1423
char *
1256
1424
nntohost(
1257
 
        u_int32 netnum
 
1425
        struct sockaddr_storage *netnum
1258
1426
        )
1259
1427
{
1260
1428
        if (!showhostnames)
1261
 
            return numtoa(netnum);
1262
 
        if ((ntohl(netnum) & REFCLOCK_MASK) == REFCLOCK_ADDR)
1263
 
            return refnumtoa(netnum);
1264
 
        return numtohost(netnum);
 
1429
            return stoa(netnum);
 
1430
 
 
1431
        if ((netnum->ss_family == AF_INET) && ISREFCLOCKADR(netnum))
 
1432
                return refnumtoa(netnum);
 
1433
        return socktohost(netnum);
1265
1434
}
1266
1435
 
1267
1436
 
1349
1518
        const void *t2
1350
1519
        )
1351
1520
{
1352
 
        const char **name1 = (const char **)t1;
1353
 
        const char **name2 = (const char **)t2;
 
1521
        char const * const * name1 = (char const * const *)t1;
 
1522
        char const * const * name2 = (char const * const *)t2;
1354
1523
 
1355
1524
        return strcmp(*name1, *name2);
1356
1525
}
1375
1544
        FILE *fp
1376
1545
        )
1377
1546
{
1378
 
        register int i;
 
1547
        int i, opt46;
1379
1548
 
 
1549
        opt46 = 0;
1380
1550
        (void) fprintf(fp, "usage: %s", xcp->keyword);
1381
1551
        for (i = 0; i < MAXARGS && xcp->arg[i] != NO; i++) {
 
1552
                if (opt46 == 0 && (xcp->arg[i] & ~OPT) == ADD) {
 
1553
                        (void) fprintf(fp, " [ -4|-6 ]");
 
1554
                        opt46 = 1;
 
1555
                }
1382
1556
                if (xcp->arg[i] & OPT)
1383
1557
                    (void) fprintf(fp, " [ %s ]", xcp->desc[i]);
1384
1558
                else
1453
1627
        FILE *fp
1454
1628
        )
1455
1629
{
 
1630
        int i;
 
1631
 
1456
1632
        if (pcmd->nargs == 0) {
1457
1633
                if (havehost)
1458
1634
                    (void) fprintf(fp, "current host is %s\n", currenthost);
1459
1635
                else
1460
1636
                    (void) fprintf(fp, "no current host\n");
1461
 
        } else if (openhost(pcmd->argval[0].string)) {
 
1637
                return;
 
1638
        }
 
1639
 
 
1640
        i = 0;
 
1641
        if (pcmd->nargs == 2) {
 
1642
                if (!strcmp("-4", pcmd->argval[i].string))
 
1643
                        ai_fam_templ = AF_INET;
 
1644
                else if (!strcmp("-6", pcmd->argval[i].string))
 
1645
                        ai_fam_templ = AF_INET6;
 
1646
                else {
 
1647
                        if (havehost)
 
1648
                                (void) fprintf(fp,
 
1649
                                    "current host remains %s\n", currenthost);
 
1650
                        else
 
1651
                                (void) fprintf(fp, "still no current host\n");
 
1652
                        return;
 
1653
                }
 
1654
                i = 1;
 
1655
        }
 
1656
        if (openhost(pcmd->argval[i].string)) {
1462
1657
                (void) fprintf(fp, "current host set to %s\n", currenthost);
1463
1658
        } else {
1464
1659
                if (havehost)
1501
1696
{
1502
1697
        if (pcmd->nargs == 0)
1503
1698
            fprintf(fp, "keytype is %s\n",
1504
 
                    (info_auth_keytype == KEY_TYPE_MD5) ? "MD5" : "DES");
 
1699
                    (info_auth_keytype == KEY_TYPE_MD5) ? "MD5" : "???");
1505
1700
        else
1506
1701
            switch (*(pcmd->argval[0].string)) {
1507
1702
                case 'm':
1509
1704
                    info_auth_keytype = KEY_TYPE_MD5;
1510
1705
                    break;
1511
1706
 
1512
 
                case 'd':
1513
 
                case 'D':
1514
 
                    info_auth_keytype = KEY_TYPE_DES;
1515
 
                    break;
1516
 
 
1517
1707
                default:
1518
 
                    fprintf(fp, "keytype must be 'md5' or 'des'\n");
 
1708
                    fprintf(fp, "keytype must be 'md5'\n");
1519
1709
            }
1520
1710
}
1521
1711
 
1545
1735
                           (u_char *)pcmd->argval[0].string);
1546
1736
                authtrust(info_auth_keyid, 1);
1547
1737
        } else {
1548
 
                pass = getpass((info_auth_keytype == KEY_TYPE_DES)
1549
 
                               ? "DES Password: "
1550
 
                               : "MD5 Password: "
1551
 
                               );
 
1738
                pass = getpass("MD5 Password: ");
1552
1739
                if (*pass == '\0')
1553
1740
                    (void) fprintf(fp, "Password unchanged\n");
1554
1741
                else {
1698
1885
        fprintf(stderr, "%s", keyprompt); fflush(stderr);
1699
1886
        for (p=pbuf; (c = getc(fi))!='\n' && c!=EOF;) {
1700
1887
                if (p < &pbuf[18])
1701
 
                    *p++ = c;
 
1888
                    *p++ = (char) c;
1702
1889
        }
1703
1890
        *p = '\0';
1704
1891
        if (fi != stdin)