aboutsummaryrefslogtreecommitdiffhomepage
path: root/cmd/hsu/parse.go
blob: 35704c613cfcd1715e526b6445dc775df815810e (plain)
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
package main

import (
	"bufio"
	"errors"
	"fmt"
	"io"
	"log"
	"strings"
)

func parseUint32Fast(s string) (int, error) {
	sLen := len(s)
	if sLen < 1 {
		return -1, errors.New("zero length string")
	}
	if sLen > 10 {
		return -1, errors.New("string too long")
	}

	n := 0
	for i, ch := range []byte(s) {
		ch -= '0'
		if ch > 9 {
			return -1, fmt.Errorf("invalid character '%s' at index %d", string(ch+'0'), i)
		}
		n = n*10 + int(ch)
	}
	return n, nil
}

func parseConfig(r io.Reader, puid int) (fid int, ok bool, err error) {
	s := bufio.NewScanner(r)
	var line, puid0 int
	for s.Scan() {
		line++

		// <puid> <fid>
		lf := strings.SplitN(s.Text(), " ", 2)
		if len(lf) != 2 {
			return -1, false, fmt.Errorf("invalid entry on line %d", line)
		}

		puid0, err = parseUint32Fast(lf[0])
		if err != nil || puid0 < 1 {
			return -1, false, fmt.Errorf("invalid parent uid on line %d", line)
		}

		ok = puid0 == puid
		if ok {
			// allowed fid range 0 to 99
			if fid, err = parseUint32Fast(lf[1]); err != nil || fid < 0 || fid > 99 {
				return -1, false, fmt.Errorf("invalid identity on line %d", line)
			}
			return
		}
	}
	return -1, false, s.Err()
}

func mustParseConfig(r io.Reader, puid int) (int, bool) {
	fid, ok, err := parseConfig(r, puid)
	if err != nil {
		log.Fatal(err)
	}
	return fid, ok
}