Re: [PATCH cygport] Add customization support for announce command

2024-05-01 Thread Christian Franke via Cygwin-apps

Adam Dinwoodie via Cygwin-apps wrote:

On Tue, Apr 30, 2024 at 12:27:35PM +0200, Christian Franke via Cygwin-apps 
wrote:

Jon Turney wrote:

On 10/03/2024 16:33, Christian Franke via Cygwin-apps wrote:

+    /bin/bash -c "cd ${top} || exit 1
+${HOMEPAGE+HOMEPAGE=${HOMEPAGE@Q}}
+P=${P@Q}; PF=${PF@Q}; PN=${PN@Q}; PR=${PR@Q}; PV=(${PV[*]@Q})
+${SMTP_SENDER+SMTP_SENDER=${SMTP_SENDER@Q}}
+${SMTP_SERVER+SMTP_SERVER=${SMTP_SERVER@Q}}
+${SMTP_SERVER_PORT+SMTP_SERVER_PORT=${SMTP_SERVER_PORT@Q}}
+${SMTP_ENCRYPTION+SMTP_ENCRYPTION=${SMTP_ENCRYPTION@Q}}
+${SMTP_USER+SMTP_USER=${SMTP_USER@Q}}
+${SMTP_PASS+SMTP_PASS=${SMTP_PASS@Q}}
+${cmd}
+" $0 ${msg} || error "Command '\${${cmdvar}} ${msg}'
(cwd=${top}) failed"
+}

Sorry I didn't notice this before, and I am terrible at writing shell,
but perhaps you could share the reasoning behind writing this as above,
and not as, e.g.

(cd ${top} && env BLAH ${cmd})

avoiding all the verbiage in the description of ANNOUNCE_EDITOR about it
being fed into 'bash -c' (and hence getting evaluated twice??) rather
than just run?



None of the mentioned variables are exported to the environment by cygport.
I wanted to keep this fact in the subshell. Therefore the assignments are
added to the script instead of passing via env(ironment). The latter won't
even work with the PV variable because arrays could not be exported.

Variables would not be evaluated twice. For example in the rare case that
someone uses something like

SMTP_SERVER="smtp.$(hostname -d)"

in cygport.conf, this would immediately expand to
SMTP_SERVER="smtp.some.domain". The above

${SMTP_SERVER+SMTP_SERVER=${SMTP_SERVER@Q}}

would expand to

SMTP_SERVER=${SMTP_SERVER@Q}

and then to

SMTP_SERVER='smtp.some.domain'

(The @Q bash extension ensures proper quoting).

Using a subshell created by ( ... ) would achieve the behaviour you're
after, without requiring nearly so much quote handling.  The code Jon
has pulled out could be rewritten as below; using ( ... ) would mean
that everything happens in a subshell and the exports don't affect the
rest of the environment.

```
(
cd "$top"
export HOMEPAGE P PF PN PR PV SMTP_SENDER SMTP_SERVER SMTP_SERVER_PORT 
SMTP_ENCRYPTION SMTP_USER SMTP_PASS


This unnecessarily exports all variables (except PV, see below) to the 
subcommands run by $cmd.




"$cmd" "$msg" || error "Command $cmd $msg (cwd=${top}) failed"


This would limit $cmd to simple commands instead of multiline scripts. 
This reduces flexibility and some of the examples I provided in my 
original post would no longer work:

https://sourceware.org/pipermail/cygwin-apps/2024-February/043501.html



)
```

I've removed the array handling for $PV, as it's not an array; possibly
you've confused it with $PVP?



No. PV it is initialized as a regular shell variable but is later 
changed to an array by appending the PVP array.


/bin/cygport:
...
declare PV=${VERSION}
...
    PV=$(echo ${PF} | sed -e "s/${PN}\-\(.*\)\-${PR}$/\1/");
...
declare -r  PV=(${PV} ${PVP[*]});
...

$ git blame bin/cygport.in | grep 'declare -r  PV='
deb528a88 (Yaakov Selkowitz   2009-12-31 08:05:52 + 397) declare -r  
PV=(${PV} ${PVP[*]});


Bash silently ignores 'export PV'.


   In any case, there is no way to pass an
array to "$cmd" unless "$cmd" is itself a Bash function, as there's no
standard way to store anything other than strings in environment
variables.


That's why I use 'PV=(${PV[*]@Q})' as a prefix of the configured $cmd 
string instead of passing any new environment to $cmd.




I've also removed the `|| return 1` part, since cygport runs with `set
-e` enabled so you only want to catch non-zero return codes if you want
specific error handling.


There is no 'return 1' is my patch.



Finally, I've also added "$msg" to the arguments to "$cmd"; that seems
to be missing and seems to be critical to this working at all!


$msg is not missing in my patch but passed to the launched /bin/bash as $1.



Alternatively, if you really wanted to avoid the export statement, the
below will achieve the same thing; the only use of the subshell at this
point is to avoid the `cd` changing the working directory for the rest
of the script.

```
(
cd "$top"
HOMEPAGE="$HOMEPAGE" P="$P" PF="$PF" PN="$PN" PR="$PR" PV="$PV" SMTP_SENDER="$SMTP_SENDER" SMTP_SERVER="$SMTP_SERVER" 
SMTP_SERVER_PORT="$SMTP_SERVER_PORT" SMTP_ENCRYPTION="$SMTP_ENCRYPTION" SMTP_USER="$SMTP_USER" SMTP_PASS="$SMTP_PASS" "$cmd" "$msg" || error "Command $cmd $msg 
(cwd=${top}) failed"
)
```


Same problem with missing flexibility for $cmd as above.



Re: [PATCH cygport] Add check of SPDX expression provided by LICENSE variable

2024-05-01 Thread Christian Franke via Cygwin-apps

Brian Inglis via Cygwin-apps wrote:

On 2024-04-30 15:07, Christian Franke via Cygwin-apps wrote:

Brian Inglis via Cygwin-apps wrote:

On 2024-04-30 11:45, Christian Franke via Cygwin-apps wrote:
The new script uses the SPDX webpages to create the license file. I 
didn't find a usable single license list at https://github.com/spdx


As usual, it is easier if you clearly state the purpose of the file 
you want, and its desired properties, like data content, format, etc.



What about:
https://spdx.github.io/license-list-data/


This is apparently a draft version of 
https://spdx.org/licenses/index.html which is used by the script to 
generate the local license file.


Strip out the table entries and create what you want with a command or 
script.


The spdx-check script from the patch optionally (-m, -u) downloads 
https://spdx.org/licenses/index.html and creates the local spdx-licenses 
file intended to distribute with cygport. The file is grep'able.and 
reduced to the bare minimum for this use case.






and everything under:
https://github.com/spdx/license-list-data



I didn't find a single file which lists the licenses there.


GH does not always make access easy, ...


... including that github.com is still unreachable via IPv6 without 
NAT64 (except for downloads from raw.githubusercontent.com) ...



... with its limited online displays and fixed display orders, and 
searches return a lot of junk, without easy access to better searching 
in context, but try:


https://github.com/spdx/license-list-data/blob/main/licenses.md

which also has xrefs to the text files; also there are:

https://github.com/spdx/license-list-data/blob/main/json/licenses.json 

https://github.com/spdx/license-list-data/blob/main/json/exceptions.json 



which can be easily processed using `jq`.



Indeed, thanks. I obviously missed these files when I wrote the 
spdx-check script some month ago.


The current file format used by the script could then be created with:

url="https://raw.githubusercontent.com/spdx/license-list-data/main/json;

wget -O - "$url/licenses.json" \
| jq -j '
    .licenses[] | (
  if .isDeprecatedLicenseId then "!" else "" end,
  .licenseId,
  "\n"
    )'

wget -O - "$url/exceptions.json" \
| jq -j '
    .exceptions[] | (
  if .isDeprecatedLicenseId then "!&" else "&" end,
  .licenseExceptionId,
  "\n"
    )'

This adds these license ids not yet mentioned at 
https://spdx.org/licenses/index.html:

AMD-newlib, BSD-2-clause-first-lines, Catharon, HPND-UC-export-US,
MIT-Khronos-old, NCL, OAR, Sun-PPP-2000, pkgconf, threeparttable, xzoom

I could provide a new patch with an updated script if desired.



Re: [PATCH cygport] Add check of SPDX expression provided by LICENSE variable

2024-04-30 Thread Christian Franke via Cygwin-apps

Brian Inglis via Cygwin-apps wrote:

On 2024-04-30 11:45, Christian Franke via Cygwin-apps wrote:
...

Attached.
The new script uses the SPDX webpages to create the license file. I 
didn't find a usable single license list at https://github.com/spdx


What about:

https://spdx.github.io/license-list-data/



This is apparently a draft version of 
https://spdx.org/licenses/index.html which is used by the script to 
generate the local license file.




and everything under:

https://github.com/spdx/license-list-data


I didn't find a single file which lists the licenses there.



[PATCH cygport] Add check of SPDX expression provided by LICENSE variable

2024-04-30 Thread Christian Franke via Cygwin-apps
Jon Turney via Cygwin-apps wrote (thread "[PATCH cygport] Add 
repro-finish command"):

...
PS: I have a local script which checks SPDX Identifiers and 
expressions. Any interest to add this to cygport and then check 
LICENSE settings?


Oh, yes please. That sounds like a good idea.



Attached.

The new script uses the SPDX webpages to create the license file. I 
didn't find a usable single license list at https://github.com/spdx


The data/spdx-licenses file is not included in the patch. It could be 
generated from the source dir with:


$ tools/spdx-check -f data/spdx-licenses -m
...
data/spdx-licenses: created

$ sha1sum data/spdx-licenses
80a19d6891d08bf34113464464ee12308374c792 *data/spdx-licenses

The changes to the meson files are guessed. I didn't test the meson 
build yet.


--
Regards,
Christian

From 61f75757fa8e9118207cc09cf4a621aac8a4da78 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Tue, 30 Apr 2024 19:28:01 +0200
Subject: [PATCH] Add check of SPDX expression provided by LICENSE variable

The new script 'tools/spdx-checks' checks a SPDX license expression.
License identifiers are provided by the new file 'spdx-licenses'
which could be created by the script from the related SPDX webpages.
---
 bin/cygport.in|  17 
 data/meson.build  |   1 +
 tools/meson.build |   1 +
 tools/spdx-check  | 198 ++
 4 files changed, 217 insertions(+)
 create mode 100644 tools/spdx-check

diff --git a/bin/cygport.in b/bin/cygport.in
index 15bd559e..3166beba 100755
--- a/bin/cygport.in
+++ b/bin/cygport.in
@@ -41,6 +41,7 @@ declare -r  _cygport_version=@VERSION@;
 declare -r _privdatadir=@pkgdatadir@;
 declare -r _privclassdir=@cygclassdir@;
 declare -r _privlibdir=@cygpartdir@;
+declare -r _privtoolsdir=@pkgdatadir@/tools;
 declare -r _privgnuconfigdir=@gnuconfigdir@;
 declare -r _privsysconfdir=@sysconfdir@;
 
@@ -489,6 +490,22 @@ do
fi
 done
 
+if [ "${LICENSE+y}" = "y" ]
+then
+   if ! _out=$(${_privtoolsdir}/spdx-check -f 
${_privdatadir}/spdx-licenses "${LICENSE}" 2>&1)
+   then
+   warning "LICENSE='${LICENSE}' is invalid:"
+   echo "${_out}"
+   elif [ "${_out:+y}" = "y" ]
+   then
+   warning "LICENSE='${LICENSE}' has warnings:"
+   echo "${_out}"
+   else
+   inform "LICENSE='${LICENSE}' is valid"
+   fi
+   unset _out
+fi
+
 for restrict in ${RESTRICT//,/ }
 do
declare _CYGPORT_RESTRICT_${restrict//-/_}_=1
diff --git a/data/meson.build b/data/meson.build
index 51c6a5fd..e83a90fe 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -2,6 +2,7 @@ datadocs = files('cygport.conf', 'mirrors')
 
 install_data('mirrors',
  'sample.cygport',
+ 'spdx-licenses',
  install_dir: pkgdatadir)
 
 install_data('gnuconfig/config.guess',
diff --git a/tools/meson.build b/tools/meson.build
index acd83926..96d8d19e 100644
--- a/tools/meson.build
+++ b/tools/meson.build
@@ -1,6 +1,7 @@
 tools = files(
 'deb2targz',
 'pkgrip',
+'spdx-check',
 'sysrootize'
 )
 
diff --git a/tools/spdx-check b/tools/spdx-check
new file mode 100644
index ..bffcaae0
--- /dev/null
+++ b/tools/spdx-check
@@ -0,0 +1,198 @@
+#! /bin/bash
+#######
+#
+# spdx-check - check SPDX license expression
+#
+# Copyright (C) 2024 Christian Franke
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+set -e -o pipefail
+myname=$0
+
+# SPDX license list web pages
+spdx_url_lic="https://spdx.org/licenses/index.html;
+spdx_url_exc="https://spdx.org/licenses/exceptions-index.html;
+
+# Default license file
+def_spdx_file="$(dirname "$myname")/spdx-licenses"
+
+usage()
+{
+  cat <&2
+  exit 1
+}
+
+warning()
+{
+  echo "Warning:" "$@" >&2
+}
+
+check_spdx_id()
+{
+  local id=$1
+  local m m_id
+
+  if ! [ -f "$spdx_file" ]; then
+warning "Missing '$spdx_file' - SPDX identifier '$1' not checked"
+return 0
+  fi
+
+  # SPDX identifiers are case insensitive but the correct case is recommended
+  m=$(grep -Ei -m 1 "^!?&?${id//+/\\+}\$" "$spdx_file" 2>/dev/null) \
+|| error "Unknown SPDX identifier '$id'"
+
+  # TODO: Distinguish licenses and exceptions
+  m_id=${m#!}; m_id=${m_id#&}
+
+  [ "$m_id" = "$id" ] || warning "It is recommended to use '$m_id' instead of 
'$id'"
+  [ "$m" = "${m#!}" ] || warning "SPDX identifier '$m_id' is deprecated"
+}
+
+check_spdx_expr()
+{
+  local x=$1
+  local f s t
+
+  # Insert spaces around tokens to simplify parsing
+  x=" $x "; x=${x//(/ ( }; x=${

Re: [PATCH cygport] Add customization support for announce command

2024-04-30 Thread Christian Franke via Cygwin-apps

Jon Turney wrote:

On 10/03/2024 16:33, Christian Franke via Cygwin-apps wrote:

Jon Turney wrote:

On 23/02/2024 11:23, Christian Franke via Cygwin-apps wrote:

Christian Franke wrote:
The email generated by the cygport announce command is useful, but 
actual use cases are somewhat limited due to the hard-coded email 
submission.


The attached patch adds more flexibility. The patch is on top of 
the "Use correct wording if only one package is announced" patch.


Slightly changed patch attached. Also adjusted to new version of 
"Use correct wording if only one package is announced" patch.




[...]

Thanks for this.


Possible (better?) alternative names for the new settings:
ANNOUNCEMENT_EDITOR
ANNOUNCEMENT_MAILER


Hmmm... I think "ANNOUNCE_EDITOR" and "ANNOUNCE_MAILER" would be
the best for clarity and conciseness.


New patch attached. Is still on top of "Use correct wording ..." patch.

I also added HOMEPAGE to the propagated variables as this should be 
included in an announcement.


Thanks.


+    /bin/bash -c "cd ${top} || exit 1
+${HOMEPAGE+HOMEPAGE=${HOMEPAGE@Q}}
+P=${P@Q}; PF=${PF@Q}; PN=${PN@Q}; PR=${PR@Q}; PV=(${PV[*]@Q})
+${SMTP_SENDER+SMTP_SENDER=${SMTP_SENDER@Q}}
+${SMTP_SERVER+SMTP_SERVER=${SMTP_SERVER@Q}}
+${SMTP_SERVER_PORT+SMTP_SERVER_PORT=${SMTP_SERVER_PORT@Q}}
+${SMTP_ENCRYPTION+SMTP_ENCRYPTION=${SMTP_ENCRYPTION@Q}}
+${SMTP_USER+SMTP_USER=${SMTP_USER@Q}}
+${SMTP_PASS+SMTP_PASS=${SMTP_PASS@Q}}
+${cmd}
+" $0 ${msg} || error "Command '\${${cmdvar}} ${msg}' 
(cwd=${top}) failed"

+}


Sorry I didn't notice this before, and I am terrible at writing shell, 
but perhaps you could share the reasoning behind writing this as 
above, and not as, e.g.


(cd ${top} && env BLAH ${cmd})

avoiding all the verbiage in the description of ANNOUNCE_EDITOR about 
it being fed into 'bash -c' (and hence getting evaluated twice??) 
rather than just run?





None of the mentioned variables are exported to the environment by 
cygport. I wanted to keep this fact in the subshell. Therefore the 
assignments are added to the script instead of passing via 
env(ironment). The latter won't even work with the PV variable because 
arrays could not be exported.


Variables would not be evaluated twice. For example in the rare case 
that someone uses something like


SMTP_SERVER="smtp.$(hostname -d)"

in cygport.conf, this would immediately expand to 
SMTP_SERVER="smtp.some.domain". The above


${SMTP_SERVER+SMTP_SERVER=${SMTP_SERVER@Q}}

would expand to

SMTP_SERVER=${SMTP_SERVER@Q}

and then to

SMTP_SERVER='smtp.some.domain'

(The @Q bash extension ensures proper quoting).



Re: [PATCH cygport] Increase _FORTIFY_SOURCE level from 2 to 3 in CFLAGS

2024-04-28 Thread Christian Franke via Cygwin-apps

ASSI via Cygwin-apps wrote:

Christian Franke via Cygwin-apps writes:

_FORTIFY_SOURCE=3 is supported by Cygwin 3.5.0 headers and Cygwin gcc
13.2.1 test release.

Silently falls back to level 2 if level 3 is unsupported (older
headers or gcc) or to level 0 if unsupported at all (C++, clang).

Well, if only that was the case…

--8<---cut here---start->8---
  from /usr/include/w32api/windows.h:9,
  from 
/mnt/share/cygpkgs/libarchive/libarchive.x86_64/src/libarchive-3.7.4/test_utils/test_common.h:88,
  from 
/mnt/share/cygpkgs/libarchive/libarchive.x86_64/src/libarchive-3.7.4/tar/test/test.h:38,
  from 
/mnt/share/cygpkgs/libarchive/libarchive.x86_64/src/libarchive-3.7.4/tar/test/test_extract_tar_lrz.c:25:
/usr/include/w32api/_mingw_mac.h:319:8: warning: #warning Using 
_FORTIFY_SOURCE=2 (level 3 requires __builtin_dynamic_object_size support) 
[-Wcpp]
   319 | #  warning Using _FORTIFY_SOURCE=2 (level 3 requires 
__builtin_dynamic_object_size support)
--8<---cut here---end--->8---

Can't we conditiohnalize this to depend on the actual compiler support?


This is a bogus warning. Sorry, my bad.

In my contribution of _FORTIFY_SOURCE support to MinGW-w64 from 2019, I 
didn't realize that these warnings also appear if only Win32 API 
includes (windows.h, ...) are used. The related internal macros have 
only an effect if MinGW-w64 runtime includes (stdio.h, string.h, ...) 
are used.


Meantime this has been fixed upstream:
https://sourceforge.net/p/mingw-w64/mingw-w64/ci/f8e088e

--
Regards,
Christian



Re: [ITP] afflib 3.7.20-1

2024-03-22 Thread Christian Franke via Cygwin-apps

Christian Franke wrote:

marco atzeri wrote:

On Wed, Mar 6, 2024 at 11:26 PM Christian Franke via Cygwin-apps  wrote:

...
Should I also rename libtsk to libtsk19 in the planned sleutkit-*-2
package which will add afflib support ?

yes please


The original package is only a few days old and has possibly only a
small but experienced audience, so I expect not much worries if the
change will be explained in the announcement.

not worries at all if you use

libtsk19_OBSOLETES=libtsk

see
https://cygwin.github.io/cygport/pkg_pkg_cygpart.html#PKG_OBSOLETES


Thanks for the info. I will do this that way when libafflib0 package 
is available.




Just for info: This worked as expected. Setup automatically selected 
"Uninstall" for libtsk.




Re: [ITP] afflib 3.7.20-1

2024-03-21 Thread Christian Franke via Cygwin-apps

On Wed, 6 Mar 2024 23:26:05 +0100, Christian Franke wrote:

Jon Turney wrote:
...


be added only when needed for new not backward compatible releases. 
The upstream afflib project is mostly idling, so I don't expect any 
new major lib versions in the near future.


If course, I could rename it to libafflib0 if desired.


As far as I know, there is no cost for doing this, and it saves grief 
if upstream ever bumps the soversion.


Also, it's probably best to explicitly list the filename with 
soversion in the CONTENTS, so that if upstream ever does change the 
soversion, it will be detected as a packaging failure, rather than 
producing a package with a mismatch between the soversion in it's 
name and in it's contents.


Good point, new cygport file is attached.


Any further issues with this ITP?



[ITP] mandoc 1.14.6-1

2024-03-11 Thread Christian Franke via Cygwin-apps
I would like to contribute mandoc. Also present in Debian, Fedora, 
Ubuntu, ... and as the default man page formatter on *BSD.


Useful to check man pages for compatibility with *BSD systems.

The build is reproducible without the need to export SOURCE_DATE_EPOCH.

SUMMARY="BSD mandoc compiler toolset"

DESCRIPTION="\
mandoc is a suite of tools compiling mdoc, the roff macro language of
choice for BSD manual pages, and man, the predominant historical language
for UNIX manuals.  It is small, self-contained, and quite fast.  The main
component of the toolset is the mandoc utility program, based on the
libmandoc validating compiler, to format output for UTF-8 and ASCII
terminals, HTML 5, PostScript, and PDF."

mandoc-1.14.6-1.tar.xz:
usr/bin/demandoc.exe
usr/bin/mandoc.exe
usr/bin/mapropos -> mandoc
usr/bin/mman -> mandoc
usr/bin/msoelim.exe
usr/bin/mwhatis -> mandoc
usr/sbin/mandocdb -> ../bin/mandoc
usr/share/doc/mandoc/*
usr/share/man/man1/demandoc.1.gz
usr/share/man/man1/mandoc.1.gz
usr/share/man/man1/mapropos.1.gz
usr/share/man/man1/mman.1.gz
usr/share/man/man1/msoelim.1.gz
usr/share/man/man1/mwhatis.1.gz
usr/share/man/man5/mandoc.conf.5.gz
usr/share/man/man5/mandoc.db.5.gz
usr/share/man/man7/mandoc_char.7.gz
usr/share/man/man7/mandoc_eqn.7.gz
usr/share/man/man7/mandoc_man.7.gz
usr/share/man/man7/mandoc_mdoc.7.gz
usr/share/man/man7/mandoc_roff.7.gz
usr/share/man/man7/mandoc_tbl.7.gz
usr/share/man/man8/mandocdb.8.gz

--
Regards,
Christian

# cygport script for mandoc
NAME=mandoc
VERSION=1.14.6
RELEASE=1
SOURCE_DATE="2024-03-11 18:00:00 UTC"

SUMMARY="BSD mandoc compiler toolset"

DESCRIPTION="\
mandoc is a suite of tools compiling mdoc, the roff macro language of
choice for BSD manual pages, and man, the predominant historical language
for UNIX manuals.  It is small, self-contained, and quite fast.  The main
component of the toolset is the mandoc utility program, based on the
libmandoc validating compiler, to format output for UTF-8 and ASCII
terminals, HTML 5, PostScript, and PDF."

LICENSE="ISC"
CATEGORY="Text"
REQUIRES="" # zlib0
BUILD_REQUIRES="binutils gcc-core perl_base" # make

HOMEPAGE="https://mandoc.bsd.lv/;
SRC_URI="https://mandoc.bsd.lv/snapshots/${P}.tar.gz;

SOURCE_DATE_EPOCH=$(date -d "${SOURCE_DATE}" +%s) # 'export' is not needed

src_compile() {
cd ${B}
lndirs

cat <<-EOF > configure.local
OSNAME="Cygwin"

PREFIX="/usr"
MANDIR="/usr/share/man"
MANPATH_BASE="/usr/share/man"
MANPATH_DEFAULT="/usr/share/man:/usr/local/share/man"

HAVE_WCHAR=1
CFLAGS="${CFLAGS}"
LDFLAGS="${LDFLAGS}"
LN="ln -sf"

BINM_APROPOS="mapropos" # "apropos"
BINM_MAKEWHATIS="mandocdb"  # "makewhatis"
BINM_MAN="mman" # "man"
BINM_SOELIM="msoelim"   # "soelim"
BINM_WHATIS="mwhatis"   # "whatis"
MANM_EQN="mandoc_eqn"   # "eqn"
MANM_MANCONF="mandoc.conf"  # "man.conf"
MANM_MAN="mandoc_man"   # "man"
MANM_MDOC="mandoc_mdoc" # "mdoc"
MANM_ROFF="mandoc_roff" # "roff"
MANM_TBL="mandoc_tbl"   # "tbl"
EOF

# No cygconf because ./configure is not generated
./configure

cygmake
}

src_test() {
cd ${B}/regress
./regress.pl . ascii tag man html markdown lint

# Unicode chars >= U+1 do not work
# U+1D6C1 (Mathematical Bold Nabla) is output as U+D6C1 (Hangul 
Syllable Hyot)
./regress.pl . utf8 ||
inform "The above failure of the 'nabla' testcase could be 
safely ignored"
}


[PATCH cygport] Add repro-finish command

2024-03-11 Thread Christian Franke via Cygwin-apps

Thanks for accepting the repro-check patch. A minor enhancement is attached.

The function is in pkg_pkg.cygpart instead of pkg_cleanup.cygpart 
because then it is easier to keep it in sync with the other __repro_* 
functions.


PS: I have a local script which checks SPDX Identifiers and expressions. 
Any interest to add this to cygport and then check LICENSE settings?


--
Regards,
Christian

From b08796262308cf1b3a2c063349d024a5ccfd2455 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Mon, 11 Mar 2024 12:12:32 +0100
Subject: [PATCH] Add repro-finish command

This command removes the temporary directory used by repro-check.
---
 README  |  7 ---
 bin/cygport.in  |  4 
 lib/help.cygpart|  1 +
 lib/pkg_pkg.cygpart | 24 +++-
 4 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/README b/README
index 3c9e4d4a..a0897a4f 100644
--- a/README
+++ b/README
@@ -163,9 +163,10 @@ Other COMMANDs are meant primarily for maintainers:
 diff - write a patch file capturing changes to source in the working 
directory
 stage- as upload, but don't request processing of uploaded packages
 announce - compose and send a package announcement
-repro-build - rebuild from created source package to temp directory
-repro-diff  - check whether packages from original and rebuild differ
-repro-check - run repro-build and repro-diff
+repro-build  - rebuild from created source package to temp directory
+repro-diff   - check whether packages from original and rebuild differ
+repro-check  - run repro-build and repro-diff
+repro-finish - delete the temp directory used for rebuild
 
 The standard arguments --help or --version may also be passed to cygport.
 
diff --git a/bin/cygport.in b/bin/cygport.in
index df38a8b5..15bd559e 100755
--- a/bin/cygport.in
+++ b/bin/cygport.in
@@ -801,6 +801,10 @@ do
__pkg_repro_diff
_status=$?
;;
+   repro-finish)
+   __pkg_repro_finish
+   _status=$?
+   ;;
help)
__show_help;
exit 0;
diff --git a/lib/help.cygpart b/lib/help.cygpart
index d28fd7bb..ff03fb5f 100644
--- a/lib/help.cygpart
+++ b/lib/help.cygpart
@@ -59,6 +59,7 @@ __show_help() {
  repro-build   rebuild from created source package to temp 
directory
  repro-diffcheck whether packages from original and 
rebuild differ
  repro-check   run repro-build and repro-diff
+ repro-finish  delete the temp directory used for rebuild
 
See the included README file for further documentation.
 
diff --git a/lib/pkg_pkg.cygpart b/lib/pkg_pkg.cygpart
index 25b80906..07313c66 100644
--- a/lib/pkg_pkg.cygpart
+++ b/lib/pkg_pkg.cygpart
@@ -1048,6 +1048,28 @@ __pkg_repro_diff() {
inform "Rebuild produced identical packages"
 }
 
+__pkg_repro_finish() {
+   local t_spkgdir=${T}/${spkgdir##*/}
+
+   cd ${top}
+
+   __step "Removing rebuild directory in 2 seconds..."
+   inform "Rebuild dir: ${t_spkgdir}"
+   if ! [ -d ${t_spkgdir} ]
+   then
+   inform "Rebuild directory does not exist"
+   return 0
+   fi
+
+   sleep 2 || exit $?
+
+   __step "Removing rebuild directory NOW."
+   rm -rf ${t_spkgdir}
+
+   __step "Finished."
+}
+
 # protect functions
 readonly -f __pkg_binpkg __pkg_diff __gpg_sign __pkg_srcpkg __pkg_dist \
-__pkg_repro_build __pkg_repro_diff __squeeze_whitespace __tar
+__pkg_repro_build __pkg_repro_diff __pkg_repro_finish \
+__squeeze_whitespace __tar
-- 
2.43.0



Re: [PATCH cygport] Add customization support for announce command

2024-03-10 Thread Christian Franke via Cygwin-apps

Jon Turney wrote:

On 23/02/2024 11:23, Christian Franke via Cygwin-apps wrote:

Christian Franke wrote:
The email generated by the cygport announce command is useful, but 
actual use cases are somewhat limited due to the hard-coded email 
submission.


The attached patch adds more flexibility. The patch is on top of the 
"Use correct wording if only one package is announced" patch.


Slightly changed patch attached. Also adjusted to new version of "Use 
correct wording if only one package is announced" patch.




[...]

Thanks for this.


Possible (better?) alternative names for the new settings:
ANNOUNCEMENT_EDITOR
ANNOUNCEMENT_MAILER


Hmmm... I think "ANNOUNCE_EDITOR" and "ANNOUNCE_MAILER" would be
the best for clarity and conciseness.


New patch attached. Is still on top of "Use correct wording ..." patch.

I also added HOMEPAGE to the propagated variables as this should be 
included in an announcement.







-From: ${SMTP_SENDER}
-To: cygwin-annou...@cygwin.com
+${SMTP_SENDER:+From: ${SMTP_SENDER}
+}To: cygwin-annou...@cygwin.com
 Date: $(date -R --date=${msgat})
-Message-Id: <$(date "+%Y%m%d%H%M%S.$$" --date=${msgat})-1-$(echo 
${SMTP_SENDER} | sed 's|.*<\(.*\)>.*|\1|')>
+Message-Id: <$(date "+%Y%m%d%H%M%S.$$" --date=${msgat})-1-$(echo 
${SMTP_SENDER:-cygport} | sed 's|.*<\(.*\)>.*|\1|')>

 Subject: ${NAME} ${PVR}


Can you also explain what this is doing in the commit message, since 
it's not immediately apparent.





If the mail infrastructure always replaces the "From:" line or the 
default one is sufficient, then there is no need to generate one. 
SMTP_SENDER could be left alone then. I added a related comment to 
cygport.conf


From 335cbde3c6c2450051cc739cee60a555b236843e Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Sun, 10 Mar 2024 17:28:09 +0100
Subject: [PATCH] Add customization support for announce command

Two new configuration settings allow to override the launch of
a text editor (ANNOUNCE_EDITOR) and the builtin email submission
(ANNOUNCE_MAILER).  Don't create a "From:" header line if
SMTP_SENDER is undefined or empty.
---
 data/cygport.conf  | 27 +++-
 lib/pkg_upload.cygpart | 57 +-
 2 files changed, 77 insertions(+), 7 deletions(-)

diff --git a/data/cygport.conf b/data/cygport.conf
index 34ccd291..3da744d9 100644
--- a/data/cygport.conf
+++ b/data/cygport.conf
@@ -101,10 +101,35 @@
 #PAGER=
 
 
+#v* Configuration/ANNOUNCE_EDITOR
+#  DESCRIPTION
+#  Shell command string to process the email message created by cygport's
+#  announce command before sending the email.  If undefined, a text editor
+#  will be run, see EDITOR setting above.  If empty, nothing will be run.
+#  If not empty, '/bin/bash' will be launched with the command string passed
+#  with '-c' option and the path of the temporary email message file as '$1'.
+#  The working directory of the shell will be the directory of the cygport
+#  file.  The specified command string will be prepended by shell assignments
+#  of the cygport variables HOMEPAGE, P, PF, PN, PR and PV and all SMTP_*
+#  settings described below.
+#ANNOUNCE_EDITOR=
+
+#v* Configuration/ANNOUNCE_MAILER
+#  DESCRIPTION
+#  Shell command string to process the email message created by cygport's
+#  announce command after editing.  If undefined, the email will be sent
+#  using the builtin perl-based SMTP support.  If empty, nothing will be run.
+#  If not empty, the command string will be handled similar to ANNOUNCE_EDITOR
+#  described above.
+#ANNOUNCE_MAILER=
+
+
 #v* Configuration/SMTP_SENDER
 #  DESCRIPTION
 #  Name and email address, in the form of "First Last " to be used
-#  by cygport's announcement command.
+#  by cygport's announcement command.  If undefined or empty, no "From:" email
+#  header line will be generated.  The local mail tool or the mail provider may
+#  unconditionally replace this header line or only the "" part.
 #  NOTE
 #  Many webmail services do not allow using arbitrary sender address in SMTP
 #  mail, or may first require registering other email addresses as authorized
diff --git a/lib/pkg_upload.cygpart b/lib/pkg_upload.cygpart
index 37bc2d63..9ced1fb5 100644
--- a/lib/pkg_upload.cygpart
+++ b/lib/pkg_upload.cygpart
@@ -168,6 +168,34 @@ EOF
echo "Upload complete."
 }
 
+__pkg_announce_run_cmd_on_msg() {
+   local cmdvar=$1
+   local msg=$2
+   local cmd
+
+   eval cmd="\${${cmdvar}}"
+
+   if [ "${cmd:+y}" != "y" ]
+   then
+   inform "\${${cmdvar}} is empty"
+   return 0
+   fi
+   echo
+   inform "Launching '\${${cmdvar}} ${msg}'"
+
+   /bin/bash -c "cd ${top} || exit 1
+${HOMEPAGE+HOMEPAGE=${HOMEPAGE@Q}}
+P=${P@Q}; PF=${PF@Q}; PN=${PN@Q}; PR=

Re: [PATCH cygport] dodoc: Skip a file if a compressed version already exists

2024-03-10 Thread Christian Franke via Cygwin-apps

Jon Turney wrote:

On 01/03/2024 13:13, Christian Franke via Cygwin-apps wrote:
It IMO makes sense to compress large and rarely viewed doc files like 
change logs. This seems to be common practice on Debian etc.


With current cygport, the following results in ChangeLog and 
ChangeLog.gz in the docdir:


src_install()
{
   ...
   dodoc ChangeLog
   gzip -9 -n "${D}/usr/share/doc/${PN}/ChangeLog"
}


Uh, I don't quite see how this patch will change the behavior of this 
fragment.




Yes, it actually doesn't change the behavior of this fragment itself.


Even more confusing, why isn't this already doing what you want? 
Unless you specify -k/--keep to gzip, the input file is removed, right?


Yes - but after this src_install() the file will be re-added by 
__predoc() unless _CYGPORT_RESTRICT_postinst_doc_ is set. The patch 
avoids this because __predoc() also uses dodoc().




Re: [PATCH cygport] Add more checks of SOURCE_DATE_EPOCH

2024-03-10 Thread Christian Franke via Cygwin-apps

Jon Turney wrote:

On 26/02/2024 19:53, Christian Franke via Cygwin-apps wrote:



Would it not make more sense to just re-export it if set?


If the cygport file decides to set but not export it, there is 
possibly no need to do it. An example is smartmontools.cygport which 
passes the unexported variable as a parameter to configure.


Ok, but exporting it is harmless there, right?


I'm not aware of any corner cases where exporting would break something. 
But leaving the decision to the user would allow to handle such cases. 
It would also allow to check whether it makes a difference and if yes, 
which files are affected.






(so that commands like "SOURCE_DATE_EPOCH=something cygport foo" 
work as expected?)




Would make no difference as the 'VAR=val CMD...' syntax already 
exports the variable to the CMD:


$ unset FOO; FOO=bar sh -c 'sh -c "sh -c printenv\ FOO"'
bar


Ah, right.

So you seem to be saying that the only situation where it's set but 
not exported is where it's set in the cygport.


So we're just making people (need to remember to) explicitly write 
"export SOURCE_DATE_EPOCH" in their cygport where needed?


Exactly.



[ITP] bmake 20240301-1

2024-03-09 Thread Christian Franke via Cygwin-apps
I would like to contribute bmake. Also present in Debian, Fedora, 
FreeBSD, Ubuntu, ...


I occasionally use it to check whether Makefiles are compatible with 
non-GNU versions of make.


SUMMARY="Portable version of the NetBSD 'make' utility"

DESCRIPTION="\
bmake is a portable version of the NetBSD make(1) utility.  It is similar
to GNU make, even though the syntax for the advanced features supported
in Makefiles is very different."

bmake_extras_SUMMARY="${SUMMARY} (additional support files)"

bmake_extras_DESCRIPTION="${DESCRIPTION}
This package contains many additional *.mk files and some support scripts
which are only required if used in Makefiles."

bmake-20240301-1.tar.xz:
usr/bin/bmake.exe
usr/share/doc/bmake/*
usr/share/man/man1/bmake.1.gz
usr/share/bmake/mk/host-target.mk
usr/share/bmake/mk/suffixes.mk
usr/share/bmake/mk/sys.mk
usr/share/bmake/mk/sys.*.mk
usr/share/bmake/mk/sys/Generic.mk

bmake-extras-20240301-1.tar.xz:
usr/share/bmake/mk/*.mk
usr/share/bmake/mk/install-sh
usr/share/bmake/mk/meta2deps.py
usr/share/bmake/mk/meta2deps.sh
usr/share/bmake/mk/mkopt.sh
usr/share/bmake/mk/stage-install.sh
usr/share/bmake/mk/sys/*.mk

--
Regards,
Christian

# cygport script for bmake
NAME=bmake
VERSION=20240301
RELEASE=1
SOURCE_DATE="2024-03-09 12:00:00 UTC"

SUMMARY="Portable version of the NetBSD 'make' utility"

DESCRIPTION="\
bmake is a portable version of the NetBSD make(1) utility.  It is similar
to GNU make, even though the syntax for the advanced features supported
in Makefiles is very different."

LICENSE="BSD-3-Clause"
CATEGORY="Devel"

PKG_NAMES="bmake bmake-extras"

bmake_extras_SUMMARY="${SUMMARY} (additional support files)"
bmake_extras_DESCRIPTION="${DESCRIPTION}  
This package contains many additional *.mk files and some support scripts
which are only required if used in Makefiles."

REQUIRES=""
bmake_extras_REQUIRES="bmake" # bash python3
BUILD_REQUIRES="binutils gcc-core" # "make" not required

HOMEPAGE="https://www.crufty.net/help/sjg/bmake.htm;
SRC_URI="https://www.crufty.net/ftp/pub/sjg/bmake-${PV}.tar.gz
 https://www.crufty.net/ftp/pub/sjg/bmake-${PV}.tar.gz.asc;
SRC_DIR="bmake"

bmake_CONTENTS="
usr/bin
usr/share/doc
usr/share/man
usr/share/${PN}/mk/host-target.mk
usr/share/${PN}/mk/suffixes.mk
usr/share/${PN}/mk/sys.mk
usr/share/${PN}/mk/sys.*.mk
usr/share/${PN}/mk/sys/Generic.mk
"
bmake_extras_CONTENTS="
--exclude=usr/share/${PN}/mk/host-target.mk
--exclude=usr/share/${PN}/mk/suffixes.mk
--exclude=usr/share/${PN}/mk/sys.mk
--exclude=usr/share/${PN}/mk/sys.*.mk
--exclude=usr/share/${PN}/mk/sys/Generic.mk
usr/share/${PN}
"

SOURCE_DATE_EPOCH=$(date -d "$SOURCE_DATE" +%s) # 'export' not needed

src_compile() {
cd ${B}
${S}/boot-strap --prefix=/usr \
--with-default-sys-path=/usr/share/${PN}/mk \
--skip-test op=build
}

src_test() {
cd ${B}
${S}/boot-strap op=test

if false; then # BROKEN_TESTS (all harmless)
TESTS='export opt-chdir opt-keep-going-indirect' \
${S}/boot-strap op=test
fi
}

src_install() {
cd ${B}
# Don't use 'install -s' for bmake.exe.
STRIP_FLAG="" \
${S}/boot-strap --prefix=/usr \
--install-destdir=${D} \
--skip-test op=install
}
--- origsrc/bmake/Makefile  2024-03-09 12:00:00.0 +
+++ src/bmake/Makefile  2024-03-09 12:00:00.0 +
@@ -90,7 +90,7 @@ OS := ${.MAKE.OS:U${uname -s:L:sh}}
 # are we 4.4BSD ?
 isBSD44:=${BSD44_LIST:M${OS}}
 
-.if ${isBSD44} == "" && ${OS:NDarwin:NLinux} != ""
+.if ${isBSD44} == "" && ${OS:NCYGWIN*:NDarwin:NLinux} != ""
 MANTARGET= cat
 INSTALL?=${srcdir}/install-sh
 .if ${MACHINE} == "sun386"
@@ -192,7 +192,7 @@ CONFIGURE_ARGS += --without-makefile
 AUTOCONF_GENERATED_MAKEFILE = Makefile.config
 .include 
 .endif
-SHARE_MK ?= ${SHAREDIR}/mk
+SHARE_MK ?= ${DEFAULT_SYS_PATH}
 MKSRC = ${srcdir}/mk
 INSTALL ?= ${srcdir}/install-sh
 
--- origsrc/bmake/boot-strap2024-03-09 12:00:00.0 +
+++ src/bmake/boot-strap2024-03-09 12:00:00.0 +
@@ -69,6 +69,9 @@
 #  This is useful when $prefix/ is shared by multiple
 #  machines.
 #
+#  --skip-test
+#  Don't run test after build or before install.
+#
 #  Flags relevant when installing:
 #
 #  -DWITHOUT_INSTALL_MK
@@ -212,6 +215,7 @@ srcdir=$Mydir
 mksrc=$Mydir/mk
 objdir=
 quiet=:
+skip_test=false
 
 ${SKIP_RC:+:} source_rc .bmake-boot-strap.rc . "$Mydir/.." "$HOME"
 
@@ -249,6 +253,7 @@ do
 INSTALL_BIN=$HOST_TARGET/bin;;
--install-destdir=*) INSTALL_DESTDIR=`get_optarg "$1"`;;
--install-prefix=*) INSTALL_PREFIX=`get_optarg "$1"`;;
+   --skip-test) skip_test=true;;
-DWITH*) INSTALL_ARGS="$INSTALL_ARGS $1";;
-s|--src) 

Re: [ITP] afflib 3.7.20-1

2024-03-08 Thread Christian Franke via Cygwin-apps

marco atzeri wrote:

On Wed, Mar 6, 2024 at 11:26 PM Christian Franke via Cygwin-apps  wrote:

Jon Turney wrote:

On 06/03/2024 15:39, Christian Franke via Cygwin-apps wrote:

Jon Turney wrote:

Thanks!


libafflib_CONTENTS="
 usr/bin/cygafflib-*.dll

Any reason why this package doesn't include the soversion, i.e. why
not libafflib0?


Libtsk and libafflib are my first library packages, so I'm not sure
what the policy is. My recent package libtsk has been accepted
without soversion, so I omitted it also here. I assumed that the
soversion will

I'm going to suggest that was an oversight in the review.

Should I also rename libtsk to libtsk19 in the planned sleutkit-*-2
package which will add afflib support ?

yes please


The original package is only a few days old and has possibly only a
small but experienced audience, so I expect not much worries if the
change will be explained in the announcement.

not worries at all if you use

libtsk19_OBSOLETES=libtsk

see
https://cygwin.github.io/cygport/pkg_pkg_cygpart.html#PKG_OBSOLETES


Thanks for the info. I will do this that way when libafflib0 package is 
available.


--
Regards,
Christian



Re: [ITP] afflib 3.7.20-1

2024-03-06 Thread Christian Franke via Cygwin-apps

Jon Turney wrote:

On 06/03/2024 15:39, Christian Franke via Cygwin-apps wrote:

Jon Turney wrote:


Thanks!



libafflib_CONTENTS="
usr/bin/cygafflib-*.dll


Any reason why this package doesn't include the soversion, i.e. why 
not libafflib0?




Libtsk and libafflib are my first library packages, so I'm not sure 
what the policy is. My recent package libtsk has been accepted 
without soversion, so I omitted it also here. I assumed that the 
soversion will 


I'm going to suggest that was an oversight in the review.


Should I also rename libtsk to libtsk19 in the planned sleutkit-*-2 
package which will add afflib support ?
The original package is only a few days old and has possibly only a 
small but experienced audience, so I expect not much worries if the 
change will be explained in the announcement.





be added only when needed for new not backward compatible releases. 
The upstream afflib project is mostly idling, so I don't expect any 
new major lib versions in the near future.


If course, I could rename it to libafflib0 if desired.


As far as I know, there is no cost for doing this, and it saves grief 
if upstream ever bumps the soversion.


Also, it's probably best to explicitly list the filename with 
soversion in the CONTENTS, so that if upstream ever does change the 
soversion, it will be detected as a packaging failure, rather than 
producing a package with a mismatch between the soversion in it's name 
and in it's contents.


Good point, new cygport file is attached.




(Cygport should perhaps and detect and warn about apparently 
soversioned libraries that aren't in appropriately named packages, 
but...)




... this is possibly a good idea.

# cygport script for afflib
NAME=afflib
VERSION=3.7.20
RELEASE=1
SOURCE_DATE="2024-03-06 22:00:00 UTC"

SUMMARY="Library and tools for the Advanced Forensic Format"

DESCRIPTION="\
The Advanced Forensic Format (AFF) is a file format for storing computer
forensic information.  It supports metadata, compression, encryption and
signing."

LICENSE="BSD-4-clause"

PKG_NAMES="afflib-tools libafflib0 libafflib-devel"

afflib_tools_SUMMARY="${SUMMARY} (tools)"
afflib_tools_DESCRIPTION="${DESCRIPTION}  
This package contains tools to examine, convert, compare, copy, encrypt,
decrypt and sign AFF files."

libafflib0_SUMMARY="${SUMMARY} (runtime)"
libafflib0_DESCRIPTION="${DESCRIPTION}  
This package contains the runtime library for afflib."

libafflib_devel_SUMMARY="${SUMMARY} (development)"
libafflib_devel_DESCRIPTION="${DESCRIPTION}  
This package contains the development files for libafflib0."

CATEGORY="Devel Libs Utils"
afflib_tools_CATEGORY="Utils"
libafflib0_CATEGORY="Libs"
libafflib_devel_CATEGORY="Devel Libs"

afflib_tools_REQUIRES="" # libafflib0 libexpat1 libgcc1 libreadline7 libssl3 
libstdc++6
libafflib0_REQUIRES="" # libcurl4 libexpat1 libgcc1 libssl3 libstdc++6 zlib0
libafflib_devel_REQUIRES="" # libafflib0 libssl-devel pkg-config

BUILD_REQUIRES="
  binutils gcc-g++ gzip libcurl-devel libexpat-devel libreadline-devel
  libssl-devel zlib-devel
" # make

HOMEPAGE="https://github.com/sshock/AFFLIBv3;
SRC_URI="https://codeload.github.com/sshock/AFFLIBv3/tar.gz/refs/tags/v${PV}#/${P}.tar.gz;
SRC_DIR="AFFLIBv3-${PV}"

afflib_tools_CONTENTS="
--exclude=usr/bin/cygafflib-0.dll
usr/bin
usr/share
"
libafflib0_CONTENTS="
usr/bin/cygafflib-0.dll
"
libafflib_devel_CONTENTS="
usr/include/afflib
usr/lib
"

DIFF_EXCLUDES="lzma443"

export SOURCE_DATE_EPOCH=$(date -d "$SOURCE_DATE" +%s)

src_compile() {
cd ${S}
cygautoreconf

cd ${B}
cygconf --enable-shared --disable-static \
--enable-qemu --enable-s3 --enable-threading \
--with-curl --with-expat --with-gnu-ld \
--disable-fuse --disable-python

# configure sets _FORTIFY_SOURCE=2 which would override level 3
# libtool requires '-no-undefined'
cygmake CFLAGS="${CFLAGS}" CXXFLAGS="${CXXFLAGS}" \
LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-no-undefined"
}

src_install() {
cd ${B}
cyginstall

cd ${S}
dodoc doc/*.txt

cd ${D}
# affuse only prints that FUSE is not supported
rm -v usr/bin/affuse.exe usr/share/man/man1/affuse.1

gzip -9nv usr/share/doc/${PN}/*.txt
}


Re: [ITP] afflib 3.7.20-1

2024-03-06 Thread Christian Franke via Cygwin-apps

Jon Turney wrote:


Thanks!



libafflib_CONTENTS="
usr/bin/cygafflib-*.dll


Any reason why this package doesn't include the soversion, i.e. why 
not libafflib0?




Libtsk and libafflib are my first library packages, so I'm not sure what 
the policy is. My recent package libtsk has been accepted without 
soversion, so I omitted it also here. I assumed that the soversion will 
be added only when needed for new not backward compatible releases. The 
upstream afflib project is mostly idling, so I don't expect any new 
major lib versions in the near future.


If course, I could rename it to libafflib0 if desired.


rm -v usr/bin/affuse.exe usr/share/man/man1/affuse.1 # 
--disable-fuse


I guess this comment means something to someone.  But it doesn't tell 
me anything...




:-)

Long form: If (Linux-)FUSE is unavailable, the affuse tool only prints 
that this is the case and exits then. There is no need to distribute it.




[ITP] afflib 3.7.20-1

2024-03-06 Thread Christian Franke via Cygwin-apps
I would like to contribute afflib. Also present in Debian, Fedora, 
Ubuntu, ... but package naming differs:


Debian/Ubuntu: afflib-tools, libafflib0v5, libafflib-dev
Fedora: afftools, afflib, afflib-devel

It is indented to enable afflib format support for the next version of 
the sleuthkit package.


SUMMARY="Library and tools for the Advanced Forensic Format"

DESCRIPTION="\
The Advanced Forensic Format (AFF) is a file format for storing computer
forensic information.  It supports metadata, compression, encryption and
signing."

afflib_tools_DESCRIPTION="...
This package contains tools to examine, convert, compare, copy, encrypt,
decrypt and sign AFF files."

afflib-tools-3.7.20-1.tar.xz:
usr/bin/affcat.exe
usr/bin/affcompare.exe
usr/bin/affconvert.exe
usr/bin/affcopy.exe
usr/bin/affcrypto.exe
usr/bin/affdiskprint.exe
usr/bin/affinfo.exe
usr/bin/affix.exe
usr/bin/affrecover.exe
usr/bin/affsegment.exe
usr/bin/affsign.exe
usr/bin/affstats.exe
usr/bin/affverify.exe
usr/bin/affxml.exe
usr/share/doc/afflib/*
usr/share/man/man1/aff*.1.gz

libafflib-3.7.20-1.tar.xz:
usr/bin/cygafflib-0.dll

libafflib-devel-3.7.20-1.tar.xz:
usr/include/afflib/*.h
usr/lib/libafflib.dll.a
usr/lib/pkgconfig/afflib.pc

--
Regards,
Christian

# cygport script for afflib
NAME=afflib
VERSION=3.7.20
RELEASE=1
SOURCE_DATE="2024-03-06 13:00:00 UTC"

SUMMARY="Library and tools for the Advanced Forensic Format"

DESCRIPTION="\
The Advanced Forensic Format (AFF) is a file format for storing computer
forensic information.  It supports metadata, compression, encryption and
signing."

LICENSE="BSD-4-clause"

PKG_NAMES="afflib-tools libafflib libafflib-devel"

afflib_tools_SUMMARY="${SUMMARY} (tools)"
afflib_tools_DESCRIPTION="${DESCRIPTION}  
This package contains tools to examine, convert, compare, copy, encrypt,
decrypt and sign AFF files."

libafflib_SUMMARY="${SUMMARY} (runtime)"
libafflib_DESCRIPTION="${DESCRIPTION}  
This package contains the runtime library for afflib."

libafflib_devel_SUMMARY="${SUMMARY} (development)"
libafflib_devel_DESCRIPTION="${DESCRIPTION}  
This package contains the development files for libafflib."

CATEGORY="Devel Libs Utils"
afflib_tools_CATEGORY="Utils"
libafflib_CATEGORY="Libs"
libafflib_devel_CATEGORY="Devel Libs"

afflib_tools_REQUIRES="" # libafflib libexpat1 libgcc1 libreadline7 libssl3 
libstdc++6
libafflib_REQUIRES="" # libcurl4 libexpat1 libgcc1 libssl3 libstdc++6 zlib0
libafflib_devel_REQUIRES="" # libafflib libssl-devel pkg-config

BUILD_REQUIRES="
  binutils gcc-g++ gzip libcurl-devel libexpat-devel libreadline-devel
  libssl-devel zlib-devel
" # make

HOMEPAGE="https://github.com/sshock/AFFLIBv3;
SRC_URI="https://codeload.github.com/sshock/AFFLIBv3/tar.gz/refs/tags/v${PV}#/${P}.tar.gz;
SRC_DIR="AFFLIBv3-${PV}"

afflib_tools_CONTENTS="
--exclude=usr/bin/cygafflib-*.dll
usr/bin
usr/share
"
libafflib_CONTENTS="
usr/bin/cygafflib-*.dll
"
libafflib_devel_CONTENTS="
usr/include/afflib
usr/lib
"

DIFF_EXCLUDES="lzma443"

export SOURCE_DATE_EPOCH=$(date -d "$SOURCE_DATE" +%s)

src_compile() {
cd ${S}
cygautoreconf

cd ${B}
cygconf --enable-shared --disable-static \
--enable-s3 --enable-threading --enable-qemu \
--with-curl --with-gnu-ld --with-expat \
--disable-fuse --disable-python

# configure sets _FORTIFY_SOURCE=2 which would override level 3
# libtool requires '-no-undefined'
cygmake CFLAGS="${CFLAGS}" CXXFLAGS="${CXXFLAGS}" \
LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-no-undefined"
}

src_install() {
cd ${B}
cyginstall

cd ${S}
dodoc doc/*.txt

cd ${D}
rm -v usr/bin/affuse.exe usr/share/man/man1/affuse.1 # --disable-fuse
gzip -9nv usr/share/doc/${PN}/*.txt
}
--- origsrc/AFFLIBv3-3.7.20/lib/Makefile.am 2024-03-06 13:00:00.0 
+
+++ src/AFFLIBv3-3.7.20/lib/Makefile.am 2024-03-06 13:00:00.0 +
@@ -76,7 +76,7 @@ install-exec-hook:
  then echo $(libdir) already installed ; \
  else echo installing $(libdir) in $(DESTDIR)/etc/ld.so.conf ; \
   echo $(libdir) >> $(DESTDIR)/etc/ld.so.conf ; \
- PATH=$(PATH):/sbin; \
+ PATH="$(PATH):/sbin"; \
  ldconfig; \
   fi ; \
  echo "*" ;\
--- origsrc/AFFLIBv3-3.7.20/tools/affcopy.cpp   2024-03-06 13:00:00.0 
+
+++ src/AFFLIBv3-3.7.20/tools/affcopy.cpp   2024-03-06 13:00:00.0 
+
@@ -146,7 +146,7 @@ void unlink_outfiles(vector outf
 if(failure) exit(1);
 }
 
-#if !defined( __BSD_VISIBLE) && !defined(isnumber)
+#if (!defined(__BSD_VISIBLE) || defined(__CYGWIN__)) && !defined(isnumber)
 #define isnumber(x) isdigit(x)
 #endif
 


Re: [ITP] sleuthkit 4.12.1

2024-03-02 Thread Christian Franke via Cygwin-apps

Hi Marco,

Marco Atzeri via Cygwin-apps wrote:

On 02/03/2024 13:05, Christian Franke via Cygwin-apps wrote:
I would like to contribute sleuthkit. Also present in Debian, Fedora, 
Ubuntu, ...


SUMMARY="Tools for analysis of volume and filesystem data"

DESCRIPTION="The Sleuth Kit (TSK) is a collection of command line tools
for disk images.  It allows to analyze volume and filesystem data,
examine disk layout, recover deleted files, etc.  Many partition and
filesystem formats are supported."

libtsk_SUMMARY="${SUMMARY} (runtime)"

libtsk_devel_SUMMARY="${SUMMARY} (development)"


I'm not sure about the LICENSE string:

LICENSE="CPL-1.0 AND GPL-2.0-or-later"

The license/README.md file mentions a bunch of licenses, see comment 
in cygport file. CPL-1.0 is the main license, one separate tool uses 
GPL-2.0-or-later.



The source package supports reproducible builds except for 
libtsk-devel (timestamps in *.a files).


Hi Christian,

usually we do no distribute static library


Didn't know, sorry. Makes plenty of sense, at least to prevent that 
other packages accidentally link to the static lib.





Any reason here ?


No, static lib removed.



except that GTG

$ git diff |grep "^+"
+++ b/cygwin-pkg-maint
+sleuthkit    Christian Franke



Thanks,
Christian



[ITP] sleuthkit 4.12.1

2024-03-02 Thread Christian Franke via Cygwin-apps
I would like to contribute sleuthkit. Also present in Debian, Fedora, 
Ubuntu, ...


SUMMARY="Tools for analysis of volume and filesystem data"

DESCRIPTION="The Sleuth Kit (TSK) is a collection of command line tools
for disk images.  It allows to analyze volume and filesystem data,
examine disk layout, recover deleted files, etc.  Many partition and
filesystem formats are supported."

libtsk_SUMMARY="${SUMMARY} (runtime)"

libtsk_devel_SUMMARY="${SUMMARY} (development)"


I'm not sure about the LICENSE string:

LICENSE="CPL-1.0 AND GPL-2.0-or-later"

The license/README.md file mentions a bunch of licenses, see comment in 
cygport file. CPL-1.0 is the main license, one separate tool uses 
GPL-2.0-or-later.



The source package supports reproducible builds except for libtsk-devel 
(timestamps in *.a files).


Abbreviated list of files:

sleuthkit-4.12.1-1.tar.xz:
usr/bin/blkcalc.exe
usr/bin/blkcat.exe
usr/bin/blkls.exe
usr/bin/blkstat.exe
usr/bin/fcat.exe
usr/bin/ffind.exe
usr/bin/fiwalk.exe
usr/bin/fls.exe
usr/bin/fsstat.exe
usr/bin/hfind.exe
usr/bin/icat.exe
usr/bin/ifind.exe
usr/bin/ils.exe
usr/bin/img_cat.exe
usr/bin/img_stat.exe
usr/bin/istat.exe
usr/bin/jcat.exe
usr/bin/jls.exe
usr/bin/jpeg_extract.exe
usr/bin/mactime
usr/bin/mmcat.exe
usr/bin/mmls.exe
usr/bin/mmstat.exe
usr/bin/pstat.exe
usr/bin/sigfind.exe
usr/bin/sorter
usr/bin/srch_strings.exe
usr/bin/tsk_comparedir.exe
usr/bin/tsk_gettimes.exe
usr/bin/tsk_imageinfo.exe
usr/bin/tsk_loaddb.exe
usr/bin/tsk_recover.exe
usr/bin/usnjls.exe
usr/share/doc/sleuthkit/*
usr/share/man/man1/*
usr/share/tsk/sorter/*.sort

libtsk-4.12.1-1.tar.xz:
usr/bin/cygtsk-19.dll

libtsk-devel-4.12.1-1.tar.xz:
usr/include/tsk/*
usr/lib/libtsk.a
usr/lib/libtsk.dll.a
usr/lib/pkgconfig/tsk.pc
usr/share/doc/sleuthkit/samples/*.cpp



Real world use case: Check whether the SSD TRIM command actually works:

$ # Create a test file (> ~3*256B to prevent resident file)
$ printf 'Line %s\n' {0001..0100} > trim_check

$ # Get full path of file
$ cygpath -am trim_check
D:/tmp/trim_check

$ # Find raw device of partition
$ grep D: /proc/partitions # or: ls -l /dev/disk/by-drive/d
    8    20 629145944 sdb4   D:\

$ # Find inode (here: $MFT index) of file
$ ifind -n /tmp/trim_check /dev/sdb4
339065

$ # Find cluster(s) used by inode
$ istat /dev/sdb4 339065
...
Name: TRIM_C~1
...
Name: trim_check
...
Type: $DATA (128-4)   Name: N/A   Non-Resident size: 1000  init_size: 1000
7876740

$ # Read cluster (assumes 4KiB cluster size, could be checked with fsstat)
$ dd if=/dev/sdb4 bs=4096 count=1 skip=7876740 iflag=direct status=none 
| cat -A

Line 0001$
Line 0002$
...

$ # Remove file, flush buffers and wait
$ rm trim_check; sync; sleep 10

$ # Re-read cluster
$ dd if=/dev/sdb4 bs=4096 count=1 skip=7876740 iflag=direct status=none | od
000 00 00 00 00 00 00 00 00
*
001

$ echo "TRIM works!"
TRIM works!


--
Regards,
Christian




# cygport script for sleuthkit
NAME=sleuthkit
VERSION=4.12.1
RELEASE=1
SOURCE_DATE="2024-03-02 11:00:00 UTC"

SUMMARY="Tools for analysis of volume and filesystem data"

DESCRIPTION="The Sleuth Kit (TSK) is a collection of command line tools
for disk images.  It allows to analyze volume and filesystem data,
examine disk layout, recover deleted files, etc.  Many partition and
filesystem formats are supported."

LICENSE="CPL-1.0 AND GPL-2.0-or-later"
# Licenses mentioned in licenses/README.md:
# Apache-2.0 # case-uco/*, win32/rejistry++/* (code not used)
# BSD-3-Clause   # samples/*, tsk/fs/lzvn.c
# CPL-1.0# The Sleuth Kit (TSK) license
# GPL-2.0-or-later   # tools/srchtools/srch_strings.c
# GPL-3.0-or-later   # m4/ax_pthread.m4 (... WITH Autoconf-exception-3.0)
# IPL-1.0# The Coroner's Toolkit (TCT) license
# ISC# tools/fiwalk/src/base64.*
# "public domain"# tools/fiwalk/*, tsk/base/sha1.c
# MIT# tsk/auto/guid.cpp
# RSA-MD # tsk/base/md5c.c
# "Unicode"  # tsk/base/tsk_unicode.*

CATEGORY="Utils"
PKG_NAMES="sleuthkit libtsk libtsk-devel"

REQUIRES="" # libgcc1 libstdc++6 libtsk perl-DateTime-TimeZone perl_base
libtsk_REQUIRES="" # libgcc1 libsqlite3_0 libstdc++6 zlib0
libtsk_devel_REQUIRES="" # libtsk pkg-config
BUILD_REQUIRES="
  binutils cygwin-devel gcc-g++ gzip libsqlite3-devel perl_base zlib-devel
" # make

HOMEPAGE="https://www.sleuthkit.org/sleuthkit/;
SRC_URI="https://github.com/sleuthkit/sleuthkit/releases/download/${P}/${P}.tar.gz;

libtsk_SUMMARY="${SUMMARY} (runtime)"
libtsk_DESCRIPTION="${DESCRIPTION}  
This package contains the runtime library for sleuthkit."

libtsk_devel_SUMMARY="${SUMMARY} (development)"
libtsk_devel_DESCRIPTION="${DESCRIPTION}  
This package contains the development files for libtsk."

sleuthkit_CONTENTS="
--exclude=usr/bin/cygtsk-*.dll
--exclude=usr/share/doc/${PN}/samples
usr/bin
usr/share
"
libtsk_CONTENTS="

Re: [PATCH cygport] Add repro-check command

2024-03-01 Thread Christian Franke via Cygwin-apps

Christian Franke wrote:
This could be used to check whether a package is possibly 
reproducible. Then it could make sense to add a reasonable 
SOURCE_DATE_EPOCH value to the cygport file.


Example:

$ export SOURCE_DATE_EPOCH=$(date +%s)

$ cygport project.cygport all repro-check
...
*** Info: Build reproducibility test succeeded

$ TZ=UTC cygport project.cygport repro-check
...
*** Info: Build reproducibility test succeeded

$ unset SOURCE_DATE_EPOCH

$ cygport project.cygport repro-check
...
*** ERROR: Build reproducibility test failed



An enhanced version of the patch is attached. The build and diff could 
now be run also individually and the diff report includes individual 
files from the packages.


As a side effect, this enables another use case: Check whether changes 
to cygport only change the expected files.


$ cygport project.cygport all repro-check
...
*** Info: Rebuild produced identical packages

$ editor project.cygport
... Change some comments ...

$ cygport project.cygport all repro-diff
...
Differing files found:
! dist/project/project-1.2-3-src.tar.xz
! spkg/project-1.2-3.src/project.cygport

*** ERROR: Rebuild differs from original

--
Regards,
Christian

From 152a21dfad4c786cff1712e6aa1c33f2db0b6a75 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Fri, 1 Mar 2024 19:46:50 +0100
Subject: [PATCH] Add repro-build, repro-diff und repro-check commands

These commands check for reproducibility of distribution packages.
The repro-build command unpacks the source package from the dist
directory to the temp directory and performs a nested rebuild of
the packages there.
The repro-diff command compares original and rebuild packages.
If different, a report about individual differing files in dist,
inst and spkg directories is printed.
The repro-check command combines both commands.
---
 README  |  3 +++
 bin/cygport.in  | 17 +
 lib/help.cygpart|  3 +++
 lib/pkg_pkg.cygpart | 58 -
 4 files changed, 80 insertions(+), 1 deletion(-)

diff --git a/README b/README
index fd16df6b..3c9e4d4a 100644
--- a/README
+++ b/README
@@ -163,6 +163,9 @@ Other COMMANDs are meant primarily for maintainers:
 diff - write a patch file capturing changes to source in the working 
directory
 stage- as upload, but don't request processing of uploaded packages
 announce - compose and send a package announcement
+repro-build - rebuild from created source package to temp directory
+repro-diff  - check whether packages from original and rebuild differ
+repro-check - run repro-build and repro-diff
 
 The standard arguments --help or --version may also be passed to cygport.
 
diff --git a/bin/cygport.in b/bin/cygport.in
index 5fc89eaf..a2c2b5a3 100755
--- a/bin/cygport.in
+++ b/bin/cygport.in
@@ -29,6 +29,10 @@ set -e;
 #
 

 
+# Preserve original environment for repro-check command
+declare -r _cygport_orig_env=$(export)
+declare -r _cygport_orig_pwd=$(pwd)
+
 # for regexes, sort, etc.
 export LC_COLLATE=C
 
@@ -784,6 +788,19 @@ do
test ${PIPESTATUS[0]} -eq 0
_status=$?;
;;
+   repro-build)
+   __pkg_repro_build
+   _status=$?
+   ;;
+   repro-diff)
+   __pkg_repro_diff
+   _status=$?
+   ;;
+   repro-check)
+   __pkg_repro_build && \
+   __pkg_repro_diff
+   _status=$?
+   ;;
help)
__show_help;
exit 0;
diff --git a/lib/help.cygpart b/lib/help.cygpart
index a7f30f7a..d28fd7bb 100644
--- a/lib/help.cygpart
+++ b/lib/help.cygpart
@@ -56,6 +56,9 @@ __show_help() {
  finishdelete the working directory
  all   run prep, compile, install and package
  all-test  run prep, compile, install and package-test
+ repro-build   rebuild from created source package to temp 
directory
+ repro-diffcheck whether packages from original and 
rebuild differ
+ repro-check   run repro-build and repro-diff
 
See the included README file for further documentation.
 
diff --git a/lib/pkg_pkg.cygpart b/lib/pkg_pkg.cygpart
index 756a687c..3c531c0e 100644
--- a/lib/pkg_pkg.cygpart
+++ b/lib/pkg_pkg.cygpart
@@ -992,6 +992,62 @@ _EOF
fi
 }
 
+__pkg_repro_build() {
+   local srcpkg=${distdir}/${PN}/${PF}-src.tar.${TAR_COMPRESSION_EXT}
+   local t_spkgdir=${T}/${spkgdir##*/}
+   local t_workdir=${t_spkgdir}/${PF}.${ARCH}
+   local t_cygport="cygport ${cygportfile} finish all"
+   local rc
+
+   __stage "Reb

[PATCH cygport] dodoc: Skip a file if a compressed version already exists

2024-03-01 Thread Christian Franke via Cygwin-apps
It IMO makes sense to compress large and rarely viewed doc files like 
change logs. This seems to be common practice on Debian etc.


With current cygport, the following results in ChangeLog and 
ChangeLog.gz in the docdir:


src_install()
{
  ...
  dodoc ChangeLog
  gzip -9 -n "${D}/usr/share/doc/${PN}/ChangeLog"
}

The attached patch fixes this and also adds some missing documentation.

--
Regards,
Christian

From 1934651b93cda92207429ac91b964cff220c76d5 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Fri, 1 Mar 2024 13:56:45 +0100
Subject: [PATCH] dodoc: Skip a file if a compressed version already exists

This prevents that __prepdoc() also adds the uncompressed version
of a default doc file if src_install() installed the compressed
version.  Also add missing documentation about the handling of
FILE.md, FILE.rst and FILE.txt.
---
 lib/src_install.cygpart | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/lib/src_install.cygpart b/lib/src_install.cygpart
index 481457dc..7aca673c 100644
--- a/lib/src_install.cygpart
+++ b/lib/src_install.cygpart
@@ -162,9 +162,12 @@ docinto() {
 #  DESCRIPTION
 #  Installs the given files or directories into $D/usr/share/doc/PN/, or a
 #  subdirectory thereof specified by the previous call to docinto.
+#  If a FILE does not exist, FILE.md, FILE.rst and FILE.txt are also
+#  considered.  A FILE is skipped if the destination file or a compressed
+#  version (.bz2, .gz, .xz, .zstd) of it already exists.
 #
 dodoc() {
-   local docdir d f i x
+   local docdir d e f i x
 
case "${_docinto_dir}" in
'') docdir=/usr/share/doc/${PN} ;;
@@ -191,6 +194,10 @@ dodoc() {
do
if [ -s "${i}${x}" -a ! -f 
"${D}${docdir}/${i}${x}" ]
then
+   for e in bz2 gz xz zst
+   do
+   ! [ -f 
"${D}${docdir}/${i}${x}.${e}" ] || continue 2
+   done
__doinstall 0644 "${i}${x}" ${docdir} 
|| error "dodoc ${i} failed"
break
fi
-- 
2.43.0



Re: [PATCH cygport] Set TZ=UTC if SOURCE_DATE_EPOCH is used

2024-02-28 Thread Christian Franke via Cygwin-apps

Christian Franke wrote:
Further tests of 'repro-check' patch revealed that the "origsrc/*" 
timestamps in patch files contain the local timezone offset.




This would be no longer needed for patch files if "Modify origsrc 
timestamp in patch files if SOURCE_DATE_EPOCH is used" would be applied.


This TZ=UTC patch could possibly be dropped then.


The attached patch is on top of the "Add more checks of 
SOURCE_DATE_EPOCH" patch. It could also be applied independently but 
then requires conflict resolution due to the then missing 'else' branch.






[PATCH cygport] Modify origsrc timestamp in patch files if SOURCE_DATE_EPOCH is used

2024-02-28 Thread Christian Franke via Cygwin-apps
Found during testing of 'repro-check' patch with getent-2.18.90-5 source 
package.


This patch also removes the requirement to set TZ=UTC before patches are 
generated.


--
Regards,
Christian

From 342ff5113499a83b2ffda441ddc80b4952b400f8 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Wed, 28 Feb 2024 16:46:51 +0100
Subject: [PATCH] Modify origsrc timestamp in patch files if SOURCE_DATE_EPOCH
 is used

Also the timestamp of a file in origsrc directory may be newer than
SOURCE_DATE_EPOCH if modified after unpacking e.g. by a src_*_hook.
---
 lib/pkg_pkg.cygpart | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/pkg_pkg.cygpart b/lib/pkg_pkg.cygpart
index 756a687c..414ec4b4 100644
--- a/lib/pkg_pkg.cygpart
+++ b/lib/pkg_pkg.cygpart
@@ -508,9 +508,9 @@ __pkg_diff() {
 
if [ -n "${SOURCE_DATE_EPOCH}" ]
then
-   # Ensure that the timestamp comment in the generated patch file 
is reproducible
+   # Ensure that the timestamp comments in the patch files are 
reproducible
source_date=$(date -d @"${SOURCE_DATE_EPOCH}" -u +'%Y-%m-%d 
%H:%M:%S.0 +')
-   sed -b -e  "s|^\(+++ [^\t]*\t\).*\$|\1${source_date}|" \
+   sed -E -b -e "s/^((---|\+\+\+) [^\t]*\t).*\$/\1${source_date}/" 
\
-i ${optional_patchfiles} ${patchdir}/${src_patchfile}
fi
 
-- 
2.43.0



Re: [PATCH cygport] Add more checks of SOURCE_DATE_EPOCH

2024-02-26 Thread Christian Franke via Cygwin-apps

Jon Turney wrote:

On 16/02/2024 12:29, Christian Franke via Cygwin-apps wrote:
Fail if it is out of range. Warn if it lies in the future. Inform 
whether it is set or set but not exported.


What is the valid range here?


The range accepted by 'date -d @EPOCH ...', later used to adjust the 
patch timestamps.


The test could also be removed as date interestingly accepts a (too) 
wide range of values :-)


$ date -d @$((1<<55))
Sun Jun 13 08:26:08 CEST 1141709097

$ date -d @$((1<<56))
date: time ‘72057594037927936’ is out of range

$ date -d @$((-(1<<55)))
Sun Jul 20 18:27:20 LMT -1141705158

$ date -d @$((-(1<<56)))
date: time ‘-72057594037927936’ is out of range



Would it not make more sense to just re-export it if set?


If the cygport file decides to set but not export it, there is possibly 
no need to do it. An example is smartmontools.cygport which passes the 
unexported variable as a parameter to configure.



(so that commands like "SOURCE_DATE_EPOCH=something cygport foo" work 
as expected?)




Would make no difference as the 'VAR=val CMD...' syntax already exports 
the variable to the CMD:


$ unset FOO; FOO=bar sh -c 'sh -c "sh -c printenv\ FOO"'
bar



[PATCH cygport] Fix variable expansion in error message of embedded SMTP perl script

2024-02-23 Thread Christian Franke via Cygwin-apps

Harmless bug ...

--
Regards,
Christian

From b1074f4cfe549c852be7fa59d85d312c9579cf0d Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Fri, 23 Feb 2024 13:04:21 +0100
Subject: [PATCH] Fix variable expansion in error message of embedded SMTP perl
 script

---
 lib/pkg_upload.cygpart | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/pkg_upload.cygpart b/lib/pkg_upload.cygpart
index dcae8e2c..cdeae283 100644
--- a/lib/pkg_upload.cygpart
+++ b/lib/pkg_upload.cygpart
@@ -222,7 +222,7 @@ if (\$smtp_encryption eq 'tls') {
require Net::SMTP::SSL;
\$smtp->command('STARTTLS');
\$smtp->response();
-   \$smtp->code == 220 or die "$server does not support STARTTLS";
+   \$smtp->code == 220 or die "\$smtp_server does not support STARTTLS";
\$smtp = Net::SMTP::SSL->start_SSL(\$smtp) or die "STARTTLS failed";
\$smtp->hello(\$smtp_server);
 }
-- 
2.43.0



Re: [PATCH cygport] Add customization support for announce command

2024-02-23 Thread Christian Franke via Cygwin-apps

Christian Franke wrote:
The email generated by the cygport announce command is useful, but 
actual use cases are somewhat limited due to the hard-coded email 
submission.


The attached patch adds more flexibility. The patch is on top of the 
"Use correct wording if only one package is announced" patch.


Slightly changed patch attached. Also adjusted to new version of "Use 
correct wording if only one package is announced" patch.





Examples for cygport.conf settings:

ANNOUNCE_EDITOR='printf "\\nRegards,\\n$PN package maintainer\\n" >>"$1"'

ANNOUNCE_EDITOR='
n=$(wc -l <"$1") && cat >>"$1" <>> This is an update to the latest upstream release.
  >>> This is a bugfix release.
  <<< PLEASE EDIT >>>

Regards,
$PN package maintainer
EOF
vim +$((n+2)) "$1" && ! grep -E "<<<|>>>" "$1"
'

ANNOUNCE_TO_CMD='cat "$1" >/dev/clipboard'

ANNOUNCE_TO_CMD='
sed "1,/^\$/d" "$1" >$PF-announcement.txt &&
echo "Announcement placed here: $(pwd)/$PF-announcement.txt"
'

ANNOUNCE_TO_CMD='
/usr/local/sbin/custom-mailer \
  --sender="$SMTP_SENDER" \
  --smarthost="$SMTP_SERVER" \
  ...more...options... \
  cygwin-annou...@cygwin.com <"$1"
'



Possible (better?) alternative names for the new settings:
ANNOUNCEMENT_EDITOR
ANNOUNCEMENT_MAILER

From 14709f0a1ed19c7d00588fb2a1fa7273d47e00fd Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Fri, 23 Feb 2024 12:04:17 +0100
Subject: [PATCH] Add customization support for announce command

Two new configuration settings allow to override the launch of
a text editor (ANNOUNCE_EDITOR) and the builtin email submission
(ANNOUNCE_TO_CMD).
---
 data/cygport.conf  | 23 +
 lib/pkg_upload.cygpart | 56 +-
 2 files changed, 73 insertions(+), 6 deletions(-)

diff --git a/data/cygport.conf b/data/cygport.conf
index 34ccd291..48dc7bfe 100644
--- a/data/cygport.conf
+++ b/data/cygport.conf
@@ -101,6 +101,29 @@
 #PAGER=
 
 
+#v* Configuration/ANNOUNCE_EDITOR
+#  DESCRIPTION
+#  Shell command string to process the email message created by cygport's
+#  announce command before sending the email.  If undefined, a text editor
+#  will be run, see EDITOR setting above.  If empty, nothing will be run.
+#  If not empty, '/bin/bash' will be launched with the command string passed
+#  with '-c' option and the path of the temporary email message file as '$1'.
+#  The working directory of the shell will be the directory of the cygport
+#  file.  The specified command string will be prepended by shell assignments
+#  of the cygport variables P, PF, PN, PR and PV and all SMTP_* settings
+#  described below.
+#ANNOUNCE_EDITOR=
+
+#v* Configuration/ANNOUNCE_TO_CMD
+#  DESCRIPTION
+#  Shell command string to process the email message created by cygport's
+#  announce command after editing.  If undefined, the email will be sent
+#  using the builtin perl-based SMTP support.  If empty, nothing will be run.
+#  If not empty, the command string will be handled similar to ANNOUNCE_EDITOR
+#  described above.
+#ANNOUNCE_TO_CMD=
+
+
 #v* Configuration/SMTP_SENDER
 #  DESCRIPTION
 #  Name and email address, in the form of "First Last " to be used
diff --git a/lib/pkg_upload.cygpart b/lib/pkg_upload.cygpart
index 37bc2d63..d38ea8b6 100644
--- a/lib/pkg_upload.cygpart
+++ b/lib/pkg_upload.cygpart
@@ -168,6 +168,33 @@ EOF
echo "Upload complete."
 }
 
+__pkg_announce_run_cmd_on_msg() {
+   local cmdvar=$1
+   local msg=$2
+   local cmd
+
+   eval cmd="\${${cmdvar}}"
+
+   if [ "${cmd:+y}" != "y" ]
+   then
+   inform "\${${cmdvar}} is empty"
+   return 0
+   fi
+   echo
+   inform "Launching '\${${cmdvar}} ${msg}'"
+
+   /bin/bash -c "cd ${top} || exit 1
+P=${P@Q}; PF=${PF@Q}; PN=${PN@Q}; PR=${PR@Q}; PV=(${PV[*]@Q})
+${SMTP_SENDER+SMTP_SENDER=${SMTP_SENDER@Q}}
+${SMTP_SERVER+SMTP_SERVER=${SMTP_SERVER@Q}}
+${SMTP_SERVER_PORT+SMTP_SERVER_PORT=${SMTP_SERVER_PORT@Q}}
+${SMTP_ENCRYPTION+SMTP_ENCRYPTION=${SMTP_ENCRYPTION@Q}}
+${SMTP_USER+SMTP_USER=${SMTP_USER@Q}}
+${SMTP_PASS+SMTP_PASS=${SMTP_PASS@Q}}
+${cmd}
+"  $0 ${msg} || error "Command '\${${cmdvar}} ${msg}' (cwd=${top}) 
failed"
+}
+
 __pkg_announce() {
local msg=$(mktemp -t cygwin-announce-${PF}.XX)
local msgat=$(date +@%s)
@@ -178,10 +205,10 @@ __pkg_announce() {
 
cat > ${msg} <<_EOF
 From cygwin-announce-${PF} $(date '+%a %b %d %H:%M:%S %Y' --date=${msgat})
-From: ${SMTP_SENDER}
-To: cygwin-annou...@cygwin.com
+${SMTP_SENDER:+From: ${SMTP_SENDER}
+}To: cygwin-annou...@cygwin.com
 Date: $(date -R --date=${msgat})
-Message-Id: <$

Re: [PATCH cygport] Use correct wording if only one package is announced

2024-02-23 Thread Christian Franke via Cygwin-apps

Brian Inglis via Cygwin-apps wrote:

On 2024-02-21 07:25, Christian Franke via Cygwin-apps wrote:

Change variable name from $s to $has or $s_have as variable $s usually 
implies only the plural letter s or nothing; e.g.

...
+    local has="s have"
+
+    [ $pkg_count != 1 ] || has=" has"
...
+The following package${has} been uploaded to the Cygwin distribution:
...


Agree - new patch attached.

From 6da0f806a94621d0ecfcca3c63e5c46e8ab3cd32 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Fri, 23 Feb 2024 11:35:01 +0100
Subject: [PATCH] Use correct wording if only one package is announced

---
 lib/pkg_upload.cygpart | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/pkg_upload.cygpart b/lib/pkg_upload.cygpart
index dcae8e2c..37bc2d63 100644
--- a/lib/pkg_upload.cygpart
+++ b/lib/pkg_upload.cygpart
@@ -172,6 +172,9 @@ __pkg_announce() {
local msg=$(mktemp -t cygwin-announce-${PF}.XX)
local msgat=$(date +@%s)
local -i n=0
+   local s_have="s have"
+
+   [ $pkg_count != 1 ] || s_have=" has"
 
cat > ${msg} <<_EOF
 From cygwin-announce-${PF} $(date '+%a %b %d %H:%M:%S %Y' --date=${msgat})
@@ -181,7 +184,7 @@ Date: $(date -R --date=${msgat})
 Message-Id: <$(date "+%Y%m%d%H%M%S.$$" --date=${msgat})-1-$(echo 
${SMTP_SENDER} | sed 's|.*<\(.*\)>.*|\1|')>
 Subject: ${NAME} ${PVR}
 
-The following packages have been uploaded to the Cygwin distribution:
+The following package${s_have} been uploaded to the Cygwin distribution:
 
 _EOF
 
-- 
2.43.0



[PATCH cygport] Add customization support for announce command

2024-02-21 Thread Christian Franke via Cygwin-apps
The email generated by the cygport announce command is useful, but 
actual use cases are somewhat limited due to the hard-coded email 
submission.


The attached patch adds more flexibility. The patch is on top of the 
"Use correct wording if only one package is announced" patch.


Examples for cygport.conf settings:

ANNOUNCE_EDITOR='printf "\\nRegards,\\n$PN package maintainer\\n" >>"$1"'

ANNOUNCE_EDITOR='
n=$(wc -l <"$1") && cat >>"$1" <>> This is an update to the latest upstream release.
  >>> This is a bugfix release.
  <<< PLEASE EDIT >>>

Regards,
$PN package maintainer
EOF
vim +$((n+2)) "$1" && ! grep -E "<<<|>>>" "$1"
'

ANNOUNCE_TO_CMD='cat "$1" >/dev/clipboard'

ANNOUNCE_TO_CMD='
sed "1,/^\$/d" "$1" >$PF-announcement.txt &&
echo "Announcement placed here: $(pwd)/$PF-announcement.txt"
'

ANNOUNCE_TO_CMD='
/usr/local/sbin/custom-mailer \
  --sender="$SMTP_SENDER" \
  --smarthost="$SMTP_SERVER" \
  ...more...options... \
  cygwin-annou...@cygwin.com <"$1"
'

--
Regards,
Christian

From 1f13d54a40d639938fb67245eed4615be0a6e6c4 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Wed, 21 Feb 2024 15:14:53 +0100
Subject: [PATCH] Add customization support for announce command

Two new configuration settings allow to override the launch of
a text editor (ANNOUNCE_EDITOR) and the builtin email submission
(ANNOUNCE_TO_CMD).
---
 data/cygport.conf  | 23 +
 lib/pkg_upload.cygpart | 57 +-
 2 files changed, 74 insertions(+), 6 deletions(-)

diff --git a/data/cygport.conf b/data/cygport.conf
index 34ccd291..48dc7bfe 100644
--- a/data/cygport.conf
+++ b/data/cygport.conf
@@ -101,6 +101,29 @@
 #PAGER=
 
 
+#v* Configuration/ANNOUNCE_EDITOR
+#  DESCRIPTION
+#  Shell command string to process the email message created by cygport's
+#  announce command before sending the email.  If undefined, a text editor
+#  will be run, see EDITOR setting above.  If empty, nothing will be run.
+#  If not empty, '/bin/bash' will be launched with the command string passed
+#  with '-c' option and the path of the temporary email message file as '$1'.
+#  The working directory of the shell will be the directory of the cygport
+#  file.  The specified command string will be prepended by shell assignments
+#  of the cygport variables P, PF, PN, PR and PV and all SMTP_* settings
+#  described below.
+#ANNOUNCE_EDITOR=
+
+#v* Configuration/ANNOUNCE_TO_CMD
+#  DESCRIPTION
+#  Shell command string to process the email message created by cygport's
+#  announce command after editing.  If undefined, the email will be sent
+#  using the builtin perl-based SMTP support.  If empty, nothing will be run.
+#  If not empty, the command string will be handled similar to ANNOUNCE_EDITOR
+#  described above.
+#ANNOUNCE_TO_CMD=
+
+
 #v* Configuration/SMTP_SENDER
 #  DESCRIPTION
 #  Name and email address, in the form of "First Last " to be used
diff --git a/lib/pkg_upload.cygpart b/lib/pkg_upload.cygpart
index 8039ec5c..b81bf3d5 100644
--- a/lib/pkg_upload.cygpart
+++ b/lib/pkg_upload.cygpart
@@ -168,6 +168,28 @@ EOF
echo "Upload complete."
 }
 
+__pkg_announce_run_cmd_on_msg() {
+   local cmdvar=$1
+   local msg=$2
+   local cmd
+
+   eval cmd="\${${cmdvar}}"
+
+   (
+   cd ${top} && /bin/bash -c "\
+P=${P@Q}; PF=${PF@Q}; PN=${PN@Q}; PR=${PR@Q}; PV=(${PV[*]@Q})
+${SMTP_SENDER+SMTP_SENDER=${SMTP_SENDER@Q}}
+${SMTP_SERVER+SMTP_SERVER=${SMTP_SERVER@Q}}
+${SMTP_SERVER_PORT+SMTP_SERVER_PORT=${SMTP_SERVER_PORT@Q}}
+${SMTP_ENCRYPTION+SMTP_ENCRYPTION=${SMTP_ENCRYPTION@Q}}
+${SMTP_USER+SMTP_USER=${SMTP_USER@Q}}
+${SMTP_PASS+SMTP_PASS=${SMTP_PASS@Q}}
+${cmd}
+" \
+   $0 ${msg}
+   ) || error "Command '\${${cmdvar}} ${msg}' (cwd=${top}) failed"
+}
+
 __pkg_announce() {
local msg=$(mktemp -t cygwin-announce-${PF}.XX)
local msgat=$(date +@%s)
@@ -178,10 +200,10 @@ __pkg_announce() {
 
cat > ${msg} <<_EOF
 From cygwin-announce-${PF} $(date '+%a %b %d %H:%M:%S %Y' --date=${msgat})
-From: ${SMTP_SENDER}
-To: cygwin-annou...@cygwin.com
+${SMTP_SENDER:+From: ${SMTP_SENDER}
+}To: cygwin-annou...@cygwin.com
 Date: $(date -R --date=${msgat})
-Message-Id: <$(date "+%Y%m%d%H%M%S.$$" --date=${msgat})-1-$(echo 
${SMTP_SENDER} | sed 's|.*<\(.*\)>.*|\1|')>
+Message-Id: <$(date "+%Y%m%d%H%M%S.$$" --date=${msgat})-1-$(echo 
${SMTP_SENDER:-cygport} | sed 's|.*<\(.*\)>.*|\1|')>
 Subject: ${NAME} ${PVR}
 
 The following package${s} been uploaded to the Cygwin distribution:
@@ -199,7 +221,30 @@ _EOF
 ${DESCRIPTION}
 _EOF
 
-   ${EDITOR:-vi} $msg || error 

[PATCH cygport] Use correct wording if only one package is announced

2024-02-21 Thread Christian Franke via Cygwin-apps

Only cosmetic ...

--
Regards,
Christian

From f1381ebc872f3b099c257677e2b8d5bf2451bb23 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Wed, 21 Feb 2024 13:35:14 +0100
Subject: [PATCH] Use correct wording if only one package is announced

---
 lib/pkg_upload.cygpart | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/lib/pkg_upload.cygpart b/lib/pkg_upload.cygpart
index dcae8e2c..8039ec5c 100644
--- a/lib/pkg_upload.cygpart
+++ b/lib/pkg_upload.cygpart
@@ -172,6 +172,9 @@ __pkg_announce() {
local msg=$(mktemp -t cygwin-announce-${PF}.XX)
local msgat=$(date +@%s)
local -i n=0
+   local s="s have"
+
+   [ $pkg_count != 1 ] || s=" has"
 
cat > ${msg} <<_EOF
 From cygwin-announce-${PF} $(date '+%a %b %d %H:%M:%S %Y' --date=${msgat})
@@ -181,7 +184,7 @@ Date: $(date -R --date=${msgat})
 Message-Id: <$(date "+%Y%m%d%H%M%S.$$" --date=${msgat})-1-$(echo 
${SMTP_SENDER} | sed 's|.*<\(.*\)>.*|\1|')>
 Subject: ${NAME} ${PVR}
 
-The following packages have been uploaded to the Cygwin distribution:
+The following package${s} been uploaded to the Cygwin distribution:
 
 _EOF
 
-- 
2.43.0



[PATCH cygport] Set TZ=UTC if SOURCE_DATE_EPOCH is used

2024-02-20 Thread Christian Franke via Cygwin-apps
Further tests of 'repro-check' patch revealed that the "origsrc/*" 
timestamps in patch files contain the local timezone offset.


The attached patch is on top of the "Add more checks of 
SOURCE_DATE_EPOCH" patch. It could also be applied independently but 
then requires conflict resolution due to the then missing 'else' branch.


--
Regards,
Christian

From e9553d8541f9fb2fd4a4e49a488dfc8511fb9c8e Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Tue, 20 Feb 2024 10:32:52 +0100
Subject: [PATCH] Set TZ=UTC if SOURCE_DATE_EPOCH is used

---
 bin/cygport.in | 4 
 1 file changed, 4 insertions(+)

diff --git a/bin/cygport.in b/bin/cygport.in
index 3fe8a52e..2261a5bd 100755
--- a/bin/cygport.in
+++ b/bin/cygport.in
@@ -517,6 +517,10 @@ then
4.6.[6-9]|4.[7-9]*|[5-9]*) ;;
*) error "SOURCE_DATE_EPOCH requires peflags 4.6.6 or later"
esac
+
+   # Ensure that date and time formatting (e.g. in patch files) is 
reproducible
+   [ "${TZ}" = "UTC" ] || inform "Using TZ='UTC' instead of 
TZ='${TZ-(unset)}'"
+   export TZ=UTC
 else
inform "SOURCE_DATE_EPOCH is not set"
 fi
-- 
2.43.0



[PATCH cygport] Add repro-check command

2024-02-18 Thread Christian Franke via Cygwin-apps
This could be used to check whether a package is possibly reproducible. 
Then it could make sense to add a reasonable SOURCE_DATE_EPOCH value to 
the cygport file.


Example:

$ export SOURCE_DATE_EPOCH=$(date +%s)

$ cygport project.cygport all repro-check
...
*** Info: Build reproducibility test succeeded

$ TZ=UTC cygport project.cygport repro-check
...
*** Info: Build reproducibility test succeeded

$ unset SOURCE_DATE_EPOCH

$ cygport project.cygport repro-check
...
*** ERROR: Build reproducibility test failed

--
Regards,
Christian

From 97f518478dac722647b8a423068f2a5461c82f19 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Sun, 18 Feb 2024 16:33:07 +0100
Subject: [PATCH] Add repro-check command

This command checks for reproducibility of distribution packages.
The source package from the dist directory is unpacked to the
temp directory.  A nested rebuild of the packages is run there.
If successful, original and rebuild packages are compared and the
result is reported.
---
 README  |  1 +
 bin/cygport.in  |  8 
 lib/help.cygpart|  1 +
 lib/pkg_pkg.cygpart | 42 +-
 4 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/README b/README
index fd16df6b..fec46b13 100644
--- a/README
+++ b/README
@@ -163,6 +163,7 @@ Other COMMANDs are meant primarily for maintainers:
 diff - write a patch file capturing changes to source in the working 
directory
 stage- as upload, but don't request processing of uploaded packages
 announce - compose and send a package announcement
+repro-check - check whether a rebuild produces binary identical packages
 
 The standard arguments --help or --version may also be passed to cygport.
 
diff --git a/bin/cygport.in b/bin/cygport.in
index 5fc89eaf..6acbc85b 100755
--- a/bin/cygport.in
+++ b/bin/cygport.in
@@ -29,6 +29,10 @@ set -e;
 #
 

 
+# Preserve original environment for repro-check command
+declare -r _cygport_orig_env=$(export)
+declare -r _cygport_orig_pwd=$(pwd)
+
 # for regexes, sort, etc.
 export LC_COLLATE=C
 
@@ -784,6 +788,10 @@ do
test ${PIPESTATUS[0]} -eq 0
_status=$?;
;;
+   repro-check)
+   __pkg_repro_check
+   _status=$?
+   ;;
help)
__show_help;
exit 0;
diff --git a/lib/help.cygpart b/lib/help.cygpart
index a7f30f7a..d851762e 100644
--- a/lib/help.cygpart
+++ b/lib/help.cygpart
@@ -56,6 +56,7 @@ __show_help() {
  finishdelete the working directory
  all   run prep, compile, install and package
  all-test  run prep, compile, install and package-test
+ repro-check   check whether a rebuild produces binary 
identical packages
 
See the included README file for further documentation.
 
diff --git a/lib/pkg_pkg.cygpart b/lib/pkg_pkg.cygpart
index 756a687c..719ffcd1 100644
--- a/lib/pkg_pkg.cygpart
+++ b/lib/pkg_pkg.cygpart
@@ -992,6 +992,46 @@ _EOF
fi
 }
 
+__pkg_repro_check() {
+   local rc srcpkg t_cygport t_spkgdir
+
+   srcpkg=${distdir}/${PN}/${PF}-src.tar.${TAR_COMPRESSION_EXT}
+   t_spkgdir=${T}/${spkgdir##*/}
+
+   echo
+   __stage "Checking reproducibility of"
+
+   echo
+   __step "Unpacking ${srcpkg}"
+   [ -f "${srcpkg}" ] || error "Packages not built yet"
+   tar xf ${srcpkg} -C ${T} || error "tar xf ${srcpkg} -C ${T} failed"
+
+   echo
+   __step "Rebuilding in ${t_spkgdir}"
+   t_cygport="cygport ${cygportfile} finish all"
+   echo "${_cygport_orig_env}" > ${T}/.cygport_orig_env
+   __step "=== Start: ${t_cygport} ="
+
+   # Start nested cygport with original environment in temp directory
+   rc=0
+   env --chdir=${_cygport_orig_pwd} --ignore-environment /bin/bash -c \
+   "source ${T}/.cygport_orig_env && cd ${t_spkgdir} && 
${t_cygport}" \
+   || rc=$?
+
+   __step "=== Done: ${t_cygport} (exit $rc) ="
+   echo
+   [ $rc = 0 ] || error "Rebuild in ${t_spkgdir} failed"
+
+   __step "Comparing original and rebuilt packages"
+   if ! diff -qr ${distdir} ${t_spkgdir}/${PF}.${ARCH}/dist
+   then
+   echo
+   error "Build reproducibility test failed"
+   fi
+   echo
+   inform "Build reproducibility test succeeded"
+}
+
 # protect functions
 readonly -f __pkg_binpkg __pkg_diff __gpg_sign __pkg_srcpkg __pkg_dist \
-__squeeze_whitespace __tar
+__pkg_repro_check __squeeze_whitespace __tar
-- 
2.43.0



[ITP] f3 8.0

2024-02-17 Thread Christian Franke via Cygwin-apps

I would like to contribute f3. Also present in Debian, Fedora, Ubuntu, ...

SUMMARY="Test real flash memory capacity"

DESCRIPTION="f3 is a simple tool that tests flash cards capacity and
performance to see if they live up to claimed specifications.
It fills the device with pseudorandom data and then checks if it
returns the same on reading.
F3 stands for Fight Flash Fraud, or Fight Fake Flash."

List of files:

f3-8.0-1.tar.xz:
usr/bin/f3read.exe
usr/bin/f3write.exe
usr/share/doc/f3/LICENSE
usr/share/doc/f3/README.rst
usr/share/doc/f3/changelog.gz
usr/share/doc/f3/contribute.rst.gz
usr/share/doc/f3/examples/f3write.h2w
usr/share/doc/f3/examples/log-f3wr
usr/share/doc/f3/history.rst.gz
usr/share/doc/f3/usage.rst.gz
usr/share/man/man1/f3read.1.gz
usr/share/man/man1/f3write.1.gz

f3-debuginfo-8.0-1.tar.xz:
usr/lib/debug/usr/bin/f3read.exe.dbg
usr/lib/debug/usr/bin/f3write.exe.dbg
usr/src/debug/f3-8.0-1/f3read.c
usr/src/debug/f3-8.0-1/f3write.c
usr/src/debug/f3-8.0-1/libflow.c
usr/src/debug/f3-8.0-1/libflow.h
usr/src/debug/f3-8.0-1/utils.c
usr/src/debug/f3-8.0-1/utils.h

f3-8.0-1.src.tar.xz:
f3-8.0-1.src/f3-8.0.tar.gz
f3-8.0-1.src/f3.cygport

The source package supports reproducible builds.

--
Regards,
Christian

# cygport script for f3
NAME=f3
VERSION=8.0
RELEASE=1
SOURCE_DATE="2024-02-17 13:00:00 UTC"

SUMMARY="Test real flash memory capacity"

DESCRIPTION="f3 is a simple tool that tests flash cards capacity and
performance to see if they live up to claimed specifications.
It fills the device with pseudorandom data and then checks if it
returns the same on reading.  
F3 stands for Fight Flash Fraud, or Fight Fake Flash."

LICENSE="GPL-3.0-only" # or GPL-3.0-or-later ?
CATEGORY="Utils"
REQUIRES="" # libargp
BUILD_REQUIRES="binutils gcc-core gzip libargp-devel" # make

HOMEPAGE="https://fight-flash-fraud.readthedocs.io/;
SRC_URI="https://codeload.github.com/AltraMayor/f3/tar.gz/refs/tags/v${PV}#/${P}.tar.gz;

export SOURCE_DATE_EPOCH=$(date -d "$SOURCE_DATE" +%s)

src_compile() {
cd ${B}
lndirs
cygmake PREFIX=/usr \
LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-Wl,--stack,400 -largp" 
}

src_install() {
cd ${B}
cyginstall PREFIX=/usr

cd ${S}
dodoc changelog doc/{contribute,history,usage}.rst
gzip -9 -n ${D}/usr/share/doc/${PN}/{changelog,*.rst}

docinto examples
dodoc f3write.h2w log-f3wr
}


[PATCH cygport] Add more checks of SOURCE_DATE_EPOCH

2024-02-16 Thread Christian Franke via Cygwin-apps


From b04c8f5e9becd6e91095e2add551f72870c9e869 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Fri, 16 Feb 2024 13:16:06 +0100
Subject: [PATCH] Add more checks of SOURCE_DATE_EPOCH

Fail if it is out of range.  Warn if it lies in the future.
Inform whether it is set or set but not exported.
---
 bin/cygport.in | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/bin/cygport.in b/bin/cygport.in
index 5fc89eaf..3fe8a52e 100755
--- a/bin/cygport.in
+++ b/bin/cygport.in
@@ -493,14 +493,32 @@ unset restrict
 
 if [ "${SOURCE_DATE_EPOCH+y}" = "y" ]
 then
-   if [ -n "$(echo "${SOURCE_DATE_EPOCH}" | sed -e 's/^$/X/' -e 
's/[0-9]//g')" ]
+   if ! [[ "${SOURCE_DATE_EPOCH}" =~ ^[0-9]+$ ]]
then
error "SOURCE_DATE_EPOCH must be an integer number (seconds 
since the unix epoch)"
fi
+   if ! _d=$(date --iso-8601=seconds -d "@${SOURCE_DATE_EPOCH}" 
2>/dev/null)
+   then
+   error "SOURCE_DATE_EPOCH is out of range"
+   fi
+   if [ "${SOURCE_DATE_EPOCH}" -le "$(printf '%(%s)T')" ]
+   then
+   inform "Reproducible build: 
SOURCE_DATE_EPOCH='${SOURCE_DATE_EPOCH}' [$_d]"
+   else
+   warning "SOURCE_DATE_EPOCH='${SOURCE_DATE_EPOCH}' [$_d] lies in 
the future"
+   fi
+   unset _d
+   if [ -z "$(printenv SOURCE_DATE_EPOCH 2>/dev/null)" ]
+   then
+   inform "SOURCE_DATE_EPOCH is not exported to the environment"
+   fi
+
case $(peflags --version 2>/dev/null | sed -n '1s/^.* //p') in
4.6.[6-9]|4.[7-9]*|[5-9]*) ;;
*) error "SOURCE_DATE_EPOCH requires peflags 4.6.6 or later"
esac
+else
+   inform "SOURCE_DATE_EPOCH is not set"
 fi
 
 
-- 
2.43.0



Re: [PATCH cygport] Increase _FORTIFY_SOURCE level from 2 to 3 in CFLAGS

2024-02-04 Thread Christian Franke via Cygwin-apps

Jon Turney wrote:

On 02/02/2024 16:13, Christian Franke via Cygwin-apps wrote:
_FORTIFY_SOURCE=3 is supported by Cygwin 3.5.0 headers and Cygwin gcc 
13.2.1 test release.


Silently falls back to level 2 if level 3 is unsupported (older 
headers or gcc) or to level 0 if unsupported at all (C++, clang).


Thanks. I applied this.

I'm thinking I want to try to do another cygport release fairly 
soonish, so please feel free to remind me about any other patches by 
you (or others) which I need to look at before then.




Possibly some initial SOURCE_DATE_EPOCH support:
https://sourceware.org/pipermail/cygwin-apps/2023-August/043108.html

Related:
https://cygwin.com/git/?p=newlib-cygwin.git;a=commit;h=f5e37b9



[PATCH cygport] Increase _FORTIFY_SOURCE level from 2 to 3 in CFLAGS

2024-02-02 Thread Christian Franke via Cygwin-apps
_FORTIFY_SOURCE=3 is supported by Cygwin 3.5.0 headers and Cygwin gcc 
13.2.1 test release.


Silently falls back to level 2 if level 3 is unsupported (older headers 
or gcc) or to level 0 if unsupported at all (C++, clang).


--
Regards,
Christian

From 1a32375682d0e5ff6b80a47de70d3d9cfe0f0780 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Fri, 2 Feb 2024 17:00:18 +0100
Subject: [PATCH] Increase _FORTIFY_SOURCE level from 2 to 3 in CFLAGS

This enables buffer overflow checks if the buffer size is non-const
but known during runtime and GCC 12.0 or later is used.
---
 lib/compilers.cygpart | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/compilers.cygpart b/lib/compilers.cygpart
index 35e6fe28..52df5304 100644
--- a/lib/compilers.cygpart
+++ b/lib/compilers.cygpart
@@ -34,9 +34,9 @@ declare -x CC="gcc";
 #  Flags passed to CC when compiling C code.  Individual packages may append
 #  or override this value if they will not build correctly without it.
 #  DEFAULT VALUE
-#  -ggdb -O2 -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 
-fstack-protector-strong --param=ssp-buffer-size=4
+#  -ggdb -O2 -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=3 
-fstack-protector-strong --param=ssp-buffer-size=4
 #
-declare -x CFLAGS="-ggdb -O2 -pipe -Wall -Werror=format-security 
-Wp,-D_FORTIFY_SOURCE=2 -fstack-protector-strong --param=ssp-buffer-size=4";
+declare -x CFLAGS="-ggdb -O2 -pipe -Wall -Werror=format-security 
-Wp,-D_FORTIFY_SOURCE=3 -fstack-protector-strong --param=ssp-buffer-size=4";
 
 #v* Compiling/CPPFLAGS
 #  DESCRIPTION
-- 
2.43.0



Re: [PATCH cygport] Add initial support for SOURCE_DATE_EPOCH

2023-10-30 Thread Christian Franke via Cygwin-apps

Jon Turney wrote:

On 28/08/2023 16:12, Christian Franke via Cygwin-apps wrote:

Christian Franke wrote:

A small step towards reproducible packaging...



Thanks very much for this. Sorry for taking so long to look at it.



No problem.



A few questions and suggestions interspersed

[...]


--
Regards,
Christian


0001-Add-initial-support-for-SOURCE_DATE_EPOCH.patch

 From 73dde4d2dabb74b7b9ee40655204f84e1d4086d6 Mon Sep 17 00:00:00 2001
From: Christian Franke
Date: Mon, 28 Aug 2023 16:24:36 +0200
Subject: [PATCH] Add initial support for SOURCE_DATE_EPOCH

If specified, set the header timestamps of executables and
patch files to SOURCE_DATE_EPOCH.
Suppress the header timestamp of .gz files.
Instruct tar to avoid more recent modification times and
to sort all entries by name.
---
  bin/cygport.in   | 17 +++--
  lib/pkg_pkg.cygpart  | 20 ++--
  lib/src_postinst.cygpart | 22 +++---
  3 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/bin/cygport.in b/bin/cygport.in
index 3f89ac67..e2fe1785 100755
--- a/bin/cygport.in
+++ b/bin/cygport.in
@@ -231,8 +231,9 @@ source ${_privlibdir}/check_funcs.cygpart
  ###
    # check now for all mandatory programs
-for _myprog in bzip2 cat chmod cp diff diffstat dos2unix file find 
gawk grep gzip \
-   install ln mkdir mv patch rm rsync sed sort tar xargs 
which xz
+for _myprog in bzip2 cat chmod cp date diff diffstat dos2unix file 
find gawk grep \
+   gzip install ln mkdir mv patch rm rsync sed sort tar 
touch which \

+   xargs xz
  do
  if ! check_prog ${_myprog}
  then
@@ -490,6 +491,18 @@ do
  done
  unset restrict
  +if [ "${SOURCE_DATE_EPOCH+y}" = "y" ]
+then
+    if [ -n "$(echo "${SOURCE_DATE_EPOCH}" | sed -e 's/^$/X/' -e 
's/[0-9]//g')" ]

+    then
+    error "Malformed SOURCE_DATE_EPOCH: '${SOURCE_DATE_EPOCH}'"


This error message should perhaps say what a well-formed 
SOURCE_DATE_EPOCH looks like: an integer number of seconds since the 
unix epoch?




error "SOURCE_DATE_EPOCH must be an integer number (seconds since the 
unix epoch)" ?




+    fi
+    case $(peflags --version 2>/dev/null | sed -n '1s/^.* //p') in
+    4.6.[6-9]|4.[7-9]*|[5-9]*) ;;
+    *) error "SOURCE_DATE_EPOCH requires peflags 4.6.6 or later"
+    esac
+fi
+

  #
diff --git a/lib/pkg_pkg.cygpart b/lib/pkg_pkg.cygpart
index 2a2bb663..4e6a7cd2 100644
--- a/lib/pkg_pkg.cygpart
+++ b/lib/pkg_pkg.cygpart
@@ -42,7 +42,7 @@ TAR_COMPRESSION_EXT="${TAR_COMPRESSION_EXT:-xz}"
  #
    __tar() {
-    local TAR_COMPRESSION_OPT;
+    local TAR_COMPRESSION_OPT TAR_SOURCE_DATE_OPTS;
    # We could use --auto-compress, but this also constrains the 
extension

  # to the currently valid set. We could probe if tar supports the
@@ -65,7 +65,14 @@ __tar() {
  error "tar option for 
TAR_COMPRESSION_EXT='${TAR_COMPRESSION_EXT}' unknown"

  ;;
  esac
-    tar ${TAR_COMPRESSION_OPT} --owner=Guest:501 --group=None:513 
-cvf "$@"

+
+    if [ -n "${SOURCE_DATE_EPOCH}" ]
+    then
+    # Ensure reproducible sort order and last modification times 
<= SOURCE_DATE_EPOCH
+    TAR_SOURCE_DATE_OPTS="--sort=name 
--mtime=@${SOURCE_DATE_EPOCH} --clamp-mtime"


I'm slightly concerned that maybe this is masking problems elsewhere, 
at least when making the source archive: In 2eb7c0eb I started making 
an effort so that if the "source inputs" have fixed, upstream 
timestamps, we'll preserve those in the output the source package.


(Obviously that's not always going to be the case, e.g. where cygport 
patches are from a local git checkout, so maybe that's not a real 
problem...)


If the following condition holds, the timestamps of "source inputs" are 
not affected:

newest_source_timestamp < SOURCE_DATE_EPOCH < build_time





+    fi
+
+    tar ${TAR_COMPRESSION_OPT} ${TAR_SOURCE_DATE_OPTS} 
--owner=Guest:501 --group=None:513 -cvf "$@"

  }
    __pkg_binpkg() {
@@ -319,6 +326,7 @@ __pkg_diff() {
  local difflevel;
  local exclude;
  local optional_patchfiles;
+    local source_date;
    default_excludes="CYGWIN-PATCHES aclocal.m4~ aclocal.m4t 
autom4te.cache

  config.cache config.guess config.log config.status config.sub
@@ -498,6 +506,14 @@ __pkg_diff() {
    sed -b -e '/^diff -u/d' -i ${optional_patchfiles} 
${patchdir}/${src_patchfile};

  +    if [ -n "${SOURCE_DATE_EPOCH}" ]
+    then
+    # Ensure that the timestamp comment of the new file is 
reproducible


"timestamp comments in the generated patch files" or suchlike?


OK.





+    source_date=$(date -d @"${SOURCE_DATE_EPOCH}" -u +'%Y-%m-%d 
%H:%M:%S.0 +')

+    se

Re: cygport may not create debug info if top directory contains a symlink

2023-10-30 Thread Christian Franke via Cygwin-apps

Jon Turney wrote:

On 20/09/2023 11:58, Christian Franke via Cygwin-apps wrote:

Brian Inglis wrote:

On 2023-09-18 04:41, Christian Franke via Cygwin-apps wrote:

Brian Inglis wrote:

On 2023-09-17 08:01, Jon Turney via Cygwin-apps wrote:

On 16/09/2023 15:17, Christian Franke via Cygwin wrote:

Found during tests of busybox package:
If the path of the top build directory contains a symlink and 
the project's build scripts normalize pathnames, no debug info 
is created by cygport.


This is because options like
  -fdebug-prefix-map=${B}=/usr/src/debug/${PF}
have no effect because ${B} contains a symlink but the compiler 
is run with the real source path.


I think that there was some historical bug with gcc where a 
relative path for the old path in this mapping wasn't correctly 
handled, which is why were using an absolute path here at all.


So changing it to something like [1] (if that works), might be 
better.


[1] 
https://github.com/jon-turney/cygport/commit/4175d456a9184c5cdebd8bfb4b5ba30583cedd66


Should bin/cygport.in:534: not have $B between the == as in line 531:

declare ${flags}+=" -fdebug-prefix-map=${B}=/usr/src/debug/${PF}"
...
declare ${flags}+=" -fdebug-prefix-map==/usr/src/debug/${PF}"

or be hoist above the condition if identical, unless that is some 
undocumented default for cwd?


I guess the == without ${B} is intentional because it makes the debug 
source path relative to ${B} as lines 535-536 also do.


Yeah, I think that "==" is shorthand for "=.=", i.e. relative to cwd.



Further tests show that "==" behaves strange and is not useful at all 
(no problem as it doesn't actually appear in cygport.in).


The "=.=" only does a simple replacement of first "." in source name.

Testcases with file.c in /var/tmp/test:

$ gcc -g file.c && objdump -dl a.exe | grep -F file.c
/var/tmp/test/file.c:1

$ gcc -g ./file.c && objdump -dl a.exe | grep -F file.c
/var/tmp/test/./file.c:1

$ gcc -g ../test/file.c && objdump -dl a.exe | grep -F file.c
/var/tmp/test/../test/file.c:1

$ gcc -g -fdebug-prefix-map==/foo/bar file.c && ...
/foo/bar/foo/barfile.c:1

$ gcc -g -fdebug-prefix-map=.=/foo/bar file.c && ...
/var/tmp/test/file.c:1

$ gcc -g -fdebug-prefix-map=.=/foo/bar ./file.c && ...
/foo/bar/file.c:1

$ gcc -g -fdebug-prefix-map=/var/tmp/test=/foo/bar file.c && ...
/foo/bar/file.c:1

Source directories with symlinks are preserved in line number info like 
with 'pwd -L'.



Does using relative paths in the prefix-map resolve the original issue 
seen with busybox?


No, relative paths do not work. Adding this to top of src_compile() works:

   CFLAGS+=" -fdebug-prefix-map=$(cd ${S} && pwd -P)=/usr/src/debug/${PF}"

Same for ${B} is not required for this project. This also works (B and S 
are not set yet):


 DEBUG_PREFIX_MAPS=( "$(pwd -P)/${PF}.${ARCH}/src/${PN}-${PV}" )


(It's unclear to me how gcc compares paths to apply this mapping. If 
it's a literal string prefix, rather than on some (semi-)canonicalized 
path, then we're maybe going to lose here sometimes, depending on the 
vagaries of the build-system, unless we list all of relative, 
absolute, and canonical absolute paths?)


(But then maybe we can push dealing with or indicating which of those 
is correct off onto the individual cygport?)




Adding this if "$(cd ${S} && pwd -P)" != "${S}" should IMO be safe:
  -fdebug-prefix-map=$(cd ${B} && pwd -P)=/usr/src/debug/${PF}
  -fdebug-prefix-map=$(cd ${S} && pwd -P)=/usr/src/debug/${PF}
(or use realpath)



[PATCH rebase] Fix handling of unset PE checksums

2023-10-09 Thread Christian Franke via Cygwin-apps
Tests with non-Cygwin executables show that other toolchains (LLVM LLD, 
MS link without /RELEASE option) leave the PE checksum field as zero. 
Peflags+rebase 4.6.6 still work correctly then, but rebase prints a 
misleading warning 'Checksum update failed' in this case. With the 
attached patch, a zero checksum is left as is and no message is printed.


This currently does not affect typical Cygwin use cases, so there is IMO 
no urgent need for a new package.


BTW, there was possibly no announcement for the rebase 4.6.6 package.

--
Regards,
Christian

From 855be8d72a1f96d0a3cfcb0a97fbe12a9a912748 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Mon, 9 Oct 2023 09:56:05 +0200
Subject: [PATCH] Fix handling of unset PE checksums

Leave unset (zero) checksums as is unless checksum update is
explicitly requested.  Remove misleading peflags warning
'Checksum update failed'.

Signed-off-by: Christian Franke 
---
 imagehelper/objectfile.cc |  9 ++--
 peflags.c | 45 ++-
 rebase.c  |  7 +++---
 3 files changed, 36 insertions(+), 25 deletions(-)

diff --git a/imagehelper/objectfile.cc b/imagehelper/objectfile.cc
index 651fcce..ce4b444 100755
--- a/imagehelper/objectfile.cc
+++ b/imagehelper/objectfile.cc
@@ -497,13 +497,18 @@ BOOL LinkedObjectFile::updateCheckSum()
 p_checksum =  ()->OptionalHeader.CheckSum;
   else
 p_checksum =  ()->OptionalHeader.CheckSum;
+  uint32_t checksum = *p_checksum;
+
+  // Leave unset checksum as is
+  if (!checksum)
+return TRUE;
 
   // Add changes from NT header to checksum updated by relocs
   uint16_t checksum16;
   if (relocs)
 checksum16 = relocs->getCheckSum16();
   else
-checksum16 = pe32_checksum_update_begin(*p_checksum, FileSize);
+checksum16 = pe32_checksum_update_begin(checksum, FileSize);
 
   if (is64bit ())
 checksum16 = pe32_checksum_update_add(checksum16, _ntheader64,
@@ -514,7 +519,7 @@ BOOL LinkedObjectFile::updateCheckSum()
 getNTHeader32 (),
 sizeof(old_ntheader32));
 
-  uint32_t checksum = pe32_checksum_update_end(checksum16, FileSize);
+  checksum = pe32_checksum_update_end(checksum16, FileSize);
   if (!checksum)
 return FALSE;
 
diff --git a/peflags.c b/peflags.c
index 917088b..14ea78d 100644
--- a/peflags.c
+++ b/peflags.c
@@ -508,7 +508,7 @@ do_mark (const char *pathname)
 
 }
 
-  /* Update the checksum. */
+  /* Update the checksum if set. */
   changed = FALSE;
   {
 const void *p_oldheader, *p_newheader;
@@ -529,20 +529,24 @@ do_mark (const char *pathname)
p_checksum = >ntheader32->OptionalHeader.CheckSum;
   }
 
-hdr_checksum = pe32_checksum_update_end(
-  pe32_checksum_update_add(
-   pe32_checksum_update_begin(*p_checksum, pep->filesize),
-   p_oldheader, p_newheader, headersize
-  ),
-  pep->filesize
-);
-
-if (!hdr_checksum)
-  fprintf(stderr, "%s: Checksum update failed\n", pathname);
-else if (*p_checksum != hdr_checksum)
+hdr_checksum = *p_checksum;
+if (hdr_checksum)
   {
-   changed = TRUE;
-   *p_checksum = hdr_checksum;
+   ULONG new_hdr_checksum = pe32_checksum_update_end (
+ pe32_checksum_update_add (
+   pe32_checksum_update_begin (hdr_checksum, pep->filesize),
+   p_oldheader, p_newheader, headersize
+ ),
+ pep->filesize
+   );
+
+   /* Update the checksum or set it to 0 if the old value is invalid. */
+   if (new_hdr_checksum != hdr_checksum
+   && (mark_any || handle_any_sizeof == DO_WRITE))
+ {
+   changed = TRUE;
+   *p_checksum = hdr_checksum = new_hdr_checksum;
+ }
   }
   }
 
@@ -650,7 +654,7 @@ static void
 do_checksum (const char *pathname, int indent, int changed, ULONG hdr_checksum)
 {
   const char name[] = "PE file checksum";
-  if (checksum_option > 1)
+  if (checksum_option > 1 && (checksum_option > 2 || hdr_checksum))
 {
   int fd;
   unsigned new_checksum, old_checksum;
@@ -684,10 +688,11 @@ do_checksum (const char *pathname, int indent, int 
changed, ULONG hdr_checksum)
  printf ("%*s%-24s: 0x%08x (*needs update to 0x%08x*)\n", indent, "", 
name,
  old_checksum, new_checksum);
 }
-  else /* (checksum_option == 1) */
+  else /* (checksum_option == 1 || (checksum_option == 2 && !hdr_checksum)) */
 {
-  printf ("%*s%-24s: 0x%08x (%schanged, not verified)\n", indent, "", name,
- hdr_checksum, (changed ? "" : "un"));
+  printf ("%*s%-24s: 0x%08x (%schanged%s)\n", indent, "", name,
+ hdr_checksum, (changed ? "" : "un"),
+ (hdr_checksum ? ", not verified" : "

Re: cygport may not create debug info if top directory contains a symlink

2023-09-20 Thread Christian Franke via Cygwin-apps

Brian Inglis wrote:

On 2023-09-18 04:41, Christian Franke via Cygwin-apps wrote:

Brian Inglis wrote:

On 2023-09-17 08:01, Jon Turney via Cygwin-apps wrote:

On 16/09/2023 15:17, Christian Franke via Cygwin wrote:

Found during tests of busybox package:
If the path of the top build directory contains a symlink and the 
project's build scripts normalize pathnames, no debug info is 
created by cygport.


This is because options like
  -fdebug-prefix-map=${B}=/usr/src/debug/${PF}
have no effect because ${B} contains a symlink but the compiler is 
run with the real source path.


I think that there was some historical bug with gcc where a 
relative path for the old path in this mapping wasn't correctly 
handled, which is why were using an absolute path here at all.


So changing it to something like [1] (if that works), might be better.

[1] 
https://github.com/jon-turney/cygport/commit/4175d456a9184c5cdebd8bfb4b5ba30583cedd66


Should bin/cygport.in:534: not have $B between the == as in line 531:

declare ${flags}+=" -fdebug-prefix-map=${B}=/usr/src/debug/${PF}"
...
declare ${flags}+=" -fdebug-prefix-map==/usr/src/debug/${PF}"

or be hoist above the condition if identical, unless that is some 
undocumented default for cwd?


I guess the == without ${B} is intentional because it makes the debug 
source path relative to ${B} as lines 535-536 also do.




...
An STC script which creates test dirs to demonstrate the issue and 
show the alternative outputs would be nice so anyone can see.



$ ln -s /usr/src /tmp/source

$ cd /tmp/source

$ pwd
/tmp/source

$ /bin/pwd
/usr/src

$ pwd -P
/usr/src

$ /bin/pwd -L
/tmp/source


Thanks, looks good - care to submit a patch, including above 
suggestions, to cover all bases?




Users may have a good reason to use a symlinked directory, e.g. fake the 
original build path during a rebuild. So I'm still not sure how to 
handle this.


- Simply warn the user:

  declare -r top=$(cd ${_topdir}; pwd);
 +if [ "${top}" != "$(cd ${_topdir}; pwd -P)" ]
 +then
 +   warning "symlinks in ${top} do not work with some build systems."
 +fi
  unset _topdir;

- or enforce the real path:

 -declare -r top=$(cd ${_topdir}; pwd);
 +declare -r top=$(cd ${_topdir}; pwd -P);
 +if [ "${top}" != "$(cd ${_topdir}; pwd -L)" ]
 +then
 +   inform "using real path ${top} as top level directory."
 +fi
  unset _topdir;

Projects using GNU autotools and cyg{conf,make,install} in cygport are 
usually not affected by symlinks in ${top}.


--
Regards,
Christian



Re: cygport may not create debug info if top directory contains a symlink

2023-09-18 Thread Christian Franke via Cygwin-apps

Brian Inglis wrote:

On 2023-09-17 08:01, Jon Turney via Cygwin-apps wrote:

On 16/09/2023 15:17, Christian Franke via Cygwin wrote:

Found during tests of busybox package:
If the path of the top build directory contains a symlink and the 
project's build scripts normalize pathnames, no debug info is 
created by cygport.


This is because options like
  -fdebug-prefix-map=${B}=/usr/src/debug/${PF}
have no effect because ${B} contains a symlink but the compiler is 
run with the real source path.


I think that there was some historical bug with gcc where a relative 
path for the old path in this mapping wasn't correctly handled, which 
is why were using an absolute path here at all.


So changing it to something like [1] (if that works), might be better.

[1] 
https://github.com/jon-turney/cygport/commit/4175d456a9184c5cdebd8bfb4b5ba30583cedd66


Sidenote: we should probably also be using file-prefix-map, now we're 
on a gcc which supports it.


Definitely. in particular useful in conjunction with reproducible builds 
and this cygport patch:

https://sourceware.org/pipermail/cygwin-apps/2023-August/043108.html
The related newlib-cygwin patch has been pushed already:
https://cygwin.com/git/?p=newlib-cygwin.git;a=commit;h=f5e37b93





The postinstall code then does not find any line number info with 
source path /usr/src/debug/${PF}/...


Could be fixed easily in line 414 of /bin/cygport:

-declare -r top=$(cd ${_topdir}; pwd);
+declare -r top=$(cd ${_topdir}; /bin/pwd);


Can you explain why this makes a difference?


In cygport, pwd is a bash builtin defaulting to -L; /bin/pwd defaults 
to -P.

Both commands support both options and we might expect the same output.
It would be better to use builtin `pwd -P` if that produces the 
correct result.


It does.




An STC script which creates test dirs to demonstrate the issue and 
show the alternative outputs would be nice so anyone can see.


$ ln -s /usr/src /tmp/source

$ cd /tmp/source

$ pwd
/tmp/source

$ /bin/pwd
/usr/src

$ pwd -P
/usr/src

$ /bin/pwd -L
/tmp/source

--
Regards,
Christian



Re: [PATCH cygport] Add initial support for SOURCE_DATE_EPOCH

2023-08-29 Thread Christian Franke via Cygwin-apps

ASSI via Cygwin-apps wrote:

Christian Franke via Cygwin-apps writes:

If the build-path changes, more files differ (cygcheck.exe, ldd.exe,
cygserver.exe) because __FILE__ is used and expands to an absolute
path name.

This could be fixed by adding -fmacro-prefix and/or -ffile-prefix arguments.


Yes, -fmacro-prefix-map should do the trick.

Meantime I found a workaround for the additional timestamp in the PE 
Export Tables header:
The ld option --no-insert-timestamp also sets this timestamp to 0. This 
is apparently preserved by objcopy, regardless of --preserve-dates option.


--
Regards,
Christian



Re: [PATCH cygport] Add initial support for SOURCE_DATE_EPOCH

2023-08-28 Thread Christian Franke via Cygwin-apps

Christian Franke wrote:

A small step towards reproducible packaging...

Currently only tested with upcoming smartmontools package - contains 
only exe, man, doc files (no dll, lib, ...). Multiple cygport runs 
produce binary identical distribution tarballs if SOURCE_DATE_EPOCH 
(from the past) is specified in the cygport file.




A slightly enhanced patch is attached. For .gz files, 'gzip -n' is now 
used as suggested.



Result from a test with the cygwin-3.4.8-1 source package:

These two lines were added to cygwin.cygport:

 VERSION="3.4.8"
 RELEASE="1"
+export SOURCE_DATE_EPOCH=$(date -d '2023-08-18 UTC' +%s)
+export TZ=UTC

(TZ=UTC is a workaround for a minor bug in SOURCE_DATE_EPOCH handling of 
gropdf)


These distribution files are always identical:
- cygwin-3.4.8-1-src.tar.xz
- cygwin-doc-3.4.8-1.tar.xz

These individual files differ if the build-path of multiple test-builds 
is always the same:


- usr/bin/cygwin1.dll:
-- Contains a build timestamp not based on '__DATE__ __TIME__'. Could be 
easily addressed in scripts/mkvers.sh.
-- The PE Export Tables header contains a timestamp independent from the 
PE header. There is possibly no easy way to fix this without an extra 
tool (or further enhancing peflags).


- usr/lib/lib*.a:
-- Object file time timestamps differ. Could be addressed by adding 'ar' 
option 'D' (deterministic) in Makefiles and scripts/speclib.


- usr/lib/debug/usr/bin/cygwin1.dll.dbg: As expected, because 
cygwin1.dll differ.


If the build-path changes, more files differ (cygcheck.exe, ldd.exe, 
cygserver.exe) because __FILE__ is used and expands to an absolute path 
name.


--
Regards,
Christian

From 73dde4d2dabb74b7b9ee40655204f84e1d4086d6 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Mon, 28 Aug 2023 16:24:36 +0200
Subject: [PATCH] Add initial support for SOURCE_DATE_EPOCH

If specified, set the header timestamps of executables and
patch files to SOURCE_DATE_EPOCH.
Suppress the header timestamp of .gz files.
Instruct tar to avoid more recent modification times and
to sort all entries by name.
---
 bin/cygport.in   | 17 +++--
 lib/pkg_pkg.cygpart  | 20 ++--
 lib/src_postinst.cygpart | 22 +++---
 3 files changed, 52 insertions(+), 7 deletions(-)

diff --git a/bin/cygport.in b/bin/cygport.in
index 3f89ac67..e2fe1785 100755
--- a/bin/cygport.in
+++ b/bin/cygport.in
@@ -231,8 +231,9 @@ source ${_privlibdir}/check_funcs.cygpart
 ###
 
 # check now for all mandatory programs
-for _myprog in bzip2 cat chmod cp diff diffstat dos2unix file find gawk grep 
gzip \
-   install ln mkdir mv patch rm rsync sed sort tar xargs which xz
+for _myprog in bzip2 cat chmod cp date diff diffstat dos2unix file find gawk 
grep \
+   gzip install ln mkdir mv patch rm rsync sed sort tar touch 
which \
+   xargs xz
 do
if ! check_prog ${_myprog}
then
@@ -490,6 +491,18 @@ do
 done
 unset restrict
 
+if [ "${SOURCE_DATE_EPOCH+y}" = "y" ]
+then
+   if [ -n "$(echo "${SOURCE_DATE_EPOCH}" | sed -e 's/^$/X/' -e 
's/[0-9]//g')" ]
+   then
+   error "Malformed SOURCE_DATE_EPOCH: '${SOURCE_DATE_EPOCH}'"
+   fi
+   case $(peflags --version 2>/dev/null | sed -n '1s/^.* //p') in
+   4.6.[6-9]|4.[7-9]*|[5-9]*) ;;
+   *) error "SOURCE_DATE_EPOCH requires peflags 4.6.6 or later"
+   esac
+fi
+
 
 

 #
diff --git a/lib/pkg_pkg.cygpart b/lib/pkg_pkg.cygpart
index 2a2bb663..4e6a7cd2 100644
--- a/lib/pkg_pkg.cygpart
+++ b/lib/pkg_pkg.cygpart
@@ -42,7 +42,7 @@ TAR_COMPRESSION_EXT="${TAR_COMPRESSION_EXT:-xz}"
 #
 
 __tar() {
-   local TAR_COMPRESSION_OPT;
+   local TAR_COMPRESSION_OPT TAR_SOURCE_DATE_OPTS;
 
# We could use --auto-compress, but this also constrains the extension
# to the currently valid set. We could probe if tar supports the
@@ -65,7 +65,14 @@ __tar() {
error "tar option for 
TAR_COMPRESSION_EXT='${TAR_COMPRESSION_EXT}' unknown"
;;
esac
-   tar ${TAR_COMPRESSION_OPT} --owner=Guest:501 --group=None:513 -cvf "$@"
+
+   if [ -n "${SOURCE_DATE_EPOCH}" ]
+   then
+   # Ensure reproducible sort order and last modification times <= 
SOURCE_DATE_EPOCH
+   TAR_SOURCE_DATE_OPTS="--sort=name --mtime=@${SOURCE_DATE_EPOCH} 
--clamp-mtime"
+   fi
+
+   tar ${TAR_COMPRESSION_OPT} ${TAR_SOURCE_DATE_OPTS} --owner=Guest:501 
--group=None:513 -cvf "$@"
 }
 
 __pkg_binpkg() {
@@ -319,6 +326,7 @@ __pkg_diff() {
local difflevel;
local exclude;
local optional_patchfiles;
+   local source_date;
 
default_excludes="CYGWIN-PATCHES aclocal.m4~ aclocal.m4t autom4te.cache

Re: [PATCH cygport] Add initial support for SOURCE_DATE_EPOCH

2023-08-24 Thread Christian Franke via Cygwin-apps

ASSI via Cygwin-apps wrote:

Christian Franke via Cygwin-apps writes:

If binutils, gzip and tar also would support this, the patch would be
empty :-)

GZip has -n though ...


For gzip I decided to keep the timestamp and use (the GNU version of) 
touch instead.




and GNU tar --mtime and --clamp-mtime, so why not use
that?


Already done:

+    if [ -n "${SOURCE_DATE_EPOCH}" ]
+    then
+        # Ensure reproducible sort order and last modification times <= 
SOURCE_DATE_EPOCH
+        TAR_SOURCE_DATE_OPTS="--sort=name --mtime=@${SOURCE_DATE_EPOCH} 
--clamp-mtime"

+    fi


:-)

--
Regards,
Christian




Re: [PATCH cygport] Add initial support for SOURCE_DATE_EPOCH

2023-08-24 Thread Christian Franke via Cygwin-apps

Brian Inglis via Cygwin-apps wrote:

On 2023-08-23 11:39, Christian Franke via Cygwin-apps wrote:

A small step towards reproducible packaging...

Currently only tested with upcoming smartmontools package - contains 
only exe, man, doc files (no dll, lib, ...). Multiple cygport runs 
produce binary identical distribution tarballs if SOURCE_DATE_EPOCH 
(from the past) is specified in the cygport file.


What format is this variable?


Unix epoch, see: https://reproducible-builds.org/docs/source-date-epoch/

Some tools like gcc and gropdf already support this:

$ echo '__DATE__ __TIME__' | SOURCE_DATE_EPOCH=1672531200 gcc -E -xc -
# 0 ""
# 0 ""
# 0 ""
# 1 ""
"Jan  1 2023" "00:00:00"

$ TZ=UTC SOURCE_DATE_EPOCH=1672531200 man -Tpdf ls | TZ=UTC pdfinfo -
Creator:    groff version 1.23.0
Producer:   gropdf version 1.23.0
CreationDate:   Sun Jan  1 00:00:00 2023 UTC
ModDate:    Sun Jan  1 00:00:00 2023 UTC
...

If binutils, gzip and tar also would support this, the patch would be 
empty :-)




Would be best to use some ISO format e.g.

%Y-%m-%dT%H:%M:%SZ    or
%Y-%m-%dT%H:%M:%S    [local]

that is human readable and can be used by all POSIX command options
[e.g. see touch(1p) -d] that accept date-time stamps.



I use this in smartmontools.cygport:

SOURCE_DATE=2023-08-23
SOURCE_DATE_EPOCH=$(date -d "$SOURCE_DATE UTC" +%s)

This relies on GNU date, BSD date is very different, a POSIX-only date 
would be useless in this context.



Could do with docs and NEWS entries for new variables, otherwise 
packagers do not know it exists, and how to use it e.g.


#f* Information/BUILD_REQUIRES
#  SYNOPSIS
...


Of course this should be documented, but I left this for a later patch.

--
Regards,
Christian



[PATCH cygport] Add initial support for SOURCE_DATE_EPOCH

2023-08-23 Thread Christian Franke via Cygwin-apps

A small step towards reproducible packaging...

Currently only tested with upcoming smartmontools package - contains 
only exe, man, doc files (no dll, lib, ...). Multiple cygport runs 
produce binary identical distribution tarballs if SOURCE_DATE_EPOCH 
(from the past) is specified in the cygport file.


--
Regards,
Christian

From 146b1df83a20ccd71e57d6123c7ee24b8390ca3a Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Wed, 23 Aug 2023 19:27:02 +0200
Subject: [PATCH] Add initial support for SOURCE_DATE_EPOCH

If specified, ensure that the header timestamps of executables
and of compressed man pages are set to this value.
Instruct tar to avoid more recent modification times and
sort all entries by name.
---
 bin/cygport.in   | 14 +-
 lib/pkg_pkg.cygpart  | 11 +--
 lib/src_postinst.cygpart | 21 +
 3 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/bin/cygport.in b/bin/cygport.in
index 3f89ac67..f7c476b0 100755
--- a/bin/cygport.in
+++ b/bin/cygport.in
@@ -232,7 +232,7 @@ source ${_privlibdir}/check_funcs.cygpart
 
 # check now for all mandatory programs
 for _myprog in bzip2 cat chmod cp diff diffstat dos2unix file find gawk grep 
gzip \
-   install ln mkdir mv patch rm rsync sed sort tar xargs which xz
+   install ln mkdir mv patch rm rsync sed sort tar touch xargs 
which xz
 do
if ! check_prog ${_myprog}
then
@@ -490,6 +490,18 @@ do
 done
 unset restrict
 
+if [ "${SOURCE_DATE_EPOCH+y}" = "y" ]
+then
+   if [ -n "$(echo "${SOURCE_DATE_EPOCH}" | sed -e 's/^$/X/' -e 
's/[0-9]//g')" ]
+   then
+   error "Malformed SOURCE_DATE_EPOCH: '${SOURCE_DATE_EPOCH}'"
+   fi
+   case $(peflags --version 2>/dev/null | sed -n '1s/^.* //p') in
+   4.6.[6-9]|4.[7-9]*|[5-9]*) ;;
+   *) error "SOURCE_DATE_EPOCH requires peflags 4.6.6 or later"
+   esac
+fi
+
 
 

 #
diff --git a/lib/pkg_pkg.cygpart b/lib/pkg_pkg.cygpart
index 2a2bb663..3869bdb7 100644
--- a/lib/pkg_pkg.cygpart
+++ b/lib/pkg_pkg.cygpart
@@ -42,7 +42,7 @@ TAR_COMPRESSION_EXT="${TAR_COMPRESSION_EXT:-xz}"
 #
 
 __tar() {
-   local TAR_COMPRESSION_OPT;
+   local TAR_COMPRESSION_OPT TAR_SOURCE_DATE_OPTS;
 
# We could use --auto-compress, but this also constrains the extension
# to the currently valid set. We could probe if tar supports the
@@ -65,7 +65,14 @@ __tar() {
error "tar option for 
TAR_COMPRESSION_EXT='${TAR_COMPRESSION_EXT}' unknown"
;;
esac
-   tar ${TAR_COMPRESSION_OPT} --owner=Guest:501 --group=None:513 -cvf "$@"
+
+   if [ -n "${SOURCE_DATE_EPOCH}" ]
+   then
+   # Ensure reproducible sort order and last modification times <= 
SOURCE_DATE_EPOCH
+   TAR_SOURCE_DATE_OPTS="--sort=name --mtime=@${SOURCE_DATE_EPOCH} 
--clamp-mtime"
+   fi
+
+   tar ${TAR_COMPRESSION_OPT} ${TAR_SOURCE_DATE_OPTS} --owner=Guest:501 
--group=None:513 -cvf "$@"
 }
 
 __pkg_binpkg() {
diff --git a/lib/src_postinst.cygpart b/lib/src_postinst.cygpart
index dd947311..f0ab0f8b 100644
--- a/lib/src_postinst.cygpart
+++ b/lib/src_postinst.cygpart
@@ -775,6 +775,11 @@ __prepman() {
while read -d $'\0' manpage
do
echo "${manpage##*/}";
+   if [ -n "${SOURCE_DATE_EPOCH}" ]
+   then
+   # Ensure that the timestamp in gzip header is 
reproducible
+   touch -d @${SOURCE_DATE_EPOCH} "${manpage}"
+   fi
gzip -q "${manpage}";
done
fi
@@ -989,6 +994,12 @@ __prepstrip_one() {
 
objdump=${objcopy/copy/dump}
 
+   if [ -n "${SOURCE_DATE_EPOCH}" ]
+   then
+   # Let objcopy preserve the timestamps
+   objcopy+=" --enable-deterministic-archives --preserve-dates"
+   fi
+
# Static libraries should not be fully stripped, but we can
# still provide split debuginfo if desired
case "${exe}" in
@@ -1074,6 +1085,16 @@ __prepstrip_one() {
# keep sticky bit if present
chmod u+w,a+x "${exe}";
 
+   if [ -n "${SOURCE_DATE_EPOCH}" ]
+   then
+   case "${exe}" in
+   *.exe|*.dll|*.so|*.so.*|*.oct|*.mex|*.cmxs)
+   # Ensure PE header timestamp is reproducible and 
checksum is correct
+   # objcopy later inherits the timestamp to debug info 
and stripped file
+   peflags --checksum=1 --timestamp=${SOURCE_DATE_EPOCH} 
${exe} >/dev/null ;;
+   esac
+   fi
+
if defined _CYGPORT_RESTRICT_debuginfo_
then
${objcopy} --strip-all "${exe}";
-- 
2.39.0



Re: [PATCH rebase 1/2] Always update the file checksum in the PE header

2023-08-15 Thread Christian Franke via Cygwin-apps

Corinna Vinschen wrote:

On Aug 12 14:26, Christian Franke via Cygwin-apps wrote:

This patch is still experimental, but tested with all /bin/cyg*.dll from my
installation.

Does that mean I shouldn't apply it for now, or do you want me to
apply it but not create a new release yet?



Meantime I did more tests, also a few with 32-bit DLLs, which all 
succeeded. So it should be safe to use.


In conjunction with the "Don't update the PE header timestamp unless -t 
is used" patch, rebase results are reproducible.


--
Regards,
Christian



[PATCH rebase 2/2] rebase: Don't update the PE header timestamp unless -t is used

2023-08-12 Thread Christian Franke via Cygwin-apps
This changes existing behavior but a new option --keep-timestamp is IMO 
not needed.


--
Regards,
Christian

From 1c13ccb047ebfbcd2f239bedcd50a128fec659e9 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Sat, 12 Aug 2023 14:17:04 +0200
Subject: [PATCH] rebase: Don't update the PE header timestamp unless -t is
 used

This enables reproducible rebase.

Signed-off-by: Christian Franke 
---
 imagehelper/rebaseimage.cc | 6 --
 rebase.c   | 3 ++-
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/imagehelper/rebaseimage.cc b/imagehelper/rebaseimage.cc
index 8827a14..0dec93c 100755
--- a/imagehelper/rebaseimage.cc
+++ b/imagehelper/rebaseimage.cc
@@ -111,12 +111,14 @@ BOOL ReBaseImage64 (
   if (dll.is64bit ())
 {
   ntheader64->OptionalHeader.ImageBase = *NewImageBase;
-  ntheader64->FileHeader.TimeDateStamp = TimeStamp;
+  if (ReBaseChangeFileTime)
+   ntheader64->FileHeader.TimeDateStamp = TimeStamp;
 }
   else
 {
   ntheader32->OptionalHeader.ImageBase = *NewImageBase;
-  ntheader32->FileHeader.TimeDateStamp = TimeStamp;
+  if (ReBaseChangeFileTime)
+   ntheader32->FileHeader.TimeDateStamp = TimeStamp;
 }
 
   int64_t difference = *NewImageBase - *OldImageBase;
diff --git a/rebase.c b/rebase.c
index 20a9902..6a531d0 100644
--- a/rebase.c
+++ b/rebase.c
@@ -1687,7 +1687,8 @@ Rebase PE files, usually DLLs, to a specified address or 
address range.\n\
   -o, --offset=OFFSET Specify an additional offset between adjacent DLLs\n\
   when rebasing.  Default is no offset.\n\
   -t, --touch Use this option to make sure the file's 
modification\n\
-  time is bumped if it has been successfully 
rebased.\n\
+  time and the timestamp in the PE header are bumped 
if\n\
+  the file has been successfully rebased.\n\
   Usually rebase does not change the file's time 
unless\n\
   the -c flag is also specified.\n\
   -T, --filelist=FILE Also rebase the files specified in FILE.  The 
format\n\
-- 
2.39.0



[PATCH rebase 1/2] Always update the file checksum in the PE header

2023-08-12 Thread Christian Franke via Cygwin-apps
This patch is still experimental, but tested with all /bin/cyg*.dll from 
my installation.


--
Regards,
Christian

From 53663d46c2c989e665143b33c0614b416fd1c666 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Sat, 12 Aug 2023 14:13:43 +0200
Subject: [PATCH] Always update the file checksum in the PE header

Both peflags and rebase now update the checksum without reading
the whole file under the assumption that the original checksum
was correct.  Calculation is done by new module
'imagehelper/pechecksum_update.c'.
Slightly change the peflags -k, --checksum option accordingly.

Signed-off-by: Christian Franke 
---
 Makefile.in |   6 +-
 imagehelper/Makefile.in |   7 ++-
 imagehelper/imagehelper.h   |   4 ++
 imagehelper/objectfile.cc   |  62 +++---
 imagehelper/objectfile.h|   7 +++
 imagehelper/pechecksum_update.c |  56 +
 imagehelper/pechecksum_update.h |  52 
 imagehelper/rebaseimage.cc  |   4 ++
 imagehelper/sections.cc |  20 +-
 imagehelper/sections.h  |   8 ++-
 peflags.c   | 107 +---
 rebase.c|  39 
 12 files changed, 305 insertions(+), 67 deletions(-)
 create mode 100644 imagehelper/pechecksum_update.c
 create mode 100644 imagehelper/pechecksum_update.h

diff --git a/Makefile.in b/Makefile.in
index e7b7f6a..edc9eda 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -81,7 +81,7 @@ REBASE_DUMP_OBJS = rebase-dump.$(O) rebase-db.$(O) $(LIBOBJS)
 REBASE_DUMP_LIBS =
 
 PEFLAGS_OBJS = peflags.$(O) pechecksum.$(O) $(LIBOBJS)
-PEFLAGS_LIBS =
+PEFLAGS_LIBS = $(LIBIMAGEHELPER)
 
 SRC_DISTFILES = configure.ac configure Makefile.in \
peflagsall.in rebaseall.in \
@@ -109,8 +109,8 @@ rebase-dump$(EXEEXT): $(REBASE_DUMP_OBJS)
 
 rebase-dump.$(O):: rebase-dump.c rebase-db.h Makefile
 
-peflags$(EXEEXT): $(PEFLAGS_OBJS)
-   $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PEFLAGS_OBJS)
+peflags$(EXEEXT): $(PEFLAGS_OBJS) $(PEFLAGS_LIBS)
+   $(CXX) $(CXXFLAGS) $(LDFLAGS) $(CXX_LDFLAGS) -o $@ $(PEFLAGS_OBJS) 
$(PEFLAGS_LIBS)
 
 peflags.$(O):: peflags.c pechecksum.h Makefile
 
diff --git a/imagehelper/Makefile.in b/imagehelper/Makefile.in
index 0ed8e6c..a40cd8c 100755
--- a/imagehelper/Makefile.in
+++ b/imagehelper/Makefile.in
@@ -75,11 +75,12 @@ LIB_TARGET=imagehelper
 LIB_TARGET_FILE=libimagehelper.a
 LIB_OBJS = objectfile.$(O) objectfilelist.$(O) sections.$(O) debug.$(O) \
rebaseimage.$(O) checkimage.$(O) fiximage.$(O) getimageinfos.$(O) \
-   bindimage.$(O)
+   bindimage.$(O) pechecksum_update.$(O)
 LIB_SRCS = objectfile.cc objectfilelist.cc sections.cc debug.cc \
rebaseimage.cc checkimage.cc fiximage.cc getimageinfos.cc \
-   bindimage.cc
-LIB_HDRS = objectfilelist.h imagehelper.h sections.h objectfile.h
+   bindimage.cc pechecksum_update.c
+LIB_HDRS = objectfilelist.h imagehelper.h sections.h objectfile.h \
+   pechecksum_update.h
 
 #
 # (obsolete) applications
diff --git a/imagehelper/imagehelper.h b/imagehelper/imagehelper.h
index bafc106..8535311 100755
--- a/imagehelper/imagehelper.h
+++ b/imagehelper/imagehelper.h
@@ -33,6 +33,10 @@ extern BOOL ReBaseChangeFileTime;
 /* Set to TRUE, if rebasing should also drop the /DYNAMICBASE flag
from the PE flags. */
 extern BOOL ReBaseDropDynamicbaseFlag;
+/* Set to TRUE if ReBaseImage{64} should update the PE checksum.
+   Cleared if the update failed due to inconsistent original
+   checksum. */
+extern BOOL ReBaseUpdateCheckSum;
 
 BOOL ReBaseImage64(
   LPCSTR CurrentImageName,
diff --git a/imagehelper/objectfile.cc b/imagehelper/objectfile.cc
index 4dafa6a..651fcce 100755
--- a/imagehelper/objectfile.cc
+++ b/imagehelper/objectfile.cc
@@ -24,6 +24,7 @@
 #include 
 
 #include "objectfile.h"
+#include "pechecksum_update.h"
 
 // read a dll into the cache
 
@@ -109,6 +110,15 @@ ObjectFile::ObjectFile(const char *aFileName, bool 
writeable)
   FileName = strdup(name);
 }
 
+  LARGE_INTEGER fs;
+  if (!GetFileSizeEx(hfile, ))
+{
+  CloseHandle(hfile);
+  Error = 2;
+  return;
+}
+  FileSize = fs.QuadPart;
+
   hfilemapping = CreateFileMapping(hfile, NULL, writeable ? PAGE_READWRITE : 
PAGE_READONLY , 0, 0,  NULL);
   if (hfilemapping == 0)
 {
@@ -139,8 +149,7 @@ ObjectFile::ObjectFile(const char *aFileName, bool 
writeable)
   return;
 }
   // filesize big enough to allow at least reading the NT header?
-  if (GetFileSize (hfile, NULL)
-  < (char *) ntheader - (char *) dosheader + sizeof *ntheader)
+  if (FileSize < (char *) ntheader - (char *) dosheader + sizeof *ntheader)
 {
   Error = 4;
   return;
@@ -178,9 +187,6 @@ ObjectFile::~ObjectFile()
 CloseHandle(hfile);
 }
 
-
-
-
 int LinkedObjectFile::level = 0;
 
 LinkedObjectFile::LinkedObjectFile(const char *aFileName, bool writable) : 
ObjectFile(aFileName,writable)
@@ -204,6 +210,12 @@ LinkedOb

Re: [PATCH rebase] rebase: Add -c, --checksum option

2023-08-08 Thread Christian Franke via Cygwin-apps

Jon Turney wrote:

On 08/08/2023 11:10, Christian Franke via Cygwin-apps wrote:

Last patch for now.

Left for later: ReBaseImage64() unconditionally updates the timestamp 
in the file header.


Just for clarity: does this mean that rebasing as it is currently 
implemented leaves the PE file with an invalid checksum, and the 
Windows loader is just fine this that?


Or is there something else happening which makes the checksum wrong?




Both rebase and peflags leave the PE file with an invalid checksum.

This is no problem for Cygwin uses cases:
"Checksums are required for kernel-mode drivers and some system DLLs."
https://learn.microsoft.com/en-us/windows/win32/api/imagehlp/nf-imagehlp-mapfileandchecksuma

--
Regards,
Christian



[PATCH rebase] rebase: Add -c, --checksum option

2023-08-08 Thread Christian Franke via Cygwin-apps

Last patch for now.

Left for later: ReBaseImage64() unconditionally updates the timestamp in 
the file header.


--
Regards,
Christian

From 3973a92cf11056521552d9d3f87efe8e721e8c31 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Tue, 8 Aug 2023 12:04:25 +0200
Subject: [PATCH] rebase: Add -c, --checksum option

If specified, the file checksum in the PE header is updated after
rebasing.

Signed-off-by: Christian Franke 
---
 Makefile.in |  4 ++--
 rebase.c| 50 ++
 2 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/Makefile.in b/Makefile.in
index adb7972..2f061ca 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -74,7 +74,7 @@ override CXX_LDFLAGS+=@EXTRA_CXX_LDFLAG_OVERRIDES@
 
 LIBIMAGEHELPER = imagehelper/libimagehelper.a
 
-REBASE_OBJS = rebase.$(O) rebase-db.$(O) $(LIBOBJS)
+REBASE_OBJS = rebase.$(O) rebase-db.$(O) pechecksum.$(O) $(LIBOBJS)
 REBASE_LIBS = $(LIBIMAGEHELPER)
 
 REBASE_DUMP_OBJS = rebase-dump.$(O) rebase-db.$(O) $(LIBOBJS)
@@ -100,7 +100,7 @@ $(LIBIMAGEHELPER):
 rebase$(EXEEXT): $(REBASE_LIBS) $(REBASE_OBJS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(CXX_LDFLAGS) -o $@ $(REBASE_OBJS) 
$(REBASE_LIBS)
 
-rebase.$(O):: rebase.c rebase-db.h Makefile
+rebase.$(O):: rebase.c pechecksum.h rebase-db.h Makefile
 
 rebase-db.$(O):: rebase-db.c rebase-db.h Makefile
 
diff --git a/rebase.c b/rebase.c
index 7417d4d..50cc79f 100644
--- a/rebase.c
+++ b/rebase.c
@@ -39,6 +39,7 @@
 #include 
 #include 
 #include "imagehelper.h"
+#include "pechecksum.h"
 #include "rebase-db.h"
 #include  /* requires  */
 
@@ -74,6 +75,7 @@ WORD machine = IMAGE_FILE_MACHINE_I386;
 ULONG64 image_base = 0;
 ULONG64 low_addr;
 BOOL down_flag = FALSE;
+BOOL checksum_flag = FALSE;
 BOOL image_info_flag = FALSE;
 BOOL image_storage_flag = FALSE;
 BOOL image_oblivious_flag = FALSE;
@@ -1188,6 +1190,32 @@ print_overlapped ()
 }
 }
 
+static BOOL
+update_checksum (const char *pathname)
+{
+  int fd, err;
+  unsigned old_checksum, new_checksum;
+
+  if ((fd = open (pathname, O_RDWR | O_BINARY)) == -1)
+{
+  fprintf (stderr, "%s: failed to reopen for checksum update: %s\n",
+  pathname, strerror (errno));
+  return FALSE;
+}
+  new_checksum = pe32_checksum (fd, 1, _checksum);
+  err = errno;
+  close(fd);
+  if (!new_checksum)
+{
+  fprintf (stderr, "%s: checksum update failed: %s\n", pathname,
+  strerror (err));
+  /* Assume file is unchanged. */
+  return FALSE;
+}
+
+  return (new_checksum != old_checksum);
+}
+
 BOOL
 rebase (const char *pathname, ULONG64 *new_image_base, BOOL down_flag)
 {
@@ -1279,13 +1307,18 @@ retry:
 }
 #endif
 
+  /* Update checksum, if requested. */
+  status = (checksum_flag ? update_checksum (pathname) : FALSE);
+
   /* Display rebase results, if verbose. */
   if (verbose)
 {
-  printf ("%s: new base = %" PRIx64 ", new size = %x\n",
+  printf ("%s: new base = %" PRIx64 ", new size = %x%s\n",
  pathname,
  (uint64_t) ((down_flag) ? *new_image_base : prev_new_image_base),
- (uint32_t) (new_image_size + offset));
+ (uint32_t) (new_image_size + offset),
+ (checksum_flag ? (status ? ", checksum updated" :
+ ", checksum unchanged") : ""));
 }
 
   /* Calculate next base address, if rebasing up. */
@@ -1299,6 +1332,7 @@ static struct option long_options[] = {
   {"32",   no_argument,   NULL, '4'},
   {"64",   no_argument,   NULL, '8'},
   {"base", required_argument, NULL, 'b'},
+  {"checksum", no_argument,   NULL, 'c'},
   {"down", no_argument,   NULL, 'd'},
   {"help", no_argument,   NULL, 'h'},
   {"usage",no_argument,   NULL, 'h'},
@@ -1316,7 +1350,7 @@ static struct option long_options[] = {
   {NULL,   no_argument,   NULL,  0 }
 };
 
-static const char *short_options = "48b:dhiMno:OqstT:vV";
+static const char *short_options = "48b:cdhiMno:OqstT:vV";
 
 void
 parse_args (int argc, char *argv[])
@@ -1341,6 +1375,9 @@ parse_args (int argc, char *argv[])
  image_base = string_to_ulonglong (optarg);
  force_rebase_flag = TRUE;
  break;
+   case 'c':
+ checksum_flag = TRUE;
+ break;
case 'd':
  down_flag = TRUE;
  break;
@@ -1625,6 +1662,10 @@ Rebase PE files, usually DLLs, to a specified address or 
address range.\n\
   One of the options -b, -s or -i is mandatory.  If no rebase database 
exists\n\
   yet, -b is required together with -s.\n\
 \n\
+  -c, --checksum  Update the file's checksum in the PE header if the\n\
+  file has been successfully rebased.  This also 
bumps\n\
+  the file's modificatio

[PATCH rebase] Add missing pechecksum.* to SRC_DISTFILES

2023-08-08 Thread Christian Franke via Cygwin-apps

Missed yesterday, sorry.

--
Regards,
Christian

From 84065da466d9501d0522af8860ea829ee51c12f5 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Tue, 8 Aug 2023 10:52:14 +0200
Subject: [PATCH] Add missing pechecksum.* to SRC_DISTFILES

Signed-off-by: Christian Franke 
---
 Makefile.in | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Makefile.in b/Makefile.in
index 46df1d5..adb7972 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -84,7 +84,8 @@ PEFLAGS_OBJS = peflags.$(O) pechecksum.$(O) $(LIBOBJS)
 PEFLAGS_LIBS =
 
 SRC_DISTFILES = configure.ac configure Makefile.in \
-   peflagsall.in rebaseall.in peflags.c rebase.c \
+   peflagsall.in rebaseall.in \
+   pechecksum.c pechecksum.h peflags.c rebase.c \
build.sh ChangeLog COPYING NEWS README setup.hint Todo \
build-aux/config.guess build-aux/config.sub \
build-aux/install-sh getopt.h_ getopt_long.c \
-- 
2.39.0



Re: [PATCH rebase] peflags: Fix ULONG range checks

2023-08-08 Thread Christian Franke via Cygwin-apps

Corinna Vinschen wrote:

On Aug  8 10:06, Christian Franke via Cygwin-apps wrote:

Corinna Vinschen via Cygwin-apps wrote:

Hi Christian,

On Aug  7 16:07, Christian Franke via Cygwin-apps wrote:

Minor issue found during tests of the upcoming 'peflags --timestamp' patch.

--
Regards,
Christian

...
diff --git a/peflags.c b/peflags.c
index 93eaa0b..d98b121 100644
--- a/peflags.c
+++ b/peflags.c
@@ -30,7 +30,6 @@
   #include 
   #include 
   #include 
-#include 
   #if defined (__CYGWIN__) || defined (__MSYS__)
   #include 
   #endif
@@ -598,7 +597,7 @@ handle_num_option (const char *option_name,
   || sizeof_vals[option_index].value > 0xULL
   /* Just a ULONG value */
   || (sizeof_vals[option_index].is_ulong
-  && sizeof_vals[option_index].value > ULONG_MAX))
+  && sizeof_vals[option_index].value > 0xULL))

What about using MAXDWORD or MAXULONG32 instead?

Of course :-)

Christian


Pushed.  I've started deploying a new release.


I'm currently working on 'rebase -c, --checksum' and found one minor 
issue: pechecksum.* are missing in SRC_DISTFILES.




Re: [PATCH rebase] peflags: Fix ULONG range checks

2023-08-08 Thread Christian Franke via Cygwin-apps

Corinna Vinschen via Cygwin-apps wrote:

Hi Christian,

On Aug  7 16:07, Christian Franke via Cygwin-apps wrote:

Minor issue found during tests of the upcoming 'peflags --timestamp' patch.

--
Regards,
Christian

...
diff --git a/peflags.c b/peflags.c
index 93eaa0b..d98b121 100644
--- a/peflags.c
+++ b/peflags.c
@@ -30,7 +30,6 @@
  #include 
  #include 
  #include 
-#include 
  #if defined (__CYGWIN__) || defined (__MSYS__)
  #include 
  #endif
@@ -598,7 +597,7 @@ handle_num_option (const char *option_name,
   || sizeof_vals[option_index].value > 0xULL
   /* Just a ULONG value */
   || (sizeof_vals[option_index].is_ulong
-  && sizeof_vals[option_index].value > ULONG_MAX))
+  && sizeof_vals[option_index].value > 0xULL))

What about using MAXDWORD or MAXULONG32 instead?


Of course :-)

Christian

From 8c8537fbc08d677651eee3055e5b0c6c9873804d Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Tue, 8 Aug 2023 09:58:39 +0200
Subject: [PATCH] peflags: Fix ULONG range checks

Don't use ULONG_MAX from  because ULONG is not necessarily
'unsigned long'.  Use MAXULONG32 instead.

Signed-off-by: Christian Franke 
---
 peflags.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/peflags.c b/peflags.c
index f215704..1a61da7 100644
--- a/peflags.c
+++ b/peflags.c
@@ -30,7 +30,6 @@
 #include 
 #include 
 #include 
-#include 
 #if defined (__CYGWIN__) || defined (__MSYS__)
 #include 
 #endif
@@ -696,7 +695,7 @@ handle_num_option (const char *option_name,
   || sizeof_vals[option_index].value > 0xULL
   /* Just a ULONG value */
   || (sizeof_vals[option_index].is_ulong
-  && sizeof_vals[option_index].value > ULONG_MAX))
+  && sizeof_vals[option_index].value > MAXULONG32))
 {
   fprintf (stderr, "Invalid argument for %s: %s\n", 
   option_name, option_arg);
@@ -1092,7 +1091,7 @@ get_and_set_size (const pe_file *pep, sizeof_values_t 
*val)
 }
   else if (val->handle == DO_WRITE)
 {
-  if ((!pep->is_64bit || val->is_ulong) && val->value >= ULONG_MAX)
+  if ((!pep->is_64bit || val->is_ulong) && val->value > MAXULONG32)
{
  fprintf (stderr, "%s: Skip writing %s, value too big\n",
   pep->pathname, val->name);
-- 
2.39.0



[PATCH rebase 2/2] peflags: Add -k, --checksum option

2023-08-07 Thread Christian Franke via Cygwin-apps
This patch is on top of the --timestamp patch. Could not be applied to 
current HEAD without conflicts.


--
Regards,
Christian

From 9ecaf86bff5d229bf5b2a1ba1ff4674526fc1b68 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Mon, 7 Aug 2023 15:52:14 +0200
Subject: [PATCH] peflags: Add -k, --checksum option

This allows to fix the file checksum in the PE header.
An invalid checksum may break reproducible builds or may
increase the risk of false positive malware detections.
The checksum calculation is done by a new self-contained module
'pechecksum.c' which could also be built as a stand-alone tool
or later added to rebase.

Signed-off-by: Christian Franke 
---
 Makefile.in  |   6 +-
 pechecksum.c | 195 +++
 pechecksum.h |  25 +++
 peflags.c| 129 --
 4 files changed, 347 insertions(+), 8 deletions(-)
 create mode 100644 pechecksum.c
 create mode 100644 pechecksum.h

diff --git a/Makefile.in b/Makefile.in
index 34c4684..46df1d5 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -80,7 +80,7 @@ REBASE_LIBS = $(LIBIMAGEHELPER)
 REBASE_DUMP_OBJS = rebase-dump.$(O) rebase-db.$(O) $(LIBOBJS)
 REBASE_DUMP_LIBS =
 
-PEFLAGS_OBJS = peflags.$(O) $(LIBOBJS)
+PEFLAGS_OBJS = peflags.$(O) pechecksum.$(O) $(LIBOBJS)
 PEFLAGS_LIBS =
 
 SRC_DISTFILES = configure.ac configure Makefile.in \
@@ -111,7 +111,9 @@ rebase-dump.$(O):: rebase-dump.c rebase-db.h Makefile
 peflags$(EXEEXT): $(PEFLAGS_OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(PEFLAGS_OBJS)
 
-peflags.$(O):: peflags.c Makefile
+peflags.$(O):: peflags.c pechecksum.h Makefile
+
+pechecksum.$(O):: pechecksum.c pechecksum.h Makefile
 
 getopt.h: getopt.h_
cp $^ $@
diff --git a/pechecksum.c b/pechecksum.c
new file mode 100644
index 000..8695138
--- /dev/null
+++ b/pechecksum.c
@@ -0,0 +1,195 @@
+/*
+ * PE32 checksum
+ *
+ * Copyright (C) 2023 Christian Franke
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "pechecksum.h"
+
+#include 
+#include 
+#include 
+
+static inline unsigned get_word(const unsigned char * p)
+{
+  return p[0] | (p[1] << 8);
+}
+
+static inline unsigned get_dword(const unsigned char * p)
+{
+  return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
+}
+
+static inline void put_dword(unsigned char * p, unsigned val)
+{
+  p[0] = (unsigned char) val;
+  p[1] = (unsigned char)(val >>  8);
+  p[2] = (unsigned char)(val >> 16);
+  p[3] = (unsigned char)(val >> 24);
+}
+
+unsigned pe32_checksum(int fd, int set, unsigned * old_checksum)
+{
+  // Read headers.
+  const unsigned bufsiz = 4096;
+  unsigned char buf[bufsiz];
+  if (lseek(fd, 0, SEEK_SET) != 0)
+return 0;
+  int nr = read(fd, buf, bufsiz);
+  if (nr < 0)
+return 0;
+  if (nr <= 0x200) {
+errno = EINVAL;
+return 0;
+  }
+
+  // IMAGE_DOS_HEADER.pe_magic == "MZ" ?
+  if (get_word(buf) != 0x5a4d) {
+errno = EINVAL;
+return 0;
+  }
+  // pehdr_offs = IMAGE_DOS_HEADER.lfa_new
+  unsigned pehdr_offs = get_dword(buf + 0x3c);
+  if (!(0x40 <= pehdr_offs && pehdr_offs <= nr - 0x100)) {
+errno = EINVAL;
+return 0;
+  }
+  // IMAGE_NT_HEADERS.Signature == "PE" ?
+  if (get_word(buf + pehdr_offs) != 0x4550) {
+errno = EINVAL;
+return 0;
+  }
+  // old_sum = IMAGE_OPTIONAL_HEADER(32|64).CheckSum
+  unsigned sum_offs = pehdr_offs + 0x58;
+  unsigned old_sum = get_dword(buf + sum_offs);
+  if (old_checksum)
+*old_checksum = old_sum;
+
+  // Clear old checksum because it is included below.
+  put_dword(buf + sum_offs, 0);
+
+  // Calc new checksum.
+  unsigned sum = 0, size = 0;
+  int i = 0;
+  for (;;) {
+sum += get_word(buf + i);
+sum = (sum + (sum >> 16)) & 0x;
+
+if ((size += 2) >= 0x4000) {
+  // 1GiB, assume something is wrong.
+  errno = EINVAL;
+  return 0;
+}
+if ((i += 2) < nr - 1)
+  continue; // ... with next 2 bytes.
+
+// Assume that there are no short reads.
+if (i < nr)
+  break; // Last byte.
+i = 0;
+if ((nr = read(fd, buf, bufsiz)) < 0)
+  return 0;
+if (nr < 2)
+  break; // Last byte or EOF.
+// Continue with next block.
+  }
+
+  // Handle last byte of file with uneven size.
+  if (i < nr) {
+sum += buf[i];
+sum = (sum + (sum >> 16)) & 0x;
+size++;
+  }
+
+  // Add filesize to use some of the upper 16 bits.
+  sum += size;
+
+  // Fix the checksum if requested and required.
+  if (set && old_sum != sum) {
+put_dword(buf, sum);
+if (lseek(fd, sum_offs, SEEK_SET) == -1)
+  return 0;
+if (write(fd, buf, 4) == -1)
+  return 0;
+  }
+
+  return sum;
+}
+
+#if STANDALONE
+//
+// Test program
+//
+#include 
+#include 
+
+// Optionally check result using native imagehlp.dll function.
+#if STANDALONE > 1
+#include 
+#include 
+#endif
+
+int main(int argc, char ** argv)
+{
+  int i = 1,

[PATCH rebase 1/2] peflags: Add -p, --timestamp option

2023-08-07 Thread Christian Franke via Cygwin-apps
Running 'peflags -p /bin/*.exe' with the patch applied suggests that 
objcopy/strip recently changed behavior and no longer set timestamps to 0.


Related: https://sourceware.org/bugzilla/show_bug.cgi?id=30702

--
Regards,
Christian

From 68d42574e4b7bbc0659708ce801b6cd25b88dc11 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Mon, 7 Aug 2023 14:02:12 +0200
Subject: [PATCH] peflags: Add -p, --timestamp option

This allows to set the header timestamp to 0 or some other fixed
value (SOURCE_DATE_EPOCH) to support reproducible builds.

Signed-off-by: Christian Franke 
---
 peflags.c | 29 +
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/peflags.c b/peflags.c
index d98b121..f4b1812 100644
--- a/peflags.c
+++ b/peflags.c
@@ -131,6 +131,7 @@ enum {
   SIZEOF_HEAP_RESERVE,
   SIZEOF_HEAP_COMMIT,
   SIZEOF_CYGWIN_HEAP,
+  SIZEOF_TIMESTAMP,
   NUM_SIZEOF_VALUES/* Keep at the end */
 };
 
@@ -152,7 +153,7 @@ typedef struct {
   ULONG   offset32;
 } sizeof_values_t;
 
-sizeof_values_t sizeof_vals[5] = {
+static sizeof_values_t sizeof_vals[NUM_SIZEOF_VALUES] = {
   { 0, "stack reserve size"  , "bytes", 0, FALSE,
 offsetof (IMAGE_NT_HEADERS64, OptionalHeader.SizeOfStackReserve),
 offsetof (IMAGE_NT_HEADERS32, OptionalHeader.SizeOfStackReserve),
@@ -172,6 +173,10 @@ sizeof_values_t sizeof_vals[5] = {
   { 0, "initial Cygwin heap size", "MB", 0, TRUE,
 offsetof (IMAGE_NT_HEADERS64, OptionalHeader.LoaderFlags),
 offsetof (IMAGE_NT_HEADERS32, OptionalHeader.LoaderFlags),
+  },
+  { 0, "file header timestamp", "seconds", 0, TRUE,
+offsetof (IMAGE_NT_HEADERS64, FileHeader.TimeDateStamp),
+offsetof (IMAGE_NT_HEADERS32, FileHeader.TimeDateStamp),
   }
 };
 
@@ -197,6 +202,7 @@ static struct option long_options[] = {
   {"heap-reserve", optional_argument, NULL, 'y'},
   {"heap-commit",  optional_argument, NULL, 'Y'},
   {"cygwin-heap",  optional_argument, NULL, 'z'},
+  {"timestamp",optional_argument, NULL, 'p'},
   {"filelist", no_argument, NULL, 'T'},
   {"verbose",  no_argument, NULL, 'v'},
   {"help", no_argument, NULL, 'h'},
@@ -204,7 +210,7 @@ static struct option long_options[] = {
   {NULL, no_argument, NULL, 0}
 };
 static const char *short_options
-   = "d::e::c::f::n::i::s::b::W::t::w::l::S::x::X::y::Y::z::T:vhV";
+   = "d::e::c::f::n::i::s::b::W::t::w::l::S::x::X::y::Y::z::p::T:vhV";
 
 static void short_usage (FILE *f);
 static void help (FILE *f);
@@ -459,13 +465,22 @@ do_mark (const char *pathname)
{
  if (sizeof_vals[i].handle != DONT_HANDLE)
{
- printf ("%*s%-24s: %" PRIu64 " (0x%" PRIx64 ") %s\n",
+  char extra[32] = "";
+ if (verbose && i == SIZEOF_TIMESTAMP)
+   {
+ time_t t = (time_t)sizeof_vals[i].value;
+ const struct tm * tp = gmtime ();
+ if (tp)
+   strftime (extra, sizeof(extra), " [%Y-%m-%d %H:%M:%S UTC]", 
tp);
+   }
+
+ printf ("%*s%-24s: %" PRIu64 " (0x%" PRIx64 ") %s%s\n",
  printed_characteristic ? (int) strlen (pathname) + 2
 : 0, "",
  sizeof_vals[i].name,
  (uint64_t) sizeof_vals[i].value,
  (uint64_t) sizeof_vals[i].value,
- sizeof_vals[i].unit);
+ sizeof_vals[i].unit, extra);
  printed_characteristic = TRUE;
}
}
@@ -786,6 +801,11 @@ parse_args (int argc, char *argv[])
 optarg,
 SIZEOF_CYGWIN_HEAP);
  break;
+   case 'p':
+ handle_num_option (long_options[option_index].name,
+optarg,
+SIZEOF_TIMESTAMP);
+ break;
case 'T':
  file_list = optarg;
  break;
@@ -1118,6 +1138,7 @@ help (FILE *f)
 "  Useful values are between 4 and 2048.  If 0,\n"
 "  Cygwin uses the default heap size of 384 
Megs.\n"
 "  Has no meaning for non-Cygwin applications.\n"
+"  -p, --timestamp [NUM]   Timestamp in file header (seconds since 
epoch).\n"
 "  -T, --filelist FILE Indicate that FILE contains a list\n"
 "  of PE files to process\n"
 "  -v, --verbose   Display diagnostic information\n"
-- 
2.39.0



[PATCH rebase] peflags: Fix ULONG range checks

2023-08-07 Thread Christian Franke via Cygwin-apps

Minor issue found during tests of the upcoming 'peflags --timestamp' patch.

--
Regards,
Christian

From 9da405da78e92dc8263239e25365bee3167f185e Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Mon, 7 Aug 2023 13:42:50 +0200
Subject: [PATCH] peflags: Fix ULONG range checks

Don't use ULONG_MAX from  because ULONG is not necessarily
'unsigned long'.

Signed-off-by: Christian Franke 
---
 peflags.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/peflags.c b/peflags.c
index 93eaa0b..d98b121 100644
--- a/peflags.c
+++ b/peflags.c
@@ -30,7 +30,6 @@
 #include 
 #include 
 #include 
-#include 
 #if defined (__CYGWIN__) || defined (__MSYS__)
 #include 
 #endif
@@ -598,7 +597,7 @@ handle_num_option (const char *option_name,
   || sizeof_vals[option_index].value > 0xULL
   /* Just a ULONG value */
   || (sizeof_vals[option_index].is_ulong
-  && sizeof_vals[option_index].value > ULONG_MAX))
+  && sizeof_vals[option_index].value > 0xULL))
 {
   fprintf (stderr, "Invalid argument for %s: %s\n", 
   option_name, option_arg);
@@ -960,7 +959,7 @@ get_and_set_size (const pe_file *pep, sizeof_values_t *val)
 }
   else if (val->handle == DO_WRITE)
 {
-  if ((!pep->is_64bit || val->is_ulong) && val->value >= ULONG_MAX)
+  if ((!pep->is_64bit || val->is_ulong) && val->value > 
0xULL)
{
  fprintf (stderr, "%s: Skip writing %s, value too big\n",
   pep->pathname, val->name);
-- 
2.39.0



Re: [PATCH setup] Keyboard accelerator for keep or skip

2023-07-31 Thread Christian Franke via Cygwin-apps

Jon Turney wrote:

On 25/04/2023 18:00, Christian Franke via Cygwin-apps wrote:
Use case: Easily prevent update of multiple packages in the "Pending" 
view, in particular useful if "Test" is selected.


Sorry for the delay in looking at this.  Obviously needed.


N.P.



Please apply.


Done.



Re: [PATCH setup 2/2] Detect filename collisions between packages

2023-04-27 Thread Christian Franke via Cygwin-apps

Jon Turney wrote:

...
Using std::set_intersection() on values from std::map() here is 
probably

a mistake. It's simple to write, but the performance is not good.


A faster alternative which avoids set_intersection calls in a loop is 
possibly to use one large data structure which maps filenames to sets 
of packages. Using multimap instead of the 
straightforward map> needs possibly less memory 
(not tested). But for multimap it is required that file/package name 
pairs are not inserted twice.


I attached a small standalone POC source file using multimap. It 
would also detect collisions in the already installed packages.


Thanks for the ideas. It seems I really didn't think that carefully 
about this...


It seems like maybe building a map from filename to the set of package 
names which contain it, and then finding all the filenames where that 
set has more than one member would be a possible better implementation.


Of course this is the more obvious method and easier to implement. It is 
somewhat slower and needs more memory.


Meantime I did a quick artificial test with 1 "packages" with 100 
"files" each and 2 collisions. This resulted in a (multi)map size if 
100(+2), total size of strings was ~80MB. Results:


Data structure: execution time, memory (working set)
multimap: 1.8 seconds, 238MB
map>: 2.0 seconds, 318MB

The execution time is needed for the map insertions. The final scan for 
collisions is very fast in both cases.




[PATCH setup] Keyboard accelerator for keep or skip

2023-04-25 Thread Christian Franke via Cygwin-apps
Use case: Easily prevent update of multiple packages in the "Pending" 
view, in particular useful if "Test" is selected.


--
Regards,
Christian

From 05d9c72f07cf754dc6172a998b2e0991034d363f Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Tue, 25 Apr 2023 18:42:18 +0200
Subject: [PATCH] Keyboard accelerator for keep or skip

Ctrl+K selects keep or skip and then moves selection to next row.
---
 PickPackageLine.cc | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/PickPackageLine.cc b/PickPackageLine.cc
index c1e2a15..d380965 100644
--- a/PickPackageLine.cc
+++ b/PickPackageLine.cc
@@ -155,6 +155,7 @@ PickPackageLine::map_key_to_action(WORD vkey, int modkeys, 
int & col_num,
   col_num = new_col;
   return Action::PopUp;
 case 'I': // Ctrl+I: select install default version and move to next row
+case 'K': // Ctrl+K: select keep or skip package and move to next row
 case 'R': // Ctrl+R: select reinstall and move to next row
 case 'U': // Ctrl+U: select uninstall and move to next row
   if (modkeys != ModifierKeys::Control)
@@ -163,8 +164,9 @@ PickPackageLine::map_key_to_action(WORD vkey, int modkeys, 
int & col_num,
   switch (vkey)
 {
 case 'I': action_id = packagemeta::Install_action; break;
+default:  action_id = packagemeta::NoChange_action; break;
 case 'R': action_id = packagemeta::Reinstall_action; break;
-default:  action_id = packagemeta::Uninstall_action; break;
+case 'U': action_id = packagemeta::Uninstall_action; break;
 }
   return Action::Direct | Action::NextRow;
 }
-- 
2.39.0



Re: [PATCH setup 2/2] Detect filename collisions between packages

2023-04-24 Thread Christian Franke via Cygwin-apps

Jon Turney via Cygwin-apps wrote:

Detect filename collisions between packages
Don't check filenames under /etc/postinstall/ for collisions
Report when filename collisions exist
Add option '--collisions' to enable


IMO a useful enhancement.



Notes:

Reading file catalog from a package is moderately expensive in terms of
I/O: To extract all the filenames from a tar archive, we need to seek to
every file header, and to seek forward through a compressed file, we
must examine every intervening byte to decompress it.

This adds a fourth(!) pass through each archive (one to checksum it, one
to extract files, another one (I added in dbfd1a64 without thinking too
deeply about it) to extract symlinks), and now one to check for filename
collisions).

Using std::set_intersection() on values from std::map() here is probably
a mistake. It's simple to write, but the performance is not good.


A faster alternative which avoids set_intersection calls in a loop is 
possibly to use one large data structure which maps filenames to sets of 
packages. Using multimap instead of the straightforward 
map> needs possibly less memory (not tested). But 
for multimap it is required that file/package name pairs are not 
inserted twice.


I attached a small standalone POC source file using multimap. It would 
also detect collisions in the already installed packages.




...
diff --git a/filemanifest.h b/filemanifest.h
new file mode 100644
index 000..cc6fb81
--- /dev/null
+++ b/filemanifest.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2022 Jon Turney
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * A copy of the GNU General Public License can be found at
+ *http://www.gnu.org/


"SPDX-License-Identifier: GPL-2.0-or-later" is possibly a more brief and 
modern way to say this in new code.




+ *
+ */
+
+/*
+  FileManifest
+
+  A serializable set of filenames
+  each filename is associated with the package name that owns it
+
+  Used when working with the install package file manifests in /etc/setup
+*/
+
+#include 
+#include 


This should be  as std::unordered_map is not used in the code.



+#include 
+
+class FileManifest: public std::map
+{
+};


Is the new file filemanifest.h required at all? It could be reduced to 
the following in install.cc:


#include 
...
typedef std::map FileManifest;
// or more modern (C++11):
// using FileManifest = std::map;


--
Regards,
Christian

#include 
#include 
#include 

using FileManifest = std::multimap;

int main()
{
  FileManifest manifest;

  // read from /etc/setup/*.lst.gz
  const FileManifest installed {
{"/usr/bin/file11", "package1"}, // #1 package2
{"/usr/bin/file12", "package1"}, // #2 package3
{"/usr/bin/file21", "package2"},
{"/usr/bin/file22", "package2"}, // #3 package3, package4
{"/usr/bin/file11", "package2"}  // #1 package1
  };
  manifest.insert(installed.begin(), installed.end());

  // read from tar files to be installed
  const FileManifest install {
{"/usr/bin/file31", "package3"},
{"/usr/bin/file12", "package3"}, // #2 package1
{"/usr/bin/file22", "package3"}, // #3 package2, package4
{"/usr/bin/file41", "package4"},
{"/usr/bin/file42", "package4"},
{"/usr/bin/file22", "package4"}  // #3 package2, package3
  };
  manifest.insert(install.begin(), install.end());
  
  for (auto i = manifest.cbegin(), end = manifest.cend(); i != end; ) {
auto j = i;
if (++j != end && j->first == i->first) {
  std::printf("Packages");
  j = i;
  do
std::printf(" %s", j->second.c_str());
  while (++j != end && j->first == i->first);
  std::printf(" contain file %s\n", i->first.c_str());
}
  //else
//std::printf("Package %s contains file %s\n",
//i->second.c_str(), i->first.c_str());
i = j;
  }
  return 0;
}


Re: [PATCH setup] Add tooltip for Ctrl+I/R/U accelerator keys

2023-02-02 Thread Christian Franke via Cygwin-apps

Jon Turney wrote:

On 22/11/2022 16:00, Christian Franke wrote:
This is a first try to make these keys more obvious as requested on 
the Cygwin ML.


A more complex approach would be to mention only the keys which 
actually would change the current package state.


Thanks for this patch.

So, I appreciate what this is trying to do, but I have great 
difficultly convincing myself that this is the right approach.




I'm also not sure. An alternative would possibly be some help below the 
listbox, centered in the same line as "Hide obsolete packages".



We don't need to resort to a tooltip for any other shortcut, because 
there is an established visual design language to indicate those.  I 
guess we just need to find what's consistent with pre-existing ways of 
indicating this kind of behaviour in other applications.




Cygwin setup is somewhat uncommon as there is no default menu bar with 
drop-down menus. Accelerator keys are traditionally mentioned there.




Re: [PATCH setup] Ignore reinstall requests if version is not accessible

2022-12-16 Thread Christian Franke via Cygwin-apps

Jon Turney wrote:

On 11/12/2022 15:11, Christian Franke via Cygwin-apps wrote:
This prevents accidental package loss if reinstall is run from local 
directory but the package is no longer cached.


Thanks.  This seems right, so please apply.


Done.

Could you please also review "[PATCH setup] Add tooltip for Ctrl+I/R/U 
accelerator keys" before next release?





Possible further improvement: Do not offer "Reinstall" in the popup 
menu in this case.


Indeed.

That might be simply fixable, but really, we need to keep an index of 
the files in the package cache, so we can handle situations like this 
properly, without spending lots of time spinning rust 


Agree. "Install from Local Directory" is in particular slow on HDDs when 
directory tree is fragmented or even slower if the cache is on a network 
share.



(we could then also do some expiry on the cache, which is a feature 
that has been needed for decades...)



For example: Add checkbox(es) to LocalDirPage to enable/configure cache 
cleanup. In a later step remove all files that could no longer be 
downloaded (like Debian's "apt-get autoclean") and are no longer 
installed. The latter would need some heuristics for source packages as 
these do not appear in installed.db.


BTW, I have a local bash-script 'cygcache' which allows to list package 
states ([auto]installed, cached, curr/prev/test), cleanup the cache 
using above rules (configurable) or merge cache directories into one. 
Still requires some polishing. If there is any interest, I could ITP it 
next year.




[PATCH setup] Ignore reinstall requests if version is not accessible

2022-12-11 Thread Christian Franke via Cygwin-apps
This prevents accidental package loss if reinstall is run from local 
directory but the package is no longer cached.


Possible further improvement: Do not offer "Reinstall" in the popup menu 
in this case.


--
Regards,
Christian

From 054697c297a3e21ee5e63f51b27431640cab5cde Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Sun, 11 Dec 2022 15:55:47 +0100
Subject: [PATCH] Ignore reinstall requests if version is not accessible

---
 package_meta.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package_meta.cc b/package_meta.cc
index 2257b59..3daa970 100644
--- a/package_meta.cc
+++ b/package_meta.cc
@@ -672,7 +672,7 @@ packagemeta::set_action (_actions action, packageversion 
const _version,
   else if (action == Reinstall_action)
 {
   desired = installed;
-  if (desired)
+  if (desired.accessible ())
{
  pick (true);
  srcpick (false);
-- 
2.38.1



Re: [Bug] setup regression #2

2022-11-30 Thread Christian Franke

Jon Turney wrote:

On 20/11/2022 19:05, Achim Gratz wrote:

Jon Turney writes:

I believe that the intent of the code in setup is that there should
only be two modes:

USER: install "for me", with the users primary group


As I understand it, the intention here was that the user can have a
"single user installation" in a place that they have access to (say,
their home directory) while they have no permission in one of the usual
places.  In a setup where that place is a certain type of share the user
will not be able to change the group the files are owned by anyway
(standard NetApp CIFS shares are set up this way) and it may not be the
users primary group.


SYSTEM: install "for everyone", with the administrators primary group
(only permitted if you are an administrator)


I don't see why the fact the installation is meant to be used by
multiple users means that the install must be owned by group
Administrators.  I'm not sure this is a good idea on Windows anyway, at
least when you don't put extra (inheritable) DACL on the install
folder.


Christian,

Maybe you can offer your opinion here, since you seem to have the 
opposite, or at least a different, point of view.


Anything installed with "All Users" option should IMO be protected 
against modifications by any regular non-elevated user.


This is not the case if the RID=513 group ("HOST\None", 
"DOMAIN\Domain-Users") is used. Many upstream projects install 
directories and files with permissions like 0664, 0775, 0660 or 0770. 
This is safe when the group is "root". On current Cygwin, all users have 
R/W access regardless of the "other" permission bits.


Try for example: find /usr/share ! -type l -perm -020 -ls (~4000 hits on 
my installation)


Using the administrators group as discussed here would solve this but 
apparently introduces interesting new permission problems with some 
packages. Could these possibly be solved by the maintainers of the 
affected packages?


An alternative may be: Keep the group as is, but prevent using above 
permissions as far as possible. For new packages, this could possibly be 
done with an enhancement of cygport. But I'm sure that there will also 
be subtle cases where these modified permissions break things. Cygport 
could allow to opt-out then.


Ideally the protection should also be effective for the non-elevated 
user who runs setup elevated. This is automatically the case for typical 
installers because Windows changes TokenOwner to administrators group if 
run elevated. That's why I provided 
https://sourceware.org/pipermail/cygwin-apps/2022-August/042221.html




Re: [PATCH setup] Add new option --chown-admin

2022-11-30 Thread Christian Franke

Jon Turney wrote:

On 04/10/2022 13:05, Christian Franke wrote:

Jon Turney wrote:


Corinna had some concerns about making the owner a group, rather 
than a user, which I believe historically caused some difficulties 
in Cygwin, so I think I'll need to understand that better before 
making a decision about this change.


I see. Do you have any info about these difficulties?
Are these still relevant? If yes, let's forget this patch.


After a bit of research, I think the issue was that if you make user 
owner and group owner map onto the same Windows SID, certain unix 
access permissions cannot be reversibly mapped onto a Windows ACL.


(e.g you can't set the mode to 0600, because when you read that back, 
it's mode is 0660. Some programs e.g ssh check for and require 0600 
permission on some files)




No and yes.

No, a quick test shows that stat() returns what chmod() sets even in 
this case:


# for p in 600 640 660 644 664; do f=perm-$p &&
    touch $f && chown Administrators.Administrators $f &&
    chmod $p $f && ls -l $f
  done
-rw--- 1 Administrators Administrators 0 Nov 30 18:39 perm-600
-rw-r- 1 Administrators Administrators 0 Nov 30 18:39 perm-640
-rw-rw 1 Administrators Administrators 0 Nov 30 18:39 perm-660
-rw-r--r-- 1 Administrators Administrators 0 Nov 30 18:39 perm-644
-rw-rw-r-- 1 Administrators Administrators 0 Nov 30 18:39 perm-664

The above likely works due to some heuristic based on ACE order.

Yes, the effective permissions of 0600 are always the same as 0660 
because the first ACE is already for the group:


# icacls perm-\*
perm-600 BUILTIN\Administrators:(R,W,D,WDAC,WO)
 BUILTIN\Administrators:(Rc,S,RA)
 Everyone:(Rc,S,RA)

perm-640 BUILTIN\Administrators:(R,W,D,WDAC,WO)
 BUILTIN\Administrators:(R)
 Everyone:(Rc,S,RA)

perm-644 BUILTIN\Administrators:(R,W,D,WDAC,WO)
 BUILTIN\Administrators:(R)
 Everyone:(R)

perm-660 BUILTIN\Administrators:(R,W,D,WDAC,WO)
 BUILTIN\Administrators:(R,W)
 Everyone:(Rc,S,RA)

perm-664 BUILTIN\Administrators:(R,W,D,WDAC,WO)
 BUILTIN\Administrators:(R,W)
 Everyone:(R)

(Tests done on German Windows and localized names renamed afterwards).



This perhaps isn't terribly relevant to files created by setup


It may depend on how access checks are done by ssh etc.. (mode bits or 
effective permissions).




[PATCH setup] Add tooltip for Ctrl+I/R/U accelerator keys

2022-11-22 Thread Christian Franke
This is a first try to make these keys more obvious as requested on the 
Cygwin ML.


A more complex approach would be to mention only the keys which actually 
would change the current package state.


--
Regards,
Christian

From 6bfb1f07c772fd6298c63b3b2ae53000e26a6237 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Tue, 22 Nov 2022 16:38:39 +0100
Subject: [PATCH] Add tooltip for Ctrl+I/R/U accelerator keys

Tooltip is shown for "New" column of selected row.
---
 ListView.cc | 3 ++-
 ListView.h  | 2 +-
 PickCategoryLine.cc | 2 +-
 PickCategoryLine.h  | 2 +-
 PickPackageLine.cc  | 9 +++--
 PickPackageLine.h   | 2 +-
 res/en/res.rc   | 1 +
 res/fr/res.rc   | 1 +
 resource.h  | 1 +
 9 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/ListView.cc b/ListView.cc
index 7cc7f0f..40addaa 100644
--- a/ListView.cc
+++ b/ListView.cc
@@ -643,7 +643,8 @@ ListView::OnNotify (NMHDR *pNmHdr, LRESULT *pResult)
   static StringCache tooltip;
   tooltip = "";
   if (contents)
-tooltip = (*contents)[iRow]->get_tooltip(iCol);
+tooltip = (*contents)[iRow]->get_tooltip(iCol, GetFocus() == 
hWndListView
+  && ListView_GetSelectionMark(hWndListView) == iRow);
 
   // set the tooltip text
   NMTTDISPINFO *pNmTTDispInfo = (NMTTDISPINFO *)pNmHdr;
diff --git a/ListView.h b/ListView.h
index 6a1be0b..2703d1f 100644
--- a/ListView.h
+++ b/ListView.h
@@ -40,7 +40,7 @@ class ListViewLine
   virtual ~ListViewLine() {};
   virtual const std::wstring get_text(int col) const = 0;
   virtual State get_state() const = 0;
-  virtual const std::string get_tooltip(int col) const = 0;
+  virtual const std::string get_tooltip(int col, bool selected) const = 0;
   virtual int get_indent() const = 0;
   virtual ActionList *get_actions(int col) const = 0;
   virtual int do_action(int col, int id) = 0;
diff --git a/PickCategoryLine.cc b/PickCategoryLine.cc
index b13dbe4..d9f9535 100644
--- a/PickCategoryLine.cc
+++ b/PickCategoryLine.cc
@@ -91,7 +91,7 @@ PickCategoryLine::get_indent() const
 }
 
 const std::string
-PickCategoryLine::get_tooltip(int col_num) const
+PickCategoryLine::get_tooltip(int col_num, bool selected) const
 {
   return "";
 }
diff --git a/PickCategoryLine.h b/PickCategoryLine.h
index 7616b15..8352c36 100644
--- a/PickCategoryLine.h
+++ b/PickCategoryLine.h
@@ -36,7 +36,7 @@ public:
 
   const std::wstring get_text(int col) const;
   State get_state() const;
-  const std::string get_tooltip(int col) const;
+  const std::string get_tooltip(int col, bool selected) const;
   int get_indent() const;
   ActionList *get_actions(int col) const;
   int do_action(int col, int action_id);
diff --git a/PickPackageLine.cc b/PickPackageLine.cc
index c1e2a15..fd033e2 100644
--- a/PickPackageLine.cc
+++ b/PickPackageLine.cc
@@ -16,6 +16,7 @@
 #include "PickPackageLine.h"
 #include "PickView.h"
 #include "package_db.h"
+#include "resource.h"
 
 const std::wstring
 PickPackageLine::get_text(int col_num) const
@@ -86,9 +87,13 @@ PickPackageLine::get_text(int col_num) const
 }
 
 const std::string
-PickPackageLine::get_tooltip(int col_num) const
+PickPackageLine::get_tooltip(int col_num, bool selected) const
 {
-  if (col_num == pkg_col)
+  if (col_num == new_col && selected)
+{
+  return wstring_to_string(LoadStringW(IDS_CTRL_IRU_TOOLTIP));
+}
+  else if (col_num == pkg_col)
 {
   return pkg.LDesc();
 }
diff --git a/PickPackageLine.h b/PickPackageLine.h
index 0bf4ae6..f882ac8 100644
--- a/PickPackageLine.h
+++ b/PickPackageLine.h
@@ -32,7 +32,7 @@ public:
   };
   const std::wstring get_text(int col) const;
   State get_state() const { return State::nothing; }
-  const std::string get_tooltip(int col) const;
+  const std::string get_tooltip(int col, bool selected) const;
   int get_indent() const;
   ActionList *get_actions(int col_num) const;
   int do_action(int col, int action_id);
diff --git a/res/en/res.rc b/res/en/res.rc
index ef5e8b1..9b3288d 100644
--- a/res/en/res.rc
+++ b/res/en/res.rc
@@ -653,6 +653,7 @@ BEGIN
 IDS_CONFIRM_SOURCE "(source)"
 IDS_FILE_INUSE_KILL " Processes"
 IDS_FILE_INUSE_MSG "Unable to extract"
+IDS_CTRL_IRU_TOOLTIP "Ctrl+I: Install, Ctrl+R: Reinstall, Ctrl+U: 
Uninstall"
 END
 
 //
diff --git a/res/fr/res.rc b/res/fr/res.rc
index 747e1dd..b6d2f6d 100644
--- a/res/fr/res.rc
+++ b/res/fr/res.rc
@@ -633,6 +633,7 @@ BEGIN
 IDS_CONFIRM_SOURCE "(source)"
 IDS_FILE_INUSE_KILL " les processus"
 IDS_FILE_INUSE_MSG "Incapable d'extraire"
+// IDS_CTRL_IRU_TOOLTIP "XXX: missing translation"
 END
 
 //
diff --git a/resource.h b/resource.h
index cfe860b..4b636d2 100644
--- a/resource.h
+++ b/resource.h
@@ -107,6 +107,7 @@
 #define IDS_DEPRECATED_WINDOWS_ARCH  1210
 #define IDS_VIEW_REMOVABL

Re: [PATCH setup] Add new option --chown-admin

2022-10-04 Thread Christian Franke

Jon Turney wrote:

On 02/09/2022 16:17, Christian Franke wrote:

Jon Turney wrote:

On 28/08/2022 18:33, Christian Franke wrote:
As the 'root_scope' issues are now fixed, here a reworked and 
enhanced (checkbox, setup.rc entry) version of the original patch 
from this thread.


With the new setting enabled, setup behaves like other install 
tools when run elevated: The installation is then also protected 
against accidental modifications by the current user.


owner:group assignments of newly installed dirs/files:

adm:adm -- "All Users", "[X] Change owner of newly installed files 
to local Administrator"

usr:adm -- "All Users"
usr:def -- "Just Me"

(usr = user running setup, adm = S-1-5-32-544, def = S-1-5-21-*-513)



Thanks.  When writing the change summary for the last RC, I wondered 
what the file owner should be.


I guess my question is, if adm:adm ownership is correct, and 
expected for consistency with other Windows installers, why not make 
that the default? and then do we really need to provide the current 
behaviour as an option, if it's "wrong".


Two good questions. I'm not sure.


Well, perhaps we can explore that by asking what is the motivation for 
this change?  Does the current situation cause you a problem? Is is it 
just motivated by the concern that the user running setup could 
accidentally modify the installation, or something else?


If "All Users" is selected, the installation should IMO be protected 
against the same user if not elevated. This is automatically the case 
for other installers because Windows sets TokenOwner=Administrator if 
elevated.





Corinna had some concerns about making the owner a group, rather than 
a user, which I believe historically caused some difficulties in 
Cygwin, so I think I'll need to understand that better before making a 
decision about this change.


I see. Do you have any info about these difficulties?
Are these still relevant? If yes, let's forget this patch.



Re: [Bug] setup regression

2022-10-04 Thread Christian Franke

Jon Turney wrote:

On 27/09/2022 14:51, Christian Franke wrote:

Christian Franke wrote:

...
I made the false assumption that default_version=empty in 
set_action() always implies that the default version is not 
accessible. This is not the case for packages selected for 
installation before chooser is visible.


I'm working on a new fix for the "Ctrl+I pressed but current version 
is not accessible" case. ...


See attached patch. It also fixes the same problem for the "Category" 
view. Testing shows that the problem only affects the display of the 
version number as the solver later silently removes such install 
requests.



The correct logic is already in toggle_action(): Install the most 
recent accessible non-test ('naively_preferred') version.




I dropped this idea and aligned Ctrl+I behavior with "Install" from 
"Category" view instead. Toggle_action() behaves different in such 
corner cases as it always installs something.


Thanks, I applied both patches.

Do you have a simple way of causing a non-accessible package for 
testing with?


Unfortunately there is only a simple one if the current installation and 
cache directory matches some conditions. The "Ignore install requests if 
version is not accessible" case appears if:


- "Install from Local Directory" is selected.
- A previous version of a no longer installed package is still in the 
cache directory. Otherwise the package would not appear in the chooser.
- The current version of this package is not in the cache directory. The 
"Size" column shows "?" for such packages.


Without commit 63a2c90, Ctrl+I or "Install" from "Category" view shows 
an empty version in "New" column. The "Install" from "Category" case 
could also be reproduced with setup 2.919.


With this commit, the Install request does nothing.



Re: [Bug] setup regression

2022-09-27 Thread Christian Franke

Christian Franke wrote:

...
I made the false assumption that default_version=empty in set_action() 
always implies that the default version is not accessible. This is not 
the case for packages selected for installation before chooser is 
visible.


I'm working on a new fix for the "Ctrl+I pressed but current version 
is not accessible" case. ...


See attached patch. It also fixes the same problem for the "Category" 
view. Testing shows that the problem only affects the display of the 
version number as the solver later silently removes such install requests.



The correct logic is already in toggle_action(): Install the most 
recent accessible non-test ('naively_preferred') version.




I dropped this idea and aligned Ctrl+I behavior with "Install" from 
"Category" view instead. Toggle_action() behaves different in such 
corner cases as it always installs something.


From 7e1efd346e35898e3486fb84cf25b3885a2a16ec Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Tue, 27 Sep 2022 15:41:06 +0200
Subject: [PATCH] Ignore install requests if version is not accessible

This avoids that an empty "New" version is shown when install is
requested via "Install" from "Category" view or Ctrl+I and the
version is not accessible.
---
 package_meta.cc | 12 
 1 file changed, 12 insertions(+)

diff --git a/package_meta.cc b/package_meta.cc
index 05b8946..ebfc947 100644
--- a/package_meta.cc
+++ b/package_meta.cc
@@ -539,6 +539,17 @@ packagemeta::select_action (int id, trusts const deftrust)
 {
   if (id == packagemeta::NoChange_action)
 set_action((packagemeta::_actions)id, installed);
+  else if (id == Install_action)
+   {
+ // Ignore install request if the default version is not accessible.
+ // This assumes that all available versions are already known.
+ // This is not always the case when set_action is called directly.
+ packageversion v = trustp (true, deftrust);
+ if (v.accessible ())
+   set_action(Install_action, v, true);
+ else
+   set_action(NoChange_action, installed);
+   }
   else
 set_action((packagemeta::_actions)id, trustp (true, deftrust), true);
 }
@@ -627,6 +638,7 @@ packagemeta::set_action (_actions action, packageversion 
const _version,
   else if (action == Install_action)
 {
   desired = default_version;
+  // If desired is empty, it will be set to the solver's preferred version 
later.
   if (desired)
{
  if (desired != installed)
-- 
2.37.2



Re: [Bug] setup regression

2022-09-26 Thread Christian Franke

Jon Turney wrote:

On 22/09/2022 17:56, Achim Gratz wrote:

Achim Gratz writes:

Achim Gratz writes:
I had updated setup to 2.921 recently, so I rolled it back to 2.920 
and
this version does the package selection correctly.  I haven't yet 
looked
what commit is responsible, but whatever the cause of the 
regression is

still in 2.922 as well.


The most likely change responsible for this is the additions in
package_meta.cc in commit c99e4c14911181636892355a4f1855024051ea1d.  I
might not be able to check this tomorrow, though I'll try to free up
some time for that.


That was indeed the culprit.  I've reverted just these two hunks on top
of release_2.922 and things worked again.



Yes, looking again at that change, the first hunk in package_meta.cc, 
changing Install_action doesn't look right.


Indeed and this should be removed ASAP - patch attached.

Thanks for catching and sorry for the regression.




If I remember correctly action=Install_action, desired=empty package 
version (evaluating as a boolean is false) means "install the solver's 
preferred version", so converting that to NoChange_action seems wrong.


I'm kind of confused how to reproduce this, or why it decided to 
install only some things, rather than nothing.


Christian,

From your reply to 
https://cygwin.com/pipermail/cygwin-apps/2022-August/042212.html, it 
seems this change is meant to handle the case where 'I' is pressed but 
the package isn't accessible?  Although I don't seem quite how.


I made the false assumption that default_version=empty in set_action() 
always implies that the default version is not accessible. This is not 
the case for packages selected for installation before chooser is visible.


I'm working on a new fix for the "Ctrl+I pressed but current version is 
not accessible" case. The correct logic is already in toggle_action(): 
Install the most recent accessible non-test ('naively_preferred') version.


From 54665f0596f8ca50eff99ec8ec35970dc5fd439d Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Mon, 26 Sep 2022 16:47:42 +0200
Subject: [PATCH] Fix ignored install requests added before run of solver

Regression was introduced by commit c99e4c1.
---
 package_meta.cc | 7 ---
 1 file changed, 7 deletions(-)

diff --git a/package_meta.cc b/package_meta.cc
index a5dc436..05b8946 100644
--- a/package_meta.cc
+++ b/package_meta.cc
@@ -651,13 +651,6 @@ packagemeta::set_action (_actions action, packageversion 
const _version,
  srcpick (false);
}
}
-  else
-   {
- action = NoChange_action;
- desired = installed;
- pick (false);
- srcpick (false);
-   }
 }
   else if (action == Reinstall_action)
 {
-- 
2.37.2



Re: [PATCH setup] Add new option --chown-admin

2022-09-02 Thread Christian Franke

Jon Turney wrote:

On 28/08/2022 18:33, Christian Franke wrote:
As the 'root_scope' issues are now fixed, here a reworked and 
enhanced (checkbox, setup.rc entry) version of the original patch 
from this thread.


With the new setting enabled, setup behaves like other install tools 
when run elevated: The installation is then also protected against 
accidental modifications by the current user.


owner:group assignments of newly installed dirs/files:

adm:adm -- "All Users", "[X] Change owner of newly installed files to 
local Administrator"

usr:adm -- "All Users"
usr:def -- "Just Me"

(usr = user running setup, adm = S-1-5-32-544, def = S-1-5-21-*-513)



Thanks.  When writing the change summary for the last RC, I wondered 
what the file owner should be.


I guess my question is, if adm:adm ownership is correct, and expected 
for consistency with other Windows installers, why not make that the 
default? and then do we really need to provide the current behaviour 
as an option, if it's "wrong".


Two good questions. I'm not sure.




An alternative for the UI would be a 3rd radio button ("All Users - 
change owner of newly installed files to local Administrator"), but 
the checkbox makes this addition IMO more obvious.


The new setup.rc setting 'root-scope' is only used to read the 
chown_admin setting but this could be enhanced, e.g. warn user if 
root_scope selection differs from previous setup run.


The drawback that files generated by postinstall scripts are still 
owned by current user could be fixed with a perpetual postinstall 
script. I could provide one for base-files package if desired.


Doesn't this mean that we are using the wrong user-context to run 
those scripts?




The correct user context for running the script would be an equivalent 
to 'sudo administrator' which is not possible.


A change or addition (environment CYGWIN=chown_admin) in the Cygwin DLL 
would help: If launched with TokenOwner = Administrator, make sure that 
all newly created dirs/files are owned by TokenOwner instead of current 
user.




Re: [PATCH setup] Add new option --chown-admin

2022-08-28 Thread Christian Franke
As the 'root_scope' issues are now fixed, here a reworked and enhanced 
(checkbox, setup.rc entry) version of the original patch from this thread.


With the new setting enabled, setup behaves like other install tools 
when run elevated: The installation is then also protected against 
accidental modifications by the current user.


owner:group assignments of newly installed dirs/files:

adm:adm -- "All Users", "[X] Change owner of newly installed files to 
local Administrator"

usr:adm -- "All Users"
usr:def -- "Just Me"

(usr = user running setup, adm = S-1-5-32-544, def = S-1-5-21-*-513)

An alternative for the UI would be a 3rd radio button ("All Users - 
change owner of newly installed files to local Administrator"), but the 
checkbox makes this addition IMO more obvious.


The new setup.rc setting 'root-scope' is only used to read the 
chown_admin setting but this could be enhanced, e.g. warn user if 
root_scope selection differs from previous setup run.


The drawback that files generated by postinstall scripts are still owned 
by current user could be fixed with a perpetual postinstall script. I 
could provide one for base-files package if desired.


--
Regards,
Christian

From 6d996b377b4a6a908fbb4c217bda24249b4b58c1 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Sun, 28 Aug 2022 19:23:44 +0200
Subject: [PATCH] Optionally change owner of installed files to local
 administrator

Could be selected via new checkbox in Root dialog or via new option
--chown-admin.  This choice and the root_scope are stored in new
setup.rc entry 'root-scope'.
---
 res/en/res.rc |  6 +-
 res/fr/res.rc |  6 +-
 resource.h|  2 ++
 root.cc   | 45 -
 win32.cc  | 33 -
 win32.h   |  2 ++
 6 files changed, 78 insertions(+), 16 deletions(-)

diff --git a/res/en/res.rc b/res/en/res.rc
index ef5e8b1..74d3d0c 100644
--- a/res/en/res.rc
+++ b/res/en/res.rc
@@ -108,7 +108,10 @@ BEGIN
 CONTROL "Just ",IDC_ROOT_USER,"Button",BS_AUTORADIOBUTTON | 
 WS_TABSTOP,13,130,130,8
 LTEXT   "Cygwin will be available to all users of the system.",
-IDC_ALLUSERS_TEXT,25,101,300,28
+IDC_ALLUSERS_TEXT,25,100,300,28
+CONTROL " owner of newly installed files to local 
Administrator",
+IDC_ROOT_CHOWN_ADMIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+25,111,300,16
 LTEXT   "Cygwin will still be available to all users, but "
 "Desktop Icons, Cygwin Menu Entries, and important "
 "Installer information are only available to the current "
@@ -668,6 +671,7 @@ BEGIN
 IDS_HELPTEXT_ALLOW_UNSUPPORTED_WINDOWS "Allow old, unsupported Windows 
versions"
 IDS_HELPTEXT_ARCH "Architecture to install (x86_64 or x86)"
 IDS_HELPTEXT_CATEGORIES "Specify categories to install"
+IDS_HELPTEXT_CHOWN_ADMIN "Change owner of newly installed files to local 
Administrator"
 IDS_HELPTEXT_COMPACTOS "Compress installed files with Compact OS 
(xpress4k, xpress8k, xpress16k, lzx)"
 IDS_HELPTEXT_DELETE_ORPHANS "Remove orphaned packages"
 IDS_HELPTEXT_DISABLE_ANTIVIRUS "Disable known or suspected buggy anti 
virus software packages during execution"
diff --git a/res/fr/res.rc b/res/fr/res.rc
index d081bb2..21ba8f9 100644
--- a/res/fr/res.rc
+++ b/res/fr/res.rc
@@ -102,7 +102,10 @@ BEGIN
 CONTROL "Juste ",IDC_ROOT_USER,"Button",BS_AUTORADIOBUTTON |
 WS_TABSTOP,13,130,130,8
 LTEXT   "Cygwin sera disponible pour tous les utilisateurs.",
-IDC_ALLUSERS_TEXT,25,101,300,28
+IDC_ALLUSERS_TEXT,25,100,300,28
+CONTROL " owner of newly installed files to local 
Administrator", // XXX: missing translation
+IDC_ROOT_CHOWN_ADMIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+25,111,300,16
 LTEXT   "Cygwin sera disponible pour tous les utilisateurs "
 "mais les icônes et les menus uniquement pour 
l'utilisateur "
 "en cours. Ne sélectionner que si vous n'avez pas les 
droits "
@@ -648,6 +651,7 @@ BEGIN
 IDS_HELPTEXT_ALLOW_UNSUPPORTED_WINDOWS "Autoriser les vieilles versions de 
Windows"
 IDS_HELPTEXT_ARCH "Architecture à installer (x86_64 ou x86)"
 IDS_HELPTEXT_CATEGORIES "Spécifie les catégories à installer"
+// IDS_HELPTEXT_CHOWN_ADMIN "XXX: missing translation"
 // IDS_HELPTEXT_COMPACTOS "XXX: missing translation"
 IDS_HELPTEXT_DELETE_ORPHANS "Su

Re: [PATCH setup] Add new option --chown-admin

2022-08-26 Thread Christian Franke

Jon Turney wrote:

On 23/08/2022 18:27, Christian Franke wrote:

Jon Turney wrote:

On 12/07/2022 13:50, Jon Turney wrote:

[Replying to the right list this time...]
On 09/07/2022 13:21, Christian Franke wrote:

[...]


The UserSettings ctor has a somewhat hidden side effect which sets 
root_scope correctly:


  UserSettings::UserSettings(...);
   open_settings("setup.rc", ...);
    io_stream::open("cygfile:///etc/setup/setup.rc", ...);
io_stream_cygfile::io_stream_cygfile("/etc/setup/setup.rc", ...);
  get_root_dir_now();
   read_mounts("");
    read_mounts_nt("");
 root_scope = isuser ? IDC_ROOT_USER : IDC_ROOT_SYSTEM;

Conclusion: Regression introduced Feb 24, 2012 (befc9dd).



Thanks for tracking this down.

That just seems... fractally wrong.


I kind of lost track of this.  Is there anything else needed to fix 
the original problem here?  Or is it solved by the change to defer 
setting the group until after root_scope is known?


The group seems to be correctly set now.

An old problem still remains: root_scope always ends up as 
IDC_ROOT_SYSTEM if setup is run elevated, regardless off GUI setting. 
Apply the temporary patch from here to see what happens:

https://sourceware.org/pipermail/cygwin-apps/2022-July/042151.html


Ah, right, I remember now.

I think having read_mounts() have a side effect of setting root_scope 
is just nonsense now (it might have made some sense back in the day 
when the mount table was also stored in the registry).


So, how about the attached?

(We should perhaps also set the installation root directory to 
something other than C:\cygwin64 if a non-admin user, since they are 
unlikely to be able to write there in current windows versions, but 
that's difficult from a sequencing point of view in that dialog, and 
for backwards compatibility)


Possibly difficult to fix, in particular in conjunction with later 
changes via [< Back] button. An easier approach: Remove the GUI 
setting and connect root_scope to -B option.


Looking for that option is not correct, because we might be running 
without -B, but from an already elevated shell.  I think checking 
nt_sec.isRunAsAdmin() would be the correct test.


Did some quick tests with patch applied. LGTM.



Re: [PATCH setup] Add new option --chown-admin

2022-08-23 Thread Christian Franke

Jon Turney wrote:

On 12/07/2022 13:50, Jon Turney wrote:

[Replying to the right list this time...]
On 09/07/2022 13:21, Christian Franke wrote:

[...]


The UserSettings ctor has a somewhat hidden side effect which sets 
root_scope correctly:


  UserSettings::UserSettings(...);
   open_settings("setup.rc", ...);
    io_stream::open("cygfile:///etc/setup/setup.rc", ...);
io_stream_cygfile::io_stream_cygfile("/etc/setup/setup.rc", ...);
  get_root_dir_now();
   read_mounts("");
    read_mounts_nt("");
 root_scope = isuser ? IDC_ROOT_USER : IDC_ROOT_SYSTEM;

Conclusion: Regression introduced Feb 24, 2012 (befc9dd).



Thanks for tracking this down.

That just seems... fractally wrong.


I kind of lost track of this.  Is there anything else needed to fix 
the original problem here?  Or is it solved by the change to defer 
setting the group until after root_scope is known?





The group seems to be correctly set now.

An old problem still remains: root_scope always ends up as 
IDC_ROOT_SYSTEM if setup is run elevated, regardless off GUI setting. 
Apply the temporary patch from here to see what happens:

https://sourceware.org/pipermail/cygwin-apps/2022-July/042151.html

Possibly difficult to fix, in particular in conjunction with later 
changes via [< Back] button. An easier approach: Remove the GUI setting 
and connect root_scope to -B option.




Re: [PATCH setup] Keyboard accelerators for install/reinstall/uninstall

2022-08-23 Thread Christian Franke

Jon Turney wrote:

On 22/08/2022 16:29, Christian Franke wrote:

Jon Turney wrote:

On 14/08/2022 12:57, Christian Franke wrote:

This eases state changes of a selected sequence of packages.


Nice!  The keyboard control of the package chooser was a bit of an 
after-thought, which it really shouldn't be.


Thanks - revised patch is attached.



Thanks.  This looks good.  Please apply.


Thanks. Applied.




Ctrl+U is in particular useful to cleanup installations in 
conjunction with "unneeded" view:

https://sourceware.org/pipermail/cygwin-apps/2022-August/042185.html

Open issue: Add some visual clue (tooltip?) to make this 
functionality more obvious.


Yeah.  These shortcuts should also be accelerators for the package 
action selection popup menu, which would make them more discoverable?


Handling these in the popup menu is possibly tricky. According to 
documentation of TrackPopupMenu(), hWndListView "receives all 
messages from the menu" which is apparently not the case.


Confused. I don't think that matters (we could probably be using 
TPM_NONOTIFY), because we use TPM_RETURNCMD.


If we mark accelerators in the menu:

--- a/res/en/res.rc
+++ b/res/en/res.rc
@@ -573,11 +573,11 @@ BEGIN
 IDS_PROGRESS_POSTINSTALL "Running..."
 IDS_PROGRESS_SOLVING "Solving dependencies..."
 IDS_ACTION_DEFAULT "Default"
-    IDS_ACTION_INSTALL "Install"
-    IDS_ACTION_UNINSTALL "Uninstall"
+    IDS_ACTION_INSTALL ""
+    IDS_ACTION_UNINSTALL ""
 IDS_ACTION_SKIP "Skip"
 IDS_ACTION_KEEP "Keep"
-    IDS_ACTION_REINSTALL "Reinstall"
+    IDS_ACTION_REINSTALL ""
 IDS_ACTION_RETRIEVE "Retrieve"
 IDS_ACTION_UNKNOWN "Unknown"
 IDS_ACTION_SOURCE "Source"

They appear when the menu is opened by pressing the menu key (or 
always, if "Underline access keys when available" is on in 
ease-of-access settings), and menu items can be chosen using them.


It's not quite that straightforward because we need to remove the '&' 
when those strings are used elsewhere (e.g. in the action column), but 
I think it can be done...


Using plain letters (without Ctrl) or first digit of version number 
already work in the popup menu. But it is possibly tricky to also 
interpret Ctrl+I/R/U in the popup menu.





@@ -670,6 +670,10 @@ packagemeta::set_action (_actions action, 
packageversion const _version,

    else if (action == Uninstall_action)
  {
    desired = packageversion ();
+  pick (false);
+  srcpick (false);
+  if (!installed)
+    action = NoChange_action;


Hmm... why is adding this needed?


Otherwise a strange state change would occur at least in the GUI when 
an install request is undone:


"Skip" == Ctrl+I ==> "3.2-1" == Ctrl+U ==> "Uninstall"

The new patch includes another addition which prevents this on 
installs from local directory when the current default version is not 
yet downloaded:


"Skip" == Ctrl+I ==> "" (empty)


I see.  But these work correctly when chosen via the action menu dropdown?


These state changes are not offered by the popup menu. For example for 
not installed packages the popup menu does not contain a selection which 
returns Uninstall_action. Undoing an install request is done via 
re-selection of "Skip" which returns NoChange_action.


The design alternatives were either to emulate this in 
PickPackageLine::map_key_to_action() or to complete the (hidden) state 
machine in packagemeta::set_action(). I decided to use the latter.




Re: [PATCH setup] Keyboard accelerators for install/reinstall/uninstall

2022-08-22 Thread Christian Franke

Jon Turney wrote:

On 14/08/2022 12:57, Christian Franke wrote:

This eases state changes of a selected sequence of packages.


Nice!  The keyboard control of the package chooser was a bit of an 
after-thought, which it really shouldn't be.


Thanks - revised patch is attached.




Ctrl+U is in particular useful to cleanup installations in 
conjunction with "unneeded" view:

https://sourceware.org/pipermail/cygwin-apps/2022-August/042185.html

Open issue: Add some visual clue (tooltip?) to make this 
functionality more obvious.


Yeah.  These shortcuts should also be accelerators for the package 
action selection popup menu, which would make them more discoverable?


Handling these in the popup menu is possibly tricky. According to 
documentation of TrackPopupMenu(), hWndListView "receives all messages 
from the menu" which is apparently not the case.




...
+  bool down = false;
+  if 
((*contents)[iRow]->map_key_to_action(pNmLvKeyDown->wVKey, ctrl, alt, 
_num,

+ _id, ))
  {
    int update;
    if (action_id >= 0)
@@ -591,6 +597,13 @@ ListView::OnNotify (NMHDR *pNmHdr, LRESULT 
*pResult)

    if (update > 0)
  ListView_RedrawItems(hWndListView, iRow, iRow + 
update -1);

  }
+  if (down && iRow + 1 < ListView_GetItemCount(hWndListView)) {


Again as a stylistic thing, I'd suggest perhaps changing 
map_key_to_action() to return a set of flags which could include 
"ACTION", "POPUP" and "DOWN", rather than adding another flag 
parameter to it...


Done, see "enum Action".




+ ListView_SetItemState(hWndListView, -1, 0, LVIS_SELECTED | 
LVIS_FOCUSED);
+    ListView_SetItemState(hWndListView, iRow + 1, 
LVIS_SELECTED | LVIS_FOCUSED,

+  LVIS_SELECTED | LVIS_FOCUSED);
+    ListView_SetSelectionMark(hWndListView, iRow + 1);
+    ListView_EnsureVisible(hWndListView, iRow + 1, false);


A comment here saying "and move selection to next row".


Done.



...

  {
    switch (vkey)
  {
@@ -154,6 +155,20 @@ PickPackageLine::map_key_to_action(WORD vkey, 
int *col_num, int *action_id) cons

    *col_num = new_col;
    *action_id = -1;
    return true;
+    case 'I':
+    case 'R':
+    case 'U':
+  if (!(ctrl && !alt))


As a stylistic thing, I'd perhaps rather combine ctrl and alt flags as 
a modifier bitmap.


Done, see 'struct ModifierKeys'.




What is the reasoning for selecting the "ctrl but not alt" modifier 
state here?


Why should Ctrl+Alt+I have the same effect as Ctrl+I ?
The new patch also checks for shift.



...
@@ -670,6 +670,10 @@ packagemeta::set_action (_actions action, 
packageversion const _version,

    else if (action == Uninstall_action)
  {
    desired = packageversion ();
+  pick (false);
+  srcpick (false);
+  if (!installed)
+    action = NoChange_action;


Hmm... why is adding this needed?


Otherwise a strange state change would occur at least in the GUI when an 
install request is undone:


"Skip" == Ctrl+I ==> "3.2-1" == Ctrl+U ==> "Uninstall"

The new patch includes another addition which prevents this on installs 
from local directory when the current default version is not yet downloaded:


"Skip" == Ctrl+I ==> "" (empty)


BTW, I didn't understand this line:

  void
  packagemeta::set_action (...)
  {
    ...
    else if (action == Install_action)
  {
    desired = default_version;
    if (desired)
  {
    if (desired != installed)
  if (desired.accessible ())
    {
                  ...
  pick (true);
  srcpick (false);
    }
  else
    {
  pick (false);
      srcpick (true); <== why true? ==
    }
  ...

From 895f5510731bec0b161ba9b651b5a77dd8cb96a4 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Mon, 22 Aug 2022 16:39:21 +0200
Subject: [PATCH] Keyboard accelerators for install/reinstall/uninstall

Ctrl+I/R/U select install/reinstall/uninstall and then move selection
to next row.
---
 ListView.cc | 64 +++--
 ListView.h  | 10 ++-
 PickCategoryLine.cc | 21 +++
 PickCategoryLine.h  |  2 +-
 PickPackageLine.cc  | 27 ++-
 PickPackageLine.h   |  2 +-
 package_meta.cc | 11 
 7 files changed, 97 insertions(+), 40 deletions(-)

diff --git a/ListView.cc b/ListView.cc
index 62a37ab..7cc7f0f 100644
--- a/ListView.cc
+++ b/ListView.cc
@@ -24,6 +24,18 @@
 // ListView Common Control
 // ---
 
+int ModifierKeys::get()
+{
+  int keys = 0;
+  if (GetKeyState(VK_SHIFT) & 0x8000)
+   

Re: [PATCH setup] Add view mode "Unneeded"

2022-08-15 Thread Christian Franke

Jon Turney wrote:

On 02/08/2022 13:17, Christian Franke wrote:
In long standing cygwin installations, many no longer needed 
automatically installed packages (e.g. libicuNN) accumulate. This 
patch adds a new view which is possibly helpful to cleanup packages 
manually.


Some possible later enhancements:
- automatically refresh this view (a few seconds) after the user 
changed a package status as this may add or remove entries.
- add a keyboard shortcut (^U) to the list view for "Uninstall this 
package and then select next package"




Thanks.  This looks good.

I think perhaps a better approach would be a view showing all packages 
which aren't user_picked, or a dependency of a user_picked package.


This would drop the ability to easily clean up user_picked packages 
without later conflicts. The attached new patch splits this into two 
views "Removable" (not "Uninstallable" due to possible ambiguity with 
"cannot be installed") and "Unneeded" (or "Stale" ?).





(If I've read the code correctly your implementation has the weakness 
that if e.g. appA -> libbB -> libC, which is then changed to appA -> 
libD -> libE, it will only show libC as unneeded, then libB on the 
next run?)


I'm not sure for this case. It may be correct again after the view is 
refreshed during the same run. In general, this ad-hoc algorithm does 
not handle all corner cases. It should be sufficient if installation 
cleanup is done in a separate run.







+// Scan installed or desired packages and collect the names of packages
+// which provide the dependencies of other packages or are member of
+// category "Base".
+static void FindNeededPackages (const packagedb & db, 
std::set & needed)

+{
+  std::map providedBy;
+  for (const auto & p : db.packages)
+    {
+  const packagemeta & pkg = *p.second;
+  if (!pkg.isBinary ())
+    continue;
+  if (!(pkg.desired && (pkg.installed || pkg.picked (
+    continue;


This seems redundant.  Why can't this be just !pkg.desired?


Yes, fixed. I originally wanted to handle the "install source package 
without the binary" case here. During development of "Ctrl+I/R/U" patch, 
I learned that this could not happen.



This should also update the tooltip for the view dropdown 
(IDS_VIEWBUTTON_TOOLTIP) to describe the new view.




Done.

Open issue: An easy way to refresh the views after Uninstall requests 
(Ctrl+L ?).


From b31674d809a71bf17bb621c74e5ba7b3df3cd80a Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Mon, 15 Aug 2022 14:21:36 +0200
Subject: [PATCH] Add view modes "Removable" and "Unneeded"

These views show user picked or automatically installed packages which
could be safely removed.
---
 PickView.cc   | 53 ++-
 PickView.h|  2 ++
 res/en/res.rc | 12 +++-
 res/fr/res.rc |  4 
 resource.h|  2 ++
 5 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/PickView.cc b/PickView.cc
index c961b9f..7d60d8a 100644
--- a/PickView.cc
+++ b/PickView.cc
@@ -17,6 +17,7 @@
 #include "PickPackageLine.h"
 #include "PickCategoryLine.h"
 #include 
+#include 
 #include 
 #include 
 
@@ -28,6 +29,39 @@
 #include "LogSingleton.h"
 #include "Exception.h"
 
+// Scan desired packages and collect the names of packages which provide the
+// dependencies of other desired packages or are member of category "Base".
+static void FindNeededPackages (const packagedb & db, std::set & 
needed)
+{
+  std::map providedBy;
+  for (const auto & p : db.packages)
+{
+  const packagemeta & pkg = *p.second;
+  if (!pkg.isBinary ())
+continue;
+  if (!pkg.desired)
+continue;
+  for (const PackageSpecification *s : pkg.desired.provides ())
+providedBy.insert ({s->packageName (), pkg.name});
+}
+  for (const auto & p : db.packages)
+{
+  const packagemeta & pkg = *p.second;
+  if (!pkg.isBinary ())
+continue;
+  if (pkg.categories.count ("Base"))
+needed.insert (pkg.name);
+  if (!pkg.desired)
+continue;
+  for (const PackageSpecification *s : pkg.desired.depends ()) {
+const auto i = providedBy.find (s->packageName ());
+if (i == providedBy.end ())
+  continue;
+needed.insert (i->second);
+  }
+}
+}
+
 void
 PickView::setViewMode (views mode)
 {
@@ -47,6 +81,11 @@ PickView::setViewMode (views mode)
 }
   else
 {
+  std::set needed;
+  if (view_mode == PickView::views::PackageRemovable
+  || view_mode == PickView::views::PackageUnneeded)
+FindNeededPackages (db, needed);
+
   // iterate through every package
   for (packagedb::packagecollection::iterator i = db.packages.begin ();
  

[PATCH setup] Keyboard accelerators for install/reinstall/uninstall

2022-08-14 Thread Christian Franke

This eases state changes of a selected sequence of packages.

Ctrl+U is in particular useful to cleanup installations in conjunction 
with "unneeded" view:

https://sourceware.org/pipermail/cygwin-apps/2022-August/042185.html

Open issue: Add some visual clue (tooltip?) to make this functionality 
more obvious.


--
Regards,
Christian

From 71da4fbc68022b5083eba0cbdf2c0a4a541ddf1c Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Sun, 14 Aug 2022 13:43:48 +0200
Subject: [PATCH] Keyboard accelerators for install/reinstall/uninstall

Ctrl+I/R/U select install/reinstall/uninstall and then move selection
to next list item.
---
 ListView.cc | 17 +++--
 ListView.h  |  3 ++-
 PickCategoryLine.cc |  3 ++-
 PickCategoryLine.h  |  3 ++-
 PickPackageLine.cc  | 17 -
 PickPackageLine.h   |  3 ++-
 package_meta.cc |  4 
 7 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/ListView.cc b/ListView.cc
index 62a37ab..22009ba 100644
--- a/ListView.cc
+++ b/ListView.cc
@@ -564,14 +564,20 @@ ListView::OnNotify (NMHDR *pNmHdr, LRESULT *pResult)
   NMLVKEYDOWN *pNmLvKeyDown = (NMLVKEYDOWN *)pNmHdr;
   int iRow = ListView_GetSelectionMark(hWndListView);
 #if DEBUG
-  Log (LOG_PLAIN) << "LVN_KEYDOWN vkey " << pNmLvKeyDown->wVKey << " on 
row " << iRow << endLog;
+  Log (LOG_PLAIN) << "LVN_KEYDOWN vkey " << pNmLvKeyDown->wVKey << " on 
row " << iRow
+  << " Ctrl:" << !!(GetKeyState(VK_CONTROL) & 0x8000)
+  <<  " Alt:" << !!(GetKeyState(VK_MENU) & 0x8000) << 
endLog;
 #endif
 
   if (contents && iRow >= 0)
 {
+  bool ctrl = !!(GetKeyState(VK_CONTROL) & 0x8000);
+  bool alt = !!(GetKeyState(VK_MENU) & 0x8000);
   int col_num;
   int action_id;
-  if ((*contents)[iRow]->map_key_to_action(pNmLvKeyDown->wVKey, 
_num, _id))
+  bool down = false;
+  if ((*contents)[iRow]->map_key_to_action(pNmLvKeyDown->wVKey, ctrl, 
alt, _num,
+   _id, ))
 {
   int update;
   if (action_id >= 0)
@@ -591,6 +597,13 @@ ListView::OnNotify (NMHDR *pNmHdr, LRESULT *pResult)
   if (update > 0)
 ListView_RedrawItems(hWndListView, iRow, iRow + update -1);
 }
+  if (down && iRow + 1 < ListView_GetItemCount(hWndListView)) {
+ListView_SetItemState(hWndListView, -1, 0, LVIS_SELECTED | 
LVIS_FOCUSED);
+ListView_SetItemState(hWndListView, iRow + 1, LVIS_SELECTED | 
LVIS_FOCUSED,
+  LVIS_SELECTED | LVIS_FOCUSED);
+ListView_SetSelectionMark(hWndListView, iRow + 1);
+ListView_EnsureVisible(hWndListView, iRow + 1, false);
+  }
 }
 }
 break;
diff --git a/ListView.h b/ListView.h
index 95dd9ee..a2ecdef 100644
--- a/ListView.h
+++ b/ListView.h
@@ -38,7 +38,8 @@ class ListViewLine
   virtual ActionList *get_actions(int col) const = 0;
   virtual int do_action(int col, int id) = 0;
   virtual int do_default_action(int col) = 0;
-  virtual bool map_key_to_action(WORD vkey, int *col_num, int *action_id) 
const = 0;
+  virtual bool map_key_to_action(WORD vkey, bool ctrl, bool alt, int *col_num,
+ int *action_id, bool *down) const = 0;
 };
 
 typedef std::vector ListViewContents;
diff --git a/PickCategoryLine.cc b/PickCategoryLine.cc
index d2ac899..9872a2e 100644
--- a/PickCategoryLine.cc
+++ b/PickCategoryLine.cc
@@ -97,7 +97,8 @@ PickCategoryLine::get_tooltip(int col_num) const
 }
 
 bool
-PickCategoryLine::map_key_to_action(WORD vkey, int *col_num, int *action_id) 
const
+PickCategoryLine::map_key_to_action(WORD vkey, bool ctrl, bool alt, int 
*col_num,
+int *action_id, bool *down) const
 {
   switch (vkey)
 {
diff --git a/PickCategoryLine.h b/PickCategoryLine.h
index 6a7321d..0bfba33 100644
--- a/PickCategoryLine.h
+++ b/PickCategoryLine.h
@@ -41,7 +41,8 @@ public:
   ActionList *get_actions(int col) const;
   int do_action(int col, int action_id);
   int do_default_action(int col);
-  bool map_key_to_action(WORD vkey, int *col_num, int *action_id) const;
+  bool map_key_to_action(WORD vkey, bool ctrl, bool alt, int *col_num,
+ int *action_id, bool *down) const;
 
 private:
   CategoryTree * cat_tree;
diff --git a/PickPackageLine.cc b/PickPackageLine.cc
index ae1e520..ba47e1f 100644
--- a/PickPackageLine.cc
+++ b/PickPackageLine.cc
@@ -145,7 +145,8 @@ PickPackageLine::get_indent() const
 }
 
 bool
-PickPackageLine::map_key_to_action(WORD vkey, int *col_num, int *action_id) 
const
+PickPackageLine::map_key_to_action(WORD vkey, bool ctrl, bool alt

[PATCH setup] Add view mode "Unneeded"

2022-08-02 Thread Christian Franke
In long standing cygwin installations, many no longer needed 
automatically installed packages (e.g. libicuNN) accumulate. This patch 
adds a new view which is possibly helpful to cleanup packages manually.


Some possible later enhancements:
- automatically refresh this view (a few seconds) after the user changed 
a package status as this may add or remove entries.
- add a keyboard shortcut (^U) to the list view for "Uninstall this 
package and then select next package"


--
Regards,
Christian

From 07a2e561b7ba19817a0bebb2cbf542a9b18a6d4e Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Tue, 2 Aug 2022 13:54:30 +0200
Subject: [PATCH] Add view mode "Unneeded"

This view shows installed packages which could be safely removed.
---
 PickView.cc   | 47 ++-
 PickView.h|  1 +
 res/en/res.rc |  1 +
 res/fr/res.rc |  1 +
 resource.h|  1 +
 5 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/PickView.cc b/PickView.cc
index c961b9f..b7a37b5 100644
--- a/PickView.cc
+++ b/PickView.cc
@@ -17,6 +17,7 @@
 #include "PickPackageLine.h"
 #include "PickCategoryLine.h"
 #include 
+#include 
 #include 
 #include 
 
@@ -28,6 +29,40 @@
 #include "LogSingleton.h"
 #include "Exception.h"
 
+// Scan installed or desired packages and collect the names of packages
+// which provide the dependencies of other packages or are member of
+// category "Base".
+static void FindNeededPackages (const packagedb & db, std::set & 
needed)
+{
+  std::map providedBy;
+  for (const auto & p : db.packages)
+{
+  const packagemeta & pkg = *p.second;
+  if (!pkg.isBinary ())
+continue;
+  if (!(pkg.desired && (pkg.installed || pkg.picked (
+continue;
+  for (const PackageSpecification *s : pkg.desired.provides ())
+providedBy.insert ({s->packageName (), pkg.name});
+}
+  for (const auto & p : db.packages)
+{
+  const packagemeta & pkg = *p.second;
+  if (!pkg.isBinary ())
+continue;
+  if (pkg.categories.count ("Base"))
+needed.insert (pkg.name);
+  if (!(pkg.desired && (pkg.installed || pkg.picked (
+continue;
+  for (const PackageSpecification *s : pkg.desired.depends ()) {
+const auto i = providedBy.find (s->packageName ());
+if (i == providedBy.end ())
+  continue;
+needed.insert (i->second);
+  }
+}
+}
+
 void
 PickView::setViewMode (views mode)
 {
@@ -47,6 +82,10 @@ PickView::setViewMode (views mode)
 }
   else
 {
+  std::set needed;
+  if (view_mode == PickView::views::PackageUnneeded)
+FindNeededPackages (db, needed);
+
   // iterate through every package
   for (packagedb::packagecollection::iterator i = db.packages.begin ();
 i != db.packages.end (); ++i)
@@ -77,7 +116,11 @@ PickView::setViewMode (views mode)
 
   // "UserPick" : installed packages that were picked by user
   || (view_mode == PickView::views::PackageUserPicked &&
-  (pkg.installed && pkg.user_picked)))
+  (pkg.installed && pkg.user_picked))
+
+  // "Unneeded" : installed packages which could be safely removed
+  || (view_mode == PickView::views::PackageUnneeded &&
+  (pkg.installed && !needed.count (pkg.name
 {
   // Filter by package name
   if (packageFilterString.empty ()
@@ -111,6 +154,8 @@ PickView::mode_caption (views mode)
   return IDS_VIEW_NOTINSTALLED;
 case views::PackageUserPicked:
   return IDS_VIEW_PICKED;
+case views::PackageUnneeded:
+  return IDS_VIEW_UNNEEDED;
 case views::Category:
   return IDS_VIEW_CATEGORY;
 default:
diff --git a/PickView.h b/PickView.h
index 1e14a74..f2dbfa9 100644
--- a/PickView.h
+++ b/PickView.h
@@ -36,6 +36,7 @@ public:
 PackageKeeps,
 PackageSkips,
 PackageUserPicked,
+PackageUnneeded,
 Category,
   };
 
diff --git a/res/en/res.rc b/res/en/res.rc
index 644b252..9517bb2 100644
--- a/res/en/res.rc
+++ b/res/en/res.rc
@@ -578,6 +578,7 @@ BEGIN
 IDS_VIEW_UPTODATE "Up To Date"
 IDS_VIEW_NOTINSTALLED "Not Installed"
 IDS_VIEW_PICKED "Picked"
+IDS_VIEW_UNNEEDED "Unneeded"
 IDS_VIEW_CATEGORY "Category"
 IDS_COLUMN_PACKAGE "Package"
 IDS_COLUMN_CURRENT "Current"
diff --git a/res/fr/res.rc b/res/fr/res.rc
index a0a7909..d787fdb 100644
--- a/res/fr/res.rc
+++ b/res/fr/res.rc
@@ -564,6 +564,7 @@ BEGIN
 IDS_VIEW_UPTODATE "À jour"
 IDS_VIEW_NOTINSTALLED "Non installé"
 IDS_VIEW_PICKED "Sélectionné"
+// IDS_VIEW_UNNEEDED "XXX: missing translation"
 IDS_VIEW_CAT

[PATCH rebase] Print list of DLLs which still overlap after rebasing + Fix index ...

2022-07-19 Thread Christian Franke

Corinna Vinschen wrote:
> ...
> Pushed.  Do you have a few more changes in the loop?  When you're
> finished, I'll release a new rebase.

The attached 0001-*.patch is the last one in the loop - I guessed. But 
during testing this I found the long standing bug fixed in 0002-*.patch.


That's all for now.

Thanks,
Christian

From c6e050fa69552e023d18df2cf1255a2a827f1bcc Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Tue, 19 Jul 2022 10:36:20 +0200
Subject: [PATCH 1/2] Print list of DLLs which still overlap after rebasing

---
 rebase.c | 38 ++
 1 file changed, 38 insertions(+)

diff --git a/rebase.c b/rebase.c
index 1f9f74b..8ca65cc 100644
--- a/rebase.c
+++ b/rebase.c
@@ -47,6 +47,7 @@ BOOL load_image_info ();
 BOOL merge_image_info ();
 BOOL collect_image_info (const char *pathname);
 void print_image_info ();
+static void print_overlapped ();
 BOOL rebase (const char *pathname, ULONG64 *new_image_base, BOOL down_flag);
 void parse_args (int argc, char *argv[]);
 unsigned long long string_to_ulonglong (const char *string);
@@ -323,6 +324,10 @@ main (int argc, char *argv[])
  }
fprintf (stderr, "  %s\n", img_info_list[i].name);
  }
+  /* Print list of DLLs which still overlap.  This could occur if DLLs are
+not rebaseable or if --merge-files is used incorrectly. */
+  if (img_info_size)
+   print_overlapped ();
   if (save_image_info () < 0)
return 2;
 }
@@ -1149,6 +1154,39 @@ print_image_info ()
 }
 }
 
+static void
+print_overlapped ()
+{
+  BOOL header;
+  int i;
+  char overlaps[img_info_size];
+  memset (overlaps, 0, img_info_size);
+  qsort (img_info_list, img_info_size, sizeof (img_info_t), img_info_cmp);
+  for (header = FALSE, i = 0; i < img_info_size; ++i)
+{
+  int j;
+  if (img_info_list[i].flag.needs_rebasing)
+   continue; /* Rebase failed. */
+  for (j = i + 1; j < img_info_size; ++j)
+   {
+ if (img_info_list[j].flag.needs_rebasing)
+   continue; /* Rebase failed. */
+ if (img_info_list[i].base + img_info_list[i].slot_size + offset
+ <= img_info_list[j].base)
+   break;
+ overlaps[i] = overlaps[j] = 1;
+   }
+  if (!overlaps[i])
+   continue;
+  if (!header)
+   {
+ fputs ("\nThe following DLLs still overlap:\n", stderr);
+ header = TRUE;
+   }
+  fprintf (stderr, "  %s\n", img_info_list[i].name);
+}
+}
+
 BOOL
 rebase (const char *pathname, ULONG64 *new_image_base, BOOL down_flag)
 {
-- 
2.37.1

From d618ee13551b861699446f1eb0242f85a71006c6 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Tue, 19 Jul 2022 10:40:55 +0200
Subject: [PATCH 2/2] Fix index after removing missing DLL from list

---
 rebase.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/rebase.c b/rebase.c
index 8ca65cc..7417d4d 100644
--- a/rebase.c
+++ b/rebase.c
@@ -799,6 +799,7 @@ merge_image_info ()
  memmove (overlaps + i, overlaps + i + 1, img_info_size - i - 1);
  --img_info_rebase_start;
  --img_info_size;
+ --i;
  continue;
}
  slot_size = roundup2 (cur_size, ALLOCATION_SLOT);
-- 
2.37.1



Re: [PATCH rebase] Fix handling of newly added non-rebaseable DLLs

2022-07-18 Thread Christian Franke

Revised version which also handles the --oblivious case.

--
Regards,
Christian

From 19139e1b984eb3f4d11f83e6951c66064a2f2dd3 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Mon, 18 Jul 2022 17:06:05 +0200
Subject: [PATCH] Fix handling of newly added non-rebaseable DLLs

Reset needs_rebasing flag to avoid that such a DLL is later removed
from the list due to rebase failure.  Add related verbose messages.
---
 rebase.c | 18 +-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/rebase.c b/rebase.c
index 39759a9..1f9f74b 100644
--- a/rebase.c
+++ b/rebase.c
@@ -705,6 +705,17 @@ merge_image_info ()
  if (verbose)
fprintf (stderr, "rebasing %s because not in database yet\n", 
img_info_list[i].name);
}
+ else if (img_info_list[i].flag.needs_rebasing)
+   {
+ /* Not in database yet and not rebaseable.  Add without rebasing 
or
+skip if --oblivious is active. */
+ img_info_list[i].flag.needs_rebasing = 0;
+ if (verbose)
+   fprintf (stderr, "not rebasing %s because file is not 
writable\n",
+img_info_list[i].name);
+ /* FIXME: Overlaps of DLLs in the database with this DLL will
+not be detected below. */
+   }
}
 }
   if (!img_info_rebase_start || force_rebase_flag)
@@ -715,7 +726,12 @@ merge_image_info ()
{
  /* Test DLLs already in database for writability. */
  if (i < img_info_rebase_start)
-   set_cannot_rebase (_info_list[i]);
+   {
+ set_cannot_rebase (_info_list[i]);
+ if (img_info_list[i].flag.cannot_rebase == 1 && verbose)
+   fprintf (stderr, "not rebasing %s because file is not 
writable\n",
+img_info_list[i].name);
+   }
  if (!img_info_list[i].flag.cannot_rebase)
{
  img_info_list[i].base = 0;
-- 
2.37.1



[PATCH rebase] Fix handling of newly added non-rebaseable DLLs

2022-07-18 Thread Christian Franke

The current behavior in this (possibly rare) case is misleading.

--
Regards,
Christian

From 6a68800512ce80689efbf43e639e7c1f38371636 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Mon, 18 Jul 2022 16:07:26 +0200
Subject: [PATCH] Fix handling of newly added non-rebaseable DLLs

Reset needs_rebasing flag to avoid that such a DLL is later removed
from the list due to rebase failure.  Add related verbose messages.
---
 rebase.c | 17 -
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/rebase.c b/rebase.c
index 39759a9..56d743d 100644
--- a/rebase.c
+++ b/rebase.c
@@ -705,6 +705,16 @@ merge_image_info ()
  if (verbose)
fprintf (stderr, "rebasing %s because not in database yet\n", 
img_info_list[i].name);
}
+ else if (img_info_list[i].flag.cannot_rebase == 1)
+   {
+ /* Not in database yet and not rebaseable.  Add without rebasing. 
*/
+ img_info_list[i].flag.needs_rebasing = 0;
+ if (verbose)
+   fprintf (stderr, "adding %s without rebasing because file is 
not writable\n",
+img_info_list[i].name);
+ /* FIXME: Overlaps of DLLs in the database with this DLL will
+not be detected below. */
+   }
}
 }
   if (!img_info_rebase_start || force_rebase_flag)
@@ -715,7 +725,12 @@ merge_image_info ()
{
  /* Test DLLs already in database for writability. */
  if (i < img_info_rebase_start)
-   set_cannot_rebase (_info_list[i]);
+   {
+ set_cannot_rebase (_info_list[i]);
+ if (img_info_list[i].flag.cannot_rebase == 1 && verbose)
+   fprintf (stderr, "not rebasing %s because file is not 
writable\n",
+img_info_list[i].name);
+   }
  if (!img_info_list[i].flag.cannot_rebase)
{
  img_info_list[i].base = 0;
-- 
2.37.1



[PATCH rebase] Ensure that no rebaseable DLL overlaps a non-rebaseable DLL

2022-07-16 Thread Christian Franke
The current check for overlapping non-rebaseable DLLs uses a possible 
outdated base address. It also could not detect multiple overlaps by one 
non-rebaseable DLL.


Patch size may be misleading due to indentation change.

--
Regards,
Christian

From ee8a966cb6da48b45dfb6de3e732dade81ce7fb9 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Sat, 16 Jul 2022 17:55:58 +0200
Subject: [PATCH] Ensure that no rebaseable DLL overlaps a non-rebaseable DLL

Restart rebase decision loop with newly sorted list if a DLL is not
rebaseable.  Search for all DLLs which overlap such a DLL.
---
 rebase.c | 203 +--
 1 file changed, 121 insertions(+), 82 deletions(-)

diff --git a/rebase.c b/rebase.c
index 5cda123..39759a9 100644
--- a/rebase.c
+++ b/rebase.c
@@ -625,6 +625,7 @@ merge_image_info ()
 {
   int i, end;
   img_info_t *match;
+  BOOL sorted;
   ULONG64 floating_image_base;
 
   /* Sort new files from command line by name. */
@@ -725,91 +726,129 @@ merge_image_info ()
   img_info_rebase_start = 0;
 }
 
-  /* Now sort the old part of the list by base address. */
-  if (img_info_rebase_start)
-qsort (img_info_list, img_info_rebase_start, sizeof (img_info_t),
-  img_info_cmp);
-  /* Perform several tests on the information fetched from the database
- to match with reality. */
-  for (i = 0; i < img_info_rebase_start; ++i)
+  for (sorted = FALSE; img_info_rebase_start && !sorted; )
 {
-  ULONG64 cur_base, cur_base_orig;
-  ULONG cur_size, slot_size;
-
-  /* Files with the needs_rebasing or cannot_rebase flags set have been
-checked already. */
-  if (img_info_list[i].flag.needs_rebasing
- || img_info_list[i].flag.cannot_rebase)
-   continue;
-  /* Check if the files in the old list still exist.  Drop non-existant
-or unaccessible files. */
-  if (access (img_info_list[i].name, F_OK) == -1
- || !GetImageInfos64 (img_info_list[i].name, NULL,
-  _base, _size))
-   {
- free (img_info_list[i].name);
- memmove (img_info_list + i, img_info_list + i + 1,
-  (img_info_size - i - 1) * sizeof (img_info_t));
- --img_info_rebase_start;
- --img_info_size;
- continue;
-   }
-  slot_size = roundup2 (cur_size, ALLOCATION_SLOT);
-  cur_base_orig = cur_base;
-  /* If the file has been reinstalled, try to rebase to the same address
-in the first place. */
-  if (cur_base != img_info_list[i].base)
+  char overlaps[img_info_rebase_start];
+  memset(overlaps, 0, img_info_rebase_start);
+  /* Now sort the old part of the list by base address. */
+  qsort (img_info_list, img_info_rebase_start, sizeof (img_info_t),
+img_info_cmp);
+  /* Perform several tests on the information fetched from the database
+to match with reality. */
+  for (sorted = TRUE, i = 0; sorted && i < img_info_rebase_start; ++i)
{
- img_info_list[i].flag.needs_rebasing = 1;
- if (verbose)
-   fprintf (stderr, "rebasing %s because it's base has changed (due to 
being reinstalled?)\n", img_info_list[i].name);
- /* Set cur_base to the old base to simplify subsequent tests. */
- cur_base = img_info_list[i].base;
-   }
-  /* However, if the DLL got bigger and doesn't fit into its slot
-anymore, rebase this DLL from scratch. */
-  if (i + 1 < img_info_rebase_start
- && cur_base + slot_size + offset > img_info_list[i + 1].base)
-   {
- img_info_list[i].base = 0;
- if (verbose)
-   fprintf (stderr, "rebasing %s because it won't fit in it's old slot 
without overlapping next DLL\n", img_info_list[i].name);
-   }
-  /* Does the previous DLL reach into the address space of this
-DLL?  This happens if the previous DLL is not rebaseable. */
-  else if (i > 0 && cur_base < img_info_list[i - 1].base
-  + img_info_list[i - 1].slot_size)
-   {
- img_info_list[i].base = 0;
- if (verbose)
-   fprintf (stderr, "rebasing %s because previous DLL now overlaps\n", 
img_info_list[i].name);
-   }
-  /* Does the file match the base address requirements?  If not,
-rebase from scratch. */
-  else if ((down_flag && cur_base + slot_size + offset > image_base)
-  || (!down_flag && cur_base < image_base))
-   {
- img_info_list[i].base = 0;
- if (verbose)
-   fprintf (stderr, "rebasing %s because it's base address is outside 
the expected area\n", img_info_list[i].name);
-   }
-  /* Make sure all DLLs with base address 0 have the needs_rebasing
-flag set. */
-  if (img_info_list[i].base == 0)
-   img_info_list[i].flag.needs_r

Re: [PATCH setup 0/2] Simplify setting group ownership of installed files

2022-07-13 Thread Christian Franke

Jon Turney wrote:

Jon Turney (2):
   Drop group change while running postinstall scripts
   Defer setting group until after All Users/Just For Me is chosen

  main.cc|  2 +-
  postinstall.cc | 13 -
  root.cc|  5 +
  win32.cc   | 13 ++---
  win32.h|  2 +-
  5 files changed, 9 insertions(+), 26 deletions(-)



Works for me as expected. Primary group of dirs/files of "All Users" 
installed files are now local administrator (like before Feb 2012), 
including those generated by postinstall scripts (new behavior).


As already mentioned in the '--no-write-registry' thread, "Just me" 
installs only work with non-elevated user and '-B' option. Attached is a 
temporary patch I used to log changes of root_scope variable.


diff --git a/state.cc b/state.cc
index 111b890..b4e3410 100644
--- a/state.cc
+++ b/state.cc
@@ -24,7 +24,7 @@ int source;
 
 std::string local_dir;
 
-int root_scope;
+root_scope_holder root_scope;
 int root_menu;
 int root_desktop;
 
diff --git a/state.h b/state.h
index b211de3..c561ea5 100644
--- a/state.h
+++ b/state.h
@@ -32,6 +32,7 @@
  */
 
 #include 
+#include "LogSingleton.h"
 
 enum attend_mode { attended = 0, unattended, chooseronly };
 extern enum attend_mode unattended_mode;
@@ -42,7 +43,22 @@ extern int source;
 extern std::string local_dir;
 
 extern int root_text;
-extern int root_scope;
+
+class root_scope_holder
+{
+public:
+  void operator=(int v) {
+int old = val;
+val = v;
+Log(LOG_TIMESTAMP) << "root_scope: " << old << " -> " << v << endLog;
+  }
+  operator int() const { return val; }
+private:
+  int val = 0;
+};
+
+extern root_scope_holder root_scope;
+
 extern int root_menu;
 extern int root_desktop;
 


Re: [PATCH setup] Add new option --no-write-registry

2022-07-12 Thread Christian Franke

Jon Turney wrote:

On 09/07/2022 16:59, Christian Franke wrote:
IMO useful for temporary test installs or "portable" installs to USB 
devices.


The 0002-patch adds a related log message.


These patches are ok.

If you can provide a help-text for the new option, I will apply them.


Attached new version of 0001-... patch which includes a help text.
Does not include the *.po* changes, sorry ('pip install 
translate-toolkit' failed for some reason),


From 8a93babe4ef963de9fe1d2f5ba77ea9c89afa23c Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Tue, 12 Jul 2022 18:04:25 +0200
Subject: [PATCH] Add new option --no-write-registry

If specified, the rootdir is not written to the registry and no
registry key is created.
---
 install.cc| 6 --
 res/en/res.rc | 1 +
 res/fr/res.rc | 1 +
 resource.h| 1 +
 4 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/install.cc b/install.cc
index 1fdc699..fbd28b1 100644
--- a/install.cc
+++ b/install.cc
@@ -70,6 +70,7 @@ static long long int total_bytes_sofar = 0;
 static int package_bytes = 0;
 
 static BoolOption NoReplaceOnReboot (false, 'r', "no-replaceonreboot", 
IDS_HELPTEXT_NO_REPLACEONREBOOT);
+static BoolOption NoWriteRegistry (false, '\0', "no-write-registry", 
IDS_HELPTEXT_NO_WRITE_REGISTRY);
 
 struct std_dirs_t {
   const char *name;
@@ -833,8 +834,9 @@ do_install_thread (HINSTANCE h, HWND owner)
   int df = diskfull (get_root_dir ().c_str());
   Progress.SetBar3 (df);
 
-  /* Writes Cygwin/setup/rootdir registry value */
-  create_install_root ();
+  if (!NoWriteRegistry)
+/* Writes Cygwin/setup/rootdir registry value */
+create_install_root ();
 
   std::vector  install_q, uninstall_q, sourceinstall_q;
 
diff --git a/res/en/res.rc b/res/en/res.rc
index 9683ab5..644b252 100644
--- a/res/en/res.rc
+++ b/res/en/res.rc
@@ -679,6 +679,7 @@ BEGIN
 IDS_HELPTEXT_NO_VERIFY "Don't verify setup.ini signatures"
 IDS_HELPTEXT_NO_VERSION_CHECK "Suppress checking if a newer version of 
setup is available"
 IDS_HELPTEXT_NO_WARN_DEPRECATED_WINDOWS "Don't warn about deprecated 
Windows versions"
+IDS_HELPTEXT_NO_WRITE_REGISTRY "Don't write root installation directory to 
registry"
 IDS_HELPTEXT_OLD_KEYS "Enable old cygwin.com keys"
 IDS_HELPTEXT_ONLY_SITE "Do not download mirror list.  Only use sites 
specified with -s."
 IDS_HELPTEXT_PACKAGES "Specify packages to install"
diff --git a/res/fr/res.rc b/res/fr/res.rc
index 79f2371..a0a7909 100644
--- a/res/fr/res.rc
+++ b/res/fr/res.rc
@@ -665,6 +665,7 @@ BEGIN
 IDS_HELPTEXT_NO_VERIFY "Ne pas vérifier les signatures de setup.ini"
 IDS_HELPTEXT_NO_VERSION_CHECK "Ne pas vérifier si une version plus récente 
de l'assistant est disponible"
 IDS_HELPTEXT_NO_WARN_DEPRECATED_WINDOWS "Ne pas avertir pour les vieilles 
versions de Windows"
+// IDS_HELPTEXT_NO_WRITE_REGISTRY "XXX: missing translation"
 IDS_HELPTEXT_OLD_KEYS "Utiliser les anciennes clés de cygwin.com"
 IDS_HELPTEXT_ONLY_SITE "Ignorer tous les sites sauf ceux spécifiés par -s"
 IDS_HELPTEXT_PACKAGES "Spécifie les paquets à installer"
diff --git a/resource.h b/resource.h
index e8ed0fa..2668dd9 100644
--- a/resource.h
+++ b/resource.h
@@ -154,6 +154,7 @@
 #define IDS_HELPTEXT_ERROR   1545
 #define IDS_HELPTEXT_HEADER  1546
 #define IDS_HELPTEXT_FOOTER  1547
+#define IDS_HELPTEXT_NO_WRITE_REGISTRY   1548
 
 // Dialogs
 
-- 
2.37.0



[PATCH setup] Add new option --no-write-registry

2022-07-09 Thread Christian Franke
IMO useful for temporary test installs or "portable" installs to USB 
devices.


The 0002-patch adds a related log message.


BTW: During testing I found that the "All Users" <> "Just Me" GUI 
setting has no effect at all. If setup is run elevated, "All Users" is 
always implied.


This is likely because read_mounts() is called again after the "Root" 
dialog. It resets root_scope and does not re-read the registry.


read_mounts (const std::string val)
{
...
  root_scope = (nt_sec.isRunAsAdmin ())? IDC_ROOT_SYSTEM : IDC_ROOT_USER;
...
}

--
Regards,
Christian

From ab3c94ebf0e78606c3660bec8e0c04c6e6b8ddd4 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Sat, 9 Jul 2022 16:52:47 +0200
Subject: [PATCH 1/2] Add new option --no-write-registry

If specified, the rootdir is not written to the registry and no
registry key is created.
---
 install.cc | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/install.cc b/install.cc
index 1fdc699..eb7b1b2 100644
--- a/install.cc
+++ b/install.cc
@@ -70,6 +70,7 @@ static long long int total_bytes_sofar = 0;
 static int package_bytes = 0;
 
 static BoolOption NoReplaceOnReboot (false, 'r', "no-replaceonreboot", 
IDS_HELPTEXT_NO_REPLACEONREBOOT);
+static BoolOption NoWriteRegistry (false, '\0', "no-write-registry" /*, TODO: 
IDS_HELPTEXT_... */);
 
 struct std_dirs_t {
   const char *name;
@@ -833,8 +834,9 @@ do_install_thread (HINSTANCE h, HWND owner)
   int df = diskfull (get_root_dir ().c_str());
   Progress.SetBar3 (df);
 
-  /* Writes Cygwin/setup/rootdir registry value */
-  create_install_root ();
+  if (!NoWriteRegistry)
+/* Writes Cygwin/setup/rootdir registry value */
+create_install_root ();
 
   std::vector  install_q, uninstall_q, sourceinstall_q;
 
-- 
2.36.1

From 467b30e19e506ecb4b1e9ed9c4d7528d77db0228 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Sat, 9 Jul 2022 16:57:31 +0200
Subject: [PATCH 2/2] Log writes to rootdir registry entry

---
 mount.cc | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/mount.cc b/mount.cc
index f63edd4..0136396 100644
--- a/mount.cc
+++ b/mount.cc
@@ -135,6 +135,12 @@ create_install_root ()
 mbox (NULL, IDS_MOUNT_REGISTRY_KEY_FAILED, MB_OK | MB_ICONWARNING);
   RegCloseKey (key);
 
+  Log (LOG_TIMESTAMP) << "Registry value set: HKEY_"
+ << (root_scope == IDC_ROOT_USER ? "CURRENT_USER\\"
+ : "LOCAL_MACHINE\\")
+ << buf << "\\rootdir = \"" << get_root_dir () << "\""
+ << endLog;
+
   // The mount table is already in the right shape at this point.
   // Reading it again is not necessary.
   //read_mounts (std::string ());
-- 
2.36.1



Re: [PATCH setup] Add new option --chown-admin

2022-07-07 Thread Christian Franke

Christian Franke wrote:


It does fix the regression, it adds a new installation flavor which 
fixes it as a side effect.


It does *not* fix the regression, of course




Re: [PATCH setup] Add new option --chown-admin

2022-07-07 Thread Christian Franke

Jon Turney wrote:

On 06/07/2022 17:34, Christian Franke wrote:

Jon Turney wrote:

On 06/07/2022 08:14, Christian Franke wrote:
If an installer is run elevated, the installed files will be 
typically owned by the local administrator (or in some cases SYSTEM 
or TrustedInstaller) instead of the current user. This is not the 
case for a Cygwin "All Users" installation. The files are then not 
protected from 


... instead the files are owned by the user running setup?


Yes, because the TokenUser is unconditionally copied to TokenOwner. 
Some research with 'git blame' shows that many parts of the related 
code are from the early days of UAC and elevated processes (Vista 
2006, Win7 2009). Things may have changed since then, I don't know 
(or remember).


If a process is run elevated, Windows keeps TokenUser unchanged but 
sets the TokenOwner to local administrator. The --chown-admin option 
simply keeps this as is, so no actual chown() is needed later. The 
TokenPrimaryGroup is not changed by Windows, therefore --chown-admin 
calls setAdminGroup() to mimic the usual "root root" ownership.


Typical simple installers leave everything as is, so the installed 
files are owned by local adminstrator and group "None" 
(S-1-5-21-*-513), see 'ls -l "$PROGRAMFILES"'.




accidental changes by this user.

The attached patch adds an experimental --chown-admin option which 
allows (new) installations owned by local administrator user and 
group.


Thanks for the patch, but...

A drawback is that files generated by postinstall scripts are still 
owned by current user + "None" group. It should be possible to fix 
this with some perpetual preremove+postinstall scripts.


I also don't know whether this may break some postinstall scripts.

BTW: 'nt_sec.setDefaultSecurity (isAdmin)' is never called with 
'isAdmin==true' as 'root_scope' is always 0.


root_scope is set later, by the "Install For" option on the "Select 
Root Install Directory" page.


To me, this looks like a (very long standing) bug that we shouldn't 
be calling setAdminGroup() here, but after root_scope has been set.


If this bug is very old, I'm not sure whether this should be fixed. 
Setting admin group to files which are owned "only" by current user 
is possibly not very effective.


It's true that some people might be relying on that buggy behaviour.


I have one very old Cygwin installation from Win7 times. Very old 
installed files still have group="Administrator", newer files have 
group="None". The timestamps suggest that the regression was introduced 
early in 2012. The first file with group="None" is from March 2 2012.



But, please help me understand how your patch differs from adding an 
option which fixes that misbehaviour when supplied?


It does fix the regression, it adds a new installation flavor which 
fixes it as a side effect.


Possible owner:group assignments of newly installed dirs/files:

"All Users":
adm:adm -- With this patch and --chown-admin set
usr:def -- Current behavior, regardless of this patch
usr:adm -- Before 'isAdmin always false' regression was introduced

"Just Me":
adm:adm -- With this patch, --chown-admin set and setup has admin rights
usr:def -- Otherwise

(usr = user running setup, adm = S-1-5-32-544, def = S-1-5-21-*-513)




(As an aside, looking at how setAdminGroup()/resetPrimaryGroup() are 
used, changing the token for the postinstall scripts seems unnecessary 
now, since we don't run mkpasswd there any more...)


Agree.



Re: [PATCH setup] Add new option --chown-admin

2022-07-06 Thread Christian Franke

Jon Turney wrote:

On 06/07/2022 08:14, Christian Franke wrote:
If an installer is run elevated, the installed files will be 
typically owned by the local administrator (or in some cases SYSTEM 
or TrustedInstaller) instead of the current user. This is not the 
case for a Cygwin "All Users" installation. The files are then not 
protected from 


... instead the files are owned by the user running setup?


Yes, because the TokenUser is unconditionally copied to TokenOwner. Some 
research with 'git blame' shows that many parts of the related code are 
from the early days of UAC and elevated processes (Vista 2006, Win7 
2009). Things may have changed since then, I don't know (or remember).


If a process is run elevated, Windows keeps TokenUser unchanged but sets 
the TokenOwner to local administrator. The --chown-admin option simply 
keeps this as is, so no actual chown() is needed later. The 
TokenPrimaryGroup is not changed by Windows, therefore --chown-admin 
calls setAdminGroup() to mimic the usual "root root" ownership.


Typical simple installers leave everything as is, so the installed files 
are owned by local adminstrator and group "None" (S-1-5-21-*-513), see 
'ls -l "$PROGRAMFILES"'.




accidental changes by this user.

The attached patch adds an experimental --chown-admin option which 
allows (new) installations owned by local administrator user and group.


Thanks for the patch, but...

A drawback is that files generated by postinstall scripts are still 
owned by current user + "None" group. It should be possible to fix 
this with some perpetual preremove+postinstall scripts.


I also don't know whether this may break some postinstall scripts.

BTW: 'nt_sec.setDefaultSecurity (isAdmin)' is never called with 
'isAdmin==true' as 'root_scope' is always 0.


root_scope is set later, by the "Install For" option on the "Select 
Root Install Directory" page.


To me, this looks like a (very long standing) bug that we shouldn't be 
calling setAdminGroup() here, but after root_scope has been set.


If this bug is very old, I'm not sure whether this should be fixed. 
Setting admin group to files which are owned "only" by current user is 
possibly not very effective.




Re: New version of GNU ddrescue available (1.26)

2022-07-06 Thread Christian Franke

Hamish McIntyre-Bhatty wrote:

On 05/07/2022 10:22, Christian Franke wrote:

Hamish McIntyre-Bhatty wrote:
I was wondering if the maintainer for GNU ddrescue could update to 
1.26 please?


1.27-pre2 is already released, so I wait for 1.27 final.



Fair enough. Do you know if there's a mailing list or similar to be 
notified of new versions? I was on the GNU mailing list for a bit, but 
I couldn't configure it to not just constantly spam me.


Perhaps you want to try this low volume list:
https://lists.gnu.org/mailman/listinfo/bug-ddrescue



[PATCH setup] Add new option --chown-admin

2022-07-06 Thread Christian Franke
If an installer is run elevated, the installed files will be typically 
owned by the local administrator (or in some cases SYSTEM or 
TrustedInstaller) instead of the current user. This is not the case for 
a Cygwin "All Users" installation. The files are then not protected from 
accidental changes by this user.


The attached patch adds an experimental --chown-admin option which 
allows (new) installations owned by local administrator user and group.


A drawback is that files generated by postinstall scripts are still 
owned by current user + "None" group. It should be possible to fix this 
with some perpetual preremove+postinstall scripts.


I also don't know whether this may break some postinstall scripts.

BTW: 'nt_sec.setDefaultSecurity (isAdmin)' is never called with 
'isAdmin==true' as 'root_scope' is always 0.


--
Regards,
Christian

From 1dfc8d63a8438e42544b06cfdf225f222107eed2 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Wed, 6 Jul 2022 07:41:18 +0200
Subject: [PATCH] Add new option --chown-admin

If specified and the process token owner is the local administrator,
the owner is preserved and the primary group is set to the local
administrator group.
---
 main.cc  |  3 ++-
 win32.cc | 41 ++---
 win32.h  |  2 +-
 3 files changed, 33 insertions(+), 13 deletions(-)

diff --git a/main.cc b/main.cc
index 3a8c5ea..81c4a65 100644
--- a/main.cc
+++ b/main.cc
@@ -99,6 +99,7 @@ static StringOption Arch ("", 'a', "arch", IDS_HELPTEXT_ARCH, 
false);
 static BoolOption UnattendedOption (false, 'q', "quiet-mode", 
IDS_HELPTEXT_QUIET_MODE);
 static BoolOption PackageManagerOption (false, 'M', "package-manager", 
IDS_HELPTEXT_PACKAGE_MANAGER);
 static BoolOption NoAdminOption (false, 'B', "no-admin", 
IDS_HELPTEXT_NO_ADMIN);
+static BoolOption ChownAdminOption (false, '\0', "chown-admin" /*, TODO: 
IDS_HELPTEXT_... */);
 static BoolOption WaitOption (false, 'W', "wait", IDS_HELPTEXT_WAIT);
 static BoolOption HelpOption (false, 'h', "help", IDS_HELPTEXT_HELP);
 static BoolOption VersionOption (false, 'V', "version", IDS_HELPTEXT_VERSION);
@@ -359,7 +360,7 @@ WinMain (HINSTANCE h,
   }
 
 /* Set default DACL and Group. */
-nt_sec.setDefaultSecurity ((root_scope == IDC_ROOT_SYSTEM));
+nt_sec.setDefaultSecurity ((root_scope == IDC_ROOT_SYSTEM), 
ChownAdminOption);
 
 /*
If --symlink-type option isn't given, look for winsymlinks in CYGWIN
diff --git a/win32.cc b/win32.cc
index 55072a9..5dc9616 100644
--- a/win32.cc
+++ b/win32.cc
@@ -308,7 +308,7 @@ NTSecurity::setAdminGroup ()
 }
 
 void
-NTSecurity::setDefaultSecurity (bool isAdmin)
+NTSecurity::setDefaultSecurity (bool isAdmin, bool keepAdmin)
 {
   /* Get the processes access token. */
   if (!OpenProcessToken (GetCurrentProcess (),
@@ -335,21 +335,40 @@ NTSecurity::setDefaultSecurity (bool isAdmin)
   /* Set the default DACL to all permissions for everyone as a fallback. */
   setDefaultDACL ();
 
-  /* Get the user */
-  if (!GetTokenInformation (token.theHANDLE (), TokenUser, ,
+  /* Get the owner */
+  if (!GetTokenInformation (token.theHANDLE (), TokenOwner, ,
sizeof ownerSID, ))
 {
-  NoteFailedAPI ("GetTokenInformation(user)");
+  NoteFailedAPI ("GetTokenInformation(owner)");
   return;
 }
-  /* Make it the owner */
-  TOKEN_OWNER owner = { ownerSID.user.User.Sid };
-  if (!SetTokenInformation (token.theHANDLE (), TokenOwner, ,
-   sizeof owner))
+
+  bool ownerIsAdmin = !!EqualSid (ownerSID.user.User.Sid, 
administratorsSID.theSID ());
+
+  if (keepAdmin && ownerIsAdmin)
+Log (LOG_TIMESTAMP) << "Default owner is Administrator" << endLog;
+  else
 {
-  NoteFailedAPI ("SetTokenInformation(owner)");
-  return;
+  /* Get the user */
+  if (!GetTokenInformation (token.theHANDLE (), TokenUser, ,
+   sizeof ownerSID, ))
+   {
+ NoteFailedAPI ("GetTokenInformation(user)");
+ return;
+   }
+  /* Make it the owner */
+  TOKEN_OWNER owner = { ownerSID.user.User.Sid };
+  if (!SetTokenInformation (token.theHANDLE (), TokenOwner, ,
+   sizeof owner))
+   {
+ NoteFailedAPI ("SetTokenInformation(owner)");
+ return;
+   }
+  Log (LOG_TIMESTAMP) << "Default owner changed "
+ << (ownerIsAdmin ? "from Administrator " : "")
+ << "to current user" << endLog;
 }
+
   /* Get original primary group.  The token's primary group will be reset
  to the original group right before we call the postinstall scripts.
  This is necessary, otherwise, if the installing user is a domain user,

Re: New version of GNU ddrescue available (1.26)

2022-07-05 Thread Christian Franke

Hamish McIntyre-Bhatty wrote:
I was wondering if the maintainer for GNU ddrescue could update to 
1.26 please?


1.27-pre2 is already released, so I wait for 1.27 final.

--
Regards,
Christian



Re: SFTP release directories missing

2022-07-03 Thread Christian Franke

Christian Franke wrote:

Adam Dinwoodie wrote:

I'm currently seeing attempts to run `cygport  stage` fail with
an error "cd: Access failed: No such file (/x86_64/release)". And
logging in manually over sftp, that looks to be accurate; the only
file I can see is my !mail file.

```
$ echo $'ls\npwd\n' | sftp cyg...@cygwin.com
Connected to cygwin.com.
sftp> ls
!mail
sftp> pwd
Remote working directory: /
sftp>
```

Clearly something has gone wrong with the upload space for my
packages; can someone fix it / tell me what I need to do to fix it?


I got the same problem 2x today during upload of pass and etckeeper. 
Could be fixed by creating the directories manually with mkdir.




Seems to be fixed now. Empty directories {noarch,x86,x86_64}/release 
reappeared in my lftp account.




Re: SFTP release directories missing

2022-07-02 Thread Christian Franke

Adam Dinwoodie wrote:

I'm currently seeing attempts to run `cygport  stage` fail with
an error "cd: Access failed: No such file (/x86_64/release)". And
logging in manually over sftp, that looks to be accurate; the only
file I can see is my !mail file.

```
$ echo $'ls\npwd\n' | sftp cyg...@cygwin.com
Connected to cygwin.com.
sftp> ls
!mail
sftp> pwd
Remote working directory: /
sftp>
```

Clearly something has gone wrong with the upload space for my
packages; can someone fix it / tell me what I need to do to fix it?


I got the same problem 2x today during upload of pass and etckeeper. 
Could be fixed by creating the directories manually with mkdir.


--
Regards,
Christian



Re: [ITP] etckeeper 1.18.17-1

2022-07-02 Thread Christian Franke

Adam Dinwoodie wrote:

On Wed, Jun 29, 2022 at 09:55:10AM +0200, Christian Franke wrote:

Christian Franke wrote:

...

A possible simple extension which would allow the user to choose between
manual or automatic installation+initialization:

Provide an optional package, for example "etckeeper-git-init", which depends
on etckeeper+git and only contains /etc/postinstall/etckeeper-git-init.sh
which triggers new initialization code in
/etc/postinstall/zp_zzz_etckeeper-postinstall.sh via some file in
/var/cache/etckeeper. This code performs 'etckeeper init && etckeeper
commit' if and only if VCS=git is selected and /etc/.git does not exist.

Honestly, I suspect it's not worth the effort of doing things like that.
As you say, 99.8% of users who might be interested in using etckeeper
are going to be people who already have a good idea what they're doing
and will be able to work it out for themselves.

Thinking about it some more, I'm also mildly concerned about the small
but non-trivial proportion of users who blithely install every package
available on Cygwin, which I don't think is going to be an issue for
more-or-less any other *nix distribution.  I don't normally think it's
worth doing much to actively catering for those users -- I'm generally
of the opinion that they're making their own misery -- but in this case
automatically starting etckeeper would be a potentially significant
impact, and for the sake of both their lives and yours, I suspect it's
best to just leave etckeeper as something that requires manual
initiation.


Good point.



That said, if you're keen to set up that optional package, I definitely
don't think it's a bad idea; "it wouldn't be worth the effort to me"
doesn't mean you shouldn't do it!


 I now decided to leave this for later (or never). The package is new 
and if there are still issues during initialization, the messages should 
be visible on console.




Re: [PATCH setup] Add perpetual support for preremove scripts

2022-07-01 Thread Christian Franke

Christian Franke wrote:

Jon Turney wrote:
...
Can you please also write a patch for [1] (source in [2]) to document 
this?


[1] https://cygwin.com/packaging-package-files.html#postinstall
[2] 
https://cygwin.com/git/?p=cygwin-htdocs.git;a=blob;f=packaging-package-files.html




Of course. I will possibly wait until my ITP of etckeeper is accepted 
to have a real world example for the doc.




Patch attached. Written under the assumption that "[PATCH] Also run 
stratum 'z' perpetual preremove scripts" and "[ITP] etckeeper 1.18.17-1" 
will eventually be accepted :-)


From b8225603a5d66760445c04ec14861764deb1489f Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Fri, 1 Jul 2022 18:52:17 +0200
Subject: [PATCH] Add perpetual pre-remove scripts

---
 packaging-package-files.html | 40 +---
 1 file changed, 24 insertions(+), 16 deletions(-)

diff --git a/packaging-package-files.html b/packaging-package-files.html
index 446e62db..5b214f53 100755
--- a/packaging-package-files.html
+++ b/packaging-package-files.html
@@ -223,27 +223,35 @@ etc...
   after it is installed.
 
 
-Perpetual post-install scripts
+Perpetual post-install and pre-remove scripts
 
-  In addition to the ordinary ("run-once") post-install scripts described 
above,
-  the setup program supports "perpetual" post-install scripts.  These are run 
on
-  every invocation of setup, as long as the package is still installed.
-  Perpetual post-install scripts are distinguished from run-once scripts by
+  In addition to the ordinary ("run-once") scripts described above,
+  the setup program supports "perpetual" post-install and pre-remove scripts.
+  These are run on every invocation of setup, as long as the package is still
+  installed.  Perpetual scripts are distinguished from run-once scripts by
   having names that start with "0p_" or "zp_".  Those that start with "0p_" are
-  run before the run-once scripts, and those that start with "zp_" are run 
after
-  the run-once scripts.  Examples include
-  0p_000_autorebase.dash (provided by the 
_autorebase package)
-  and 0p_update-info-dir.dash (provided by the info 
package).
+  run before the run-once scripts, and those that start with "zp_" are run
+  after the run-once scripts.  Examples include
+  postinstall/0p_000_autorebase.dash (provided by the
+  _autorebase package),
+  postinstall/0p_update-info-dir.dash (provided by the
+  info package),
+  postinstall/zp_zzz_etckeeper_post-install.sh and
+  preremove/0p_000_etckeeper_pre-install.sh (provided by the
+  etckeeper package).
 
 
   For those package maintainers wanting to employ perpetual scripts, the first
-  thing to keep in mind is to only use this feature for things that really 
can't
-  be done with run-once scripting.  Any perpetual script should minimize the
-  resources used (use dash instead of bash for instance) and exit at the
-  earliest possible moment if no action is required.  Scripts of type "0p_" 
must
-  be able to run with the Base packages installed but the post-install scripts
-  not yet executed; in practical terms that rules out using bash scripts.  This
-  limitation does not apply to scripts of type "zp_".
+  thing to keep in mind is to only use this feature for things that really
+  can't be done with run-once scripting.  Any perpetual script should minimize
+  the resources used (use dash instead of bash for instance) and exit at the
+  earliest possible moment if no action is required.  Post-install scripts of
+  type "0p_" must be able to run with the Base packages installed but the
+  remaining post-install scripts not yet executed; in practical terms that
+  rules out using bash scripts.  Pre-remove scripts of type "zp_" must be able
+  to run with the other pre-remove scripts already executed.  These limitations
+  do not apply to post-install scripts of type "zp_" and pre-remove scripts of
+  type "0p_".
 
 
   See https://cygwin.com/ml/cygwin-apps/2014-12/msg00148.html;>this
-- 
2.36.1



[ITP] pass 1.7.4-1 (password-store)

2022-07-01 Thread Christian Franke

I would like to contribute pass (password-store):

https://www.passwordstore.org/
https://repology.org/project/password-store/versions

pass-1.7.4-1.hint:
category: Utils
requires: bash coreutils grep sed tree
sdesc: "Lightweight CLI directory-based password manager"
ldesc: "Pass is a command line tool which stores, retrieves and
generates passwords securely using gpg.  Optionally password changes
could be tracked and synchronized with git.  Passwords could be
temporarily pasted to /dev/clipboard or displayed as QR codes
(requires package qrencode).  Auto completion modules for bash, fish
and zsh are included.  A vim plugin disables insecure options during
password editing."

Package for review:
wget -r -nH --cut-dirs=2 \
https://chrfranke.de/cygwin/noarch/pass-1.7.4-1.hint \
https://chrfranke.de/cygwin/noarch/pass-1.7.4-1-src.hint \
https://chrfranke.de/cygwin/noarch/pass-1.7.4-1-src.tar.xz \
https://chrfranke.de/cygwin/noarch/pass-1.7.4-1.tar.xz \
https://chrfranke.de/cygwin/noarch/pass-1.7.4-1.sha256

gpg or gpg2 are also required. Non-Cygwin versions of gpg.exe or 
gpg2.exe are also supported if neither gnupg nor gnupg2 is installed.


Package naming differs in practice:
- "pass": Fedora, ... - I decided to use this.
- "pass" but "password-store" for src package: Debian, Ubuntu, ...
- "password-store": ...

--
Regards,
Christian



Re: [PATCH setup] Add perpetual support for preremove scripts

2022-06-29 Thread Christian Franke

Christian Franke wrote:

Jon Turney wrote:

On 26/06/2022 17:33, Christian Franke wrote:

...
This patch adds the missing functionality to run the pre-install 
hook. It is limited to /etc/preremove/0p_* because there is possibly 
no use case for /etc/preremove/zp_*.


Thanks.

I'm not sure what you mean by 'there is possibly no use case': That 
you don't have one currently, or that you've reasoned that there 
can't be one?




I don't have one currently and found none which is useful in practice, 
but cannot prove that there is none. If desired, I could provide a 
patch which adds 'zp_*' support.




Meantime I realized that this is one of these cases where discussion may 
take longer than implementation. Attached is a patch ...




...

I applied this patch.



Thanks. I found a minor GUI issue during testing: Script filename 
display persists during package remove phase. Fixed with attached patch.


... which should be applied on top of this last patch.

From 7e3350f633f18e5639a109e0d779473e949ebe57 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Wed, 29 Jun 2022 19:57:26 +0200
Subject: [PATCH] Also run stratum 'z' perpetual preremove scripts

---
 install.cc | 29 +
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/install.cc b/install.cc
index 0ceb05f..1fdc699 100644
--- a/install.cc
+++ b/install.cc
@@ -76,26 +76,28 @@ struct std_dirs_t {
   mode_t mode;
 };
 
-class Perpetual0RemoveFindVisitor : public FindVisitor
+class PerpetualRemoveFindVisitor : public FindVisitor
 {
 public:
-  explicit Perpetual0RemoveFindVisitor (std::vector

Re: [PATCH setup] Add perpetual support for preremove scripts

2022-06-29 Thread Christian Franke

Jon Turney wrote:

On 26/06/2022 17:33, Christian Franke wrote:
Use case: I ITP etckeeper (https://etckeeper.branchable.com/) which I 
frequently use on Debian. For fully automatic operation, it requires 
pre-install and post-install hooks, e.g:


/etc/preremove/0p_000_etckeeper_pre-install.sh
/etc/postinstall/zp_zzz_etckeeper_post-install.sh

This patch adds the missing functionality to run the pre-install 
hook. It is limited to /etc/preremove/0p_* because there is possibly 
no use case for /etc/preremove/zp_*.


Thanks.

I'm not sure what you mean by 'there is possibly no use case': That 
you don't have one currently, or that you've reasoned that there can't 
be one?




I don't have one currently and found none which is useful in practice, 
but cannot prove that there is none. If desired, I could provide a patch 
which adds 'zp_*' support.



'class Perpetual0RemoveFindVisitor' is borrowed from postinstall.cc 
and modified. It still uses the ugly pre-C++11 hack to disable 
copy-ctor and operator=. Possible refactoring like merging all 3 
mostly similar visitors into one (or if C++11 is now allowed, use 
lambda functions instead) are left for later.


Yeah, some refactoring would make this simpler and easier to 
understand. :)


I applied this patch.



Thanks. I found a minor GUI issue during testing: Script filename 
display persists during package remove phase. Fixed with attached patch.



Can you please also write a patch for [1] (source in [2]) to document 
this?


[1] https://cygwin.com/packaging-package-files.html#postinstall
[2] 
https://cygwin.com/git/?p=cygwin-htdocs.git;a=blob;f=packaging-package-files.html




Of course. I will possibly wait until my ITP of etckeeper is accepted to 
have a real world example for the doc.


--
Regards,
Christian

From dd31653b99c3a970fd145d2ffbad5809de7e0273 Mon Sep 17 00:00:00 2001
From: Christian Franke 
Date: Wed, 29 Jun 2022 16:51:47 +0200
Subject: [PATCH] Clear filename on GUI after running perpetual preremove
 scripts

---
 install.cc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/install.cc b/install.cc
index 6689a08..0ceb05f 100644
--- a/install.cc
+++ b/install.cc
@@ -192,6 +192,7 @@ Installer::preremovePerpetual0 ()
 Progress.SetText3 (i->fullName ().c_str());
 i->run();
   }
+  Progress.SetText3 ("");
 }
 
 void
-- 
2.36.1



  1   2   3   >