// Write an event into the Wtmp file. An error is returned if the event // cannot be appended to the Wtmp file. func WriteWtmp(user, id string, pid int32, utype int16, line string) error { u := new(Utmp) u.Time.GetTimeOfDay() u.Pid = pid u.Type = utype _ = copy(u.User[:], []byte(user)) _ = copy(u.Id[:], []byte(id)) _ = copy(u.Line[:], []byte(line)) name := new(syscall.Utsname) if err := syscall.Uname(name); err == nil { _ = copy(u.Host[:], general.Int8ToByte(name.Release[:])) } return u.UpdWtmp(WtmpFile) }
// Write an event into the Utmp file. An error is returned if the event // cannot be written to the Utmp file. func WriteUtmp(user, id string, pid int32, utype int16, line, oldline string) error { u := new(Utmp) u.Time.GetTimeOfDay() u.Pid = pid u.Type = utype _ = copy(u.User[:], []byte(user)) _ = copy(u.Id[:], []byte(id)) _ = copy(u.Line[:], []byte(line)) name := new(syscall.Utsname) if err := syscall.Uname(name); err == nil { _ = copy(u.Host[:], general.Int8ToByte(name.Release[:])) } file, lk, err := SafeOpen(UtmpFile) if err != nil { goto done } if utype == DeadProcess { _ = SetUtEnt(file) if st, r := u.GetUtid(file); r > -1 { _ = copy(u.Line[:], st.Line[:]) if oldline != "" { _ = copy([]byte(oldline), st.Line[:]) } } } err = SetUtEnt(file) if err != nil { goto done } err = u.PutUtLine(file) done: if file != nil { SafeClose(file, lk) } return err }
// recursively walk through the named directory `dir` until the correct device // is found. // Directories in []searchDevs are automatically skipped func checkDirs(dir string) (string, error) { var ( rs string nameBuf = make([]byte, 256) dirBuf = make([]syscall.Dirent, 256) ) fi, err := os.Open(dir) if err != nil { return "", err } defer fi.Close() err = dirent.ReadDir(int(fi.Fd()), -1, &dirBuf) if err != nil && err != io.EOF { return "", err } for _, v := range dirBuf { // quickly skip most entries if v.Ino != Stat.Ino { continue } _ = copy(nameBuf, general.Int8ToByte(v.Name[:])) name := path.Join(dir, string(nameBuf[:general.Clen(nameBuf)])) // Directories to skip if name == "/dev/stderr" || name == "/dev/stdin" || name == "/dev/stdout" || (len(name) >= 8 && name[0:8] == "/dev/fd/") { continue } // We have to stat the file to determine its Rdev fstat := new(syscall.Stat_t) err = syscall.Stat(name, fstat) if err != nil { continue } // file mode sans permission bits fmode := os.FileMode(fstat.Mode) if fmode.IsDir() { rs, err = checkDirs(name) if err != nil { continue } return rs, nil } if fmode&os.ModeCharDevice == 0 && fstat.Ino == Stat.Ino && fstat.Rdev == Stat.Rdev { return name, nil } } return "", ErrNotFound }