├── .gitattributes ├── LICENSE ├── README.md ├── apt-cyg ├── known_problems.md └── other_forks.md /.gitattributes: -------------------------------------------------------------------------------- 1 | apt-cyg text eol=lf 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Stephen Jungels 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | apt-cyg 2 | ======= 3 | 4 | apt-cyg is a command-line installer for [Cygwin](http://cygwin.com/) which cooperates with Cygwin Setup and uses the same repository. The syntax is similar to apt-get. 5 | 6 | Usage 7 | ----- 8 | 9 | ### Command line 10 | 11 | apt-cyg [] [ [ ...]] 12 | 13 | ### Subcommands 14 | 15 | | Subcommand | Description | 16 | |:------- |:----------- | 17 | | `install ` | to install packages | 18 | | `remove ` | to remove packages | 19 | | `update` | to update *setup.ini* | 20 | | `show` | to show installed packages | 21 | | `find ` | to find packages matching patterns | 22 | | `describe ` | to describe packages matching patterns | 23 | | `packageof ...` | to locate parent packages | 24 | | `pathof {cache\|mirror\|mirrors\|mirrordir\|cache/mirrordir\|setup.ini}` | to show path | 25 | | `key-add ...` | to add keys contained in \ | 26 | | `key-del ...` | to remove keys \ | 27 | | `key-list` | to list keys | 28 | | `key-finger` | to list fingerprints | 29 | | `upgrade-self` | to upgrade apt-cyg | 30 | | `depends ...` | to show forward dependency information for packages with depth. | 31 | | `rdepends ...` | to show reverse dependency information for packages with depth. | 32 | | `completion-install` | to install completion. | 33 | | `completion-uninstall` | to uninstall completion. | 34 | | `mirrors-list` | to show list of mirrors. | 35 | | `mirrors-list-long` | to show list of mirros with full details. | 36 | | `mirrors-list-online` | to show list of mirrors from online. | 37 | | `benchmark-mirrors ...` | to benchmark mirrors. | 38 | | `benchmark-parallel-mirrors ...` | to benchmark mirrors in parallel. | 39 | | `benchmark-parallel-mirrors-list` | to benchmark mirrors-list in parallel. | 40 | | `scriptinfo` | to show script information. | 41 | | `show-packages-busyness ...` | to show if packages are busy or not. | 42 | | `dist-upgrade` | to upgrade all packages that is installed. This subcommand uses **`setup-*.exe`** | 43 | | `update-setup` | to update setup.exe | 44 | | `setup [ ...]` | to call setup.exe | 45 | | `packages-total-count` | count number of total packages from setup.ini | 46 | | `packages-total-size []` | count size of total packages from setup.ini | 47 | | `packages-cached-count` | count number of cached packages in cache/mirrordir. | 48 | | `packages-cached-size` | count size of cached packages in cache/mirrordir. | 49 | | `repair-acl` | to repair the windows ACL (Access Control List). | 50 | | `repair-postinstall` | Repair postinstall scripts. | 51 | | `source ...` | download source archive. | 52 | | `mirror-source ...` | download the source package into the current cache/mirrordir as mirror. | 53 | | `download ...` | download the binary package into the current directory. | 54 | | `mirror ...` | download the binary package into the current cache/mirrordir as mirror. | 55 | | `browse-homepage-with-mirror-source [ ...]` | Browse homepages of packages with mirror-source. | 56 | | `browse-homepage [ ...]` | Browse homepages of packages. | 57 | | `browse-summary [ ...]` | Browse summaries of packages. | 58 | | `listfiles ...` | List files 'owned' by package(s). | 59 | | `get-proxy` | Get proxies for eval. | 60 | | `ls-categories` | List categories. | 61 | | `ls-pkg-with-category` | List packages with category. | 62 | | `category ` | List all packages in given \.| 63 | | `setuprc-get
` | Get section from **`setup.rc`**. | 64 | | `set-cache []` | Set cache. | 65 | | `set-mirror [ ...]` | Set mirrors. Note: `setup-x86{,_64}.exe` uses all of them but currently `apt-cyg` uses the first one only. | 66 | | `mark-auto [ ...]` | Mark the given packages as automatically installed. | 67 | | `mark-manual [ ...]` | Mark the given packages as manually installed. | 68 | | `mark-showauto` |Print the list of automatically installed packages. | 69 | | `mark-showmanual` | Print the list of manually installed packages. | 70 | | `call [ [ ...]]` | Call internal function in apt-cyg. | 71 | | `time [ [ ...]]` | Report time consumed to call internal function in apt-cyg. | 72 | | `filelist []` | File list like apt-file list. | 73 | | `filesearch []` | File search like apt-file search. | 74 | 75 | ### Options 76 | 77 | | Option | Description | 78 | |:------ |:----------- | 79 | | `--ag` | use the silver searcher (currently work only at packageof subcommand) | 80 | | `--benchmark-timeout ` | Truncate items that take longer than \ when benchmarking | 81 | | `--ignore-case`, `-i` | ignore case distinctions for `` | 82 | | `--force-remove` | force remove 83 | | `--force-fetch-trustedkeys` | force fetch trustedkeys | 84 | | `--force-update-packageof-cache` | force update packageof cache | 85 | | `--no-verify`, `-X` | Don't verify setup.ini signatures | 86 | | `--no-check-certificate` | Don't validate the server's certificate | 87 | | `--no-update-setup` | Don't update setup.exe 88 | | `--no-header` | Don't print header | 89 | | `--proxy`, `-p {auto\|inherit\|none\|}` | set proxy (default: ${APT_CYG_PROXY:-auto}) | 90 | | `--completion-get-subcommand` | get subcommand (for completion internal use) | 91 | | `--completion-disable-autoupdate` | disable completion autoupdate | 92 | | `--max-jobs`, `-j ` | Run \ jobs in parallel | 93 | | `--mirror`, `-m ` | set mirror 94 | | `--mirror-index`, `-M ` | choose mirror from last-mirror list. \ is 0-based index in last-mirror. | 95 | | `--cache`, `-c ` | set cache | 96 | | `--file`, `-f ` | read package names from \ | 97 | | `--noupdate`, `-u` | don't update setup.ini from mirror | 98 | | `--ipv4`, `-4` | wget prefer ipv4 | 99 | | `--no-progress` | hide the progress bar in any verbosity mode | 100 | | `--quiet`, `-q` | quiet (no output) | 101 | | `--verbose`, `-v` | verbose | 102 | | `--help` | Display help and exit | 103 | | `--version` | Display version and exit | 104 | 105 | Requirements 106 | ------------ 107 | 108 | `apt-cyg` requires the Cygwin default environment and the additional *Cygwin* packages: 109 | 110 | `wget`, `ca-certificates`, `gnupg`, `libiconv` 111 | 112 | In **32bit** version of cygwin, `wget` requires an additional setting for the `ca-certificates` package. 113 | Choose one of below settings. 114 | 115 | # 1. Create symbolic link for the default ca-directory of wget. 116 | ln -s /usr/ssl /etc/ 117 | 118 | # or 119 | # 2. Set ca-directory paramete in '/etc/wgetrc'. 120 | echo "ca-directory = /usr/ssl/certs" >> /etc/wgetrc 121 | 122 | # or 123 | # 3. Set ca-directory paramete in '~/.wgetrc'. 124 | echo "ca-directory = /usr/ssl/certs" >> ~/.wgetrc 125 | 126 | Remarks: 127 | Above additional settings for wget is not required for 64bit version of cygwin. 128 | But, as of 2014-01-17, perhaps `ca-certificates` package makes fail of certification in 64bit version of cygwin with Windows 8. See below: 129 | 130 | * Known Problem / [2014-01-17: ca-certificates package is not setup correct at x86_64 with Windows 8.](#2014-01-17-ca-certificates-package-is-not-setup-correct-at-x86_64-with-windows-8) 131 | 132 | Quick start 133 | ----------- 134 | 135 | The most recommended way to deploy this fork can be seen from a link below: 136 | * New features / [Upgrade apt-cyg](#upgrade-apt-cyg) 137 | 138 | apt-cyg is a simple script. Once you have a copy, make it executable: 139 | 140 | chmod +x /bin/apt-cyg 141 | 142 | Optionally place apt-cyg in a bin/ folder on your path. 143 | 144 | Then use apt-cyg, for example: 145 | 146 | apt-cyg install nano 147 | 148 | New features 149 | ------------ 150 | 151 | ### dist-upgrade support 152 | 153 | This fork has achieved `dist-upgrade` command by using `setup-x86.exe` and `setup-x86_64.exe` as a backend. 154 | Note that all of running tasks on the cygwin will be killed before starting dist-upgrade. 155 | 156 | ### Multiple hash algorithms support 157 | 158 | After the middle of 2015-03, the cygwin project changed the hash algorithm for checking tarball from md5 to sha512. 159 | But, as of 2015-04-09, the cygwinports project seems still using md5. 160 | This fork is available for both of cygwin and cygwinports by supporting algorithm of md5, sha1, sha224, sha256 and sha512. 161 | 162 | ### Signature check and key management by GnuPG 163 | 164 | The default action of apt-cyg has been changed to check signature for 'setup.ini'. 165 | Of course you can also avoid signature check by using `--no-verify` or `-X` options. 166 | Public keys of cygwin and cygwinports are already registered to trusted keys of embeded. 167 | If you want to use some other public keys, please use `key-*` subcommands. 168 | 169 | ### Upgrade apt-cyg 170 | 171 | If apt-cyg is under Git version control, this fork can upgrade itself by `upgrade-self` subcommand. 172 | Therefore, the most recommended way to deploy this fork is `copy and paste` below commands to cygwin console: 173 | 174 | # cd $DIR # Change working directory where you want to install apt-cyg 175 | git clone https://github.com/kou1okada/apt-cyg.git 176 | ln -s "$(realpath apt-cyg/apt-cyg)" /usr/local/bin/ 177 | 178 | If you want to use another fork, which forked from https://github.com/kou1okada/apt-cyg, rewrite the URL for apropriate one. 179 | 180 | ### Proxy support 181 | 182 | Use `--proxy`, `-p` option. 183 | This option must take a parameter from one of "auto", "inherit", "none" and URL. 184 | 185 | * "auto" will determine a proxy using a part of the [Web Proxy Auto-Discovery Protocol (WPAD)](http://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol). 186 | The current implementation will look for a string of "PROXY URL" from "http://wpad/wpad.dat". 187 | If "wpad.dat" could not be downloaded, the proxy settings are inherited from the parent environment. 188 | * "inherit" will inherit the proxy settings from the parent environment. 189 | * "none" will not use the proxy. 190 | * URL can take a string like "protocol://hostname:port". 191 | 192 | For example: 193 | 194 | apt-cyg --proxy http://proxy.home:8080 update 195 | 196 | The default parameter is "${APT\_CYG\_PROXY:-auto}". 197 | At the environment where is not provided the WPAD server, it makes the lag for a few seconds at startup. 198 | So, if you don't want to use WPAD, please define APT\_CYG\_PROXY environment variable as below: 199 | 200 | export APT_CYG_PROXY=inherit 201 | 202 | ### Bash completion support 203 | 204 | Bash completion script can be installed to "/etc/bash_completion.d/apt-cyg" by `completion-install` subcommand. 205 | It will be automatically updated when apt-cyg is upgraded to newer version. 206 | If you don't want to update it automatically, execute `completion-install` subcommand in conjunction with `--completion-disable-autoupdate` option. And `completion-uninstall` subcommand removes "/etc/bash_completion.d/apt-cyg". 207 | 208 | Some other forks, [Milly / apt-cyg](https://github.com/Milly/apt-cyg) under the cfg / apt-cyg fork, [ashumkin / apt-cyg](https://github.com/ashumkin/apt-cyg) and etc, are also supported it. 209 | 210 | Contributing 211 | ------------ 212 | 213 | This project has been re-published on GitHub to make contributing easier. Feel free to fork and modify this script. 214 | 215 | The [Google Code project](https://code.google.com/p/apt-cyg/) has a list of open issues. 216 | 217 | ### Forks on the github 218 | 219 | Caution: 220 | Please do not merge forks that have incompatible licenses. 221 | 222 | Ex.) Merging to the GPL from the MIT is possible. But merging to the MIT from the GPL is impossible. 223 | 224 | See [other_forks.md](other_forks.md) 225 | 226 | Todo 227 | ------------ 228 | 229 | - [ ] Support multi mirrors: Cygwin setup can use multi mirrors. They are recorded at last-mirror section in '/etc/setup/setup.rc'. It's useful for using [Cygwinports](http://cygwinports.org/). 230 | - [ ] Support upgrade: But maybe, busy resources can not be upgraded, and rebase problem will happen. Cygwin setup resolves by replacing them at next reboot. 231 | - [ ] Support dependency check for remove subcommand. 232 | 233 | Known Problems 234 | ------------ 235 | 236 | For older known problems see [known_problems.md](known_problems.md). 237 | 238 | License 239 | ------- 240 | 241 | [![The MIT license](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE) 242 | -------------------------------------------------------------------------------- /apt-cyg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # apt-cyg: install tool for cygwin similar to debian apt-get 4 | 5 | # The MIT License (MIT) 6 | # 7 | # Copyright (c) 2013 Trans-code Design 8 | # 9 | # Permission is hereby granted, free of charge, to any person obtaining a copy 10 | # of this software and associated documentation files (the "Software"), to deal 11 | # in the Software without restriction, including without limitation the rights 12 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | # copies of the Software, and to permit persons to whom the Software is 14 | # furnished to do so, subject to the following conditions: 15 | # 16 | # The above copyright notice and this permission notice shall be included in 17 | # all copies or substantial portions of the Software. 18 | # 19 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | # THE SOFTWARE. 26 | # 27 | 28 | shopt -s extglob 29 | 30 | # EMBED_BEGIN: hhs_embed 31 | 32 | (( 5 <= DEBUG )) && set -x 33 | 34 | SCRIPT_PATH="$0" 35 | SCRIPT_FILE="${SCRIPT_PATH##*/}" 36 | SCRIPT_NAME="${SCRIPT_FILE%.*}" 37 | SCRIPT_DIR="${SCRIPT_PATH%/*}" 38 | SCRIPT_REALPATH="$(readlink -f "$SCRIPT_PATH")" 39 | SCRIPT_REALFILE="${SCRIPT_REALPATH##*/}" 40 | SCRIPT_REALNAME="${SCRIPT_REALFILE%.*}" 41 | SCRIPT_REALDIR="${SCRIPT_REALPATH%/*}" 42 | 43 | # EMBED_BEGIN: hhs_sgr.bash 44 | 45 | function init_SGR () 46 | { 47 | if [ -n "$COLORIZE" ]; then 48 | SGR_reset="\e[0m" 49 | SGR_bold="\e[1m" 50 | SGR_fg_red="\e[31m" 51 | SGR_fg_green="\e[32m" 52 | SGR_fg_yellow="\e[33m" 53 | SGR_fg_blue="\e[34m" 54 | SGR_fg_magenta="\e[35m" 55 | else 56 | unset SGR_reset SGR_bold SGR_red SGR_green SGR_yellow SGR_blue SGR_magenta 57 | fi 58 | FATAL_COLOR="${SGR_fg_magenta}${SGR_bold}" 59 | ERROR_COLOR="${SGR_fg_red}${SGR_bold}" 60 | WARNING_COLOR="${SGR_fg_yellow}${SGR_bold}" 61 | INFO_COLOR="${SGR_fg_green}${SGR_bold}" 62 | DEBUG_COLOR="${SGR_fg_blue}${SGR_bold}" 63 | } 64 | 65 | # EMBED_END: hhs_sgr.bash 66 | # EMBED_BEGIN: hhs_debug.bash 67 | 68 | THRESHOLD_OF_FATAL=0 69 | THRESHOLD_OF_ERROR=1 70 | THRESHOLD_OF_WARNING=2 71 | THRESHOLD_OF_INFO=3 72 | THRESHOLD_OF_DEBUG=4 73 | 74 | function abort () #= [EXITCODE=1 [CALLSTACKSKIP=0]] 75 | { 76 | dump_callstack $(( 2 + ${2:-0} )) 77 | exit "${1:-1}" 78 | } 79 | 80 | function dump_callstack () #= [N=1] 81 | #? N is a depth to skip the callstack. 82 | #? $CALLSTACK_SKIP is depth to skip the callstack too. 83 | #? N and CALLSTACK_SKIP is summed before skipping. 84 | #? The default value is N = 1 and CALLSTACK_SKIP = 0. 85 | { 86 | local i 87 | echo "Callstack:" 88 | for i in `seq "$(( ${#FUNCNAME[@]} - 1 ))" -1 $(( ${1:-1} + ${CALLSTACK_SKIP:-0} ))`; do 89 | echo -e "\t${BASH_SOURCE[i]}: ${FUNCNAME[i]}: ${BASH_LINENO[i-1]}" 90 | done 91 | } #/dump_callstack 92 | 93 | function source_at () #= [N=1] 94 | { 95 | local i=${1:-1} 96 | echo -e "${DEBUG_COLOR}at :${SGR_reset} ${BASH_SOURCE[i-1]}: ${FUNCNAME[i]}: ${BASH_LINENO[i-1]}" 97 | } 98 | 99 | function fatal () #= [MESSAGES ...] 100 | { 101 | (( THRESHOLD_OF_FATAL <= ${VERBOSE:-0} )) || return 1 102 | echo -e "${FATAL_COLOR}Fatal:${SGR_reset} $@" 103 | (( THRESHOLD_OF_FATAL <= SOURCE_AT )) && source_at 2 104 | } >&2 #/fatal 105 | 106 | function error () #= [MESSAGES ...] 107 | { 108 | (( THRESHOLD_OF_ERROR <= ${VERBOSE:-0} )) || return 1 109 | echo -e "${ERROR_COLOR}Error:${SGR_reset} $@" 110 | (( THRESHOLD_OF_ERROR <= SOURCE_AT )) && source_at 2 111 | } >&2 #/error 112 | 113 | function warning () #= [MESSAGES ...] 114 | { 115 | (( THRESHOLD_OF_WARNING <= ${VERBOSE:-0} )) || return 1 116 | echo -e "${WARNING_COLOR}Warning:${SGR_reset} $@" 117 | (( THRESHOLD_OF_WARNING <= SOURCE_AT )) && source_at 2 118 | } >&2 #/warning 119 | 120 | function info () #= [MESSAGES ...] 121 | { 122 | (( THRESHOLD_OF_INFO <= ${VERBOSE:-0} )) || return 1 123 | echo -e "${INFO_COLOR}Info:${SGR_reset} $@" 124 | (( THRESHOLD_OF_INFO <= SOURCE_AT )) && source_at 2 125 | } >&2 #/info 126 | 127 | function debug () #= [MESSAGES ...] 128 | { 129 | (( THRESHOLD_OF_DEBUG <= ${VERBOSE:-0} )) || return 1 130 | echo -e "${DEBUG_COLOR}Debug:${SGR_reset} $@" 131 | (( THRESHOLD_OF_DEBUG <= SOURCE_AT )) && source_at 2 132 | } >&2 #/debug 133 | 134 | # EMBED_END: hhs_debug.bash 135 | 136 | : ${VERBOSE:=$THRESHOLD_OF_WARNING} 137 | : ${SOURCE_AT:=$THRESHOLD_OF_WARNING} 138 | : ${COLORIZE:=1} 139 | init_SGR 140 | 141 | # EMBED_END: hhs_embed 142 | 143 | TRUSTEDKEYS=( CYGWIN ); 144 | # ./pubring.asc 145 | # ------------ 146 | # pub 4096R/E2E56300 2020-02-27 [expires: 2026-02-27] 147 | # uid Cygwin 148 | TRUSTEDKEY_CYGWIN_SUM="3666810719f036011944cd6e95f6e73a64be9fffca06c674f2623172e044d5a5eb53fa28d4922429a8c84bd0b8e9fc2d7c4ee0e300d11b9cf934b3c68c76811d" 149 | TRUSTEDKEY_CYGWIN_FPR="56405CF6FCC81574682A5D561A698DE9E2E56300" 150 | TRUSTEDKEY_CYGWIN_URL_LATEST="https://cygwin.com/key/pubring.asc" 151 | 152 | # this script requires some packages 153 | 154 | read WGET < <( type -p wget 2>/dev/null ) 155 | read TAR < <( type -p tar 2>/dev/null ) 156 | read GAWK < <( type -p awk 2>/dev/null ) 157 | read ICONV < <( type -p iconv 2>/dev/null ) 158 | read GPG < <( type -p gpg2 2>/dev/null || type -p gpg 2>/dev/null ) 159 | if [ -z "$WGET" -o -z "$TAR" -o -z "$GAWK" -o -z "$ICONV" ]; then 160 | echo You must install wget, tar, gawk and libiconv to use apt-cyg. 161 | exit 1 162 | fi 163 | 164 | function usage() 165 | { 166 | cat<<-EOD 167 | Usage: apt-cyg [] [ [ ...]] 168 | Installs and removes Cygwin packages. 169 | Subcommands: 170 | install : to install packages 171 | remove : to remove packages 172 | update : to update setup.ini 173 | show : to show installed packages 174 | find ... : to find packages matching patterns 175 | describe ... : to describe packages matching patterns 176 | packageof ... : 177 | to locate parent packages 178 | pathof {cache|mirror|mirros|mirrordir|cache/mirrordir|setup.ini} : 179 | to show path 180 | key-add ... : to add keys contained in 181 | key-del ... : to remove keys 182 | key-list : to list keys 183 | key-finger : to list fingerprints 184 | upgrade-self : to upgrade apt-cyg 185 | depends ... : 186 | to show forward dependency information 187 | for packages with depth. 188 | rdepends ... : 189 | to show reverse dependency information 190 | for packages with depth. 191 | completion-install : to install completion. 192 | completion-uninstall : to uninstall completion. 193 | mirrors-list : to show list of mirros. 194 | mirrors-list-long : to show list of mirros with full details. 195 | mirrors-list-online : to show list of mirros from online. 196 | benchmark-mirrors ... : 197 | to benchmark mirrors. 198 | benchmark-parallel-mirrors ... : 199 | to benchmark mirrors in parallel. 200 | benchmark-parallel-mirrors-list : 201 | to benchmark mirrors-list in parallel. 202 | scriptinfo : to show script information. 203 | show-packages-busyness ... : 204 | to show packages are busy or not. 205 | dist-upgrade : to upgrade all packages that is installed. 206 | This subcommand uses setup.exe 207 | update-setup : to update setup.exe 208 | setup [ ...] : to call setup.exe 209 | packages-total-count : count number of total packages from setup.ini 210 | packages-total-size [] : 211 | count size of total packages from setup.ini 212 | packages-cached-count : count number of cached packages 213 | in cache/mirrordir. 214 | packages-cached-size : count size of cached packages 215 | in cache/mirrordir. 216 | repair-acl : repair acl. 217 | repair-postinstall : Repair postinstall scripts. 218 | source ... : 219 | download source archive. 220 | mirror-source ... : 221 | download the source package 222 | into the current cache/mirrordir as mirror. 223 | download ... : 224 | download the binary package 225 | into the current directory. 226 | mirror ... : 227 | download the binary package 228 | into the current cache/mirrordir as mirror. 229 | browse-homepage-with-mirror-source [ ...] : 230 | Browse homepages of packages with mirror-source. 231 | browse-homepage [ ...] : 232 | Browse homepages of packages. 233 | browse-summary [ ...] : 234 | Browse summaries of packages. 235 | listfiles [ ...] : 236 | List files 'owned' by package(s). 237 | get-proxy : Get proxies for eval. 238 | ls-categories : List categories. 239 | ls-pkg-with-category : List packages with category. 240 | category : List all packages in given . 241 | setuprc-get
: Get section from 'setup.rc'. 242 | set-cache [] : Set cache. 243 | set-mirror [ ...] : 244 | Set mirror. 245 | Note: setup-x86{,_64}.exe uses all of them 246 | but currently apt-cyg uses the first one only. 247 | mark-auto [ ...] : 248 | Mark the given packages 249 | as automatically installed. 250 | mark-manual [ ...] : 251 | Mark the given packages as manually installed. 252 | mark-showauto : Print the list of 253 | automatically installed packages. 254 | mark-showmanual : Print the list of manually installed packages. 255 | call [ [ ...]] : 256 | Call internal function in apt-cyg. 257 | time [ [ ...]] : 258 | Report time consumed 259 | to call internal function in apt-cyg. 260 | filelist [] : File list like apt-file list. 261 | filesearch [] : File search like apt-file search. 262 | Options: 263 | --ag : use the silver searcher 264 | (currently work only at packageof subcommand) 265 | --benchmark-timeout : 266 | Truncate items that take longer than 267 | when benchmarking. 268 | --ignore-case, -i : ignore case distinctions for 269 | --force-remove : force remove 270 | --force-fetch-trustedkeys : 271 | force fetch trustedkeys 272 | --force-update-packageof-cache : 273 | force update packageof cache 274 | --no-verify, -X : Don't verify setup.ini signatures 275 | --no-check-certificate : Don't validate the server's certificate 276 | --no-update-setup : Don't update setup.exe 277 | --no-header : Don't print header 278 | --proxy, -p {auto|inherit|none|} : 279 | set proxy (default: \${APT_CYG_PROXY:-auto}) 280 | --completion-get-subcommand : 281 | get subcommand (for completion internal use) 282 | --completion-disable-autoupdate : 283 | disable completion autoupdate 284 | --max-jobs, -j : Run jobs in parallel 285 | --mirror, -m : set mirror 286 | --mirror-index, -M : choose mirror from last-mirror list. 287 | is 0-based index in last-mirror. 288 | --cache, -c : set cache 289 | --file, -f : read package names from 290 | --noupdate, -u : don't update setup.ini from mirror 291 | --ipv4, -4 : wget prefer ipv4 292 | --no-progress : hide the progress bar in any verbosity mode 293 | --quiet, -q : quiet (no output) 294 | --verbose, -v : verbose 295 | --help : Display help and exit 296 | --version : Display version and exit 297 | EOD 298 | } 299 | 300 | 301 | 302 | function git_status () 303 | { 304 | local origin status 305 | [ ! -d "${SCRIPT_REALDIR%/}/.git" ] && return 1 306 | pushd "${SCRIPT_REALDIR}" >/dev/null 307 | echo 308 | origin="$(git config --get remote.origin.url)" && echo "origin: $origin" 309 | echo "commit: $(git log -1 --pretty=format:"%ai %h%d")" 310 | status="$(git status --short "${SCRIPT_REALNAME}")" 311 | [ -n "$status" ] && echo "status: $status" 312 | popd >/dev/null 313 | } 314 | 315 | function version () 316 | { 317 | cat<<-EOD 318 | kou1okada/apt-cyg 319 | forked from transcode-open/apt-cyg$(git_status) 320 | 321 | This script is based on apt-cyg version 0.57 322 | Copyright (c) 2005-9 Stephen Jungels. Released under the GPL. 323 | Copyright (c) 2013-7 Stephen Jungels. Republished under the MIT license. 324 | EOD 325 | } 326 | 327 | # Usage: verbose [level [msg ...]] 328 | function verbose () 329 | { 330 | (( OPT_VERBOSE_LEVEL < "${1:-1}" )) && return 331 | (( 1 < $# )) && echo "${@:2}" || cat 332 | } >&2 333 | 334 | function update_verbosefor () 335 | # Assign /dev/fd/{1000..1005} for ${verbosefor[0..5]} 336 | { 337 | local i 338 | for i in {0..5}; do 339 | (( OPT_VERBOSE_LEVEL < i )) && eval exec "100$i>/dev/null" || eval exec "100$i>&2" 340 | done 341 | } 342 | 343 | function detect_field_width () 344 | # Read stdin and detect field width. 345 | # Return NF+2 values as follorwing: 346 | # w(0) w(1) w(2) ... w(NF) sum(w(1),w(2), ..., w(NF))+NF-1 347 | # Now NF is a number of fields, 348 | # w(x) is a function of maxium width of field x th 349 | # (note that 0 does not mean the field but the whole line) 350 | # and sum(v1,v2, ..., vn) is a function to sum all arguments. 351 | { 352 | awk ' 353 | function max(a,b){return a [ ...] 370 | # Join strings with separator. 371 | # Note that separator must be single character. 372 | # If you want separator with multiple character, use join_str_ex. 373 | { 374 | (IFS="$1"; printf "%s" "${*:2}") 375 | } 376 | 377 | function join_str_ex () # [ ...] 378 | # Join strings with separator. 379 | # Different for join_str the separator can take multiple character. 380 | { 381 | local str="$(join_str $'\x1c' "${@:2}")" 382 | printf "%s" "${str//$'\x1c'/$1}" 383 | } 384 | 385 | function split_str () # [ ...] 386 | # Split strings with separator. 387 | { 388 | local str=( "${@:2}" ) 389 | (IFS=$'\n'; printf "%s" "${str[*]//$1/$'\n'}") 390 | } 391 | 392 | function join_str_uniq () # [ ...] 393 | # Append values to head of joined strings. 394 | { 395 | local str 396 | readarray -t str < <(split_str "$@" | uniqex) 397 | join_str "$1" "${str[@]}" 398 | } 399 | 400 | function mkdirp () # 401 | { 402 | [ -d "$1" ] || mkdir -p "$1" || { error "mkdir failed: $1"; exit 1; } 403 | } 404 | 405 | function mktmpfn () # -v 406 | # Temporary filename 407 | { 408 | printf ${@:1:2} "/tmp/${SCRIPT_NAME}.$$.%04x%04x" $RANDOM $RANDOM 409 | } 410 | 411 | function init_comspec () 412 | { 413 | : ${SYSTEMPATH:=$(join_str_uniq : "$(cygpath -u "${SYSTEMROOT:-$WINDIR}")"{/system32,} "$PATH")} 414 | } 415 | 416 | function comspec () # [ ...] 417 | # Call $COMSPEC. 418 | { 419 | init_comspec 420 | PATH="$SYSTEMPATH" "$(cygpath "$COMSPEC")" "$@" 421 | } 422 | 423 | function cygstart () # [ ...] 424 | { 425 | init_comspec 426 | PATH="$SYSTEMPATH" cygstart.exe "$@" 427 | } 428 | 429 | function update_cache_for_mirrors_list_online () 430 | { 431 | pushd "$apt_cyg_cachedir" >/dev/null 432 | wget -qN https://cygwin.com/mirrors.lst 433 | popd >/dev/null 434 | } 435 | 436 | function is_official_mirrors_of_cygwin () # ... 437 | # Check whether are listed in official mirrors list of cygwin. 438 | # Official mirros list provides on https://cygwin.com/mirrors.html. 439 | # Args: 440 | # : URLs of the cygwin mirror. 441 | # Return: 442 | # Return zero if all mirrors are known, non-zero otherwise. 443 | { 444 | local mirror 445 | local result=0 446 | local local_list="$(apt-cyg-mirrors-list)" 447 | local online_list="$(apt-cyg-mirrors-list-online)" 448 | for mirror; do 449 | if ! grep -q "$mirror" <<< "$local_list"; then 450 | warning "/etc/setup/setup.rc doesn't know your mirror: ${SGR_bold}$mirror${SGR_reset}" >&2 451 | result=1 452 | fi 453 | if ! grep -q "$mirror" <<< "$online_list"; then 454 | warning "Official mirrors.lst doesn't know your mirror: ${SGR_bold}$mirror${SGR_reset}" >&2 455 | result=1 456 | fi 457 | done 458 | return $result 459 | } 460 | 461 | function mirror_to_mirrordir () # 462 | { 463 | local tmp="${1//:/%3a}" 464 | echo "${tmp//\//%2f}" 465 | } 466 | 467 | function get_utf8_setuprc () 468 | { 469 | local utf8_setuprc="$apt_cyg_cachedir/setup.rc.utf8" 470 | mkdirp "$apt_cyg_cachedir" 471 | [ "$utf8_setuprc" -nt /etc/setup/setup.rc ] && { 472 | cat "$utf8_setuprc" 473 | } || { 474 | cp2utf8 /etc/setup/setup.rc | tee "$utf8_setuprc" 475 | } 476 | } 477 | 478 | function setuprc_import_sections () #
... 479 | { 480 | local IFS="|" 481 | get_utf8_setuprc \ 482 | | awk -vRS='\n\\<|\n\\'\' -vFS='\n\t' -vsections="^${*//\\/\\\\}$" ' 483 | match($1, sections) { 484 | s = gensub(/-/, "_", "g", $1) "=(" 485 | for(i = 2; i <= NF; i++) s = s " \x27" $i "\x27"; 486 | s = s " )"; 487 | print s; 488 | } 489 | ' 490 | } 491 | 492 | function setuprc_get_section () #
493 | { 494 | get_utf8_setuprc \ 495 | | awk -vRS='\n\\<|\n\\'\' -vFS='\n\t' -vsection="${1//\\/\\\\}" ' 496 | $1 == section {for(i = 2; i <= NF; i++) print $i;} 497 | ' 498 | } 499 | 500 | function setuprc_set_section () #
[ ...] 501 | { 502 | local s="$(join_str_ex $'\n\t' "${@}")" 503 | local setuprc="/etc/setup/setup.rc" 504 | local setuprc_bak="${setuprc},$(date -r "$setuprc" "+%Y%m%d_%H%M%S")" 505 | 506 | cp -a "$setuprc" "$setuprc_bak" 507 | 508 | cp2utf8 "$setuprc_bak" \ 509 | | awk -vRS='\n\\<|\n\\'\' -vFS='\n\t' -vsection="${1//\\/\\\\}" -vs="${s//\\/\\\\}" ' 510 | $1 != section 511 | $1 == section {print s; done=1;} 512 | END {if(!done) print s;} 513 | ' \ 514 | | utf82cp > "$setuprc" 515 | } 516 | 517 | function set_cachefile () # 518 | # Set filename of cachevars to $cachefile. 519 | # Returns: 520 | # $cachefile : Overwrite with filename of cachevars. 521 | # Note: 522 | # This is internal function for load_vars_from_cache and save_vars_to_cache. 523 | { 524 | cachefile="$apt_cyg_cachedir/cache_for_vars_of_${FUNCNAME[2]}" 525 | } 526 | 527 | function load_vars_from_cache () # [ ...] || { init_vars ...; save_vars_to_cache [ ...]; } 528 | # restore vars from cache. 529 | { 530 | local cachefile; set_cachefile 531 | local i 532 | set -- "$SCRIPT_PATH" "$@" 533 | for i; do [ "$cachefile" -nt "$i" ] || return 1; done 534 | source "$cachefile" 535 | } 536 | 537 | function save_vars_to_cache () # [ ...] 538 | # save vars to cache. 539 | { 540 | local cachefile; set_cachefile 541 | declare -p "$@" | sed -E 's/^declare .. //g' >"$cachefile" 542 | } 543 | 544 | function findworkspace() 545 | { 546 | local cachevars=( last_cache last_mirror mirror cache arch mirrordir ) 547 | load_vars_from_cache /etc/setup/setup.rc || { 548 | eval "$(setuprc_import_sections last-cache last-mirror)" 549 | 550 | mirror=( "${last_mirror[@]}" ) 551 | cache="$(cygpath -au "$last_cache")" 552 | 553 | cache=( "${cache[@]/%*(\/)/}" ) 554 | mirror=( "${mirror[@]/%*(\/)/}" ) 555 | 556 | readarray -t mirrordir < <(mirror_to_mirrordir "${mirror[@]/%/\/}" ) 557 | 558 | save_vars_to_cache "${cachevars[@]}" 559 | } 560 | [ -z "$OPT_MIRROR_INDEX" ] || { 561 | [[ $OPT_MIRROR_INDEX =~ ^[0-9]+$ ]] || { error "--mirror-index, -M must be 0 <= n: n = $OPT_MIRROR_INDEX"; exit 1; } 562 | mirror=( "${mirror[@]:OPT_MIRROR_INDEX:1}" "${mirror[@]:0:OPT_MIRROR_INDEX}" "${mirror[@]:OPT_MIRROR_INDEX+1}" ) 563 | readarray -t mirrordir < <(mirror_to_mirrordir "${mirror[@]/%/\/}" ) 564 | } 565 | 566 | verbose 1 "Cache directory is $cache" 567 | verbose 1 "Mirror is $mirror" 568 | 569 | mkdirp "$cache/$mirrordir/$arch" 570 | cd "$cache/$mirrordir/$arch" 571 | 572 | init_gnupg 573 | fetch_trustedkeys 574 | } 575 | 576 | function download_and_verify () # 577 | { 578 | local urls=( "$1"{,.sig} ) 579 | wget -N "${urls[@]}" || return 1 580 | if [ -z "$no_verify" ]; then 581 | [ -e "${1##*/}.sig" ] && verify_signatures "${1##*/}.sig" || return 1 582 | fi 583 | [ -e "${1##*/}" ] 584 | } 585 | 586 | function files_backup () 587 | { 588 | local file 589 | for file; do 590 | [ -e "${file}~" ] && mv "${file}~" "${file}" 591 | [ -e "${file}" ] && cp -a "${file}" "${file}~" 592 | done 593 | } 594 | 595 | function files_restore () 596 | { 597 | local file 598 | for file; do 599 | [ -e "${file}" ] && rm "${file}" 600 | [ -e "${file}~" ] && mv "${file}~" "${file}" 601 | done 602 | } 603 | 604 | function files_backup_clean () 605 | { 606 | local file 607 | for file; do 608 | [ -e "${file}~" ] && rm "${file}~" 609 | done 610 | } 611 | 612 | function setupini_download () 613 | { 614 | local BASEDIR="$cache/$mirrordir/$arch" 615 | mkdirp "$BASEDIR" 616 | 617 | [ $noscripts -ne 0 -o $noupdate -ne 0 ] && return 618 | 619 | pushd "$BASEDIR" > /dev/null 620 | files_backup setup.{zst,xz,bz2,ini}{,.sig} 621 | 622 | while true; do 623 | verbose 1 "Updating setup.ini" 624 | false \ 625 | || { download_and_verify "$mirror/$arch/setup.zst" && { zstd -dfkq setup.zst && mv setup{,.ini} && rm -f setup.ini.sig || ! rm -fv setup.zst; }; } \ 626 | || { download_and_verify "$mirror/$arch/setup.xz" && { xz -dfk setup.xz && mv setup{,.ini} && rm -f setup.ini.sig || ! rm -fv setup.xz; }; } \ 627 | || { download_and_verify "$mirror/$arch/setup.bz2" && { bzip2 -dfk setup.bz2 && mv setup{,.ini} && rm -f setup.ini.sig || ! rm -fv setup.bz2; }; } \ 628 | || download_and_verify "$mirror/$arch/setup.ini" || break 629 | 630 | files_backup_clean setup.{zst,xz,bz2,ini}{,.sig} 631 | popd > /dev/null 632 | verbose 1 "Updated setup.ini" 633 | return 634 | done 635 | files_restore setup.{zst,xz,bz2,ini}{,.sig} 636 | popd > /dev/null 637 | error "updating setup.ini failed, reverting." 638 | return 1 639 | } 640 | 641 | function getsetup () 642 | { 643 | setupini_download || return 1 644 | } 645 | 646 | function checkpackages() 647 | { 648 | if [ $# -eq 0 ]; then 649 | echo Nothing to do, exiting 650 | exit 0 651 | fi 652 | } 653 | 654 | function init_gnupg () 655 | { 656 | [ -z "$GPG" -o -n "$no_verify" ] && return 657 | export GNUPGHOME="$cache/.apt-cyg" 658 | if [ ! -d "$GNUPGHOME" ]; then 659 | if ! { mkdir -p "$GNUPGHOME" && chmod 700 "$GNUPGHOME"; } then 660 | error "Cannot initialize directory: $GNUPGHOME" 661 | exit 1 662 | fi 663 | fi 664 | } 665 | 666 | # Usage: ask_user [MESSAGE [OPTIONS]] 667 | function ask_user () 668 | { 669 | local answer retcode option 670 | local MESSAGE="$1" 671 | local OPTIONS="${2:-y/N}" 672 | local DEFAULT="$(echo "$OPTIONS" | awk -v FS=/ '{for(i=1;i<=NF;i++)if(match(substr($i,1,1),/[A-Z]/)){print $i; exit}}')" 673 | local SPLIT_OPTIONS 674 | readarray -t SPLIT_OPTIONS < <(echo "$OPTIONS" | sed -e 's:/:\n:g') 675 | while true; do 676 | echo -n "${MESSAGE}${MESSAGE:+ }[${OPTIONS}] " 677 | read answer 678 | retcode=0 679 | for option in "${SPLIT_OPTIONS[@]}"; do 680 | if [ "$option" = "${answer:-$DEFAULT}" ]; then 681 | return $retcode 682 | fi 683 | retcode=$(( retcode + 1 )) 684 | done 685 | done 686 | } 687 | 688 | unset INIT_WGET 689 | function init_wget () 690 | { 691 | [ -n "$INIT_WGET" ] && return 692 | 693 | eval "$( 694 | "$WGET" --help \ 695 | |& awk ' 696 | /--show-progres/{print "HAVE_SHOW_PROGRESS=--show-progress"} 697 | /--no-verbose/ {print "HAVE_NO_VERBOSE=--no-verbose"} 698 | ')" 699 | (( OPT_VERBOSE_LEVEL < 0 )) && WGET+=( --quiet ) || \ 700 | (( OPT_VERBOSE_LEVEL < 1 )) && WGET+=( --quiet $HAVE_SHOW_PROGRESS ) || \ 701 | (( OPT_VERBOSE_LEVEL < 2 )) && WGET+=( $HAVE_NO_VERBOSE $HAVE_SHOW_PROGRESS ) 702 | 703 | proxy_setup 704 | 705 | INIT_WGET=DONE 706 | } 707 | 708 | function wget () 709 | { 710 | init_wget 711 | "${WGET[@]}" "$@" 712 | } 713 | 714 | # Reference: 715 | # https://www.gnu.org/software/wget/manual/wget.html#Exit-Status 716 | # Usage: wget-exitstatus EXITSTATUS 717 | function wget-exitstatus () 718 | { 719 | case $1 in 720 | 0) echo "No problems occurred.";; 721 | 1) echo "Generic error code.";; 722 | 2) echo "Parse error?for instance, when parsing command-line options, the '.wgetrc' or '.netrc'...";; 723 | 3) echo "File I/O error.";; 724 | 4) echo "Network failure.";; 725 | 5) echo "SSL verification failure.";; 726 | 6) echo "Username/password authentication failure.";; 727 | 7) echo "Protocol errors.";; 728 | 8) echo "Server issued an error response.";; 729 | *) echo "Unknown errors.";; 730 | esac 731 | } 732 | 733 | function wget_advice () 734 | { 735 | local status=${1:-$?} 736 | case $status in 737 | 5) echo "If you can tolerate security risks, use --no-certification option." ;; 738 | esac 739 | return $status 740 | } 741 | 742 | # Usage: get_advice cmd 743 | function get_advice () 744 | { 745 | local status=${2:-$?} 746 | type "${1}_advice" >&/dev/nul && { ( exit $status ); "${1}_advice"; } 747 | return $status 748 | } 749 | 750 | # Usage: push_advice cmd 751 | function push_advice () 752 | { 753 | local status=${2:-$?} 754 | ADVICE+=( "$( get_advice "${1}_advice")" ) 755 | return $status 756 | } 757 | 758 | function show_advice () 759 | { 760 | local i 761 | for i in "${ADVICE[@]}"; do 762 | echo "$i" >&2 763 | done 764 | } 765 | 766 | # Usage: wget_and_hash_check label hash url file 767 | function wget_and_hash_check () 768 | { 769 | local LABEL="$1" 770 | local SUM="$2" 771 | local URL="$3" 772 | local FILE="$4" 773 | if ! { wget "$URL" -O "$FILE" || get_advice wget; }; then 774 | echo "$LABEL: FAILED: Could not download $URL." 775 | return 1 776 | fi 777 | if ! hash_check <<<"$SUM *$FILE" >&/dev/null; then 778 | echo "$LABEL: FAILED: Hash does not match $URL." 779 | return 2 780 | fi 781 | echo "$LABEL: OK" 782 | } 783 | 784 | function get_gpg_fingerprint_to_assoc () # 785 | { 786 | local -n result="$1" 787 | local line lines 788 | readarray -t lines < <("${GPG[@]}" --with-colons --fingerprint) 789 | for line in "${lines[@]}"; do 790 | [[ "$line" =~ ^fpr:+([0-9A-Za-z]+):* ]] && result[${BASH_REMATCH[1]}]=1 791 | done 792 | } 793 | 794 | function fetch_trustedkeys () 795 | { 796 | [ -z "$GPG" -o -n "$no_verify" ] && return 797 | local i 798 | local FILE ; mktmpfn -v FILE 799 | local FILE_LATEST; mktmpfn -v FILE_LATEST 800 | local -A FPRS_assoc; get_gpg_fingerprint_to_assoc FPRS_assoc 801 | for i in "${TRUSTEDKEYS[@]}"; do 802 | local LABEL="TRUSTEDKEY_${i}" 803 | local -n SUM="${LABEL}_SUM" 804 | local -n FPR="${LABEL}_FPR" 805 | local -n URL="${LABEL}_URL" 806 | local -n URL_LATEST="${LABEL}_URL_LATEST" 807 | local CASE="" 808 | if [ -z "$force_fetch_trustedkeys" -a -n "${FPRS_assoc[$FPR]}" ]; then 809 | continue 810 | fi 811 | if [ -n "$URL" ]; then 812 | wget_and_hash_check "$LABEL" "$SUM" "$URL" "$FILE" 813 | CASE+="$?" 814 | else 815 | CASE+="-" 816 | fi 817 | if [ -n "$URL_LATEST" ]; then 818 | wget_and_hash_check "$LABEL" "$SUM" "$URL_LATEST" "$FILE_LATEST" 819 | CASE+="$?" 820 | else 821 | CASE+="-" 822 | fi 823 | case "$CASE" in 824 | 00|01|0-) 825 | "${GPG[@]}" --import "$FILE" 826 | ;; 827 | 02) 828 | warning "${LABEL} has been updated." 829 | "${GPG[@]}" --import "$FILE" 830 | ;; 831 | -0) 832 | "${GPG[@]}" --import "$FILE_LATEST" 833 | ;; 834 | 10|20) 835 | error "${LABEL} has miss configuration." 836 | exit 1 837 | ;; 838 | 11|1-|-1) 839 | error "Could not download ${LABEL}." 840 | exit 1 841 | ;; 842 | 12|-2) 843 | error "${LABEL} has been updated, maybe. But sometimes it may has been cracked. Be careful !!!" 844 | exit 1 845 | ;; 846 | 21|22|2-) 847 | error "${LABEL} has been cracked, maybe" 848 | exit 1 849 | ;; 850 | --) 851 | error "${LABEL} has no URL." 852 | exit 1 853 | ;; 854 | esac 855 | rm "$FILE" "$FILE_LATEST" &>/dev/null 856 | done 857 | } 858 | 859 | # Usage: verify_signatures files ... 860 | function verify_signatures () 861 | { 862 | while [ $# -gt 0 ]; do 863 | if ! "${GPG[@]}" --verify "$1" 1>&1002 2>&1002; then 864 | error "BAD signature: $1" 865 | return 1 866 | else 867 | verbose 0 -e "${SGR_fg_green}${SGR_bold}signature verified:${SGR_reset} $1" 868 | fi 869 | shift 870 | done 871 | } 872 | 873 | # Usage: apt-cyg-key-add pkey ... 874 | function apt-cyg-key-add () 875 | { 876 | [ -z "$GPG" ] && { error "GnuPG is not installed. Prease install gnupg package"; exit 1; } 877 | local pkeys 878 | for pkey; do 879 | pkeys+=( "$(cygpath -a "$pkey" )" ) 880 | done 881 | findworkspace 882 | for pkey in "${pkeys[@]}"; do 883 | "${GPG[@]}" --import "$pkey" 884 | done 885 | } 886 | 887 | # Usage: apt-cyg-key-add keyid ... 888 | function apt-cyg-key-del () 889 | { 890 | [ -z "$GPG" ] && { error "GnuPG is not installed. Prease install gnupg package"; exit 1; } 891 | local keyid 892 | findworkspace 893 | for keyid; do 894 | "${GPG[@]}" --batch --yes --delete-key "$keyid" 895 | done 896 | } 897 | 898 | function apt-cyg-key-list () 899 | { 900 | [ -z "$GPG" ] && { error "GnuPG is not installed. Prease install gnupg package"; exit 1; } 901 | findworkspace 902 | "${GPG[@]}" --list-keys 903 | } 904 | 905 | function apt-cyg-key-finger () 906 | { 907 | [ -z "$GPG" ] && { error "GnuPG is not installed. Prease install gnupg package"; exit 1; } 908 | findworkspace 909 | "${GPG[@]}" --fingerprint 910 | } 911 | 912 | function apt-cyg-pathof () 913 | { 914 | OPT_VERBOSE_LEVEL=0 findworkspace 915 | while [ "$#" -gt 0 ]; do 916 | case "$1" in 917 | cache) echo "$cache" ;; 918 | mirror) echo "$mirror" ;; 919 | mirrors) printf "%s/\n" "${mirror[@]}" ;; 920 | mirrordir) echo "$mirrordir" ;; 921 | cache/mirrordir) echo "$cache/$mirrordir" ;; 922 | setup.ini) echo "$cache/$mirrordir/$arch/setup.ini" ;; 923 | *) 924 | error "unknown parameter: $1" 925 | exit 1 926 | ;; 927 | esac 928 | shift 929 | done 930 | } 931 | 932 | function upgrade-self-with-git () 933 | { 934 | if [ ! -d "$SCRIPT_REALDIR/.git" ]; then 935 | warning "apt-cyg is not under the git version control." 936 | return 1 937 | fi 938 | proxy_setup 939 | pushd "$SCRIPT_REALDIR" > /dev/null 940 | git pull -v 941 | popd > /dev/null 942 | } 943 | 944 | function upgrade-self-with-wget () 945 | { 946 | local updated_url='https://raw.githubusercontent.com/kou1okada/apt-cyg/master/apt-cyg' # TODO: Do not use MAGIC NUMBER 947 | local temp_file; mktmpfn -v temp_file 948 | wget "${updated_url}" -q -O "$temp_file" 949 | chmod +x "$temp_file" 950 | { diff "$temp_file" "$SCRIPT_REALPATH" >/dev/null && exit 0; } || cp "$temp_file" "$SCRIPT_REALPATH" 951 | rm "$temp_file" 952 | } 953 | 954 | function apt-cyg-upgrade-self () 955 | { 956 | upgrade-self-with-git && return 957 | echo "Fall back to wget for upgrade-self." 958 | upgrade-self-with-wget 959 | } 960 | 961 | function proxy_auto () 962 | { 963 | local hash=( $(ipconfig |& md5sum -b) ) 964 | local cache="/tmp/apt-cyg.proxy.$hash" 965 | local last="$(stat -c %Y "$cache" 2>/dev/null)" 966 | local now="$(printf "%(%s)T")" 967 | local proxy 968 | 969 | [ -n "$OPT_PROXY_FORCE_REFRESH" ] && last=0 970 | if (( (now - ${last:-0}) < OPT_PROXY_REFRESH_INTERVAL )); then 971 | read proxy < "$cache" 972 | else 973 | read proxy < <( 974 | "${WGET[@]}" --no-proxy -q -O - wpad/wpad.dat \ 975 | | sed -nE 's@//.*@@g;/PROXY/s@^.*PROXY\s*([^"; ]*).*$@http://\1@gp' 976 | ) 977 | echo "$proxy" > "$cache" 978 | fi 979 | [ -n "$proxy" ] && proxy_set "$proxy" 980 | } 981 | 982 | function proxy_set () 983 | { 984 | export http_proxy="$1" 985 | export https_proxy="$1" 986 | export ftp_proxy="$1" 987 | } 988 | 989 | function proxy_unset () 990 | { 991 | export -n http_proxy 992 | export -n https_proxy 993 | export -n ftp_proxy 994 | } 995 | 996 | unset PROXY_SETUP 997 | function proxy_setup () 998 | { 999 | [ -n "$PROXY_SETUP" ] && return 1000 | case "$OPT_PROXY" in 1001 | auto) 1002 | proxy_auto 1003 | ;; 1004 | inherit) 1005 | ;; 1006 | none) 1007 | proxy_unset 1008 | ;; 1009 | *) 1010 | proxy_set "$OPT_PROXY" 1011 | ;; 1012 | esac 1013 | PROXY_SETUP=DONE 1014 | } 1015 | 1016 | function apt-cyg-get-proxy () 1017 | { 1018 | proxy_setup 1019 | declare -p ftp_proxy http_proxy https_proxy 1020 | } 1021 | 1022 | # Usage: get_pkgname PKGFILE 1023 | function get_pkgname () 1024 | { 1025 | local tarball="${1##*/}" 1026 | echo "$tarball" | sed -re's/-[0-9].*//g' 1027 | } 1028 | 1029 | # PACKAGE_DB is defined at package_db.cc in the cygwin-app setup.exe 1030 | # See blow: 1031 | # https://www.sourceware.org/cygwin-apps/setup.html 1032 | # https://sourceware.org/cgi-bin/cvsweb.cgi/setup/package_db.cc?cvsroot=cygwin-apps 1033 | PACKAGE_DB="/etc/setup/installed.db" 1034 | 1035 | function package_db-version_check () 1036 | { 1037 | [ -n "$PACKAGE_DB_VERSION_CHECK_DONE" ] && return 1038 | 1039 | local vernhdr='INSTALLED\.DB [0-9]+' 1040 | local line1; read line1 < "${PACKAGE_DB}" 1041 | local dbver=1 1042 | 1043 | if [[ "$line1" =~ ^INSTALLED\.DB[[:space:]]+([0-9]+)$ ]]; then 1044 | dbver="${BASH_REMATCH[1]}" 1045 | else 1046 | warning "${PACKAGE_DB} does not have version header. The first line is below:\n" \ 1047 | "$(head -n1 "${PACKAGE_DB}")\n" 1048 | 1049 | # The earlyer version of apt-cyg was not treat version header correctly. 1050 | if grep -EHnx "${vernhdr}" "${PACKAGE_DB}" >&2; then 1051 | echo "The above line looks like version header, but it is not the first line." >&2 1052 | fi 1053 | fi 1054 | 1055 | if (( dbver < 3 )); then 1056 | warning "${PACKAGE_DB} version is less than 3.\n" \ 1057 | "Before continuing, recommend to execute below command:\n" \ 1058 | " apt-cyg dist-upgrade" 1059 | ask_user "Do you continue?" >&2 && { 1060 | echo "continue" >&2 1061 | } || { 1062 | echo "abort" >&2 1063 | exit 1 1064 | } 1065 | elif (( 3 < dbver )); then 1066 | error "${PACKAGE_DB} has unknown version header.\n" \ 1067 | "Currently apt-cyg supports the DB of ver 3 or ealyer, but your DB is ver $dbver.\n" 1068 | ask_user "Do you want to continue at your own risk?" >&2 && { 1069 | echo "continue" >&2 1070 | } || { 1071 | echo "abort" >&2 1072 | exit 1 1073 | } 1074 | fi 1075 | 1076 | PACKAGE_DB_VERSION_CHECK_DONE=1 1077 | } 1078 | 1079 | # Usage: package_db-is_registered PKGNAME 1080 | function package_db-is_registered () 1081 | { 1082 | package_db-version_check 1083 | 1084 | awk ' 1085 | $1 == PKGNAME && NF != 2 {found = 1; exit} 1086 | END {exit !found} 1087 | ' PKGNAME="$1" "${PACKAGE_DB}" 1088 | } 1089 | 1090 | function package_db-list () 1091 | { 1092 | package_db-version_check 1093 | 1094 | awk ' 1095 | NF == 3 { 1096 | version = gensub(/^(.*)\.(tgz|tbz|tbz2|tb2|taz|tz|tlz|txz|tar\.(gz|bz2|Z|lz|lzma|xz|zst))$/, "\\1", 1, substr($2, length($1) + 2)); 1097 | printf("%s %s %s\n", $1, version, $3); 1098 | } 1099 | ' "${PACKAGE_DB}" 1100 | } 1101 | 1102 | # Usage: package_db-register PKGFILE USER_PICKED=0 1103 | function package_db-register () 1104 | { 1105 | local pkgfile="${1##*/}" 1106 | local pkgname="$(get_pkgname "$pkgfile")" 1107 | local user_picked="${2:-0}" 1108 | local work="/tmp/apt-cyg.$$.${PACKAGE_DB##*/}" 1109 | 1110 | package_db-version_check 1111 | 1112 | awk ' 1113 | function register() {print PKGNAME " " PKGFILE " " USER_PICKED; registered = 1;} 1114 | !registered && PKGNAME < $1 && NF != 2 {register()} 1115 | {print $0} 1116 | END {if (!registered) register()} 1117 | ' PKGNAME="$pkgname" PKGFILE="${pkgfile}" USER_PICKED="${user_picked}" "${PACKAGE_DB}" > "${work}" 1118 | 1119 | mv "${PACKAGE_DB}" "${PACKAGE_DB}-save" 1120 | mv "${work}" "${PACKAGE_DB}" 1121 | } 1122 | 1123 | function package_db_change_mark () # [ ...] 1124 | # Change marks of package in PACKAGE_DB. 1125 | # means that 0 was automatically installed 1126 | # and 1 was manually installed. 1127 | { 1128 | local user_picked="$1" 1129 | local PACKAGE_NAMES="$(join_str $'\x1c' "${@:2}")" 1130 | local work="/tmp/apt-cyg.$$.${PACKAGE_DB##*/}" 1131 | 1132 | package_db-version_check 1133 | 1134 | awk -vPACKAGE_NAMES="$PACKAGE_NAMES" -vUSER_PICKED="$user_picked" ' 1135 | BEGIN { 1136 | split(PACKAGE_NAMES, package_names, "\x1c"); 1137 | for(i in package_names) target[package_names[i]]=1; 1138 | label = USER_PICKED ? "manually" : "automatically"; 1139 | } 1140 | NF==2 1141 | NF!=2&&!target[$1] 1142 | NF!=2&& target[$1] { 1143 | msg = $1 " was " ($3==USER_PICKED?"already ":"") "set to " label " installed."; 1144 | $3 = USER_PICKED; 1145 | print $0; 1146 | print msg > "/dev/stderr" 1147 | } 1148 | ' "${PACKAGE_DB}" 2>&1 >"${work}" 1149 | 1150 | mv "${PACKAGE_DB}" "${PACKAGE_DB}-save" 1151 | mv "${work}" "${PACKAGE_DB}" 1152 | } 1153 | 1154 | 1155 | # Usage: package_db-unregister PKGNAME 1156 | function package_db-unregister () 1157 | { 1158 | local work="/tmp/apt-cyg.$$.${PACKAGE_DB##*/}" 1159 | 1160 | package_db-version_check 1161 | 1162 | awk '!(PKGNAME == $1 && NF != 2) {print $0}' PKGNAME="$1" "${PACKAGE_DB}" > "${work}" 1163 | 1164 | mv "${PACKAGE_DB}" "${PACKAGE_DB}-save" 1165 | mv "${work}" "${PACKAGE_DB}" 1166 | } 1167 | 1168 | # Usage: dep_check DIR ROOTPKGS ... 1169 | # Parameters: 1170 | # DIR is "depends" or "rdepends". 1171 | # ROOTPKGS is root package names to check dependency. 1172 | # Return: 1173 | # package_name available shallow_depth deep_depth 1174 | function dep_check () 1175 | { 1176 | awk \ 1177 | ' 1178 | function min(x,y) {return x < y ? x : y} 1179 | function max(x,y) {return x < y ? y : x} 1180 | function update_result(dir, rootpkg, pkg, depth, _, i) { 1181 | if (0 + result[rootpkg, pkg, "deep"]) { 1182 | result[rootpkg, pkg, "shallow"] = min(depth, result[rootpkg, pkg, "shallow"]); 1183 | result[rootpkg, pkg, "deep"] = max(depth, result[rootpkg, pkg, "deep"]); 1184 | } else { 1185 | result[rootpkg, pkg, "deep"] = result[rootpkg, pkg, "shallow"] = depth; 1186 | result[rootpkg, pkg, "available"] = 0 + available[pkg]; 1187 | result[rootpkg, result[rootpkg, "n"]++] = pkg; 1188 | for (i = 0; i < dep[dir, pkg, "n"]; i++) { 1189 | update_result(dir, rootpkg, dep[dir, pkg, i], depth + 1); 1190 | } 1191 | } 1192 | } 1193 | $1 == "@" { 1194 | pkg = $2; 1195 | available[pkg] = 1; 1196 | } 1197 | $1 == "requires:" || $1 == "depends2:" { 1198 | for (req = 2; req <= NF; req++) { 1199 | reqpkg = gensub(/,$/, "", "g", $req); 1200 | dep["rdepends", reqpkg, dep["rdepends", reqpkg, "n"]++] = pkg; 1201 | dep["depends" , pkg , dep["depends" , pkg , "n"]++] = reqpkg; 1202 | } 1203 | } 1204 | END { 1205 | split(ROOTPKGS, rootpkgs, "\x1c"); 1206 | for (k in rootpkgs) { 1207 | update_result(DIR, rootpkgs[k], rootpkgs[k], 1); 1208 | for(i = 0; i < result[rootpkgs[k], "n"]; i++) { 1209 | printf("%-40s %d\t%d\t%d\n", 1210 | result[rootpkgs[k], i], 1211 | result[rootpkgs[k], result[rootpkgs[k], i], "available"], 1212 | result[rootpkgs[k], result[rootpkgs[k], i], "shallow"], 1213 | result[rootpkgs[k], result[rootpkgs[k], i], "deep"]); 1214 | } 1215 | } 1216 | } 1217 | ' \ 1218 | DIR="$1" ROOTPKGS="$(join_str $'\x1c' "${@:2}")" "$(apt-cyg-pathof "setup.ini")" \ 1219 | | awk ' 1220 | function min(x,y) {return x < y ? x : y} 1221 | function max(x,y) {return x < y ? y : x} 1222 | { 1223 | packages[$1] = pkg = $1; 1224 | status[pkg, "available"] = $2; 1225 | status[pkg, "shallow" ] = 0 + status[pkg, "shallow"] == 0 ? $3 : min(status[pkg, "shallow"], $3); 1226 | status[pkg, "deep" ] = max(0 + status[pkg, "deep"], $4); 1227 | } 1228 | END { 1229 | for (pkg in packages) { 1230 | printf("%-40s %d\t%d\t%d\n", 1231 | pkg, 1232 | status[pkg, "available"], 1233 | status[pkg, "shallow"], 1234 | status[pkg, "deep"]) 1235 | } 1236 | } 1237 | ' | sort -nrk4 1238 | } 1239 | 1240 | function apt-cyg-depends () 1241 | { 1242 | local pkg 1243 | [ -z "$OPT_NO_HEADER" ] && printf "%-40s %s\t%s\t%s\n" "PKGNAME" "AVAIL" "SHALLOW" "DEEP" 1244 | dep_check depends "$@" 1245 | } 1246 | 1247 | function apt-cyg-rdepends () 1248 | { 1249 | local pkg 1250 | [ -z "$OPT_NO_HEADER" ] && printf "%-40s %s\t%s\t%s\n" "PKGNAME" "AVAIL" "SHALLOW" "DEEP" 1251 | dep_check rdepends "$@" 1252 | } 1253 | 1254 | function get_module_line () # [] 1255 | # Return line numbers of module about begin and end. 1256 | { 1257 | grep -nE "^#\s*(BEGIN|END)_MODULE\s*:\s*${1}" "${@:2:1}" | grep -Eo '^[0-9]+' 1258 | } 1259 | 1260 | # EMBED_BEGIN: hhs_utils.bash 1261 | 1262 | function headtail () # [] 1263 | # Split lines from to . 1264 | { 1265 | head -n+$2 "${@:3:1}" | tail -n+$1 1266 | } 1267 | 1268 | function uniqex () 1269 | # An alternative uniq command which is not required sort 1270 | { 1271 | awk '!c[$0]++' 1272 | } 1273 | 1274 | # EMBED_END: hhs_utils.bash 1275 | 1276 | function replace_range # [] 1277 | { 1278 | awk -vl1=$1 -vl2=$2 -vs="${3//\\/\\\\}" ' 1279 | NR < l1 || l2 < NR 1280 | !done && l1 <= NR {print s;done=1;} 1281 | ' "${@:4:1}" 1282 | } 1283 | 1284 | function replace_module # 1285 | { 1286 | local tmpfile; mktmpfn -v tmpfile 1287 | local srclines=( $(get_module_line "bash completion for apt-cyg" "$2") ) 1288 | local dstlines=( $(get_module_line "bash completion for apt-cyg" "$3") ) 1289 | replace_range "${dstlines[@]}" "$(headtail "${srclines[@]}" "$2")" "$3" > "$tmpfile" 1290 | mv "$tmpfile" "$3" 1291 | } 1292 | 1293 | function apt-cyg-completion-install () 1294 | { 1295 | if [ ! -d "/etc/bash_completion.d" ]; then 1296 | error "/etc/bash_completion.d is not exist." 1297 | exit 1 1298 | fi 1299 | if ! package_db-is_registered "bash-completion"; then 1300 | error "bash-completion is not installed." 1301 | exit 1 1302 | fi 1303 | 1304 | local __APT_CYG_SUBCMDS 1305 | local __APT_CYG_OPTIONS 1306 | local __APT_CYG_SCRIPTPATH="$(realpath "$(type -p apt-cyg)")" 1307 | local __APT_CYG_SCRIPTDIR="${__APT_CYG_SCRIPTPATH%/*}" 1308 | local __APT_CYG_COMPLETION_DISABLE_AUTOUPDATE="$OPT_COMPLETION_DISABLE_AUTOUPDATE" 1309 | 1310 | readarray -t __APT_CYG_SUBCMDS < <(grep "^function " "$__APT_CYG_SCRIPTPATH" | awk 'match($2, /apt-cyg-([-_0-9A-Za-z]+)/,m){print m[1]}') 1311 | readarray -t __APT_CYG_OPTIONS < <( 1312 | awk ' 1313 | /^function *parse_args *\(\)/ {proc=1} 1314 | /^} *# *\/parse_args( |$)/ {proc=0} 1315 | proc && match($0, /^ *(-[^()*]+)\)/, m) { 1316 | split(m[1], x, "|"); 1317 | for (i in x) print x[i]; 1318 | } 1319 | ' "$__APT_CYG_SCRIPTPATH" 1320 | ) 1321 | 1322 | cat <<-EOD > /etc/bash_completion.d/apt-cyg 1323 | $(declare -p __APT_CYG_{SUBCMDS,OPTIONS,SCRIPTPATH,SCRIPTDIR,COMPLETION_DISABLE_AUTOUPDATE} | sed -E 's/^declare/\0 -g/g') 1324 | 1325 | # BEGIN_MODULE: bash completion for apt-cyg 1326 | # END_MODULE: bash completion for apt-cyg 1327 | 1328 | complete -o filenames -F __apt-cyg apt-cyg 1329 | EOD 1330 | 1331 | replace_module "bash completion for apt-cyg" "${BASH_SOURCE}" /etc/bash_completion.d/apt-cyg 1332 | touch -r "$__APT_CYG_SCRIPTPATH" "/etc/bash_completion.d/apt-cyg" 1333 | 1334 | echo "A bash completion /etc/bash_completion.d/apt-cyg is installed" 1335 | } 1336 | 1337 | # BEGIN_MODULE: bash completion for apt-cyg 1338 | 1339 | function __apt-cyg () 1340 | { 1341 | local cur prev getsubcmd subcmd 1342 | 1343 | # Auto update for completion script. 1344 | if [ -z "$__APT_CYG_COMPLETION_DISABLE_AUTOUPDATE" -a "$__APT_CYG_SCRIPTPATH" -nt "/etc/bash_completion.d/apt-cyg" ]; then 1345 | apt-cyg completion-install >/dev/null 2>&1 1346 | . /etc/bash_completion.d/apt-cyg 1347 | __apt-cyg "$@" 1348 | return 1349 | fi 1350 | 1351 | _get_comp_words_by_ref -n : cur prev 1352 | 1353 | getsubcmd=( apt-cyg --completion-get-subcommand $(echo "${COMP_LINE}" | sed -E 's/^[ \t]*[^ \t]+//g;s/[^ \t]+$//g') ) 1354 | subcmd="$( "${getsubcmd[@]}" )" 1355 | mirroridxopt=( $(echo ${COMP_LINE} | awk 'BEGIN { RS=" " } /^-M|--mirror-index$/ { if(getline) printf "-M %s", $1 }') ) 1356 | 1357 | case "$subcmd" in 1358 | install|depends|rdepends|describe|find|category) 1359 | COMPREPLY=( $(awk '/^@ /{print $2}' "$(apt-cyg pathof "${mirroridxopt[@]}" setup.ini)") ) 1360 | ;; 1361 | remove) 1362 | COMPREPLY=( $(apt-cyg --no-header show 2>/dev/null | awk '$0=$1') ) 1363 | ;; 1364 | pathof) 1365 | COMPREPLY=( cache mirror mirrors mirrordir cache/mirrordir setup.ini ) 1366 | ;; 1367 | *) 1368 | COMPREPLY=( "${__APT_CYG_SUBCMDS[@]}" ) 1369 | ;; 1370 | esac 1371 | case "$prev" in 1372 | --cache|-c) 1373 | readarray -t COMPREPLY < <(compgen -d -- "$cur") 1374 | ;; 1375 | --mirror|-m) 1376 | COMPREPLY=( $(apt-cyg mirrors-list) ) 1377 | ;; 1378 | --file|-f) 1379 | readarray -t COMPREPLY < <(compgen -f -- "$cur") 1380 | ;; 1381 | --proxy|-p) 1382 | COMPREPLY=( auto inherit none http:// ) 1383 | ;; 1384 | --mirror-index|-M) 1385 | COMPREPLY=( $(seq 0 $(($(apt-cyg pathof mirrors | wc -w)-1))) ) 1386 | ;; 1387 | *) 1388 | COMPREPLY+=( "${__APT_CYG_OPTIONS[@]}" ) 1389 | ;; 1390 | esac 1391 | if [ -n "$DEBUG_COMPLETION" ]; then 1392 | echo 1393 | declare -p BASH_SOURCE "${!COMP@}" getsubcmd subcmd cur prev 1394 | echo -n "${PS1@P}" 1395 | [[ "$COMP_LINE" =~ ^\ ]] && echo -n "time" # maybe... 1396 | echo -n "${COMP_LINE}" 1397 | (( ${#COMP_LINE} - COMP_POINT )) && echo -ne "\e[$(( ${#COMP_LINE} - COMP_POINT ))D" 1398 | fi 1399 | readarray -t COMPREPLY < <(compgen -W "${COMPREPLY[*]@Q}" -- "$cur") 1400 | __ltrim_colon_completions "$cur" 1401 | } 1402 | 1403 | # END_MODULE: bash completion for apt-cyg 1404 | 1405 | function apt-cyg-completion-uninstall () 1406 | { 1407 | if [ ! -f /etc/bash_completion.d/apt-cyg ]; then 1408 | error "/etc/bash_completion.d/apt-cyg is not exist." 1409 | exit 1 1410 | fi 1411 | rm /etc/bash_completion.d/apt-cyg 1412 | echo "A bash completion /etc/bash_completion.d/apt-cyg is uninstalled" 1413 | } 1414 | 1415 | function apt-cyg-mirrors-list () 1416 | { 1417 | setuprc_get_section mirrors-lst | sed -re 's/;.*//g' 1418 | } 1419 | 1420 | function apt-cyg-mirrors-list-long () 1421 | { 1422 | setuprc_get_section mirrors-lst | column -t -s ";" 1423 | } 1424 | 1425 | function apt-cyg-mirrors-list-online () 1426 | { 1427 | update_cache_for_mirrors_list_online 1428 | cat "${apt_cyg_cachedir}/mirrors.lst" 1429 | } 1430 | 1431 | function apt-cyg-benchmark-mirrors () 1432 | { 1433 | local mirror result exitcode 1434 | local WGET=( wget ) 1435 | [ -n "$OPT_BENCHMARK_TIMEOUT" ] && WGET=( timeout "$OPT_BENCHMARK_TIMEOUT" "${WGET[@]}" ) 1436 | for mirror; do 1437 | result="$( { time "${WGET[@]}" -qO/dev/null -T3 -t 1 "${mirror%/}/$arch/setup.bz2"; } 2>&1 )" 1438 | exitcode=$? 1439 | if [ $exitcode -ne 0 ];then 1440 | if [ $exitcode -eq 124 ]; then 1441 | echo -e "Timeout:\t${mirror}" >&2 1442 | else 1443 | warning "benchmark failed with wget exitcode $exitcode: $(wget-exitstatus $exitcode): $1" 1444 | fi 1445 | continue 1446 | fi 1447 | [[ "$result" =~ real[^0-9]*([0-9]*m[0-9.]*s) ]] && echo -e "${BASH_REMATCH[1]}\t${mirror}" 1448 | done 1449 | } 1450 | 1451 | function apt-cyg-benchmark-parallel-mirrors () 1452 | { 1453 | local result; mktmpfn -v result 1454 | local mirror 1455 | for mirror; do echo $mirror; done | lesser-parallel apt-cyg-benchmark-mirrors {} | tee "$result" 1456 | echo Finished benchmark. 1457 | echo ======================================== 1458 | echo Sorted result. 1459 | sort -rV "$result" 1460 | rm "$result" 1461 | } 1462 | 1463 | function apt-cyg-benchmark-parallel-mirrors-list () 1464 | { 1465 | local mirrors 1466 | readarray -t mirrors < <(apt-cyg-mirrors-list) 1467 | apt-cyg-benchmark-parallel-mirrors "${mirrors[@]}" 1468 | } 1469 | 1470 | function apt-cyg-scriptinfo () 1471 | { 1472 | cat<<-EOD 1473 | SCRIPT_PATH = "$SCRIPT_PATH" 1474 | SCRIPT_FILE = "$SCRIPT_FILE" 1475 | SCRIPT_NAME = "$SCRIPT_NAME" 1476 | SCRIPT_DIR = "$SCRIPT_DIR" 1477 | SCRIPT_REALPATH = "$SCRIPT_REALPATH" 1478 | SCRIPT_REALFILE = "$SCRIPT_REALFILE" 1479 | SCRIPT_REALNAME = "$SCRIPT_REALNAME" 1480 | SCRIPT_REALDIR = "$SCRIPT_REALDIR" 1481 | EOD 1482 | } 1483 | 1484 | # Usage: isbusy [file ...] 1485 | function isbusy () 1486 | { 1487 | perl -e 'foreach $i(@ARGV){if(-f $i){open(DATAFILE,"+<",$i)||exit(0);close(DATAFILE);}}exit(1);' -- "$@" 1488 | } 1489 | 1490 | function apt-cyg-show-packages-busyness () 1491 | { 1492 | local pkg lst files 1493 | for pkg; do 1494 | lst="/etc/setup/${pkg}.lst.gz" 1495 | if [ -e "$lst" ]; then 1496 | readarray -t files < <(gzip -dc "$lst"|sed 's:^:/:g') 1497 | isbusy "${files[@]}" && echo -n "busy: " || echo -n "free: " 1498 | echo "$pkg" 1499 | fi 1500 | done 1501 | } 1502 | 1503 | unset CODEPAGE 1504 | 1505 | function get_codepage_wt_chcp () 1506 | { 1507 | comspec /c chcp.com \ 1508 | | awk 'match($NF, /([0-9]+)/, m) { print m[1] == "20127" ? "US-ASCII" : ("CP" m[1]) }' 1509 | } 1510 | 1511 | function get_codepage () 1512 | { 1513 | echo -n "${CODEPAGE:=$(get_codepage_wt_chcp)}" 1514 | } 1515 | 1516 | function cp2utf8 () # [ ...] 1517 | { 1518 | iconv -f $(get_codepage) -t UTF-8 "$@" 1519 | } 1520 | 1521 | function utf82cp () # [ ...] 1522 | { 1523 | iconv -f UTF-8 -t $(get_codepage) "$@" 1524 | } 1525 | 1526 | # dummy command for unknown sum. 1527 | # Usage: unknownsum 1528 | function unknownsum () 1529 | { 1530 | return 1 1531 | } 1532 | 1533 | # Determine the hash method from a HASH. 1534 | # Usage: hash_method HASH 1535 | function hash_method () 1536 | { 1537 | case "${#1}" in 1538 | 32) echo md5 ;; 1539 | 40) echo sha1 ;; 1540 | 56) echo sha224 ;; 1541 | 64) echo sha256 ;; 1542 | 96) echo sha384 ;; 1543 | 128) echo sha512 ;; 1544 | *) echo unknown ;; 1545 | esac 1546 | } 1547 | 1548 | # Read md5 and sha{1,224,256,384,512} sums from the FILEs and check them. 1549 | # Usage: hash_check [FILE ...] 1550 | function hash_check () 1551 | { 1552 | local f0 f1 f2 method count=0 1553 | while true; do 1554 | while read f0; do 1555 | f1="${f0% *}" 1556 | f2="${f0#*\*}" 1557 | method="$(hash_method "$f1")sum" 1558 | if echo "$f0" | "$method" -c --status; then 1559 | verbose 0 "hash_check: $method: $f2: OK" 1560 | else 1561 | verbose 0 "hash_check: $method: $f2: FAILED" 1562 | count=$(( count + 1 )) 1563 | fi 1564 | done 0<${1:-<(cat)} 1565 | shift 1566 | (( $# <= 0 )) && break 1567 | done 1568 | if (( 0 < count )); then 1569 | verbose 0 "hash_check: WARNING: $count computed checksum did NOT match" 1570 | return 1 1571 | fi 1572 | return 0 1573 | } 1574 | 1575 | function kill_all_cygwin_process () 1576 | { 1577 | local family 1578 | local pid=$BASHPID 1579 | local pslog=$(ps -f | tail -n +2 | awk '{print $2, $3}') 1580 | readarray -t family < <(echo "$pslog" | awk -v pid=$pid ' 1581 | {ppids[$1] = $2;} 1582 | END {while (1 < pid) {print "-e\n"pid; pid = ppids[pid];}} 1583 | ') 1584 | kill -9 $(echo "$pslog" | grep -v "${family[@]}" | awk '{print $1}') ${family[$((${#family[@]} - 1))]} 1585 | } 1586 | 1587 | function apt-cyg-update-setup () 1588 | { 1589 | [ -n "$OPT_NO_UPDATE_SETUP" ] && return 1590 | local TARGETS=( "${SETUP_EXE}" "${SETUP_EXE}.sig" ) 1591 | 1592 | pushd . > /dev/null 1593 | findworkspace 1594 | popd > /dev/null 1595 | pushd "$(apt-cyg-pathof cache)" > /dev/null 1596 | files_backup "${TARGETS[@]}" 1597 | if download_and_verify "https://cygwin.com/${SETUP_EXE}"; then 1598 | files_backup_clean "${TARGETS[@]}" 1599 | chmod +x "${SETUP_EXE}" 1600 | ls -l "${SETUP_EXE}" >&1002 1601 | else 1602 | files_restore "${TARGETS[@]}" 1603 | error "${SETUP_EXE} could not be downloaded: Rollbacked it and aborted." 1604 | exit 1 1605 | fi 1606 | 1607 | popd > /dev/null 1608 | } 1609 | 1610 | function apt-cyg-setup () 1611 | { 1612 | pushd "$(apt-cyg-pathof cache)" > /dev/null 1613 | 1614 | local setup=( "$PWD/${SETUP_EXE}" -R "$(cygpath -wa /)" "$@" ) 1615 | 1616 | apt-cyg-update-setup 1617 | cd /etc/setup 1618 | "${setup[@]}" 1619 | 1620 | popd > /dev/null 1621 | } 1622 | 1623 | function apt-cyg-dist-upgrade-no-ask () 1624 | { 1625 | pushd "$(apt-cyg-pathof cache)" > /dev/null 1626 | 1627 | local setup=( "$(cygpath -wa "$PWD")\\${SETUP_EXE}" -R "$(cygpath -wa /)" -B -q -n -g) 1628 | 1629 | apt-cyg-update-setup 1630 | cd /etc/setup 1631 | cygstart "$COMSPEC" /c 'ECHO Press any key to start dist-upgrade for cygwin '"$arch"' && PAUSE && START /WAIT '"${setup[@]}"' && ash -c "/bin/rebaseall -v" && ECHO dist-upgrade is finished && ECHO Press any key to exit && PAUSE' # ' 1632 | kill_all_cygwin_process 1633 | 1634 | popd > /dev/null 1635 | } 1636 | 1637 | function apt-cyg-dist-upgrade () 1638 | { 1639 | echo "Kill all cygwin process and start dist-upgrade." 1640 | ask_user "Are you sure ?" && { 1641 | echo "Start dist-upgrade ..." 1642 | sleep 1 1643 | apt-cyg-dist-upgrade-no-ask 1644 | } || { 1645 | echo "Abort." 1646 | } 1647 | } 1648 | 1649 | function apt-cyg-packages-total-count () 1650 | { 1651 | grep ^@ <"$(apt-cyg-pathof setup.ini)" | wc -l 1652 | } 1653 | 1654 | # Usage: apt-cyg-packages-total-size [pattern_of_section] 1655 | function apt-cyg-packages-total-size () 1656 | { 1657 | local section="^$" 1658 | (( 0 < $# )) && section="$1" 1659 | 1660 | awk -v SECTION="$section" ' 1661 | /^@ [ -~]+ *$/ {section = ""} 1662 | match($0,/^\[([ -~]*)\] *$/,m) {section = m[1]} 1663 | match(section, SECTION) && $1 == "install:" {sum += $3} 1664 | END {print sum} 1665 | ' "$(apt-cyg-pathof setup.ini)" 1666 | } 1667 | 1668 | function apt-cyg-packages-cached-count () 1669 | { 1670 | pushd "$(apt-cyg-pathof cache/mirrordir)" > /dev/null 1671 | find . -type f | grep tar | wc -l 1672 | popd > /dev/null 1673 | } 1674 | 1675 | function apt-cyg-packages-cached-size () 1676 | { 1677 | pushd "$(apt-cyg-pathof cache/mirrordir)" > /dev/null 1678 | find . -type f -iname '*tar*' -exec ls -l {} + \ 1679 | | awk '{sum+=$5}END{print sum}' 1680 | popd > /dev/null 1681 | } 1682 | 1683 | function apt-cyg-repair-acl () 1684 | { 1685 | local target="${1:-/}" 1686 | local aclbackup="/tmp/$(date +%Y%m%d_%H%M%S)_acl" 1687 | ask_user "$(cat <<-EOD 1688 | This subcommand tries to repair the ACL for "${target}". 1689 | Maybe it repairs a cygwin that was installed by setup.exe with -B and --no-admin options. 1690 | But some package, that are failed to install by the ACL problem, need to be reinstalled. 1691 | 1692 | And unfortunately, perchance, this might cause some corruptions about the ACL. 1693 | You can find a backup of the ACL before being rewritten by this subcommand at below: 1694 | "${aclbackup}.bin" 1695 | "${aclbackup}.txt" 1696 | 1697 | Are you sure ? 1698 | EOD 1699 | )" || exit 1 1700 | echo 1701 | 1702 | comspec /c icacls.exe "$(cygpath -w "${target}")" /save "$(cygpath -w "${aclbackup}.bin")" > /dev/null 1703 | comspec /c icacls.exe "$(cygpath -w "${target}")" | cp2utf8 > "$(cygpath -w "${aclbackup}.txt")" 1704 | 1705 | comspec /c icacls.exe "$(cygpath -w "${target}")" \ 1706 | /grant \ 1707 | "%USERDOMAIN%\\%USERNAME%:F" \ 1708 | "*S-1-3-1:RX" \ 1709 | "Everyone:RX" \ 1710 | "CREATOR OWNER:(OI)(CI)(IO)F" \ 1711 | "CREATOR GROUP:(OI)(CI)(IO)RX" \ 1712 | "Everyone:(OI)(CI)(IO)RX" \ 1713 | /remove \ 1714 | "NT AUTHORITY\\Authenticated Users" \ 1715 | "NT AUTHORITY\\SYSTEM" \ 1716 | "BUILTIN\\Administrators" \ 1717 | "BUILTIN\\Users" \ 1718 | "NULL SID" \ 1719 | /inheritance:r \ 1720 | | cp2utf8 1721 | } 1722 | 1723 | function apt-cyg-repair-postinstall () 1724 | # Repair postinstall scripts 1725 | { 1726 | # Repair type p scripts that were marked "done" incorrectly. 1727 | local i done_marked_p=( /etc/postinstall/[0_z]p_*.done ) 1728 | [[ ! -e "$done_marked_p" ]] && return 1729 | 1730 | verbose 0 -e "${SGR_fg_green}${SGR_bold}Repairing:${SGR_reset} type p postinstall scripts that were marked .done incorrectly." 1731 | for i in "${done_marked_p[@]}"; do 1732 | if [[ "$i" -ot "${i%.done}" ]]; then 1733 | rm -v "$i" 1734 | else 1735 | mv -v "$i" "${i%.done}" 1736 | fi 1737 | done 1738 | echo 1739 | } 1740 | 1741 | function get_archives_list () #= section type [package_names ...] 1742 | #? get archives list by format below: 1743 | #? path size digest 1744 | #? ... 1745 | #? @param section takes section name like curr, prev, test and etc,,, 1746 | #? @param type takes type name like install or source. 1747 | { 1748 | local section="$1" 1749 | local type="$2" 1750 | shift 2 1751 | awk -v RS="\n\n@ " -v FS="\n" -v PKGS="$(join_str $'\x1c' "$@")" -v MIRROR="${mirror%/}/" \ 1752 | -v SECTION="$section" -v TYPE="$type" ' 1753 | BEGIN { 1754 | split(PKGS, tmp, "\x1c"); 1755 | for (k in tmp) pkgs[tmp[k]] = k; # swap key value 1756 | } 1757 | { 1758 | if(pkgs[$1] == "") { 1759 | delete pkgs[$1]; 1760 | } else { 1761 | section = "curr"; 1762 | for (i = 2; i <= NF; i++) { 1763 | if (match($i, /^\[(.*)\]$/, m)) { 1764 | section = m[1]; 1765 | } else if (match($i, TYPE ": *(.*)", m) && section == SECTION) { 1766 | result[0+n++]=m[1]; 1767 | delete pkgs[$1] 1768 | } 1769 | } 1770 | } 1771 | } 1772 | END { 1773 | for (i =0; i < n; i++) { 1774 | print result[i]; 1775 | } 1776 | if (0 < length(pkgs)) { 1777 | printf("\x1b[33;1mWarning:\x1b[0m following packages are not found:")>"/dev/stderr"; 1778 | for (pkg in pkgs) printf(" %s", pkg)>"/dev/stderr"; 1779 | printf("\n")>"/dev/stderr"; 1780 | } 1781 | } 1782 | ' "$(apt-cyg-pathof "setup.ini")" 1783 | } 1784 | 1785 | function download_packages () #= pos section type [package_names ...] 1786 | #? download packages 1787 | #? @param pos takes here or mirror. 1788 | #? @param section takes section name like curr, prev, test and etc,,, 1789 | #? @param type takes type name like install or source. 1790 | { 1791 | local pos="$1" 1792 | local section="$2" 1793 | local type="$3" 1794 | shift 3 1795 | 1796 | case "$pos" in 1797 | here) 1798 | ;; 1799 | mirror) 1800 | cd "$(apt-cyg-pathof cache/mirrordir)" 1801 | ;; 1802 | *) 1803 | error "unknown param: $pos" 1804 | exit 1 1805 | ;; 1806 | esac 1807 | 1808 | local mirror="$(apt-cyg-pathof mirror)" 1809 | local pkgs; readarray -t pkgs < <(get_archives_list "$section" "$type" "$@") 1810 | local total="$(printf "%s\n" "${pkgs[@]}" | awk '{sum+=$2}END{print sum;}')" 1811 | local n=${#pkgs[@]} 1812 | echo "$n packages, total $total bytes will be downloaded." 1813 | local line reply=() 1814 | for line in "${pkgs[@]}"; do 1815 | local tmp=( $line ) 1816 | local path="${tmp[0]%/*}/" 1817 | local file="${tmp[0]##*/}" 1818 | local url="${mirror%/}/${tmp[0]}" 1819 | local size="${tmp[1]}" 1820 | local digest="${tmp[2]}" 1821 | if [ "$pos" = "mirror" ]; then 1822 | mkdirp "$path" 1823 | pushd "$path" 1824 | fi 1825 | wget -N "$url" 1826 | if ! hash_check <<<"${digest} *${file}" ; then 1827 | error "hash did not match: $file" 1828 | else 1829 | reply+=( "$(cygpath -a "$file" )" ) 1830 | fi 1831 | [ "$pos" = "mirror" ] && popd 1832 | done 1833 | REPLY=( "${reply[@]}" ) 1834 | } 1835 | 1836 | function apt-cyg-source () 1837 | { 1838 | download_packages here curr source "$@" 1839 | } 1840 | 1841 | function apt-cyg-mirror-source () 1842 | { 1843 | download_packages mirror curr source "$@" 1844 | } 1845 | 1846 | function apt-cyg-download () 1847 | { 1848 | download_packages here curr install "$@" 1849 | } 1850 | 1851 | function apt-cyg-mirror () 1852 | { 1853 | download_packages mirror curr install "$@" 1854 | } 1855 | 1856 | function apt-cyg-browse-homepage-with-mirror-source () # [ ...] 1857 | # Browse homepages of packages with mirror-source. 1858 | { 1859 | apt-cyg-mirror-source "$@" 1860 | 1861 | local source sources=( "${REPLY[@]}" ) 1862 | 1863 | for source in "${sources[@]}"; do 1864 | local PN="${source##*/}";PN="${PN%%-[0-9]*}" 1865 | local cygport cygports=() 1866 | readarray -t cygports < <(tar tf "$source" | grep '\.cygport$') 1867 | if (( ${#cygports} <= 0 )); then 1868 | readarray -t cygports < <(tar tf "$source" | grep '\.patch$') 1869 | fi 1870 | for cygport in "${cygports[@]}"; do 1871 | local url 1872 | read url < <( 1873 | tar xf "$source" "$cygport" -O \ 1874 | | grep -E '^\+?HOMEPAGE=' \ 1875 | | sed -E "s/\+?HOMEPAGE=(.*?)\s*/\1/g;s/[\"']+//g;s/\\$\\{PN\\}/$PN/g" \ 1876 | ) 1877 | if [[ "$url" =~ ^https?:// ]]; then 1878 | echo "Open: $url" 1879 | cygstart "$url" 1880 | else 1881 | error "Invalid URL: $url" 1882 | fi 1883 | done 1884 | done 1885 | } 1886 | 1887 | function apt-cyg-browse-homepage () # [ ...] 1888 | # Browse homepages of packages. 1889 | { 1890 | local basepath="cygwin.com/packages/summary/" 1891 | local pkg summary_path srcsummary_path homepage_url 1892 | 1893 | pushd "$(apt-cyg-pathof cache)" > /dev/null 1894 | for pkg; do 1895 | summary_path="${basepath}${pkg}.html" 1896 | [ -e "$summary_path" ] || wget -q -N -x "https://$summary_path" 1897 | read srcsummary_path < <( 1898 | cat "$summary_path" \ 1899 | | grep "source package" \ 1900 | | sed -E 's@.*\shref="([^"]+)".*@'"${basepath}"'\1@g' 1901 | ) 1902 | [ -e "$srcsummary_path" ] || wget -q -N -x "https://$srcsummary_path" 1903 | read homepage_url < <( 1904 | cat "$srcsummary_path" \ 1905 | | grep "homepage" \ 1906 | | sed -E 's/.*\shref="([^"]+)".*/\1/g' 1907 | ) 1908 | cygstart "$homepage_url" 1909 | done 1910 | popd 1911 | } 1912 | 1913 | function apt-cyg-browse-summary () # [ ...] 1914 | # Browse summaries of packages. 1915 | { 1916 | local pkg 1917 | for pkg; do 1918 | cygstart "https://cygwin.com/packages/summary/${pkg}.html" 1919 | done 1920 | } 1921 | 1922 | function apt-cyg-listfiles () # [ ...] 1923 | # List files 'owned' by package(s). 1924 | { 1925 | local lst i sep 1926 | for i; do 1927 | echo -en "$sep"; sep="\n" 1928 | lst="/etc/setup/${i}.lst.gz" 1929 | if [ ! -e "$lst" ]; then 1930 | echo "apt-cyg-listfiles: package '${i}' is not installed" 1931 | continue 1932 | fi 1933 | zcat "${lst}" | sed -e 's:^:/:g' 1934 | done 1935 | } 1936 | 1937 | function apt-cyg-ls-categories () 1938 | { 1939 | cat "$(apt-cyg-pathof setup.ini)" \ 1940 | | grep category: \ 1941 | | sed -r 's/.*: *//g;s/ +/\n/g' \ 1942 | | sort \ 1943 | | uniq 1944 | } 1945 | 1946 | function apt-cyg-ls-pkg-with-category () 1947 | { 1948 | cat "$(apt-cyg-pathof setup.ini)" \ 1949 | | awk '$1=="@"{pkg=$2;}$1=="category:"{for(i=2;i<=NF;i++)print $i,pkg}' \ 1950 | | align_columns 1951 | } 1952 | 1953 | function apt-cyg-setuprc-get () #
1954 | { 1955 | setuprc_get_section "$1" 1956 | } 1957 | 1958 | function apt-cyg-set-cache () # [] 1959 | { 1960 | (( 0 <$# )) && setuprc_set_section last-cache "$(cygpath -aw "$1")" 1961 | } 1962 | 1963 | function apt-cyg-set-mirror () # [ ...] 1964 | { 1965 | set -- "${@%/}" 1966 | (( 0 < $# )) && setuprc_set_section last-mirror "${@/%/\/}" 1967 | is_official_mirrors_of_cygwin "${@/%/\/}" 1968 | } 1969 | 1970 | function apt-cyg-mark-auto () # [ ...] 1971 | { 1972 | package_db_change_mark 0 "$@" 1973 | } 1974 | 1975 | function apt-cyg-mark-manual () # [ ...] 1976 | { 1977 | package_db_change_mark 1 "$@" 1978 | } 1979 | 1980 | function apt-cyg-mark-showauto () 1981 | { 1982 | package_db-list | awk '!$3{print $1}' 1983 | } 1984 | 1985 | function apt-cyg-mark-showmanual () 1986 | { 1987 | package_db-list | awk '$3{print $1}' 1988 | } 1989 | 1990 | function apt-cyg-call () # [ [ ...]] 1991 | # Call internal function in apt-cyg. 1992 | { 1993 | "$@" 1994 | } 1995 | 1996 | function apt-cyg-time () # [ [ ...]] 1997 | # Report time consumed to call internal function in apt-cyg. 1998 | { 1999 | time "$@" 2000 | } 2001 | 2002 | function apt-cyg-filelist () # [] 2003 | # File list like apt-file list 2004 | { 2005 | local list_rel_urls 2006 | readarray -t list_rel_urls < <( 2007 | wget -qO- "https://cygwin.com/packages/summary/${1}.html" \ 2008 | | grep -E ']*>list of files' \ 2009 | | sed -E 's:.*$/,/^<\/pre>/' | tail -n+2 | head -n-1 \ 2015 | | awk -vpkg="$1" '$0=pkg": /"$4' 2016 | fi 2017 | } 2018 | 2019 | function apt-cyg-filesearch () # [] 2020 | # File search like apt-file search 2021 | { 2022 | local cachedir cachefile cachequery columns line package packages url 2023 | cachedir="/tmp/.apt-cyg.cache/filesearch" 2024 | cachequery="$cachedir/$(sha256sum <<<"$1"|awk '$0=$1')" 2025 | mkdirp "$cachedir" 2026 | 2027 | [ ! -e "$cachequery" ] && cygcheck -p "$1" >"$cachequery" 2028 | readarray -t packages < "$cachequery" 2029 | packages=( "${packages[@]:1}" ) 2030 | for line in "${packages[@]}"; do 2031 | columns=( $line ) 2032 | url="https://cygwin.com/packages/$arch/${columns[0]%%-[0-9]*}/${columns[0]}" 2033 | cachefile="$cachedir/$(mirror_to_mirrordir "$url")" 2034 | [ ! -e "$cachefile" ] && wget -qO"$cachefile" "$url" 2035 | echo -n "${columns[0]}" 2036 | awk '/<\/pre>/{f=0}/
/{f=1}f' "$cachefile" \
2037 |     | grep -E "$1" \
2038 |     | awk '($1=$2=$3="")||1'
2039 |   done
2040 | }
2041 | 
2042 | PACKAGEOF_CACHE="/tmp/.apt-cyg-packageof.cache.gz"
2043 | function update_packageof_cache ()
2044 | {
2045 |   local i=0 p q path fn
2046 |   local chr=( "=" "-" "/" "|" "\\" )
2047 |   local lstgz_stamp="$(find /etc/setup/ -maxdepth 1 -type f -name '*.lst.gz' -exec stat -c %Y {} + | sort | tail -n1)"
2048 |   local cache_stamp="$(stat "$PACKAGEOF_CACHE" -c %Y 2>/dev/null || echo 0)"
2049 |   local n="$(ls -1 /etc/setup/*.lst.gz|wc -l)"
2050 |   
2051 |   if (( cache_stamp < lstgz_stamp )) || [ -n "$OPT_FORCE_UPDATE_PACKAGEOF_CACHE" ]; then
2052 |     verbose 1 "Updating packageof cache:"
2053 |     progress_init
2054 |     for path in /etc/setup/*.lst.gz; do
2055 |       progress_update $(( i++ )) $n
2056 |       local fn="${path##*/}"
2057 |       zcat "$path" | awk -v PKGNAME="${fn%.lst.gz}" '{print PKGNAME ": " $0;}'
2058 | #      printf "p=%d q=%d i=%d n=%d path=[%s]\n" $p $q $i $n "$path"
2059 |     done | gzip >"$PACKAGEOF_CACHE"
2060 |     progress_finish
2061 |   fi
2062 | }
2063 | 
2064 | PROGRESS_CHAR=( "=" "-" "/" "|" "\\" )
2065 | function progress_init ()
2066 | {
2067 |   [ -n "$OPT_NO_PROGRESS" ] && return
2068 |   #          0        1         2         3         4         5
2069 |   #          12345678901234567890123456789012345678901234567890
2070 |   echo -ne "|..................................................|\r" >&1000
2071 | }
2072 | 
2073 | function progress_update () #= current total=100
2074 | {
2075 |   [ -n "$OPT_NO_PROGRESS" ] && return
2076 |   local n=${2:-100}
2077 |   local p=$((2 + 50 * ($1    ) / $n))
2078 |   local q=$((2 + 50 * ($1 + 1) / $n))
2079 |   if (( q - p <= 1 )); then
2080 |     printf "\e[%dG%s" $p "${PROGRESS_CHAR[($1 % 4 + 1) * (1 + $p - $q)]}" >&1000
2081 |   else
2082 |     printf "\e[%dG%s" $p "$(seq $((q - p))|awk '{printf "="}')" >&1000
2083 |   fi
2084 | }
2085 | 
2086 | function progress_finish ()
2087 | {
2088 |   [ -n "$OPT_NO_PROGRESS" ] && return
2089 |   echo >&1000
2090 | }
2091 | 
2092 | # Lesser Parallel for Embedding
2093 | # Copyright (c) 2014 Koichi OKADA. All rights reserved.
2094 | # The official repository is:
2095 | # https://github.com/kou1okada/lesser-parallel
2096 | # This script is distributed under the MIT license.
2097 | # http://www.opensource.org/licenses/mit-license.php
2098 | 
2099 | LESSER_PARALLEL_MAX_JOBS=${LESSER_PARALLEL_MAX_JOBS:-8}
2100 | 
2101 | function lesser-parallel-get-jobs-count ()
2102 | {
2103 |   jobs -l >/dev/null
2104 |   jobs -l | wc -l
2105 | }
2106 | 
2107 | # Usage: lesser-parallel-restrict-jobs-count MAXJOBS
2108 | function lesser-parallel-restrict-jobs-count ()
2109 | {
2110 |   while [ $(lesser-parallel-get-jobs-count) -ge $1 ]; do
2111 |     sleep 0.2
2112 |   done
2113 | }
2114 | 
2115 | # Usage: lesser-parallel [command [arguments]] < list_ot_arguments
2116 | function lesser-parallel ()
2117 | {
2118 |   local cmd arg lines line basename ext PARALLEL_SEQ=1
2119 |   readarray -t lines
2120 |   for line in "${lines[@]}"; do
2121 |     basename="$(basename "$line")"
2122 |     ext="${basename##*.}"
2123 |     [ "$ext" = "$basename" ] && ext=""
2124 |     [ "$ext" != "" ] && ext=".$ext"
2125 |     cmd=( )
2126 |     for arg; do
2127 |       case "$arg" in
2128 |       "{}")
2129 |         cmd+=( "$line" )
2130 |         ;;
2131 |       "{.}")
2132 |         cmd+=( "$(basename "$line" "$ext")" )
2133 |         ;;
2134 |       "{/}")
2135 |         cmd+=( "$basename" )
2136 |         ;;
2137 |       "{//}")
2138 |         cmd+=( "$(dirname "$line")" )
2139 |         ;;
2140 |       "{/.}")
2141 |         cmd+=( "$(basename "$basename" "$ext")" )
2142 |         ;;
2143 |       "{#}")
2144 |         cmd+=( "$PARALLEL_SEQ" )
2145 |         ;;
2146 |       *)
2147 |         cmd+=( "$arg" )
2148 |         ;;
2149 |       esac
2150 |     done
2151 |     
2152 |     lesser-parallel-restrict-jobs-count $LESSER_PARALLEL_MAX_JOBS
2153 |     
2154 |     "${cmd[@]}" &
2155 |     PARALLEL_SEQ=$[$PARALLEL_SEQ + 1]
2156 |   done
2157 |   
2158 |   lesser-parallel-restrict-jobs-count 1
2159 | }
2160 | 
2161 | #/Lesser Parallel for Embedding
2162 | 
2163 | function apt-cyg-help ()
2164 | {
2165 |   usage
2166 | }
2167 | 
2168 | # process options
2169 | 
2170 | arch="${HOSTTYPE:-$(arch)}";arch="${arch/i686/x86}"
2171 | apt_cyg_cachedir="${tmp:-/tmp}/.apt-cyg.cache"
2172 | noscripts=0
2173 | OPT_USER_PICKED=1
2174 | noupdate=0
2175 | OPT_FILES=()
2176 | SUBCOMMAND=""
2177 | ignore_case=""
2178 | force_remove=""
2179 | force_fetch_trustedkeys=""
2180 | no_verify=""
2181 | OPT_PROXY=${APT_CYG_PROXY:-auto}
2182 | OPT_PROXY_REFRESH_INTERVAL=${APT_CYG_PROXY_REFRESH_INTERVAL:-86400} # 86400s = 1day
2183 | OPTS4INHERIT=()
2184 | SETUP_EXE="setup-$arch.exe"
2185 | YES_TO_ALL=false
2186 | INITIAL_ARGS=( "$@" )
2187 | ARGS=()
2188 | 
2189 | function parse_args ()
2190 | {
2191 |   local unknown_option END_OPTS
2192 |   
2193 |   while [ $# -gt 0 ]; do
2194 |     case "$1" in
2195 |       
2196 |       --ag)
2197 |         OPT_AG="$1"
2198 |         shift
2199 |         ;;
2200 |       
2201 |       --benchmark-timeout)
2202 |         OPT_BENCHMARK_TIMEOUT="$2"
2203 |         shift 2 || break
2204 |         ;;
2205 | 
2206 |       --use-setuprc)
2207 |         warning "Ignore --use-setuprc. This option was removed with issue-24."
2208 |         shift
2209 |         ;;
2210 |       
2211 |       --ignore-case|-i)
2212 |         ignore_case="$1"
2213 |         shift
2214 |         ;;
2215 |       
2216 |       --force-remove)
2217 |         force_remove=1
2218 |         shift
2219 |         ;;
2220 |       
2221 |       --force-fetch-trustedkeys)
2222 |         force_fetch_trustedkeys=1
2223 |         shift
2224 |         ;;
2225 |       
2226 |       --force-update-packageof-cache)
2227 |         OPT_FORCE_UPDATE_PACKAGEOF_CACHE="$1"
2228 |         shift
2229 |         ;;
2230 |       
2231 |       --no-verify|-X)
2232 |         OPTS4INHERIT+=( "$1" )
2233 |         no_verify=1
2234 |         shift
2235 |         ;;
2236 |       
2237 |       --no-check-certificate)
2238 |         OPTS4INHERIT+=( "$1" )
2239 |         WGET+=( "--no-check-certificate" )
2240 |         shift
2241 |         ;;
2242 |       
2243 |       --no-update-setup)
2244 |         OPT_NO_UPDATE_SETUP="$1"
2245 |         shift
2246 |         ;;
2247 |       
2248 |       --no-header)
2249 |         OPT_NO_HEADER="$1"
2250 |         shift
2251 |         ;;
2252 |       
2253 |       --proxy|-p)
2254 |         OPT_PROXY="$2"
2255 |         shift 2 || break
2256 |         ;;
2257 |       
2258 |       --proxy-force-refresh)
2259 |         OPT_PROXY_FORCE_REFRESH="$1"
2260 |         shift
2261 |         ;;
2262 |       
2263 |       --proxy-refresh-interval)
2264 |         OPT_PROXY_REFRESH_INTERVAL="$2"
2265 |         shift 2 || break
2266 |         ;;
2267 |       
2268 |       --completion-get-subcommand)
2269 |         OPT_COMPLETION_GET_SUBCOMMAND="$1"
2270 |         shift
2271 |         ;;
2272 |       
2273 |       --completion-disable-autoupdate)
2274 |         OPT_COMPLETION_DISABLE_AUTOUPDATE="$1"
2275 |         shift
2276 |         ;;
2277 |       
2278 |       --max-jobs|-j)
2279 |         LESSER_PARALLEL_MAX_JOBS="$2"
2280 |         shift 2 || break
2281 |         ;;
2282 |       
2283 |       --mirror|-m)
2284 |         OPT_MIRROR+=( "$2" )
2285 |         shift 2 || break
2286 |         ;;
2287 |       
2288 |       --mirror-index|-M)
2289 |         OPT_MIRROR_INDEX="$2"
2290 |         shift 2 || break
2291 |         ;;
2292 |       
2293 |       --cache|-c)
2294 |         OPT_CACHE="$2"
2295 |         shift 2 || break
2296 |         ;;
2297 |       
2298 |       --noscripts)
2299 |         noscripts=1
2300 |         shift
2301 |         ;;
2302 |       
2303 |       # It will not register the user_picked flag in PACKAGE_DB.
2304 |       # This option is for internal use only.
2305 |       --no-user-picked)
2306 |         OPT_USER_PICKED=0
2307 |         shift
2308 |         ;;
2309 |       
2310 |       --noupdate|-u)
2311 |         noupdate=1
2312 |         shift
2313 |         ;;
2314 |       
2315 |       --ipv4|-4)
2316 |         WGET+=( "--prefer-family=IPv4" )
2317 |         shift
2318 |         ;;
2319 |       
2320 |       --no-progress)
2321 |         OPT_NO_PROGRESS="$1"
2322 |         shift
2323 |         ;;
2324 |       
2325 |       --quiet|-q)
2326 |         OPT_VERBOSE_LEVEL=-1
2327 |         shift
2328 |         ;;
2329 |       
2330 |       --verbose|-v)
2331 |         OPT_VERBOSE_LEVEL=2
2332 |         shift
2333 |         ;;
2334 |       
2335 |       --help)
2336 |         usage
2337 |         exit 0
2338 |         ;;
2339 |       
2340 |       --version)
2341 |         version
2342 |         exit 0
2343 |         ;;
2344 |       
2345 |       --file|-f)
2346 |         [ -n "$2" ] && OPT_FILES+=( "$2" )
2347 |         shift 2 || break
2348 |         ;;
2349 |       
2350 |       --)
2351 |         END_OPTS="$1"
2352 |         shift
2353 |         break
2354 |         ;;
2355 |       
2356 |       -*)
2357 |         unknown_option="$1"
2358 |         break
2359 |         ;;
2360 |       
2361 |       *)
2362 |         if [ -z "$SUBCOMMAND" ]; then
2363 |           SUBCOMMAND="$1"
2364 |         else
2365 |           ARGS+=( "$1" )
2366 |         fi
2367 |         shift
2368 |         
2369 |         ;;
2370 |       
2371 |     esac
2372 |   done
2373 |   [ -n "$END_OPTS" ] && while (( 0 < "$#" )); do ARGS+=( "$1" ); shift; done
2374 |   
2375 |   if [ -n "$OPT_COMPLETION_GET_SUBCOMMAND" ]; then
2376 |     echo "$SUBCOMMAND"
2377 |     exit
2378 |   fi
2379 |   
2380 |   if [ -n "$unknown_option" ]; then
2381 |     error "Unknown option: $unknown_option"
2382 |     exit 1
2383 |   fi
2384 |   
2385 |   if [ $# -gt 0 ]; then
2386 |     error "Number of parameters is not enough: $@"
2387 |     exit 1
2388 |   fi
2389 |   
2390 | } #/parse_args
2391 | 
2392 | parse_args "$@"
2393 | 
2394 | : ${OPT_VERBOSE_LEVEL:=$VERBOSE}
2395 | VERBOSE=$OPT_VERBOSE_LEVEL
2396 | 
2397 | [ "${#OPT_MIRROR[@]}" -gt 0 ] && apt-cyg-set-mirror "${OPT_MIRROR[@]}"
2398 | [ "${#OPT_CACHE[@]}"  -gt 0 ] && apt-cyg-set-cache  "${OPT_CACHE}"
2399 | 
2400 | if [ -z "$GPG" -a -z "$no_verify" ]; then
2401 |   error "GnuPG is not installed. Prease install gnupg package or use -X option."
2402 |   exit 1
2403 | fi
2404 | 
2405 | for file in "${OPT_FILES[@]}"; do
2406 |   if [ -f "$file" ]; then
2407 |     readarray -t -O ${#ARGS[@]} ARGS < "$file"
2408 |   else
2409 |     echo File $file not found, skipping
2410 |   fi
2411 | done
2412 | 
2413 | update_verbosefor
2414 | 
2415 | if [ -n "$OPT_AG" ]; then
2416 |   read AG < <( type -p ag 2>/dev/null )
2417 |   if [ -z "$AG" ]; then
2418 |     warning "ag is not found. ignore option: $OPT_AG"
2419 |     unset OPT_AG
2420 |   fi
2421 | fi
2422 | 
2423 | 
2424 | 
2425 | function apt-cyg-update ()
2426 | {
2427 |   findworkspace
2428 |   getsetup
2429 | }
2430 | 
2431 | 
2432 | function apt-cyg-show ()
2433 | {
2434 |   package_db-version_check
2435 |   [ -z "$OPT_NO_HEADER" ] && echo "The following packages are installed:"
2436 |   package_db-list | awk '($3="")||1' | align_columns
2437 | }
2438 | 
2439 | 
2440 | function apt-cyg-find ()
2441 | {
2442 |   local pkg
2443 |   
2444 |   checkpackages "$@"
2445 |   findworkspace
2446 |   getsetup
2447 |   
2448 |   for pkg do
2449 |     echo ""
2450 |     echo "Searching for installed packages matching $pkg:"
2451 |     package_db-list | awk '$1~query{print $1}' query="$pkg" IGNORECASE="$ignore_case"
2452 |     echo ""
2453 |     echo "Searching for installable packages matching $pkg:"
2454 |     awk -v query="$pkg" -v IGNORECASE="$ignore_case" \
2455 |       'BEGIN{RS="\n\n@ "; FS="\n"; ORS="\n"} {if ($1 ~ query) {print $1}}' \
2456 |       setup.ini
2457 |   done
2458 | }
2459 | 
2460 | 
2461 | function apt-cyg-category () # 
2462 | #   List all packages in given .
2463 | {
2464 |   apt-cyg-ls-pkg-with-category \
2465 |   | awk -vcategory="$1" '$1==category {print $2}'
2466 | }
2467 | 
2468 | 
2469 | function apt-cyg-describe ()
2470 | {
2471 |   local pkg exact
2472 |   
2473 |   checkpackages "$@"
2474 |   findworkspace
2475 |   getsetup
2476 |   for pkg do
2477 |     exact="$(grep -Fx "@ $pkg" setup.ini)"
2478 |     awk -v query="$pkg" -v exact="${exact:+1}" -v IGNORECASE="$ignore_case" \
2479 |       'BEGIN{RS="\n\n@ "; FS="\n"} (exact?$1==query:$1~query){print "@ "$0"\n"}' \
2480 |       setup.ini
2481 |   done
2482 | }
2483 | 
2484 | function apt-cyg-packageof ()
2485 | {
2486 |   if [ -z "$OPT_AG" ]; then
2487 |     update_packageof_cache
2488 |     zcat "$PACKAGEOF_CACHE" | grep "$@"
2489 |   else
2490 |     "$AG" -z "$@" /etc/setup/*.lst.gz
2491 |   fi
2492 | }
2493 | 
2494 | function apt-cyg-install ()
2495 | {
2496 |   local pkg
2497 |   local script
2498 |   
2499 |   package_db-version_check
2500 |   checkpackages "$@"
2501 |   findworkspace
2502 |   getsetup
2503 |   
2504 |   for pkg do
2505 |     if package_db-is_registered "$pkg"; then
2506 |       echo Package $pkg is already installed, skipping
2507 |       continue
2508 |     fi
2509 |     verbose 0 ""
2510 |     verbose 0 "Installing $pkg"
2511 |     
2512 |     # look for package and save desc file
2513 |     
2514 |     mkdirp "release/$pkg"
2515 |     awk > "release/$pkg/desc" -v package="$pkg" \
2516 |       'BEGIN{RS="\n\n@ "; FS="\n"} {if ($1 == package) {desc = $0; px++}} \
2517 |        END {if (px == 1 && desc != "") print desc; else print "Package not found"}' \
2518 |        setup.ini
2519 |     local desc="$(< "release/$pkg/desc")"
2520 |     if [ "$desc" = "Package not found" ]; then
2521 |       verbose 0 "Package $pkg not found or ambiguous name, exiting"
2522 |       rm -r "release/$pkg"
2523 |       exit 1
2524 |     fi
2525 |     verbose 0 "Found package $pkg"
2526 |     
2527 |     # download and unpack the bz2 file
2528 |     
2529 |     # pick the latest version, which comes first
2530 |     local install="$(awk '/^install: / { print $2; exit }' "release/$pkg/desc")"
2531 |     
2532 |     if [ -z "$install" ]; then
2533 |       verbose 0 "Could not find \"install\" in package description: obsolete package?"
2534 |       exit 1
2535 |     fi
2536 |     
2537 |     local file="$(basename "$install")"
2538 |     cd "release/$pkg"
2539 |     wget -Nc $mirror/$install
2540 |     
2541 |     # check the SHA512 hash
2542 |     local digest="$(awk '/^install: / { print $4; exit }' "desc")"
2543 |     if ! hash_check <<<"${digest} *${file}" ; then
2544 |       verbose 0 "error: hash did not match: $file"
2545 |       exit 1
2546 |     fi
2547 |     
2548 |     verbose 0 "Unpacking..."
2549 |     tar > "/etc/setup/$pkg.lst" xvf "$file" -C / --numeric-owner
2550 |     gzip -f "/etc/setup/$pkg.lst"
2551 |     cd ../..
2552 |     
2553 |     
2554 |     # update the package database
2555 |     
2556 |     package_db-register "$file" "$OPT_USER_PICKED"
2557 |     
2558 |     
2559 |     # recursively install required packages
2560 |     
2561 |     local requires="$(grep -E "^(requires|depends2): " "release/$pkg/desc" | sed -re 's/^(requires|depends2): *(.*[^ ]) */\2/g' -e 's/,? +/ /g')"
2562 |     
2563 |     local warn=0
2564 |     if [ -n "$requires" ]; then
2565 |       verbose 0 "Package $pkg requires the following packages, installing:"
2566 |       verbose 0 "$requires"
2567 |       for package in $requires; do
2568 |         if package_db-is_registered "$package"; then
2569 |           verbose 0 "Package $package is already installed, skipping"
2570 |           continue
2571 |         fi
2572 |         apt-cyg "${OPTS4INHERIT[@]}" --proxy inherit --noscripts --no-user-picked install $package
2573 |         if [ $? -ne 0 ]; then warn=1; fi
2574 |       done
2575 |     fi
2576 |     if [ $warn -ne 0 ]; then
2577 |       warning "some required packages did not install, continuing"
2578 |     fi
2579 |     
2580 |     # run all postinstall scripts
2581 |     
2582 |     apt-cyg-repair-postinstall
2583 |     
2584 |     local postinstalls=( /etc/postinstall/*.?(da)sh )
2585 |     if [ -e "$postinstalls" -a $noscripts -ne 1 ]; then
2586 |       verbose 0 "Running postinstall scripts"
2587 |       for script in "${postinstalls[@]}"; do
2588 |         $script \
2589 |         && [[ $script != /*/?p_* ]] \
2590 |         && mv $script $script.done
2591 |       done
2592 |     fi
2593 |     
2594 |     verbose 0 "Package $pkg installed"
2595 |     
2596 |   done
2597 | }
2598 | 
2599 | 
2600 | function apt-cyg-remove()
2601 | {
2602 |   local pkg
2603 |   local req
2604 |   
2605 |   package_db-version_check
2606 |   checkpackages "$@"
2607 |   for pkg do
2608 |     if ! package_db-is_registered "$pkg"; then
2609 |       verbose 0 "Package $pkg is not installed, skipping"
2610 |       continue
2611 |     fi
2612 |     
2613 |     local dontremove="cygwin coreutils gawk bzip2 tar xz wget bash"
2614 |     for req in $dontremove; do
2615 |       if [ "$pkg" = "$req" ]; then
2616 |         verbose 0 "apt-cyg cannot remove package $pkg, exiting"
2617 |         exit 1
2618 |       fi
2619 |     done
2620 |     
2621 |     if [ ! -e "/etc/setup/$pkg.lst.gz" -a -z "$force_remove" ]; then
2622 |       verbose 0 "Package manifest missing, cannot remove $pkg.  Exiting"
2623 |       exit 1
2624 |     fi
2625 |     verbose 0 "Removing $pkg"
2626 |     
2627 |     # run preremove scripts
2628 |     
2629 |     local i postinstalls preremoves
2630 |     readarray -t postinstalls < <(zgrep -E "^etc/postinstall/.*[.](da)?sh$" "/etc/setup/${pkg}.lst.gz" | awk '{print "/"$0}')
2631 |     readarray -t preremoves   < <(zgrep -E "^etc/preremove/.*[.](da)?sh$"   "/etc/setup/${pkg}.lst.gz" | awk '{print "/"$0}')
2632 |     for i in "${preremoves[@]}"; do
2633 |       verbose 0 "Running: ${i}"
2634 |       "${i}"
2635 |     done
2636 |     
2637 |     gzip -cd "/etc/setup/$pkg.lst.gz" | awk '/[^\/]$/{printf("/%s\0", $0)}' | xargs -0 rm -f
2638 |     gzip -cd "/etc/setup/$pkg.lst.gz" | awk '/[^./].*[/]$/{printf("/%s\0", $0)}' | sort -zr | xargs -0 rmdir --ignore-fail-on-non-empty
2639 |     rm -f "${postinstalls[@]/%/.done}" "/etc/setup/$pkg.lst.gz"
2640 |     package_db-unregister "$pkg"
2641 |     verbose 0 "Package $pkg removed"
2642 |     
2643 |   done
2644 | }
2645 | 
2646 | function invoke_subcommand ()
2647 | {
2648 |   local SUBCOMMAND="${@:1:1}"
2649 |   local ARGS=( "${@:2}" )
2650 |   local ACTION="apt-cyg-${SUBCOMMAND:-help}"
2651 |   if type "$ACTION" >& /dev/null; then
2652 |     "$ACTION" "${ARGS[@]}"
2653 |   else
2654 |     error "unknown subcommand: $SUBCOMMAND"
2655 |     exit 1
2656 |   fi
2657 | }
2658 | 
2659 | [ -d "$PWD" ] || {
2660 |   warning "Missing current directory: $PWD" \
2661 |           "\nNote that some functions, which require access to current directory, will be failed."
2662 | }
2663 | 
2664 | invoke_subcommand "$SUBCOMMAND" "${ARGS[@]}"
2665 | 


--------------------------------------------------------------------------------
/known_problems.md:
--------------------------------------------------------------------------------
 1 | Known Problems
 2 | --------------
 3 | 
 4 | ### 2016-02-12: Problems about the ACL
 5 | 
 6 | In recent version, the cygwin changed the ACL mechanism .
 7 | So, in the cygwin current version, if it will be installed by `setup.exe` with `-B` or `--no-admin` option,
 8 | the cygwin root (/) does not have correct ACL.
 9 | 
10 | A new subcommand `repair-acl` tries to repair it.
11 | But some package, that are failed to install by the ACL problem, need to be reinstalled.
12 | 
13 | 
14 | 
15 | ### 2015-04-09: gpgv seems not work correctly on 32 bit environment
16 | 
17 | To solve this problem, the backend of `verify_signatures` function was changed from `gpgv` to `gpg`.
18 | thienhv reported this problem [#14](https://github.com/kou1okada/apt-cyg/issues/14). Thanks.
19 | 
20 | 
21 | 
22 | ### 2014-01-17: ca-certificates package is not setup correct at x86_64 with Windows 8.
23 | 
24 | After clean installing with `setup-x86_64.exe`, there are something wrong about ca-certificate package as below:
25 | 
26 |     $ ls -lnG \
27 |          /cygdrive/c/cygwin/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt \
28 |          /cygdrive/c/cygwin64/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
29 |     -r--r--r-- 1 1001 314336 Jan 17 18:17 /cygdrive/c/cygwin/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
30 |     -rw-r--r-- 1 1001      0 Oct 16 12:35 /cygdrive/c/cygwin64/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
31 |     $ ls -lnG \
32 |          /cygdrive/c/cygwin/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem \
33 |          /cygdrive/c/cygwin64/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
34 |     -r--r--r-- 1 1001 232342 Jan 17 18:17 /cygdrive/c/cygwin/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
35 |     -rw-r--r-- 1 1001      0 Oct 16 12:35 /cygdrive/c/cygwin64/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
36 | 
37 | The x86 environment seems no problem except that need an additional setting for wget and ca-certificate. Hmm,,,    
38 | 
39 | It seems that `/usr/bin/update-ca-trust` is failed at x86_64.
40 | 
41 | It's ad hoc, but effective way to fix it, is to copy files from cygwin32 to cygwin64, as below:
42 | 
43 |     cp -a /cygdrive/c/cygwin/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt \
44 |           /cygdrive/c/cygwin64/etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt
45 |     cp -a /cygdrive/c/cygwin/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem \
46 |           /cygdrive/c/cygwin64/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem
47 | 
48 | This problem is fixed at 2014-01-24.
49 | version 0.18.7-1 of p11-kit, p11-kit-trust and libp11-kit0 did not work at the cygwin64 under the Windows 8.
50 | If you face the above problem, please upgrade these three packages from version 0.18.7-1 to version 0.18.7-2.
51 | 
52 | For more details, see a thread of below:
53 | 
54 | * Cygwin mailing list / cygwin / [Re: Is there someone who have a same problem ?](http://cygwin.com/ml/cygwin/2014-01/msg00368.html)
55 | 
56 | 
57 | 
58 | ### 2014-01-15: Signature check failed at cygwinports x86_64.
59 | 
60 | Oops, setup.bz2 is newer than setup.bz2.sig.
61 | And it seems to be corrupted.
62 | 
63 |     $ date
64 |     Wed Jan 15 01:30:19 JST 2014
65 |     $ w3m -dump ftp://ftp.cygwinports.org/pub/cygwinports/x86_64/
66 |     Index of ftp://ftp.cygwinports.org/pub/cygwinports/x86_64/
67 |     
68 |     [Upper Directory]
69 |     md5.sum. . . . . . . Jan 10 14:24    184
70 |     release/ . . . . . . Jan 10 18:00
71 |     setup.bz2. . . . . . Jan 10 13:59   579K
72 |     setup.bz2.sig. . . . Dec  6 11:28     72
73 |     setup.ini. . . . . . Dec  6 11:28  3.20M
74 |     setup.ini.sig. . . . Dec  6 11:28     72
75 |     
76 |     $ wget -q -O - ftp://ftp.cygwinports.org/pub/cygwinports/x86_64/setup.bz2 | bzip2 -tvv
77 |       (stdin):
78 |         [1: huff+mtf rt+rld]
79 |         [2: huff+mtf data integrity (CRC) error in data
80 |     
81 |     You can use the `bzip2recover' program to attempt to recover
82 |     data from undamaged sections of corrupted files.
83 | 
84 | As of 2014-01-24, above problem is recovered at least.
85 | 
86 | 
87 | 
88 | ### FIXED: Check setup (`cygcheck -c`) can not detect .tar.xz packages
89 | 
90 | At cygwin 1.7.25, cygcheck is hardcoded for .tar.gz and .tar.bz2.
91 | So check setup (`cygcheck -c`) can not detect .tar.xz packages.
92 | This bug was already fixed with [src/winsup/utils/dump_setup.cc#rev1.28](http://cygwin.com/cgi-bin/cvsweb.cgi/src/winsup/utils/dump_setup.cc?cvsroot=src#rev1.28).
93 | Please wait a release of cygwin 1.7.26.
94 | 
95 | This Problem was fixed [cygwin 1.7.26](http://cygwin.com/ml/cygwin-announce/2013-11/msg00027.html) which released at 2013-11-29.
96 | 


--------------------------------------------------------------------------------
/other_forks.md:
--------------------------------------------------------------------------------
 1 | Other Known *`apt-cyg`* Forks on the GitHub
 2 | -------------------------------------------
 3 | 
 4 | Caution:
 5 | Please do not merge forks that have incompatible licenses.
 6 | 
 7 | Ex.) Merging to the GPL from the MIT is possible. But merging to the MIT from the GPL is impossible.
 8 | 
 9 | **NB:** For comparison between forks, you can use a fork analyzer tool. Unfortunately, *Stagazers forks* website is down, but you can use [Lovely Forks browser extension](https://github.com/musically-ut/lovely-forks)
10 | 
11 | ### Official (MIT license)
12 | 
13 | * [transcodes-open / apt-cyg](https://github.com/transcode-open/apt-cyg/network)
14 |   * [tmshn / cyg-fast](https://github.com/tmshn/cyg-fast/network)
15 |   * [pi0 / cyg](https://github.com/pi0/cyg/network) (GPLv3)
16 | 
17 | ### Unofficial (MIT license)
18 | 
19 | * [digitallamb / apt-cyg](https://github.com/digitallamb/apt-cyg/network)
20 | * [balanx / apt-cyg](https://github.com/balanx/apt-cyg/network)
21 | * [langlichuan123 / apt-cyg](https://github.com/langlichuan123/apt-cyg/network)
22 | 
23 | ### Unofficial (GPLv2)
24 | 
25 | * [cfg / apt-cyg](https://github.com/cfg/apt-cyg/network)
26 |   * [Milly / apt-cyg](https://github.com/Milly/apt-cyg/network)
27 | * [ashumkin / apt-cyg](https://github.com/ashumkin/apt-cyg/network)
28 | * [svn2github / apt-cyg](https://github.com/svn2github/apt-cyg/network)
29 | * [nosuchuser / apt-cyg](https://github.com/nosuchuser/apt-cyg/network)
30 | * [kazuhisya / apt-cyg64](https://github.com/kazuhisya/apt-cyg64/network)
31 | * [bnormsoftware / apt-cyg](https://github.com/bnormsoftware/apt-cyg/network)
32 | * [rcmdnk / apt-cyg](https://github.com/rcmdnk/apt-cyg/network)
33 | * [buzain / apt-cyg](https://github.com/buzain/apt-cyg/network)
34 | * [wuyangnju / apt-cyg](https://github.com/wuyangnju/apt-cyg/network)
35 | * [takuya / apt-cyg](https://github.com/takuya/apt-cyg/network)
36 | 
37 | ### Derivations of non-fork on the github
38 | 
39 | * [10sr / pac-cyg](https://github.com/10sr/pac-cyg/network)
40 | * [nobuyo / medy](https://github.com/nobuyo/medy/network)
41 | * [svnpenn / sage](https://github.com/svnpenn/sage/network) -> [cup / pear](https://github.com/cup/pear/network)
42 | 
43 | 


--------------------------------------------------------------------------------