From 05b91582b2a3e255f8b22bc9f2243f3086116449 Mon Sep 17 00:00:00 2001 From: Brett Gordon Date: Sun, 28 Aug 2016 16:48:04 -0400 Subject: [PATCH] drivewire: init commit "dwdate" - set system time from userspace. --- Applications/dw/Makefile.6809 | 2 +- Applications/dw/dwdate.c | 174 ++++++++++++++++++++++++++++++++++ Applications/dw/fuzix-dw.pkg | 8 +- 3 files changed, 180 insertions(+), 4 deletions(-) create mode 100644 Applications/dw/dwdate.c diff --git a/Applications/dw/Makefile.6809 b/Applications/dw/Makefile.6809 index 4745f395..5614c926 100644 --- a/Applications/dw/Makefile.6809 +++ b/Applications/dw/Makefile.6809 @@ -15,7 +15,7 @@ CRT0 = ../../Library/libs/crt0_6809.o .SUFFIXES: .c .o -SRCS = dw.c dwgetty.c dwterm.c +SRCS = dw.c dwgetty.c dwterm.c dwdate.c OBJS = $(SRCS:.c=.o) diff --git a/Applications/dw/dwdate.c b/Applications/dw/dwdate.c new file mode 100644 index 00000000..74643b46 --- /dev/null +++ b/Applications/dw/dwdate.c @@ -0,0 +1,174 @@ +/* A program to get the time from drivewire. Displays it or sets the + system clock from it. Must be super user +*/ + + +#include +#include +#include +#include +#include +#include + + +char *devname="/dev/dw0"; + +static const uint16_t mktime_moffset[12]= { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; + + +static int printe( char *s ){ + write(2, s, strlen(s) ); + write(2, "\n", 1 ); +} + +/* A Classic, as stolen from Gnu */ +static uint32_t mul( uint32_t a, uint32_t b) +{ + uint32_t r=0; + while (a){ + if (a & 1) + r += b; + a >>= 1; + b <<= 1; + } + b=r; + return b; +} + + +static int get_time( uint8_t *tbuf ) +{ + int fd; + int ret; + struct dw_trans d; + + fd = open( devname, O_RDONLY ); + if( fd < 1){ + perror( "drivewire device open"); + exit(1); + } + + tbuf[0]=0x23; + d.sbuf = tbuf; + d.sbufz = 1; + d.rbuf = tbuf; + d.rbufz = 6; + + ret = ioctl( fd, DRIVEWIREC_TRANS, &d ); + close( fd ); + return ret; +} + + +int main( int argc, char *argv[] ){ + + int i,x; + char buf[6]; + uint8_t year, month, day, hour, minute, second; + uint32_t ret; /* accumulator for conversion */ + int setflg = 0; /* set system time flag */ + int disflg = 0; /* display retrieved time flag */ + int parbrk = 0; /* parse break flag */ + + /* scan args */ + for( x = 1; x < argc; x++ ){ + if( argv[x][0] != '-' ){ + printe( "bad arg" ); + exit(1); + } + for( i = 1; argv[x][i]; i++ ){ + switch( argv[x][i] ){ + case 's': + setflg = 1; + break; + case 'd': + disflg = 1; + break; + case 'x': + devname = argv[++x]; + if( ! devname ){ + printe("bad device name"); + exit(1); + } + parbrk = 1; + break; + default: + printe("bad option" ); + exit(1); + } + if( parbrk ){ + parbrk = 0; + break; + } + } + } + + x=get_time( buf ); + if( x ){ + perror("drivewire"); + exit(1); + } + + /* figure out secs from epoc */ + + year = buf[0]; + month = buf[1]; + day = buf[2]; + hour = buf[3]; + minute = buf[4]; + second = buf[5]; + + if(year < 70) + year += 100; + + /* following code is based on utc_mktime() from ELKS + https://github.com/jbruchon/elks/blob/master/elkscmd/sh_utils/date.c + */ + + /* uses zero-based month index */ + month--; + + /* calculate days from years */ + ret=365; + ret = mul( ret, year - 70 ); + + /* count leap days in preceding years */ + ret += (year - 69) >> 2; + + + /* calculate days from months */ + ret += mktime_moffset[month]; + + /* add in this year's leap day, if any */ + if (((year & 3) == 0) && (month > 1)) + ret++; + + /* add in days in this month */ + ret += day - 1; + /* convert to hours */ + ret = mul( ret, 24 ); + ret += hour; + + /* convert to minutes */ + ret = mul( ret, 60 ); + ret += minute; + + /* convert to seconds */ + ret = mul( ret, 60 ); + ret += second; + + if( disflg || !setflg ) + printf( ctime( (time_t *)&ret ) ); + + if( setflg ){ + /* This is a sleezy cast */ + x=stime( (time_t *)&ret ); + if( x ){ + perror( "stime" ); + exit(1); + } + } + + exit(0); + +} diff --git a/Applications/dw/fuzix-dw.pkg b/Applications/dw/fuzix-dw.pkg index 4156a05f..e1259fb0 100644 --- a/Applications/dw/fuzix-dw.pkg +++ b/Applications/dw/fuzix-dw.pkg @@ -1,6 +1,8 @@ package drivewire if-file dw -f 0755 /usr/bin/dw dw -f 0755 /usr/bin/dwgetty dwgetty -f 0755 /usr/bin/dwterm dwterm +f 0755 /usr/bin/dw dw +f 0755 /usr/bin/dwgetty dwgetty +f 0755 /usr/bin/dwterm dwterm +f 0755 /usr/bin/dwdate dwdate +f 0644 /usr/man/man1/dwdate.1 dwdate.1 \ No newline at end of file -- 2.34.1