mirror of
https://gitlab.com/buildroot.org/buildroot.git
synced 2026-08-08 00:20:38 -09:00
package/nut: bump version to 2.8.3
Release notes: https://github.com/networkupstools/nut/releases/tag/v2.8.3 Remove all patches which are included in this release. Updated license hash due to upstream commits:1cd56ce01991585bf708f9a41e7225Upstream commit4ddc5aedf3sets PKG_CONFIG_LIBDIR=/dev/null when cross-compiling and the pkg-config binary lacks the host triplet, but: "If pkg-config libdir is already defined, we suppose that callers know what they're doing and leave it alone ..." Add PKG_CONFIG_LIBDIR to NUT_CONF_ENV to fix library detections. Signed-off-by: Bernd Kuhls <bernd@kuhls.net> Signed-off-by: Julien Olivain <ju.o@free.fr>
This commit is contained in:
committed by
Julien Olivain
parent
230ee77c74
commit
df685627a2
@@ -1,878 +0,0 @@
|
||||
From 84c8ddef0b70ae14a8867639366501e2988a1092 Mon Sep 17 00:00:00 2001
|
||||
From: Jim Klimov <jimklimov+nut@gmail.com>
|
||||
Date: Mon, 1 Jul 2024 15:47:46 +0200
|
||||
Subject: [PATCH] Provide a fallback copy of telnetlib module for PyNUTClient
|
||||
[#2183]
|
||||
|
||||
Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
|
||||
|
||||
Upstream: https://github.com/networkupstools/nut/commit/84c8ddef0b70ae14a8867639366501e2988a1092
|
||||
|
||||
Signed-off-by: Bernd Kuhls <bernd@kuhls.net>
|
||||
---
|
||||
configure.ac | 17 +-
|
||||
docs/nut.dict | 3 +-
|
||||
scripts/python/Makefile.am | 1 +
|
||||
scripts/python/README.adoc | 15 +
|
||||
scripts/python/module/Makefile.am | 7 +-
|
||||
scripts/python/module/PyNUT.py.in | 18 +-
|
||||
scripts/python/module/nut_telnetlib.py | 683 +++++++++++++++++++++++++
|
||||
scripts/python/module/setup.py.in | 6 +-
|
||||
9 files changed, 746 insertions(+), 8 deletions(-)
|
||||
create mode 100644 scripts/python/module/nut_telnetlib.py
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index d369ea82b8..6f90e50a5e 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -2447,7 +2447,7 @@ if test x"${nut_with_nut_monitor}" != xno ; then
|
||||
fi
|
||||
|
||||
dnl ${nut_with_pynut}: TODO: arg values to request python 2, 3 or both
|
||||
-AC_MSG_CHECKING([if we can and should install PyNUT module])
|
||||
+AC_MSG_CHECKING([if we can and should install PyNUT module (note for warnings from python 3.11 and beyond: we have a fallback nut_telnetlib module just in case)])
|
||||
nut_with_pynut_py=""
|
||||
nut_with_pynut_py2=""
|
||||
nut_with_pynut_py3=""
|
||||
@@ -2469,6 +2469,15 @@ if test x"${nut_with_pynut}" != xno \
|
||||
if ${PYTHON3} -c "import telnetlib" \
|
||||
; then
|
||||
nut_with_pynut_py3="yes"
|
||||
+ else
|
||||
+ dnl We have a stashed copy from Python 3.10, so
|
||||
+ dnl this line essentially checks for presence of
|
||||
+ dnl a usable interpreter implementation compatible
|
||||
+ dnl with Python 3.x syntax.
|
||||
+ if (cd script/python/module && ${PYTHON3} -c "import nut_telnetlib as telnetlib") \
|
||||
+ ; then
|
||||
+ nut_with_pynut_py3="yes"
|
||||
+ fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -2480,6 +2489,12 @@ if test x"${nut_with_pynut}" != xno \
|
||||
if ${PYTHON} -c "import telnetlib" \
|
||||
; then
|
||||
nut_with_pynut_py="yes"
|
||||
+ else
|
||||
+ dnl See comments above
|
||||
+ if (cd script/python/module && ${PYTHON} -c "import nut_telnetlib as telnetlib") \
|
||||
+ ; then
|
||||
+ nut_with_pynut_py="yes"
|
||||
+ fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
diff --git a/scripts/python/Makefile.am b/scripts/python/Makefile.am
|
||||
index 0b83249cd5..a737f50c91 100644
|
||||
--- a/scripts/python/Makefile.am
|
||||
+++ b/scripts/python/Makefile.am
|
||||
@@ -70,6 +70,7 @@ NUT_MONITOR_COMMON = \
|
||||
app/locale/ru/LC_MESSAGES/NUT-Monitor.mo
|
||||
|
||||
PYNUT_COMMON = \
|
||||
+ module/nut_telnetlib.py \
|
||||
module/README.adoc
|
||||
|
||||
# Note: we both distribute and install the generated *.mo translation files
|
||||
diff --git a/scripts/python/README.adoc b/scripts/python/README.adoc
|
||||
index 72e268063b..8770d4ca06 100644
|
||||
--- a/scripts/python/README.adoc
|
||||
+++ b/scripts/python/README.adoc
|
||||
@@ -35,6 +35,21 @@ and protocol support.
|
||||
|
||||
For one practical example, you can research `tests/NIT/nit.sh` in NUT sources.
|
||||
|
||||
+telnetlib
|
||||
+^^^^^^^^^
|
||||
+
|
||||
+Historically, the `PyNUTClient` class relied on `telnetlib` module for socket
|
||||
+communications with the NUT data server, which was provided as part of Python
|
||||
+core installation with tested 2.6+ and 3.* versions. The module was, however,
|
||||
+marked deprecated since Python 3.11 and not provided since 3.13. Due to this,
|
||||
+as a quick stop-gap solution, NUT sources provide `nut_telnetlib.py` - a copy
|
||||
+of the module from Python 3.10 installation, and no longer should require its
|
||||
+presence in the Python deployment.
|
||||
+
|
||||
+A better solution would be to find or create a new layer for the constrained
|
||||
+use-case of NUT client interactions with a data server, which do not need the
|
||||
+fully fledged Telnet-like capabilities.
|
||||
+
|
||||
app
|
||||
~~~
|
||||
|
||||
diff --git a/scripts/python/module/Makefile.am b/scripts/python/module/Makefile.am
|
||||
index fc46eab0ad..5eb650969c 100644
|
||||
--- a/scripts/python/module/Makefile.am
|
||||
+++ b/scripts/python/module/Makefile.am
|
||||
@@ -16,7 +16,7 @@ check-local:
|
||||
tox: dist .pypi-tools-tox
|
||||
tox
|
||||
|
||||
-EXTRA_DIST = tox.ini MANIFEST.in
|
||||
+EXTRA_DIST = tox.ini MANIFEST.in nut_telnetlib.py
|
||||
|
||||
NUT_SOURCE_GITREV_NUMERIC = @NUT_SOURCE_GITREV_NUMERIC@
|
||||
PYTHON = @PYTHON@
|
||||
@@ -64,7 +64,9 @@ upload publish:
|
||||
esac
|
||||
|
||||
# README.txt is also a part of module standard expectations
|
||||
-.pypi-src: test_nutclient.py.in PyNUT.py.in setup.py.in README.adoc Makefile $(top_srcdir)/LICENSE-GPL3
|
||||
+# nut_telnetlib.py is not converted from a .in template, it
|
||||
+# does not even have a shebang line.
|
||||
+.pypi-src: test_nutclient.py.in PyNUT.py.in setup.py.in nut_telnetlib.py README.adoc Makefile $(top_srcdir)/LICENSE-GPL3
|
||||
@echo " PYPI Generate PyPI module source"
|
||||
@rm -rf $(GENERATED_SRC) "$@"
|
||||
@mkdir -p PyNUTClient
|
||||
@@ -83,6 +85,7 @@ upload publish:
|
||||
sed -e "s,[@]PYTHON[@],@PYTHON@," < "$(srcdir)/$${B}.in" > "PyNUTClient/$${B}" || exit ; \
|
||||
if test -x "$(srcdir)/$${B}.in" ; then chmod +x "PyNUTClient/$${B}"; fi ; \
|
||||
done ; \
|
||||
+ cp -pf "$(srcdir)/nut_telnetlib.py" PyNUTClient/ || exit ; \
|
||||
cp -pf "$(srcdir)/README.adoc" README.txt || exit ; \
|
||||
cp -pf "$(top_srcdir)/LICENSE-GPL3" . || exit ; \
|
||||
echo "from . import PyNUT" > PyNUTClient/__init__.py || exit
|
||||
diff --git a/scripts/python/module/PyNUT.py.in b/scripts/python/module/PyNUT.py.in
|
||||
index 6f3c4ff510..6838fc373a 100644
|
||||
--- a/scripts/python/module/PyNUT.py.in
|
||||
+++ b/scripts/python/module/PyNUT.py.in
|
||||
@@ -55,8 +55,20 @@
|
||||
# 2023-01-18 Jim Klimov <jimklimov+nut@gmail.com> - Version 1.6.0
|
||||
# Added CheckUPSAvailable() method originally by Michal Hlavinka
|
||||
# from 2013-01-07 RedHat/Fedora packaging
|
||||
+#
|
||||
+# 2024-07-01 Jim Klimov <jimklimov+nut@gmail.com> - Version 1.7.0
|
||||
+# Re-arranged dependency on telnetlib module (deprecated/removed
|
||||
+# since Python 3.11/3.13), so we can fall back on a privately
|
||||
+# stashed copy until a better solution is developed.
|
||||
+#
|
||||
|
||||
-import telnetlib
|
||||
+try:
|
||||
+ import telnetlib
|
||||
+except ModuleNotFoundError:
|
||||
+ import os
|
||||
+ if "true" == os.getenv('DEBUG', 'false'):
|
||||
+ print( "[DEBUG] Fall back to private copy of telnetlib for PyNUTClient\n" )
|
||||
+ import nut_telnetlib as telnetlib
|
||||
|
||||
class PyNUTError( Exception ) :
|
||||
""" Base class for custom exceptions """
|
||||
@@ -73,8 +85,8 @@ class PyNUTClient :
|
||||
__timeout = None
|
||||
__srv_handler = None
|
||||
|
||||
- __version = "1.6.0"
|
||||
- __release = "2023-01-18"
|
||||
+ __version = "1.7.0"
|
||||
+ __release = "2024-07-01"
|
||||
|
||||
|
||||
def __init__( self, host="127.0.0.1", port=3493, login=None, password=None, debug=False, timeout=5 ) :
|
||||
diff --git a/scripts/python/module/nut_telnetlib.py b/scripts/python/module/nut_telnetlib.py
|
||||
new file mode 100644
|
||||
index 0000000000..a9c444f10a
|
||||
--- /dev/null
|
||||
+++ b/scripts/python/module/nut_telnetlib.py
|
||||
@@ -0,0 +1,683 @@
|
||||
+r"""TELNET client class.
|
||||
+
|
||||
+------
|
||||
+This file has been copied for PyNUTClient fallback needs from Python 3.10
|
||||
+(newer Python releases obsoleted the module) and not modified except for
|
||||
+this notice.
|
||||
+------
|
||||
+
|
||||
+Based on RFC 854: TELNET Protocol Specification, by J. Postel and
|
||||
+J. Reynolds
|
||||
+
|
||||
+Example:
|
||||
+
|
||||
+>>> from telnetlib import Telnet
|
||||
+>>> tn = Telnet('www.python.org', 79) # connect to finger port
|
||||
+>>> tn.write(b'guido\r\n')
|
||||
+>>> print(tn.read_all())
|
||||
+Login Name TTY Idle When Where
|
||||
+guido Guido van Rossum pts/2 <Dec 2 11:10> snag.cnri.reston..
|
||||
+
|
||||
+>>>
|
||||
+
|
||||
+Note that read_all() won't read until eof -- it just reads some data
|
||||
+-- but it guarantees to read at least one byte unless EOF is hit.
|
||||
+
|
||||
+It is possible to pass a Telnet object to a selector in order to wait until
|
||||
+more data is available. Note that in this case, read_eager() may return b''
|
||||
+even if there was data on the socket, because the protocol negotiation may have
|
||||
+eaten the data. This is why EOFError is needed in some cases to distinguish
|
||||
+between "no data" and "connection closed" (since the socket also appears ready
|
||||
+for reading when it is closed).
|
||||
+
|
||||
+To do:
|
||||
+- option negotiation
|
||||
+- timeout should be intrinsic to the connection object instead of an
|
||||
+ option on one of the read calls only
|
||||
+
|
||||
+"""
|
||||
+
|
||||
+
|
||||
+# Imported modules
|
||||
+import sys
|
||||
+import socket
|
||||
+import selectors
|
||||
+from time import monotonic as _time
|
||||
+
|
||||
+__all__ = ["Telnet"]
|
||||
+
|
||||
+# Tunable parameters
|
||||
+DEBUGLEVEL = 0
|
||||
+
|
||||
+# Telnet protocol defaults
|
||||
+TELNET_PORT = 23
|
||||
+
|
||||
+# Telnet protocol characters (don't change)
|
||||
+IAC = bytes([255]) # "Interpret As Command"
|
||||
+DONT = bytes([254])
|
||||
+DO = bytes([253])
|
||||
+WONT = bytes([252])
|
||||
+WILL = bytes([251])
|
||||
+theNULL = bytes([0])
|
||||
+
|
||||
+SE = bytes([240]) # Subnegotiation End
|
||||
+NOP = bytes([241]) # No Operation
|
||||
+DM = bytes([242]) # Data Mark
|
||||
+BRK = bytes([243]) # Break
|
||||
+IP = bytes([244]) # Interrupt process
|
||||
+AO = bytes([245]) # Abort output
|
||||
+AYT = bytes([246]) # Are You There
|
||||
+EC = bytes([247]) # Erase Character
|
||||
+EL = bytes([248]) # Erase Line
|
||||
+GA = bytes([249]) # Go Ahead
|
||||
+SB = bytes([250]) # Subnegotiation Begin
|
||||
+
|
||||
+
|
||||
+# Telnet protocol options code (don't change)
|
||||
+# These ones all come from arpa/telnet.h
|
||||
+BINARY = bytes([0]) # 8-bit data path
|
||||
+ECHO = bytes([1]) # echo
|
||||
+RCP = bytes([2]) # prepare to reconnect
|
||||
+SGA = bytes([3]) # suppress go ahead
|
||||
+NAMS = bytes([4]) # approximate message size
|
||||
+STATUS = bytes([5]) # give status
|
||||
+TM = bytes([6]) # timing mark
|
||||
+RCTE = bytes([7]) # remote controlled transmission and echo
|
||||
+NAOL = bytes([8]) # negotiate about output line width
|
||||
+NAOP = bytes([9]) # negotiate about output page size
|
||||
+NAOCRD = bytes([10]) # negotiate about CR disposition
|
||||
+NAOHTS = bytes([11]) # negotiate about horizontal tabstops
|
||||
+NAOHTD = bytes([12]) # negotiate about horizontal tab disposition
|
||||
+NAOFFD = bytes([13]) # negotiate about formfeed disposition
|
||||
+NAOVTS = bytes([14]) # negotiate about vertical tab stops
|
||||
+NAOVTD = bytes([15]) # negotiate about vertical tab disposition
|
||||
+NAOLFD = bytes([16]) # negotiate about output LF disposition
|
||||
+XASCII = bytes([17]) # extended ascii character set
|
||||
+LOGOUT = bytes([18]) # force logout
|
||||
+BM = bytes([19]) # byte macro
|
||||
+DET = bytes([20]) # data entry terminal
|
||||
+SUPDUP = bytes([21]) # supdup protocol
|
||||
+SUPDUPOUTPUT = bytes([22]) # supdup output
|
||||
+SNDLOC = bytes([23]) # send location
|
||||
+TTYPE = bytes([24]) # terminal type
|
||||
+EOR = bytes([25]) # end or record
|
||||
+TUID = bytes([26]) # TACACS user identification
|
||||
+OUTMRK = bytes([27]) # output marking
|
||||
+TTYLOC = bytes([28]) # terminal location number
|
||||
+VT3270REGIME = bytes([29]) # 3270 regime
|
||||
+X3PAD = bytes([30]) # X.3 PAD
|
||||
+NAWS = bytes([31]) # window size
|
||||
+TSPEED = bytes([32]) # terminal speed
|
||||
+LFLOW = bytes([33]) # remote flow control
|
||||
+LINEMODE = bytes([34]) # Linemode option
|
||||
+XDISPLOC = bytes([35]) # X Display Location
|
||||
+OLD_ENVIRON = bytes([36]) # Old - Environment variables
|
||||
+AUTHENTICATION = bytes([37]) # Authenticate
|
||||
+ENCRYPT = bytes([38]) # Encryption option
|
||||
+NEW_ENVIRON = bytes([39]) # New - Environment variables
|
||||
+# the following ones come from
|
||||
+# http://www.iana.org/assignments/telnet-options
|
||||
+# Unfortunately, that document does not assign identifiers
|
||||
+# to all of them, so we are making them up
|
||||
+TN3270E = bytes([40]) # TN3270E
|
||||
+XAUTH = bytes([41]) # XAUTH
|
||||
+CHARSET = bytes([42]) # CHARSET
|
||||
+RSP = bytes([43]) # Telnet Remote Serial Port
|
||||
+COM_PORT_OPTION = bytes([44]) # Com Port Control Option
|
||||
+SUPPRESS_LOCAL_ECHO = bytes([45]) # Telnet Suppress Local Echo
|
||||
+TLS = bytes([46]) # Telnet Start TLS
|
||||
+KERMIT = bytes([47]) # KERMIT
|
||||
+SEND_URL = bytes([48]) # SEND-URL
|
||||
+FORWARD_X = bytes([49]) # FORWARD_X
|
||||
+PRAGMA_LOGON = bytes([138]) # TELOPT PRAGMA LOGON
|
||||
+SSPI_LOGON = bytes([139]) # TELOPT SSPI LOGON
|
||||
+PRAGMA_HEARTBEAT = bytes([140]) # TELOPT PRAGMA HEARTBEAT
|
||||
+EXOPL = bytes([255]) # Extended-Options-List
|
||||
+NOOPT = bytes([0])
|
||||
+
|
||||
+
|
||||
+# poll/select have the advantage of not requiring any extra file descriptor,
|
||||
+# contrarily to epoll/kqueue (also, they require a single syscall).
|
||||
+if hasattr(selectors, 'PollSelector'):
|
||||
+ _TelnetSelector = selectors.PollSelector
|
||||
+else:
|
||||
+ _TelnetSelector = selectors.SelectSelector
|
||||
+
|
||||
+
|
||||
+class Telnet:
|
||||
+
|
||||
+ """Telnet interface class.
|
||||
+
|
||||
+ An instance of this class represents a connection to a telnet
|
||||
+ server. The instance is initially not connected; the open()
|
||||
+ method must be used to establish a connection. Alternatively, the
|
||||
+ host name and optional port number can be passed to the
|
||||
+ constructor, too.
|
||||
+
|
||||
+ Don't try to reopen an already connected instance.
|
||||
+
|
||||
+ This class has many read_*() methods. Note that some of them
|
||||
+ raise EOFError when the end of the connection is read, because
|
||||
+ they can return an empty string for other reasons. See the
|
||||
+ individual doc strings.
|
||||
+
|
||||
+ read_until(expected, [timeout])
|
||||
+ Read until the expected string has been seen, or a timeout is
|
||||
+ hit (default is no timeout); may block.
|
||||
+
|
||||
+ read_all()
|
||||
+ Read all data until EOF; may block.
|
||||
+
|
||||
+ read_some()
|
||||
+ Read at least one byte or EOF; may block.
|
||||
+
|
||||
+ read_very_eager()
|
||||
+ Read all data available already queued or on the socket,
|
||||
+ without blocking.
|
||||
+
|
||||
+ read_eager()
|
||||
+ Read either data already queued or some data available on the
|
||||
+ socket, without blocking.
|
||||
+
|
||||
+ read_lazy()
|
||||
+ Read all data in the raw queue (processing it first), without
|
||||
+ doing any socket I/O.
|
||||
+
|
||||
+ read_very_lazy()
|
||||
+ Reads all data in the cooked queue, without doing any socket
|
||||
+ I/O.
|
||||
+
|
||||
+ read_sb_data()
|
||||
+ Reads available data between SB ... SE sequence. Don't block.
|
||||
+
|
||||
+ set_option_negotiation_callback(callback)
|
||||
+ Each time a telnet option is read on the input flow, this callback
|
||||
+ (if set) is called with the following parameters :
|
||||
+ callback(telnet socket, command, option)
|
||||
+ option will be chr(0) when there is no option.
|
||||
+ No other action is done afterwards by telnetlib.
|
||||
+
|
||||
+ """
|
||||
+
|
||||
+ def __init__(self, host=None, port=0,
|
||||
+ timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
|
||||
+ """Constructor.
|
||||
+
|
||||
+ When called without arguments, create an unconnected instance.
|
||||
+ With a hostname argument, it connects the instance; port number
|
||||
+ and timeout are optional.
|
||||
+ """
|
||||
+ self.debuglevel = DEBUGLEVEL
|
||||
+ self.host = host
|
||||
+ self.port = port
|
||||
+ self.timeout = timeout
|
||||
+ self.sock = None
|
||||
+ self.rawq = b''
|
||||
+ self.irawq = 0
|
||||
+ self.cookedq = b''
|
||||
+ self.eof = 0
|
||||
+ self.iacseq = b'' # Buffer for IAC sequence.
|
||||
+ self.sb = 0 # flag for SB and SE sequence.
|
||||
+ self.sbdataq = b''
|
||||
+ self.option_callback = None
|
||||
+ if host is not None:
|
||||
+ self.open(host, port, timeout)
|
||||
+
|
||||
+ def open(self, host, port=0, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
|
||||
+ """Connect to a host.
|
||||
+
|
||||
+ The optional second argument is the port number, which
|
||||
+ defaults to the standard telnet port (23).
|
||||
+
|
||||
+ Don't try to reopen an already connected instance.
|
||||
+ """
|
||||
+ self.eof = 0
|
||||
+ if not port:
|
||||
+ port = TELNET_PORT
|
||||
+ self.host = host
|
||||
+ self.port = port
|
||||
+ self.timeout = timeout
|
||||
+ sys.audit("telnetlib.Telnet.open", self, host, port)
|
||||
+ self.sock = socket.create_connection((host, port), timeout)
|
||||
+
|
||||
+ def __del__(self):
|
||||
+ """Destructor -- close the connection."""
|
||||
+ self.close()
|
||||
+
|
||||
+ def msg(self, msg, *args):
|
||||
+ """Print a debug message, when the debug level is > 0.
|
||||
+
|
||||
+ If extra arguments are present, they are substituted in the
|
||||
+ message using the standard string formatting operator.
|
||||
+
|
||||
+ """
|
||||
+ if self.debuglevel > 0:
|
||||
+ print('Telnet(%s,%s):' % (self.host, self.port), end=' ')
|
||||
+ if args:
|
||||
+ print(msg % args)
|
||||
+ else:
|
||||
+ print(msg)
|
||||
+
|
||||
+ def set_debuglevel(self, debuglevel):
|
||||
+ """Set the debug level.
|
||||
+
|
||||
+ The higher it is, the more debug output you get (on sys.stdout).
|
||||
+
|
||||
+ """
|
||||
+ self.debuglevel = debuglevel
|
||||
+
|
||||
+ def close(self):
|
||||
+ """Close the connection."""
|
||||
+ sock = self.sock
|
||||
+ self.sock = None
|
||||
+ self.eof = True
|
||||
+ self.iacseq = b''
|
||||
+ self.sb = 0
|
||||
+ if sock:
|
||||
+ sock.close()
|
||||
+
|
||||
+ def get_socket(self):
|
||||
+ """Return the socket object used internally."""
|
||||
+ return self.sock
|
||||
+
|
||||
+ def fileno(self):
|
||||
+ """Return the fileno() of the socket object used internally."""
|
||||
+ return self.sock.fileno()
|
||||
+
|
||||
+ def write(self, buffer):
|
||||
+ """Write a string to the socket, doubling any IAC characters.
|
||||
+
|
||||
+ Can block if the connection is blocked. May raise
|
||||
+ OSError if the connection is closed.
|
||||
+
|
||||
+ """
|
||||
+ if IAC in buffer:
|
||||
+ buffer = buffer.replace(IAC, IAC+IAC)
|
||||
+ sys.audit("telnetlib.Telnet.write", self, buffer)
|
||||
+ self.msg("send %r", buffer)
|
||||
+ self.sock.sendall(buffer)
|
||||
+
|
||||
+ def read_until(self, match, timeout=None):
|
||||
+ """Read until a given string is encountered or until timeout.
|
||||
+
|
||||
+ When no match is found, return whatever is available instead,
|
||||
+ possibly the empty string. Raise EOFError if the connection
|
||||
+ is closed and no cooked data is available.
|
||||
+
|
||||
+ """
|
||||
+ n = len(match)
|
||||
+ self.process_rawq()
|
||||
+ i = self.cookedq.find(match)
|
||||
+ if i >= 0:
|
||||
+ i = i+n
|
||||
+ buf = self.cookedq[:i]
|
||||
+ self.cookedq = self.cookedq[i:]
|
||||
+ return buf
|
||||
+ if timeout is not None:
|
||||
+ deadline = _time() + timeout
|
||||
+ with _TelnetSelector() as selector:
|
||||
+ selector.register(self, selectors.EVENT_READ)
|
||||
+ while not self.eof:
|
||||
+ if selector.select(timeout):
|
||||
+ i = max(0, len(self.cookedq)-n)
|
||||
+ self.fill_rawq()
|
||||
+ self.process_rawq()
|
||||
+ i = self.cookedq.find(match, i)
|
||||
+ if i >= 0:
|
||||
+ i = i+n
|
||||
+ buf = self.cookedq[:i]
|
||||
+ self.cookedq = self.cookedq[i:]
|
||||
+ return buf
|
||||
+ if timeout is not None:
|
||||
+ timeout = deadline - _time()
|
||||
+ if timeout < 0:
|
||||
+ break
|
||||
+ return self.read_very_lazy()
|
||||
+
|
||||
+ def read_all(self):
|
||||
+ """Read all data until EOF; block until connection closed."""
|
||||
+ self.process_rawq()
|
||||
+ while not self.eof:
|
||||
+ self.fill_rawq()
|
||||
+ self.process_rawq()
|
||||
+ buf = self.cookedq
|
||||
+ self.cookedq = b''
|
||||
+ return buf
|
||||
+
|
||||
+ def read_some(self):
|
||||
+ """Read at least one byte of cooked data unless EOF is hit.
|
||||
+
|
||||
+ Return b'' if EOF is hit. Block if no data is immediately
|
||||
+ available.
|
||||
+
|
||||
+ """
|
||||
+ self.process_rawq()
|
||||
+ while not self.cookedq and not self.eof:
|
||||
+ self.fill_rawq()
|
||||
+ self.process_rawq()
|
||||
+ buf = self.cookedq
|
||||
+ self.cookedq = b''
|
||||
+ return buf
|
||||
+
|
||||
+ def read_very_eager(self):
|
||||
+ """Read everything that's possible without blocking in I/O (eager).
|
||||
+
|
||||
+ Raise EOFError if connection closed and no cooked data
|
||||
+ available. Return b'' if no cooked data available otherwise.
|
||||
+ Don't block unless in the midst of an IAC sequence.
|
||||
+
|
||||
+ """
|
||||
+ self.process_rawq()
|
||||
+ while not self.eof and self.sock_avail():
|
||||
+ self.fill_rawq()
|
||||
+ self.process_rawq()
|
||||
+ return self.read_very_lazy()
|
||||
+
|
||||
+ def read_eager(self):
|
||||
+ """Read readily available data.
|
||||
+
|
||||
+ Raise EOFError if connection closed and no cooked data
|
||||
+ available. Return b'' if no cooked data available otherwise.
|
||||
+ Don't block unless in the midst of an IAC sequence.
|
||||
+
|
||||
+ """
|
||||
+ self.process_rawq()
|
||||
+ while not self.cookedq and not self.eof and self.sock_avail():
|
||||
+ self.fill_rawq()
|
||||
+ self.process_rawq()
|
||||
+ return self.read_very_lazy()
|
||||
+
|
||||
+ def read_lazy(self):
|
||||
+ """Process and return data that's already in the queues (lazy).
|
||||
+
|
||||
+ Raise EOFError if connection closed and no data available.
|
||||
+ Return b'' if no cooked data available otherwise. Don't block
|
||||
+ unless in the midst of an IAC sequence.
|
||||
+
|
||||
+ """
|
||||
+ self.process_rawq()
|
||||
+ return self.read_very_lazy()
|
||||
+
|
||||
+ def read_very_lazy(self):
|
||||
+ """Return any data available in the cooked queue (very lazy).
|
||||
+
|
||||
+ Raise EOFError if connection closed and no data available.
|
||||
+ Return b'' if no cooked data available otherwise. Don't block.
|
||||
+
|
||||
+ """
|
||||
+ buf = self.cookedq
|
||||
+ self.cookedq = b''
|
||||
+ if not buf and self.eof and not self.rawq:
|
||||
+ raise EOFError('telnet connection closed')
|
||||
+ return buf
|
||||
+
|
||||
+ def read_sb_data(self):
|
||||
+ """Return any data available in the SB ... SE queue.
|
||||
+
|
||||
+ Return b'' if no SB ... SE available. Should only be called
|
||||
+ after seeing a SB or SE command. When a new SB command is
|
||||
+ found, old unread SB data will be discarded. Don't block.
|
||||
+
|
||||
+ """
|
||||
+ buf = self.sbdataq
|
||||
+ self.sbdataq = b''
|
||||
+ return buf
|
||||
+
|
||||
+ def set_option_negotiation_callback(self, callback):
|
||||
+ """Provide a callback function called after each receipt of a telnet option."""
|
||||
+ self.option_callback = callback
|
||||
+
|
||||
+ def process_rawq(self):
|
||||
+ """Transfer from raw queue to cooked queue.
|
||||
+
|
||||
+ Set self.eof when connection is closed. Don't block unless in
|
||||
+ the midst of an IAC sequence.
|
||||
+
|
||||
+ """
|
||||
+ buf = [b'', b'']
|
||||
+ try:
|
||||
+ while self.rawq:
|
||||
+ c = self.rawq_getchar()
|
||||
+ if not self.iacseq:
|
||||
+ if c == theNULL:
|
||||
+ continue
|
||||
+ if c == b"\021":
|
||||
+ continue
|
||||
+ if c != IAC:
|
||||
+ buf[self.sb] = buf[self.sb] + c
|
||||
+ continue
|
||||
+ else:
|
||||
+ self.iacseq += c
|
||||
+ elif len(self.iacseq) == 1:
|
||||
+ # 'IAC: IAC CMD [OPTION only for WILL/WONT/DO/DONT]'
|
||||
+ if c in (DO, DONT, WILL, WONT):
|
||||
+ self.iacseq += c
|
||||
+ continue
|
||||
+
|
||||
+ self.iacseq = b''
|
||||
+ if c == IAC:
|
||||
+ buf[self.sb] = buf[self.sb] + c
|
||||
+ else:
|
||||
+ if c == SB: # SB ... SE start.
|
||||
+ self.sb = 1
|
||||
+ self.sbdataq = b''
|
||||
+ elif c == SE:
|
||||
+ self.sb = 0
|
||||
+ self.sbdataq = self.sbdataq + buf[1]
|
||||
+ buf[1] = b''
|
||||
+ if self.option_callback:
|
||||
+ # Callback is supposed to look into
|
||||
+ # the sbdataq
|
||||
+ self.option_callback(self.sock, c, NOOPT)
|
||||
+ else:
|
||||
+ # We can't offer automatic processing of
|
||||
+ # suboptions. Alas, we should not get any
|
||||
+ # unless we did a WILL/DO before.
|
||||
+ self.msg('IAC %d not recognized' % ord(c))
|
||||
+ elif len(self.iacseq) == 2:
|
||||
+ cmd = self.iacseq[1:2]
|
||||
+ self.iacseq = b''
|
||||
+ opt = c
|
||||
+ if cmd in (DO, DONT):
|
||||
+ self.msg('IAC %s %d',
|
||||
+ cmd == DO and 'DO' or 'DONT', ord(opt))
|
||||
+ if self.option_callback:
|
||||
+ self.option_callback(self.sock, cmd, opt)
|
||||
+ else:
|
||||
+ self.sock.sendall(IAC + WONT + opt)
|
||||
+ elif cmd in (WILL, WONT):
|
||||
+ self.msg('IAC %s %d',
|
||||
+ cmd == WILL and 'WILL' or 'WONT', ord(opt))
|
||||
+ if self.option_callback:
|
||||
+ self.option_callback(self.sock, cmd, opt)
|
||||
+ else:
|
||||
+ self.sock.sendall(IAC + DONT + opt)
|
||||
+ except EOFError: # raised by self.rawq_getchar()
|
||||
+ self.iacseq = b'' # Reset on EOF
|
||||
+ self.sb = 0
|
||||
+ pass
|
||||
+ self.cookedq = self.cookedq + buf[0]
|
||||
+ self.sbdataq = self.sbdataq + buf[1]
|
||||
+
|
||||
+ def rawq_getchar(self):
|
||||
+ """Get next char from raw queue.
|
||||
+
|
||||
+ Block if no data is immediately available. Raise EOFError
|
||||
+ when connection is closed.
|
||||
+
|
||||
+ """
|
||||
+ if not self.rawq:
|
||||
+ self.fill_rawq()
|
||||
+ if self.eof:
|
||||
+ raise EOFError
|
||||
+ c = self.rawq[self.irawq:self.irawq+1]
|
||||
+ self.irawq = self.irawq + 1
|
||||
+ if self.irawq >= len(self.rawq):
|
||||
+ self.rawq = b''
|
||||
+ self.irawq = 0
|
||||
+ return c
|
||||
+
|
||||
+ def fill_rawq(self):
|
||||
+ """Fill raw queue from exactly one recv() system call.
|
||||
+
|
||||
+ Block if no data is immediately available. Set self.eof when
|
||||
+ connection is closed.
|
||||
+
|
||||
+ """
|
||||
+ if self.irawq >= len(self.rawq):
|
||||
+ self.rawq = b''
|
||||
+ self.irawq = 0
|
||||
+ # The buffer size should be fairly small so as to avoid quadratic
|
||||
+ # behavior in process_rawq() above
|
||||
+ buf = self.sock.recv(50)
|
||||
+ self.msg("recv %r", buf)
|
||||
+ self.eof = (not buf)
|
||||
+ self.rawq = self.rawq + buf
|
||||
+
|
||||
+ def sock_avail(self):
|
||||
+ """Test whether data is available on the socket."""
|
||||
+ with _TelnetSelector() as selector:
|
||||
+ selector.register(self, selectors.EVENT_READ)
|
||||
+ return bool(selector.select(0))
|
||||
+
|
||||
+ def interact(self):
|
||||
+ """Interaction function, emulates a very dumb telnet client."""
|
||||
+ if sys.platform == "win32":
|
||||
+ self.mt_interact()
|
||||
+ return
|
||||
+ with _TelnetSelector() as selector:
|
||||
+ selector.register(self, selectors.EVENT_READ)
|
||||
+ selector.register(sys.stdin, selectors.EVENT_READ)
|
||||
+
|
||||
+ while True:
|
||||
+ for key, events in selector.select():
|
||||
+ if key.fileobj is self:
|
||||
+ try:
|
||||
+ text = self.read_eager()
|
||||
+ except EOFError:
|
||||
+ print('*** Connection closed by remote host ***')
|
||||
+ return
|
||||
+ if text:
|
||||
+ sys.stdout.write(text.decode('ascii'))
|
||||
+ sys.stdout.flush()
|
||||
+ elif key.fileobj is sys.stdin:
|
||||
+ line = sys.stdin.readline().encode('ascii')
|
||||
+ if not line:
|
||||
+ return
|
||||
+ self.write(line)
|
||||
+
|
||||
+ def mt_interact(self):
|
||||
+ """Multithreaded version of interact()."""
|
||||
+ import _thread
|
||||
+ _thread.start_new_thread(self.listener, ())
|
||||
+ while 1:
|
||||
+ line = sys.stdin.readline()
|
||||
+ if not line:
|
||||
+ break
|
||||
+ self.write(line.encode('ascii'))
|
||||
+
|
||||
+ def listener(self):
|
||||
+ """Helper for mt_interact() -- this executes in the other thread."""
|
||||
+ while 1:
|
||||
+ try:
|
||||
+ data = self.read_eager()
|
||||
+ except EOFError:
|
||||
+ print('*** Connection closed by remote host ***')
|
||||
+ return
|
||||
+ if data:
|
||||
+ sys.stdout.write(data.decode('ascii'))
|
||||
+ else:
|
||||
+ sys.stdout.flush()
|
||||
+
|
||||
+ def expect(self, list, timeout=None):
|
||||
+ """Read until one from a list of a regular expressions matches.
|
||||
+
|
||||
+ The first argument is a list of regular expressions, either
|
||||
+ compiled (re.Pattern instances) or uncompiled (strings).
|
||||
+ The optional second argument is a timeout, in seconds; default
|
||||
+ is no timeout.
|
||||
+
|
||||
+ Return a tuple of three items: the index in the list of the
|
||||
+ first regular expression that matches; the re.Match object
|
||||
+ returned; and the text read up till and including the match.
|
||||
+
|
||||
+ If EOF is read and no text was read, raise EOFError.
|
||||
+ Otherwise, when nothing matches, return (-1, None, text) where
|
||||
+ text is the text received so far (may be the empty string if a
|
||||
+ timeout happened).
|
||||
+
|
||||
+ If a regular expression ends with a greedy match (e.g. '.*')
|
||||
+ or if more than one expression can match the same input, the
|
||||
+ results are undeterministic, and may depend on the I/O timing.
|
||||
+
|
||||
+ """
|
||||
+ re = None
|
||||
+ list = list[:]
|
||||
+ indices = range(len(list))
|
||||
+ for i in indices:
|
||||
+ if not hasattr(list[i], "search"):
|
||||
+ if not re: import re
|
||||
+ list[i] = re.compile(list[i])
|
||||
+ if timeout is not None:
|
||||
+ deadline = _time() + timeout
|
||||
+ with _TelnetSelector() as selector:
|
||||
+ selector.register(self, selectors.EVENT_READ)
|
||||
+ while not self.eof:
|
||||
+ self.process_rawq()
|
||||
+ for i in indices:
|
||||
+ m = list[i].search(self.cookedq)
|
||||
+ if m:
|
||||
+ e = m.end()
|
||||
+ text = self.cookedq[:e]
|
||||
+ self.cookedq = self.cookedq[e:]
|
||||
+ return (i, m, text)
|
||||
+ if timeout is not None:
|
||||
+ ready = selector.select(timeout)
|
||||
+ timeout = deadline - _time()
|
||||
+ if not ready:
|
||||
+ if timeout < 0:
|
||||
+ break
|
||||
+ else:
|
||||
+ continue
|
||||
+ self.fill_rawq()
|
||||
+ text = self.read_very_lazy()
|
||||
+ if not text and self.eof:
|
||||
+ raise EOFError
|
||||
+ return (-1, None, text)
|
||||
+
|
||||
+ def __enter__(self):
|
||||
+ return self
|
||||
+
|
||||
+ def __exit__(self, type, value, traceback):
|
||||
+ self.close()
|
||||
+
|
||||
+
|
||||
+def test():
|
||||
+ """Test program for telnetlib.
|
||||
+
|
||||
+ Usage: python telnetlib.py [-d] ... [host [port]]
|
||||
+
|
||||
+ Default host is localhost; default port is 23.
|
||||
+
|
||||
+ """
|
||||
+ debuglevel = 0
|
||||
+ while sys.argv[1:] and sys.argv[1] == '-d':
|
||||
+ debuglevel = debuglevel+1
|
||||
+ del sys.argv[1]
|
||||
+ host = 'localhost'
|
||||
+ if sys.argv[1:]:
|
||||
+ host = sys.argv[1]
|
||||
+ port = 0
|
||||
+ if sys.argv[2:]:
|
||||
+ portstr = sys.argv[2]
|
||||
+ try:
|
||||
+ port = int(portstr)
|
||||
+ except ValueError:
|
||||
+ port = socket.getservbyname(portstr, 'tcp')
|
||||
+ with Telnet() as tn:
|
||||
+ tn.set_debuglevel(debuglevel)
|
||||
+ tn.open(host, port, timeout=0.5)
|
||||
+ tn.interact()
|
||||
+
|
||||
+if __name__ == '__main__':
|
||||
+ test()
|
||||
diff --git a/scripts/python/module/setup.py.in b/scripts/python/module/setup.py.in
|
||||
index 18f956d20c..c6276fd2f2 100644
|
||||
--- a/scripts/python/module/setup.py.in
|
||||
+++ b/scripts/python/module/setup.py.in
|
||||
@@ -30,7 +30,11 @@ setup(
|
||||
#data_files = [('', ['tox.ini'])],
|
||||
#scripts = ['PyNUTClient/test_nutclient.py', 'PyNUTClient/__init__.py'],
|
||||
python_requires = '>=2.6',
|
||||
- # install_requires = ['telnetlib'], # NOTE: telnetlib.py is part of Python core for tested 2.x and 3.x versions, not something 'pip' can download
|
||||
+ # NOTE: telnetlib.py is part of Python core for tested 2.x and 3.x versions,
|
||||
+ # not something 'pip' can download as a package. It is deprecated since 3.11
|
||||
+ # and removed since 3.13, so as a hotfix, NUT provides a copy nut_telnetlib.py
|
||||
+ # (taken from Python 3.10 - the latest one without a deprecation warning).
|
||||
+ # install_requires = ['telnetlib'],
|
||||
keywords = ['pypi', 'cicd', 'python', 'nut', 'Network UPS Tools'],
|
||||
classifiers = [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
@@ -1,37 +0,0 @@
|
||||
From d0a234ac4fe9304c4178256584712e4359541060 Mon Sep 17 00:00:00 2001
|
||||
From: Jim Klimov <jimklimov+nut@gmail.com>
|
||||
Date: Wed, 3 Jul 2024 09:51:07 +0200
|
||||
Subject: [PATCH] configure.ac: typo in path to test with nut_telnetlib Python
|
||||
module [#2183]
|
||||
|
||||
Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
|
||||
|
||||
Upstream: https://github.com/networkupstools/nut/commit/d0a234ac4fe9304c4178256584712e4359541060
|
||||
|
||||
Signed-off-by: Bernd Kuhls <bernd@kuhls.net>
|
||||
---
|
||||
configure.ac | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 935e73d368..e542baacd2 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -2474,7 +2474,7 @@ if test x"${nut_with_pynut}" != xno \
|
||||
dnl this line essentially checks for presence of
|
||||
dnl a usable interpreter implementation compatible
|
||||
dnl with Python 3.x syntax.
|
||||
- if (cd script/python/module && ${PYTHON3} -c "import nut_telnetlib as telnetlib") \
|
||||
+ if (cd scripts/python/module && ${PYTHON3} -c "import nut_telnetlib as telnetlib") \
|
||||
; then
|
||||
nut_with_pynut_py3="yes"
|
||||
fi
|
||||
@@ -2491,7 +2491,7 @@ if test x"${nut_with_pynut}" != xno \
|
||||
nut_with_pynut_py="yes"
|
||||
else
|
||||
dnl See comments above
|
||||
- if (cd script/python/module && ${PYTHON} -c "import nut_telnetlib as telnetlib") \
|
||||
+ if (cd scripts/python/module && ${PYTHON} -c "import nut_telnetlib as telnetlib") \
|
||||
; then
|
||||
nut_with_pynut_py="yes"
|
||||
fi
|
||||
@@ -1,39 +0,0 @@
|
||||
From 2898a45a83d7f9af62fe0844fcb5358337d905d3 Mon Sep 17 00:00:00 2001
|
||||
From: Jim Klimov <jimklimov+nut@gmail.com>
|
||||
Date: Wed, 3 Jul 2024 10:22:24 +0200
|
||||
Subject: [PATCH] configure.ac: be sure to probe nut_telnetlib module from
|
||||
source dir [#2183]
|
||||
|
||||
Avoid confusion for out-of-tree builds
|
||||
|
||||
Signed-off-by: Jim Klimov <jimklimov+nut@gmail.com>
|
||||
|
||||
Upstream: https://github.com/networkupstools/nut/commit/2898a45a83d7f9af62fe0844fcb5358337d905d3
|
||||
|
||||
Signed-off-by: Bernd Kuhls <bernd@kuhls.net>
|
||||
---
|
||||
configure.ac | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 5865ad5fe3..9d622c34fc 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -2474,7 +2474,7 @@ if test x"${nut_with_pynut}" != xno \
|
||||
dnl this line essentially checks for presence of
|
||||
dnl a usable interpreter implementation compatible
|
||||
dnl with Python 3.x syntax.
|
||||
- if (cd scripts/python/module && ${PYTHON3} -c "import nut_telnetlib as telnetlib") \
|
||||
+ if (cd "${srcdir}"/scripts/python/module && ${PYTHON3} -c "import nut_telnetlib as telnetlib") \
|
||||
; then
|
||||
nut_with_pynut_py3="yes"
|
||||
fi
|
||||
@@ -2491,7 +2491,7 @@ if test x"${nut_with_pynut}" != xno \
|
||||
nut_with_pynut_py="yes"
|
||||
else
|
||||
dnl See comments above
|
||||
- if (cd scripts/python/module && ${PYTHON} -c "import nut_telnetlib as telnetlib") \
|
||||
+ if (cd "${srcdir}"/scripts/python/module && ${PYTHON} -c "import nut_telnetlib as telnetlib") \
|
||||
; then
|
||||
nut_with_pynut_py="yes"
|
||||
fi
|
||||
@@ -1,7 +1,7 @@
|
||||
# From https://github.com/networkupstools/nut/releases/download/v2.8.2/nut-2.8.2.tar.gz.sha256
|
||||
sha256 e4b4b0cbe7dd39ba9097be7f7d787bb2fffbe35df64dff53b5fe393d659c597d nut-2.8.2.tar.gz
|
||||
# From https://github.com/networkupstools/nut/releases/download/v2.8.3/nut-2.8.3.tar.gz.sha256
|
||||
sha256 d6ca17f0b39003bac7649eb17ab4a713e4d5fcaa8fd1aedca28357d59df095ed nut-2.8.3.tar.gz
|
||||
|
||||
# Locally computed
|
||||
sha256 8a3de48b86daffcbe822dd94e514c8a77fe70f77c9005ffd9dcf1709dbdc80c7 COPYING
|
||||
sha256 40885775f43463c404d74bbd00a59fac6c0fe73f838d4520472d721917412577 COPYING
|
||||
sha256 ab15fd526bd8dd18a9e77ebc139656bf4d33e97fc7238cd11bf60e2b9b8666c6 LICENSE-GPL2
|
||||
sha256 fc82ca8b6fdb18d4e3e85cfd8ab58d1bcd3f1b29abe782895abd91d64763f8e7 LICENSE-GPL3
|
||||
|
||||
@@ -4,17 +4,13 @@
|
||||
#
|
||||
################################################################################
|
||||
|
||||
NUT_VERSION = 2.8.2
|
||||
NUT_VERSION = 2.8.3
|
||||
NUT_SITE = https://github.com/networkupstools/nut/releases/download/v$(NUT_VERSION)
|
||||
NUT_LICENSE = GPL-2.0+, GPL-3.0+ (python scripts), GPL/Artistic (perl client)
|
||||
NUT_LICENSE_FILES = COPYING LICENSE-GPL2 LICENSE-GPL3
|
||||
NUT_SELINUX_MODULES = apache nut
|
||||
NUT_INSTALL_STAGING = YES
|
||||
NUT_DEPENDENCIES = host-pkgconf
|
||||
# 0001-Provide-a-private-copy-of-telnetlib-for-PyNUTClient.patch
|
||||
# 0002-configure-ac-typo-in-path-to-test-with-nut_telnetlib-Python-module.patch
|
||||
# 0003-configure.ac-be-sure-to-probe-nut_telnetlib-module-from-source-dir.patch
|
||||
NUT_AUTORECONF = YES
|
||||
|
||||
# Put the PID files in a read-write place (/var/run is a tmpfs)
|
||||
# since the default location (/var/state/ups) maybe readonly.
|
||||
@@ -28,6 +24,7 @@ NUT_CONF_OPTS = \
|
||||
--with-group=nut
|
||||
|
||||
NUT_CONF_ENV = \
|
||||
PKG_CONFIG_LIBDIR=$(STAGING_DIR)/usr/lib/pkgconfig:$(STAGING_DIR)/usr/share/pkgconfig \
|
||||
ax_cv_check_cflags__Werror__Wno_unknown_warning_option=no \
|
||||
ax_cv_check_cxxflags__Werror__Wno_unknown_warning_option=no \
|
||||
ac_cv_func_strcasecmp=yes \
|
||||
|
||||
Reference in New Issue
Block a user