tests: capture stdin to get the vsftpd version number

vsftpd 3.0 at least writes its version number to stdin (!) instead of
stderr. This works due for backwards compatibility reasons in UNIX, so
we must check stdin for anything written there to reliably parse the
version string.

Closes #15278
This commit is contained in:
Dan Fandrich 2024-10-12 10:38:40 -07:00
parent 6478a36b66
commit 41c980bb0d

View File

@ -30,6 +30,7 @@ import re
import shutil
import socket
import subprocess
import tempfile
from configparser import ConfigParser, ExtendedInterpolation
from typing import Optional
@ -186,12 +187,22 @@ class EnvConfig:
self._vsftpd_version = None
if self.vsftpd is not None:
try:
p = subprocess.run(args=[self.vsftpd, '-v'],
capture_output=True, text=True)
if p.returncode != 0:
# not a working vsftpd
self.vsftpd = None
m = re.match(r'vsftpd: version (\d+\.\d+\.\d+)', p.stderr)
with tempfile.TemporaryFile('w+') as tmp:
p = subprocess.run(args=[self.vsftpd, '-v'],
capture_output=True, text=True, stdin=tmp)
if p.returncode != 0:
# not a working vsftpd
self.vsftpd = None
if p.stderr:
ver_text = p.stderr
else:
# Oddly, some versions of vsftpd write to stdin (!)
# instead of stderr, which is odd but works. If there
# is nothing on stderr, read the file on stdin and use
# any data there instead.
tmp.seek(0)
ver_text = tmp.read()
m = re.match(r'vsftpd: version (\d+\.\d+\.\d+)', ver_text)
if m:
self._vsftpd_version = m.group(1)
elif len(p.stderr) == 0: