diff options
Diffstat (limited to 'mount-deprecated/sundries.c')
-rw-r--r-- | mount-deprecated/sundries.c | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/mount-deprecated/sundries.c b/mount-deprecated/sundries.c new file mode 100644 index 000000000..9bff99753 --- /dev/null +++ b/mount-deprecated/sundries.c @@ -0,0 +1,300 @@ +/* + * Support functions. Exported functions are prototyped in sundries.h. + * + * added fcntl locking by Kjetil T. (kjetilho@math.uio.no) - aeb, 950927 + * + * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL> + * - added Native Language Support + * + */ +#include <unistd.h> +#include <stdio.h> +#include <string.h> +#include <mntent.h> /* for MNTTYPE_SWAP */ + +#include "canonicalize.h" + +#include "sundries.h" +#include "nls.h" + +int mount_quiet; +int verbose; +int nocanonicalize; +char *progname; + +char * +xstrndup (const char *s, int n) { + char *t; + + if (s == NULL) + die (EX_SOFTWARE, _("bug in xstrndup call")); + + t = xmalloc(n+1); + strncpy(t,s,n); + t[n] = 0; + + return t; +} + +/* reallocates its first arg - typical use: s = xstrconcat3(s,t,u); */ +char * +xstrconcat3 (char *s, const char *t, const char *u) { + size_t len = 0; + + len = (s ? strlen(s) : 0) + (t ? strlen(t) : 0) + (u ? strlen(u) : 0); + + if (!len) + return NULL; + if (!s) { + s = xmalloc(len + 1); + *s = '\0'; + } + else + s = xrealloc(s, len + 1); + if (t) + strcat(s, t); + if (u) + strcat(s, u); + return s; +} + +/* frees its first arg - typical use: s = xstrconcat4(s,t,u,v); */ +char * +xstrconcat4 (char *s, const char *t, const char *u, const char *v) { + size_t len = 0; + + len = (s ? strlen(s) : 0) + (t ? strlen(t) : 0) + + (u ? strlen(u) : 0) + (v ? strlen(v) : 0); + + if (!len) + return NULL; + if (!s) { + s = xmalloc(len + 1); + *s = '\0'; + } + else + s = xrealloc(s, len + 1); + if (t) + strcat(s, t); + if (u) + strcat(s, u); + if (v) + strcat(s, v); + return s; + + +} + +/* Call this with SIG_BLOCK to block and SIG_UNBLOCK to unblock. */ +void +block_signals (int how) { + sigset_t sigs; + + sigfillset (&sigs); + sigdelset(&sigs, SIGTRAP); + sigdelset(&sigs, SIGSEGV); + sigprocmask (how, &sigs, (sigset_t *) 0); +} + + +/* Non-fatal error. Print message and return. */ +/* (print the message in a single printf, in an attempt + to avoid mixing output of several threads) */ +void +error (const char *fmt, ...) { + va_list args; + + if (mount_quiet) + return; + va_start (args, fmt); + vfprintf (stderr, fmt, args); + va_end (args); + fputc('\n', stderr); +} + +/* Fatal error. Print message and exit. */ +void __attribute__ ((noreturn)) die(int err, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); + + exit(err); +} + +/* True if fstypes match. Null *TYPES means match anything, + except that swap types always return false. */ +/* Accept nonfs,proc,devpts and nonfs,noproc,nodevpts + with the same meaning. */ +int +matching_type (const char *type, const char *types) { + int no; /* negated types list */ + int len; + const char *p; + + if (streq (type, MNTTYPE_SWAP)) + return 0; + if (types == NULL) + return 1; + + no = 0; + if (!strncmp(types, "no", 2)) { + no = 1; + types += 2; + } + + /* Does type occur in types, separated by commas? */ + len = strlen(type); + p = types; + while(1) { + if (!strncmp(p, "no", 2) && !strncmp(p+2, type, len) && + (p[len+2] == 0 || p[len+2] == ',')) + return 0; + if (strncmp(p, type, len) == 0 && + (p[len] == 0 || p[len] == ',')) + return !no; + p = strchr(p,','); + if (!p) + break; + p++; + } + return no; +} + +/* Returns 1 if needle found or noneedle not found in haystack + * Otherwise returns 0 + */ +static int +check_option(const char *haystack, const char *needle) { + const char *p, *r; + int len, needle_len, this_len; + int no; + + no = 0; + if (!strncmp(needle, "no", 2)) { + no = 1; + needle += 2; + } + needle_len = strlen(needle); + len = strlen(haystack); + + for (p = haystack; p < haystack+len; p++) { + r = strchr(p, ','); + if (r) { + this_len = r-p; + } else { + this_len = strlen(p); + } + if (this_len != needle_len) { + p += this_len; + continue; + } + if (strncmp(p, needle, this_len) == 0) + return !no; /* foo or nofoo was found */ + p += this_len; + } + + return no; /* foo or nofoo was not found */ +} + + +/* Returns 1 if each of the test_opts options agrees with the entire + * list of options. + * Returns 0 if any noopt is found in test_opts and opt is found in options. + * Returns 0 if any opt is found in test_opts but is not found in options. + * Unlike fs type matching, nonetdev,user and nonetdev,nouser have + * DIFFERENT meanings; each option is matched explicitly as specified. + */ +int +matching_opts (const char *options, const char *test_opts) { + const char *p, *r; + char *q; + int len, this_len; + + if (test_opts == NULL) + return 1; + if (options == NULL) + options = ""; + + len = strlen(test_opts); + q = alloca(len+1); + if (q == NULL) + die (EX_SYSERR, _("not enough memory")); + + for (p = test_opts; p < test_opts+len; p++) { + r = strchr(p, ','); + if (r) { + this_len = r-p; + } else { + this_len = strlen(p); + } + if (!this_len) continue; /* if two ',' appear in a row */ + strncpy(q, p, this_len); + q[this_len] = '\0'; + if (!check_option(options, q)) + return 0; /* any match failure means failure */ + p += this_len; + } + + /* no match failures in list means success */ + return 1; +} + +int +is_pseudo_fs(const char *type) +{ + if (type == NULL || *type == '/') + return 0; + if (streq(type, "none") || + streq(type, "proc") || + streq(type, "tmpfs") || + streq(type, "sysfs") || + streq(type, "usbfs") || + streq(type, "cgroup") || + streq(type, "cpuset") || + streq(type, "rpc_pipefs") || + streq(type, "devpts") || + streq(type, "securityfs") || + streq(type, "debugfs")) + return 1; + return 0; +} + +/* Make a canonical pathname from PATH. Returns a freshly malloced string. + It is up the *caller* to ensure that the PATH is sensible. i.e. + canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.'' + is not a legal pathname for ``/dev/fd0''. Anything we cannot parse + we return unmodified. */ +char * +canonicalize_spec (const char *path) +{ + char *res; + + if (!path) + return NULL; + if (nocanonicalize || is_pseudo_fs(path)) + return xstrdup(path); + + res = canonicalize_path(path); + if (!res) + die(EX_SYSERR, _("not enough memory")); + return res; +} + +char *canonicalize (const char *path) +{ + char *res; + + if (!path) + return NULL; + else if (nocanonicalize) + return xstrdup(path); + + res = canonicalize_path(path); + if (!res) + die(EX_SYSERR, _("not enough memory")); + return res; +} |