/* * Support functions. Exported functions are prototyped in sundries.h. * sundries.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp * * added fcntl locking by Kjetil T. (kjetilho@math.uio.no) - aeb, 950927 */ #include <unistd.h> #include <stdio.h> #include <string.h> #include <mntent.h> /* for MNTTYPE_SWAP */ #include "fstab.h" #include "sundries.h" #include "nfsmount.h" /* String list constructor. (car() and cdr() are defined in "sundries.h"). */ string_list cons (char *a, const string_list b) { string_list p; p = xmalloc (sizeof *p); car (p) = a; cdr (p) = b; return p; } void * xmalloc (size_t size) { void *t; if (size == 0) return NULL; t = malloc (size); if (t == NULL) die (EX_SYSERR, "not enough memory"); return t; } char * xstrdup (const char *s) { char *t; if (s == NULL) return NULL; t = strdup (s); if (t == NULL) die (EX_SYSERR, "not enough memory"); return t; } 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; } char * xstrconcat2 (const char *s, const char *t) { char *res; if (!s) s = ""; if (!t) t = ""; res = xmalloc(strlen(s) + strlen(t) + 1); strcpy(res, s); strcat(res, t); return res; } char * xstrconcat3 (const char *s, const char *t, const char *u) { char *res; if (!s) s = ""; if (!t) t = ""; if (!u) u = ""; res = xmalloc(strlen(s) + strlen(t) + strlen(u) + 1); strcpy(res, s); strcat(res, t); strcat(res, u); return res; } char * xstrconcat4 (const char *s, const char *t, const char *u, const char *v) { char *res; if (!s) s = ""; if (!t) t = ""; if (!u) u = ""; if (!v) v = ""; res = xmalloc(strlen(s) + strlen(t) + strlen(u) + strlen(v) + 1); strcpy(res, s); strcat(res, t); strcat(res, u); strcat(res, v); return res; } /* 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; char *fmt2; if (mount_quiet) return; fmt2 = xstrconcat2 (fmt, "\n"); va_start (args, fmt); vfprintf (stderr, fmt2, args); va_end (args); free (fmt2); } /* Fatal error. Print message and exit. */ void die (int err, const char *fmt, ...) { va_list args; va_start (args, fmt); vfprintf (stderr, fmt, args); fprintf (stderr, "\n"); va_end (args); unlock_mtab (); exit (err); } /* Parse a list of strings like str[,str]... into a string list. */ string_list parse_list (char *strings) { string_list list; char *t; if (strings == NULL) return NULL; list = cons (strtok (strings, ","), NULL); while ((t = strtok (NULL, ",")) != NULL) list = cons (t, list); return list; } /* True if fstypes match. Null *TYPES means match anything, except that swap types always return false. This routine has some ugliness to deal with ``no'' types. Fixed bug: the `no' part comes at the end - aeb, 970216 */ int matching_type (const char *type, string_list types) { char *notype; int foundyes, foundno; int no; /* true if a "no" type match, eg -t nominix */ if (streq (type, MNTTYPE_SWAP)) return 0; if (types == NULL) return 1; #ifdef EMBED if ((notype = malloc (strlen (type) + 3)) == NULL) #else if ((notype = alloca (strlen (type) + 3)) == NULL) #endif die (EX_SYSERR, "mount: out of memory"); sprintf (notype, "no%s", type); foundyes = foundno = no = 0; while (types != NULL) { if (cdr (types) == NULL) no = (car (types)[0] == 'n') && (car (types)[1] == 'o'); if (streq (type, car (types))) foundyes = 1; else if (streq (notype, car (types))) foundno = 1; types = cdr (types); } return (foundno ? 0 : (no ^ foundyes)); } /* 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 (const char *path) { char *canonical; if (path == NULL) return NULL; if (streq(path, "none") || streq(path, "proc")) return xstrdup(path); #ifdef EMBED #ifndef PATH_MAX #define PATH_MAX 128 #endif #endif canonical = xmalloc (PATH_MAX + 1); if (realpath (path, canonical)) return canonical; free(canonical); return xstrdup(path); }