commit 965dae211063408d3b2d314470731e469c29afe6 Author: 兔子 Date: Tue Feb 11 10:53:25 2020 +0800 init diff --git a/files.go b/files.go new file mode 100644 index 0000000..0e81316 --- /dev/null +++ b/files.go @@ -0,0 +1,33 @@ +package staros + +import "os" + +// 检测文件/文件夹是否存在 +func Exists(path string) bool { + _, err := os.Stat(path) + if err != nil && os.IsNotExist(err) { + return false + } + return true +} + + +// IsFile 返回给定文件地址是否是一个文件, +//True为是一个文件,False为不是文件或路径无效 +func IsFile(fpath string) bool { + s, err := os.Stat(fpath) + if err != nil { + return false + } + return !s.IsDir() +} + +// IsFolder 返回给定文件地址是否是一个文件夹, +//True为是一个文件夹,False为不是文件夹或路径无效 +func IsFolder(fpath string) bool { + s, err := os.Stat(fpath) + if err != nil { + return false + } + return s.IsDir() +} \ No newline at end of file diff --git a/os_linux.go b/os_linux.go new file mode 100644 index 0000000..a29a5ca --- /dev/null +++ b/os_linux.go @@ -0,0 +1,66 @@ +// +build linux darwin + +package staros + +import ( + "os/user" + "strconv" + "strings" + "syscall" + "time" +) + +// StartTime 开机时间 +func StartTime() time.Time { + tmp, _ := readAsString("/proc/stat") + data := splitBy(ReplaceByte9(tmp), " ") + btime, _ := strconv.ParseInt(strings.TrimSpace(data["btime"]), 10, 64) + return time.Unix(btime, 0) +} + +// IsRoot 当前是否是管理员用户 +func IsRoot() bool { + uid, _ := user.Current() + if uid.Uid == "0" { + return true + } + return false +} + +// Memory 系统内存信息 +func Memory() MemStatus { + var mem MemStatus + ram := new(syscall.Sysinfo_t) + if err := syscall.Sysinfo(ram); err != nil { + return mem + } + mem.All = ram.Totalram + mem.BuffCache = ram.Bufferram + mem.Free = ram.Freeram + mem.Shared = ram.Sharedram + mem.Available = ram.Freeram + ram.Sharedram + ram.Bufferram + mem.SwapAll = ram.Totalswap + mem.SwapFree = ram.Freeswap + mem.SwapUsed = mem.SwapAll - mem.SwapFree + mem.Used = mem.All - mem.Free + return mem +} + +func Whoami() (uid, gid int, uname, gname, home string, err error) { + var me *user.User + var gup *user.Group + me, err = user.Current() + if err != nil { + return + } + uid, _ = strconv.Atoi(me.Uid) + gid, _ = strconv.Atoi(me.Uid) + home = me.HomeDir + uname = me.Username + gup, err = user.LookupGroupId(me.Gid) + if err != nil { + return + } + gname = gup.Name + return +} diff --git a/os_windows.go b/os_windows.go new file mode 100644 index 0000000..4b59447 --- /dev/null +++ b/os_windows.go @@ -0,0 +1,43 @@ +// +build windows + +package staros + +import ( + "time" + + "b612.me/wincmd" + + "b612.me/win32api" +) + +// StartTime 开机时间 +func StartTime() time.Time { + data, _ := win32api.GetTickCount() + date := float64(time.Now().Unix()) + unix := date - float64(data)/1000 + max := (unix - float64(int64(unix))) * 1000000000 + return time.Unix(int64(unix), int64(max)) +} + +// IsRoot 当前是否是管理员用户 +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 +} diff --git a/process_linux.go b/process_linux.go new file mode 100644 index 0000000..bfacf66 --- /dev/null +++ b/process_linux.go @@ -0,0 +1,132 @@ +// +build linux darwin + +package staros + +import ( + "bytes" + "errors" + "fmt" + "io/ioutil" + "os" + "path/filepath" + "strconv" + "strings" + "time" +) + +// FindProcessByName 通过进程名来查询应用信息 +func FindProcessByName(pname string) (datas []Process, err error) { + var name, main string + var mainb []byte + paths, errs := ioutil.ReadDir("/proc") + if errs != nil { + err = errs + return + } + for _, v := range paths { + if v.IsDir() && Exists("/proc/"+v.Name()+"/comm") { + name, err = readAsString("/proc/" + v.Name() + "/comm") + if err != nil { + return + } + if strings.TrimSpace(name) == pname { + var tmp Process + main, err = readAsString("/proc/" + v.Name() + "/status") + if err != nil { + return + } + data := splitBy(main, ":") + tmp.Name = pname + 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]) + mainb, err = ioutil.ReadFile("/proc/" + v.Name() + "/cmdline") + if err != nil { + return + } + args := bytes.Split(mainb, []byte{0}) + for _, v := range args { + tmp.Args = append(tmp.Args, string(v)) + } + tmp.LocalPath, err = os.Readlink("/proc/" + v.Name() + "/exe") + if err != nil { + return + } + tmp.LocalPath = filepath.Dir(tmp.LocalPath) + tmp.ExecPath, err = os.Readlink("/proc/" + v.Name() + "/cwd") + if err != nil { + return + } + main, err = readAsString("/proc/" + v.Name() + "/stat") + if err != nil { + return + } + 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)) + datas = append(datas, tmp) + } + } + } + return +} + +// FindProcessByPid 通过Pid来查询应用信息 +func FindProcessByPid(pid int64) (datas Process, err error) { + var name, main string + var mainb []byte + if !Exists("/proc/" + fmt.Sprint(pid) + "/comm") { + err = errors.New("Not Found") + return + } + name, err = readAsString("/proc/" + fmt.Sprint(pid) + "/comm") + if err != nil { + return + } + main, err = readAsString("/proc/" + fmt.Sprint(pid) + "/status") + if err != nil { + return + } + data := splitBy(main, ":") + datas.Name = strings.TrimSpace(name) + datas.Pid, _ = strconv.ParseInt(data["Pid"], 10, 64) + datas.PPid, _ = strconv.ParseInt(data["PPid"], 10, 64) + datas.TPid, _ = strconv.ParseInt(data["TracerPid"], 10, 64) + uids := splitBySpace(data["Uid"]) + gids := splitBySpace(data["Gid"]) + datas.RUID, _ = strconv.Atoi(uids[0]) + datas.EUID, _ = strconv.Atoi(uids[1]) + datas.RGID, _ = strconv.Atoi(gids[0]) + datas.EGID, _ = strconv.Atoi(gids[1]) + 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.LocalPath, err = os.Readlink("/proc/" + fmt.Sprint(pid) + "/exe") + if err != nil { + return + } + datas.LocalPath = filepath.Dir(datas.LocalPath) + datas.ExecPath, err = os.Readlink("/proc/" + fmt.Sprint(pid) + "/cwd") + if err != nil { + return + } + main, err = readAsString("/proc/" + fmt.Sprint(pid) + "/stat") + if err != nil { + return + } + times := splitBySpace(main) + uptime, _ := strconv.ParseInt(strings.TrimSpace(times[21]), 10, 64) + datas.Uptime = time.Unix(StartTime().Unix()+uptime/100, int64((float64(uptime)/100-float64(uptime/100))*1000000000)) + return +} diff --git a/process_test.go b/process_test.go new file mode 100644 index 0000000..6ff35c0 --- /dev/null +++ b/process_test.go @@ -0,0 +1,10 @@ +package staros + +import ( + "fmt" + "testing" +) + +func Test_Process(t *testing.T) { + fmt.Println(FindProcessByPid(16652)) +} diff --git a/process_win.go b/process_win.go new file mode 100644 index 0000000..f31dc27 --- /dev/null +++ b/process_win.go @@ -0,0 +1,49 @@ +// +build windows + +package staros + +import ( + "errors" + "fmt" + "strconv" + + "b612.me/wincmd" +) + +// FindProcessByName 通过进程名来查询应用信息 +func FindProcessByName(pname string) (data []Process, err error) { + var lists []map[string]string + lists, err = wincmd.GetRunningProcess() + if err != nil { + return + } + for _, v := range lists { + if v["name"] == pname { + var tmp Process + tmp.Name = pname + tmp.Pid, _ = strconv.ParseInt(v["pid"], 10, 64) + tmp.PPid, _ = strconv.ParseInt(v["ppid"], 10, 64) + data = append(data, tmp) + } + } + return +} + +// FindProcessByPid 通过pid来查询应用信息 +func FindProcessByPid(pid int64) (data Process, err error) { + var lists []map[string]string + lists, err = wincmd.GetRunningProcess() + if err != nil { + return + } + for _, v := range lists { + if v["pid"] == fmt.Sprint(pid) { + data.Name = v["name"] + data.Pid = pid + data.PPid, _ = strconv.ParseInt(v["ppid"], 10, 64) + return + } + } + err = errors.New("Not Found") + return +} diff --git a/staros.go b/staros.go new file mode 100644 index 0000000..4ebbb1d --- /dev/null +++ b/staros.go @@ -0,0 +1 @@ +package staros diff --git a/tools.go b/tools.go new file mode 100644 index 0000000..8d265e5 --- /dev/null +++ b/tools.go @@ -0,0 +1,44 @@ +package staros + +import ( + "bytes" + "io/ioutil" + "strings" +) + +func splitBy(data, sep string) map[string]string { + res := make(map[string]string) + lists := strings.Split(data, "\n") + for _, v := range lists { + list := strings.SplitN(v, sep, 2) + if len(list) != 2 { + continue + } + res[strings.TrimSpace(list[0])] = strings.TrimSpace(list[1]) + } + return res +} + +// 横向替换ASCII<9> +func ReplaceByte9(data string) string { + return string(bytes.ReplaceAll([]byte(data), []byte{9}, []byte(" "))) +} + +func splitBySpace(data string) []string { + data = string(bytes.ReplaceAll([]byte(data), []byte{9}, []byte(" "))) + nomorespace := func(data string) string { + return strings.ReplaceAll(data, " ", " ") + } + for strings.Index(data, " ") >= 0 { + data = nomorespace(data) + } + return strings.Split(data, " ") +} + +func readAsString(path string) (string, error) { + data, err := ioutil.ReadFile(path) + if err != nil { + return "", err + } + return string(data), nil +} diff --git a/typed.go b/typed.go new file mode 100644 index 0000000..29c8e6b --- /dev/null +++ b/typed.go @@ -0,0 +1,37 @@ +package staros + +import ( + "time" +) + +// Process 定义一个进程的信息 +type Process struct { + PPid int64 + Pid int64 + Name string + ExecPath string + LocalPath string + Args []string + RUID int + EUID int + RGID int + EGID int + TPid int64 + Uptime time.Time +} + +type MemStatus struct { + All uint64 + Used uint64 + Free uint64 + Shared uint64 + BuffCache uint64 + Available uint64 + SwapAll uint64 + SwapUsed uint64 + SwapFree uint64 + VirtualAll uint64 + VirtualUsed uint64 + VirtualAvail uint64 + AvailExtended uint64 +}