]> git.ipfire.org Git - thirdparty/util-linux.git/blame - shlibs/mount/src/fs.c
libmount: improve parsers return codes
[thirdparty/util-linux.git] / shlibs / mount / src / fs.c
CommitLineData
d115ee9b
KZ
1/*
2 * Copyright (C) 2008-2009 Karel Zak <kzak@redhat.com>
3 *
4 * This file may be redistributed under the terms of the
5 * GNU Lesser General Public License.
d115ee9b
KZ
6 */
7
192c6aad
KZ
8/**
9 * SECTION: fs
10 * @title: Filesystem
3d735589 11 * @short_description: mnt_fs represents one entry in fstab/mtab/mountinfo
192c6aad
KZ
12 *
13 */
d115ee9b
KZ
14#include <stdio.h>
15#include <string.h>
16#include <stdlib.h>
17#include <ctype.h>
3fca8422 18#include <errno.h>
8e368761 19#include <blkid.h>
9ecdf48f 20#include <stddef.h>
d115ee9b
KZ
21
22#include "nls.h"
23#include "mountP.h"
24
25/**
26 * mnt_new_fs:
27 *
192c6aad 28 * Returns: newly allocated mnt_file fs.
d115ee9b
KZ
29 */
30mnt_fs *mnt_new_fs(void)
31{
32 mnt_fs *fs = calloc(1, sizeof(struct _mnt_fs));
33 if (!fs)
34 return NULL;
35
36 INIT_LIST_HEAD(&fs->ents);
37 return fs;
38}
39
40/**
41 * mnt_free_fs:
42 * @fs: fs pointer
43 *
44 * Deallocates the fs.
45 */
46void mnt_free_fs(mnt_fs *fs)
47{
48 if (!fs)
49 return;
50 list_del(&fs->ents);
51
52 free(fs->source);
53 free(fs->tagname);
54 free(fs->tagval);
0b3953a3 55 free(fs->root);
d115ee9b
KZ
56 free(fs->target);
57 free(fs->fstype);
58 free(fs->optstr);
59 free(fs->vfs_optstr);
60 free(fs->fs_optstr);
61
62 free(fs);
63}
64
7714c689 65static inline int cpy_str_item(void *new, const void *old, size_t offset)
9ecdf48f
KZ
66{
67 char **o = (char **) (old + offset);
68 char **n = (char **) (new + offset);
69
70 if (!*o)
71 return 0; /* source (old) is empty */
72
73 *n = strdup(*o);
74 if (!*n)
56be757f 75 return -ENOMEM;
9ecdf48f
KZ
76 return 0;
77}
78
79/**
80 * mnt_copy_fs:
81 * @fs: source FS
82 *
83 * This function does not copy userdata (se mnt_fs_set_userdata()). A new copy is
84 * not linked with any existing mnt_tab.
85 *
86 * Returns: copy of @fs
87 */
7714c689 88mnt_fs *mnt_copy_fs(const mnt_fs *fs)
9ecdf48f
KZ
89{
90 mnt_fs *n = mnt_new_fs();
91
92 if (!n)
93 return NULL;
94
95 n->id = fs->id;
96 n->parent = fs->parent;
97 n->devno = fs->devno;
98
99 if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, source)))
100 goto err;
101 if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, tagname)))
102 goto err;
103 if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, tagval)))
104 goto err;
105 if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, root)))
106 goto err;
107 if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, target)))
108 goto err;
109 if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, fstype)))
110 goto err;
111 if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, optstr)))
112 goto err;
113 if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, vfs_optstr)))
114 goto err;
115 if (cpy_str_item(n, fs, offsetof(struct _mnt_fs, fs_optstr)))
116 goto err;
117 n->freq = fs->freq;
118 n->passno = fs->passno;
119 n->flags = fs->flags;
120
121 return n;
122err:
123 mnt_free_fs(n);
124 return NULL;
125}
126
26b4f9e4
KZ
127/**
128 * mnt_fs_get_userdata:
129 * @fs: mnt_file instance
130 *
192c6aad 131 * Returns: private data set by mnt_fs_set_userdata() or NULL.
26b4f9e4
KZ
132 */
133void *mnt_fs_get_userdata(mnt_fs *fs)
134{
135 return fs ? fs->userdata : NULL;
136}
137
138/**
139 * mnt_fs_set_userdata:
140 * @fs: mnt_file instance
141 *
142 * The "userdata" are library independent data.
143 *
56be757f 144 * Returns: 0 or negative number in case of error (if @fs is NULL).
26b4f9e4
KZ
145 */
146int mnt_fs_set_userdata(mnt_fs *fs, void *data)
147{
148 if (!fs)
56be757f 149 return -EINVAL;
26b4f9e4
KZ
150 fs->userdata = data;
151 return 0;
152}
153
d115ee9b
KZ
154/**
155 * mnt_fs_get_srcpath:
156 * @fs: mnt_file (fstab/mtab/mountinfo) fs
157 *
158 * The mount "source path" is:
192c6aad
KZ
159 * - a directory for 'bind' mounts (in fstab or mtab only)
160 * - a device name for standard mounts
d115ee9b
KZ
161 *
162 * See also mnt_fs_get_tag() and mnt_fs_get_source().
163 *
192c6aad 164 * Returns: mount source path or NULL in case of error or when the path
d115ee9b 165 * is not defined.
d115ee9b
KZ
166 */
167const char *mnt_fs_get_srcpath(mnt_fs *fs)
168{
169 assert(fs);
170 if (!fs)
171 return NULL;
172
173 /* fstab-like fs */
174 if (fs->tagname)
175 return NULL; /* the source contains a "NAME=value" */
176 return fs->source;
177}
178
179/**
3d735589 180 * mnt_fs_get_source:
d115ee9b
KZ
181 * @fs: mnt_file (fstab/mtab/mountinfo) fs
182 *
192c6aad 183 * Returns: mount source. Note that the source could be unparsed TAG
d115ee9b
KZ
184 * (LABEL/UUID). See also mnt_fs_get_srcpath() and mnt_fs_get_tag().
185 */
186const char *mnt_fs_get_source(mnt_fs *fs)
187{
188 return fs ? fs->source : NULL;
189}
190
191/* Used by parser mnt_file ONLY (@source has to be allocated) */
b2d0b74d 192int __mnt_fs_set_source_ptr(mnt_fs *fs, char *source)
d115ee9b 193{
b2d0b74d
KZ
194 char *t = NULL, *v = NULL;
195
d115ee9b
KZ
196 assert(fs);
197
be1a5180
KZ
198 if (source && !strcmp(source, "none"))
199 source = NULL;
d115ee9b 200
be1a5180 201 if (source && strchr(source, '=')) {
b2d0b74d 202 if (blkid_parse_tag_string(source, &t, &v) != 0)
d115ee9b 203 return -1;
d115ee9b
KZ
204 }
205
b2d0b74d
KZ
206 if (fs->source != source)
207 free(fs->source);
208
209 free(fs->tagname);
210 free(fs->tagval);
211
d115ee9b 212 fs->source = source;
b2d0b74d
KZ
213 fs->tagname = t;
214 fs->tagval = v;
d115ee9b
KZ
215 return 0;
216}
217
218/**
219 * mnt_fs_set_source:
220 * @fs: fstab/mtab/mountinfo entry
221 * @source: new source
222 *
192c6aad
KZ
223 * This function creates a private copy (strdup()) of @source.
224 *
56be757f 225 * Returns: 0 on success or negative number in case of error.
d115ee9b
KZ
226 */
227int mnt_fs_set_source(mnt_fs *fs, const char *source)
228{
229 char *p;
b2d0b74d 230 int rc;
d115ee9b
KZ
231
232 if (!fs && !source)
56be757f 233 return -EINVAL;
d115ee9b
KZ
234 p = strdup(source);
235 if (!p)
56be757f 236 return -ENOMEM;
d115ee9b 237
b2d0b74d
KZ
238 rc = __mnt_fs_set_source_ptr(fs, p);
239 if (rc)
240 free(p);
241 return rc;
d115ee9b
KZ
242}
243
244/**
245 * mnt_fs_get_tag:
246 * @fs: fs
247 * @name: returns pointer to NAME string
248 * @value: returns pointer to VALUE string
249 *
250 * "TAG" is NAME=VALUE (e.g. LABEL=foo)
251 *
192c6aad
KZ
252 * The TAG is the first column in the fstab file. The TAG or "srcpath" has to
253 * be always set for all entries.
d115ee9b
KZ
254 *
255 * See also mnt_fs_get_source().
256 *
192c6aad
KZ
257 * <informalexample>
258 * <programlisting>
d115ee9b 259 * char *src;
192c6aad 260 * mnt_fs *fs = mnt_tab_find_target(tb, "/home", MNT_ITER_FORWARD);
d115ee9b
KZ
261 *
262 * if (!fs)
263 * goto err;
264 *
265 * src = mnt_fs_get_srcpath(fs);
266 * if (!src) {
267 * char *tag, *val;
268 * if (mnt_fs_get_tag(fs, &tag, &val) == 0)
269 * printf("%s: %s\n", tag, val); // LABEL or UUID
270 * } else
271 * printf("device: %s\n", src); // device or bind path
192c6aad
KZ
272 * </programlisting>
273 * </informalexample>
d115ee9b 274 *
56be757f 275 * Returns: 0 on success or negative number in case that a TAG is not defined.
d115ee9b
KZ
276 */
277int mnt_fs_get_tag(mnt_fs *fs, const char **name, const char **value)
278{
279 if (fs == NULL || !fs->tagname)
56be757f 280 return -EINVAL;
d115ee9b
KZ
281 if (name)
282 *name = fs->tagname;
283 if (value)
284 *value = fs->tagval;
285 return 0;
286}
287
288/**
289 * mnt_fs_get_target:
290 * @fs: fstab/mtab/mountinfo entry pointer
291 *
192c6aad 292 * Returns: pointer to mountpoint path or NULL
d115ee9b
KZ
293 */
294const char *mnt_fs_get_target(mnt_fs *fs)
295{
296 assert(fs);
297 return fs ? fs->target : NULL;
298}
299
300/**
301 * mnt_fs_set_target:
302 * @fs: fstab/mtab/mountinfo entry
303 * @target: mountpoint
304 *
192c6aad
KZ
305 * This function creates a private copy (strdup()) of @target.
306 *
56be757f 307 * Returns: 0 on success or negative number in case of error.
d115ee9b
KZ
308 */
309int mnt_fs_set_target(mnt_fs *fs, const char *target)
310{
311 char *p;
312
313 assert(fs);
314
315 if (!fs || !target)
56be757f 316 return -EINVAL;
d115ee9b
KZ
317 p = strdup(target);
318 if (!p)
56be757f 319 return -ENOMEM;
d115ee9b
KZ
320 free(fs->target);
321 fs->target = p;
322
323 return 0;
324}
325
326/**
327 * mnt_fs_get_fstype:
328 * @fs: fstab/mtab/mountinfo entry pointer
329 *
192c6aad 330 * Returns: pointer to filesystem type.
d115ee9b
KZ
331 */
332const char *mnt_fs_get_fstype(mnt_fs *fs)
333{
334 assert(fs);
335 return fs ? fs->fstype : NULL;
336}
337
338/* Used by mnt_file parser only */
b2d0b74d 339int __mnt_fs_set_fstype_ptr(mnt_fs *fs, char *fstype)
d115ee9b
KZ
340{
341 assert(fs);
342
343 if (!fstype)
56be757f 344 return -EINVAL;
d115ee9b 345
b2d0b74d
KZ
346 if (fstype != fs->fstype)
347 free(fs->fstype);
348
d115ee9b
KZ
349 fs->fstype = fstype;
350 fs->flags &= ~MNT_FS_PSEUDO;
351 fs->flags &= ~MNT_FS_NET;
352
353 /* save info about pseudo filesystems */
354 if (mnt_fstype_is_pseudofs(fs->fstype))
355 fs->flags |= MNT_FS_PSEUDO;
356 else if (mnt_fstype_is_netfs(fs->fstype))
357 fs->flags |= MNT_FS_NET;
9dd75aa6
KZ
358 else if (!strcmp(fs->fstype, "swap"))
359 fs->flags |= MNT_FS_SWAP;
d115ee9b
KZ
360
361 return 0;
362}
363
364/**
365 * mnt_fs_set_fstype:
366 * @fs: fstab/mtab/mountinfo entry
367 * @fstype: filesystem type
368 *
192c6aad
KZ
369 * This function creates a private copy (strdup()) of @fstype.
370 *
56be757f 371 * Returns: 0 on success or negative number in case of error.
d115ee9b
KZ
372 */
373int mnt_fs_set_fstype(mnt_fs *fs, const char *fstype)
374{
375 char *p;
b2d0b74d 376 int rc;
d115ee9b
KZ
377
378 if (!fs || !fstype)
56be757f 379 return -EINVAL;
d115ee9b
KZ
380 p = strdup(fstype);
381 if (!p)
56be757f 382 return -ENOMEM;
b2d0b74d
KZ
383 rc = __mnt_fs_set_fstype_ptr(fs, p);
384 if (rc)
385 free(p);
386 return rc;
d115ee9b
KZ
387}
388
389/**
390 * mnt_fs_get_optstr:
391 * @fs: fstab/mtab/mountinfo entry pointer
392 *
192c6aad 393 * Returns: pointer to mount option string with all options (FS and VFS)
d115ee9b
KZ
394 */
395const char *mnt_fs_get_optstr(mnt_fs *fs)
396{
397 assert(fs);
398 return fs ? fs->optstr : NULL;
399}
400
b2d0b74d 401int __mnt_fs_set_optstr_ptr(mnt_fs *fs, char *ptr, int split)
d115ee9b 402{
b2d0b74d 403 char *v = NULL, *f = NULL;
192c6aad 404
d115ee9b
KZ
405 assert(fs);
406
be1a5180 407 if (!fs)
56be757f 408 return -EINVAL;
b2d0b74d 409 if (ptr) {
56be757f 410 int rc = 0;
be1a5180 411
56be757f 412 if (split)
b2d0b74d 413 rc = mnt_split_optstr((char *) ptr, NULL, &v, &f, 0, 0);
56be757f
KZ
414 if (rc)
415 return rc;
3661b841 416 }
192c6aad 417
b2d0b74d
KZ
418 if (ptr != fs->optstr)
419 free(fs->optstr);
420
d115ee9b
KZ
421 free(fs->fs_optstr);
422 free(fs->vfs_optstr);
d6fead1e 423
b2d0b74d 424 fs->optstr = ptr;
3661b841
KZ
425 fs->fs_optstr = f;
426 fs->vfs_optstr = v;
192c6aad 427 return 0;
d115ee9b
KZ
428}
429
b2d0b74d
KZ
430int __mnt_fs_set_optstr(mnt_fs *fs, const char *optstr, int split)
431{
432 char *p;
433 int rc;
434
435 assert(fs);
436
437 p = strdup(optstr);
438 if (!p)
439 return -ENOMEM;
440 rc = __mnt_fs_set_optstr_ptr(fs, p, split);
441 if (rc)
442 free(p); /* error, deallocate */
443 return rc;
444}
445
3661b841 446/**
569f95b7
KZ
447 * mnt_fs_set_optstr:
448 * @fs: fstab/mtab/mountinfo entry
449 * @optstr: options string
450 *
451 * This function creates a private copy of @optstr. The function also updates
452 * VFS and FS mount options.
453 *
56be757f 454 * Returns: 0 on success or negative number in case of error.
569f95b7
KZ
455 */
456int mnt_fs_set_optstr(mnt_fs *fs, const char *optstr)
457{
458 return __mnt_fs_set_optstr(fs, optstr, TRUE);
459}
460
461/**
462 * mnt_fs_append_userspace_optstr:
3661b841 463 * @fs: fstab/mtab/mountinfo entry
569f95b7 464 * @optstr: options string
3661b841 465 *
569f95b7
KZ
466 * This function appends @optstr to the current list of the mount options. The VFS and
467 * FS mount options are not modified.
3661b841 468 *
56be757f 469 * Returns: 0 on success or negative number in case of error.
3661b841 470 */
569f95b7 471int mnt_fs_append_userspace_optstr(mnt_fs *fs, const char *optstr)
3661b841
KZ
472{
473 assert(fs);
3661b841 474 if (!fs || !optstr)
56be757f 475 return -EINVAL;
3661b841
KZ
476 return mnt_optstr_append_option(&fs->optstr, optstr, NULL);
477}
478
569f95b7
KZ
479/**
480 * mnt_fs_append_optstr:
481 * @fs: fstab/mtab/mountinfo entry
482 * @optstr: mount options
483 *
56be757f 484 * Returns: 0 on success or negative number in case of error.
569f95b7
KZ
485 */
486int mnt_fs_append_optstr(mnt_fs *fs, const char *optstr)
487{
488 char *v = NULL, *f = NULL;
56be757f 489 int rc;
569f95b7
KZ
490
491 assert(fs);
492
493 if (!fs)
56be757f 494 return -EINVAL;
569f95b7
KZ
495 if (!optstr)
496 return 0;
497
56be757f
KZ
498 rc = mnt_split_optstr((char *) optstr, NULL, &v, &f, 0, 0);
499 if (!rc)
500 rc = mnt_optstr_append_option(&fs->optstr, optstr, NULL);
501 if (!rc && v)
502 rc = mnt_optstr_append_option(&fs->vfs_optstr, v, NULL);
503 if (!rc && f)
504 rc = mnt_optstr_append_option(&fs->fs_optstr, f, NULL);
569f95b7 505
56be757f 506 return rc;
569f95b7
KZ
507}
508
c83fd489
KZ
509/**
510 * mnt_fs_prepend_optstr:
511 * @fs: fstab/mtab/mountinfo entry
512 * @optstr: mount options
513 *
514 * Returns: 0 on success or negative number in case of error.
515 */
516int mnt_fs_prepend_optstr(mnt_fs *fs, const char *optstr)
517{
518 char *v = NULL, *f = NULL;
519 int rc;
520
521 assert(fs);
522
523 if (!fs)
524 return -EINVAL;
525 if (!optstr)
526 return 0;
527
528 rc = mnt_split_optstr((char *) optstr, NULL, &v, &f, 0, 0);
529 if (!rc)
530 rc = mnt_optstr_prepend_option(&fs->optstr, optstr, NULL);
531 if (!rc && v)
532 rc = mnt_optstr_prepend_option(&fs->vfs_optstr, v, NULL);
533 if (!rc && f)
9dd75aa6 534 rc = mnt_optstr_prepend_option(&fs->fs_optstr, f, NULL);
c83fd489
KZ
535
536 return rc;
537}
538
d115ee9b
KZ
539/**
540 * mnt_fs_get_fs_optstr:
541 * @fs: fstab/mtab/mountinfo entry pointer
542 *
192c6aad 543 * Returns: pointer to superblock (fs-depend) mount option string or NULL.
d115ee9b
KZ
544 */
545const char *mnt_fs_get_fs_optstr(mnt_fs *fs)
546{
547 assert(fs);
548 return fs ? fs->fs_optstr : NULL;
549}
550
551/**
552 * mnt_fs_get_vfs_optstr:
efe73c3e 553 * @fs: fstab/mtab entry pointer
d115ee9b 554 *
192c6aad 555 * Returns: pointer to fs-independent (VFS) mount option string or NULL.
d115ee9b
KZ
556 */
557const char *mnt_fs_get_vfs_optstr(mnt_fs *fs)
558{
559 assert(fs);
560 return fs ? fs->vfs_optstr : NULL;
561}
562
563
564/**
565 * mnt_fs_get_freq:
566 * @fs: fstab/mtab/mountinfo entry pointer
567 *
3d735589 568 * Returns: dump frequency in days.
d115ee9b
KZ
569 */
570int mnt_fs_get_freq(mnt_fs *fs)
571{
572 assert(fs);
573 return fs ? fs->freq : 0;
574}
575
576/**
577 * mnt_fs_set_freq:
efe73c3e 578 * @fs: fstab/mtab entry pointer
d115ee9b
KZ
579 * @freq: dump frequency in days
580 *
56be757f 581 * Returns: 0 on success or negative number in case of error.
d115ee9b
KZ
582 */
583int mnt_fs_set_freq(mnt_fs *fs, int freq)
584{
585 assert(fs);
d115ee9b 586 if (!fs)
56be757f 587 return -EINVAL;
d115ee9b
KZ
588 fs->freq = freq;
589 return 0;
590}
591
592/**
593 * mnt_fs_get_passno:
efe73c3e 594 * @fs: fstab/mtab entry pointer
d115ee9b 595 *
192c6aad 596 * Returns: "pass number on parallel fsck".
d115ee9b
KZ
597 */
598int mnt_fs_get_passno(mnt_fs *fs)
599{
600 assert(fs);
601 return fs ? fs->passno: 0;
602}
603
604/**
605 * mnt_fs_set_passno:
efe73c3e 606 * @fs: fstab/mtab entry pointer
d115ee9b
KZ
607 * @passno: pass number
608 *
56be757f 609 * Returns: 0 on success or negative number in case of error.
d115ee9b
KZ
610 */
611int mnt_fs_set_passno(mnt_fs *fs, int passno)
612{
613 assert(fs);
d115ee9b 614 if (!fs)
56be757f 615 return -EINVAL;
d115ee9b
KZ
616 fs->passno = passno;
617 return 0;
618}
619
0b3953a3
KZ
620/**
621 * mnt_fs_get_root:
622 * @fs: /proc/self/mountinfo entry
623 *
624 * Returns: root of the mount within the filesystem or NULL
625 */
626const char *mnt_fs_get_root(mnt_fs *fs)
627{
628 assert(fs);
629 return fs ? fs->root : NULL;
630}
631
9ecdf48f
KZ
632/**
633 * mnt_fs_set_root:
634 * @fs: mountinfo entry
635 * @root: path
636 *
56be757f 637 * Returns: 0 on success or negative number in case of error.
9ecdf48f
KZ
638 */
639int mnt_fs_set_root(mnt_fs *fs, const char *root)
640{
641 char *p = NULL;
642
643 assert(fs);
644 if (!fs)
56be757f 645 return -EINVAL;
9ecdf48f
KZ
646 if (root) {
647 p = strdup(root);
648 if (!p)
56be757f 649 return -ENOMEM;
9ecdf48f
KZ
650 }
651 free(fs->root);
652 fs->root = p;
653 return 0;
654}
655
efe73c3e
KZ
656/**
657 * mnt_fs_get_id:
658 * @fs: /proc/self/mountinfo entry
659 *
56be757f 660 * Returns: mount ID (unique identifier of the mount) or negative number in case of error.
efe73c3e
KZ
661 */
662int mnt_fs_get_id(mnt_fs *fs)
663{
664 assert(fs);
56be757f 665 return fs ? fs->id : -EINVAL;
efe73c3e
KZ
666}
667
668/**
669 * mnt_fs_get_parent_id:
670 * @fs: /proc/self/mountinfo entry
671 *
56be757f 672 * Returns: parent mount ID or negative number in case of error.
efe73c3e
KZ
673 */
674int mnt_fs_get_parent_id(mnt_fs *fs)
675{
676 assert(fs);
56be757f 677 return fs ? fs->parent : -EINVAL;
efe73c3e
KZ
678}
679
680/**
681 * mnt_fs_get_devno:
0b3953a3 682 * @fs: /proc/self/mountinfo entry
efe73c3e
KZ
683 *
684 * Returns: value of st_dev for files on filesystem or 0 in case of error.
685 */
686dev_t mnt_fs_get_devno(mnt_fs *fs)
687{
688 assert(fs);
689 return fs ? fs->devno : 0;
690}
691
d115ee9b
KZ
692/**
693 * mnt_fs_get_option:
694 * @fs: fstab/mtab/mountinfo entry pointer
695 * @name: option name
696 * @value: returns pointer to the begin of the value (e.g. name=VALUE) or NULL
697 * @valsz: returns size of options value or 0
698 *
56be757f 699 * Returns: 0 on success, 1 when not found the @name or negative number in case of error.
d115ee9b
KZ
700 */
701int mnt_fs_get_option(mnt_fs *fs, const char *name,
702 char **value, size_t *valsz)
703{
704 char *optstr = (char *) mnt_fs_get_optstr(fs);
705 return optstr ? mnt_optstr_get_option(optstr, name, value, valsz) : 1;
706}
707
3fca8422
KZ
708/**
709 * mnt_fs_match_target:
710 * @fs: filesystem
711 * @target: mountpoint path
712 * @cache: tags/paths cache or NULL
713 *
714 * Possible are three attempts:
715 * 1) compare @target with @fs->target
716 * 2) realpath(@target) with @fs->target
717 * 3) realpath(@target) with realpath(@fs->target).
718 *
719 * The 2nd and 3rd attempts are not performed when @cache is NULL.
720 *
192c6aad 721 * Returns: 1 if @fs target is equal to @target else 0.
3fca8422
KZ
722 */
723int mnt_fs_match_target(mnt_fs *fs, const char *target, mnt_cache *cache)
724{
725 int rc = 0;
726
727 if (!fs || !target || !fs->target)
728 return 0;
729
730 /* 1) native paths */
731 rc = !strcmp(target, fs->target);
732
733 if (!rc && cache) {
734 /* 2) - canonicalized and non-canonicalized */
735 char *cn = mnt_resolve_path(target, cache);
736 rc = (cn && strcmp(cn, fs->target) == 0);
737
738 /* 3) - canonicalized and canonicalized */
739 if (!rc && cn) {
740 char *tcn = mnt_resolve_path(fs->target, cache);
741 rc = (tcn && strcmp(cn, tcn) == 0);
742 }
743 }
744
745 return rc;
746}
747
748/**
749 * mnt_fs_match_source:
750 * @fs: filesystem
751 * @source: tag or path (device or so)
752 * @cache: tags/paths cache or NULL
753 *
754 * Possible are four attempts:
755 * 1) compare @source with @fs->source
756 * 2) compare realpath(@source) with @fs->source
757 * 3) compare realpath(@source) with realpath(@fs->source)
758 * 4) compare realpath(@source) with evaluated tag from @fs->source
759 *
760 * The 2nd, 3rd and 4th attempts are not performed when @cache is NULL. The
761 * 2nd and 3rd attempts are not performed if @fs->source is tag.
762 *
192c6aad 763 * Returns: 1 if @fs source is equal to @source else 0.
3fca8422
KZ
764 */
765int mnt_fs_match_source(mnt_fs *fs, const char *source, mnt_cache *cache)
766{
3fca8422
KZ
767 char *cn;
768 const char *src, *t, *v;
769
770 if (!fs || !source || !fs->source)
771 return 0;
772
773 /* 1) native paths/tags */
3ef87248
KZ
774 if (!strcmp(source, fs->source))
775 return 1;
3fca8422 776
3ef87248
KZ
777 if (!cache)
778 return 0;
3fca8422
KZ
779 if (fs->flags & (MNT_FS_NET | MNT_FS_PSEUDO))
780 return 0;
781
782 cn = mnt_resolve_spec(source, cache);
783 if (!cn)
784 return 0;
785
786 /* 2) canonicalized and native */
787 src = mnt_fs_get_srcpath(fs);
3ef87248
KZ
788 if (src && !strcmp(cn, src))
789 return 1;
3fca8422
KZ
790
791 /* 3) canonicalized and canonicalized */
3ef87248 792 if (src) {
3fca8422 793 src = mnt_resolve_path(src, cache);
3ef87248
KZ
794 if (src && !strcmp(cn, src))
795 return 1;
3fca8422 796 }
3ef87248
KZ
797 if (src || mnt_fs_get_tag(fs, &t, &v))
798 /* src path does not match and tag is not defined */
3fca8422
KZ
799 return 0;
800
801 /* read @source's tags to the cache */
ba7232a1 802 if (mnt_cache_read_tags(cache, cn) < 0) {
3fca8422
KZ
803 if (errno == EACCES) {
804 /* we don't have permissions to read TAGs from
805 * @source, but can translate @fs tag to devname.
806 *
807 * (because libblkid uses udev symlinks and this is
808 * accessible for non-root uses)
809 */
810 char *x = mnt_resolve_tag(t, v, cache);
811 if (x && !strcmp(x, cn))
812 return 1;
813 }
814 return 0;
815 }
816
817 /* 4) has the @source a tag that matches with tag from @fs ? */
3ef87248
KZ
818 if (mnt_cache_device_has_tag(cache, cn, t, v))
819 return 1;
3fca8422 820
3ef87248 821 return 0;
3fca8422
KZ
822}
823
824/**
825 * mnt_fs_match_fstype:
826 * @fs: filesystem
827 * @types: filesystem name or comma delimited list of filesystems
828 *
829 * For more details see mnt_match_fstype().
830 *
192c6aad 831 * Returns: 1 if @fs type is matching to @types else 0. The function returns
3fca8422
KZ
832 * 0 when types is NULL.
833 */
834int mnt_fs_match_fstype(mnt_fs *fs, const char *types)
835{
836 return mnt_match_fstype(fs->fstype, types);
837}
838
839/**
840 * mnt_fs_match_options:
841 * @fs: filesystem
842 * @options: comma delimited list of options (and nooptions)
843 *
844 * For more details see mnt_match_options().
845 *
192c6aad 846 * Returns: 1 if @fs type is matching to @options else 0. The function returns
3fca8422
KZ
847 * 0 when types is NULL.
848 */
849int mnt_fs_match_options(mnt_fs *fs, const char *options)
850{
851 return mnt_match_options(fs->optstr, options);
852}
853
d115ee9b
KZ
854/**
855 * mnt_fs_print_debug
856 * @fs: fstab/mtab/mountinfo entry
857 * @file: output
858 *
56be757f 859 * Returns: 0 on success or negative number in case of error.
d115ee9b
KZ
860 */
861int mnt_fs_print_debug(mnt_fs *fs, FILE *file)
862{
863 if (!fs)
56be757f 864 return -EINVAL;
d115ee9b
KZ
865 fprintf(file, "------ fs: %p\n", fs);
866 fprintf(file, "source: %s\n", mnt_fs_get_source(fs));
867 fprintf(file, "target: %s\n", mnt_fs_get_target(fs));
868 fprintf(file, "fstype: %s\n", mnt_fs_get_fstype(fs));
869 fprintf(file, "optstr: %s\n", mnt_fs_get_optstr(fs));
9dd75aa6
KZ
870 if (mnt_fs_get_freq(fs))
871 fprintf(file, "freq: %d\n", mnt_fs_get_freq(fs));
872 if (mnt_fs_get_passno(fs))
873 fprintf(file, "pass: %d\n", mnt_fs_get_passno(fs));
874 if (mnt_fs_get_id(fs))
875 fprintf(file, "id: %d\n", mnt_fs_get_id(fs));
876 if (mnt_fs_get_parent_id(fs))
877 fprintf(file, "parent: %d\n", mnt_fs_get_parent_id(fs));
878 if (mnt_fs_get_devno(fs))
879 fprintf(file, "devno: %d:%d\n", major(mnt_fs_get_devno(fs)),
880 minor(mnt_fs_get_devno(fs)));
d115ee9b
KZ
881 return 0;
882}