Skip to content

Commit

Permalink
SNTP v1.1: Fix invalid time when seconds are multiple of 60 (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
ducasp authored and Konamiman committed Aug 14, 2019
1 parent d23c6ee commit a3ac9b7
Showing 1 changed file with 56 additions and 53 deletions.
109 changes: 56 additions & 53 deletions SRC/NETWORK/sntp.c
@@ -1,19 +1,21 @@
/* SNTP client for Ethernet UNAPI
By Konamiman 2/2010
v1.1 by Oduvaldo Pavan Junior ( ducasp@gmail.com )
v1.1 fixes when the count of seconds will end with HH:MM:60 when
it should be HH:MM+1:00
Compilation command line:
sdcc --code-loc 0x170 --data-loc 0 -mz80 --disable-warning 196
--no-std-crt0 crt0_msxdos_advanced.rel msxchar.rel asm.lib sntp.c
sdcc --code-loc 0x180 --data-loc 0 -mz80 --disable-warning 196
--no-std-crt0 crt0msx_msxdos_advanced.rel printf_simple.rel
putchar_msxdos.rel asm.lib sntp.c
hex2bin -e com sntp.ihx
ASM.LIB, MSXCHAR.REL and crt0msx_msxdos_advanced.rel
are available at www.konamiman.com
(You don't need MSXCHAR.LIB if you manage to put proper PUTCHAR.REL,
GETCHAR.REL and PRINTF.REL in the standard Z80.LIB... I couldn't manage to
do it, I get a "Library not created with SDCCLIB" error)
Comments are welcome: konamiman@konamiman.com
*/

Expand Down Expand Up @@ -65,27 +67,28 @@ enum TcpipUnapiFunctions {
};

enum TcpipErrorCodes {
ERR_OK,
ERR_NOT_IMP,
ERR_NO_NETWORK,
ERR_NO_DATA,
ERR_INV_PARAM,
ERR_QUERY_EXISTS,
ERR_INV_IP,
ERR_NO_DNS,
ERR_DNS,
ERR_NO_FREE_CONN,
ERR_CONN_EXISTS,
ERR_NO_CONN,
ERR_CONN_STATE,
ERR_BUFFER,
ERR_LARGE_DGRAM,
ERR_OK,
ERR_NOT_IMP,
ERR_NO_NETWORK,
ERR_NO_DATA,
ERR_INV_PARAM,
ERR_QUERY_EXISTS,
ERR_INV_IP,
ERR_NO_DNS,
ERR_DNS,
ERR_NO_FREE_CONN,
ERR_CONN_EXISTS,
ERR_NO_CONN,
ERR_CONN_STATE,
ERR_BUFFER,
ERR_LARGE_DGRAM,
ERR_INV_OPER
};

const char* strPresentation=
"SNTP time setter for the TCP/IP UNAPI 1.0\r\n"
"By Konamiman, 4/2010\r\n"
"SNTP time setter for the TCP/IP UNAPI 1.1\r\n"
"by Oduvaldo\r\n"
"based on SNTP 1.0 by Konamiman\r\n"
"\r\n";

const char* strUsage=
Expand Down Expand Up @@ -142,7 +145,7 @@ void CheckYear();
/**********************
*** MAIN is here ***
**********************/

int main(char** argv, int argc)
{
char paramLetter;
Expand Down Expand Up @@ -170,7 +173,7 @@ int main(char** argv, int argc)
SecsPerMonth[11]=SECS_IN_MONTH_31;

//* Try to get time zone from environment item

timeZoneBuffer[0] = '\0';
regs.Words.HL = (int)"TIMEZONE";
regs.Words.DE = (int)timeZoneBuffer;
Expand Down Expand Up @@ -228,18 +231,18 @@ int main(char** argv, int argc)
}

//* Parse time zone

if(timeZoneString != NULL) {
timeZoneHours = (((byte)(timeZoneString[1])-'0')*10) + (byte)(timeZoneString[2]-'0');
if(timeZoneHours > 12) {
Terminate(strInvalidTimeZone);
}

timeZoneMinutes = (((byte)(timeZoneString[4])-'0')*10) + (byte)(timeZoneString[5]-'0');
if(timeZoneMinutes > 59) {
Terminate(strInvalidTimeZone);
}

timeZoneSeconds = ((timeZoneHours * (int)SECS_IN_HOUR)) + ((timeZoneMinutes * (int)SECS_IN_MINUTE));
}

Expand All @@ -250,7 +253,7 @@ int main(char** argv, int argc)
Terminate("No TCP/IP UNAPI implementations found");
}
UnapiBuildCodeBlock(NULL, 1, &codeBlock);

