chiark / gitweb /
abeb0ac7a99844330081aa408900b08563622438
[elogind.git] / systemctl.vala
1 using DBus;
2 using GLib;
3
4 [DBus (name = "org.freedesktop.systemd1")]
5 public interface Manager : DBus.Object {
6
7         public struct UnitInfo {
8                 string id;
9                 string description;
10                 string load_state;
11                 string active_state;
12                 ObjectPath unit_path;
13                 uint32 job_id;
14                 string job_type;
15                 ObjectPath job_path;
16         }
17
18         public struct JobInfo {
19                 uint32 id;
20                 string name;
21                 string type;
22                 string state;
23                 ObjectPath job_path;
24                 ObjectPath unit_path;
25         }
26
27         public abstract UnitInfo[] ListUnits() throws DBus.Error;
28         public abstract JobInfo[] ListJobs() throws DBus.Error;
29
30         public abstract ObjectPath LoadUnit(string name) throws DBus.Error;
31
32         public abstract void ClearJobs() throws DBus.Error;
33 }
34
35 static string type = null;
36 static bool all = false;
37
38 public static int job_info_compare(void* key1, void* key2) {
39         Manager.JobInfo *j1 = (Manager.JobInfo*) key1;
40         Manager.JobInfo *j2 = (Manager.JobInfo*) key2;
41
42         return Posix.strcmp(j1->name, j2->name);
43 }
44
45 public static int unit_info_compare(void* key1, void* key2) {
46         Manager.UnitInfo *u1 = (Manager.UnitInfo*) key1;
47         Manager.UnitInfo *u2 = (Manager.UnitInfo*) key2;
48
49         int r = Posix.strcmp(Posix.strrchr(u1->id, '.'), Posix.strrchr(u2->id, '.'));
50         if (r != 0)
51                 return r;
52
53         return Posix.strcmp(u1->id, u2->id);
54 }
55
56 static const OptionEntry entries[] = {
57         { "type", 't', 0, OptionArg.STRING, out type, "List only particular type of units", "TYPE" },
58         { "all",  'a', 0, OptionArg.NONE,   out all,  "Show all units, including dead ones", null  },
59         { null }
60 };
61
62 int main (string[] args) {
63
64         OptionContext context = new OptionContext(" -- Control systemd");
65         context.add_main_entries(entries, null);
66
67         try {
68                 context.parse(ref args);
69         } catch (GLib.OptionError e) {
70                 message("Failed to parse command line: %s".printf(e.message));
71         }
72
73         try {
74                 Connection bus = Bus.get(BusType.SESSION);
75
76                 Manager manager = bus.get_object (
77                                 "org.freedesktop.systemd1",
78                                 "/org/freedesktop/systemd1",
79                                 "org.freedesktop.systemd1") as Manager;
80
81                 if (args[1] == "list-units" || args.length <= 1) {
82                         var list = manager.ListUnits();
83                         uint n = 0;
84                         Posix.qsort(list, list.length, sizeof(Manager.UnitInfo), unit_info_compare);
85
86                         stdout.printf("%-45s %-6s %-12s %-17s\n", "UNIT", "LOAD", "ACTIVE", "JOB");
87
88                         foreach (var i in list) {
89
90                                 if (type != null && !i.id.has_suffix(".%s".printf(type)))
91                                         continue;
92
93                                 if (!all && i.active_state == "inactive")
94                                         continue;
95
96                                 stdout.printf("%-45s %-6s %-12s", i.id, i.load_state, i.active_state);
97
98                                 if (i.job_id != 0)
99                                         stdout.printf("→ %-15s", i.job_type);
100
101                                 stdout.puts("\n");
102                                 n++;
103                         }
104
105                         if (all)
106                                 stdout.printf("\n%u units listed.\n", n);
107                         else
108                                 stdout.printf("\n%u live units listed. Pass --all to see dead units, too.\n", n);
109
110
111                 } else if (args[1] == "list-jobs") {
112                         var list = manager.ListJobs();
113                         Posix.qsort(list, list.length, sizeof(Manager.JobInfo), job_info_compare);
114
115                         stdout.printf("%-45s %-17s %-7s\n", "UNIT", "TYPE", "STATE");
116
117                         foreach (var i in list)
118                                 stdout.printf("%-45s → %-15s %-7s\n", i.name, i.type, i.state);
119
120                         stdout.printf("\n%u jobs listed.\n", list.length);
121
122                 } else if (args[1] == "clear-jobs") {
123
124                         manager.ClearJobs();
125
126                 } else if (args[1] == "load") {
127
128                         if (args.length < 3) {
129                                 stderr.printf("Missing argument.\n");
130                                 return 1;
131                         }
132
133                         manager.LoadUnit(args[2]);
134                 } else {
135                         stderr.printf("Unknown command %s.\n", args[1]);
136                         return 1;
137                 }
138
139         } catch (DBus.Error e) {
140                 stderr.printf("%s\n".printf(e.message));
141         }
142
143         return 0;
144 }