From 1b0dd37dd30dfb7d069de363017d5ec406ec63b0 Mon Sep 17 00:00:00 2001 From: Alex Kopp Date: Thu, 2 Oct 2025 21:09:06 -0400 Subject: [PATCH] Support falling back to a global configuration file Signed-off-by: Alex Kopp --- CHANGELOG.md | 4 ++++ cmd/privatebin/main.go | 19 ++++++++++++++++++- doc/privatebin.1.md | 2 ++ doc/privatebin.conf.5.md | 9 +++++++-- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e4bb67..ced557f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added + +- Attempt to read a global system configuration file if `~/.config/privatebin/config.json` is not found. On Windows, `C:\ProgramData\privatebin\config.json` and on other operating systems, `/etc/privatebin/config.json`. + ## [2.1.1] - 2025-09-08 ### Fixed diff --git a/cmd/privatebin/main.go b/cmd/privatebin/main.go index 30f8bc5..555ec3e 100644 --- a/cmd/privatebin/main.go +++ b/cmd/privatebin/main.go @@ -25,6 +25,7 @@ import ( "os" "path" "path/filepath" + "runtime" "strings" "github.com/spf13/cobra" @@ -83,6 +84,22 @@ var ( } cfgPath = path.Join(homeDir, ".config", "privatebin", "config.json") + + // Try to load from user's config first + _, err = os.Stat(cfgPath) + if err != nil { + // If user config doesn't exist, try system-wide config + var systemPath string + if runtime.GOOS == "windows" { + systemPath = path.Join("C:", "ProgramData", "privatebin", "config.json") + } else { + systemPath = path.Join(string(os.PathSeparator), "etc", "privatebin", "config.json") + } + + if _, err := os.Stat(systemPath); err == nil { + cfgPath = systemPath + } + } } cfg, err := loadCfgFile(cfgPath) @@ -303,7 +320,7 @@ var ( func init() { rootCmd.PersistentFlags().StringVarP(&output, "output", "o", "", "the command output format") - rootCmd.PersistentFlags().StringVarP(&cfgPath, "config", "c", "", "the config file (default is $HOME/.config/privatebin/config.json)") + rootCmd.PersistentFlags().StringVarP(&cfgPath, "config", "c", "", "the config file (default is $HOME/.config/privatebin/config.json, or system-wide /etc/privatebin/config.json on Linux/macOS, C:\\ProgramData\\privatebin\\config.json on Windows)") rootCmd.PersistentFlags().StringVarP(&binName, "bin", "b", "", "the name of the privatebin instance to use (default \"\")") rootCmd.PersistentFlags().StringSliceVarP(&extraHeaderFields, "header", "H", []string{}, "extra HTTP header fields to include in the request sent") diff --git a/doc/privatebin.1.md b/doc/privatebin.1.md index 5aed624..1006cea 100644 --- a/doc/privatebin.1.md +++ b/doc/privatebin.1.md @@ -30,6 +30,8 @@ instances. **-c, -\-config** \ : The path of the configuration file (default "~/.config/privatebin/config.json"). + If not found, the CLI will also look for a system-wide configuration file at + "/etc/privatebin/config.json" (Linux/macOS) or "C:\\ProgramData\\privatebin\\config.json" (Windows). **-H, -\-header** \ : The extra HTTP header fields to include in the request sent. diff --git a/doc/privatebin.conf.5.md b/doc/privatebin.conf.5.md index 2eda542..7feaf98 100644 --- a/doc/privatebin.conf.5.md +++ b/doc/privatebin.conf.5.md @@ -124,8 +124,13 @@ A bit more complete configuration file: # FILES _~/.config/privatebin/config.json_ -: Default location of the privatebin configuration. The file has to be -created manually as it is not installed with a standard installation. +: Default location of the privatebin configuration. The file has to be created manually as it is not installed with a standard installation. + +_/etc/privatebin/config.json_ (Linux/macOS) +: System-wide configuration file location, used if the user config is not found. + +_C:\\ProgramData\\privatebin\\config.json_ (Windows) +: System-wide configuration file location, used if the user config is not found. # AUTHORS