-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmain.go
More file actions
120 lines (111 loc) · 2.77 KB
/
main.go
File metadata and controls
120 lines (111 loc) · 2.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// convert uid and gid between mac and linux during rclone sync, using --metadata-mapper
//
// usage: rclone sync source:path dest:path --metadata-mapper /path/to/rclone-permissions-mapper
// or, to see input and output:
// rclone sync source:path dest:path --metadata-mapper /path/to/rclone-permissions-mapper -v --dump mapper
// https://rclone.org/docs/#metadata-mapper
// https://github.com/nielash/rclone-permissions-mapper
package main
import (
"encoding/json"
"fmt"
"log"
"os"
"path/filepath"
"strconv"
)
func main() {
// Read the input
var in map[string]any
err := json.NewDecoder(os.Stdin).Decode(&in)
if err != nil {
log.Fatal(err)
}
// Check the input
metadata, ok := in["Metadata"]
if !ok {
fmt.Fprintf(os.Stderr, "Metadata key not found\n")
os.Exit(1)
}
// Map the metadata
metadataOut := map[string]string{}
var out = map[string]any{
"Metadata": metadataOut,
}
// debug settings
debugging := false // set true to debug
dir := "/"
debugfile := ""
var df *os.File
if debugging {
dir, err = os.UserHomeDir()
if err == nil {
debugfile = filepath.Join(dir, "rclone-permissions-mapper-debug.txt")
}
df, err = os.Create(debugfile)
defer df.Close()
}
debug := func(format string, a ...any) {
if !debugging {
return
}
fmt.Fprintf(df, format, a...)
}
// loop through the metadata keys
for k, v := range metadata.(map[string]any) {
switch k {
case "error":
fmt.Fprintf(os.Stderr, "Error: %s\n", v)
os.Exit(1)
case "uid":
debug("uid detected! key: %s, val: %v\n", k, v)
uidstr, ok := v.(string)
osuid := os.Getuid()
debug("osuid: %v\n", osuid)
if ok {
uid, err := strconv.Atoi(uidstr)
if err != nil {
fmt.Fprintf(os.Stderr, "Error converting string to int: %v\n", uidstr)
}
// mac is 501 - 999, linux is 1000+
if (uid >= 1000 && osuid >= 501 && osuid < 1000) || (osuid >= 1000 && uid >= 501 && uid < 1000) {
// unset it
debug("unsetting. key: %s, val: %v\n", k, v)
continue
}
}
case "gid":
debug("gid detected! key: %s, val: %v\n", k, v)
gidstr, ok := v.(string)
if ok {
gid, err := strconv.Atoi(gidstr)
if err != nil {
fmt.Fprintf(os.Stderr, "Error converting string to int: %v\n", gidstr)
}
// mac is 20, linux is 1000
debug("osgid: %v\n", os.Getgid())
if gid != os.Getgid() {
// unset it
debug("unsetting. key: %s, val: %v\n", k, v)
continue
}
}
default:
debug("skipping -- key: %s, val: %v\n", k, v)
}
metadataOut[k] = v.(string)
}
// Write the output
json.NewEncoder(os.Stdout).Encode(&out)
if err != nil {
log.Fatal(err)
}
if debugging {
debug("final: \n")
bytes, err := json.MarshalIndent(&out, "", "\t")
debug("%v", string(bytes))
if err != nil {
debug("json err: %v", err.Error())
}
}
}