From 75baad1c00daa0bac94a529a43bece6bb6ab65cd Mon Sep 17 00:00:00 2001 From: llsth Date: Thu, 12 Mar 2015 22:48:56 +0100 Subject: [PATCH] Purified to Amiga OS code --- README.rst | 99 +++++++++------- agetaddrinfo.c | 10 +- atimed.h | 39 +++--- configure | 18 ++- doc/reference | 80 +++++++++++++ main_amiga.c | 314 +++++++++++++++++++++++++++++++++++++++++++++++++ ntimed.h | 1 + ntp_packet.c | 11 +- ntp_peerset.c | 4 + ocx_stdio.c | 11 +- param.c | 10 +- time_amiga.c | 31 +++-- alib.c => tz.c | 77 ++---------- tz.h | 54 +++++---- udp.c | 77 ++++-------- udp.h | 2 + 16 files changed, 601 insertions(+), 237 deletions(-) create mode 100644 doc/reference create mode 100644 main_amiga.c rename alib.c => tz.c (64%) diff --git a/README.rst b/README.rst index f6e538a..ebccf91 100644 --- a/README.rst +++ b/README.rst @@ -1,66 +1,85 @@ Ntimed -- Network Time Synchronization ====================================== -What is this ? -~~~~~~~~~~~~~~ +Introduction +~~~~~~~~~~~~ -This is a preview/early-acces/alpha/buzzword-of-the-times release -of a new FOSS project written to gradually take over the world of -networked timekeeping. +Ntimed is a network time synchronization client for the Amiga. It is based on +the NTimed Free Open Source Software project by Poul-Henning Kamp and sponsored +by the Linux Foundation. -The first step is a NTP protocol client daemon, 'Ntimed-client', -which will synchronize a systems clock to some set of NTP servers +It uses the NTP protocol to synchronize the local Amiga clock to a set of +network server. Public available NTP servers are reachable through the +Internet. -If this catches on, support for slave servers, refclocks and other -protocols, such as PTP, can be added, subject to interest, skill, -time and money. +Ntimed for the Amiga works only with IPv4 networks. Your Amiga needs to be +connected to a network and to have an IPv4 address in order for Ntimed to +work. -The overall architectural goals are the same as every other FOSS -project claims to follow: Simplicity, Quality, Security etc. etc. -but I tend to think that we stick a little bit more closely to them. +Reference +~~~~~~~~~ -This work is sponsored by Linux Foundation, partly in response to -the HeartBleed fiasco, and after studying the 300,000+ lines of -source-code in NTPD. I concluded that while it *could* be salvaged, -it would be more economical, much faster and far more efficient to -start from scratch. +Format + NTIMED [PARAM ] [TRACEFILE ] [TIMEZONE ] {servers} + [SYNC] [SAVE] [QUIET] -Ntimed is the result. +Template + P=PARAM/K,T=TRACEFILE/K,Z=TIMEZONE/K,SERVERS/M,SYNC/S,SAVE/S,QUIET/S -(Poul-Henning Kamp) +PARAM are used to show and set internal Ntimed parameters. A list of parameters +will be shown when using question mark. TRACEFILE can be specified to write a +full blow-by-blow trace file, for analysis and debugging. +TIMEZONE is used to specify local time zone. If no value is specified time will +be synchronized to Coordinated Universal Time (UTC). A list of parameters will +be shown when using question mark. {servers} is a list of NTP time servers. -Where can I read more ? -~~~~~~~~~~~~~~~~~~~~~~~ +SYNC will tell Ntimed to use 15 seconds to synchronizing local time and then +exit. If SAVE is specified time will be written to hardware clock upon exit. -The authors repository is located at github: +Example 1 +NTIMED ntp1.example.com ntp2.example.com + +Example 2 +NTIMED TRACEFILE=RAM:trace TIMEZONE=CEST ntp1.example.com + +Example 3 +NTIMED P "foo=20,pollrate_25" T T:trace ntp7.example.com + +Example 4 +NTIMED Z EST ntp4.example.com SYNC + +Example 5 +NTIMED Z ? + +Public available timeservers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A list of public available timeservers from ntp.org: +http://support.ntp.org/bin/view/Servers/StratumTwoTimeServers + +Instructions of how to use NTP pool servers are at: +http://www.pool.ntp.org/ + +Further info +~~~~~~~~~~~~ + +The Ntimed main repository is located at Github: https://github.com/bsdphk/Ntimed -He maintain a blog-of-sorts about this project here: +Poul-Henning Kamp maintains a blog about this project here: http://phk.freebsd.dk/time -The AROS repository is located here: +The Amiga and AROS repository is located at: https://github.com/llsth/Ntimed +Amiga and AROS versions are independent from the official Ntimed +FOSS project. How to compile ~~~~~~~~~~~~~~ -Pull the source code over to the machine you want to play on, and:: +Pull the source code over to the machine you want to play on, and: sh configure AMIGA (or sh configure AROS) make - - -How to use -~~~~~~~~~~ - -ntimed-client -z CET -t RAM:somefile some_ntp_server some_other_ntp_server - -That should synchronize your clock to those servers. - -Because this is a preview release, there is no commodity support and the -process cannot be stopped once started. - -The -z arguments tells it to use CET as timezone, and the '-t RAM:somefile' -to write a full blow-by-blow tracefile, for analysis and debugging. diff --git a/agetaddrinfo.c b/agetaddrinfo.c index b791c0e..dcec001 100644 --- a/agetaddrinfo.c +++ b/agetaddrinfo.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2015 Carsten Larsen * Copyright (c) 2001, 02 Motoyuki Kasahara * * Redistribution and use in source and binary forms, with or without @@ -44,15 +45,6 @@ * * This program also provides freeaddrinfo() and gai_strerror(). * - * To use this program in your application, insert the following lines to - * C source files after including `sys/types.h', `sys/socket.h' and - * `netdb.h'. `getaddrinfo.h' defines `struct addrinfo' and AI_, NI_, - * EAI_ macros. - * - * #ifndef HAVE_GETADDRINFO - * #include "agetaddrinfo.h" - * #endif - * * Restriction: * getaddrinfo() and getnameinfo() of this program are NOT thread * safe, unless the cpp macro ENABLE_PTHREAD is defined. diff --git a/atimed.h b/atimed.h index aae9dfe..6399ea1 100644 --- a/atimed.h +++ b/atimed.h @@ -27,26 +27,22 @@ #ifndef ATIMED_H #define ATIMED_H -int OpenLibraries(); -void CloseLibraries(); - -int ArgTimezone(const char *tz); -extern float utcoffset; -extern int tzid; - #if defined(AROS) || defined(AOS3) #ifndef AMIGA #define AMIGA #endif -double nan(const char*); #endif -#ifndef AF_INET6 -#define AF_INET6 10 +#ifdef AOS3 +#include +#include +#define IPTR APTR +#define CONST_STRPTR STRPTR +#define ARGSPTR LONG* #endif -#ifndef va_copy -#define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list)) +#ifdef AROS +#define ARGSPTR IPTR* #endif #ifdef AOS3 @@ -66,6 +62,13 @@ round(double x) } #endif +#define nan(p) 0./0. + +#ifdef AROS +#include +typedef uint32_t register_t; +#endif + #ifdef AOS3 #define ATIMER TIMERNAME #endif @@ -74,9 +77,12 @@ round(double x) #define ATIMER (CONST_STRPTR)TIMERNAME #endif -#ifdef AROS -#include -typedef uint32_t register_t; +#ifndef AF_INET6 +#define AF_INET6 10 +#endif + +#ifndef va_copy +#define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list)) #endif #ifndef _ALIGNBYTES @@ -98,4 +104,7 @@ struct sockaddr_storage { char __ss_pad1[128 - sizeof(sa_family_t)]; }; +void amiga_save_time(void); +#define Time_Amiga_Save amiga_save_time + #endif diff --git a/configure b/configure index 4327c7f..825f54d 100644 --- a/configure +++ b/configure @@ -1,5 +1,6 @@ #!/bin/sh # +# Copyright (c) 2014 Carsten Larsen # Copyright (c) 2014 Poul-Henning Kamp # All rights reserved. # @@ -49,20 +50,17 @@ HDRS=' ntp_tbl.h param_instance.h param_tbl.h + tz.h udp.h agetaddrinfo.h apoll.h - tz.h ' # List of .c files SRCS=' + main_amiga.c combine_delta.c - main.c - main_client.c - main_poll_server.c - main_sim_client.c ntp_filter.c ntp_packet.c ntp_peer.c @@ -76,8 +74,8 @@ SRCS=' time_sim.c time_stuff.c todo.c + tz.c udp.c - alib.c agetaddrinfo.c apoll.c ' @@ -113,7 +111,7 @@ else ( echo '# Portable Makefile generated by configure' echo '' - echo 'all: ntimed-client' + echo 'all: ntimed' echo '' if [ -n "$1" ] && [ $1 = "AMIGA" ] ; then echo 'CC = gcc' @@ -156,11 +154,11 @@ else done echo - echo "ntimed-client: ${l}" - echo " \${CC} \${CFLAGS} -o ntimed-client ${l} -lm" + echo "ntimed: ${l}" + echo " \${CC} \${CFLAGS} -o ntimed ${l} -lm" echo echo "clean:" - echo " rm -f ${l} ntimed-client" + echo " rm -f ${l} ntimed" echo echo "depend:" echo " @echo Dependencies already done" diff --git a/doc/reference b/doc/reference new file mode 100644 index 0000000..44dfb55 --- /dev/null +++ b/doc/reference @@ -0,0 +1,80 @@ +Introduction +============ + +Ntimed is a network time synchronization client for the Amiga. It is based on +the NTimed Free Open Source Software project by Poul-Henning Kamp and sponsored +by the Linux Foundation. + +It uses the NTP protocol to synchronize the local Amiga clock to a set of +network server. Public available NTP servers are reachable through the +Internet. + +Ntimed for the Amiga works only with IPv4 networks. Your Amiga needs to be +connected to a network and to have an IPv4 address in order for Ntimed to +work. + + +Reference +========= + +Format + NTIMED [PARAM ] [TRACEFILE ] [TIMEZONE ] {servers} + [SYNC] [SAVE] [QUIET] + +Template + P=PARAM/K,T=TRACEFILE/K,Z=TIMEZONE/K,SERVERS/M,SYNC/S,SAVE/S,QUIET/S + +PARAM are used to show and set internal Ntimed parameters. A list of parameters +will be shown when using question mark. TRACEFILE can be specified to write a +full blow-by-blow trace file, for analysis and debugging. + +TIMEZONE is used to specify local time zone. If no value is specified time will +be synchronized to Coordinated Universal Time (UTC). A list of parameters will +be shown when using question mark. {servers} is a list of NTP time servers. + +SYNC will tell Ntimed to use 15 seconds to synchronizing local time and then +exit. If SAVE is specified time will be written to hardware clock upon exit. + +NTIMED can be stopped with CTRL+C. + + +Example 1 +NTIMED ntp1.example.com ntp2.example.com + +Example 2 +NTIMED TRACEFILE=RAM:trace TIMEZONE=CEST ntp1.example.com + +Example 3 +NTIMED P "foo=20,pollrate_25" T T:trace ntp7.example.com + +Example 4 +NTIMED Z EST ntp4.example.com SYNC + +Example 5 +NTIMED Z ? + + +Public available timeservers +============================ + +A list of public available timeservers from ntp.org: +http://support.ntp.org/bin/view/Servers/StratumTwoTimeServers + +Instructions of how to use NTP pool servers are at: +http://www.pool.ntp.org/ + + +Further info +============ + +The Ntimed main repository is located at Github: +https://github.com/bsdphk/Ntimed + +Poul-Henning Kamp maintains a blog about this project here: +http://phk.freebsd.dk/time + +The Amiga and AROS repository is located at: +https://github.com/llsth/Ntimed + +Amiga and AROS versions are independent from the official Ntimed +FOSS project. diff --git a/main_amiga.c b/main_amiga.c new file mode 100644 index 0000000..e794507 --- /dev/null +++ b/main_amiga.c @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2015 Carsten Larsen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef Debug +#undef Debug +#endif + +#ifdef AROS +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#ifdef Debug +#undef Debug +#endif +#endif + +#include "tz.h" +#include "atimed.h" +#include "ntimed.h" +#include "ntp.h" +#include "udp.h" + +#define PARAM_CLIENT PARAM_INSTANCE +#define PARAM_TABLE_NAME client_param_table +#include "param_instance.h" +#undef PARAM_TABLE_NAME +#undef PARAM_CLIENT + +const char *vers = "\0$VER: ntimed 1.0"; + +#define ARG_TEMPLATE "P=PARAM/K,T=TRACEFILE/K,Z=TIMEZONE/K,SERVERS/M,SYNC/S,SAVE/S,QUIET/S" + +enum +{ + ARG_PARAM, + ARG_TRACE, + ARG_ZONE, + ARG_SERVERS, + ARG_SYNC, + ARG_SAVE, + ARG_QUIET, + ARG_LAST +}; + +extern int errno; + +BOOL started_from_wb; + +struct Library *BattClockBase; +struct Library *UtilityBase = NULL; +struct Library *SocketBase = NULL; +struct RDArgs *rda = NULL; +struct ntp_peerset *nps = NULL; +struct todolist *tdl = NULL; +struct combine_delta *cd = NULL; +struct udp_socket *usc = NULL; + +int saveclock = 0; +int tracefile = 0; + +static void set_params(const char *params); +static void clean_exit(); + +static enum todo_e __match_proto__(todo_f) +sync_end(struct ocx *ocx, struct todolist *tdl, void *priv) +{ + (void)tdl; + (void)priv; + Put(ocx, OCX_TRACE, "# Sync done\n"); + return(TODO_FAIL); +} + +int main(int argc, char **argv) +{ + IPTR args[ARG_LAST]; + const char **servers; + struct ntp_peer *np; + + int i; + int sync = 0; + int npeer = 0; + + atexit(clean_exit); + + started_from_wb = (BOOL)argc; + args[ARG_PARAM] = (IPTR)NULL; + args[ARG_TRACE] = (IPTR)NULL; + args[ARG_ZONE] = (IPTR)NULL; + args[ARG_SERVERS] = (IPTR)NULL; + args[ARG_SYNC] = (IPTR)NULL; + args[ARG_SAVE] = (IPTR)NULL; + args[ARG_QUIET] = (IPTR)NULL; + + rda = (struct RDArgs*)ReadArgs((CONST_STRPTR)ARG_TEMPLATE, (ARGSPTR)args, NULL); + if (!rda) + { + PrintFault(IoErr(), (CONST_STRPTR)argv[0]); + exit(1); + } + + if(!(UtilityBase = (struct Library *)OpenLibrary((CONST_STRPTR)"utility.library",33))) { + PrintFault(IoErr(), (CONST_STRPTR)argv[0]); + exit(1); + } + + if (args[ARG_SYNC]) { + sync = 1; + } + + if (args[ARG_QUIET]) { + MuteDebug(); + } + + if (args[ARG_SAVE]) { + saveclock = 1; + BattClockBase = OpenResource((CONST_STRPTR)BATTCLOCKNAME); + } + +#ifdef AROS + if(!(SocketBase = OpenLibrary((CONST_STRPTR)"bsdsocket.library", 4 ))) { + PrintFault(IoErr(), (CONST_STRPTR)argv[0]); + exit(1); + } + + if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (IPTR)&errno, + SBTM_SETVAL(SBTC_HERRNOLONGPTR), (IPTR)&h_errno, TAG_DONE)) { + PrintFault(IoErr(), (CONST_STRPTR)argv[0]); + exit(1); + } +#endif + + // *** INITIALIZE LOGIC *** + + tdl = TODO_NewList(); + Time_Amiga(tdl); + + PLL_Init(); + + nps = NTP_PeerSet_New(NULL); + + Param_Register(client_param_table); + NF_Init(); + + if (args[ARG_ZONE]) { + ArgTimezone((const char*)args[ARG_ZONE]); + } + + if (args[ARG_PARAM]) { + set_params((const char*)args[ARG_PARAM]); + } + + if (args[ARG_TRACE]) { + ArgTracefile((const char*)args[ARG_TRACE]); + tracefile = 1; + } + + servers = (const char**)args[ARG_SERVERS]; + + for (i = 0; servers[i]; i++) + npeer += NTP_PeerSet_Add(NULL, nps, servers[i]); + + if (npeer == 0) { + Fail(NULL, 0, "No NTP peers found"); + } + + Put(NULL, OCX_TRACE, "# NTIMED Format client 1.0\n"); + Put(NULL, OCX_TRACE, "# Found %d peers\n", npeer); + Put(NULL, OCX_TRACE, "# Timezone set to %s (UTC%s%.2f) %s\n", + tza[tzid].abbr, + tza[tzid].offset < 0.0 ? "-" : "+", + fabs(tza[tzid].offset), + tza[tzid].name); + + Param_Report(NULL, OCX_TRACE); + + usc = UdpTimedSocket(NULL); + if (usc == NULL) { + Fail(NULL, errno, "Could not open UDP socket"); + } + + cd = CD_New(); + + NTP_PeerSet_Foreach(np, nps) { + NF_New(np); + np->combiner = CD_AddSource(cd, np->hostname, np->ip); + } + + if (sync) { + TODO_ScheduleRel(tdl, sync_end, NULL, 15.0, 0, "End sync task"); + Put(NULL, OCX_DEBUG, "Synchronizing local time to server(s)\n"); + } else { + Put(NULL, OCX_DEBUG, "Synchronizing ...\n"); + } + + NTP_PeerSet_Poll(NULL, nps, usc, tdl); + (void)TODO_Run(NULL, tdl); + + return 0; +} + +static void set_params(const char *params) +{ + char *token; + const char d[2] = ","; + token = strtok((char*)params, d); + + while (token != NULL) + { + Param_Tweak(NULL, token); + token = strtok(NULL, d); + } +} + +static void clean_exit() +{ + if (saveclock) { + Time_Amiga_Save(); + Put(NULL, OCX_TRACE, "# Saved time to hardware clock\n"); + } + + // Free peer set && peers && NTP filters + if(nps) { + + } + + // Free combine delta + if(cd) { + + } + + // Free todo list + if(tdl) { + + } + + // Free UDP socket + if(usc) { + UDP_Socket_Destroy(usc); + usc = NULL; + } + + if(tracefile) { + ArgTracefile(NULL); + } + + if (rda) { + FreeArgs(rda); + rda = NULL; + } + + if (UtilityBase != NULL) { + CloseLibrary(UtilityBase); + } + +#ifdef AROS + if (SocketBase != NULL) { + CloseLibrary(SocketBase); + } +#endif +} + diff --git a/ntimed.h b/ntimed.h index 333fe82..9511da0 100644 --- a/ntimed.h +++ b/ntimed.h @@ -66,6 +66,7 @@ void Fail(struct ocx *, int err, const char *, ...) \ #define DebugHex(ocx, ptr, len) PutHex(ocx, OCX_DEBUG, ptr, len) void ArgTracefile(const char *fn); +void MuteDebug(); /* param.c -- Parameters **********************************************/ diff --git a/ntp_packet.c b/ntp_packet.c index 7d434f3..41d1757 100644 --- a/ntp_packet.c +++ b/ntp_packet.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2015 Carsten Larsen * Copyright (c) 2014 Poul-Henning Kamp * All rights reserved. * @@ -64,10 +65,10 @@ #include "ntimed_endian.h" /* - * Seconds between 1900 (NTP epoch) and 1970 (UNIX epoch). - * 17 is the number of leapdays. + * Seconds between 1900 (NTP epoch) and 1978 (Amiga epoch). + * 19 is the number of leapdays. */ -#define NTP_UNIX (((1970U - 1900U) * 365U + 17U) * 24U * 60U * 60U) +#define NTP_AMIGA (((1978U - 1900U) * 365U + 19U) * 24U * 60U * 60U) /********************************************************************** * Picking a NTP packet apart in a safe, byte-order agnostic manner @@ -78,7 +79,7 @@ ntp64_2ts(struct timestamp *ts, const uint8_t *ptr) { INIT_OBJ(ts, TIMESTAMP_MAGIC); - ts->sec = Be32dec(ptr) - NTP_UNIX; + ts->sec = Be32dec(ptr) - NTP_AMIGA; ts->frac = (uint64_t)Be32dec(ptr + 4) << 32ULL; } @@ -145,7 +146,7 @@ ts_2ntp64(uint8_t *dst, const struct timestamp *ts) { CHECK_OBJ_NOTNULL(ts, TIMESTAMP_MAGIC); - Be32enc(dst, ts->sec + NTP_UNIX); + Be32enc(dst, ts->sec + NTP_AMIGA); Be32enc(dst + 4, ts->frac >> 32ULL); } diff --git a/ntp_peerset.c b/ntp_peerset.c index d68322a..182f70e 100644 --- a/ntp_peerset.c +++ b/ntp_peerset.c @@ -257,6 +257,10 @@ ntp_peerset_poll(struct ocx *ocx, struct todolist *tdl, void *priv) np->filter_func(ocx, np); } + //if (stopclient) { + // TODO_ScheduleRel(tdl, client_end, NULL, 1.0, 0, "Client interrupted."); + //} + return (TODO_OK); } diff --git a/ocx_stdio.c b/ocx_stdio.c index 665d110..d083025 100644 --- a/ocx_stdio.c +++ b/ocx_stdio.c @@ -67,7 +67,8 @@ #include "ntimed.h" -static FILE *tracefile; +static FILE *debugout; +static FILE *tracefile = (FILE*)-1; static FILE * getdst(enum ocx_chan chan) @@ -77,7 +78,7 @@ getdst(enum ocx_chan chan) if (chan == OCX_TRACE) return (tracefile); if (chan == OCX_DEBUG) - return (stdout); + return (debugout == (FILE*)-1 ? stdout : debugout); WRONG("Wrong ocx_chan"); NEEDLESS_RETURN(NULL); } @@ -126,6 +127,12 @@ ArgTracefile(const char *fn) setbuf(tracefile, NULL); } +void +MuteDebug() +{ + debugout = NULL; +} + /********************************************************************** * XXX: The stuff below is generic and really ought to be in ocx.c on * XXX: its own. diff --git a/param.c b/param.c index 62f0616..e24757a 100644 --- a/param.c +++ b/param.c @@ -109,7 +109,7 @@ Param_Tweak(struct ocx *ocx, const char *arg) if (!strcmp(pt->name, arg)) break; if (pt == NULL) - Fail(ocx, 0, "-p unknown parameter '%s' (try -p '?')", + Fail(ocx, 0, "unknown parameter '%s' (try PARAM ?)", arg); Put(ocx, OCX_DIAG, "Parameter:\n\t%s\n", pt->name); Put(ocx, OCX_DIAG, "Minimum:\n\t%.3e\n", pt->min); @@ -131,19 +131,19 @@ Param_Tweak(struct ocx *ocx, const char *arg) break; } if (pt == NULL) - Fail(ocx, 0, "-p unknown parameter '%.*s' (try -p '?')", + Fail(ocx, 0, "unknown parameter '%.*s' (try PARAM ?)", (int)(q - arg), arg); r = NULL; d = strtod(q + 1, &r); if (*r != '\0') - Fail(ocx, 0, "-p '%.*s' bad value '%s'\n", + Fail(ocx, 0, "PARAM '%.*s' bad value '%s'\n", (int)(q - arg), arg, q + 1); if (d < pt->min) - Fail(ocx, 0, "-p '%.*s' below min value (%g)\n", + Fail(ocx, 0, "PARAM '%.*s' below min value (%g)\n", (int)(q - arg), arg, pt->min); if (d > pt->max) - Fail(ocx, 0, "-p '%.*s' above max value (%g)\n", + Fail(ocx, 0, "PARAM '%.*s' above max value (%g)\n", (int)(q - arg), arg, pt->max); Put(ocx, OCX_DIAG, "# Tweak(%s -> %.3e)\n", arg, d); *(pt->val) = d; diff --git a/time_amiga.c b/time_amiga.c index e17b6b6..61ac932 100644 --- a/time_amiga.c +++ b/time_amiga.c @@ -24,8 +24,9 @@ * */ -#include +#include #include +#include #include #include @@ -35,7 +36,9 @@ #include #include +#include #include +#include #ifdef Debug #undef Debug @@ -147,6 +150,7 @@ amiga_now(struct timestamp *storage) static int __match_proto__(tb_sleep_f) amiga_sleep(double dur) { + ULONG sigs, timersig; struct timerequest *request; struct timeval tv; tv.tv_sec = 0; @@ -161,8 +165,14 @@ amiga_sleep(double dur) request->tr_node.io_Command = TR_ADDREQUEST; request->tr_time = tv; - DoIO((struct IORequest*)request); + timersig = (1L << request->tr_node.io_Message.mn_ReplyPort->mp_SigBit); + SendIO((struct IORequest*)request); + sigs = Wait(SIGBREAKF_CTRL_C | timersig); + if (sigs & SIGBREAKF_CTRL_C) { + exit(1); + } + delete_timer(request); return 0; } @@ -229,9 +239,6 @@ void delete_timer(struct timerequest *request) /**********************************************************************/ -// 2922 is the number of days between 1.1.1970 and 1.1.1978 (2 leap years and 6 normal) -const long amigaoffset = 2922 * 24 * 60 * 60; // 252460800 - int amiga_get_time(struct timeval *tv) { struct timerequest *request; @@ -245,7 +252,7 @@ int amiga_get_time(struct timeval *tv) DoIO((struct IORequest*)request); *tv = request->tr_time; - tv->tv_secs = tv->tv_secs + (amigaoffset - tzoffset); + tv->tv_secs = (long)tv->tv_secs - tzoffset; delete_timer(request); return 0; @@ -262,7 +269,7 @@ int amiga_set_time(struct timeval *tv) request->tr_node.io_Command = TR_SETSYSTIME; request->tr_time = *tv; - request->tr_time.tv_secs -= (amigaoffset - tzoffset); + request->tr_time.tv_secs += tzoffset; DoIO((struct IORequest*)request); @@ -270,6 +277,16 @@ int amiga_set_time(struct timeval *tv) return 0; } + +void amiga_save_time(void) +{ +#ifndef AROS + struct timeval tv; + amiga_get_time(&tv); + WriteBattClock(tv.tv_sec); +#endif +} + /**********************************************************************/ void adjust_timeval(struct timeval *tv, double offset) diff --git a/alib.c b/tz.c similarity index 64% rename from alib.c rename to tz.c index d01236b..9646796 100644 --- a/alib.c +++ b/tz.c @@ -24,103 +24,44 @@ * */ -#ifdef AROS -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#ifdef Debug -#undef Debug -#endif -#endif - #include #include #include #include #include "tz.h" -#include "atimed.h" - -double nan(const char *tagp) { - return 0./0.; -} - -struct Library * SocketBase = NULL; -extern int errno; +#include "ntimed.h" int tzid = 0; -int OpenLibraries() -{ -#ifdef AROS - if(!(SocketBase = OpenLibrary((CONST_STRPTR)"bsdsocket.library", 4 ))) { - return(-1); - } - - if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (IPTR)&errno, - SBTM_SETVAL(SBTC_HERRNOLONGPTR), (IPTR)&h_errno, TAG_DONE)) { - return(-1); - } -#endif - - return 0; -} - -void CloseLibraries() -{ -#ifdef AROS - if (SocketBase != NULL) { - CloseLibrary(SocketBase); - } -#endif -} - -void PrintTimeZones(); - -int ArgTimezone(const char *tz) +void ArgTimezone(const char *tz) { unsigned int i; static const unsigned int count = sizeof(tza) / sizeof(struct tzabbr); if (tz == NULL) - return 0; + return; if (!strcmp(tz, "-")) { utcoffset = 0.0; - return 0; + return; } if (!strcmp(tz, "?")) { PrintTimeZones(); - return 1; + return; } for (i = 0; i < count; i++) { if (!strcmp(tza[i].abbr, tz)) { tzid = i; utcoffset = tza[i].offset; - return 0; + return; } } - utcoffset = 0.0; - return 0; + Fail(NULL, 0, "Unknown timezone. Try TZ=?"); + exit(1); } void PrintTimeZones() @@ -135,4 +76,6 @@ void PrintTimeZones() fabs(tza[i].offset), tza[i].name); } + + exit(1); } diff --git a/tz.h b/tz.h index 61e4891..4377561 100644 --- a/tz.h +++ b/tz.h @@ -24,7 +24,11 @@ * */ -#include +extern int tzid; +extern float utcoffset; + +void ArgTimezone(const char *tz); +void PrintTimeZones(); typedef struct tzabbr { const char *abbr; @@ -215,29 +219,29 @@ static const tzabbr tza[] = { {"YAKT", "Yakutsk Time", 9}, {"YEKT", "Yekaterinburg Time", 5}, #endif - {"Z+1", "Coordinated Universal Time + 1", 1.0}, - {"Z+2", "Coordinated Universal Time + 2", 2.0}, - {"Z+3", "Coordinated Universal Time + 3", 3.0}, - {"Z+4", "Coordinated Universal Time + 4", 4.0}, - {"Z+5", "Coordinated Universal Time + 5", 5.0}, - {"Z+6", "Coordinated Universal Time + 6", 6.0}, - {"Z+7", "Coordinated Universal Time + 7", 7.0}, - {"Z+8", "Coordinated Universal Time + 8", 8.0}, - {"Z+9", "Coordinated Universal Time + 9", 9.0}, - {"Z+10", "Coordinated Universal Time + 10", 10.0}, - {"Z+11", "Coordinated Universal Time + 11", 11.0}, - {"Z+12", "Coordinated Universal Time + 12", 12.0}, - {"Z-1", "Coordinated Universal Time - 1", -1.0}, - {"Z-2", "Coordinated Universal Time - 2", -2.0}, - {"Z-3", "Coordinated Universal Time - 3", -3.0}, - {"Z-4", "Coordinated Universal Time - 4", -4.0}, - {"Z-5", "Coordinated Universal Time - 5", -5.0}, - {"Z-6", "Coordinated Universal Time - 6", -6.0}, - {"Z-7", "Coordinated Universal Time - 7", -7.0}, - {"Z-8", "Coordinated Universal Time - 8", -8.0}, - {"Z-9", "Coordinated Universal Time - 9", -9.0}, - {"Z-10", "Coordinated Universal Time - 10", -10.0}, - {"Z-11", "Coordinated Universal Time - 11", -11.0}, - {"Z-12", "Coordinated Universal Time - 12", -12.0} + {"+1", "Coordinated Universal Time +1", 1.0}, + {"+2", "Coordinated Universal Time +2", 2.0}, + {"+3", "Coordinated Universal Time +3", 3.0}, + {"+4", "Coordinated Universal Time +4", 4.0}, + {"+5", "Coordinated Universal Time +5", 5.0}, + {"+6", "Coordinated Universal Time +6", 6.0}, + {"+7", "Coordinated Universal Time +7", 7.0}, + {"+8", "Coordinated Universal Time +8", 8.0}, + {"+9", "Coordinated Universal Time +9", 9.0}, + {"+10", "Coordinated Universal Time +10", 10.0}, + {"+11", "Coordinated Universal Time +11", 11.0}, + {"+12", "Coordinated Universal Time +12", 12.0}, + {"-1", "Coordinated Universal Time -1", -1.0}, + {"-2", "Coordinated Universal Time -2", -2.0}, + {"-3", "Coordinated Universal Time -3", -3.0}, + {"-4", "Coordinated Universal Time -4", -4.0}, + {"-5", "Coordinated Universal Time -5", -5.0}, + {"-6", "Coordinated Universal Time -6", -6.0}, + {"-7", "Coordinated Universal Time -7", -7.0}, + {"-8", "Coordinated Universal Time -8", -8.0}, + {"-9", "Coordinated Universal Time -9", -9.0}, + {"-10", "Coordinated Universal Time -10", -10.0}, + {"-11", "Coordinated Universal Time -11", -11.0}, + {"-12", "Coordinated Universal Time -12", -12.0} }; diff --git a/udp.c b/udp.c index b518c0a..fd647a6 100644 --- a/udp.c +++ b/udp.c @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2015 Carsten Larsen * Copyright (c) 2014 Poul-Henning Kamp * All rights reserved. * @@ -25,31 +26,28 @@ */ #include -//#include #include #include -#include /* Compat for NetBSD */ -#include /* Compat for OpenBSD */ + +#include #include - -#include "ntimed.h" -#include "udp.h" - -#ifdef AROS +#include +#include +#include #include #include #include #include -#endif -#include +#include "ntimed.h" +#include "udp.h" + #include "atimed.h" #include "apoll.h" struct udp_socket { unsigned magic; #define UDP_SOCKET_MAGIC 0x302a563f - int fd4; }; @@ -57,19 +55,7 @@ static int udp_sock(int fam) { int fd; -// int i; - fd = socket(fam, SOCK_DGRAM, 0); - if (fd < 0) - return (fd); - -#ifdef SO_TIMESTAMPNS - i = 1; - (void)setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPNS, &i, sizeof i); -#elif defined(SO_TIMESTAMP) - i = 1; - (void)setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, &i, sizeof i); -#endif return (fd); } @@ -81,12 +67,24 @@ UdpTimedSocket(struct ocx *ocx) ALLOC_OBJ(usc, UDP_SOCKET_MAGIC); AN(usc); usc->fd4 = udp_sock(AF_INET); -// usc->fd6 = udp_sock(AF_INET6); if (usc->fd4 < 0) - Fail(ocx, 1, "socket(2) failed"); + Fail(ocx, 1, "socket failed"); return (usc); } +void +UDP_Socket_Destroy(struct udp_socket *usc) +{ + CHECK_OBJ_NOTNULL(usc, UDP_SOCKET_MAGIC); +#ifdef AOS3 + close(usc->fd4); +#endif +#ifdef AROS + CloseSocket(usc->fd4); +#endif + FREE_OBJ(usc); +} + ssize_t UdpTimedRx(struct ocx *ocx, const struct udp_socket *usc, sa_family_t fam, @@ -111,8 +109,6 @@ UdpTimedRx(struct ocx *ocx, const struct udp_socket *usc, if (fam == AF_INET) pfd[0].fd = usc->fd4; -// else if (fam == AF_INET6) -// pfd[0].fd = usc->fd6; else WRONG("Wrong family in UdpTimedRx"); @@ -122,19 +118,18 @@ UdpTimedRx(struct ocx *ocx, const struct udp_socket *usc, if (tmo == 0.0) { tmo_msec = -1; } else { - tmo_msec = round(1e3 * tmo);// lround(1e3 * tmo); + tmo_msec = round(1e3 * tmo); if (tmo_msec <= 0) tmo_msec = 0; } i = poll(pfd, 1, tmo_msec); if (i < 0) - Fail(ocx, 1, "poll(2) failed\n"); + Fail(ocx, 1, "poll failed\n"); if (i == 0) return (0); - /* Grab a timestamp in case none of the SCM_TIMESTAMP* works */ TB_Now(ts); memset(&msg, 0, sizeof msg); @@ -165,26 +160,6 @@ UdpTimedRx(struct ocx *ocx, const struct udp_socket *usc, return (rl); for(;cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { -#ifdef SCM_TIMESTAMPNS - if (cmsg->cmsg_level == SOL_SOCKET && - cmsg->cmsg_type == SCM_TIMESTAMPNS && - cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval))) { - struct timespec tsc; - memcpy(&tsc, CMSG_DATA(cmsg), sizeof tsc); - (void)TS_Nanosec(ts, tsc.tv_sec, tsc.tv_nsec); - continue; - } -#endif -#ifdef SCM_TIMESTAMP - if (cmsg->cmsg_level == SOL_SOCKET && - cmsg->cmsg_type == SCM_TIMESTAMP && - cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval))) { - struct timeval tv; - memcpy(&tv, CMSG_DATA(cmsg), sizeof tv); - (void)TS_Nanosec(ts, tv.tv_sec, tv.tv_usec * 1000LL); - continue; - } -#endif Debug(ocx, "RX-msg: %d %d %u ", cmsg->cmsg_level, cmsg->cmsg_type, cmsg->cmsg_len); DebugHex(ocx, CMSG_DATA(cmsg), cmsg->cmsg_len); @@ -209,8 +184,6 @@ Udp_Send(struct ocx *ocx, const struct udp_socket *usc, sa = ss; if (sa->sa_family == AF_INET) return (sendto(usc->fd4, buf, len, 0, ss, sl)); -// if (sa->sa_family == AF_INET6) -// return (sendto(usc->fd6, buf, len, 0, ss, sl)); WRONG("Wrong AF_"); NEEDLESS_RETURN(0); diff --git a/udp.h b/udp.h index 4c078c4..e4e8d95 100644 --- a/udp.h +++ b/udp.h @@ -1,4 +1,5 @@ /*- + * Copyright (c) 2015 Carsten Larsen * Copyright (c) 2014 Poul-Henning Kamp * All rights reserved. * @@ -44,3 +45,4 @@ ssize_t UdpTimedRx(struct ocx *, const struct udp_socket *, ssize_t Udp_Send(struct ocx *, const struct udp_socket *, const void *sa, socklen_t, const void *ptr, size_t); +void UDP_Socket_Destroy(struct udp_socket *usc);