r23563: Add dump-event-list command to smbcontrol.
[sfrench/samba-autobuild/.git] / source / utils / net_time.c
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 */
27 static 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         NTSTATUS status;
33
34         cli = cli_initialise();
35         if (!cli) {
36                 goto done;
37         }
38
39         status = cli_connect(cli, host, ip);
40         if (!NT_STATUS_IS_OK(status)) {
41                 fprintf(stderr,"Can't contact server %s. Error %s\n", host, nt_errstr(status));
42                 goto done;
43         }
44
45         make_nmb_name(&calling, global_myname(), 0x0);
46         if (host) {
47                 make_nmb_name(&called, host, 0x20);
48         } else {
49                 make_nmb_name(&called, "*SMBSERVER", 0x20);
50         }
51
52         if (!cli_session_request(cli, &calling, &called)) {
53                 fprintf(stderr,"Session request failed\n");
54                 goto done;
55         }
56         if (!cli_negprot(cli)) {
57                 fprintf(stderr,"Protocol negotiation failed\n");
58                 goto done;
59         }
60
61         ret = cli->servertime;
62         if (zone) *zone = cli->serverzone;
63
64 done:
65         if (cli) {
66                 cli_shutdown(cli);
67         }
68         return ret;
69 }
70
71 /* find the servers time on the opt_host host */
72 static time_t nettime(int *zone)
73 {
74         return cli_servertime(opt_host, opt_have_ip? &opt_dest_ip : NULL, zone);
75 }
76
77 /* return a time as a string ready to be passed to /bin/date */
78 static const char *systime(time_t t)
79 {
80         static fstring s;
81         struct tm *tm;
82
83         tm = localtime(&t);
84         if (!tm) {
85                 return "unknown";
86         }
87         
88         fstr_sprintf(s, "%02d%02d%02d%02d%04d.%02d", 
89                  tm->tm_mon+1, tm->tm_mday, tm->tm_hour, 
90                  tm->tm_min, tm->tm_year + 1900, tm->tm_sec);
91         return s;
92 }
93
94 int net_time_usage(int argc, const char **argv)
95 {
96         d_printf(
97 "net time\n\tdisplays time on a server\n\n"\
98 "net time system\n\tdisplays time on a server in a format ready for /bin/date\n\n"\
99 "net time set\n\truns /bin/date with the time from the server\n\n"\
100 "net time zone\n\tdisplays the timezone in hours from GMT on the remote computer\n\n"\
101 "\n");
102         net_common_flags_usage(argc, argv);
103         return -1;
104 }
105
106 /* try to set the system clock using /bin/date */
107 static int net_time_set(int argc, const char **argv)
108 {
109         time_t t = nettime(NULL);
110         char *cmd;
111         int result;
112
113         if (t == 0) return -1;
114         
115         /* yes, I know this is cheesy. Use "net time system" if you want to 
116            roll your own. I'm putting this in as it works on a large number
117            of systems and the user has a choice in whether its used or not */
118         asprintf(&cmd, "/bin/date %s", systime(t));
119         result = system(cmd);
120         if (result)
121                 d_fprintf(stderr, "%s failed.  Error was (%s)\n",
122                         cmd, strerror(errno));
123         free(cmd);
124
125         return result;
126 }
127
128 /* display the time on a remote box in a format ready for /bin/date */
129 static int net_time_system(int argc, const char **argv)
130 {
131         time_t t = nettime(NULL);
132
133         if (t == 0) return -1;
134
135         printf("%s\n", systime(t));
136
137         return 0;
138 }
139
140 /* display the time on a remote box in a format ready for /bin/date */
141 static int net_time_zone(int argc, const char **argv)
142 {
143         int zone = 0;
144         int hours, mins;
145         char zsign;
146         time_t t;
147
148         t = nettime(&zone);
149
150         if (t == 0) return -1;
151
152         zsign = (zone > 0) ? '-' : '+';
153         if (zone < 0) zone = -zone;
154
155         zone /= 60;
156         hours = zone / 60;
157         mins = zone % 60;
158
159         printf("%c%02d%02d\n", zsign, hours, mins);
160
161         return 0;
162 }
163
164 /* display or set the time on a host */
165 int net_time(int argc, const char **argv)
166 {
167         time_t t;
168         struct functable func[] = {
169                 {"SYSTEM", net_time_system},
170                 {"SET", net_time_set},
171                 {"ZONE", net_time_zone},
172                 {NULL, NULL}
173         };
174
175         if (!opt_host && !opt_have_ip && 
176             !find_master_ip(opt_target_workgroup, &opt_dest_ip)) {
177                 d_fprintf(stderr, "Could not locate a time server.  Try "\
178                                  "specifying a target host.\n");
179                 net_time_usage(argc,argv);
180                 return -1;
181         }
182
183         if (argc != 0) {
184                 return net_run_function(argc, argv, func, net_time_usage);
185         }
186
187         /* default - print the time */
188         t = cli_servertime(opt_host, opt_have_ip? &opt_dest_ip : NULL, NULL);
189         if (t == 0) return -1;
190
191         d_printf("%s", ctime(&t));
192         return 0;
193 }