Imported from util-linux-2.12a tarball.
This commit is contained in:
parent
a21409f54e
commit
d03dd60840
27
HISTORY
27
HISTORY
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
4
MCONFIG
4
MCONFIG
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
238
install-sh
238
install-sh
|
@ -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
|
27
lib/md5.c
27
lib/md5.c
|
@ -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];
|
||||
|
|
13
lib/md5.h
13
lib/md5.h
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -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,8 +1362,10 @@ dolastlog(int quiet) {
|
|||
if (!quiet) {
|
||||
if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
|
||||
ll.ll_time != 0) {
|
||||
time_t ll_time = (time_t) ll.ll_time;
|
||||
|
||||
printf(_("Last login: %.*s "),
|
||||
24-5, (char *)ctime(&ll.ll_time));
|
||||
24-5, ctime(&ll_time));
|
||||
|
||||
if (*ll.ll_host != '\0')
|
||||
printf(_("from %.*s\n"),
|
||||
|
|
|
@ -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
|
|
@ -0,0 +1,2 @@
|
|||
extern int checkAccess(char *name,int access);
|
||||
extern int setupDefaultContext(char *orig_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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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] */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -186,23 +186,55 @@ getmntfile (const char *name) {
|
|||
}
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -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));
|
||||
|
|
337
mount/lomount.c
337
mount/lomount.c
|
@ -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 Mi¶kiewicz <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,44 +41,44 @@ 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;
|
||||
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) {
|
||||
struct loop_info loopinfo;
|
||||
int fd;
|
||||
struct loop_info64 loopinfo64;
|
||||
int fd, errsv;
|
||||
|
||||
if ((fd = open(device, O_RDONLY)) < 0) {
|
||||
int errsv = errno;
|
||||
|
@ -81,48 +86,69 @@ show_loop (char *device) {
|
|||
device, strerror (errsv));
|
||||
return 2;
|
||||
}
|
||||
if (ioctl (fd, LOOP_GET_STATUS, &loopinfo) < 0) {
|
||||
int errsv = errno;
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
#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,47 +185,71 @@ 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;
|
||||
const char *encryption, int pfd, int *loopro) {
|
||||
struct loop_info64 loopinfo64;
|
||||
int fd, ffd, mode;
|
||||
char *pass;
|
||||
|
||||
mode = (*loopro ? O_RDONLY : O_RDWR);
|
||||
|
@ -218,15 +267,21 @@ set_loop (const char *device, const char *file, int offset,
|
|||
}
|
||||
*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;
|
||||
}
|
||||
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);
|
||||
return 1;
|
||||
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_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;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
extern int verbose;
|
||||
extern int set_loop (const char *, const char *, int, const char *, int *);
|
||||
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);
|
||||
|
|
|
@ -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];
|
||||
};
|
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
@ -776,7 +788,8 @@ 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.
|
||||
*/
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
if (strstr(ptname, "xvm") && strstr(ptname, "data"))
|
||||
return 1;
|
||||
int len;
|
||||
|
||||
/* if it doesn't start with "xvm," we're done. */
|
||||
if (strncmp(ptname, "xvm", 3))
|
||||
return 0;
|
||||
|
||||
len = strlen(ptname);
|
||||
/*
|
||||
* 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;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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)
|
|
@ -3,14 +3,17 @@
|
|||
/* Written 2000 by Werner Almesberger */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h> /* needed for <linux/unistd.h> below */
|
||||
|
||||
#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>
|
||||
#include <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
|
||||
|
|
|
@ -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,13 +402,21 @@ 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) {
|
||||
umount_one_bw (const char *file, struct mntentchn *mc0) {
|
||||
struct mntentchn *mc;
|
||||
int res = 1;
|
||||
|
||||
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 = getmntfilesbackward (file, 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;
|
||||
}
|
||||
|
@ -525,7 +535,6 @@ get_value(string_list list, char *s) {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
/*=======================================================================*/
|
||||
|
||||
static int
|
||||
umount_file (char *arg) {
|
||||
|
@ -538,15 +547,23 @@ umount_file (char *arg) {
|
|||
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);
|
||||
|
|
36
partx/dos.c
36
partx/dos.c
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
2715
po/cat-id-tbl.c
2715
po/cat-id-tbl.c
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue