Keep the network printer off the driver helper port and install folder.
Use 8632 when 631 is taken, install standalone Windows and macOS builds beside the driver instead of over it, open the LAN firewall ports, and give silent NSIS dialogs a default plus an install log. Co-authored-by: George Lambert <marchon@gmail.com>
This commit is contained in:
parent
bc7b09061b
commit
2f7f7aa873
17 changed files with 748 additions and 126 deletions
|
|
@ -26,7 +26,7 @@ verae-print setup
|
|||
verae-print stamp document.pdf
|
||||
```
|
||||
|
||||
**Network printer (optional, separate from the driver):** an IPP Everywhere queue named **Verae Timestamp** for other devices on the LAN. Install the standalone package, or leave the driver installer’s option off (Windows checkbox, macOS Customize, Debian debconf). Both use one service and one tray / menu-bar control. See [docs/network-printer.md](docs/network-printer.md).
|
||||
**Network printer (optional, separate from the driver):** an IPP Everywhere queue named **Verae Timestamp** for other devices on the LAN. Install the standalone package, or leave the driver installer’s option off (Windows checkbox, macOS Customize, Debian debconf). Both use one service and one tray / menu-bar control. The standalone Windows folder is `C:\Program Files\Verae\NetPrint` (the driver stays in `PrintStamp`). The LAN fallback port is **8632**, so it does not collide with the driver helper on `127.0.0.1:8631`. See [docs/network-printer.md](docs/network-printer.md).
|
||||
|
||||
| OS | Standalone | With the driver (off unless you opt in) |
|
||||
|----|------------|------------------------------------------|
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
Optional IPP Everywhere printer. Phones and other computers on the LAN print to **Verae Timestamp**. This machine hashes the document, registers the SHA-256 with Verae the same way the desktop drivers do, and keeps the receipt. Document bytes are not uploaded.
|
||||
|
||||
The printer is off until you install the standalone package or turn on the driver installer option. Both paths install one binary command, one config file, one service, and one tray / menu-bar control.
|
||||
The printer is off until you install the standalone package or turn on the driver installer option. Both paths install one service and one tray / menu-bar control. They do not share an install folder: the standalone package never overwrites the driver binary. If both are installed, the service runs whichever binary is the same version or newer, and removing one leaves the other in place.
|
||||
|
||||
| | Windows | macOS | Debian / Ubuntu |
|
||||
|---|---|---|---|
|
||||
|
|
@ -10,17 +10,19 @@ The printer is off until you install the standalone package or turn on the drive
|
|||
| Driver installer option | Unchecked checkbox on the options page | Customize → “Network timestamp printer” (unselected) | debconf “Enable the Verae network timestamp printer?” (default no), or `apt install verae-netprint` |
|
||||
| Service | `VeraeNetPrint` | LaunchDaemon `com.verae.netprint` | `verae-netprint.service` |
|
||||
| Tray / menu bar | `verae-netprint-tray.exe` (notification area) | `verae-print tray` (menu bar) | `verae-print tray` (StatusNotifier / AppIndicator) |
|
||||
| Command | `%ProgramFiles%\Verae\PrintStamp\bin\verae-print.exe` | `/Library/Application Support/Verae/PrintStamp/bin/verae-print` | `/usr/bin/verae-print` |
|
||||
| Standalone command | `%ProgramFiles%\Verae\NetPrint\bin\verae-print.exe` | `/Library/Application Support/Verae/NetPrint/bin/verae-print` | `/usr/lib/verae-netprint/verae-print` |
|
||||
| Driver command | `%ProgramFiles%\Verae\PrintStamp\bin\verae-print.exe` | `/Library/Application Support/Verae/PrintStamp/bin/verae-print` | `/usr/lib/verae-print/verae-print` |
|
||||
| CLI on `PATH` | the driver binary when the driver is installed | `/usr/local/bin/verae-print` points at the driver when it is installed, otherwise at NetPrint | `/usr/bin/verae-print` points at the driver when it is installed, otherwise at NetPrint |
|
||||
| Config | `%ProgramData%\Verae\PrintStamp\netprint.json` | `/Library/Application Support/Verae/PrintStamp/netprint.json` | `/etc/verae/netprint.json` |
|
||||
| Receipts | `%ProgramData%\Verae\NetPrint` | `/Library/Application Support/Verae/NetPrint` | `/var/lib/verae-netprint` |
|
||||
|
||||
Installing the standalone package when the driver option is already installed (or the other way around) keeps the same service name and config. Removing one product leaves the service in place while the other is still installed.
|
||||
The desktop driver's loopback helper stays on `127.0.0.1:8631`. The network printer does not use that port.
|
||||
|
||||
## Try it
|
||||
|
||||
1. Install using either path above. The tray or menu-bar icon starts at login only after the print server is installed.
|
||||
2. Open **Settings** from the icon and paste the same `xVerae-` signing key the drivers use (or sign in first with `verae-print setup` on that machine). The service stores the key; the tray does not edit config files.
|
||||
3. On another device, add the printer **Verae Timestamp**. It is advertised with DNS-SD (`_ipp._tcp`, plus `_universal` and `_print`) and AirPrint text records. The IPP port is 631, or 8631 when 631 is already taken by CUPS.
|
||||
3. On another device, add the printer **Verae Timestamp**. It is advertised with DNS-SD (`_ipp._tcp`, plus `_universal` and `_print`) and AirPrint text records. The IPP port is 631, or 8632 when 631 is already taken by CUPS. mDNS and the tray show the port that was actually bound.
|
||||
4. Print a PDF. Open **Receipts** from the tray, or browse to the printer’s admin URL (`http://<lan-address>:<port>/`). Each job has a receipt PDF and a verify link on `https://explorer.verae.ai/time`.
|
||||
|
||||
The icon shows running or stopped, the printer name, a LAN address and port, and how many jobs arrived today. It can start, stop, and restart the service, turn launch-at-login on or off for the service and for the icon, open recent receipts, and open settings (printer name, forward-to printer, signing key).
|
||||
|
|
@ -29,12 +31,21 @@ Forward-to is optional: a local queue name, or an `ipp://` URI. A failed forward
|
|||
|
||||
## Firewall
|
||||
|
||||
Allow TCP **631** (and **8631** if CUPS already owns 631) from your LAN. Allow UDP **5353** so other devices can discover the printer. The control API listens only on `127.0.0.1:8630`.
|
||||
The Windows installers add inbound rules named **Verae NetPrint IPP** (TCP 631), **Verae NetPrint IPP Fallback** (TCP 8632), and **Verae NetPrint mDNS** (UDP 5353) on the private and domain profiles. They are removed when the last NetPrint product is uninstalled. Port 8631 is not opened; that is the driver helper on loopback.
|
||||
|
||||
On Debian and Ubuntu, `postinst` opens the same three ports with `ufw` when ufw is installed and already active. The rules are removed when the last package is removed.
|
||||
|
||||
On macOS, the Application Firewall is per application (System Settings → Network → Firewall). Install runs `/usr/libexec/ApplicationFirewall/socketfilterfw --add` and `--unblockapp` on the service binary when that tool is present. If other devices still cannot connect, allow `verae-print` in that pane.
|
||||
|
||||
The control API listens only on `127.0.0.1:8630`.
|
||||
|
||||
A silent Windows install (`/S`) does not wait on a dialog. If the service does not start, the message is written to `%ProgramData%\Verae\logs\netprint-installer.log`.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- The icon says stopped. Start it from the menu. On Linux, `systemctl status verae-netprint`. On Windows, `sc query VeraeNetPrint`. On macOS, `sudo launchctl print system/com.verae.netprint`.
|
||||
- Other devices do not see it. Confirm the service is running, mDNS is not blocked, and the host has a LAN address. CUPS on the same machine is fine: this printer falls back to port 8631 and still advertises that port.
|
||||
- Other devices do not see it. Confirm the service is running, mDNS (UDP 5353) is not blocked, and the host has a LAN address. CUPS on the same machine is fine: this printer falls back to port 8632 and still advertises that port. It does not fall back to 8631.
|
||||
- Windows setup seemed to hang with `/S`. Every installer dialog has a silent default. Read `%ProgramData%\Verae\logs\netprint-installer.log`.
|
||||
- Jobs fail with an authentication error. Open Settings and save a current `xVerae-` key. The service reads the machine token (`/etc/verae/xverae-token`, the macOS Application Support file, or `%ProgramData%\Verae\PrintStamp\xverae-token`) and the usual per-user token.
|
||||
- Raster jobs (AirPrint `image/urf`, Linux `image/pwg-raster`) are converted to PDF on this machine before they are hashed. PDF is accepted as-is.
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,17 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultFallbackPort is the LAN IPP port when 631 is already taken.
|
||||
// It is not 8631: that port belongs to the desktop driver's loopback helper.
|
||||
DefaultFallbackPort = 8632
|
||||
// DriverHelperPort is reserved for the desktop driver's loopback IPP helper
|
||||
// (127.0.0.1:8631). The network printer never binds it.
|
||||
DriverHelperPort = 8631
|
||||
// DefaultControlPort is the loopback control API.
|
||||
DefaultControlPort = 8630
|
||||
)
|
||||
|
||||
// Config is the network printer. The Verae signing key is not stored here;
|
||||
// the process loads it the same way the drivers do (internal/auth).
|
||||
type Config struct {
|
||||
|
|
@ -20,6 +31,7 @@ type Config struct {
|
|||
// Port is the IPP/HTTP port to try first. 631 is the IPP default.
|
||||
Port int `json:"port,omitempty"`
|
||||
// FallbackPort is used when Port is already taken (CUPS on macOS and Debian).
|
||||
// The default is 8632. 8631 is reserved for the driver helper and is never bound.
|
||||
FallbackPort int `json:"fallbackPort,omitempty"`
|
||||
// Bind is the listen address without a port. Empty listens on all interfaces.
|
||||
Bind string `json:"bind,omitempty"`
|
||||
|
|
@ -50,8 +62,8 @@ func Defaults() Config {
|
|||
return Config{
|
||||
Name: "Verae Timestamp",
|
||||
Port: 631,
|
||||
FallbackPort: 8631,
|
||||
ControlPort: 8630,
|
||||
FallbackPort: DefaultFallbackPort,
|
||||
ControlPort: DefaultControlPort,
|
||||
DataDir: defaultDataDir(),
|
||||
KeepPDF: &keep,
|
||||
Advertise: &adv,
|
||||
|
|
@ -191,7 +203,7 @@ func (c *Config) normalize() error {
|
|||
return fmt.Errorf("port must be 1-65535")
|
||||
}
|
||||
if c.ControlPort <= 0 {
|
||||
c.ControlPort = 8630
|
||||
c.ControlPort = DefaultControlPort
|
||||
}
|
||||
if c.ControlPort > 65535 {
|
||||
return fmt.Errorf("controlPort must be 1-65535")
|
||||
|
|
@ -220,8 +232,8 @@ func ExampleJSON(dataDir string) []byte {
|
|||
c := Config{
|
||||
Name: "Verae Timestamp",
|
||||
Port: 631,
|
||||
FallbackPort: 8631,
|
||||
ControlPort: 8630,
|
||||
FallbackPort: DefaultFallbackPort,
|
||||
ControlPort: DefaultControlPort,
|
||||
DataDir: dataDir,
|
||||
KeepPDF: &keep,
|
||||
ForwardPrinter: "",
|
||||
|
|
|
|||
|
|
@ -190,12 +190,30 @@ func (s *Server) Shutdown(ctx context.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// ippListenPorts is the IPP port list for cfg. Port 8631 is the desktop
|
||||
// driver's loopback helper and is never used, even when a saved config asks for it.
|
||||
func ippListenPorts(cfg Config) []int {
|
||||
primary := cfg.Port
|
||||
fallback := cfg.FallbackPort
|
||||
if primary == DriverHelperPort {
|
||||
primary = DefaultFallbackPort
|
||||
}
|
||||
if fallback == DriverHelperPort {
|
||||
fallback = DefaultFallbackPort
|
||||
}
|
||||
if primary <= 0 {
|
||||
primary = 631
|
||||
}
|
||||
out := []int{primary}
|
||||
if fallback > 0 && fallback != primary {
|
||||
out = append(out, fallback)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func listenIPP(cfg Config) (net.Listener, int, error) {
|
||||
bind := cfg.Bind
|
||||
try := []int{cfg.Port}
|
||||
if cfg.FallbackPort > 0 && cfg.FallbackPort != cfg.Port {
|
||||
try = append(try, cfg.FallbackPort)
|
||||
}
|
||||
try := ippListenPorts(cfg)
|
||||
var last error
|
||||
for _, port := range try {
|
||||
ln, err := net.Listen("tcp", net.JoinHostPort(bind, fmt.Sprint(port)))
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package netprint
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
|
|
@ -110,7 +111,10 @@ func launchctl(args ...string) error {
|
|||
func mustExe() string {
|
||||
p, err := Executable()
|
||||
if err != nil {
|
||||
return "/Library/Application Support/Verae/PrintStamp/bin/verae-print"
|
||||
if _, statErr := os.Stat("/Library/Application Support/Verae/PrintStamp/bin/verae-print"); statErr == nil {
|
||||
return "/Library/Application Support/Verae/PrintStamp/bin/verae-print"
|
||||
}
|
||||
return "/Library/Application Support/Verae/NetPrint/bin/verae-print"
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
|
@ -149,24 +153,22 @@ func Install(owner, tokenFile string) error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
chosen := selectServiceBinary(exe, currentServiceExe())
|
||||
if err := os.MkdirAll("/Library/LaunchDaemons", 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := os.Stat(daemonPlist); os.IsNotExist(err) {
|
||||
if err := os.WriteFile(daemonPlist, []byte(plistDaemon(exe, cfgPath)), 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.WriteFile(daemonPlist, []byte(plistDaemon(chosen, cfgPath)), 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.MkdirAll("/Library/LaunchAgents", 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.WriteFile(agentPlist, []byte(plistAgent(exe)), 0o644); err != nil {
|
||||
if err := os.WriteFile(agentPlist, []byte(plistAgent(chosen)), 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
_ = os.MkdirAll("/usr/local/bin", 0o755)
|
||||
_ = os.Remove("/usr/local/bin/verae-print")
|
||||
_ = os.Symlink(exe, "/usr/local/bin/verae-print")
|
||||
linkCLI(exe)
|
||||
copyToken(tokenFile)
|
||||
allowAppFirewall(chosen)
|
||||
_ = exec.Command("launchctl", "bootout", "system/"+launchdLabel).Run()
|
||||
if err := launchctl("bootstrap", "system", daemonPlist); err != nil {
|
||||
return err
|
||||
|
|
@ -183,6 +185,13 @@ func Uninstall(owner string) error {
|
|||
return err
|
||||
}
|
||||
if !o.empty() {
|
||||
if other := peerBinary(owner); other != "" {
|
||||
cfgPath := SystemConfigPath()
|
||||
_ = os.WriteFile(daemonPlist, []byte(plistDaemon(other, cfgPath)), 0o644)
|
||||
_ = os.WriteFile(agentPlist, []byte(plistAgent(other)), 0o644)
|
||||
_ = exec.Command("launchctl", "bootout", "system/"+launchdLabel).Run()
|
||||
_ = launchctl("bootstrap", "system", daemonPlist)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
_ = exec.Command("launchctl", "bootout", "system/"+launchdLabel).Run()
|
||||
|
|
@ -194,5 +203,60 @@ func Uninstall(owner string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func currentServiceExe() string {
|
||||
b, err := os.ReadFile(daemonPlist)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return parseDarwinProgram(string(b))
|
||||
}
|
||||
|
||||
func peerBinary(owner string) string {
|
||||
p := "/Library/Application Support/Verae/NetPrint/bin/verae-print"
|
||||
if owner == "standalone" {
|
||||
p = "/Library/Application Support/Verae/PrintStamp/bin/verae-print"
|
||||
}
|
||||
if _, err := os.Stat(p); err == nil {
|
||||
return p
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// linkCLI keeps /usr/local/bin/verae-print on the driver binary when that
|
||||
// install is present. A real file at the link path is left alone.
|
||||
func linkCLI(exe string) {
|
||||
const link = "/usr/local/bin/verae-print"
|
||||
const driver = "/Library/Application Support/Verae/PrintStamp/bin/verae-print"
|
||||
target := exe
|
||||
if _, err := os.Stat(driver); err == nil {
|
||||
target = driver
|
||||
}
|
||||
_ = os.MkdirAll("/usr/local/bin", 0o755)
|
||||
st, err := os.Lstat(link)
|
||||
if err == nil && st.Mode()&os.ModeSymlink == 0 {
|
||||
return
|
||||
}
|
||||
if err == nil {
|
||||
_ = os.Remove(link)
|
||||
}
|
||||
_ = os.Symlink(target, link)
|
||||
}
|
||||
|
||||
// allowAppFirewall asks the macOS application firewall to accept the service
|
||||
// binary. System Settings → Network → Firewall still applies if this tool
|
||||
// is unavailable or the user has blocked the app.
|
||||
func allowAppFirewall(exe string) {
|
||||
const fw = "/usr/libexec/ApplicationFirewall/socketfilterfw"
|
||||
if _, err := os.Stat(fw); err != nil {
|
||||
return
|
||||
}
|
||||
if out, err := exec.Command(fw, "--add", exe).CombinedOutput(); err != nil {
|
||||
log.Printf("netprint: socketfilterfw --add: %v (%s)", err, strings.TrimSpace(string(out)))
|
||||
}
|
||||
if out, err := exec.Command(fw, "--unblockapp", exe).CombinedOutput(); err != nil {
|
||||
log.Printf("netprint: socketfilterfw --unblockapp: %v (%s)", err, strings.TrimSpace(string(out)))
|
||||
}
|
||||
}
|
||||
|
||||
// silence unused in case strconv is needed by future uid parsing
|
||||
var _ = strconv.Itoa
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package netprint
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
|
@ -180,13 +181,12 @@ func Install(owner, tokenFile string) error {
|
|||
_ = os.Chown("/etc/verae", uid, uid)
|
||||
_ = os.Chown(cfgPath, uid, uid)
|
||||
}
|
||||
if _, err := os.Stat(unitPath); err != nil {
|
||||
if err := os.MkdirAll(filepath.Dir(unitPath), 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.WriteFile(unitPath, []byte(unitText(exe, cfgPath)), 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
chosen := selectServiceBinary(exe, currentServiceExe())
|
||||
if err := os.MkdirAll(filepath.Dir(unitPath), 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.WriteFile(unitPath, []byte(unitText(chosen, cfgPath)), 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(ctlPath), 0o755); err != nil {
|
||||
return err
|
||||
|
|
@ -200,11 +200,12 @@ func Install(owner, tokenFile string) error {
|
|||
if err := os.MkdirAll(filepath.Dir(trayDesktop), 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.WriteFile(trayDesktop, []byte(trayDesktopText(exe, true)), 0o644); err != nil {
|
||||
if err := os.WriteFile(trayDesktop, []byte(trayDesktopText(chosen, true)), 0o644); err != nil {
|
||||
return err
|
||||
}
|
||||
linkBin(exe)
|
||||
copyToken(tokenFile)
|
||||
ensureFirewall()
|
||||
_ = exec.Command("systemctl", "daemon-reload").Run()
|
||||
if err := systemctlNow("enable", "--now", linuxUnit); err != nil {
|
||||
return err
|
||||
|
|
@ -220,8 +221,16 @@ func Uninstall(owner string) error {
|
|||
return err
|
||||
}
|
||||
if !o.empty() {
|
||||
if other := peerBinary(owner); other != "" {
|
||||
cfgPath := SystemConfigPath()
|
||||
_ = os.WriteFile(unitPath, []byte(unitText(other, cfgPath)), 0o644)
|
||||
_ = os.WriteFile(trayDesktop, []byte(trayDesktopText(other, true)), 0o644)
|
||||
_ = exec.Command("systemctl", "daemon-reload").Run()
|
||||
_ = systemctlNow("restart", linuxUnit)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
removeFirewall()
|
||||
_ = systemctlNow("disable", "--now", linuxUnit)
|
||||
_ = os.Remove(unitPath)
|
||||
_ = os.Remove(trayDesktop)
|
||||
|
|
@ -230,13 +239,74 @@ func Uninstall(owner string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func currentServiceExe() string {
|
||||
b, err := os.ReadFile(unitPath)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return parseExecStart(string(b))
|
||||
}
|
||||
|
||||
func peerBinary(owner string) string {
|
||||
p := "/usr/lib/verae-netprint/verae-print"
|
||||
if owner == "standalone" {
|
||||
p = "/usr/lib/verae-print/verae-print"
|
||||
}
|
||||
if _, err := os.Stat(p); err == nil {
|
||||
return p
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// linkBin points /usr/bin/verae-print at this binary only when the driver
|
||||
// package is not installed. An installed driver keeps the CLI. A real
|
||||
// (non-symlink) file is left alone.
|
||||
func linkBin(exe string) {
|
||||
const link = "/usr/bin/verae-print"
|
||||
if exe == link {
|
||||
const driver = "/usr/lib/verae-print/verae-print"
|
||||
target := exe
|
||||
if _, err := os.Stat(driver); err == nil {
|
||||
target = driver
|
||||
}
|
||||
if target == link {
|
||||
return
|
||||
}
|
||||
_ = os.Remove(link)
|
||||
_ = os.Symlink(exe, link)
|
||||
st, err := os.Lstat(link)
|
||||
if err == nil && st.Mode()&os.ModeSymlink == 0 {
|
||||
return
|
||||
}
|
||||
if err == nil {
|
||||
_ = os.Remove(link)
|
||||
}
|
||||
_ = os.Symlink(target, link)
|
||||
}
|
||||
|
||||
func ensureFirewall() {
|
||||
if _, err := exec.LookPath("ufw"); err != nil {
|
||||
return
|
||||
}
|
||||
out, err := exec.Command("ufw", "status").CombinedOutput()
|
||||
if err != nil || !strings.Contains(string(out), "Status: active") {
|
||||
return
|
||||
}
|
||||
status := string(out)
|
||||
for _, rule := range []string{"631/tcp", "8632/tcp", "5353/udp"} {
|
||||
if strings.Contains(status, rule) {
|
||||
continue
|
||||
}
|
||||
if err := exec.Command("ufw", "--force", "allow", rule, "comment", "Verae NetPrint").Run(); err != nil {
|
||||
log.Printf("netprint: ufw allow %s: %v", rule, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func removeFirewall() {
|
||||
if _, err := exec.LookPath("ufw"); err != nil {
|
||||
return
|
||||
}
|
||||
for _, rule := range []string{"631/tcp", "8632/tcp", "5353/udp"} {
|
||||
_ = exec.Command("ufw", "--force", "delete", "allow", rule).Run()
|
||||
}
|
||||
}
|
||||
|
||||
func ensureServiceUser() error {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package netprint
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
|
@ -42,11 +43,8 @@ func (osControl) TrayAtLogin() (bool, error) {
|
|||
return err == nil && strings.Contains(string(out), "VeraeNetPrintTray"), nil
|
||||
}
|
||||
func (osControl) SetTrayAtLogin(on bool) error {
|
||||
if !on {
|
||||
return exec.Command("reg.exe", "delete", runKey, "/v", "VeraeNetPrintTray", "/f").Run()
|
||||
}
|
||||
tray := trayExe()
|
||||
return exec.Command("reg.exe", "add", runKey, "/v", "VeraeNetPrintTray", "/t", "REG_SZ", "/d", tray, "/f").Run()
|
||||
exe, _ := Executable()
|
||||
return setTrayFor(exe, on)
|
||||
}
|
||||
|
||||
func sc(args ...string) error {
|
||||
|
|
@ -63,16 +61,85 @@ func delayed(args ...string) error {
|
|||
return cmd.Start()
|
||||
}
|
||||
|
||||
func trayExe() string {
|
||||
exe, err := Executable()
|
||||
if err != nil {
|
||||
func trayNextTo(serviceExe string) string {
|
||||
serviceExe = strings.Trim(serviceExe, `"`)
|
||||
if serviceExe == "" {
|
||||
return `verae-print.exe tray`
|
||||
}
|
||||
sibling := filepath.Join(filepath.Dir(exe), "verae-netprint-tray.exe")
|
||||
sibling := filepath.Join(filepath.Dir(serviceExe), "verae-netprint-tray.exe")
|
||||
if _, err := os.Stat(sibling); err == nil {
|
||||
return `"` + sibling + `"`
|
||||
}
|
||||
return `"` + exe + `" tray`
|
||||
return `"` + serviceExe + `" tray`
|
||||
}
|
||||
|
||||
func setTrayFor(serviceExe string, on bool) error {
|
||||
if !on {
|
||||
return exec.Command("reg.exe", "delete", runKey, "/v", "VeraeNetPrintTray", "/f").Run()
|
||||
}
|
||||
return exec.Command("reg.exe", "add", runKey, "/v", "VeraeNetPrintTray", "/t", "REG_SZ", "/d", trayNextTo(serviceExe), "/f").Run()
|
||||
}
|
||||
|
||||
func serviceBinPath(exe string) string {
|
||||
return fmt.Sprintf(`"%s" netprint`, exe)
|
||||
}
|
||||
|
||||
func currentServiceExe() string {
|
||||
out, err := exec.Command("sc.exe", "qc", winService).CombinedOutput()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return parseWindowsBinPath(string(out))
|
||||
}
|
||||
|
||||
func peerBinary(owner string) string {
|
||||
rel := filepath.Join("Verae", "NetPrint", "bin", "verae-print.exe")
|
||||
if owner == "standalone" {
|
||||
rel = filepath.Join("Verae", "PrintStamp", "bin", "verae-print.exe")
|
||||
}
|
||||
var roots []string
|
||||
if p := os.Getenv("ProgramW6432"); p != "" {
|
||||
roots = append(roots, p)
|
||||
}
|
||||
if p := os.Getenv("ProgramFiles"); p != "" {
|
||||
roots = append(roots, p)
|
||||
}
|
||||
roots = append(roots, `C:\Program Files`)
|
||||
seen := map[string]bool{}
|
||||
for _, root := range roots {
|
||||
if seen[root] {
|
||||
continue
|
||||
}
|
||||
seen[root] = true
|
||||
p := filepath.Join(root, rel)
|
||||
if _, err := os.Stat(p); err == nil {
|
||||
return p
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func ensureFirewall() {
|
||||
removeFirewall()
|
||||
rules := []struct{ name, proto, port string }{
|
||||
{"Verae NetPrint IPP", "TCP", "631"},
|
||||
{"Verae NetPrint IPP Fallback", "TCP", "8632"},
|
||||
{"Verae NetPrint mDNS", "UDP", "5353"},
|
||||
}
|
||||
for _, r := range rules {
|
||||
out, err := exec.Command("netsh", "advfirewall", "firewall", "add", "rule",
|
||||
"name="+r.name, "dir=in", "action=allow", "protocol="+r.proto,
|
||||
"localport="+r.port, "profile=private,domain").CombinedOutput()
|
||||
if err != nil {
|
||||
log.Printf("netprint: firewall %s: %v (%s)", r.name, err, strings.TrimSpace(string(out)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func removeFirewall() {
|
||||
for _, name := range []string{"Verae NetPrint IPP", "Verae NetPrint IPP Fallback", "Verae NetPrint mDNS"} {
|
||||
_ = exec.Command("netsh", "advfirewall", "firewall", "delete", "rule", "name="+name).Run()
|
||||
}
|
||||
}
|
||||
|
||||
func setOwnerReg(name string, on bool) {
|
||||
|
|
@ -112,18 +179,27 @@ func Install(owner, tokenFile string) error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
bin := fmt.Sprintf(`"%s" netprint`, exe)
|
||||
_ = exec.Command("sc.exe", "stop", winService).Run()
|
||||
_ = exec.Command("sc.exe", "delete", winService).Run()
|
||||
if err := sc("create", winService, "binPath=", bin, "start=", "auto", "DisplayName=", "Verae Network Printer"); err != nil {
|
||||
return err
|
||||
current := currentServiceExe()
|
||||
chosen := selectServiceBinary(exe, current)
|
||||
bin := serviceBinPath(chosen)
|
||||
if current == "" {
|
||||
if err := sc("create", winService, "binPath=", bin, "start=", "auto", "DisplayName=", "Verae Network Printer"); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if chosen != current {
|
||||
_ = exec.Command("sc.exe", "stop", winService).Run()
|
||||
if err := sc("config", winService, "binPath=", bin); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
_ = exec.Command("sc.exe", "description", winService, "Verae network timestamp printer").Run()
|
||||
_ = exec.Command("sc.exe", "config", winService, "start=", "auto").Run()
|
||||
copyToken(tokenFile)
|
||||
ensureFirewall()
|
||||
if err := sc("start", winService); err != nil {
|
||||
return err
|
||||
}
|
||||
return osControl{}.SetTrayAtLogin(true)
|
||||
return setTrayFor(chosen, true)
|
||||
}
|
||||
|
||||
// Uninstall removes the service only when neither installer still owns it.
|
||||
|
|
@ -138,10 +214,17 @@ func Uninstall(owner string) error {
|
|||
setOwnerReg("Standalone", false)
|
||||
}
|
||||
if !o.empty() || ownerReg("Driver") || ownerReg("Standalone") {
|
||||
if other := peerBinary(owner); other != "" {
|
||||
_ = exec.Command("sc.exe", "stop", winService).Run()
|
||||
_ = sc("config", winService, "binPath=", serviceBinPath(other))
|
||||
_ = sc("start", winService)
|
||||
_ = setTrayFor(other, true)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
_ = exec.Command("sc.exe", "stop", winService).Run()
|
||||
_ = exec.Command("sc.exe", "delete", winService).Run()
|
||||
_ = osControl{}.SetTrayAtLogin(false)
|
||||
_ = setTrayFor("", false)
|
||||
removeFirewall()
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
161
internal/netprint/version.go
Normal file
161
internal/netprint/version.go
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
package netprint
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// compareVersions compares dotted numeric versions.
|
||||
// It returns -1 when a is older than b, 0 when they are equal, and 1 when a is newer.
|
||||
func compareVersions(a, b string) int {
|
||||
ap := splitVer(a)
|
||||
bp := splitVer(b)
|
||||
n := len(ap)
|
||||
if len(bp) > n {
|
||||
n = len(bp)
|
||||
}
|
||||
for i := 0; i < n; i++ {
|
||||
av, bv := 0, 0
|
||||
if i < len(ap) {
|
||||
av = ap[i]
|
||||
}
|
||||
if i < len(bp) {
|
||||
bv = bp[i]
|
||||
}
|
||||
if av < bv {
|
||||
return -1
|
||||
}
|
||||
if av > bv {
|
||||
return 1
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func splitVer(s string) []int {
|
||||
s = strings.TrimSpace(s)
|
||||
s = strings.TrimPrefix(s, "v")
|
||||
if i := strings.IndexAny(s, " \t\r\n"); i >= 0 {
|
||||
s = s[:i]
|
||||
}
|
||||
if s == "" {
|
||||
return nil
|
||||
}
|
||||
parts := strings.Split(s, ".")
|
||||
out := make([]int, 0, len(parts))
|
||||
for _, p := range parts {
|
||||
n, err := strconv.Atoi(p)
|
||||
if err != nil {
|
||||
digits := strings.TrimLeftFunc(p, func(r rune) bool { return r < '0' || r > '9' })
|
||||
end := 0
|
||||
for end < len(digits) && digits[end] >= '0' && digits[end] <= '9' {
|
||||
end++
|
||||
}
|
||||
if end == 0 {
|
||||
break
|
||||
}
|
||||
n, _ = strconv.Atoi(digits[:end])
|
||||
}
|
||||
out = append(out, n)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// versionOf runs `exe version` and returns the first line.
|
||||
func versionOf(exe string) string {
|
||||
exe = strings.TrimSpace(exe)
|
||||
if exe == "" {
|
||||
return ""
|
||||
}
|
||||
out, err := exec.Command(exe, "version").Output()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
line := strings.TrimSpace(string(out))
|
||||
if i := strings.IndexAny(line, "\r\n"); i >= 0 {
|
||||
line = strings.TrimSpace(line[:i])
|
||||
}
|
||||
return line
|
||||
}
|
||||
|
||||
// selectServiceBinary chooses which installed binary the shared service should run.
|
||||
// ours is used when current is missing or ours is the same version or newer.
|
||||
// A newer current binary is kept so an older installer cannot downgrade the service
|
||||
// or replace the other product's files.
|
||||
func selectServiceBinary(ours, current string) string {
|
||||
return selectServiceBinaryVersions(ours, current, versionOf(ours), versionOf(current))
|
||||
}
|
||||
|
||||
func selectServiceBinaryVersions(ours, current, oursVer, curVer string) string {
|
||||
ours = strings.TrimSpace(ours)
|
||||
current = strings.TrimSpace(current)
|
||||
if current == "" {
|
||||
return ours
|
||||
}
|
||||
if ours == "" {
|
||||
return current
|
||||
}
|
||||
if compareVersions(oursVer, curVer) < 0 {
|
||||
return current
|
||||
}
|
||||
return ours
|
||||
}
|
||||
|
||||
func parseWindowsBinPath(qc string) string {
|
||||
for _, line := range strings.Split(qc, "\n") {
|
||||
if !strings.Contains(strings.ToUpper(line), "BINARY_PATH_NAME") {
|
||||
continue
|
||||
}
|
||||
i := strings.Index(line, ":")
|
||||
if i < 0 {
|
||||
continue
|
||||
}
|
||||
return firstExecutable(strings.TrimSpace(line[i+1:]))
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func parseExecStart(unit string) string {
|
||||
for _, line := range strings.Split(unit, "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if !strings.HasPrefix(line, "ExecStart=") {
|
||||
continue
|
||||
}
|
||||
return firstExecutable(strings.TrimSpace(strings.TrimPrefix(line, "ExecStart=")))
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func parseDarwinProgram(plist string) string {
|
||||
i := strings.Index(plist, "<key>ProgramArguments</key>")
|
||||
if i < 0 {
|
||||
return ""
|
||||
}
|
||||
rest := plist[i:]
|
||||
s := strings.Index(rest, "<string>")
|
||||
e := strings.Index(rest, "</string>")
|
||||
if s < 0 || e < 0 || e <= s+len("<string>") {
|
||||
return ""
|
||||
}
|
||||
return strings.TrimSpace(rest[s+len("<string>") : e])
|
||||
}
|
||||
|
||||
func firstExecutable(rest string) string {
|
||||
rest = strings.TrimSpace(rest)
|
||||
if rest == "" {
|
||||
return ""
|
||||
}
|
||||
if strings.HasPrefix(rest, `"`) {
|
||||
rest = rest[1:]
|
||||
if j := strings.Index(rest, `"`); j >= 0 {
|
||||
return rest[:j]
|
||||
}
|
||||
return rest
|
||||
}
|
||||
fields := strings.Fields(rest)
|
||||
if len(fields) == 0 {
|
||||
return ""
|
||||
}
|
||||
return fields[0]
|
||||
}
|
||||
66
internal/netprint/version_test.go
Normal file
66
internal/netprint/version_test.go
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
package netprint
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFallbackPortAvoidsDriverHelper(t *testing.T) {
|
||||
d := Defaults()
|
||||
if d.FallbackPort != DefaultFallbackPort || d.FallbackPort == DriverHelperPort {
|
||||
t.Fatalf("fallback port %d, want %d and not the driver helper %d", d.FallbackPort, DefaultFallbackPort, DriverHelperPort)
|
||||
}
|
||||
if d.Port == DriverHelperPort {
|
||||
t.Fatal("primary port collides with the driver helper")
|
||||
}
|
||||
sample := string(ExampleJSON(d.DataDir))
|
||||
if !strings.Contains(sample, "8632") || strings.Contains(sample, "8631") {
|
||||
t.Fatalf("example config should advertise 8632 and not 8631:\n%s", sample)
|
||||
}
|
||||
ports := ippListenPorts(Config{Port: 631, FallbackPort: DriverHelperPort})
|
||||
for _, p := range ports {
|
||||
if p == DriverHelperPort {
|
||||
t.Fatalf("listen ports include driver helper: %v", ports)
|
||||
}
|
||||
}
|
||||
if len(ports) != 2 || ports[0] != 631 || ports[1] != DefaultFallbackPort {
|
||||
t.Fatalf("631 with a saved 8631 fallback should try 631 then %d, got %v", DefaultFallbackPort, ports)
|
||||
}
|
||||
only := ippListenPorts(Config{Port: DriverHelperPort, FallbackPort: DriverHelperPort})
|
||||
if len(only) != 1 || only[0] != DefaultFallbackPort {
|
||||
t.Fatalf("both ports set to the helper should bind %d, got %v", DefaultFallbackPort, only)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelectServiceBinary(t *testing.T) {
|
||||
if compareVersions("0.3.4", "0.3.3") <= 0 || compareVersions("0.3.4", "0.3.4") != 0 || compareVersions("0.3.4", "0.4") >= 0 {
|
||||
t.Fatal("compareVersions")
|
||||
}
|
||||
if got := selectServiceBinaryVersions(`/new/verae-print.exe`, `/old/verae-print.exe`, "0.3.4", "0.3.3"); got != `/new/verae-print.exe` {
|
||||
t.Fatal(got)
|
||||
}
|
||||
if got := selectServiceBinaryVersions(`/new/verae-print.exe`, `/old/verae-print.exe`, "0.3.3", "0.3.4"); got != `/old/verae-print.exe` {
|
||||
t.Fatal(got)
|
||||
}
|
||||
if got := selectServiceBinaryVersions(`/new/verae-print.exe`, `/old/verae-print.exe`, "0.3.4", "0.3.4"); got != `/new/verae-print.exe` {
|
||||
t.Fatal(got)
|
||||
}
|
||||
if got := selectServiceBinaryVersions(`/new/verae-print.exe`, "", "0.3.4", ""); got != `/new/verae-print.exe` {
|
||||
t.Fatal(got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseServiceExecutable(t *testing.T) {
|
||||
qc := "BINARY_PATH_NAME : \"C:\\Program Files\\Verae\\NetPrint\\bin\\verae-print.exe\" netprint\r\n"
|
||||
if got := parseWindowsBinPath(qc); got != `C:\Program Files\Verae\NetPrint\bin\verae-print.exe` {
|
||||
t.Fatal(got)
|
||||
}
|
||||
unit := "ExecStart=/usr/lib/verae-netprint/verae-print netprint --config /etc/verae/netprint.json\n"
|
||||
if got := parseExecStart(unit); got != "/usr/lib/verae-netprint/verae-print" {
|
||||
t.Fatal(got)
|
||||
}
|
||||
plist := "<key>ProgramArguments</key><array><string>/Library/Application Support/Verae/NetPrint/bin/verae-print</string><string>netprint</string></array>"
|
||||
if got := parseDarwinProgram(plist); got != "/Library/Application Support/Verae/NetPrint/bin/verae-print" {
|
||||
t.Fatal(got)
|
||||
}
|
||||
}
|
||||
|
|
@ -40,8 +40,8 @@ build_arch() {
|
|||
"$stage/usr/share/man/man1" \
|
||||
"$stage/usr/share/applications"
|
||||
|
||||
# The command is /usr/bin/verae-print, a symlink created in postinst, so the
|
||||
# standalone verae-netprint package can share that path without dpkg conflicts.
|
||||
# The command is /usr/bin/verae-print, a symlink created in postinst.
|
||||
# The standalone package uses /usr/lib/verae-netprint and does not replace this file.
|
||||
install -m 755 "$bin" "$stage/usr/lib/verae-print/verae-print"
|
||||
if [[ -f "$ROOT/platform/linux/cups/backend-verae.sh" ]]; then
|
||||
install -m 700 "$ROOT/platform/linux/cups/backend-verae.sh" "$stage/usr/lib/cups/backend/verae"
|
||||
|
|
@ -127,8 +127,10 @@ Description: Digests-only Verae timestamping from Print / CLI
|
|||
The same package can enable the Verae network timestamp printer
|
||||
(IPP Everywhere on the LAN). That choice is off unless you accept
|
||||
the debconf prompt, or you install the verae-netprint package.
|
||||
Both use /usr/bin/verae-print, /etc/verae/netprint.json, and
|
||||
systemd unit verae-netprint.service.
|
||||
Both use /etc/verae/netprint.json and systemd unit verae-netprint.service.
|
||||
The driver binary stays in /usr/lib/verae-print. The standalone package
|
||||
uses /usr/lib/verae-netprint and does not replace this binary.
|
||||
/usr/bin/verae-print points at the driver while this package is installed.
|
||||
EOF
|
||||
|
||||
cat >"$stage/DEBIAN/templates" <<'EOF'
|
||||
|
|
@ -173,6 +175,11 @@ if [ -e /usr/share/debconf/confmodule ]; then
|
|||
enable=${RET:-false}
|
||||
fi
|
||||
if [ "$enable" = "true" ]; then
|
||||
if command -v ufw >/dev/null 2>&1 && ufw status 2>/dev/null | grep -q "Status: active"; then
|
||||
ufw status | grep -q "631/tcp" || ufw allow 631/tcp comment "Verae NetPrint" || true
|
||||
ufw status | grep -q "8632/tcp" || ufw allow 8632/tcp comment "Verae NetPrint" || true
|
||||
ufw status | grep -q "5353/udp" || ufw allow 5353/udp comment "Verae NetPrint" || true
|
||||
fi
|
||||
/usr/lib/verae-print/verae-print netprint install --owner driver || true
|
||||
fi
|
||||
echo "verae-print installed. Next: verae-print setup"
|
||||
|
|
@ -201,10 +208,17 @@ EOF
|
|||
set -e
|
||||
if [ "$1" = "remove" ] || [ "$1" = "purge" ]; then
|
||||
if [ -x /usr/lib/verae-netprint/verae-print ]; then
|
||||
ln -sfn /usr/lib/verae-netprint/verae-print /usr/bin/verae-print
|
||||
else
|
||||
if [ -L /usr/bin/verae-print ] || [ ! -e /usr/bin/verae-print ]; then
|
||||
ln -sfn /usr/lib/verae-netprint/verae-print /usr/bin/verae-print
|
||||
fi
|
||||
elif [ -L /usr/bin/verae-print ]; then
|
||||
rm -f /usr/bin/verae-print
|
||||
fi
|
||||
if [ ! -x /usr/lib/verae-netprint/verae-print ] && command -v ufw >/dev/null 2>&1; then
|
||||
ufw --force delete allow 631/tcp >/dev/null 2>&1 || true
|
||||
ufw --force delete allow 8632/tcp >/dev/null 2>&1 || true
|
||||
ufw --force delete allow 5353/udp >/dev/null 2>&1 || true
|
||||
fi
|
||||
fi
|
||||
exit 0
|
||||
EOF
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
#!/usr/bin/env bash
|
||||
# Build the standalone verae-netprint Debian package.
|
||||
# It shares /usr/bin/verae-print (a symlink), /etc/verae/netprint.json, and
|
||||
# systemd unit verae-netprint.service with the driver package's opt-in.
|
||||
# The binary lives in /usr/lib/verae-netprint and does not replace
|
||||
# /usr/lib/verae-print. /usr/bin/verae-print stays on the driver when that
|
||||
# package is installed. Both share /etc/verae/netprint.json and
|
||||
# systemd unit verae-netprint.service.
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/../../.." && pwd)"
|
||||
|
|
@ -59,16 +61,28 @@ Description: Verae network timestamp printer (IPP Everywhere)
|
|||
on this computer. Installs systemd unit verae-netprint, a tray icon at
|
||||
login, and the loopback control API on 127.0.0.1:8630.
|
||||
.
|
||||
Shares /usr/bin/verae-print and the service name with the optional
|
||||
component of the verae-print driver package, so installing both upgrades
|
||||
in place instead of running two servers.
|
||||
Uses the same service name as the optional component of the verae-print
|
||||
driver package, so installing both keeps one server. The driver keeps
|
||||
/usr/bin/verae-print when it is installed. This package does not replace
|
||||
the driver binary.
|
||||
EOF
|
||||
|
||||
cat >"$stage/DEBIAN/postinst" <<'EOF'
|
||||
#!/bin/sh
|
||||
set -e
|
||||
if [ "$1" = "configure" ]; then
|
||||
ln -sfn /usr/lib/verae-netprint/verae-print /usr/bin/verae-print
|
||||
# Leave the CLI on the driver when that package is installed. Do not
|
||||
# replace a real (non-symlink) /usr/bin/verae-print.
|
||||
if [ ! -x /usr/lib/verae-print/verae-print ]; then
|
||||
if [ -L /usr/bin/verae-print ] || [ ! -e /usr/bin/verae-print ]; then
|
||||
ln -sfn /usr/lib/verae-netprint/verae-print /usr/bin/verae-print
|
||||
fi
|
||||
fi
|
||||
if command -v ufw >/dev/null 2>&1 && ufw status 2>/dev/null | grep -q "Status: active"; then
|
||||
ufw status | grep -q "631/tcp" || ufw allow 631/tcp comment "Verae NetPrint" || true
|
||||
ufw status | grep -q "8632/tcp" || ufw allow 8632/tcp comment "Verae NetPrint" || true
|
||||
ufw status | grep -q "5353/udp" || ufw allow 5353/udp comment "Verae NetPrint" || true
|
||||
fi
|
||||
/usr/lib/verae-netprint/verae-print netprint install --owner standalone
|
||||
fi
|
||||
exit 0
|
||||
|
|
@ -91,9 +105,14 @@ set -e
|
|||
if [ "$1" = "remove" ] || [ "$1" = "purge" ]; then
|
||||
if [ -x /usr/lib/verae-print/verae-print ]; then
|
||||
ln -sfn /usr/lib/verae-print/verae-print /usr/bin/verae-print
|
||||
else
|
||||
elif [ -L /usr/bin/verae-print ]; then
|
||||
rm -f /usr/bin/verae-print
|
||||
fi
|
||||
if [ ! -x /usr/lib/verae-print/verae-print ] && command -v ufw >/dev/null 2>&1; then
|
||||
ufw --force delete allow 631/tcp >/dev/null 2>&1 || true
|
||||
ufw --force delete allow 8632/tcp >/dev/null 2>&1 || true
|
||||
ufw --force delete allow 5353/udp >/dev/null 2>&1 || true
|
||||
fi
|
||||
fi
|
||||
exit 0
|
||||
EOF
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<key>Label</key><string>com.verae.netprint</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/Library/Application Support/Verae/PrintStamp/bin/verae-print</string>
|
||||
<string>/Library/Application Support/Verae/NetPrint/bin/verae-print</string>
|
||||
<string>netprint</string>
|
||||
<string>--config</string>
|
||||
<string>/Library/Application Support/Verae/PrintStamp/netprint.json</string>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
<key>Label</key><string>com.verae.netprint.tray</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/Library/Application Support/Verae/PrintStamp/bin/verae-print</string>
|
||||
<string>/Library/Application Support/Verae/NetPrint/bin/verae-print</string>
|
||||
<string>tray</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key><true/>
|
||||
|
|
|
|||
|
|
@ -19,15 +19,15 @@ fi
|
|||
STAGE="$OUT/payload"
|
||||
SCRIPTS="$OUT/scripts"
|
||||
rm -rf "$STAGE" "$SCRIPTS"
|
||||
mkdir -p "$STAGE/Library/Application Support/Verae/PrintStamp/bin" "$SCRIPTS"
|
||||
cp -f "$BIN" "$STAGE/Library/Application Support/Verae/PrintStamp/bin/verae-print"
|
||||
chmod 755 "$STAGE/Library/Application Support/Verae/PrintStamp/bin/verae-print"
|
||||
cp -f "$ROOT/platform/macos/netprint/com.verae.netprint.plist" "$STAGE/Library/Application Support/Verae/PrintStamp/"
|
||||
cp -f "$ROOT/platform/macos/netprint/com.verae.netprint.tray.plist" "$STAGE/Library/Application Support/Verae/PrintStamp/"
|
||||
mkdir -p "$STAGE/Library/Application Support/Verae/NetPrint/bin" "$SCRIPTS"
|
||||
cp -f "$BIN" "$STAGE/Library/Application Support/Verae/NetPrint/bin/verae-print"
|
||||
chmod 755 "$STAGE/Library/Application Support/Verae/NetPrint/bin/verae-print"
|
||||
cp -f "$ROOT/platform/macos/netprint/com.verae.netprint.plist" "$STAGE/Library/Application Support/Verae/NetPrint/"
|
||||
cp -f "$ROOT/platform/macos/netprint/com.verae.netprint.tray.plist" "$STAGE/Library/Application Support/Verae/NetPrint/"
|
||||
cat >"$SCRIPTS/postinstall" <<'EOF'
|
||||
#!/bin/bash
|
||||
export VERAE_NETPRINT_OWNER=standalone
|
||||
exec "/Library/Application Support/Verae/PrintStamp/bin/verae-print" netprint install --owner standalone
|
||||
exec "/Library/Application Support/Verae/NetPrint/bin/verae-print" netprint install --owner standalone
|
||||
EOF
|
||||
chmod 755 "$SCRIPTS/postinstall"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
; Verae Network Printer — standalone Windows installer (NSIS).
|
||||
; Installs the same binaries, service name (VeraeNetPrint), and config as the
|
||||
; optional checkbox in the driver installer. Installing one when the other is
|
||||
; present upgrades in place.
|
||||
; Installs into its own folder (C:\Program Files\Verae\NetPrint) so it does not
|
||||
; overwrite the driver's C:\Program Files\Verae\PrintStamp\bin\verae-print.exe.
|
||||
; The service name (VeraeNetPrint) and %ProgramData% config are shared. Installing
|
||||
; one product when the other is present points the service at the same or newer
|
||||
; binary and leaves the other product's files in place.
|
||||
!ifndef VERSION
|
||||
!define VERSION "0.3.4"
|
||||
!endif
|
||||
|
|
@ -20,7 +22,7 @@
|
|||
|
||||
Name "${PRODUCT_NAME} ${VERSION}"
|
||||
OutFile "${OUTDIR}\VeraeNetPrint-windows-${ARCH}-${VERSION}-setup.exe"
|
||||
InstallDir "$PROGRAMFILES64\Verae\PrintStamp"
|
||||
InstallDir "$PROGRAMFILES64\Verae\NetPrint"
|
||||
RequestExecutionLevel admin
|
||||
Unicode true
|
||||
SetCompressor /SOLID lzma
|
||||
|
|
@ -40,15 +42,69 @@ ShowInstDetails show
|
|||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
|
||||
Var LogFile
|
||||
Var LogDir
|
||||
|
||||
Function .onInit
|
||||
${IfNot} ${RunningX64}
|
||||
MessageBox MB_ICONSTOP "This build targets 64-bit Windows."
|
||||
MessageBox MB_ICONSTOP "This build targets 64-bit Windows." /SD IDOK
|
||||
Abort
|
||||
${EndIf}
|
||||
SetRegView 64
|
||||
SetShellVarContext all
|
||||
Call SetupLogPath
|
||||
FunctionEnd
|
||||
|
||||
Function un.onInit
|
||||
SetRegView 64
|
||||
SetShellVarContext all
|
||||
Call un.SetupLogPath
|
||||
FunctionEnd
|
||||
|
||||
Function SetupLogPath
|
||||
ReadEnvStr $LogDir "ProgramData"
|
||||
${If} $LogDir == ""
|
||||
StrCpy $LogDir "C:\ProgramData"
|
||||
${EndIf}
|
||||
StrCpy $LogDir "$LogDir\Verae\logs"
|
||||
StrCpy $LogFile "$LogDir\netprint-installer.log"
|
||||
FunctionEnd
|
||||
|
||||
Function un.SetupLogPath
|
||||
ReadEnvStr $LogDir "ProgramData"
|
||||
${If} $LogDir == ""
|
||||
StrCpy $LogDir "C:\ProgramData"
|
||||
${EndIf}
|
||||
StrCpy $LogDir "$LogDir\Verae\logs"
|
||||
StrCpy $LogFile "$LogDir\netprint-installer.log"
|
||||
FunctionEnd
|
||||
|
||||
; Inbound TCP 631 (IPP), TCP 8632 (fallback; 8631 is the driver helper), UDP 5353 (mDNS).
|
||||
; Private and domain profiles only. A macro so the uninstaller can run the same commands.
|
||||
!macro NETPRINT_FIREWALL_ADD
|
||||
nsExec::Exec 'netsh advfirewall firewall delete rule name="Verae NetPrint IPP"'
|
||||
Pop $0
|
||||
nsExec::Exec 'netsh advfirewall firewall add rule name="Verae NetPrint IPP" dir=in action=allow protocol=TCP localport=631 profile=private,domain'
|
||||
Pop $0
|
||||
nsExec::Exec 'netsh advfirewall firewall delete rule name="Verae NetPrint IPP Fallback"'
|
||||
Pop $0
|
||||
nsExec::Exec 'netsh advfirewall firewall add rule name="Verae NetPrint IPP Fallback" dir=in action=allow protocol=TCP localport=8632 profile=private,domain'
|
||||
Pop $0
|
||||
nsExec::Exec 'netsh advfirewall firewall delete rule name="Verae NetPrint mDNS"'
|
||||
Pop $0
|
||||
nsExec::Exec 'netsh advfirewall firewall add rule name="Verae NetPrint mDNS" dir=in action=allow protocol=UDP localport=5353 profile=private,domain'
|
||||
Pop $0
|
||||
!macroend
|
||||
|
||||
!macro NETPRINT_FIREWALL_REMOVE
|
||||
nsExec::Exec 'netsh advfirewall firewall delete rule name="Verae NetPrint IPP"'
|
||||
Pop $0
|
||||
nsExec::Exec 'netsh advfirewall firewall delete rule name="Verae NetPrint IPP Fallback"'
|
||||
Pop $0
|
||||
nsExec::Exec 'netsh advfirewall firewall delete rule name="Verae NetPrint mDNS"'
|
||||
Pop $0
|
||||
!macroend
|
||||
|
||||
Section "Verae Network Printer" SecMain
|
||||
SectionIn RO
|
||||
SetOutPath "$INSTDIR\bin"
|
||||
|
|
@ -63,16 +119,35 @@ Section "Verae Network Printer" SecMain
|
|||
WriteRegStr HKLM "${UNINST_KEY}" "Publisher" "Verae"
|
||||
CreateDirectory "$SMPROGRAMS\Verae"
|
||||
CreateShortCut "$SMPROGRAMS\Verae\Verae Network Printer.lnk" "$INSTDIR\bin\verae-netprint-tray.exe"
|
||||
nsExec::Exec '"$INSTDIR\bin\verae-print.exe" netprint install --owner standalone'
|
||||
!insertmacro NETPRINT_FIREWALL_ADD
|
||||
CreateDirectory "$LogDir"
|
||||
nsExec::ExecToStack '"$INSTDIR\bin\verae-print.exe" netprint install --owner standalone'
|
||||
Pop $0
|
||||
Pop $1
|
||||
ClearErrors
|
||||
FileOpen $2 "$LogFile" a
|
||||
${IfNot} ${Errors}
|
||||
FileSeek $2 0 END
|
||||
FileWrite $2 "netprint install exit $0$\r$\n$1$\r$\n"
|
||||
FileClose $2
|
||||
${EndIf}
|
||||
${If} $0 != 0
|
||||
MessageBox MB_ICONEXCLAMATION "The service did not start (exit $0). You can start it from the tray icon after signing in."
|
||||
MessageBox MB_ICONEXCLAMATION "The service did not start (exit $0).$\r$\nDetails were written to $LogFile$\r$\nYou can start it from the tray icon after signing in." /SD IDOK
|
||||
${EndIf}
|
||||
SectionEnd
|
||||
|
||||
Section "Uninstall"
|
||||
nsExec::Exec '"$INSTDIR\bin\verae-print.exe" netprint uninstall --owner standalone'
|
||||
nsExec::ExecToStack '"$INSTDIR\bin\verae-print.exe" netprint uninstall --owner standalone'
|
||||
Pop $0
|
||||
Pop $1
|
||||
CreateDirectory "$LogDir"
|
||||
ClearErrors
|
||||
FileOpen $2 "$LogFile" a
|
||||
${IfNot} ${Errors}
|
||||
FileSeek $2 0 END
|
||||
FileWrite $2 "netprint uninstall exit $0$\r$\n$1$\r$\n"
|
||||
FileClose $2
|
||||
${EndIf}
|
||||
ClearErrors
|
||||
ReadRegDWORD $R1 HKLM "Software\Verae\NetPrint" "Driver"
|
||||
${If} ${Errors}
|
||||
|
|
@ -82,17 +157,15 @@ Section "Uninstall"
|
|||
${If} $R1 != 1
|
||||
nsExec::Exec 'taskkill /F /IM verae-netprint-tray.exe'
|
||||
Pop $0
|
||||
Delete "$INSTDIR\bin\verae-print.exe"
|
||||
Delete "$INSTDIR\bin\verae-netprint-tray.exe"
|
||||
RMDir "$INSTDIR\bin"
|
||||
Delete "$INSTDIR\LICENSE.txt"
|
||||
Delete "$INSTDIR\Uninstall-NetPrint.exe"
|
||||
RMDir "$INSTDIR"
|
||||
Delete "$SMPROGRAMS\Verae\Verae Network Printer.lnk"
|
||||
RMDir "$SMPROGRAMS\Verae"
|
||||
${Else}
|
||||
Delete "$INSTDIR\Uninstall-NetPrint.exe"
|
||||
Delete "$SMPROGRAMS\Verae\Verae Network Printer.lnk"
|
||||
!insertmacro NETPRINT_FIREWALL_REMOVE
|
||||
${EndIf}
|
||||
Delete "$INSTDIR\bin\verae-print.exe"
|
||||
Delete "$INSTDIR\bin\verae-netprint-tray.exe"
|
||||
RMDir "$INSTDIR\bin"
|
||||
Delete "$INSTDIR\LICENSE.txt"
|
||||
Delete "$INSTDIR\Uninstall-NetPrint.exe"
|
||||
RMDir "$INSTDIR"
|
||||
Delete "$SMPROGRAMS\Verae\Verae Network Printer.lnk"
|
||||
RMDir "$SMPROGRAMS\Verae"
|
||||
DeleteRegKey HKLM "${UNINST_KEY}"
|
||||
SectionEnd
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ FunctionEnd
|
|||
|
||||
Function .onInit
|
||||
${IfNot} ${RunningX64}
|
||||
MessageBox MB_ICONSTOP "This build targets 64-bit Windows."
|
||||
MessageBox MB_ICONSTOP "This build targets 64-bit Windows." /SD IDOK
|
||||
Abort
|
||||
${EndIf}
|
||||
SetRegView 64
|
||||
|
|
@ -252,7 +252,7 @@ Function KeyPageLeave
|
|||
StrCpy $KeyChoice "paste"
|
||||
${Else}
|
||||
StrCpy $KeyChoice "skip"
|
||||
MessageBox MB_YESNO|MB_ICONEXCLAMATION "Continue without a Verae key?$\r$\n$\r$\nThe printer will be installed, but documents cannot be timestamped until you add a key. On your first print you will be asked for one (or use Start > Verae > Setup signing key)." IDYES +2
|
||||
MessageBox MB_YESNO|MB_ICONEXCLAMATION "Continue without a Verae key?$\r$\n$\r$\nThe printer will be installed, but documents cannot be timestamped until you add a key. On your first print you will be asked for one (or use Start > Verae > Setup signing key)." /SD IDYES IDYES +2
|
||||
Abort
|
||||
${EndIf}
|
||||
StrCpy $TokenReady 0
|
||||
|
|
@ -301,7 +301,7 @@ Function LoginPageLeave
|
|||
${NSD_GetText} $hTotp $3
|
||||
${If} $1 == ""
|
||||
${OrIf} $2 == ""
|
||||
MessageBox MB_ICONEXCLAMATION "Please enter your email and password."
|
||||
MessageBox MB_ICONEXCLAMATION "Please enter your email and password." /SD IDOK
|
||||
Abort
|
||||
${EndIf}
|
||||
!insertmacro REQ_OPEN "$PLUGINSDIR\req.txt"
|
||||
|
|
@ -331,18 +331,18 @@ Function HandleAccountResult
|
|||
${EndIf}
|
||||
${If} $4 == "ok"
|
||||
StrCpy $TokenReady 1
|
||||
MessageBox MB_ICONINFORMATION "A new Verae key was created for this PC.$\r$\nIt will be saved for $TargetUser."
|
||||
MessageBox MB_ICONINFORMATION "A new Verae key was created for this PC.$\r$\nIt will be saved for $TargetUser." /SD IDOK
|
||||
${ElseIf} $4 == "code_sent"
|
||||
; handled by caller
|
||||
${ElseIf} $4 == "totp_required"
|
||||
MessageBox MB_ICONINFORMATION "$5"
|
||||
MessageBox MB_ICONINFORMATION "$5" /SD IDOK
|
||||
${NSD_SetFocus} $hTotp
|
||||
Abort
|
||||
${Else}
|
||||
${If} $4 == ""
|
||||
StrCpy $5 "No response from the helper (exit $0)."
|
||||
${EndIf}
|
||||
MessageBox MB_ICONEXCLAMATION "Verae said: $5"
|
||||
MessageBox MB_ICONEXCLAMATION "Verae said: $5" /SD IDOK
|
||||
Abort
|
||||
${EndIf}
|
||||
FunctionEnd
|
||||
|
|
@ -393,7 +393,7 @@ Function CreatePageLeave
|
|||
${NSD_GetText} $hPass $3
|
||||
${NSD_GetText} $hConfirm $6
|
||||
${If} $3 != $6
|
||||
MessageBox MB_ICONEXCLAMATION "The passwords do not match."
|
||||
MessageBox MB_ICONEXCLAMATION "The passwords do not match." /SD IDOK
|
||||
Abort
|
||||
${EndIf}
|
||||
!insertmacro REQ_OPEN "$PLUGINSDIR\req.txt"
|
||||
|
|
@ -449,7 +449,7 @@ Function ResendCode
|
|||
Pop $0
|
||||
ReadINIStr $5 "$PLUGINSDIR\acct.ini" account detail
|
||||
Delete "$PLUGINSDIR\acct.ini"
|
||||
MessageBox MB_ICONINFORMATION "$5"
|
||||
MessageBox MB_ICONINFORMATION "$5" /SD IDOK
|
||||
FunctionEnd
|
||||
|
||||
Function VerifyPageLeave
|
||||
|
|
@ -490,7 +490,7 @@ FunctionEnd
|
|||
Function PastePageLeave
|
||||
${NSD_GetText} $hKey $1
|
||||
${If} $1 == ""
|
||||
MessageBox MB_ICONEXCLAMATION "Please paste your key (or go Back and choose Skip)."
|
||||
MessageBox MB_ICONEXCLAMATION "Please paste your key (or go Back and choose Skip)." /SD IDOK
|
||||
Abort
|
||||
${EndIf}
|
||||
FileOpen $9 "$PLUGINSDIR\newtoken.txt" w
|
||||
|
|
@ -513,14 +513,14 @@ Function PastePageLeave
|
|||
StrCpy $TokenReady 1
|
||||
${ElseIf} $4 == "invalid"
|
||||
Delete "$PLUGINSDIR\newtoken.txt"
|
||||
MessageBox MB_ICONEXCLAMATION "Verae rejected this key ($5). Please check it and paste again."
|
||||
MessageBox MB_ICONEXCLAMATION "Verae rejected this key ($5). Please check it and paste again." /SD IDOK
|
||||
Abort
|
||||
${ElseIf} $4 == "badformat"
|
||||
Delete "$PLUGINSDIR\newtoken.txt"
|
||||
MessageBox MB_ICONEXCLAMATION "That does not look like a Verae key: $5"
|
||||
MessageBox MB_ICONEXCLAMATION "That does not look like a Verae key: $5" /SD IDOK
|
||||
Abort
|
||||
${Else}
|
||||
MessageBox MB_YESNO|MB_ICONQUESTION "Could not reach Verae to check the key ($5).$\r$\nSave it anyway?" IDYES +3
|
||||
MessageBox MB_YESNO|MB_ICONQUESTION "Could not reach Verae to check the key ($5).$\r$\nSave it anyway?" /SD IDYES IDYES +3
|
||||
Delete "$PLUGINSDIR\newtoken.txt"
|
||||
Abort
|
||||
StrCpy $TokenReady 1
|
||||
|
|
@ -716,13 +716,35 @@ Section "Verae Print Stamp + printer" SecMain
|
|||
SetOutPath "$INSTDIR\bin"
|
||||
File "${SRCDIR}\verae-netprint-tray.exe"
|
||||
DetailPrint "Installing the Verae network printer (service + tray)"
|
||||
nsExec::Exec '"$INSTDIR\bin\verae-print.exe" netprint install --owner driver'
|
||||
; TCP 631, TCP 8632 (not the helper's 8631), UDP 5353. Private and domain only.
|
||||
nsExec::Exec 'netsh advfirewall firewall delete rule name="Verae NetPrint IPP"'
|
||||
Pop $0
|
||||
nsExec::Exec 'netsh advfirewall firewall add rule name="Verae NetPrint IPP" dir=in action=allow protocol=TCP localport=631 profile=private,domain'
|
||||
Pop $0
|
||||
nsExec::Exec 'netsh advfirewall firewall delete rule name="Verae NetPrint IPP Fallback"'
|
||||
Pop $0
|
||||
nsExec::Exec 'netsh advfirewall firewall add rule name="Verae NetPrint IPP Fallback" dir=in action=allow protocol=TCP localport=8632 profile=private,domain'
|
||||
Pop $0
|
||||
nsExec::Exec 'netsh advfirewall firewall delete rule name="Verae NetPrint mDNS"'
|
||||
Pop $0
|
||||
nsExec::Exec 'netsh advfirewall firewall add rule name="Verae NetPrint mDNS" dir=in action=allow protocol=UDP localport=5353 profile=private,domain'
|
||||
Pop $0
|
||||
CreateDirectory "$LogDir"
|
||||
nsExec::ExecToStack '"$INSTDIR\bin\verae-print.exe" netprint install --owner driver'
|
||||
Pop $0
|
||||
Pop $1
|
||||
ClearErrors
|
||||
FileOpen $2 "$LogDir\netprint-installer.log" a
|
||||
${IfNot} ${Errors}
|
||||
FileSeek $2 0 END
|
||||
FileWrite $2 "driver netprint install exit $0$\r$\n$1$\r$\n"
|
||||
FileClose $2
|
||||
${EndIf}
|
||||
${If} $0 == 0
|
||||
!insertmacro STEP_RESULT "Network printer" "OK - Verae Timestamp on the LAN, tray at login"
|
||||
${Else}
|
||||
${LOG} "ERROR network printer install exit $0"
|
||||
!insertmacro STEP_RESULT "Network printer" "FAIL (exit $0)"
|
||||
${LOG} "ERROR network printer install exit $0. See $LogDir\netprint-installer.log"
|
||||
!insertmacro STEP_RESULT "Network printer" "FAIL (exit $0) - see netprint-installer.log"
|
||||
${EndIf}
|
||||
${Else}
|
||||
!insertmacro STEP_RESULT "Network printer" "SKIPPED"
|
||||
|
|
@ -746,8 +768,8 @@ Section "Uninstall"
|
|||
Pop $0
|
||||
nsExec::Exec 'taskkill /F /IM verae-printhelper.exe'
|
||||
Pop $0
|
||||
; The standalone network-printer setup shares these binaries. Leave them
|
||||
; when that product is still installed.
|
||||
; Standalone NetPrint lives in its own folder. Always remove this driver's files.
|
||||
; Drop the shared firewall rules only when the standalone product is gone.
|
||||
ClearErrors
|
||||
ReadRegDWORD $R1 HKLM "Software\Verae\NetPrint" "Standalone"
|
||||
${If} ${Errors}
|
||||
|
|
@ -757,22 +779,31 @@ Section "Uninstall"
|
|||
${If} $R1 != 1
|
||||
nsExec::Exec 'taskkill /F /IM verae-netprint-tray.exe'
|
||||
Pop $0
|
||||
Delete "$INSTDIR\bin\verae-print.exe"
|
||||
Delete "$INSTDIR\bin\verae-printhelper.exe"
|
||||
Delete "$INSTDIR\bin\verae-netprint-tray.exe"
|
||||
RMDir "$INSTDIR\bin"
|
||||
Delete "$INSTDIR\scripts\*.ps1"
|
||||
RMDir "$INSTDIR\scripts"
|
||||
Delete "$INSTDIR\README-WINDOWS.txt"
|
||||
Delete "$INSTDIR\LICENSE.txt"
|
||||
Delete "$INSTDIR\Uninstall.exe"
|
||||
RMDir "$INSTDIR"
|
||||
Delete "$SMPROGRAMS\Verae\*.lnk"
|
||||
RMDir "$SMPROGRAMS\Verae"
|
||||
DeleteRegKey HKLM "Software\Verae\PrintStamp"
|
||||
${Else}
|
||||
Delete "$INSTDIR\Uninstall.exe"
|
||||
nsExec::Exec 'netsh advfirewall firewall delete rule name="Verae NetPrint IPP"'
|
||||
Pop $0
|
||||
nsExec::Exec 'netsh advfirewall firewall delete rule name="Verae NetPrint IPP Fallback"'
|
||||
Pop $0
|
||||
nsExec::Exec 'netsh advfirewall firewall delete rule name="Verae NetPrint mDNS"'
|
||||
Pop $0
|
||||
${EndIf}
|
||||
Delete "$INSTDIR\bin\verae-print.exe"
|
||||
Delete "$INSTDIR\bin\verae-printhelper.exe"
|
||||
Delete "$INSTDIR\bin\verae-netprint-tray.exe"
|
||||
RMDir "$INSTDIR\bin"
|
||||
Delete "$INSTDIR\scripts\*.ps1"
|
||||
RMDir "$INSTDIR\scripts"
|
||||
Delete "$INSTDIR\README-WINDOWS.txt"
|
||||
Delete "$INSTDIR\LICENSE.txt"
|
||||
Delete "$INSTDIR\Uninstall.exe"
|
||||
RMDir "$INSTDIR"
|
||||
Delete "$SMPROGRAMS\Verae\Verae - Setup signing key.lnk"
|
||||
Delete "$SMPROGRAMS\Verae\Verae - Start print helper.lnk"
|
||||
Delete "$SMPROGRAMS\Verae\Verae - Logs folder.lnk"
|
||||
Delete "$SMPROGRAMS\Verae\Verae - Collect diagnostics.lnk"
|
||||
Delete "$SMPROGRAMS\Verae\Uninstall Verae Print Stamp.lnk"
|
||||
Delete "$SMPROGRAMS\Verae\Uninstall Verae Print Stamp (debug).lnk"
|
||||
RMDir "$SMPROGRAMS\Verae"
|
||||
DeleteRegKey HKLM "Software\Verae\PrintStamp"
|
||||
DeleteRegKey HKLM "${UNINST_KEY}"
|
||||
; logs and the user's .verae\xverae-token are kept on purpose
|
||||
SectionEnd
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@
|
|||
<div class="row">
|
||||
<div>
|
||||
<h2>Network printer</h2>
|
||||
<p>Optional LAN queue “Verae Timestamp” (IPP Everywhere) plus a tray or menu-bar control. Standalone installers, or the off-by-default option inside the driver installers. One service either way. Version 0.3.4.</p>
|
||||
<p>Optional LAN queue “Verae Timestamp” (IPP Everywhere) plus a tray or menu-bar control. Standalone installers, or the off-by-default option inside the driver installers. One service either way. The Windows standalone setup uses <code>C:\Program Files\Verae\NetPrint</code> and does not replace the driver. If port 631 is taken, the printer uses 8632 (the driver helper keeps 8631). Version 0.3.4.</p>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<a class="btn btn-primary" href="/downloads/verae-netprint_amd64.deb">Debian amd64</a>
|
||||
|
|
|
|||
Loading…
Reference in a new issue