0

I am trying to convert a systemd service to sysvinit, while trying to run the following service named mullvad-vpn;

#!/bin/sh
.....

. /lib/lsb/init-functions
prog=mullvad-daemon
PIDFILE=/var/run/$prog.pid
DESC="Mullvad VPN daemon"
start() {
    log_daemon_msg "Starting $DESC" "$prog"
    start_daemon -p $PIDFILE /opt/Mullvad\x20VPN/resources/mullvad-daemon -v --disable-stdout-timestamps
    if [ $? -ne 0 ]; then
        log_end_msg 1
        exit 1
    fi
    if [ $? -eq 0 ]; then
        log_end_msg 0
    fi
    exit 0
}

stop() {
    log_daemon_msg "Stopping $DESC" "$prog"
    killproc -p $PIDFILE /opt/Mullvad\x20VPN/resources/mullvad-daemon
    if [ $? -ne 0 ]; then
        log_end_msg 1
        exit 1
    fi
    if [ $? -eq 0 ]; then
        log_end_msg 0
    fi
.....

Giving me the following result;

sudo service mullvad-daemon.sh start
Starting Mullvad VPN daemon: mullvad-daemon/sbin/start-stop-daemon: unable to stat /opt/Mullvadx20VPN/resources/mullvad-daemon (No such file or directory)

I tried; double quotes around path with just a space, single quotes path with just a space, and with backslashes, double backward backslashes, to try and escape further. All with combinations of \x20 or \xa0. It works if I remove the space from the folder name and adjust directory, and while it's usable it obviously fails to load some assets. This is probably very simple and the only thing stopping it from being fully functional.

  • 1
    escaping the space should work: `/opt/Mullvad\ VPN/resources/mullvad-daemon` – Diego Torres Milano Apr 06 '22 at 02:14
  • forgot to mention I tried that as well Starting Mullvad VPN daemon: mullvad-daemon/sbin/start-stop-daemon: unable to stat /opt/Mullvad (No such file or directory) – localdegen Apr 06 '22 at 02:21
  • Kept trying with making sure every variable was double quotes, turning this dir into a variable, everything I could find on stackoverflow for similar issues. I'm just gonna end up keeping the modified folder name and having a properly named folder symlink to it for the assets to load. – localdegen Apr 06 '22 at 03:21
  • 1
    If you want `\x20` interpreted as a space, you need to use Bash's ANSI-C quoting: `$’\x20’`. – Jonathan Leffler Apr 06 '22 at 03:43
  • Like this ? `start_daemon -p $PIDFILE /opt/Mullvad$’\x20’VPN/resources/mullvad-daemon -v --disable-stdout-timestamps` It gives me this; `sudo service mullvad-daemon.sh start Starting Mullvad VPN daemon: mullvad-daemon/sbin/start-stop-daemon: unable to stat /opt/Mullvad$’x20’VPN/resources/mullvad-daemon (No such file or directory) failed!` – localdegen Apr 06 '22 at 03:53
  • @localdegen ANSI-C quoting is a bash feature; /bin/sh may not support it. Try changing the shebang to `#!/bin/bash` (or whatever the location of bash is on your system). Also, what is the `start_daemon` command? If it mishandles its arguments (which is common in shell scripts), there may be no way to get it to handle an argument with a space in it. – Gordon Davisson Apr 06 '22 at 04:01
  • @GordonDavisson This seems to be the man page https://man7.org/linux/man-pages/man8/start-stop-daemon.8.html I used https://github.com/akhilvij/systemd-to-sysvinit-converter to convert mullvad-vpn's default service file to this script and it seems to work perfectly when the paths are detected. I don't have the knowledge to figure out what is responsible here. I'm running Devuan Chimera with Sysvinit on xfce4 terminal. – localdegen Apr 06 '22 at 04:18
  • Oh and yes I tried to change to #!/bin/bash with no success. – localdegen Apr 06 '22 at 04:34
  • Demonstrate that you don't have success with a minimal, reproducible example. Also print your bash version, for instance do in your script a: `echo bash$`\x20`version=$BASH_VERSION` and post the exact output you get. – user1934428 Apr 06 '22 at 06:11
  • Does your /lib/lsb/init-functions file look like the one in [this question](https://stackoverflow.com/questions/42513396/unable-to-start-apache2-syntax-error) (first line is "`# /lib/lsb/init-functions for Debian -*- shell-script -*-`", third is "`#Copyright (c) 2002-08 Chris Lawrence`")? If so, the definition of the `start_daemon` function is buggy, and cannot deal with spaces in filenames, no matter how they're quoted/escaped. – Gordon Davisson Apr 06 '22 at 06:45
  • @user1934428 `sudo service mullvad-daemon.sh start bash$x20version=5.1.4(1)-release` Same output inside/outside the script. @GordonDavisson Aside from his foreign code, the start-daemon function looks the same. I do remember seeing the -oknodo on line 58 one time in my console when I was trying different things though. – localdegen Apr 06 '22 at 06:58
  • @GordonDavisson Sorry, to properly answer your question; yes those three lines look the same. – localdegen Apr 06 '22 at 07:05
  • Sorry for my typo. It must be of course `echo bash$'\x20'version=$BASH_VERSION`, as Jonathan Leffler had explained. Please repeat the test with the fixed version. – user1934428 Apr 06 '22 at 07:12
  • Would it be possible to edit the /lib/lsb/init-functions file, or would that cause other problems? – Gordon Davisson Apr 06 '22 at 07:20
  • @user1934428 `echo bash$'\x20'version=$BASH_VERSION bash version=5.1.4(1)-release` and `sudo service mullvad-daemon.sh start bash version=5.1.4(1)-release`, but `/opt/Mullvad$'\x20'VPN/resources/mullvad-daemon` still gives `Starting Mullvad VPN daemon: mullvad-daemon/sbin/start-stop-daemon: unable to stat /opt/Mullvad (No such file or directory)` So the problem is now isolated to start_daemon as @GordonDavisson suggests. I wouldn't know where to start to modify it, but if it's too much trouble I do have a functional workaround with the symlink. – localdegen Apr 06 '22 at 16:01
  • @GordonDavisson After some trial and error the faulty line was `#58 --chdir "$PWD" --exec $exec --oknodo --pidfile "$pidfile" -- "$@"` in `/lib/lsb/init-functions`. I wrapped `"$exec"` and my path name in quotes everything is well. Thank you for putting me on the right track. – localdegen Apr 06 '22 at 18:39

1 Answers1

0

Thank you @user1934428 and @GordonDavisson for putting me on the right track. The solution was to wrap $exec in quotes on line 58 in /lib/lsb/init-functions;

 --chdir "$PWD" --exec "$exec" --oknodo --pidfile "$pidfile" -- "$@"

my /etc/init.d/mullvad-daemon.sh now looks like this

#!/bin/sh
### BEGIN INIT INFO
# Provides: mullvad-daemon
# Required-Start:   $syslog $local_fs 
# Required-Stop:    $syslog $local_fs 
# Should-Start: $network 
# Default-Start:    2 3 4 5
# Default-Stop:     0 1 6
# Short-Description: Mullvad VPN daemon
### END INIT INFO

. /lib/lsb/init-functions
prog=mullvad-daemon
PIDFILE=/var/run/$prog.pid
DESC="Mullvad VPN daemon"
start() {
    log_daemon_msg "Starting $DESC" "$prog"
    start_daemon -p $PIDFILE "/opt/Mullvad VPN/resources/mullvad-daemon" -v --disable-stdout-timestamps
    if [ $? -ne 0 ]; then
        log_end_msg 1
        exit 1
    fi
    if [ $? -eq 0 ]; then
        log_end_msg 0
    fi
    exit 0
}

stop() {
    log_daemon_msg "Stopping $DESC" "$prog"
    killproc -p $PIDFILE "/opt/Mullvad VPN/resources/mullvad-daemon"
    if [ $? -ne 0 ]; then
        log_end_msg 1
        exit 1
    fi
    if [ $? -eq 0 ]; then
        log_end_msg 0
    fi
}

force_reload() {
    stop
    start

}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    force-reload)
        force_reload
        ;;
    restart)
        stop
        start
        ;;

    *)
        echo "$Usage: $prog {start|stop|force-reload|restart}"
        exit 2
esac