]>
Commit | Line | Data |
---|---|---|
813683a3 OO |
1 | /* |
2 | * Python bindings for the libmount library. | |
3 | * | |
4 | * Copyright (C) 2013, Red Hat, Inc. All rights reserved. | |
5 | * Written by Ondrej Oprala and Karel Zak | |
6 | * | |
7 | * This file is free software; you can redistribute it and/or | |
8 | * modify it under the terms of the GNU Lesser General Public | |
9 | * License as published by the Free Software Foundation; either | |
10 | * version 3 of the License, or (at your option) any later version. | |
11 | * | |
12 | * This file is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | * Lesser General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public | |
18 | * License along with this file; if not, write to the Free Software | |
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
20 | */ | |
21 | ||
22 | /* | |
23 | * TODO: | |
24 | * mnt_fs_match_{source,target} | |
25 | * mnt_fs_get_{attribute,option} | |
26 | */ | |
27 | ||
28 | #include "pylibmount.h" | |
46407453 | 29 | #include <errno.h> |
813683a3 | 30 | |
71fbe151 | 31 | #define Fs_HELP "Fs(source=None, root=None, target=None, fstype=None, options=None, attributes=None, freq=0, passno=0)" |
813683a3 OO |
32 | |
33 | static PyMemberDef Fs_members[] = { | |
34 | {NULL} | |
35 | }; | |
36 | ||
37 | static PyObject *Fs_get_tag(FsObject *self) | |
38 | { | |
39 | const char *tag = NULL, *val = NULL; | |
40 | PyObject *result; | |
41 | ||
1d4d4b42 KZ |
42 | if (mnt_fs_get_tag(self->fs, &tag, &val) != 0) |
43 | return NULL; | |
813683a3 OO |
44 | |
45 | result = Py_BuildValue("(ss)", tag, val); | |
46 | if (!result) | |
47 | PyErr_SetString(PyExc_RuntimeError, CONSTRUCT_ERR); | |
48 | return result; | |
49 | } | |
71fbe151 | 50 | |
813683a3 OO |
51 | static PyObject *Fs_get_id(FsObject *self) |
52 | { | |
53 | return PyObjectResultInt(mnt_fs_get_id(self->fs)); | |
54 | } | |
71fbe151 | 55 | |
813683a3 OO |
56 | static PyObject *Fs_get_parent_id(FsObject *self) |
57 | { | |
58 | return PyObjectResultInt(mnt_fs_get_parent_id(self->fs)); | |
59 | } | |
71fbe151 | 60 | |
813683a3 OO |
61 | static PyObject *Fs_get_devno(FsObject *self) |
62 | { | |
63 | return PyObjectResultInt(mnt_fs_get_devno(self->fs)); | |
64 | } | |
71fbe151 | 65 | |
8a12ab57 FS |
66 | static void _dump_debug_string(const char *lead, const char *s, char quote) |
67 | { | |
68 | /* PySys_WriteStdout() will automatically truncate any '%s' token | |
69 | * longer than a certain length (documented as 1000 bytes, but we | |
70 | * give ourselves some margin here just in case). The only way I | |
71 | * know to get around this is to print such strings in bite-sized | |
72 | * chunks. | |
73 | */ | |
74 | static const unsigned int _PY_MAX_LEN = 900; | |
75 | static const char *_PY_MAX_LEN_FMT = "%.900s"; | |
76 | unsigned int len; | |
77 | ||
78 | if (lead != NULL) | |
79 | PySys_WriteStdout("%s", lead); | |
80 | ||
81 | if (quote != 0) | |
82 | PySys_WriteStdout("%c", quote); | |
83 | ||
2bb3aa36 | 84 | for (len = strlen(s); len > _PY_MAX_LEN; len -= _PY_MAX_LEN, s += _PY_MAX_LEN) |
8a12ab57 FS |
85 | PySys_WriteStdout(_PY_MAX_LEN_FMT, s); |
86 | ||
87 | if (len > 0) | |
88 | PySys_WriteStdout(_PY_MAX_LEN_FMT, s); | |
89 | ||
90 | if (quote != 0) | |
91 | PySys_WriteStdout("%c\n", quote); | |
92 | else | |
93 | PySys_WriteStdout("\n"); | |
94 | } | |
95 | ||
46407453 OO |
96 | #define Fs_print_debug_HELP "print_debug()\n\n" |
97 | static PyObject *Fs_print_debug(FsObject *self) | |
98 | { | |
99 | PySys_WriteStdout("------ fs: %p\n", self->fs); | |
8a12ab57 FS |
100 | _dump_debug_string("source: ", mnt_fs_get_source(self->fs), 0); |
101 | _dump_debug_string("target: ", mnt_fs_get_target(self->fs), 0); | |
102 | _dump_debug_string("fstype: ", mnt_fs_get_fstype(self->fs), 0); | |
46407453 OO |
103 | |
104 | if (mnt_fs_get_options(self->fs)) | |
8a12ab57 | 105 | _dump_debug_string("optstr: ", mnt_fs_get_options(self->fs), 0); |
46407453 | 106 | if (mnt_fs_get_vfs_options(self->fs)) |
8a12ab57 | 107 | _dump_debug_string("VFS-optstr: ", mnt_fs_get_vfs_options(self->fs), 0); |
46407453 | 108 | if (mnt_fs_get_fs_options(self->fs)) |
8a12ab57 | 109 | _dump_debug_string("FS-opstr: ", mnt_fs_get_fs_options(self->fs), 0); |
46407453 | 110 | if (mnt_fs_get_user_options(self->fs)) |
8a12ab57 | 111 | _dump_debug_string("user-optstr: ", mnt_fs_get_user_options(self->fs), 0); |
46407453 | 112 | if (mnt_fs_get_optional_fields(self->fs)) |
8a12ab57 | 113 | _dump_debug_string("optional-fields: ", mnt_fs_get_optional_fields(self->fs), '\''); |
46407453 | 114 | if (mnt_fs_get_attributes(self->fs)) |
8a12ab57 | 115 | _dump_debug_string("attributes: ", mnt_fs_get_attributes(self->fs), 0); |
46407453 OO |
116 | |
117 | if (mnt_fs_get_root(self->fs)) | |
8a12ab57 | 118 | _dump_debug_string("root: ", mnt_fs_get_root(self->fs), 0); |
46407453 OO |
119 | |
120 | if (mnt_fs_get_swaptype(self->fs)) | |
8a12ab57 | 121 | _dump_debug_string("swaptype: ", mnt_fs_get_swaptype(self->fs), 0); |
46407453 OO |
122 | if (mnt_fs_get_size(self->fs)) |
123 | PySys_WriteStdout("size: %jd\n", mnt_fs_get_size(self->fs)); | |
124 | if (mnt_fs_get_usedsize(self->fs)) | |
125 | PySys_WriteStdout("usedsize: %jd\n", mnt_fs_get_usedsize(self->fs)); | |
126 | if (mnt_fs_get_priority(self->fs)) | |
127 | PySys_WriteStdout("priority: %d\n", mnt_fs_get_priority(self->fs)); | |
128 | ||
129 | if (mnt_fs_get_bindsrc(self->fs)) | |
8a12ab57 | 130 | _dump_debug_string("bindsrc: ", mnt_fs_get_bindsrc(self->fs), 0); |
46407453 OO |
131 | if (mnt_fs_get_freq(self->fs)) |
132 | PySys_WriteStdout("freq: %d\n", mnt_fs_get_freq(self->fs)); | |
133 | if (mnt_fs_get_passno(self->fs)) | |
134 | PySys_WriteStdout("pass: %d\n", mnt_fs_get_passno(self->fs)); | |
135 | if (mnt_fs_get_id(self->fs)) | |
136 | PySys_WriteStdout("id: %d\n", mnt_fs_get_id(self->fs)); | |
137 | if (mnt_fs_get_parent_id(self->fs)) | |
138 | PySys_WriteStdout("parent: %d\n", mnt_fs_get_parent_id(self->fs)); | |
139 | if (mnt_fs_get_devno(self->fs)) | |
140 | PySys_WriteStdout("devno: %d:%d\n", major(mnt_fs_get_devno(self->fs)), | |
141 | minor(mnt_fs_get_devno(self->fs))); | |
142 | if (mnt_fs_get_tid(self->fs)) | |
143 | PySys_WriteStdout("tid: %d\n", mnt_fs_get_tid(self->fs)); | |
144 | if (mnt_fs_get_comment(self->fs)) | |
8a12ab57 | 145 | _dump_debug_string("comment: ", mnt_fs_get_comment(self->fs), '\''); |
46407453 | 146 | return UL_IncRef(self); |
813683a3 OO |
147 | } |
148 | /* | |
149 | ** Fs getters/setters | |
150 | */ | |
151 | ||
813683a3 OO |
152 | static PyObject *Fs_get_comment(FsObject *self, void *closure __attribute__((unused))) |
153 | { | |
154 | return PyObjectResultStr(mnt_fs_get_comment(self->fs)); | |
155 | } | |
156 | ||
157 | static int Fs_set_comment(FsObject *self, PyObject *value, void *closure __attribute__((unused))) | |
158 | { | |
159 | char *comment = NULL; | |
160 | int rc = 0; | |
161 | ||
162 | if (!value) { | |
163 | PyErr_SetString(PyExc_TypeError, NODEL_ATTR); | |
164 | return -1; | |
165 | } | |
166 | if (!(comment = pystos(value))) | |
167 | return -1; | |
168 | ||
169 | rc = mnt_fs_set_comment(self->fs, comment); | |
170 | if (rc) { | |
171 | UL_RaiseExc(-rc); | |
172 | return -1; | |
173 | } | |
174 | return 0; | |
175 | } | |
176 | /* source */ | |
177 | static PyObject *Fs_get_source(FsObject *self) | |
178 | { | |
179 | return PyObjectResultStr(mnt_fs_get_source(self->fs)); | |
180 | } | |
181 | ||
182 | static int Fs_set_source(FsObject *self, PyObject *value, void *closure __attribute__((unused))) | |
183 | { | |
184 | char *source = NULL; | |
185 | int rc = 0; | |
679f086c | 186 | |
813683a3 OO |
187 | if (!value) { |
188 | PyErr_SetString(PyExc_TypeError, NODEL_ATTR); | |
189 | return -1; | |
190 | } | |
191 | if (!(source = pystos(value))) | |
192 | return -1; | |
193 | ||
194 | rc = mnt_fs_set_source(self->fs, source); | |
195 | if (rc) { | |
196 | UL_RaiseExc(-rc); | |
197 | return -1; | |
198 | } | |
199 | return 0; | |
200 | } | |
a2cb0250 | 201 | |
813683a3 OO |
202 | static PyObject *Fs_get_srcpath(FsObject *self) |
203 | { | |
204 | return PyObjectResultStr(mnt_fs_get_srcpath(self->fs)); | |
205 | } | |
a2cb0250 | 206 | |
813683a3 OO |
207 | static PyObject *Fs_get_root(FsObject *self) |
208 | { | |
209 | return PyObjectResultStr(mnt_fs_get_root(self->fs)); | |
210 | } | |
211 | ||
212 | static int Fs_set_root(FsObject *self, PyObject *value, void *closure __attribute__((unused))) | |
213 | { | |
214 | char *root = NULL; | |
215 | int rc = 0; | |
679f086c | 216 | |
813683a3 OO |
217 | if (!value) { |
218 | PyErr_SetString(PyExc_TypeError, NODEL_ATTR); | |
219 | return -1; | |
220 | } | |
221 | if (!(root = pystos(value))) | |
222 | return -1; | |
223 | ||
224 | rc = mnt_fs_set_root(self->fs, root); | |
225 | if (rc) { | |
226 | UL_RaiseExc(-rc); | |
227 | return -1; | |
228 | } | |
229 | return 0; | |
230 | } | |
a2cb0250 | 231 | |
813683a3 OO |
232 | static PyObject *Fs_get_target(FsObject *self) |
233 | { | |
234 | return PyObjectResultStr(mnt_fs_get_target(self->fs)); | |
235 | } | |
236 | ||
237 | static int Fs_set_target(FsObject *self, PyObject *value, void *closure __attribute__((unused))) | |
238 | { | |
239 | char *target = NULL; | |
240 | int rc = 0; | |
679f086c | 241 | |
813683a3 OO |
242 | if (!value) { |
243 | PyErr_SetString(PyExc_TypeError, NODEL_ATTR); | |
244 | return -1; | |
245 | } | |
246 | if (!(target = pystos(value))) | |
247 | return -1; | |
248 | ||
249 | rc = mnt_fs_set_target(self->fs, target); | |
250 | if (rc) { | |
251 | UL_RaiseExc(-rc); | |
252 | return -1; | |
253 | } | |
254 | return 0; | |
255 | } | |
a2cb0250 | 256 | |
813683a3 OO |
257 | static PyObject *Fs_get_fstype(FsObject *self) |
258 | { | |
259 | return PyObjectResultStr(mnt_fs_get_fstype(self->fs)); | |
260 | } | |
261 | ||
a2cb0250 KZ |
262 | static int Fs_set_fstype(FsObject *self, PyObject *value, |
263 | void *closure __attribute__((unused))) | |
813683a3 OO |
264 | { |
265 | char *fstype = NULL; | |
266 | int rc = 0; | |
679f086c | 267 | |
813683a3 OO |
268 | if (!value) { |
269 | PyErr_SetString(PyExc_TypeError, NODEL_ATTR); | |
270 | return -1; | |
271 | } | |
272 | if (!(fstype = pystos(value))) | |
273 | return -1; | |
274 | ||
275 | rc = mnt_fs_set_fstype(self->fs, fstype); | |
276 | if (rc) { | |
277 | UL_RaiseExc(-rc); | |
278 | return -1; | |
279 | } | |
280 | return 0; | |
281 | } | |
a2cb0250 | 282 | |
813683a3 OO |
283 | static PyObject *Fs_get_options(FsObject *self) |
284 | { | |
285 | return PyObjectResultStr(mnt_fs_get_options(self->fs)); | |
286 | } | |
287 | ||
a2cb0250 KZ |
288 | static int Fs_set_options(FsObject *self, PyObject *value, |
289 | void *closure __attribute__((unused))) | |
813683a3 OO |
290 | { |
291 | char *options = NULL; | |
292 | int rc = 0; | |
679f086c | 293 | |
813683a3 OO |
294 | if (!value) { |
295 | PyErr_SetString(PyExc_TypeError, NODEL_ATTR); | |
296 | return -1; | |
297 | } | |
298 | if (!(options = pystos(value))) | |
299 | return -1; | |
300 | ||
301 | rc = mnt_fs_set_options(self->fs, options); | |
302 | if (rc) { | |
303 | UL_RaiseExc(-rc); | |
304 | return -1; | |
305 | } | |
306 | return 0; | |
307 | } | |
a2cb0250 | 308 | |
813683a3 OO |
309 | static PyObject *Fs_get_vfs_options(FsObject *self) |
310 | { | |
311 | return PyObjectResultStr(mnt_fs_get_vfs_options(self->fs)); | |
312 | } | |
313 | ||
a2cb0250 | 314 | |
813683a3 OO |
315 | static PyObject *Fs_get_optional_fields(FsObject *self) |
316 | { | |
317 | return PyObjectResultStr(mnt_fs_get_optional_fields(self->fs)); | |
318 | } | |
319 | ||
a2cb0250 | 320 | |
813683a3 OO |
321 | static PyObject *Fs_get_fs_options(FsObject *self) |
322 | { | |
323 | return PyObjectResultStr(mnt_fs_get_fs_options(self->fs)); | |
324 | } | |
325 | ||
a2cb0250 | 326 | |
813683a3 OO |
327 | static PyObject *Fs_get_user_options(FsObject *self) |
328 | { | |
329 | return PyObjectResultStr(mnt_fs_get_user_options(self->fs)); | |
330 | } | |
331 | ||
a2cb0250 | 332 | |
813683a3 OO |
333 | static PyObject *Fs_get_attributes(FsObject *self) |
334 | { | |
335 | return PyObjectResultStr(mnt_fs_get_attributes(self->fs)); | |
336 | } | |
337 | ||
a2cb0250 KZ |
338 | static int Fs_set_attributes(FsObject *self, PyObject *value, |
339 | void *closure __attribute__((unused))) | |
813683a3 OO |
340 | { |
341 | char *attributes = NULL; | |
342 | int rc = 0; | |
679f086c | 343 | |
813683a3 OO |
344 | if (!value) { |
345 | PyErr_SetString(PyExc_TypeError, NODEL_ATTR); | |
346 | return -1; | |
347 | } | |
348 | if (!(attributes = pystos(value))) | |
349 | return -1; | |
350 | ||
351 | rc = mnt_fs_set_attributes(self->fs, attributes); | |
352 | if (rc) { | |
353 | UL_RaiseExc(-rc); | |
354 | return -1; | |
355 | } | |
356 | return 0; | |
357 | } | |
a2cb0250 | 358 | |
813683a3 OO |
359 | static PyObject *Fs_get_freq(FsObject *self, void *closure __attribute__((unused))) |
360 | { | |
361 | return PyObjectResultInt(mnt_fs_get_freq(self->fs)); | |
362 | } | |
363 | ||
a2cb0250 KZ |
364 | static int Fs_set_freq(FsObject *self, PyObject *value, |
365 | void *closure __attribute__((unused))) | |
813683a3 OO |
366 | { |
367 | int freq = 0; | |
679f086c | 368 | |
813683a3 OO |
369 | if (!value) { |
370 | PyErr_SetString(PyExc_TypeError, NODEL_ATTR); | |
371 | return -1; | |
a2cb0250 | 372 | |
042f62df RP |
373 | } |
374 | ||
375 | if (!PyLong_Check(value)) { | |
813683a3 OO |
376 | PyErr_SetString(PyExc_TypeError, ARG_ERR); |
377 | return -1; | |
378 | } | |
379 | ||
46407453 | 380 | freq = PyLong_AsLong(value); |
813683a3 OO |
381 | if (freq == -1 && PyErr_Occurred()) { |
382 | PyErr_SetString(PyExc_RuntimeError, "type conversion failed"); | |
383 | return -1; | |
384 | } | |
385 | return mnt_fs_set_freq(self->fs, freq); | |
386 | } | |
a2cb0250 | 387 | |
813683a3 OO |
388 | static PyObject *Fs_get_passno(FsObject *self) |
389 | { | |
390 | return PyObjectResultInt(mnt_fs_get_passno(self->fs)); | |
391 | } | |
392 | ||
393 | static int Fs_set_passno(FsObject *self, PyObject *value, void *closure __attribute__((unused))) | |
394 | { | |
395 | int passno = 0; | |
679f086c | 396 | |
813683a3 OO |
397 | if (!value) { |
398 | PyErr_SetString(PyExc_TypeError, NODEL_ATTR); | |
399 | return -1; | |
042f62df RP |
400 | } |
401 | ||
402 | if (!PyLong_Check(value)) { | |
813683a3 OO |
403 | PyErr_SetString(PyExc_TypeError, ARG_ERR); |
404 | return -1; | |
405 | } | |
406 | ||
46407453 | 407 | passno = PyLong_AsLong(value); |
813683a3 OO |
408 | if (passno == -1 && PyErr_Occurred()) { |
409 | PyErr_SetString(PyExc_RuntimeError, "type conversion failed"); | |
410 | return -1; | |
411 | } | |
412 | return mnt_fs_set_passno(self->fs, passno); | |
413 | } | |
813683a3 OO |
414 | |
415 | static PyObject *Fs_get_swaptype(FsObject *self) | |
416 | { | |
417 | return PyObjectResultStr(mnt_fs_get_swaptype(self->fs)); | |
418 | } | |
419 | ||
813683a3 OO |
420 | static PyObject *Fs_get_size(FsObject *self) |
421 | { | |
422 | return PyObjectResultInt(mnt_fs_get_size(self->fs)); | |
423 | } | |
424 | ||
813683a3 OO |
425 | static PyObject *Fs_get_usedsize(FsObject *self) |
426 | { | |
427 | return PyObjectResultInt(mnt_fs_get_usedsize(self->fs)); | |
428 | } | |
813683a3 OO |
429 | |
430 | static PyObject *Fs_get_priority(FsObject *self) | |
431 | { | |
432 | return PyObjectResultInt(mnt_fs_get_priority(self->fs)); | |
433 | } | |
a2cb0250 | 434 | |
813683a3 OO |
435 | #define Fs_get_propagation_HELP "get_propagation(flags)\n\n\ |
436 | Note that this function set flags to zero if not found any propagation flag\n\ | |
437 | in mountinfo file. The kernel default is MS_PRIVATE, this flag is not stored\n\ | |
438 | in the mountinfo file.\n\ | |
439 | \n\ | |
440 | Returns self or raises an exception in case of an error." | |
f218d8d2 | 441 | static PyObject *Fs_get_propagation(FsObject *self) |
813683a3 OO |
442 | { |
443 | unsigned long flags; | |
f218d8d2 | 444 | int rc; |
679f086c | 445 | |
f218d8d2 GS |
446 | rc = mnt_fs_get_propagation(self->fs, &flags); |
447 | return rc ? UL_RaiseExc(-rc) : PyObjectResultInt(flags); | |
813683a3 | 448 | } |
813683a3 OO |
449 | |
450 | static PyObject *Fs_get_tid(FsObject *self) | |
451 | { | |
452 | return PyObjectResultInt(mnt_fs_get_tid(self->fs)); | |
453 | } | |
a2cb0250 KZ |
454 | |
455 | #define Fs_is_kernel_HELP "is_kernel()\n\nReturns 1 if the filesystem " \ | |
456 | "description is read from kernel e.g. /proc/mounts." | |
813683a3 OO |
457 | static PyObject *Fs_is_kernel(FsObject *self) |
458 | { | |
459 | return PyBool_FromLong(mnt_fs_is_kernel(self->fs)); | |
460 | } | |
a2cb0250 KZ |
461 | |
462 | #define Fs_is_netfs_HELP "is_netfs()\n\nReturns 1 if the filesystem is " \ | |
463 | "a network filesystem" | |
813683a3 OO |
464 | static PyObject *Fs_is_netfs(FsObject *self) |
465 | { | |
466 | return PyBool_FromLong(mnt_fs_is_netfs(self->fs)); | |
467 | } | |
a2cb0250 KZ |
468 | |
469 | #define Fs_is_pseudofs_HELP "is_pseudofs()\n\nReturns 1 if the filesystem is "\ | |
470 | "a pseudo fs type (proc, cgroups)" | |
813683a3 OO |
471 | static PyObject *Fs_is_pseudofs(FsObject *self) |
472 | { | |
473 | return PyBool_FromLong(mnt_fs_is_pseudofs(self->fs)); | |
474 | } | |
a2cb0250 KZ |
475 | |
476 | #define Fs_is_swaparea_HELP "is_swaparea()\n\nReturns 1 if the filesystem " \ | |
477 | "uses \"swap\" as a type" | |
813683a3 OO |
478 | static PyObject *Fs_is_swaparea(FsObject *self) |
479 | { | |
480 | return PyBool_FromLong(mnt_fs_is_swaparea(self->fs)); | |
481 | } | |
a2cb0250 KZ |
482 | |
483 | #define Fs_append_attributes_HELP "append_attributes(optstr)\n\n" \ | |
484 | "Appends mount attributes." | |
813683a3 OO |
485 | static PyObject *Fs_append_attributes(FsObject *self, PyObject *args, PyObject *kwds) |
486 | { | |
487 | char *kwlist[] = {"optstr", NULL}; | |
488 | char *optstr = NULL; | |
489 | int rc; | |
679f086c | 490 | |
813683a3 OO |
491 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &optstr)) { |
492 | PyErr_SetString(PyExc_TypeError, ARG_ERR); | |
493 | return NULL; | |
494 | } | |
679f086c KZ |
495 | rc = mnt_fs_append_attributes(self->fs, optstr); |
496 | return rc ? UL_RaiseExc(-rc) : UL_IncRef(self); | |
813683a3 | 497 | } |
a2cb0250 KZ |
498 | |
499 | #define Fs_append_options_HELP "append_options(optstr)\n\n" \ | |
500 | "Parses (splits) optstr and appends results to VFS, " \ | |
501 | "FS and userspace lists of options." | |
813683a3 OO |
502 | static PyObject *Fs_append_options(FsObject *self, PyObject *args, PyObject *kwds) |
503 | { | |
504 | char *kwlist[] = {"optstr", NULL}; | |
505 | char *optstr = NULL; | |
506 | int rc; | |
679f086c | 507 | |
813683a3 OO |
508 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &optstr)) { |
509 | PyErr_SetString(PyExc_TypeError, ARG_ERR); | |
510 | return NULL; | |
511 | } | |
679f086c KZ |
512 | rc = mnt_fs_append_options(self->fs, optstr); |
513 | return rc ? UL_RaiseExc(-rc) : UL_IncRef(self); | |
813683a3 | 514 | } |
679f086c | 515 | |
a2cb0250 KZ |
516 | #define Fs_prepend_attributes_HELP "prepend_attributes(optstr)\n\n" \ |
517 | "Prepends mount attributes." | |
813683a3 OO |
518 | static PyObject *Fs_prepend_attributes(FsObject *self, PyObject *args, PyObject *kwds) |
519 | { | |
520 | char *kwlist[] = {"optstr", NULL}; | |
521 | char *optstr = NULL; | |
522 | int rc; | |
679f086c | 523 | |
813683a3 OO |
524 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &optstr)) { |
525 | PyErr_SetString(PyExc_TypeError, ARG_ERR); | |
526 | return NULL; | |
527 | } | |
679f086c KZ |
528 | rc = mnt_fs_prepend_attributes(self->fs, optstr); |
529 | return rc ? UL_RaiseExc(-rc) : UL_IncRef(self); | |
813683a3 | 530 | } |
679f086c | 531 | |
a2cb0250 KZ |
532 | #define Fs_prepend_options_HELP "prepend_options(optstr)\n\n" \ |
533 | "Parses (splits) optstr and prepends results to VFS, " \ | |
534 | "FS and userspace lists of options." | |
813683a3 OO |
535 | static PyObject *Fs_prepend_options(FsObject *self, PyObject *args, PyObject *kwds) |
536 | { | |
537 | char *kwlist[] = {"optstr", NULL}; | |
538 | char *optstr = NULL; | |
539 | int rc; | |
679f086c | 540 | |
813683a3 OO |
541 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &optstr)) { |
542 | PyErr_SetString(PyExc_TypeError, ARG_ERR); | |
543 | return NULL; | |
544 | } | |
679f086c KZ |
545 | rc = mnt_fs_prepend_options(self->fs, optstr); |
546 | return rc ? UL_RaiseExc(-rc) : UL_IncRef(self); | |
813683a3 | 547 | } |
679f086c | 548 | |
a2cb0250 KZ |
549 | #define Fs_match_fstype_HELP "match_fstype(pattern)\n\n" \ |
550 | "pattern: filesystem name or comma delimited list(string) of names\n\n" \ | |
551 | "The pattern list of filesystem can be prefixed with a global\n" \ | |
552 | "\"no\" prefix to invert matching of the whole list. The \"no\" could\n" \ | |
553 | "also be used for individual items in the pattern list. So,\n" \ | |
554 | "\"nofoo,bar\" has the same meaning as \"nofoo,nobar\".\n" \ | |
555 | "\"bar\" : \"nofoo,bar\" -> False (global \"no\" prefix)\n" \ | |
556 | "\"bar\" : \"foo,bar\" -> True\n" \ | |
557 | "\"bar\" : \"foo,nobar\" -> False\n\n" \ | |
558 | "Returns True if type is matching, else False." | |
813683a3 OO |
559 | static PyObject *Fs_match_fstype(FsObject *self, PyObject *args, PyObject *kwds) |
560 | { | |
561 | char *kwlist[] = {"pattern", NULL}; | |
562 | char *pattern = NULL; | |
679f086c | 563 | |
813683a3 OO |
564 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &pattern)) { |
565 | PyErr_SetString(PyExc_TypeError, ARG_ERR); | |
566 | return NULL; | |
567 | } | |
568 | return PyBool_FromLong(mnt_fs_match_fstype(self->fs, pattern)); | |
569 | } | |
679f086c | 570 | |
a2cb0250 KZ |
571 | #define Fs_match_options_HELP "match_options(options)\n\n" \ |
572 | "options: comma delimited list of options (and nooptions)\n" \ | |
573 | "Returns True if fs type is matching to options else False." | |
813683a3 OO |
574 | static PyObject *Fs_match_options(FsObject *self, PyObject *args, PyObject *kwds) |
575 | { | |
576 | char *kwlist[] = {"options", NULL}; | |
577 | char *options = NULL; | |
679f086c | 578 | |
813683a3 OO |
579 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &options)) { |
580 | PyErr_SetString(PyExc_TypeError, ARG_ERR); | |
581 | return NULL; | |
582 | } | |
583 | return PyBool_FromLong(mnt_fs_match_options(self->fs, options)); | |
584 | } | |
679f086c | 585 | |
a2cb0250 KZ |
586 | #define Fs_streq_srcpath_HELP "streq_srcpath(srcpath)\n\n" \ |
587 | "Compares fs source path with path. The tailing slash is ignored.\n" \ | |
588 | "Returns True if fs source path equal to path, otherwise False." | |
813683a3 OO |
589 | static PyObject *Fs_streq_srcpath(FsObject *self, PyObject *args, PyObject *kwds) |
590 | { | |
591 | char *kwlist[] = {"srcpath", NULL}; | |
592 | char *srcpath = NULL; | |
679f086c | 593 | |
813683a3 OO |
594 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &srcpath)) { |
595 | PyErr_SetString(PyExc_TypeError, ARG_ERR); | |
596 | return NULL; | |
597 | } | |
598 | return PyBool_FromLong(mnt_fs_streq_srcpath(self->fs, srcpath)); | |
599 | } | |
679f086c | 600 | |
a2cb0250 KZ |
601 | #define Fs_streq_target_HELP "streq_target(target)\n\n" \ |
602 | "Compares fs target path with path. The tailing slash is ignored.\n" \ | |
603 | "See also Fs.match_target().\n" \ | |
604 | "Returns True if fs target path equal to path, otherwise False." | |
813683a3 OO |
605 | static PyObject *Fs_streq_target(FsObject *self, PyObject *args, PyObject *kwds) |
606 | { | |
607 | char *kwlist[] = {"target", NULL}; | |
608 | char *target = NULL; | |
679f086c | 609 | |
813683a3 OO |
610 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &target)) { |
611 | PyErr_SetString(PyExc_TypeError, ARG_ERR); | |
612 | return NULL; | |
613 | } | |
614 | return PyBool_FromLong(mnt_fs_streq_target(self->fs, target)); | |
615 | } | |
616 | ||
a2cb0250 KZ |
617 | #define Fs_copy_fs_HELP "copy_fs(dest=None)\n\n" \ |
618 | "If dest is None, a new object is created, if any fs " \ | |
619 | "field is already set, then the field is NOT overwritten." | |
813683a3 | 620 | static PyObject *Fs_copy_fs(FsObject *self, PyObject *args, PyObject *kwds); |
a2cb0250 | 621 | |
813683a3 | 622 | static PyMethodDef Fs_methods[] = { |
f218d8d2 | 623 | {"get_propagation", (PyCFunction)Fs_get_propagation, METH_NOARGS, Fs_get_propagation_HELP}, |
813683a3 OO |
624 | {"mnt_fs_append_attributes", (PyCFunction)Fs_append_attributes, METH_VARARGS|METH_KEYWORDS, Fs_append_attributes_HELP}, |
625 | {"append_options", (PyCFunction)Fs_append_options, METH_VARARGS|METH_KEYWORDS, Fs_append_options_HELP}, | |
626 | {"mnt_fs_prepend_attributes", (PyCFunction)Fs_prepend_attributes, METH_VARARGS|METH_KEYWORDS, Fs_prepend_attributes_HELP}, | |
627 | {"prepend_options", (PyCFunction)Fs_prepend_options, METH_VARARGS|METH_KEYWORDS, Fs_prepend_options_HELP}, | |
a2cb0250 KZ |
628 | {"copy_fs", (PyCFunction)Fs_copy_fs, METH_VARARGS|METH_KEYWORDS, Fs_copy_fs_HELP}, |
629 | {"is_kernel", (PyCFunction)Fs_is_kernel, METH_NOARGS, Fs_is_kernel_HELP}, | |
630 | {"is_netfs", (PyCFunction)Fs_is_netfs, METH_NOARGS, Fs_is_netfs_HELP}, | |
631 | {"is_pseudofs", (PyCFunction)Fs_is_pseudofs, METH_NOARGS, Fs_is_pseudofs_HELP}, | |
632 | {"is_swaparea", (PyCFunction)Fs_is_swaparea, METH_NOARGS, Fs_is_swaparea_HELP}, | |
813683a3 OO |
633 | {"match_fstype", (PyCFunction)Fs_match_fstype, METH_VARARGS|METH_KEYWORDS, Fs_match_fstype_HELP}, |
634 | {"match_options", (PyCFunction)Fs_match_options, METH_VARARGS|METH_KEYWORDS, Fs_match_options_HELP}, | |
635 | {"streq_srcpath", (PyCFunction)Fs_streq_srcpath, METH_VARARGS|METH_KEYWORDS, Fs_streq_srcpath_HELP}, | |
636 | {"streq_target", (PyCFunction)Fs_streq_target, METH_VARARGS|METH_KEYWORDS, Fs_streq_target_HELP}, | |
46407453 | 637 | {"print_debug", (PyCFunction)Fs_print_debug, METH_NOARGS, Fs_print_debug_HELP}, |
813683a3 OO |
638 | {NULL} |
639 | }; | |
640 | ||
b7e47ac1 | 641 | static void Fs_destructor(FsObject *self) |
813683a3 | 642 | { |
9e930041 | 643 | DBG(FS, pymnt_debug_h(self->fs, "destructor py-obj: %p, py-refcnt=%d", |
b7e47ac1 | 644 | self, (int) ((PyObject *) self)->ob_refcnt)); |
20b222ec | 645 | mnt_unref_fs(self->fs); |
46407453 | 646 | PyFree(self); |
813683a3 OO |
647 | } |
648 | ||
649 | static PyObject *Fs_new(PyTypeObject *type, PyObject *args __attribute__((unused)), | |
650 | PyObject *kwds __attribute__((unused))) | |
651 | { | |
652 | FsObject *self = (FsObject*)type->tp_alloc(type, 0); | |
679f086c | 653 | |
b7e47ac1 | 654 | if (self) { |
813683a3 | 655 | self->fs = NULL; |
b7e47ac1 KZ |
656 | DBG(FS, pymnt_debug_h(self, "new")); |
657 | } | |
679f086c | 658 | return (PyObject *) self; |
813683a3 OO |
659 | } |
660 | ||
661 | static int Fs_init(FsObject *self, PyObject *args, PyObject *kwds) | |
662 | { | |
71fbe151 | 663 | char *source = NULL, *root = NULL, *target = NULL; |
813683a3 OO |
664 | char *fstype = NULL, *options = NULL, *attributes =NULL; |
665 | int freq = 0; int passno = 0; | |
666 | int rc = 0; | |
a2cb0250 KZ |
667 | char *kwlist[] = { |
668 | "source", "root", "target", | |
669 | "fstype", "options", "attributes", | |
670 | "freq", "passno", NULL | |
671 | }; | |
679f086c | 672 | |
71fbe151 KZ |
673 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "|ssssssii", kwlist, |
674 | &source, &root, &target, &fstype, &options, | |
813683a3 OO |
675 | &attributes, &freq, &passno)) { |
676 | PyErr_SetString(PyExc_TypeError, "Invalid type"); | |
677 | return -1; | |
678 | } | |
b7e47ac1 KZ |
679 | |
680 | DBG(FS, pymnt_debug_h(self, "init")); | |
681 | ||
813683a3 | 682 | if (self->fs) |
20b222ec KZ |
683 | mnt_unref_fs(self->fs); |
684 | ||
685 | self->fs = mnt_new_fs(); /* new FS with refcount=1 */ | |
813683a3 | 686 | |
679f086c KZ |
687 | if (source && (rc = mnt_fs_set_source(self->fs, source))) { |
688 | PyErr_SetString(PyExc_MemoryError, MEMORY_ERR); | |
689 | return rc; | |
690 | } | |
691 | if (root && (rc = mnt_fs_set_root(self->fs, root))) { | |
692 | PyErr_SetString(PyExc_MemoryError, MEMORY_ERR); | |
693 | return rc; | |
813683a3 | 694 | } |
679f086c KZ |
695 | if (target && (rc = mnt_fs_set_target(self->fs, target))) { |
696 | PyErr_SetString(PyExc_MemoryError, MEMORY_ERR); | |
697 | return rc; | |
698 | } | |
699 | if (fstype && (rc = mnt_fs_set_fstype(self->fs, fstype))) { | |
700 | PyErr_SetString(PyExc_MemoryError, MEMORY_ERR); | |
701 | return rc; | |
702 | } | |
703 | if (options && (rc = mnt_fs_set_options(self->fs, options))) { | |
704 | PyErr_SetString(PyExc_MemoryError, MEMORY_ERR); | |
705 | return rc; | |
706 | } | |
707 | if (attributes && (rc = mnt_fs_set_attributes(self->fs, attributes))) { | |
708 | PyErr_SetString(PyExc_MemoryError, MEMORY_ERR); | |
709 | return rc; | |
710 | } | |
711 | ||
813683a3 OO |
712 | mnt_fs_set_freq(self->fs, freq); |
713 | mnt_fs_set_passno(self->fs, passno); | |
279a6d5f | 714 | mnt_fs_set_userdata(self->fs, self); /* store a pointer to self, convenient when resetting the table */ |
813683a3 OO |
715 | return 0; |
716 | } | |
717 | ||
718 | /* | |
719 | * missing: | |
720 | * attribute | |
721 | * option | |
722 | */ | |
723 | static PyGetSetDef Fs_getseters[] = { | |
724 | {"id", (getter)Fs_get_id, NULL, "mountinfo[1]: ID", NULL}, | |
725 | {"parent", (getter)Fs_get_parent_id, NULL, "mountinfo[2]: parent", NULL}, | |
726 | {"devno", (getter)Fs_get_devno, NULL, "mountinfo[3]: st_dev", NULL}, | |
813683a3 OO |
727 | {"comment", (getter)Fs_get_comment, (setter)Fs_set_comment, "fstab entry comment", NULL}, |
728 | {"source", (getter)Fs_get_source, (setter)Fs_set_source, "fstab[1], mountinfo[10], swaps[1]: source dev, file, dir or TAG", NULL}, | |
729 | {"srcpath", (getter)Fs_get_srcpath, NULL, "mount source path or NULL in case of error or when the path is not defined.", NULL}, | |
730 | {"root", (getter)Fs_get_root, (setter)Fs_set_root, "mountinfo[4]: root of the mount within the FS", NULL}, | |
731 | {"target", (getter)Fs_get_target, (setter)Fs_set_target, "mountinfo[5], fstab[2]: mountpoint", NULL}, | |
732 | {"fstype", (getter)Fs_get_fstype, (setter)Fs_set_fstype, "mountinfo[9], fstab[3]: filesystem type", NULL}, | |
733 | {"options", (getter)Fs_get_options, (setter)Fs_set_options, "fstab[4]: merged options", NULL}, | |
734 | {"vfs_options", (getter)Fs_get_vfs_options, NULL, "mountinfo[6]: fs-independent (VFS) options", NULL}, | |
735 | {"opt_fields", (getter)Fs_get_optional_fields, NULL, "mountinfo[7]: optional fields", NULL}, | |
736 | {"fs_options", (getter)Fs_get_fs_options, NULL, "mountinfo[11]: fs-dependent options", NULL}, | |
737 | {"usr_options", (getter)Fs_get_user_options, NULL, "userspace mount options", NULL}, | |
738 | {"attributes", (getter)Fs_get_attributes, (setter)Fs_set_attributes, "mount attributes", NULL}, | |
739 | {"freq", (getter)Fs_get_freq, (setter)Fs_set_freq, "fstab[5]: dump frequency in days", NULL}, | |
740 | {"passno", (getter)Fs_get_passno, (setter)Fs_set_passno, "fstab[6]: pass number on parallel fsck", NULL}, | |
741 | {"swaptype", (getter)Fs_get_swaptype, NULL, "swaps[2]: device type", NULL}, | |
742 | {"size", (getter)Fs_get_size, NULL, "saps[3]: swaparea size", NULL}, | |
743 | {"usedsize", (getter)Fs_get_usedsize, NULL, "swaps[4]: used size", NULL}, | |
744 | {"priority", (getter)Fs_get_priority, NULL, "swaps[5]: swap priority", NULL}, | |
745 | {"tag", (getter)Fs_get_tag, NULL, "(Name, Value)", NULL}, | |
746 | {"tid", (getter)Fs_get_tid, NULL, "/proc/<tid>/mountinfo, otherwise zero", NULL}, | |
747 | {NULL} | |
748 | }; | |
749 | ||
750 | static PyObject *Fs_repr(FsObject *self) | |
751 | { | |
a2cb0250 KZ |
752 | const char *src = mnt_fs_get_source(self->fs), |
753 | *tgt = mnt_fs_get_target(self->fs), | |
754 | *type = mnt_fs_get_fstype(self->fs); | |
755 | ||
46407453 | 756 | return PyUnicode_FromFormat( |
a2cb0250 KZ |
757 | "<libmount.Fs object at %p, " |
758 | "source=%s, target=%s, fstype=%s>", | |
813683a3 | 759 | self, |
a2cb0250 KZ |
760 | src ? src : "None", |
761 | tgt ? tgt : "None", | |
762 | type ? type : "None"); | |
813683a3 OO |
763 | } |
764 | ||
765 | PyObject *PyObjectResultFs(struct libmnt_fs *fs) | |
766 | { | |
279a6d5f KZ |
767 | FsObject *result; |
768 | ||
813683a3 OO |
769 | if (!fs) { |
770 | PyErr_SetString(LibmountError, "internal exception"); | |
771 | return NULL; | |
772 | } | |
279a6d5f KZ |
773 | |
774 | result = mnt_fs_get_userdata(fs); | |
775 | if (result) { | |
776 | Py_INCREF(result); | |
b7e47ac1 KZ |
777 | DBG(FS, pymnt_debug_h(fs, "result py-obj %p: already exists, py-refcnt=%d", |
778 | result, (int) ((PyObject *) result)->ob_refcnt)); | |
279a6d5f | 779 | return (PyObject *) result; |
813683a3 OO |
780 | } |
781 | ||
9e930041 | 782 | /* Creating an encapsulating object: increment the refcount, so that code |
279a6d5f KZ |
783 | * such as tab.next_fs() doesn't call the destructor, which would free |
784 | * our fs struct as well | |
785 | */ | |
786 | result = PyObject_New(FsObject, &FsType); | |
813683a3 OO |
787 | if (!result) { |
788 | UL_RaiseExc(ENOMEM); | |
789 | return NULL; | |
790 | } | |
279a6d5f | 791 | |
813683a3 | 792 | Py_INCREF(result); |
20b222ec KZ |
793 | mnt_ref_fs(fs); |
794 | ||
b7e47ac1 KZ |
795 | DBG(FS, pymnt_debug_h(fs, "result py-obj %p new, py-refcnt=%d", |
796 | result, (int) ((PyObject *) result)->ob_refcnt)); | |
813683a3 | 797 | result->fs = fs; |
279a6d5f | 798 | mnt_fs_set_userdata(fs, result); |
a2cb0250 | 799 | return (PyObject *) result; |
813683a3 OO |
800 | } |
801 | ||
802 | static PyObject *Fs_copy_fs(FsObject *self, PyObject *args, PyObject *kwds) | |
803 | { | |
804 | PyObject *dest = NULL; | |
805 | char *kwlist[] = {"dest", NULL}; | |
679f086c | 806 | |
813683a3 OO |
807 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist, &dest)) { |
808 | PyErr_SetString(PyExc_TypeError, ARG_ERR); | |
809 | return NULL; | |
810 | } | |
a2cb0250 | 811 | if (PyObject_TypeCheck(dest, &FsType)) { /* existing object passed as argument */ |
813683a3 OO |
812 | if (!mnt_copy_fs(((FsObject *)dest)->fs, self->fs)) |
813 | return NULL; | |
b7e47ac1 | 814 | DBG(FS, pymnt_debug_h(dest, "copy data")); |
679f086c | 815 | return (PyObject *)dest; |
a2cb0250 | 816 | |
042f62df RP |
817 | } |
818 | ||
819 | if (dest == Py_None) { /* create new object */ | |
813683a3 | 820 | FsObject *result = PyObject_New(FsObject, &FsType); |
b7e47ac1 KZ |
821 | |
822 | DBG(FS, pymnt_debug_h(result, "new copy")); | |
813683a3 | 823 | result->fs = mnt_copy_fs(NULL, self->fs); |
279a6d5f | 824 | mnt_fs_set_userdata(result->fs, result); /* keep a pointer to encapsulating object */ |
813683a3 OO |
825 | return (PyObject *)result; |
826 | } | |
679f086c KZ |
827 | |
828 | PyErr_SetString(PyExc_TypeError, ARG_ERR); | |
829 | return NULL; | |
813683a3 OO |
830 | } |
831 | ||
832 | ||
833 | PyTypeObject FsType = { | |
46407453 | 834 | PyVarObject_HEAD_INIT(NULL, 0) |
813683a3 OO |
835 | "libmount.Fs", /*tp_name*/ |
836 | sizeof(FsObject), /*tp_basicsize*/ | |
837 | 0, /*tp_itemsize*/ | |
b7e47ac1 | 838 | (destructor)Fs_destructor, /*tp_dealloc*/ |
87918040 SK |
839 | NULL, /*tp_print*/ |
840 | NULL, /*tp_getattr*/ | |
841 | NULL, /*tp_setattr*/ | |
842 | NULL, /*tp_compare*/ | |
813683a3 | 843 | (reprfunc)Fs_repr, /*tp_repr*/ |
87918040 SK |
844 | NULL, /*tp_as_number*/ |
845 | NULL, /*tp_as_sequence*/ | |
846 | NULL, /*tp_as_mapping*/ | |
847 | NULL, /*tp_hash */ | |
848 | NULL, /*tp_call*/ | |
849 | NULL, /*tp_str*/ | |
850 | NULL, /*tp_getattro*/ | |
851 | NULL, /*tp_setattro*/ | |
852 | NULL, /*tp_as_buffer*/ | |
813683a3 OO |
853 | Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ |
854 | Fs_HELP, /* tp_doc */ | |
87918040 SK |
855 | NULL, /* tp_traverse */ |
856 | NULL, /* tp_clear */ | |
857 | NULL, /* tp_richcompare */ | |
813683a3 | 858 | 0, /* tp_weaklistoffset */ |
87918040 SK |
859 | NULL, /* tp_iter */ |
860 | NULL, /* tp_iternext */ | |
813683a3 OO |
861 | Fs_methods, /* tp_methods */ |
862 | Fs_members, /* tp_members */ | |
863 | Fs_getseters, /* tp_getset */ | |
87918040 SK |
864 | NULL, /* tp_base */ |
865 | NULL, /* tp_dict */ | |
866 | NULL, /* tp_descr_get */ | |
867 | NULL, /* tp_descr_set */ | |
813683a3 OO |
868 | 0, /* tp_dictoffset */ |
869 | (initproc)Fs_init, /* tp_init */ | |
87918040 | 870 | NULL, /* tp_alloc */ |
813683a3 OO |
871 | Fs_new, /* tp_new */ |
872 | }; | |
873 | ||
20b222ec | 874 | void FS_AddModuleObject(PyObject *mod) |
813683a3 OO |
875 | { |
876 | if (PyType_Ready(&FsType) < 0) | |
877 | return; | |
878 | ||
b7e47ac1 | 879 | DBG(FS, pymnt_debug("add to module")); |
813683a3 OO |
880 | Py_INCREF(&FsType); |
881 | PyModule_AddObject(mod, "Fs", (PyObject *)&FsType); | |
882 | } | |
883 |