github.com/meulengracht/snapd@v0.0.0-20210719210640-8bde69bcc84e/systemd/escape.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2014-2015 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package systemd 21 22 import ( 23 "bytes" 24 "fmt" 25 "path/filepath" 26 "strings" 27 ) 28 29 const allowed = `:_.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789` 30 31 // EscapeUnitNamePath works like systemd-escape --path 32 // FIXME: we could use github.com/coreos/go-systemd/unit/escape.go 33 // and EscapePath from it. 34 // 35 // But thats not in the archive and it won't work with go1.3 36 func EscapeUnitNamePath(in string) string { 37 // "" is the same as "/" which is escaped to "-" 38 // the filepath.Clean will turn "" into "." and make this incorrect 39 if len(in) == 0 { 40 return "-" 41 } 42 buf := bytes.NewBuffer(nil) 43 44 // clean and trim leading/trailing "/" 45 in = filepath.Clean(in) 46 in = strings.Trim(in, "/") 47 48 // empty strings is "/" 49 if len(in) == 0 { 50 in = "/" 51 } 52 // leading "." is special 53 if in[0] == '.' { 54 fmt.Fprintf(buf, `\x%x`, in[0]) 55 in = in[1:] 56 } 57 58 // replace all special chars 59 for i := 0; i < len(in); i++ { 60 c := in[i] 61 if c == '/' { 62 buf.WriteByte('-') 63 } else if strings.IndexByte(allowed, c) >= 0 { 64 buf.WriteByte(c) 65 } else { 66 fmt.Fprintf(buf, `\x%x`, []byte{in[i]}) 67 } 68 } 69 70 return buf.String() 71 }