You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
3.0 KiB
124 lines
3.0 KiB
4 months ago
|
// Program mknames parses the cap_names.h file and creates an
|
||
|
// equivalent names.go file including comments on each cap.Value from
|
||
|
// the documentation directory.
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"flag"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"io/ioutil"
|
||
|
"log"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
header = flag.String("header", "", "name of header file")
|
||
|
text = flag.String("textdir", "", "directory name for value txt files")
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
flag.Parse()
|
||
|
|
||
|
if *header == "" {
|
||
|
log.Fatal("usage: mknames --header=.../cap_names.h")
|
||
|
}
|
||
|
d, err := ioutil.ReadFile(*header)
|
||
|
if err != nil {
|
||
|
log.Fatal("reading:", err)
|
||
|
}
|
||
|
|
||
|
b := bytes.NewBuffer(d)
|
||
|
|
||
|
var list []string
|
||
|
for {
|
||
|
line, err := b.ReadString('\n')
|
||
|
if err == io.EOF {
|
||
|
break
|
||
|
}
|
||
|
if !strings.Contains(line, `"`) {
|
||
|
continue
|
||
|
}
|
||
|
i := strings.Index(line, `"`)
|
||
|
line = line[i+1:]
|
||
|
i = strings.Index(line, `"`)
|
||
|
line = line[:i]
|
||
|
list = append(list, line)
|
||
|
}
|
||
|
|
||
|
// generate package file names.go
|
||
|
fmt.Print(`package cap
|
||
|
|
||
|
/* ** DO NOT EDIT THIS FILE. IT WAS AUTO-GENERATED BY LIBCAP'S GO BUILDER (mknames.go) ** */
|
||
|
|
||
|
// NamedCount holds the number of capability values with official
|
||
|
// names known at the time this libcap/cap version, was released. The
|
||
|
// "../libcap/cap" package is fully able to manipulate higher numbered
|
||
|
// capability values by numerical value. However, if you find
|
||
|
// cap.NamedCount < cap.MaxBits(), it is probably time to upgrade this
|
||
|
// package on your system.
|
||
|
//
|
||
|
// FWIW the userspace tool '/sbin/capsh' also contains a runtime check
|
||
|
// for the condition that libcap is behind the running kernel in this
|
||
|
// way.
|
||
|
const NamedCount = `, len(list), `
|
||
|
|
||
|
// CHOWN etc., are the named capability values of the Linux
|
||
|
// kernel. The canonical source for each name is the
|
||
|
// "uapi/linux/capabilities.h" file. Some values may not be available
|
||
|
// (yet) where the kernel is older. The actual number of capabities
|
||
|
// supported by the running kernel can be obtained using the
|
||
|
// cap.MaxBits() function.
|
||
|
const (
|
||
|
`)
|
||
|
bits := make(map[string]string)
|
||
|
for i, name := range list {
|
||
|
doc := fmt.Sprintf("%s/%d.txt", *text, i)
|
||
|
content, err := ioutil.ReadFile(doc)
|
||
|
if err != nil {
|
||
|
log.Fatalf("filed to read %q: %v", doc, err)
|
||
|
}
|
||
|
detail := strings.Split(strings.Replace(string(content), "CAP_", "cap.", -1), "\n")
|
||
|
if i != 0 {
|
||
|
fmt.Println()
|
||
|
}
|
||
|
v := strings.ToUpper(strings.TrimPrefix(name, "cap_"))
|
||
|
for j, line := range detail {
|
||
|
preamble := ""
|
||
|
offset := 0
|
||
|
if j == 0 {
|
||
|
if !strings.HasPrefix(line, "Allows ") {
|
||
|
log.Fatalf("line should begin \"Allows \": got %s:%d:%q", doc, j, line)
|
||
|
}
|
||
|
preamble = fmt.Sprint(v, " a")
|
||
|
offset = 1
|
||
|
}
|
||
|
if len(line) != 0 || j != len(detail)-1 {
|
||
|
fmt.Printf(" // %s%s\n", preamble, line[offset:])
|
||
|
}
|
||
|
}
|
||
|
bits[name] = v
|
||
|
if i == 0 {
|
||
|
fmt.Println(v, " Value = iota")
|
||
|
} else {
|
||
|
fmt.Println(v)
|
||
|
}
|
||
|
}
|
||
|
fmt.Print(`)
|
||
|
|
||
|
var names = map[Value]string{
|
||
|
`)
|
||
|
for _, name := range list {
|
||
|
fmt.Printf("%s: %q,\n", bits[name], name)
|
||
|
}
|
||
|
fmt.Print(`}
|
||
|
|
||
|
var bits = map[string]Value {
|
||
|
`)
|
||
|
for _, name := range list {
|
||
|
fmt.Printf("%q: %s,\n", name, bits[name])
|
||
|
}
|
||
|
fmt.Println(`}`)
|
||
|
}
|