Windows DnsServiceRegister now registers the Bonjour service-type form and the RFC subtype name so a Mac browse of _ipp._tcp,_universal can see the printer. document-format-supported matches the TXT pdl list, including JPEG. Job ids persist in next-job and job-N directories. The service log is written and flushed even when stderr fails. The tray is started by Task Scheduler or Explorer so setup is not its parent. Co-authored-by: George Lambert <marchon@gmail.com>
66 lines
1.6 KiB
Go
66 lines
1.6 KiB
Go
package netprint
|
|
|
|
import (
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
// serviceLogWriter appends each line to the log file and flushes it.
|
|
// A Windows service has no console, so os.Stderr.Write fails. io.MultiWriter
|
|
// stops at that first error and never reaches the file, which left
|
|
// netprint.log at 0 bytes. The file is written first; stderr is best-effort.
|
|
type serviceLogWriter struct {
|
|
file *os.File
|
|
extra io.Writer
|
|
}
|
|
|
|
func (w *serviceLogWriter) Write(p []byte) (int, error) {
|
|
if w == nil || w.file == nil {
|
|
return 0, os.ErrInvalid
|
|
}
|
|
n, err := w.file.Write(p)
|
|
if err != nil {
|
|
return n, err
|
|
}
|
|
if n != len(p) {
|
|
return n, io.ErrShortWrite
|
|
}
|
|
_ = w.file.Sync()
|
|
if w.extra != nil {
|
|
_, _ = w.extra.Write(p)
|
|
}
|
|
return n, nil
|
|
}
|
|
|
|
// setupServiceLog appends the service log under %ProgramData%\Verae\logs on Windows.
|
|
// VERAE_LOG_DIR overrides the directory (used by tests).
|
|
func setupServiceLog() {
|
|
dir := serviceLogDir()
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
|
log.Printf("netprint: log directory: %v", err)
|
|
return
|
|
}
|
|
_ = osChmodUsers(dir)
|
|
f, err := os.OpenFile(filepath.Join(dir, "netprint.log"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0o644)
|
|
if err != nil {
|
|
log.Printf("netprint: log file: %v", err)
|
|
return
|
|
}
|
|
log.SetFlags(log.Ldate | log.Ltime)
|
|
log.SetOutput(&serviceLogWriter{file: f, extra: os.Stderr})
|
|
log.Printf("netprint: log file %s", f.Name())
|
|
}
|
|
|
|
func serviceLogDir() string {
|
|
if d := os.Getenv("VERAE_LOG_DIR"); d != "" {
|
|
return d
|
|
}
|
|
return defaultServiceLogDir()
|
|
}
|
|
|
|
func osChmodUsers(dir string) error {
|
|
// Users (S-1-5-32-545) can read the service log. Ignore failure when not elevated.
|
|
return execGrantUsers(dir)
|
|
}
|