228 lines
4.8 KiB
C
228 lines
4.8 KiB
C
/*
|
|
* 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;
|
|
|
|
if ((notype = alloca (strlen (type) + 3)) == NULL)
|
|
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);
|
|
|
|
canonical = xmalloc (PATH_MAX + 1);
|
|
|
|
if (realpath (path, canonical))
|
|
return canonical;
|
|
|
|
free(canonical);
|
|
return xstrdup(path);
|
|
}
|