Skip to content

Instantly share code, notes, and snippets.

@dutchLuck
Last active February 21, 2024 13:31
Show Gist options
  • Save dutchLuck/4ec6d2f9f7d8fc269695d590535d9a50 to your computer and use it in GitHub Desktop.
Save dutchLuck/4ec6d2f9f7d8fc269695d590535d9a50 to your computer and use it in GitHub Desktop.
Linux man page example of using library rtime function to get time from a network server running the RFC 868 time (port 37) service.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <rpc/auth_des.h>
#include <netdb.h>
static int use_tcp = 0;
static char *servername = "linux";
int
main(void)
{
struct sockaddr_in name;
struct rpc_timeval time1 = {0,0};
struct rpc_timeval timeout = {1,0};
struct hostent *hent;
int ret;
memset(&name, 0, sizeof(name));
sethostent(1);
hent = gethostbyname(servername);
memcpy(&name.sin_addr, hent->h_addr, hent->h_length);
ret = rtime(&name, &time1, use_tcp ? NULL : &timeout);
if (ret < 0)
perror("rtime error");
else {
time_t t = time1.tv_sec;
printf("%s\n", ctime(&t));
}
exit(EXIT_SUCCESS);
}

#rtime_man_example

Linux comes with a library function name rtime to provide access to a RFC 868 time (port 37) service on a remote server. When successful the rtime function will return the number of seconds since Jan 1st 1900 as determined by the server.

The (Ubuntu) Linux man page for the rtime gives an example snippet of code. Unfortunately the example doesn't compile on Ubuntu 22.04LTS, which is my current version, but will compile with gcc on earlier Ubuntu LTS releases, such as on Ubuntu 14.04 LTS up to 20.04 LTS. For example on 20.04.6LTS the following command line will compile the example code without any warnings or errors.

cc -Wall -o rtime_man_example rtime_man_example.c

On 22.04LTS the first difficulty is that header file rpc/auth_des.h cannot be found. That header file can be found if the compiler invocation is; -

cc -Wall -I /usr/include/tirpc -o rtimeExample rtimeExample.c -ltirpc

Unfortunately the necessary struct definitions are still not available. The Ubuntu 22.04 auth_des.h uses struct timeval rather than struct rpc_timeval. Modifying the struct to timeval allows the compile to succeed but the executable does not succeed in obtaining the time. Initially there is the known requirement to change the server name from "linux" to the name of a server that does exist. Once this is done the code outputs that there has been an I/O error. It doesn't make any difference if the code is modified to change rtime to use TCP rather than UDP as its means of connection.

Falling back to using an older version of Ubuntu the code in rtimeExample.c will work.

/*
* R T I M E E X A M P L E
*
*/
/*
* Manpage example for rtime() slightly modified
* compile on Ubuntu 20.04 LTS or older LTS version
* cc -Wall -o rtimeExample rtimeExample.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <rpc/auth_des.h>
#include <netdb.h>
static int use_tcp = 0;
static char * servername = NULL;
int main(int argc, char * argv[]) {
struct sockaddr_in name;
struct rpc_timeval time1 = {0,0};
struct rpc_timeval timeout = {1,0};
struct hostent *hent;
int ret;
if( argc < 2 ) {
printf("Useage: %s name_of_time_server [Use_TCP]\n", argv[0]);
exit(EXIT_FAILURE);
}
else {
servername = argv[1];
use_tcp = ( argc > 2 );
memset(&name, 0, sizeof(name));
sethostent(1);
if(( hent = gethostbyname(servername)) == NULL ) {
fprintf(stderr, "DNS error for name \"%s\"\n", servername );
exit(EXIT_FAILURE);
}
else {
memcpy(&name.sin_addr, hent->h_addr, hent->h_length);
ret = rtime(&name, &time1, use_tcp ? NULL : &timeout);
if (ret < 0) {
perror("rtime error");
exit(EXIT_FAILURE);
}
else {
time_t t = time1.tv_sec;
printf("%s", ctime(&t));
}
}
}
exit(EXIT_SUCCESS);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment