summaryrefslogtreecommitdiffstats
path: root/mount-deprecated/sundries.c
diff options
context:
space:
mode:
Diffstat (limited to 'mount-deprecated/sundries.c')
-rw-r--r--mount-deprecated/sundries.c300
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;
+}