/* Unix SMB/Netbios implementation. Version 2.1. MSRPC client: scheduler service Copyright (C) Matthew Chapman 1999 Copyright (C) Luke Kenneth Casson Leighton 1996-1999 Copyright (C) Andrew Tridgell 1994-1999 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 the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifdef SYSLOG #undef SYSLOG #endif #include "includes.h" #include "nterr.h" extern int DEBUGLEVEL; #define DEBUG_TESTING extern struct cli_state *smb_cli; extern FILE* out_hnd; /**************************************************************************** checks for a /OPTION:param style option ****************************************************************************/ static BOOL checkopt(char *input, char *optname, char **params) { char *inend; if (*input++ != '/') return False; for (inend = input; *inend != 0 && *inend != ':'; inend++); if (params != NULL) { *inend = 0; *params = inend; } while(input < inend) { if (toupper(*input++) != *optname++) return False; } return True; } char *daynames[] = {"Mon","Tue","Wed","Thu","Fri","Sat","Sun"}; char *daynames_short[] = {"M", "T", "W", "Th", "F", "S", "Su"}; /**************************************************************************** parses a list of days of the week and month ****************************************************************************/ static BOOL at_parse_days(char *str, uint32 *monthdays, uint8 *weekdays) { char *tok; char *nexttok = str; int day; do { tok = nexttok; if ((nexttok = strchr(tok, ',')) != NULL) { *nexttok++ = 0; } if (isdigit((int)*tok)) { day = strtol(tok, NULL, 10); if (day == 0 || day > 31) { printf("\tInvalid day of month.\n\n"); return False; } *monthdays |= (1 << (day-1)); } else { if (strlen(tok) < 3) { for (day = 0; day < 7; day++) { if (!strcasecmp(tok, daynames_short[day])) break; } } else { for (day = 0; day < 7; day++) { if (!strncasecmp(tok, daynames[day], 3)) break; } } if (day < 7) { *weekdays |= (1 << day); } else { printf("\tInvalid day of week\n\n"); return False; } } } while (nexttok != NULL); 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 ****************************************************************************/ void cmd_at(struct client_info *info) { uint16 nt_pipe_fnum; fstring temp; fstring dest_wks; BOOL add = False; BOOL del = False; char *p; uint32 jobid = -1; unsigned int hours, minutes, seconds = 0; uint32 monthdays = 0; uint8 weekdays = 0; uint8 flags = JOB_NONINTERACTIVE; fstring command; while (next_token(NULL, temp, NULL, sizeof(temp))) { if (checkopt(temp, "DELETE", NULL)) { del = True; continue; } else if (checkopt(temp, "YES", NULL)) { /* Compatibility */ continue; } jobid = strtol(temp, &p, 10); if (*p == 0) /* Entirely numeric field */ continue; if (!strcasecmp(temp, "NOW")) { if (!at_soon(dest_wks, &hours, &minutes, &seconds)) { return; } } else if (sscanf(temp, "%d:%d:%d", &hours, &minutes, &seconds) > 2) { p = strchr(temp, 0); 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) { printf("\tInvalid time.\n\n"); return; } } else { printf("at { {time | NOW} [/INTERACTIVE] [{/EVERY|/NEXT}:5,Sun,...] command\n\t| [/DEL] [jobid] }\n\n"); return; } add = True; command[0] = 0; p = NULL; if (!next_token(NULL, temp, NULL, sizeof(temp))) break; if (checkopt(temp, "INTERACTIVE", NULL)) { flags &= ~JOB_NONINTERACTIVE; if (!next_token(NULL, temp, NULL, sizeof(temp))) break; } if (checkopt(temp, "EVERY", &p)) { flags |= JOB_PERIODIC; } else { checkopt(temp, "NEXT", &p); } if (p != NULL) { if (*p == ':') { if (!at_parse_days(p, &monthdays, &weekdays)) return; } else { weekdays = 0x7F; } if (!next_token(NULL, temp, NULL, sizeof(temp))) break; } while (True) { fstrcat(command, temp); if (!next_token(NULL, temp, NULL, sizeof(temp))) break; fstrcat(command, " "); } break; } if (add && !command[0]) { printf("\tNo command specified.\n\n"); return; } fstrcpy(dest_wks, "\\\\"); fstrcat(dest_wks, info->dest_host); strupper(dest_wks); /* open scheduler session. */ if (!cli_nt_session_open(smb_cli, PIPE_ATSVC, &nt_pipe_fnum)) return; if (add) /* add job */ { AT_JOB_INFO job; job.time = ((((hours * 60) + minutes) * 60) + seconds) * 1000; job.monthdays = monthdays; job.weekdays = weekdays; job.flags = flags; job.ptr_command = 1; display_at_job_info(out_hnd, ACTION_HEADER , &job, command); display_at_job_info(out_hnd, ACTION_ENUMERATE, &job, command); display_at_job_info(out_hnd, ACTION_FOOTER , &job, command); if (at_add_job(smb_cli, nt_pipe_fnum, dest_wks, &job, command, &jobid)) { fprintf(out_hnd, "\tJob ID: %d\n\n", jobid); } } else if (del) /* delete */ { if (jobid == -1) { fprintf(out_hnd, "\tDeleting all jobs.\n\n"); at_del_job(smb_cli, nt_pipe_fnum, dest_wks, 0, 0xffffffff); } else { fprintf(out_hnd, "\tDeleting job %d.\n\n", jobid); at_del_job(smb_cli, nt_pipe_fnum, dest_wks, jobid, jobid); } } else if (jobid == -1) /* enumerate */ { AT_ENUM_INFO jobs[AT_MAX_JOBS]; fstring commands[AT_MAX_JOBS]; uint32 num_jobs; if (at_enum_jobs(smb_cli, nt_pipe_fnum, dest_wks, &num_jobs, jobs, commands)) { display_at_enum_info(out_hnd, ACTION_HEADER , num_jobs, jobs, commands); display_at_enum_info(out_hnd, ACTION_ENUMERATE, num_jobs, jobs, commands); display_at_enum_info(out_hnd, ACTION_FOOTER , num_jobs, jobs, commands); } } else /* job info */ { AT_JOB_INFO job; if (at_query_job(smb_cli, nt_pipe_fnum, dest_wks, jobid, &job, command)) { display_at_job_info(out_hnd, ACTION_HEADER , &job, command); display_at_job_info(out_hnd, ACTION_ENUMERATE, &job, command); display_at_job_info(out_hnd, ACTION_FOOTER , &job, command); } } /* close the session */ cli_nt_session_close(smb_cli, nt_pipe_fnum); }