Skip to content

Instantly share code, notes, and snippets.

@Vlado-99
Last active May 15, 2020 13:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Vlado-99/1d59bf05b70481377ff90bb53e13bb2d to your computer and use it in GitHub Desktop.
Save Vlado-99/1d59bf05b70481377ff90bb53e13bb2d to your computer and use it in GitHub Desktop.
Helper script for Cygwin installation update
@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