1/* 2 Samba Unix/Linux SMB client library 3 net time command 4 Copyright (C) 2001 Andrew Tridgell (tridge@samba.org) 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ 19 20#include "includes.h" 21#include "utils/net.h" 22 23 24/* 25 return the time on a server. This does not require any authentication 26*/ 27static time_t cli_servertime(const char *host, struct in_addr *ip, int *zone) 28{ 29 struct nmb_name calling, called; 30 time_t ret = 0; 31 struct cli_state *cli = NULL; 32 33 cli = cli_initialise(); 34 if (!cli) { 35 goto done; 36 } 37 38 if (!cli_connect(cli, host, ip)) { 39 fprintf(stderr,"Can't contact server\n"); 40 goto done; 41 } 42 43 make_nmb_name(&calling, global_myname(), 0x0); 44 if (host) { 45 make_nmb_name(&called, host, 0x20); 46 } else { 47 make_nmb_name(&called, "*SMBSERVER", 0x20); 48 } 49 50 if (!cli_session_request(cli, &calling, &called)) { 51 fprintf(stderr,"Session request failed\n"); 52 goto done; 53 } 54 if (!cli_negprot(cli)) { 55 fprintf(stderr,"Protocol negotiation failed\n"); 56 goto done; 57 } 58 59 ret = cli->servertime; 60 if (zone) *zone = cli->serverzone; 61 62done: 63 if (cli) { 64 cli_shutdown(cli); 65 } 66 return ret; 67} 68 69/* find the servers time on the opt_host host */ 70static time_t nettime(int *zone) 71{ 72 return cli_servertime(opt_host, opt_have_ip? &opt_dest_ip : NULL, zone); 73} 74 75/* return a time as a string ready to be passed to /bin/date */ 76static const char *systime(time_t t) 77{ 78 static fstring s; 79 struct tm *tm; 80 81 tm = localtime(&t); 82 if (!tm) { 83 return "unknown"; 84 } 85 86 fstr_sprintf(s, "%02d%02d%02d%02d%04d.%02d", 87 tm->tm_mon+1, tm->tm_mday, tm->tm_hour, 88 tm->tm_min, tm->tm_year + 1900, tm->tm_sec); 89 return s; 90} 91 92int net_time_usage(int argc, const char **argv) 93{ 94 d_printf( 95"net time\n\tdisplays time on a server\n\n"\ 96"net time system\n\tdisplays time on a server in a format ready for /bin/date\n\n"\ 97"net time set\n\truns /bin/date with the time from the server\n\n"\ 98"net time zone\n\tdisplays the timezone in hours from GMT on the remote computer\n\n"\ 99"\n"); 100 net_common_flags_usage(argc, argv); 101 return -1; 102} 103 104/* try to set the system clock using /bin/date */ 105static int net_time_set(int argc, const char **argv) 106{ 107 time_t t = nettime(NULL); 108 char *cmd; 109 int result; 110 111 if (t == 0) return -1; 112 113 /* yes, I know this is cheesy. Use "net time system" if you want to 114 roll your own. I'm putting this in as it works on a large number 115 of systems and the user has a choice in whether its used or not */ 116 asprintf(&cmd, "/bin/date %s", systime(t)); 117 result = system(cmd); 118 if (result) 119 d_fprintf(stderr, "%s failed. Error was (%s)\n", 120 cmd, strerror(errno)); 121 free(cmd); 122 123 return result; 124} 125 126/* display the time on a remote box in a format ready for /bin/date */ 127static int net_time_system(int argc, const char **argv) 128{ 129 time_t t = nettime(NULL); 130 131 if (t == 0) return -1; 132 133 printf("%s\n", systime(t)); 134 135 return 0; 136} 137 138/* display the time on a remote box in a format ready for /bin/date */ 139static int net_time_zone(int argc, const char **argv) 140{ 141 int zone = 0; 142 int hours, mins; 143 char zsign; 144 time_t t; 145 146 t = nettime(&zone); 147 148 if (t == 0) return -1; 149 150 zsign = (zone > 0) ? '-' : '+'; 151 if (zone < 0) zone = -zone; 152 153 zone /= 60; 154 hours = zone / 60; 155 mins = zone % 60; 156 157 printf("%c%02d%02d\n", zsign, hours, mins); 158 159 return 0; 160} 161 162/* display or set the time on a host */ 163int net_time(int argc, const char **argv) 164{ 165 time_t t; 166 struct functable func[] = { 167 {"SYSTEM", net_time_system}, 168 {"SET", net_time_set}, 169 {"ZONE", net_time_zone}, 170 {NULL, NULL} 171 }; 172 173 if (!opt_host && !opt_have_ip && 174 !find_master_ip(opt_target_workgroup, &opt_dest_ip)) { 175 d_fprintf(stderr, "Could not locate a time server. Try "\ 176 "specifying a target host.\n"); 177 net_time_usage(argc,argv); 178 return -1; 179 } 180 181 if (argc != 0) { 182 return net_run_function(argc, argv, func, net_time_usage); 183 } 184 185 /* default - print the time */ 186 t = cli_servertime(opt_host, opt_have_ip? &opt_dest_ip : NULL, NULL); 187 if (t == 0) return -1; 188 189 d_printf("%s", ctime(&t)); 190 return 0; 191} 192