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
|
util-linux 2.12c,d
|
||||||
|
|
||||||
* mount.8: added recent ext2 mount options
|
* mount.8: added recent ext2 mount options
|
||||||
|
|
6
MCONFIG
6
MCONFIG
|
@ -7,6 +7,12 @@
|
||||||
# - set USE_TTY_GROUP=no
|
# - set USE_TTY_GROUP=no
|
||||||
# - define DESTDIR
|
# - 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 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
|
# Select for CPU i386 if the binaries must be able to run on an intel 386
|
||||||
# (by default i486 code is generated, see below)
|
# (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.
|
and installing it does no harm.
|
||||||
On the other hand, the stuff in login-utils defines initial boot-time
|
On the other hand, the stuff in login-utils defines initial boot-time
|
||||||
stuff, things that are done in different ways by different distributions.
|
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.
|
No RPMs are provided - get yours from your distributor.
|
||||||
|
|
|
@ -20,12 +20,15 @@
|
||||||
* Public License, version 2.
|
* Public License, version 2.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/ioctl.h>
|
#include <getopt.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
#include "nls.h"
|
#include "nls.h"
|
||||||
|
|
||||||
/* this has to match with the kernel structure */
|
/* this has to match with the kernel structure */
|
||||||
|
@ -37,6 +40,7 @@ typedef struct blkelv_ioctl_arg_s {
|
||||||
int max_bomb_segments;
|
int max_bomb_segments;
|
||||||
} blkelv_ioctl_arg_t;
|
} blkelv_ioctl_arg_t;
|
||||||
|
|
||||||
|
/* ioctls introduced in 2.2.16, removed in 2.5.58 */
|
||||||
#define BLKELVGET _IOR(0x12,106,size_t)
|
#define BLKELVGET _IOR(0x12,106,size_t)
|
||||||
#define BLKELVSET _IOW(0x12,107,size_t)
|
#define BLKELVSET _IOW(0x12,107,size_t)
|
||||||
|
|
||||||
|
@ -48,6 +52,8 @@ usage(void) {
|
||||||
" /dev/blkdev1 [/dev/blkdev2...]\n");
|
" /dev/blkdev1 [/dev/blkdev2...]\n");
|
||||||
fprintf(stderr, "\telvtune -h\n");
|
fprintf(stderr, "\telvtune -h\n");
|
||||||
fprintf(stderr, "\telvtune -v\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
|
static void
|
||||||
|
@ -55,6 +61,23 @@ version(void) {
|
||||||
fprintf(stderr, "elvtune (%s)\n", util_linux_version);
|
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
|
int
|
||||||
main(int argc, char * argv[]) {
|
main(int argc, char * argv[]) {
|
||||||
int read_value = 0xbeefbeef, write_value = 0xbeefbeef, bomb_value = 0xbeefbeef;
|
int read_value = 0xbeefbeef, write_value = 0xbeefbeef, bomb_value = 0xbeefbeef;
|
||||||
|
@ -110,8 +133,20 @@ main(int argc, char * argv[]) {
|
||||||
break;
|
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) {
|
if (ioctl(fd, BLKELVGET, &elevator) < 0) {
|
||||||
|
int errsv = errno;
|
||||||
perror("ioctl get");
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
103
fdisk/cfdisk.c
103
fdisk/cfdisk.c
|
@ -1488,55 +1488,68 @@ said_yes(char answer) {
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_partition_table_geometry(partition_table *bufp) {
|
get_partition_table_geometry(partition_table *bufp) {
|
||||||
struct partition *p;
|
struct partition *p;
|
||||||
int i,h,s,hh,ss;
|
int i,h,s,hh,ss;
|
||||||
int first = TRUE;
|
int first = TRUE;
|
||||||
int bad = FALSE;
|
int bad = FALSE;
|
||||||
|
|
||||||
if (bufp->p.magicflag[0] != PART_TABLE_FLAG0 ||
|
for (i=0; i<66; i++)
|
||||||
bufp->p.magicflag[1] != PART_TABLE_FLAG1) {
|
if (bufp->c.b[446+i])
|
||||||
/* Matthew Wilcox: slightly friendlier version of
|
goto nonz;
|
||||||
fatal(_("Bad signature on partition table"), 3);
|
|
||||||
*/
|
|
||||||
int cont;
|
|
||||||
mvaddstr(WARNING_START, 0,
|
|
||||||
_("No partition table or unknown signature on partition table"));
|
|
||||||
mvaddstr(WARNING_START+1, 0,
|
|
||||||
_("Do you wish to start with a zero table [y/N] ?"));
|
|
||||||
putchar(BELL);
|
|
||||||
refresh();
|
|
||||||
cont = getch();
|
|
||||||
if (cont == EOF || !said_yes(cont))
|
|
||||||
die_x(3);
|
|
||||||
zero_table = TRUE;
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Oskar Liljeblad suggested:
|
/* zero table */
|
||||||
Bad signature blah blah
|
if (!curses_started) {
|
||||||
If this is a brand new harddrive that has not been partitioned
|
fatal(_("No partition table.\n"), 3);
|
||||||
before, please run cfdisk -z.
|
return;
|
||||||
*/
|
} else {
|
||||||
}
|
mvaddstr(WARNING_START, 0,
|
||||||
|
_("No partition table. Starting with zero table."));
|
||||||
hh = ss = 0;
|
putchar(BELL);
|
||||||
for (i=0; i<4; i++) {
|
refresh();
|
||||||
p = &(bufp->p.part[i]);
|
zero_table = TRUE;
|
||||||
if (p->sys_ind != 0) {
|
return;
|
||||||
h = p->end_head + 1;
|
|
||||||
s = (p->end_sector & 077);
|
|
||||||
if (first) {
|
|
||||||
hh = h;
|
|
||||||
ss = s;
|
|
||||||
first = FALSE;
|
|
||||||
} else if (hh != h || ss != s)
|
|
||||||
bad = TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
nonz:
|
||||||
|
if (bufp->p.magicflag[0] != PART_TABLE_FLAG0 ||
|
||||||
|
bufp->p.magicflag[1] != PART_TABLE_FLAG1) {
|
||||||
|
if (!curses_started)
|
||||||
|
fatal(_("Bad signature on partition table"), 3);
|
||||||
|
|
||||||
if (!first && !bad) {
|
/* Matthew Wilcox */
|
||||||
pt_heads = hh;
|
mvaddstr(WARNING_START, 0,
|
||||||
pt_sectors = ss;
|
_("Unknown partition table type"));
|
||||||
}
|
mvaddstr(WARNING_START+1, 0,
|
||||||
|
_("Do you wish to start with a zero table [y/N] ?"));
|
||||||
|
putchar(BELL);
|
||||||
|
refresh();
|
||||||
|
{
|
||||||
|
int cont = getch();
|
||||||
|
if (cont == EOF || !said_yes(cont))
|
||||||
|
die_x(3);
|
||||||
|
}
|
||||||
|
zero_table = TRUE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hh = ss = 0;
|
||||||
|
for (i=0; i<4; i++) {
|
||||||
|
p = &(bufp->p.part[i]);
|
||||||
|
if (p->sys_ind != 0) {
|
||||||
|
h = p->end_head + 1;
|
||||||
|
s = (p->end_sector & 077);
|
||||||
|
if (first) {
|
||||||
|
hh = h;
|
||||||
|
ss = s;
|
||||||
|
first = FALSE;
|
||||||
|
} else if (hh != h || ss != s)
|
||||||
|
bad = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!first && !bad) {
|
||||||
|
pt_heads = hh;
|
||||||
|
pt_sectors = ss;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -129,6 +129,18 @@ fatal(char *s, ...) {
|
||||||
exit(1);
|
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
|
* A. About seeking
|
||||||
*/
|
*/
|
||||||
|
@ -143,8 +155,13 @@ fatal(char *s, ...) {
|
||||||
*
|
*
|
||||||
* Note: we use 512-byte sectors here, irrespective of the hardware ss.
|
* Note: we use 512-byte sectors here, irrespective of the hardware ss.
|
||||||
*/
|
*/
|
||||||
#if !defined (__alpha__) && !defined (__ia64__) && !defined (__x86_64__) && !defined (__s390x__)
|
#undef use_lseek
|
||||||
static
|
#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,
|
_syscall5(int, _llseek, unsigned int, fd, ulong, hi, ulong, lo,
|
||||||
loff_t *, res, unsigned int, wh);
|
loff_t *, res, unsigned int, wh);
|
||||||
#endif
|
#endif
|
||||||
|
@ -155,7 +172,7 @@ sseek(char *dev, unsigned int fd, unsigned long s) {
|
||||||
in = ((loff_t) s << 9);
|
in = ((loff_t) s << 9);
|
||||||
out = 1;
|
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) {
|
if (_llseek (fd, in>>32, in & 0xffffffff, &out, SEEK_SET) != 0) {
|
||||||
#else
|
#else
|
||||||
if ((out = lseek(fd, in, SEEK_SET)) != in) {
|
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 */
|
/* compute starting sector of a partition inside an extended one */
|
||||||
|
/* return 0 on failure */
|
||||||
/* ep is 0 or points to surrounding extended partition */
|
/* ep is 0 or points to surrounding extended partition */
|
||||||
static int
|
static int
|
||||||
compute_start_sect(struct part_desc *p, struct part_desc *ep) {
|
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;
|
delta = -inc;
|
||||||
else
|
else
|
||||||
delta = 0;
|
delta = 0;
|
||||||
|
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
p->start -= delta;
|
p->start -= delta;
|
||||||
p->size += delta;
|
p->size += delta;
|
||||||
|
|
|
@ -632,7 +632,18 @@ unmount_disks_ourselves(void)
|
||||||
}
|
}
|
||||||
n = 0;
|
n = 0;
|
||||||
while (n < 100 && (mnt = getmntent(mtab))) {
|
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);
|
mntlist[n++] = strdup(mnt->mnt_dir);
|
||||||
}
|
}
|
||||||
endmntent(mtab);
|
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''
|
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''
|
(do not mount when "mount -a" is given, e.g., at boot time), ``user''
|
||||||
(allow a user to mount), and ``owner''
|
(allow a user to mount), and ``owner''
|
||||||
(allow device owner to mount), and ``_netdev'' (device requires network
|
(allow device owner to mount), and ``comment''
|
||||||
to be available).
|
(e.g., for use by fstab-maintaining programs).
|
||||||
The ``owner'' and ``_netdev'' options are Linux-specific.
|
The ``owner'' and ``comment'' options are Linux-specific.
|
||||||
For more details, see
|
For more details, see
|
||||||
.BR mount (8).
|
.BR mount (8).
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "fstab.h"
|
#include "fstab.h"
|
||||||
#include "sundries.h" /* for xmalloc() etc */
|
#include "sundries.h" /* for xmalloc() etc */
|
||||||
#include "mount_blkid.h"
|
#include "mount_blkid.h"
|
||||||
|
#include "paths.h"
|
||||||
#include "nls.h"
|
#include "nls.h"
|
||||||
|
|
||||||
#define streq(s, t) (strcmp ((s), (t)) == 0)
|
#define streq(s, t) (strcmp ((s), (t)) == 0)
|
||||||
|
@ -94,12 +95,32 @@ fstab_head() {
|
||||||
return &fstab;
|
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
|
static void
|
||||||
read_mntentchn(mntFILE *mfp, const char *fnam, struct mntentchn *mc0) {
|
read_mntentchn(mntFILE *mfp, const char *fnam, struct mntentchn *mc0) {
|
||||||
struct mntentchn *mc = mc0;
|
struct mntentchn *mc = mc0;
|
||||||
struct mntent *mnt;
|
struct my_mntent *mnt;
|
||||||
|
|
||||||
while ((mnt = my_getmntent (mfp)) != NULL) {
|
while ((mnt = my_getmntent(mfp)) != NULL) {
|
||||||
if (!streq(mnt->mnt_type, MNTTYPE_IGNORE)) {
|
if (!streq(mnt->mnt_type, MNTTYPE_IGNORE)) {
|
||||||
mc->nxt = (struct mntentchn *) xmalloc(sizeof(*mc));
|
mc->nxt = (struct mntentchn *) xmalloc(sizeof(*mc));
|
||||||
mc->nxt->prev = mc;
|
mc->nxt->prev = mc;
|
||||||
|
@ -109,7 +130,7 @@ read_mntentchn(mntFILE *mfp, const char *fnam, struct mntentchn *mc0) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mc0->prev = mc;
|
mc0->prev = mc;
|
||||||
if (ferror (mfp->mntent_fp)) {
|
if (ferror(mfp->mntent_fp)) {
|
||||||
int errsv = errno;
|
int errsv = errno;
|
||||||
error(_("warning: error reading %s: %s"),
|
error(_("warning: error reading %s: %s"),
|
||||||
fnam, strerror (errsv));
|
fnam, strerror (errsv));
|
||||||
|
@ -239,7 +260,7 @@ is_mounted_once(const char *name) {
|
||||||
struct mntentchn *
|
struct mntentchn *
|
||||||
getmntoptfile (const char *file) {
|
getmntoptfile (const char *file) {
|
||||||
struct mntentchn *mc, *mc0;
|
struct mntentchn *mc, *mc0;
|
||||||
char *opts, *s;
|
const char *opts, *s;
|
||||||
int l;
|
int l;
|
||||||
|
|
||||||
if (!file)
|
if (!file)
|
||||||
|
@ -404,13 +425,14 @@ setlkw_timeout (int sig) {
|
||||||
|
|
||||||
/* Where does the link point to? Obvious choices are mtab and mtab~~.
|
/* 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
|
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 MOUNTED_LOCK "%d"
|
||||||
|
#define MOUNTLOCK_LINKTARGET_LTH (sizeof(MOUNTED_LOCK)+20)
|
||||||
|
|
||||||
void
|
void
|
||||||
lock_mtab (void) {
|
lock_mtab (void) {
|
||||||
int tries = 3;
|
int tries = 3;
|
||||||
char *linktargetfile;
|
char linktargetfile[MOUNTLOCK_LINKTARGET_LTH];
|
||||||
|
|
||||||
if (!signals_have_been_setup) {
|
if (!signals_have_been_setup) {
|
||||||
int sig = 0;
|
int sig = 0;
|
||||||
|
@ -431,9 +453,6 @@ lock_mtab (void) {
|
||||||
signals_have_been_setup = 1;
|
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 ());
|
sprintf(linktargetfile, MOUNTLOCK_LINKTARGET, getpid ());
|
||||||
|
|
||||||
/* Repeat until it was us who made the link */
|
/* Repeat until it was us who made the link */
|
||||||
|
@ -542,11 +561,11 @@ unlock_mtab (void) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
update_mtab (const char *dir, struct mntent *instead) {
|
update_mtab (const char *dir, struct my_mntent *instead) {
|
||||||
mntFILE *mfp, *mftmp;
|
mntFILE *mfp, *mftmp;
|
||||||
const char *fnam = MOUNTED;
|
const char *fnam = MOUNTED;
|
||||||
struct mntentchn mtabhead; /* dummy */
|
struct mntentchn mtabhead; /* dummy */
|
||||||
struct mntentchn *mc, *mc0, absent;
|
struct mntentchn *mc, *mc0, *absent = NULL;
|
||||||
|
|
||||||
if (mtab_does_not_exist() || mtab_is_a_symlink())
|
if (mtab_does_not_exist() || mtab_is_a_symlink())
|
||||||
return;
|
return;
|
||||||
|
@ -577,6 +596,7 @@ update_mtab (const char *dir, struct mntent *instead) {
|
||||||
if (mc && mc != mc0) {
|
if (mc && mc != mc0) {
|
||||||
mc->prev->nxt = mc->nxt;
|
mc->prev->nxt = mc->nxt;
|
||||||
mc->nxt->prev = mc->prev;
|
mc->nxt->prev = mc->prev;
|
||||||
|
free(mc);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* A remount */
|
/* A remount */
|
||||||
|
@ -584,12 +604,13 @@ update_mtab (const char *dir, struct mntent *instead) {
|
||||||
}
|
}
|
||||||
} else if (instead) {
|
} else if (instead) {
|
||||||
/* not found, add a new entry */
|
/* not found, add a new entry */
|
||||||
absent.m = *instead;
|
absent = xmalloc(sizeof(*absent));
|
||||||
absent.nxt = mc0;
|
absent->m = *instead;
|
||||||
absent.prev = mc0->prev;
|
absent->nxt = mc0;
|
||||||
mc0->prev = &absent;
|
absent->prev = mc0->prev;
|
||||||
|
mc0->prev = absent;
|
||||||
if (mc0->nxt == NULL)
|
if (mc0->nxt == NULL)
|
||||||
mc0->nxt = &absent;
|
mc0->nxt = absent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write chain to mtemp */
|
/* 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),
|
if (fchmod (fileno (mftmp->mntent_fp),
|
||||||
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
|
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
|
||||||
int errsv = errno;
|
int errsv = errno;
|
||||||
|
|
|
@ -1,14 +1,4 @@
|
||||||
#include <mntent.h>
|
#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
|
|
||||||
|
|
||||||
int mtab_is_writable(void);
|
int mtab_is_writable(void);
|
||||||
int mtab_does_not_exist(void);
|
int mtab_does_not_exist(void);
|
||||||
int mtab_is_a_symlink(void);
|
int mtab_is_a_symlink(void);
|
||||||
|
@ -16,7 +6,7 @@ int is_mounted_once(const char *name);
|
||||||
|
|
||||||
struct mntentchn {
|
struct mntentchn {
|
||||||
struct mntentchn *nxt, *prev;
|
struct mntentchn *nxt, *prev;
|
||||||
struct mntent m;
|
struct my_mntent m;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mntentchn *mtab_head (void);
|
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 *getfsuuidspec (const char *uuid);
|
||||||
struct mntentchn *getfsvolspec (const char *label);
|
struct mntentchn *getfsvolspec (const char *label);
|
||||||
|
|
||||||
#include <mntent.h>
|
|
||||||
void lock_mtab (void);
|
void lock_mtab (void);
|
||||||
void unlock_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.
|
* 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
|
int
|
||||||
get_label_uuid(const char *device, char **label, char *uuid) {
|
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 jfs_super_block jfssb;
|
||||||
struct ocfs_volume_header ovh; /* Oracle */
|
struct ocfs_volume_header ovh; /* Oracle */
|
||||||
struct ocfs_volume_label olbl;
|
struct ocfs_volume_label olbl;
|
||||||
|
struct ocfs2_super_block osb;
|
||||||
struct reiserfs_super_block reiserfssb;
|
struct reiserfs_super_block reiserfssb;
|
||||||
|
|
||||||
fd = open(device, O_RDONLY);
|
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));
|
memcpy(uuid, reiserfssb.s_uuid, sizeof (reiserfssb.s_uuid));
|
||||||
rv = 0;
|
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);
|
close(fd);
|
||||||
return rv;
|
return rv;
|
||||||
|
|
|
@ -236,35 +236,49 @@ struct ocfs_volume_label {
|
||||||
#define ocfslabellen(o) assemble2le(o.label_len)
|
#define ocfslabellen(o) assemble2le(o.label_len)
|
||||||
#define OCFS_MAGIC "OracleCFS"
|
#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 */
|
struct efs_volume_directory { /* size 16 */
|
||||||
char vd_name[8];
|
char vd_name[8];
|
||||||
char vd_lbn[4];
|
char vd_lbn[4];
|
||||||
char vd_nbytes[4];
|
char vd_nbytes[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct efs_partition_table { /* size 12 */
|
struct efs_partition_table { /* size 12 */
|
||||||
char pt_nblks[4];
|
char pt_nblks[4];
|
||||||
char pt_firstlbn[4];
|
char pt_firstlbn[4];
|
||||||
char pt_type[4];
|
char pt_type[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct efs_volume_header { /* size 512 */
|
struct efs_volume_header { /* size 512 */
|
||||||
char vh_magic[4];
|
char vh_magic[4];
|
||||||
short vh_rootpt;
|
short vh_rootpt;
|
||||||
short vh_swappt;
|
short vh_swappt;
|
||||||
char vh_bootfile[16];
|
char vh_bootfile[16];
|
||||||
char pad[48];
|
char pad[48];
|
||||||
struct efs_volume_directory vh_vd[15];
|
struct efs_volume_directory vh_vd[15];
|
||||||
struct efs_partition_table vh_pt[16];
|
struct efs_partition_table vh_pt[16];
|
||||||
int vh_csum;
|
int vh_csum;
|
||||||
int vh_fill;
|
int vh_fill;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct efs_super {
|
struct efs_super {
|
||||||
char fs_stuff[512+28];
|
char fs_stuff[512+28];
|
||||||
char fs_magic[4];
|
char fs_magic[4];
|
||||||
char fs_fname[6];
|
char fs_fname[6];
|
||||||
char fs_fpack[6];
|
char fs_fpack[6];
|
||||||
/* ... */
|
/* ... */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,7 @@ int
|
||||||
set_loop(const char *device, const char *file, unsigned long long offset,
|
set_loop(const char *device, const char *file, unsigned long long offset,
|
||||||
const char *encryption, int pfd, int *loopro) {
|
const char *encryption, int pfd, int *loopro) {
|
||||||
struct loop_info64 loopinfo64;
|
struct loop_info64 loopinfo64;
|
||||||
int fd, ffd, mode;
|
int fd, ffd, mode, i;
|
||||||
char *pass;
|
char *pass;
|
||||||
|
|
||||||
mode = (*loopro ? O_RDONLY : O_RDWR);
|
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:
|
case LO_CRYPT_XOR:
|
||||||
pass = getpass(_("Password: "));
|
pass = getpass(_("Password: "));
|
||||||
xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
|
xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
|
||||||
|
memset(pass, 0, strlen(pass));
|
||||||
loopinfo64.lo_encrypt_key_size =
|
loopinfo64.lo_encrypt_key_size =
|
||||||
strlen(loopinfo64.lo_encrypt_key);
|
strlen(loopinfo64.lo_encrypt_key);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pass = xgetpass(pfd, _("Password: "));
|
pass = xgetpass(pfd, _("Password: "));
|
||||||
xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
|
xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
|
||||||
|
memset(pass, 0, strlen(pass));
|
||||||
loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;
|
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);
|
close (ffd);
|
||||||
|
|
||||||
if (ioctl(fd, LOOP_SET_STATUS64, &loopinfo64) < 0) {
|
i = ioctl(fd, LOOP_SET_STATUS64, &loopinfo64);
|
||||||
|
if (i) {
|
||||||
struct loop_info loopinfo;
|
struct loop_info loopinfo;
|
||||||
int errsv = errno;
|
int errsv = errno;
|
||||||
|
|
||||||
errno = loop_info64_to_old(&loopinfo64, &loopinfo);
|
i = loop_info64_to_old(&loopinfo64, &loopinfo);
|
||||||
if (errno) {
|
if (i) {
|
||||||
errno = errsv;
|
errno = errsv;
|
||||||
perror("ioctl: LOOP_SET_STATUS64");
|
perror("ioctl: LOOP_SET_STATUS64");
|
||||||
goto fail;
|
} else {
|
||||||
}
|
i = ioctl(fd, LOOP_SET_STATUS, &loopinfo);
|
||||||
|
if (i)
|
||||||
if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) {
|
perror("ioctl: LOOP_SET_STATUS");
|
||||||
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);
|
close (fd);
|
||||||
|
|
||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
printf(_("set_loop(%s,%s,%llu): success\n"),
|
printf(_("set_loop(%s,%s,%llu): success\n"),
|
||||||
device, file, offset);
|
device, file, offset);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
|
||||||
(void) ioctl (fd, LOOP_CLR_FD, 0);
|
|
||||||
close (fd);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
|
static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
mangle(unsigned char *s) {
|
mangle(const unsigned char *s) {
|
||||||
char *ss, *sp;
|
char *ss, *sp;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ my_setmntent (const char *file, char *mode) {
|
||||||
mntFILE *mfp = xmalloc(sizeof(*mfp));
|
mntFILE *mfp = xmalloc(sizeof(*mfp));
|
||||||
mode_t old_umask = umask(077);
|
mode_t old_umask = umask(077);
|
||||||
|
|
||||||
mfp->mntent_fp = fopen (file, mode);
|
mfp->mntent_fp = fopen(file, mode);
|
||||||
umask(old_umask);
|
umask(old_umask);
|
||||||
mfp->mntent_file = xstrdup(file);
|
mfp->mntent_file = xstrdup(file);
|
||||||
mfp->mntent_errs = (mfp->mntent_fp == NULL);
|
mfp->mntent_errs = (mfp->mntent_fp == NULL);
|
||||||
|
@ -118,9 +118,8 @@ my_endmntent (mntFILE *mfp) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
my_addmntent (mntFILE *mfp, struct mntent *mnt) {
|
my_addmntent (mntFILE *mfp, struct my_mntent *mnt) {
|
||||||
char *m1, *m2, *m3, *m4;
|
char *m1, *m2, *m3, *m4;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
@ -132,22 +131,21 @@ my_addmntent (mntFILE *mfp, struct mntent *mnt) {
|
||||||
m3 = mangle(mnt->mnt_type);
|
m3 = mangle(mnt->mnt_type);
|
||||||
m4 = mangle(mnt->mnt_opts);
|
m4 = mangle(mnt->mnt_opts);
|
||||||
|
|
||||||
res = ((fprintf (mfp->mntent_fp, "%s %s %s %s %d %d\n",
|
res = fprintf (mfp->mntent_fp, "%s %s %s %s %d %d\n",
|
||||||
m1, m2, m3, m4, mnt->mnt_freq, mnt->mnt_passno)
|
m1, m2, m3, m4, mnt->mnt_freq, mnt->mnt_passno);
|
||||||
< 0) ? 1 : 0);
|
|
||||||
|
|
||||||
free(m1);
|
free(m1);
|
||||||
free(m2);
|
free(m2);
|
||||||
free(m3);
|
free(m3);
|
||||||
free(m4);
|
free(m4);
|
||||||
return res;
|
return (res < 0) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read the next entry from the file fp. Stop reading at an incorrect entry. */
|
/* Read the next entry from the file fp. Stop reading at an incorrect entry. */
|
||||||
struct mntent *
|
struct my_mntent *
|
||||||
my_getmntent (mntFILE *mfp) {
|
my_getmntent (mntFILE *mfp) {
|
||||||
static char buf[4096];
|
static char buf[4096];
|
||||||
static struct mntent me;
|
static struct my_mntent me;
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
again:
|
again:
|
||||||
|
@ -193,7 +191,7 @@ my_getmntent (mntFILE *mfp) {
|
||||||
s = skip_nonspaces(s);
|
s = skip_nonspaces(s);
|
||||||
s = skip_spaces(s);
|
s = skip_spaces(s);
|
||||||
|
|
||||||
if(isdigit(*s)) {
|
if (isdigit(*s)) {
|
||||||
me.mnt_freq = atoi(s);
|
me.mnt_freq = atoi(s);
|
||||||
while(isdigit(*s)) s++;
|
while(isdigit(*s)) s++;
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -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
|
#define ERR_MAX 5
|
||||||
|
|
||||||
|
@ -12,5 +22,7 @@ typedef struct mntFILEstruct {
|
||||||
|
|
||||||
mntFILE *my_setmntent (const char *file, char *mode);
|
mntFILE *my_setmntent (const char *file, char *mode);
|
||||||
void my_endmntent (mntFILE *mfp);
|
void my_endmntent (mntFILE *mfp);
|
||||||
int my_addmntent (mntFILE *mfp, struct mntent *mnt);
|
int my_addmntent (mntFILE *mfp, struct my_mntent *mnt);
|
||||||
struct mntent *my_getmntent (mntFILE *mfp);
|
struct my_mntent *my_getmntent (mntFILE *mfp);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -109,6 +109,7 @@ file hierarchy somewhere else. The call is
|
||||||
.B "mount --bind olddir newdir"
|
.B "mount --bind olddir newdir"
|
||||||
.RE
|
.RE
|
||||||
After this call the same contents is accessible in two places.
|
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
|
This call attaches only (part of) a single filesystem, not possible
|
||||||
submounts. The entire file hierarchy including submounts is attached
|
submounts. The entire file hierarchy including submounts is attached
|
||||||
|
@ -120,7 +121,7 @@ a second place using
|
||||||
.\" available since Linux 2.4.11.
|
.\" available since Linux 2.4.11.
|
||||||
The mount options are not changed.
|
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
|
to another place. The call is
|
||||||
.RS
|
.RS
|
||||||
.br
|
.br
|
||||||
|
@ -242,6 +243,8 @@ option below). It is possible to replace
|
||||||
.I /etc/mtab
|
.I /etc/mtab
|
||||||
by a symbolic link to
|
by a symbolic link to
|
||||||
.IR /proc/mounts ,
|
.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
|
but some information is lost that way, and in particular
|
||||||
working with the loop device will be less convenient,
|
working with the loop device will be less convenient,
|
||||||
and using the "user" option will fail.
|
and using the "user" option will fail.
|
||||||
|
@ -421,35 +424,15 @@ program have different calling conventions,
|
||||||
.I /sbin/mount.smbfs
|
.I /sbin/mount.smbfs
|
||||||
may have to be a shell script that sets up the desired call.
|
may have to be a shell script that sets up the desired call.
|
||||||
|
|
||||||
The type
|
If no
|
||||||
.I iso9660
|
|
||||||
is the default. If no
|
|
||||||
.B \-t
|
.B \-t
|
||||||
option is given, or if the
|
option is given, or if the
|
||||||
.B auto
|
.B auto
|
||||||
type is specified, the superblock is probed for the filesystem type
|
type is specified, mount will try to guess the desired type.
|
||||||
.RI ( adfs ,
|
If mount was compiled with the blkid library, the guessing is done
|
||||||
.IR bfs ,
|
by this library. Otherwise, mount guesses itself by probing the
|
||||||
.IR cramfs ,
|
superblock; if that does not turn up anything that looks familiar,
|
||||||
.IR ext ,
|
mount will try to read the file
|
||||||
.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
|
|
||||||
.IR /etc/filesystems ,
|
.IR /etc/filesystems ,
|
||||||
or, if that does not exist,
|
or, if that does not exist,
|
||||||
.IR /proc/filesystems .
|
.IR /proc/filesystems .
|
||||||
|
@ -470,8 +453,8 @@ The
|
||||||
type may be useful for user-mounted floppies.
|
type may be useful for user-mounted floppies.
|
||||||
Creating a file
|
Creating a file
|
||||||
.I /etc/filesystems
|
.I /etc/filesystems
|
||||||
can be useful to change the probe order (e.g., to try vfat before msdos)
|
can be useful to change the probe order (e.g., to try vfat before msdos
|
||||||
or if you use a kernel module autoloader.
|
or ext3 before ext2) or if you use a kernel module autoloader.
|
||||||
Warning: the probing uses a heuristic (the presence of appropriate `magic'),
|
Warning: the probing uses a heuristic (the presence of appropriate `magic'),
|
||||||
and could recognize the wrong filesystem type, possibly with catastrophic
|
and could recognize the wrong filesystem type, possibly with catastrophic
|
||||||
consequences. If your data is valuable, don't ask
|
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.
|
system.
|
||||||
.TP
|
.TP
|
||||||
.B noexec
|
.B noexec
|
||||||
Do not allow execution of any binaries on the mounted file system.
|
Do not allow direct execution of any binaries on the mounted file system.
|
||||||
This option might be useful for a server that has file systems containing
|
(Until recently it was possible to run binaries anyway using a command like
|
||||||
binaries for architectures other than its own.
|
/lib/ld*.so /mnt/binary. This trick fails since Linux 2.4.25 / 2.6.0.)
|
||||||
.TP
|
.TP
|
||||||
.B nosuid
|
.B nosuid
|
||||||
Do not allow set-user-identifier or set-group-identifier bits to take
|
Do not allow set-user-identifier or set-group-identifier bits to take
|
||||||
|
|
453
mount/mount.c
453
mount/mount.c
|
@ -2,43 +2,7 @@
|
||||||
* A mount(8) for Linux 0.99.
|
* A mount(8) for Linux 0.99.
|
||||||
* mount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
|
* mount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
|
||||||
*
|
*
|
||||||
* Wed Sep 14 22:43:00 1994: Mitchum DSouza
|
* Modifications by many people. Distributed under GPL.
|
||||||
* (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
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
@ -69,6 +33,7 @@
|
||||||
#include "mount_guess_fstype.h"
|
#include "mount_guess_fstype.h"
|
||||||
#include "mount_by_label.h"
|
#include "mount_by_label.h"
|
||||||
#include "getusername.h"
|
#include "getusername.h"
|
||||||
|
#include "paths.h"
|
||||||
#include "env.h"
|
#include "env.h"
|
||||||
#include "nls.h"
|
#include "nls.h"
|
||||||
|
|
||||||
|
@ -131,11 +96,11 @@ struct opt_map {
|
||||||
#define MS_USERS 0x40000000
|
#define MS_USERS 0x40000000
|
||||||
#define MS_USER 0x20000000
|
#define MS_USER 0x20000000
|
||||||
#define MS_OWNER 0x10000000
|
#define MS_OWNER 0x10000000
|
||||||
#define MS_NETDEV 0x00020000
|
#define MS_COMMENT 0x00020000
|
||||||
#define MS_LOOP 0x00010000
|
#define MS_LOOP 0x00010000
|
||||||
|
|
||||||
/* Options that we keep the mount system call from seeing. */
|
/* 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. */
|
/* Options that we keep from appearing in the options field in the mtab. */
|
||||||
#define MS_NOMTAB (MS_REMOUNT|MS_NOAUTO|MS_USERS|MS_USER)
|
#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 */
|
{ "nouser", 0, 1, MS_USER }, /* Forbid ordinary user to mount */
|
||||||
{ "owner", 0, 0, MS_OWNER }, /* Let the owner of the device mount */
|
{ "owner", 0, 0, MS_OWNER }, /* Let the owner of the device mount */
|
||||||
{ "noowner", 0, 1, MS_OWNER }, /* Device owner has no special privs */
|
{ "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 */
|
/* add new options here */
|
||||||
#ifdef MS_NOSUB
|
#ifdef MS_NOSUB
|
||||||
{ "sub", 0, 1, MS_NOSUB }, /* allow submounts */
|
{ "sub", 0, 1, MS_NOSUB }, /* allow submounts */
|
||||||
|
@ -196,19 +163,20 @@ static const struct opt_map opt_map[] = {
|
||||||
{ NULL, 0, 0, 0 }
|
{ NULL, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption,
|
static const char *opt_loopdev, *opt_vfstype, *opt_offset, *opt_encryption,
|
||||||
*opt_speed;
|
*opt_speed, *opt_comment;
|
||||||
|
|
||||||
static struct string_opt_map {
|
static struct string_opt_map {
|
||||||
char *tag;
|
char *tag;
|
||||||
int skip;
|
int skip;
|
||||||
char **valptr;
|
const char **valptr;
|
||||||
} string_opt_map[] = {
|
} string_opt_map[] = {
|
||||||
{ "loop=", 0, &opt_loopdev },
|
{ "loop=", 0, &opt_loopdev },
|
||||||
{ "vfs=", 1, &opt_vfstype },
|
{ "vfs=", 1, &opt_vfstype },
|
||||||
{ "offset=", 0, &opt_offset },
|
{ "offset=", 0, &opt_offset },
|
||||||
{ "encryption=", 0, &opt_encryption },
|
{ "encryption=", 0, &opt_encryption },
|
||||||
{ "speed=", 0, &opt_speed },
|
{ "speed=", 0, &opt_speed },
|
||||||
|
{ "comment=", 1, &opt_comment },
|
||||||
{ NULL, 0, NULL }
|
{ NULL, 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -239,23 +207,23 @@ int mount_quiet=0;
|
||||||
|
|
||||||
/* Report on a single mount. */
|
/* Report on a single mount. */
|
||||||
static void
|
static void
|
||||||
print_one (const struct mntent *me) {
|
print_one (const struct my_mntent *me) {
|
||||||
if (mount_quiet)
|
if (mount_quiet)
|
||||||
return;
|
return;
|
||||||
printf ("%s on %s", me->mnt_fsname, me->mnt_dir);
|
printf ("%s on %s", me->mnt_fsname, me->mnt_dir);
|
||||||
if (me->mnt_type != NULL && *(me->mnt_type) != '\0')
|
if (me->mnt_type != NULL && *(me->mnt_type) != '\0')
|
||||||
printf (" type %s", me->mnt_type);
|
printf (" type %s", me->mnt_type);
|
||||||
if (me->mnt_opts != NULL)
|
if (me->mnt_opts != NULL)
|
||||||
printf (" (%s)", me->mnt_opts);
|
printf (" (%s)", me->mnt_opts);
|
||||||
if (list_with_volumelabel) {
|
if (list_with_volumelabel) {
|
||||||
const char *label;
|
const char *label;
|
||||||
label = mount_get_volume_label_by_spec(me->mnt_fsname);
|
label = mount_get_volume_label_by_spec(me->mnt_fsname);
|
||||||
if (label) {
|
if (label) {
|
||||||
printf (" [%s]", label);
|
printf (" [%s]", label);
|
||||||
/* free(label); */
|
/* free(label); */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Report on everything in mtab (of the specified types if any). */
|
/* Report on everything in mtab (of the specified types if any). */
|
||||||
|
@ -271,6 +239,11 @@ print_all (char *types) {
|
||||||
exit (0);
|
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.
|
* 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
|
/* 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 */
|
gets the standard options (indicated by bits) and extra_opts all the rest */
|
||||||
static void
|
static void
|
||||||
parse_opts (char *opts, int *flags, char **extra_opts) {
|
parse_opts (const char *options, int *flags, char **extra_opts) {
|
||||||
char *opt;
|
|
||||||
|
|
||||||
*flags = 0;
|
*flags = 0;
|
||||||
*extra_opts = NULL;
|
*extra_opts = NULL;
|
||||||
|
|
||||||
clear_string_opts();
|
clear_string_opts();
|
||||||
|
|
||||||
if (opts != NULL) {
|
if (options != NULL) {
|
||||||
|
char *opts = xstrdup(options);
|
||||||
|
char *opt;
|
||||||
|
|
||||||
*extra_opts = xmalloc (strlen (opts) + 1);
|
*extra_opts = xmalloc (strlen (opts) + 1);
|
||||||
**extra_opts = '\0';
|
**extra_opts = '\0';
|
||||||
|
|
||||||
for (opt = strtok (opts, ","); opt; opt = strtok (NULL, ","))
|
for (opt = strtok (opts, ","); opt; opt = strtok (NULL, ","))
|
||||||
if (!parse_string_opt (opt))
|
if (!parse_string_opt (opt))
|
||||||
parse_opt (opt, flags, *extra_opts);
|
parse_opt (opt, flags, *extra_opts);
|
||||||
|
|
||||||
|
free(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (readonly)
|
if (readonly)
|
||||||
|
@ -363,7 +339,7 @@ fix_opts_string (int flags, const char *extra_opts, const char *user) {
|
||||||
const struct string_opt_map *m;
|
const struct string_opt_map *m;
|
||||||
char *new_opts;
|
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++) {
|
for (om = opt_map; om->opt != NULL; om++) {
|
||||||
if (om->skip)
|
if (om->skip)
|
||||||
continue;
|
continue;
|
||||||
|
@ -388,63 +364,66 @@ fix_opts_string (int flags, const char *extra_opts, const char *user) {
|
||||||
|
|
||||||
static int
|
static int
|
||||||
already (const char *spec, const char *node) {
|
already (const char *spec, const char *node) {
|
||||||
struct mntentchn *mc;
|
struct mntentchn *mc;
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
|
|
||||||
if ((mc = getmntfile(node)) != NULL)
|
if ((mc = getmntfile(node)) != NULL)
|
||||||
error (_("mount: according to mtab, %s is already mounted on %s"),
|
error (_("mount: according to mtab, "
|
||||||
mc->m.mnt_fsname, node);
|
"%s is already mounted on %s"),
|
||||||
else if (spec && strcmp (spec, "none") &&
|
mc->m.mnt_fsname, node);
|
||||||
(mc = getmntfile(spec)) != NULL)
|
else if (spec && strcmp (spec, "none") &&
|
||||||
error (_("mount: according to mtab, %s is mounted on %s"),
|
(mc = getmntfile(spec)) != NULL)
|
||||||
spec, mc->m.mnt_dir);
|
error (_("mount: according to mtab, %s is mounted on %s"),
|
||||||
else
|
spec, mc->m.mnt_dir);
|
||||||
ret = 0;
|
else
|
||||||
return ret;
|
ret = 0;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create mtab with a root entry. */
|
/* Create mtab with a root entry. */
|
||||||
static void
|
static void
|
||||||
create_mtab (void) {
|
create_mtab (void) {
|
||||||
struct mntentchn *fstab;
|
struct mntentchn *fstab;
|
||||||
struct mntent mnt;
|
struct my_mntent mnt;
|
||||||
int flags;
|
int flags;
|
||||||
char *extra_opts;
|
mntFILE *mfp;
|
||||||
mntFILE *mfp;
|
|
||||||
|
|
||||||
lock_mtab();
|
lock_mtab();
|
||||||
|
|
||||||
mfp = my_setmntent (MOUNTED, "a+");
|
mfp = my_setmntent (MOUNTED, "a+");
|
||||||
if (mfp == NULL || mfp->mntent_fp == NULL) {
|
if (mfp == NULL || mfp->mntent_fp == NULL) {
|
||||||
int errsv = errno;
|
int errsv = errno;
|
||||||
die (EX_FILEIO, _("mount: can't open %s for writing: %s"),
|
die (EX_FILEIO, _("mount: can't open %s for writing: %s"),
|
||||||
MOUNTED, strerror (errsv));
|
MOUNTED, strerror (errsv));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the root entry by looking it up in fstab */
|
/* Find the root entry by looking it up in fstab */
|
||||||
if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root"))) {
|
if ((fstab = getfsfile ("/")) || (fstab = getfsfile ("root"))) {
|
||||||
parse_opts (xstrdup (fstab->m.mnt_opts), &flags, &extra_opts);
|
char *extra_opts;
|
||||||
mnt.mnt_dir = "/";
|
parse_opts (fstab->m.mnt_opts, &flags, &extra_opts);
|
||||||
mnt.mnt_fsname = canonicalize (fstab->m.mnt_fsname);
|
mnt.mnt_dir = "/";
|
||||||
mnt.mnt_type = fstab->m.mnt_type;
|
mnt.mnt_fsname = canonicalize (fstab->m.mnt_fsname);
|
||||||
mnt.mnt_opts = fix_opts_string (flags, extra_opts, NULL);
|
mnt.mnt_type = fstab->m.mnt_type;
|
||||||
mnt.mnt_freq = mnt.mnt_passno = 0;
|
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) {
|
if (my_addmntent (mfp, &mnt) == 1) {
|
||||||
int errsv = errno;
|
int errsv = errno;
|
||||||
die (EX_FILEIO, _("mount: error writing %s: %s"),
|
die (EX_FILEIO, _("mount: error writing %s: %s"),
|
||||||
MOUNTED, strerror (errsv));
|
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) {
|
if (errno != EROFS) {
|
||||||
int errsv = errno;
|
int errsv = errno;
|
||||||
die (EX_FILEIO, _("mount: error changing mode of %s: %s"),
|
die (EX_FILEIO,
|
||||||
MOUNTED, strerror (errsv));
|
_("mount: error changing mode of %s: %s"),
|
||||||
}
|
MOUNTED, strerror (errsv));
|
||||||
my_endmntent (mfp);
|
}
|
||||||
|
my_endmntent (mfp);
|
||||||
|
|
||||||
unlock_mtab();
|
unlock_mtab();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* count successful mount system calls */
|
/* count successful mount system calls */
|
||||||
|
@ -477,8 +456,8 @@ do_mount_syscall (struct mountargs *args) {
|
||||||
* on return types is filled with the type used.
|
* on return types is filled with the type used.
|
||||||
*/
|
*/
|
||||||
static int
|
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) {
|
int flags, char *mount_opts) {
|
||||||
struct mountargs args = { spec, node, NULL, flags & ~MS_NOSYS, mount_opts };
|
struct mountargs args = { spec, node, NULL, flags & ~MS_NOSYS, mount_opts };
|
||||||
|
|
||||||
if (*types && strcasecmp (*types, "auto") == 0)
|
if (*types && strcasecmp (*types, "auto") == 0)
|
||||||
|
@ -526,12 +505,12 @@ guess_fstype_and_mount (char *spec, char *node, char **types,
|
||||||
* Die if the user is not allowed to do this.
|
* Die if the user is not allowed to do this.
|
||||||
*/
|
*/
|
||||||
static void
|
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) {
|
if (suid) {
|
||||||
/* RedHat patch: allow owners to mount when fstab contains
|
/* RedHat patch: allow owners to mount when fstab contains
|
||||||
the owner option. Note that this should never be used
|
the owner option. Note that this should never be used
|
||||||
in a high security environment, but may be useful to give
|
in a high security environment, but may be useful to give
|
||||||
people at the console the possibility of mounting a floppy. */
|
people at the console the possibility of mounting a floppy. */
|
||||||
if (*flags & MS_OWNER) {
|
if (*flags & MS_OWNER) {
|
||||||
if (!strncmp(spec, "/dev/", 5)) {
|
if (!strncmp(spec, "/dev/", 5)) {
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
@ -545,14 +524,14 @@ suid_check(char *spec, char *node, int *flags, char **user) {
|
||||||
/* James Kehl <mkehl@gil.com.au> came with a similar patch:
|
/* James Kehl <mkehl@gil.com.au> came with a similar patch:
|
||||||
allow an arbitrary user to mount when he is the owner of
|
allow an arbitrary user to mount when he is the owner of
|
||||||
the mount-point and has write-access to the device.
|
the mount-point and has write-access to the device.
|
||||||
This is even less secure. Let me skip it for the time being;
|
This is even less secure. Let me skip it for the time being;
|
||||||
there should be an explicit fstab line allowing such things. */
|
there should be an explicit fstab line allowing such things. */
|
||||||
|
|
||||||
if (!(*flags & (MS_USER | MS_USERS))) {
|
if (!(*flags & (MS_USER | MS_USERS))) {
|
||||||
if (already (spec, node))
|
if (already (spec, node))
|
||||||
die (EX_USAGE, _("mount failed"));
|
die (EX_USAGE, _("mount failed"));
|
||||||
else
|
else
|
||||||
die (EX_USAGE, _("mount: only root can mount %s on %s"), spec, node);
|
die (EX_USAGE, _("mount: only root can mount %s on %s"), spec, node);
|
||||||
}
|
}
|
||||||
if (*flags & MS_USER)
|
if (*flags & MS_USER)
|
||||||
*user = getusername();
|
*user = getusername();
|
||||||
|
@ -563,8 +542,8 @@ suid_check(char *spec, char *node, int *flags, char **user) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
loop_check(char **spec, char **type, int *flags,
|
loop_check(const char **spec, const char **type, int *flags,
|
||||||
int *loop, char **loopdev, char **loopfile) {
|
int *loop, const char **loopdev, const char **loopfile) {
|
||||||
int looptype;
|
int looptype;
|
||||||
unsigned long long offset;
|
unsigned long long offset;
|
||||||
|
|
||||||
|
@ -627,45 +606,47 @@ loop_check(char **spec, char **type, int *flags,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_mtab_entry(char *spec, char *node, char *type, char *opts,
|
update_mtab_entry(const char *spec, const char *node, const char *type,
|
||||||
int flags, int freq, int pass) {
|
const char *opts, int flags, int freq, int pass) {
|
||||||
struct mntent mnt;
|
struct my_mntent mnt;
|
||||||
|
|
||||||
mnt.mnt_fsname = canonicalize (spec);
|
mnt.mnt_fsname = canonicalize (spec);
|
||||||
mnt.mnt_dir = canonicalize (node);
|
mnt.mnt_dir = canonicalize (node);
|
||||||
mnt.mnt_type = type;
|
mnt.mnt_type = type;
|
||||||
mnt.mnt_opts = opts;
|
mnt.mnt_opts = opts;
|
||||||
mnt.mnt_freq = freq;
|
mnt.mnt_freq = freq;
|
||||||
mnt.mnt_passno = pass;
|
mnt.mnt_passno = pass;
|
||||||
|
|
||||||
/* We get chatty now rather than after the update to mtab since the
|
/* We get chatty now rather than after the update to mtab since the
|
||||||
mount succeeded, even if the write to /etc/mtab should fail. */
|
mount succeeded, even if the write to /etc/mtab should fail. */
|
||||||
if (verbose)
|
if (verbose)
|
||||||
print_one (&mnt);
|
print_one (&mnt);
|
||||||
|
|
||||||
if (!nomtab && mtab_is_writable()) {
|
if (!nomtab && mtab_is_writable()) {
|
||||||
if (flags & MS_REMOUNT)
|
if (flags & MS_REMOUNT)
|
||||||
update_mtab (mnt.mnt_dir, &mnt);
|
update_mtab (mnt.mnt_dir, &mnt);
|
||||||
else {
|
else {
|
||||||
mntFILE *mfp;
|
mntFILE *mfp;
|
||||||
|
|
||||||
lock_mtab();
|
lock_mtab();
|
||||||
mfp = my_setmntent(MOUNTED, "a+");
|
mfp = my_setmntent(MOUNTED, "a+");
|
||||||
if (mfp == NULL || mfp->mntent_fp == NULL) {
|
if (mfp == NULL || mfp->mntent_fp == NULL) {
|
||||||
int errsv = errno;
|
int errsv = errno;
|
||||||
error(_("mount: can't open %s: %s"), MOUNTED,
|
error(_("mount: can't open %s: %s"), MOUNTED,
|
||||||
strerror (errsv));
|
strerror (errsv));
|
||||||
} else {
|
} else {
|
||||||
if ((my_addmntent (mfp, &mnt)) == 1) {
|
if ((my_addmntent (mfp, &mnt)) == 1) {
|
||||||
int errsv = errno;
|
int errsv = errno;
|
||||||
error(_("mount: error writing %s: %s"), MOUNTED,
|
error(_("mount: error writing %s: %s"),
|
||||||
strerror (errsv));
|
MOUNTED, strerror (errsv));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
my_endmntent(mfp);
|
||||||
|
unlock_mtab();
|
||||||
}
|
}
|
||||||
my_endmntent(mfp);
|
|
||||||
}
|
|
||||||
unlock_mtab();
|
|
||||||
}
|
}
|
||||||
}
|
my_free(mnt.mnt_fsname);
|
||||||
|
my_free(mnt.mnt_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -677,20 +658,21 @@ set_pfd(char *s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cdrom_setspeed(char *spec) {
|
cdrom_setspeed(const char *spec) {
|
||||||
#define CDROM_SELECT_SPEED 0x5322 /* Set the CD-ROM speed */
|
#define CDROM_SELECT_SPEED 0x5322 /* Set the CD-ROM speed */
|
||||||
if (opt_speed) {
|
if (opt_speed) {
|
||||||
int cdrom;
|
int cdrom;
|
||||||
int speed = atoi(opt_speed);
|
int speed = atoi(opt_speed);
|
||||||
|
|
||||||
if ((cdrom = open(spec, O_RDONLY | O_NONBLOCK)) < 0)
|
if ((cdrom = open(spec, O_RDONLY | O_NONBLOCK)) < 0)
|
||||||
die(EX_FAIL, _("mount: cannot open %s for setting speed"),
|
die(EX_FAIL,
|
||||||
spec);
|
_("mount: cannot open %s for setting speed"),
|
||||||
if (ioctl(cdrom, CDROM_SELECT_SPEED, speed) < 0)
|
spec);
|
||||||
die(EX_FAIL, _("mount: cannot set speed: %s"),
|
if (ioctl(cdrom, CDROM_SELECT_SPEED, speed) < 0)
|
||||||
strerror(errno));
|
die(EX_FAIL, _("mount: cannot set speed: %s"),
|
||||||
close(cdrom);
|
strerror(errno));
|
||||||
}
|
close(cdrom);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -700,8 +682,8 @@ cdrom_setspeed(char *spec) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
check_special_mountprog(char *spec, char *node, char *type, int flags,
|
check_special_mountprog(const char *spec, const char *node, const char *type,
|
||||||
char *extra_opts, int *status) {
|
int flags, char *extra_opts, int *status) {
|
||||||
char mountprog[120];
|
char mountprog[120];
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
int res;
|
int res;
|
||||||
|
@ -714,7 +696,7 @@ check_special_mountprog(char *spec, char *node, char *type, int flags,
|
||||||
if (stat(mountprog, &statbuf) == 0) {
|
if (stat(mountprog, &statbuf) == 0) {
|
||||||
res = fork();
|
res = fork();
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
char *oo, *mountargs[10];
|
const char *oo, *mountargs[10];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
setuid(getuid());
|
setuid(getuid());
|
||||||
|
@ -732,7 +714,7 @@ check_special_mountprog(char *spec, char *node, char *type, int flags,
|
||||||
mountargs[i++] = oo;
|
mountargs[i++] = oo;
|
||||||
}
|
}
|
||||||
mountargs[i] = NULL;
|
mountargs[i] = NULL;
|
||||||
execv(mountprog, mountargs);
|
execv(mountprog, (char **) mountargs);
|
||||||
exit(1); /* exec failed */
|
exit(1); /* exec failed */
|
||||||
} else if (res != -1) {
|
} else if (res != -1) {
|
||||||
int st;
|
int st;
|
||||||
|
@ -758,32 +740,35 @@ check_special_mountprog(char *spec, char *node, char *type, int flags,
|
||||||
* return status from wait
|
* return status from wait
|
||||||
*/
|
*/
|
||||||
static int
|
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) {
|
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 mnt5_res = 0; /* only for gcc */
|
||||||
int mnt_err;
|
int mnt_err;
|
||||||
int flags;
|
int flags;
|
||||||
char *extra_opts; /* written in mtab */
|
char *extra_opts; /* written in mtab */
|
||||||
char *mount_opts; /* actually used on system call */
|
char *mount_opts; /* actually used on system call */
|
||||||
const char *opts;
|
const char *opts, *spec, *node, *types;
|
||||||
char *spec, *node, *types;
|
|
||||||
char *user = 0;
|
char *user = 0;
|
||||||
int loop = 0;
|
int loop = 0;
|
||||||
char *loopdev = 0, *loopfile = 0;
|
const char *loopdev = 0, *loopfile = 0;
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
int nfs_mount_version = 0; /* any version */
|
int nfs_mount_version = 0; /* any version */
|
||||||
|
|
||||||
spec = xstrdup(spec0);
|
/* copies for freeing on exit */
|
||||||
node = xstrdup(node0);
|
const char *opts1, *spec1, *node1, *types1, *extra_opts1;
|
||||||
types = xstrdup(types0);
|
|
||||||
opts = xstrdup(opts0);
|
|
||||||
|
|
||||||
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 */
|
/* quietly succeed for fstab entries that don't get mounted automatically */
|
||||||
if (mount_all && (flags & MS_NOAUTO))
|
if (mount_all && (flags & MS_NOAUTO))
|
||||||
return 0;
|
goto out;
|
||||||
|
|
||||||
suid_check(spec, node, &flags, &user);
|
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);
|
res = loop_check(&spec, &types, &flags, &loop, &loopdev, &loopfile);
|
||||||
if (res)
|
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.
|
* For the moment these types are ncpfs and smbfs. Maybe also vxfs.
|
||||||
* All such special things must occur isolated in the types string.
|
* All such special things must occur isolated in the types string.
|
||||||
*/
|
*/
|
||||||
if (check_special_mountprog (spec, node, types, flags, extra_opts, &status))
|
if (check_special_mountprog(spec, node, types, flags, extra_opts, &status)) {
|
||||||
return status;
|
res = status;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Also nfs requires a separate program, but it is built in.
|
* Also nfs requires a separate program, but it is built in.
|
||||||
|
@ -819,11 +806,13 @@ try_mount_one (const char *spec0, const char *node0, char *types0,
|
||||||
retry_nfs:
|
retry_nfs:
|
||||||
mnt_err = nfsmount (spec, node, &flags, &extra_opts, &mount_opts,
|
mnt_err = nfsmount (spec, node, &flags, &extra_opts, &mount_opts,
|
||||||
&nfs_mount_version, bg);
|
&nfs_mount_version, bg);
|
||||||
if (mnt_err)
|
if (mnt_err) {
|
||||||
return mnt_err;
|
res = mnt_err;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
die (EX_SOFTWARE, _("mount: this version was compiled "
|
die (EX_SOFTWARE, _("mount: this version was compiled "
|
||||||
"without support for the type `nfs'"));
|
"without support for the type `nfs'"));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -847,7 +836,8 @@ retry_nfs:
|
||||||
pass);
|
pass);
|
||||||
|
|
||||||
block_signals (SIG_UNBLOCK);
|
block_signals (SIG_UNBLOCK);
|
||||||
return 0;
|
res = 0;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
mnt_err = errno;
|
mnt_err = errno;
|
||||||
|
@ -913,13 +903,13 @@ retry_nfs:
|
||||||
else if (stat (spec, &statbuf))
|
else if (stat (spec, &statbuf))
|
||||||
error (_("mount: special device %s does not exist"), spec);
|
error (_("mount: special device %s does not exist"), spec);
|
||||||
else {
|
else {
|
||||||
errno = mnt_err;
|
errno = mnt_err;
|
||||||
perror("mount");
|
perror("mount");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ENOTDIR:
|
case ENOTDIR:
|
||||||
if (stat (node, &statbuf) || ! S_ISDIR(statbuf.st_mode))
|
if (stat (node, &statbuf) || ! S_ISDIR(statbuf.st_mode))
|
||||||
error (_("mount: mount point %s is not a directory"), node);
|
error (_("mount: mount point %s is not a directory"), node);
|
||||||
else if (stat (spec, &statbuf) && errno == ENOTDIR)
|
else if (stat (spec, &statbuf) && errno == ENOTDIR)
|
||||||
error (_("mount: special device %s does not exist\n"
|
error (_("mount: special device %s does not exist\n"
|
||||||
" (a path prefix is not a directory)\n"), spec);
|
" (a path prefix is not a directory)\n"), spec);
|
||||||
|
@ -981,7 +971,7 @@ retry_nfs:
|
||||||
char *lowtype, *p;
|
char *lowtype, *p;
|
||||||
int u;
|
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 */
|
/* maybe this loser asked for FAT or ISO9660 or isofs */
|
||||||
lowtype = xstrdup(types);
|
lowtype = xstrdup(types);
|
||||||
|
@ -995,7 +985,9 @@ retry_nfs:
|
||||||
if (u && is_in_procfs(lowtype) == 1)
|
if (u && is_in_procfs(lowtype) == 1)
|
||||||
error (_("mount: probably you meant %s"), lowtype);
|
error (_("mount: probably you meant %s"), lowtype);
|
||||||
else if (!strncmp(lowtype, "iso", 3) && is_in_procfs("iso9660") == 1)
|
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);
|
free(lowtype);
|
||||||
} else
|
} else
|
||||||
error (_("mount: %s has wrong device number or fs type %s not supported"),
|
error (_("mount: %s has wrong device number or fs type %s not supported"),
|
||||||
|
@ -1033,16 +1025,18 @@ retry_nfs:
|
||||||
types = types0;
|
types = types0;
|
||||||
}
|
}
|
||||||
if (opts) {
|
if (opts) {
|
||||||
char *opts1 = realloc(xstrdup(opts), strlen(opts)+4);
|
char *opts2 = realloc(xstrdup(opts), strlen(opts)+4);
|
||||||
strcat(opts1, ",ro");
|
strcat(opts2, ",ro");
|
||||||
opts = opts1;
|
my_free(opts1);
|
||||||
|
opts = opts1 = opts2;
|
||||||
} else
|
} else
|
||||||
opts = "ro";
|
opts = "ro";
|
||||||
if (types && !strcmp(types, "guess"))
|
if (types && !strcmp(types, "guess"))
|
||||||
types = 0;
|
types = 0;
|
||||||
error (_("mount: %s%s is write-protected, mounting read-only"),
|
error (_("mount: %s%s is write-protected, mounting read-only"),
|
||||||
bd, spec0);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1050,7 +1044,16 @@ retry_nfs:
|
||||||
error ("mount: %s", strerror (mnt_err)); break;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1094,14 +1097,20 @@ usersubst(const char *opts) {
|
||||||
}
|
}
|
||||||
return 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)
|
* Return 0 for success (either mounted sth or -a and NOAUTO was given)
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
mount_one (const char *spec, const char *node, char *types, const char *opts,
|
mount_one (const char *spec, const char *node, const char *types,
|
||||||
char *cmdlineopts, int freq, int pass) {
|
const char *opts, char *cmdlineopts, int freq, int pass) {
|
||||||
int status, status2;
|
int status, status2;
|
||||||
const char *nspec;
|
const char *nspec;
|
||||||
|
|
||||||
|
@ -1119,7 +1128,7 @@ mount_one (const char *spec, const char *node, char *types, const char *opts,
|
||||||
if (nspec)
|
if (nspec)
|
||||||
spec = nspec;
|
spec = nspec;
|
||||||
|
|
||||||
if (types == NULL && !mounttype) {
|
if (types == NULL && !mounttype && !is_existing_file(spec)) {
|
||||||
if (strchr (spec, ':') != NULL) {
|
if (strchr (spec, ':') != NULL) {
|
||||||
types = "nfs";
|
types = "nfs";
|
||||||
if (verbose)
|
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. */
|
/* Check if an fsname/dir pair was already in the old mtab. */
|
||||||
static int
|
static int
|
||||||
mounted (const char *spec, char *node) {
|
mounted (const char *spec0, const char *node0) {
|
||||||
struct mntentchn *mc, *mc0;
|
struct mntentchn *mc, *mc0;
|
||||||
|
char *spec, *node;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
/* Handle possible UUID= and LABEL= in spec */
|
/* Handle possible UUID= and LABEL= in spec */
|
||||||
spec = mount_get_devname(spec);
|
spec0 = mount_get_devname(spec0);
|
||||||
|
|
||||||
spec = canonicalize(spec);
|
spec = canonicalize(spec0);
|
||||||
node = canonicalize(node);
|
node = canonicalize(node0);
|
||||||
|
|
||||||
mc0 = mtab_head();
|
mc0 = mtab_head();
|
||||||
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
|
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
|
||||||
if (streq (spec, mc->m.mnt_fsname) && streq (node, mc->m.mnt_dir))
|
if (streq (spec, mc->m.mnt_fsname) &&
|
||||||
return 1;
|
streq (node, mc->m.mnt_dir)) {
|
||||||
return 0;
|
ret = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(spec);
|
||||||
|
free(node);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* avoid using stat() on things we are not going to mount anyway.. */
|
/* avoid using stat() on things we are not going to mount anyway.. */
|
||||||
static int
|
static int
|
||||||
has_noauto (char *opts) {
|
has_noauto (const char *opts) {
|
||||||
char *s;
|
char *s;
|
||||||
|
|
||||||
if (!opts)
|
if (!opts)
|
||||||
|
@ -1586,8 +1604,7 @@ main (int argc, char *argv[]) {
|
||||||
die (EX_USAGE,
|
die (EX_USAGE,
|
||||||
_("mount: cannot find %s in %s"),
|
_("mount: cannot find %s in %s"),
|
||||||
spec, _PATH_FSTAB);
|
spec, _PATH_FSTAB);
|
||||||
/* struct mntent does not have const qualifiers */
|
mc->m.mnt_fsname = spec;
|
||||||
mc->m.mnt_fsname = (char *) spec;
|
|
||||||
} else {
|
} else {
|
||||||
/* Try to find the other pathname in fstab. */
|
/* Try to find the other pathname in fstab. */
|
||||||
spec = canonicalize (*argv);
|
spec = canonicalize (*argv);
|
||||||
|
@ -1605,6 +1622,8 @@ main (int argc, char *argv[]) {
|
||||||
/* Earlier mtab was tried first, but this would
|
/* Earlier mtab was tried first, but this would
|
||||||
sometimes try the wrong mount in case mtab had
|
sometimes try the wrong mount in case mtab had
|
||||||
the root device entry wrong. */
|
the root device entry wrong. */
|
||||||
|
|
||||||
|
my_free(spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
result = mount_one (xstrdup (mc->m.mnt_fsname),
|
result = mount_one (xstrdup (mc->m.mnt_fsname),
|
||||||
|
|
|
@ -97,11 +97,12 @@ swapped(unsigned short a) {
|
||||||
Added jfs - Christoph Hellwig
|
Added jfs - Christoph Hellwig
|
||||||
Added sysv - Tim Launchbury
|
Added sysv - Tim Launchbury
|
||||||
Added udf - Bryce Nesbitt
|
Added udf - Bryce Nesbitt
|
||||||
|
Added ocfs, ocfs2 - Manish Singh - http://oss.oracle.com/projects/ocfs2/
|
||||||
*/
|
*/
|
||||||
static char
|
static char
|
||||||
*magic_known[] = {
|
*magic_known[] = {
|
||||||
"adfs", "bfs", "cramfs", "efs", "ext", "ext2", "ext3",
|
"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",
|
"qnx4", "reiserfs", "romfs", "swap", "sysv", "udf", "ufs",
|
||||||
"vxfs", "xfs", "xiafs"
|
"vxfs", "xfs", "xiafs"
|
||||||
};
|
};
|
||||||
|
@ -212,6 +213,7 @@ do_guess_fstype(const char *device) {
|
||||||
struct fat_super_block fatsb;
|
struct fat_super_block fatsb;
|
||||||
struct xfs_super_block xfsb;
|
struct xfs_super_block xfsb;
|
||||||
struct cramfs_super_block cramfssb;
|
struct cramfs_super_block cramfssb;
|
||||||
|
struct ocfs_volume_header ovh;
|
||||||
struct efs_volume_header efsvh;
|
struct efs_volume_header efsvh;
|
||||||
struct efs_super efssb;
|
struct efs_super efssb;
|
||||||
} xsb; /* stuff at 0 */
|
} xsb; /* stuff at 0 */
|
||||||
|
@ -232,6 +234,7 @@ do_guess_fstype(const char *device) {
|
||||||
struct hpfs_super_block hpfssb;
|
struct hpfs_super_block hpfssb;
|
||||||
struct adfs_super_block adfssb;
|
struct adfs_super_block adfssb;
|
||||||
struct sysv_super_block svsb;
|
struct sysv_super_block svsb;
|
||||||
|
struct ocfs2_super_block osb;
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
|
||||||
/* opening and reading an arbitrary unknown path can have
|
/* opening and reading an arbitrary unknown path can have
|
||||||
|
@ -261,6 +264,8 @@ do_guess_fstype(const char *device) {
|
||||||
type = "romfs";
|
type = "romfs";
|
||||||
else if(!strncmp(xsb.xfsb.s_magic, XFS_SUPER_MAGIC, 4))
|
else if(!strncmp(xsb.xfsb.s_magic, XFS_SUPER_MAGIC, 4))
|
||||||
type = "xfs";
|
type = "xfs";
|
||||||
|
else if(!strncmp(xsb.ovh.signature, OCFS_MAGIC, sizeof(OCFS_MAGIC)))
|
||||||
|
type = "ocfs";
|
||||||
else if(!strncmp(xsb.qnx4fs_magic+4, "QNX4FS", 6))
|
else if(!strncmp(xsb.qnx4fs_magic+4, "QNX4FS", 6))
|
||||||
type = "qnx4";
|
type = "qnx4";
|
||||||
else if(xsb.bfs_magic == 0x1badface)
|
else if(xsb.bfs_magic == 0x1badface)
|
||||||
|
@ -438,6 +443,22 @@ do_guess_fstype(const char *device) {
|
||||||
type = "reiserfs";
|
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) {
|
if (!type) {
|
||||||
/* perhaps the user tries to mount the swap space
|
/* perhaps the user tries to mount the swap space
|
||||||
on a new disk; warn her before she does mke2fs on it */
|
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 */
|
/* when 1 is returned, *types is NULL */
|
||||||
int
|
int
|
||||||
procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args,
|
procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args,
|
||||||
char **types) {
|
const char **types) {
|
||||||
char *files[2] = { ETC_FILESYSTEMS, PROC_FILESYSTEMS };
|
char *files[2] = { ETC_FILESYSTEMS, PROC_FILESYSTEMS };
|
||||||
FILE *procfs;
|
FILE *procfs;
|
||||||
char *fsname;
|
char *fsname;
|
||||||
char *notypes = NULL;
|
const char *notypes = NULL;
|
||||||
int no = 0;
|
int no = 0;
|
||||||
int ret = 1;
|
int ret = 1;
|
||||||
int errsv = 0;
|
int errsv = 0;
|
||||||
|
|
|
@ -11,6 +11,6 @@ extern int verbose;
|
||||||
char *guess_fstype(const char *device);
|
char *guess_fstype(const char *device);
|
||||||
char *do_guess_fstype(const char *device);
|
char *do_guess_fstype(const char *device);
|
||||||
int procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args,
|
int procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args,
|
||||||
char **type);
|
const char **type);
|
||||||
int is_in_procfs(const char *fstype);
|
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
|
#define MAX_READLINKS 32
|
||||||
|
|
||||||
/* this leaks some memory - unimportant for mount */
|
|
||||||
char *
|
char *
|
||||||
myrealpath(const char *path, char *resolved_path, int maxreslth) {
|
myrealpath(const char *path, char *resolved_path, int maxreslth) {
|
||||||
int readlinks = 0;
|
int readlinks = 0;
|
||||||
char *npath;
|
char *npath;
|
||||||
char link_path[PATH_MAX+1];
|
char link_path[PATH_MAX+1];
|
||||||
int n;
|
int n;
|
||||||
#ifdef resolve_symlinks
|
char *buf = NULL;
|
||||||
char *buf;
|
|
||||||
int m;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
npath = resolved_path;
|
npath = resolved_path;
|
||||||
|
|
||||||
|
@ -83,7 +79,7 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
|
||||||
while (*path != '\0' && *path != '/') {
|
while (*path != '\0' && *path != '/') {
|
||||||
if (npath-resolved_path > maxreslth-2) {
|
if (npath-resolved_path > maxreslth-2) {
|
||||||
errno = ENAMETOOLONG;
|
errno = ENAMETOOLONG;
|
||||||
return NULL;
|
goto err;
|
||||||
}
|
}
|
||||||
*npath++ = *path++;
|
*npath++ = *path++;
|
||||||
}
|
}
|
||||||
|
@ -91,7 +87,7 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
|
||||||
/* Protect against infinite loops. */
|
/* Protect against infinite loops. */
|
||||||
if (readlinks++ > MAX_READLINKS) {
|
if (readlinks++ > MAX_READLINKS) {
|
||||||
errno = ELOOP;
|
errno = ELOOP;
|
||||||
return NULL;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if last pathname component is a symlink. */
|
/* See if last pathname component is a symlink. */
|
||||||
|
@ -100,9 +96,11 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
/* EINVAL means the file exists but isn't a symlink. */
|
/* EINVAL means the file exists but isn't a symlink. */
|
||||||
if (errno != EINVAL)
|
if (errno != EINVAL)
|
||||||
return NULL;
|
goto err;
|
||||||
} else {
|
} else {
|
||||||
#ifdef resolve_symlinks /* Richard Gooch dislikes sl resolution */
|
#ifdef resolve_symlinks /* Richard Gooch dislikes sl resolution */
|
||||||
|
int m;
|
||||||
|
|
||||||
/* Note: readlink doesn't add the null byte. */
|
/* Note: readlink doesn't add the null byte. */
|
||||||
link_path[n] = '\0';
|
link_path[n] = '\0';
|
||||||
if (*link_path == '/')
|
if (*link_path == '/')
|
||||||
|
@ -115,6 +113,8 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
|
||||||
|
|
||||||
/* Insert symlink contents into path. */
|
/* Insert symlink contents into path. */
|
||||||
m = strlen(path);
|
m = strlen(path);
|
||||||
|
if (buf)
|
||||||
|
free(buf);
|
||||||
buf = xmalloc(m + n + 1);
|
buf = xmalloc(m + n + 1);
|
||||||
memcpy(buf, link_path, n);
|
memcpy(buf, link_path, n);
|
||||||
memcpy(buf + n, path, m + 1);
|
memcpy(buf + n, path, m + 1);
|
||||||
|
@ -128,5 +128,13 @@ myrealpath(const char *path, char *resolved_path, int maxreslth) {
|
||||||
npath--;
|
npath--;
|
||||||
/* Make sure it's null terminated. */
|
/* Make sure it's null terminated. */
|
||||||
*npath = '\0';
|
*npath = '\0';
|
||||||
|
|
||||||
|
if (buf)
|
||||||
|
free(buf);
|
||||||
return resolved_path;
|
return resolved_path;
|
||||||
|
|
||||||
|
err:
|
||||||
|
if (buf)
|
||||||
|
free(buf);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,7 @@ xstrconcat2 (const char *s, const char *t) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* frees its first arg - typical use: s = xstrconcat3(s,t,u); */
|
||||||
char *
|
char *
|
||||||
xstrconcat3 (const char *s, const char *t, const char *u) {
|
xstrconcat3 (const char *s, const char *t, const char *u) {
|
||||||
char *res;
|
char *res;
|
||||||
|
@ -84,9 +85,11 @@ xstrconcat3 (const char *s, const char *t, const char *u) {
|
||||||
strcpy(res, s);
|
strcpy(res, s);
|
||||||
strcat(res, t);
|
strcat(res, t);
|
||||||
strcat(res, u);
|
strcat(res, u);
|
||||||
|
free((void *) s);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* frees its first arg - typical use: s = xstrconcat4(s,t,u,v); */
|
||||||
char *
|
char *
|
||||||
xstrconcat4 (const char *s, const char *t, const char *u, const char *v) {
|
xstrconcat4 (const char *s, const char *t, const char *u, const char *v) {
|
||||||
char *res;
|
char *res;
|
||||||
|
@ -100,6 +103,7 @@ xstrconcat4 (const char *s, const char *t, const char *u, const char *v) {
|
||||||
strcat(res, t);
|
strcat(res, t);
|
||||||
strcat(res, u);
|
strcat(res, u);
|
||||||
strcat(res, v);
|
strcat(res, v);
|
||||||
|
free((void *) s);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,19 +273,18 @@ matching_opts (const char *options, const char *test_opts) {
|
||||||
we return unmodified. */
|
we return unmodified. */
|
||||||
char *
|
char *
|
||||||
canonicalize (const char *path) {
|
canonicalize (const char *path) {
|
||||||
char *canonical;
|
char canonical[PATH_MAX+2];
|
||||||
|
|
||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (streq(path, "none") || streq(path, "proc") || streq(path, "devpts"))
|
if (streq(path, "none") ||
|
||||||
return xstrdup(path);
|
streq(path, "proc") ||
|
||||||
|
streq(path, "devpts"))
|
||||||
|
return xstrdup(path);
|
||||||
|
|
||||||
canonical = xmalloc (PATH_MAX+2);
|
if (myrealpath (path, canonical, PATH_MAX+1))
|
||||||
|
return xstrdup(canonical);
|
||||||
if (myrealpath (path, canonical, PATH_MAX+1))
|
|
||||||
return canonical;
|
|
||||||
|
|
||||||
free(canonical);
|
return xstrdup(path);
|
||||||
return xstrdup(path);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,7 +249,7 @@ do_swapoff(const char *special, int quiet) {
|
||||||
exit(1); /* any further swapoffs will also fail */
|
exit(1); /* any further swapoffs will also fail */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!quiet) {
|
if (!quiet || errno == ENOMEM) {
|
||||||
int errsv = errno;
|
int errsv = errno;
|
||||||
fprintf(stderr, "%s: %s: %s\n", program_name,
|
fprintf(stderr, "%s: %s: %s\n", program_name,
|
||||||
special, strerror(errsv));
|
special, strerror(errsv));
|
||||||
|
|
|
@ -316,7 +316,7 @@ umount_one (const char *spec, const char *node, const char *type,
|
||||||
res = mount(spec, node, NULL,
|
res = mount(spec, node, NULL,
|
||||||
MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL);
|
MS_MGC_VAL | MS_REMOUNT | MS_RDONLY, NULL);
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
struct mntent remnt;
|
struct my_mntent remnt;
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
_("umount: %s busy - remounted read-only\n"),
|
_("umount: %s busy - remounted read-only\n"),
|
||||||
spec);
|
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?
|
* Why this loop?
|
||||||
* 1. People who boot a system with a bad fstab root entry
|
* 1. People who boot a system with a bad fstab root entry
|
||||||
* will get an incorrect "/dev/foo on /" in mtab.
|
* will get an incorrect "/dev/foo on /" in mtab.
|
||||||
|
@ -472,52 +474,18 @@ usage (FILE *fp, int n)
|
||||||
|
|
||||||
int mount_quiet = 0;
|
int mount_quiet = 0;
|
||||||
|
|
||||||
/*=======================================================================*/
|
/*
|
||||||
/* string list stuff - no longer used by mount - will disappear entirely */
|
* Look for an option in a comma-separated list
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
contains(string_list list, char *s) {
|
contains(const char *list, const char *s) {
|
||||||
while (list) {
|
int n = strlen(s);
|
||||||
if (streq (car (list), s))
|
|
||||||
|
while (*list) {
|
||||||
|
if (strncmp(list, s, n) == 0 &&
|
||||||
|
(list[n] == 0 || list[n] == ','))
|
||||||
return 1;
|
return 1;
|
||||||
list = cdr (list);
|
while (*list && *list++ != ',') ;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -526,12 +494,18 @@ contains(string_list list, char *s) {
|
||||||
* If list contains "user=peter" and we ask for "user=", return "peter"
|
* If list contains "user=peter" and we ask for "user=", return "peter"
|
||||||
*/
|
*/
|
||||||
static char *
|
static char *
|
||||||
get_value(string_list list, char *s) {
|
get_value(const char *list, const char *s) {
|
||||||
|
const char *t;
|
||||||
int n = strlen(s);
|
int n = strlen(s);
|
||||||
while (list) {
|
|
||||||
if (strncmp (car (list), s, n) == 0)
|
while (*list) {
|
||||||
return car(list)+n;
|
if (strncmp(list, s, n) == 0) {
|
||||||
list = cdr (list);
|
s = t = list+n;
|
||||||
|
while (*s && *s != ',')
|
||||||
|
s++;
|
||||||
|
return xstrndup(t, s-t);
|
||||||
|
}
|
||||||
|
while (*list && *list++ != ',') ;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -539,8 +513,7 @@ get_value(string_list list, char *s) {
|
||||||
static int
|
static int
|
||||||
umount_file (char *arg) {
|
umount_file (char *arg) {
|
||||||
struct mntentchn *mc, *fs;
|
struct mntentchn *mc, *fs;
|
||||||
char *file;
|
const char *file, *options;
|
||||||
string_list options;
|
|
||||||
int fstab_has_user, fstab_has_users, fstab_has_owner, ok;
|
int fstab_has_user, fstab_has_users, fstab_has_owner, ok;
|
||||||
|
|
||||||
file = canonicalize(arg); /* mtab paths are canonicalized */
|
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
|
/* A convenient side effect is that the user who mounted
|
||||||
is visible in mtab. */
|
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_user = contains(options, "user");
|
||||||
fstab_has_users = contains(options, "users");
|
fstab_has_users = contains(options, "users");
|
||||||
fstab_has_owner = contains(options, "owner");
|
fstab_has_owner = contains(options, "owner");
|
||||||
|
@ -606,7 +581,9 @@ umount_file (char *arg) {
|
||||||
if (!ok && (fstab_has_user || fstab_has_owner)) {
|
if (!ok && (fstab_has_user || fstab_has_owner)) {
|
||||||
char *user = getusername();
|
char *user = getusername();
|
||||||
|
|
||||||
options = parse_list (mc->m.mnt_opts);
|
options = mc->m.mnt_opts;
|
||||||
|
if (!options)
|
||||||
|
options = "";
|
||||||
mtab_user = get_value(options, "user=");
|
mtab_user = get_value(options, "user=");
|
||||||
|
|
||||||
if (user && mtab_user && streq (user, mtab_user))
|
if (user && mtab_user && streq (user, mtab_user))
|
||||||
|
|
2
po/ca.po
2
po/ca.po
|
@ -10,7 +10,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: util-linux 2.12\n"
|
"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"
|
"PO-Revision-Date: 2003-08-01 10:59+0200\n"
|
||||||
"Last-Translator: Antoni Bella Perez <bella5@teleline.es>\n"
|
"Last-Translator: Antoni Bella Perez <bella5@teleline.es>\n"
|
||||||
"Language-Team: Catalan <ca@dodds.net>\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 ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: util-linux-2.11d\n"
|
"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"
|
"PO-Revision-Date: 2001-05-30 15:11+0200\n"
|
||||||
"Last-Translator: Jiøí Pavlovský <pavlovsk@ff.cuni.cz>\n"
|
"Last-Translator: Jiøí Pavlovský <pavlovsk@ff.cuni.cz>\n"
|
||||||
"Language-Team: Czech <cs@li.org>\n"
|
"Language-Team: Czech <cs@li.org>\n"
|
||||||
|
|
2
po/da.po
2
po/da.po
|
@ -12,7 +12,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: util-linux 2.11y\n"
|
"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"
|
"PO-Revision-Date: 2002-12-02 21:15GMT\n"
|
||||||
"Last-Translator: Claus Hindsgaul <claus_h@image.dk>\n"
|
"Last-Translator: Claus Hindsgaul <claus_h@image.dk>\n"
|
||||||
"Language-Team: Danish <dansk@klid.dk>\n"
|
"Language-Team: Danish <dansk@klid.dk>\n"
|
||||||
|
|
2
po/de.po
2
po/de.po
|
@ -44,7 +44,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: util-linux 2.12\n"
|
"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"
|
"PO-Revision-Date: 2003-08-14 15:43:31+0200\n"
|
||||||
"Last-Translator: Michael Piefel <piefel@informatik.hu-berlin.de>\n"
|
"Last-Translator: Michael Piefel <piefel@informatik.hu-berlin.de>\n"
|
||||||
"Language-Team: German <de@li.org>\n"
|
"Language-Team: German <de@li.org>\n"
|
||||||
|
|
2
po/es.po
2
po/es.po
|
@ -12,7 +12,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: util-linux 2.12\n"
|
"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"
|
"PO-Revision-Date: 2003-08-09 16:18+0200\n"
|
||||||
"Last-Translator: Santiago Vila Doncel <sanvila@unex.es>\n"
|
"Last-Translator: Santiago Vila Doncel <sanvila@unex.es>\n"
|
||||||
"Language-Team: Spanish <es@li.org>\n"
|
"Language-Team: Spanish <es@li.org>\n"
|
||||||
|
|
2
po/et.po
2
po/et.po
|
@ -11,7 +11,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: util-linux 2.11r\n"
|
"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"
|
"PO-Revision-Date: 2002-05-19 20:04GMT+0300\n"
|
||||||
"Last-Translator: Meelis Roos <mroos@linux.ee>\n"
|
"Last-Translator: Meelis Roos <mroos@linux.ee>\n"
|
||||||
"Language-Team: Estonian <et@li.org>\n"
|
"Language-Team: Estonian <et@li.org>\n"
|
||||||
|
|
2
po/fi.po
2
po/fi.po
|
@ -14,7 +14,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: util-linux 2.12\n"
|
"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"
|
"PO-Revision-Date: 2003-08-20 11:40+0300\n"
|
||||||
"Last-Translator: Lauri Nurmi <lanurmi@iki.fi>\n"
|
"Last-Translator: Lauri Nurmi <lanurmi@iki.fi>\n"
|
||||||
"Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n"
|
"Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n"
|
||||||
|
|
2
po/fr.po
2
po/fr.po
|
@ -9,7 +9,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: util-linux 2.12\n"
|
"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"
|
"PO-Revision-Date: 2004-05-10 08:00-0500\n"
|
||||||
"Last-Translator: Michel Robitaille <robitail@IRO.UMontreal.CA>\n"
|
"Last-Translator: Michel Robitaille <robitail@IRO.UMontreal.CA>\n"
|
||||||
"Language-Team: French <traduc@traduc.org>\n"
|
"Language-Team: French <traduc@traduc.org>\n"
|
||||||
|
|
2
po/it.po
2
po/it.po
|
@ -4,7 +4,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: util-linux 2.10f\n"
|
"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"
|
"PO-Revision-Date: 2000-04-04 21:52-0800\n"
|
||||||
"Last-Translator: Beth Powell <bpowell@turbolinux.com>\n"
|
"Last-Translator: Beth Powell <bpowell@turbolinux.com>\n"
|
||||||
"Language-Team: <support@turbolinux.com>\n"
|
"Language-Team: <support@turbolinux.com>\n"
|
||||||
|
|
2
po/ja.po
2
po/ja.po
|
@ -7,7 +7,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: util-linux 2.11n\n"
|
"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"
|
"PO-Revision-Date: 2001-12-11 22:43+0900\n"
|
||||||
"Last-Translator: Daisuke Yamashita <yamad@mb.infoweb.ne.jp>\n"
|
"Last-Translator: Daisuke Yamashita <yamad@mb.infoweb.ne.jp>\n"
|
||||||
"Language-Team: Japanese <ja@li.org>\n"
|
"Language-Team: Japanese <ja@li.org>\n"
|
||||||
|
|
2
po/nl.po
2
po/nl.po
|
@ -19,7 +19,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: util-linux 2.12\n"
|
"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"
|
"PO-Revision-Date: 2003-07-29 22:55+0100\n"
|
||||||
"Last-Translator: Taco Witte <T.C.Witte@phys.uu.nl>\n"
|
"Last-Translator: Taco Witte <T.C.Witte@phys.uu.nl>\n"
|
||||||
"Language-Team: Dutch <vertaling@nl.linux.org>\n"
|
"Language-Team: Dutch <vertaling@nl.linux.org>\n"
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: util-linux 2.11b\n"
|
"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"
|
"PO-Revision-Date: 2001-05-24 16:03-03:00\n"
|
||||||
"Last-Translator: Rodrigo Stulzer Lopes <rodrigo@conectiva.com.br>\n"
|
"Last-Translator: Rodrigo Stulzer Lopes <rodrigo@conectiva.com.br>\n"
|
||||||
"Language-Team: Brazilian Portuguese <ldp-br@bazar.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 ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: util-linux 2.11y\n"
|
"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"
|
"PO-Revision-Date: 2003-01-28 16:30+0100\n"
|
||||||
"Last-Translator: Primo¾ Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>\n"
|
"Last-Translator: Primo¾ Peterlin <primoz.peterlin@biofiz.mf.uni-lj.si>\n"
|
||||||
"Language-Team: Slovenian <translation-team-sl@lists.sourceforge.net>\n"
|
"Language-Team: Slovenian <translation-team-sl@lists.sourceforge.net>\n"
|
||||||
|
|
2
po/sv.po
2
po/sv.po
|
@ -10,7 +10,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: util-linux 2.12\n"
|
"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"
|
"PO-Revision-Date: 2003-08-01 01:33+0200\n"
|
||||||
"Last-Translator: Christian Rose <menthos@menthos.com>\n"
|
"Last-Translator: Christian Rose <menthos@menthos.com>\n"
|
||||||
"Language-Team: Swedish <sv@li.org>\n"
|
"Language-Team: Swedish <sv@li.org>\n"
|
||||||
|
|
2
po/tr.po
2
po/tr.po
|
@ -10,7 +10,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: util-linux 2.12\n"
|
"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"
|
"PO-Revision-Date: 2003-08-03 13:18+0300\n"
|
||||||
"Last-Translator: Nilgün Belma Bugüner <nilgun@superonline.com>\n"
|
"Last-Translator: Nilgün Belma Bugüner <nilgun@superonline.com>\n"
|
||||||
"Language-Team: Turkish <gnu-tr-u12a@lists.sourceforge.net>\n"
|
"Language-Team: Turkish <gnu-tr-u12a@lists.sourceforge.net>\n"
|
||||||
|
|
2
po/uk.po
2
po/uk.po
|
@ -6,7 +6,7 @@
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: util-linux 2.12\n"
|
"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"
|
"PO-Revision-Date: 2004-02-24 10:45+0200\n"
|
||||||
"Last-Translator: Maxim V. Dziumanenko <mvd@mylinux.com.ua>\n"
|
"Last-Translator: Maxim V. Dziumanenko <mvd@mylinux.com.ua>\n"
|
||||||
"Language-Team: Ukrainian <translation-team-uk@lists.sourceforge.net>\n"
|
"Language-Team: Ukrainian <translation-team-uk@lists.sourceforge.net>\n"
|
||||||
|
|
Loading…
Reference in New Issue