]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - mount/sundries.c
2 * Support functions. Exported functions are prototyped in sundries.h.
4 * added fcntl locking by Kjetil T. (kjetilho@math.uio.no) - aeb, 950927
6 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
7 * - added Native Language Support
13 #include <mntent.h> /* for MNTTYPE_SWAP */
15 #include "canonicalize.h"
27 xstrndup (const char *s
, int n
) {
31 die (EX_SOFTWARE
, _("bug in xstrndup call"));
40 /* reallocates its first arg - typical use: s = xstrconcat3(s,t,u); */
42 xstrconcat3 (char *s
, const char *t
, const char *u
) {
45 len
= (s
? strlen(s
) : 0) + (t
? strlen(t
) : 0) + (u
? strlen(u
) : 0);
54 s
= xrealloc(s
, len
+ 1);
62 /* frees its first arg - typical use: s = xstrconcat4(s,t,u,v); */
64 xstrconcat4 (char *s
, const char *t
, const char *u
, const char *v
) {
67 len
= (s
? strlen(s
) : 0) + (t
? strlen(t
) : 0) +
68 (u
? strlen(u
) : 0) + (v
? strlen(v
) : 0);
77 s
= xrealloc(s
, len
+ 1);
89 /* Call this with SIG_BLOCK to block and SIG_UNBLOCK to unblock. */
91 block_signals (int how
) {
95 sigdelset(&sigs
, SIGTRAP
);
96 sigdelset(&sigs
, SIGSEGV
);
97 sigprocmask (how
, &sigs
, (sigset_t
*) 0);
101 /* Non-fatal error. Print message and return. */
102 /* (print the message in a single printf, in an attempt
103 to avoid mixing output of several threads) */
105 error (const char *fmt
, ...) {
110 va_start (args
, fmt
);
111 vfprintf (stderr
, fmt
, args
);
116 /* Fatal error. Print message and exit. */
118 die(int err
, const char *fmt
, ...) {
122 vfprintf(stderr
, fmt
, args
);
123 fprintf(stderr
, "\n");
129 /* True if fstypes match. Null *TYPES means match anything,
130 except that swap types always return false. */
131 /* Accept nonfs,proc,devpts and nonfs,noproc,nodevpts
132 with the same meaning. */
134 matching_type (const char *type
, const char *types
) {
135 int no
; /* negated types list */
139 if (streq (type
, MNTTYPE_SWAP
))
145 if (!strncmp(types
, "no", 2)) {
150 /* Does type occur in types, separated by commas? */
154 if (!strncmp(p
, "no", 2) && !strncmp(p
+2, type
, len
) &&
155 (p
[len
+2] == 0 || p
[len
+2] == ','))
157 if (strncmp(p
, type
, len
) == 0 &&
158 (p
[len
] == 0 || p
[len
] == ','))
168 /* Returns 1 if needle found or noneedle not found in haystack
169 * Otherwise returns 0
172 check_option(const char *haystack
, const char *needle
) {
174 int len
, needle_len
, this_len
;
178 if (!strncmp(needle
, "no", 2)) {
182 needle_len
= strlen(needle
);
183 len
= strlen(haystack
);
185 for (p
= haystack
; p
< haystack
+len
; p
++) {
190 this_len
= strlen(p
);
192 if (this_len
!= needle_len
) {
196 if (strncmp(p
, needle
, this_len
) == 0)
197 return !no
; /* foo or nofoo was found */
201 return no
; /* foo or nofoo was not found */
205 /* Returns 1 if each of the test_opts options agrees with the entire
207 * Returns 0 if any noopt is found in test_opts and opt is found in options.
208 * Returns 0 if any opt is found in test_opts but is not found in options.
209 * Unlike fs type matching, nonetdev,user and nonetdev,nouser have
210 * DIFFERENT meanings; each option is matched explicitly as specified.
213 matching_opts (const char *options
, const char *test_opts
) {
218 if (test_opts
== NULL
)
221 len
= strlen(test_opts
);
224 die (EX_SYSERR
, _("not enough memory"));
226 for (p
= test_opts
; p
< test_opts
+len
; p
++) {
231 this_len
= strlen(p
);
233 if (!this_len
) continue; /* if two ',' appear in a row */
234 strncpy(q
, p
, this_len
);
236 if (!check_option(options
, q
))
237 return 0; /* any match failure means failure */
241 /* no match failures in list means success */
246 * Parses NAME=value, returns -1 on parse error, 0 success. The success is also
247 * when the 'spec' doesn't contain name=value pair (because the spec could be
248 * a devname too). In particular case the pointer 'name' is set to NULL.
250 * The result is a new allocated string (the 'name' pointer).
253 parse_spec(const char *spec
, char **name
, char **value
)
260 if (!(cp
= strchr(spec
, '=')))
261 return 0; /* no name= */
264 vl
= tk
+ (cp
- spec
);
267 if (*vl
== '"' || *vl
== '\'') {
268 if (!(cp
= strrchr(vl
+1, *vl
))) {
270 return -1; /* parse error */
282 is_pseudo_fs(const char *type
)
284 if (type
== NULL
|| *type
== '/')
286 if (streq(type
, "none") ||
287 streq(type
, "proc") ||
288 streq(type
, "tmpfs") ||
289 streq(type
, "sysfs") ||
290 streq(type
, "devpts"))
295 /* Make a canonical pathname from PATH. Returns a freshly malloced string.
296 It is up the *caller* to ensure that the PATH is sensible. i.e.
297 canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
298 is not a legal pathname for ``/dev/fd0''. Anything we cannot parse
299 we return unmodified. */
301 canonicalize_spec (const char *path
)
307 if (is_pseudo_fs(path
))
308 return xstrdup(path
);
310 res
= canonicalize_path(path
);
312 die(EX_SYSERR
, _("not enough memory"));
316 char *canonicalize (const char *path
)
318 char *res
= canonicalize_path(path
);
321 die(EX_SYSERR
, _("not enough memory"));