~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/coreos/go-systemd/login1/dbus.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2015 CoreOS, Inc.
 
2
//
 
3
// Licensed under the Apache License, Version 2.0 (the "License");
 
4
// you may not use this file except in compliance with the License.
 
5
// You may obtain a copy of the License at
 
6
//
 
7
//     http://www.apache.org/licenses/LICENSE-2.0
 
8
//
 
9
// Unless required by applicable law or agreed to in writing, software
 
10
// distributed under the License is distributed on an "AS IS" BASIS,
 
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
12
// See the License for the specific language governing permissions and
 
13
// limitations under the License.
 
14
 
 
15
// Integration with the systemd logind API.  See http://www.freedesktop.org/wiki/Software/systemd/logind/
 
16
package login1
 
17
 
 
18
import (
 
19
        "fmt"
 
20
        "os"
 
21
        "strconv"
 
22
 
 
23
        "github.com/godbus/dbus"
 
24
)
 
25
 
 
26
const (
 
27
        dbusInterface = "org.freedesktop.login1.Manager"
 
28
        dbusPath      = "/org/freedesktop/login1"
 
29
)
 
30
 
 
31
// Conn is a connection to systemds dbus endpoint.
 
32
type Conn struct {
 
33
        conn   *dbus.Conn
 
34
        object dbus.BusObject
 
35
}
 
36
 
 
37
// New() establishes a connection to the system bus and authenticates.
 
38
func New() (*Conn, error) {
 
39
        c := new(Conn)
 
40
 
 
41
        if err := c.initConnection(); err != nil {
 
42
                return nil, err
 
43
        }
 
44
 
 
45
        return c, nil
 
46
}
 
47
 
 
48
func (c *Conn) initConnection() error {
 
49
        var err error
 
50
        c.conn, err = dbus.SystemBusPrivate()
 
51
        if err != nil {
 
52
                return err
 
53
        }
 
54
 
 
55
        // Only use EXTERNAL method, and hardcode the uid (not username)
 
56
        // to avoid a username lookup (which requires a dynamically linked
 
57
        // libc)
 
58
        methods := []dbus.Auth{dbus.AuthExternal(strconv.Itoa(os.Getuid()))}
 
59
 
 
60
        err = c.conn.Auth(methods)
 
61
        if err != nil {
 
62
                c.conn.Close()
 
63
                return err
 
64
        }
 
65
 
 
66
        err = c.conn.Hello()
 
67
        if err != nil {
 
68
                c.conn.Close()
 
69
                return err
 
70
        }
 
71
 
 
72
        c.object = c.conn.Object("org.freedesktop.login1", dbus.ObjectPath(dbusPath))
 
73
 
 
74
        return nil
 
75
}
 
76
 
 
77
// Reboot asks logind for a reboot optionally asking for auth.
 
78
func (c *Conn) Reboot(askForAuth bool) {
 
79
        c.object.Call(dbusInterface+".Reboot", 0, askForAuth)
 
80
}
 
81
 
 
82
// Inhibit takes inhibition lock in logind.
 
83
func (c *Conn) Inhibit(what, who, why, mode string) (*os.File, error) {
 
84
        var fd dbus.UnixFD
 
85
 
 
86
        err := c.object.Call(dbusInterface+".Inhibit", 0, what, who, why, mode).Store(&fd)
 
87
        if err != nil {
 
88
                return nil, err
 
89
        }
 
90
 
 
91
        return os.NewFile(uintptr(fd), "inhibit"), nil
 
92
}
 
93
 
 
94
// Subscribe to signals on the logind dbus
 
95
func (c *Conn) Subscribe(members ...string) chan *dbus.Signal {
 
96
        for _, member := range members {
 
97
                c.conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0,
 
98
                        fmt.Sprintf("type='signal',interface='org.freedesktop.login1.Manager',member='%s'", member))
 
99
        }
 
100
        ch := make(chan *dbus.Signal, 10)
 
101
        c.conn.Signal(ch)
 
102
        return ch
 
103
}
 
104
 
 
105
// PowerOff asks logind for a power off optionally asking for auth.
 
106
func (c *Conn) PowerOff(askForAuth bool) {
 
107
        c.object.Call(dbusInterface+".PowerOff", 0, askForAuth)
 
108
}