regs.Bytes.B = 0;
UnapiCall(&codeBlock, TCPIP_UDP_CLOSE, &regs, REGS_MAIN, REGS_NONE);
if(regs.Bytes.A == ERR_NOT_IMP) {
Expand All @@ -260,7 +263,7 @@ int main(char** argv, int argc)
regs.Words.HL = SNTP_PORT;
regs.Bytes.B = 0;
UnapiCall(&codeBlock, TCPIP_UDP_OPEN, &regs, REGS_MAIN, REGS_MAIN);
if(regs.Bytes.A == ERR_NO_FREE_CONN) {
if(regs.Bytes.A == ERR_NO_FREE_CONN) {
Terminate("No free UDP connections available");
}
else if(regs.Bytes.A == ERR_CONN_EXISTS) {
Expand All @@ -275,7 +278,7 @@ int main(char** argv, int argc)
//* Resolve the host name

PrintIfVerbose("Resolving host name... ");

regs.Words.HL = (int)hostString;
regs.Bytes.B = 0;
UnapiCall(&codeBlock, TCPIP_DNS_Q, &regs, REGS_MAIN, REGS_MAIN);
Expand All @@ -289,13 +292,13 @@ int main(char** argv, int argc)
sprintf(buffer, "Unknown error when resolving the host name (code %i)", regs.Bytes.A);
Terminate(buffer);
}

do {
UnapiCall(&codeBlock, TCPIP_WAIT, &regs, REGS_NONE, REGS_NONE);
regs.Bytes.B = 0;
UnapiCall(&codeBlock, TCPIP_DNS_S, &regs, REGS_MAIN, REGS_MAIN);
} while (regs.Bytes.A == 0 && regs.Bytes.B == 1);

if(regs.Bytes.A != 0) {
if(regs.Bytes.B == 2) {
Terminate("DNS server failure");
Expand All @@ -313,7 +316,7 @@ int main(char** argv, int argc)
sprintf(buffer, "Unknown error returned by DNS server (code %i)", regs.Bytes.B);
Terminate(buffer);
}
}
}

paramsBlock[0] = regs.Bytes.L;
paramsBlock[1] = regs.Bytes.H;
Expand All @@ -325,9 +328,9 @@ int main(char** argv, int argc)
}

//* Open a new UDP connection and send request

PrintIfVerbose("Querying the time server... ");

*buffer=0x1B;
for(i=1; i<48; i++) {
buffer[i]=0;
Expand All @@ -341,7 +344,7 @@ int main(char** argv, int argc)
regs.Bytes.B = conn;
regs.Words.HL=(int)buffer;
regs.Words.DE=(int)paramsBlock;

UnapiCall(&codeBlock, TCPIP_UDP_SEND, &regs, REGS_MAIN, REGS_MAIN);
if(regs.Bytes.A != 0) {
sprintf(buffer, "Unknown error when sending request to time server (code %i)", regs.Bytes.A);
Expand Down Expand Up @@ -394,7 +397,7 @@ int main(char** argv, int argc)
((byte*)&seconds)[1]=buffer[42];
((byte*)&seconds)[2]=buffer[41];
((byte*)&seconds)[3]=buffer[40];

if(verbose) {
SecondsToDate(seconds, &year, &month, &day, &hour, &minute, &second);
CheckYear();
Expand All @@ -408,15 +411,15 @@ int main(char** argv, int argc)
seconds += timeZoneSeconds;
}
}

SecondsToDate(seconds, &year, &month, &day, &hour, &minute, &second);
CheckYear();
if(verbose && timeZoneString != NULL) {
printf("Time adjusted to time zone: %i-%i-%i, %i:%i:%i\r\n", year, month, day, hour, minute, second);
}

//* Change the MSX clock if necessary

if(displayOnly) {
if(!verbose) {
printf("Time obtained from time server: %i-%i-%i, %i:%i:%i\r\n", year, month, day, hour, minute, second);
Expand All @@ -429,22 +432,22 @@ int main(char** argv, int argc)
if(regs.Bytes.A != 0) {
Terminate("Invalid date for the MSX clock");
}

regs.Bytes.H = hour;
regs.Bytes.L = minute;
regs.Bytes.D = second;
DosCall(_STIME, &regs, REGS_MAIN, REGS_AF);
if(regs.Bytes.A != 0) {
Terminate("Invalid time for the MSX clock");
}

if(verbose) {
print("The clock has been set to the adjusted time.");
} else {
printf("The clock has been set to: %i-%i-%i, %i:%i:%i\r\n", year, month, day, hour, minute, second);
}
}

Terminate(NULL);
return 0;
}
Expand Down Expand Up @@ -527,7 +530,7 @@ void SecondsToDate(unsigned long seconds, int* year, byte* month, byte* day, byt

*minute = 0;

while(seconds > SECS_IN_MINUTE) {
while(seconds >= SECS_IN_MINUTE) {
seconds -= SECS_IN_MINUTE;
*minute = (byte)(*minute + 1);
}
Expand All @@ -543,17 +546,17 @@ int IsValidTimeZone(byte* timeZoneString)
if(!(timeZoneString[0]==(byte)'+' || timeZoneString[0]==(byte)'-')) {
return 0;
}

if(!(IsDigit(timeZoneString[1]) && IsDigit(timeZoneString[2]) && IsDigit(timeZoneString[4]) && IsDigit(timeZoneString[5])))
{
return 0;
}

if(timeZoneString[3] != (byte)':' || timeZoneString[6] != 0)
{
return 0;
}

return 1;
}

Expand All @@ -573,12 +576,12 @@ void Terminate(char* errorMessage)
printf("*** SNTP ERROR: %s\r\n", errorMessage);
}
}

if(conn != 0) {
regs.Bytes.B = conn;
UnapiCall(&codeBlock, TCPIP_UDP_CLOSE, &regs, REGS_MAIN, REGS_NONE);
}

DosCall(_TERM0, &regs, REGS_NONE, REGS_NONE);
}

Expand All @@ -588,7 +591,7 @@ void CheckYear()
if(year < 2010) {
Terminate("The server returned a date that is before year 2010");
}

if(year > 2079) {
Terminate("The server returned a date that is after year 2079");
}
Expand Down

0 comments on commit a3ac9b7

Please sign in to comment.