Fossil SCM
Fixed command line processing for the "winsrv" command. Corrected a typo in the documentation of the "winsrv create" command. Report error messages in the native language if english is not available.
Commit
cff9cc34f078cbca2f36810bcd25cd8ab3ff6703
Parent
e130c2e781e4b2c…
1 file changed
+54
-29
+54
-29
| --- src/winhttp.c | ||
| +++ src/winhttp.c | ||
| @@ -267,24 +267,40 @@ | ||
| 267 | 267 | ** message string. Call fossil_mbcs_free() to deallocate any memory used |
| 268 | 268 | ** to store the message string when done. |
| 269 | 269 | */ |
| 270 | 270 | static char *win32_get_last_errmsg(void){ |
| 271 | 271 | DWORD nMsg; |
| 272 | + DWORD nErr = GetLastError(); | |
| 272 | 273 | LPTSTR tmp = NULL; |
| 273 | 274 | char *zMsg = NULL; |
| 274 | 275 | |
| 276 | + /* Try first to get the error text in english. */ | |
| 275 | 277 | nMsg = FormatMessage( |
| 276 | 278 | FORMAT_MESSAGE_ALLOCATE_BUFFER | |
| 277 | 279 | FORMAT_MESSAGE_FROM_SYSTEM | |
| 278 | 280 | FORMAT_MESSAGE_IGNORE_INSERTS, |
| 279 | 281 | NULL, |
| 280 | - GetLastError(), | |
| 282 | + nErr, | |
| 281 | 283 | MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), |
| 282 | 284 | (LPTSTR) &tmp, |
| 283 | 285 | 0, |
| 284 | 286 | NULL |
| 285 | 287 | ); |
| 288 | + if( !nMsg ){ | |
| 289 | + /* No english, get what the system has available. */ | |
| 290 | + nMsg = FormatMessage( | |
| 291 | + FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
| 292 | + FORMAT_MESSAGE_FROM_SYSTEM | | |
| 293 | + FORMAT_MESSAGE_IGNORE_INSERTS, | |
| 294 | + NULL, | |
| 295 | + nErr, | |
| 296 | + 0, | |
| 297 | + (LPTSTR) &tmp, | |
| 298 | + 0, | |
| 299 | + NULL | |
| 300 | + ); | |
| 301 | + } | |
| 286 | 302 | if( nMsg ){ |
| 287 | 303 | zMsg = fossil_mbcs_to_utf8(tmp); |
| 288 | 304 | }else{ |
| 289 | 305 | fossil_fatal("unable to get system error message."); |
| 290 | 306 | } |
| @@ -301,11 +317,11 @@ | ||
| 301 | 317 | static void win32_report_service_status( |
| 302 | 318 | DWORD dwCurrentState, /* The current state of the service */ |
| 303 | 319 | DWORD dwWin32ExitCode, /* The error code to report */ |
| 304 | 320 | DWORD dwWaitHint /* The estimated time for a pending operation */ |
| 305 | 321 | ){ |
| 306 | - if( dwCurrentState==SERVICE_START_PENDING) { | |
| 322 | + if( dwCurrentState==SERVICE_START_PENDING ){ | |
| 307 | 323 | ssStatus.dwControlsAccepted = 0; |
| 308 | 324 | }else{ |
| 309 | 325 | ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; |
| 310 | 326 | } |
| 311 | 327 | ssStatus.dwCurrentState = dwCurrentState; |
| @@ -477,11 +493,11 @@ | ||
| 477 | 493 | ** Password for the user account. |
| 478 | 494 | ** |
| 479 | 495 | ** The following options are more or less the same as for the "server" |
| 480 | 496 | ** command and influence the behaviour of the http server: |
| 481 | 497 | ** |
| 482 | -** -p|--port TCPPORT | |
| 498 | +** -P|--port TCPPORT | |
| 483 | 499 | ** |
| 484 | 500 | ** Specifies the TCP port (default port is 8080) on which the |
| 485 | 501 | ** server should listen. |
| 486 | 502 | ** |
| 487 | 503 | ** -R|--repository REPOSITORY |
| @@ -544,69 +560,62 @@ | ||
| 544 | 560 | if( g.argc<3 ){ |
| 545 | 561 | usage("create|delete|show|start|stop ..."); |
| 546 | 562 | } |
| 547 | 563 | zMethod = g.argv[2]; |
| 548 | 564 | n = strlen(zMethod); |
| 549 | - if( g.argc==4 ){ | |
| 550 | - zSvcName = g.argv[3]; | |
| 551 | - } | |
| 552 | 565 | |
| 553 | 566 | if( strncmp(zMethod, "create", n)==0 ){ |
| 554 | 567 | SC_HANDLE hScm; |
| 555 | 568 | SC_HANDLE hSvc; |
| 556 | 569 | SERVICE_DESCRIPTION |
| 557 | 570 | svcDescr = {"Fossil - Distributed Software Configuration Management"}; |
| 558 | 571 | char *zErrFmt = "unable to create service '%s': %s"; |
| 559 | 572 | DWORD dwStartType = SERVICE_DEMAND_START; |
| 560 | - const char *zDisplay; | |
| 561 | - const char *zStart; | |
| 562 | - const char *zUsername; | |
| 563 | - const char *zPassword; | |
| 564 | - const char *zPort; | |
| 565 | - const char *zNotFound; | |
| 566 | - const char *zLocalAuth; | |
| 567 | - const char *zRepository; | |
| 573 | + const char *zDisplay = find_option("display", "D", 1); | |
| 574 | + const char *zStart = find_option("start", "S", 1); | |
| 575 | + const char *zUsername = find_option("username", "U", 1); | |
| 576 | + const char *zPassword = find_option("password", "W", 1); | |
| 577 | + const char *zPort = find_option("port", "P", 1); | |
| 578 | + const char *zNotFound = find_option("notfound", 0, 1); | |
| 579 | + const char *zLocalAuth = find_option("localauth", 0, 0); | |
| 580 | + const char *zRepository = find_option("repository", "R", 1); | |
| 568 | 581 | Blob binPath; |
| 569 | 582 | |
| 583 | + verify_all_options(); | |
| 584 | + if( g.argc==4 ){ | |
| 585 | + zSvcName = g.argv[3]; | |
| 586 | + }else if( g.argc>4 ){ | |
| 587 | + fossil_fatal("to much arguments for create method."); | |
| 588 | + } | |
| 570 | 589 | /* Process service creation specific options. */ |
| 571 | - zDisplay = find_option("display", "D", 1); | |
| 572 | 590 | if( !zDisplay ){ |
| 573 | 591 | zDisplay = zSvcName; |
| 574 | 592 | } |
| 575 | - zStart = find_option("start", "S", 1); | |
| 576 | 593 | if( zStart ){ |
| 577 | 594 | if( strncmp(zStart, "auto", strlen(zStart))==0 ){ |
| 578 | 595 | dwStartType = SERVICE_AUTO_START; |
| 579 | - }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){ | |
| 596 | + }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){ | |
| 580 | 597 | dwStartType = SERVICE_DEMAND_START; |
| 581 | 598 | }else{ |
| 582 | 599 | fossil_fatal(zErrFmt, zSvcName, |
| 583 | 600 | "specify 'auto' or 'manual' for the '-S|--start' option"); |
| 584 | 601 | } |
| 585 | 602 | } |
| 586 | - zUsername = find_option("username", "U", 1); | |
| 587 | - zPassword = find_option("password", "W", 1); | |
| 588 | 603 | /* Process options for Fossil running as server. */ |
| 589 | - zPort = find_option("port", "P", 1); | |
| 590 | 604 | if( zPort && (atoi(zPort)<=0) ){ |
| 591 | 605 | fossil_fatal(zErrFmt, zSvcName, |
| 592 | 606 | "port number must be in the range 1 - 65535."); |
| 593 | 607 | } |
| 594 | - zNotFound = find_option("notfound", 0, 1); | |
| 595 | - zLocalAuth = find_option("localauth", 0, 0); | |
| 596 | - zRepository = find_option("repository", "R", 1); | |
| 597 | 608 | if( !zRepository ){ |
| 598 | 609 | db_must_be_within_tree(); |
| 599 | 610 | }else if( file_isdir(zRepository)==1 ){ |
| 600 | 611 | g.zRepositoryName = mprintf("%s", zRepository); |
| 601 | 612 | file_simplify_name(g.zRepositoryName, -1, 0); |
| 602 | 613 | }else{ |
| 603 | 614 | db_open_repository(zRepository); |
| 604 | 615 | } |
| 605 | 616 | db_close(0); |
| 606 | - verify_all_options(); | |
| 607 | - if( g.argc>4 ) fossil_fatal("to much arguments for create method."); | |
| 608 | 617 | /* Build the fully-qualified path to the service binary file. */ |
| 609 | 618 | blob_zero(&binPath); |
| 610 | 619 | blob_appendf(&binPath, "\"%s\" server", fossil_nameofexe()); |
| 611 | 620 | if( zPort ) blob_appendf(&binPath, " --port %s", zPort); |
| 612 | 621 | if( zNotFound ) blob_appendf(&binPath, " --notfound \"%s\"", zNotFound); |
| @@ -642,11 +651,15 @@ | ||
| 642 | 651 | SC_HANDLE hSvc; |
| 643 | 652 | SERVICE_STATUS sstat; |
| 644 | 653 | char *zErrFmt = "unable to delete service '%s': %s"; |
| 645 | 654 | |
| 646 | 655 | verify_all_options(); |
| 647 | - if( g.argc>4 ) fossil_fatal("to much arguments for delete method."); | |
| 656 | + if( g.argc==4 ){ | |
| 657 | + zSvcName = g.argv[3]; | |
| 658 | + }else if( g.argc>4 ){ | |
| 659 | + fossil_fatal("to much arguments for delete method."); | |
| 660 | + } | |
| 648 | 661 | hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 649 | 662 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 650 | 663 | hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS); |
| 651 | 664 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 652 | 665 | QueryServiceStatus(hSvc, &sstat); |
| @@ -706,11 +719,15 @@ | ||
| 706 | 719 | "Continue pending", "Pause pending", "Paused" |
| 707 | 720 | }; |
| 708 | 721 | const char *zSvcState = ""; |
| 709 | 722 | |
| 710 | 723 | verify_all_options(); |
| 711 | - if( g.argc>4 ) fossil_fatal("to much arguments for show method."); | |
| 724 | + if( g.argc==4 ){ | |
| 725 | + zSvcName = g.argv[3]; | |
| 726 | + }else if( g.argc>4 ){ | |
| 727 | + fossil_fatal("to much arguments for show method."); | |
| 728 | + } | |
| 712 | 729 | hScm = OpenSCManager(NULL, NULL, GENERIC_READ); |
| 713 | 730 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 714 | 731 | hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), GENERIC_READ); |
| 715 | 732 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 716 | 733 | /* Get the service configuration */ |
| @@ -784,11 +801,15 @@ | ||
| 784 | 801 | SC_HANDLE hSvc; |
| 785 | 802 | SERVICE_STATUS sstat; |
| 786 | 803 | char *zErrFmt = "unable to start service '%s': %s"; |
| 787 | 804 | |
| 788 | 805 | verify_all_options(); |
| 789 | - if( g.argc>4 ) fossil_fatal("to much arguments for start method."); | |
| 806 | + if( g.argc==4 ){ | |
| 807 | + zSvcName = g.argv[3]; | |
| 808 | + }else if( g.argc>4 ){ | |
| 809 | + fossil_fatal("to much arguments for start method."); | |
| 810 | + } | |
| 790 | 811 | hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 791 | 812 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 792 | 813 | hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS); |
| 793 | 814 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 794 | 815 | QueryServiceStatus(hSvc, &sstat); |
| @@ -816,11 +837,15 @@ | ||
| 816 | 837 | SC_HANDLE hSvc; |
| 817 | 838 | SERVICE_STATUS sstat; |
| 818 | 839 | char *zErrFmt = "unable to stop service '%s': %s"; |
| 819 | 840 | |
| 820 | 841 | verify_all_options(); |
| 821 | - if( g.argc>4 ) fossil_fatal("to much arguments for stop method."); | |
| 842 | + if( g.argc==4 ){ | |
| 843 | + zSvcName = g.argv[3]; | |
| 844 | + }else if( g.argc>4 ){ | |
| 845 | + fossil_fatal("to much arguments for stop method."); | |
| 846 | + } | |
| 822 | 847 | hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 823 | 848 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 824 | 849 | hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS); |
| 825 | 850 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 826 | 851 | QueryServiceStatus(hSvc, &sstat); |
| 827 | 852 |
| --- src/winhttp.c | |
| +++ src/winhttp.c | |
| @@ -267,24 +267,40 @@ | |
| 267 | ** message string. Call fossil_mbcs_free() to deallocate any memory used |
| 268 | ** to store the message string when done. |
| 269 | */ |
| 270 | static char *win32_get_last_errmsg(void){ |
| 271 | DWORD nMsg; |
| 272 | LPTSTR tmp = NULL; |
| 273 | char *zMsg = NULL; |
| 274 | |
| 275 | nMsg = FormatMessage( |
| 276 | FORMAT_MESSAGE_ALLOCATE_BUFFER | |
| 277 | FORMAT_MESSAGE_FROM_SYSTEM | |
| 278 | FORMAT_MESSAGE_IGNORE_INSERTS, |
| 279 | NULL, |
| 280 | GetLastError(), |
| 281 | MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), |
| 282 | (LPTSTR) &tmp, |
| 283 | 0, |
| 284 | NULL |
| 285 | ); |
| 286 | if( nMsg ){ |
| 287 | zMsg = fossil_mbcs_to_utf8(tmp); |
| 288 | }else{ |
| 289 | fossil_fatal("unable to get system error message."); |
| 290 | } |
| @@ -301,11 +317,11 @@ | |
| 301 | static void win32_report_service_status( |
| 302 | DWORD dwCurrentState, /* The current state of the service */ |
| 303 | DWORD dwWin32ExitCode, /* The error code to report */ |
| 304 | DWORD dwWaitHint /* The estimated time for a pending operation */ |
| 305 | ){ |
| 306 | if( dwCurrentState==SERVICE_START_PENDING) { |
| 307 | ssStatus.dwControlsAccepted = 0; |
| 308 | }else{ |
| 309 | ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; |
| 310 | } |
| 311 | ssStatus.dwCurrentState = dwCurrentState; |
| @@ -477,11 +493,11 @@ | |
| 477 | ** Password for the user account. |
| 478 | ** |
| 479 | ** The following options are more or less the same as for the "server" |
| 480 | ** command and influence the behaviour of the http server: |
| 481 | ** |
| 482 | ** -p|--port TCPPORT |
| 483 | ** |
| 484 | ** Specifies the TCP port (default port is 8080) on which the |
| 485 | ** server should listen. |
| 486 | ** |
| 487 | ** -R|--repository REPOSITORY |
| @@ -544,69 +560,62 @@ | |
| 544 | if( g.argc<3 ){ |
| 545 | usage("create|delete|show|start|stop ..."); |
| 546 | } |
| 547 | zMethod = g.argv[2]; |
| 548 | n = strlen(zMethod); |
| 549 | if( g.argc==4 ){ |
| 550 | zSvcName = g.argv[3]; |
| 551 | } |
| 552 | |
| 553 | if( strncmp(zMethod, "create", n)==0 ){ |
| 554 | SC_HANDLE hScm; |
| 555 | SC_HANDLE hSvc; |
| 556 | SERVICE_DESCRIPTION |
| 557 | svcDescr = {"Fossil - Distributed Software Configuration Management"}; |
| 558 | char *zErrFmt = "unable to create service '%s': %s"; |
| 559 | DWORD dwStartType = SERVICE_DEMAND_START; |
| 560 | const char *zDisplay; |
| 561 | const char *zStart; |
| 562 | const char *zUsername; |
| 563 | const char *zPassword; |
| 564 | const char *zPort; |
| 565 | const char *zNotFound; |
| 566 | const char *zLocalAuth; |
| 567 | const char *zRepository; |
| 568 | Blob binPath; |
| 569 | |
| 570 | /* Process service creation specific options. */ |
| 571 | zDisplay = find_option("display", "D", 1); |
| 572 | if( !zDisplay ){ |
| 573 | zDisplay = zSvcName; |
| 574 | } |
| 575 | zStart = find_option("start", "S", 1); |
| 576 | if( zStart ){ |
| 577 | if( strncmp(zStart, "auto", strlen(zStart))==0 ){ |
| 578 | dwStartType = SERVICE_AUTO_START; |
| 579 | }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){ |
| 580 | dwStartType = SERVICE_DEMAND_START; |
| 581 | }else{ |
| 582 | fossil_fatal(zErrFmt, zSvcName, |
| 583 | "specify 'auto' or 'manual' for the '-S|--start' option"); |
| 584 | } |
| 585 | } |
| 586 | zUsername = find_option("username", "U", 1); |
| 587 | zPassword = find_option("password", "W", 1); |
| 588 | /* Process options for Fossil running as server. */ |
| 589 | zPort = find_option("port", "P", 1); |
| 590 | if( zPort && (atoi(zPort)<=0) ){ |
| 591 | fossil_fatal(zErrFmt, zSvcName, |
| 592 | "port number must be in the range 1 - 65535."); |
| 593 | } |
| 594 | zNotFound = find_option("notfound", 0, 1); |
| 595 | zLocalAuth = find_option("localauth", 0, 0); |
| 596 | zRepository = find_option("repository", "R", 1); |
| 597 | if( !zRepository ){ |
| 598 | db_must_be_within_tree(); |
| 599 | }else if( file_isdir(zRepository)==1 ){ |
| 600 | g.zRepositoryName = mprintf("%s", zRepository); |
| 601 | file_simplify_name(g.zRepositoryName, -1, 0); |
| 602 | }else{ |
| 603 | db_open_repository(zRepository); |
| 604 | } |
| 605 | db_close(0); |
| 606 | verify_all_options(); |
| 607 | if( g.argc>4 ) fossil_fatal("to much arguments for create method."); |
| 608 | /* Build the fully-qualified path to the service binary file. */ |
| 609 | blob_zero(&binPath); |
| 610 | blob_appendf(&binPath, "\"%s\" server", fossil_nameofexe()); |
| 611 | if( zPort ) blob_appendf(&binPath, " --port %s", zPort); |
| 612 | if( zNotFound ) blob_appendf(&binPath, " --notfound \"%s\"", zNotFound); |
| @@ -642,11 +651,15 @@ | |
| 642 | SC_HANDLE hSvc; |
| 643 | SERVICE_STATUS sstat; |
| 644 | char *zErrFmt = "unable to delete service '%s': %s"; |
| 645 | |
| 646 | verify_all_options(); |
| 647 | if( g.argc>4 ) fossil_fatal("to much arguments for delete method."); |
| 648 | hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 649 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 650 | hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS); |
| 651 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 652 | QueryServiceStatus(hSvc, &sstat); |
| @@ -706,11 +719,15 @@ | |
| 706 | "Continue pending", "Pause pending", "Paused" |
| 707 | }; |
| 708 | const char *zSvcState = ""; |
| 709 | |
| 710 | verify_all_options(); |
| 711 | if( g.argc>4 ) fossil_fatal("to much arguments for show method."); |
| 712 | hScm = OpenSCManager(NULL, NULL, GENERIC_READ); |
| 713 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 714 | hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), GENERIC_READ); |
| 715 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 716 | /* Get the service configuration */ |
| @@ -784,11 +801,15 @@ | |
| 784 | SC_HANDLE hSvc; |
| 785 | SERVICE_STATUS sstat; |
| 786 | char *zErrFmt = "unable to start service '%s': %s"; |
| 787 | |
| 788 | verify_all_options(); |
| 789 | if( g.argc>4 ) fossil_fatal("to much arguments for start method."); |
| 790 | hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 791 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 792 | hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS); |
| 793 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 794 | QueryServiceStatus(hSvc, &sstat); |
| @@ -816,11 +837,15 @@ | |
| 816 | SC_HANDLE hSvc; |
| 817 | SERVICE_STATUS sstat; |
| 818 | char *zErrFmt = "unable to stop service '%s': %s"; |
| 819 | |
| 820 | verify_all_options(); |
| 821 | if( g.argc>4 ) fossil_fatal("to much arguments for stop method."); |
| 822 | hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 823 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 824 | hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS); |
| 825 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 826 | QueryServiceStatus(hSvc, &sstat); |
| 827 |
| --- src/winhttp.c | |
| +++ src/winhttp.c | |
| @@ -267,24 +267,40 @@ | |
| 267 | ** message string. Call fossil_mbcs_free() to deallocate any memory used |
| 268 | ** to store the message string when done. |
| 269 | */ |
| 270 | static char *win32_get_last_errmsg(void){ |
| 271 | DWORD nMsg; |
| 272 | DWORD nErr = GetLastError(); |
| 273 | LPTSTR tmp = NULL; |
| 274 | char *zMsg = NULL; |
| 275 | |
| 276 | /* Try first to get the error text in english. */ |
| 277 | nMsg = FormatMessage( |
| 278 | FORMAT_MESSAGE_ALLOCATE_BUFFER | |
| 279 | FORMAT_MESSAGE_FROM_SYSTEM | |
| 280 | FORMAT_MESSAGE_IGNORE_INSERTS, |
| 281 | NULL, |
| 282 | nErr, |
| 283 | MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), |
| 284 | (LPTSTR) &tmp, |
| 285 | 0, |
| 286 | NULL |
| 287 | ); |
| 288 | if( !nMsg ){ |
| 289 | /* No english, get what the system has available. */ |
| 290 | nMsg = FormatMessage( |
| 291 | FORMAT_MESSAGE_ALLOCATE_BUFFER | |
| 292 | FORMAT_MESSAGE_FROM_SYSTEM | |
| 293 | FORMAT_MESSAGE_IGNORE_INSERTS, |
| 294 | NULL, |
| 295 | nErr, |
| 296 | 0, |
| 297 | (LPTSTR) &tmp, |
| 298 | 0, |
| 299 | NULL |
| 300 | ); |
| 301 | } |
| 302 | if( nMsg ){ |
| 303 | zMsg = fossil_mbcs_to_utf8(tmp); |
| 304 | }else{ |
| 305 | fossil_fatal("unable to get system error message."); |
| 306 | } |
| @@ -301,11 +317,11 @@ | |
| 317 | static void win32_report_service_status( |
| 318 | DWORD dwCurrentState, /* The current state of the service */ |
| 319 | DWORD dwWin32ExitCode, /* The error code to report */ |
| 320 | DWORD dwWaitHint /* The estimated time for a pending operation */ |
| 321 | ){ |
| 322 | if( dwCurrentState==SERVICE_START_PENDING ){ |
| 323 | ssStatus.dwControlsAccepted = 0; |
| 324 | }else{ |
| 325 | ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; |
| 326 | } |
| 327 | ssStatus.dwCurrentState = dwCurrentState; |
| @@ -477,11 +493,11 @@ | |
| 493 | ** Password for the user account. |
| 494 | ** |
| 495 | ** The following options are more or less the same as for the "server" |
| 496 | ** command and influence the behaviour of the http server: |
| 497 | ** |
| 498 | ** -P|--port TCPPORT |
| 499 | ** |
| 500 | ** Specifies the TCP port (default port is 8080) on which the |
| 501 | ** server should listen. |
| 502 | ** |
| 503 | ** -R|--repository REPOSITORY |
| @@ -544,69 +560,62 @@ | |
| 560 | if( g.argc<3 ){ |
| 561 | usage("create|delete|show|start|stop ..."); |
| 562 | } |
| 563 | zMethod = g.argv[2]; |
| 564 | n = strlen(zMethod); |
| 565 | |
| 566 | if( strncmp(zMethod, "create", n)==0 ){ |
| 567 | SC_HANDLE hScm; |
| 568 | SC_HANDLE hSvc; |
| 569 | SERVICE_DESCRIPTION |
| 570 | svcDescr = {"Fossil - Distributed Software Configuration Management"}; |
| 571 | char *zErrFmt = "unable to create service '%s': %s"; |
| 572 | DWORD dwStartType = SERVICE_DEMAND_START; |
| 573 | const char *zDisplay = find_option("display", "D", 1); |
| 574 | const char *zStart = find_option("start", "S", 1); |
| 575 | const char *zUsername = find_option("username", "U", 1); |
| 576 | const char *zPassword = find_option("password", "W", 1); |
| 577 | const char *zPort = find_option("port", "P", 1); |
| 578 | const char *zNotFound = find_option("notfound", 0, 1); |
| 579 | const char *zLocalAuth = find_option("localauth", 0, 0); |
| 580 | const char *zRepository = find_option("repository", "R", 1); |
| 581 | Blob binPath; |
| 582 | |
| 583 | verify_all_options(); |
| 584 | if( g.argc==4 ){ |
| 585 | zSvcName = g.argv[3]; |
| 586 | }else if( g.argc>4 ){ |
| 587 | fossil_fatal("to much arguments for create method."); |
| 588 | } |
| 589 | /* Process service creation specific options. */ |
| 590 | if( !zDisplay ){ |
| 591 | zDisplay = zSvcName; |
| 592 | } |
| 593 | if( zStart ){ |
| 594 | if( strncmp(zStart, "auto", strlen(zStart))==0 ){ |
| 595 | dwStartType = SERVICE_AUTO_START; |
| 596 | }else if( strncmp(zStart, "manual", strlen(zStart))==0 ){ |
| 597 | dwStartType = SERVICE_DEMAND_START; |
| 598 | }else{ |
| 599 | fossil_fatal(zErrFmt, zSvcName, |
| 600 | "specify 'auto' or 'manual' for the '-S|--start' option"); |
| 601 | } |
| 602 | } |
| 603 | /* Process options for Fossil running as server. */ |
| 604 | if( zPort && (atoi(zPort)<=0) ){ |
| 605 | fossil_fatal(zErrFmt, zSvcName, |
| 606 | "port number must be in the range 1 - 65535."); |
| 607 | } |
| 608 | if( !zRepository ){ |
| 609 | db_must_be_within_tree(); |
| 610 | }else if( file_isdir(zRepository)==1 ){ |
| 611 | g.zRepositoryName = mprintf("%s", zRepository); |
| 612 | file_simplify_name(g.zRepositoryName, -1, 0); |
| 613 | }else{ |
| 614 | db_open_repository(zRepository); |
| 615 | } |
| 616 | db_close(0); |
| 617 | /* Build the fully-qualified path to the service binary file. */ |
| 618 | blob_zero(&binPath); |
| 619 | blob_appendf(&binPath, "\"%s\" server", fossil_nameofexe()); |
| 620 | if( zPort ) blob_appendf(&binPath, " --port %s", zPort); |
| 621 | if( zNotFound ) blob_appendf(&binPath, " --notfound \"%s\"", zNotFound); |
| @@ -642,11 +651,15 @@ | |
| 651 | SC_HANDLE hSvc; |
| 652 | SERVICE_STATUS sstat; |
| 653 | char *zErrFmt = "unable to delete service '%s': %s"; |
| 654 | |
| 655 | verify_all_options(); |
| 656 | if( g.argc==4 ){ |
| 657 | zSvcName = g.argv[3]; |
| 658 | }else if( g.argc>4 ){ |
| 659 | fossil_fatal("to much arguments for delete method."); |
| 660 | } |
| 661 | hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 662 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 663 | hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS); |
| 664 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 665 | QueryServiceStatus(hSvc, &sstat); |
| @@ -706,11 +719,15 @@ | |
| 719 | "Continue pending", "Pause pending", "Paused" |
| 720 | }; |
| 721 | const char *zSvcState = ""; |
| 722 | |
| 723 | verify_all_options(); |
| 724 | if( g.argc==4 ){ |
| 725 | zSvcName = g.argv[3]; |
| 726 | }else if( g.argc>4 ){ |
| 727 | fossil_fatal("to much arguments for show method."); |
| 728 | } |
| 729 | hScm = OpenSCManager(NULL, NULL, GENERIC_READ); |
| 730 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 731 | hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), GENERIC_READ); |
| 732 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 733 | /* Get the service configuration */ |
| @@ -784,11 +801,15 @@ | |
| 801 | SC_HANDLE hSvc; |
| 802 | SERVICE_STATUS sstat; |
| 803 | char *zErrFmt = "unable to start service '%s': %s"; |
| 804 | |
| 805 | verify_all_options(); |
| 806 | if( g.argc==4 ){ |
| 807 | zSvcName = g.argv[3]; |
| 808 | }else if( g.argc>4 ){ |
| 809 | fossil_fatal("to much arguments for start method."); |
| 810 | } |
| 811 | hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 812 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 813 | hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS); |
| 814 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 815 | QueryServiceStatus(hSvc, &sstat); |
| @@ -816,11 +837,15 @@ | |
| 837 | SC_HANDLE hSvc; |
| 838 | SERVICE_STATUS sstat; |
| 839 | char *zErrFmt = "unable to stop service '%s': %s"; |
| 840 | |
| 841 | verify_all_options(); |
| 842 | if( g.argc==4 ){ |
| 843 | zSvcName = g.argv[3]; |
| 844 | }else if( g.argc>4 ){ |
| 845 | fossil_fatal("to much arguments for stop method."); |
| 846 | } |
| 847 | hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); |
| 848 | if( !hScm ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 849 | hSvc = OpenService(hScm, fossil_utf8_to_mbcs(zSvcName), SERVICE_ALL_ACCESS); |
| 850 | if( !hSvc ) fossil_fatal(zErrFmt, zSvcName, win32_get_last_errmsg()); |
| 851 | QueryServiceStatus(hSvc, &sstat); |
| 852 |