1
0
mirror of https://frontier.innolan.net/rainlance/amiga-ntimed.git synced 2026-01-11 22:22:27 +00:00

Purified to Amiga OS code

This commit is contained in:
llsth
2015-03-12 22:48:56 +01:00
parent bc91b7a3c3
commit 75baad1c00
16 changed files with 601 additions and 237 deletions

View File

@ -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 <parameter>] [TRACEFILE <file>] [TIMEZONE <zone>] {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.

View File

@ -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.

View File

@ -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 <exec/types.h>
#include <exec/memory.h>
#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 <stdint.h>
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 <stdint.h>
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

18
configure vendored
View File

@ -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"

80
doc/reference Normal file
View File

@ -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 <parameter>] [TRACEFILE <file>] [TIMEZONE <zone>] {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.

314
main_amiga.c Normal file
View File

@ -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 <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <math.h>
#include <sys/socket.h>
#include <resources/battclock.h>
#include <clib/battclock_protos.h>
#include <clib/utility_protos.h>
#ifdef Debug
#undef Debug
#endif
#ifdef AROS
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <proto/socket.h>
#include <sys/socket.h>
#include <bsdsocket/socketbasetags.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#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
}

View File

@ -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 **********************************************/

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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.

10
param.c
View File

@ -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;

View File

@ -24,8 +24,9 @@
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <exec/types.h>
@ -35,7 +36,9 @@
#include <clib/alib_protos.h>
#include <proto/dos.h>
#include <clib/battclock_protos.h>
#include <devices/timer.h>
#include <signal.h>
#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)

View File

@ -24,103 +24,44 @@
*
*/
#ifdef AROS
#include <proto/exec.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <proto/socket.h>
#include <sys/socket.h>
#include <bsdsocket/socketbasetags.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#ifdef Debug
#undef Debug
#endif
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#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);
}

54
tz.h
View File

@ -24,7 +24,11 @@
*
*/
#include <stdio.h>
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}
};

77
udp.c
View File

@ -1,4 +1,5 @@
/*-
* Copyright (c) 2015 Carsten Larsen
* Copyright (c) 2014 Poul-Henning Kamp
* All rights reserved.
*
@ -25,31 +26,28 @@
*/
#include <math.h>
//#include <poll.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h> /* Compat for NetBSD */
#include <sys/types.h> /* Compat for OpenBSD */
#include <sys/types.h>
#include <sys/socket.h>
#include "ntimed.h"
#include "udp.h"
#ifdef AROS
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/uio.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#endif
#include <sys/uio.h>
#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);

2
udp.h
View File

@ -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);