1 |
|
|
/* $OpenBSD: util.c,v 1.24 2017/03/01 00:56:30 gsoares Exp $ */ |
2 |
|
|
|
3 |
|
|
/* |
4 |
|
|
* Copyright (c) 2004 Alexander Guy <alexander.guy@andern.org> |
5 |
|
|
* |
6 |
|
|
* Permission to use, copy, modify, and distribute this software for any |
7 |
|
|
* purpose with or without fee is hereby granted, provided that the above |
8 |
|
|
* copyright notice and this permission notice appear in all copies. |
9 |
|
|
* |
10 |
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
11 |
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
12 |
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
13 |
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
14 |
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
15 |
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
16 |
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
17 |
|
|
*/ |
18 |
|
|
|
19 |
|
|
#include <fcntl.h> |
20 |
|
|
#include <limits.h> |
21 |
|
|
#include <stdio.h> |
22 |
|
|
#include <stdlib.h> |
23 |
|
|
#include <time.h> |
24 |
|
|
#include <unistd.h> |
25 |
|
|
|
26 |
|
|
#include "ntpd.h" |
27 |
|
|
|
28 |
|
|
double |
29 |
|
|
gettime_corrected(void) |
30 |
|
|
{ |
31 |
|
|
return (gettime() + getoffset()); |
32 |
|
|
} |
33 |
|
|
|
34 |
|
|
double |
35 |
|
|
getoffset(void) |
36 |
|
|
{ |
37 |
|
|
struct timeval tv; |
38 |
|
|
if (adjtime(NULL, &tv) == -1) |
39 |
|
|
return (0.0); |
40 |
|
|
return (tv.tv_sec + 1.0e-6 * tv.tv_usec); |
41 |
|
|
} |
42 |
|
|
|
43 |
|
|
double |
44 |
|
|
gettime(void) |
45 |
|
|
{ |
46 |
|
|
struct timeval tv; |
47 |
|
|
|
48 |
|
|
if (gettimeofday(&tv, NULL) == -1) |
49 |
|
|
fatal("gettimeofday"); |
50 |
|
|
|
51 |
|
|
return (gettime_from_timeval(&tv)); |
52 |
|
|
} |
53 |
|
|
|
54 |
|
|
double |
55 |
|
|
gettime_from_timeval(struct timeval *tv) |
56 |
|
|
{ |
57 |
|
|
/* |
58 |
|
|
* Account for overflow on OSes that have a 32-bit time_t. |
59 |
|
|
*/ |
60 |
|
|
return ((uint64_t)tv->tv_sec + JAN_1970 + 1.0e-6 * tv->tv_usec); |
61 |
|
|
} |
62 |
|
|
|
63 |
|
|
time_t |
64 |
|
|
getmonotime(void) |
65 |
|
|
{ |
66 |
|
|
struct timespec ts; |
67 |
|
|
|
68 |
|
|
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) |
69 |
|
|
fatal("clock_gettime"); |
70 |
|
|
|
71 |
|
|
return (ts.tv_sec); |
72 |
|
|
} |
73 |
|
|
|
74 |
|
|
|
75 |
|
|
void |
76 |
|
|
d_to_tv(double d, struct timeval *tv) |
77 |
|
|
{ |
78 |
|
|
tv->tv_sec = d; |
79 |
|
|
tv->tv_usec = (d - tv->tv_sec) * 1000000; |
80 |
|
|
while (tv->tv_usec < 0) { |
81 |
|
|
tv->tv_usec += 1000000; |
82 |
|
|
tv->tv_sec -= 1; |
83 |
|
|
} |
84 |
|
|
} |
85 |
|
|
|
86 |
|
|
double |
87 |
|
|
lfp_to_d(struct l_fixedpt lfp) |
88 |
|
|
{ |
89 |
|
|
double ret; |
90 |
|
|
|
91 |
|
|
lfp.int_partl = ntohl(lfp.int_partl); |
92 |
|
|
lfp.fractionl = ntohl(lfp.fractionl); |
93 |
|
|
|
94 |
|
|
ret = (double)(lfp.int_partl) + ((double)lfp.fractionl / UINT_MAX); |
95 |
|
|
|
96 |
|
|
return (ret); |
97 |
|
|
} |
98 |
|
|
|
99 |
|
|
struct l_fixedpt |
100 |
|
|
d_to_lfp(double d) |
101 |
|
|
{ |
102 |
|
|
struct l_fixedpt lfp; |
103 |
|
|
|
104 |
|
|
lfp.int_partl = htonl((u_int32_t)d); |
105 |
|
|
lfp.fractionl = htonl((u_int32_t)((d - (u_int32_t)d) * UINT_MAX)); |
106 |
|
|
|
107 |
|
|
return (lfp); |
108 |
|
|
} |
109 |
|
|
|
110 |
|
|
double |
111 |
|
|
sfp_to_d(struct s_fixedpt sfp) |
112 |
|
|
{ |
113 |
|
|
double ret; |
114 |
|
|
|
115 |
|
|
sfp.int_parts = ntohs(sfp.int_parts); |
116 |
|
|
sfp.fractions = ntohs(sfp.fractions); |
117 |
|
|
|
118 |
|
|
ret = (double)(sfp.int_parts) + ((double)sfp.fractions / USHRT_MAX); |
119 |
|
|
|
120 |
|
|
return (ret); |
121 |
|
|
} |
122 |
|
|
|
123 |
|
|
struct s_fixedpt |
124 |
|
|
d_to_sfp(double d) |
125 |
|
|
{ |
126 |
|
|
struct s_fixedpt sfp; |
127 |
|
|
|
128 |
|
|
sfp.int_parts = htons((u_int16_t)d); |
129 |
|
|
sfp.fractions = htons((u_int16_t)((d - (u_int16_t)d) * USHRT_MAX)); |
130 |
|
|
|
131 |
|
|
return (sfp); |
132 |
|
|
} |
133 |
|
|
|
134 |
|
|
char * |
135 |
|
|
print_rtable(int r) |
136 |
|
|
{ |
137 |
|
|
static char b[11]; |
138 |
|
|
|
139 |
|
|
b[0] = 0; |
140 |
|
|
if (r > 0) |
141 |
|
|
snprintf(b, sizeof(b), "rtable %d", r); |
142 |
|
|
|
143 |
|
|
return (b); |
144 |
|
|
} |
145 |
|
|
|
146 |
|
|
const char * |
147 |
|
|
log_sockaddr(struct sockaddr *sa) |
148 |
|
|
{ |
149 |
|
|
static char buf[NI_MAXHOST]; |
150 |
|
|
|
151 |
|
|
if (getnameinfo(sa, SA_LEN(sa), buf, sizeof(buf), NULL, 0, |
152 |
|
|
NI_NUMERICHOST)) |
153 |
|
|
return ("(unknown)"); |
154 |
|
|
else |
155 |
|
|
return (buf); |
156 |
|
|
} |
157 |
|
|
|
158 |
|
|
pid_t |
159 |
|
|
start_child(char *pname, int cfd, int argc, char **argv) |
160 |
|
|
{ |
161 |
|
|
char **nargv; |
162 |
|
|
int nargc, i; |
163 |
|
|
pid_t pid; |
164 |
|
|
|
165 |
|
|
/* Prepare the child process new argv. */ |
166 |
|
|
nargv = calloc(argc + 3, sizeof(char *)); |
167 |
|
|
if (nargv == NULL) |
168 |
|
|
fatal("%s: calloc", __func__); |
169 |
|
|
|
170 |
|
|
/* Copy the program name first. */ |
171 |
|
|
nargc = 0; |
172 |
|
|
nargv[nargc++] = argv[0]; |
173 |
|
|
|
174 |
|
|
/* Set the process name and copy the original args. */ |
175 |
|
|
nargv[nargc++] = "-P"; |
176 |
|
|
nargv[nargc++] = pname; |
177 |
|
|
for (i = 1; i < argc; i++) |
178 |
|
|
nargv[nargc++] = argv[i]; |
179 |
|
|
|
180 |
|
|
nargv[nargc] = NULL; |
181 |
|
|
|
182 |
|
|
switch (pid = fork()) { |
183 |
|
|
case -1: |
184 |
|
|
fatal("%s: fork", __func__); |
185 |
|
|
break; |
186 |
|
|
case 0: |
187 |
|
|
/* Prepare the parent socket and execute. */ |
188 |
|
|
if (cfd != PARENT_SOCK_FILENO) { |
189 |
|
|
if (dup2(cfd, PARENT_SOCK_FILENO) == -1) |
190 |
|
|
fatal("dup2"); |
191 |
|
|
} else if (fcntl(cfd, F_SETFD, 0) == -1) |
192 |
|
|
fatal("fcntl"); |
193 |
|
|
|
194 |
|
|
execvp(argv[0], nargv); |
195 |
|
|
fatal("%s: execvp", __func__); |
196 |
|
|
break; |
197 |
|
|
|
198 |
|
|
default: |
199 |
|
|
/* Close child's socket end. */ |
200 |
|
|
close(cfd); |
201 |
|
|
break; |
202 |
|
|
} |
203 |
|
|
|
204 |
|
|
free(nargv); |
205 |
|
|
return (pid); |
206 |
|
|
} |
207 |
|
|
|
208 |
|
|
int |
209 |
|
|
sanitize_argv(int *argc, char ***argv) |
210 |
|
|
{ |
211 |
|
|
char **nargv; |
212 |
|
|
int nargc; |
213 |
|
|
int i; |
214 |
|
|
|
215 |
|
|
/* |
216 |
|
|
* We need at least three arguments: |
217 |
|
|
* Example: '/usr/sbin/ntpd' '-P' 'foobar'. |
218 |
|
|
*/ |
219 |
|
|
if (*argc < 3) |
220 |
|
|
return (-1); |
221 |
|
|
|
222 |
|
|
*argc -= 2; |
223 |
|
|
|
224 |
|
|
/* Allocate new arguments vector and copy pointers. */ |
225 |
|
|
nargv = calloc((*argc) + 1, sizeof(char *)); |
226 |
|
|
if (nargv == NULL) |
227 |
|
|
return (-1); |
228 |
|
|
|
229 |
|
|
nargc = 0; |
230 |
|
|
nargv[nargc++] = (*argv)[0]; |
231 |
|
|
for (i = 1; i < *argc; i++) |
232 |
|
|
nargv[nargc++] = (*argv)[i + 2]; |
233 |
|
|
|
234 |
|
|
nargv[nargc] = NULL; |
235 |
|
|
*argv = nargv; |
236 |
|
|
return (0); |
237 |
|
|
} |