root/source3/utils/net_time.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cli_servertime
  2. nettime
  3. systime
  4. net_time_usage
  5. net_time_set
  6. net_time_system
  7. net_time_zone
  8. net_time

   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 3 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, see <http://www.gnu.org/licenses/>.
  18 */
  19 #include "includes.h"
  20 #include "utils/net.h"
  21 
  22 /*
  23   return the time on a server. This does not require any authentication
  24 */
  25 static time_t cli_servertime(const char *host, struct sockaddr_storage *pss, int *zone)
     /* [<][>][^][v][top][bottom][index][help] */
  26 {
  27         struct nmb_name calling, called;
  28         time_t ret = 0;
  29         struct cli_state *cli = NULL;
  30         NTSTATUS status;
  31 
  32         cli = cli_initialise();
  33         if (!cli) {
  34                 goto done;
  35         }
  36 
  37         status = cli_connect(cli, host, pss);
  38         if (!NT_STATUS_IS_OK(status)) {
  39                 fprintf(stderr,"Can't contact server %s. Error %s\n", host, nt_errstr(status));
  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         status = cli_negprot(cli);
  55         if (!NT_STATUS_IS_OK(status)) {
  56                 fprintf(stderr, "Protocol negotiation failed: %s\n",
  57                         nt_errstr(status));
  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(struct net_context *c, int *zone)
     /* [<][>][^][v][top][bottom][index][help] */
  73 {
  74         return cli_servertime(c->opt_host,
  75                               c->opt_have_ip? &c->opt_dest_ip : NULL, zone);
  76 }
  77 
  78 /* return a time as a string ready to be passed to /bin/date */
  79 static const char *systime(time_t t)
     /* [<][>][^][v][top][bottom][index][help] */
  80 {
  81         static fstring s;
  82         struct tm *tm;
  83 
  84         tm = localtime(&t);
  85         if (!tm) {
  86                 return "unknown";
  87         }
  88 
  89         fstr_sprintf(s, "%02d%02d%02d%02d%04d.%02d",
  90                  tm->tm_mon+1, tm->tm_mday, tm->tm_hour,
  91                  tm->tm_min, tm->tm_year + 1900, tm->tm_sec);
  92         return s;
  93 }
  94 
  95 int net_time_usage(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
  96 {
  97         d_printf(
  98 "net time\n\tdisplays time on a server\n\n"
  99 "net time system\n\tdisplays time on a server in a format ready for /bin/date\n\n"
 100 "net time set\n\truns /bin/date with the time from the server\n\n"
 101 "net time zone\n\tdisplays the timezone in hours from GMT on the remote computer\n\n"
 102 "\n");
 103         net_common_flags_usage(c, argc, argv);
 104         return -1;
 105 }
 106 
 107 /* try to set the system clock using /bin/date */
 108 static int net_time_set(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 109 {
 110         time_t t = nettime(c, NULL);
 111         char *cmd;
 112         int result;
 113 
 114         if (t == 0) return -1;
 115 
 116         /* yes, I know this is cheesy. Use "net time system" if you want to
 117            roll your own. I'm putting this in as it works on a large number
 118            of systems and the user has a choice in whether its used or not */
 119         if (asprintf(&cmd, "/bin/date %s", systime(t)) == -1) {
 120                 return -1;
 121         }
 122         result = system(cmd);
 123         if (result)
 124                 d_fprintf(stderr, "%s failed.  Error was (%s)\n",
 125                         cmd, strerror(errno));
 126         free(cmd);
 127 
 128         return result;
 129 }
 130 
 131 /* display the time on a remote box in a format ready for /bin/date */
 132 static int net_time_system(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 133 {
 134         time_t t;
 135 
 136         if (c->display_usage) {
 137                 d_printf("Usage:\n"
 138                          "net time system\n"
 139                          "    Output remote time server time in a format ready "
 140                          "for /bin/date\n");
 141                 return 0;
 142         }
 143 
 144         t = nettime(c, NULL);
 145         if (t == 0) return -1;
 146 
 147         printf("%s\n", systime(t));
 148 
 149         return 0;
 150 }
 151 
 152 /* display the remote time server's offset to UTC */
 153 static int net_time_zone(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 154 {
 155         int zone = 0;
 156         int hours, mins;
 157         char zsign;
 158         time_t t;
 159 
 160         if (c->display_usage) {
 161                 d_printf("Usage:\n"
 162                          "net time zone\n"
 163                          "   Display the remote time server's offset to UTC\n");
 164                 return 0;
 165         }
 166 
 167         t = nettime(c, &zone);
 168 
 169         if (t == 0) return -1;
 170 
 171         zsign = (zone > 0) ? '-' : '+';
 172         if (zone < 0) zone = -zone;
 173 
 174         zone /= 60;
 175         hours = zone / 60;
 176         mins = zone % 60;
 177 
 178         printf("%c%02d%02d\n", zsign, hours, mins);
 179 
 180         return 0;
 181 }
 182 
 183 /* display or set the time on a host */
 184 int net_time(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 185 {
 186         time_t t;
 187         struct functable func[] = {
 188                 {
 189                         "system",
 190                         net_time_system,
 191                         NET_TRANSPORT_LOCAL,
 192                         "Display time ready for /bin/date",
 193                         "net time system\n"
 194                         "    Display time ready for /bin/date"
 195                 },
 196                 {
 197                         "set",
 198                         net_time_set,
 199                         NET_TRANSPORT_LOCAL,
 200                         "Set the system time from time server",
 201                         "net time set\n"
 202                         "    Set the system time from time server"
 203                 },
 204                 {
 205                         "zone",
 206                         net_time_zone,
 207                         NET_TRANSPORT_LOCAL,
 208                         "Display timezone offset from UTC",
 209                         "net time zone\n"
 210                         "    Display timezone offset from UTC"
 211                 },
 212                 {NULL, NULL, 0, NULL, NULL}
 213         };
 214 
 215         if (argc != 0) {
 216                 return net_run_function(c, argc, argv, "net time", func);
 217         }
 218 
 219         if (c->display_usage) {
 220                 d_printf("Usage:\n");
 221                 d_printf("net time\n"
 222                          "    Display the remote time server's time\n");
 223                 net_display_usage_from_functable(func);
 224                 return 0;
 225         }
 226 
 227         if (!c->opt_host && !c->opt_have_ip &&
 228             !find_master_ip(c->opt_target_workgroup, &c->opt_dest_ip)) {
 229                 d_fprintf(stderr, "Could not locate a time server.  Try "
 230                                  "specifying a target host.\n");
 231                 net_time_usage(c, argc,argv);
 232                 return -1;
 233         }
 234 
 235         /* default - print the time */
 236         t = cli_servertime(c->opt_host, c->opt_have_ip? &c->opt_dest_ip : NULL,
 237                            NULL);
 238         if (t == 0) return -1;
 239 
 240         d_printf("%s", ctime(&t));
 241         return 0;
 242 }

/* [<][>][^][v][top][bottom][index][help] */