Merge pull request #13 from cherti/socketactivation

socket-activate printer
This commit is contained in:
Evan Widloski 2024-03-17 21:06:16 -05:00 committed by GitHub
commit 8e07c1eb9f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 73 additions and 43 deletions

View file

@ -24,14 +24,15 @@ install: printer.arm
ssh -o AddKeysToAgent=yes root@$(host) systemctl stop printer || true
scp printer.arm root@$(host):
scp printer.service root@$(host):/etc/systemd/system
scp printer.socket root@$(host):/etc/systemd/system
ssh root@$(host) systemctl daemon-reload
ssh root@$(host) systemctl enable printer
ssh root@$(host) systemctl restart printer
ssh root@$(host) systemctl enable printer.socket
ssh root@$(host) systemctl restart printer.socket
.PHONY: release
release: printer.arm printer.x86
rm -f release.zip
zip release.zip printer.arm printer.x86 printer.service -r
zip release.zip printer.arm printer.x86 printer.service printer.socket -r
.PHONY: install_config
install_config:

View file

@ -48,7 +48,7 @@ No authentication, so keep WiFi off while not in use.
Virtually all network printers accept raw Postscript/PDF data on TCP port 9100 via the Appsocket/HP Jetdirect protocol. Sometimes this data is preceded by a few plaintext lines telling the printer information such as the print job name and print settings.
This script simply listens on TCP 9100 and waits for a PDF header, then begins saving data to a pdf file (while also creating the accompanying .metadata file). The output filename is extracted from the print job name line, if it exists.
This setup simply listens on TCP 9100 and upon data sent waits for a PDF header, then begins saving data to a pdf file (while also creating the accompanying .metadata file) and then exits again, waiting for the next connection on the port to repeat the procedure. The output filename is extracted from the print job name line, if it exists.
## Testing on host

View file

@ -1,9 +1,11 @@
systemctl stop printer.service || true
systemctl stop printer.socket || true
mkdir -p /home/root/bin
cd /home/root/bin
wget -O release.zip http://github.com/evidlo/remarkable_printer/releases/latest/download/release.zip
unzip -o release.zip
mv printer.service /etc/systemd/system
mv printer.socket /etc/systemd/system
systemctl daemon-reload
systemctl enable --now printer.service
systemctl enable --now printer.socket
rm printer.x86 release.zip

89
main.go
View file

@ -4,22 +4,24 @@
package main
import (
"bufio"
"flag"
"fmt"
"io"
"net"
"os"
"os/exec"
"bufio"
"strconv"
"strings"
"io"
"flag"
"github.com/google/uuid"
"time"
"github.com/google/uuid"
)
var (
CONN_HOST = "0.0.0.0"
CONN_PORT = "9100"
LOG_LEVEL = "error"
CONN_HOST = "0.0.0.0"
CONN_PORT = "9100"
LOG_LEVEL = "error"
XOCHITL_DIR = "/home/root/.local/share/remarkable/xochitl/"
)
@ -39,11 +41,7 @@ const METADATA_TEMPLATE = `{
}
`
const CONTENT_TEMPLATE = `{
"fileType": "pdf"
}
`
const CONTENT_TEMPLATE = "{}"
func main() {
@ -68,14 +66,14 @@ func main() {
// ----- Listen for connections -----
// Listen for incoming connections.
l, err := net.Listen("tcp", *CONN_HOST + ":" + *CONN_PORT)
check(err)
defer l.Close()
// Close the listener when the application closes.
fmt.Println("Listening on " + *CONN_HOST + ":" + *CONN_PORT)
for {
// Listen for an incoming connection.
var l net.Listener
var err error
var isSocketActivated = os.Getenv("LISTEN_PID") == strconv.Itoa(os.Getpid())
if isSocketActivated {
l, err = net.FileListener(os.NewFile(3, "systemd-socket"))
fmt.Println("Listening on systemd-socket")
conn, err := l.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
@ -83,24 +81,33 @@ func main() {
}
handleRequest(conn)
// Restart xochitl
if *restart {
services := []string{"xochitl", "remux", "tarnish", "draft"}
for _, service := range services {
_, exitcode := exec.Command("systemctl", "is-active", service).CombinedOutput()
if exitcode == nil {
debug("Restarting " + service)
stdout, err := exec.Command("systemctl", "restart", service).CombinedOutput()
if err != nil {
fmt.Println(service + " restart failed with message:", string(stdout))
}
}
}
restartUISoftware()
}
}
}
} else {
l, err = net.Listen("tcp", *CONN_HOST+":"+*CONN_PORT)
fmt.Println("Listening on " + *CONN_HOST + ":" + *CONN_PORT)
for {
// Listen for an incoming connection.
conn, err := l.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
os.Exit(1)
}
handleRequest(conn)
if *restart {
restartUISoftware()
}
}
}
check(err)
defer l.Close() // Close the listener when the application closes.
}
func debug(msg ...string) {
if LOG_LEVEL == "debug" {
@ -118,7 +125,6 @@ func check(e error) {
}
}
// Handles incoming requests.
func handleRequest(conn net.Conn) {
u, _ := uuid.NewRandom()
@ -191,3 +197,18 @@ func handleRequest(conn net.Conn) {
conn.Close()
}
// Restarts xochitl or other UI software
func restartUISoftware() {
services := []string{"xochitl", "remux", "tarnish", "draft"}
for _, service := range services {
_, exitcode := exec.Command("systemctl", "is-active", service).CombinedOutput()
if exitcode == nil {
debug("Restarting " + service)
stdout, err := exec.Command("systemctl", "restart", service).CombinedOutput()
if err != nil {
fmt.Println(service+" restart failed with message:", string(stdout))
}
}
}
}

View file

@ -1,9 +1,6 @@
[Unit]
Description=Native printing to reMarkable
Requires=printer.socket
[Service]
ExecStart=/home/root/bin/printer.arm -restart -debug
Restart=always
[Install]
WantedBy=multi-user.target

9
printer.socket Normal file
View file

@ -0,0 +1,9 @@
[Unit]
Description=Socket for native printing to reMarkable
After=multi-user.target
[Socket]
ListenStream=0.0.0.0:9100
[Install]
WantedBy=multi-user.target