mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-04-14 04:38:28 +10:00
98 lines
2.5 KiB
Go
98 lines
2.5 KiB
Go
//go:build darwin || linux || windows
|
|
|
|
package libbox
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strconv"
|
|
"time"
|
|
|
|
C "github.com/sagernet/sing-box/constant"
|
|
E "github.com/sagernet/sing/common/exceptions"
|
|
)
|
|
|
|
type reportMetadata struct {
|
|
Source string `json:"source,omitempty"`
|
|
BundleIdentifier string `json:"bundleIdentifier,omitempty"`
|
|
ProcessName string `json:"processName,omitempty"`
|
|
ProcessPath string `json:"processPath,omitempty"`
|
|
StartedAt string `json:"startedAt,omitempty"`
|
|
AppVersion string `json:"appVersion,omitempty"`
|
|
AppMarketingVersion string `json:"appMarketingVersion,omitempty"`
|
|
CoreVersion string `json:"coreVersion,omitempty"`
|
|
GoVersion string `json:"goVersion,omitempty"`
|
|
}
|
|
|
|
func baseReportMetadata() reportMetadata {
|
|
processPath, _ := os.Executable()
|
|
processName := filepath.Base(processPath)
|
|
if processName == "." {
|
|
processName = ""
|
|
}
|
|
return reportMetadata{
|
|
Source: sCrashReportSource,
|
|
ProcessName: processName,
|
|
ProcessPath: processPath,
|
|
CoreVersion: C.Version,
|
|
GoVersion: GoVersion(),
|
|
}
|
|
}
|
|
|
|
func writeReportFile(destPath string, name string, content []byte) {
|
|
filePath := filepath.Join(destPath, name)
|
|
os.WriteFile(filePath, content, 0o666)
|
|
chownReport(filePath)
|
|
}
|
|
|
|
func writeReportMetadata(destPath string, metadata any) {
|
|
data, err := json.Marshal(metadata)
|
|
if err != nil {
|
|
return
|
|
}
|
|
writeReportFile(destPath, "metadata.json", data)
|
|
}
|
|
|
|
func copyConfigSnapshot(destPath string) {
|
|
snapshotPath := configSnapshotPath()
|
|
content, err := os.ReadFile(snapshotPath)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if len(bytes.TrimSpace(content)) == 0 {
|
|
return
|
|
}
|
|
writeReportFile(destPath, "configuration.json", content)
|
|
}
|
|
|
|
func initReportDir(path string) {
|
|
os.MkdirAll(path, 0o777)
|
|
chownReport(path)
|
|
}
|
|
|
|
func chownReport(path string) {
|
|
if runtime.GOOS != "android" && runtime.GOOS != "windows" {
|
|
os.Chown(path, sUserID, sGroupID)
|
|
}
|
|
}
|
|
|
|
func nextAvailableReportPath(reportsDir string, timestamp time.Time) (string, error) {
|
|
destName := timestamp.Format("2006-01-02T15-04-05")
|
|
destPath := filepath.Join(reportsDir, destName)
|
|
_, err := os.Stat(destPath)
|
|
if os.IsNotExist(err) {
|
|
return destPath, nil
|
|
}
|
|
for i := 1; i <= 1000; i++ {
|
|
suffixedPath := filepath.Join(reportsDir, destName+"-"+strconv.Itoa(i))
|
|
_, err = os.Stat(suffixedPath)
|
|
if os.IsNotExist(err) {
|
|
return suffixedPath, nil
|
|
}
|
|
}
|
|
return "", E.New("no available report path for ", destName)
|
|
}
|