Imported from util-linux-2.10f tarball.
This commit is contained in:
parent
7eda085c41
commit
eb63b9b8f4
129 changed files with 24647 additions and 15787 deletions
88
HISTORY
88
HISTORY
|
@ -1,3 +1,88 @@
|
|||
util-linux 2.10f:
|
||||
|
||||
* Security fix for mount (okir)
|
||||
* Avoid infinite loop in namei (Brett Wuth)
|
||||
* added clock-ppc.c (from Matsuura Takanori), not merged yet
|
||||
* deleted clockB subdirectory
|
||||
* recognize mkdosfs string (Michal Svec)
|
||||
|
||||
util-linux 2.10e:
|
||||
|
||||
* New: rename
|
||||
* Added option to mkswap so that user can override pagesize
|
||||
* fdisk -l now reads /proc/partitions when no device was given
|
||||
* Fixed fdisk.8 (James Manning)
|
||||
* Added devpts info to mount.8 (Elrond)
|
||||
* Newline fix for logger output to stdout (Henri Spencer)
|
||||
|
||||
util-linux 2.10d:
|
||||
|
||||
* Do not try to mount something as udf without good reason
|
||||
* Do not loop in umount if there is a stale lock file
|
||||
* Allow fdisk twice as many cylinders
|
||||
* Fixed non-casefolding search in look (Markus Demleitner)
|
||||
|
||||
util-linux 2.10c:
|
||||
|
||||
* Various compilation fixes
|
||||
|
||||
util-linux 2.10b:
|
||||
|
||||
* Fixed smbmount problem (Andrew Tridgell)
|
||||
* Fixed ddate problem with the day after St. Tib's Day (Brad)
|
||||
* German messages (Elrond)
|
||||
* Made kill a bit more standard compliant
|
||||
* Made some more programs output a version
|
||||
|
||||
util-linux 2.10a:
|
||||
|
||||
* Japanese messages (Daisuke Yamashita)
|
||||
* French messages and several Debian fixes (Vincent Renardias)
|
||||
* Fixed infinite loop in mkfs.minix
|
||||
|
||||
util-linux 2.10:
|
||||
|
||||
* Added BSD disklabel code to rescuept
|
||||
* Added blockdev utility
|
||||
* Fix losetup return code
|
||||
* Fix unit display in cfdisk
|
||||
* Do not redefine _PATH_MAILDIR (so that recent systems can have /var/mail)
|
||||
* Added --localtime option to hwclock;
|
||||
added third line (LOCAL/UTC) to /etc/adjtime.
|
||||
* Add -H option to agetty (David Holland)
|
||||
|
||||
util-linux 2.9z:
|
||||
|
||||
* Japanese messages (Daisuke Yamashita)
|
||||
* Czech messages (Jiri Pavlovsky)
|
||||
* Added some udf stuff to mount.8
|
||||
* Added ioctl for fdisk on bsdlabels
|
||||
|
||||
util-linux 2.9y:
|
||||
|
||||
* Wide character support (Bruno Haible)
|
||||
* German messages and some small fixes (Elrond)
|
||||
* Small fix to owner mount option (Erik Troan)
|
||||
* Don't sleep so long in clock/kd.c (Christian T. Steigies)
|
||||
|
||||
util-linux 2.9x:
|
||||
|
||||
* German messages and a i18n fix (Elrond)
|
||||
* mount option: allow the owner to mount a device (RedHat)
|
||||
* ugly: let login open console with O_NONBLOCK (Maciej W. Rozycki)
|
||||
* UGLY: let login ignore mail that is precisely 523 bytes long (RedHat)
|
||||
* added mkfs.bfs, mkfs.bfs.8
|
||||
* mount now recognizes qnx4 and bfs partitions
|
||||
* rescuept now recognizes Unixware partitions
|
||||
* hwclock fix on m68k (Roman Hodek)
|
||||
* several minor things
|
||||
|
||||
util-linux 2.9w:
|
||||
|
||||
* Updated mount.8 (Yann Droneaud)
|
||||
* Improved makefiles
|
||||
* Fixed flaw in fdisk
|
||||
|
||||
util-linux 2.9v:
|
||||
|
||||
* cfdisk no longer believes the kernel's HDGETGEO
|
||||
|
@ -31,6 +116,7 @@ util-linux 2.9t:
|
|||
util-linux 2.9s:
|
||||
|
||||
* tunelp patch (Andrea Arcangeli)
|
||||
* fixed mount race (HJLu)
|
||||
* German messages (Elrond)
|
||||
|
||||
util-linux 2.9[pqr]:
|
||||
|
@ -66,8 +152,8 @@ util-linux 2.9l:
|
|||
util-linux 2.9k:
|
||||
|
||||
* major reshuffle of hwclock stuff; added sparc and alpha code
|
||||
* fdisk fix
|
||||
* tiny shutdown fix
|
||||
* tiny fdisk fix
|
||||
|
||||
util-linux 2.9j:
|
||||
|
||||
|
|
29
INSTALL
29
INSTALL
|
@ -21,8 +21,8 @@ WARNING: The simpleinit and some other programs in this package are
|
|||
To install from source:
|
||||
|
||||
1) Get source distribution (see the .lsm file for locations)
|
||||
2) Untar util-linux-2.9X.tar.gz somewhere
|
||||
3) cd util-linux-2.9X
|
||||
2) Untar util-linux-2.10X.tar.gz somewhere
|
||||
3) cd util-linux-2.10X
|
||||
4) Edit MCONFIG
|
||||
5) ./configure
|
||||
6) Look at defines.h and make_include, and edit if necessary
|
||||
|
@ -37,15 +37,30 @@ To install from source:
|
|||
|
||||
If you have compilation problems: tell util-linux@math.uio.no about it.
|
||||
|
||||
Users of libc 5.4.46 may get warnings like
|
||||
/usr/include/linux/byteorder/swab.h:100: warning: no previous prototype for `__fswab16'
|
||||
that they'll have to ignore. The Linux kernel includes are not meant to be included
|
||||
in user programs, but libc5 does precisely that and is inherently broken.
|
||||
A glibc header bug causes
|
||||
/usr/include/bits/string2.h:419: warning: pointer of type `void *'
|
||||
used in arithmetic
|
||||
This is harmless.
|
||||
|
||||
Some old libc have complaints like
|
||||
Users of libc5 may get warnings like
|
||||
/usr/include/linux/byteorder/swab.h:100: warning: no previous prototype for `__fswab16'
|
||||
that they'll have to ignore. The Linux kernel includes are not meant to be
|
||||
included in user programs, but libc5 does precisely that and is inherently
|
||||
broken.
|
||||
|
||||
Several old libc have complaints like
|
||||
/usr/include/sys/syslog.h:71: warning: missing braces around initializer
|
||||
/usr/include/rpc/xdr.h:103: warning: function declaration isn't a prototype
|
||||
/usr/include/rpc/auth.h:86: warning: function declaration isn't a prototype
|
||||
/usr/include/rpc/svc.h:79: warning: function declaration isn't a prototype
|
||||
Also this is a libc/include problem.
|
||||
|
||||
Warnings like
|
||||
<sys/mman.h>:11: warning: `MAP_FILE' redefined
|
||||
<asm/mman.h>:30: warning: this is the location of the previous definition
|
||||
are caused by the libc/kernel combination.
|
||||
|
||||
All such warnings are harmless.
|
||||
There should be no compilation errors.
|
||||
|
||||
|
||||
|
|
2
MAINTAINER
Normal file
2
MAINTAINER
Normal file
|
@ -0,0 +1,2 @@
|
|||
Maintainer: Andries Brouwer (aeb@cwi.nl)
|
||||
Maintainer address: util-linux@math.uio.no
|
24
MCONFIG
24
MCONFIG
|
@ -8,7 +8,7 @@
|
|||
# - define DESTDIR
|
||||
|
||||
# Select for CPU one of intel, alpha, sparc, arm, m68k, mips
|
||||
CPU=$(shell uname -m | sed s/i.86/intel/)
|
||||
CPU=$(shell uname -m | sed 's/i.86/intel/;s/arm.*/arm/')
|
||||
|
||||
# define where is locale directrory (default /usr/share/locale)
|
||||
LOCALEDIR=/usr/share/locale
|
||||
|
@ -74,25 +74,36 @@ HAVE_RESET=yes
|
|||
# sln also comes with libc and glibc.
|
||||
HAVE_SLN=no
|
||||
|
||||
# If HAVE_TSORT is set to "yes", then tsort won't be installed.
|
||||
# GNU textutils 2.0 includes tsort.
|
||||
HAVE_TSORT=no
|
||||
|
||||
# If HAVE_FDUTILS is set to "yes", then setfdprm won't be installed.
|
||||
HAVE_FDUTILS=no
|
||||
|
||||
# Get CC from environment if defined
|
||||
ifeq "$(CC)" ""
|
||||
CC= gcc
|
||||
endif
|
||||
|
||||
# Different optimizations for different cpus.
|
||||
ifeq "$(CPU)" "intel"
|
||||
OPT= -pipe -O2 -m486 -fomit-frame-pointer
|
||||
else
|
||||
ifeq "$(CPU)" "arm"
|
||||
OPT= -O2 -m3 -fomit-frame-pointer
|
||||
OPT= -pipe -O2 -fsigned-char -fomit-frame-pointer
|
||||
else
|
||||
OPT= -O2 -fomit-frame-pointer
|
||||
endif
|
||||
endif
|
||||
|
||||
ERR_O=$(LIB)/err.o
|
||||
LDFLAGS = -s
|
||||
|
||||
WARNFLAGS = -Wall
|
||||
|
||||
LIB=../lib
|
||||
|
||||
LDFLAGS = -s
|
||||
WARNFLAGS = -Wall
|
||||
ERR_O=$(LIB)/err.o
|
||||
|
||||
CFLAGS = $(OPT) -I. -I$(LIB) $(WARNFLAGS) \
|
||||
$(CURSESFLAGS) $(SLANGFLAGS) \
|
||||
|
@ -141,6 +152,9 @@ FSCKDIR= $(SBINDIR)
|
|||
# Directory for passwd
|
||||
PASSWDDIR= $(USRBINDIR)
|
||||
|
||||
# Directory for help file for more. Some may want /usr/share/misc .
|
||||
MOREHELPDIR= $(USRLIBDIR)
|
||||
|
||||
# Modes
|
||||
DIRMODE= 755
|
||||
BINMODE= 755
|
||||
|
|
41
Makefile
41
Makefile
|
@ -5,8 +5,6 @@
|
|||
# May be distributed under the terms of the GNU GPL.
|
||||
#
|
||||
|
||||
VERSION=2.9
|
||||
|
||||
include ./make_include
|
||||
include ./MCONFIG
|
||||
|
||||
|
@ -24,7 +22,7 @@ SUBDIRS=po \
|
|||
text-utils \
|
||||
kbd
|
||||
|
||||
.PHONEY: all install clean
|
||||
.PHONEY: all install clean now
|
||||
all: defines.h
|
||||
@for subdir in $(SUBDIRS); do \
|
||||
(cd $$subdir && $(MAKE) $@) || exit 1; \
|
||||
|
@ -33,6 +31,12 @@ all: defines.h
|
|||
defines.h make_include:
|
||||
./configure
|
||||
|
||||
now:
|
||||
touch defines.h
|
||||
|
||||
$(SUBDIRS): defines.h now
|
||||
cd $@ && $(MAKE)
|
||||
|
||||
install:
|
||||
@if [ "`whoami`" = "root" ]; then umask 022; fi
|
||||
@for subdir in $(SUBDIRS); do \
|
||||
|
@ -49,17 +53,20 @@ distclean: make_include clean
|
|||
cd po && make distclean
|
||||
-rm -f defines.h make_include
|
||||
|
||||
dist:
|
||||
(cd /tmp; \
|
||||
rm -rf /tmp/util-linux-$(VERSION); \
|
||||
cvs export -fNd util-linux-$(VERSION) -r HEAD util-linux; \
|
||||
cd util-linux-$(VERSION); \
|
||||
find -type d | xargs chmod 755; \
|
||||
find -type f | xargs chmod 644; \
|
||||
find -type d | xargs chown root:root; \
|
||||
find -type f | xargs chown root:root; \
|
||||
cd ..; \
|
||||
GZIP=-9 tar cvvzf util-linux-$(VERSION).tar.gz util-linux-$(VERSION); \
|
||||
cp -p util-linux-$(VERSION)/LSM util-linux-$(VERSION).lsm; \
|
||||
cp -p util-linux-$(VERSION)/ANNOUNCE util-linux-$(VERSION).Announce; \
|
||||
echo Done.)
|
||||
#
|
||||
# dist:
|
||||
# (cd /tmp; \
|
||||
# rm -rf /tmp/util-linux-$(VERSION); \
|
||||
# cvs export -fNd util-linux-$(VERSION) -r HEAD util-linux; \
|
||||
# cd util-linux-$(VERSION); \
|
||||
# find -type d | xargs chmod 755; \
|
||||
# find -type f | xargs chmod 644; \
|
||||
# find -type d | xargs chown root:root; \
|
||||
# find -type f | xargs chown root:root; \
|
||||
# cd ..; \
|
||||
# GZIP=-9 tar cvvzf util-linux-$(VERSION).tar.gz util-linux-$(VERSION); \
|
||||
# cp -p util-linux-$(VERSION)/LSM util-linux-$(VERSION).lsm; \
|
||||
# cp -p util-linux-$(VERSION)/ANNOUNCE util-linux-$(VERSION).Announce; \
|
||||
# echo Done.)
|
||||
#
|
||||
|
||||
|
|
39
README.clock
39
README.clock
|
@ -1,39 +0,0 @@
|
|||
Util-linux has always had the clock program (by Charles Hedrick,
|
||||
Rob Hooft, Harald Koenig, Alan Modra).
|
||||
|
||||
Slackware still uses the clock.c and clock.8 from util-linux-2.6
|
||||
(and calls the resulting source fragment clock-1.6.tar.gz).
|
||||
|
||||
Bryan Henderson rewrote it, calling the result hwclock,
|
||||
and util-linux-2.6 has both clock.c and hwclock.c,
|
||||
util-linux-2.7 and later only have hwclock.c.
|
||||
|
||||
Unfortunately, hwclock.c was broken in various ways, especially
|
||||
on non-intel hardware, and distributions started shipping private
|
||||
versions (usually derived from the old clock).
|
||||
|
||||
For util-linux-2.9k Andries Brouwer took all clock versions around,
|
||||
and merged them. The resulting hwclock program works on all architectures.
|
||||
There are some kernel bugs in the handling of /dev/rtc on some i386 hardware,
|
||||
so under certain circumstances where hwclock fails one has to give it the
|
||||
--directisa flag to let hwclock do the clock access itself (which works)
|
||||
rather than leave it to the kernel. [The precise cause is still being
|
||||
investigated.]
|
||||
This is the code presently found in the clock subdirectory.
|
||||
|
||||
Bryan Henderson took this code again and merged it with his original
|
||||
hwclock source. That is the code found in the util-linux-2.9q clock
|
||||
directory. Unfortunately, this new version didnt work on Sparcs
|
||||
and in util-linux-2.9r this code was moved to the clockB subdirectory.
|
||||
|
||||
|
||||
Executive summary:
|
||||
clock/hwclock is claimed to be good (but may need the --directisa flag).
|
||||
|
||||
|
||||
Comments, bug reports etc are welcome.
|
||||
Note that the source contains a rather detailed description of the clock
|
||||
hardware involved. Additions and corrections are welcome.
|
||||
|
||||
Andries
|
||||
aeb@cwi.nl
|
1
VERSION
Normal file
1
VERSION
Normal file
|
@ -0,0 +1 @@
|
|||
2.10f
|
|
@ -2,21 +2,11 @@ Hwclock is a program that runs under Linux and sets and queries the
|
|||
Hardware Clock, which is often called the Real Time Clock, RTC, or
|
||||
CMOS clock.
|
||||
|
||||
Hwclock is shipped with an ELF executable built for ISA (Intel)
|
||||
machines. So there is nothing to build for those machines. Just
|
||||
install the executable file "hwclock" and the man page file
|
||||
"hwclock.8" in suitable directories (like /sbin/hwclock and
|
||||
/usr/man/man8/hwclock.8) and you're ready to go.
|
||||
|
||||
hwclock accesses platform-dependent hardware, so if you have something
|
||||
other than an ISA machine, the shipped executable probably doesn't work,
|
||||
and you have to compile hwclock yourself.
|
||||
|
||||
Sometimes, you need to install hwclock setuid root. If you want users
|
||||
other than the superuser to be able to display the clock value using the
|
||||
direct ISA I/O method, install it setuid root. If you have the /dev/rtc
|
||||
interface on your system or are on a non-ISA system, there's no need for
|
||||
users to use the direct ISA I/O method, so don't bother.
|
||||
interface on your system or are on a non-ISA system, there's probably
|
||||
no need for users to use the direct ISA I/O method, so don't bother.
|
||||
|
||||
To install setuid root, do something like this:
|
||||
|
||||
|
@ -32,15 +22,6 @@ If you want to build hwclock, just cd to the source directory and invoke
|
|||
make with no parameters.
|
||||
|
||||
hwclock calls option processing routines in the libsshopt library,
|
||||
which is part of Sverre H. Huseby's "shhopt" package. An ELF
|
||||
executable of this library is included in the package, but you can use
|
||||
a copy that is already on your system by altering the make file. You
|
||||
can find a more authoritative copy of this library, and its source
|
||||
code, on sunsite (ftp://sunsite.unc.edu/pub/Linux/libs/shhopt-X.Y).
|
||||
|
||||
As shipped, the routines are linked in statically, so you only need the
|
||||
libsshopt.a file to build hwclock, not to run it.
|
||||
|
||||
|
||||
|
||||
|
||||
which is part of Sverre H. Huseby's "shhopt" package. You
|
||||
can find a more authoritative copy of this package on metalab
|
||||
(ftp://metalab.unc.edu/pub/Linux/libs/shhopt-X.Y).
|
||||
|
|
459
clock/clock-ppc.c
Normal file
459
clock/clock-ppc.c
Normal file
|
@ -0,0 +1,459 @@
|
|||
/*
|
||||
From t-matsuu@protein.osaka-u.ac.jp Sat Jan 22 13:43:20 2000
|
||||
Date: Sat, 22 Jan 2000 21:42:54 +0900 (JST)
|
||||
To: Andries.Brouwer@cwi.nl
|
||||
Subject: Please merge the source for PPC
|
||||
From: MATSUURA Takanori <t-matsuu@protein.osaka-u.ac.jp>
|
||||
|
||||
Even now, it is used clock-1.1 based source on Linux for PowerPC
|
||||
architecture, attached on this mail.
|
||||
|
||||
Please merge this source in main util-linux source.
|
||||
|
||||
But I'm not an author of this source, but Paul Mackerras.
|
||||
http://linuxcare.com.au/paulus/
|
||||
shows details of him.
|
||||
|
||||
MATSUURA Takanori @ Division of Protein Chemistry,
|
||||
Institute for Protein Research, Osaka University, Japan
|
||||
E-Mail: t-matsuu@protein.osaka-u.ac.jp
|
||||
Web Page: http://www.protein.osaka-u.ac.jp/chemistry/matsuura/
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <asm/cuda.h>
|
||||
|
||||
/*
|
||||
* Adapted for Power Macintosh by Paul Mackerras.
|
||||
*/
|
||||
|
||||
/* V1.0
|
||||
* CMOS clock manipulation - Charles Hedrick, hedrick@cs.rutgers.edu, Apr 1992
|
||||
*
|
||||
* clock [-u] -r - read cmos clock
|
||||
* clock [-u] -w - write cmos clock from system time
|
||||
* clock [-u] -s - set system time from cmos clock
|
||||
* clock [-u] -a - set system time from cmos clock, adjust the time to
|
||||
* correct for systematic error, and put it back to the cmos.
|
||||
* -u indicates cmos clock is kept in universal time
|
||||
*
|
||||
* The program is designed to run setuid, since we need to be able to
|
||||
* write to the CUDA.
|
||||
*
|
||||
*********************
|
||||
* V1.1
|
||||
* Modified for clock adjustments - Rob Hooft, hooft@chem.ruu.nl, Nov 1992
|
||||
* Also moved error messages to stderr. The program now uses getopt.
|
||||
* Changed some exit codes. Made 'gcc 2.3 -Wall' happy.
|
||||
*
|
||||
* I think a small explanation of the adjustment routine should be given
|
||||
* here. The problem with my machine is that its CMOS clock is 10 seconds
|
||||
* per day slow. With this version of clock.c, and my '/etc/rc.local'
|
||||
* reading '/etc/clock -au' instead of '/etc/clock -u -s', this error
|
||||
* is automatically corrected at every boot.
|
||||
*
|
||||
* To do this job, the program reads and writes the file '/etc/adjtime'
|
||||
* to determine the correction, and to save its data. In this file are
|
||||
* three numbers:
|
||||
*
|
||||
* 1) the correction in seconds per day (So if your clock runs 5
|
||||
* seconds per day fast, the first number should read -5.0)
|
||||
* 2) the number of seconds since 1/1/1970 the last time the program was
|
||||
* used.
|
||||
* 3) the remaining part of a second which was leftover after the last
|
||||
* adjustment
|
||||
*
|
||||
* Installation and use of this program:
|
||||
*
|
||||
* a) create a file '/etc/adjtime' containing as the first and only line:
|
||||
* '0.0 0 0.0'
|
||||
* b) run 'clock -au' or 'clock -a', depending on whether your cmos is in
|
||||
* universal or local time. This updates the second number.
|
||||
* c) set your system time using the 'date' command.
|
||||
* d) update your cmos time using 'clock -wu' or 'clock -w'
|
||||
* e) replace the first number in /etc/adjtime by your correction.
|
||||
* f) put the command 'clock -au' or 'clock -a' in your '/etc/rc.local'
|
||||
*
|
||||
* If the adjustment doesn't work for you, try contacting me by E-mail.
|
||||
*
|
||||
******
|
||||
* V1.2
|
||||
*
|
||||
* Applied patches by Harald Koenig (koenig@nova.tat.physik.uni-tuebingen.de)
|
||||
* Patched and indented by Rob Hooft (hooft@EMBL-Heidelberg.DE)
|
||||
*
|
||||
* A free quote from a MAIL-message (with spelling corrections):
|
||||
*
|
||||
* "I found the explanation and solution for the CMOS reading 0xff problem
|
||||
* in the 0.99pl13c (ALPHA) kernel: the RTC goes offline for a small amount
|
||||
* of time for updating. Solution is included in the kernel source
|
||||
* (linux/kernel/time.c)."
|
||||
*
|
||||
* "I modified clock.c to fix this problem and added an option (now default,
|
||||
* look for USE_INLINE_ASM_IO) that I/O instructions are used as inline
|
||||
* code and not via /dev/port (still possible via #undef ...)."
|
||||
*
|
||||
* With the new code, which is partially taken from the kernel sources,
|
||||
* the CMOS clock handling looks much more "official".
|
||||
* Thanks Harald (and Torsten for the kernel code)!
|
||||
*
|
||||
******
|
||||
* V1.3
|
||||
* Canges from alan@spri.levels.unisa.edu.au (Alan Modra):
|
||||
* a) Fix a few typos in comments and remove reference to making
|
||||
* clock -u a cron job. The kernel adjusts cmos time every 11
|
||||
* minutes - see kernel/sched.c and kernel/time.c set_rtc_mmss().
|
||||
* This means we should really have a cron job updating
|
||||
* /etc/adjtime every 11 mins (set last_time to the current time
|
||||
* and not_adjusted to ???).
|
||||
* b) Swapped arguments of outb() to agree with asm/io.h macro of the
|
||||
* same name. Use outb() from asm/io.h as it's slightly better.
|
||||
* c) Changed CMOS_READ and CMOS_WRITE to inline functions. Inserted
|
||||
* cli()..sti() pairs in appropriate places to prevent possible
|
||||
* errors, and changed ioperm() call to iopl() to allow cli.
|
||||
* d) Moved some variables around to localise them a bit.
|
||||
* e) Fixed bug with clock -ua or clock -us that cleared environment
|
||||
* variable TZ. This fix also cured the annoying display of bogus
|
||||
* day of week on a number of machines. (Use mktime(), ctime()
|
||||
* rather than asctime() )
|
||||
* f) Use settimeofday() rather than stime(). This one is important
|
||||
* as it sets the kernel's timezone offset, which is returned by
|
||||
* gettimeofday(), and used for display of MSDOS and OS2 file
|
||||
* times.
|
||||
* g) faith@cs.unc.edu added -D flag for debugging
|
||||
*
|
||||
* V1.4: alan@SPRI.Levels.UniSA.Edu.Au (Alan Modra)
|
||||
* Wed Feb 8 12:29:08 1995, fix for years > 2000.
|
||||
* faith@cs.unc.edu added -v option to print version.
|
||||
*
|
||||
* August 1996 Tom Dyas (tdyas@eden.rutgers.edu)
|
||||
* Converted to be compatible with the SPARC /dev/rtc driver.
|
||||
*
|
||||
*/
|
||||
|
||||
#define VERSION "1.4"
|
||||
|
||||
/* Here the information for time adjustments is kept. */
|
||||
#define ADJPATH "/etc/adjtime"
|
||||
|
||||
/* Apparently the RTC on PowerMacs stores seconds since 1 Jan 1904 */
|
||||
#define RTC_OFFSET 2082844800
|
||||
|
||||
/* used for debugging the code. */
|
||||
/*#define KEEP_OFF */
|
||||
|
||||
/* Globals */
|
||||
int readit = 0;
|
||||
int adjustit = 0;
|
||||
int writeit = 0;
|
||||
int setit = 0;
|
||||
int universal = 0;
|
||||
int debug = 0;
|
||||
|
||||
time_t mkgmtime(struct tm *);
|
||||
|
||||
volatile void
|
||||
usage ( void )
|
||||
{
|
||||
(void) fprintf (stderr,
|
||||
"clock [-u] -r|w|s|a|v\n"
|
||||
" r: read and print CMOS clock\n"
|
||||
" w: write CMOS clock from system time\n"
|
||||
" s: set system time from CMOS clock\n"
|
||||
" a: get system time and adjust CMOS clock\n"
|
||||
" u: CMOS clock is in universal time\n"
|
||||
" v: print version (" VERSION ") and exit\n"
|
||||
);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int adb_fd;
|
||||
|
||||
void
|
||||
adb_init ( void )
|
||||
{
|
||||
adb_fd = open ("/dev/adb", 2);
|
||||
if (adb_fd < 0)
|
||||
{
|
||||
perror ("unable to open /dev/adb read/write : ");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char get_packet[2] = { (unsigned char) CUDA_PACKET,
|
||||
(unsigned char) CUDA_GET_TIME };
|
||||
unsigned char set_packet[6] = { (unsigned char) CUDA_PACKET,
|
||||
(unsigned char) CUDA_SET_TIME };
|
||||
|
||||
int
|
||||
main (int argc, char **argv )
|
||||
{
|
||||
struct tm tm, *tmp;
|
||||
time_t systime;
|
||||
time_t last_time;
|
||||
time_t clock_time;
|
||||
int i, arg;
|
||||
double factor;
|
||||
double not_adjusted;
|
||||
int adjustment = 0;
|
||||
/* unsigned char save_control, save_freq_select; */
|
||||
unsigned char reply[16];
|
||||
|
||||
while ((arg = getopt (argc, argv, "rwsuaDv")) != -1)
|
||||
{
|
||||
switch (arg)
|
||||
{
|
||||
case 'r':
|
||||
readit = 1;
|
||||
break;
|
||||
case 'w':
|
||||
writeit = 1;
|
||||
break;
|
||||
case 's':
|
||||
setit = 1;
|
||||
break;
|
||||
case 'u':
|
||||
universal = 1;
|
||||
break;
|
||||
case 'a':
|
||||
adjustit = 1;
|
||||
break;
|
||||
case 'D':
|
||||
debug = 1;
|
||||
break;
|
||||
case 'v':
|
||||
(void) fprintf( stderr, "clock " VERSION "\n" );
|
||||
exit(EXIT_SUCCESS);
|
||||
default:
|
||||
usage ();
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are in MkLinux do not even bother trying to set the clock */
|
||||
if(!access("/proc/osfmach3/version", R_OK))
|
||||
{ // We're running MkLinux
|
||||
if ( readit | writeit | setit | adjustit )
|
||||
printf("You must change the clock setting in MacOS.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (readit + writeit + setit + adjustit > 1)
|
||||
usage (); /* only allow one of these */
|
||||
|
||||
if (!(readit | writeit | setit | adjustit)) /* default to read */
|
||||
readit = 1;
|
||||
|
||||
adb_init ();
|
||||
|
||||
if (adjustit)
|
||||
{ /* Read adjustment parameters first */
|
||||
FILE *adj;
|
||||
if ((adj = fopen (ADJPATH, "r")) == NULL)
|
||||
{
|
||||
perror (ADJPATH);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (fscanf (adj, "%lf %d %lf", &factor, (int *) (&last_time),
|
||||
¬_adjusted) < 0)
|
||||
{
|
||||
perror (ADJPATH);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
(void) fclose (adj);
|
||||
if (debug) (void) printf(
|
||||
"Last adjustment done at %d seconds after 1/1/1970\n",
|
||||
(int) last_time);
|
||||
}
|
||||
|
||||
if (readit || setit || adjustit)
|
||||
{
|
||||
int ii;
|
||||
|
||||
if (write(adb_fd, get_packet, sizeof(get_packet)) < 0) {
|
||||
perror("write adb");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
ii = (int) read(adb_fd, reply, sizeof(reply));
|
||||
if (ii < 0) {
|
||||
perror("read adb");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (ii != 7)
|
||||
(void) fprintf(stderr,
|
||||
"Warning: bad reply length from CUDA (%d)\n", ii);
|
||||
clock_time = (time_t) ((reply[3] << 24) + (reply[4] << 16)
|
||||
+ (reply[5] << 8)) + (time_t) reply[6];
|
||||
clock_time -= RTC_OFFSET;
|
||||
|
||||
if (universal) {
|
||||
systime = clock_time;
|
||||
} else {
|
||||
tm = *gmtime(&clock_time);
|
||||
(void) printf("time in rtc is %s", asctime(&tm));
|
||||
tm.tm_isdst = -1; /* don't know whether it's DST */
|
||||
systime = mktime(&tm);
|
||||
}
|
||||
}
|
||||
|
||||
if (readit)
|
||||
{
|
||||
(void) printf ("%s", ctime (&systime ));
|
||||
}
|
||||
|
||||
if (setit || adjustit)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
||||
/* program is designed to run setuid, be secure! */
|
||||
|
||||
if (getuid () != 0)
|
||||
{
|
||||
(void) fprintf (stderr,
|
||||
"Sorry, must be root to set or adjust time\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (adjustit)
|
||||
{ /* the actual adjustment */
|
||||
double exact_adjustment;
|
||||
|
||||
exact_adjustment = ((double) (systime - last_time))
|
||||
* factor / (24 * 60 * 60)
|
||||
+ not_adjusted;
|
||||
if (exact_adjustment > 0.)
|
||||
adjustment = (int) (exact_adjustment + 0.5);
|
||||
else
|
||||
adjustment = (int) (exact_adjustment - 0.5);
|
||||
not_adjusted = exact_adjustment - (double) adjustment;
|
||||
systime += adjustment;
|
||||
if (debug) {
|
||||
(void) printf ("Time since last adjustment is %d seconds\n",
|
||||
(int) (systime - last_time));
|
||||
(void) printf ("Adjusting time by %d seconds\n",
|
||||
adjustment);
|
||||
(void) printf ("remaining adjustment is %.3f seconds\n",
|
||||
not_adjusted);
|
||||
}
|
||||
}
|
||||
#ifndef KEEP_OFF
|
||||
tv.tv_sec = systime;
|
||||
tv.tv_usec = 0;
|
||||
tz.tz_minuteswest = timezone / 60;
|
||||
tz.tz_dsttime = daylight;
|
||||
|
||||
if (settimeofday (&tv, &tz) != 0)
|
||||
{
|
||||
(void) fprintf (stderr,
|
||||
"Unable to set time -- probably you are not root\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
(void) printf( "Called settimeofday:\n" );
|
||||
(void) printf( "\ttv.tv_sec = %ld, tv.tv_usec = %ld\n",
|
||||
tv.tv_sec, tv.tv_usec );
|
||||
(void) printf( "\ttz.tz_minuteswest = %d, tz.tz_dsttime = %d\n",
|
||||
tz.tz_minuteswest, tz.tz_dsttime );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (writeit || (adjustit && adjustment != 0))
|
||||
{
|
||||
systime = time (NULL);
|
||||
|
||||
if (universal) {
|
||||
clock_time = systime;
|
||||
|
||||
} else {
|
||||
tmp = localtime(&systime);
|
||||
clock_time = mkgmtime(tmp);
|
||||
}
|
||||
|
||||
clock_time += RTC_OFFSET;
|
||||
set_packet[2] = clock_time >> 24;
|
||||
set_packet[3] = clock_time >> 16;
|
||||
set_packet[4] = clock_time >> 8;
|
||||
set_packet[5] = (unsigned char) clock_time;
|
||||
|
||||
if (write(adb_fd, set_packet, sizeof(set_packet)) < 0) {
|
||||
perror("write adb (set)");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
i = (int) read(adb_fd, reply, sizeof(reply));
|
||||
if (debug) {
|
||||
int j;
|
||||
(void) printf("set reply %d bytes:", i);
|
||||
for (j = 0; j < i; ++j)
|
||||
(void) printf(" %.2x", (unsigned int) reply[j]);
|
||||
(void) printf("\n");
|
||||
}
|
||||
if (i != 3 || reply[1] != (unsigned char) 0)
|
||||
(void) fprintf(stderr, "Warning: error %d setting RTC\n",
|
||||
(int) reply[1]);
|
||||
|
||||
if (debug) {
|
||||
clock_time -= RTC_OFFSET;
|
||||
(void) printf("set RTC to %s", asctime(gmtime(&clock_time)));
|
||||
}
|
||||
}
|
||||
else
|
||||
if (debug) (void) printf ("CMOS clock unchanged.\n");
|
||||
/* Save data for next 'adjustit' call */
|
||||
if (adjustit)
|
||||
{
|
||||
FILE *adj;
|
||||
if ((adj = fopen (ADJPATH, "w")) == NULL)
|
||||
{
|
||||
perror (ADJPATH);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
(void) fprintf (adj, "%f %d %f\n", factor, (int) systime, not_adjusted);
|
||||
(void) fclose (adj);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* Stolen from linux/arch/i386/kernel/time.c. */
|
||||
/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
|
||||
* Assumes input in normal date format, i.e. 1980-12-31 23:59:59
|
||||
* => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
|
||||
*
|
||||
* [For the Julian calendar (which was used in Russia before 1917,
|
||||
* Britain & colonies before 1752, anywhere else before 1582,
|
||||
* and is still in use by some communities) leave out the
|
||||
* -year/100+year/400 terms, and add 10.]
|
||||
*
|
||||
* This algorithm was first published by Gauss (I think).
|
||||
*
|
||||
* WARNING: this function will overflow on 2106-02-07 06:28:16 on
|
||||
* machines were long is 32-bit! (However, as time_t is signed, we
|
||||
* will already get problems at other places on 2038-01-19 03:14:08)
|
||||
*/
|
||||
time_t mkgmtime(struct tm *tm)
|
||||
{
|
||||
int mon = tm->tm_mon + 1;
|
||||
int year = tm->tm_year + 1900;
|
||||
|
||||
if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
|
||||
mon += 12; /* Puts Feb last since it has leap day */
|
||||
year -= 1;
|
||||
}
|
||||
return (((
|
||||
(unsigned long)(year/4 - year/100 + year/400 + 367*mon/12) +
|
||||
tm->tm_mday + year*365 - 719499
|
||||
)*24 + tm->tm_hour /* now have hours */
|
||||
)*60 + tm->tm_min /* now have minutes */
|
||||
)*60 + tm->tm_sec; /* finally seconds */
|
||||
}
|
|
@ -146,8 +146,9 @@ set_cmos_epoch(int ARCconsole, int SRM) {
|
|||
if (debug) printf (_("booted from MILO\n"));
|
||||
}
|
||||
|
||||
/* See whether we are dealing with a RUFFIAN aka UX, as they have REALLY
|
||||
different TOY (TimeOfYear) format: BCD, and not an ARC-style epoch.
|
||||
/* See whether we are dealing with a RUFFIAN aka Alpha PC-164 UX (or BX),
|
||||
as they have REALLY different TOY (TimeOfYear) format: BCD, and not
|
||||
an ARC-style epoch.
|
||||
BCD is detected dynamically, but we must NOT adjust like ARC. */
|
||||
if (ARCconsole && is_in_cpuinfo("system type", "Ruffian")) {
|
||||
ARCconsole = 0;
|
||||
|
|
|
@ -2,34 +2,35 @@
|
|||
.SH NAME
|
||||
clock \- query and set the hardware clock (RTC)
|
||||
.SH SYNOPSIS
|
||||
.B "hwclock --show"
|
||||
.B "hwclock \-\-show"
|
||||
.br
|
||||
.B "hwclock --set --date=newdate"
|
||||
.B "hwclock \-\-set \-\-date=newdate"
|
||||
.br
|
||||
.B "hwclock --systohc"
|
||||
.B "hwclock \-\-systohc"
|
||||
.br
|
||||
.B "hwclock --hctosys"
|
||||
.B "hwclock \-\-hctosys"
|
||||
.br
|
||||
.B "hwclock --getepoch"
|
||||
.B "hwclock \-\-getepoch"
|
||||
.br
|
||||
.B "hwclock --setepoch --epoch=year"
|
||||
.B "hwclock \-\-setepoch \-\-epoch=year"
|
||||
.br
|
||||
.B "hwclock --adjust"
|
||||
.B "hwclock \-\-adjust"
|
||||
.br
|
||||
.B "hwclock --version"
|
||||
.B "hwclock \-\-version"
|
||||
.PP
|
||||
other options:
|
||||
.PP
|
||||
.B "--utc --localtime --directisa --test --debug"
|
||||
.B "\-\-utc \-\-localtime \-\-directisa \-\-test \-\-debug"
|
||||
.PP
|
||||
and arcane options for DEC Alpha:
|
||||
.PP
|
||||
.B "--arc --jensen --srm --funky-toy"
|
||||
.B "\-\-arc \-\-jensen \-\-srm \-\-funky-toy"
|
||||
.PP
|
||||
Minimum unique abbreviations of all options are acceptable.
|
||||
.PP
|
||||
Also, equivalent options -r, -w, -s, -a, -v, -u, -D, -A, -J, -S, and -F
|
||||
are accepted for compatibility with the program "clock".
|
||||
Also, equivalent options \-r, \-w, \-s, \-a, \-v, \-u,
|
||||
\-D, \-A, \-J, \-S, and \-F are accepted for compatibility
|
||||
with the program "clock", while \-h asks for a help message.
|
||||
|
||||
.SH DESCRIPTION
|
||||
.I hwclock
|
||||
|
@ -239,7 +240,9 @@ are invalid if you don't have an Alpha and shouldn't be necessary if you
|
|||
do, because
|
||||
.I hwclock
|
||||
should be able to determine by itself what it's
|
||||
running on. These options make it possible for
|
||||
running on, at least when
|
||||
.I /proc
|
||||
is mounted. These options make it possible for
|
||||
.I hwclock
|
||||
to work even when
|
||||
its environment does not conform to its expectations and thus it cannot
|
||||
|
@ -259,10 +262,12 @@ automatically.
|
|||
means you are running on a Jensen model.
|
||||
|
||||
.B \-\-arc
|
||||
means your machine is running with ARC console time.
|
||||
means your machine uses epoch 1980 in its hardware clock, as is commonly
|
||||
the case for machines on ARC console (but Ruffians have epoch 1900).
|
||||
|
||||
.B \-\-srm
|
||||
means your machine is running with SRM console time.
|
||||
means your machine uses epoch 1900 in its hardware clock, as is commonly
|
||||
the case for machines on SRM console.
|
||||
|
||||
.B \-\-funky\-toy
|
||||
means that on your machine, one has to use the UF bit instead
|
||||
|
|
197
clock/hwclock.c
197
clock/hwclock.c
|
@ -75,9 +75,9 @@
|
|||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <shhopt.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "clock.h"
|
||||
#include "../version.h"
|
||||
#include "nls.h"
|
||||
|
||||
#define MYNAME "hwclock"
|
||||
|
@ -105,10 +105,18 @@ struct adjtime {
|
|||
updated since read from the disk file).
|
||||
*/
|
||||
bool dirty;
|
||||
/* line 1 */
|
||||
float drift_factor;
|
||||
time_t last_adj_time;
|
||||
float not_adjusted;
|
||||
/* line 2 */
|
||||
time_t last_calib_time;
|
||||
/* The most recent time that we set the clock from an external
|
||||
authority (as opposed to just doing a drift adjustment) */
|
||||
/* line 3 */
|
||||
enum a_local_utc {LOCAL, UTC, UNKNOWN} local_utc;
|
||||
/* To which time zone, local or UTC, we most recently set the
|
||||
hardware clock. */
|
||||
};
|
||||
|
||||
bool debug;
|
||||
|
@ -189,6 +197,25 @@ time_inc(struct timeval addend, float increment) {
|
|||
}
|
||||
|
||||
|
||||
static bool
|
||||
hw_clock_is_utc(const bool utc, const bool local_opt,
|
||||
const struct adjtime adjtime) {
|
||||
bool ret;
|
||||
|
||||
if (utc)
|
||||
ret = TRUE; /* --utc explicitly given on command line */
|
||||
else if (local_opt)
|
||||
ret = FALSE; /* --localtime explicitly given */
|
||||
else
|
||||
/* get info from adjtime file - default is local */
|
||||
ret = (adjtime.local_utc == UTC);
|
||||
if (debug)
|
||||
printf(_("Assuming hardware clock is kept in %s time.\n"),
|
||||
ret ? _("UTC") : _("local"));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
read_adjtime(struct adjtime *adjtime_p, int *rc_p) {
|
||||
|
@ -214,6 +241,7 @@ read_adjtime(struct adjtime *adjtime_p, int *rc_p) {
|
|||
adjtime_p->last_adj_time = 0;
|
||||
adjtime_p->not_adjusted = 0;
|
||||
adjtime_p->last_calib_time = 0;
|
||||
adjtime_p->local_utc = UNKNOWN;
|
||||
|
||||
*rc_p = 0;
|
||||
} else {
|
||||
|
@ -224,11 +252,14 @@ read_adjtime(struct adjtime *adjtime_p, int *rc_p) {
|
|||
} else {
|
||||
char line1[81]; /* String: first line of adjtime file */
|
||||
char line2[81]; /* String: second line of adjtime file */
|
||||
char line3[81]; /* String: third line of adjtime file */
|
||||
|
||||
line1[0] = '\0'; /* In case fgets fails */
|
||||
fgets(line1, sizeof(line1), adjfile);
|
||||
line2[0] = '\0'; /* In case fgets fails */
|
||||
fgets(line2, sizeof(line2), adjfile);
|
||||
line3[0] = '\0'; /* In case fgets fails */
|
||||
fgets(line3, sizeof(line3), adjfile);
|
||||
|
||||
fclose(adjfile);
|
||||
|
||||
|
@ -245,6 +276,19 @@ read_adjtime(struct adjtime *adjtime_p, int *rc_p) {
|
|||
|
||||
sscanf(line2, "%d", (int *) &adjtime_p->last_calib_time);
|
||||
|
||||
if (!strcmp(line3, "UTC\n"))
|
||||
adjtime_p->local_utc = UTC;
|
||||
else if (!strcmp(line3, "LOCAL\n"))
|
||||
adjtime_p->local_utc = LOCAL;
|
||||
else {
|
||||
adjtime_p->local_utc = UNKNOWN;
|
||||
if (line3[0]) {
|
||||
fprintf(stderr, _("%s: Warning: unrecognized third line in adjtime file\n"),
|
||||
MYNAME);
|
||||
fprintf(stderr, _("(Expected: `UTC' or `LOCAL' or nothing.)\n"));
|
||||
}
|
||||
}
|
||||
|
||||
*rc_p = 0;
|
||||
}
|
||||
adjtime_p->dirty = FALSE;
|
||||
|
@ -254,6 +298,9 @@ read_adjtime(struct adjtime *adjtime_p, int *rc_p) {
|
|||
(int) adjtime_p->last_adj_time);
|
||||
printf(_("Last calibration done at %d seconds after 1969\n"),
|
||||
(int) adjtime_p->last_calib_time);
|
||||
printf(_("Hardware clock is on %s time\n"),
|
||||
(adjtime_p->local_utc == LOCAL) ? _("local") :
|
||||
(adjtime_p->local_utc == UTC) ? _("UTC") : _("unknown"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -312,7 +359,6 @@ mktime_tz(struct tm tm, const bool universal,
|
|||
changing the local time zone to UTC.
|
||||
*/
|
||||
zone = (char *) getenv("TZ"); /* remember original time zone */
|
||||
mktime_result = mktime(&tm);
|
||||
if (universal) {
|
||||
/* Set timezone to UTC */
|
||||
setenv("TZ", "", TRUE);
|
||||
|
@ -340,7 +386,9 @@ mktime_tz(struct tm tm, const bool universal,
|
|||
*valid_p = TRUE;
|
||||
*systime_p = mktime_result;
|
||||
if (debug)
|
||||
printf(_("Hw clock time : %.2d:%.2d:%.2d = %d seconds since 1969\n"),
|
||||
printf(_("Hw clock time : %2d/%.2d/%.2d %.2d:%.2d:%.2d = "
|
||||
"%d seconds since 1969\n"),
|
||||
tm.tm_year, tm.tm_mon+1, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec, (int) *systime_p);
|
||||
}
|
||||
/* now put back the original zone. */
|
||||
|
@ -578,10 +626,7 @@ set_system_clock(const bool hclock_valid, const time_t newtime,
|
|||
|
||||
Also set the kernel time zone value to the value indicated by the
|
||||
TZ environment variable and/or /usr/lib/zoneinfo/, interpreted as
|
||||
tzset() would interpret them. Except: do not consider Daylight
|
||||
Savings Time to be a separate component of the time zone. Include
|
||||
any effect of DST in the basic timezone value and set the kernel
|
||||
DST value to 0.
|
||||
tzset() would interpret them.
|
||||
|
||||
EXCEPT: if hclock_valid is false, just issue an error message
|
||||
saying there is no valid time in the Hardware Clock to which to set
|
||||
|
@ -590,7 +635,7 @@ set_system_clock(const bool hclock_valid, const time_t newtime,
|
|||
If 'testing' is true, don't actually update anything -- just say we
|
||||
would have.
|
||||
-----------------------------------------------------------------------------*/
|
||||
int retcode; /* our eventual return code */
|
||||
int retcode;
|
||||
|
||||
if (!hclock_valid) {
|
||||
fprintf(stderr,_("The Hardware Clock does not contain a valid time, so "
|
||||
|
@ -598,21 +643,18 @@ set_system_clock(const bool hclock_valid, const time_t newtime,
|
|||
retcode = 1;
|
||||
} else {
|
||||
struct timeval tv;
|
||||
int rc; /* local return code */
|
||||
int rc;
|
||||
|
||||
tv.tv_sec = newtime;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
tzset(); /* init timezone, daylight from TZ or ...zoneinfo/localtime */
|
||||
/* An undocumented function of tzset() is to set global variabales
|
||||
'timezone' and 'daylight'
|
||||
*/
|
||||
tzset(); /* init timezone from TZ or ...zoneinfo/localtime */
|
||||
|
||||
if (debug) {
|
||||
printf( _("Calling settimeofday:\n") );
|
||||
printf( _("\ttv.tv_sec = %ld, tv.tv_usec = %ld\n"),
|
||||
(long) tv.tv_sec, (long) tv.tv_usec );
|
||||
printf( _("\ttz.tz_minuteswest = %ld\n"), timezone/60 - 60*daylight);
|
||||
printf( _("\ttz.tz_minuteswest = %ld\n"), timezone/60);
|
||||
}
|
||||
if (testing) {
|
||||
printf(_("Not setting system clock because running in test mode.\n"));
|
||||
|
@ -620,10 +662,11 @@ set_system_clock(const bool hclock_valid, const time_t newtime,
|
|||
} else {
|
||||
/* For documentation of settimeofday(), in addition to its man page,
|
||||
see kernel/time.c in the Linux source code.
|
||||
*/
|
||||
const struct timezone tz = { timezone/60 - 60*daylight, 0 };
|
||||
/* put daylight in minuteswest rather than dsttime,
|
||||
since the latter is mostly ignored ... */
|
||||
The code used to have `-60*daylight' here, but that is wrong.
|
||||
The variable `daylight' does not specify whether it is DST now. */
|
||||
|
||||
const struct timezone tz = { timezone/60, 0 };
|
||||
|
||||
rc = settimeofday(&tv, &tz);
|
||||
if (rc != 0) {
|
||||
if (errno == EPERM)
|
||||
|
@ -744,16 +787,17 @@ save_adjtime(const struct adjtime adjtime, const bool testing) {
|
|||
But if the contents are clean (unchanged since read from disk), don't
|
||||
bother.
|
||||
-----------------------------------------------------------------------------*/
|
||||
char newfile[405]; /* Stuff to write to disk file */
|
||||
char newfile[412]; /* Stuff to write to disk file */
|
||||
|
||||
if (adjtime.dirty) {
|
||||
/* snprintf is not always available, but this is safe
|
||||
as long as libc does not use more than 100 positions for %ld or %f */
|
||||
sprintf(newfile, "%f %ld %f\n%ld\n",
|
||||
sprintf(newfile, "%f %ld %f\n%ld\n%s\n",
|
||||
adjtime.drift_factor,
|
||||
(long) adjtime.last_adj_time,
|
||||
adjtime.not_adjusted,
|
||||
(long) adjtime.last_calib_time );
|
||||
(long) adjtime.last_calib_time,
|
||||
(adjtime.local_utc == UTC) ? "UTC" : "LOCAL");
|
||||
|
||||
if (testing) {
|
||||
printf(_("Not updating adjtime file because of testing mode.\n"));
|
||||
|
@ -883,9 +927,8 @@ manipulate_clock(const bool show, const bool adjust,
|
|||
const bool set, const time_t set_time,
|
||||
const bool hctosys, const bool systohc,
|
||||
const struct timeval startup_time,
|
||||
const bool universal, const bool testing,
|
||||
int *retcode_p
|
||||
) {
|
||||
const bool utc, const bool local_opt,
|
||||
const bool testing, int *retcode_p) {
|
||||
/*---------------------------------------------------------------------------
|
||||
Do all the normal work of hwclock - read, set clock, etc.
|
||||
|
||||
|
@ -902,7 +945,7 @@ manipulate_clock(const bool show, const bool adjust,
|
|||
|
||||
if (no_auth) *retcode_p = 1;
|
||||
else {
|
||||
if (adjust || set || systohc)
|
||||
if (adjust || set || systohc || (!utc && !local_opt))
|
||||
read_adjtime(&adjtime, &rc);
|
||||
else {
|
||||
/* A little trick to avoid reading the file if we don't have to */
|
||||
|
@ -911,6 +954,14 @@ manipulate_clock(const bool show, const bool adjust,
|
|||
}
|
||||
if (rc != 0) *retcode_p = 2;
|
||||
else {
|
||||
const bool universal = hw_clock_is_utc(utc, local_opt, adjtime);
|
||||
|
||||
if ((set || systohc || adjust) &&
|
||||
(adjtime.local_utc == UTC) != universal) {
|
||||
adjtime.local_utc = universal ? UTC : LOCAL;
|
||||
adjtime.dirty = TRUE;
|
||||
}
|
||||
|
||||
synchronize_to_clock_tick(retcode_p);
|
||||
/* this takes up to 1 second */
|
||||
if (*retcode_p == 0) {
|
||||
|
@ -1016,6 +1067,66 @@ manipulate_epoch(const bool getepoch, const bool setepoch,
|
|||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
usage - Output (error and) usage information
|
||||
|
||||
This function is called both directly from main to show usage
|
||||
information and as fatal function from shhopt if some argument is
|
||||
not understood. In case of normal usage info FMT should be NULL.
|
||||
In that case the info is printed to stdout. If FMT is given
|
||||
usage will act like fprintf( stderr, fmt, ... ), show a usage
|
||||
information and terminate the program afterwards.
|
||||
*/
|
||||
static void
|
||||
usage( const char *fmt, ... ) {
|
||||
FILE *usageto;
|
||||
va_list ap;
|
||||
|
||||
usageto = fmt ? stderr : stdout;
|
||||
|
||||
fprintf( usageto, _(
|
||||
"hwclock - query and set the hardware clock (RTC)\n\n"
|
||||
"Usage: hwclock [function] [options...]\n\n"
|
||||
"Functions:\n"
|
||||
" --help show this help\n"
|
||||
" --show read hardware clock and print result\n"
|
||||
" --set set the rtc to the time given with --date\n"
|
||||
" --hctosys set the system time from the hardware clock\n"
|
||||
" --systohc set the hardware clock to the current system time\n"
|
||||
" --adjust adjust the rtc to account for systematic drift since \n"
|
||||
" the clock was last set or adjusted\n"
|
||||
" --getepoch print out the kernel's hardware clock epoch value\n"
|
||||
" --setepoch set the kernel's hardware clock epoch value to the \n"
|
||||
" value given with --epoch\n"
|
||||
" --version print out the version of hwclock to stdout\n"
|
||||
"\nOptions: \n"
|
||||
" --utc the hardware clock is kept in coordinated universal time\n"
|
||||
" --localtime the hardware clock is kept in local time\n"
|
||||
" --directisa access the ISA bus directly instead of /dev/rtc\n"
|
||||
" --badyear ignore rtc's year because the bios is broken\n"
|
||||
" --date specifies the time to which to set the hardware clock\n"
|
||||
" --epoch=year specifies the year which is the beginning of the \n"
|
||||
" hardware clock's epoch value\n"
|
||||
));
|
||||
#ifdef __alpha__
|
||||
fprintf( usageto, _(
|
||||
" --jensen, --arc, --srm, --funky-toy\n"
|
||||
" tell hwclock the type of alpha you have (see hwclock(8))\n"
|
||||
) );
|
||||
#endif
|
||||
|
||||
|
||||
fflush(stdout);
|
||||
if( fmt ) {
|
||||
usageto = stderr;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
exit( fmt ? 99 : 0 );
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv, char **envp) {
|
||||
|
||||
|
@ -1034,12 +1145,14 @@ main(int argc, char **argv, char **envp) {
|
|||
are given by the option_def. The only exception is <show>, which
|
||||
may be modified after parsing is complete to effect an implied option.
|
||||
*/
|
||||
bool show, set, systohc, hctosys, adjust, getepoch, setepoch, version;
|
||||
bool ARCconsole, universal, testing, directisa, Jensen, SRM, funky_toy;
|
||||
bool help, show, set, systohc, hctosys, adjust, getepoch, setepoch, version;
|
||||
bool ARCconsole, utc, testing, directisa, Jensen, SRM, funky_toy;
|
||||
bool local_opt;
|
||||
char *date_opt;
|
||||
int epoch_opt;
|
||||
|
||||
const optStruct option_def[] = {
|
||||
{ 'h', (char *) "help", OPT_FLAG, &help, 0 },
|
||||
{ 'r', (char *) "show", OPT_FLAG, &show, 0 },
|
||||
{ 0, (char *) "set", OPT_FLAG, &set, 0 },
|
||||
{ 'w', (char *) "systohc", OPT_FLAG, &systohc, 0 },
|
||||
|
@ -1048,9 +1161,11 @@ main(int argc, char **argv, char **envp) {
|
|||
{ 0, (char *) "setepoch", OPT_FLAG, &setepoch, 0 },
|
||||
{ 'a', (char *) "adjust", OPT_FLAG, &adjust, 0 },
|
||||
{ 'v', (char *) "version", OPT_FLAG, &version, 0 },
|
||||
{ 'V', (char *) "version", OPT_FLAG, &version, 0 },
|
||||
{ 0, (char *) "date", OPT_STRING, &date_opt, 0 },
|
||||
{ 0, (char *) "epoch", OPT_UINT, &epoch_opt, 0 },
|
||||
{ 'u', (char *) "utc", OPT_FLAG, &universal, 0 },
|
||||
{ 'u', (char *) "utc", OPT_FLAG, &utc, 0 },
|
||||
{ 0, (char *) "localtime", OPT_FLAG, &local_opt, 0 },
|
||||
{ 0, (char *) "badyear", OPT_FLAG, &badyear, 0 },
|
||||
{ 0, (char *) "directisa", OPT_FLAG, &directisa, 0 },
|
||||
{ 0, (char *) "test", OPT_FLAG, &testing, 0 },
|
||||
|
@ -1073,8 +1188,8 @@ main(int argc, char **argv, char **envp) {
|
|||
textdomain(PACKAGE);
|
||||
|
||||
/* set option defaults */
|
||||
show = set = systohc = hctosys = adjust = getepoch = setepoch =
|
||||
version = universal = ARCconsole = SRM = funky_toy =
|
||||
help = show = set = systohc = hctosys = adjust = getepoch = setepoch =
|
||||
version = utc = local_opt = ARCconsole = SRM = funky_toy =
|
||||
directisa = badyear = Jensen = testing = debug = FALSE;
|
||||
date_opt = NULL;
|
||||
epoch_opt = -1;
|
||||
|
@ -1082,8 +1197,8 @@ main(int argc, char **argv, char **envp) {
|
|||
argc_parse = argc; argv_parse = argv;
|
||||
optParseOptions(&argc_parse, argv_parse, option_def, 0);
|
||||
/* Uses and sets argc_parse, argv_parse.
|
||||
Sets show, systohc, hctosys, adjust, universal, version, testing,
|
||||
debug, set, date_opt, getepoch, setepoch, epoch_opt
|
||||
Sets show, systohc, hctosys, adjust, utc, local_opt, version,
|
||||
testing, debug, set, date_opt, getepoch, setepoch, epoch_opt
|
||||
*/
|
||||
/* This is an ugly routine - for example, if I give an incorrect
|
||||
option, it only says "unrecognized option" without telling
|
||||
|
@ -1091,12 +1206,14 @@ main(int argc, char **argv, char **envp) {
|
|||
getopt() and usage() and throw shhopt out. */
|
||||
|
||||
if (argc_parse - 1 > 0) {
|
||||
fprintf(stderr, _("%s takes no non-option arguments. "
|
||||
usage( _("%s takes no non-option arguments. "
|
||||
"You supplied %d.\n"),
|
||||
MYNAME, argc_parse - 1);
|
||||
exit(100);
|
||||
}
|
||||
|
||||
if (help)
|
||||
usage( NULL );
|
||||
|
||||
if (show + set + systohc + hctosys + adjust +
|
||||
getepoch + setepoch + version > 1) {
|
||||
fprintf(stderr, _("You have specified multiple function options.\n"
|
||||
|
@ -1104,6 +1221,12 @@ main(int argc, char **argv, char **envp) {
|
|||
exit(100);
|
||||
}
|
||||
|
||||
if (utc && local_opt) {
|
||||
fprintf(stderr, _("%s: The --utc and --localtime options are mutually "
|
||||
"exclusive. You specified both.\n"), MYNAME);
|
||||
exit(100);
|
||||
}
|
||||
|
||||
#ifdef __alpha__
|
||||
set_cmos_epoch(ARCconsole, SRM);
|
||||
set_cmos_access(Jensen, funky_toy);
|
||||
|
@ -1145,6 +1268,8 @@ main(int argc, char **argv, char **envp) {
|
|||
} else if (getepoch || setepoch) {
|
||||
manipulate_epoch(getepoch, setepoch, epoch_opt, testing);
|
||||
} else {
|
||||
if (debug)
|
||||
printf(MYNAME " " VERSION "/%s\n",util_linux_version);
|
||||
determine_clock_access_method(directisa);
|
||||
if (!ur)
|
||||
fprintf(stderr, _("Cannot access the Hardware Clock via any known "
|
||||
|
@ -1152,7 +1277,7 @@ main(int argc, char **argv, char **envp) {
|
|||
"search for an access method.\n"));
|
||||
else
|
||||
manipulate_clock(show, adjust, set, set_time, hctosys, systohc,
|
||||
startup_time, universal, testing, &rc);
|
||||
startup_time, utc, local_opt, testing, &rc);
|
||||
}
|
||||
}
|
||||
exit(retcode);
|
||||
|
@ -1161,7 +1286,7 @@ main(int argc, char **argv, char **envp) {
|
|||
/* A single routine for greater uniformity */
|
||||
void
|
||||
outsyserr(char *msg) {
|
||||
fprintf(stderr, _("%s: %s, errno=%d: %s.\n"),
|
||||
fprintf(stderr, "%s: %s, errno=%d: %s.\n",
|
||||
progname, msg, errno, strerror(errno));
|
||||
}
|
||||
|
||||
|
|
15
clock/kd.c
15
clock/kd.c
|
@ -3,6 +3,7 @@
|
|||
#include <fcntl.h> /* for O_RDONLY */
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "../defines.h" /* for HAVE_nanosleep */
|
||||
#include "clock.h"
|
||||
#include "nls.h"
|
||||
|
||||
|
@ -46,6 +47,20 @@ synchronize_to_clock_tick_kd(void) {
|
|||
|
||||
i = 0;
|
||||
do {
|
||||
/* Added by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
|
||||
/* "The culprit is the fast loop with KDGHWCLK ioctls. It seems
|
||||
the kernel gets confused by those on Amigas with A2000 RTCs
|
||||
and simply hangs after some time. Inserting a nanosleep helps." */
|
||||
/* Christian T. Steigies: 1 instead of 1000000 is still sufficient
|
||||
to keep the machine from freezing. */
|
||||
|
||||
#ifdef HAVE_nanosleep
|
||||
struct timespec sleep = { 0, 1 };
|
||||
nanosleep( &sleep, NULL );
|
||||
#else
|
||||
usleep(1);
|
||||
#endif
|
||||
|
||||
if (i++ >= 1000000) {
|
||||
fprintf(stderr, _("Timed out waiting for time change.\n"));
|
||||
return 2;
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
# Makefile -- Makefile for util-linux Linux utilities
|
||||
#
|
||||
include ../make_include
|
||||
include ../MCONFIG
|
||||
|
||||
# Where to put man pages?
|
||||
|
||||
MAN8= hwclock.8
|
||||
|
||||
# Where to put binaries?
|
||||
# See the "install" rule for the links. . .
|
||||
|
||||
SBIN= hwclock
|
||||
|
||||
|
||||
all: $(SBIN)
|
||||
|
||||
|
||||
CFLAGS = -s -Wall -Wwrite-strings -Wstrict-prototypes -Winline $(CDEBUG)
|
||||
|
||||
hwclock: hwclock.o rtc.o directio.o kd.o util.o shhopt.o
|
||||
hwclock.o: shhopt.h
|
||||
hwclock.o rtc.o directio.o kd.o util.o: hwclock.h
|
||||
|
||||
install: all
|
||||
$(INSTALLDIR) $(SBINDIR) $(BINDIR) $(USRBINDIR)
|
||||
$(INSTALLBIN) $(SBIN) $(SBINDIR)
|
||||
$(INSTALLMAN) $(MAN8) $(MAN8DIR)
|
||||
|
||||
clean:
|
||||
-rm -f *.o *~ core $(SBIN)
|
|
@ -1,727 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
This is a component of the hwclock program.
|
||||
|
||||
This file contains the code for accessing the hardware clock via
|
||||
direct I/O (kernel-style input and output operations) as opposed
|
||||
to via a device driver.
|
||||
|
||||
|
||||
MAINTENANCE NOTES
|
||||
|
||||
Here is some information on how the Hardware Clock works, from
|
||||
unknown source and authority. In theory, the specification for this
|
||||
stuff is the specification of Motorola's MC146818A clock chip, used
|
||||
in the early ISA machines. Subsequent machines should have copied
|
||||
its function exactly. In reality, though, the copies are inexact
|
||||
and the MC146818A itself may fail to implement its specifications,
|
||||
and we have just have to work with whatever is there (actually,
|
||||
anything that Windows works with, because that's what determines
|
||||
whether broken hardware has to be fixed!).
|
||||
|
||||
i386 CMOS starts out with 14 bytes clock data
|
||||
alpha has something similar, but with details
|
||||
depending on the machine type.
|
||||
|
||||
byte 0: seconds (0-59)
|
||||
byte 2: minutes (0-59)
|
||||
byte 4: hours (0-23 in 24hr mode,
|
||||
1-12 in 12hr mode, with high bit unset/set if am/pm)
|
||||
byte 6: weekday (1-7, Sunday=1)
|
||||
byte 7: day of the month (1-31)
|
||||
byte 8: month (1-12)
|
||||
byte 9: year (0-99)
|
||||
|
||||
|
||||
Numbers are stored in BCD/binary if bit 2 of byte 11 is unset/set
|
||||
The clock is in 12hr/24hr mode if bit 1 of byte 11 is unset/set
|
||||
The clock is undefined (being updated) if bit 7 of byte 10 is set.
|
||||
The clock is frozen (to be updated) by setting bit 7 of byte 11
|
||||
Bit 7 of byte 14 indicates whether the CMOS clock is reliable:
|
||||
it is 1 if RTC power has been good since this bit was last read;
|
||||
it is 0 when the battery is dead and system power has been off.
|
||||
|
||||
The century situation is messy:
|
||||
|
||||
Usually byte 50 (0x32) gives the century (in BCD, so 0x19 or 0x20 in
|
||||
pure binary), but IBM PS/2 has (part of) a checksum there and uses
|
||||
byte 55 (0x37). Sometimes byte 127 (0x7f) or Bank 1, byte 0x48
|
||||
gives the century. The original RTC will not access any century
|
||||
byte; some modern versions will. If a modern RTC or BIOS increments
|
||||
the century byte it may go from 0x19 to 0x20, but in some buggy
|
||||
cases 0x1a is produced.
|
||||
|
||||
CMOS byte 10 (clock status register A) has 3 bitfields:
|
||||
bit 7: 1 if data invalid, update in progress (read-only bit)
|
||||
(this is raised 224 us before the actual update starts)
|
||||
6-4 select base frequency
|
||||
010: 32768 Hz time base (default)
|
||||
111: reset
|
||||
all other combinations are manufacturer-dependent
|
||||
(e.g.: DS1287: 010 = start oscillator, anything else = stop)
|
||||
3-0 rate selection bits for interrupt
|
||||
0000 none
|
||||
0001, 0010 give same frequency as 1000, 1001
|
||||
0011 122 microseconds (minimum, 8192 Hz)
|
||||
.... each increase by 1 halves the frequency, doubles the period
|
||||
1111 500 milliseconds (maximum, 2 Hz)
|
||||
0110 976.562 microseconds (default 1024 Hz)
|
||||
|
||||
Avoid setting the RTC clock within 2 seconds of the day rollover
|
||||
that starts a new month or enters daylight saving time.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__i386__) || defined(__alpha__)
|
||||
#include <asm/io.h> /* for inb, outb */
|
||||
#else
|
||||
void outb(int a, int b){}
|
||||
int inb(int c){ return 0; }
|
||||
#endif
|
||||
|
||||
#include "hwclock.h"
|
||||
|
||||
#define BCD_TO_BIN(val) (((val)&0x0f) + ((val)>>4)*10)
|
||||
#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
ATOMIC_TOP and ATOMIC_BOTTOM are wierd macros that help us to do
|
||||
atomic operations when we do ugly low level I/O.
|
||||
|
||||
You put ATOMIC_TOP above some code and ATOMIC_BOTTOM below it and
|
||||
it makes sure all the enclosed code executes without interruption
|
||||
by some other process (and, in some cases, even the kernel).
|
||||
|
||||
These work fundamentally differently depending on the machine
|
||||
architecture. In the case of a x86, it simply turns interrupts off
|
||||
at the top and turns them back on at the bottom.
|
||||
|
||||
For Alpha, we can't mess with interrupts (we shouldn't for x86
|
||||
either, but at least it tends to work!), so instead we start a loop
|
||||
at the top and close it at the bottom. This loop repeats the
|
||||
enclosed code until the upper 32 bits of the cycle counter are the
|
||||
same before and after. That means there was no context change
|
||||
while the enclosed code was executing.
|
||||
|
||||
For other architectures, we do nothing, and the atomicity is only
|
||||
feigned.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(__i386__)
|
||||
#define ATOMIC_TOP \
|
||||
{ \
|
||||
const bool interrupts_were_enabled = interrupts_enabled; \
|
||||
__asm__ volatile ("cli"); \
|
||||
interrupts_enabled = FALSE;
|
||||
|
||||
#define ATOMIC_BOTTOM \
|
||||
if (interrupts_were_enabled) { \
|
||||
__asm__ volatile ("sti"); \
|
||||
interrupts_enabled = TRUE; \
|
||||
} \
|
||||
}
|
||||
#elif defined(__alpha__)
|
||||
#define ATOMIC_TOP \
|
||||
{ \
|
||||
unsigned long ts1, ts2, n; \
|
||||
n = 0; \
|
||||
do { \
|
||||
asm volatile ("rpcc %0" : "r="(ts1));
|
||||
|
||||
#define ATOMIC_BOTTOM \
|
||||
asm volatile ("rpcc %0" : "r="(ts2)); \
|
||||
n++; \
|
||||
} while ((ts1 ^ ts2) >> 32 != 0); \
|
||||
}
|
||||
#else
|
||||
#define ATOMIC_BOTTOM
|
||||
#define ATOMIC_TOP
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__i386__) || defined(__alpha__)
|
||||
/* The following are just constants. Oddly, this program will not
|
||||
compile if the inb() and outb() functions use something even
|
||||
slightly different from these variables. This is probably at least
|
||||
partially related to the fact that __builtin_constant_p() doesn't
|
||||
work (is never true) in an inline function. See comment to this
|
||||
effect in asm/io.h.
|
||||
*/
|
||||
static unsigned short clock_ctl_addr = 0x70;
|
||||
static unsigned short clock_data_addr = 0x71;
|
||||
#endif
|
||||
|
||||
|
||||
static bool interrupts_enabled;
|
||||
/* Interrupts are enabled as normal. We, unfortunately, turn interrupts
|
||||
on the machine off in some places where we do the direct ISA accesses
|
||||
to the Hardware Clock. It is in extremely poor form for a user space
|
||||
program to do this, but that's the price we have to pay to run on an
|
||||
ISA machine without the rtc driver in the kernel.
|
||||
|
||||
Code which turns interrupts off uses this value to determine if they
|
||||
need to be turned back on.
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
assume_interrupts_enabled(void) {
|
||||
interrupts_enabled = TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
i386_iopl(const int level) {
|
||||
/*----------------------------------------------------------------------------
|
||||
When compiled for an Intel target, this is just the iopl() kernel call.
|
||||
When compiled for any other target, this is a dummy function.
|
||||
|
||||
We do it this way in order to keep the conditional compilation stuff
|
||||
out of the way so it doesn't mess up readability of the code.
|
||||
-----------------------------------------------------------------------------*/
|
||||
#ifdef __i386__
|
||||
extern int iopl(int level);
|
||||
return iopl(level);
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
uf_bit_needed(const bool user_wants_uf) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Return true iff the UIP bit doesn't work on this hardware clock, so
|
||||
we will need to use the UF bit to synchronize with the clock (if in
|
||||
fact we synchronize using direct I/O to the clock).
|
||||
|
||||
To wit, we need to use the UF bit on a DEC Alpha PC164/LX164/SX164.
|
||||
Or, of course, if the user told us to.
|
||||
-----------------------------------------------------------------------------*/
|
||||
bool retval;
|
||||
|
||||
if (user_wants_uf) retval = TRUE;
|
||||
else {
|
||||
if (alpha_machine && (
|
||||
is_in_cpuinfo("system variation", "PC164") ||
|
||||
is_in_cpuinfo("system variation", "LX164") ||
|
||||
is_in_cpuinfo("system variation", "SX164")))
|
||||
retval = TRUE;
|
||||
else retval = FALSE;
|
||||
}
|
||||
if (debug && retval)
|
||||
printf("We will be using the UF bit instead of the usual "
|
||||
"UIP bit to synchronize with the clock, as required on "
|
||||
"certain models of DEC Alpha.\n");
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
zero_year(const bool arc_opt, const bool srm_opt) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Return the year of the century (e.g. 0) to which a zero value in
|
||||
the year register of the hardware clock applies (or at least what
|
||||
we are to assume -- nobody can say for sure!)
|
||||
|
||||
'arc_opt' and 'srm_opt' are the true iff the user specified the
|
||||
corresponding invocation option to instruct us that the machine is an
|
||||
Alpha with ARC or SRM console time.
|
||||
|
||||
A note about hardware clocks:
|
||||
|
||||
ISA machines are simple: the year register is a year-of-century
|
||||
register, so the zero year is zero. On Alphas, we may see 1980 or
|
||||
1952 (Digital Unix?) or 1958 (ALPHA_PRE_V1_2_SRM_CONSOLE)
|
||||
-----------------------------------------------------------------------------*/
|
||||
int retval; /* our return value */
|
||||
|
||||
if (arc_opt || srm_opt) {
|
||||
/* User is telling us what epoch his machine uses. Believe it. */
|
||||
if (arc_opt) retval = 0;
|
||||
else retval = 0;
|
||||
} else {
|
||||
unsigned long kernel_epoch;
|
||||
char *reason; /* malloc'ed */
|
||||
|
||||
get_epoch(&kernel_epoch, &reason);
|
||||
if (reason == NULL) retval = kernel_epoch;
|
||||
else {
|
||||
/* OK, the user doesn't know and the kernel doesn't know;
|
||||
figure it out from the machine model
|
||||
*/
|
||||
free(reason); /* Don't care about kernel's excuses */
|
||||
/* See whether we are dealing with SRM or MILO, as they have
|
||||
different "epoch" ideas. */
|
||||
if (is_in_cpuinfo("system serial number", "MILO")) {
|
||||
if (debug) printf("booted from MILO\n");
|
||||
/* See whether we are dealing with a RUFFIAN aka UX, as they
|
||||
have REALLY different TOY (TimeOfYear) format: BCD, and not
|
||||
an ARC-style epoch. BCD is detected dynamically, but we
|
||||
must NOT adjust like ARC.
|
||||
*/
|
||||
if (is_in_cpuinfo("system type", "Ruffian")) {
|
||||
if (debug) printf("Ruffian BCD clock\n");
|
||||
retval = 0;
|
||||
} else {
|
||||
if (debug) printf("Not Ruffian BCD clock\n");
|
||||
retval = 80;
|
||||
}
|
||||
} else {
|
||||
if (debug) printf("Not booted from MILO\n");
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline unsigned char
|
||||
hclock_read(const unsigned char reg, const int dev_port) {
|
||||
/*---------------------------------------------------------------------------
|
||||
Relative byte 'reg' of the Hardware Clock value.
|
||||
|
||||
Get this with direct CPU I/O instructions. If 'dev_port' is not -1,
|
||||
use the /dev/port device driver (via the 'dev_port' file descriptor)
|
||||
to do this I/O. Otherwise, use the kernel's inb()/outb() facility.
|
||||
|
||||
On a system without the inb()/outb() facility, if 'dev_port' is -1,
|
||||
just return 0.
|
||||
|
||||
Results undefined if 'reg' is out of range.
|
||||
---------------------------------------------------------------------------*/
|
||||
unsigned char ret;
|
||||
|
||||
ATOMIC_TOP
|
||||
if (dev_port >= 0) {
|
||||
const unsigned char v = reg | 0x80;
|
||||
lseek(dev_port, 0x170, 0);
|
||||
write(dev_port, &v, 1);
|
||||
lseek(dev_port, 0x171, 0);
|
||||
read(dev_port, &ret, 1);
|
||||
} else {
|
||||
#if defined(__i386__) || defined(__alpha__)
|
||||
/* & 0x7f ensures that we are not disabling NMI while we read.
|
||||
Setting on Bit 7 here would disable NMI
|
||||
|
||||
Various docs suggest that one should disable NMI while
|
||||
reading/writing CMOS data, and enable it again afterwards.
|
||||
This would yield the sequence
|
||||
outb (reg | 0x80, 0x70);
|
||||
val = inb(0x71);
|
||||
outb (0x0d, 0x70); // 0x0d: random read-only location
|
||||
Other docs state that "any write to 0x70 should be followed
|
||||
by an action to 0x71 or the RTC wil be left in an unknown state".
|
||||
Most docs say that it doesn't matter at all what one does.
|
||||
*/
|
||||
outb(reg & 0x7f, clock_ctl_addr);
|
||||
ret = inb(clock_data_addr);
|
||||
#else
|
||||
ret = 0;
|
||||
#endif
|
||||
}
|
||||
ATOMIC_BOTTOM
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline void
|
||||
hclock_write(unsigned char reg, unsigned char val, const int dev_port) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Set relative byte 'reg' of the Hardware Clock value to 'val'.
|
||||
Do this with the kernel's outb() function if 'dev_port' is -1, but
|
||||
if not, use the /dev/port device (via the 'dev_port' file descriptor),
|
||||
which is almost the same thing.
|
||||
|
||||
On a non-ISA, non-Alpha machine, if 'dev_port' is -1, do nothing.
|
||||
----------------------------------------------------------------------------*/
|
||||
if (dev_port >= 0) {
|
||||
unsigned char v;
|
||||
v = reg | 0x80;
|
||||
lseek(dev_port, 0x170, 0);
|
||||
write(dev_port, &v, 1);
|
||||
v = (val & 0xff);
|
||||
lseek(dev_port, 0x171, 0);
|
||||
write(dev_port, &v, 1);
|
||||
} else {
|
||||
#if defined(__i386__) || defined(__alpha__)
|
||||
/* & 0x7f ensures that we are not disabling NMI while we read.
|
||||
Setting on Bit 7 here would disable NMI
|
||||
*/
|
||||
outb(reg & 0x7f, clock_ctl_addr);
|
||||
outb(val, clock_data_addr);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static inline int
|
||||
hardware_clock_busy(const int dev_port, const bool use_uf_bit) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Return whether the hardware clock is in the middle of an update
|
||||
(which happens once each second).
|
||||
|
||||
Use the clock's UIP bit (bit 7 of Control Register A) to tell
|
||||
unless 'use_uf_bit' is true, in which case use the UF bit (bit 4 of
|
||||
Control Register C).
|
||||
-----------------------------------------------------------------------------*/
|
||||
return
|
||||
use_uf_bit ? (hclock_read(12, dev_port) & 0x10) :
|
||||
(hclock_read(10, dev_port) & 0x80);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
synchronize_to_clock_tick_ISA(int *retcode_p, const int dev_port,
|
||||
const bool use_uf_bit) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Same as synchronize_to_clock_tick(), but just for ISA.
|
||||
-----------------------------------------------------------------------------*/
|
||||
int i; /* local loop index */
|
||||
|
||||
/* Wait for rise. Should be within a second, but in case something
|
||||
weird happens, we have a limit on this loop to reduce the impact
|
||||
of this failure.
|
||||
*/
|
||||
for (i = 0;
|
||||
!hardware_clock_busy(dev_port, use_uf_bit) && (i < 10000000);
|
||||
i++);
|
||||
if (i >= 10000000) *retcode_p = 1;
|
||||
else {
|
||||
/* Wait for fall. Should be within 2.228 ms. */
|
||||
for (i = 0;
|
||||
hardware_clock_busy(dev_port, use_uf_bit) && (i < 1000000);
|
||||
i++);
|
||||
if (i >= 10000000) *retcode_p = 1;
|
||||
else *retcode_p = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
read_hardware_clock_isa(struct tm *tm, const int dev_port,
|
||||
int hc_zero_year) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Read the hardware clock and return the current time via <tm> argument.
|
||||
Assume we have an ISA machine and read the clock directly with CPU I/O
|
||||
instructions. If 'dev_port' isn't -1, use the /dev/port facility to
|
||||
do this I/O. Otherwise, use the kernel's inb()/outb() service.
|
||||
|
||||
This function is not totally reliable. It takes a finite and
|
||||
unpredictable amount of time to execute the code below. During that
|
||||
time, the clock may change and we may even read an invalid value in
|
||||
the middle of an update. We do a few checks to minimize this
|
||||
possibility, but only the kernel can actually read the clock
|
||||
properly, since it can execute code in a short and predictable
|
||||
amount of time (by turning off interrupts).
|
||||
|
||||
In practice, the chance of this function returning the wrong time is
|
||||
extremely remote.
|
||||
|
||||
-----------------------------------------------------------------------------*/
|
||||
bool got_time;
|
||||
/* We've successfully read a time from the Hardware Clock */
|
||||
int attempts;
|
||||
/* Number of times we've tried to read the clock. This only
|
||||
matters because we will give up (and proceed with garbage in
|
||||
variables) rather than hang if something is broken and we are
|
||||
never able to read the clock
|
||||
*/
|
||||
int hclock_sec = 0, hclock_min = 0, hclock_hour = 0, hclock_wday = 0,
|
||||
hclock_mon = 0, hclock_mday = 0, hclock_year = 0;
|
||||
/* The values we got from the Hardware Clock's registers, assuming
|
||||
they are in pure binary.
|
||||
*/
|
||||
|
||||
int status = 0; /* Hardware Clock status register, as if pure binary */
|
||||
int adjusted_year;
|
||||
int ampmhour;
|
||||
int pmbit;
|
||||
|
||||
got_time = FALSE;
|
||||
attempts = 0; /* initial value */
|
||||
while (!got_time && attempts++ < 1000000) {
|
||||
/* Bit 7 of Byte 10 of the Hardware Clock value is the Update In Progress
|
||||
(UIP) bit, which is on while and 244 uS before the Hardware Clock
|
||||
updates itself. It updates the counters individually, so reading
|
||||
them during an update would produce garbage. The update takes 2mS,
|
||||
so we could be spinning here that long waiting for this bit to turn
|
||||
off.
|
||||
|
||||
Furthermore, it is pathologically possible for us to be in this
|
||||
code so long that even if the UIP bit is not on at first, the
|
||||
clock has changed while we were running. We check for that too,
|
||||
and if it happens, we start over.
|
||||
*/
|
||||
|
||||
if ((hclock_read(10, dev_port) & 0x80) == 0) {
|
||||
/* No clock update in progress, go ahead and read */
|
||||
|
||||
status = hclock_read(11, dev_port);
|
||||
|
||||
hclock_sec = hclock_read(0, dev_port);
|
||||
hclock_min = hclock_read(2, dev_port);
|
||||
hclock_hour = hclock_read(4, dev_port);
|
||||
hclock_wday = hclock_read(6, dev_port);
|
||||
hclock_mday = hclock_read(7, dev_port);
|
||||
hclock_mon = hclock_read(8, dev_port);
|
||||
hclock_year = hclock_read(9, dev_port);
|
||||
/* Unless the clock changed while we were reading, consider this
|
||||
a good clock read .
|
||||
*/
|
||||
if (hclock_sec == hclock_read(0, dev_port)) got_time = TRUE;
|
||||
/* Yes, in theory we could have been running for 60 seconds and
|
||||
the above test wouldn't work!
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
if (!(status & 0x04)) {
|
||||
/* The hardware clock is in BCD mode. This is normal. */
|
||||
tm->tm_sec = BCD_TO_BIN(hclock_sec);
|
||||
tm->tm_min = BCD_TO_BIN(hclock_min);
|
||||
ampmhour = BCD_TO_BIN(hclock_hour & 0x7f);
|
||||
pmbit = hclock_hour & 0x80;
|
||||
tm->tm_wday = BCD_TO_BIN(hclock_wday) - 1; /* Used to be 3. Why?? */
|
||||
tm->tm_mday = BCD_TO_BIN(hclock_mday);
|
||||
tm->tm_mon = BCD_TO_BIN(hclock_mon) - 1;
|
||||
adjusted_year = BCD_TO_BIN(hclock_year);
|
||||
} else {
|
||||
/* The hardware clock registers are in pure binary format. */
|
||||
tm->tm_sec = hclock_sec;
|
||||
tm->tm_min = hclock_min;
|
||||
ampmhour = hclock_hour & 0x7f;
|
||||
pmbit = hclock_hour & 0x80;
|
||||
tm->tm_wday = hclock_wday - 1; /* Used to be 3. Why?? */
|
||||
tm->tm_mday = hclock_mday;
|
||||
tm->tm_mon = hclock_mon - 1;
|
||||
adjusted_year = hclock_year;
|
||||
}
|
||||
|
||||
if (!(status & 0x02)) {
|
||||
/* Clock is in 12 hour (am/pm) mode. This is unusual. */
|
||||
if (pmbit == 0x80) {
|
||||
if (ampmhour == 12) tm->tm_hour = 12;
|
||||
else tm->tm_hour = 12 + ampmhour;
|
||||
} else {
|
||||
if (ampmhour ==12) tm->tm_hour = 0;
|
||||
else tm->tm_hour = ampmhour;
|
||||
}
|
||||
} else {
|
||||
/* Clock is in 24 hour mode. This is normal. */
|
||||
tm->tm_hour = ampmhour;
|
||||
}
|
||||
/* We don't use the century byte (Byte 50) of the Hardware Clock.
|
||||
Here's why: It didn't exist in the original ISA specification,
|
||||
so old machines don't have it, and even some new ones don't.
|
||||
Some machines, including the IBM Valuepoint 6387-X93, use that
|
||||
byte for something else. Some machines have the century in
|
||||
Byte 55.
|
||||
|
||||
Furthermore, the Linux standard time data structure doesn't
|
||||
allow for times beyond about 2037 and no Linux systems were
|
||||
running before 1937. Therefore, all the century byte could tell
|
||||
us is that the clock is wrong or this whole program is obsolete!
|
||||
|
||||
So we just say if the year of century is less than 37, it's the
|
||||
2000's, otherwise it's the 1900's.
|
||||
|
||||
Alpha machines (some, anyway) don't have this ambiguity
|
||||
because they do not have a year-of-century register. We
|
||||
pretend they do anyway, for simplicity and to avoid
|
||||
recognizing times that can't be represented in Linux standard
|
||||
time. So even though we already have enough information to
|
||||
know that the clock says 2050, we will render it as 1950.
|
||||
*/
|
||||
{
|
||||
const int year_of_century = (adjusted_year + hc_zero_year) % 100;
|
||||
if (year_of_century >= 37) tm->tm_year = year_of_century;
|
||||
else tm->tm_year = year_of_century + 100;
|
||||
}
|
||||
tm->tm_isdst = -1; /* don't know whether it's daylight */
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_hardware_clock_isa(const struct tm new_tm,
|
||||
const int hc_zero_year,
|
||||
const int dev_port,
|
||||
const bool testing) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Set the Hardware Clock to the time (in broken down format)
|
||||
new_tm. Use direct I/O instructions to what we assume is
|
||||
an ISA Hardware Clock.
|
||||
|
||||
Iff 'dev_port' is -1, use the kernel inb()/outb() service, otherwise
|
||||
use the /dev/port device (via file descriptor 'dev_port')
|
||||
to do those I/O instructions.
|
||||
----------------------------------------------------------------------------*/
|
||||
unsigned char save_control, save_freq_select;
|
||||
|
||||
if (testing)
|
||||
printf("Not setting Hardware Clock because running in test mode.\n");
|
||||
else {
|
||||
int ampmhour;
|
||||
/* The hour number that goes into the hardware clock, taking into
|
||||
consideration whether the clock is in 12 or 24 hour mode
|
||||
*/
|
||||
int pmbit;
|
||||
/* Value to OR into the hour register as the am/pm bit */
|
||||
const int adjusted_year =
|
||||
(new_tm.tm_year - hc_zero_year)%100;
|
||||
/* The number that goes in the hardware clock's year register */
|
||||
|
||||
int hclock_sec, hclock_min, hclock_hour, hclock_wday, hclock_mon,
|
||||
hclock_mday, hclock_year;
|
||||
/* The values we will put, in pure binary, in the Hardware Clock's
|
||||
registers.
|
||||
*/
|
||||
|
||||
ATOMIC_TOP
|
||||
|
||||
save_control = hclock_read(11, dev_port);
|
||||
/* tell the clock it's being set */
|
||||
hclock_write(11, (save_control | 0x80), dev_port);
|
||||
save_freq_select = hclock_read(10, dev_port);
|
||||
/* stop and reset prescaler */
|
||||
hclock_write (10, (save_freq_select | 0x70), dev_port);
|
||||
|
||||
|
||||
if (!(save_control & 0x02)) {
|
||||
/* Clock is in 12 hour (am/pm) mode. This is unusual. */
|
||||
if (new_tm.tm_hour == 0) {
|
||||
ampmhour = 12;
|
||||
pmbit = 0x00;
|
||||
} else if (new_tm.tm_hour < 12) {
|
||||
ampmhour = new_tm.tm_hour;
|
||||
pmbit = 0x00;
|
||||
} else if (new_tm.tm_hour == 12) {
|
||||
ampmhour = 12;
|
||||
pmbit = 0x80;
|
||||
} else {
|
||||
ampmhour = new_tm.tm_hour - 12;
|
||||
pmbit = 0x80;
|
||||
}
|
||||
} else {
|
||||
/* Clock is in 24 hour mode. This is normal. */
|
||||
ampmhour = new_tm.tm_hour;
|
||||
pmbit = 0x00;
|
||||
}
|
||||
|
||||
|
||||
if (!(save_control & 0x04)) {
|
||||
/* Clock's registers are in BCD. This is normal. */
|
||||
hclock_sec = BIN_TO_BCD(new_tm.tm_sec);
|
||||
hclock_min = BIN_TO_BCD(new_tm.tm_min);
|
||||
hclock_hour = pmbit | BIN_TO_BCD(ampmhour);
|
||||
hclock_wday = BIN_TO_BCD(new_tm.tm_wday + 1); /* Used to be 3. Why??*/
|
||||
hclock_mday = BIN_TO_BCD(new_tm.tm_mday);
|
||||
hclock_mon = BIN_TO_BCD(new_tm.tm_mon + 1);
|
||||
hclock_year = BIN_TO_BCD(adjusted_year);
|
||||
} else {
|
||||
/* Clock's registers are in pure binary. This is unusual. */
|
||||
hclock_sec = new_tm.tm_sec;
|
||||
hclock_min = new_tm.tm_min;
|
||||
hclock_hour = pmbit | ampmhour;
|
||||
hclock_wday = new_tm.tm_wday + 1; /* Used to be 3. Why?? */
|
||||
hclock_mday = new_tm.tm_mday;
|
||||
hclock_mon = new_tm.tm_mon + 1;
|
||||
hclock_year = adjusted_year;
|
||||
}
|
||||
|
||||
hclock_write(0, hclock_sec, dev_port);
|
||||
hclock_write(2, hclock_min, dev_port);
|
||||
hclock_write(4, hclock_hour, dev_port);
|
||||
hclock_write(6, hclock_wday, dev_port);
|
||||
hclock_write(7, hclock_mday, dev_port);
|
||||
hclock_write(8, hclock_mon, dev_port);
|
||||
hclock_write(9, hclock_year, dev_port);
|
||||
|
||||
/* We don't set the century byte (usually Byte 50) because it isn't
|
||||
always there. (see further comments in read_hardware_clock_isa).
|
||||
In previous releases, we did.
|
||||
*/
|
||||
|
||||
/* The kernel sources, linux/arch/i386/kernel/time.c, have the
|
||||
following comment:
|
||||
|
||||
The following flags have to be released exactly in this order,
|
||||
otherwise the DS12887 (popular MC146818A clone with integrated
|
||||
battery and quartz) will not reset the oscillator and will not
|
||||
update precisely 500 ms later. You won't find this mentioned
|
||||
in the Dallas Semiconductor data sheets, but who believes data
|
||||
sheets anyway ... -- Markus Kuhn
|
||||
|
||||
Hence, they will also be done in this order here.
|
||||
faith@cs.unc.edu, Thu Nov 9 08:26:37 1995
|
||||
*/
|
||||
|
||||
hclock_write (11, save_control, dev_port);
|
||||
hclock_write (10, save_freq_select, dev_port);
|
||||
|
||||
ATOMIC_BOTTOM
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
get_inb_outb_privilege(const enum clock_access_method clock_access,
|
||||
bool * const no_auth_p) {
|
||||
|
||||
if (clock_access == ISA) {
|
||||
const int rc = i386_iopl(3);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, MYNAME " is unable to get I/O port access. "
|
||||
"I.e. iopl(3) returned nonzero return code %d.\n"
|
||||
"This is often because the program isn't running "
|
||||
"with superuser privilege, which it needs.\n",
|
||||
rc);
|
||||
*no_auth_p = TRUE;
|
||||
} else *no_auth_p = FALSE;
|
||||
} else *no_auth_p = FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
get_dev_port_access(const enum clock_access_method clock_access,
|
||||
int * dev_port_p) {
|
||||
|
||||
if (clock_access == DEV_PORT) {
|
||||
/* Get the /dev/port file open */
|
||||
*dev_port_p = open("/dev/port", O_RDWR);
|
||||
if (*dev_port_p < 0) {
|
||||
fprintf(stderr, MYNAME "is unable to open the /dev/port file. "
|
||||
"I.e. open() of the file failed with errno = %s (%d).\n"
|
||||
"Run with the --debug option and check documentation "
|
||||
"to find out why we are trying "
|
||||
"to use /dev/port instead of some other means to access "
|
||||
"the Hardware Clock.",
|
||||
strerror(errno), errno);
|
||||
}
|
||||
} else *dev_port_p = 0;
|
||||
}
|
||||
|
||||
|
||||
|
599
clockB/hwclock.8
599
clockB/hwclock.8
|
@ -1,599 +0,0 @@
|
|||
.TH CLOCK 8 "02 March 1998"
|
||||
.SH NAME
|
||||
clock \- query and set the hardware clock (RTC)
|
||||
.SH SYNOPSIS
|
||||
.B "hwclock --show"
|
||||
.br
|
||||
.B "hwclock --set --date=newdate"
|
||||
.br
|
||||
.B "hwclock --systohc"
|
||||
.br
|
||||
.B "hwclock --hctosys"
|
||||
.br
|
||||
.B "hwclock --getepoch"
|
||||
.br
|
||||
.B "hwclock --setepoch --epoch=year"
|
||||
.br
|
||||
.B "hwclock --adjust"
|
||||
.br
|
||||
.B "hwclock --version"
|
||||
.PP
|
||||
other options:
|
||||
.PP
|
||||
.B "--utc --localtime --directisa --test --debug"
|
||||
.PP
|
||||
and arcane options for DEC Alpha:
|
||||
.PP
|
||||
.B "--arc --jensen --srm --funky-toy"
|
||||
.PP
|
||||
Minimum unique abbreviations of all options are acceptable.
|
||||
.PP
|
||||
Also, equivalent options -r, -w, -s, -a, -v, -u, -D, -A, -J, -S, and -F
|
||||
are accepted for compatibility with the program "clock".
|
||||
|
||||
.SH DESCRIPTION
|
||||
.I hwclock
|
||||
is a tool for accessing the Hardware Clock. You can display the
|
||||
current time, set the Hardware Clock to a specified time, set the
|
||||
Hardware Clock to the System Time, and set the System Time from the
|
||||
Hardware Clock.
|
||||
.PP
|
||||
You can also run
|
||||
.I hwclock
|
||||
periodically to insert or remove time from the Hardware Clock to
|
||||
compensate for systematic drift (where the clock consistently gains or
|
||||
loses time at a certain rate if left to run).
|
||||
|
||||
.SH OPTIONS
|
||||
You need exactly one of the following options to tell
|
||||
.I hwclock
|
||||
what function to perform:
|
||||
.PP
|
||||
.TP
|
||||
.B \-\-show
|
||||
Read the Hardware Clock and print the time on Standard Output.
|
||||
The time is always in local time, even if you keep your Hardware Clock
|
||||
in Coordinated Universal Time. See the
|
||||
.B \-\-utc
|
||||
option.
|
||||
|
||||
.TP
|
||||
.B \-\-set
|
||||
Set the Hardware Clock to the time given by the
|
||||
.B \-\-date
|
||||
option.
|
||||
.TP
|
||||
.B \-\-hctosys
|
||||
Set the System Time from the Hardware Clock.
|
||||
|
||||
Also set the kernel's timezone value to the local timezone as indicated by
|
||||
the TZ environment variable and/or
|
||||
.IR /usr/lib/zoneinfo ,
|
||||
as
|
||||
.BR tzset (3)
|
||||
would interpret them. EXCEPT: always set the Daylight Savings Time part of
|
||||
the kernel's timezone value to 0 ("not Daylight Savings Time"). If DST
|
||||
is indicated, just add an hour to the base part.
|
||||
|
||||
See the discussion of timezones below.
|
||||
|
||||
This is a good option to use in one of the system startup scripts.
|
||||
.TP
|
||||
.B \-\-systohc
|
||||
Set the Hardware Clock to the current System Time.
|
||||
.TP
|
||||
.B \-\-adjust
|
||||
Add or subtract time from the Hardware Clock to account for systematic
|
||||
drift since the last time the clock was set or adjusted. See discussion
|
||||
below.
|
||||
.TP
|
||||
.B \-\-getepoch
|
||||
Print out standard output the kernel's Hardware Clock epoch value.
|
||||
This is the number of years into AD to which a zero year value in the
|
||||
Hardware Clock refers. For example, if you are using the convention
|
||||
that the year counter in your Hardware Clock contains the number of
|
||||
full years since 1952, then the kernel's Hardware Counter epoch value
|
||||
must be 1952.
|
||||
|
||||
This epoch value is used whenever hwclock reads or sets the Hardware Clock.
|
||||
.TP
|
||||
.B \-\-setepoch
|
||||
Set the kernel's Hardware Clock epoch value to the value specified by the
|
||||
.B \-\-epoch
|
||||
option. See the
|
||||
.B \-\-getepoch
|
||||
option for details.
|
||||
.TP
|
||||
.B \-\-version
|
||||
Print the version of
|
||||
.I hwclock
|
||||
on Standard Output.
|
||||
.br
|
||||
You need the following option if you specify
|
||||
.B \-\-set
|
||||
option. Otherwise, it is ignored.
|
||||
.TP
|
||||
.B \-\-date=date_string
|
||||
Specifies the time to which to set the Hardware Clock. The value of this
|
||||
option is an argument to the
|
||||
.I date(1)
|
||||
program. For example,
|
||||
.sp
|
||||
.I hwclock --set --date="9/22/96 16:45:05"
|
||||
.sp
|
||||
The argument is in local time, even if you keep your Hardware Clock in
|
||||
Coordinated Universal time. See the
|
||||
.I \-\-utc
|
||||
option.
|
||||
|
||||
.TP
|
||||
.B \-\-epoch=year
|
||||
Specifies the year which is the beginning of the Hardware Clock's
|
||||
epoch. I.e. the number of years into AD to which a zero value in the
|
||||
Hardware Clock's year counter refers.
|
||||
|
||||
For example,
|
||||
.sp
|
||||
.I hwclock --setepoch --epoch=1952
|
||||
|
||||
.PP
|
||||
The following options apply to most functions.
|
||||
.TP
|
||||
.B \-\-utc
|
||||
.TP
|
||||
.B \-\-localtime
|
||||
Indicates that the Hardware Clock is kept in Coordinated Universal
|
||||
Time or local time, respectively. It is your choice whether to keep
|
||||
your clock in UTC or local time, but nothing in the clock tells which
|
||||
you've chosen. So this option is how you give that information to
|
||||
.IR hwclock .
|
||||
|
||||
If you specify the wrong one of these options (or specify neither and
|
||||
take a wrong default), both setting and querying of the Hardware Clock
|
||||
will be messed up.
|
||||
|
||||
If you specify neither
|
||||
.B \-\-utc
|
||||
nor
|
||||
.B \-\-localtime
|
||||
, the default is whichever was specified the last time
|
||||
.I hwclock
|
||||
was used to set the clock (i.e. hwclock was successfully run with the
|
||||
.B \-\-set
|
||||
,
|
||||
.B \-\-systohc
|
||||
,
|
||||
or
|
||||
.B \-\-adjust
|
||||
options), as recorded in the adjtime file. If the adjtime file doesn't
|
||||
exist, the default is local time.
|
||||
|
||||
.TP
|
||||
.B \-\-directisa
|
||||
is meaningful only on an ISA machine or an Alpha (which implements enough
|
||||
of ISA to be, roughly speaking, an ISA machine for
|
||||
.IR hwclock 's
|
||||
purposes). For other machines, it has no effect. This option tells
|
||||
.I hwclock
|
||||
to use explicit I/O instructions to access the Hardware Clock.
|
||||
Without this option,
|
||||
.I hwclock
|
||||
will try to use the /dev/rtc device (which it assumes to be driven by the
|
||||
rtc device driver). If it is unable to open the device (for read), it will
|
||||
use the explicit I/O instructions anyway.
|
||||
|
||||
The rtc device driver was new in Linux Release 2.
|
||||
.TP
|
||||
.B \-\-badyear
|
||||
Indicates that the Hardware Clock is incapable of storing years outside
|
||||
the range 1994-1999. There is a problem in some BIOSes (almost all
|
||||
Award BIOSes made between 4/26/94 and 5/31/95) wherein they are unable
|
||||
to deal with years after 1999. If one attempts to set the year-of-century
|
||||
value to something less than 94 (or 95 in some cases), the value that
|
||||
actually gets set is 94 (or 95). Thus, if you have one of these machines,
|
||||
.I hwclock
|
||||
cannot set the year after 1999 and cannot use the value of the clock as
|
||||
the true time in the normal way.
|
||||
|
||||
To compensate for this (without your getting a BIOS update, which would
|
||||
definitely be preferable), always use
|
||||
.B \-\-badyear
|
||||
if you have one of these machines. When
|
||||
.I hwclock
|
||||
knows it's working with a brain-damaged clock, it ignores the year part of
|
||||
the Hardware Clock value and instead tries to guess the year based on the
|
||||
last calibrated date in the adjtime file, by assuming that that date is
|
||||
within the past year. For this to work, you had better do a
|
||||
.I hwclock \-\-set
|
||||
or
|
||||
.I hwclock \-\-systohc
|
||||
at least once a year!
|
||||
|
||||
Though
|
||||
.I hwclock
|
||||
ignores the year value when it reads the Hardware Clock, it sets the
|
||||
year value when it sets the clock. It sets it to 1995, 1996, 1997, or
|
||||
1998, whichever one has the same position in the leap year cycle as
|
||||
the true year. That way, the Hardware Clock inserts leap days where
|
||||
they belong. Again, if you let the Hardware Clock run for more than a
|
||||
year without setting it, this scheme could be defeated and you could
|
||||
end up losing a day.
|
||||
|
||||
.I hwclock
|
||||
warns you that you probably need
|
||||
.B \-\-badyear
|
||||
whenever it finds your Hardware Clock set to 1994 or 1995.
|
||||
|
||||
.TP
|
||||
.B \-\-srm
|
||||
.TP
|
||||
.B \-\-arc
|
||||
.TP
|
||||
.B \-\-jensen
|
||||
.TP
|
||||
.B \-\-funky\-toy
|
||||
These options all tell
|
||||
.I hwclock
|
||||
what kind of Alpha machine you have. They
|
||||
are invalid if you don't have an Alpha and shouldn't be necessary if you
|
||||
do, because
|
||||
.I hwclock
|
||||
should be able to determine by itself what it's
|
||||
running on. These options make it possible for
|
||||
.I hwclock
|
||||
to work even when
|
||||
its environment does not conform to its expectations and thus it cannot
|
||||
accurately determine what sort of system it is running on. If you think
|
||||
hwclock is incorrectly determining the system's characteristics, try
|
||||
running with the
|
||||
.B \-\-debug
|
||||
option to see what conclusions the program is
|
||||
reaching and how. If you find you need one of these options to make
|
||||
.I hwclock
|
||||
work, contact the
|
||||
.I hwclock
|
||||
maintainer to see if the program can be improved to detect your system
|
||||
automatically.
|
||||
|
||||
.B \-\-jensen
|
||||
means you are running on a Jensen model.
|
||||
|
||||
.B \-\-arc
|
||||
means your machine is running with ARC console time.
|
||||
|
||||
.B \-\-srm
|
||||
means your machine is running with SRM console time.
|
||||
|
||||
.B \-\-funky\-toy
|
||||
means that on your machine, one has to use the UF bit instead
|
||||
of the UIP bit in the Hardware Clock to detect a time transition. "Toy"
|
||||
in the option name refers to the Time Of Year facility of the machine.
|
||||
|
||||
|
||||
.TP
|
||||
.B \-\-test
|
||||
Do everything except actually updating the Hardware Clock or anything
|
||||
else. This is useful, especially in conjunction with
|
||||
.B \-\-debug,
|
||||
in learning about
|
||||
.I hwclock.
|
||||
.TP
|
||||
.B \-\-debug
|
||||
Display a lot of information about what
|
||||
.I hwclock
|
||||
is doing internally. Some of its function is complex and this output
|
||||
can help you understand how the program works.
|
||||
|
||||
|
||||
.SH NOTES
|
||||
|
||||
|
||||
.SH Clocks in a Linux System
|
||||
.PP
|
||||
There are two main clocks in a Linux system:
|
||||
.PP
|
||||
.B The Hardware Clock:
|
||||
This is a clock that runs independently of any control program running
|
||||
in the CPU and even when the machine is powered off.
|
||||
|
||||
On an ISA system, this clock is specified as part of the ISA standard.
|
||||
The control program can read or set this clock to a whole second, but
|
||||
the control program can also detect the edges of the 1 second clock
|
||||
ticks, so the clock actually has virtually infinite precision.
|
||||
.PP
|
||||
This clock is commonly called the hardware clock, the real time clock,
|
||||
the RTC, the BIOS clock, and the CMOS clock. Hardware Clock, in its
|
||||
capitalized form, was coined for use by
|
||||
.I hwclock
|
||||
because all of the other names are inappropriate to the point of being
|
||||
misleading.
|
||||
.PP
|
||||
.B The System Time:
|
||||
This is the time kept by a clock inside the Linux kernel and driven by
|
||||
a timer interrupt. (On an ISA machine, the timer interrupt is part of
|
||||
the ISA standard). It has meaning only while Linux is running on the
|
||||
machine. The System Time is the number of seconds since 00:00:00
|
||||
January 1, 1970 UTC (or more succinctly, the number of seconds since
|
||||
1969). The System Time is not an integer, though. It has virtually
|
||||
infinite precision.
|
||||
.PP
|
||||
The System Time is the time that matters. The Hardware Clock's basic
|
||||
purpose in a Linux system is to keep time when Linux is not running. You
|
||||
initialize the System Time to the time from the Hardware Clock when Linux
|
||||
starts up, and then never use the Hardware Clock again. Note that in DOS,
|
||||
for which ISA was designed, the Hardware Clock is the only real time clock.
|
||||
.PP
|
||||
It is important that the System Time not have any discontinuities such as
|
||||
would happen if you used the
|
||||
.BR date (1L)
|
||||
program to set it while the system is running. You can, however, do whatever
|
||||
you want to the Hardware Clock while the system is running, and the next
|
||||
time Linux starts up, it will do so with the adjusted time from the Hardware
|
||||
Clock. You can also use the program
|
||||
.BR adjtimex (8)
|
||||
to smoothly adjust the System Time while the system runs.
|
||||
.PP
|
||||
A Linux kernel maintains a concept of a local timezone for the system.
|
||||
But don't be misled -- almost nobody cares what timezone the kernel
|
||||
thinks it is in. Instead, programs that care about the timezone
|
||||
(perhaps because they want to display a local time for you) almost
|
||||
always use a more traditional method of determining the timezone: They
|
||||
use the TZ environment variable and/or the /usr/local/timezone
|
||||
directory, as explained in the man page for tzset(3). However, some
|
||||
programs and fringe parts of the Linux kernel such as filesystems use
|
||||
the kernel timezone value. An example is the vfat filesystem. If the
|
||||
kernel timezone value is wrong, the vfat filesystem will report and
|
||||
set the wrong timestamps on files.
|
||||
.PP
|
||||
.I hwclock
|
||||
sets the kernel timezone to the value indicated by TZ and/or
|
||||
/usr/local/timezone when you set the System Time using the
|
||||
.B \-\-hctosys
|
||||
option.
|
||||
.PP
|
||||
A complication is that the timezone value actually consists of two
|
||||
parts: 1) how far from the Standard Meridian the locality is
|
||||
geographically, and 2) whether or not a Daylight Savings Time (DST)
|
||||
convention is in effect in the locality at the present time. In
|
||||
practice, the DST part of the timezone value is almost never used, so
|
||||
if the geographical part were to be set to its correct value, the
|
||||
users of the timezone value would actually compute the wrong local
|
||||
time.
|
||||
.PP
|
||||
Therefore,
|
||||
.I hwclock
|
||||
violates the definition of the kernel's timezone value and always sets
|
||||
the DST part to zero. If DST is supposed to be in effect,
|
||||
.I hwclock
|
||||
simply adds an hour to the geographical part.
|
||||
|
||||
.SH How hwclock Accesses the Hardware Clock
|
||||
.PP
|
||||
.I hwclock
|
||||
Uses many different ways to get and set Hardware Clock values.
|
||||
The most normal way is to do I/O to the device special file /dev/rtc,
|
||||
which is presumed to be driven by the rtc device driver. However,
|
||||
this method is not always available. For one thing, the rtc driver is
|
||||
a relatively recent addition to Linux. Older systems don't have it.
|
||||
Also, though there are versions of the rtc driver that work on DEC
|
||||
Alphas, there appear to be plenty of Alphas on which the rtc driver
|
||||
does not work (a common symptom is hwclock hanging).
|
||||
.PP
|
||||
On older systems, the method of accessing the Hardware Clock depends on
|
||||
the system hardware.
|
||||
.PP
|
||||
On an ISA system,
|
||||
.I hwclock
|
||||
can directly access the "CMOS memory" registers that
|
||||
constitute the clock, by doing I/O to Ports 0x70 and 0x71. It does
|
||||
this with actual I/O instructions and consequently can only do it if
|
||||
running with superuser effective userid. (In the case of a Jensen
|
||||
Alpha, there is no way for
|
||||
.I hwclock
|
||||
to execute those I/O instructions, and so it uses instead the
|
||||
/dev/port device special file, which provides almost as low-level an
|
||||
interface to the I/O subsystem).
|
||||
|
||||
This is a really poor method of accessing the clock, for all the
|
||||
reasons that user space programs are generally not supposed to do
|
||||
direct I/O and disable interrupts. Hwclock provides it because it is
|
||||
the only method available on ISA and Alpha systems which don't have
|
||||
working rtc device drivers available.
|
||||
|
||||
.PP
|
||||
On an m68k system,
|
||||
.I hwclock
|
||||
can access the clock via the console driver, via the device special
|
||||
file /dev/tty1.
|
||||
.PP
|
||||
.I hwclock
|
||||
tries to use /dev/rtc. If it is compiled for a kernel that doesn't have
|
||||
that function or it is unable to open /dev/rtc,
|
||||
.I hwclock
|
||||
will fall back to another method, if available. On an ISA or Alpha
|
||||
machine, you can force
|
||||
.I hwclock
|
||||
to use the direct manipulation of the CMOS registers without even trying
|
||||
.I /dev/rtc
|
||||
by specifying the \-\-directisa option.
|
||||
|
||||
|
||||
.SH The Adjust Function
|
||||
.PP
|
||||
The Hardware Clock is usually not very accurate. However, much of its
|
||||
inaccuracy is completely predictable - it gains or loses the same amount
|
||||
of time every day. This is called systematic drift.
|
||||
.IR hwclock 's
|
||||
"adjust" function lets you make systematic corrections to correct the
|
||||
systematic drift.
|
||||
.PP
|
||||
It works like this:
|
||||
.I hwclock
|
||||
keeps a file,
|
||||
.I /etc/adjtime,
|
||||
that keeps some historical information. This is called the adjtime file.
|
||||
.PP
|
||||
Suppose you start with no adjtime file. You issue a
|
||||
.I hwclock \-\-set
|
||||
command to set the Hardware Clock to the true current time.
|
||||
.I Hwclock
|
||||
creates the adjtime file and records in it the current time as the
|
||||
last time the clock was calibrated.
|
||||
5 days
|
||||
later, the clock has gained 10 seconds, so you issue another
|
||||
.I hwclock \-\-set
|
||||
command to set it back 10 seconds.
|
||||
.I Hwclock
|
||||
updates the adjtime file to show the current time as the last time the
|
||||
clock was calibrated, and records 2 seconds per day as the systematic
|
||||
drift rate. 24 hours go by, and then you issue a
|
||||
.I hwclock \-\-adjust
|
||||
command.
|
||||
.I Hwclock
|
||||
consults the adjtime file and sees that the clock gains 2 seconds per
|
||||
day when left alone and that it has been left alone for exactly one
|
||||
day. So it subtracts 2 seconds from the Hardware Clock. It then
|
||||
records the current time as the last time the clock was adjusted.
|
||||
Another 24 hours goes by and you issue another
|
||||
.I hwclock \-\-adjust.
|
||||
.I Hwclock
|
||||
does the same thing: subtracts 2 seconds and updates the adjtime file
|
||||
with the current time as the last time the clock was adjusted.
|
||||
.PP
|
||||
Every time you calibrate (set) the clock (using
|
||||
.I \-\-set
|
||||
or
|
||||
.I \-\-systohc
|
||||
),
|
||||
.I hwclock
|
||||
recalculates the systematic drift rate based on how long it has been
|
||||
since the last calibration, how long it has been since the last
|
||||
adjustment, what drift rate was assumed in any intervening
|
||||
adjustments, and the amount by which the clock is presently off.
|
||||
.PP
|
||||
A small amount of error creeps in any time
|
||||
.I hwclock
|
||||
sets the clock, so it refrains from making an adjustment that would be
|
||||
less than 1 second. Later on, when you request an adjustment again,
|
||||
the accumulated drift will be more than a second and
|
||||
.I hwclock
|
||||
will do the adjustment then.
|
||||
.PP
|
||||
It is good to do a
|
||||
.I hwclock \-\-adjust
|
||||
just before the
|
||||
.I hwclock \-\-hctosys
|
||||
at system startup time, and maybe periodically while the system is
|
||||
running via cron.
|
||||
.PP
|
||||
The adjtime file, while named for its historical purpose of controlling
|
||||
adjustments only, actually contains other information for use by hwclock
|
||||
in remembering information from one invocation to the next.
|
||||
.PP
|
||||
The format of the adjtime file is, in ASCII:
|
||||
.PP
|
||||
Line 1: 3 numbers, separated by blanks: 1) systematic drift rate in
|
||||
seconds per day, floating point decimal; 2) Resulting number of
|
||||
seconds since 1969 UTC of most recent adjustment or calibration,
|
||||
decimal integer; 3) zero (for compatibility with
|
||||
.IR clock )
|
||||
as a decimal integer.
|
||||
.PP
|
||||
Line 2: 1 number: Resulting number of seconds since 1969 UTC of most
|
||||
recent calibration. Zero if there has been no calibration yet or it
|
||||
is known that any previous calibration is moot (for example, because
|
||||
the Hardware Clock has been found, since that calibration, not to
|
||||
contain a valid time). This is a decimal integer.
|
||||
.PP
|
||||
Line 3: "UTC" or "LOCAL". Tells whether the Hardware Clock is set to
|
||||
Coordinated Universal Time or local time. You can always override this
|
||||
value with options on the
|
||||
.I hwclock
|
||||
command line.
|
||||
.PP
|
||||
You can use an adjtime file that was previously used with the
|
||||
.I clock
|
||||
program with
|
||||
.I hwclock.
|
||||
|
||||
|
||||
.SH "Automatic Hardware Clock Synchronization By the Kernel"
|
||||
|
||||
You should be aware of another way that the Hardware Clock is kept
|
||||
synchronized in some systems. The Linux kernel has a mode wherein it
|
||||
copies the System Time to the Hardware Clock every 11 minutes.
|
||||
This is a good mode to use when you are using something sophisticated
|
||||
like ntp to keep your System Time synchronized. (ntp is a way to keep
|
||||
your System Time synchronized either to a time server somewhere on the
|
||||
network or to a radio clock hooked up to your system. See RFC 1305).
|
||||
|
||||
This mode (we'll call it "11 minute mode") is off until something
|
||||
turns it on. The ntp daemon xntpd is one thing that turns it on. You
|
||||
can turn it off by running anything, including
|
||||
.IR "hwclock \-\-hctosys" ,
|
||||
that sets the System Time the old fashioned way.
|
||||
|
||||
To see if it is on or
|
||||
off, use the command
|
||||
.I adjtimex \-\-print
|
||||
and look at the value of "status". If the "64" bit of this number
|
||||
(expressed in binary) equal to 0, 11 minute mode is on. Otherwise, it
|
||||
is off.
|
||||
|
||||
If your system runs with 11 minute mode on, don't use
|
||||
.I hwclock \-\-adjust
|
||||
or
|
||||
.IR "hwclock \-\-hctosys" .
|
||||
You'll just make a mess. It is acceptable to use a
|
||||
.I hwclock \-\-hctosys
|
||||
at startup time to get a reasonable System Time until your system is
|
||||
able to set the System Time from the external source and start 11
|
||||
minute mode.
|
||||
|
||||
|
||||
.SH ISA Hardware Clock Century value
|
||||
|
||||
There is some sort of standard that defines CMOS memory Byte 50 on an ISA
|
||||
machine as an indicator of what century it is.
|
||||
.I hwclock
|
||||
does not use or set that byte because there are some machines that
|
||||
don't define the byte that way, and it really isn't necessary anyway,
|
||||
since the year-of-century does a good job of implying which century it
|
||||
is.
|
||||
|
||||
If you have a bona fide use for a CMOS century byte, contact the
|
||||
.I hwclock
|
||||
maintainer; an option may be appropriate.
|
||||
|
||||
Note that this section is only relevant when you are using the "direct
|
||||
ISA" method of accessing the Hardware Clock.
|
||||
|
||||
|
||||
|
||||
.SH "ENVIRONMENT VARIABLES"
|
||||
.I TZ
|
||||
|
||||
.SH FILES
|
||||
.I /etc/adjtime
|
||||
.I /usr/lib/zoneinfo/
|
||||
.I /dev/rtc
|
||||
.I /dev/port
|
||||
.I /dev/tty1
|
||||
.I /proc/cpuinfo
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR adjtimex (8),
|
||||
.BR date (1),
|
||||
.BR gettimeofday (2),
|
||||
.BR settimeofday (2),
|
||||
.BR crontab (1),
|
||||
.BR tzset (3)
|
||||
|
||||
.SH AUTHORS
|
||||
Written By Bryan Henderson, September 1996 (bryanh@giraffe-data.com),
|
||||
based on work done on the
|
||||
.I clock
|
||||
program by Charles Hedrick, Rob Hooft, and Harald Koenig.
|
||||
See the source code for complete history and credits.
|
||||
|
||||
|
1744
clockB/hwclock.c
1744
clockB/hwclock.c
File diff suppressed because it is too large
Load diff
139
clockB/hwclock.h
139
clockB/hwclock.h
|
@ -1,139 +0,0 @@
|
|||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
typedef int bool;
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define MYNAME "hwclock"
|
||||
#define VERSION "2.5"
|
||||
|
||||
|
||||
enum clock_access_method {ISA, RTC_IOCTL, KD, DEV_PORT, NOCLOCK};
|
||||
/* A method for accessing (reading, writing) the hardware clock:
|
||||
|
||||
ISA:
|
||||
via direct CPU I/O instructions that work on an ISA family
|
||||
machine (IBM PC compatible) or most DEC Alphas, which implement
|
||||
enough of ISA to get by.
|
||||
|
||||
RTC_IOCTL:
|
||||
via the rtc device driver, using device special file /dev/rtc.
|
||||
|
||||
KD:
|
||||
via the console driver, using device special file /dev/tty1.
|
||||
This is the m68k ioctl interface, known as KDGHWCLK.
|
||||
|
||||
DEV_PORT:
|
||||
via the /dev/port device, which is almost the same thing as
|
||||
direct I/O instructions via the ISA method, but works on a Jensen
|
||||
model of Alpha, whereas ISA does not. Also, use I/O addresses
|
||||
0x170 and 0x171 instead of the ISA 0x70 and 0x71.
|
||||
|
||||
NO_CLOCK:
|
||||
Unable to determine a usable access method for the system clock.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/* hwclock.c */
|
||||
extern int debug;
|
||||
extern const bool alpha_machine;
|
||||
extern const bool isa_machine;
|
||||
|
||||
/* directio.c */
|
||||
|
||||
extern void
|
||||
assume_interrupts_enabled(void);
|
||||
|
||||
extern void
|
||||
synchronize_to_clock_tick_ISA(int *retcode_p, const int dev_port,
|
||||
const bool use_uf_bit);
|
||||
|
||||
extern void
|
||||
read_hardware_clock_isa(struct tm *tm, const int dev_port,
|
||||
int hc_zero_year);
|
||||
|
||||
extern void
|
||||
set_hardware_clock_isa(const struct tm new_tm,
|
||||
const int hc_zero_year,
|
||||
const int dev_port,
|
||||
const bool testing);
|
||||
|
||||
extern void
|
||||
get_inb_outb_privilege(const enum clock_access_method clock_access,
|
||||
bool * const no_auth_p);
|
||||
|
||||
extern void
|
||||
get_dev_port_access(const enum clock_access_method clock_access,
|
||||
int * dev_port_p);
|
||||
|
||||
extern bool
|
||||
uf_bit_needed(const bool user_wants_uf);
|
||||
|
||||
extern int
|
||||
zero_year(const bool arc_opt, const bool srm_opt);
|
||||
|
||||
|
||||
/* rtc.c */
|
||||
extern void
|
||||
synchronize_to_clock_tick_RTC(int *retcode_p);
|
||||
|
||||
extern void
|
||||
read_hardware_clock_rtc_ioctl(struct tm *tm);
|
||||
|
||||
extern void
|
||||
set_hardware_clock_rtc_ioctl(const struct tm new_broken_time,
|
||||
const bool testing);
|
||||
extern void
|
||||
see_if_rtc_works(bool * const rtc_works_p);
|
||||
|
||||
extern void
|
||||
get_epoch(unsigned long *epoch_p, char **reason_p);
|
||||
|
||||
extern void
|
||||
set_epoch(unsigned long epoch, const bool testing, int *retcode_p);
|
||||
|
||||
|
||||
/* kd.c */
|
||||
|
||||
extern void
|
||||
synchronize_to_clock_tick_KD(int *retcode_p);
|
||||
|
||||
extern void
|
||||
read_hardware_clock_kd(struct tm *tm);
|
||||
|
||||
extern void
|
||||
set_hardware_clock_kd(const struct tm new_broken_time,
|
||||
const bool testing);
|
||||
|
||||
extern void
|
||||
see_if_kdghwclk_works(bool * const kdghwclk_works_p);
|
||||
|
||||
extern const bool got_kdghwclk;
|
||||
|
||||
/* util.c */
|
||||
extern bool
|
||||
is_in_cpuinfo(const char * const fmt, const char * const str);
|
||||
|
||||
extern char *
|
||||
ctime2(const time_t time);
|
||||
|
||||
extern struct timeval
|
||||
t2tv(time_t argument);
|
||||
|
||||
extern struct timeval
|
||||
t2tv(time_t argument);
|
||||
|
||||
extern float
|
||||
time_diff(struct timeval subtrahend, struct timeval subtractor);
|
||||
|
||||
extern struct timeval
|
||||
time_inc(struct timeval addend, float increment);
|
||||
|
||||
|
||||
|
||||
|
||||
|
219
clockB/kd.c
219
clockB/kd.c
|
@ -1,219 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
This is a component of the hwclock program.
|
||||
|
||||
This file contains the code for accessing the hardware clock via
|
||||
the KDHWCLK facility of M68k machines.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "hwclock.h"
|
||||
|
||||
|
||||
|
||||
#if defined(KDGHWCLK)
|
||||
const bool got_kdghwclk = TRUE;
|
||||
static const int kdghwclk_ioctl = KDGHWCLK;
|
||||
static const int kdshwclk_ioctl = KDSHWCLK;
|
||||
#else
|
||||
const bool got_kdghwclk = FALSE;
|
||||
static const int kdghwclk_ioctl; /* Never used; just to make compile work */
|
||||
struct hwclk_time {int sec;};
|
||||
/* Never used; just to make compile work */
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
synchronize_to_clock_tick_KD(int *retcode_p) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Wait for the top of a clock tick by calling KDGHWCLK in a busy loop until
|
||||
we see it.
|
||||
-----------------------------------------------------------------------------*/
|
||||
int con_fd;
|
||||
|
||||
if (debug)
|
||||
printf("Waiting in loop for time from KDGHWCLK to change\n");
|
||||
|
||||
con_fd = open("/dev/tty1", O_RDONLY);
|
||||
if (con_fd < 0) {
|
||||
fprintf(stderr, "%s: open() failed to open /dev/tty1, errno = %s (%d).\n",
|
||||
MYNAME, strerror(errno), errno);
|
||||
*retcode_p = 1;
|
||||
} else {
|
||||
int rc; /* return code from ioctl() */
|
||||
int i; /* local loop index */
|
||||
/* The time when we were called (and started waiting) */
|
||||
struct hwclk_time start_time, nowtime;
|
||||
|
||||
rc = ioctl(con_fd, kdghwclk_ioctl, &start_time);
|
||||
if (rc == -1) {
|
||||
fprintf(stderr, "%s: KDGHWCLK to read time failed, "
|
||||
"errno = %s (%d).\n", MYNAME, strerror(errno), errno);
|
||||
*retcode_p = 3;
|
||||
}
|
||||
|
||||
for (i = 0;
|
||||
(rc = ioctl(con_fd, kdghwclk_ioctl, &nowtime)) != -1
|
||||
&& start_time.sec == nowtime.sec && i < 1000000;
|
||||
i++);
|
||||
if (i >= 1000000) {
|
||||
fprintf(stderr, "%s: Timed out waiting for time change.\n", MYNAME);
|
||||
*retcode_p = 2;
|
||||
} else if (rc == -1) {
|
||||
fprintf(stderr, "%s: KDGHWCLK to read time failed, "
|
||||
"errno = %s (%d).\n", MYNAME, strerror(errno), errno);
|
||||
*retcode_p = 3;
|
||||
} else *retcode_p = 0;
|
||||
close(con_fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
read_hardware_clock_kd(struct tm *tm) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Read the hardware clock and return the current time via <tm>
|
||||
argument. Use ioctls to /dev/tty1 on what we assume is an m68k
|
||||
machine.
|
||||
|
||||
Note that we don't use /dev/console here. That might be a serial
|
||||
console.
|
||||
-----------------------------------------------------------------------------*/
|
||||
#ifdef KDGHWCLK
|
||||
int con_fd;
|
||||
struct hwclk_time t;
|
||||
|
||||
con_fd = open("/dev/tty1", O_RDONLY);
|
||||
if (con_fd < 0) {
|
||||
fprintf(stderr, "%s: open() failed to open /dev/tty1, errno = %s (%d).\n",
|
||||
MYNAME, strerror(errno), errno);
|
||||
exit(5);
|
||||
} else {
|
||||
int rc; /* return code from ioctl() */
|
||||
|
||||
rc = ioctl(con_fd, kdghwclk_ioctl, &t);
|
||||
if (rc == -1) {
|
||||
fprintf(stderr, "%s: ioctl() failed to read time from /dev/tty1, "
|
||||
"errno = %s (%d).\n",
|
||||
MYNAME, strerror(errno), errno);
|
||||
exit(5);
|
||||
}
|
||||
close(con_fd);
|
||||
}
|
||||
|
||||
tm->tm_sec = t.sec;
|
||||
tm->tm_min = t.min;
|
||||
tm->tm_hour = t.hour;
|
||||
tm->tm_mday = t.day;
|
||||
tm->tm_mon = t.mon;
|
||||
tm->tm_year = t.year;
|
||||
tm->tm_wday = t.wday;
|
||||
tm->tm_isdst = -1; /* Don't know if it's Daylight Savings Time */
|
||||
#else
|
||||
/* This routine should never be invoked. It is here just to make the
|
||||
program compile.
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_hardware_clock_kd(const struct tm new_broken_time,
|
||||
const bool testing) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Set the Hardware Clock to the time <new_broken_time>. Use ioctls to
|
||||
/dev/tty1 on what we assume is an m68k machine.
|
||||
|
||||
Note that we don't use /dev/console here. That might be a serial console.
|
||||
----------------------------------------------------------------------------*/
|
||||
#ifdef KDGHWCLK
|
||||
int con_fd; /* File descriptor of /dev/tty1 */
|
||||
struct hwclk_time t;
|
||||
|
||||
con_fd = open("/dev/tty1", O_RDONLY);
|
||||
if (con_fd < 0) {
|
||||
fprintf(stderr, "%s: Error opening /dev/tty1. Errno: %s (%d)\n",
|
||||
MYNAME, strerror(errno), errno);
|
||||
exit(1);
|
||||
} else {
|
||||
int rc; /* locally used return code */
|
||||
|
||||
t.sec = new_broken_time.tm_sec;
|
||||
t.min = new_broken_time.tm_min;
|
||||
t.hour = new_broken_time.tm_hour;
|
||||
t.day = new_broken_time.tm_mday;
|
||||
t.mon = new_broken_time.tm_mon;
|
||||
t.year = new_broken_time.tm_year;
|
||||
t.wday = new_broken_time.tm_wday;
|
||||
|
||||
if (testing)
|
||||
printf("Not setting Hardware Clock because running in test mode.\n");
|
||||
else {
|
||||
rc = ioctl(con_fd, kdshwclk_ioctl, &t );
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "%s: ioctl() to open /dev/tty1 failed. "
|
||||
"Errno: %s (%d)\n",
|
||||
MYNAME, strerror(errno), errno);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
close(con_fd);
|
||||
}
|
||||
#else
|
||||
/* This function should never be invoked. It is here just to make the
|
||||
program compile.
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
see_if_kdghwclk_works(bool * const kdghwclk_works_p) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Find out if we are capable of accessing the Hardware Clock via the
|
||||
KDHWCLK facility (ioctl to /dev/tty1).
|
||||
-----------------------------------------------------------------------------*/
|
||||
if (got_kdghwclk) {
|
||||
int con_fd;
|
||||
struct hwclk_time t;
|
||||
|
||||
con_fd = open("/dev/tty1", O_RDONLY);
|
||||
if (con_fd >= 0) {
|
||||
if (ioctl( con_fd, kdghwclk_ioctl, &t ) >= 0)
|
||||
*kdghwclk_works_p = TRUE;
|
||||
else {
|
||||
if (errno == EINVAL) {
|
||||
/* KDGHWCLK not implemented in this kernel... */
|
||||
*kdghwclk_works_p = FALSE;
|
||||
if (debug)
|
||||
printf(MYNAME "was built with KDGHWCLK capability, but the "
|
||||
"ioctl does not exist in the kernel. The ioctl (to "
|
||||
"/dev/tty1) failed with errno EINVAL.\n");
|
||||
} else {
|
||||
*kdghwclk_works_p = FALSE;
|
||||
fprintf(stderr,
|
||||
"%s: KDGHWCLK ioctl failed, errno = %s (%d).\n",
|
||||
MYNAME, strerror(errno), errno);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
*kdghwclk_works_p = FALSE;
|
||||
fprintf(stderr,
|
||||
"%s: Can't open /dev/tty1. open() errno = %s (%d).\n",
|
||||
MYNAME, strerror(errno), errno);
|
||||
}
|
||||
close(con_fd);
|
||||
} else *kdghwclk_works_p = FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
425
clockB/rtc.c
425
clockB/rtc.c
|
@ -1,425 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
This is a component of the hwclock program.
|
||||
|
||||
This file contains the code for accessing the hardware clock via
|
||||
the rtc device driver (usually hooked up to the /dev/rtc device
|
||||
special file).
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "hwclock.h"
|
||||
|
||||
/*
|
||||
Get defines for rtc stuff.
|
||||
|
||||
Getting the rtc defines is nontrivial. The obvious way is by
|
||||
including <linux/mc146818rtc.h> but that again includes <asm/io.h>
|
||||
which again includes ... and on sparc and alpha this gives
|
||||
compilation errors for many kernel versions. So, we give the defines
|
||||
ourselves here. Moreover, some Sparc person decided to be
|
||||
incompatible, and used a struct rtc_time different from that used in
|
||||
mc146818rtc.h.
|
||||
*/
|
||||
|
||||
/* On Sparcs, there is a <asm/rtc.h> that defines different ioctls
|
||||
(that are required on my machine). However, this include file
|
||||
does not exist on other architectures. */
|
||||
/* One might do:
|
||||
#ifdef __sparc__
|
||||
#include <asm/rtc.h>
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* The following is roughly equivalent */
|
||||
struct sparc_rtc_time
|
||||
{
|
||||
int sec; /* Seconds (0-59) */
|
||||
int min; /* Minutes (0-59) */
|
||||
int hour; /* Hour (0-23) */
|
||||
int dow; /* Day of the week (1-7) */
|
||||
int dom; /* Day of the month (1-31) */
|
||||
int month; /* Month of year (1-12) */
|
||||
int year; /* Year (0-99) */
|
||||
};
|
||||
|
||||
|
||||
#define RTCGET _IOR('p', 20, struct sparc_rtc_time)
|
||||
#define RTCSET _IOW('p', 21, struct sparc_rtc_time)
|
||||
|
||||
|
||||
#include <linux/version.h>
|
||||
/* Check if the /dev/rtc interface is available in this version of
|
||||
the system headers. 131072 is linux 2.0.0. Might need to make
|
||||
it conditional on i386 or something too -janl */
|
||||
#if LINUX_VERSION_CODE >= 131072
|
||||
#include <linux/kd.h>
|
||||
static const bool got_rtc = TRUE;
|
||||
#else
|
||||
static const bool got_rtc = FALSE;
|
||||
#endif
|
||||
|
||||
/* struct linux_rtc_time is present since Linux 1.3.99 */
|
||||
/* Earlier (since 1.3.89), a struct tm was used. */
|
||||
struct linux_rtc_time {
|
||||
int tm_sec;
|
||||
int tm_min;
|
||||
int tm_hour;
|
||||
int tm_mday;
|
||||
int tm_mon;
|
||||
int tm_year;
|
||||
int tm_wday;
|
||||
int tm_yday;
|
||||
int tm_isdst;
|
||||
};
|
||||
|
||||
/* RTC_RD_TIME etc have this definition since Linux 1.99.9 (pre2.0-9) */
|
||||
#ifndef RTC_RD_TIME
|
||||
#define RTC_RD_TIME _IOR('p', 0x09, struct linux_rtc_time)
|
||||
#define RTC_SET_TIME _IOW('p', 0x0a, struct linux_rtc_time)
|
||||
#define RTC_UIE_ON _IO('p', 0x03) /* Update int. enable on */
|
||||
#define RTC_UIE_OFF _IO('p', 0x04) /* Update int. enable off */
|
||||
#endif
|
||||
/* RTC_EPOCH_READ and RTC_EPOCH_SET ioctls are in kernels since
|
||||
Linux 2.0.34 and 2.1.89
|
||||
*/
|
||||
#ifndef RTC_EPOCH_READ
|
||||
#define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long) /* Read epoch */
|
||||
#define RTC_EPOCH_SET _IOW('p', 0x0e, unsigned long) /* Set epoch */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static void
|
||||
do_rtc_read_ioctl(int rtc_fd, struct tm *tm, int *retcode_p) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Do the ioctl to read the time. This is, unfortunately, a slightly
|
||||
different function for Sparc than for everything else. But we
|
||||
return the standard 'tm' structure result in spite of the fact that
|
||||
the Sparc ioctl returns something else.
|
||||
|
||||
If the ioctl fails, issue message to stderr and return rc = 1;
|
||||
else, no message and rc = 0.
|
||||
-----------------------------------------------------------------------------*/
|
||||
int rc;
|
||||
|
||||
#ifdef __sparc__
|
||||
struct sparc_rtc_time stm;
|
||||
|
||||
rc = ioctl(rtc_fd, RTCGET, &stm);
|
||||
tm->tm_sec = stm.sec;
|
||||
tm->tm_min = stm.min;
|
||||
tm->tm_hour = stm.hour;
|
||||
tm->tm_mday = stm.dom;
|
||||
tm->tm_mon = stm.month - 1;
|
||||
tm->tm_year = stm.year - 1900;
|
||||
tm->tm_wday = stm.dow - 1;
|
||||
tm->tm_yday = -1; /* day in the year */
|
||||
#else
|
||||
rc = ioctl(rtc_fd, RTC_RD_TIME, tm);
|
||||
#endif
|
||||
if (rc == -1) {
|
||||
fprintf(stderr, "%s: ioctl() to /dev/rtc to read the time failed. "
|
||||
"errno = %s (%d)\n", MYNAME, strerror(errno), errno);
|
||||
*retcode_p = 1;
|
||||
} else *retcode_p = 0;
|
||||
tm->tm_isdst = -1; /* don't know whether it's daylight */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
get_epoch(unsigned long *epoch_p, char **reason_p){
|
||||
/*----------------------------------------------------------------------------
|
||||
Get the Hardware Clock epoch setting from the kernel.
|
||||
|
||||
If we succeed, return the setting (number of year A.D.) as
|
||||
*epoch_p and *reason_p == NULL.
|
||||
|
||||
If we fail, return and English description of what went wrong as a
|
||||
null-terminated string in newly malloc'ed storage and the pointer to
|
||||
it as *reason_p.
|
||||
----------------------------------------------------------------------------*/
|
||||
int rtc_fd;
|
||||
|
||||
rtc_fd = open("/dev/rtc", O_RDONLY);
|
||||
if (rtc_fd < 0) {
|
||||
if (errno == ENOENT)
|
||||
*reason_p =
|
||||
strdup("To manipulate the epoch value in the kernel, we must "
|
||||
"access the Linux 'rtc' device driver via the device special "
|
||||
"file /dev/rtc. This file does not exist on this system.\n");
|
||||
else {
|
||||
*reason_p = malloc(200);
|
||||
sprintf(*reason_p, "Unable to open /dev/rtc, open() errno = %s (%d)\n",
|
||||
strerror(errno), errno);
|
||||
}
|
||||
} else {
|
||||
int rc; /* return code from ioctl */
|
||||
rc = ioctl(rtc_fd, RTC_EPOCH_READ, epoch_p);
|
||||
if (rc == -1) {
|
||||
*reason_p = malloc(200);
|
||||
sprintf(*reason_p, "ioctl(RTC_EPOCH_READ) to /dev/rtc failed, "
|
||||
"errno = %s (%d).\n", strerror(errno), errno);
|
||||
} else {
|
||||
*reason_p = NULL;
|
||||
if (debug) printf("we have read epoch %ld from /dev/rtc "
|
||||
"with RTC_EPOCH_READ ioctl.\n", *epoch_p);
|
||||
}
|
||||
close(rtc_fd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
busywait_for_rtc_clock_tick(const int rtc_fd, int *retcode_p) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Wait for the top of a clock tick by reading /dev/rtc in a busy loop until
|
||||
we see it.
|
||||
-----------------------------------------------------------------------------*/
|
||||
struct tm start_time;
|
||||
/* The time when we were called (and started waiting) */
|
||||
int rc;
|
||||
|
||||
if (debug)
|
||||
printf("Waiting in loop for time from /dev/rtc to change\n");
|
||||
|
||||
do_rtc_read_ioctl(rtc_fd, &start_time, &rc);
|
||||
if (rc != 0) *retcode_p = 1;
|
||||
else {
|
||||
/* Wait for change. Should be within a second, but in case something
|
||||
weird happens, we have a limit on this loop to reduce the impact
|
||||
of this failure.
|
||||
*/
|
||||
struct tm nowtime;
|
||||
int iterations; /* how many time's we've spun through the loop */
|
||||
int rc; /* Return code from do_rtc_read_ioctl */
|
||||
|
||||
iterations = 0;
|
||||
do {
|
||||
do_rtc_read_ioctl(rtc_fd, &nowtime, &rc);
|
||||
} while (rc == 0 && start_time.tm_sec == nowtime.tm_sec
|
||||
&& iterations++ < 1000000);
|
||||
|
||||
if (iterations >= 1000000) {
|
||||
fprintf(stderr, "%s: Timed out waiting for time change.\n", MYNAME);
|
||||
*retcode_p = 2;
|
||||
} else if (rc != 0) *retcode_p = 3;
|
||||
else *retcode_p = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
synchronize_to_clock_tick_RTC(int *retcode_p) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Same as synchronize_to_clock_tick(), but just for /dev/rtc.
|
||||
-----------------------------------------------------------------------------*/
|
||||
int rtc_fd; /* File descriptor of /dev/rtc */
|
||||
|
||||
rtc_fd = open("/dev/rtc", O_RDONLY);
|
||||
|
||||
if (rtc_fd == -1) {
|
||||
fprintf(stderr, "%s: open() of /dev/rtc failed, errno = %s (%d).\n",
|
||||
MYNAME, strerror(errno), errno);
|
||||
*retcode_p = 1;
|
||||
} else {
|
||||
int rc; /* Return code from ioctl */
|
||||
/* Turn on update interrupts (one per second) */
|
||||
rc = ioctl(rtc_fd, RTC_UIE_ON, 0);
|
||||
if (rc == -1 && errno == EINVAL) {
|
||||
/* This rtc device doesn't have interrupt functions. This is typical
|
||||
on an Alpha, where the Hardware Clock interrupts are used by the
|
||||
kernel for the system clock, so aren't at the user's disposal.
|
||||
*/
|
||||
if (debug) printf("/dev/rtc does not have interrupt functions. \n");
|
||||
busywait_for_rtc_clock_tick(rtc_fd, retcode_p);
|
||||
} else if (rc != -1) {
|
||||
int rc; /* return code from ioctl */
|
||||
unsigned long dummy;
|
||||
|
||||
/* this blocks until the next update interrupt */
|
||||
rc = read(rtc_fd, &dummy, sizeof(dummy));
|
||||
if (rc == -1) {
|
||||
fprintf(stderr, "%s: read() to /dev/rtc to wait for clock tick "
|
||||
"failed, errno = %s (%d).\n", MYNAME, strerror(errno), errno);
|
||||
*retcode_p = 1;
|
||||
} else {
|
||||
*retcode_p = 0;
|
||||
}
|
||||
/* Turn off update interrupts */
|
||||
rc = ioctl(rtc_fd, RTC_UIE_OFF, 0);
|
||||
if (rc == -1) {
|
||||
fprintf(stderr,
|
||||
"%s: ioctl() to /dev/rtc to turn off update interrupts "
|
||||
"failed, errno = %s (%d).\n", MYNAME, strerror(errno), errno);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "%s: ioctl() to /dev/rtc to turn on update interrupts "
|
||||
"failed unexpectedly, errno = %s (%d).\n",
|
||||
MYNAME, strerror(errno), errno);
|
||||
*retcode_p = 1;
|
||||
}
|
||||
close(rtc_fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
read_hardware_clock_rtc_ioctl(struct tm *tm) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Read the hardware clock and return the current time via <tm>
|
||||
argument. Use ioctls to "rtc" device /dev/rtc.
|
||||
-----------------------------------------------------------------------------*/
|
||||
int rc; /* Local return code */
|
||||
int rtc_fd; /* File descriptor of /dev/rtc */
|
||||
|
||||
rtc_fd = open("/dev/rtc",O_RDONLY);
|
||||
if (rtc_fd == -1) {
|
||||
fprintf(stderr, "%s: open() of /dev/rtc failed, errno = %s (%d).\n",
|
||||
MYNAME, strerror(errno), errno);
|
||||
exit(5);
|
||||
} else {
|
||||
/* Read the RTC time/date */
|
||||
|
||||
rc = ioctl(rtc_fd, RTC_RD_TIME, tm);
|
||||
if (rc == -1) {
|
||||
fprintf(stderr, "%s: ioctl() to /dev/rtc to read the time failed, "
|
||||
"errno = %s (%d).\n", MYNAME, strerror(errno), errno);
|
||||
exit(5);
|
||||
}
|
||||
close(rtc_fd);
|
||||
}
|
||||
tm->tm_isdst = -1; /* don't know whether it's daylight */
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_hardware_clock_rtc_ioctl(const struct tm new_broken_time,
|
||||
const bool testing) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Set the Hardware Clock to the broken down time <new_broken_time>.
|
||||
Use ioctls to "rtc" device /dev/rtc.
|
||||
----------------------------------------------------------------------------*/
|
||||
int rc;
|
||||
int rtc_fd;
|
||||
|
||||
rtc_fd = open("/dev/rtc", O_RDONLY);
|
||||
if (rtc_fd < 0) {
|
||||
fprintf(stderr, "%s: Unable to open /dev/rtc, open() errno = %s (%d)\n",
|
||||
MYNAME, strerror(errno), errno);
|
||||
exit(5);
|
||||
} else {
|
||||
if (testing)
|
||||
printf("Not setting Hardware Clock because running in test mode.\n");
|
||||
else {
|
||||
rc = ioctl(rtc_fd, RTC_SET_TIME, &new_broken_time);
|
||||
if (rc == -1) {
|
||||
fprintf(stderr,
|
||||
"%s: ioctl() (RTC_SET_TIME) to /dev/rtc to set time failed, "
|
||||
"errno = %s (%d).\n", MYNAME, strerror(errno), errno);
|
||||
exit(5);
|
||||
} else {
|
||||
if (debug)
|
||||
printf("ioctl(RTC_SET_TIME) was successful.\n");
|
||||
}
|
||||
}
|
||||
close(rtc_fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
set_epoch(unsigned long epoch, const bool testing, int *retcode_p) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Set the Hardware Clock epoch in the kernel.
|
||||
----------------------------------------------------------------------------*/
|
||||
if (epoch < 1900)
|
||||
/* kernel would not accept this epoch value */
|
||||
fprintf(stderr, "%s: The epoch value may not be less than 1900. "
|
||||
"You requested %ld\n", MYNAME, epoch);
|
||||
else {
|
||||
int rtc_fd;
|
||||
|
||||
rtc_fd = open("/dev/rtc", O_RDONLY);
|
||||
if (rtc_fd < 0) {
|
||||
if (errno == ENOENT)
|
||||
fprintf(stderr,
|
||||
"%s: To manipulate the epoch value in the kernel, we must "
|
||||
"access the Linux 'rtc' device driver via the device special "
|
||||
"file /dev/rtc. This file does not exist on this system.\n",
|
||||
MYNAME);
|
||||
fprintf(stderr, "%s: Unable to open /dev/rtc, open() errno = %s (%d)\n",
|
||||
MYNAME, strerror(errno), errno);
|
||||
*retcode_p = 1;
|
||||
} else {
|
||||
if (debug) printf("setting epoch to %ld "
|
||||
"with RTC_EPOCH_SET ioctl to /dev/rtc.\n", epoch);
|
||||
if (testing) {
|
||||
printf("Not setting epoch because running in test mode.\n");
|
||||
*retcode_p = 0;
|
||||
} else {
|
||||
int rc; /* return code from ioctl */
|
||||
rc = ioctl(rtc_fd, RTC_EPOCH_SET, epoch);
|
||||
if (rc == -1) {
|
||||
if (errno == EINVAL)
|
||||
fprintf(stderr, "%s: The kernel (specifically, the device driver "
|
||||
"for /dev/rtc) does not have the RTC_EPOCH_SET ioctl. "
|
||||
"Get a newer driver.\n", MYNAME);
|
||||
else
|
||||
fprintf(stderr, "%s: ioctl(RTC_EPOCH_SET) to /dev/rtc failed, "
|
||||
"errno = %s (%d).\n", MYNAME, strerror(errno), errno);
|
||||
*retcode_p = 1;
|
||||
} else *retcode_p = 0;
|
||||
}
|
||||
close(rtc_fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
see_if_rtc_works(bool * const rtc_works_p) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Find out if we are capable of accessing the Hardware Clock via the rtc
|
||||
driver (via device file /dev/rtc).
|
||||
-----------------------------------------------------------------------------*/
|
||||
if (got_rtc) {
|
||||
int rtc_fd = open("/dev/rtc", O_RDONLY);
|
||||
if (rtc_fd > 0) {
|
||||
*rtc_works_p = TRUE;
|
||||
close(rtc_fd);
|
||||
} else {
|
||||
*rtc_works_p = FALSE;
|
||||
if (debug)
|
||||
printf("Open of /dev/rtc failed, errno = %s (%d). "
|
||||
"falling back to more primitive clock access method.\n",
|
||||
strerror(errno), errno);
|
||||
}
|
||||
} else {
|
||||
if (debug)
|
||||
printf("The Linux kernel for which this copy of hwclock() was built "
|
||||
"is too old to have /dev/rtc\n");
|
||||
*rtc_works_p = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
467
clockB/shhopt.c
467
clockB/shhopt.c
|
@ -1,467 +0,0 @@
|
|||
/* $Id: shhopt.c,v 2.2 1997/07/06 23:11:55 aebr Exp $ */
|
||||
/**************************************************************************
|
||||
*
|
||||
* FILE shhopt.c
|
||||
*
|
||||
* DESCRIPTION Functions for parsing command line arguments. Values
|
||||
* of miscellaneous types may be stored in variables,
|
||||
* or passed to functions as specified.
|
||||
*
|
||||
* REQUIREMENTS Some systems lack the ANSI C -function strtoul. If your
|
||||
* system is one of those, you'll ned to write one yourself,
|
||||
* or get the GNU liberty-library (from prep.ai.mit.edu).
|
||||
*
|
||||
* WRITTEN BY Sverre H. Huseby <sverrehu@ifi.uio.no>
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "shhopt.h"
|
||||
|
||||
/**************************************************************************
|
||||
* *
|
||||
* P R I V A T E D A T A *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
static void optFatalFunc(const char *, ...);
|
||||
static void (*optFatal)(const char *format, ...) = optFatalFunc;
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* *
|
||||
* P R I V A T E F U N C T I O N S *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* NAME optFatalFunc
|
||||
*
|
||||
* FUNCTION Show given message and abort the program.
|
||||
*
|
||||
* INPUT format, ...
|
||||
* Arguments used as with printf().
|
||||
*
|
||||
* RETURNS Never returns. The program is aborted.
|
||||
*
|
||||
*/
|
||||
void optFatalFunc(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
fflush(stdout);
|
||||
va_start(ap, format);
|
||||
vfprintf(stderr, format, ap);
|
||||
va_end(ap);
|
||||
exit(99);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* NAME optStructCount
|
||||
*
|
||||
* FUNCTION Get number of options in a optStruct.
|
||||
*
|
||||
* INPUT opt array of possible options.
|
||||
*
|
||||
* RETURNS Number of options in the given array.
|
||||
*
|
||||
* DESCRIPTION Count elements in an optStruct-array. The strcture must
|
||||
* be ended using an element of type OPT_END.
|
||||
*
|
||||
*/
|
||||
static int optStructCount(const optStruct opt[])
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
while (opt[ret].type != OPT_END)
|
||||
++ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* NAME optMatch
|
||||
*
|
||||
* FUNCTION Find a matching option.
|
||||
*
|
||||
* INPUT opt array of possible options.
|
||||
* s string to match, without `-' or `--'.
|
||||
* lng match long option, otherwise short.
|
||||
*
|
||||
* RETURNS Index to the option if found, -1 if not found.
|
||||
*
|
||||
* DESCRIPTION Short options are matched from the first character in
|
||||
* the given string.
|
||||
*
|
||||
*/
|
||||
static int optMatch(const optStruct opt[], const char *s, int lng)
|
||||
{
|
||||
int nopt, q, matchlen = 0;
|
||||
char *p;
|
||||
|
||||
nopt = optStructCount(opt);
|
||||
if (lng) {
|
||||
if ((p = strchr(s, '=')) != NULL)
|
||||
matchlen = p - s;
|
||||
else
|
||||
matchlen = strlen(s);
|
||||
}
|
||||
for (q = 0; q < nopt; q++) {
|
||||
if (lng) {
|
||||
if (!opt[q].longName)
|
||||
continue;
|
||||
if (strncmp(s, opt[q].longName, matchlen) == 0)
|
||||
return q;
|
||||
} else {
|
||||
if (!opt[q].shortName)
|
||||
continue;
|
||||
if (*s == opt[q].shortName)
|
||||
return q;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* NAME optString
|
||||
*
|
||||
* FUNCTION Return a (static) string with the option name.
|
||||
*
|
||||
* INPUT opt the option to stringify.
|
||||
* lng is it a long option?
|
||||
*
|
||||
* RETURNS Pointer to static string.
|
||||
*
|
||||
*/
|
||||
static char *optString(const optStruct *opt, int lng)
|
||||
{
|
||||
static char ret[31];
|
||||
|
||||
if (lng) {
|
||||
strcpy(ret, "--");
|
||||
strncpy(ret + 2, opt->longName, 28);
|
||||
} else {
|
||||
ret[0] = '-';
|
||||
ret[1] = opt->shortName;
|
||||
ret[2] = '\0';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* NAME optNeedsArgument
|
||||
*
|
||||
* FUNCTION Check if an option requires an argument.
|
||||
*
|
||||
* INPUT opt the option to check.
|
||||
*
|
||||
* RETURNS Boolean value.
|
||||
*
|
||||
*/
|
||||
static int optNeedsArgument(const optStruct *opt)
|
||||
{
|
||||
return opt->type == OPT_STRING
|
||||
|| opt->type == OPT_INT
|
||||
|| opt->type == OPT_UINT
|
||||
|| opt->type == OPT_LONG
|
||||
|| opt->type == OPT_ULONG;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* NAME argvRemove
|
||||
*
|
||||
* FUNCTION Remove an entry from an argv-array.
|
||||
*
|
||||
* INPUT argc pointer to number of options.
|
||||
* argv array of option-/argument-strings.
|
||||
* i index of option to remove.
|
||||
*
|
||||
* OUTPUT argc new argument count.
|
||||
* argv array with given argument removed.
|
||||
*
|
||||
*/
|
||||
static void argvRemove(int *argc, char *argv[], int i)
|
||||
{
|
||||
if (i >= *argc)
|
||||
return;
|
||||
while (i++ < *argc)
|
||||
argv[i - 1] = argv[i];
|
||||
--*argc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* NAME optExecute
|
||||
*
|
||||
* FUNCTION Perform the action of an option.
|
||||
*
|
||||
* INPUT opt array of possible options.
|
||||
* arg argument to option, if it applies.
|
||||
* lng was the option given as a long option?
|
||||
*
|
||||
* RETURNS Nothing. Aborts in case of error.
|
||||
*
|
||||
*/
|
||||
void optExecute(const optStruct *opt, char *arg, int lng)
|
||||
{
|
||||
switch (opt->type) {
|
||||
case OPT_FLAG:
|
||||
if (opt->flags & OPT_CALLFUNC)
|
||||
((void (*)(void)) opt->arg)();
|
||||
else
|
||||
*((int *) opt->arg) = 1;
|
||||
break;
|
||||
|
||||
case OPT_STRING:
|
||||
if (opt->flags & OPT_CALLFUNC)
|
||||
((void (*)(char *)) opt->arg)(arg);
|
||||
else
|
||||
*((char **) opt->arg) = arg;
|
||||
break;
|
||||
|
||||
case OPT_INT:
|
||||
case OPT_LONG: {
|
||||
long tmp;
|
||||
char *e;
|
||||
|
||||
tmp = strtol(arg, &e, 10);
|
||||
if (*e)
|
||||
optFatal("invalid number `%s'\n", arg);
|
||||
if (errno == ERANGE
|
||||
|| (opt->type == OPT_INT && (tmp > INT_MAX || tmp < INT_MIN)))
|
||||
optFatal("number `%s' to `%s' out of range\n",
|
||||
arg, optString(opt, lng));
|
||||
if (opt->type == OPT_INT) {
|
||||
if (opt->flags & OPT_CALLFUNC)
|
||||
((void (*)(int)) opt->arg)((int) tmp);
|
||||
else
|
||||
*((int *) opt->arg) = (int) tmp;
|
||||
} else /* OPT_LONG */ {
|
||||
if (opt->flags & OPT_CALLFUNC)
|
||||
((void (*)(long)) opt->arg)(tmp);
|
||||
else
|
||||
*((long *) opt->arg) = tmp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case OPT_UINT:
|
||||
case OPT_ULONG: {
|
||||
unsigned long tmp;
|
||||
char *e;
|
||||
|
||||
tmp = strtoul(arg, &e, 10);
|
||||
if (*e)
|
||||
optFatal("invalid number `%s'\n", arg);
|
||||
if (errno == ERANGE
|
||||
|| (opt->type == OPT_UINT && tmp > UINT_MAX))
|
||||
optFatal("number `%s' to `%s' out of range\n",
|
||||
arg, optString(opt, lng));
|
||||
if (opt->type == OPT_UINT) {
|
||||
if (opt->flags & OPT_CALLFUNC)
|
||||
((void (*)(unsigned)) opt->arg)((unsigned) tmp);
|
||||
else
|
||||
*((unsigned *) opt->arg) = (unsigned) tmp;
|
||||
} else /* OPT_ULONG */ {
|
||||
if (opt->flags & OPT_CALLFUNC)
|
||||
((void (*)(unsigned long)) opt->arg)(tmp);
|
||||
else
|
||||
*((unsigned long *) opt->arg) = tmp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**************************************************************************
|
||||
* *
|
||||
* P U B L I C F U N C T I O N S *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* NAME optSetFatalFunc
|
||||
*
|
||||
* FUNCTION Set function used to display error message and exit.
|
||||
*
|
||||
* SYNOPSIS #include "shhmsg.h"
|
||||
* void optSetFatalFunc(void (*f)(const char *, ...));
|
||||
*
|
||||
* INPUT f function accepting printf()'like parameters,
|
||||
* that _must_ abort the program.
|
||||
*
|
||||
*/
|
||||
void optSetFatalFunc(void (*f)(const char *, ...))
|
||||
{
|
||||
optFatal = f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* NAME optParseOptions
|
||||
*
|
||||
* FUNCTION Parse commandline options.
|
||||
*
|
||||
* SYNOPSIS #include "shhopt.h"
|
||||
* void optParseOptions(int *argc, char *argv[],
|
||||
* const optStruct opt[], int allowNegNum);
|
||||
*
|
||||
* INPUT argc Pointer to number of options.
|
||||
* argv Array of option-/argument-strings.
|
||||
* opt Array of possible options.
|
||||
* allowNegNum
|
||||
* a negative number is not to be taken as
|
||||
* an option.
|
||||
*
|
||||
* OUTPUT argc new argument count.
|
||||
* argv array with arguments removed.
|
||||
*
|
||||
* RETURNS Nothing. Aborts in case of error.
|
||||
*
|
||||
* DESCRIPTION This function checks each option in the argv-array
|
||||
* against strings in the opt-array, and `executes' any
|
||||
* matching action. Any arguments to the options are
|
||||
* extracted and stored in the variables or passed to
|
||||
* functions pointed to by entries in opt.
|
||||
*
|
||||
* Options and arguments used are removed from the argv-
|
||||
* array, and argc is decreased accordingly.
|
||||
*
|
||||
* Any error leads to program abortion.
|
||||
*
|
||||
*/
|
||||
void optParseOptions(int *argc, char *argv[],
|
||||
const optStruct opt[], int allowNegNum)
|
||||
{
|
||||
int ai, /* argv index. */
|
||||
optarg, /* argv index of option argument, or -1 if none. */
|
||||
mi, /* Match index in opt. */
|
||||
done;
|
||||
char *arg, /* Pointer to argument to an option. */
|
||||
*o, /* pointer to an option character */
|
||||
*p;
|
||||
|
||||
/*
|
||||
* Loop through all arguments.
|
||||
*/
|
||||
for (ai = 0; ai < *argc; ) {
|
||||
/*
|
||||
* "--" indicates that the rest of the argv-array does not
|
||||
* contain options.
|
||||
*/
|
||||
if (strcmp(argv[ai], "--") == 0) {
|
||||
argvRemove(argc, argv, ai);
|
||||
break;
|
||||
}
|
||||
|
||||
if (allowNegNum && argv[ai][0] == '-' && isdigit(argv[ai][1])) {
|
||||
++ai;
|
||||
continue;
|
||||
} else if (strncmp(argv[ai], "--", 2) == 0) {
|
||||
/* long option */
|
||||
/* find matching option */
|
||||
if ((mi = optMatch(opt, argv[ai] + 2, 1)) < 0)
|
||||
optFatal("unrecognized option `%s'\n", argv[ai]);
|
||||
|
||||
/* possibly locate the argument to this option. */
|
||||
arg = NULL;
|
||||
if ((p = strchr(argv[ai], '=')) != NULL)
|
||||
arg = p + 1;
|
||||
|
||||
/* does this option take an argument? */
|
||||
optarg = -1;
|
||||
if (optNeedsArgument(&opt[mi])) {
|
||||
/* option needs an argument. find it. */
|
||||
if (!arg) {
|
||||
if ((optarg = ai + 1) == *argc)
|
||||
optFatal("option `%s' requires an argument\n",
|
||||
optString(&opt[mi], 1));
|
||||
arg = argv[optarg];
|
||||
}
|
||||
} else {
|
||||
if (arg)
|
||||
optFatal("option `%s' doesn't allow an argument\n",
|
||||
optString(&opt[mi], 1));
|
||||
}
|
||||
/* perform the action of this option. */
|
||||
optExecute(&opt[mi], arg, 1);
|
||||
/* remove option and any argument from the argv-array. */
|
||||
if (optarg >= 0)
|
||||
argvRemove(argc, argv, ai);
|
||||
argvRemove(argc, argv, ai);
|
||||
} else if (*argv[ai] == '-') {
|
||||
/* A dash by itself is not considered an option. */
|
||||
if (argv[ai][1] == '\0') {
|
||||
++ai;
|
||||
continue;
|
||||
}
|
||||
/* Short option(s) following */
|
||||
o = argv[ai] + 1;
|
||||
done = 0;
|
||||
optarg = -1;
|
||||
while (*o && !done) {
|
||||
/* find matching option */
|
||||
if ((mi = optMatch(opt, o, 0)) < 0)
|
||||
optFatal("unrecognized option `-%c'\n", *o);
|
||||
|
||||
/* does this option take an argument? */
|
||||
optarg = -1;
|
||||
arg = NULL;
|
||||
if (optNeedsArgument(&opt[mi])) {
|
||||
/* option needs an argument. find it. */
|
||||
arg = o + 1;
|
||||
if (!*arg) {
|
||||
if ((optarg = ai + 1) == *argc)
|
||||
optFatal("option `%s' requires an argument\n",
|
||||
optString(&opt[mi], 0));
|
||||
arg = argv[optarg];
|
||||
}
|
||||
done = 1;
|
||||
}
|
||||
/* perform the action of this option. */
|
||||
optExecute(&opt[mi], arg, 0);
|
||||
++o;
|
||||
}
|
||||
/* remove option and any argument from the argv-array. */
|
||||
if (optarg >= 0)
|
||||
argvRemove(argc, argv, ai);
|
||||
argvRemove(argc, argv, ai);
|
||||
} else {
|
||||
/* a non-option argument */
|
||||
++ai;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/* $Id: shhopt.h,v 1.2 1996/06/06 00:06:35 sverrehu Exp $ */
|
||||
#ifndef SHHOPT_H
|
||||
#define SHHOPT_H
|
||||
|
||||
/* constants for recognized option types. */
|
||||
typedef enum {
|
||||
OPT_END, /* nothing. used as ending element. */
|
||||
OPT_FLAG, /* no argument following. sets variable to 1. */
|
||||
OPT_STRING, /* string argument. */
|
||||
OPT_INT, /* signed integer argument. */
|
||||
OPT_UINT, /* unsigned integer argument. */
|
||||
OPT_LONG, /* signed long integer argument. */
|
||||
OPT_ULONG, /* unsigned long integer argument. */
|
||||
} optArgType;
|
||||
|
||||
/* flags modifying the default way options are handeled. */
|
||||
#define OPT_CALLFUNC 1 /* pass argument to a function. */
|
||||
|
||||
typedef struct {
|
||||
char shortName; /* Short option name. */
|
||||
char *longName; /* Long option name, no including '--'. */
|
||||
optArgType type; /* Option type. */
|
||||
void *arg; /* Pointer to variable to fill with argument,
|
||||
* or pointer to function if Type == OPT_FUNC. */
|
||||
int flags; /* Modifier flags. */
|
||||
} optStruct;
|
||||
|
||||
|
||||
void optSetFatalFunc(void (*f)(const char *, ...));
|
||||
void optParseOptions(int *argc, char *argv[],
|
||||
const optStruct opt[], const int allowNegNum);
|
||||
|
||||
#endif
|
120
clockB/util.c
120
clockB/util.c
|
@ -1,120 +0,0 @@
|
|||
/**************************************************************************
|
||||
|
||||
This is a component of the hwclock program.
|
||||
|
||||
This file contains the code for various basic utility routines
|
||||
needed by the other modules.
|
||||
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hwclock.h"
|
||||
|
||||
bool
|
||||
is_in_cpuinfo(const char * const fmt, const char * const str) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Return true iff the /proc/cpuinfo file shows the value 'str' for the
|
||||
keyword 'fmt'. Both arguments are null-terminated strings.
|
||||
|
||||
If for any reason we can't read /proc/cpuinfo, return false.
|
||||
-----------------------------------------------------------------------------*/
|
||||
FILE *cpuinfo;
|
||||
char field[256];
|
||||
char format[256];
|
||||
bool found;
|
||||
|
||||
sprintf(format, "%s : %s", fmt, "%255s");
|
||||
|
||||
found = FALSE; /* initial value */
|
||||
if ((cpuinfo = fopen ("/proc/cpuinfo", "r")) != NULL) {
|
||||
while (!feof(cpuinfo)) {
|
||||
if (fscanf (cpuinfo, format, field) == 1) {
|
||||
if (strncmp(field, str, strlen(str)) == 0)
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
fgets (field, 256, cpuinfo);
|
||||
}
|
||||
fclose(cpuinfo);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *
|
||||
ctime2(const time_t time) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Same as ctime() from the standard C library, except it takes a time_t
|
||||
as an argument instead of a pointer to a time_t, so it is much more
|
||||
useful.
|
||||
|
||||
Also, don't include a newline at the end of the returned string. If
|
||||
the user wants a newline, he can provide it himself.
|
||||
|
||||
return value is in static storage within.
|
||||
-----------------------------------------------------------------------------*/
|
||||
static char retval[30];
|
||||
|
||||
strncpy(retval, ctime(&time), sizeof(retval));
|
||||
retval[sizeof(retval)-1] = '\0';
|
||||
|
||||
/* Now chop off the last character, which is the newline */
|
||||
if (strlen(retval) >= 1) /* for robustness */
|
||||
retval[strlen(retval)-1] = '\0';
|
||||
return(retval);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct timeval
|
||||
t2tv(time_t argument) {
|
||||
/*----------------------------------------------------------------------------
|
||||
Convert from "time_t" format to "timeval" format.
|
||||
-----------------------------------------------------------------------------*/
|
||||
struct timeval retval;
|
||||
|
||||
retval.tv_sec = argument;
|
||||
retval.tv_usec = 0;
|
||||
return(retval);
|
||||
}
|
||||
|
||||
|
||||
|
||||
float
|
||||
time_diff(struct timeval subtrahend, struct timeval subtractor) {
|
||||
/*---------------------------------------------------------------------------
|
||||
The difference in seconds between two times in "timeval" format.
|
||||
----------------------------------------------------------------------------*/
|
||||
return( (subtrahend.tv_sec - subtractor.tv_sec)
|
||||
+ (subtrahend.tv_usec - subtractor.tv_usec) / 1E6 );
|
||||
}
|
||||
|
||||
|
||||
struct timeval
|
||||
time_inc(struct timeval addend, float increment) {
|
||||
/*----------------------------------------------------------------------------
|
||||
The time, in "timeval" format, which is <increment> seconds after
|
||||
the time <addend>. Of course, <increment> may be negative.
|
||||
-----------------------------------------------------------------------------*/
|
||||
struct timeval newtime;
|
||||
|
||||
newtime.tv_sec = addend.tv_sec + (int) increment;
|
||||
newtime.tv_usec = addend.tv_usec + (increment - (int) increment) * 1E6;
|
||||
|
||||
/* Now adjust it so that the microsecond value is between 0 and 1 million */
|
||||
if (newtime.tv_usec < 0) {
|
||||
newtime.tv_usec += 1E6;
|
||||
newtime.tv_sec -= 1;
|
||||
} else if (newtime.tv_usec >= 1E6) {
|
||||
newtime.tv_usec -= 1E6;
|
||||
newtime.tv_sec += 1;
|
||||
}
|
||||
return(newtime);
|
||||
}
|
||||
|
||||
|
||||
|
149
configure
vendored
149
configure
vendored
|
@ -6,7 +6,6 @@
|
|||
# 1. For mount/nfsmount.c: is inet_aton() available?
|
||||
# 2. For fdisk/fdisksunlabel.c: is there a <scsi/scsi.h>?
|
||||
# For fdisk/fdisk.c: is there a <linux/blkpg.h>?
|
||||
# 3. For sys-utils/ipcs.c: do we need __KERNEL__ and <linux/linkage.h>?
|
||||
# 4. For sys-utils/cytune.c: do we need <linux/tqueue.h>?
|
||||
# 5. For sys-utils/kbd_rate.c: does <linux/kd.h> exist?
|
||||
# 6. For cfdisk, setterm, more, ul: do we have ncurses? How installed?
|
||||
|
@ -19,7 +18,22 @@
|
|||
# 12. For cal.c: do we have <langinfo.h>?
|
||||
# 13. For err.c: do we have __progname?
|
||||
# 14. For script.c: do we have <pty.h> and openpty()?
|
||||
# 15. For lib/widechar.h: do we have wide character support?
|
||||
# 16. For clock/kd.c: do we have nanosleep()?
|
||||
|
||||
rm -f make_include defines.h
|
||||
|
||||
VERSION=`cat VERSION`
|
||||
echo
|
||||
echo configuring util-linux-$VERSION
|
||||
echo
|
||||
echo "VERSION=$VERSION" > make_include
|
||||
echo '#define UTIL_LINUX_VERSION "'$VERSION'"' > defines.h
|
||||
echo '#define util_linux_version "util-linux-'$VERSION'"' >> defines.h
|
||||
echo >> defines.h
|
||||
|
||||
if test -z "$CC"
|
||||
then
|
||||
if test "$RANDOM" = "$RANDOM"; then
|
||||
# Plain old Bourne shell.
|
||||
echo checking for gcc
|
||||
|
@ -29,6 +43,10 @@ else
|
|||
echo checking for gcc
|
||||
test -z "$CC" && type gcc && CC="gcc -O"
|
||||
fi
|
||||
else
|
||||
echo "Using CC=\"$CC\""
|
||||
echo
|
||||
fi
|
||||
|
||||
CC=${CC-cc}
|
||||
CFLAGS=${CFLAGS-"-O"}
|
||||
|
@ -36,8 +54,10 @@ DEFS=
|
|||
LIBS=
|
||||
compile='$CC $CFLAGS $DEFS conftest.c -o conftest $LIBS >/dev/null 2>&1'
|
||||
static_compile='$CC -static $DEFS conftest.c -o conftest $LIBS >/dev/null 2>&1'
|
||||
eval COMPILE='"'$compile'"'
|
||||
export COMPILE
|
||||
|
||||
rm -f make_include defines.h conftest.c conftest
|
||||
rm -f conftest.c conftest
|
||||
|
||||
#
|
||||
# 1. For mount/nfsmount.c: is inet_aton() available?
|
||||
|
@ -84,35 +104,9 @@ rm -f conftest conftest.c
|
|||
#
|
||||
# 2A. For fdisk/fdisk.c: is <linux/blkpg.h> available?
|
||||
#
|
||||
echo "
|
||||
#include <linux/blkpg.h>
|
||||
main(){ exit(0); }
|
||||
" > conftest.c
|
||||
eval $compile
|
||||
if test -s conftest && ./conftest 2>/dev/null; then
|
||||
if ./testincl "linux/blkpg.h"; then
|
||||
echo "#define HAVE_blkpg_h" >> defines.h
|
||||
echo "You have <linux/blkpg.h>"
|
||||
else
|
||||
echo "You don't have <linux/blkpg.h>"
|
||||
fi
|
||||
rm -f conftest conftest.c
|
||||
|
||||
#
|
||||
# 3. ipcs.c includes <sys/shm.h> and family
|
||||
# Do we need __KERNEL__ and asmlinkage for SHM_DEST?
|
||||
#
|
||||
echo "
|
||||
#include <sys/shm.h>
|
||||
main(){ int i=SHM_DEST; exit(0); }
|
||||
" > conftest.c
|
||||
eval $compile
|
||||
if test -s conftest && ./conftest 2>/dev/null; then
|
||||
echo "You don't need <linux/linkage.h>"
|
||||
else
|
||||
echo "#define NEED_linkage_h" >> defines.h
|
||||
echo "You need <linux/linkage.h>"
|
||||
fi
|
||||
rm -f conftest conftest.c
|
||||
|
||||
#
|
||||
# 4. cytune.c may need struct tq_struct
|
||||
|
@ -134,29 +128,22 @@ rm -f conftest conftest.c
|
|||
#
|
||||
# 5. Does <linux/kd.h> exist?
|
||||
#
|
||||
echo "
|
||||
#include <linux/kd.h>
|
||||
main(){ exit(0); }
|
||||
" > conftest.c
|
||||
eval $compile
|
||||
if test -s conftest && ./conftest 2>/dev/null; then
|
||||
if ./testincl "linux/kd.h"; then
|
||||
echo "#define HAVE_kd_h" >> defines.h
|
||||
echo "You have <linux/kd.h>"
|
||||
else
|
||||
echo "You don't have <linux/kd.h>"
|
||||
fi
|
||||
rm -f conftest conftest.c
|
||||
|
||||
#
|
||||
# 6. How is [n]curses installed?
|
||||
#
|
||||
test_curses_h=0
|
||||
have_ncurses=1
|
||||
if [ -f /usr/include/ncurses/curses.h ]; then
|
||||
if ! ./testincl "term.h"; then
|
||||
have_ncurses=0
|
||||
elif ./testincl -q "ncurses/curses.h"; then
|
||||
echo "HAVE_NCURSES=yes" >> make_include
|
||||
echo "CURSESFLAGS=-I/usr/include/ncurses -DNCH=0" >> make_include
|
||||
echo "You have ncurses. Using <ncurses/curses.h>."
|
||||
elif [ -f /usr/include/ncurses.h ]; then
|
||||
elif ./testincl -q "ncurses.h"; then
|
||||
echo "HAVE_NCURSES=yes" >> make_include
|
||||
echo "CURSESFLAGS=-DNCH=1" >> make_include
|
||||
echo "You have ncurses. Using <ncurses.h>."
|
||||
|
@ -164,7 +151,7 @@ elif [ -f /usr/local/include/ncurses.h ]; then
|
|||
echo "HAVE_NCURSES=yes" >> make_include
|
||||
echo "CURSESFLAGS=-I/usr/local/include -DNCH=1" >> make_include
|
||||
echo "You have ncurses. Using /usr/local/include/ncurses.h."
|
||||
elif [ -f /usr/include/curses.h ]; then
|
||||
elif ./testincl -q "curses.h"; then
|
||||
test_curses_h=1
|
||||
else
|
||||
have_ncurses=0
|
||||
|
@ -214,8 +201,12 @@ if test -s conftest && ./conftest 2>/dev/null; then
|
|||
echo "You have termcap"
|
||||
else
|
||||
echo "HAVE_TERMCAP=no" >> make_include
|
||||
if [ $have_ncurses = 0 ]; then
|
||||
echo "You don't have termcap - I will not make more."
|
||||
else
|
||||
echo "You don't have termcap"
|
||||
fi
|
||||
fi
|
||||
rm -f conftest conftest.c
|
||||
|
||||
#
|
||||
|
@ -253,18 +244,9 @@ fi
|
|||
#
|
||||
# 9. For lib/nls.h: do we have <locale.h>?
|
||||
#
|
||||
echo "
|
||||
#include <locale.h>
|
||||
main(){ exit(0); }
|
||||
" > conftest.c
|
||||
eval $compile
|
||||
if test -s conftest && ./conftest 2>/dev/null; then
|
||||
if ./testincl "locale.h"; then
|
||||
echo "#define HAVE_locale_h" >> defines.h
|
||||
echo "You have <locale.h>"
|
||||
else
|
||||
echo "You don't have <locale.h>"
|
||||
fi
|
||||
rm -f conftest conftest.c
|
||||
|
||||
|
||||
#
|
||||
|
@ -284,7 +266,7 @@ if test -s conftest && ./conftest 2>/dev/null; then
|
|||
echo "You have <libintl.h> and gettext()"
|
||||
echo '#define ENABLE_NLS' >> defines.h
|
||||
echo "Assuming that you want to enable NLS support."
|
||||
echo "(Otherwise, edit defines.h)"
|
||||
echo "(Otherwise, edit defines.h and remove the line with ENABLE_NLS)"
|
||||
ENABLE_NLS=yes
|
||||
else
|
||||
echo "You don't have <libintl.h>"
|
||||
|
@ -311,18 +293,9 @@ fi
|
|||
#
|
||||
# 12. For cal.c: do we have <langinfo.h>?
|
||||
#
|
||||
echo "
|
||||
#include <langinfo.h>
|
||||
main(){ exit(0); }
|
||||
" > conftest.c
|
||||
eval $compile
|
||||
if test -s conftest && ./conftest 2>/dev/null; then
|
||||
if ./testincl "langinfo.h"; then
|
||||
echo "#define HAVE_langinfo_h" >> defines.h
|
||||
echo "You have <langinfo.h>"
|
||||
else
|
||||
echo "You don't have <langinfo.h>"
|
||||
fi
|
||||
rm -f conftest conftest.c
|
||||
|
||||
|
||||
#
|
||||
|
@ -343,7 +316,6 @@ else
|
|||
fi
|
||||
rm -f conftest conftest.c
|
||||
|
||||
|
||||
#
|
||||
# 14. For script.c: do we have <pty.h> and openpty()?
|
||||
#
|
||||
|
@ -360,3 +332,52 @@ else
|
|||
echo "You don't have <pty.h> and openpty()"
|
||||
fi
|
||||
rm -f conftest conftest.c
|
||||
|
||||
#
|
||||
# 15. For lib/widechar.h: do we have wide character support?
|
||||
# [Do we have the headers <wchar.h>, <wctype.h>, the types wchar_t, wint_t
|
||||
# and the fgetwc, fputwc, WEOF functions/macros?]
|
||||
#
|
||||
echo "
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
#include <stdio.h>
|
||||
int main () {
|
||||
wchar_t wc;
|
||||
wint_t w;
|
||||
w = fgetwc(stdin);
|
||||
if (w == WEOF) exit(1);
|
||||
wc = w;
|
||||
fputwc(wc,stdout);
|
||||
exit(0);
|
||||
}
|
||||
" > conftest.c
|
||||
eval $compile
|
||||
if test -s conftest && ./conftest < conftest.c > /dev/null 2>/dev/null; then
|
||||
echo "#define ENABLE_WIDECHAR" >> defines.h
|
||||
echo "You have wide character support"
|
||||
else
|
||||
echo "You don't have wide character support"
|
||||
fi
|
||||
rm -f conftest conftest.c
|
||||
|
||||
#
|
||||
# 16. For clock/kd.c: do we have nanosleep?
|
||||
#
|
||||
echo "
|
||||
#include <time.h>
|
||||
int main () {
|
||||
struct timespec sleep = { 0, 1 };
|
||||
nanosleep( &sleep, NULL );
|
||||
exit(0);
|
||||
}
|
||||
" > conftest.c
|
||||
eval $compile
|
||||
if test -s conftest && ./conftest 2>/dev/null; then
|
||||
echo "#define HAVE_nanosleep" >> defines.h
|
||||
echo "You have nanosleep()"
|
||||
else
|
||||
echo "You don't have nanosleep()"
|
||||
fi
|
||||
rm -f conftest conftest.c
|
||||
|
||||
|
|
|
@ -1,49 +1,53 @@
|
|||
# Makefile -- Makefile for util-linux Linux utilities
|
||||
# Created: Sat Dec 26 20:09:40 1992
|
||||
# Revised: Fri Oct 6 21:02:21 1995 by r.faith@ieee.org
|
||||
# Copyright 1992, 1993, 1994, 1995 Rickard E. Faith (faith@cs.unc.edu)
|
||||
#
|
||||
|
||||
|
||||
include ../make_include
|
||||
include ../MCONFIG
|
||||
|
||||
# Where to put man pages?
|
||||
|
||||
MAN8= fdformat.8 mkswap.8 setfdprm.8
|
||||
MAN8= fdformat.8 mkfs.8 mkswap.8
|
||||
|
||||
# Where to put binaries?
|
||||
# See the "install" rule for the links. . .
|
||||
|
||||
SBIN= mkfs mkswap
|
||||
SBIN= mkfs mkswap blockdev
|
||||
|
||||
USRBIN= fdformat setfdprm
|
||||
USRBIN= fdformat
|
||||
|
||||
ETC= fdprm
|
||||
|
||||
ifneq "$(CPU)" "sparc"
|
||||
# fsck and mkfs will compile, but there is no kernel support on sparc
|
||||
MAN8:=$(MAN8) fsck.minix.8 mkfs.8 mkfs.minix.8
|
||||
SBIN:=$(SBIN) fsck.minix mkfs.minix
|
||||
MAN8:=$(MAN8) fsck.minix.8 mkfs.minix.8 mkfs.bfs.8
|
||||
SBIN:=$(SBIN) fsck.minix mkfs.minix mkfs.bfs
|
||||
endif
|
||||
|
||||
# Where to put datebase files?
|
||||
ifneq "$(HAVE_FDUTILS)" "yes"
|
||||
USRBIN:=$(USRBIN) setfdprm
|
||||
MAN8:=$(MAN8) setfdprm.8
|
||||
endif
|
||||
|
||||
# raw.c does not compile on 2.2.*.
|
||||
# find out later where it does and add tests to config
|
||||
ifeq "$(ADD_RAW)" "yes"
|
||||
USRBIN:=$(USRBIN) raw
|
||||
MAN8:=$(MAN8) raw.8
|
||||
endif
|
||||
|
||||
all: $(SBIN) $(USRBIN)
|
||||
|
||||
fdformat: fdformat.o
|
||||
fsck.minix: fsck.minix.o
|
||||
fsck.minix.o: fsck.minix.c bitops.h
|
||||
mkfs: mkfs.o
|
||||
mkfs.minix: mkfs.minix.o
|
||||
mkfs.minix.o: mkfs.minix.c bitops.h
|
||||
mkswap: mkswap.o
|
||||
setfdprm: setfdprm.o
|
||||
fsck.minix.o mkfs.minix.o: bitops.h
|
||||
|
||||
install: all
|
||||
$(INSTALLDIR) $(SBINDIR) $(USRBINDIR) $(ETCDIR)
|
||||
$(INSTALLBIN) $(SBIN) $(SBINDIR)
|
||||
$(INSTALLBIN) $(USRBIN) $(USRBINDIR)
|
||||
ifneq "$(HAVE_FDUTILS)" "yes"
|
||||
$(INSTALLDAT) $(ETC) $(ETCDIR)
|
||||
endif
|
||||
$(INSTALLDIR) $(MAN8DIR)
|
||||
$(INSTALLMAN) $(MAN8) $(MAN8DIR)
|
||||
|
||||
|
|
220
disk-utils/blockdev.c
Normal file
220
disk-utils/blockdev.c
Normal file
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* blockdev.c --- Do various simple block device ioctls from the command line
|
||||
* aeb, 991028
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include "nls.h"
|
||||
|
||||
const char *progname;
|
||||
|
||||
struct bdc {
|
||||
char *name;
|
||||
char *iocname;
|
||||
long ioc;
|
||||
int argtype;
|
||||
#define ARGNONE 0
|
||||
#define ARGINTA 1
|
||||
#define ARGINTP 2
|
||||
#define ARGINTG 3
|
||||
#define ARGLINTG 4
|
||||
long argval;
|
||||
char *argname;
|
||||
char *help;
|
||||
} bdcms[] = {
|
||||
#ifdef BLKROSET
|
||||
{ "--setro", "BLKROSET", BLKROSET, ARGINTP, 1, NULL, N_("set read-only") },
|
||||
{ "--setrw", "BLKROSET", BLKROSET, ARGINTP, 0, NULL, N_("set read-write") },
|
||||
#endif
|
||||
#ifdef BLKROGET
|
||||
{ "--getro", "BLKROGET", BLKROGET, ARGINTG, -1, NULL, N_("get read-only") },
|
||||
#endif
|
||||
#ifdef BLKSSZGET
|
||||
{ "--getss", "BLKSSZGET", BLKSSZGET, ARGINTG, -1, NULL, N_("get sectorsize") },
|
||||
#endif
|
||||
#ifdef BLKGETSIZE
|
||||
{ "--getsize", "BLKGETSIZE", BLKGETSIZE, ARGLINTG, -1, NULL, N_("get size") },
|
||||
#endif
|
||||
#ifdef BLKRASET
|
||||
{ "--setra", "BLKRASET", BLKRASET, ARGINTA, 0, "READAHEAD", N_("set readahead") },
|
||||
#endif
|
||||
#ifdef BLKRAGET
|
||||
{ "--getra", "BLKRAGET", BLKRAGET, ARGLINTG, -1, NULL, N_("get readahead") },
|
||||
#endif
|
||||
#ifdef BLKFLSBUF
|
||||
{ "--flushbufs", "BLKFLSBUF", BLKFLSBUF, ARGNONE, 0, NULL, N_("flush buffers") },
|
||||
#endif
|
||||
#ifdef BLKRRPART
|
||||
{ "--rereadpt", "BLKRRPART", BLKRRPART, ARGNONE, 0, NULL,
|
||||
N_("reread partition table") },
|
||||
#endif
|
||||
};
|
||||
|
||||
#define SIZE(a) (sizeof(a)/sizeof((a)[0]))
|
||||
|
||||
static void
|
||||
usage(void) {
|
||||
int i;
|
||||
fprintf(stderr, _("Usage: %s [-V] [-v|-q] commands devices\n"), progname);
|
||||
fprintf(stderr, _("Available commands:\n"));
|
||||
for (i = 0; i < SIZE(bdcms); i++) {
|
||||
fprintf(stderr, "\t%s", bdcms[i].name);
|
||||
if (bdcms[i].argname)
|
||||
fprintf(stderr, " %s", bdcms[i].argname);
|
||||
if (bdcms[i].help)
|
||||
fprintf(stderr, "\t(%s)", _(bdcms[i].help));
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
find_cmd(char *s) {
|
||||
int j;
|
||||
|
||||
for (j = 0; j < SIZE(bdcms); j++)
|
||||
if (!strcmp(s, bdcms[j].name))
|
||||
return j;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void do_commands(int fd, char **argv, int d);
|
||||
|
||||
int
|
||||
main(int argc, char **argv) {
|
||||
int fd, d, j, k;
|
||||
char *p;
|
||||
|
||||
/* egcs-2.91.66 is buggy and says:
|
||||
blockdev.c:93: warning: `d' might be used uninitialized */
|
||||
d = 0;
|
||||
|
||||
progname = argv[0];
|
||||
if ((p = strrchr(progname, '/')) != NULL)
|
||||
progname = p+1;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
||||
/* -V not together with commands */
|
||||
if (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")) {
|
||||
printf("%s from %s\n", progname, util_linux_version);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* do each of the commands on each of the devices */
|
||||
/* devices start after last command */
|
||||
for (d = 1; d < argc; d++) {
|
||||
j = find_cmd(argv[d]);
|
||||
if (j >= 0) {
|
||||
if (bdcms[j].argtype == ARGINTA)
|
||||
d++;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[d], "--")) {
|
||||
d++;
|
||||
break;
|
||||
}
|
||||
if (argv[d][0] != '-')
|
||||
break;
|
||||
}
|
||||
|
||||
if (d >= argc)
|
||||
usage();
|
||||
|
||||
for (k = d; k < argc; k++) {
|
||||
fd = open(argv[k], O_RDONLY, 0);
|
||||
if (fd < 0) {
|
||||
perror(argv[k]);
|
||||
exit(1);
|
||||
}
|
||||
do_commands(fd, argv, d);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
do_commands(int fd, char **argv, int d) {
|
||||
int res, i, j;
|
||||
int iarg;
|
||||
long larg;
|
||||
int verbose = 0;
|
||||
|
||||
for (i = 1; i < d; i++) {
|
||||
if (!strcmp(argv[i], "-v")) {
|
||||
verbose = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-q")) {
|
||||
verbose = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
j = find_cmd(argv[i]);
|
||||
if (j == -1) {
|
||||
fprintf(stderr, _("%s: Unknown command: %s\n"), progname, argv[i]);
|
||||
usage();
|
||||
}
|
||||
|
||||
switch(bdcms[j].argtype) {
|
||||
default:
|
||||
case ARGNONE:
|
||||
res = ioctl(fd, bdcms[j].ioc, 0);
|
||||
break;
|
||||
case ARGINTA:
|
||||
if (i == d-1) {
|
||||
fprintf(stderr, _("%s requires an argument\n"),
|
||||
bdcms[j].name);
|
||||
usage();
|
||||
}
|
||||
iarg = atoi(argv[++i]);
|
||||
res = ioctl(fd, bdcms[j].ioc, iarg);
|
||||
break;
|
||||
case ARGINTP:
|
||||
case ARGINTG:
|
||||
iarg = bdcms[j].argval;
|
||||
res = ioctl(fd, bdcms[j].ioc, &iarg);
|
||||
break;
|
||||
case ARGLINTG:
|
||||
larg = bdcms[j].argval;
|
||||
res = ioctl(fd, bdcms[j].ioc, &larg);
|
||||
break;
|
||||
}
|
||||
if (res == -1) {
|
||||
perror(bdcms[j].iocname);
|
||||
if (verbose)
|
||||
printf("%s failed.\n", _(bdcms[j].help));
|
||||
exit(1);
|
||||
}
|
||||
switch(bdcms[j].argtype) {
|
||||
case ARGINTG:
|
||||
if (verbose)
|
||||
printf("%s: %d\n", _(bdcms[j].help), iarg);
|
||||
else
|
||||
printf("%d\n", iarg);
|
||||
break;
|
||||
case ARGLINTG:
|
||||
if (verbose)
|
||||
printf("%s: %ld\n", _(bdcms[j].help), larg);
|
||||
else
|
||||
printf("%ld\n", larg);
|
||||
break;
|
||||
default:
|
||||
if (verbose)
|
||||
printf("%s succeeded.\n", _(bdcms[j].help));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -101,22 +101,31 @@ static void usage(char *name)
|
|||
int main(int argc,char **argv)
|
||||
{
|
||||
int verify;
|
||||
char *name;
|
||||
struct stat st;
|
||||
char *progname, *p;
|
||||
|
||||
progname = argv[0];
|
||||
if ((p = strrchr(progname, '/')) != NULL)
|
||||
progname = p+1;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
name = argv[0];
|
||||
if (argc == 2 &&
|
||||
(!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
|
||||
printf(_("%s from %s\n"), progname, util_linux_version);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
verify = 1;
|
||||
if (argc > 1 && argv[1][0] == '-') {
|
||||
if (argv[1][1] != 'n') usage(name);
|
||||
if (argv[1][1] != 'n') usage(progname);
|
||||
verify = 0;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
if (argc != 2) usage(name);
|
||||
if (argc != 2) usage(progname);
|
||||
if (stat(argv[1],&st) < 0) PERROR(argv[1]);
|
||||
if (!S_ISBLK(st.st_mode) || MAJOR(st.st_rdev) != FLOPPY_MAJOR) {
|
||||
fprintf(stderr,_("%s: not a floppy device\n"),argv[1]);
|
||||
|
@ -127,7 +136,8 @@ int main(int argc,char **argv)
|
|||
if (ioctl(ctrl,FDGETPRM,(long) ¶m) < 0)
|
||||
PERROR(_("Could not determine current format type"));
|
||||
printf(_("%s-sided, %d tracks, %d sec/track. Total capacity %d kB.\n"),
|
||||
param.head ? _("Double") : _("Single"),param.track,param.sect,param.size >> 1);
|
||||
param.head ? _("Double") : _("Single"),
|
||||
param.track, param.sect,param.size >> 1);
|
||||
format_disk(argv[1]);
|
||||
if (verify) verify_disk(argv[1]);
|
||||
return 0;
|
||||
|
|
|
@ -98,7 +98,6 @@
|
|||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/minix_fs.h>
|
||||
#include "../version.h"
|
||||
#include "nls.h"
|
||||
|
||||
#ifdef MINIX2_SUPER_MAGIC2
|
||||
|
@ -125,7 +124,6 @@
|
|||
#define BITS_PER_BLOCK (BLOCK_SIZE<<3)
|
||||
|
||||
static char * program_name = "fsck.minix";
|
||||
static char * program_version = "1.2 - 11/11/96";
|
||||
static char * device_name = NULL;
|
||||
static int IN;
|
||||
static int repair=0, automatic=0, verbose=0, list=0, show=0, warn_mode=0,
|
||||
|
@ -185,17 +183,25 @@ void recursive_check2(unsigned int ino);
|
|||
#define mark_zone(x) (setbit(zone_map,(x)-FIRSTZONE+1),changed=1)
|
||||
#define unmark_zone(x) (clrbit(zone_map,(x)-FIRSTZONE+1),changed=1)
|
||||
|
||||
void fatal_error(const char *, int) __attribute__ ((noreturn));
|
||||
void fatal_error(const char * fmt_string, int status)
|
||||
void leave(int) __attribute__ ((noreturn));
|
||||
void leave(int status)
|
||||
{
|
||||
fprintf(stderr,fmt_string,program_name,device_name);
|
||||
if (termios_set)
|
||||
tcsetattr(0, TCSANOW, &termios);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
#define usage() fatal_error(_("Usage: %s [-larvsmf] /dev/name\n"),16)
|
||||
#define die(str) fatal_error(_("%s: " str "\n"),8)
|
||||
void usage(void) {
|
||||
fprintf(stderr,
|
||||
_("Usage: %s [-larvsmf] /dev/name\n"),
|
||||
program_name);
|
||||
leave(16);
|
||||
}
|
||||
|
||||
void die(const char *str) {
|
||||
fprintf(stderr, "%s: %s\n", program_name, str);
|
||||
leave(8);
|
||||
}
|
||||
|
||||
/*
|
||||
* This simply goes through the file-name data and prints out the
|
||||
|
@ -381,7 +387,7 @@ void write_block(unsigned int nr, char * addr)
|
|||
return;
|
||||
}
|
||||
if (BLOCK_SIZE*nr != lseek(IN, BLOCK_SIZE*nr, SEEK_SET))
|
||||
die("seek failed in write_block");
|
||||
die(_("seek failed in write_block"));
|
||||
if (BLOCK_SIZE != write(IN, addr, BLOCK_SIZE)) {
|
||||
printf(_("Write error: bad block in file '"));
|
||||
print_current_name();
|
||||
|
@ -502,9 +508,9 @@ void write_super_block(void)
|
|||
Super.s_state &= ~MINIX_ERROR_FS;
|
||||
|
||||
if (BLOCK_SIZE != lseek(IN, BLOCK_SIZE, SEEK_SET))
|
||||
die("seek failed in write_super_block");
|
||||
die(_("seek failed in write_super_block"));
|
||||
if (BLOCK_SIZE != write(IN, super_block_buffer, BLOCK_SIZE))
|
||||
die("unable to write super-block");
|
||||
die(_("unable to write super-block"));
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -514,11 +520,11 @@ void write_tables(void)
|
|||
write_super_block();
|
||||
|
||||
if (IMAPS*BLOCK_SIZE != write(IN,inode_map,IMAPS*BLOCK_SIZE))
|
||||
die("Unable to write inode map");
|
||||
die(_("Unable to write inode map"));
|
||||
if (ZMAPS*BLOCK_SIZE != write(IN,zone_map,ZMAPS*BLOCK_SIZE))
|
||||
die("Unable to write zone map");
|
||||
die(_("Unable to write zone map"));
|
||||
if (INODE_BUFFER_SIZE != write(IN,inode_buffer,INODE_BUFFER_SIZE))
|
||||
die("Unable to write inodes");
|
||||
die(_("Unable to write inodes"));
|
||||
}
|
||||
|
||||
void get_dirsize (void)
|
||||
|
@ -547,9 +553,9 @@ void get_dirsize (void)
|
|||
void read_superblock(void)
|
||||
{
|
||||
if (BLOCK_SIZE != lseek(IN, BLOCK_SIZE, SEEK_SET))
|
||||
die("seek failed");
|
||||
die(_("seek failed"));
|
||||
if (BLOCK_SIZE != read(IN, super_block_buffer, BLOCK_SIZE))
|
||||
die("unable to read super block");
|
||||
die(_("unable to read super block"));
|
||||
if (MAGIC == MINIX_SUPER_MAGIC) {
|
||||
namelen = 14;
|
||||
dirsize = 16;
|
||||
|
@ -569,20 +575,20 @@ void read_superblock(void)
|
|||
version2 = 1;
|
||||
#endif
|
||||
} else
|
||||
die("bad magic number in super-block");
|
||||
die(_("bad magic number in super-block"));
|
||||
if (ZONESIZE != 0 || BLOCK_SIZE != 1024)
|
||||
die("Only 1k blocks/zones supported");
|
||||
die(_("Only 1k blocks/zones supported"));
|
||||
if (IMAPS * BLOCK_SIZE * 8 < INODES + 1)
|
||||
die("bad s_imap_blocks field in super-block");
|
||||
die(_("bad s_imap_blocks field in super-block"));
|
||||
if (ZMAPS * BLOCK_SIZE * 8 < ZONES - FIRSTZONE + 1)
|
||||
die("bad s_zmap_blocks field in super-block");
|
||||
die(_("bad s_zmap_blocks field in super-block"));
|
||||
}
|
||||
|
||||
void read_tables(void)
|
||||
{
|
||||
inode_map = malloc(IMAPS * BLOCK_SIZE);
|
||||
if (!inode_map)
|
||||
die("Unable to allocate buffer for inode map");
|
||||
die(_("Unable to allocate buffer for inode map"));
|
||||
zone_map = malloc(ZMAPS * BLOCK_SIZE);
|
||||
if (!inode_map)
|
||||
die("Unable to allocate buffer for zone map");
|
||||
|
@ -590,19 +596,19 @@ void read_tables(void)
|
|||
memset(zone_map,0,sizeof(zone_map));
|
||||
inode_buffer = malloc(INODE_BUFFER_SIZE);
|
||||
if (!inode_buffer)
|
||||
die("Unable to allocate buffer for inodes");
|
||||
die(_("Unable to allocate buffer for inodes"));
|
||||
inode_count = malloc(INODES + 1);
|
||||
if (!inode_count)
|
||||
die("Unable to allocate buffer for inode count");
|
||||
die(_("Unable to allocate buffer for inode count"));
|
||||
zone_count = malloc(ZONES);
|
||||
if (!zone_count)
|
||||
die("Unable to allocate buffer for zone count");
|
||||
die(_("Unable to allocate buffer for zone count"));
|
||||
if (IMAPS*BLOCK_SIZE != read(IN,inode_map,IMAPS*BLOCK_SIZE))
|
||||
die("Unable to read inode map");
|
||||
die(_("Unable to read inode map"));
|
||||
if (ZMAPS*BLOCK_SIZE != read(IN,zone_map,ZMAPS*BLOCK_SIZE))
|
||||
die("Unable to read zone map");
|
||||
die(_("Unable to read zone map"));
|
||||
if (INODE_BUFFER_SIZE != read(IN,inode_buffer,INODE_BUFFER_SIZE))
|
||||
die("Unable to read inodes");
|
||||
die(_("Unable to read inodes"));
|
||||
if (NORM_FIRSTZONE != FIRSTZONE) {
|
||||
printf(_("Warning: Firstzone != Norm_firstzone\n"));
|
||||
errors_uncorrected = 1;
|
||||
|
@ -723,7 +729,7 @@ void check_root(void)
|
|||
struct minix_inode * inode = Inode + ROOT_INO;
|
||||
|
||||
if (!inode || !S_ISDIR(inode->i_mode))
|
||||
die("root inode isn't a directory");
|
||||
die(_("root inode isn't a directory"));
|
||||
}
|
||||
|
||||
#ifdef HAVE_MINIX2
|
||||
|
@ -1065,7 +1071,7 @@ void recursive_check(unsigned int ino)
|
|||
|
||||
dir = Inode + ino;
|
||||
if (!S_ISDIR(dir->i_mode))
|
||||
die("internal error");
|
||||
die(_("internal error"));
|
||||
if (dir->i_size < 2 * dirsize) {
|
||||
print_current_name();
|
||||
printf(_(": bad directory: size<32"));
|
||||
|
@ -1100,7 +1106,7 @@ int bad_zone(int i)
|
|||
char buffer[1024];
|
||||
|
||||
if (BLOCK_SIZE*i != lseek(IN, BLOCK_SIZE*i, SEEK_SET))
|
||||
die("seek failed in bad_zone");
|
||||
die(_("seek failed in bad_zone"));
|
||||
return (BLOCK_SIZE != read(IN, buffer, BLOCK_SIZE));
|
||||
}
|
||||
|
||||
|
@ -1234,19 +1240,27 @@ int main(int argc, char ** argv)
|
|||
struct termios tmp;
|
||||
int count;
|
||||
int retcode = 0;
|
||||
char *p;
|
||||
|
||||
program_name = (argc && *argv) ? argv[0] : "fsck.minix";
|
||||
if ((p = strrchr(program_name, '/')) != NULL)
|
||||
program_name = p+1;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
if (argc == 2 &&
|
||||
(!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
|
||||
printf(_("%s from %s\n"), program_name, util_linux_version);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (argc && *argv)
|
||||
program_name = *argv;
|
||||
if (INODE_SIZE * MINIX_INODES_PER_BLOCK != BLOCK_SIZE)
|
||||
die("bad inode size");
|
||||
die(_("bad inode size"));
|
||||
#ifdef HAVE_MINIX2
|
||||
if (INODE_SIZE2 * MINIX2_INODES_PER_BLOCK != BLOCK_SIZE)
|
||||
die("bad v2 inode size");
|
||||
die(_("bad v2 inode size"));
|
||||
#endif
|
||||
while (argc-- > 1) {
|
||||
argv++;
|
||||
|
@ -1272,11 +1286,11 @@ int main(int argc, char ** argv)
|
|||
check_mount(); /* trying to check a mounted filesystem? */
|
||||
if (repair && !automatic) {
|
||||
if (!isatty(0) || !isatty(1))
|
||||
die("need terminal for interactive repairs");
|
||||
die(_("need terminal for interactive repairs"));
|
||||
}
|
||||
IN = open(device_name,repair?O_RDWR:O_RDONLY);
|
||||
if (IN < 0)
|
||||
die("unable to open '%s'");
|
||||
die(_("unable to open '%s'"));
|
||||
for (count=0 ; count<3 ; count++)
|
||||
sync();
|
||||
read_superblock();
|
||||
|
@ -1287,8 +1301,6 @@ int main(int argc, char ** argv)
|
|||
* flags and whether or not the -f switch was specified on the
|
||||
* command line.
|
||||
*/
|
||||
printf("%s, %s / %s\n", program_name, program_version,
|
||||
util_linux_version);
|
||||
if ( !(Super.s_state & MINIX_ERROR_FS) &&
|
||||
(Super.s_state & MINIX_VALID_FS) &&
|
||||
!force ) {
|
||||
|
|
48
disk-utils/mkfs.bfs.8
Normal file
48
disk-utils/mkfs.bfs.8
Normal file
|
@ -0,0 +1,48 @@
|
|||
.\" Copyright 1999 Andries E. Brouwer (aeb@cwi.nl)
|
||||
.\" May be freely distributed.
|
||||
.TH MKFS.BFS 8 "12 Sept 1999" "Util-linux 2.9x" "Linux System Administrator's Manual"
|
||||
.SH NAME
|
||||
mkfs.bfs \- make an SCO bfs filesystem
|
||||
.SH SYNOPSIS
|
||||
.BR "mkfs.bfs [ \-N"
|
||||
nr-of-inodes
|
||||
.B ] [ \-V
|
||||
volume-name
|
||||
.B ] [ \-F
|
||||
fsname
|
||||
.B ]
|
||||
device
|
||||
.B [
|
||||
size-in-blocks
|
||||
.B ]
|
||||
.SH DESCRIPTION
|
||||
.B mkfs.bfs
|
||||
creates an SCO bfs file-system on a block device
|
||||
(usually a disk partition or a file accessed via the loop device).
|
||||
|
||||
The
|
||||
.I size-in-blocks
|
||||
parameter is the desired size of the file system, in blocks.
|
||||
If nothing is specified, the entire partition will be used.
|
||||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-N
|
||||
Specify the desired number of inodes (at most 512).
|
||||
If nothing is specified some default number in the range 48-512 is picked
|
||||
depending on the size of the partition.
|
||||
.TP
|
||||
.BI \-V " volume-label"
|
||||
Specify the volume label. I have no idea if/where this is used.
|
||||
.TP
|
||||
.BI \-F " fsname"
|
||||
Specify the fsname. I have no idea if/where this is used.
|
||||
.TP
|
||||
.B \-v
|
||||
Be verbose.
|
||||
.SH "EXIT CODES"
|
||||
The exit code returned by
|
||||
.B mkfs.bfs
|
||||
is 0 when all went well, and 1 when something went wrong.
|
||||
.SH "SEE ALSO"
|
||||
.BR mkfs (8).
|
284
disk-utils/mkfs.bfs.c
Normal file
284
disk-utils/mkfs.bfs.c
Normal file
|
@ -0,0 +1,284 @@
|
|||
/*
|
||||
* mkfs.bfs - Create SCO BFS filesystem - aeb, 1999-09-07
|
||||
*
|
||||
* Usage: mkfs.bfs [-N nr-of-inodes] [-V volume-name] [-F fsname] device
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <linux/fs.h> /* for BLKGETSIZE */
|
||||
|
||||
#include "../defines.h" /* for util_linux_version */
|
||||
|
||||
#define BFS_ROOT_INO 2
|
||||
#define BFS_NAMELEN 14
|
||||
#define BFS_BLOCKSIZE 512
|
||||
#define BFS_SUPER_MAGIC 0x1badface
|
||||
|
||||
/* superblock - 512 bytes */
|
||||
struct bfssb {
|
||||
unsigned int s_magic;
|
||||
unsigned int s_start; /* byte offset of start of data */
|
||||
unsigned int s_end; /* sizeof(slice)-1 */
|
||||
|
||||
/* for recovery during compaction */
|
||||
int s_from, s_to; /* src and dest block of current transfer */
|
||||
int s_backup_from, s_backup_to;
|
||||
|
||||
/* labels - may well contain garbage */
|
||||
char s_fsname[6];
|
||||
char s_volume[6];
|
||||
char s_pad[472];
|
||||
};
|
||||
|
||||
/* inode - 64 bytes */
|
||||
struct bfsi {
|
||||
unsigned short i_ino;
|
||||
unsigned char i_pad1[2];
|
||||
unsigned long i_first_block;
|
||||
unsigned long i_last_block;
|
||||
unsigned long i_bytes_to_end;
|
||||
unsigned long i_type; /* 1: file, 2: the unique dir */
|
||||
unsigned long i_mode;
|
||||
unsigned long i_uid, i_gid;
|
||||
unsigned long i_nlinks;
|
||||
unsigned long i_atime, i_mtime, i_ctime;
|
||||
unsigned char i_pad2[16];
|
||||
};
|
||||
|
||||
#define BFS_DIR_TYPE 2
|
||||
|
||||
/* directory entry - 16 bytes */
|
||||
struct bfsde {
|
||||
unsigned short d_ino;
|
||||
char d_name[BFS_NAMELEN];
|
||||
};
|
||||
|
||||
|
||||
static char *progname;
|
||||
|
||||
static void
|
||||
fatal(char *s, ...) {
|
||||
va_list p;
|
||||
|
||||
va_start(p, s);
|
||||
fflush(stdout);
|
||||
fprintf(stderr, "\n%s: ", progname);
|
||||
vfprintf(stderr, s, p);
|
||||
va_end(p);
|
||||
fprintf(stderr, "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void) {
|
||||
fprintf(stderr,
|
||||
"Usage: %s [-v] [-N nr-of-inodes] [-V volume-name]\n"
|
||||
" [-F fsname] device [block-count]\n",
|
||||
progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
char *device, *volume, *fsname;
|
||||
int inodes;
|
||||
unsigned long total_blocks, ino_bytes, ino_blocks, data_blocks;
|
||||
unsigned long user_specified_total_blocks = 0;
|
||||
int verbose = 0;
|
||||
int fd;
|
||||
struct bfssb sb;
|
||||
struct bfsi ri;
|
||||
struct bfsde de;
|
||||
struct stat statbuf;
|
||||
time_t now;
|
||||
int c, i, len;
|
||||
char *p;
|
||||
|
||||
progname = argv[0];
|
||||
if ((p = strrchr(progname, '/')) != NULL)
|
||||
progname = p+1;
|
||||
|
||||
if (argc < 2)
|
||||
usage();
|
||||
|
||||
if (argc == 2 &&
|
||||
(!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
|
||||
printf("%s from %s\n", progname, util_linux_version);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
volume = fsname = " "; /* is there a default? */
|
||||
inodes = 0;
|
||||
|
||||
while (EOF != (c = getopt(argc, argv, "vF:N:V:cl:"))) {
|
||||
switch (c) {
|
||||
case 'N':
|
||||
inodes = atol(optarg);
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
len = strlen(optarg);
|
||||
if (len <= 0 || len > 6)
|
||||
fatal("volume name too long");
|
||||
volume = strdup(optarg);
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
len = strlen(optarg);
|
||||
if (len <= 0 || len > 6)
|
||||
fatal("fsname name too long");
|
||||
fsname = strdup(optarg);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
|
||||
/* when called via mkfs we may get options c,l,v */
|
||||
case 'c':
|
||||
case 'l':
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
if (optind == argc)
|
||||
usage();
|
||||
|
||||
device = argv[optind++];
|
||||
|
||||
if (stat(device, &statbuf) == -1) {
|
||||
perror(device);
|
||||
fatal("cannot stat device %s", device);
|
||||
}
|
||||
|
||||
if (!S_ISBLK(statbuf.st_mode))
|
||||
fatal("%s is not a block special device", device);
|
||||
|
||||
fd = open(device, O_RDWR);
|
||||
if (fd == -1) {
|
||||
perror(device);
|
||||
fatal("cannot open %s", device);
|
||||
}
|
||||
|
||||
if (optind == argc-1)
|
||||
user_specified_total_blocks = atoi(argv[optind]);
|
||||
else if (optind != argc)
|
||||
usage();
|
||||
|
||||
if (ioctl(fd, BLKGETSIZE, &total_blocks) == -1) {
|
||||
if (!user_specified_total_blocks) {
|
||||
perror("BLKGETSIZE");
|
||||
fatal("cannot get size of %s", device);
|
||||
}
|
||||
total_blocks = user_specified_total_blocks;
|
||||
} else if (user_specified_total_blocks) {
|
||||
if (user_specified_total_blocks > total_blocks)
|
||||
fatal("blocks argument too large, max is %d",
|
||||
total_blocks);
|
||||
total_blocks = user_specified_total_blocks;
|
||||
}
|
||||
|
||||
if (!inodes) {
|
||||
/* pick some reasonable default */
|
||||
inodes = 8*(total_blocks/800);
|
||||
if (inodes < 48)
|
||||
inodes = 48;
|
||||
if (inodes > 512)
|
||||
inodes = 512;
|
||||
} else {
|
||||
/* believe the user */
|
||||
if (inodes > 512)
|
||||
fatal("too many inodes - max is 512");
|
||||
}
|
||||
|
||||
ino_bytes = inodes * sizeof(struct bfsi);
|
||||
ino_blocks = (ino_bytes + BFS_BLOCKSIZE - 1) / BFS_BLOCKSIZE;
|
||||
data_blocks = total_blocks - ino_blocks - 1;
|
||||
|
||||
/* mimic the behaviour of SCO's mkfs - maybe this limit is needed */
|
||||
if (data_blocks < 32)
|
||||
fatal("not enough space, need at least %d blocks",
|
||||
ino_blocks + 33);
|
||||
|
||||
memset(&sb, 0, sizeof(sb));
|
||||
sb.s_magic = BFS_SUPER_MAGIC;
|
||||
sb.s_start = ino_bytes + sizeof(struct bfssb);
|
||||
sb.s_end = total_blocks * BFS_BLOCKSIZE - 1;
|
||||
sb.s_from = sb.s_to = sb.s_backup_from = sb.s_backup_to = -1;
|
||||
memcpy(sb.s_fsname, fsname, 6);
|
||||
memcpy(sb.s_volume, volume, 6);
|
||||
|
||||
if (verbose) {
|
||||
fprintf(stderr, "Device: %s\n", device);
|
||||
fprintf(stderr, "Volume: <%-6s>\n", volume);
|
||||
fprintf(stderr, "FSname: <%-6s>\n", fsname);
|
||||
fprintf(stderr, "BlockSize: %d\n", BFS_BLOCKSIZE);
|
||||
fprintf(stderr, "Inodes: %d (in %ld block%s)\n",
|
||||
inodes, ino_blocks, (ino_blocks==1) ? "" : "s");
|
||||
fprintf(stderr, "Blocks: %ld\n", total_blocks);
|
||||
fprintf(stderr, "Inode end: %d, Data end: %d\n",
|
||||
sb.s_start-1, sb.s_end);
|
||||
}
|
||||
|
||||
if (write(fd, &sb, sizeof(sb)) != sizeof(sb))
|
||||
fatal("error writing superblock");
|
||||
|
||||
memset(&ri, 0, sizeof(ri));
|
||||
ri.i_ino = BFS_ROOT_INO;
|
||||
ri.i_first_block = 1 + ino_blocks;
|
||||
ri.i_last_block = ri.i_first_block +
|
||||
(inodes * sizeof(de) - 1) / BFS_BLOCKSIZE;
|
||||
ri.i_bytes_to_end = ri.i_first_block * BFS_BLOCKSIZE
|
||||
+ 2 * sizeof(struct bfsde) - 1;
|
||||
ri.i_type = BFS_DIR_TYPE;
|
||||
ri.i_mode = S_IFDIR | 0755; /* or just 0755 */
|
||||
ri.i_uid = 0;
|
||||
ri.i_gid = 1; /* random */
|
||||
ri.i_nlinks = 2;
|
||||
time(&now);
|
||||
ri.i_atime = now;
|
||||
ri.i_mtime = now;
|
||||
ri.i_ctime = now;
|
||||
|
||||
if (write(fd, &ri, sizeof(ri)) != sizeof(ri))
|
||||
fatal("error writing root inode");
|
||||
|
||||
memset(&ri, 0, sizeof(ri));
|
||||
for (i=1; i<inodes; i++)
|
||||
if (write(fd, &ri, sizeof(ri)) != sizeof(ri))
|
||||
fatal("error writing inode");
|
||||
|
||||
if (lseek(fd, (1 + ino_blocks)*BFS_BLOCKSIZE, SEEK_SET) == -1)
|
||||
fatal("seek error");
|
||||
|
||||
memset(&de, 0, sizeof(de));
|
||||
de.d_ino = BFS_ROOT_INO;
|
||||
memcpy(de.d_name, ".", 1);
|
||||
if (write(fd, &de, sizeof(de)) != sizeof(de))
|
||||
fatal("error writing . entry");
|
||||
|
||||
memcpy(de.d_name, "..", 2);
|
||||
if (write(fd, &de, sizeof(de)) != sizeof(de))
|
||||
fatal("error writing .. entry");
|
||||
|
||||
if (close(fd) == -1) {
|
||||
perror(device);
|
||||
fatal("error closing %s", device);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -24,7 +24,6 @@
|
|||
#include <limits.h>
|
||||
#include "nls.h"
|
||||
|
||||
#include "../version.h"
|
||||
#define VERSION UTIL_LINUX_VERSION
|
||||
|
||||
#ifndef DEFAULT_FSTYPE
|
||||
|
@ -41,11 +40,22 @@ int main(int argc, char *argv[])
|
|||
char *fstype = NULL;
|
||||
int i, more = 0, verbose = 0;
|
||||
char *oldpath, *newpath;
|
||||
char *program_name, *p;
|
||||
|
||||
program_name = argv[0];
|
||||
if ((p = strrchr(program_name, '/')) != NULL)
|
||||
program_name = p+1;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
if (argc == 2 &&
|
||||
(!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
|
||||
printf(_("%s from %s\n"), program_name, util_linux_version);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Check commandline options. */
|
||||
opterr = 0;
|
||||
while ((more == 0) && ((i = getopt(argc, argv, "Vt:")) != EOF))
|
||||
|
@ -86,7 +96,7 @@ int main(int argc, char *argv[])
|
|||
argv[--optind] = progname;
|
||||
|
||||
if (verbose) {
|
||||
puts(_("mkfs version " VERSION " (" __DATE__ ")"));
|
||||
printf(_("mkfs version %s (%s)\n"), VERSION, __DATE__);
|
||||
i = optind;
|
||||
while (argv[i])
|
||||
printf("%s ", argv[i++]);
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
.\" Copyright 1992, 1993, 1994 Rickard E. Faith (faith@cs.unc.edu)
|
||||
.\" May be freely distributed.
|
||||
.\" " for emacs hilit19 mode
|
||||
.TH MKFS 8 "2 July 1996" "Util-linux 2.6" "Linux System Administrator's Manual"
|
||||
.TH MKFS.MINIX 8 "2 July 1996" "Util-linux 2.6" "Linux System Administrator's Manual"
|
||||
.SH NAME
|
||||
mkfs \- make a Linux MINIX filesystem
|
||||
mkfs.minix \- make a Linux MINIX filesystem
|
||||
.SH SYNOPSIS
|
||||
.BR "mkfs [ \-c | \-l filename ] [ \-n"
|
||||
.BR "mkfs.minix [ \-c | \-l filename ] [ \-n"
|
||||
namelength
|
||||
.B ] [ \-i
|
||||
inodecount
|
||||
|
@ -15,7 +14,7 @@ device
|
|||
size-in-blocks
|
||||
.B ]
|
||||
.SH DESCRIPTION
|
||||
.B mkfs
|
||||
.B mkfs.minix
|
||||
creates a Linux MINIX file-system on a device (usually a disk partition).
|
||||
|
||||
The
|
||||
|
@ -33,14 +32,11 @@ is usually of the following form:
|
|||
|
||||
The
|
||||
.I size-in-blocks
|
||||
parameter is the desired size of the file system, in blocks. This
|
||||
information can be determined from the
|
||||
.BR fdisk (8)
|
||||
or
|
||||
.BR cfdisk (8)
|
||||
program. If omitted it will be determined automaticaly. Only block
|
||||
counts strictly greater than 10 and strictly less than 65536 are
|
||||
allowed.
|
||||
parameter is the desired size of the file system, in blocks.
|
||||
It is present only for backwards compatibility.
|
||||
If omitted the size will be determined automatically.
|
||||
Only block counts strictly greater than 10 and strictly less than
|
||||
65536 are allowed.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-c
|
||||
|
@ -50,7 +46,7 @@ are found, the count is printed.
|
|||
.BI \-n " namelength"
|
||||
Specify the maximum length of filenames.
|
||||
Currently, the only allowable values are 14 and 30.
|
||||
.B 30 is the default.
|
||||
The default is 30.
|
||||
.TP
|
||||
.BI \-i " inodecount"
|
||||
Specify the number of inodes for the filesystem.
|
||||
|
@ -76,24 +72,4 @@ Usage or syntax error
|
|||
.SH "SEE ALSO"
|
||||
.BR mkfs (8),
|
||||
.BR fsck (8),
|
||||
.BR mke2fs (8),
|
||||
.BR e2fsck (8),
|
||||
.BR reboot (8)
|
||||
.\" .SH AUTHORS
|
||||
.\" Linus Torvalds (torvalds@cs.helsinki.fi).
|
||||
.\" .br
|
||||
.\" Error code values by Rik Faith (faith@cs.unc.edu)
|
||||
.\" .br
|
||||
.\" Inode request feature by Scott Heavner (sdh@po.cwru.edu)
|
||||
.\" .br
|
||||
.\" Support for the file system valid flag by Dr. Wettstein
|
||||
.\" (greg%wind.uucp@plains.nodak.edu)
|
||||
.\" .br
|
||||
.\" Check to prevent mkfs of mounted filesystem and boot sector clearing
|
||||
.\" by Daniel Quinlan (quinlan@yggdrasil.com)
|
||||
.\" .br
|
||||
.\" Minix v2 support by Andreas Schwab
|
||||
.\" (schwab@issan.informatik.uni-dortmund.de), updated by Nicolai
|
||||
.\" Langfeldt (janl@math.uio.no)
|
||||
.\" .br
|
||||
.\" Portability patch by Russell King.
|
||||
|
|
|
@ -76,7 +76,6 @@
|
|||
#include <linux/minix_fs.h>
|
||||
|
||||
#include "nls.h"
|
||||
#include "../version.h"
|
||||
|
||||
#ifdef MINIX2_SUPER_MAGIC2
|
||||
#define HAVE_MINIX2 1
|
||||
|
@ -489,6 +488,7 @@ void setup_tables(void)
|
|||
ZONESIZE = 0;
|
||||
MAXSIZE = version2 ? 0x7fffffff : (7+512+512*512)*1024;
|
||||
ZONES = BLOCKS;
|
||||
|
||||
/* some magic nrs: 1 inode / 3 blocks */
|
||||
if ( req_nr_inodes == 0 )
|
||||
inodes = BLOCKS/3;
|
||||
|
@ -507,9 +507,13 @@ void setup_tables(void)
|
|||
inodes = 65535;
|
||||
INODES = inodes;
|
||||
IMAPS = UPPER(INODES + 1,BITS_PER_BLOCK);
|
||||
ZMAPS = 0;
|
||||
while (ZMAPS != UPPER(BLOCKS - NORM_FIRSTZONE + 1,BITS_PER_BLOCK))
|
||||
ZMAPS = UPPER(BLOCKS - NORM_FIRSTZONE + 1,BITS_PER_BLOCK);
|
||||
ZMAPS = UPPER(BLOCKS - (1+IMAPS+INODE_BLOCKS), BITS_PER_BLOCK+1);
|
||||
/* The old code here
|
||||
* ZMAPS = 0;
|
||||
* while (ZMAPS != UPPER(BLOCKS - NORM_FIRSTZONE + 1,BITS_PER_BLOCK))
|
||||
* ZMAPS = UPPER(BLOCKS - NORM_FIRSTZONE + 1,BITS_PER_BLOCK);
|
||||
* was no good, since it may loop. - aeb
|
||||
*/
|
||||
FIRSTZONE = NORM_FIRSTZONE;
|
||||
inode_map = malloc(IMAPS * BLOCK_SIZE);
|
||||
zone_map = malloc(ZMAPS * BLOCK_SIZE);
|
||||
|
@ -630,9 +634,23 @@ int main(int argc, char ** argv)
|
|||
char * tmp;
|
||||
struct stat statbuf;
|
||||
char * listfile = NULL;
|
||||
char * p;
|
||||
|
||||
if (argc && *argv)
|
||||
program_name = *argv;
|
||||
if ((p = strrchr(program_name, '/')) != NULL)
|
||||
program_name = p+1;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
if (argc == 2 &&
|
||||
(!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
|
||||
printf(_("%s from %s\n"), program_name, util_linux_version);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (INODE_SIZE * MINIX_INODES_PER_BLOCK != BLOCK_SIZE)
|
||||
die(_("bad inode size"));
|
||||
#ifdef HAVE_MINIX2
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
.SH NAME
|
||||
mkswap \- set up a Linux swap area
|
||||
.SH SYNOPSIS
|
||||
.BI "mkswap [\-c] [\-v" N "] [\-f] " device " [" size "]"
|
||||
.BI "mkswap [\-c] [\-v" N "] [\-f] [\-p " PSZ "] "device " [" size "]"
|
||||
.SH DESCRIPTION
|
||||
.B mkswap
|
||||
sets up a Linux swap area on a device or in a file.
|
||||
|
@ -30,6 +30,8 @@ but can also be a file.
|
|||
The Linux kernel does not look at partition Id's, but
|
||||
many installation scripts will assume that partitions
|
||||
of hex type 82 (LINUX_SWAP) are meant to be swap partitions.
|
||||
(Warning: Solaris also uses this type. Be careful not to kill
|
||||
your Solaris partitions.)
|
||||
|
||||
The
|
||||
.I size
|
||||
|
@ -39,6 +41,18 @@ parameter is superfluous but retained for backwards compatibility.
|
|||
will use the entire partition or file if it is omitted.
|
||||
Specifying it is unwise - a typo may destroy your disk.)
|
||||
|
||||
The
|
||||
.I PSZ
|
||||
parameter specifies the page size to use. It is almost always
|
||||
unnecessary (even unwise) to specify it, but certain old libc
|
||||
versions lie about the page size, so it is possible that
|
||||
.B mkswap
|
||||
gets it wrong. The symptom is that a subsequent
|
||||
.B swapon
|
||||
fails because no swap signature is found. Typical values for
|
||||
.I PSZ
|
||||
are 4096 or 8192.
|
||||
|
||||
Linux knows about two styles of swap areas, old style and new style.
|
||||
The last 10 bytes of the first page of the swap area distinguishes
|
||||
them: old style has `SWAP_SPACE', new style has `SWAPSPACE2' as
|
||||
|
@ -51,9 +65,9 @@ Also, the last 10 bytes hold the signature. So, if the page
|
|||
size is S, an old style swap area can describe at most
|
||||
8*(S-10)-1 pages used for swapping.
|
||||
With S=4096 (as on i386), the useful area is at most 133890048 bytes
|
||||
(almost 128 MB if you believe in 1 MB=2^20 bytes), and the rest is wasted.
|
||||
(almost 128 MiB), and the rest is wasted.
|
||||
On an alpha and sparc64, with S=8192, the useful area is at most
|
||||
535560992 bytes (almost 512 MB with the same proviso).
|
||||
535560992 bytes (almost 512 MiB).
|
||||
|
||||
The old setup wastes most of this bitmap page, because zero bits
|
||||
denote bad blocks or blocks past the end of the swap space,
|
||||
|
@ -63,12 +77,12 @@ to use a swap space with hundreds of bad blocks. (I would not even
|
|||
use a swap space with 1 bad block.)
|
||||
In the new style swap area this is precisely what is done.
|
||||
The maximum useful size of a swap area now depends on the architecture.
|
||||
It is roughly 2GB on i386, PPC, m68k, ARM, 1GB on sparc, 512MB on mips,
|
||||
128GB on alpha and 3TB on sparc64.
|
||||
It is roughly 2GiB on i386, PPC, m68k, ARM, 1GiB on sparc, 512MiB on mips,
|
||||
128GiB on alpha and 3TiB on sparc64.
|
||||
|
||||
Note that before 2.1.117 the kernel allocated one byte for each page,
|
||||
while it now allocates two bytes, so that taking a swap area of 2 GB
|
||||
in use might require 2 MB of kernel memory.
|
||||
while it now allocates two bytes, so that taking a swap area of 2 GiB
|
||||
in use might require 2 MiB of kernel memory.
|
||||
|
||||
Presently, Linux allows 8 swap areas. The areas in use can be seen
|
||||
in the file
|
||||
|
@ -114,6 +128,9 @@ Without this option
|
|||
will refuse to create a v0 swap on a device with a valid SPARC superblock,
|
||||
as that probably means one is going to erase the partition table.
|
||||
.TP
|
||||
.BI "\-p " PSZ
|
||||
Specify the page size to use.
|
||||
.TP
|
||||
.B \-v0
|
||||
Create an old style swap area.
|
||||
.TP
|
||||
|
|
|
@ -77,9 +77,20 @@ linux_version_code(void) {
|
|||
/*
|
||||
* The definition of the union swap_header uses the constant PAGE_SIZE.
|
||||
* Unfortunately, on some architectures this depends on the hardware model,
|
||||
* and can only be found at run time -- we use getpagesize().
|
||||
* and can only be found at run time -- we use getpagesize(), so that
|
||||
* we do not need separate binaries e.g. for sun4, sun4c/d/m and sun4u.
|
||||
*
|
||||
* Even more unfortunately, getpagesize() does not always return
|
||||
* the right information. For example, libc4 and libc5 do not use
|
||||
* the system call but invent a value themselves
|
||||
* (EXEC_PAGESIZE or NBPG * CLSIZE or NBPC), and thus it may happen
|
||||
* that e.g. on a sparc PAGE_SIZE=4096 and getpagesize() returns 8192.
|
||||
* What to do? Let us allow the user to specify the pagesize explicitly.
|
||||
*/
|
||||
|
||||
static int user_pagesize = 0;
|
||||
static int kernel_pagesize; /* obtained via getpagesize(); */
|
||||
static int defined_pagesize = 0; /* PAGE_SIZE, when that exists */
|
||||
static int pagesize;
|
||||
static int *signature_page;
|
||||
|
||||
|
@ -94,12 +105,31 @@ struct swap_header_v1 {
|
|||
|
||||
static void
|
||||
init_signature_page() {
|
||||
pagesize = getpagesize();
|
||||
|
||||
#ifdef PAGE_SIZE
|
||||
if (pagesize != PAGE_SIZE)
|
||||
fprintf(stderr, _("Assuming pages of size %d\n"), pagesize);
|
||||
defined_pagesize = PAGE_SIZE;
|
||||
#endif
|
||||
kernel_pagesize = getpagesize();
|
||||
pagesize = kernel_pagesize;
|
||||
|
||||
if (user_pagesize) {
|
||||
if ((user_pagesize & (user_pagesize-1)) ||
|
||||
user_pagesize < 1024) {
|
||||
fprintf(stderr, _("Bad user-specified page size %d\n"),
|
||||
user_pagesize);
|
||||
exit(1);
|
||||
}
|
||||
pagesize = user_pagesize;
|
||||
}
|
||||
|
||||
if (user_pagesize && user_pagesize != kernel_pagesize &&
|
||||
user_pagesize != defined_pagesize)
|
||||
fprintf(stderr, _("Using user-specified page size %d, "
|
||||
"instead of the system values %d/%d\n"),
|
||||
pagesize, kernel_pagesize, defined_pagesize);
|
||||
else if (defined_pagesize && pagesize != defined_pagesize)
|
||||
fprintf(stderr, _("Assuming pages of size %d (not %d)\n"),
|
||||
pagesize, defined_pagesize);
|
||||
|
||||
signature_page = (int *) malloc(pagesize);
|
||||
memset(signature_page,0,pagesize);
|
||||
p = (struct swap_header_v1 *) signature_page;
|
||||
|
@ -158,8 +188,8 @@ It is roughly 2GB on i386, PPC, m68k, ARM, 1GB on sparc, 512MB on mips,
|
|||
|
||||
#define MAX_BADPAGES ((pagesize-1024-128*sizeof(int)-10)/sizeof(int))
|
||||
|
||||
static void bit_set (unsigned int *addr, unsigned int nr)
|
||||
{
|
||||
static void
|
||||
bit_set (unsigned int *addr, unsigned int nr) {
|
||||
unsigned int r, m;
|
||||
|
||||
addr += nr / (8 * sizeof(int));
|
||||
|
@ -168,8 +198,8 @@ static void bit_set (unsigned int *addr, unsigned int nr)
|
|||
*addr = r | m;
|
||||
}
|
||||
|
||||
static int bit_test_and_clear (unsigned int *addr, unsigned int nr)
|
||||
{
|
||||
static int
|
||||
bit_test_and_clear (unsigned int *addr, unsigned int nr) {
|
||||
unsigned int r, m;
|
||||
|
||||
addr += nr / (8 * sizeof(int));
|
||||
|
@ -179,14 +209,19 @@ static int bit_test_and_clear (unsigned int *addr, unsigned int nr)
|
|||
return (r & m) != 0;
|
||||
}
|
||||
|
||||
void fatal_error(const char * fmt_string)
|
||||
{
|
||||
fprintf(stderr,fmt_string,program_name,device_name);
|
||||
void
|
||||
usage(void) {
|
||||
fprintf(stderr,
|
||||
_("Usage: %s [-c] [-v0|-v1] [-pPAGESZ] /dev/name [blocks]\n"),
|
||||
program_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#define usage() fatal_error(_("Usage: %s [-c] [-v0|-v1] /dev/name [blocks]\n"))
|
||||
#define die(str) fatal_error(_("%s: " str "\n"))
|
||||
void
|
||||
die(const char *str) {
|
||||
fprintf(stderr, "%s: %s\n", program_name, str);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
page_ok(int page) {
|
||||
|
@ -200,7 +235,7 @@ page_bad(int page) {
|
|||
bit_test_and_clear(signature_page, page);
|
||||
else {
|
||||
if (badpages == MAX_BADPAGES)
|
||||
die("too many bad pages");
|
||||
die(_("too many bad pages"));
|
||||
p->badpages[badpages] = page;
|
||||
}
|
||||
badpages++;
|
||||
|
@ -214,7 +249,7 @@ check_blocks(void) {
|
|||
|
||||
buffer = malloc(pagesize);
|
||||
if (!buffer)
|
||||
die("Out of memory");
|
||||
die(_("Out of memory"));
|
||||
current_page = 0;
|
||||
while (current_page < PAGES) {
|
||||
if (!check) {
|
||||
|
@ -223,7 +258,7 @@ check_blocks(void) {
|
|||
}
|
||||
if (do_seek && lseek(DEV,current_page*pagesize,SEEK_SET) !=
|
||||
current_page*pagesize)
|
||||
die("seek failed in check_blocks");
|
||||
die(_("seek failed in check_blocks"));
|
||||
if ((do_seek = (pagesize != read(DEV, buffer, pagesize)))) {
|
||||
page_bad(current_page++);
|
||||
continue;
|
||||
|
@ -236,8 +271,8 @@ check_blocks(void) {
|
|||
printf(_("%d bad pages\n"), badpages);
|
||||
}
|
||||
|
||||
static long valid_offset (int fd, int offset)
|
||||
{
|
||||
static long
|
||||
valid_offset (int fd, int offset) {
|
||||
char ch;
|
||||
|
||||
if (lseek (fd, offset, 0) < 0)
|
||||
|
@ -248,8 +283,7 @@ static long valid_offset (int fd, int offset)
|
|||
}
|
||||
|
||||
static int
|
||||
find_size (int fd)
|
||||
{
|
||||
find_size (int fd) {
|
||||
unsigned int high, low;
|
||||
|
||||
low = 0;
|
||||
|
@ -269,8 +303,7 @@ find_size (int fd)
|
|||
|
||||
/* return size in pages, to avoid integer overflow */
|
||||
static long
|
||||
get_size(const char *file)
|
||||
{
|
||||
get_size(const char *file) {
|
||||
int fd;
|
||||
long size;
|
||||
|
||||
|
@ -289,58 +322,85 @@ get_size(const char *file)
|
|||
return size;
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
char * tmp;
|
||||
int
|
||||
isnzdigit(char c) {
|
||||
return (c >= '1' && c <= '9');
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char ** argv) {
|
||||
struct stat statbuf;
|
||||
int sz;
|
||||
int i, sz;
|
||||
int maxpages;
|
||||
int goodpages;
|
||||
int offset;
|
||||
int force = 0;
|
||||
char *block_count = 0;
|
||||
char *pp;
|
||||
|
||||
program_name = (argc && *argv) ? argv[0] : "fsck.minix";
|
||||
if ((pp = strrchr(program_name, '/')) != NULL)
|
||||
program_name = pp+1;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
if (argc == 2 &&
|
||||
(!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
|
||||
printf(_("%s from %s\n"), program_name, util_linux_version);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (argc && *argv)
|
||||
program_name = *argv;
|
||||
|
||||
init_signature_page(); /* get pagesize */
|
||||
|
||||
while (argc-- > 1) {
|
||||
argv++;
|
||||
if (argv[0][0] != '-') {
|
||||
if (device_name) {
|
||||
int blocks_per_page = pagesize/1024;
|
||||
PAGES = strtol(argv[0],&tmp,0)/blocks_per_page;
|
||||
if (*tmp)
|
||||
usage();
|
||||
} else
|
||||
device_name = argv[0];
|
||||
} else {
|
||||
switch (argv[0][1]) {
|
||||
for (i=1; i<argc; i++) {
|
||||
if (argv[i][0] == '-') {
|
||||
switch (argv[i][1]) {
|
||||
case 'c':
|
||||
check=1;
|
||||
break;
|
||||
case 'f':
|
||||
force=1;
|
||||
break;
|
||||
case 'p':
|
||||
pp = argv[i]+2;
|
||||
if (!*pp && i+1 < argc)
|
||||
pp = argv[++i];
|
||||
if (isnzdigit(*pp))
|
||||
user_pagesize=atoi(pp);
|
||||
else
|
||||
usage();
|
||||
break;
|
||||
case 'v':
|
||||
version = atoi(argv[0]+2);
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
} else if (!device_name) {
|
||||
device_name = argv[i];
|
||||
} else if (!block_count) {
|
||||
block_count = argv[i];
|
||||
} else
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
init_signature_page(); /* get pagesize */
|
||||
|
||||
if (!device_name) {
|
||||
fprintf(stderr,
|
||||
_("%s: error: Nowhere to set up swap on?\n"),
|
||||
program_name);
|
||||
usage();
|
||||
}
|
||||
if (block_count) {
|
||||
/* this silly user specified the number of blocks
|
||||
explicitly */
|
||||
char *tmp;
|
||||
int blocks_per_page = pagesize/1024;
|
||||
PAGES = strtol(block_count,&tmp,0)/blocks_per_page;
|
||||
if (*tmp)
|
||||
usage();
|
||||
}
|
||||
sz = get_size(device_name);
|
||||
if (!PAGES) {
|
||||
PAGES = sz;
|
||||
|
@ -401,7 +461,7 @@ int main(int argc, char ** argv)
|
|||
if (!S_ISBLK(statbuf.st_mode))
|
||||
check=0;
|
||||
else if (statbuf.st_rdev == 0x0300 || statbuf.st_rdev == 0x0340)
|
||||
die("Will not try to make swapdevice on '%s'");
|
||||
die(_("Will not try to make swapdevice on '%s'"));
|
||||
|
||||
#ifdef __sparc__
|
||||
if (!force && version == 0) {
|
||||
|
@ -410,7 +470,7 @@ int main(int argc, char ** argv)
|
|||
unsigned short *q, sum;
|
||||
|
||||
if (read(DEV, buffer, 512) != 512)
|
||||
die("fatal: first page unreadable");
|
||||
die(_("fatal: first page unreadable"));
|
||||
if (buffer[508] == 0xDA && buffer[509] == 0xBE) {
|
||||
q = (unsigned short *)(buffer + 510);
|
||||
for (sum = 0; q >= (unsigned short *) buffer;)
|
||||
|
@ -431,7 +491,7 @@ the -f option to force it.\n"),
|
|||
if (version == 0 || check)
|
||||
check_blocks();
|
||||
if (version == 0 && !bit_test_and_clear(signature_page,0))
|
||||
die("fatal: first page unreadable");
|
||||
die(_("fatal: first page unreadable"));
|
||||
if (version == 1) {
|
||||
p->version = version;
|
||||
p->last_page = PAGES-1;
|
||||
|
@ -440,23 +500,23 @@ the -f option to force it.\n"),
|
|||
|
||||
goodpages = PAGES - badpages - 1;
|
||||
if (goodpages <= 0)
|
||||
die("Unable to set up swap-space: unreadable");
|
||||
die(_("Unable to set up swap-space: unreadable"));
|
||||
printf(_("Setting up swapspace version %d, size = %ld bytes\n"),
|
||||
version, (long)(goodpages*pagesize));
|
||||
write_signature((version == 0) ? "SWAP-SPACE" : "SWAPSPACE2");
|
||||
|
||||
offset = ((version == 0) ? 0 : 1024);
|
||||
if (lseek(DEV, offset, SEEK_SET) != offset)
|
||||
die("unable to rewind swap-device");
|
||||
die(_("unable to rewind swap-device"));
|
||||
if (write(DEV,(char*)signature_page+offset, pagesize-offset)
|
||||
!= pagesize-offset)
|
||||
die("unable to write signature page");
|
||||
die(_("unable to write signature page"));
|
||||
|
||||
/*
|
||||
* A subsequent swapon() will fail if the signature
|
||||
* is not actually on disk. (This is a kernel bug.)
|
||||
*/
|
||||
if (fsync(DEV))
|
||||
die("fsync failed");
|
||||
die(_("fsync failed"));
|
||||
return 0;
|
||||
}
|
||||
|
|
87
disk-utils/raw.8
Normal file
87
disk-utils/raw.8
Normal file
|
@ -0,0 +1,87 @@
|
|||
.\" -*- nroff -*-
|
||||
.TH RAW 8 "Aug 1999" "Version 0.1"
|
||||
.SH NAME
|
||||
raw \- bind a Linux raw character device
|
||||
.SH SYNOPSIS
|
||||
.B raw
|
||||
.I /dev/raw<N> <major> <minor>
|
||||
.PP
|
||||
.B raw
|
||||
.I /dev/raw<N> /dev/<blockdev>
|
||||
.PP
|
||||
.B raw
|
||||
.B \-q
|
||||
.I /dev/raw<N>
|
||||
.PP
|
||||
.B raw
|
||||
.B \-qa
|
||||
.SH DESCRIPTION
|
||||
.B raw
|
||||
is used to bind a Linux raw character device to a block device. Any
|
||||
block device may be used: at the time of binding, the device driver does
|
||||
not even have to be accessible (it may be loaded on demand as a kernel
|
||||
module later).
|
||||
.PP
|
||||
.B raw
|
||||
is used in two modes: it either sets raw device bindings, or it queries
|
||||
existing bindings. When setting a raw device,
|
||||
.I /dev/raw<N>
|
||||
is the device name of an existing raw device node in the filesystem.
|
||||
The block device to which it is to be bound can be specified either in
|
||||
terms of its
|
||||
.I major
|
||||
and
|
||||
.I minor
|
||||
device numbers, or as a path name
|
||||
.I /dev/<blockdev>
|
||||
to an existing block device file.
|
||||
.PP
|
||||
The bindings already in existence can be queried with the
|
||||
.I \-q
|
||||
option, with is used either with a raw device filename to query that one
|
||||
device, or with the
|
||||
.I \-a
|
||||
option to query all bound raw devices.
|
||||
.PP
|
||||
Once bound to a block device, a raw device can be opened, read and
|
||||
written, just like the block device it is bound to. However, the raw
|
||||
device does not behave exactly like the block device. In particular,
|
||||
access to the raw device bypasses the kernel's block buffer cache
|
||||
entirely: all I/O is done directly to and from the address space of the
|
||||
process performing the I/O. If the underlying block device driver can
|
||||
support DMA, then no data copying at all is required to complete the
|
||||
I/O.
|
||||
.PP
|
||||
Because raw I/O involves direct hardware access to a process's memory, a
|
||||
few extra restrictions must be observed. All I/Os must be correctly
|
||||
aligned in memory and on disk: they must start at a sector offset on
|
||||
disk, they must be an exact number of sectors long, and the data buffer
|
||||
in virtual memory must also be aligned to a multiple of the sector
|
||||
size. The sector size is 512 bytes for most devices.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -q
|
||||
Set query mode.
|
||||
.B raw
|
||||
will query an existing binding instead of setting a new one.
|
||||
.TP
|
||||
.B -a
|
||||
With
|
||||
.B -q
|
||||
, specifies that all bound raw devices should be queried.
|
||||
.TP
|
||||
.B -h
|
||||
provides a usage summary.
|
||||
.SH BUGS
|
||||
The Linux
|
||||
.B dd
|
||||
(1) command does not currently align its buffers correctly, and so
|
||||
cannot be used on raw devices.
|
||||
.PP
|
||||
Raw I/O devices do not maintain cache coherency with the Linux block
|
||||
device buffer cache. If you use raw I/O to overwrite data already in
|
||||
the buffer cache, the buffer cache will no longer correspond to the
|
||||
contents of the actual storage device underneath. This is deliberate,
|
||||
but is regarded either a bug or a feature depending on who you ask!
|
||||
.SH AUTHOR
|
||||
Stephen Tweedie (sct@redhat.com)
|
217
disk-utils/raw.c
Normal file
217
disk-utils/raw.c
Normal file
|
@ -0,0 +1,217 @@
|
|||
/*
|
||||
* raw.c: User mode tool to bind and query raw character devices.
|
||||
*
|
||||
* Stephen Tweedie, 1999
|
||||
*
|
||||
* This file may be redistributed under the terms of the GNU General
|
||||
* Public License, version 2.
|
||||
*
|
||||
* Copyright Red Hat Software, 1999
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <sys/raw.h>
|
||||
|
||||
|
||||
|
||||
char * progname;
|
||||
int do_query = 0;
|
||||
int do_query_all = 0;
|
||||
|
||||
int master_fd;
|
||||
int raw_minor;
|
||||
|
||||
void open_raw_ctl(void);
|
||||
int query(int minor, int quiet);
|
||||
int bind (int minor, int block_major, int block_minor);
|
||||
|
||||
|
||||
static void usage(int err)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"Usage:\n"
|
||||
" %s /dev/rawN <major> <minor>\n"
|
||||
" %s /dev/rawN /dev/<blockdev>\n"
|
||||
" %s -q /dev/rawN\n"
|
||||
" %s -qa\n",
|
||||
progname, progname, progname, progname);
|
||||
exit(err);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char c;
|
||||
char * raw_name;
|
||||
char * block_name;
|
||||
int err;
|
||||
int block_major, block_minor;
|
||||
int i;
|
||||
|
||||
struct stat statbuf;
|
||||
|
||||
progname = argv[0];
|
||||
|
||||
while ((c = getopt(argc, argv, "ahq")) != EOF) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
do_query_all = 1;
|
||||
break;
|
||||
case 'h':
|
||||
usage(0);
|
||||
case 'q':
|
||||
do_query = 1;
|
||||
break;
|
||||
default:
|
||||
usage(1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for, and open, the master raw device, /dev/raw
|
||||
*/
|
||||
|
||||
open_raw_ctl();
|
||||
|
||||
if (do_query_all) {
|
||||
if (optind < argc)
|
||||
usage(1);
|
||||
for (i=1; i<255; i++)
|
||||
query(i, 1);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* It's a bind or a single query. Either way we need a raw device.
|
||||
*/
|
||||
|
||||
if (optind >= argc)
|
||||
usage(1);
|
||||
raw_name = argv[optind++];
|
||||
|
||||
err = stat(raw_name, &statbuf);
|
||||
if (err) {
|
||||
fprintf (stderr, "Cannot locate raw device '%s' (%s)\n",
|
||||
raw_name, strerror(errno));
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (!S_ISCHR(statbuf.st_mode)) {
|
||||
fprintf (stderr, "raw device '%s' is not a character dev\n",
|
||||
raw_name);
|
||||
exit(2);
|
||||
}
|
||||
if (major(statbuf.st_rdev) != RAW_MAJOR) {
|
||||
fprintf (stderr, "Device '%s' is not a raw dev\n",
|
||||
raw_name);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
raw_minor = minor(statbuf.st_rdev);
|
||||
|
||||
if (do_query)
|
||||
return query(raw_minor, 0);
|
||||
|
||||
/*
|
||||
* It's not a query, so we still have some parsing to do. Have
|
||||
* we been given a block device filename or a major/minor pair?
|
||||
*/
|
||||
|
||||
switch (argc - optind) {
|
||||
case 1:
|
||||
block_name = argv[optind];
|
||||
err = stat(block_name, &statbuf);
|
||||
if (err) {
|
||||
fprintf (stderr,
|
||||
"Cannot locate block device '%s' (%s)\n",
|
||||
block_name, strerror(errno));
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (!S_ISBLK(statbuf.st_mode)) {
|
||||
fprintf (stderr, "Device '%s' is not a block dev\n",
|
||||
block_name);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
block_major = major(statbuf.st_rdev);
|
||||
block_minor = minor(statbuf.st_rdev);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
block_major = strtol(argv[optind], 0, 0);
|
||||
block_minor = strtol(argv[optind+1], 0, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
usage(1);
|
||||
}
|
||||
|
||||
return bind(raw_minor, block_major, block_minor);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void open_raw_ctl(void)
|
||||
{
|
||||
master_fd = open("/dev/raw", O_RDWR, 0);
|
||||
if (master_fd < 0) {
|
||||
fprintf (stderr,
|
||||
"Cannot open master raw device '/dev/raw' (%s)\n",
|
||||
strerror(errno));
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
int query(int minor, int quiet)
|
||||
{
|
||||
struct raw_config_request rq;
|
||||
int err;
|
||||
|
||||
rq.raw_minor = minor;
|
||||
err = ioctl(master_fd, RAW_GETBIND, &rq);
|
||||
if (err < 0) {
|
||||
if (quiet && errno == ENODEV)
|
||||
return 3;
|
||||
fprintf (stderr,
|
||||
"Error querying raw device (%s)\n",
|
||||
strerror(errno));
|
||||
exit(3);
|
||||
}
|
||||
if (quiet && !rq.block_major && !rq.block_minor)
|
||||
return 0;
|
||||
printf ("/dev/raw%d: bound to major %d, minor %d\n",
|
||||
minor, (int) rq.block_major, (int) rq.block_minor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bind(int minor, int block_major, int block_minor)
|
||||
{
|
||||
struct raw_config_request rq;
|
||||
int err;
|
||||
|
||||
rq.raw_minor = minor;
|
||||
rq.block_major = block_major;
|
||||
rq.block_minor = block_minor;
|
||||
err = ioctl(master_fd, RAW_SETBIND, &rq);
|
||||
if (err < 0) {
|
||||
fprintf (stderr,
|
||||
"Error setting raw device (%s)\n",
|
||||
strerror(errno));
|
||||
exit(3);
|
||||
}
|
||||
printf ("/dev/raw%d: bound to major %d, minor %d\n",
|
||||
raw_minor, (int) rq.block_major, (int) rq.block_minor);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -113,14 +113,23 @@ main(int argc,char **argv)
|
|||
{
|
||||
int fd;
|
||||
unsigned int cmd;
|
||||
char *name;
|
||||
char *progname, *p;
|
||||
|
||||
progname = argv[0];
|
||||
if ((p = strrchr(progname, '/')) != NULL)
|
||||
progname = p+1;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
name = argv[0];
|
||||
if (argc < 3) usage(name);
|
||||
if (argc == 2 &&
|
||||
(!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) {
|
||||
printf(_("%s from %s\n"), progname, util_linux_version);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (argc < 3) usage(progname);
|
||||
cmd = FDSETPRM;
|
||||
if (*argv[1] == '-') {
|
||||
switch (argv[1][1]) {
|
||||
|
@ -142,7 +151,7 @@ main(int argc,char **argv)
|
|||
break;
|
||||
#endif
|
||||
default:
|
||||
usage(name);
|
||||
usage(progname);
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
|
@ -152,11 +161,11 @@ main(int argc,char **argv)
|
|||
exit(1);
|
||||
}
|
||||
if (cmd != FDSETPRM && cmd != FDDEFPRM) {
|
||||
if (argc != 2) usage(name);
|
||||
if (argc != 2) usage(progname);
|
||||
cmd_without_param(cmd,fd);
|
||||
}
|
||||
if (argc != 11 && argc != 3)
|
||||
usage(name);
|
||||
usage(progname);
|
||||
else if (argc == 11)
|
||||
set_params(cmd,fd,&argv[2]);
|
||||
else
|
||||
|
|
|
@ -69,7 +69,6 @@
|
|||
#endif
|
||||
#include <signal.h>
|
||||
#include <math.h>
|
||||
#include <locale.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
@ -89,7 +88,6 @@ typedef long ext2_loff_t;
|
|||
extern ext2_loff_t ext2_llseek(unsigned int fd, ext2_loff_t offset,
|
||||
unsigned int origin);
|
||||
|
||||
#include "../version.h"
|
||||
#define VERSION UTIL_LINUX_VERSION
|
||||
|
||||
#define DEFAULT_DEVICE "/dev/hda"
|
||||
|
@ -1316,7 +1314,7 @@ void new_part(int i)
|
|||
int num_sects = last - first + 1;
|
||||
int len, ext, j;
|
||||
char *errmsg;
|
||||
|
||||
double sectors_per_MB = K*K / 512.0;
|
||||
|
||||
if (p_info[i].num == PRI_OR_LOG) {
|
||||
static struct MenuItem menuPartType[]=
|
||||
|
@ -1341,7 +1339,7 @@ void new_part(int i)
|
|||
else
|
||||
print_warning(_("!!! Internal error !!!"));
|
||||
|
||||
sprintf(def, "%.2f", ceiling(num_sects/(K*0.02))/100);
|
||||
sprintf(def, "%.2f", num_sects/sectors_per_MB);
|
||||
mvaddstr(COMMAND_LINE_Y, COMMAND_LINE_X, _("Size (in MB): "));
|
||||
if ((len = get_string(response, LINE_LENGTH, def)) <= 0 &&
|
||||
len != GS_DEFAULT)
|
||||
|
@ -2367,8 +2365,13 @@ void draw_partition(int i)
|
|||
}
|
||||
|
||||
if (p_info[i].id > 0) {
|
||||
char *dbn = my_basename(disk_device);
|
||||
int l = strlen(dbn);
|
||||
int digit_last = isdigit(dbn[l-1]);
|
||||
|
||||
mvprintw(y, NAME_START,
|
||||
"%s%d", my_basename(disk_device), p_info[i].num+1);
|
||||
"%s%s%d", dbn, (digit_last ? "p" : ""),
|
||||
p_info[i].num+1);
|
||||
if (p_info[i].flags) {
|
||||
if (p_info[i].flags == ACTIVE_FLAG)
|
||||
mvaddstr(y, FLAGS_START, _("Boot"));
|
||||
|
|
|
@ -6,3 +6,4 @@ struct systypes {
|
|||
};
|
||||
|
||||
extern struct systypes i386_sys_types[];
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ fdisk \- Partition table manipulator for Linux
|
|||
.SH SYNOPSIS
|
||||
.BI "fdisk [\-u] " device
|
||||
.sp
|
||||
.BI "fdisk \-l [\-u] " "device ..."
|
||||
.BI "fdisk \-l [\-u] [" "device ..." ]
|
||||
.sp
|
||||
.BI "fdisk \-s " "partition ..."
|
||||
.sp
|
||||
|
@ -175,11 +175,10 @@ Print version number of
|
|||
program and exit.
|
||||
.TP
|
||||
.B \-l
|
||||
List the partition tables for
|
||||
.BR /dev/hd[a-d] ,
|
||||
.BR /dev/sd[a-h] ,
|
||||
.BR /dev/ed[a-d] ,
|
||||
and then exit.
|
||||
List the partition tables for the specified devices and then exit.
|
||||
If no devices are given, those mentioned in
|
||||
.I /proc/partitions
|
||||
(if that exists) are used.
|
||||
.TP
|
||||
.B \-u
|
||||
When listing partition tables, give sizes in sectors instead
|
||||
|
|
|
@ -94,7 +94,6 @@
|
|||
#include <setjmp.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <locale.h>
|
||||
#include "nls.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
@ -110,7 +109,6 @@
|
|||
#include "fdisksgilabel.h"
|
||||
#include "fdiskaixlabel.h"
|
||||
|
||||
#include "../version.h"
|
||||
#include "../defines.h"
|
||||
#ifdef HAVE_blkpg_h
|
||||
#include <linux/blkpg.h>
|
||||
|
@ -264,13 +262,6 @@ void fatal(enum failure why)
|
|||
" or: fdisk /dev/rd/c0d0 or: fdisk /dev/ida/c0d0 (for RAID devices)\n"
|
||||
" ...\n");
|
||||
break;
|
||||
case no_device:
|
||||
message = _("A disk block device is needed.\n");
|
||||
break;
|
||||
case no_partition:
|
||||
message =_("Given name does not refer to a partition,\n"
|
||||
"or maybe not even to a block device.\n");
|
||||
break;
|
||||
case unable_to_open:
|
||||
sprintf(error, _("Unable to open %s\n"), disk_device);
|
||||
break;
|
||||
|
@ -805,7 +796,7 @@ read_hex(struct systypes *sys)
|
|||
}
|
||||
|
||||
/*
|
||||
* Print the message MESG, then read an integer between LOW and HIGH.
|
||||
* Print the message MESG, then read an integer between LOW and HIGH (inclusive).
|
||||
* If the user hits Enter, DFLT is returned.
|
||||
* Answers like +10 are interpreted as offsets from BASE.
|
||||
*
|
||||
|
@ -1246,7 +1237,7 @@ void x_list_table(int extend)
|
|||
printf(_("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID\n"));
|
||||
for (i = 0 ; i < partitions; i++)
|
||||
if ((p = q[i]) != NULL) {
|
||||
printf("%2d %02x%4d%4d%5d%4d%4d%5d%8d%8d %02x\n",
|
||||
printf("%2d %02x%4d%4d%5d%4d%4d%5d%9d%9d %02x\n",
|
||||
i + 1, p->boot_ind, p->head,
|
||||
sector(p->sector),
|
||||
cylinder(p->sector, p->cyl), p->end_head,
|
||||
|
@ -1370,7 +1361,7 @@ void verify(void)
|
|||
|
||||
void add_partition(int n, int sys)
|
||||
{
|
||||
char mesg[48];
|
||||
char mesg[256]; /* 48 does not suffice in Japanese */
|
||||
int i, read = 0;
|
||||
struct partition *p = part_table[n], *q = part_table[ext_index];
|
||||
uint start, stop = 0, limit, temp,
|
||||
|
@ -1563,7 +1554,7 @@ void new_partition(void)
|
|||
|
||||
void write_table(void)
|
||||
{
|
||||
int i, error = 0;
|
||||
int i;
|
||||
|
||||
changed[3] = changed[0] || changed[1] || changed[2] || changed[3];
|
||||
if (!sun_label && !sgi_label) {
|
||||
|
@ -1588,6 +1579,13 @@ void write_table(void)
|
|||
}
|
||||
|
||||
printf(_("The partition table has been altered!\n\n"));
|
||||
reread_partition_table(1);
|
||||
}
|
||||
|
||||
void
|
||||
reread_partition_table(int leave) {
|
||||
int error = 0;
|
||||
int i;
|
||||
|
||||
printf(_("Calling ioctl() to re-read partition table.\n"));
|
||||
sync();
|
||||
|
@ -1604,12 +1602,6 @@ void write_table(void)
|
|||
error = errno;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
||||
printf(_("Syncing disks.\n"));
|
||||
sync();
|
||||
sleep(4); /* for sync() */
|
||||
|
||||
if (i < 0)
|
||||
printf(_("Re-read table failed with error %d: %s.\nReboot your "
|
||||
"system to ensure the partition table is updated.\n"),
|
||||
|
@ -1621,7 +1613,14 @@ void write_table(void)
|
|||
"partitions, please see the fdisk manual page for additional\n"
|
||||
"information.\n"));
|
||||
|
||||
exit(0);
|
||||
if (leave) {
|
||||
close(fd);
|
||||
|
||||
printf(_("Syncing disks.\n"));
|
||||
sync();
|
||||
sleep(4); /* for sync() */
|
||||
exit(!!i);
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_PER_LINE 16
|
||||
|
@ -1693,7 +1692,7 @@ void xselect(void)
|
|||
move_begin(get_partition(0, partitions));
|
||||
break;
|
||||
case 'c':
|
||||
cylinders = read_int(1, cylinders, 65535,
|
||||
cylinders = read_int(1, cylinders, 131071,
|
||||
0, _("Number of cylinders"));
|
||||
if (sun_label)
|
||||
sun_set_ncyl(cylinders);
|
||||
|
@ -1826,6 +1825,32 @@ void try(char *device, int user_specified)
|
|||
}
|
||||
}
|
||||
|
||||
/* for fdisk -l: try all things in /proc/partitions
|
||||
that look like a partition name (do not end in a digit) */
|
||||
void
|
||||
tryprocpt() {
|
||||
FILE *procpt;
|
||||
char line[100], ptname[100], devname[120], *s;
|
||||
int ma, mi, sz;
|
||||
|
||||
procpt = fopen(PROC_PARTITIONS, "r");
|
||||
if (procpt == NULL) {
|
||||
fprintf(stderr, _("cannot open %s\n"), PROC_PARTITIONS);
|
||||
return;
|
||||
}
|
||||
|
||||
while (fgets(line, sizeof(line), procpt)) {
|
||||
if (sscanf (line, " %d %d %d %[^\n]\n",
|
||||
&ma, &mi, &sz, ptname) != 4)
|
||||
continue;
|
||||
for(s = ptname; *s; s++);
|
||||
if (isdigit(s[-1]))
|
||||
continue;
|
||||
sprintf(devname, "/dev/%s", ptname);
|
||||
try(devname, 1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
dir_exists(char *dirname) {
|
||||
struct stat statbuf;
|
||||
|
@ -1837,8 +1862,7 @@ void
|
|||
dummy(int *kk) {}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
main(int argc, char **argv) {
|
||||
int j, c;
|
||||
int optl = 0, opts = 0;
|
||||
int user_set_sector_size = 0;
|
||||
|
@ -1892,7 +1916,6 @@ main(int argc, char **argv)
|
|||
#endif
|
||||
|
||||
if (optl) {
|
||||
listing = 1;
|
||||
nowarn = 1;
|
||||
type_open = O_RDONLY;
|
||||
if (argc > optind) {
|
||||
|
@ -1900,11 +1923,13 @@ main(int argc, char **argv)
|
|||
/* avoid gcc warning:
|
||||
variable `k' might be clobbered by `longjmp' */
|
||||
dummy(&k);
|
||||
listing = 1;
|
||||
for(k=optind; k<argc; k++)
|
||||
try(argv[k], 1);
|
||||
} else {
|
||||
/* we no longer have default device names */
|
||||
fatal(usage2);
|
||||
/* but, we can use /proc/partitions instead */
|
||||
tryprocpt();
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ struct partition {
|
|||
|
||||
enum failure {usage, usage2, ioctl_error,
|
||||
unable_to_open, unable_to_read, unable_to_seek,
|
||||
unable_to_write, out_of_memory, no_partition, no_device};
|
||||
unable_to_write, out_of_memory};
|
||||
|
||||
enum action {fdisk, require, try_only, create_empty};
|
||||
|
||||
|
@ -68,6 +68,7 @@ extern void list_types(struct systypes *sys);
|
|||
extern int read_line (void);
|
||||
extern char read_char(char *mesg);
|
||||
extern int read_hex(struct systypes *sys);
|
||||
extern void reread_partition_table(int leave);
|
||||
uint read_int(uint low, uint dflt, uint high, uint base, char *mesg);
|
||||
|
||||
#define PLURAL 0
|
||||
|
@ -83,3 +84,5 @@ extern int btrydev (char * dev);
|
|||
|
||||
/* prototypes for fdisksgilabel.c */
|
||||
extern int valid_part_table_flag(unsigned char *b);
|
||||
|
||||
#define PROC_PARTITIONS "/proc/partitions"
|
||||
|
|
|
@ -75,7 +75,7 @@ static int xbsd_initlabel (struct partition *p, struct xbsd_disklabel *d, int p
|
|||
static int xbsd_readlabel (struct partition *p, struct xbsd_disklabel *d);
|
||||
static int xbsd_writelabel (struct partition *p, struct xbsd_disklabel *d);
|
||||
static void sync_disks (void);
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
static int xbsd_translate_fstype (int linux_type);
|
||||
static void xbsd_link_part (void);
|
||||
#endif
|
||||
|
@ -85,7 +85,7 @@ void alpha_bootblock_checksum (char *boot);
|
|||
|
||||
static struct xbsd_disklabel xbsd_dlabel;
|
||||
static char buffer[BSD_BBSIZE];
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
static struct partition *xbsd_part;
|
||||
static int xbsd_part_index;
|
||||
#endif
|
||||
|
@ -111,13 +111,13 @@ bmenu (void)
|
|||
puts (_(" n add a new BSD partition"));
|
||||
puts (_(" p print BSD partition table"));
|
||||
puts (_(" q quit without saving changes"));
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
puts (_(" r return to main menu"));
|
||||
#endif
|
||||
puts (_(" s show complete disklabel"));
|
||||
puts (_(" t change a partition's filesystem id"));
|
||||
puts (_(" w write disklabel to disk"));
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
puts (_(" x link BSD partition to non-BSD partition"));
|
||||
#endif
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ is_netbsd_partition_type(int type) {
|
|||
|
||||
void
|
||||
bselect (void) {
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
int t, ss;
|
||||
|
||||
for (t=0; t<4; t++)
|
||||
|
@ -203,7 +203,7 @@ bselect (void) {
|
|||
case 'w':
|
||||
xbsd_write_disklabel ();
|
||||
break;
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
case 'r':
|
||||
return;
|
||||
case 'x':
|
||||
|
@ -235,33 +235,35 @@ static void
|
|||
xbsd_new_part (void)
|
||||
{
|
||||
uint begin, end;
|
||||
char mesg[48];
|
||||
char mesg[256];
|
||||
int i;
|
||||
|
||||
if (!xbsd_check_new_partition (&i))
|
||||
return;
|
||||
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
begin = get_start_sect(xbsd_part);
|
||||
end = begin + get_nr_sects(xbsd_part) - 1;
|
||||
#elif defined (__alpha__) || defined (__powerpc__)
|
||||
begin = 0;
|
||||
end = xbsd_dlabel.d_secperunit;
|
||||
end = xbsd_dlabel.d_secperunit - 1;
|
||||
#endif
|
||||
|
||||
sprintf (mesg, _("First %s"), str_units(SINGULAR));
|
||||
begin = read_int (cround (begin), cround (begin), cround (end),
|
||||
0, mesg);
|
||||
|
||||
sprintf (mesg, _("Last %s or +size or +sizeM or +sizeK"), str_units(SINGULAR));
|
||||
if (display_in_cyl_units)
|
||||
begin = (begin - 1) * units_per_sector;
|
||||
|
||||
sprintf (mesg, _("Last %s or +size or +sizeM or +sizeK"),
|
||||
str_units(SINGULAR));
|
||||
end = read_int (cround (begin), cround (end), cround (end),
|
||||
cround (begin), mesg);
|
||||
|
||||
if (display_in_cyl_units)
|
||||
{
|
||||
begin = (begin - 1) * units_per_sector;
|
||||
end = end * units_per_sector - 1;
|
||||
}
|
||||
|
||||
xbsd_dlabel.d_partitions[i].p_size = end - begin + 1;
|
||||
xbsd_dlabel.d_partitions[i].p_offset = begin;
|
||||
xbsd_dlabel.d_partitions[i].p_fstype = BSD_FS_UNUSED;
|
||||
|
@ -277,7 +279,7 @@ xbsd_print_disklabel (int show_all)
|
|||
|
||||
if (show_all)
|
||||
{
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
fprintf(f, "# %s%d:\n", disk_device, xbsd_part_index+1);
|
||||
#elif defined (__alpha__)
|
||||
fprintf(f, "# %s:\n", disk_device);
|
||||
|
@ -374,13 +376,14 @@ xbsd_print_disklabel (int show_all)
|
|||
static void
|
||||
xbsd_write_disklabel (void)
|
||||
{
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
printf (_("Writing disklabel to %s%d.\n"), disk_device, xbsd_part_index+1);
|
||||
xbsd_writelabel (xbsd_part, &xbsd_dlabel);
|
||||
#elif defined (__alpha__)
|
||||
printf (_("Writing disklabel to %s.\n"), disk_device);
|
||||
xbsd_writelabel (NULL, &xbsd_dlabel);
|
||||
#endif
|
||||
reread_partition_table(0); /* no exit yet */
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -388,7 +391,7 @@ xbsd_create_disklabel (void)
|
|||
{
|
||||
char c;
|
||||
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
fprintf (stderr, _("%s%d contains no disklabel.\n"),
|
||||
disk_device, xbsd_part_index+1);
|
||||
#elif defined (__alpha__)
|
||||
|
@ -398,7 +401,7 @@ xbsd_create_disklabel (void)
|
|||
while (1)
|
||||
if ((c = tolower (read_char (_("Do you want to create a disklabel? (y/n) ")))) == 'y')
|
||||
{
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
if (xbsd_initlabel (xbsd_part, &xbsd_dlabel, xbsd_part_index) == 1)
|
||||
#elif defined (__alpha__) || defined (__powerpc__)
|
||||
if (xbsd_initlabel (NULL, &xbsd_dlabel, 0) == 1)
|
||||
|
@ -529,7 +532,7 @@ xbsd_write_bootstrap (void)
|
|||
|
||||
bcopy (&dl, d, sizeof (struct xbsd_disklabel));
|
||||
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
sector = get_start_sect(xbsd_part);
|
||||
#elif defined (__powerpc__)
|
||||
sector = 0;
|
||||
|
@ -543,7 +546,7 @@ xbsd_write_bootstrap (void)
|
|||
if (BSD_BBSIZE != write (fd, buffer, BSD_BBSIZE))
|
||||
fatal (unable_to_write);
|
||||
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
printf (_("Bootstrap installed on %s%d.\n"), disk_device, xbsd_part_index+1);
|
||||
#elif defined (__alpha__)
|
||||
printf (_("Bootstrap installed on %s.\n"), disk_device);
|
||||
|
@ -564,7 +567,7 @@ xbsd_change_fstype (void)
|
|||
static int
|
||||
xbsd_get_part_index (int max)
|
||||
{
|
||||
char prompt[40];
|
||||
char prompt[256];
|
||||
char l;
|
||||
|
||||
sprintf (prompt, _("Partition (a-%c): "), 'a' + max - 1);
|
||||
|
@ -647,7 +650,7 @@ xbsd_initlabel (struct partition *p, struct xbsd_disklabel *d, int pindex)
|
|||
d -> d_subtype = BSD_DSTYPE_INDOSPART & pindex;
|
||||
#endif
|
||||
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
d -> d_flags = BSD_D_DOSPART;
|
||||
#else
|
||||
d -> d_flags = 0;
|
||||
|
@ -670,7 +673,7 @@ xbsd_initlabel (struct partition *p, struct xbsd_disklabel *d, int pindex)
|
|||
d -> d_bbsize = BSD_BBSIZE;
|
||||
d -> d_sbsize = BSD_SBSIZE;
|
||||
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
d -> d_npartitions = 4;
|
||||
pp = &d -> d_partitions[2]; /* Partition C should be the NetBSD partition */
|
||||
pp -> p_offset = get_start_sect(p);
|
||||
|
@ -696,7 +699,7 @@ xbsd_readlabel (struct partition *p, struct xbsd_disklabel *d)
|
|||
{
|
||||
int t, sector;
|
||||
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
sector = (p ? get_start_sect(p) : 0);
|
||||
#elif defined (__alpha__)
|
||||
sector = 0;
|
||||
|
@ -730,7 +733,7 @@ xbsd_writelabel (struct partition *p, struct xbsd_disklabel *d)
|
|||
{
|
||||
int sector;
|
||||
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
sector = get_start_sect(p) + BSD_LABELSECTOR;
|
||||
#elif defined (__alpha__) || defined (__powerpc__)
|
||||
sector = BSD_LABELSECTOR;
|
||||
|
@ -771,7 +774,7 @@ sync_disks (void)
|
|||
sleep (4);
|
||||
}
|
||||
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
static int
|
||||
xbsd_translate_fstype (int linux_type)
|
||||
{
|
||||
|
@ -810,7 +813,7 @@ xbsd_link_part (void)
|
|||
|
||||
#if defined (__alpha__)
|
||||
|
||||
#if 0
|
||||
#if !defined(__GLIBC__)
|
||||
typedef unsigned long long u_int64_t;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
#define BSD_LINUX_BOOTDIR "/usr/ucb/mdec"
|
||||
|
||||
#if defined (i386) || defined (sparc)
|
||||
#if defined (i386) || defined (__sparc__) || defined (__arm__)
|
||||
#define BSD_LABELSECTOR 1
|
||||
#define BSD_LABELOFFSET 0
|
||||
#elif defined (__alpha__) || defined (__powerpc__)
|
||||
|
|
|
@ -671,7 +671,7 @@ sgi_delete_partition( int i )
|
|||
void
|
||||
sgi_add_partition( int n, int sys )
|
||||
{
|
||||
char mesg[48];
|
||||
char mesg[256];
|
||||
int first=0, last=0;
|
||||
|
||||
if( n == 10 ) {
|
||||
|
|
|
@ -472,7 +472,7 @@ void add_sun_partition(int n, int sys)
|
|||
uint starts[8], lens[8];
|
||||
int whole_disk = 0;
|
||||
|
||||
char mesg[48];
|
||||
char mesg[256];
|
||||
int i, first, last;
|
||||
|
||||
if (sunlabel->partitions[n].num_sectors && sunlabel->infos[n].id) {
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#define PROGNAME "sfdisk"
|
||||
#define VERSION "3.07"
|
||||
#define DATE "980518"
|
||||
#define DATE "990908"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> /* atoi, free */
|
||||
|
@ -48,7 +48,6 @@
|
|||
#include <linux/unistd.h> /* _syscall */
|
||||
#include <linux/hdreg.h> /* HDIO_GETGEO */
|
||||
#include <linux/fs.h> /* BLKGETSIZE */
|
||||
#include <locale.h>
|
||||
#include "nls.h"
|
||||
#include "common.h"
|
||||
|
||||
|
@ -829,7 +828,7 @@ void
|
|||
out_partition_header(char *dev, int format, struct geometry G) {
|
||||
if (dump) {
|
||||
printf(_("# partition table of %s\n"), dev);
|
||||
printf(_("unit: sectors\n\n"));
|
||||
printf("unit: sectors\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -929,12 +928,12 @@ out_partition(char *dev, int format, struct part_desc *p,
|
|||
size = p->size;
|
||||
|
||||
if (dump) {
|
||||
printf(_(" start=%9lu"), start);
|
||||
printf(_(", size=%8lu"), size);
|
||||
printf(" start=%9lu", start);
|
||||
printf(", size=%8lu", size);
|
||||
if (p->ptype == DOS_TYPE) {
|
||||
printf(_(", Id=%2x"), p->p.sys_type);
|
||||
printf(", Id=%2x", p->p.sys_type);
|
||||
if (p->p.bootable == 0x80)
|
||||
printf(_(", bootable"));
|
||||
printf(", bootable");
|
||||
}
|
||||
printf("\n");
|
||||
return;
|
||||
|
@ -1012,16 +1011,24 @@ out_partition(char *dev, int format, struct part_desc *p,
|
|||
|
||||
void
|
||||
out_partitions(char *dev, struct disk_desc *z) {
|
||||
struct part_desc *p;
|
||||
int pno, format = 0;
|
||||
|
||||
if (z->partno == 0)
|
||||
printf(_("No partitions found\n"));
|
||||
else {
|
||||
if (get_fdisk_geometry(&(z->partitions[0])))
|
||||
printf(_("Warning: The first partition looks like it was made\n"
|
||||
for (pno=0; pno < z->partno; pno++) {
|
||||
p = &(z->partitions[pno]);
|
||||
if (p->size != 0 && p->p.sys_type != 0) {
|
||||
if (get_fdisk_geometry(p))
|
||||
printf(
|
||||
_("Warning: The first partition looks like it was made\n"
|
||||
" for C/H/S=*/%ld/%ld (instead of %ld/%ld/%ld).\n"
|
||||
"For this listing I'll assume that geometry.\n"),
|
||||
F.heads, F.sectors, B.cylinders, B.heads, B.sectors);
|
||||
break;
|
||||
}
|
||||
}
|
||||
out_partition_header(dev, format, F);
|
||||
for(pno=0; pno < z->partno; pno++) {
|
||||
out_partition(dev, format, &(z->partitions[pno]), z, F);
|
||||
|
|
|
@ -20,6 +20,7 @@ all: $(USRGAMES)
|
|||
|
||||
# Rules for everything else
|
||||
|
||||
banner.o: $(LIB)/errs.h
|
||||
banner: banner.o $(ERR_O)
|
||||
ddate: ddate.o
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
* banner [-w#] [-d] [-t] message ...
|
||||
*/
|
||||
|
||||
#include "err.h"
|
||||
#include "errs.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -47,6 +47,9 @@ milliseconds.
|
|||
For Intel-based systems, the allowable range is from 250 to 1000 ms,
|
||||
in 250 ms steps. For SPARC systems, possible values are between 10 ms and 1440 ms,
|
||||
in 10 ms steps.
|
||||
.TP
|
||||
.B \-V
|
||||
Display a version number and exit.
|
||||
.SH BUGS
|
||||
Not all keyboards support all rates.
|
||||
.PP
|
||||
|
|
|
@ -85,7 +85,6 @@ beats rebuilding the kernel!
|
|||
#endif
|
||||
|
||||
#include "nls.h"
|
||||
#include "../version.h"
|
||||
|
||||
static int valid_rates[] = { 300, 267, 240, 218, 200, 185, 171, 160, 150,
|
||||
133, 120, 109, 100, 92, 86, 80, 75, 67,
|
||||
|
@ -202,7 +201,7 @@ int main( int argc, char **argv )
|
|||
textdomain(PACKAGE);
|
||||
|
||||
|
||||
while ( (c = getopt( argc, argv, "r:d:sv" )) != EOF ) {
|
||||
while ( (c = getopt( argc, argv, "r:d:svVh?" )) != EOF ) {
|
||||
switch (c) {
|
||||
case 'r':
|
||||
rate = atof( optarg );
|
||||
|
@ -214,8 +213,14 @@ int main( int argc, char **argv )
|
|||
silent = 1;
|
||||
break;
|
||||
case 'v':
|
||||
case 'V':
|
||||
fprintf( stderr, "util-linux %s kbdrate\n", UTIL_LINUX_VERSION);
|
||||
exit(0);
|
||||
case 'h':
|
||||
case '?':
|
||||
fprintf( stderr,
|
||||
_("Usage: kbdrate [-V] [-s] [-r rate] [-d delay]\n"));
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
18
lib/README.widechar
Normal file
18
lib/README.widechar
Normal file
|
@ -0,0 +1,18 @@
|
|||
From haible@ilog.fr Mon Sep 20 15:34:21 1999
|
||||
|
||||
Hello Andries,
|
||||
|
||||
Here is a patch for adding multi-byte locale support to a few programs
|
||||
found in util-linux-2.9u. With these patches, the programs
|
||||
|
||||
col colcrt colrm column rev ul
|
||||
|
||||
now work correctly in UTF-8 locales. This is done by using the ISO C / SUSV2
|
||||
i18n functions, therefore they will become effective when glibc-2.2 comes
|
||||
out. For the moment, you can test the patches by
|
||||
1. defining ENABLE_WIDECHAR in defines.h
|
||||
2. Change the #if 0 to #if 1 in lib/widechar.h
|
||||
3. Modify your CFLAGS and LDFLAGS to include the directories where libutf8
|
||||
is installed.
|
||||
|
||||
|
112
lib/err.c
112
lib/err.c
|
@ -31,17 +31,13 @@
|
|||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include "errs.h"
|
||||
|
||||
|
||||
#include "../defines.h"
|
||||
#ifdef HAVE_progname
|
||||
|
@ -50,101 +46,63 @@ extern char *__progname; /* Program name, from crt0. */
|
|||
char *__progname = "foo"; /* probably libc4 */
|
||||
#endif
|
||||
|
||||
__dead void
|
||||
#ifdef __STDC__
|
||||
err(int eval, const char *fmt, ...)
|
||||
#else
|
||||
err(eval, fmt, va_alist)
|
||||
int eval;
|
||||
const char *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
/* Some compilers complain "null format string" upon err(1,NULL) */
|
||||
/* Make them happy with a separate routine. */
|
||||
void
|
||||
err_nomsg(int exitval) {
|
||||
(void)fprintf(stderr, "%s: %s\n", __progname, strerror(errno));
|
||||
exit(exitval);
|
||||
}
|
||||
|
||||
void
|
||||
err(int exitval, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
#if __STDC__
|
||||
va_start(ap, fmt);
|
||||
#else
|
||||
va_start(ap);
|
||||
#endif
|
||||
verr(eval, fmt, ap);
|
||||
verr(exitval, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
__dead void
|
||||
verr(eval, fmt, ap)
|
||||
int eval;
|
||||
const char *fmt;
|
||||
va_list ap;
|
||||
{
|
||||
void
|
||||
verr(int exitval, const char *fmt, va_list ap) {
|
||||
int sverrno;
|
||||
|
||||
sverrno = errno;
|
||||
(void)fprintf(stderr, "%s: ", __progname);
|
||||
if (fmt != NULL) {
|
||||
if (fmt != NULL && *fmt != 0) {
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
(void)fprintf(stderr, ": ");
|
||||
}
|
||||
(void)fprintf(stderr, "%s\n", strerror(sverrno));
|
||||
exit(eval);
|
||||
exit(exitval);
|
||||
}
|
||||
|
||||
__dead void
|
||||
#if __STDC__
|
||||
errx(int eval, const char *fmt, ...)
|
||||
#else
|
||||
errx(eval, fmt, va_alist)
|
||||
int eval;
|
||||
const char *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
void
|
||||
errx(int exitval, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
#if __STDC__
|
||||
va_start(ap, fmt);
|
||||
#else
|
||||
va_start(ap);
|
||||
#endif
|
||||
verrx(eval, fmt, ap);
|
||||
verrx(exitval, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
__dead void
|
||||
verrx(eval, fmt, ap)
|
||||
int eval;
|
||||
const char *fmt;
|
||||
va_list ap;
|
||||
{
|
||||
void
|
||||
verrx(int exitval, const char *fmt, va_list ap) {
|
||||
(void)fprintf(stderr, "%s: ", __progname);
|
||||
if (fmt != NULL)
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
(void)fprintf(stderr, "\n");
|
||||
exit(eval);
|
||||
exit(exitval);
|
||||
}
|
||||
|
||||
void
|
||||
#if __STDC__
|
||||
warn(const char *fmt, ...)
|
||||
#else
|
||||
warn(fmt, va_alist)
|
||||
const char *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
warn(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
#if __STDC__
|
||||
va_start(ap, fmt);
|
||||
#else
|
||||
va_start(ap);
|
||||
#endif
|
||||
vwarn(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
vwarn(fmt, ap)
|
||||
const char *fmt;
|
||||
va_list ap;
|
||||
{
|
||||
vwarn(const char *fmt, va_list ap) {
|
||||
int sverrno;
|
||||
|
||||
sverrno = errno;
|
||||
|
@ -157,29 +115,15 @@ vwarn(fmt, ap)
|
|||
}
|
||||
|
||||
void
|
||||
#ifdef __STDC__
|
||||
warnx(const char *fmt, ...)
|
||||
#else
|
||||
warnx(fmt, va_alist)
|
||||
const char *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
warnx(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
#ifdef __STDC__
|
||||
va_start(ap, fmt);
|
||||
#else
|
||||
va_start(ap);
|
||||
#endif
|
||||
vwarnx(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
vwarnx(fmt, ap)
|
||||
const char *fmt;
|
||||
va_list ap;
|
||||
{
|
||||
vwarnx(const char *fmt, va_list ap) {
|
||||
(void)fprintf(stderr, "%s: ", __progname);
|
||||
if (fmt != NULL)
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
|
|
70
lib/err.h
70
lib/err.h
|
@ -1,70 +0,0 @@
|
|||
/*-
|
||||
* Copyright (c) 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)err.h 8.1 (Berkeley) 6/2/93
|
||||
*/
|
||||
|
||||
#ifndef _ERR_H_
|
||||
#define _ERR_H_
|
||||
|
||||
#ifdef __linux__
|
||||
#include <stdarg.h>
|
||||
#define _BSD_VA_LIST_ va_list
|
||||
#define __dead /* */
|
||||
#else
|
||||
/*
|
||||
* Don't use va_list in the err/warn prototypes. Va_list is typedef'd in two
|
||||
* places (<machine/varargs.h> and <machine/stdarg.h>), so if we include one
|
||||
* of them here we may collide with the utility's includes. It's unreasonable
|
||||
* for utilities to have to include one of them to include err.h, so we get
|
||||
* _BSD_VA_LIST_ from <machine/ansi.h> and use it.
|
||||
*/
|
||||
#include <machine/ansi.h>
|
||||
#endif
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
__dead void err __P((int, const char *, ...));
|
||||
__dead void verr __P((int, const char *, _BSD_VA_LIST_));
|
||||
__dead void errx __P((int, const char *, ...));
|
||||
__dead void verrx __P((int, const char *, _BSD_VA_LIST_));
|
||||
void warn __P((const char *, ...));
|
||||
void vwarn __P((const char *, _BSD_VA_LIST_));
|
||||
void warnx __P((const char *, ...));
|
||||
void vwarnx __P((const char *, _BSD_VA_LIST_));
|
||||
__END_DECLS
|
||||
|
||||
#ifdef __linux__
|
||||
#undef _BSD_VA_LIST_
|
||||
#endif
|
||||
|
||||
#endif /* !_ERR_H_ */
|
16
lib/errs.h
Normal file
16
lib/errs.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef _ERR_H_
|
||||
#define _ERR_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
void err_nomsg (int);
|
||||
void err (int, const char *, ...);
|
||||
void verr (int, const char *, va_list);
|
||||
void errx (int, const char *, ...);
|
||||
void verrx (int, const char *, va_list);
|
||||
void warn (const char *, ...);
|
||||
void vwarn (const char *, va_list);
|
||||
void warnx (const char *, ...);
|
||||
void vwarnx (const char *, va_list);
|
||||
|
||||
#endif /* !_ERR_H_ */
|
|
@ -1,43 +1,78 @@
|
|||
/*
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by the University of California, Berkeley. The name of the
|
||||
* University may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Vaguely based on
|
||||
* @(#)pathnames.h 5.3 (Berkeley) 5/9/89
|
||||
*
|
||||
* Changed: Sun Nov 21 12:30:54 1993 by faith@cs.unc.edu
|
||||
* Changed: Wed Jun 22 20:47:27 1994 by faith@cs.unc.edu, based on changes
|
||||
* from poe@daimi.aau.dk
|
||||
* Changed: Wed Jun 22 22:50:13 1994 by faith@cs.unc.edu
|
||||
* Changed: Sat Feb 4 16:02:10 1995 by faith@cs.unc.edu
|
||||
* Changed: Tue Jul 2 09:37:36 1996 by janl@math.uio.no, axp patches
|
||||
* Changed: Thu Nov 9 21:58:36 1995 by joey@infodrom.north.de
|
||||
* This code is in the public domain.
|
||||
*/
|
||||
#include <paths.h>
|
||||
|
||||
#ifndef __STDC__
|
||||
# error "we need an ANSI compiler"
|
||||
#endif
|
||||
|
||||
/* The paths for some of these are wrong in /usr/include/paths.h, but we
|
||||
re-define them here. */
|
||||
/* The paths for some of these are wrong in /usr/include/paths.h,
|
||||
but we re-define them here. */
|
||||
|
||||
/* Used in login.c, agetty.c, simpleinit.c, shutdown.c, write.c */
|
||||
#undef _PATH_UTMP
|
||||
/* Used in login.c, agetty.c, simpleinit.c, shutdown.c, last.c */
|
||||
#undef _PATH_WTMP
|
||||
/* These four are used in login.c only */
|
||||
#undef _PATH_DEFPATH
|
||||
#undef _PATH_DEFPATH_ROOT
|
||||
#undef _PATH_LASTLOG
|
||||
#undef _PATH_MAILDIR
|
||||
|
||||
/*
|
||||
* HISTORY
|
||||
*
|
||||
What is the history of these six, and related defines?
|
||||
------------------------------------------------------------------------
|
||||
_PATH_UTMP and UTMP_FILE and UTMP_FILENAME:
|
||||
/etc/utmp > /var/adm/utmp > /var/run/utmp.
|
||||
Traditionally we have /etc/utmp.
|
||||
In <paths.h> we have /etc/utmp, but since 4.6.0 /var/adm/utmp
|
||||
and since 5.0.9 (and in glibc2) /var/run/utmp.
|
||||
In login/pathnames.h we have /etc/utmp, but since 4.6.6 /var/adm/utmp.
|
||||
In <utmp.h> UTMP_FILE is defined as /etc/utmp, but in 4.6.* as _PATH_UTMP.
|
||||
|
||||
_PATH_WTMP and WTMP_FILE and WTMP_FILENAME:
|
||||
/etc/wtmp > /usr/adm/wtmp > /var/adm/wtmp > /var/log/wtmp.
|
||||
Traditionally we have /etc/wtmp.
|
||||
In <paths.h> we have /usr/adm/wtmp, but since 4.5.13 /var/adm/wtmp,
|
||||
and since 5.0.9 (and in glibc2) /var/log/wtmp.
|
||||
In login/pathnames.h. we have /etc/wtmp, but since 4.6.6 /var/adm/wtmp.
|
||||
In <utmp.h> WTMP_FILE is defined as /usr/adm/wtmp, but in 4.5.* as
|
||||
/var/adm/wtmp, and in 4.6.* as _PATH_WTMP.
|
||||
|
||||
_PATH_DEFPATH)
|
||||
Long ago this was ".:/bin:/usr/bin".
|
||||
In <paths.h> libc 4.4.1-4.4.4 have "/usr/bin:/bin"
|
||||
and libc 4.5.21-5.4.23 have "/usr/local/bin:/usr/bin:/bin:."
|
||||
and libc 5.4.38-5.4.46 have "/usr/local/bin:/usr/bin:/bin".
|
||||
In login/pathnames.h libc4 and libc5 have "/usr/local/bin:/bin:/usr/bin:."
|
||||
|
||||
_PATH_DEFPATH_ROOT)
|
||||
Long ago this was identical to _PATH_DEFPATH.
|
||||
In <paths.h> no definition is present before libc 4.5.13.
|
||||
Libc 4.5.13 has "/bin:/usr/bin:/etc"
|
||||
Libc 4.5.14-5.4.46 have "/sbin:/bin:/usr/sbin:/usr/bin"
|
||||
In login/pathnames.h libc4 and libc5 have "/bin:/usr/bin:/etc"
|
||||
|
||||
_PATH_LASTLOG)
|
||||
/etc/lastlog > /usr/adm/lastlog > /var/adm/lastlog > /var/log/lastlog.
|
||||
Traditionally we have /etc/lastlog.
|
||||
In <bsd/utmp.h> libc 4.4.1-4.5.12 have /usr/adm/lastlog, 4.5.13 and
|
||||
later have /var/adm/lastlog.
|
||||
In paths.h all libc5 and glibc2 versions have /var/log/lastlog.
|
||||
In login/pathnames.h all libc4 and libc5 versions have /usr/adm/lastlog.
|
||||
|
||||
_PATH_MAILDIR)
|
||||
/usr/spool/mail > /var/spool/mail > /var/mail.
|
||||
Traditionally we have /usr/spool/mail.
|
||||
In <paths.h> we have /usr/spool/mail, but since libc 4.5.13 /var/spool/mail.
|
||||
In login/pathnames.h all libc4 versions have /var/spool/mail.
|
||||
Libc5 and glibc 2.0-2.1 have /var/spool/mail, but glibc 2.1.1 has /var/mail.
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef SBINDIR
|
||||
#define SBINDIR "/sbin"
|
||||
|
@ -73,7 +108,10 @@
|
|||
#define _PATH_DEFPATH_ROOT SBINDIR ":/bin:" USRSBINDIR ":/usr/bin"
|
||||
#define _PATH_HUSHLOGIN ".hushlogin"
|
||||
#define _PATH_LASTLOG LOGDIR "/lastlog"
|
||||
|
||||
#ifndef _PATH_MAILDIR
|
||||
#define _PATH_MAILDIR VARPATH "/spool/mail"
|
||||
#endif
|
||||
#define _PATH_MOTDFILE "/etc/motd"
|
||||
#define _PATH_NOLOGIN "/etc/nologin"
|
||||
|
||||
|
@ -87,18 +125,22 @@
|
|||
#define _PATH_SECURE "/etc/securesingle"
|
||||
#define _PATH_USERTTY "/etc/usertty"
|
||||
|
||||
/* used in login-utils/shutdown.c */
|
||||
#define _PATH_MTAB "/etc/mtab"
|
||||
#define _PATH_UMOUNT "/bin/umount"
|
||||
#define UMOUNT_ARGS "umount", "-a"
|
||||
#define SWAPOFF_ARGS "swapoff", "-a"
|
||||
|
||||
/* used in login-utils/setpwnam.h and login-utils/islocal.c */
|
||||
#define _PATH_PASSWD "/etc/passwd"
|
||||
|
||||
/* used in login-utils/setpwnam.h */
|
||||
#define _PATH_PTMP "/etc/ptmp"
|
||||
#define _PATH_PTMPTMP "/etc/ptmptmp"
|
||||
|
||||
#define _PATH_GROUP "/etc/group"
|
||||
#define _PATH_GTMP "/etc/gtmp"
|
||||
#define _PATH_GTMPTMP "/etc/gtmptmp"
|
||||
|
||||
/* used in misc-utils/look.c */
|
||||
#define _PATH_WORDS "/usr/dict/words"
|
||||
#define _PATH_WORDS_ALT "/usr/dict/web2"
|
||||
|
|
41
lib/widechar.h
Normal file
41
lib/widechar.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/* Declarations for wide characters */
|
||||
/* This file must be included last because the redefinition of wchar_t may
|
||||
cause conflicts when system include files were included after it. */
|
||||
|
||||
#include "../defines.h" /* for ENABLE_WIDECHAR */
|
||||
|
||||
#ifdef ENABLE_WIDECHAR
|
||||
|
||||
# include <wchar.h>
|
||||
# include <wctype.h>
|
||||
#if 0 /* for testing on platforms without built-in wide character support */
|
||||
# include <libutf8.h>
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
# include <ctype.h>
|
||||
/* Fallback for types */
|
||||
# define wchar_t char
|
||||
# define wint_t int
|
||||
# define WEOF EOF
|
||||
/* Fallback for input operations */
|
||||
# define fgetwc fgetc
|
||||
# define getwc getc
|
||||
# define getwchar getchar
|
||||
# define fgetws fgets
|
||||
/* Fallback for output operations */
|
||||
# define fputwc fputc
|
||||
# define putwc putc
|
||||
# define putwchar putchar
|
||||
# define fputws fputs
|
||||
/* Fallback for character classification */
|
||||
# define iswgraph isgraph
|
||||
# define iswprint isprint
|
||||
# define iswspace isspace
|
||||
/* Fallback for string functions */
|
||||
# define wcschr strchr
|
||||
# define wcsdup strdup
|
||||
# define wcslen strlen
|
||||
|
||||
#endif
|
|
@ -124,12 +124,12 @@ wall: wall.o ttymsg.o
|
|||
ifeq "$(USE_TTY_GROUP)" "yes"
|
||||
login.o: login.c $(LIB)/pathnames.h $(LIB)/setproctitle.c $(LIB)/setproctitle.h
|
||||
$(CC) -c $(CFLAGS) $(PAMFL) -DUSE_TTY_GROUP login.c
|
||||
mesg.o: mesg.c $(LIB)/err.h
|
||||
mesg.o: mesg.c $(LIB)/errs.h
|
||||
$(CC) -c $(CFLAGS) -DUSE_TTY_GROUP mesg.c
|
||||
else
|
||||
login.o: $(LIB)/pathnames.h
|
||||
$(CC) -c $(CFLAGS) $(PAMFL) login.c
|
||||
mesg.o: $(LIB)/err.h
|
||||
mesg.o: $(LIB)/errs.h
|
||||
endif
|
||||
|
||||
passwd: passwd.o islocal.o setpwnam.o $(LIB)/env.o
|
||||
|
|
|
@ -8,6 +8,7 @@ agetty \- alternative Linux getty
|
|||
.RI "[-l " login_program ]
|
||||
.RI "[-I " init ]
|
||||
.RI "[-t " timeout ]
|
||||
.RI "[-H " login_host ]
|
||||
.I port
|
||||
.I baud_rate,...
|
||||
.RI [ term ]
|
||||
|
@ -17,6 +18,7 @@ agetty \- alternative Linux getty
|
|||
.RI "[-l " login_program ]
|
||||
.RI "[-I " init ]
|
||||
.RI "[-t " timeout ]
|
||||
.RI "[-H " login_host ]
|
||||
.I baud_rate,...
|
||||
.I port
|
||||
.RI [ term ]
|
||||
|
@ -120,6 +122,12 @@ This allows the use of a non-standard login program (for example,
|
|||
one that asks for a dial-up password or that uses a different
|
||||
password file).
|
||||
.TP
|
||||
\-H \fIlogin_host\fP
|
||||
Write the specified \fIlogin_host\fP into the utmp file. (Normally,
|
||||
no login host is given, since \fBagetty\fP is used for local hardwired
|
||||
connections and consoles. However, this option can be useful for
|
||||
identifying terminal concentrators and the like.
|
||||
.TP
|
||||
\-m
|
||||
Try to extract the baud rate the CONNECT status message
|
||||
produced by Hayes(tm)\-compatible modems. These status
|
||||
|
|
|
@ -237,6 +237,9 @@ void error P_((int va_alist));
|
|||
|
||||
char *progname;
|
||||
|
||||
/* Fake hostname for ut_host specified on command line. */
|
||||
char *fakehost = NULL;
|
||||
|
||||
/* ... */
|
||||
#ifdef DEBUGGING
|
||||
#define debug(s) fprintf(dbf,s); fflush(dbf)
|
||||
|
@ -390,7 +393,7 @@ parse_args(argc, argv, op)
|
|||
extern int optind; /* getopt */
|
||||
int c;
|
||||
|
||||
while (isascii(c = getopt(argc, argv, "I:Lf:hil:mt:wn"))) {
|
||||
while (isascii(c = getopt(argc, argv, "I:LH:f:hil:mt:wn"))) {
|
||||
switch (c) {
|
||||
case 'I':
|
||||
if (!(op->initstring = malloc(strlen(optarg)))) {
|
||||
|
@ -435,6 +438,9 @@ parse_args(argc, argv, op)
|
|||
case 'L': /* force local */
|
||||
op->flags |= F_LOCAL;
|
||||
break;
|
||||
case 'H': /* fake login host */
|
||||
fakehost = optarg;
|
||||
break;
|
||||
case 'f': /* custom issue file */
|
||||
op->flags |= F_CUSTISSUE;
|
||||
op->issue = optarg;
|
||||
|
@ -547,6 +553,8 @@ update_utmp(line)
|
|||
|
||||
strncpy(ut.ut_user, "LOGIN", sizeof(ut.ut_user));
|
||||
strncpy(ut.ut_line, line, sizeof(ut.ut_line));
|
||||
if (fakehost)
|
||||
strncpy(ut.ut_host, fakehost, sizeof(ut.ut_host));
|
||||
time(&t);
|
||||
ut.ut_time = t;
|
||||
ut.ut_type = LOGIN_PROCESS;
|
||||
|
@ -586,6 +594,8 @@ update_utmp(line)
|
|||
ut.ut_time = time((long *) 0);
|
||||
(void) strncpy(ut.ut_name, "LOGIN", sizeof(ut.ut_name));
|
||||
(void) strncpy(ut.ut_line, line, sizeof(ut.ut_line));
|
||||
if (fakehost)
|
||||
(void) strncpy(ut.ut_host, fakehost, sizeof(ut.ut_host));
|
||||
(void) lseek(ut_fd, -ut_size, 1);
|
||||
(void) write(ut_fd, (char *) &ut, sizeof(ut));
|
||||
(void) close(ut_fd);
|
||||
|
@ -1160,7 +1170,7 @@ bcode(s)
|
|||
void
|
||||
usage()
|
||||
{
|
||||
fprintf(stderr, _("Usage: %s [-hiLmw] [-l login_program] [-t timeout] [-I initstring] baud_rate,... line [termtype]\nor\t[-hiLmw] [-l login_program] [-t timeout] [-I initstring] line baud_rate,... [termtype]\n"), progname);
|
||||
fprintf(stderr, _("Usage: %s [-hiLmw] [-l login_program] [-t timeout] [-I initstring] [-H login_host] baud_rate,... line [termtype]\nor\t[-hiLmw] [-l login_program] [-t timeout] [-I initstring] [-H login_host] line baud_rate,... [termtype]\n"), progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,9 +33,7 @@
|
|||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include <locale.h>
|
||||
#include "my_crypt.h"
|
||||
#include "../version.h"
|
||||
#include "nls.h"
|
||||
#include "env.h"
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include "my_crypt.h"
|
||||
#include "../version.h"
|
||||
#include "nls.h"
|
||||
#include "env.h"
|
||||
|
||||
|
|
|
@ -35,14 +35,14 @@ these must be met, or the log in attempt will be denied and a
|
|||
.B syslog
|
||||
message will be generated. See the section on "Special Access Restrictions".
|
||||
|
||||
If the user is root, then the login must be occuring on a tty listed in
|
||||
If the user is root, then the login must be occurring on a tty listed in
|
||||
.IR /etc/securetty .
|
||||
Failures will be logged with the
|
||||
.B syslog
|
||||
facility.
|
||||
|
||||
After these conditions are checked, the password will be requested and
|
||||
checks (if a password is required for this username). Ten attempts
|
||||
After these conditions have been checked, the password will be requested and
|
||||
checked (if a password is required for this username). Ten attempts
|
||||
are allowed before
|
||||
.B login
|
||||
dies, but after the first three, the response starts to get very slow.
|
||||
|
@ -53,8 +53,8 @@ facility. This facility is also used to report any successful root logins.
|
|||
If the file
|
||||
.I .hushlogin
|
||||
exists, then a "quiet" login is performed (this disables the checking
|
||||
of the checking of mail and the printing of the last login time and
|
||||
message of the day). Otherwise, if
|
||||
of mail and the printing of the last login time and message of the day).
|
||||
Otherwise, if
|
||||
.I /var/log/lastlog
|
||||
exists, the last login time is printed (and the current login is
|
||||
recorded).
|
||||
|
|
|
@ -162,6 +162,23 @@
|
|||
#include "setproctitle.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* RedHat writes:
|
||||
* we've got a REAL HACK to avoid telling people that they have
|
||||
* mail because the imap server has left a turd in their inbox.
|
||||
* It works, but it sucks...
|
||||
* It turns out that the turd is always 523 bytes long, so we
|
||||
* just check for that size.
|
||||
*/
|
||||
/*
|
||||
* If you want to turn this strange hack off, set
|
||||
#define REDHAT_IGNORED_MAILSIZE 0
|
||||
* In case people complain, this may become a configuration option,
|
||||
* or perhaps this hack is thrown out again.
|
||||
* A better solution would be to check the contents of this file..
|
||||
*/
|
||||
#define REDHAT_IGNORED_MAILSIZE 523
|
||||
|
||||
#if 0
|
||||
/* from before we had a lastlog.h file in linux */
|
||||
struct lastlog
|
||||
|
@ -241,12 +258,23 @@ const char *months[] =
|
|||
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
|
||||
"Sep", "Oct", "Nov", "Dec" };
|
||||
|
||||
/* provided by Linus Torvalds 16-Feb-93 */
|
||||
/* Nice and simple code provided by Linus Torvalds 16-Feb-93 */
|
||||
/* Nonblocking stuff by Maciej W. Rozycki, macro@ds2.pg.gda.pl, 1999.
|
||||
He writes: "Login performs open() on a tty in a blocking mode.
|
||||
In some cases it may make login wait in open() for carrier infinitely,
|
||||
for example if the line is a simplistic case of a three-wire serial
|
||||
connection. I believe login should open the line in the non-blocking mode
|
||||
leaving the decision to make a connection to getty (where it actually
|
||||
belongs). */
|
||||
void
|
||||
opentty(const char * tty)
|
||||
{
|
||||
int i;
|
||||
int fd = open(tty, O_RDWR);
|
||||
int fd = open(tty, O_RDWR | O_NONBLOCK);
|
||||
int flags = fcntl(fd, F_GETFL);
|
||||
|
||||
flags &= ~O_NONBLOCK;
|
||||
fcntl(fd, F_SETFL, flags);
|
||||
|
||||
for (i = 0 ; i < fd ; i++)
|
||||
close(i);
|
||||
|
@ -485,6 +513,12 @@ main(int argc, char **argv)
|
|||
retcode = pam_set_item(pamh, PAM_TTY, tty);
|
||||
PAM_FAIL_CHECK;
|
||||
|
||||
/* Andrew.Taylor@cal.montage.ca: Provide a user prompt to PAM
|
||||
so that the "login: " prompt gets localized. Unfortunately,
|
||||
PAM doesn't have an interface to specify the "Password: " string (yet). */
|
||||
retcode = pam_set_item(pamh, PAM_USER_PROMPT, _("login: "));
|
||||
PAM_FAIL_CHECK;
|
||||
|
||||
#if 0
|
||||
/* other than iso-8859-1
|
||||
* one more time due to reset tty by PAM
|
||||
|
@ -1050,7 +1084,8 @@ Michael Riepe <michael@stud.uni-hannover.de>
|
|||
|
||||
motd();
|
||||
mail = getenv("MAIL");
|
||||
if (mail && stat(mail, &st) == 0 && st.st_size != 0) {
|
||||
if (mail && stat(mail, &st) == 0 && st.st_size != 0
|
||||
&& st.st_size != REDHAT_IGNORED_MAILSIZE) {
|
||||
printf(_("You have %smail.\n"),
|
||||
(st.st_mtime > st.st_atime) ? _("new ") : "");
|
||||
}
|
||||
|
|
|
@ -48,12 +48,12 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "errs.h"
|
||||
#include "nls.h"
|
||||
|
||||
int
|
||||
|
|
|
@ -68,8 +68,6 @@
|
|||
#include "nls.h"
|
||||
#include "env.h"
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
#ifndef _PATH_CHFN
|
||||
# define _PATH_CHFN "/usr/bin/chfn"
|
||||
# define _PATH_CHSH "/usr/bin/chsh"
|
||||
|
|
|
@ -56,10 +56,7 @@
|
|||
#include <unistd.h>
|
||||
#include <utmp.h>
|
||||
#include "nls.h"
|
||||
#ifdef __linux__
|
||||
#include <locale.h>
|
||||
#include "pathnames.h"
|
||||
#endif
|
||||
|
||||
void makemsg __P((char *));
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@ include ../MCONFIG
|
|||
# Where to put man pages?
|
||||
|
||||
MAN1= cal.1 chkdupexe.1 ddate.1 kill.1 \
|
||||
logger.1 look.1 mcookie.1 namei.1 script.1 \
|
||||
tsort.1 whereis.1 write.1
|
||||
logger.1 look.1 mcookie.1 namei.1 rename.1 script.1 \
|
||||
whereis.1 write.1
|
||||
|
||||
# Where to put binaries?
|
||||
# See the "install" rule for the links. . .
|
||||
|
@ -19,12 +19,7 @@ MAN1= cal.1 chkdupexe.1 ddate.1 kill.1 \
|
|||
BIN= kill
|
||||
|
||||
USRBIN= cal chkdupexe ddate logger look mcookie \
|
||||
namei script tsort whereis write
|
||||
|
||||
ifeq "$(HAVE_CLEAR)" "no"
|
||||
USRBIN:=$(USRBIN) clear
|
||||
MAN1:=$(MAN1) clear.1
|
||||
endif
|
||||
namei rename script whereis write
|
||||
|
||||
ifeq "$(HAVE_RESET)" "no"
|
||||
USRBIN:=$(USRBIN) reset
|
||||
|
@ -36,6 +31,11 @@ USRBIN:=$(USRBIN) setterm
|
|||
MAN1:=$(MAN1) setterm.1
|
||||
endif
|
||||
|
||||
ifeq "$(HAVE_TSORT)" "no"
|
||||
USRBIN:=$(USRBIN) tsort
|
||||
MAN1:=$(MAN1) tsort.1
|
||||
endif
|
||||
|
||||
# For script only
|
||||
LIBPTY=
|
||||
ifeq "$(HAVE_OPENPTY)" "yes"
|
||||
|
@ -69,9 +69,9 @@ $(NEEDS_OPENPTY):
|
|||
|
||||
# Rules for everything else
|
||||
|
||||
cal.o: $(LIB)/errs.h
|
||||
cal: cal.o $(ERR_O)
|
||||
chkdupexe: chkdupexe.pl
|
||||
clear: clear.sh
|
||||
kill: kill.o procs.o
|
||||
logger: logger.o
|
||||
mcookie: mcookie.o md5.o
|
||||
|
|
|
@ -52,9 +52,10 @@ the current month is displayed.
|
|||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl m
|
||||
Display monday as the first day of the week.
|
||||
Display Monday as the first day of the week.
|
||||
(The default is Sunday.)
|
||||
.It Fl j
|
||||
Display julian dates (days one-based, numbered from January 1).
|
||||
Display Julian dates (days one-based, numbered from January 1).
|
||||
.It Fl y
|
||||
Display a calendar for the current year.
|
||||
.El
|
||||
|
|
|
@ -44,13 +44,13 @@
|
|||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <locale.h>
|
||||
#include "errs.h"
|
||||
#include "nls.h"
|
||||
#include "../defines.h"
|
||||
|
||||
|
@ -138,6 +138,7 @@ void trim_trailing_spaces __P((char *));
|
|||
void usage __P((void));
|
||||
void yearly __P((int));
|
||||
void headers_init(void);
|
||||
extern char *__progname;
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
|
@ -147,17 +148,17 @@ main(argc, argv)
|
|||
struct tm *local_time;
|
||||
time_t now;
|
||||
int ch, month, year, yflag;
|
||||
char *progname, *p;
|
||||
|
||||
#ifdef __linux__
|
||||
extern char *__progname;
|
||||
__progname = argv[0];
|
||||
#endif
|
||||
progname = argv[0];
|
||||
if ((p = strrchr(progname, '/')) != NULL)
|
||||
progname = p+1;
|
||||
__progname = progname;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
setlocale(LC_ALL,"");
|
||||
yflag = 0;
|
||||
while ((ch = getopt(argc, argv, "mjy")) != EOF)
|
||||
switch(ch) {
|
||||
|
@ -170,6 +171,10 @@ main(argc, argv)
|
|||
case 'y':
|
||||
yflag = 1;
|
||||
break;
|
||||
case 'V':
|
||||
printf(_("%s from %s\n"),
|
||||
progname, util_linux_version);
|
||||
return 0;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
|
@ -254,7 +259,7 @@ monthly(month, year)
|
|||
int month, year;
|
||||
{
|
||||
int col, row, len, days[MAXDAYS];
|
||||
char *p, lineout[30];
|
||||
char *p, lineout[300];
|
||||
|
||||
day_array(month, year, days);
|
||||
len = sprintf(lineout, "%s %d", full_month[month - 1], year);
|
||||
|
@ -481,6 +486,6 @@ void
|
|||
usage()
|
||||
{
|
||||
|
||||
(void)fprintf(stderr, _("usage: cal [-mjy] [[month] year]\n"));
|
||||
(void)fprintf(stderr, _("usage: cal [-mjyV] [[month] year]\n"));
|
||||
exit(1);
|
||||
}
|
||||
|
|
|
@ -29,13 +29,18 @@ $execdirs='/bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin '.
|
|||
'/usr/TeX/bin /usr/tex/bin /usr/games '.
|
||||
'/usr/local/games';
|
||||
|
||||
# Turn off buffering for the output channel.
|
||||
$|=1;
|
||||
|
||||
# Values from /usr/include/linux/errno.h. Existence of linux/errno.ph is not
|
||||
# something to count on... :-(
|
||||
$ENOENT=2;
|
||||
|
||||
%didthis=();
|
||||
|
||||
foreach $dir (split(/\s+/, "$execdirs")) {
|
||||
foreach $dir (split(/\s+/, "$execdirs"), "\0", split(/:/, $ENV{PATH})) {
|
||||
|
||||
if ($dir eq "\0") { $checkingpath = 1; next; }
|
||||
|
||||
# It's like this: One directory corresponds to one $device,$inode tuple
|
||||
# If a symlink points to a directory we already checked that directory
|
||||
|
@ -52,7 +57,7 @@ foreach $dir (split(/\s+/, "$execdirs")) {
|
|||
print "Dangling symlink: $dir\n";
|
||||
next;
|
||||
}
|
||||
# warn "Nonexistent directory: $dir\n";
|
||||
warn "Nonexistent directory: $dir\n" if ($checkingpath);
|
||||
next;
|
||||
}
|
||||
|
||||
|
@ -90,7 +95,7 @@ foreach $dir (split(/\s+/, "$execdirs")) {
|
|||
closedir(DIR);
|
||||
}
|
||||
|
||||
open(LS,"| xargs ls -ldU");
|
||||
open(LS,"| xargs -r ls -ldU");
|
||||
while (($prog,$paths)=each %progs) {
|
||||
print LS "$paths\n" if ($count{$prog}>1);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
- added Native Language Support
|
||||
|
||||
*/
|
||||
#include "../defines.h" /* for util-linux-version */
|
||||
|
||||
|
||||
/* configuration options VVVVV READ THIS!!! */
|
||||
|
@ -150,6 +151,11 @@ main (int argc, char *argv[])
|
|||
struct disc_time hastur;
|
||||
char schwa[23*17], *fnord=0;
|
||||
int pi;
|
||||
char *progname, *p;
|
||||
|
||||
progname = argv[0];
|
||||
if ((p = strrchr(progname, '/')) != NULL)
|
||||
progname = p+1;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
|
@ -162,6 +168,8 @@ main (int argc, char *argv[])
|
|||
case '+': fnord=argv[pi]+1; break;
|
||||
case '-':
|
||||
switch(argv[pi][1]) {
|
||||
case 'V':
|
||||
printf(_("%s from %s\n"), progname, util_linux_version);
|
||||
default: goto usage;
|
||||
}
|
||||
default: goto thud;
|
||||
|
@ -281,7 +289,7 @@ struct disc_time makeday(int imonth,int iday,int iyear) /*i for input */
|
|||
funkychickens.day=dayspast+iday-1;
|
||||
funkychickens.season=0;
|
||||
if((funkychickens.year%4)==2) {
|
||||
if (funkychickens.day==59) funkychickens.day=-1;
|
||||
if (funkychickens.day==59 && iday==29) funkychickens.day=-1;
|
||||
}
|
||||
funkychickens.yday=funkychickens.day;
|
||||
/* note: EQUAL SIGN...hopefully that fixes it */
|
||||
|
|
73
misc-utils/ddate.doc
Normal file
73
misc-utils/ddate.doc
Normal file
|
@ -0,0 +1,73 @@
|
|||
|
||||
PERPETUAL DATE CONVERTER FROM GREGORIAN TO POEE CALENDAR
|
||||
|
||||
SEASONS
|
||||
1. Chaos -- Patron Apostle Hung Mung
|
||||
2. Discord -- Patron Apostle Dr. Van Van Mojo
|
||||
3. Confusion -- Patron Apostle Sri Syadasti
|
||||
4. Bureaucracy -- Patron Apostle Zarathud
|
||||
5. The Aftermath -- Patron Apostle the Elder Malaclypse
|
||||
|
||||
DAYS OF THE WEEK*
|
||||
1. Sweetmorn *The DAYS OF THE WEEK
|
||||
2. Boomtime are named from the five
|
||||
3. Pungenday basic elements: SWEET,
|
||||
4. Prickle-Prickle BOOM, PUNGENT, PRICKLE,
|
||||
5. Setting Orange and ORANGE.
|
||||
|
||||
HOLYDAYS
|
||||
A. Apostle Holydays B. Seasons Holydays
|
||||
1. Mungday 1. Chaoflux
|
||||
2. Mojoday 2. Discoflux
|
||||
3. Syaday 3. Confuflux
|
||||
4. Zaraday 4. Bureflux
|
||||
5. Maladay 5. Afflux
|
||||
Each occurs on the 5th Each occurs on the 50th
|
||||
day of the Season day of the Season
|
||||
|
||||
C. Saint Tib's Day -- occurs once every four years (1 + 4 = 5) and is
|
||||
inserted between the 59th and 60th days of the Season of Chaos
|
||||
|
||||
ST BT PD PP SO SM BT PD PP SO
|
||||
Jan 1 2 3 4 5 1 2 3 4 5 Chs Jul 5 6 7 8 9 40 41 42 43 44 Cfn
|
||||
6 7 8 9 10 6 7 8 9 10 10 11 12 13 14 45 46 47 48 49
|
||||
11 12 13 14 15 11 12 13 14 15 15 16 17 18 19 50 51 52 53 54
|
||||
16 17 18 19 20 16 17 18 19 20 20 21 22 23 24 55 56 57 58 59
|
||||
21 22 23 24 25 21 22 23 24 25 25 26 27 28 29 60 61 62 63 64
|
||||
26 27 28 29 30 26 27 28 29 30 30 31 1 2 3 65 66 67 68 69
|
||||
31 1 2 3 4 31 32 33 34 35 Aug 4 5 6 7 8 70 71 72 73 1 Bcy
|
||||
Feb 5 6 7 8 9 36 37 38 39 40 9 10 11 12 13 2 3 4 5 6
|
||||
10 11 12 13 14 41 42 43 44 45 14 15 16 17 18 7 8 9 10 11
|
||||
15 16 17 18 19 46 47 48 49 50 19 20 21 22 23 12 13 14 15 16
|
||||
20 21 22 23 24 51 52 53 54 55 24 25 26 27 28 17 18 19 20 21
|
||||
25 26 27 28* 1 56 57 58 59 60 29 30 31 1 2 22 23 24 25 26
|
||||
Mar 2 3 4 5 6 61 62 63 64 65 Sep 3 4 5 6 7 27 28 29 30 31
|
||||
7 8 9 10 11 66 67 68 69 70 8 9 10 11 12 32 33 34 35 36
|
||||
12 13 14 15 16 71 72 73 1 2 Dsc 13 14 15 16 17 37 38 39 40 41
|
||||
17 18 19 20 21 3 4 5 6 7 18 19 20 21 22 42 43 44 45 46
|
||||
22 23 24 25 26 8 9 10 11 12 23 24 25 26 27 47 48 49 50 51
|
||||
27 28 29 30 31 13 14 15 16 17 28 29 30 1 2 52 53 54 55 56
|
||||
Apr 1 2 3 4 5 18 19 20 21 22 Oct 3 4 5 6 7 57 58 59 60 61
|
||||
6 7 8 9 10 23 24 25 26 27 8 9 10 11 12 62 63 64 65 66
|
||||
11 12 13 14 15 28 29 30 31 32 13 14 15 16 17 67 68 69 70 71
|
||||
16 17 18 19 20 33 34 35 36 37 18 19 20 21 22 72 73 1 2 3 Afm
|
||||
21 22 23 24 25 38 39 40 41 42 23 24 25 26 27 4 5 6 7 8
|
||||
26 27 28 29 30 43 44 45 46 47 28 29 30 31 1 9 10 11 12 13
|
||||
May 1 2 3 4 5 48 49 50 51 52 Nov 2 3 4 5 6 14 15 16 17 18
|
||||
6 7 8 9 10 53 54 55 56 57 7 8 9 10 11 19 20 21 22 23
|
||||
11 12 13 14 15 58 59 60 61 62 12 13 14 15 16 24 25 26 27 28
|
||||
16 17 18 19 20 63 64 65 66 67 17 18 19 20 21 29 30 31 32 33
|
||||
21 22 23 24 25 68 69 70 71 72 22 23 24 25 26 34 35 36 37 38
|
||||
26 27 28 29 30 73 1 2 3 4 Cfn 27 28 29 30 1 39 40 41 42 43
|
||||
31 1 2 3 4 5 6 7 8 9 Dec 2 3 4 5 6 44 45 46 47 48
|
||||
Jun 5 6 7 8 9 10 11 12 13 14 7 8 9 10 11 49 50 51 52 53
|
||||
10 11 12 13 14 15 16 17 18 19 12 13 14 15 16 54 55 56 57 58
|
||||
15 16 17 18 19 20 21 22 23 24 17 18 19 20 21 59 60 61 62 63
|
||||
20 21 22 23 24 25 26 27 28 29 22 23 24 25 26 64 65 66 67 68
|
||||
25 26 27 28 29 30 31 32 33 34 27 28 29 30 31 69 70 71 72 73
|
||||
30 1 2 3 4 35 36 37 38 39 [1970 = 3136] [Next St. Tib's Day in 3138]
|
||||
|
||||
SACRED DOCUMENT OF THE FROGS (old Erisian poem):
|
||||
73 Days hath
|
||||
Chaos, Discord, Confusion, Bureaucracy, and Aftermath
|
||||
|
|
@ -38,6 +38,8 @@
|
|||
* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
|
||||
* - added Native Language Support
|
||||
*
|
||||
* 1999-11-13 aeb Accept signal numers 128+s.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -137,7 +139,7 @@ struct signv {
|
|||
int main (int argc, char *argv[]);
|
||||
extern char *mybasename(char *);
|
||||
int signame_to_signum (char *sig);
|
||||
int arg_to_signum (char *arg);
|
||||
int arg_to_signum (char *arg, int mask);
|
||||
void nosig (char *name);
|
||||
void printsig (int sig);
|
||||
void printsignals (FILE *fp);
|
||||
|
@ -146,16 +148,19 @@ int kill_verbose (char *procname, int pid, int sig);
|
|||
|
||||
extern int *get_pids (char *, int);
|
||||
|
||||
char version_string[] = "kill v2.0\n";
|
||||
char *whoami;
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
{
|
||||
int errors, numsig, pid;
|
||||
char *ep, *arg;
|
||||
char *ep, *arg, *progname, *p;
|
||||
int do_pid, do_kill, check_all;
|
||||
int *pids, *ip;
|
||||
|
||||
progname = argv[0];
|
||||
if ((p = strrchr(progname, '/')) != NULL)
|
||||
progname = p+1;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
@ -174,11 +179,16 @@ int main (int argc, char *argv[])
|
|||
if (*arg != '-') {
|
||||
break;
|
||||
}
|
||||
if (! strcmp (arg, "--")) {
|
||||
argc--, argv++;
|
||||
break;
|
||||
}
|
||||
if (! strcmp (arg, "-u")) {
|
||||
return usage (0);
|
||||
}
|
||||
if (! strcmp (arg, "-v")) {
|
||||
fputs (version_string, stdout);
|
||||
if (! strcmp (arg, "-v") || ! strcmp (arg, "-V") ||
|
||||
! strcmp (arg, "--version")) {
|
||||
printf(_("%s from %s\n"), progname, util_linux_version);
|
||||
return 0;
|
||||
}
|
||||
if (! strcmp (arg, "-a")) {
|
||||
|
@ -193,9 +203,9 @@ int main (int argc, char *argv[])
|
|||
if (argc > 2) {
|
||||
return usage (1);
|
||||
}
|
||||
/* argc == 2 */
|
||||
/* argc == 2, accept "kill -l $?" */
|
||||
arg = argv[1];
|
||||
if ((numsig = arg_to_signum (arg)) < 0) {
|
||||
if ((numsig = arg_to_signum (arg, 1)) < 0) {
|
||||
fprintf (stderr, _("%s: unknown signal %s\n"), whoami, arg);
|
||||
return 1;
|
||||
}
|
||||
|
@ -217,7 +227,7 @@ int main (int argc, char *argv[])
|
|||
return usage (1);
|
||||
argc--, argv++;
|
||||
arg = *argv;
|
||||
if ((numsig = arg_to_signum (arg)) < 0) {
|
||||
if ((numsig = arg_to_signum (arg, 0)) < 0) {
|
||||
nosig (arg);
|
||||
return 1;
|
||||
}
|
||||
|
@ -231,7 +241,7 @@ int main (int argc, char *argv[])
|
|||
if (do_kill)
|
||||
break;
|
||||
arg++;
|
||||
if ((numsig = arg_to_signum (arg)) < 0) {
|
||||
if ((numsig = arg_to_signum (arg, 0)) < 0) {
|
||||
return usage (1);
|
||||
}
|
||||
do_kill++;
|
||||
|
@ -284,13 +294,15 @@ int signame_to_signum (char *sig)
|
|||
return (-1);
|
||||
}
|
||||
|
||||
int arg_to_signum (char *arg)
|
||||
int arg_to_signum (char *arg, int maskbit)
|
||||
{
|
||||
int numsig;
|
||||
char *ep;
|
||||
|
||||
if (isdigit (*arg)) {
|
||||
numsig = strtol (arg, &ep, 10);
|
||||
if (numsig >= NSIG && maskbit && (numsig & 128) != 0)
|
||||
numsig -= 128;
|
||||
if (*ep != 0 || numsig < 0 || numsig >= NSIG)
|
||||
return (-1);
|
||||
return (numsig);
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
.\"
|
||||
.\" @(#)logger.1 8.1 (Berkeley) 6/6/93
|
||||
.\"
|
||||
.\" Section on valid facitily and level strings added by
|
||||
.\" and1000@debian.org, 26 Oct 1997.
|
||||
.Dd June 6, 1993
|
||||
.Dt LOGGER 1
|
||||
.Os BSD 4.3
|
||||
|
@ -78,6 +80,11 @@ Mark every line in the log with the specified
|
|||
Write to socket as specified with
|
||||
.Ar socket
|
||||
instead of builtin syslog routines.
|
||||
.It --
|
||||
End the argument list. This is to allow the
|
||||
.Ar message
|
||||
to start with a hyphen (\-). This feature was not present in the
|
||||
original BSD logger command; it is a GNU-specific extra.
|
||||
.It Ar message
|
||||
Write the message to log; if not specified, and the
|
||||
.Fl f
|
||||
|
@ -88,6 +95,15 @@ provided, standard input is logged.
|
|||
The
|
||||
.Nm logger
|
||||
utility exits 0 on success, and >0 if an error occurs.
|
||||
.Pp
|
||||
Valid facility names are: auth, authpriv (for security information of
|
||||
a sensitive nature), cron, daemon, ftp, kern, lpr, mail, news,
|
||||
security (deprecated synonym for auth), syslog, user, uucp, and local0
|
||||
to local7, inclusive.
|
||||
.Pp
|
||||
Valid level names are: alert, crit, debug, emerg, err, error
|
||||
(deprecated synonym for err), info, notice, panic (deprecated synonym
|
||||
for emerg), warning, warn (deprecated synonym for warning).
|
||||
.Sh EXAMPLES
|
||||
.Bd -literal -offset indent -compact
|
||||
logger System rebooted
|
||||
|
|
|
@ -210,6 +210,13 @@ main(argc, argv)
|
|||
}
|
||||
} else
|
||||
while (fgets(buf, sizeof(buf), stdin) != NULL) {
|
||||
/* glibc is buggy and adds an additional newline,
|
||||
so we have to remove it here until glibc is fixed */
|
||||
int len = strlen(buf);
|
||||
|
||||
if (len > 0 && buf[len - 1] == '\n')
|
||||
buf[len - 1] = '\0';
|
||||
|
||||
if (!usock)
|
||||
syslog(pri, "%s", buf);
|
||||
else
|
||||
|
|
|
@ -55,7 +55,11 @@ As
|
|||
.Nm look
|
||||
performs a binary search, the lines in
|
||||
.Ar file
|
||||
must be sorted.
|
||||
must be sorted (where
|
||||
.Xr sort 1
|
||||
got the same options \-d and/or \-f that
|
||||
.Nm look
|
||||
is invoked with).
|
||||
.Pp
|
||||
If
|
||||
.Ar file
|
||||
|
|
|
@ -74,7 +74,7 @@ char *string;
|
|||
char *comparbuf;
|
||||
|
||||
static char *binary_search (char *, char *);
|
||||
static int compare (char *, char *, int);
|
||||
static int compare (char *, char *);
|
||||
static void err (const char *fmt, ...);
|
||||
static char *linear_search (char *, char *);
|
||||
static int look (char *, char *);
|
||||
|
@ -192,10 +192,6 @@ look(char *front, char *back)
|
|||
* back points to the beginning of a line at or after the first
|
||||
* matching line.
|
||||
*
|
||||
* Base of the Invariants.
|
||||
* front = NULL;
|
||||
* back = EOF;
|
||||
*
|
||||
* Advancing the Invariants:
|
||||
*
|
||||
* p = first newline after halfway point from front to back.
|
||||
|
@ -232,7 +228,7 @@ binary_search(char *front, char *back)
|
|||
* infinitely loop.
|
||||
*/
|
||||
while (p < back && back > front) {
|
||||
if (compare(p, back, 1) == GREATER)
|
||||
if (compare(p, back) == GREATER)
|
||||
front = p;
|
||||
else
|
||||
back = p;
|
||||
|
@ -257,7 +253,7 @@ char *
|
|||
linear_search(char *front, char *back)
|
||||
{
|
||||
while (front < back) {
|
||||
switch (compare(front, back, 1)) {
|
||||
switch (compare(front, back)) {
|
||||
case EQUAL: /* Found it. */
|
||||
return (front);
|
||||
break;
|
||||
|
@ -280,8 +276,8 @@ print_from(char *front, char *back)
|
|||
{
|
||||
int eol;
|
||||
|
||||
while (front < back && compare(front, back, 1) == EQUAL) {
|
||||
if (compare(front, back, fflag) == EQUAL) {
|
||||
while (front < back && compare(front, back) == EQUAL) {
|
||||
if (compare(front, back) == EQUAL) {
|
||||
eol = 0;
|
||||
while (front < back && !eol) {
|
||||
if (putchar(*front) == EOF)
|
||||
|
@ -311,7 +307,7 @@ print_from(char *front, char *back)
|
|||
* in other locales.
|
||||
*/
|
||||
int
|
||||
compare(char *s2, char *s2end, int nocase) {
|
||||
compare(char *s2, char *s2end) {
|
||||
int i;
|
||||
char *p;
|
||||
|
||||
|
@ -326,7 +322,7 @@ compare(char *s2, char *s2end, int nocase) {
|
|||
*p = 0;
|
||||
|
||||
/* and compare */
|
||||
if (nocase)
|
||||
if (fflag)
|
||||
i = strncasecmp(comparbuf, string, stringlen);
|
||||
else
|
||||
i = strncmp(comparbuf, string, stringlen);
|
||||
|
|
|
@ -255,11 +255,12 @@ register int lev;
|
|||
(void)printf(" l %s -> %s", buf, sym);
|
||||
|
||||
if(symcount > 0 && symcount++ > MAXSYMLINKS){
|
||||
(void)printf(_(" *** EXCEEDED UNIX LIMIT OF SYMLINKS ***"));
|
||||
(void)printf(_(" *** EXCEEDED UNIX LIMIT OF SYMLINKS ***\n"));
|
||||
symcount = -1;
|
||||
}
|
||||
} else {
|
||||
(void)printf("\n");
|
||||
namei(sym, lev + 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case S_IFCHR:
|
||||
|
|
40
misc-utils/rename.1
Normal file
40
misc-utils/rename.1
Normal file
|
@ -0,0 +1,40 @@
|
|||
.\" Written by Andries E. Brouwer (aeb@cwi.nl)
|
||||
.\" Placed in the public domain
|
||||
.\"
|
||||
.TH RENAME 1 "1 Januari 2000" "" "Linux Programmer's Manual"
|
||||
.SH NAME
|
||||
rename \- Rename files
|
||||
.SH SYNOPSIS
|
||||
.BI rename " from to file..."
|
||||
.SH DESCRIPTION
|
||||
.B rename
|
||||
will rename the specified files by replacing the first occurrence of
|
||||
.I from
|
||||
in their name by
|
||||
.IR to .
|
||||
|
||||
For example, given the files
|
||||
.IR foo1 ", ..., " foo9 ", " foo10 ", ..., " foo278 ,
|
||||
the commands
|
||||
|
||||
.RS
|
||||
.nf
|
||||
rename foo foo0 foo?
|
||||
rename foo foo0 foo??
|
||||
.fi
|
||||
.RE
|
||||
|
||||
will turn them into
|
||||
.IR foo001 ", ..., " foo009 ", " foo010 ", ..., " foo278 .
|
||||
|
||||
And
|
||||
.RS
|
||||
.nf
|
||||
rename .htm .html *.htm
|
||||
.fi
|
||||
.RE
|
||||
|
||||
will fix the extension of your html files.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR mv (1)
|
97
misc-utils/rename.c
Normal file
97
misc-utils/rename.c
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* rename.c - aeb 2000-01-01
|
||||
*
|
||||
--------------------------------------------------------------
|
||||
#!/bin/sh
|
||||
if [ $# -le 2 ]; then echo call: rename from to files; exit; fi
|
||||
FROM="$1"
|
||||
TO="$2"
|
||||
shift
|
||||
shift
|
||||
for i in $@; do N=`echo "$i" | sed "s/$FROM/$TO/g"`; mv "$i" "$N"; done
|
||||
--------------------------------------------------------------
|
||||
* This shell script will do renames of files, but may fail
|
||||
* in cases involving special characters. Here a C version.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "nls.h"
|
||||
|
||||
static char *progname;
|
||||
|
||||
int
|
||||
do_rename(char *from, char *to, char *s) {
|
||||
char *newname, *where, *p, *q;
|
||||
int flen, tlen, slen;
|
||||
|
||||
where = strstr(s, from);
|
||||
if (where == NULL)
|
||||
return 0;
|
||||
|
||||
flen = strlen(from);
|
||||
tlen = strlen(to);
|
||||
slen = strlen(s);
|
||||
newname = malloc(tlen+slen+1);
|
||||
if (newname == NULL) {
|
||||
fprintf(stderr, _("%s: out of memory\n"), progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
p = s;
|
||||
q = newname;
|
||||
while (p < where)
|
||||
*q++ = *p++;
|
||||
p = to;
|
||||
while (*p)
|
||||
*q++ = *p++;
|
||||
p = where+flen;
|
||||
while (*p)
|
||||
*q++ = *p++;
|
||||
*p = 0;
|
||||
|
||||
if (rename(s, newname) != 0) {
|
||||
int errsv = errno;
|
||||
fprintf(stderr, _("%s: renaming %s to %s failed: %s\n"),
|
||||
progname, s, newname, strerror(errsv));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv) {
|
||||
char *from, *to, *p;
|
||||
int i, ct;
|
||||
|
||||
progname = argv[0];
|
||||
if ((p = strrchr(progname, '/')) != NULL)
|
||||
progname = p+1;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
if (argc == 2) {
|
||||
if (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")) {
|
||||
printf(_("%s from %s\n"),
|
||||
progname, util_linux_version);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, _("call: %s from to files...\n"), progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
from = argv[1];
|
||||
to = argv[2];
|
||||
|
||||
ct = 0;
|
||||
for (i=3; i<argc; i++)
|
||||
ct += do_rename(from, to, argv[i]);
|
||||
return 0;
|
||||
}
|
|
@ -11,7 +11,6 @@ setterm \- set terminal attributes
|
|||
.B "setterm [ \-reset ]"
|
||||
.B "setterm [ \-initialize ]"
|
||||
.B "setterm [ \-cursor [on|off] ]"
|
||||
.B "setterm [ \-keyboard pc|olivetti|dutch|extended ]"
|
||||
.B "setterm [ \-repeat [on|off] ]"
|
||||
.B "setterm [ \-appcursorkeys [on|off] ]"
|
||||
.B "setterm [ \-linewrap [on|off] ]"
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
*
|
||||
* Sanity increases by Cafeine Addict [sic].
|
||||
*
|
||||
* Powersave features by, todd j. derr <tjd@wordsmith.org>
|
||||
* Powersave features by todd j. derr <tjd@wordsmith.org>
|
||||
*
|
||||
* Converted to terminfo by Kars de Jong (jongk@cs.utwente.nl)
|
||||
*
|
||||
|
@ -27,7 +27,6 @@
|
|||
* [ -reset ]
|
||||
* [ -initialize ]
|
||||
* [ -cursor [on|off] ]
|
||||
* [ -keyboard pc|olivetti|dutch|extended ]
|
||||
* [ -repeat [on|off] ]
|
||||
* [ -appcursorkeys [on|off] ]
|
||||
* [ -linewrap [on|off] ]
|
||||
|
@ -162,7 +161,7 @@ extern int klogctl(int type, char *buf, int len);
|
|||
/* Static variables. */
|
||||
|
||||
/* Option flags. Set if the option is to be invoked. */
|
||||
int opt_term, opt_reset, opt_initialize, opt_cursor, opt_keyboard;
|
||||
int opt_term, opt_reset, opt_initialize, opt_cursor;
|
||||
int opt_linewrap, opt_snow, opt_softscroll, opt_default, opt_foreground;
|
||||
int opt_background, opt_bold, opt_blink, opt_reverse, opt_underline;
|
||||
int opt_store, opt_clear, opt_blank, opt_snap, opt_snapfile, opt_standout;
|
||||
|
@ -252,33 +251,6 @@ int *bad_arg; /* Set to true if an error is detected. */
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void parse_keyboard(argc, argv, option, opt_keyboard, bad_arg)
|
||||
int argc; /* Number of arguments for this option. */
|
||||
char *argv[]; /* Arguments for this option. */
|
||||
int *option; /* Keyboard flag to set. */
|
||||
int *opt_keyboard; /* Keyboard type to set. */
|
||||
int *bad_arg; /* Set to true if an error is detected. */
|
||||
{
|
||||
/* Parse a -keyboard specification. */
|
||||
|
||||
if (argc != 1 || *option) *bad_arg = TRUE;
|
||||
*option = TRUE;
|
||||
if (argc == 1) {
|
||||
if (strcmp(argv[0], "pc") == 0)
|
||||
*opt_keyboard = PC;
|
||||
else if (strcmp(argv[0], "olivetti") == 0)
|
||||
*opt_keyboard = OLIVETTI;
|
||||
else if (strcmp(argv[0], "dutch") == 0)
|
||||
*opt_keyboard = DUTCH;
|
||||
else if (strcmp(argv[0], "extended") == 0)
|
||||
*opt_keyboard = EXTENDED;
|
||||
else
|
||||
*bad_arg = TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void par_color(argc, argv, option, opt_color, bad_arg)
|
||||
int argc; /* Number of arguments for this option. */
|
||||
char *argv[]; /* Arguments for this option. */
|
||||
|
@ -659,10 +631,6 @@ int *bad_arg; /* Set to true if an error is detected. */
|
|||
parse_none(argc, argv, &opt_initialize, bad_arg);
|
||||
else if (STRCMP(option, "cursor") == 0)
|
||||
parse_switch(argc, argv, &opt_cursor, &opt_cu_on, bad_arg);
|
||||
#if 0
|
||||
else if (STRCMP(option, "keyboard") == 0)
|
||||
parse_keyboard(argc, argv, &opt_keyboard, &opt_ke_type, bad_arg);
|
||||
#endif
|
||||
else if (STRCMP(option, "repeat") == 0)
|
||||
parse_switch(argc, argv, &opt_repeat, &opt_rep_on, bad_arg);
|
||||
else if (STRCMP(option, "appcursorkeys") == 0)
|
||||
|
@ -752,7 +720,6 @@ char *prog_name; /* Name of this program. */
|
|||
#if 0
|
||||
fprintf(stderr, _(" [ -snow [on|off] ]\n"));
|
||||
fprintf(stderr, _(" [ -softscroll [on|off] ]\n"));
|
||||
fprintf(stderr, _(" [ -keyboard pc|olivetti|dutch|extended ]\n"));
|
||||
#endif
|
||||
fprintf(stderr, _(" [ -repeat [on|off] ]\n"));
|
||||
fprintf(stderr, _(" [ -appcursorkeys [on|off] ]\n"));
|
||||
|
@ -833,26 +800,6 @@ int vcterm; /* Set if terminal is a virtual console. */
|
|||
putp(ti_entry("civis"));
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* -keyboard pc|olivetti|dutch|extended. Vc only. */
|
||||
if (opt_keyboard && vcterm) {
|
||||
switch (opt_ke_type) {
|
||||
case PC:
|
||||
printf("%s%s%s", DCS, _("keyboard.pc"), ST);
|
||||
break;
|
||||
case OLIVETTI:
|
||||
printf("%s%s%s", DCS, _("keyboard.olivetti"), ST);
|
||||
break;
|
||||
case DUTCH:
|
||||
printf("%s%s%s", DCS, _("keyboard.dutch"), ST);
|
||||
break;
|
||||
case EXTENDED:
|
||||
printf("%s%s%s", DCS, _("keyboard.extended"), ST);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -linewrap [on|off]. Vc only (vt102) */
|
||||
if (opt_linewrap && vcterm) {
|
||||
if (opt_li_on)
|
||||
|
|
13
misc-utils/sparc-solaris-hostid.sh
Executable file
13
misc-utils/sparc-solaris-hostid.sh
Executable file
|
@ -0,0 +1,13 @@
|
|||
#!/bin/sh
|
||||
# This script reproduces the output of the Solaris hostid program.
|
||||
# It might be put in /usr/bin/hostid or so.
|
||||
# Note that the hostid program does not have any known uses
|
||||
# and does not exist on other architectures.
|
||||
# Copyright 1999 Peter Jones, <pjones@redhat.com> .
|
||||
# GPL and all that good stuff apply.
|
||||
(
|
||||
idprom=`cat /proc/openprom/idprom`
|
||||
echo $idprom|dd bs=1 skip=2 count=2
|
||||
echo $idprom|dd bs=1 skip=27 count=6
|
||||
echo
|
||||
) 2>/dev/null
|
|
@ -39,6 +39,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
@ -87,7 +88,7 @@ typedef struct _buf {
|
|||
|
||||
NODE *add_node(), *find_node();
|
||||
void add_arc(), no_memory(), remove_node(), tsort();
|
||||
char *grow_buf(), *malloc();
|
||||
char *grow_buf();
|
||||
int find_cycle(NODE *, NODE *, int, int);
|
||||
|
||||
extern int errno;
|
||||
|
@ -168,8 +169,6 @@ grow_buf(bp, size)
|
|||
char *bp;
|
||||
int size;
|
||||
{
|
||||
char *realloc();
|
||||
|
||||
if (!(bp = realloc(bp, (u_int)size)))
|
||||
no_memory();
|
||||
return(bp);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
include ../make_include
|
||||
include ../MCONFIG
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -I$(LIB) $(OPT)
|
||||
WARNFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes
|
||||
DEFINES = -DHAVE_NFS
|
||||
|
@ -9,17 +8,6 @@ DEFINES = -DHAVE_NFS
|
|||
RPCSVCDIR = rpcsvc
|
||||
RPC_CFLAGS = -Wno-unused
|
||||
RPCGEN = rpcgen
|
||||
#INSTALL = install
|
||||
#INSTALLSUID = $(INSTALL) -m 4755 -o root
|
||||
#INSTALLPROG = $(INSTALL) -m 755
|
||||
#INSTALLDATA = $(INSTALL) -m 644
|
||||
|
||||
## for suid progs (mount, umount)
|
||||
#BINDIR = /bin
|
||||
## for nosuid progs (swapon)
|
||||
#SBINDIR = /sbin
|
||||
|
||||
# End of configuration section.
|
||||
|
||||
COMPILE = $(CC) -c $(WARNFLAGS) $(CFLAGS) $(DEFINES)
|
||||
LINK = $(CC) $(LDFLAGS)
|
||||
|
@ -67,7 +55,7 @@ swapon: swapon.o version.o
|
|||
losetup: losetup.o
|
||||
$(LINK) $^ -o $@
|
||||
|
||||
mount.o umount.o nfsmount.o losetup.o fstab.o sundries.o: sundries.h
|
||||
mount.o umount.o nfsmount.o losetup.o fstab.o realpath.o sundries.o: sundries.h
|
||||
|
||||
mount.o umount.o fstab.o sundries.o: fstab.h
|
||||
|
||||
|
@ -89,6 +77,8 @@ umount.o: mount_constants.h
|
|||
|
||||
mount.o mount_by_label.o mount_guess_fstype.o: linux_fs.h
|
||||
|
||||
sundries.o realpath.o: realpath.h
|
||||
|
||||
nfsmount_clnt.o: nfsmount_clnt.c
|
||||
$(COMPILE) $(RPC_CFLAGS) nfsmount_clnt.c
|
||||
|
||||
|
|
|
@ -189,7 +189,11 @@ The documentation in
|
|||
.BR mount (8)
|
||||
is often more up-to-date.
|
||||
.SH "SEE ALSO"
|
||||
.BR getmntent "(3), " mount "(8), " swapon "(8), " nfs (5)
|
||||
.BR getmntent (3),
|
||||
.BR mount (8),
|
||||
.BR swapon (8),
|
||||
.BR fs (5)
|
||||
.BR nfs (5)
|
||||
.SH HISTORY
|
||||
The
|
||||
.B fstab
|
||||
|
|
|
@ -224,6 +224,23 @@ getmntoptfile (const char *file)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Find the entry (SPEC,FILE) in fstab */
|
||||
struct mntentchn *
|
||||
getfsspecfile (const char *spec, const char *file) {
|
||||
struct mntentchn *mc;
|
||||
|
||||
for (mc = fstab_head()->nxt; mc; mc = mc->nxt)
|
||||
if (streq (mc->mnt_dir, file) && streq (mc->mnt_fsname, spec))
|
||||
return mc;
|
||||
for (mc = fstab_head()->nxt; mc; mc = mc->nxt)
|
||||
if ((streq (mc->mnt_dir, file) ||
|
||||
streq (canonicalize(mc->mnt_dir), file))
|
||||
&& (streq (mc->mnt_fsname, spec) ||
|
||||
streq (canonicalize(mc->mnt_fsname), spec)))
|
||||
break;
|
||||
return mc;
|
||||
}
|
||||
|
||||
/* Find the dir FILE in fstab. */
|
||||
struct mntentchn *
|
||||
getfsfile (const char *file) {
|
||||
|
@ -401,6 +418,8 @@ lock_mtab (void) {
|
|||
}
|
||||
we_created_lockfile = 1;
|
||||
} else {
|
||||
static int tries = 0;
|
||||
|
||||
/* Someone else made the link. Wait. */
|
||||
alarm(LOCK_TIMEOUT);
|
||||
if (fcntl (fd, F_SETLKW, &flock) == -1) {
|
||||
|
@ -410,7 +429,15 @@ lock_mtab (void) {
|
|||
_("timed out") : strerror (errsv));
|
||||
}
|
||||
alarm(0);
|
||||
/* Maybe limit the number of iterations? */
|
||||
/* Limit the number of iterations - maybe there
|
||||
still is some old /etc/mtab~ */
|
||||
if (tries++ > 3) {
|
||||
if (tries > 5)
|
||||
die (EX_FILEIO, _("Cannot create link %s\n"
|
||||
"Perhaps there is a stale lock file?\n"),
|
||||
MOUNTED_LOCK);
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
close(fd);
|
||||
|
|
|
@ -28,6 +28,7 @@ struct mntentchn *getmntfilesbackward (const char *file, struct mntentchn *mc);
|
|||
struct mntentchn *fstab_head (void);
|
||||
struct mntentchn *getfsfile (const char *file);
|
||||
struct mntentchn *getfsspec (const char *spec);
|
||||
struct mntentchn *getfsspecfile (const char *spec, const char *file);
|
||||
struct mntentchn *getfsuuidspec (const char *uuid);
|
||||
struct mntentchn *getfsvolspec (const char *label);
|
||||
|
||||
|
|
|
@ -91,6 +91,7 @@ struct ntfs_super_block {
|
|||
struct fat_super_block {
|
||||
u_char s_dummy[3];
|
||||
u_char s_os[8]; /* "MSDOS5.0" or "MSWIN4.0" or "MSWIN4.1" */
|
||||
/* mtools-3.9.4 writes "MTOOL394" */
|
||||
u_char s_dummy2[32];
|
||||
u_char s_label[11]; /* for DOS? */
|
||||
u_char s_fs[8]; /* "FAT12 " or "FAT16 " or all zero */
|
||||
|
|
|
@ -103,7 +103,8 @@ int set_loop(const char *device, const char *file, int offset,
|
|||
loopinfo.lo_name[LO_NAME_SIZE-1] = 0;
|
||||
if (encryption && (loopinfo.lo_encrypt_type = crypt_type(encryption))
|
||||
< 0) {
|
||||
fprintf(stderr,_("Unsupported encryption type %s\n"),encryption);
|
||||
fprintf(stderr,_("Unsupported encryption type %s\n"),
|
||||
encryption);
|
||||
exit(1);
|
||||
}
|
||||
loopinfo.lo_offset = offset;
|
||||
|
@ -129,7 +130,8 @@ int set_loop(const char *device, const char *file, int offset,
|
|||
(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]);
|
||||
fprintf(stderr,_("Non-hex digit '%c'.\n"),
|
||||
pass[i]);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
@ -183,6 +185,7 @@ int main(int argc, char **argv)
|
|||
{
|
||||
char *offset,*encryption;
|
||||
int delete,off,c;
|
||||
int res = 0;
|
||||
int ro = 0;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
|
@ -219,9 +222,9 @@ int main(int argc, char **argv)
|
|||
} else {
|
||||
if (offset && sscanf(offset,"%d",&off) != 1)
|
||||
usage();
|
||||
set_loop(argv[optind],argv[optind+1],off,encryption,&ro);
|
||||
res = set_loop(argv[optind],argv[optind+1],off,encryption,&ro);
|
||||
}
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
#else /* LOOP_SET_FD not defined */
|
||||
|
|
|
@ -14,8 +14,10 @@ rm -f loop.h
|
|||
|
||||
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
|
||||
|
||||
|
|
|
@ -86,10 +86,10 @@ unmangle(char *s) {
|
|||
|
||||
/*
|
||||
* fstat'ing the file and allocating a buffer holding all of it
|
||||
* may be a bad idea: if the file is /proc/mounttab, the stat
|
||||
* may be a bad idea: if the file is /proc/mounts, the stat
|
||||
* returns 0.
|
||||
* (On the other hand, mangling and unmangling is meaningless
|
||||
* for /proc/mounttab.)
|
||||
* for /proc/mounts.)
|
||||
*/
|
||||
|
||||
mntFILE *
|
||||
|
|
264
mount/mount.8
264
mount/mount.8
|
@ -33,6 +33,8 @@
|
|||
.\" 970914, reg: -s option
|
||||
.\" 981111, K.Garloff: /etc/filesystems
|
||||
.\" 990111, aeb: documented /sbin/mount.smbfs
|
||||
.\" 990730, Yann Droneaud <lch@multimania.com>: updated page
|
||||
.\" 991214, Elrond <Elrond@Wunder-Nett.org>: added some docs on devpts
|
||||
.\"
|
||||
.TH MOUNT 8 "14 September 1997" "Linux 2.0" "Linux Programmer's Manual"
|
||||
.SH NAME
|
||||
|
@ -175,6 +177,14 @@ instead of
|
|||
in the
|
||||
.I fstab
|
||||
line.
|
||||
The
|
||||
.B owner
|
||||
option is similar to the
|
||||
.B user
|
||||
option, with the restriction that the user must be the owner
|
||||
of the special file. This may be useful e.g. for
|
||||
.I /dev/fd
|
||||
if a login script makes the console user owner of this device.
|
||||
|
||||
The programs
|
||||
.B mount
|
||||
|
@ -202,7 +212,11 @@ option below). It is possible to replace
|
|||
by a symbolic link to
|
||||
.IR /proc/mounts ,
|
||||
but some information is lost that way, and in particular
|
||||
working with the loop device will be less convenient.
|
||||
working with the loop device will be less convenient. Also,
|
||||
pathnames containing spaces are handled correctly by
|
||||
.I /etc/mtab
|
||||
but not (yet) by
|
||||
.IR /proc/mounts .
|
||||
|
||||
.SH OPTIONS
|
||||
The full set of options used by an invocation of
|
||||
|
@ -294,31 +308,35 @@ The argument following the
|
|||
is used to indicate the file system type. The file system types which are
|
||||
currently supported are listed in
|
||||
.IR linux/fs/filesystems.c :
|
||||
.IR minix ,
|
||||
.IR xiafs ,
|
||||
.IR ext ,
|
||||
.IR ext2 ,
|
||||
.IR msdos ,
|
||||
.IR umsdos ,
|
||||
.IR vfat ,
|
||||
.IR proc ,
|
||||
.IR autofs ,
|
||||
.IR devpts ,
|
||||
.IR nfs ,
|
||||
.IR iso9660 ,
|
||||
.IR smbfs ,
|
||||
.IR ncpfs ,
|
||||
.IR adfs ,
|
||||
.IR affs ,
|
||||
.IR autofs ,
|
||||
.IR coda ,
|
||||
.IR coherent ,
|
||||
.IR devpts ,
|
||||
.IR efs ,
|
||||
.IR ext ,
|
||||
.IR ext2 ,
|
||||
.IR hfs ,
|
||||
.IR hpfs ,
|
||||
.IR iso9660 ,
|
||||
.IR minix ,
|
||||
.IR msdos ,
|
||||
.IR ncpfs ,
|
||||
.IR nfs ,
|
||||
.IR ntfs ,
|
||||
.IR proc ,
|
||||
.IR qnx4 ,
|
||||
.IR romfs ,
|
||||
.IR smbfs ,
|
||||
.IR sysv ,
|
||||
.IR udf ,
|
||||
.IR ufs ,
|
||||
.IR sysv ", " xenix ", " coherent .
|
||||
Note that the last three are equivalent and that
|
||||
.IR umsdos ,
|
||||
.IR vfat ,
|
||||
.IR xenix ,
|
||||
.IR xiafs .
|
||||
Note that coherent, sysv and xenix are equivalent and that
|
||||
.I xenix
|
||||
and
|
||||
.I coherent
|
||||
|
@ -355,6 +373,7 @@ option is given, or if the
|
|||
.B auto
|
||||
type is specified, the superblock is probed for the filesystem type
|
||||
.RI ( minix ", " ext ", " ext2 ", " xiafs ", " iso9660 ", " romfs
|
||||
.RI , ufs ", " ntfs ", " qnx4 ", " bfs
|
||||
are supported).
|
||||
If this probe fails, mount will try to read the file
|
||||
.IR /etc/filesystems ,
|
||||
|
@ -362,6 +381,7 @@ or, if that does not exist,
|
|||
.IR /proc/filesystems .
|
||||
All of the filesystem types listed there will be tried,
|
||||
except for those that are labeled "nodev" (e.g.,
|
||||
.IR devpts ,
|
||||
.I proc
|
||||
and
|
||||
.IR nfs ).
|
||||
|
@ -537,6 +557,32 @@ These options are accepted but ignored.
|
|||
.SH "Mount options for coherent"
|
||||
None.
|
||||
|
||||
.SH "Mount options for devpts"
|
||||
The devpts file system is a pseudo file system, traditionally mounted on
|
||||
.IR /dev/pts .
|
||||
In order to acquire a pseudo terminal, a process opens
|
||||
.IR /dev/ptmx ;
|
||||
the number of the pseudo terminal is then made available to the process
|
||||
and the pseudo terminal slave can be accessed as
|
||||
.IR /dev/pts/ <number>.
|
||||
.TP
|
||||
\fBuid=\fP\fIvalue\fP and \fBgid=\fP\fIvalue\fP
|
||||
This sets the owner or the group of newly created PTYs to
|
||||
the specified values. When nothing is specified, they will
|
||||
be set to the UID and GID of the creating process.
|
||||
For example, if there is a tty group with GID 5, then
|
||||
.B gid=5
|
||||
will cause newly created PTYs to belong to the tty group.
|
||||
.TP
|
||||
.BI mode= value
|
||||
Set the mode of newly created PTYs to the specified value.
|
||||
The default is 0600.
|
||||
A value of
|
||||
.B mode=620
|
||||
and
|
||||
.B gid=5
|
||||
makes "mesg y" the default on newly created PTYs.
|
||||
|
||||
.SH "Mount options for ext"
|
||||
None.
|
||||
Note that the `ext' file system is obsolete. Don't use it.
|
||||
|
@ -619,11 +665,15 @@ These options determine who can use the reserved blocks.
|
|||
Instead of block 1, use block
|
||||
.I n
|
||||
as superblock. This could be useful when the filesystem has been damaged.
|
||||
Usually, copies of the superblock are found every 8192 blocks: in
|
||||
block 1, 8193, 16385, ...
|
||||
(Thus, one gets hundreds or even thousands of copies of the superblock
|
||||
on a big filesystem. I do not know of options to mke2fs that would
|
||||
cause fewer copies to be written.)
|
||||
(Earlier, copies of the superblock would be made every 8192 blocks: in
|
||||
block 1, 8193, 16385, ... (and one got hundreds or even thousands
|
||||
of copies on a big filesystem). Since version 1.08,
|
||||
.B mke2fs
|
||||
has a \-s (sparse superblock) option to reduce the number of backup
|
||||
superblocks, and since version 1.15 this is the default. Note
|
||||
that this may mean that ext2 filesystems created by a recent
|
||||
.B mke2fs
|
||||
cannot be mounted r/w under Linux 2.0.*.)
|
||||
.TP
|
||||
.BR grpquota " / " noquota " / " quota " / " usrquota
|
||||
These options are accepted but ignored.
|
||||
|
@ -638,7 +688,7 @@ and
|
|||
.I vfat
|
||||
filesystems.)
|
||||
.TP
|
||||
.BR blocksize=512 " / " blocksize=1024
|
||||
.BR blocksize=512 " / " blocksize=1024 " / " blocksize=2048
|
||||
Set blocksize (default 512).
|
||||
.TP
|
||||
\fBuid=\fP\fIvalue\fP and \fBgid=\fP\fIvalue\fP
|
||||
|
@ -673,6 +723,10 @@ that are sometimes used on Linux, but are not accepted by MS-DOS are
|
|||
rejected. (+, =, spaces, etc.)
|
||||
.RE
|
||||
.TP
|
||||
.BI codepage= value
|
||||
Sets the codepage for converting to shortname characters on FAT
|
||||
and VFAT filesystems. By default, codepage 437 is used.
|
||||
.TP
|
||||
.BR conv=b[inary] " / " conv=t[ext] " / " conv=a[uto]
|
||||
The
|
||||
.I fat
|
||||
|
@ -703,6 +757,15 @@ For file systems mounted in binary mode, a conversion tool
|
|||
(fromdos/todos) is available.
|
||||
.RE
|
||||
.TP
|
||||
.BI cvf_format= module
|
||||
Forces the driver to use the CVF (Compressed Volume File) module
|
||||
.RI cvf_ module
|
||||
instead of auto-detection. If the kernel supports kmod, the
|
||||
cvf_format=xxx option also controls on-demand CVF module loading.
|
||||
.TP
|
||||
.BI cvf_option= option
|
||||
Option passed to the CVF module.
|
||||
.TP
|
||||
.B debug
|
||||
Turn on the
|
||||
.I debug
|
||||
|
@ -710,10 +773,15 @@ flag. A version string and a list of file system parameters will be
|
|||
printed (these data are also printed if the parameters appear to be
|
||||
inconsistent).
|
||||
.TP
|
||||
.BR fat=12 " / " fat=16
|
||||
Specify either a 12 bit fat or a 16 bit fat. This overrides
|
||||
.BR fat=12 " / " fat=16 " / " fat=32
|
||||
Specify a 12, 16 or 32 bit fat. This overrides
|
||||
the automatic FAT type detection routine. Use with caution!
|
||||
.TP
|
||||
.BI iocharset= value
|
||||
Character set to use for converting between 8 bit characters
|
||||
and 16 bit Unicode characters. The default is iso8859-1.
|
||||
Long filenames are stored on disk in Unicode format.
|
||||
.TP
|
||||
.B quiet
|
||||
Turn on the
|
||||
.I quiet
|
||||
|
@ -774,6 +842,9 @@ that it is read-only, of course).
|
|||
.B norock
|
||||
Disable the use of Rock Ridge extensions, even if available. Cf.\&
|
||||
.BR map .
|
||||
.B nojoliet
|
||||
Disable the use of Microsoft Joliet extensions, even if available. Cf.\&
|
||||
.BR map .
|
||||
.TP
|
||||
.BR check=r[elaxed] " / " check=s[trict]
|
||||
With
|
||||
|
@ -792,7 +863,7 @@ possibly overriding the information found in the Rock Ridge extensions.
|
|||
(Default:
|
||||
.BR uid=0,gid=0 .)
|
||||
.TP
|
||||
.BR map=n[ormal] " / " map=o[ff]
|
||||
.BR map=n[ormal] " / " map=o[ff] " / " map=a[corn]
|
||||
For non-Rock Ridge volumes, normal name translation maps upper
|
||||
to lower case ASCII, drops a trailing `;1', and converts `;' to `.'.
|
||||
With
|
||||
|
@ -801,6 +872,10 @@ no name translation is done. See
|
|||
.BR norock .
|
||||
(Default:
|
||||
.BR map=normal .)
|
||||
.B map=acorn
|
||||
is like
|
||||
.BR map=normal
|
||||
but also apply Acorn extensions if present.
|
||||
.TP
|
||||
.BI mode= value
|
||||
For non-Rock Ridge volumes, give all files the indicated mode.
|
||||
|
@ -821,7 +896,7 @@ Set the block size to the indicated value.
|
|||
.BR conv=binary .)
|
||||
Since Linux 1.3.54 this option has no effect anymore.
|
||||
(And non-binary settings used to be very dangerous,
|
||||
often leading to silent data corruption.)
|
||||
possibly leading to silent data corruption.)
|
||||
.TP
|
||||
.B cruft
|
||||
If the high byte of the file length contains other garbage,
|
||||
|
@ -830,6 +905,12 @@ This implies that a file cannot be larger than 16MB.
|
|||
The `cruft' option is set automatically if the entire CDROM
|
||||
has a weird size (negative, or more than 800MB). It is also
|
||||
set when volume sequence numbers other than 0 or 1 are seen.
|
||||
.TP
|
||||
.B session=x
|
||||
Select number of session on multisession CD. (Since 2.3.4.)
|
||||
.TP
|
||||
.B sbsector=xxx
|
||||
Session begins from sector xxx. (Since 2.3.4.)
|
||||
|
||||
.SH "Mount options for minix"
|
||||
None.
|
||||
|
@ -926,6 +1007,30 @@ Usually it just causes lots of trouble.
|
|||
.B nolock
|
||||
Do not use locking. Do not start lockd.
|
||||
|
||||
.SH "Mount options for ntfs"
|
||||
.TP
|
||||
.BI iocharset= name
|
||||
Character set to use when returning file names.
|
||||
Unlike VFAT, NTFS suppresses names that contain
|
||||
unconvertible characters.
|
||||
.TP
|
||||
.BR utf8
|
||||
Use UTF-8 for converting file names.
|
||||
.TP
|
||||
.B uni_xlate=[0|1|2]
|
||||
For 0 (or `no' or `false') or 1 (or `yes' or `true'):
|
||||
use the VFAT-style encoding for file names outside the current
|
||||
character set. A value of 2 will disable the encoding with ":".
|
||||
.TP
|
||||
.B posix=[0|1]
|
||||
If enabled (posix=1), the file system distinguishes between
|
||||
upper and lower case. The 8.3 alias names are presented as
|
||||
hard links instead of being suppressed.
|
||||
.TP
|
||||
\fBuid=\fP\fIvalue\fP, \fBgid=\fP\fIvalue\fP and \fBumask=\fP\fIvalue\fP
|
||||
Set the file permission on the filesystem.
|
||||
By default, the files are owned by root and not readable by somebody else.
|
||||
|
||||
.SH "Mount options for proc"
|
||||
.TP
|
||||
\fBuid=\fP\fIvalue\fP and \fBgid=\fP\fIvalue\fP
|
||||
|
@ -943,13 +1048,109 @@ to the mount system call. This argument is constructed by
|
|||
.BR smbmount (8)
|
||||
and the current version of
|
||||
.B mount
|
||||
(2.6c) does not know anything about smb.
|
||||
(2.9w) does not know anything about smb.
|
||||
|
||||
.SH "Mount options for sysv"
|
||||
None.
|
||||
|
||||
.SH "Mount options for udf"
|
||||
.TP
|
||||
.B gid=
|
||||
Set the default group.
|
||||
.TP
|
||||
.B umask=
|
||||
Set the default umask.
|
||||
.TP
|
||||
.B uid=
|
||||
Set the default user.
|
||||
.TP
|
||||
.B unhide
|
||||
Show otherwise hidden files.
|
||||
.TP
|
||||
.B undelete
|
||||
Show deleted files in lists.
|
||||
.TP
|
||||
.B strict
|
||||
Set strict conformance (unused).
|
||||
.TP
|
||||
.B utf8
|
||||
(unused).
|
||||
.TP
|
||||
.B iocharset
|
||||
(unused).
|
||||
.TP
|
||||
.B bs=
|
||||
Set the block size. (May not work unless 2048.)
|
||||
.TP
|
||||
.B novrs
|
||||
Skip volume sequence recognition.
|
||||
.TP
|
||||
.B session=
|
||||
Set the CDROM session counting from 0. Default: last session.
|
||||
.TP
|
||||
.B anchor=
|
||||
Override standard anchor location. Default: 256.
|
||||
.TP
|
||||
.B volume=
|
||||
Override the VolumeDesc location. (unused)
|
||||
.TP
|
||||
.B partition=
|
||||
Override the PartitionDesc location. (unused)
|
||||
.TP
|
||||
.B lastblock=
|
||||
Set the last block of the filesystem.
|
||||
.TP
|
||||
.B fileset=
|
||||
Override the fileset block location. (unused)
|
||||
.TP
|
||||
.B rootdir=
|
||||
Override the root directory location. (unused)
|
||||
|
||||
.SH "Mount options for ufs"
|
||||
None.
|
||||
.TP
|
||||
.BI ufstype= value
|
||||
UFS is a file system widely used in different operating systems.
|
||||
The problem are differences among implementations. Features of some
|
||||
implementations are undocumented, so its hard to recognize the
|
||||
type of ufs automatically.
|
||||
That's why user must specify the type of ufs by mount option.
|
||||
Possible values are:
|
||||
.RS
|
||||
.TP
|
||||
.B old
|
||||
Old format of ufs, this is the default, read only.
|
||||
.TP
|
||||
.B 44bsd
|
||||
For filesystems created by a BSD-like system (NetBSD,FreeBSD,OpenBSD).
|
||||
.TP
|
||||
.B sun
|
||||
For filesystems created by SunOS or Solaris on Sparc.
|
||||
.TP
|
||||
.B sunx86
|
||||
For filesystems created by Solaris on x86.
|
||||
.TP
|
||||
.B nextstep
|
||||
For filesystems created by NeXTStep (on NeXT station) (currently read only).
|
||||
.TP
|
||||
.B nextstep-cd
|
||||
For NextStep CDROMs (block_size == 2048), read-only.
|
||||
.TP
|
||||
.B openstep
|
||||
For filesystems created by OpenStep (currently read only).
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.BI onerror= value
|
||||
Set behaviour on error:
|
||||
.RS
|
||||
.TP
|
||||
.B panic
|
||||
If an error is encountered, cause a kernel panic.
|
||||
.TP
|
||||
.B [lock|umount|repair]
|
||||
These mount options don't do anything at present;
|
||||
when an error is encountered only a console message is printed.
|
||||
.RE
|
||||
|
||||
.SH "Mount options for umsdos"
|
||||
See mount options for msdos.
|
||||
|
@ -984,6 +1185,11 @@ Allow two files with names that only differ in case.
|
|||
First try to make a short name without sequence number,
|
||||
before trying
|
||||
.IR name~num.ext .
|
||||
.TP
|
||||
.B utf8
|
||||
UTF8 is the filesystem safe 8-bit encoding of Unicode that is used
|
||||
by the console. It can be be enabled for the filesystem with this option.
|
||||
If `uni_xlate' gets set, UTF8 gets disabled.
|
||||
|
||||
.SH "Mount options for xenix"
|
||||
None.
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
* - fixed strerr(errno) in gettext calls
|
||||
* 1999-07-05 Hirokazu Takahashi <h-takaha@sss.abk.nec.co.jp>
|
||||
* - fixed use of nouser option
|
||||
* 1999-09-09 Michael K. Johnson <johnsonm@redhat.com>
|
||||
* - added `owner' mount option
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
@ -107,6 +109,7 @@ struct opt_map
|
|||
#define MS_NOAUTO 0x80000000
|
||||
#define MS_USERS 0x40000000
|
||||
#define MS_USER 0x20000000
|
||||
#define MS_OWNER 0x10000000
|
||||
#define MS_LOOP 0x00010000
|
||||
|
||||
/* Options that we keep the mount system call from seeing. */
|
||||
|
@ -115,9 +118,12 @@ struct opt_map
|
|||
/* Options that we keep from appearing in the options field in the mtab. */
|
||||
#define MS_NOMTAB (MS_REMOUNT|MS_NOAUTO|MS_USERS|MS_USER)
|
||||
|
||||
/* OPTIONS that we make ordinary users have by default. */
|
||||
/* Options that we make ordinary users have by default. */
|
||||
#define MS_SECURE (MS_NOEXEC|MS_NOSUID|MS_NODEV)
|
||||
|
||||
/* Options that we make owner-mounted devices have by default */
|
||||
#define MS_OWNERSECURE (MS_NOSUID|MS_NODEV)
|
||||
|
||||
const struct opt_map opt_map[] = {
|
||||
{ "defaults", 0, 0, 0 }, /* default options */
|
||||
{ "ro", 1, 0, MS_RDONLY }, /* read-only */
|
||||
|
@ -137,6 +143,8 @@ const struct opt_map opt_map[] = {
|
|||
{ "nousers", 0, 1, MS_USERS }, /* Forbid ordinary user to mount */
|
||||
{ "user", 0, 0, MS_USER }, /* Allow ordinary user to mount */
|
||||
{ "nouser", 0, 1, MS_USER }, /* Forbid ordinary user to mount */
|
||||
{ "owner", 0, 0, MS_OWNER }, /* Let the owner of the device mount */
|
||||
{ "noowner", 0, 1, MS_OWNER }, /* Device owner has no special privs */
|
||||
/* add new options here */
|
||||
#ifdef MS_NOSUB
|
||||
{ "sub", 0, 1, MS_NOSUB }, /* allow submounts */
|
||||
|
@ -244,6 +252,8 @@ parse_opt (const char *opt, int *mask, char *extra_opts)
|
|||
if ((om->mask == MS_USER || om->mask == MS_USERS)
|
||||
&& !om->inv)
|
||||
*mask |= MS_SECURE;
|
||||
if ((om->mask == MS_OWNER) && !om->inv)
|
||||
*mask |= MS_OWNERSECURE;
|
||||
#ifdef MS_SILENT
|
||||
if (om->mask == MS_SILENT && om->inv) {
|
||||
mount_quiet = 1;
|
||||
|
@ -377,6 +387,7 @@ create_mtab (void) {
|
|||
/* count successful mount system calls */
|
||||
static int mountcount = 0;
|
||||
|
||||
/* returns 0: OK, -1: error */
|
||||
static int
|
||||
mount5 (struct mountargs *args) {
|
||||
int ret = mount (args->spec, args->node, args->type,
|
||||
|
@ -386,9 +397,9 @@ mount5 (struct mountargs *args) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Mount a single file system. Return status,
|
||||
so don't exit on non-fatal errors. */
|
||||
|
||||
/* Mount a single file system.
|
||||
Return status: 0: OK, -1: error in errno, 1: other error
|
||||
don't exit on non-fatal errors. */
|
||||
static int
|
||||
try_mount5 (char *spec, char *node, char **type, int flags, char *mount_opts) {
|
||||
struct mountargs args = { spec, node, NULL, flags & ~MS_NOSYS, mount_opts };
|
||||
|
@ -396,8 +407,14 @@ try_mount5 (char *spec, char *node, char **type, int flags, char *mount_opts) {
|
|||
if (*type && strcasecmp (*type, "auto") == 0)
|
||||
*type = NULL;
|
||||
|
||||
if (!*type && !(flags & MS_REMOUNT))
|
||||
if (!*type && !(flags & MS_REMOUNT)) {
|
||||
*type = guess_fstype_from_superblock(spec);
|
||||
if (*type && !strcmp(*type, "swap")) {
|
||||
error(_("%s looks like swapspace - not mounted"), spec);
|
||||
*type = NULL;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (*type || (flags & MS_REMOUNT)) {
|
||||
args.type = *type;
|
||||
|
@ -419,6 +436,7 @@ try_mount_one (const char *spec0, const char *node0, char *type0,
|
|||
const char *opts0, int freq, int pass, int bg, int ro) {
|
||||
struct mntentchn mcn;
|
||||
struct mntent mnt;
|
||||
int mnt5_res = 0; /* only for gcc */
|
||||
int mnt_err;
|
||||
int flags;
|
||||
char *extra_opts; /* written in mtab */
|
||||
|
@ -438,6 +456,26 @@ try_mount_one (const char *spec0, const char *node0, char *type0,
|
|||
|
||||
/* root may allow certain types of mounts by ordinary users */
|
||||
if (suid) {
|
||||
/* RedHat patch: allow owners to mount when fstab contains
|
||||
the owner option. Note that this should never be used
|
||||
in a high security environment, but may be useful to give
|
||||
people at the console the possibility of mounting a floppy. */
|
||||
if (flags & MS_OWNER) {
|
||||
if (!strncmp(spec0, "/dev/", 5)) {
|
||||
struct stat sb;
|
||||
|
||||
if (!stat(spec0, &sb)) {
|
||||
if (getuid() == sb.st_uid)
|
||||
flags |= MS_USER;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* James Kehl <mkehl@gil.com.au> came with a similar patch:
|
||||
allow an arbitrary user to mount when he is the owner of
|
||||
the mount-point and has write-access to the device.
|
||||
This is even less secure. Let me skip it for the time being;
|
||||
there should be an explicit fstab line allowing such things. */
|
||||
|
||||
if (!(flags & (MS_USER | MS_USERS))) {
|
||||
if (already (spec, node))
|
||||
die (EX_USAGE, _("mount failed"));
|
||||
|
@ -448,6 +486,9 @@ try_mount_one (const char *spec0, const char *node0, char *type0,
|
|||
user = getusername();
|
||||
}
|
||||
|
||||
if (flags & MS_OWNER)
|
||||
flags &= ~MS_OWNER;
|
||||
|
||||
/* quietly succeed for fstab entries that don't get mounted automatically */
|
||||
if (all && (flags & MS_NOAUTO))
|
||||
return 0;
|
||||
|
@ -538,7 +579,8 @@ try_mount_one (const char *spec0, const char *node0, char *type0,
|
|||
|
||||
sprintf(mountprog, "/sbin/mount.%s", type);
|
||||
if (stat(mountprog, &statbuf) == 0) {
|
||||
if (fork() == 0) {
|
||||
int res;
|
||||
if ((res = fork()) == 0) {
|
||||
char *oo, *mountargs[10];
|
||||
int i = 0;
|
||||
|
||||
|
@ -559,7 +601,7 @@ try_mount_one (const char *spec0, const char *node0, char *type0,
|
|||
mountargs[i] = NULL;
|
||||
execv(mountprog, mountargs);
|
||||
exit(1); /* exec failed */
|
||||
} else if (fork() != -1) {
|
||||
} else if (res != -1) {
|
||||
int status;
|
||||
wait(&status);
|
||||
return status;
|
||||
|
@ -572,10 +614,11 @@ try_mount_one (const char *spec0, const char *node0, char *type0,
|
|||
|
||||
block_signals (SIG_BLOCK);
|
||||
|
||||
if (fake
|
||||
|| (try_mount5 (spec, node, &type, flags & ~MS_NOSYS, mount_opts)) == 0)
|
||||
if (!fake)
|
||||
mnt5_res = try_mount5 (spec, node, &type, flags & ~MS_NOSYS, mount_opts);
|
||||
|
||||
if (fake || mnt5_res == 0) {
|
||||
/* Mount succeeded, report this (if verbose) and write mtab entry. */
|
||||
{
|
||||
if (loop)
|
||||
opt_loopdev = loopdev;
|
||||
|
||||
|
@ -630,11 +673,17 @@ try_mount_one (const char *spec0, const char *node0, char *type0,
|
|||
|
||||
/* Mount failed, complain, but don't die. */
|
||||
|
||||
if (type == 0)
|
||||
error (_("mount: you must specify the filesystem type"));
|
||||
if (type == 0) {
|
||||
if (suid)
|
||||
error (_("mount: I could not determine the filesystem type, "
|
||||
"and none was specified"));
|
||||
else
|
||||
switch (mnt_err)
|
||||
{
|
||||
error (_("mount: you must specify the filesystem type"));
|
||||
} else if (mnt5_res != -1) {
|
||||
/* should not happen */
|
||||
error (_("mount: mount failed"));
|
||||
} else {
|
||||
switch (mnt_err) {
|
||||
case EPERM:
|
||||
if (geteuid() == 0) {
|
||||
if (stat (node, &statbuf) || !S_ISDIR(statbuf.st_mode))
|
||||
|
@ -775,6 +824,7 @@ try_mount_one (const char *spec0, const char *node0, char *type0,
|
|||
default:
|
||||
error ("mount: %s", strerror (mnt_err)); break;
|
||||
}
|
||||
}
|
||||
return EX_FAIL;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
*
|
||||
* Wed Nov 11 11:33:55 1998: K.Garloff@ping.de, try /etc/filesystems before
|
||||
* /proc/filesystems
|
||||
* [This was mainly in order to specify vfat before fat; these days we often
|
||||
* detect *fat and then assume vfat, so perhaps /etc/filesystems isnt
|
||||
* so useful anymore.]
|
||||
*
|
||||
* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@misiek.eu.org>
|
||||
* - added Native Language Support
|
||||
|
@ -67,12 +70,17 @@ swapped(unsigned short a) {
|
|||
Added ufs from a patch by jj. But maybe there are several types of ufs?
|
||||
Added ntfs from a patch by Richard Russon.
|
||||
Added a very weak heuristic for vfat - aeb
|
||||
Added qnx4 - aeb
|
||||
Added swap - aeb
|
||||
|
||||
Currently supports: minix, ext, ext2, xiafs, iso9660, romfs, ufs, ntfs, vfat
|
||||
Currently supports: minix, ext, ext2, xiafs, iso9660, romfs,
|
||||
ufs, ntfs, vfat, qnx4, bfs
|
||||
*/
|
||||
static char
|
||||
*magic_known[] = { "minix", "ext", "ext2", "xiafs", "iso9660", "romfs",
|
||||
"ufs", "ntfs" };
|
||||
"ufs", "ntfs", "qnx4", "bfs", "udf",
|
||||
"swap" /* last - just to warn the user */
|
||||
};
|
||||
|
||||
static int
|
||||
tested(const char *device) {
|
||||
|
@ -84,6 +92,32 @@ tested(const char *device) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* udf magic - I find that trying to mount garbage as an udf fs
|
||||
causes a very large kernel delay, almost killing the machine.
|
||||
So, we do not try udf unless there is positive evidence that it
|
||||
might work. Try iso9660 first, it is much more likely.
|
||||
|
||||
Strings below taken from ECMA 167. */
|
||||
static char
|
||||
*udf_magic[] = { "BEA01", "BOOT2", "CD001", "CDW02", "NSR02",
|
||||
"NSR03", "TEA01" };
|
||||
|
||||
static int
|
||||
may_be_udf(const char *id) {
|
||||
char **m;
|
||||
|
||||
for (m = udf_magic; m - udf_magic < SIZE(udf_magic); m++)
|
||||
if (!strncmp(*m, id, 5))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
may_be_swap(const char *s) {
|
||||
return (strncmp(s-10, "SWAP-SPACE", 10) == 0 ||
|
||||
strncmp(s-10, "SWAPSPACE2", 10) == 0);
|
||||
}
|
||||
|
||||
static char *
|
||||
fstype(const char *device) {
|
||||
int fd;
|
||||
|
@ -96,6 +130,8 @@ fstype(const char *device) {
|
|||
union {
|
||||
struct xiafs_super_block xiasb;
|
||||
char romfs_magic[8];
|
||||
char qnx4fs_magic[10]; /* ignore first 4 bytes */
|
||||
long bfs_magic;
|
||||
struct ntfs_super_block ntfssb;
|
||||
struct fat_super_block fatsb;
|
||||
} xsb;
|
||||
|
@ -141,11 +177,17 @@ fstype(const char *device) {
|
|||
type = "xiafs";
|
||||
else if(!strncmp(xsb.romfs_magic, "-rom1fs-", 8))
|
||||
type = "romfs";
|
||||
else if(!strncmp(xsb.qnx4fs_magic+4, "QNX4FS", 6))
|
||||
type = "qnx4fs";
|
||||
else if(xsb.bfs_magic == 0x1badface)
|
||||
type = "bfs";
|
||||
else if(!strncmp(xsb.ntfssb.s_magic, NTFS_SUPER_MAGIC,
|
||||
sizeof(xsb.ntfssb.s_magic)))
|
||||
type = "ntfs";
|
||||
else if ((!strncmp(xsb.fatsb.s_os, "MSDOS", 5) ||
|
||||
!strncmp(xsb.fatsb.s_os, "MSWIN", 5))
|
||||
!strncmp(xsb.fatsb.s_os, "MSWIN", 5) ||
|
||||
!strncmp(xsb.fatsb.s_os, "MTOOL", 5) ||
|
||||
!strncmp(xsb.fatsb.s_os, "mkdosfs", 7))
|
||||
&& (!strncmp(xsb.fatsb.s_fs, "FAT12 ", 8) ||
|
||||
!strncmp(xsb.fatsb.s_fs, "FAT16 ", 8) ||
|
||||
!strncmp(xsb.fatsb.s_fs2, "FAT32 ", 8)))
|
||||
|
@ -169,6 +211,28 @@ fstype(const char *device) {
|
|||
if(strncmp(isosb.iso.id, ISO_STANDARD_ID, sizeof(isosb.iso.id)) == 0
|
||||
|| strncmp(isosb.hs.id, HS_STANDARD_ID, sizeof(isosb.hs.id)) == 0)
|
||||
type = "iso9660";
|
||||
else if (may_be_udf(isosb.iso.id))
|
||||
type = "udf";
|
||||
}
|
||||
|
||||
if (!type) {
|
||||
/* perhaps the user tries to mount the swap space
|
||||
on a new disk; warn her before she does mke2fs on it */
|
||||
int pagesize = getpagesize();
|
||||
int rd;
|
||||
char buf[32768];
|
||||
|
||||
rd = pagesize;
|
||||
if (rd < 8192)
|
||||
rd = 8192;
|
||||
if (rd > sizeof(buf))
|
||||
rd = sizeof(buf);
|
||||
if (lseek(fd, 0, SEEK_SET) != 0
|
||||
|| read(fd, buf, rd) != rd)
|
||||
goto io_error;
|
||||
if (may_be_swap(buf+pagesize) ||
|
||||
may_be_swap(buf+4096) || may_be_swap(buf+8192))
|
||||
type = "swap";
|
||||
}
|
||||
|
||||
close (fd);
|
||||
|
@ -186,11 +250,13 @@ guess_fstype_from_superblock(const char *spec) {
|
|||
if (verbose) {
|
||||
printf (_("mount: you didn't specify a filesystem type for %s\n"),
|
||||
spec);
|
||||
if (type)
|
||||
printf (_(" I will try type %s\n"), type);
|
||||
else
|
||||
if (!type)
|
||||
printf (_(" I will try all types mentioned in %s or %s\n"),
|
||||
ETC_FILESYSTEMS, PROC_FILESYSTEMS);
|
||||
else if (!strcmp(type, "swap"))
|
||||
printf (_(" and it looks like this is swapspace\n"));
|
||||
else
|
||||
printf (_(" I will try type %s\n"), type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
@ -237,17 +303,24 @@ is_in_procfs(const char *type) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* return: 0: OK, -1: error in errno, 1: type not found */
|
||||
/* when 1 is returned, *type is NULL */
|
||||
int
|
||||
procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args,
|
||||
char **type) {
|
||||
char *fsname;
|
||||
|
||||
*type = NULL;
|
||||
if (!procfsopen())
|
||||
return -1;
|
||||
return 1;
|
||||
while ((fsname = procfsnext()) != NULL) {
|
||||
if (tested (fsname))
|
||||
continue;
|
||||
args->type = fsname;
|
||||
if (verbose) {
|
||||
printf(_("Trying %s\n"), fsname);
|
||||
fflush(stdout);
|
||||
}
|
||||
if ((*mount_fn) (args) == 0) {
|
||||
*type = xstrdup(fsname);
|
||||
procfsclose();
|
||||
|
@ -255,13 +328,11 @@ procfsloop(int (*mount_fn)(struct mountargs *), struct mountargs *args,
|
|||
} else if (errno != EINVAL) {
|
||||
*type = "guess";
|
||||
procfsclose();
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
procfsclose();
|
||||
*type = NULL;
|
||||
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
143
mount/realpath.c
143
mount/realpath.c
|
@ -13,170 +13,109 @@
|
|||
* GNU Library Public License for more details.
|
||||
*/
|
||||
|
||||
#define HAVE_GETCWD
|
||||
|
||||
/*
|
||||
* This routine is part of libc. We include it nevertheless,
|
||||
* since the libc version has some security flaws.
|
||||
*/
|
||||
|
||||
#ifdef __linux__
|
||||
extern char *realpath(const char *path, char *resolved_path);
|
||||
#define HAVE_UNISTD_H
|
||||
#define HAVE_STRING_H
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#if defined(HAVE_UNISTD_H) || defined(STDC_HEADERS)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#ifdef _POSIX_VERSION
|
||||
#include <limits.h> /* for PATH_MAX */
|
||||
#else
|
||||
#include <sys/param.h> /* for MAXPATHLEN */
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/stat.h> /* for S_IFLNK */
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#ifdef _POSIX_VERSION
|
||||
#define PATH_MAX _POSIX_PATH_MAX
|
||||
#else
|
||||
#ifdef MAXPATHLEN
|
||||
#define PATH_MAX MAXPATHLEN
|
||||
#else
|
||||
#define PATH_MAX 1024
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#include "realpath.h"
|
||||
#include "sundries.h" /* for xstrdup */
|
||||
|
||||
#define MAX_READLINKS 32
|
||||
|
||||
#ifdef __STDC__
|
||||
char *realpath(const char *path, char *resolved_path)
|
||||
#else
|
||||
char *realpath(path, resolved_path)
|
||||
const char *path;
|
||||
char *resolved_path;
|
||||
#endif
|
||||
{
|
||||
char copy_path[PATH_MAX];
|
||||
char link_path[PATH_MAX];
|
||||
char *new_path = resolved_path;
|
||||
char *max_path;
|
||||
char *
|
||||
myrealpath(const char *path, char *resolved_path, int maxreslth) {
|
||||
char *npath;
|
||||
char link_path[PATH_MAX+1];
|
||||
int readlinks = 0;
|
||||
int n;
|
||||
|
||||
/* Make a copy of the source path since we may need to modify it. */
|
||||
if (strlen(path) >= PATH_MAX) {
|
||||
errno = ENAMETOOLONG;
|
||||
return NULL;
|
||||
}
|
||||
strcpy(copy_path, path);
|
||||
path = copy_path;
|
||||
max_path = copy_path + PATH_MAX - 2;
|
||||
npath = resolved_path;
|
||||
|
||||
/* If it's a relative pathname use getwd for starters. */
|
||||
/* If it's a relative pathname use getcwd for starters. */
|
||||
if (*path != '/') {
|
||||
#ifdef HAVE_GETCWD
|
||||
getcwd(new_path, PATH_MAX - 1);
|
||||
#else
|
||||
getwd(new_path);
|
||||
#endif
|
||||
new_path += strlen(new_path);
|
||||
if (new_path[-1] != '/')
|
||||
*new_path++ = '/';
|
||||
}
|
||||
else {
|
||||
*new_path++ = '/';
|
||||
getcwd(npath, maxreslth-2);
|
||||
npath += strlen(npath);
|
||||
if (npath[-1] != '/')
|
||||
*npath++ = '/';
|
||||
} else {
|
||||
*npath++ = '/';
|
||||
path++;
|
||||
}
|
||||
|
||||
/* Expand each slash-separated pathname component. */
|
||||
while (*path != '\0') {
|
||||
/* Ignore stray "/". */
|
||||
/* Ignore stray "/" */
|
||||
if (*path == '/') {
|
||||
path++;
|
||||
continue;
|
||||
}
|
||||
if (*path == '.') {
|
||||
/* Ignore ".". */
|
||||
if (path[1] == '\0' || path[1] == '/') {
|
||||
if (*path == '.' && (path[1] == '\0' || path[1] == '/')) {
|
||||
/* Ignore "." */
|
||||
path++;
|
||||
continue;
|
||||
}
|
||||
if (path[1] == '.') {
|
||||
if (path[2] == '\0' || path[2] == '/') {
|
||||
if (*path == '.' && path[1] == '.' &&
|
||||
(path[2] == '\0' || path[2] == '/')) {
|
||||
/* Backup for ".." */
|
||||
path += 2;
|
||||
/* Ignore ".." at root. */
|
||||
if (new_path == resolved_path + 1)
|
||||
continue;
|
||||
/* Handle ".." by backing up. */
|
||||
while ((--new_path)[-1] != '/')
|
||||
while (npath > resolved_path+1 &&
|
||||
(--npath)[-1] != '/')
|
||||
;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Safely copy the next pathname component. */
|
||||
while (*path != '\0' && *path != '/') {
|
||||
if (path > max_path) {
|
||||
if (npath-resolved_path > maxreslth-2) {
|
||||
errno = ENAMETOOLONG;
|
||||
return NULL;
|
||||
}
|
||||
*new_path++ = *path++;
|
||||
*npath++ = *path++;
|
||||
}
|
||||
#ifdef S_IFLNK
|
||||
|
||||
/* Protect against infinite loops. */
|
||||
if (readlinks++ > MAX_READLINKS) {
|
||||
errno = ELOOP;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* See if latest pathname component is a symlink. */
|
||||
*new_path = '\0';
|
||||
n = readlink(resolved_path, link_path, PATH_MAX - 1);
|
||||
*npath = '\0';
|
||||
n = readlink(resolved_path, link_path, PATH_MAX);
|
||||
if (n < 0) {
|
||||
/* EINVAL means the file exists but isn't a symlink. */
|
||||
if (errno != EINVAL)
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
/* Note: readlink doesn't add the null byte. */
|
||||
link_path[n] = '\0';
|
||||
if (*link_path == '/')
|
||||
/* Start over for an absolute symlink. */
|
||||
new_path = resolved_path;
|
||||
npath = resolved_path;
|
||||
else
|
||||
/* Otherwise back up over this component. */
|
||||
while (*(--new_path) != '/')
|
||||
while (*(--npath) != '/')
|
||||
;
|
||||
/* Safe sex check. */
|
||||
if (strlen(path) + n >= PATH_MAX) {
|
||||
if (strlen(path) + n >= sizeof(link_path)) {
|
||||
errno = ENAMETOOLONG;
|
||||
return NULL;
|
||||
}
|
||||
/* Insert symlink contents into path. */
|
||||
strcat(link_path, path);
|
||||
strcpy(copy_path, link_path);
|
||||
path = copy_path;
|
||||
path = xstrdup(link_path);
|
||||
}
|
||||
#endif /* S_IFLNK */
|
||||
*new_path++ = '/';
|
||||
|
||||
*npath++ = '/';
|
||||
}
|
||||
/* Delete trailing slash but don't whomp a lone slash. */
|
||||
if (new_path != resolved_path + 1 && new_path[-1] == '/')
|
||||
new_path--;
|
||||
if (npath != resolved_path+1 && npath[-1] == '/')
|
||||
npath--;
|
||||
/* Make sure it's null terminated. */
|
||||
*new_path = '\0';
|
||||
*npath = '\0';
|
||||
return resolved_path;
|
||||
}
|
||||
|
|
1
mount/realpath.h
Normal file
1
mount/realpath.h
Normal file
|
@ -0,0 +1 @@
|
|||
extern char *myrealpath(const char *path, char *resolved_path, int m);
|
|
@ -14,6 +14,7 @@
|
|||
#include <mntent.h> /* for MNTTYPE_SWAP */
|
||||
#include "fstab.h"
|
||||
#include "sundries.h"
|
||||
#include "realpath.h"
|
||||
#include "nfsmount.h"
|
||||
#include "nls.h"
|
||||
|
||||
|
@ -224,9 +225,9 @@ canonicalize (const char *path) {
|
|||
if (streq(path, "none") || streq(path, "proc") || streq(path, "devpts"))
|
||||
return xstrdup(path);
|
||||
|
||||
canonical = xmalloc (PATH_MAX + 1);
|
||||
canonical = xmalloc (PATH_MAX+2);
|
||||
|
||||
if (realpath (path, canonical))
|
||||
if (myrealpath (path, canonical, PATH_MAX+1))
|
||||
return canonical;
|
||||
|
||||
free(canonical);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue