Revision 1.04 changes

This commit is contained in:
llsth 2015-07-25 23:11:11 +02:00
parent ce27e11c51
commit c086e3bea2
24 changed files with 494 additions and 374 deletions

2
.gitignore vendored
View File

@ -1,5 +1,5 @@
Makefile
ntimed-client
ntimed*
.gdbinit
.depend
*.o

View File

@ -1,13 +1,13 @@
This software contains copyrighted material by:
The NetBSD Foundation, Inc.
Poul-Henning Kamp
Motoyuki Kasahara
Diego Casorran
Carsten Larsen
Portions of the code have been contributed by:
Charles M. Hannum
Poul-Henning Kamp
Motoyuki Kasahara
Diego Casorran
Carsten Larsen
This software contains copyrighted material by:
The NetBSD Foundation, Inc.
Poul-Henning Kamp
Motoyuki Kasahara
Carsten Larsen
Portions of the code have been contributed by:
Charles M. Hannum
Poul-Henning Kamp
Motoyuki Kasahara
Carsten Larsen
See license file for details.

View File

@ -1,7 +1,8 @@
History
-------
1.04 Bug-fixes in TCP/IP and debugging logic.
1.03 Rebuild for AROS. Removed broken Time Zone Database library.
1.02 Restructured code. New fork of offical Ntimed with modifications.
1.01 Internal release. Testing and bugfixing. Never published
1.02 Restructured code. New fork of official Ntimed with modifications.
1.01 Internal release. Testing and bug fixing. Never published
1.00a Initial release. First public release

View File

@ -1,6 +1,3 @@
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:
@ -21,7 +18,3 @@ 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.
------------------------------------------------------------------------------
See individual files for license details.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 Carsten Larsen
//--------------------------------------------------------------------------//
/* Copyright (c) 2015 Carsten Larsen
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -21,25 +21,21 @@
* 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.
*
*/
//--------------------------------------------------------------------------//
#ifndef NTIMED_COMPILER_H
#define NTIMED_COMPILER_H
//--------------------------------------------------------------------------//
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <math.h>
/*
* See also:
* http://codewiz.org/projects/amiga/Headers/CompilerSpecific.h
*
*/
//--------------------------------------------------------------------------//
// More info at:
// http://codewiz.org/projects/amiga/Headers/CompilerSpecific.h
//--------------------------------------------------------------------------//
#ifdef __VBCC__
# include <stdint.h>
# include <sys/socket.h>
@ -49,40 +45,31 @@
# define round(x) x > 0.0 ? floor(x + 0.5) : ceil(x - 0.5)
typedef uint32_t register_t;
#endif
//--------------------------------------------------------------------------//
#ifdef __GNUC__
# if (__GNUC__ == 2 && __GNUC_MINOR__ == 95)
# include <math.h>
# include <sys/types.h>
# define round(x) x > 0.0 ? floor(x + 0.5) : ceil(x - 0.5)
# define nan(p) 0./0.
typedef u_int8_t uint8_t;
typedef u_int16_t uint16_t;
typedef u_int32_t uint32_t;
typedef u_int64_t uint64_t;
typedef uint32_t uintptr_t;
typedef unsigned int socklen_t;
typedef u_int8_t uint8_t;
typedef u_int16_t uint16_t;
typedef u_int32_t uint32_t;
typedef u_int64_t uint64_t;
typedef uint32_t uintptr_t;
typedef unsigned int socklen_t;
# endif
# ifdef AROS
# include <stdint.h>
typedef uint32_t register_t;
typedef uint32_t register_t;
# endif
typedef uint16_t in_port_t;
typedef unsigned int sa_family_t;
#endif
#ifdef __GNUC__
# define HAVE_ASCTIME
typedef uint16_t in_port_t;
typedef unsigned int sa_family_t;
#endif
// General socket address holding structure, big enough to hold either
// struct sockaddr_in or struct sockaddr_in6 data:
//--------------------------------------------------------------------------//
struct sockaddr_storage {
sa_family_t ss_family; // address family
// all this is padding, implementation specific, ignore it:
char __ss_pad1[128 - sizeof(sa_family_t)];
sa_family_t ss_family;
char __ss_pad1[128 - sizeof(sa_family_t)];
};
//--------------------------------------------------------------------------//
#endif

6
configure vendored
View File

@ -173,11 +173,11 @@ if $VALID ; then
echo ''
if [ -n "$1" ] && [ $1 = "AMIGA" ] ; then
echo 'CC = m68k-amigaos-gcc'
echo "CFLAGS = -O2 -noixemul -DAOS3 -DWITHTEST -DHAVE_LIBTZ -I. -Ilib -Wall -Werror"
echo "LDLIBS = -Llib/aos3 -ltz -lm"
echo "CFLAGS = -O2 -noixemul -DAOS3 -DWITHTEST -I. -Iinclude -Wall -Werror"
echo "LDLIBS = -lm"
elif [ -n "$1" ] && [ $1 = "AROS" ] ; then
echo 'CC = gcc'
echo "CFLAGS = -O2 -DAROS -DWITHTEST -I. -Wall -Werror"
echo "CFLAGS = -O2 -DAROS -I. -Iinclude -Wall -Werror"
echo "LDLIBS = -lm"
else
echo "CFLAGS = -O2 -Wall -DWITHTEST -Werror"

View File

@ -28,7 +28,7 @@
#define _SOCKET_AMITCP_H
//--------------------------------------------------------------------------//
#define AMITCP_BASE_NAME SocketBase
#include "inline_amitcp.h"
#include "inline/amitcp.h"
//--------------------------------------------------------------------------//
#define socket Socket
#define bind Bind

View File

@ -0,0 +1,101 @@
//--------------------------------------------------------------------------//
/*
* 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.
*
*/
//--------------------------------------------------------------------------//
#ifndef _CLIB_TIMEZONE_H
#define _CLIB_TIMEZONE_H
//--------------------------------------------------------------------------//
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <devices/timer.h>
#include <libraries/locale.h>
//--------------------------------------------------------------------------//
#define TZVARIABLE "timezone.prefs"
#define TZDIR "ZONEINFO:"
#define TZDEFAULT "localtime"
#define TZDEFRULES "posixrules"
//--------------------------------------------------------------------------//
#ifndef HAVE_TIMEZONE_T
typedef struct timezone* timezone_t;
#endif
//--------------------------------------------------------------------------//
#ifndef HAVE_LOCATE_T
typedef struct Locale* locale_t;
#endif
//--------------------------------------------------------------------------//
#ifndef _TIME_H_
struct tm {
int tm_sec; /* seconds after the minute [0-61] */
int tm_min; /* minutes after the hour [0-59] */
int tm_hour; /* hours since midnight [0-23] */
int tm_mday; /* day of the month [1-31] */
int tm_mon; /* months since January [0-11] */
int tm_year; /* years since 1900 */
int tm_wday; /* days since Sunday [0-6] */
int tm_yday; /* days since January 1 [0-365] */
int tm_isdst; /* Daylight Savings Time flag */
long tm_gmtoff; /* offset from UTC in seconds */
char *tm_zone; /* timezone abbreviation */
};
#endif
//--------------------------------------------------------------------------//
void tzset(void);
timezone_t tzalloc(char const *name);
void tzfree(timezone_t tz);
time_t time(time_t *p);
time_t mktime(struct tm *tmp);
time_t mktime_z(const timezone_t tz, struct tm *tmp);
struct tm* localtime(const time_t *const timep);
struct tm* localtime_r(const time_t *const timep, struct tm *tmp);
struct tm* localtime_rz(timezone_t tz, time_t const *timep, struct tm *tmp);
struct tm* gmtime(const time_t *timep);
struct tm* gmtime_r(const time_t *timep, struct tm *tmp);
char* ctime(const time_t *const timep);
char* ctime_r(const time_t *const timep, char *buf);
double difftime(const time_t time1, const time_t time0);
char* asctime(const struct tm *timeptr);
char* asctime_r(const struct tm *timeptr, char *buf);
size_t strftime(char * const s, const size_t maxsize,
const char *const format, const struct tm *const t);
size_t strftime_l(char * const s, size_t maxsize,
const char *const format, const struct tm *const t,
locale_t locale);
//--------------------------------------------------------------------------//
void getsystime(struct timeval *tv);
void setsystime(struct timeval *tv);
#ifndef AVOID_TIMEOFDAY
int gettimeofday(struct timeval *tv, const timezone_t tz);
int settimeofday(const struct timeval *tv, const timezone_t tz);
#endif
//--------------------------------------------------------------------------//
int gmtoffset(time_t tloc);
char* tzlocation(void);
void underscore_add(char *s);
void underscore_remove(char *s);
//--------------------------------------------------------------------------//
#endif

View File

@ -1,13 +1,15 @@
/* Automatically generated header! Do not edit! */
#ifndef _INLINE_AMITCP_H
#define _INLINE_AMITCP_H
#ifndef __INLINE_MACROS_H
#include <inline/macros.h>
#endif
#endif /* !__INLINE_MACROS_H */
#ifndef AMITCP_BASE_NAME
#define AMITCP_BASE_NAME lss->lx_BsdSocketBase
#endif
#endif /* !AMITCP_BASE_NAME */
#define TCP_Accept(s, addr, addrlen) \
LP3(0x30, LONG, TCP_Accept, LONG, s, d0, struct sockaddr *, addr, a0, int *, addrlen, a1, \
@ -198,4 +200,4 @@
LP6(0x7e, LONG, TCP_WaitSelect, LONG, nfds, d0, fd_set *, readfds, a0, fd_set *, writefds, a1, fd_set *, execptfds, a2, struct timeval *, timeout, a3, ULONG *, maskp, d1, \
, AMITCP_BASE_NAME)
#endif
#endif /* !_INLINE_AMITCP_H */

122
include/inline/timezone.h Normal file
View File

@ -0,0 +1,122 @@
/* Automatically generated header! Do not edit! */
#ifndef _INLINE_TIMEZONE_H
#define _INLINE_TIMEZONE_H
#ifndef __INLINE_MACROS_H
#include <inline/macros.h>
#endif /* !__INLINE_MACROS_H */
#ifndef TIMEZONE_BASE_NAME
#define TIMEZONE_BASE_NAME TimezoneBase
#endif /* !TIMEZONE_BASE_NAME */
#define asctime(timeptr) \
LP1(0x72, char*, asctime, const struct tm *, timeptr, a0, \
, TIMEZONE_BASE_NAME)
#define asctime_r(timeptr, buf) \
LP2(0x78, char*, asctime_r, const struct tm *, timeptr, a0, char *, buf, a1, \
, TIMEZONE_BASE_NAME)
#define ctime(timep) \
LP1(0x60, char*, ctime, const time_t *const, timep, a0, \
, TIMEZONE_BASE_NAME)
#define ctime_r(timep, buf) \
LP2(0x66, char*, ctime_r, const time_t *const, timep, a0, char *, buf, a1, \
, TIMEZONE_BASE_NAME)
#define difftime(time1, time0) \
LP2(0x6c, double, difftime, const time_t, time1, d1, const time_t, time0, d0, \
, TIMEZONE_BASE_NAME)
#define getsystime(tv) \
LP1NR(0x8a, getsystime, struct timeval *, tv, a0, \
, TIMEZONE_BASE_NAME)
#ifndef AVOID_TIMEOFDAY
#define gettimeofday(tv, tz) \
LP2(0x96, int, gettimeofday, struct timeval *, tv, a0, const timezone_t, tz, a1, \
, TIMEZONE_BASE_NAME)
#endif
#define gmtime(timep) \
LP1(0x54, struct tm*, gmtime, const time_t *, timep, a0, \
, TIMEZONE_BASE_NAME)
#define gmtime_r(timep, tm0) \
LP2(0x5a, struct tm*, gmtime_r, const time_t *, timep, a0, struct tm *, tm0, a1, \
, TIMEZONE_BASE_NAME)
#define gmtoffset(tloc) \
LP1(0xa2, int, gmtoffset, time_t, tloc, d0, \
, TIMEZONE_BASE_NAME)
#define localtime(timep) \
LP1(0x42, struct tm*, localtime, const time_t *const, timep, a0, \
, TIMEZONE_BASE_NAME)
#define localtime_r(timep, tmp) \
LP2(0x48, struct tm*, localtime_r, const time_t *const, timep, a0, struct tm *, tmp, a1, \
, TIMEZONE_BASE_NAME)
#define localtime_rz(tz, timep, tmp) \
LP3(0x4e, struct tm*, localtime_rz, timezone_t, tz, a2, time_t const *, timep, a0, struct tm *, tmp, a1, \
, TIMEZONE_BASE_NAME)
#define mktime(tmp) \
LP1(0x36, time_t, mktime, struct tm *, tmp, a0, \
, TIMEZONE_BASE_NAME)
#define mktime_z(tz, tmp) \
LP2(0x3c, time_t, mktime_z, const timezone_t, tz, a1, struct tm *, tmp, a0, \
, TIMEZONE_BASE_NAME)
#define setsystime(tv) \
LP1NR(0x90, setsystime, struct timeval *, tv, a0, \
, TIMEZONE_BASE_NAME)
#ifndef AVOID_TIMEOFDAY
#define settimeofday(tv, tz) \
LP2(0x9c, int, settimeofday, const struct timeval *, tv, a0, const timezone_t, tz, a1, \
, TIMEZONE_BASE_NAME)
#endif
#define strftime(s, maxsize, format, t) \
LP4(0x7e, size_t, strftime, char * const, s, a0, size_t, maxsize, d0, const char *const, format, a1, const struct tm *const, t, a2, \
, TIMEZONE_BASE_NAME)
#define strftime_l(s, maxsize, format, t, locale) \
LP5(0x84, size_t, strftime_l, char * const, s, a0, size_t, maxsize, d0, const char *const, format, a1, const struct tm *const, t, a2, locale_t, locale, a3, \
, TIMEZONE_BASE_NAME)
#define time(p) \
LP1(0x30, time_t, time, time_t *, p, a0, \
, TIMEZONE_BASE_NAME)
#define tzalloc(name) \
LP1(0x24, timezone_t, tzalloc, char const *, name, a0, \
, TIMEZONE_BASE_NAME)
#define tzfree(tz) \
LP1NR(0x2a, tzfree, timezone_t, tz, a0, \
, TIMEZONE_BASE_NAME)
#define tzlocation() \
LP0(0xa8, char*, tzlocation, \
, TIMEZONE_BASE_NAME)
#define tzset() \
LP0NR(0x1e, tzset, \
, TIMEZONE_BASE_NAME)
#define underscore_add(s) \
LP1NR(0xae, underscore_add, char *, s, a0, \
, TIMEZONE_BASE_NAME)
#define underscore_remove(s) \
LP1NR(0xb4, underscore_remove, char *, s, a0, \
, TIMEZONE_BASE_NAME)
#endif /* !_INLINE_TIMEZONE_H */

Binary file not shown.

Binary file not shown.

View File

@ -1,96 +0,0 @@
/* $NetBSD: time.h,v 1.40 2010/12/16 18:36:47 christos Exp $ */
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
* (c) UNIX System Laboratories, Inc.
* All or some portions of this file are derived from material licensed
* to the University of California by American Telephone and Telegraph
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
* the permission of UNIX System Laboratories, Inc.
*
* 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
*
* @(#)time.h 8.3 (Berkeley) 1/21/94
*/
/**
* @file tz.h
* @brief
* Parts of this file was retrieved from:
* ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-release-6/src/include/time.h
*/
#ifndef _TZ_HEADER
#define _TZ_HEADER
extern char *tzname[2];
#define TZVARIABLE "timezone.prefs"
#define TZDIR "LOCALE:Zoneinfo"
#define TZDEFAULT "localtime"
struct tm {
int tm_sec; /* seconds after the minute [0-61] */
int tm_min; /* minutes after the hour [0-59] */
int tm_hour; /* hours since midnight [0-23] */
int tm_mday; /* day of the month [1-31] */
int tm_mon; /* months since January [0-11] */
int tm_year; /* years since 1900 */
int tm_wday; /* days since Sunday [0-6] */
int tm_yday; /* days since January 1 [0-365] */
int tm_isdst; /* Daylight Savings Time flag */
long tm_gmtoff; /* offset from UTC in seconds */
char *tm_zone; /* timezone abbreviation */
};
#ifndef HAVE_TIME_T
typedef long time_t;
#endif
typedef struct state *timezone_t;
void tzset(void);
void tzfree(const timezone_t);
timezone_t tzalloc(const char *);
time_t time(time_t *);
time_t mktime_z(const timezone_t, struct tm *);
time_t mktime(struct tm *);
struct tm *localtime_rz(const timezone_t, const time_t *, struct tm *);
struct tm *localtime_r(const time_t *, struct tm *);
struct tm *localtime(const time_t *);
struct tm *gmtime_r(const time_t *, struct tm *);
struct tm *gmtime(const time_t *);
char *ctime_r(const time_t *, char *);
char *ctime(const time_t *);
double difftime(time_t, time_t);
time_t time(time_t *x);
#ifndef HAVE_ASCTIME
char *asctime_r(const struct tm *, char *);
char *asctime(const struct tm *);
#endif
#endif

View File

@ -39,11 +39,13 @@ const char *vers = "\0$VER: ntimed-client" AMIGA_VERSION;
#undef PARAM_TABLE_NAME
#undef PARAM_CLIENT
extern int validtime;
struct RDArgs *rdargs = NULL;
struct ntp_peerset *nps = NULL;
struct todolist *tdl = NULL;
struct udp_socket *usc = NULL;
extern char *zone_message;
extern int validtime;
int savetime;
struct ntimedargs {
@ -63,8 +65,8 @@ int main(int argc, char **argv)
{
int result = 0;
struct ntimedargs args = { NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE };
atexit(clean_exit);
atexit(clean_exit);
if((result = amiga_open_libs()) != 0) {
exit(result);
}
@ -172,13 +174,17 @@ static void init_logic(struct ntimedargs *args)
}
amiga_init_offset();
if (zone_message) {
Put(NULL, OCX_DEBUG, "%s\n", zone_message);
}
}
static void clean_exit()
{
if (savetime && validtime) {
Time_Amiga_Save();
Put(NULL, OCX_DEBUG, "Saved to real-time clock\n");
}
ArgTracefile(NULL);

View File

@ -1,4 +1,5 @@
/*-
* Copyright (c) 2015 Carsten Larsen
* Copyright (c) 2014 Poul-Henning Kamp
* All rights reserved.
*
@ -40,13 +41,13 @@ static void clean_exit()
int main(int argc, char * const *argv)
{
int result = 0;
EnableDebug();
atexit(clean_exit);
if((result = amiga_open_libs()) != 0) {
exit(result);
}
EnableDebug();
amiga_init_offset();
Time_Amiga_Passive();
TS_RunTest(NULL);

91
mem.c
View File

@ -1,66 +1,47 @@
/*
* 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.
*
*/
//--------------------------------------------------------------------------//
// This file is in the public domain. //
//--------------------------------------------------------------------------//
#include <stddef.h>
#include <exec/io.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/semaphores.h>
#include <clib/exec_protos.h>
#include "ntimed.h"
//--------------------------------------------------------------------------//
#include "mem.h"
#include "ntimed.h"
//--------------------------------------------------------------------------//
struct MemoryBlock
{
struct MemoryBlock *next;
size_t size;
void *address;
};
//--------------------------------------------------------------------------//
struct MemoryList
{
struct MemoryBlock *first;
struct MemoryBlock *last;
long size;
long count;
long opcount;
};
struct MemoryList *list = NULL;
//--------------------------------------------------------------------------//
static struct MemoryList *list = NULL;
//--------------------------------------------------------------------------//
void allocerror(char*, size_t);
void deallocerror(char*, void*);
//--------------------------------------------------------------------------//
void* allocmem(size_t size)
{
struct MemoryBlock *newblock;
size_t allocsize;
if (list == NULL) {
list = (struct MemoryList*)AllocVec(sizeof(struct MemoryList), MEMF_ANY | MEMF_CLEAR);
list =
(struct MemoryList*)
AllocVec(sizeof(struct MemoryList), MEMF_ANY | MEMF_CLEAR);
if (!list) {
allocerror("list", sizeof(struct MemoryList));
return 0;
@ -75,13 +56,19 @@ void* allocmem(size_t size)
// Align to bytes of 4
allocsize = (size + 3) & ~0x03;
newblock = (struct MemoryBlock*)AllocVec(sizeof(struct MemoryBlock), MEMF_ANY | MEMF_CLEAR);
newblock =
(struct MemoryBlock*)
AllocVec(sizeof(struct MemoryBlock), MEMF_ANY | MEMF_CLEAR);
if (!newblock) {
allocerror("block", sizeof(struct MemoryBlock));
return 0;
}
newblock->address = (struct MemoryBlock*)AllocVec(allocsize, MEMF_ANY | MEMF_CLEAR);
newblock->address =
(struct MemoryBlock*)
AllocVec(allocsize, MEMF_ANY | MEMF_CLEAR);
if (!newblock->address) {
FreeVec(newblock);
allocerror("memory", allocsize);
@ -102,12 +89,23 @@ void* allocmem(size_t size)
list->size += allocsize;
list->count++;
// DEBUG code
// Debug(NULL, "Mememory allocated at address (%x)\n", newblock->address);
list->opcount++;
if (list->opcount % 25 == 0) {
Debug(
NULL,
"Memory usage: %d bytes allocated in %d blocks.\n",
list->size,
list->count
);
}
//Debug(NULL, "Memory allocated at address (%x)\n", newblock->address);
return newblock->address;
}
//--------------------------------------------------------------------------//
void freemem(void* block)
{
struct MemoryBlock *current, *last;
@ -150,8 +148,9 @@ void freemem(void* block)
FreeVec(current->address);
FreeVec(current);
// DEBUG code
// Debug(NULL, "Mememory deallocated at address (%x)\n", block);
list->opcount++;
//Debug(NULL, "Memory deallocated at address (%x)\n", block);
}
void freeall()
@ -174,16 +173,20 @@ void freeall()
list = NULL;
}
//--------------------------------------------------------------------------//
void allocerror(char *descr, size_t size)
{
Debug(NULL, "Mememory allocation error (%s) with size (%d)\n", descr, size);
Debug(NULL, "Memory allocation error (%s) with size (%d)\n", descr, size);
}
void deallocerror(char *descr, void *p)
{
Debug(NULL, "Mememory deallocation error (%s) address (%x)\n", descr, p);
Debug(NULL, "Memory deallocation error (%s) address (%x)\n", descr, p);
}
//--------------------------------------------------------------------------//
char *strdup(const char *s1)
{
char *s2;
@ -198,3 +201,5 @@ char *strdup(const char *s1)
memcpy(s2, s1, --len);
return s2;
}
//--------------------------------------------------------------------------//

37
mem.h
View File

@ -1,39 +1,16 @@
/*
* 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.
*
*/
//--------------------------------------------------------------------------//
// This file is in the public domain. //
//--------------------------------------------------------------------------//
#ifndef AMIGA_MEM_H
#define AMIGA_MEM_H
//--------------------------------------------------------------------------//
#include <stddef.h>
//--------------------------------------------------------------------------//
void* allocmem(size_t);
void freemem(void*);
void freeall();
//--------------------------------------------------------------------------//
#define strdup(s) managed_strdup(s)
char *strdup(const char *s1);
//--------------------------------------------------------------------------//
#endif

View File

@ -508,7 +508,7 @@ int getnameinfo(const struct sockaddr *sa, socklen_t salen, char *node, socklen_
#ifndef AOS3
ntoa_address = inet_ntoa(sa_in->sin_addr);
#else
ntoa_address = inet_ntoa((ULONG)&sa_in->sin_addr);
ntoa_address = inet_ntoa((LONG)sa_in->sin_addr.s_addr);
#endif
if (nodelen <= strlen(ntoa_address)) {
result = EAI_OVERFLOW;

View File

@ -1,16 +1,16 @@
@database ntimed.guide
@author Carsten Larsen
@(c) Carsten Larsen
@$VER: ntimed.guide 1.02 (10.07.2015)
@$VER: ntimed.guide 1.04 (25.07.2015)
@node Main "User manual"
@title "Ntimed user manual"
Ntimed is a network time synchronization client for the Amiga. It is based on
the Ntimed free and open-source software by Poul-Henning Kamp, and sponsored
by the Linux Foundation.
Ntimed is a network time synchronization client for the Amiga. It is based on
the Ntimed free and open-source software by Poul-Henning Kamp, 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
It uses the NTP protocol to synchronize the local Amiga clock to a set of
network servers. Public available NTP servers are reachable through the
Internet.
@ -36,13 +36,13 @@ Local GMT offset will be used if no time zone is selected.
@{b}Template@{ub}
P=PARAM/K, T=TRACEFILE/K, SERVERS/M/A, SYNC/S, SAVE/S, SHOW/S, QUIET/S
PARAM are used to show and set internal Ntimed parameters. A list of parameters
PARAM is 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. {servers} is a list of
NTP time servers.
SYNC will tell Ntimed to spent 5-10 seconds synchronizing and then exit. If
SAVE is specified, time will be save to the real-time clock (RTC) upon exit.
SAVE is specified time will be save to the real-time clock (RTC) upon exit.
SHOW will display extended debugging information in the shell.
NTIMED can be stopped with CTRL C.

View File

@ -40,6 +40,7 @@
struct todolist;
struct udp_socket;
struct timestamp;
/* ocx_*.c -- Operational Context *************************************/
@ -54,6 +55,8 @@ enum ocx_chan {
void Put(struct ocx *, enum ocx_chan, const char *, ...)
__printflike(3, 4);
void PutHex(struct ocx *, enum ocx_chan, const void *, ssize_t len);
void PutTime(struct ocx *, enum ocx_chan , const char *,
const struct timestamp *);
/*
* Report "Failure: " + args + "\n" [+ errno-line] + "\n". exit(1);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 Carsten Larsen
//--------------------------------------------------------------------------//
/* Copyright (c) 2015 Carsten Larsen
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -21,27 +21,18 @@
* 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.
*
*/
//--------------------------------------------------------------------------//
#ifndef NTIMED_PLATFORM_H
#define NTIMED_PLATFORM_H
//--------------------------------------------------------------------------//
#if defined(AROS) || defined(AOS3)
# define AMIGA_VERSION " 1.03 (13.07.2015)"
# define AMIGA_VERSION " 1.04 (25.07.2015)"
# ifndef AMIGA
# define AMIGA
# endif
#endif
//--------------------------------------------------------------------------//
#ifdef HAVE_LIBTZ
# define _TIME_H_
# define HAVE_TIME_T
# include <sys/time.h>
# include "tz.h"
#endif
#define HAVE_WAITSELECT
//--------------------------------------------------------------------------//
#ifdef AMIGA
# include <exec/io.h>
# include <exec/types.h>
@ -77,19 +68,18 @@
#define LOCALELIB_REV 37L
#define BSDLIB_NAME "bsdsocket.library"
#define BSDLIB_REV 03L
#define TIMEZONELIB_NAME "timezone.library"
#define TIMEZONELIB_REV 0L
#define TIMER_NAME TIMERNAME
#define BATTCLOCK_NAME BATTCLOCKNAME
#ifdef TZVARIABLE
# define TZVARIABLE_NAME TZVARIABLE
#endif
#define HAVE_WAITSELECT 1
#define AVOID_TIMEOFDAY 1
//--------------------------------------------------------------------------//
#ifdef AOS3
# define REQ_ERROR "Requires Kickstart 2.04 (37.175) or later.\n"
# include "socket_amitcp.h"
# include <amitcp/socketbasetags.h>
# include "clib/amitcp_protos.h"
#endif
#ifdef AROS
# define REQ_ERROR "Requires a newer version of AROS.\n"
# include <proto/socket.h>
# include <bsdsocket/socketbasetags.h>
# define APRT IPRT
@ -128,16 +118,16 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz);
#endif
//--------------------------------------------------------------------------//
#ifndef _ALIGNBYTES
# define _ALIGNBYTES (sizeof(register_t) - 1)
# define _ALIGNBYTES (sizeof(register_t) - 1)
#endif
#ifndef ALIGN
# define ALIGN(p) (((uintptr_t)(p) + _ALIGNBYTES) & ~_ALIGNBYTES)
# define ALIGN(p) (((uintptr_t)(p) + _ALIGNBYTES) & ~_ALIGNBYTES)
#endif
#ifndef SO_TIMESTAMPING
# define SO_TIMESTAMPING 37
#endif
#ifndef SO_TIMESTAMPNS
# define SO_TIMESTAMPNS 35
# define SO_TIMESTAMPNS 35
#endif
//--------------------------------------------------------------------------//
int amiga_open_libs();
@ -153,5 +143,6 @@ extern struct Library *DOSBase;
extern struct Library *UtilityBase;
extern struct Library *LocaleBase;
extern struct Library *SocketBase;
extern struct Library *TimezoneBase;
//--------------------------------------------------------------------------//
#endif

View File

@ -68,6 +68,11 @@
#include "ntimed_platform.h"
#include "ntimed.h"
#ifdef AOS3
# include "clib/timezone_protos.h"
# include "inline/timezone.h"
#endif
int repeat_trace = 0;
static FILE *debugfile = NULL;
@ -133,17 +138,18 @@ Put(struct ocx *ocx, enum ocx_chan chan, const char *fmt, ...)
va_start(ap, fmt);
dst = getdst(chan);
if (dst != NULL && dst == stdout) {
if (dst != NULL) {
(void)vfprintf(dst, fmt, ap);
fflush(dst);
}
dst = getdst(OCX_DEBUG);
if (
dst != NULL && dst == stdout &&
repeat_trace && chan == OCX_TRACE) {
(void)vfprintf(dst, fmt, ap);
fflush(dst);
// Repeat trace in debug channel
if (chan == OCX_TRACE && repeat_trace) {
dst = getdst(OCX_DEBUG);
if (dst != NULL) {
(void)vfprintf(dst, fmt, ap);
fflush(dst);
}
}
va_end(ap);
@ -164,6 +170,26 @@ PutHex(struct ocx *ocx, enum ocx_chan chan, const void *ptr, ssize_t len)
}
}
void
PutTime(struct ocx *ocx, enum ocx_chan chan, const char *fmt, const struct timestamp *ts)
{
FILE *dst;
struct tm tm;
static char buf[80];
if (TimezoneBase) {
const time_t t = (uint32_t)ts->sec;
localtime_r((const time_t*)&t, &tm);
strftime(buf, 80, "%+", &tm);
dst = getdst(chan);
if (dst != NULL && dst == stdout) {
(void)fprintf(dst, fmt, buf);
fflush(dst);
}
}
}
void
Fail(struct ocx *ocx, int err, const char *fmt, ...)
{
@ -188,3 +214,4 @@ Fail(struct ocx *ocx, int err, const char *fmt, ...)
exit(1);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015 Carsten Larsen
//--------------------------------------------------------------------------//
/* Copyright (c) 2015 Carsten Larsen
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -21,16 +21,15 @@
* 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 "ntimed_platform.h"
#include "ntimed.h"
//--------------------------------------------------------------------------//
#ifdef Debug
#undef Debug
#endif
//--------------------------------------------------------------------------//
#include <exec/io.h>
#include <exec/types.h>
#include <exec/memory.h>
@ -44,49 +43,52 @@
#include <clib/locale_protos.h>
#include <clib/utility_protos.h>
#include <clib/battclock_protos.h>
// 2922 is the number of days between 1.1.1970 and 1.1.1978 (2 leap years and 6 normal)
#define AMIGAOFFSET 2922 * 24 * 60 * 60
#define ENVSIZE 256
// -------------------------------------------------------------------------- //
#ifdef AOS3
# include "clib/timezone_protos.h"
# include "inline/timezone.h"
#endif
// -------------------------------------------------------------------------- //
// 2922 is the number of days between 1.1.1970 and 1.1.1978
// (2 leap years and 6 normal)
// 2922 * 24 * 60 * 60 = 252460800
// -------------------------------------------------------------------------- //
#define AMIGAOFFSET 252460800
//--------------------------------------------------------------------------//
int create_timer();
int delete_timer();
void adjust_timeval(struct timeval *tv, double offset);
//--------------------------------------------------------------------------//
struct Library *BattClockBase;
struct Library *DOSBase = NULL;
struct Library *UtilityBase = NULL;
struct Library *LocaleBase = NULL;
struct Library *SocketBase = NULL;
struct Locale *locale = NULL;
struct Device *TimerBase = NULL;
struct timerequest *request = NULL;
struct Library *DOSBase = NULL;
struct Library *UtilityBase = NULL;
struct Library *LocaleBase = NULL;
struct Library *SocketBase = NULL;
struct Library *TimezoneBase = NULL;
struct Locale *locale = NULL;
struct Device *TimerBase = NULL;
struct timerequest *request = NULL;
struct timeval sync_time;
char *zone_message = NULL;
int validtime = 0;
int limited_sync = 0;
long offset = 0;
//--------------------------------------------------------------------------//
#ifdef AOS3
int errno;
int h_errno;
#endif
//--------------------------------------------------------------------------//
void amiga_open_error(char *name)
{
Put(NULL, OCX_DIAG, OPEN_ERROR, "Locale");
FPrintf(Output(), (STRPTR)OPEN_ERROR, name);
Put(NULL, OCX_DIAG, OPEN_ERROR, name);
}
void amiga_open_lib_error(char *name, int version)
{
Put(NULL, OCX_DIAG, OPEN_VER_ERROR, name, version);
Put(NULL, OCX_DIAG, REQ_ERROR);
FPrintf(Output(), (STRPTR)OPEN_VER_ERROR, name, version);
FPrintf(Output(), (STRPTR)REQ_ERROR, NULL);
}
//--------------------------------------------------------------------------//
int amiga_open_libs()
{
if(!(DOSBase = OpenLibrary((STRPTR)DOSLIB_NAME, DOSLIB_REV))) {
@ -130,11 +132,17 @@ int amiga_open_libs()
return 10;
}
TimezoneBase = OpenLibrary((STRPTR)TIMEZONELIB_NAME, TIMEZONELIB_REV);
return 0;
}
//--------------------------------------------------------------------------//
void amiga_close_libs()
{
if (TimezoneBase != NULL) {
CloseLibrary(TimezoneBase);
}
if (request != NULL) {
delete_timer();
}
@ -163,65 +171,45 @@ void amiga_close_libs()
CloseLibrary(SocketBase);
SocketBase = NULL;
}
}
/**********************************************************************/
#ifdef HAVE_LIBTZ
int amiga_get_gmtoffset_attime(time_t locale_time)
{
struct tm tm;
timezone_t tz;
char *tzvar;
int gmtoffset = 0;
tzvar = AllocVec(ENVSIZE, MEMF_ANY | MEMF_CLEAR);
GetVar(
(STRPTR)TZVARIABLE_NAME,
(STRPTR)tzvar,
ENVSIZE - 1,
GVF_GLOBAL_ONLY
);
tz = tzalloc(tzvar);
if (tz) {
localtime_rz(tz, &locale_time, &tm);
tzfree(tz);
gmtoffset = tm.tm_gmtoff;
} else {
gmtoffset = locale->loc_GMTOffset * 60;
if (zone_message != NULL) {
freemem(zone_message);
zone_message = NULL;
}
Put(NULL, OCX_DEBUG,
"Current time zone offset: UTC/GMT %.1f hour\n",
(float)gmtoffset / 60.0 / 60.0);
FreeVec(tzvar);
return gmtoffset;
}
int amiga_get_gmtoffset()
{
time_t now = time(NULL);
return amiga_get_gmtoffset_attime(now);
}
#endif
/**********************************************************************/
//--------------------------------------------------------------------------//
void amiga_init_offset()
{
int gmt_offset;
time_t now;
struct tm tm;
int gmtoffset;
char *abbr;
#ifdef HAVE_LIBTZ
gmt_offset = amiga_get_gmtoffset();
#else
gmt_offset = locale->loc_GMTOffset * 60 * 60;
if (TimezoneBase) {
now = time(NULL);
localtime_r(&now, &tm);
gmtoffset = tm.tm_gmtoff;
abbr = tm.tm_zone;
} else {
gmtoffset = locale->loc_GMTOffset * 60 * 60;
abbr = '\0';
}
#endif
if (!zone_message) {
zone_message = allocmem(40);
snprintf(zone_message, 40,
"Time zone is GMT %s %.f%s%s%s",
(gmtoffset >= 0.0 ? "+" : "-"),
fabs((float)gmtoffset / 60.0 / 60.0),
(abbr != '\0' ? " (" : '\0'),
(abbr != '\0' ? abbr : '\0'),
(abbr != '\0' ? ")" : '\0')
);
}
offset = -gmt_offset + AMIGAOFFSET;
offset = -gmtoffset + AMIGAOFFSET;
}
/**********************************************************************/
//--------------------------------------------------------------------------//
int create_timer()
{
LONG error;
@ -251,7 +239,7 @@ int create_timer()
return 0;
}
//--------------------------------------------------------------------------//
int delete_timer()
{
struct MsgPort *port;
@ -268,18 +256,13 @@ int delete_timer()
return 0;
}
/**********************************************************************/
//--------------------------------------------------------------------------//
int gettimeofday(struct timeval *tv, struct timezone *tz)
{
#ifdef USESYSTIME
GetSysTime(tv);
tv_secs = (long)tv_secs + offset;
#else
request->tr_node.io_Command = TR_GETSYSTIME;
DoIO((struct IORequest*)request);
tv->tv_secs = (long)request->tr_time.tv_secs + offset;
tv->tv_micro = request->tr_time.tv_micro;
#endif
return 0;
}
@ -289,21 +272,35 @@ int settimeofday(const struct timeval *tv, const struct timezone *tz)
request->tr_time.tv_secs = (long)tv->tv_secs - offset;
request->tr_time.tv_micro = tv->tv_micro;
DoIO((struct IORequest*)request);
validtime = 1;
validtime++;
// Make sure we are in the right timezone
if (validtime == 2) {
amiga_init_offset();
}
return 0;
}
/**********************************************************************/
//--------------------------------------------------------------------------//
void amiga_save_time(void)
{
time_t now;
struct tm tm;
struct timeval tv;
int gmt_offset = 0;
int gmtoffset = 0;
char *message = '\0';
#ifdef HAVE_LIBTZ
gmt_offset = amiga_get_gmtoffset();
#endif
// Assume HW clock is in GMT if timezone library is present
if (TimezoneBase) {
now = time(NULL);
localtime_r(&now, &tm);
gmtoffset = tm.tm_gmtoff;
message = " GMT";
}
gettimeofday(&tv, NULL);
WriteBattClock((long)tv.tv_secs - offset - gmt_offset);
WriteBattClock((long)tv.tv_secs - offset - gmtoffset);
Put(NULL, OCX_DEBUG, "Saved%s to real-time clock\n", message);
}
void amiga_sync_time(int seconds)
@ -344,7 +341,7 @@ int amiga_sleep_time(double dur)
return 0;
}
/**********************************************************************/
//--------------------------------------------------------------------------//
void adjust_timeval(struct timeval *tv, double offset)
{
double d1, d2;
@ -367,7 +364,7 @@ void adjust_timeval(struct timeval *tv, double offset)
tv->tv_secs = secs;
tv->tv_micro = micro;
}
/**********************************************************************/
//--------------------------------------------------------------------------//
#ifndef HAVE_POLL
int poll(struct pollfd *pfds, nfds_t nfds, int timeout)
{
@ -428,4 +425,4 @@ int poll(struct pollfd *pfds, nfds_t nfds, int timeout)
return ret;
}
#endif
/**********************************************************************/
//--------------------------------------------------------------------------//

3
todo.c
View File

@ -167,6 +167,7 @@ enum todo_e
TODO_Run(struct ocx *ocx, struct todolist *tdl)
{
struct todo *tp;
struct timestamp show;
enum todo_e ret = TODO_OK;
char buf[40];
int i;
@ -180,6 +181,8 @@ TODO_Run(struct ocx *ocx, struct todolist *tdl)
AZ(i);
TS_Format(buf, sizeof buf, &tp->when);
Put(ocx, OCX_TRACE, "Now %s %s\n", buf, tp->what);
show = tp->when;
PutTime(ocx, OCX_DEBUG, "%s\n", &show);
ret = tp->func(ocx, tdl, tp->priv);
if (ret == TODO_FAIL)
break;