From e3a888d5a935047367e531321981cbed8618c5a3 Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Sat, 1 May 1999 05:56:55 +0000 Subject: Adding "time" rpcclient command which displays the remote time. Also added special "now" time to the "at" command, e.g.: at now /i cmd ; pops up a command prompt (This used to be commit f456dcf08ec96c631f5e6f2e857115d4bbf94d1b) --- source3/include/proto.h | 4 +++ source3/rpc_client/cli_srvsvc.c | 56 ++++++++++++++++++++++++++++++ source3/rpc_parse/parse_srv.c | 11 ++++++ source3/rpcclient/cmd_atsvc.c | 75 +++++++++++++++++++++++++++++++---------- source3/rpcclient/cmd_srvsvc.c | 41 ++++++++++++++++++++++ source3/rpcclient/display.c | 4 +-- source3/rpcclient/rpcclient.c | 1 + 7 files changed, 172 insertions(+), 20 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 577215913f..13e75421c3 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1914,6 +1914,8 @@ BOOL do_srv_net_srv_file_enum(struct cli_state *cli, uint16 fnum, ENUM_HND *hnd); BOOL do_srv_net_srv_get_info(struct cli_state *cli, uint16 fnum, char *server_name, uint32 switch_value, SRV_INFO_CTR *ctr); +BOOL do_srv_net_remote_tod(struct cli_state *cli, uint16 fnum, + char *server_name, TIME_OF_DAY_INFO *tod); /*The following definitions come from rpc_client/cli_svcctl.c */ @@ -2856,6 +2858,7 @@ void srv_io_q_net_srv_get_info(char *desc, SRV_Q_NET_SRV_GET_INFO *q_n, prs_str void make_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv, uint32 switch_value, SRV_INFO_CTR *ctr, uint32 status); void srv_io_r_net_srv_get_info(char *desc, SRV_R_NET_SRV_GET_INFO *r_n, prs_struct *ps, int depth); +void make_srv_q_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_t, char *server_name); void srv_io_q_net_remote_tod(char *desc, SRV_Q_NET_REMOTE_TOD *q_n, prs_struct *ps, int depth); void make_time_of_day_info(TIME_OF_DAY_INFO *tod, uint32 elapsedt, uint32 msecs, uint32 hours, uint32 mins, uint32 secs, uint32 hunds, @@ -3076,6 +3079,7 @@ void cmd_srv_enum_conn(struct client_info *info); void cmd_srv_enum_shares(struct client_info *info); void cmd_srv_enum_sess(struct client_info *info); void cmd_srv_enum_files(struct client_info *info); +void cmd_time(struct client_info *info); /*The following definitions come from rpcclient/cmd_svcctl.c */ diff --git a/source3/rpc_client/cli_srvsvc.c b/source3/rpc_client/cli_srvsvc.c index 86862c7a2a..70aee4e1c8 100644 --- a/source3/rpc_client/cli_srvsvc.c +++ b/source3/rpc_client/cli_srvsvc.c @@ -409,3 +409,59 @@ BOOL do_srv_net_srv_get_info(struct cli_state *cli, uint16 fnum, return valid_info; } +/**************************************************************************** +get server time +****************************************************************************/ +BOOL do_srv_net_remote_tod(struct cli_state *cli, uint16 fnum, + char *server_name, TIME_OF_DAY_INFO *tod) +{ + prs_struct data; + prs_struct rdata; + SRV_Q_NET_REMOTE_TOD q_t; + BOOL valid_info = False; + + if (server_name == NULL || tod == NULL) return False; + + prs_init(&data , 1024, 4, SAFETY_MARGIN, False); + prs_init(&rdata, 0 , 4, SAFETY_MARGIN, True ); + + /* create and send a MSRPC command with api SRV_NET_REMOTE_TOD */ + + DEBUG(4,("SRV Remote TOD (%s)\n", server_name)); + + /* store the parameters */ + make_srv_q_net_remote_tod(&q_t, server_name); + + /* turn parameters into data stream */ + srv_io_q_net_remote_tod("", &q_t, &data, 0); + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, fnum, SRV_NET_REMOTE_TOD, &data, &rdata)) + { + SRV_R_NET_REMOTE_TOD r_t; + BOOL p; + + r_t.tod = tod; + + srv_io_r_net_remote_tod("", &r_t, &rdata, 0); + p = rdata.offset != 0; + p = rdata.offset != 0; + + if (p && r_t.status != 0) + { + /* report error code */ + DEBUG(0,("SRV_R_NET_REMOTE_TOD: %s\n", get_nt_error_msg(r_t.status))); + p = False; + } + + if (p) + { + valid_info = True; + } + } + + prs_mem_free(&data ); + prs_mem_free(&rdata ); + + return valid_info; +} diff --git a/source3/rpc_parse/parse_srv.c b/source3/rpc_parse/parse_srv.c index 56b8be2acb..1bcc961853 100644 --- a/source3/rpc_parse/parse_srv.c +++ b/source3/rpc_parse/parse_srv.c @@ -1459,6 +1459,17 @@ void srv_io_r_net_srv_get_info(char *desc, SRV_R_NET_SRV_GET_INFO *r_n, prs_str prs_uint32("status ", ps, depth, &(r_n->status )); } +/******************************************************************* + makes a SRV_Q_NET_REMOTE_TOD structure. + ********************************************************************/ +void make_srv_q_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_t, char *server_name) +{ + if (q_t == NULL) return; + + DEBUG(5,("make_srv_q_net_remote_tod\n")); + + make_buf_unistr2(&(q_t->uni_srv_name), &(q_t->ptr_srv_name), server_name); +} /******************************************************************* reads or writes a structure. diff --git a/source3/rpcclient/cmd_atsvc.c b/source3/rpcclient/cmd_atsvc.c index a7b771e48e..7e9f05fb6f 100644 --- a/source3/rpcclient/cmd_atsvc.c +++ b/source3/rpcclient/cmd_atsvc.c @@ -43,7 +43,6 @@ checks for a /OPTION:param style option static BOOL checkopt(char *input, char *optname, char **params) { char *inend; - int i, len; if (*input++ != '/') return False; @@ -85,7 +84,7 @@ static BOOL at_parse_days(char *str, uint32 *monthdays, uint8 *weekdays) *nexttok++ = 0; } - if (isdigit(*tok)) + if (isdigit((int)*tok)) { day = strtol(tok, NULL, 10); if (day == 0 || day > 31) @@ -131,6 +130,38 @@ static BOOL at_parse_days(char *str, uint32 *monthdays, uint8 *weekdays) return True; } +#define SOON_OFFSET 2 /* seconds */ + +/**************************************************************************** +schedule the job 'soon' +****************************************************************************/ +static BOOL at_soon(char *dest_srv, uint32 *hours, uint32 *minutes, uint32 *seconds) +{ + uint16 nt_pipe_fnum; + TIME_OF_DAY_INFO tod; + BOOL res = True; + + /* open srvsvc session. */ + res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC, &nt_pipe_fnum) : False; + + /* enumerate files on server */ + res = res ? do_srv_net_remote_tod(smb_cli, nt_pipe_fnum, + dest_srv, &tod) : False; + + /* Close the session */ + cli_nt_session_close(smb_cli, nt_pipe_fnum); + + if (res) + { + *hours = (tod.hours - ((int)tod.zone/60)) % 24; + *minutes = tod.mins; + *seconds = (tod.secs + SOON_OFFSET) % 60; + return True; + } + + return False; +} + /**************************************************************************** scheduler add job @@ -168,28 +199,36 @@ void cmd_at(struct client_info *info) if (*p == 0) /* Entirely numeric field */ continue; - if ((p == temp) || (sscanf(temp, "%d:%d:%d", - &hours, &minutes, &seconds) < 2)) + if (!strcasecmp(temp, "NOW")) { - printf("at { time [/INTERACTIVE] [{/EVERY|/NEXT}:5,Sun,...] command | [/DEL] [jobid] }\n\n"); - return; + if (!at_soon(dest_wks, &hours, &minutes, &seconds)) + { + return; + } } - - p = strchr(temp, 0); - - if (!strcasecmp(p-2, "AM")) + else if (sscanf(temp, "%d:%d:%d", &hours, &minutes, &seconds) > 2) { - hours = (hours == 12) ? 0 : hours; - } + p = strchr(temp, 0); - if (!strcasecmp(p-2, "PM")) - { - hours = (hours == 12) ? 12 : hours + 12; - } + if (!strcasecmp(p-2, "AM")) + { + hours = (hours == 12) ? 0 : hours; + } + + if (!strcasecmp(p-2, "PM")) + { + hours = (hours == 12) ? 12 : hours + 12; + } - if (hours > 23 || minutes > 59 || seconds > 59) + if (hours > 23 || minutes > 59 || seconds > 59) + { + printf("\tInvalid time.\n\n"); + return; + } + } + else { - printf("\tInvalid time.\n\n"); + printf("at { {time | NOW} [/INTERACTIVE] [{/EVERY|/NEXT}:5,Sun,...] command\n\t| [/DEL] [jobid] }\n\n"); return; } diff --git a/source3/rpcclient/cmd_srvsvc.c b/source3/rpcclient/cmd_srvsvc.c index 1be35608ee..2cb741b966 100644 --- a/source3/rpcclient/cmd_srvsvc.c +++ b/source3/rpcclient/cmd_srvsvc.c @@ -331,3 +331,44 @@ void cmd_srv_enum_files(struct client_info *info) } } +/**************************************************************************** +display remote time +****************************************************************************/ +void cmd_time(struct client_info *info) +{ + uint16 nt_pipe_fnum; + fstring dest_srv; + TIME_OF_DAY_INFO tod; + BOOL res = True; + + fstrcpy(dest_srv, "\\\\"); + fstrcat(dest_srv, info->dest_host); + strupper(dest_srv); + + DEBUG(4,("cmd_time: server:%s\n", dest_srv)); + + /* open srvsvc session. */ + res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC, &nt_pipe_fnum) : False; + + /* enumerate files on server */ + res = res ? do_srv_net_remote_tod(smb_cli, nt_pipe_fnum, + dest_srv, &tod) : False; + + if (res) + { + fprintf(out_hnd, "\tRemote Time:\t%s\n\n", + http_timestring(tod.elapsedt)); + } + + /* Close the session */ + cli_nt_session_close(smb_cli, nt_pipe_fnum); + + if (res) + { + DEBUG(5,("cmd_srv_enum_files: query succeeded\n")); + } + else + { + DEBUG(5,("cmd_srv_enum_files: query failed\n")); + } +} diff --git a/source3/rpcclient/display.c b/source3/rpcclient/display.c index e5c65fdec8..963b5b6249 100644 --- a/source3/rpcclient/display.c +++ b/source3/rpcclient/display.c @@ -1662,12 +1662,12 @@ void display_svc_info(FILE *out_hnd, enum action_type action, ENUM_SRVC_STATUS * } } -static char *get_at_time_str(uint32 time) +static char *get_at_time_str(uint32 t) { static fstring timestr; unsigned int hours, minutes, seconds; - hours = time / 1000; + hours = t / 1000; seconds = hours % 60; hours /= 60; minutes = hours % 60; diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 20cc3ad49b..255ec4c936 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -107,6 +107,7 @@ struct { {"svcenum", cmd_svc_enum, "[-i] Lists Services Manager"}, {"at", cmd_at, "Scheduler control (at /? for syntax)"}, + {"time", cmd_time, "Display remote time"}, {"regenum", cmd_reg_enum, " Registry Enumeration (keys, values)"}, {"regdeletekey",cmd_reg_delete_key, " Registry Key Delete"}, {"regcreatekey",cmd_reg_create_key, " [keyclass] Registry Key Create"}, -- cgit