1 /* 2 * PROJECT: ReactOS AT utility 3 * COPYRIGHT: See COPYING in the top level directory 4 * FILE: base/applications/cmdutils/at/at.c 5 * PURPOSE: ReactOS AT utility 6 * PROGRAMMERS: Eric Kohl <eric.kohl@reactos.org> 7 */ 8 9 #include <stdlib.h> 10 #include <stdio.h> 11 12 #include <windef.h> 13 #include <winbase.h> 14 #include <winuser.h> 15 #include <wincon.h> 16 #include <winnls.h> 17 #include <lm.h> 18 19 #include <conutils.h> 20 21 #include "resource.h" 22 23 24 PWSTR pszDaysOfWeekArray[7] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; 25 26 27 static 28 VOID 29 FreeDaysOfWeekArray(VOID) 30 { 31 INT i; 32 33 for (i = 0; i < 7; i++) 34 { 35 if (pszDaysOfWeekArray[i] != NULL) 36 HeapFree(GetProcessHeap(), 0, pszDaysOfWeekArray[i]); 37 } 38 } 39 40 41 static 42 BOOL 43 InitDaysOfWeekArray(VOID) 44 { 45 INT i, nLength; 46 47 for (i = 0; i < 7; i++) 48 { 49 nLength = GetLocaleInfo(LOCALE_USER_DEFAULT, 50 LOCALE_SABBREVDAYNAME1 + i, 51 NULL, 52 0); 53 54 pszDaysOfWeekArray[i] = HeapAlloc(GetProcessHeap(), 55 HEAP_ZERO_MEMORY, 56 nLength * sizeof(WCHAR)); 57 if (pszDaysOfWeekArray[i] == NULL) 58 { 59 FreeDaysOfWeekArray(); 60 return FALSE; 61 } 62 63 GetLocaleInfo(LOCALE_USER_DEFAULT, 64 LOCALE_SABBREVDAYNAME1 + i, 65 pszDaysOfWeekArray[i], 66 nLength); 67 } 68 69 return TRUE; 70 } 71 72 73 static 74 BOOL 75 ParseTime( 76 PWSTR pszTime, 77 PULONG pulJobHour, 78 PULONG pulJobMinute) 79 { 80 WCHAR szHour[3], szMinute[3], szAmPm[5]; 81 PWSTR startPtr, endPtr; 82 ULONG ulHour = 0, ulMinute = 0; 83 INT nLength; 84 85 if (pszTime == NULL) 86 return FALSE; 87 88 startPtr = pszTime; 89 90 /* Extract the hour string */ 91 nLength = 0; 92 while (*startPtr != L'\0' && iswdigit(*startPtr)) 93 { 94 if (nLength >= 2) 95 return FALSE; 96 97 szHour[nLength] = *startPtr; 98 nLength++; 99 100 startPtr++; 101 } 102 szHour[nLength] = L'\0'; 103 104 /* Check for a valid time separator */ 105 if (*startPtr != L':') 106 return FALSE; 107 108 /* Skip the time separator */ 109 startPtr++; 110 111 /* Extract the minute string */ 112 nLength = 0; 113 while (*startPtr != L'\0' && iswdigit(*startPtr)) 114 { 115 if (nLength >= 2) 116 return FALSE; 117 118 szMinute[nLength] = *startPtr; 119 nLength++; 120 121 startPtr++; 122 } 123 szMinute[nLength] = L'\0'; 124 125 /* Extract the optional AM/PM indicator string */ 126 nLength = 0; 127 while (*startPtr != L'\0') 128 { 129 if (nLength >= 4) 130 return FALSE; 131 132 if (!iswspace(*startPtr)) 133 { 134 szAmPm[nLength] = *startPtr; 135 nLength++; 136 } 137 138 startPtr++; 139 } 140 szAmPm[nLength] = L'\0'; 141 142 /* Convert the hour string */ 143 ulHour = wcstoul(szHour, &endPtr, 10); 144 if (ulHour == 0 && *endPtr != UNICODE_NULL) 145 return FALSE; 146 147 /* Convert the minute string */ 148 ulMinute = wcstoul(szMinute, &endPtr, 10); 149 if (ulMinute == 0 && *endPtr != UNICODE_NULL) 150 return FALSE; 151 152 /* Check for valid AM/PM indicator */ 153 if (wcslen(szAmPm) > 0 && 154 _wcsicmp(szAmPm, L"a") != 0 && 155 _wcsicmp(szAmPm, L"am") != 0 && 156 _wcsicmp(szAmPm, L"p") != 0 && 157 _wcsicmp(szAmPm, L"pm") != 0) 158 return FALSE; 159 160 /* Check for the valid minute range [0-59] */ 161 if (ulMinute > 59) 162 return FALSE; 163 164 if (wcslen(szAmPm) > 0) 165 { 166 /* 12 hour time format */ 167 168 /* Check for the valid hour range [1-12] */ 169 if (ulHour == 0 || ulHour > 12) 170 return FALSE; 171 172 /* Convert 12 hour format to 24 hour format */ 173 if (_wcsicmp(szAmPm, L"a") == 0 || 174 _wcsicmp(szAmPm, L"am") == 0) 175 { 176 if (ulHour == 12) 177 ulHour = 0; 178 } 179 else 180 { 181 if (ulHour >= 1 && ulHour <= 11) 182 ulHour += 12; 183 } 184 } 185 else 186 { 187 /* 24 hour time format */ 188 189 /* Check for the valid hour range [0-23] */ 190 if (ulHour > 23) 191 return FALSE; 192 } 193 194 if (pulJobHour != NULL) 195 *pulJobHour = ulHour; 196 197 if (pulJobMinute != NULL) 198 *pulJobMinute = ulMinute; 199 200 return TRUE; 201 } 202 203 204 static 205 BOOL 206 ParseId( 207 PWSTR pszId, 208 PULONG pulId) 209 { 210 PWSTR startPtr, endPtr; 211 ULONG ulId = 0; 212 BOOL bResult = FALSE; 213 214 startPtr = pszId; 215 endPtr = NULL; 216 ulId = wcstoul(startPtr, &endPtr, 10); 217 if (endPtr != NULL && *endPtr == UNICODE_NULL) 218 { 219 bResult = TRUE; 220 221 if (pulId != NULL) 222 *pulId = ulId; 223 } 224 225 return bResult; 226 } 227 228 229 static 230 BOOL 231 ParseDaysOfMonth( 232 PWSTR pszBuffer, 233 PULONG pulDaysOfMonth) 234 { 235 PWSTR startPtr, endPtr; 236 ULONG ulValue; 237 238 if (wcslen(pszBuffer) == 0) 239 return FALSE; 240 241 startPtr = pszBuffer; 242 endPtr = NULL; 243 for (;;) 244 { 245 ulValue = wcstoul(startPtr, &endPtr, 10); 246 if (ulValue == 0) 247 return FALSE; 248 249 if (ulValue > 0 && ulValue <= 31) 250 *pulDaysOfMonth |= (1 << (ulValue - 1)); 251 252 if (endPtr != NULL && *endPtr == UNICODE_NULL) 253 return TRUE; 254 255 startPtr = endPtr + 1; 256 endPtr = NULL; 257 } 258 259 return FALSE; 260 } 261 262 263 static 264 BOOL 265 ParseDaysOfWeek( 266 PWSTR pszBuffer, 267 PUCHAR pucDaysOfWeek) 268 { 269 PWSTR startPtr, endPtr; 270 INT nLength, i; 271 272 if (wcslen(pszBuffer) == 0) 273 return FALSE; 274 275 startPtr = pszBuffer; 276 endPtr = NULL; 277 for (;;) 278 { 279 endPtr = wcschr(startPtr, L','); 280 if (endPtr == NULL) 281 nLength = wcslen(startPtr); 282 else 283 nLength = (INT)((ULONG_PTR)endPtr - (ULONG_PTR)startPtr) / sizeof(WCHAR); 284 285 for (i = 0; i < 7; i++) 286 { 287 if (nLength == wcslen(pszDaysOfWeekArray[i]) && 288 _wcsnicmp(startPtr, pszDaysOfWeekArray[i], nLength) == 0) 289 { 290 *pucDaysOfWeek |= (1 << i); 291 break; 292 } 293 } 294 295 if (endPtr == NULL) 296 return TRUE; 297 298 startPtr = endPtr + 1; 299 endPtr = NULL; 300 } 301 302 return FALSE; 303 } 304 305 306 static 307 VOID 308 PrintErrorMessage( 309 DWORD dwError) 310 { 311 PWSTR pszBuffer = NULL; 312 313 FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 314 NULL, 315 dwError, 316 0, 317 (PWSTR)&pszBuffer, 318 0, 319 NULL); 320 321 ConPrintf(StdErr, L"%s\n", pszBuffer); 322 LocalFree(pszBuffer); 323 } 324 325 326 static 327 VOID 328 PrintHorizontalLine(VOID) 329 { 330 WCHAR szBuffer[80]; 331 INT i; 332 333 for (i = 0; i < 79; i++) 334 szBuffer[i] = L'-'; 335 szBuffer[79] = UNICODE_NULL; 336 337 ConPrintf(StdOut, L"%s\n", szBuffer); 338 } 339 340 341 static 342 BOOL 343 Confirm(VOID) 344 { 345 HINSTANCE hInstance; 346 WCHAR szYesBuffer[8]; 347 WCHAR szNoBuffer[8]; 348 WCHAR szInput[80]; 349 DWORD dwOldMode; 350 DWORD dwRead = 0; 351 BOOL ret = FALSE; 352 HANDLE hFile; 353 354 hInstance = GetModuleHandleW(NULL); 355 LoadStringW(hInstance, IDS_CONFIRM_YES, szYesBuffer, _countof(szYesBuffer)); 356 LoadStringW(hInstance, IDS_CONFIRM_NO, szNoBuffer, _countof(szNoBuffer)); 357 358 ZeroMemory(szInput, sizeof(szInput)); 359 360 hFile = GetStdHandle(STD_INPUT_HANDLE); 361 GetConsoleMode(hFile, &dwOldMode); 362 363 SetConsoleMode(hFile, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); 364 365 for (;;) 366 { 367 ConResPrintf(StdOut, IDS_CONFIRM_QUESTION); 368 369 ReadConsoleW(hFile, szInput, _countof(szInput), &dwRead, NULL); 370 371 szInput[0] = towupper(szInput[0]); 372 if (szInput[0] == szYesBuffer[0]) 373 { 374 ret = TRUE; 375 break; 376 } 377 else if (szInput[0] == 13 || szInput[0] == szNoBuffer[0]) 378 { 379 ret = FALSE; 380 break; 381 } 382 383 ConResPrintf(StdOut, IDS_CONFIRM_INVALID); 384 } 385 386 SetConsoleMode(hFile, dwOldMode); 387 388 return ret; 389 } 390 391 392 static 393 DWORD_PTR 394 GetTimeAsJobTime(VOID) 395 { 396 SYSTEMTIME Time; 397 DWORD_PTR JobTime; 398 399 GetLocalTime(&Time); 400 401 JobTime = (DWORD_PTR)Time.wHour * 3600000 + 402 (DWORD_PTR)Time.wMinute * 60000; 403 404 return JobTime; 405 } 406 407 408 static 409 ULONG 410 GetCurrentDayOfMonth(VOID) 411 { 412 SYSTEMTIME Time; 413 414 GetLocalTime(&Time); 415 416 return 1UL << (Time.wDay - 1); 417 } 418 419 420 static 421 VOID 422 JobTimeToTimeString( 423 PWSTR pszBuffer, 424 INT cchBuffer, 425 WORD wHour, 426 WORD wMinute) 427 { 428 SYSTEMTIME Time = {0, 0, 0, 0, 0, 0, 0, 0}; 429 430 Time.wHour = wHour; 431 Time.wMinute = wMinute; 432 433 GetTimeFormat(LOCALE_USER_DEFAULT, 434 TIME_NOSECONDS, 435 &Time, 436 NULL, 437 pszBuffer, 438 cchBuffer); 439 } 440 441 442 static 443 INT 444 PrintJobDetails( 445 PWSTR pszComputerName, 446 ULONG ulJobId) 447 { 448 PAT_INFO pBuffer = NULL; 449 DWORD_PTR CurrentTime; 450 WCHAR szStatusBuffer[16]; 451 WCHAR szScheduleBuffer[60]; 452 WCHAR szTimeBuffer[16]; 453 WCHAR szInteractiveBuffer[16]; 454 WCHAR szDateBuffer[8]; 455 INT i, nDateLength, nScheduleLength; 456 HINSTANCE hInstance; 457 NET_API_STATUS Status; 458 459 Status = NetScheduleJobGetInfo(pszComputerName, 460 ulJobId, 461 (PBYTE *)&pBuffer); 462 if (Status != NERR_Success) 463 { 464 PrintErrorMessage(Status); 465 return 1; 466 } 467 468 hInstance = GetModuleHandle(NULL); 469 470 if (pBuffer->Flags & JOB_EXEC_ERROR) 471 LoadStringW(hInstance, IDS_ERROR, szStatusBuffer, _countof(szStatusBuffer)); 472 else 473 LoadStringW(hInstance, IDS_OK, szStatusBuffer, _countof(szStatusBuffer)); 474 475 if (pBuffer->DaysOfMonth != 0) 476 { 477 if (pBuffer->Flags & JOB_RUN_PERIODICALLY) 478 LoadStringW(hInstance, IDS_EVERY, szScheduleBuffer, _countof(szScheduleBuffer)); 479 else 480 LoadStringW(hInstance, IDS_NEXT, szScheduleBuffer, _countof(szScheduleBuffer)); 481 482 nScheduleLength = wcslen(szScheduleBuffer); 483 for (i = 0; i < 31; i++) 484 { 485 if (pBuffer->DaysOfMonth & (1 << i)) 486 { 487 swprintf(szDateBuffer, L" %d", i + 1); 488 nDateLength = wcslen(szDateBuffer); 489 if (nScheduleLength + nDateLength <= 55) 490 { 491 wcscat(szScheduleBuffer, szDateBuffer); 492 nScheduleLength += nDateLength; 493 } 494 else 495 { 496 wcscat(szScheduleBuffer, L"..."); 497 break; 498 } 499 } 500 } 501 } 502 else if (pBuffer->DaysOfWeek != 0) 503 { 504 if (pBuffer->Flags & JOB_RUN_PERIODICALLY) 505 LoadStringW(hInstance, IDS_EVERY, szScheduleBuffer, _countof(szScheduleBuffer)); 506 else 507 LoadStringW(hInstance, IDS_NEXT, szScheduleBuffer, _countof(szScheduleBuffer)); 508 509 nScheduleLength = wcslen(szScheduleBuffer); 510 for (i = 0; i < 7; i++) 511 { 512 if (pBuffer->DaysOfWeek & (1 << i)) 513 { 514 swprintf(szDateBuffer, L" %s", pszDaysOfWeekArray[i]); 515 nDateLength = wcslen(szDateBuffer); 516 if (nScheduleLength + nDateLength <= 55) 517 { 518 wcscat(szScheduleBuffer, szDateBuffer); 519 nScheduleLength += nDateLength; 520 } 521 else 522 { 523 wcscat(szScheduleBuffer, L"..."); 524 break; 525 } 526 } 527 } 528 } 529 else 530 { 531 CurrentTime = GetTimeAsJobTime(); 532 if (CurrentTime > pBuffer->JobTime) 533 LoadStringW(hInstance, IDS_TOMORROW, szScheduleBuffer, _countof(szScheduleBuffer)); 534 else 535 LoadStringW(hInstance, IDS_TODAY, szScheduleBuffer, _countof(szScheduleBuffer)); 536 } 537 538 JobTimeToTimeString(szTimeBuffer, 539 _countof(szTimeBuffer), 540 (WORD)(pBuffer->JobTime / 3600000), 541 (WORD)((pBuffer->JobTime % 3600000) / 60000)); 542 543 if (pBuffer->Flags & JOB_NONINTERACTIVE) 544 LoadStringW(hInstance, IDS_NO, szInteractiveBuffer, _countof(szInteractiveBuffer)); 545 else 546 LoadStringW(hInstance, IDS_YES, szInteractiveBuffer, _countof(szInteractiveBuffer)); 547 548 ConResPrintf(StdOut, IDS_TASKID, ulJobId); 549 ConResPrintf(StdOut, IDS_STATUS, szStatusBuffer); 550 ConResPrintf(StdOut, IDS_SCHEDULE, szScheduleBuffer); 551 ConResPrintf(StdOut, IDS_TIME, szTimeBuffer); 552 ConResPrintf(StdOut, IDS_INTERACTIVE, szInteractiveBuffer); 553 ConResPrintf(StdOut, IDS_COMMAND, pBuffer->Command); 554 555 NetApiBufferFree(pBuffer); 556 557 return 0; 558 } 559 560 561 static 562 INT 563 PrintAllJobs( 564 PWSTR pszComputerName) 565 { 566 PAT_ENUM pBuffer = NULL; 567 DWORD dwRead = 0, dwTotal = 0; 568 DWORD dwResume = 0, i; 569 DWORD_PTR CurrentTime; 570 NET_API_STATUS Status; 571 572 WCHAR szScheduleBuffer[32]; 573 WCHAR szTimeBuffer[16]; 574 WCHAR szDateBuffer[8]; 575 HINSTANCE hInstance; 576 INT j, nDateLength, nScheduleLength; 577 578 Status = NetScheduleJobEnum(pszComputerName, 579 (PBYTE *)&pBuffer, 580 MAX_PREFERRED_LENGTH, 581 &dwRead, 582 &dwTotal, 583 &dwResume); 584 if (Status != NERR_Success) 585 { 586 PrintErrorMessage(Status); 587 return 1; 588 } 589 590 if (dwTotal == 0) 591 { 592 ConResPrintf(StdOut, IDS_NO_ENTRIES); 593 return 0; 594 } 595 596 ConResPrintf(StdOut, IDS_JOBS_LIST); 597 PrintHorizontalLine(); 598 599 hInstance = GetModuleHandle(NULL); 600 601 for (i = 0; i < dwRead; i++) 602 { 603 if (pBuffer[i].DaysOfMonth != 0) 604 { 605 if (pBuffer[i].Flags & JOB_RUN_PERIODICALLY) 606 LoadStringW(hInstance, IDS_EVERY, szScheduleBuffer, _countof(szScheduleBuffer)); 607 else 608 LoadStringW(hInstance, IDS_NEXT, szScheduleBuffer, _countof(szScheduleBuffer)); 609 610 nScheduleLength = wcslen(szScheduleBuffer); 611 for (j = 0; j < 31; j++) 612 { 613 if (pBuffer[i].DaysOfMonth & (1 << j)) 614 { 615 swprintf(szDateBuffer, L" %d", j + 1); 616 nDateLength = wcslen(szDateBuffer); 617 if (nScheduleLength + nDateLength <= 19) 618 { 619 wcscat(szScheduleBuffer, szDateBuffer); 620 nScheduleLength += nDateLength; 621 } 622 else 623 { 624 wcscat(szScheduleBuffer, L"..."); 625 break; 626 } 627 } 628 } 629 } 630 else if (pBuffer[i].DaysOfWeek != 0) 631 { 632 if (pBuffer[i].Flags & JOB_RUN_PERIODICALLY) 633 LoadStringW(hInstance, IDS_EVERY, szScheduleBuffer, _countof(szScheduleBuffer)); 634 else 635 LoadStringW(hInstance, IDS_NEXT, szScheduleBuffer, _countof(szScheduleBuffer)); 636 637 nScheduleLength = wcslen(szScheduleBuffer); 638 for (j = 0; j < 7; j++) 639 { 640 if (pBuffer[i].DaysOfWeek & (1 << j)) 641 { 642 swprintf(szDateBuffer, L" %s", pszDaysOfWeekArray[j]); 643 nDateLength = wcslen(szDateBuffer); 644 if (nScheduleLength + nDateLength <= 55) 645 { 646 wcscat(szScheduleBuffer, szDateBuffer); 647 nScheduleLength += nDateLength; 648 } 649 else 650 { 651 wcscat(szScheduleBuffer, L"..."); 652 break; 653 } 654 } 655 } 656 } 657 else 658 { 659 CurrentTime = GetTimeAsJobTime(); 660 if (CurrentTime > pBuffer[i].JobTime) 661 LoadStringW(hInstance, IDS_TOMORROW, szScheduleBuffer, _countof(szScheduleBuffer)); 662 else 663 LoadStringW(hInstance, IDS_TODAY, szScheduleBuffer, _countof(szScheduleBuffer)); 664 } 665 666 JobTimeToTimeString(szTimeBuffer, 667 _countof(szTimeBuffer), 668 (WORD)(pBuffer[i].JobTime / 3600000), 669 (WORD)((pBuffer[i].JobTime % 3600000) / 60000)); 670 671 ConPrintf(StdOut, 672 L" %6lu %-21s %-11s %s\n", 673 pBuffer[i].JobId, 674 szScheduleBuffer, 675 szTimeBuffer, 676 pBuffer[i].Command); 677 } 678 679 NetApiBufferFree(pBuffer); 680 681 return 0; 682 } 683 684 685 static 686 INT 687 AddJob( 688 PWSTR pszComputerName, 689 ULONG ulJobHour, 690 ULONG ulJobMinute, 691 ULONG ulDaysOfMonth, 692 UCHAR ucDaysOfWeek, 693 BOOL bInteractiveJob, 694 BOOL bPeriodicJob, 695 PWSTR pszCommand) 696 { 697 AT_INFO InfoBuffer; 698 ULONG ulJobId = 0; 699 NET_API_STATUS Status; 700 701 InfoBuffer.JobTime = (DWORD_PTR)ulJobHour * 3600000 + 702 (DWORD_PTR)ulJobMinute * 60000; 703 InfoBuffer.DaysOfMonth = ulDaysOfMonth; 704 InfoBuffer.DaysOfWeek = ucDaysOfWeek; 705 InfoBuffer.Flags = (bInteractiveJob ? 0 : JOB_NONINTERACTIVE) | 706 (bPeriodicJob ? JOB_RUN_PERIODICALLY : 0); 707 InfoBuffer.Command = pszCommand; 708 709 Status = NetScheduleJobAdd(pszComputerName, 710 (PBYTE)&InfoBuffer, 711 &ulJobId); 712 if (Status != NERR_Success) 713 { 714 PrintErrorMessage(Status); 715 return 1; 716 } 717 718 ConResPrintf(StdOut, IDS_NEW_JOB, ulJobId); 719 720 return 0; 721 } 722 723 724 static 725 INT 726 DeleteJob( 727 PWSTR pszComputerName, 728 ULONG ulJobId, 729 BOOL bForceDelete) 730 { 731 NET_API_STATUS Status; 732 733 if (ulJobId == (ULONG)-1 && bForceDelete == FALSE) 734 { 735 ConResPrintf(StdOut, IDS_DELETE_ALL); 736 if (!Confirm()) 737 return 0; 738 } 739 740 Status = NetScheduleJobDel(pszComputerName, 741 (ulJobId == (ULONG)-1) ? 0 : ulJobId, 742 (ulJobId == (ULONG)-1) ? -1 : ulJobId); 743 if (Status != NERR_Success) 744 { 745 PrintErrorMessage(Status); 746 return 1; 747 } 748 749 return 0; 750 } 751 752 753 int wmain(int argc, WCHAR **argv) 754 { 755 PWSTR pszComputerName = NULL; 756 PWSTR pszCommand = NULL; 757 ULONG ulJobId = (ULONG)-1; 758 ULONG ulJobHour = (ULONG)-1; 759 ULONG ulJobMinute = (ULONG)-1; 760 BOOL bDeleteJob = FALSE, bForceDelete = FALSE; 761 BOOL bInteractiveJob = FALSE, bPeriodicJob = FALSE; 762 BOOL bPrintUsage = FALSE; 763 ULONG ulDaysOfMonth = 0; 764 UCHAR ucDaysOfWeek = 0; 765 INT nResult = 0; 766 INT i, minIdx; 767 768 /* Initialize the Console Standard Streams */ 769 ConInitStdStreams(); 770 771 if (!InitDaysOfWeekArray()) 772 return 1; 773 774 /* Parse the computer name */ 775 i = 1; 776 minIdx = 1; 777 if (i < argc && 778 argv[i][0] == L'\\' && 779 argv[i][1] == L'\\') 780 { 781 pszComputerName = argv[i]; 782 i++; 783 minIdx++; 784 } 785 786 /* Parse the time or job id */ 787 if (i < argc && argv[i][0] != L'/') 788 { 789 if (ParseTime(argv[i], &ulJobHour, &ulJobMinute)) 790 { 791 i++; 792 minIdx++; 793 } 794 else if (ParseId(argv[i], &ulJobId)) 795 { 796 i++; 797 minIdx++; 798 } 799 } 800 801 /* Parse the options */ 802 for (; i < argc; i++) 803 { 804 if (argv[i][0] == L'/') 805 { 806 if (_wcsicmp(argv[i], L"/?") == 0) 807 { 808 bPrintUsage = TRUE; 809 goto done; 810 } 811 else if (_wcsicmp(argv[i], L"/delete") == 0) 812 { 813 bDeleteJob = TRUE; 814 } 815 else if (_wcsicmp(argv[i], L"/yes") == 0) 816 { 817 bForceDelete = TRUE; 818 } 819 else if (_wcsicmp(argv[i], L"/interactive") == 0) 820 { 821 bInteractiveJob = TRUE; 822 } 823 else if (_wcsnicmp(argv[i], L"/every:", 7) == 0) 824 { 825 bPeriodicJob = TRUE; 826 if (ParseDaysOfMonth(&(argv[i][7]), &ulDaysOfMonth) == FALSE) 827 { 828 if (ParseDaysOfWeek(&(argv[i][7]), &ucDaysOfWeek) == FALSE) 829 { 830 ulDaysOfMonth = GetCurrentDayOfMonth(); 831 } 832 } 833 } 834 else if (_wcsnicmp(argv[i], L"/next:", 6) == 0) 835 { 836 bPeriodicJob = FALSE; 837 if (ParseDaysOfMonth(&(argv[i][6]), &ulDaysOfMonth) == FALSE) 838 { 839 if (ParseDaysOfWeek(&(argv[i][6]), &ucDaysOfWeek) == FALSE) 840 { 841 ulDaysOfMonth = GetCurrentDayOfMonth(); 842 } 843 } 844 } 845 else 846 { 847 bPrintUsage = TRUE; 848 nResult = 1; 849 goto done; 850 } 851 } 852 } 853 854 /* Parse the command */ 855 if (argc > minIdx && argv[argc - 1][0] != L'/') 856 { 857 pszCommand = argv[argc - 1]; 858 } 859 860 if (bDeleteJob == TRUE) 861 { 862 /* Check for invalid options or arguments */ 863 if (bInteractiveJob == TRUE || 864 ulJobHour != (ULONG)-1 || 865 ulJobMinute != (ULONG)-1 || 866 ulDaysOfMonth != 0 || 867 ucDaysOfWeek != 0 || 868 pszCommand != NULL) 869 { 870 bPrintUsage = TRUE; 871 nResult = 1; 872 goto done; 873 } 874 875 nResult = DeleteJob(pszComputerName, 876 ulJobId, 877 bForceDelete); 878 } 879 else 880 { 881 if (ulJobHour != (ULONG)-1 && ulJobMinute != (ULONG)-1) 882 { 883 /* Check for invalid options or arguments */ 884 if (bForceDelete == TRUE || 885 pszCommand == NULL) 886 { 887 bPrintUsage = TRUE; 888 nResult = 1; 889 goto done; 890 } 891 892 nResult = AddJob(pszComputerName, 893 ulJobHour, 894 ulJobMinute, 895 ulDaysOfMonth, 896 ucDaysOfWeek, 897 bInteractiveJob, 898 bPeriodicJob, 899 pszCommand); 900 } 901 else 902 { 903 /* Check for invalid options or arguments */ 904 if (bForceDelete == TRUE || 905 bInteractiveJob == TRUE || 906 ulDaysOfMonth != 0 || 907 ucDaysOfWeek != 0 || 908 pszCommand != NULL) 909 { 910 bPrintUsage = TRUE; 911 nResult = 1; 912 goto done; 913 } 914 915 if (ulJobId == (ULONG)-1) 916 { 917 nResult = PrintAllJobs(pszComputerName); 918 } 919 else 920 { 921 nResult = PrintJobDetails(pszComputerName, 922 ulJobId); 923 } 924 } 925 } 926 927 done: 928 FreeDaysOfWeekArray(); 929 930 if (bPrintUsage == TRUE) 931 ConResPuts(StdOut, IDS_USAGE); 932 933 return nResult; 934 } 935 936 /* EOF */ 937