diff --git a/libbsm.go b/libbsm.go index 9e5510d..355ff82 100644 --- a/libbsm.go +++ b/libbsm.go @@ -1,15 +1,30 @@ // This is an implementation of libbsm // Copyright johan@nosd.in 2021 // +// +build freebsd +// +// Use libc to get pw name from uid + package main +/* +#cgo CFLAGS: -I /usr/lib +#cgo LDFLAGS: -L. -lc +#include +#include +#include +#include +#include +*/ +import "C" + import ( "io" "os" "fmt" -// "net" "time" "bytes" + "strconv" "encoding/binary" ) @@ -95,7 +110,15 @@ const ( // Display control - PRT_ONELINE = 1 + PRT_ONELINE = 1 + PRT_NORESOLVE_USER = 2 +) + +var ( + // A global user/uid cache + gUsers []user + // A global group/gid cache + gGroups []group ) // Fields types, from https://github.com/freebsd/freebsd-src/blob/main/contrib/openbsm/bsm/libbsm.h @@ -282,6 +305,96 @@ type Text struct { /* Utilities */ +// users ID for resolution +type user struct { + uid uint32 + name string +} + +// groups ID for resolution +type group struct { + gid uint32 + name string +} + +/* Utilities */ +// Return uid if user not found +func getUserName(uid uint32) (string, error) { + for _, u := range gUsers { + if u.uid == uid { + return u.name, nil + } + } + // Not found in cache, get it from system query + u, err := getUserNameByUid(uid) + if err != nil { + // If not found, return user object with name = uid + if err.Error() == "User ID not found" { + u.uid = uid + u.name = strconv.FormatUint(uint64(uid), 10) + gUsers = append(gUsers, u) + return u.name, err + } else { + return "", err + } + } + gUsers = append(gUsers, u) + return u.name, nil +} +func getUserNameByUid(uid uint32) (user, error) { + var pw *C.struct_passwd + var usr user + + pw = C.getpwuid((C.uint32_t)(uid)) + if pw == nil { + return usr, fmt.Errorf("User ID not found") + } + + usr.uid = uid + usr.name = C.GoString(pw.pw_name) + + return usr, nil +} + + +func getGroupName(gid uint32) (string, error) { + for _, g := range gGroups { + if g.gid == gid { + return g.name, nil + } + } + // Not found in cache, get it from system query + g, err := getGroupNameByGid(gid) + if err != nil { + // If not found, return group object with name = gid + if err.Error() == "Group ID not found" { + g.gid = gid + g.name = strconv.FormatUint(uint64(gid), 10) + gGroups = append(gGroups, g) + return g.name, err + } else { + return "", err + } + } + gGroups = append(gGroups, g) + return g.name, nil +} +func getGroupNameByGid(gid uint32) (group, error) { + var gr *C.struct_group + var grp group + + gr = C.getgrgid((C.uint32_t)(gid)) + if gr == nil { + return grp, fmt.Errorf("Group ID not found") + } + + grp.gid = gid + grp.name = C.GoString(gr.gr_name) + + return grp, nil +} + + func PrintIpv4FromInt(ipv4int uint32) string { return fmt.Sprintf("%d.%d.%d.%d", ipv4int & 0xFF000000 >> 24, ipv4int & 0x00FF0000 >> 16, ipv4int & 0x0000FF00 >> 8, ipv4int & 0x000000FF) @@ -296,7 +409,6 @@ func PrintIpv6FromInt(ipv6int [4]uint32) string { ipv6int[3] & 0xFFFF0000 >> 16, ipv6int[3] & 0x0000FFFF) } - /* Records structs implementation */ func NewHeader32(h Header32) *Header32 { return &Header32{ @@ -352,6 +464,8 @@ func (h *Header32) Print(file *os.File, delimiter string, flags int) { h.E_type, delimiter, h.E_mod, delimiter, t.Format(time.UnixDate), delimiter, h.Msec) if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -393,9 +507,9 @@ func (e *ExecArg) LoadFromBinary(file *os.File) error { return fmt.Errorf("Error searching for null terminated exec arg: Loop exec n%d, offset of record start: %x, error : %v", i, startOf, err) } // Allocate before reading - //e.Text[i] = make([]byte, len(buf)) totLen += int64(len(arg)) - e.Text = append(e.Text, arg) + //e.Text = append(e.Text, arg) // Discard last 0 + e.Text = append(e.Text, arg[:len(arg)-1]) } startOf, err = file.Seek(int64(startOf+totLen), io.SeekStart) @@ -417,6 +531,8 @@ func (e *ExecArg) Print(file *os.File, delimiter string, flags int) { } if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -456,7 +572,7 @@ func (p *Path) LoadFromBinary(file *os.File) error { return fmt.Errorf("Error searching for null terminated path: offset of record start: %x, error : %v", startOf, err) } totLen := int64(len(arg)) - p.Path = arg + p.Path = arg[:totLen-1] startOf, err = file.Seek(int64(startOf+totLen), io.SeekStart) if err != nil { @@ -470,6 +586,8 @@ func (p *Path) Print(file *os.File, delimiter string, flags int) { fmt.Fprintf(file, "path%s%s", delimiter, string(p.Path)) if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -511,11 +629,24 @@ func (a *Attribute32) LoadFromBinary(file *os.File) error { } func (a *Attribute32) Print(file *os.File, delimiter string, flags int) { + var user string + var group string // TODO : resolve Uid and Gid (also support domain accounts) - fmt.Fprintf(file, "attribute%s%o%s%v%s%v%s%v%s%v%s%v", delimiter, a.Mode, delimiter, a.Uid, delimiter, - a.Gid, delimiter, a.Fsid, delimiter, a.Nid, delimiter, a.Dev) + if PRT_NORESOLVE_USER == flags & PRT_NORESOLVE_USER { + user = string(a.Uid) + group = string(a.Gid) + } else { + user, _ = getUserName(a.Uid) + group, _ = getGroupName(a.Gid) + } + + fmt.Fprintf(file, "attribute%s%o%s%v%s%v%s%v%s%v%s%v", delimiter, a.Mode, delimiter, user, delimiter, + group, delimiter, a.Fsid, delimiter, a.Nid, delimiter, a.Dev) + if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -557,11 +688,22 @@ func (a *Attribute64) LoadFromBinary(file *os.File) error { } func (a *Attribute64) Print(file *os.File, delimiter string, flags int) { + var user string + var group string // TODO : resolve Uid and Gid (also support domain accounts) - fmt.Fprintf(file, "attribute%s%o%s%v%s%v%s%v%s%v%s%v", delimiter, a.Mode, delimiter, a.Uid, delimiter, - a.Gid, delimiter, a.Fsid, delimiter, a.Nid, delimiter, a.Dev) + if PRT_NORESOLVE_USER == flags & PRT_NORESOLVE_USER { + user = string(a.Uid) + group = string(a.Gid) + } else { + user, _ = getUserName(a.Uid) + group, _ = getGroupName(a.Gid) + } + fmt.Fprintf(file, "attribute%s%o%s%v%s%v%s%v%s%v%s%v", delimiter, a.Mode, delimiter, user, delimiter, + group, delimiter, a.Fsid, delimiter, a.Nid, delimiter, a.Dev) if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -608,11 +750,28 @@ func (s *Subject32) LoadFromBinary(file *os.File) error { } func (s *Subject32) Print(file *os.File, delimiter string, flags int) { - fmt.Fprintf(file, "subject%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%s", delimiter, s.Auid, delimiter, s.Euid, delimiter, s.Egid, - delimiter, s.Ruid, delimiter, s.Rgid, delimiter, s.Sid, delimiter, s.Tid.Port, delimiter, s.Tid.IpVers, + var euser string + var egroup string + var ruser string + var rgroup string + if PRT_NORESOLVE_USER == flags & PRT_NORESOLVE_USER { + euser = string(s.Euid) + egroup = string(s.Egid) + ruser = string(s.Ruid) + rgroup = string(s.Rgid) + } else { + euser, _ = getUserName(s.Euid) + egroup, _ = getGroupName(s.Egid) + ruser, _ = getUserName(s.Ruid) + rgroup, _ = getGroupName(s.Rgid) + } + fmt.Fprintf(file, "subject%s%v%s%s%s%s%s%s%s%s%s%v%s%v%s%v%s%s", delimiter, s.Auid, delimiter, euser, delimiter, egroup, + delimiter, ruser, delimiter, rgroup, delimiter, s.Sid, delimiter, s.Tid.Port, delimiter, s.Tid.IpVers, delimiter, PrintIpv4FromInt(s.Tid.Addr)) if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -659,11 +818,28 @@ func (p *Process32) LoadFromBinary(file *os.File) error { } func (p *Process32) Print(file *os.File, delimiter string, flags int) { - fmt.Fprintf(file, "process%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%s", delimiter, p.Auid, delimiter, p.Euid, delimiter, p.Egid, - delimiter, p.Ruid, delimiter, p.Rgid, delimiter, p.Sid, delimiter, p.Tid.Port, delimiter, p.Tid.IpVers, + var euser string + var egroup string + var ruser string + var rgroup string + if PRT_NORESOLVE_USER == flags & PRT_NORESOLVE_USER { + euser = string(p.Euid) + egroup = string(p.Egid) + ruser = string(p.Ruid) + rgroup = string(p.Rgid) + } else { + euser, _ = getUserName(p.Euid) + egroup, _ = getGroupName(p.Egid) + ruser, _ = getUserName(p.Ruid) + rgroup, _ = getGroupName(p.Rgid) + } + fmt.Fprintf(file, "process%s%v%s%s%s%s%s%s%s%s%s%v%s%v%s%v%s%s", delimiter, p.Auid, delimiter, euser, delimiter, egroup, + delimiter, ruser, delimiter, rgroup, delimiter, p.Sid, delimiter, p.Tid.Port, delimiter, p.Tid.IpVers, delimiter, PrintIpv4FromInt(p.Tid.Addr)) if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -725,17 +901,35 @@ func (s *Subject32Ex) LoadFromBinary(file *os.File) error { } func (s *Subject32Ex) Print(file *os.File, delimiter string, flags int) { - if s.Tid.IpVers == 0x04 { - fmt.Fprintf(file, "subject_ex%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%s", delimiter, s.Auid, delimiter, s.Euid, - delimiter, s.Egid, delimiter, s.Ruid, delimiter, s.Rgid, delimiter, s.Sid, delimiter, s.Tid.Port, delimiter, - s.Tid.Ttype, delimiter, PrintIpv4FromInt(s.Tid.Addr4)) + var euser string + var egroup string + var ruser string + var rgroup string + var ip string + if PRT_NORESOLVE_USER == flags & PRT_NORESOLVE_USER { + euser = string(s.Euid) + egroup = string(s.Egid) + ruser = string(s.Ruid) + rgroup = string(s.Rgid) } else { - fmt.Fprintf(file, "subject_ex%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%s", delimiter, s.Auid, delimiter, s.Euid, - delimiter, s.Egid, delimiter, s.Ruid, delimiter, s.Rgid, delimiter, s.Sid, delimiter, s.Tid.Port, delimiter, - s.Tid.Ttype, delimiter, PrintIpv6FromInt(s.Tid.Addr6)) + euser, _ = getUserName(s.Euid) + egroup, _ = getGroupName(s.Egid) + ruser, _ = getUserName(s.Ruid) + rgroup, _ = getGroupName(s.Rgid) } + if s.Tid.IpVers == 0x04 { + ip = PrintIpv4FromInt(s.Tid.Addr4) + } else { + ip = PrintIpv6FromInt(s.Tid.Addr6) + } + fmt.Fprintf(file, "subject_ex%s%v%s%s%s%s%s%s%s%s%s%v%s%v%s%v%s%s", delimiter, s.Auid, delimiter, euser, + delimiter, egroup, delimiter, ruser, delimiter, rgroup, delimiter, s.Sid, delimiter, s.Tid.Port, delimiter, + s.Tid.Ttype, delimiter, ip) + if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -797,17 +991,37 @@ func (p *Process32Ex) LoadFromBinary(file *os.File) error { } func (p *Process32Ex) Print(file *os.File, delimiter string, flags int) { - if p.Tid.IpVers == 0x04 { - fmt.Fprintf(file, "process_ex%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%s", delimiter, p.Auid, delimiter, p.Euid, - delimiter, p.Egid, delimiter, p.Ruid, delimiter, p.Rgid, delimiter, p.Sid, delimiter, p.Tid.Port, delimiter, - p.Tid.Ttype, delimiter, PrintIpv4FromInt(p.Tid.Addr4)) + var euser string + var egroup string + var ruser string + var rgroup string + var ip string + if PRT_NORESOLVE_USER == flags & PRT_NORESOLVE_USER { + euser = string(p.Euid) + egroup = string(p.Egid) + ruser = string(p.Ruid) + rgroup = string(p.Rgid) } else { - fmt.Fprintf(file, "process_ex%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%s", delimiter, p.Auid, delimiter, p.Euid, - delimiter, p.Egid, delimiter, p.Ruid, delimiter, p.Rgid, delimiter, p.Sid, delimiter, p.Tid.Port, delimiter, - p.Tid.Ttype, delimiter, PrintIpv6FromInt(p.Tid.Addr6)) + euser, _ = getUserName(p.Euid) + egroup, _ = getGroupName(p.Egid) + ruser, _ = getUserName(p.Ruid) + rgroup, _ = getGroupName(p.Rgid) } + + if p.Tid.IpVers == 0x04 { + ip = PrintIpv4FromInt(p.Tid.Addr4) + } else { + ip = PrintIpv6FromInt(p.Tid.Addr6) + } + + fmt.Fprintf(file, "process_ex%s%v%s%s%s%s%s%s%s%s%s%v%s%v%s%v%s%s", delimiter, p.Auid, delimiter, euser, + delimiter, egroup, delimiter, ruser, delimiter, rgroup, delimiter, p.Sid, delimiter, p.Tid.Port, delimiter, + p.Tid.Ttype, delimiter, ip) + if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -854,11 +1068,28 @@ func (s *Subject64) LoadFromBinary(file *os.File) error { } func (s *Subject64) Print(file *os.File, delimiter string, flags int) { - fmt.Fprintf(file, "subject%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%s", delimiter, s.Auid, delimiter, s.Euid, delimiter, s.Egid, - delimiter, s.Ruid, delimiter, s.Rgid, delimiter, s.Sid, delimiter, s.Tid.Port, delimiter, s.Tid.IpVers, + var euser string + var egroup string + var ruser string + var rgroup string + if PRT_NORESOLVE_USER == flags & PRT_NORESOLVE_USER { + euser = string(s.Euid) + egroup = string(s.Egid) + ruser = string(s.Ruid) + rgroup = string(s.Rgid) + } else { + euser, _ = getUserName(s.Euid) + egroup, _ = getGroupName(s.Egid) + ruser, _ = getUserName(s.Ruid) + rgroup, _ = getGroupName(s.Rgid) + } + fmt.Fprintf(file, "subject%s%v%s%s%s%s%s%s%s%s%s%v%s%v%s%v%s%s", delimiter, s.Auid, delimiter, euser, delimiter, egroup, + delimiter, ruser, delimiter, rgroup, delimiter, s.Sid, delimiter, s.Tid.Port, delimiter, s.Tid.IpVers, delimiter, PrintIpv4FromInt(s.Tid.Addr)) if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -905,11 +1136,28 @@ func (p *Process64) LoadFromBinary(file *os.File) error { } func (p *Process64) Print(file *os.File, delimiter string, flags int) { - fmt.Fprintf(file, "process%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%s", delimiter, p.Auid, delimiter, p.Euid, delimiter, p.Egid, - delimiter, p.Ruid, delimiter, p.Rgid, delimiter, p.Sid, delimiter, p.Tid.Port, delimiter, p.Tid.IpVers, + var euser string + var egroup string + var ruser string + var rgroup string + if PRT_NORESOLVE_USER == flags & PRT_NORESOLVE_USER { + euser = string(p.Euid) + egroup = string(p.Egid) + ruser = string(p.Ruid) + rgroup = string(p.Rgid) + } else { + euser, _ = getUserName(p.Euid) + egroup, _ = getGroupName(p.Egid) + ruser, _ = getUserName(p.Ruid) + rgroup, _ = getGroupName(p.Rgid) + } + fmt.Fprintf(file, "process%s%v%s%s%s%s%s%s%s%s%s%v%s%v%s%v%s%s", delimiter, p.Auid, delimiter, euser, delimiter, egroup, + delimiter, ruser, delimiter, rgroup, delimiter, p.Sid, delimiter, p.Tid.Port, delimiter, p.Tid.IpVers, delimiter, PrintIpv4FromInt(p.Tid.Addr)) if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -970,17 +1218,36 @@ func (s *Subject64Ex) LoadFromBinary(file *os.File) error { } func (s *Subject64Ex) Print(file *os.File, delimiter string, flags int) { - if s.Tid.IpVers == 0x04 { - fmt.Fprintf(file, "subject_ex%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%s", delimiter, s.Auid, delimiter, s.Euid, - delimiter, s.Egid, delimiter, s.Ruid, delimiter, s.Rgid, delimiter, s.Sid, delimiter, s.Tid.Port, delimiter, - s.Tid.Ttype, delimiter, PrintIpv4FromInt(s.Tid.Addr4)) + var euser string + var egroup string + var ruser string + var rgroup string + var ip string + if PRT_NORESOLVE_USER == flags & PRT_NORESOLVE_USER { + euser = string(s.Euid) + egroup = string(s.Egid) + ruser = string(s.Ruid) + rgroup = string(s.Rgid) } else { - fmt.Fprintf(file, "subject_ex%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%s", delimiter, s.Auid, delimiter, s.Euid, - delimiter, s.Egid, delimiter, s.Ruid, delimiter, s.Rgid, delimiter, s.Sid, delimiter, s.Tid.Port, delimiter, - s.Tid.Ttype, delimiter, PrintIpv6FromInt(s.Tid.Addr6)) + euser, _ = getUserName(s.Euid) + egroup, _ = getGroupName(s.Egid) + ruser, _ = getUserName(s.Ruid) + rgroup, _ = getGroupName(s.Rgid) } + if s.Tid.IpVers == 0x04 { + ip = PrintIpv4FromInt(s.Tid.Addr4) + } else { + ip = PrintIpv6FromInt(s.Tid.Addr6) + } + + fmt.Fprintf(file, "subject_ex%s%v%s%s%s%s%s%s%s%s%s%v%s%v%s%v%s%s", delimiter, s.Auid, delimiter, euser, + delimiter, egroup, delimiter, ruser, delimiter, rgroup, delimiter, s.Sid, delimiter, s.Tid.Port, delimiter, + s.Tid.Ttype, delimiter, ip) + if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -998,7 +1265,7 @@ func NewProcess64Ex(p Process64Ex) *Process64Ex { } func (p *Process64Ex) GetType() uint8 { - return AUT_SUBJECT64_EX + return AUT_PROCESS64_EX } func (p *Process64Ex) LoadFromBinary(file *os.File) error { @@ -1041,17 +1308,36 @@ func (p *Process64Ex) LoadFromBinary(file *os.File) error { } func (p *Process64Ex) Print(file *os.File, delimiter string, flags int) { - if p.Tid.IpVers == 0x04 { - fmt.Fprintf(file, "process_ex%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%s", delimiter, p.Auid, delimiter, p.Euid, - delimiter, p.Egid, delimiter, p.Ruid, delimiter, p.Rgid, delimiter, p.Sid, delimiter, p.Tid.Port, delimiter, - p.Tid.Ttype, delimiter, PrintIpv4FromInt(p.Tid.Addr4)) + var euser string + var egroup string + var ruser string + var rgroup string + var ip string + if PRT_NORESOLVE_USER == flags & PRT_NORESOLVE_USER { + euser = string(p.Euid) + egroup = string(p.Egid) + ruser = string(p.Ruid) + rgroup = string(p.Rgid) } else { - fmt.Fprintf(file, "process_ex%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%v%s%s", delimiter, p.Auid, delimiter, p.Euid, - delimiter, p.Egid, delimiter, p.Ruid, delimiter, p.Rgid, delimiter, p.Sid, delimiter, p.Tid.Port, delimiter, - p.Tid.Ttype, delimiter, PrintIpv6FromInt(p.Tid.Addr6)) + euser, _ = getUserName(p.Euid) + egroup, _ = getGroupName(p.Egid) + ruser, _ = getUserName(p.Ruid) + rgroup, _ = getGroupName(p.Rgid) } + if p.Tid.IpVers == 0x04 { + ip = PrintIpv4FromInt(p.Tid.Addr4) + } else { + ip = PrintIpv6FromInt(p.Tid.Addr6) + } + + fmt.Fprintf(file, "process_ex%s%v%s%s%s%s%s%s%s%s%s%v%s%v%s%v%s%s", delimiter, p.Auid, delimiter, euser, + delimiter, egroup, delimiter, ruser, delimiter, rgroup, delimiter, p.Sid, delimiter, p.Tid.Port, delimiter, + p.Tid.Ttype, delimiter, ip) + if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -1080,6 +1366,8 @@ func (r *Return32) Print(file *os.File, delimiter string, flags int) { fmt.Fprintf(file, "return%s%v%s%v", delimiter, r.Status, delimiter, r.Ret) if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -1108,6 +1396,8 @@ func (r *Return64) Print(file *os.File, delimiter string, flags int) { fmt.Fprintf(file, "return%s%v%s%v", delimiter, r.Status, delimiter, r.Ret) if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -1134,9 +1424,8 @@ func (t *Trailer) LoadFromBinary(file *os.File) error { func (t *Trailer) Print(file *os.File, delimiter string, flags int) { fmt.Fprintf(file, "trailer%s%v", delimiter, t.Count) - if 0 == (flags & PRT_ONELINE) { - fmt.Fprintf(file, "\n") - } +// The trailer close the record print, whatever the oneLine flag value + fmt.Fprintf(file, "\n") } func NewArg32(a Arg32) *Arg32 { @@ -1182,7 +1471,7 @@ func (a *Arg32) LoadFromBinary(file *os.File) error { return fmt.Errorf("Error searching for null terminated path: offset of record start: %x, error : %v", startOf, err) } totLen := int64(len(arg)) - a.Text = arg + a.Text = arg[:totLen-1] startOf, err = file.Seek(int64(startOf+totLen), io.SeekStart) if err != nil { @@ -1196,6 +1485,8 @@ func (a *Arg32) Print(file *os.File, delimiter string, flags int) { fmt.Fprintf(file, "argument%s%v%s%v%s%s", delimiter, a.No, delimiter, a.Val, delimiter, string(a.Text)) if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -1242,7 +1533,7 @@ func (a *Arg64) LoadFromBinary(file *os.File) error { return fmt.Errorf("Error searching for null terminated path: offset of record start: %x, error : %v", startOf, err) } totLen := int64(len(arg)) - a.Text = arg + a.Text = arg[:totLen-1] startOf, err = file.Seek(int64(startOf+totLen), io.SeekStart) if err != nil { @@ -1256,6 +1547,8 @@ func (a *Arg64) Print(file *os.File, delimiter string, flags int) { fmt.Fprintf(file, "argument%s%v%s%v%s%s", delimiter, a.No, delimiter, a.Val, delimiter, string(a.Text)) if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -1284,6 +1577,8 @@ func (e *Exit) Print(file *os.File, delimiter string, flags int) { fmt.Fprintf(file, "exit%s%v%s%v", delimiter, e.Status, delimiter, e.Ret) if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -1306,7 +1601,7 @@ func (t *Text) LoadFromBinary(file *os.File) error { text := make([]byte, t.Length) err = binary.Read(file, binary.BigEndian, &text) if err != nil { return fmt.Errorf("Unable to read Text.Text from file: %v", err) } - t.Text = text + t.Text = text[:len(text)-1] return nil } @@ -1315,6 +1610,8 @@ func (t *Text) Print(file *os.File, delimiter string, flags int) { fmt.Fprintf(file, "text%s%s", delimiter, t.Text) if 0 == (flags & PRT_ONELINE) { fmt.Fprintf(file, "\n") + } else { + fmt.Fprintf(file, "%s", delimiter) } } @@ -1334,7 +1631,6 @@ func readRecordToStruct(file *os.File) (Record, error) { /* startOf, _ := file.Seek(0, io.SeekCurrent) fmt.Printf("Offset dans le fichier : %x\n", startOf) */ - //switch hdr.(int8) { switch (int8)(hdr[0]) { case AUT_HEADER32: var h Header32 diff --git a/main.go b/main.go index 79ba1c8..1b4f6b1 100644 --- a/main.go +++ b/main.go @@ -104,8 +104,12 @@ func print_tokens(filename string) error { func main() { - - pflag.BoolVarP(&randFlag, "randFlag", "r", false, "A random flag, just to play you.") + var flags int + var oneLine bool + var noUserResolve bool + + pflag.BoolVarP(&oneLine, "oneline", "l", false, "Prints the entire record on the same line. If this option is not specified, every token is displayed on a different line.") + pflag.BoolVarP(&noUserResolve, "numeric", "n", false, "Do not convert user and group IDs to their names but leave in their numeric forms.") pflag.BoolVarP(&showVersion, "version", "V", false, "Show version then exit") pflag.Parse() @@ -115,6 +119,14 @@ func main() { return } + if oneLine { + flags = flags + PRT_ONELINE + } + + if noUserResolve { + flags = flags + PRT_NORESOLVE_USER + } + args := os.Args filename := args[len(args)-1] @@ -146,7 +158,7 @@ func main() { } return } - rec.Print(os.Stdout, ",", 0) + rec.Print(os.Stdout, ",", flags) } } }