Implement a variable polling rate capability.
[dragonfly.git] / usr.sbin / dntpd / main.c
1 /*
2  * Copyright (c) 2005 The DragonFly Project.  All rights reserved.
3  * 
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  * 
34  * $DragonFly: src/usr.sbin/dntpd/main.c,v 1.3 2005/04/24 23:09:32 dillon Exp $
35  */
36
37 #include "defs.h"
38
39 static void usage(const char *av0);
40 static void dotest(const char *target);
41 static void add_server(const char *target);
42
43 static struct server_info **servers;
44 static int nservers;
45 static int maxservers;
46
47 int debug_opt;
48 int min_sleep_opt = 5;          /* 5 seconds minimum poll interval */
49 int nom_sleep_opt = 300;        /* 5 minutes nominal poll interval */
50 int max_sleep_opt = 1800;       /* 30 minutes maximum poll interval */
51
52 int
53 main(int ac, char **av)
54 {
55     int test_opt = 0;
56     int rc;
57     int ch;
58     int i;
59
60     /*
61      * Really randomize
62      */
63     srandomdev();
64     rc = 0;
65
66     /*
67      * Process Options
68      */
69     while ((ch = getopt(ac, av, "dtT:L:")) != -1) {
70         switch(ch) {
71         case 'T':
72             nom_sleep_opt = strtol(optarg, NULL, 0);
73             if (nom_sleep_opt < 1) {
74                 fprintf(stderr, "Warning: nominal poll interval too small, "
75                                 "limiting to 1 second\n");
76                 nom_sleep_opt = 1;
77             }
78             if (nom_sleep_opt > 24 * 60 * 60) {
79                 fprintf(stderr, "Warning: nominal poll interval too large, "
80                                 "limiting to 24 hours\n");
81                 nom_sleep_opt = 24 * 60 * 60;
82             }
83             if (min_sleep_opt > nom_sleep_opt)
84                 min_sleep_opt = nom_sleep_opt;
85             if (max_sleep_opt < nom_sleep_opt * 5)
86                 max_sleep_opt = nom_sleep_opt * 5;
87             break;
88         case 'L':
89             max_sleep_opt = strtol(optarg, NULL, 0);
90             break;
91         case 'd':
92             debug_opt = 1;
93             break;
94         case 't':
95             test_opt = 1;
96             break;
97         case 'h':
98         default:
99             usage(av[0]);
100             /* not reached */
101         }
102     }
103
104     if (test_opt) {
105         if (optind != ac - 1)
106             usage(av[0]);
107         dotest(av[optind]);
108         /* not reached */
109     }
110
111     /*
112      * Add additional hosts.
113      */
114     for (i = optind; i < ac; ++i) {
115         add_server(av[i]);
116     }
117     if (nservers == 0) {
118         usage(av[0]);
119         /* not reached */
120     }
121
122     /*
123      * And go.
124      */
125     client_init();
126     rc = client_main(servers, nservers);
127     return(rc);
128 }
129
130 static
131 void
132 usage(const char *av0)
133 {
134     fprintf(stderr, "%s [-dt] [-T poll_interval] [additional_targets]\n", av0);
135     fprintf(stderr, "\t-d\tforeground operation, debugging turned on\n");
136     fprintf(stderr, "\t-t\ttest mode (specify one target on command line)\n");
137     exit(1);
138 }
139
140 static
141 void
142 dotest(const char *target)
143 {
144     struct server_info info;
145
146     bzero(&info, sizeof(info));
147     info.fd = udp_socket(target, 123);
148     if (info.fd < 0) {
149         logerrstr("unable to create UDP socket for %s", target);
150         return;
151     }
152     info.target = strdup(target);
153     client_init();
154
155     debug_opt = 1;
156
157     fprintf(stderr, 
158             "Will run %d-second polls until interrupted.\n", nom_sleep_opt);
159
160     for (;;) {
161         client_poll(&info, nom_sleep_opt);
162         sleep(nom_sleep_opt);
163     }
164     /* not reached */
165 }
166
167 static void
168 add_server(const char *target)
169 {
170     server_info_t info;
171
172     if (nservers == maxservers) {
173         maxservers += 16;
174         servers = realloc(servers, maxservers * sizeof(server_info_t));
175         assert(servers != NULL);
176     }
177     info = malloc(sizeof(struct server_info));
178     servers[nservers] = info;
179     bzero(info, sizeof(struct server_info));
180     info->fd = udp_socket(target, 123);
181     if (info->fd < 0) {
182         logerrstr("Unable to add server %s", target);
183     } else {
184         info->target = strdup(target);
185         ++nservers;
186     }
187 }
188