Imported from util-linux-2.12a tarball.

This commit is contained in:
Karel Zak 2006-12-07 00:26:14 +01:00
parent a21409f54e
commit d03dd60840
52 changed files with 7224 additions and 5577 deletions

27
HISTORY
View File

@ -1,3 +1,30 @@
util-linux 2.12a
* chfn, chsh, login, vipw: SElinux support
* fdisk: fix for kernels 2.4.15-2.4.17
* fdisk: fix when all partitions are in use
* hwclock: add a timeout when waiting for a clock update (Göran Weinholt)
* ipcs: compilation fix
* ipcs: shminfo.shmall gives pages
* login: use getutline() instead of getutid()
* login: fix for 64-bit time_t
* mount: efs support
* partx: bigendian fix
* readprofile: support for 64-bit addresses
* setterm: fix klogctl error message (Joern Heissler)
* setterm.1: clarification
* sfdisk: fix check for is_ide_cdrom_or_tape
* umount: skip proc, devfs, devpts on umount -a
util-linux 2.12
* losetup: cryptoloop support
* losetup: -p option specifies fd for passphrase
* fdisk: sgi layout fix
* mount: -p option specifies fd for passphrase
* mount: recognize some PCDOS floppies
* umount: in "umount name", first try to interpret "name" as a mount point
util-linux 2.12pre
* Catalan messages (Antoni Bella Perez)

View File

@ -1,5 +1,5 @@
Maintainer: Andries Brouwer <aeb@cwi.nl>
Maintainer address: util-linux@math.uio.no
Use a Subject line with [util-linux] .
Maintainer of getopt: Frodo Looijaard <frodol@dds.nl>
Maintainer of simpleinit: Richard Gooch <rgooch@atnf.csiro.au>

View File

@ -18,6 +18,10 @@ ARCH=$(shell echo $(CPU) | sed 's/i.86/intel/;s/arm.*/arm/')
# installed as it is not PAM aware.
HAVE_PAM=no
# If HAVE_SELINUX is set to "yes", the login will make sure the user is
# logged into an appropriate security context
HAVE_SELINUX=no
# If HAVE_SHADOW is set to "yes", then login, chfn, chsh, newgrp, passwd,
# and vipw will not be built or installed from the login-utils
# subdirectory.

View File

@ -1 +1 @@
2.12pre
2.12a

19
configure vendored
View File

@ -15,6 +15,7 @@
# H7. For nfsmount.c: do we have <rpcsvc/nfs_prot.h>?
# H8. For nfsmount.h (nfsmount_xdr.c: int32_t): do we have <asm/types.h>?
# H9. For raw.c: do we have <linux/raw.h>?
# H10. For md5.c: do we have <stdint.h>?
#
# Existence of functions:
# F1. For nfsmount.c: is inet_aton() available?
@ -37,7 +38,7 @@
# 8. For err.c: do we have __progname?
# 9. For script.c: do we have <pty.h> and openpty()?
# 10. For lib/widechar.h: do we have wide character support?
# 11. For pivot_root.c: does <linux/unistd.h> define __NR_pivot_root?
# 11. For pivot_root.c: does <sys/syscall.h> define SYS_pivot_root?
# 12. For hwclock.c: does struct tm have a field tm_gmtoff?
# 13. For nfsmount: does the output of rpcgen compile?
# 14. For fsck.cramfs, mkfs.cramfs: do we have libz?
@ -165,6 +166,11 @@ if ./testincl "linux/raw.h"; then
echo "HAVE_RAW_H=yes" >> make_include
fi
#
# H10. For md5.c: do we have <stdint.h>?
if ./testincl "stdint.h"; then
echo "#define HAVE_stdint_h" >> defines.h
fi
#
# Find out about the existence of functions
@ -594,21 +600,22 @@ fi
rm -f conftest conftest.c
#
# 11. For pivot_root.c: does <linux/unistd.h> define __NR_pivot_root?
# 11. For pivot_root.c: does <sys/syscall.h> define SYS_pivot_root?
#
echo "
#include <linux/unistd.h>
#include <sys/syscall.h>
#include <unistd.h>
int main(void)
{
return __NR_pivot_root;
return SYS_pivot_root;
}
" >conftest.c
eval $compile
if test -s conftest; then
echo "HAVE_PIVOT_ROOT=yes" >> make_include
echo "You have __NR_pivot_root"
echo "You have SYS_pivot_root"
else
echo "You don't have __NR_pivot_root"
echo "You don't have SYS_pivot_root"
fi
rm -f conftest conftest.c

View File

