chiark / gitweb /
systemd-python: add wrappers for easy functions in sd-login
[elogind.git] / src / python-systemd / login.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Zbigniew JÄ™drzejewski-Szmek <zbyszek@in.waw.pl>
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #define PY_SSIZE_T_CLEAN
23 #pragma GCC diagnostic push
24 #pragma GCC diagnostic ignored "-Wredundant-decls"
25 #include <Python.h>
26 #pragma GCC diagnostic pop
27
28 #include "systemd/sd-login.h"
29 #include "pyutil.h"
30 #include "util.h"
31 #include "strv.h"
32
33 PyDoc_STRVAR(module__doc__,
34              "Python interface to the libsystemd-login library."
35 );
36
37 #define helper(name)                                                    \
38 static PyObject* name(PyObject *self, PyObject *args) {                 \
39         _cleanup_strv_free_ char **list = NULL;                         \
40         int r;                                                          \
41         PyObject *ans;                                                  \
42                                                                         \
43         assert(args == NULL);                                           \
44                                                                         \
45         r = sd_get_##name(&list);                                       \
46         if (r < 0) {                                                    \
47                 errno = -r;                                             \
48                 return PyErr_SetFromErrno(PyExc_IOError);               \
49         }                                                               \
50                                                                         \
51         ans = PyList_New(r);                                            \
52         if (!ans)                                                       \
53                 return NULL;                                            \
54                                                                         \
55         for (r--; r >= 0; r--) {                                        \
56                 PyObject *s = unicode_FromString(list[r]);              \
57                 if (!s) {                                               \
58                         Py_DECREF(ans);                                 \
59                         return NULL;                                    \
60                 }                                                       \
61                                                                         \
62                 PyList_SetItem(ans, r, s);                              \
63         }                                                               \
64                                                                         \
65         return ans;                                                     \
66 }
67
68 helper(seats)
69 helper(sessions)
70 helper(machine_names)
71 #undef helper
72
73 static PyObject* uids(PyObject *self, PyObject *args) {
74         _cleanup_free_ uid_t *list = NULL;
75         int r;
76         PyObject *ans;
77
78         assert(args == NULL);
79
80         r = sd_get_uids(&list);
81         if (r < 0) {
82                 errno = -r;
83                 return PyErr_SetFromErrno(PyExc_IOError);
84         }
85
86         ans = PyList_New(r);
87         if (!ans)
88                 return NULL;
89
90         for (r--; r >= 0; r--) {
91                 PyObject *s = long_FromLong(list[r]);
92                 if (!s) {
93                         Py_DECREF(ans);
94                         return NULL;
95                 }
96
97                 PyList_SetItem(ans, r, s);
98         }
99
100         return ans;
101 }
102
103 PyDoc_STRVAR(seats__doc__,
104              "seats() -> list\n\n"
105              "Returns a list of currently available local seats.\n"
106              "Wraps sd_get_seats(3)."
107 );
108
109 PyDoc_STRVAR(sessions__doc__,
110              "sessions() -> list\n\n"
111              "Returns a list of current login sessions.\n"
112              "Wraps sd_get_sessions(3)."
113 );
114
115 PyDoc_STRVAR(machine_names__doc__,
116              "machine_names() -> list\n\n"
117              "Returns a list of currently running virtual machines\n"
118              "and containers on the system.\n"
119              "Wraps sd_get_machine_names(3)."
120 );
121
122 PyDoc_STRVAR(uids__doc__,
123              "uids() -> list\n\n"
124              "Returns a list of uids of users who currently have login sessions.\n"
125              "Wraps sd_get_uids(3)."
126 );
127
128 static PyMethodDef methods[] = {
129         { "seats", seats, METH_NOARGS, seats__doc__},
130         { "sessions", sessions, METH_NOARGS, sessions__doc__},
131         { "machine_names", machine_names, METH_NOARGS, machine_names__doc__},
132         { "uids", uids, METH_NOARGS, uids__doc__},
133         {} /* Sentinel */
134 };
135
136 #pragma GCC diagnostic push
137 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
138
139 #if PY_MAJOR_VERSION < 3
140
141 PyMODINIT_FUNC initlogin(void) {
142         PyObject *m;
143
144         m = Py_InitModule3("login", methods, module__doc__);
145         if (m == NULL)
146                 return;
147         PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION);
148 }
149 #else
150
151 static struct PyModuleDef module = {
152         PyModuleDef_HEAD_INIT,
153         "login", /* name of module */
154         module__doc__, /* module documentation, may be NULL */
155         -1, /* size of per-interpreter state of the module */
156         methods
157 };
158
159 PyMODINIT_FUNC PyInit_login(void) {
160         PyObject *m;
161
162         m = PyModule_Create(&module);
163         if (m == NULL)
164                 return NULL;
165
166         if (PyModule_AddStringConstant(m, "__version__", PACKAGE_VERSION)) {
167                 Py_DECREF(m);
168                 return NULL;
169         }
170
171         return m;
172 }
173
174 #endif
175
176 #pragma GCC diagnostic pop