2001-12-11 08:21:50 +03:00
/*
Samba Unix / Linux SMB client library
net time command
Copyright ( C ) 2001 Andrew Tridgell ( tridge @ samba . org )
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2001-12-11 08:21:50 +03:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>. */
2001-12-11 08:21:50 +03:00
# include "includes.h"
2004-10-07 08:01:18 +04:00
# include "utils/net.h"
2001-12-11 08:21:50 +03:00
/*
return the time on a server . This does not require any authentication
*/
2001-12-12 12:37:17 +03:00
static time_t cli_servertime ( const char * host , struct in_addr * ip , int * zone )
2001-12-11 08:21:50 +03:00
{
struct nmb_name calling , called ;
time_t ret = 0 ;
struct cli_state * cli = NULL ;
2007-06-20 21:38:42 +04:00
NTSTATUS status ;
2001-12-11 08:21:50 +03:00
2006-07-11 22:01:26 +04:00
cli = cli_initialise ( ) ;
if ( ! cli ) {
goto done ;
}
2001-12-11 08:47:26 +03:00
2007-06-20 21:38:42 +04:00
status = cli_connect ( cli , host , ip ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
fprintf ( stderr , " Can't contact server %s. Error %s \n " , host , nt_errstr ( status ) ) ;
2001-12-11 08:47:26 +03:00
goto done ;
}
2001-12-11 08:21:50 +03:00
2002-11-13 02:20:50 +03:00
make_nmb_name ( & calling , global_myname ( ) , 0x0 ) ;
2001-12-11 08:21:50 +03:00
if ( host ) {
make_nmb_name ( & called , host , 0x20 ) ;
} else {
make_nmb_name ( & called , " *SMBSERVER " , 0x20 ) ;
}
2001-12-11 08:47:26 +03:00
if ( ! cli_session_request ( cli , & calling , & called ) ) {
fprintf ( stderr , " Session request failed \n " ) ;
goto done ;
}
if ( ! cli_negprot ( cli ) ) {
fprintf ( stderr , " Protocol negotiation failed \n " ) ;
goto done ;
}
2001-12-11 08:21:50 +03:00
ret = cli - > servertime ;
2001-12-12 12:37:17 +03:00
if ( zone ) * zone = cli - > serverzone ;
2001-12-11 08:21:50 +03:00
done :
2006-07-11 22:01:26 +04:00
if ( cli ) {
cli_shutdown ( cli ) ;
}
2001-12-11 08:21:50 +03:00
return ret ;
}
/* find the servers time on the opt_host host */
2001-12-12 12:37:17 +03:00
static time_t nettime ( int * zone )
2001-12-11 08:21:50 +03:00
{
2001-12-12 12:37:17 +03:00
return cli_servertime ( opt_host , opt_have_ip ? & opt_dest_ip : NULL , zone ) ;
2001-12-11 08:21:50 +03:00
}
2001-12-14 04:15:14 +03:00
/* return a time as a string ready to be passed to /bin/date */
2006-06-15 01:36:49 +04:00
static const char * systime ( time_t t )
2001-12-11 08:21:50 +03:00
{
2003-07-23 16:33:59 +04:00
static fstring s ;
2001-12-11 08:21:50 +03:00
struct tm * tm ;
2001-12-14 04:15:14 +03:00
tm = localtime ( & t ) ;
2006-06-15 01:36:49 +04:00
if ( ! tm ) {
return " unknown " ;
}
2001-12-11 08:21:50 +03:00
2003-07-23 16:33:59 +04:00
fstr_sprintf ( s , " %02d%02d%02d%02d%04d.%02d " ,
2001-12-11 08:21:50 +03:00
tm - > tm_mon + 1 , tm - > tm_mday , tm - > tm_hour ,
tm - > tm_min , tm - > tm_year + 1900 , tm - > tm_sec ) ;
return s ;
}
int net_time_usage ( int argc , const char * * argv )
{
d_printf (
" net time \n \t displays time on a server \n \n " \
" net time system \n \t displays time on a server in a format ready for /bin/date \n \n " \
2001-12-14 04:15:14 +03:00
" net time set \n \t runs /bin/date with the time from the server \n \n " \
2001-12-12 12:37:17 +03:00
" net time zone \n \t displays the timezone in hours from GMT on the remote computer \n \n " \
2001-12-11 08:21:50 +03:00
" \n " ) ;
2002-03-15 23:03:07 +03:00
net_common_flags_usage ( argc , argv ) ;
2001-12-11 08:21:50 +03:00
return - 1 ;
}
/* try to set the system clock using /bin/date */
static int net_time_set ( int argc , const char * * argv )
{
2001-12-12 12:37:17 +03:00
time_t t = nettime ( NULL ) ;
2001-12-11 08:21:50 +03:00
char * cmd ;
2006-01-18 00:22:00 +03:00
int result ;
2001-12-11 08:21:50 +03:00
2001-12-11 08:47:26 +03:00
if ( t = = 0 ) return - 1 ;
2001-12-11 08:28:56 +03:00
/* yes, I know this is cheesy. Use "net time system" if you want to
roll your own . I ' m putting this in as it works on a large number
of systems and the user has a choice in whether its used or not */
2001-12-14 04:15:14 +03:00
asprintf ( & cmd , " /bin/date %s " , systime ( t ) ) ;
2006-01-18 00:22:00 +03:00
result = system ( cmd ) ;
if ( result )
d_fprintf ( stderr , " %s failed. Error was (%s) \n " ,
cmd , strerror ( errno ) ) ;
2001-12-11 08:21:50 +03:00
free ( cmd ) ;
2006-01-18 00:22:00 +03:00
return result ;
2001-12-11 08:21:50 +03:00
}
/* display the time on a remote box in a format ready for /bin/date */
static int net_time_system ( int argc , const char * * argv )
{
2001-12-12 12:37:17 +03:00
time_t t = nettime ( NULL ) ;
2001-12-11 08:21:50 +03:00
2001-12-11 08:47:26 +03:00
if ( t = = 0 ) return - 1 ;
2001-12-11 08:21:50 +03:00
printf ( " %s \n " , systime ( t ) ) ;
return 0 ;
}
2001-12-12 12:37:17 +03:00
/* display the time on a remote box in a format ready for /bin/date */
static int net_time_zone ( int argc , const char * * argv )
{
int zone = 0 ;
2002-01-05 02:02:14 +03:00
int hours , mins ;
char zsign ;
2001-12-12 12:37:17 +03:00
time_t t ;
t = nettime ( & zone ) ;
if ( t = = 0 ) return - 1 ;
2002-01-05 02:02:14 +03:00
zsign = ( zone > 0 ) ? ' - ' : ' + ' ;
if ( zone < 0 ) zone = - zone ;
2001-12-12 12:37:17 +03:00
zone / = 60 ;
2002-01-05 02:02:14 +03:00
hours = zone / 60 ;
mins = zone % 60 ;
2001-12-12 12:37:17 +03:00
2002-01-05 02:02:14 +03:00
printf ( " %c%02d%02d \n " , zsign , hours , mins ) ;
2001-12-12 12:37:17 +03:00
return 0 ;
}
2001-12-11 08:21:50 +03:00
/* display or set the time on a host */
int net_time ( int argc , const char * * argv )
{
time_t t ;
struct functable func [ ] = {
{ " SYSTEM " , net_time_system } ,
{ " SET " , net_time_set } ,
2001-12-12 12:37:17 +03:00
{ " ZONE " , net_time_zone } ,
2001-12-11 08:21:50 +03:00
{ NULL , NULL }
} ;
2002-07-15 14:35:28 +04:00
if ( ! opt_host & & ! opt_have_ip & &
! find_master_ip ( opt_target_workgroup , & opt_dest_ip ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Could not locate a time server. Try " \
2002-07-15 14:35:28 +04:00
" specifying a target host. \n " ) ;
2002-03-15 23:03:07 +03:00
net_time_usage ( argc , argv ) ;
2001-12-11 08:21:50 +03:00
return - 1 ;
}
if ( argc ! = 0 ) {
return net_run_function ( argc , argv , func , net_time_usage ) ;
}
/* default - print the time */
2001-12-12 12:37:17 +03:00
t = cli_servertime ( opt_host , opt_have_ip ? & opt_dest_ip : NULL , NULL ) ;
2001-12-11 08:47:26 +03:00
if ( t = = 0 ) return - 1 ;
2001-12-11 08:21:50 +03:00
d_printf ( " %s " , ctime ( & t ) ) ;
return 0 ;
}