Imported from util-linux-2.12h tarball.
This commit is contained in:
parent
2cccd0ff2b
commit
d26aa358f4
12
HISTORY
12
HISTORY
|
@ -1,3 +1,15 @@
|
|||
util-linux 2.12e,f,g,h
|
||||
|
||||
* cfdisk: avoid crash if no partition table
|
||||
* elvtune: tell user that this only works on 2.4 kernels
|
||||
* lomount: clear passwords after use
|
||||
* mount: accept comments (introduced by \;) in fstab - withdrawn again
|
||||
* mount: accept comments (specified by comment=) in fstab
|
||||
* mount: support ocfs, ocfs2
|
||||
* [u]mount: be more careful with malloc, try to avoid OOM with many mounts
|
||||
* sfdisk: __attribute__used nonsense to support gcc 3.4
|
||||
* shutdown: do not unmount various virtual filesystems
|
||||
|
||||
util-linux 2.12c,d
|
||||
|
||||
* mount.8: added recent ext2 mount options
|
||||
|
|
6
MCONFIG
6
MCONFIG
|
@ -7,6 +7,12 @@
|
|||
# - set USE_TTY_GROUP=no
|
||||
# - define DESTDIR
|
||||
|
||||
## Configuration outside of this file you might want to do for mount:
|
||||
## If make_include has HAVE_BLKID=yes, turn that into HAVE_BLKID=no
|
||||
## if you do not want to use the blkid library.
|
||||
## In mount/realpath.c turn #define resolve_symlinks into
|
||||
## #undef resolve_symlinks if you use devfs and hate long names.
|
||||
|
||||
# Select for ARCH one of intel, alpha, sparc, arm, m68k, mips
|
||||
# Select for CPU i386 if the binaries must be able to run on an intel 386
|
||||
# (by default i486 code is generated, see below)
|
||||
|
|
4
README
4
README
|
@ -5,5 +5,7 @@ misc-utils, sys-utils, getopt-* should be rather distribution-neutral,
|
|||
and installing it does no harm.
|
||||
On the other hand, the stuff in login-utils defines initial boot-time
|
||||
stuff, things that are done in different ways by different distributions.
|
||||
If you install it, your machine may not boot anymore.
|
||||
If you install it, your machine may not boot anymore, or you may be
|
||||
unable to login.
|
||||
|
||||
No RPMs are provided - get yours from your distributor.
|
||||
|
|
|
@ -20,12 +20,15 @@
|
|||
* Public License, version 2.
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/utsname.h>
|
||||
#include "nls.h"
|
||||
|
||||
/* this has to match with the kernel structure */
|
||||
|
@ -37,6 +40,7 @@ typedef struct blkelv_ioctl_arg_s {
|
|||
int max_bomb_segments;
|
||||
} blkelv_ioctl_arg_t;
|
||||
|
||||
/* ioctls introduced in 2.2.16, removed in 2.5.58 */
|
||||
#define BLKELVGET _IOR(0x12,106,size_t)
|
||||
#define BLKELVSET _IOW(0x12,107,size_t)
|
||||
|
||||
|
@ -48,6 +52,8 @@ usage(void) {
|
|||
" /dev/blkdev1 [/dev/blkdev2...]\n");
|
||||
fprintf(stderr, "\telvtune -h\n");
|
||||
fprintf(stderr, "\telvtune -v\n");
|
||||
fprintf(stderr, "\tNOTE: elvtune only works with 2.4 kernels\n");
|
||||
/* (ioctls exist in 2.2.16 - 2.5.57) */
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -55,6 +61,23 @@ version(void) {
|
|||
fprintf(stderr, "elvtune (%s)\n", util_linux_version);
|
||||
}
|
||||
|
||||
#define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
|
||||
|
||||
static int
|
||||
linux_version_code(void) {
|
||||
struct utsname my_utsname;
|
||||
int p, q, r;
|
||||
|
||||
if (uname(&my_utsname) == 0) {
|
||||
p = atoi(strtok(my_utsname.release, "."));
|
||||
q = atoi(strtok(NULL, "."));
|
||||
r = atoi(strtok(NULL, "."));
|
||||
return MAKE_VERSION(p,q,r);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char * argv[]) {
|
||||
int read_value = 0xbeefbeef, write_value = 0xbeefbeef, bomb_value = 0xbeefbeef;
|
||||
|
@ -110,8 +133,20 @@ main(int argc, char * argv[]) {
|
|||
break;
|
||||
}
|
||||
|
||||
/* mmj: If we get EINVAL it's not a 2.4 kernel, so warn about
|
||||
that and exit. It should return ENOTTY however, so check for
|
||||
that as well in case it gets corrected in the future */
|
||||
|
||||
if (ioctl(fd, BLKELVGET, &elevator) < 0) {
|
||||
int errsv = errno;
|
||||
perror("ioctl get");
|
||||
if ((errsv == EINVAL || errsv == ENOTTY) &&
|
||||
linux_version_code() >= MAKE_VERSION(2,5,58)) {
|
||||
fprintf(stderr,
|
||||
"\nelvtune is only useful on older "
|
||||
"kernels;\nfor 2.6 use IO scheduler "
|
||||
"sysfs tunables instead..\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1493,29 +1493,42 @@ get_partition_table_geometry(partition_table *bufp) {
|
|||
int first = TRUE;
|
||||
int bad = FALSE;
|
||||
|
||||
for (i=0; i<66; i++)
|
||||
if (bufp->c.b[446+i])
|
||||
goto nonz;
|
||||
|
||||
/* zero table */
|
||||
if (!curses_started) {
|
||||
fatal(_("No partition table.\n"), 3);
|
||||
return;
|
||||
} else {
|
||||
mvaddstr(WARNING_START, 0,
|
||||
_("No partition table. Starting with zero table."));
|
||||
putchar(BELL);
|
||||
refresh();
|
||||
zero_table = TRUE;
|
||||
return;
|
||||
}
|
||||
nonz:
|
||||
if (bufp->p.magicflag[0] != PART_TABLE_FLAG0 ||
|
||||
bufp->p.magicflag[1] != PART_TABLE_FLAG1) {
|
||||
/* Matthew Wilcox: slightly friendlier version of
|
||||
if (!curses_started)
|
||||
fatal(_("Bad signature on partition table"), 3);
|
||||
*/
|
||||
int cont;
|
||||
|
||||
/* Matthew Wilcox */
|
||||
mvaddstr(WARNING_START, 0,
|
||||
_("No partition table or unknown signature on partition table"));
|
||||
_("Unknown partition table type"));
|
||||
mvaddstr(WARNING_START+1, 0,
|
||||
_("Do you wish to start with a zero table [y/N] ?"));
|
||||
putchar(BELL);
|
||||
refresh();
|
||||
cont = getch();
|
||||
{
|
||||
int cont = getch();
|
||||
if (cont == EOF || !said_yes(cont))
|
||||
die_x(3);
|
||||
}
|
||||
zero_table = TRUE;
|
||||
return;
|
||||
|
||||
/* Oskar Liljeblad suggested:
|
||||
Bad signature blah blah
|
||||
If this is a brand new harddrive that has not been partitioned
|
||||
before, please run cfdisk -z.
|
||||
*/
|
||||
}
|
||||
|
||||
hh = ss = 0;
|
||||
|
|
|
@ -129,6 +129,18 @@ fatal(char *s, ...) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* GCC nonsense - needed for GCC 3.4.x with -O2
|
||||
*/
|
||||
#if defined(__GNUC__PREREQ) && __GNUC_PREREQ(3,4)
|
||||
#define __attribute__used __attribute__ ((used))
|
||||
#else
|
||||
#define __attribute__used
|
||||
#endif
|
||||
|
||||
/* Or test with #if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 4) */
|
||||
|
||||
|
||||
/*
|
||||
* A. About seeking
|
||||
*/
|
||||
|
@ -143,8 +155,13 @@ fatal(char *s, ...) {
|
|||
*
|
||||
* Note: we use 512-byte sectors here, irrespective of the hardware ss.
|
||||
*/
|
||||
#if !defined (__alpha__) && !defined (__ia64__) && !defined (__x86_64__) && !defined (__s390x__)
|
||||
static
|
||||
#undef use_lseek
|
||||
#if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (__s390x__)
|
||||
#define use_lseek
|
||||
#endif
|
||||
|
||||
#ifndef use_lseek
|
||||
static __attribute__used
|
||||
_syscall5(int, _llseek, unsigned int, fd, ulong, hi, ulong, lo,
|
||||
loff_t *, res, unsigned int, wh);
|
||||
#endif
|
||||
|
@ -155,7 +172,7 @@ sseek(char *dev, unsigned int fd, unsigned long s) {
|
|||
in = ((loff_t) s << 9);
|
||||
out = 1;
|
||||
|
||||
#if !defined (__alpha__) && !defined (__ia64__) && !defined (__x86_64__) && !defined (__s390x__)
|
||||
#ifndef use_lseek
|
||||
if (_llseek (fd, in>>32, in & 0xffffffff, &out, SEEK_SET) != 0) {
|
||||
#else
|
||||
if ((out = lseek(fd, in, SEEK_SET)) != in) {
|
||||
|
@ -1876,6 +1893,7 @@ max_length(int pno, int is_extended, struct part_desc *ep, int format,
|
|||
}
|
||||
|
||||
/* compute starting sector of a partition inside an extended one */
|
||||
/* return 0 on failure */
|
||||
/* ep is 0 or points to surrounding extended partition */
|
||||
static int
|
||||
compute_start_sect(struct part_desc *p, struct part_desc *ep) {
|
||||
|
@ -1889,6 +1907,7 @@ compute_start_sect(struct part_desc *p, struct part_desc *ep) {
|
|||
delta = -inc;
|
||||
else
|
||||
delta = 0;
|
||||
|
||||
if (delta < 0) {
|
||||
p->start -= delta;
|
||||
p->size += delta;
|
||||
|
|
|
@ -632,7 +632,18 @@ unmount_disks_ourselves(void)
|
|||
}
|
||||
n = 0;
|
||||
while (n < 100 && (mnt = getmntent(mtab))) {
|
||||
if (strcmp (mnt->mnt_type, "devfs") == 0) continue;
|
||||
/*
|
||||
* Neil Phillips: trying to unmount temporary / kernel
|
||||
* filesystems is pointless and may cause error messages;
|
||||
* /dev can be a ramfs managed by udev.
|
||||
*/
|
||||
if (strcmp(mnt->mnt_type, "devfs") == 0 ||
|
||||
strcmp(mnt->mnt_type, "proc") == 0 ||
|
||||
strcmp(mnt->mnt_type, "sysfs") == 0 ||
|
||||
strcmp(mnt->mnt_type, "ramfs") == 0 ||
|
||||
strcmp(mnt->mnt_type, "tmpfs") == 0 ||
|
||||
strcmp(mnt->mnt_type, "devpts") == 0)
|
||||
continue;
|
||||
mntlist[n++] = strdup(mnt->mnt_dir);
|
||||
}
|
||||
endmntent(mtab);
|
||||
|
|
|
@ -157,9 +157,9 @@ For documentation on all nfs-specific options have a look at
|
|||
Common for all types of file system are the options ``noauto''
|
||||
(do not mount when "mount -a" is given, e.g., at boot time), ``user''
|
||||
(allow a user to mount), and ``owner''
|
||||
(allow device owner to mount), and ``_netdev'' (device requires network
|
||||
to be available).
|
||||
The ``owner'' and ``_netdev'' options are Linux-specific.
|
||||
(allow device owner to mount), and ``comment''
|
||||
(e.g., for use by fstab-maintaining programs).
|
||||
The ``owner'' and ``comment'' options are Linux-specific.
|
||||
For more details, see
|
||||
.BR mount (8).
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "fstab.h"
|
||||
#include "sundries.h" /* for xmalloc() etc */
|
||||
#include "mount_blkid.h"
|
||||
#include "paths.h"
|
||||
#include "nls.h"
|
||||
|
||||
#define streq(s, t) (strcmp ((s), (t)) == 0)
|
||||
|
@ -94,10 +95,30 @@ fstab_head() {
|
|||
return &fstab;
|
||||
}
|
||||
|
||||
static void
|
||||
my_free(const void *s) {
|
||||
if (s)
|
||||
free((void *) s);
|
||||
}
|
||||
|
||||
static void
|
||||
discard_mntentchn(struct mntentchn *mc0) {
|
||||
struct mntentchn *mc, *mc1;
|
||||
|
||||
for (mc = mc0->nxt; mc != mc0; mc = mc1) {
|
||||
mc1 = mc->nxt;
|
||||
my_free(mc->m.mnt_fsname);
|
||||
my_free(mc->m.mnt_dir);
|
||||
my_free(mc->m.mnt_type);
|
||||
my_free(mc->m.mnt_opts);
|
||||
free(mc);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
read_mntentchn(mntFILE *mfp, const char *fnam, struct mntentchn *mc0) {
|
||||
struct mntentchn *mc = mc0;
|
||||
struct mntent *mnt;
|
||||
struct my_mntent *mnt;
|
||||
|
||||
while ((mnt = my_getmntent(mfp)) != NULL) {
|
||||
if (!streq(mnt->mnt_type, MNTTYPE_IGNORE)) {
|
||||
|
@ -239,7 +260,7 @@ is_mounted_once(const char *name) {
|
|||
struct mntentchn *
|
||||
getmntoptfile (const char *file) {
|
||||
struct mntentchn *mc, *mc0;
|
||||
char *opts, *s;
|
||||
const char *opts, *s;
|
||||
int l;
|
||||
|
||||
if (!file)
|
||||
|
@ -404,13 +425,14 @@ setlkw_timeout (int sig) {
|
|||
|
||||
/* Where does the link point to? Obvious choices are mtab and mtab~~.
|
||||
HJLu points out that the latter leads to races. Right now we use
|
||||
mtab~.<pid> instead. */
|
||||
mtab~.<pid> instead. Use 20 as upper bound for the length of %d. */
|
||||
#define MOUNTLOCK_LINKTARGET MOUNTED_LOCK "%d"
|
||||
#define MOUNTLOCK_LINKTARGET_LTH (sizeof(MOUNTED_LOCK)+20)
|
||||
|
||||
void
|
||||
lock_mtab (void) {
|
||||
int tries = 3;
|
||||
char *linktargetfile;
|
||||
char linktargetfile[MOUNTLOCK_LINKTARGET_LTH];
|
||||
|
||||
if (!signals_have_been_setup) {
|
||||
int sig = 0;
|
||||
|
@ -431,9 +453,6 @@ lock_mtab (void) {
|
|||
signals_have_been_setup = 1;
|
||||
}
|
||||
|
||||
/* somewhat clumsy, but some ancient systems do not have snprintf() */
|
||||
/* use 20 as upper bound for the length of %d output */
|
||||
linktargetfile = xmalloc(strlen(MOUNTLOCK_LINKTARGET) + 20);
|
||||
sprintf(linktargetfile, MOUNTLOCK_LINKTARGET, getpid ());
|
||||
|
||||
/* Repeat until it was us who made the link */
|
||||
|
@ -542,11 +561,11 @@ unlock_mtab (void) {
|
|||
*/
|
||||
|
||||
void
|
||||
update_mtab (const char *dir, struct mntent *instead) {
|
||||
update_mtab (const char *dir, struct my_mntent *instead) {
|
||||
mntFILE *mfp, *mftmp;
|
||||
const char *fnam = MOUNTED;
|
||||
struct mntentchn mtabhead; /* dummy */
|
||||
struct mntentchn *mc, *mc0, absent;
|
||||
struct mntentchn *mc, *mc0, *absent = NULL;
|
||||
|
||||
if (mtab_does_not_exist() || mtab_is_a_symlink())
|
||||
return;
|
||||
|
@ -577,6 +596,7 @@ update_mtab (const char *dir, struct mntent *instead) {
|
|||
if (mc && mc != mc0) {
|
||||
mc->prev->nxt = mc->nxt;
|
||||
mc->nxt->prev = mc->prev;
|
||||
free(mc);
|
||||
}
|
||||
} else {
|
||||
/* A remount */
|
||||
|
@ -584,12 +604,13 @@ update_mtab (const char *dir, struct mntent *instead) {
|
|||
}
|
||||
} else if (instead) {
|
||||
/* not found, add a new entry */
|
||||
absent.m = *instead;
|
||||
absent.nxt = mc0;
|
||||
absent.prev = mc0->prev;
|
||||
mc0->prev = &absent;
|
||||
absent = xmalloc(sizeof(*absent));
|
||||
absent->m = *instead;
|
||||
absent->nxt = mc0;
|
||||
absent->prev = mc0->prev;
|
||||
mc0->prev = absent;
|
||||
if (mc0->nxt == NULL)
|
||||
mc0->nxt = &absent;
|
||||
mc0->nxt = absent;
|
||||
}
|
||||
|
||||
/* write chain to mtemp */
|
||||
|
@ -609,6 +630,8 @@ update_mtab (const char *dir, struct mntent *instead) {
|
|||
}
|
||||
}
|
||||
|
||||
discard_mntentchn(mc0);
|
||||
|
||||
if (fchmod (fileno (mftmp->mntent_fp),
|
||||
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
|
||||
int errsv = errno;
|
||||
|
|
|
@ -1,14 +1,4 @@
|
|||
#include <mntent.h>
|
||||
#define _PATH_FSTAB "/etc/fstab"
|
||||
#ifdef _PATH_MOUNTED
|
||||
#define MOUNTED_LOCK _PATH_MOUNTED "~"
|
||||
#define MOUNTED_TEMP _PATH_MOUNTED ".tmp"
|
||||
#else
|
||||
#define MOUNTED_LOCK "/etc/mtab~"
|
||||
#define MOUNTED_TEMP "/etc/mtab.tmp"
|
||||
#endif
|
||||
#define LOCK_TIMEOUT 10
|
||||
|
||||
#include "mntent.h"
|
||||
int mtab_is_writable(void);
|
||||
int mtab_does_not_exist(void);
|
||||
int mtab_is_a_symlink(void);
|
||||
|
@ -16,7 +6,7 @@ int is_mounted_once(const char *name);
|
|||
|
||||
struct mntentchn {
|
||||
struct mntentchn *nxt, *prev;
|
||||
struct mntent m;
|
||||
struct my_mntent m;
|
||||
};
|
||||
|
||||
struct mntentchn *mtab_head (void);
|
||||
|
@ -32,7 +22,6 @@ struct mntentchn *getfsspecfile (const char *spec, const char *file);
|
|||
struct mntentchn *getfsuuidspec (const char *uuid);
|
||||
struct mntentchn *getfsvolspec (const char *label);
|
||||
|
||||
#include <mntent.h>
|
||||
void lock_mtab (void);
|
||||
void unlock_mtab (void);
|
||||
void update_mtab (const char *special, struct mntent *with);
|
||||
void update_mtab (const char *special, struct my_mntent *with);
|
||||
|
|
|
@ -62,7 +62,7 @@ reiserfs_magic_version(const char *magic) {
|
|||
|
||||
/*
|
||||
* Get both label and uuid.
|
||||
* For now, only ext2, ext3, xfs, ocfs, reiserfs are supported
|
||||
* For now, only ext2, ext3, xfs, ocfs, ocfs2, reiserfs are supported
|
||||
*/
|
||||
int
|
||||
get_label_uuid(const char *device, char **label, char *uuid) {
|
||||
|
@ -74,6 +74,7 @@ get_label_uuid(const char *device, char **label, char *uuid) {
|
|||
struct jfs_super_block jfssb;
|
||||
struct ocfs_volume_header ovh; /* Oracle */
|
||||
struct ocfs_volume_label olbl;
|
||||
struct ocfs2_super_block osb;
|
||||
struct reiserfs_super_block reiserfssb;
|
||||
|
||||
fd = open(device, O_RDONLY);
|
||||
|
@ -160,6 +161,29 @@ get_label_uuid(const char *device, char **label, char *uuid) {
|
|||
memcpy(uuid, reiserfssb.s_uuid, sizeof (reiserfssb.s_uuid));
|
||||
rv = 0;
|
||||
}
|
||||
else {
|
||||
int blksize, blkoff;
|
||||
|
||||
for (blksize = OCFS2_MIN_BLOCKSIZE;
|
||||
blksize <= OCFS2_MAX_BLOCKSIZE;
|
||||
blksize <<= 1) {
|
||||
blkoff = blksize * OCFS2_SUPER_BLOCK_BLKNO;
|
||||
if (lseek(fd, blkoff, SEEK_SET) == blkoff
|
||||
&& read(fd, (char *) &osb, sizeof(osb))
|
||||
== sizeof(osb)
|
||||
&& strncmp(osb.signature,
|
||||
OCFS2_SUPER_BLOCK_SIGNATURE,
|
||||
sizeof(OCFS2_SUPER_BLOCK_SIGNATURE))
|
||||
== 0) {
|
||||
memcpy(uuid, osb.s_uuid, sizeof(osb.s_uuid));
|
||||
namesize = sizeof(osb.s_label);
|
||||
if ((*label = calloc(namesize, 1)) != NULL)
|
||||
memcpy(*label, osb.s_label, namesize);
|
||||
rv = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return rv;
|
||||
|
|
|
@ -236,6 +236,20 @@ struct ocfs_volume_label {
|
|||
#define ocfslabellen(o) assemble2le(o.label_len)
|
||||
#define OCFS_MAGIC "OracleCFS"
|
||||
|
||||
struct ocfs2_super_block {
|
||||
u_char signature[8];
|
||||
u_char s_dummy1[184];
|
||||
u_char s_dummy2[80];
|
||||
u_char s_label[64];
|
||||
u_char s_uuid[16];
|
||||
};
|
||||
|
||||
#define OCFS2_MIN_BLOCKSIZE 512
|
||||
#define OCFS2_MAX_BLOCKSIZE 4096
|
||||
#define OCFS2_SUPER_BLOCK_BLKNO 2
|
||||
#define OCFS2_SUPER_BLOCK_SIGNATURE "OCFSV2"
|
||||
|
||||
|
||||
struct efs_volume_directory { /* size 16 */
|
||||
char vd_name[8];
|
||||
char vd_lbn[4];
|
||||
|
|
|
@ -249,7 +249,7 @@ int
|
|||
set_loop(const char *device, const char *file, unsigned long long offset,
|
||||
const char *encryption, int pfd, int *loopro) {
|
||||
struct loop_info64 loopinfo64;
|
||||
int fd, ffd, mode;
|
||||
int fd, ffd, mode, i;
|
||||
char *pass;
|
||||
|
||||
mode = (*loopro ? O_RDONLY : O_RDWR);
|
||||
|
@ -303,12 +303,14 @@ set_loop(const char *device, const char *file, unsigned long long offset,
|
|||
case LO_CRYPT_XOR:
|
||||
pass = getpass(_("Password: "));
|
||||
xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
|
||||
memset(pass, 0, strlen(pass));
|
||||
loopinfo64.lo_encrypt_key_size =
|
||||
strlen(loopinfo64.lo_encrypt_key);
|
||||
break;
|
||||
default:
|
||||
pass = xgetpass(pfd, _("Password: "));
|
||||
xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
|
||||
memset(pass, 0, strlen(pass));
|
||||
loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;
|
||||
}
|
||||
|
||||
|
@ -318,33 +320,35 @@ set_loop(const char *device, const char *file, unsigned long long offset,
|
|||
}
|
||||
close (ffd);
|
||||
|
||||
if (ioctl(fd, LOOP_SET_STATUS64, &loopinfo64) < 0) {
|
||||
i = ioctl(fd, LOOP_SET_STATUS64, &loopinfo64);
|
||||
if (i) {
|
||||
struct loop_info loopinfo;
|
||||
int errsv = errno;
|
||||
|
||||
errno = loop_info64_to_old(&loopinfo64, &loopinfo);
|
||||
if (errno) {
|
||||
i = loop_info64_to_old(&loopinfo64, &loopinfo);
|
||||
if (i) {
|
||||
errno = errsv;
|
||||
perror("ioctl: LOOP_SET_STATUS64");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) {
|
||||
} else {
|
||||
i = ioctl(fd, LOOP_SET_STATUS, &loopinfo);
|
||||
if (i)
|
||||
perror("ioctl: LOOP_SET_STATUS");
|
||||
goto fail;
|
||||
}
|
||||
memset(&loopinfo, 0, sizeof(loopinfo));
|
||||
}
|
||||
memset(&loopinfo64, 0, sizeof(loopinfo64));
|
||||
|
||||
if (i) {
|
||||
ioctl (fd, LOOP_CLR_FD, 0);
|
||||
close (fd);
|
||||
return 1;
|
||||
}
|
||||
close (fd);
|
||||
|
||||
if (verbose > 1)
|
||||
printf(_("set_loop(%s,%s,%llu): success\n"),
|
||||
device, file, offset);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
(void) ioctl (fd, LOOP_CLR_FD, 0);
|
||||
close (fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
|
||||
|
||||
static char *
|
||||
mangle(unsigned char *s) {
|
||||
mangle(const unsigned char *s) {
|
||||
char *ss, *sp;
|
||||
int n;
|
||||
|
||||
|
@ -118,9 +118,8 @@ my_endmntent (mntFILE *mfp) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
my_addmntent (mntFILE *mfp, struct mntent *mnt) {
|
||||
my_addmntent (mntFILE *mfp, struct my_mntent *mnt) {
|
||||
char *m1, *m2, *m3, *m4;
|
||||
int res;
|
||||
|
||||
|
@ -132,22 +131,21 @@ my_addmntent (mntFILE *mfp, struct mntent *mnt) {
|
|||
m3 = mangle(mnt->mnt_type);
|
||||
m4 = mangle(mnt->mnt_opts);
|
||||
|
||||
res = ((fprintf (mfp->mntent_fp, "%s %s %s %s %d %d\n",
|
||||
m1, m2, m3, m4, mnt->mnt_freq, mnt->mnt_passno)
|
||||
< 0) ? 1 : 0);
|
||||
res = fprintf (mfp->mntent_fp, "%s %s %s %s %d %d\n",
|
||||
m1, m2, m3, m4, mnt->mnt_freq, mnt->mnt_passno);
|
||||
|
||||
free(m1);
|
||||
free(m2);
|
||||
free(m3);
|
||||
free(m4);
|
||||
return res;
|
||||
return (res < 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Read the next entry from the file fp. Stop reading at an incorrect entry. */
|
||||
struct mntent *
|
||||
struct my_mntent *
|
||||
my_getmntent (mntFILE *mfp) {
|
||||
static char buf[4096];
|
||||
static struct mntent me;
|
||||
static struct my_mntent me;
|
||||
char *s;
|
||||
|
||||
again:
|
||||
|
|
|
@ -1,4 +1,14 @@
|
|||
#include <mntent.h> /* for struct mntent */
|
||||
#ifndef MY_MNTENT_H
|
||||
#define MY_MNTENT_H
|
||||
|
||||
struct my_mntent {
|
||||
const char *mnt_fsname;
|
||||
const char *mnt_dir;
|
||||
const char *mnt_type;
|
||||
const char *mnt_opts;
|
||||
int mnt_freq;
|
||||
int mnt_passno;
|
||||
};
|
||||
|
||||
#define ERR_MAX 5
|
||||
|
||||
|
@ -12,5 +22,7 @@ typedef struct mntFILEstruct {
|
|||
|
||||
mntFILE *my_setmntent (const char *file, char *mode);
|
||||
void my_endmntent (mntFILE *mfp);
|
||||
int my_addmntent (mntFILE *mfp, struct mntent *mnt);
|
||||
struct mntent *my_getmntent (mntFILE *mfp);
|
||||
int my_addmntent (mntFILE *mfp, struct my_mntent *mnt);
|
||||
struct my_mntent *my_getmntent (mntFILE *mfp);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -109,6 +109,7 @@ file hierarchy somewhere else. The call is
|
|||
.B "mount --bind olddir newdir"
|
||||
.RE
|
||||
After this call the same contents is accessible in two places.
|
||||
One can also remount a single file (on a single file).
|
||||
|
||||
This call attaches only (part of) a single filesystem, not possible
|
||||
submounts. The entire file hierarchy including submounts is attached
|
||||
|
@ -120,7 +121,7 @@ a second place using
|
|||
.\" available since Linux 2.4.11.
|
||||
The mount options are not changed.
|
||||
|
||||
Since Linux 2.5.1 it is possible to atomically move a subtree
|
||||
Since Linux 2.5.1 it is possible to atomically move a mounted tree
|
||||
to another place. The call is
|
||||
.RS
|
||||
.br
|
||||
|
@ -242,6 +243,8 @@ option below). It is possible to replace
|
|||
.I /etc/mtab
|
||||
by a symbolic link to
|
||||
.IR /proc/mounts ,
|
||||
and especially when you have very large numbers of mounts
|
||||
things will be much faster with that symlink,
|
||||
but some information is lost that way, and in particular
|
||||
working with the loop device will be less convenient,
|
||||
and using the "user" option will fail.
|
||||
|
@ -421,35 +424,15 @@ program have different calling conventions,
|
|||
.I /sbin/mount.smbfs
|
||||
may have to be a shell script that sets up the desired call.
|
||||
|
||||
The type
|
||||
.I iso9660
|
||||
is the default. If no
|
||||
If no
|
||||
.B \-t
|
||||
option is given, or if the
|
||||
.B auto
|
||||
type is specified, the superblock is probed for the filesystem type
|
||||
.RI ( adfs ,
|
||||
.IR bfs ,
|
||||
.IR cramfs ,
|
||||
.IR ext ,
|
||||
.IR ext2 ,
|
||||
.IR ext3 ,
|
||||
.IR hfs ,
|
||||
.IR hpfs ,
|
||||
.IR iso9660 ,
|
||||
.IR jfs ,
|
||||
.IR minix ,
|
||||
.IR ntfs ,
|
||||
.IR qnx4 ,
|
||||
.IR reiserfs ,
|
||||
.IR romfs ,
|
||||
.IR udf ,
|
||||
.IR ufs ,
|
||||
.IR vxfs ,
|
||||
.IR xfs ,
|
||||
.IR xiafs
|
||||
are supported).
|
||||
If this probe fails, mount will try to read the file
|
||||
type is specified, mount will try to guess the desired type.
|
||||
If mount was compiled with the blkid library, the guessing is done
|
||||
by this library. Otherwise, mount guesses itself by probing the
|
||||
superblock; if that does not turn up anything that looks familiar,
|
||||
mount will try to read the file
|
||||
.IR /etc/filesystems ,
|
||||
or, if that does not exist,
|
||||
.IR /proc/filesystems .
|
||||
|
@ -470,8 +453,8 @@ The
|
|||
type may be useful for user-mounted floppies.
|
||||
Creating a file
|
||||
.I /etc/filesystems
|
||||
can be useful to change the probe order (e.g., to try vfat before msdos)
|
||||
or if you use a kernel module autoloader.
|
||||
can be useful to change the probe order (e.g., to try vfat before msdos
|
||||
or ext3 before ext2) or if you use a kernel module autoloader.
|
||||
Warning: the probing uses a heuristic (the presence of appropriate `magic'),
|
||||
and could recognize the wrong filesystem type, possibly with catastrophic
|
||||
consequences. If your data is valuable, don't ask
|
||||
|
@ -587,9 +570,9 @@ Do not interpret character or block special devices on the file
|
|||
system.
|
||||
.TP
|
||||
.B noexec
|
||||
Do not allow execution of any binaries on the mounted file system.
|
||||
This option might be useful for a server that has file systems containing
|
||||
binaries for architectures other than its own.
|
||||
Do not allow direct execution of any binaries on the mounted file system.
|
||||
(Until recently it was possible to run binaries anyway using a command like
|
||||
/lib/ld*.so /mnt/binary. This trick fails since Linux 2.4.25 / 2.6.0.)
|
||||
.TP
|
||||
.B nosuid
|
||||
Do not allow set-user-identifier or set-group-identifier bits to take
|
||||
|
|
235
mount/mount.c
235
mount/mount.c
|
@ -2,43 +2,7 @@
|
|||
* A mount(8) for Linux 0.99.
|
||||
* mount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
|
||||
*
|
||||
* Wed Sep 14 22:43:00 1994: Mitchum DSouza
|
||||
* (mitch@mrc-applied-psychology.cambridge.ac.uk) added support for mounting
|
||||
* the "loop" device.
|
||||
*
|
||||
* Wed Sep 14 22:55:10 1994: Sander van Malssen (svm@kozmix.hacktic.nl)
|
||||
* added support for remounting readonly file systems readonly.
|
||||
*
|
||||
* Wed Feb 8 12:27:00 1995: Andries.Brouwer@cwi.nl fixed up error messages.
|
||||
* Sat Jun 3 20:44:38 1995: Patches from Andries.Brouwer@cwi.nl applied.
|
||||
* Tue Sep 26 22:38:20 1995: aeb@cwi.nl, many changes
|
||||
* Fri Feb 23 13:47:00 1996: aeb@cwi.nl, loop device related changes
|
||||
*
|
||||
* Since then, many changes - aeb.
|
||||
*
|
||||
* Wed Oct 1 23:55:28 1997: Dick Streefland <dick_streefland@tasking.com>
|
||||
* Implemented the "bg", "fg" and "retry" mount options for NFS.
|
||||
*
|
||||
* Tue Aug 4 15:54:31 1998: aeb@cwi.nl:
|
||||
* Open fd 0,1,2 so that printf's do not clobber /etc/mtab or so.
|
||||
* Mangle filenames with embedded spaces. Add ufsmagic. Add locking.
|
||||
* Avoid unnecessary error messages about /proc.
|
||||
* Improve support for noncanonical names in /etc/fstab.
|
||||
* Add support for volume labels and UUIDs.
|
||||
*
|
||||
* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
|
||||
* - added Native Language Support
|
||||
* 1999-03-21 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
||||
* - fixed strerr(errno) in gettext calls
|
||||
* 1999-07-05 Hirokazu Takahashi <h-takaha@sss.abk.nec.co.jp>
|
||||
* - fixed use of nouser option
|
||||
* 1999-09-09 Michael K. Johnson <johnsonm@redhat.com>
|
||||
* - added `owner' mount option
|
||||
* 2000-05-11 Mark A. Peloquin <peloquin@us.ibm.com>
|
||||
* - check_special_mountprog now returns correct status
|
||||
* 2000-11-08 aeb: accept nonnumeric uid=, gid= options
|
||||
* 2001-07-13 Michael K. Johnson <johnsonm@redhat.com>
|
||||
* - implemented -a -O
|
||||
* Modifications by many people. Distributed under GPL.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
@ -69,6 +33,7 @@
|
|||
#include "mount_guess_fstype.h"
|
||||
#include "mount_by_label.h"
|
||||
#include "getusername.h"
|
||||
#include "paths.h"
|
||||
#include "env.h"
|
||||
#include "nls.h"
|
||||
|
||||
|
@ -131,11 +96,11 @@ struct opt_map {
|
|||
#define MS_USERS 0x40000000
|
||||
#define MS_USER 0x20000000
|
||||
#define MS_OWNER 0x10000000
|
||||
#define MS_NETDEV 0x00020000
|
||||
#define MS_COMMENT 0x00020000
|
||||
#define MS_LOOP 0x00010000
|
||||
|
||||
/* Options that we keep the mount system call from seeing. */
|
||||
#define MS_NOSYS (MS_NOAUTO|MS_USERS|MS_USER|MS_NETDEV|MS_LOOP)
|
||||
#define MS_NOSYS (MS_NOAUTO|MS_USERS|MS_USER|MS_COMMENT|MS_LOOP)
|
||||
|
||||
/* Options that we keep from appearing in the options field in the mtab. */
|
||||
#define MS_NOMTAB (MS_REMOUNT|MS_NOAUTO|MS_USERS|MS_USER)
|
||||
|
@ -170,7 +135,9 @@ static const struct opt_map opt_map[] = {
|
|||
{ "nouser", 0, 1, MS_USER }, /* Forbid ordinary user to mount */
|
||||
{ "owner", 0, 0, MS_OWNER }, /* Let the owner of the device mount */
|
||||
{ "noowner", 0, 1, MS_OWNER }, /* Device owner has no special privs */
|
||||
{ "_netdev", 0, 0, MS_NETDEV }, /* Device accessible only via network */
|
||||
{ "_netdev", 0, 0, MS_COMMENT}, /* Device requires network */
|
||||
{ "comment", 0, 0, MS_COMMENT}, /* fstab comment only (kudzu,_netdev)*/
|
||||
|
||||
/* add new options here */
|
||||
#ifdef MS_NOSUB
|
||||
{ "sub", 0, 1, MS_NOSUB }, /* allow submounts */
|
||||
|
@ -196,19 +163,20 @@ static const struct opt_map opt_map[] = {
|
|||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption,
|
||||
*opt_speed;
|
||||
static const char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption,
|
||||
*opt_speed, *opt_comment;
|
||||
|
||||
static struct string_opt_map {
|
||||
char *tag;
|
||||
int skip;
|
||||
char **valptr;
|
||||
const char **valptr;
|
||||
} string_opt_map[] = {
|
||||
{ "loop=", 0, &opt_loopdev },
|
||||
{ "vfs=", 1, &opt_vfstype },
|
||||
{ "offset=", 0, &opt_offset },
|
||||
{ "encryption=", 0, &opt_encryption },
|
||||
{ "speed=", 0, &opt_speed },
|
||||
{ "comment=", 1, &opt_comment },
|
||||
{ NULL, 0, NULL }
|
||||
};
|
||||
|
||||
|
@ -239,7 +207,7 @@ int mount_quiet=0;
|
|||
|
||||
/* Report on a single mount. */
|
||||
static void
|
||||
print_one (const struct mntent *me) {
|
||||
print_one (const struct my_mntent *me) {
|
||||
if (mount_quiet)
|
||||
return;
|
||||
printf ("%s on %s", me->mnt_fsname, me->mnt_dir);
|
||||
|
@ -271,6 +239,11 @@ print_all (char *types) {
|
|||
exit (0);
|
||||
}
|
||||
|
||||
static void
|
||||
my_free(const void *s) {
|
||||
if (s)
|
||||
free((void *) s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for OPT in opt_map table and return mask value.
|
||||
|
@ -332,21 +305,24 @@ parse_opt (const char *opt, int *mask, char *extra_opts) {
|
|||
/* Take -o options list and compute 4th and 5th args to mount(2). flags
|
||||
gets the standard options (indicated by bits) and extra_opts all the rest */
|
||||
static void
|
||||
parse_opts (char *opts, int *flags, char **extra_opts) {
|
||||
char *opt;
|
||||
|
||||
parse_opts (const char *options, int *flags, char **extra_opts) {
|
||||
*flags = 0;
|
||||
*extra_opts = NULL;
|
||||
|
||||
clear_string_opts();
|
||||
|
||||
if (opts != NULL) {
|
||||
if (options != NULL) {
|
||||
char *opts = xstrdup(options);
|
||||
char *opt;
|
||||
|
||||
*extra_opts = xmalloc (strlen (opts) + 1);
|
||||
**extra_opts = '\0';
|
||||
|
||||
for (opt = strtok (opts, ","); opt; opt = strtok (NULL, ","))
|
||||
if (!parse_string_opt (opt))
|
||||
parse_opt (opt, flags, *extra_opts);
|
||||
|
||||
free(opts);
|
||||
}
|
||||
|
||||
if (readonly)
|
||||
|
@ -363,7 +339,7 @@ fix_opts_string (int flags, const char *extra_opts, const char *user) {
|
|||
const struct string_opt_map *m;
|
||||
char *new_opts;
|
||||
|
||||
new_opts = (flags & MS_RDONLY) ? "ro" : "rw";
|
||||
new_opts = xstrdup((flags & MS_RDONLY) ? "ro" : "rw");
|
||||
for (om = opt_map; om->opt != NULL; om++) {
|
||||
if (om->skip)
|
||||
continue;
|
||||
|
@ -392,7 +368,8 @@ already (const char *spec, const char *node) {
|
|||
int ret = 1;
|
||||
|
||||
if ((mc = getmntfile(node)) != NULL)
|
||||
error (_("mount: according to mtab, %s is already mounted on %s"),
|
||||
error (_("mount: according to mtab, "
|
||||
"%s is already mounted on %s"),
|
||||
mc->m.mnt_fsname, node);
|
||||
else if (spec && strcmp (spec, "none") &&
|
||||
(mc = getmntfile(spec)) != NULL)
|
||||
|
@ -407,9 +384,8 @@ already (const char *spec, const char *node) {
|
|||
static void
|
||||
create_mtab (void) {
|
||||
struct mntentchn *fstab;
|
||||
struct mntent mnt;
|
||||
struct my_mntent mnt;
|
||||
int flags;
|
||||
char *extra_opts;
|
||||
mntFILE *mfp;
|
||||
|
||||
lock_mtab();
|
||||
|
@ -423,12 +399,14 @@ create_mtab (void) {
|
|||
|
||||
/* Find the root entry by looking it up in fstab */
|
||||
if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root"))) {
|
||||
parse_opts (xstrdup (fstab->m.mnt_opts), &flags, &extra_opts);
|
||||
char *extra_opts;
|
||||
parse_opts (fstab->m.mnt_opts, &flags, &extra_opts);
|
||||
mnt.mnt_dir = "/";
|
||||
mnt.mnt_fsname = canonicalize (fstab->m.mnt_fsname);
|
||||
mnt.mnt_type = fstab->m.mnt_type;
|
||||
mnt.mnt_opts = fix_opts_string (flags, extra_opts, NULL);
|
||||
mnt.mnt_freq = mnt.mnt_passno = 0;
|
||||
my_free(extra_opts);
|
||||
|
||||
if (my_addmntent (mfp, &mnt) == 1) {
|
||||
int errsv = errno;
|
||||
|
@ -436,10 +414,11 @@ create_mtab (void) {
|
|||
MOUNTED, strerror (errsv));
|
||||
}
|
||||
}
|
||||
if (fchmod (fileno (mfp->mntent_fp), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0)
|
||||
if (fchmod (fileno (mfp->mntent_fp), 0644) < 0)
|
||||
if (errno != EROFS) {
|
||||
int errsv = errno;
|
||||
die (EX_FILEIO, _("mount: error changing mode of %s: %s"),
|
||||
die (EX_FILEIO,
|
||||
_("mount: error changing mode of %s: %s"),
|
||||
MOUNTED, strerror (errsv));
|
||||
}
|
||||
my_endmntent (mfp);
|
||||
|
@ -477,7 +456,7 @@ do_mount_syscall (struct mountargs *args) {
|
|||
* on return types is filled with the type used.
|
||||
*/
|
||||
static int
|
||||
guess_fstype_and_mount (char *spec, char *node, char **types,
|
||||
guess_fstype_and_mount(const char *spec, const char *node, const char **types,
|
||||
int flags, char *mount_opts) {
|
||||
struct mountargs args = { spec, node, NULL, flags & ~MS_NOSYS, mount_opts };
|
||||
|
||||
|
@ -526,7 +505,7 @@ guess_fstype_and_mount (char *spec, char *node, char **types,
|
|||
* Die if the user is not allowed to do this.
|
||||
*/
|
||||
static void
|
||||
suid_check(char *spec, char *node, int *flags, char **user) {
|
||||
suid_check(const char *spec, const char *node, int *flags, char **user) {
|
||||
if (suid) {
|
||||
/* RedHat patch: allow owners to mount when fstab contains
|
||||
the owner option. Note that this should never be used
|
||||
|
@ -563,8 +542,8 @@ suid_check(char *spec, char *node, int *flags, char **user) {
|
|||
}
|
||||
|
||||
static int
|
||||
loop_check(char **spec, char **type, int *flags,
|
||||
int *loop, char **loopdev, char **loopfile) {
|
||||
loop_check(const char **spec, const char **type, int *flags,
|
||||
int *loop, const char **loopdev, const char **loopfile) {
|
||||
int looptype;
|
||||
unsigned long long offset;
|
||||
|
||||
|
@ -627,9 +606,9 @@ loop_check(char **spec, char **type, int *flags,
|
|||
}
|
||||
|
||||
static void
|
||||
update_mtab_entry(char *spec, char *node, char *type, char *opts,
|
||||
int flags, int freq, int pass) {
|
||||
struct mntent mnt;
|
||||
update_mtab_entry(const char *spec, const char *node, const char *type,
|
||||
const char *opts, int flags, int freq, int pass) {
|
||||
struct my_mntent mnt;
|
||||
|
||||
mnt.mnt_fsname = canonicalize (spec);
|
||||
mnt.mnt_dir = canonicalize (node);
|
||||
|
@ -658,14 +637,16 @@ update_mtab_entry(char *spec, char *node, char *type, char *opts,
|
|||
} else {
|
||||
if ((my_addmntent (mfp, &mnt)) == 1) {
|
||||
int errsv = errno;
|
||||
error(_("mount: error writing %s: %s"), MOUNTED,
|
||||
strerror (errsv));
|
||||
error(_("mount: error writing %s: %s"),
|
||||
MOUNTED, strerror (errsv));
|
||||
}
|
||||
}
|
||||
my_endmntent(mfp);
|
||||
}
|
||||
unlock_mtab();
|
||||
}
|
||||
}
|
||||
my_free(mnt.mnt_fsname);
|
||||
my_free(mnt.mnt_dir);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -677,14 +658,15 @@ set_pfd(char *s) {
|
|||
}
|
||||
|
||||
static void
|
||||
cdrom_setspeed(char *spec) {
|
||||
cdrom_setspeed(const char *spec) {
|
||||
#define CDROM_SELECT_SPEED 0x5322 /* Set the CD-ROM speed */
|
||||
if (opt_speed) {
|
||||
int cdrom;
|
||||
int speed = atoi(opt_speed);
|
||||
|
||||
if ((cdrom = open(spec, O_RDONLY | O_NONBLOCK)) < 0)
|
||||
die(EX_FAIL, _("mount: cannot open %s for setting speed"),
|
||||
die(EX_FAIL,
|
||||
_("mount: cannot open %s for setting speed"),
|
||||
spec);
|
||||
if (ioctl(cdrom, CDROM_SELECT_SPEED, speed) < 0)
|
||||
die(EX_FAIL, _("mount: cannot set speed: %s"),
|
||||
|
@ -700,8 +682,8 @@ cdrom_setspeed(char *spec) {
|
|||
*/
|
||||
|
||||
static int
|
||||
check_special_mountprog(char *spec, char *node, char *type, int flags,
|
||||
char *extra_opts, int *status) {
|
||||
check_special_mountprog(const char *spec, const char *node, const char *type,
|
||||
int flags, char *extra_opts, int *status) {
|
||||
char mountprog[120];
|
||||
struct stat statbuf;
|
||||
int res;
|
||||
|
@ -714,7 +696,7 @@ check_special_mountprog(char *spec, char *node, char *type, int flags,
|
|||
if (stat(mountprog, &statbuf) == 0) {
|
||||
res = fork();
|
||||
if (res == 0) {
|
||||
char *oo, *mountargs[10];
|
||||
const char *oo, *mountargs[10];
|
||||
int i = 0;
|
||||
|
||||
setuid(getuid());
|
||||
|
@ -732,7 +714,7 @@ check_special_mountprog(char *spec, char *node, char *type, int flags,
|
|||
mountargs[i++] = oo;
|
||||
}
|
||||
mountargs[i] = NULL;
|
||||
execv(mountprog, mountargs);
|
||||
execv(mountprog, (char **) mountargs);
|
||||
exit(1); /* exec failed */
|
||||
} else if (res != -1) {
|
||||
int st;
|
||||
|
@ -758,32 +740,35 @@ check_special_mountprog(char *spec, char *node, char *type, int flags,
|
|||
* return status from wait
|
||||
*/
|
||||
static int
|
||||
try_mount_one (const char *spec0, const char *node0, char *types0,
|
||||
try_mount_one (const char *spec0, const char *node0, const char *types0,
|
||||
const char *opts0, int freq, int pass, int bg, int ro) {
|
||||
int res, status;
|
||||
int res = 0, status;
|
||||
int mnt5_res = 0; /* only for gcc */
|
||||
int mnt_err;
|
||||
int flags;
|
||||
char *extra_opts; /* written in mtab */
|
||||
char *mount_opts; /* actually used on system call */
|
||||
const char *opts;
|
||||
char *spec, *node, *types;
|
||||
const char *opts, *spec, *node, *types;
|
||||
char *user = 0;
|
||||
int loop = 0;
|
||||
char *loopdev = 0, *loopfile = 0;
|
||||
const char *loopdev = 0, *loopfile = 0;
|
||||
struct stat statbuf;
|
||||
int nfs_mount_version = 0; /* any version */
|
||||
|
||||
spec = xstrdup(spec0);
|
||||
node = xstrdup(node0);
|
||||
types = xstrdup(types0);
|
||||
opts = xstrdup(opts0);
|
||||
/* copies for freeing on exit */
|
||||
const char *opts1, *spec1, *node1, *types1, *extra_opts1;
|
||||
|
||||
parse_opts (xstrdup (opts), &flags, &extra_opts);
|
||||
spec = spec1 = xstrdup(spec0);
|
||||
node = node1 = xstrdup(node0);
|
||||
types = types1 = xstrdup(types0);
|
||||
opts = opts1 = xstrdup(opts0);
|
||||
|
||||
parse_opts (opts, &flags, &extra_opts);
|
||||
extra_opts1 = extra_opts;
|
||||
|
||||
/* quietly succeed for fstab entries that don't get mounted automatically */
|
||||
if (mount_all && (flags & MS_NOAUTO))
|
||||
return 0;
|
||||
goto out;
|
||||
|
||||
suid_check(spec, node, &flags, &user);
|
||||
|
||||
|
@ -800,7 +785,7 @@ try_mount_one (const char *spec0, const char *node0, char *types0,
|
|||
*/
|
||||
res = loop_check(&spec, &types, &flags, &loop, &loopdev, &loopfile);
|
||||
if (res)
|
||||
return res;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -808,8 +793,10 @@ try_mount_one (const char *spec0, const char *node0, char *types0,
|
|||
* For the moment these types are ncpfs and smbfs. Maybe also vxfs.
|
||||
* All such special things must occur isolated in the types string.
|
||||
*/
|
||||
if (check_special_mountprog (spec, node, types, flags, extra_opts, &status))
|
||||
return status;
|
||||
if (check_special_mountprog(spec, node, types, flags, extra_opts, &status)) {
|
||||
res = status;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Also nfs requires a separate program, but it is built in.
|
||||
|
@ -819,8 +806,10 @@ try_mount_one (const char *spec0, const char *node0, char *types0,
|
|||
retry_nfs:
|
||||
mnt_err = nfsmount (spec, node, &flags, &extra_opts, &mount_opts,
|
||||
&nfs_mount_version, bg);
|
||||
if (mnt_err)
|
||||
return mnt_err;
|
||||
if (mnt_err) {
|
||||
res = mnt_err;
|
||||
goto out;
|
||||
}
|
||||
#else
|
||||
die (EX_SOFTWARE, _("mount: this version was compiled "
|
||||
"without support for the type `nfs'"));
|
||||
|
@ -847,7 +836,8 @@ retry_nfs:
|
|||
pass);
|
||||
|
||||
block_signals (SIG_UNBLOCK);
|
||||
return 0;
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
mnt_err = errno;
|
||||
|
@ -981,7 +971,7 @@ retry_nfs:
|
|||
char *lowtype, *p;
|
||||
int u;
|
||||
|
||||
error (_("mount: fs type %s not supported by kernel"), types);
|
||||
error (_("mount: unknown filesystem type '%s'"), types);
|
||||
|
||||
/* maybe this loser asked for FAT or ISO9660 or isofs */
|
||||
lowtype = xstrdup(types);
|
||||
|
@ -995,7 +985,9 @@ retry_nfs:
|
|||
if (u && is_in_procfs(lowtype) == 1)
|
||||
error (_("mount: probably you meant %s"), lowtype);
|
||||
else if (!strncmp(lowtype, "iso", 3) && is_in_procfs("iso9660") == 1)
|
||||
error (_("mount: maybe you meant iso9660 ?"));
|
||||
error (_("mount: maybe you meant 'iso9660'?"));
|
||||
else if (!strncmp(lowtype, "fat", 3) && is_in_procfs("vfat") == 1)
|
||||
error (_("mount: maybe you meant 'vfat'?"));
|
||||
free(lowtype);
|
||||
} else
|
||||
error (_("mount: %s has wrong device number or fs type %s not supported"),
|
||||
|
@ -1033,16 +1025,18 @@ retry_nfs:
|
|||
types = types0;
|
||||
}
|
||||
if (opts) {
|
||||
char *opts1 = realloc(xstrdup(opts), strlen(opts)+4);
|
||||
strcat(opts1, ",ro");
|
||||
opts = opts1;
|
||||
char *opts2 = realloc(xstrdup(opts), strlen(opts)+4);
|
||||
strcat(opts2, ",ro");
|
||||
my_free(opts1);
|
||||
opts = opts1 = opts2;
|
||||
} else
|
||||
opts = "ro";
|
||||
if (types && !strcmp(types, "guess"))
|
||||
types = 0;
|
||||
error (_("mount: %s%s is write-protected, mounting read-only"),
|
||||
bd, spec0);
|
||||
return try_mount_one (spec0, node0, types, opts, freq, pass, bg, 1);
|
||||
res = try_mount_one (spec0, node0, types, opts, freq, pass, bg, 1);
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1050,7 +1044,16 @@ retry_nfs:
|
|||
error ("mount: %s", strerror (mnt_err)); break;
|
||||
}
|
||||
}
|
||||
return EX_FAIL;
|
||||
res = EX_FAIL;
|
||||
|
||||
out:
|
||||
my_free(extra_opts1);
|
||||
my_free(spec1);
|
||||
my_free(node1);
|
||||
my_free(opts1);
|
||||
my_free(types1);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1095,13 +1098,19 @@ usersubst(const char *opts) {
|
|||
return opts;
|
||||
}
|
||||
|
||||
static int
|
||||
is_existing_file (const char *s) {
|
||||
struct stat statbuf;
|
||||
|
||||
return (stat(s, &statbuf) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return 0 for success (either mounted sth or -a and NOAUTO was given)
|
||||
*/
|
||||
static int
|
||||
mount_one (const char *spec, const char *node, char *types, const char *opts,
|
||||
char *cmdlineopts, int freq, int pass) {
|
||||
mount_one (const char *spec, const char *node, const char *types,
|
||||
const char *opts, char *cmdlineopts, int freq, int pass) {
|
||||
int status, status2;
|
||||
const char *nspec;
|
||||
|
||||
|
@ -1119,7 +1128,7 @@ mount_one (const char *spec, const char *node, char *types, const char *opts,
|
|||
if (nspec)
|
||||
spec = nspec;
|
||||
|
||||
if (types == NULL && !mounttype) {
|
||||
if (types == NULL && !mounttype && !is_existing_file(spec)) {
|
||||
if (strchr (spec, ':') != NULL) {
|
||||
types = "nfs";
|
||||
if (verbose)
|
||||
|
@ -1161,25 +1170,34 @@ mount_one (const char *spec, const char *node, char *types, const char *opts,
|
|||
|
||||
/* Check if an fsname/dir pair was already in the old mtab. */
|
||||
static int
|
||||
mounted (const char *spec, char *node) {
|
||||
mounted (const char *spec0, const char *node0) {
|
||||
struct mntentchn *mc, *mc0;
|
||||
char *spec, *node;
|
||||
int ret = 0;
|
||||
|
||||
/* Handle possible UUID= and LABEL= in spec */
|
||||
spec = mount_get_devname(spec);
|
||||
spec0 = mount_get_devname(spec0);
|
||||
|
||||
spec = canonicalize(spec);
|
||||
node = canonicalize(node);
|
||||
spec = canonicalize(spec0);
|
||||
node = canonicalize(node0);
|
||||
|
||||
mc0 = mtab_head();
|
||||
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
|
||||
if (streq (spec, mc->m.mnt_fsname) && streq (node, mc->m.mnt_dir))
|
||||
return 1;
|
||||
return 0;
|
||||
if (streq (spec, mc->m.mnt_fsname) &&
|
||||
streq (node, mc->m.mnt_dir)) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
free(spec);
|
||||
free(node);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* avoid using stat() on things we are not going to mount anyway.. */
|
||||
static int
|
||||
has_noauto (char *opts) {
|
||||
has_noauto (const char *opts) {
|
||||
char *s;
|
||||
|
||||
if (!opts)
|
||||
|
@ -1586,8 +1604,7 @@ main (int argc, char *argv[]) {
|
|||
die (EX_USAGE,
|
||||
_("mount: cannot find %s in %s"),
|
||||
spec, _PATH_FSTAB);
|
||||
/* struct mntent does not have const qualifiers */
|
||||
mc->m.mnt_fsname = (char *) spec;
|
||||
mc->m.mnt_fsname = spec;
|
||||
} else {
|
||||
/* Try to find the other pathname in fstab. */
|
||||
spec = canonicalize (*argv);
|
||||
|
@ -1605,6 +1622,8 @@ main (int argc, char *argv[]) {
|
|||
/* Earlier mtab was tried first, but this would
|
||||
sometimes try the wrong mount in case mtab had
|
||||
the root device entry wrong. */
|
||||
|
||||
my_free(spec);
|
||||
}
|
||||
|
||||
result = mount_one (xstrdup (mc->m.mnt_fsname),
|
||||
|
|
|
@ -97,11 +97,12 @@ swapped(unsigned short a) {
|
|||
Added jfs - Christoph Hellwig
|
||||
Added sysv - Tim Launchbury
|
||||
Added udf - Bryce Nesbitt
|
||||
Added ocfs, ocfs2 - Manish Singh - http://oss.oracle.com/projects/ocfs2/
|
||||
*/
|
||||
static char
|
||||
*magic_known[] = {
|
||||
"adfs", "bfs", "cramfs", "efs", "ext", "ext2", "ext3",
|
||||
"hfs", "hpfs", "iso9660", "jfs", "minix", "ntfs",
|
||||
"hfs", "hpfs", "iso9660", "jfs", "minix", "ntfs", "ocfs", "ocfs2",
|
||||
"qnx4", "reiserfs", "romfs", "swap", "sysv", "udf", "ufs",
|
||||
"vxfs", "xfs", "xiafs"
|
||||
};
|
||||
|
@ -212,6 +213,7 @@ do_guess_fstype(const char *device) {
|
|||
struct fat_super_block fatsb;
|
||||
struct xfs_super_block xfsb;
|
||||
struct cramfs_super_block cramfssb;
|
||||
struct ocfs_volume_header ovh;
|
||||
struct efs_volume_header efsvh;
|
||||
struct efs_super efssb;
|
||||
} xsb; /* stuff at 0 */
|
||||
|
@ -232,6 +234,7 @@ do_guess_fstype(const char *device) {
|
|||
struct hpfs_super_block hpfssb;
|
||||
struct adfs_super_block adfssb;
|
||||
struct sysv_super_block svsb;
|
||||
struct ocfs2_super_block osb;
|
||||
struct stat statbuf;
|
||||
|
||||
/* opening and reading an arbitrary unknown path can have
|
||||
|
@ -261,6 +264,8 @@ do_guess_fstype(const char *device) {
|
|||
type = "romfs";
|
||||
else if(!strncmp(xsb.xfsb.s_magic, XFS_SUPER_MAGIC, 4))
|
||||
type = "xfs";
|
||||
else if(!strncmp(xsb.ovh.signature, OCFS_MAGIC, sizeof(OCFS_MAGIC)))
|
||||
type = "ocfs";
|
||||
else if(!strncmp(xsb.qnx4fs_magic+4, "QNX4FS", 6))
|
||||
type = "qnx4";
|
||||
else if(xsb.bfs_magic == 0x1badface)
|
||||
|
@ -438,6 +443,22 @@ do_guess_fstype(const char *device) {
|
|||
type = "reiserfs";
|
||||
}
|
||||
|
||||
if (!type) {
|
||||
int blksize, blkoff;
|
||||
|
||||
for (blksize = OCFS2_MIN_BLOCKSIZE;
|
||||
blksize <= OCFS2_MAX_BLOCKSIZE;
|
||||
blksize <<= 1) {
|
||||
blkoff = blksize * OCFS2_SUPER_BLOCK_BLKNO;
|
||||
if (lseek(fd, blkoff, SEEK_SET) != blkoff
|
||||
|| read(fd, (char *) &osb, sizeof(osb)) != sizeof(osb))
|
||||
goto io_error;
|
||||
if (strncmp(osb.signature, OCFS2_SUPER_BLOCK_SIGNATURE,
|
||||
sizeof(OCFS2_SUPER_BLOCK_SIGNATURE)) == 0)
|
||||
type = "ocfs2";
|
||||
}
|
||||
}
|
||||
|
||||
if (!type) {
|
||||
/* perhaps the user tries to mount the swap space
|
||||
on a new disk; warn her before she does mke2fs on it */
|
||||
|
@ -573,11 +594,11 @@ is_in_procfs(const char *type) {
|
|||
/* when 1 is returned, *types is NULL */
|
||||
int
|
||||
procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args,
|
||||
char **types) {
|
||||
const char **types) {
|
||||
char *files[2] = { ETC_FILESYSTEMS, PROC_FILESYSTEMS };
|
||||
FILE *procfs;
|
||||
char *fsname;
|
||||
char *notypes = NULL;
|
||||
const char *notypes = NULL;
|
||||
int no = 0;
|
||||
int ret = 1;
|
||||
int errsv = 0;
|
||||
|
|
|
@ -11,6 +11,6 @@ extern int verbose;
|
|||
char *guess_fstype(const char *device);
|
||||
char *do_guess_fstype(const char *device);
|
||||
int procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args,
|
||||
char **type);
|
||||
const char **type);
|
||||
int is_in_procfs(const char *fstype);
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#include <mntent.h>
|
||||
#define _PATH_FSTAB "/etc/fstab"
|
||||
#ifdef _PATH_MOUNTED
|
||||
#define MOUNTED_LOCK _PATH_MOUNTED "~"
|
||||
#define MOUNTED_TEMP _PATH_MOUNTED ".tmp"
|
||||
#else
|
||||
#define MOUNTED_LOCK "/etc/mtab~"
|
||||
#define MOUNTED_TEMP "/etc/mtab.tmp"
|
||||
#endif
|
||||
#define LOCK_TIMEOUT 10
|
|
@ -32,17 +32,13 @@
|
|||
|
||||
#define MAX_READLINKS 32
|
||||
|
||||
/* this leaks some memory - unimportant for mount */
|
||||
char *
|
||||
myrealpath(const char *path, char *resolved_path, int maxreslth) {
|
||||
int readlinks = 0;
|
||||
char *npath;
|
||||
char link_path[PATH_MAX+1];
|
||||
int n;
|
||||
#ifdef resolve_symlinks
|
||||
char *buf;
|
||||
int m;
|
||||
#endif
|
||||
char *buf = NULL;
|
||||
|
||||
npath = resolved_path;
|
||||
|
||||
|
@ -83,7 +79,7 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
|
|||
while (*path != '\0' && *path != '/') {
|
||||
if (npath-resolved_path > maxreslth-2) {
|
||||
errno = ENAMETOOLONG;
|
||||
return NULL;
|
||||
goto err;
|
||||
}
|
||||
*npath++ = *path++;
|
||||
}
|
||||
|
@ -91,7 +87,7 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
|
|||
/* Protect against infinite loops. */
|
||||
if (readlinks++ > MAX_READLINKS) {
|
||||
errno = ELOOP;
|
||||
return NULL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* See if last pathname component is a symlink. */
|
||||
|
@ -100,9 +96,11 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
|
|||
if (n < 0) {
|
||||
/* EINVAL means the file exists but isn't a symlink. */
|
||||
if (errno != EINVAL)
|
||||
return NULL;
|
||||
goto err;
|
||||
} else {
|
||||
#ifdef resolve_symlinks /* Richard Gooch dislikes sl resolution */
|
||||
int m;
|
||||
|
||||
/* Note: readlink doesn't add the null byte. */
|
||||
link_path[n] = '\0';
|
||||
if (*link_path == '/')
|
||||
|
@ -115,6 +113,8 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
|
|||
|
||||
/* Insert symlink contents into path. */
|
||||
m = strlen(path);
|
||||
if (buf)
|
||||
free(buf);
|
||||
buf = xmalloc(m + n + 1);
|
||||
memcpy(buf, link_path, n);
|
||||
memcpy(buf + n, path, m + 1);
|
||||
|
@ -128,5 +128,13 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
|
|||
npath--;
|
||||
/* Make sure it's null terminated. */
|
||||
*npath = '\0';
|
||||
|
||||
if (buf)
|
||||
free(buf);
|
||||
return resolved_path;
|
||||
|
||||
err:
|
||||
if (buf)
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ xstrconcat2 (const char *s, const char *t) {
|
|||
return res;
|
||||
}
|
||||
|
||||
/* frees its first arg - typical use: s = xstrconcat3(s,t,u); */
|
||||
char *
|
||||
xstrconcat3 (const char *s, const char *t, const char *u) {
|
||||
char *res;
|
||||
|
@ -84,9 +85,11 @@ xstrconcat3 (const char *s, const char *t, const char *u) {
|
|||
strcpy(res, s);
|
||||
strcat(res, t);
|
||||
strcat(res, u);
|
||||
free((void *) s);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* frees its first arg - typical use: s = xstrconcat4(s,t,u,v); */
|
||||
char *
|
||||
xstrconcat4 (const char *s, const char *t, const char *u, const char *v) {
|
||||
char *res;
|
||||
|
@ -100,6 +103,7 @@ xstrconcat4 (const char *s, const char *t, const char *u, const char *v) {
|
|||
strcat(res, t);
|
||||
strcat(res, u);
|
||||
strcat(res, v);
|
||||
free((void *) s);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -269,19 +273,18 @@ matching_opts (const char *options, const char *test_opts) {
|
|||
we return unmodified. */
|
||||
char *
|
||||
canonicalize (const char *path) {
|
||||
char *canonical;
|
||||
char canonical[PATH_MAX+2];
|
||||
|
||||
if (path == NULL)
|
||||
return NULL;
|
||||
|
||||
if (streq(path, "none") || streq(path, "proc") || streq(path, "devpts"))
|
||||
if (streq(path, "none") ||
|
||||
streq(path, "proc") ||
|
||||
streq(path, "devpts"))
|
||||
return xstrdup(path);
|
||||
|
||||
canonical = xmalloc (PATH_MAX+2);
|
||||
|
||||
if (myrealpath (path, canonical, PATH_MAX+1))
|
||||
return canonical;
|
||||
return xstrdup(canonical);
|
||||
|
||||
free(canonical);
|
||||
return xstrdup(path);
|
||||
}
|
||||
|
|
|
@ -249,7 +249,7 @@ do_swapoff(const char *special, int quiet) {
|
|||
exit(1); /* any further swapoffs will also fail */
|
||||
}
|
||||
|
||||
if (!quiet) {
|
||||
if (!quiet || errno == ENOMEM) {
|
||||
int errsv = errno;
|
||||
fprintf(stderr, "%s: %s: %s\n", program_name,
|
||||
special, strerror(errsv));
|
||||
|
|
|
@ -316,7 +316,7 @@ umount_one (const char *spec, const char *node, const char *type,
|
|||
res = mount(spec, node, NULL,
|
||||
MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL);
|
||||
if (res == 0) {
|
||||
struct mntent remnt;
|
||||
struct my_mntent remnt;
|
||||
fprintf(stderr,
|
||||
_("umount: %s busy - remounted read-only\n"),
|
||||
spec);
|
||||
|
@ -392,6 +392,8 @@ umount_one (const char *spec, const char *node, const char *type,
|
|||
}
|
||||
|
||||
/*
|
||||
* umount_one_bw: unmount FILE that has last occurrence MC0
|
||||
*
|
||||
* Why this loop?
|
||||
* 1. People who boot a system with a bad fstab root entry
|
||||
* will get an incorrect "/dev/foo on /" in mtab.
|
||||
|
@ -472,52 +474,18 @@ usage (FILE *fp, int n)
|
|||
|
||||
int mount_quiet = 0;
|
||||
|
||||
/*=======================================================================*/
|
||||
/* string list stuff - no longer used by mount - will disappear entirely */
|
||||
typedef struct string_list {
|
||||
char *hd;
|
||||
struct string_list *tl;
|
||||
} *string_list;
|
||||
|
||||
#define car(p) ((p) -> hd)
|
||||
#define cdr(p) ((p) -> tl)
|
||||
|
||||
static string_list
|
||||
cons (char *a, const string_list b) {
|
||||
string_list p;
|
||||
|
||||
p = xmalloc (sizeof *p);
|
||||
car (p) = a;
|
||||
cdr (p) = b;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Parse a list of strings like str[,str]... into a string list. */
|
||||
static string_list
|
||||
parse_list (char *strings) {
|
||||
string_list list;
|
||||
char *s, *t;
|
||||
|
||||
if (strings == NULL)
|
||||
return NULL;
|
||||
|
||||
/* strtok() destroys its argument, so we have to use a copy */
|
||||
s = xstrdup(strings);
|
||||
|
||||
list = cons (strtok (s, ","), NULL);
|
||||
|
||||
while ((t = strtok (NULL, ",")) != NULL)
|
||||
list = cons (t, list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for an option in a comma-separated list
|
||||
*/
|
||||
static int
|
||||
contains(string_list list, char *s) {
|
||||
while (list) {
|
||||
if (streq (car (list), s))
|
||||
contains(const char *list, const char *s) {
|
||||
int n = strlen(s);
|
||||
|
||||
while (*list) {
|
||||
if (strncmp(list, s, n) == 0 &&
|
||||
(list[n] == 0 || list[n] == ','))
|
||||
return 1;
|
||||
list = cdr (list);
|
||||
while (*list && *list++ != ',') ;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -526,12 +494,18 @@ contains(string_list list, char *s) {
|
|||
* If list contains "user=peter" and we ask for "user=", return "peter"
|
||||
*/
|
||||
static char *
|
||||
get_value(string_list list, char *s) {
|
||||
get_value(const char *list, const char *s) {
|
||||
const char *t;
|
||||
int n = strlen(s);
|
||||
while (list) {
|
||||
if (strncmp (car (list), s, n) == 0)
|
||||
return car(list)+n;
|
||||
list = cdr (list);
|
||||
|
||||
while (*list) {
|
||||
if (strncmp(list, s, n) == 0) {
|
||||
s = t = list+n;
|
||||
while (*s && *s != ',')
|
||||
s++;
|
||||
return xstrndup(t, s-t);
|
||||
}
|
||||
while (*list && *list++ != ',') ;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -539,8 +513,7 @@ get_value(string_list list, char *s) {
|
|||
static int
|
||||
umount_file (char *arg) {
|
||||
struct mntentchn *mc, *fs;
|
||||
char *file;
|
||||
string_list options;
|
||||
const char *file, *options;
|
||||
int fstab_has_user, fstab_has_users, fstab_has_owner, ok;
|
||||
|
||||
file = canonicalize(arg); /* mtab paths are canonicalized */
|
||||
|
@ -594,7 +567,9 @@ umount_file (char *arg) {
|
|||
/* A convenient side effect is that the user who mounted
|
||||
is visible in mtab. */
|
||||
|
||||
options = parse_list (fs->m.mnt_opts);
|
||||
options = fs->m.mnt_opts;
|
||||
if (!options)
|
||||
options = "";
|
||||
fstab_has_user = contains(options, "user");
|
||||
fstab_has_users = contains(options, "users");
|
||||
fstab_has_owner = contains(options, "owner");
|
||||
|
@ -606,7 +581,9 @@ umount_file (char *arg) {
|
|||
if (!ok && (fstab_has_user || fstab_has_owner)) {
|
||||
char *user = getusername();
|
||||
|
||||
options = parse_list (mc->m.mnt_opts);
|
||||
options = mc->m.mnt_opts;
|
||||
if (!options)
|
||||
options = "";
|
||||
mtab_user = get_value(options, "user=");
|
||||
|
||||
if (user && mtab_user && streq (user, mtab_user))
|
||||
|
|
2
po/ca.po
2
po/ca.po
|
@ -10,7 +10,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: util-linux 2.12\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:04+0200\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:05+0200\n"
|
||||
"PO-Revision-Date: 2003-08-01 10:59+0200\n"
|
||||
"Last-Translator: Antoni Bella Perez <bella5@teleline.es>\n"
|
||||
"Language-Team: Catalan <ca@dodds.net>\n"
|
||||
|
|
3250
po/cat-id-tbl.c
3250
po/cat-id-tbl.c
File diff suppressed because it is too large
Load Diff
2
po/cs.po
2
po/cs.po
|
@ -4,7 +4,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: util-linux-2.11d\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:04+0200\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:05+0200\n"
|
||||
"PO-Revision-Date: 2001-05-30 15:11+0200\n"
|
||||
"Last-Translator: Jiøí Pavlovský <pavlovsk@ff.cuni.cz>\n"
|
||||
"Language-Team: Czech <cs@li.org>\n"
|
||||
|
|
2
po/da.po
2
po/da.po
|
@ -12,7 +12,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: util-linux 2.11y\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:04+0200\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:05+0200\n"
|
||||
"PO-Revision-Date: 2002-12-02 21:15GMT\n"
|
||||
"Last-Translator: Claus Hindsgaul <claus_h@image.dk>\n"
|
||||
"Language-Team: Danish <dansk@klid.dk>\n"
|
||||
|
|
2
po/de.po
2
po/de.po
|
@ -44,7 +44,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: util-linux 2.12\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:04+0200\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:05+0200\n"
|
||||
"PO-Revision-Date: 2003-08-14 15:43:31+0200\n"
|
||||
"Last-Translator: Michael Piefel <piefel@informatik.hu-berlin.de>\n"
|
||||
"Language-Team: German <de@li.org>\n"
|
||||
|
|
2
po/es.po
2
po/es.po
|
@ -12,7 +12,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: util-linux 2.12\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:04+0200\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:05+0200\n"
|
||||
"PO-Revision-Date: 2003-08-09 16:18+0200\n"
|
||||
"Last-Translator: Santiago Vila Doncel <sanvila@unex.es>\n"
|
||||
"Language-Team: Spanish <es@li.org>\n"
|
||||
|
|
2
po/et.po
2
po/et.po
|
@ -11,7 +11,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: util-linux 2.11r\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:04+0200\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:05+0200\n"
|
||||
"PO-Revision-Date: 2002-05-19 20:04GMT+0300\n"
|
||||
"Last-Translator: Meelis Roos <mroos@linux.ee>\n"
|
||||
"Language-Team: Estonian <et@li.org>\n"
|
||||
|
|
2
po/fi.po
2
po/fi.po
|
@ -14,7 +14,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: util-linux 2.12\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:04+0200\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:05+0200\n"
|
||||
"PO-Revision-Date: 2003-08-20 11:40+0300\n"
|
||||
"Last-Translator: Lauri Nurmi <lanurmi@iki.fi>\n"
|
||||
"Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n"
|
||||
|
|
2
po/fr.po
2
po/fr.po
|
@ -9,7 +9,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: util-linux 2.12\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:04+0200\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:05+0200\n"
|
||||
"PO-Revision-Date: 2004-05-10 08:00-0500\n"
|
||||
"Last-Translator: Michel Robitaille <robitail@IRO.UMontreal.CA>\n"
|
||||
"Language-Team: French <traduc@traduc.org>\n"
|
||||
|
|
2
po/it.po
2
po/it.po
|
@ -4,7 +4,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: util-linux 2.10f\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:04+0200\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:05+0200\n"
|
||||
"PO-Revision-Date: 2000-04-04 21:52-0800\n"
|
||||
"Last-Translator: Beth Powell <bpowell@turbolinux.com>\n"
|
||||
"Language-Team: <support@turbolinux.com>\n"
|
||||
|
|
2
po/ja.po
2
po/ja.po
|
@ -7,7 +7,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: util-linux 2.11n\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:04+0200\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:05+0200\n"
|
||||
"PO-Revision-Date: 2001-12-11 22:43+0900\n"
|
||||
"Last-Translator: Daisuke Yamashita <yamad@mb.infoweb.ne.jp>\n"
|
||||
"Language-Team: Japanese <ja@li.org>\n"
|
||||
|
|
2
po/nl.po
2
po/nl.po
|
@ -19,7 +19,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: util-linux 2.12\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:04+0200\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:05+0200\n"
|
||||
"PO-Revision-Date: 2003-07-29 22:55+0100\n"
|
||||
"Last-Translator: Taco Witte <T.C.Witte@phys.uu.nl>\n"
|
||||
"Language-Team: Dutch <vertaling@nl.linux.org>\n"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: util-linux 2.11b\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:04+0200\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:05+0200\n"
|
||||
"PO-Revision-Date: 2001-05-24 16:03-03:00\n"
|
||||
"Last-Translator: Rodrigo Stulzer Lopes <rodrigo@conectiva.com.br>\n"
|
||||
"Language-Team: Brazilian Portuguese <ldp-br@bazar.conectiva.com.br>\n"
|
||||
|
|
2
po/sl.po
2
po/sl.po
|
@ -11,7 +11,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: util-linux 2.11y\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:04+0200\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:05+0200\n"
|
||||
"PO-Revision-Date: 2003-01-28 16:30+0100\n"
|
||||
"Last-Translator: Primo¾ Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>\n"
|
||||
"Language-Team: Slovenian <translation-team-sl@lists.sourceforge.net>\n"
|
||||
|
|
2
po/sv.po
2
po/sv.po
|
@ -10,7 +10,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: util-linux 2.12\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:04+0200\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:05+0200\n"
|
||||
"PO-Revision-Date: 2003-08-01 01:33+0200\n"
|
||||
"Last-Translator: Christian Rose <menthos@menthos.com>\n"
|
||||
"Language-Team: Swedish <sv@li.org>\n"
|
||||
|
|
2
po/tr.po
2
po/tr.po
|
@ -10,7 +10,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: util-linux 2.12\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:04+0200\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:05+0200\n"
|
||||
"PO-Revision-Date: 2003-08-03 13:18+0300\n"
|
||||
"Last-Translator: Nilgün Belma Bugüner <nilgun@superonline.com>\n"
|
||||
"Language-Team: Turkish <gnu-tr-u12a@lists.sourceforge.net>\n"
|
||||
|
|
2
po/uk.po
2
po/uk.po
|
@ -6,7 +6,7 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: util-linux 2.12\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:04+0200\n"
|
||||
"POT-Creation-Date: 2004-09-07 03:05+0200\n"
|
||||
"PO-Revision-Date: 2004-02-24 10:45+0200\n"
|
||||
"Last-Translator: Maxim V. Dziumanenko <mvd@mylinux.com.ua>\n"
|
||||
"Language-Team: Ukrainian <translation-team-uk@lists.sourceforge.net>\n"
|
||||
|
|
Loading…
Reference in New Issue