2008-05-08 13:23:38 +04:00
/*
Samba Unix / Linux SMB client library
2001-12-11 08:21:50 +03:00
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 .
2008-05-08 13:23:38 +04:00
2001-12-11 08:21:50 +03:00
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 .
2008-05-08 13:23:38 +04:00
2001-12-11 08:21:50 +03:00
You should have received a copy of the GNU General Public License
2008-05-10 01:22:12 +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
*/
2007-10-25 01:16:54 +04:00
static time_t cli_servertime ( const char * host , struct sockaddr_storage * pss , 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-10-25 01:16:54 +04:00
status = cli_connect ( cli , host , pss ) ;
2007-06-20 21:38:42 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-11 10:38:42 +04:00
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 ) ) {
2009-08-11 10:38:42 +04:00
fprintf ( stderr , _ ( " Session request failed \n " ) ) ;
2001-12-11 08:47:26 +03:00
goto done ;
}
2008-09-11 20:57:49 +04:00
status = cli_negprot ( cli ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-08-11 10:38:42 +04:00
fprintf ( stderr , _ ( " Protocol negotiation failed: %s \n " ) ,
2008-09-11 20:57:49 +04:00
nt_errstr ( status ) ) ;
2001-12-11 08:47:26 +03:00
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 */
2008-05-10 01:22:12 +04:00
static time_t nettime ( struct net_context * c , int * zone )
2001-12-11 08:21:50 +03:00
{
2008-05-10 01:22:12 +04:00
return cli_servertime ( c - > opt_host ,
c - > opt_have_ip ? & c - > 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
{
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 " ;
}
2007-10-25 01:16:54 +04:00
2009-07-25 20:57:46 +04:00
return talloc_asprintf ( talloc_tos ( ) , " %02d%02d%02d%02d%04d.%02d " ,
tm - > tm_mon + 1 , tm - > tm_mday , tm - > tm_hour ,
tm - > tm_min , tm - > tm_year + 1900 , tm - > tm_sec ) ;
2001-12-11 08:21:50 +03:00
}
2008-05-10 01:22:12 +04:00
int net_time_usage ( struct net_context * c , int argc , const char * * argv )
2001-12-11 08:21:50 +03:00
{
2009-08-11 10:38:42 +04:00
d_printf ( _ (
2008-05-19 18:19:37 +04:00
" 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 "
" net time set \n \t runs /bin/date with the time from the server \n \n "
" net time zone \n \t displays the timezone in hours from GMT on the remote computer \n \n "
2009-08-11 10:38:42 +04:00
" \n " ) ) ;
2008-05-10 01:22:12 +04:00
net_common_flags_usage ( c , argc , argv ) ;
2001-12-11 08:21:50 +03:00
return - 1 ;
}
/* try to set the system clock using /bin/date */
2008-05-10 01:22:12 +04:00
static int net_time_set ( struct net_context * c , int argc , const char * * argv )
2001-12-11 08:21:50 +03:00
{
2008-05-10 01:22:12 +04:00
time_t t = nettime ( c , 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 ;
2007-10-25 01:16:54 +04:00
/* yes, I know this is cheesy. Use "net time system" if you want to
2001-12-11 08:28:56 +03:00
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 */
2009-01-01 05:06:57 +03:00
if ( asprintf ( & cmd , " /bin/date %s " , systime ( t ) ) = = - 1 ) {
return - 1 ;
}
2006-01-18 00:22:00 +03:00
result = system ( cmd ) ;
if ( result )
2009-08-11 10:38:42 +04:00
d_fprintf ( stderr , _ ( " %s failed. Error was (%s) \n " ) ,
2006-01-18 00:22:00 +03:00
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 */
2008-05-10 01:22:12 +04:00
static int net_time_system ( struct net_context * c , int argc , const char * * argv )
2001-12-11 08:21:50 +03:00
{
2008-05-19 18:19:37 +04:00
time_t t ;
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2009-08-11 10:38:42 +04:00
" net time system \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Output remote time server time in a format "
" ready for /bin/date " ) ) ;
2008-05-19 18:19:37 +04:00
return 0 ;
}
2001-12-11 08:21:50 +03:00
2008-05-19 18:19:37 +04:00
t = nettime ( c , NULL ) ;
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 ;
}
2008-06-06 00:14:38 +04:00
/* display the remote time server's offset to UTC */
2008-05-10 01:22:12 +04:00
static int net_time_zone ( struct net_context * c , int argc , const char * * argv )
2001-12-12 12:37:17 +03:00
{
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 ;
2008-05-19 18:19:37 +04:00
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2009-08-11 10:38:42 +04:00
" net time zone \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Display the remote time server's offset to "
" UTC " ) ) ;
2008-05-19 18:19:37 +04:00
return 0 ;
}
2008-05-10 01:22:12 +04:00
t = nettime ( c , & zone ) ;
2001-12-12 12:37:17 +03:00
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 */
2008-05-10 01:22:12 +04:00
int net_time ( struct net_context * c , int argc , const char * * argv )
2001-12-11 08:21:50 +03:00
{
time_t t ;
2008-06-07 04:25:08 +04:00
struct functable func [ ] = {
2008-05-19 18:19:37 +04:00
{
" system " ,
net_time_system ,
NET_TRANSPORT_LOCAL ,
2009-08-11 10:38:42 +04:00
N_ ( " Display time ready for /bin/date " ) ,
N_ ( " net time system \n "
" Display time ready for /bin/date " )
2008-05-19 18:19:37 +04:00
} ,
{
" set " ,
net_time_set ,
NET_TRANSPORT_LOCAL ,
2009-08-11 10:38:42 +04:00
N_ ( " Set the system time from time server " ) ,
N_ ( " net time set \n "
" Set the system time from time server " )
2008-05-19 18:19:37 +04:00
} ,
{
" zone " ,
net_time_zone ,
NET_TRANSPORT_LOCAL ,
2009-08-11 10:38:42 +04:00
N_ ( " Display timezone offset from UTC " ) ,
N_ ( " net time zone \n "
" Display timezone offset from UTC " )
2008-05-19 18:19:37 +04:00
} ,
{ NULL , NULL , 0 , NULL , NULL }
2001-12-11 08:21:50 +03:00
} ;
2008-05-19 02:33:02 +04:00
if ( argc ! = 0 ) {
2008-06-07 04:25:08 +04:00
return net_run_function ( c , argc , argv , " net time " , func ) ;
2008-05-19 18:19:37 +04:00
}
if ( c - > display_usage ) {
2010-01-19 13:43:54 +03:00
d_printf ( " %s \n "
2009-08-11 10:38:42 +04:00
" net time \n "
2010-01-19 13:43:54 +03:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Display the remote time server's time " ) ) ;
2008-05-19 18:19:37 +04:00
net_display_usage_from_functable ( func ) ;
return 0 ;
2008-05-19 02:33:02 +04:00
}
2008-05-10 01:22:12 +04:00
if ( ! c - > opt_host & & ! c - > opt_have_ip & &
! find_master_ip ( c - > opt_target_workgroup , & c - > opt_dest_ip ) ) {
2009-08-11 10:38:42 +04:00
d_fprintf ( stderr , _ ( " Could not locate a time server. Try "
" specifying a target host. \n " ) ) ;
2008-05-10 01:22:12 +04:00
net_time_usage ( c , argc , argv ) ;
2001-12-11 08:21:50 +03:00
return - 1 ;
}
/* default - print the time */
2008-05-10 01:22:12 +04:00
t = cli_servertime ( c - > opt_host , c - > opt_have_ip ? & c - > 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 ;
}