@ -63,9 +63,9 @@
static char * program_name = "mkswap";
static char * device_name = NULL;
static int DEV = -1;
static long PAGES = 0;
static unsigned long PAGES = 0;
static unsigned long badpages = 0;
static int check = 0;
static int badpages = 0;
static int version = -1;
#define MAKE_VERSION(p,q,r) (65536*(p) + 256*(q) + (r))
@ -379,7 +379,7 @@ check_blocks(void) {
if (badpages == 1)
printf(_("one bad page\n"));
else if (badpages > 1)
printf(_("%d bad pages\n"), badpages);
printf(_("%lu bad pages\n"), badpages);
}
static long
@ -412,10 +412,10 @@ find_size (int fd) {
}
/* return size in pages, to avoid integer overflow */
static long
static unsigned long
get_size(const char *file) {
int fd;
long size;
unsigned long size;
fd = open(file, O_RDONLY);
if (fd < 0) {
@ -440,9 +440,10 @@ isnzdigit(char c) {
int
main(int argc, char ** argv) {
struct stat statbuf;
int i, sz;
long maxpages;
long goodpages;
int i;
unsigned long maxpages;
unsigned long goodpages;
unsigned long sz;
off_t offset;
int force = 0;
char *block_count = 0;
@ -507,7 +508,7 @@ main(int argc, char ** argv) {
explicitly */
char *tmp;
int blocks_per_page = pagesize/1024;
PAGES = strtol(block_count,&tmp,0)/blocks_per_page;
PAGES = strtoul(block_count,&tmp,0)/blocks_per_page;
if (*tmp)
usage();
}
@ -517,7 +518,7 @@ main(int argc, char ** argv) {
} else if (PAGES > sz && !force) {
fprintf(stderr,
_("%s: error: "
"size %ld is larger than device size %d\n"),
"size %lu is larger than device size %lu\n"),
program_name,
PAGES*(pagesize/1024), sz*(pagesize/1024));
exit(1);
@ -611,7 +612,7 @@ the -f option to force it.\n"),
}
goodpages = PAGES - badpages - 1;
if (goodpages <= 0)
if ((long) goodpages <= 0)
die(_("Unable to set up swap-space: unreadable"));
printf(_("Setting up swapspace version %d, size = %llu kB\n"),
version, (unsigned long long)goodpages * pagesize / 1000);

View File

@ -118,28 +118,6 @@ extern long long ext2_llseek(unsigned int fd, long long offset,
#define LINUX_SWAP 0x82
#define LINUX 0x83
/* There used to be defined error messages here. However, it turns out
* that gettext cannot handle constructions like
*
* #define ADD_EXISTS _("This partition is already in use")
* ...
* print_warning(ADD_EXISTS);
*
* So, now the messages are spread over the source again.
* Another thing which gettext cannot cope with are multi-line strings:
*
* printf("Usage:
* Print version:
* cfdisk -v
* Print partition table:
* cfdisk -P{r|s|t} device
* ");
*
* (This is a commonly used gnu extension of the C syntax, but not ANSI-C.)
* Another reason to uglify the source a little.
*/
#define PRI_OR_LOG -1
#define PRIMARY -2
#define LOGICAL -3

View File

@ -220,7 +220,7 @@ Try them in the order
.B cfdisk
is a beautiful program that has strict requirements on
the partition tables it accepts, and produces high quality partition
tables. Use it if you can.
tables. Use it if you can.
.B fdisk
is a buggy program that does fuzzy things - usually it happens to
produce reasonable results. Its single advantage is that it has
@ -231,6 +231,11 @@ is for hackers only - the user interface is terrible, but it is
more correct than fdisk and more powerful than both fdisk and cfdisk.
Moreover, it can be used noninteractively.)
.PP
These days there also is
.BR parted .
The cfdisk interface is nicer, but parted does much more: it not only
resizes partitions, but also the filesystems that live in them.
.PP
The IRIX/SGI type disklabel is currently not supported by the kernel.
Moreover, IRIX/SGI header directories are not fully supported yet.
.PP

View File

@ -801,6 +801,7 @@ get_partition_table_geometry(void) {
void
get_geometry(int fd, struct geom *g) {
int sec_fac;
unsigned long longsectors;
unsigned long long bytes; /* really u64 */
get_sectorsize(fd);
@ -820,15 +821,18 @@ get_geometry(int fd, struct geom *g) {
pt_sectors ? pt_sectors :
kern_sectors ? kern_sectors : 63;
if (ioctl(fd, BLKGETSIZE64, &bytes) == 0) {
/* got bytes */
} else {
unsigned long longsectors;
if (ioctl(fd, BLKGETSIZE, &longsectors))
longsectors = 0;
if (ioctl(fd, BLKGETSIZE64, &bytes))
bytes = 0;
if (ioctl(fd, BLKGETSIZE, &longsectors))
longsectors = 0;
/*
* If BLKGETSIZE64 was unknown or broken, use longsectors.
* (Kernels 2.4.15-2.4.17 had a broken BLKGETSIZE64
* that returns sectors instead of bytes.)
*/
if (bytes == 0 || bytes == longsectors)
bytes = ((unsigned long long) longsectors) << 9;
}
total_number_of_sectors = (bytes >> 9);
@ -1853,11 +1857,12 @@ verify(void) {
}
}
if (total > heads * sectors * cylinders)
if (total > total_number_of_sectors)
printf(_("Total allocated sectors %d greater than the maximum "
"%d\n"), total, heads * sectors * cylinders);
else if ((total = heads * sectors * cylinders - total) != 0)
printf(_("%d unallocated sectors\n"), total);
"%lld\n"), total, total_number_of_sectors);
else if (total < total_number_of_sectors)
printf(_("%lld unallocated sectors\n"),
total_number_of_sectors - total);
}
static void
@ -2045,6 +2050,10 @@ new_partition(void) {
else
printf(_("You must delete some partition and add "
"an extended partition first\n"));
} else if (partitions >= MAXIMUM_PARTS) {
printf(_("All logical partitions are in use\n"));
printf(_("Adding a primary partition\n"));
add_partition(get_partition(0, 4), LINUX_NATIVE);
} else {
char c, line[LINE_LENGTH];
snprintf(line, sizeof(line),
@ -2506,7 +2515,7 @@ main(int argc, char **argv) {
}
if (opts) {
long size;
unsigned long size;
nowarn = 1;
type_open = O_RDONLY;
@ -2523,9 +2532,9 @@ main(int argc, char **argv) {
fatal(ioctl_error);
close(fd);
if (opts == 1)
printf("%ld\n", size/2);
printf("%lu\n", size/2);
else
printf("%s: %ld\n", argv[j], size/2);
printf("%s: %lu\n", argv[j], size/2);
}
exit(0);
}

View File

@ -396,7 +396,7 @@ struct geometry {
static struct geometry
get_geometry(char *dev, int fd, int silent) {
struct hd_geometry g;
long size;
unsigned long size;
struct geometry R;
if (ioctl(fd, BLKGETSIZE, &size)) {
@ -2398,7 +2398,7 @@ static void do_change_id(char *dev, char *part, char *id);
static void do_unhide(char **av, int ac, char *arg);
static void do_activate(char **av, int ac, char *arg);
int total_size;
unsigned long total_size;
int
main(int argc, char **argv) {
@ -2527,7 +2527,7 @@ main(int argc, char **argv) {
total_size = 0;
openproc();
while ((dev = nextproc()) != NULL) {
if (!strncmp(dev, "hd", 2) && is_ide_cdrom_or_tape(dev))
if (is_ide_cdrom_or_tape(dev))
continue;
if (opt_out_geom)
do_geom(dev, 1);
@ -2538,7 +2538,7 @@ main(int argc, char **argv) {
}
if (opt_size)
printf(_("total: %d blocks\n"), total_size);
printf(_("total: %lu blocks\n"), total_size);
exit(exit_status);
}
@ -2664,7 +2664,7 @@ do_geom (char *dev, int silent) {
static void
do_size (char *dev, int silent) {
int fd;
long size;
unsigned long size;
fd = my_open(dev, 0, silent);
if (fd < 0)
@ -2685,9 +2685,9 @@ do_size (char *dev, int silent) {
return;
if (silent)
printf("%s: %9ld\n", dev, size);
printf("%s: %9lu\n", dev, size);
else
printf("%ld\n", size);
printf("%lu\n", size);
total_size += size;
}

View File

@ -3,6 +3,7 @@
#include <fcntl.h> /* for O_RDONLY */
#include <sysexits.h>
#include <sys/ioctl.h>
#include <sys/time.h> /* for struct timeval */
#include "clock.h"
#include "nls.h"
@ -226,17 +227,40 @@ int ret;
rtc_dev_name);
ret = busywait_for_rtc_clock_tick(rtc_fd);
} else if (rc == 0) {
#ifdef Wait_until_update_interrupt
unsigned long dummy;
/* this blocks until the next update interrupt */
rc = read(rtc_fd, &dummy, sizeof(dummy));
if (rc == -1) {
ret = 1;
if (rc == -1)
outsyserr(_("read() to %s to wait for clock tick failed"),
rtc_dev_name);
ret = 1;
} else {
else
ret = 0;
}
#else
/* Just reading rtc_fd fails on broken hardware: no update
interrupt comes and a bootscript with a hwclock call hangs */
fd_set rfds;
struct timeval tv;
/* Wait up to five seconds for the next update interrupt */
FD_ZERO(&rfds);
FD_SET(rtc_fd, &rfds);
tv.tv_sec = 5;
tv.tv_usec = 0;
rc = select(rtc_fd + 1, &rfds, NULL, NULL, &tv);
ret = 1;
if (rc == -1)
outsyserr(_("select() to %s to wait for clock tick failed"),
rtc_dev_name);
else if (rc == 0)
fprintf(stderr, _("select() to %s to wait for clock tick timed out\n"),
rtc_dev_name);
else
ret = 0;
#endif
/* Turn off update interrupts */
rc = ioctl(rtc_fd, RTC_UIE_OFF, 0);
if (rc == -1)

View File

@ -1,238 +0,0 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
#
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
tranformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

View File

@ -15,6 +15,7 @@
* will fill a supplied 16-byte array with the digest.
*/
#include <string.h> /* for memcpy() */
#include "md5.h"
#ifndef HIGHFIRST
@ -28,11 +29,11 @@ void byteReverse(unsigned char *buf, unsigned longs);
*/
void byteReverse(unsigned char *buf, unsigned longs)
{
uint32 t;
uint32_t t;
do {
t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
((unsigned) buf[1] << 8 | buf[0]);
*(uint32 *) buf = t;
*(uint32_t *) buf = t;
buf += 4;
} while (--longs);
}
@ -60,12 +61,12 @@ void MD5Init(struct MD5Context *ctx)
*/
void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
{
uint32 t;
uint32_t t;
/* Update bitcount */
t = ctx->bits[0];
if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t)
ctx->bits[1]++; /* Carry from low to high */
ctx->bits[1] += len >> 29;
@ -83,7 +84,7 @@ void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
}
memcpy(p, buf, t);
byteReverse(ctx->in, 16);
MD5Transform(ctx->buf, (uint32 *) ctx->in);
MD5Transform(ctx->buf, (uint32_t *) ctx->in);
buf += t;
len -= t;
}
@ -92,7 +93,7 @@ void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
while (len >= 64) {
memcpy(ctx->in, buf, 64);
byteReverse(ctx->in, 16);
MD5Transform(ctx->buf, (uint32 *) ctx->in);
MD5Transform(ctx->buf, (uint32_t *) ctx->in);
buf += 64;
len -= 64;
}
@ -127,7 +128,7 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
/* Two lots of padding: Pad the first block to 64 bytes */
memset(p, 0, count);
byteReverse(ctx->in, 16);
MD5Transform(ctx->buf, (uint32 *) ctx->in);
MD5Transform(ctx->buf, (uint32_t *) ctx->in);
/* Now fill the next block with 56 bytes */
memset(ctx->in, 0, 56);
@ -138,10 +139,10 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
byteReverse(ctx->in, 14);
/* Append length in bits and transform */
((uint32 *) ctx->in)[14] = ctx->bits[0];
((uint32 *) ctx->in)[15] = ctx->bits[1];
((uint32_t *) ctx->in)[14] = ctx->bits[0];
((uint32_t *) ctx->in)[15] = ctx->bits[1];
MD5Transform(ctx->buf, (uint32 *) ctx->in);
MD5Transform(ctx->buf, (uint32_t *) ctx->in);
byteReverse((unsigned char *) ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
@ -166,9 +167,9 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
void MD5Transform(uint32 buf[4], uint32 const in[16])
void MD5Transform(uint32_t buf[4], uint32_t const in[16])
{
register uint32 a, b, c, d;
register uint32_t a, b, c, d;
a = buf[0];
b = buf[1];

View File

@ -1,15 +1,16 @@
#ifndef MD5_H
#define MD5_H
#if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__)
typedef unsigned int uint32;
#include "../defines.h"
#ifdef HAVE_stdint_h
#include <stdint.h>
#else
typedef unsigned long uint32;
typedef unsigned int uint32_t;
#endif
struct MD5Context {
uint32 buf[4];
uint32 bits[2];
uint32_t buf[4];
uint32_t bits[2];
unsigned char in[64];
};
@ -17,7 +18,7 @@ void MD5Init(struct MD5Context *context);
void MD5Update(struct MD5Context *context, unsigned char const *buf,
unsigned len);
void MD5Final(unsigned char digest[16], struct MD5Context *context);
void MD5Transform(uint32 buf[4], uint32 const in[16]);
void MD5Transform(uint32_t buf[4], uint32_t const in[16]);
/*
* This is needed to make RSAREF happy on some MS-DOS compilers.

View File

@ -48,6 +48,12 @@ PAM=-lpam -ldl -lpam_misc
PAMFL=-DUSE_PAM=1
endif
ifeq "$(HAVE_SELINUX)" "yes"
CFLAGS += -DWITH_SELINUX=1 -g
SELINUXLLIB=-lselinux
SELINUXOBJS=selinux_utils.o
endif
ifeq "$(HAVE_SHADOW)" "no"
ifeq "$(HAVE_PAM)" "no"
ifeq "$(HAVE_PASSWD)" "no"
@ -96,18 +102,18 @@ shutdown.o simpleinit.o: $(LIB)/linux_reboot.h
wall.o: ttymsg.h $(LIB)/carefulputc.h
agetty: agetty.o $(LIB)/xstrncpy.o
chfn: chfn.o islocal.o setpwnam.o $(LIB)/env.o $(LIB)/xstrncpy.o
$(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM)
chsh: chsh.o islocal.o setpwnam.o $(LIB)/env.o
$(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM)
chfn: chfn.o islocal.o setpwnam.o $(SELINUXOBJS) $(LIB)/env.o $(LIB)/xstrncpy.o
$(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM) $(SELINUXLLIB)
chsh: chsh.o islocal.o setpwnam.o $(SELINUXOBJS) $(LIB)/env.o
$(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM) $(SELINUXLLIB)
last: last.o
ifeq "$(HAVE_PAM)" "yes"
login: login.o $(LIB)/setproctitle.o $(LIB)/xstrncpy.o
$(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM)
$(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(PAM) $(SELINUXLLIB)
else
login: login.o $(LIB)/xstrncpy.o $(LIB)/setproctitle.o checktty.o
$(CC) $(LDFLAGS) -o $@ $^ $(CRYPT)
$(CC) $(LDFLAGS) -o $@ $^ $(CRYPT) $(SELINUXLLIB)
endif
mesg: mesg.o $(ERR_O)
@ -124,6 +130,7 @@ initctl: initctl.o
$(CC) $(LDFLAGS) -o $@ $^
vipw: vipw.o $(LIB)/xstrncpy.o
$(CC) $(LDFLAGS) -o $@ $^ $(SELINUXLLIB)
newgrp.o: $(LIB)/pathnames.h
$(CC) -c $(CFLAGS) $(PAMFL) newgrp.c

View File

@ -40,6 +40,12 @@
#include "nls.h"
#include "env.h"
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#include <selinux/av_permissions.h>
#include "selinux_utils.h"
#endif
#if REQUIRE_PASSWORD && USE_PAM
#include <security/pam_appl.h>
#include <security/pam_misc.h>
@ -136,6 +142,27 @@ int main (int argc, char **argv) {
exit(1);
}
#ifdef WITH_SELINUX
if (is_selinux_enabled()) {
if(uid == 0) {
if (checkAccess(oldf.username,PASSWD__CHFN)!=0) {
security_context_t user_context;
if (getprevcon(&user_context) < 0)
user_context=(security_context_t) strdup(_("Unknown user context"));
fprintf(stderr, _("%s: %s is not authorized to change the finger info of %s\n"),
whoami, user_context, oldf.username);
freecon(user_context);
exit(1);
}
}
if (setupDefaultContext("/etc/passwd") != 0) {
fprintf(stderr,_("%s: Can't set default context for /etc/passwd"),
whoami);
exit(1);
}
}
#endif
/* Reality check */
if (uid != 0 && uid != oldf.pw->pw_uid) {
errno = EACCES;

View File

@ -47,6 +47,12 @@
#include <security/pam_misc.h>
#endif
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#include <selinux/av_permissions.h>
#include "selinux_utils.h"
#endif
typedef unsigned char boolean;
#define false 0
#define true 1
@ -121,6 +127,27 @@ main (int argc, char *argv[]) {
exit(1);
}
#ifdef WITH_SELINUX
if (is_selinux_enabled()) {
if(uid == 0) {
if (checkAccess(pw->pw_name,PASSWD__CHSH)!=0) {
security_context_t user_context;
if (getprevcon(&user_context) < 0)
user_context=(security_context_t) strdup(_("Unknown user context"));
fprintf(stderr, _("%s: %s is not authorized to change the shell of %s\n"),
whoami, user_context, pw->pw_name);
freecon(user_context);
exit(1);
}
}
if (setupDefaultContext("/etc/passwd") != 0) {
fprintf(stderr,_("%s: Can't set default context for /etc/passwd"),
whoami);
exit(1);
}
}
#endif
oldshell = pw->pw_shell;
if (!oldshell[0]) oldshell = "/bin/sh";

View File

@ -906,9 +906,8 @@ Michael Riepe <michael@stud.uni-hannover.de>
if (utp == NULL) {
setutent();
ut.ut_type = LOGIN_PROCESS;
strncpy(ut.ut_id, tty_number, sizeof(ut.ut_id));
strncpy(ut.ut_line, tty_name, sizeof(ut.ut_line));
utp = getutid(&ut);
utp = getutline(&ut);
}
if (utp) {
@ -1363,15 +1362,17 @@ dolastlog(int quiet) {
if (!quiet) {
if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
ll.ll_time != 0) {
printf(_("Last login: %.*s "),
24-5, (char *)ctime(&ll.ll_time));
time_t ll_time = (time_t) ll.ll_time;
printf(_("Last login: %.*s "),
24-5, ctime(&ll_time));
if (*ll.ll_host != '\0')
printf(_("from %.*s\n"),
(int)sizeof(ll.ll_host), ll.ll_host);
else
printf(_("on %.*s\n"),
(int)sizeof(ll.ll_line), ll.ll_line);
if (*ll.ll_host != '\0')
printf(_("from %.*s\n"),
(int)sizeof(ll.ll_host), ll.ll_host);
else
printf(_("on %.*s\n"),
(int)sizeof(ll.ll_line), ll.ll_line);
}
lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
}

View File

@ -0,0 +1,55 @@
#ifdef WITH_SELINUX
#include <sys/types.h>
#include <stdio.h>
#include <selinux/selinux.h>
#include <selinux/flask.h>
#include <selinux/av_permissions.h>
#include <selinux/context.h>
#include "selinux_utils.h"
int checkAccess(char *chuser, int access) {
int status=-1;
security_context_t user_context;
char *user=NULL;
if( getprevcon(&user_context)==0 ) {
context_t c=context_new(user_context);
user=context_user_get(c);
if (strcmp(chuser, user) == 0) {
status=0;
} else {
struct av_decision avd;
int retval = security_compute_av(user_context,
user_context,
SECCLASS_PASSWD,
access,
&avd);
if ((retval == 0) &&
((access & avd.allowed) == access)) {
status=0;
}
}
context_free(c);
freecon(user_context);
}
return status;
}
int setupDefaultContext(char *orig_file) {
if (is_selinux_enabled()) {
security_context_t scontext;
if (getfilecon(orig_file,&scontext)<0) {
return 1;
}
if (setfscreatecon(scontext) < 0)
{
freecon(scontext);
return 1;
}
freecon(scontext);
}
return 0;
}
#endif

View File

@ -0,0 +1,2 @@
extern int checkAccess(char *name,int access);
extern int setupDefaultContext(char *orig_file);

View File

@ -67,6 +67,10 @@ static char version_string[] = "vipw 1.4";
#include "xstrncpy.h"
#include "nls.h"
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif
#define FILENAMELEN 67
char *progname;
@ -189,6 +193,24 @@ pw_unlock(void) {
sprintf(tmp, "%s%s", orig_file, ".OLD");
unlink(tmp);
link(orig_file, tmp);
#ifdef WITH_SELINUX
if (is_selinux_enabled()) {
security_context_t passwd_context=NULL;
int ret=0;
if (getfilecon(orig_file,&passwd_context) < 0) {
(void) fprintf(stderr,_("%s: Can't get context for %s"),progname,orig_file);
pw_error(orig_file, 1, 1);
}
ret=setfilecon(tmp_file,passwd_context);
freecon(passwd_context);
if (ret!=0) {
(void) fprintf(stderr,_("%s: Can't set context for %s"),progname,tmp_file);
pw_error(tmp_file, 1, 1);
}
}
#endif
if (rename(tmp_file, orig_file) == -1) {
int errsv = errno;
fprintf(stderr,
@ -266,7 +288,9 @@ edit_file(int is_shadow)
if (stat(tmp_file, &begin))
pw_error(tmp_file, 1, 1);
pw_edit(0);
if (stat(tmp_file, &end))
pw_error(tmp_file, 1, 1);
if (begin.st_mtime == end.st_mtime) {

View File

@ -111,7 +111,8 @@ reverse).
Turns underline mode on or off (see \fB\-ulcolor\fP).
.TP
.BR \-store " (virtual consoles only)"
Stores the terminal's current rendering options as the default values.
Stores the terminal's current rendering options (foreground and
background colors) as the values to be used at reset-to-default.
.TP
.BR \-clear " [" all ]
Clears the screen and "homes" the cursor, as

View File

@ -1085,7 +1085,7 @@ perform_sequence(int vcterm) {
result = klogctl(6, NULL, 0);
if (result != 0)
printf(_("klogctl error: %s\n"), strerror(result));
printf(_("klogctl error: %s\n"), strerror(errno));
}
/* -msglevel [0-8] */
@ -1093,7 +1093,7 @@ perform_sequence(int vcterm) {
/* 8 -- Set level of messages printed to console */
result = klogctl(8, NULL, opt_msglevel_num);
if (result != 0)
printf(_("klogctl error: %s\n"), strerror(result));
printf(_("klogctl error: %s\n"), strerror(errno));
}
/* -blength [0-2000] */

View File

@ -72,7 +72,7 @@ mount.o: $(LIB)/setproctitle.h
mount.o umount.o getusername.o: getusername.h
mount.o umount.o losetup.o lomount.o: lomount.h loop.h
mount.o umount.o losetup.o lomount.o: lomount.h loop.h my_dev_t.h
swapon.o: swap_constants.h swapargs.h
@ -118,12 +118,9 @@ nfsmount.o: nfs_mount4.h
swapargs.h:
sh swap.configure
loop.h:
sh mk_loop_h
clean:
rm -f a.out core *~ *.o swapargs.h $(PROGS) $(MAYBE)
rm -f loop.h nfs_mountversion.h
rm -f nfs_mountversion.h
clobber distclean realclean: clean
rm -f $(GEN_FILES)

View File

@ -100,7 +100,7 @@ read_mntentchn(mntFILE *mfp, const char *fnam, struct mntentchn *mc0) {
struct mntent *mnt;
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->prev = mc;
mc = mc->nxt;
@ -179,30 +179,62 @@ getmntfile (const char *name) {
mc0 = mtab_head();
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
if (streq (mc->m.mnt_dir, name) ||
streq (mc->m.mnt_fsname, name))
if (streq(mc->m.mnt_dir, name) ||
streq(mc->m.mnt_fsname, name))
return mc;
return NULL;
}
/*
* Given the name NAME, and the place MCPREV we found it last time,
* Given the directory name NAME, and the place MCPREV we found it last time,
* try to find more occurrences.
*/
struct mntentchn *
getmntfilesbackward (const char *name, struct mntentchn *mcprev) {
getmntdirbackward (const char *name, struct mntentchn *mcprev) {
struct mntentchn *mc, *mc0;
mc0 = mtab_head();
if (!mcprev)
mcprev = mc0;
for (mc = mcprev->prev; mc && mc != mc0; mc = mc->prev)
if (streq (mc->m.mnt_dir, name) ||
streq (mc->m.mnt_fsname, name))
if (streq(mc->m.mnt_dir, name))
return mc;
return NULL;
}
/*
* Given the device name NAME, and the place MCPREV we found it last time,
* try to find more occurrences.
*/
struct mntentchn *
getmntdevbackward (const char *name, struct mntentchn *mcprev) {
struct mntentchn *mc, *mc0;
mc0 = mtab_head();
if (!mcprev)
mcprev = mc0;
for (mc = mcprev->prev; mc && mc != mc0; mc = mc->prev)
if (streq(mc->m.mnt_fsname, name))
return mc;
return NULL;
}
/*
* Given the name NAME, check that it occurs precisely once as dir or dev.
*/
int
is_mounted_once(const char *name) {
struct mntentchn *mc, *mc0;
int ct = 0;
mc0 = mtab_head();
for (mc = mc0->prev; mc && mc != mc0; mc = mc->prev)
if (streq(mc->m.mnt_dir, name) ||
streq(mc->m.mnt_fsname, name))
ct++;
return (ct == 1);
}
/* Given the name FILE, try to find the option "loop=FILE" in mtab. */
struct mntentchn *
getmntoptfile (const char *file) {
@ -253,29 +285,29 @@ getfsspecfile (const char *spec, const char *file) {
/* first attempt: names occur precisely as given */
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
if (streq (mc->m.mnt_dir, file) &&
streq (mc->m.mnt_fsname, spec))
if (streq(mc->m.mnt_dir, file) &&
streq(mc->m.mnt_fsname, spec))
return mc;
/* second attempt: names found after symlink resolution */
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
if ((streq (mc->m.mnt_dir, file) ||
streq (canonicalize(mc->m.mnt_dir), file))
&& (streq (mc->m.mnt_fsname, spec) ||
streq (canonicalize(mc->m.mnt_fsname), spec)))
if ((streq(mc->m.mnt_dir, file) ||
streq(canonicalize(mc->m.mnt_dir), file))
&& (streq(mc->m.mnt_fsname, spec) ||
streq(canonicalize(mc->m.mnt_fsname), spec)))
return mc;
/* third attempt: names found after LABEL= or UUID= resolution */
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) {
if (!strncmp (mc->m.mnt_fsname, "LABEL=", 6) &&
(streq (mc->m.mnt_dir, file) ||
streq (canonicalize(mc->m.mnt_dir), file))) {
(streq(mc->m.mnt_dir, file) ||
streq(canonicalize(mc->m.mnt_dir), file))) {
if (has_label(spec, mc->m.mnt_fsname+6))
return mc;
}
if (!strncmp (mc->m.mnt_fsname, "UUID=", 5) &&
(streq (mc->m.mnt_dir, file) ||
streq (canonicalize(mc->m.mnt_dir), file))) {
(streq(mc->m.mnt_dir, file) ||
streq(canonicalize(mc->m.mnt_dir), file))) {
if (has_uuid(spec, mc->m.mnt_fsname+5))
return mc;
}
@ -290,7 +322,7 @@ getfsfile (const char *file) {
mc0 = fstab_head();
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
if (streq (mc->m.mnt_dir, file))
if (streq(mc->m.mnt_dir, file))
return mc;
return NULL;
}
@ -302,7 +334,7 @@ getfsspec (const char *spec) {
mc0 = fstab_head();
for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt)
if (streq (mc->m.mnt_fsname, spec))
if (streq(mc->m.mnt_fsname, spec))
return mc;
return NULL;
}
@ -531,7 +563,7 @@ update_mtab (const char *dir, struct mntent *instead) {
/* find last occurrence of dir */
for (mc = mc0->prev; mc && mc != mc0; mc = mc->prev)
if (streq (mc->m.mnt_dir, dir))
if (streq(mc->m.mnt_dir, dir))
break;
if (mc && mc != mc0) {
if (instead == NULL) {

View File

@ -12,6 +12,7 @@
int mtab_is_writable(void);
int mtab_does_not_exist(void);
int mtab_is_a_symlink(void);
int is_mounted_once(const char *name);
struct mntentchn {
struct mntentchn *nxt, *prev;
@ -21,7 +22,8 @@ struct mntentchn {
struct mntentchn *mtab_head (void);
struct mntentchn *getmntfile (const char *name);
struct mntentchn *getmntoptfile (const char *file);
struct mntentchn *getmntfilesbackward (const char *file, struct mntentchn *mc);
struct mntentchn *getmntdirbackward (const char *dir, struct mntentchn *mc);
struct mntentchn *getmntdevbackward (const char *dev, struct mntentchn *mc);
struct mntentchn *fstab_head (void);
struct mntentchn *getfsfile (const char *file);

View File

@ -1,37 +0,0 @@
/*
* include/linux/loop.h
*
* Written by Theodore Ts'o, 3/29/93.
*
* Copyright 1993 by Theodore Ts'o. Redistribution of this file is
* permitted under the GNU Public License.
*/
#define LO_NAME_SIZE 64
#define LO_KEY_SIZE 32
struct loop_info {
int lo_number; /* ioctl r/o */
dev_t lo_device; /* ioctl r/o */
unsigned long lo_inode; /* ioctl r/o */
dev_t lo_rdevice; /* ioctl r/o */
int lo_offset;
int lo_encrypt_type;
int lo_encrypt_key_size; /* ioctl w/o */
int lo_flags; /* ioctl r/o */
char lo_name[LO_NAME_SIZE];
unsigned char lo_encrypt_key[LO_KEY_SIZE]; /* ioctl w/o */
unsigned long lo_init[2];
char reserved[4];
};
#define LO_CRYPT_NONE 0
#define LO_CRYPT_XOR 1
#define LO_CRYPT_DES 2
#define LO_CRYPT_IDEA 3
#define MAX_LO_CRYPT 4
#define LOOP_SET_FD 0x4C00
#define LOOP_CLR_FD 0x4C01
#define LOOP_SET_STATUS 0x4C02
#define LOOP_GET_STATUS 0x4C03

View File

@ -221,6 +221,42 @@ struct ocfs_volume_label {
#define ocfslabellen(o) assemble2le(o.label_len)
#define OCFS_MAGIC "OracleCFS"
struct efs_volume_directory { /* size 16 */
char vd_name[8];
char vd_lbn[4];
char vd_nbytes[4];
};
struct efs_partition_table { /* size 12 */
char pt_nblks[4];
char pt_firstlbn[4];
char pt_type[4];
};
struct efs_volume_header { /* size 512 */
char vh_magic[4];
short vh_rootpt;
short vh_swappt;
char vh_bootfile[16];
char pad[48];
struct efs_volume_directory vh_vd[15];
struct efs_partition_table vh_pt[16];
int vh_csum;
int vh_fill;
};
struct efs_super {
char fs_stuff[512+28];
char fs_magic[4];
char fs_fname[6];
char fs_fpack[6];
/* ... */
};
#define EFS_VHMAGIC 0x0be5a941 /* big endian */
#define EFS_SBMAGIC 0x00072959 /* idem */
#define EFS_SBMAGIC2 0x0007295a /* idem */
static inline int
assemble2le(unsigned char *p) {
return (p[0] | (p[1] << 8));

View File

@ -2,13 +2,18 @@
/* Added vfs mount options - aeb - 960223 */
/* Removed lomount - aeb - 960224 */
/* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
/*
* 1999-02-22 Arkadiusz Mikiewicz <misiek@pld.ORG.PL>
* - added Native Language Support
* Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* 1999-03-21 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* - fixed strerr(errno) in gettext calls
* 2000-09-24 Marc Mutz <Marc@Mutz.com>
* - added -p option to pass passphrases via fd's to losetup/mount.
* Used for encryption in non-interactive environments.
* The idea behind xgetpass() is stolen from GnuPG, v.1.0.3.
*/
#define PROC_DEVICES "/proc/devices"
#define LOOPMAJOR 7
/*
* losetup.c - setup and control loop devices
@ -36,93 +41,114 @@ extern char *xstrdup (const char *s); /* not: #include "sundries.h" */
extern void error (const char *fmt, ...); /* idem */
#ifdef LOOP_SET_FD
struct crypt_type_struct {
int id;
char *name;
} crypt_type_tbl[] = {
{ LO_CRYPT_NONE, "no" },
{ LO_CRYPT_NONE, "none" },
{ LO_CRYPT_XOR, "xor" },
{ LO_CRYPT_DES, "DES" },
{ -1, NULL }
};
static int
crypt_type (const char *name) {
int i;
static int
loop_info64_to_old(const struct loop_info64 *info64, struct loop_info *info)
{
memset(info, 0, sizeof(*info));
info->lo_number = info64->lo_number;
info->lo_device = info64->lo_device;
info->lo_inode = info64->lo_inode;
info->lo_rdevice = info64->lo_rdevice;
info->lo_offset = info64->lo_offset;
info->lo_encrypt_type = info64->lo_encrypt_type;
info->lo_encrypt_key_size = info64->lo_encrypt_key_size;
info->lo_flags = info64->lo_flags;
info->lo_init[0] = info64->lo_init[0];
info->lo_init[1] = info64->lo_init[1];
if (info->lo_encrypt_type == LO_CRYPT_CRYPTOAPI)
memcpy(info->lo_name, info64->lo_crypt_name, LO_NAME_SIZE);
else
memcpy(info->lo_name, info64->lo_file_name, LO_NAME_SIZE);
memcpy(info->lo_encrypt_key, info64->lo_encrypt_key, LO_KEY_SIZE);
if (name) {
for (i = 0; crypt_type_tbl[i].id != -1; i++)
if (!strcasecmp (name, crypt_type_tbl[i].name))
return crypt_type_tbl[i].id;
}
return -1;
/* error in case values were truncated */
if (info->lo_device != info64->lo_device ||
info->lo_rdevice != info64->lo_rdevice ||
info->lo_inode != info64->lo_inode ||
info->lo_offset != info64->lo_offset)
return -EOVERFLOW;
return 0;
}
#ifdef MAIN
static char *
crypt_name (int id) {
int i;
for (i = 0; crypt_type_tbl[i].id != -1; i++)
if (id == crypt_type_tbl[i].id)
return crypt_type_tbl[i].name;
return "undefined";
}
static int
show_loop (char *device) {
show_loop(char *device) {
struct loop_info loopinfo;
int fd;
struct loop_info64 loopinfo64;
int fd, errsv;
if ((fd = open (device, O_RDONLY)) < 0) {
if ((fd = open(device, O_RDONLY)) < 0) {
int errsv = errno;
fprintf(stderr, _("loop: can't open device %s: %s\n"),
device, strerror (errsv));
return 2;
}
if (ioctl (fd, LOOP_GET_STATUS, &loopinfo) < 0) {
int errsv = errno;
fprintf(stderr, _("loop: can't get info on device %s: %s\n"),
device, strerror (errsv));
close (fd);
return 1;
}
printf (_("%s: [%04x]:%ld (%s) offset %d, %s encryption\n"),
device, loopinfo.lo_device, loopinfo.lo_inode,
loopinfo.lo_name, loopinfo.lo_offset,
crypt_name (loopinfo.lo_encrypt_type));
close (fd);
return 0;
if (ioctl(fd, LOOP_GET_STATUS64, &loopinfo64) == 0) {
loopinfo64.lo_file_name[LO_NAME_SIZE-2] = '*';
loopinfo64.lo_file_name[LO_NAME_SIZE-1] = 0;
loopinfo64.lo_crypt_name[LO_NAME_SIZE-1] = 0;
printf("%s: [%04llx]:%llu (%s)",
device, loopinfo64.lo_device, loopinfo64.lo_inode,
loopinfo64.lo_file_name);
if (loopinfo64.lo_offset)
printf(_(", offset %lld"), loopinfo64.lo_offset);
if (loopinfo64.lo_sizelimit)
printf(_(", sizelimit %lld"), loopinfo64.lo_sizelimit);
if (loopinfo64.lo_encrypt_type ||
loopinfo64.lo_crypt_name[0]) {
char *e = loopinfo64.lo_crypt_name;
if (*e == 0 && loopinfo64.lo_encrypt_type == 1)
e = "XOR";
printf(_(", encryption %s (type %d)"),
e, loopinfo64.lo_encrypt_type);
}
printf("\n");
close (fd);
return 0;
}
if (ioctl(fd, LOOP_GET_STATUS, &loopinfo) == 0) {
printf ("%s: [%04x]:%ld (%s)",
device, loopinfo.lo_device, loopinfo.lo_inode,
loopinfo.lo_name);
if (loopinfo.lo_offset)
printf(_(", offset %d"), loopinfo.lo_offset);
if (loopinfo.lo_encrypt_type)
printf(_(", encryption type %d\n"),
loopinfo.lo_encrypt_type);
printf("\n");
close (fd);
return 0;
}
errsv = errno;
fprintf(stderr, _("loop: can't get info on device %s: %s\n"),
device, strerror (errsv));
close (fd);
return 1;
}
#endif
int
is_loop_device (const char *device) {
struct stat statbuf;
int loopmajor;
#if 1
loopmajor = 7;
#else
FILE *procdev;
char line[100], *cp;
loopmajor = 0;
if ((procdev = fopen(PROC_DEVICES, "r")) != NULL) {
while (fgets (line, sizeof(line), procdev)) {
if ((cp = strstr (line, " loop\n")) != NULL) {
*cp='\0';
loopmajor=atoi(line);
break;
}
}
fclose(procdev);
}
#endif
return (loopmajor && stat(device, &statbuf) == 0 &&
return (stat(device, &statbuf) == 0 &&
S_ISBLK(statbuf.st_mode) &&
major(statbuf.st_rdev) == loopmajor);
major(statbuf.st_rdev) == LOOPMAJOR);
}
#define SIZE(a) (sizeof(a)/sizeof(a[0]))
@ -134,10 +160,9 @@ find_unused_loop_device (void) {
So, we just try /dev/loop[0-7]. */
char dev[20];
char *loop_formats[] = { "/dev/loop%d", "/dev/loop/%d" };
int i, j, fd, somedev = 0, someloop = 0, loop_known = 0;
int i, j, fd, somedev = 0, someloop = 0;
struct stat statbuf;
struct loop_info loopinfo;
FILE *procdev;
for (j = 0; j < SIZE(loop_formats); j++) {
for(i = 0; i < 256; i++) {
@ -160,73 +185,103 @@ find_unused_loop_device (void) {
}
}
/* Nothing found. Why not? */
if ((procdev = fopen(PROC_DEVICES, "r")) != NULL) {
char line[100];
while (fgets (line, sizeof(line), procdev))
if (strstr (line, " loop\n")) {
loop_known = 1;
break;
}
fclose(procdev);
if (!loop_known)
loop_known = -1;
}
if (!somedev)
error(_("mount: could not find any device /dev/loop#"));
else if (!someloop) {
if (loop_known == 1)
error(_(
"mount: Could not find any loop device.\n"
" Maybe /dev/loop# has a wrong major number?"));
else if (loop_known == -1)
error(_(
"mount: Could not find any loop device, and, according to %s,\n"
" this kernel does not know about the loop device.\n"
" (If so, then recompile or `insmod loop.o'.)"),
PROC_DEVICES);
else
error(_(
"mount: Could not find any loop device. Maybe this kernel does not know\n"
" about the loop device (then recompile or `insmod loop.o'), or\n"
" maybe /dev/loop# has the wrong major number?"));
"mount: Could not find any loop device. Maybe this kernel "
"does not know\n"
" about the loop device? (If so, recompile or "
"`modprobe loop'.)"));
} else
error(_("mount: could not find any free loop device"));
return 0;
}
/*
* A function to read the passphrase either from the terminal or from
* an open file descriptor.
*/
static char *
xgetpass(int pfd, const char *prompt) {
char *pass;
int buflen, i;
if (pfd < 0) /* terminal */
return getpass(prompt);
pass = NULL;
buflen = 0;
for (i=0; ; i++) {
if (i >= buflen-1) {
/* we're running out of space in the buffer.
* Make it bigger: */
char *tmppass = pass;
buflen += 128;
pass = realloc(tmppass, buflen);
if (pass == NULL) {
/* realloc failed. Stop reading. */
error("Out of memory while reading passphrase");
pass = tmppass; /* the old buffer hasn't changed */
break;
}
}
if (read(pfd, pass+i, 1) != 1 || pass[i] == '\n')
break;
}
if (pass == NULL)
return "";
else {
pass[i] = 0;
return pass;
}
}
static int
digits_only(const char *s) {
while (*s)
if (!isdigit(*s++))
return 0;
return 1;
}
int
set_loop (const char *device, const char *file, int offset,
const char *encryption, int *loopro) {
struct loop_info loopinfo;
int fd, ffd, mode, i;
set_loop(const char *device, const char *file, int offset,
const char *encryption, int pfd, int *loopro) {
struct loop_info64 loopinfo64;
int fd, ffd, mode;
char *pass;
mode = (*loopro ? O_RDONLY : O_RDWR);
if ((ffd = open (file, mode)) < 0) {
if ((ffd = open(file, mode)) < 0) {
if (!*loopro && errno == EROFS)
ffd = open (file, mode = O_RDONLY);
ffd = open(file, mode = O_RDONLY);
if (ffd < 0) {
perror (file);
perror(file);
return 1;
}
}
if ((fd = open (device, mode)) < 0) {
if ((fd = open(device, mode)) < 0) {
perror (device);
return 1;
}
*loopro = (mode == O_RDONLY);
memset (&loopinfo, 0, sizeof (loopinfo));
xstrncpy (loopinfo.lo_name, file, LO_NAME_SIZE);
if (encryption && (loopinfo.lo_encrypt_type = crypt_type (encryption))
< 0) {
fprintf (stderr, _("Unsupported encryption type %s\n"),
encryption);
return 1;
memset(&loopinfo64, 0, sizeof(loopinfo64));
xstrncpy(loopinfo64.lo_file_name, file, LO_NAME_SIZE);
if (encryption && *encryption) {
if (digits_only(encryption)) {
loopinfo64.lo_encrypt_type = atoi(encryption);
} else {
loopinfo64.lo_encrypt_type = LO_CRYPT_CRYPTOAPI;
snprintf(loopinfo64.lo_crypt_name, LO_NAME_SIZE,
"%s", encryption);
}
}
loopinfo.lo_offset = offset;
loopinfo64.lo_offset = offset;
#ifdef MCL_FUTURE
/*
@ -241,53 +296,55 @@ set_loop (const char *device, const char *file, int offset,
}
#endif
switch (loopinfo.lo_encrypt_type) {
switch (loopinfo64.lo_encrypt_type) {
case LO_CRYPT_NONE:
loopinfo.lo_encrypt_key_size = 0;
loopinfo64.lo_encrypt_key_size = 0;
break;
case LO_CRYPT_XOR:
pass = getpass (_("Password: "));
xstrncpy (loopinfo.lo_encrypt_key, pass, LO_KEY_SIZE);
loopinfo.lo_encrypt_key_size = strlen(loopinfo.lo_encrypt_key);
break;
case LO_CRYPT_DES:
pass = getpass (_("Password: "));
strncpy (loopinfo.lo_encrypt_key, pass, 8);
loopinfo.lo_encrypt_key[8] = 0;
loopinfo.lo_encrypt_key_size = 8;
pass = getpass (_("Init (up to 16 hex digits): "));
for (i = 0; i < 16 && pass[i]; i++)
if (isxdigit (pass[i])) {
loopinfo.lo_init[i >> 3] |= (pass[i] > '9' ?
(islower (pass[i]) ? toupper (pass[i]) :
pass[i])-'A'+10 : pass[i]-'0') << (i&7) * 4;
} else {
fprintf (stderr, _("Non-hex digit '%c'.\n"),
pass[i]);
return 1;
}
pass = getpass(_("Password: "));
xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
loopinfo64.lo_encrypt_key_size =
strlen(loopinfo64.lo_encrypt_key);
break;
default:
fprintf (stderr,
_("Don't know how to get key for encryption system %d\n"),
loopinfo.lo_encrypt_type);
pass = xgetpass(pfd, _("Password: "));
xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;
}
if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
perror("ioctl: LOOP_SET_FD");
return 1;
}
if (ioctl (fd, LOOP_SET_FD, ffd) < 0) {
perror ("ioctl: LOOP_SET_FD");
return 1;
}
if (ioctl (fd, LOOP_SET_STATUS, &loopinfo) < 0) {
(void) ioctl (fd, LOOP_CLR_FD, 0);
perror ("ioctl: LOOP_SET_STATUS");
return 1;
}
close (fd);
close (ffd);
if (ioctl(fd, LOOP_SET_STATUS64, &loopinfo64) < 0) {
struct loop_info loopinfo;
int errsv = errno;
errno = loop_info64_to_old(&loopinfo64, &loopinfo);
if (errno) {
errno = errsv;
perror("ioctl: LOOP_SET_STATUS64");
goto fail;
}
if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) {
perror("ioctl: LOOP_SET_STATUS");
goto fail;
}
}
close (fd);
if (verbose > 1)
printf(_("set_loop(%s,%s,%d): success\n"),
device, file, offset);
return 0;
fail:
(void) ioctl (fd, LOOP_CLR_FD, 0);
close (fd);
return 1;
}
int
@ -388,29 +445,34 @@ error (const char *fmt, ...) {
int
main(int argc, char **argv) {
char *offset, *encryption;
int delete,off,c;
char *offset, *encryption, *passfd;
int delete, off, c;
int res = 0;
int ro = 0;
int pfd = -1;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
delete = off = 0;
offset = encryption = NULL;
offset = encryption = passfd = NULL;
progname = argv[0];
while ((c = getopt(argc,argv,"de:o:v")) != -1) {
while ((c = getopt(argc,argv,"de:E:o:p:v")) != -1) {
switch (c) {
case 'd':
delete = 1;
break;
case 'E':
case 'e':
encryption = optarg;
break;
case 'o':
offset = optarg;
break;
case 'p':
passfd = optarg;
break;
case 'v':
verbose = 1;
break;
@ -430,7 +492,10 @@ main(int argc, char **argv) {
} else {
if (offset && sscanf(offset,"%d",&off) != 1)
usage();
res = set_loop(argv[optind],argv[optind+1],off,encryption,&ro);
if (passfd && sscanf(passfd,"%d",&pfd) != 1)
usage();
res = set_loop(argv[optind], argv[optind+1], off,
encryption, pfd, &ro);
}
return res;
}

View File

@ -1,5 +1,6 @@
extern int verbose;
extern int set_loop (const char *, const char *, int, const char *, int *);
extern int del_loop (const char *);
extern int is_loop_device (const char *);
extern char * find_unused_loop_device (void);
extern int set_loop(const char *, const char *, int, const char *,
int, int *);
extern int del_loop(const char *);
extern int is_loop_device(const char *);
extern char * find_unused_loop_device(void);

51
mount/loop.h Normal file
View File

@ -0,0 +1,51 @@
#define LO_CRYPT_NONE 0
#define LO_CRYPT_XOR 1
#define LO_CRYPT_DES 2
#define LO_CRYPT_CRYPTOAPI 18
#define LOOP_SET_FD 0x4C00
#define LOOP_CLR_FD 0x4C01
#define LOOP_SET_STATUS 0x4C02
#define LOOP_GET_STATUS 0x4C03
#define LOOP_SET_STATUS64 0x4C04
#define LOOP_GET_STATUS64 0x4C05
#define LO_NAME_SIZE 64
#define LO_KEY_SIZE 32
#include "my_dev_t.h"
struct loop_info {
int lo_number;
my_dev_t lo_device;
unsigned long lo_inode;
my_dev_t lo_rdevice;
int lo_offset;
int lo_encrypt_type;
int lo_encrypt_key_size;
int lo_flags;
char lo_name[LO_NAME_SIZE];
unsigned char lo_encrypt_key[LO_KEY_SIZE];
unsigned long lo_init[2];
char reserved[4];
};
/*
* Where to get __u8, __u32, __u64? Let us use unsigned char/int/long long
* and get punished when someone comes with 128-bit long longs.
*/
struct loop_info64 {
unsigned long long lo_device;
unsigned long long lo_inode;
unsigned long long lo_rdevice;
unsigned long long lo_offset;
unsigned long long lo_sizelimit; /* bytes, 0 == max available */
unsigned int lo_number;
unsigned int lo_encrypt_type;
unsigned int lo_encrypt_key_size;
unsigned int lo_flags;
unsigned char lo_file_name[LO_NAME_SIZE];
unsigned char lo_crypt_name[LO_NAME_SIZE];
unsigned char lo_encrypt_key[LO_KEY_SIZE];
unsigned long long lo_init[2];
};

View File

@ -1,15 +1,18 @@
.TH LOSETUP 8 "Nov 24 1993" "Linux" "MAINTENANCE COMMANDS"
.TH LOSETUP 8 "2003-07-01" "Linux" "MAINTENANCE COMMANDS"
.SH NAME
losetup \- set up and control loop devices
.SH SYNOPSIS
.ad l
.B losetup
[
.B \-e
.RB [ \-e | \-E ]
.I encryption
] [
.B \-o
.I offset
] [
.B \-p
.I pfd
]
.I loop_device file
.br
@ -25,27 +28,41 @@ is used to associate loop devices with regular files or block devices,
to detach loop devices and to query the status of a loop device. If only the
\fIloop_device\fP argument is given, the status of the corresponding loop
device is shown.
.SS "Encryption"
It is possible to specify transfer functions (for encryption/decryption
or other purposes) using one of the
.B \-E
and
.B \-e
options.
There are two mechanisms to specify the desired encryption: by number
and by name. If an encryption is specified by number then one
has to make sure that the Linux kernel knows about the encryption with that
number, probably by patching the kernel. Standard numbers that are
always present are 0 (no encryption) and 1 (XOR encryption).
When the cryptoloop module is loaded (or compiled in), it uses number 18.
This cryptoloop module wil take the name of an arbitrary encryption type
and finds the module that knows how to perform that encryption.
(Thus, either one uses a number different from 18 with the
.B \-E
option, or one uses a name with the
.B \-e
option.)
.SH OPTIONS
.IP \fB\-d\fP
detach the file or device associated with the specified loop device.
.IP "\fB\-e \fIencryption\fP"
.RS
enable data encryption. The following keywords are recognized:
.IP \fBNONE\fP
use no encryption (default).
.PD 0
.IP \fBXOR\fP
use a simple XOR encryption.
.IP \fBDES\fP
use DES encryption. DES encryption is only available if the optional
DES package has been added to the kernel. DES encryption uses an additional
start value that is used to protect passwords against dictionary
attacks.
.PD
.RE
Detach the file or device associated with the specified loop device.
.IP "\fB\-E \fIencryption_type\fP"
Enable data encryption with specified number.
.IP "\fB\-e \fIencryption_name\fP"
Enable data encryption with specified name.
.IP "\fB\-o \fIoffset\fP"
the data start is moved \fIoffset\fP bytes into the specified file or
The data start is moved \fIoffset\fP bytes into the specified file or
device.
.IP "\fB\-p \fInum\fP"
Read the passphrase from file descriptor with number
.I num
instead of from the terminal.
.SH RETURN VALUE
.B losetup
returns 0 on success, nonzero on failure. When
@ -57,7 +74,7 @@ from determining the status of the device.
.SH FILES
.nf
/dev/loop0,/dev/loop1,... loop devices (major=7)
/dev/loop0, /dev/loop1, ... loop devices (major=7)
.fi
.SH EXAMPLE
If you are using the loadable module you must have the module loaded
@ -65,18 +82,23 @@ first with the command
.IP
# insmod loop.o
.LP
Maybe also encryption modules are needed.
.IP
# insmod des.o
# insmod cryptoloop.o
.LP
The following commands can be used as an example of using the loop device.
.nf
.IP
dd if=/dev/zero of=/file bs=1k count=100
losetup -e des /dev/loop0 /file
# dd if=/dev/zero of=/file bs=1k count=100
# losetup -e des /dev/loop0 /file
Password:
Init (up to 16 hex digits):
mkfs -t ext2 /dev/loop0 100
mount -t ext2 /dev/loop0 /mnt
# mkfs -t ext2 /dev/loop0 100
# mount -t ext2 /dev/loop0 /mnt
...
umount /dev/loop0
losetup -d /dev/loop0
# umount /dev/loop0
# losetup -d /dev/loop0
.fi
.LP
If you are using the loadable module you may remove the module with
@ -87,8 +109,8 @@ the command
.fi
.SH RESTRICTION
DES encryption is painfully slow. On the other hand, XOR is terribly weak.
.SH AUTHORS
.nf
Original version: Theodore Ts'o <tytso@athena.mit.edu>
Original DES by: Eric Young <eay@psych.psy.uq.oz.au>
.fi
.\" .SH AUTHORS
.\" .nf
.\" Original version: Theodore Ts'o <tytso@athena.mit.edu>
.\" Original DES by: Eric Young <eay@psych.psy.uq.oz.au>
.\" .fi

View File

@ -1,34 +0,0 @@
#!/bin/sh
#
# Figure out (i) the type of dev_t (ii) the defines for loop stuff
#
rm -f loop.h
# Since 1.3.79 there is an include file <asm/posix_types.h>
# that defines __kernel_dev_t.
# (The file itself appeared in 1.3.78, but there it defined __dev_t.)
# If it exists, we use it, or, rather, <linux/posix_types.h> which
# avoids namespace pollution. Otherwise we guess that __kernel_dev_t
# is an unsigned short (which is true on i386, but false on alpha).
if [ -f /usr/include/linux/posix_types.h ]; then
echo '#include <linux/posix_types.h>' >> loop.h
echo '#undef dev_t' >> loop.h
echo '#define dev_t __kernel_dev_t' >> loop.h
else
echo '#undef dev_t' >> loop.h
echo '#define dev_t unsigned short' >> loop.h
fi
# Next we have to find the loop stuff itself.
# First try kernel source, then a private version.
if [ -f /usr/include/linux/loop.h ]; then
echo '#include <linux/loop.h>' >> loop.h
else
echo '#include "h/loop.h"' >> loop.h
fi
echo '#undef dev_t' >> loop.h

View File

@ -118,6 +118,7 @@ a second place using
.B "mount --rbind olddir newdir"
.RE
.\" available since Linux 2.4.11.
The mount options are not changed.
Since Linux 2.5.1 it is possible to atomically move a subtree
to another place. The call is
@ -315,6 +316,12 @@ This is necessary for example when
.I /etc
is on a read-only file system.
.TP
.BI \-p " num"
In case of a loop mount with encryption, read the passphrase from
file descriptor
.I num
instead of from the terminal.
.TP
.B \-s
Tolerate sloppy mount options rather than failing. This will ignore
mount options not supported by a filesystem type. Not all filesystems
@ -376,6 +383,7 @@ currently supported are:
.IR udf ,
.IR ufs ,
.IR umsdos ,
.IR usbfs ,
.IR vfat ,
.IR xenix ,
.IR xfs ,
@ -390,7 +398,10 @@ instead. Since kernel version 2.1.21 the types
.I ext
and
.I xiafs
do not exist anymore.
do not exist anymore. Earlier,
.I usbfs
was known as
.IR usbdevfs .
For most types all the
.B mount
@ -1479,6 +1490,9 @@ For filesystems created by SunOS or Solaris on Sparc.
.B sunx86
For filesystems created by Solaris on x86.
.TP
.B hp
For filesystems created by HP-UX, read-only.
.TP
.B nextstep
For filesystems created by NeXTStep (on NeXT station) (currently read only).
.TP
@ -1556,7 +1570,7 @@ the short name is not all upper case.
.I win95
Force the short name to upper case upon display; store a long name when
the short name is not all upper case.
. TP
.TP
.I winnt
Display the shortname as is; store a long name when the short name is
not all lower case or all upper case.
@ -1568,6 +1582,21 @@ all upper case.
The default is "lower".
.SH "Mount options for usbfs"
.TP
\fBdevuid=\fP\fIuid\fP and \fBdevgid=\fP\fIgid\fP and \fBdevmode=\fP\fImode\fP
Set the owner and group and mode of the device files in the usbfs file system
(default: uid=gid=0, mode=0644). The mode is given in octal.
.TP
\fBbusuid=\fP\fIuid\fP and \fBbusgid=\fP\fIgid\fP and \fBbusmode=\fP\fImode\fP
Set the owner and group and mode of the bus directories in the usbfs
file system (default: uid=gid=0, mode=0555). The mode is given in octal.
.TP
\fBlistuid=\fP\fIuid\fP and \fBlistgid=\fP\fIgid\fP and \fBlistmode=\fP\fImode\fP
Set the owner and group and mode of the file
.I devices
(default: uid=gid=0, mode=0444). The mode is given in octal.
.SH "Mount options for xenix"
None.

View File

@ -113,6 +113,9 @@ static int mounttype = 0;
/* True if ruid != euid. */
static int suid = 0;
/* Contains the fd to read the passphrase from, if any. */
static int pfd = -1;
/* Map from -o and fstab option strings to the flag argument to mount(2). */
struct opt_map {
const char *opt; /* option name */
@ -601,7 +604,8 @@ loop_check(char **spec, char **type, int *flags,
if (verbose)
printf(_("mount: going to use the loop device %s\n"), *loopdev);
offset = opt_offset ? strtoul(opt_offset, NULL, 0) : 0;
if (set_loop (*loopdev, *loopfile, offset, opt_encryption, &loopro)) {
if (set_loop(*loopdev, *loopfile, offset,
opt_encryption, pfd, &loopro)) {
if (verbose)
printf(_("mount: failed setting up loop device\n"));
return EX_FAIL;
@ -659,6 +663,14 @@ update_mtab_entry(char *spec, char *node, char *type, char *opts,
}
}
static void
set_pfd(char *s) {
if (!isdigit(*s))
die(EX_USAGE,
_("mount: argument to -p or --pass-fd must be a number"));
pfd = atoi(optarg);
}
static void
cdrom_setspeed(char *spec) {
#define CDROM_SELECT_SPEED 0x5322 /* Set the CD-ROM speed */
@ -768,7 +780,7 @@ try_mount_one (const char *spec0, const char *node0, char *types0,
if (mount_all && (flags & MS_NOAUTO))
return 0;
suid_check (spec, node, &flags, &user);
suid_check(spec, node, &flags, &user);
mount_opts = extra_opts;
@ -776,11 +788,12 @@ try_mount_one (const char *spec0, const char *node0, char *types0,
cdrom_setspeed(spec);
if (!(flags & MS_REMOUNT)) {
/* don't set up a (new) loop device if we only remount - this left
/*
* Don't set up a (new) loop device if we only remount - this left
* stale assignments of files to loop devices. Nasty when used for
* encryption.
*/
res = loop_check (&spec, &types, &flags, &loop, &loopdev, &loopfile);
res = loop_check(&spec, &types, &flags, &loop, &loopdev, &loopfile);
if (res)
return res;
}
@ -841,7 +854,7 @@ retry_nfs:
#ifdef HAVE_NFS
if (mnt_err && types && streq (types, "nfs")) {
if (nfs_mount_version == 4) {
if (nfs_mount_version == 4 && mnt_err != EBUSY && mnt_err != ENOENT) {
if (verbose)
printf(_("mount: failed with nfs mount version 4, trying 3..\n"));
nfs_mount_version = 3;
@ -912,7 +925,7 @@ retry_nfs:
break;
case EINVAL:
{ int fd;
long size;
unsigned long size;
int warned=0;
if (flags & MS_REMOUNT) {
@ -922,9 +935,9 @@ retry_nfs:
" or too many mounted file systems"),
spec);
if (stat (spec, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)
if (stat(spec, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)
&& (fd = open(spec, O_RDONLY | O_NONBLOCK)) >= 0) {
if(ioctl(fd, BLKGETSIZE, &size) == 0) {
if (ioctl(fd, BLKGETSIZE, &size) == 0) {
if (size == 0) {
warned++;
error (" (could this be the IDE device where you in fact use\n"
@ -1357,6 +1370,7 @@ static struct option longopts[] = {
{ "rw", 0, 0, 'w' },
{ "options", 1, 0, 'o' },
{ "test-opts", 1, 0, 'O' },
{ "pass-fd", 1, 0, 'p' },
{ "types", 1, 0, 't' },
{ "bind", 0, 0, 128 },
{ "replace", 0, 0, 129 },
@ -1394,7 +1408,7 @@ usage (FILE *fp, int n) {
" mount --move olddir newdir\n"
"A device can be given by name, say /dev/hda1 or /dev/cdrom,\n"
"or by label, using -L label or by uuid, using -U uuid .\n"
"Other options: [-nfFrsvw] [-o options].\n"
"Other options: [-nfFrsvw] [-o options] [-p passwdfd].\n"
"For many more details, say man 8 mount .\n"
));
/*
@ -1433,7 +1447,7 @@ main (int argc, char *argv[]) {
initproctitle(argc, argv);
#endif
while ((c = getopt_long (argc, argv, "afFhilL:no:O:rsU:vVwt:",
while ((c = getopt_long (argc, argv, "afFhilL:no:O:p:rsU:vVwt:",
longopts, NULL)) != -1) {
switch (c) {
case 'a': /* mount everything in fstab */
@ -1472,6 +1486,9 @@ main (int argc, char *argv[]) {
else
test_opts = xstrdup(optarg);
break;
case 'p': /* fd on which to read passwd */
set_pfd(optarg);
break;
case 'r': /* mount readonly */
readonly = 1;
readwrite = 0;

View File

@ -139,24 +139,26 @@ uuidcache_init_evms(void) {
* special devices for the xfs filesystem external log & realtime device.
*/
/*
* XVM support - Eric Sandeen
* Return 1 if this looks like an xvm device that should be scanned
*/
/* Return 1 if this looks like an xvm device that should be scanned */
static int
is_xvm(char *ptname)
{
int len;
/* if it doesn't start with "xvm," we're done. */
if (strncmp(ptname, "xvm", 3))
return 0;
len = strlen(ptname);
/*
* Scan anything with "xvm" and "data" in its name.
* That might pick up non-data xvm subvols if the
* volumename contains the string 'data' but
* that should be harmless.
* check for "log/block" or "rt/block" on the end,
* these are special - don't scan.
*/
if (!strncmp(ptname+(len-9), "log/block", 9) ||
!strncmp(ptname+(len-8), "rt/block", 8))
return 0;
if (strstr(ptname, "xvm") && strstr(ptname, "data"))
return 1;
return 0;
return 1;
}
static void

View File

@ -71,7 +71,7 @@ swapped(unsigned short a) {
Corrected the test for xiafs - aeb
Read the superblock only once - aeb
Added a very weak heuristic for vfat - aeb
Added iso9660, minix-v2, romfs, qnx4, udf, vxfs, swap - aeb
Added efs, iso9660, minix-v2, romfs, qnx4, udf, vxfs, swap - aeb
Added a test for high sierra (iso9660) - quinlan@bucknell.edu
Added ufs from a patch by jj. But maybe there are several types of ufs?
Added ntfs from a patch by Richard Russon.
@ -84,7 +84,7 @@ swapped(unsigned short a) {
*/
static char
*magic_known[] = {
"adfs", "bfs", "cramfs", "ext", "ext2", "ext3",
"adfs", "bfs", "cramfs", "efs", "ext", "ext2", "ext3",
"hfs", "hpfs", "iso9660", "jfs", "minix", "ntfs",
"qnx4", "reiserfs", "romfs", "swap", "sysv", "udf", "ufs",
"vxfs", "xfs", "xiafs"
@ -228,12 +228,6 @@ char *
do_guess_fstype(const char *device) {
int fd;
char *type = NULL;
union {
struct minix_super_block ms;
struct ext_super_block es;
struct ext2_super_block e2s;
struct vxfs_super_block vs;
} sb; /* stuff at 1024 */
union {
struct xiafs_super_block xiasb;
char romfs_magic[8];
@ -243,7 +237,15 @@ do_guess_fstype(const char *device) {
struct fat_super_block fatsb;
struct xfs_super_block xfsb;
struct cramfs_super_block cramfssb;
} xsb;
struct efs_volume_header efsvh;
struct efs_super efssb;
} xsb; /* stuff at 0 */
union {
struct minix_super_block ms;
struct ext_super_block es;
struct ext2_super_block e2s;
struct vxfs_super_block vs;
} sb; /* stuff at 1024 */
struct ufs_super_block ufssb;
union {
struct iso_volume_descriptor iso;
@ -294,9 +296,17 @@ do_guess_fstype(const char *device) {
else if(cramfsmagic(xsb.cramfssb) == CRAMFS_SUPER_MAGIC ||
cramfsmagic(xsb.cramfssb) == CRAMFS_SUPER_MAGIC_BE)
type = "cramfs";
else if (assemble4be(xsb.efsvh.vh_magic) == EFS_VHMAGIC)
type = "efs"; /* EFS volume header */
/* might check checksum here */
else if (assemble4be(xsb.efssb.fs_magic) == EFS_SBMAGIC ||
assemble4be(xsb.efssb.fs_magic) == EFS_SBMAGIC2)
type = "efs"; /* EFS partition */
else if ((!strncmp(xsb.fatsb.s_os, "MSDOS", 5) ||
!strncmp(xsb.fatsb.s_os, "MSWIN", 5) ||
!strncmp(xsb.fatsb.s_os, "MTOOL", 5) ||
!strncmp(xsb.fatsb.s_os, "IBM", 3) ||
!strncmp(xsb.fatsb.s_os, "DRDOS", 5) ||
!strncmp(xsb.fatsb.s_os, "mkdosfs", 7) ||
!strncmp(xsb.fatsb.s_os, "kmkdosfs", 8) ||
/* Michal Svec: created by fdformat, old msdos utility for

7
mount/my_dev_t.h Normal file
View File

@ -0,0 +1,7 @@
/* silliness to get dev_t defined as the kernel defines it */
/* glibc uses a different dev_t */
/* maybe we need __kernel_old_dev_t -- later */
/* for ancient systems use "unsigned short" */
#include <linux/posix_types.h>
#define my_dev_t __kernel_dev_t

View File

@ -1,97 +0,0 @@
.TH PIVOT_ROOT 2 "Feb 23, 2000" "Linux" "System Calls"
.SH NAME
pivot_root \- change the root file system
.SH SYNOPSIS
.B #include <linux/unistd.h>
.sp
.B _syscall2(int,pivot_root,const char *,new_root,const char *,put_old)
.sp
.BI "int pivot_root(const char *" new_root ", const char *" put_old );
.SH DESCRIPTION
\fBpivot_root\fP moves the root file system of the current process to the
directory \fIput_old\fP and makes \fInew_root\fP the new root file system
of the current process.
The typical use of \fBpivot_root\fP is during system startup, when the
system mounts a temporary root file system (e.g. an \fBinitrd\fP), then
mounts the real root file system, and eventually turns the latter into
the current root of all relevant processes or threads.
\fBpivot_root\fP may or may not change the current root and the current
working directory (cwd) of any processes or threads which use the old
root directory. The caller of \fBpivot_root\fP
must ensure that processes with root or cwd at the old root operate
correctly in either case. An easy way to ensure this is to change their
root and cwd to \fInew_root\fP before invoking \fBpivot_root\fP.
The paragraph above is intentionally vague because the implementation
of \fBpivot_root\fP may change in the future. At the time of writing,
\fBpivot_root\fP changes root and cwd of each process or
thread to \fInew_root\fP if they point to the old root directory. This
is necessary in order to prevent kernel threads from keeping the old
root directory busy with their root and cwd, even if they never access
the file system in any way. In the future, there may be a mechanism for
kernel threads to explicitly relinquish any access to the file system,
such that this fairly intrusive mechanism can be removed from
\fBpivot_root\fP.
Note that this also applies to the current process: \fBpivot_root\fP may
or may not affect its cwd. It is therefore recommended to call
\fBchdir("/")\fP immediately after \fBpivot_root\fP.
The following restrictions apply to \fInew_root\fP and \fIput_old\fP:
.IP \- 3
They must be directories.
.IP \- 3
\fInew_root\fP and \fIput_old\fP must not be on the same file system as
the current root.
.IP \- 3
\fIput_old\fP must be underneath \fInew_root\fP, i.e. adding a non-zero
number of \fB/..\fP to the string pointed to by \fIput_old\fP must yield
the same directory as \fInew_root\fP.
.IP \- 3
No other file system may be mounted on \fIput_old\fP.
.PP
See also \fBpivot_root(8)\fP for additional usage examples.
If the current root is not a mount point (e.g. after \fBchroot(2)\fP or
\fBpivot_root\fP, see also below), not the old root directory, but the
mount point of that file system is mounted on \fIput_old\fP.
.SH NOTES
\fInew_root\fP does not have to be a mount point. In this case,
\fB/proc/mounts\fP will show the mount point of the file system containing
\fInew_root\fP as root (\fB/\fP).
.SH "RETURN VALUE"
On success, zero is returned. On error, \-1 is returned, and
\fIerrno\fP is set appropriately.
.SH ERRORS
\fBpivot_root\fP may return (in \fIerrno\fP) any of the errors returned by
\fBstat(2)\fP. Additionally, it may return:
.TP
.B EBUSY
\fInew_root\fP or \fIput_old\fP are on the current root file system,
or a file system is already mounted on \fIput_old\fP.
.TP
.B EINVAL
\fIput_old\fP is not underneath \fInew_root\fP.
.TP
.B ENOTDIR
\fInew_root\fP or \fIput_old\fP is not a directory.
.TP
.B EPERM
The current process does not have the administrator capability.
.SH BUGS
\fBpivot_root\fP should not have to change root and cwd of all other
processes in the system.
Some of the more obscure uses of \fBpivot_root\fP may quickly lead to
insanity.
.SH HISTORY
\fBpivot_root\fP was introduced in Linux 2.3.41.
.SH "SEE ALSO"
.BR chdir(2),
.BR chroot(2),
.BR initrd(4),
.BR pivot_root(8),
.BR stat(2)

View File

@ -3,14 +3,17 @@
/* Written 2000 by Werner Almesberger */
#include <stdio.h>
#include <errno.h> /* needed for <linux/unistd.h> below */
#include <sys/syscall.h>
#include <unistd.h>
#ifdef __ia64__
# include <sys/syscall.h>
# define pivot_root(new_root,put_old) syscall(SYS_pivot_root,new_root,put_old)
#else
# include <linux/unistd.h>
#define pivot_root(new_root,put_old) syscall(SYS_pivot_root,new_root,put_old)
#if 0
/*
* With kernelheaders 2.3.41 or later, and ancient libc, try the following.
*/
#include <errno.h>
#include <linux/unistd.h>
static
_syscall2(int,pivot_root,const char *,new_root,const char *,put_old)
#endif

View File

@ -279,7 +279,9 @@ umount_one (const char *spec, const char *node, const char *type,
if (force) { /* only supported for NFS */
res = umount2 (node, MNT_FORCE);
if (res == -1) {
int errsv = errno;
perror("umount2");
errno = errsv;
if (errno == ENOSYS) {
if (verbose)
printf(_("no umount2, trying umount...\n"));
@ -400,15 +402,23 @@ umount_one (const char *spec, const char *node, const char *type,
* In both cases, it is best to try the last occurrence first.
*/
static int
umount_one_bw (const char *file, struct mntentchn *mc) {
int res = 1;
umount_one_bw (const char *file, struct mntentchn *mc0) {
struct mntentchn *mc;
int res = 1;
while (res && mc) {
res = umount_one(mc->m.mnt_fsname, mc->m.mnt_dir,
mc->m.mnt_type, mc->m.mnt_opts, mc);
mc = getmntfilesbackward (file, mc);
}
return res;
mc = mc0;
while (res && mc) {
res = umount_one(mc->m.mnt_fsname, mc->m.mnt_dir,
mc->m.mnt_type, mc->m.mnt_opts, mc);
mc = getmntdirbackward(file, mc);
}
mc = mc0;
while (res && mc) {
res = umount_one(mc->m.mnt_fsname, mc->m.mnt_dir,
mc->m.mnt_type, mc->m.mnt_opts, mc);
mc = getmntdevbackward(file, mc);
}
return res;
}
/* Unmount all filesystems of type VFSTYPES found in mtab. Since we are
@ -525,7 +535,6 @@ get_value(string_list list, char *s) {
}
return 0;
}
/*=======================================================================*/
static int
umount_file (char *arg) {
@ -534,19 +543,27 @@ umount_file (char *arg) {
string_list options;
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 */
if (verbose > 1)
printf(_("Trying to umount %s\n"), file);
mc = getmntfilesbackward (file, NULL);
mc = getmntdirbackward(file, NULL);
if (!mc)
mc = getmntdevbackward(file, NULL);
if (!mc && verbose)
printf(_("Could not find %s in mtab\n"), file);
if (suid) {
char *mtab_user = NULL;
if (!mc)
die (2, _("umount: %s is not mounted (according to mtab)"), file);
if (getmntfilesbackward (file, mc))
die (2, _("umount: it seems %s is mounted multiple times"), file);
die(2,
_("umount: %s is not mounted (according to mtab)"),
file);
if (!is_mounted_once(file))
die(2,
_("umount: it seems %s is mounted multiple times"),
file);
/* If fstab contains the two lines
/dev/sda1 /mnt/zip auto user,noauto 0 0
@ -558,10 +575,12 @@ umount_file (char *arg) {
if (!fs) {
if (!getfsspec (file) && !getfsfile (file))
die (2,
_("umount: %s is not in the fstab (and you are not root)"),
_("umount: %s is not in the fstab "
"(and you are not root)"),
file);
else
die (2, _("umount: %s mount disagrees with the fstab"), file);
die (2, _("umount: %s mount disagrees with "
"the fstab"), file);
}
/* User mounting and unmounting is allowed only
@ -586,7 +605,6 @@ umount_file (char *arg) {
if (!ok && (fstab_has_user || fstab_has_owner)) {
char *user = getusername();
char *mtab_user;
options = parse_list (mc->m.mnt_opts);
mtab_user = get_value(options, "user=");
@ -595,7 +613,8 @@ umount_file (char *arg) {
ok = 1;
}
if (!ok)
die (2, _("umount: only root can unmount %s from %s"),
die (2, _("umount: only %s can unmount %s from %s"),
mtab_user ? mtab_user : "root",
fs->m.mnt_fsname, fs->m.mnt_dir);
}
@ -673,8 +692,9 @@ main (int argc, char *argv[]) {
argv += optind;
if (all) {
/* nodev stuff: sysfs, usbfs, oprofilefs, ... */
if (types == NULL)
types = "noproc,nodevfs";
types = "noproc,nodevfs,nodevpts";
result = umount_all (types, test_opts);
} else if (argc < 1) {
usage (stderr, 2);

View File

@ -7,6 +7,22 @@ is_extended(int type) {
return (type == 5 || type == 0xf || type == 0x85);
}
/* assemble badly aligned little endian integer */
static inline unsigned int
assemble4le(unsigned char *p) {
return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
}
static inline unsigned int
partition_start(struct partition *p) {
return assemble4le(&(p->start_sect[0]));
}
static inline unsigned int
partition_size(struct partition *p) {
return assemble4le(&(p->nr_sects[0]));
}
static int
read_extended_partition(int fd, struct partition *ep,
struct slice *sp, int ns)
@ -18,7 +34,7 @@ read_extended_partition(int fd, struct partition *ep,
int moretodo = 1;
int i, n=0;
here = start = ep->start_sect;
here = start = partition_start(ep);;
while (moretodo) {
moretodo = 0;
@ -35,11 +51,11 @@ read_extended_partition(int fd, struct partition *ep,
p = (struct partition *) (bp + 0x1be);
for (i=0; i<2; i++, p++) {
if (p->nr_sects == 0 || is_extended(p->sys_type))
if (partition_size(p) == 0 || is_extended(p->sys_type))
continue;
if (n < ns) {
sp[n].start = here + p->start_sect;
sp[n].size = p->nr_sects;
sp[n].start = here + partition_start(p);
sp[n].size = partition_size(p);
n++;
} else {
fprintf(stderr,
@ -51,8 +67,9 @@ read_extended_partition(int fd, struct partition *ep,
p -= 2;
for (i=0; i<2; i++, p++) {
if(p->nr_sects != 0 && is_extended(p->sys_type)) {
here = start + p->start_sect;
if (partition_size(p) != 0 &&
is_extended(p->sys_type)) {
here = start + partition_start(p);
moretodo = 1;
break;
}
@ -82,17 +99,16 @@ read_dos_pt(int fd, struct slice all, struct slice *sp, int ns) {
p = (struct partition *) (bp + 0x1be);
for (i=0; i<4; i++) {
if (is_gpt(p->sys_type)) {
if (is_gpt(p->sys_type))
return 0;
}
p++;
}
p = (struct partition *) (bp + 0x1be);
for (i=0; i<4; i++) {
/* always add, even if zero length */
if (n < ns) {
sp[n].start = p->start_sect;
sp[n].size = p->nr_sects;
sp[n].start = partition_start(p);
sp[n].size = partition_size(p);
n++;
} else {
fprintf(stderr,

View File

@ -6,8 +6,8 @@ struct partition {
unsigned char bh, bs, bc;
unsigned char sys_type;
unsigned char eh, es, ec;
unsigned int start_sect;
unsigned int nr_sects;
unsigned char start_sect[4];
unsigned char nr_sects[4];
};
#endif /* DOS_H_INCLUDED */

2162
po/ca.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1886
po/da.po

File diff suppressed because it is too large Load Diff

2348
po/fr.po

File diff suppressed because it is too large Load Diff

1928
po/sl.po

File diff suppressed because it is too large Load Diff

View File

@ -262,7 +262,7 @@ void do_shm (char format)
struct ipc_perm *ipcp = &shmseg.shm_perm;
struct passwd *pw;
maxid = shmctl (0, SHM_INFO, (struct shmid_ds *) &shm_info);
maxid = shmctl (0, SHM_INFO, (struct shmid_ds *) (void *) &shm_info);
if (maxid < 0) {
printf (_("kernel not configured for shared memory\n"));
return;
@ -271,18 +271,18 @@ void do_shm (char format)
switch (format) {
case LIMITS:
printf (_("------ Shared Memory Limits --------\n"));
if ((shmctl (0, IPC_INFO, (struct shmid_ds *) &shminfo)) < 0 )
if ((shmctl (0, IPC_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0 )
return;
/* glibc 2.1.3 and all earlier libc's have ints as fields
of struct shminfo; glibc 2.1.91 has unsigned long; ach */
printf (_("max number of segments = %ld\n"),
(long) shminfo.shmmni);
printf (_("max seg size (kbytes) = %ld\n"),
(long) (shminfo.shmmax >> 10));
printf (_("max total shared memory (kbytes) = %ld\n"),
(long) shminfo.shmall << 2);
printf (_("min seg size (bytes) = %ld\n"),
(long) shminfo.shmmin);
printf (_("max number of segments = %lu\n"),
(unsigned long) shminfo.shmmni);
printf (_("max seg size (kbytes) = %lu\n"),
(unsigned long) (shminfo.shmmax >> 10));
printf (_("max total shared memory (pages) = %lu\n"),
(unsigned long) shminfo.shmall);
printf (_("min seg size (bytes) = %lu\n"),
(unsigned long) shminfo.shmmin);
return;
case STATUS:
@ -360,12 +360,12 @@ void do_shm (char format)
printf ("%-10d %-10.10s", shmid, pw->pw_name);
else
printf ("%-10d %-10d", shmid, ipcp->uid);
printf ("%-10o %-10ld %-10ld %-6s %-6s\n",
printf ("%-10o %-10lu %-10ld %-6s %-6s\n",
ipcp->mode & 0777,
/*
* earlier: int, Austin has size_t
*/
(long) shmseg.shm_segsz,
(unsigned long) shmseg.shm_segsz,
/*
* glibc-2.1.3 and earlier has unsigned short;
* Austin has shmatt_t
@ -389,7 +389,7 @@ void do_sem (char format)
struct passwd *pw;
union semun arg;
arg.array = (ushort *) &seminfo;
arg.array = (ushort *) (void *) &seminfo;
maxid = semctl (0, 0, SEM_INFO, arg);
if (maxid < 0) {
printf (_("kernel not configured for semaphores\n"));
@ -399,7 +399,7 @@ void do_sem (char format)
switch (format) {
case LIMITS:
printf (_("------ Semaphore Limits --------\n"));
arg.array = (ushort *) &seminfo; /* damn union */
arg.array = (ushort *) (void *) &seminfo; /* damn union */
if ((semctl (0, 0, IPC_INFO, arg)) < 0 )
return;
printf (_("max number of arrays = %d\n"), seminfo.semmni);
@ -491,7 +491,7 @@ void do_msg (char format)
struct ipc_perm *ipcp = &msgque.msg_perm;
struct passwd *pw;
maxid = msgctl (0, MSG_INFO, (struct msqid_ds *) &msginfo);
maxid = msgctl (0, MSG_INFO, (struct msqid_ds *) (void *) &msginfo);
if (maxid < 0) {
printf (_("kernel not configured for message queues\n"));
return;
@ -499,7 +499,7 @@ void do_msg (char format)
switch (format) {
case LIMITS:
if ((msgctl (0, IPC_INFO, (struct msqid_ds *) &msginfo)) < 0 )
if ((msgctl (0, IPC_INFO, (struct msqid_ds *) (void *) &msginfo)) < 0 )
return;
printf (_("------ Messages: Limits --------\n"));
printf (_("max queues system wide = %d\n"), msginfo.msgmni);

View File

@ -34,8 +34,8 @@ Available command line options are the following:
Specify a mapfile, which by default is
.B /usr/src/linux/System.map.
You should specify the map file on cmdline if your current kernel isn't the
last one you compiled. If the name of the map file ends with `.gz' it
is decompressed on the fly.
last one you compiled, or if you keep System.map elsewhere. If the name of
the map file ends with `.gz' it is decompressed on the fly.
.TP
.RB -p " pro-file"

View File

@ -132,10 +132,11 @@ main(int argc, char **argv) {
FILE *map;
int proFd;
char *mapFile, *proFile, *mult=0;
unsigned long len=0, add0=0, indx=1;
unsigned long len=0, indx=1;
unsigned long long add0=0;
unsigned int step;
unsigned int *buf, total, fn_len;
unsigned long fn_add, next_add; /* current and next address */
unsigned long long fn_add, next_add; /* current and next address */
char fn_name[S_LEN], next_name[S_LEN]; /* current and next name */
char mode[8];
int c;
@ -292,7 +293,7 @@ main(int argc, char **argv) {
}
while (fgets(mapline,S_LEN,map)) {
if (sscanf(mapline,"%lx %s %s",&fn_add,mode,fn_name) != 3) {
if (sscanf(mapline,"%llx %s %s",&fn_add,mode,fn_name) != 3) {
fprintf(stderr,_("%s: %s(%i): wrong map line\n"),
prgname, mapFile, maplineno);
exit(1);
@ -316,7 +317,7 @@ main(int argc, char **argv) {
while (fgets(mapline,S_LEN,map)) {
unsigned int this=0;
if (sscanf(mapline,"%lx %s %s",&next_add,mode,next_name)!=3) {
if (sscanf(mapline,"%llx %s %s",&next_add,mode,next_name)!=3) {
fprintf(stderr,_("%s: %s(%i): wrong map line\n"),
prgname,mapFile, maplineno);
exit(1);
@ -342,7 +343,7 @@ main(int argc, char **argv) {
printf ("%s:\n", fn_name);
header_printed = 1;
}
printf ("\t%lx\t%u\n", (indx - 1)*step + add0, buf[indx]);
printf ("\t%llx\t%u\n", (indx - 1)*step + add0, buf[indx]);
}
this += buf[indx++];
}
@ -355,7 +356,7 @@ main(int argc, char **argv) {
fn_len = next_add-fn_add;
if (fn_len && (this || optAll)) {
if (optVerbose)
printf("%08lx %-40s %6i %8.4f\n", fn_add,
printf("%016llx %-40s %6i %8.4f\n", fn_add,
fn_name,this,this/(double)fn_len);
else
printf("%6i %-40s %8.4f\n",
@ -368,7 +369,7 @@ main(int argc, char **argv) {
}
/* trailer */
if (optVerbose)
printf("%08x %-40s %6i %8.4f\n",
printf("%016x %-40s %6i %8.4f\n",
0,"total",total,total/(double)(fn_add-add0));
else
printf("%6i %-40s %8.4f\n",

View File

@ -1,19 +1,19 @@
.\" @(#)pg.1 1.12 (gritter) 3/12/03
.TH PG 1 "2003-03-12" "Gunnar Ritter" "User Commands"
.\" @(#)pg.1 1.7 (gritter) 4/25/01
.TH PG 1 "2001-04-25" "Gunnar Ritter" "User Commands"
.SH NAME
pg \- browse pagewise through text files
.SH SYNOPSIS
.B pg
[
.BI \- number
.I \-number
] [
.BI \-p \ string
] [
.B \-cefnrs
] [
.BI + line
.I +line
] [
.BI +/ pattern /
.I +/pattern/
] [ file . . . ]
.SH DESCRIPTION
.I Pg
@ -76,7 +76,7 @@ If
.I string
contains
.I %d
, its first occurrence is replaced by the number of the current page.
, its first occurence is replaced by the number of the current page.
.TP
.B \-r
Disallow the shell escape.
@ -91,7 +91,7 @@ if the terminfo entry for the terminal provides this capability.
Start at the given line.
.TP
.BI +/ pattern /
Start at the line containing the basic regular expression
Start at the line containing the Basic Regular Expression
.I pattern
given.
.SH USAGE
@ -137,7 +137,7 @@ Advance to the last line of the input file.
.TP
.IB i / pattern /
Search forward until the first or the \fIi\fR-th
occurrence of the basic regular expression
occurence of the Basic Regular Expression
.I pattern
is found. The search starts
after the current page and stops at the end of the file. No wrap-around is
@ -147,7 +147,7 @@ must be a positive number.
.TP
\fIi\fR\fB?\fR\fIpattern\fR\fB?\fR or \fIi\fR\fB^\fR\fIpattern\fR\fB^\fR
Search backward until the first or the \fIi\fR-th
occurrence of the basic regular expression
occurence of the Basic Regular Expression
.I pattern
is found. The search starts
before the current page and stops at the beginning of the file.