nslink
The package downloads source code from a plausible project-owned host (pepperl-fuchs.com) for building a kernel driver; this is normal AUR packaging behavior despite the non-whitelisted domain, and no untrusted executables are run.
Triggered rules
llm_review
The static rules flagged this MEDIUM, but an AI model (qwen/qwen3-235b-a22b-07-25) reviewed the full PKGBUILD and judged it LOW (confidence 90%): The package downloads source code from a plausible project-owned host (pepperl-fuchs.com) for building a kernel driver; this is normal AUR packaging behavior despite the non-whitelisted domain, and no untrusted executables are run.
1 higher static finding superseded - not the current verdict (shown for transparency)
source_untrusted_domain
One or more source=() URLs point to a host outside the trusted allowlist (github.com, gitlab.com, codeberg.org, pypi.org, …).
-
PKGBUILD:49
"devicemaster-linux-${pkgver}-${_dl}.zip::https://files.pepperl-fuchs.com/webcat/navi/productInfo/18/${_dl}.zip" -
PKGBUILD:53
'https://downloads.comtrol.com/dev_mstr/rts/utility/linux_firmware_uploader/DM-Firmware-Updater-1.06.tar.gz'
PKGBUILD
2 offending line(s) highlighted# Maintainer: Chris Severance aur.severach aATt spamgourmet dott com
_opt_DKMS=1 # This can be toggled between installs
_opt_defaultmode='660' # default: 620
#export KERNELRELEASE="$(basename $(dirname /usr/lib/modules/6.12.*/modules.alias))"
# Todo: Test secure mode
# Todo: python tools should be updated to python3
# Todo: nslinktool Config Driver needs an up down button to reorder entries
# Todo: TUI firmware updater.
# Todo: Firmware updater can't update unit set to DHCP.
# Todo: Firmware updater errors out on old versions: Expected to connect to bootloader after reboot but found DeviceMaster Boot Version 1.20
# Todo: Comtrol icons for nslinktool and the firmware updater
# Todo: nslinktool set the mouse pointer to a spinning circle far too long after startup
# Todo: rm /dev/ttySI* on rmmod nslink
# Todo: When characters are held by RTS low, opening ttySI* raises RTS too soon and some characters are lost
# Todo: nslinktool, HUB IP Admin, [Get] with SocketServer, error getting IP info, did not get ip6info reply
# Uninstall cleanup: sudo rm -f /etc/nslink.conf*
# Configure with the NS-Link Manager GUI, Config Driver
# Ports are /dev/ttySI0 through /dev/ttySI31
set -u
pkgname='nslink'
pkgver='8.12'; _dl='1833783f'
pkgrel='1'
pkgdesc='tty driver and firmware update for Comtrol DeviceMaster, RTS, LT, PRO, 500, UP, RPSH-SI, RPSH, and Serial port Hub console terminal device server'
# UP is not explicitly supported by NS-Link, only by the firmware updater.
_pkgdescshort="Comtrol DeviceMaster ${pkgname} TTY driver"
arch=('i686' 'x86_64')
#url='http://www.comtrol.com/'
url='https://www.pepperl-fuchs.com/global/en/classid_8222.htm'
license=('GPL')
depends=('glibc' 'openssl' 'python3' 'sed' 'groff' 'tcl' 'tk' 'util-linux') # python is also needed for the firmware updater
optdepends=(
'gksu: NS-Link Manager GUI'
)
backup=('etc/nslink.conf')
options=('!zipman' '!strip')
install="${pkgname}-install.sh"
#_verwatch=('http://downloads.comtrol.com/html/DM_PRO_RTS_SERIALHUB_drivers.htm' '.*/devicemaster-linux-\([0-9\.]\+\)\.tar\.gz' 'l')
_srcdir="devicemaster-linux-${pkgver}"
_srcdir_dm='DM-Firmware-Updater-1.06' # http://downloads.comtrol.com/html/DM_PRO_RTS_SERIALHUB_pvdx2.htm
source=(
"devicemaster-linux-${pkgver}-${_dl}.zip::https://files.pepperl-fuchs.com/webcat/navi/productInfo/18/${_dl}.zip"
#"ftp://ftp.comtrol.com/dev_mstr/rts/drivers/linux/devicemaster-linux-${pkgver}.tar.gz"
#"https://downloads.comtrol.com/dev_mstr/rts/drivers/linux/devicemaster-linux-${pkgver}.tar.gz"
#'ftp://ftp.comtrol.com/dev_mstr/rts/utility/linux_firmware_uploader/DM-Firmware-Updater-1.06.tar.gz'
'https://downloads.comtrol.com/dev_mstr/rts/utility/linux_firmware_uploader/DM-Firmware-Updater-1.06.tar.gz'
'dmupdate.py.usage.patch'
'0002-kernel-5.6-proc_dir_entry-proc_ops.patch'
'0003-tty_unregister_driver-void.patch'
'0004-kernel-5.12-tty-low_latency.patch'
'0005-kernel-5.14-unsigned-tty-flow-tty.patch'
'0006-kernel-5.15-alloc_tty_driver-put_tty_driver.patch'
'0007-service-priority.patch'
'0008-python3-firmware.patch'
'0009-python3-nslink.patch'
'0010-kernel-6.1-TTY_DRIVER_MAGIC-remove-dead-code.patch'
'0011-kernel-6.0-set_termios-const-ktermios.patch'
'0012-kernel-6.6-struct-tty_operations-write-size_t.patch'
'0013-kernel-6.3-tty_port_operations-int-to-bool.patch'
'0014-kernel-6.8-tty_driver.h-send_xchar-to-u8.patch'
)
md5sums=('e5d1a3959fb63c2c70bab9da47af3bb4'
'e3ffb36acfdd321c919e44d477f0774a'
'581cd5f582ed20c7cf85a4df23a9f78a'
'dd44ac32eb3632120258cc4727221e15'
'23414fe236ef697e39f9bf6c26e482d9'
'26cd5af09d89c1b48a33fcbee00ce248'
'59e2c6d076c5346807088899bd05df3b'
'3cbb73aa4cdd04374744651ae5475b3c'
'e5692035f047cdec52658f67954c6f4d'
'8c329cf0f9c90cfd07ba86a4027eec48'
'e21d8211b2f209ace648340cb5583805'
'2774e3aa64717a7613e96fd86f649ea1'
'98788ff1378604e9fda43eb6ef9e9e3d'
'feb1ccc7522a6ac2b33326c7f648edb2'
'1ff77ae8edbcd654c680999eadd4911b'
'ed93e16d8cbac647e69a473359991c2d')
sha256sums=('0d3e75732edda607006f04baa50d8d3c1b44df26e4535de47dffb341da9e99d1'
'd21c5eeefdbf08a202a230454f0bf702221686ba3e663eb41852719bb20b75fb'
'5a4e2713a8d1fe0eebd94fc843839ce5daa647f9fa7d88f62507e660ae111073'
'9fe2680244ce4e5dc933e028a5e7944a912c2980a91cee92509904ede2cf8bea'
'de8de0c17c8075bbd792d271a869c5248063bf7126c60c61f37d833ee7f57fb7'
'79d86016eb5b2e80fd97350986fcd3c3050f10eb6fbe50f69b7fb454c8c049fa'
'13ec641d2371bb5fe4d4e745b95c2722652fc5bdb7ceef5a48882f9977b0c0ca'
'4411ef239ab5d8b227f08dc37ee33dc0a21ca9b98f03f39e90ea396d04127bdf'
'bfa34783131c52e0bc0645c76469aaf504b13ac16d57b02d5ea9002603fb583e'
'1353bc403b56ef0b00f4b87826991812ee24bcc9a0b2612c0027317a7aa86736'
'a84e1a9884580917afe55816b4ec9b44ec0f4977144e7f4325647ff58642ecd6'
'2b909997f0662ae9a49463be4c1ef2af718882924071e0d74b9c04d9d1198691'
'7f181d1542b542989b319caf85621725389d7681cf2d5c3bb57dc774d14f1b76'
'5a62d3658d716c8140de65c2ac2e2560ca33f0f2a58212e29df74eadb821b6ce'
'4c605df9b08ea2be3b3c94a2dab8554902ff15576a7075c597453306c275e3e2'
'4ec33cda5131d1502ad46a26de68f0ae579e050e9ed7a111d7f9285caf972221')
if [ "${_opt_DKMS}" -ne 0 ]; then
depends+=('linux' 'dkms' 'linux-headers')
else
makedepends+=('linux-headers')
fi
prepare() {
set -u
set -x
# Pacman v7.0.0 makepkg won't unpack zip files
bsdtar -xf "${source[0]%%::*}"
if [ ! -d "${_srcdir}" ]; then
find -type 'f' -name "${_srcdir}.tar.gz" -exec bsdtar -xf '{}' ';' -quit
fi
set +x
cd "${_srcdir}"
# Fix permissions
find -type 'f' -perm '/111' -exec chmod 644 '{}' '+'
chmod 755 *.sh *.py 'nslinktool'
# Version check
local _ver
_ver="$(sed -n -e 's:^#define\sSI_VERSION\s"\([^"]\+\).*$:\1:p' 'version.h')"
if [ "${pkgver}" != "${_ver}" ]; then
echo "Version mismatch ${pkgver} != ${_ver}"
set +u
false
fi
unset _ver
local _patches=()
#_patches+=('0002-kernel-5.6-proc_dir_entry-proc_ops.patch')
#_patches+=('0003-tty_unregister_driver-void.patch')
#_patches+=('0004-kernel-5.12-tty-low_latency.patch')
# tty.stopped https://lore.kernel.org/lkml/20210505091928.22010-13-jslaby@suse.cz/
# unsigned write_room https://www.spinics.net/lists/linux-serial/msg42297.html
# unsigned chars_in_buffer https://www.spinics.net/lists/linux-serial/msg42299.html
#_patches+=('0005-kernel-5.14-unsigned-tty-flow-tty.patch')
# http://lkml.iu.edu/hypermail/linux/kernel/2107.2/08799.html [PATCH 5/8] tty: drop alloc_tty_driver
# http://lkml.iu.edu/hypermail/linux/kernel/2107.2/08801.html [PATCH 7/8] tty: drop put_tty_driver
#_patches+=('0006-kernel-5.15-alloc_tty_driver-put_tty_driver.patch')
_patches+=('0007-service-priority.patch')
_patches+=('0009-python3-nslink.patch')
#_patches+=('0010-kernel-6.1-TTY_DRIVER_MAGIC-remove-dead-code.patch')
# https://lore.kernel.org/linux-arm-kernel/20220816115739.10928-9-ilpo.jarvinen@linux.intel.com/T/
#_patches+=('0011-kernel-6.0-set_termios-const-ktermios.patch')
#_patches+=('0012-kernel-6.6-struct-tty_operations-write-size_t.patch')
#_patches+=('0013-kernel-6.3-tty_port_operations-int-to-bool.patch')
#_patches+=('0014-kernel-6.8-tty_driver.h-send_xchar-to-u8.patch')
local _pt _ptf=() _pts=()
for _pt in "${_patches[@]}"; do
set +u; msg2 "Patch ${_pt}"; set -u
if patch -Nup1 --no-backup-if-mismatch -i "${srcdir}/${_pt}"; then
_pts+=("${_pt}")
else
_ptf+=("${_pt}")
fi
done
if [ "${#_ptf[@]}" -gt 0 ]; then
if [ "${#_pts[@]}" -gt 0 ]; then
printf 'Patch success %s\n' "${_pts[@]}"
printf 'Warning: Some old patches may need to be removed even if they are successful\n'
fi
printf 'Patch failed %s\n' "${_ptf[@]}"
set +x
false
fi
#cd '..'; cp -pr "${_srcdir}" 'a'; ln -s "${_srcdir}" 'b'; false
#diff -pNaru5 'a' 'b' > "0000-$RANDOM.patch"
# Make package compatible
#cp -p 'install.sh' 'install.sh.Arch' # testmode for diff comparison
sed -e '# Fix some paths' \
-e 's: /lib/: /usr/lib/:g' \
-e 's: /sbin: /usr/bin:g' \
-e 's:"/sbin:"/usr/bin:g' \
-e 's:/usr/sbin:/usr/bin:g' \
-e 's:/usr/local/man:/usr/share/man:g' \
-e '# I suspect this folder for systemd is wrong even on RedHat' \
-e 's:/etc/systemd/system:/usr/lib/systemd/system:g' \
-e '# make package compatible' \
-e 's:"/etc/:"${DESTDIR}/etc/:g' \
-e 's: /etc/: "${DESTDIR}"/etc/:g' \
-e 's:"/usr/:"${DESTDIR}/usr/:g' \
-e 's: /usr/: "${DESTDIR}"/usr/:g' \
-e '# Disable module management and message' \
-e 's:^\s\+echo\s-n\s"Rebuilding:# &:g' \
-e 's:^.*depmod -a:# &:g' \
-e '# Disable systemd management' \
-e 's:^\s\+systemctl:# &:g' \
-e '# Get rid of the start messages lest someone believes them' \
-e 's:^\s\+if\s\[\s"$WillStart"\s=\syes\s\]:return\n&:g' \
-i 'install.sh'
test ! -s 'install.sh.Arch' || echo "${}"
# Fix /var/run
sed -e 's:/var/run/:/run/:g' -i 'nslink.service'
# Switch to python2
sed -e '# Why using local on just this one?' \
-e '#s:/usr/local/bin/python:/usr/bin/python:g' \
-e '#s:/usr/bin/python:&2:g' \
-i *.py 'nslinktool'
# Branding in dmesg
sed -e '/^int nrp_init(/,/^}/ s:version %s %s:& Arch Linux:g' -i 'nslink.c'
grep -qFe 'Arch Linux' 'nslink.c' || echo "${}"
# Fix nslinktool. We'll get rid of the tabs while we're here.
expand -i 'nslinktool' | sed -e 's:\s\+$::g' > 'nslinktool.orig'
sed -e 's:/usr/local/man:/usr/share/man:g' 'nslinktool.orig' > 'nslinktool'
rm 'nslinktool.orig'
# Convert the live config entries to samples. This eliminates
# special handling for detecting a blank configuration.
sed -e 's:^[^#]:#&:g' -i 'nslink.conf'
# Fix makefile
#cp -p 'Makefile'{,.Arch}
sed -e 's:=/lib/modules:=/usr/lib/modules:g' \
-e '# Switch SUBDIRS= to M= for Kernel 5.4' \
-e 's:SUBDIRS=:M=:g' \
-e '# No DKMS instructions say to do this but it works and keeps the MAKE line real simple' \
-e 's:$(shell uname -r):$(KERNELRELEASE):g' \
-e 's:`uname -r`:$(KERNELRELEASE):g' \
-e '#s:$(KVER):$(KERNELRELEASE):g' \
-e '# Shift make executable to separate target' \
-e 's@^\tmake nslinkd@\nnslink:\n&@g' \
-e '1i KERNELRELEASE?=$(shell uname -r)' \
-i 'Makefile'
test ! -s 'Makefile.Arch'
# Correct group and chmod for serial
sed -e '/getgrnam/ s:"tty":"uucp":g' \
-e '# This method results in 666' \
-e '#s:\(mode_t mode\) = [0-9]\+\(.*;\)'":\1 = ${_opt_defaultmode}\2:g" \
-e "/mknod/ s:mode:0${_opt_defaultmode}:g" \
-i 'nslinkd.c'
# Fix up the firmware downloaders
cd "${srcdir}/${_srcdir_dm}"
# Fix permissions
find -type 'f' -perm '/111' -exec chmod 644 '{}' '+'
chmod 755 *.py
sed -e '# Cosmetic cleanup for simpler patch editing, trim space at eol' \
-e 's:\s\+$::g' \
-e '# Switch to python2' \
-e '#s:/usr/bin/python:&2:g' \
-i *.py
#rm -f *.orig; cd '..'; cp -pr 'DM-Firmware-Updater-1.06' 'a'; ln -s 'DM-Firmware-Updater-1.06' 'b'; false
#diff -pNaru5 'a' 'b' > '0008-python3-firmware.patch'
patch -Nup1 -i "${srcdir}/0008-python3-firmware.patch"
# Patch usage and help into command line tool
#diff -pNau5 dmupdate.py{.orig,} > '../dmupdate.py.usage.patch'
patch -Nup0 -i "${srcdir}/dmupdate.py.usage.patch"
set +u
}
build() {
set -u
cd "${_srcdir}"
set +u
if ! make -j1 QUIET=0 all nslink; then
warning 'a no such file or directory error means you need to reboot to load the updated kernel'
false
fi
}
package() {
set -u
cd "${_srcdir}"
if [ "${_opt_DKMS}" -eq 0 ]; then
# I don't want Linux version info showing on AUR web. After a few months 'linux<0.0.0' makes it look like an out of date package.
local _kernelversionsmall="$(uname -r)"
_kernelversionsmall="${_kernelversionsmall%%-*}"
_kernelversionsmall="${_kernelversionsmall%\.0}" # trim 4.0.0 -> 4.0, 4.1.0 -> 4.1
# prevent the mksrcinfo bash emulator from getting these vars!
#eval 'conf''licts=("linux>${_kernelversionsmall}" "linux<${_kernelversionsmall}")'
eval 'dep''ends+=("linux=${_kernelversionsmall}")'
fi
# This installer expects the system folders to already exist
install -dm755 "${pkgdir}"{'/usr/bin','/etc',"/usr/lib/modules/$(uname -r)/misc",'/usr/lib/systemd/system'}
DESTDIR="${pkgdir}" \
INIT='systemd' \
sh -e -u 'install.sh' "$(uname -r)" install | \
sed -e "s:${pkgdir}::g" # cleaner display
# Fix paths in the service file
sed -e 's:/sbin/:/usr/bin/:g' -i "${pkgdir}/usr/lib/systemd/system/nslink.service"
# Root only permissions on executables. Easier than hacking UID 0 into them.
find "${pkgdir}/usr/bin/" -type 'f' -perm /111 -exec chmod 744 '{}' '+'
# Preserve an original copy of the config file
install -Dpm644 "${pkgdir}/etc/nslink.conf" "${pkgdir}/usr/share/nslink/nslink.conf.orig"
# Desktop file for NS-Link
install -Dm644 <(cat << EOF
[Desktop Entry]
Name=Comtrol NS-Link Administration
GenericName=Device Server Manager
Comment=DeviceMaster NS-Link for Comtrol Device Servers
Exec=gksudo -k -u root nslinktool
Terminal=false
Type=Application
#Icon=
Categories=Application;Utilities;
MimeType=application/x-executable
EOF
) "${pkgdir}/usr/share/applications/nslinktool.desktop"
# DKMS
if [ "${_opt_DKMS}" -ne 0 ]; then
rm -r "${pkgdir}/usr/lib/modules/"
local _dkms="${pkgdir}/usr/src/${pkgname}-${pkgver}"
#install -d "${_dkms}"
install -Dm644 <(cat << EOF
# Automatically generated by ${pkgname}-${pkgver} PKGBUILD from Arch Linux AUR
# https://aur.archlinux.org/
PACKAGE_NAME="${pkgname}"
PACKAGE_VERSION="${pkgver}"
AUTOINSTALL="yes"
BUILT_MODULE_NAME[0]="nslink"
BUILT_MODULE_LOCATION[0]=""
# Using all processors doesn't compile this tiny module any faster.
MAKE[0]="make -j1 all QUIET=1"
CLEAN[0]="make -j1 clean"
# Placing the DKMS generated module in a different location than the standard install prevents conflicts when PKGBUILD _opt_DKMS is toggled
DEST_MODULE_LOCATION[0]="/kernel/drivers/misc"
EOF
) "${_dkms}/dkms.conf"
install -Dpm644 'nslink.h' 'nslink_int.h' 'version.h' 'nslink.c' 'Makefile' -t "${_dkms}"
#make -C "${_dkms}" clean
fi
# Install firmware updaters
cd "${srcdir}/${_srcdir_dm}"
install -Dpm755 *.py -t "${pkgdir}/usr/bin/"
install -Dpm644 'README.txt' -t "${pkgdir}/usr/share/nslink/"
# Desktop file for GUI firmware updater
install -Dm644 <(cat << EOF
[Desktop Entry]
Name=Comtrol Update Firmware
GenericName=Device Server Manager
Comment=Manage Firmware on Comtrol Device Servers
Exec=DM-Firmware-Updater.py
Terminal=false
Type=Application
#Icon=
Categories=Application;Utilities;
MimeType=application/x-executable
EOF
) "${pkgdir}/usr/share/applications/DM-Firmware-Updater.py.desktop"
set +u
}
set +u
Scan history
| Scanned at (UTC) | Severity | Rules |
|---|---|---|
| 2026-09-17 00:27:14 | Low | 2 |
| 2026-09-16 00:03:17 | Low | 2 |
| 2026-09-15 00:25:31 | Low | 2 |
| 2026-09-14 00:27:57 | Low | 2 |
| 2026-09-13 00:19:54 | Low | 2 |
| 2026-09-12 00:25:17 | Low | 2 |
| 2026-09-11 00:19:22 | Low | 2 |
| 2026-09-10 00:22:44 | Low | 2 |
| 2026-09-09 00:04:09 | Low | 2 |
| 2026-09-08 00:18:08 | Low | 2 |
| 2026-09-07 00:30:15 | Low | 2 |
| 2026-09-06 00:17:06 | Low | 2 |
| 2026-09-05 00:16:27 | Low | 2 |
| 2026-09-04 00:03:13 | Low | 2 |
| 2026-09-03 00:15:47 | Low | 2 |
| 2026-09-02 00:02:31 | Low | 2 |
| 2026-09-01 00:11:19 | Low | 2 |
| 2026-08-31 00:19:57 | Low | 2 |
| 2026-08-30 00:04:14 | Low | 2 |
| 2026-08-29 00:29:17 | Low | 2 |