Module: tools Branch: master Commit: df9f82b2f5e8040085f97e116f93f60187825ec7 URL: http://source.winehq.org/git/tools.git/?a=commit;h=df9f82b2f5e8040085f97e116...
Author: Francois Gouget fgouget@codeweavers.com Date: Thu Mar 6 15:24:05 2014 +0100
testbot/testagentd: Add an RPC to set the remote host's system time.
---
testbot/lib/WineTestBot/TestAgent.pm | 23 ++++++++++++++++++ testbot/scripts/TestAgent | 8 ++++++- testbot/src/testagentd/platform.h | 6 +++++ testbot/src/testagentd/platform_unix.c | 24 +++++++++++++++++++ testbot/src/testagentd/platform_windows.c | 37 +++++++++++++++++++++++++++++ testbot/src/testagentd/testagentd.c | 25 ++++++++++++++++++- 6 files changed, 121 insertions(+), 2 deletions(-)
diff --git a/testbot/lib/WineTestBot/TestAgent.pm b/testbot/lib/WineTestBot/TestAgent.pm index dfc86e3..299f63e 100644 --- a/testbot/lib/WineTestBot/TestAgent.pm +++ b/testbot/lib/WineTestBot/TestAgent.pm @@ -36,6 +36,7 @@ my $RPC_RUN = 3; my $RPC_WAIT = 4; my $RPC_RM = 5; my $RPC_WAIT2 = 6; +my $RPC_SETTIME = 7;
my %RpcNames=( $RPC_PING => 'ping', @@ -45,6 +46,7 @@ my %RpcNames=( $RPC_WAIT => 'wait', $RPC_RM => 'rm', $RPC_WAIT2 => 'wait2', + $RPC_SETTIME => 'settime', );
my $Debug = 0; @@ -1155,4 +1157,25 @@ sub Rm($@) return $self->_RecvErrorList(); }
+sub SetTime($) +{ + my ($self) = @_; + debug("SetTime\n"); + + # Make sure we have the server version + return undef if (!$self->{agentversion} and !$self->_Connect()); + + # Send the command + if (!$self->_StartRPC($RPC_SETTIME) or + !$self->_SendListSize(2) or + !$self->_SendUInt64(time()) or + !$self->_SendUInt32(30)) + { + return undef; + } + + # Get the reply + return $self->_RecvList(''); +} + 1; diff --git a/testbot/scripts/TestAgent b/testbot/scripts/TestAgent index bb7dd14..30e2fbc 100755 --- a/testbot/scripts/TestAgent +++ b/testbot/scripts/TestAgent @@ -187,7 +187,7 @@ while (@ARGV) { $Cmd = $arg; } - elsif ($arg eq "ping") + elsif ($arg eq "ping" or $arg eq "settime") { $Cmd = $arg; } @@ -268,6 +268,7 @@ if (defined $Usage) print "or $name0 [options] <hostname> getfile <serverpath> <localpath>\n"; print "or $name0 [options] <hostname> run <command> <arguments>\n"; print "or $name0 [options] <hostname> wait <pid>\n"; + print "or $name0 [options] <hostname> settime\n"; print "or $name0 [options] <hostname> rm <serverfiles>\n"; print "or $name0 [options] <hostname> [ping|version]\n"; print "\n"; @@ -290,6 +291,7 @@ if (defined $Usage) print " specified server file.\n"; print " --run-dntrunc-err Do not truncate the file stderr is redirected to.\n"; print " wait Waits for the specified child process on the server.\n"; + print " settime Set the system time of the remote host.\n"; print " rm Deletes the specified files on the server.\n"; print " getversion Returns the version of the server.\n"; print " ping Makes sure the server is still alive.\n"; @@ -370,6 +372,10 @@ elsif ($Cmd eq "rm") $Result = 1; } } +elsif ($Cmd eq "settime") +{ + $Result = $TA->SetTime(); +} elsif ($Cmd eq "getversion") { $Result = $TA->GetVersion(); diff --git a/testbot/src/testagentd/platform.h b/testbot/src/testagentd/platform.h index fffaa4b..785b3b5 100644 --- a/testbot/src/testagentd/platform.h +++ b/testbot/src/testagentd/platform.h @@ -79,6 +79,12 @@ uint64_t platform_run(char** argv, uint32_t flags, char** redirects); */ int platform_wait(SOCKET client, uint64_t pid, uint32_t timeout, uint32_t *childstatus);
+/* Sets the system time to the specified Unix epoch. If the system time is + * already within leeway seconds of the specified time, then consider that + * the system clock is already correct. + */ +int platform_settime(uint64_t epoch, uint32_t leeway); + /* Returns a string describing the last socket-related error */ int sockeintr(void); const char* sockerror(void); diff --git a/testbot/src/testagentd/platform_unix.c b/testbot/src/testagentd/platform_unix.c index e003135..c9fc7fd 100644 --- a/testbot/src/testagentd/platform_unix.c +++ b/testbot/src/testagentd/platform_unix.c @@ -29,6 +29,7 @@ #include <sys/wait.h> #include <signal.h> #include <time.h> +#include <sys/time.h>
#include "platform.h" #include "list.h" @@ -198,6 +199,29 @@ int platform_wait(SOCKET client, uint64_t pid, uint32_t timeout, uint32_t *child return 1; }
+int platform_settime(uint64_t epoch, uint32_t leeway) +{ + struct timeval tv; + + if (leeway) + { + uint64_t offset; + gettimeofday(&tv, NULL); + offset = llabs(tv.tv_sec-epoch); + if (offset <= leeway) + return 2; + } + + tv.tv_sec = epoch; + tv.tv_usec = 0; + if (!settimeofday(&tv, NULL)) + { + set_status(ST_ERROR, "failed to set the time: %s", strerror(errno)); + return 0; + } + return 1; +} + int sockeintr(void) { return errno == EINTR; diff --git a/testbot/src/testagentd/platform_windows.c b/testbot/src/testagentd/platform_windows.c index a0dccfa..9dda56a 100644 --- a/testbot/src/testagentd/platform_windows.c +++ b/testbot/src/testagentd/platform_windows.c @@ -221,6 +221,43 @@ int platform_wait(SOCKET client, uint64_t pid, uint32_t timeout, uint32_t *child return success; }
+int platform_settime(uint64_t epoch, uint32_t leeway) +{ + FILETIME filetime; + SYSTEMTIME systemtime; + + /* Where 134774 is the number of days from 1601/1/1 to 1970/1/1 */ + epoch = (epoch + ((uint64_t)134774) * 24 * 3600 ) * 10000000; + + if (leeway) + { + ULARGE_INTEGER ul; + GetSystemTime(&systemtime); + /* in case of an error set the time unconditionally */ + if (SystemTimeToFileTime(&systemtime, &filetime)) + { + ul.LowPart = filetime.dwLowDateTime; + ul.HighPart = filetime.dwHighDateTime; + if (llabs(ul.QuadPart-epoch)/10000000 < leeway) + return 1; + } + } + + filetime.dwLowDateTime = (DWORD)epoch; + filetime.dwHighDateTime = epoch >> 32; + if (!FileTimeToSystemTime(&filetime, &systemtime)) + { + set_status(ST_ERROR, "failed to oconvert the time (%lu)", GetLastError()); + return 0; + } + if (!SetSystemTime(&systemtime)) + { + set_status(ST_ERROR, "failed to set the time (%lu)", GetLastError()); + return 0; + } + return 1; +} + int sockretry(void) { return (WSAGetLastError() == WSAEINTR); diff --git a/testbot/src/testagentd/testagentd.c b/testbot/src/testagentd/testagentd.c index e99dcb4..35b42f3 100644 --- a/testbot/src/testagentd/testagentd.c +++ b/testbot/src/testagentd/testagentd.c @@ -35,8 +35,9 @@ * 1.1: Added the wait2 RPC. * 1.2: Add more redirection options to the run RPC. * 1.3: Fix the zero / infinite timeouts in the wait2 RPC. + * 1.4: Add the settime RPC. */ -#define PROTOCOL_VERSION "testagentd 1.3" +#define PROTOCOL_VERSION "testagentd 1.4"
#define BLOCK_SIZE 65536
@@ -82,6 +83,7 @@ enum rpc_ids_t RPCID_WAIT, RPCID_RM, RPCID_WAIT2, + RPCID_SETTIME, };
/* This is the RPC currently being processed */ @@ -891,6 +893,24 @@ static void do_rm(SOCKET client) } }
+static void do_settime(SOCKET client) +{ + uint64_t epoch; + uint32_t leeway; + + if (!expect_list_size(client, 2) || + !recv_uint64(client, &epoch) || + !recv_uint32(client, &leeway)) + { + send_error(client); + return; + } + if (platform_settime(epoch, leeway)) + send_list_size(client, 0); + else + send_error(client); +} + static void do_unknown(SOCKET client, uint32_t id) { uint32_t argc; @@ -952,6 +972,9 @@ static void process_rpc(SOCKET client) case RPCID_RM: do_rm(client); break; + case RPCID_SETTIME: + do_settime(client); + break; default: do_unknown(client, rpcid); }