4 Commits

Author SHA1 Message Date
b612 3501166592 bug fix 2021-07-07 10:39:07 +08:00
Starainrt d981a03b14 bug fix & netconn add 2021-06-04 10:44:53 +08:00
Starainrt fd5cf2c1f6 csv support 2021-05-17 15:09:04 +08:00
Starainrt c3ca057b96 add ini config parse and fix bug:math problem 2021-03-17 11:16:28 +08:00
24 changed files with 1256 additions and 190 deletions
+2
View File
@@ -0,0 +1,2 @@
.idea
.vscode
+21
View File
@@ -0,0 +1,21 @@
//+build darwin
package staros
import (
"os"
"syscall"
"time"
)
func timespecToTime(ts syscall.Timespec) time.Time {
return time.Unix(int64(ts.Sec), int64(ts.Nsec))
}
func GetFileCreationTime(fileinfo os.FileInfo) time.Time {
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Ctimespec)
}
func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
return timespecToTime(fileinfo.Sys().(*syscall.Stat_t).Atimespec)
}
+1 -1
View File
@@ -1,4 +1,4 @@
//+build linux darwin
//+build linux
package staros
+8
View File
@@ -17,3 +17,11 @@ func GetFileAccessTime(fileinfo os.FileInfo) time.Time {
d := fileinfo.Sys().(*syscall.Win32FileAttributeData)
return time.Unix(0, d.LastAccessTime.Nanoseconds())
}
func SetFileTimes(file *os.File,info os.FileInfo) {
}
func SetFileTimesbyTime(file *os.File) {
}
+17 -6
View File
@@ -14,7 +14,17 @@ func Calc(math string) (float64, error) {
if err := check(math); err != nil {
return 0, err
}
return calc(math)
result,err:=calc(math)
if err!=nil {
return 0,err
}
return floatRound(result,15),nil
}
func floatRound(f float64, n int) float64 {
format := "%." + strconv.Itoa(n) + "f"
res, _ := strconv.ParseFloat(fmt.Sprintf(format, f), 64)
return res
}
func check(math string) error {
@@ -37,11 +47,12 @@ func check(math string) error {
if string([]rune{v}) != "+" && string([]rune{v}) != "-" {
return fmt.Errorf("err at position %d.Reason is sign %s not correct", k, string([]rune{v}))
}
signReady = false
} else {
signReady = true
continue
}
}
signReady = false
}
if bracketSum != 0 {
return fmt.Errorf("Error:right bracket is not equal as left bracket")
@@ -188,16 +199,16 @@ func calcPool(numPool []float64, operPool []string) (float64, error) {
func calcSigFloat(floatA float64, b string, floatC float64) (float64, error) {
switch b {
case "+":
return floatA + floatC, nil
return floatRound(floatA + floatC,15), nil
case "-":
return floatA - floatC, nil
return floatRound(floatA - floatC,15), nil
case "*":
return floatA * floatC, nil
return floatRound(floatA * floatC,15), nil
case "/":
if floatC == 0 {
return 0, errors.New("Divisor cannot be 0")
}
return floatA / floatC, nil
return floatRound(floatA / floatC,15), nil
case "^":
return math.Pow(floatA, floatC), nil
}
+95 -2
View File
@@ -2,7 +2,100 @@
package staros
import (
"encoding/binary"
"fmt"
"golang.org/x/sys/unix"
"os/exec"
"strconv"
"strings"
"unsafe"
)
// Memory 系统内存信息
func Memory() MemStatus {
return MemStatus{}
func Memory() (MemStatus,error) {
return darwinMemory()
}
type swapUsage struct {
Total uint64
Avail uint64
Used uint64
Pagesize int32
Encrypted bool
}
func darwinMemory() (MemStatus, error) {
var err error
var res MemStatus
vm_stat, err := exec.LookPath("vm_stat")
if err != nil {
return res, err
}
out, err := exec.Command(vm_stat).CombinedOutput()
if err != nil {
return res, err
}
totalString, err := unix.Sysctl("hw.memsize")
if err != nil {
return res, err
}
// unix.sysctl() helpfully assumes the result is a null-terminated string and
// removes the last byte of the result if it's 0 :/
totalString += "\x00"
res.All = uint64(binary.LittleEndian.Uint64([]byte(totalString)))
lines := strings.Split(string(out), "\n")
pagesize := uint64(unix.Getpagesize())
for _, line := range lines {
fields := strings.Split(line, ":")
if len(fields) < 2 {
continue
}
key := strings.TrimSpace(fields[0])
value := strings.Trim(fields[1], " .")
switch key {
case "Pages free":
free, e := strconv.ParseUint(value, 10, 64)
if e != nil {
err = e
}
res.Free = free * pagesize
case "Pages inactive":
inactive, e := strconv.ParseUint(value, 10, 64)
if e != nil {
err = e
}
res.Available = inactive * pagesize
case "Pages active":
active, e := strconv.ParseUint(value, 10, 64)
if e != nil {
err = e
}
_ = active * pagesize
case "Pages wired down":
wired, e := strconv.ParseUint(value, 10, 64)
if e != nil {
err = e
}
_ = wired * pagesize
}
}
res.Available += res.Free
res.Used = res.All - res.Available
//swap
value, err := unix.SysctlRaw("vm.swapusage")
if err != nil {
return res, err
}
if len(value) != 32 {
return res, fmt.Errorf("unexpected output of sysctl vm.swapusage: %v (len: %d)", value, len(value))
}
swap := (*swapUsage)(unsafe.Pointer(&value[0]))
res.SwapAll = swap.Total
res.SwapUsed = swap.Used
res.SwapFree = swap.Avail
return res, err
}
+3 -3
View File
@@ -5,11 +5,11 @@ package staros
import "syscall"
// Memory 系统内存信息
func Memory() MemStatus {
func Memory() (MemStatus, error) {
var mem MemStatus
ram := new(syscall.Sysinfo_t)
if err := syscall.Sysinfo(ram); err != nil {
return mem
return mem, err
}
mem.All = uint64(ram.Totalram)
mem.BuffCache = uint64(ram.Bufferram)
@@ -20,5 +20,5 @@ func Memory() MemStatus {
mem.SwapFree = uint64(ram.Freeswap)
mem.SwapUsed = uint64(mem.SwapAll - mem.SwapFree)
mem.Used = uint64(mem.All - mem.Free)
return mem
return mem, nil
}
+26
View File
@@ -0,0 +1,26 @@
// +build windows
package staros
import "b612.me/win32api"
// Memory 系统内存信息
func Memory() (MemStatus, error) {
var mem MemStatus
ram := new(win32api.MEMORYSTATUSEX)
_, err := win32api.GlobalMemoryStatusEx(ram)
if err != nil {
return mem, err
}
mem.All = uint64(ram.UllTotalPhys)
mem.Free = uint64(ram.UllAvailPhys)
mem.Available = uint64(ram.UllAvailPhys)
mem.Used = uint64(mem.All - mem.Free)
mem.SwapAll = uint64(ram.UllTotalPageFile)
mem.SwapFree = uint64(ram.UllAvailPageFile)
mem.SwapUsed = mem.SwapAll - mem.SwapFree
mem.VirtualAll = uint64(mem.VirtualAll)
mem.VirtualAvail = uint64(mem.VirtualAvail)
mem.VirtualUsed = mem.VirtualAll - mem.VirtualUsed
return mem, nil
}
-85
View File
@@ -1,85 +0,0 @@
// +build !windows
package staros
import (
"errors"
"io/ioutil"
"strconv"
"strings"
"time"
)
func NetUsage() ([]NetAdapter, error) {
data, err := ioutil.ReadFile("/proc/net/dev")
if err != nil {
return []NetAdapter{}, err
}
sps := strings.Split(strings.TrimSpace(string(data)), "\n")
if len(sps) < 3 {
return []NetAdapter{}, errors.New("No Adaptor")
}
var res []NetAdapter
netLists := sps[2:]
for _, v := range netLists {
v = strings.ReplaceAll(v, " ", " ")
for strings.Contains(v, " ") {
v = strings.ReplaceAll(v, " ", " ")
}
v = strings.TrimSpace(v)
card := strings.Split(v, " ")
name := strings.ReplaceAll(card[0], ":", "")
recvBytes, _ := strconv.Atoi(card[1])
sendBytes, _ := strconv.Atoi(card[9])
res = append(res, NetAdapter{name, uint64(recvBytes), uint64(sendBytes)})
}
return res, nil
}
func NetUsageByname(name string) (NetAdapter, error) {
ada, err := NetUsage()
if err != nil {
return NetAdapter{}, err
}
for _, v := range ada {
if v.Name == name {
return v, nil
}
}
return NetAdapter{}, errors.New("Not Found")
}
func NetSpeeds(duration time.Duration) ([]NetSpeed, error) {
list1, err := NetUsage()
if err != nil {
return []NetSpeed{}, err
}
time.Sleep(duration)
list2, err := NetUsage()
if err != nil {
return []NetSpeed{}, err
}
if len(list1) > len(list2) {
return []NetSpeed{}, errors.New("NetWork Adaptor Num Not ok")
}
var res []NetSpeed
for k, v := range list1 {
recv := float64(list2[k].RecvBytes-v.RecvBytes) / duration.Seconds()
send := float64(list2[k].SendBytes-v.SendBytes) / duration.Seconds()
res = append(res, NetSpeed{v.Name, recv, send})
}
return res, nil
}
func NetSpeedsByName(duration time.Duration, name string) (NetSpeed, error) {
ada, err := NetSpeeds(duration)
if err != nil {
return NetSpeed{}, err
}
for _, v := range ada {
if v.Name == name {
return v, nil
}
}
return NetSpeed{}, errors.New("Not Found")
}
+9
View File
@@ -0,0 +1,9 @@
package staros
import (
"testing"
)
func Test_TrimSpace(t *testing.T) {
}
+248
View File
@@ -0,0 +1,248 @@
// +build !windows
package staros
import (
"errors"
"io/ioutil"
"os"
"strconv"
"strings"
"time"
)
func NetUsage() ([]NetAdapter, error) {
data, err := ioutil.ReadFile("/proc/net/dev")
if err != nil {
return []NetAdapter{}, err
}
sps := strings.Split(strings.TrimSpace(string(data)), "\n")
if len(sps) < 3 {
return []NetAdapter{}, errors.New("No Adaptor")
}
var res []NetAdapter
netLists := sps[2:]
for _, v := range netLists {
v = strings.ReplaceAll(v, " ", " ")
for strings.Contains(v, " ") {
v = strings.ReplaceAll(v, " ", " ")
}
v = strings.TrimSpace(v)
card := strings.Split(v, " ")
name := strings.ReplaceAll(card[0], ":", "")
recvBytes, _ := strconv.Atoi(card[1])
sendBytes, _ := strconv.Atoi(card[9])
res = append(res, NetAdapter{name, uint64(recvBytes), uint64(sendBytes)})
}
return res, nil
}
func NetUsageByname(name string) (NetAdapter, error) {
ada, err := NetUsage()
if err != nil {
return NetAdapter{}, err
}
for _, v := range ada {
if v.Name == name {
return v, nil
}
}
return NetAdapter{}, errors.New("Not Found")
}
func NetSpeeds(duration time.Duration) ([]NetSpeed, error) {
list1, err := NetUsage()
if err != nil {
return []NetSpeed{}, err
}
time.Sleep(duration)
list2, err := NetUsage()
if err != nil {
return []NetSpeed{}, err
}
if len(list1) > len(list2) {
return []NetSpeed{}, errors.New("NetWork Adaptor Num Not ok")
}
var res []NetSpeed
for k, v := range list1 {
recv := float64(list2[k].RecvBytes-v.RecvBytes) / duration.Seconds()
send := float64(list2[k].SendBytes-v.SendBytes) / duration.Seconds()
res = append(res, NetSpeed{v.Name, recv, send})
}
return res, nil
}
func NetSpeedsByName(duration time.Duration, name string) (NetSpeed, error) {
ada, err := NetSpeeds(duration)
if err != nil {
return NetSpeed{}, err
}
for _, v := range ada {
if v.Name == name {
return v, nil
}
}
return NetSpeed{}, errors.New("Not Found")
}
// NetConnections return all TCP/UDP/UNIX DOMAIN SOCKET Connections
// if your uid != 0 ,and analysePid==true ,you should have CAP_SYS_PRTACE and CAP_DAC_OVERRIDE/CAP_DAC_READ_SEARCH Caps
func NetConnections(analysePid bool) ([]NetConn, error) {
var result []NetConn
var inodeMap map[string]int64
var err error
fileList := []string{
"/proc/net/tcp",
"/proc/net/tcp6",
"/proc/net/udp",
"/proc/net/udp6",
"/proc/net/unix",
}
if analysePid {
inodeMap, err = GetInodeMap()
if err != nil {
return result, err
}
}
for _, file := range fileList {
data, err := ioutil.ReadFile(file)
if err != nil {
return result, err
}
tmpRes, err := analyseNetFiles(data, inodeMap, file[strings.LastIndex(file, "/")+1:])
if err != nil {
return result, err
}
result = append(result, tmpRes...)
}
return result, nil
}
func GetInodeMap() (map[string]int64, error) {
res := make(map[string]int64)
paths, err := ioutil.ReadDir("/proc")
if err != nil {
return nil, err
}
for _, v := range paths {
if v.IsDir() && Exists("/proc/"+v.Name()+"/fd") {
fds, err := ioutil.ReadDir("/proc/" + v.Name() + "/fd")
if err != nil && Exists("/proc/"+v.Name()+"/fd") {
return nil, err
}
for _, fd := range fds {
socket, err := os.Readlink("/proc/" + v.Name() + "/fd/" + fd.Name())
if err != nil {
continue
}
start := strings.Index(socket, "[")
if start < 0 {
continue
}
pid, err := strconv.ParseInt(v.Name(), 10, 64)
if err != nil {
break
}
res[socket[start+1:len(socket)-1]] = pid
}
}
}
return nil, err
}
func analyseNetFiles(data []byte, inodeMap map[string]int64, typed string) ([]NetConn, error) {
if typed == "unix" {
return analyseUnixFiles(data, inodeMap, typed)
}
var result []NetConn
strdata := strings.TrimSpace(string(data))
strdata = remainOne(strdata, " ", " ")
csvData := strings.Split(strdata, "\n")
pidMap := make(map[int64]*Process)
for line, lineData := range csvData {
if line == 0 {
continue
}
v := strings.Split(strings.TrimSpace(lineData), " ")
var res NetConn
ip, port, err := parseHexIpPort(v[1])
if err != nil {
return result, err
}
res.LocalAddr = ip
res.LocalPort = port
ip, port, err = parseHexIpPort(v[2])
if err != nil {
return result, err
}
res.RemoteAddr = ip
res.RemotePort = port
res.Uid, err = strconv.ParseInt(v[7], 10, 64)
if err != nil {
return result, err
}
res.Inode = v[9]
if inodeMap != nil && len(inodeMap) > 0 {
var ok bool
res.Pid, ok = inodeMap[res.Inode]
if !ok {
res.Pid = -1
} else {
_, ok := pidMap[res.Pid]
if !ok {
tmp, err := FindProcessByPid(res.Pid)
if err != nil {
pidMap[res.Pid] = nil
} else {
pidMap[res.Pid] = &tmp
}
}
res.Process = pidMap[res.Pid]
}
}
res.Typed = typed
result = append(result, res)
}
return result, nil
}
func analyseUnixFiles(data []byte, inodeMap map[string]int64, typed string) ([]NetConn, error) {
var result []NetConn
strdata := strings.TrimSpace(string(data))
strdata = remainOne(strdata, " ", " ")
csvData := strings.Split(strdata, "\n")
pidMap := make(map[int64]*Process)
for line, lineData := range csvData {
if line == 0 {
continue
}
v := strings.Split(strings.TrimSpace(lineData), " ")
var res NetConn
res.Inode = v[6]
if len(v) == 8 {
res.Socket = v[7]
}
if inodeMap != nil && len(inodeMap) > 0 {
var ok bool
res.Pid, ok = inodeMap[res.Inode]
if !ok {
res.Pid = -1
} else {
_, ok := pidMap[res.Pid]
if !ok {
tmp, err := FindProcessByPid(res.Pid)
if err != nil {
pidMap[res.Pid] = nil
} else {
pidMap[res.Pid] = &tmp
}
}
res.Uid = int64(pidMap[res.Pid].RUID)
res.Process = pidMap[res.Pid]
}
}
res.Typed = typed
result = append(result, res)
}
return result, nil
}
+7
View File
@@ -24,3 +24,10 @@ func NetSpeedsByName(duration time.Duration, name string) (NetSpeed, error) {
return NetSpeed{}, nil
}
// NetConnections return all TCP/UDP/UNIX DOMAIN SOCKET Connections
// if your uid != 0 ,and analysePid==true ,you should have CAP_SYS_PRTACE and CAP_DAC_OVERRIDE/CAP_DAC_READ_SEARCH Caps
func NetConnections(analysePid bool) ([]NetConn, error) {
var result []NetConn
return result, nil
}
+1 -1
View File
@@ -1,4 +1,4 @@
// +build !windows
// +build linux darwin unix
package staros
-17
View File
@@ -27,23 +27,6 @@ func IsRoot() bool {
return wincmd.Isas()
}
// Memory 系统内存信息
func Memory() MemStatus {
var mem MemStatus
ram := new(win32api.MEMORYSTATUSEX)
win32api.GlobalMemoryStatusEx(ram)
mem.All = uint64(ram.UllTotalPhys)
mem.Free = uint64(ram.UllAvailPhys)
mem.Available = uint64(ram.UllAvailPhys)
mem.Used = uint64(mem.All - mem.Free)
mem.SwapAll = uint64(ram.UllTotalPageFile)
mem.SwapFree = uint64(ram.UllAvailPageFile)
mem.SwapUsed = mem.SwapAll - mem.SwapFree
mem.VirtualAll = uint64(mem.VirtualAll)
mem.VirtualAvail = uint64(mem.VirtualAvail)
mem.VirtualUsed = mem.VirtualAll - mem.VirtualUsed
return mem
}
func DiskUsage(path string) (disk DiskStatus) {
kernel32, err := syscall.LoadLibrary("Kernel32.dll")
+33 -8
View File
@@ -7,6 +7,8 @@ import (
"io"
"os"
"os/exec"
"strings"
"sync"
"syscall"
"time"
)
@@ -26,11 +28,11 @@ type StarCmd struct {
errout []byte
runerr error
exitcode int
customCtx context.Context
stdoutBuf *bytes.Buffer
stderrBuf *bytes.Buffer
stdoutpoint int
stderrpoint int
lock sync.Mutex
prewrite []string
prewritetime time.Duration
stopctxfunc context.CancelFunc
@@ -98,12 +100,13 @@ func (starcli *StarCmd) queryStdout(ctx context.Context) {
case <-ctx.Done():
return
default:
break
}
out := make([]byte, 65535)
n, err := starcli.outfile.Read(out)
if n != 0 {
starcli.lock.Lock()
starcli.stdoutBuf.Write(out[:n])
starcli.lock.Unlock()
for _, v := range out[:n] {
starcli.stdout = append(starcli.stdout, v)
}
@@ -112,7 +115,9 @@ func (starcli *StarCmd) queryStdout(ctx context.Context) {
if err == io.EOF {
break
} else {
starcli.runerr = err
if !strings.Contains(err.Error(),"file already closed") {
starcli.runerr = err
}
return
}
}
@@ -125,12 +130,13 @@ func (starcli *StarCmd) queryStderr(ctx context.Context) {
case <-ctx.Done():
return
default:
break
}
out := make([]byte, 65535)
n, err := starcli.errfile.Read(out)
if n != 0 {
starcli.lock.Lock()
starcli.stderrBuf.Write(out[:n])
starcli.lock.Unlock()
for _, v := range out[:n] {
starcli.errout = append(starcli.errout, v)
}
@@ -139,7 +145,9 @@ func (starcli *StarCmd) queryStderr(ctx context.Context) {
if err == io.EOF {
break
} else {
starcli.runerr = err
if !strings.Contains(err.Error(),"file already closed") {
starcli.runerr = err
}
return
}
}
@@ -147,8 +155,10 @@ func (starcli *StarCmd) queryStderr(ctx context.Context) {
return
}
func (starcli *StarCmd) NowLineOutput() (string, error) {
starcli.lock.Lock()
buf, _ := starcli.stdoutBuf.ReadBytes('\n')
buferr, _ := starcli.stderrBuf.ReadBytes(byte('\n'))
starcli.lock.Unlock()
if len(buferr) != 0 {
return string(buf), errors.New(string(buferr))
}
@@ -156,11 +166,15 @@ func (starcli *StarCmd) NowLineOutput() (string, error) {
}
func (starcli *StarCmd) NowLineStdOut() string {
starcli.lock.Lock()
defer starcli.lock.Unlock()
buf, _ := starcli.stdoutBuf.ReadBytes('\n')
return string(buf)
}
func (starcli *StarCmd) NowLineStdErr() error {
starcli.lock.Lock()
defer starcli.lock.Unlock()
buferr, _ := starcli.stderrBuf.ReadBytes(byte('\n'))
if len(buferr) != 0 {
return errors.New(string(buferr))
@@ -170,16 +184,20 @@ func (starcli *StarCmd) NowLineStdErr() error {
func (starcli *StarCmd) NowAllOutput() (string, error) {
var outstr string
starcli.lock.Lock()
buf := make([]byte, starcli.stdoutBuf.Len())
n, _ := starcli.stdoutBuf.Read(buf)
starcli.lock.Unlock()
if n != 0 {
outstr = string(buf[:n])
}
if starcli.runerr != nil {
return outstr, starcli.runerr
}
starcli.lock.Lock()
buf = make([]byte, starcli.stderrBuf.Len())
n, _ = starcli.stderrBuf.Read(buf)
starcli.lock.Unlock()
if n != 0 {
return outstr, errors.New(string(buf[:n]))
}
@@ -188,8 +206,10 @@ func (starcli *StarCmd) NowAllOutput() (string, error) {
func (starcli *StarCmd) NowStdOut() string {
var outstr string
starcli.lock.Lock()
buf := make([]byte, starcli.stdoutBuf.Len())
n, _ := starcli.stdoutBuf.Read(buf)
starcli.lock.Unlock()
if n != 0 {
outstr = string(buf[:n])
}
@@ -197,9 +217,10 @@ func (starcli *StarCmd) NowStdOut() string {
}
func (starcli *StarCmd) NowStdErr() error {
starcli.lock.Lock()
buf := make([]byte, starcli.stderrBuf.Len())
n, _ := starcli.stderrBuf.Read(buf)
starcli.lock.Unlock()
if n != 0 {
return errors.New(string(buf[:n]))
}
@@ -292,9 +313,13 @@ func (starcli *StarCmd) ExitCode() int {
return starcli.exitcode
}
func (starcli *StarCmd) Kill() {
starcli.CMD.Process.Kill()
func (starcli *StarCmd) Kill() error{
err:=starcli.CMD.Process.Kill()
if err!=nil{
return err
}
starcli.running = false
return nil
}
func (starcli *StarCmd) GetPid() int {
+167 -54
View File
@@ -30,11 +30,43 @@ func FindProcessByName(name string) (datas []Process, err error) {
func FindProcess(compare func(Process) bool) (datas []Process, err error) {
var name, main string
var mainb []byte
paths, errs := ioutil.ReadDir("/proc")
if errs != nil {
err = errs
var netErr error
var netInfo []NetConn
paths, err := ioutil.ReadDir("/proc")
if err != nil {
return
}
netInfo, netErr = NetConnections(false)
appendNetInfo := func(p *Process) {
if netErr != nil {
p.netErr = netErr
return
}
fds, err := ioutil.ReadDir("/proc/" + strconv.Itoa(int(p.Pid)) + "/fd")
if err != nil && Exists("/proc/"+strconv.Itoa(int(p.Pid))+"/fd") {
p.netErr = err
return
}
for _, fd := range fds {
socket, err := os.Readlink("/proc/" + strconv.Itoa(int(p.Pid)) + "/fd/" + fd.Name())
if err != nil {
p.netErr = err
return
}
start := strings.Index(socket, "[")
if start < 0 {
continue
}
sid := socket[start+1 : len(socket)-1]
for _, v := range netInfo {
if v.Inode == sid {
v.Pid = p.Pid
v.Process = p
p.netConn = append(p.netConn, v)
}
}
}
}
for _, v := range paths {
if v.IsDir() && Exists("/proc/"+v.Name()+"/comm") {
name, err = readAsString("/proc/" + v.Name() + "/comm")
@@ -49,68 +81,80 @@ func FindProcess(compare func(Process) bool) (datas []Process, err error) {
tmp.Name = strings.TrimSpace(name)
main, err = readAsString("/proc/" + v.Name() + "/status")
if err != nil {
tmp.Err = err
if compare(tmp) {
appendNetInfo(&tmp)
datas = append(datas, tmp)
continue
}
} else {
data := splitBy(main, ":")
tmp.Pid, _ = strconv.ParseInt(data["Pid"], 10, 64)
tmp.PPid, _ = strconv.ParseInt(data["PPid"], 10, 64)
tmp.TPid, _ = strconv.ParseInt(data["TracerPid"], 10, 64)
uids := splitBySpace(data["Uid"])
gids := splitBySpace(data["Gid"])
tmp.RUID, _ = strconv.Atoi(uids[0])
tmp.EUID, _ = strconv.Atoi(uids[1])
tmp.RGID, _ = strconv.Atoi(gids[0])
tmp.EGID, _ = strconv.Atoi(gids[1])
tmp.VmPeak, _ = strconv.ParseInt(splitBySpace(data["VmPeak"])[0], 10, 64)
tmp.VmSize, _ = strconv.ParseInt(splitBySpace(data["VmSize"])[0], 10, 64)
tmp.VmHWM, _ = strconv.ParseInt(splitBySpace(data["VmHWM"])[0], 10, 64)
tmp.VmRSS, _ = strconv.ParseInt(splitBySpace(data["VmRSS"])[0], 10, 64)
tmp.VmLck, _ = strconv.ParseInt(splitBySpace(data["VmLck"])[0], 10, 64)
tmp.VmData, _ = strconv.ParseInt(splitBySpace(data["VmData"])[0], 10, 64)
tmp.VmLck *= 1024
tmp.VmData *= 1024
tmp.VmPeak *= 1024
tmp.VmSize *= 1024
tmp.VmHWM *= 1024
tmp.VmRSS *= 1024
}
data := splitBy(main, ":")
tmp.Pid, _ = strconv.ParseInt(data["Pid"], 10, 64)
tmp.PPid, _ = strconv.ParseInt(data["PPid"], 10, 64)
tmp.TPid, _ = strconv.ParseInt(data["TracerPid"], 10, 64)
uids := splitBySpace(data["Uid"])
gids := splitBySpace(data["Gid"])
tmp.RUID, _ = strconv.Atoi(uids[0])
tmp.EUID, _ = strconv.Atoi(uids[1])
tmp.RGID, _ = strconv.Atoi(gids[0])
tmp.EGID, _ = strconv.Atoi(gids[1])
tmp.VmPeak, _ = strconv.ParseInt(splitBySpace(data["VmPeak"])[0], 10, 64)
tmp.VmSize, _ = strconv.ParseInt(splitBySpace(data["VmSize"])[0], 10, 64)
tmp.VmHWM, _ = strconv.ParseInt(splitBySpace(data["VmHWM"])[0], 10, 64)
tmp.VmRSS, _ = strconv.ParseInt(splitBySpace(data["VmRSS"])[0], 10, 64)
tmp.VmLck, _ = strconv.ParseInt(splitBySpace(data["VmLck"])[0], 10, 64)
tmp.VmData, _ = strconv.ParseInt(splitBySpace(data["VmData"])[0], 10, 64)
tmp.VmLck *= 1024
tmp.VmData *= 1024
tmp.VmPeak *= 1024
tmp.VmSize *= 1024
tmp.VmHWM *= 1024
tmp.VmRSS *= 1024
mainb, err = ioutil.ReadFile("/proc/" + v.Name() + "/cmdline")
if err != nil {
tmp.Err = err
if compare(tmp) {
appendNetInfo(&tmp)
datas = append(datas, tmp)
continue
}
} else {
args := bytes.Split(mainb, []byte{0})
for _, v := range args {
tmp.Args = append(tmp.Args, string(v))
}
}
args := bytes.Split(mainb, []byte{0})
for _, v := range args {
tmp.Args = append(tmp.Args, string(v))
}
mainb, err = ioutil.ReadFile("/proc/" + v.Name() + "/environ")
if err != nil {
tmp.Err = err
if compare(tmp) {
appendNetInfo(&tmp)
datas = append(datas, tmp)
continue
}
}
args = bytes.Split(mainb, []byte{0})
for _, v := range args {
tmp.Env = append(tmp.Env, string(v))
} else {
args := bytes.Split(mainb, []byte{0})
for _, v := range args {
tmp.Env = append(tmp.Env, string(v))
}
}
main, err = readAsString("/proc/" + v.Name() + "/stat")
if err != nil {
tmp.Err = err
if compare(tmp) {
appendNetInfo(&tmp)
datas = append(datas, tmp)
continue
}
} else {
times := splitBySpace(main)
uptime, _ := strconv.ParseInt(strings.TrimSpace(times[21]), 10, 64)
tmp.Uptime = time.Unix(StartTime().Unix()+uptime/100, int64((float64(uptime)/100-float64(uptime/100))*1000000000))
}
times := splitBySpace(main)
uptime, _ := strconv.ParseInt(strings.TrimSpace(times[21]), 10, 64)
tmp.Uptime = time.Unix(StartTime().Unix()+uptime/100, int64((float64(uptime)/100-float64(uptime/100))*1000000000))
if compare(tmp) {
appendNetInfo(&tmp)
datas = append(datas, tmp)
}
}
@@ -126,6 +170,38 @@ func FindProcessByPid(pid int64) (datas Process, err error) {
err = errors.New("Not Found")
return
}
netInfo, netErr := NetConnections(false)
appendNetInfo := func(p *Process) {
if netErr != nil {
p.netErr = netErr
return
}
fds, err := ioutil.ReadDir("/proc/" + strconv.Itoa(int(p.Pid)) + "/fd")
if err != nil && Exists("/proc/"+strconv.Itoa(int(p.Pid))+"/fd") {
p.netErr = err
return
}
for _, fd := range fds {
socket, err := os.Readlink("/proc/" + strconv.Itoa(int(p.Pid)) + "/fd/" + fd.Name())
if err != nil {
p.netErr = err
return
}
start := strings.Index(socket, "[")
if start < 0 {
continue
}
sid := socket[start+1 : len(socket)-1]
for _, v := range netInfo {
if v.Inode == sid {
v.Pid = p.Pid
v.Process = p
p.netConn = append(p.netConn, v)
}
}
}
}
name, err = readAsString("/proc/" + fmt.Sprint(pid) + "/comm")
if err != nil {
return
@@ -157,22 +233,27 @@ func FindProcessByPid(pid int64) (datas Process, err error) {
datas.VmSize *= 1024
datas.VmHWM *= 1024
datas.VmRSS *= 1024
appendNetInfo(&datas)
mainb, err = ioutil.ReadFile("/proc/" + fmt.Sprint(pid) + "/cmdline")
if err != nil {
return
}
args := bytes.Split(mainb, []byte{0})
for _, v := range args {
datas.Args = append(datas.Args, string(v))
datas.Err = err
err = nil
} else {
args := bytes.Split(mainb, []byte{0})
for _, v := range args {
datas.Args = append(datas.Args, string(v))
}
}
mainb, err = ioutil.ReadFile("/proc/" + fmt.Sprint(pid) + "/environ")
if err != nil {
return
}
args = bytes.Split(mainb, []byte{0})
for _, v := range args {
datas.Env = append(datas.Env, string(v))
datas.Err = err
err = nil
} else {
args := bytes.Split(mainb, []byte{0})
for _, v := range args {
datas.Env = append(datas.Env, string(v))
}
}
datas.LocalPath, err = os.Readlink("/proc/" + fmt.Sprint(pid) + "/exe")
@@ -202,25 +283,49 @@ func Daemon(path string, args ...string) (int, error) {
return pid, err
}
func (starcli *StarCmd) SetRunUser(uid, gid uint32) {
func DaemonWithUser(uid, gid uint32,groups []uint32,path string, args ...string) (int, error) {
cmd := exec.Command(path, args...)
cmd.SysProcAttr = &syscall.SysProcAttr{
Credential: &syscall.Credential{
Uid: uid,
Gid: gid,
Groups: groups,
},
Setsid: true,
}
if err := cmd.Start(); err != nil {
return -1, err
}
pid := cmd.Process.Pid
err := cmd.Process.Release()
return pid, err
}
func (starcli *StarCmd) SetRunUser(uid, gid uint32,groups []uint32) {
starcli.CMD.SysProcAttr = &syscall.SysProcAttr{
Credential: &syscall.Credential{
Uid: uid,
Gid: gid,
Groups: groups,
},
Setsid: true,
}
}
func (starcli *StarCmd) Release() error {
if err := starcli.CMD.Start(); err != nil {
return err
if starcli.CMD.SysProcAttr == nil {
starcli.CMD.SysProcAttr = &syscall.SysProcAttr{
Setsid: true,
}
} else {
starcli.CMD.SysProcAttr.Setsid = true
}
starcli.CMD.SysProcAttr = &syscall.SysProcAttr{
Setsid: true,
if !starcli.IsRunning() {
if err := starcli.CMD.Start(); err != nil {
return err
}
}
starcli.CMD.Process.Release()
return nil
return starcli.CMD.Process.Release()
}
func (starcli *StarCmd) SetKeepCaps() error {
@@ -230,3 +335,11 @@ func (starcli *StarCmd) SetKeepCaps() error {
}
return nil
}
func SetKeepCaps() error {
_, _, err := syscall.RawSyscall(157 /*SYS PRCTL */, 0x8 /*PR SET KEEPCAPS*/, 1, 0)
if 0 != err {
return err
}
return nil
}
+8
View File
@@ -62,3 +62,11 @@ func Daemon(path string, args ...string) (int, error) {
func (starcli *StarCmd) SetRunUser(uid, gid uint32) {
}
func (starcli *StarCmd) Release() error {
if err := starcli.CMD.Start(); err != nil {
return err
}
starcli.CMD.Process.Release()
return nil
}
+261
View File
@@ -0,0 +1,261 @@
package sysconf
import (
"bytes"
"errors"
"fmt"
"reflect"
"strconv"
"strings"
)
type CSV struct {
header []string
text [][]string
}
type CSVRow struct {
header []string
data []string
}
type CSVValue struct {
key string
value string
}
func ParseCSV(data []byte, hasHeader bool) (csv CSV, err error) {
strData := strings.Split(string(bytes.TrimSpace(data)), "\n")
if len(strData) < 1 {
err = fmt.Errorf("cannot parse data,invalid data format")
}
var header []string
var text [][]string
if hasHeader {
header = csvAnalyse(strData[0])
strData = strData[1:]
} else {
num := len(csvAnalyse(strData[0]))
for i := 0; i < num; i++ {
header = append(header, strconv.Itoa(i))
}
}
for k, v := range strData {
tmpData := csvAnalyse(v)
if len(tmpData) != len(header) {
err = fmt.Errorf("cannot parse data line %d,got %d values but need %d", k, len(tmpData), len(header))
return
}
text = append(text, tmpData)
}
csv.header = header
csv.text = text
return
}
func (csv *CSV) Header() []string {
return csv.header
}
func (csv *CSV) Data() [][]string {
return csv.text
}
func (csv *CSV) Row(row int) *CSVRow {
if row >= len(csv.Data()) {
return nil
}
return &CSVRow{
header: csv.Header(),
data: csv.Data()[row],
}
}
func (csv *CSVRow) Get(key string) *CSVValue {
for k, v := range csv.header {
if v == key {
return &CSVValue{
key: key,
value: csv.data[k],
}
}
}
return nil
}
func (csv *CSVRow) Col(key int) *CSVValue {
if key >= len(csv.header) {
return nil
}
return &CSVValue{
key: csv.header[key],
value: csv.data[key],
}
}
func (csv *CSVRow) Header() []string {
return csv.header
}
func (csv *CSV) MapData() []map[string]string {
var result []map[string]string
for _, v := range csv.text {
tmp := make(map[string]string)
for k, v2 := range csv.header {
tmp[v2] = v[k]
}
result = append(result, tmp)
}
return result
}
func CsvAnalyse(data string) []string {
return csvAnalyse(data)
}
func csvAnalyse(data string) []string {
var segStart bool = false
var segReady bool = false
var segSign string = ""
var dotReady bool = false
data = strings.TrimSpace(data)
var result []string
var seg string
for k, v := range []rune(data) {
if k == 0 && v != []rune(`"`)[0] {
dotReady = true
}
if v != []rune(`,`)[0] && dotReady {
segSign = `,`
segStart = true
dotReady = false
if v == []rune(`"`)[0] {
segSign = `"`
continue
}
}
if dotReady && v == []rune(`,`)[0] {
//dotReady = false
result = append(result, "")
continue
}
if v == []rune(`"`)[0] && segStart {
if !segReady {
segReady = true
continue
}
seg += `"`
segReady = false
continue
}
if segReady && segSign == `"` && segStart {
segReady = false
segStart = false
result = append(result, seg)
segSign = ``
seg = ""
}
if v == []rune(`"`)[0] && !segStart {
segStart = true
segReady = false
segSign = `"`
continue
}
if v == []rune(`,`)[0] && !segStart {
dotReady = true
}
if v == []rune(`,`)[0] && segStart && segSign == "," {
segStart = false
result = append(result, seg)
dotReady = true
segSign = ``
seg = ""
}
if segStart {
seg = string(append([]rune(seg), v))
}
}
if len(data) != 0 && len(result) == 0 && seg == "" {
result = append(result, data)
} else {
result = append(result, seg)
}
return result
}
func MarshalCSV(header []string, ins interface{}) ([]byte, error) {
var result [][]string
t := reflect.TypeOf(ins)
v := reflect.ValueOf(ins)
if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
return nil, errors.New("not a Slice or Array")
}
if t.Kind() == reflect.Ptr {
t = t.Elem()
v = v.Elem()
}
for i := 0; i < v.Len(); i++ {
subT := reflect.TypeOf(v.Index(i).Interface())
subV := reflect.ValueOf(v.Index(i).Interface())
if subV.Kind() == reflect.Slice || subV.Kind() == reflect.Array {
if subT.Kind() == reflect.Ptr {
subV = subV.Elem()
}
var tmp []string
for j := 0; j < subV.Len(); j++ {
tmp = append(tmp, fmt.Sprint(reflect.ValueOf(subV.Index(j))))
}
result = append(result, tmp)
}
if subV.Kind() == reflect.Struct {
var tmp []string
if subT.Kind() == reflect.Ptr {
subV = subV.Elem()
}
for i := 0; i < subV.NumField(); i++ {
tmp = append(tmp, fmt.Sprint(subV.Field(i)))
}
result = append(result, tmp)
}
}
return buildCSV(header,result)
}
func buildCSV(header []string, data [][]string) ([]byte, error) {
var result []string
var length int
build := func(slc []string) string {
for k, v := range slc {
if strings.Index(v, `"`) >= 0 {
v = strings.ReplaceAll(v, `"`, `""`)
}
if strings.Index(v,"\n")>=0 {
v=strings.ReplaceAll(v,"\n",`\n`)
}
if strings.Index(v,"\r")>=0 {
v=strings.ReplaceAll(v,"\r",`\r`)
}
v = `"` + v + `"`
slc[k] = v
}
return strings.Join(slc, ",")
}
if len(header) != 0 {
result = append(result, build(header))
length = len(header)
} else {
length = len(data[0])
}
for k, v := range data {
if len(v) != length {
return nil, fmt.Errorf("line %d got length %d ,but need %d", k, len(v), length)
}
result = append(result, build(v))
}
return []byte(strings.Join(result, "\n")), nil
}
+38
View File
@@ -0,0 +1,38 @@
package sysconf
import (
"fmt"
"testing"
)
func Test_csv(t *testing.T) {
//var test Sqlplus
var text=`
姓名,班级,性别,年龄
张三,"我,不""知道",boy,23
"里斯","哈哈",girl,23
`
fmt.Println(csvAnalyse(`请求权,lkjdshck,dsvdsv,"sdvkjsdv,",=dsvdsv,"=,dsvsdv"`))
a,b:=ParseCSV([]byte(text),true)
fmt.Println(b)
fmt.Println(a.Row(0).Col(3).MustInt())
}
type csvtest struct {
A string
B int
}
func Test_Masharl(t *testing.T) {
//var test Sqlplus
/*
var a []csvtest = []csvtest{
{"lala",1},
{"haha",34},
}
*/
var a [][]string
a=append(a,[]string{"a","b","c"})
a=append(a,[]string{"1",`s"s"d`,"3"})
b,_:=MarshalCSV([]string{},a)
fmt.Println(string(b))
}
+120
View File
@@ -0,0 +1,120 @@
package sysconf
import "strconv"
func (csv *CSVValue)Key()string {
return csv.key
}
func (csv *CSVValue)Int()(int,error) {
tmp,err:=strconv.Atoi(csv.value)
return tmp,err
}
func (csv *CSVValue)MustInt()int {
tmp,err:=csv.Int()
if err!=nil {
panic(err)
}
return tmp
}
func (csv *CSVValue)Int64()(int64,error) {
tmp,err:=strconv.ParseInt(csv.value,10,64)
return tmp,err
}
func (csv *CSVValue)MustInt64()int64 {
tmp,err:=csv.Int64()
if err!=nil {
panic(err)
}
return tmp
}
func (csv *CSVValue)Int32()(int32,error) {
tmp,err:=strconv.ParseInt(csv.value,10,32)
return int32(tmp),err
}
func (csv *CSVValue)MustInt32()int32 {
tmp,err:=csv.Int32()
if err!=nil {
panic(err)
}
return tmp
}
func (csv *CSVValue)Uint64()(uint64,error) {
tmp,err:=strconv.ParseUint(csv.value,10,64)
return tmp,err
}
func (csv *CSVValue)MustUint64()uint64 {
tmp,err:=csv.Uint64()
if err!=nil {
panic(err)
}
return tmp
}
func (csv *CSVValue)Uint32()(uint32,error) {
tmp,err:=strconv.ParseUint(csv.value,10,32)
return uint32(tmp),err
}
func (csv *CSVValue)MustUint32()uint32 {
tmp,err:=csv.Uint32()
if err!=nil {
panic(err)
}
return tmp
}
func (csv *CSVValue)String()string {
return csv.value
}
func (csv *CSVValue)Byte()[]byte {
return []byte(csv.value)
}
func (csv *CSVValue)Bool()(bool,error) {
tmp,err:=strconv.ParseBool(csv.value)
return tmp,err
}
func (csv *CSVValue)MustBool()bool {
tmp,err:=csv.Bool()
if err!=nil {
panic(err)
}
return tmp
}
func (csv *CSVValue)Float64()(float64,error) {
tmp,err:=strconv.ParseFloat(csv.value,64)
return tmp,err
}
func (csv *CSVValue)MustFloat64()float64 {
tmp,err:=csv.Float64()
if err!=nil {
panic(err)
}
return tmp
}
func (csv *CSVValue)Float32()(float32,error) {
tmp,err:=strconv.ParseFloat(csv.value,32)
return float32(tmp),err
}
func (csv *CSVValue)MustFloat32()float32 {
tmp,err:=csv.Float32()
if err!=nil {
panic(err)
}
return tmp
}
+26 -13
View File
@@ -9,8 +9,6 @@ import (
"strconv"
"strings"
"sync"
"b612.me/staros"
)
type SysConf struct {
@@ -47,6 +45,18 @@ type SysNode struct {
lock sync.RWMutex
}
func NewIni() *SysConf {
ini := NewSysConf("=")
ini.CommentCR = true
ini.CommentFlag = []string{"#", ";"}
ini.HaveSegMent = true
ini.SegStart = "["
ini.SegEnd = "]"
ini.SpaceStr = " "
ini.EscapeFlag = "\\"
return ini
}
func NewSysConf(EqualFlag string) *SysConf {
syscnf := new(SysConf)
syscnf.EqualFlag = EqualFlag
@@ -64,9 +74,6 @@ func NewLinuxConf(EqualFlag string) *SysConf {
}
func (syscfg *SysConf) ParseFromFile(filepath string) error {
if !staros.Exists(filepath) {
return errors.New(filepath + " 不存在")
}
data, err := ioutil.ReadFile(filepath)
if err != nil {
return err
@@ -470,7 +477,7 @@ func SliceIn(slice interface{}, data interface{}) bool {
// Unmarshal 输出结果到结构体中
func (cfg *SysConf) Unmarshal(ins interface{}) error {
var structSet func(t reflect.Type, v reflect.Value) error
var structSet func(t reflect.Type, v reflect.Value,oriSeg string) error
t := reflect.TypeOf(ins)
v := reflect.ValueOf(ins).Elem()
if v.Kind() != reflect.Struct {
@@ -480,7 +487,7 @@ func (cfg *SysConf) Unmarshal(ins interface{}) error {
return errors.New("Cannot Write!")
}
t = t.Elem()
structSet = func(t reflect.Type, v reflect.Value) error {
structSet = func(t reflect.Type, v reflect.Value,oriSeg string) error {
for i := 0; i < t.NumField(); i++ {
tp := t.Field(i)
vl := v.Field(i)
@@ -488,11 +495,14 @@ func (cfg *SysConf) Unmarshal(ins interface{}) error {
continue
}
if vl.Type().Kind() == reflect.Struct {
structSet(vl.Type(), vl)
structSet(vl.Type(), vl,tp.Tag.Get("seg"))
continue
}
seg := tp.Tag.Get("seg")
key := tp.Tag.Get("key")
if oriSeg!="" {
seg=oriSeg
}
if seg == "" || key == "" {
continue
}
@@ -520,12 +530,12 @@ func (cfg *SysConf) Unmarshal(ins interface{}) error {
}
return nil
}
return structSet(t, v)
return structSet(t, v,"")
}
// Marshal 输出结果到结构体中
func (cfg *SysConf) Marshal(ins interface{}) ([]byte, error) {
var structSet func(t reflect.Type, v reflect.Value)
var structSet func(t reflect.Type, v reflect.Value,oriSeg string)
t := reflect.TypeOf(ins)
v := reflect.ValueOf(ins)
if v.Kind() != reflect.Struct {
@@ -535,18 +545,21 @@ func (cfg *SysConf) Marshal(ins interface{}) ([]byte, error) {
t = t.Elem()
v = v.Elem()
}
structSet = func(t reflect.Type, v reflect.Value) {
structSet = func(t reflect.Type, v reflect.Value,oriSeg string) {
for i := 0; i < t.NumField(); i++ {
var seg, key, comment string = "", "", ""
tp := t.Field(i)
vl := v.Field(i)
if vl.Type().Kind() == reflect.Struct {
structSet(vl.Type(), vl)
structSet(vl.Type(), vl,tp.Tag.Get("seg"))
continue
}
seg = tp.Tag.Get("seg")
key = tp.Tag.Get("key")
comment = tp.Tag.Get("comment")
if oriSeg != "" {
seg=oriSeg
}
if seg == "" || key == "" {
continue
}
@@ -557,7 +570,7 @@ func (cfg *SysConf) Marshal(ins interface{}) ([]byte, error) {
}
}
structSet(t, v)
structSet(t, v,"")
return cfg.Build(), nil
}
+30
View File
@@ -36,3 +36,33 @@ func Test_Parse(t *testing.T) {
//fmt.Println(cfg.Data[0].Comment)
fmt.Println(string(cfg.Build()))
}
type slicetest struct {
A string `seg:"s" key:"a"`
B string `seg:"a" key:"b"`
}
type testme struct {
Love slicetest `seg:"love"`
Star slicetest `seg:"star"`
}
func Test_Marshal(t *testing.T) {
var info string =`
[love]
a=abc
b=123
[star]
a=456
b=789
`
var tmp testme
ini:=NewIni()
ini.Parse([]byte(info))
ini.Unmarshal(&tmp)
fmt.Printf("%+v\n",tmp)
b,_:=ini.Marshal(tmp)
fmt.Println(string(b))
}
+115
View File
@@ -2,7 +2,9 @@ package staros
import (
"bytes"
"errors"
"io/ioutil"
"strconv"
"strings"
)
@@ -42,3 +44,116 @@ func readAsString(path string) (string, error) {
}
return string(data), nil
}
func remainOne(data, old, new string) string {
data = strings.TrimSpace(data)
if !strings.Contains(data, old) {
return data
}
data = strings.ReplaceAll(data, old, new)
return remainOne(data, old, new)
}
func parseHexIpPort(str string) (string, int, error) {
str = strings.TrimSpace(str)
if len(str) != 13 && len(str) != 37 {
return "", 0, errors.New("Not a valid ip:port addr:" + str)
}
ipPort := strings.Split(str, ":")
if len(ipPort) != 2 {
return "", 0, errors.New("Not a valid ip:port addr:" + str)
}
if len(ipPort[0]) == 8 {
ip, err := parseHexIPv4(ipPort[0])
if err != nil {
return "", 0, err
}
port, err := parseHexPort(ipPort[1])
return ip, port, err
}
if len(ipPort[0]) == 32 {
ip, err := parseHexIPv6(ipPort[0])
if err != nil {
return "", 0, err
}
port, err := parseHexPort(ipPort[1])
return ip, port, err
}
return "", 0, errors.New("Invalid ip address:" + str)
}
func parseHexPort(str string) (int, error) {
tmpUint32, err := strconv.ParseUint(str, 16, 32)
return int(tmpUint32), err
}
func parseHexIPv4(str string) (string, error) {
var result string
if len(str) != 8 {
return "", errors.New("Not a vaild ipv4:" + str)
}
tmpUint64, err := strconv.ParseUint(str, 16, 32)
if err != nil {
return "", err
}
numicIp := uint32(tmpUint64)
for i := 0; i < 4; i++ {
result += strconv.FormatUint(uint64(uint8(numicIp>>(8*uint8(i)))), 10) + "."
}
return result[0 : len(result)-1], nil
}
func parseHexIPv6(str string) (string, error) {
var result string
if len(str) != 32 {
return "", errors.New("Not a vaild ipv6:" + str)
}
for i := 0; i < 4; i++ {
part := str[i*8 : (i+1)*8]
tmpUint64, err := strconv.ParseUint(part, 16, 32)
if err != nil {
return "", err
}
tmpUint32 := uint32(tmpUint64)
//07C2022A
for i := 0; i < 4; i++ {
tmp := strconv.FormatUint(uint64(uint8(tmpUint32>>uint8(8*i))), 16)
if len(tmp) == 1 {
tmp = "0" + tmp
}
result += tmp
if (i+1)%2 == 0 {
result += ":"
}
}
}
ipv6 := result[0 : len(result)-1]
ipv6List := strings.Split(ipv6, ":")
prepareZero := false
alreadyZero := false
for k, v := range ipv6List {
if v == "0000" && !alreadyZero {
ipv6List[k] = ""
prepareZero = true
continue
}
if v != "0000" && prepareZero {
alreadyZero = true
}
var nonZero = 0
for i := 0; i < 4; i++ {
sig := v[i : i+1]
if sig != "0" {
nonZero = i
break
}
}
ipv6List[k] = v[nonZero:4]
}
ipv6 = strings.TrimSuffix(remainOne(strings.Join(ipv6List, ":"), ":::", "::"), "::")
if ipv6 == "" {
ipv6 = "::0"
}
return ipv6, nil
}
+20
View File
@@ -46,6 +46,13 @@ type Process struct {
VmHWM int64
VmRSS int64
VmData int64
netConn []NetConn
netErr error
Err error
}
func (p Process) GetNetConns() ([]NetConn, error) {
return p.netConn, p.netErr
}
type MemStatus struct {
@@ -70,3 +77,16 @@ type DiskStatus struct {
Free uint64
Available uint64
}
type NetConn struct {
LocalAddr string
LocalPort int
Typed string
RemoteAddr string
RemotePort int
Socket string
Inode string
Pid int64
Uid int64
Process *Process
}