Last active
May 15, 2020 13:20
-
-
Save Vlado-99/1d59bf05b70481377ff90bb53e13bb2d to your computer and use it in GitHub Desktop.
Helper script for Cygwin installation update
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@echo off | |
rem Leave empty for defaults/autodetect, or set BOTH variables (C:\cygwin64;x86_64) | |
set MY_CYGWIN_PATH= | |
set MY_CYGWIN_ARCH= | |
rem GnuPG is needed for setup file signature check. | |
rem Download ftp://ftp.gnupg.org/gcrypt/binary/gnupg-w32cli-1.4.23.exe | |
rem Actually only needed files are gpg.exe and iconv.dll. gpgkeys_hkp.exe is needed for import new key: | |
rem gpg\gpg --keyserver keys.gnupg.net --recv-key 1A698DE9E2E56300 | |
set GNUPG=C:\Program Files (x86)\GNU\GnuPG\gpg.exe | |
if %2_==_ goto :BEGIN | |
set MY_CYGWIN_PATH=%~1 | |
set MY_CYGWIN_ARCH=%~2 | |
goto :BEGIN | |
REM Last change: | |
rem 2020-05-15: updated gpg info, fix acls after every download | |
rem 2020-03-02: + cron | |
rem 2017-05-15: be smarter finding name for old setup | |
rem 2016-07-16: cmd line args, bug fix | |
rem 2016-07-14: when autodetected C:\cygwin, verify if actually contains 32-bit Cygwin | |
rem 2016-04-29: reset file permissions to widnows-default, gpg subdir, icacls /Q | |
rem 2016-01-19: + ssh-pageant | |
rem 2016-01-06: help prevent "directory poisoning" with malicious DLLs | |
rem 2015-11-19: tested on Windows Server 2008 R2 | |
rem 2015-11-19: iconv.dll link, typos, tested on Windows Server 2012 R2 | |
rem 2015-11-18: tested on Windows 7 64-bit | |
rem 2015-11-18: completely rewritten | |
REM Author: Vladimir Bella, vlabeg@gmail.com | |
REM DISCLAIMER | |
rem I wrote this software for myself, to satisfy my needs and requirements. | |
rem You can freely use (and modify) it, but this is YOUR decision and YOU are responsible if this | |
rem software fits to you. | |
:IS_ADMIN_ELEVATED | |
rem Thanks to Ben Hooper, http://stackoverflow.com/questions/4051883/batch-script-how-to-check-for-admin-rights | |
set RV=0 | |
net session >nul 2>&1 | |
if not errorlevel 1 set RV=1 | |
goto :EOF | |
:DOWNLOAD | |
if not "%WGET%"=="" "%WGET%" %1 -O %2 | |
if "%WGET%"=="" "%CURL%" %1 -o %2 | |
if errorlevel 1 if exist %2 del %2 | |
if exist %2 icacls %2 /reset /Q | |
goto :EOF | |
:FIND_IN_PATH | |
set RV=%~$PATH:1 | |
goto :EOF | |
:NORMALIZE_NUMBER | |
rem Remove leading 0's | |
set RV=%~1 | |
if "%RV%"=="" goto :EOF | |
:NN_LOOP | |
if "%RV%"=="0" goto :EOF | |
if not "%RV:~0,1%"=="0" goto :EOF | |
set RV=%RV:~1% | |
goto :NN_LOOP | |
:FORMAT_NUMBER | |
rem call :FORMAT_NUMBER integer_to_format num_of_digits | |
setlocal enableextensions, enabledelayedexpansion | |
set RV=0000000000%~1 | |
set FN=%~2 | |
set RV=!RV:~-%FN%! | |
endlocal && set RV=%RV% | |
goto :EOF | |
:INCREMENT | |
call :NORMALIZE_NUMBER %1 | |
set /A RV=RV+1 | |
call :FORMAT_NUMBER %RV% %2 | |
goto :EOF | |
:ERR_PERMISSIONS | |
@echo Please run this script with administrative/elevated permissions. | |
@pause | |
goto :EOF | |
:ERR_CYGWIN_NOT_FOUND | |
@echo Cygwin installation not found. | |
@pause | |
goto :EOF | |
:ERR_MISSING_WGET | |
@echo Neither wget nor curl found in Cygwin. | |
@pause | |
goto :EOF | |
:ERR_NO_SETUP | |
@echo %SETUP%.exe not found in script directory (%~dp0). | |
@pause | |
goto :EOF | |
:ERR_NO_PUBRING | |
@echo Missing/can't be downloaded pubring.asc. | |
@pause | |
goto :EOF | |
:ERR_NO_SIGNATURE | |
@echo Missing/can't be downloaded fresh setup signature. | |
@pause | |
goto :EOF | |
:ERR_NO_GPG | |
@echo Gpg.exe can't be found. | |
@pause | |
goto :EOF | |
:ERR_GPG_IMPORT | |
@echo Gpg: import of Cygwin key failed. | |
@pause | |
goto :EOF | |
:ERR_SETUP_DNL_FAILED | |
@echo Downloading new setup failed. | |
@pause | |
goto :EOF | |
:ERR_NEW_SETUP_SIG | |
@echo ERROR. New setup (%SETUP%.exe) signature verification FAILED. | |
@pause | |
goto :EOF | |
:ERR_DLL_FOUND | |
@echo There are DLL(s) in setup directory - risk of "directory poisoning". | |
@echo For more information read: http://seclists.org/fulldisclosure/2015/Nov/101 | |
dir /B .\*.DLL | |
@pause | |
goto :EOF | |
:BEGIN | |
setlocal enableextensions enabledelayedexpansion | |
@REM ================================================== | |
@REM Check and set environment | |
@REM ================================================== | |
@echo Checking for administrative/elevated permissions... | |
call :IS_ADMIN_ELEVATED | |
if %RV%==0 goto :ERR_PERMISSIONS | |
@echo Ok. | |
@echo. | |
@echo Searching for Cygwin installation to upgrade... | |
if not "%MY_CYGWIN_PATH%"=="" if not "%MY_CYGWIN_ARCH%"=="" goto :VERIFY_MY_CYGWIN | |
set MY_CYGWIN_PATH=C:\cygwin64 | |
set MY_CYGWIN_ARCH=x86_64 | |
if exist "%MY_CYGWIN_PATH%\bin\cygwin*.dll" goto :VERIFY_MY_CYGWIN | |
set MY_CYGWIN_PATH=C:\cygwin | |
set MY_CYGWIN_ARCH=x86 | |
if not exist "%MY_CYGWIN_PATH%\bin\uname.exe" goto :VERIFY_MY_CYGWIN | |
@rem Verify, if in MY_CYGWIN_PATH is actually 32-bit Cygwin | |
"%MY_CYGWIN_PATH%\bin\uname.exe" -a | find " x86_64 Cygwin" >nul: 2>nul: | |
if not errorlevel 1 set MY_CYGWIN_ARCH=x86_64 | |
:VERIFY_MY_CYGWIN | |
@set WGET=%MY_CYGWIN_PATH%\bin\wget.exe | |
@set CURL=%MY_CYGWIN_PATH%\bin\curl.exe | |
@set SETUP=setup-%MY_CYGWIN_ARCH% | |
if not exist "%MY_CYGWIN_PATH%\bin\cygwin*.dll" goto :ERR_CYGWIN_NOT_FOUND | |
if not exist "%WGET%" if not exist "%CURL%" goto :ERR_MISSING_WGET | |
@echo Found %MY_CYGWIN_PATH%, %MY_CYGWIN_ARCH%. | |
@echo. | |
@REM Next is needed, because UAC changes current directory | |
cd /d "%~dp0" | |
@echo Help prevent "directory poisoning" | |
if exist .\*.DLL goto :ERR_DLL_FOUND | |
@echo Ok. | |
@echo. | |
@echo Checking for GnuPG... | |
if not exist "%GNUPG%" ( | |
call :FIND_IN_PATH gpg.exe | |
set GNUPG=%RV% | |
) | |
if not exist "%GNUPG%" set GNUPG=gpg\gpg.exe | |
if not exist "%GNUPG%" set GNUPG=gpg.exe | |
if not exist "%GNUPG%" goto :ERR_NO_GPG | |
@echo Ok. | |
@echo. | |
@REM ================================================== | |
@REM Ensure current and correct setup program | |
@REM ================================================== | |
@echo Checking for setup in current directory... | |
if not exist %SETUP%.exe goto :ERR_NO_SETUP | |
@echo Ok. | |
@echo. | |
@echo Downloading public key and current setup signature... | |
if not exist cygwin-pubring.asc call :DOWNLOAD https://cygwin.com/key/pubring.asc cygwin-pubring.asc | |
call :DOWNLOAD https://cygwin.com/%SETUP%.exe.sig %SETUP%.exe.sig | |
if not exist cygwin-pubring.asc goto :ERR_NO_PUBRING | |
if not exist %SETUP%.exe.sig goto :ERR_NO_SIGNATURE | |
@echo Ok. | |
@echo. | |
@echo Ensure Cygwin key is in keyring... | |
"%GNUPG%" --list-keys Cygwin >nul: | |
if errorlevel 1 "%GNUPG%" --import cygwin-pubring.asc | |
if errorlevel 1 goto :ERR_GPG_IMPORT | |
@echo Ok. | |
@echo. | |
@echo Check, if we have current setup... | |
"%GNUPG%" --verify %SETUP%.exe.sig %SETUP%.exe | |
if not errorlevel 1 ( | |
@echo Yes, we have. | |
@echo. | |
goto :HAVE_SETUP | |
) | |
@echo Nope. Need new setup... | |
set EXT=0 | |
for /F "usebackq tokens=3 delims=." %%i in (`dir /b %SETUP%.exe.* 2^>nul ^| findstr /I /E "\.exe\.[0-9][0-9][0-9]" ^| sort`) do @set EXT=%%i | |
call :INCREMENT %EXT% 3 | |
set EXT=%RV% | |
rename %SETUP%.exe %SETUP%.exe.%EXT% | |
call :DOWNLOAD https://cygwin.com/%SETUP%.exe %SETUP%.exe | |
if not exist %SETUP%.exe ( | |
rem revert last rename | |
rename %SETUP%.exe.%EXT% %SETUP%.exe | |
goto :ERR_SETUP_DNL_FAILED | |
) | |
@echo New setup downloaded. | |
@echo Old setup saved as %SETUP%.exe.%EXT%. | |
@echo. | |
@echo Check new setup signature... | |
"%GNUPG%" --verify %SETUP%.exe.sig %SETUP%.exe | |
if errorlevel 1 goto :ERR_NEW_SETUP_SIG | |
Rem Setup is valid. Repair file permissions: | |
icacls %SETUP%.exe /reset /Q | |
@echo Ok. | |
@echo. | |
:HAVE_SETUP | |
@REM ================================================== | |
@REM Stop running services | |
@REM ================================================== | |
set HAVE_CRON=0 | |
set HAVE_HTTPD=0 | |
set HAVE_MYSQLD=0 | |
set HAVE_SSHD=0 | |
set HAVE_CYGSERVER=0 | |
set HAVE_PAGEANT=0 | |
@REM ================================================== | |
@echo Service: cron | |
sc query cron | find "RUNNING" >nul | |
if not errorlevel 1 set HAVE_CRON=1 | |
if %HAVE_CRON%==1 @echo ... stopping | |
if %HAVE_CRON%==1 net stop cron | |
if %HAVE_CRON%==0 @echo ... did not run | |
@echo Service: httpd | |
tasklist | find "httpd.exe" >nul | |
if not errorlevel 1 set HAVE_HTTPD=1 | |
set OLD_PATH=%PATH% | |
set PATH=C:\cygwin\bin;C:\cygwin\usr\local\bin;%PATH% | |
if %HAVE_HTTPD%==1 @echo ... stopping | |
if %HAVE_HTTPD%==1 "%MY_CYGWIN_PATH%\bin\bash" /usr/sbin/apachectl -k stop | |
if %HAVE_HTTPD%==0 @echo ... did not run | |
set PATH=%OLD_PATH% | |
@echo Service: mysqld | |
sc query mysqld | find "RUNNING" >nul | |
if not errorlevel 1 set HAVE_MYSQLD=1 | |
if %HAVE_MYSQLD%==1 @echo ... stopping | |
if %HAVE_MYSQLD%==1 net stop mysqld | |
if %HAVE_MYSQLD%==0 @echo ... did not run | |
@echo Service: sshd | |
sc query sshd | find "RUNNING" >nul | |
if not errorlevel 1 set HAVE_SSHD=1 | |
if %HAVE_SSHD%==1 @echo ... stopping | |
if %HAVE_SSHD%==1 net stop sshd | |
if %HAVE_SSHD%==0 @echo ... did not run | |
@echo Process: ssh-pageant | |
tasklist /FI "IMAGENAME eq ssh-pageant.exe" | find "ssh-pageant" >nul | |
if not errorlevel 1 set HAVE_PAGEANT=1 | |
if %HAVE_PAGEANT%==1 @echo ... stopping | |
if %HAVE_PAGEANT%==1 taskkill /T /F /IM ssh-pageant.exe | |
if %HAVE_PAGEANT%==0 @echo ... did not run | |
@echo Service: cygserver | |
sc query cygserver | find "RUNNING" >nul | |
if not errorlevel 1 set HAVE_CYGSERVER=1 | |
if %HAVE_CYGSERVER%==1 @echo ... stopping | |
if %HAVE_CYGSERVER%==1 net stop cygserver | |
if %HAVE_CYGSERVER%==0 @echo ... did not run | |
@REM ================================================== | |
@echo CYGWIN SETUP | |
%SETUP%.exe --no-desktop --delete-orphans --root %MY_CYGWIN_PATH% | |
@echo. | |
@REM ================================================== | |
@REM Restore running services | |
@REM ================================================== | |
if %HAVE_CYGSERVER%==1 @echo Starting cygserver | |
if %HAVE_CYGSERVER%==1 net start cygserver | |
if %HAVE_CYGSERVER%==0 @echo cygserver did not run | |
@rem No need to start ssh-pageant | |
if %HAVE_SSHD%==1 @echo Starting sshd | |
if %HAVE_SSHD%==1 net start sshd | |
if %HAVE_SSHD%==0 @echo sshd did not run | |
if %HAVE_MYSQLD%==1 @echo Starting mysqld | |
if %HAVE_MYSQLD%==1 net start mysqld | |
if %HAVE_MYSQLD%==0 @echo mysqld did not run | |
set OLD_PATH=%PATH% | |
set PATH=C:\cygwin\bin;C:\cygwin\usr\local\bin;%PATH% | |
if %HAVE_HTTPD%==1 @echo Starting httpd | |
if %HAVE_HTTPD%==1 "%MY_CYGWIN_PATH%\bin\bash" /usr/sbin/apachectl -k start | |
if %HAVE_HTTPD%==0 @echo httpd did not run | |
set PATH=%OLD_PATH% | |
if %HAVE_CRON%==1 @echo Starting cron | |
if %HAVE_CRON%==1 net start cron | |
if %HAVE_CRON%==0 @echo cron did not run | |
:END | |
@echo Done. | |
pause |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment