]> git.ipfire.org Git - thirdparty/chrony.git/blame - refclock_sock.c
test: use env shebang in all bash scripts
[thirdparty/chrony.git] / refclock_sock.c
CommitLineData
3a9e1344
ML
1/*
2 chronyd/chronyc - Programs for keeping computer clocks accurate.
3
4 **********************************************************************
f7e08d0c 5 * Copyright (C) Miroslav Lichvar 2009
3a9e1344
ML
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
8e23110a 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
3a9e1344
ML
19 *
20 **********************************************************************
21
22 =======================================================================
23
24 Unix domain socket refclock driver.
25
26 */
27
da2c8d90
ML
28#include "config.h"
29
6ca73bf6
ML
30#include "sysincl.h"
31
3a9e1344
ML
32#include "refclock.h"
33#include "logging.h"
34#include "util.h"
35#include "sched.h"
207f9fb1 36#include "socket.h"
3a9e1344 37
dd5405a2
ML
38#define SOCK_MAGIC 0x534f434b
39
3a9e1344 40struct sock_sample {
ba25fb1b 41 /* Time of the measurement (system time) */
3a9e1344 42 struct timeval tv;
ba25fb1b
ML
43
44 /* Offset between the true time and the system time (in seconds) */
3a9e1344 45 double offset;
ba25fb1b
ML
46
47 /* Non-zero if the sample is from a PPS signal, i.e. another source
48 is needed to obtain seconds */
6d242a33 49 int pulse;
ba25fb1b
ML
50
51 /* 0 - normal, 1 - insert leap second, 2 - delete leap second */
3a9e1344 52 int leap;
ba25fb1b
ML
53
54 /* Padding, ignored */
dd5405a2 55 int _pad;
ba25fb1b
ML
56
57 /* Protocol identifier (0x534f434b) */
dd5405a2 58 int magic;
3a9e1344
ML
59};
60
0a105453 61static void read_sample(int sockfd, int event, void *anything)
3a9e1344
ML
62{
63 struct sock_sample sample;
d0dfa1de 64 struct timespec ts;
3a9e1344 65 RCL_Instance instance;
0a105453 66 int s;
3a9e1344
ML
67
68 instance = (RCL_Instance)anything;
3a9e1344 69
dd5405a2
ML
70 s = recv(sockfd, &sample, sizeof (sample), 0);
71
72 if (s < 0) {
e15c7cd2 73 DEBUG_LOG("Could not read SOCK sample : %s", strerror(errno));
dd5405a2
ML
74 return;
75 }
76
77 if (s != sizeof (sample)) {
e15c7cd2
ML
78 DEBUG_LOG("Unexpected length of SOCK sample : %d != %ld",
79 s, (long)sizeof (sample));
dd5405a2
ML
80 return;
81 }
82
83 if (sample.magic != SOCK_MAGIC) {
e15c7cd2
ML
84 DEBUG_LOG("Unexpected magic number in SOCK sample : %x != %x",
85 (unsigned int)sample.magic, (unsigned int)SOCK_MAGIC);
3a9e1344 86 return;
dd5405a2 87 }
3a9e1344 88
d0dfa1de
ML
89 UTI_TimevalToTimespec(&sample.tv, &ts);
90 UTI_NormaliseTimespec(&ts);
91
6d242a33 92 if (sample.pulse) {
d0dfa1de 93 RCL_AddPulse(instance, &ts, sample.offset);
6d242a33 94 } else {
d0dfa1de 95 RCL_AddSample(instance, &ts, sample.offset, sample.leap);
6d242a33 96 }
3a9e1344
ML
97}
98
99static int sock_initialise(RCL_Instance instance)
100{
3a9e1344
ML
101 int sockfd;
102 char *path;
103
a78031ce
ML
104 RCL_CheckDriverOptions(instance, NULL);
105
3a9e1344
ML
106 path = RCL_GetDriverParameter(instance);
107
207f9fb1
ML
108 sockfd = SCK_OpenUnixDatagramSocket(NULL, path, 0);
109 if (sockfd < 0)
110 LOG_FATAL("Could not open socket %s", path);
3a9e1344
ML
111
112 RCL_SetDriverData(instance, (void *)(long)sockfd);
0a105453 113 SCH_AddFileHandler(sockfd, SCH_FILE_INPUT, read_sample, instance);
3a9e1344
ML
114 return 1;
115}
116
117static void sock_finalise(RCL_Instance instance)
118{
5a3d85b4
ML
119 int sockfd;
120
121 sockfd = (long)RCL_GetDriverData(instance);
0a105453 122 SCH_RemoveFileHandler(sockfd);
c651ea9b 123 SCK_RemoveSocket(sockfd);
207f9fb1 124 SCK_CloseSocket(sockfd);
3a9e1344
ML
125}
126
127RefclockDriver RCL_SOCK_driver = {
128 sock_initialise,
129 sock_finalise,
130 NULL
131};